Partial management of offgrid fixed segments in Katana.
NOTE: To myself, one more bug uncovered in the Track segments management. This is really too complex, must find time to re-think and simplify the whole thing. * New: In Katana::NegociateWidow::createTrackSegment(), detect offgrid fixed segments and insert them into tracks directly (as *wide* segment of two tracks). * New: In Katana::TrackSegment::create() factory method, check for offgrid fixed segment and use a TrackSegmentWide (of 2 tracks) for them. * New: In Katana::TrackSegmentWide CTOR, check if they are used in the context of an offgrid segment and in that case set the track span to two. We *do not* manage yet the case for both *wide* and *offgrid* segments. * Change: In Katana::PowerRails::Rails::doLayout(), do not expand blockage rectangles over their real size. Add the guard only for real layers segments. * Bug: In Katana::PreProcess::propagateCagedConstraints(), when looking for the first track index, check for out of bound value (npos). * Bug: In Katana::Track::addOverlapCost(), before using the overlap segment indexes, check if we are not in a free hole (get the free interval from center). * Bug: In Katana::Track::expandFreeInterval(), the interval was badly computed if it was included inside segments of another (same) net.
This commit is contained in:
parent
db0ad6bf07
commit
7bae6d8bad
|
@ -321,45 +321,53 @@ namespace Katana {
|
||||||
DebugSession::open( autoSegment->getNet(), 159, 160 );
|
DebugSession::open( autoSegment->getNet(), 159, 160 );
|
||||||
|
|
||||||
cdebug_log(159,1) << "NegociateWindow::createTrackSegment() - " << autoSegment << endl;
|
cdebug_log(159,1) << "NegociateWindow::createTrackSegment() - " << autoSegment << endl;
|
||||||
|
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(autoSegment->getLayer());
|
||||||
|
Track* refTrack = plane->getTrackByPosition( autoSegment->getAxis() );
|
||||||
|
Track* insTrack = NULL;
|
||||||
|
size_t trackSpan = 1;
|
||||||
|
|
||||||
// Special case: fixed AutoSegments must not interfere with blockages.
|
// Special case: fixed AutoSegments must not interfere with blockages.
|
||||||
// Ugly: uses of getExtensionCap().
|
// Ugly: uses of getExtensionCap().
|
||||||
if (autoSegment->isFixed()) {
|
if (autoSegment->isFixed()) {
|
||||||
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(autoSegment->getLayer());
|
|
||||||
Track* track = plane->getTrackByPosition( autoSegment->getAxis() );
|
|
||||||
size_t begin;
|
size_t begin;
|
||||||
size_t end;
|
size_t end;
|
||||||
Interval fixedSpan;
|
Interval fixedSpan;
|
||||||
Interval blockageSpan;
|
Interval blockageSpan;
|
||||||
|
|
||||||
autoSegment->getCanonical( fixedSpan );
|
if (refTrack->getAxis() != autoSegment->getAxis()) {
|
||||||
fixedSpan.inflate( Session::getExtensionCap(autoSegment->getLayer())-1 );
|
trackSpan = 2;
|
||||||
|
refTrack = plane->getTrackByPosition( autoSegment->getAxis(), Constant::Inferior );
|
||||||
|
insTrack = refTrack;
|
||||||
|
}
|
||||||
|
|
||||||
track->getOverlapBounds( fixedSpan, begin, end );
|
Track* track = refTrack;
|
||||||
for ( ; (begin < end) ; begin++ ) {
|
for ( size_t ispan=0 ; track and (ispan < trackSpan) ; ++ispan, track=track->getNextTrack() ) {
|
||||||
|
autoSegment->getCanonical( fixedSpan );
|
||||||
|
fixedSpan.inflate( Session::getExtensionCap(autoSegment->getLayer())-1 );
|
||||||
|
|
||||||
TrackElement* other = track->getSegment(begin);
|
track->getOverlapBounds( fixedSpan, begin, end );
|
||||||
cdebug_log(159,0) << "| overlap: " << other << endl;
|
for ( ; (begin < end) ; begin++ ) {
|
||||||
|
TrackElement* other = track->getSegment(begin);
|
||||||
|
cdebug_log(159,0) << "| overlap: " << other << endl;
|
||||||
|
|
||||||
if (not other->isBlockage()) continue;
|
if (not other->isBlockage()) continue;
|
||||||
|
|
||||||
other->getCanonical( blockageSpan );
|
other->getCanonical( blockageSpan );
|
||||||
blockageSpan.inflate( Session::getExtensionCap(autoSegment->getLayer()) );
|
blockageSpan.inflate( Session::getExtensionCap(autoSegment->getLayer()) );
|
||||||
|
|
||||||
cdebug_log(159,0) << " fixed:" << fixedSpan << " vs. blockage:" << blockageSpan << endl;
|
cdebug_log(159,0) << " fixed:" << fixedSpan << " vs. blockage:" << blockageSpan << endl;
|
||||||
|
if (not fixedSpan.intersect(blockageSpan)) continue;
|
||||||
|
|
||||||
if (not fixedSpan.intersect(blockageSpan)) continue;
|
// Overlap between fixed & blockage.
|
||||||
|
cdebug_log(159,0) << "* Blockage overlap: " << autoSegment << endl;
|
||||||
// Overlap between fixed & blockage.
|
//Session::destroyRequest( autoSegment );
|
||||||
cdebug_log(159,0) << "* Blockage overlap: " << autoSegment << endl;
|
cerr << Warning( "Overlap between fixed %s and blockage at %s."
|
||||||
//Session::destroyRequest( autoSegment );
|
, getString(autoSegment).c_str()
|
||||||
|
, getString(blockageSpan).c_str() ) << endl;
|
||||||
cerr << Warning( "Overlap between fixed %s and blockage at %s."
|
cdebug_tabw(159,-1);
|
||||||
, getString(autoSegment).c_str()
|
DebugSession::close();
|
||||||
, getString(blockageSpan).c_str() ) << endl;
|
return NULL;
|
||||||
cdebug_tabw(159,-1);
|
}
|
||||||
DebugSession::close();
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +375,7 @@ namespace Katana {
|
||||||
autoSegment = autoSegment->getCanonical( span );
|
autoSegment = autoSegment->getCanonical( span );
|
||||||
|
|
||||||
bool created;
|
bool created;
|
||||||
TrackElement* trackSegment = TrackSegment::create( autoSegment, NULL, created );
|
TrackElement* trackSegment = TrackSegment::create( autoSegment, insTrack, created );
|
||||||
|
|
||||||
if (not (flags & Flags::LoadingStage))
|
if (not (flags & Flags::LoadingStage))
|
||||||
cdebug_log(159,0) << "* lookup: " << autoSegment << endl;
|
cdebug_log(159,0) << "* lookup: " << autoSegment << endl;
|
||||||
|
@ -383,38 +391,38 @@ namespace Katana {
|
||||||
return trackSegment;
|
return trackSegment;
|
||||||
}
|
}
|
||||||
|
|
||||||
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(autoSegment->getLayer());
|
Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) );
|
||||||
Track* track = plane->getTrackByPosition ( autoSegment->getAxis() );
|
Interval constraints;
|
||||||
Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) );
|
|
||||||
|
|
||||||
Interval constraints;
|
|
||||||
autoSegment->getConstraints( constraints );
|
autoSegment->getConstraints( constraints );
|
||||||
cdebug_log(159,0) << "* Constraints " << constraints << endl;
|
cdebug_log(159,0) << "* Constraints " << constraints << endl;
|
||||||
|
|
||||||
uside.intersection( constraints );
|
uside.intersection( constraints );
|
||||||
cdebug_log(159,0) << "* Constraints+U-side " << constraints << endl;
|
cdebug_log(159,0) << "* Constraints+U-side " << constraints << endl;
|
||||||
cdebug_log(159,0) << "* Nearest " << track << endl;
|
cdebug_log(159,0) << "* Nearest " << refTrack << endl;
|
||||||
|
|
||||||
if (not track)
|
if (not refTrack)
|
||||||
throw Error( "NegociateWindow::createTrackSegment(): No track near axis of %s."
|
throw Error( "NegociateWindow::createTrackSegment(): No track near axis of %s."
|
||||||
, getString(autoSegment).c_str() );
|
, getString(autoSegment).c_str() );
|
||||||
|
|
||||||
if (track->getAxis() > uside.getVMax()) track = track->getPreviousTrack();
|
if (not insTrack) {
|
||||||
if (track->getAxis() < uside.getVMin()) track = track->getNextTrack();
|
insTrack = refTrack;
|
||||||
|
if (refTrack->getAxis() > uside.getVMax()) insTrack = refTrack->getPreviousTrack();
|
||||||
if (not track)
|
if (refTrack->getAxis() < uside.getVMin()) insTrack = refTrack->getNextTrack();
|
||||||
|
}
|
||||||
|
if (not insTrack)
|
||||||
throw Error( "NegociateWindow::createTrackSegment(): No track near axis of %s (after adjust)."
|
throw Error( "NegociateWindow::createTrackSegment(): No track near axis of %s (after adjust)."
|
||||||
, getString(autoSegment).c_str() );
|
, getString(autoSegment).c_str() );
|
||||||
|
|
||||||
cdebug_log(159,0) << "* GCell U-side " << uside << endl;
|
cdebug_log(159,0) << "* GCell U-side " << uside << endl;
|
||||||
cdebug_log(159,0) << "* " << plane << endl;
|
cdebug_log(159,0) << "* " << plane << endl;
|
||||||
cdebug_log(159,0) << "* " << track << endl;
|
cdebug_log(159,0) << "* " << insTrack << endl;
|
||||||
|
|
||||||
trackSegment->setAxis( track->getAxis(), AutoSegment::SegAxisSet );
|
if (trackSpan == 1)
|
||||||
|
trackSegment->setAxis( insTrack->getAxis(), AutoSegment::SegAxisSet );
|
||||||
trackSegment->invalidate();
|
trackSegment->invalidate();
|
||||||
|
|
||||||
if (trackSegment->isFixed()) {
|
if (trackSegment->isFixed() and not trackSegment->getTrack()) {
|
||||||
Session::addInsertEvent( trackSegment, track, track->getAxis() );
|
Session::addInsertEvent( trackSegment, insTrack, refTrack->getAxis() );
|
||||||
} else {
|
} else {
|
||||||
_segments.push_back( trackSegment );
|
_segments.push_back( trackSegment );
|
||||||
}
|
}
|
||||||
|
|
|
@ -518,9 +518,11 @@ namespace {
|
||||||
DbU::Unit axisMin = 0;
|
DbU::Unit axisMin = 0;
|
||||||
DbU::Unit axisMax = 0;
|
DbU::Unit axisMax = 0;
|
||||||
|
|
||||||
if (AllianceFramework::get()->getCellGauge()->getName() == Name("FlexLib")) {
|
if (not layer->isBlockage()) {
|
||||||
if (_width >= DbU::fromPhysical( 10.0, DbU::UnitPower::Micro )) {
|
if (AllianceFramework::get()->getCellGauge()->getName() == Name("FlexLib")) {
|
||||||
delta = 2 * plane->getLayerGauge()->getPitch();
|
if (_width >= DbU::fromPhysical( 10.0, DbU::UnitPower::Micro )) {
|
||||||
|
delta = 2 * plane->getLayerGauge()->getPitch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ namespace {
|
||||||
// Computing constraints from fixed only TrackElements (caging).
|
// Computing constraints from fixed only TrackElements (caging).
|
||||||
TrackElement* parallel;
|
TrackElement* parallel;
|
||||||
size_t i = track->find( segment );
|
size_t i = track->find( segment );
|
||||||
while ( i > 0 ) {
|
while ( (i != Track::npos) and (i > 0) ) {
|
||||||
parallel = track->getSegment( --i );
|
parallel = track->getSegment( --i );
|
||||||
if (not parallel) continue;
|
if (not parallel) continue;
|
||||||
if (parallel->getTargetU() < uside.getVMin()) break;
|
if (parallel->getTargetU() < uside.getVMin()) break;
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace Katana {
|
||||||
|
|
||||||
|
|
||||||
RoutingPlane::RoutingPlane ( KatanaEngine* katana, size_t depth )
|
RoutingPlane::RoutingPlane ( KatanaEngine* katana, size_t depth )
|
||||||
: _katana (katana)
|
: _katana (katana)
|
||||||
, _layerGauge(katana->getConfiguration()->getLayerGauge(depth))
|
, _layerGauge(katana->getConfiguration()->getLayerGauge(depth))
|
||||||
, _depth (depth)
|
, _depth (depth)
|
||||||
, _flags (0)
|
, _flags (0)
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace {
|
||||||
: segment->base()->getAutoTarget() ;
|
: segment->base()->getAutoTarget() ;
|
||||||
if (contact->getLayer() != layer) return false;
|
if (contact->getLayer() != layer) return false;
|
||||||
if (not contact->isTurn()) return false;
|
if (not contact->isTurn()) return false;
|
||||||
AutoSegment* pp = contact->getPerpandicular( segment->base() );
|
//AutoSegment* pp = contact->getPerpandicular( segment->base() );
|
||||||
return contact->getPerpandicular(segment->base())->getLength();
|
return contact->getPerpandicular(segment->base())->getLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,11 +368,13 @@ namespace Katana {
|
||||||
|
|
||||||
TrackCost& Track::addOverlapCost ( TrackCost& cost ) const
|
TrackCost& Track::addOverlapCost ( TrackCost& cost ) const
|
||||||
{
|
{
|
||||||
size_t begin = Track::npos;
|
size_t begin = Track::npos;
|
||||||
size_t end = Track::npos;
|
size_t end = Track::npos;
|
||||||
const Interval& interval = cost.getInterval();
|
const Interval& interval = cost.getInterval();
|
||||||
|
Interval freeInterval = getFreeInterval( interval.getCenter(), cost.getNet() );
|
||||||
|
|
||||||
getOverlapBounds( cost.getInterval(), begin, end );
|
if (not freeInterval.contains(interval))
|
||||||
|
getOverlapBounds( cost.getInterval(), begin, end );
|
||||||
cost.setTrack( const_cast<Track*>(this), begin, end );
|
cost.setTrack( const_cast<Track*>(this), begin, end );
|
||||||
|
|
||||||
cdebug_log(155,1) << "addOverlapCost() @" << DbU::getValueString(_axis)
|
cdebug_log(155,1) << "addOverlapCost() @" << DbU::getValueString(_axis)
|
||||||
|
@ -380,6 +382,9 @@ namespace Katana {
|
||||||
<< ":" << DbU::getValueString(interval.getVMax())
|
<< ":" << DbU::getValueString(interval.getVMax())
|
||||||
<< "] <-> [" << begin << ":" << end << "]"
|
<< "] <-> [" << begin << ":" << end << "]"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
cdebug_log(155,0) << "freeInterval [" << DbU::getValueString(freeInterval.getVMin())
|
||||||
|
<< ":" << DbU::getValueString(freeInterval.getVMax()) << "]"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
vector<TrackMarker*>::const_iterator lowerBound
|
vector<TrackMarker*>::const_iterator lowerBound
|
||||||
= lower_bound( _markers.begin(), _markers.end(), interval.getVMin(), TrackMarker::Compare() );
|
= lower_bound( _markers.begin(), _markers.end(), interval.getVMin(), TrackMarker::Compare() );
|
||||||
|
@ -407,7 +412,8 @@ namespace Katana {
|
||||||
|
|
||||||
for ( ; begin < end ; begin++ ) {
|
for ( ; begin < end ; begin++ ) {
|
||||||
Interval overlap = interval.getIntersection( _segments[begin]->getCanonicalInterval() );
|
Interval overlap = interval.getIntersection( _segments[begin]->getCanonicalInterval() );
|
||||||
cdebug_log(155,0) << "overlap:" << overlap << " size:" << overlap.getSize() << endl;
|
cdebug_log(155,0) << "overlap:" << overlap
|
||||||
|
<< " size:" << DbU::getValueString(overlap.getSize()) << endl;
|
||||||
if (overlap.getSize() == 0) continue;
|
if (overlap.getSize() == 0) continue;
|
||||||
|
|
||||||
if (_segments[begin]->getNet() == cost.getNet()) {
|
if (_segments[begin]->getNet() == cost.getNet()) {
|
||||||
|
@ -523,19 +529,15 @@ namespace Katana {
|
||||||
} else {
|
} else {
|
||||||
cdebug_log(155,0) << "| same net, end:" << end << " (after last)" << endl;
|
cdebug_log(155,0) << "| same net, end:" << end << " (after last)" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end == npos) {
|
|
||||||
end = _segments.size() - 1;
|
|
||||||
setMaximalFlags( state, EndIsTrackMax );
|
|
||||||
} else {
|
|
||||||
setMaximalFlags( state, EndIsSegmentMin );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state = EndIsTrackMax;
|
|
||||||
cdebug_log(155,0) << "| already after last" << endl;
|
|
||||||
}
|
}
|
||||||
|
if (end == npos) {
|
||||||
|
end = _segments.size() - 1;
|
||||||
|
setMaximalFlags( state, EndIsTrackMax );
|
||||||
|
} else {
|
||||||
|
setMaximalFlags( state, EndIsSegmentMin );
|
||||||
|
}
|
||||||
cdebug_log(155,0) << "end:" << end << " state:" << state << endl;
|
cdebug_log(155,0) << "end:" << end << " state:" << state << endl;
|
||||||
|
cdebug_log(155,0) << "end:" << _segments[end] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdebug_tabw(155,-1);
|
cdebug_tabw(155,-1);
|
||||||
|
|
|
@ -147,10 +147,12 @@ namespace Katana {
|
||||||
cerr << Error( "TrackSegment::create(): Must not set track when creating a non-preferred element.\n"
|
cerr << Error( "TrackSegment::create(): Must not set track when creating a non-preferred element.\n"
|
||||||
" (on %s)", getString(segment).c_str() ) << endl;
|
" (on %s)", getString(segment).c_str() ) << endl;
|
||||||
} else {
|
} else {
|
||||||
if (segment->base()->getWidth() <= defaultWireWidth)
|
if (segment->isFixed() and track and (segment->getAxis() != track->getAxis()))
|
||||||
|
trackElement = new TrackSegmentWide( segment, track );
|
||||||
|
else if (segment->base()->getWidth() <= defaultWireWidth)
|
||||||
trackElement = new TrackSegmentRegular( segment, track );
|
trackElement = new TrackSegmentRegular( segment, track );
|
||||||
else
|
else
|
||||||
trackElement = new TrackSegmentWide ( segment, track );
|
trackElement = new TrackSegmentWide( segment, track );
|
||||||
}
|
}
|
||||||
|
|
||||||
trackElement->_postCreate();
|
trackElement->_postCreate();
|
||||||
|
|
|
@ -62,8 +62,11 @@ namespace Katana {
|
||||||
|
|
||||||
if (not _trackSpan) {
|
if (not _trackSpan) {
|
||||||
DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) );
|
DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) );
|
||||||
if (segment->getWidth() < mWidth) {
|
if (segment->getWidth() <= mWidth) {
|
||||||
_trackSpan = 1;
|
_trackSpan = 1;
|
||||||
|
if (track and (track->getAxis() != segment->getAxis())) {
|
||||||
|
_trackSpan = 2;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
DbU::Unit pitch = Session::getPitch(segment->getLayer());
|
DbU::Unit pitch = Session::getPitch(segment->getLayer());
|
||||||
DbU::Unit width = segment->getWidth() - mWidth;
|
DbU::Unit width = segment->getWidth() - mWidth;
|
||||||
|
|
Loading…
Reference in New Issue