* ./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:
Jean-Paul Chaput 2010-08-25 11:42:04 +00:00
parent 048841ef07
commit b0e234b3af
6 changed files with 324 additions and 25 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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 );

View File

@ -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"

View File

@ -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;
};
@ -135,6 +141,7 @@ namespace {
, _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;
@ -348,6 +365,11 @@ namespace {
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;

View File

@ -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"
@ -242,9 +243,18 @@ namespace {
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
);
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() );
}
}
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"