aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap
diff options
context:
space:
mode:
authorEddie Hung <eddie@fpgeh.com>2020-01-11 13:56:41 -0800
committerEddie Hung <eddie@fpgeh.com>2020-01-11 13:56:41 -0800
commit11128dccb53983e7bb784cf2514edcaa6eb822fb (patch)
tree0cdf181b2b00302543a5eed54dd6453b2ce9a114 /passes/techmap
parent88f14b8bca811a3945aa642ccd50d22ffa0adcbd (diff)
parent784fec93c901caa6f9d980388356d120b0cdfea9 (diff)
downloadyosys-11128dccb53983e7bb784cf2514edcaa6eb822fb.tar.gz
yosys-11128dccb53983e7bb784cf2514edcaa6eb822fb.tar.bz2
yosys-11128dccb53983e7bb784cf2514edcaa6eb822fb.zip
Merge branch 'eddie/abc9_refactor' of github.com:YosysHQ/yosys into eddie/abc9_refactor
Diffstat (limited to 'passes/techmap')
-rw-r--r--passes/techmap/abc9.cc20
-rw-r--r--passes/techmap/abc9_exe.cc15
-rw-r--r--passes/techmap/abc9_ops.cc154
3 files changed, 88 insertions, 101 deletions
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index ba5f97626..939eff021 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");
diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc
index f7dafda96..3108765a1 100644
--- a/passes/techmap/abc9_exe.cc
+++ b/passes/techmap/abc9_exe.cc
@@ -289,10 +289,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
@@ -311,18 +313,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 721a33f09..6f089447e 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -40,7 +40,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;
@@ -116,7 +116,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;
@@ -179,11 +179,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 = replace.at(conn, conn);
}
}
@@ -198,7 +195,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;
@@ -236,21 +233,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;
@@ -488,11 +487,13 @@ void reintegrate(RTLIL::Module *module)
}
}
- for (auto it = module->cells_.begin(); it != module->cells_.end(); )
- if (it->second->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_)))
- it = module->cells_.erase(it);
- else
- ++it;
+ std::vector<Cell*> boxes;
+ for (auto cell : module->cells().to_vector()) {
+ if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_)))
+ module->remove(cell);
+ else if (cell->attributes.erase("\\abc9_box_seq"))
+ boxes.emplace_back(cell);
+ }
dict<SigBit, pool<IdString>> bit_drivers, bit_users;
TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
@@ -504,7 +505,6 @@ void reintegrate(RTLIL::Module *module)
{
toposort.node(mapped_cell->name);
- RTLIL::Cell *cell = nullptr;
if (mapped_cell->type == ID($_NOT_)) {
RTLIL::SigBit a_bit = mapped_cell->getPort(ID::A);
RTLIL::SigBit y_bit = mapped_cell->getPort(ID::Y);
@@ -536,7 +536,7 @@ void reintegrate(RTLIL::Module *module)
if (!driver_lut) {
// If a driver couldn't be found (could be from PI or box CI)
// then implement using a LUT
- cell = module->addLut(remap_name(stringf("%s$lut", mapped_cell->name.c_str())),
+ RTLIL::Cell *cell = module->addLut(remap_name(stringf("%s$lut", mapped_cell->name.c_str())),
RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset),
RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset),
RTLIL::Const::from_string("01"));
@@ -548,10 +548,9 @@ void reintegrate(RTLIL::Module *module)
}
continue;
}
- cell_stats[mapped_cell->type]++;
- RTLIL::Cell *existing_cell = nullptr;
if (mapped_cell->type.in(ID($lut), ID($__ABC9_FF_))) {
+ // Convert buffer into direct connection
if (mapped_cell->type == ID($lut) &&
GetSize(mapped_cell->getPort(ID::A)) == 1 &&
mapped_cell->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) {
@@ -561,22 +560,48 @@ void reintegrate(RTLIL::Module *module)
log_abort();
continue;
}
- cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
+ RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
+ cell->parameters = mapped_cell->parameters;
+ cell->attributes = mapped_cell->attributes;
+
+ for (auto &mapped_conn : mapped_cell->connections()) {
+ RTLIL::SigSpec newsig;
+ for (auto c : mapped_conn.second.chunks()) {
+ if (c.width == 0)
+ continue;
+ //log_assert(c.width == 1);
+ if (c.wire)
+ c.wire = module->wires_.at(remap_name(c.wire->name));
+ newsig.append(c);
+ }
+ cell->setPort(mapped_conn.first, newsig);
+
+ if (cell->input(mapped_conn.first)) {
+ for (auto i : newsig)
+ bit2sinks[i].push_back(cell);
+ for (auto i : mapped_conn.second)
+ bit_users[i].insert(mapped_cell->name);
+ }
+ if (cell->output(mapped_conn.first))
+ for (auto i : mapped_conn.second)
+ bit_drivers[i].insert(mapped_cell->name);
+ }
}
else {
- existing_cell = module->cell(mapped_cell->name);
+ RTLIL::Cell *existing_cell = module->cell(mapped_cell->name);
log_assert(existing_cell);
+ log_assert(mapped_cell->type.begins_with("$__boxid"));
- if (mapped_cell->type.begins_with("$__boxid")) {
- auto type = box_lookup.at(mapped_cell->type, IdString());
- if (type == IdString())
- log_error("No module with abc9_box_id = %s found.\n", mapped_cell->type.c_str() + strlen("$__boxid"));
- mapped_cell->type = type;
- }
- cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
- }
+ auto type = box_lookup.at(mapped_cell->type, IdString());
+ if (type == IdString())
+ log_error("No module with abc9_box_id = %s found.\n", mapped_cell->type.c_str() + strlen("$__boxid"));
+ mapped_cell->type = type;
+
+ RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
+ cell->parameters = existing_cell->parameters;
+ cell->attributes = existing_cell->attributes;
+ module->swap_names(cell, existing_cell);
- if (existing_cell) {
auto it = mapped_cell->connections_.find("\\i");
log_assert(it != mapped_cell->connections_.end());
SigSpec inputs = std::move(it->second);
@@ -635,45 +660,13 @@ void reintegrate(RTLIL::Module *module)
bit2sinks[i].push_back(cell);
}
}
- else {
- for (auto &mapped_conn : mapped_cell->connections()) {
- RTLIL::SigSpec newsig;
- for (auto c : mapped_conn.second.chunks()) {
- if (c.width == 0)
- continue;
- //log_assert(c.width == 1);
- if (c.wire)
- c.wire = module->wires_.at(remap_name(c.wire->name));
- newsig.append(c);
- }
- cell->setPort(mapped_conn.first, newsig);
- if (cell->input(mapped_conn.first)) {
- for (auto i : newsig)
- bit2sinks[i].push_back(cell);
- for (auto i : mapped_conn.second)
- bit_users[i].insert(mapped_cell->name);
- }
- if (cell->output(mapped_conn.first))
- for (auto i : mapped_conn.second)
- bit_drivers[i].insert(mapped_cell->name);
- }
- }
-
- if (existing_cell) {
- cell->parameters = existing_cell->parameters;
- cell->attributes = existing_cell->attributes;
- if (cell->attributes.erase("\\abc9_box_seq")) {
- module->swap_names(cell, existing_cell);
- module->remove(existing_cell);
- }
- }
- else {
- cell->parameters = mapped_cell->parameters;
- cell->attributes = mapped_cell->attributes;
- }
+ cell_stats[mapped_cell->type]++;
}
+ for (auto cell : boxes)
+ module->remove(cell);
+
// Copy connections (and rename) from mapped_mod to module
for (auto conn : mapped_mod->connections()) {
if (!conn.first.is_fully_const()) {
@@ -851,6 +844,12 @@ struct Abc9OpsPass : public Pass {
}
extra_args(args, argidx, design);
+ if (!(break_scc_mode || unbreak_scc_mode || prep_dff_mode || reintegrate_mode))
+ log_cmd_error("At least one of -{,un}break_scc, -prep_{dff,holes}, -reintegrate must be specified.\n");
+
+ if (dff_mode && !prep_holes_mode)
+ log_cmd_error("'-dff' option is only relevant for -prep_holes.\n");
+
for (auto mod : design->selected_modules()) {
if (mod->get_bool_attribute("\\abc9_holes"))
continue;
@@ -860,6 +859,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)