X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=worker.v;h=9a7760e5d07f2f19eddfd00b4abfd25b869581c6;hb=46a95fd39e0ef114dd837bed285f8ca6acf6bb32;hp=7a5a909effeaf81f3396aa140c26f0271b3d466a;hpb=3b542afc856d736dfd2ff0eed081f647de07af4c;p=clump.git diff --git a/worker.v b/worker.v index 7a5a909..9a7760e 100644 --- a/worker.v +++ b/worker.v @@ -6,34 +6,49 @@ `ifdef SIM `define UART_DIVIDE 1 `else - `define UART_DIVIDE 1 - // s/192/3/ for 19200 baud uart + `define UART_DIVIDE 2048 `endif -module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, output reg ready_out = 1, input ready_in); - wire clk; - wire clk_tmp; - - //pll pll (.clock_in(CLKin), .clock_out(clk)); +module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, output reg busy_out = 1, input busy_in, input is_worker); + wire clk = CLKin; - reg [20:0] counter = 0; +`ifndef SIM + // if [is_worker == 0], boot into master image + SB_WARMBOOT wb (.BOOT (!is_worker), .S0(1'b1), .S1(1'b0)); +`endif - reg clk = 0; +`ifdef SIM + wire dont_send = 0; +`else + reg [25:0] dont_send = 23'b11111111111111111111111; - always @ (posedge CLKin) begin - if(counter == 5000) begin - counter <= 0; - clk <= 1 - clk; - end - else - counter <= counter + 1; + always @(posedge clk) begin + if(busy_in) + dont_send <= 23'b11111111111111111111111; + else if(dont_send) + dont_send <= dont_send - 1; end +`endif wire [11:0] mem_addr; - wire [63:0] mem_in; - wire [63:0] mem_out; + wire [15:0] mem_in; + wire [15:0] mem_out; wire mem_write; + reg [31:0] the_rom [0:100]; + reg [10:0] rom_pc = 0; + + initial begin + the_rom[0] <= 32'hfC000005; + the_rom[1] <= 32'hfC010007; + the_rom[2] <= 32'hf9001d00; + the_rom[3] <= 32'hfA0112d0; + the_rom[4] <= 32'hfB000004; + the_rom[5] <= 32'hf9000004; + the_rom[6] <= 32'hfA001550; + the_rom[7] <= 32'hfB010000; + end + RAM #(.ADDRESS_BITS(8)) ram (.clk(clk), .write(mem_write), .addr(mem_addr), .in(mem_in), .out(mem_out)); reg [7:0] from_uart [3:0]; @@ -42,16 +57,37 @@ module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, out wire [15:0] I = {from_uart[1], from_uart[0]}; assign mem_addr = from_uart[2]; wire [2:0] op_from_uart = from_uart[3][2:0]; - wire CS = from_uart[3][3]; + + wire [3:0] chip_select = from_uart[3][7:4]; + wire is_virtual = from_uart[3][3]; + wire dont_propagate = is_virtual || ~| chip_select; + wire not_for_us = !chip_select[0]; + + wire [7:0] to_uart [3:0]; + wire [3:0] next_chip_select = {0, chip_select[3:1]}; + assign to_uart[0] = from_uart[0]; + assign to_uart[1] = from_uart[1]; + assign to_uart[2] = from_uart[2]; + assign to_uart[3] = {next_chip_select, from_uart[3][3:0]}; + + /* to execute a ROUTE instruction, we send our neighbour a STOREI + /* instruction with the correct address and value. This is the + /* STOREI instruction. */ + wire [7:0] route_storei [3:0]; + assign route_storei[0] = mem_out[7:0]; + assign route_storei[1] = mem_out[15:8]; + assign route_storei[2] = from_uart[0]; + assign route_storei[3] = 8'h1C; // chip_select = 1, is_virtual = 1, op = OP_STOREI reg [2:0] op = 0; reg [2:0] last_op = 0; reg [15:0] I; - reg CS; - chip chip (.clk(clk), .op(op), .I(I), .io_pin(0), .CS(CS), .mem_in(mem_in), .mem_out(mem_out), .mem_write(mem_write)); + reg [3:0] led_out; + + chip chip (.clk(clk), .op(op), .I(I), .mem_in(mem_in), .mem_out(mem_out), .mem_write(mem_write), .led_out(led_out)); wire received; wire [7:0] rx_byte; @@ -59,25 +95,20 @@ module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, out reg [7:0] tx_byte = 0; wire is_receiving; wire is_transmitting; + wire recv_error; - // 19200 (actually 300) baud uart - uart #(.CLOCK_DIVIDE(`UART_DIVIDE)) uart (.clk(clk), .rx(uart_rx), .tx(uart_tx), .received(received), .transmit(transmit), .tx_byte(tx_byte), .rx_byte(rx_byte), .is_receiving(is_receiving), .is_transmitting(is_transmitting)); - - assign led[0] = is_transmitting; - assign led[4] = received; -// assign led[3:1] = last_op; + uart #(.CLOCK_DIVIDE(`UART_DIVIDE)) uart (.clk(clk), .rx(uart_rx), .tx(uart_tx), .received(received), .transmit(transmit), .tx_byte(tx_byte), .rx_byte(rx_byte), .is_receiving(is_receiving), .is_transmitting(is_transmitting), .recv_error(recv_error)); - assign led[2] = |mem_out; // so that mem_out is used - - // 0 is idle `define STATE_IDLE 0 `define STATE_PROPAGATE 1 -`define STATE_EXECUTE 2 -`define STATE_ROUTE 3 +`define STATE_PREEXEC 2 +`define STATE_EXECUTE 3 +`define STATE_ROUTE 4 - reg [5:0] state = 0; + reg [3:0] state = `STATE_IDLE; -// assign led[4:2] = state; + assign led[3:0] = uart_ptr; + assign led[4] = is_receiving; always @ (posedge clk) begin case(state) @@ -85,14 +116,27 @@ module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, out if(uart_ptr == 4) begin last_op <= op_from_uart; uart_ptr <= 0; - state <= `STATE_PROPAGATE; - ready_out <= 0; + if(dont_propagate) + state <= `STATE_PREEXEC; + else + state <= `STATE_PROPAGATE; + busy_out <= 1; end else if (received) begin from_uart[uart_ptr] <= rx_byte; uart_ptr <= uart_ptr + 1; - end else - ready_out <= 1; + end else begin +`ifdef SIM + from_uart[0] <= the_rom[rom_pc][7:0]; + from_uart[1] <= the_rom[rom_pc][15:8]; + from_uart[2] <= the_rom[rom_pc][23:16]; + from_uart[3] <= the_rom[rom_pc][31:24]; + uart_ptr <= 4; + rom_pc <= rom_pc + 1; +`else + busy_out <= 0; +`endif + end end `STATE_PROPAGATE: begin @@ -100,17 +144,23 @@ module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, out transmit <= 0; else if(uart_ptr == 4) begin uart_ptr <= 0; - if(op == `OP_ROUTE) begin - state <= `STATE_ROUTE; - end else begin - op <= last_op; - state <= `STATE_EXECUTE; - end - end else if(!is_transmitting && ready_in) begin - tx_byte <= from_uart[uart_ptr]; + state <= `STATE_PREEXEC; + end else if(!is_transmitting && !dont_send) begin + tx_byte <= to_uart[uart_ptr]; transmit <= 1; uart_ptr <= uart_ptr + 1; end + end // case: `STATE_PROPAGATE + + `STATE_PREEXEC: begin + if(not_for_us) begin + state <= `STATE_IDLE; + end else if(last_op == `OP_ROUTE) begin + state <= `STATE_ROUTE; + end else begin + op <= last_op; + state <= `STATE_EXECUTE; + end end `STATE_EXECUTE: begin @@ -119,42 +169,17 @@ module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, out end `STATE_ROUTE: begin - state <= `STATE_IDLE; // for now + if(transmit) + transmit <= 0; + else if(uart_ptr == 4) begin + uart_ptr <= 0; + state <= `STATE_IDLE; + end else if(!is_transmitting && !dont_send) begin + tx_byte <= route_storei[uart_ptr]; + transmit <= 1; + uart_ptr <= uart_ptr + 1; + end end endcase - - /* - - if (state == 1 && op != `OP_READ) begin - op <= 0; - state <= 0; - end - - if (state == 1 && op == `OP_READ) begin - op <= 0; - state <= 2; - transmit <= 1; - tx_byte <= mem_out[7:0]; - end - - if (state == 2 && transmit) begin - transmit <= 0; - end - - if (state == 2 && !transmit && !is_transmitting) begin - state <= 3; - transmit <= 1; - tx_byte <= mem_out[15:8]; - end - - if (state == 3) begin - transmit <= 0; - state <= 0; - end */ end - - wire ready = (state == 0 && !is_receiving); - - assign ready_out = ready_in & ready; - endmodule