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