`ifdef SIM
`define UART_DIVIDE 1
`else
- `define UART_DIVIDE 1
- // s/192/3/ for 19200 baud uart
+ `define UART_DIVIDE 1024
`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 <= 21'b111111111111111111111;
+ else if(dont_send)
+ dont_send <= dont_send - 1;
end
+`endif
wire [11:0] mem_addr;
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];
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
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] = 3'd4; // OP_STOREI
+ 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;
reg [3:0] led_out;
- 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), .led_out(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;
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));
+ 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));
`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 = `STATE_IDLE;
+ reg [3:0] state = `STATE_IDLE;
- assign led[3:0] = led_out;
- assign led[4] = 0;
+ assign led[3:0] = uart_ptr;
+ assign led[4] = is_receiving;
always @ (posedge clk) begin
case(state)
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
transmit <= 0;
else if(uart_ptr == 4) begin
uart_ptr <= 0;
- the_leds <= last_op;
- if(last_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
else if(uart_ptr == 4) begin
uart_ptr <= 0;
state <= `STATE_IDLE;
- end else if(!is_transmitting && ready_in) begin
+ end else if(!is_transmitting && !dont_send) begin
tx_byte <= route_storei[uart_ptr];
transmit <= 1;
uart_ptr <= uart_ptr + 1;
end
endcase
end
-
-// wire ready = (state == 0 && !is_receiving);
endmodule