Change of loading order in LefImport, now GDS first then LEF.
* Bug: In LefImport::_macroCbk(), the GDS file must be loaded *before* we start putting nets & components from the LEF file. The GDS parser must find an blank slate and not try to modifies nets already created by LEF. This way, we really can modify the GDS layout to suit the LEF statements. Note that we may end up with two set of terminal exactly overlapping, a Pad from the GDS and a Segment from LEF.
This commit is contained in:
parent
bec7bba938
commit
9c7770806c
|
@ -85,6 +85,8 @@ namespace {
|
||||||
inline bool isVH () const;
|
inline bool isVH () const;
|
||||||
bool isUnmatchedLayer ( string );
|
bool isUnmatchedLayer ( string );
|
||||||
Library* createLibrary ();
|
Library* createLibrary ();
|
||||||
|
Cell* earlyGetCell ( string name="" );
|
||||||
|
Net* earlyGetNet ( string name );
|
||||||
inline string getLibraryName () const;
|
inline string getLibraryName () const;
|
||||||
inline Library* getLibrary ( bool create=false );
|
inline Library* getLibrary ( bool create=false );
|
||||||
inline string getForeignPath () const;
|
inline string getForeignPath () const;
|
||||||
|
@ -350,6 +352,27 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Cell* LefParser::earlyGetCell ( string name )
|
||||||
|
{
|
||||||
|
if (not _cell) {
|
||||||
|
if (name.empty())
|
||||||
|
name = "EarlyLEFCell";
|
||||||
|
_cell = Cell::create( getLibrary(true), name );
|
||||||
|
}
|
||||||
|
return _cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Net* LefParser::earlyGetNet ( string name )
|
||||||
|
{
|
||||||
|
if (not _cell) earlyGetCell();
|
||||||
|
Net* net = _cell->getNet( name );
|
||||||
|
if (not net)
|
||||||
|
net = Net::create( _cell, name );
|
||||||
|
return net;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int LefParser::_unitsCbk ( lefrCallbackType_e c, lefiUnits* units, lefiUserData ud )
|
int LefParser::_unitsCbk ( lefrCallbackType_e c, lefiUnits* units, lefiUserData ud )
|
||||||
{
|
{
|
||||||
LefParser* parser = (LefParser*)ud;
|
LefParser* parser = (LefParser*)ud;
|
||||||
|
@ -505,10 +528,10 @@ namespace {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LefParser::_macroForeignCbk ( lefrCallbackType_e c, const lefiMacroForeign* foreign, lefiUserData ud )
|
int LefParser::_macroForeignCbk ( lefrCallbackType_e c, const lefiMacroForeign* foreign, lefiUserData ud )
|
||||||
{
|
{
|
||||||
LefParser* parser = (LefParser*)ud;
|
LefParser* parser = (LefParser*)ud;
|
||||||
AllianceFramework* af = AllianceFramework::get();
|
|
||||||
|
|
||||||
if (_gdsForeignDirectory.empty()) {
|
if (_gdsForeignDirectory.empty()) {
|
||||||
cerr << Warning( "LefParser::_macroForeignCbk(): GDS directory *not* set, ignoring FOREIGN statement." ) << endl;
|
cerr << Warning( "LefParser::_macroForeignCbk(): GDS directory *not* set, ignoring FOREIGN statement." ) << endl;
|
||||||
|
@ -520,9 +543,25 @@ namespace {
|
||||||
parser->setForeignPosition( Point( parser->fromUnitsMicrons( foreign->px() )
|
parser->setForeignPosition( Point( parser->fromUnitsMicrons( foreign->px() )
|
||||||
, parser->fromUnitsMicrons( foreign->px() )));
|
, parser->fromUnitsMicrons( foreign->px() )));
|
||||||
|
|
||||||
|
Cell* cell = parser->earlyGetCell( foreign->cellName() );
|
||||||
|
|
||||||
|
Gds::load( parser->getLibrary(), parser->getForeignPath()
|
||||||
|
, Gds::NoGdsPrefix|Gds::NoBlockages|Gds::Layer_0_IsBoundary);
|
||||||
|
for ( Net* net : cell->getNets() ) {
|
||||||
|
if (net->isPower ()) parser->setGdsPower ( net );
|
||||||
|
if (net->isGround()) parser->setGdsGround( net );
|
||||||
|
if (parser->getForeignPosition() != Point(0,0)) {
|
||||||
|
for ( Component* component : net->getComponents() ) {
|
||||||
|
component->translate( parser->getForeignPosition().getX()
|
||||||
|
, parser->getForeignPosition().getY() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LefParser::_obstructionCbk ( lefrCallbackType_e c, lefiObstruction* obstruction, lefiUserData ud )
|
int LefParser::_obstructionCbk ( lefrCallbackType_e c, lefiObstruction* obstruction, lefiUserData ud )
|
||||||
{
|
{
|
||||||
LefParser* parser = (LefParser*)ud;
|
LefParser* parser = (LefParser*)ud;
|
||||||
|
@ -600,33 +639,16 @@ namespace {
|
||||||
AllianceFramework* af = AllianceFramework::get();
|
AllianceFramework* af = AllianceFramework::get();
|
||||||
LefParser* parser = (LefParser*)ud;
|
LefParser* parser = (LefParser*)ud;
|
||||||
|
|
||||||
parser->setCellGauge( NULL );
|
parser->setCellGauge( nullptr );
|
||||||
|
|
||||||
string cellName = macro->name();
|
string cellName = macro->name();
|
||||||
DbU::Unit width = 0;
|
DbU::Unit width = 0;
|
||||||
DbU::Unit height = 0;
|
DbU::Unit height = 0;
|
||||||
Cell* cell = parser->getCell();
|
Cell* cell = parser->earlyGetCell();
|
||||||
|
|
||||||
if (cell) {
|
if (cell->getName() != Name(cellName)) {
|
||||||
|
cerr << cell << " -> " << cellName << endl;
|
||||||
cell->setName( cellName );
|
cell->setName( cellName );
|
||||||
} else {
|
|
||||||
cell = Cell::create( parser->getLibrary(true), cellName );
|
|
||||||
parser->setCell( cell );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not parser->getForeignPath().empty()) {
|
|
||||||
Gds::load( parser->getLibrary(), parser->getForeignPath()
|
|
||||||
, Gds::NoGdsPrefix|Gds::NoBlockages|Gds::Layer_0_IsBoundary);
|
|
||||||
for ( Net* net : cell->getNets() ) {
|
|
||||||
if (net->isPower ()) parser->setGdsPower ( net );
|
|
||||||
if (net->isGround()) parser->setGdsGround( net );
|
|
||||||
if (parser->getForeignPosition() != Point(0,0)) {
|
|
||||||
for ( Component* component : net->getComponents() ) {
|
|
||||||
component->translate( parser->getForeignPosition().getX()
|
|
||||||
, parser->getForeignPosition().getY() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (macro->hasSize()) {
|
if (macro->hasSize()) {
|
||||||
|
@ -673,7 +695,9 @@ namespace {
|
||||||
| Catalog::State::InMemory
|
| Catalog::State::InMemory
|
||||||
| Catalog::State::TerminalNetlist, true );
|
| Catalog::State::TerminalNetlist, true );
|
||||||
cell->setTerminalNetlist( true );
|
cell->setTerminalNetlist( true );
|
||||||
parser->setCell( NULL );
|
parser->setCell ( nullptr );
|
||||||
|
parser->setGdsPower ( nullptr );
|
||||||
|
parser->setGdsGround( nullptr );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -689,7 +713,7 @@ namespace {
|
||||||
|
|
||||||
//cerr << " @ _pinCbk: " << pin->name() << endl;
|
//cerr << " @ _pinCbk: " << pin->name() << endl;
|
||||||
|
|
||||||
if (not parser->getCell()) parser->setCell( Cell::create( parser->getLibrary(true), "LefImportTmpCell" ) );
|
parser->earlyGetCell();
|
||||||
|
|
||||||
Net* net = nullptr;
|
Net* net = nullptr;
|
||||||
Net::Type netType = Net::Type::UNDEFINED;
|
Net::Type netType = Net::Type::UNDEFINED;
|
||||||
|
@ -718,7 +742,7 @@ namespace {
|
||||||
net->setName( pin->name() );
|
net->setName( pin->name() );
|
||||||
parser->setGdsGround( nullptr );
|
parser->setGdsGround( nullptr );
|
||||||
} else {
|
} else {
|
||||||
net = Net::create( parser->getCell(), pin->name() );
|
net = parser->earlyGetNet( pin->name() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
net->setExternal( true );
|
net->setExternal( true );
|
||||||
|
|
Loading…
Reference in New Issue