sf2: replace sf2_iobs with {clkbuf,iopad}map
authorDan Ravensloft <dan.ravensloft@gmail.com>
Sat, 4 Jul 2020 20:20:26 +0000 (21:20 +0100)
committerDan Ravensloft <dan.ravensloft@gmail.com>
Thu, 9 Jul 2020 20:28:52 +0000 (21:28 +0100)
techlibs/sf2/Makefile.inc
techlibs/sf2/cells_sim.v
techlibs/sf2/sf2_iobs.cc [deleted file]
techlibs/sf2/synth_sf2.cc

index cc3054aced8f055eaef0ffc8986760ba62e62d67..cade49f37dd26fcc99bc9deeb4a751a5718d0a50 100644 (file)
@@ -1,6 +1,5 @@
 
 OBJS += techlibs/sf2/synth_sf2.o
-OBJS += techlibs/sf2/sf2_iobs.o
 
 $(eval $(call add_share_file,share/sf2,techlibs/sf2/arith_map.v))
 $(eval $(call add_share_file,share/sf2,techlibs/sf2/cells_map.v))
index c62748b11b7d7863b302f2e8fbea4baba58794b9..eff57a65534d09274e40869e909e60f96f11a50b 100644 (file)
@@ -1,7 +1,6 @@
 // https://coredocs.s3.amazonaws.com/Libero/12_0_0/Tool/sf2_mlg.pdf
 
 module ADD2 (
-
        input A, B,
        output Y
 );
@@ -76,6 +75,7 @@ endmodule
 
 module CLKINT (
        input A,
+       (* clkbuf_driver *)
        output Y
 );
        assign Y = A;
@@ -83,6 +83,7 @@ endmodule
 
 module CLKINT_PRESERVE (
        input A,
+       (* clkbuf_driver *)
        output Y
 );
        assign Y = A;
@@ -90,6 +91,7 @@ endmodule
 
 module GCLKINT (
        input A, EN,
+       (* clkbuf_driver *)
        output Y
 );
        assign Y = A & EN;
@@ -97,6 +99,7 @@ endmodule
 
 module RCLKINT (
        input A,
+       (* clkbuf_driver *)
        output Y
 );
        assign Y = A;
@@ -104,6 +107,7 @@ endmodule
 
 module RGCLKINT (
        input A, EN,
+       (* clkbuf_driver *)
        output Y
 );
        assign Y = A & EN;
@@ -113,6 +117,7 @@ module SLE (
        output Q,
        input ADn,
        input ALn,
+       (* clkbuf_sink *)
        input CLK,
        input D,
        input LAT,
@@ -155,9 +160,41 @@ endmodule
 // module SYSRESET
 // module SYSCTRL_RESET_STATUS
 // module LIVE_PROBE_FB
-// module GCLKBUF
-// module GCLKBUF_DIFF
-// module GCLKBIBUF
+
+(* blackbox *)
+module GCLKBUF (
+       (* iopad_external_pin *)
+       input PAD,
+       input EN,
+       (* clkbuf_driver *)
+       output Y
+);
+endmodule
+
+(* blackbox *)
+module GCLKBUF_DIFF (
+       (* iopad_external_pin *)
+       input PADP,
+       (* iopad_external_pin *)
+       input PADN,
+       input EN,
+       (* clkbuf_driver *)
+       output Y
+);
+endmodule
+
+(* blackbox *)
+module GCLKBIBUF (
+       input D,
+       input E,
+       input EN,
+       (* iopad_external_pin *)
+       inout PAD,
+       (* clkbuf_driver *)
+       output Y
+);
+endmodule
+
 // module DFN1
 // module DFN1C0
 // module DFN1E1
@@ -288,38 +325,118 @@ module XOR8 (
 endmodule
 
 // module UJTAG
-// module BIBUF
-// module BIBUF_DIFF
-// module CLKBIBUF
+
+module BIBUF (
+       input D,
+       input E,
+       (* iopad_external_pin *)
+       inout PAD,
+       output Y
+);
+       assign PAD = E ? D : 1'bz;
+       assign Y = PAD;
+endmodule
+
+(* blackbox *)
+module BIBUF_DIFF (
+       input D,
+       input E,
+       (* iopad_external_pin *)
+       inout PADP,
+       (* iopad_external_pin *)
+       inout PADN,
+       output Y
+);
+endmodule
+
+module CLKBIBUF (
+       input D,
+       input E,
+       (* iopad_external_pin *)
+       inout PAD,
+       (* clkbuf_driver *)
+       output Y
+);
+       assign PAD = E ? D : 1'bz;
+       assign Y = PAD;
+endmodule
 
 module CLKBUF (
+       (* iopad_external_pin *)
        input PAD,
+       (* clkbuf_driver *)
        output Y
 );
        assign Y = PAD;
 endmodule
 
-// module CLKBUF_DIFF
+(* blackbox *)
+module CLKBUF_DIFF (
+       (* iopad_external_pin *)
+       input PADP,
+       (* iopad_external_pin *)
+       input PADN,
+       (* clkbuf_driver *)
+       output Y
+);
+endmodule
 
 module INBUF (
+       (* iopad_external_pin *)
        input PAD,
        output Y
 );
        assign Y = PAD;
 endmodule
 
-// module INBUF_DIFF
+(* blackbox *)
+module INBUF_DIFF (
+       (* iopad_external_pin *)
+       input PADP,
+       (* iopad_external_pin *)
+       input PADN,
+       output Y
+);
+endmodule
 
 module OUTBUF (
        input D,
+       (* iopad_external_pin *)
        output PAD
 );
        assign PAD = D;
 endmodule
 
-// module OUTBUF_DIFF
-// module TRIBUFF
-// module TRIBUFF_DIFF
+(* blackbox *)
+module OUTBUF_DIFF (
+       input D,
+       (* iopad_external_pin *)
+       output PADP,
+       (* iopad_external_pin *)
+       output PADN
+);
+endmodule
+
+module TRIBUFF (
+       input D,
+       input E,
+       (* iopad_external_pin *)
+       output PAD
+);
+       assign PAD = E ? D : 1'bz;
+endmodule
+
+(* blackbox *)
+module TRIBUFF_DIFF (
+       input D,
+       input E,
+       (* iopad_external_pin *)
+       output PADP,
+       (* iopad_external_pin *)
+       output PADN
+);
+endmodule
+
 // module DDR_IN
 // module DDR_OUT
 // module RAM1K18
diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc
deleted file mode 100644 (file)
index 5fd719c..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- *  yosys -- Yosys Open SYnthesis Suite
- *
- *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
- *
- *  Permission to use, copy, modify, and/or distribute this software for any
- *  purpose with or without fee is hereby granted, provided that the above
- *  copyright notice and this permission notice appear in all copies.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "kernel/yosys.h"
-#include "kernel/sigtools.h"
-
-USING_YOSYS_NAMESPACE
-PRIVATE_NAMESPACE_BEGIN
-
-static void handle_iobufs(Module *module, bool clkbuf_mode)
-{
-       SigMap sigmap(module);
-
-       pool<SigBit> clk_bits;
-       pool<SigBit> handled_io_bits;
-       dict<SigBit, SigBit> rewrite_bits;
-       vector<pair<Cell*, SigBit>> pad_bits;
-
-       for (auto cell : module->cells())
-       {
-               if (clkbuf_mode && cell->type == ID(SLE)) {
-                       for (auto bit : sigmap(cell->getPort(ID::CLK)))
-                               clk_bits.insert(bit);
-               }
-               if (cell->type.in(ID(INBUF), ID(OUTBUF), ID(TRIBUFF), ID(BIBUF), ID(CLKBUF), ID(CLKBIBUF),
-                               ID(INBUF_DIFF), ID(OUTBUF_DIFF), ID(BIBUFF_DIFF), ID(TRIBUFF_DIFF), ID(CLKBUF_DIFF),
-                               ID(GCLKBUF), ID(GCLKBUF_DIFF), ID(GCLKBIBUF))) {
-                       for (auto bit : sigmap(cell->getPort(ID(PAD))))
-                               handled_io_bits.insert(bit);
-               }
-       }
-
-       for (auto wire : vector<Wire*>(module->wires()))
-       {
-               if (!wire->port_input && !wire->port_output)
-                       continue;
-
-               for (int index = 0; index < GetSize(wire); index++)
-               {
-                       SigBit bit(wire, index);
-                       SigBit canonical_bit = sigmap(bit);
-
-                       if (handled_io_bits.count(canonical_bit))
-                               continue;
-
-                       if (wire->port_input && wire->port_output)
-                               log_error("Failed to add buffer for inout port bit %s.\n", log_signal(bit));
-
-                       IdString buf_type, buf_port;
-
-                       if (wire->port_output) {
-                               buf_type = ID(OUTBUF);
-                               buf_port = ID::D;
-                       } else if (clkbuf_mode && clk_bits.count(canonical_bit)) {
-                               buf_type = ID(CLKBUF);
-                               buf_port = ID::Y;
-                       } else {
-                               buf_type = ID(INBUF);
-                               buf_port = ID::Y;
-                       }
-
-                       Cell *c = module->addCell(NEW_ID, buf_type);
-                       SigBit new_bit = module->addWire(NEW_ID);
-                       c->setPort(buf_port, new_bit);
-                       pad_bits.push_back(make_pair(c, bit));
-                       rewrite_bits[canonical_bit] = new_bit;
-
-                       log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit));
-               }
-       }
-
-       auto rewrite_function = [&](SigSpec &s) {
-               for (auto &bit : s) {
-                       SigBit canonical_bit = sigmap(bit);
-                       if (rewrite_bits.count(canonical_bit))
-                               bit = rewrite_bits.at(canonical_bit);
-               }
-       };
-
-       module->rewrite_sigspecs(rewrite_function);
-
-       for (auto &it : pad_bits)
-               it.first->setPort(ID(PAD), it.second);
-}
-
-static void handle_clkint(Module *module)
-{
-       SigMap sigmap(module);
-
-       pool<SigBit> clk_bits;
-       vector<SigBit> handled_clk_bits;
-
-       for (auto cell : module->cells())
-       {
-               if (cell->type == ID(SLE)) {
-                       for (auto bit : sigmap(cell->getPort(ID::CLK)))
-                               clk_bits.insert(bit);
-               }
-               if (cell->type.in(ID(CLKBUF), ID(CLKBIBUF), ID(CLKBUF_DIFF), ID(GCLKBUF), ID(GCLKBUF_DIFF), ID(GCLKBIBUF),
-                               ID(CLKINT), ID(CLKINT_PRESERVE), ID(GCLKINT), ID(RCLKINT), ID(RGCLKINT))) {
-                       for (auto bit : sigmap(cell->getPort(ID::Y)))
-                               handled_clk_bits.push_back(bit);
-               }
-       }
-
-       for (auto bit : handled_clk_bits)
-               clk_bits.erase(bit);
-
-       for (auto cell : vector<Cell*>(module->cells()))
-       for (auto &conn : cell->connections())
-       {
-               if (!cell->output(conn.first))
-                       continue;
-
-               SigSpec sig = conn.second;
-               bool did_something = false;
-
-               for (auto &bit : sig) {
-                       SigBit canonical_bit = sigmap(bit);
-                       if (clk_bits.count(canonical_bit)) {
-                               Cell *c = module->addCell(NEW_ID, ID(CLKINT));
-                               SigBit new_bit = module->addWire(NEW_ID);
-                               c->setPort(ID::A, new_bit);
-                               c->setPort(ID::Y, bit);
-                               log("Added %s cell %s for clock signal %s.\n", log_id(c->type), log_id(c), log_signal(bit));
-                               clk_bits.erase(canonical_bit);
-                               did_something = true;
-                               bit = new_bit;
-                       }
-               }
-
-               if (did_something)
-                       cell->setPort(conn.first, sig);
-       }
-
-       for (auto bit : clk_bits)
-               log_error("Failed to insert CLKINT for clock signal %s.\n", log_signal(bit));
-}
-
-struct Sf2IobsPass : public Pass {
-       Sf2IobsPass() : Pass("sf2_iobs", "SF2: insert IO buffers") { }
-       void help() override
-       {
-               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
-               log("\n");
-               log("    sf2_iobs [options] [selection]\n");
-               log("\n");
-               log("Add SF2 I/O buffers and global buffers to top module as needed.\n");
-               log("\n");
-               log("    -clkbuf\n");
-               log("        Insert PAD->global_net clock buffers\n");
-               log("\n");
-       }
-       void execute(std::vector<std::string> args, RTLIL::Design *design) override
-       {
-               bool clkbuf_mode = false;
-
-               log_header(design, "Executing sf2_iobs pass (insert IO buffers).\n");
-
-               size_t argidx;
-               for (argidx = 1; argidx < args.size(); argidx++)
-               {
-                       if (args[argidx] == "-clkbuf") {
-                               clkbuf_mode = true;
-                               continue;
-                       }
-                       break;
-               }
-               extra_args(args, argidx, design);
-
-               Module *module = design->top_module();
-
-               if (module == nullptr)
-                       log_cmd_error("No top module found.\n");
-
-               handle_iobufs(module, clkbuf_mode);
-               handle_clkint(module);
-       }
-} Sf2IobsPass;
-
-PRIVATE_NAMESPACE_END
index 6b2a3f9b8306ea344dbe39fa1ad69806f3d13ed7..096450ad3d1b840c0d69520b08a8f77cb8b5ee35 100644 (file)
@@ -209,10 +209,12 @@ struct SynthSf2Pass : public ScriptPass
 
                if (check_label("map_iobs"))
                {
-                       if (help_mode)
-                               run("sf2_iobs [-clkbuf]", "(unless -noiobs)");
-                       else if (iobs)
-                               run(clkbuf ? "sf2_iobs -clkbuf" : "sf2_iobs");
+                       if (help_mode || iobs) {
+                               if (help_mode || clkbuf) {
+                                       run("clkbufmap -buf CLKINT Y:A -inpad CLKBUF Y:PAD", "(if -clkbuf, unless -noiobs)");
+                               }
+                               run("iopadmap -bits -inpad INBUF Y:PAD -outpad OUTBUF D:PAD -toutpad TRIBUFF E:D:PAD -tinoutpad BIBUF E:Y:D:PAD", "(unless -noiobs");
+                       }
                        run("clean");
                }