3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-24 08:02:32 +00:00
This commit is contained in:
Emil J. Tywoniak 2026-06-11 13:17:54 +02:00
parent f592f2f3af
commit 8e522b08c0
206 changed files with 3081 additions and 2782 deletions

View file

@ -204,7 +204,7 @@ struct MemMapping {
if (!check_init(rdef))
continue;
if (rdef.prune_rom && mem.wr_ports.empty()) {
log_debug("memory %s.%s: rejecting mapping to %s: ROM mapping disabled (prune_rom set)\n", mem.module->name.unescape(), mem.memid.unescape(), rdef.id.unescape());
log_debug("memory %s.%s: rejecting mapping to %s: ROM mapping disabled (prune_rom set)\n", log_id(mem.module), mem.memid.unescape(), rdef.id.unescape());
continue;
}
MemConfig cfg;
@ -380,7 +380,7 @@ void MemMapping::dump_configs(int stage) {
default:
abort();
}
log_debug("Memory %s.%s mapping candidates (%s):\n", mem.module->name.unescape(), mem.memid.unescape(), stage_name);
log_debug("Memory %s.%s mapping candidates (%s):\n", log_id(mem.module), mem.memid.unescape(), stage_name);
if (logic_ok) {
log_debug("- logic fallback\n");
log_debug(" - cost: %f\n", logic_cost);
@ -527,7 +527,7 @@ void MemMapping::determine_style() {
auto find_attr = search_for_attribute(mem, ID::lram);
if (find_attr.first && find_attr.second.as_bool()) {
kind = RamKind::Huge;
log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", mem.module->name.unescape(), mem.memid.unescape());
log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", log_id(mem.module), mem.memid.unescape());
return;
}
for (auto attr: {ID::ram_block, ID::rom_block, ID::ram_style, ID::rom_style, ID::ramstyle, ID::romstyle, ID::syn_ramstyle, ID::syn_romstyle}) {
@ -536,7 +536,7 @@ void MemMapping::determine_style() {
Const val = find_attr.second;
if (val == 1) {
kind = RamKind::NotLogic;
log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", attr.unescape(), mem.module->name.unescape(), mem.memid.unescape());
log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", attr.unescape(), log_id(mem.module), mem.memid.unescape());
return;
}
std::string val_s = val.decode_string();
@ -549,20 +549,20 @@ void MemMapping::determine_style() {
// Nothing.
} else if (val_s == "logic" || val_s == "registers") {
kind = RamKind::Logic;
log("found attribute '%s = %s' on memory %s.%s, forced mapping to FF\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape());
log("found attribute '%s = %s' on memory %s.%s, forced mapping to FF\n", attr.unescape(), val_s, log_id(mem.module), mem.memid.unescape());
} else if (val_s == "distributed") {
kind = RamKind::Distributed;
log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape());
log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", attr.unescape(), val_s, log_id(mem.module), mem.memid.unescape());
} else if (val_s == "block" || val_s == "block_ram" || val_s == "ebr") {
kind = RamKind::Block;
log("found attribute '%s = %s' on memory %s.%s, forced mapping to block RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape());
log("found attribute '%s = %s' on memory %s.%s, forced mapping to block RAM\n", attr.unescape(), val_s, log_id(mem.module), mem.memid.unescape());
} else if (val_s == "huge" || val_s == "ultra") {
kind = RamKind::Huge;
log("found attribute '%s = %s' on memory %s.%s, forced mapping to huge RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape());
log("found attribute '%s = %s' on memory %s.%s, forced mapping to huge RAM\n", attr.unescape(), val_s, log_id(mem.module), mem.memid.unescape());
} else {
kind = RamKind::NotLogic;
style = val_s;
log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape(), val_s);
log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", attr.unescape(), val_s, log_id(mem.module), mem.memid.unescape(), val_s);
}
return;
}
@ -1626,8 +1626,8 @@ std::vector<SigSpec> generate_demux(Mem &mem, int wpidx, const Swizzle &swz) {
lo = new_lo;
hi = new_hi;
}
SigSpec in_range = mem.module->And(NEW_ID, mem.module->Ge(NEW_ID, addr, lo), mem.module->Lt(NEW_ID, addr, hi));
sig_a = mem.module->Mux(NEW_ID, Const(State::S0, GetSize(sig_a)), sig_a, in_range);
SigSpec in_range = mem.module->And(NEW_TWINE, mem.module->Ge(NEW_TWINE, addr, lo), mem.module->Lt(NEW_TWINE, addr, hi));
sig_a = mem.module->Mux(NEW_TWINE, Const(State::S0, GetSize(sig_a)), sig_a, in_range);
}
addr.extend_u0(swz.addr_shift + hi_bits, false);
SigSpec sig_s;
@ -1639,7 +1639,7 @@ std::vector<SigSpec> generate_demux(Mem &mem, int wpidx, const Swizzle &swz) {
if (GetSize(sig_s) == 0)
sig_y = sig_a;
else
sig_y = mem.module->Demux(NEW_ID, sig_a, sig_s);
sig_y = mem.module->Demux(NEW_TWINE, sig_a, sig_s);
for (int i = 0; i < ((swz.addr_end - swz.addr_start) >> swz.addr_shift); i++) {
for (int j = 0; j < (1 << GetSize(swz.addr_mux_bits)); j++) {
int hi = ((swz.addr_start >> swz.addr_shift) + i) & ((1 << hi_bits) - 1);
@ -1666,7 +1666,7 @@ std::vector<SigSpec> generate_mux(Mem &mem, int rpidx, const Swizzle &swz) {
}
if (port.clk_enable) {
SigSpec new_sig_s = mem.module->addWire(NEW_TWINE, GetSize(sig_s));
mem.module->addDffe(NEW_ID, port.clk, port.en, sig_s, new_sig_s, port.clk_polarity);
mem.module->addDffe(NEW_TWINE, port.clk, port.en, sig_s, new_sig_s, port.clk_polarity);
sig_s = new_sig_s;
}
SigSpec sig_a = Const(State::Sx, GetSize(port.data) << hi_bits << GetSize(swz.addr_mux_bits));
@ -1680,7 +1680,7 @@ std::vector<SigSpec> generate_mux(Mem &mem, int rpidx, const Swizzle &swz) {
res.push_back(sig);
}
}
mem.module->addBmux(NEW_ID, sig_a, sig_s, port.data);
mem.module->addBmux(NEW_TWINE, sig_a, sig_s, port.data);
return res;
}
@ -1710,7 +1710,7 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
if (pdef.clk_en) {
if (rpcfg.rd_en_to_clk_en) {
if (pdef.rdwr == RdWrKind::NoChange) {
clk_en = mem.module->Or(NEW_ID, rport.en, mem.module->ReduceOr(NEW_ID, wport.en));
clk_en = mem.module->Or(NEW_TWINE, rport.en, mem.module->ReduceOr(NEW_TWINE, wport.en));
} else {
clk_en = rport.en;
}
@ -1744,20 +1744,20 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
switch (pdef.clk_pol) {
case ClkPolKind::Posedge:
if (!clk_pol)
clk = mem.module->Not(NEW_ID, clk);
clk = mem.module->Not(NEW_TWINE, clk);
break;
case ClkPolKind::Negedge:
if (clk_pol)
clk = mem.module->Not(NEW_ID, clk);
clk = mem.module->Not(NEW_TWINE, clk);
break;
case ClkPolKind::Anyedge:
for (auto cell: cells)
cell->setParam(stringf("\\PORT_%s_CLK_POL", name), clk_pol);
}
for (auto cell: cells) {
cell->setPort(stringf("\\PORT_%s_CLK", name), clk);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_CLK", name)}), clk);
if (pdef.clk_en)
cell->setPort(stringf("\\PORT_%s_CLK_EN", name), clk_en);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_CLK_EN", name)}), clk_en);
}
}
@ -1819,7 +1819,7 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
for (int i = 0; i < hw_wr_wide_log2 && i < hw_rd_wide_log2; i++)
hw_addr[i] = State::S0;
for (auto cell: cells)
cell->setPort(stringf("\\PORT_%s_ADDR", name), hw_addr);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_ADDR", name)}), hw_addr);
// Write part.
if (pdef.kind != PortKind::Ar && pdef.kind != PortKind::Sr) {
@ -1850,31 +1850,31 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
hw_wren.append(big_wren[bit.mux_idx][bit.bit]);
}
}
cell->setPort(stringf("\\PORT_%s_WR_DATA", name), hw_wdata);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_WR_DATA", name)}), hw_wdata);
if (pdef.wrbe_separate) {
// TODO make some use of it
SigSpec en = mem.module->ReduceOr(NEW_ID, hw_wren);
cell->setPort(stringf("\\PORT_%s_WR_EN", name), en);
cell->setPort(stringf("\\PORT_%s_WR_BE", name), hw_wren);
SigSpec en = mem.module->ReduceOr(NEW_TWINE, hw_wren);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_WR_EN", name)}), en);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_WR_BE", name)}), hw_wren);
if (cfg.def->width_mode != WidthMode::Single)
cell->setParam(stringf("\\PORT_%s_WR_BE_WIDTH", name), GetSize(hw_wren));
} else {
cell->setPort(stringf("\\PORT_%s_WR_EN", name), hw_wren);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_WR_EN", name)}), hw_wren);
if (cfg.def->byte != 0 && (cfg.def->width_mode != WidthMode::Single || opts.force_params))
cell->setParam(stringf("\\PORT_%s_WR_EN_WIDTH", name), GetSize(hw_wren));
}
}
} else {
for (auto cell: cells) {
cell->setPort(stringf("\\PORT_%s_WR_DATA", name), Const(State::Sx, width));
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_WR_DATA", name)}), Const(State::Sx, width));
SigSpec hw_wren = Const(State::S0, width / effective_byte);
if (pdef.wrbe_separate) {
cell->setPort(stringf("\\PORT_%s_WR_EN", name), State::S0);
cell->setPort(stringf("\\PORT_%s_WR_BE", name), hw_wren);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_WR_EN", name)}), State::S0);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_WR_BE", name)}), hw_wren);
if (cfg.def->width_mode != WidthMode::Single)
cell->setParam(stringf("\\PORT_%s_WR_BE_WIDTH", name), GetSize(hw_wren));
} else {
cell->setPort(stringf("\\PORT_%s_WR_EN", name), hw_wren);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_WR_EN", name)}), hw_wren);
if (cfg.def->byte != 0 && cfg.def->width_mode != WidthMode::Single)
cell->setParam(stringf("\\PORT_%s_WR_EN_WIDTH", name), GetSize(hw_wren));
}
@ -1894,11 +1894,11 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
auto cell = cells[rd];
if (pdef.kind == PortKind::Sr || pdef.kind == PortKind::Srsw) {
if (pdef.rd_en)
cell->setPort(stringf("\\PORT_%s_RD_EN", name), rpcfg.rd_en_to_clk_en ? State::S1 : rport.en);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_RD_EN", name)}), rpcfg.rd_en_to_clk_en ? State::S1 : rport.en);
if (pdef.rdarstval != ResetValKind::None)
cell->setPort(stringf("\\PORT_%s_RD_ARST", name), rport.arst);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_RD_ARST", name)}), rport.arst);
if (pdef.rdsrstval != ResetValKind::None)
cell->setPort(stringf("\\PORT_%s_RD_SRST", name), rport.srst);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_RD_SRST", name)}), rport.srst);
if (pdef.rdinitval == ResetValKind::Any || pdef.rdinitval == ResetValKind::NoUndef) {
Const val = rport.init_value;
if (pdef.rdarstval == ResetValKind::Init && rport.arst != State::S0) {
@ -1949,7 +1949,7 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
}
}
SigSpec hw_rdata = mem.module->addWire(NEW_TWINE, width);
cell->setPort(stringf("\\PORT_%s_RD_DATA", name), hw_rdata);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_RD_DATA", name)}), hw_rdata);
SigSpec lhs;
SigSpec rhs;
for (int i = 0; i < GetSize(hw_rdata); i++) {
@ -1965,11 +1965,11 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
for (auto cell: cells) {
if (pdef.kind == PortKind::Sr || pdef.kind == PortKind::Srsw) {
if (pdef.rd_en)
cell->setPort(stringf("\\PORT_%s_RD_EN", name), State::S0);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_RD_EN", name)}), State::S0);
if (pdef.rdarstval != ResetValKind::None)
cell->setPort(stringf("\\PORT_%s_RD_ARST", name), State::S0);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_RD_ARST", name)}), State::S0);
if (pdef.rdsrstval != ResetValKind::None)
cell->setPort(stringf("\\PORT_%s_RD_SRST", name), State::S0);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_RD_SRST", name)}), State::S0);
if (pdef.rdinitval == ResetValKind::Any)
cell->setParam(stringf("\\PORT_%s_RD_INIT_VALUE", name), Const(State::Sx, width));
else if (pdef.rdinitval == ResetValKind::NoUndef)
@ -1984,14 +1984,14 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
cell->setParam(stringf("\\PORT_%s_RD_SRST_VALUE", name), Const(State::S0, width));
}
SigSpec hw_rdata = mem.module->addWire(NEW_TWINE, width);
cell->setPort(stringf("\\PORT_%s_RD_DATA", name), hw_rdata);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\PORT_%s_RD_DATA", name)}), hw_rdata);
}
}
}
}
void MemMapping::emit(const MemConfig &cfg) {
log("mapping memory %s.%s via %s\n", mem.module->name.unescape(), mem.memid.unescape(), cfg.def->id.unescape());
log("mapping memory %s.%s via %s\n", log_id(mem.module), mem.memid.unescape(), cfg.def->id.unescape());
// First, handle emulations.
if (cfg.emu_read_first)
mem.emulate_read_first(&worker.initvals);
@ -2068,7 +2068,7 @@ void MemMapping::emit(const MemConfig &cfg) {
for (int rp = 0; rp < cfg.repl_port; rp++) {
std::vector<Cell *> cells;
for (int rd = 0; rd < cfg.repl_d; rd++) {
Cell *cell = mem.module->addCell(stringf("%s.%d.%d", mem.memid, rp, rd), cfg.def->id);
Cell *cell = mem.module->addCell(mem.module->design->twines.add(Twine{stringf("%s.%d.%d", mem.memid.str(), rp, rd)}), cfg.def->id);
if (cfg.def->width_mode == WidthMode::Global || opts.force_params)
cell->setParam(ID::WIDTH, cfg.def->dbits[cfg.base_width_log2]);
if (opts.force_params)
@ -2086,12 +2086,12 @@ void MemMapping::emit(const MemConfig &cfg) {
auto &ccfg = cfg.shared_clocks[i];
if (cdef.anyedge) {
cell->setParam(stringf("\\CLK_%s_POL", cdef.name), ccfg.used ? ccfg.polarity : true);
cell->setPort(stringf("\\CLK_%s", cdef.name), ccfg.used ? ccfg.clk : State::S0);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\CLK_%s", cdef.name)}), ccfg.used ? ccfg.clk : State::S0);
} else {
SigSpec sig = ccfg.used ? ccfg.clk : State::S0;
if (ccfg.used && ccfg.invert)
sig = mem.module->Not(NEW_ID, sig);
cell->setPort(stringf("\\CLK_%s", cdef.name), sig);
sig = mem.module->Not(NEW_TWINE, sig);
cell->setPort(mem.module->design->twines.add(Twine{stringf("\\CLK_%s", cdef.name)}), sig);
}
}
if (cfg.def->init == MemoryInitKind::Any || cfg.def->init == MemoryInitKind::NoUndef) {
@ -2252,9 +2252,9 @@ struct MemoryLibMapPass : public Pass {
int best = map.logic_cost;
if (!map.logic_ok) {
if (map.cfgs.empty()) {
log_debug("Rejected candidates for mapping memory %s.%s:\n", module->name.unescape(), mem.memid.unescape());
log_debug("Rejected candidates for mapping memory %s.%s:\n", log_id(module), mem.memid.unescape());
log_debug("%s", map.rejected_cfg_debug_msgs);
log_error("no valid mapping found for memory %s.%s\n", module->name.unescape(), mem.memid.unescape());
log_error("no valid mapping found for memory %s.%s\n", log_id(module), mem.memid.unescape());
}
idx = 0;
best = map.cfgs[0].cost;
@ -2266,7 +2266,7 @@ struct MemoryLibMapPass : public Pass {
}
}
if (idx == -1) {
log("using FF mapping for memory %s.%s\n", module->name.unescape(), mem.memid.unescape());
log("using FF mapping for memory %s.%s\n", log_id(module), mem.memid.unescape());
} else {
map.emit(map.cfgs[idx]);
// Rebuild indices after modifying module