From 3aa4484a3cd9a2e82fddd499cde575eaf8c565cc Mon Sep 17 00:00:00 2001 From: Henner Zeller Date: Fri, 20 Jul 2018 23:41:18 -0700 Subject: Consistent use of 'override' for virtual methods in derived classes. o Not all derived methods were marked 'override', but it is a great feature of C++11 that we should make use of. o While at it: touched header files got a -*- c++ -*- for emacs to provide support for that language. o use YS_OVERRIDE for all override keywords (though we should probably use the plain keyword going forward now that C++11 is established) --- passes/memory/memory_bram.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'passes/memory/memory_bram.cc') diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index a7f9cf382..e8552bbcf 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -1120,7 +1120,7 @@ void handle_cell(Cell *cell, const rules_t &rules) struct MemoryBramPass : public Pass { MemoryBramPass() : Pass("memory_bram", "map memories to block rams") { } - virtual void help() + void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -1210,7 +1210,7 @@ struct MemoryBramPass : public Pass { log("the data bits to accommodate the enable pattern of port A.\n"); log("\n"); } - virtual void execute(vector args, Design *design) + void execute(vector args, Design *design) YS_OVERRIDE { rules_t rules; -- cgit v1.2.3 From 3420ae5ca5a6148c54310d065e7dcbd5a0ea1c8f Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 19 Oct 2018 14:45:45 +0100 Subject: memory_bram: Reset make_outreg when growing read ports Signed-off-by: David Shah --- passes/memory/memory_bram.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'passes/memory/memory_bram.cc') diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index e8552bbcf..8740042c4 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -623,6 +623,7 @@ grow_read_ports:; pi.sig_addr = SigSpec(); pi.sig_data = SigSpec(); pi.sig_en = SigSpec(); + pi.make_outreg = false; } new_portinfos.push_back(pi); if (pi.dupidx == dup_count-1) { -- cgit v1.2.3 From 4fef9689abb81286af4d9c6bc420b78f61d89550 Mon Sep 17 00:00:00 2001 From: Graham Edgecombe Date: Sat, 8 Dec 2018 09:59:56 +0000 Subject: memory_bram: Fix initdata bit order after shuffling In some cases the memory_bram pass shuffles the order of the bits in a memory's RD_DATA port. Although the order of the bits in the WR_DATA and WR_EN ports is changed to match the RD_DATA port, the order of the bits in the initialization data is not. This causes reads of initialized memories to return invalid data (until the initialization data is overwritten). This commit fixes the bug by shuffling the initdata bits in exactly the same order as the RD_DATA/WR_DATA/WR_EN bits. --- passes/memory/memory_bram.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'passes/memory/memory_bram.cc') diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 8740042c4..cf4095d06 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -472,8 +472,12 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, std::vector new_wr_en(GetSize(old_wr_en)); std::vector new_wr_data(GetSize(old_wr_data)); std::vector new_rd_data(GetSize(old_rd_data)); + std::vector> new_initdata; std::vector shuffle_map; + if (cell_init) + new_initdata.resize(mem_size); + for (auto &it : en_order) { auto &bits = bits_wr_en.at(it); @@ -489,6 +493,10 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, } for (int j = 0; j < rd_ports; j++) new_rd_data[j].append(old_rd_data[j][bits[i]]); + if (cell_init) { + for (int j = 0; j < mem_size; j++) + new_initdata[j].push_back(initdata[j][bits[i]]); + } shuffle_map.push_back(bits[i]); } @@ -499,6 +507,10 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, } for (int j = 0; j < rd_ports; j++) new_rd_data[j].append(State::Sx); + if (cell_init) { + for (int j = 0; j < mem_size; j++) + new_initdata[j].push_back(State::Sx); + } shuffle_map.push_back(-1); } } @@ -522,6 +534,11 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, for (int i = 0; i < rd_ports; i++) rd_data.replace(i*mem_width, new_rd_data[i]); + + if (cell_init) { + for (int i = 0; i < mem_size; i++) + initdata[i] = Const(new_initdata[i]); + } } // assign write ports -- cgit v1.2.3 From ac6cc88db352938d8dd9f2f9c6d404663674538e Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 24 Mar 2019 16:21:36 +0000 Subject: memory_bram: Fix multiclock make_transp Signed-off-by: David Shah --- passes/memory/memory_bram.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'passes/memory/memory_bram.cc') 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), -- cgit v1.2.3 From 60594ad40cb51f6cf8a5e6ce61377b3405b873a8 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 27 Mar 2019 17:19:14 +0000 Subject: memory_bram: Reset make_transp when growing read ports Signed-off-by: David Shah --- passes/memory/memory_bram.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'passes/memory/memory_bram.cc') diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index c38eabaee..85ed1c053 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -641,6 +641,7 @@ grow_read_ports:; pi.sig_data = SigSpec(); pi.sig_en = SigSpec(); pi.make_outreg = false; + pi.make_transp = false; } new_portinfos.push_back(pi); if (pi.dupidx == dup_count-1) { -- cgit v1.2.3 From 6acbc016f43b1464e6322b895f16d01ed51eea18 Mon Sep 17 00:00:00 2001 From: David Shah Date: Tue, 2 Apr 2019 19:47:50 +0100 Subject: memory_bram: Consider read enable for address expansion register Signed-off-by: David Shah --- passes/memory/memory_bram.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'passes/memory/memory_bram.cc') diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 85ed1c053..804aa21f9 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -957,6 +957,8 @@ grow_read_ports:; SigSpec addr_ok_q = addr_ok; if ((pi.clocks || pi.make_outreg) && !addr_ok.empty()) { addr_ok_q = module->addWire(NEW_ID); + if (!pi.sig_en.empty()) + addr_ok = module->Mux(NEW_ID, addr_ok_q, addr_ok, pi.sig_en); module->addDff(NEW_ID, pi.sig_clock, addr_ok, addr_ok_q, pi.effective_clkpol); } -- cgit v1.2.3 From 2bf3ca64435b11726d87cc0d34e887a79351ec45 Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 7 Apr 2019 16:56:31 +0100 Subject: memory_bram: Fix multiport make_transp Signed-off-by: David Shah --- passes/memory/memory_bram.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'passes/memory/memory_bram.cc') diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 804aa21f9..ddc56d9b5 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -744,7 +744,8 @@ grow_read_ports:; if (clken) { clock_domains[pi.clocks] = clkdom; clock_polarities[pi.clkpol] = clkdom.second; - read_transp[pi.transp] = transp; + if (!pi.make_transp) + read_transp[pi.transp] = transp; pi.sig_clock = clkdom.first; pi.sig_en = rd_en[cell_port_i]; pi.effective_clkpol = clkdom.second; -- cgit v1.2.3 From ab3917d0791874bab845ca74203c5aaa2ec842d2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 13 Jul 2019 03:39:23 -0700 Subject: Error out if enable > dbits --- passes/memory/memory_bram.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'passes/memory/memory_bram.cc') diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index ddc56d9b5..aa8f94149 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -68,6 +68,10 @@ struct rules_t if (groups != GetSize(transp)) log_error("Bram %s variant %d has %d groups but only %d entries in 'transp'.\n", log_id(name), variant, groups, GetSize(transp)); if (groups != GetSize(clocks)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clocks'.\n", log_id(name), variant, groups, GetSize(clocks)); if (groups != GetSize(clkpol)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clkpol'.\n", log_id(name), variant, groups, GetSize(clkpol)); + + int group = 0; + for (auto e : enable) + if (e > dbits) log_error("Bram %s variant %d group %d has %d enable bits but only %d dbits.\n", log_id(name), variant, group, e, dbits); } vector make_portinfos() const -- cgit v1.2.3