@@ -78,3 +78,195 @@ select -assert-count 1 t:$assert
7878sat -tempinduct -verify -prove-asserts
7979
8080design -reset
81+
82+ # A mix of different flop types all described together to stress test proc_dff
83+ # more
84+ read_verilog -formal <<EOT
85+ module top(
86+ input wire clk,
87+ input wire arst,
88+ input wire [7:0] d0, d1, d2, d3,
89+ input wire [7:0] ad2,
90+ output reg [7:0] q0, q1, q2, q3
91+ );
92+
93+ wire never = '0;
94+
95+ always @(posedge clk, posedge arst) begin
96+ {q0, q1, q2, q3} <= {d0, d1, d2, d3};
97+ if (arst)
98+ {q0, q2[7:4], q3, q2[3:0]} <= {q0, ad2[3:0], 8'hFF, 4'h5};
99+ else if (never)
100+ {q0, q1, q2, q3} <= {q3, q2, q1, q0};
101+ end
102+
103+ always @* begin
104+ if (arst) begin
105+ assert(q2 == {ad2[3:0], 4'h5});
106+ assert(q3 == 8'hFF);
107+ end
108+ end
109+
110+ endmodule
111+ EOT
112+
113+ proc
114+ opt_dff
115+ opt_clean
116+
117+ # q0 is a standard $dffe
118+ select w:q0 %ci* c:* %i
119+ select -assert-count 1 %
120+ select -assert-count 1 % t:$dffe %i
121+
122+ # q1 is an $aldff where both both aload and data take the same value
123+ select w:q1 %ci* c:* %i
124+ select -assert-count 1 %
125+ select -assert-count 1 % t:$aldff %i
126+ select -assert-count 1 % %ci:+[AD,D] w:* %i
127+
128+ # q2 is part driven by an $adff, and part by an $aldff
129+ select w:q2 %ci* c:* %i
130+ select -assert-count 2 %
131+ select -assert-count 1 % t:$adff %i
132+ select -assert-count 1 % t:$aldff %i
133+
134+ # q3 is driven by an $adff
135+ select w:q3 %ci* c:* %i
136+ select -assert-count 1 %
137+ select -assert-count 1 % t:$adff %i
138+
139+ # never should appear in none of the cones of flops
140+ select -assert-none c:* %x* w:never %i
141+
142+ select -clear
143+
144+ clk2fflogic
145+ select -assert-any t:$assert
146+ sat -tempinduct -verify -prove-asserts
147+
148+ design -reset
149+
150+ # A design which is best mapped with different flops for different ranges of
151+ # the variable
152+ read_verilog <<EOT
153+ module top(
154+ input wire clk,
155+ input wire rsta,
156+ input wire rstb,
157+ input wire [7:0] d,
158+ output reg [7:0] q
159+ );
160+
161+ always @(posedge clk or posedge rsta or posedge rstb) begin
162+ if (rsta)
163+ q <= '0;
164+ else if (rstb)
165+ q[3:0] <= 4'b0;
166+ else
167+ q <= d;
168+ end
169+
170+ endmodule
171+ EOT
172+
173+ proc
174+ opt_dff
175+ opt_clean
176+
177+ select w:q %ci* c:* %i
178+ select -assert-count 1 % t:$adffe %i
179+ select -assert-count 1 % t:$adff %i
180+
181+ design -reset
182+
183+ # Another design which is best mapped with different flops for different ranges
184+ # of the variable.
185+ read_verilog <<EOT
186+ module top(
187+ input wire clk,
188+ input wire rst,
189+ output reg [7:0] q,
190+ input wire [7:0] d
191+ );
192+
193+ always @(posedge clk or posedge rst) begin
194+ if (rst)
195+ q[3:0] <= '0;
196+ else
197+ q <= d;
198+ end
199+
200+ endmodule
201+ EOT
202+
203+ proc
204+ opt_dff
205+ opt_clean
206+
207+ select w:q %ci* c:* %i
208+ select -assert-count 1 % t:$dffe %i
209+ select -assert-count 1 % t:$adff %i
210+
211+ design -reset
212+
213+ # A design that relies on merging adjacent sync rules with the same priority
214+ # and folding low priority feedback rules into enables at the bit level
215+ read_verilog -formal <<EOT
216+ module top(
217+ input wire clk,
218+ input wire rsta, rstb, rstc, rstd,
219+ input wire [2:0] d,
220+ output reg [2:0] q
221+ );
222+
223+ always @(posedge clk, posedge rsta, negedge rstb, posedge rstc, negedge rstd) begin
224+ if (rsta)
225+ q <= {1'b1, 1'b0, d[0]};
226+ else if (!rstb)
227+ q <= {1'b1, 1'b0, d[0]};
228+ else if (rstc)
229+ q <= {q[2], 1'b0, d[0]};
230+ else if (~rstd)
231+ q <= {q[2], 1'b1, d[0]};
232+ else
233+ q <= d;
234+ end
235+
236+ always @* begin
237+ if (rsta) begin
238+ assert(q[2] == 1'b1);
239+ assert(q[1] == 1'b0);
240+ assert(q[0] == d[0]);
241+ end else if (!rstb) begin
242+ assert(q[2] == 1'b1);
243+ assert(q[1] == 1'b0);
244+ assert(q[0] == d[0]);
245+ end else if (rstc) begin
246+ assert(q[1] == 1'b0);
247+ assert(q[0] == d[0]);
248+ end else if (!rstd) begin
249+ assert(q[1] == 1'b1);
250+ assert(q[0] == d[0]);
251+ end
252+ end
253+
254+ endmodule
255+ EOT
256+
257+ proc
258+ opt_dff
259+ opt_clean
260+
261+ # q is driven by an adffe, a dffsr and an aldff per bit
262+ select w:q %ci1 c:* %i
263+ select -assert-count 3 %
264+ select -assert-count 1 % t:$adffe %i
265+ select -assert-count 1 % t:$dffsr %i
266+ select -assert-count 1 % t:$aldff %i
267+
268+ select -clear
269+
270+ clk2fflogic
271+ select -assert-any t:$assert
272+ sat -tempinduct -verify -prove-asserts
0 commit comments