diff options
author | Marcin KoĆcielnicki <koriakin@0x04.net> | 2019-08-12 15:57:43 +0000 |
---|---|---|
committer | Marcin KoĆcielnicki <koriakin@0x04.net> | 2019-08-13 00:16:38 +0200 |
commit | f4c62f33ac56bc5725c44ad822e75d2387f98061 (patch) | |
tree | 4a1659237670042c8709777d660b14be57cb004f /techlibs/xilinx | |
parent | 78b30bbb1102047585d1a2eac89b1c7f5ca7344e (diff) | |
download | yosys-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.v | 16 | ||||
-rw-r--r-- | techlibs/xilinx/cells_xtra.sh | 144 | ||||
-rw-r--r-- | techlibs/xilinx/cells_xtra.v | 90 | ||||
-rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 37 | ||||
-rw-r--r-- | techlibs/xilinx/xc6s_brams_bb.v | 2 | ||||
-rw-r--r-- | techlibs/xilinx/xc7_brams_bb.v | 2 |
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, |