Add ability to override verilog mode for verific -f command
[yosys.git] / tests / opt / memory_dff_trans.ys
1 # Good case 1: single port.
2
3 read_verilog << EOT
4
5 module top(
6 input [3:0] addr,
7 input [3:0] wd,
8 input we,
9 input clk,
10 output reg [3:0] rd,
11 );
12
13 reg [3:0] mem[0:15];
14
15 always @(posedge clk) begin
16 if (we) begin
17 mem[addr] <= wd;
18 rd <= wd;
19 end else begin
20 rd <= mem[addr];
21 end
22 end
23
24 endmodule
25
26 EOT
27
28 hierarchy -auto-top
29 proc
30 opt_dff
31 opt_clean
32 memory_dff
33 memory_collect
34 select -assert-count 1 t:$mem_v2
35 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=1'b1 r:RD_COLLISION_X_MASK=1'b0 %i %i
36
37 design -reset
38
39 # Good case 2: single port, exclusive.
40
41 read_verilog << EOT
42
43 module top(
44 input [3:0] addr,
45 input [3:0] wd,
46 input we,
47 input clk,
48 output reg [3:0] rd,
49 );
50
51 reg [3:0] mem[0:15];
52
53 always @(posedge clk) begin
54 if (we) begin
55 mem[addr] <= wd;
56 end else begin
57 rd <= mem[addr];
58 end
59 end
60
61 endmodule
62
63 EOT
64
65 hierarchy -auto-top
66 proc
67 opt_dff
68 opt_clean
69 memory_dff
70 memory_collect
71 select -assert-count 1 t:$mem_v2
72 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=1'b0 r:RD_COLLISION_X_MASK=1'b1 %i %i
73
74 design -reset
75
76 # Good case 3: proper bypass muxes.
77
78 read_verilog << EOT
79
80 module top(
81 input [3:0] ra,
82 input [3:0] wa1,
83 input [3:0] wa2,
84 input [3:0] wd1,
85 input [3:0] wd2,
86 input we1, we2,
87 input re,
88 input clk,
89 output reg [3:0] rd,
90 );
91
92 reg [3:0] mem[0:15];
93
94 always @(posedge clk) begin
95 if (we1)
96 mem[wa1] <= wd1;
97 if (we2)
98 mem[wa2] <= wd2;
99 if (re) begin
100 rd <= mem[ra];
101 if (we1 && wa1 == ra)
102 rd <= wd1;
103 if (we2 && wa2 == ra)
104 rd <= wd2;
105 end
106 end
107
108 endmodule
109
110 EOT
111
112 hierarchy -auto-top
113 proc
114 opt_dff
115 opt_clean
116 memory_dff
117 memory_collect
118 select -assert-count 1 t:$mem_v2
119 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b11 r:RD_COLLISION_X_MASK=2'b00 %i %i
120
121 design -reset
122
123 # Good case 4: proper bypass mux, but only one.
124
125 read_verilog << EOT
126
127 module top(
128 input [3:0] ra,
129 input [3:0] wa1,
130 input [3:0] wa2,
131 input [3:0] wd1,
132 input [3:0] wd2,
133 input we1, we2,
134 input re,
135 input clk,
136 output reg [3:0] rd,
137 );
138
139 reg [3:0] mem[0:15];
140
141 always @(posedge clk) begin
142 if (we1)
143 mem[wa1] <= wd1;
144 if (we2)
145 mem[wa2] <= wd2;
146 if (re) begin
147 rd <= mem[ra];
148 if (we1 && wa1 == ra)
149 rd <= wd1;
150 end
151 end
152
153 endmodule
154
155 EOT
156
157 hierarchy -auto-top
158 proc
159 opt_dff
160 opt_clean
161 memory_dff
162 memory_collect
163 select -assert-count 1 t:$mem_v2
164 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b01 r:RD_COLLISION_X_MASK=2'b00 %i %i
165
166 design -reset
167
168 # Good case 5: proper bypass mux, but the other one.
169
170 read_verilog << EOT
171
172 module top(
173 input [3:0] ra,
174 input [3:0] wa1,
175 input [3:0] wa2,
176 input [3:0] wd1,
177 input [3:0] wd2,
178 input we1, we2,
179 input re,
180 input clk,
181 output reg [3:0] rd,
182 );
183
184 reg [3:0] mem[0:15];
185
186 always @(posedge clk) begin
187 if (we1)
188 mem[wa1] <= wd1;
189 if (we2)
190 mem[wa2] <= wd2;
191 if (re) begin
192 rd <= mem[ra];
193 if (we2 && wa2 == ra)
194 rd <= wd2;
195 end
196 end
197
198 endmodule
199
200 EOT
201
202 hierarchy -auto-top
203 proc
204 opt_dff
205 opt_clean
206 memory_dff
207 memory_collect
208 select -assert-count 1 t:$mem_v2
209 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b10 r:RD_COLLISION_X_MASK=2'b00 %i %i
210
211 design -reset
212
213 # Good case 6: 'x mux.
214
215 read_verilog << EOT
216
217 module top(
218 input [3:0] ra,
219 input [3:0] wa1,
220 input [3:0] wa2,
221 input [3:0] wd1,
222 input [3:0] wd2,
223 input we1, we2,
224 input re,
225 input clk,
226 output reg [3:0] rd,
227 );
228
229 reg [3:0] mem[0:15];
230
231 always @(posedge clk) begin
232 if (we1)
233 mem[wa1] <= wd1;
234 if (we2)
235 mem[wa2] <= wd2;
236 if (re) begin
237 rd <= mem[ra];
238 if (we1 && wa1 == ra)
239 rd <= 4'hx;
240 if (we2 && wa2 == ra)
241 rd <= wd2;
242 end
243 end
244
245 endmodule
246
247 EOT
248
249 hierarchy -auto-top
250 proc
251 opt_dff
252 opt_clean
253 memory_dff
254 memory_collect
255 select -assert-count 1 t:$mem_v2
256 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b10 r:RD_COLLISION_X_MASK=2'b01 %i %i
257
258 design -reset
259
260 # Good case 7: uncollidable addresses.
261
262 read_verilog << EOT
263
264 module top(
265 input [3:0] addr,
266 input [3:0] wd1,
267 input [3:0] wd2,
268 input we1, we2,
269 input re,
270 input clk,
271 output reg [3:0] rd,
272 );
273
274 reg [3:0] mem[0:15];
275
276 wire [3:0] wa1 = addr;
277 wire [3:0] wa2 = addr + 1;
278 wire [3:0] ra = addr + 2;
279
280 always @(posedge clk) begin
281 if (we1)
282 mem[wa1] <= wd1;
283 if (we2)
284 mem[wa2] <= wd2;
285 if (re) begin
286 rd <= mem[ra];
287 end
288 end
289
290 endmodule
291
292 EOT
293
294 hierarchy -auto-top
295 proc
296 opt_dff
297 opt_clean
298 memory_dff
299 memory_collect
300 select -assert-count 1 t:$mem_v2
301 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b00 r:RD_COLLISION_X_MASK=2'b11 %i %i
302
303 design -reset
304
305 # Good case 8: uncollidable addresses, but still have soft transparency logic.
306
307 read_verilog << EOT
308
309 module top(
310 input [3:0] addr,
311 input [3:0] wd1,
312 input [3:0] wd2,
313 input we1, we2,
314 input re,
315 input clk,
316 output reg [3:0] rd,
317 );
318
319 reg [3:0] mem[0:15];
320
321 wire [3:0] wa1 = addr;
322 wire [3:0] wa2 = addr + 1;
323 wire [3:0] ra = addr + 2;
324
325 always @(posedge clk) begin
326 if (we1)
327 mem[wa1] <= wd1;
328 if (we2)
329 mem[wa2] <= wd2;
330 if (re) begin
331 rd <= mem[ra];
332 if (we1 && wa1 == ra)
333 rd <= wd1;
334 if (we2 && wa2 == ra)
335 rd <= wd2;
336 end
337 end
338
339 endmodule
340
341 EOT
342
343 hierarchy -auto-top
344 proc
345 opt_dff
346 opt_clean
347 memory_dff
348 memory_collect
349 select -assert-count 1 t:$mem_v2
350 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b00 r:RD_COLLISION_X_MASK=2'b11 %i %i
351
352 design -reset
353
354 # Bad case 1: broken bypass signal.
355
356 read_verilog << EOT
357
358 module top(
359 input [3:0] ra,
360 input [3:0] wa1,
361 input [3:0] wa2,
362 input [3:0] wd1,
363 input [3:0] wd2,
364 input we1, we2,
365 input re,
366 input clk,
367 output reg [3:0] rd,
368 );
369
370 reg [3:0] mem[0:15];
371
372 always @(posedge clk) begin
373 if (we1)
374 mem[wa1] <= wd1;
375 if (we2)
376 mem[wa2] <= wd2;
377 if (re) begin
378 rd <= mem[ra];
379 if (we1 && wa1 == ra)
380 rd <= wd1;
381 if (we2 && wa2 == ra && we1)
382 rd <= wd2;
383 end
384 end
385
386 endmodule
387
388 EOT
389
390 hierarchy -auto-top
391 proc
392 opt_dff
393 opt_clean
394 logger -expect log "FF found, but with a mux select that doesn't seem to correspond to transparency logic" 1
395 memory_dff
396 logger -check-expected
397 memory_collect
398 select -assert-count 1 t:$mem_v2
399 select -assert-count 1 t:$mem_v2 r:RD_CLK_ENABLE=1'b0 %i
400
401 design -reset
402
403 # Bad case 2: bad data signal.
404
405 read_verilog << EOT
406
407 module top(
408 input [3:0] ra,
409 input [3:0] wa1,
410 input [3:0] wa2,
411 input [3:0] wd1,
412 input [3:0] wd2,
413 input we1, we2,
414 input re,
415 input clk,
416 output reg [3:0] rd,
417 );
418
419 reg [3:0] mem[0:15];
420
421 always @(posedge clk) begin
422 if (we1)
423 mem[wa1] <= wd1;
424 if (we2)
425 mem[wa2] <= wd2;
426 if (re) begin
427 rd <= mem[ra];
428 if (we1 && wa1 == ra)
429 rd <= wd1;
430 if (we2 && wa2 == ra)
431 rd <= wd1;
432 end
433 end
434
435 endmodule
436
437 EOT
438
439 hierarchy -auto-top
440 proc
441 opt_dff
442 opt_clean
443 logger -expect log "FF found, but with a mux data input that doesn't seem to correspond to transparency logic" 1
444 memory_dff
445 logger -check-expected
446 memory_collect
447 select -assert-count 1 t:$mem_v2
448 select -assert-count 1 t:$mem_v2 r:RD_CLK_ENABLE=1'b0 %i
449
450 design -reset
451
452 # Bad case 3: priority mismatch.
453
454 read_verilog << EOT
455
456 module top(
457 input [3:0] ra,
458 input [3:0] wa1,
459 input [3:0] wa2,
460 input [3:0] wd1,
461 input [3:0] wd2,
462 input we1, we2,
463 input re,
464 input clk,
465 output reg [3:0] rd,
466 );
467
468 reg [3:0] mem[0:15];
469
470 always @(posedge clk) begin
471 if (we1)
472 mem[wa1] <= wd1;
473 if (we2)
474 mem[wa2] <= wd2;
475 if (re) begin
476 rd <= mem[ra];
477 if (we2 && wa2 == ra)
478 rd <= wd2;
479 if (we1 && wa1 == ra)
480 rd <= wd1;
481 end
482 end
483
484 endmodule
485
486 EOT
487
488 hierarchy -auto-top
489 proc
490 opt_dff
491 opt_clean
492 logger -expect log "FF found, but transparency logic priority doesn't match write priority." 1
493 memory_dff
494 logger -check-expected
495 memory_collect
496 select -assert-count 1 t:$mem_v2
497 select -assert-count 1 t:$mem_v2 r:RD_CLK_ENABLE=1'b0 %i
498
499 design -reset
500
501 # Good case 10: priority mismatch, but since the second value is 'x, it's still OK.
502
503 read_verilog << EOT
504
505 module top(
506 input [3:0] ra,
507 input [3:0] wa1,
508 input [3:0] wa2,
509 input [3:0] wd1,
510 input [3:0] wd2,
511 input we1, we2,
512 input re,
513 input clk,
514 output reg [3:0] rd,
515 );
516
517 reg [3:0] mem[0:15];
518
519 always @(posedge clk) begin
520 if (we1)
521 mem[wa1] <= wd1;
522 if (we2)
523 mem[wa2] <= wd2;
524 if (re) begin
525 rd <= mem[ra];
526 if (we2 && wa2 == ra)
527 rd <= wd2;
528 if (we1 && wa1 == ra)
529 rd <= 4'hx;
530 end
531 end
532
533 endmodule
534
535 EOT
536
537 hierarchy -auto-top
538 proc
539 opt_dff
540 opt_clean
541 memory_dff
542 memory_collect
543 select -assert-count 1 t:$mem_v2
544 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b10 r:RD_COLLISION_X_MASK=2'b01 %i %i
545
546 design -reset
547
548 # Good case 11: priority mismatch, but since three-way collision cannot happen, it's still OK.
549
550 read_verilog << EOT
551
552 module top(
553 input [3:0] addr,
554 input [1:0] mode,
555 input [3:0] wd1,
556 input [3:0] wd2,
557 input we1, we2,
558 input re,
559 input clk,
560 output reg [3:0] rd,
561 );
562
563 reg [3:0] wa1, wa2, ra;
564
565 always @* begin
566 case (mode)
567 0: begin
568 wa1 = addr+1;
569 wa2 = addr;
570 ra = addr;
571 end
572 1: begin
573 wa1 = addr;
574 wa2 = addr+1;
575 ra = addr;
576 end
577 2: begin
578 wa1 = addr;
579 wa2 = addr;
580 ra = addr+1;
581 end
582 3: begin
583 wa1 = addr;
584 wa2 = addr+1;
585 ra = addr+2;
586 end
587 endcase
588 end
589
590 reg [3:0] mem[0:15];
591
592 always @(posedge clk) begin
593 if (we1)
594 mem[wa1] <= wd1;
595 if (we2)
596 mem[wa2] <= wd2;
597 if (re) begin
598 rd <= mem[ra];
599 if (we2 && wa2 == ra)
600 rd <= wd2;
601 if (we1 && wa1 == ra)
602 rd <= wd1;
603 end
604 end
605
606 endmodule
607
608 EOT
609
610 hierarchy -auto-top
611 proc
612 opt_dff
613 opt_clean
614 memory_dff
615 memory_collect
616 select -assert-count 1 t:$mem_v2
617 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b11 r:RD_COLLISION_X_MASK=2'b00 %i %i
618
619 design -reset
620
621 # Bad case 4: half of the port is transparent.
622
623 read_verilog << EOT
624
625 module top(
626 input [3:0] ra,
627 input [3:0] wa1,
628 input [3:0] wa2,
629 input [3:0] wd1,
630 input [3:0] wd2,
631 input we1, we2,
632 input re,
633 input clk,
634 output reg [3:0] rd,
635 );
636
637 reg [3:0] mem[0:15];
638
639 always @(posedge clk) begin
640 if (we1)
641 mem[wa1] <= wd1;
642 if (we2)
643 mem[wa2] <= wd2;
644 if (re) begin
645 rd <= mem[ra];
646 if (we1 && wa1 == ra)
647 rd <= wd1;
648 if (we2 && wa2 == ra)
649 rd[3:2] <= wd2[3:2];
650 end
651 end
652
653 endmodule
654
655 EOT
656
657 hierarchy -auto-top
658 proc
659 opt_dff
660 opt_clean
661 logger -expect log "FF found, but soft transparency logic is inconsistent for port 1." 1
662 memory_dff
663 logger -check-expected
664 memory_collect
665 select -assert-count 1 t:$mem_v2
666 select -assert-count 1 t:$mem_v2 r:RD_CLK_ENABLE=1'b0 %i
667
668 design -reset
669
670 # Good case 12: like above, but the other bits aren't changed by the port anyway.
671
672 read_verilog << EOT
673
674 module top(
675 input [3:0] ra,
676 input [3:0] wa1,
677 input [3:0] wa2,
678 input [3:0] wd1,
679 input [3:0] wd2,
680 input we1, we2,
681 input re,
682 input clk,
683 output reg [3:0] rd,
684 );
685
686 reg [3:0] mem[0:15];
687
688 always @(posedge clk) begin
689 if (we1)
690 mem[wa1] <= wd1;
691 if (we2)
692 mem[wa2][3:2] <= wd2[3:2];
693 if (re) begin
694 rd <= mem[ra];
695 if (we1 && wa1 == ra)
696 rd <= wd1;
697 if (we2 && wa2 == ra)
698 rd[3:2] <= wd2[3:2];
699 end
700 end
701
702 endmodule
703
704 EOT
705
706 hierarchy -auto-top
707 proc
708 opt_dff
709 opt_clean
710 memory_dff
711 memory_collect
712 select -assert-count 1 t:$mem_v2
713 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b11 r:RD_COLLISION_X_MASK=2'b00 %i %i
714
715 design -reset
716
717 # Good case 13: wide read, narrow write.
718
719 read_verilog << EOT
720
721 module top(
722 input [7:0] addr,
723 input [7:0] wd,
724 input we,
725 input re,
726 input clk,
727 output reg [31:0] rd,
728 );
729
730 reg [7:0] mem[0:255];
731
732 always @(posedge clk) begin
733 if (we)
734 mem[addr] <= wd;
735 if (re) begin
736 rd[7:0] <= mem[{addr[7:2], 2'b00}];
737 rd[15:8] <= mem[{addr[7:2], 2'b01}];
738 rd[23:16] <= mem[{addr[7:2], 2'b10}];
739 rd[31:24] <= mem[{addr[7:2], 2'b11}];
740 case ({we, addr[1:0]})
741 3'b100: rd[7:0] <= wd;
742 3'b101: rd[15:8] <= wd;
743 3'b110: rd[23:16] <= wd;
744 3'b111: rd[31:24] <= wd;
745 endcase
746 end
747 end
748
749 endmodule
750
751 EOT
752
753 hierarchy -auto-top
754 proc
755 opt_dff
756 opt_clean
757 dump
758 memory_dff
759 memory_collect
760 select -assert-count 1 t:$mem_v2
761 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=4'b1111 r:RD_COLLISION_X_MASK=4'b0000 %i %i
762 memory_share
763 select -assert-count 1 t:$mem_v2
764 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=4'b1111 r:RD_COLLISION_X_MASK=4'b0000 %i %i
765 select -assert-count 1 t:$mem_v2 r:RD_WIDE_CONTINUATION=4'b1110 %i
766
767 design -reset
768
769 # Good case 14: narrow read, wide write.
770
771 read_verilog << EOT
772
773 module top(
774 input [7:0] addr,
775 input [31:0] wd,
776 input we,
777 input re,
778 input clk,
779 output reg [7:0] rd,
780 );
781
782 reg [7:0] mem[0:255];
783
784 always @(posedge clk) begin
785 if (we) begin
786 mem[{addr[7:2], 2'b00}] <= wd[7:0];
787 mem[{addr[7:2], 2'b01}] <= wd[15:8];
788 mem[{addr[7:2], 2'b10}] <= wd[23:16];
789 mem[{addr[7:2], 2'b11}] <= wd[31:24];
790 end
791 if (re) begin
792 rd <= mem[addr];
793 case ({we, addr[1:0]})
794 3'b100: rd <= wd[7:0];
795 3'b101: rd <= wd[15:8];
796 3'b110: rd <= wd[23:16];
797 3'b111: rd <= wd[31:24];
798 endcase
799 end
800 end
801
802 endmodule
803
804 EOT
805
806 hierarchy -auto-top
807 proc
808 opt_dff
809 opt_clean
810 dump
811 memory_dff
812 memory_collect
813 select -assert-count 1 t:$mem_v2
814 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=4'b1111 r:RD_COLLISION_X_MASK=4'b0000 %i %i
815 memory_share
816 select -assert-count 1 t:$mem_v2
817 select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=4'b1111 r:RD_COLLISION_X_MASK=4'b0000 %i %i
818 select -assert-count 1 t:$mem_v2 r:WR_WIDE_CONTINUATION=4'b1110 %i
819
820 design -reset
821
822 # Good case 15: wide read, wide write.
823
824 read_verilog << EOT
825
826 module top(
827 input [7:0] addr,
828 input [31:0] wd,
829 input we,
830 input re,
831 input clk,
832 output reg [31:0] rd,
833 );
834
835 reg [7:0] mem[0:255];
836
837 always @(posedge clk) begin
838 if (we) begin
839 mem[{addr[7:2], 2'b00}] <= wd[7:0];
840 mem[{addr[7:2], 2'b01}] <= wd[15:8];
841 mem[{addr[7:2], 2'b10}] <= wd[23:16];
842 mem[{addr[7:2], 2'b11}] <= wd[31:24];
843 end
844 if (re) begin
845 rd[7:0] <= mem[{addr[7:2], 2'b00}];
846 rd[15:8] <= mem[{addr[7:2], 2'b01}];
847 rd[23:16] <= mem[{addr[7:2], 2'b10}];
848 rd[31:24] <= mem[{addr[7:2], 2'b11}];
849 if (we)
850 rd <= wd;
851 end
852 end
853
854 endmodule
855
856 EOT
857
858 hierarchy -auto-top
859 proc
860 opt_dff
861 opt_clean
862 dump
863 memory_dff
864 select -assert-count 4 t:$memrd_v2
865 select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b0001 r:COLLISION_X_MASK=4'b1110 %i %i
866 select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b0010 r:COLLISION_X_MASK=4'b1101 %i %i
867 select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b0100 r:COLLISION_X_MASK=4'b1011 %i %i
868 select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b1000 r:COLLISION_X_MASK=4'b0111 %i %i
869 memory_share
870 select -assert-count 1 t:$memrd_v2
871 select -assert-count 1 t:$memwr_v2
872 select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=1'b1 r:COLLISION_X_MASK=1'b0 %i %i
873
874 design -reset