From 2b89074240b42648c6fad377156b19f21fb23fb8 Mon Sep 17 00:00:00 2001 From: TK Lam Date: Wed, 26 Sep 2018 16:11:45 +0800 Subject: [PATCH 1/4] Fix issue #639 --- passes/equiv/equiv_make.cc | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index b1f88d55e..8590c820b 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -40,6 +40,8 @@ struct EquivMakeWorker pool undriven_bits; SigMap assign_map; + dict> bit2driven; // map: bit <--> and its driven cells + void read_blacklists() { for (auto fn : blacklists) @@ -278,12 +280,20 @@ struct EquivMakeWorker } } + init_bit2driven(); + + pool 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 +388,54 @@ 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 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) + { + 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(); From b86eb3deef7d80fc5450379c80047636832ef458 Mon Sep 17 00:00:00 2001 From: tklam Date: Wed, 26 Sep 2018 17:57:39 +0800 Subject: [PATCH 2/4] fix bug: pass by reference --- passes/equiv/equiv_make.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index 8590c820b..e74dab36f 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -404,7 +404,7 @@ struct EquivMakeWorker } } - bool check_signal_in_fanout(pool visited_cells, SigBit source_bit, SigBit target_bit) + bool check_signal_in_fanout(pool & visited_cells, SigBit source_bit, SigBit target_bit) { if (source_bit == target_bit) return true; From 302edf04291467469f8f48bd60edadbf1ee54798 Mon Sep 17 00:00:00 2001 From: tklam Date: Sat, 13 Oct 2018 23:11:19 +0800 Subject: [PATCH 3/4] stop check_signal_in_fanout from traversing FFs --- passes/equiv/equiv_make.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index e74dab36f..e75482e9f 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -42,6 +42,14 @@ struct EquivMakeWorker dict> 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) @@ -415,9 +423,12 @@ struct EquivMakeWorker auto driven_cells = bit2driven.at(source_bit); for (auto driven_cell: driven_cells) { - if (visited_cells.count(driven_cell) > 0) + bool is_comb = comb_ct.cell_known(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()) From f4343b3dc7dfb1908848b21b406f13884e8c407a Mon Sep 17 00:00:00 2001 From: tklam Date: Sat, 13 Oct 2018 23:24:24 +0800 Subject: [PATCH 4/4] stop check_signal_in_fanout from traversing FFs --- passes/equiv/equiv_make.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index e75482e9f..66ee28aff 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -423,8 +423,8 @@ struct EquivMakeWorker auto driven_cells = bit2driven.at(source_bit); for (auto driven_cell: driven_cells) { - bool is_comb = comb_ct.cell_known(cell->type); - if (is_comb) + bool is_comb = comb_ct.cell_known(driven_cell->type); + if (!is_comb) continue; if (visited_cells.count(driven_cell) > 0)