@@ -33,6 +33,7 @@ struct EquivMakeWorker
33
33
bool inames;
34
34
vector<string> blacklists;
35
35
vector<string> encfiles;
36
+ bool emit_assertions;
36
37
37
38
pool<IdString> blacklist_names;
38
39
dict<IdString, dict<Const, Const>> encdata;
@@ -143,6 +144,12 @@ struct EquivMakeWorker
143
144
delete gate_clone;
144
145
}
145
146
147
+ void add_eq_assertion (IdString sig_id, 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, eq_wire, State::S1, " $equiv_make$assert:" + sig_id.str ());
151
+ }
152
+
146
153
void find_same_wires ()
147
154
{
148
155
SigMap assign_map (equiv_mod);
@@ -240,18 +247,25 @@ struct EquivMakeWorker
240
247
241
248
if (gold_wire->port_output || gate_wire->port_output )
242
249
{
243
- Wire *wire = equiv_mod->addWire (id, gold_wire->width );
244
- wire->port_output = true ;
245
250
gold_wire->port_input = false ;
246
251
gate_wire->port_input = false ;
247
252
gold_wire->port_output = false ;
248
253
gate_wire->port_output = false ;
249
254
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
+ if (emit_assertions)
256
+ add_eq_assertion (id, gold_wire, gate_wire);
257
+
258
+ else
259
+ {
260
+ Wire *wire = equiv_mod->addWire (id, gold_wire->width );
261
+ wire->port_output = true ;
262
+
263
+ for (int i = 0 ; i < wire->width ; i++)
264
+ equiv_mod->addEquiv (NEW_ID, SigSpec (gold_wire, i), SigSpec (gate_wire, i), SigSpec (wire, i));
252
265
253
- rd_signal_map.add (assign_map (gold_wire), wire);
254
- rd_signal_map.add (assign_map (gate_wire), wire);
266
+ rd_signal_map.add (assign_map (gold_wire), wire);
267
+ rd_signal_map.add (assign_map (gate_wire), wire);
268
+ }
255
269
}
256
270
else
257
271
if (gold_wire->port_input || gate_wire->port_input )
@@ -265,26 +279,31 @@ struct EquivMakeWorker
265
279
}
266
280
else
267
281
{
268
- Wire *wire = equiv_mod-> addWire (id, gold_wire-> width );
269
- SigSpec rdmap_gold, rdmap_gate, rdmap_equiv ;
282
+ if (emit_assertions)
283
+ add_eq_assertion (id, gold_wire, gate_wire) ;
270
284
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 ;
285
+ else {
286
+ Wire *wire = equiv_mod->addWire (id, gold_wire->width );
287
+ SigSpec rdmap_gold, rdmap_gate, rdmap_equiv;
288
+
289
+ for (int i = 0 ; i < wire->width ; i++) {
290
+ if (undriven_bits.count (assign_map (SigBit (gold_wire, i)))) {
291
+ log (" Skipping signal bit %s [%d]: undriven on gold side.\n " , id2cstr (gold_wire->name ), i);
292
+ continue ;
293
+ }
294
+ if (undriven_bits.count (assign_map (SigBit (gate_wire, i)))) {
295
+ log (" Skipping signal bit %s [%d]: undriven on gate side.\n " , id2cstr (gate_wire->name ), i);
296
+ continue ;
297
+ }
298
+ equiv_mod->addEquiv (NEW_ID, SigSpec (gold_wire, i), SigSpec (gate_wire, i), SigSpec (wire, i));
299
+ rdmap_gold.append (SigBit (gold_wire, i));
300
+ rdmap_gate.append (SigBit (gate_wire, i));
301
+ rdmap_equiv.append (SigBit (wire, i));
279
302
}
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
- }
285
303
286
- rd_signal_map.add (rdmap_gold, rdmap_equiv);
287
- rd_signal_map.add (rdmap_gate, rdmap_equiv);
304
+ rd_signal_map.add (rdmap_gold, rdmap_equiv);
305
+ rd_signal_map.add (rdmap_gate, rdmap_equiv);
306
+ }
288
307
}
289
308
}
290
309
@@ -353,12 +372,20 @@ struct EquivMakeWorker
353
372
continue ;
354
373
}
355
374
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
- }
375
+ if (emit_assertions)
376
+ {
377
+ if (gold_sig != gate_sig)
378
+ add_eq_assertion (id, gold_sig, gate_sig);
379
+ }
380
+ else
381
+ {
382
+ for (int i = 0 ; i < GetSize (gold_sig); i++)
383
+ if (gold_sig[i] != gate_sig[i]) {
384
+ Wire *w = equiv_mod->addWire (NEW_ID);
385
+ equiv_mod->addEquiv (NEW_ID, gold_sig[i], gate_sig[i], w);
386
+ gold_sig[i] = w;
387
+ }
388
+ }
362
389
363
390
gold_cell->setPort (gold_conn.first , gold_sig);
364
391
}
@@ -486,6 +513,9 @@ struct EquivMakePass : public Pass {
486
513
log (" Match FSM encodings using the description from the file.\n " );
487
514
log (" See 'help fsm_recode' for details.\n " );
488
515
log (" \n " );
516
+ log (" -assert\n " );
517
+ log (" Create $eqx and $assert cells to encode equivalence instead of $equiv.\n " );
518
+ log (" \n " );
489
519
log (" Note: The circuit created by this command is not a miter (with something like\n " );
490
520
log (" a trigger output), but instead uses $equiv cells to encode the equivalence\n " );
491
521
log (" checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n " );
@@ -496,6 +526,7 @@ struct EquivMakePass : public Pass {
496
526
EquivMakeWorker worker;
497
527
worker.ct .setup (design);
498
528
worker.inames = false ;
529
+ worker.emit_assertions = false ;
499
530
500
531
size_t argidx;
501
532
for (argidx = 1 ; argidx < args.size (); argidx++)
@@ -512,6 +543,10 @@ struct EquivMakePass : public Pass {
512
543
worker.encfiles .push_back (args[++argidx]);
513
544
continue ;
514
545
}
546
+ if (args[argidx] == " -assert" ) {
547
+ worker.emit_assertions = true ;
548
+ continue ;
549
+ }
515
550
break ;
516
551
}
517
552
0 commit comments