diff options
Diffstat (limited to 'passes')
-rw-r--r-- | passes/cmds/add.cc | 2 | ||||
-rw-r--r-- | passes/cmds/bugpoint.cc | 8 | ||||
-rw-r--r-- | passes/cmds/setattr.cc | 39 | ||||
-rw-r--r-- | passes/cmds/show.cc | 27 | ||||
-rw-r--r-- | passes/equiv/equiv_opt.cc | 2 | ||||
-rw-r--r-- | passes/hierarchy/hierarchy.cc | 10 | ||||
-rw-r--r-- | passes/hierarchy/uniquify.cc | 2 | ||||
-rw-r--r-- | passes/memory/memory_bram.cc | 3 | ||||
-rw-r--r-- | passes/pmgen/README.md | 6 | ||||
-rw-r--r-- | passes/proc/proc_mux.cc | 78 | ||||
-rw-r--r-- | passes/proc/proc_rmdead.cc | 18 | ||||
-rw-r--r-- | passes/sat/miter.cc | 8 | ||||
-rw-r--r-- | passes/sat/mutate.cc | 32 | ||||
-rw-r--r-- | passes/techmap/abc.cc | 56 | ||||
-rw-r--r-- | passes/techmap/dfflibmap.cc | 2 | ||||
-rw-r--r-- | passes/techmap/pmuxtree.cc | 4 | ||||
-rw-r--r-- | passes/techmap/simplemap.cc | 2 | ||||
-rw-r--r-- | passes/techmap/techmap.cc | 33 |
18 files changed, 237 insertions, 95 deletions
diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index cfccca966..af6f7043d 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -71,7 +71,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n RTLIL::Module *mod = design->modules_.at(it.second->type); if (!design->selected_whole_module(mod->name)) continue; - if (mod->get_bool_attribute("\\blackbox")) + if (mod->get_blackbox_attribute()) continue; if (it.second->hasPort(name)) continue; diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 606276e64..4b22f6d2d 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -128,7 +128,7 @@ struct BugpointPass : public Pass { { for (auto &it : design_copy->modules_) { - if (it.second->get_bool_attribute("\\blackbox")) + if (it.second->get_blackbox_attribute()) continue; if (index++ == seed) @@ -143,7 +143,7 @@ struct BugpointPass : public Pass { { for (auto mod : design_copy->modules()) { - if (mod->get_bool_attribute("\\blackbox")) + if (mod->get_blackbox_attribute()) continue; for (auto wire : mod->wires()) @@ -168,7 +168,7 @@ struct BugpointPass : public Pass { { for (auto mod : design_copy->modules()) { - if (mod->get_bool_attribute("\\blackbox")) + if (mod->get_blackbox_attribute()) continue; for (auto &it : mod->cells_) @@ -186,7 +186,7 @@ struct BugpointPass : public Pass { { for (auto mod : design_copy->modules()) { - if (mod->get_bool_attribute("\\blackbox")) + if (mod->get_blackbox_attribute()) continue; for (auto cell : mod->cells()) diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index d38a6b3da..b9fcc3e7a 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -128,6 +128,45 @@ struct SetattrPass : public Pass { } } SetattrPass; +struct WbflipPass : public Pass { + WbflipPass() : Pass("wbflip", "flip the whitebox attribute") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" wbflip [selection]\n"); + log("\n"); + log("Flip the whitebox attribute on selected cells. I.e. if it's set, unset it, and\n"); + log("vice-versa. Blackbox cells are not effected by this command.\n"); + log("\n"); + } + void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + { + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + std::string arg = args[argidx]; + // if (arg == "-mod") { + // flag_mod = true; + // continue; + // } + break; + } + extra_args(args, argidx, design); + + for (Module *module : design->modules()) + { + if (!design->selected(module)) + continue; + + if (module->get_bool_attribute("\\blackbox")) + continue; + + module->set_bool_attribute("\\whitebox", !module->get_bool_attribute("\\whitebox")); + } + } +} WbflipPass; + struct SetparamPass : public Pass { SetparamPass() : Pass("setparam", "set/unset parameters on objects") { } void help() YS_OVERRIDE diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 58acd302d..cf729215f 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -237,15 +237,34 @@ struct ShowWorker int idx = single_idx_count++; for (int rep, i = int(sig.chunks().size())-1; i >= 0; i -= rep) { const RTLIL::SigChunk &c = sig.chunks().at(i); - net = gen_signode_simple(c, false); - log_assert(!net.empty()); + if (!driver && c.wire == nullptr) { + RTLIL::State s1 = c.data.front(); + for (auto s2 : c.data) + if (s1 != s2) + goto not_const_stream; + net.clear(); + } else { + not_const_stream: + net = gen_signode_simple(c, false); + log_assert(!net.empty()); + } for (rep = 1; i-rep >= 0 && c == sig.chunks().at(i-rep); rep++) {} std::string repinfo = rep > 1 ? stringf("%dx ", rep) : ""; if (driver) { + log_assert(!net.empty()); label_string += stringf("<s%d> %d:%d - %s%d:%d |", i, pos, pos-c.width+1, repinfo.c_str(), c.offset+c.width-1, c.offset); net_conn_map[net].in.insert(stringf("x%d:s%d", idx, i)); net_conn_map[net].bits = rep*c.width; net_conn_map[net].color = nextColor(c, net_conn_map[net].color); + } else + if (net.empty()) { + log_assert(rep == 1); + label_string += stringf("%c -> %d:%d |", + c.data.front() == State::S0 ? '0' : + c.data.front() == State::S1 ? '1' : + c.data.front() == State::Sx ? 'X' : + c.data.front() == State::Sz ? 'Z' : '?', + pos, pos-rep*c.width+1); } else { label_string += stringf("<s%d> %s%d:%d - %d:%d |", i, repinfo.c_str(), c.offset+c.width-1, c.offset, pos, pos-rep*c.width+1); net_conn_map[net].out.insert(stringf("x%d:s%d", idx, i)); @@ -555,7 +574,7 @@ struct ShowWorker if (!design->selected_module(module->name)) continue; if (design->selected_whole_module(module->name)) { - if (module->get_bool_attribute("\\blackbox")) { + if (module->get_blackbox_attribute()) { // log("Skipping blackbox module %s.\n", id2cstr(module->name)); continue; } else @@ -771,7 +790,7 @@ struct ShowPass : public Pass { if (format != "ps" && format != "dot") { int modcount = 0; for (auto &mod_it : design->modules_) { - if (mod_it.second->get_bool_attribute("\\blackbox")) + if (mod_it.second->get_blackbox_attribute()) continue; if (mod_it.second->cells_.empty() && mod_it.second->connections().empty()) continue; diff --git a/passes/equiv/equiv_opt.cc b/passes/equiv/equiv_opt.cc index 86550a69b..e5dda9c24 100644 --- a/passes/equiv/equiv_opt.cc +++ b/passes/equiv/equiv_opt.cc @@ -134,7 +134,7 @@ struct EquivOptPass:public ScriptPass opts = " -map <filename> ..."; else opts = techmap_opts; - run("techmap -D EQUIV -autoproc" + opts); + run("techmap -wb -D EQUIV -autoproc" + opts); } if (check_label("prove")) { diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 88c339e8c..b8ff99884 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -346,9 +346,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } RTLIL::Module *mod = design->modules_[cell->type]; - if (design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) { + if (design->modules_.at(cell->type)->get_blackbox_attribute()) { if (flag_simcheck) - log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox module.\n", + log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n", cell->type.c_str(), module->name.c_str(), cell->name.c_str()); continue; } @@ -451,7 +451,7 @@ void hierarchy_worker(RTLIL::Design *design, std::set<RTLIL::Module*, IdString:: if (indent == 0) log("Top module: %s\n", mod->name.c_str()); - else if (!mod->get_bool_attribute("\\blackbox")) + else if (!mod->get_blackbox_attribute()) log("Used module: %*s%s\n", indent, "", mod->name.c_str()); used.insert(mod); @@ -491,7 +491,7 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib) int del_counter = 0; for (auto mod : del_modules) { - if (!purge_lib && mod->get_bool_attribute("\\blackbox")) + if (!purge_lib && mod->get_blackbox_attribute()) continue; log("Removing unused module `%s'.\n", mod->name.c_str()); design->modules_.erase(mod->name); @@ -910,7 +910,7 @@ struct HierarchyPass : public Pass { if (m == nullptr) continue; - if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) { + if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) { IdString new_m_name = m->derive(design, cell->parameters, true); if (new_m_name.empty()) continue; diff --git a/passes/hierarchy/uniquify.cc b/passes/hierarchy/uniquify.cc index e6154e94f..ad3220918 100644 --- a/passes/hierarchy/uniquify.cc +++ b/passes/hierarchy/uniquify.cc @@ -75,7 +75,7 @@ struct UniquifyPass : public Pass { if (tmod == nullptr) continue; - if (tmod->get_bool_attribute("\\blackbox")) + if (tmod->get_blackbox_attribute()) continue; if (tmod->get_bool_attribute("\\unique") && newname == tmod->name) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 804aa21f9..ddc56d9b5 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -744,7 +744,8 @@ grow_read_ports:; if (clken) { clock_domains[pi.clocks] = clkdom; clock_polarities[pi.clkpol] = clkdom.second; - read_transp[pi.transp] = transp; + if (!pi.make_transp) + read_transp[pi.transp] = transp; pi.sig_clock = clkdom.first; pi.sig_en = rd_en[cell_port_i]; pi.effective_clkpol = clkdom.second; diff --git a/passes/pmgen/README.md b/passes/pmgen/README.md index 223b43059..7a46558b1 100644 --- a/passes/pmgen/README.md +++ b/passes/pmgen/README.md @@ -83,8 +83,8 @@ They are declared like state variables, just using the `udata` statement: udata <int> min_data_width max_data_width udata <IdString> data_port_name -They are atomatically initialzed to the default constructed value of their type -when ther pattern matcher object is constructed. +They are automatically initialized to the default constructed value of their type +when the pattern matcher object is constructed. Embedded C++ code ----------------- @@ -158,7 +158,7 @@ Finally, `filter <expression>` narrows down the remaining list of cells. For performance reasons `filter` statements should only be used for things that can't be done using `select` and `index`. -The `optional` statement marks optional matches. I.e. the matcher will also +The `optional` statement marks optional matches. That is, the matcher will also explore the case where `mul` is set to `nullptr`. Without the `optional` statement a match may only be assigned nullptr when one of the `if` expressions evaluates to `false`. diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index bac2dc2cd..aac0b121c 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -108,6 +108,7 @@ struct SigSnippets struct SnippetSwCache { + dict<RTLIL::SwitchRule*, pool<RTLIL::SigBit>, hash_ptr_ops> full_case_bits_cache; dict<RTLIL::SwitchRule*, pool<int>, hash_ptr_ops> cache; const SigSnippets *snippets; int current_snippet; @@ -268,6 +269,49 @@ void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::ve last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->getPort("\\S").size(); } +const pool<SigBit> &get_full_case_bits(SnippetSwCache &swcache, RTLIL::SwitchRule *sw) +{ + if (!swcache.full_case_bits_cache.count(sw)) + { + pool<SigBit> bits; + + if (sw->get_bool_attribute("\\full_case")) + { + bool first_case = true; + + for (auto cs : sw->cases) + { + pool<SigBit> case_bits; + + for (auto it : cs->actions) { + for (auto bit : it.first) + case_bits.insert(bit); + } + + for (auto it : cs->switches) { + for (auto bit : get_full_case_bits(swcache, it)) + case_bits.insert(bit); + } + + if (first_case) { + first_case = false; + bits = case_bits; + } else { + pool<SigBit> new_bits; + for (auto bit : bits) + if (case_bits.count(bit)) + new_bits.insert(bit); + bits.swap(new_bits); + } + } + } + + bits.swap(swcache.full_case_bits_cache[sw]); + } + + return swcache.full_case_bits_cache.at(sw); +} + RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, dict<RTLIL::SwitchRule*, bool, hash_ptr_ops> &swpara, RTLIL::CaseRule *cs, const RTLIL::SigSpec &sig, const RTLIL::SigSpec &defval, bool ifxmode) { @@ -337,10 +381,15 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d } } + // mask default bits that are irrelevant because the output is driven by a full case + const pool<SigBit> &full_case_bits = get_full_case_bits(swcache, sw); + for (int i = 0; i < GetSize(sig); i++) + if (full_case_bits.count(sig[i])) + result[i] = State::Sx; + // evaluate in reverse order to give the first entry the top priority RTLIL::SigSpec initial_val = result; RTLIL::Cell *last_mux_cell = NULL; - bool shiftx = initial_val.is_fully_undef(); for (size_t i = 0; i < sw->cases.size(); i++) { int case_idx = sw->cases.size() - i - 1; RTLIL::CaseRule *cs2 = sw->cases[case_idx]; @@ -349,33 +398,6 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d append_pmux(mod, sw->signal, cs2->compare, value, last_mux_cell, sw, ifxmode); else result = gen_mux(mod, sw->signal, cs2->compare, value, result, last_mux_cell, sw, ifxmode); - - // Ignore output values which are entirely don't care - if (shiftx && !value.is_fully_undef()) { - // Keep checking if case condition is the same as the current case index - if (cs2->compare.size() == 1 && cs2->compare.front().is_fully_const()) - shiftx = (cs2->compare.front().as_int() == case_idx); - else - shiftx = false; - } - } - - // Transform into a $shiftx where possible - if (shiftx && last_mux_cell && last_mux_cell->type == "$pmux") { - // Create bit-blasted $shiftx-es that shifts by the address line used in the case statement - auto pmux_b_port = last_mux_cell->getPort("\\B"); - auto pmux_y_port = last_mux_cell->getPort("\\Y"); - int width = last_mux_cell->getParam("\\WIDTH").as_int(); - for (int i = 0; i < width; ++i) { - RTLIL::SigSpec a_port; - // Because we went in reverse order above, un-reverse $pmux's B port here - for (int j = pmux_b_port.size()/width-1; j >= 0; --j) - a_port.append(pmux_b_port.extract(j*width+i, 1)); - // Create a $shiftx that shifts by the address line used in the case statement - mod->addShiftx(NEW_ID, a_port, sw->signal, pmux_y_port.extract(i, 1)); - } - // Disconnect $pmux by replacing its output port with a floating wire - last_mux_cell->setPort("\\Y", mod->addWire(NEW_ID, width)); } } diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index 7c334e661..4f40be446 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -28,7 +28,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -void proc_rmdead(RTLIL::SwitchRule *sw, int &counter) +void proc_rmdead(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter) { BitPatternPool pool(sw->signal); @@ -56,11 +56,16 @@ void proc_rmdead(RTLIL::SwitchRule *sw, int &counter) } for (auto switch_it : sw->cases[i]->switches) - proc_rmdead(switch_it, counter); + proc_rmdead(switch_it, counter, full_case_counter); if (is_default) pool.take_all(); } + + if (pool.empty() && !sw->get_bool_attribute("\\full_case")) { + sw->set_bool_attribute("\\full_case"); + full_case_counter++; + } } struct ProcRmdeadPass : public Pass { @@ -87,12 +92,15 @@ struct ProcRmdeadPass : public Pass { for (auto &proc_it : mod->processes) { if (!design->selected(mod, proc_it.second)) continue; - int counter = 0; + int counter = 0, full_case_counter = 0; for (auto switch_it : proc_it.second->root_case.switches) - proc_rmdead(switch_it, counter); + proc_rmdead(switch_it, counter, full_case_counter); if (counter > 0) log("Removed %d dead cases from process %s in module %s.\n", counter, - proc_it.first.c_str(), log_id(mod)); + log_id(proc_it.first), log_id(mod)); + if (full_case_counter > 0) + log("Marked %d switch rules as full_case in process %s in module %s.\n", + full_case_counter, log_id(proc_it.first), log_id(mod)); total_counter += counter; } } diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index d37f1b126..1a886af70 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -254,7 +254,7 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: if (flag_flatten) { log_push(); - Pass::call_on_module(design, miter_module, "flatten; opt_expr -keepdc -undriven;;"); + Pass::call_on_module(design, miter_module, "flatten -wb; opt_expr -keepdc -undriven;;"); log_pop(); } } @@ -308,7 +308,7 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL if (flag_flatten) { log_push(); - Pass::call_on_module(design, module, "flatten;;"); + Pass::call_on_module(design, module, "flatten -wb;;"); log_pop(); } @@ -385,7 +385,7 @@ struct MiterPass : public Pass { log(" also create an 'assert' cell that checks if trigger is always low.\n"); log("\n"); log(" -flatten\n"); - log(" call 'flatten; opt_expr -keepdc -undriven;;' on the miter circuit.\n"); + log(" call 'flatten -wb; opt_expr -keepdc -undriven;;' on the miter circuit.\n"); log("\n"); log("\n"); log(" miter -assert [options] module [miter_name]\n"); @@ -399,7 +399,7 @@ struct MiterPass : public Pass { log(" keep module output ports.\n"); log("\n"); log(" -flatten\n"); - log(" call 'flatten; opt_expr -keepdc -undriven;;' on the miter circuit.\n"); + log(" call 'flatten -wb; opt_expr -keepdc -undriven;;' on the miter circuit.\n"); log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE diff --git a/passes/sat/mutate.cc b/passes/sat/mutate.cc index c50678c51..b53bbfeb2 100644 --- a/passes/sat/mutate.cc +++ b/passes/sat/mutate.cc @@ -934,6 +934,32 @@ struct MutatePass : public Pass { return; } + if (opts.module.empty()) + log_cmd_error("Missing -module argument.\n"); + + Module *module = design->module(opts.module); + if (module == nullptr) + log_cmd_error("Module %s not found.\n", log_id(opts.module)); + + if (opts.cell.empty()) + log_cmd_error("Missing -cell argument.\n"); + + Cell *cell = module->cell(opts.cell); + if (cell == nullptr) + log_cmd_error("Cell %s not found in module %s.\n", log_id(opts.cell), log_id(opts.module)); + + if (opts.port.empty()) + log_cmd_error("Missing -port argument.\n"); + + if (!cell->hasPort(opts.port)) + log_cmd_error("Port %s not found on cell %s.%s.\n", log_id(opts.port), log_id(opts.module), log_id(opts.cell)); + + if (opts.portbit < 0) + log_cmd_error("Missing -portbit argument.\n"); + + if (GetSize(cell->getPort(opts.port)) <= opts.portbit) + log_cmd_error("Out-of-range -portbit argument for port %s on cell %s.%s.\n", log_id(opts.port), log_id(opts.module), log_id(opts.cell)); + if (opts.mode == "inv") { mutate_inv(design, opts); return; @@ -944,6 +970,12 @@ struct MutatePass : public Pass { return; } + if (opts.ctrlbit < 0) + log_cmd_error("Missing -ctrlbit argument.\n"); + + if (GetSize(cell->getPort(opts.port)) <= opts.ctrlbit) + log_cmd_error("Out-of-range -ctrlbit argument for port %s on cell %s.%s.\n", log_id(opts.port), log_id(opts.module), log_id(opts.cell)); + if (opts.mode == "cnot0" || opts.mode == "cnot1") { mutate_cnot(design, opts, opts.mode == "cnot1"); return; diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 21b70f492..547115459 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -29,17 +29,17 @@ // Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558-562, doi:10.1145/368996.369025 // http://en.wikipedia.org/wiki/Topological_sorting -#define ABC_COMMAND_LIB "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put" -#define ABC_COMMAND_CTR "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put; buffer; upsize {D}; dnsize {D}; stime -p" -#define ABC_COMMAND_LUT "strash; ifraig; scorr; dc2; dretime; strash; dch -f; if; mfs2" -#define ABC_COMMAND_SOP "strash; ifraig; scorr; dc2; dretime; strash; dch -f; cover {I} {P}" -#define ABC_COMMAND_DFL "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put" - -#define ABC_FAST_COMMAND_LIB "strash; dretime; map {D}" -#define ABC_FAST_COMMAND_CTR "strash; dretime; map {D}; buffer; upsize {D}; dnsize {D}; stime -p" -#define ABC_FAST_COMMAND_LUT "strash; dretime; if" -#define ABC_FAST_COMMAND_SOP "strash; dretime; cover -I {I} -P {P}" -#define ABC_FAST_COMMAND_DFL "strash; dretime; map" +#define ABC_COMMAND_LIB "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put" +#define ABC_COMMAND_CTR "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put; buffer; upsize {D}; dnsize {D}; stime -p" +#define ABC_COMMAND_LUT "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; dch -f; if; mfs2" +#define ABC_COMMAND_SOP "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; dch -f; cover {I} {P}" +#define ABC_COMMAND_DFL "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put" + +#define ABC_FAST_COMMAND_LIB "strash; dretime; retime {D}; map {D}" +#define ABC_FAST_COMMAND_CTR "strash; dretime; retime {D}; map {D}; buffer; upsize {D}; dnsize {D}; stime -p" +#define ABC_FAST_COMMAND_LUT "strash; dretime; retime {D}; if" +#define ABC_FAST_COMMAND_SOP "strash; dretime; retime {D}; cover -I {I} -P {P}" +#define ABC_FAST_COMMAND_DFL "strash; dretime; retime {D}; map" #include "kernel/register.h" #include "kernel/sigtools.h" @@ -331,19 +331,23 @@ std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullp { std::string abc_sname = abc_name.substr(1); if (abc_sname.substr(0, 5) == "ys__n") { - int sid = std::stoi(abc_sname.substr(5)); bool inv = abc_sname.back() == 'v'; - for (auto sig : signal_list) { - if (sig.id == sid && sig.bit.wire != nullptr) { - std::stringstream sstr; - sstr << "$abc$" << map_autoidx << "$" << sig.bit.wire->name.substr(1); - if (sig.bit.wire->width != 1) - sstr << "[" << sig.bit.offset << "]"; - if (inv) - sstr << "_inv"; - if (orig_wire != nullptr) - *orig_wire = sig.bit.wire; - return sstr.str(); + if (inv) abc_sname.pop_back(); + abc_sname.erase(0, 5); + if (abc_sname.find_last_not_of("012345689") == std::string::npos) { + int sid = std::stoi(abc_sname); + for (auto sig : signal_list) { + if (sig.id == sid && sig.bit.wire != nullptr) { + std::stringstream sstr; + sstr << "$abc$" << map_autoidx << "$" << sig.bit.wire->name.substr(1); + if (sig.bit.wire->width != 1) + sstr << "[" << sig.bit.offset << "]"; + if (inv) + sstr << "_inv"; + if (orig_wire != nullptr) + *orig_wire = sig.bit.wire; + return sstr.str(); + } } } } @@ -731,10 +735,6 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin else abc_script += fast_mode ? ABC_FAST_COMMAND_DFL : ABC_COMMAND_DFL; - if (script_file.empty() && !delay_target.empty()) - for (size_t pos = abc_script.find("dretime;"); pos != std::string::npos; pos = abc_script.find("dretime;", pos+1)) - abc_script = abc_script.substr(0, pos) + "dretime; retime -o {D};" + abc_script.substr(pos+8); - for (size_t pos = abc_script.find("{D}"); pos != std::string::npos; pos = abc_script.find("{D}", pos)) abc_script = abc_script.substr(0, pos) + delay_target + abc_script.substr(pos+3); @@ -1726,7 +1726,7 @@ struct AbcPass : public Pass { signal_init[initsig[i]] = State::S0; break; case State::S1: - signal_init[initsig[i]] = State::S0; + signal_init[initsig[i]] = State::S1; break; default: break; diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 274177a68..b5c0498d0 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -664,7 +664,7 @@ struct DfflibmapPass : public Pass { logmap_all(); for (auto &it : design->modules_) - if (design->selected(it.second) && !it.second->get_bool_attribute("\\blackbox")) + if (design->selected(it.second) && !it.second->get_blackbox_attribute()) dfflibmap(design, it.second, prepare_mode); cell_mappings.clear(); diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc index b7a22dc3b..6a923f481 100644 --- a/passes/techmap/pmuxtree.cc +++ b/passes/techmap/pmuxtree.cc @@ -71,9 +71,9 @@ struct PmuxtreePass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" pmuxtree [options] [selection]\n"); + log(" pmuxtree [selection]\n"); log("\n"); - log("This pass transforms $pmux cells to a trees of $mux cells.\n"); + log("This pass transforms $pmux cells to trees of $mux cells.\n"); log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 660b60601..f3da80c66 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -599,7 +599,7 @@ struct SimplemapPass : public Pass { simplemap_get_mappers(mappers); for (auto mod : design->modules()) { - if (!design->selected(mod)) + if (!design->selected(mod) || mod->get_blackbox_attribute()) continue; std::vector<RTLIL::Cell*> cells = mod->cells(); for (auto cell : cells) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index d0e5e2236..ee319b6e6 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -84,6 +84,7 @@ struct TechmapWorker bool flatten_mode; bool recursive_mode; bool autoproc_mode; + bool ignore_wb; TechmapWorker() { @@ -92,6 +93,7 @@ struct TechmapWorker flatten_mode = false; recursive_mode = false; autoproc_mode = false; + ignore_wb = false; } std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose) @@ -383,7 +385,7 @@ struct TechmapWorker { std::string mapmsg_prefix = in_recursion ? "Recursively mapping" : "Mapping"; - if (!design->selected(module)) + if (!design->selected(module) || module->get_blackbox_attribute(ignore_wb)) return false; bool log_continue = false; @@ -472,7 +474,7 @@ struct TechmapWorker RTLIL::Module *tpl = map->modules_[tpl_name]; std::map<RTLIL::IdString, RTLIL::Const> parameters(cell->parameters.begin(), cell->parameters.end()); - if (tpl->get_bool_attribute("\\blackbox")) + if (tpl->get_blackbox_attribute(ignore_wb)) continue; if (!flatten_mode) @@ -925,6 +927,9 @@ struct TechmapPass : public Pass { log(" -autoproc\n"); log(" Automatically call \"proc\" on implementations that contain processes.\n"); log("\n"); + log(" -wb\n"); + log(" Ignore the 'whitebox' attribute on cell implementations.\n"); + log("\n"); log(" -assert\n"); log(" this option will cause techmap to exit with an error if it can't map\n"); log(" a selected cell. only cell types that end on an underscore are accepted\n"); @@ -1068,6 +1073,10 @@ struct TechmapPass : public Pass { worker.autoproc_mode = true; continue; } + if (args[argidx] == "-wb") { + worker.ignore_wb = true; + continue; + } break; } extra_args(args, argidx, design); @@ -1145,7 +1154,7 @@ struct FlattenPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" flatten [selection]\n"); + log(" flatten [options] [selection]\n"); log("\n"); log("This pass flattens the design by replacing cells by their implementation. This\n"); log("pass is very similar to the 'techmap' pass. The only difference is that this\n"); @@ -1154,17 +1163,29 @@ struct FlattenPass : public Pass { log("Cells and/or modules with the 'keep_hierarchy' attribute set will not be\n"); log("flattened by this command.\n"); log("\n"); + log(" -wb\n"); + log(" Ignore the 'whitebox' attribute on cell implementations.\n"); + log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing FLATTEN pass (flatten design).\n"); log_push(); - extra_args(args, 1, design); - TechmapWorker worker; worker.flatten_mode = true; + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-wb") { + worker.ignore_wb = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap; for (auto module : design->modules()) celltypeMap[module->name].insert(module->name); @@ -1209,7 +1230,7 @@ struct FlattenPass : public Pass { dict<RTLIL::IdString, RTLIL::Module*> new_modules; for (auto mod : vector<Module*>(design->modules())) - if (used_modules[mod->name] || mod->get_bool_attribute("\\blackbox")) { + if (used_modules[mod->name] || mod->get_blackbox_attribute(worker.ignore_wb)) { new_modules[mod->name] = mod; } else { log("Deleting now unused module %s.\n", log_id(mod)); |