mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-24 08:02:32 +00:00
WIP
This commit is contained in:
parent
f592f2f3af
commit
8e522b08c0
206 changed files with 3081 additions and 2782 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue