xilinx: Add tristate buffer mapping. (#1528)
authorMarcin Koƛcielnicki <mwk@0x04.net>
Wed, 4 Dec 2019 08:44:00 +0000 (09:44 +0100)
committerGitHub <noreply@github.com>
Wed, 4 Dec 2019 08:44:00 +0000 (09:44 +0100)
Fixes #1225.

techlibs/xilinx/cells_map.v
techlibs/xilinx/synth_xilinx.cc

index a15884ec4c694fbae33103ad5c08075bc3d21bd6..de2068bc50f83a1143e76188b44ad4845a9c4a81 100644 (file)
@@ -363,3 +363,11 @@ module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1);
   else
     MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O));
 endmodule
+
+module \$__XILINX_TINOUTPAD (input I, OE, output O, inout IO);
+  IOBUF _TECHMAP_REPLACE_ (.I(I), .O(O), .T(~OE), .IO(IO));
+endmodule
+
+module \$__XILINX_TOUTPAD (input I, OE, output O);
+  OBUFT _TECHMAP_REPLACE_ (.I(I), .O(O), .T(~OE));
+endmodule
index 3d4a65c5dfe1aa2c3f08f574c27d3acbaa474c2f..2c5686a3564a28448abe285a1e7ebbdce92547a6 100644 (file)
@@ -282,6 +282,7 @@ struct SynthXilinxPass : public ScriptPass
 
        void script() YS_OVERRIDE
        {
+               bool do_iopad = iopad || (ise && !noiopad);
                std::string ff_map_file;
                if (help_mode)
                        ff_map_file = "+/xilinx/{family}_ff_map.v";
@@ -305,6 +306,8 @@ struct SynthXilinxPass : public ScriptPass
                        run("proc");
                        if (flatten || help_mode)
                                run("flatten", "(with '-flatten')");
+                       run("tribuf -logic");
+                       run("deminout");
                        run("opt_expr");
                        run("opt_clean");
                        run("check");
@@ -503,6 +506,9 @@ struct SynthXilinxPass : public ScriptPass
                }
 
                if (check_label("map_cells")) {
+                       // Needs to be done before logic optimization, so that inverters (OE vs T) are handled.
+                       if (help_mode || do_iopad)
+                               run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top", "(only if '-iopad' or '-ise' and not '-noiopad')");
                        std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v";
                        if (widemux > 0)
                                techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
@@ -561,15 +567,8 @@ struct SynthXilinxPass : public ScriptPass
                }
 
                if (check_label("finalize")) {
-                       bool do_iopad = iopad || (ise && !noiopad);
-                       if (help_mode || !noclkbuf) {
-                               if (help_mode || do_iopad)
-                                       run("clkbufmap -buf BUFG O:I -inpad IBUFG O:I", "(skip if '-noclkbuf', '-inpad' passed if '-iopad' or '-ise' and not '-noiopad')");
-                               else
-                                       run("clkbufmap -buf BUFG O:I");
-                       }
-                       if (help_mode || do_iopad)
-                               run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopad' or '-ise' and not '-noiopad')");
+                       if (help_mode || !noclkbuf)
+                               run("clkbufmap -buf BUFG O:I ", "(skip if '-noclkbuf')");
                        if (help_mode || ise)
                                run("extractinv -inv INV O:I", "(only if '-ise')");
                }