Merge pull request #1355 from YosysHQ/eddie/peepopt_dffmuxext
[yosys.git] / techlibs / xilinx / cells_xtra.py
1 #!/usr/bin/env python3
2
3 from argparse import ArgumentParser
4 from io import StringIO
5 from enum import Enum, auto
6 import os.path
7 import sys
8
9
10 class Cell:
11 def __init__(self, name, keep=False, port_attrs={}):
12 self.name = name
13 self.keep = keep
14 self.port_attrs = port_attrs
15
16
17 XC6S_CELLS = [
18 # Design elements types listed in Xilinx UG615.
19
20 # Advanced.
21 Cell('MCB'),
22 Cell('PCIE_A1'),
23
24 # Arithmetic functions.
25 Cell('DSP48A1', port_attrs={'CLK': ['clkbuf_sink']}),
26
27 # Clock components.
28 # Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
29 Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
30 Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
31 Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
32 Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
33 Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
34 Cell('BUFIO2', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}),
35 Cell('BUFIO2_2CLK', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}),
36 Cell('BUFIO2FB', port_attrs={'O': ['clkbuf_driver']}),
37 Cell('BUFPLL_MCB', port_attrs={'IOCLK0': ['clkbuf_driver'], 'IOCLK1': ['clkbuf_driver']}),
38 Cell('DCM_CLKGEN'),
39 Cell('DCM_SP'),
40 Cell('PLL_BASE'),
41
42 # Config/BSCAN components.
43 Cell('BSCAN_SPARTAN6', keep=True),
44 Cell('DNA_PORT'),
45 Cell('ICAP_SPARTAN6', keep=True),
46 Cell('POST_CRC_INTERNAL'),
47 Cell('STARTUP_SPARTAN6', keep=True),
48 Cell('SUSPEND_SYNC', keep=True),
49
50 # I/O components.
51 Cell('GTPA1_DUAL'),
52 # Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
53 Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
54 Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
55 Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
56 Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
57 Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
58 Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
59 Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
60 Cell('IODELAY2', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
61 Cell('IODRP2', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
62 Cell('IODRP2_MCB', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
63 Cell('ISERDES2', port_attrs={
64 'CLK0': ['clkbuf_sink'],
65 'CLK1': ['clkbuf_sink'],
66 'CLKDIV': ['clkbuf_sink'],
67 }),
68 Cell('KEEPER'),
69 # Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
70 Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
71 Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
72 Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
73 Cell('OSERDES2', port_attrs={
74 'CLK0': ['clkbuf_sink'],
75 'CLK1': ['clkbuf_sink'],
76 'CLKDIV': ['clkbuf_sink'],
77 }),
78 Cell('PULLDOWN'),
79 Cell('PULLUP'),
80
81 # RAM/ROM.
82 #Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
83 # NOTE: not in the official library guide!
84 Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
85 Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
86 Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
87 #Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
88 Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
89 Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
90 Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
91 Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
92 #Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
93 Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
94 Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
95 # NOTE: not in the official library guide!
96 Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
97 # Cell('RAMB8BWER', port_attrs={'CLKAWRCLK': ['clkbuf_sink'], 'CLKBRDCLK': ['clkbuf_sink']}),
98 # Cell('RAMB16BWER', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
99 Cell('ROM128X1'),
100 Cell('ROM256X1'),
101 Cell('ROM32X1'),
102 Cell('ROM64X1'),
103
104 # Registers/latches.
105 # Cell('FDCE'),
106 # Cell('FDPE'),
107 # Cell('FDRE'),
108 # Cell('FDSE'),
109 Cell('IDDR2', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
110 Cell('LDCE'),
111 Cell('LDPE'),
112 Cell('ODDR2', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
113
114 # Slice/CLB primitives.
115 # Cell('CARRY4'),
116 Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
117 # Cell('LUT1'),
118 # Cell('LUT2'),
119 # Cell('LUT3'),
120 # Cell('LUT4'),
121 # Cell('LUT5'),
122 # Cell('LUT6'),
123 # Cell('LUT6_2'),
124 # Cell('MUXF7'),
125 # Cell('MUXF8'),
126 # Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
127 # Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
128 ]
129
130
131 XC6V_CELLS = [
132 # Design elements types listed in Xilinx UG623.
133
134 # Advanced.
135 Cell('PCIE_2_0'),
136 Cell('SYSMON'),
137
138 # Arithmetic functions.
139 Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}),
140
141 # Clock components.
142 # Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
143 Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
144 Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
145 #Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
146 Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
147 Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
148 Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
149 Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
150 #Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}),
151 Cell('BUFIO', port_attrs={'O': ['clkbuf_driver']}),
152 Cell('BUFIODQS', port_attrs={'O': ['clkbuf_driver']}),
153 Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}),
154 Cell('IBUFDS_GTXE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
155 Cell('MMCM_ADV'),
156 Cell('MMCM_BASE'),
157
158 # Config/BSCAN components.
159 Cell('BSCAN_VIRTEX6', keep=True),
160 Cell('CAPTURE_VIRTEX6', keep=True),
161 Cell('DNA_PORT'),
162 Cell('EFUSE_USR'),
163 Cell('FRAME_ECC_VIRTEX6'),
164 Cell('ICAP_VIRTEX6', keep=True),
165 Cell('STARTUP_VIRTEX6', keep=True),
166 Cell('USR_ACCESS_VIRTEX6'),
167
168 # I/O components.
169 Cell('DCIRESET', keep=True),
170 Cell('GTHE1_QUAD'),
171 Cell('GTXE1'),
172 # Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
173 Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
174 Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
175 Cell('IBUFDS_GTHE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
176 Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
177 Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
178 Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
179 Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
180 Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
181 Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
182 Cell('IODELAYE1', port_attrs={'C': ['clkbuf_sink']}),
183 Cell('ISERDESE1', port_attrs={
184 'CLK': ['clkbuf_sink'],
185 'CLKB': ['clkbuf_sink'],
186 'OCLK': ['clkbuf_sink'],
187 'CLKDIV': ['clkbuf_sink'],
188 }),
189 Cell('KEEPER'),
190 # Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
191 Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
192 Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
193 Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
194 Cell('OSERDESE1', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
195 Cell('PULLDOWN'),
196 Cell('PULLUP'),
197 Cell('TEMAC_SINGLE'),
198
199 # RAM/ROM.
200 Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
201 Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
202 #Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
203 Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
204 Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
205 Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
206 #Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
207 Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
208 Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
209 Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
210 Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
211 #Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
212 Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
213 Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
214 # NOTE: not in the official library guide!
215 Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
216 # Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
217 # Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
218 Cell('ROM128X1'),
219 Cell('ROM256X1'),
220 Cell('ROM32X1'),
221 Cell('ROM64X1'),
222
223 # Registers/latches.
224 # Cell('FDCE'),
225 # Cell('FDPE'),
226 # Cell('FDRE'),
227 # Cell('FDSE'),
228 Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
229 Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
230 Cell('LDCE'),
231 Cell('LDPE'),
232 Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
233
234 # Slice/CLB primitives.
235 # Cell('CARRY4'),
236 Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
237 # Cell('LUT1'),
238 # Cell('LUT2'),
239 # Cell('LUT3'),
240 # Cell('LUT4'),
241 # Cell('LUT5'),
242 # Cell('LUT6'),
243 # Cell('LUT6_2'),
244 # Cell('MUXF7'),
245 # Cell('MUXF8'),
246 # Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
247 # Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
248 ]
249
250
251 XC7_CELLS = [
252 # Design elements types listed in Xilinx UG953.
253
254 # Advanced.
255 Cell('GTHE2_CHANNEL'),
256 Cell('GTHE2_COMMON'),
257 Cell('GTPE2_CHANNEL'),
258 Cell('GTPE2_COMMON'),
259 Cell('GTXE2_CHANNEL'),
260 Cell('GTXE2_COMMON'),
261 Cell('PCIE_2_1'),
262 Cell('PCIE_3_0'),
263 Cell('XADC'),
264
265 # Arithmetic functions.
266 Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}),
267
268 # Clock components.
269 # Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
270 Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
271 Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
272 #Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
273 Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
274 Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
275 Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
276 Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
277 #Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}),
278 Cell('BUFIO', port_attrs={'O': ['clkbuf_driver']}),
279 Cell('BUFMR', port_attrs={'O': ['clkbuf_driver']}),
280 Cell('BUFMRCE', port_attrs={'O': ['clkbuf_driver']}),
281 Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}),
282 Cell('MMCME2_ADV'),
283 Cell('MMCME2_BASE'),
284 Cell('PLLE2_ADV'),
285 Cell('PLLE2_BASE'),
286
287 # Config/BSCAN components.
288 Cell('BSCANE2', keep=True),
289 Cell('CAPTUREE2', keep=True),
290 Cell('DNA_PORT'),
291 Cell('EFUSE_USR'),
292 Cell('FRAME_ECCE2'),
293 Cell('ICAPE2', keep=True),
294 Cell('STARTUPE2', keep=True),
295 Cell('USR_ACCESSE2'),
296
297 # I/O components.
298 Cell('DCIRESET', keep=True),
299 # Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
300 Cell('IBUF_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin']}),
301 Cell('IBUF_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin']}),
302 Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
303 Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
304 Cell('IBUFDS_DIFF_OUT_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
305 Cell('IBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
306 Cell('IBUFDS_GTE2', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
307 Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
308 Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
309 Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
310 Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
311 Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
312 Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
313 Cell('IDELAYE2', port_attrs={'C': ['clkbuf_sink']}),
314 Cell('IN_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
315 Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
316 Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}),
317 Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}),
318 Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
319 Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
320 Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
321 Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
322 Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
323 Cell('IOBUFDS_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
324 Cell('ISERDESE2', port_attrs={
325 'CLK': ['clkbuf_sink'],
326 'CLKB': ['clkbuf_sink'],
327 'OCLK': ['clkbuf_sink'],
328 'OCLKB': ['clkbuf_sink'],
329 'CLKDIV': ['clkbuf_sink'],
330 'CLKDIVP': ['clkbuf_sink'],
331 }),
332 Cell('KEEPER'),
333 # Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
334 Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
335 Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
336 Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
337 Cell('ODELAYE2', port_attrs={'C': ['clkbuf_sink']}),
338 Cell('OSERDESE2', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
339 Cell('OUT_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
340 Cell('PHASER_IN'),
341 Cell('PHASER_IN_PHY'),
342 Cell('PHASER_OUT'),
343 Cell('PHASER_OUT_PHY'),
344 Cell('PHASER_REF'),
345 Cell('PHY_CONTROL'),
346 Cell('PULLDOWN'),
347 Cell('PULLUP'),
348
349 # RAM/ROM.
350 Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
351 Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
352 #Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
353 Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
354 Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
355 Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
356 #Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
357 Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
358 Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
359 Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
360 Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
361 #Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
362 Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
363 Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
364 # NOTE: not in the official library guide!
365 Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
366 # Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
367 # Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
368 Cell('ROM128X1'),
369 Cell('ROM256X1'),
370 Cell('ROM32X1'),
371 Cell('ROM64X1'),
372
373 # Registers/latches.
374 # Cell('FDCE'),
375 # Cell('FDPE'),
376 # Cell('FDRE'),
377 # Cell('FDSE'),
378 Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
379 Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
380 Cell('LDCE'),
381 Cell('LDPE'),
382 Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
383
384 # Slice/CLB primitives.
385 # Cell('CARRY4'),
386 Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
387 # Cell('LUT1'),
388 # Cell('LUT2'),
389 # Cell('LUT3'),
390 # Cell('LUT4'),
391 # Cell('LUT5'),
392 # Cell('LUT6'),
393 # Cell('LUT6_2'),
394 # Cell('MUXF7'),
395 # Cell('MUXF8'),
396 # Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
397 # Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
398
399 # NOTE: not in the official library guide!
400 Cell('PS7', keep=True),
401 ]
402
403
404 XCU_CELLS = [
405 # Design elements types listed in Xilinx UG974.
406
407 # Advanced.
408 Cell('CMAC'),
409 Cell('CMACE4'),
410 Cell('GTHE3_CHANNEL'),
411 Cell('GTHE3_COMMON'),
412 Cell('GTHE4_CHANNEL'),
413 Cell('GTHE4_COMMON'),
414 Cell('GTYE3_CHANNEL'),
415 Cell('GTYE3_COMMON'),
416 Cell('GTYE4_CHANNEL'),
417 Cell('GTYE4_COMMON'),
418 Cell('IBUFDS_GTE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
419 Cell('IBUFDS_GTE4', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
420 Cell('ILKN'),
421 Cell('ILKNE4'),
422 Cell('OBUFDS_GTE3', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
423 Cell('OBUFDS_GTE3_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
424 Cell('OBUFDS_GTE4', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
425 Cell('OBUFDS_GTE4_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
426 Cell('PCIE40E4'),
427 Cell('PCIE_3_1'),
428 Cell('SYSMONE1'),
429 Cell('SYSMONE4'),
430
431 # Arithmetic functions.
432 Cell('DSP48E2', port_attrs={'CLK': ['clkbuf_sink']}),
433
434 # Blockram.
435 Cell('FIFO18E2', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
436 Cell('FIFO36E2', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
437 Cell('RAMB18E2', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
438 Cell('RAMB36E2', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
439 Cell('URAM288', port_attrs={'CLK': ['clkbuf_sink']}),
440 Cell('URAM288_BASE', port_attrs={'CLK': ['clkbuf_sink']}),
441
442 # CLB.
443 # Cell('LUT6_2'),
444 #Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
445 Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
446 Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
447 Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
448 Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
449 Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}),
450 #Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
451 Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
452 Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
453 Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
454 Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}),
455 #Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
456 Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
457 Cell('AND2B1L'),
458 Cell('CARRY8'),
459 Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
460 # Cell('LUT1'),
461 # Cell('LUT2'),
462 # Cell('LUT3'),
463 # Cell('LUT4'),
464 # Cell('LUT5'),
465 # Cell('LUT6'),
466 # Cell('MUXF7'),
467 # Cell('MUXF8'),
468 Cell('MUXF9'),
469 Cell('OR2L'),
470 # Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
471 # Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
472
473 # Clock.
474 # Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
475 Cell('BUFG_GT', port_attrs={'O': ['clkbuf_driver']}),
476 Cell('BUFG_GT_SYNC'),
477 Cell('BUFG_PS', port_attrs={'O': ['clkbuf_driver']}),
478 Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
479 Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
480 Cell('BUFGCE_DIV', port_attrs={'O': ['clkbuf_driver']}),
481 #Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
482 Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
483 Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
484 Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
485 Cell('MMCME3_ADV'),
486 Cell('MMCME3_BASE'),
487 Cell('MMCME4_ADV'),
488 Cell('MMCME4_BASE'),
489 Cell('PLLE3_ADV'),
490 Cell('PLLE3_BASE'),
491 Cell('PLLE4_ADV'),
492 Cell('PLLE4_BASE'),
493
494 # Configuration.
495 Cell('BSCANE2', keep=True),
496 Cell('DNA_PORTE2'),
497 Cell('EFUSE_USR'),
498 Cell('FRAME_ECCE3'),
499 Cell('ICAPE3', keep=True),
500 Cell('MASTER_JTAG', keep=True),
501 Cell('STARTUPE3', keep=True),
502 Cell('USR_ACCESSE2'),
503
504 # I/O.
505 Cell('BITSLICE_CONTROL', keep=True),
506 Cell('DCIRESET', keep=True),
507 Cell('HPIO_VREF'),
508 # XXX
509 # Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
510 Cell('IBUF_ANALOG', port_attrs={'I': ['iopad_external_pin']}),
511 Cell('IBUF_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin']}),
512 Cell('IBUF_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin']}),
513 Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
514 Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
515 Cell('IBUFDS_DIFF_OUT_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
516 Cell('IBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
517 Cell('IBUFDS_DPHY', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
518 Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
519 Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
520 Cell('IBUFDSE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
521 Cell('IBUFE3', port_attrs={'I': ['iopad_external_pin']}),
522 Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
523 Cell('IDELAYE3', port_attrs={'CLK': ['clkbuf_sink']}),
524 Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
525 Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}),
526 Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}),
527 Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
528 Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
529 Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
530 Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
531 Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
532 Cell('IOBUFDS_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
533 Cell('IOBUFDSE3', port_attrs={'IO': ['iopad_external_pin']}),
534 Cell('IOBUFE3', port_attrs={'IO': ['iopad_external_pin']}),
535 Cell('ISERDESE3', port_attrs={
536 'CLK': ['clkbuf_sink'],
537 'CLK_B': ['clkbuf_sink'],
538 'FIFO_RD_CLK': ['clkbuf_sink'],
539 'CLKDIV': ['clkbuf_sink'],
540 }),
541 Cell('KEEPER'),
542 # Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
543 Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
544 Cell('OBUFDS_DPHY', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
545 Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
546 Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
547 Cell('ODELAYE3', port_attrs={'CLK': ['clkbuf_sink']}),
548 Cell('OSERDESE3', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
549 Cell('PULLDOWN'),
550 Cell('PULLUP'),
551 Cell('RIU_OR'),
552 Cell('RX_BITSLICE'),
553 Cell('RXTX_BITSLICE'),
554 Cell('TX_BITSLICE'),
555 Cell('TX_BITSLICE_TRI'),
556
557 # Registers.
558 # Cell('FDCE'),
559 # Cell('FDPE'),
560 # Cell('FDRE'),
561 # Cell('FDSE'),
562 Cell('HARD_SYNC', port_attrs={'CLK': ['clkbuf_sink']}),
563 Cell('IDDRE1', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
564 Cell('LDCE'),
565 Cell('LDPE'),
566 Cell('ODDRE1', port_attrs={'C': ['clkbuf_sink']}),
567
568 # NOTE: not in the official library guide!
569 Cell('PS8', keep=True),
570 ]
571
572
573 class State(Enum):
574 OUTSIDE = auto()
575 IN_MODULE = auto()
576 IN_OTHER_MODULE = auto()
577 IN_FUNCTION = auto()
578 IN_TASK = auto()
579
580 def xtract_cell_decl(cell, dirs, outf):
581 for dir in dirs:
582 fname = os.path.join(dir, cell.name + '.v')
583 try:
584 with open(fname) as f:
585 state = State.OUTSIDE
586 found = False
587 # Probably the most horrible Verilog "parser" ever written.
588 for l in f:
589 l = l.partition('//')[0]
590 l = l.strip()
591 if l == 'module {}'.format(cell.name) or l.startswith('module {} '.format(cell.name)):
592 if found:
593 print('Multiple modules in {}.'.format(fname))
594 sys.exit(1)
595 elif state != State.OUTSIDE:
596 print('Nested modules in {}.'.format(fname))
597 sys.exit(1)
598 found = True
599 state = State.IN_MODULE
600 if cell.keep:
601 outf.write('(* keep *)\n')
602 outf.write('module {} (...);\n'.format(cell.name))
603 elif l.startswith('module '):
604 if state != State.OUTSIDE:
605 print('Nested modules in {}.'.format(fname))
606 sys.exit(1)
607 state = State.IN_OTHER_MODULE
608 elif l.startswith('task '):
609 if state == State.IN_MODULE:
610 state = State.IN_TASK
611 elif l.startswith('function '):
612 if state == State.IN_MODULE:
613 state = State.IN_FUNCTION
614 elif l == 'endtask':
615 if state == State.IN_TASK:
616 state = State.IN_MODULE
617 elif l == 'endfunction':
618 if state == State.IN_FUNCTION:
619 state = State.IN_MODULE
620 elif l == 'endmodule':
621 if state == State.IN_MODULE:
622 outf.write(l + '\n')
623 outf.write('\n')
624 elif state != State.IN_OTHER_MODULE:
625 print('endmodule in weird place in {}.'.format(cell.name, fname))
626 sys.exit(1)
627 state = State.OUTSIDE
628 elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE:
629 if l.endswith((';', ',')):
630 l = l[:-1]
631 if ';' in l:
632 print('Weird port line in {} [{}].'.format(fname, l))
633 sys.exit(1)
634 kind, _, ports = l.partition(' ')
635 for port in ports.split(','):
636 port = port.strip()
637 for attr in cell.port_attrs.get(port, []):
638 outf.write(' (* {} *)\n'.format(attr))
639 outf.write(' {} {};\n'.format(kind, port))
640 elif l.startswith('parameter ') and state == State.IN_MODULE:
641 if 'UNPLACED' in l:
642 continue
643 if l.endswith((';', ',')):
644 l = l[:-1]
645 while ' ' in l:
646 l = l.replace(' ', ' ')
647 if ';' in l:
648 print('Weird parameter line in {} [{}].'.format(fname, l))
649 sys.exit(1)
650 outf.write(' {};\n'.format(l))
651 if state != State.OUTSIDE:
652 print('endmodule not found in {}.'.format(fname))
653 sys.exit(1)
654 if not found:
655 print('Cannot find module {} in {}.'.format(cell.name, fname))
656 sys.exit(1)
657 return
658 except FileNotFoundError:
659 continue
660 print('Cannot find {}.'.format(cell.name))
661 sys.exit(1)
662
663 if __name__ == '__main__':
664 parser = ArgumentParser(description='Extract Xilinx blackbox cell definitions from ISE and Vivado.')
665 parser.add_argument('vivado_dir', nargs='?', default='/opt/Xilinx/Vivado/2018.1')
666 parser.add_argument('ise_dir', nargs='?', default='/opt/Xilinx/ISE/14.7')
667 args = parser.parse_args()
668
669 dirs = [
670 os.path.join(args.vivado_dir, 'data/verilog/src/xeclib'),
671 os.path.join(args.vivado_dir, 'data/verilog/src/retarget'),
672 os.path.join(args.ise_dir, 'ISE_DS/ISE/verilog/xeclib/unisims'),
673 ]
674 for dir in dirs:
675 if not os.path.isdir(dir):
676 print('{} is not a directory'.format(dir))
677
678 for ofile, cells in [
679 ('xc6s_cells_xtra.v', XC6S_CELLS),
680 ('xc6v_cells_xtra.v', XC6V_CELLS),
681 ('xc7_cells_xtra.v', XC7_CELLS),
682 ('xcu_cells_xtra.v', XCU_CELLS),
683 ]:
684 out = StringIO()
685 for cell in cells:
686 xtract_cell_decl(cell, dirs, out)
687
688 with open(ofile, 'w') as f:
689 f.write('// Created by cells_xtra.py from Xilinx models\n')
690 f.write('\n')
691 f.write(out.getvalue())