From 25ff27e37fcb12c6a298267eda2464431304d713 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 12:34:04 -0700 Subject: [PATCH 01/19] SigSpec::extract to take negative lengths --- kernel/rtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a09f4a0d1..85b013bdc 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3353,7 +3353,7 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const { unpack(); cover("kernel.rtlil.sigspec.extract_pos"); - return std::vector(bits_.begin() + offset, bits_.begin() + offset + length); + return std::vector(bits_.begin() + offset, length >= 0 ? bits_.begin() + offset + length : bits_.end() + length + 1); } void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) From 3839bd50f28a16f1253a56d5871465763e72180c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 12:43:02 -0700 Subject: [PATCH 02/19] Add test --- tests/various/wreduce.ys | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/various/wreduce.ys diff --git a/tests/various/wreduce.ys b/tests/various/wreduce.ys new file mode 100644 index 000000000..0b5403fa1 --- /dev/null +++ b/tests/various/wreduce.ys @@ -0,0 +1,22 @@ + +read_verilog < Date: Fri, 19 Jul 2019 12:50:11 -0700 Subject: [PATCH 03/19] Add tests for sub too --- tests/various/wreduce.ys | 49 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/tests/various/wreduce.ys b/tests/various/wreduce.ys index 0b5403fa1..ee03e008d 100644 --- a/tests/various/wreduce.ys +++ b/tests/various/wreduce.ys @@ -5,7 +5,7 @@ module wreduce_add_test(input [3:0] i, input [7:0] j, output [7:0] o); endmodule EOT -hierarchy -top wreduce_add_test +hierarchy -auto-top proc design -save gold @@ -20,3 +20,50 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + + +### X - 0 +read_verilog < Date: Fri, 19 Jul 2019 12:50:21 -0700 Subject: [PATCH 04/19] wreduce for $sub --- passes/opt/wreduce.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 1fbc41082..e8c2cb726 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -365,6 +365,29 @@ struct WreduceWorker } } + if (cell->type.in("$add", "$sub")) { + SigSpec A = cell->getPort("\\A"); + SigSpec B = cell->getPort("\\B"); + bool sub = cell->type == "$sub"; + + int i; + for (i = 0; i < GetSize(sig); i++) { + if (B[i] != S0 && (sub || A[i] != S0)) + break; + if (B[i] == S0) + module->connect(sig[i], A[i]); + else if (A[i] == S0) + module->connect(sig[i], B[i]); + else log_abort(); + } + if (i > 0) { + cell->setPort("\\A", A.extract(i, -1)); + cell->setPort("\\B", B.extract(i, -1)); + sig.remove(0, i); + bits_removed += i; + } + } + if (GetSize(sig) == 0) { log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); module->remove(cell); From 415a2716df8c41193650804158281ef73e7fc655 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 12:53:18 -0700 Subject: [PATCH 05/19] Be more explicit --- tests/various/wreduce.ys | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/tests/various/wreduce.ys b/tests/various/wreduce.ys index ee03e008d..f9e5ed4e3 100644 --- a/tests/various/wreduce.ys +++ b/tests/various/wreduce.ys @@ -1,6 +1,6 @@ read_verilog < Date: Fri, 19 Jul 2019 13:11:30 -0700 Subject: [PATCH 06/19] Add one more test with trimming Y_WIDTH of $sub --- tests/various/wreduce.ys | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/various/wreduce.ys b/tests/various/wreduce.ys index f9e5ed4e3..8030c005e 100644 --- a/tests/various/wreduce.ys +++ b/tests/various/wreduce.ys @@ -9,7 +9,7 @@ hierarchy -auto-top proc design -save gold -prep +prep # calls wreduce select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i @@ -21,8 +21,8 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter +########## -### X - 0 read_verilog <> 4) - i; endmodule EOT @@ -79,9 +81,10 @@ hierarchy -auto-top proc design -save gold -prep +prep # calls wreduce -select -assert-count 1 t:$sub r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i +dump +select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i design -stash gate From bcd802718256efbacaf0a73f99347af40b61e464 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 13:11:48 -0700 Subject: [PATCH 07/19] Also optimise MSB of $sub --- passes/opt/wreduce.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index e8c2cb726..dff1c5370 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -342,9 +342,9 @@ struct WreduceWorker } } - if (cell->type.in("$pos", "$add", "$mul", "$and", "$or", "$xor")) + if (cell->type.in("$pos", "$add", "$mul", "$and", "$or", "$xor", "$sub")) { - bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + bool is_signed = cell->getParam("\\A_SIGNED").as_bool() || cell->type == "$sub"; int a_size = 0, b_size = 0; if (cell->hasPort("\\A")) a_size = GetSize(cell->getPort("\\A")); @@ -352,7 +352,7 @@ struct WreduceWorker int max_y_size = max(a_size, b_size); - if (cell->type == "$add") + if (cell->type.in("$add", "$sub")) max_y_size++; if (cell->type == "$mul") From 31b0002e8c0e1b7a8ad054e02b1200c03461b581 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 13:20:45 -0700 Subject: [PATCH 08/19] Remove "top" from message --- passes/opt/wreduce.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index dff1c5370..23e14f7f5 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -395,7 +395,7 @@ struct WreduceWorker } if (bits_removed) { - log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", + log("Removed %d bits (of %d) from port Y of cell %s.%s (%s).\n", bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); cell->setPort("\\Y", sig); did_something = true; From 3a87dc35242598b6951fb70d4302ede60c2a96b2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 13:23:07 -0700 Subject: [PATCH 09/19] Wrap A and B in sigmap --- passes/opt/wreduce.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 23e14f7f5..294f0d57e 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -366,8 +366,8 @@ struct WreduceWorker } if (cell->type.in("$add", "$sub")) { - SigSpec A = cell->getPort("\\A"); - SigSpec B = cell->getPort("\\B"); + SigSpec A = mi.sigmap(cell->getPort("\\A")); + SigSpec B = mi.sigmap(cell->getPort("\\B")); bool sub = cell->type == "$sub"; int i; From 54708dfbd786032e841f48f15af4875c1eabbbfe Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 13:54:57 -0700 Subject: [PATCH 10/19] Add an SigSpec::at(offset, defval) convenience method --- kernel/rtlil.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 82cbfaf28..f9412e776 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -818,6 +818,7 @@ public: operator std::vector() const { return chunks(); } operator std::vector() const { return bits(); } + RTLIL::SigBit at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; } unsigned int hash() const { if (!hash_) updhash(); return hash_; }; From cb0fd0521531a69632102f5fad8cdc9996ed4dee Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 13:58:50 -0700 Subject: [PATCH 11/19] Do not access beyond bounds --- passes/opt/wreduce.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 294f0d57e..908a85d5b 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -372,7 +372,7 @@ struct WreduceWorker int i; for (i = 0; i < GetSize(sig); i++) { - if (B[i] != S0 && (sub || A[i] != S0)) + if (B.at(i, Sx) != S0 && (sub || A.at(i, Sx) != S0)) break; if (B[i] == S0) module->connect(sig[i], A[i]); From c926eeb43a9c42a0ecc34871f383f4181b7a45f9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 19 Jul 2019 14:02:46 -0700 Subject: [PATCH 12/19] Add another test --- tests/various/wreduce.ys | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/various/wreduce.ys b/tests/various/wreduce.ys index 8030c005e..deb99304d 100644 --- a/tests/various/wreduce.ys +++ b/tests/various/wreduce.ys @@ -83,7 +83,6 @@ design -save gold prep # calls wreduce -dump select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i design -stash gate @@ -93,3 +92,27 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + +########## + +read_verilog < Date: Fri, 19 Jul 2019 14:40:57 -0700 Subject: [PATCH 13/19] Try and fix again --- passes/opt/wreduce.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 908a85d5b..22af0bd8b 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -372,13 +372,12 @@ struct WreduceWorker int i; for (i = 0; i < GetSize(sig); i++) { - if (B.at(i, Sx) != S0 && (sub || A.at(i, Sx) != S0)) - break; - if (B[i] == S0) + if (B.at(i, Sx) == S0 && A.at(i, Sx) != Sx) module->connect(sig[i], A[i]); - else if (A[i] == S0) + else if (!sub && A.at(i, Sx) == S0 && B.at(i, Sx) != Sx) module->connect(sig[i], B[i]); - else log_abort(); + else + break; } if (i > 0) { cell->setPort("\\A", A.extract(i, -1)); From 51b39219cda35e782fe4372409edf5432f86741f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 6 Aug 2019 15:24:49 -0700 Subject: [PATCH 14/19] Move LSB tests from wreduce to opt_expr --- tests/various/opt_expr.ys | 98 ++++++++++++++++++++++++++++++++++++ tests/various/wreduce.ys | 102 ++------------------------------------ 2 files changed, 101 insertions(+), 99 deletions(-) create mode 100644 tests/various/opt_expr.ys diff --git a/tests/various/opt_expr.ys b/tests/various/opt_expr.ys new file mode 100644 index 000000000..2165802d6 --- /dev/null +++ b/tests/various/opt_expr.ys @@ -0,0 +1,98 @@ + +read_verilog <> 4) - i; endmodule EOT @@ -81,7 +8,8 @@ hierarchy -auto-top proc design -save gold -prep # calls wreduce +opt_expr +wreduce select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i @@ -92,27 +20,3 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter - -########## - -read_verilog < Date: Tue, 6 Aug 2019 15:24:55 -0700 Subject: [PATCH 15/19] Restore original SigSpec::extract() --- kernel/rtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f2c81db72..ba8472ec1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3355,7 +3355,7 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const { unpack(); cover("kernel.rtlil.sigspec.extract_pos"); - return std::vector(bits_.begin() + offset, length >= 0 ? bits_.begin() + offset + length : bits_.end() + length + 1); + return std::vector(bits_.begin() + offset, bits_.begin() + offset + length); } void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) From 84f52aee0d01378796792c9a2f068a22d955f586 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 6 Aug 2019 15:25:11 -0700 Subject: [PATCH 16/19] Add SigSpec::extract_end() convenience function --- kernel/rtlil.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 633cb51d6..c07d39c65 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -788,6 +788,7 @@ public: RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(const pool &pattern, const RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(int offset, int length = 1) const; + RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); } void append(const RTLIL::SigSpec &signal); void append_bit(const RTLIL::SigBit &bit); From bfc7164af7bf64cb2fe5d00e87bbfead841a4dc2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 6 Aug 2019 15:25:50 -0700 Subject: [PATCH 17/19] Move LSB-trimming functionality from wreduce to opt_expr --- passes/opt/opt_expr.cc | 25 +++++++++++++++++++++++++ passes/opt/wreduce.cc | 24 +----------------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 512ef0cbf..acdc39937 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -641,6 +641,31 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons did_something = true; } } + + if (cell->type.in("$add", "$sub")) { + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + bool sub = cell->type == "$sub"; + + int i; + for (i = 0; i < GetSize(sig_y); i++) { + if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) + module->connect(sig_y[i], sig_a[i]); + else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) + module->connect(sig_y[i], sig_b[i]); + else + break; + } + if (i > 0) { + cover_list("opt.opt_expr.fine", "$add", "$sub", cell->type.str()); + cell->setPort("\\A", sig_a.extract_end(i)); + cell->setPort("\\B", sig_b.extract_end(i)); + cell->setPort("\\Y", sig_y.extract_end(i)); + cell->fixup_parameters(); + did_something = true; + } + } } if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$shift" || cell->type == "$shiftx" || diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 22af0bd8b..1eeca2748 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -365,28 +365,6 @@ struct WreduceWorker } } - if (cell->type.in("$add", "$sub")) { - SigSpec A = mi.sigmap(cell->getPort("\\A")); - SigSpec B = mi.sigmap(cell->getPort("\\B")); - bool sub = cell->type == "$sub"; - - int i; - for (i = 0; i < GetSize(sig); i++) { - if (B.at(i, Sx) == S0 && A.at(i, Sx) != Sx) - module->connect(sig[i], A[i]); - else if (!sub && A.at(i, Sx) == S0 && B.at(i, Sx) != Sx) - module->connect(sig[i], B[i]); - else - break; - } - if (i > 0) { - cell->setPort("\\A", A.extract(i, -1)); - cell->setPort("\\B", B.extract(i, -1)); - sig.remove(0, i); - bits_removed += i; - } - } - if (GetSize(sig) == 0) { log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); module->remove(cell); @@ -394,7 +372,7 @@ struct WreduceWorker } if (bits_removed) { - log("Removed %d bits (of %d) from port Y of cell %s.%s (%s).\n", + log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); cell->setPort("\\Y", sig); did_something = true; From 769c750c226cfde5efcd1f75940b25f51330d67b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 6 Aug 2019 15:38:43 -0700 Subject: [PATCH 18/19] Add signed test --- tests/various/wreduce.ys | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/various/wreduce.ys b/tests/various/wreduce.ys index 7e4f1765a..4257292f5 100644 --- a/tests/various/wreduce.ys +++ b/tests/various/wreduce.ys @@ -20,3 +20,29 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + +########## + +read_verilog <>> 4) - i; +endmodule +EOT + +hierarchy -auto-top +proc +design -save gold + +opt_expr +wreduce + +dump +select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i + +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 From 2d1b517b01b6cd1ec35018d4c63aaa091fcc1917 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 6 Aug 2019 15:40:30 -0700 Subject: [PATCH 19/19] Add signed opt_expr tests --- tests/various/opt_expr.ys | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/various/opt_expr.ys b/tests/various/opt_expr.ys index 2165802d6..0c61ac881 100644 --- a/tests/various/opt_expr.ys +++ b/tests/various/opt_expr.ys @@ -24,6 +24,31 @@ sat -verify -prove-asserts -show-ports miter ########## +read_verilog <