From 81920c622e3826233bf0dd19e22e25186c76ad02 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 27 Oct 2022 19:45:20 +0200 Subject: [PATCH] Stricter layer management in the GDS parser. * In CRL::GdsStream::_staticInit(), all the layers where added to the translation table, whether or not they where configured for the GDS stream. So the non GDS configured layers got a GDS layer id of 0 and were using this case. Either overwriting the legit layer or creating a new one while it should have been invalid. Now we check for the hasGds() predicate of the layers. * In CRL::GdsStream, add a new option to tell that, layer id 0, if undefined, may be used as the definition of the boudary of the cell (abutment box). * In CRL::PyGds, now also export the flags to the Python interface. --- crlcore/src/ccore/crlcore/Gds.h | 16 ++-- crlcore/src/ccore/gds/GdsParser.cpp | 120 +++++++++++++++++++++++----- crlcore/src/pyCRL/PyGds.cpp | 15 +++- crlcore/src/pyCRL/crlcore/PyGds.h | 15 ++-- 4 files changed, 126 insertions(+), 40 deletions(-) diff --git a/crlcore/src/ccore/crlcore/Gds.h b/crlcore/src/ccore/crlcore/Gds.h index d4401841..959ba926 100644 --- a/crlcore/src/ccore/crlcore/Gds.h +++ b/crlcore/src/ccore/crlcore/Gds.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2018-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2018-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -13,11 +13,8 @@ // | C++ Header : "./crlcore/Gds.h" | // +-----------------------------------------------------------------+ - -#ifndef CRL_GDS_H -#define CRL_GDS_H - -#include +#pragma once +#include namespace Hurricane { @@ -33,12 +30,13 @@ namespace CRL { class Gds { + public: + static const uint32_t NoGdsPrefix = (1<<0); + static const uint32_t Layer_0_IsBoundary = (1<<1); public: static bool save ( Cell* ); - static bool load ( Library*, std::string gdsPath ); + static bool load ( Library*, std::string gdsPath, uint32_t flags=0 ); }; } // CRL namespace. - -# endif diff --git a/crlcore/src/ccore/gds/GdsParser.cpp b/crlcore/src/ccore/gds/GdsParser.cpp index 8a7a9f3a..07941574 100644 --- a/crlcore/src/ccore/gds/GdsParser.cpp +++ b/crlcore/src/ccore/gds/GdsParser.cpp @@ -648,7 +648,9 @@ namespace { static const Layer* gdsToLayer ( uint16_t gdsLayer, uint16_t datatype ); public: static void _staticInit (); - GdsStream ( string gdsPath ); + GdsStream ( string gdsPath, uint32_t flags ); + inline bool useGdsPrefix () const; + inline bool useLayer0AsBoundary () const; inline bool isValidSyntax () const; bool misplacedRecord (); inline void resetStrans (); @@ -666,6 +668,7 @@ namespace { bool readTextbody ( const Layer* ); bool readStrans (); bool readProperty (); + void xyToAbutmentBox (); void xyToComponent ( const Layer* ); void xyToPath ( uint16_t pathtype , const Layer* @@ -693,6 +696,7 @@ namespace { private: static map _gdsLayerTable; vector _delayedInstances; + uint32_t _flags; string _gdsPath; ifstream _stream; GdsRecord _record; @@ -730,8 +734,10 @@ namespace { void GdsStream::_staticInit () { for ( const BasicLayer* layer : DataBase::getDB()->getTechnology()->getBasicLayers() ) { - uint32_t gdsNumber = (layer->getGds2Layer() << 16) + layer->getGds2Datatype(); - _gdsLayerTable[gdsNumber] = layer; + if (layer->hasGds()) { + uint32_t gdsNumber = (layer->getGds2Layer() << 16) + layer->getGds2Datatype(); + _gdsLayerTable[gdsNumber] = layer; + } } } @@ -749,11 +755,14 @@ namespace { } - inline bool GdsStream::isValidSyntax () const { return _validSyntax; } + inline bool GdsStream::isValidSyntax () const { return _validSyntax; } + inline bool GdsStream::useGdsPrefix () const { return not(_flags & Gds::NoGdsPrefix); } + inline bool GdsStream::useLayer0AsBoundary () const { return (_flags & Gds::Layer_0_IsBoundary); } - GdsStream::GdsStream ( string gdsPath ) + GdsStream::GdsStream ( string gdsPath, uint32_t flags ) : _delayedInstances() + , _flags (flags) , _gdsPath (gdsPath) , _stream () , _record () @@ -890,11 +899,12 @@ namespace { if (_record.isSTRNAME()) { if (_library) { - string cellName = "gds_" + _record.getName(); + string cellName = _record.getName(); + if (useGdsPrefix()) cellName.insert( 0, "gds_" ); _cell = _library->getCell( cellName ); if (not _cell) { - cparanoid << Warning( "GdsStream::readStructure(): No Cell named \"gds_%s\" in Library \"%s\" (created)." - , _record.getName().c_str() + cparanoid << Warning( "GdsStream::readStructure(): No Cell named \"%s\" in Library \"%s\" (created)." + , cellName.c_str() , getString(_library).c_str() ) << endl; _cell = Cell::create( _library, cellName ); @@ -969,11 +979,13 @@ namespace { } const Layer* layer = gdsToLayer( gdsLayer, gdsDatatype ); - cdebug_log(101,0) << "Layer id+datatype:" << gdsLayer << "+" << gdsDatatype << " " << layer << endl; - if (not layer) { - cerr << Error( "GdsStream::readLayerAndDatatype(): No BasicLayer id:%d+%d in GDS conversion table (skipped)." - , gdsLayer, gdsDatatype - ) << endl; + if ((gdsLayer == 0) and not useLayer0AsBoundary()) { + cdebug_log(101,0) << "Layer id+datatype:" << gdsLayer << "+" << gdsDatatype << " " << layer << endl; + if (not layer) { + cerr << Error( "GdsStream::readLayerAndDatatype(): No BasicLayer id:%d+%d in GDS conversion table (skipped)." + , gdsLayer, gdsDatatype + ) << endl; + } } return layer; @@ -1105,8 +1117,13 @@ namespace { } if (_record.isXY()) { - if (_cell and layer) xyToComponent( layer ); - else _stream >> _record; + if (_cell and layer) + xyToComponent( layer ); + else if (not layer and useLayer0AsBoundary()) { + xyToAbutmentBox(); + } + else + _stream >> _record; } else { _validSyntax = false; cdebug_tabw(101,-1); @@ -1240,8 +1257,9 @@ namespace { // << " XR:" << _xReflection << " angle:" << _angle // << " " << Transformation(xpos,ypos,orient) // << " in " << _cell << endl; + if (useGdsPrefix()) masterName.insert( 0, "gds_" ); _delayedInstances.push_back( DelayedInstance( _cell - , "gds_" + masterName + , masterName , Transformation(xpos,ypos,orient)) ); } @@ -1379,6 +1397,70 @@ namespace { } + void GdsStream::xyToAbutmentBox () + { + DbU::Unit oneGrid = DbU::fromGrid( 1 ); + + vector points; + vector coordinates = _record.getInt32s(); + vector offgrids; + for ( size_t i=0 ; i> _record; + + if ( (_record.getType() == GdsRecord::ENDEL) + or (_record.getType() == GdsRecord::STRING)) { + //_stream >> _record; + } else { + _validSyntax = false; + return; + } + + if (_record.getType() == GdsRecord::TEXT) { + _stream >> _record; + readText(); + } else + _skipENDEL = true; + + bool isRectilinear = true; + for ( size_t i=1 ; isetAbutmentBox( ab ); + cdebug_log(101,0) << "| Abutment box =" << ab << endl; + } + } + + void GdsStream::xyToComponent ( const Layer* layer ) { DbU::Unit oneGrid = DbU::fromGrid( 1 ); @@ -1651,7 +1733,7 @@ namespace { for ( const PinPoint& ref : netPins.second ) { const Layer* layer = ref._layer; string layerName = getString( layer->getName() ); - if (layerName.substr(layerName.size()-4) == ".pin") { + if ((layerName.size() > 4) and layerName.substr(layerName.size()-4) == ".pin") { layer = DataBase::getDB()->getTechnology()->getLayer( layerName.substr(0,layerName.size()-4) ); } cdebug_log(101,0) << "Looking for components of \"" << net->getName() @@ -1737,13 +1819,13 @@ namespace CRL { // ------------------------------------------------------------------- // Class : "CRL::Gds". - bool Gds::load ( Library* library, string gdsPath ) + bool Gds::load ( Library* library, string gdsPath, uint32_t flags ) { //DebugSession::open( 101, 110 ); UpdateSession::open(); Contact::disableCheckMinSize(); - GdsStream gstream ( gdsPath ); + GdsStream gstream ( gdsPath, flags ); if (not gstream.read( library )) cerr << Error( "Gds::load(): An error occurred while reading GDSII stream\n" diff --git a/crlcore/src/pyCRL/PyGds.cpp b/crlcore/src/pyCRL/PyGds.cpp index bf6d229a..1e2d7270 100644 --- a/crlcore/src/pyCRL/PyGds.cpp +++ b/crlcore/src/pyCRL/PyGds.cpp @@ -87,13 +87,14 @@ extern "C" { { cdebug_log(30,0) << "PyGds_load()" << endl; - char* path = NULL; + char* path = NULL; + uint32_t flags = 0; HTRY PyObject* pyLibrary = NULL; - if (PyArg_ParseTuple( args, "Os:Gds.load", &pyLibrary, &path )) { + if (PyArg_ParseTuple( args, "Os|I:Gds.load", &pyLibrary, &path, &flags )) { if (IsPyLibrary(pyLibrary)) { - Gds::load( PYLIBRARY_O(pyLibrary), string(path) ); + Gds::load( PYLIBRARY_O(pyLibrary), string(path), flags ); } else { PyErr_SetString( ConstructorError, "Gds.load(): Bad parameter type (not a Library)." ); return NULL; @@ -135,6 +136,14 @@ extern "C" { PyTypeObjectDefinitionsOfModule(CRL,Gds) + extern void PyGds_postModuleInit () + { + PyObject* constant; + LoadObjectConstant(PyTypeGds.tp_dict,Gds::NoGdsPrefix ,"NoGdsPrefix"); + LoadObjectConstant(PyTypeGds.tp_dict,Gds::Layer_0_IsBoundary,"Layer_0_IsBoundary"); + } + + #endif // End of Shared Library Code Part. } // extern "C". diff --git a/crlcore/src/pyCRL/crlcore/PyGds.h b/crlcore/src/pyCRL/crlcore/PyGds.h index 5ade37c9..9d97aa67 100644 --- a/crlcore/src/pyCRL/crlcore/PyGds.h +++ b/crlcore/src/pyCRL/crlcore/PyGds.h @@ -2,22 +2,20 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2018-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2018-2022, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | // | Alliance / Hurricane Interface | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./crlcore/PyGds.h" | +// | C++ Header : "./crlcore/PyGds.h" | // +-----------------------------------------------------------------+ -#ifndef CRL_PY_GDS_H -#define CRL_PY_GDS_H - +#pragma once #include "hurricane/isobar/PyHurricane.h" #include "crlcore/Gds.h" @@ -41,7 +39,8 @@ extern "C" { extern PyTypeObject PyTypeGds; extern PyMethodDef PyGds_Methods[]; - extern void PyGds_LinkPyType(); + extern void PyGds_LinkPyType (); + extern void PyGds_postModuleInit (); #define IsPyGds(v) ( (v)->ob_type == &PyTypeGds ) @@ -51,5 +50,3 @@ extern "C" { } // extern "C". } // Hurricane namespace. - -#endif // CRL_PY_GDS_H