* ./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.
This commit is contained in:
parent
048841ef07
commit
b0e234b3af
|
@ -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<CatalogProperty*>(property)->getState();
|
||||
else _cache = NULL;
|
||||
|
||||
return _cache;
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<string>& 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<string,Net*> _netsLookup;
|
||||
vector<string> _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<string>& 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;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue