From ebb11bcea4ab5d2aed90d640904bf490a3285fb8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 13 Feb 2020 12:05:14 -0800 Subject: [PATCH 1/3] iopadmap: move \init attributes from outpad output to its input --- passes/techmap/iopadmap.cc | 23 ++++++++++++++++++++--- tests/techmap/iopadmap.ys | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 531ac2b99..b3ae5eafe 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -408,18 +408,35 @@ struct IopadmapPass : public Pass { RTLIL::Wire *wire = it.first; RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire); module->swap_names(new_wire, wire); - wire->attributes.clear(); for (int i = 0; i < wire->width; i++) { SigBit wire_bit(wire, i); if (!it.second.count(i)) { - if (wire->port_output) + if (wire->port_output) { module->connect(SigSpec(new_wire, i), SigSpec(wire, i)); - else + wire->attributes.clear(); + } + else { module->connect(SigSpec(wire, i), SigSpec(new_wire, i)); + wire->attributes.clear(); + + } } else { auto &new_conn = it.second.at(i); new_conn.first->setPort(new_conn.second, RTLIL::SigSpec(new_wire, i)); + + // For cell outputs, move \init attributes from old wire to new wire + if (new_conn.first->output(new_conn.second)) { + auto it = wire->attributes.find(ID(init)); + if (it != wire->attributes.end()) { + for (auto it2 = wire->attributes.begin(); it2 != wire->attributes.end(); ) + if (it == it2) + ++it2; + else + it2 = wire->attributes.erase(it2); + new_wire->attributes.erase(ID(init)); + } + } } } diff --git a/tests/techmap/iopadmap.ys b/tests/techmap/iopadmap.ys index c058d1607..b787bb55f 100644 --- a/tests/techmap/iopadmap.ys +++ b/tests/techmap/iopadmap.ys @@ -120,3 +120,40 @@ select -assert-count 1 g/t:iobuf select -assert-count 1 h/t:ibuf select -assert-count 1 h/t:iobuf select -assert-count 1 h/t:obuf + + +# Check that \init attributes get moved from output buffer +# to buffer input +design -reset +read_verilog << EOT +module obuf (input i, (* iopad_external_pin *) output o); endmodule +module obuft (input i, input oe, (* iopad_external_pin *) output o); endmodule +module iobuf (input i, input oe, output o, (* iopad_external_pin *) inout io); endmodule +module sub(input i, output o); endmodule + +module a(input i, (* init=1'b1 *) output o); +sub s(.i(i), .o(o)); +endmodule + +module b(input i, oe, output o); +(* init=1'b1 *) wire w; +sub s(.i(i), .o(w)); +assign o = oe ? w : 1'bz; +endmodule + +module c(input i, oe, inout io); +(* init=1'b1 *) wire w; +sub s(.i(i), .o(w)); +assign io = oe ? w : 1'bz; +endmodule +EOT +opt_clean +tribuf +simplemap +iopadmap -bits -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io +select -assert-count 1 a/c:s %co a/a:init=1'1 %i +select -assert-count 1 a/a:init=1'1 +select -assert-count 1 b/c:s %co b/a:init=1'1 %i +select -assert-count 1 b/a:init=1'1 +select -assert-count 1 c/c:s %co c/a:init=1'1 %i +select -assert-count 1 c/a:init=1'1 From 3d2a2e87992e1ecd3e724f379ce32044b7506aa3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 13 Feb 2020 14:57:06 -0800 Subject: [PATCH 2/3] iopadmap: fixes as suggested by @mwkmwkmwk --- passes/techmap/iopadmap.cc | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index b3ae5eafe..a6e4fac14 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -408,35 +408,27 @@ struct IopadmapPass : public Pass { RTLIL::Wire *wire = it.first; RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire); module->swap_names(new_wire, wire); + wire->attributes.clear(); for (int i = 0; i < wire->width; i++) { SigBit wire_bit(wire, i); if (!it.second.count(i)) { - if (wire->port_output) { + if (wire->port_output) module->connect(SigSpec(new_wire, i), SigSpec(wire, i)); - wire->attributes.clear(); - } - else { + else module->connect(SigSpec(wire, i), SigSpec(new_wire, i)); - wire->attributes.clear(); - - } } else { auto &new_conn = it.second.at(i); new_conn.first->setPort(new_conn.second, RTLIL::SigSpec(new_wire, i)); + } + } - // For cell outputs, move \init attributes from old wire to new wire - if (new_conn.first->output(new_conn.second)) { - auto it = wire->attributes.find(ID(init)); - if (it != wire->attributes.end()) { - for (auto it2 = wire->attributes.begin(); it2 != wire->attributes.end(); ) - if (it == it2) - ++it2; - else - it2 = wire->attributes.erase(it2); - new_wire->attributes.erase(ID(init)); - } - } + if (wire->port_output) { + auto jt = new_wire->attributes.find(ID(init)); + // For output ports, move \init attributes from old wire to new wire + if (jt != new_wire->attributes.end()) { + wire->attributes[ID(init)] = std::move(jt->second); + new_wire->attributes.erase(jt); } } From 3065d4092e2d2f252a270ecadc1943833a68e384 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 13 Feb 2020 15:14:58 -0800 Subject: [PATCH 3/3] Fine tune #1699 tests --- tests/techmap/iopadmap.ys | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/techmap/iopadmap.ys b/tests/techmap/iopadmap.ys index b787bb55f..0bcc71cce 100644 --- a/tests/techmap/iopadmap.ys +++ b/tests/techmap/iopadmap.ys @@ -135,25 +135,25 @@ module a(input i, (* init=1'b1 *) output o); sub s(.i(i), .o(o)); endmodule -module b(input i, oe, output o); -(* init=1'b1 *) wire w; -sub s(.i(i), .o(w)); -assign o = oe ? w : 1'bz; +module b(input [1:0] i, oe, (* init=2'b1x *) output [1:0] o); +wire [1:0] w; +sub s1(.i(i[0]), .o(w[0])); +sub s2(.i(i[1]), .o(w[1])); +assign o = oe ? w : 2'bz; endmodule -module c(input i, oe, inout io); -(* init=1'b1 *) wire w; -sub s(.i(i), .o(w)); -assign io = oe ? w : 1'bz; +module c(input i, oe, (* init=2'b00 *) inout io, output o1, o2); +assign io = oe ? i : 1'bz; +assign {o1,o2} = {io,io}; endmodule EOT opt_clean tribuf simplemap iopadmap -bits -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io -select -assert-count 1 a/c:s %co a/a:init=1'1 %i -select -assert-count 1 a/a:init=1'1 -select -assert-count 1 b/c:s %co b/a:init=1'1 %i -select -assert-count 1 b/a:init=1'1 -select -assert-count 1 c/c:s %co c/a:init=1'1 %i -select -assert-count 1 c/a:init=1'1 +select -assert-count 1 a/c:s %co a/a:init=1'b1 %i +select -assert-count 1 a/a:init +select -assert-count 1 b/c:s* %co %a b/a:init=2'b1x %i +select -assert-count 1 b/a:init +select -assert-count 1 c/t:iobuf %co c/a:init=2'b00 %i +select -assert-count 1 c/a:init