diff options
author | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-11-09 11:22:48 +0100 |
---|---|---|
committer | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-11-09 15:40:16 +0100 |
commit | 15b0d717ed658b342ce5f74df5a65827eed04a94 (patch) | |
tree | e9dfb025526ea0f1fbddf705987872fc889a951c /passes/techmap/iopadmap.cc | |
parent | 4871d8f19911dc48bf7726519437be8a821c0a1f (diff) | |
download | yosys-15b0d717ed658b342ce5f74df5a65827eed04a94.tar.gz yosys-15b0d717ed658b342ce5f74df5a65827eed04a94.tar.bz2 yosys-15b0d717ed658b342ce5f74df5a65827eed04a94.zip |
iopadmap: Add native support for negative-polarity output enable.
Diffstat (limited to 'passes/techmap/iopadmap.cc')
-rw-r--r-- | passes/techmap/iopadmap.cc | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 45fa5f226..ce1988c49 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -43,26 +43,28 @@ struct IopadmapPass : public Pass { log("can only map to very simple PAD cells. Use 'techmap' to further map\n"); log("the resulting cells to more sophisticated PAD cells.\n"); log("\n"); - log(" -inpad <celltype> <portname>[:<portname>]\n"); + log(" -inpad <celltype> <in_port>[:<ext_port>]\n"); log(" Map module input ports to the given cell type with the\n"); log(" given output port name. if a 2nd portname is given, the\n"); log(" signal is passed through the pad call, using the 2nd\n"); log(" portname as the port facing the module port.\n"); log("\n"); - log(" -outpad <celltype> <portname>[:<portname>]\n"); - log(" -inoutpad <celltype> <portname>[:<portname>]\n"); + log(" -outpad <celltype> <out_port>[:<ext_port>]\n"); + log(" -inoutpad <celltype> <io_port>[:<ext_port>]\n"); log(" Similar to -inpad, but for output and inout ports.\n"); log("\n"); - log(" -toutpad <celltype> <portname>:<portname>[:<portname>]\n"); + log(" -toutpad <celltype> <oe_port>:<out_port>[:<ext_port>]\n"); log(" Merges $_TBUF_ cells into the output pad cell. This takes precedence\n"); log(" over the other -outpad cell. The first portname is the enable input\n"); - log(" of the tristate driver.\n"); + log(" of the tristate driver, which can be prefixed with `~` for negative\n"); + log(" polarity enable.\n"); log("\n"); - log(" -tinoutpad <celltype> <portname>:<portname>:<portname>[:<portname>]\n"); + log(" -tinoutpad <celltype> <oe_port>:<in_port>:<out_port>[:<ext_port>]\n"); log(" Merges $_TBUF_ cells into the inout pad cell. This takes precedence\n"); log(" over the other -inoutpad cell. The first portname is the enable input\n"); log(" of the tristate driver and the 2nd portname is the internal output\n"); - log(" buffering the external signal.\n"); + log(" buffering the external signal. Like with `-toutpad`, the enable can\n"); + log(" be marked as negative polarity by prefixing the name with `~`.\n"); log("\n"); log(" -ignore <celltype> <portname>[:<portname>]*\n"); log(" Skips mapping inputs/outputs that are already connected to given\n"); @@ -106,6 +108,7 @@ struct IopadmapPass : public Pass { std::string inoutpad_celltype, inoutpad_portname_io, inoutpad_portname_pad; std::string toutpad_celltype, toutpad_portname_oe, toutpad_portname_i, toutpad_portname_pad; std::string tinoutpad_celltype, tinoutpad_portname_oe, tinoutpad_portname_o, tinoutpad_portname_i, tinoutpad_portname_pad; + bool toutpad_neg_oe = false, tinoutpad_neg_oe = false; std::string widthparam, nameparam; pool<pair<IdString, IdString>> ignore; bool flag_bits = false; @@ -137,6 +140,10 @@ struct IopadmapPass : public Pass { toutpad_portname_oe = args[++argidx]; split_portname_pair(toutpad_portname_oe, toutpad_portname_i); split_portname_pair(toutpad_portname_i, toutpad_portname_pad); + if (toutpad_portname_oe[0] == '~') { + toutpad_neg_oe = true; + toutpad_portname_oe = toutpad_portname_oe.substr(1); + } continue; } if (arg == "-tinoutpad" && argidx+2 < args.size()) { @@ -145,6 +152,10 @@ struct IopadmapPass : public Pass { split_portname_pair(tinoutpad_portname_oe, tinoutpad_portname_o); split_portname_pair(tinoutpad_portname_o, tinoutpad_portname_i); split_portname_pair(tinoutpad_portname_i, tinoutpad_portname_pad); + if (toutpad_portname_oe[0] == '~') { + tinoutpad_neg_oe = true; + tinoutpad_portname_oe = tinoutpad_portname_oe.substr(1); + } continue; } if (arg == "-ignore" && argidx+2 < args.size()) { @@ -318,6 +329,8 @@ struct IopadmapPass : public Pass { module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)), RTLIL::escape_id(tinoutpad_celltype)); + if (tinoutpad_neg_oe) + en_sig = module->NotGate(NEW_ID, en_sig); cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig); cell->attributes[ID::keep] = RTLIL::Const(1); @@ -340,6 +353,8 @@ struct IopadmapPass : public Pass { module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)), RTLIL::escape_id(toutpad_celltype)); + if (toutpad_neg_oe) + en_sig = module->NotGate(NEW_ID, en_sig); cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig); cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig); cell->attributes[ID::keep] = RTLIL::Const(1); |