Skip to content

Commit fbf5d89

Browse files
committed
equiv_make: Add -make_assert option
This adds a -make_assert flag to equiv_make. When used, the pass generates $eqx and $assert cells to encode equivalence instead of $equiv.
1 parent 34804f3 commit fbf5d89

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;
@@ -143,6 +144,12 @@ struct EquivMakeWorker
143144
delete gate_clone;
144145
}
145146

147+
void add_eq_assertion(const SigSpec &gold_sig, const SigSpec &gate_sig)
148+
{
149+
auto eq_wire = equiv_mod->Eqx(NEW_ID, gold_sig, gate_sig);
150+
equiv_mod->addAssert(NEW_ID_SUFFIX("assert"), eq_wire, State::S1);
151+
}
152+
146153
void find_same_wires()
147154
{
148155
SigMap assign_map(equiv_mod);
@@ -240,15 +247,24 @@ struct EquivMakeWorker
240247

241248
if (gold_wire->port_output || gate_wire->port_output)
242249
{
243-
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
244-
wire->port_output = true;
245250
gold_wire->port_input = false;
246251
gate_wire->port_input = false;
247252
gold_wire->port_output = false;
248253
gate_wire->port_output = false;
249254

250-
for (int i = 0; i < wire->width; i++)
251-
equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
255+
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
256+
wire->port_output = true;
257+
258+
if (make_assert)
259+
{
260+
add_eq_assertion(gold_wire, gate_wire);
261+
equiv_mod->connect(wire, gold_wire);
262+
}
263+
else
264+
{
265+
for (int i = 0; i < wire->width; i++)
266+
equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i));
267+
}
252268

253269
rd_signal_map.add(assign_map(gold_wire), wire);
254270
rd_signal_map.add(assign_map(gate_wire), wire);
@@ -265,26 +281,31 @@ struct EquivMakeWorker
265281
}
266282
else
267283
{
268-
Wire *wire = equiv_mod->addWire(id, gold_wire->width);
269-
SigSpec rdmap_gold, rdmap_gate, rdmap_equiv;
284+
if (make_assert)
285+
add_eq_assertion(gold_wire, gate_wire);
270286

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

286-
rd_signal_map.add(rdmap_gold, rdmap_equiv);
287-
rd_signal_map.add(rdmap_gate, rdmap_equiv);
306+
rd_signal_map.add(rdmap_gold, rdmap_equiv);
307+
rd_signal_map.add(rdmap_gate, rdmap_equiv);
308+
}
288309
}
289310
}
290311

@@ -353,12 +374,20 @@ struct EquivMakeWorker
353374
continue;
354375
}
355376

356-
for (int i = 0; i < GetSize(gold_sig); i++)
357-
if (gold_sig[i] != gate_sig[i]) {
358-
Wire *w = equiv_mod->addWire(NEW_ID);
359-
equiv_mod->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], w);
360-
gold_sig[i] = w;
361-
}
377+
if (make_assert)
378+
{
379+
if (gold_sig != gate_sig)
380+
add_eq_assertion(gold_sig, gate_sig);
381+
}
382+
else
383+
{
384+
for (int i = 0; i < GetSize(gold_sig); i++)
385+
if (gold_sig[i] != gate_sig[i]) {
386+
Wire *w = equiv_mod->addWire(NEW_ID);
387+
equiv_mod->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], w);
388+
gold_sig[i] = w;
389+
}
390+
}
362391

363392
gold_cell->setPort(gold_conn.first, gold_sig);
364393
}
@@ -486,6 +515,10 @@ struct EquivMakePass : public Pass {
486515
log(" Match FSM encodings using the description from the file.\n");
487516
log(" See 'help fsm_recode' for details.\n");
488517
log("\n");
518+
log(" -make_assert\n");
519+
log(" Check equivalence with $assert cells instead of $equiv.\n");
520+
log(" $eqx (===) is used to compare signals.");
521+
log("\n");
489522
log("Note: The circuit created by this command is not a miter (with something like\n");
490523
log("a trigger output), but instead uses $equiv cells to encode the equivalence\n");
491524
log("checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n");
@@ -496,6 +529,7 @@ struct EquivMakePass : public Pass {
496529
EquivMakeWorker worker;
497530
worker.ct.setup(design);
498531
worker.inames = false;
532+
worker.make_assert = false;
499533

500534
size_t argidx;
501535
for (argidx = 1; argidx < args.size(); argidx++)
@@ -512,6 +546,10 @@ struct EquivMakePass : public Pass {
512546
worker.encfiles.push_back(args[++argidx]);
513547
continue;
514548
}
549+
if (args[argidx] == "-make_assert") {
550+
worker.make_assert = true;
551+
continue;
552+
}
515553
break;
516554
}
517555

+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)