summaryrefslogtreecommitdiff
path: root/hdl/top.sv
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-02-16 14:25:06 -0800
committerJulian Blake Kongslie2022-02-16 14:25:06 -0800
commit7ebfec600044d050477b650abc775a81f5d037d8 (patch)
tree2d93a9b02023cdb45baea825a09a070e993ce788 /hdl/top.sv
parentInitial commit. (diff)
downloadsimple-memory-controller-7ebfec600044d050477b650abc775a81f5d037d8.tar.xz
Complete rewrite to break out the separate state machines and fix timing
Diffstat (limited to 'hdl/top.sv')
-rw-r--r--hdl/top.sv669
1 files changed, 509 insertions, 160 deletions
diff --git a/hdl/top.sv b/hdl/top.sv
index babdc95..fee1b68 100644
--- a/hdl/top.sv
+++ b/hdl/top.sv
@@ -1,193 +1,542 @@
1module top 1module command_parser
2 ( input bit clock 2 ( input bit clock
3 , input bit resetn 3 , input bit resetn
4 4
5 , output bit ramresetn 5 , output bit uart_ready
6 , output bit [1:0] ramcsn 6 , input bit uart_valid
7 , output bit ramclkp 7 , input bit [7:0] uart_data
8 , output bit ramclkn 8
9 , input bit ramrwds 9 , input bit echo_ready
10 , inout bit [7:0] ramdata 10 , output bit echo_valid
11 , output bit [7:0] echo_data
12
13 , input bit command_ready
14 , output bit command_valid
15 , output bit [23:0] command_address
16 , output bit command_write
17 , output bit [15:0] command_data
11 ); 18 );
12 19
13assign ramresetn = resetn; 20 bit input_byte_valid;
14assign ramclkn = !ramclkp; 21 bit [7:0] input_byte;
15 22
16bit ram_data_oe; 23 enum
17bit [7:0] ram_send_data; 24 { READ_ADDRESS_OR_COMMAND
25 , READ_DATA_1
26 , READ_DATA_2
27 , READ_DATA_3
28 , READ_DATA_4
29 } state;
18 30
19assign ramdata = ram_data_oe ? ram_send_data : 8'bZ; 31 always @(posedge clock) begin
32 if (!resetn) begin
33 uart_ready = 0;
34 command_valid = 0;
35 command_address = 0;
36 command_write = 0;
37 command_data = 0;
38 input_byte_valid = 0;
39 input_byte = 0;
40 state = state.first;
41 end else begin
42 if (echo_ready) echo_valid = 0;
43 if (command_ready) command_valid = 0;
44 if (uart_ready && uart_valid) begin
45 echo_valid = 1;
46 echo_data = uart_data;
47 input_byte_valid = 1;
48 input_byte = uart_data;
49 end
20 50
21bit rx_ready; 51 if (!command_valid && input_byte_valid) begin
22bit rx_valid; 52 case (state)
23bit [7:0] rx_data; 53 READ_ADDRESS_OR_COMMAND: begin
54 if (input_byte >= "0" && input_byte <= "9") begin
55 command_address = command_address << 4;
56 command_address[3:0] = input_byte - "0";
57 end else if (input_byte >= "a" && input_byte <= "f") begin
58 command_address = command_address << 4;
59 command_address[3:0] = input_byte - "a" + 10;
60 end else if (input_byte >= "A" && input_byte <= "F") begin
61 command_address = command_address << 4;
62 command_address[3:0] = input_byte - "A" + 10;
63 end else if (input_byte == "?") begin
64 command_valid = 1;
65 command_write = 0;
66 command_data = 0;
67 end else if (input_byte == "=") begin
68 command_write = 1;
69 command_data = 0;
70 state = READ_DATA_1;
71 end
72 end
73 READ_DATA_1, READ_DATA_2, READ_DATA_3, READ_DATA_4: begin
74 if (input_byte >= "0" && input_byte <= "9") begin
75 command_data = command_data << 4;
76 command_data[3:0] = input_byte - "0";
77 state = state.next;
78 end else if (input_byte >= "a" && input_byte <= "f") begin
79 command_data = command_data << 4;
80 command_data[3:0] = input_byte - "a" + 10;
81 state = state.next;
82 end else if (input_byte >= "A" && input_byte <= "F") begin
83 command_data = command_data << 4;
84 command_data[3:0] = input_byte - "A" + 10;
85 state = state.next;
86 end else begin
87 state = state.first;
88 end
89 command_valid = state == state.first;
90 end
91 endcase
92 input_byte_valid = 0;
93 end
24 94
25bit tx_ready; 95 uart_ready = !echo_valid && !input_byte_valid;
26bit tx_valid; 96 end
27bit [7:0] tx_data; 97 end
28 98
29alt_jtag_atlantic 99endmodule
30 #( .INSTANCE_ID(0) 100
31 , .LOG2_RXFIFO_DEPTH(6) 101module echo_arbiter
32 , .LOG2_TXFIFO_DEPTH(6) 102 ( input bit clock
33 , .SLD_AUTO_INSTANCE_INDEX("NO") 103 , input bit resetn
34 ) jtag 104
35 ( .clk(clock) 105 , output bit in0_ready
36 , .rst_n(resetn) 106 , input bit in0_valid
37 , .r_dat(tx_data) 107 , input bit [7:0] in0_data
38 , .r_val(tx_valid) 108
39 , .r_ena(tx_ready) 109 , output bit in1_ready
40 , .t_dat(rx_data) 110 , input bit in1_valid
41 , .t_dav(rx_ready) 111 , input bit [7:0] in1_data
42 , .t_ena(rx_valid) 112
113 , input bit out_ready
114 , output bit out_valid
115 , output bit [7:0] out_data
43 ); 116 );
44 117
45bit input_byte_valid; 118 bit in0_hold_valid;
46bit [7:0] input_byte; 119 bit [7:0] in0_hold;
47 120
48bit [22:0] address; 121 bit in1_hold_valid;
49bit [7:0] data; 122 bit [7:0] in1_hold;
50bit write;
51 123
52bit [47:0] command; 124 always @(posedge clock) begin
125 if (!resetn) begin
126 in0_ready = 0;
127 in1_ready = 0;
128 out_valid = 0;
129 out_data = 0;
130 in0_hold_valid = 0;
131 in0_hold = 0;
132 in1_hold_valid = 0;
133 in1_hold = 0;
134 end else begin
135 if (out_ready) out_valid = 0;
136 if (in0_ready && in0_valid) begin
137 in0_hold_valid = 1;
138 in0_hold = in0_data;
139 end
140 if (in1_ready && in1_valid) begin
141 in1_hold_valid = 1;
142 in1_hold = in1_data;
143 end
53 144
54enum 145 if (!out_valid) begin
55 { UART_READ_ADDRESS_OR_COMMAND 146 if (in0_hold_valid) begin
56 , UART_READ_DATA_1 147 out_valid = 1;
57 , UART_READ_DATA_0 148 out_data = in0_hold;
58 , RAM_WAIT_READY 149 in0_hold_valid = 0;
59 , RAM_SEND_COMMAND_5 150 end else if (in1_hold_valid) begin
60 , RAM_SEND_COMMAND_4 151 out_valid = 1;
61 , RAM_SEND_COMMAND_3 152 out_data = in1_hold;
62 , RAM_SEND_COMMAND_2 153 in1_hold_valid = 0;
63 , RAM_SEND_COMMAND_1 154 end
64 , RAM_SEND_COMMAND_0 155 end
65 , RAM_INIT_WAIT_DATA
66 , RAM_WAIT_DATA
67 , RAM_SENDRECV_DATA
68 , UART_WRITE_DATA_1
69 , UART_WRITE_DATA_0
70 } state;
71 156
72always @(posedge clock) begin 157 in0_ready = !in0_hold_valid;
73 if (!resetn) begin 158 in1_ready = !in1_hold_valid;
74 ramcsn[0] = 1;
75 ramcsn[1] = 1;
76 ramclkp = 0;
77 ram_data_oe = 0;
78 rx_ready = 0;
79 tx_valid = 0;
80 input_byte_valid = 0;
81 address = 0;
82 state = state.first;
83 end else begin
84 if (tx_ready) tx_valid = 0;
85 if (rx_valid && !input_byte_valid && !tx_valid) begin
86 tx_valid = 1;
87 tx_data = rx_data;
88 input_byte_valid = 1;
89 input_byte = rx_data;
90 end 159 end
91 case (state) 160 end
92 UART_READ_ADDRESS_OR_COMMAND: 161
93 if (input_byte_valid) begin 162endmodule
94 if (input_byte >= "0" && input_byte <= "9") begin 163
95 address = address << 4; 164module ram_controller
96 address[3:0] = input_byte - "0"; 165 ( input bit clock
97 end else if (input_byte >= "a" && input_byte <= "f") begin 166 , input bit resetn
98 address = address << 4; 167
99 address[3:0] = input_byte - "a" + 10; 168 , output bit command_ready
100 end else if (input_byte >= "A" && input_byte <= "F") begin 169 , input bit command_valid
101 address = address << 4; 170 , input bit [23:0] command_address
102 address[3:0] = input_byte - "A" + 10; 171 , input bit command_write
103 end else if (input_byte == "?") begin 172 , input bit [15:0] command_data
104 write = 0; 173
105 command = {12'b100000000000, address[22:3], 13'b0, address[2:0]}; 174 , input bit result_ready
106 address = 0; 175 , output bit result_valid
107 data = 0; 176 , output bit [15:0] result_data
108 state = RAM_SEND_COMMAND_5; 177
109 end else if (input_byte == "=") begin 178 , output bit ram_resetn
110 write = 1; 179 , output bit [1:0] ram_csn
111 command = {12'b000000000000, address[22:3], 13'b0, address[2:0]}; 180 , output bit ram_clkp
112 address = 0; 181 , output bit ram_clkn
113 data = 0; 182 , output bit ram_rwds_oe
114 state = UART_READ_DATA_1; 183 , input bit ram_rwds_in
115 end 184 , output bit ram_rwds_out
116 input_byte_valid = 0; 185 , output bit ram_data_oe
186 , input bit [7:0] ram_data_in
187 , output bit [7:0] ram_data_out
188 );
189
190 assign ram_clkn = !ram_clkp;
191
192 bit valid;
193 bit [23:0] address;
194 bit write;
195 bit [15:0] data;
196
197 int reset_counter;
198
199 bit slow;
200
201 enum
202 { SEND_COMMAND_1
203 , SEND_COMMAND_2
204 , SEND_COMMAND_3
205 , SEND_COMMAND_4
206 , SEND_COMMAND_5
207 , SEND_COMMAND_6
208
209 , LAT2_CYC1
210 , LAT2_CYC2
211 , LAT2_CYC3
212 , LAT2_CYC4
213 , LAT2_CYC5
214 , LAT2_CYC6
215
216 , LAT1_CYC1
217 , LAT1_CYC2
218 , LAT1_CYC3
219 , LAT1_CYC4
220 // Latency blocks are 6 cycle, but they start in the SEND_COMMAND_5 cycle, so block 1 is only 4 real cycles
221 //, LAT1_CYC5
222 //, LAT1_CYC6
223
224 , DATA_1
225 , DATA_2
226 } state;
227
228 always @(posedge clock) begin
229 if (!resetn || reset_counter != 0) begin
230 command_ready = 0;
231 result_valid = 0;
232 result_data = 0;
233 ram_resetn = 0;
234 ram_csn[0] = 1;
235 ram_csn[1] = 1;
236 ram_clkp = 0;
237 ram_rwds_oe = 0;
238 ram_rwds_out = 0;
239 ram_data_oe = 0;
240 ram_data_out = 0;
241 valid = 0;
242 address = 0;
243 write = 0;
244 data = 0;
245 if (!resetn)
246 reset_counter = 5; // Spec wants >= 100ns of reset
247 else
248 reset_counter = reset_counter - 1;
249 slow = 0;
250 state = state.first;
251 end else begin
252 ram_resetn = 1;
253 ram_rwds_oe = 0;
254 ram_data_oe = 0;
255 if (result_ready) result_valid = 0;
256 if (command_ready && command_valid) begin
257 valid = 1;
258 address = command_address;
259 write = command_write;
260 data = command_data;
261 state = state.first;
117 end 262 end
118 UART_READ_DATA_1, UART_READ_DATA_0: 263
119 if (input_byte_valid) begin 264 if (!valid) begin
120 if (input_byte >= "0" && input_byte <= "9") begin 265 ram_csn[0] = 1;
121 data = data << 4; 266 ram_csn[1] = 1;
122 data[3:0] = input_byte - "0"; 267 ram_clkp = 0;
268 end else begin
269 case (state)
270 SEND_COMMAND_1: begin
271 ram_clkp = 0;
272 ram_csn[address[23]] = 0;
273 ram_data_oe = 1;
274 ram_data_out = {!write, 1'b0, 1'b0, 5'b0}; // R/W# AS BURST RESERVED
123 state = state.next; 275 state = state.next;
124 end else if (input_byte >= "a" && input_byte <= "f") begin 276 end
125 data = data << 4; 277 SEND_COMMAND_2: begin
126 data[3:0] = input_byte - "a" + 10; 278 ram_clkp = 1;
279 ram_data_oe = 1;
280 ram_data_out = {4'b0, address[22:19]}; // RESERVED ROW
127 state = state.next; 281 state = state.next;
128 end else if (input_byte >= "A" && input_byte <= "F") begin 282 end
129 data = data << 4; 283 SEND_COMMAND_3: begin
130 data[3:0] = input_byte - "A" + 10; 284 ram_clkp = 0;
285 ram_data_oe = 1;
286 ram_data_out = {address[18:11]}; // ROW
131 state = state.next; 287 state = state.next;
132 end 288 end
133 input_byte_valid = 0; 289 SEND_COMMAND_4: begin
134 end 290 ram_clkp = 1;
135 RAM_WAIT_READY: 291 ram_data_oe = 1;
136 begin 292 ram_data_out = {address[10:9], address[8:3]}; // ROW UPPERCOL
137 ramcsn[0] = 0; 293 slow = ram_rwds_in; // Sort of arbitrarily capturing RWDS in the middle of the command string
138 if (ramrwds) state = state.next; 294 state = state.next;
139 end 295 end
140 RAM_SEND_COMMAND_5, RAM_SEND_COMMAND_4, RAM_SEND_COMMAND_3, RAM_SEND_COMMAND_2, RAM_SEND_COMMAND_1, RAM_SEND_COMMAND_0: 296 SEND_COMMAND_5: begin
141 begin 297 ram_clkp = 0;
142 ramclkp = ~ramclkp; 298 ram_data_oe = 1;
143 ram_data_oe = 1; 299 ram_data_out = {8'b0}; // RESERVED
144 ram_send_data = command[47:40]; 300 state = state.next;
145 command = command << 8; 301 end
146 state = state.next; 302 SEND_COMMAND_6: begin
147 end 303 ram_clkp = 1;
148 RAM_INIT_WAIT_DATA: 304 ram_data_oe = 1;
149 begin 305 ram_data_out = {5'b0, address[2:0]}; // RESERVED LOWERCOL
150 ramclkp = ~ramclkp; 306 if (slow)
151 ram_data_oe = 0; 307 state = LAT2_CYC1;
152 state = state.next; 308 else
153 end 309 state = LAT1_CYC1;
154 RAM_WAIT_DATA: 310 end
155 begin 311 LAT2_CYC1, LAT2_CYC2, LAT2_CYC3, LAT2_CYC4, LAT2_CYC5, LAT2_CYC6,
156 ramclkp = ~ramclkp; 312 LAT1_CYC1, LAT1_CYC2, LAT1_CYC3, LAT1_CYC4: begin
157 if (ramrwds) begin 313 ram_clkp = !ram_clkp;
314 state = state.next;
315 end
316 DATA_1, DATA_2: begin
317 ram_clkp = !ram_clkp;
158 if (write) begin 318 if (write) begin
319 ram_rwds_oe = 1;
320 ram_rwds_out = 1;
159 ram_data_oe = 1; 321 ram_data_oe = 1;
160 ram_send_data = data; 322 ram_data_out = data[7:0];
323 data = data >> 8;
324 state = state.next;
325 end else if (ram_rwds_in) begin
326 data = data << 8;
327 data[7:0] = ram_data_in;
328 state = state.next;
329 end
330 if (state == state.first) begin
331 valid = 0;
332 if (!write) begin
333 result_valid = 1;
334 result_data = data;
335 end
161 end 336 end
162 state = state.next;
163 end 337 end
338 endcase
164 end 339 end
165 RAM_SENDRECV_DATA: 340
166 begin 341 command_ready = !valid && !result_valid;
167 ramclkp = ~ramclkp; 342 end
168 ramcsn[0] = 1; 343 end
169 ram_data_oe = 0; 344
170 if (write) begin 345endmodule
171 state = state.first; 346
172 end else begin 347module result_printer
173 data = ramdata; 348 ( input bit clock
174 state = UART_WRITE_DATA_1; 349 , input bit resetn
175 end 350
351 , output bit result_ready
352 , input bit result_valid
353 , input bit [15:0] result_data
354
355 , input bit echo_ready
356 , output bit echo_valid
357 , output bit [7:0] echo_data
358 );
359
360 bit hold_valid;
361 bit [15:0] hold;
362
363 enum
364 { DIGIT_1
365 , DIGIT_2
366 , DIGIT_3
367 , DIGIT_4
368 } state;
369
370 always @(posedge clock) begin
371 if (!resetn) begin
372 result_ready = 0;
373 echo_valid = 0;
374 echo_data = 0;
375 hold_valid = 0;
376 hold = 0;
377 state = state.first;
378 end else begin
379 if (echo_ready) echo_valid = 0;
380 if (result_ready && result_valid) begin
381 hold_valid = 1;
382 hold = result_data;
176 end 383 end
177 UART_WRITE_DATA_1, UART_WRITE_DATA_0: 384
178 if (!tx_valid) begin 385 if (hold_valid && !echo_valid) begin
179 tx_valid = 1; 386 echo_valid = 1;
180 if (data[7:4] < 10) begin 387 echo_data = hold[15:12];
181 tx_data = data[7:4] + "0"; 388 hold = hold << 4;
182 end else begin 389 if (echo_data < 10)
183 tx_data = data[7:4] + "A" - 10; 390 echo_data = echo_data + "0";
184 end 391 else
185 data = data << 4; 392 echo_data = echo_data + "A" - 10;
186 state = state.next; 393 state = state.next;
394 if (state == state.first) hold_valid = 0;
187 end 395 end
188 endcase 396
189 rx_ready = !input_byte_valid && !tx_valid; 397 result_ready = !hold_valid;
398 end
190 end 399 end
191end 400
401endmodule
402
403module top
404 ( input bit clock
405 , input bit resetn
406
407 , output bit ram_resetn
408 , output bit [1:0] ram_csn
409 , output bit ram_clkp
410 , output bit ram_clkn
411 , inout bit ram_rwds
412 , inout bit [7:0] ram_data
413 );
414
415 bit rx_ready;
416 bit rx_valid;
417 bit [7:0] rx_data;
418
419 bit tx_ready;
420 bit tx_valid;
421 bit [7:0] tx_data;
422
423 alt_jtag_atlantic
424 #( .INSTANCE_ID(0)
425 , .LOG2_RXFIFO_DEPTH(6)
426 , .LOG2_TXFIFO_DEPTH(6)
427 , .SLD_AUTO_INSTANCE_INDEX("NO")
428 ) jtag
429 ( .clk(clock)
430 , .rst_n(resetn)
431
432 , .r_dat(tx_data)
433 , .r_val(tx_valid)
434 , .r_ena(tx_ready)
435
436 , .t_dat(rx_data)
437 , .t_dav(rx_ready)
438 , .t_ena(rx_valid)
439 );
440
441 bit echo_in0_ready;
442 bit echo_in0_valid;
443 bit [7:0] echo_in0_data;
444
445 bit echo_in1_ready;
446 bit echo_in1_valid;
447 bit [7:0] echo_in1_data;
448
449 echo_arbiter arb
450 ( .clock(clock)
451 , .resetn(resetn)
452
453 , .in0_ready(echo_in0_ready)
454 , .in0_valid(echo_in0_valid)
455 , .in0_data(echo_in0_data)
456
457 , .in1_ready(echo_in1_ready)
458 , .in1_valid(echo_in1_valid)
459 , .in1_data(echo_in1_data)
460
461 , .out_ready(tx_ready)
462 , .out_valid(tx_valid)
463 , .out_data(tx_data)
464 );
465
466 bit command_ready;
467 bit command_valid;
468 bit [23:0] command_address;
469 bit command_write;
470 bit [15:0] command_data;
471
472 command_parser parser
473 ( .clock(clock)
474 , .resetn(resetn)
475
476 , .uart_ready(rx_ready)
477 , .uart_valid(rx_valid)
478 , .uart_data(rx_data)
479
480 , .echo_ready(echo_in0_ready)
481 , .echo_valid(echo_in0_valid)
482 , .echo_data(echo_in0_data)
483
484 , .command_ready(command_ready)
485 , .command_valid(command_valid)
486 , .command_address(command_address)
487 , .command_write(command_write)
488 , .command_data(command_data)
489 );
490
491 bit result_ready;
492 bit result_valid;
493 bit [15:0] result_data;
494
495 bit ram_rwds_oe;
496 bit ram_rwds_out;
497 assign ram_rwds = ram_rwds_oe ? ram_rwds_out : 'bZ;
498
499 bit ram_data_oe;
500 bit [7:0] ram_data_out;
501 assign ram_data = ram_data_oe ? ram_data_out : 'bZ;
502
503 ram_controller ram
504 ( .clock(clock)
505 , .resetn(resetn)
506
507 , .command_ready(command_ready)
508 , .command_valid(command_valid)
509 , .command_address(command_address)
510 , .command_write(command_write)
511 , .command_data(command_data)
512
513 , .result_ready(result_ready)
514 , .result_valid(result_valid)
515 , .result_data(result_data)
516
517 , .ram_resetn(ram_resetn)
518 , .ram_csn(ram_csn)
519 , .ram_clkp(ram_clkp)
520 , .ram_clkn(ram_clkn)
521 , .ram_rwds_oe(ram_rwds_oe)
522 , .ram_rwds_in(ram_rwds)
523 , .ram_rwds_out(ram_rwds_out)
524 , .ram_data_oe(ram_data_oe)
525 , .ram_data_in(ram_data)
526 , .ram_data_out(ram_data_out)
527 );
528
529 result_printer print
530 ( .clock(clock)
531 , .resetn(resetn)
532
533 , .result_ready(result_ready)
534 , .result_valid(result_valid)
535 , .result_data(result_data)
536
537 , .echo_ready(echo_in1_ready)
538 , .echo_valid(echo_in1_valid)
539 , .echo_data(echo_in1_data)
540 );
192 541
193endmodule 542endmodule