aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
Diffstat (limited to 'passes')
-rw-r--r--passes/cmds/bugpoint.cc118
-rw-r--r--passes/cmds/check.cc77
-rw-r--r--passes/cmds/plugin.cc6
-rw-r--r--passes/cmds/scc.cc77
-rw-r--r--passes/hierarchy/hierarchy.cc8
-rw-r--r--passes/opt/opt_lut.cc6
-rw-r--r--passes/opt/opt_share.cc4
-rw-r--r--passes/pmgen/pmgen.py8
-rw-r--r--passes/sat/freduce.cc1
-rw-r--r--passes/sat/sim.cc4
-rw-r--r--passes/techmap/abc.cc37
-rw-r--r--passes/techmap/abc9.cc2
-rw-r--r--passes/techmap/flatten.cc7
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);