implement routing + storei instruction
[clump.git] / worker.v
CommitLineData
3b542afc
MG
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 1
10 // s/192/3/ for 19200 baud uart
11`endif
12
13module worker (input CLKin, output [4:0] led, output uart_tx, input uart_rx, output reg ready_out = 1, input ready_in);
14 wire clk;
15 wire clk_tmp;
16
17 //pll pll (.clock_in(CLKin), .clock_out(clk));
18
19 reg [20:0] counter = 0;
20
21 reg clk = 0;
22
23 always @ (posedge CLKin) begin
24 if(counter == 5000) begin
25 counter <= 0;
26 clk <= 1 - clk;
27 end
28 else
29 counter <= counter + 1;
30 end
31
32 wire [11:0] mem_addr;
7f1b6bd9
MG
33 wire [15:0] mem_in;
34 wire [15:0] mem_out;
3b542afc
MG
35 wire mem_write;
36
37 RAM #(.ADDRESS_BITS(8)) ram (.clk(clk), .write(mem_write), .addr(mem_addr), .in(mem_in), .out(mem_out));
38
39 reg [7:0] from_uart [3:0];
40 reg [2:0] uart_ptr = 0;
41
42 wire [15:0] I = {from_uart[1], from_uart[0]};
43 assign mem_addr = from_uart[2];
44 wire [2:0] op_from_uart = from_uart[3][2:0];
45 wire CS = from_uart[3][3];
46
7f1b6bd9
MG
47 /* to execute a ROUTE instruction, we send our neighbour a STOREI
48 /* instruction with the correct address and value. This is the
49 /* STOREI instruction. */
50 wire [7:0] route_storei [3:0];
51 assign route_storei[0] = mem_out[7:0];
52 assign route_storei[1] = mem_out[15:8];
53 assign route_storei[2] = from_uart[0];
54 assign route_storei[3] = 3'd4; // OP_STOREI
55
3b542afc
MG
56 reg [2:0] op = 0;
57
58 reg [2:0] last_op = 0;
59
60 reg [15:0] I;
61 reg CS;
62
7f1b6bd9
MG
63 reg [3:0] led_out;
64
65 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));
3b542afc
MG
66
67 wire received;
68 wire [7:0] rx_byte;
69 reg transmit = 0;
70 reg [7:0] tx_byte = 0;
71 wire is_receiving;
72 wire is_transmitting;
73
74 // 19200 (actually 300) baud uart
75 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));
76
3b542afc
MG
77`define STATE_IDLE 0
78`define STATE_PROPAGATE 1
79`define STATE_EXECUTE 2
80`define STATE_ROUTE 3
81
7f1b6bd9 82 reg [5:0] state = `STATE_IDLE;
3b542afc 83
7f1b6bd9
MG
84 assign led[3:0] = led_out;
85 assign led[4] = 0;
3b542afc
MG
86
87 always @ (posedge clk) begin
88 case(state)
89 `STATE_IDLE: begin
90 if(uart_ptr == 4) begin
91 last_op <= op_from_uart;
92 uart_ptr <= 0;
93 state <= `STATE_PROPAGATE;
94 ready_out <= 0;
95 end
96 else if (received) begin
97 from_uart[uart_ptr] <= rx_byte;
98 uart_ptr <= uart_ptr + 1;
99 end else
100 ready_out <= 1;
101 end
102
103 `STATE_PROPAGATE: begin
104 if(transmit)
105 transmit <= 0;
106 else if(uart_ptr == 4) begin
107 uart_ptr <= 0;
7f1b6bd9
MG
108 the_leds <= last_op;
109 if(last_op == `OP_ROUTE) begin
3b542afc
MG
110 state <= `STATE_ROUTE;
111 end else begin
112 op <= last_op;
113 state <= `STATE_EXECUTE;
114 end
115 end else if(!is_transmitting && ready_in) begin
116 tx_byte <= from_uart[uart_ptr];
117 transmit <= 1;
118 uart_ptr <= uart_ptr + 1;
119 end
120 end
121
122 `STATE_EXECUTE: begin
123 op <= 0;
124 state <= `STATE_IDLE;
125 end
126
127 `STATE_ROUTE: begin
7f1b6bd9
MG
128 if(transmit)
129 transmit <= 0;
130 else if(uart_ptr == 4) begin
131 uart_ptr <= 0;
132 state <= `STATE_IDLE;
133 end else if(!is_transmitting && ready_in) begin
134 tx_byte <= route_storei[uart_ptr];
135 transmit <= 1;
136 uart_ptr <= uart_ptr + 1;
137 end
3b542afc
MG
138 end
139 endcase
3b542afc
MG
140 end
141
7f1b6bd9 142// wire ready = (state == 0 && !is_receiving);
3b542afc 143endmodule
This page took 0.018074 seconds and 4 git commands to generate.