@@ -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;
@@ -133,6 +134,12 @@ struct EquivMakeWorker
133
134
delete gate_clone;
134
135
}
135
136
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
+
136
143
void find_same_wires ()
137
144
{
138
145
SigMap assign_map (equiv_mod);
@@ -231,15 +238,24 @@ struct EquivMakeWorker
231
238
232
239
if (gold_wire->port_output || gate_wire->port_output )
233
240
{
234
- Wire *wire = equiv_mod->addWire (id, gold_wire->width );
235
- wire->port_output = true ;
236
241
gold_wire->port_input = false ;
237
242
gate_wire->port_input = false ;
238
243
gold_wire->port_output = false ;
239
244
gate_wire->port_output = false ;
240
245
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
+ }
243
259
244
260
rd_signal_map.add (assign_map (gold_wire), wire);
245
261
rd_signal_map.add (assign_map (gate_wire), wire);
@@ -259,26 +275,31 @@ struct EquivMakeWorker
259
275
}
260
276
else
261
277
{
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) ;
264
280
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));
273
298
}
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
- }
279
299
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
+ }
282
303
}
283
304
}
284
305
@@ -335,12 +356,20 @@ struct EquivMakeWorker
335
356
continue ;
336
357
}
337
358
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
+ }
344
373
345
374
gold_cell->setPort (gold_conn.first , gold_sig);
346
375
}
@@ -417,6 +446,10 @@ struct EquivMakePass : public Pass {
417
446
log (" Match FSM encodings using the description from the file.\n " );
418
447
log (" See 'help fsm_recode' for details.\n " );
419
448
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 " );
420
453
log (" Note: The circuit created by this command is not a miter (with something like\n " );
421
454
log (" a trigger output), but instead uses $equiv cells to encode the equivalence\n " );
422
455
log (" checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n " );
@@ -427,6 +460,7 @@ struct EquivMakePass : public Pass {
427
460
EquivMakeWorker worker;
428
461
worker.ct .setup (design);
429
462
worker.inames = false ;
463
+ worker.make_assert = false ;
430
464
431
465
size_t argidx;
432
466
for (argidx = 1 ; argidx < args.size (); argidx++)
@@ -443,6 +477,10 @@ struct EquivMakePass : public Pass {
443
477
worker.encfiles .push_back (args[++argidx]);
444
478
continue ;
445
479
}
480
+ if (args[argidx] == " -make_assert" ) {
481
+ worker.make_assert = true ;
482
+ continue ;
483
+ }
446
484
break ;
447
485
}
448
486
0 commit comments