diff options
author | Marcelina KoĆcielnicka <mwk@0x04.net> | 2020-03-02 21:40:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-02 21:40:09 +0100 |
commit | 968956badb977984133b00c38d0a08f3e2d0b854 (patch) | |
tree | 08e308cfa903dc4e7f706ce627fd60bdc2d3b5bc /passes/techmap | |
parent | 4f889b2f57b732083dd4bf336a0d361f70e5b2d0 (diff) | |
download | yosys-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.cc | 68 |
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)) |