From b0e234b3af7ef3a79b042e839e979fdcde4ff1d3 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 25 Aug 2010 11:42:04 +0000 Subject: [PATCH] * ./crlcore: - New: In LefExport, export the spacer cells (rowend & tie) to enable filling in Cadence Encounter. - New: In DefImport, added support for regular wiring in NETS. Allows us to import routing from Encounter and characterize it. - New: In Catalog, added a CatalogExtension static property manager to allow more easy access to the Catalog::State of each Cell. Do not uses the default template because of a specific destructor and a "by pointer" value. --- crlcore/src/ccore/Catalog.cpp | 21 +++ crlcore/src/ccore/crlcore/Catalog.h | 173 +++++++++++++++++++++++-- crlcore/src/ccore/crlcore/LefExport.h | 2 +- crlcore/src/ccore/lefdef/DefExport.cpp | 2 +- crlcore/src/ccore/lefdef/DefImport.cpp | 113 +++++++++++++++- crlcore/src/ccore/lefdef/LefExport.cpp | 38 ++++-- 6 files changed, 324 insertions(+), 25 deletions(-) diff --git a/crlcore/src/ccore/Catalog.cpp b/crlcore/src/ccore/Catalog.cpp index fe932ba2..196fb3da 100644 --- a/crlcore/src/ccore/Catalog.cpp +++ b/crlcore/src/ccore/Catalog.cpp @@ -304,4 +304,25 @@ namespace CRL { } +// ------------------------------------------------------------------- +// Class : "CatalogExtension" + + + const Cell* CatalogExtension::_owner = NULL; + Catalog::State* CatalogExtension::_cache = NULL; + + + Catalog::State* CatalogExtension::_get ( const Cell* cell ) + { + if ( cell == _owner ) return _cache; + _owner = cell; + + Property* property = _owner->getProperty ( CatalogProperty::getPropertyName() ); + if ( property ) _cache = static_cast(property)->getState(); + else _cache = NULL; + + return _cache; + } + + } // End of CRL namespace. diff --git a/crlcore/src/ccore/crlcore/Catalog.h b/crlcore/src/ccore/crlcore/Catalog.h index b8de439e..4bfd072f 100644 --- a/crlcore/src/ccore/crlcore/Catalog.h +++ b/crlcore/src/ccore/crlcore/Catalog.h @@ -51,6 +51,10 @@ namespace CRL { using Hurricane::DBo; using Hurricane::Cell; using Hurricane::Library; + using Hurricane::Property; + + + extern const char* MissingStateProperty; // ------------------------------------------------------------------- @@ -170,14 +174,6 @@ namespace CRL { }; - - -// ------------------------------------------------------------------- -// Error Strings. - - extern const char* MissingStateProperty; - - // ------------------------------------------------------------------- // Inline Functions. @@ -220,6 +216,167 @@ namespace CRL { inline void CatalogProperty::setState ( Catalog::State* state ) { _state = state; } +// ------------------------------------------------------------------- +// Class : "CRL::CatalogExtension". + + + class CatalogExtension { + public: + static inline bool isFlattenLeaf ( const Cell* ); + static inline bool isFeed ( const Cell* ); + static inline bool isGds ( const Cell* ); + static inline bool isDelete ( const Cell* ); + static inline bool isPhysical ( const Cell* ); + static inline bool isLogical ( const Cell* ); + // Flags management. + static inline unsigned int getFlags ( const Cell*, unsigned int mask=(unsigned int)-1 ); + static inline bool setFlags ( const Cell*, unsigned int mask, bool value ); + static inline bool setFlattenLeaf ( const Cell*, bool value ); + static inline bool setFeed ( const Cell*, bool value ); + static inline bool setGds ( const Cell*, bool value ); + static inline bool setDelete ( const Cell*, bool value ); + static inline bool setPhysical ( const Cell*, bool value ); + static inline bool setLogical ( const Cell*, bool value ); + // Accessors. + static inline Library* getLibrary ( const Cell* ); + static inline unsigned int getDepth ( const Cell* ); + // Modifiers. + static inline Library* setLibrary ( const Cell*, Library* library ); + static inline void setDepth ( const Cell*, unsigned int depth ); + private: + static Catalog::State* _get ( const Cell* ); + private: + static const Cell* _owner; + static Catalog::State* _cache; + }; + + + inline bool CatalogExtension::isFlattenLeaf ( const Cell* cell ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->isFlattenLeaf(); + } + + + inline bool CatalogExtension::isFeed ( const Cell* cell ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->isFeed(); + } + + + inline bool CatalogExtension::isGds ( const Cell* cell ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->isGds(); + } + + + inline bool CatalogExtension::isDelete ( const Cell* cell ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->isDelete(); + } + + + inline bool CatalogExtension::isPhysical ( const Cell* cell ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->isPhysical(); + } + + + inline bool CatalogExtension::isLogical ( const Cell* cell ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->isLogical(); + } + + + inline unsigned int CatalogExtension::getFlags ( const Cell* cell, unsigned int mask ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? 0 : state->getFlags(); + } + + + inline bool CatalogExtension::setFlags ( const Cell* cell, unsigned int mask, bool value ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->setFlags(mask,value); + } + + + inline bool CatalogExtension::setFlattenLeaf ( const Cell* cell, bool value ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->setFlattenLeaf(value); + } + + + inline bool CatalogExtension::setFeed ( const Cell* cell, bool value ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->setFeed(value); + } + + + inline bool CatalogExtension::setGds ( const Cell* cell, bool value ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->setGds(value); + } + + + inline bool CatalogExtension::setDelete ( const Cell* cell, bool value ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->setDelete(value); + } + + + inline bool CatalogExtension::setPhysical ( const Cell* cell, bool value ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->setPhysical(value); + } + + + inline bool CatalogExtension::setLogical ( const Cell* cell, bool value ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? false : state->setLogical(value); + } + + + inline Library* CatalogExtension::getLibrary ( const Cell* cell ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? NULL : state->getLibrary(); + } + + + inline unsigned int CatalogExtension::getDepth ( const Cell* cell ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? 0 : state->getDepth(); + } + + + inline Library* CatalogExtension::setLibrary ( const Cell* cell, Library* library ) + { + Catalog::State* state = _get(cell); + return (state == NULL) ? NULL : state->setLibrary(library); + } + + + inline void CatalogExtension::setDepth ( const Cell* cell, unsigned int depth ) + { + Catalog::State* state = _get(cell); + if ( state == NULL ) state->setDepth(depth); + } + + } // End of CRL namespace. diff --git a/crlcore/src/ccore/crlcore/LefExport.h b/crlcore/src/ccore/crlcore/LefExport.h index ca2e49c0..fd805e2e 100644 --- a/crlcore/src/ccore/crlcore/LefExport.h +++ b/crlcore/src/ccore/crlcore/LefExport.h @@ -38,7 +38,7 @@ namespace CRL { class LefExport { public: - enum Flag { WithTechnology=0x1 }; + enum Flag { WithTechnology=0x1, WithSpacers=0x2 }; public: static void drive ( Hurricane::Cell* , unsigned int flags ); static void drive ( Hurricane::Library*, unsigned int flags ); diff --git a/crlcore/src/ccore/lefdef/DefExport.cpp b/crlcore/src/ccore/lefdef/DefExport.cpp index 898e2f1f..f9418658 100644 --- a/crlcore/src/ccore/lefdef/DefExport.cpp +++ b/crlcore/src/ccore/lefdef/DefExport.cpp @@ -621,7 +621,7 @@ namespace CRL { #if HAVE_LEFDEF DefDriver::drive ( cell, flags ); - if ( flags & WithLEF ) LefExport::drive ( cell, LefExport::WithTechnology ); + if ( flags & WithLEF ) LefExport::drive ( cell, LefExport::WithTechnology|LefExport::WithSpacers ); #else cerr << "[ERROR] CRL::DefExport::drive(): \n" << " Coriolis2 hasn't been compiled with LEF/DEF support. To enable LEF/DEF\n" diff --git a/crlcore/src/ccore/lefdef/DefImport.cpp b/crlcore/src/ccore/lefdef/DefImport.cpp index 3da01b6c..45c41bd7 100644 --- a/crlcore/src/ccore/lefdef/DefImport.cpp +++ b/crlcore/src/ccore/lefdef/DefImport.cpp @@ -36,6 +36,7 @@ #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" @@ -91,6 +92,7 @@ namespace { inline size_t getPitchs () const; inline size_t getSlices () const; inline const Box& getFitOnCellsDieArea () const; + inline Net* getPrebuildNet () const; Net* lookupNet ( const string& ); inline vector& getErrors (); inline void pushError ( const string& ); @@ -98,6 +100,7 @@ namespace { inline void clearErrors (); inline void setPitchs ( size_t ); inline void setSlices ( size_t ); + inline void setPrebuildNet ( Net* ); void addNetLookup ( const string& netName, Net* ); inline void mergeToFitOnCellsDieArea ( const Box& ); private: @@ -107,6 +110,8 @@ namespace { static int _componentCbk ( defrCallbackType_e, defiComponent*, defiUserData ); static int _componentEndCbk ( defrCallbackType_e, void* , defiUserData ); static int _netCbk ( defrCallbackType_e, defiNet* , defiUserData ); + static int _netEndCbk ( defrCallbackType_e, void* , defiUserData ); + static int _pathCbk ( defrCallbackType_e, defiPath* , defiUserData ); Cell* _createCell ( const char* name ); private: static double _defUnits; @@ -118,6 +123,7 @@ namespace { size_t _pitchs; size_t _slices; Box _fitOnCellsDieArea; + Net* _prebuildNet; map _netsLookup; vector _errors; }; @@ -128,13 +134,14 @@ namespace { DefParser::DefParser ( string& file, AllianceLibrary* library, unsigned int flags ) - : _file (file) - , _flags (flags) + : _file (file) + , _flags (flags) , _library (library) , _cell (NULL) , _pitchs (0) , _slices (0) , _fitOnCellsDieArea() + , _prebuildNet (NULL) , _netsLookup () , _errors () { @@ -145,7 +152,8 @@ namespace { defrSetComponentCbk ( _componentCbk ); defrSetComponentEndCbk ( _componentEndCbk ); defrSetNetCbk ( _netCbk ); - defrSetNetEndCbk ( _componentEndCbk ); + defrSetNetEndCbk ( _netEndCbk ); + defrSetPathCbk ( _pathCbk ); } @@ -164,11 +172,13 @@ namespace { inline size_t DefParser::getPitchs () const { return _pitchs; } inline size_t DefParser::getSlices () const { return _slices; } inline const Box& DefParser::getFitOnCellsDieArea () const { return _fitOnCellsDieArea; } + inline Net* DefParser::getPrebuildNet () const { return _prebuildNet; } inline vector& DefParser::getErrors () { return _errors; } inline void DefParser::pushError ( const string& error ) { _errors.push_back(error); } inline void DefParser::clearErrors () { return _errors.clear(); } inline void DefParser::setPitchs ( size_t pitchs ) { _pitchs=pitchs; } inline void DefParser::setSlices ( size_t slices ) { _slices=slices; } + inline void DefParser::setPrebuildNet ( Net* net ) { _prebuildNet=net; } inline void DefParser::mergeToFitOnCellsDieArea ( const Box& box ) { _fitOnCellsDieArea.merge(box); } @@ -336,6 +346,13 @@ namespace { } + int DefParser::_componentEndCbk ( defrCallbackType_e c, void*, lefiUserData ud ) + { + DefParser* parser = (DefParser*)ud; + return parser->flushErrors (); + } + + int DefParser::_netCbk ( defrCallbackType_e c, defiNet* net, lefiUserData ud ) { static size_t netCount = 0; @@ -343,11 +360,16 @@ namespace { DefParser* parser = (DefParser*)ud; //cout << " - Net " << net->name() << endl; - + Net* hnet = parser->lookupNet ( net->name() ); if ( hnet == NULL ) hnet = Net::create ( parser->getCell(), net->name() ); + if ( parser->getPrebuildNet() != NULL ) { + hnet->merge ( parser->getPrebuildNet() ); + parser->setPrebuildNet ( NULL ); + } + if (tty::enabled()) { cmess2 << " " << tty::bold << setw(7) << setfill('0') << ++netCount << ":" << setfill(' ') << tty::reset << setw(40) << "<" << net->name() << "> " << tty::cr; @@ -386,13 +408,94 @@ namespace { } - int DefParser::_componentEndCbk ( defrCallbackType_e c, void*, lefiUserData ud ) + int DefParser::_netEndCbk ( defrCallbackType_e c, void*, lefiUserData ud ) { DefParser* parser = (DefParser*)ud; return parser->flushErrors (); } + int DefParser::_pathCbk ( defrCallbackType_e c, defiPath* path, lefiUserData ud ) + { + + DefParser* parser = (DefParser*)ud; + Technology* technology = DataBase::getDB()->getTechnology(); + Net* hnet = parser->getPrebuildNet(); + + if ( hnet == NULL ) { + hnet = Net::create ( parser->getCell(), "__prebuild__" ); + parser->setPrebuildNet ( hnet ); + } + + Contact* source = NULL; + Contact* target = NULL; + const Layer* layer = NULL; + const Layer* viaLayer = NULL; + DbU::Unit width = DbU::lambda(2.0); + DbU::Unit x, y; + int defx, defy, defext; + int elementType; + + path->initTraverse (); + while ( (elementType = path->next()) != DEFIPATH_DONE ) { + bool createSegment = false; + bool createVia = false; + + switch ( elementType ) { + case DEFIPATH_LAYER: + layer = technology->getLayer ( path->getLayer() ); + break; + case DEFIPATH_WIDTH: + width = fromDefUnits(path->getWidth()); + break; + case DEFIPATH_POINT: + path->getPoint ( &defx, &defy ); + x = fromDefUnits ( defx ); + y = fromDefUnits ( defy ); + createSegment = true; + break; + case DEFIPATH_FLUSHPOINT: + path->getFlushPoint ( &defx, &defy, &defext ); + x = fromDefUnits ( defx ); + y = fromDefUnits ( defy ); + target = NULL; + createSegment = true; + break; + case DEFIPATH_VIA: + viaLayer = technology->getLayer ( path->getVia() ); + createVia = true; + break; + } + + if ( createSegment ) { + source = target; + target = Contact::create ( hnet, layer, x, y ); + if ( source != NULL ) { + if ( source->getX() == x ) { + Vertical::create ( source, target, layer, x, width ); + } else if ( source->getY() == y ) { + Horizontal::create ( source, target, layer, y, width ); + } else { + ostringstream message; + message << "Non-manhattan segment in net <" << hnet->getName() << ">."; + parser->pushError ( message.str() ); + } + } + } + + if ( createVia ) { + if ( target != NULL ) { + target = Contact::create ( target, viaLayer, 0, 0 ); + } else { + target = Contact::create ( hnet, viaLayer, x, y, 0, 0 ); + } + } + } + + return 0; + } + + Cell* DefParser::parse ( string file, unsigned int flags ) { cmess1 << " o DEF: <" << file << ">" << endl; diff --git a/crlcore/src/ccore/lefdef/LefExport.cpp b/crlcore/src/ccore/lefdef/LefExport.cpp index 1c254781..e986153c 100644 --- a/crlcore/src/ccore/lefdef/LefExport.cpp +++ b/crlcore/src/ccore/lefdef/LefExport.cpp @@ -45,6 +45,7 @@ #include "crlcore/RoutingLayerGauge.h" #include "crlcore/RoutingGauge.h" #include "crlcore/CellGauge.h" +#include "crlcore/Catalog.h" #include "crlcore/AllianceFramework.h" #include "crlcore/LefExport.h" @@ -237,14 +238,23 @@ namespace { _status = lefwStartMacro ( getString(cell->getName()).c_str() ); CHECK_STATUS(_status); - Box abutmentBox ( cell->getAbutmentBox() ); - double pitchWidth = toLefUnits ( LefDriver::getPitchWidth () ); - double sliceHeight = toLefUnits ( LefDriver::getSliceHeight() ); - int slices = (int)floor( abutmentBox.getHeight() / LefDriver::getSliceHeight() ); - int pitchs = (int)floor( abutmentBox.getWidth () / LefDriver::getPitchWidth () ); - _status = lefwMacroClass ( (slices > 1) ? "BLOCK" : "CORE" - , (slices > 1) ? "BLACKBOX" : NULL - ); + Box abutmentBox ( cell->getAbutmentBox() ); + double pitchWidth = toLefUnits ( LefDriver::getPitchWidth () ); + double sliceHeight = toLefUnits ( LefDriver::getSliceHeight() ); + int slices = (int)floor( abutmentBox.getHeight() / LefDriver::getSliceHeight() ); + int pitchs = (int)floor( abutmentBox.getWidth () / LefDriver::getPitchWidth () ); + const char* macroClass = NULL; + const char* macroSubClass = NULL; + + if ( slices > 1 ) { + macroClass = "BLOCK"; + macroSubClass = "BLACKBOX"; + } else { + macroClass = "CORE"; + if ( CatalogExtension::isFeed(cell) ) macroSubClass = "SPACER"; + } + + _status = lefwMacroClass ( macroClass, macroSubClass ); CHECK_STATUS(_status); double originX = toLefUnits ( abutmentBox.getXMin() ); @@ -704,11 +714,19 @@ namespace CRL { libraryName = getString(cell->getName()) + "export"; forEach ( Instance*, iinstance, cell->getInstances() ) { - if ( cells.find((*iinstance)->getMasterCell()) == cells.end()) - cells.insert ( (*iinstance)->getMasterCell() ); + cells.insert ( (*iinstance)->getMasterCell() ); } } + if ( flags & WithSpacers ) { + // Ugly. Direct uses of Alliance Framework. + Cell* spacer = AllianceFramework::get()->getCell("tie_x0",Catalog::State::Views); + if ( spacer != NULL ) cells.insert ( spacer ); + + spacer = AllianceFramework::get()->getCell("rowend_x0",Catalog::State::Views); + if ( spacer != NULL ) cells.insert ( spacer ); + } + LefDriver::drive ( cells, libraryName, flags ); #else cerr << "[ERROR] CRL::LefExport::drive(Cell*): \n"