Better management of discrepencies bewteen LEF & techno layers.

* Change: In CRL::LefImport::LefParser, layers defined in the LEF file
    are matched *in order* to the ones from the technology *in order*
    (not by name matching). But if there is a mismatch, that is more
    layers in the techno than in LEF, we got a shift. Now we can tell
    the parser to ignore a set of layers by setting up the configuration
    variable:
       LefImport.unmatchedLayers = 'DIFFP,POLY2,SMURF'
This commit is contained in:
Jean-Paul Chaput 2022-10-27 19:46:29 +02:00
parent 81920c622e
commit 775b6bf1fc
1 changed files with 33 additions and 0 deletions

View File

@ -79,6 +79,7 @@ namespace {
LefParser ( string file, string libraryName ); LefParser ( string file, string libraryName );
~LefParser (); ~LefParser ();
inline bool isVH () const; inline bool isVH () const;
bool isUnmatchedLayer ( string );
Library* createLibrary (); Library* createLibrary ();
inline string getLibraryName () const; inline string getLibraryName () const;
inline Library* getLibrary ( bool create=false ); inline Library* getLibrary ( bool create=false );
@ -129,6 +130,7 @@ namespace {
double _unitsMicrons; double _unitsMicrons;
map< string, vector<Segment*> > _pinSegments; map< string, vector<Segment*> > _pinSegments;
static map<string,Layer*> _layerLut; static map<string,Layer*> _layerLut;
vector<string> _unmatchedLayers;
vector<string> _errors; vector<string> _errors;
int _nthMetal; int _nthMetal;
int _nthCut; int _nthCut;
@ -204,6 +206,15 @@ namespace {
} }
bool LefParser::isUnmatchedLayer ( string layerName )
{
for ( string layer : _unmatchedLayers ) {
if (layer == layerName) return true;
}
return false;
}
LefParser::LefParser ( string file, string libraryName ) LefParser::LefParser ( string file, string libraryName )
: _file (file) : _file (file)
, _libraryName (libraryName) , _libraryName (libraryName)
@ -212,6 +223,7 @@ namespace {
, _net (NULL) , _net (NULL)
, _busBits ("()") , _busBits ("()")
, _unitsMicrons (0.01) , _unitsMicrons (0.01)
, _unmatchedLayers ()
, _errors () , _errors ()
, _nthMetal (0) , _nthMetal (0)
, _nthCut (0) , _nthCut (0)
@ -228,6 +240,18 @@ namespace {
if (not _cellGauge) if (not _cellGauge)
throw Error( "LefParser::LefParser(): No default cell gauge defined in Alliance framework." ); throw Error( "LefParser::LefParser(): No default cell gauge defined in Alliance framework." );
string unmatcheds = Cfg::getParamString("LefImport.unmatchedLayers","")->asString();
if (not unmatcheds.empty()) {
size_t ibegin = 0;
size_t iend = unmatcheds.find( ',', ibegin );
while (iend != string::npos) {
_unmatchedLayers.push_back( unmatcheds.substr(ibegin,iend-ibegin) );
ibegin = iend+1;
iend = unmatcheds.find( ',', ibegin );
}
_unmatchedLayers.push_back( unmatcheds.substr(ibegin) );
}
lefrInit(); lefrInit();
lefrSetUnitsCbk ( _unitsCbk ); lefrSetUnitsCbk ( _unitsCbk );
@ -295,6 +319,10 @@ namespace {
if (lefType == "CUT") { if (lefType == "CUT") {
Layer* layer = techno->getNthCut( parser->getNthCut() ); Layer* layer = techno->getNthCut( parser->getNthCut() );
while (parser->isUnmatchedLayer(getString(layer->getName()))) {
parser->incNthCut();
layer = techno->getNthCut( parser->getNthCut() );
}
if (layer) { if (layer) {
parser->addLayer( lefLayer->name(), layer ); parser->addLayer( lefLayer->name(), layer );
parser->incNthCut(); parser->incNthCut();
@ -305,6 +333,11 @@ namespace {
if (lefType == "ROUTING") { if (lefType == "ROUTING") {
Layer* layer = techno->getNthMetal( parser->getNthMetal() ); Layer* layer = techno->getNthMetal( parser->getNthMetal() );
while (parser->isUnmatchedLayer(getString(layer->getName()))) {
parser->incNthMetal();
layer = techno->getNthMetal( parser->getNthMetal() );
}
if (layer) { if (layer) {
BasicLayer* basicLayer = layer->getBasicLayers().getFirst(); BasicLayer* basicLayer = layer->getBasicLayers().getFirst();
parser->addLayer( lefLayer->name(), basicLayer ); parser->addLayer( lefLayer->name(), basicLayer );