Add diagrams and pictures
[clump.git] / worker.v
index 7a5a909effeaf81f3396aa140c26f0271b3d466a..9e03d936f9a5a756fc8346e9c166b4e2fb8c272c 100644 (file)
--- 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 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 [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
This page took 0.012279 seconds and 4 git commands to generate.