From 1be8f8023ab5d3685480e9e6e584e2e608458b45 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 20 Jun 2024 23:41:09 +0200 Subject: [PATCH] add morphCell instead of type assignments, test_cell passes for all cells --- frontends/ast/genrtlil.cc | 7 ++-- frontends/liberty/liberty.cc | 8 ++--- frontends/rpc/rpc_frontend.cc | 2 +- kernel/mem.cc | 8 ++--- kernel/rtlil.cc | 27 +++++++++++++++- kernel/rtlil.h | 17 +++++++--- passes/cmds/chformal.cc | 4 +-- passes/cmds/chtype.cc | 4 +-- passes/cmds/design.cc | 2 +- passes/cmds/dft_tag.cc | 2 +- passes/cmds/setattr.cc | 2 +- passes/hierarchy/hierarchy.cc | 2 +- passes/hierarchy/uniquify.cc | 2 +- passes/opt/muxpack.cc | 2 +- passes/opt/opt_demorgan.cc | 4 +-- passes/opt/opt_expr.cc | 43 ++++++++++--------------- passes/opt/opt_lut_ins.cc | 12 +++---- passes/opt/opt_muxtree.cc | 2 +- passes/opt/opt_reduce.cc | 4 +-- passes/pmgen/pmgen.py | 2 ++ passes/proc/proc_dlatch.cc | 4 +-- passes/proc/proc_mux.cc | 2 +- passes/techmap/abc9_ops.cc | 6 ++-- passes/techmap/extract_counter.cc | 2 +- passes/techmap/shregmap.cc | 2 +- passes/techmap/techmap.cc | 20 ++++++------ passes/techmap/tribuf.cc | 4 +-- passes/tests/test_cell.cc | 4 +-- techlibs/coolrunner2/coolrunner2_sop.cc | 16 ++++----- techlibs/greenpak4/greenpak4_dffinv.cc | 4 +-- techlibs/ice40/ice40_opt.cc | 4 +-- techlibs/quicklogic/ql_bram_types.cc | 2 +- techlibs/quicklogic/ql_dsp_io_regs.cc | 2 +- 33 files changed, 129 insertions(+), 99 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3d47bd3c0..a5578d75a 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -2093,9 +2093,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (auto it = children.begin(); it != children.end(); it++) { AstNode *child = *it; if (child->type == AST_CELLTYPE) { - cell->type = child->str; - if (flag_icells && cell->type.begins_with("\\$")) - cell->type = cell->type.substr(1); + auto type = IdString(child->str); + if (flag_icells && type.begins_with("\\$")) + type = type.substr(1); + cell = cell->module->morphCell(type, cell); continue; } if (child->type == AST_PARASET) { diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index cadbcaee6..a228cff0d 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -269,21 +269,21 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) cell->setPort(ID::C, clk_sig); if (clear_sig.size() == 0 && preset_sig.size() == 0) { - cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); + cell = cell->module->morphCell(stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'), cell); } if (clear_sig.size() == 1 && preset_sig.size() == 0) { - cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); + cell = cell->module->morphCell(stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'), cell); cell->setPort(ID::R, clear_sig); } if (clear_sig.size() == 0 && preset_sig.size() == 1) { - cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); + cell = cell->module->morphCell(stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'), cell); cell->setPort(ID::R, preset_sig); } if (clear_sig.size() == 1 && preset_sig.size() == 1) { - cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); + cell = cell->module->morphCell(stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'), cell); cell->setPort(ID::S, preset_sig); cell->setPort(ID::R, clear_sig); } diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index ec3952661..73dad9c81 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -207,7 +207,7 @@ struct RpcModule : RTLIL::Module { for (auto module : derived_design->modules()) for (auto cell : module->cells()) if (name_mangling.count(cell->type.str())) - cell->type = name_mangling[cell->type.str()]; + cell = cell->module->morphCell(name_mangling[cell->type.str()], cell); for (auto module : derived_design->modules_) { std::string mangled_name = name_mangling[module.first.str()]; diff --git a/kernel/mem.cc b/kernel/mem.cc index bd7910f0a..8bfbe7ed4 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -125,7 +125,7 @@ void Mem::emit() { memid = NEW_ID; cell = module->addCell(memid, ID($mem_v2)); } - cell->type = ID($mem_v2); + cell = cell->module->morphCell(ID($mem_v2), cell); cell->attributes = attributes; cell->parameters[ID::MEMID] = Const(memid.str()); cell->parameters[ID::WIDTH] = Const(width); @@ -280,7 +280,7 @@ void Mem::emit() { for (auto &port : rd_ports) { if (!port.cell) port.cell = module->addCell(NEW_ID, ID($memrd_v2)); - port.cell->type = ID($memrd_v2); + port.cell = cell->module->morphCell(ID($memrd_v2), cell); port.cell->attributes = port.attributes; port.cell->parameters[ID::MEMID] = memid.str(); port.cell->parameters[ID::ABITS] = GetSize(port.addr); @@ -305,7 +305,7 @@ void Mem::emit() { for (auto &port : wr_ports) { if (!port.cell) port.cell = module->addCell(NEW_ID, ID($memwr_v2)); - port.cell->type = ID($memwr_v2); + port.cell = cell->module->morphCell(ID($memwr_v2), cell); port.cell->attributes = port.attributes; if (port.cell->parameters.count(ID::PRIORITY)) port.cell->parameters.erase(ID::PRIORITY); @@ -327,7 +327,7 @@ void Mem::emit() { if (!init.cell) init.cell = module->addCell(NEW_ID, v2 ? ID($meminit_v2) : ID($meminit)); else - init.cell->type = v2 ? ID($meminit_v2) : ID($meminit); + init.cell = cell->module->morphCell(v2 ? ID($meminit_v2) : ID($meminit), cell); init.cell->attributes = init.attributes; init.cell->parameters[ID::MEMID] = memid.str(); init.cell->parameters[ID::ABITS] = GetSize(init.addr); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 67dd6a3db..7a7d1d655 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2434,7 +2434,6 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) cell->type = type; if (RTLIL::Cell::is_legacy_type(type)) { cell->legacy = new RTLIL::OldCell; - cell->legacy->name = name; cell->legacy->type = type; cell->legacy->module = this; log_assert(this); @@ -2466,6 +2465,32 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth return cell; } +// Swap cell for a new one with a different type, keeping everything else +// Throws if their types don't allow it +RTLIL::Cell *RTLIL::Module::morphCell(RTLIL::IdString type, RTLIL::Cell *old) +{ + // if (old->is_legacy() && Cell::is_legacy_type(type)) { + // old->type = type; + // return old; + // } + // TODO xtrace + if (yosys_xtrace) { + log("#X# Morphing %s.%s from type %s to %s\n", log_id(this), log_id(old), log_id(old->type), log_id(type)); + log_backtrace("-X- ", yosys_xtrace-1); + } + log_assert(old); + cells_.erase(old->name); + RTLIL::Cell *new_cell = addCell(old->name, type); + new_cell->connections_ = old->connections_.as_dict(); + new_cell->parameters = old->parameters.as_dict(); + new_cell->attributes = old->attributes; + new_cell->name = old->name; + log_assert(refcount_cells_ == 0); + cells_[new_cell->name] = new_cell; + delete old; + return new_cell; +} + RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name, const RTLIL::Memory *other) { RTLIL::Memory *mem = new RTLIL::Memory; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 9ccf12fc1..cc9bed4fa 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1276,6 +1276,8 @@ public: RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other); + RTLIL::Cell *morphCell(RTLIL::IdString type, RTLIL::Cell *old); + RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other); RTLIL::Process *addProcess(RTLIL::IdString name); @@ -1559,6 +1561,7 @@ struct RTLIL::OldCell protected: // use module->addCell() and module->remove() to create or destroy cells + // also see morphCell friend struct RTLIL::Module; friend struct RTLIL::Cell; OldCell(); @@ -1711,8 +1714,10 @@ public: return parent->getMutParam(name); } void operator=(dict from) { - if (parent->is_legacy()) + if (parent->is_legacy()) { parent->legacy->parameters = from; + return; + } if (parent->type == ID($not)) { parent->not_.params_from_dict(from); @@ -1991,7 +1996,7 @@ public: throw std::out_of_range("Cell::getParam()"); } } - void operator=(const FakeConns& from) { + void operator=(const FakeConns& from) { // TODO check warning log_assert(parent->type == from.parent->type); if (parent->is_legacy()) { @@ -2269,8 +2274,10 @@ public: } // TODO check void unsetPort(const RTLIL::IdString& portname) { - if (is_legacy()) + if (is_legacy()) { legacy->unsetPort(portname); + return; + } try { setPort(portname, SigSpec()); } catch (const std::out_of_range& e) {} @@ -2289,8 +2296,10 @@ public: } // TODO check void unsetParam(const RTLIL::IdString& paramname) { - if (is_legacy()) + if (is_legacy()) { legacy->unsetParam(paramname); + return; + } try { setPort(paramname, Const()); } catch (const std::out_of_range& e) {} diff --git a/passes/cmds/chformal.cc b/passes/cmds/chformal.cc index 03187d014..6d61e25fe 100644 --- a/passes/cmds/chformal.cc +++ b/passes/cmds/chformal.cc @@ -46,7 +46,7 @@ static RTLIL::IdString formal_flavor(RTLIL::Cell *cell) static void set_formal_flavor(RTLIL::Cell *cell, RTLIL::IdString flavor) { if (cell->type != ID($check)) { - cell->type = flavor; + cell = cell->module->morphCell(flavor, cell); return; } @@ -423,7 +423,7 @@ struct ChformalPass : public Pass { if (cell->getPort(ID::ARGS).empty()) { module->remove(cell); } else { - cell->type = ID($print); + cell = cell->module->morphCell(ID($print), cell); cell->setPort(ID::EN, combined_en); cell->unsetPort(ID::A); cell->unsetParam(ID(FLAVOR)); diff --git a/passes/cmds/chtype.cc b/passes/cmds/chtype.cc index dc8786dde..7ef64c4c5 100644 --- a/passes/cmds/chtype.cc +++ b/passes/cmds/chtype.cc @@ -70,12 +70,12 @@ struct ChtypePass : public Pass { for (auto cell : module->selected_cells()) { if (map_types.count(cell->type)) { - cell->type = map_types.at(cell->type); + cell = cell->module->morphCell(map_types.at(cell->type), cell); continue; } if (set_type != IdString()) { - cell->type = set_type; + cell = cell->module->morphCell(set_type, cell); continue; } } diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index c4f1bc161..212598381 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -318,7 +318,7 @@ struct DesignPass : public Pass { done[cell->type] = trg_name; } - cell->type = done.at(cell->type); + cell = cell->module->morphCell(done.at(cell->type), cell); } } } diff --git a/passes/cmds/dft_tag.cc b/passes/cmds/dft_tag.cc index 5ea55de44..d4da5dcdc 100644 --- a/passes/cmds/dft_tag.cc +++ b/passes/cmds/dft_tag.cc @@ -109,7 +109,7 @@ struct DftTagWorker { module->remove(cell); } for (auto cell : original_cells) { - cell->type = ID($get_tag); + cell = cell->module->morphCell(ID($get_tag), cell); } if (design_changed) diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index e4e4c3dd6..f5ad8c8e8 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -220,7 +220,7 @@ struct SetparamPass : public Pass { { for (auto cell : module->selected_cells()) { if (!new_cell_type.empty()) - cell->type = new_cell_type; + cell = cell->module->morphCell(new_cell_type, cell); do_setunset(cell->parameters, setunset_list); } } diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index b54d75e84..cdbb16f0d 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -473,7 +473,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str()); int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str()); array_cells[cell] = std::pair(idx, num); - cell->type = cell->type.substr(pos_type + 1); + cell = cell->module->morphCell(cell->type.substr(pos_type + 1), cell); } RTLIL::Module *mod = design->module(cell->type); diff --git a/passes/hierarchy/uniquify.cc b/passes/hierarchy/uniquify.cc index 94f2d9dfd..260c900c1 100644 --- a/passes/hierarchy/uniquify.cc +++ b/passes/hierarchy/uniquify.cc @@ -89,7 +89,7 @@ struct UniquifyPass : public Pass { auto smod = tmod->clone(); smod->name = newname; - cell->type = newname; + cell = cell->module->morphCell(newname, cell); smod->set_bool_attribute(ID::unique); if (smod->attributes.count(ID::hdlname) == 0) smod->attributes[ID::hdlname] = string(log_id(tmod->name)); diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index fd40a2a9c..d7eb145a1 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -269,7 +269,7 @@ struct MuxpackWorker mux_count += cases; pmux_count += 1; - first_cell->type = ID($pmux); + first_cell = first_cell->module->morphCell(ID($pmux), first_cell); SigSpec b_sig = first_cell->getPort(ID::B); SigSpec s_sig = first_cell->getPort(ID::S); diff --git a/passes/opt/opt_demorgan.cc b/passes/opt/opt_demorgan.cc index a33b452db..7a8b400f7 100644 --- a/passes/opt/opt_demorgan.cc +++ b/passes/opt/opt_demorgan.cc @@ -155,9 +155,9 @@ void demorgan_worker( //Change the cell type if(cell->type == ID($reduce_and)) - cell->type = ID($reduce_or); + cell = m->morphCell(ID($reduce_or), cell); else if(cell->type == ID($reduce_or)) - cell->type = ID($reduce_and); + cell = m->morphCell(ID($reduce_and), cell); //don't change XOR //Add an inverter to the output diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 364a0dd92..c7905bef1 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -125,7 +125,6 @@ void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, log_debug("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", cell->type.c_str(), cell->name.c_str(), info.c_str(), module->name.c_str(), log_signal(Y), log_signal(out_val)); - // log_cell(cell); assign_map.add(Y, out_val); module->connect(Y, out_val); module->remove(cell); @@ -341,7 +340,7 @@ void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, IdStrin log_id(port), log_id(cell->type), log_id(cell), log_id(cell->module), log_signal(sig), log_signal(invert_map.at(sig))); cell->setPort(port, (invert_map.at(sig))); - cell->type = cell->type == type1 ? type2 : type1; + cell = cell->module->morphCell(cell->type == type1 ? type2 : type1, cell); } } } @@ -408,8 +407,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (auto cell : module->cells()) if (design->selected(module, cell) && cell->type[0] == '$') { - log("%s\n", cell->name.c_str()); - log_cell(cell, "inner "); if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1) invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A)); @@ -642,7 +639,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover("opt.opt_expr.reduce_xnor_not"); log_debug("Replacing %s cell `%s' in module `%s' with $not cell.\n", log_id(cell->type), log_id(cell->name), log_id(module)); - cell->type = ID($not); + cell = cell->module->morphCell(ID($not), cell); did_something = true; } else { cover("opt.opt_expr.unary_buffer"); @@ -1169,7 +1166,7 @@ skip_fine_alu: if (input.match("01 ")) ACTION_DO(ID::Y, input.extract(0, 1)); if (input.match("10 ")) { cover("opt.opt_expr.mux_to_inv"); - cell->type = ID($_NOT_); + cell = cell->module->morphCell(ID($_NOT_), cell); cell->setPort(ID::A, input.extract(0, 1)); cell->unsetPort(ID::B); cell->unsetPort(ID::S); @@ -1273,7 +1270,7 @@ skip_fine_alu: } else { cover_list("opt.opt_expr.eqneq.isnot", "$eq", "$ne", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); - cell->type = ID($not); + cell = cell->module->morphCell(ID($not), cell); cell->parameters.erase(ID::B_WIDTH); cell->parameters.erase(ID::B_SIGNED); cell->unsetPort(ID::B); @@ -1289,7 +1286,7 @@ skip_fine_alu: cover_list("opt.opt_expr.eqneq.cmpzero", "$eq", "$ne", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with %s.\n", log_id(cell->type), log_id(cell), log_id(module), cell->type == ID($eq) ? "$logic_not" : "$reduce_bool"); - cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool); + cell = cell->module->morphCell(cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool), cell); if (assign_map(cell->getPort(ID::A)).is_fully_zero()) { cell->setPort(ID::A, cell->getPort(ID::B)); cell->setParam(ID::A_SIGNED, cell->getParam(ID::B_SIGNED)); @@ -1437,7 +1434,7 @@ skip_fine_alu: cell->setParam(ID::A_SIGNED, cell->getParam(ID::B_SIGNED)); } - cell->type = arith_inverse ? ID($neg) : ID($pos); + cell = cell->module->morphCell(arith_inverse ? ID($neg) : ID($pos), cell); cell->unsetPort(ID::B); cell->parameters.erase(ID::B_WIDTH); cell->parameters.erase(ID::B_SIGNED); @@ -1469,9 +1466,9 @@ skip_identity: cell->parameters[ID::Y_WIDTH] = width; cell->parameters[ID::A_SIGNED] = 0; cell->parameters.erase(ID::WIDTH); - cell->type = ID($not); + cell = cell->module->morphCell(ID($not), cell); } else - cell->type = ID($_NOT_); + cell = cell->module->morphCell(ID($_NOT_), cell); did_something = true; goto next_cell; } @@ -1489,9 +1486,9 @@ skip_identity: cell->parameters[ID::A_SIGNED] = 0; cell->parameters[ID::B_SIGNED] = 0; cell->parameters.erase(ID::WIDTH); - cell->type = ID($and); + cell = cell->module->morphCell(ID($and), cell); } else - cell->type = ID($_AND_); + cell = cell->module->morphCell(ID($_AND_), cell); did_something = true; goto next_cell; } @@ -1509,9 +1506,9 @@ skip_identity: cell->parameters[ID::A_SIGNED] = 0; cell->parameters[ID::B_SIGNED] = 0; cell->parameters.erase(ID::WIDTH); - cell->type = ID($or); + cell = cell->module->morphCell(ID($or), cell); } else - cell->type = ID($_OR_); + cell = cell->module->morphCell(ID($_OR_), cell); did_something = true; goto next_cell; } @@ -1557,10 +1554,10 @@ skip_identity: cell->setPort(ID::B, new_b); cell->setPort(ID::S, new_s); if (new_s.size() > 1) { - cell->type = ID($pmux); + cell = cell->module->morphCell(ID($pmux), cell); cell->parameters[ID::S_WIDTH] = new_s.size(); } else { - cell->type = ID($mux); + cell = cell->module->morphCell(ID($mux), cell); cell->parameters.erase(ID::S_WIDTH); } did_something = true; @@ -1733,7 +1730,7 @@ skip_identity: Const new_b = exp; - cell->type = ID($shl); + cell = cell->module->morphCell(ID($shl), cell); cell->parameters[ID::B_WIDTH] = GetSize(new_b); cell->parameters[ID::B_SIGNED] = false; cell->setPort(ID::B, new_b); @@ -1824,7 +1821,7 @@ skip_identity: Const new_b = exp; - cell->type = ID($sshr); + cell = cell->module->morphCell(ID($sshr), cell); cell->parameters[ID::B_WIDTH] = GetSize(new_b); cell->parameters[ID::B_SIGNED] = false; cell->setPort(ID::B, new_b); @@ -1873,7 +1870,7 @@ skip_identity: if (b_signed || exp == 0) new_b.push_back(State::S0); - cell->type = ID($and); + cell = cell->module->morphCell(ID($and), cell); cell->parameters[ID::B_WIDTH] = GetSize(new_b); cell->setPort(ID::B, new_b); cell->check(); @@ -2307,9 +2304,6 @@ struct OptExprPass : public Pass { CellTypes ct(design); for (auto module : design->selected_modules()) { - for (auto cell : module->cells()) { - log_cell(cell, "start "); - } log("Optimizing module %s.\n", log_id(module)); if (undriven) { @@ -2318,9 +2312,6 @@ struct OptExprPass : public Pass { if (did_something) design->scratchpad_set_bool("opt.did_something", true); } - for (auto cell : module->cells()) { - log_cell(cell, "mid "); - } do { do { diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc index 296fccb5a..e660aa036 100644 --- a/passes/opt/opt_lut_ins.cc +++ b/passes/opt/opt_lut_ins.cc @@ -244,17 +244,17 @@ struct OptLutInsPass : public Pass { else log_assert(GetSize(new_inputs) <= 4); if (GetSize(new_inputs) == 1) - cell->type = ID(LUT1); + cell = cell->module->morphCell(ID(LUT1), cell); else if (GetSize(new_inputs) == 2) - cell->type = ID(LUT2); + cell = cell->module->morphCell(ID(LUT2), cell); else if (GetSize(new_inputs) == 3) - cell->type = ID(LUT3); + cell = cell->module->morphCell(ID(LUT3), cell); else if (GetSize(new_inputs) == 4) - cell->type = ID(LUT4); + cell = cell->module->morphCell(ID(LUT4), cell); else if (GetSize(new_inputs) == 5) - cell->type = ID(LUT5); + cell = cell->module->morphCell(ID(LUT5), cell); else if (GetSize(new_inputs) == 6) - cell->type = ID(LUT6); + cell = cell->module->morphCell(ID(LUT6), cell); else log_assert(0); cell->unsetPort(ID(I0)); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index faf448bc9..64016bd86 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -259,7 +259,7 @@ struct OptMuxtreeWorker mi.cell->setPort(ID::B, new_sig_b); mi.cell->setPort(ID::S, new_sig_s); if (GetSize(new_sig_s) == 1) { - mi.cell->type = ID($mux); + mi.cell = mi.cell->module->morphCell(ID($mux), mi.cell); mi.cell->parameters.erase(ID::S_WIDTH); } else { mi.cell->parameters[ID::S_WIDTH] = RTLIL::Const(GetSize(new_sig_s)); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index e3e77b6e3..fe90c28dc 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -160,7 +160,7 @@ struct OptReduceWorker if (new_sig_s.size() > 1) { cell->parameters[ID::S_WIDTH] = RTLIL::Const(new_sig_s.size()); } else { - cell->type = ID($mux); + cell = cell->module->morphCell(ID($mux), cell); cell->parameters.erase(ID::S_WIDTH); } } @@ -228,7 +228,7 @@ struct OptReduceWorker if (new_sig_s.size() == 1) { - cell->type = ID($mux); + cell = cell->module->morphCell(ID($mux), cell); cell->setPort(ID::A, new_sig_a.extract(0, width)); cell->setPort(ID::B, new_sig_a.extract(width, width)); cell->setPort(ID::S, new_sig_s); diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 6e2fabeeb..4a23cda4a 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -5,6 +5,8 @@ import sys import pprint import getopt +# TODO there's an invalid cell type assignment here that should be turned into morphCell + pp = pprint.PrettyPrinter(indent=4) prefix = None diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc index b9b0414c9..0446a5cec 100644 --- a/passes/proc/proc_dlatch.cc +++ b/passes/proc/proc_dlatch.cc @@ -293,10 +293,10 @@ struct proc_dlatch_db_t cell->setPort(ID::A, sig_any_valid_b); if (GetSize(sig_new_s) == 1) { - cell->type = ID($mux); + cell = cell->module->morphCell(ID($mux), cell); cell->unsetParam(ID::S_WIDTH); } else { - cell->type = ID($pmux); + cell = cell->module->morphCell(ID($pmux), cell); cell->setParam(ID::S_WIDTH, GetSize(sig_new_s)); } diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index c49f35b9b..412f45ea7 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -262,7 +262,7 @@ void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::ve RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode); log_assert(ctrl_sig.size() == 1); - last_mux_cell->type = ID($pmux); + last_mux_cell = last_mux_cell->module->morphCell(ID($pmux), last_mux_cell); RTLIL::SigSpec new_s = last_mux_cell->getPort(ID::S); new_s.append(ctrl_sig); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 7c6474dd6..57476c3aa 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -195,7 +195,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) // If derived_type is present in unmap_design, it means that it was processed previously, but found to be incompatible -- e.g. if // it contained a non-zero initial state. In this case, continue to replace the cell type/parameters so that it has the same properties // as a compatible type, yet will be safely unmapped later - cell->type = derived_type; + cell = cell->module->morphCell(derived_type, cell); cell->parameters.clear(); unused_derived.erase(derived_type); } @@ -255,7 +255,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) } } - cell->type = derived_type; + cell = cell->module->morphCell(derived_type, cell); cell->parameters.clear(); unused_derived.erase(derived_type); } @@ -1344,7 +1344,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) RTLIL::Module* box_module = design->module(existing_cell->type); log_assert(existing_cell->parameters.empty()); log_assert(mapped_cell->type == stringf("$__boxid%d", box_module->attributes.at(ID::abc9_box_id).as_int())); - mapped_cell->type = existing_cell->type; + mapped_cell = mapped_cell->module->morphCell(existing_cell->type, mapped_cell); RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); cell->parameters = existing_cell->parameters; diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc index 08dac523c..24bbbf61f 100644 --- a/passes/techmap/extract_counter.cc +++ b/passes/techmap/extract_counter.cc @@ -628,7 +628,7 @@ void counter_worker( cell->unsetParam(ID::Y_WIDTH); //Change the cell type - cell->type = ID($__COUNT_); + cell = cell->module->morphCell(ID($__COUNT_), cell); //Hook up resets if(extract.has_reset) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index b50c20ad0..492e760af 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -332,7 +332,7 @@ struct ShregmapWorker if (opts.ffe) first_cell->setParam(ID(ENPOL), param_enpol); } - first_cell->type = shreg_cell_type_str; + first_cell = first_cell->module->morphCell(shreg_cell_type_str, first_cell); first_cell->setPort(q_port, last_cell->getPort(q_port)); first_cell->setParam(ID::DEPTH, depth); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index a33187954..139f89bc4 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -331,16 +331,18 @@ struct TechmapWorker else apply_prefix(cell->name, c_name); + auto type = tpl_cell->type; RTLIL::Cell *c = module->addCell(c_name, tpl_cell); design->select(module, c); - if (c->type.begins_with("\\$")) - c->type = c->type.substr(1); - - if (c->type == ID::_TECHMAP_PLACEHOLDER_ && tpl_cell->has_attribute(ID::techmap_chtype)) { - c->type = RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype)); + if (type.begins_with("\\$")) + type = type.substr(1); + + if (type == ID::_TECHMAP_PLACEHOLDER_ && tpl_cell->has_attribute(ID::techmap_chtype)) { + type = RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype)); c->attributes.erase(ID::techmap_chtype); } + c = module->morphCell(type, c); vector autopurge_ports; @@ -508,7 +510,7 @@ struct TechmapWorker if (!extmapper_name.empty()) { - cell->type = cell_type; + cell = cell->module->morphCell(cell_type, cell); if ((extern_mode && !in_recursion) || extmapper_name == "wrap") { @@ -570,7 +572,7 @@ struct TechmapWorker } } - cell->type = extmapper_module->name; + cell = cell->module->morphCell(extmapper_module->name, cell); cell->parameters.clear(); if (!extern_mode || in_recursion) { @@ -937,14 +939,14 @@ struct TechmapWorker for (auto cell : m->cells()) { if (cell->type.begins_with("\\$")) - cell->type = cell->type.substr(1); + cell = cell->module->morphCell(cell->type.substr(1), cell); } module_queue.insert(m); } log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(m_name)); - cell->type = m_name; + cell = cell->module->morphCell(m_name, cell); cell->parameters.clear(); } else diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc index 9f58727e4..d106712f5 100644 --- a/passes/techmap/tribuf.cc +++ b/passes/techmap/tribuf.cc @@ -86,7 +86,7 @@ struct TribufWorker { cell->setPort(en_port, cell->getPort(ID::S)); cell->unsetPort(ID::B); cell->unsetPort(ID::S); - cell->type = tri_type; + cell = cell->module->morphCell(tri_type, cell); tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); module->design->scratchpad_set_bool("tribuf.added_something", true); continue; @@ -96,7 +96,7 @@ struct TribufWorker { cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID::S))); cell->unsetPort(ID::B); cell->unsetPort(ID::S); - cell->type = tri_type; + cell = cell->module->morphCell(tri_type, cell); tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); module->design->scratchpad_set_bool("tribuf.added_something", true); continue; diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 79eb6b6ea..66f75e603 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -973,9 +973,9 @@ struct TestCellPass : public Pass { Frontend::frontend_call(design, NULL, std::string(), "rtlil " + rtlil_file); else create_gold_module(design, cell_type, cell_types.at(cell_type), constmode, muxdiv); - if (!write_prefix.empty()) { + if (!write_prefix.empty()) Pass::call(design, stringf("write_rtlil %s_%s_%05d.il", write_prefix.c_str(), cell_type.c_str()+1, i)); - } else if (edges) { + if (edges) { Pass::call(design, "dump gold"); run_edges_test(design, verbose); } else { diff --git a/techlibs/coolrunner2/coolrunner2_sop.cc b/techlibs/coolrunner2/coolrunner2_sop.cc index 17e0d8432..9ab7c5173 100644 --- a/techlibs/coolrunner2/coolrunner2_sop.cc +++ b/techlibs/coolrunner2/coolrunner2_sop.cc @@ -170,14 +170,14 @@ struct Coolrunner2SopPass : public Pass { if (has_invert) { auto cell = std::get<0>(x); - if (cell->type == ID(FDCP)) cell->type = ID(FDCP_N); - else if (cell->type == ID(FDCP_N)) cell->type = ID(FDCP); - else if (cell->type == ID(FTCP)) cell->type = ID(FTCP_N); - else if (cell->type == ID(FTCP_N)) cell->type = ID(FTCP); - else if (cell->type == ID(FDCPE)) cell->type = ID(FDCPE_N); - else if (cell->type == ID(FDCPE_N)) cell->type = ID(FDCPE); - else if (cell->type == ID(LDCP)) cell->type = ID(LDCP_N); - else if (cell->type == ID(LDCP_N)) cell->type = ID(LDCP); + if (cell->type == ID(FDCP)) cell = cell->module->morphCell(ID(FDCP_N), cell); + else if (cell->type == ID(FDCP_N)) cell = cell->module->morphCell(ID(FDCP), cell); + else if (cell->type == ID(FTCP)) cell = cell->module->morphCell(ID(FTCP_N), cell); + else if (cell->type == ID(FTCP_N)) cell = cell->module->morphCell(ID(FTCP), cell); + else if (cell->type == ID(FDCPE)) cell = cell->module->morphCell(ID(FDCPE_N), cell); + else if (cell->type == ID(FDCPE_N)) cell = cell->module->morphCell(ID(FDCPE), cell); + else if (cell->type == ID(LDCP)) cell = cell->module->morphCell(ID(LDCP_N), cell); + else if (cell->type == ID(LDCP_N)) cell = cell->module->morphCell(ID(LDCP), cell); else log_assert(!"Internal error! Bad cell type!"); } } diff --git a/techlibs/greenpak4/greenpak4_dffinv.cc b/techlibs/greenpak4/greenpak4_dffinv.cc index a77711e01..c779c3f0d 100644 --- a/techlibs/greenpak4/greenpak4_dffinv.cc +++ b/techlibs/greenpak4/greenpak4_dffinv.cc @@ -81,9 +81,9 @@ void invert_gp_dff(Cell *cell, bool invert_input) } if(cell_type_latch) - cell->type = stringf("\\GP_DLATCH%s%s%s", cell_type_s ? "S" : "", cell_type_r ? "R" : "", cell_type_i ? "I" : ""); + cell = cell->module->morphCell(stringf("\\GP_DLATCH%s%s%s", cell_type_s ? "S" : "", cell_type_r ? "R" : "", cell_type_i ? "I" : ""), cell); else - cell->type = stringf("\\GP_DFF%s%s%s", cell_type_s ? "S" : "", cell_type_r ? "R" : "", cell_type_i ? "I" : ""); + cell = cell->module->morphCell(stringf("\\GP_DFF%s%s%s", cell_type_s ? "S" : "", cell_type_r ? "R" : "", cell_type_i ? "I" : ""), cell); log("Merged %s inverter into cell %s.%s: %s -> %s\n", invert_input ? "input" : "output", log_id(cell->module), log_id(cell), cell_type.c_str()+1, log_id(cell->type)); diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index b13d33018..ee5de195b 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -138,7 +138,7 @@ static void run_ice40_opts(Module *module) module->design->scratchpad_set_bool("opt.did_something", true); log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); - cell->type = ID($lut); + cell = cell->module->morphCell(ID($lut), cell); auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3))); cell->setPort(ID::A, { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort(ID(I0))) }); cell->setPort(ID::Y, cell->getPort(ID::O)); @@ -177,7 +177,7 @@ static void run_ice40_opts(Module *module) module->design->scratchpad_set_bool("opt.did_something", true); log("Mapping SB_LUT4 cell %s.%s back to logic.\n", log_id(module), log_id(cell)); - cell->type = ID($lut); + cell = cell->module->morphCell(ID($lut), cell); cell->setParam(ID::WIDTH, 4); cell->setParam(ID::LUT, cell->getParam(ID(LUT_INIT))); cell->unsetParam(ID(LUT_INIT)); diff --git a/techlibs/quicklogic/ql_bram_types.cc b/techlibs/quicklogic/ql_bram_types.cc index cf42703aa..393c668a5 100644 --- a/techlibs/quicklogic/ql_bram_types.cc +++ b/techlibs/quicklogic/ql_bram_types.cc @@ -154,7 +154,7 @@ struct QlBramTypesPass : public Pass { type += "nonsplit"; } - cell->type = RTLIL::escape_id(type); + cell = cell->module->morphCell(RTLIL::escape_id(type), cell); log_debug("Changed type of memory cell %s to %s\n", log_id(cell->name), log_id(cell->type)); } } diff --git a/techlibs/quicklogic/ql_dsp_io_regs.cc b/techlibs/quicklogic/ql_dsp_io_regs.cc index ecf163dbf..986c59aea 100644 --- a/techlibs/quicklogic/ql_dsp_io_regs.cc +++ b/techlibs/quicklogic/ql_dsp_io_regs.cc @@ -127,7 +127,7 @@ struct QlDspIORegs : public Pass { } // Set new type name - cell->type = RTLIL::IdString(new_type); + cell = cell->module->morphCell(RTLIL::IdString(new_type), cell); std::vector ports2del;