From 3d0431b2383a08f2d137a4f3a8b7bce2d291c608 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 6 Jan 2018 16:18:33 +0100 Subject: [PATCH] In CRL, update real conf. files. Smarter management of pin in LEF parser. * Change: In CRL Core, etc/, update the configuration files of real technologies. Mostly for FreePDK 45. This work is also done for AMS c35b4 (350nm) but in a private (SoC) git repository. Added a new parameter 'lefImport.minTerminalwidth' for the minimum size (width) of a metal1 terminal in standard cells. Corrected bug of the minimum trace level which must be initialized to a great value and *not* zero; * Change: In CRL Core, BlifParser, detect when there is no tie low or tie high defined, issue an error (connexion left open) but continue. * New: In CRL::RoutingLayerGauge, new overlad of getTrackPosition() with the parameter set of getTrackIndex(). Used to know if a terminal is on-grid or not. * New: In CRL::LefImport, smarter management of metal1 pins. Adds a _pinPostProcess() function to select the external components among the various shapes. If the gauge is VH, all the pin rectangles are translateds into vertical segments (even if the metal1 gauge says the tracks are horizontals). The _pinPostProcess() function adds as external components of a net, only the segments of a sufficent width as given in 'lefImport.minTerminalWidth' and that are on-grid. --- crlcore/etc/180/scn6m_deep_09/kite.conf | 3 +- crlcore/etc/45/freepdk_45/etesian.conf | 8 + crlcore/etc/45/freepdk_45/kite.conf | 26 +- crlcore/etc/45/freepdk_45/technology.conf | 34 ++- crlcore/etc/common/etesian.conf | 4 + crlcore/etc/common/misc.conf | 4 +- crlcore/etc/symbolic/cmos/kite.conf | 3 +- crlcore/etc/symbolic/ispd05/kite.conf | 3 +- crlcore/etc/symbolic/vsc200/kite.conf | 3 +- crlcore/src/ccore/Utilities.cpp | 2 +- crlcore/src/ccore/blif/BlifParser.cpp | 89 ++++--- crlcore/src/ccore/crlcore/RoutingLayerGauge.h | 3 + crlcore/src/ccore/lefdef/LefImport.cpp | 231 ++++++++++++------ 13 files changed, 285 insertions(+), 128 deletions(-) diff --git a/crlcore/etc/180/scn6m_deep_09/kite.conf b/crlcore/etc/180/scn6m_deep_09/kite.conf index 88d6800b..e177382f 100644 --- a/crlcore/etc/180/scn6m_deep_09/kite.conf +++ b/crlcore/etc/180/scn6m_deep_09/kite.conf @@ -7,7 +7,8 @@ execfile( helpers.sysConfDir+'/common/kite.conf' ) parametersTable = \ - ( ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. + ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 ) + , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) , ('katabatic.topRoutingLayer' ,TypeString , 'METAL5') diff --git a/crlcore/etc/45/freepdk_45/etesian.conf b/crlcore/etc/45/freepdk_45/etesian.conf index 60954b3c..fb0c9f68 100644 --- a/crlcore/etc/45/freepdk_45/etesian.conf +++ b/crlcore/etc/45/freepdk_45/etesian.conf @@ -3,3 +3,11 @@ 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/freepdk_45/kite.conf b/crlcore/etc/45/freepdk_45/kite.conf index d1554e33..39e9e6b0 100644 --- a/crlcore/etc/45/freepdk_45/kite.conf +++ b/crlcore/etc/45/freepdk_45/kite.conf @@ -9,10 +9,12 @@ helpers.micronsMode() parametersTable = \ - ( ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. + ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.065 ) + , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) - , ('katabatic.topRoutingLayer' ,TypeString , 'METAL5') + , ('katabatic.topRoutingLayer' ,TypeString , 'metal5') + , ('anabatic.routingGauge' ,TypeString , 'gscl45') # Kite parameters. , ("kite.hTracksReservedLocal" ,TypeInt ,4 , { 'min':0, 'max':18 } ) , ("kite.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':18 } ) @@ -41,16 +43,16 @@ parametersTable = \ routingGaugesTable = {} routingGaugesTable['gscl45'] = \ - ( ( 'METAL1' , ( Gauge.Vertical , Gauge.PinOnly, 0, 0.0, 0, 0.190, 0.065, 0.650, 7 ) ) - , ( 'METAL2' , ( Gauge.Horizontal, Gauge.Default, 1, 0.0, 0, 0.190, 0.075, 0.700, 8 ) ) - , ( 'METAL3' , ( Gauge.Vertical , Gauge.Default, 2, 0.0, 0, 0.190, 0.070, 0.700, 8 ) ) - , ( 'METAL4' , ( Gauge.Horizontal, Gauge.Default, 3, 0.0, 0, 0.285, 0.140, 0.140, 8 ) ) - , ( 'METAL5' , ( Gauge.Vertical , Gauge.Default, 4, 0.0, 0, 0.285, 0.140, 0.140, 8 ) ) - , ( 'METAL6' , ( Gauge.Horizontal, Gauge.Default, 5, 0.0, 0, 0.285, 0.140, 0.140, 8 ) ) - #, ( 'METAL7' , ( Gauge.Vertical , Gauge.Default, 5, 0.0, 0, 0.855, 0.400, 0.400, 8 ) ) - #, ( 'METAL8' , ( Gauge.Horizontal, Gauge.Default, 5, 0.0, 0, 0.855, 0.400, 0.400, 8 ) ) - #, ( 'METAL9' , ( Gauge.Vertical , Gauge.Default, 5, 0.0, 0, 1.710, 0.800, 0.800, 8 ) ) - #, ( 'METAL10' , ( Gauge.Horizontal, Gauge.Default, 5, 0.0, 0, 1.710, 0.800, 0.800, 8 ) ) + ( ( 'metal1' , ( Gauge.Horizontal, Gauge.PinOnly, 0, 0.0, 0, 0.190, 0.065, 0.065, 7 ) ) + , ( 'metal2' , ( Gauge.Vertical , Gauge.Default, 1, 0.0, 0, 0.190, 0.070, 0.070, 8 ) ) + , ( 'metal3' , ( Gauge.Horizontal, Gauge.Default, 2, 0.0, 0, 0.190, 0.070, 0.070, 8 ) ) + , ( 'metal4' , ( Gauge.Vertical , Gauge.Default, 3, 0.0, 0, 0.285, 0.140, 0.140, 8 ) ) + , ( 'metal5' , ( Gauge.Horizontal, Gauge.Default, 4, 0.0, 0, 0.285, 0.140, 0.140, 8 ) ) + , ( 'metal6' , ( Gauge.Vertical , Gauge.Default, 5, 0.0, 0, 0.285, 0.140, 0.140, 8 ) ) + , ( 'metal7' , ( Gauge.Horizontal, Gauge.Default, 6, 0.0, 0, 0.855, 0.400, 0.400, 8 ) ) + , ( 'metal8' , ( Gauge.Vertical , Gauge.Default, 7, 0.0, 0, 0.855, 0.400, 0.400, 8 ) ) + , ( 'metal9' , ( Gauge.Horizontal, Gauge.Default, 8, 0.0, 0, 1.710, 0.800, 0.800, 8 ) ) + , ( 'metal10' , ( Gauge.Vertical , Gauge.Default, 9, 0.0, 0, 1.710, 0.800, 0.800, 8 ) ) ) diff --git a/crlcore/etc/45/freepdk_45/technology.conf b/crlcore/etc/45/freepdk_45/technology.conf index 31fa48a4..fa691884 100644 --- a/crlcore/etc/45/freepdk_45/technology.conf +++ b/crlcore/etc/45/freepdk_45/technology.conf @@ -10,13 +10,14 @@ from Hurricane import DbU - # Contains the layers execfile( helpers.sysConfDir+'/common/technology.conf' ) +helpers.micronsMode() + technoConfig = { 'name' : 'freepdk_45' - , 'gridValue' : 0.005 + , 'gridValue' : 0.0025 , 'gridUnit' : DbU.UnitPowerMicro , 'gridsPerLambda': 18 } @@ -163,6 +164,35 @@ layersExtensionsTable = \ , ('VIA910.metal9.enclosure' , 0.5) , ('VIA910.metal10.enclosure' , 0.5) + # VIAs (i.e. Metal <--> Metal) (real). + , ('via12.minimum.side' , 0.065) + , ('via12.metal1.enclosure' , 0.0 ) + , ('via12.metal2.enclosure' , 0.025) + , ('via23.minimum.side' , 0.070) + , ('via23.metal2.enclosure' , 0.0 ) + , ('via23.metal3.enclosure' , 0.035) + , ('via34.minimum.side' , 0.070) + , ('via34.metal3.enclosure' , 0.0 ) + , ('via34.metal4.enclosure' , 0.035) + , ('via45.minimum.side' , 0.140) + , ('via45.metal4.enclosure' , 0.0 ) + , ('via45.metal5.enclosure' , 0.0 ) + , ('via56.minimum.side' , 0.140) + , ('via56.metal5.enclosure' , 0.0 ) + , ('via56.metal6.enclosure' , 0.0 ) + , ('via67.minimum.side' , 0.140) + , ('via67.metal6.enclosure' , 0.0 ) + , ('via67.metal7.enclosure' , 0.130) + , ('via78.minimum.side' , 0.200) + , ('via78.metal7.enclosure' , 0.0 ) + , ('via78.metal8.enclosure' , 0.0 ) + , ('via89.minimum.side' , 0.200) + , ('via89.metal8.enclosure' , 0.0 ) + , ('via89.metal9.enclosure' , 0.200) + , ('via910.minimum.side' , 0.400) + , ('via910.metal9.enclosure' , 0.0 ) + , ('via910.metal10.enclosure' , 0.0 ) + # Blockages (symbolic). , ('BLOCKAGE1.minimum.width' , 1.0) , ('BLOCKAGE1.blockage1.extention.cap' , 0.5) diff --git a/crlcore/etc/common/etesian.conf b/crlcore/etc/common/etesian.conf index a1166cf9..ca8240c4 100644 --- a/crlcore/etc/common/etesian.conf +++ b/crlcore/etc/common/etesian.conf @@ -6,6 +6,10 @@ parametersTable = \ , ('etesian.spaceMargin' , TypePercentage, 5 ) , ('etesian.uniformDensity' , TypeBool , False ) , ('etesian.routingDriven' , TypeBool , False ) + , ('etesian.feedNames' , TypeString , 'tie_x0,rowend_x0') + , ('etesian.cell.zero' , TypeString , 'zero_x0' ) + , ('etesian.cell.one' , TypeString , 'one_x0' ) + , ("etesian.effort" , TypeEnumerate , 2 , { 'values':( ("Fast" , 1) , ("Standard" , 2) diff --git a/crlcore/etc/common/misc.conf b/crlcore/etc/common/misc.conf index 107491e4..738e215c 100644 --- a/crlcore/etc/common/misc.conf +++ b/crlcore/etc/common/misc.conf @@ -7,8 +7,8 @@ parametersTable = \ , ('misc.logMode' , TypeBool, False) , ('misc.verboseLevel1', TypeBool, True ) , ('misc.verboseLevel2', TypeBool, False) - , ('misc.minTraceLevel', TypeInt , 0, {'min':0} ) - , ('misc.maxTraceLevel', TypeInt , 0, {'min':0} ) + , ('misc.minTraceLevel', TypeInt , 100000, {'min':0} ) + , ('misc.maxTraceLevel', TypeInt , 0, {'min':0} ) , ('viewer.printer.DPI' , TypeInt , 150, {'min':100} ) , ("viewer.printer.mode", TypeEnumerate , 1 diff --git a/crlcore/etc/symbolic/cmos/kite.conf b/crlcore/etc/symbolic/cmos/kite.conf index 39606153..f408cd58 100644 --- a/crlcore/etc/symbolic/cmos/kite.conf +++ b/crlcore/etc/symbolic/cmos/kite.conf @@ -7,7 +7,8 @@ execfile( helpers.sysConfDir+'/common/kite.conf' ) parametersTable = \ - ( ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. + ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 ) + , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) , ('katabatic.topRoutingLayer' ,TypeString , 'METAL5') diff --git a/crlcore/etc/symbolic/ispd05/kite.conf b/crlcore/etc/symbolic/ispd05/kite.conf index fc0815b0..221311bd 100644 --- a/crlcore/etc/symbolic/ispd05/kite.conf +++ b/crlcore/etc/symbolic/ispd05/kite.conf @@ -7,7 +7,8 @@ execfile( helpers.sysConfDir+'/common/kite.conf' ) parametersTable = \ - ( ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. + ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 ) + , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) , ('katabatic.topRoutingLayer' ,TypeString , 'METAL5') diff --git a/crlcore/etc/symbolic/vsc200/kite.conf b/crlcore/etc/symbolic/vsc200/kite.conf index 8b756b7c..913b62c4 100644 --- a/crlcore/etc/symbolic/vsc200/kite.conf +++ b/crlcore/etc/symbolic/vsc200/kite.conf @@ -7,7 +7,8 @@ execfile( helpers.sysConfDir+'/common/kite.conf' ) parametersTable = \ - ( ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. + ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 ) + , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) , ('katabatic.topRoutingLayer' ,TypeString , 'METAL5') diff --git a/crlcore/src/ccore/Utilities.cpp b/crlcore/src/ccore/Utilities.cpp index 86a9b103..e6a836ea 100644 --- a/crlcore/src/ccore/Utilities.cpp +++ b/crlcore/src/ccore/Utilities.cpp @@ -371,7 +371,7 @@ namespace CRL { void System::_trapSig ( int sig ) { cerr << "\n\n[CRL ERROR] System::_trapSig():\n" << endl; - cerr << "Program stack:\n" << Backtrace().textWhere() << endl; + cerr << "Program stack:\n" << Backtrace(true).textWhere() << endl; switch ( sig ) { case SIGINT: diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp index 5dc936cb..81026826 100644 --- a/crlcore/src/ccore/blif/BlifParser.cpp +++ b/crlcore/src/ccore/blif/BlifParser.cpp @@ -247,7 +247,13 @@ namespace { typedef unordered_map Lut; static Lut _blifLut; static vector _blifOrder; + static bool _staticInit; + static Cell* _zero; + static Cell* _one; + static Net* _masterNetZero; + static Net* _masterNetOne; public: + static void staticInit (); static Model* find ( string modelName ); static void orderModels (); static void connectModels (); @@ -307,6 +313,11 @@ namespace { Model::Lut Model::_blifLut; vector Model::_blifOrder; + bool Model::_staticInit = false; + Cell* Model::_zero = NULL; + Cell* Model::_one = NULL; + Net* Model::_masterNetZero = NULL; + Net* Model::_masterNetOne = NULL; struct CompareByDepth { @@ -318,6 +329,32 @@ namespace { }; + void Model::staticInit () + { + _staticInit = true; + + auto framework = AllianceFramework::get(); + + static string zeroName = Cfg::getParamString("etesian.cell.zero","zero_x0")->asString(); + static string oneName = Cfg::getParamString("etesian.cell.one" , "one_x0")->asString(); + + _zero = framework->getCell( zeroName, Catalog::State::Views|Catalog::State::Foreign ); + _one = framework->getCell( oneName, Catalog::State::Views|Catalog::State::Foreign ); + + if (_zero) { + for ( Net* net : _zero->getNets() ) if (not net->isSupply()) { _masterNetZero = net; break; } + } else + cerr << Warning( "BlifParser::Model::connectSubckts(): The zero (tie high) cell \"%s\" has not been found." + , zeroName.c_str() ) << endl; + + if (_one) { + for ( Net* net : _one->getNets() ) if (not net->isSupply()) { _masterNetOne = net; break; } + } else + cerr << Warning( "BlifParser::Model::connectSubckts(): The one (tie low) cell \"%s\" has not been found." + , oneName.c_str() ) << endl; + } + + Model* Model::find ( string modelName ) { Lut::iterator ibcell = _blifLut.find( modelName ); @@ -367,6 +404,8 @@ namespace { , _subckts() , _depth (0) { + if (not _staticInit) staticInit(); + _blifLut.insert( make_pair(getString(_cell->getName()), this) ); if (_cell->isTerminal()) _depth = 1; @@ -473,20 +512,7 @@ namespace { void Model::connectSubckts () { - auto framework = AllianceFramework::get(); - - static string zeroName = Cfg::getParamString("etesian.cell.zero","zero_x0")->asString(); - static string oneName = Cfg::getParamString("etesian.cell.one" , "one_x0")->asString(); - unsigned int supplyCount = 0; - Cell* zero = framework->getCell( zeroName, Catalog::State::Views|Catalog::State::Foreign ); - Cell* one = framework->getCell( oneName, Catalog::State::Views|Catalog::State::Foreign ); - - Net* masterNetZero = NULL; - for ( Net* net : zero->getNets() ) if (not net->isSupply()) { masterNetZero = net; break; } - - Net* masterNetOne = NULL; - for ( Net* net : one->getNets() ) if (not net->isSupply()) { masterNetOne = net; break; } for ( Subckt* subckt : _subckts ) { if(not subckt->getModel()) @@ -551,27 +577,34 @@ namespace { << " is connected to POWER/GROUND " << plugNet->getName() << " through the alias " << netName << "."; - cerr << Warning( message.str() ) << endl; - if (plugNet->isPower()) { - ostringstream insName; insName << "one_" << supplyCount++; + if (_masterNetOne) { + if (plugNet->isPower()) { + ostringstream insName; insName << "one_" << supplyCount++; - Instance* insOne = Instance::create( _cell, insName.str(), one ); - Net* netOne = Net::create( _cell, insName.str() ); + Instance* insOne = Instance::create( _cell, insName.str(), _one ); + Net* netOne = Net::create( _cell, insName.str() ); - insOne->getPlug( masterNetOne )->setNet( netOne ); - plug->setNet( netOne ); - } + insOne->getPlug( _masterNetOne )->setNet( netOne ); + plug->setNet( netOne ); + } + } else + message << "\n (no tie high, connexion has been LEFT OPEN)"; - if (plugNet->isGround()) { - ostringstream insName; insName << "zero_" << supplyCount++; + if (_masterNetZero) { + if (plugNet->isGround()) { + ostringstream insName; insName << "zero_" << supplyCount++; - Instance* insZero = Instance::create( _cell, insName.str(), zero ); - Net* netZero = Net::create( _cell, insName.str() ); + Instance* insZero = Instance::create( _cell, insName.str(), _zero ); + Net* netZero = Net::create( _cell, insName.str() ); - insZero->getPlug( masterNetZero )->setNet( netZero ); - plug->setNet( netZero ); - } + insZero->getPlug( _masterNetZero )->setNet( netZero ); + plug->setNet( netZero ); + } + } else + message << "\n (no tie low, connexion has been LEFT OPEN)"; + + if (not message.str().empty()) cerr << Warning( message.str() ) << endl; } } } diff --git a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h index d567588b..6deb2777 100644 --- a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h @@ -109,6 +109,7 @@ namespace CRL { void divide ( DbU::Unit dividend, long& quotient, long& modulo ) const; unsigned int getTrackNumber ( DbU::Unit start, DbU::Unit stop ) const; unsigned int getTrackIndex ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const; + inline DbU::Unit getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const; DbU::Unit getTrackPosition ( DbU::Unit start, unsigned depth ) const; // Hurricane Managment. void toJson ( JsonWriter* ) const; @@ -181,6 +182,8 @@ namespace CRL { inline DbU::Unit RoutingLayerGauge::getViaWidth () const { return _viaWidth; } inline DbU::Unit RoutingLayerGauge::getHalfViaWidth () const { return _viaWidth>>1; } inline DbU::Unit RoutingLayerGauge::getObstacleDw () const { return _obstacleDw; } + inline DbU::Unit RoutingLayerGauge::getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const + { return getTrackPosition( start, getTrackIndex(start,stop,position,mode) ); } // ------------------------------------------------------------------- diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index 92fe08a1..b67eec7b 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -14,33 +14,34 @@ // +-----------------------------------------------------------------+ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #if defined(HAVE_LEFDEF) # include "lefrReader.hpp" #endif -#include "hurricane/Error.h" -#include "hurricane/Warning.h" -#include "hurricane/DataBase.h" -#include "hurricane/BasicLayer.h" -#include "hurricane/Technology.h" -#include "hurricane/Net.h" -#include "hurricane/NetExternalComponents.h" -#include "hurricane/Contact.h" -#include "hurricane/Horizontal.h" -#include "hurricane/Vertical.h" -#include "hurricane/Cell.h" -#include "hurricane/Library.h" -#include "hurricane/UpdateSession.h" -#include "crlcore/Utilities.h" -#include "crlcore/ToolBox.h" -#include "crlcore/RoutingGauge.h" -#include "crlcore/CellGauge.h" -#include "crlcore/AllianceFramework.h" -#include "crlcore/LefImport.h" +#include "vlsisapd/configuration/Configuration.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Technology.h" +#include "hurricane/Net.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Contact.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Cell.h" +#include "hurricane/Library.h" +#include "hurricane/UpdateSession.h" +#include "crlcore/Utilities.h" +#include "crlcore/ToolBox.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/CellGauge.h" +#include "crlcore/AllianceFramework.h" +#include "crlcore/LefImport.h" #if defined(HAVE_LEFDEF) @@ -77,6 +78,7 @@ namespace { static Library* parse ( string file ); LefParser ( string file, string libraryName ); ~LefParser (); + inline bool isVH () const; Library* createLibrary (); inline string getLibraryName () const; inline Library* getLibrary ( bool create=false ); @@ -102,6 +104,8 @@ namespace { inline void incNthCut (); inline RoutingGauge* getRoutingGauge () const; inline CellGauge* getCellGauge () const; + inline void addPinSegment ( string name, Segment* ); + inline void clearPinSegments (); private: static int _unitsCbk ( lefrCallbackType_e, lefiUnits* , lefiUserData ); static int _layerCbk ( lefrCallbackType_e, lefiLayer* , lefiUserData ); @@ -109,6 +113,7 @@ namespace { static int _obstructionCbk ( lefrCallbackType_e, lefiObstruction*, lefiUserData ); static int _macroCbk ( lefrCallbackType_e, lefiMacro* , lefiUserData ); static int _pinCbk ( lefrCallbackType_e, lefiPin* , lefiUserData ); + void _pinPostProcess (); private: string _file; string _libraryName; @@ -117,6 +122,7 @@ namespace { Net* _net; string _busBits; double _unitsMicrons; + map< string, vector > _pinSegments; static map _layerLut; vector _errors; int _nthMetal; @@ -129,29 +135,32 @@ namespace { }; - inline DbU::Unit LefParser::getMinTerminalWidth () const { return _minTerminalWidth; } - inline string LefParser::getLibraryName () const { return _libraryName; } - inline Library* LefParser::getLibrary ( bool create ) { if (not _library and create) createLibrary(); return _library; } - inline Cell* LefParser::getCell () const { return _cell; } - inline void LefParser::setCell ( Cell* cell ) { _cell=cell; } - inline Net* LefParser::getNet () const { return _net; } - inline void LefParser::setNet ( Net* net ) { _net=net; } - inline DbU::Unit LefParser::fromUnitsMicrons ( double d ) const { return DbU::fromPhysical(d,DbU::Micro); } - inline double LefParser::getUnitsMicrons () const { return _unitsMicrons; } - inline void LefParser::setUnitsMicrons ( double precision ) { _unitsMicrons=precision; } - inline int LefParser::getNthMetal () const { return _nthMetal; } - inline void LefParser::incNthMetal () { ++_nthMetal; } - inline int LefParser::getNthCut () const { return _nthCut; } - inline void LefParser::incNthCut () { ++_nthCut; } - inline RoutingGauge* LefParser::getRoutingGauge () const { return _routingGauge; } - inline CellGauge* LefParser::getCellGauge () const { return _cellGauge; } - inline void LefParser::setCoreSite ( DbU::Unit x, DbU::Unit y ) { _coreSiteX=x; _coreSiteY=y; } - inline DbU::Unit LefParser::getCoreSiteX () { return _coreSiteX; } - inline DbU::Unit LefParser::getCoreSiteY () { return _coreSiteY; } - inline bool LefParser::hasErrors () const { return not _errors.empty(); } - inline const vector& LefParser::getErrors () const { return _errors; } - inline void LefParser::pushError ( const string& error ) { _errors.push_back(error); } - inline void LefParser::clearErrors () { return _errors.clear(); } + inline bool LefParser::isVH () const { return _routingGauge->isVH(); } + inline DbU::Unit LefParser::getMinTerminalWidth () const { return _minTerminalWidth; } + inline string LefParser::getLibraryName () const { return _libraryName; } + inline Library* LefParser::getLibrary ( bool create ) { if (not _library and create) createLibrary(); return _library; } + inline Cell* LefParser::getCell () const { return _cell; } + inline void LefParser::setCell ( Cell* cell ) { _cell=cell; } + inline Net* LefParser::getNet () const { return _net; } + inline void LefParser::setNet ( Net* net ) { _net=net; } + inline DbU::Unit LefParser::fromUnitsMicrons ( double d ) const { return DbU::fromPhysical(d,DbU::Micro); } + inline double LefParser::getUnitsMicrons () const { return _unitsMicrons; } + inline void LefParser::setUnitsMicrons ( double precision ) { _unitsMicrons=precision; } + inline int LefParser::getNthMetal () const { return _nthMetal; } + inline void LefParser::incNthMetal () { ++_nthMetal; } + inline int LefParser::getNthCut () const { return _nthCut; } + inline void LefParser::incNthCut () { ++_nthCut; } + inline RoutingGauge* LefParser::getRoutingGauge () const { return _routingGauge; } + inline CellGauge* LefParser::getCellGauge () const { return _cellGauge; } + inline void LefParser::setCoreSite ( DbU::Unit x, DbU::Unit y ) { _coreSiteX=x; _coreSiteY=y; } + inline DbU::Unit LefParser::getCoreSiteX () { return _coreSiteX; } + inline DbU::Unit LefParser::getCoreSiteY () { return _coreSiteY; } + inline bool LefParser::hasErrors () const { return not _errors.empty(); } + inline const vector& LefParser::getErrors () const { return _errors; } + inline void LefParser::pushError ( const string& error ) { _errors.push_back(error); } + inline void LefParser::clearErrors () { return _errors.clear(); } + inline void LefParser::addPinSegment ( string name, Segment* s ) { _pinSegments[name].push_back(s); } + inline void LefParser::clearPinSegments () { _pinSegments.clear(); } map LefParser::_layerLut; @@ -199,7 +208,7 @@ namespace { , _nthCut (0) , _routingGauge (NULL) , _cellGauge (NULL) - , _minTerminalWidth(DbU::fromPhysical(0.9,DbU::UnitPower::Micro)) + , _minTerminalWidth(DbU::fromPhysical(Cfg::getParamDouble("lefImport.minTerminalWidth",0.0)->asDouble(),DbU::UnitPower::Micro)) { _routingGauge = AllianceFramework::get()->getRoutingGauge(); _cellGauge = AllianceFramework::get()->getCellGauge(); @@ -384,21 +393,20 @@ namespace { lefiGeomRect* r = geoms->getRect(igeom); double w = r->xh - r->xl; double h = r->yh - r->yl; - Component* component = NULL; if (w >= h) { - component = Horizontal::create( blockageNet, layer - , parser->fromUnitsMicrons( (r->yl + r->yh)/2 ) - , parser->fromUnitsMicrons( h ) - , parser->fromUnitsMicrons( r->xl ) - , parser->fromUnitsMicrons( r->xh ) - ); + Horizontal::create( blockageNet, layer + , parser->fromUnitsMicrons( (r->yl + r->yh)/2 ) + , parser->fromUnitsMicrons( h ) + , parser->fromUnitsMicrons( r->xl ) + , parser->fromUnitsMicrons( r->xh ) + ); } else { - component = Vertical::create( blockageNet, layer - , parser->fromUnitsMicrons( (r->xl + r->xh)/2 ) - , parser->fromUnitsMicrons( w ) - , parser->fromUnitsMicrons( r->yl ) - , parser->fromUnitsMicrons( r->yh ) - ); + Vertical::create( blockageNet, layer + , parser->fromUnitsMicrons( (r->xl + r->xh)/2 ) + , parser->fromUnitsMicrons( w ) + , parser->fromUnitsMicrons( r->yl ) + , parser->fromUnitsMicrons( r->yh ) + ); } } } @@ -429,6 +437,9 @@ namespace { cell->setAbutmentBox( Box( 0, 0, width, height ) ); } + parser->_pinPostProcess(); + parser->clearPinSegments(); + cerr << " - " << cellName << " " << DbU::getValueString(width) << " " << DbU::getValueString(height) << endl; parser->setCell( NULL ); @@ -481,26 +492,25 @@ namespace { lefiGeomRect* r = geoms->getRect(igeom); DbU::Unit w = parser->fromUnitsMicrons(r->xh - r->xl); DbU::Unit h = parser->fromUnitsMicrons(r->yh - r->yl); - Component* component = NULL; - bool isExternal = false; - if (w >= h) { - isExternal = (h >= parser->getMinTerminalWidth()); - component = Horizontal::create( net, layer - , parser->fromUnitsMicrons( (r->yl + r->yh)/2 ) - , h - , parser->fromUnitsMicrons( r->xl ) - , parser->fromUnitsMicrons( r->xh ) - ); - } else { - isExternal = (w >= parser->getMinTerminalWidth()); - component = Vertical::create( net, layer - , parser->fromUnitsMicrons( (r->xl + r->xh)/2 ) - , w - , parser->fromUnitsMicrons( r->yl ) - , parser->fromUnitsMicrons( r->yh ) + Segment* segment = NULL; + float formFactor = (float)w / (float)h; + + if ( (formFactor > 0.5) and not parser->isVH() ) { + segment = Horizontal::create( net, layer + , parser->fromUnitsMicrons( (r->yl + r->yh)/2 ) + , h + , parser->fromUnitsMicrons( r->xl ) + , parser->fromUnitsMicrons( r->xh ) ); + } else { + segment = Vertical::create( net, layer + , parser->fromUnitsMicrons( (r->xl + r->xh)/2 ) + , w + , parser->fromUnitsMicrons( r->yl ) + , parser->fromUnitsMicrons( r->yh ) + ); } - if (isExternal) NetExternalComponents::setExternal( component ); + if (segment) parser->addPinSegment( pin->name(), segment ); continue; } @@ -534,6 +544,69 @@ namespace { } + void LefParser::_pinPostProcess () + { + const Layer* metal1 = _routingGauge->getLayerGauge( (size_t)0 )->getLayer(); + const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 ); + Box ab = _cell->getAbutmentBox(); + + for ( auto element : _pinSegments ) { + string pinName = element.first; + vector& segments = element.second; + vector ongrids; + + for ( Segment* segment : segments ) { + bool isWide = (segment->getWidth() >= getMinTerminalWidth()); + + if (not segment->getNet()->isSupply()) { + if (isVH() and (segment->getLayer()->getMask() == metal1->getMask())) { + Vertical* v = dynamic_cast( segment ); + if (v) { + DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin() + , ab.getXMax() + , v->getX() + , Constant::Nearest ); + + if (nearestX == v->getX()) { + } else { + DbU::Unit neighbor = nearestX + + ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch(); + if ( (v->getX() - v->getHalfWidth() > neighbor) + or (v->getX() + v->getHalfWidth() < neighbor) ) { + ongrids.push_back( Vertical::create( v->getNet() + , v->getLayer() + , nearestX + , _routingGauge->getLayerGauge((size_t)0)->getWireWidth() + , v->getDySource() + , v->getDyTarget() + ) + ); + + } else { + // Unpitched and not wide enough to be under a metal2 track, ignore. + } + + continue; + } + } + } + } + + if (isWide) ongrids.push_back( segment ); + } + + if (ongrids.empty()) { + cerr << Warning( "LefParser::_pinPostProcess(): Pin \"%s\" has no terminal ongrid." + , pinName.c_str() ) << endl; + } else { + for ( Segment* segment : ongrids ) { + NetExternalComponents::setExternal( segment ); + } + } + } + } + + int LefParser::flushErrors () { int code = (hasErrors()) ? 1 : 0;