# -*- Mode:Python -*-
-import Cfg
-import CRL
-import Viewer
-from helpers.overlay import CfgCache
-import symbolic.cmos45 # do not remove
import os
+import socket
+import helpers
+
+NdaDirectory = None
+if os.environ.has_key('NDA_TOP'):
+ NdaDirectory = os.environ['NDA_TOP']
+if not NdaDirectory:
+ hostname = socket.gethostname()
+ if hostname.startswith('lepka'):
+ NdaDirectory = '/dsk/l1/jpc/crypted/soc/techno'
+ if not os.path.isdir(NdaDirectory):
+ print '[ERROR] You forgot to mount the NDA encrypted directory, stupid!'
+ else:
+ NdaDirectory = '/users/soft/techno/techno'
+helpers.setNdaTopDir( NdaDirectory )
-if os.environ.has_key('CELLS_TOP'):
- cellsTop = os.environ['CELLS_TOP']
-else:
- cellsTop = '../../../alliance-check-toolkit/cells'
-
-with CfgCache('', priority=Cfg.Parameter.Priority.UserFile) as cfg:
- cfg.misc.catchCore = False
- cfg.misc.info = False
- cfg.misc.paranoid = False
- cfg.misc.bug = False
- cfg.misc.logMode = True
- cfg.misc.verboseLevel1 = True
- cfg.misc.verboseLevel2 = True
- cfg.anabatic.edgeLenght = 24
- cfg.anabatic.edgeWidth = 8
- cfg.anabatic.topRoutingLayer = 'METAL5'
- cfg.etesian.graphics = 3
-
- #cfg.katana.searchHalo = 30
- #cfg.katana.eventsLimit = 1000000
- #cfg.katana.hTracksReservedLocal = 7
-
- # Run 2 (make-cgt-2.log)
- #cfg.etesian.effort = 2
- #cfg.etesian.uniformDensity = True
- #cfg.etesian.spaceMargin = 0.05
- #cfg.etesian.aspectRatio = 1.0
- #cfg.katana.vTracksReservedLocal = 4
- #cfg.katana.hTracksReservedLocal = 4
-
- # Run 3 (make-cgt-3.log)
- #cfg.etesian.effort = 2
- #cfg.etesian.uniformDensity = False
- #cfg.etesian.spaceMargin = 0.05
- #cfg.etesian.aspectRatio = 1.0
- #cfg.katana.vTracksReservedLocal = 5
- #cfg.katana.hTracksReservedLocal = 5
-
- # Run 4 (make-cgt-4.log)
- #cfg.etesian.effort = 2
- #cfg.etesian.uniformDensity = True
- #cfg.etesian.spaceMargin = 0.05
- #cfg.etesian.aspectRatio = 1.0
-
- # Run 5 (make-cgt-5.log)
- cfg.etesian.effort = 2
- cfg.etesian.uniformDensity = True
- cfg.etesian.spaceMargin = 0.05
- cfg.etesian.aspectRatio = 1.0
- cfg.katana.useGlobalEstimate = False
- cfg.katana.vTracksReservedLocal = 7
- cfg.katana.hTracksReservedLocal = 6
- cfg.katana.bloatOverloadAdd = 4
- cfg.conductor.stopLevel = 0
- cfg.conductor.maxPlaceIterations = 2
- cfg.conductor.useFixedAbHeight = False
-
- env = CRL.AllianceFramework.get().getEnvironment()
+import Cfg
+from CRL import AllianceFramework
+from helpers import overlay, l, u, n
+from NDA.node180.tsmc_c018 import techno, FlexLib, LibreSOCIO, LibreSOCMem
+
+techno.setup()
+FlexLib.setup()
+LibreSOCIO.setup()
+LibreSOCMem.setup()
+
+with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
+ cfg.misc.catchCore = False
+ cfg.misc.minTraceLevel = 14700
+ cfg.misc.maxTraceLevel = 14800
+ cfg.misc.info = False
+ cfg.misc.paranoid = False
+ cfg.misc.bug = False
+ cfg.misc.logMode = True
+ cfg.misc.verboseLevel1 = True
+ cfg.misc.verboseLevel2 = True
+ cfg.etesian.graphics = 3
+ cfg.etesian.spaceMargin = 0.10
+ cfg.katana.eventsLimit = 4000000
+ af = AllianceFramework.get()
+ env = af.getEnvironment()
env.setCLOCK( '^sys_clk$|^ck|^jtag_tck$' )
- env.addSYSTEM_LIBRARY(library=cellsTop+'/niolib',
- mode=CRL.Environment.Prepend )
- env.addSYSTEM_LIBRARY(library=cellsTop+'/nsxlib',
- mode=CRL.Environment.Prepend )
- env.setPOWER ('vdd')
- env.setGROUND('vss')
-
-Viewer.Graphics.setStyle('Alliance.Classic [black]')
-
-print( ' o Successfully run "<>/coriolis2/settings.py".' )
-print( ' - CELLS_TOP = "{}"'.format(cellsTop) )
import json
import sys
import traceback
+import collections
import CRL
import helpers
-from helpers.io import ErrorMessage, WarningMessage
-from helpers import trace, l, u, n
+from helpers import trace, l, u, n
+from helpers.io import ErrorMessage, WarningMessage
+from helpers.overlay import UpdateSession
import plugins
-from Hurricane import DbU
-from plugins.alpha.block.configuration import IoPin, GaugeConf
+from Hurricane import Breakpoint, DbU, Transformation, Box, Instance
+from plugins.alpha.macro.macro import Macro
from plugins.alpha.block.iospecs import IoSpecs
from plugins.alpha.block.block import Block
+from plugins.alpha.block.configuration import IoPin, GaugeConf
from plugins.alpha.core2chip.libresocio import CoreToChip
from plugins.alpha.chip.configuration import ChipConf
from plugins.alpha.chip.chip import Chip
-af = CRL.AllianceFramework.get()
+af = CRL.AllianceFramework.get()
+powerCount = 0
+
+
+def isiterable ( pyobj ):
+ if isinstance(pyobj,collections.Iterable): return True
+ return False
+
+
+def doIoPowerCap ( flags ):
+ global powerCount
+ side = flags & IoPin.SIDE_MASK
+ if flags & IoPin.A_BEGIN:
+ 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
+
+
+def doIoPinVector ( ioSpec, bits ):
+ v = []
+ if not isiterable(bits): bits = range(bits)
+ if not bits:
+ raise ErrorMessage( 1, [ 'doIoPinVector(): Argument "bits" is neither a width nor an iterable.'
+ , '(bits={})'.format(bits)
+ ] )
+ if len(ioSpec) == 5:
+ for bit in bits:
+ v.append(( ioSpec[0]
+ , ioSpec[1]
+ , ioSpec[2].format(bit)
+ , ioSpec[3].format(bit)
+ , ioSpec[4].format(bit) ))
+ elif len(ioSpec) == 6:
+ for bit in bits:
+ v.append(( ioSpec[0]
+ , ioSpec[1]
+ , ioSpec[2].format(bit)
+ , ioSpec[3].format(bit)
+ , ioSpec[4].format(bit)
+ , ioSpec[5].format(bit) ))
+ elif len(ioSpec) == 7:
+ for bit in bits:
+ v.append(( ioSpec[0]
+ , ioSpec[1]
+ , ioSpec[2].format(bit)
+ , ioSpec[3].format(bit)
+ , ioSpec[4].format(bit)
+ , 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))
+ , '(ioSpec={})'.format(ioSpec)
+ ] )
+ return v
+
+
+def rgetInstance ( cell, path ):
+ """
+ Get the instance designated by path (recursively). The path argument can be
+ either a string of instance names separated by dots or directly a list of
+ instances names.
+ """
+ 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 ({})"' \
+ .format(path) )
+ instance = cell.getInstance( path[0] )
+ if instance is None:
+ raise ErrorMessage( 1, 'rgetInstance(): no instance "{}" in cell "{}"' \
+ .format(path[0],cell.getName()) )
+ if len(path) == 1:
+ return instance
+ return rgetInstance( instance.getMasterCell(), path[1:] )
+
+
+def rsetAbutmentBox ( cell, ab ):
+ for occurrence in cell.getNonTerminalNetlistInstanceOccurrences():
+ masterCell = occurrence.getEntity().getMasterCell()
+ masterCell.setAbutmentBox( ab )
+
def scriptMain (**kw):
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
global af
- rvalue = True
- coreSize = 5200.0
- chipBorder = 2*214.0 + 10*13.0
- ioSpecs = IoSpecs()
- ioSpecs.loadFromPinmux( './non_generated/litex_pinpads.json' )
+ #helpers.setTraceLevel( 550 )
+ rvalue = True
+ coreSize = u(5850.0)
+ chipBorder = u(2*214.0 + 10*13.0)
+ ioSpecs = IoSpecs()
+ #pinmuxFile = './non_generated/litex_pinpads.json'
+ #pinmuxFile = './coriolis2/ls180/litex_pinpads.json'
+ #ioSpecs.loadFromPinmux( pinmuxFile )
+ # 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 += 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 += [ (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' )
+ ]
+ 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 += 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 += doIoPinVector( (IoPin.NORTH, None, 'nc_{}', 'nc({})', 'nc({})'), range(16,18) )
+ 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 += [ (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) )
+ ioPadsSpec += [ (IoPin.SOUTH, None, 'sys_pll_18_o' , 'sys_pll_18_o' , 'sys_pll_18_o' ) ]
+ ioPadsSpec += doIoPinVector( (IoPin.SOUTH, None, 'sys_clksel_i{}', 'sys_clksel_i({})', 'sys_clksel_i({})'), 2 )
+ ioPadsSpec += [ (IoPin.SOUTH, None, 'sys_pll_lck_o' , 'sys_pll_lck_o' , 'sys_pll_lck_o' ) ]
+ ioPadsSpec += doIoPowerCap( IoPin.SOUTH|IoPin.A_END )
try:
- #helpers.setTraceLevel( 550 )
cell, editor = plugins.kwParseMain( **kw )
cell = af.getCell( 'ls180', CRL.Catalog.State.Logical )
if cell is None:
.format('ls180') ))
sys.exit(1)
if editor: editor.setCell( cell )
- ls180Conf = ChipConf( cell, ioPads=ioSpecs.ioPadsSpec )
+ #ls180Conf = ChipConf( cell, ioPads=ioSpecs.ioPadsSpec )
+ ls180Conf = ChipConf( cell, ioPads=ioPadsSpec )
ls180Conf.cfg.etesian.bloat = 'nsxlib'
ls180Conf.cfg.etesian.uniformDensity = True
ls180Conf.cfg.etesian.aspectRatio = 1.0
ls180Conf.cfg.katana.vTracksReservedLocal = 3
ls180Conf.cfg.katana.hTracksReservedMin = 3
ls180Conf.cfg.katana.vTracksReservedMin = 1
- ls180Conf.cfg.block.spareSide = u(200)
+ ls180Conf.cfg.block.spareSide = u(156)
ls180Conf.cfg.chip.supplyRailWidth = u(35)
ls180Conf.cfg.chip.supplyRailPitch = u(90)
ls180Conf.editor = editor
ls180Conf.bRows = 2
ls180Conf.chipConf.name = 'chip'
ls180Conf.chipConf.ioPadGauge = 'LibreSOCIO'
- ls180Conf.coreSize = (u(coreSize), u(coreSize))
- ls180Conf.chipSize = (u(coreSize + chipBorder), u(coreSize + chipBorder))
+ ls180Conf.coreSize = (coreSize, coreSize)
+ ls180Conf.chipSize = (coreSize + chipBorder, coreSize + chipBorder)
+
+ with UpdateSession():
+ sliceHeight = ls180Conf.sliceHeight
+ coreAb = Box( 0, 0, coreSize, coreSize )
+ rsetAbutmentBox( cell, coreAb )
+ tiPath = 'subckt_38695_test_issuer.subckt_1_ti.'
+ sramPaths = [ tiPath+'subckt_3695_sram4k_0.subckt_144_SPBlock_512W64B8W'
+ , tiPath+'subckt_3696_sram4k_1.subckt_144_SPBlock_512W64B8W'
+ , tiPath+'subckt_3697_sram4k_2.subckt_144_SPBlock_512W64B8W'
+ , tiPath+'subckt_3698_sram4k_3.subckt_144_SPBlock_512W64B8W'
+ ]
+ sramAb = None
+ for i in range(4):
+ sram = rgetInstance( cell, sramPaths[i] )
+ if not sram:
+ raise ErrorMessage( 1, 'SRAM instance "{}" not found.'.format(sramPaths[i]) )
+ if i == 0:
+ Macro.wrap( sram.getMasterCell(), 'FlexLib', 3, 2 )
+ sramAb = sram.getMasterCell().getAbutmentBox()
+ Macro.place( sram
+ , Transformation( coreAb.getXMin() + sramAb.getWidth ()*i
+ , coreAb.getYMax() - sramAb.getHeight()
+ , Transformation.Orientation.ID )
+ , Instance.PlacementStatus.FIXED )
+ ls180Conf.placeArea = Box( coreAb.getXMin()
+ , coreAb.getYMin()
+ , coreAb.getXMax()
+ , coreAb.getYMax() - sramAb.getHeight()
+ )
+ Breakpoint.stop( 99, 'After core placement.' )
+
ls180ToChip = CoreToChip( ls180Conf )
ls180ToChip.buildChip()
chipBuilder = Chip( ls180Conf )