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;