Improvements in equiv_struct

This commit is contained in:
Clifford Wolf 2015-10-23 15:11:57 +02:00
parent 84a07ffb8a
commit d19069b0fb
1 changed files with 18 additions and 11 deletions

View File

@ -28,7 +28,7 @@ struct EquivStructWorker
Module *module; Module *module;
SigMap sigmap; SigMap sigmap;
SigMap equiv_bits; SigMap equiv_bits;
bool mode_nortl; bool mode_icells;
int merge_count; int merge_count;
dict<IdString, pool<IdString>> cells_by_type; dict<IdString, pool<IdString>> cells_by_type;
@ -39,6 +39,7 @@ struct EquivStructWorker
return; return;
bool merge_this_cells = false; bool merge_this_cells = false;
bool found_diff_inputs = false;
vector<SigSpec> inputs_a, inputs_b; vector<SigSpec> inputs_a, inputs_b;
for (auto &port_a : cell_a->connections()) for (auto &port_a : cell_a->connections())
@ -63,10 +64,14 @@ struct EquivStructWorker
if (!diff_bits_a.empty()) { if (!diff_bits_a.empty()) {
inputs_a.push_back(diff_bits_a); inputs_a.push_back(diff_bits_a);
inputs_b.push_back(diff_bits_b); inputs_b.push_back(diff_bits_b);
found_diff_inputs = true;
} }
} }
} }
if (!found_diff_inputs)
merge_this_cells = true;
if (merge_this_cells) if (merge_this_cells)
{ {
SigMap merged_map; SigMap merged_map;
@ -106,8 +111,8 @@ struct EquivStructWorker
} }
} }
EquivStructWorker(Module *module, bool mode_nortl) : EquivStructWorker(Module *module, bool mode_icells) :
module(module), sigmap(module), equiv_bits(module), mode_nortl(mode_nortl), merge_count(0) module(module), sigmap(module), equiv_bits(module), mode_icells(mode_icells), merge_count(0)
{ {
log(" Starting new iteration.\n"); log(" Starting new iteration.\n");
@ -116,7 +121,7 @@ struct EquivStructWorker
equiv_bits.add(sigmap(cell->getPort("\\A")), sigmap(cell->getPort("\\B"))); equiv_bits.add(sigmap(cell->getPort("\\A")), sigmap(cell->getPort("\\B")));
} else } else
if (module->design->selected(module, cell)) { if (module->design->selected(module, cell)) {
if (!mode_nortl || module->design->module(cell->type)) if (mode_icells || module->design->module(cell->type))
cells_by_type[cell->type].insert(cell->name); cells_by_type[cell->type].insert(cell->name);
} }
@ -151,22 +156,24 @@ struct EquivStructPass : public Pass {
log("This command adds additional $equiv cells based on the assumption that the\n"); log("This command adds additional $equiv cells based on the assumption that the\n");
log("gold and gate circuit are structurally equivalent. Note that this can introduce\n"); log("gold and gate circuit are structurally equivalent. Note that this can introduce\n");
log("bad $equiv cells in cases where the netlists are not structurally equivalent,\n"); log("bad $equiv cells in cases where the netlists are not structurally equivalent,\n");
log("for example when analyzing circuits with cells with commutative inputs.\n"); log("for example when analyzing circuits with cells with commutative inputs. This\n");
log("command will also de-duplicate gates.\n");
log("\n"); log("\n");
log(" -nortl\n"); log(" -icells\n");
log(" only operate on 'blackbox' cells and hierarchical module instantiations\n"); log(" by default, the internal RTL and gate cell types are ignored. add\n");
log(" this option to also process those cell types with this command.\n");
log("\n"); log("\n");
} }
virtual void execute(std::vector<std::string> args, Design *design) virtual void execute(std::vector<std::string> args, Design *design)
{ {
bool mode_nortl = false; bool mode_icells = false;
log_header("Executing EQUIV_STRUCT pass.\n"); log_header("Executing EQUIV_STRUCT pass.\n");
size_t argidx; size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) { for (argidx = 1; argidx < args.size(); argidx++) {
if (args[argidx] == "-bb") { if (args[argidx] == "-icells") {
mode_nortl = true; mode_icells = true;
continue; continue;
} }
break; break;
@ -176,7 +183,7 @@ struct EquivStructPass : public Pass {
for (auto module : design->selected_modules()) { for (auto module : design->selected_modules()) {
log("Running equiv_struct on module %s:", log_id(module)); log("Running equiv_struct on module %s:", log_id(module));
while (1) { while (1) {
EquivStructWorker worker(module, mode_nortl); EquivStructWorker worker(module, mode_icells);
if (worker.merge_count == 0) if (worker.merge_count == 0)
break; break;
} }