In GdsStream & LefImport, thorough verification that coordinates are on foundry grid.
This commit is contained in:
parent
e470ca8375
commit
96f41776a8
|
@ -474,6 +474,7 @@ namespace {
|
||||||
public:
|
public:
|
||||||
GdsStream ( string filename );
|
GdsStream ( string filename );
|
||||||
~GdsStream ();
|
~GdsStream ();
|
||||||
|
inline Point putOnGrid ( const Point& ) const;
|
||||||
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 );
|
||||||
|
@ -496,9 +497,10 @@ namespace {
|
||||||
GdsStream& operator<< ( const Cell* );
|
GdsStream& operator<< ( const Cell* );
|
||||||
GdsStream& operator<< ( const Transformation& );
|
GdsStream& operator<< ( const Transformation& );
|
||||||
private:
|
private:
|
||||||
ofstream _ostream;
|
ofstream _ostream;
|
||||||
double _dbuPerUu;
|
double _dbuPerUu;
|
||||||
double _metricDbU;
|
double _metricDbU;
|
||||||
|
DbU::Unit _oneGrid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -522,14 +524,31 @@ namespace {
|
||||||
inline GdsRecord GdsStream::SNAME ( const Name& n ) { return GdsRecord(GdsRecord::SNAME,getString(n)); }
|
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 Name& n ) { return GdsRecord(GdsRecord::STRING,getString(n)); }
|
||||||
inline GdsRecord GdsStream::STRING ( const string s ) { return GdsRecord(GdsRecord::STRING,s); }
|
inline GdsRecord GdsStream::STRING ( const string s ) { return GdsRecord(GdsRecord::STRING,s); }
|
||||||
|
|
||||||
inline int32_t GdsStream::toGdsDbu ( DbU::Unit v ) const
|
inline int32_t GdsStream::toGdsDbu ( DbU::Unit v ) const
|
||||||
{ return uint32_t( std::lrint( DbU::toPhysical( v, DbU::UnitPower::Unity ) / _metricDbU )); }
|
{
|
||||||
|
if (v % _oneGrid) {
|
||||||
|
cerr << getString( Error( "Offgrid value %s (DbU=%d), grid %s (DbU=%d)."
|
||||||
|
, DbU::getValueString(v).c_str(), v
|
||||||
|
, DbU::getValueString(_oneGrid).c_str(), _oneGrid ))
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
return uint32_t( std::lrint( DbU::toPhysical( v, DbU::UnitPower::Unity ) / _metricDbU ));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Point GdsStream::putOnGrid ( const Point& p ) const
|
||||||
|
{
|
||||||
|
return Point( p.getX() - (p.getX() % _oneGrid)
|
||||||
|
, p.getY() - (p.getY() % _oneGrid));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GdsStream::GdsStream ( string filename )
|
GdsStream::GdsStream ( string filename )
|
||||||
: _ostream ()
|
: _ostream ()
|
||||||
, _dbuPerUu (Cfg::getParamDouble("gdsDriver.dbuPerUu" ,0.001)->asDouble()) // 1000
|
, _dbuPerUu (Cfg::getParamDouble("gdsDriver.dbuPerUu" ,0.001)->asDouble()) // 1000
|
||||||
, _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um.
|
, _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um.
|
||||||
|
, _oneGrid (DbU::grid(1.0))
|
||||||
{
|
{
|
||||||
std::fesetround( FE_TONEAREST );
|
std::fesetround( FE_TONEAREST );
|
||||||
_ostream.open( filename, ios_base::out|ios_base::binary );
|
_ostream.open( filename, ios_base::out|ios_base::binary );
|
||||||
|
@ -723,7 +742,7 @@ namespace {
|
||||||
if (cell->getName() == "control_r") return *this;
|
if (cell->getName() == "control_r") return *this;
|
||||||
if (not hasLayout(cell)) return *this;
|
if (not hasLayout(cell)) return *this;
|
||||||
|
|
||||||
//cerr << "GdsStream::operator<<(Cell*): " << getString(cell) << endl;
|
cdebug_log(101,1) << "GdsStream::operator<<(Cell*): " << getString(cell) << endl;
|
||||||
|
|
||||||
Technology* tech = DataBase::getDB()->getTechnology();
|
Technology* tech = DataBase::getDB()->getTechnology();
|
||||||
|
|
||||||
|
@ -762,7 +781,9 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( Net* net : cell->getNets() ) {
|
for ( Net* net : cell->getNets() ) {
|
||||||
|
cdebug_log(101,1) << "Writing net " << net << endl;
|
||||||
for ( Component* component : net->getComponents() ) {
|
for ( Component* component : net->getComponents() ) {
|
||||||
|
cdebug_log(101,0) << "Writing " << component << endl;
|
||||||
Polygon* polygon = dynamic_cast<Polygon*>(component);
|
Polygon* polygon = dynamic_cast<Polygon*>(component);
|
||||||
if (polygon) {
|
if (polygon) {
|
||||||
vector< vector<Point> > subpolygons;
|
vector< vector<Point> > subpolygons;
|
||||||
|
@ -849,7 +870,7 @@ namespace {
|
||||||
(*this) << TEXTTYPE( 0 );
|
(*this) << TEXTTYPE( 0 );
|
||||||
cdebug_log(101,0) << "TEXTYPE end record" << endl;
|
cdebug_log(101,0) << "TEXTYPE end record" << endl;
|
||||||
(*this) << PRESENTATION( 5 );
|
(*this) << PRESENTATION( 5 );
|
||||||
(*this) << bb.getCenter();
|
(*this) << putOnGrid( bb.getCenter() );
|
||||||
(*this) << STRING( name );
|
(*this) << STRING( name );
|
||||||
(*this) << ENDEL;
|
(*this) << ENDEL;
|
||||||
cdebug_log(101,0) << "TEXT ENDEL" << endl;
|
cdebug_log(101,0) << "TEXT ENDEL" << endl;
|
||||||
|
@ -859,9 +880,11 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*this) << ENDSTR;
|
(*this) << ENDSTR;
|
||||||
|
cdebug_tabw(101,-1);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,7 @@ namespace {
|
||||||
Net* _net;
|
Net* _net;
|
||||||
string _busBits;
|
string _busBits;
|
||||||
double _unitsMicrons;
|
double _unitsMicrons;
|
||||||
|
DbU::Unit _oneGrid;
|
||||||
map< string, vector<Component*> > _pinComponents;
|
map< string, vector<Component*> > _pinComponents;
|
||||||
static map<string,Layer*> _layerLut;
|
static map<string,Layer*> _layerLut;
|
||||||
vector<string> _unmatchedLayers;
|
vector<string> _unmatchedLayers;
|
||||||
|
@ -179,7 +180,6 @@ namespace {
|
||||||
inline void LefParser::setCellGauge ( CellGauge* gauge ) { _cellGauge=gauge; }
|
inline void LefParser::setCellGauge ( CellGauge* gauge ) { _cellGauge=gauge; }
|
||||||
inline Net* LefParser::getNet () const { return _net; }
|
inline Net* LefParser::getNet () const { return _net; }
|
||||||
inline void LefParser::setNet ( Net* net ) { _net=net; }
|
inline void LefParser::setNet ( Net* net ) { _net=net; }
|
||||||
inline DbU::Unit LefParser::fromUnitsMicrons ( double d ) const { return DbU::fromPhysical(d,DbU::Micro); }
|
|
||||||
inline double LefParser::getUnitsMicrons () const { return _unitsMicrons; }
|
inline double LefParser::getUnitsMicrons () const { return _unitsMicrons; }
|
||||||
inline void LefParser::setUnitsMicrons ( double precision ) { _unitsMicrons=precision; }
|
inline void LefParser::setUnitsMicrons ( double precision ) { _unitsMicrons=precision; }
|
||||||
inline int LefParser::getNthMetal () const { return _nthMetal; }
|
inline int LefParser::getNthMetal () const { return _nthMetal; }
|
||||||
|
@ -200,6 +200,18 @@ namespace {
|
||||||
inline void LefParser::addPinComponent ( string name, Component* comp ) { _pinComponents[name].push_back(comp); }
|
inline void LefParser::addPinComponent ( string name, Component* comp ) { _pinComponents[name].push_back(comp); }
|
||||||
inline void LefParser::clearPinComponents () { _pinComponents.clear(); }
|
inline void LefParser::clearPinComponents () { _pinComponents.clear(); }
|
||||||
|
|
||||||
|
inline DbU::Unit LefParser::fromUnitsMicrons ( double d ) const
|
||||||
|
{
|
||||||
|
DbU::Unit u = DbU::fromPhysical(d,DbU::Micro);
|
||||||
|
if (u % _oneGrid) {
|
||||||
|
cerr << Error( "LefParser::fromUnitsMicrons(): Offgrid value %s (DbU=%d), grid %s (DbU=%d)."
|
||||||
|
, DbU::getValueString(u).c_str(), u
|
||||||
|
, DbU::getValueString(_oneGrid).c_str(), _oneGrid )
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string LefParser::_gdsForeignDirectory = "";
|
string LefParser::_gdsForeignDirectory = "";
|
||||||
Library* LefParser::_mergeLibrary = nullptr;
|
Library* LefParser::_mergeLibrary = nullptr;
|
||||||
|
@ -264,6 +276,7 @@ namespace {
|
||||||
, _net (nullptr)
|
, _net (nullptr)
|
||||||
, _busBits ("()")
|
, _busBits ("()")
|
||||||
, _unitsMicrons (0.01)
|
, _unitsMicrons (0.01)
|
||||||
|
, _oneGrid (DbU::fromGrid(1.0))
|
||||||
, _unmatchedLayers ()
|
, _unmatchedLayers ()
|
||||||
, _errors ()
|
, _errors ()
|
||||||
, _nthMetal (0)
|
, _nthMetal (0)
|
||||||
|
@ -497,7 +510,10 @@ namespace {
|
||||||
LefParser* parser = (LefParser*)ud;
|
LefParser* parser = (LefParser*)ud;
|
||||||
AllianceFramework* af = AllianceFramework::get();
|
AllianceFramework* af = AllianceFramework::get();
|
||||||
|
|
||||||
if (_gdsForeignDirectory.empty()) return 0;
|
if (_gdsForeignDirectory.empty()) {
|
||||||
|
cerr << Warning( "LefParser::_macroForeignCbk(): GDS directory *not* set, ignoring FOREIGN statement." ) << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
string gdsPath = _gdsForeignDirectory + "/" + foreign->cellName() + ".gds";
|
string gdsPath = _gdsForeignDirectory + "/" + foreign->cellName() + ".gds";
|
||||||
parser->setForeignPath( gdsPath );
|
parser->setForeignPath( gdsPath );
|
||||||
|
|
Loading…
Reference in New Issue