In GdsStream & LefImport, thorough verification that coordinates are on foundry grid.

This commit is contained in:
Jean-Paul Chaput 2023-07-22 16:37:36 +02:00
parent e470ca8375
commit 96f41776a8
2 changed files with 47 additions and 8 deletions

View File

@ -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;
}

View File

@ -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 );