aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap
diff options
context:
space:
mode:
Diffstat (limited to 'passes/techmap')
-rw-r--r--passes/techmap/abc.cc32
-rw-r--r--passes/techmap/deminout.cc32
-rw-r--r--passes/techmap/iopadmap.cc57
3 files changed, 111 insertions, 10 deletions
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index 009ba6b97..18868c6d7 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -60,6 +60,10 @@
#include "frontends/blif/blifparse.h"
+#ifdef YOSYS_LINK_ABC
+extern "C" int Abc_RealMain(int argc, char *argv[]);
+#endif
+
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@@ -546,11 +550,13 @@ std::string replace_tempdir(std::string text, std::string tempdir_name, bool sho
}
std::string selfdir_name = proc_self_dirname();
- while (1) {
- size_t pos = text.find(selfdir_name);
- if (pos == std::string::npos)
- break;
- text = text.substr(0, pos) + "<yosys-exe-dir>/" + text.substr(pos + GetSize(selfdir_name));
+ if (selfdir_name != "/") {
+ while (1) {
+ size_t pos = text.find(selfdir_name);
+ if (pos == std::string::npos)
+ break;
+ text = text.substr(0, pos) + "<yosys-exe-dir>/" + text.substr(pos + GetSize(selfdir_name));
+ }
}
return text;
@@ -943,8 +949,24 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
buffer = stringf("%s -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str());
log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str());
+#ifndef YOSYS_LINK_ABC
abc_output_filter filt(tempdir_name, show_tempdir);
int ret = run_command(buffer, std::bind(&abc_output_filter::next_line, filt, std::placeholders::_1));
+#else
+ // These needs to be mutable, supposedly due to getopt
+ char *abc_argv[5];
+ string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str());
+ abc_argv[0] = strdup(exe_file.c_str());
+ abc_argv[1] = strdup("-s");
+ abc_argv[2] = strdup("-f");
+ abc_argv[3] = strdup(tmp_script_name.c_str());
+ abc_argv[4] = 0;
+ int ret = Abc_RealMain(4, abc_argv);
+ free(abc_argv[0]);
+ free(abc_argv[1]);
+ free(abc_argv[2]);
+ free(abc_argv[3]);
+#endif
if (ret != 0)
log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret);
diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc
index ed4e45762..0b8fd5246 100644
--- a/passes/techmap/deminout.cc
+++ b/passes/techmap/deminout.cc
@@ -57,7 +57,7 @@ struct DeminoutPass : public Pass {
for (auto module : design->selected_modules())
{
SigMap sigmap(module);
- pool<SigBit> bits_written, bits_used, bits_inout;
+ pool<SigBit> bits_written, bits_used, bits_inout, bits_tribuf;
dict<SigBit, int> bits_numports;
for (auto wire : module->wires())
@@ -82,6 +82,25 @@ struct DeminoutPass : public Pass {
if (cellport_in)
for (auto bit : sigmap(conn.second))
bits_used.insert(bit);
+
+ if (conn.first == "\\Y" && cell->type.in("$mux", "$pmux", "$_MUX_", "$_TBUF_"))
+ {
+ bool tribuf = (cell->type == "$_TBUF_");
+
+ if (!tribuf) {
+ for (auto &c : cell->connections()) {
+ if (!c.first.in("\\A", "\\B"))
+ continue;
+ for (auto b : sigmap(c.second))
+ if (b == State::Sz)
+ tribuf = true;
+ }
+ }
+
+ if (tribuf)
+ for (auto bit : sigmap(conn.second))
+ bits_tribuf.insert(bit);
+ }
}
for (auto wire : module->selected_wires())
@@ -95,10 +114,15 @@ struct DeminoutPass : public Pass {
if (bits_numports[bit] > 1 || bits_inout.count(bit))
new_input = true, new_output = true;
- if (bits_written.count(bit))
+ if (bits_written.count(bit)) {
new_output = true;
- else if (bits_used.count(bit))
- new_input = true;
+ if (bits_tribuf.count(bit))
+ goto tribuf_bit;
+ } else {
+ tribuf_bit:
+ if (bits_used.count(bit))
+ new_input = true;
+ }
}
if (new_input != new_output) {
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc
index 4acbf7c0d..690ba87ed 100644
--- a/passes/techmap/iopadmap.cc
+++ b/passes/techmap/iopadmap.cc
@@ -146,11 +146,37 @@ struct IopadmapPass : public Pass {
for (auto module : design->selected_modules())
{
dict<IdString, pool<int>> skip_wires;
+ pool<SigBit> skip_wire_bits;
+ SigMap sigmap(module);
+
+ for (auto cell : module->cells())
+ {
+ if (cell->type == RTLIL::escape_id(inpad_celltype) && cell->hasPort(RTLIL::escape_id(inpad_portname2)))
+ for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(inpad_portname2))))
+ skip_wire_bits.insert(bit);
+
+ if (cell->type == RTLIL::escape_id(outpad_celltype) && cell->hasPort(RTLIL::escape_id(outpad_portname2)))
+ for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(outpad_portname2))))
+ skip_wire_bits.insert(bit);
+
+ if (cell->type == RTLIL::escape_id(inoutpad_celltype) && cell->hasPort(RTLIL::escape_id(inoutpad_portname2)))
+ for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(inoutpad_portname2))))
+ skip_wire_bits.insert(bit);
+
+ if (cell->type == RTLIL::escape_id(toutpad_celltype) && cell->hasPort(RTLIL::escape_id(toutpad_portname3)))
+ for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(toutpad_portname3))))
+ skip_wire_bits.insert(bit);
+
+ if (cell->type == RTLIL::escape_id(tinoutpad_celltype) && cell->hasPort(RTLIL::escape_id(tinoutpad_portname4)))
+ for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(tinoutpad_portname4))))
+ skip_wire_bits.insert(bit);
+ }
if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
{
- SigMap sigmap(module);
dict<SigBit, pair<IdString, pool<IdString>>> tbuf_bits;
+ pool<pair<IdString, IdString>> norewrites;
+ SigMap rewrites;
for (auto cell : module->cells())
if (cell->type == "$_TBUF_") {
@@ -177,6 +203,9 @@ struct IopadmapPass : public Pass {
if (tbuf_bits.count(mapped_wire_bit) == 0)
continue;
+ if (skip_wire_bits.count(mapped_wire_bit))
+ continue;
+
auto &tbuf_cache = tbuf_bits.at(mapped_wire_bit);
Cell *tbuf_cell = module->cell(tbuf_cache.first);
@@ -219,6 +248,9 @@ struct IopadmapPass : public Pass {
module->remove(tbuf_cell);
skip_wires[wire->name].insert(i);
+
+ norewrites.insert(make_pair(cell->name, RTLIL::escape_id(tinoutpad_portname4)));
+ rewrites.add(sigmap(wire_bit), owire);
continue;
}
@@ -256,6 +288,22 @@ struct IopadmapPass : public Pass {
}
}
}
+
+ if (GetSize(norewrites))
+ {
+ for (auto cell : module->cells())
+ for (auto port : cell->connections())
+ {
+ if (norewrites.count(make_pair(cell->name, port.first)))
+ continue;
+
+ SigSpec orig_sig = sigmap(port.second);
+ SigSpec new_sig = rewrites(orig_sig);
+
+ if (orig_sig != new_sig)
+ cell->setPort(port.first, new_sig);
+ }
+ }
}
for (auto wire : module->selected_wires())
@@ -272,6 +320,13 @@ struct IopadmapPass : public Pass {
skip_bit_indices = skip_wires.at(wire->name);
}
+ for (int i = 0; i < GetSize(wire); i++)
+ if (skip_wire_bits.count(sigmap(SigBit(wire, i))))
+ skip_bit_indices.insert(i);
+
+ if (GetSize(wire) == GetSize(skip_bit_indices))
+ continue;
+
if (wire->port_input && !wire->port_output) {
if (inpad_celltype.empty()) {
log("Don't map input port %s.%s: Missing option -inpad.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name));