diff options
author | Eddie Hung <eddie@fpgeh.com> | 2020-01-11 13:56:41 -0800 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2020-01-11 13:56:41 -0800 |
commit | 11128dccb53983e7bb784cf2514edcaa6eb822fb (patch) | |
tree | 0cdf181b2b00302543a5eed54dd6453b2ce9a114 /passes/techmap | |
parent | 88f14b8bca811a3945aa642ccd50d22ffa0adcbd (diff) | |
parent | 784fec93c901caa6f9d980388356d120b0cdfea9 (diff) | |
download | yosys-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.cc | 20 | ||||
-rw-r--r-- | passes/techmap/abc9_exe.cc | 15 | ||||
-rw-r--r-- | passes/techmap/abc9_ops.cc | 154 |
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) |