aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorMarcelina Kościelnicka <mwk@0x04.net>2021-05-25 15:48:52 +0200
committerMarcelina Kościelnicka <mwk@0x04.net>2021-05-25 17:51:47 +0200
commit097de6c5f8c5170cc275b7250bf3780ae6ab3a00 (patch)
treeb7445fa9c7131335aa3c5ad0290d273afebb0981 /kernel
parent96c7d60304e4e9e4cb4d85924efcafa546283c65 (diff)
downloadyosys-097de6c5f8c5170cc275b7250bf3780ae6ab3a00.tar.gz
yosys-097de6c5f8c5170cc275b7250bf3780ae6ab3a00.tar.bz2
yosys-097de6c5f8c5170cc275b7250bf3780ae6ab3a00.zip
mem/extract_rdff: Fix wire naming and wide port support.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/mem.cc28
1 files changed, 22 insertions, 6 deletions
diff --git a/kernel/mem.cc b/kernel/mem.cc
index 649515e0c..f1fedf3c2 100644
--- a/kernel/mem.cc
+++ b/kernel/mem.cc
@@ -524,17 +524,33 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
if (port.transparent)
{
- SigSpec sig_q = module->addWire(stringf("%s$rdreg[%d]$q", memid.c_str(), idx), GetSize(port.addr));
- SigSpec sig_d = port.addr;
- port.addr = sig_q;
- c = module->addDffe(stringf("%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true);
+ log_assert(port.en == State::S1);
+
+ // Do not put a register in front of constant address bits — this is both
+ // unnecessary and will break wide ports.
+ int width = 0;
+ for (int i = 0; i < GetSize(port.addr); i++)
+ if (port.addr[i].wire)
+ width++;
+
+ SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid.c_str(), idx), width);
+ SigSpec sig_d;
+
+ int pos = 0;
+ for (int i = 0; i < GetSize(port.addr); i++)
+ if (port.addr[i].wire) {
+ sig_d.append(port.addr[i]);
+ port.addr[i] = sig_q[pos++];
+ }
+
+ c = module->addDffe(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, State::S1, sig_d, sig_q, port.clk_polarity, true);
}
else
{
- SigSpec sig_d = module->addWire(stringf("%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data));
+ SigSpec sig_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data));
SigSpec sig_q = port.data;
port.data = sig_d;
- c = module->addDffe(stringf("%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true);
+ c = module->addDffe(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, port.en, sig_d, sig_q, port.clk_polarity, true);
}
log("Extracted %s FF from read port %d of %s.%s: %s\n", port.transparent ? "addr" : "data",