Skip to content

Commit 85f611f

Browse files
authored
Merge pull request #3126 from georgerennie/equiv_make_assertions
equiv_make: Add -make_assert option
2 parents f370730 + fbf5d89 commit 85f611f

File tree

2 files changed

+97
-27
lines changed

2 files changed

+97
-27
lines changed

passes/equiv/equiv_make.cc

+65-27
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct EquivMakeWorker
3333
bool inames;
3434
vector<string> blacklists;
3535
vector<string> encfiles;
36+
bool make_assert;
3637

3738
pool<IdString> blacklist_names;
3839
dict<IdString, dict<Const, Const>> encdata;
@@ -133,6 +134,12 @@ struct EquivMakeWorker
133134
delete gate_clone;
134135
}
135136

137+
void add_eq_assertion(const SigSpec &gold_sig, const SigSpec &gate_sig)
138+
{
139+
auto eq_wire = equiv_mod->Eqx(NEW_ID, gold_sig, gate_sig);
140+
equiv_mod->addAssert(NEW_ID_SUFFIX("assert"), eq_wire, State::S1);
141+
}
142+
136143
void find_same_wires()
137144
{
138145
SigMap assign_map(equiv_mod);
@@ -231,15 +238,24 @@ struct EquivMakeWorker
231238

232239
if (gold_wire->port_output || gate_wire->port_output)
233240
{
234-
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
235-
wire->port_output = true;
236241
gold_wire->port_input = false;
237242
gate_wire->port_input = false;
238243
gold_wire->port_output = false;
239244
gate_wire->port_output = false;
240245

241-
for (int i = 0; i < wire->width; i++)
242-
equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
246+
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
247+
wire->port_output = true;
248+
249+
if (make_assert)
250+
{
251+
add_eq_assertion(gold_wire, gate_wire);
252+
equiv_mod->connect(wire, gold_wire);
253+
}
254+
else
255+
{
256+
for (int i = 0; i < wire->width; i++)
257+
equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
258+
}
243259

244260
rd_signal_map.add(assign_map(gold_wire), wire);
245261
rd_signal_map.add(assign_map(gate_wire), wire);
@@ -259,26 +275,31 @@ struct EquivMakeWorker
259275
}
260276
else
261277
{
262-
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
263-
SigSpec rdmap_gold, rdmap_gate, rdmap_equiv;
278+
if (make_assert)
279+
add_eq_assertion(gold_wire, gate_wire);
264280

265-
for (int i = 0; i < wire->width; i++) {
266-
if (undriven_bits.count(assign_map(SigBit(gold_wire, i)))) {
267-
log(" Skipping signal bit %s [%d]: undriven on gold side.\n", id2cstr(gold_wire->name), i);
268-
continue;
269-
}
270-
if (undriven_bits.count(assign_map(SigBit(gate_wire, i)))) {
271-
log(" Skipping signal bit %s [%d]: undriven on gate side.\n", id2cstr(gate_wire->name), i);
272-
continue;
281+
else {
282+
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
283+
SigSpec rdmap_gold, rdmap_gate, rdmap_equiv;
284+
285+
for (int i = 0; i < wire->width; i++) {
286+
if (undriven_bits.count(assign_map(SigBit(gold_wire, i)))) {
287+
log(" Skipping signal bit %s [%d]: undriven on gold side.\n", id2cstr(gold_wire->name), i);
288+
continue;
289+
}
290+
if (undriven_bits.count(assign_map(SigBit(gate_wire, i)))) {
291+
log(" Skipping signal bit %s [%d]: undriven on gate side.\n", id2cstr(gate_wire->name), i);
292+
continue;
293+
}
294+
equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
295+
rdmap_gold.append(SigBit(gold_wire, i));
296+
rdmap_gate.append(SigBit(gate_wire, i));
297+
rdmap_equiv.append(SigBit(wire, i));
273298
}
274-
equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
275-
rdmap_gold.append(SigBit(gold_wire, i));
276-
rdmap_gate.append(SigBit(gate_wire, i));
277-
rdmap_equiv.append(SigBit(wire, i));
278-
}
279299

280-
rd_signal_map.add(rdmap_gold, rdmap_equiv);
281-
rd_signal_map.add(rdmap_gate, rdmap_equiv);
300+
rd_signal_map.add(rdmap_gold, rdmap_equiv);
301+
rd_signal_map.add(rdmap_gate, rdmap_equiv);
302+
}
282303
}
283304
}
284305

@@ -335,12 +356,20 @@ struct EquivMakeWorker
335356
continue;
336357
}
337358

338-
for (int i = 0; i < GetSize(gold_sig); i++)
339-
if (gold_sig[i] != gate_sig[i]) {
340-
Wire *w = equiv_mod->addWire(NEW_ID);
341-
equiv_mod->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], w);
342-
gold_sig[i] = w;
343-
}
359+
if (make_assert)
360+
{
361+
if (gold_sig != gate_sig)
362+
add_eq_assertion(gold_sig, gate_sig);
363+
}
364+
else
365+
{
366+
for (int i = 0; i < GetSize(gold_sig); i++)
367+
if (gold_sig[i] != gate_sig[i]) {
368+
Wire *w = equiv_mod->addWire(NEW_ID);
369+
equiv_mod->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], w);
370+
gold_sig[i] = w;
371+
}
372+
}
344373

345374
gold_cell->setPort(gold_conn.first, gold_sig);
346375
}
@@ -417,6 +446,10 @@ struct EquivMakePass : public Pass {
417446
log(" Match FSM encodings using the description from the file.\n");
418447
log(" See 'help fsm_recode' for details.\n");
419448
log("\n");
449+
log(" -make_assert\n");
450+
log(" Check equivalence with $assert cells instead of $equiv.\n");
451+
log(" $eqx (===) is used to compare signals.");
452+
log("\n");
420453
log("Note: The circuit created by this command is not a miter (with something like\n");
421454
log("a trigger output), but instead uses $equiv cells to encode the equivalence\n");
422455
log("checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n");
@@ -427,6 +460,7 @@ struct EquivMakePass : public Pass {
427460
EquivMakeWorker worker;
428461
worker.ct.setup(design);
429462
worker.inames = false;
463+
worker.make_assert = false;
430464

431465
size_t argidx;
432466
for (argidx = 1; argidx < args.size(); argidx++)
@@ -443,6 +477,10 @@ struct EquivMakePass : public Pass {
443477
worker.encfiles.push_back(args[++argidx]);
444478
continue;
445479
}
480+
if (args[argidx] == "-make_assert") {
481+
worker.make_assert = true;
482+
continue;
483+
}
446484
break;
447485
}
448486

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
read_verilog <<EOT
2+
module gold(
3+
input wire [7:0] a,
4+
input wire [7:0] b,
5+
output wire [7:0] c
6+
);
7+
8+
wire [7:0] b_neg;
9+
assign b_neg = -b;
10+
assign c = a + b_neg;
11+
endmodule
12+
13+
module gate(
14+
input wire [7:0] a,
15+
input wire [7:0] b,
16+
output wire [7:0] c
17+
);
18+
19+
wire [7:0] b_neg;
20+
assign b_neg = ~b + 1;
21+
assign c = a + b_neg;
22+
endmodule
23+
24+
EOT
25+
26+
equiv_make -make_assert gold gate miter
27+
28+
select -assert-count 0 t:$equiv
29+
select -assert-count 2 t:$assert
30+
31+
prep -top miter
32+
sat -prove-asserts -verify

0 commit comments

Comments
 (0)