Added $assert cell
[yosys.git] / techlibs / common / simlib.v
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * ---
19 *
20 * The Simulation Library.
21 *
22 * This verilog library contains simple simulation models for the internal
23 * cells ($not, ...) generated by the frontends and used in most passes.
24 *
25 * This library can be used to verify the internal netlists as generated
26 * by the different frontends and passes.
27 *
28 * Note that memory can only be simulated when all $memrd and $memwr cells
29 * have been merged to stand-alone $mem cells (this is what the "memory_collect"
30 * pass is doing).
31 *
32 */
33
34 `define INPUT_A input [A_WIDTH-1:0] A; \
35 generate if (A_SIGNED) begin:A_BUF wire signed [A_WIDTH-1:0] val = A; end else begin:A_BUF wire [A_WIDTH-1:0] val = A; end endgenerate
36
37 `define INPUT_B input [B_WIDTH-1:0] B; \
38 generate if (B_SIGNED) begin:B_BUF wire signed [B_WIDTH-1:0] val = B; end else begin:B_BUF wire [B_WIDTH-1:0] val = B; end endgenerate
39
40 // --------------------------------------------------------
41
42 module \$not (A, Y);
43
44 parameter A_SIGNED = 0;
45 parameter A_WIDTH = 0;
46 parameter Y_WIDTH = 0;
47
48 `INPUT_A
49 output [Y_WIDTH-1:0] Y;
50
51 assign Y = ~A_BUF.val;
52
53 endmodule
54
55
56 // --------------------------------------------------------
57
58 module \$bu0 (A, Y);
59
60 parameter A_SIGNED = 0;
61 parameter A_WIDTH = 0;
62 parameter Y_WIDTH = 0;
63
64 `INPUT_A
65 output [Y_WIDTH-1:0] Y;
66
67 generate
68 if (!A_SIGNED && 0 < A_WIDTH && A_WIDTH < Y_WIDTH) begin:BLOCK1
69 assign Y[A_WIDTH-1:0] = A_BUF.val;
70 assign Y[Y_WIDTH-1:A_WIDTH] = 0;
71 end else begin:BLOCK2
72 assign Y = +A_BUF.val;
73 end
74 endgenerate
75
76 endmodule
77
78 // --------------------------------------------------------
79
80 module \$pos (A, Y);
81
82 parameter A_SIGNED = 0;
83 parameter A_WIDTH = 0;
84 parameter Y_WIDTH = 0;
85
86 `INPUT_A
87 output [Y_WIDTH-1:0] Y;
88
89 assign Y = +A_BUF.val;
90
91 endmodule
92
93 // --------------------------------------------------------
94
95 module \$neg (A, Y);
96
97 parameter A_SIGNED = 0;
98 parameter A_WIDTH = 0;
99 parameter Y_WIDTH = 0;
100
101 `INPUT_A
102 output [Y_WIDTH-1:0] Y;
103
104 assign Y = -A_BUF.val;
105
106 endmodule
107
108 // --------------------------------------------------------
109
110 module \$and (A, B, Y);
111
112 parameter A_SIGNED = 0;
113 parameter B_SIGNED = 0;
114 parameter A_WIDTH = 0;
115 parameter B_WIDTH = 0;
116 parameter Y_WIDTH = 0;
117
118 `INPUT_A
119 `INPUT_B
120 output [Y_WIDTH-1:0] Y;
121
122 assign Y = A_BUF.val & B_BUF.val;
123
124 endmodule
125
126 // --------------------------------------------------------
127
128 module \$or (A, B, Y);
129
130 parameter A_SIGNED = 0;
131 parameter B_SIGNED = 0;
132 parameter A_WIDTH = 0;
133 parameter B_WIDTH = 0;
134 parameter Y_WIDTH = 0;
135
136 `INPUT_A
137 `INPUT_B
138 output [Y_WIDTH-1:0] Y;
139
140 assign Y = A_BUF.val | B_BUF.val;
141
142 endmodule
143
144 // --------------------------------------------------------
145
146 module \$xor (A, B, Y);
147
148 parameter A_SIGNED = 0;
149 parameter B_SIGNED = 0;
150 parameter A_WIDTH = 0;
151 parameter B_WIDTH = 0;
152 parameter Y_WIDTH = 0;
153
154 `INPUT_A
155 `INPUT_B
156 output [Y_WIDTH-1:0] Y;
157
158 assign Y = A_BUF.val ^ B_BUF.val;
159
160 endmodule
161
162 // --------------------------------------------------------
163
164 module \$xnor (A, B, Y);
165
166 parameter A_SIGNED = 0;
167 parameter B_SIGNED = 0;
168 parameter A_WIDTH = 0;
169 parameter B_WIDTH = 0;
170 parameter Y_WIDTH = 0;
171
172 `INPUT_A
173 `INPUT_B
174 output [Y_WIDTH-1:0] Y;
175
176 assign Y = A_BUF.val ~^ B_BUF.val;
177
178 endmodule
179
180 // --------------------------------------------------------
181
182 module \$reduce_and (A, Y);
183
184 parameter A_SIGNED = 0;
185 parameter A_WIDTH = 0;
186 parameter Y_WIDTH = 0;
187
188 `INPUT_A
189 output Y;
190
191 assign Y = &A_BUF.val;
192
193 endmodule
194
195 // --------------------------------------------------------
196
197 module \$reduce_or (A, Y);
198
199 parameter A_SIGNED = 0;
200 parameter A_WIDTH = 0;
201 parameter Y_WIDTH = 0;
202
203 `INPUT_A
204 output Y;
205
206 assign Y = |A_BUF.val;
207
208 endmodule
209
210 // --------------------------------------------------------
211
212 module \$reduce_xor (A, Y);
213
214 parameter A_SIGNED = 0;
215 parameter A_WIDTH = 0;
216 parameter Y_WIDTH = 0;
217
218 `INPUT_A
219 output Y;
220
221 assign Y = ^A_BUF.val;
222
223 endmodule
224
225 // --------------------------------------------------------
226
227 module \$reduce_xnor (A, Y);
228
229 parameter A_SIGNED = 0;
230 parameter A_WIDTH = 0;
231 parameter Y_WIDTH = 0;
232
233 `INPUT_A
234 output Y;
235
236 assign Y = ~^A_BUF.val;
237
238 endmodule
239
240 // --------------------------------------------------------
241
242 module \$reduce_bool (A, Y);
243
244 parameter A_SIGNED = 0;
245 parameter A_WIDTH = 0;
246 parameter Y_WIDTH = 0;
247
248 `INPUT_A
249 output Y;
250
251 assign Y = A_BUF.val != 0;
252
253 endmodule
254
255 // --------------------------------------------------------
256
257 module \$shl (A, B, Y);
258
259 parameter A_SIGNED = 0;
260 parameter B_SIGNED = 0;
261 parameter A_WIDTH = 0;
262 parameter B_WIDTH = 0;
263 parameter Y_WIDTH = 0;
264
265 `INPUT_A
266 `INPUT_B
267 output [Y_WIDTH-1:0] Y;
268
269 assign Y = A_BUF.val << B_BUF.val;
270
271 endmodule
272
273 // --------------------------------------------------------
274
275 module \$shr (A, B, Y);
276
277 parameter A_SIGNED = 0;
278 parameter B_SIGNED = 0;
279 parameter A_WIDTH = 0;
280 parameter B_WIDTH = 0;
281 parameter Y_WIDTH = 0;
282
283 `INPUT_A
284 `INPUT_B
285 output [Y_WIDTH-1:0] Y;
286
287 assign Y = A_BUF.val >> B_BUF.val;
288
289 endmodule
290
291 // --------------------------------------------------------
292
293 module \$sshl (A, B, Y);
294
295 parameter A_SIGNED = 0;
296 parameter B_SIGNED = 0;
297 parameter A_WIDTH = 0;
298 parameter B_WIDTH = 0;
299 parameter Y_WIDTH = 0;
300
301 `INPUT_A
302 `INPUT_B
303 output [Y_WIDTH-1:0] Y;
304
305 assign Y = A_BUF.val <<< B_BUF.val;
306
307 endmodule
308
309 // --------------------------------------------------------
310
311 module \$sshr (A, B, Y);
312
313 parameter A_SIGNED = 0;
314 parameter B_SIGNED = 0;
315 parameter A_WIDTH = 0;
316 parameter B_WIDTH = 0;
317 parameter Y_WIDTH = 0;
318
319 `INPUT_A
320 `INPUT_B
321 output [Y_WIDTH-1:0] Y;
322
323 assign Y = A_BUF.val >>> B_BUF.val;
324
325 endmodule
326
327 // --------------------------------------------------------
328
329 module \$lt (A, B, Y);
330
331 parameter A_SIGNED = 0;
332 parameter B_SIGNED = 0;
333 parameter A_WIDTH = 0;
334 parameter B_WIDTH = 0;
335 parameter Y_WIDTH = 0;
336
337 `INPUT_A
338 `INPUT_B
339 output [Y_WIDTH-1:0] Y;
340
341 assign Y = A_BUF.val < B_BUF.val;
342
343 endmodule
344
345 // --------------------------------------------------------
346
347 module \$le (A, B, Y);
348
349 parameter A_SIGNED = 0;
350 parameter B_SIGNED = 0;
351 parameter A_WIDTH = 0;
352 parameter B_WIDTH = 0;
353 parameter Y_WIDTH = 0;
354
355 `INPUT_A
356 `INPUT_B
357 output [Y_WIDTH-1:0] Y;
358
359 assign Y = A_BUF.val <= B_BUF.val;
360
361 endmodule
362
363 // --------------------------------------------------------
364
365 module \$eq (A, B, Y);
366
367 parameter A_SIGNED = 0;
368 parameter B_SIGNED = 0;
369 parameter A_WIDTH = 0;
370 parameter B_WIDTH = 0;
371 parameter Y_WIDTH = 0;
372
373 `INPUT_A
374 `INPUT_B
375 output [Y_WIDTH-1:0] Y;
376
377 assign Y = A_BUF.val == B_BUF.val;
378
379 endmodule
380
381 // --------------------------------------------------------
382
383 module \$ne (A, B, Y);
384
385 parameter A_SIGNED = 0;
386 parameter B_SIGNED = 0;
387 parameter A_WIDTH = 0;
388 parameter B_WIDTH = 0;
389 parameter Y_WIDTH = 0;
390
391 `INPUT_A
392 `INPUT_B
393 output [Y_WIDTH-1:0] Y;
394
395 assign Y = A_BUF.val != B_BUF.val;
396
397 endmodule
398
399 // --------------------------------------------------------
400
401 module \$eqx (A, B, Y);
402
403 parameter A_SIGNED = 0;
404 parameter B_SIGNED = 0;
405 parameter A_WIDTH = 0;
406 parameter B_WIDTH = 0;
407 parameter Y_WIDTH = 0;
408
409 `INPUT_A
410 `INPUT_B
411 output [Y_WIDTH-1:0] Y;
412
413 assign Y = A_BUF.val === B_BUF.val;
414
415 endmodule
416
417 // --------------------------------------------------------
418
419 module \$nex (A, B, Y);
420
421 parameter A_SIGNED = 0;
422 parameter B_SIGNED = 0;
423 parameter A_WIDTH = 0;
424 parameter B_WIDTH = 0;
425 parameter Y_WIDTH = 0;
426
427 `INPUT_A
428 `INPUT_B
429 output [Y_WIDTH-1:0] Y;
430
431 assign Y = A_BUF.val !== B_BUF.val;
432
433 endmodule
434
435 // --------------------------------------------------------
436
437 module \$ge (A, B, Y);
438
439 parameter A_SIGNED = 0;
440 parameter B_SIGNED = 0;
441 parameter A_WIDTH = 0;
442 parameter B_WIDTH = 0;
443 parameter Y_WIDTH = 0;
444
445 `INPUT_A
446 `INPUT_B
447 output [Y_WIDTH-1:0] Y;
448
449 assign Y = A_BUF.val >= B_BUF.val;
450
451 endmodule
452
453 // --------------------------------------------------------
454
455 module \$gt (A, B, Y);
456
457 parameter A_SIGNED = 0;
458 parameter B_SIGNED = 0;
459 parameter A_WIDTH = 0;
460 parameter B_WIDTH = 0;
461 parameter Y_WIDTH = 0;
462
463 `INPUT_A
464 `INPUT_B
465 output [Y_WIDTH-1:0] Y;
466
467 assign Y = A_BUF.val > B_BUF.val;
468
469 endmodule
470
471 // --------------------------------------------------------
472
473 module \$add (A, B, Y);
474
475 parameter A_SIGNED = 0;
476 parameter B_SIGNED = 0;
477 parameter A_WIDTH = 0;
478 parameter B_WIDTH = 0;
479 parameter Y_WIDTH = 0;
480
481 `INPUT_A
482 `INPUT_B
483 output [Y_WIDTH-1:0] Y;
484
485 assign Y = A_BUF.val + B_BUF.val;
486
487 endmodule
488
489 // --------------------------------------------------------
490
491 module \$sub (A, B, Y);
492
493 parameter A_SIGNED = 0;
494 parameter B_SIGNED = 0;
495 parameter A_WIDTH = 0;
496 parameter B_WIDTH = 0;
497 parameter Y_WIDTH = 0;
498
499 `INPUT_A
500 `INPUT_B
501 output [Y_WIDTH-1:0] Y;
502
503 assign Y = A_BUF.val - B_BUF.val;
504
505 endmodule
506
507 // --------------------------------------------------------
508
509 module \$mul (A, B, Y);
510
511 parameter A_SIGNED = 0;
512 parameter B_SIGNED = 0;
513 parameter A_WIDTH = 0;
514 parameter B_WIDTH = 0;
515 parameter Y_WIDTH = 0;
516
517 `INPUT_A
518 `INPUT_B
519 output [Y_WIDTH-1:0] Y;
520
521 assign Y = A_BUF.val * B_BUF.val;
522
523 endmodule
524
525 // --------------------------------------------------------
526
527 module \$div (A, B, Y);
528
529 parameter A_SIGNED = 0;
530 parameter B_SIGNED = 0;
531 parameter A_WIDTH = 0;
532 parameter B_WIDTH = 0;
533 parameter Y_WIDTH = 0;
534
535 `INPUT_A
536 `INPUT_B
537 output [Y_WIDTH-1:0] Y;
538
539 assign Y = A_BUF.val / B_BUF.val;
540
541 endmodule
542
543 // --------------------------------------------------------
544
545 module \$mod (A, B, Y);
546
547 parameter A_SIGNED = 0;
548 parameter B_SIGNED = 0;
549 parameter A_WIDTH = 0;
550 parameter B_WIDTH = 0;
551 parameter Y_WIDTH = 0;
552
553 `INPUT_A
554 `INPUT_B
555 output [Y_WIDTH-1:0] Y;
556
557 assign Y = A_BUF.val % B_BUF.val;
558
559 endmodule
560
561 // --------------------------------------------------------
562
563 module \$pow (A, B, Y);
564
565 parameter A_SIGNED = 0;
566 parameter B_SIGNED = 0;
567 parameter A_WIDTH = 0;
568 parameter B_WIDTH = 0;
569 parameter Y_WIDTH = 0;
570
571 `INPUT_A
572 `INPUT_B
573 output [Y_WIDTH-1:0] Y;
574
575 assign Y = A_BUF.val ** B_BUF.val;
576
577 endmodule
578
579 // --------------------------------------------------------
580
581 module \$logic_not (A, Y);
582
583 parameter A_SIGNED = 0;
584 parameter A_WIDTH = 0;
585 parameter Y_WIDTH = 0;
586
587 `INPUT_A
588 output [Y_WIDTH-1:0] Y;
589
590 assign Y = !A_BUF.val;
591
592 endmodule
593
594 // --------------------------------------------------------
595
596 module \$logic_and (A, B, Y);
597
598 parameter A_SIGNED = 0;
599 parameter B_SIGNED = 0;
600 parameter A_WIDTH = 0;
601 parameter B_WIDTH = 0;
602 parameter Y_WIDTH = 0;
603
604 `INPUT_A
605 `INPUT_B
606 output [Y_WIDTH-1:0] Y;
607
608 assign Y = A_BUF.val && B_BUF.val;
609
610 endmodule
611
612 // --------------------------------------------------------
613
614 module \$logic_or (A, B, Y);
615
616 parameter A_SIGNED = 0;
617 parameter B_SIGNED = 0;
618 parameter A_WIDTH = 0;
619 parameter B_WIDTH = 0;
620 parameter Y_WIDTH = 0;
621
622 `INPUT_A
623 `INPUT_B
624 output [Y_WIDTH-1:0] Y;
625
626 assign Y = A_BUF.val || B_BUF.val;
627
628 endmodule
629
630 // --------------------------------------------------------
631
632 module \$mux (A, B, S, Y);
633
634 parameter WIDTH = 0;
635
636 input [WIDTH-1:0] A, B;
637 input S;
638 output reg [WIDTH-1:0] Y;
639
640 always @* begin
641 if (S)
642 Y = B;
643 else
644 Y = A;
645 end
646
647 endmodule
648
649 // --------------------------------------------------------
650
651 module \$pmux (A, B, S, Y);
652
653 parameter WIDTH = 0;
654 parameter S_WIDTH = 0;
655
656 input [WIDTH-1:0] A;
657 input [WIDTH*S_WIDTH-1:0] B;
658 input [S_WIDTH-1:0] S;
659 output reg [WIDTH-1:0] Y;
660
661 integer i;
662
663 always @* begin
664 Y = A;
665 for (i = 0; i < S_WIDTH; i = i+1)
666 if (S[i])
667 Y = B >> (WIDTH*i);
668 end
669
670 endmodule
671
672 // --------------------------------------------------------
673
674 module \$safe_pmux (A, B, S, Y);
675
676 parameter WIDTH = 0;
677 parameter S_WIDTH = 0;
678
679 input [WIDTH-1:0] A;
680 input [WIDTH*S_WIDTH-1:0] B;
681 input [S_WIDTH-1:0] S;
682 output reg [WIDTH-1:0] Y;
683
684 integer i, j;
685
686 always @* begin
687 j = 0;
688 for (i = 0; i < S_WIDTH; i = i+1)
689 if (S[i]) begin
690 Y = B >> (WIDTH*i);
691 j = j + 1;
692 end
693 if (j != 1)
694 Y = A;
695 end
696
697 endmodule
698
699 // --------------------------------------------------------
700
701 module \$lut (I, O);
702
703 parameter WIDTH = 0;
704 parameter LUT = 0;
705
706 input [WIDTH-1:0] I;
707 output reg O;
708
709 wire lut0_out, lut1_out;
710
711 generate
712 if (WIDTH <= 1) begin:simple
713 assign {lut1_out, lut0_out} = LUT;
714 end else begin:complex
715 \$lut #( .WIDTH(WIDTH-1), .LUT(LUT ) ) lut0 ( .I(I[WIDTH-2:0]), .O(lut0_out) );
716 \$lut #( .WIDTH(WIDTH-1), .LUT(LUT >> (2**(WIDTH-1))) ) lut1 ( .I(I[WIDTH-2:0]), .O(lut1_out) );
717 end
718
719 if (WIDTH > 0) begin:lutlogic
720 always @* begin
721 casez ({I[WIDTH-1], lut0_out, lut1_out})
722 3'b?11: O = 1'b1;
723 3'b?00: O = 1'b0;
724 3'b0??: O = lut0_out;
725 3'b1??: O = lut1_out;
726 default: O = 1'bx;
727 endcase
728 end
729 end
730 endgenerate
731
732 endmodule
733
734 // --------------------------------------------------------
735
736 module \$assert (A, EN);
737
738 input A, EN;
739
740 always @* begin
741 if (A !== 1'b1 && EN === 1'b1) begin
742 $display("Assertation failed!");
743 $finish;
744 end
745 end
746
747 endmodule
748
749 // --------------------------------------------------------
750
751 module \$sr (SET, CLR, Q);
752
753 parameter WIDTH = 0;
754 parameter SET_POLARITY = 1'b1;
755 parameter CLR_POLARITY = 1'b1;
756
757 input [WIDTH-1:0] SET, CLR;
758 output reg [WIDTH-1:0] Q;
759
760 wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET;
761 wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR;
762
763 genvar i;
764 generate
765 for (i = 0; i < WIDTH; i = i+1) begin:bit
766 always @(posedge pos_set[i], posedge pos_clr[i])
767 if (pos_clr[i])
768 Q[i] <= 0;
769 else if (pos_set[i])
770 Q[i] <= 1;
771 end
772 endgenerate
773
774 endmodule
775
776 // --------------------------------------------------------
777
778 module \$dff (CLK, D, Q);
779
780 parameter WIDTH = 0;
781 parameter CLK_POLARITY = 1'b1;
782
783 input CLK;
784 input [WIDTH-1:0] D;
785 output reg [WIDTH-1:0] Q;
786 wire pos_clk = CLK == CLK_POLARITY;
787
788 always @(posedge pos_clk) begin
789 Q <= D;
790 end
791
792 endmodule
793
794 // --------------------------------------------------------
795
796 module \$dffsr (CLK, SET, CLR, D, Q);
797
798 parameter WIDTH = 0;
799 parameter CLK_POLARITY = 1'b1;
800 parameter SET_POLARITY = 1'b1;
801 parameter CLR_POLARITY = 1'b1;
802
803 input CLK;
804 input [WIDTH-1:0] SET, CLR, D;
805 output reg [WIDTH-1:0] Q;
806
807 wire pos_clk = CLK == CLK_POLARITY;
808 wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET;
809 wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR;
810
811 genvar i;
812 generate
813 for (i = 0; i < WIDTH; i = i+1) begin:bit
814 always @(posedge pos_set[i], posedge pos_clr[i], posedge pos_clk)
815 if (pos_clr[i])
816 Q[i] <= 0;
817 else if (pos_set[i])
818 Q[i] <= 1;
819 else
820 Q[i] <= D[i];
821 end
822 endgenerate
823
824 endmodule
825
826 // --------------------------------------------------------
827
828 module \$adff (CLK, ARST, D, Q);
829
830 parameter WIDTH = 0;
831 parameter CLK_POLARITY = 1'b1;
832 parameter ARST_POLARITY = 1'b1;
833 parameter ARST_VALUE = 0;
834
835 input CLK, ARST;
836 input [WIDTH-1:0] D;
837 output reg [WIDTH-1:0] Q;
838 wire pos_clk = CLK == CLK_POLARITY;
839 wire pos_arst = ARST == ARST_POLARITY;
840
841 always @(posedge pos_clk, posedge pos_arst) begin
842 if (pos_arst)
843 Q <= ARST_VALUE;
844 else
845 Q <= D;
846 end
847
848 endmodule
849
850 // --------------------------------------------------------
851
852 module \$dlatch (EN, D, Q);
853
854 parameter WIDTH = 0;
855 parameter EN_POLARITY = 1'b1;
856
857 input EN;
858 input [WIDTH-1:0] D;
859 output reg [WIDTH-1:0] Q;
860
861 always @* begin
862 if (EN == EN_POLARITY)
863 Q <= D;
864 end
865
866 endmodule
867
868 // --------------------------------------------------------
869
870 module \$fsm (CLK, ARST, CTRL_IN, CTRL_OUT);
871
872 parameter NAME = "";
873
874 parameter CLK_POLARITY = 1'b1;
875 parameter ARST_POLARITY = 1'b1;
876
877 parameter CTRL_IN_WIDTH = 1;
878 parameter CTRL_OUT_WIDTH = 1;
879
880 parameter STATE_BITS = 1;
881 parameter STATE_NUM = 1;
882 parameter STATE_NUM_LOG2 = 1;
883 parameter STATE_RST = 0;
884 parameter STATE_TABLE = 1'b0;
885
886 parameter TRANS_NUM = 1;
887 parameter TRANS_TABLE = 4'b0x0x;
888
889 input CLK, ARST;
890 input [CTRL_IN_WIDTH-1:0] CTRL_IN;
891 output reg [CTRL_OUT_WIDTH-1:0] CTRL_OUT;
892
893 wire pos_clk = CLK == CLK_POLARITY;
894 wire pos_arst = ARST == ARST_POLARITY;
895
896 reg [STATE_BITS-1:0] state;
897 reg [STATE_BITS-1:0] state_tmp;
898 reg [STATE_BITS-1:0] next_state;
899
900 reg [STATE_BITS-1:0] tr_state_in;
901 reg [STATE_BITS-1:0] tr_state_out;
902 reg [CTRL_IN_WIDTH-1:0] tr_ctrl_in;
903 reg [CTRL_OUT_WIDTH-1:0] tr_ctrl_out;
904
905 integer i;
906
907 task tr_fetch;
908 input [31:0] tr_num;
909 reg [31:0] tr_pos;
910 reg [STATE_NUM_LOG2-1:0] state_num;
911 begin
912 tr_pos = (2*STATE_NUM_LOG2+CTRL_IN_WIDTH+CTRL_OUT_WIDTH)*tr_num;
913 tr_ctrl_out = TRANS_TABLE >> tr_pos;
914 tr_pos = tr_pos + CTRL_OUT_WIDTH;
915 state_num = TRANS_TABLE >> tr_pos;
916 tr_state_out = STATE_TABLE >> (STATE_BITS*state_num);
917 tr_pos = tr_pos + STATE_NUM_LOG2;
918 tr_ctrl_in = TRANS_TABLE >> tr_pos;
919 tr_pos = tr_pos + CTRL_IN_WIDTH;
920 state_num = TRANS_TABLE >> tr_pos;
921 tr_state_in = STATE_TABLE >> (STATE_BITS*state_num);
922 tr_pos = tr_pos + STATE_NUM_LOG2;
923 end
924 endtask
925
926 always @(posedge pos_clk, posedge pos_arst) begin
927 if (pos_arst)
928 state_tmp = STATE_TABLE[STATE_BITS*(STATE_RST+1)-1:STATE_BITS*STATE_RST];
929 else
930 state_tmp = next_state;
931 for (i = 0; i < STATE_BITS; i = i+1)
932 if (state_tmp[i] === 1'bz)
933 state_tmp[i] = 0;
934 state <= state_tmp;
935 end
936
937 always @(state, CTRL_IN) begin
938 next_state <= STATE_TABLE[STATE_BITS*(STATE_RST+1)-1:STATE_BITS*STATE_RST];
939 CTRL_OUT <= 'bx;
940 // $display("---");
941 // $display("Q: %b %b", state, CTRL_IN);
942 for (i = 0; i < TRANS_NUM; i = i+1) begin
943 tr_fetch(i);
944 // $display("T: %b %b -> %b %b [%d]", tr_state_in, tr_ctrl_in, tr_state_out, tr_ctrl_out, i);
945 casez ({state, CTRL_IN})
946 {tr_state_in, tr_ctrl_in}: begin
947 // $display("-> %b %b <- MATCH", state, CTRL_IN);
948 {next_state, CTRL_OUT} <= {tr_state_out, tr_ctrl_out};
949 end
950 endcase
951 end
952 end
953
954 endmodule
955
956 // --------------------------------------------------------
957 `ifndef SIMLIB_NOMEM
958
959 module \$memrd (CLK, ADDR, DATA);
960
961 parameter MEMID = "";
962 parameter ABITS = 8;
963 parameter WIDTH = 8;
964
965 parameter CLK_ENABLE = 0;
966 parameter CLK_POLARITY = 0;
967
968 input CLK;
969 input [ABITS-1:0] ADDR;
970 output [WIDTH-1:0] DATA;
971
972 initial begin
973 if (MEMID != "") begin
974 $display("ERROR: Found non-simulatable instance of $memrd!");
975 $finish;
976 end
977 end
978
979 endmodule
980
981 // --------------------------------------------------------
982
983 module \$memwr (CLK, EN, ADDR, DATA);
984
985 parameter MEMID = "";
986 parameter ABITS = 8;
987 parameter WIDTH = 8;
988
989 parameter CLK_ENABLE = 0;
990 parameter CLK_POLARITY = 0;
991
992 input CLK, EN;
993 input [ABITS-1:0] ADDR;
994 input [WIDTH-1:0] DATA;
995
996 initial begin
997 if (MEMID != "") begin
998 $display("ERROR: Found non-simulatable instance of $memwr!");
999 $finish;
1000 end
1001 end
1002
1003 endmodule
1004
1005 // --------------------------------------------------------
1006
1007 module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
1008
1009 parameter MEMID = "";
1010 parameter SIZE = 256;
1011 parameter OFFSET = 0;
1012 parameter ABITS = 8;
1013 parameter WIDTH = 8;
1014
1015 parameter RD_PORTS = 1;
1016 parameter RD_CLK_ENABLE = 1'b1;
1017 parameter RD_CLK_POLARITY = 1'b1;
1018
1019 parameter WR_PORTS = 1;
1020 parameter WR_CLK_ENABLE = 1'b1;
1021 parameter WR_CLK_POLARITY = 1'b1;
1022
1023 input [RD_PORTS-1:0] RD_CLK;
1024 input [RD_PORTS*ABITS-1:0] RD_ADDR;
1025 output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
1026
1027 input [WR_PORTS-1:0] WR_CLK, WR_EN;
1028 input [WR_PORTS*ABITS-1:0] WR_ADDR;
1029 input [WR_PORTS*WIDTH-1:0] WR_DATA;
1030
1031 reg [WIDTH-1:0] data [SIZE-1:0];
1032 reg update_async_rd;
1033
1034 genvar i;
1035 generate
1036
1037 for (i = 0; i < RD_PORTS; i = i+1) begin:rd
1038 if (RD_CLK_ENABLE[i] == 0) begin:rd_noclk
1039 always @(RD_ADDR or update_async_rd)
1040 RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ];
1041 end else
1042 if (RD_CLK_POLARITY[i] == 1) begin:rd_posclk
1043 always @(posedge RD_CLK[i])
1044 RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ];
1045 end else begin:rd_negclk
1046 always @(negedge RD_CLK[i])
1047 RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ];
1048 end
1049 end
1050
1051 for (i = 0; i < WR_PORTS; i = i+1) begin:wr
1052 if (WR_CLK_ENABLE[i] == 0) begin:wr_noclk
1053 always @(WR_ADDR or WR_DATA or WR_EN) begin
1054 if (WR_EN[i]) begin
1055 data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ];
1056 update_async_rd <= 1; update_async_rd <= 0;
1057 end
1058 end
1059 end else
1060 if (WR_CLK_POLARITY[i] == 1) begin:rd_posclk
1061 always @(posedge WR_CLK[i])
1062 if (WR_EN[i]) begin
1063 data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ];
1064 update_async_rd <= 1; update_async_rd <= 0;
1065 end
1066 end else begin:rd_negclk
1067 always @(negedge WR_CLK[i])
1068 if (WR_EN[i]) begin
1069 data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] - OFFSET ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ];
1070 update_async_rd <= 1; update_async_rd <= 0;
1071 end
1072 end
1073 end
1074
1075 endgenerate
1076
1077 endmodule
1078
1079 `endif
1080 // --------------------------------------------------------