3 from argparse
import ArgumentParser
4 from io
import StringIO
5 from enum
import Enum
, auto
12 def __init__(self
, name
, keep
=False, port_attrs
={}):
15 self
.port_attrs
= port_attrs
19 # Design element types listed in:
21 # - UG613 (Spartan 3A)
22 # - UG617 (Spartan 3E)
28 # - UG974 (Ultrascale)
31 # Cell('RAM16X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
32 # Cell('RAM16X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
33 # Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
34 # Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
35 # Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
36 # Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
37 # Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
38 # Cell('RAM128X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
39 # Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
40 # Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
41 # Cell('RAM16X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
42 # Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
43 # Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
44 # Cell('RAM16X4S', port_attrs={'WCLK': ['clkbuf_sink']}),
45 # Cell('RAM32X4S', port_attrs={'WCLK': ['clkbuf_sink']}),
46 # Cell('RAM16X8S', port_attrs={'WCLK': ['clkbuf_sink']}),
47 # Cell('RAM32X8S', port_attrs={'WCLK': ['clkbuf_sink']}),
48 # Cell('RAM16X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
49 # Cell('RAM16X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}),
50 # Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
51 # Cell('RAM32X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}),
52 # Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
53 # Cell('RAM64X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}),
54 # Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
55 # Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
56 # Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
57 # Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}),
58 # Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
59 # Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}),
66 # CLB -- registers/latches.
67 # Virtex 1/2/4/5, Spartan 3.
68 # Cell('FDCPE', port_attrs={'C': ['clkbuf_sink']}),
69 # Cell('FDRSE', port_attrs={'C': ['clkbuf_sink']}),
70 # Cell('LDCPE', port_attrs={'C': ['clkbuf_sink']}),
71 # Virtex 6, Spartan 6, Series 7, Ultrascale.
100 # Cell('SRL16', port_attrs={'CLK': ['clkbuf_sink']}),
101 # Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
102 # Cell('SRLC16', port_attrs={'CLK': ['clkbuf_sink']}),
103 # Cell('SRLC16E', port_attrs={'CLK': ['clkbuf_sink']}),
104 # Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
105 # Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
110 # Virtex 2, Spartan 3.
111 Cell('RAMB16_S1', port_attrs
={'CLK': ['clkbuf_sink']}),
112 Cell('RAMB16_S2', port_attrs
={'CLK': ['clkbuf_sink']}),
113 Cell('RAMB16_S4', port_attrs
={'CLK': ['clkbuf_sink']}),
114 Cell('RAMB16_S9', port_attrs
={'CLK': ['clkbuf_sink']}),
115 Cell('RAMB16_S18', port_attrs
={'CLK': ['clkbuf_sink']}),
116 Cell('RAMB16_S36', port_attrs
={'CLK': ['clkbuf_sink']}),
117 Cell('RAMB16_S1_S1', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
118 Cell('RAMB16_S1_S2', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
119 Cell('RAMB16_S1_S4', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
120 Cell('RAMB16_S1_S9', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
121 Cell('RAMB16_S1_S18', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
122 Cell('RAMB16_S1_S36', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
123 Cell('RAMB16_S2_S2', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
124 Cell('RAMB16_S2_S4', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
125 Cell('RAMB16_S2_S9', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
126 Cell('RAMB16_S2_S18', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
127 Cell('RAMB16_S2_S36', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
128 Cell('RAMB16_S4_S4', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
129 Cell('RAMB16_S4_S9', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
130 Cell('RAMB16_S4_S18', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
131 Cell('RAMB16_S4_S36', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
132 Cell('RAMB16_S9_S9', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
133 Cell('RAMB16_S9_S18', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
134 Cell('RAMB16_S9_S36', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
135 Cell('RAMB16_S18_S18', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
136 Cell('RAMB16_S18_S36', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
137 Cell('RAMB16_S36_S36', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
138 # Spartan 3A (in addition to above).
139 Cell('RAMB16BWE_S18', port_attrs
={'CLK': ['clkbuf_sink']}),
140 Cell('RAMB16BWE_S36', port_attrs
={'CLK': ['clkbuf_sink']}),
141 Cell('RAMB16BWE_S18_S9', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
142 Cell('RAMB16BWE_S18_S18', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
143 Cell('RAMB16BWE_S36_S9', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
144 Cell('RAMB16BWE_S36_S18', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
145 Cell('RAMB16BWE_S36_S36', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
147 Cell('RAMB16BWER', port_attrs
={ 'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
148 # Spartan 6 (in addition to above).
149 Cell('RAMB8BWER', port_attrs
={ 'CLKAWRCLK': ['clkbuf_sink'], 'CLKBRDCLK': ['clkbuf_sink']}),
151 Cell('FIFO16', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
152 Cell('RAMB16', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
153 Cell('RAMB32_S64_ECC', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
155 Cell('FIFO18', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
156 Cell('FIFO18_36', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
157 Cell('FIFO36', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
158 Cell('FIFO36_72', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
159 Cell('RAMB18', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
160 Cell('RAMB36', port_attrs
={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
161 Cell('RAMB18SDP', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
162 Cell('RAMB36SDP', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
163 # Virtex 6 / Series 7.
164 Cell('FIFO18E1', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
165 Cell('FIFO36E1', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
166 #Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']]}),
167 #Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']]}),
169 Cell('FIFO18E2', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
170 Cell('FIFO36E2', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
171 Cell('RAMB18E2', port_attrs
={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
172 Cell('RAMB36E2', port_attrs
={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
175 Cell('URAM288', port_attrs
={'CLK': ['clkbuf_sink']}),
176 Cell('URAM288_BASE', port_attrs
={'CLK': ['clkbuf_sink']}),
178 # Multipliers and DSP.
179 # Cell('MULT18X18'), # Virtex 2, Spartan 3
180 # Cell('MULT18X18S', port_attrs={'C': ['clkbuf_sink']}), # Spartan 3
181 # Cell('MULT18X18SIO', port_attrs={'CLK': ['clkbuf_sink']}), # Spartan 3E
182 # Cell('DSP48A', port_attrs={'CLK': ['clkbuf_sink']}), # Spartan 3A DSP
183 # Cell('DSP48A1', port_attrs={'CLK': ['clkbuf_sink']}), # Spartan 6
184 # Cell('DSP48', port_attrs={'CLK': ['clkbuf_sink']}), # Virtex 4
185 Cell('DSP48E', port_attrs
={'CLK': ['clkbuf_sink']}), # Virtex 5
186 #Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}), # Virtex 6 / Series 7
187 Cell('DSP48E2', port_attrs
={'CLK': ['clkbuf_sink']}), # Ultrascale
190 # Virtex 2, Spartan 3.
191 Cell('IFDDRCPE', port_attrs
={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'D': ['iopad_external_pin']}),
192 Cell('IFDDRRSE', port_attrs
={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'D': ['iopad_external_pin']}),
193 Cell('OFDDRCPE', port_attrs
={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'Q': ['iopad_external_pin']}),
194 Cell('OFDDRRSE', port_attrs
={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'Q': ['iopad_external_pin']}),
195 Cell('OFDDRTCPE', port_attrs
={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'O': ['iopad_external_pin']}),
196 Cell('OFDDRTRSE', port_attrs
={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'O': ['iopad_external_pin']}),
198 Cell('IDDR2', port_attrs
={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
199 Cell('ODDR2', port_attrs
={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
201 Cell('IDDR', port_attrs
={'C': ['clkbuf_sink']}),
202 Cell('IDDR_2CLK', port_attrs
={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
203 Cell('ODDR', port_attrs
={'C': ['clkbuf_sink']}),
204 Cell('IDELAYCTRL', keep
=True, port_attrs
={'REFCLK': ['clkbuf_sink']}),
205 Cell('IDELAY', port_attrs
={'C': ['clkbuf_sink']}),
206 Cell('ISERDES', port_attrs
={
207 'CLK': ['clkbuf_sink'],
208 'OCLK': ['clkbuf_sink'],
209 'CLKDIV': ['clkbuf_sink'],
211 Cell('OSERDES', port_attrs
={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
213 Cell('IODELAY', port_attrs
={'C': ['clkbuf_sink']}),
214 Cell('ISERDES_NODELAY', port_attrs
={
215 'CLK': ['clkbuf_sink'],
216 'CLKB': ['clkbuf_sink'],
217 'OCLK': ['clkbuf_sink'],
218 'CLKDIV': ['clkbuf_sink'],
221 Cell('IODELAYE1', port_attrs
={'C': ['clkbuf_sink']}),
222 Cell('ISERDESE1', port_attrs
={
223 'CLK': ['clkbuf_sink'],
224 'CLKB': ['clkbuf_sink'],
225 'OCLK': ['clkbuf_sink'],
226 'CLKDIV': ['clkbuf_sink'],
228 Cell('OSERDESE1', port_attrs
={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
230 Cell('IDELAYE2', port_attrs
={'C': ['clkbuf_sink']}),
231 Cell('ODELAYE2', port_attrs
={'C': ['clkbuf_sink']}),
232 Cell('ISERDESE2', port_attrs
={
233 'CLK': ['clkbuf_sink'],
234 'CLKB': ['clkbuf_sink'],
235 'OCLK': ['clkbuf_sink'],
236 'OCLKB': ['clkbuf_sink'],
237 'CLKDIV': ['clkbuf_sink'],
238 'CLKDIVP': ['clkbuf_sink'],
240 Cell('OSERDESE2', port_attrs
={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
242 Cell('PHASER_IN_PHY'),
244 Cell('PHASER_OUT_PHY'),
248 Cell('IDDRE1', port_attrs
={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
249 Cell('ODDRE1', port_attrs
={'C': ['clkbuf_sink']}),
250 Cell('IDELAYE3', port_attrs
={'CLK': ['clkbuf_sink']}),
251 Cell('ODELAYE3', port_attrs
={'CLK': ['clkbuf_sink']}),
252 Cell('ISERDESE3', port_attrs
={
253 'CLK': ['clkbuf_sink'],
254 'CLK_B': ['clkbuf_sink'],
255 'FIFO_RD_CLK': ['clkbuf_sink'],
256 'CLKDIV': ['clkbuf_sink'],
258 Cell('OSERDESE3', port_attrs
={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
259 Cell('BITSLICE_CONTROL', keep
=True),
262 Cell('RXTX_BITSLICE'),
264 Cell('TX_BITSLICE_TRI'),
266 Cell('IODELAY2', port_attrs
={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
267 Cell('IODRP2', port_attrs
={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
268 Cell('IODRP2_MCB', port_attrs
={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
269 Cell('ISERDES2', port_attrs
={
270 'CLK0': ['clkbuf_sink'],
271 'CLK1': ['clkbuf_sink'],
272 'CLKDIV': ['clkbuf_sink'],
274 Cell('OSERDES2', port_attrs
={
275 'CLK0': ['clkbuf_sink'],
276 'CLK1': ['clkbuf_sink'],
277 'CLKDIV': ['clkbuf_sink'],
282 # Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
283 Cell('IBUF_DLY_ADJ', port_attrs
={'I': ['iopad_external_pin']}),
284 Cell('IBUF_IBUFDISABLE', port_attrs
={'I': ['iopad_external_pin']}),
285 Cell('IBUF_INTERMDISABLE', port_attrs
={'I': ['iopad_external_pin']}),
286 Cell('IBUF_ANALOG', port_attrs
={'I': ['iopad_external_pin']}),
287 Cell('IBUFE3', port_attrs
={'I': ['iopad_external_pin']}),
288 Cell('IBUFDS', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
289 Cell('IBUFDS_DLY_ADJ', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
290 Cell('IBUFDS_IBUFDISABLE', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
291 Cell('IBUFDS_INTERMDISABLE', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
292 Cell('IBUFDS_DIFF_OUT', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
293 Cell('IBUFDS_DIFF_OUT_IBUFDISABLE', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
294 Cell('IBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
295 Cell('IBUFDSE3', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
296 Cell('IBUFDS_DPHY', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
297 # Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
298 Cell('IBUFGDS', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
299 Cell('IBUFGDS_DIFF_OUT', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
301 # Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
302 Cell('IOBUF_DCIEN', port_attrs
={'IO': ['iopad_external_pin']}),
303 Cell('IOBUF_INTERMDISABLE', port_attrs
={'IO': ['iopad_external_pin']}),
304 Cell('IOBUFE3', port_attrs
={'IO': ['iopad_external_pin']}),
305 Cell('IOBUFDS', port_attrs
={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
306 Cell('IOBUFDS_DCIEN', port_attrs
={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
307 Cell('IOBUFDS_INTERMDISABLE', port_attrs
={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
308 Cell('IOBUFDS_DIFF_OUT', port_attrs
={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
309 Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs
={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
310 Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs
={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
311 Cell('IOBUFDSE3', port_attrs
={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
313 # Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
314 Cell('OBUFDS', port_attrs
={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
315 Cell('OBUFDS_DPHY', port_attrs
={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
317 # Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
318 Cell('OBUFTDS', port_attrs
={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
324 Cell('DCIRESET', keep
=True),
325 Cell('HPIO_VREF'), # Ultrascale
327 # Clock buffers (global).
328 # Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
329 Cell('BUFGCE', port_attrs
={'O': ['clkbuf_driver']}),
330 Cell('BUFGCE_1', port_attrs
={'O': ['clkbuf_driver']}),
331 Cell('BUFGMUX', port_attrs
={'O': ['clkbuf_driver']}),
332 Cell('BUFGMUX_1', port_attrs
={'O': ['clkbuf_driver']}),
333 #Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
334 Cell('BUFGMUX_CTRL', port_attrs
={'O': ['clkbuf_driver']}),
335 Cell('BUFGMUX_VIRTEX4', port_attrs
={'O': ['clkbuf_driver']}),
336 Cell('BUFG_GT', port_attrs
={'O': ['clkbuf_driver']}),
337 Cell('BUFG_GT_SYNC'),
338 Cell('BUFG_PS', port_attrs
={'O': ['clkbuf_driver']}),
339 Cell('BUFGCE_DIV', port_attrs
={'O': ['clkbuf_driver']}),
340 Cell('BUFH', port_attrs
={'O': ['clkbuf_driver']}),
341 #Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}),
343 # Clock buffers (IO) -- Spartan 6.
344 Cell('BUFIO2', port_attrs
={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}),
345 Cell('BUFIO2_2CLK', port_attrs
={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}),
346 Cell('BUFIO2FB', port_attrs
={'O': ['clkbuf_driver']}),
347 Cell('BUFPLL', port_attrs
={'IOCLK': ['clkbuf_driver']}),
348 Cell('BUFPLL_MCB', port_attrs
={'IOCLK0': ['clkbuf_driver'], 'IOCLK1': ['clkbuf_driver']}),
350 # Clock buffers (IO and regional) -- Virtex.
351 Cell('BUFIO', port_attrs
={'O': ['clkbuf_driver']}),
352 Cell('BUFIODQS', port_attrs
={'O': ['clkbuf_driver']}),
353 Cell('BUFR', port_attrs
={'O': ['clkbuf_driver']}),
354 Cell('BUFMR', port_attrs
={'O': ['clkbuf_driver']}),
355 Cell('BUFMRCE', port_attrs
={'O': ['clkbuf_driver']}),
362 # Virtex 2, Spartan 3.
366 # Spartan 6 (also uses DCM_SP and PLL_BASE).
398 # Series 7 I/O FIFOs.
399 Cell('IN_FIFO', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
400 Cell('OUT_FIFO', port_attrs
={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
401 # Ultrascale special synchronizer register.
402 Cell('HARD_SYNC', port_attrs
={'CLK': ['clkbuf_sink']}),
406 # TODO: STARTUP_VIRTEX
407 # TODO: STARTUP_VIRTEX2
408 Cell('STARTUP_SPARTAN3', keep
=True),
409 Cell('STARTUP_SPARTAN3E', keep
=True),
410 Cell('STARTUP_SPARTAN3A', keep
=True),
411 Cell('STARTUP_SPARTAN6', keep
=True),
412 Cell('STARTUP_VIRTEX4', keep
=True),
413 Cell('STARTUP_VIRTEX5', keep
=True),
414 Cell('STARTUP_VIRTEX6', keep
=True),
415 Cell('STARTUPE2', keep
=True), # Series 7
416 Cell('STARTUPE3', keep
=True), # Ultrascale
418 # TODO: CAPTURE_VIRTEX
419 # TODO: CAPTURE_VIRTEX2
420 Cell('CAPTURE_SPARTAN3', keep
=True),
421 Cell('CAPTURE_SPARTAN3A', keep
=True),
422 Cell('CAPTURE_VIRTEX4', keep
=True),
423 Cell('CAPTURE_VIRTEX5', keep
=True),
424 Cell('CAPTURE_VIRTEX6', keep
=True),
425 Cell('CAPTUREE2', keep
=True), # Series 7
426 # Internal Configuration Access Port.
428 Cell('ICAP_SPARTAN3A', keep
=True),
429 Cell('ICAP_SPARTAN6', keep
=True),
430 Cell('ICAP_VIRTEX4', keep
=True),
431 Cell('ICAP_VIRTEX5', keep
=True),
432 Cell('ICAP_VIRTEX6', keep
=True),
433 Cell('ICAPE2', keep
=True), # Series 7
434 Cell('ICAPE3', keep
=True), # Ultrascale
437 # TODO: BSCAN_VIRTEX2
438 Cell('BSCAN_SPARTAN3', keep
=True),
439 Cell('BSCAN_SPARTAN3A', keep
=True),
440 Cell('BSCAN_SPARTAN6', keep
=True),
441 Cell('BSCAN_VIRTEX4', keep
=True),
442 Cell('BSCAN_VIRTEX5', keep
=True),
443 Cell('BSCAN_VIRTEX6', keep
=True),
444 Cell('BSCANE2', keep
=True), # Series 7, Ultrascale
446 Cell('DNA_PORT'), # Virtex 5/6, Series 7, Spartan 3A/6
447 Cell('DNA_PORTE2'), # Ultrascale
449 Cell('FRAME_ECC_VIRTEX4'),
450 Cell('FRAME_ECC_VIRTEX5'),
451 Cell('FRAME_ECC_VIRTEX6'),
452 Cell('FRAME_ECCE2'), # Series 7
453 Cell('FRAME_ECCE3'), # Ultrascale
454 # AXSS command access.
455 Cell('USR_ACCESS_VIRTEX4'),
456 Cell('USR_ACCESS_VIRTEX5'),
457 Cell('USR_ACCESS_VIRTEX6'),
458 Cell('USR_ACCESSE2'), # Series 7, Ultrascale
460 Cell('POST_CRC_INTERNAL'), # Spartan 6
461 Cell('SUSPEND_SYNC', keep
=True), # Spartan 6
462 Cell('KEY_CLEAR', keep
=True), # Virtex 5
463 Cell('MASTER_JTAG', keep
=True), # Ultrascale
464 Cell('SPI_ACCESS', keep
=True), # Spartan 3AN
468 Cell('SYSMON'), # Virtex 5/6
469 Cell('XADC'), # Series 7
470 Cell('SYSMONE1'), # Ultrascale
471 Cell('SYSMONE4'), # Ultrascale+
473 # Gigabit transceivers.
487 Cell('CRC32', port_attrs
={'CRCCLK': ['clkbuf_sink']}),
488 Cell('CRC64', port_attrs
={'CRCCLK': ['clkbuf_sink']}),
492 Cell('IBUFDS_GTXE1', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
493 Cell('IBUFDS_GTHE1', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
495 Cell('GTHE2_CHANNEL'),
496 Cell('GTHE2_COMMON'),
497 Cell('GTPE2_CHANNEL'),
498 Cell('GTPE2_COMMON'),
499 Cell('GTXE2_CHANNEL'),
500 Cell('GTXE2_COMMON'),
501 Cell('IBUFDS_GTE2', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
503 Cell('GTHE3_CHANNEL'),
504 Cell('GTHE3_COMMON'),
505 Cell('GTHE4_CHANNEL'),
506 Cell('GTHE4_COMMON'),
507 Cell('GTYE3_CHANNEL'),
508 Cell('GTYE3_COMMON'),
509 Cell('GTYE4_CHANNEL'),
510 Cell('GTYE4_COMMON'),
511 Cell('IBUFDS_GTE3', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
512 Cell('IBUFDS_GTE4', port_attrs
={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
513 Cell('OBUFDS_GTE3', port_attrs
={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
514 Cell('OBUFDS_GTE3_ADV', port_attrs
={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
515 Cell('OBUFDS_GTE4', port_attrs
={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
516 Cell('OBUFDS_GTE4_ADV', port_attrs
={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
519 Cell('PCIE_A1'), # Spartan 6
520 Cell('PCIE_EP'), # Virtex 5
521 Cell('PCIE_2_0'), # Virtex 6
522 Cell('PCIE_2_1'), # Series 7
523 Cell('PCIE_3_0'), # Series 7
524 Cell('PCIE_3_1'), # Ultrascale
525 Cell('PCIE40E4'), # Ultrascale+
528 Cell('EMAC'), # Virtex 4
529 Cell('TEMAC'), # Virtex 5
530 Cell('TEMAC_SINGLE'), # Virtex 6
531 Cell('CMAC'), # Ultrascale
532 Cell('CMACE4'), # Ultrsacale+
535 # TODO PPC405 (Virtex 2)
536 Cell('PPC405_ADV'), # Virtex 4
537 Cell('PPC440'), # Virtex 5
540 Cell('MCB'), # Spartan 6 Memory Controller Block
541 Cell('PS7', keep
=True), # The Zynq 7000 ARM Processor System.
542 Cell('PS8', keep
=True), # The Zynq Ultrascale+ ARM Processor System.
543 Cell('ILKN'), # Ultrascale Interlaken
544 Cell('ILKNE4'), # Ultrascale+ Interlaken
551 IN_OTHER_MODULE
= auto()
555 def xtract_cell_decl(cell
, dirs
, outf
):
557 fname
= os
.path
.join(dir, cell
.name
+ '.v')
559 with
open(fname
) as f
:
560 state
= State
.OUTSIDE
562 # Probably the most horrible Verilog "parser" ever written.
564 invertible_ports
= set()
566 l
= l
.partition('//')[0]
568 if l
== 'module {}'.format(cell
.name
) or l
.startswith('module {} '.format(cell
.name
)):
570 print('Multiple modules in {}.'.format(fname
))
572 elif state
!= State
.OUTSIDE
:
573 print('Nested modules in {}.'.format(fname
))
576 state
= State
.IN_MODULE
578 outf
.write('(* keep *)\n')
579 outf
.write('module {} (...);\n'.format(cell
.name
))
580 elif l
.startswith('module '):
581 if state
!= State
.OUTSIDE
:
582 print('Nested modules in {}.'.format(fname
))
584 state
= State
.IN_OTHER_MODULE
585 elif l
.startswith('task '):
586 if state
== State
.IN_MODULE
:
587 state
= State
.IN_TASK
588 elif l
.startswith('function '):
589 if state
== State
.IN_MODULE
:
590 state
= State
.IN_FUNCTION
592 if state
== State
.IN_TASK
:
593 state
= State
.IN_MODULE
594 elif l
== 'endfunction':
595 if state
== State
.IN_FUNCTION
:
596 state
= State
.IN_MODULE
597 elif l
== 'endmodule':
598 if state
== State
.IN_MODULE
:
599 for kind
, rng
, port
in module_ports
:
600 for attr
in cell
.port_attrs
.get(port
, []):
601 outf
.write(' (* {} *)\n'.format(attr
))
602 if port
in invertible_ports
:
603 outf
.write(' (* invertible_pin = "IS_{}_INVERTED" *)\n'.format(port
))
605 outf
.write(' {} {};\n'.format(kind
, port
))
607 outf
.write(' {} {} {};\n'.format(kind
, rng
, port
))
610 elif state
!= State
.IN_OTHER_MODULE
:
611 print('endmodule in weird place in {}.'.format(cell
.name
, fname
))
613 state
= State
.OUTSIDE
614 elif l
.startswith(('input ', 'output ', 'inout ')) and state
== State
.IN_MODULE
:
615 if l
.endswith((';', ',')):
618 print('Weird port line in {} [{}].'.format(fname
, l
))
620 kind
, _
, ports
= l
.partition(' ')
621 for port
in ports
.split(','):
623 if port
.startswith('['):
624 rng
, port
= port
.split()
627 module_ports
.append((kind
, rng
, port
))
628 elif l
.startswith('parameter ') and state
== State
.IN_MODULE
:
631 if l
.endswith((';', ',')):
634 l
= l
.replace(' ', ' ')
636 print('Weird parameter line in {} [{}].'.format(fname
, l
))
638 outf
.write(' {};\n'.format(l
))
639 match
= re
.search('IS_([a-zA-Z0-9_]+)_INVERTED', l
)
641 invertible_ports
.add(match
[1])
642 if state
!= State
.OUTSIDE
:
643 print('endmodule not found in {}.'.format(fname
))
646 print('Cannot find module {} in {}.'.format(cell
.name
, fname
))
649 except FileNotFoundError
:
651 print('Cannot find {}.'.format(cell
.name
))
654 if __name__
== '__main__':
655 parser
= ArgumentParser(description
='Extract Xilinx blackbox cell definitions from ISE and Vivado.')
656 parser
.add_argument('vivado_dir', nargs
='?', default
='/opt/Xilinx/Vivado/2018.1')
657 parser
.add_argument('ise_dir', nargs
='?', default
='/opt/Xilinx/ISE/14.7')
658 args
= parser
.parse_args()
661 os
.path
.join(args
.vivado_dir
, 'data/verilog/src/xeclib'),
662 os
.path
.join(args
.vivado_dir
, 'data/verilog/src/retarget'),
663 os
.path
.join(args
.ise_dir
, 'ISE_DS/ISE/verilog/xeclib/unisims'),
666 if not os
.path
.isdir(dir):
667 print('{} is not a directory'.format(dir))
671 xtract_cell_decl(cell
, dirs
, out
)
673 with
open('cells_xtra.v', 'w') as f
:
674 f
.write('// Created by cells_xtra.py from Xilinx models\n')
676 f
.write(out
.getvalue())