Walk through as many muxes as exist for rd_en
authorEddie Hung <eddie@fpgeh.com>
Tue, 25 Jun 2019 01:33:06 +0000 (18:33 -0700)
committerEddie Hung <eddie@fpgeh.com>
Tue, 25 Jun 2019 01:33:06 +0000 (18:33 -0700)
passes/memory/memory_dff.cc

index 220d29295467a0c3fa32a4bed836a89d8a321afb..d37cac28e61fb47d85271efeab210535c4048282 100644 (file)
@@ -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);