from helpers.io import ErrorMessage, WarningMessage
from helpers.overlay import UpdateSession
import plugins
-from Hurricane import (Breakpoint, DataBase, DbU, Transformation,
- Point, Box,
- Cell, Instance)
+from Hurricane import Breakpoint, DataBase, DbU, Transformation, Point, Box, \
+ Cell, Instance
from plugins.alpha.block.matrix import RegisterMatrix
from plugins.alpha.macro.macro import Macro
from plugins.alpha.block.iospecs import IoSpecs
from plugins.alpha.chip.chip import Chip
-af = CRL.AllianceFramework.get()
+af = CRL.AllianceFramework.get()
powerCount = 0
+placeHolderCount = 0
+
+
+def onGrid ( v ):
+ twoGrid = DbU.fromGrid( 2 )
+ modulo = v % twoGrid
+ if modulo:
+ v += twoGrid - modulo
+ return v
def isiterable ( pyobj ):
- if isinstance(pyobj, collections.Iterable): return True
+ if isinstance(pyobj,collections.Iterable): return True
return False
def doIoPowerCap ( flags ):
global powerCount
side = flags & IoPin.SIDE_MASK
- ioPadPower = [ (side , None, 'iopower_%d' % powerCount, 'iovdd' )
- , (side , None, 'ioground_%d' % powerCount, 'iovss' )
- , (side , None, 'ground_%d' % powerCount, 'vss' )
- , (side , None, 'power_%d' % powerCount, 'vdd' )
- ]
if flags & IoPin.A_BEGIN:
- ioPadPower.reverse()
+ ioPadPower = [ (side , None, 'power_{}'.format(powerCount), 'vdd' )
+ , (side , None, 'ground_{}'.format(powerCount), 'vss' )
+ , (side , None, 'ioground_{}'.format(powerCount), 'iovss' )
+ , (side , None, 'iopower_{}'.format(powerCount), 'iovdd' )
+ ]
+ else:
+ ioPadPower = [ (side , None, 'iopower_{}'.format(powerCount), 'iovdd' )
+ , (side , None, 'ioground_{}'.format(powerCount), 'iovss' )
+ , (side , None, 'ground_{}'.format(powerCount), 'vss' )
+ , (side , None, 'power_{}'.format(powerCount), 'vdd' )
+ ]
powerCount += 1
return ioPadPower
v = []
if not isiterable(bits): bits = range(bits)
if not bits:
- raise ErrorMessage( 1, [ 'doIoPinVector(): Argument "bits" ' \
- 'is neither a width nor an iterable.'
+ raise ErrorMessage( 1, [ 'doIoPinVector(): Argument "bits" is neither a width nor an iterable.'
, '(bits={})'.format(bits)
] )
if len(ioSpec) == 5:
, ioSpec[5].format(bit)
, ioSpec[6].format(bit) ))
else:
- raise ErrorMessage( 1, [ 'doIoPinVector(): Argument "ioSpec" ' \
- 'must have between 5 and 7 ' \
- 'fields ({})'.format(len(ioSpec))
+ raise ErrorMessage( 1, [ 'doIoPinVector(): Argument "ioSpec" must have between 5 and 7 fields ({})'.format(len(ioSpec))
, '(ioSpec={})'.format(ioSpec)
] )
return v
if isinstance(path,str):
path = path.split( '.' )
elif not isinstance(path,list):
- raise ErrorMessage( 1, 'rgetInstance(): "path" argument ' \
- 'is neither a string or a list ({})"' \
+ raise ErrorMessage( 1, 'rgetInstance(): "path" argument is neither a string or a list ({})"' \
.format(path) )
instance = cell.getInstance( path[0] )
if instance is None:
masterCell = occurrence.getEntity().getMasterCell()
masterCell.setAbutmentBox( ab )
-def addPllPlaceHolder ( cell ):
- pllPlaceHolder = Cell.create( af.getLibrary(0), 'pllplaceholder' )
- pllPlaceHolder.setAbutmentBox( Box( u(0.0), u(0.0), u(200.0), u(200.0) ))
- pllPlaceHolder.setTerminalNetlist( True )
- instance = Instance.create( cell, 'pllPlaceholder', pllPlaceHolder )
- return instance
-
def scriptMain (**kw):
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
#helpers.setTraceLevel( 550 )
#Breakpoint.setStopLevel( 100 )
rvalue = True
- #coreSize = u(37*90.0)
- coreSize = u(59*90.0)
+ coreSizeX = u(51*90.0)
+ coreSizeY = u(56*90.0)
chipBorder = u(2*214.0 + 10*13.0)
ioSpecs = IoSpecs()
#pinmuxFile = './non_generated/litex_pinpads.json'
# I/O pads, East side.
ioPadsSpec = []
ioPadsSpec += doIoPowerCap( IoPin.EAST|IoPin.A_BEGIN )
- ioPadsSpec += doIoPinVector( (IoPin.EAST , None, 'sdram_a_{}', 'sdram_a({})', 'sdram_a({})'), 13 )
- ioPadsSpec += doIoPinVector( (IoPin.EAST , None, 'gpio_{}', 'gpio({})', 'gpio_i({})', 'gpio_oe({})', 'gpio_o({})'), range(8,16) )
- ioPadsSpec += [ (IoPin.EAST , None, 'jtag_tms', 'jtag_tms', 'jtag_tms' )
- , (IoPin.EAST , None, 'jtag_tdi', 'jtag_tdi', 'jtag_tdi' )
- , (IoPin.EAST , None, 'jtag_tdo', 'jtag_tdo', 'jtag_tdo' )
- , (IoPin.EAST , None, 'jtag_tck', 'jtag_tck', 'jtag_tck' )
- ]
- ioPadsSpec += doIoPinVector( (IoPin.EAST , None, 'nc_{}', 'nc({})', 'nc({})'), range(4) )
+ ioPadsSpec += doIoPinVector( (IoPin.EAST, None, 'sdram_a_{}' , 'sdram_a({})' , 'sdram_a({})'), 13 )
+ ioPadsSpec += doIoPinVector( (IoPin.EAST, None, 'sdram_dm_{}', 'sdram_dm({})', 'sdram_dm({})'), 2 )
+ ioPadsSpec += doIoPinVector( (IoPin.EAST, None, 'sdram_dq_{}', 'sdram_dq({})', 'sdram_dq_i({})', 'sdram_dq_oe({})', 'sdram_dq_o({})'), range(0,16) )
+ ioPadsSpec += doIoPinVector( (IoPin.EAST, None, 'sdram_ba_{}', 'sdram_ba({})', 'sdram_ba({})'), 2 )
ioPadsSpec += doIoPowerCap( IoPin.EAST|IoPin.A_END )
# I/O pads, West side.
ioPadsSpec += doIoPowerCap( IoPin.WEST|IoPin.A_BEGIN )
- ioPadsSpec += [ (IoPin.WEST, None, 'pwm_1', 'pwm(1)', 'pwm(1)' ) ]
- ioPadsSpec += doIoPinVector( (IoPin.WEST , None, 'eint_{}', 'eint({})', 'eint({})'), 3 )
+ ioPadsSpec += doIoPinVector( (IoPin.WEST , None, 'nc_{}', ' nc({})', 'nc({})'), range(40) )
+ #ioPadsSpec += doIoPinVector( (IoPin.WEST , None, 'pwm_{}', 'pwm({})', 'pwm({})'), 2 )
+ ioPadsSpec += doIoPinVector( (IoPin.WEST , None, 'eint_{}', 'eint_{}', 'eint_{}'), 3 )
ioPadsSpec += [ (IoPin.WEST , None, 'spimaster_clk' , 'spimaster_clk' , 'spimaster_clk' )
, (IoPin.WEST , None, 'spimaster_cs_n', 'spimaster_cs_n', 'spimaster_cs_n' )
, (IoPin.WEST , None, 'spimaster_mosi', 'spimaster_mosi', 'spimaster_mosi' )
, (IoPin.WEST , None, 'spimaster_miso', 'spimaster_miso', 'spimaster_miso' )
- , (IoPin.WEST , None, 'sdcard_cmd' , 'sdcard_cmd' , 'sdcard_cmd_i', 'sdcard_cmd_oe', 'sdcard_cmd_o' )
- , (IoPin.WEST , None, 'sdcard_clk' , 'sdcard_clk' , 'sdcard_clk' )
+ #, (IoPin.WEST , None, 'sdcard_cmd' , 'sdcard_cmd' , 'sdcard_cmd_i', 'sdcard_cmd_oe', 'sdcard_cmd_o' )
+ #, (IoPin.WEST , None, 'sdcard_clk' , 'sdcard_clk' , 'sdcard_clk' )
]
- ioPadsSpec += doIoPinVector( (IoPin.WEST , None, 'sdcard_data_{}', 'sdcard_data({})', 'sdcard_data_i({})', 'sdcard_data_oe', 'sdcard_data_o({})'), 4 )
- ioPadsSpec += doIoPinVector( (IoPin.WEST , None, 'nc_{}', 'nc({})', 'nc({})'), range(4,16) )
+ #ioPadsSpec += doIoPinVector( (IoPin.WEST , None, 'sdcard_data_{}', 'sdcard_data({})', 'sdcard_data_i({})', 'sdcard_data_oe', 'sdcard_data_o({})'), 4 )
ioPadsSpec += doIoPowerCap( IoPin.WEST|IoPin.A_END )
# I/O pads, North side.
ioPadsSpec += doIoPowerCap( IoPin.NORTH|IoPin.A_BEGIN )
- ioPadsSpec += doIoPinVector( (IoPin.NORTH, None, 'sdram_dm_{}', 'sdram_dm({})', 'sdram_dm({})'), 2 )
- ioPadsSpec += doIoPinVector( (IoPin.NORTH, None, 'sdram_dq_{}', 'sdram_dq({})', 'sdram_dq_i({})', 'sdram_dq_oe', 'sdram_dq_o({})'), range(0,16) )
- ioPadsSpec += doIoPinVector( (IoPin.NORTH, None, 'sdram_ba_{}', 'sdram_ba({})', 'sdram_ba({})'), 2 )
- ioPadsSpec += [ (IoPin.NORTH, None, 'sdram_clock' , 'sdram_clock' , 'sdram_clock' )
- , (IoPin.NORTH, None, 'sdram_cke' , 'sdram_cke' , 'sdram_cke' )
- , (IoPin.NORTH, None, 'sdram_ras_n' , 'sdram_ras_n' , 'sdram_ras_n' )
- , (IoPin.NORTH, None, 'sdram_cas_n' , 'sdram_cas_n' , 'sdram_cas_n' )
- , (IoPin.NORTH, None, 'sdram_we_n' , 'sdram_we_n' , 'sdram_we_n' )
- , (IoPin.NORTH, None, 'sdram_cs_n' , 'sdram_cs_n' , 'sdram_cs_n' )
+ ioPadsSpec += [ (IoPin.NORTH, None, 'jtag_tms' , 'jtag_tms' , 'jtag_tms' )
+ , (IoPin.NORTH, None, 'jtag_tdi' , 'jtag_tdi' , 'jtag_tdi' )
+ , (IoPin.NORTH, None, 'jtag_tdo' , 'jtag_tdo' , 'jtag_tdo' )
+ , (IoPin.NORTH, None, 'jtag_tck' , 'jtag_tck' , 'jtag_tck' )
+ , (IoPin.NORTH, None, 'sys_clk' , 'sys_clk' , 'sys_clk' )
+ , (IoPin.NORTH, None, 'sys_pll_18_o' , 'sys_pll_18_o' , 'sys_pll_18_o' )
+ , (IoPin.NORTH, None, 'sys_pll_lck_o', 'sys_pll_lck_o', 'sys_pll_lck_o' )
]
- ioPadsSpec += doIoPinVector( (IoPin.NORTH, None, 'nc_{}', 'nc({})', 'nc({})'), range(16,18) )
+ ioPadsSpec += doIoPinVector( (IoPin.NORTH, None, 'sys_clksel_i{}', 'sys_clksel_i({})', 'sys_clksel_i({})'), 2 )
ioPadsSpec += doIoPowerCap( IoPin.NORTH|IoPin.A_END )
# I/O pads, South side.
ioPadsSpec += doIoPowerCap( IoPin.SOUTH|IoPin.A_BEGIN )
- ioPadsSpec += [ (IoPin.SOUTH, None, 'i2c_sda_i' , 'i2c_sda_i' , 'i2c_sda_i' ) ]
- ioPadsSpec += doIoPinVector( (IoPin.SOUTH, None, 'nc_{}', 'nc({})', 'nc({})'), range(18,22) )
- ioPadsSpec += [ (IoPin.SOUTH, None, 'spisdcard_clk' , 'spisdcard_clk' , 'spisdcard_clk' )
- , (IoPin.SOUTH, None, 'spisdcard_cs_n', 'spisdcard_cs_n', 'spisdcard_cs_n' )
- , (IoPin.SOUTH, None, 'spisdcard_mosi', 'spisdcard_mosi', 'spisdcard_mosi' )
- , (IoPin.SOUTH, None, 'spisdcard_miso', 'spisdcard_miso', 'spisdcard_miso' )
- ]
- ioPadsSpec += doIoPinVector( (IoPin.SOUTH, None, 'nc_{}', 'nc({})', 'nc({})'), range(22,23) )
+ ioPadsSpec += doIoPinVector( (IoPin.SOUTH, None, 'gpio_{}', 'gpio({})', 'gpio_i({})', 'gpio_oe({})', 'gpio_o({})'), range(0,16) )
+ ioPadsSpec += [ (IoPin.SOUTH, None, 'i2c_sda_i' , 'i2c_sda_i' , 'i2c_sda_i', 'i2c_sda_oe', 'i2c_sda_o' ) ]
+ ioPadsSpec += [ (IoPin.SOUTH, None, 'i2c_scl' , 'i2c_scl' , 'i2c_scl' ) ]
ioPadsSpec += [ (IoPin.SOUTH, None, 'uart_tx', 'uart_tx', 'uart_tx' )
, (IoPin.SOUTH, None, 'uart_rx', 'uart_rx', 'uart_rx' )
- ]
- ioPadsSpec += doIoPinVector( (IoPin.SOUTH, None, 'gpio_{}', 'gpio({})', 'gpio_i({})', 'gpio_oe({})', 'gpio_o({})'), range(0,8) )
- ioPadsSpec += [ (IoPin.SOUTH, None, 'sys_clk', 'sys_clk', 'sys_clk' )
, (IoPin.SOUTH, None, 'sys_rst', 'sys_rst', 'sys_rst' )
]
- ioPadsSpec += doIoPinVector( (IoPin.SOUTH, None, 'nc_{}', 'nc({})', 'nc({})'), range(23,24) )
- # TODO, Jean-Paul, resolve these
- # this one is analog voltage out (test purposes) vco_test_ana
- ioPadsSpec += [ (IoPin.SOUTH, None, 'sys_pll_vco_o' , 'sys_pll_vco_o' , 'sys_pll_vco_o' ) ]
- # this one is the divided internal PLL clock, div_out_test
- ioPadsSpec += [ (IoPin.SOUTH, None, 'sys_pll_testout_o' , 'sys_pll_testout_o' , 'sys_pll_testout_o' ) ]
- # these are a0, a1 in the PLL block, for selecting the PLL clock rate out
- ioPadsSpec += doIoPinVector( (IoPin.SOUTH, None, 'sys_clksel_i{}', 'sys_clksel_i({})', 'sys_clksel_i({})'), 2 )
+ ioPadsSpec += [ (IoPin.SOUTH, None, 'sdram_clock' , 'sdram_clock' , 'sdram_clock' )
+ , (IoPin.SOUTH, None, 'sdram_cke' , 'sdram_cke' , 'sdram_cke' )
+ , (IoPin.SOUTH, None, 'sdram_ras_n' , 'sdram_ras_n' , 'sdram_ras_n' )
+ , (IoPin.SOUTH, None, 'sdram_cas_n' , 'sdram_cas_n' , 'sdram_cas_n' )
+ , (IoPin.SOUTH, None, 'sdram_we_n' , 'sdram_we_n' , 'sdram_we_n' )
+ , (IoPin.SOUTH, None, 'sdram_cs_n' , 'sdram_cs_n' , 'sdram_cs_n' )
+ ]
ioPadsSpec += doIoPowerCap( IoPin.SOUTH|IoPin.A_END )
try:
cell, editor = plugins.kwParseMain( **kw )
cell = af.getCell( 'ls180', CRL.Catalog.State.Logical )
if cell is None:
- print( ErrorMessage( 2, 'doDesign.scriptMain(): ' \
- 'Unable to load cell "{}".' \
+ print( ErrorMessage( 2, 'doDesign.scriptMain(): Unable to load cell "{}".' \
.format('ls180') ))
sys.exit(1)
if editor: editor.setCell( cell )
ls180Conf.cfg.anabatic.searchHalo = 2
ls180Conf.cfg.anabatic.globalIterations = 20
ls180Conf.cfg.anabatic.topRoutingLayer = 'METAL5'
- ls180Conf.cfg.katana.hTracksReservedLocal = 6
- ls180Conf.cfg.katana.vTracksReservedLocal = 3
- ls180Conf.cfg.katana.hTracksReservedMin = 3
- ls180Conf.cfg.katana.vTracksReservedMin = 1
+ ls180Conf.cfg.katana.hTracksReservedLocal = 9
+ ls180Conf.cfg.katana.vTracksReservedLocal = 5
+ ls180Conf.cfg.katana.hTracksReservedMin = 6
+ ls180Conf.cfg.katana.vTracksReservedMin = 4
+ ls180Conf.cfg.katana.runRealignStage = True
ls180Conf.cfg.block.spareSide = u(7*13)
ls180Conf.cfg.chip.supplyRailWidth = u(35)
ls180Conf.cfg.chip.supplyRailPitch = u(90)
ls180Conf.bRows = 2
ls180Conf.chipConf.name = 'chip'
ls180Conf.chipConf.ioPadGauge = 'LibreSOCIO'
- ls180Conf.coreSize = (coreSize, coreSize)
- ls180Conf.chipSize = (coreSize + chipBorder, coreSize + chipBorder)
+ ls180Conf.coreSize = (coreSizeX, coreSizeY)
+ ls180Conf.chipSize = (coreSizeX + chipBorder + u(5.0), coreSizeY + chipBorder - u(0.04) )
with UpdateSession():
sliceHeight = ls180Conf.sliceHeight
- coreAb = Box( 0, 0, coreSize, coreSize )
+ coreAb = Box( 0, 0, coreSizeX, coreSizeY )
rsetAbutmentBox( cell, coreAb )
ls180ToChip = CoreToChip( ls180Conf )
# Thoses ids are dependent on Yosys. They need to be adjusted whenever
# the design changes.
#tiId = 38695
- tiId = 38381
+ #tiId = 38381
+ #tiId = 10863
+ tiId = 12974
#sramId = 3695
- sramId = 3300
+ #sramId = 3300
+ #sramId = 3301
+ sramId = 3481
tiPath = 'subckt_{}_test_issuer.subckt_1_ti.'.format(tiId)
- sramPaths = [ tiPath+'subckt_{}_sram4k_0.subckt_144_SPBlock_512W64B8W'.format(sramId)
- , tiPath+'subckt_{}_sram4k_1.subckt_144_SPBlock_512W64B8W'.format(sramId+1)
- , tiPath+'subckt_{}_sram4k_2.subckt_144_SPBlock_512W64B8W'.format(sramId+2)
- , tiPath+'subckt_{}_sram4k_3.subckt_144_SPBlock_512W64B8W'.format(sramId+3)
- ]
- sram = DataBase.getDB().getCell( 'SPBlock_512W64B8W' )
+ sramDatas \
+ = [ (tiPath+'subckt_{}_sram4k_0.subckt_152_spblock_512w64b8w'.format(sramId) , -2)
+ , (tiPath+'subckt_{}_sram4k_1.subckt_152_spblock_512w64b8w'.format(sramId+1), 3)
+ , (tiPath+'subckt_{}_sram4k_2.subckt_152_spblock_512w64b8w'.format(sramId+2), 2)
+ , (tiPath+'subckt_{}_sram4k_3.subckt_152_spblock_512w64b8w'.format(sramId+3), 3)
+ ]
+ sram = DataBase.getDB().getCell( 'spblock_512w64b8w' )
if not sram:
- raise ErrorMessage( 1, 'SRAM instance "{}" ' \
- 'not found.'.format(sramPaths[i]) )
+ raise ErrorMessage( 1, 'SRAM instance "{}" not found.'.format(sramDatas[i][0]) )
+ sram.setAbstractedSupply( True )
sramAb = sram.getAbutmentBox()
- coreAb = cell.getAbutmentBox()
+ sramAb = sram.getAbutmentBox()
+ coreAb = cell.getAbutmentBox()
sliceHeight = chipBuilder.conf.sliceHeight
- originX = coreAb.getXMin() + 2*chipBuilder.conf.sliceStep
- for i in range(4):
- sram = rgetInstance( cell, sramPaths[i] )
- y = coreAb.getYMax() - sramAb.getHeight() - 2*sliceHeight
- t = Transformation(originX, y, Transformation.Orientation.ID)
- chipBuilder.placeMacro ( sramPaths[i], t )
- originX += sramAb.getWidth () + 3*sliceHeight
- pll = addPllPlaceHolder( cell )
- pllAb = pll.getAbutmentBox()
- t = Transformation( coreAb.getXMax() - pllAb.getWidth()
- , coreAb.getYMax() - pllAb.getHeight()
- , Transformation.Orientation.ID )
- pll.setTransformation(t)
- pll.setPlacementStatus( Instance.PlacementStatus.FIXED )
- #ls180Conf.placeArea = Box( coreAb.getXMin()
- # , coreAb.getYMin()
- # , coreAb.getXMax() - chipBuilder.conf.sliceStep
- # , coreAb.getYMax() - sramAb.getHeight() - 2*sliceHeight
- # )
- #memPatterns = [ r'^mem_(?P<i>\d+)__(?P<j>[\d+])$'
- # , r'^mem_1_(?P<i>\d+)__(?P<j>[\d+])$'
- # , r'^mem_2_(?P<i>\d+)__(?P<j>[\d+])$'
- # , r'^mem_3_(?P<i>\d+)__(?P<j>[\d+])$'
- # ]
- #originX += 2*sliceHeight
- #originY = coreAb.getYMax()
- #for i in range(len(memPatterns)):
- # mem = RegisterMatrix( ls180Conf, cell, memPatterns[i] )
- # originY -= mem.getHeight()
- # mem.place( Point(originX,originY) )
+ sliceStep = chipBuilder.conf.sliceStep
+ originX = coreAb.getXMin() + sramDatas[0][1]*chipBuilder.conf.sliceStep
+ for i in range(len(sramDatas)):
+ sram = rgetInstance( cell, sramDatas[i][0] )
+ chipBuilder.placeMacro \
+ ( sramDatas[i][0]
+ , Transformation( originX
+ , coreAb.getYMax() - sramAb.getHeight() - 2*sliceHeight
+ , Transformation.Orientation.ID )
+ )
+ if i+1 < len(sramDatas):
+ originX += sramAb.getWidth() + 2*sliceHeight + sramDatas[i+1][1]*sliceStep
+ twoGrid = DbU.fromGrid( 2 )
+ pll = DataBase.getDB().getCell( 'gds_PLL' )
+ pllAb = pll.getAbutmentBox()
+ pllInstance = Instance.create( cell, 'GDS_PLL', pll )
+ position = Transformation( onGrid( coreAb.getXMax() - pllAb.getWidth () -pllAb.getXMin() )
+ , onGrid( coreAb.getYMax() - pllAb.getHeight() -pllAb.getYMin() )
+ , Transformation.Orientation.ID )
+ pllInstance.setTransformation( position )
+ pllInstance.setPlacementStatus( Instance.PlacementStatus.FIXED )
Breakpoint.stop( 99, 'After core placement.' )
rvalue = chipBuilder.doPnR()