mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	prjtrellis documentation shows that EBR clock inputs have optional inverters. The bram techmap outputs those parameters, and nextpnr consumes them. But for whatever reason, Diamond doesn't include those parameters in its blackbox models. This makes synth_lattice fail when targeting ECP5 with a design that maps block RAMs if you include any pass that needs cells_bb_ecp5.v's definitions. This change fixes up the ECP5 bram blackbox models at generation time, by adding the missing parameters back in. Signed-off-by: David Anderson <dave@natulte.net>
		
			
				
	
	
		
			871 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			871 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| # Based on Xilinx cells_xtra.py; modified for Lattice'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={}, extra_params={}):
 | |
|         self.name = name
 | |
|         self.keep = keep
 | |
|         self.port_attrs = port_attrs
 | |
|         self.extra_params = extra_params
 | |
|         self.found = False
 | |
| 
 | |
| class State(Enum):
 | |
|     OUTSIDE = auto()
 | |
|     IN_MODULE = auto()
 | |
|     IN_OTHER_MODULE = auto()
 | |
|     IN_FUNCTION = auto()
 | |
|     IN_TASK = auto()
 | |
| 
 | |
| devices = [
 | |
|     ("cells_bb_ecp5.v", "ecp5u", [
 | |
|         #Cell("AND2"),
 | |
|         #Cell("AND3"),
 | |
|         #Cell("AND4"),
 | |
|         #Cell("AND5"),
 | |
|         #Cell("BB"),
 | |
|         #Cell("BBPD"),
 | |
|         #Cell("BBPU"),
 | |
|         #Cell("CCU2C"),
 | |
|         #Cell("FD1P3AX"),
 | |
|         #Cell("FD1P3AY"),
 | |
|         #Cell("FD1P3BX"),
 | |
|         #Cell("FD1P3DX"),
 | |
|         #Cell("FD1P3IX"),
 | |
|         #Cell("FD1P3JX"),
 | |
|         #Cell("FD1S3AX"),
 | |
|         #Cell("FD1S3AY"),
 | |
|         #Cell("FD1S3BX"),
 | |
|         #Cell("FD1S3DX"),
 | |
|         #Cell("FD1S3IX"),
 | |
|         #Cell("FD1S3JX"),
 | |
|         #Cell("FL1P3AY"),
 | |
|         #Cell("FL1P3AZ"),
 | |
|         #Cell("FL1P3BX"),
 | |
|         #Cell("FL1P3DX"),
 | |
|         #Cell("FL1P3IY"),
 | |
|         #Cell("FL1P3JY"),
 | |
|         #Cell("FL1S3AX"),
 | |
|         #Cell("FL1S3AY"),
 | |
|         Cell("GSR", True),
 | |
|         #Cell("IB"),
 | |
|         #Cell("IBPD"),
 | |
|         #Cell("IBPU"),
 | |
|         #Cell("IFS1P3BX"),
 | |
|         #Cell("IFS1P3DX"),
 | |
|         #Cell("IFS1P3IX"),
 | |
|         #Cell("IFS1P3JX"),
 | |
|         #Cell("IFS1S1B"),
 | |
|         #Cell("IFS1S1D"),
 | |
|         #Cell("IFS1S1I"),
 | |
|         #Cell("IFS1S1J"),
 | |
|         #Cell("ILVDS"),
 | |
|         #Cell("INV"),
 | |
|         #Cell("L6MUX21"),
 | |
|         #Cell("LUT4"),
 | |
|         #Cell("LUT5"),
 | |
|         #Cell("LUT6"),
 | |
|         #Cell("LUT7"),
 | |
|         #Cell("LUT8"),
 | |
|         #Cell("MUX161"),
 | |
|         #Cell("MUX21"),
 | |
|         #Cell("MUX321"),
 | |
|         #Cell("MUX41"),
 | |
|         #Cell("MUX81"),
 | |
|         #Cell("ND2"),
 | |
|         #Cell("ND3"),
 | |
|         #Cell("ND4"),
 | |
|         #Cell("ND5"),
 | |
|         #Cell("NR2"),
 | |
|         #Cell("NR3"),
 | |
|         #Cell("NR4"),
 | |
|         #Cell("NR5"),
 | |
|         #Cell("OB"),
 | |
|         #Cell("OBCO"),
 | |
|         #Cell("OBZ"),
 | |
|         #Cell("OBZPU"),
 | |
|         #Cell("OFS1P3BX"),
 | |
|         #Cell("OFS1P3DX"),
 | |
|         #Cell("OFS1P3IX"),
 | |
|         #Cell("OFS1P3JX"),
 | |
|         #Cell("OLVDS"),
 | |
|         #Cell("OR2"),
 | |
|         #Cell("OR3"),
 | |
|         #Cell("OR4"),
 | |
|         #Cell("OR5"),
 | |
|         #Cell("PFUMX"),
 | |
|         Cell("PUR"),
 | |
|         #Cell("ROM128X1A"),
 | |
|         #Cell("ROM16X1A"),
 | |
|         #Cell("ROM256X1A"),
 | |
|         #Cell("ROM32X1A"),
 | |
|         #Cell("ROM64X1A"),
 | |
|         Cell("SGSR", True),
 | |
|         #Cell("VHI"),
 | |
|         #Cell("VLO"),
 | |
|         #Cell("XNOR2"),
 | |
|         #Cell("XNOR3"),
 | |
|         #Cell("XNOR4"),
 | |
|         #Cell("XNOR5"),
 | |
|         #Cell("XOR11"),
 | |
|         #Cell("XOR2"),
 | |
|         #Cell("XOR21"),
 | |
|         #Cell("XOR3"),
 | |
|         #Cell("XOR4"),
 | |
|         #Cell("XOR5"),
 | |
|         Cell("DP16KD", extra_params={
 | |
|             # Optional clock inverters, present in prjtrellis data but
 | |
|             # not in Diamond bb models.
 | |
|             "CLKAMUX": "CLKA",
 | |
|             "CLKBMUX": "CLKB",
 | |
|         }),
 | |
|         Cell("PDPW16KD", extra_params={
 | |
|             # Optional clock inverters, present in prjtrellis data but
 | |
|             # not in Diamond bb models.
 | |
|             "CLKWMUX": "CLKW",
 | |
|             "CLKRMUX": "CLKR",
 | |
|         }),
 | |
|         #Cell("DPR16X4C"),
 | |
|         #Cell("SPR16X4C"),
 | |
|         #Cell("LVDSOB"),
 | |
|         #Cell("IMIPI"),
 | |
|         #Cell("MULT9X9C"),
 | |
|         #Cell("MULT9X9D"),
 | |
|         #Cell("MULT18X18C"),
 | |
|         Cell("MULT18X18D"),
 | |
|         #Cell("ALU24A"),
 | |
|         #Cell("ALU54A"),
 | |
|         #Cell("ALU24B"),
 | |
|         Cell("ALU54B"),
 | |
|         #Cell("PRADD9A"),
 | |
|         #Cell("PRADD18A"),
 | |
|         #Cell("BCINRD"),
 | |
|         #Cell("BCLVDSOB"),
 | |
|         #Cell("INRDB"),
 | |
|         Cell("CLKDIVF"),
 | |
|         Cell("PCSCLKDIV"),
 | |
|         Cell("DCSC"),
 | |
|         Cell("DCCA"),
 | |
|         Cell("ECLKSYNCB"),
 | |
|         Cell("ECLKBRIDGECS"),
 | |
|         #Cell("PLLREFCS"),
 | |
|         Cell("DELAYF"),
 | |
|         Cell("DELAYG"),
 | |
|         #Cell("START"),
 | |
|         Cell("USRMCLK", True),
 | |
|         Cell("DQSBUFM"),
 | |
|         Cell("DDRDLLA"),
 | |
|         Cell("DLLDELD"),
 | |
|         Cell("IDDRX1F"),
 | |
|         Cell("IDDRX2F"),
 | |
|         Cell("IDDR71B"),
 | |
|         Cell("IDDRX2DQA"),
 | |
|         Cell("ODDRX1F"),
 | |
|         Cell("ODDRX2F"),
 | |
|         Cell("ODDR71B"),
 | |
|         Cell("OSHX2A"),
 | |
|         Cell("TSHX2DQA"),
 | |
|         Cell("TSHX2DQSA"),
 | |
|         Cell("ODDRX2DQA"),
 | |
|         Cell("ODDRX2DQSB"),
 | |
|         Cell("EHXPLLL"),
 | |
|         Cell("DTR"),
 | |
|         Cell("OSCG"),
 | |
|         Cell("EXTREFB"),
 | |
|         Cell("JTAGG", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}),
 | |
|         #Cell("SEDGA"),
 | |
|         Cell("DCUA", True, port_attrs={'CH0_HDINP': ['iopad_external_pin'], 'CH1_HDINP': ['iopad_external_pin'], 'CH0_HDINN': ['iopad_external_pin'], 'CH1_HDINN': ['iopad_external_pin']}),
 | |
|     ]),
 | |
|     ("cells_bb_xo2.v", "machxo2", [
 | |
|         #Cell("AGEB2"),
 | |
|         #Cell("ALEB2"),
 | |
|         #Cell("AND2"),
 | |
|         #Cell("AND3"),
 | |
|         #Cell("AND4"),
 | |
|         #Cell("AND5"),
 | |
|         #Cell("ANEB2"),
 | |
|         #Cell("BB"),
 | |
|         #Cell("BBPD"),
 | |
|         #Cell("BBPU"),
 | |
|         #Cell("BBW"),
 | |
|         #Cell("CB2"),
 | |
|         #Cell("CD2"),
 | |
|         #Cell("CU2"),
 | |
|         #Cell("FADD2B"),
 | |
|         #Cell("FADSU2"),
 | |
|         #Cell("FD1P3AX"),
 | |
|         #Cell("FD1P3AY"),
 | |
|         #Cell("FD1P3BX"),
 | |
|         #Cell("FD1P3DX"),
 | |
|         #Cell("FD1P3IX"),
 | |
|         #Cell("FD1P3JX"),
 | |
|         #Cell("FD1S1A"),
 | |
|         #Cell("FD1S1AY"),
 | |
|         #Cell("FD1S1B"),
 | |
|         #Cell("FD1S1D"),
 | |
|         #Cell("FD1S1I"),
 | |
|         #Cell("FD1S1J"),
 | |
|         #Cell("FD1S3AX"),
 | |
|         #Cell("FD1S3AY"),
 | |
|         #Cell("FD1S3BX"),
 | |
|         #Cell("FD1S3DX"),
 | |
|         #Cell("FD1S3IX"),
 | |
|         #Cell("FD1S3JX"),
 | |
|         #Cell("FL1P3AY"),
 | |
|         #Cell("FL1P3AZ"),
 | |
|         #Cell("FL1P3BX"),
 | |
|         #Cell("FL1P3DX"),
 | |
|         #Cell("FL1P3IY"),
 | |
|         #Cell("FL1P3JY"),
 | |
|         #Cell("FL1S1A"),
 | |
|         #Cell("FL1S1AY"),
 | |
|         #Cell("FL1S1B"),
 | |
|         #Cell("FL1S1D"),
 | |
|         #Cell("FL1S1I"),
 | |
|         #Cell("FL1S1J"),
 | |
|         #Cell("FL1S3AX"),
 | |
|         #Cell("FL1S3AY"),
 | |
|         #Cell("FSUB2B"),
 | |
|         Cell("GSR", True),
 | |
|         #Cell("IB"),
 | |
|         #Cell("IBPD"),
 | |
|         #Cell("IBPU"),
 | |
|         #Cell("IFS1P3BX"),
 | |
|         #Cell("IFS1P3DX"),
 | |
|         #Cell("IFS1P3IX"),
 | |
|         #Cell("IFS1P3JX"),
 | |
|         #Cell("ILVDS"),
 | |
|         #Cell("INV"),
 | |
|         #Cell("L6MUX21"),
 | |
|         #Cell("LB2P3AX"),
 | |
|         #Cell("LB2P3AY"),
 | |
|         #Cell("LB2P3BX"),
 | |
|         #Cell("LB2P3DX"),
 | |
|         #Cell("LB2P3IX"),
 | |
|         #Cell("LB2P3JX"),
 | |
|         #Cell("LD2P3AX"),
 | |
|         #Cell("LD2P3AY"),
 | |
|         #Cell("LD2P3BX"),
 | |
|         #Cell("LD2P3DX"),
 | |
|         #Cell("LD2P3IX"),
 | |
|         #Cell("LD2P3JX"),
 | |
|         #Cell("LU2P3AX"),
 | |
|         #Cell("LU2P3AY"),
 | |
|         #Cell("LU2P3BX"),
 | |
|         #Cell("LU2P3DX"),
 | |
|         #Cell("LU2P3IX"),
 | |
|         #Cell("LU2P3JX"),
 | |
|         #Cell("MULT2"),
 | |
|         #Cell("MUX161"),
 | |
|         #Cell("MUX21"),
 | |
|         #Cell("MUX321"),
 | |
|         #Cell("MUX41"),
 | |
|         #Cell("MUX81"),
 | |
|         #Cell("ND2"),
 | |
|         #Cell("ND3"),
 | |
|         #Cell("ND4"),
 | |
|         #Cell("ND5"),
 | |
|         #Cell("NR2"),
 | |
|         #Cell("NR3"),
 | |
|         #Cell("NR4"),
 | |
|         #Cell("NR5"),
 | |
|         #Cell("OB"),
 | |
|         #Cell("OBCO"),
 | |
|         #Cell("OBZ"),
 | |
|         #Cell("OBZPU"),
 | |
|         #Cell("OFS1P3BX"),
 | |
|         #Cell("OFS1P3DX"),
 | |
|         #Cell("OFS1P3IX"),
 | |
|         #Cell("OFS1P3JX"),
 | |
|         #Cell("OLVDS"),
 | |
|         #Cell("OR2"),
 | |
|         #Cell("OR3"),
 | |
|         #Cell("OR4"),
 | |
|         #Cell("OR5"),
 | |
|         #Cell("LUT4"),
 | |
|         #Cell("LUT5"),
 | |
|         #Cell("LUT6"),
 | |
|         #Cell("LUT7"),
 | |
|         #Cell("LUT8"),
 | |
|         #Cell("PFUMX"),
 | |
|         #Cell("PUR"),
 | |
|         #Cell("ROM128X1A"),
 | |
|         #Cell("ROM16X1A"),
 | |
|         #Cell("ROM256X1A"),
 | |
|         #Cell("ROM32X1A"),
 | |
|         #Cell("ROM64X1A"),
 | |
|         #Cell("CCU2D"),
 | |
|         #Cell("VHI"),
 | |
|         #Cell("VLO"),
 | |
|         #Cell("XNOR2"),
 | |
|         #Cell("XNOR3"),
 | |
|         #Cell("XNOR4"),
 | |
|         #Cell("XNOR5"),
 | |
|         #Cell("XOR11"),
 | |
|         #Cell("XOR2"),
 | |
|         #Cell("XOR21"),
 | |
|         #Cell("XOR3"),
 | |
|         #Cell("XOR4"),
 | |
|         #Cell("XOR5"),
 | |
|         #Cell("IFS1S1B"),
 | |
|         #Cell("IFS1S1D"),
 | |
|         #Cell("IFS1S1I"),
 | |
|         #Cell("IFS1S1J"),
 | |
|         #Cell("DPR16X4C"),
 | |
|         #Cell("SPR16X4C"),
 | |
|         Cell("SGSR", True),
 | |
|         Cell("DP8KC"),
 | |
|         Cell("PDPW8KC"),
 | |
|         Cell("SP8KC"),
 | |
|         Cell("FIFO8KB"),
 | |
|         Cell("CLKDIVC"),
 | |
|         Cell("DCMA"),
 | |
|         Cell("ECLKSYNCA"),
 | |
|         Cell("ECLKBRIDGECS"),
 | |
|         Cell("DCCA"),
 | |
|         #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}),
 | |
|         Cell("START", True),
 | |
|         #Cell("SEDFA"),
 | |
|         #Cell("SEDFB"),
 | |
|         #Cell("IDDRXE"),
 | |
|         #Cell("IDDRX2E"),
 | |
|         #Cell("IDDRX4B"),
 | |
|         #Cell("IDDRDQSX1A"),
 | |
|         #Cell("IDDRX71A"),
 | |
|         #Cell("ODDRXE"),
 | |
|         #Cell("ODDRX2E"),
 | |
|         #Cell("ODDRX4B"),
 | |
|         #Cell("ODDRDQSX1A"),
 | |
|         #Cell("ODDRX71A"),
 | |
|         #Cell("TDDRA"),
 | |
|         #Cell("DQSBUFH"),
 | |
|         #Cell("DQSDLLC"),
 | |
|         #Cell("DELAYE"),
 | |
|         #Cell("DELAYD"),
 | |
|         #Cell("DLLDELC"),
 | |
|         #Cell("CLKFBBUFA"),
 | |
|         #Cell("PCNTR"),
 | |
|         #Cell("BCINRD"),
 | |
|         #Cell("BCLVDSO"),
 | |
|         #Cell("INRDB"),
 | |
|         #Cell("LVDSOB"),
 | |
|         #Cell("PG"),
 | |
|         Cell("EHXPLLJ"),
 | |
|         #Cell("PLLREFCS"),
 | |
|         Cell("OSCH"),
 | |
|         #Cell("EFB"),
 | |
|         Cell("TSALL", True),
 | |
|     ]),
 | |
|     ("cells_bb_xo3.v", "machxo3lf", [
 | |
|         #Cell("AGEB2"),
 | |
|         #Cell("ALEB2"),
 | |
|         #Cell("AND2"),
 | |
|         #Cell("AND3"),
 | |
|         #Cell("AND4"),
 | |
|         #Cell("AND5"),
 | |
|         #Cell("ANEB2"),
 | |
|         #Cell("BB"),
 | |
|         #Cell("BBPD"),
 | |
|         #Cell("BBPU"),
 | |
|         #Cell("BBW"),
 | |
|         #Cell("CB2"),
 | |
|         #Cell("CD2"),
 | |
|         #Cell("CU2"),
 | |
|         #Cell("FADD2B"),
 | |
|         #Cell("FADSU2"),
 | |
|         #Cell("FD1P3AX"),
 | |
|         #Cell("FD1P3AY"),
 | |
|         #Cell("FD1P3BX"),
 | |
|         #Cell("FD1P3DX"),
 | |
|         #Cell("FD1P3IX"),
 | |
|         #Cell("FD1P3JX"),
 | |
|         #Cell("FD1S1A"),
 | |
|         #Cell("FD1S1AY"),
 | |
|         #Cell("FD1S1B"),
 | |
|         #Cell("FD1S1D"),
 | |
|         #Cell("FD1S1I"),
 | |
|         #Cell("FD1S1J"),
 | |
|         #Cell("FD1S3AX"),
 | |
|         #Cell("FD1S3AY"),
 | |
|         #Cell("FD1S3BX"),
 | |
|         #Cell("FD1S3DX"),
 | |
|         #Cell("FD1S3IX"),
 | |
|         #Cell("FD1S3JX"),
 | |
|         #Cell("FL1P3AY"),
 | |
|         #Cell("FL1P3AZ"),
 | |
|         #Cell("FL1P3BX"),
 | |
|         #Cell("FL1P3DX"),
 | |
|         #Cell("FL1P3IY"),
 | |
|         #Cell("FL1P3JY"),
 | |
|         #Cell("FL1S1A"),
 | |
|         #Cell("FL1S1AY"),
 | |
|         #Cell("FL1S1B"),
 | |
|         #Cell("FL1S1D"),
 | |
|         #Cell("FL1S1I"),
 | |
|         #Cell("FL1S1J"),
 | |
|         #Cell("FL1S3AX"),
 | |
|         #Cell("FL1S3AY"),
 | |
|         #Cell("FSUB2B"),
 | |
|         Cell("GSR", True),
 | |
|         #Cell("IB"),
 | |
|         #Cell("IBPD"),
 | |
|         #Cell("IBPU"),
 | |
|         #Cell("IFS1P3BX"),
 | |
|         #Cell("IFS1P3DX"),
 | |
|         #Cell("IFS1P3IX"),
 | |
|         #Cell("IFS1P3JX"),
 | |
|         #Cell("ILVDS"),
 | |
|         #Cell("INV"),
 | |
|         #Cell("L6MUX21"),
 | |
|         #Cell("LB2P3AX"),
 | |
|         #Cell("LB2P3AY"),
 | |
|         #Cell("LB2P3BX"),
 | |
|         #Cell("LB2P3DX"),
 | |
|         #Cell("LB2P3IX"),
 | |
|         #Cell("LB2P3JX"),
 | |
|         #Cell("LD2P3AX"),
 | |
|         #Cell("LD2P3AY"),
 | |
|         #Cell("LD2P3BX"),
 | |
|         #Cell("LD2P3DX"),
 | |
|         #Cell("LD2P3IX"),
 | |
|         #Cell("LD2P3JX"),
 | |
|         #Cell("LU2P3AX"),
 | |
|         #Cell("LU2P3AY"),
 | |
|         #Cell("LU2P3BX"),
 | |
|         #Cell("LU2P3DX"),
 | |
|         #Cell("LU2P3IX"),
 | |
|         #Cell("LU2P3JX"),
 | |
|         #Cell("MULT2"),
 | |
|         #Cell("MUX161"),
 | |
|         #Cell("MUX21"),
 | |
|         #Cell("MUX321"),
 | |
|         #Cell("MUX41"),
 | |
|         #Cell("MUX81"),
 | |
|         #Cell("ND2"),
 | |
|         #Cell("ND3"),
 | |
|         #Cell("ND4"),
 | |
|         #Cell("ND5"),
 | |
|         #Cell("NR2"),
 | |
|         #Cell("NR3"),
 | |
|         #Cell("NR4"),
 | |
|         #Cell("NR5"),
 | |
|         #Cell("OB"),
 | |
|         #Cell("OBCO"),
 | |
|         #Cell("OBZ"),
 | |
|         #Cell("OBZPU"),
 | |
|         #Cell("OFS1P3BX"),
 | |
|         #Cell("OFS1P3DX"),
 | |
|         #Cell("OFS1P3IX"),
 | |
|         #Cell("OFS1P3JX"),
 | |
|         #Cell("OLVDS"),
 | |
|         #Cell("OR2"),
 | |
|         #Cell("OR3"),
 | |
|         #Cell("OR4"),
 | |
|         #Cell("OR5"),
 | |
|         #Cell("LUT4"),
 | |
|         #Cell("LUT5"),
 | |
|         #Cell("LUT6"),
 | |
|         #Cell("LUT7"),
 | |
|         #Cell("LUT8"),
 | |
|         #Cell("PFUMX"),
 | |
|         #Cell("PUR"),
 | |
|         #Cell("ROM128X1A"),
 | |
|         #Cell("ROM16X1A"),
 | |
|         #Cell("ROM256X1A"),
 | |
|         #Cell("ROM32X1A"),
 | |
|         #Cell("ROM64X1A"),
 | |
|         #Cell("CCU2D"),
 | |
|         #Cell("VHI"),
 | |
|         #Cell("VLO"),
 | |
|         #Cell("XNOR2"),
 | |
|         #Cell("XNOR3"),
 | |
|         #Cell("XNOR4"),
 | |
|         #Cell("XNOR5"),
 | |
|         #Cell("XOR11"),
 | |
|         #Cell("XOR2"),
 | |
|         #Cell("XOR21"),
 | |
|         #Cell("XOR3"),
 | |
|         #Cell("XOR4"),
 | |
|         #Cell("XOR5"),
 | |
|         #Cell("IFS1S1B"),
 | |
|         #Cell("IFS1S1D"),
 | |
|         #Cell("IFS1S1I"),
 | |
|         #Cell("IFS1S1J"),
 | |
|         #Cell("DPR16X4C"),
 | |
|         #Cell("SPR16X4C"),
 | |
|         Cell("SGSR", True),
 | |
|         Cell("DP8KC"),
 | |
|         Cell("PDPW8KC"),
 | |
|         Cell("SP8KC"),
 | |
|         Cell("FIFO8KB"),
 | |
|         Cell("CLKDIVC"),
 | |
|         Cell("DCMA"),
 | |
|         Cell("ECLKSYNCA"),
 | |
|         Cell("ECLKBRIDGECS"),
 | |
|         Cell("DCCA"),
 | |
|         #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}),
 | |
|         Cell("START", True),
 | |
|         #Cell("SEDFA"),
 | |
|         #Cell("SEDFB"),
 | |
|         #Cell("IDDRXE"),
 | |
|         #Cell("IDDRX2E"),
 | |
|         #Cell("IDDRX4B"),
 | |
|         #Cell("IDDRX71A"),
 | |
|         #Cell("ODDRXE"),
 | |
|         #Cell("ODDRX2E"),
 | |
|         #Cell("ODDRX4B"),
 | |
|         #Cell("ODDRX71A"),
 | |
|         #Cell("DQSDLLC"),
 | |
|         #Cell("DELAYE"),
 | |
|         #Cell("DELAYD"),
 | |
|         #Cell("DLLDELC"),
 | |
|         #Cell("CLKFBBUFA"),
 | |
|         #Cell("PCNTR"),
 | |
|         #Cell("BCINRD"),
 | |
|         #Cell("BCLVDSO"),
 | |
|         #Cell("INRDB"),
 | |
|         #Cell("LVDSOB"),
 | |
|         #Cell("PG"),
 | |
|         Cell("EHXPLLJ"),
 | |
|         #Cell("PLLREFCS"),
 | |
|         Cell("OSCH"),
 | |
|         #Cell("EFB"),
 | |
|         Cell("TSALL", True),
 | |
|     ]),
 | |
|     ("cells_bb_xo3d.v", "machxo3d", [
 | |
|         #Cell("AGEB2"),
 | |
|         #Cell("ALEB2"),
 | |
|         #Cell("AND2"),
 | |
|         #Cell("AND3"),
 | |
|         #Cell("AND4"),
 | |
|         #Cell("AND5"),
 | |
|         #Cell("ANEB2"),
 | |
|         #Cell("BB"),
 | |
|         #Cell("BBPD"),
 | |
|         #Cell("BBPU"),
 | |
|         #Cell("BBI3C"),
 | |
|         #Cell("BBW"),
 | |
|         #Cell("CB2"),
 | |
|         #Cell("CD2"),
 | |
|         #Cell("CU2"),
 | |
|         #Cell("FADD2B"),
 | |
|         #Cell("FADSU2"),
 | |
|         #Cell("FD1P3AX"),
 | |
|         #Cell("FD1P3AY"),
 | |
|         #Cell("FD1P3BX"),
 | |
|         #Cell("FD1P3DX"),
 | |
|         #Cell("FD1P3IX"),
 | |
|         #Cell("FD1P3JX"),
 | |
|         #Cell("FD1S1A"),
 | |
|         #Cell("FD1S1AY"),
 | |
|         #Cell("FD1S1B"),
 | |
|         #Cell("FD1S1D"),
 | |
|         #Cell("FD1S1I"),
 | |
|         #Cell("FD1S1J"),
 | |
|         #Cell("FD1S3AX"),
 | |
|         #Cell("FD1S3AY"),
 | |
|         #Cell("FD1S3BX"),
 | |
|         #Cell("FD1S3DX"),
 | |
|         #Cell("FD1S3IX"),
 | |
|         #Cell("FD1S3JX"),
 | |
|         #Cell("FL1P3AY"),
 | |
|         #Cell("FL1P3AZ"),
 | |
|         #Cell("FL1P3BX"),
 | |
|         #Cell("FL1P3DX"),
 | |
|         #Cell("FL1P3IY"),
 | |
|         #Cell("FL1P3JY"),
 | |
|         #Cell("FL1S1A"),
 | |
|         #Cell("FL1S1AY"),
 | |
|         #Cell("FL1S1B"),
 | |
|         #Cell("FL1S1D"),
 | |
|         #Cell("FL1S1I"),
 | |
|         #Cell("FL1S1J"),
 | |
|         #Cell("FL1S3AX"),
 | |
|         #Cell("FL1S3AY"),
 | |
|         #Cell("FSUB2B"),
 | |
|         Cell("GSR", True),
 | |
|         #Cell("IB"),
 | |
|         #Cell("IBPD"),
 | |
|         #Cell("IBPU"),
 | |
|         #Cell("IFS1P3BX"),
 | |
|         #Cell("IFS1P3DX"),
 | |
|         #Cell("IFS1P3IX"),
 | |
|         #Cell("IFS1P3JX"),
 | |
|         #Cell("ILVDS"),
 | |
|         #Cell("INV"),
 | |
|         #Cell("L6MUX21"),
 | |
|         #Cell("LB2P3AX"),
 | |
|         #Cell("LB2P3AY"),
 | |
|         #Cell("LB2P3BX"),
 | |
|         #Cell("LB2P3DX"),
 | |
|         #Cell("LB2P3IX"),
 | |
|         #Cell("LB2P3JX"),
 | |
|         #Cell("LD2P3AX"),
 | |
|         #Cell("LD2P3AY"),
 | |
|         #Cell("LD2P3BX"),
 | |
|         #Cell("LD2P3DX"),
 | |
|         #Cell("LD2P3IX"),
 | |
|         #Cell("LD2P3JX"),
 | |
|         #Cell("LU2P3AX"),
 | |
|         #Cell("LU2P3AY"),
 | |
|         #Cell("LU2P3BX"),
 | |
|         #Cell("LU2P3DX"),
 | |
|         #Cell("LU2P3IX"),
 | |
|         #Cell("LU2P3JX"),
 | |
|         #Cell("MULT2"),
 | |
|         #Cell("MUX161"),
 | |
|         #Cell("MUX21"),
 | |
|         #Cell("MUX321"),
 | |
|         #Cell("MUX41"),
 | |
|         #Cell("MUX81"),
 | |
|         #Cell("ND2"),
 | |
|         #Cell("ND3"),
 | |
|         #Cell("ND4"),
 | |
|         #Cell("ND5"),
 | |
|         #Cell("NR2"),
 | |
|         #Cell("NR3"),
 | |
|         #Cell("NR4"),
 | |
|         #Cell("NR5"),
 | |
|         #Cell("OB"),
 | |
|         #Cell("OBCO"),
 | |
|         #Cell("OBZ"),
 | |
|         #Cell("OBZPU"),
 | |
|         #Cell("OFS1P3BX"),
 | |
|         #Cell("OFS1P3DX"),
 | |
|         #Cell("OFS1P3IX"),
 | |
|         #Cell("OFS1P3JX"),
 | |
|         #Cell("OLVDS"),
 | |
|         #Cell("OR2"),
 | |
|         #Cell("OR3"),
 | |
|         #Cell("OR4"),
 | |
|         #Cell("OR5"),
 | |
|         #Cell("LUT4"),
 | |
|         #Cell("LUT5"),
 | |
|         #Cell("LUT6"),
 | |
|         #Cell("LUT7"),
 | |
|         #Cell("LUT8"),
 | |
|         #Cell("PFUMX"),
 | |
|         #Cell("PUR"),
 | |
|         #Cell("ROM128X1A"),
 | |
|         #Cell("ROM16X1A"),
 | |
|         #Cell("ROM256X1A"),
 | |
|         #Cell("ROM32X1A"),
 | |
|         #Cell("ROM64X1A"),
 | |
|         #Cell("CCU2D"),
 | |
|         #Cell("VHI"),
 | |
|         #Cell("VLO"),
 | |
|         #Cell("XNOR2"),
 | |
|         #Cell("XNOR3"),
 | |
|         #Cell("XNOR4"),
 | |
|         #Cell("XNOR5"),
 | |
|         #Cell("XOR11"),
 | |
|         #Cell("XOR2"),
 | |
|         #Cell("XOR21"),
 | |
|         #Cell("XOR3"),
 | |
|         #Cell("XOR4"),
 | |
|         #Cell("XOR5"),
 | |
|         #Cell("IFS1S1B"),
 | |
|         #Cell("IFS1S1D"),
 | |
|         #Cell("IFS1S1I"),
 | |
|         #Cell("IFS1S1J"),
 | |
|         #Cell("DPR16X4C"),
 | |
|         #Cell("SPR16X4C"),
 | |
|         Cell("SGSR", True),
 | |
|         Cell("DP8KC"),
 | |
|         Cell("PDPW8KC"),
 | |
|         Cell("SP8KC"),
 | |
|         Cell("FIFO8KB"),
 | |
|         Cell("CLKDIVC"),
 | |
|         Cell("DCMA"),
 | |
|         Cell("ECLKSYNCA"),
 | |
|         Cell("ECLKBRIDGECS"),
 | |
|         Cell("DCCA"),
 | |
|         #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}),
 | |
|         Cell("START", True),
 | |
|         #Cell("SEDFA"),
 | |
|         #Cell("SEDFB"),
 | |
|         #Cell("IDDRXE"),
 | |
|         #Cell("IDDRX2E"),
 | |
|         #Cell("IDDRX4B"),
 | |
|         #Cell("IDDRX71A"),
 | |
|         #Cell("ODDRXE"),
 | |
|         #Cell("ODDRX2E"),
 | |
|         #Cell("ODDRX4B"),
 | |
|         #Cell("ODDRX71A"),
 | |
|         #Cell("DQSDLLC"),
 | |
|         #Cell("DELAYE"),
 | |
|         #Cell("DELAYD"),
 | |
|         #Cell("DLLDELC"),
 | |
|         #Cell("CLKFBBUFA"),
 | |
|         #Cell("PCNTR"),
 | |
|         #Cell("BCINRD"),
 | |
|         #Cell("BCLVDSO"),
 | |
|         #Cell("INRDB"),
 | |
|         #Cell("LVDSOB"),
 | |
|         #Cell("PG"),
 | |
|         Cell("EHXPLLJ"),
 | |
|         #Cell("PLLREFCS"),
 | |
|         Cell("OSCJ"),
 | |
|         #Cell("EFBB"),
 | |
|         Cell("TSALL", True),
 | |
|         #Cell("ESBA"),
 | |
|         #Cell("BCSLEWRATEA"),
 | |
|     ])
 | |
| ]
 | |
| 
 | |
| 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
 | |
|         kind = None
 | |
|         for l in f:
 | |
|             l, _, comment = l.partition('//')
 | |
|             l = l.strip()
 | |
|             m = re.search(r'synthesis .*black_box_pad_pin="([^"]*)"', comment)
 | |
|             if m:
 | |
|                 iopad_pin = set(m.group(1).split(","))
 | |
| 
 | |
|             if l.startswith("module "):
 | |
|                 cell_name = l[7:l.find('(')].strip()
 | |
|                 cell = None
 | |
|                 kind = 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
 | |
|                     outf.write('(* blackbox *)')
 | |
|                     if cell.keep:
 | |
|                         outf.write(' (* keep *)\n')
 | |
|                     else:
 | |
|                         outf.write('\n')
 | |
|                     outf.write('module {} (...);\n'.format(cell.name))
 | |
|                     cell.found = True
 | |
|                 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:
 | |
|                 l = l.strip()
 | |
|                 if l == "":
 | |
|                     continue
 | |
|                 if l.endswith((';', ',', ")")):
 | |
|                     l = l[:-1]
 | |
|                 l = l.replace(")","")
 | |
|                 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 cell.extra_params:
 | |
|                     for name, default in sorted(cell.extra_params.items()):
 | |
|                         outf.write('    parameter {} = "{}";\n'.format(name, default))
 | |
|                     cell.extra_params = None
 | |
|                 l = l.strip()
 | |
|                 if l.endswith((';', ',')):
 | |
|                     l = l[:-1]
 | |
|                 while '  ' in l:
 | |
|                     l = l.replace('  ', ' ')
 | |
| 
 | |
|                 if "INITVAL" in l:
 | |
|                     l = l.replace('"0x', "320'h")
 | |
|                     l = l.replace('"', '')
 | |
|                 if ';' in l:
 | |
|                     print('Weird parameter line in {} [{}].'.format(fname, l))
 | |
|                     sys.exit(1)
 | |
|                 outf.write('    {};\n'.format(l))
 | |
|             elif kind is not None and state == State.IN_MODULE:
 | |
|                 l = l.strip()
 | |
|                 if l == "":
 | |
|                     continue
 | |
|                 if l.endswith((';', ',', ")")):
 | |
|                     l = l[:-1]
 | |
|                 l = l.replace(")","")
 | |
|                 if l == "":
 | |
|                     continue
 | |
|                 if ';' in l:
 | |
|                     print('Weird port line in {} [{}].'.format(fname, l))
 | |
|                     sys.exit(1)
 | |
|                 ports = l
 | |
|                 for port in ports.split(','):
 | |
|                     port = port.strip()
 | |
|                     if port.startswith('['):
 | |
|                         rng, port = port.split()
 | |
|                     else:
 | |
|                         rng = None
 | |
|                     module_ports.append((kind, rng, port))
 | |
| 
 | |
|         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 Lattice Diamond.')
 | |
|     parser.add_argument('diamond_dir', nargs='?', default='/usr/local/diamond/3.12/')
 | |
|     args = parser.parse_args()
 | |
| 
 | |
|     dirs = [
 | |
|         os.path.join(args.diamond_dir, 'cae_library/synthesis/verilog/'),
 | |
|     ]
 | |
|     for dir in dirs:
 | |
|         if not os.path.isdir(dir):
 | |
|             print('{} is not a directory'.format(dir))
 | |
| 
 | |
|     for fn, device, cells in devices:
 | |
|         out = StringIO()
 | |
|         xtract_cells_decl(device, cells, dirs, out)
 | |
|         with open(fn, 'w') as f:
 | |
|             f.write('// Created by cells_xtra.py from Lattice models\n')
 | |
|             f.write('\n')
 | |
|             f.write(out.getvalue())
 |