aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEddie Hung <eddie@fpgeh.com>2020-01-12 15:19:41 -0800
committerEddie Hung <eddie@fpgeh.com>2020-01-12 15:19:41 -0800
commitf9aae90e7a9d238f5063d980e2b1e85a94cff4c7 (patch)
tree90cdb2422cf1194b6ab72997a82c54e5e0b4818c
parentf24de88f385a3eeaadd9b9c8c200a7c338f37448 (diff)
parent295e241c074ae275e832fdde9fae6fd897170ac8 (diff)
downloadyosys-f9aae90e7a9d238f5063d980e2b1e85a94cff4c7.tar.gz
yosys-f9aae90e7a9d238f5063d980e2b1e85a94cff4c7.tar.bz2
yosys-f9aae90e7a9d238f5063d980e2b1e85a94cff4c7.zip
Merge remote-tracking branch 'origin/eddie/abc9_refactor' into eddie/abc9_required
-rw-r--r--Makefile4
-rw-r--r--backends/aiger/xaiger.cc47
-rw-r--r--kernel/register.cc15
-rw-r--r--kernel/register.h3
-rw-r--r--kernel/yosys.cc3
-rw-r--r--passes/techmap/abc9.cc22
-rw-r--r--passes/techmap/abc9_exe.cc15
-rw-r--r--passes/techmap/abc9_ops.cc215
-rw-r--r--techlibs/ecp5/synth_ecp5.cc4
-rw-r--r--techlibs/xilinx/synth_xilinx.cc1
-rw-r--r--tests/arch/ecp5/bug1459.ys25
11 files changed, 198 insertions, 156 deletions
diff --git a/Makefile b/Makefile
index fd95219ee..43c4d0890 100644
--- a/Makefile
+++ b/Makefile
@@ -115,7 +115,7 @@ LDFLAGS += -rdynamic
LDLIBS += -lrt
endif
-YOSYS_VER := 0.9+932
+YOSYS_VER := 0.9+1706
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
OBJS = kernel/version_$(GIT_REV).o
@@ -128,7 +128,7 @@ bumpversion:
# is just a symlink to your actual ABC working directory, as 'make mrproper'
# will remove the 'abc' directory and you do not want to accidentally
# delete your work on ABC..
-ABCREV = 144c5be
+ABCREV = 71f2b40
ABCPULL = 1
ABCURL ?= https://github.com/berkeley-abc/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc
index 359d951b9..d934a9aa9 100644
--- a/backends/aiger/xaiger.cc
+++ b/backends/aiger/xaiger.cc
@@ -93,7 +93,6 @@ struct XAigerWriter
dict<SigBit, int> ordered_outputs;
vector<Cell*> box_list;
- dict<IdString, std::vector<IdString>> box_ports;
int mkgate(int a0, int a1)
{
@@ -296,6 +295,7 @@ struct XAigerWriter
//log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
}
+ dict<IdString, std::vector<IdString>> box_ports;
for (auto cell : box_list) {
log_assert(cell);
@@ -405,7 +405,8 @@ struct XAigerWriter
if (holes_mode) {
struct sort_by_port_id {
bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const {
- return a.wire->port_id < b.wire->port_id;
+ return a.wire->port_id < b.wire->port_id ||
+ (a.wire->port_id == b.wire->port_id && a.offset < b.offset);
}
};
input_bits.sort(sort_by_port_id());
@@ -545,7 +546,7 @@ struct XAigerWriter
RTLIL::Module *holes_module = module->design->module(stringf("%s$holes", module->name.c_str()));
log_assert(holes_module);
- dict<IdString, Cell*> cell_cache;
+ dict<IdString, std::tuple<int,int,int>> cell_cache;
int box_count = 0;
for (auto cell : box_list) {
@@ -554,24 +555,32 @@ struct XAigerWriter
RTLIL::Module* box_module = module->design->module(cell->type);
log_assert(box_module);
- int box_inputs = 0, box_outputs = 0;
- for (auto port_name : box_module->ports) {
- RTLIL::Wire *w = box_module->wire(port_name);
- log_assert(w);
- if (w->port_input)
- box_inputs += GetSize(w);
- if (w->port_output)
- box_outputs += GetSize(w);
- }
+ auto r = cell_cache.insert(cell->type);
+ auto &v = r.first->second;
+ if (r.second) {
+ int box_inputs = 0, box_outputs = 0;
+ for (auto port_name : box_module->ports) {
+ RTLIL::Wire *w = box_module->wire(port_name);
+ log_assert(w);
+ if (w->port_input)
+ box_inputs += GetSize(w);
+ if (w->port_output)
+ box_outputs += GetSize(w);
+ }
- // For flops only, create an extra 1-bit input that drives a new wire
- // called "<cell>.abc9_ff.Q" that is used below
- if (box_module->get_bool_attribute("\\abc9_flop"))
- box_inputs++;
+ // For flops only, create an extra 1-bit input that drives a new wire
+ // called "<cell>.abc9_ff.Q" that is used below
+ if (box_module->get_bool_attribute("\\abc9_flop"))
+ box_inputs++;
+
+ std::get<0>(v) = box_inputs;
+ std::get<1>(v) = box_outputs;
+ std::get<2>(v) = box_module->attributes.at("\\abc9_box_id").as_int();
+ }
- write_h_buffer(box_inputs);
- write_h_buffer(box_outputs);
- write_h_buffer(box_module->attributes.at("\\abc9_box_id").as_int());
+ write_h_buffer(std::get<0>(v));
+ write_h_buffer(std::get<1>(v));
+ write_h_buffer(std::get<2>(v));
write_h_buffer(box_count++);
}
diff --git a/kernel/register.cc b/kernel/register.cc
index 37f2e5e1b..5d0fb3c8c 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -114,20 +114,35 @@ void Pass::run_register()
void Pass::init_register()
{
+ vector<Pass*> added_passes;
while (first_queued_pass) {
+ added_passes.push_back(first_queued_pass);
first_queued_pass->run_register();
first_queued_pass = first_queued_pass->next_queued_pass;
}
+ for (auto added_pass : added_passes)
+ added_pass->on_register();
}
void Pass::done_register()
{
+ for (auto &it : pass_register)
+ it.second->on_shutdown();
+
frontend_register.clear();
pass_register.clear();
backend_register.clear();
log_assert(first_queued_pass == NULL);
}
+void Pass::on_register()
+{
+}
+
+void Pass::on_shutdown()
+{
+}
+
Pass::~Pass()
{
}
diff --git a/kernel/register.h b/kernel/register.h
index 85d552f0d..821faff3e 100644
--- a/kernel/register.h
+++ b/kernel/register.h
@@ -62,6 +62,9 @@ struct Pass
virtual void run_register();
static void init_register();
static void done_register();
+
+ virtual void on_register();
+ virtual void on_shutdown();
};
struct ScriptPass : Pass
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 5018a4888..8190d8902 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -544,6 +544,8 @@ void yosys_shutdown()
already_shutdown = true;
log_pop();
+ Pass::done_register();
+
delete yosys_design;
yosys_design = NULL;
@@ -553,7 +555,6 @@ void yosys_shutdown()
log_errfile = NULL;
log_files.clear();
- Pass::done_register();
yosys_celltypes.clear();
#ifdef YOSYS_ENABLE_TCL
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 41cfdeece..1be7519b7 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -26,9 +26,6 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate
- // to one LUT6 (instead of a LUT5 + LUT2)
-
struct Abc9Pass : public ScriptPass
{
Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { }
@@ -39,8 +36,9 @@ struct Abc9Pass : public ScriptPass
log("\n");
log(" abc9 [options] [selection]\n");
log("\n");
- log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n");
- log("library to a target architecture. Only fully-selected modules are supported.\n");
+ log("This script pass performs a sequence of commands to facilitate the use of the ABC\n");
+ log("tool [1] for technology mapping of the current design to a target FPGA\n");
+ log("architecture. Only fully-selected modules are supported.\n");
log("\n");
log(" -exe <command>\n");
#ifdef ABCEXTERNAL
@@ -59,21 +57,13 @@ struct Abc9Pass : public ScriptPass
log(" replaced with blanks before the string is passed to ABC.\n");
log("\n");
log(" if no -script parameter is given, the following scripts are used:\n");
- log("\n");
- log(" for -lut/-luts (only one LUT size):\n");
- // FIXME
- //log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str());
- log("\n");
- log(" for -lut/-luts (different LUT sizes):\n");
- // FIXME
+ //FIXME:
//log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str());
log("\n");
log(" -fast\n");
log(" use different default scripts that are slightly faster (at the cost\n");
log(" of output quality):\n");
- log("\n");
- log(" for -lut/-luts:\n");
- // FIXME
+ //FIXME:
//log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str());
log("\n");
log(" -D <picoseconds>\n");
@@ -200,10 +190,10 @@ struct Abc9Pass : public ScriptPass
run("select -set abc9_holes A:abc9_holes");
run("flatten -wb @abc9_holes");
run("techmap @abc9_holes");
- run("aigmap");
if (dff_mode || help_mode)
run("abc9_ops -prep_dff", "(only if -dff)");
run("opt -purge @abc9_holes");
+ run("aigmap");
run("wbflip @abc9_holes");
}
diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc
index b3afaebe6..d92285a51 100644
--- a/passes/techmap/abc9_exe.cc
+++ b/passes/techmap/abc9_exe.cc
@@ -284,10 +284,12 @@ struct Abc9ExePass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" abc9_exe [options] [selection]\n");
+ log(" abc9_exe [options]\n");
log("\n");
- log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n");
- log("library to a target architecture.\n");
+ log(" \n");
+ log("This pass uses the ABC tool [1] for technology mapping of the top module\n");
+ log("(according to the (* top *) attribute or if only one module is currently selected)\n");
+ log("to a target FPGA architecture.\n");
log("\n");
log(" -exe <command>\n");
#ifdef ABCEXTERNAL
@@ -306,18 +308,11 @@ struct Abc9ExePass : public Pass {
log(" replaced with blanks before the string is passed to ABC.\n");
log("\n");
log(" if no -script parameter is given, the following scripts are used:\n");
- log("\n");
- log(" for -lut/-luts (only one LUT size):\n");
- log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str());
- log("\n");
- log(" for -lut/-luts (different LUT sizes):\n");
log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str());
log("\n");
log(" -fast\n");
log(" use different default scripts that are slightly faster (at the cost\n");
log(" of output quality):\n");
- log("\n");
- log(" for -lut/-luts:\n");
log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str());
log("\n");
log(" -D <picoseconds>\n");
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index eac1ff2b6..7f3bbc7ad 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -98,7 +98,7 @@ void break_scc(RTLIL::Module *module)
// its output ports into a new PO, and drive its previous
// sinks with a new PI
pool<RTLIL::Const> ids_seen;
- for (auto cell : module->selected_cells()) {
+ for (auto cell : module->cells()) {
auto it = cell->attributes.find(ID(abc9_scc_id));
if (it == cell->attributes.end())
continue;
@@ -174,7 +174,7 @@ void prep_dff(RTLIL::Module *module)
typedef SigSpec clkdomain_t;
dict<clkdomain_t, int> clk_to_mergeability;
- for (auto cell : module->selected_cells()) {
+ for (auto cell : module->cells()) {
if (cell->type != "$__ABC9_FF_")
continue;
@@ -202,14 +202,16 @@ void prep_dff(RTLIL::Module *module)
RTLIL::Module *holes_module = design->module(stringf("%s$holes", module->name.c_str()));
if (holes_module) {
- dict<SigSig, SigSig> replace;
+ SigMap sigmap(holes_module);
+
+ dict<SigSpec, SigSpec> replace;
for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) {
auto cell = it->second;
if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_",
"$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) {
SigBit D = cell->getPort("\\D");
SigBit Q = cell->getPort("\\Q");
- // Remove the DFF cell from what needs to be a combinatorial box
+ // Remove the $_DFF_* cell from what needs to be a combinatorial box
it = holes_module->cells_.erase(it);
Wire *port;
if (GetSize(Q.wire) == 1)
@@ -217,10 +219,10 @@ void prep_dff(RTLIL::Module *module)
else
port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset));
log_assert(port);
- // Prepare to replace "assign <port> = DFF.Q;" with "assign <port> = DFF.D;"
- // in order to extract the combinatorial control logic that feeds the box
+ // Prepare to replace "assign <port> = $_DFF_*.Q;" with "assign <port> = $_DFF_*.D;"
+ // in order to extract just the combinatorial control logic that feeds the box
// (i.e. clock enable, synchronous reset, etc.)
- replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D)));
+ replace.insert(std::make_pair(Q,D));
// Since `flatten` above would have created wires named "<cell>.Q",
// extract the pre-techmap cell name
auto pos = Q.wire->name.str().rfind(".");
@@ -228,7 +230,7 @@ void prep_dff(RTLIL::Module *module)
IdString driver = Q.wire->name.substr(0, pos);
// And drive the signal that was previously driven by "DFF.Q" (typically
// used to implement clock-enable functionality) with the "<cell>.$abc9_currQ"
- // wire (which itself is driven an input port) we inserted above
+ // wire (which itself is driven an by input port) we inserted above
Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str()));
log_assert(currQ);
holes_module->connect(Q, currQ);
@@ -237,11 +239,8 @@ void prep_dff(RTLIL::Module *module)
++it;
}
- for (auto &conn : holes_module->connections_) {
- auto it = replace.find(conn);
- if (it != replace.end())
- conn = it->second;
- }
+ for (auto &conn : holes_module->connections_)
+ conn.second = replace.at(sigmap(conn.second), conn.second);
}
}
@@ -256,7 +255,7 @@ void prep_holes(RTLIL::Module *module, bool dff)
TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
bool abc9_box_seen = false;
- for (auto cell : module->selected_cells()) {
+ for (auto cell : module->cells()) {
if (cell->type == "$__ABC9_FF_")
continue;
@@ -294,21 +293,23 @@ void prep_holes(RTLIL::Module *module, bool dff)
for (auto user_cell : it.second)
toposort.edge(driver_cell, user_cell);
-#if 0
- toposort.analyze_loops = true;
-#endif
+ if (ys_debug(1))
+ toposort.analyze_loops = true;
+
bool no_loops YS_ATTRIBUTE(unused) = toposort.sort();
-#if 0
- unsigned i = 0;
- for (auto &it : toposort.loops) {
- log(" loop %d\n", i++);
- for (auto cell_name : it) {
- auto cell = module->cell(cell_name);
- log_assert(cell);
- log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute().c_str());
+
+ if (ys_debug(1)) {
+ unsigned i = 0;
+ for (auto &it : toposort.loops) {
+ log(" loop %d\n", i++);
+ for (auto cell_name : it) {
+ auto cell = module->cell(cell_name);
+ log_assert(cell);
+ log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute().c_str());
+ }
}
}
-#endif
+
log_assert(no_loops);
vector<Cell*> box_list;
@@ -377,100 +378,97 @@ void prep_holes(RTLIL::Module *module, bool dff)
log_assert(orig_box_module);
IdString derived_name = orig_box_module->derive(design, cell->parameters);
RTLIL::Module* box_module = design->module(derived_name);
- cell->type = derived_name;
- cell->parameters.clear();
-
- int box_inputs = 0;
- auto r = cell_cache.insert(std::make_pair(derived_name, nullptr));
- Cell *holes_cell = r.first->second;
- if (r.second && box_module->get_bool_attribute("\\whitebox")) {
- holes_cell = holes_module->addCell(cell->name, cell->type);
- holes_cell->parameters = cell->parameters;
- r.first->second = holes_cell;
-
- if (box_module->has_processes())
- Pass::call_on_module(design, box_module, "proc");
- }
+ //cell->type = derived_name;
+ //cell->parameters.clear();
- auto r2 = box_ports.insert(cell->type);
- if (r2.second) {
- // Make carry in the last PI, and carry out the last PO
- // since ABC requires it this way
- IdString carry_in, carry_out;
- for (const auto &port_name : box_module->ports) {
- auto w = box_module->wire(port_name);
- log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
- if (w->port_input)
- carry_in = port_name;
- if (w->port_output)
- carry_out = port_name;
+ auto r = cell_cache.insert(derived_name);
+ auto &holes_cell = r.first->second;
+ if (r.second) {
+ auto r2 = box_ports.insert(cell->type);
+ if (r2.second) {
+ // Make carry in the last PI, and carry out the last PO
+ // since ABC requires it this way
+ IdString carry_in, carry_out;
+ for (const auto &port_name : box_module->ports) {
+ auto w = box_module->wire(port_name);
+ log_assert(w);
+ if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->port_input)
+ carry_in = port_name;
+ if (w->port_output)
+ carry_out = port_name;
+ }
+ else
+ r2.first->second.push_back(port_name);
}
- else
- r2.first->second.push_back(port_name);
- }
- if (carry_in != IdString()) {
- r2.first->second.push_back(carry_in);
- r2.first->second.push_back(carry_out);
+ if (carry_in != IdString()) {
+ r2.first->second.push_back(carry_in);
+ r2.first->second.push_back(carry_out);
+ }
}
- }
- for (const auto &port_name : box_ports.at(cell->type)) {
- RTLIL::Wire *w = box_module->wire(port_name);
- log_assert(w);
- RTLIL::Wire *holes_wire;
- RTLIL::SigSpec port_sig;
- if (w->port_input)
- for (int i = 0; i < GetSize(w); i++) {
+ if (box_module->get_bool_attribute("\\whitebox")) {
+ holes_cell = holes_module->addCell(cell->name, derived_name);
+
+ if (box_module->has_processes())
+ Pass::call_on_module(design, box_module, "proc");
+
+ int box_inputs = 0;
+ for (auto port_name : box_ports.at(cell->type)) {
+ RTLIL::Wire *w = box_module->wire(port_name);
+ log_assert(w);
+ log_assert(!w->port_input || !w->port_output);
+ auto &conn = holes_cell->connections_[port_name];
+ if (w->port_input) {
+ for (int i = 0; i < GetSize(w); i++) {
+ box_inputs++;
+ RTLIL::Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
+ if (!holes_wire) {
+ holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs));
+ holes_wire->port_input = true;
+ holes_wire->port_id = port_id++;
+ holes_module->ports.push_back(holes_wire->name);
+ }
+ conn.append(holes_wire);
+ }
+ }
+ else if (w->port_output)
+ conn = holes_module->addWire(stringf("%s.%s", derived_name.c_str(), log_id(port_name)), GetSize(w));
+ }
+
+ // For flops only, create an extra 1-bit input that drives a new wire
+ // called "<cell>.abc9_ff.Q" that is used below
+ if (box_module->get_bool_attribute("\\abc9_flop")) {
box_inputs++;
- holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
+ Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
if (!holes_wire) {
holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs));
holes_wire->port_input = true;
holes_wire->port_id = port_id++;
holes_module->ports.push_back(holes_wire->name);
}
- if (holes_cell)
- port_sig.append(holes_wire);
- }
- if (w->port_output)
- for (int i = 0; i < GetSize(w); i++) {
- if (GetSize(w) == 1)
- holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(w->name)));
- else
- holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i));
- holes_wire->port_output = true;
- holes_wire->port_id = port_id++;
- holes_module->ports.push_back(holes_wire->name);
- if (holes_cell)
- port_sig.append(holes_wire);
- else
- holes_module->connect(holes_wire, State::S0);
+ Wire *Q = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str()));
+ holes_module->connect(Q, holes_wire);
}
- if (!port_sig.empty()) {
- if (r.second)
- holes_cell->setPort(w->name, port_sig);
- else
- holes_module->connect(holes_cell->getPort(w->name), port_sig);
}
+ else // box_module is a blackbox
+ log_assert(holes_cell == nullptr);
}
- // For flops only, create an extra 1-bit input that drives a new wire
- // called "<cell>.$abc9_currQ" that is used below
- if (box_module->get_bool_attribute("\\abc9_flop")) {
- log_assert(holes_cell);
-
- box_inputs++;
- Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
- if (!holes_wire) {
- holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs));
- holes_wire->port_input = true;
- holes_wire->port_id = port_id++;
- holes_module->ports.push_back(holes_wire->name);
- }
- Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str()));
- holes_module->connect(w, holes_wire);
+ for (auto port_name : box_ports.at(cell->type)) {
+ RTLIL::Wire *w = box_module->wire(port_name);
+ log_assert(w);
+ if (!w->port_output)
+ continue;
+ Wire *holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(port_name)), GetSize(w));
+ holes_wire->port_output = true;
+ holes_wire->port_id = port_id++;
+ holes_module->ports.push_back(holes_wire->name);
+ if (holes_cell) // whitebox
+ holes_module->connect(holes_wire, holes_cell->getPort(port_name));
+ else // blackbox
+ holes_module->connect(holes_wire, Const(State::S0, GetSize(w)));
}
}
}
@@ -1059,7 +1057,11 @@ struct Abc9OpsPass : public Pass {
}
extra_args(args, argidx, design);
- // TODO: Check at least one mode given
+ if (!(check_mode || break_scc_mode || unbreak_scc_mode || prep_times_mode || prep_holes_mode || prep_dff_mode || !write_box_src.empty() || reintegrate_mode))
+ log_cmd_error("At least one of -check, -{,un}break_scc, -prep_{times,holes,dff}, -write_box, -reintegrate must be specified.\n");
+
+ if (dff_mode && !prep_holes_mode)
+ log_cmd_error("'-dff' option is only relevant for -prep_holes.\n");
if (check_mode)
check(design);
@@ -1075,6 +1077,9 @@ struct Abc9OpsPass : public Pass {
continue;
}
+ if (!design->selected_whole_module(mod))
+ log_error("Can't handle partially selected module %s!\n", log_id(mod));
+
if (break_scc_mode)
break_scc(mod);
if (unbreak_scc_mode)
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index d616391b2..6583f43fd 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -323,9 +323,9 @@ struct SynthEcp5Pass : public ScriptPass
if (abc9) {
run("read_verilog -icells -lib +/ecp5/abc9_model.v");
if (nowidelut)
- run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
+ run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200");
else
- run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
+ run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200");
run("techmap -map +/ecp5/abc9_unmap.v");
} else {
if (nowidelut)
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index 51d2cbbd2..63d00027a 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -556,7 +556,6 @@ struct SynthXilinxPass : public ScriptPass
run("read_verilog -icells -lib +/xilinx/abc9_model.v");
std::string abc9_opts = " -box +/xilinx/abc9_xc7.box";
abc9_opts += stringf(" -W %d", XC7_WIRE_DELAY);
- abc9_opts += " -nomfs";
if (nowidelut)
abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut";
else
diff --git a/tests/arch/ecp5/bug1459.ys b/tests/arch/ecp5/bug1459.ys
new file mode 100644
index 000000000..1142ae0b5
--- /dev/null
+++ b/tests/arch/ecp5/bug1459.ys
@@ -0,0 +1,25 @@
+read_verilog <<EOT
+module register_file(
+ input wire clk,
+ input wire write_enable,
+ input wire [63:0] write_data,
+ input wire [4:0] write_reg,
+ input wire [4:0] read1_reg,
+ output reg [63:0] read1_data,
+ );
+
+ reg [63:0] registers[0:31];
+
+ always @(posedge clk) begin
+ if (write_enable == 1'b1) begin
+ registers[write_reg] <= write_data;
+ end
+ end
+
+ always @(all) begin
+ read1_data <= registers[read1_reg];
+ end
+endmodule
+EOT
+
+synth_ecp5 -abc9