mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 11:12:29 +00:00 
			
		
		
		
	synth_nexus: Initial implementation
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
		
							parent
							
								
									f9ed9786bf
								
							
						
					
					
						commit
						4d584d9319
					
				
					 30 changed files with 12528 additions and 0 deletions
				
			
		
							
								
								
									
										286
									
								
								techlibs/nexus/cells_xtra.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								techlibs/nexus/cells_xtra.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,286 @@ | |||
| #!/usr/bin/env python3 | ||||
| 
 | ||||
| # Based on Xilinx cells_xtra.py; modified for Radiant's structure | ||||
| 
 | ||||
| from argparse import ArgumentParser | ||||
| from io import StringIO | ||||
| from enum import Enum, auto | ||||
| import os.path | ||||
| import sys | ||||
| import re | ||||
| 
 | ||||
| 
 | ||||
| class Cell: | ||||
|     def __init__(self, name, keep=False, port_attrs={}): | ||||
|         self.name = name | ||||
|         self.keep = keep | ||||
|         self.port_attrs = port_attrs | ||||
|         self.found = False | ||||
| 
 | ||||
| class State(Enum): | ||||
|     OUTSIDE = auto() | ||||
|     IN_MODULE = auto() | ||||
|     IN_OTHER_MODULE = auto() | ||||
|     IN_FUNCTION = auto() | ||||
|     IN_TASK = auto() | ||||
| 
 | ||||
| devices = [ | ||||
|     ("lifcl", [ | ||||
|         Cell("ACC54"), | ||||
|         Cell("ADC"), | ||||
|         Cell("ALUREG"), | ||||
|         Cell("BB_ADC", keep=True), | ||||
|         Cell("BB_CDR", keep=True), | ||||
|         Cell("BB_I3C_A", keep=True), | ||||
|         Cell("BFD1P3KX"), | ||||
|         Cell("BFD1P3LX"), | ||||
|         Cell("BNKREF18", keep=True), | ||||
|         Cell("CONFIG_LMMI", keep=True), | ||||
|         Cell("DCC"), | ||||
|         Cell("DCS"), | ||||
|         Cell("DDRDLL"), | ||||
|         Cell("DELAYA"), | ||||
|         Cell("DELAYB"), | ||||
|         Cell("DIFFIO18", keep=True), | ||||
|         Cell("DLLDEL"), | ||||
|         Cell("DP16K_MODE"), | ||||
|         Cell("DP16K"), | ||||
|         Cell("DPHY", keep=True), | ||||
|         Cell("DPSC512K"), | ||||
|         Cell("DQSBUF"), | ||||
|         Cell("EBR_CORE"), | ||||
|         Cell("EBR"), | ||||
|         Cell("ECLKDIV"), | ||||
|         Cell("ECLKSYNC"), | ||||
|         Cell("FBMUX"), | ||||
|         Cell("FIFO16K_MODE"), | ||||
|         Cell("FIFO16K"), | ||||
|         Cell("GSR"), | ||||
|         Cell("HSE"), | ||||
|         Cell("I2CFIFO"), | ||||
|         Cell("IDDR71"), | ||||
|         Cell("IDDRX1"), | ||||
|         Cell("IDDRX2DQ"), | ||||
|         Cell("IDDRX2"), | ||||
|         Cell("IDDRX4DQ"), | ||||
|         Cell("IDDRX4"), | ||||
|         Cell("IDDRX5"), | ||||
|         Cell("IFD1P3BX"), | ||||
|         Cell("IFD1P3DX"), | ||||
|         Cell("IFD1P3IX"), | ||||
|         Cell("IFD1P3JX"), | ||||
|         Cell("JTAG", keep=True), | ||||
|         Cell("LRAM"), | ||||
|         Cell("M18X36"), | ||||
|         Cell("MIPI"), | ||||
|         Cell("MULT18"), | ||||
|         Cell("MULT18X18"), | ||||
|         Cell("MULT18X36"), | ||||
|         Cell("MULT36"), | ||||
|         Cell("MULT36X36"), | ||||
|         Cell("MULT9"), | ||||
|         Cell("MULT9X9"), | ||||
|         Cell("MULTADDSUB18X18"), | ||||
|         Cell("MULTADDSUB18X18WIDE"), | ||||
|         Cell("MULTADDSUB18X36"), | ||||
|         Cell("MULTADDSUB36X36"), | ||||
|         Cell("MULTADDSUB9X9WIDE"), | ||||
|         Cell("MULTIBOOT", keep=True), | ||||
|         Cell("MULTPREADD18X18"), | ||||
|         Cell("MULTPREADD9X9"), | ||||
|         Cell("ODDR71"), | ||||
|         Cell("ODDRX1"), | ||||
|         Cell("ODDRX2DQS"), | ||||
|         Cell("ODDRX2DQ"), | ||||
|         Cell("ODDRX2"), | ||||
|         Cell("ODDRX4DQS"), | ||||
|         Cell("ODDRX4DQ"), | ||||
|         Cell("ODDRX4"), | ||||
|         Cell("ODDRX5"), | ||||
|         Cell("OFD1P3BX"), | ||||
|         Cell("OFD1P3DX"), | ||||
|         Cell("OFD1P3IX"), | ||||
|         Cell("OFD1P3JX"), | ||||
|         Cell("OSC"), | ||||
|         Cell("OSCA"), | ||||
|         Cell("OSHX2"), | ||||
|         Cell("OSHX4"), | ||||
|         Cell("PCIE"), | ||||
|         Cell("PCLKDIV"), | ||||
|         Cell("PCLKDIVSP"), | ||||
|         Cell("PDP16K_MODE"), | ||||
|         Cell("PDP16K"), | ||||
|         Cell("PDPSC16K_MODE"), | ||||
|         Cell("PDPSC16K"), | ||||
|         Cell("PDPSC512K"), | ||||
|         Cell("PLL"), | ||||
|         Cell("PREADD9"), | ||||
|         Cell("PUR", keep=True), | ||||
|         Cell("REFMUX"), | ||||
|         Cell("REG18"), | ||||
|         Cell("SEDC", keep=True), | ||||
|         Cell("SEIO18"), | ||||
|         Cell("SEIO33"), | ||||
|         Cell("SGMIICDR"), | ||||
|         Cell("SP16K_MODE"), | ||||
|         Cell("SP16K"), | ||||
|         Cell("SP512K"), | ||||
|         Cell("TSALLA"), | ||||
|         Cell("TSHX2DQS"), | ||||
|         Cell("TSHX2DQ"), | ||||
|         Cell("TSHX4DQS"), | ||||
|         Cell("TSHX4DQ"), | ||||
|         Cell("WDT", keep=True), | ||||
| 
 | ||||
|         Cell("ACC54_CORE"), | ||||
|         Cell("ADC_CORE"), | ||||
|         Cell("ALUREG_CORE"), | ||||
|         Cell("BNKREF18_CORE"), | ||||
|         Cell("BNKREF33_CORE"), | ||||
|         Cell("DIFFIO18_CORE"), | ||||
|         Cell("CONFIG_CLKRST_CORE", keep=True), | ||||
|         Cell("CONFIG_HSE_CORE", keep=True), | ||||
|         Cell("CONFIG_IP_CORE", keep=True), | ||||
|         Cell("CONFIG_JTAG_CORE", keep=True), | ||||
|         Cell("CONFIG_LMMI_CORE", keep=True), | ||||
|         Cell("CONFIG_MULTIBOOT_CORE", keep=True), | ||||
|         Cell("CONFIG_SEDC_CORE", keep=True), | ||||
|         Cell("CONFIG_WDT_CORE", keep=True), | ||||
|         Cell("DDRDLL_CORE"), | ||||
|         Cell("DLLDEL_CORE"), | ||||
|         Cell("DPHY_CORE"), | ||||
|         Cell("DQSBUF_CORE"), | ||||
|         Cell("ECLKDIV_CORE"), | ||||
|         Cell("ECLKSYNC_CORE"), | ||||
|         Cell("FBMUX_CORE"), | ||||
|         Cell("GSR_CORE"), | ||||
|         Cell("I2CFIFO_CORE"), | ||||
|         Cell("LRAM_CORE"), | ||||
|         Cell("MULT18_CORE"), | ||||
|         Cell("MULT18X36_CORE"), | ||||
|         Cell("MULT36_CORE"), | ||||
|         Cell("MULT9_CORE"), | ||||
|         Cell("OSC_CORE"), | ||||
|         Cell("PCIE_CORE"), | ||||
|         Cell("PLL_CORE"), | ||||
|         Cell("PREADD9_CORE"), | ||||
|         Cell("REFMUX_CORE"), | ||||
|         Cell("REG18_CORE"), | ||||
|         Cell("SEIO18_CORE"), | ||||
|         Cell("SEIO33_CORE"), | ||||
|         Cell("SGMIICDR_CORE"), | ||||
|     ]) | ||||
| ] | ||||
| 
 | ||||
| def xtract_cells_decl(device, cells, dirs, outf): | ||||
|     fname = os.path.join(dir, device + '.v') | ||||
|     with open(fname) as f: | ||||
|         state = State.OUTSIDE | ||||
|         # Probably the most horrible Verilog "parser" ever written. | ||||
|         cell = None | ||||
|         for l in f: | ||||
|             l, _, comment = l.partition('//') | ||||
|             l = l.strip() | ||||
|             if l.startswith("module "): | ||||
|                 cell_name = l[7:l.find('(')].strip() | ||||
|                 cell = None | ||||
|                 module_ports = [] | ||||
|                 iopad_pin = set() | ||||
|                 if state != State.OUTSIDE: | ||||
|                     print('Nested modules in {}.'.format(fname)) | ||||
|                     sys.exit(1) | ||||
|                 for c in cells: | ||||
|                     if c.name != cell_name: | ||||
|                         continue | ||||
|                     cell = c | ||||
|                     state = State.IN_MODULE | ||||
|                     if cell.keep: | ||||
|                         outf.write('(* keep *)\n') | ||||
|                     outf.write('module {} (...);\n'.format(cell.name)) | ||||
|                     cell.found = True | ||||
| 
 | ||||
|                     m = re.search(r'synthesis .*black_box_pad_pin="([^"]*)"', comment) | ||||
|                     if m: | ||||
|                         iopad_pin = set(m.group(1).split(",")) | ||||
| 
 | ||||
|                 if cell is None: | ||||
|                     state = State.IN_OTHER_MODULE | ||||
|             elif l.startswith('task '): | ||||
|                 if state == State.IN_MODULE: | ||||
|                     state = State.IN_TASK | ||||
|             elif l.startswith('function '): | ||||
|                 if state == State.IN_MODULE: | ||||
|                     state = State.IN_FUNCTION | ||||
|             elif l == 'endtask': | ||||
|                 if state == State.IN_TASK: | ||||
|                     state = State.IN_MODULE | ||||
|             elif l == 'endfunction': | ||||
|                 if state == State.IN_FUNCTION: | ||||
|                     state = State.IN_MODULE | ||||
|             elif l == 'endmodule': | ||||
|                 if state == State.IN_MODULE: | ||||
|                     for kind, rng, port in module_ports: | ||||
|                         for attr in cell.port_attrs.get(port, []): | ||||
|                             outf.write('    (* {} *)\n'.format(attr)) | ||||
|                         if port in iopad_pin: | ||||
|                             outf.write('    (* iopad_external_pin *)\n') | ||||
|                         if rng is None: | ||||
|                             outf.write('    {} {};\n'.format(kind, port)) | ||||
|                         else: | ||||
|                             outf.write('    {} {} {};\n'.format(kind, rng, port)) | ||||
|                     outf.write(l + '\n') | ||||
|                     outf.write('\n') | ||||
|                 elif state != State.IN_OTHER_MODULE: | ||||
|                     print('endmodule in weird place in {}.'.format(cell.name, fname)) | ||||
|                     sys.exit(1) | ||||
|                 state = State.OUTSIDE | ||||
|             elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE: | ||||
|                 if l.endswith((';', ',')): | ||||
|                     l = l[:-1] | ||||
|                 if ';' in l: | ||||
|                     print('Weird port line in {} [{}].'.format(fname, l)) | ||||
|                     sys.exit(1) | ||||
|                 kind, _, ports = l.partition(' ') | ||||
|                 for port in ports.split(','): | ||||
|                     port = port.strip() | ||||
|                     if port.startswith('['): | ||||
|                         rng, port = port.split() | ||||
|                     else: | ||||
|                         rng = None | ||||
|                     module_ports.append((kind, rng, port)) | ||||
|             elif l.startswith('parameter ') and state == State.IN_MODULE: | ||||
|                 if l.endswith((';', ',')): | ||||
|                     l = l[:-1] | ||||
|                 while '  ' in l: | ||||
|                     l = l.replace('  ', ' ') | ||||
|                 if ';' in l: | ||||
|                     print('Weird parameter line in {} [{}].'.format(fname, l)) | ||||
|                     sys.exit(1) | ||||
|                 outf.write('    {};\n'.format(l)) | ||||
| 
 | ||||
|         if state != State.OUTSIDE: | ||||
|             print('endmodule not found in {}.'.format(fname)) | ||||
|             sys.exit(1) | ||||
|         for cell in cells: | ||||
|             if not cell.found: | ||||
|                 print('cell {} not found in {}.'.format(cell.name, fname)) | ||||
| if __name__ == '__main__': | ||||
|     parser = ArgumentParser(description='Extract Lattice blackbox cell definitions from Radiant.') | ||||
|     parser.add_argument('radiant_dir', nargs='?', default='/opt/lscc/radiant/2.0/') | ||||
|     args = parser.parse_args() | ||||
| 
 | ||||
|     dirs = [ | ||||
|         os.path.join(args.radiant_dir, 'cae_library/synthesis/verilog/'), | ||||
|     ] | ||||
|     for dir in dirs: | ||||
|         if not os.path.isdir(dir): | ||||
|             print('{} is not a directory'.format(dir)) | ||||
| 
 | ||||
|     out = StringIO() | ||||
|     for device, cells in devices: | ||||
|         xtract_cells_decl(device, cells, dirs, out) | ||||
| 
 | ||||
|     with open('cells_xtra.v', 'w') as f: | ||||
|         f.write('// Created by cells_xtra.py from Lattice models\n') | ||||
|         f.write('\n') | ||||
|         f.write(out.getvalue()) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue