Add diagrams and pictures
[clump.git] / worker.v
index e8552d0b43b87f2629d7837bc7681d54c754701f..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 [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,7 +57,18 @@ 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
@@ -51,18 +77,17 @@ module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, out
    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;
@@ -70,19 +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));
+   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)
@@ -90,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
@@ -105,18 +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;
-                         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
@@ -130,7 +174,7 @@ module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, out
                   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;
@@ -138,6 +182,4 @@ module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, out
                end
          endcase
    end
-
-//   wire ready = (state == 0 && !is_receiving);
 endmodule
This page took 0.013647 seconds and 4 git commands to generate.