diff --git a/crlcore/src/ccore/lefdef/DefExport.cpp b/crlcore/src/ccore/lefdef/DefExport.cpp index 11f8865d..b865c3b8 100644 --- a/crlcore/src/ccore/lefdef/DefExport.cpp +++ b/crlcore/src/ccore/lefdef/DefExport.cpp @@ -26,6 +26,7 @@ #include "hurricane/Technology.h" #include "hurricane/Net.h" #include "hurricane/NetExternalComponents.h" +#include "hurricane/RoutingPad.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" #include "hurricane/Cell.h" @@ -36,6 +37,7 @@ #include "crlcore/RoutingGauge.h" #include "crlcore/RoutingLayerGauge.h" #include "crlcore/AllianceFramework.h" +#include "crlcore/CellGauge.h" #include "crlcore/LefExport.h" #include "crlcore/DefExport.h" @@ -63,6 +65,39 @@ namespace { } + string toDefName ( string name ) + { + if (name.empty()) return name; + + if (name[0] == '<') name.erase ( 0, 1 ); + if (name[name.size()-1] == '>') name.erase ( name.size()-1 ); + for ( size_t i=0 ; igetOccurrence(); + + name << getString(occurrence.getOwnerCell()->getName()) << '.'; + + if (not rp->getOccurrence().getPath().getHeadPath().isEmpty()) + name << getString(rp->getOccurrence().getPath().getHeadPath().getName()) << "."; + + name << "I." << getString(rp->getOccurrence().getPath().getTailInstance()->getName()); + + return toDefName(name.str()); + } + + #define CHECK_STATUS_CBK(status) if ((status) != 0) return driver->checkStatus(status); #define CHECK_STATUS_DRV(status) if ((status) != 0) return checkStatus(status); #define RETURN_CHECK_STATUS_CBK(status) return driver->checkStatus(status); @@ -75,7 +110,7 @@ namespace { static int getUnits (); static int toDefUnits ( DbU::Unit ); static int toDefOrient ( Transformation::Orientation ); - static void toDefCoordinates ( Instance*, int& statusX, int& statusY, int& statusOrient ); + static void toDefCoordinates ( Instance*, Transformation, int& statusX, int& statusY, int& statusOrient ); static DbU::Unit getSliceHeight (); static DbU::Unit getPitchWidth (); ~DefDriver (); @@ -155,9 +190,9 @@ namespace { } - void DefDriver::toDefCoordinates ( Instance* instance, int& statusX, int& statusY, int& statusOrient ) + void DefDriver::toDefCoordinates ( Instance* instance, Transformation transf, int& statusX, int& statusY, int& statusOrient ) { - const Transformation& transf = instance->getTransformation(); + instance->getTransformation().applyOn( transf ); statusX = toDefUnits ( transf.getTx() ); statusY = toDefUnits ( transf.getTy() ); statusOrient = toDefOrient( transf.getOrientation() ); @@ -192,8 +227,11 @@ namespace { , _flags (flags) , _status (0) { - _sliceHeight = DbU::lambda(50.0); - _pitchWidth = DbU::lambda( 5.0); + AllianceFramework* framework = AllianceFramework::get (); + CellGauge* cg = framework->getCellGauge(); + + _sliceHeight = cg->getSliceHeight (); + _pitchWidth = cg->getPitch (); _status = defwInitCbk ( _defStream ); if ( _status != 0 ) return; @@ -230,6 +268,7 @@ namespace { int DefDriver::write () { + _cell->flattenNets( Cell::Flags::NoFlags ); return checkStatus ( defwWrite(_defStream,_designName.c_str(),(void*)this) ); } @@ -238,7 +277,9 @@ namespace { { if ( (_status=status) != 0 ) { defwPrintError ( _status ); - cerr << Error("DefDriver::drive(): Error occured while driving <%s>.",_designName.c_str()) << endl; + ostringstream message; + message << "DefDriver::drive(): Error occured while driving <" << _designName << ">."; + cerr << Error(message.str()) << endl; } return _status; } @@ -346,6 +387,8 @@ namespace { Cell* cell = driver->getCell(); Box abutmentBox ( cell->getAbutmentBox() ); + if (abutmentBox.isEmpty()) return 0; + int origY = (int)( toDefUnits(abutmentBox.getYMin()) ); int origX = (int)( toDefUnits(abutmentBox.getXMin()) ); int stepY = (int)( toDefUnits(DefDriver::getSliceHeight()) ); @@ -390,6 +433,8 @@ namespace { Cell* cell = driver->getCell(); Box abutmentBox ( cell->getAbutmentBox() ); + if (abutmentBox.isEmpty()) return 0; + const vector& rg = AllianceFramework::get()->getRoutingGauge()->getLayerGauges(); @@ -487,27 +532,33 @@ namespace { status = defwNewLine (); CHECK_STATUS_CBK(status); - status = defwStartComponents ( cell->getInstances().getSize() ); + status = defwStartComponents ( cell->getLeafInstanceOccurrences().getSize() ); CHECK_STATUS_CBK(status); - forEach ( Instance*, iinstance, cell->getInstances() ) { - string insname = getString((*iinstance)->getName()); + for ( Occurrence occurrence : cell->getLeafInstanceOccurrences() ) { + Instance* instance = static_cast(occurrence.getEntity()); + string insname = toDefName(occurrence.getCompactString()); const char* source = NULL; const char* statusS = "UNPLACED"; int statusX = 0; int statusY = 0; int statusOrient = 0; - if (CatalogExtension::isFeed((*iinstance)->getMasterCell())) source = "DIST"; + Box instanceAb = instance->getMasterCell()->getAbutmentBox(); + Transformation instanceTransf = instance->getTransformation(); + occurrence.getPath().getTransformation().applyOn( instanceTransf ); + instanceTransf.applyOn( instanceAb ); - if ((*iinstance)->getPlacementStatus() == Instance::PlacementStatus::PLACED) statusS = "PLACED"; - if ((*iinstance)->getPlacementStatus() == Instance::PlacementStatus::FIXED ) statusS = "FIXED"; + if (CatalogExtension::isFeed(instance->getMasterCell())) source = "DIST"; + + if (instance->getPlacementStatus() == Instance::PlacementStatus::PLACED) statusS = "PLACED"; + if (instance->getPlacementStatus() == Instance::PlacementStatus::FIXED ) statusS = "FIXED"; if (statusS[0] != 'U') { - toDefCoordinates( *iinstance, statusX, statusY, statusOrient ); + toDefCoordinates( instance, occurrence.getPath().getTransformation(), statusX, statusY, statusOrient ); } status = defwComponent ( insname.c_str() - , getString((*iinstance)->getMasterCell()->getName()).c_str() + , getString((instance)->getMasterCell()->getName()).c_str() , 0 // numNetNames (disabled). , NULL // netNames (disabled). , NULL // eeq (electrical equivalence). @@ -541,24 +592,30 @@ namespace { Cell* cell = driver->getCell(); int netsNb = 0; - forEach ( Net*, inet, cell->getNets() ) { - if ( (*inet)->isSupply() or (*inet)->isClock() ) continue; + for ( Net* net : cell->getNets() ) { + if ( net->isSupply() or net->isClock() ) continue; ++netsNb; } status = defwStartNets ( netsNb ); if ( status != 0 ) return driver->checkStatus(status); - forEach ( Net*, inet, cell->getNets() ) { - if ( (*inet)->isSupply() or (*inet)->isClock() ) continue; + for ( Net* net : cell->getNets() ) { + if ( net->isSupply() or net->isClock() ) continue; + + size_t pos = string::npos; + string netName = getString( net->getName() ); + if (netName[netName.size()-1] == ')') pos = netName.rfind('('); + if (pos == string::npos) pos = netName.size(); + netName.insert( pos, "_net" ); + netName = toDefName( netName ); - string netName = getString((*inet)->getName()) + "_net"; status = defwNet ( netName.c_str() ); if ( status != 0 ) return driver->checkStatus(status); - forEach ( Plug*, iplug, (*inet)->getPlugs() ) { - status = defwNetConnection ( getString((*iplug)->getInstance ()->getName()).c_str() - , getString((*iplug)->getMasterNet()->getName()).c_str() + for ( RoutingPad* rp : net->getRoutingPads() ) { + status = defwNetConnection ( extractInstanceName(rp).c_str() + , getString(static_cast(rp->getPlugOccurrence().getEntity())->getMasterNet()->getName()).c_str() , 0 ); if ( status != 0 ) return driver->checkStatus(status); diff --git a/crlcore/src/ccore/lefdef/DefImport.cpp b/crlcore/src/ccore/lefdef/DefImport.cpp index 485e533e..d2249b25 100644 --- a/crlcore/src/ccore/lefdef/DefImport.cpp +++ b/crlcore/src/ccore/lefdef/DefImport.cpp @@ -83,7 +83,8 @@ namespace { inline size_t getPitchs () const; inline size_t getSlices () const; inline const Box& getFitOnCellsDieArea () const; - inline Net* getPrebuildNet () const; + inline Net* getPrebuildNet () const; + inline string getBusBits () const; Net* lookupNet ( const string& ); inline vector& getErrors (); inline void pushError ( const string& ); @@ -91,10 +92,13 @@ namespace { inline void clearErrors (); inline void setPitchs ( size_t ); inline void setSlices ( size_t ); - inline void setPrebuildNet ( Net* ); + inline void setPrebuildNet ( Net* ); + inline void setBusBits ( string ); void addNetLookup ( const string& netName, Net* ); + void toHurricaneName ( string& ); inline void mergeToFitOnCellsDieArea ( const Box& ); private: + static int _busBitCbk ( defrCallbackType_e, const char* , defiUserData ); static int _designEndCbk ( defrCallbackType_e, void* , defiUserData ); static int _dieAreaCbk ( defrCallbackType_e, defiBox* , defiUserData ); static int _pinCbk ( defrCallbackType_e, defiPin* , defiUserData ); @@ -110,6 +114,7 @@ namespace { string _file; unsigned int _flags; AllianceLibrary* _library; + string _busBits; Cell* _cell; size_t _pitchs; size_t _slices; @@ -128,6 +133,7 @@ namespace { : _file (file) , _flags (flags) , _library (library) + , _busBits ("()") , _cell (NULL) , _pitchs (0) , _slices (0) @@ -137,6 +143,7 @@ namespace { , _errors () { defrInit (); + defrSetBusBitCbk ( _busBitCbk ); defrSetDesignEndCbk ( _designEndCbk ); defrSetDieAreaCbk ( _dieAreaCbk ); defrSetPinCbk ( _pinCbk ); @@ -158,6 +165,7 @@ namespace { inline DbU::Unit DefParser::fromDefUnits ( int u ) { return DbU::lambda(_defUnits*(double)u); } inline bool DefParser::hasErrors () { return not _errors.empty(); } inline unsigned int DefParser::getFlags () const { return _flags; } + inline string DefParser::getBusBits () const { return _busBits; } inline AllianceLibrary* DefParser::getLibrary () { return _library; } inline Cell* DefParser::getCell () { return _cell; } inline size_t DefParser::getPitchs () const { return _pitchs; } @@ -170,6 +178,7 @@ namespace { 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::setBusBits ( string busbits ) { _busBits = busbits; } inline void DefParser::mergeToFitOnCellsDieArea ( const Box& box ) { _fitOnCellsDieArea.merge(box); } @@ -192,6 +201,20 @@ namespace { } + void DefParser::toHurricaneName ( string& defName ) + { + if (_busBits != "()") { + if (defName[defName.size()-1] == _busBits[1]) { + size_t pos = defName.rfind( _busBits[0] ); + if (pos != string::npos) { + defName[pos] = '('; + defName[defName.size()-1] = ')'; + } + } + } + } + + Transformation DefParser::getTransformation ( const Box& abox , DbU::Unit x , DbU::Unit y @@ -250,6 +273,22 @@ namespace { } + int DefParser::_busBitCbk ( defrCallbackType_e c, const char* busbits, lefiUserData ud ) + { + DefParser* parser = (DefParser*)ud; + + if (strlen(busbits) == 2) { + parser->setBusBits( busbits ); + } else { + ostringstream message; + message << "BUSBITCHARS is not two character long (" << busbits << ")"; + parser->pushError( message.str() ); + } + + return 0; + } + + int DefParser::_designEndCbk ( defrCallbackType_e c, void*, lefiUserData ud ) { DefParser* parser = (DefParser*)ud; @@ -283,11 +322,14 @@ namespace { //cout << " - Pin " << pin->pinName() << ":" << pin->netName() << endl; - Net* hnet = parser->getCell()->getNet ( pin->netName() ); + string netName = pin->netName(); + parser->toHurricaneName( netName ); + + Net* hnet = parser->getCell()->getNet ( netName ); if ( hnet == NULL ) { - hnet = Net::create ( parser->getCell(), pin->netName() ); - parser->addNetLookup ( pin->netName(), hnet ); - if ( string(pin->netName()).compare(pin->pinName()) != 0 ) + hnet = Net::create ( parser->getCell(), netName ); + parser->addNetLookup ( netName, hnet ); + if ( netName.compare(pin->pinName()) != 0 ) parser->addNetLookup ( pin->pinName(), hnet ); } @@ -351,19 +393,33 @@ namespace { DefParser* parser = (DefParser*)ud; //cout << " - Net " << net->name() << endl; + + string name = net->name(); + parser->toHurricaneName( name ); - Net* hnet = parser->lookupNet ( net->name() ); + Net* hnet = parser->lookupNet ( name ); if ( hnet == NULL ) - hnet = Net::create ( parser->getCell(), net->name() ); + hnet = Net::create ( parser->getCell(), name ); if ( parser->getPrebuildNet() != NULL ) { + Name prebuildAlias = parser->getPrebuildNet()->getName(); hnet->merge ( parser->getPrebuildNet() ); + hnet->removeAlias ( prebuildAlias ); parser->setPrebuildNet ( NULL ); } + if (name.size() > 78) { + name.erase ( 0, name.size()-75 ); + name.insert( 0, 3, '.' ); + } + 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(' ') - << tty::reset << setw(40) << "<" << net->name() << "> " << tty::cr; + cmess2 << " " + << tty::bold << setw(7) << setfill('0') << ++netCount << ":" << setfill(' ') + << tty::reset << setw(80) << name << tty::cr; cmess2.flush (); } @@ -374,6 +430,7 @@ namespace { // Connect to an external pin. if ( instanceName.compare("PIN") == 0 ) continue; + parser->toHurricaneName( pinName ); Instance* instance = parser->getCell()->getInstance ( instanceName ); if ( instance == NULL ) { @@ -402,6 +459,7 @@ namespace { int DefParser::_netEndCbk ( defrCallbackType_e c, void*, lefiUserData ud ) { DefParser* parser = (DefParser*)ud; + if (tty::enabled()) cmess2 << endl; return parser->flushErrors (); } diff --git a/crlcore/src/ccore/lefdef/LefExport.cpp b/crlcore/src/ccore/lefdef/LefExport.cpp index 1f7e6697..7b834f44 100644 --- a/crlcore/src/ccore/lefdef/LefExport.cpp +++ b/crlcore/src/ccore/lefdef/LefExport.cpp @@ -580,7 +580,7 @@ namespace { // The driver puts it before UNITS, which seems to displease Cadence Encounter. // So, as long as it doesn't prevent Encounter to works, disable it. LefDriver* driver = (LefDriver*)udata; - return driver->checkStatus ( lefwManufacturingGrid ( LefDriver::getUnits()/10.0 ) ); + return driver->checkStatus ( lefwManufacturingGrid ( LefDriver::toLefUnits(DbU::fromLambda(0.5)) ) ); #else return 0; #endif @@ -724,8 +724,9 @@ namespace CRL { if ( cell != NULL ) { libraryName = getString(cell->getName()) + "_export"; - forEach ( Instance*, iinstance, cell->getInstances() ) { - cells.insert ( (*iinstance)->getMasterCell() ); + for ( Occurrence occurrence : cell->getLeafInstanceOccurrences() ) { + Instance* instance = static_cast(occurrence.getEntity()); + cells.insert ( instance->getMasterCell() ); } } diff --git a/hurricane/src/hurricane/NetAlias.cpp b/hurricane/src/hurricane/NetAlias.cpp index 2868b797..18788180 100644 --- a/hurricane/src/hurricane/NetAlias.cpp +++ b/hurricane/src/hurricane/NetAlias.cpp @@ -59,8 +59,9 @@ namespace Hurricane { { const NetAliasHook* current = this; do { - if ( not isMaster() and (current->getName() == name) ) + if ( not current->isMaster() and (current->getName() == name) ) { return const_cast( dynamic_cast(current) ); + } current = current->_next; } while ( current != this );