From 95a39d342584fc9f98c57550aa7fba9e4652067b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 17:00:20 +0200 Subject: [PATCH] kernel/mem: Add priority_mask to model. This is going to be used to store arbitrary priority masks in the future. Right now, it is not supported by our cell library, so the priority_mask is computed from port order on helper construction, and discarded when emitted. However, this allows us to already convert helper-using passes to the new model. --- kernel/mem.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++++- kernel/mem.h | 1 + 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 4c3b333c1..2a51ec5d9 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -85,7 +85,12 @@ void Mem::emit() { wr_ports.resize(GetSize(wr_left)); // for future: handle transparency mask here - // for future: handle priority mask here + + for (auto &port : wr_ports) { + for (int i = 0; i < GetSize(wr_left); i++) + port.priority_mask[i] = port.priority_mask[wr_left[i]]; + port.priority_mask.resize(GetSize(wr_left)); + } if (packed) { if (mem) { @@ -276,6 +281,18 @@ void Mem::check() { log_assert(GetSize(port.clk) == 1); log_assert(GetSize(port.en) == width); log_assert(GetSize(port.data) == width); + log_assert(GetSize(port.priority_mask) == GetSize(wr_ports)); + for (int j = 0; j < GetSize(wr_ports); j++) { + auto &wport = wr_ports[j]; + if (port.priority_mask[j] && !wport.removed) { + log_assert(j < i); + log_assert(port.clk_enable == wport.clk_enable); + if (port.clk_enable) { + log_assert(port.clk == wport.clk); + log_assert(port.clk_polarity == wport.clk_polarity); + } + } + } } } @@ -355,6 +372,20 @@ namespace { for (auto &it : inits) res.inits.push_back(it.second); } + for (int i = 0; i < GetSize(res.wr_ports); i++) { + auto &port = res.wr_ports[i]; + port.priority_mask.resize(GetSize(res.wr_ports)); + for (int j = 0; j < i; j++) { + auto &oport = res.wr_ports[j]; + if (port.clk_enable != oport.clk_enable) + continue; + if (port.clk_enable && port.clk != oport.clk) + continue; + if (port.clk_enable && port.clk_polarity != oport.clk_polarity) + continue; + port.priority_mask[j] = true; + } + } res.check(); return res; } @@ -412,6 +443,20 @@ namespace { mwr.data = cell->getPort(ID::WR_DATA).extract(i * res.width, res.width); res.wr_ports.push_back(mwr); } + for (int i = 0; i < GetSize(res.wr_ports); i++) { + auto &port = res.wr_ports[i]; + port.priority_mask.resize(GetSize(res.wr_ports)); + for (int j = 0; j < i; j++) { + auto &oport = res.wr_ports[j]; + if (port.clk_enable != oport.clk_enable) + continue; + if (port.clk_enable && port.clk != oport.clk) + continue; + if (port.clk_enable && port.clk_polarity != oport.clk_polarity) + continue; + port.priority_mask[j] = true; + } + } res.check(); return res; } diff --git a/kernel/mem.h b/kernel/mem.h index a2af6a183..af06e970a 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -40,6 +40,7 @@ struct MemWr { dict attributes; Cell *cell; bool clk_enable, clk_polarity; + std::vector priority_mask; SigSpec clk, en, addr, data; MemWr() : removed(false), cell(nullptr) {} }; -- 2.30.2