diff --git a/kernel/mem.cc b/kernel/mem.cc index abf5453d3..8ba81eead 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -888,6 +888,8 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { if (!port.clk_enable) return nullptr; + std::string mem_src = get_src_attribute(); + Cell *c; // There are two ways to handle rdff extraction when transparency is involved: @@ -934,7 +936,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { port.addr[i] = sig_q[pos++]; } - c = module->addDff(stringf("$%s$rdreg[%d]", memid, idx), port.clk, sig_d, sig_q, port.clk_polarity); + c = module->addDff(stringf("$%s$rdreg[%d]", memid, idx), port.clk, sig_d, sig_q, port.clk_polarity, mem_src); } else { c = nullptr; } @@ -966,7 +968,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { raddr = port.sub_addr(sub); SigSpec addr_eq; if (raddr != waddr) - addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid, idx, i, sub), raddr, waddr); + addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid, idx, i, sub), raddr, waddr, false, mem_src); int pos = 0; int ewidth = width << min_wide_log2; int wsub = wide_write ? sub : 0; @@ -979,10 +981,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { SigSpec other = port.transparency_mask[i] ? wport.data.extract(pos + wsub * width, epos-pos) : Const(State::Sx, epos-pos); SigSpec cond; if (raddr != waddr) - cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq); + cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq, false, mem_src); else cond = wport.en[pos + wsub * width]; - SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), cur, other, cond); + SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), cur, other, cond, mem_src); sig_d.replace(pos + rsub * width, merged); pos = epos; } @@ -992,6 +994,8 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { IdString name = stringf("$%s$rdreg[%d]", memid, idx); FfData ff(module, initvals, name); + if (!mem_src.empty()) + ff.attributes[ID::src] = mem_src; ff.width = GetSize(port.data); ff.has_clk = true; ff.sig_clk = port.clk; diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index cc8dce13e..0d922f257 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -42,6 +42,10 @@ struct MemoryMapWorker std::map, RTLIL::SigBit> decoder_cache; + // src of the Mem currently being lowered, so every cell created on its + // behalf inherits source-location tracking from the original $mem_v2. + std::string mem_src; + MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module), sigmap(module), initvals(&sigmap, module) {} std::string map_case(std::string value) const @@ -89,12 +93,12 @@ struct MemoryMapWorker if (decoder_cache.count(key) == 0) { if (GetSize(addr_sig) < 2) { - decoder_cache[key] = module->Eq(NEW_ID, addr_sig, addr_val); + decoder_cache[key] = module->Eq(NEW_ID, addr_sig, addr_val, false, mem_src); } else { int split_at = GetSize(addr_sig) / 2; RTLIL::SigBit left_eq = addr_decode(addr_sig.extract(0, split_at), addr_val.extract(0, split_at)); RTLIL::SigBit right_eq = addr_decode(addr_sig.extract(split_at, GetSize(addr_sig) - split_at), addr_val.extract(split_at, GetSize(addr_val) - split_at)); - decoder_cache[key] = module->And(NEW_ID, left_eq, right_eq); + decoder_cache[key] = module->And(NEW_ID, left_eq, right_eq, false, mem_src); } } @@ -108,6 +112,8 @@ struct MemoryMapWorker std::set static_ports; std::map static_cells_map; + mem_src = mem.get_src_attribute(); + SigSpec init_data = mem.get_init_data(); if (!mem.wr_ports.empty() && rom_only) @@ -238,6 +244,7 @@ struct MemoryMapWorker c->parameters[ID::CLK_POLARITY] = RTLIL::Const(refclock_pol); c->setPort(ID::CLK, refclock); } + c->set_src_attribute(mem_src); c->parameters[ID::WIDTH] = mem.width; RTLIL::Wire *w_in = module->addWire(genid(mem.memid, "", addr, "$d"), mem.width); @@ -292,6 +299,7 @@ struct MemoryMapWorker for (size_t k = 0; k < rd_signals.size(); k++) { RTLIL::Cell *c = module->addCell(genid(mem.memid, "$rdmux", i, "", j, "", k), ID($mux)); + c->set_src_attribute(mem_src); c->parameters[ID::WIDTH] = GetSize(port.data); c->setPort(ID::Y, rd_signals[k]); c->setPort(ID::S, rd_addr.extract(abits-j-1, 1)); @@ -351,6 +359,7 @@ struct MemoryMapWorker if (wr_bit != State::S1) { RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wren", addr, "", j, "", wr_offset), ID($and)); + c->set_src_attribute(mem_src); c->parameters[ID::A_SIGNED] = RTLIL::Const(0); c->parameters[ID::B_SIGNED] = RTLIL::Const(0); c->parameters[ID::A_WIDTH] = RTLIL::Const(1); @@ -364,6 +373,7 @@ struct MemoryMapWorker } RTLIL::Cell *c = module->addCell(genid(mem.memid, "$wrmux", addr, "", j, "", wr_offset), ID($mux)); + c->set_src_attribute(mem_src); c->parameters[ID::WIDTH] = wr_width; c->setPort(ID::A, sig.extract(wr_offset, wr_width)); c->setPort(ID::B, port.data.extract(wr_offset + sub * mem.width, wr_width));