diff options
Diffstat (limited to 'passes/memory')
| -rw-r--r-- | passes/memory/memory_dff.cc | 24 | 
1 files changed, 16 insertions, 8 deletions
diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 220d29295..d37cac28e 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -182,20 +182,28 @@ struct MemoryDffWorker  		if (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data))  		{ -			bool enable_invert = mux_cells_a.count(sig_data) != 0; -			Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data); -			SigSpec check_q = sigmap(mux->getPort(enable_invert ? "\\B" : "\\A")); +			RTLIL::SigSpec en; +			RTLIL::SigSpec check_q; -			sig_data = sigmap(mux->getPort("\\Y")); -			for (auto bit : sig_data) -				if (sigbit_users_count[bit] > 1) -					goto skip_ff_after_read_merging; +			do { +				bool enable_invert = mux_cells_a.count(sig_data) != 0; +				Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data); +				check_q = sigmap(mux->getPort(enable_invert ? "\\B" : "\\A")); + +				sig_data = sigmap(mux->getPort("\\Y")); +				for (auto bit : sig_data) +					if (sigbit_users_count[bit] > 1) { +						goto skip_ff_after_read_merging; +					} + +				en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort("\\S")) : mux->getPort("\\S")); +			} while (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data));  			if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx) && sig_data == check_q)  			{  				disconnect_dff(sig_data);  				cell->setPort("\\CLK", clk_data); -				cell->setPort("\\EN", enable_invert ? module->LogicNot(NEW_ID, mux->getPort("\\S")) : mux->getPort("\\S")); +				cell->setPort("\\EN", en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en);  				cell->setPort("\\DATA", sig_data);  				cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);  				cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);  | 
