aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2020-03-02 21:40:09 +0100
committerGitHub <noreply@github.com>2020-03-02 21:40:09 +0100
commit968956badb977984133b00c38d0a08f3e2d0b854 (patch)
tree08e308cfa903dc4e7f706ce627fd60bdc2d3b5bc /passes/techmap
parent4f889b2f57b732083dd4bf336a0d361f70e5b2d0 (diff)
downloadyosys-968956badb977984133b00c38d0a08f3e2d0b854.tar.gz
yosys-968956badb977984133b00c38d0a08f3e2d0b854.tar.bz2
yosys-968956badb977984133b00c38d0a08f3e2d0b854.zip
iopadmap: Look harder for already-present buffers. (#1731)
iopadmap: Look harder for already-present buffers. Fixes #1720.
Diffstat (limited to 'passes/techmap')
-rw-r--r--passes/techmap/iopadmap.cc68
1 files changed, 54 insertions, 14 deletions
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc
index a6e4fac14..f63012d1a 100644
--- a/passes/techmap/iopadmap.cc
+++ b/passes/techmap/iopadmap.cc
@@ -83,6 +83,20 @@ struct IopadmapPass : public Pass {
log("Tristate PADS (-toutpad, -tinoutpad) always operate in -bits mode.\n");
log("\n");
}
+
+ void module_queue(Design *design, Module *module, std::vector<Module *> &modules_sorted, pool<Module *> &modules_processed) {
+ if (modules_processed.count(module))
+ return;
+ for (auto cell : module->cells()) {
+ Module *submodule = design->module(cell->type);
+ if (!submodule)
+ continue;
+ module_queue(design, submodule, modules_sorted, modules_processed);
+ }
+ modules_sorted.push_back(module);
+ modules_processed.insert(module);
+ }
+
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n");
@@ -172,22 +186,49 @@ struct IopadmapPass : public Pass {
if (!tinoutpad_portname_pad.empty())
ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname_pad)));
- for (auto module : design->modules())
- if (module->get_blackbox_attribute())
- for (auto wire : module->wires())
- if (wire->get_bool_attribute("\\iopad_external_pin"))
- ignore.insert(make_pair(module->name, wire->name));
+ // Recursively collect list of (module, port, bit) triples that already have buffers.
+ pool<pair<IdString, pair<IdString, int>>> buf_ports;
+
+ // Process submodules before module using them.
+ std::vector<Module *> modules_sorted;
+ pool<Module *> modules_processed;
for (auto module : design->selected_modules())
+ module_queue(design, module, modules_sorted, modules_processed);
+
+ for (auto module : modules_sorted)
{
- pool<SigBit> skip_wire_bits;
- dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
+ pool<SigBit> buf_bits;
+ SigMap sigmap(module);
+
+ // Collect explicitly-marked already-buffered SigBits.
+ for (auto wire : module->wires())
+ if (wire->get_bool_attribute("\\iopad_external_pin") || ignore.count(make_pair(module->name, wire->name)))
+ for (int i = 0; i < GetSize(wire); i++)
+ buf_bits.insert(sigmap(SigBit(wire, i)));
+ // Collect SigBits connected to already-buffered ports.
for (auto cell : module->cells())
for (auto port : cell->connections())
- if (ignore.count(make_pair(cell->type, port.first)))
- for (auto bit : port.second)
- skip_wire_bits.insert(bit);
+ for (int i = 0; i < port.second.size(); i++)
+ if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i))))
+ buf_bits.insert(sigmap(port.second[i]));
+
+ // Now fill buf_ports.
+ for (auto wire : module->wires())
+ if (wire->port_input || wire->port_output)
+ for (int i = 0; i < GetSize(wire); i++)
+ if (buf_bits.count(sigmap(SigBit(wire, i)))) {
+ buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
+ log("Marking already mapped port: %s.%s[%d].\n", log_id(module), log_id(wire), i);
+ }
+ }
+
+ // Now do the actual buffer insertion.
+
+ for (auto module : design->selected_modules())
+ {
+ dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
{
@@ -234,7 +275,7 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
Cell *tbuf_cell = nullptr;
- if (skip_wire_bits.count(wire_bit))
+ if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i))))
continue;
if (tbuf_bits.count(wire_bit))
@@ -282,7 +323,6 @@ struct IopadmapPass : public Pass {
cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit);
cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig);
}
- skip_wire_bits.insert(wire_bit);
if (!tinoutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad));
} else {
@@ -298,10 +338,10 @@ struct IopadmapPass : public Pass {
module->remove(tbuf_cell);
module->connect(wire_bit, data_sig);
}
- skip_wire_bits.insert(wire_bit);
if (!toutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad));
}
+ buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
}
}
}
@@ -315,7 +355,7 @@ struct IopadmapPass : public Pass {
pool<int> skip_bit_indices;
for (int i = 0; i < GetSize(wire); i++)
- if (skip_wire_bits.count(SigBit(wire, i)))
+ if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i))))
skip_bit_indices.insert(i);
if (GetSize(wire) == GetSize(skip_bit_indices))