From bbcf14eb5a7926b4befbcd29197dcf02b60a548f Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 29 Mar 2019 11:07:55 +0100 Subject: [PATCH] First step in supporting ISPD18 detailed routing benchmarks. * Change: In CRL::DefImport, added callback to read the DEF UNITS statement and perform a correct length conversion. Previously set to read pseudo lambdas in hundredth of microns. Added DefParser::getLefCell() to lookup master cells in the LEF libraries before looking in the Alliance ones (rooted under "LEF" library). * Change: In CRL::LefParser::_pinPostProcess(), when no segment suitable for terminal connexion is found, add all of them. This is a quick hack and an a correct policy that match all techno must be implemeneted. * New: In CRL::pyCRL, add a Python wrapper for DefImport. * New: In CRL/etc/45/ispd18/ added configuration files for the "real" technology used by the ISPD18 45nm design benchmarks. --- crlcore/etc/45/ispd18/alliance.conf | 39 +++++++ crlcore/etc/45/ispd18/analog.conf | 10 ++ crlcore/etc/45/ispd18/display.conf | 11 ++ crlcore/etc/45/ispd18/etesian.conf | 13 +++ crlcore/etc/45/ispd18/hMetis.conf | 5 + crlcore/etc/45/ispd18/kite.conf | 68 +++++++++++ crlcore/etc/45/ispd18/mauka.conf | 5 + crlcore/etc/45/ispd18/misc.conf | 9 ++ crlcore/etc/45/ispd18/nimbus.conf | 5 + crlcore/etc/45/ispd18/patterns.conf | 5 + crlcore/etc/45/ispd18/plugins.conf | 27 +++++ crlcore/etc/45/ispd18/stratus1.conf | 13 +++ crlcore/etc/45/ispd18/technology.conf | 148 ++++++++++++++++++++++++ crlcore/src/ccore/crlcore/DefImport.h | 5 +- crlcore/src/ccore/lefdef/DefImport.cpp | 70 +++++++++-- crlcore/src/ccore/lefdef/LefImport.cpp | 3 + crlcore/src/cyclop/CMakeLists.txt | 2 + crlcore/src/pyCRL/CMakeLists.txt | 2 + crlcore/src/pyCRL/PyCRL.cpp | 5 + crlcore/src/pyCRL/PyDefImport.cpp | 121 +++++++++++++++++++ crlcore/src/pyCRL/crlcore/PyDefImport.h | 55 +++++++++ 21 files changed, 609 insertions(+), 12 deletions(-) create mode 100644 crlcore/etc/45/ispd18/alliance.conf create mode 100644 crlcore/etc/45/ispd18/analog.conf create mode 100644 crlcore/etc/45/ispd18/display.conf create mode 100644 crlcore/etc/45/ispd18/etesian.conf create mode 100644 crlcore/etc/45/ispd18/hMetis.conf create mode 100644 crlcore/etc/45/ispd18/kite.conf create mode 100644 crlcore/etc/45/ispd18/mauka.conf create mode 100644 crlcore/etc/45/ispd18/misc.conf create mode 100644 crlcore/etc/45/ispd18/nimbus.conf create mode 100644 crlcore/etc/45/ispd18/patterns.conf create mode 100644 crlcore/etc/45/ispd18/plugins.conf create mode 100644 crlcore/etc/45/ispd18/stratus1.conf create mode 100644 crlcore/etc/45/ispd18/technology.conf create mode 100644 crlcore/src/pyCRL/PyDefImport.cpp create mode 100644 crlcore/src/pyCRL/crlcore/PyDefImport.h diff --git a/crlcore/etc/45/ispd18/alliance.conf b/crlcore/etc/45/ispd18/alliance.conf new file mode 100644 index 00000000..c15196ea --- /dev/null +++ b/crlcore/etc/45/ispd18/alliance.conf @@ -0,0 +1,39 @@ +# -*- Mode:Python; explicit-buffer-name: "alliance.conf" -*- + +import os +from helpers.Alliance import AddMode +from helpers.Alliance import Gauge + + +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/' + + +allianceConfig = \ + ( ( 'CATALOG' , 'CATAL') + , ( 'WORKING_LIBRARY' , '.') + , ( 'SYSTEM_LIBRARY' , ( (cellsTop+'/nsxlib' , Environment.Append) + , (cellsTop+'/mpxlib' , Environment.Append)) ) + , ( 'SCALE_X' , 100) + , ( 'IN_LO' , 'vst') + , ( 'IN_PH' , 'ap') + , ( 'OUT_LO' , 'vst') + , ( 'OUT_PH' , 'ap') + , ( 'POWER' , 'vdd') + , ( 'GROUND' , 'vss') + , ( 'CLOCK' , '^ck.*') + , ( 'BLOCKAGE' , '^blockage[Nn]et*') + , ( 'PAD' , '.*_mpx$') + # The following are only read by the Alliance tool wrappers. + , ( 'ALLIANCE_TOP' , allianceTop) + , ( 'MBK_TARGET_LIB' , cellsTop+'/msxlib') + , ( 'RDS_TECHNO_NAME' , allianceTop+'/etc/scn6m_deep_09.rds') + , ( 'GRAAL_TECHNO_NAME' , allianceTop+'/etc/graal.rds') + ) diff --git a/crlcore/etc/45/ispd18/analog.conf b/crlcore/etc/45/ispd18/analog.conf new file mode 100644 index 00000000..e8bc341d --- /dev/null +++ b/crlcore/etc/45/ispd18/analog.conf @@ -0,0 +1,10 @@ +# -*- Mode:Python; explicit-buffer-name: "analog.conf" -*- + +import helpers + + +parametersTable = \ + ( ('analog.techno' , TypeString, 'Analog_technology_is_disabled', + { 'flags':Cfg.Parameter.Flags.NeedRestart|Cfg.Parameter.Flags.MustExist } ) + , ('analog.devices', TypeString, helpers.technoDir+'/devices.conf' ) + ) diff --git a/crlcore/etc/45/ispd18/display.conf b/crlcore/etc/45/ispd18/display.conf new file mode 100644 index 00000000..c17aea70 --- /dev/null +++ b/crlcore/etc/45/ispd18/display.conf @@ -0,0 +1,11 @@ +# -*- Mode:Python; explicit-buffer-name: "display.conf" -*- + +import helpers + +# Provides standard settings for: +# - +# - + +scale = 0.5 + +execfile( helpers.sysConfDir+'/common/display.conf' ) diff --git a/crlcore/etc/45/ispd18/etesian.conf b/crlcore/etc/45/ispd18/etesian.conf new file mode 100644 index 00000000..333ec4c5 --- /dev/null +++ b/crlcore/etc/45/ispd18/etesian.conf @@ -0,0 +1,13 @@ +# -*- Mode:Python; explicit-buffer-name: "etesian.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/etesian.conf' ) + +parametersTable = helpers.overload \ + ( parametersTable + , ( ('etesian.feedNames', TypeString, 'FILL' ) + , ('etesian.cell.zero', TypeString, 'missing_tie_low' ) + , ('etesian.cell.one' , TypeString, 'missing_tie_high') + ) + ) diff --git a/crlcore/etc/45/ispd18/hMetis.conf b/crlcore/etc/45/ispd18/hMetis.conf new file mode 100644 index 00000000..1336de6c --- /dev/null +++ b/crlcore/etc/45/ispd18/hMetis.conf @@ -0,0 +1,5 @@ +# -*- Mode:Python; explicit-buffer-name: "hMetis.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/hMetis.conf' ) diff --git a/crlcore/etc/45/ispd18/kite.conf b/crlcore/etc/45/ispd18/kite.conf new file mode 100644 index 00000000..7bddb4f7 --- /dev/null +++ b/crlcore/etc/45/ispd18/kite.conf @@ -0,0 +1,68 @@ +# -*- Mode:Python; explicit-buffer-name: "kite.conf" -*- + +import helpers +from helpers import l, u, n + +# Contains the layout (shared by all technologies). +execfile( helpers.sysConfDir+'/common/kite.conf' ) + + +parametersTable = \ + ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.065 ) + , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. + , ("katabatic.saturateRatio" ,TypePercentage,90 ) + , ("katabatic.saturateRp" ,TypeInt ,10 ) + , ('katabatic.topRoutingLayer' ,TypeString , 'metal9') + , ('anabatic.routingGauge' ,TypeString , 'ispd18') + , ('crlcore.groundName' ,TypeString , 'VSS' ) + , ('crlcore.powerName' ,TypeString , 'VDD' ) + # Kite parameters. + , ("kite.hTracksReservedLocal" ,TypeInt ,4 , { 'min':0, 'max':18 } ) + , ("kite.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':18 } ) + , ("kite.eventsLimit" ,TypeInt ,4000002 ) + , ("kite.ripupCost" ,TypeInt ,3 , { 'min':0 } ) + , ("kite.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } ) + , ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } ) + , ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) + , ("kite.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) + # Anabatic parameters are temporarily hosted here. + , ("anabatic.edgeLength" ,TypeInt ,24 ) + , ("anabatic.edgeWidth" ,TypeInt ,4 ) + , ("anabatic.edgeCostH" ,TypeDouble ,9.0 ) + , ("anabatic.edgeCostK" ,TypeDouble ,-10.0 ) + , ("anabatic.edgeHScaling" ,TypeDouble ,1.0 ) + , ("anabatic.globalIterations" ,TypeInt ,10 , { 'min':1, 'max':100 } ) + , ("anabatic.gcell.displayMode" ,TypeEnumerate ,1 + , { 'values':( ("Boundary" , 1) + , ("Density" , 2) ) } + ) + ) + + +# Format of routingGaugesTable (dictionary): +# A list of entry of the form: +# ( METAL_NAME, (Direction, Type, depth, density, offset, pitch, wire_width, via_width, obs_dw) ) + +routingGaugesTable = {} + +routingGaugesTable['ispd18'] = \ + ( ( 'symbolic', False ) + , ( 'metal1' , ( Gauge.Horizontal, Gauge.PinOnly, 0, 0.0, u(0.095), u(0.190), u(0.060), u(0.070), u(7) ) ) + , ( 'metal2' , ( Gauge.Vertical , Gauge.Default, 1, 0.0, u(0.100), u(0.200), u(0.070), u(0.070), u(8) ) ) + , ( 'metal3' , ( Gauge.Horizontal, Gauge.Default, 2, 0.0, u(0.100), u(0.200), u(0.070), u(0.070), u(8) ) ) + , ( 'metal4' , ( Gauge.Vertical , Gauge.Default, 3, 0.0, u(0.100), u(0.200), u(0.070), u(0.070), u(8) ) ) + , ( 'metal5' , ( Gauge.Horizontal, Gauge.Default, 4, 0.0, u(0.100), u(0.200), u(0.070), u(0.070), u(8) ) ) + , ( 'metal6' , ( Gauge.Vertical , Gauge.Default, 5, 0.0, u(0.100), u(0.200), u(0.070), u(0.360), u(8) ) ) + , ( 'metal7' , ( Gauge.Horizontal, Gauge.Default, 6, 0.0, u(0.100), u(0.200), u(0.070), u(0.360), u(8) ) ) + , ( 'metal8' , ( Gauge.Vertical , Gauge.Default, 7, 0.0, u(0.100), u(0.200), u(0.070), u(0.360), u(8) ) ) + , ( 'metal9' , ( Gauge.Horizontal, Gauge.Default, 8, 0.0, u(0.475), u(0.330), u(0.070), u(0.360), u(8) ) ) + ) + + +# Format of cellGaugesTable (dictionary): +# A list of entry of the form: +# ( METAL_PIN, xy_common_pitch, slice_height, slice_step ) + +cellGaugesTable = {} +cellGaugesTable['ispd18'] = ('metal2', u(0.2), u(1.71), u(0.2)) + diff --git a/crlcore/etc/45/ispd18/mauka.conf b/crlcore/etc/45/ispd18/mauka.conf new file mode 100644 index 00000000..9e3b89a4 --- /dev/null +++ b/crlcore/etc/45/ispd18/mauka.conf @@ -0,0 +1,5 @@ +# -*- Mode:Python; explicit-buffer-name: "mauka.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/mauka.conf' ) diff --git a/crlcore/etc/45/ispd18/misc.conf b/crlcore/etc/45/ispd18/misc.conf new file mode 100644 index 00000000..23e41634 --- /dev/null +++ b/crlcore/etc/45/ispd18/misc.conf @@ -0,0 +1,9 @@ +# -*- Mode:Python; explicit-buffer-name: "misc.conf" -*- + +import helpers + +# Provides standard settings for: +# # - +# # - +# +execfile( helpers.sysConfDir+'/common/misc.conf' ) diff --git a/crlcore/etc/45/ispd18/nimbus.conf b/crlcore/etc/45/ispd18/nimbus.conf new file mode 100644 index 00000000..df8b61ff --- /dev/null +++ b/crlcore/etc/45/ispd18/nimbus.conf @@ -0,0 +1,5 @@ +# -*- Mode:Python; explicit-buffer-name: "nimbus.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/nimbus.conf' ) diff --git a/crlcore/etc/45/ispd18/patterns.conf b/crlcore/etc/45/ispd18/patterns.conf new file mode 100644 index 00000000..9242ac3d --- /dev/null +++ b/crlcore/etc/45/ispd18/patterns.conf @@ -0,0 +1,5 @@ +# -*- Mode:Python; explicit-buffer-name: "patterns.conf" -*- + +import helpers + +execfile( helpers.sysConfDir+'/common/patterns.conf' ) diff --git a/crlcore/etc/45/ispd18/plugins.conf b/crlcore/etc/45/ispd18/plugins.conf new file mode 100644 index 00000000..6af21f6b --- /dev/null +++ b/crlcore/etc/45/ispd18/plugins.conf @@ -0,0 +1,27 @@ +# -*- Mode:Python; explicit-buffer-name: "plugins.conf" -*- + +import helpers + +# Contains the layout (shared by all technologies). +#execfile( helpers.sysConfDir+'/common/plugins.conf' ) + + +# WARNING: Those values have not been adjusted yet for this technologies. +# Must be done. +# +# Parameters for chip plugin. +parametersTable = \ + ( ("chip.block.rails.count" , TypeInt , 5 ) + , ("chip.block.rails.hWidth" , TypeInt , 24 ) + , ("chip.block.rails.vWidth" , TypeInt , 24 ) + , ("chip.block.rails.hSpacing" , TypeInt , 12 ) + , ("chip.block.rails.vSpacing" , TypeInt , 12 ) + , ('chip.pad.pck' , TypeString, 'pck_mpx') + , ('chip.pad.pvddick' , TypeString, 'pvddick_mpx') + , ('chip.pad.pvssick' , TypeString, 'pvssick_mpx') + , ('chip.pad.pvddeck' , TypeString, 'pvddeck_mpx') + , ('chip.pad.pvsseck' , TypeString, 'pvsseck_mpx') + , ('clockTree.minimumSide' , TypeInt , 1000) + , ('clockTree.buffer' , TypeString, 'buf_x2') + , ('clockTree.placerEngine' , TypeString, 'Etesian') + ) diff --git a/crlcore/etc/45/ispd18/stratus1.conf b/crlcore/etc/45/ispd18/stratus1.conf new file mode 100644 index 00000000..8afa3b66 --- /dev/null +++ b/crlcore/etc/45/ispd18/stratus1.conf @@ -0,0 +1,13 @@ +# -*- Mode:Python; explicit-buffer-name: "stratus1.conf" -*- + +import helpers + + +# Status1 parameters. +parametersTable = \ + ( ("stratus1.format" , TypeString, "vst") + , ("stratus1.simulator" , TypeString, "asimut") + ,) + + +execfile( helpers.sysConfDir+'/common/stratus1.conf' ) diff --git a/crlcore/etc/45/ispd18/technology.conf b/crlcore/etc/45/ispd18/technology.conf new file mode 100644 index 00000000..6bc44f66 --- /dev/null +++ b/crlcore/etc/45/ispd18/technology.conf @@ -0,0 +1,148 @@ +# -*- Mode:Python; explicit-buffer-name: "technology.conf" -*- +# +# FreePDK 45 nanometers. +# +# Provides standard settings for: +# - +# - +# - +# - + +from Hurricane import DbU +from helpers import sysConfDir +from helpers import l, u, n +from helpers.Technology import initTechno + +initTechno( { 'name' : 'ispd18' + , 'precision' : 2 + , 'gridValue' : 0.0005 + , 'gridUnit' : DbU.UnitPowerMicro + , 'gridsPerLambda' : 10 + , 'symbolicGridStep' : 1.0 + , 'polygonStep' : 1.0 + } ) + +# Contains the layers +execfile( helpers.sysConfDir+'/common/technology.conf' ) + + +# Format of : +# Each entry is a pair of (string, value). +# * string: a synthetic way to designate the real or symbolic layer on +# which it applies, an optional sub layer (BasicLayer) in case +# where there is more than one, and the dimension name. +# * value : the rule (dimension) value. +# Values/dimensions must be given using one of the following conversion +# function: +# * l(value) : value expressed in lambda (symbolic). +# * u(value) : value is expressed in microns. +# * n(value) : value is expressed in nanometers. + +layersExtensionsTable = symbolicLayersExtensionsTable + \ + [ ('metal1.minimalSpacing' , u( 0.1 )) + , ('metal2.minimalSpacing' , u( 0.15 )) + , ('metal3.minimalSpacing' , u( 0.15 )) + , ('metal4.minimalSpacing' , u( 0.15 )) + , ('metal5.minimalSpacing' , u( 0.15 )) + , ('metal6.minimalSpacing' , u( 0.15 )) + , ('metal7.minimalSpacing' , u( 0.15 )) + , ('metal8.minimalSpacing' , u( 0.15 )) + , ('metal9.minimalSpacing' , u( 0.15 )) + , ('metal10.minimalSpacing' , u( 0.15 )) + + # VIAs (i.e. Metal <--> Metal) (real). + , ('via12.minimum.side' , u(0.070)) + , ('via12.metal1.enclosure' , (u(0.030 ), u(0.0 )) ) + , ('via12.metal2.enclosure' , (u(0.0 ), u(0.030)) ) + , ('via23.minimum.side' , u(0.070 )) + , ('via23.metal2.enclosure' , (u(0.0 ), u(0.030)) ) + , ('via23.metal3.enclosure' , (u(0.030 ), u(0.0 )) ) + , ('via34.minimum.side' , u(0.070)) + , ('via34.metal3.enclosure' , (u(0.030 ), u(0.0 )) ) + , ('via34.metal4.enclosure' , (u(0.0 ), u(0.030)) ) + , ('via45.minimum.side' , u(0.070 )) + , ('via45.metal4.enclosure' , (u(0.0 ), u(0.030)) ) + , ('via45.metal5.enclosure' , (u(0.030 ), u(0.0 )) ) + , ('via56.minimum.side' , u(0.070)) + , ('via56.metal5.enclosure' , (u(0.030 ), u(0.0 )) ) + , ('via56.metal6.enclosure' , (u(0.0 ), u(0.030)) ) + , ('via67.minimum.side' , u(0.360)) + , ('via67.metal6.enclosure' , (u(0.02 ), u(0.08 )) ) + , ('via67.metal7.enclosure' , (u(0.08 ), u(0.02 )) ) + , ('via78.minimum.side' , u(0.360)) + , ('via78.metal7.enclosure' , (u(0.08 ), u(0.02 )) ) + , ('via78.metal8.enclosure' , (u(0.02 ), u(0.08 )) ) + , ('via89.minimum.side' , u(0.360)) + , ('via89.metal8.enclosure' , (u(0.02 ), u(0.08 )) ) + , ('via89.metal9.enclosure' , (u(0.08 ), u(0.02 )) ) + ] + + +# 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) + ) diff --git a/crlcore/src/ccore/crlcore/DefImport.h b/crlcore/src/ccore/crlcore/DefImport.h index b369e245..6e23441f 100644 --- a/crlcore/src/ccore/crlcore/DefImport.h +++ b/crlcore/src/ccore/crlcore/DefImport.h @@ -8,7 +8,7 @@ // | C a d e n c e D E F I m p o r t e r | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./crlcore/DefImport.h" | // +-----------------------------------------------------------------+ @@ -31,7 +31,8 @@ namespace CRL { public: enum Flags { FitAbOnCells=0x1 }; public: - static Hurricane::Cell* load ( std::string design, unsigned int flags ); + static void reset (); + static Hurricane::Cell* load ( std::string design, unsigned int flags ); }; diff --git a/crlcore/src/ccore/lefdef/DefImport.cpp b/crlcore/src/ccore/lefdef/DefImport.cpp index 1204a082..cdae7413 100644 --- a/crlcore/src/ccore/lefdef/DefImport.cpp +++ b/crlcore/src/ccore/lefdef/DefImport.cpp @@ -65,6 +65,8 @@ namespace { class DefParser { public: static AllianceFramework* getFramework (); + static Cell* getLefCell ( string name ); + static void setUnits ( double ); static DbU::Unit fromDefUnits ( int ); static Transformation::Orientation fromDefOrientation ( int orient ); @@ -98,6 +100,7 @@ namespace { void toHurricaneName ( string& ); inline void mergeToFitOnCellsDieArea ( const Box& ); private: + static int _unitsCbk ( defrCallbackType_e, double , defiUserData ); static int _busBitCbk ( defrCallbackType_e, const char* , defiUserData ); static int _designEndCbk ( defrCallbackType_e, void* , defiUserData ); static int _dieAreaCbk ( defrCallbackType_e, defiBox* , defiUserData ); @@ -111,6 +114,7 @@ namespace { private: static double _defUnits; static AllianceFramework* _framework; + static Library* _lefRootLibrary; string _file; unsigned int _flags; AllianceLibrary* _library; @@ -125,8 +129,9 @@ namespace { }; - double DefParser::_defUnits = 0.01; - AllianceFramework* DefParser::_framework = NULL; + double DefParser::_defUnits = 0.01; + AllianceFramework* DefParser::_framework = NULL; + Library* DefParser::_lefRootLibrary = NULL; DefParser::DefParser ( string& file, AllianceLibrary* library, unsigned int flags ) @@ -143,6 +148,7 @@ namespace { , _errors () { defrInit (); + defrSetUnitsCbk ( _unitsCbk ); defrSetBusBitCbk ( _busBitCbk ); defrSetDesignEndCbk ( _designEndCbk ); defrSetDieAreaCbk ( _dieAreaCbk ); @@ -162,7 +168,8 @@ namespace { AllianceFramework* DefParser::getFramework () { return _framework; } - inline DbU::Unit DefParser::fromDefUnits ( int u ) { return DbU::lambda(_defUnits*(double)u); } + inline void DefParser::setUnits ( double units ) { _defUnits = 1/units; } + inline DbU::Unit DefParser::fromDefUnits ( int u ) { return DbU::fromPhysical(_defUnits*(double)u,DbU::UnitPower::Micro); } inline bool DefParser::hasErrors () { return not _errors.empty(); } inline unsigned int DefParser::getFlags () const { return _flags; } inline string DefParser::getBusBits () const { return _busBits; } @@ -182,6 +189,32 @@ namespace { inline void DefParser::mergeToFitOnCellsDieArea ( const Box& box ) { _fitOnCellsDieArea.merge(box); } + Cell* DefParser::getLefCell ( string name ) + { + if (not _lefRootLibrary) { + DataBase* db = DataBase::getDB(); + Library* rootLibrary = db->getRootLibrary(); + + if (rootLibrary) { + _lefRootLibrary = rootLibrary->getLibrary( "LEF" ); + } + } + + Cell* masterCell = NULL; + if (_lefRootLibrary) { + for ( Library* library : _lefRootLibrary->getLibraries() ) { + masterCell = library->getCell( name ); + if (masterCell) break; + } + } + + if (not masterCell) + masterCell = DefParser::getFramework()->getCell ( name, Catalog::State::Views ); + + return masterCell; + } + + Transformation::Orientation DefParser::fromDefOrientation ( int orient ) { // Note : the codes between DEF & Hurricane matches. @@ -273,6 +306,14 @@ namespace { } + int DefParser::_unitsCbk ( defrCallbackType_e c, double defUnits, lefiUserData ud ) + { + DefParser* parser = (DefParser*)ud; + parser->setUnits( defUnits ); + return 0; + } + + int DefParser::_busBitCbk ( defrCallbackType_e c, const char* busbits, lefiUserData ud ) { DefParser* parser = (DefParser*)ud; @@ -343,8 +384,8 @@ namespace { string componentName = component->name(); string componentId = component->id(); + Cell* masterCell = getLefCell( componentName ); - Cell* masterCell = DefParser::getFramework()->getCell ( componentName, Catalog::State::Views ); if ( masterCell == NULL ) { ostringstream message; message << "Unknown model/Cell (LEF MACRO) " << componentName << " in <%s>."; @@ -375,6 +416,9 @@ namespace { parser->mergeToFitOnCellsDieArea ( instance->getAbutmentBox() ); } + //cerr << "Create " << componentId << " of " << masterCell + // << " ab:" << masterCell->getAbutmentBox() << " @" << placement << endl; + return 0; } @@ -412,13 +456,13 @@ namespace { name.erase ( 0, name.size()-75 ); name.insert( 0, 3, '.' ); } - name.insert( 0, "<" ); - name.insert( name.size(), ">" ); + name.insert( 0, "\"" ); + name.insert( name.size(), "\"" ); if (name.size() < 80) name.insert( name.size(), 80-name.size(), ' ' ); if (tty::enabled()) { - cmess2 << " " - << tty::bold << setw(7) << setfill('0') << ++netCount << ":" << setfill(' ') + cmess2 << " " << setfill(' ') << tty::reset << setw(80) << name << tty::cr; cmess2.flush (); } @@ -573,7 +617,7 @@ namespace { } -} // End of anonymous namespace. +} // Anonymous namespace. #endif // HAVE_LEFDEF @@ -606,4 +650,10 @@ namespace CRL { } -} // End of CRL namespace. + void DefImport::reset () + { + // DefParser::reset(); + } + + +} // CRL namespace. diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index 55ae22dc..ea96367e 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -614,6 +614,9 @@ namespace { if (ongrids.empty()) { cerr << Warning( "LefParser::_pinPostProcess(): Pin \"%s\" has no terminal ongrid." , pinName.c_str() ) << endl; + for ( Segment* segment : segments ) { + NetExternalComponents::setExternal( segment ); + } } else { for ( Segment* segment : ongrids ) { NetExternalComponents::setExternal( segment ); diff --git a/crlcore/src/cyclop/CMakeLists.txt b/crlcore/src/cyclop/CMakeLists.txt index ecedb60c..21b92dfe 100644 --- a/crlcore/src/cyclop/CMakeLists.txt +++ b/crlcore/src/cyclop/CMakeLists.txt @@ -21,7 +21,9 @@ link_directories ( ${CRLCORE_BINARY_DIR}/src/ccore ) + if(NOT WITH_QT5) list ( APPEND cpps ${mocCpps} ) + endif() add_executable ( cyclop ${cpps} ) target_link_libraries ( cyclop crlcore diff --git a/crlcore/src/pyCRL/CMakeLists.txt b/crlcore/src/pyCRL/CMakeLists.txt index 0134ecda..7e74aec0 100644 --- a/crlcore/src/pyCRL/CMakeLists.txt +++ b/crlcore/src/pyCRL/CMakeLists.txt @@ -46,6 +46,7 @@ PyBlif.cpp PyGds.cpp PyLefImport.cpp + PyDefImport.cpp ) set( pyIncludes crlcore/PyBanner.h crlcore/PyCatalog.h @@ -65,6 +66,7 @@ crlcore/PyBlif.h crlcore/PyGds.h crlcore/PyLefImport.h + crlcore/PyDefImport.h ) set( depLibs crlcore ${HURRICANE_PYTHON_LIBRARIES} diff --git a/crlcore/src/pyCRL/PyCRL.cpp b/crlcore/src/pyCRL/PyCRL.cpp index 985e54a9..71a03f38 100644 --- a/crlcore/src/pyCRL/PyCRL.cpp +++ b/crlcore/src/pyCRL/PyCRL.cpp @@ -34,6 +34,7 @@ #include "crlcore/PyBlif.h" #include "crlcore/PyGds.h" #include "crlcore/PyLefImport.h" +#include "crlcore/PyDefImport.h" #include "crlcore/VhdlEntity.h" @@ -124,6 +125,7 @@ extern "C" { PyBlif_LinkPyType (); PyGds_LinkPyType (); PyLefImport_LinkPyType (); + PyDefImport_LinkPyType (); PYTYPE_READY ( Banner ); PYTYPE_READY ( CatalogState ); @@ -144,6 +146,7 @@ extern "C" { PYTYPE_READY ( Blif ); PYTYPE_READY ( Gds ); PYTYPE_READY ( LefImport ); + PYTYPE_READY ( DefImport ); // Identifier string can take up to 10 characters. __cs.addType ( "alcLib" , &PyTypeAllianceLibrary , "" , false ); @@ -198,6 +201,8 @@ extern "C" { PyModule_AddObject ( module, "Gds", (PyObject*)&PyTypeGds ); Py_INCREF ( &PyTypeLefImport ); PyModule_AddObject ( module, "LefImport", (PyObject*)&PyTypeLefImport ); + Py_INCREF ( &PyTypeDefImport ); + PyModule_AddObject ( module, "DefImport", (PyObject*)&PyTypeDefImport ); PyCatalog_postModuleInit (); PyEnvironment_postModuleInit (); diff --git a/crlcore/src/pyCRL/PyDefImport.cpp b/crlcore/src/pyCRL/PyDefImport.cpp new file mode 100644 index 00000000..74046cae --- /dev/null +++ b/crlcore/src/pyCRL/PyDefImport.cpp @@ -0,0 +1,121 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-2018, 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 | +// | =============================================================== | +// | C++ Module : "./PyDefImport.cpp" | +// +-----------------------------------------------------------------+ + + +#include "crlcore/PyDefImport.h" +#include "hurricane/isobar/PyCell.h" +#include +#include + + +namespace CRL { + + using std::cerr; + using std::endl; + using std::hex; + using std::string; + using std::ostringstream; + using Hurricane::tab; + using Hurricane::Exception; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Cell; + using Isobar::ProxyProperty; + using Isobar::ProxyError; + using Isobar::ConstructorError; + using Isobar::HurricaneError; + using Isobar::HurricaneWarning; + using Isobar::ParseOneArg; + using Isobar::ParseTwoArg; + using Isobar::__cs; + using Isobar::PyCell_Link; + + +extern "C" { + + +#if defined(__PYTHON_MODULE__) + +// +=================================================================+ +// | "PyDefImport" Python Module Code Part | +// +=================================================================+ + + + static PyObject* PyDefImport_load ( PyObject*, PyObject* args ) + { + cdebug_log(30,0) << "PyDefImport_load()" << endl; + + Cell* cell = NULL; + + HTRY + char* defFile = NULL; + + if (PyArg_ParseTuple( args, "s:DefImport.load", &defFile )) { + cell = DefImport::load( defFile, 0 ); + } else { + PyErr_SetString ( ConstructorError, "DefImport.load(): Bad type or bad number of parameters." ); + return NULL; + } + HCATCH + + return (PyObject*)PyCell_Link( cell ); + } + + + static PyObject* PyDefImport_reset ( PyObject*, PyObject* ) + { + cdebug_log(30,0) << "PyDefImport_reset()" << endl; + HTRY + DefImport::reset(); + HCATCH + Py_RETURN_NONE; + } + + + // Standart Destroy (Attribute). + + + PyMethodDef PyDefImport_Methods[] = + { { "load" , (PyCFunction)PyDefImport_load , METH_VARARGS|METH_STATIC + , "Load a complete Cadence LEF library." } + , { "reset" , (PyCFunction)PyDefImport_reset , METH_NOARGS|METH_STATIC + , "Reset the Cadence LEF parser (clear technology)." } + //, { "destroy" , (PyCFunction)PyDefImport_destroy , METH_VARARGS + // , "Destroy the associated hurricane object. The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + NoObjectDeleteMethod(DefImport) + PyTypeObjectLinkPyTypeWithoutObject(DefImport,DefImport) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyDefImport" Shared Library Code Part | +// +=================================================================+ + + // Type Definition. + PyTypeObjectDefinitionsOfModule(CRL,DefImport) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // CRL namespace. diff --git a/crlcore/src/pyCRL/crlcore/PyDefImport.h b/crlcore/src/pyCRL/crlcore/PyDefImport.h new file mode 100644 index 00000000..5060e1a2 --- /dev/null +++ b/crlcore/src/pyCRL/crlcore/PyDefImport.h @@ -0,0 +1,55 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-2018, 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 | +// | =============================================================== | +// | C++ Header : "./crlcore/PyDefImport.h" | +// +-----------------------------------------------------------------+ + + +#ifndef CRL_PY_DEF_IMPORT_H +#define CRL_PY_DEF_IMPORT_H + +#include "hurricane/isobar/PyHurricane.h" +#include "crlcore/DefImport.h" + + +namespace CRL { + +extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PyDefImport". + + typedef struct { + PyObject_HEAD + } PyDefImport; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyCRL.ccp". + + extern PyTypeObject PyTypeDefImport; + extern PyMethodDef PyDefImport_Methods[]; + + extern void PyDefImport_LinkPyType(); + + +#define IsPyDefImport(v) ( (v)->ob_type == &PyTypeDefImport ) +#define PY_DEFIMPORT(v) ( (PyDefImport*)(v) ) + + +} // extern "C". + +} // CRL namespace. + +#endif // CRL_PY_DEF_IMPORT_H