coolrunner2: Use extract_counter to optimize counters
[yosys.git] / techlibs / coolrunner2 / cells_counter_map.v
1 module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP);
2
3 input wire CE;
4 input wire CLK;
5 output wire OUT;
6 output wire[WIDTH-1:0] POUT;
7 input wire RST;
8 input wire UP;
9
10 parameter COUNT_TO = 1;
11 parameter RESET_MODE = "RISING";
12 parameter RESET_TO_MAX = 0;
13 parameter HAS_POUT = 0;
14 parameter HAS_CE = 0;
15 parameter WIDTH = 8;
16 parameter DIRECTION = "DOWN";
17
18 if (DIRECTION == "UP") begin
19 if (WIDTH < 2) begin
20 initial begin
21 $display("ERROR: \$__COUNT_ must be at least 2 bits wide (bug in extract_counter pass?).");
22 $finish;
23 end
24 end
25
26 // FIXME: Max width?
27
28 assign OUT = POUT == COUNT_TO;
29
30 if (HAS_CE) begin
31 genvar i;
32 for (i = 0; i < WIDTH; i++) begin: countbits
33 // each bit = (cur & !reset) ^ (all prev & !reset)
34 wire xor_to_mc_bitn;
35 FDCP #(
36 .INIT(0)
37 ) bitn_ff (
38 .C(CLK),
39 .CLR(0),
40 .D(xor_to_mc_bitn),
41 .PRE(0),
42 .Q(POUT[i])
43 );
44 wire orterm_to_xor_bitn;
45 wire pterm0_to_or_bitn;
46 wire pterm1_to_or_bitn;
47 MACROCELL_XOR #(
48 .INVERT_OUT(0)
49 ) bitn_xor (
50 .IN_ORTERM(orterm_to_xor_bitn),
51 .IN_PTC(pterm1_to_or_bitn),
52 .OUT(xor_to_mc_bitn)
53 );
54 ORTERM #(
55 .WIDTH(1)
56 ) bitn_or (
57 .IN(pterm0_to_or_bitn),
58 .OUT(orterm_to_xor_bitn)
59 );
60 ANDTERM #(
61 .COMP_INP(1),
62 .TRUE_INP(1)
63 ) bitn_pterm0 (
64 .IN(POUT[i]),
65 .IN_B(OUT),
66 .OUT(pterm0_to_or_bitn)
67 );
68 ANDTERM #(
69 .COMP_INP(1),
70 .TRUE_INP(i + 1)
71 ) bitn_pterm1 (
72 .IN({POUT[i-1:0], CE}),
73 .IN_B(OUT),
74 .OUT(pterm1_to_or_bitn)
75 );
76 end
77 end else begin
78 // Bit0 is special; toggle unless reset
79 // cur reset out
80 // 0 0 1
81 // 0 1 0
82 // 1 0 0
83 // 1 1 0
84 wire xor_to_mc_bit0;
85 FDCP #(
86 .INIT(0)
87 ) bit0_ff (
88 .C(CLK),
89 .CLR(0),
90 .D(xor_to_mc_bit0),
91 .PRE(0),
92 .Q(POUT[0])
93 );
94 wire pterm_to_xor_bit0;
95 MACROCELL_XOR #(
96 .INVERT_OUT(0)
97 ) bit0_xor (
98 .IN_PTC(pterm_to_xor_bit0),
99 .OUT(xor_to_mc_bit0)
100 );
101 ANDTERM #(
102 .COMP_INP(2),
103 .TRUE_INP(0)
104 ) bit0_pterm (
105 .IN(),
106 .IN_B({POUT[0], OUT}),
107 .OUT(pterm_to_xor_bit0)
108 );
109
110 genvar i;
111 for (i = 1; i < WIDTH; i++) begin: countbits
112 // each bit = (cur & !reset) ^ (all prev & !reset)
113 wire xor_to_mc_bitn;
114 FDCP #(
115 .INIT(0)
116 ) bitn_ff (
117 .C(CLK),
118 .CLR(0),
119 .D(xor_to_mc_bitn),
120 .PRE(0),
121 .Q(POUT[i])
122 );
123 wire orterm_to_xor_bitn;
124 wire pterm0_to_or_bitn;
125 wire pterm1_to_or_bitn;
126 MACROCELL_XOR #(
127 .INVERT_OUT(0)
128 ) bitn_xor (
129 .IN_ORTERM(orterm_to_xor_bitn),
130 .IN_PTC(pterm1_to_or_bitn),
131 .OUT(xor_to_mc_bitn)
132 );
133 ORTERM #(
134 .WIDTH(1)
135 ) bitn_or (
136 .IN(pterm0_to_or_bitn),
137 .OUT(orterm_to_xor_bitn)
138 );
139 ANDTERM #(
140 .COMP_INP(1),
141 .TRUE_INP(1)
142 ) bitn_pterm0 (
143 .IN(POUT[i]),
144 .IN_B(OUT),
145 .OUT(pterm0_to_or_bitn)
146 );
147 ANDTERM #(
148 .COMP_INP(1),
149 .TRUE_INP(i)
150 ) bitn_pterm1 (
151 .IN(POUT[i-1:0]),
152 .IN_B(OUT),
153 .OUT(pterm1_to_or_bitn)
154 );
155 end
156 end
157 end
158
159 // FIXME: down counters
160
161 endmodule