From 0f6e914ef63d06ae77b54d246b61118c19647f26 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 08:34:58 -0700 Subject: Another muxpack test --- tests/various/muxpack.v | 17 +++++++++++++++++ tests/various/muxpack.ys | 15 +++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/tests/various/muxpack.v b/tests/various/muxpack.v index f1bd5ea8e..41dfed396 100644 --- a/tests/various/muxpack.v +++ b/tests/various/muxpack.v @@ -136,3 +136,20 @@ always @* else o <= i[7*W+:W]; endmodule + +module mux_if_bal_5_1 #(parameter N=5, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o); +always @* + if (s[0] == 1'b0) + if (s[1] == 1'b0) + if (s[2] == 1'b0) + o <= i[0*W+:W]; + else + o <= i[1*W+:W]; + else + if (s[2] == 1'b0) + o <= i[2*W+:W]; + else + o <= i[3*W+:W]; + else + o <= i[4*W+:W]; +endmodule diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys index 9ea743b9f..dd3c143d8 100644 --- a/tests/various/muxpack.ys +++ b/tests/various/muxpack.ys @@ -148,3 +148,18 @@ design -import gold -as gold design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top mux_if_bal_5_1 +prep +design -save gold +muxpack +opt +stat +select -assert-count 2 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter -- cgit v1.2.3 From 5ab59cd59ee90abc4b6991486854dbe4c3f4d0a4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 11:36:19 -0700 Subject: Resolve @cliffordwolf comment on sigmap --- passes/opt/muxpack.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index 8c4db4e4d..b060389e3 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -94,9 +94,9 @@ struct MuxpackWorker { log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); - SigSpec a_sig = cell->getPort("\\A"); + SigSpec a_sig = sigmap(cell->getPort("\\A")); if (cell->type == "$mux") { - SigSpec b_sig = cell->getPort("\\B"); + SigSpec b_sig = sigmap(cell->getPort("\\B")); if (sig_chain_prev.count(a_sig) + sig_chain_prev.count(b_sig) != 1) goto start_cell; -- cgit v1.2.3 From 887df8914c64220b9f306b7d21f199fa247224fd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 11:37:52 -0700 Subject: Resolve @cliffordwolf comment on redundant check --- passes/opt/muxpack.cc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index b060389e3..15a646e2e 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -109,17 +109,9 @@ struct MuxpackWorker } else log_abort(); - { - for (auto bit : a_sig.bits()) - if (sigbit_with_non_chain_users.count(bit)) - goto start_cell; - - Cell *c1 = sig_chain_prev.at(a_sig); - Cell *c2 = cell; - - if (c1->getParam("\\WIDTH") != c2->getParam("\\WIDTH")) + for (auto bit : a_sig.bits()) + if (sigbit_with_non_chain_users.count(bit)) goto start_cell; - } continue; -- cgit v1.2.3 From e263bc249b905195120fbc074c6f80d03fb21cf8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 11:54:29 -0700 Subject: Add nonexclusive test from @cliffordwolf --- tests/various/muxpack.v | 13 +++++++++++++ tests/various/muxpack.ys | 15 +++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/tests/various/muxpack.v b/tests/various/muxpack.v index 41dfed396..f3c25db8d 100644 --- a/tests/various/muxpack.v +++ b/tests/various/muxpack.v @@ -153,3 +153,16 @@ always @* else o <= i[4*W+:W]; endmodule + +module cliffordwolf_nonexclusive_select ( + input wire x, y, z, + input wire a, b, c, d, + output reg o +); + always @* begin + o = a; + if (x) o = b; + if (y) o = c; + if (z) o = d; + end +endmodule diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys index dd3c143d8..7c3fe5070 100644 --- a/tests/various/muxpack.ys +++ b/tests/various/muxpack.ys @@ -163,3 +163,18 @@ design -import gold -as gold design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top cliffordwolf_nonexclusive_select +prep +design -save gold +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter -- cgit v1.2.3 From 1da12c5071a738504d22e68d66cab7c5c5afb07e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 12:12:11 -0700 Subject: Add @cliffordwolf freduce testcase --- tests/various/muxpack.v | 13 +++++++++++++ tests/various/muxpack.ys | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/tests/various/muxpack.v b/tests/various/muxpack.v index f3c25db8d..d45ce4045 100644 --- a/tests/various/muxpack.v +++ b/tests/various/muxpack.v @@ -166,3 +166,16 @@ module cliffordwolf_nonexclusive_select ( if (z) o = d; end endmodule + +module cliffordwolf_freduce ( + input wire [1:0] s, + input wire a, b, c, d, + output reg [3:0] o +); + always @* begin + o = {4{a}}; + if (s == 0) o = {3{b}}; + if (s == 1) o = {2{c}}; + if (s == 2) o = d; + end +endmodule diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys index 7c3fe5070..afdacdf30 100644 --- a/tests/various/muxpack.ys +++ b/tests/various/muxpack.ys @@ -178,3 +178,20 @@ design -import gold -as gold design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + +design -load read +hierarchy -top cliffordwolf_freduce +prep +design -save gold +proc; opt; freduce; opt +write_verilog -noexpr -norename +muxpack +opt +stat +select -assert-count 0 t:$mux +select -assert-count 1 t:$pmux +design -stash gate +design -import gold -as gold +design -import gate -as gate +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports miter -- cgit v1.2.3 From 9b408838f191bb0390b6edff55770cab8e8ca15d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 14:18:17 -0700 Subject: Add ExclusiveDatabase to check exclusive $eq/$logic_not cell results --- passes/opt/muxpack.cc | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index 15a646e2e..0cf9e0e30 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -24,6 +24,58 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +struct ExclusiveDatabase +{ + Module *module; + const SigMap &sigmap; + + dict sig_cmp_prev; + dict> sig_exclusive; + + ExclusiveDatabase(Module *module, const SigMap &sigmap) : module(module), sigmap(sigmap) + { + SigSpec a_port, b_port, y_port; + for (auto cell : module->cells()) { + if (cell->type == "$eq") { + a_port = sigmap(cell->getPort("\\A")); + b_port = sigmap(cell->getPort("\\B")); + if (!b_port.is_fully_const()) { + if (!a_port.is_fully_const()) + continue; + std::swap(a_port, b_port); + } + y_port = sigmap(cell->getPort("\\Y")); + } + else if (cell->type == "$logic_not") { + a_port = sigmap(cell->getPort("\\A")); + b_port = Const(RTLIL::S0, GetSize(a_port)); + y_port = sigmap(cell->getPort("\\Y")); + } + else continue; + + auto r = sig_exclusive[a_port].insert(b_port.as_const()); + if (!r.second) + continue; + sig_cmp_prev[y_port] = a_port; + } + } + + bool query(const SigSpec& sig1, const SigSpec& sig2) const + { + auto it = sig_cmp_prev.find(sig1); + if (it == sig_cmp_prev.end()) + return false; + + auto jt = sig_cmp_prev.find(sig2); + if (jt == sig_cmp_prev.end()) + return false; + + log("query = %s %s\n", log_signal(it->second), log_signal(jt->second)); + return it->second == jt->second; + } +}; + + struct MuxpackWorker { Module *module; @@ -39,6 +91,8 @@ struct MuxpackWorker pool chain_start_cells; pool candidate_cells; + ExclusiveDatabase excl_db; + void make_sig_chain_next_prev() { for (auto wire : module->wires()) @@ -90,6 +144,7 @@ struct MuxpackWorker void find_chain_start_cells() { + Cell* first_cell = nullptr; for (auto cell : candidate_cells) { log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); @@ -102,6 +157,13 @@ struct MuxpackWorker if (!sig_chain_prev.count(a_sig)) a_sig = b_sig; + + if (first_cell) { + SigSpec s_sig = sigmap(cell->getPort("\\S")); + SigSpec prev_s_sig = sigmap(first_cell->getPort("\\S")); + if (!excl_db.query(prev_s_sig, s_sig)) + goto start_cell; + } } else if (cell->type == "$pmux") { if (!sig_chain_prev.count(a_sig)) @@ -117,6 +179,7 @@ struct MuxpackWorker start_cell: chain_start_cells.insert(cell); + first_cell = cell; } } @@ -208,7 +271,7 @@ struct MuxpackWorker } MuxpackWorker(Module *module) : - module(module), sigmap(module), mux_count(0), pmux_count(0) + module(module), sigmap(module), mux_count(0), pmux_count(0), excl_db(module, sigmap) { make_sig_chain_next_prev(); find_chain_start_cells(); -- cgit v1.2.3 From ba52d9b4716b287b0a469597b748f9859e897329 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 15:34:16 -0700 Subject: Extend ExclusiveDatabase to query SigSpec-s (for $pmux) --- passes/opt/muxpack.cc | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index 0cf9e0e30..4b02df394 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -29,7 +29,7 @@ struct ExclusiveDatabase Module *module; const SigMap &sigmap; - dict sig_cmp_prev; + dict sig_cmp_prev; dict> sig_exclusive; ExclusiveDatabase(Module *module, const SigMap &sigmap) : module(module), sigmap(sigmap) @@ -62,16 +62,23 @@ struct ExclusiveDatabase bool query(const SigSpec& sig1, const SigSpec& sig2) const { - auto it = sig_cmp_prev.find(sig1); - if (it == sig_cmp_prev.end()) - return false; - - auto jt = sig_cmp_prev.find(sig2); - if (jt == sig_cmp_prev.end()) - return false; + // FIXME: O(N) + for (auto bit1 : sig1.bits()) { + auto it = sig_cmp_prev.find(bit1); + if (it == sig_cmp_prev.end()) + return false; + + for (auto bit2 : sig2.bits()) { + auto jt = sig_cmp_prev.find(bit2); + if (jt == sig_cmp_prev.end()) + return false; + + if (it->second != jt->second) + return false; + } + } - log("query = %s %s\n", log_signal(it->second), log_signal(jt->second)); - return it->second == jt->second; + return true; } }; @@ -144,7 +151,6 @@ struct MuxpackWorker void find_chain_start_cells() { - Cell* first_cell = nullptr; for (auto cell : candidate_cells) { log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); @@ -157,13 +163,6 @@ struct MuxpackWorker if (!sig_chain_prev.count(a_sig)) a_sig = b_sig; - - if (first_cell) { - SigSpec s_sig = sigmap(cell->getPort("\\S")); - SigSpec prev_s_sig = sigmap(first_cell->getPort("\\S")); - if (!excl_db.query(prev_s_sig, s_sig)) - goto start_cell; - } } else if (cell->type == "$pmux") { if (!sig_chain_prev.count(a_sig)) @@ -175,11 +174,19 @@ struct MuxpackWorker if (sigbit_with_non_chain_users.count(bit)) goto start_cell; + { + Cell *prev_cell = sig_chain_prev.at(a_sig); + log_assert(prev_cell); + SigSpec s_sig = sigmap(cell->getPort("\\S")); + SigSpec next_s_sig = sigmap(prev_cell->getPort("\\S")); + if (!excl_db.query(s_sig, next_s_sig)) + goto start_cell; + } + continue; start_cell: chain_start_cells.insert(cell); - first_cell = cell; } } @@ -243,6 +250,7 @@ struct MuxpackWorker s_sig.append(cursor_cell->getPort("\\S")); } else { + log_assert(cursor_cell->type == "$mux"); b_sig.append(cursor_cell->getPort("\\A")); s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort("\\S"))); } -- cgit v1.2.3 From b959bf79c004fdf81ccc397d5aa774b67a09d6da Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 15:35:15 -0700 Subject: Add nonexcl case test, comment out two others --- tests/various/muxpack.v | 18 ++++++++++++++ tests/various/muxpack.ys | 61 +++++++++++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 22 deletions(-) diff --git a/tests/various/muxpack.v b/tests/various/muxpack.v index d45ce4045..3a1086dbf 100644 --- a/tests/various/muxpack.v +++ b/tests/various/muxpack.v @@ -179,3 +179,21 @@ module cliffordwolf_freduce ( if (s == 2) o = d; end endmodule + +module case_nonexclusive_select ( + input wire [1:0] x, y, + input wire a, b, c, d, e, + output reg o +); + always @* begin + case (x) + 0, 2: o = b; + 1: o = c; + default: begin + o = a; + if (y == 0) o = d; + if (y == 1) o = e; + end + endcase + end +endmodule diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys index afdacdf30..579dad8d3 100644 --- a/tests/various/muxpack.ys +++ b/tests/various/muxpack.ys @@ -1,5 +1,6 @@ read_verilog muxpack.v design -save read + hierarchy -top mux_if_unbal_4_1 prep design -save gold @@ -29,20 +30,21 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter -design -load read -hierarchy -top mux_if_unbal_5_3_invert -prep -design -save gold -muxpack -opt -stat -select -assert-count 0 t:$mux -select -assert-count 1 t:$pmux -design -stash gate -design -import gold -as gold -design -import gate -as gate -miter -equiv -flatten -make_assert -make_outputs gold gate miter -sat -verify -prove-asserts -show-ports miter +# TODO: Currently ExclusiveDatabase only analyses $eq cells +#design -load read +#hierarchy -top mux_if_unbal_5_3_invert +#prep +#design -save gold +#muxpack +#opt +#stat +#select -assert-count 0 t:$mux +#select -assert-count 1 t:$pmux +#design -stash gate +#design -import gold -as gold +#design -import gate -as gate +#miter -equiv -flatten -make_assert -make_outputs gold gate miter +#sat -verify -prove-asserts -show-ports miter design -load read hierarchy -top mux_if_unbal_5_3_width_mismatch @@ -156,8 +158,8 @@ design -save gold muxpack opt stat -select -assert-count 2 t:$mux -select -assert-count 1 t:$pmux +select -assert-count 4 t:$mux +select -assert-count 0 t:$pmux design -stash gate design -import gold -as gold design -import gate -as gate @@ -171,25 +173,40 @@ design -save gold muxpack opt stat -select -assert-count 0 t:$mux -select -assert-count 1 t:$pmux +select -assert-count 3 t:$mux +select -assert-count 0 t:$pmux design -stash gate design -import gold -as gold design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter +#design -load read +#hierarchy -top cliffordwolf_freduce +#prep +#design -save gold +#proc; opt; freduce; opt +#show +#muxpack +#opt +#stat +#select -assert-count 0 t:$mux +#select -assert-count 1 t:$pmux +#design -stash gate +#design -import gold -as gold +#design -import gate -as gate +#miter -equiv -flatten -make_assert -make_outputs gold gate miter +#sat -verify -prove-asserts -show-ports miter + design -load read -hierarchy -top cliffordwolf_freduce +hierarchy -top case_nonexclusive_select prep design -save gold -proc; opt; freduce; opt -write_verilog -noexpr -norename muxpack opt stat select -assert-count 0 t:$mux -select -assert-count 1 t:$pmux +select -assert-count 2 t:$pmux design -stash gate design -import gold -as gold design -import gate -as gate -- cgit v1.2.3 From f705f6a0b5d19d38cf41ba5f782847de54110463 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 15:39:12 -0700 Subject: Comment O(N) -> O(N^2) --- passes/opt/muxpack.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index 4b02df394..f01d5474d 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -62,7 +62,7 @@ struct ExclusiveDatabase bool query(const SigSpec& sig1, const SigSpec& sig2) const { - // FIXME: O(N) + // FIXME: O(N^2) for (auto bit1 : sig1.bits()) { auto it = sig_cmp_prev.find(bit1); if (it == sig_cmp_prev.end()) -- cgit v1.2.3 From 5b999ae68decef5646ef0ccac53463f22fe18d8f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 10 Jun 2019 10:32:19 -0700 Subject: Elaborate muxpack doc --- passes/opt/muxpack.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index f01d5474d..b6f3313bf 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -302,8 +302,12 @@ struct MuxpackPass : public Pass { log(" muxpack [selection]\n"); log("\n"); log("This pass converts cascaded chains of $pmux cells (e.g. those create from case\n"); - log("constructs) and $mux cells (e.g. those created by if-else constructs) into \n"); - log("into $pmux cells.\n"); + log("constructs) and $mux cells (e.g. those created by if-else constructs) into\n"); + log("$pmux cells.\n"); + log("\n"); + log("This optimisation is conservative --- it will only pack $mux or $pmux cells with\n"); + log("other such cells if it can be certain that the select lines are mutually\n"); + log("exclusive.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE -- cgit v1.2.3