diff options
Diffstat (limited to 'passes/proc')
| -rw-r--r-- | passes/proc/proc_mux.cc | 27 | 
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));  		}  	} | 
