aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/xilinx
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <koriakin@0x04.net>2019-08-12 15:57:43 +0000
committerMarcin Koƛcielnicki <koriakin@0x04.net>2019-08-13 00:16:38 +0200
commitf4c62f33ac56bc5725c44ad822e75d2387f98061 (patch)
tree4a1659237670042c8709777d660b14be57cb004f /techlibs/xilinx
parent78b30bbb1102047585d1a2eac89b1c7f5ca7344e (diff)
downloadyosys-f4c62f33ac56bc5725c44ad822e75d2387f98061.tar.gz
yosys-f4c62f33ac56bc5725c44ad822e75d2387f98061.tar.bz2
yosys-f4c62f33ac56bc5725c44ad822e75d2387f98061.zip
Add clock buffer insertion pass, improve iopadmap.
A few new attributes are defined for use in cell libraries: - iopad_external_pin: marks PAD cell's external-facing pin. Pad insertion will be skipped for ports that are already connected to such a pin. - clkbuf_sink: marks an input pin as a clock pin, requesting clock buffer insertion. - clkbuf_driver: marks an output pin as a clock buffer output pin. Clock buffer insertion will be skipped for nets that are already driven by such a pin. All three are module attributes that should be set to a comma-separeted list of pin names. Clock buffer insertion itself works as follows: 1. All cell ports, starting from bottom up, can be marked as clock sinks (requesting clock buffer insertion) or as clock buffer outputs. 2. If a wire in a given module is driven by a cell port that is a clock buffer output, it is in turn also considered a clock buffer output. 3. If an input port in a non-top module is connected to a clock sink in a contained cell, it is also in turn considered a clock sink. 4. If a wire in a module is driven by a non-clock-buffer cell, and is also connected to a clock sink port in a contained cell, a clock buffer is inserted in this module. 5. For the top module, a clock buffer is also inserted on input ports connected to clock sinks, optionally with a special kind of input PAD (such as IBUFG for Xilinx). 6. Clock buffer insertion on a given wire is skipped if the clkbuf_inhibit attribute is set on it.
Diffstat (limited to 'techlibs/xilinx')
-rw-r--r--techlibs/xilinx/cells_sim.v16
-rw-r--r--techlibs/xilinx/cells_xtra.sh144
-rw-r--r--techlibs/xilinx/cells_xtra.v90
-rw-r--r--techlibs/xilinx/synth_xilinx.cc37
-rw-r--r--techlibs/xilinx/xc6s_brams_bb.v2
-rw-r--r--techlibs/xilinx/xc7_brams_bb.v2
6 files changed, 220 insertions, 71 deletions
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index 05e46b4e7..d5815ca77 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -42,10 +42,12 @@ module OBUF(output O, input I);
assign O = I;
endmodule
+(* clkbuf_driver = "O" *)
module BUFG(output O, input I);
assign O = I;
endmodule
+(* clkbuf_driver = "O" *)
module BUFGCTRL(
output O,
input I0, input I1,
@@ -72,6 +74,7 @@ assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT);
endmodule
+(* clkbuf_driver = "O" *)
module BUFHCE(output O, input I, input CE);
parameter [0:0] INIT_OUT = 1'b0;
@@ -213,6 +216,7 @@ endmodule
`endif
+(* clkbuf_sink = "C" *)
module FDRE (output reg Q, input C, CE, D, R);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
@@ -225,6 +229,7 @@ module FDRE (output reg Q, input C, CE, D, R);
endcase endgenerate
endmodule
+(* clkbuf_sink = "C" *)
module FDSE (output reg Q, input C, CE, D, S);
parameter [0:0] INIT = 1'b1;
parameter [0:0] IS_C_INVERTED = 1'b0;
@@ -237,6 +242,7 @@ module FDSE (output reg Q, input C, CE, D, S);
endcase endgenerate
endmodule
+(* clkbuf_sink = "C" *)
module FDCE (output reg Q, input C, CE, D, CLR);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
@@ -251,6 +257,7 @@ module FDCE (output reg Q, input C, CE, D, CLR);
endcase endgenerate
endmodule
+(* clkbuf_sink = "C" *)
module FDPE (output reg Q, input C, CE, D, PRE);
parameter [0:0] INIT = 1'b1;
parameter [0:0] IS_C_INVERTED = 1'b0;
@@ -265,30 +272,35 @@ module FDPE (output reg Q, input C, CE, D, PRE);
endcase endgenerate
endmodule
+(* clkbuf_sink = "C" *)
module FDRE_1 (output reg Q, input C, CE, D, R);
parameter [0:0] INIT = 1'b0;
initial Q <= INIT;
always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D;
endmodule
+(* clkbuf_sink = "C" *)
module FDSE_1 (output reg Q, input C, CE, D, S);
parameter [0:0] INIT = 1'b1;
initial Q <= INIT;
always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D;
endmodule
+(* clkbuf_sink = "C" *)
module FDCE_1 (output reg Q, input C, CE, D, CLR);
parameter [0:0] INIT = 1'b0;
initial Q <= INIT;
always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
endmodule
+(* clkbuf_sink = "C" *)
module FDPE_1 (output reg Q, input C, CE, D, PRE);
parameter [0:0] INIT = 1'b1;
initial Q <= INIT;
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
endmodule
+(* clkbuf_sink = "WCLK" *)
(* abc_box_id = 5, abc_scc_break="D,WE" *)
module RAM32X1D (
output DPO, SPO,
@@ -307,6 +319,7 @@ module RAM32X1D (
always @(posedge clk) if (WE) mem[a] <= D;
endmodule
+(* clkbuf_sink = "WCLK" *)
(* abc_box_id = 6, abc_scc_break="D,WE" *)
module RAM64X1D (
output DPO, SPO,
@@ -325,6 +338,7 @@ module RAM64X1D (
always @(posedge clk) if (WE) mem[a] <= D;
endmodule
+(* clkbuf_sink = "WCLK" *)
(* abc_box_id = 7, abc_scc_break="D,WE" *)
module RAM128X1D (
output DPO, SPO,
@@ -340,6 +354,7 @@ module RAM128X1D (
always @(posedge clk) if (WE) mem[A] <= D;
endmodule
+(* clkbuf_sink = "CLK" *)
module SRL16E (
output Q,
input A0, A1, A2, A3, CE, CLK, D
@@ -358,6 +373,7 @@ module SRL16E (
endgenerate
endmodule
+(* clkbuf_sink = "CLK" *)
module SRLC32E (
output Q,
output Q31,
diff --git a/techlibs/xilinx/cells_xtra.sh b/techlibs/xilinx/cells_xtra.sh
index 53b528820..3291e46a8 100644
--- a/techlibs/xilinx/cells_xtra.sh
+++ b/techlibs/xilinx/cells_xtra.sh
@@ -1,7 +1,12 @@
#!/bin/bash
set -e
-libdir="/opt/Xilinx/Vivado/2018.1/data/verilog/src"
+if [ -z "$1" ]
+then
+ libdir="/opt/Xilinx/Vivado/2018.1/data/verilog/src"
+else
+ libdir=$1
+fi
function xtract_cell_decl()
{
@@ -24,33 +29,33 @@ function xtract_cell_decl()
echo
# Design elements types listed in Xilinx UG953
- xtract_cell_decl BSCANE2
- # xtract_cell_decl BUFG
- xtract_cell_decl BUFGCE
- xtract_cell_decl BUFGCE_1
- #xtract_cell_decl BUFGCTRL
- xtract_cell_decl BUFGMUX
- xtract_cell_decl BUFGMUX_1
- xtract_cell_decl BUFGMUX_CTRL
- xtract_cell_decl BUFH
- #xtract_cell_decl BUFHCE
- xtract_cell_decl BUFIO
- xtract_cell_decl BUFMR
- xtract_cell_decl BUFMRCE
- xtract_cell_decl BUFR
+ xtract_cell_decl BSCANE2 "(* keep *)"
+ # xtract_cell_decl BUFG "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFGCE "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFGCE_1 "(* clkbuf_driver = \"O\" *)"
+ #xtract_cell_decl BUFGCTRL "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFGMUX "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFGMUX_1 "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFGMUX_CTRL "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFH "(* clkbuf_driver = \"O\" *)"
+ #xtract_cell_decl BUFHCE "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFIO "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFMR "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFMRCE "(* clkbuf_driver = \"O\" *)"
+ xtract_cell_decl BUFR "(* clkbuf_driver = \"O\" *)"
xtract_cell_decl CAPTUREE2 "(* keep *)"
# xtract_cell_decl CARRY4
- xtract_cell_decl CFGLUT5
+ xtract_cell_decl CFGLUT5 "(* clkbuf_sink = \"CLK\" *)"
xtract_cell_decl DCIRESET "(* keep *)"
xtract_cell_decl DNA_PORT
- xtract_cell_decl DSP48E1
+ xtract_cell_decl DSP48E1 "(* clkbuf_sink = \"CLK\" *)"
xtract_cell_decl EFUSE_USR
# xtract_cell_decl FDCE
# xtract_cell_decl FDPE
# xtract_cell_decl FDRE
# xtract_cell_decl FDSE
- xtract_cell_decl FIFO18E1
- xtract_cell_decl FIFO36E1
+ xtract_cell_decl FIFO18E1 "(* clkbuf_sink = \"RDCLK,WRCLK\" *)"
+ xtract_cell_decl FIFO36E1 "(* clkbuf_sink = \"RDCLK,WRCLK\" *)"
xtract_cell_decl FRAME_ECCE2
xtract_cell_decl GTHE2_CHANNEL
xtract_cell_decl GTHE2_COMMON
@@ -58,31 +63,34 @@ function xtract_cell_decl()
xtract_cell_decl GTPE2_COMMON
xtract_cell_decl GTXE2_CHANNEL
xtract_cell_decl GTXE2_COMMON
- # xtract_cell_decl IBUF
- xtract_cell_decl IBUF_IBUFDISABLE
- xtract_cell_decl IBUF_INTERMDISABLE
- xtract_cell_decl IBUFDS
- xtract_cell_decl IBUFDS_DIFF_OUT
- xtract_cell_decl IBUFDS_DIFF_OUT_IBUFDISABLE
- xtract_cell_decl IBUFDS_DIFF_OUT_INTERMDISABLE
- xtract_cell_decl IBUFDS_GTE2
- xtract_cell_decl IBUFDS_IBUFDISABLE
- xtract_cell_decl IBUFDS_INTERMDISABLE
+ # xtract_cell_decl IBUF "(* iopad_external_pin = \"I\" *)"
+ xtract_cell_decl IBUF_IBUFDISABLE "(* iopad_external_pin = \"I\" *)"
+ xtract_cell_decl IBUF_INTERMDISABLE "(* iopad_external_pin = \"I\" *)"
+ xtract_cell_decl IBUFDS "(* iopad_external_pin = \"I,IB\" *)"
+ xtract_cell_decl IBUFDS_DIFF_OUT "(* iopad_external_pin = \"I,IB\" *)"
+ xtract_cell_decl IBUFDS_DIFF_OUT_IBUFDISABLE "(* iopad_external_pin = \"I,IB\" *)"
+ xtract_cell_decl IBUFDS_DIFF_OUT_INTERMDISABLE "(* iopad_external_pin = \"I,IB\" *)"
+ xtract_cell_decl IBUFDS_GTE2 "(* iopad_external_pin = \"I,IB\" *)"
+ xtract_cell_decl IBUFDS_IBUFDISABLE "(* iopad_external_pin = \"I,IB\" *)"
+ xtract_cell_decl IBUFDS_INTERMDISABLE "(* iopad_external_pin = \"I,IB\" *)"
+ xtract_cell_decl IBUFG "(* iopad_external_pin = \"I\" *)"
+ xtract_cell_decl IBUFGDS "(* iopad_external_pin = \"I,IB\" *)"
+ xtract_cell_decl IBUFGDS_DIFF_OUT "(* iopad_external_pin = \"I,IB\" *)"
xtract_cell_decl ICAPE2 "(* keep *)"
- xtract_cell_decl IDDR
- xtract_cell_decl IDDR_2CLK
- xtract_cell_decl IDELAYCTRL "(* keep *)"
- xtract_cell_decl IDELAYE2
- xtract_cell_decl IN_FIFO
- xtract_cell_decl IOBUF
- xtract_cell_decl IOBUF_DCIEN
- xtract_cell_decl IOBUF_INTERMDISABLE
- xtract_cell_decl IOBUFDS
- xtract_cell_decl IOBUFDS_DCIEN
- xtract_cell_decl IOBUFDS_DIFF_OUT
- xtract_cell_decl IOBUFDS_DIFF_OUT_DCIEN
- xtract_cell_decl IOBUFDS_DIFF_OUT_INTERMDISABLE
- xtract_cell_decl ISERDESE2
+ xtract_cell_decl IDDR "(* clkbuf_sink = \"C\" *)"
+ xtract_cell_decl IDDR_2CLK "(* clkbuf_sink = \"C,CB\" *)"
+ xtract_cell_decl IDELAYCTRL "(* keep *) (* clkbuf_sink = \"REFCLK\" *)"
+ xtract_cell_decl IDELAYE2 "(* clkbuf_sink = \"C\" *)"
+ xtract_cell_decl IN_FIFO "(* clkbuf_sink = \"RDCLK,WRCLK\" *)"
+ xtract_cell_decl IOBUF "(* iopad_external_pin = \"IO\" *)"
+ xtract_cell_decl IOBUF_DCIEN "(* iopad_external_pin = \"IO\" *)"
+ xtract_cell_decl IOBUF_INTERMDISABLE "(* iopad_external_pin = \"IO\" *)"
+ xtract_cell_decl IOBUFDS "(* iopad_external_pin = \"IO\" *)"
+ xtract_cell_decl IOBUFDS_DCIEN "(* iopad_external_pin = \"IO,IOB\" *)"
+ xtract_cell_decl IOBUFDS_DIFF_OUT "(* iopad_external_pin = \"IO,IOB\" *)"
+ xtract_cell_decl IOBUFDS_DIFF_OUT_DCIEN "(* iopad_external_pin = \"IO,IOB\" *)"
+ xtract_cell_decl IOBUFDS_DIFF_OUT_INTERMDISABLE "(* iopad_external_pin = \"IO,IOB\" *)"
+ xtract_cell_decl ISERDESE2 "(* clkbuf_sink = \"CLK,CLKB,CLKDIV,CLKDIVP,OCLK,OCLKB\" *)"
xtract_cell_decl KEEPER
xtract_cell_decl LDCE
xtract_cell_decl LDPE
@@ -97,14 +105,14 @@ function xtract_cell_decl()
xtract_cell_decl MMCME2_BASE
# xtract_cell_decl MUXF7
# xtract_cell_decl MUXF8
- # xtract_cell_decl OBUF
- xtract_cell_decl OBUFDS
- xtract_cell_decl OBUFT
- xtract_cell_decl OBUFTDS
- xtract_cell_decl ODDR
- xtract_cell_decl ODELAYE2
- xtract_cell_decl OSERDESE2
- xtract_cell_decl OUT_FIFO
+ # xtract_cell_decl OBUF "(* iopad_external_pin = \"O\" *)"
+ xtract_cell_decl OBUFDS "(* iopad_external_pin = \"O,OB\" *)"
+ xtract_cell_decl OBUFT "(* iopad_external_pin = \"O\" *)"
+ xtract_cell_decl OBUFTDS "(* iopad_external_pin = \"O,OB\" *)"
+ xtract_cell_decl ODDR "(* clkbuf_sink = \"C\" *)"
+ xtract_cell_decl ODELAYE2 "(* clkbuf_sink = \"C\" *)"
+ xtract_cell_decl OSERDESE2 "(* clkbuf_sink = \"CLK,CLKDIV\" *)"
+ xtract_cell_decl OUT_FIFO "(* clkbuf_sink = \"RDCLK,WRCLK\" *)"
xtract_cell_decl PHASER_IN
xtract_cell_decl PHASER_IN_PHY
xtract_cell_decl PHASER_OUT
@@ -116,27 +124,27 @@ function xtract_cell_decl()
xtract_cell_decl PS7 "(* keep *)"
xtract_cell_decl PULLDOWN
xtract_cell_decl PULLUP
- #xtract_cell_decl RAM128X1D
- xtract_cell_decl RAM128X1S
- xtract_cell_decl RAM256X1S
- xtract_cell_decl RAM32M
- #xtract_cell_decl RAM32X1D
- xtract_cell_decl RAM32X1S
- xtract_cell_decl RAM32X1S_1
- xtract_cell_decl RAM32X2S
- xtract_cell_decl RAM64M
- #xtract_cell_decl RAM64X1D
- xtract_cell_decl RAM64X1S
- xtract_cell_decl RAM64X1S_1
- xtract_cell_decl RAM64X2S
- # xtract_cell_decl RAMB18E1
- # xtract_cell_decl RAMB36E1
+ #xtract_cell_decl RAM128X1D "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM128X1S "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM256X1S "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM32M "(* clkbuf_sink = \"WCLK\" *)"
+ #xtract_cell_decl RAM32X1D "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM32X1S "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM32X1S_1 "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM32X2S "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM64M "(* clkbuf_sink = \"WCLK\" *)"
+ #xtract_cell_decl RAM64X1D "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM64X1S "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM64X1S_1 "(* clkbuf_sink = \"WCLK\" *)"
+ xtract_cell_decl RAM64X2S "(* clkbuf_sink = \"WCLK\" *)"
+ # xtract_cell_decl RAMB18E1 "(* clkbuf_sink = \"CLKARDCLK,CLKBWRCLK\" *)"
+ # xtract_cell_decl RAMB36E1 "(* clkbuf_sink = \"CLKARDCLK,CLKBWRCLK\" *)"
xtract_cell_decl ROM128X1
xtract_cell_decl ROM256X1
xtract_cell_decl ROM32X1
xtract_cell_decl ROM64X1
- #xtract_cell_decl SRL16E
- #xtract_cell_decl SRLC32E
+ #xtract_cell_decl SRL16E "(* clkbuf_sink = \"CLK\" *)"
+ #xtract_cell_decl SRLC32E "(* clkbuf_sink = \"CLK\" *)"
xtract_cell_decl STARTUPE2 "(* keep *)"
xtract_cell_decl USR_ACCESSE2
xtract_cell_decl XADC
diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v
index 15fa1b63a..0fbbc0fdf 100644
--- a/techlibs/xilinx/cells_xtra.v
+++ b/techlibs/xilinx/cells_xtra.v
@@ -1,5 +1,6 @@
// Created by cells_xtra.sh from Xilinx models
+(* keep *)
module BSCANE2 (...);
parameter DISABLE_JTAG = "FALSE";
parameter integer JTAG_CHAIN = 1;
@@ -16,6 +17,7 @@ module BSCANE2 (...);
input TDO;
endmodule
+(* clkbuf_driver = "O" *)
module BUFGCE (...);
parameter CE_TYPE = "SYNC";
parameter [0:0] IS_CE_INVERTED = 1'b0;
@@ -25,23 +27,28 @@ module BUFGCE (...);
input I;
endmodule
+(* clkbuf_driver = "O" *)
module BUFGCE_1 (...);
output O;
- input CE, I;
+ input CE;
+ input I;
endmodule
+(* clkbuf_driver = "O" *)
module BUFGMUX (...);
parameter CLK_SEL_TYPE = "SYNC";
output O;
input I0, I1, S;
endmodule
+(* clkbuf_driver = "O" *)
module BUFGMUX_1 (...);
parameter CLK_SEL_TYPE = "SYNC";
output O;
input I0, I1, S;
endmodule
+(* clkbuf_driver = "O" *)
module BUFGMUX_CTRL (...);
output O;
input I0;
@@ -49,21 +56,25 @@ module BUFGMUX_CTRL (...);
input S;
endmodule
+(* clkbuf_driver = "O" *)
module BUFH (...);
output O;
input I;
endmodule
+(* clkbuf_driver = "O" *)
module BUFIO (...);
output O;
input I;
endmodule
+(* clkbuf_driver = "O" *)
module BUFMR (...);
output O;
input I;
endmodule
+(* clkbuf_driver = "O" *)
module BUFMRCE (...);
parameter CE_TYPE = "SYNC";
parameter integer INIT_OUT = 0;
@@ -73,6 +84,7 @@ module BUFMRCE (...);
input I;
endmodule
+(* clkbuf_driver = "O" *)
module BUFR (...);
output O;
input CE;
@@ -89,6 +101,7 @@ module CAPTUREE2 (...);
input CLK;
endmodule
+(* clkbuf_sink = "CLK" *)
module CFGLUT5 (...);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
@@ -111,6 +124,7 @@ module DNA_PORT (...);
input CLK, DIN, READ, SHIFT;
endmodule
+(* clkbuf_sink = "CLK" *)
module DSP48E1 (...);
parameter integer ACASCREG = 1;
parameter integer ADREG = 1;
@@ -198,6 +212,7 @@ module EFUSE_USR (...);
output [31:0] EFUSEUSR;
endmodule
+(* clkbuf_sink = "RDCLK,WRCLK" *)
module FIFO18E1 (...);
parameter ALMOST_EMPTY_OFFSET = 13'h0080;
parameter ALMOST_FULL_OFFSET = 13'h0080;
@@ -236,6 +251,7 @@ module FIFO18E1 (...);
input WREN;
endmodule
+(* clkbuf_sink = "RDCLK,WRCLK" *)
module FIFO36E1 (...);
parameter ALMOST_EMPTY_OFFSET = 13'h0080;
parameter ALMOST_FULL_OFFSET = 13'h0080;
@@ -1963,6 +1979,7 @@ module GTXE2_COMMON (...);
input [7:0] PMARSVD;
endmodule
+(* iopad_external_pin = "I" *)
module IBUF_IBUFDISABLE (...);
parameter IBUF_LOW_PWR = "TRUE";
parameter IOSTANDARD = "DEFAULT";
@@ -1973,6 +1990,7 @@ module IBUF_IBUFDISABLE (...);
input IBUFDISABLE;
endmodule
+(* iopad_external_pin = "I" *)
module IBUF_INTERMDISABLE (...);
parameter IBUF_LOW_PWR = "TRUE";
parameter IOSTANDARD = "DEFAULT";
@@ -1984,6 +2002,7 @@ module IBUF_INTERMDISABLE (...);
input INTERMDISABLE;
endmodule
+(* iopad_external_pin = "I,IB" *)
module IBUFDS (...);
parameter CAPACITANCE = "DONT_CARE";
parameter DIFF_TERM = "FALSE";
@@ -1996,6 +2015,7 @@ module IBUFDS (...);
input I, IB;
endmodule
+(* iopad_external_pin = "I,IB" *)
module IBUFDS_DIFF_OUT (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2005,6 +2025,7 @@ module IBUFDS_DIFF_OUT (...);
input I, IB;
endmodule
+(* iopad_external_pin = "I,IB" *)
module IBUFDS_DIFF_OUT_IBUFDISABLE (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2019,6 +2040,7 @@ module IBUFDS_DIFF_OUT_IBUFDISABLE (...);
input IBUFDISABLE;
endmodule
+(* iopad_external_pin = "I,IB" *)
module IBUFDS_DIFF_OUT_INTERMDISABLE (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2034,6 +2056,7 @@ module IBUFDS_DIFF_OUT_INTERMDISABLE (...);
input INTERMDISABLE;
endmodule
+(* iopad_external_pin = "I,IB" *)
module IBUFDS_GTE2 (...);
parameter CLKCM_CFG = "TRUE";
parameter CLKRCV_TRST = "TRUE";
@@ -2045,6 +2068,7 @@ module IBUFDS_GTE2 (...);
input IB;
endmodule
+(* iopad_external_pin = "I,IB" *)
module IBUFDS_IBUFDISABLE (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2058,6 +2082,7 @@ module IBUFDS_IBUFDISABLE (...);
input IBUFDISABLE;
endmodule
+(* iopad_external_pin = "I,IB" *)
module IBUFDS_INTERMDISABLE (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2072,6 +2097,37 @@ module IBUFDS_INTERMDISABLE (...);
input INTERMDISABLE;
endmodule
+(* iopad_external_pin = "I" *)
+module IBUFG (...);
+ parameter CAPACITANCE = "DONT_CARE";
+ parameter IBUF_DELAY_VALUE = "0";
+ parameter IBUF_LOW_PWR = "TRUE";
+ parameter IOSTANDARD = "DEFAULT";
+ output O;
+ input I;
+endmodule
+
+(* iopad_external_pin = "I,IB" *)
+module IBUFGDS (...);
+ parameter CAPACITANCE = "DONT_CARE";
+ parameter DIFF_TERM = "FALSE";
+ parameter IBUF_DELAY_VALUE = "0";
+ parameter IBUF_LOW_PWR = "TRUE";
+ parameter IOSTANDARD = "DEFAULT";
+ output O;
+ input I, IB;
+endmodule
+
+(* iopad_external_pin = "I,IB" *)
+module IBUFGDS_DIFF_OUT (...);
+ parameter DIFF_TERM = "FALSE";
+ parameter DQS_BIAS = "FALSE";
+ parameter IBUF_LOW_PWR = "TRUE";
+ parameter IOSTANDARD = "DEFAULT";
+ output O, OB;
+ input I, IB;
+endmodule
+
(* keep *)
module ICAPE2 (...);
parameter [31:0] DEVICE_ID = 32'h04244093;
@@ -2084,6 +2140,7 @@ module ICAPE2 (...);
input [31:0] I;
endmodule
+(* clkbuf_sink = "C" *)
module IDDR (...);
parameter DDR_CLK_EDGE = "OPPOSITE_EDGE";
parameter INIT_Q1 = 1'b0;
@@ -2102,6 +2159,7 @@ module IDDR (...);
input S;
endmodule
+(* clkbuf_sink = "C,CB" *)
module IDDR_2CLK (...);
parameter DDR_CLK_EDGE = "OPPOSITE_EDGE";
parameter INIT_Q1 = 1'b0;
@@ -2120,7 +2178,7 @@ module IDDR_2CLK (...);
input S;
endmodule
-(* keep *)
+(* keep *) (* clkbuf_sink = "REFCLK" *)
module IDELAYCTRL (...);
parameter SIM_DEVICE = "7SERIES";
output RDY;
@@ -2128,6 +2186,7 @@ module IDELAYCTRL (...);
input RST;
endmodule
+(* clkbuf_sink = "C" *)
module IDELAYE2 (...);
parameter CINVCTRL_SEL = "FALSE";
parameter DELAY_SRC = "IDATAIN";
@@ -2155,6 +2214,7 @@ module IDELAYE2 (...);
input REGRST;
endmodule
+(* clkbuf_sink = "RDCLK,WRCLK" *)
module IN_FIFO (...);
parameter integer ALMOST_EMPTY_VALUE = 1;
parameter integer ALMOST_FULL_VALUE = 1;
@@ -2191,6 +2251,7 @@ module IN_FIFO (...);
input [7:0] D6;
endmodule
+(* iopad_external_pin = "IO" *)
module IOBUF (...);
parameter integer DRIVE = 12;
parameter IBUF_LOW_PWR = "TRUE";
@@ -2201,6 +2262,7 @@ module IOBUF (...);
input I, T;
endmodule
+(* iopad_external_pin = "IO" *)
module IOBUF_DCIEN (...);
parameter integer DRIVE = 12;
parameter IBUF_LOW_PWR = "TRUE";
@@ -2216,6 +2278,7 @@ module IOBUF_DCIEN (...);
input T;
endmodule
+(* iopad_external_pin = "IO" *)
module IOBUF_INTERMDISABLE (...);
parameter integer DRIVE = 12;
parameter IBUF_LOW_PWR = "TRUE";
@@ -2231,6 +2294,7 @@ module IOBUF_INTERMDISABLE (...);
input T;
endmodule
+(* iopad_external_pin = "IO" *)
module IOBUFDS (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2242,6 +2306,7 @@ module IOBUFDS (...);
input I, T;
endmodule
+(* iopad_external_pin = "IO,IOB" *)
module IOBUFDS_DCIEN (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2259,6 +2324,7 @@ module IOBUFDS_DCIEN (...);
input T;
endmodule
+(* iopad_external_pin = "IO,IOB" *)
module IOBUFDS_DIFF_OUT (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2273,6 +2339,7 @@ module IOBUFDS_DIFF_OUT (...);
input TS;
endmodule
+(* iopad_external_pin = "IO,IOB" *)
module IOBUFDS_DIFF_OUT_DCIEN (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2291,6 +2358,7 @@ module IOBUFDS_DIFF_OUT_DCIEN (...);
input TS;
endmodule
+(* iopad_external_pin = "IO,IOB" *)
module IOBUFDS_DIFF_OUT_INTERMDISABLE (...);
parameter DIFF_TERM = "FALSE";
parameter DQS_BIAS = "FALSE";
@@ -2309,6 +2377,7 @@ module IOBUFDS_DIFF_OUT_INTERMDISABLE (...);
input TS;
endmodule
+(* clkbuf_sink = "CLK,CLKB,CLKDIV,CLKDIVP,OCLK,OCLKB" *)
module ISERDESE2 (...);
parameter DATA_RATE = "DDR";
parameter integer DATA_WIDTH = 4;
@@ -2529,6 +2598,7 @@ module MMCME2_BASE (...);
input RST;
endmodule
+(* iopad_external_pin = "O,OB" *)
module OBUFDS (...);
parameter CAPACITANCE = "DONT_CARE";
parameter IOSTANDARD = "DEFAULT";
@@ -2537,6 +2607,7 @@ module OBUFDS (...);
input I;
endmodule
+(* iopad_external_pin = "O" *)
module OBUFT (...);
parameter CAPACITANCE = "DONT_CARE";
parameter integer DRIVE = 12;
@@ -2546,6 +2617,7 @@ module OBUFT (...);
input I, T;
endmodule
+(* iopad_external_pin = "O,OB" *)
module OBUFTDS (...);
parameter CAPACITANCE = "DONT_CARE";
parameter IOSTANDARD = "DEFAULT";
@@ -2554,6 +2626,7 @@ module OBUFTDS (...);
input I, T;
endmodule
+(* clkbuf_sink = "C" *)
module ODDR (...);
output Q;
input C;
@@ -2572,6 +2645,7 @@ module ODDR (...);
parameter XON = "TRUE";
endmodule
+(* clkbuf_sink = "C" *)
module ODELAYE2 (...);
parameter CINVCTRL_SEL = "FALSE";
parameter DELAY_SRC = "ODATAIN";
@@ -2598,6 +2672,7 @@ module ODELAYE2 (...);
input REGRST;
endmodule
+(* clkbuf_sink = "CLK,CLKDIV" *)
module OSERDESE2 (...);
parameter DATA_RATE_OQ = "DDR";
parameter DATA_RATE_TQ = "DDR";
@@ -2653,6 +2728,7 @@ module OSERDESE2 (...);
input TCE;
endmodule
+(* clkbuf_sink = "RDCLK,WRCLK" *)
module OUT_FIFO (...);
parameter integer ALMOST_EMPTY_VALUE = 1;
parameter integer ALMOST_FULL_VALUE = 1;
@@ -3655,6 +3731,7 @@ module PULLUP (...);
output O;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM128X1S (...);
parameter [127:0] INIT = 128'h00000000000000000000000000000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
@@ -3662,6 +3739,7 @@ module RAM128X1S (...);
input A0, A1, A2, A3, A4, A5, A6, D, WCLK, WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM256X1S (...);
parameter [255:0] INIT = 256'h0;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
@@ -3672,6 +3750,7 @@ module RAM256X1S (...);
input WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM32M (...);
parameter [63:0] INIT_A = 64'h0000000000000000;
parameter [63:0] INIT_B = 64'h0000000000000000;
@@ -3694,6 +3773,7 @@ module RAM32M (...);
input WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM32X1S (...);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
@@ -3701,6 +3781,7 @@ module RAM32X1S (...);
input A0, A1, A2, A3, A4, D, WCLK, WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM32X1S_1 (...);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
@@ -3708,6 +3789,7 @@ module RAM32X1S_1 (...);
input A0, A1, A2, A3, A4, D, WCLK, WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM32X2S (...);
parameter [31:0] INIT_00 = 32'h00000000;
parameter [31:0] INIT_01 = 32'h00000000;
@@ -3716,6 +3798,7 @@ module RAM32X2S (...);
input A0, A1, A2, A3, A4, D0, D1, WCLK, WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM64M (...);
parameter [63:0] INIT_A = 64'h0000000000000000;
parameter [63:0] INIT_B = 64'h0000000000000000;
@@ -3738,6 +3821,7 @@ module RAM64M (...);
input WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM64X1S (...);
parameter [63:0] INIT = 64'h0000000000000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
@@ -3745,6 +3829,7 @@ module RAM64X1S (...);
input A0, A1, A2, A3, A4, A5, D, WCLK, WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM64X1S_1 (...);
parameter [63:0] INIT = 64'h0000000000000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
@@ -3752,6 +3837,7 @@ module RAM64X1S_1 (...);
input A0, A1, A2, A3, A4, A5, D, WCLK, WE;
endmodule
+(* clkbuf_sink = "WCLK" *)
module RAM64X2S (...);
parameter [63:0] INIT_00 = 64'h0000000000000000;
parameter [63:0] INIT_01 = 64'h0000000000000000;
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index d143c6823..a7362d26b 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -63,6 +63,9 @@ struct SynthXilinxPass : public ScriptPass
log(" generate an output netlist (and BLIF file) suitable for VPR\n");
log(" (this feature is experimental and incomplete)\n");
log("\n");
+ log(" -ise\n");
+ log(" generate an output netlist suitable for ISE\n");
+ log("\n");
log(" -nobram\n");
log(" disable inference of block rams\n");
log("\n");
@@ -78,6 +81,12 @@ struct SynthXilinxPass : public ScriptPass
log(" -nowidelut\n");
log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
log("\n");
+ log(" -iopads\n");
+ log(" perform I/O buffer insertion (selected automatically by -ise)\n");
+ log("\n");
+ log(" -noiopads\n");
+ log(" disable I/O buffer insertion (only useful with -ise)\n");
+ log("\n");
log(" -widemux <int>\n");
log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
log(" above this number of inputs (minimum value 2, recommended value >= 5).\n");
@@ -104,7 +113,7 @@ struct SynthXilinxPass : public ScriptPass
}
std::string top_opt, edif_file, blif_file, family;
- bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, abc9;
+ bool flatten, retime, vpr, ise, iopads, noiopads, nobram, nodram, nosrl, nocarry, nowidelut, abc9;
int widemux;
void clear_flags() YS_OVERRIDE
@@ -116,6 +125,9 @@ struct SynthXilinxPass : public ScriptPass
flatten = false;
retime = false;
vpr = false;
+ ise = false;
+ iopads = false;
+ noiopads = false;
nocarry = false;
nobram = false;
nodram = false;
@@ -178,6 +190,18 @@ struct SynthXilinxPass : public ScriptPass
vpr = true;
continue;
}
+ if (args[argidx] == "-ise") {
+ ise = true;
+ continue;
+ }
+ if (args[argidx] == "-iopads") {
+ iopads = true;
+ continue;
+ }
+ if (args[argidx] == "-noiopads") {
+ noiopads = true;
+ continue;
+ }
if (args[argidx] == "-nocarry") {
nocarry = true;
continue;
@@ -410,6 +434,17 @@ struct SynthXilinxPass : public ScriptPass
run("clean");
}
+ if (check_label("finalize")) {
+ bool do_iopads = iopads || (ise && !noiopads);
+ if (help_mode || do_iopads)
+ run("clkbufmap -buf BUFG O:I -inpad IBUFG O:I", "(-inpad passed if '-iopads' or '-ise' and not '-noiopads')");
+ else
+ run("clkbufmap -buf BUFG O:I");
+
+ if (do_iopads)
+ run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopads' or '-ise' and not '-noiopads')");
+ }
+
if (check_label("check")) {
run("hierarchy -check");
run("stat -tech xilinx");
diff --git a/techlibs/xilinx/xc6s_brams_bb.v b/techlibs/xilinx/xc6s_brams_bb.v
index eb1a29579..1287e2c53 100644
--- a/techlibs/xilinx/xc6s_brams_bb.v
+++ b/techlibs/xilinx/xc6s_brams_bb.v
@@ -1,3 +1,4 @@
+(* clkbuf_sink = "CLKAWRCLK,CLKBRDCLK" *)
module RAMB8BWER (
input CLKAWRCLK,
input CLKBRDCLK,
@@ -86,6 +87,7 @@ module RAMB8BWER (
parameter SIM_COLLISION_CHECK = "ALL";
endmodule
+(* clkbuf_sink = "CLKA,CLKB" *)
module RAMB16BWER (
input CLKA,
input CLKB,
diff --git a/techlibs/xilinx/xc7_brams_bb.v b/techlibs/xilinx/xc7_brams_bb.v
index a682ba4a7..046a8fa26 100644
--- a/techlibs/xilinx/xc7_brams_bb.v
+++ b/techlibs/xilinx/xc7_brams_bb.v
@@ -1,3 +1,4 @@
+(* clkbuf_sink = "CLKARDCLK,CLKBWRCLK" *)
module RAMB18E1 (
input CLKARDCLK,
input CLKBWRCLK,
@@ -122,6 +123,7 @@ module RAMB18E1 (
parameter SIM_DEVICE = "VIRTEX6";
endmodule
+(* clkbuf_sink = "CLKARDCLK,CLKBWRCLK" *)
module RAMB36E1 (
input CLKARDCLK,
input CLKBWRCLK,