From d3a212ff91de5e4f082f2c133becd4338661ac16 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 21 Aug 2019 19:18:05 -0700
Subject: opt_expr to trim A port of $shiftx if Y_WIDTH == 1

---
 passes/opt/opt_expr.cc | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

(limited to 'passes')

diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 858b3560c..b56ce252f 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -745,6 +745,23 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 			}
 		}
 
+		if (cell->type == ID($shiftx) && cell->getPort(ID::Y).size() == 1) {
+			SigSpec sig_a = assign_map(cell->getPort(ID::A));
+			int width;
+			for (width = GetSize(sig_a); width > 1; width--) {
+				if (sig_a[width-1] != State::Sx)
+					break;
+			}
+
+			if (width < GetSize(sig_a)) {
+				sig_a.remove(width, GetSize(sig_a)-width);
+				cell->setPort(ID::A, sig_a);
+				cell->setParam(ID(A_WIDTH), width);
+				did_something = true;
+				goto next_cell;
+			}
+		}
+
 		if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 &&
 				invert_map.count(assign_map(cell->getPort(ID::A))) != 0) {
 			cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str());
-- 
cgit v1.2.3


From d0ffe7544cd3c808857f3a99bbf330de61c618f2 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Thu, 22 Aug 2019 08:05:01 -0700
Subject: Canonical form

---
 passes/opt/opt_expr.cc | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'passes')

diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index b56ce252f..7fdfa82bd 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -369,7 +369,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 	for (auto cell : module->cells())
 		if (design->selected(module, cell) && cell->type[0] == '$') {
 			if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) &&
-					cell->getPort(ID::A).size() == 1 && cell->getPort(ID::Y).size() == 1)
+					GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1)
 				invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A));
 			if (cell->type.in(ID($mux), ID($_MUX_)) &&
 					cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0))
@@ -740,12 +740,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 				if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt)))
 					replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx);
 				else
-					replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID::Y).size()));
+					replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, GetSize(cell->getPort(ID::Y))));
 				goto next_cell;
 			}
 		}
 
-		if (cell->type == ID($shiftx) && cell->getPort(ID::Y).size() == 1) {
+		if (cell->type == ID($shiftx) && GetSize(cell->getPort(ID::Y)) == 1) {
 			SigSpec sig_a = assign_map(cell->getPort(ID::A));
 			int width;
 			for (width = GetSize(sig_a); width > 1; width--) {
@@ -762,7 +762,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 			}
 		}
 
-		if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 &&
+		if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && GetSize(cell->getPort(ID::Y)) == 1 &&
 				invert_map.count(assign_map(cell->getPort(ID::A))) != 0) {
 			cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str());
 			replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A))));
@@ -1159,7 +1159,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 
 		if (mux_undef && cell->type.in(ID($mux), ID($pmux))) {
 			RTLIL::SigSpec new_a, new_b, new_s;
-			int width = cell->getPort(ID::A).size();
+			int width = GetSize(cell->getPort(ID::A));
 			if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) ||
 					cell->getPort(ID(S)).is_fully_undef()) {
 				cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str());
-- 
cgit v1.2.3


From 9e31f01b343a9b246430419e81da647e75bd1626 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Thu, 22 Aug 2019 08:06:24 -0700
Subject: Add cover()

---
 passes/opt/opt_expr.cc | 1 +
 1 file changed, 1 insertion(+)

(limited to 'passes')

diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 7fdfa82bd..aca15e5f2 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -754,6 +754,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 			}
 
 			if (width < GetSize(sig_a)) {
+				cover("opt.opt_expr.trim_shiftx");
 				sig_a.remove(width, GetSize(sig_a)-width);
 				cell->setPort(ID::A, sig_a);
 				cell->setParam(ID(A_WIDTH), width);
-- 
cgit v1.2.3


From 379f33af5489850ef8e2e58ef12ff5b22da87711 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Thu, 22 Aug 2019 08:22:23 -0700
Subject: Handle $shift and Y_WIDTH > 1 as per @cliffordwolf

---
 passes/opt/opt_expr.cc | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

(limited to 'passes')

diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index aca15e5f2..c4da613ab 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -745,16 +745,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 			}
 		}
 
-		if (cell->type == ID($shiftx) && GetSize(cell->getPort(ID::Y)) == 1) {
+		if (cell->type.in(ID($shiftx), ID($shift))) {
 			SigSpec sig_a = assign_map(cell->getPort(ID::A));
 			int width;
+			bool trim_x = true;
+			bool trim_0 = cell->type == ID($shift);
 			for (width = GetSize(sig_a); width > 1; width--) {
-				if (sig_a[width-1] != State::Sx)
-					break;
+				if ((trim_x && sig_a[width-1] == State::Sx) ||
+					(trim_0 && sig_a[width-1] == State::S0))
+					continue;
+				break;
 			}
 
 			if (width < GetSize(sig_a)) {
-				cover("opt.opt_expr.trim_shiftx");
+				cover_list("opt.opt_expr.xbit", "$shiftx", "$shift", cell->type.str());
 				sig_a.remove(width, GetSize(sig_a)-width);
 				cell->setPort(ID::A, sig_a);
 				cell->setParam(ID(A_WIDTH), width);
-- 
cgit v1.2.3


From 6f971470f83b8e4ed29232be4b6cb5da89d50dc0 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Thu, 22 Aug 2019 08:37:27 -0700
Subject: Respect opt_expr -keepdc as per @cliffordwolf

---
 passes/opt/opt_expr.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'passes')

diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index c4da613ab..73f48317a 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -748,7 +748,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 		if (cell->type.in(ID($shiftx), ID($shift))) {
 			SigSpec sig_a = assign_map(cell->getPort(ID::A));
 			int width;
-			bool trim_x = true;
+			bool trim_x = cell->type == ID($shiftx) || !keepdc;
 			bool trim_0 = cell->type == ID($shift);
 			for (width = GetSize(sig_a); width > 1; width--) {
 				if ((trim_x && sig_a[width-1] == State::Sx) ||
-- 
cgit v1.2.3


From 9245f0d3f564644290b6650b3f8f642789062e9e Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Thu, 22 Aug 2019 08:43:44 -0700
Subject: Copy-paste typo

---
 passes/opt/opt_expr.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'passes')

diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 73f48317a..00d7d6063 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -758,7 +758,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 			}
 
 			if (width < GetSize(sig_a)) {
-				cover_list("opt.opt_expr.xbit", "$shiftx", "$shift", cell->type.str());
+				cover_list("opt.opt_expr.trim", "$shiftx", "$shift", cell->type.str());
 				sig_a.remove(width, GetSize(sig_a)-width);
 				cell->setPort(ID::A, sig_a);
 				cell->setParam(ID(A_WIDTH), width);
-- 
cgit v1.2.3