@@ -33,6 +33,7 @@ struct EquivMakeWorker
33
33
bool inames;
34
34
vector<string> blacklists;
35
35
vector<string> encfiles;
36
+ bool make_assert;
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 (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
+
146
153
void find_same_wires ()
147
154
{
148
155
SigMap assign_map (equiv_mod);
@@ -240,15 +247,24 @@ 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
+ 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
+ }
252
268
253
269
rd_signal_map.add (assign_map (gold_wire), wire);
254
270
rd_signal_map.add (assign_map (gate_wire), wire);
@@ -265,26 +281,31 @@ struct EquivMakeWorker
265
281
}
266
282
else
267
283
{
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) ;
270
286
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));
279
304
}
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
305
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
+ }
288
309
}
289
310
}
290
311
@@ -353,12 +374,20 @@ struct EquivMakeWorker
353
374
continue ;
354
375
}
355
376
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
+ }
362
391
363
392
gold_cell->setPort (gold_conn.first , gold_sig);
364
393
}
@@ -486,6 +515,10 @@ struct EquivMakePass : public Pass {
486
515
log (" Match FSM encodings using the description from the file.\n " );
487
516
log (" See 'help fsm_recode' for details.\n " );
488
517
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 " );
489
522
log (" Note: The circuit created by this command is not a miter (with something like\n " );
490
523
log (" a trigger output), but instead uses $equiv cells to encode the equivalence\n " );
491
524
log (" checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n " );
@@ -496,6 +529,7 @@ struct EquivMakePass : public Pass {
496
529
EquivMakeWorker worker;
497
530
worker.ct .setup (design);
498
531
worker.inames = false ;
532
+ worker.make_assert = false ;
499
533
500
534
size_t argidx;
501
535
for (argidx = 1 ; argidx < args.size (); argidx++)
@@ -512,6 +546,10 @@ struct EquivMakePass : public Pass {
512
546
worker.encfiles .push_back (args[++argidx]);
513
547
continue ;
514
548
}
549
+ if (args[argidx] == " -make_assert" ) {
550
+ worker.make_assert = true ;
551
+ continue ;
552
+ }
515
553
break ;
516
554
}
517
555
0 commit comments