kernel/mem: Add prepare_wr_merge helper.
authorMarcelina Kościelnicka <mwk@0x04.net>
Wed, 26 May 2021 00:06:44 +0000 (02:06 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Wed, 26 May 2021 00:55:00 +0000 (02:55 +0200)
kernel/mem.cc
kernel/mem.h

index fe88be5d7bc0c46b2817467f19d870bc94af9186..77165d97fbc0ae50bbd33389e5b714618907fd58 100644 (file)
@@ -786,3 +786,23 @@ void Mem::emulate_priority(int idx1, int idx2)
        }
        port2.priority_mask[idx1] = false;
 }
+
+void Mem::prepare_wr_merge(int idx1, int idx2) {
+       log_assert(idx1 < idx2);
+       auto &port1 = wr_ports[idx1];
+       auto &port2 = wr_ports[idx2];
+       // If port 2 has priority over a port before port 1, make port 1 have priority too.
+       for (int i = 0; i < idx1; i++)
+               if (port2.priority_mask[i])
+                       port1.priority_mask[i] = true;
+       // If port 2 has priority over a port after port 1, emulate it.
+       for (int i = idx1 + 1; i < idx2; i++)
+               if (port2.priority_mask[i])
+                       emulate_priority(i, idx2);
+       // If some port had priority over port 2, make it have priority over the merged port too.
+       for (int i = idx2 + 1; i < GetSize(wr_ports); i++) {
+               auto &oport = wr_ports[i];
+               if (oport.priority_mask[idx2])
+                       oport.priority_mask[idx1] = true;
+       }
+}
index 49b72bc353ea572871a85074717029ffa7c0a0a7..15886877a80a342e709f8295bc68564610e02389 100644 (file)
@@ -84,6 +84,13 @@ struct Mem {
        // from the priority mask.
        void emulate_priority(int idx1, int idx2);
 
+       // Prepares for merging write port idx2 into idx1 (where idx1 < idx2).
+       // Specifically, takes care of priority masks: any priority relations
+       // that idx2 had are replicated onto idx1, unless they conflict with
+       // priorities already present on idx1, in which case emulate_priority
+       // is called.
+       void prepare_wr_merge(int idx1, int idx2);
+
        Mem(Module *module, IdString memid, int width, int start_offset, int size) : module(module), memid(memid), packed(false), mem(nullptr), cell(nullptr), width(width), start_offset(start_offset), size(size) {}
 };