iopadmap: move \init attributes from outpad output to its input
authorEddie Hung <eddie@fpgeh.com>
Thu, 13 Feb 2020 20:05:14 +0000 (12:05 -0800)
committerEddie Hung <eddie@fpgeh.com>
Thu, 13 Feb 2020 20:05:14 +0000 (12:05 -0800)
passes/techmap/iopadmap.cc
tests/techmap/iopadmap.ys

index 531ac2b99efc65d6d0b7e79b82061b0c41e7d01e..b3ae5eafea516ecd3d56d5b2206736d10690768f 100644 (file)
@@ -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));
+                                                       }
+                                               }
                                        }
                                }
 
index c058d1607f4fd0c9391ddc5c748e3368451aa5e6..b787bb55ffb08d82fc3955909c2d360b4071ad25 100644 (file)
@@ -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