aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/sf2
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/sf2')
-rw-r--r--techlibs/sf2/cells_map.v64
-rw-r--r--techlibs/sf2/cells_sim.v281
-rw-r--r--techlibs/sf2/sf2_iobs.cc217
-rw-r--r--techlibs/sf2/synth_sf2.cc16
4 files changed, 450 insertions, 128 deletions
diff --git a/techlibs/sf2/cells_map.v b/techlibs/sf2/cells_map.v
index 5b8888294..6ad7807d2 100644
--- a/techlibs/sf2/cells_map.v
+++ b/techlibs/sf2/cells_map.v
@@ -1,40 +1,54 @@
-// module \$_DFF_N_ (input D, C, output Q); SB_DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); endmodule
+module \$_DFF_N_ (input D, C, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(1'b1), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
module \$_DFF_P_ (input D, C, output Q);
- SLE _TECHMAP_REPLACE_ (
- .D(D),
- .CLK(C),
- .EN(1'b1),
- .ALn(1'b1),
- .ADn(1'b1),
- .SLn(1'b1),
- .SD(1'b0),
- .LAT(1'b0),
- .Q(Q)
- );
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(1'b1), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
+
+module \$_DFF_NN0_ (input D, C, R, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
+
+module \$_DFF_NN1_ (input D, C, R, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
+
+module \$_DFF_NP0_ (input D, C, R, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(!R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
+
+module \$_DFF_NP1_ (input D, C, R, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(!R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
+
+module \$_DFF_PN0_ (input D, C, R, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
+
+module \$_DFF_PN1_ (input D, C, R, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
+
+module \$_DFF_PP0_ (input D, C, R, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(!R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
+endmodule
+
+module \$_DFF_PP1_ (input D, C, R, output Q);
+ SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(!R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q));
endmodule
// module \$_DFFE_NN_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule
// module \$_DFFE_PN_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule
-//
+//
// module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule
// module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule
-//
-// module \$_DFF_NN0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule
-// module \$_DFF_NN1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule
-// module \$_DFF_PN0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule
-// module \$_DFF_PN1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule
-//
-// module \$_DFF_NP0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule
-// module \$_DFF_NP1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule
-// module \$_DFF_PP0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule
-// module \$_DFF_PP1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule
-//
+//
// module \$__DFFE_NN0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule
// module \$__DFFE_NN1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule
// module \$__DFFE_PN0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule
// module \$__DFFE_PN1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule
-//
+//
// module \$__DFFE_NP0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule
// module \$__DFFE_NP1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule
// module \$__DFFE_PP0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule
diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v
index f967068af..c62748b11 100644
--- a/techlibs/sf2/cells_sim.v
+++ b/techlibs/sf2/cells_sim.v
@@ -1,3 +1,114 @@
+// https://coredocs.s3.amazonaws.com/Libero/12_0_0/Tool/sf2_mlg.pdf
+
+module ADD2 (
+
+ input A, B,
+ output Y
+);
+ assign Y = A & B;
+endmodule
+
+module ADD3 (
+ input A, B, C,
+ output Y
+);
+ assign Y = A & B & C;
+endmodule
+
+module ADD4 (
+ input A, B, C, D,
+ output Y
+);
+ assign Y = A & B & C & D;
+endmodule
+
+module CFG1 (
+ output Y,
+ input A
+);
+ parameter [1:0] INIT = 2'h0;
+ assign Y = INIT >> A;
+endmodule
+
+module CFG2 (
+ output Y,
+ input A,
+ input B
+);
+ parameter [3:0] INIT = 4'h0;
+ assign Y = INIT >> {B, A};
+endmodule
+
+module CFG3 (
+ output Y,
+ input A,
+ input B,
+ input C
+);
+ parameter [7:0] INIT = 8'h0;
+ assign Y = INIT >> {C, B, A};
+endmodule
+
+module CFG4 (
+ output Y,
+ input A,
+ input B,
+ input C,
+ input D
+);
+ parameter [15:0] INIT = 16'h0;
+ assign Y = INIT >> {D, C, B, A};
+endmodule
+
+module BUFF (
+ input A,
+ output Y
+);
+ assign Y = A;
+endmodule
+
+module BUFD (
+ input A,
+ output Y
+);
+ assign Y = A;
+endmodule
+
+module CLKINT (
+ input A,
+ output Y
+);
+ assign Y = A;
+endmodule
+
+module CLKINT_PRESERVE (
+ input A,
+ output Y
+);
+ assign Y = A;
+endmodule
+
+module GCLKINT (
+ input A, EN,
+ output Y
+);
+ assign Y = A & EN;
+endmodule
+
+module RCLKINT (
+ input A,
+ output Y
+);
+ assign Y = A;
+endmodule
+
+module RGCLKINT (
+ input A, EN,
+ output Y
+);
+ assign Y = A & EN;
+endmodule
+
module SLE (
output Q,
input ADn,
@@ -36,44 +147,151 @@ module SLE (
assign Q = LAT ? q_latch : q_ff;
endmodule
-module CFG1 (
- output Y,
- input A
+// module AR1
+// module FCEND_BUFF
+// module FCINIT_BUFF
+// module FLASH_FREEZE
+// module OSCILLATOR
+// module SYSRESET
+// module SYSCTRL_RESET_STATUS
+// module LIVE_PROBE_FB
+// module GCLKBUF
+// module GCLKBUF_DIFF
+// module GCLKBIBUF
+// module DFN1
+// module DFN1C0
+// module DFN1E1
+// module DFN1E1C0
+// module DFN1E1P0
+// module DFN1P0
+// module DLN1
+// module DLN1C0
+// module DLN1P0
+
+module INV (
+ input A,
+ output Y
);
- parameter [1:0] INIT = 2'h0;
- assign Y = INIT >> A;
+ assign Y = !A;
endmodule
-module CFG2 (
- output Y,
+module INVD (
input A,
- input B
+ output Y
);
- parameter [3:0] INIT = 4'h0;
- assign Y = INIT >> {B, A};
+ assign Y = !A;
endmodule
-module CFG3 (
- output Y,
- input A,
- input B,
- input C
+module MX2 (
+ input A, B, S,
+ output Y
);
- parameter [7:0] INIT = 8'h0;
- assign Y = INIT >> {C, B, A};
+ assign Y = S ? B : A;
endmodule
-module CFG4 (
- output Y,
- input A,
- input B,
- input C,
- input D
+module MX4 (
+ input D0, D1, D2, D3, S0, S1,
+ output Y
);
- parameter [15:0] INIT = 16'h0;
- assign Y = INIT >> {D, C, B, A};
+ assign Y = S1 ? (S0 ? D3 : D2) : (S0 ? D1 : D0);
+endmodule
+
+module NAND2 (
+ input A, B,
+ output Y
+);
+ assign Y = !(A & B);
+endmodule
+
+module NAND3 (
+ input A, B, C,
+ output Y
+);
+ assign Y = !(A & B & C);
+endmodule
+
+module NAND4 (
+ input A, B, C, D,
+ output Y
+);
+ assign Y = !(A & B & C & D);
+endmodule
+
+module NOR2 (
+ input A, B,
+ output Y
+);
+ assign Y = !(A | B);
+endmodule
+
+module NOR3 (
+ input A, B, C,
+ output Y
+);
+ assign Y = !(A | B | C);
+endmodule
+
+module NOR4 (
+ input A, B, C, D,
+ output Y
+);
+ assign Y = !(A | B | C | D);
endmodule
+module OR2 (
+ input A, B,
+ output Y
+);
+ assign Y = A | B;
+endmodule
+
+module OR3 (
+ input A, B, C,
+ output Y
+);
+ assign Y = A | B | C;
+endmodule
+
+module OR4 (
+ input A, B, C, D,
+ output Y
+);
+ assign Y = A | B | C | D;
+endmodule
+
+module XOR2 (
+ input A, B,
+ output Y
+);
+ assign Y = A ^ B;
+endmodule
+
+module XOR3 (
+ input A, B, C,
+ output Y
+);
+ assign Y = A ^ B ^ C;
+endmodule
+
+module XOR4 (
+ input A, B, C, D,
+ output Y
+);
+ assign Y = A ^ B ^ C ^ D;
+endmodule
+
+module XOR8 (
+ input A, B, C, D, E, F, G, H,
+ output Y
+);
+ assign Y = A ^ B ^ C ^ D ^ E ^ F ^ G ^ H;
+endmodule
+
+// module UJTAG
+// module BIBUF
+// module BIBUF_DIFF
+// module CLKBIBUF
+
module CLKBUF (
input PAD,
output Y
@@ -81,6 +299,8 @@ module CLKBUF (
assign Y = PAD;
endmodule
+// module CLKBUF_DIFF
+
module INBUF (
input PAD,
output Y
@@ -88,9 +308,20 @@ module INBUF (
assign Y = PAD;
endmodule
+// module INBUF_DIFF
+
module OUTBUF (
input D,
output PAD
);
assign PAD = D;
endmodule
+
+// module OUTBUF_DIFF
+// module TRIBUFF
+// module TRIBUFF_DIFF
+// module DDR_IN
+// module DDR_OUT
+// module RAM1K18
+// module RAM64x18
+// module MACC
diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc
index 27141430c..3d43332e2 100644
--- a/techlibs/sf2/sf2_iobs.cc
+++ b/techlibs/sf2/sf2_iobs.cc
@@ -23,6 +23,136 @@
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 == "\\SLE") {
+ for (auto bit : sigmap(cell->getPort("\\CLK")))
+ clk_bits.insert(bit);
+ }
+ if (cell->type.in("\\INBUF", "\\OUTBUF", "\\TRIBUFF", "\\BIBUF", "\\CLKBUF", "\\CLKBIBUF",
+ "\\INBUF_DIFF", "\\OUTBUF_DIFF", "\\BIBUFF_DIFF", "\\TRIBUFF_DIFF", "\\CLKBUF_DIFF",
+ "\\GCLKBUF", "\\GCLKBUF_DIFF", "\\GCLKBIBUF")) {
+ for (auto bit : sigmap(cell->getPort("\\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 = "\\OUTBUF";
+ buf_port = "\\D";
+ } else if (clkbuf_mode && clk_bits.count(canonical_bit)) {
+ buf_type = "\\CLKBUF";
+ buf_port = "\\Y";
+ } else {
+ buf_type = "\\INBUF";
+ buf_port = "\\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("\\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 == "\\SLE") {
+ for (auto bit : sigmap(cell->getPort("\\CLK")))
+ clk_bits.insert(bit);
+ }
+ if (cell->type.in("\\CLKBUF", "\\CLKBIBUF", "\\CLKBUF_DIFF", "\\GCLKBUF", "\\GCLKBUF_DIFF", "\\GCLKBIBUF",
+ "\\CLKINT", "\\CLKINT_PRESERVE", "\\GCLKINT", "\\RCLKINT", "\\RGCLKINT")) {
+ for (auto bit : sigmap(cell->getPort("\\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, "\\CLKINT");
+ SigBit new_bit = module->addWire(NEW_ID);
+ c->setPort("\\A", new_bit);
+ c->setPort("\\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() YS_OVERRIDE
@@ -31,20 +161,25 @@ struct Sf2IobsPass : public Pass {
log("\n");
log(" sf2_iobs [options] [selection]\n");
log("\n");
- log("Add SF2 I/O buffers to top module IOs as needed.\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) YS_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] == "-singleton") {
- // singleton_mode = true;
- // continue;
- // }
+ if (args[argidx] == "-clkbuf") {
+ clkbuf_mode = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -54,76 +189,8 @@ struct Sf2IobsPass : public Pass {
if (module == nullptr)
log_cmd_error("No top module found.\n");
- 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 (cell->type == "\\SLE") {
- for (auto bit : sigmap(cell->getPort("\\CLK")))
- clk_bits.insert(bit);
- }
- if (cell->type.in("\\INBUF", "\\OUTBUF", "\\CLKBUF")) {
- for (auto bit : sigmap(cell->getPort("\\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 = "\\OUTBUF";
- buf_port = "\\D";
- } else if (clk_bits.count(canonical_bit)) {
- buf_type = "\\CLKBUF";
- buf_port = "\\Y";
- } else {
- buf_type = "\\INBUF";
- buf_port = "\\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("\\PAD", it.second);
+ handle_iobufs(module, clkbuf_mode);
+ handle_clkint(module);
}
} Sf2IobsPass;
diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc
index bdc20456d..0924df7a6 100644
--- a/techlibs/sf2/synth_sf2.cc
+++ b/techlibs/sf2/synth_sf2.cc
@@ -63,6 +63,9 @@ struct SynthSf2Pass : public ScriptPass
log(" -noiobs\n");
log(" run synthesis in \"block mode\", i.e. do not insert IO buffers\n");
log("\n");
+ log(" -clkbuf\n");
+ log(" insert direct PAD->global_net buffers\n");
+ log("\n");
log(" -retime\n");
log(" run 'abc' with -dff option\n");
log("\n");
@@ -73,7 +76,7 @@ struct SynthSf2Pass : public ScriptPass
}
string top_opt, edif_file, vlog_file, json_file;
- bool flatten, retime, iobs;
+ bool flatten, retime, iobs, clkbuf;
void clear_flags() YS_OVERRIDE
{
@@ -84,6 +87,7 @@ struct SynthSf2Pass : public ScriptPass
flatten = true;
retime = false;
iobs = true;
+ clkbuf = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -130,6 +134,10 @@ struct SynthSf2Pass : public ScriptPass
iobs = false;
continue;
}
+ if (args[argidx] == "-clkbuf") {
+ clkbuf = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -201,8 +209,10 @@ struct SynthSf2Pass : public ScriptPass
if (check_label("map_iobs"))
{
- if (iobs || help_mode)
- run("sf2_iobs", "(unless -noiobs)");
+ if (help_mode)
+ run("sf2_iobs [-clkbuf]", "(unless -noiobs)");
+ else if (iobs)
+ run(clkbuf ? "sf2_iobs -clkbuf" : "sf2_iobs");
run("clean");
}