Skip to content

Commit f17a6e1

Browse files
btor2aiger: Add test
Based on fifo.sby, running both with and without `btor_aig on`, as well as combined with `vcd_sim on` (after an earlier version had issues when using `vcd_sim off`). Has both pass and fail checks, so should be able to catch any major issues, although it doesn't fully check equivalence.
1 parent c081a8a commit f17a6e1

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

tests/unsorted/btor2aig.sby

+204
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
[tasks]
2+
bmc
3+
prove
4+
prove_f: prove
5+
prove_v: prove_f prove
6+
bmc_b2a: bmc btor_aig
7+
prove_b2a: prove btor_aig
8+
prove_f_b2a: prove_f prove btor_aig
9+
prove_v_b2a: prove_v prove_f prove btor_aig
10+
11+
[options]
12+
prove:
13+
mode prove
14+
--
15+
16+
bmc:
17+
mode bmc
18+
--
19+
20+
prove_f: expect fail
21+
prove_v: vcd_sim on
22+
btor_aig: btor_aig on
23+
24+
[engines]
25+
bmc: abc bmc3
26+
prove: abc --keep-going pdr
27+
28+
[script]
29+
prove_f: read -define NO_FULL_SKIP=1
30+
read -formal fifo.sv
31+
prep -top fifo
32+
33+
[file fifo.sv]
34+
// address generator/counter
35+
module addr_gen
36+
#( parameter MAX_DATA=16
37+
) ( input en, clk, rst,
38+
output reg [3:0] addr
39+
);
40+
initial addr <= 0;
41+
42+
// async reset
43+
// increment address when enabled
44+
always @(posedge clk or posedge rst)
45+
if (rst)
46+
addr <= 0;
47+
else if (en) begin
48+
if (addr == MAX_DATA-1)
49+
addr <= 0;
50+
else
51+
addr <= addr + 1;
52+
end
53+
endmodule
54+
55+
// Define our top level fifo entity
56+
module fifo
57+
#( parameter MAX_DATA=16
58+
) ( input wen, ren, clk, rst,
59+
input [7:0] wdata,
60+
output [7:0] rdata,
61+
output [4:0] count,
62+
output full, empty
63+
);
64+
wire wskip, rskip;
65+
reg [4:0] data_count;
66+
67+
// fifo storage
68+
// async read, sync write
69+
wire [3:0] waddr, raddr;
70+
reg [7:0] data [MAX_DATA-1:0];
71+
always @(posedge clk)
72+
if (wen)
73+
data[waddr] <= wdata;
74+
assign rdata = data[raddr];
75+
// end storage
76+
77+
// addr_gen for both write and read addresses
78+
addr_gen #(.MAX_DATA(MAX_DATA))
79+
fifo_writer (
80+
.en (wen || wskip),
81+
.clk (clk ),
82+
.rst (rst),
83+
.addr (waddr)
84+
);
85+
86+
addr_gen #(.MAX_DATA(MAX_DATA))
87+
fifo_reader (
88+
.en (ren || rskip),
89+
.clk (clk ),
90+
.rst (rst),
91+
.addr (raddr)
92+
);
93+
94+
// status signals
95+
initial data_count <= 0;
96+
97+
always @(posedge clk or posedge rst) begin
98+
if (rst)
99+
data_count <= 0;
100+
else if (wen && !ren && data_count < MAX_DATA)
101+
data_count <= data_count + 1;
102+
else if (ren && !wen && data_count > 0)
103+
data_count <= data_count - 1;
104+
end
105+
106+
assign full = data_count == MAX_DATA;
107+
assign empty = (data_count == 0) && ~rst;
108+
assign count = data_count;
109+
110+
// overflow protection
111+
`ifndef NO_FULL_SKIP
112+
// write while full => overwrite oldest data, move read pointer
113+
assign rskip = wen && !ren && data_count >= MAX_DATA;
114+
// read while empty => read invalid data, keep write pointer in sync
115+
assign wskip = ren && !wen && data_count == 0;
116+
`else
117+
assign rskip = 0;
118+
assign wskip = 0;
119+
`endif // NO_FULL_SKIP
120+
121+
`ifdef FORMAL
122+
// observers
123+
wire [4:0] addr_diff;
124+
assign addr_diff = waddr >= raddr
125+
? waddr - raddr
126+
: waddr + MAX_DATA - raddr;
127+
128+
// tests
129+
always @(posedge clk) begin
130+
if (~rst) begin
131+
// waddr and raddr can only be non zero if reset is low
132+
w_nreset: cover (waddr || raddr);
133+
134+
// count never more than max
135+
a_oflow: assert (count <= MAX_DATA);
136+
a_oflow2: assert (waddr < MAX_DATA);
137+
138+
// count should be equal to the difference between writer and reader address
139+
a_count_diff: assert (count == addr_diff
140+
|| count == MAX_DATA && addr_diff == 0);
141+
142+
// count should only be able to increase or decrease by 1
143+
a_counts: assert (count == 0
144+
|| count == $past(count)
145+
|| count == $past(count) + 1
146+
|| count == $past(count) - 1);
147+
148+
// read/write addresses can only increase (or stay the same)
149+
a_raddr: assert (raddr == 0
150+
|| raddr == $past(raddr)
151+
|| raddr == $past(raddr + 1));
152+
a_waddr: assert (waddr == 0
153+
|| waddr == $past(waddr)
154+
|| waddr == $past(waddr + 1));
155+
156+
// full and empty work as expected
157+
a_full: assert (!full || count == MAX_DATA);
158+
w_full: cover (wen && !ren && count == MAX_DATA-1);
159+
a_empty: assert (!empty || count == 0);
160+
w_empty: cover (ren && !wen && count == 1);
161+
162+
// reading/writing non zero values
163+
w_nzero_write: cover (wen && wdata);
164+
w_nzero_read: cover (ren && rdata);
165+
end else begin
166+
// waddr and raddr are zero while reset is high
167+
a_reset: assert (!waddr && !raddr);
168+
w_reset: cover (rst);
169+
170+
// outputs are zero while reset is high
171+
a_zero_out: assert (!empty && !full && !count);
172+
end
173+
end
174+
175+
// if we have verific we can also do the following additional tests
176+
// read/write enables enable
177+
ap_raddr2: assert property (@(posedge clk) disable iff (rst) ren |=> $changed(raddr));
178+
ap_waddr2: assert property (@(posedge clk) disable iff (rst) wen |=> $changed(waddr));
179+
180+
// read/write needs enable UNLESS full/empty
181+
ap_raddr3: assert property (@(posedge clk) disable iff (rst) !ren && !full |=> $stable(raddr));
182+
ap_waddr3: assert property (@(posedge clk) disable iff (rst) !wen && !empty |=> $stable(waddr));
183+
184+
// use block formatting for w_underfill so it's easier to describe in docs
185+
// and is more readily comparable with the non SVA implementation
186+
property write_skip;
187+
@(posedge clk) disable iff (rst)
188+
!wen |=> $changed(waddr);
189+
endproperty
190+
w_underfill: cover property (write_skip);
191+
192+
// look for an overfill where the value in memory changes
193+
// the change in data makes certain that the value is overriden
194+
let d_change = (wdata != rdata);
195+
property read_skip;
196+
@(posedge clk) disable iff (rst)
197+
!ren && d_change |=> $changed(raddr);
198+
endproperty
199+
w_overfill: cover property (read_skip);
200+
201+
`endif // FORMAL
202+
203+
endmodule
204+

0 commit comments

Comments
 (0)