diff options
author | Eddie Hung <eddie@fpgeh.com> | 2020-01-27 10:34:10 -0800 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2020-01-27 10:34:10 -0800 |
commit | f443695a38fbdd8c2ca38cab45ca964a173dc158 (patch) | |
tree | 4ac13e4fe8ee5e71f963c4230f9f26f32901c2ba /passes/techmap/clkbufmap.cc | |
parent | d730bba6d2847515795c32d3a753320b8b48bee0 (diff) | |
parent | da6abc014987ef562a577dc374bcb03aad9256cd (diff) | |
download | yosys-f443695a38fbdd8c2ca38cab45ca964a173dc158.tar.gz yosys-f443695a38fbdd8c2ca38cab45ca964a173dc158.tar.bz2 yosys-f443695a38fbdd8c2ca38cab45ca964a173dc158.zip |
Merge remote-tracking branch 'origin/master' into eddie/verific_help
Diffstat (limited to 'passes/techmap/clkbufmap.cc')
-rw-r--r-- | passes/techmap/clkbufmap.cc | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc index 246932d81..b9cd68883 100644 --- a/passes/techmap/clkbufmap.cc +++ b/passes/techmap/clkbufmap.cc @@ -115,6 +115,8 @@ struct ClkbufmapPass : public Pass { // Cell type, port name, bit index. pool<pair<IdString, pair<IdString, int>>> sink_ports; pool<pair<IdString, pair<IdString, int>>> buf_ports; + dict<pair<IdString, pair<IdString, int>>, pair<IdString, int>> inv_ports_out; + dict<pair<IdString, pair<IdString, int>>, pair<IdString, int>> inv_ports_in; // Process submodules before module using them. std::vector<Module *> modules_sorted; @@ -133,6 +135,14 @@ struct ClkbufmapPass : public Pass { if (wire->get_bool_attribute("\\clkbuf_sink")) for (int i = 0; i < GetSize(wire); i++) sink_ports.insert(make_pair(module->name, make_pair(wire->name, i))); + auto it = wire->attributes.find("\\clkbuf_inv"); + if (it != wire->attributes.end()) { + IdString in_name = RTLIL::escape_id(it->second.decode_string()); + for (int i = 0; i < GetSize(wire); i++) { + inv_ports_out[make_pair(module->name, make_pair(wire->name, i))] = make_pair(in_name, i); + inv_ports_in[make_pair(module->name, make_pair(in_name, i))] = make_pair(wire->name, i); + } + } } continue; } @@ -157,6 +167,37 @@ struct ClkbufmapPass : public Pass { if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i)))) buf_wire_bits.insert(sigmap(port.second[i])); + // Third, propagate tags through inverters. + bool retry = true; + while (retry) { + retry = false; + for (auto cell : module->cells()) + for (auto port : cell->connections()) + for (int i = 0; i < port.second.size(); i++) { + auto it = inv_ports_out.find(make_pair(cell->type, make_pair(port.first, i))); + auto bit = sigmap(port.second[i]); + // If output of an inverter is connected to a sink, mark it as buffered, + // and request a buffer on the inverter's input instead. + if (it != inv_ports_out.end() && !buf_wire_bits.count(bit) && sink_wire_bits.count(bit)) { + buf_wire_bits.insert(bit); + auto other_bit = sigmap(cell->getPort(it->second.first)[it->second.second]); + sink_wire_bits.insert(other_bit); + retry = true; + } + // If input of an inverter is marked as already-buffered, + // mark its output already-buffered as well. + auto it2 = inv_ports_in.find(make_pair(cell->type, make_pair(port.first, i))); + if (it2 != inv_ports_in.end() && buf_wire_bits.count(bit)) { + auto other_bit = sigmap(cell->getPort(it2->second.first)[it2->second.second]); + if (!buf_wire_bits.count(other_bit)) { + buf_wire_bits.insert(other_bit); + retry = true; + } + } + + } + }; + // Collect all driven bits. for (auto cell : module->cells()) for (auto port : cell->connections()) |