mirror of https://github.com/YosysHQ/yosys.git
Improvements in equiv_struct
This commit is contained in:
parent
d014ba2d0e
commit
27714acd8a
|
@ -169,13 +169,14 @@ struct EquivStructWorker
|
|||
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
SigSpec sig = equiv_bits(conn.second);
|
||||
|
||||
if (cell->input(conn.first))
|
||||
if (cell->input(conn.first)) {
|
||||
SigSpec sig = sigmap(conn.second);
|
||||
for (int i = 0; i < GetSize(sig); i++)
|
||||
fwd_connections.push_back(make_tuple(conn.first, i, sig[i]));
|
||||
}
|
||||
|
||||
if (cell->output(conn.first))
|
||||
if (cell->output(conn.first)) {
|
||||
SigSpec sig = equiv_bits(conn.second);
|
||||
for (int i = 0; i < GetSize(sig); i++) {
|
||||
key.connections.clear();
|
||||
key.connections.push_back(make_tuple(conn.first, i, sig[i]));
|
||||
|
@ -185,6 +186,7 @@ struct EquivStructWorker
|
|||
merge_cache[key].insert(cell_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(fwd_connections.begin(), fwd_connections.end());
|
||||
key.connections.swap(fwd_connections);
|
||||
|
@ -200,26 +202,65 @@ struct EquivStructWorker
|
|||
|
||||
for (auto &key : queue)
|
||||
{
|
||||
Cell *gold_cell = nullptr;
|
||||
pool<Cell*> cells;
|
||||
const char *strategy = nullptr;
|
||||
vector<Cell*> gold_cells, gate_cells, other_cells;
|
||||
vector<pair<Cell*, Cell*>> cell_pairs;
|
||||
|
||||
for (auto cell_name : merge_cache[key]) {
|
||||
Cell *c = module->cell(cell_name);
|
||||
if (c != nullptr) {
|
||||
string n = cell_name.str();
|
||||
if (gold_cell == nullptr || (GetSize(n) > 5 && n.substr(GetSize(n)-5) == "_gold"))
|
||||
gold_cell = c;
|
||||
cells.insert(c);
|
||||
if (GetSize(n) > 5 && n.substr(GetSize(n)-5) == "_gold")
|
||||
gold_cells.push_back(c);
|
||||
else if (GetSize(n) > 5 && n.substr(GetSize(n)-5) == "_gate")
|
||||
gate_cells.push_back(c);
|
||||
else
|
||||
other_cells.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetSize(cells) < 2)
|
||||
if (GetSize(gold_cells) > 1 || GetSize(gate_cells) > 1 || GetSize(other_cells) > 1)
|
||||
{
|
||||
strategy = "deduplicate";
|
||||
for (int i = 0; i+1 < GetSize(gold_cells); i += 2)
|
||||
cell_pairs.push_back(make_pair(gold_cells[i], gold_cells[i+1]));
|
||||
for (int i = 0; i+1 < GetSize(gate_cells); i += 2)
|
||||
cell_pairs.push_back(make_pair(gate_cells[i], gate_cells[i+1]));
|
||||
for (int i = 0; i+1 < GetSize(other_cells); i += 2)
|
||||
cell_pairs.push_back(make_pair(other_cells[i], other_cells[i+1]));
|
||||
goto run_strategy;
|
||||
}
|
||||
|
||||
if (GetSize(gold_cells) == 1 && GetSize(gate_cells) == 1)
|
||||
{
|
||||
strategy = "gold-gate-pairs";
|
||||
cell_pairs.push_back(make_pair(gold_cells[0], gate_cells[0]));
|
||||
goto run_strategy;
|
||||
}
|
||||
|
||||
if (GetSize(gold_cells) == 1 && GetSize(other_cells) == 1)
|
||||
{
|
||||
strategy = "gold-guess";
|
||||
cell_pairs.push_back(make_pair(gold_cells[0], other_cells[0]));
|
||||
goto run_strategy;
|
||||
}
|
||||
|
||||
if (GetSize(other_cells) == 1 && GetSize(gate_cells) == 1)
|
||||
{
|
||||
strategy = "gate-guess";
|
||||
cell_pairs.push_back(make_pair(other_cells[0], gate_cells[0]));
|
||||
goto run_strategy;
|
||||
}
|
||||
|
||||
log_assert(GetSize(gold_cells) + GetSize(gate_cells) + GetSize(other_cells) < 2);
|
||||
continue;
|
||||
|
||||
for (auto gate_cell : cells)
|
||||
if (gate_cell != gold_cell) {
|
||||
log(" %s merging cells %s and %s.\n", phase ? "Bwd" : "Fwd", log_id(gold_cell), log_id(gate_cell));
|
||||
merge_cell_pair(gold_cell, gate_cell);
|
||||
run_strategy:
|
||||
log(" %s merging %d cells (from group of %d) using strategy %s:\n", phase ? "Bwd" : "Fwd",
|
||||
2*GetSize(cell_pairs), GetSize(gold_cells) + GetSize(gate_cells) + GetSize(other_cells), strategy);
|
||||
for (auto it : cell_pairs) {
|
||||
log(" Merging cells %s and %s.\n", log_id(it.first), log_id(it.second));
|
||||
merge_cell_pair(it.first, it.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,12 +319,16 @@ struct EquivStructPass : public Pass {
|
|||
extra_args(args, argidx, design);
|
||||
|
||||
for (auto module : design->selected_modules()) {
|
||||
int module_merge_count = 0;
|
||||
log("Running equiv_struct on module %s:\n", log_id(module));
|
||||
while (1) {
|
||||
EquivStructWorker worker(module, mode_fwd, mode_icells);
|
||||
if (worker.merge_count == 0)
|
||||
break;
|
||||
module_merge_count += worker.merge_count;
|
||||
}
|
||||
if (module_merge_count)
|
||||
log(" Performed a total of %d merges in module %s.\n", module_merge_count, log_id(module));
|
||||
}
|
||||
}
|
||||
} EquivStructPass;
|
||||
|
|
Loading…
Reference in New Issue