diff options
Diffstat (limited to 'passes/techmap/abc9.cc')
-rw-r--r-- | passes/techmap/abc9.cc | 141 |
1 files changed, 78 insertions, 63 deletions
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 658bb1225..c1d4fff2d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -71,25 +71,23 @@ RTLIL::Module *module; bool clk_polarity, en_polarity; RTLIL::SigSpec clk_sig, en_sig; -std::string remap_name(RTLIL::IdString abc_name) +inline std::string remap_name(RTLIL::IdString abc_name) { - std::stringstream sstr; - sstr << "$abc$" << map_autoidx << "$" << abc_name.substr(1); - return sstr.str(); + return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1); } void handle_loops(RTLIL::Design *design) { Pass::call(design, "scc -set_attr abc_scc_id {}"); - dict<IdString, vector<IdString>> abc_scc_break; + dict<IdString, vector<IdString>> abc_scc_break; // For every unique SCC found, (arbitrarily) find the first // cell in the component, and select (and mark) all its output // wires pool<RTLIL::Const> ids_seen; for (auto cell : module->cells()) { - auto it = cell->attributes.find("\\abc_scc_id"); + auto it = cell->attributes.find(ID(abc_scc_id)); if (it != cell->attributes.end()) { auto r = ids_seen.insert(it->second); if (r.second) { @@ -109,7 +107,7 @@ void handle_loops(RTLIL::Design *design) log_assert(w->port_input); log_assert(b.offset < GetSize(w)); } - w->set_bool_attribute("\\abc_scc_break"); + w->set_bool_attribute(ID(abc_scc_break)); module->swap_names(b.wire, w); c.second = RTLIL::SigBit(w, b.offset); } @@ -123,7 +121,7 @@ void handle_loops(RTLIL::Design *design) std::vector<IdString> ports; RTLIL::Module* box_module = design->module(cell->type); if (box_module) { - auto ports_csv = box_module->attributes.at("\\abc_scc_break", RTLIL::Const::from_string("")).decode_string(); + auto ports_csv = box_module->attributes.at(ID(abc_scc_break), RTLIL::Const::from_string("")).decode_string(); for (const auto &port_name : split_tokens(ports_csv, ",")) { auto port_id = RTLIL::escape_id(port_name); auto kt = cell->connections_.find(port_id); @@ -142,7 +140,7 @@ void handle_loops(RTLIL::Design *design) Wire *w = b.wire; if (!w) continue; w->port_output = true; - w->set_bool_attribute("\\abc_scc_break"); + w->set_bool_attribute(ID(abc_scc_break)); w = module->wire(stringf("%s.abci", w->name.c_str())); if (!w) { w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); @@ -290,7 +288,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str, bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, bool show_tempdir, std::string box_file, std::string lut_file, - std::string wire_delay) + std::string wire_delay, const dict<int,IdString> &box_lookup) { module = current_module; map_autoidx = autoidx++; @@ -429,10 +427,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Selection& sel = design->selection_stack.back(); sel.select(module); - Pass::call(design, "aigmap"); - handle_loops(design); + Pass::call(design, "aigmap"); + //log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n", // count_gates, GetSize(signal_list), count_input, count_output); @@ -446,14 +444,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (ifs.fail()) log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module("$__abc9__")); + log_assert(!design->module(ID($__abc9__))); { - AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); reader.parse_xaiger(); } ifs.close(); Pass::call(design, stringf("write_verilog -noexpr -norename")); - design->remove(design->module("$__abc9__")); + design->remove(design->module(ID($__abc9__))); #endif design->selection_stack.pop_back(); @@ -462,7 +460,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // the expose operation -- remove them from PO/PI // and re-connecting them back together for (auto wire : module->wires()) { - auto it = wire->attributes.find("\\abc_scc_break"); + auto it = wire->attributes.find(ID(abc_scc_break)); if (it != wire->attributes.end()) { wire->attributes.erase(it); log_assert(wire->port_output); @@ -476,7 +474,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } module->fixup_ports(); - log_header(design, "Executing ABC9.\n"); if (!lut_costs.empty()) { @@ -519,9 +516,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); - log_assert(!design->module("$__abc9__")); - AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); - reader.parse_xaiger(); + log_assert(!design->module(ID($__abc9__))); + + AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); + reader.parse_xaiger(box_lookup); ifs.close(); #if 0 @@ -529,7 +527,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri #endif log_header(design, "Re-integrating ABC9 results.\n"); - RTLIL::Module *mapped_mod = design->module("$__abc9__"); + RTLIL::Module *mapped_mod = design->module(ID($__abc9__)); if (mapped_mod == NULL) log_error("ABC output file does not contain a module `$__abc9__'.\n"); @@ -537,7 +535,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto &it : mapped_mod->wires_) { RTLIL::Wire *w = it.second; RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); - if (markgroups) remap_wire->attributes["\\abcgroup"] = map_autoidx; + if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; if (w->port_output) { RTLIL::Wire *wire = module->wire(w->name); log_assert(wire); @@ -559,14 +557,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri vector<RTLIL::Cell*> boxes; for (const auto &it : module->cells_) { auto cell = it.second; - if (cell->type.in("$_AND_", "$_NOT_")) { + if (cell->type.in(ID($_AND_), ID($_NOT_))) { module->remove(cell); continue; } auto jt = abc_box.find(cell->type); if (jt == abc_box.end()) { RTLIL::Module* box_module = design->module(cell->type); - jt = abc_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count("\\abc_box_id"))).first; + jt = abc_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc_box_id)))).first; } if (jt->second) boxes.emplace_back(cell); @@ -577,23 +575,23 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri dict<RTLIL::Cell*,RTLIL::Cell*> not2drivers; dict<SigBit, std::vector<RTLIL::Cell*>> bit2sinks; - std::map<std::string, int> cell_stats; + std::map<IdString, int> cell_stats; for (auto c : mapped_mod->cells()) { toposort.node(c->name); RTLIL::Cell *cell = nullptr; - if (c->type == "$_NOT_") { - RTLIL::SigBit a_bit = c->getPort("\\A"); - RTLIL::SigBit y_bit = c->getPort("\\Y"); + if (c->type == ID($_NOT_)) { + RTLIL::SigBit a_bit = c->getPort(ID::A); + RTLIL::SigBit y_bit = c->getPort(ID::Y); bit_users[a_bit].insert(c->name); bit_drivers[y_bit].insert(c->name); if (!a_bit.wire) { - c->setPort("\\Y", module->addWire(NEW_ID)); + c->setPort(ID::Y, module->addWire(NEW_ID)); RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); log_assert(wire); - module->connect(RTLIL::SigBit(wire, y_bit.offset), RTLIL::S1); + module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); } else if (!lut_costs.empty() || !lut_file.empty()) { RTLIL::Cell* driver_lut = nullptr; @@ -618,8 +616,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), RTLIL::Const::from_string("01")); - bit2sinks[cell->getPort("\\A")].push_back(cell); - cell_stats["$lut"]++; + bit2sinks[cell->getPort(ID::A)].push_back(cell); + cell_stats[ID($lut)]++; } else not2drivers[c] = driver_lut; @@ -627,18 +625,18 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } else log_abort(); - if (cell && markgroups) cell->attributes["\\abcgroup"] = map_autoidx; + if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; continue; } - cell_stats[RTLIL::unescape_id(c->type)]++; + cell_stats[c->type]++; RTLIL::Cell *existing_cell = nullptr; - if (c->type == "$lut") { - if (GetSize(c->getPort("\\A")) == 1 && c->getParam("\\LUT") == RTLIL::Const::from_string("01")) { - SigSpec my_a = module->wires_.at(remap_name(c->getPort("\\A").as_wire()->name)); - SigSpec my_y = module->wires_.at(remap_name(c->getPort("\\Y").as_wire()->name)); + if (c->type == ID($lut)) { + if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { + SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name)); + SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name)); module->connect(my_y, my_a); - if (markgroups) c->attributes["\\abcgroup"] = map_autoidx; + if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; log_abort(); continue; } @@ -646,11 +644,12 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } else { existing_cell = module->cell(c->name); + log_assert(existing_cell); cell = module->addCell(remap_name(c->name), c->type); module->swap_names(cell, existing_cell); } - if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; + if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; if (existing_cell) { cell->parameters = existing_cell->parameters; cell->attributes = existing_cell->attributes; @@ -740,20 +739,20 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto driver_cell : bit_drivers.at(it.first)) for (auto user_cell : it.second) toposort.edge(driver_cell, user_cell); - bool no_loops = toposort.sort(); + bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); log_assert(no_loops); for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { RTLIL::Cell *not_cell = mapped_mod->cell(*ii); log_assert(not_cell); - if (not_cell->type != "$_NOT_") + if (not_cell->type != ID($_NOT_)) continue; auto it = not2drivers.find(not_cell); if (it == not2drivers.end()) continue; RTLIL::Cell *driver_lut = it->second; - RTLIL::SigBit a_bit = not_cell->getPort("\\A"); - RTLIL::SigBit y_bit = not_cell->getPort("\\Y"); + RTLIL::SigBit a_bit = not_cell->getPort(ID::A); + RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); RTLIL::Const driver_mask; a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); @@ -764,13 +763,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri goto clone_lut; for (auto sink_cell : jt->second) - if (sink_cell->type != "$lut") + if (sink_cell->type != ID($lut)) goto clone_lut; // Push downstream LUTs past inverter for (auto sink_cell : jt->second) { - SigSpec A = sink_cell->getPort("\\A"); - RTLIL::Const mask = sink_cell->getParam("\\LUT"); + SigSpec A = sink_cell->getPort(ID::A); + RTLIL::Const mask = sink_cell->getParam(ID(LUT)); int index = 0; for (; index < GetSize(A); index++) if (A[index] == a_bit) @@ -783,8 +782,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri i += 1 << (index+1); } A[index] = y_bit; - sink_cell->setPort("\\A", A); - sink_cell->setParam("\\LUT", mask); + sink_cell->setPort(ID::A, A); + sink_cell->setParam(ID(LUT), mask); } // Since we have rewritten all sinks (which we know @@ -793,16 +792,16 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // that the original driving LUT will become dangling // and get cleaned away clone_lut: - driver_mask = driver_lut->getParam("\\LUT"); + driver_mask = driver_lut->getParam(ID(LUT)); for (auto &b : driver_mask.bits) { if (b == RTLIL::State::S0) b = RTLIL::State::S1; else if (b == RTLIL::State::S1) b = RTLIL::State::S0; } auto cell = module->addLut(NEW_ID, - driver_lut->getPort("\\A"), + driver_lut->getPort(ID::A), y_bit, driver_mask); - for (auto &bit : cell->connections_.at("\\A")) { + for (auto &bit : cell->connections_.at(ID::A)) { bit.wire = module->wires_.at(remap_name(bit.wire->name)); bit2sinks[bit].push_back(cell); } @@ -1081,9 +1080,24 @@ struct Abc9Pass : public Pass { } extra_args(args, argidx, design); + dict<int,IdString> box_lookup; + for (auto m : design->modules()) { + auto it = m->attributes.find(ID(abc_box_id)); + if (it == m->attributes.end()) + continue; + if (m->name.begins_with("$paramod")) + continue; + auto id = it->second.as_int(); + auto r = box_lookup.insert(std::make_pair(id, m->name)); + if (!r.second) + log_error("Module '%s' has the same abc_box_id = %d value as '%s'.\n", + log_id(m), id, log_id(r.first->second)); + log_assert(r.second); + } + for (auto mod : design->selected_modules()) { - if (mod->attributes.count("\\abc_box_id")) + if (mod->attributes.count(ID(abc_box_id))) continue; if (mod->processes.size() > 0) { @@ -1096,7 +1110,7 @@ struct Abc9Pass : public Pass { if (!dff_mode || !clk_str.empty()) { abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay); + box_file, lut_file, wire_delay, box_lookup); continue; } @@ -1137,16 +1151,16 @@ struct Abc9Pass : public Pass { } } - if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") + if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) { - key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec()); + key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); } else - if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_") + if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) { - bool this_clk_pol = cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_"; - bool this_en_pol = cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_"; - key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E"))); + bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); + bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); + key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); } else continue; @@ -1242,15 +1256,16 @@ struct Abc9Pass : public Pass { en_sig = assign_map(std::get<3>(it.first)); abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay); + box_file, lut_file, wire_delay, box_lookup); assign_map.set(mod); } } - Pass::call(design, "clean"); - assign_map.clear(); + // The "clean" pass also contains a design->check() call + Pass::call(design, "clean"); + log_pop(); } } Abc9Pass; |