From 73265c2d6852aa3c695cc750d9b50ba7dbab8979 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 3 Jul 2023 20:00:58 +0200 Subject: [PATCH] Quick and DRC unclean hack to manage rectilinear in LefImport. --- crlcore/src/ccore/lefdef/LefImport.cpp | 115 +++++++++++++++++++------ 1 file changed, 89 insertions(+), 26 deletions(-) diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index 593b1392..32c0a9fe 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -110,8 +110,8 @@ namespace { inline int getNthRouting () const; inline void incNthRouting (); inline RoutingGauge* getRoutingGauge () const; - inline void addPinSegment ( string name, Segment* ); - inline void clearPinSegments (); + inline void addPinComponent ( string name, Component* ); + inline void clearPinComponents (); private: static int _unitsCbk ( lefrCallbackType_e, lefiUnits* , lefiUserData ); static int _layerCbk ( lefrCallbackType_e, lefiLayer* , lefiUserData ); @@ -131,7 +131,7 @@ namespace { Net* _net; string _busBits; double _unitsMicrons; - map< string, vector > _pinSegments; + map< string, vector > _pinComponents; static map _layerLut; vector _unmatchedLayers; vector _errors; @@ -173,8 +173,8 @@ namespace { inline const vector& LefParser::getErrors () const { return _errors; } inline void LefParser::pushError ( const string& error ) { _errors.push_back(error); } inline void LefParser::clearErrors () { return _errors.clear(); } - inline void LefParser::addPinSegment ( string name, Segment* s ) { _pinSegments[name].push_back(s); } - inline void LefParser::clearPinSegments () { _pinSegments.clear(); } + inline void LefParser::addPinComponent ( string name, Component* comp ) { _pinComponents[name].push_back(comp); } + inline void LefParser::clearPinComponents () { _pinComponents.clear(); } Library* LefParser::_mergeLibrary = nullptr; @@ -520,6 +520,8 @@ namespace { points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint]) , parser->fromUnitsMicrons(polygon->y[ipoint]) )); } + points.push_back( Point( parser->fromUnitsMicrons(polygon->x[0]) + , parser->fromUnitsMicrons(polygon->y[0]) )); Rectilinear::create( blockageNet, blockageLayer, points ); continue; } @@ -577,7 +579,7 @@ namespace { if (not isPad) parser->_pinStdPostProcess(); else parser->_pinPadPostProcess(); - parser->clearPinSegments(); + parser->clearPinComponents(); cerr << " - " << cellName << " " << DbU::getValueString(width) << " " << DbU::getValueString(height) @@ -667,7 +669,7 @@ namespace { , parser->fromUnitsMicrons( r->yh ) ); } - if (segment) parser->addPinSegment( pin->name(), segment ); + if (segment) parser->addPinComponent( pin->name(), segment ); //cerr << " | " << segment << endl; continue; } @@ -678,7 +680,10 @@ namespace { points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint]) , parser->fromUnitsMicrons(polygon->y[ipoint]) )); } - Rectilinear::create( net, layer, points ); + points.push_back( Point( parser->fromUnitsMicrons(polygon->x[0]) + , parser->fromUnitsMicrons(polygon->y[0]) )); + Rectilinear* rectilinear = Rectilinear::create( net, layer, points ); + if (rectilinear) parser->addPinComponent( pin->name(), rectilinear ); continue; } if (geoms->itemType(igeom) == lefiGeomClassE) { @@ -722,20 +727,27 @@ namespace { const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 ); Box ab = _cell->getAbutmentBox(); - //cerr << " @ _pinStdPostProcess" << endl; + cerr << " @ _pinStdPostProcess" << endl; - for ( auto element : _pinSegments ) { - string pinName = element.first; - vector& segments = element.second; - vector ongrids; + for ( auto element : _pinComponents ) { + string pinName = element.first; + vector& components = element.second; + vector ongrids; - for ( Segment* segment : segments ) { - bool isWide = (segment->getWidth() >= getMinTerminalWidth()); + for ( Component* component : components ) { + Segment* segment = dynamic_cast( component ); + if (segment) { + if (component->getNet()->isSupply()) continue; + bool isWide = (segment->getWidth() >= getMinTerminalWidth()); - //cerr << " > " << segment << endl; + cerr << " > " << segment << endl; + if (not isVH()) + cerr << "NOT isVH()" << endl; + else + cerr << "isVH()" << endl; - if (not segment->getNet()->isSupply()) { if (isVH() and (segment->getLayer()->getMask() == metal1->getMask())) { + cerr << "isVH()" << endl; Vertical* v = dynamic_cast( segment ); if (v) { DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin() @@ -746,7 +758,7 @@ namespace { if (nearestX == v->getX()) { } else { DbU::Unit neighbor = nearestX - + ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch(); + + ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch(); //cerr << " | X:" << DbU::getValueString(v->getX()) // << " nearestX:" << DbU::getValueString(nearestX) @@ -772,16 +784,67 @@ namespace { } } } - } - if (isWide) ongrids.push_back( segment ); + if (isWide) ongrids.push_back( segment ); + } + Rectilinear* rectilinear = dynamic_cast( component ); + if (not (rectilinear->getLayer()->getMask() == metal1->getMask())) + continue; + + if (rectilinear) { + cerr << " > " << rectilinear << endl; + vector boxes; + rectilinear->getAsRectangles( boxes ); + + if (component->getNet()->isSupply()) { + ongrids.push_back( Horizontal::create( rectilinear->getNet() + , rectilinear->getLayer() + , boxes.front().getYCenter() + , boxes.front().getHeight() + , _cell->getAbutmentBox().getXMin() + , _cell->getAbutmentBox().getXMax() + ) + ); + } else { + for ( const Box& box : boxes ) { + DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin() + , ab.getXMax() + , box.getXCenter() + , Constant::Nearest ); + DbU::Unit xmin = std::min( box.getXMin(), nearestX - gaugeMetal2->getViaWidth()/2 ); + DbU::Unit xmax = std::max( box.getXMax(), nearestX + gaugeMetal2->getViaWidth()/2 ); + ongrids.push_back( Vertical::create( rectilinear->getNet() + , rectilinear->getLayer() + , (xmax+xmin)/2 + , xmax-xmin + , box.getYMin() + , box.getYMax() + ) + ); + // DbU::Unit neighbor = nearestY + // + ((nearestY > box.getYCenter()) ? 1 : -1) * gaugeMetal2->getPitch(); + + // if ( (box.getYMin() > neighbor) + // or (box.getYMax() < neighbor) ) { + // ongrids.push_back( Vertical::create( rectilinear->getNet() + // , rectilinear->getLayer() + // , box.getXCenter() + // , box.getWidth() + // , box.getYMin() + // , box.getYMax() + // ) + // ); + // } + } + } + } } if (ongrids.empty()) { cerr << Warning( "LefParser::_pinStdPostProcess(): Pin \"%s\" has no terminal ongrid." , pinName.c_str() ) << endl; - for ( Segment* segment : segments ) { - NetExternalComponents::setExternal( segment ); + for ( Component* component : components ) { + NetExternalComponents::setExternal( component ); } } else { for ( Segment* segment : ongrids ) { @@ -797,10 +860,10 @@ namespace { Box ab = getCell()->getAbutmentBox(); bool isCornerPad = (_cellGauge) and (_cellGauge->getSliceHeight() == _cellGauge->getSliceStep()); - for ( auto element : _pinSegments ) { - string pinName = element.first; - vector& segments = element.second; - vector ongrids; + for ( auto element : _pinComponents ) { + string pinName = element.first; + vector& segments = element.second; + vector ongrids; if (segments.empty()) continue;