diff --git a/anabatic/src/NetBuilderVH.cpp b/anabatic/src/NetBuilderVH.cpp index 3919e4b5..51c92749 100644 --- a/anabatic/src/NetBuilderVH.cpp +++ b/anabatic/src/NetBuilderVH.cpp @@ -521,6 +521,12 @@ namespace Anabatic { } + bool NetBuilderVH::_do_2G () + { + cdebug_log(145,0) << getTypeName() << "::_do_2G()" << endl; + return _do_xG(); + } + bool NetBuilderVH::_do_xG () { cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl; diff --git a/anabatic/src/anabatic/NetBuilderVH.h b/anabatic/src/anabatic/NetBuilderVH.h index 43a628b0..0c266a52 100644 --- a/anabatic/src/anabatic/NetBuilderVH.h +++ b/anabatic/src/anabatic/NetBuilderVH.h @@ -41,6 +41,7 @@ namespace Anabatic { virtual bool _do_2G_1M1 (); virtual bool _do_xG_xM1_xM3 (); virtual bool _do_xG (); + virtual bool _do_2G (); virtual bool _do_globalSegment (); virtual void singleGCell ( AnabaticEngine*, Net* ); public: diff --git a/crlcore/etc/CMakeLists.txt b/crlcore/etc/CMakeLists.txt index bc1f1611..3fc94878 100644 --- a/crlcore/etc/CMakeLists.txt +++ b/crlcore/etc/CMakeLists.txt @@ -1,6 +1,7 @@ install( DIRECTORY common DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install( DIRECTORY symbolic DESTINATION ${SYS_CONF_DIR}/coriolis2 ) + install( DIRECTORY node45 DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install( DIRECTORY node180 DESTINATION ${SYS_CONF_DIR}/coriolis2 ) install( DIRECTORY node600 DESTINATION ${SYS_CONF_DIR}/coriolis2 ) diff --git a/crlcore/etc/common/technology.py b/crlcore/etc/common/technology.py index bd3b1504..cad2ba12 100644 --- a/crlcore/etc/common/technology.py +++ b/crlcore/etc/common/technology.py @@ -93,15 +93,15 @@ gcut = createBL( 'gcut' , BasicLayer.Material.cut ) # *Must be a gmetalv = createBL( 'gmetalv' , BasicLayer.Material.metal ) # VIAs for real technologies. -ViaLayer.create( tech, 'via12' , metal1, cut1, metal2 ) -ViaLayer.create( tech, 'via23' , metal2, cut2, metal3 ) -ViaLayer.create( tech, 'via34' , metal3, cut3, metal4 ) -ViaLayer.create( tech, 'via45' , metal4, cut4, metal5 ) -ViaLayer.create( tech, 'via56' , metal5, cut5, metal6 ) -ViaLayer.create( tech, 'via67' , metal6, cut6, metal7 ) -ViaLayer.create( tech, 'via78' , metal7, cut7, metal8 ) -ViaLayer.create( tech, 'via89' , metal8, cut8, metal9 ) -ViaLayer.create( tech, 'via910', metal9, cut9, metal10 ) +via12 = ViaLayer.create( tech, 'via12' , metal1, cut1, metal2 ) +via23 = ViaLayer.create( tech, 'via23' , metal2, cut2, metal3 ) +via34 = ViaLayer.create( tech, 'via34' , metal3, cut3, metal4 ) +via45 = ViaLayer.create( tech, 'via45' , metal4, cut4, metal5 ) +via56 = ViaLayer.create( tech, 'via56' , metal5, cut5, metal6 ) +via67 = ViaLayer.create( tech, 'via67' , metal6, cut6, metal7 ) +via78 = ViaLayer.create( tech, 'via78' , metal7, cut7, metal8 ) +via89 = ViaLayer.create( tech, 'via89' , metal8, cut8, metal9 ) +via910 = ViaLayer.create( tech, 'via910', metal9, cut9, metal10 ) # Composite/Symbolic layers. NWELL = RegularLayer .create( tech, 'NWELL' , nWell ) diff --git a/crlcore/etc/node45/__init__.py b/crlcore/etc/node45/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/crlcore/etc/node45/freepdk45/__init__.py b/crlcore/etc/node45/freepdk45/__init__.py new file mode 100644 index 00000000..c245b98c --- /dev/null +++ b/crlcore/etc/node45/freepdk45/__init__.py @@ -0,0 +1,40 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2019, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/__init__.py" | +# +-----------------------------------------------------------------+ + + +import Cfg +import helpers.io +helpers.io.vprint( 1, ' o Loading "node45.freepdk45" technology.' ) +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +from Hurricane import DataBase +from CRL import System + +Cfg.Configuration.pushDefaultPriority( Cfg.Parameter.Priority.ConfigurationFile ) + +DataBase.create() +System.get() + +import node45.freepdk45.misc +import node45.freepdk45.technology +import node45.freepdk45.display +import node45.freepdk45.analog +import node45.freepdk45.alliance +import node45.freepdk45.etesian +import node45.freepdk45.kite +import node45.freepdk45.plugins +import node45.freepdk45.stratus1 +import node45.freepdk45.devices + +Cfg.Configuration.popDefaultPriority() diff --git a/crlcore/etc/node45/freepdk45/alliance.py b/crlcore/etc/node45/freepdk45/alliance.py new file mode 100644 index 00000000..4f0a978a --- /dev/null +++ b/crlcore/etc/node45/freepdk45/alliance.py @@ -0,0 +1,52 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2020, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/alliance.py" | +# +-----------------------------------------------------------------+ + + +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +import os +import os.path +from CRL import Environment +from CRL import AllianceFramework + + +allianceTop = None +if os.environ.has_key('ALLIANCE_TOP'): + allianceTop = os.environ['ALLIANCE_TOP'] + if not os.path.isdir(allianceTop): + allianceTop = None + +if not allianceTop: allianceTop = '/soc/alliance' + +cellsTop = allianceTop+'/cells' + +af = AllianceFramework.get() +env = af.getEnvironment() + +env.setSCALE_X ( 100 ) +env.setCATALOG ( 'CATAL' ) +env.setIN_LO ( 'vst' ) +env.setIN_PH ( 'ap' ) +env.setOUT_LO ( 'vst' ) +env.setOUT_PH ( 'ap' ) +env.setPOWER ( 'vdd' ) +env.setGROUND ( 'vss' ) +env.setCLOCK ( '.*ck.*|.*nck.*' ) +env.setBLOCKAGE ( 'blockage[Nn]et.*' ) +env.setPad ( '.*_mpx$' ) + +env.setWORKING_LIBRARY( '.' ) +env.addSYSTEM_LIBRARY ( library=cellsTop+'/nsxlib', mode=Environment.Append ) +env.addSYSTEM_LIBRARY ( library=cellsTop+'/mpxlib', mode=Environment.Append ) diff --git a/crlcore/etc/node45/freepdk45/analog.py b/crlcore/etc/node45/freepdk45/analog.py new file mode 100644 index 00000000..83b2d1fa --- /dev/null +++ b/crlcore/etc/node45/freepdk45/analog.py @@ -0,0 +1,19 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2020, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/analog.py" | +# +-----------------------------------------------------------------+ + + +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +#import common.analog diff --git a/crlcore/etc/node45/freepdk45/devices.py b/crlcore/etc/node45/freepdk45/devices.py new file mode 100644 index 00000000..9926656b --- /dev/null +++ b/crlcore/etc/node45/freepdk45/devices.py @@ -0,0 +1,138 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2020, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./node45/freepdk45/devices.py" | +# +-----------------------------------------------------------------+ + + +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +import common.devices +from common.devices import addDevice + + +chamsDir = helpers.sysConfDir + '/share/coriolis2/' +spiceDir = chamsDir + 'spice/' + + +addDevice( name = 'DifferentialPairBulkConnected' + , spice = spiceDir+'DiffPairBulkConnected.spi' + , connectors = ( 'D1', 'D2', 'G1', 'G2', 'S' ) + , layouts = ( ('Horizontal M2' , 'DP_horizontalM2.py' ) + , ('Symmetrical' , 'DP_symmetrical.py' ) + , ('Common centroid', 'DP_2DCommonCentroid.py') + , ('Interdigitated' , 'DP_interdigitated.py' ) + , ('WIP DP' , 'wip_dp.py' ) + ) + ) +addDevice( name = 'DifferentialPairBulkUnconnected' + , spice = spiceDir+'DiffPairBulkUnconnected.spi' + , connectors = ( 'D1', 'D2', 'G1', 'G2', 'S', 'B' ) + , layouts = ( ('Horizontal M2' , 'DP_horizontalM2.py' ) + , ('Symmetrical' , 'DP_symmetrical.py' ) + , ('Common centroid', 'DP_2DCommonCentroid.py') + , ('Interdigitated' , 'DP_interdigitated.py' ) + , ('WIP DP' , 'wip_dp.py' ) + ) + ) +addDevice( name = 'LevelShifterBulkUnconnected' + , spice = spiceDir+'LevelShifterBulkUnconnected.spi' + , connectors = ( 'D1', 'D2', 'S1', 'S2', 'B' ) + , layouts = ( ('Horizontal M2' , 'LS_horizontalM2.py' ) + , ('Symmetrical' , 'LS_symmetrical.py' ) + , ('Common centroid', 'LS_2DCommonCentroid.py') + , ('Interdigitated' , 'LS_interdigitated.py' ) + ) + ) +addDevice( name = 'TransistorBulkConnected' + , spice = spiceDir+'TransistorBulkConnected.spi' + , connectors = ( 'D', 'G', 'S' ) + , layouts = ( ('Rotate transistor', 'Transistor_rotate.py') + , ('Common transistor', 'Transistor_common.py') + , ('WIP Transistor' , 'wip_transistor.py' ) + ) + ) +addDevice( name = 'TransistorBulkUnconnected' + , spice = spiceDir+'TransistorBulkUnconnected.spi' + , connectors = ( 'D', 'G', 'S', 'B' ) + , layouts = ( ('Rotate transistor', 'Transistor_rotate.py') + , ('Common transistor', 'Transistor_common.py') + , ('WIP Transistor' , 'wip_transistor.py' ) + ) + ) +addDevice( name = 'CrossCoupledPairBulkConnected' + , spice = spiceDir+'CCPairBulkConnected.spi' + , connectors = ( 'D1', 'D2', 'S' ) + , layouts = ( ('Horizontal M2' , 'CCP_horizontalM2.py' ) + , ('Symmetrical' , 'CCP_symmetrical.py' ) + , ('Common centroid', 'CCP_2DCommonCentroid.py') + , ('Interdigitated' , 'CCP_interdigitated.py' ) + ) + ) +addDevice( name = 'CrossCoupledPairBulkUnconnected' + , spice = spiceDir+'CCPairBulkUnconnected.spi' + , connectors = ( 'D1', 'D2', 'S', 'B' ) + , layouts = ( ('Horizontal M2' , 'CCP_horizontalM2.py' ) + , ('Symmetrical' , 'CCP_symmetrical.py' ) + , ('Common centroid', 'CCP_2DCommonCentroid.py') + , ('Interdigitated' , 'CCP_interdigitated.py' ) + ) + ) +addDevice( name = 'CommonSourcePairBulkConnected' + , spice = spiceDir+'CommonSourcePairBulkConnected.spi' + , connectors = ( 'D1', 'D2', 'S', 'G' ) + , layouts = ( ('Horizontal M2' , 'CSP_horizontalM2.py' ) + , ('Symmetrical' , 'CSP_symmetrical.py' ) + , ('Interdigitated' , 'CSP_interdigitated.py' ) + , ('WIP CSP' , 'wip_csp.py' ) + ) + ) +addDevice( name = 'CommonSourcePairBulkUnconnected' + , spice = spiceDir+'CommonSourcePairBulkUnconnected.spi' + , connectors = ( 'D1', 'D2', 'S', 'G', 'B' ) + , layouts = ( ('Horizontal M2' , 'CSP_horizontalM2.py' ) + , ('Symmetrical' , 'CSP_symmetrical.py' ) + , ('Interdigitated' , 'CSP_interdigitated.py' ) + , ('WIP CSP' , 'wip_csp.py' ) + ) + ) +addDevice( name = 'SimpleCurrentMirrorBulkConnected' + , spice = spiceDir+'CurrMirBulkConnected.spi' + , connectors = ( 'D1', 'D2', 'S' ) + , layouts = ( ('Horizontal M2' , 'SCM_horizontalM2.py' ) + , ('Symmetrical' , 'SCM_symmetrical.py' ) + , ('Common centroid', 'SCM_2DCommonCentroid.py') + , ('Interdigitated' , 'SCM_interdigitated.py' ) + ) + ) +addDevice( name = 'SimpleCurrentMirrorBulkUnconnected' + , spice = spiceDir+'CurrMirBulkUnconnected.spi' + , connectors = ( 'D1', 'D2', 'S', 'B' ) + , layouts = ( ('Horizontal M2' , 'SCM_horizontalM2.py' ) + , ('Symmetrical' , 'SCM_symmetrical.py' ) + , ('Common centroid', 'SCM_2DCommonCentroid.py') + , ('Interdigitated' , 'SCM_interdigitated.py' ) + ) + ) +addDevice( name = 'MultiCapacitor' + #, spice = spiceDir+'MIM_OneCapacitor.spi' + #, connectors = ( 'T1', 'B1' ) + , layouts = ( ('Matrix', 'capacitormatrix.py' ), + ) + ) +addDevice( name = 'Resistor' + #, spice = spiceDir+'MIM_OneCapacitor.spi' + , connectors = ( 'PIN1', 'PIN2' ) + , layouts = ( ('Snake', 'resistorsnake.py' ), + ) + ) + diff --git a/crlcore/etc/node45/freepdk45/display.py b/crlcore/etc/node45/freepdk45/display.py new file mode 100644 index 00000000..4843a1ef --- /dev/null +++ b/crlcore/etc/node45/freepdk45/display.py @@ -0,0 +1,22 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2020, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/display.py" | +# +-----------------------------------------------------------------+ + + +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +import common.display + + +common.display.createStyles( scale=0.5 ) diff --git a/crlcore/etc/node45/freepdk45/etesian.py b/crlcore/etc/node45/freepdk45/etesian.py new file mode 100644 index 00000000..b8197ff0 --- /dev/null +++ b/crlcore/etc/node45/freepdk45/etesian.py @@ -0,0 +1,19 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2019, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/etesian.py" | +# +-----------------------------------------------------------------+ + + +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +import common.etesian diff --git a/crlcore/etc/node45/freepdk45/kite.py b/crlcore/etc/node45/freepdk45/kite.py new file mode 100644 index 00000000..fff00d91 --- /dev/null +++ b/crlcore/etc/node45/freepdk45/kite.py @@ -0,0 +1,213 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2019, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/kite.py" | +# +-----------------------------------------------------------------+ + + +import Cfg +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +from Hurricane import DataBase +from CRL import AllianceFramework +from CRL import RoutingGauge +from CRL import RoutingLayerGauge +from CRL import CellGauge +from helpers import l, n, u +import common.kite + + +p = Cfg.getParamDouble ( 'lefImport.minTerminalWidth' ).setDouble ( 0.0 ) +p = Cfg.getParamString ( 'katabatic.routingGauge' ).setString ( 'LEF.CoreSite' ) +p = Cfg.getParamInt ( "katabatic.globalLengthThreshold" ).setInt ( 1450 ) +p = Cfg.getParamPercentage( "katabatic.saturateRatio" ).setPercentage( 80 ) +p = Cfg.getParamInt ( "katabatic.saturateRp" ).setInt ( 8 ) +p = Cfg.getParamString ( 'katabatic.topRoutingLayer' ).setString ( 'metal5' ) + + # Kite parameters. +p = Cfg.getParamInt( "kite.hTracksReservedLocal" ); p.setInt( 4 ); p.setMin( 0 ); p.setMax( 18 ) +p = Cfg.getParamInt( "kite.vTracksReservedLocal" ); p.setInt( 3 ); p.setMin( 0 ); p.setMax( 18 ) +p = Cfg.getParamInt( "kite.eventsLimit" ); p.setInt( 4000002 ) +p = Cfg.getParamInt( "kite.ripupCost" ); p.setInt( 3 ); p.setMin( 0 ) +p = Cfg.getParamInt( "kite.strapRipupLimit" ); p.setInt( 16 ); p.setMin( 1 ) +p = Cfg.getParamInt( "kite.localRipupLimit" ); p.setInt( 9 ); p.setMin( 1 ) +p = Cfg.getParamInt( "kite.globalRipupLimit" ); p.setInt( 5 ); p.setMin( 1 ) +p = Cfg.getParamInt( "kite.longGlobalRipupLimit" ); p.setInt( 5 ); p.setMin( 1 ) + +# Anabatic & Katana parameters are temporarily hosted here. +p = Cfg.getParamString ( 'crlcore.groundName' ); p.setString ( 'gnd!' ) +p = Cfg.getParamString ( 'crlcore.powerName' ); p.setString ( 'vdd!' ) +p = Cfg.getParamString ( 'anabatic.routingGauge' ); p.setString ( 'LEF.CoreSite' ) +p = Cfg.getParamInt ( "anabatic.globalLengthThreshold" ); p.setInt ( 1450 ) +p = Cfg.getParamPercentage( "anabatic.saturateRatio" ); p.setPercentage( 90 ) +p = Cfg.getParamInt ( "anabatic.saturateRp" ); p.setInt ( 10 ) +p = Cfg.getParamString ( 'anabatic.topRoutingLayer' ); p.setString ( 'metal5' ) +p = Cfg.getParamInt ( "anabatic.edgeLength" ); p.setInt ( 48 ) +p = Cfg.getParamInt ( "anabatic.edgeWidth" ); p.setInt ( 8 ) +p = Cfg.getParamDouble ( "anabatic.edgeCostH" ); p.setDouble ( 9.0 ) +p = Cfg.getParamDouble ( "anabatic.edgeCostK" ); p.setDouble ( -10.0 ) +p = Cfg.getParamDouble ( "anabatic.edgeHInc" ); p.setDouble ( 1.0 ) +p = Cfg.getParamDouble ( "anabatic.edgeHScaling" ); p.setDouble ( 1.0 ) +p = Cfg.getParamInt ( "anabatic.globalIterations" ); p.setInt ( 10 ); p.setMin(1); p.setMax(100) +p = Cfg.getParamEnumerate ( "anabatic.gcell.displayMode" ); p.setInt ( 1 ) +p.addValue( "Boundary", 1 ) +p.addValue( "Density" , 2 ) + +p = Cfg.getParamInt ( "katana.hTracksReservedLocal" ); p.setInt ( 4 ); p.setMin(0); p.setMax(20) +p = Cfg.getParamInt ( "katana.vTracksReservedLocal" ); p.setInt ( 3 ); p.setMin(0); p.setMax(20) +p = Cfg.getParamInt ( "katana.termSatReservedLocal" ); p.setInt ( 8 ) +p = Cfg.getParamInt ( "katana.termSatThreshold" ); p.setInt ( 9 ) +p = Cfg.getParamInt ( "katana.eventsLimit" ); p.setInt ( 4000002 ) +p = Cfg.getParamInt ( "katana.ripupCost" ); p.setInt ( 3 ); p.setMin(0) +p = Cfg.getParamInt ( "katana.strapRipupLimit" ); p.setInt ( 16 ); p.setMin(1) +p = Cfg.getParamInt ( "katana.localRipupLimit" ); p.setInt ( 9 ); p.setMin(1) +p = Cfg.getParamInt ( "katana.globalRipupLimit" ); p.setInt ( 5 ); p.setMin(1) +p = Cfg.getParamInt ( "katana.longGlobalRipupLimit" ); p.setInt ( 5 ); p.setMin(1) +p = Cfg.getParamString( 'chip.padCoreSide' ); p.setString( 'South' ) + + +tech = DataBase.getDB().getTechnology() +af = AllianceFramework.get() +rg = RoutingGauge.create( 'LEF.CoreSite' ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal1') # metal. + , RoutingLayerGauge.Horizontal # preferred routing direction. + , RoutingLayerGauge.PinOnly # layer usage. + , 0 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(0.190) # track pitch. + , u(0.065) # wire width. + , u(0.065) # VIA side (that is VIA12). + , u(0) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal2') # metal. + , RoutingLayerGauge.Vertical # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 1 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(0.190) # track pitch. + , u(0.070) # wire width. + , u(0.070) # VIA side (that is VIA23). + , u(0) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal3') # metal. + , RoutingLayerGauge.Horizontal # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 2 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(0.190) # track pitch. + , u(0.070) # wire width. + , u(0.070) # VIA side (that is VIA34). + , u(0) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal4') # metal. + , RoutingLayerGauge.Vertical # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 3 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(0.285) # track pitch. + , u(0.140) # wire width. + , u(0.140) # VIA side (that is VIA23). + , u(0) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal5') # metal. + , RoutingLayerGauge.Horizontal # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 4 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(0.285) # track pitch. + , u(0.140) # wire width. + , u(0.140) # VIA side (that is VIA23). + , u(0) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal6') # metal. + , RoutingLayerGauge.Vertical # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 5 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(0.285) # track pitch. + , u(0.140) # wire width. + , u(0.140) # VIA side (that is VIA23). + , u(8) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal7') # metal. + , RoutingLayerGauge.Horizontal # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 5 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(0.855) # track pitch. + , u(0.400) # wire width. + , u(0.400) # VIA side (that is VIA23). + , u(0) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal8') # metal. + , RoutingLayerGauge.Vertical # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 5 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(0.855) # track pitch. + , u(0.400) # wire width. + , u(0.400) # VIA side (that is VIA23). + , u(0) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal9') # metal. + , RoutingLayerGauge.Horizontal # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 5 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(1.710) # track pitch. + , u(0.800) # wire width. + , u(0.800) # VIA side (that is VIA23). + , u(0) # obstacle dW. + ) ) + +rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('metal10') # metal. + , RoutingLayerGauge.Vertical # preferred routing direction. + , RoutingLayerGauge.Default # layer usage. + , 5 # depth. + , 0.0 # density (deprecated). + , u(0) # track offset from AB. + , u(1.710) # track pitch. + , u(0.800) # wire width. + , u(0.800) # VIA side (that is VIA23). + , u(0) # obstacle dW. + ) ) + +af.addRoutingGauge( rg ) +af.setRoutingGauge( 'LEF.CoreSite' ) + +# Gauge for standard cells. +cg = CellGauge.create( 'LEF.CoreSite' + , 'metal2' # pin layer name. + , u(0.38) # pitch. + , u(2.47) # cell slice height. + , u(0.38) # cell slice step. + ) +af.addCellGauge( cg ) +af.setCellGauge( 'LEF.CoreSite' ) diff --git a/crlcore/etc/node45/freepdk45/misc.py b/crlcore/etc/node45/freepdk45/misc.py new file mode 100644 index 00000000..155a4762 --- /dev/null +++ b/crlcore/etc/node45/freepdk45/misc.py @@ -0,0 +1,19 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2019, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/misc.py" | +# +-----------------------------------------------------------------+ + + +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +import common.misc diff --git a/crlcore/etc/node45/freepdk45/patterns.py b/crlcore/etc/node45/freepdk45/patterns.py new file mode 100644 index 00000000..a70984b2 --- /dev/null +++ b/crlcore/etc/node45/freepdk45/patterns.py @@ -0,0 +1,19 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2019, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/patterns.py" | +# +-----------------------------------------------------------------+ + + +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +import common.patterns diff --git a/crlcore/etc/node45/freepdk45/plugins.py b/crlcore/etc/node45/freepdk45/plugins.py new file mode 100644 index 00000000..819811f7 --- /dev/null +++ b/crlcore/etc/node45/freepdk45/plugins.py @@ -0,0 +1,29 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2019, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/plugins.py" | +# +-----------------------------------------------------------------+ + + +import Cfg +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +from helpers import l, u, n + +Cfg.getParamInt ( "chip.block.rails.count" ).setInt ( 5 ) +Cfg.getParamInt ( "chip.block.rails.hWidth" ).setInt ( l( 24) ) +Cfg.getParamInt ( "chip.block.rails.vWidth" ).setInt ( l( 24) ) +Cfg.getParamInt ( "chip.block.rails.hSpacing" ).setInt ( l( 12) ) +Cfg.getParamInt ( "chip.block.rails.vSpacing" ).setInt ( l( 12) ) +Cfg.getParamInt ( 'clockTree.minimumSide' ).setInt ( l(1200) ) +Cfg.getParamString( 'clockTree.buffer' ).setString( 'buf_x2') +Cfg.getParamString( 'clockTree.placerEngine' ).setString( 'Etesian') diff --git a/crlcore/etc/node45/freepdk45/stratus1.py b/crlcore/etc/node45/freepdk45/stratus1.py new file mode 100644 index 00000000..d7c124b9 --- /dev/null +++ b/crlcore/etc/node45/freepdk45/stratus1.py @@ -0,0 +1,24 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2019, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/stratus1.py" | +# +-----------------------------------------------------------------+ + + +import Cfg +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +import common.stratus1 + + +Cfg.getParamString( "stratus1.format" ).setString( "vst" ) +Cfg.getParamString( "stratus1.simulator" ).setString( "asimut" ) diff --git a/crlcore/etc/node45/freepdk45/technology.py b/crlcore/etc/node45/freepdk45/technology.py new file mode 100644 index 00000000..2e9bf3c0 --- /dev/null +++ b/crlcore/etc/node45/freepdk45/technology.py @@ -0,0 +1,343 @@ + +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2019-2019, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | Alliance / Hurricane Interface | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@lip6.fr | +# | =============================================================== | +# | Python : "./etc/node45/freepdk45/technology.py" | +# +-----------------------------------------------------------------+ + + +import helpers.io +helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) ) + +from helpers import l, u, n +from Hurricane import DbU +from Hurricane import DataBase +from Hurricane import Technology + + +def setEnclosures ( layer, subLayer, enclosures ): + if isinstance(enclosures,tuple): + henclosure = enclosures[0] + venclosure = enclosures[1] + else: + henclosure = enclosures + venclosure = enclosures + layer.setEnclosure( subLayer, henclosure, Layer.EnclosureH ) + layer.setEnclosure( subLayer, venclosure, Layer.EnclosureV ) + return + + +tech = DataBase.getDB().getTechnology() +if tech: + print WarningMessage( 'cmos.technology: Technology already exists, "%s"' % tech.getName() ) +else: + tech = Technology.create( DataBase.getDB(), 'freepdk45' ) + +DbU.setPrecision ( 2 ) +DbU.setPhysicalsPerGrid ( 0.0025, DbU.UnitPowerMicro ) +DbU.setGridsPerLambda ( 18 ) +DbU.setSymbolicSnapGridStep( DbU.fromLambda( 1.0) ) +DbU.setPolygonStep ( DbU.fromGrid ( 1.0) ) + + +import common +from common.technology import * + +# Rules for real layers. +metal1 .setMinimalSpacing( u( 0.065) ) +metal2 .setMinimalSpacing( u( 0.075) ) +metal3 .setMinimalSpacing( u( 0.07 ) ) +metal4 .setMinimalSpacing( u( 0.14 ) ) +metal5 .setMinimalSpacing( u( 0.14 ) ) +metal6 .setMinimalSpacing( u( 0.14 ) ) +metal7 .setMinimalSpacing( u( 0.4 ) ) +metal8 .setMinimalSpacing( u( 0.4 ) ) +metal9 .setMinimalSpacing( u( 0.8 ) ) +metal10.setMinimalSpacing( u( 0.8 ) ) + +# VIAs (i.e. Metal <--> Metal) (real). +via12.setMinimalSize( u( 0.065) ) +# This is the rule as defined in LEF, but seems wrong to me. +#setEnclosures( via12, metal1, (u(0.035 ), u(0.0 )) ) +setEnclosures( via12, metal1, (u(0.0 ), u(0.035)) ) +setEnclosures( via12, metal2, (u(0.0025), u(0.035)) ) + +via23.setMinimalSize( u(0.070 )) +setEnclosures( via23, metal2, (u(0.0 ), u(0.035)) ) +setEnclosures( via23, metal3, (u(0.035 ), u(0.0 )) ) + +via34.setMinimalSize( u(0.070 )) +setEnclosures( via34, metal3, (u(0.035 ), u(0.0 )) ) +setEnclosures( via34, metal4, u(0.035 )) + +via45.setMinimalSize( u(0.140 )) +setEnclosures( via45, metal4, u(0.0 )) +setEnclosures( via45, metal5, u(0.0 )) + +via56.setMinimalSize( u(0.140 )) +setEnclosures( via56, metal5, u(0.0 )) +setEnclosures( via56, metal6, u(0.0 )) + +via67.setMinimalSize( u(0.140 )) +setEnclosures( via67, metal6, u(0.0 )) +setEnclosures( via67, metal7, u(0.130 )) + +via78.setMinimalSize( u(0.200 )) +setEnclosures( via78, metal7, u(0.0 )) +setEnclosures( via78, metal8, u(0.0 )) + +via89.setMinimalSize( u(0.200 )) +setEnclosures( via89, metal8, u(0.0 )) +setEnclosures( via89, metal9, u(0.200 )) + +via910.setMinimalSize(u(0.400 )) +setEnclosures( via910, metal9, u(0.0 )) +setEnclosures( via910, metal10, (0.0 )) + + + +# Redefine all size from the "cmos" common part. +NWELL.setExtentionCap( nWell, l(4.0) ) +PWELL.setExtentionCap( pWell, l(4.0) ) + +NTIE.setMinimalSize ( l( 3.0) ) +NTIE.setExtentionCap ( nWell , l( 3.0) ) +NTIE.setExtentionWidth( nWell , l( 2.0) ) +NTIE.setExtentionCap ( nImplant, l( 2.5) ) +NTIE.setExtentionWidth( nImplant, l( 1.5) ) +NTIE.setExtentionCap ( active , l( 0.5) ) +NTIE.setExtentionWidth( active , l(-0.5) ) + +PTIE.setMinimalSize ( l( 3.0) ) +PTIE.setExtentionCap ( nWell , l( 3.0) ) +PTIE.setExtentionWidth( nWell , l( 2.0) ) +PTIE.setExtentionCap ( nImplant, l( 2.5) ) +PTIE.setExtentionWidth( nImplant, l( 1.5) ) +PTIE.setExtentionCap ( active , l( 0.5) ) +PTIE.setExtentionWidth( active , l(-0.5) ) + +NDIF.setMinimalSize ( l(3.0) ) +NDIF.setExtentionCap ( nImplant, l(4.0) ) +NDIF.setExtentionWidth( nImplant, l(2.0) ) +NDIF.setExtentionCap ( active , l(2.0) ) +NDIF.setExtentionWidth( active , l(0.0) ) + +PDIF.setMinimalSize ( l(3.0) ) +PDIF.setExtentionCap ( pImplant, l(4.0) ) +PDIF.setExtentionWidth( pImplant, l(2.0) ) +PDIF.setExtentionCap ( active , l(2.0) ) +PDIF.setExtentionWidth( active , l(0.0) ) + +GATE.setMinimalSize ( l(2.0) ) +GATE.setExtentionCap ( poly , l(2.5) ) + +NTRANS.setMinimalSize ( l( 2.0) ) +NTRANS.setExtentionCap ( nImplant, l( 2.0) ) +NTRANS.setExtentionWidth( nImplant, l( 7.0) ) +NTRANS.setExtentionCap ( active , l( 0.0) ) +NTRANS.setExtentionWidth( active , l( 3.0) ) +NTRANS.setExtentionCap ( poly , l( 3.0) ) +NTRANS.setExtentionWidth( poly , l( 0.0) ) + +PTRANS.setMinimalSize ( l( 2.0) ) +PTRANS.setExtentionCap ( nWell , l( 2.5) ) +PTRANS.setExtentionWidth( nWell , l( 7.5) ) +PTRANS.setExtentionCap ( pImplant, l( 2.0) ) +PTRANS.setExtentionWidth( pImplant, l( 7.0) ) +PTRANS.setExtentionCap ( active , l( 0.0) ) +PTRANS.setExtentionWidth( active , l( 3.0) ) +PTRANS.setExtentionCap ( poly , l( 3.0) ) +PTRANS.setExtentionWidth( poly , l( 0.0) ) + +POLY .setMinimalSize ( l(2.0) ) +POLY .setExtentionCap ( poly , l(1.0) ) +POLY2.setMinimalSize ( l(2.0) ) +POLY2.setExtentionCap ( poly , l(1.0) ) + +# Routing Layers (symbolic). +METAL1 .setMinimalSize ( l( 2.0) ) +METAL1 .setExtentionCap ( metal1 , l( 2.0) ) +METAL1 .setExtentionWidth( metal1 , l( 1.0) ) +METAL1 .setMinimalSpacing( l( 6.0) ) +METAL2 .setMinimalSize ( l( 4.0) ) +METAL2 .setExtentionCap ( metal2 , l( 2.0) ) +METAL2 .setMinimalSpacing( l( 6.0) ) +METAL3 .setMinimalSize ( l( 4.0) ) +METAL3 .setExtentionCap ( metal3 , l( 2.0) ) +METAL3 .setMinimalSpacing( l( 6.0) ) +METAL4 .setMinimalSize ( l( 4.0) ) +METAL4 .setExtentionCap ( metal4 , l( 2.0) ) +METAL4 .setMinimalSpacing( l( 6.0) ) +METAL5 .setMinimalSize ( l( 4.0) ) +METAL5 .setExtentionCap ( metal5 , l( 2.0) ) +METAL5 .setMinimalSpacing( l( 6.0) ) +METAL6 .setMinimalSize ( l(10.0) ) +METAL6 .setExtentionCap ( metal6 , l( 5.0) ) +METAL6 .setMinimalSpacing( l( 6.0) ) +#METAL7 .setMinimalSize ( l( 2.0) ) +#METAL7 .setExtentionCap ( metal7 , l( 1.0) ) +#METAL8 .setMinimalSize ( l( 2.0) ) +#METAL8 .setExtentionCap ( metal8 , l( 1.0) ) +#METAL9 .setMinimalSize ( l( 2.0) ) +#METAL9 .setExtentionCap ( metal9 , l( 1.0) ) +#METAL10.setMinimalSize ( l( 2.0) ) +#METAL10.setExtentionCap ( metal10 , l( 1.0) ) + +# Contacts (i.e. Active <--> Metal) (symbolic). +CONT_BODY_N.setMinimalSize( l( 2.0) ) +CONT_BODY_N.setEnclosure ( nWell , l( 4.0), Layer.EnclosureH|Layer.EnclosureV ) +CONT_BODY_N.setEnclosure ( nImplant, l( 3.5), Layer.EnclosureH|Layer.EnclosureV ) +CONT_BODY_N.setEnclosure ( active , l( 1.5), Layer.EnclosureH|Layer.EnclosureV ) +CONT_BODY_N.setEnclosure ( metal1 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) + +CONT_BODY_P.setMinimalSize( l( 2.0) ) +CONT_BODY_P.setEnclosure ( pWell , l( 4.0), Layer.EnclosureH|Layer.EnclosureV ) +CONT_BODY_P.setEnclosure ( pImplant, l( 3.5), Layer.EnclosureH|Layer.EnclosureV ) +CONT_BODY_P.setEnclosure ( active , l( 1.5), Layer.EnclosureH|Layer.EnclosureV ) +CONT_BODY_P.setEnclosure ( metal1 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) + +CONT_DIF_N.setMinimalSize( l( 2.0) ) +CONT_DIF_N.setEnclosure ( nImplant, l( 4.0), Layer.EnclosureH|Layer.EnclosureV ) +CONT_DIF_N.setEnclosure ( active , l( 2.0), Layer.EnclosureH|Layer.EnclosureV ) +CONT_DIF_N.setEnclosure ( metal1 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) + +CONT_DIF_P.setMinimalSize( l( 2.0) ) +CONT_DIF_P.setEnclosure ( pImplant, l( 4.0), Layer.EnclosureH|Layer.EnclosureV ) +CONT_DIF_P.setEnclosure ( active , l( 2.0), Layer.EnclosureH|Layer.EnclosureV ) +CONT_DIF_P.setEnclosure ( metal1 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) + +CONT_POLY.setMinimalSize( l( 2.0) ) +CONT_POLY.setEnclosure ( poly , l( 2.0), Layer.EnclosureH|Layer.EnclosureV ) +CONT_POLY.setEnclosure ( metal1 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) + +# VIAs (i.e. Metal <--> Metal) (symbolic). +VIA12 .setMinimalSize( l( 2.0) ) +VIA12 .setEnclosure ( metal1 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA12 .setEnclosure ( metal2 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA23 .setMinimalSize( l( 2.0) ) +VIA23 .setEnclosure ( metal2 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA23 .setEnclosure ( metal3 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA34 .setMinimalSize( l( 2.0) ) +VIA34 .setEnclosure ( metal3 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA34 .setEnclosure ( metal4 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA45 .setMinimalSize( l( 2.0) ) +VIA45 .setEnclosure ( metal4 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA45 .setEnclosure ( metal5 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA56 .setMinimalSize( l( 5.0) ) +VIA56 .setEnclosure ( metal5 , l( 1.0), Layer.EnclosureH|Layer.EnclosureV ) +VIA56 .setEnclosure ( metal6 , l( 1.5), Layer.EnclosureH|Layer.EnclosureV ) +#VIA67 .setMinimalSize( l( 1.0) ) +#VIA67 .setEnclosure ( metal6 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV ) +#VIA67 .setEnclosure ( metal7 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV ) +#VIA78 .setMinimalSize( l( 1.0) ) +#VIA78 .setEnclosure ( metal7 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV ) +#VIA78 .setEnclosure ( metal8 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV ) +#VIA89 .setMinimalSize( l( 1.0) ) +#VIA89 .setEnclosure ( metal8 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV ) +#VIA89 .setEnclosure ( metal9 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV ) +#VIA910.setMinimalSize( l( 1.0) ) +#VIA910.setEnclosure ( metal9 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV ) +#VIA910.setEnclosure ( metal10 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV ) + +# Blockages (symbolic). +BLOCKAGE1 .setMinimalSize ( l( 4.0) ) +BLOCKAGE1 .setExtentionCap ( blockage1 , l( 2.0) ) +BLOCKAGE1 .setExtentionWidth( blockage1 , l( 0.5) ) +BLOCKAGE2 .setMinimalSize ( l( 4.0) ) +BLOCKAGE2 .setExtentionCap ( blockage2 , l( 2.0) ) +BLOCKAGE3 .setMinimalSize ( l( 4.0) ) +BLOCKAGE3 .setExtentionCap ( blockage3 , l( 2.0) ) +BLOCKAGE4 .setMinimalSize ( l( 4.0) ) +BLOCKAGE4 .setExtentionCap ( blockage4 , l( 2.0) ) +BLOCKAGE5 .setMinimalSize ( l( 4.0) ) +BLOCKAGE5 .setExtentionCap ( blockage5 , l( 2.0) ) +BLOCKAGE6 .setMinimalSize ( l( 8.0) ) +BLOCKAGE6 .setExtentionCap ( blockage6 , l( 2.5) ) +#BLOCKAGE7 .setMinimalSize ( l( 2.0) ) +#BLOCKAGE7 .setExtentionCap ( blockage7 , l( 1.0) ) +#BLOCKAGE8 .setMinimalSize ( l( 2.0) ) +#BLOCKAGE8 .setExtentionCap ( blockage8 , l( 1.0) ) +#BLOCKAGE9 .setMinimalSize ( l( 2.0) ) +#BLOCKAGE9 .setExtentionCap ( blockage9 , l( 1.0) ) +#BLOCKAGE10.setMinimalSize ( l( 2.0) ) +#BLOCKAGE10.setExtentionCap ( blockage10, l( 1.0) ) + + +# Table guessed from the Cadence configuration files: +# FreePDK45/ncsu_basekit/techfile/FreePDK45.tf +# +# Format of an entry in the table: +# (Symbolic_Name, CIF_Name, GDSII_Number) +#gdsLayersTable = \ +# ( ("pWell" , "CWN" , 2, 0) +# , ("nWell" , "CWP" , 3, 0) +# , ("active" , "CAA" , 1, 0) +# , ("pImplant", "CSP" , 5, 0) +# , ("nImplant", "CSN" , 4, 0) +# , ("poly" , "CPG" , 9, 0) +# , ("cut0" , "CCC" , 10, 0) +# , ("metal1" , "CM1" , 11, 0) +# , ("cut1" , "CV1" , 12, 0) +# , ("metal2" , "CM2" , 13, 0) +# , ("cut2" , "CV2" , 14, 0) +# , ("metal3" , "CM3" , 15, 0) +# , ("cut3" , "CV3" , 16, 0) +# , ("metal4" , "CM4" , 17, 0) +# , ("cut4" , "CV4" , 18, 0) +# , ("metal5" , "CM5" , 19, 0) +# , ("cut5" , "CV5" , 20, 0) +# , ("metal6" , "CM6" , 21, 0) +# , ("cut6" , "CV6" , 22, 0) +# , ("metal7" , "CM7" , 23, 0) +# , ("cut7" , "CV7" , 24, 0) +# , ("metal8" , "CM8" , 25, 0) +# , ("cut8" , "CV8" , 26, 0) +# , ("metal9" , "CM9" , 27, 0) +# , ("cut9" , "CV9" , 28, 0) +# , ("metal10" , "CM10" , 29, 0) +# ) + + +# Table guessed from the GDSII layouts of the cells. +# FreePDK45/osu_soc/lib/source/gds/*.gds +# +# Format of an entry in the table: +# (Symbolic_Name, CIF_Name, GDSII_Number) +gdsLayersTable = \ + ( ("pWell" , "CWN" , 2, 0) + , ("nWell" , "CWP" , 1, 0) + , ("active" , "CAA" , 5, 0) + , ("pImplant", "CSP" , 8, 0) + , ("nImplant", "CSN" , 7, 0) + , ("poly" , "CPG" , 15, 0) + , ("cut0" , "CCC" , 16, 0) + , ("metal1" , "CM1" , 21, 0) + , ("cut1" , "CV1" , 22, 0) + , ("metal2" , "CM2" , 23, 0) + , ("cut2" , "CV2" , 24, 0) + , ("metal3" , "CM3" , 25, 0) + , ("cut3" , "CV3" , 26, 0) + , ("metal4" , "CM4" , 27, 0) + , ("cut4" , "CV4" , 28, 0) + , ("metal5" , "CM5" , 29, 0) + , ("cut5" , "CV5" , 30, 0) + , ("metal6" , "CM6" , 31, 0) + , ("cut6" , "CV6" , 32, 0) + , ("metal7" , "CM7" , 33, 0) + , ("cut7" , "CV7" , 34, 0) + , ("metal8" , "CM8" , 35, 0) + , ("cut8" , "CV8" , 36, 0) + , ("metal9" , "CM9" , 37, 0) + , ("cut9" , "CV9" , 38, 0) + , ("metal10" , "CM10" , 39, 0) + ) + + +common.loadGdsLayers( gdsLayersTable ) diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index 6ae66891..37cb35f4 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -216,6 +216,12 @@ namespace { { _routingGauge = AllianceFramework::get()->getRoutingGauge(); _cellGauge = AllianceFramework::get()->getCellGauge(); + + if (not _routingGauge) + throw Error( "LefParser::LefParser(): No default routing gauge defined in Alliance framework." ); + + if (not _cellGauge) + throw Error( "LefParser::LefParser(): No default cell gauge defined in Alliance framework." ); lefrInit(); lefrSetUnitsCbk ( _unitsCbk ); @@ -357,7 +363,10 @@ namespace { DbU::Unit lefSiteHeight = DbU::fromPhysical( site->sizeY(), DbU::Micro ); if (siteClass == "CORE") { - CellGauge* gauge = parser->getCellGauge(); + CellGauge* gauge = parser->getCellGauge(); + if (not gauge) + throw Error( "LefParser::_siteCbk(): Default gauge is not defined. Aborting." ); + DbU::Unit crlSliceStep = gauge->getSliceStep (); DbU::Unit crlSliceHeight = gauge->getSliceHeight(); @@ -501,6 +510,13 @@ namespace { if (isPad) cerr << " (PAD)"; cerr << endl; + Catalog::State* state = af->getCatalog()->getState( cellName ); + if (not state) state = af->getCatalog()->getState ( cellName, true ); + state->setFlags( Catalog::State::Logical + | Catalog::State::Physical + | Catalog::State::InMemory + | Catalog::State::TerminalNetlist, true ); + cell->setTerminalNetlist( true ); parser->setCell( NULL ); return 0; @@ -836,7 +852,9 @@ namespace { fclose( lefStream ); - if (not parser->getCoreSiteX()) { + if (not parser->getCellGauge()) { + cerr << Warning( "LefParser::parse(): No default Alliance cell gauge, unable to check the Cell gauge." ) << endl; + } else if (not parser->getCoreSiteX()) { cerr << Warning( "LefParser::parse(): No CORE site found in library, unable to check the Cell gauge." ) << endl; } else { if (parser->getCoreSiteY() != parser->getCellGauge()->getSliceHeight()) diff --git a/crlcore/src/pyCRL/PyAllianceFramework.cpp b/crlcore/src/pyCRL/PyAllianceFramework.cpp index b017eac4..b4f6dacb 100644 --- a/crlcore/src/pyCRL/PyAllianceFramework.cpp +++ b/crlcore/src/pyCRL/PyAllianceFramework.cpp @@ -439,6 +439,29 @@ extern "C" { } + static PyObject* PyAllianceFramework_setCellGauge ( PyAllianceFramework* self, PyObject* args ) + { + cdebug_log(30,0) << "PyAllianceFramework_setCellGauge()" << endl; + + HTRY + METHOD_HEAD("AllianceFramework.setCellGauge()") + PyObject* arg0; + __cs.init ("AllianceFramework.setCellGauge"); + if (not PyArg_ParseTuple( args, "O&:AllianceFramework.setCellGauge", Converter, &arg0 )) { + PyErr_SetString( ConstructorError, "Invalid number of parameters for AllianceFramework.setCellGauge()." ); + return NULL; + } + if (__cs.getObjectIds() == ":string") af->setCellGauge( Name(PyString_AsString(arg0)) ); + else { + PyErr_SetString( ConstructorError, "Bad parameter type for AllianceFramework.setCellGauge()." ); + return NULL; + } + HCATCH + + Py_RETURN_NONE; + } + + static PyObject* PyAllianceFramework_matchCellGauge ( PyAllianceFramework* self, PyObject* args ) { cdebug_log(30,0) << "PyAllianceFramework_matchCellGauge()" << endl; @@ -539,6 +562,8 @@ extern "C" { , "Add a new cell gauge." } , { "getCellGauge" , (PyCFunction)PyAllianceFramework_getCellGauge , METH_VARARGS , "Get a cell gauge (without a name, return the default)." } + , { "setCellGauge" , (PyCFunction)PyAllianceFramework_setCellGauge , METH_VARARGS + , "Select the default cell gauge." } , { "matchCellGauge" , (PyCFunction)PyAllianceFramework_matchCellGauge , METH_VARARGS , "Find the first CellGauge comptible with width and height." } , { "addRoutingGauge" , (PyCFunction)PyAllianceFramework_addRoutingGauge , METH_VARARGS diff --git a/cumulus/src/CMakeLists.txt b/cumulus/src/CMakeLists.txt index c34761f6..65f95df7 100644 --- a/cumulus/src/CMakeLists.txt +++ b/cumulus/src/CMakeLists.txt @@ -36,10 +36,14 @@ ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/padscorona.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/chip.py ) + set ( pyTools ${CMAKE_CURRENT_SOURCE_DIR}/tools/blif2vst.py + ${CMAKE_CURRENT_SOURCE_DIR}/tools/yosys.py + ) - install ( FILES ${pySources} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus ) - install ( FILES ${pyPlugins} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins ) - #install ( FILES ${pyPluginBlock} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/block ) - install ( FILES ${pyPluginCTS} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/cts ) - install ( FILES ${pyPluginC2C} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/core2chip ) - install ( FILES ${pyPluginChip} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/chip ) + install ( FILES ${pySources} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus ) + install ( FILES ${pyPlugins} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins ) + #install ( FILES ${pyPluginBlock} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/block ) + install ( FILES ${pyPluginCTS} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/cts ) + install ( FILES ${pyPluginC2C} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/core2chip ) + install ( FILES ${pyPluginChip} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/chip ) + #install ( PROGRAMS ${pyTools} DESTINATION bin ) diff --git a/cumulus/src/tools/blif2vst.py b/cumulus/src/tools/blif2vst.py new file mode 100755 index 00000000..737b4aef --- /dev/null +++ b/cumulus/src/tools/blif2vst.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +try: + import sys + import traceback + import os.path + import optparse + import helpers + from helpers import showPythonTrace + from helpers.io import ErrorMessage + from helpers.io import catch + helpers.loadUserSettings() + import Cfg + import Hurricane + from Hurricane import DbU + from Hurricane import UpdateSession + from Hurricane import Breakpoint + from Hurricane import Transformation + from Hurricane import Instance + import Viewer + import CRL + import plugins.rsave +except Exception, e: + catch( e ) + sys.exit(2) + + +framework = CRL.AllianceFramework.get() + + +def renameNMigenUniquify ( topCell ): + for occurrence in topCell.getTerminalNetlistInstanceOccurrences(): + masterCell = occurrence.getEntity().getMasterCell() + origName = masterCell.getName() + replName = origName.replace( '$$', '_unm' ) + if origName != replName: + print ' - "%s" => "%s"' % (origName,replName) + masterCell.setName( replName ) + + for occurrence in topCell.getNonTerminalNetlistInstanceOccurrences(): + masterCell = occurrence.getEntity().getMasterCell() + origName = masterCell.getName() + replName = origName.replace( '$$', '_unm' ) + if origName != replName: + print ' - "%s" => "%s"' % (origName,replName) + masterCell.setName( replName ) + return + + +if __name__ == '__main__': + + parser = optparse.OptionParser() + parser.add_option( '-c', '--cell' , type='string', dest='cellName' , help='The name of the BLIF to convert, without extension.') + parser.add_option( '-v', '--verbose' , action='store_true', dest='verbose' , help='First level of verbosity.') + parser.add_option( '-V', '--very-verbose' , action='store_true', dest='veryVerbose' , help='Second level of verbosity.') + parser.add_option( '--vst-use-concat' , action='store_true', dest='vstUseConcat' , help='The VST driver will use "&" (concat) in PORT MAP.') + (options, args) = parser.parse_args() + + views = CRL.Catalog.State.Logical + if options.verbose: + Cfg.getParamBool('misc.verboseLevel1').setBool(True) + if options.veryVerbose: + Cfg.getParamBool('misc.verboseLevel1').setBool(True) + Cfg.getParamBool('misc.verboseLevel2').setBool(True) + if options.vstUseConcat: views |= CRL.Catalog.State.VstUseConcat + + cell = CRL.Blif.load( options.cellName ) + if cell.getName() == 'top': + print ' o Renaming RTLIL anonymous top cell "top" into "%s".' % options.cellName + cell.setName( options.cellName ) + renameNMigenUniquify( cell ) + + kw = {} + kw['views'] = views + kw['cell' ] = cell + + plugins.rsave.scriptMain( **kw ) + + sys.exit( 0 ) diff --git a/cumulus/src/tools/yosys.py b/cumulus/src/tools/yosys.py new file mode 100755 index 00000000..57f23b2a --- /dev/null +++ b/cumulus/src/tools/yosys.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python + +import sys +import os +import os.path +import subprocess +import optparse +from helpers.io import ErrorMessage +from helpers.io import catch + + +class Yosys ( object ): + + ReadRTLIL = 0x0001 + ReadVerilog = 0x0002 + Flatten = 0x0004 + KeepTcl = 0x0008 + ReadMask = ReadRTLIL | ReadVerilog + + def __init__ ( self ): + self.flags = Yosys.ReadRTLIL + self.libertyFile = None + return + + def setFlags ( self, mask, value ): + if value: self.flags |= mask + else: self.flags &= ~mask + return + + def setFlatten ( self, value ): self.setFlags( Yosys.Flatten, True ) + def setKeepTcl ( self, value ): self.setFlags( Yosys.KeepTcl, True ) + + def setLiberty ( self, libertyFile ): + if not os.path.isfile(libertyFile): + raise ErrorMessage( 1, [ 'Yosys.setLiberty(): Can\'t find liberty file.' + , '"%s"' % libertyFile ] ) + + self.libertyFile = libertyFile + return + + def setInputRTLIL ( self ): + self.setFlags( Yosys.ReadMask , False ) + self.setFlags( Yosys.ReadRTLIL, True ) + return + + def setInputVerilog ( self ): + self.setFlags( Yosys.ReadMask , False ) + self.setFlags( Yosys.ReadVerilog, True ) + return + + def run ( self, designName, top='top' ): + if self.flags & Yosys.ReadRTLIL: + if not os.path.isfile(designName+'.il'): + raise ErrorMessage( 1, 'Yosys.run(): Can\'t find RTLIL design file "%s.il".' % designName ) + tclScript = 'yosys read_ilang %(designName)s.il\n' + else: + if not os.path.isfile(designName+".v"): + raise ErrorMessage( 1, 'Yosys.run(): Can\'t find Verilog design file "%s.v".' % designName ) + tclScript = 'yosys read_verilog %(designName)s.v\n' + + tclScript += 'yosys hierarchy -check -top %(designTop)s\n' \ + 'yosys synth -top %(designTop)s\n' + + if self.flags & Yosys.Flatten: + tclScript += 'yosys flatten %(designTop)s\n' \ + 'yosys hierarchy -top %(designTop)s\n' + + tclScript += 'yosys dfflibmap -liberty %(libertyFile)s\n' \ + 'yosys abc -liberty %(libertyFile)s\n' \ + 'yosys clean\n' \ + 'yosys write_blif %(designName)s.blif\n' + + tclFile = designName + '.tcl' + tclFd = open( tclFile, 'w' ) + tclFd.write( tclScript % { 'designName' : designName + , 'designTop' : top + , 'libertyFile': self.libertyFile + } ) + tclFd.close() + + status = subprocess.call( [ 'yosys', '-c', tclFile ] ) + + if not (self.flags & Yosys.KeepTcl): os.unlink( tclFile ) + return status + + +if __name__ == '__main__': + + parser = optparse.OptionParser() + parser.add_option ( '-d', '--design' , action='store' , type='string', dest='design' , help='The name of the design file, without extension.' ) + parser.add_option ( '-t', '--top' , action='store' , type='string', dest='top' + , default='top' , help='The hierarchy top level name model.' ) + parser.add_option ( '-f', '--flatten' , action='store_true', dest='flatten' , help='Flatten the design hierarchy.' ) + parser.add_option ( '-k', '--keep-tcl' , action='store_true', dest='keepTcl' , help='Keep the Yosys TCL command script.' ) + parser.add_option ( '-i', '--input-lang', action='store' , type='string', dest='inputLang', help='Set the input description language (RTLIL or Verilog).' ) + parser.add_option ( '-l', '--liberty' , action='store' , type='string', dest='liberty' , help='Set the path to the liberty file (.lib).' ) + (options, args) = parser.parse_args() + + try: + yosys = Yosys() + if options.inputLang == 'Verilog': yosys.setInputVerilog() + if options.inputLang == 'RTLIL' : yosys.setInputRTLIL() + if options.flatten: yosys.setFlatten( True ) + if options.keepTcl: yosys.setKeepTcl( True ) + if options.liberty: yosys.setLiberty( options.liberty ) + + rcode = yosys.run( options.design, top=options.top ) + + except Exception, e: + catch( e ) + sys.exit(2) + + sys.exit( rcode ) diff --git a/etesian/src/Configuration.cpp b/etesian/src/Configuration.cpp index 06b72e3c..2c57d993 100644 --- a/etesian/src/Configuration.cpp +++ b/etesian/src/Configuration.cpp @@ -66,7 +66,8 @@ namespace Etesian { if (cg == NULL) { cg = AllianceFramework::get()->getCellGauge( gaugeName ); if (cg == NULL) - throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." ); + throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge \"%s\"." + , gaugeName.c_str() ); } if (rg == NULL) { diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index 36e2a549..1996ef07 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -809,7 +809,7 @@ namespace { PowerRailsPlanes::PowerRailsPlanes ( KatanaEngine* katana ) - : _katana (katana) + : _katana (katana) , _globalNets (katana) , _planes () , _activePlane (NULL) @@ -820,23 +820,20 @@ namespace { Technology* technology = DataBase::getDB()->getTechnology(); RoutingGauge* rg = _katana->getConfiguration()->getRoutingGauge(); - for( Layer* layer : technology->getLayers() ) { - RegularLayer* regular = dynamic_cast(layer); - if ( not regular - or (regular->getBasicLayer()->getMaterial() != BasicLayer::Material::metal) ) continue; - - RoutingLayerGauge* lg = rg->getLayerGauge(regular); - if ( not lg ) continue; - + for ( RoutingLayerGauge* lg : rg->getLayerGauges() ) { cdebug_log(159,0) << "Gauge: [" << lg->getDepth() << "] " << lg << endl; + const BasicLayer* basicLayer = dynamic_cast( lg->getLayer() ); + if (not basicLayer) + basicLayer = dynamic_cast( lg->getLayer() )->getBasicLayer(); + RoutingPlane* rp = _katana->getRoutingPlaneByIndex(lg->getDepth()); cdebug_log(159,0) << "Plane:" << rp << endl; - _planes.insert( make_pair(regular->getBasicLayer(),new Plane(regular,rp)) ); + _planes.insert( make_pair(basicLayer,new Plane(lg->getLayer(),rp)) ); //if (lg->getType() == Constant::PinOnly) continue; - const BasicLayer* blockageLayer = regular->getBasicLayer()->getBlockageLayer(); + const BasicLayer* blockageLayer = dynamic_cast( lg->getBlockageLayer() ); if (not blockageLayer) continue; _planes.insert( make_pair(blockageLayer,new Plane(blockageLayer,rp)) ); diff --git a/unicorn/src/cgt.py b/unicorn/src/cgt.py index 0c30921d..00421797 100755 --- a/unicorn/src/cgt.py +++ b/unicorn/src/cgt.py @@ -220,7 +220,7 @@ if __name__ == '__main__': #katana.printConfiguration () katana.digitalInit () #katana.runNegociatePreRouted() - katana.runGlobalRouter () + katana.runGlobalRouter ( Katana.Flags.NoFlags ) katana.loadGlobalRouting ( Anabatic.EngineLoadGrByNet ) katana.layerAssign ( Anabatic.EngineNoNetLayerAssign ) katana.runNegociate ( Katana.Flags.NoFlags )