3 # Based on Xilinx cells_xtra.py; modified for Radiant's structure
5 from argparse
import ArgumentParser
6 from io
import StringIO
7 from enum
import Enum
, auto
14 def __init__(self
, name
, keep
=False, port_attrs
={}):
17 self
.port_attrs
= port_attrs
23 IN_OTHER_MODULE
= auto()
32 Cell("BB_ADC", keep
=True),
33 Cell("BB_CDR", keep
=True),
34 Cell("BB_I3C_A", keep
=True),
37 Cell("BNKREF18", keep
=True),
38 Cell("CONFIG_LMMI", keep
=True),
44 Cell("DIFFIO18", keep
=True),
48 Cell("DPHY", keep
=True),
72 Cell("JTAG", keep
=True),
83 # Cell("MULTADDSUB18X18"),
84 Cell("MULTADDSUB18X18WIDE"),
85 # Cell("MULTADDSUB18X36"),
86 # Cell("MULTADDSUB36X36"),
87 Cell("MULTADDSUB9X9WIDE"),
88 Cell("MULTIBOOT", keep
=True),
89 # Cell("MULTPREADD18X18"),
90 # Cell("MULTPREADD9X9"),
113 Cell("PDPSC16K_MODE"),
118 Cell("PUR", keep
=True),
121 Cell("SEDC", keep
=True),
133 Cell("WDT", keep
=True),
138 Cell("BNKREF18_CORE"),
139 Cell("BNKREF33_CORE"),
140 Cell("DIFFIO18_CORE"),
141 Cell("CONFIG_CLKRST_CORE", keep
=True),
142 Cell("CONFIG_HSE_CORE", keep
=True),
143 Cell("CONFIG_IP_CORE", keep
=True),
144 Cell("CONFIG_JTAG_CORE", keep
=True),
145 Cell("CONFIG_LMMI_CORE", keep
=True),
146 Cell("CONFIG_MULTIBOOT_CORE", keep
=True),
147 Cell("CONFIG_SEDC_CORE", keep
=True),
148 Cell("CONFIG_WDT_CORE", keep
=True),
153 Cell("ECLKDIV_CORE"),
154 Cell("ECLKSYNC_CORE"),
157 Cell("I2CFIFO_CORE"),
160 Cell("MULT18X36_CORE"),
166 Cell("PREADD9_CORE"),
171 Cell("SGMIICDR_CORE"),
175 def xtract_cells_decl(device
, cells
, dirs
, outf
):
176 fname
= os
.path
.join(dir, device
+ '.v')
177 with
open(fname
) as f
:
178 state
= State
.OUTSIDE
179 # Probably the most horrible Verilog "parser" ever written.
182 l
, _
, comment
= l
.partition('//')
184 if l
.startswith("module "):
185 cell_name
= l
[7:l
.find('(')].strip()
189 if state
!= State
.OUTSIDE
:
190 print('Nested modules in {}.'.format(fname
))
193 if c
.name
!= cell_name
:
196 state
= State
.IN_MODULE
198 outf
.write('(* keep *)\n')
199 outf
.write('module {} (...);\n'.format(cell
.name
))
202 m
= re
.search(r
'synthesis .*black_box_pad_pin="([^"]*)"', comment
)
204 iopad_pin
= set(m
.group(1).split(","))
207 state
= State
.IN_OTHER_MODULE
208 elif l
.startswith('task '):
209 if state
== State
.IN_MODULE
:
210 state
= State
.IN_TASK
211 elif l
.startswith('function '):
212 if state
== State
.IN_MODULE
:
213 state
= State
.IN_FUNCTION
215 if state
== State
.IN_TASK
:
216 state
= State
.IN_MODULE
217 elif l
== 'endfunction':
218 if state
== State
.IN_FUNCTION
:
219 state
= State
.IN_MODULE
220 elif l
== 'endmodule':
221 if state
== State
.IN_MODULE
:
222 for kind
, rng
, port
in module_ports
:
223 for attr
in cell
.port_attrs
.get(port
, []):
224 outf
.write(' (* {} *)\n'.format(attr
))
225 if port
in iopad_pin
:
226 outf
.write(' (* iopad_external_pin *)\n')
228 outf
.write(' {} {};\n'.format(kind
, port
))
230 outf
.write(' {} {} {};\n'.format(kind
, rng
, port
))
233 elif state
!= State
.IN_OTHER_MODULE
:
234 print('endmodule in weird place in {}.'.format(cell
.name
, fname
))
236 state
= State
.OUTSIDE
237 elif l
.startswith(('input ', 'output ', 'inout ')) and state
== State
.IN_MODULE
:
238 if l
.endswith((';', ',')):
241 print('Weird port line in {} [{}].'.format(fname
, l
))
243 kind
, _
, ports
= l
.partition(' ')
244 for port
in ports
.split(','):
246 if port
.startswith('['):
247 rng
, port
= port
.split()
250 module_ports
.append((kind
, rng
, port
))
251 elif l
.startswith('parameter ') and state
== State
.IN_MODULE
:
252 if l
.endswith((';', ',')):
255 l
= l
.replace(' ', ' ')
257 print('Weird parameter line in {} [{}].'.format(fname
, l
))
259 outf
.write(' {};\n'.format(l
))
261 if state
!= State
.OUTSIDE
:
262 print('endmodule not found in {}.'.format(fname
))
266 print('cell {} not found in {}.'.format(cell
.name
, fname
))
267 if __name__
== '__main__':
268 parser
= ArgumentParser(description
='Extract Lattice blackbox cell definitions from Radiant.')
269 parser
.add_argument('radiant_dir', nargs
='?', default
='/opt/lscc/radiant/2.0/')
270 args
= parser
.parse_args()
273 os
.path
.join(args
.radiant_dir
, 'cae_library/synthesis/verilog/'),
276 if not os
.path
.isdir(dir):
277 print('{} is not a directory'.format(dir))
280 for device
, cells
in devices
:
281 xtract_cells_decl(device
, cells
, dirs
, out
)
283 with
open('cells_xtra.v', 'w') as f
:
284 f
.write('// Created by cells_xtra.py from Lattice models\n')
286 f
.write(out
.getvalue())