mirror of
https://github.com/lip6/coriolis.git
synced 2026-05-30 10:06:21 +08:00
Fix in LefParser::_pinStdPostProcess() to avoid offgrid segments.
This commit is contained in:
@@ -129,8 +129,12 @@ namespace {
|
||||
|
||||
cdebug_log(100,0) << "| candidate pitched size: " << DbU::getValueString(candidateWidth)
|
||||
<< " x " << DbU::getValueString(candidateHeight) << endl;
|
||||
cdebug_log(100,0) << "| best pitched size: " << DbU::getValueString(bestWidth)
|
||||
<< " x " << DbU::getValueString(bestHeight) << endl;
|
||||
if (best.isEmpty()) {
|
||||
cdebug_log(100,0) << "| best pitched size: empty (no previous candidate)" << endl;
|
||||
} else {
|
||||
cdebug_log(100,0) << "| best pitched size: " << DbU::getValueString(bestWidth)
|
||||
<< " x " << DbU::getValueString(bestHeight) << endl;
|
||||
}
|
||||
|
||||
if (_flags & LefImport::PinFilter_TALLEST) {
|
||||
if (candidateHeight != bestHeight) return (candidateHeight > bestHeight);
|
||||
@@ -240,7 +244,12 @@ namespace {
|
||||
static int _pinCbk ( lefrCallbackType_e, lefiPin* , lefiUserData );
|
||||
void _pinStdPostProcess ();
|
||||
void _pinPadPostProcess ();
|
||||
Segment* _createBestSegment ( Rectilinear*, DbU::Unit minWidth, DbU::Unit minHeight, const RoutingLayerGauge*, uint32_t flags );
|
||||
bool _createBestSegment ( Rectilinear*
|
||||
, DbU::Unit minWidth
|
||||
, DbU::Unit minHeight
|
||||
, const RoutingLayerGauge*
|
||||
, uint32_t flags
|
||||
, Segment*& bestSegment );
|
||||
private:
|
||||
static string _gdsForeignDirectory;
|
||||
static Library* _mergeLibrary;
|
||||
@@ -329,15 +338,18 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
Segment* LefParser::_createBestSegment ( Rectilinear* rectilinear
|
||||
, DbU::Unit minWidth
|
||||
, DbU::Unit minHeight
|
||||
, const RoutingLayerGauge* rlg
|
||||
, uint32_t flags )
|
||||
bool LefParser::_createBestSegment ( Rectilinear* rectilinear
|
||||
, DbU::Unit minWidth
|
||||
, DbU::Unit minHeight
|
||||
, const RoutingLayerGauge* rlg
|
||||
, uint32_t flags
|
||||
, Segment*& bestSegment )
|
||||
{
|
||||
cdebug_log(100,1) << "LefParser::_createBestSegment() " << rectilinear << endl;
|
||||
|
||||
PinRectilinearFilter pinFilter ( minWidth, minHeight, flags );
|
||||
|
||||
Segment* segment = nullptr;
|
||||
bool useOngrid = true;
|
||||
vector<Box> boxes;
|
||||
rectilinear->getAsBiggestRectangles( boxes
|
||||
, pinFilter.getXThreshold()
|
||||
@@ -345,11 +357,12 @@ namespace {
|
||||
Box best;
|
||||
Box offgrid;
|
||||
for ( Box& candidate : boxes ) {
|
||||
cdebug_log(100,0) << "raw candidate " << candidate << endl;
|
||||
|
||||
DbU::Unit widthAdjust = candidate.getWidth () % DbU::twoGrid;
|
||||
DbU::Unit heightAdjust = candidate.getHeight() % DbU::twoGrid;
|
||||
|
||||
if (heightAdjust) {
|
||||
//candidate.inflate( 0, 0, 0, -heightAdjust );
|
||||
if (rlg->isHorizontal()) {
|
||||
DbU::Unit trackMin = rlg->getTrackPosition( getCell()->getAbutmentBox()
|
||||
, candidate.getYMin() + minHeight/2
|
||||
@@ -359,7 +372,6 @@ namespace {
|
||||
, candidate.getYMax() - minHeight/2
|
||||
, Constant::Inferior );
|
||||
DbU::Unit deltaMax = candidate.getYMax() - minHeight/2 - trackMax;
|
||||
cdebug_log(100,0) << " raw candidate " << candidate << endl;
|
||||
cdebug_log(100,0) << " min height (pin)=" << DbU::getValueString(minHeight) << endl;
|
||||
cdebug_log(100,0) << " min LZ=" << DbU::getValueString(candidate.getYMin() + minHeight/2)
|
||||
<< " track min=" << DbU::getValueString(trackMin) << endl;
|
||||
@@ -369,6 +381,7 @@ namespace {
|
||||
<< " deltaMax=" << DbU::getValueString(deltaMax)
|
||||
<< endl;
|
||||
if (trackMin > trackMax) {
|
||||
candidate.inflate( 0, 0, -widthAdjust, -heightAdjust );
|
||||
if (offgrid.isEmpty() or pinFilter.match(candidate,offgrid))
|
||||
offgrid = candidate;
|
||||
continue;
|
||||
@@ -376,9 +389,11 @@ namespace {
|
||||
if (deltaMin < deltaMax) candidate.inflate( 0, 0, 0, -heightAdjust );
|
||||
else candidate.inflate( 0, -heightAdjust, 0, 0 );
|
||||
} else {
|
||||
cdebug_log(100,0) << "Non PP track driven height adjust" << endl;
|
||||
candidate.inflate( 0, 0, 0, -heightAdjust );
|
||||
}
|
||||
}
|
||||
cdebug_log(100,0) << "After height adjust: " << candidate << endl;
|
||||
|
||||
if (widthAdjust) {
|
||||
if (rlg->isVertical()) {
|
||||
@@ -390,7 +405,6 @@ namespace {
|
||||
, candidate.getXMax() - minWidth/2
|
||||
, Constant::Inferior );
|
||||
DbU::Unit deltaMax = candidate.getXMax() - minWidth/2 - trackMax;
|
||||
cdebug_log(100,0) << " raw candidate " << candidate << endl;
|
||||
cdebug_log(100,0) << " min width (pin)=" << DbU::getValueString(minWidth) << endl;
|
||||
cdebug_log(100,0) << " min LZ=" << DbU::getValueString(candidate.getXMin() + minWidth/2)
|
||||
<< " track min=" << DbU::getValueString(trackMin) << endl;
|
||||
@@ -400,6 +414,7 @@ namespace {
|
||||
<< " deltaMax=" << DbU::getValueString(deltaMax)
|
||||
<< endl;
|
||||
if (trackMin > trackMax) {
|
||||
candidate.inflate( 0, 0, -widthAdjust, -heightAdjust );
|
||||
if (offgrid.isEmpty() or pinFilter.match(candidate,offgrid))
|
||||
offgrid = candidate;
|
||||
continue;
|
||||
@@ -407,42 +422,39 @@ namespace {
|
||||
if (deltaMin < deltaMax) candidate.inflate( 0, 0, -widthAdjust, 0 );
|
||||
else candidate.inflate( -widthAdjust, 0, 0, 0 );
|
||||
} else {
|
||||
cdebug_log(100,0) << "Non PP track driven width adjust" << endl;
|
||||
candidate.inflate( 0, 0, -widthAdjust, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_log(100,0) << "| " << candidate << endl;
|
||||
cdebug_log(100,0) << "After width adjust: " << candidate << endl;
|
||||
if (pinFilter.match(candidate,best))
|
||||
best = candidate;
|
||||
}
|
||||
if (best.isEmpty()) {
|
||||
best = offgrid;
|
||||
if (not rectilinear->getNet()->isSupply())
|
||||
cerr << Warning( "LefParser::_createBestSegment(): Pin \"%s\" of \"%s\" has no terminal ongrid."
|
||||
, getString(rectilinear->getNet()->getName()).c_str()
|
||||
, getString(_cell->getName()).c_str() ) << endl;
|
||||
best = offgrid;
|
||||
useOngrid = false;
|
||||
}
|
||||
if (not best.isEmpty()) {
|
||||
if (best.getWidth() < best.getHeight()) {
|
||||
segment = Vertical::create( rectilinear->getNet()
|
||||
, rectilinear->getLayer()
|
||||
, best.getXCenter()
|
||||
, best.getWidth()
|
||||
, best.getYMin()
|
||||
, best.getYMax()
|
||||
);
|
||||
} else {
|
||||
segment = Horizontal::create( rectilinear->getNet()
|
||||
bestSegment = Vertical::create( rectilinear->getNet()
|
||||
, rectilinear->getLayer()
|
||||
, best.getYCenter()
|
||||
, best.getHeight()
|
||||
, best.getXMin()
|
||||
, best.getXMax()
|
||||
, best.getXCenter()
|
||||
, best.getWidth()
|
||||
, best.getYMin()
|
||||
, best.getYMax()
|
||||
);
|
||||
} else {
|
||||
bestSegment = Horizontal::create( rectilinear->getNet()
|
||||
, rectilinear->getLayer()
|
||||
, best.getYCenter()
|
||||
, best.getHeight()
|
||||
, best.getXMin()
|
||||
, best.getXMax()
|
||||
);
|
||||
}
|
||||
}
|
||||
cdebug_log(100,0) << "| -> " << segment << endl;
|
||||
return segment;
|
||||
cdebug_log(100,-1) << "Using: useOnGrid=" << useOngrid << " " << bestSegment << endl;
|
||||
return useOngrid;
|
||||
}
|
||||
|
||||
|
||||
@@ -1270,8 +1282,9 @@ namespace {
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__aoi222_1")
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__dffsnq_1")
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__aoi22_1")
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__clkbuf_2")
|
||||
if (_cell->getName() == "AOI221X1_V5")
|
||||
//if (_cell->getName() == "AOI221X1_V5")
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__addh_1")
|
||||
if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__clkbuf_2")
|
||||
DebugSession::open( 100, 110 );
|
||||
cdebug_log(100,1) << "LefParser::_pinStdPostProcess" << endl;
|
||||
|
||||
@@ -1409,19 +1422,32 @@ namespace {
|
||||
)
|
||||
);
|
||||
} else {
|
||||
Segment* segment = _createBestSegment( rectilinear
|
||||
, minMetal1Width
|
||||
, minMetal1Height
|
||||
, gaugeMetal2
|
||||
, normalFlags );
|
||||
if (segment) ongrids.push_back( segment );
|
||||
Segment* candidateR = nullptr;
|
||||
Segment* candidateN = nullptr;
|
||||
bool isOngridR = false;
|
||||
bool isOngridN = _createBestSegment( rectilinear
|
||||
, minMetal1Width
|
||||
, minMetal1Height
|
||||
, gaugeMetal2
|
||||
, normalFlags
|
||||
, candidateN );
|
||||
if (isOngridN) ongrids.push_back( candidateN );
|
||||
else {
|
||||
segment = _createBestSegment( rectilinear
|
||||
, minMetal1Height
|
||||
, minMetal1Width
|
||||
, gaugeMetal2
|
||||
, rotatedFlags );
|
||||
if (segment) ongrids.push_back( segment );
|
||||
isOngridR = _createBestSegment( rectilinear
|
||||
, minMetal1Height
|
||||
, minMetal1Width
|
||||
, gaugeMetal2
|
||||
, rotatedFlags
|
||||
, candidateR );
|
||||
if (isOngridR) ongrids.push_back( candidateR );
|
||||
else {
|
||||
if (not rectilinear->getNet()->isSupply() and not isOngridN and not isOngridR)
|
||||
cerr << Warning( "LefParser::_pinStdPostProcess(): Pin \"%s\" of \"%s\" has no terminal ongrid."
|
||||
, getString(rectilinear->getNet()->getName()).c_str()
|
||||
, getString(_cell->getName()).c_str() ) << endl;
|
||||
if (candidateN) ongrids.push_back( candidateN );
|
||||
else if (candidateR) ongrids.push_back( candidateR );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1453,8 +1479,9 @@ namespace {
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__aoi222_1")
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__dffsnq_1")
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__aoi22_1")
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__clkbuf_2")
|
||||
if (_cell->getName() == "AOI221X1_V5")
|
||||
//if (_cell->getName() == "AOI221X1_V5")
|
||||
//if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__addh_1")
|
||||
if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__clkbuf_2")
|
||||
DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user