aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-10-17 12:15:14 +0200
committerGitHub <noreply@github.com>2018-10-17 12:15:14 +0200
commit08be796cb8b1890923e459cda92211fda763f0c1 (patch)
tree9eee9647a492fccf679a6771fcc17c129bbd5d62
parent38dbb44fa0815b1fe80e68e17798aaa341d998cd (diff)
parentf4343b3dc7dfb1908848b21b406f13884e8c407a (diff)
downloadyosys-08be796cb8b1890923e459cda92211fda763f0c1.tar.gz
yosys-08be796cb8b1890923e459cda92211fda763f0c1.tar.bz2
yosys-08be796cb8b1890923e459cda92211fda763f0c1.zip
Merge pull request #641 from tklam/master
Fix issue #639
-rw-r--r--passes/equiv/equiv_make.cc69
1 files changed, 69 insertions, 0 deletions
diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc
index b1f88d55e..66ee28aff 100644
--- a/passes/equiv/equiv_make.cc
+++ b/passes/equiv/equiv_make.cc
@@ -40,6 +40,16 @@ struct EquivMakeWorker
pool<SigBit> undriven_bits;
SigMap assign_map;
+ dict<SigBit, pool<Cell*>> bit2driven; // map: bit <--> and its driven cells
+
+ CellTypes comb_ct;
+
+ EquivMakeWorker()
+ {
+ comb_ct.setup_internals();
+ comb_ct.setup_stdcells();
+ }
+
void read_blacklists()
{
for (auto fn : blacklists)
@@ -278,12 +288,20 @@ struct EquivMakeWorker
}
}
+ init_bit2driven();
+
+ pool<Cell*> visited_cells;
for (auto c : cells_list)
for (auto &conn : c->connections())
if (!ct.cell_output(c->type, conn.first)) {
SigSpec old_sig = assign_map(conn.second);
SigSpec new_sig = rd_signal_map(old_sig);
+
+ visited_cells.clear();
if (old_sig != new_sig) {
+ if (check_signal_in_fanout(visited_cells, old_sig, new_sig))
+ continue;
+
log("Changing input %s of cell %s (%s): %s -> %s\n",
log_id(conn.first), log_id(c), log_id(c->type),
log_signal(old_sig), log_signal(new_sig));
@@ -378,6 +396,57 @@ struct EquivMakeWorker
}
}
+ void init_bit2driven()
+ {
+ for (auto cell : equiv_mod->cells()) {
+ if (!ct.cell_known(cell->type) && !cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_"))
+ continue;
+ for (auto &conn : cell->connections())
+ {
+ if (yosys_celltypes.cell_input(cell->type, conn.first))
+ for (auto bit : assign_map(conn.second))
+ {
+ bit2driven[bit].insert(cell);
+ }
+ }
+ }
+ }
+
+ bool check_signal_in_fanout(pool<Cell*> & visited_cells, SigBit source_bit, SigBit target_bit)
+ {
+ if (source_bit == target_bit)
+ return true;
+
+ if (bit2driven.count(source_bit) == 0)
+ return false;
+
+ auto driven_cells = bit2driven.at(source_bit);
+ for (auto driven_cell: driven_cells)
+ {
+ bool is_comb = comb_ct.cell_known(driven_cell->type);
+ if (!is_comb)
+ continue;
+
+ if (visited_cells.count(driven_cell) > 0)
+ continue;
+ visited_cells.insert(driven_cell);
+
+ for (auto &conn: driven_cell->connections())
+ {
+ if (yosys_celltypes.cell_input(driven_cell->type, conn.first))
+ continue;
+
+ for (auto bit: conn.second) {
+ bool is_in_fanout = check_signal_in_fanout(visited_cells, bit, target_bit);
+ if (is_in_fanout == true)
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
void run()
{
copy_to_equiv();