aboutsummaryrefslogtreecommitdiffstats
path: root/passes/memory
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2022-06-17 14:11:04 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2022-06-17 15:17:14 +0200
commit01daa077a2837830914f3d99f351918d690b9093 (patch)
tree6a8d6b74eace680c65a73f14afb4b80866cba796 /passes/memory
parentbb634d39ef6c2b915a7b7526029197ecf948e183 (diff)
downloadyosys-01daa077a2837830914f3d99f351918d690b9093.tar.gz
yosys-01daa077a2837830914f3d99f351918d690b9093.tar.bz2
yosys-01daa077a2837830914f3d99f351918d690b9093.zip
memory_map: Use const drivers instead of FFs for ROMs.
Diffstat (limited to 'passes/memory')
-rw-r--r--passes/memory/memory_map.cc111
1 files changed, 59 insertions, 52 deletions
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);