aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2021-11-09 11:22:48 +0100
committerMarcelina Koƛcielnicka <mwk@0x04.net>2021-11-09 15:40:16 +0100
commit15b0d717ed658b342ce5f74df5a65827eed04a94 (patch)
treee9dfb025526ea0f1fbddf705987872fc889a951c /passes/techmap
parent4871d8f19911dc48bf7726519437be8a821c0a1f (diff)
downloadyosys-15b0d717ed658b342ce5f74df5a65827eed04a94.tar.gz
yosys-15b0d717ed658b342ce5f74df5a65827eed04a94.tar.bz2
yosys-15b0d717ed658b342ce5f74df5a65827eed04a94.zip
iopadmap: Add native support for negative-polarity output enable.
Diffstat (limited to 'passes/techmap')
-rw-r--r--passes/techmap/iopadmap.cc29
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);