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 <cmath>
|
||||
#include <cstdio>
|
||||
#include <cfenv>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
@ -36,6 +37,7 @@ using namespace std;
|
|||
#include "hurricane/Polygon.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Instance.h"
|
||||
|
@ -262,7 +264,7 @@ namespace {
|
|||
//static const uint16_t PATH = 0x0900 | NoData;
|
||||
static const uint16_t SREF = 0x0a00 | 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 DATATYPE = 0x0e00 | TwoByteInteger;
|
||||
//static const uint16_t WIDTH = 0x0f00 | FourByteInteger;
|
||||
|
@ -272,10 +274,10 @@ namespace {
|
|||
//static const uint16_t COLROW = 0x1300 | TwoByteInteger;
|
||||
//static const uint16_t TEXTNODE = 0x1400 | NoData; // Unused.
|
||||
//static const uint16_t NODE = 0x1500 | NoData;
|
||||
//static const uint16_t TEXTTYPE = 0x1600 | TwoByteInteger;
|
||||
//static const uint16_t PRESENTATION = 0x1700 | BitArray;
|
||||
static const uint16_t TEXTTYPE = 0x1600 | TwoByteInteger;
|
||||
static const uint16_t PRESENTATION = 0x1700 | BitArray;
|
||||
//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 MAG = 0x1b00 | EightByteReal;
|
||||
static const uint16_t ANGLE = 0x1c00 | EightByteReal;
|
||||
|
@ -428,13 +430,27 @@ namespace {
|
|||
|
||||
void GdsRecord::toStream ( ostream& stream ) const
|
||||
{
|
||||
static size_t count = 0;
|
||||
|
||||
uint16_t length = (uint16_t)( _bytes.size()+2 );
|
||||
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).
|
||||
stream.put( bytearray[1] );
|
||||
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 ENDSTR;
|
||||
static const GdsRecord SREF;
|
||||
static const GdsRecord TEXT;
|
||||
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& );
|
||||
GdsStream& operator<< ( const BasicLayer* );
|
||||
GdsStream& operator<< ( const Box& );
|
||||
GdsStream& operator<< ( const Points );
|
||||
GdsStream& operator<< ( const vector<Point>& points );
|
||||
GdsStream& operator<< ( const Cell* );
|
||||
GdsStream& operator<< ( const Transformation& );
|
||||
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 TEXTTYPE ( int16_t );
|
||||
static inline GdsRecord LAYER ( int16_t );
|
||||
static inline GdsRecord PRESENTATION ( 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& );
|
||||
static inline GdsRecord STRING ( const Name& );
|
||||
static inline GdsRecord STRING ( const string );
|
||||
GdsStream& operator<< ( const GdsRecord& );
|
||||
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:
|
||||
ofstream _ostream;
|
||||
double _dbuPerUu;
|
||||
|
@ -483,16 +505,22 @@ namespace {
|
|||
const GdsRecord GdsStream::ENDEL = GdsRecord(GdsRecord::ENDEL);
|
||||
const GdsRecord GdsStream::ENDSTR = GdsRecord(GdsRecord::ENDSTR);
|
||||
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::DATATYPE ( int16_t v ) { return GdsRecord(GdsRecord::DATATYPE,v); }
|
||||
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
|
||||
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::TEXTTYPE ( int16_t v ) { return GdsRecord(GdsRecord::TEXTTYPE,v); }
|
||||
inline GdsRecord GdsStream::LAYER ( int16_t v ) { return GdsRecord(GdsRecord::LAYER,v); }
|
||||
inline GdsRecord GdsStream::PRESENTATION ( int16_t v ) { return GdsRecord(GdsRecord::PRESENTATION,v); }
|
||||
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 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 )); }
|
||||
|
||||
|
||||
|
@ -502,7 +530,7 @@ namespace {
|
|||
, _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um.
|
||||
{
|
||||
std::fesetround( FE_TONEAREST );
|
||||
_ostream.open( filename, ios_base::out );
|
||||
_ostream.open( filename, ios_base::out|ios_base::binary );
|
||||
|
||||
GdsRecord record ( GdsRecord::HEADER );
|
||||
record.push( (uint16_t)600 );
|
||||
|
@ -552,18 +580,22 @@ namespace {
|
|||
{ _ostream << record; return *this; }
|
||||
|
||||
|
||||
#if 0
|
||||
GdsStream& GdsStream::operator<< ( const BasicLayer* layer )
|
||||
{
|
||||
cdebug_log(101,0) << "LAYER" << endl;
|
||||
GdsRecord record ( GdsRecord::LAYER );
|
||||
record.push( (int16_t)layer->getGds2Layer() );
|
||||
_ostream << record;
|
||||
|
||||
cdebug_log(101,0) << "DATATYPE" << endl;
|
||||
record = GdsRecord( GdsRecord::DATATYPE );
|
||||
record.push( (int16_t)layer->getGds2Datatype() );
|
||||
_ostream << record;
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
GdsRecord record ( GdsRecord::XY );
|
||||
|
@ -720,7 +762,8 @@ namespace {
|
|||
for ( const vector<Point>& subpolygon : subpolygons ) {
|
||||
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
||||
(*this) << BOUNDARY;
|
||||
(*this) << layer;
|
||||
(*this) << LAYER(layer->getGds2Layer());
|
||||
(*this) << DATATYPE(layer->getGds2Datatype());
|
||||
(*this) << subpolygon;
|
||||
(*this) << ENDEL;
|
||||
}
|
||||
|
@ -730,7 +773,8 @@ namespace {
|
|||
if (rectilinear) {
|
||||
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
||||
(*this) << BOUNDARY;
|
||||
(*this) << layer;
|
||||
(*this) << LAYER(layer->getGds2Layer());
|
||||
(*this) << DATATYPE(layer->getGds2Datatype());
|
||||
(*this) << rectilinear->getPoints();
|
||||
(*this) << ENDEL;
|
||||
isOnGrid( component, rectilinear->getPoints() );
|
||||
|
@ -740,7 +784,8 @@ namespace {
|
|||
if (diagonal) {
|
||||
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
||||
(*this) << BOUNDARY;
|
||||
(*this) << layer;
|
||||
(*this) << LAYER(layer->getGds2Layer());
|
||||
(*this) << DATATYPE(layer->getGds2Datatype());
|
||||
(*this) << diagonal->getContour();
|
||||
(*this) << ENDEL;
|
||||
}
|
||||
|
@ -753,10 +798,34 @@ namespace {
|
|||
if ((bb.getWidth() == 0) or (bb.getHeight() == 0))
|
||||
continue;
|
||||
(*this) << BOUNDARY;
|
||||
(*this) << layer;
|
||||
(*this) << LAYER(layer->getGds2Layer());
|
||||
(*this) << DATATYPE(layer->getGds2Datatype());
|
||||
(*this) << bb;
|
||||
(*this) << ENDEL;
|
||||
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 <cstdio>
|
||||
#include <string>
|
||||
#include <bitset>
|
||||
#include <sstream>
|
||||
|
@ -201,6 +202,8 @@ namespace {
|
|||
void readString ();
|
||||
void readUnits ();
|
||||
void readLayer ();
|
||||
void readWidth ();
|
||||
void readPathtype ();
|
||||
void readStrname ();
|
||||
void readXy ();
|
||||
static string toStrType ( uint16_t );
|
||||
|
@ -211,6 +214,7 @@ namespace {
|
|||
double _readDouble ();
|
||||
private:
|
||||
istream* _stream;
|
||||
uint32_t _offset;
|
||||
uint16_t _length;
|
||||
uint16_t _count;
|
||||
uint16_t _type;
|
||||
|
@ -220,6 +224,7 @@ namespace {
|
|||
vector<int16_t> _int16s;
|
||||
vector<int32_t> _int32s;
|
||||
vector<double> _doubles;
|
||||
char _buffer[64];
|
||||
};
|
||||
|
||||
|
||||
|
@ -293,6 +298,7 @@ namespace {
|
|||
|
||||
GdsRecord::GdsRecord ()
|
||||
: _stream (NULL)
|
||||
, _offset (0)
|
||||
, _length (0)
|
||||
, _count (0)
|
||||
, _type (0)
|
||||
|
@ -344,7 +350,7 @@ namespace {
|
|||
case TEXT: readDummy( false ); break;
|
||||
case LAYER: readLayer(); break;
|
||||
case DATATYPE: readDummy( false ); break;
|
||||
case WIDTH: readDummy( false ); break;
|
||||
case WIDTH: readWidth(); break;
|
||||
case XY: readXy(); break;
|
||||
case ENDEL: readDummy( false ); break;
|
||||
case SNAME: readStrname(); break;
|
||||
|
@ -360,7 +366,7 @@ namespace {
|
|||
case ANGLE: _doubles.push_back( _readDouble() ); break;
|
||||
case REFLIBS: readDummy( false ); break;
|
||||
case FONTS: readDummy( false ); break;
|
||||
case PATHTYPE: readDummy( false ); break;
|
||||
case PATHTYPE: readPathtype(); break;
|
||||
case GENERATIONS: readDummy( false ); break;
|
||||
case ATTRTABLE: readDummy( false ); break;
|
||||
case STYPTABLE: readDummy( false ); break;
|
||||
|
@ -389,7 +395,13 @@ namespace {
|
|||
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 ];
|
||||
};
|
||||
|
||||
char bytes[typeSize];
|
||||
_stream->read( bytes, typeSize );
|
||||
_count += typeSize;
|
||||
unsigned char bytes[typeSize];
|
||||
_stream->read( (char*)(&bytes[0]), 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;
|
||||
// Little endian (x86).
|
||||
|
@ -440,6 +458,12 @@ namespace {
|
|||
_stream->read( bytes, 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;
|
||||
for ( size_t i=0 ; i<7 ; ++i ) mantisse.bytes[i] = bytes[7-i];
|
||||
mantisse.bytes[7] = 0;
|
||||
|
@ -456,31 +480,38 @@ namespace {
|
|||
|
||||
string GdsRecord::_readString ()
|
||||
{
|
||||
cdebug_log(101,0) << "GdsRecord::_readDouble() " << endl;
|
||||
string s;
|
||||
char c;
|
||||
for ( ; _count<_length ; ++_count ) {
|
||||
_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);
|
||||
}
|
||||
cerr << "GdsRecord::_readString(): \"" << s << "\"" << endl;
|
||||
cdebug_log(101,0) << "GdsRecord::_readString(): \"" << s << "\"" << endl;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void GdsRecord::readDummy ( bool showError )
|
||||
{
|
||||
cdebug_log(101,0) << "GdsRecord::readDummy() " << endl;
|
||||
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) {
|
||||
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 ()
|
||||
{
|
||||
|
||||
const uint16_t XRMask = 0x8000;
|
||||
uint16_t flags = _readInt<uint16_t>();
|
||||
_xReflection = (flags & XRMask);
|
||||
|
@ -508,6 +539,14 @@ namespace {
|
|||
{ _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 ()
|
||||
{ while ( _count < _length ) _int32s.push_back( _readInt<int32_t>() ); }
|
||||
|
||||
|
@ -607,12 +646,15 @@ namespace {
|
|||
bool readNode ();
|
||||
bool readBox ();
|
||||
bool readText ();
|
||||
bool readTextbody ();
|
||||
bool readTextbody ( const Layer* );
|
||||
bool readStrans ();
|
||||
bool readProperty ();
|
||||
void xyToComponent ( const Layer* );
|
||||
void xyToPath ( uint16_t pathtype, const Layer*, DbU::Unit width );
|
||||
void makeInstances ();
|
||||
void makeExternals ();
|
||||
Net* fusedNet ();
|
||||
void addNetReference ( Net*, const Layer*, DbU::Unit x, DbU::Unit y );
|
||||
private:
|
||||
struct DelayedInstance {
|
||||
inline DelayedInstance ( Cell* owner, string masterName, const Transformation& );
|
||||
|
@ -621,6 +663,12 @@ namespace {
|
|||
string _masterName;
|
||||
Transformation _transformation;
|
||||
};
|
||||
private:
|
||||
struct PinPoint {
|
||||
inline PinPoint ( const Layer*, DbU::Unit x, DbU::Unit y );
|
||||
const Layer* _layer;
|
||||
Point _position;
|
||||
};
|
||||
private:
|
||||
static vector<const Layer*> _gdsLayerTable;
|
||||
vector<DelayedInstance> _delayedInstances;
|
||||
|
@ -637,6 +685,9 @@ namespace {
|
|||
int64_t _SREFCount;
|
||||
bool _validSyntax;
|
||||
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;
|
||||
|
||||
|
||||
|
@ -688,7 +744,7 @@ namespace {
|
|||
{
|
||||
if (_gdsLayerTable.empty()) _staticInit();
|
||||
|
||||
_stream.open( gdsPath, ios_base::in );
|
||||
_stream.open( gdsPath, ios_base::in|ios_base::binary );
|
||||
|
||||
_stream >> _record;
|
||||
if (not _record.isHEADER()) {
|
||||
|
@ -715,7 +771,7 @@ namespace {
|
|||
|
||||
bool GdsStream::read ( Library* library )
|
||||
{
|
||||
//cerr << "GdsStream::read(Library*)" << endl;
|
||||
cdebug_log(101,1) << "GdsStream::read(Library*)" << endl;
|
||||
|
||||
_library = library;
|
||||
|
||||
|
@ -724,6 +780,7 @@ namespace {
|
|||
" in \"%s\""
|
||||
, _gdsPath.c_str() ) << endl;
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
_stream >> _record;
|
||||
|
@ -737,13 +794,20 @@ namespace {
|
|||
" in \"%s\""
|
||||
, _gdsPath.c_str() ) << endl;
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
if (_record.isREFLIBS ()) { _stream >> _record; }
|
||||
if (_record.isFONTS ()) { _stream >> _record; }
|
||||
if (_record.isATTRTABLE ()) { _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()) {
|
||||
_scale = DbU::fromPhysical( _record.getDoubles()[1], DbU::Unity );
|
||||
|
@ -757,17 +821,20 @@ namespace {
|
|||
|
||||
if (_validSyntax and not _record.isENDLIB()) { misplacedRecord(); }
|
||||
|
||||
if (_validSyntax) makeInstances();
|
||||
if (_validSyntax) {
|
||||
makeInstances();
|
||||
makeExternals();
|
||||
}
|
||||
|
||||
_library = NULL;
|
||||
//cerr << "GdsStream::read(Library*) - return:" << _validSyntax << endl;
|
||||
cdebug_log(101,-1) << " GdsStream::read(Library*) - return:" << _validSyntax << endl;
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readFormatType ()
|
||||
{
|
||||
//cerr << "GdsStream::readFormatType()" << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readFormatType()" << endl;
|
||||
|
||||
if (_record.isMASK()) {
|
||||
_stream >> _record;
|
||||
|
@ -779,14 +846,14 @@ namespace {
|
|||
else { _validSyntax = false; return _validSyntax; }
|
||||
}
|
||||
|
||||
//cerr << "GdsStream::readFormatType() - return:" << _validSyntax << endl;
|
||||
//cdebug(101,0) << "GdsStream::readFormatType() - return:" << _validSyntax << endl;
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readStructure ()
|
||||
{
|
||||
//cerr << "GdsStream::readStructure()" << endl;
|
||||
cdebug_log(101,1) << "GdsStream::readStructure()" << endl;
|
||||
|
||||
if (_record.isSTRNAME()) {
|
||||
if (_library) {
|
||||
|
@ -819,7 +886,9 @@ namespace {
|
|||
if (not _skipENDEL) {
|
||||
if (_record.isENDEL()) { _stream >> _record; }
|
||||
else {
|
||||
_validSyntax = false; break;
|
||||
_validSyntax = false;
|
||||
cdebug_log(101,0) << "Missing ENDEL inside STRUCTURE loop" << endl;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
_skipENDEL = false;
|
||||
|
@ -832,7 +901,7 @@ namespace {
|
|||
_cell->setAbutmentBox( _cell->getBoundingBox() );
|
||||
UpdateSession::open();
|
||||
_cell = NULL;
|
||||
cerr << "GdsStream::readStructure() - return:" << _validSyntax << endl;
|
||||
cdebug_log(101,-1) << " GdsStream::readStructure() - return:" << _validSyntax << endl;
|
||||
|
||||
return _validSyntax;
|
||||
}
|
||||
|
@ -840,25 +909,41 @@ namespace {
|
|||
|
||||
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.isPLEX ()) { _stream >> _record; }
|
||||
if (_record.isLAYER ()) { _stream >> _record; }
|
||||
else { _validSyntax = false; return _validSyntax; }
|
||||
if (_record.isLAYER ()) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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; }
|
||||
else { _validSyntax = false; return _validSyntax; }
|
||||
else {
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
if (_record.isPRESENTATION()) { _stream >> _record; }
|
||||
if (_record.isPATH ()) { _stream >> _record; }
|
||||
|
@ -867,27 +952,55 @@ namespace {
|
|||
if (_record.isSTRANS()) {
|
||||
_stream >> _record;
|
||||
readStrans();
|
||||
if (not _validSyntax) return _validSyntax;
|
||||
if (not _validSyntax) {
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
}
|
||||
|
||||
if (_record.isXY()) { _stream >> _record; }
|
||||
else { _validSyntax = false; return _validSyntax; }
|
||||
if (_record.isXY()) {
|
||||
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()) {
|
||||
_text = _record.getName();
|
||||
_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;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readStrans ()
|
||||
{
|
||||
//cerr << "GdsStream::readStrans()" << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readStrans()" << endl;
|
||||
|
||||
_angle = 0.0;
|
||||
_xReflection = _record.hasXReflection();
|
||||
|
@ -895,14 +1008,14 @@ namespace {
|
|||
if (_record.isMAG ()) { _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;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readBoundary ()
|
||||
{
|
||||
//cerr << "GdsStream::readBoundary()" << endl;
|
||||
cdebug_log(101,1) << "GdsStream::readBoundary()" << endl;
|
||||
|
||||
const Layer* layer = NULL;
|
||||
|
||||
|
@ -918,29 +1031,39 @@ namespace {
|
|||
}
|
||||
_stream >> _record;
|
||||
} else {
|
||||
_validSyntax = false; return _validSyntax;
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
if (_record.isDATATYPE()) { _stream >> _record; }
|
||||
else { _validSyntax = false; return _validSyntax; }
|
||||
else {
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
if (_record.isXY()) {
|
||||
if (_cell and layer) xyToComponent( layer );
|
||||
else _stream >> _record;
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
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.isPLEX ()) { _stream >> _record; }
|
||||
|
@ -953,33 +1076,50 @@ namespace {
|
|||
) << endl;
|
||||
}
|
||||
_stream >> _record;
|
||||
cdebug_log(101,0) << layer << endl;
|
||||
} else {
|
||||
_validSyntax = false; return _validSyntax;
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
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.isWIDTH ()) { _stream >> _record; }
|
||||
if (_record.isPATHTYPE()) {
|
||||
pathtype = _record.getInt16s()[0];
|
||||
_stream >> _record;
|
||||
}
|
||||
if (_record.isWIDTH ()) {
|
||||
width = _record.getInt32s()[0] * _scale;
|
||||
_stream >> _record;
|
||||
}
|
||||
if (_record.isBGNEXTN ()) { _stream >> _record; }
|
||||
if (_record.isENDEXTN ()) { _stream >> _record; }
|
||||
|
||||
if (_record.isXY()) {
|
||||
if (_cell and layer) xyToComponent( layer );
|
||||
_stream >> _record;
|
||||
if (_cell and layer) xyToPath( pathtype, layer, width );
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readSref ()
|
||||
{
|
||||
//cerr << "GdsStream::readSref()" << endl;
|
||||
cdebug_log(101,1) << "GdsStream::readSref()" << endl;
|
||||
resetStrans();
|
||||
|
||||
string masterName;
|
||||
|
@ -991,22 +1131,28 @@ namespace {
|
|||
|
||||
if (_record.isSNAME()) {
|
||||
masterName = _record.getName();
|
||||
|
||||
_stream >> _record;
|
||||
} else {
|
||||
_validSyntax = false; return _validSyntax;
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
if (_record.isSTRANS()) {
|
||||
readStrans();
|
||||
//_stream >> _record;
|
||||
if (not _validSyntax) return _validSyntax;
|
||||
if (not _validSyntax) {
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
}
|
||||
|
||||
if (_record.isXY()) {
|
||||
vector<int32_t> coordinates = _record.getInt32s();
|
||||
if (coordinates.size() != 2) {
|
||||
_validSyntax = false; return _validSyntax;
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
xpos = coordinates[ 0 ]*_scale;
|
||||
|
@ -1014,7 +1160,9 @@ namespace {
|
|||
|
||||
_stream >> _record;
|
||||
} else {
|
||||
_validSyntax = false; return _validSyntax;
|
||||
_validSyntax = false;
|
||||
cdebug_tabw(101,-1);
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
if (not masterName.empty()) {
|
||||
|
@ -1048,14 +1196,14 @@ namespace {
|
|||
, Transformation(xpos,ypos,orient)) );
|
||||
}
|
||||
|
||||
//cerr << "GdsStream::readSref() - return:" << _validSyntax << endl;
|
||||
cdebug_log(101,-1) << "GdsStream::readSref() - return:" << _validSyntax << endl;
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readAref ()
|
||||
{
|
||||
//cerr << "GdsStream::readAref()" << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readAref()" << endl;
|
||||
|
||||
const Layer* layer = NULL;
|
||||
|
||||
|
@ -1087,14 +1235,14 @@ namespace {
|
|||
_validSyntax = false; return _validSyntax;
|
||||
}
|
||||
|
||||
//cerr << "GdsStream::readAref() - return:" << _validSyntax << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readAref() - return:" << _validSyntax << endl;
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readNode ()
|
||||
{
|
||||
//cerr << "GdsStream::readNode()" << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readNode()" << endl;
|
||||
|
||||
const Layer* layer = NULL;
|
||||
|
||||
|
@ -1117,14 +1265,14 @@ namespace {
|
|||
_validSyntax = false; return _validSyntax;
|
||||
}
|
||||
|
||||
//cerr << "GdsStream::readNode() - return:" << _validSyntax << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readNode() - return:" << _validSyntax << endl;
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readBox ()
|
||||
{
|
||||
//cerr << "GdsStream::readBox()" << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readBox()" << endl;
|
||||
|
||||
const Layer* layer = NULL;
|
||||
|
||||
|
@ -1147,19 +1295,19 @@ namespace {
|
|||
_validSyntax = false; return _validSyntax;
|
||||
}
|
||||
|
||||
//cerr << "GdsStream::readBox() - return:" << _validSyntax << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readBox() - return:" << _validSyntax << endl;
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
|
||||
bool GdsStream::readProperty ()
|
||||
{
|
||||
//cerr << "GdsStream::readProperty()" << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readProperty()" << endl;
|
||||
|
||||
if (_record.isPROPVALUE ()) { _stream >> _record; }
|
||||
else { _validSyntax = false; return _validSyntax; }
|
||||
|
||||
//cerr << "GdsStream::readProperty() - return:" << _validSyntax << endl;
|
||||
cdebug_log(101,0) << "GdsStream::readProperty() - return:" << _validSyntax << endl;
|
||||
return _validSyntax;
|
||||
}
|
||||
|
||||
|
@ -1174,8 +1322,9 @@ namespace {
|
|||
|
||||
_stream >> _record;
|
||||
|
||||
if (_record.getType() == GdsRecord::ENDEL) {
|
||||
_stream >> _record;
|
||||
if ( (_record.getType() == GdsRecord::ENDEL)
|
||||
or (_record.getType() == GdsRecord::STRING)) {
|
||||
//_stream >> _record;
|
||||
} else {
|
||||
_validSyntax = false;
|
||||
return;
|
||||
|
@ -1184,9 +1333,7 @@ namespace {
|
|||
Net* net = NULL;
|
||||
if (_record.getType() == GdsRecord::TEXT) {
|
||||
_stream >> _record;
|
||||
cerr << " BOUNDARY --> TEXT record" << endl;
|
||||
readText();
|
||||
cerr << " AFTER readText()" << endl;
|
||||
|
||||
if (not _text.empty()) {
|
||||
net = _cell->getNet( _text );
|
||||
|
@ -1214,33 +1361,174 @@ namespace {
|
|||
Box boundingBox;
|
||||
for ( Point p : points ) boundingBox.merge( p );
|
||||
_component = Pad::create( net, layer, boundingBox );
|
||||
cerr << _component << endl;
|
||||
} else {
|
||||
_component = Rectilinear::create( net, layer, points );
|
||||
}
|
||||
// cdebug(101,0) << "| " << net->getCell() << endl;
|
||||
// cdebug(101,0) << "| " << _component << endl;
|
||||
|
||||
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 ()
|
||||
{
|
||||
//cerr << "GdsStream::makeInstances(): " << endl;
|
||||
cdebug_log(101,1) << "GdsStream::makeInstances(): " << endl;
|
||||
|
||||
for ( const DelayedInstance& di : _delayedInstances ) {
|
||||
Cell* masterCell = _library->getCell( di._masterName );
|
||||
|
||||
if (masterCell) {
|
||||
string insName = "sref_" + getString(_SREFCount++);
|
||||
//Instance* instance =
|
||||
Instance* instance =
|
||||
Instance::create( di._owner
|
||||
, insName
|
||||
, masterCell
|
||||
, di._transformation
|
||||
, 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