Added support for external connectors in GDS parser/driver.
* New: In CRL::GdsDriver, create TEXT record under each external Net component. Seems to be the aknoweledged way to signal external pins. * New: In CRL::GdsParser, read TEXT record and create Net and external components that are in the same layer and at the same position.
This commit is contained in:
parent
8fdaf47f3d
commit
ead11f8b93
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
#include <cfenv>
|
#include <cfenv>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -36,6 +37,7 @@ using namespace std;
|
||||||
#include "hurricane/Polygon.h"
|
#include "hurricane/Polygon.h"
|
||||||
#include "hurricane/Pad.h"
|
#include "hurricane/Pad.h"
|
||||||
#include "hurricane/Net.h"
|
#include "hurricane/Net.h"
|
||||||
|
#include "hurricane/NetExternalComponents.h"
|
||||||
#include "hurricane/Cell.h"
|
#include "hurricane/Cell.h"
|
||||||
#include "hurricane/Plug.h"
|
#include "hurricane/Plug.h"
|
||||||
#include "hurricane/Instance.h"
|
#include "hurricane/Instance.h"
|
||||||
|
@ -262,7 +264,7 @@ namespace {
|
||||||
//static const uint16_t PATH = 0x0900 | NoData;
|
//static const uint16_t PATH = 0x0900 | NoData;
|
||||||
static const uint16_t SREF = 0x0a00 | NoData;
|
static const uint16_t SREF = 0x0a00 | NoData;
|
||||||
//static const uint16_t AREF = 0x0b00 | NoData;
|
//static const uint16_t AREF = 0x0b00 | NoData;
|
||||||
//static const uint16_t TEXT = 0x0c00 | NoData;
|
static const uint16_t TEXT = 0x0c00 | NoData;
|
||||||
static const uint16_t LAYER = 0x0d00 | TwoByteInteger;
|
static const uint16_t LAYER = 0x0d00 | TwoByteInteger;
|
||||||
static const uint16_t DATATYPE = 0x0e00 | TwoByteInteger;
|
static const uint16_t DATATYPE = 0x0e00 | TwoByteInteger;
|
||||||
//static const uint16_t WIDTH = 0x0f00 | FourByteInteger;
|
//static const uint16_t WIDTH = 0x0f00 | FourByteInteger;
|
||||||
|
@ -272,10 +274,10 @@ namespace {
|
||||||
//static const uint16_t COLROW = 0x1300 | TwoByteInteger;
|
//static const uint16_t COLROW = 0x1300 | TwoByteInteger;
|
||||||
//static const uint16_t TEXTNODE = 0x1400 | NoData; // Unused.
|
//static const uint16_t TEXTNODE = 0x1400 | NoData; // Unused.
|
||||||
//static const uint16_t NODE = 0x1500 | NoData;
|
//static const uint16_t NODE = 0x1500 | NoData;
|
||||||
//static const uint16_t TEXTTYPE = 0x1600 | TwoByteInteger;
|
static const uint16_t TEXTTYPE = 0x1600 | TwoByteInteger;
|
||||||
//static const uint16_t PRESENTATION = 0x1700 | BitArray;
|
static const uint16_t PRESENTATION = 0x1700 | BitArray;
|
||||||
//static const uint16_t SPACING = 0x1800 | NoData; // Discontinued.
|
//static const uint16_t SPACING = 0x1800 | NoData; // Discontinued.
|
||||||
//static const uint16_t STRING = 0x1900 | String;
|
static const uint16_t STRING = 0x1900 | String;
|
||||||
static const uint16_t STRANS = 0x1a00 | BitArray;
|
static const uint16_t STRANS = 0x1a00 | BitArray;
|
||||||
//static const uint16_t MAG = 0x1b00 | EightByteReal;
|
//static const uint16_t MAG = 0x1b00 | EightByteReal;
|
||||||
static const uint16_t ANGLE = 0x1c00 | EightByteReal;
|
static const uint16_t ANGLE = 0x1c00 | EightByteReal;
|
||||||
|
@ -428,13 +430,27 @@ namespace {
|
||||||
|
|
||||||
void GdsRecord::toStream ( ostream& stream ) const
|
void GdsRecord::toStream ( ostream& stream ) const
|
||||||
{
|
{
|
||||||
|
static size_t count = 0;
|
||||||
|
|
||||||
uint16_t length = (uint16_t)( _bytes.size()+2 );
|
uint16_t length = (uint16_t)( _bytes.size()+2 );
|
||||||
const unsigned char* bytearray = reinterpret_cast<const unsigned char*>( &length );
|
const unsigned char* bytearray = reinterpret_cast<const unsigned char*>( &length );
|
||||||
|
|
||||||
|
// char buffer[512];
|
||||||
|
// sprintf( buffer, "0x%02x", bytearray[1] );
|
||||||
|
// cerr << setw(6) << hex << count++ << " | " << buffer << endl;
|
||||||
|
// sprintf( buffer, "0x%02x", bytearray[0] );
|
||||||
|
// cerr << setw(6) << hex << count++ << " | " << buffer << endl;
|
||||||
|
|
||||||
// Little endian (x86).
|
// Little endian (x86).
|
||||||
stream.put( bytearray[1] );
|
stream.put( bytearray[1] );
|
||||||
stream.put( bytearray[0] );
|
stream.put( bytearray[0] );
|
||||||
|
|
||||||
for ( char byte : _bytes ) stream.put( byte );
|
for ( unsigned char byte : _bytes ) {
|
||||||
|
uint32_t b = byte;
|
||||||
|
// sprintf( buffer, "0x%02x", b );
|
||||||
|
// cerr << setw(6) << hex << count++ << " | " << buffer << endl;
|
||||||
|
stream.put( byte );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -452,25 +468,31 @@ namespace {
|
||||||
static const GdsRecord ENDEL;
|
static const GdsRecord ENDEL;
|
||||||
static const GdsRecord ENDSTR;
|
static const GdsRecord ENDSTR;
|
||||||
static const GdsRecord SREF;
|
static const GdsRecord SREF;
|
||||||
|
static const GdsRecord TEXT;
|
||||||
public:
|
public:
|
||||||
GdsStream ( string filename );
|
GdsStream ( string filename );
|
||||||
~GdsStream ();
|
~GdsStream ();
|
||||||
inline int32_t toGdsDbu ( DbU::Unit ) const;
|
inline int32_t toGdsDbu ( DbU::Unit ) const;
|
||||||
static inline GdsRecord PROPATTR ( int16_t );
|
static inline GdsRecord PROPATTR ( int16_t );
|
||||||
static inline GdsRecord DATATYPE ( int16_t );
|
static inline GdsRecord DATATYPE ( int16_t );
|
||||||
static inline GdsRecord PROPVALUE ( string );
|
static inline GdsRecord TEXTTYPE ( int16_t );
|
||||||
static inline GdsRecord STRNAME ( string );
|
static inline GdsRecord LAYER ( int16_t );
|
||||||
static inline GdsRecord STRNAME ( const Name& );
|
static inline GdsRecord PRESENTATION ( int16_t );
|
||||||
static inline GdsRecord LIBNAME ( string );
|
static inline GdsRecord PROPVALUE ( string );
|
||||||
static inline GdsRecord SNAME ( string );
|
static inline GdsRecord STRNAME ( string );
|
||||||
static inline GdsRecord SNAME ( const Name& );
|
static inline GdsRecord STRNAME ( const Name& );
|
||||||
GdsStream& operator<< ( const GdsRecord& );
|
static inline GdsRecord LIBNAME ( string );
|
||||||
GdsStream& operator<< ( const BasicLayer* );
|
static inline GdsRecord SNAME ( string );
|
||||||
GdsStream& operator<< ( const Box& );
|
static inline GdsRecord SNAME ( const Name& );
|
||||||
GdsStream& operator<< ( const Points );
|
static inline GdsRecord STRING ( const Name& );
|
||||||
GdsStream& operator<< ( const vector<Point>& points );
|
static inline GdsRecord STRING ( const string );
|
||||||
GdsStream& operator<< ( const Cell* );
|
GdsStream& operator<< ( const GdsRecord& );
|
||||||
GdsStream& operator<< ( const Transformation& );
|
GdsStream& operator<< ( const Box& );
|
||||||
|
GdsStream& operator<< ( const Points );
|
||||||
|
GdsStream& operator<< ( const Point& point );
|
||||||
|
GdsStream& operator<< ( const vector<Point>& points );
|
||||||
|
GdsStream& operator<< ( const Cell* );
|
||||||
|
GdsStream& operator<< ( const Transformation& );
|
||||||
private:
|
private:
|
||||||
ofstream _ostream;
|
ofstream _ostream;
|
||||||
double _dbuPerUu;
|
double _dbuPerUu;
|
||||||
|
@ -483,16 +505,22 @@ namespace {
|
||||||
const GdsRecord GdsStream::ENDEL = GdsRecord(GdsRecord::ENDEL);
|
const GdsRecord GdsStream::ENDEL = GdsRecord(GdsRecord::ENDEL);
|
||||||
const GdsRecord GdsStream::ENDSTR = GdsRecord(GdsRecord::ENDSTR);
|
const GdsRecord GdsStream::ENDSTR = GdsRecord(GdsRecord::ENDSTR);
|
||||||
const GdsRecord GdsStream::SREF = GdsRecord(GdsRecord::SREF);
|
const GdsRecord GdsStream::SREF = GdsRecord(GdsRecord::SREF);
|
||||||
|
const GdsRecord GdsStream::TEXT = GdsRecord(GdsRecord::TEXT);
|
||||||
|
|
||||||
inline GdsRecord GdsStream::PROPATTR ( int16_t v ) { return GdsRecord(GdsRecord::PROPATTR,v); }
|
inline GdsRecord GdsStream::PROPATTR ( int16_t v ) { return GdsRecord(GdsRecord::PROPATTR,v); }
|
||||||
inline GdsRecord GdsStream::DATATYPE ( int16_t v ) { return GdsRecord(GdsRecord::DATATYPE,v); }
|
inline GdsRecord GdsStream::DATATYPE ( int16_t v ) { return GdsRecord(GdsRecord::DATATYPE,v); }
|
||||||
inline GdsRecord GdsStream::PROPVALUE ( string s ) { return GdsRecord(GdsRecord::PROPVALUE,s); }
|
inline GdsRecord GdsStream::TEXTTYPE ( int16_t v ) { return GdsRecord(GdsRecord::TEXTTYPE,v); }
|
||||||
inline GdsRecord GdsStream::STRNAME ( string s ) { return GdsRecord(GdsRecord::STRNAME,s); }
|
inline GdsRecord GdsStream::LAYER ( int16_t v ) { return GdsRecord(GdsRecord::LAYER,v); }
|
||||||
inline GdsRecord GdsStream::STRNAME ( const Name& n ) { return GdsRecord(GdsRecord::STRNAME,getString(n)); }
|
inline GdsRecord GdsStream::PRESENTATION ( int16_t v ) { return GdsRecord(GdsRecord::PRESENTATION,v); }
|
||||||
inline GdsRecord GdsStream::LIBNAME ( string s ) { return GdsRecord(GdsRecord::LIBNAME,s); }
|
inline GdsRecord GdsStream::PROPVALUE ( string s ) { return GdsRecord(GdsRecord::PROPVALUE,s); }
|
||||||
inline GdsRecord GdsStream::SNAME ( string s ) { return GdsRecord(GdsRecord::SNAME,s); }
|
inline GdsRecord GdsStream::STRNAME ( string s ) { return GdsRecord(GdsRecord::STRNAME,s); }
|
||||||
inline GdsRecord GdsStream::SNAME ( const Name& n ) { return GdsRecord(GdsRecord::SNAME,getString(n)); }
|
inline GdsRecord GdsStream::STRNAME ( const Name& n ) { return GdsRecord(GdsRecord::STRNAME,getString(n)); }
|
||||||
inline int32_t GdsStream::toGdsDbu ( DbU::Unit v ) const
|
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 GdsRecord GdsStream::STRING ( const Name& n ) { return GdsRecord(GdsRecord::STRING,getString(n)); }
|
||||||
|
inline GdsRecord GdsStream::STRING ( const string s ) { return GdsRecord(GdsRecord::STRING,s); }
|
||||||
|
inline int32_t GdsStream::toGdsDbu ( DbU::Unit v ) const
|
||||||
{ return uint32_t( std::lrint( DbU::toPhysical( v, DbU::UnitPower::Unity ) / _metricDbU )); }
|
{ return uint32_t( std::lrint( DbU::toPhysical( v, DbU::UnitPower::Unity ) / _metricDbU )); }
|
||||||
|
|
||||||
|
|
||||||
|
@ -502,7 +530,7 @@ namespace {
|
||||||
, _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um.
|
, _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um.
|
||||||
{
|
{
|
||||||
std::fesetround( FE_TONEAREST );
|
std::fesetround( FE_TONEAREST );
|
||||||
_ostream.open( filename, ios_base::out );
|
_ostream.open( filename, ios_base::out|ios_base::binary );
|
||||||
|
|
||||||
GdsRecord record ( GdsRecord::HEADER );
|
GdsRecord record ( GdsRecord::HEADER );
|
||||||
record.push( (uint16_t)600 );
|
record.push( (uint16_t)600 );
|
||||||
|
@ -552,18 +580,22 @@ namespace {
|
||||||
{ _ostream << record; return *this; }
|
{ _ostream << record; return *this; }
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
GdsStream& GdsStream::operator<< ( const BasicLayer* layer )
|
GdsStream& GdsStream::operator<< ( const BasicLayer* layer )
|
||||||
{
|
{
|
||||||
|
cdebug_log(101,0) << "LAYER" << endl;
|
||||||
GdsRecord record ( GdsRecord::LAYER );
|
GdsRecord record ( GdsRecord::LAYER );
|
||||||
record.push( (int16_t)layer->getGds2Layer() );
|
record.push( (int16_t)layer->getGds2Layer() );
|
||||||
_ostream << record;
|
_ostream << record;
|
||||||
|
|
||||||
|
cdebug_log(101,0) << "DATATYPE" << endl;
|
||||||
record = GdsRecord( GdsRecord::DATATYPE );
|
record = GdsRecord( GdsRecord::DATATYPE );
|
||||||
record.push( (int16_t)layer->getGds2Datatype() );
|
record.push( (int16_t)layer->getGds2Datatype() );
|
||||||
_ostream << record;
|
_ostream << record;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
GdsStream& GdsStream::operator<< ( const Transformation& transf )
|
GdsStream& GdsStream::operator<< ( const Transformation& transf )
|
||||||
|
@ -657,6 +689,16 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GdsStream& GdsStream::operator<< ( const Point& point )
|
||||||
|
{
|
||||||
|
GdsRecord record ( GdsRecord::XY );
|
||||||
|
record.push( (int32_t)toGdsDbu(point.getX()) );
|
||||||
|
record.push( (int32_t)toGdsDbu(point.getY()) );
|
||||||
|
_ostream << record;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GdsStream& GdsStream::operator<< ( const vector<Point>& points )
|
GdsStream& GdsStream::operator<< ( const vector<Point>& points )
|
||||||
{
|
{
|
||||||
GdsRecord record ( GdsRecord::XY );
|
GdsRecord record ( GdsRecord::XY );
|
||||||
|
@ -720,7 +762,8 @@ namespace {
|
||||||
for ( const vector<Point>& subpolygon : subpolygons ) {
|
for ( const vector<Point>& subpolygon : subpolygons ) {
|
||||||
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
||||||
(*this) << BOUNDARY;
|
(*this) << BOUNDARY;
|
||||||
(*this) << layer;
|
(*this) << LAYER(layer->getGds2Layer());
|
||||||
|
(*this) << DATATYPE(layer->getGds2Datatype());
|
||||||
(*this) << subpolygon;
|
(*this) << subpolygon;
|
||||||
(*this) << ENDEL;
|
(*this) << ENDEL;
|
||||||
}
|
}
|
||||||
|
@ -730,7 +773,8 @@ namespace {
|
||||||
if (rectilinear) {
|
if (rectilinear) {
|
||||||
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
||||||
(*this) << BOUNDARY;
|
(*this) << BOUNDARY;
|
||||||
(*this) << layer;
|
(*this) << LAYER(layer->getGds2Layer());
|
||||||
|
(*this) << DATATYPE(layer->getGds2Datatype());
|
||||||
(*this) << rectilinear->getPoints();
|
(*this) << rectilinear->getPoints();
|
||||||
(*this) << ENDEL;
|
(*this) << ENDEL;
|
||||||
isOnGrid( component, rectilinear->getPoints() );
|
isOnGrid( component, rectilinear->getPoints() );
|
||||||
|
@ -740,7 +784,8 @@ namespace {
|
||||||
if (diagonal) {
|
if (diagonal) {
|
||||||
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
||||||
(*this) << BOUNDARY;
|
(*this) << BOUNDARY;
|
||||||
(*this) << layer;
|
(*this) << LAYER(layer->getGds2Layer());
|
||||||
|
(*this) << DATATYPE(layer->getGds2Datatype());
|
||||||
(*this) << diagonal->getContour();
|
(*this) << diagonal->getContour();
|
||||||
(*this) << ENDEL;
|
(*this) << ENDEL;
|
||||||
}
|
}
|
||||||
|
@ -753,10 +798,34 @@ namespace {
|
||||||
if ((bb.getWidth() == 0) or (bb.getHeight() == 0))
|
if ((bb.getWidth() == 0) or (bb.getHeight() == 0))
|
||||||
continue;
|
continue;
|
||||||
(*this) << BOUNDARY;
|
(*this) << BOUNDARY;
|
||||||
(*this) << layer;
|
(*this) << LAYER(layer->getGds2Layer());
|
||||||
|
(*this) << DATATYPE(layer->getGds2Datatype());
|
||||||
(*this) << bb;
|
(*this) << bb;
|
||||||
(*this) << ENDEL;
|
(*this) << ENDEL;
|
||||||
isOnGrid( component, bb );
|
isOnGrid( component, bb );
|
||||||
|
|
||||||
|
if (NetExternalComponents::isExternal(component)) {
|
||||||
|
string name = getString( component->getNet()->getName() );
|
||||||
|
if (name.size() > 511) {
|
||||||
|
cerr << getString(
|
||||||
|
Warning( "GdsStream::operator<<(): Truncate Net name to 511 first characters,\n"
|
||||||
|
" on \"%s\"."
|
||||||
|
, name.c_str() )) << endl;
|
||||||
|
name.erase( 511 );
|
||||||
|
}
|
||||||
|
// PRESENTATION: 0b000101 means font:00, vpres:01 (center), hpres:01 (center)
|
||||||
|
cdebug_log(101,0) << "TEXT" << endl;
|
||||||
|
(*this) << TEXT;
|
||||||
|
(*this) << LAYER(layer->getGds2Layer());
|
||||||
|
cdebug_log(101,0) << "TEXTTYPE" << endl;
|
||||||
|
(*this) << TEXTTYPE( 0 );
|
||||||
|
cdebug_log(101,0) << "TEXTYPE end record" << endl;
|
||||||
|
(*this) << PRESENTATION( 5 );
|
||||||
|
(*this) << bb.getCenter();
|
||||||
|
(*this) << STRING( name );
|
||||||
|
(*this) << ENDEL;
|
||||||
|
cdebug_log(101,0) << "TEXT ENDEL" << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -201,6 +202,8 @@ namespace {
|
||||||
void readString ();
|
void readString ();
|
||||||
void readUnits ();
|
void readUnits ();
|
||||||
void readLayer ();
|
void readLayer ();
|
||||||
|
void readWidth ();
|
||||||
|
void readPathtype ();
|
||||||
void readStrname ();
|
void readStrname ();
|
||||||
void readXy ();
|
void readXy ();
|
||||||
static string toStrType ( uint16_t );
|
static string toStrType ( uint16_t );
|
||||||
|
@ -211,6 +214,7 @@ namespace {
|
||||||
double _readDouble ();
|
double _readDouble ();
|
||||||
private:
|
private:
|
||||||
istream* _stream;
|
istream* _stream;
|
||||||
|
uint32_t _offset;
|
||||||
uint16_t _length;
|
uint16_t _length;
|
||||||
uint16_t _count;
|
uint16_t _count;
|
||||||
uint16_t _type;
|
uint16_t _type;
|
||||||
|
@ -220,6 +224,7 @@ namespace {
|
||||||
vector<int16_t> _int16s;
|
vector<int16_t> _int16s;
|
||||||
vector<int32_t> _int32s;
|
vector<int32_t> _int32s;
|
||||||
vector<double> _doubles;
|
vector<double> _doubles;
|
||||||
|
char _buffer[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,6 +298,7 @@ namespace {
|
||||||
|
|
||||||
GdsRecord::GdsRecord ()
|
GdsRecord::GdsRecord ()
|
||||||
: _stream (NULL)
|
: _stream (NULL)
|
||||||
|
, _offset (0)
|
||||||
, _length (0)
|
, _length (0)
|
||||||
, _count (0)
|
, _count (0)
|
||||||
, _type (0)
|
, _type (0)
|
||||||
|
@ -344,7 +350,7 @@ namespace {
|
||||||
case TEXT: readDummy( false ); break;
|
case TEXT: readDummy( false ); break;
|
||||||
case LAYER: readLayer(); break;
|
case LAYER: readLayer(); break;
|
||||||
case DATATYPE: readDummy( false ); break;
|
case DATATYPE: readDummy( false ); break;
|
||||||
case WIDTH: readDummy( false ); break;
|
case WIDTH: readWidth(); break;
|
||||||
case XY: readXy(); break;
|
case XY: readXy(); break;
|
||||||
case ENDEL: readDummy( false ); break;
|
case ENDEL: readDummy( false ); break;
|
||||||
case SNAME: readStrname(); break;
|
case SNAME: readStrname(); break;
|
||||||
|
@ -360,7 +366,7 @@ namespace {
|
||||||
case ANGLE: _doubles.push_back( _readDouble() ); break;
|
case ANGLE: _doubles.push_back( _readDouble() ); break;
|
||||||
case REFLIBS: readDummy( false ); break;
|
case REFLIBS: readDummy( false ); break;
|
||||||
case FONTS: readDummy( false ); break;
|
case FONTS: readDummy( false ); break;
|
||||||
case PATHTYPE: readDummy( false ); break;
|
case PATHTYPE: readPathtype(); break;
|
||||||
case GENERATIONS: readDummy( false ); break;
|
case GENERATIONS: readDummy( false ); break;
|
||||||
case ATTRTABLE: readDummy( false ); break;
|
case ATTRTABLE: readDummy( false ); break;
|
||||||
case STYPTABLE: readDummy( false ); break;
|
case STYPTABLE: readDummy( false ); break;
|
||||||
|
@ -389,7 +395,13 @@ namespace {
|
||||||
case LIBSECUR: readDummy( false ); break;
|
case LIBSECUR: readDummy( false ); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << " GdsRecord::read() " << toStrType(_type) << endl;
|
ostringstream s;
|
||||||
|
s << " (0x" << std::setfill('0') << std::setw(4) << std::hex << _type << ")";
|
||||||
|
cdebug_log(101,0) << "GdsRecord::read() " << toStrType(_type)
|
||||||
|
<< s.str()
|
||||||
|
<< " _bytes:" << _length
|
||||||
|
<< " (offset:" << (_offset-4) << ")"
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -417,9 +429,15 @@ namespace {
|
||||||
unsigned char bytes[ typeSize ];
|
unsigned char bytes[ typeSize ];
|
||||||
};
|
};
|
||||||
|
|
||||||
char bytes[typeSize];
|
unsigned char bytes[typeSize];
|
||||||
_stream->read( bytes, typeSize );
|
_stream->read( (char*)(&bytes[0]), typeSize );
|
||||||
_count += typeSize;
|
_count += typeSize;
|
||||||
|
|
||||||
|
// cdebug_log(101,0) << "GdsRecord::_readInt() " << endl;
|
||||||
|
// for ( size_t i=0 ; i<typeSize ; ++i ) {
|
||||||
|
// sprintf( _buffer, "0x%02x", bytes[i] );
|
||||||
|
// cdebug(101,0) << setw(6) << hex << _offset++ << " | " << _buffer << endl;
|
||||||
|
// }
|
||||||
|
|
||||||
UType uvalue;
|
UType uvalue;
|
||||||
// Little endian (x86).
|
// Little endian (x86).
|
||||||
|
@ -440,6 +458,12 @@ namespace {
|
||||||
_stream->read( bytes, 8 );
|
_stream->read( bytes, 8 );
|
||||||
_count += 8;
|
_count += 8;
|
||||||
|
|
||||||
|
// cdebug_log(101,0) << "GdsRecord::_readDouble() " << endl;
|
||||||
|
// for ( size_t i=0 ; i<8 ; ++i ) {
|
||||||
|
// sprintf( _buffer, "0x%02x", bytes[i] );
|
||||||
|
// cdebug(101,0) << setw(6) << hex << _offset++ << " | " << _buffer << endl;
|
||||||
|
// }
|
||||||
|
|
||||||
gdsUInt64 mantisse;
|
gdsUInt64 mantisse;
|
||||||
for ( size_t i=0 ; i<7 ; ++i ) mantisse.bytes[i] = bytes[7-i];
|
for ( size_t i=0 ; i<7 ; ++i ) mantisse.bytes[i] = bytes[7-i];
|
||||||
mantisse.bytes[7] = 0;
|
mantisse.bytes[7] = 0;
|
||||||
|
@ -456,31 +480,38 @@ namespace {
|
||||||
|
|
||||||
string GdsRecord::_readString ()
|
string GdsRecord::_readString ()
|
||||||
{
|
{
|
||||||
|
cdebug_log(101,0) << "GdsRecord::_readDouble() " << endl;
|
||||||
string s;
|
string s;
|
||||||
char c;
|
char c;
|
||||||
for ( ; _count<_length ; ++_count ) {
|
for ( ; _count<_length ; ++_count ) {
|
||||||
_stream->get( c );
|
_stream->get( c );
|
||||||
|
// sprintf( _buffer, "0x%02x", c );
|
||||||
|
// cdebug_log(101,0) << setw(6) << hex << _offset++ << " | " << _buffer << endl;
|
||||||
|
|
||||||
if (c != (char)0) s.push_back(c);
|
if (c != (char)0) s.push_back(c);
|
||||||
}
|
}
|
||||||
cerr << "GdsRecord::_readString(): \"" << s << "\"" << endl;
|
cdebug_log(101,0) << "GdsRecord::_readString(): \"" << s << "\"" << endl;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GdsRecord::readDummy ( bool showError )
|
void GdsRecord::readDummy ( bool showError )
|
||||||
{
|
{
|
||||||
|
cdebug_log(101,0) << "GdsRecord::readDummy() " << endl;
|
||||||
char c;
|
char c;
|
||||||
for ( ; _count<_length ; ++_count ) _stream->get( c );
|
for ( ; _count<_length ; ++_count ) {
|
||||||
|
_stream->get( c );
|
||||||
|
sprintf( _buffer, "0x%02x", c );
|
||||||
|
cdebug_log(101,0) << setw(6) << hex << _offset++ << " | " << _buffer << endl;
|
||||||
|
}
|
||||||
if (showError) {
|
if (showError) {
|
||||||
cerr << Error( "GdsRecord type %s unsupported.", toStrType(_type).c_str() ) << endl;
|
cdebug_log(101,0) << Error( "GdsRecord type %s unsupported.", toStrType(_type).c_str() ) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GdsRecord::readStrans ()
|
void GdsRecord::readStrans ()
|
||||||
{
|
{
|
||||||
|
|
||||||
const uint16_t XRMask = 0x8000;
|
const uint16_t XRMask = 0x8000;
|
||||||
uint16_t flags = _readInt<uint16_t>();
|
uint16_t flags = _readInt<uint16_t>();
|
||||||
_xReflection = (flags & XRMask);
|
_xReflection = (flags & XRMask);
|
||||||
|
@ -508,6 +539,14 @@ namespace {
|
||||||
{ _int16s.push_back( _readInt<uint16_t>() ); }
|
{ _int16s.push_back( _readInt<uint16_t>() ); }
|
||||||
|
|
||||||
|
|
||||||
|
void GdsRecord::readWidth ()
|
||||||
|
{ _int32s.push_back( _readInt<uint32_t>() ); }
|
||||||
|
|
||||||
|
|
||||||
|
void GdsRecord::readPathtype ()
|
||||||
|
{ _int16s.push_back( _readInt<uint16_t>() ); }
|
||||||
|
|
||||||
|
|
||||||
void GdsRecord::readXy ()
|
void GdsRecord::readXy ()
|
||||||
{ while ( _count < _length ) _int32s.push_back( _readInt<int32_t>() ); }
|
{ while ( _count < _length ) _int32s.push_back( _readInt<int32_t>() ); }
|
||||||
|
|
||||||
|
@ -607,12 +646,15 @@ namespace {
|
||||||
bool readNode ();
|
bool readNode ();
|
||||||
bool readBox ();
|
bool readBox ();
|
||||||
bool readText ();
|
bool readText ();
|
||||||
bool readTextbody ();
|
bool readTextbody ( const Layer* );
|
||||||
bool readStrans ();
|
bool readStrans ();
|
||||||
bool readProperty ();
|
bool readProperty ();
|
||||||
void xyToComponent ( const Layer* );
|
void xyToComponent ( const Layer* );
|
||||||
|
void xyToPath ( uint16_t pathtype, const Layer*, DbU::Unit width );
|
||||||
void makeInstances ();
|
void makeInstances ();
|
||||||
|
void makeExternals ();
|
||||||
Net* fusedNet ();
|
Net* fusedNet ();
|
||||||
|
void addNetReference ( Net*, const Layer*, DbU::Unit x, DbU::Unit y );
|
||||||
private:
|
private:
|
||||||
struct DelayedInstance {
|
struct DelayedInstance {
|
||||||
inline DelayedInstance ( Cell* owner, string masterName, const Transformation& );
|
inline DelayedInstance ( Cell* owner, string masterName, const Transformation& );
|
||||||
|
@ -621,6 +663,12 @@ namespace {
|
||||||
string _masterName;
|
string _masterName;
|
||||||
Transformation _transformation;
|
Transformation _transformation;
|
||||||
};
|
};
|
||||||
|
private:
|
||||||
|
struct PinPoint {
|
||||||
|
inline PinPoint ( const Layer*, DbU::Unit x, DbU::Unit y );
|
||||||
|
const Layer* _layer;
|
||||||
|
Point _position;
|
||||||
|
};
|
||||||
private:
|
private:
|
||||||
static vector<const Layer*> _gdsLayerTable;
|
static vector<const Layer*> _gdsLayerTable;
|
||||||
vector<DelayedInstance> _delayedInstances;
|
vector<DelayedInstance> _delayedInstances;
|
||||||
|
@ -637,6 +685,9 @@ namespace {
|
||||||
int64_t _SREFCount;
|
int64_t _SREFCount;
|
||||||
bool _validSyntax;
|
bool _validSyntax;
|
||||||
bool _skipENDEL;
|
bool _skipENDEL;
|
||||||
|
map< Net*
|
||||||
|
, vector<PinPoint>
|
||||||
|
, DBo::CompareById > _netReferences;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -647,6 +698,11 @@ namespace {
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
inline GdsStream::PinPoint::PinPoint ( const Layer* layer, DbU::Unit x, DbU::Unit y )
|
||||||
|
: _layer(layer), _position(x,y)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
vector<const Layer*> GdsStream::_gdsLayerTable;
|
vector<const Layer*> GdsStream::_gdsLayerTable;
|
||||||
|
|
||||||
|
|
||||||
|
@ -688,7 +744,7 @@ namespace {
|
||||||
{
|
{
|
||||||
if (_gdsLayerTable.empty()) _staticInit();
|
if (_gdsLayerTable.empty()) _staticInit();
|
||||||
|
|
||||||
_stream.open( gdsPath, ios_base::in );
|
_stream.open( gdsPath, ios_base::in|ios_base::binary );
|
||||||
|
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
if (not _record.isHEADER()) {
|
if (not _record.isHEADER()) {
|
||||||
|
@ -715,7 +771,7 @@ namespace {
|
||||||
|
|
||||||
bool GdsStream::read ( Library* library )
|
bool GdsStream::read ( Library* library )
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::read(Library*)" << endl;
|
cdebug_log(101,1) << "GdsStream::read(Library*)" << endl;
|
||||||
|
|
||||||
_library = library;
|
_library = library;
|
||||||
|
|
||||||
|
@ -724,6 +780,7 @@ namespace {
|
||||||
" in \"%s\""
|
" in \"%s\""
|
||||||
, _gdsPath.c_str() ) << endl;
|
, _gdsPath.c_str() ) << endl;
|
||||||
_validSyntax = false;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
|
@ -737,13 +794,20 @@ namespace {
|
||||||
" in \"%s\""
|
" in \"%s\""
|
||||||
, _gdsPath.c_str() ) << endl;
|
, _gdsPath.c_str() ) << endl;
|
||||||
_validSyntax = false;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
if (_record.isREFLIBS ()) { _stream >> _record; }
|
if (_record.isREFLIBS ()) { _stream >> _record; }
|
||||||
if (_record.isFONTS ()) { _stream >> _record; }
|
if (_record.isFONTS ()) { _stream >> _record; }
|
||||||
if (_record.isATTRTABLE ()) { _stream >> _record; }
|
if (_record.isATTRTABLE ()) { _stream >> _record; }
|
||||||
if (_record.isGENERATIONS()) { _stream >> _record; }
|
if (_record.isGENERATIONS()) { _stream >> _record; }
|
||||||
if (_record.isFORMAT ()) { readFormatType(); if (not _validSyntax) return _validSyntax; }
|
if (_record.isFORMAT ()) {
|
||||||
|
readFormatType();
|
||||||
|
if (not _validSyntax) {
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_record.isUNITS()) {
|
if (_record.isUNITS()) {
|
||||||
_scale = DbU::fromPhysical( _record.getDoubles()[1], DbU::Unity );
|
_scale = DbU::fromPhysical( _record.getDoubles()[1], DbU::Unity );
|
||||||
|
@ -757,17 +821,20 @@ namespace {
|
||||||
|
|
||||||
if (_validSyntax and not _record.isENDLIB()) { misplacedRecord(); }
|
if (_validSyntax and not _record.isENDLIB()) { misplacedRecord(); }
|
||||||
|
|
||||||
if (_validSyntax) makeInstances();
|
if (_validSyntax) {
|
||||||
|
makeInstances();
|
||||||
|
makeExternals();
|
||||||
|
}
|
||||||
|
|
||||||
_library = NULL;
|
_library = NULL;
|
||||||
//cerr << "GdsStream::read(Library*) - return:" << _validSyntax << endl;
|
cdebug_log(101,-1) << " GdsStream::read(Library*) - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readFormatType ()
|
bool GdsStream::readFormatType ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readFormatType()" << endl;
|
cdebug_log(101,0) << "GdsStream::readFormatType()" << endl;
|
||||||
|
|
||||||
if (_record.isMASK()) {
|
if (_record.isMASK()) {
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
|
@ -779,14 +846,14 @@ namespace {
|
||||||
else { _validSyntax = false; return _validSyntax; }
|
else { _validSyntax = false; return _validSyntax; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << "GdsStream::readFormatType() - return:" << _validSyntax << endl;
|
//cdebug(101,0) << "GdsStream::readFormatType() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readStructure ()
|
bool GdsStream::readStructure ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readStructure()" << endl;
|
cdebug_log(101,1) << "GdsStream::readStructure()" << endl;
|
||||||
|
|
||||||
if (_record.isSTRNAME()) {
|
if (_record.isSTRNAME()) {
|
||||||
if (_library) {
|
if (_library) {
|
||||||
|
@ -819,7 +886,9 @@ namespace {
|
||||||
if (not _skipENDEL) {
|
if (not _skipENDEL) {
|
||||||
if (_record.isENDEL()) { _stream >> _record; }
|
if (_record.isENDEL()) { _stream >> _record; }
|
||||||
else {
|
else {
|
||||||
_validSyntax = false; break;
|
_validSyntax = false;
|
||||||
|
cdebug_log(101,0) << "Missing ENDEL inside STRUCTURE loop" << endl;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
_skipENDEL = false;
|
_skipENDEL = false;
|
||||||
|
@ -832,7 +901,7 @@ namespace {
|
||||||
_cell->setAbutmentBox( _cell->getBoundingBox() );
|
_cell->setAbutmentBox( _cell->getBoundingBox() );
|
||||||
UpdateSession::open();
|
UpdateSession::open();
|
||||||
_cell = NULL;
|
_cell = NULL;
|
||||||
cerr << "GdsStream::readStructure() - return:" << _validSyntax << endl;
|
cdebug_log(101,-1) << " GdsStream::readStructure() - return:" << _validSyntax << endl;
|
||||||
|
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
@ -840,25 +909,41 @@ namespace {
|
||||||
|
|
||||||
bool GdsStream::readText ()
|
bool GdsStream::readText ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readText()" << endl;
|
const Layer* layer = NULL;
|
||||||
|
|
||||||
|
cdebug_log(101,0) << "GdsStream::readText()" << endl;
|
||||||
if (_record.isELFLAGS()) { _stream >> _record; }
|
if (_record.isELFLAGS()) { _stream >> _record; }
|
||||||
if (_record.isPLEX ()) { _stream >> _record; }
|
if (_record.isPLEX ()) { _stream >> _record; }
|
||||||
if (_record.isLAYER ()) { _stream >> _record; }
|
if (_record.isLAYER ()) {
|
||||||
else { _validSyntax = false; return _validSyntax; }
|
layer = gdsToLayer( _record.getInt16s()[0] );
|
||||||
|
if (not layer) {
|
||||||
|
cerr << Error( "GdsStream::readText(): No BasicLayer id:%d in GDS conversion table (skipped)."
|
||||||
|
, _record.getInt16s()[0]
|
||||||
|
) << endl;
|
||||||
|
}
|
||||||
|
_stream >> _record;
|
||||||
|
} else { _validSyntax = false; return _validSyntax; }
|
||||||
|
|
||||||
readTextbody();
|
readTextbody( layer );
|
||||||
|
|
||||||
//cerr << "GdsStream::readText() - return:" << _validSyntax << endl;
|
//cdebug(101,0) << "GdsStream::readText() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readTextbody ()
|
bool GdsStream::readTextbody ( const Layer* layer )
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readTextbody()" << endl;
|
cdebug_log(101,1) << "GdsStream::readTextbody()" << endl;
|
||||||
|
|
||||||
|
DbU::Unit xpos = 0;
|
||||||
|
DbU::Unit ypos = 0;
|
||||||
|
|
||||||
if (_record.isTEXTTYPE()) { _stream >> _record; }
|
if (_record.isTEXTTYPE()) { _stream >> _record; }
|
||||||
else { _validSyntax = false; return _validSyntax; }
|
else {
|
||||||
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
if (_record.isPRESENTATION()) { _stream >> _record; }
|
if (_record.isPRESENTATION()) { _stream >> _record; }
|
||||||
if (_record.isPATH ()) { _stream >> _record; }
|
if (_record.isPATH ()) { _stream >> _record; }
|
||||||
|
@ -867,27 +952,55 @@ namespace {
|
||||||
if (_record.isSTRANS()) {
|
if (_record.isSTRANS()) {
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
readStrans();
|
readStrans();
|
||||||
if (not _validSyntax) return _validSyntax;
|
if (not _validSyntax) {
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_record.isXY()) { _stream >> _record; }
|
if (_record.isXY()) {
|
||||||
else { _validSyntax = false; return _validSyntax; }
|
vector<int32_t> coordinates = _record.getInt32s();
|
||||||
|
if (coordinates.size() != 2) {
|
||||||
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
|
xpos = coordinates[ 0 ]*_scale;
|
||||||
|
ypos = coordinates[ 1 ]*_scale;
|
||||||
|
_stream >> _record;
|
||||||
|
} else {
|
||||||
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
if (_record.isSTRING()) {
|
if (_record.isSTRING()) {
|
||||||
_text = _record.getName();
|
_text = _record.getName();
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
cerr << "_text:\"" << _text << "\"" << endl;
|
|
||||||
}
|
}
|
||||||
else { _validSyntax = false; return _validSyntax; }
|
else {
|
||||||
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
//cerr << "GdsStream::readTextbody() - return:" << _validSyntax << endl;
|
if (not _text.empty()) {
|
||||||
|
Net* net = _cell->getNet( _text );
|
||||||
|
if (not net) {
|
||||||
|
net = Net::create( _cell, _text );
|
||||||
|
net->setExternal( true );
|
||||||
|
}
|
||||||
|
addNetReference( net, layer, xpos, ypos );
|
||||||
|
}
|
||||||
|
|
||||||
|
cdebug_log(101,-1) << "GdsStream::readTextbody() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readStrans ()
|
bool GdsStream::readStrans ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readStrans()" << endl;
|
cdebug_log(101,0) << "GdsStream::readStrans()" << endl;
|
||||||
|
|
||||||
_angle = 0.0;
|
_angle = 0.0;
|
||||||
_xReflection = _record.hasXReflection();
|
_xReflection = _record.hasXReflection();
|
||||||
|
@ -895,14 +1008,14 @@ namespace {
|
||||||
if (_record.isMAG ()) { _stream >> _record; }
|
if (_record.isMAG ()) { _stream >> _record; }
|
||||||
if (_record.isANGLE()) { _angle = _record.getDoubles()[0]; _stream >> _record; }
|
if (_record.isANGLE()) { _angle = _record.getDoubles()[0]; _stream >> _record; }
|
||||||
|
|
||||||
//cerr << "GdsStream::readStrans() - return:" << _validSyntax << endl;
|
//cdebug(101,0) << "GdsStream::readStrans() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readBoundary ()
|
bool GdsStream::readBoundary ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readBoundary()" << endl;
|
cdebug_log(101,1) << "GdsStream::readBoundary()" << endl;
|
||||||
|
|
||||||
const Layer* layer = NULL;
|
const Layer* layer = NULL;
|
||||||
|
|
||||||
|
@ -918,29 +1031,39 @@ namespace {
|
||||||
}
|
}
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
} else {
|
} else {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_record.isDATATYPE()) { _stream >> _record; }
|
if (_record.isDATATYPE()) { _stream >> _record; }
|
||||||
else { _validSyntax = false; return _validSyntax; }
|
else {
|
||||||
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
if (_record.isXY()) {
|
if (_record.isXY()) {
|
||||||
if (_cell and layer) xyToComponent( layer );
|
if (_cell and layer) xyToComponent( layer );
|
||||||
else _stream >> _record;
|
else _stream >> _record;
|
||||||
} else {
|
} else {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << "GdsStream::readBoundary() - return:" << _validSyntax << endl;
|
cdebug_log(101,-1) << "GdsStream::readBoundary() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readPath ()
|
bool GdsStream::readPath ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readPath()" << endl;
|
cdebug_log(101,1) << "GdsStream::readPath()" << endl;
|
||||||
|
|
||||||
const Layer* layer = NULL;
|
const Layer* layer = NULL;
|
||||||
|
DbU::Unit width = 0;
|
||||||
|
uint16_t pathtype = 0;
|
||||||
|
|
||||||
if (_record.isELFLAGS()) { _stream >> _record; }
|
if (_record.isELFLAGS()) { _stream >> _record; }
|
||||||
if (_record.isPLEX ()) { _stream >> _record; }
|
if (_record.isPLEX ()) { _stream >> _record; }
|
||||||
|
@ -953,33 +1076,50 @@ namespace {
|
||||||
) << endl;
|
) << endl;
|
||||||
}
|
}
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
|
cdebug_log(101,0) << layer << endl;
|
||||||
} else {
|
} else {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_record.isDATATYPE()) { _stream >> _record; }
|
if (_record.isDATATYPE()) { _stream >> _record; }
|
||||||
else { _validSyntax = false; return _validSyntax; }
|
else {
|
||||||
|
cerr << Error( "GdsStream::readPath(): Expecting DATATYPE record, got %s."
|
||||||
|
, GdsRecord::toStrType(_record.getType()).c_str()
|
||||||
|
) << endl;
|
||||||
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
if (_record.isPATHTYPE()) { _stream >> _record; }
|
if (_record.isPATHTYPE()) {
|
||||||
if (_record.isWIDTH ()) { _stream >> _record; }
|
pathtype = _record.getInt16s()[0];
|
||||||
|
_stream >> _record;
|
||||||
|
}
|
||||||
|
if (_record.isWIDTH ()) {
|
||||||
|
width = _record.getInt32s()[0] * _scale;
|
||||||
|
_stream >> _record;
|
||||||
|
}
|
||||||
if (_record.isBGNEXTN ()) { _stream >> _record; }
|
if (_record.isBGNEXTN ()) { _stream >> _record; }
|
||||||
if (_record.isENDEXTN ()) { _stream >> _record; }
|
if (_record.isENDEXTN ()) { _stream >> _record; }
|
||||||
|
|
||||||
if (_record.isXY()) {
|
if (_record.isXY()) {
|
||||||
if (_cell and layer) xyToComponent( layer );
|
if (_cell and layer) xyToPath( pathtype, layer, width );
|
||||||
_stream >> _record;
|
|
||||||
} else {
|
} else {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << "GdsStream::readPath() - return:" << _validSyntax << endl;
|
cdebug_log(101,-1) << "GdsStream::readPath() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readSref ()
|
bool GdsStream::readSref ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readSref()" << endl;
|
cdebug_log(101,1) << "GdsStream::readSref()" << endl;
|
||||||
resetStrans();
|
resetStrans();
|
||||||
|
|
||||||
string masterName;
|
string masterName;
|
||||||
|
@ -991,22 +1131,28 @@ namespace {
|
||||||
|
|
||||||
if (_record.isSNAME()) {
|
if (_record.isSNAME()) {
|
||||||
masterName = _record.getName();
|
masterName = _record.getName();
|
||||||
|
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
} else {
|
} else {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_record.isSTRANS()) {
|
if (_record.isSTRANS()) {
|
||||||
readStrans();
|
readStrans();
|
||||||
//_stream >> _record;
|
//_stream >> _record;
|
||||||
if (not _validSyntax) return _validSyntax;
|
if (not _validSyntax) {
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_record.isXY()) {
|
if (_record.isXY()) {
|
||||||
vector<int32_t> coordinates = _record.getInt32s();
|
vector<int32_t> coordinates = _record.getInt32s();
|
||||||
if (coordinates.size() != 2) {
|
if (coordinates.size() != 2) {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
xpos = coordinates[ 0 ]*_scale;
|
xpos = coordinates[ 0 ]*_scale;
|
||||||
|
@ -1014,7 +1160,9 @@ namespace {
|
||||||
|
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
} else {
|
} else {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not masterName.empty()) {
|
if (not masterName.empty()) {
|
||||||
|
@ -1048,14 +1196,14 @@ namespace {
|
||||||
, Transformation(xpos,ypos,orient)) );
|
, Transformation(xpos,ypos,orient)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << "GdsStream::readSref() - return:" << _validSyntax << endl;
|
cdebug_log(101,-1) << "GdsStream::readSref() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readAref ()
|
bool GdsStream::readAref ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readAref()" << endl;
|
cdebug_log(101,0) << "GdsStream::readAref()" << endl;
|
||||||
|
|
||||||
const Layer* layer = NULL;
|
const Layer* layer = NULL;
|
||||||
|
|
||||||
|
@ -1087,14 +1235,14 @@ namespace {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false; return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << "GdsStream::readAref() - return:" << _validSyntax << endl;
|
cdebug_log(101,0) << "GdsStream::readAref() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readNode ()
|
bool GdsStream::readNode ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readNode()" << endl;
|
cdebug_log(101,0) << "GdsStream::readNode()" << endl;
|
||||||
|
|
||||||
const Layer* layer = NULL;
|
const Layer* layer = NULL;
|
||||||
|
|
||||||
|
@ -1117,14 +1265,14 @@ namespace {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false; return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << "GdsStream::readNode() - return:" << _validSyntax << endl;
|
cdebug_log(101,0) << "GdsStream::readNode() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readBox ()
|
bool GdsStream::readBox ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readBox()" << endl;
|
cdebug_log(101,0) << "GdsStream::readBox()" << endl;
|
||||||
|
|
||||||
const Layer* layer = NULL;
|
const Layer* layer = NULL;
|
||||||
|
|
||||||
|
@ -1147,19 +1295,19 @@ namespace {
|
||||||
_validSyntax = false; return _validSyntax;
|
_validSyntax = false; return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << "GdsStream::readBox() - return:" << _validSyntax << endl;
|
cdebug_log(101,0) << "GdsStream::readBox() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GdsStream::readProperty ()
|
bool GdsStream::readProperty ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::readProperty()" << endl;
|
cdebug_log(101,0) << "GdsStream::readProperty()" << endl;
|
||||||
|
|
||||||
if (_record.isPROPVALUE ()) { _stream >> _record; }
|
if (_record.isPROPVALUE ()) { _stream >> _record; }
|
||||||
else { _validSyntax = false; return _validSyntax; }
|
else { _validSyntax = false; return _validSyntax; }
|
||||||
|
|
||||||
//cerr << "GdsStream::readProperty() - return:" << _validSyntax << endl;
|
cdebug_log(101,0) << "GdsStream::readProperty() - return:" << _validSyntax << endl;
|
||||||
return _validSyntax;
|
return _validSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,8 +1322,9 @@ namespace {
|
||||||
|
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
|
|
||||||
if (_record.getType() == GdsRecord::ENDEL) {
|
if ( (_record.getType() == GdsRecord::ENDEL)
|
||||||
_stream >> _record;
|
or (_record.getType() == GdsRecord::STRING)) {
|
||||||
|
//_stream >> _record;
|
||||||
} else {
|
} else {
|
||||||
_validSyntax = false;
|
_validSyntax = false;
|
||||||
return;
|
return;
|
||||||
|
@ -1184,9 +1333,7 @@ namespace {
|
||||||
Net* net = NULL;
|
Net* net = NULL;
|
||||||
if (_record.getType() == GdsRecord::TEXT) {
|
if (_record.getType() == GdsRecord::TEXT) {
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
cerr << " BOUNDARY --> TEXT record" << endl;
|
|
||||||
readText();
|
readText();
|
||||||
cerr << " AFTER readText()" << endl;
|
|
||||||
|
|
||||||
if (not _text.empty()) {
|
if (not _text.empty()) {
|
||||||
net = _cell->getNet( _text );
|
net = _cell->getNet( _text );
|
||||||
|
@ -1214,33 +1361,174 @@ namespace {
|
||||||
Box boundingBox;
|
Box boundingBox;
|
||||||
for ( Point p : points ) boundingBox.merge( p );
|
for ( Point p : points ) boundingBox.merge( p );
|
||||||
_component = Pad::create( net, layer, boundingBox );
|
_component = Pad::create( net, layer, boundingBox );
|
||||||
cerr << _component << endl;
|
|
||||||
} else {
|
} else {
|
||||||
_component = Rectilinear::create( net, layer, points );
|
_component = Rectilinear::create( net, layer, points );
|
||||||
}
|
}
|
||||||
|
// cdebug(101,0) << "| " << net->getCell() << endl;
|
||||||
|
// cdebug(101,0) << "| " << _component << endl;
|
||||||
|
|
||||||
if (not net->isAutomatic()) NetExternalComponents::setExternal( _component );
|
if (not net->isAutomatic()) NetExternalComponents::setExternal( _component );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GdsStream::xyToPath ( uint16_t pathtype, const Layer* layer, DbU::Unit width )
|
||||||
|
{
|
||||||
|
cdebug_log(101,0) << "GdsStream::xyToPath(): pathtype=" << pathtype
|
||||||
|
<< " layer=" << layer->getName()
|
||||||
|
<< " width=" << DbU::getValueString(width) << endl;
|
||||||
|
|
||||||
|
vector<Point> points;
|
||||||
|
vector<int32_t> coordinates = _record.getInt32s();
|
||||||
|
for ( size_t i=0 ; i<coordinates.size() ; i += 2 )
|
||||||
|
points.push_back( Point( coordinates[i ]*_scale
|
||||||
|
, coordinates[i+1]*_scale ) );
|
||||||
|
_stream >> _record;
|
||||||
|
if (_record.getType() != GdsRecord::ENDEL) {
|
||||||
|
_validSyntax = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Net* net = fusedNet();
|
||||||
|
|
||||||
|
for ( size_t i=1 ; i<points.size() ; ++i ) {
|
||||||
|
if ( (points[i-1].getX() != points[i].getX())
|
||||||
|
and (points[i-1].getY() != points[i].getY()) ) {
|
||||||
|
cerr << Error( "GdsStream::xyToPath(): Non-rectilinear paths are not supporteds (skipped)."
|
||||||
|
) << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DbU::Unit hWidthCap = width;
|
||||||
|
DbU::Unit vWidthCap = width;
|
||||||
|
if (pathtype == 0) {
|
||||||
|
if (points[0].getX() == points[1].getX()) vWidthCap = 0;
|
||||||
|
else hWidthCap = 0;
|
||||||
|
}
|
||||||
|
Contact* source = Contact::create( net
|
||||||
|
, layer
|
||||||
|
, points[0].getX()
|
||||||
|
, points[0].getY()
|
||||||
|
, hWidthCap
|
||||||
|
, vWidthCap );
|
||||||
|
hWidthCap = width;
|
||||||
|
vWidthCap = width;
|
||||||
|
Contact* target = NULL;
|
||||||
|
Segment* segment = NULL;
|
||||||
|
for ( size_t i=1 ; i<points.size() ; ++i ) {
|
||||||
|
if (i == points.size()-1) {
|
||||||
|
if (pathtype == 0) {
|
||||||
|
if (points[0].getX() == points[1].getX()) vWidthCap = 0;
|
||||||
|
else hWidthCap = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target = Contact::create( net
|
||||||
|
, layer
|
||||||
|
, points[i].getX()
|
||||||
|
, points[i].getY()
|
||||||
|
, hWidthCap
|
||||||
|
, vWidthCap );
|
||||||
|
if (points[i-1].getY() == points[i].getY()) {
|
||||||
|
segment = Horizontal::create( source
|
||||||
|
, target
|
||||||
|
, layer
|
||||||
|
, points[i].getY()
|
||||||
|
, width
|
||||||
|
, 0, 0 );
|
||||||
|
} else {
|
||||||
|
segment = Vertical::create( source
|
||||||
|
, target
|
||||||
|
, layer
|
||||||
|
, points[i].getX()
|
||||||
|
, width
|
||||||
|
, 0, 0 );
|
||||||
|
}
|
||||||
|
if (not net->isAutomatic()) NetExternalComponents::setExternal( segment );
|
||||||
|
source = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GdsStream::makeInstances ()
|
void GdsStream::makeInstances ()
|
||||||
{
|
{
|
||||||
//cerr << "GdsStream::makeInstances(): " << endl;
|
cdebug_log(101,1) << "GdsStream::makeInstances(): " << endl;
|
||||||
|
|
||||||
for ( const DelayedInstance& di : _delayedInstances ) {
|
for ( const DelayedInstance& di : _delayedInstances ) {
|
||||||
Cell* masterCell = _library->getCell( di._masterName );
|
Cell* masterCell = _library->getCell( di._masterName );
|
||||||
|
|
||||||
if (masterCell) {
|
if (masterCell) {
|
||||||
string insName = "sref_" + getString(_SREFCount++);
|
string insName = "sref_" + getString(_SREFCount++);
|
||||||
//Instance* instance =
|
Instance* instance =
|
||||||
Instance::create( di._owner
|
Instance::create( di._owner
|
||||||
, insName
|
, insName
|
||||||
, masterCell
|
, masterCell
|
||||||
, di._transformation
|
, di._transformation
|
||||||
, Instance::PlacementStatus::FIXED
|
, Instance::PlacementStatus::FIXED
|
||||||
);
|
);
|
||||||
//cerr << "| " << instance << " @" << di._transformation << " in " << di._owner << endl;
|
cdebug_log(101,0) << "| " << instance << " @" << di._transformation << " in " << di._owner << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GdsStream::addNetReference ( Net* net, const Layer* layer, DbU::Unit x, DbU::Unit y )
|
||||||
|
{
|
||||||
|
if (not layer) return;
|
||||||
|
|
||||||
|
auto inet = _netReferences.find( net );
|
||||||
|
if (inet == _netReferences.end()) {
|
||||||
|
_netReferences[ net ] = vector<PinPoint>();
|
||||||
|
}
|
||||||
|
_netReferences[ net ].push_back( PinPoint(layer,x,y) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GdsStream::makeExternals ()
|
||||||
|
{
|
||||||
|
UpdateSession::close();
|
||||||
|
UpdateSession::open();
|
||||||
|
for ( auto netPins : _netReferences ) {
|
||||||
|
Net* net = netPins.first;
|
||||||
|
for ( const PinPoint& ref : netPins.second ) {
|
||||||
|
const Layer* layer = ref._layer;
|
||||||
|
string layerName = getString( layer->getName() );
|
||||||
|
if (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()
|
||||||
|
<< "\" in " << layer
|
||||||
|
<< " @" << ref._position
|
||||||
|
<< endl;
|
||||||
|
if (not layer) continue;
|
||||||
|
for ( Component* component : net->getCell()
|
||||||
|
->getComponentsUnder( Box(ref._position).inflate(1),layer->getMask() ) ) {
|
||||||
|
cdebug_log(101,0) << "| " << component << endl;
|
||||||
|
Horizontal* href = dynamic_cast<Horizontal*>( component );
|
||||||
|
if (href) {
|
||||||
|
Horizontal* h = Horizontal::create( net
|
||||||
|
, href->getLayer()
|
||||||
|
, href->getY()
|
||||||
|
, href->getWidth()
|
||||||
|
, href->getSourceX()
|
||||||
|
, href->getTargetX()
|
||||||
|
);
|
||||||
|
NetExternalComponents::setExternal( h );
|
||||||
|
} else {
|
||||||
|
Vertical* vref = dynamic_cast<Vertical*>( component );
|
||||||
|
if (vref) {
|
||||||
|
Vertical* v = Vertical::create( net
|
||||||
|
, vref->getLayer()
|
||||||
|
, vref->getX()
|
||||||
|
, vref->getWidth()
|
||||||
|
, vref->getSourceY()
|
||||||
|
, vref->getTargetY()
|
||||||
|
);
|
||||||
|
NetExternalComponents::setExternal( v );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue