From: Marcelina Koƛcielnicka Date: Fri, 17 Jun 2022 12:11:04 +0000 (+0200) Subject: memory_map: Use const drivers instead of FFs for ROMs. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=01daa077a2837830914f3d99f351918d690b9093;p=yosys.git memory_map: Use const drivers instead of FFs for ROMs. --- diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index ca1ca483d..21c7a761e 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -191,6 +191,10 @@ struct MemoryMapWorker data_reg_out[idx] = static_cells_map[addr]; count_static++; } + else if (mem.wr_ports.empty()) + { + data_reg_out[idx] = init_data.extract(i*mem.width, mem.width); + } else { RTLIL::Cell *c = module->addCell(genid(mem.memid, "", addr), ID($dff)); @@ -266,69 +270,72 @@ struct MemoryMapWorker log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); - for (int i = 0; i < mem.size; i++) + if (!mem.wr_ports.empty()) { - int addr = i + mem.start_offset; - int idx = addr & ((1 << abits) - 1); - if (static_cells_map.count(addr) > 0) - continue; - - RTLIL::SigSpec sig = data_reg_out[idx]; - - for (int j = 0; j < GetSize(mem.wr_ports); j++) + for (int i = 0; i < mem.size; i++) { - auto &port = mem.wr_ports[j]; - RTLIL::SigSpec wr_addr = port.addr.extract_end(port.wide_log2); - RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(addr >> port.wide_log2, GetSize(wr_addr))); + int addr = i + mem.start_offset; + int idx = addr & ((1 << abits) - 1); + if (static_cells_map.count(addr) > 0) + continue; - int sub = addr & ((1 << port.wide_log2) - 1); + RTLIL::SigSpec sig = data_reg_out[idx]; - int wr_offset = 0; - while (wr_offset < mem.width) + for (int j = 0; j < GetSize(mem.wr_ports); j++) { - int wr_width = 1; - RTLIL::SigSpec wr_bit = port.en.extract(wr_offset + sub * mem.width, 1); - - while (wr_offset + wr_width < mem.width) { - RTLIL::SigSpec next_wr_bit = port.en.extract(wr_offset + wr_width + sub * mem.width, 1); - if (next_wr_bit != wr_bit) - break; - wr_width++; - } + auto &port = mem.wr_ports[j]; + RTLIL::SigSpec wr_addr = port.addr.extract_end(port.wide_log2); + RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(addr >> port.wide_log2, GetSize(wr_addr))); - RTLIL::Wire *w = w_seladdr; + int sub = addr & ((1 << port.wide_log2) - 1); - if (wr_bit != State::S1) + int wr_offset = 0; + while (wr_offset < mem.width) { - RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wren", addr, "", j, "", wr_offset), ID($and)); - c->parameters[ID::A_SIGNED] = RTLIL::Const(0); - c->parameters[ID::B_SIGNED] = RTLIL::Const(0); - c->parameters[ID::A_WIDTH] = RTLIL::Const(1); - c->parameters[ID::B_WIDTH] = RTLIL::Const(1); - c->parameters[ID::Y_WIDTH] = RTLIL::Const(1); - c->setPort(ID::A, w); - c->setPort(ID::B, wr_bit); - - w = module->addWire(genid(mem.memid, "$wren", addr, "", j, "", wr_offset, "$y")); - c->setPort(ID::Y, RTLIL::SigSpec(w)); + int wr_width = 1; + RTLIL::SigSpec wr_bit = port.en.extract(wr_offset + sub * mem.width, 1); + + while (wr_offset + wr_width < mem.width) { + RTLIL::SigSpec next_wr_bit = port.en.extract(wr_offset + wr_width + sub * mem.width, 1); + if (next_wr_bit != wr_bit) + break; + wr_width++; + } + + RTLIL::Wire *w = w_seladdr; + + if (wr_bit != State::S1) + { + RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wren", addr, "", j, "", wr_offset), ID($and)); + c->parameters[ID::A_SIGNED] = RTLIL::Const(0); + c->parameters[ID::B_SIGNED] = RTLIL::Const(0); + c->parameters[ID::A_WIDTH] = RTLIL::Const(1); + c->parameters[ID::B_WIDTH] = RTLIL::Const(1); + c->parameters[ID::Y_WIDTH] = RTLIL::Const(1); + c->setPort(ID::A, w); + c->setPort(ID::B, wr_bit); + + w = module->addWire(genid(mem.memid, "$wren", addr, "", j, "", wr_offset, "$y")); + c->setPort(ID::Y, RTLIL::SigSpec(w)); + } + + RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset), ID($mux)); + c->parameters[ID::WIDTH] = wr_width; + c->setPort(ID::A, sig.extract(wr_offset, wr_width)); + c->setPort(ID::B, port.data.extract(wr_offset + sub * mem.width, wr_width)); + c->setPort(ID::S, RTLIL::SigSpec(w)); + + w = module->addWire(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset, "$y"), wr_width); + c->setPort(ID::Y, w); + + sig.replace(wr_offset, w); + wr_offset += wr_width; + count_wrmux++; } - - RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset), ID($mux)); - c->parameters[ID::WIDTH] = wr_width; - c->setPort(ID::A, sig.extract(wr_offset, wr_width)); - c->setPort(ID::B, port.data.extract(wr_offset + sub * mem.width, wr_width)); - c->setPort(ID::S, RTLIL::SigSpec(w)); - - w = module->addWire(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset, "$y"), wr_width); - c->setPort(ID::Y, w); - - sig.replace(wr_offset, w); - wr_offset += wr_width; - count_wrmux++; } - } - module->connect(RTLIL::SigSig(data_reg_in[idx], sig)); + module->connect(RTLIL::SigSig(data_reg_in[idx], sig)); + } } log(" write interface: %d write mux blocks.\n", count_wrmux);