aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap
diff options
context:
space:
mode:
authorJim Lawson <ucbjrl@berkeley.edu>2019-04-30 13:19:27 -0700
committerJim Lawson <ucbjrl@berkeley.edu>2019-04-30 13:19:27 -0700
commit58650ffe876d1caedd8ffc9b0207f5cf75eef97b (patch)
tree5389584f1c3ad8c9e9003e78d4b6e22dca5e3a83 /passes/techmap
parent354ba5ba83f7b1fc3bb07aa6bf26dde7a00201d1 (diff)
parente35fe1344dd4c8f11632ed2a7f5b0463352a1ee4 (diff)
downloadyosys-58650ffe876d1caedd8ffc9b0207f5cf75eef97b.tar.gz
yosys-58650ffe876d1caedd8ffc9b0207f5cf75eef97b.tar.bz2
yosys-58650ffe876d1caedd8ffc9b0207f5cf75eef97b.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'passes/techmap')
-rw-r--r--passes/techmap/abc.cc56
-rw-r--r--passes/techmap/attrmap.cc4
-rw-r--r--passes/techmap/dfflibmap.cc2
-rw-r--r--passes/techmap/pmuxtree.cc4
-rw-r--r--passes/techmap/shregmap.cc164
-rw-r--r--passes/techmap/simplemap.cc2
-rw-r--r--passes/techmap/techmap.cc72
7 files changed, 254 insertions, 50 deletions
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index 21b70f492..547115459 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -29,17 +29,17 @@
// Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558-562, doi:10.1145/368996.369025
// http://en.wikipedia.org/wiki/Topological_sorting
-#define ABC_COMMAND_LIB "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put"
-#define ABC_COMMAND_CTR "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put; buffer; upsize {D}; dnsize {D}; stime -p"
-#define ABC_COMMAND_LUT "strash; ifraig; scorr; dc2; dretime; strash; dch -f; if; mfs2"
-#define ABC_COMMAND_SOP "strash; ifraig; scorr; dc2; dretime; strash; dch -f; cover {I} {P}"
-#define ABC_COMMAND_DFL "strash; ifraig; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put"
-
-#define ABC_FAST_COMMAND_LIB "strash; dretime; map {D}"
-#define ABC_FAST_COMMAND_CTR "strash; dretime; map {D}; buffer; upsize {D}; dnsize {D}; stime -p"
-#define ABC_FAST_COMMAND_LUT "strash; dretime; if"
-#define ABC_FAST_COMMAND_SOP "strash; dretime; cover -I {I} -P {P}"
-#define ABC_FAST_COMMAND_DFL "strash; dretime; map"
+#define ABC_COMMAND_LIB "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put"
+#define ABC_COMMAND_CTR "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put; buffer; upsize {D}; dnsize {D}; stime -p"
+#define ABC_COMMAND_LUT "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; dch -f; if; mfs2"
+#define ABC_COMMAND_SOP "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; dch -f; cover {I} {P}"
+#define ABC_COMMAND_DFL "strash; ifraig; scorr; dc2; dretime; retime {D}; strash; &get -n; &dch -f; &nf {D}; &put"
+
+#define ABC_FAST_COMMAND_LIB "strash; dretime; retime {D}; map {D}"
+#define ABC_FAST_COMMAND_CTR "strash; dretime; retime {D}; map {D}; buffer; upsize {D}; dnsize {D}; stime -p"
+#define ABC_FAST_COMMAND_LUT "strash; dretime; retime {D}; if"
+#define ABC_FAST_COMMAND_SOP "strash; dretime; retime {D}; cover -I {I} -P {P}"
+#define ABC_FAST_COMMAND_DFL "strash; dretime; retime {D}; map"
#include "kernel/register.h"
#include "kernel/sigtools.h"
@@ -331,19 +331,23 @@ std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullp
{
std::string abc_sname = abc_name.substr(1);
if (abc_sname.substr(0, 5) == "ys__n") {
- int sid = std::stoi(abc_sname.substr(5));
bool inv = abc_sname.back() == 'v';
- for (auto sig : signal_list) {
- if (sig.id == sid && sig.bit.wire != nullptr) {
- std::stringstream sstr;
- sstr << "$abc$" << map_autoidx << "$" << sig.bit.wire->name.substr(1);
- if (sig.bit.wire->width != 1)
- sstr << "[" << sig.bit.offset << "]";
- if (inv)
- sstr << "_inv";
- if (orig_wire != nullptr)
- *orig_wire = sig.bit.wire;
- return sstr.str();
+ if (inv) abc_sname.pop_back();
+ abc_sname.erase(0, 5);
+ if (abc_sname.find_last_not_of("012345689") == std::string::npos) {
+ int sid = std::stoi(abc_sname);
+ for (auto sig : signal_list) {
+ if (sig.id == sid && sig.bit.wire != nullptr) {
+ std::stringstream sstr;
+ sstr << "$abc$" << map_autoidx << "$" << sig.bit.wire->name.substr(1);
+ if (sig.bit.wire->width != 1)
+ sstr << "[" << sig.bit.offset << "]";
+ if (inv)
+ sstr << "_inv";
+ if (orig_wire != nullptr)
+ *orig_wire = sig.bit.wire;
+ return sstr.str();
+ }
}
}
}
@@ -731,10 +735,6 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
else
abc_script += fast_mode ? ABC_FAST_COMMAND_DFL : ABC_COMMAND_DFL;
- if (script_file.empty() && !delay_target.empty())
- for (size_t pos = abc_script.find("dretime;"); pos != std::string::npos; pos = abc_script.find("dretime;", pos+1))
- abc_script = abc_script.substr(0, pos) + "dretime; retime -o {D};" + abc_script.substr(pos+8);
-
for (size_t pos = abc_script.find("{D}"); pos != std::string::npos; pos = abc_script.find("{D}", pos))
abc_script = abc_script.substr(0, pos) + delay_target + abc_script.substr(pos+3);
@@ -1726,7 +1726,7 @@ struct AbcPass : public Pass {
signal_init[initsig[i]] = State::S0;
break;
case State::S1:
- signal_init[initsig[i]] = State::S0;
+ signal_init[initsig[i]] = State::S1;
break;
default:
break;
diff --git a/passes/techmap/attrmap.cc b/passes/techmap/attrmap.cc
index 0b5576b06..aa48e1125 100644
--- a/passes/techmap/attrmap.cc
+++ b/passes/techmap/attrmap.cc
@@ -111,9 +111,10 @@ struct AttrmapMap : AttrmapAction {
};
struct AttrmapRemove : AttrmapAction {
+ bool has_value;
string name, value;
bool apply(IdString &id, Const &val) YS_OVERRIDE {
- return !(match_name(name, id) && match_value(value, val));
+ return !(match_name(name, id) && (!has_value || match_value(value, val)));
}
};
@@ -235,6 +236,7 @@ struct AttrmapPass : public Pass {
}
auto action = new AttrmapRemove;
action->name = arg1;
+ action->has_value = (p != string::npos);
action->value = val1;
actions.push_back(std::unique_ptr<AttrmapAction>(action));
continue;
diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc
index 274177a68..b5c0498d0 100644
--- a/passes/techmap/dfflibmap.cc
+++ b/passes/techmap/dfflibmap.cc
@@ -664,7 +664,7 @@ struct DfflibmapPass : public Pass {
logmap_all();
for (auto &it : design->modules_)
- if (design->selected(it.second) && !it.second->get_bool_attribute("\\blackbox"))
+ if (design->selected(it.second) && !it.second->get_blackbox_attribute())
dfflibmap(design, it.second, prepare_mode);
cell_mappings.clear();
diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc
index b7a22dc3b..6a923f481 100644
--- a/passes/techmap/pmuxtree.cc
+++ b/passes/techmap/pmuxtree.cc
@@ -71,9 +71,9 @@ struct PmuxtreePass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" pmuxtree [options] [selection]\n");
+ log(" pmuxtree [selection]\n");
log("\n");
- log("This pass transforms $pmux cells to a trees of $mux cells.\n");
+ log("This pass transforms $pmux cells to trees of $mux cells.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc
index f20863ba0..a541b33be 100644
--- a/passes/techmap/shregmap.cc
+++ b/passes/techmap/shregmap.cc
@@ -26,7 +26,9 @@ PRIVATE_NAMESPACE_BEGIN
struct ShregmapTech
{
virtual ~ShregmapTech() { }
- virtual bool analyze(vector<int> &taps) = 0;
+ virtual void init(const Module * /*module*/, const SigMap &/*sigmap*/) {}
+ virtual void non_chain_user(const SigBit &/*bit*/, const Cell* /*cell*/, IdString /*port*/) {}
+ virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) = 0;
virtual bool fixup(Cell *cell, dict<int, SigBit> &taps) = 0;
};
@@ -54,7 +56,7 @@ struct ShregmapOptions
struct ShregmapTechGreenpak4 : ShregmapTech
{
- bool analyze(vector<int> &taps)
+ bool analyze(vector<int> &taps, const vector<SigBit> &/*qbits*/)
{
if (GetSize(taps) > 2 && taps[0] == 0 && taps[2] < 17) {
taps.clear();
@@ -91,6 +93,145 @@ struct ShregmapTechGreenpak4 : ShregmapTech
}
};
+struct ShregmapTechXilinx7 : ShregmapTech
+{
+ dict<SigBit, std::tuple<Cell*,int,int>> sigbit_to_shiftx_offset;
+ const ShregmapOptions &opts;
+
+ ShregmapTechXilinx7(const ShregmapOptions &opts) : opts(opts) {}
+
+ virtual void init(const Module* module, const SigMap &sigmap) override
+ {
+ for (const auto &i : module->cells_) {
+ auto cell = i.second;
+ if (cell->type == "$shiftx") {
+ if (cell->getParam("\\Y_WIDTH") != 1) continue;
+ int j = 0;
+ for (auto bit : sigmap(cell->getPort("\\A")))
+ sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j++, 0);
+ log_assert(j == cell->getParam("\\A_WIDTH").as_int());
+ }
+ else if (cell->type == "$mux") {
+ int j = 0;
+ for (auto bit : sigmap(cell->getPort("\\A")))
+ sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++);
+ j = 0;
+ for (auto bit : sigmap(cell->getPort("\\B")))
+ sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 1, j++);
+ }
+ }
+ }
+
+ virtual void non_chain_user(const SigBit &bit, const Cell *cell, IdString port) override
+ {
+ auto it = sigbit_to_shiftx_offset.find(bit);
+ if (it == sigbit_to_shiftx_offset.end())
+ return;
+ if (cell) {
+ if (cell->type == "$shiftx" && port == "\\A")
+ return;
+ if (cell->type == "$mux" && (port == "\\A" || port == "\\B"))
+ return;
+ }
+ sigbit_to_shiftx_offset.erase(it);
+ }
+
+ virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) override
+ {
+ if (GetSize(taps) == 1)
+ return taps[0] >= opts.minlen-1 && sigbit_to_shiftx_offset.count(qbits[0]);
+
+ if (taps.back() < opts.minlen-1)
+ return false;
+
+ Cell *shiftx = nullptr;
+ int group = 0;
+ for (int i = 0; i < GetSize(taps); ++i) {
+ auto it = sigbit_to_shiftx_offset.find(qbits[i]);
+ if (it == sigbit_to_shiftx_offset.end())
+ return false;
+
+ // Check taps are sequential
+ if (i != taps[i])
+ return false;
+ // Check taps are not connected to a shift register,
+ // or sequential to the same shift register
+ if (i == 0) {
+ int offset;
+ std::tie(shiftx,offset,group) = it->second;
+ if (offset != i)
+ return false;
+ }
+ else {
+ Cell *shiftx_ = std::get<0>(it->second);
+ if (shiftx_ != shiftx)
+ return false;
+ int offset = std::get<1>(it->second);
+ if (offset != i)
+ return false;
+ int group_ = std::get<2>(it->second);
+ if (group_ != group)
+ return false;
+ }
+ }
+ log_assert(shiftx);
+
+ // Only map if $shiftx exclusively covers the shift register
+ if (shiftx->type == "$shiftx") {
+ if (GetSize(taps) != shiftx->getParam("\\A_WIDTH").as_int())
+ return false;
+ }
+ else if (shiftx->type == "$mux") {
+ if (GetSize(taps) != 2)
+ return false;
+ }
+ else log_abort();
+
+ return true;
+ }
+
+ virtual bool fixup(Cell *cell, dict<int, SigBit> &taps) override
+ {
+ const auto &tap = *taps.begin();
+ auto bit = tap.second;
+
+ auto it = sigbit_to_shiftx_offset.find(bit);
+ log_assert(it != sigbit_to_shiftx_offset.end());
+
+ auto newcell = cell->module->addCell(NEW_ID, "$__XILINX_SHREG_");
+ newcell->set_src_attribute(cell->get_src_attribute());
+ newcell->setParam("\\DEPTH", cell->getParam("\\DEPTH"));
+ newcell->setParam("\\INIT", cell->getParam("\\INIT"));
+ newcell->setParam("\\CLKPOL", cell->getParam("\\CLKPOL"));
+ newcell->setParam("\\ENPOL", cell->getParam("\\ENPOL"));
+
+ newcell->setPort("\\C", cell->getPort("\\C"));
+ newcell->setPort("\\D", cell->getPort("\\D"));
+ if (cell->hasPort("\\E"))
+ newcell->setPort("\\E", cell->getPort("\\E"));
+
+ Cell* shiftx = std::get<0>(it->second);
+ RTLIL::SigSpec l_wire, q_wire;
+ if (shiftx->type == "$shiftx") {
+ l_wire = shiftx->getPort("\\B");
+ q_wire = shiftx->getPort("\\Y");
+ shiftx->setPort("\\Y", cell->module->addWire(NEW_ID));
+ }
+ else if (shiftx->type == "$mux") {
+ l_wire = shiftx->getPort("\\S");
+ q_wire = shiftx->getPort("\\Y");
+ shiftx->setPort("\\Y", cell->module->addWire(NEW_ID));
+ }
+ else log_abort();
+
+ newcell->setPort("\\Q", q_wire);
+ newcell->setPort("\\L", l_wire);
+
+ return false;
+ }
+};
+
+
struct ShregmapWorker
{
Module *module;
@@ -113,8 +254,10 @@ struct ShregmapWorker
for (auto wire : module->wires())
{
if (wire->port_output || wire->get_bool_attribute("\\keep")) {
- for (auto bit : sigmap(wire))
+ for (auto bit : sigmap(wire)) {
sigbit_with_non_chain_users.insert(bit);
+ if (opts.tech) opts.tech->non_chain_user(bit, nullptr, {});
+ }
}
if (wire->attributes.count("\\init")) {
@@ -152,8 +295,10 @@ struct ShregmapWorker
for (auto conn : cell->connections())
if (cell->input(conn.first))
- for (auto bit : sigmap(conn.second))
+ for (auto bit : sigmap(conn.second)) {
sigbit_with_non_chain_users.insert(bit);
+ if (opts.tech) opts.tech->non_chain_user(bit, cell, conn.first);
+ }
}
}
@@ -258,7 +403,7 @@ struct ShregmapWorker
if (taps.empty() || taps.back() < depth-1)
taps.push_back(depth-1);
- if (opts.tech->analyze(taps))
+ if (opts.tech->analyze(taps, qbits))
break;
taps.pop_back();
@@ -377,6 +522,9 @@ struct ShregmapWorker
ShregmapWorker(Module *module, const ShregmapOptions &opts) :
module(module), sigmap(module), opts(opts), dff_count(0), shreg_count(0)
{
+ if (opts.tech)
+ opts.tech->init(module, sigmap);
+
make_sigbit_chain_next_prev();
find_chain_start_cells();
@@ -501,6 +649,12 @@ struct ShregmapPass : public Pass {
clkpol = "pos";
opts.zinit = true;
opts.tech = new ShregmapTechGreenpak4;
+ }
+ else if (tech == "xilinx") {
+ opts.init = true;
+ opts.params = true;
+ enpol = "any_or_none";
+ opts.tech = new ShregmapTechXilinx7(opts);
} else {
argidx--;
break;
diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc
index 660b60601..f3da80c66 100644
--- a/passes/techmap/simplemap.cc
+++ b/passes/techmap/simplemap.cc
@@ -599,7 +599,7 @@ struct SimplemapPass : public Pass {
simplemap_get_mappers(mappers);
for (auto mod : design->modules()) {
- if (!design->selected(mod))
+ if (!design->selected(mod) || mod->get_blackbox_attribute())
continue;
std::vector<RTLIL::Cell*> cells = mod->cells();
for (auto cell : cells) {
diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc
index d0e5e2236..ab0bd3b54 100644
--- a/passes/techmap/techmap.cc
+++ b/passes/techmap/techmap.cc
@@ -72,6 +72,8 @@ struct TechmapWorker
pool<IdString> flatten_done_list;
pool<Cell*> flatten_keep_list;
+ pool<string> log_msg_cache;
+
struct TechmapWireData {
RTLIL::Wire *wire;
RTLIL::SigSpec value;
@@ -84,6 +86,7 @@ struct TechmapWorker
bool flatten_mode;
bool recursive_mode;
bool autoproc_mode;
+ bool ignore_wb;
TechmapWorker()
{
@@ -92,6 +95,7 @@ struct TechmapWorker
flatten_mode = false;
recursive_mode = false;
autoproc_mode = false;
+ ignore_wb = false;
}
std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose)
@@ -383,11 +387,12 @@ struct TechmapWorker
{
std::string mapmsg_prefix = in_recursion ? "Recursively mapping" : "Mapping";
- if (!design->selected(module))
+ if (!design->selected(module) || module->get_blackbox_attribute(ignore_wb))
return false;
bool log_continue = false;
bool did_something = false;
+ LogMakeDebugHdl mkdebug;
SigMap sigmap(module);
@@ -472,7 +477,7 @@ struct TechmapWorker
RTLIL::Module *tpl = map->modules_[tpl_name];
std::map<RTLIL::IdString, RTLIL::Const> parameters(cell->parameters.begin(), cell->parameters.end());
- if (tpl->get_bool_attribute("\\blackbox"))
+ if (tpl->get_blackbox_attribute(ignore_wb))
continue;
if (!flatten_mode)
@@ -545,6 +550,7 @@ struct TechmapWorker
if (extmapper_name == "wrap") {
std::string cmd_string = tpl->attributes.at("\\techmap_wrap").decode_string();
log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module));
+ mkdebug.on();
Pass::call_on_module(extmapper_design, extmapper_module, cmd_string);
log_continue = true;
}
@@ -558,11 +564,21 @@ struct TechmapWorker
goto use_wrapper_tpl;
}
- log("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module));
+ auto msg = stringf("Using extmapper %s for cells of type %s.", log_id(extmapper_module), log_id(cell->type));
+ if (!log_msg_cache.count(msg)) {
+ log_msg_cache.insert(msg);
+ log("%s\n", msg.c_str());
+ }
+ log_debug("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module));
}
else
{
- log("%s %s.%s (%s) with %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), extmapper_name.c_str());
+ auto msg = stringf("Using extmapper %s for cells of type %s.", extmapper_name.c_str(), log_id(cell->type));
+ if (!log_msg_cache.count(msg)) {
+ log_msg_cache.insert(msg);
+ log("%s\n", msg.c_str());
+ }
+ log_debug("%s %s.%s (%s) with %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), extmapper_name.c_str());
if (extmapper_name == "simplemap") {
if (simplemap_mappers.count(cell->type) == 0)
@@ -660,6 +676,7 @@ struct TechmapWorker
tpl = techmap_cache[key];
} else {
if (parameters.size() != 0) {
+ mkdebug.on();
derived_name = tpl->derive(map, dict<RTLIL::IdString, RTLIL::Const>(parameters.begin(), parameters.end()));
tpl = map->module(derived_name);
log_continue = true;
@@ -829,6 +846,7 @@ struct TechmapWorker
if (log_continue) {
log_header(design, "Continuing TECHMAP pass.\n");
log_continue = false;
+ mkdebug.off();
}
while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) { }
}
@@ -840,6 +858,7 @@ struct TechmapWorker
if (log_continue) {
log_header(design, "Continuing TECHMAP pass.\n");
log_continue = false;
+ mkdebug.off();
}
if (extern_mode && !in_recursion)
@@ -859,13 +878,18 @@ struct TechmapWorker
module_queue.insert(m);
}
- log("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(m_name));
+ log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(m_name));
cell->type = m_name;
cell->parameters.clear();
}
else
{
- log("%s %s.%s using %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(tpl));
+ auto msg = stringf("Using template %s for cells of type %s.", log_id(tpl), log_id(cell->type));
+ if (!log_msg_cache.count(msg)) {
+ log_msg_cache.insert(msg);
+ log("%s\n", msg.c_str());
+ }
+ log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(tpl));
techmap_module_worker(design, module, cell, tpl);
cell = NULL;
}
@@ -883,6 +907,7 @@ struct TechmapWorker
if (log_continue) {
log_header(design, "Continuing TECHMAP pass.\n");
log_continue = false;
+ mkdebug.off();
}
return did_something;
@@ -925,6 +950,9 @@ struct TechmapPass : public Pass {
log(" -autoproc\n");
log(" Automatically call \"proc\" on implementations that contain processes.\n");
log("\n");
+ log(" -wb\n");
+ log(" Ignore the 'whitebox' attribute on cell implementations.\n");
+ log("\n");
log(" -assert\n");
log(" this option will cause techmap to exit with an error if it can't map\n");
log(" a selected cell. only cell types that end on an underscore are accepted\n");
@@ -1031,7 +1059,7 @@ struct TechmapPass : public Pass {
simplemap_get_mappers(worker.simplemap_mappers);
std::vector<std::string> map_files;
- std::string verilog_frontend = "verilog -nooverwrite";
+ std::string verilog_frontend = "verilog -nooverwrite -noblackbox";
int max_iter = -1;
size_t argidx;
@@ -1068,6 +1096,10 @@ struct TechmapPass : public Pass {
worker.autoproc_mode = true;
continue;
}
+ if (args[argidx] == "-wb") {
+ worker.ignore_wb = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -1076,7 +1108,7 @@ struct TechmapPass : public Pass {
if (map_files.empty()) {
std::istringstream f(stdcells_code);
Frontend::frontend_call(map, &f, "<techmap.v>", verilog_frontend);
- } else
+ } else {
for (auto &fn : map_files)
if (fn.substr(0, 1) == "%") {
if (!saved_designs.count(fn.substr(1))) {
@@ -1095,6 +1127,9 @@ struct TechmapPass : public Pass {
log_cmd_error("Can't open map file `%s'\n", fn.c_str());
Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend);
}
+ }
+
+ log_header(design, "Continuing TECHMAP pass.\n");
std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
for (auto &it : map->modules_) {
@@ -1145,7 +1180,7 @@ struct FlattenPass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" flatten [selection]\n");
+ log(" flatten [options] [selection]\n");
log("\n");
log("This pass flattens the design by replacing cells by their implementation. This\n");
log("pass is very similar to the 'techmap' pass. The only difference is that this\n");
@@ -1154,17 +1189,29 @@ struct FlattenPass : public Pass {
log("Cells and/or modules with the 'keep_hierarchy' attribute set will not be\n");
log("flattened by this command.\n");
log("\n");
+ log(" -wb\n");
+ log(" Ignore the 'whitebox' attribute on cell implementations.\n");
+ log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing FLATTEN pass (flatten design).\n");
log_push();
- extra_args(args, 1, design);
-
TechmapWorker worker;
worker.flatten_mode = true;
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ if (args[argidx] == "-wb") {
+ worker.ignore_wb = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+
std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
for (auto module : design->modules())
celltypeMap[module->name].insert(module->name);
@@ -1190,6 +1237,7 @@ struct FlattenPass : public Pass {
}
}
+ log_suppressed();
log("No more expansions possible.\n");
if (top_mod != NULL)
@@ -1209,7 +1257,7 @@ struct FlattenPass : public Pass {
dict<RTLIL::IdString, RTLIL::Module*> new_modules;
for (auto mod : vector<Module*>(design->modules()))
- if (used_modules[mod->name] || mod->get_bool_attribute("\\blackbox")) {
+ if (used_modules[mod->name] || mod->get_blackbox_attribute(worker.ignore_wb)) {
new_modules[mod->name] = mod;
} else {
log("Deleting now unused module %s.\n", log_id(mod));