memory_map: Use const drivers instead of FFs for ROMs.
authorMarcelina Kościelnicka <mwk@0x04.net>
Fri, 17 Jun 2022 12:11:04 +0000 (14:11 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Fri, 17 Jun 2022 13:17:14 +0000 (15:17 +0200)
passes/memory/memory_map.cc

index ca1ca483d0e45f468ed32a08aa63b3e3acaa2e80..21c7a761e3d03ed8da9ef53e26a33be34afa3bfe 100644 (file)
@@ -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);