aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2021-05-22 16:10:18 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2021-05-22 21:42:53 +0200
commitff9e0394b86f701db17ceda48bf8075ce8ac597d (patch)
tree993c3561ab40550dab42dff915dc8f206d802bec /kernel
parent8c734e07b87974fc4931d41b37b459d2c664e1bf (diff)
downloadyosys-ff9e0394b86f701db17ceda48bf8075ce8ac597d.tar.gz
yosys-ff9e0394b86f701db17ceda48bf8075ce8ac597d.tar.bz2
yosys-ff9e0394b86f701db17ceda48bf8075ce8ac597d.zip
kernel/mem: defer port removal to emit()
Diffstat (limited to 'kernel')
-rw-r--r--kernel/mem.cc48
-rw-r--r--kernel/mem.h8
2 files changed, 38 insertions, 18 deletions
diff --git a/kernel/mem.cc b/kernel/mem.cc
index 0301a913c..9d68dbbb7 100644
--- a/kernel/mem.cc
+++ b/kernel/mem.cc
@@ -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)
diff --git a/kernel/mem.h b/kernel/mem.h
index 6d727e71d..547386f3c 100644
--- a/kernel/mem.h
+++ b/kernel/mem.h
@@ -25,20 +25,22 @@
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);