diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/mem.cc | 32 | ||||
-rw-r--r-- | kernel/mem.h | 18 |
2 files changed, 30 insertions, 20 deletions
diff --git a/kernel/mem.cc b/kernel/mem.cc index 77165d97f..a7ee1f2d6 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -136,10 +136,8 @@ void Mem::emit() { rd_transparent.bits.push_back(State(port.transparent)); rd_clk.append(port.clk); rd_en.append(port.en); - SigSpec addr = port.addr; + SigSpec addr = port.sub_addr(sub); addr.extend_u0(abits, false); - for (int i = 0; i < port.wide_log2; i++) - addr[i] = State(sub >> i & 1); rd_addr.append(addr); log_assert(GetSize(addr) == abits); } @@ -170,10 +168,8 @@ void Mem::emit() { wr_clk_enable.bits.push_back(State(port.clk_enable)); wr_clk_polarity.bits.push_back(State(port.clk_polarity)); wr_clk.append(port.clk); - SigSpec addr = port.addr; + SigSpec addr = port.sub_addr(sub); addr.extend_u0(abits, false); - for (int i = 0; i < port.wide_log2; i++) - addr[i] = State(sub >> i & 1); wr_addr.append(addr); log_assert(GetSize(addr) == abits); } @@ -615,11 +611,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { SigSpec raddr = port.addr; SigSpec waddr = wport.addr; - for (int j = min_wide_log2; j < max_wide_log2; j++) - if (wide_write) - waddr[j] = State(sub >> j & 1); - else - raddr[j] = State(sub >> j & 1); + if (wide_write) + waddr = wport.sub_addr(sub); + else + raddr = port.sub_addr(sub); SigSpec addr_eq; if (raddr != waddr) addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid.c_str(), idx, i, sub), raddr, waddr); @@ -722,8 +717,7 @@ void Mem::narrow() { port.init_value = port.init_value.extract(it.second * width, width); port.arst_value = port.arst_value.extract(it.second * width, width); port.srst_value = port.srst_value.extract(it.second * width, width); - for (int i = 0; i < port.wide_log2; i++) - port.addr[i] = State(it.second >> i & 1); + port.addr = port.sub_addr(it.second); port.wide_log2 = 0; } new_rd_ports.push_back(port); @@ -736,8 +730,7 @@ void Mem::narrow() { if (port.wide_log2) { port.data = port.data.extract(it.second * width, width); port.en = port.en.extract(it.second * width, width); - for (int i = 0; i < port.wide_log2; i++) - port.addr[i] = State(it.second >> i & 1); + port.addr = port.sub_addr(it.second); port.wide_log2 = 0; } port.priority_mask.clear(); @@ -761,11 +754,10 @@ void Mem::emulate_priority(int idx1, int idx2) for (int sub = 0; sub < (1 << max_wide_log2); sub += (1 << min_wide_log2)) { SigSpec addr1 = port1.addr; SigSpec addr2 = port2.addr; - for (int j = min_wide_log2; j < max_wide_log2; j++) - if (wide1) - addr1[j] = State(sub >> j & 1); - else - addr2[j] = State(sub >> j & 1); + if (wide1) + addr1 = port1.sub_addr(sub); + else + addr2 = port2.sub_addr(sub); SigSpec addr_eq = module->Eq(NEW_ID, addr1, addr2); int ewidth = width << min_wide_log2; int sub1 = wide1 ? sub : 0; diff --git a/kernel/mem.h b/kernel/mem.h index 15886877a..82eb0f488 100644 --- a/kernel/mem.h +++ b/kernel/mem.h @@ -34,7 +34,16 @@ struct MemRd { Const arst_value, srst_value, init_value; bool transparent; SigSpec clk, en, arst, srst, addr, data; + MemRd() : removed(false), cell(nullptr) {} + + // Returns the address of given subword index accessed by this port. + SigSpec sub_addr(int sub) { + SigSpec res = addr; + for (int i = 0; i < wide_log2; i++) + res[i] = State(sub >> i & 1); + return res; + } }; struct MemWr { @@ -45,7 +54,16 @@ struct MemWr { bool clk_enable, clk_polarity; std::vector<bool> priority_mask; SigSpec clk, en, addr, data; + MemWr() : removed(false), cell(nullptr) {} + + // Returns the address of given subword index accessed by this port. + SigSpec sub_addr(int sub) { + SigSpec res = addr; + for (int i = 0; i < wide_log2; i++) + res[i] = State(sub >> i & 1); + return res; + } }; struct MemInit { |