kernel/mem: defer port removal to emit()
authorMarcelina Kościelnicka <mwk@0x04.net>
Sat, 22 May 2021 14:10:18 +0000 (16:10 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Sat, 22 May 2021 19:42:53 +0000 (21:42 +0200)
kernel/mem.cc
kernel/mem.h

index 0301a913c4295a7e7c98d4e279f22f9e662eefaf..9d68dbbb742d8387ffed5c0fd8bbc6f9b23a0d0b 100644 (file)
@@ -52,6 +52,40 @@ void Mem::remove() {
 }
 
 void Mem::emit() {
+       std::vector<int> rd_left;
+       for (int i = 0; i < GetSize(rd_ports); i++) {
+               auto &port = rd_ports[i];
+               if (port.removed) {
+                       if (port.cell) {
+                               module->remove(port.cell);
+                       }
+               } else {
+                       rd_left.push_back(i);
+               }
+       }
+       std::vector<int> wr_left;
+       for (int i = 0; i < GetSize(wr_ports); i++) {
+               auto &port = wr_ports[i];
+               if (port.removed) {
+                       if (port.cell) {
+                               module->remove(port.cell);
+                       }
+               } else {
+                       wr_left.push_back(i);
+               }
+       }
+       for (int i = 0; i < GetSize(rd_left); i++)
+               if (i != rd_left[i])
+                       std::swap(rd_ports[i], rd_ports[rd_left[i]]);
+       rd_ports.resize(GetSize(rd_left));
+       for (int i = 0; i < GetSize(wr_left); i++)
+               if (i != wr_left[i])
+                       std::swap(wr_ports[i], wr_ports[wr_left[i]]);
+       wr_ports.resize(GetSize(wr_left));
+
+       // for future: handle transparency mask here
+       // for future: handle priority mask here
+
        if (packed) {
                if (mem) {
                        module->memories.erase(mem->name);
@@ -205,20 +239,6 @@ void Mem::emit() {
        }
 }
 
-void Mem::remove_wr_port(int idx) {
-       if (wr_ports[idx].cell) {
-               module->remove(wr_ports[idx].cell);
-       }
-       wr_ports.erase(wr_ports.begin() + idx);
-}
-
-void Mem::remove_rd_port(int idx) {
-       if (rd_ports[idx].cell) {
-               module->remove(rd_ports[idx].cell);
-       }
-       rd_ports.erase(rd_ports.begin() + idx);
-}
-
 void Mem::clear_inits() {
        for (auto &init : inits)
                if (init.cell)
index 6d727e71d1a33de5a788fbf0e416a13abb31967d..547386f3cb89de02f416b03088d93cf91a9984ea 100644 (file)
 YOSYS_NAMESPACE_BEGIN
 
 struct MemRd {
+       bool removed;
        dict<IdString, Const> attributes;
        Cell *cell;
        bool clk_enable, clk_polarity;
        bool transparent;
        SigSpec clk, en, addr, data;
-       MemRd() : cell(nullptr) {}
+       MemRd() : removed(false), cell(nullptr) {}
 };
 
 struct MemWr {
+       bool removed;
        dict<IdString, Const> attributes;
        Cell *cell;
        bool clk_enable, clk_polarity;
        SigSpec clk, en, addr, data;
-       MemWr() : cell(nullptr) {}
+       MemWr() : removed(false), cell(nullptr) {}
 };
 
 struct MemInit {
@@ -63,8 +65,6 @@ struct Mem {
 
        void remove();
        void emit();
-       void remove_wr_port(int idx);
-       void remove_rd_port(int idx);
        void clear_inits();
        Const get_init_data() const;
        static std::vector<Mem> get_all_memories(Module *module);