diff --git a/frontends/verific/decorate_loops.h b/frontends/verific/decorate_loops.h index fdf199856..204cbcd18 100644 --- a/frontends/verific/decorate_loops.h +++ b/frontends/verific/decorate_loops.h @@ -17,8 +17,6 @@ * */ #ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS -#include - /* This Visitor decorates the AST with a loop ID attribute for all outer for loops. All AST nodes contained within the subtree of an outer for-loop @@ -41,7 +39,7 @@ class DecorateLoopsVisitor : public VeriVisitor // We increase the loop count when we enter a new set of imbricated loops, // That way we have a loop index for the outermost loop as we want to identify and group // logic generated by imbricated loops - outerLoopId++; + outerLoopId = node.Linefile(); } loopStack.push((VeriLoop *)&node); } @@ -58,7 +56,7 @@ class DecorateLoopsVisitor : public VeriVisitor if (loopStack.size()) { if (loopStack.top() == (VeriLoop *)&node) { loopStack.pop(); - std::cout << "Loop out: " << (VeriFor *)&node << std::endl; + // std::cout << "Loop out: " << (VeriFor *)&node << std::endl; return; } Verific::linefile_type linefile = (Verific::linefile_type)node.Linefile(); @@ -73,6 +71,6 @@ class DecorateLoopsVisitor : public VeriVisitor private: std::stack loopStack; - uint32_t outerLoopId = 0; + linefile_type outerLoopId = nullptr; }; #endif diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 22512c67d..945ccc301 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -55,6 +55,7 @@ USING_YOSYS_NAMESPACE #include "VeriLibrary.h" #include "VeriExpression.h" #ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS +#include "VeriStatement.h" #include "VeriConstVal.h" #endif #endif @@ -430,8 +431,8 @@ void VerificImporter::import_attributes(dict &att if (obj->Linefile()) { attributes[ID::src] = stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(obj->Linefile()), obj->Linefile()->GetLeftLine(), obj->Linefile()->GetLeftCol(), obj->Linefile()->GetRightLine(), obj->Linefile()->GetRightCol()); #ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS - if (uint32_t loopid = obj->Linefile()->GetInLoop()) { - attributes[RTLIL::escape_id("in_loop_" + std::to_string(loopid))] = std::to_string(loopid); + if (linefile_type loopid = obj->Linefile()->GetInLoop()) { + attributes[RTLIL::escape_id("in_for_loop")] = stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(loopid), loopid->GetLeftLine(), loopid->GetLeftCol(), loopid->GetRightLine(), loopid->GetRightCol()); } #endif } diff --git a/passes/cmds/longloop_select.cc b/passes/cmds/longloop_select.cc new file mode 100644 index 000000000..b4696543a --- /dev/null +++ b/passes/cmds/longloop_select.cc @@ -0,0 +1,214 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/celltypes.h" +#include "kernel/sigtools.h" +#include "kernel/utils.h" +#include "kernel/yosys.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct LongLoopSelect : public ScriptPass { + LongLoopSelect() + : ScriptPass("longloop_select", "Selects long for-loops (Creating logic above a certain logic depth) for further optimization") + { + } + void script() override {} + + // Adapted from the torder pass + void toposorting(std::vector &cells, SigMap &sigmap, + TopoSort> &toposort, bool debug) + { + if (debug) { + log(" Collecting design data\n"); + log_flush(); + } + dict> bit_drivers, bit_users; + for (Cell *cell : cells) { + for (auto conn : cell->connections()) { + bool noautostop = false; + if (!noautostop && yosys_celltypes.cell_known(cell->type)) { + if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA)) + continue; + if (cell->type.in(ID($memrd), ID($memrd_v2)) && conn.first == ID::DATA) + continue; + } + + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_users[bit].insert(cell); + + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + bit_drivers[bit].insert(cell); + + toposort.node(cell); + } + } + if (debug) { + log(" Creating sorting data structure\n"); + log_flush(); + } + for (auto &it : bit_users) + if (bit_drivers.count(it.first)) + for (auto driver_cell : bit_drivers.at(it.first)) + for (auto user_cell : it.second) + toposort.edge(driver_cell, user_cell); + + toposort.analyze_loops = false; + if (debug) { + log(" Sorting\n"); + log_flush(); + } + toposort.sort(); + } + + void execute(std::vector args, RTLIL::Design *design) override + { + if (design == nullptr) { + log_error("No design object"); + return; + } + uint32_t threshold_depth = 100; + bool debug = false; + size_t argidx; + std::string abc_script; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-depth") { + argidx++; + threshold_depth = std::stoul(args[argidx], nullptr, 10); + } else if (args[argidx] == "-debug") { + debug = true; + } else if (args[argidx] == "-abc") { + argidx++; + abc_script = args[argidx]; + } else { + break; + } + } + extra_args(args, argidx, design); + + if (std::getenv("DEBUG_LONGLOOPS")) { + debug = true; + } + log("Running longloop_select pass\n"); + log_flush(); + for (auto module : design->modules()) { + if (debug) { + log("Module %s\n", log_id(module)); + log_flush(); + } + if (debug) { + log(" Creating sigmap\n"); + log_flush(); + } + SigMap sigmap(module); + std::map> loopIndexCellMap; + if (debug) { + log(" Creating sorting datastructures\n"); + log_flush(); + } + for (auto cell : module->cells()) { + std::string loopIndex = cell->get_string_attribute("\\in_for_loop"); + if (!loopIndex.empty()) { + std::map>::iterator itr = loopIndexCellMap.find(loopIndex); + if (itr == loopIndexCellMap.end()) { + std::vector cellSet; + cellSet.push_back(cell); + loopIndexCellMap.emplace(loopIndex, cellSet); + } else { + itr->second.push_back(cell); + } + } + } + if (!loopIndexCellMap.empty()) { + log(" Found %ld for-loop clusters in module %s\n", loopIndexCellMap.size(), module->name.c_str()); + log_flush(); + } + + for (std::map>::iterator itrCluster = loopIndexCellMap.begin(); + itrCluster != loopIndexCellMap.end(); itrCluster++) { + std::string loopInd = itrCluster->first; + if (itrCluster->second.size() < threshold_depth) { + if (debug) { + log(" Skipping loop id %s as it contains only %ld cells\n", loopInd.c_str(), itrCluster->second.size()); + log_flush(); + } + continue; + } + if (debug) { + log(" Analyzing loop id %s containing %ld cells\n", loopInd.c_str(), itrCluster->second.size()); + log_flush(); + } + // For a given for-loop cell group, perform topological sorting to get the logic depth of the ending cell in + // the group + TopoSort> toposort; + toposorting(itrCluster->second, sigmap, toposort, debug); + std::vector::reverse_iterator itrLastCell = toposort.sorted.rbegin(); + int logicdepth = toposort.node_to_index.find((*itrLastCell))->second; + if (debug) { + log(" Logic depth: %d\n", logicdepth); + log_flush(); + } + if (logicdepth > (int)threshold_depth) { + log(" Selecting %ld cells in for-loop id %s of depth %d ending with cell %s\n", itrCluster->second.size(), + loopInd.c_str(), logicdepth, log_id((*itrLastCell))); + log_flush(); + std::string src_info = (*itrLastCell)->get_src_attribute(); + if (!(*itrLastCell)->get_string_attribute("\\in_for_loop").empty()) { + src_info = (*itrLastCell)->get_string_attribute("\\in_for_loop"); + } + // Select all cells in the loop cluster + if (!abc_script.empty()) { + Pass::call(design, "select -none"); + } + for (auto cell : itrCluster->second) { + design->select(module, cell); + if (cell->get_string_attribute("\\in_for_loop").empty()) { + cell->set_string_attribute("\\in_for_loop", src_info); + } else { + src_info = cell->get_string_attribute("\\in_for_loop"); + } + } + if (!abc_script.empty()) { + if (abc_script.find("map") == std::string::npos) { + abc_script.erase(std::remove(abc_script.begin(), abc_script.end(), '"'), abc_script.end()); + std::string command = "abc -map_src " + src_info + " " + abc_script; + log(" Executing: %s\n", command.c_str()); + log_flush(); + Pass::call(design, command); + } else { + std::string command = "abc -map_src " + src_info+ src_info + " -script " + abc_script; + log(" Executing: %s\n", command.c_str()); + log_flush(); + Pass::call(design, command); + } + } + + } + } + } + + log("End longloop_select pass\n"); + log_flush(); + } +} LongLoopSelect; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index b0b849133..496fa4bc7 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -707,7 +707,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin std::vector &liberty_files, std::vector &genlib_files, std::string constr_file, bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, bool keepff, std::string delay_target, std::string sop_inputs, std::string sop_products, std::string lutin_shared, bool fast_mode, - const std::vector &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector &dont_use_cells) + const std::vector &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector &dont_use_cells, const std::string& map_src) { module = current_module; map_autoidx = autoidx++; @@ -1212,6 +1212,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (c->type == ID(NOT)) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_)); if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; for (auto name : {ID::A, ID::Y}) { RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); cell->setPort(name, module->wire(remapped_name)); @@ -1221,6 +1223,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; for (auto name : {ID::A, ID::B, ID::Y}) { RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); @@ -1231,6 +1235,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } if (c->type.in(ID(MUX), ID(NMUX))) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; for (auto name : {ID::A, ID::B, ID::S, ID::Y}) { RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); @@ -1241,6 +1247,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } if (c->type == ID(MUX4)) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::S, ID::T, ID::Y}) { RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); @@ -1251,6 +1259,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } if (c->type == ID(MUX8)) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::S, ID::T, ID::U, ID::Y}) { RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); @@ -1261,6 +1271,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } if (c->type == ID(MUX16)) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::I, ID::J, ID::K, ID::L, ID::M, ID::N, ID::O, ID::P, ID::S, ID::T, ID::U, ID::V, ID::Y}) { @@ -1272,6 +1284,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } if (c->type.in(ID(AOI3), ID(OAI3))) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; for (auto name : {ID::A, ID::B, ID::C, ID::Y}) { RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); @@ -1282,6 +1296,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } if (c->type.in(ID(AOI4), ID(OAI4))) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::Y}) { RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); @@ -1388,6 +1404,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type); + if (!map_src.empty()) + cell->attributes[ID::src] = map_src; if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; cell->parameters = c->parameters; for (auto &conn : c->connections()) { @@ -1667,7 +1685,7 @@ struct AbcPass : public Pass { bool abc_dress = false; vector lut_costs; markgroups = false; - + std::string map_src; map_mux4 = false; map_mux8 = false; map_mux16 = false; @@ -1775,6 +1793,10 @@ struct AbcPass : public Pass { lut_arg = args[++argidx]; continue; } + if (arg == "-map_src" && argidx+1 < args.size()) { + map_src = args[++argidx]; + continue; + } if (arg == "-luts" && argidx+1 < args.size()) { luts_arg = args[++argidx]; continue; @@ -2053,7 +2075,7 @@ struct AbcPass : public Pass { if (!dff_mode || !clk_str.empty()) { abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, - delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress, dont_use_cells); + delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress, dont_use_cells, map_src); continue; } @@ -2215,7 +2237,7 @@ struct AbcPass : public Pass { srst_polarity = std::get<6>(it.first); srst_sig = assign_map(std::get<7>(it.first)); abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", - keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress, dont_use_cells); + keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress, dont_use_cells, map_src); assign_map.set(mod); } } diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index a6453336a..7c9e87980 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -110,6 +110,8 @@ struct AigmapPass : public Pass { if (nand_mode && node.inverter) { bit = module->addWire(NEW_ID2_SUFFIX("bit")); auto gate = module->addNandGate(NEW_ID2_SUFFIX("nand"), A, B, bit); + for (auto attr : cell->attributes) + gate->attributes[attr.first] = attr.second; if (select_mode) new_sel.insert(gate->name); @@ -121,6 +123,8 @@ struct AigmapPass : public Pass { else { bit = module->addWire(NEW_ID2_SUFFIX("bit")); auto gate = module->addAndGate(NEW_ID2_SUFFIX("and"), A, B, bit); + for (auto attr : cell->attributes) + gate->attributes[attr.first] = attr.second; if (select_mode) new_sel.insert(gate->name); } @@ -130,6 +134,8 @@ struct AigmapPass : public Pass { if (node.inverter) { SigBit new_bit = module->addWire(NEW_ID2_SUFFIX("new_bit")); auto gate = module->addNotGate(NEW_ID2_SUFFIX("inv"), bit, new_bit); + for (auto attr : cell->attributes) + gate->attributes[attr.first] = attr.second; bit = new_bit; if (select_mode) new_sel.insert(gate->name); diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index e4e70004c..f3013fb2a 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -368,8 +368,9 @@ struct AlumaccWorker log(" creating $macc cell for %s: %s\n", log_id(n->cell), log_id(cell)); - cell->set_src_attribute(n->cell->get_src_attribute()); - + for (auto attr: n->cell->attributes) { + cell->attributes[attr.first] = attr.second; + } n->macc.optimize(GetSize(n->y)); n->macc.to_cell(cell); cell->setPort(ID::Y, n->y); @@ -473,6 +474,10 @@ struct AlumaccWorker if (GetSize(n->b) == 0 && GetSize(n->c) == 0 && GetSize(n->cmp) == 0) { n->alu_cell = module->addPos(NEW_ID, n->a, n->y, n->is_signed); + if (n->cells.size() > 0) { + for (auto attr : n->cells[0]->attributes) + n->alu_cell->attributes[attr.first] = attr.second; + } log(" creating $pos cell for "); for (int i = 0; i < GetSize(n->cells); i++) @@ -490,8 +495,10 @@ struct AlumaccWorker log("%s%s", i ? ", ": "", log_id(n->cells[i])); log(": %s\n", log_id(n->alu_cell)); - if (n->cells.size() > 0) - n->alu_cell->set_src_attribute(n->cells[0]->get_src_attribute()); + if (n->cells.size() > 0) { + for (auto attr : n->cells[0]->attributes) + n->alu_cell->attributes[attr.first] = attr.second; + } n->alu_cell->setPort(ID::A, n->a); n->alu_cell->setPort(ID::B, n->b); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index e272b6a4a..cb147aaf0 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -36,7 +36,7 @@ void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_NOT_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::Y, sig_y[i]); } @@ -73,7 +73,7 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID2, gate_type); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::B, sig_b[i]); gate->setPort(ID::Y, sig_y[i]); @@ -124,7 +124,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::Cell *gate = module->addCell(NEW_ID2, gate_type); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::B, sig_a[i+1]); gate->setPort(ID::Y, sig_t[i/2]); @@ -137,7 +137,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == ID($reduce_xnor)) { RTLIL::SigSpec sig_t = module->addWire(NEW_ID2_SUFFIX("sig_t")); // SILIMATE: Improve the naming RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_NOT_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a); gate->setPort(ID::Y, sig_t); last_output_cell = gate; @@ -165,7 +165,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell } RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_OR_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig[i]); gate->setPort(ID::B, sig[i+1]); gate->setPort(ID::Y, sig_t[i/2]); @@ -194,7 +194,7 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_NOT_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a); gate->setPort(ID::Y, sig_y); } @@ -223,7 +223,7 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) log_assert(!gate_type.empty()); RTLIL::Cell *gate = module->addCell(NEW_ID2, gate_type); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a); gate->setPort(ID::B, sig_b); gate->setPort(ID::Y, sig_y); @@ -239,19 +239,19 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec xor_out = module->addWire(NEW_ID2_SUFFIX("xor_out"), max(GetSize(sig_a), GetSize(sig_b))); // SILIMATE: Improve the naming RTLIL::Cell *xor_cell = module->addXor(NEW_ID2, sig_a, sig_b, xor_out, is_signed, cell->get_src_attribute()); // SILIMATE: Improve the naming - xor_cell->attributes[ID::src] = cell->attributes[ID::src]; + xor_cell->attributes = cell->attributes; simplemap_bitop(module, xor_cell); module->remove(xor_cell); RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID2_SUFFIX("reduce_out")); // SILIMATE: Improve the naming RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID2_SUFFIX("reduce_or"), xor_out, reduce_out, false, cell->get_src_attribute()); // SILIMATE: Improve the naming - reduce_cell->attributes[ID::src] = cell->attributes[ID::src]; + reduce_cell->attributes = cell->attributes; simplemap_reduce(module, reduce_cell); module->remove(reduce_cell); if (!is_ne) { RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID2_SUFFIX("not"), reduce_out, sig_y, false, cell->get_src_attribute()); // SILIMATE: Improve the naming - not_cell->attributes[ID::src] = cell->attributes[ID::src]; + not_cell->attributes = cell->attributes; simplemap_lognot(module, not_cell); module->remove(not_cell); } @@ -265,7 +265,7 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_MUX_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::B, sig_b[i]); gate->setPort(ID::S, cell->getPort(ID::S)); @@ -282,7 +282,7 @@ void simplemap_bwmux(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_MUX_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::B, sig_b[i]); gate->setPort(ID::S, sig_s[i]); @@ -298,7 +298,7 @@ void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_TBUF_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::E, sig_e); gate->setPort(ID::Y, sig_y[i]); @@ -316,7 +316,7 @@ void simplemap_bmux(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(new_data); i += width) { for (int k = 0; k < width; k++) { RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_MUX_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, data[i*2+k]); gate->setPort(ID::B, data[i*2+width+k]); gate->setPort(ID::S, sel[idx]); @@ -339,7 +339,7 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell) SigSpec new_lut_data = module->addWire(NEW_ID2_SUFFIX("data"), GetSize(lut_data)/2); // SILIMATE: Improve the naming for (int i = 0; i < GetSize(lut_data); i += 2) { RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_MUX_)); // SILIMATE: Improve the naming - gate->attributes[ID::src] = cell->attributes[ID::src]; + gate->attributes = cell->attributes; gate->setPort(ID::A, lut_data[i]); gate->setPort(ID::B, lut_data[i+1]); gate->setPort(ID::S, lut_ctrl[idx]); @@ -374,11 +374,16 @@ void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell) pat.append(State::S1); } } - - products.append(GetSize(in) > 0 ? module->Eq(NEW_ID2_SUFFIX("eq"), in, pat, false, cell->get_src_attribute()) : State::S1); // SILIMATE: Improve the naming + SigSpec eq_y = module->addWire(NEW_ID2_SUFFIX("eq_out"), max(GetSize(in), GetSize(pat))); // SILIMATE: Improve the naming + Cell* eq = module->addEq(NEW_ID2_SUFFIX("eq"), in, pat, eq_y, false, cell->get_src_attribute()); + eq->attributes = cell->attributes; + products.append(GetSize(in) > 0 ? eq_y : State::S1); // SILIMATE: Improve the naming } - module->connect(cell->getPort(ID::Y), module->ReduceOr(NEW_ID2_SUFFIX("reduce_or"), products, false, cell->get_src_attribute())); // SILIMATE: Improve the naming + SigSpec red_or_y = module->addWire(NEW_ID2_SUFFIX("red_or_out"), GetSize(products)); // SILIMATE: Improve the naming + Cell* red_or = module->addReduceOr(NEW_ID2_SUFFIX("reduce_or"), products, red_or_y, false, cell->get_src_attribute()); + red_or->attributes = cell->attributes; + module->connect(cell->getPort(ID::Y), red_or_y); // SILIMATE: Improve the naming } void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 1ccb58b5d..978f7e31b 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -165,6 +165,11 @@ struct TechmapWorker break; } + for (auto tpl_cell : tpl->cells()) + for (auto attr : cell->attributes) { + tpl_cell->attributes[attr.first] = attr.second; + } + dict memory_renames; for (auto &it : tpl->memories) { @@ -388,6 +393,9 @@ struct TechmapWorker c->attributes[attr.first] = attr.second; c->attributes.erase(ID::reprocess_after); } + for (auto attr : tpl_cell->attributes) { + c->attributes[attr.first] = attr.second; + } } for (auto &it : tpl->connections()) { @@ -527,9 +535,9 @@ struct TechmapWorker { extmapper_module = extmapper_design->addModule(m_name); RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell); - - extmapper_cell->set_src_attribute(cell->get_src_attribute()); - + for (auto attr : cell->attributes) { + extmapper_cell->attributes[attr.first] = attr.second; + } int port_counter = 1; for (auto &c : extmapper_cell->connections_) { RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second));