diff options
Diffstat (limited to 'passes')
-rw-r--r-- | passes/cmds/bugpoint.cc | 118 | ||||
-rw-r--r-- | passes/cmds/check.cc | 77 | ||||
-rw-r--r-- | passes/cmds/plugin.cc | 6 | ||||
-rw-r--r-- | passes/cmds/scc.cc | 77 | ||||
-rw-r--r-- | passes/hierarchy/hierarchy.cc | 8 | ||||
-rw-r--r-- | passes/opt/opt_lut.cc | 6 | ||||
-rw-r--r-- | passes/opt/opt_share.cc | 4 | ||||
-rw-r--r-- | passes/pmgen/pmgen.py | 8 | ||||
-rw-r--r-- | passes/sat/freduce.cc | 1 | ||||
-rw-r--r-- | passes/sat/sim.cc | 4 | ||||
-rw-r--r-- | passes/techmap/abc.cc | 37 | ||||
-rw-r--r-- | passes/techmap/abc9.cc | 2 | ||||
-rw-r--r-- | passes/techmap/flatten.cc | 7 |
13 files changed, 270 insertions, 85 deletions
diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 81d7a34bb..da81e7f09 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -30,7 +30,7 @@ struct BugpointPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" bugpoint [options] -script <filename>\n"); + log(" bugpoint [options] [-script <filename> | -command \"<command>\"]\n"); log("\n"); log("This command minimizes the current design that is known to crash Yosys with the\n"); log("given script into a smaller testcase. It does this by removing an arbitrary part\n"); @@ -39,13 +39,13 @@ struct BugpointPass : public Pass { log("still causes a crash. Once this command finishes, it replaces the current design\n"); log("with the smallest testcase it was able to produce.\n"); log("\n"); - log(" -script <filename>\n"); - log(" use this script to crash Yosys. required.\n"); + log(" -script <filename> | -command \"<command>\"\n"); + log(" use this script file or command to crash Yosys. required.\n"); log("\n"); log(" -yosys <filename>\n"); log(" use this Yosys binary. if not specified, `yosys` is used.\n"); log("\n"); - log(" -grep <string>\n"); + log(" -grep \"<string>\"\n"); log(" only consider crashes that place this string in the log file.\n"); log("\n"); log(" -fast\n"); @@ -77,6 +77,10 @@ struct BugpointPass : public Pass { log(" -connections\n"); log(" try to reconnect ports to 'x.\n"); log("\n"); + log(" -processes\n"); + log(" try to remove processes. processes with a (* bugpoint_keep *) attribute\n"); + log(" will be skipped.\n"); + log("\n"); log(" -assigns\n"); log(" try to remove process assigns from cases.\n"); log("\n"); @@ -85,7 +89,7 @@ struct BugpointPass : public Pass { log("\n"); } - bool run_yosys(RTLIL::Design *design, string yosys_cmd, string script) + bool run_yosys(RTLIL::Design *design, string yosys_cmd, string yosys_arg) { design->sort(); @@ -93,7 +97,7 @@ struct BugpointPass : public Pass { RTLIL_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false); f.close(); - string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log -s %s bugpoint-case.il", yosys_cmd.c_str(), script.c_str()); + string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log %s bugpoint-case.il", yosys_cmd.c_str(), yosys_arg.c_str()); return run_command(yosys_cmdline) == 0; } @@ -102,6 +106,9 @@ struct BugpointPass : public Pass { if (grep.empty()) return true; + if (grep.size() > 2 && grep.front() == '"' && grep.back() == '"') + grep = grep.substr(1, grep.size() - 2); + std::ifstream f("bugpoint-case.log"); while (!f.eof()) { @@ -129,7 +136,7 @@ struct BugpointPass : public Pass { return design_copy; } - RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool assigns, bool updates) + RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool processes, bool assigns, bool updates, bool wires) { RTLIL::Design *design_copy = new RTLIL::Design; for (auto module : design->modules()) @@ -194,7 +201,6 @@ struct BugpointPass : public Pass { if (mod->get_blackbox_attribute()) continue; - Cell *removed_cell = nullptr; for (auto cell : mod->cells()) { @@ -257,6 +263,33 @@ struct BugpointPass : public Pass { } } } + if (processes) + { + for (auto mod : design_copy->modules()) + { + if (mod->get_blackbox_attribute()) + continue; + + RTLIL::IdString removed_process; + for (auto process : mod->processes) + { + if (process.second->get_bool_attribute(ID::bugpoint_keep)) + continue; + + if (index++ == seed) + { + log_header(design, "Trying to remove process %s.%s.\n", log_id(mod), log_id(process.first)); + removed_process = process.first; + break; + } + } + if (!removed_process.empty()) { + delete mod->processes[removed_process]; + mod->processes.erase(removed_process); + return design_copy; + } + } + } if (assigns) { for (auto mod : design_copy->modules()) @@ -310,14 +343,43 @@ struct BugpointPass : public Pass { } } } + if (wires) + { + for (auto mod : design_copy->modules()) + { + if (mod->get_blackbox_attribute()) + continue; + + Wire *removed_wire = nullptr; + for (auto wire : mod->wires()) + { + if (wire->get_bool_attribute(ID::bugpoint_keep)) + continue; + + if (wire->name.begins_with("$delete_wire")) + continue; + + if (index++ == seed) + { + log_header(design, "Trying to remove wire %s.%s.\n", log_id(mod), log_id(wire)); + removed_wire = wire; + break; + } + } + if (removed_wire) { + mod->remove({removed_wire}); + return design_copy; + } + } + } return nullptr; } void execute(std::vector<std::string> args, RTLIL::Design *design) override { - string yosys_cmd = "yosys", script, grep; + string yosys_cmd = "yosys", yosys_arg, grep; bool fast = false, clean = false; - bool modules = false, ports = false, cells = false, connections = false, assigns = false, updates = false, has_part = false; + bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, wires = false, has_part = false; log_header(design, "Executing BUGPOINT pass (minimize testcases).\n"); log_push(); @@ -330,7 +392,15 @@ struct BugpointPass : public Pass { continue; } if (args[argidx] == "-script" && argidx + 1 < args.size()) { - script = args[++argidx]; + if (!yosys_arg.empty()) + log_cmd_error("A -script or -command option can be only provided once!\n"); + yosys_arg = stringf("-s %s", args[++argidx].c_str()); + continue; + } + if (args[argidx] == "-command" && argidx + 1 < args.size()) { + if (!yosys_arg.empty()) + log_cmd_error("A -script or -command option can be only provided once!\n"); + yosys_arg = stringf("-p %s", args[++argidx].c_str()); continue; } if (args[argidx] == "-grep" && argidx + 1 < args.size()) { @@ -365,6 +435,11 @@ struct BugpointPass : public Pass { has_part = true; continue; } + if (args[argidx] == "-processes") { + processes = true; + has_part = true; + continue; + } if (args[argidx] == "-assigns") { assigns = true; has_part = true; @@ -375,12 +450,17 @@ struct BugpointPass : public Pass { has_part = true; continue; } + if (args[argidx] == "-wires") { + wires = true; + has_part = true; + continue; + } break; } extra_args(args, argidx, design); - if (script.empty()) - log_cmd_error("Missing -script option.\n"); + if (yosys_arg.empty()) + log_cmd_error("Missing -script or -command option.\n"); if (!has_part) { @@ -388,16 +468,18 @@ struct BugpointPass : public Pass { ports = true; cells = true; connections = true; + processes = true; assigns = true; updates = true; + wires = true; } if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); RTLIL::Design *crashing_design = clean_design(design, clean); - if (run_yosys(crashing_design, yosys_cmd, script)) - log_cmd_error("The provided script file and Yosys binary do not crash on this design!\n"); + if (run_yosys(crashing_design, yosys_cmd, yosys_arg)) + log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n"); if (!check_logfile(grep)) log_cmd_error("The provided grep string is not found in the log file!\n"); @@ -405,7 +487,7 @@ struct BugpointPass : public Pass { bool found_something = false, stage2 = false; while (true) { - if (RTLIL::Design *simplified = simplify_something(crashing_design, seed, stage2, modules, ports, cells, connections, assigns, updates)) + if (RTLIL::Design *simplified = simplify_something(crashing_design, seed, stage2, modules, ports, cells, connections, processes, assigns, updates, wires)) { simplified = clean_design(simplified, fast, /*do_delete=*/true); @@ -413,12 +495,12 @@ struct BugpointPass : public Pass { if (clean) { RTLIL::Design *testcase = clean_design(simplified); - crashes = !run_yosys(testcase, yosys_cmd, script); + crashes = !run_yosys(testcase, yosys_cmd, yosys_arg); delete testcase; } else { - crashes = !run_yosys(simplified, yosys_cmd, script); + crashes = !run_yosys(simplified, yosys_cmd, yosys_arg); } if (crashes && check_logfile(grep)) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index a8b5362b3..36febb98a 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -35,30 +35,28 @@ struct CheckPass : public Pass { log("\n"); log("This pass identifies the following problems in the current design:\n"); log("\n"); - log(" - combinatorial loops\n"); - log("\n"); - log(" - two or more conflicting drivers for one wire\n"); - log("\n"); - log(" - used wires that do not have a driver\n"); + log(" - combinatorial loops\n"); + log(" - two or more conflicting drivers for one wire\n"); + log(" - used wires that do not have a driver\n"); log("\n"); log("Options:\n"); log("\n"); - log(" -noinit\n"); - log(" Also check for wires which have the 'init' attribute set.\n"); + log(" -noinit\n"); + log(" also check for wires which have the 'init' attribute set\n"); log("\n"); - log(" -initdrv\n"); - log(" Also check for wires that have the 'init' attribute set and are not\n"); - log(" driven by an FF cell type.\n"); + log(" -initdrv\n"); + log(" also check for wires that have the 'init' attribute set and are not\n"); + log(" driven by an FF cell type\n"); log("\n"); - log(" -mapped\n"); - log(" Also check for internal cells that have not been mapped to cells of the\n"); - log(" target architecture.\n"); + log(" -mapped\n"); + log(" also check for internal cells that have not been mapped to cells of the\n"); + log(" target architecture\n"); log("\n"); - log(" -allow-tbuf\n"); - log(" Modify the -mapped behavior to still allow $_TBUF_ cells.\n"); + log(" -allow-tbuf\n"); + log(" modify the -mapped behavior to still allow $_TBUF_ cells\n"); log("\n"); - log(" -assert\n"); - log(" Produce a runtime error if any problems are found in the current design.\n"); + log(" -assert\n"); + log(" produce a runtime error if any problems are found in the current design\n"); log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) override @@ -100,10 +98,7 @@ struct CheckPass : public Pass { for (auto module : design->selected_whole_modules_warn()) { - if (module->has_processes_warn()) - continue; - - log("checking module %s..\n", log_id(module)); + log("Checking module %s...\n", log_id(module)); SigMap sigmap(module); dict<SigBit, vector<string>> wire_drivers; @@ -111,6 +106,44 @@ struct CheckPass : public Pass { pool<SigBit> used_wires; TopoSort<string> topo; + for (auto &proc_it : module->processes) + { + std::vector<RTLIL::CaseRule*> all_cases = {&proc_it.second->root_case}; + for (size_t i = 0; i < all_cases.size(); i++) { + for (auto action : all_cases[i]->actions) { + for (auto bit : sigmap(action.first)) + if (bit.wire) { + wire_drivers[bit].push_back( + stringf("action %s <= %s (case rule) in process %s", + log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + } + for (auto bit : sigmap(action.second)) + if (bit.wire) used_wires.insert(bit); + } + for (auto switch_ : all_cases[i]->switches) { + for (auto case_ : switch_->cases) { + all_cases.push_back(case_); + for (auto compare : case_->compare) + for (auto bit : sigmap(compare)) + if (bit.wire) used_wires.insert(bit); + } + } + } + for (auto &sync : proc_it.second->syncs) { + for (auto bit : sigmap(sync->signal)) + if (bit.wire) used_wires.insert(bit); + for (auto action : sync->actions) { + for (auto bit : sigmap(action.first)) + if (bit.wire) + wire_drivers[bit].push_back( + stringf("action %s <= %s (sync rule) in process %s", + log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + for (auto bit : sigmap(action.second)) + if (bit.wire) used_wires.insert(bit); + } + } + } + for (auto cell : module->cells()) { if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) { @@ -216,7 +249,7 @@ struct CheckPass : public Pass { } } - log("found and reported %d problems.\n", counter); + log("Found and reported %d problems.\n", counter); if (assert_mode && counter > 0) log_error("Found %d problems in 'check -assert'.\n", counter); diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 3ed19497d..a94769bcd 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -93,7 +93,11 @@ void load_plugin(std::string filename, std::vector<std::string> aliases) #else void load_plugin(std::string, std::vector<std::string>) { - log_error("This version of yosys is built without plugin support.\n"); + log_error( + "\n This version of Yosys cannot load plugins at runtime.\n" + " Some plugins may have been included at build time.\n" + " Use option `-H' to see the available built-in and plugin commands.\n" + ); } #endif diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 8e7f3f990..7aa9a484f 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -37,7 +37,7 @@ struct SccWorker RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap; - CellTypes ct; + CellTypes ct, specifyCells; std::set<RTLIL::Cell*> workQueue; std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> cellToNextCell; @@ -100,7 +100,7 @@ struct SccWorker } } - SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, int maxDepth) : + SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, bool specifyMode, int maxDepth) : design(design), module(module), sigmap(module) { if (module->processes.size() > 0) { @@ -115,6 +115,18 @@ struct SccWorker ct.setup_stdcells(); } + // Discover boxes with specify rules in them, for special handling. + if (specifyMode) { + for (auto mod : design->modules()) + if (mod->get_blackbox_attribute(false)) + for (auto cell : mod->cells()) + if (cell->type == ID($specify2)) + { + specifyCells.setup_module(mod); + break; + } + } + SigPool selectedSignals; SigSet<RTLIL::Cell*> sigToNextCells; @@ -129,29 +141,52 @@ struct SccWorker if (!design->selected(module, cell)) continue; - if (!allCellTypes && !ct.cell_known(cell->type)) + if (!allCellTypes && !ct.cell_known(cell->type) && !specifyCells.cell_known(cell->type)) continue; workQueue.insert(cell); RTLIL::SigSpec inputSignals, outputSignals; - for (auto &conn : cell->connections()) - { - bool isInput = true, isOutput = true; + if (specifyCells.cell_known(cell->type)) { + // Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes. + for (auto subcell : design->module(cell->type)->cells()) + { + if (subcell->type != ID($specify2)) + continue; - if (ct.cell_known(cell->type)) { - isInput = ct.cell_input(cell->type, conn.first); - isOutput = ct.cell_output(cell->type, conn.first); + for (auto bit : subcell->getPort(ID::SRC)) + { + if (!bit.wire || !cell->hasPort(bit.wire->name)) + continue; + inputSignals.append(sigmap(cell->getPort(bit.wire->name))); + } + + for (auto bit : subcell->getPort(ID::DST)) + { + if (!bit.wire || !cell->hasPort(bit.wire->name)) + continue; + outputSignals.append(sigmap(cell->getPort(bit.wire->name))); + } } + } else { + for (auto &conn : cell->connections()) + { + bool isInput = true, isOutput = true; + + if (ct.cell_known(cell->type)) { + isInput = ct.cell_input(cell->type, conn.first); + isOutput = ct.cell_output(cell->type, conn.first); + } - RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); - sig.sort_and_unify(); + RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); + sig.sort_and_unify(); - if (isInput) - inputSignals.append(sig); - if (isOutput) - outputSignals.append(sig); + if (isInput) + inputSignals.append(sig); + if (isOutput) + outputSignals.append(sig); + } } inputSignals.sort_and_unify(); @@ -228,7 +263,7 @@ struct SccPass : public Pass { log("design.\n"); log("\n"); log(" -expect <num>\n"); - log(" expect to find exactly <num> SSCs. A different number of SSCs will\n"); + log(" expect to find exactly <num> SCCs. A different number of SCCs will\n"); log(" produce an error.\n"); log("\n"); log(" -max_depth <num>\n"); @@ -254,6 +289,9 @@ struct SccPass : public Pass { log(" replace the current selection with a selection of all cells and wires\n"); log(" that are part of a found logic loop\n"); log("\n"); + log(" -specify\n"); + log(" examine specify rules to detect logic loops in whitebox/blackbox cells\n"); + log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) override { @@ -261,6 +299,7 @@ struct SccPass : public Pass { bool allCellTypes = false; bool selectMode = false; bool nofeedbackMode = false; + bool specifyMode = false; int maxDepth = -1; int expect = -1; @@ -293,6 +332,10 @@ struct SccPass : public Pass { selectMode = true; continue; } + if (args[argidx] == "-specify") { + specifyMode = true; + continue; + } break; } int origSelectPos = design->selection_stack.size() - 1; @@ -303,7 +346,7 @@ struct SccPass : public Pass { for (auto mod : design->selected_modules()) { - SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth); + SccWorker worker(design, mod, nofeedbackMode, allCellTypes, specifyMode, maxDepth); if (!setAttr.empty()) { diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 225e1feae..3372687e1 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -1233,14 +1233,18 @@ struct HierarchyPass : public Pass { { int n = GetSize(conn.second) - GetSize(w); if (!w->port_input && w->port_output) - module->connect(sig.extract(GetSize(w), n), Const(0, n)); + { + RTLIL::SigSpec out = sig.extract(0, GetSize(w)); + out.extend_u0(GetSize(sig), w->is_signed); + module->connect(sig.extract(GetSize(w), n), out.extract(GetSize(w), n)); + } sig.remove(GetSize(w), n); } else { int n = GetSize(w) - GetSize(conn.second); if (w->port_input && !w->port_output) - sig.append(Const(0, n)); + sig.extend_u0(GetSize(w), sig.is_wire() && sig.as_wire()->is_signed); else sig.append(module->addWire(NEW_ID, n)); } diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 07a91af8a..623101016 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -277,12 +277,13 @@ struct OptLutWorker module->connect(lut_output, value); sigmap.add(lut_output, value); - module->remove(lut); luts.erase(lut); luts_arity.erase(lut); luts_dlogics.erase(lut); luts_dlogic_inputs.erase(lut); + module->remove(lut); + eliminated_count++; if (limit > 0) limit--; @@ -493,11 +494,12 @@ struct OptLutWorker luts_arity[lutM] = lutM_arity; luts.erase(lutR); luts_arity.erase(lutR); - lutR->module->remove(lutR); worklist.insert(lutM); worklist.erase(lutR); + lutR->module->remove(lutR); + combined_count++; if (limit > 0) limit--; diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 53296699c..62a478673 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -244,8 +244,8 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< } if (shared_op->type.in(ID($alu))) { - shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_sig_out))); - shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_sig_out))); + shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_out))); + shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_out))); } bool is_fine = shared_op->type.in(FINE_BITWISE_OPS); diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 592a26fa6..6e2fabeeb 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -451,7 +451,9 @@ with open(outfile, "w") as f: current_pattern = None print(" SigSpec port(Cell *cell, IdString portname) {", file=f) - print(" return sigmap(cell->getPort(portname));", file=f) + print(" try {", file=f) + print(" return sigmap(cell->getPort(portname));", file=f) + print(" } catch(std::out_of_range&) { log_error(\"Accessing non existing port %s\\n\",portname.c_str()); }", file=f) print(" }", file=f) print("", file=f) print(" SigSpec port(Cell *cell, IdString portname, const SigSpec& defval) {", file=f) @@ -460,7 +462,9 @@ with open(outfile, "w") as f: print("", file=f) print(" Const param(Cell *cell, IdString paramname) {", file=f) - print(" return cell->getParam(paramname);", file=f) + print(" try {", file=f) + print(" return cell->getParam(paramname);", file=f) + print(" } catch(std::out_of_range&) { log_error(\"Accessing non existing parameter %s\\n\",paramname.c_str()); }", file=f) print(" }", file=f) print("", file=f) print(" Const param(Cell *cell, IdString paramname, const Const& defval) {", file=f) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 762edfdfb..f87b85da9 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -27,6 +27,7 @@ #include <stdio.h> #include <string.h> #include <algorithm> +#include <limits> USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 75f922dba..3ba66bd33 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -810,7 +810,9 @@ struct SimPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-vcd" && argidx+1 < args.size()) { - worker.vcdfile.open(args[++argidx].c_str()); + std::string vcd_filename = args[++argidx]; + rewrite_filename(vcd_filename); + worker.vcdfile.open(vcd_filename.c_str()); continue; } if (args[argidx] == "-n" && argidx+1 < args.size()) { diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 192e39372..1169e3da0 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -54,6 +54,7 @@ #include <cerrno> #include <sstream> #include <climits> +#include <vector> #ifndef _WIN32 # include <unistd.h> @@ -654,7 +655,7 @@ struct abc_output_filter }; void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - std::string liberty_file, std::string constr_file, bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str, + std::vector<std::string> &liberty_files, std::string constr_file, bool cleanup, vector<int> 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<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, bool abc_dress) { @@ -709,8 +710,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin std::string abc_script = stringf("read_blif %s/input.blif; ", tempdir_name.c_str()); - if (!liberty_file.empty()) { - abc_script += stringf("read_lib -w %s; ", liberty_file.c_str()); + if (!liberty_files.empty()) { + for (std::string liberty_file : liberty_files) abc_script += stringf("read_lib -w %s; ", liberty_file.c_str()); if (!constr_file.empty()) abc_script += stringf("read_constr -v %s; ", constr_file.c_str()); } else @@ -738,7 +739,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; if (all_luts_cost_same && !fast_mode) abc_script += "; lutpack {S}"; - } else if (!liberty_file.empty()) + } else if (!liberty_files.empty()) abc_script += constr_file.empty() ? (fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR); else if (sop_mode) abc_script += fast_mode ? ABC_FAST_COMMAND_SOP : ABC_COMMAND_SOP; @@ -1019,7 +1020,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (ifs.fail()) log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); - bool builtin_lib = liberty_file.empty(); + bool builtin_lib = liberty_files.empty(); RTLIL::Design *mapped_design = new RTLIL::Design; parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, sop_mode); @@ -1471,7 +1472,8 @@ struct AbcPass : public Pass { po_map.clear(); std::string exe_file = yosys_abc_executable; - std::string script_file, liberty_file, constr_file, clk_str; + std::string script_file, default_liberty_file, constr_file, clk_str; + std::vector<std::string> liberty_files; std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1"; bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; bool show_tempdir = false, sop_mode = false; @@ -1489,7 +1491,7 @@ struct AbcPass : public Pass { std::string lut_arg, luts_arg, g_arg; exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */); script_file = design->scratchpad_get_string("abc.script", script_file); - liberty_file = design->scratchpad_get_string("abc.liberty", liberty_file); + default_liberty_file = design->scratchpad_get_string("abc.liberty", default_liberty_file); constr_file = design->scratchpad_get_string("abc.constr", constr_file); if (design->scratchpad.count("abc.D")) { delay_target = "-D " + design->scratchpad_get_string("abc.D"); @@ -1551,7 +1553,7 @@ struct AbcPass : public Pass { continue; } if (arg == "-liberty" && argidx+1 < args.size()) { - liberty_file = args[++argidx]; + liberty_files.push_back(args[++argidx]); continue; } if (arg == "-constr" && argidx+1 < args.size()) { @@ -1643,12 +1645,16 @@ struct AbcPass : public Pass { } extra_args(args, argidx, design); + if (liberty_files.empty() && !default_liberty_file.empty()) liberty_files.push_back(default_liberty_file); + rewrite_filename(script_file); if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') script_file = std::string(pwd) + "/" + script_file; - rewrite_filename(liberty_file); - if (!liberty_file.empty() && !is_absolute_path(liberty_file)) - liberty_file = std::string(pwd) + "/" + liberty_file; + for (int i = 0; i < GetSize(liberty_files); i++) { + rewrite_filename(liberty_files[i]); + if (!liberty_files[i].empty() && !is_absolute_path(liberty_files[i])) + liberty_files[i] = std::string(pwd) + "/" + liberty_files[i]; + } rewrite_filename(constr_file); if (!constr_file.empty() && !is_absolute_path(constr_file)) constr_file = std::string(pwd) + "/" + constr_file; @@ -1794,6 +1800,7 @@ struct AbcPass : public Pass { gate_list.push_back("OAI4"); gate_list.push_back("MUX"); gate_list.push_back("NMUX"); + goto ok_alias; } if (g_arg_from_cmd) cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str())); @@ -1811,9 +1818,9 @@ struct AbcPass : public Pass { } } - if (!lut_costs.empty() && !liberty_file.empty()) + if (!lut_costs.empty() && !liberty_files.empty()) log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n"); - if (!constr_file.empty() && liberty_file.empty()) + if (!constr_file.empty() && liberty_files.empty()) log_cmd_error("Got -constr but no -liberty!\n"); if (enabled_gates.empty()) { @@ -1844,7 +1851,7 @@ struct AbcPass : public Pass { initvals.set(&assign_map, mod); if (!dff_mode || !clk_str.empty()) { - abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, + abc_module(design, mod, script_file, exe_file, liberty_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); continue; } @@ -1989,7 +1996,7 @@ struct AbcPass : public Pass { clk_sig = assign_map(std::get<1>(it.first)); en_polarity = std::get<2>(it.first); en_sig = assign_map(std::get<3>(it.first)); - abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", + abc_module(design, mod, script_file, exe_file, liberty_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); assign_map.set(mod); } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7d017ac40..56bb15495 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -339,7 +339,7 @@ struct Abc9Pass : public ScriptPass if (check_label("pre")) { run("read_verilog -icells -lib -specify +/abc9_model.v"); - run("scc -set_attr abc9_scc_id {}"); + run("scc -specify -set_attr abc9_scc_id {}"); if (help_mode) run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); else diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index 08978f446..f35b7ff60 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -180,12 +180,15 @@ struct FlattenWorker RTLIL::Wire *tpl_wire = tpl->wire(port_name); RTLIL::SigSig new_conn; + bool is_signed = false; if (tpl_wire->port_output && !tpl_wire->port_input) { new_conn.first = port_it.second; new_conn.second = tpl_wire; + is_signed = tpl_wire->is_signed; } else if (!tpl_wire->port_output && tpl_wire->port_input) { new_conn.first = tpl_wire; new_conn.second = port_it.second; + is_signed = new_conn.second.is_wire() && new_conn.second.as_wire()->is_signed; } else { SigSpec sig_tpl = tpl_wire, sig_mod = port_it.second; for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) { @@ -204,11 +207,11 @@ struct FlattenWorker if (new_conn.second.size() > new_conn.first.size()) new_conn.second.remove(new_conn.first.size(), new_conn.second.size() - new_conn.first.size()); if (new_conn.second.size() < new_conn.first.size()) - new_conn.second.append(RTLIL::SigSpec(RTLIL::State::S0, new_conn.first.size() - new_conn.second.size())); + new_conn.second.extend_u0(new_conn.first.size(), is_signed); log_assert(new_conn.first.size() == new_conn.second.size()); if (sigmap(new_conn.first).has_const()) - log_error("Mismatch in directionality for cell port %s.%s.%s: %s <= %s\n", + log_error("Cell port %s.%s.%s is driving constant bits: %s <= %s\n", log_id(module), log_id(cell), log_id(port_it.first), log_signal(new_conn.first), log_signal(new_conn.second)); module->connect(new_conn); |