aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2021-05-26 02:06:44 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2021-05-26 02:55:00 +0200
commit57ca51be76ec4dc6eba802728ca6407520c704e4 (patch)
tree68c12bdc81109f6bd3d231ce162ea7a0370bd6a0
parent64ba3c384255335d61e2d07160c57fa74156cde1 (diff)
downloadyosys-57ca51be76ec4dc6eba802728ca6407520c704e4.tar.gz
yosys-57ca51be76ec4dc6eba802728ca6407520c704e4.tar.bz2
yosys-57ca51be76ec4dc6eba802728ca6407520c704e4.zip
kernel/mem: Add prepare_wr_merge helper.
-rw-r--r--kernel/mem.cc20
-rw-r--r--kernel/mem.h7
2 files changed, 27 insertions, 0 deletions
diff --git a/kernel/mem.cc b/kernel/mem.cc
index fe88be5d7..77165d97f 100644
--- a/kernel/mem.cc
+++ b/kernel/mem.cc
@@ -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;
+ }
+}
diff --git a/kernel/mem.h b/kernel/mem.h
index 49b72bc35..15886877a 100644
--- a/kernel/mem.h
+++ b/kernel/mem.h
@@ -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) {}
};