From d99d797a40f2177ef4f396c950ab79889faed694 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 16 Jul 2018 19:43:44 +0200 Subject: [PATCH] Debugged the GDSII driver. Now working with Cadence. * Bug: In CRL::GdsDriver::GdsStream two bugs : 1. The tm fields are int but must be casted into uint16_t in BGNLIB and BGNSTR. 2. The mandatory LIBNAME record was missing. 3. We also force, for now the dbu to be 1000 and the UU to be 1um. --- crlcore/src/ccore/gds/GdsDriver.cpp | 82 +++++++++++++++++------------ 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/crlcore/src/ccore/gds/GdsDriver.cpp b/crlcore/src/ccore/gds/GdsDriver.cpp index ff91da65..6a0c5cfc 100644 --- a/crlcore/src/ccore/gds/GdsDriver.cpp +++ b/crlcore/src/ccore/gds/GdsDriver.cpp @@ -329,11 +329,13 @@ namespace { public: GdsStream ( string filename ); ~GdsStream (); + inline int32_t toGdsDbu ( DbU::Unit ) const; static inline GdsRecord PROPATTR ( int16_t ); static inline GdsRecord DATATYPE ( int16_t ); static inline GdsRecord PROPVALUE ( string ); static inline GdsRecord STRNAME ( string ); static inline GdsRecord STRNAME ( const Name& ); + static inline GdsRecord LIBNAME ( string ); static inline GdsRecord SNAME ( string ); static inline GdsRecord SNAME ( const Name& ); GdsStream& operator<< ( const GdsRecord& ); @@ -345,6 +347,8 @@ namespace { GdsStream& operator<< ( const Transformation& ); private: ofstream _ostream; + double _dbuPerUu; + double _metricDbU; }; @@ -359,12 +363,16 @@ namespace { inline GdsRecord GdsStream::PROPVALUE ( string s ) { return GdsRecord(GdsRecord::PROPVALUE,s); } inline GdsRecord GdsStream::STRNAME ( string s ) { return GdsRecord(GdsRecord::STRNAME,s); } inline GdsRecord GdsStream::STRNAME ( const Name& n ) { return GdsRecord(GdsRecord::STRNAME,getString(n)); } + inline GdsRecord GdsStream::LIBNAME ( string s ) { return GdsRecord(GdsRecord::LIBNAME,s); } inline GdsRecord GdsStream::SNAME ( string s ) { return GdsRecord(GdsRecord::SNAME,s); } inline GdsRecord GdsStream::SNAME ( const Name& n ) { return GdsRecord(GdsRecord::SNAME,getString(n)); } + inline int32_t GdsStream::toGdsDbu ( DbU::Unit v ) const { return DbU::toPhysical( v, DbU::UnitPower::Unity ) / _metricDbU; } GdsStream::GdsStream ( string filename ) - : _ostream() + : _ostream () + , _dbuPerUu (Cfg::getParamDouble("gdsDriver.dbuPerUu" ,0.001)->asDouble()) // 1000 + , _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um. { _ostream.open( filename, ios_base::out ); @@ -377,25 +385,29 @@ namespace { record = GdsRecord( GdsRecord::BGNLIB ); // Last modification time. - record.push( now->tm_year+1900 ); - record.push( now->tm_mon ); - record.push( now->tm_mday ); - record.push( now->tm_hour ); - record.push( now->tm_sec ); + record.push( (uint16_t)now->tm_year+1900 ); + record.push( (uint16_t)now->tm_mon ); + record.push( (uint16_t)now->tm_mday ); + record.push( (uint16_t)now->tm_hour ); + record.push( (uint16_t)now->tm_sec ); // Last access time. - record.push( now->tm_year+1900 ); - record.push( now->tm_mon ); - record.push( now->tm_mday ); - record.push( now->tm_hour ); - record.push( now->tm_sec ); + record.push( (uint16_t)now->tm_year+1900 ); + record.push( (uint16_t)now->tm_mon ); + record.push( (uint16_t)now->tm_mday ); + record.push( (uint16_t)now->tm_hour ); + record.push( (uint16_t)now->tm_sec ); _ostream << record; + _ostream << LIBNAME( "LIB" ); + // Generate a GDSII which coordinates are relatives to the um. double gridPerUu = 10e-6 / DbU::getPhysicalsPerGrid(); record = GdsRecord( GdsRecord::UNITS ); - record.push( gridPerUu ); - record.push( DbU::getPhysicalsPerGrid() ); + record.push( _dbuPerUu ); + record.push( _metricDbU ); + //record.push( gridPerUu ); + //record.push( DbU::getPhysicalsPerGrid() ); _ostream << record; } @@ -474,8 +486,8 @@ namespace { } record = GdsRecord( GdsRecord::XY ); - record.push( (int32_t)DbU::toGrid(transf.getTx()) ); - record.push( (int32_t)DbU::toGrid(transf.getTy()) ); + record.push( (int32_t)toGdsDbu(transf.getTx()) ); + record.push( (int32_t)toGdsDbu(transf.getTy()) ); _ostream << record; return *this; @@ -493,8 +505,8 @@ namespace { case 2: p = Point( box.getXMax(), box.getYMax() ); break; case 3: p = Point( box.getXMax(), box.getYMin() ); break; } - record.push( (int32_t)DbU::toGrid(p.getX()) ); - record.push( (int32_t)DbU::toGrid(p.getY()) ); + record.push( (int32_t)toGdsDbu(p.getX()) ); + record.push( (int32_t)toGdsDbu(p.getY()) ); } _ostream << record; return *this; @@ -506,11 +518,11 @@ namespace { GdsRecord record ( GdsRecord::XY ); Point first = points.getFirst(); for ( Point p : points ) { - record.push( (int32_t)DbU::toGrid(p.getX()) ); - record.push( (int32_t)DbU::toGrid(p.getY()) ); + record.push( (int32_t)toGdsDbu(p.getX()) ); + record.push( (int32_t)toGdsDbu(p.getY()) ); } - record.push( (int32_t)DbU::toGrid(first.getX()) ); - record.push( (int32_t)DbU::toGrid(first.getY()) ); + record.push( (int32_t)toGdsDbu(first.getX()) ); + record.push( (int32_t)toGdsDbu(first.getY()) ); _ostream << record; return *this; } @@ -520,11 +532,11 @@ namespace { { GdsRecord record ( GdsRecord::XY ); for ( Point p : points ) { - record.push( (int32_t)DbU::toGrid(p.getX()) ); - record.push( (int32_t)DbU::toGrid(p.getY()) ); + record.push( (int32_t)toGdsDbu(p.getX()) ); + record.push( (int32_t)toGdsDbu(p.getY()) ); } - record.push( (int32_t)DbU::toGrid(points[0].getX()) ); - record.push( (int32_t)DbU::toGrid(points[0].getY()) ); + record.push( (int32_t)toGdsDbu(points[0].getX()) ); + record.push( (int32_t)toGdsDbu(points[0].getY()) ); _ostream << record; return *this; } @@ -537,17 +549,17 @@ namespace { GdsRecord record ( GdsRecord::BGNSTR ); // Last modification time. - record.push( now->tm_year+1900 ); - record.push( now->tm_mon ); - record.push( now->tm_mday); - record.push( now->tm_hour); - record.push( now->tm_sec ); + record.push( (uint16_t)now->tm_year+1900 ); + record.push( (uint16_t)now->tm_mon ); + record.push( (uint16_t)now->tm_mday); + record.push( (uint16_t)now->tm_hour); + record.push( (uint16_t)now->tm_sec ); // Last access time. - record.push( now->tm_year+1900 ); - record.push( now->tm_mon ); - record.push( now->tm_mday); - record.push( now->tm_hour); - record.push( now->tm_sec ); + record.push( (uint16_t)now->tm_year+1900 ); + record.push( (uint16_t)now->tm_mon ); + record.push( (uint16_t)now->tm_mday); + record.push( (uint16_t)now->tm_hour); + record.push( (uint16_t)now->tm_sec ); _ostream << record; _ostream << STRNAME(cell->getName());