Changes to "memory" pass for new $memwr/$mem WR_EN interface
authorClifford Wolf <clifford@clifford.at>
Wed, 16 Jul 2014 10:13:13 +0000 (12:13 +0200)
committerClifford Wolf <clifford@clifford.at>
Wed, 16 Jul 2014 10:49:50 +0000 (12:49 +0200)
passes/memory/memory_collect.cc
passes/memory/memory_map.cc
passes/memory/memory_unpack.cc

index 6fe5e162c3e8b3d00a9cb697678b6a1fef5ef81c..028841f60e4eb4453c0a76e2059faf02bc41bc04 100644 (file)
@@ -88,7 +88,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory)
                        clk_polarity.extend(1, false);
                        addr.extend(addr_bits, false);
                        data.extend(memory->width, false);
-                       en.extend(1, false);
+                       en.extend(memory->width, false);
 
                        sig_wr_clk.append(clk);
                        sig_wr_clk_enable.append(clk_enable);
@@ -147,7 +147,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory)
        assert(sig_wr_clk_polarity.width == wr_ports && sig_wr_clk_polarity.is_fully_const());
        assert(sig_wr_addr.width == wr_ports * addr_bits);
        assert(sig_wr_data.width == wr_ports * memory->width);
-       assert(sig_wr_en.width == wr_ports);
+       assert(sig_wr_en.width == wr_ports * memory->width);
 
        mem->parameters["\\WR_PORTS"] = RTLIL::Const(wr_ports);
        mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.chunks[0].data : RTLIL::Const(0, 0);
index e0e3802d1e2dc9b0d785a7c1a33584d8525ec6a7..10ab6e2f464b69b2bf3760ceed5de8a4a99379cc 100644 (file)
@@ -69,8 +69,8 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell)
        RTLIL::SigSpec refclock;
        RTLIL::State refclock_pol = RTLIL::State::Sx;
        for (int i = 0; i < clocks.width; i++) {
-               RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(i, 1);
-               if (wr_en.is_fully_const() && wr_en.as_int() == 0) {
+               RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(i * mem_width, mem_width);
+               if (wr_en.is_fully_const() && !wr_en.as_bool()) {
                        static_ports.insert(i);
                        continue;
                }
@@ -256,7 +256,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell)
                {
                        RTLIL::SigSpec wr_addr = cell->connections["\\WR_ADDR"].extract(j*mem_abits, mem_abits);
                        RTLIL::SigSpec wr_data = cell->connections["\\WR_DATA"].extract(j*mem_width, mem_width);
-                       RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(j, 1);
+                       RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(j*mem_width, mem_width);
 
                        RTLIL::Cell *c = new RTLIL::Cell;
                        c->name = genid(cell->name, "$wreq", i, "", j);
@@ -271,46 +271,64 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell)
                        module->cells[c->name] = c;
                        count_wrmux++;
 
-                       RTLIL::Wire *w = new RTLIL::Wire;
-                       w->name = genid(cell->name, "$wreq", i, "", j, "$y");
-                       module->wires[w->name] = w;
-                       c->connections["\\Y"] = RTLIL::SigSpec(w);
+                       RTLIL::Wire *w_seladdr = new RTLIL::Wire;
+                       w_seladdr->name = genid(cell->name, "$wreq", i, "", j, "$y");
+                       module->wires[w_seladdr->name] = w_seladdr;
+                       c->connections["\\Y"] = w_seladdr;
 
-                       if (wr_en != RTLIL::SigSpec(1, 1))
+                       int wr_offset = 0;
+                       while (wr_offset < wr_en.width)
                        {
+                               int wr_width = 1;
+                               RTLIL::SigSpec wr_bit = wr_en.extract(wr_offset, 1);
+
+                               while (wr_offset + wr_width < wr_en.width) {
+                                       RTLIL::SigSpec next_wr_bit = wr_en.extract(wr_offset + wr_width, 1);
+                                       if (next_wr_bit != wr_bit)
+                                               break;
+                                       wr_width++;
+                               }
+
+                               RTLIL::Wire *w = w_seladdr;
+
+                               if (wr_bit != RTLIL::SigSpec(1, 1))
+                               {
+                                       c = new RTLIL::Cell;
+                                       c->name = genid(cell->name, "$wren", i, "", j, "", wr_offset);
+                                       c->type = "$and";
+                                       c->parameters["\\A_SIGNED"] = RTLIL::Const(0);
+                                       c->parameters["\\B_SIGNED"] = RTLIL::Const(0);
+                                       c->parameters["\\A_WIDTH"] = RTLIL::Const(1);
+                                       c->parameters["\\B_WIDTH"] = RTLIL::Const(1);
+                                       c->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
+                                       c->connections["\\A"] = w;
+                                       c->connections["\\B"] = wr_bit;
+                                       module->cells[c->name] = c;
+
+                                       w = new RTLIL::Wire;
+                                       w->name = genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y");
+                                       module->wires[w->name] = w;
+                                       c->connections["\\Y"] = RTLIL::SigSpec(w);
+                               }
+
                                c = new RTLIL::Cell;
-                               c->name = genid(cell->name, "$wren", i, "", j);
-                               c->type = "$and";
-                               c->parameters["\\A_SIGNED"] = RTLIL::Const(0);
-                               c->parameters["\\B_SIGNED"] = RTLIL::Const(0);
-                               c->parameters["\\A_WIDTH"] = RTLIL::Const(1);
-                               c->parameters["\\B_WIDTH"] = RTLIL::Const(1);
-                               c->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
-                               c->connections["\\A"] = RTLIL::SigSpec(w);
-                               c->connections["\\B"] = wr_en;
+                               c->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset);
+                               c->type = "$mux";
+                               c->parameters["\\WIDTH"] = wr_width;
+                               c->connections["\\A"] = sig.extract(wr_offset, wr_width);
+                               c->connections["\\B"] = wr_data.extract(wr_offset, wr_width);
+                               c->connections["\\S"] = RTLIL::SigSpec(w);
                                module->cells[c->name] = c;
 
                                w = new RTLIL::Wire;
-                               w->name = genid(cell->name, "$wren", i, "", j, "$y");
+                               w->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y");
+                               w->width = wr_width;
                                module->wires[w->name] = w;
-                               c->connections["\\Y"] = RTLIL::SigSpec(w);
-                       }
+                               c->connections["\\Y"] = w;
 
-                       c = new RTLIL::Cell;
-                       c->name = genid(cell->name, "$wrmux", i, "", j);
-                       c->type = "$mux";
-                       c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
-                       c->connections["\\A"] = sig;
-                       c->connections["\\B"] = wr_data;
-                       c->connections["\\S"] = RTLIL::SigSpec(w);
-                       module->cells[c->name] = c;
-
-                       w = new RTLIL::Wire;
-                       w->name = genid(cell->name, "$wrmux", i, "", j, "$y");
-                       w->width = mem_width;
-                       module->wires[w->name] = w;
-                       c->connections["\\Y"] = RTLIL::SigSpec(w);
-                       sig = RTLIL::SigSpec(w);
+                               sig.replace(wr_offset, w);
+                               wr_offset += wr_width;
+                       }
                }
 
                module->connections.push_back(RTLIL::SigSig(data_reg_in[i], sig));
index 782c0cd798074bb87fb74a26590fb645ca361918..bbd0158336dfc0993479ff5cebaf63fc474e02d0 100644 (file)
@@ -74,7 +74,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
                cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_POLARITY")).extract(i, 1).as_const();
                cell->parameters["\\PRIORITY"] = i;
                cell->connections["\\CLK"] = memory->connections.at("\\WR_CLK").extract(i, 1);
-               cell->connections["\\EN"] = memory->connections.at("\\WR_EN").extract(i, 1);
+               cell->connections["\\EN"] = memory->connections.at("\\WR_EN").extract(i*mem->width, mem->width);
                cell->connections["\\ADDR"] = memory->connections.at("\\WR_ADDR").extract(i*abits, abits);
                cell->connections["\\DATA"] = memory->connections.at("\\WR_DATA").extract(i*mem->width, mem->width);
                module->add(cell);