opt_mem_feedback: Add wide port support.
authorMarcelina Kościelnicka <mwk@0x04.net>
Mon, 24 May 2021 23:52:52 +0000 (01:52 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Tue, 25 May 2021 00:57:32 +0000 (02:57 +0200)
passes/opt/opt_mem_feedback.cc

index f186d845dd95bc719a1ea10b4f8eddbbd0e33b63..90e5cea9bc2f017b5e3ac9b61533087a809ef924 100644 (file)
@@ -144,11 +144,14 @@ struct OptMemFeedbackWorker
                        if (port.clk_enable)
                                continue;
 
-                       SigSpec addr = sigmap_xmux(port.addr);
-
-                       async_rd_bits[addr].resize(mem.width);
-                       for (int i = 0; i < mem.width; i++)
-                               async_rd_bits[addr][i].insert(sigmap(port.data[i]));
+                       for (int sub = 0; sub < (1 << port.wide_log2); sub++) {
+                               SigSpec addr = sigmap_xmux(port.addr);
+                               for (int i = 0; i < port.wide_log2; i++)
+                                       addr[i] = State(sub >> i & 1);
+                               async_rd_bits[addr].resize(mem.width);
+                               for (int i = 0; i < mem.width; i++)
+                                       async_rd_bits[addr][i].insert(sigmap(port.data[i + sub * mem.width]));
+                       }
                }
 
                if (async_rd_bits.empty())
@@ -161,21 +164,28 @@ struct OptMemFeedbackWorker
                {
                        auto &port = mem.wr_ports[i];
 
-                       SigSpec addr = sigmap_xmux(port.addr);
-
-                       if (!async_rd_bits.count(addr))
-                               continue;
-
                        log("  Analyzing %s.%s write port %d.\n", log_id(module), log_id(mem.memid), i);
 
-                       for (int j = 0; j < GetSize(port.data); j++)
+                       for (int sub = 0; sub < (1 << port.wide_log2); sub++)
                        {
-                               if (port.en[j] == State::S0)
+                               SigSpec addr = sigmap_xmux(port.addr);
+                               for (int k = 0; k < port.wide_log2; k++)
+                                       addr[k] = State(sub >> k & 1);
+
+                               if (!async_rd_bits.count(addr))
                                        continue;
 
-                               dict<RTLIL::SigBit, bool> state;
+                               for (int j = 0; j < mem.width; j++)
+                               {
+                                       int bit_idx = sub * mem.width + j;
+
+                                       if (port.en[bit_idx] == State::S0)
+                                               continue;
+
+                                       dict<RTLIL::SigBit, bool> state;
 
-                               find_data_feedback(async_rd_bits.at(addr).at(j), sigmap(port.data[j]), state, i, j, paths);
+                                       find_data_feedback(async_rd_bits.at(addr).at(j), sigmap(port.data[bit_idx]), state, i, bit_idx, paths);
+                               }
                        }
                }