aboutsummaryrefslogtreecommitdiffstats
path: root/passes/proc
diff options
context:
space:
mode:
authorEddie Hung <eddieh@ece.ubc.ca>2019-03-25 11:16:56 -0700
committerEddie Hung <eddieh@ece.ubc.ca>2019-03-25 11:16:56 -0700
commitb7a3d35c6b02f44dcad4052e2efe05c32fdada6b (patch)
tree20e284ddc0b8ce89fac83747b40b1cec2232dbf2 /passes/proc
parent2507d01b03cb4ec0a1345532d22688dd9a623948 (diff)
downloadyosys-b7a3d35c6b02f44dcad4052e2efe05c32fdada6b.tar.gz
yosys-b7a3d35c6b02f44dcad4052e2efe05c32fdada6b.tar.bz2
yosys-b7a3d35c6b02f44dcad4052e2efe05c32fdada6b.zip
Create one $shiftx per bit in width
Diffstat (limited to 'passes/proc')
-rw-r--r--passes/proc/proc_mux.cc27
1 files changed, 17 insertions, 10 deletions
diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc
index 7cac0327b..7d3d23408 100644
--- a/passes/proc/proc_mux.cc
+++ b/passes/proc/proc_mux.cc
@@ -340,7 +340,7 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d
// evaluate in reverse order to give the first entry the top priority
RTLIL::SigSpec initial_val = result;
RTLIL::Cell *last_mux_cell = NULL;
- bool shiftx = true;
+ bool shiftx = initial_val.is_fully_undef();
for (size_t i = 0; i < sw->cases.size(); i++) {
int case_idx = sw->cases.size() - i - 1;
RTLIL::CaseRule *cs2 = sw->cases[case_idx];
@@ -355,20 +355,27 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d
// Keep checking if case condition is the same as the current case index
if (cs2->compare.size() == 1 && cs2->compare.front().is_fully_const())
shiftx = (cs2->compare.front().as_int() == case_idx);
+ else
+ shiftx = false;
}
}
- // Transform into a $shiftx if possible
+ // Transform into a $shiftx where possible
if (shiftx && last_mux_cell->type == "$pmux") {
- // Sanity check that A port of $pmux should be 'bx
- log_assert(last_mux_cell->getPort("\\A").is_fully_undef());
- // Because we went in reverse order above, un-reverse its B port here
- auto b_port = last_mux_cell->getPort("\\B").chunks();
- std::reverse(b_port.begin(), b_port.end());
- // Create a $shiftx that shifts by the address line used in the case statement
- mod->addShiftx(NEW_ID, b_port, sw->signal, last_mux_cell->getPort("\\Y"));
+ // Create bit-blasted $shiftx-es that shifts by the address line used in the case statement
+ auto pmux_b_port = last_mux_cell->getPort("\\B");
+ auto pmux_y_port = last_mux_cell->getPort("\\Y");
+ int width = last_mux_cell->getParam("\\WIDTH").as_int();
+ for (int i = 0; i < width; ++i) {
+ RTLIL::SigSpec a_port;
+ // Because we went in reverse order above, un-reverse $pmux's B port here
+ for (int j = pmux_b_port.size()/width-1; j >= 0; --j)
+ a_port.append(pmux_b_port.extract(j*width+i, 1));
+ // Create a $shiftx that shifts by the address line used in the case statement
+ mod->addShiftx(NEW_ID, a_port, sw->signal, pmux_y_port.extract(i, 1));
+ }
// Disconnect $pmux by replacing its output port with a floating wire
- last_mux_cell->setPort("\\Y", mod->addWire(NEW_ID, last_mux_cell->getParam("\\WIDTH").as_int()));
+ last_mux_cell->setPort("\\Y", mod->addWire(NEW_ID, width));
}
}