| 1 | `include "pll.v" |
| 2 | `include "ram.v" |
| 3 | `include "chip.v" |
| 4 | `include "uart.v" |
| 5 | |
| 6 | `ifdef SIM |
| 7 | `define UART_DIVIDE 1 |
| 8 | `else |
| 9 | `define UART_DIVIDE 1024 |
| 10 | `endif |
| 11 | |
| 12 | 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); |
| 13 | wire clk = CLKin; |
| 14 | |
| 15 | `ifndef SIM |
| 16 | // if [is_worker == 0], boot into master image |
| 17 | SB_WARMBOOT wb (.BOOT (!is_worker), .S0(1'b1), .S1(1'b0)); |
| 18 | `endif |
| 19 | |
| 20 | `ifdef SIM |
| 21 | wire dont_send = 0; |
| 22 | `else |
| 23 | reg [25:0] dont_send = 23'b11111111111111111111111; |
| 24 | |
| 25 | always @(posedge clk) begin |
| 26 | if(busy_in) |
| 27 | dont_send <= 21'b111111111111111111111; |
| 28 | else if(dont_send) |
| 29 | dont_send <= dont_send - 1; |
| 30 | end |
| 31 | `endif |
| 32 | |
| 33 | wire [11:0] mem_addr; |
| 34 | wire [15:0] mem_in; |
| 35 | wire [15:0] mem_out; |
| 36 | wire mem_write; |
| 37 | |
| 38 | reg [31:0] the_rom [0:100]; |
| 39 | reg [10:0] rom_pc = 0; |
| 40 | |
| 41 | initial begin |
| 42 | the_rom[0] <= 32'hfC000005; |
| 43 | the_rom[1] <= 32'hfC010007; |
| 44 | the_rom[2] <= 32'hf9001d00; |
| 45 | the_rom[3] <= 32'hfA0112d0; |
| 46 | the_rom[4] <= 32'hfB000004; |
| 47 | the_rom[5] <= 32'hf9000004; |
| 48 | the_rom[6] <= 32'hfA001550; |
| 49 | the_rom[7] <= 32'hfB010000; |
| 50 | end |
| 51 | |
| 52 | RAM #(.ADDRESS_BITS(8)) ram (.clk(clk), .write(mem_write), .addr(mem_addr), .in(mem_in), .out(mem_out)); |
| 53 | |
| 54 | reg [7:0] from_uart [3:0]; |
| 55 | reg [2:0] uart_ptr = 0; |
| 56 | |
| 57 | wire [15:0] I = {from_uart[1], from_uart[0]}; |
| 58 | assign mem_addr = from_uart[2]; |
| 59 | wire [2:0] op_from_uart = from_uart[3][2:0]; |
| 60 | |
| 61 | wire [3:0] chip_select = from_uart[3][7:4]; |
| 62 | wire is_virtual = from_uart[3][3]; |
| 63 | wire dont_propagate = is_virtual || ~| chip_select; |
| 64 | wire not_for_us = !chip_select[0]; |
| 65 | |
| 66 | wire [7:0] to_uart [3:0]; |
| 67 | wire [3:0] next_chip_select = {0, chip_select[3:1]}; |
| 68 | assign to_uart[0] = from_uart[0]; |
| 69 | assign to_uart[1] = from_uart[1]; |
| 70 | assign to_uart[2] = from_uart[2]; |
| 71 | assign to_uart[3] = {next_chip_select, from_uart[3][3:0]}; |
| 72 | |
| 73 | /* to execute a ROUTE instruction, we send our neighbour a STOREI |
| 74 | /* instruction with the correct address and value. This is the |
| 75 | /* STOREI instruction. */ |
| 76 | wire [7:0] route_storei [3:0]; |
| 77 | assign route_storei[0] = mem_out[7:0]; |
| 78 | assign route_storei[1] = mem_out[15:8]; |
| 79 | assign route_storei[2] = from_uart[0]; |
| 80 | assign route_storei[3] = 8'h1C; // chip_select = 1, is_virtual = 1, op = OP_STOREI |
| 81 | |
| 82 | reg [2:0] op = 0; |
| 83 | |
| 84 | reg [2:0] last_op = 0; |
| 85 | |
| 86 | reg [15:0] I; |
| 87 | |
| 88 | reg [3:0] led_out; |
| 89 | |
| 90 | chip chip (.clk(clk), .op(op), .I(I), .mem_in(mem_in), .mem_out(mem_out), .mem_write(mem_write), .led_out(led_out)); |
| 91 | |
| 92 | wire received; |
| 93 | wire [7:0] rx_byte; |
| 94 | reg transmit = 0; |
| 95 | reg [7:0] tx_byte = 0; |
| 96 | wire is_receiving; |
| 97 | wire is_transmitting; |
| 98 | wire recv_error; |
| 99 | |
| 100 | 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)); |
| 101 | |
| 102 | `define STATE_IDLE 0 |
| 103 | `define STATE_PROPAGATE 1 |
| 104 | `define STATE_PREEXEC 2 |
| 105 | `define STATE_EXECUTE 3 |
| 106 | `define STATE_ROUTE 4 |
| 107 | |
| 108 | reg [3:0] state = `STATE_IDLE; |
| 109 | |
| 110 | assign led[3:0] = uart_ptr; |
| 111 | assign led[4] = is_receiving; |
| 112 | |
| 113 | always @ (posedge clk) begin |
| 114 | case(state) |
| 115 | `STATE_IDLE: begin |
| 116 | if(uart_ptr == 4) begin |
| 117 | last_op <= op_from_uart; |
| 118 | uart_ptr <= 0; |
| 119 | if(dont_propagate) |
| 120 | state <= `STATE_PREEXEC; |
| 121 | else |
| 122 | state <= `STATE_PROPAGATE; |
| 123 | busy_out <= 1; |
| 124 | end |
| 125 | else if (received) begin |
| 126 | from_uart[uart_ptr] <= rx_byte; |
| 127 | uart_ptr <= uart_ptr + 1; |
| 128 | end else begin |
| 129 | `ifdef SIM |
| 130 | from_uart[0] <= the_rom[rom_pc][7:0]; |
| 131 | from_uart[1] <= the_rom[rom_pc][15:8]; |
| 132 | from_uart[2] <= the_rom[rom_pc][23:16]; |
| 133 | from_uart[3] <= the_rom[rom_pc][31:24]; |
| 134 | uart_ptr <= 4; |
| 135 | rom_pc <= rom_pc + 1; |
| 136 | `else |
| 137 | busy_out <= 0; |
| 138 | `endif |
| 139 | end |
| 140 | end |
| 141 | |
| 142 | `STATE_PROPAGATE: begin |
| 143 | if(transmit) |
| 144 | transmit <= 0; |
| 145 | else if(uart_ptr == 4) begin |
| 146 | uart_ptr <= 0; |
| 147 | state <= `STATE_PREEXEC; |
| 148 | end else if(!is_transmitting && !dont_send) begin |
| 149 | tx_byte <= to_uart[uart_ptr]; |
| 150 | transmit <= 1; |
| 151 | uart_ptr <= uart_ptr + 1; |
| 152 | end |
| 153 | end // case: `STATE_PROPAGATE |
| 154 | |
| 155 | `STATE_PREEXEC: begin |
| 156 | if(not_for_us) begin |
| 157 | state <= `STATE_IDLE; |
| 158 | end else if(last_op == `OP_ROUTE) begin |
| 159 | state <= `STATE_ROUTE; |
| 160 | end else begin |
| 161 | op <= last_op; |
| 162 | state <= `STATE_EXECUTE; |
| 163 | end |
| 164 | end |
| 165 | |
| 166 | `STATE_EXECUTE: begin |
| 167 | op <= 0; |
| 168 | state <= `STATE_IDLE; |
| 169 | end |
| 170 | |
| 171 | `STATE_ROUTE: begin |
| 172 | if(transmit) |
| 173 | transmit <= 0; |
| 174 | else if(uart_ptr == 4) begin |
| 175 | uart_ptr <= 0; |
| 176 | state <= `STATE_IDLE; |
| 177 | end else if(!is_transmitting && !dont_send) begin |
| 178 | tx_byte <= route_storei[uart_ptr]; |
| 179 | transmit <= 1; |
| 180 | uart_ptr <= uart_ptr + 1; |
| 181 | end |
| 182 | end |
| 183 | endcase |
| 184 | end |
| 185 | endmodule |