From ac6cc88db352938d8dd9f2f9c6d404663674538e Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 24 Mar 2019 16:21:36 +0000 Subject: [PATCH] memory_bram: Fix multiclock make_transp Signed-off-by: David Shah --- passes/memory/memory_bram.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index cf4095d06..c38eabaee 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -542,7 +542,7 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, } // assign write ports - + pair wr_clkdom; for (int cell_port_i = 0, bram_port_i = 0; cell_port_i < wr_ports; cell_port_i++) { bool clken = wr_clken[cell_port_i] == State::S1; @@ -552,7 +552,7 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, pair clkdom(clksig, clkpol); if (!clken) clkdom = pair(State::S1, false); - + wr_clkdom = clkdom; log(" Write port #%d is in clock domain %s%s.\n", cell_port_i, clkdom.second ? "" : "!", clken ? log_signal(clkdom.first) : "~async~"); @@ -718,7 +718,13 @@ grow_read_ports:; if (read_transp.count(pi.transp) && read_transp.at(pi.transp) != transp) { if (match.make_transp && wr_ports <= 1) { pi.make_transp = true; - enable_make_transp = true; + if (pi.clocks != 0) { + if (wr_ports == 1 && wr_clkdom != clkdom) { + log(" Bram port %c%d.%d cannot have soft transparency logic added as read and write clock domains differ.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); + goto skip_bram_rport; + } + enable_make_transp = true; + } } else { log(" Bram port %c%d.%d has incompatible read transparency.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); goto skip_bram_rport; @@ -913,17 +919,18 @@ grow_read_ports:; } else { SigSpec bram_dout = module->addWire(NEW_ID, bram.dbits); c->setPort(stringf("\\%sDATA", pf), bram_dout); - - if (pi.make_outreg) { + if (pi.make_outreg && pi.make_transp) { + log(" Moving output register to address for transparent port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); + SigSpec sig_addr_q = module->addWire(NEW_ID, bram.abits); + module->addDff(NEW_ID, pi.sig_clock, sig_addr, sig_addr_q, pi.effective_clkpol); + c->setPort(stringf("\\%sADDR", pf), sig_addr_q); + } else if (pi.make_outreg) { SigSpec bram_dout_q = module->addWire(NEW_ID, bram.dbits); if (!pi.sig_en.empty()) bram_dout = module->Mux(NEW_ID, bram_dout_q, bram_dout, pi.sig_en); module->addDff(NEW_ID, pi.sig_clock, bram_dout, bram_dout_q, pi.effective_clkpol); bram_dout = bram_dout_q; - } - - if (pi.make_transp) - { + } else if (pi.make_transp) { log(" Adding extra logic for transparent port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1); SigSpec transp_en_d = module->Mux(NEW_ID, SigSpec(0, make_transp_enbits),