Add & fix GDS parser for PATH of type 4 (seen in the PLL).
* New: In CRL::GdsStream::xyToPath(), now manage BGNEXTN & ENDEXTN for PATHTYPE 4. The begin/end Contact are created to use exactly the area of the extension. Otherwise there were overspill when the size of the extension is greater than the width of the path. Also need to do a sligth shift if the extension is an odd number of foundry grid. This fix the offgrid problems.
This commit is contained in:
parent
39231d5191
commit
5b6bc7c91b
|
@ -27,6 +27,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#include "vlsisapd/configuration/Configuration.h"
|
#include "vlsisapd/configuration/Configuration.h"
|
||||||
|
#include "hurricane/DebugSession.h"
|
||||||
#include "hurricane/Warning.h"
|
#include "hurricane/Warning.h"
|
||||||
#include "hurricane/DataBase.h"
|
#include "hurricane/DataBase.h"
|
||||||
#include "hurricane/Technology.h"
|
#include "hurricane/Technology.h"
|
||||||
|
@ -203,6 +204,8 @@ namespace {
|
||||||
void readUnits ();
|
void readUnits ();
|
||||||
void readLayer ();
|
void readLayer ();
|
||||||
void readWidth ();
|
void readWidth ();
|
||||||
|
void readBgnextn ();
|
||||||
|
void readEndextn ();
|
||||||
void readPathtype ();
|
void readPathtype ();
|
||||||
void readStrname ();
|
void readStrname ();
|
||||||
void readXy ();
|
void readXy ();
|
||||||
|
@ -381,8 +384,8 @@ namespace {
|
||||||
case BOX: readDummy( false ); break;
|
case BOX: readDummy( false ); break;
|
||||||
case BOXTYPE: readDummy( false ); break;
|
case BOXTYPE: readDummy( false ); break;
|
||||||
case PLEX: readDummy( false ); break;
|
case PLEX: readDummy( false ); break;
|
||||||
case BGNEXTN: readDummy( false ); break;
|
case BGNEXTN: readBgnextn(); break;
|
||||||
case ENDEXTN: readDummy( false ); break;
|
case ENDEXTN: readEndextn(); break;
|
||||||
case TAPENUM: readDummy( false ); break;
|
case TAPENUM: readDummy( false ); break;
|
||||||
case TAPECODE: readDummy( false ); break;
|
case TAPECODE: readDummy( false ); break;
|
||||||
case STRCLASS: readDummy( false ); break;
|
case STRCLASS: readDummy( false ); break;
|
||||||
|
@ -543,6 +546,14 @@ namespace {
|
||||||
{ _int32s.push_back( _readInt<uint32_t>() ); }
|
{ _int32s.push_back( _readInt<uint32_t>() ); }
|
||||||
|
|
||||||
|
|
||||||
|
void GdsRecord::readBgnextn ()
|
||||||
|
{ _int32s.push_back( _readInt<uint32_t>() ); }
|
||||||
|
|
||||||
|
|
||||||
|
void GdsRecord::readEndextn ()
|
||||||
|
{ _int32s.push_back( _readInt<uint32_t>() ); }
|
||||||
|
|
||||||
|
|
||||||
void GdsRecord::readPathtype ()
|
void GdsRecord::readPathtype ()
|
||||||
{ _int16s.push_back( _readInt<uint16_t>() ); }
|
{ _int16s.push_back( _readInt<uint16_t>() ); }
|
||||||
|
|
||||||
|
@ -650,7 +661,11 @@ namespace {
|
||||||
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 xyToPath ( uint16_t pathtype
|
||||||
|
, const Layer*
|
||||||
|
, DbU::Unit width
|
||||||
|
, DbU::Unit bgnextn
|
||||||
|
, DbU::Unit endextn );
|
||||||
void makeInstances ();
|
void makeInstances ();
|
||||||
void makeExternals ();
|
void makeExternals ();
|
||||||
Net* fusedNet ();
|
Net* fusedNet ();
|
||||||
|
@ -1077,6 +1092,8 @@ namespace {
|
||||||
const Layer* layer = NULL;
|
const Layer* layer = NULL;
|
||||||
DbU::Unit width = 0;
|
DbU::Unit width = 0;
|
||||||
uint16_t pathtype = 0;
|
uint16_t pathtype = 0;
|
||||||
|
DbU::Unit bgnextn = 0;
|
||||||
|
DbU::Unit endextn = 0;
|
||||||
|
|
||||||
if (_record.isELFLAGS()) { _stream >> _record; }
|
if (_record.isELFLAGS()) { _stream >> _record; }
|
||||||
if (_record.isPLEX ()) { _stream >> _record; }
|
if (_record.isPLEX ()) { _stream >> _record; }
|
||||||
|
@ -1114,11 +1131,17 @@ namespace {
|
||||||
width = _record.getInt32s()[0] * _scale;
|
width = _record.getInt32s()[0] * _scale;
|
||||||
_stream >> _record;
|
_stream >> _record;
|
||||||
}
|
}
|
||||||
if (_record.isBGNEXTN ()) { _stream >> _record; }
|
if (_record.isBGNEXTN ()) {
|
||||||
if (_record.isENDEXTN ()) { _stream >> _record; }
|
bgnextn = _record.getInt32s()[0] * _scale;
|
||||||
|
_stream >> _record;
|
||||||
|
}
|
||||||
|
if (_record.isENDEXTN ()) {
|
||||||
|
endextn = _record.getInt32s()[0] * _scale;
|
||||||
|
_stream >> _record;
|
||||||
|
}
|
||||||
|
|
||||||
if (_record.isXY()) {
|
if (_record.isXY()) {
|
||||||
if (_cell and layer) xyToPath( pathtype, layer, width );
|
if (_cell and layer) xyToPath( pathtype, layer, width, bgnextn, endextn );
|
||||||
} else {
|
} else {
|
||||||
_validSyntax = false;
|
_validSyntax = false;
|
||||||
cdebug_tabw(101,-1);
|
cdebug_tabw(101,-1);
|
||||||
|
@ -1409,11 +1432,17 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GdsStream::xyToPath ( uint16_t pathtype, const Layer* layer, DbU::Unit width )
|
void GdsStream::xyToPath ( uint16_t pathtype
|
||||||
|
, const Layer* layer
|
||||||
|
, DbU::Unit width
|
||||||
|
, DbU::Unit bgnextn
|
||||||
|
, DbU::Unit endextn )
|
||||||
{
|
{
|
||||||
cdebug_log(101,0) << "GdsStream::xyToPath(): pathtype=" << pathtype
|
cdebug_log(101,0) << "GdsStream::xyToPath(): pathtype=" << pathtype
|
||||||
<< " layer=" << layer->getName()
|
<< " layer=" << layer->getName()
|
||||||
<< " width=" << DbU::getValueString(width) << endl;
|
<< " width=" << DbU::getValueString(width)
|
||||||
|
<< " bgnextn=" << DbU::getValueString(bgnextn)
|
||||||
|
<< " endextn=" << DbU::getValueString(endextn) << endl;
|
||||||
|
|
||||||
vector<Point> points;
|
vector<Point> points;
|
||||||
vector<int32_t> coordinates = _record.getInt32s();
|
vector<int32_t> coordinates = _record.getInt32s();
|
||||||
|
@ -1428,7 +1457,10 @@ namespace {
|
||||||
|
|
||||||
Net* net = fusedNet();
|
Net* net = fusedNet();
|
||||||
|
|
||||||
|
cdebug_log(101,0) << "Points" << endl;
|
||||||
|
cdebug_log(101,0) << " 0 | " << points[0] << endl;
|
||||||
for ( size_t i=1 ; i<points.size() ; ++i ) {
|
for ( size_t i=1 ; i<points.size() ; ++i ) {
|
||||||
|
cdebug_log(101,0) << " " << i << " | " << points[i] << endl;
|
||||||
if ( (points[i-1].getX() != points[i].getX())
|
if ( (points[i-1].getX() != points[i].getX())
|
||||||
and (points[i-1].getY() != points[i].getY()) ) {
|
and (points[i-1].getY() != points[i].getY()) ) {
|
||||||
cerr << Error( "GdsStream::xyToPath(): Non-rectilinear paths are not supporteds (skipped)."
|
cerr << Error( "GdsStream::xyToPath(): Non-rectilinear paths are not supporteds (skipped)."
|
||||||
|
@ -1437,35 +1469,86 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DbU::Unit twoGrid = DbU::fromGrid( 2 );
|
||||||
|
DbU::Unit xadjust = 0;
|
||||||
|
DbU::Unit yadjust = 0;
|
||||||
DbU::Unit hWidthCap = width;
|
DbU::Unit hWidthCap = width;
|
||||||
DbU::Unit vWidthCap = width;
|
DbU::Unit vWidthCap = width;
|
||||||
if (pathtype == 0) {
|
if (pathtype == 0) {
|
||||||
if (points[0].getX() == points[1].getX()) vWidthCap = 0;
|
if (points[0].getX() == points[1].getX()) vWidthCap = 0;
|
||||||
else hWidthCap = 0;
|
else hWidthCap = 0;
|
||||||
}
|
}
|
||||||
|
if (pathtype == 4) {
|
||||||
|
if (not (bgnextn % twoGrid)) twoGrid = 0;
|
||||||
|
else {
|
||||||
|
cdebug_log(101,0) << "bgnextn is an odd number of grid." << endl;
|
||||||
|
twoGrid >>= 1;
|
||||||
|
}
|
||||||
|
if (points[0].getX() == points[1].getX()) {
|
||||||
|
hWidthCap = width;
|
||||||
|
vWidthCap = bgnextn + twoGrid;
|
||||||
|
yadjust = -vWidthCap/2 + twoGrid;
|
||||||
|
if (points[0].getY() > points[1].getY())
|
||||||
|
yadjust = -yadjust;
|
||||||
|
} else {
|
||||||
|
hWidthCap = bgnextn + twoGrid;
|
||||||
|
vWidthCap = width;
|
||||||
|
xadjust = -hWidthCap/2 + twoGrid;
|
||||||
|
if (points[0].getX() > points[1].getX())
|
||||||
|
xadjust = -xadjust;
|
||||||
|
}
|
||||||
|
}
|
||||||
Contact* source = Contact::create( net
|
Contact* source = Contact::create( net
|
||||||
, layer
|
, layer
|
||||||
, points[0].getX()
|
, points[0].getX() + xadjust
|
||||||
, points[0].getY()
|
, points[0].getY() + yadjust
|
||||||
, hWidthCap
|
, hWidthCap
|
||||||
, vWidthCap );
|
, vWidthCap );
|
||||||
hWidthCap = width;
|
cdebug_log(101,0) << "+ " << source << endl;
|
||||||
vWidthCap = width;
|
|
||||||
Contact* target = NULL;
|
Contact* target = NULL;
|
||||||
Segment* segment = NULL;
|
Segment* segment = NULL;
|
||||||
for ( size_t i=1 ; i<points.size() ; ++i ) {
|
for ( size_t i=1 ; i<points.size() ; ++i ) {
|
||||||
|
hWidthCap = width;
|
||||||
|
vWidthCap = width;
|
||||||
|
xadjust = 0;
|
||||||
|
yadjust = 0;
|
||||||
if (i == points.size()-1) {
|
if (i == points.size()-1) {
|
||||||
if (pathtype == 0) {
|
if (pathtype == 0) {
|
||||||
if (points[0].getX() == points[1].getX()) vWidthCap = 0;
|
if (points[i].getX() == points[i-1].getX()) vWidthCap = 0;
|
||||||
else hWidthCap = 0;
|
else hWidthCap = 0;
|
||||||
}
|
}
|
||||||
|
if (pathtype == 4) {
|
||||||
|
twoGrid = DbU::fromGrid( 2 );
|
||||||
|
if (not (endextn % twoGrid)) twoGrid = 0;
|
||||||
|
else {
|
||||||
|
cdebug_log(101,0) << "endextn is an odd number of grid." << endl;
|
||||||
|
twoGrid >>= 1;
|
||||||
|
}
|
||||||
|
if (points[i-1].getX() == points[i].getX()) {
|
||||||
|
hWidthCap = width;
|
||||||
|
vWidthCap = endextn + twoGrid;
|
||||||
|
yadjust = vWidthCap/2 - twoGrid;
|
||||||
|
if (points[i-1].getY() > points[i].getY())
|
||||||
|
yadjust = -yadjust;
|
||||||
|
} else {
|
||||||
|
cdebug_log(101,0) << "endextn=" << DbU::getValueString(endextn)
|
||||||
|
<< " twoGrid=" << DbU::getValueString(twoGrid) << endl;
|
||||||
|
hWidthCap = endextn + twoGrid;
|
||||||
|
vWidthCap = width;
|
||||||
|
xadjust = hWidthCap/2 - twoGrid;
|
||||||
|
if (points[i-1].getX() > points[i].getX())
|
||||||
|
xadjust = -xadjust;
|
||||||
|
cdebug_log(101,0) << "xadjust=" << DbU::getValueString(xadjust) << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
target = Contact::create( net
|
target = Contact::create( net
|
||||||
, layer
|
, layer
|
||||||
, points[i].getX()
|
, points[i].getX() + xadjust
|
||||||
, points[i].getY()
|
, points[i].getY() + yadjust
|
||||||
, hWidthCap
|
, hWidthCap
|
||||||
, vWidthCap );
|
, vWidthCap );
|
||||||
|
cdebug_log(101,0) << "+ " << target << endl;
|
||||||
if (points[i-1].getY() == points[i].getY()) {
|
if (points[i-1].getY() == points[i].getY()) {
|
||||||
segment = Horizontal::create( source
|
segment = Horizontal::create( source
|
||||||
, target
|
, target
|
||||||
|
@ -1481,6 +1564,7 @@ namespace {
|
||||||
, width
|
, width
|
||||||
, 0, 0 );
|
, 0, 0 );
|
||||||
}
|
}
|
||||||
|
cdebug_log(101,0) << "| " << segment << endl;
|
||||||
if (not net->isAutomatic()) NetExternalComponents::setExternal( segment );
|
if (not net->isAutomatic()) NetExternalComponents::setExternal( segment );
|
||||||
source = target;
|
source = target;
|
||||||
}
|
}
|
||||||
|
@ -1620,7 +1704,9 @@ namespace CRL {
|
||||||
|
|
||||||
bool Gds::load ( Library* library, string gdsPath )
|
bool Gds::load ( Library* library, string gdsPath )
|
||||||
{
|
{
|
||||||
|
//DebugSession::open( 101, 110 );
|
||||||
UpdateSession::open();
|
UpdateSession::open();
|
||||||
|
Contact::disableCheckMinSize();
|
||||||
|
|
||||||
GdsStream gstream ( gdsPath );
|
GdsStream gstream ( gdsPath );
|
||||||
|
|
||||||
|
@ -1630,7 +1716,9 @@ namespace CRL {
|
||||||
, gdsPath.c_str()
|
, gdsPath.c_str()
|
||||||
) << endl;
|
) << endl;
|
||||||
|
|
||||||
|
Contact::enableCheckMinSize();
|
||||||
UpdateSession::close();
|
UpdateSession::close();
|
||||||
|
//DebugSession::close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue