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:
|
||||
GdsStream ( string filename );
|
||||
~GdsStream ();
|
||||
inline Point putOnGrid ( const Point& ) const;
|
||||
inline int32_t toGdsDbu ( DbU::Unit ) const;
|
||||
static inline GdsRecord PROPATTR ( int16_t );
|
||||
static inline GdsRecord DATATYPE ( int16_t );
|
||||
|
@ -496,9 +497,10 @@ namespace {
|
|||
GdsStream& operator<< ( const Cell* );
|
||||
GdsStream& operator<< ( const Transformation& );
|
||||
private:
|
||||
ofstream _ostream;
|
||||
double _dbuPerUu;
|
||||
double _metricDbU;
|
||||
ofstream _ostream;
|
||||
double _dbuPerUu;
|
||||
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::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 )); }
|
||||
{
|
||||
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 )
|
||||
: _ostream ()
|
||||
, _dbuPerUu (Cfg::getParamDouble("gdsDriver.dbuPerUu" ,0.001)->asDouble()) // 1000
|
||||
, _metricDbU(Cfg::getParamDouble("gdsDriver.metricDbu",10e-9)->asDouble()) // 1um.
|
||||
, _oneGrid (DbU::grid(1.0))
|
||||
{
|
||||
std::fesetround( FE_TONEAREST );
|
||||
_ostream.open( filename, ios_base::out|ios_base::binary );
|
||||
|
@ -723,7 +742,7 @@ namespace {
|
|||
if (cell->getName() == "control_r") 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();
|
||||
|
||||
|
@ -762,7 +781,9 @@ namespace {
|
|||
}
|
||||
|
||||
for ( Net* net : cell->getNets() ) {
|
||||
cdebug_log(101,1) << "Writing net " << net << endl;
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
cdebug_log(101,0) << "Writing " << component << endl;
|
||||
Polygon* polygon = dynamic_cast<Polygon*>(component);
|
||||
if (polygon) {
|
||||
vector< vector<Point> > subpolygons;
|
||||
|
@ -849,7 +870,7 @@ namespace {
|
|||
(*this) << TEXTTYPE( 0 );
|
||||
cdebug_log(101,0) << "TEXTYPE end record" << endl;
|
||||
(*this) << PRESENTATION( 5 );
|
||||
(*this) << bb.getCenter();
|
||||
(*this) << putOnGrid( bb.getCenter() );
|
||||
(*this) << STRING( name );
|
||||
(*this) << ENDEL;
|
||||
cdebug_log(101,0) << "TEXT ENDEL" << endl;
|
||||
|
@ -859,9 +880,11 @@ namespace {
|
|||
}
|
||||
}
|
||||
}
|
||||
cdebug_tabw(101,-1);
|
||||
}
|
||||
|
||||
(*this) << ENDSTR;
|
||||
cdebug_tabw(101,-1);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -147,6 +147,7 @@ namespace {
|
|||
Net* _net;
|
||||
string _busBits;
|
||||
double _unitsMicrons;
|
||||
DbU::Unit _oneGrid;
|
||||
map< string, vector<Component*> > _pinComponents;
|
||||
static map<string,Layer*> _layerLut;
|
||||
vector<string> _unmatchedLayers;
|
||||
|
@ -179,7 +180,6 @@ namespace {
|
|||
inline void LefParser::setCellGauge ( CellGauge* gauge ) { _cellGauge=gauge; }
|
||||
inline Net* LefParser::getNet () const { return _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 void LefParser::setUnitsMicrons ( double precision ) { _unitsMicrons=precision; }
|
||||
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::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 = "";
|
||||
Library* LefParser::_mergeLibrary = nullptr;
|
||||
|
@ -264,6 +276,7 @@ namespace {
|
|||
, _net (nullptr)
|
||||
, _busBits ("()")
|
||||
, _unitsMicrons (0.01)
|
||||
, _oneGrid (DbU::fromGrid(1.0))
|
||||
, _unmatchedLayers ()
|
||||
, _errors ()
|
||||
, _nthMetal (0)
|
||||
|
@ -497,7 +510,10 @@ namespace {
|
|||
LefParser* parser = (LefParser*)ud;
|
||||
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";
|
||||
parser->setForeignPath( gdsPath );
|
||||
|
|
Loading…
Reference in New Issue