Bad computation of optimal position for analog segments.
* Bug: In Anabatic::AutoSegment::computeOptimal(), the "side stack" computing the intersection of all the sides of the GCell that the segment is going through was implicitly supposing that the resulting intersection wasn't empty. But for analog segment, we compute the position of all the segments linked though simple doglegs, and as dogleg occurs there can be a sufficient shift so the intersections of all the sides became empty. Now the "side stack" can manage configuration when instead of having an intersection we have a "hole" in the GCell side span (only one hole is supported at the moment). When a hole is present, the optimal position is the center of the hole. Should be refined so that the position is computed according to the longest GCell that we go through. * Change: In Katana::SegmentFsm::_slackenGlobal(), when slackening a global from a ananlog net, allow to make a dog leg once instead of immediately moving up. The break point is the center of the segment. * Change: In Katana::Manipulator::Makedogleg(DbU::Unit) if the break position is over a device, choose the left of right GCell.
This commit is contained in:
parent
793dbb26b2
commit
97d5a1f583
|
@ -239,16 +239,20 @@ namespace {
|
|||
|
||||
class SideStack {
|
||||
public:
|
||||
SideStack ( Flags direction, DbU::Unit pitch );
|
||||
const Interval& getSideAt ( DbU::Unit ) const;
|
||||
inline const Interval& getGSide () const;
|
||||
inline DbU::Unit getGSideMin () const;
|
||||
inline DbU::Unit getGSideMax () const;
|
||||
void addGCell ( const GCell* );
|
||||
inline void restrictGSide ( const Interval& );
|
||||
void show () const;
|
||||
SideStack ( Flags direction, DbU::Unit pitch );
|
||||
inline bool isHoled () const;
|
||||
const Interval& getSideAt ( DbU::Unit ) const;
|
||||
inline const Interval& getGSide () const;
|
||||
inline DbU::Unit getGSideMin () const;
|
||||
inline DbU::Unit getGSideMax () const;
|
||||
inline DbU::Unit getGSideCenter () const;
|
||||
void addGCell ( const GCell* );
|
||||
inline bool intersect ( const Interval& ) const;
|
||||
inline void restrictGSide ( const Interval& );
|
||||
void show () const;
|
||||
private:
|
||||
Flags _direction;
|
||||
bool _holed;
|
||||
DbU::Unit _pitch;
|
||||
Interval _full;
|
||||
Interval _gside;
|
||||
|
@ -258,6 +262,7 @@ namespace {
|
|||
|
||||
SideStack::SideStack ( Flags direction, DbU::Unit pitch )
|
||||
: _direction( (direction & Flags::Horizontal) ? Flags::Vertical : Flags::Horizontal )
|
||||
, _holed (false)
|
||||
, _pitch (pitch)
|
||||
, _full (false)
|
||||
, _gside (false)
|
||||
|
@ -265,10 +270,13 @@ namespace {
|
|||
{ }
|
||||
|
||||
|
||||
inline const Interval& SideStack::getGSide () const { return _gside; }
|
||||
inline DbU::Unit SideStack::getGSideMin () const { return _gside.getVMin(); }
|
||||
inline DbU::Unit SideStack::getGSideMax () const { return _gside.getVMax(); }
|
||||
inline void SideStack::restrictGSide ( const Interval& restrict ) { _gside.intersection( restrict ); }
|
||||
inline bool SideStack::isHoled () const { return _holed; }
|
||||
inline const Interval& SideStack::getGSide () const { return _gside; }
|
||||
inline DbU::Unit SideStack::getGSideMin () const { return _gside.getVMin(); }
|
||||
inline DbU::Unit SideStack::getGSideMax () const { return _gside.getVMax(); }
|
||||
inline DbU::Unit SideStack::getGSideCenter () const { return _gside.getVMax(); }
|
||||
inline bool SideStack::intersect ( const Interval& side ) const { return _gside.intersect(side); }
|
||||
inline void SideStack::restrictGSide ( const Interval& restrict ) { if (not _holed) _gside.intersection(restrict); }
|
||||
|
||||
|
||||
const Interval& SideStack::getSideAt ( DbU::Unit position ) const
|
||||
|
@ -290,7 +298,20 @@ namespace {
|
|||
DbU::Unit position = (_direction & Flags::Vertical) ? gcell->getBoundingBox().getXMin()
|
||||
: gcell->getBoundingBox().getYMin();
|
||||
|
||||
_gside.intersection( side );
|
||||
if (not _holed and intersect(side)) _gside.intersection( side );
|
||||
else {
|
||||
if (not _holed) {
|
||||
_holed = true;
|
||||
if (side.getVMin() > _gside.getVMax()) _gside = Interval( _gside.getVMax(), side.getVMin() );
|
||||
else _gside = Interval( side.getVMax(), _gside.getVMin() );
|
||||
} else {
|
||||
if (not intersect(side)) {
|
||||
if (side.getVMax() < _gside.getVMin()) _gside.merge( side.getVMax() );
|
||||
else _gside.merge( side.getVMin() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_sides.insert( make_pair(position,side) );
|
||||
}
|
||||
|
||||
|
@ -1176,15 +1197,20 @@ namespace Anabatic {
|
|||
|
||||
cdebug_log(145,0) << "Using pitch for L/T shrink:" << DbU::getValueString(getPitch()) << endl;
|
||||
for ( AutoSegment* aligned : aligneds ) {
|
||||
cdebug_log(145,0) << "@ " << aligned << endl;
|
||||
|
||||
aligned->getGCells( gcells );
|
||||
for ( GCell* gcell : gcells ) {
|
||||
sideStack.addGCell( gcell );
|
||||
cdebug_log(145,0) << "| gcellSide:" << sideStack.getGSide() << " (from " << gcell << ")" << endl;
|
||||
}
|
||||
if (aligned->isStrongTerminal()) {
|
||||
if (aligned->isStrongTerminal() and not sideStack.isHoled()) {
|
||||
cdebug_log(145,0) << "> Is strong terminal, restrict." << aligned << endl;
|
||||
|
||||
Interval terminalConstraints;
|
||||
aligned->getConstraints( terminalConstraints );
|
||||
sideStack.restrictGSide( terminalConstraints );
|
||||
cdebug_log(145,0) << "| " << terminalConstraints.intersection(sideStack.getGSide()) << endl;
|
||||
cdebug_log(145,0) << "| gcellSide:" << sideStack.getGSide() << " (from " << aligned << ")" << endl;
|
||||
}
|
||||
}
|
||||
|
@ -1274,20 +1300,24 @@ namespace Anabatic {
|
|||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
if (attractors.getAttractorsCount()) {
|
||||
optimalMin = attractors.getLowerMedian();
|
||||
optimalMax = attractors.getUpperMedian();
|
||||
if (sideStack.isHoled()) {
|
||||
optimalMin = optimalMax = sideStack.getGSideCenter();
|
||||
} else {
|
||||
cdebug_log(145,0) << "No attractors, reverting to GCell bounding box" << endl;
|
||||
if (attractors.getAttractorsCount()) {
|
||||
optimalMin = attractors.getLowerMedian();
|
||||
optimalMax = attractors.getUpperMedian();
|
||||
} else {
|
||||
cdebug_log(145,0) << "No attractors, reverting to GCell bounding box" << endl;
|
||||
|
||||
optimalMin = 0;
|
||||
optimalMax = (isHorizontal()) ? _gcell->getBoundingBox().getYMax()
|
||||
: _gcell->getBoundingBox().getXMax();
|
||||
}
|
||||
|
||||
optimalMin = 0;
|
||||
optimalMax = (isHorizontal()) ? _gcell->getBoundingBox().getYMax()
|
||||
: _gcell->getBoundingBox().getXMax();
|
||||
setInBound( sideStack.getGSideMin(), sideStack.getGSideMax(), optimalMin );
|
||||
setInBound( sideStack.getGSideMin(), sideStack.getGSideMax(), optimalMax );
|
||||
}
|
||||
|
||||
setInBound( sideStack.getGSideMin(), sideStack.getGSideMax(), optimalMin );
|
||||
setInBound( sideStack.getGSideMin(), sideStack.getGSideMax(), optimalMax );
|
||||
|
||||
cdebug_log(145,0) << "optimalMin: " << DbU::getValueString(optimalMin) << endl;
|
||||
cdebug_log(145,0) << "optimalMax: " << DbU::getValueString(optimalMax) << endl;
|
||||
}
|
||||
|
|
|
@ -1263,6 +1263,12 @@ namespace Katana {
|
|||
break;
|
||||
}
|
||||
if (igcell == gcells.size()) return false;
|
||||
if (gcells[igcell]->isDevice()) {
|
||||
if (igcell > 0) --igcell;
|
||||
else if (igcell < gcells.size()-1) ++igcell;
|
||||
else return false;
|
||||
}
|
||||
|
||||
if (not _segment->canDogleg(gcells[igcell])) return false;
|
||||
|
||||
TrackElement* dogleg = NULL;
|
||||
|
|
|
@ -1286,13 +1286,19 @@ namespace Katana {
|
|||
case DataNegociate::RipupPerpandiculars:
|
||||
case DataNegociate::Minimize:
|
||||
case DataNegociate::Dogleg:
|
||||
cdebug_log(159,0) << "Global, SegmentFsm: RipupPerpandiculars." << endl;
|
||||
if (NetRoutingExtension::isAnalog(segment->getNet())) {
|
||||
cdebug_log(159,0) << "Global, SegmentFsm / Analogic: Try to dogleg once." << endl;
|
||||
success = manipulator.makeDogleg( segment->getCanonicalInterval().getCenter() );
|
||||
if (success) break;
|
||||
} else {
|
||||
cdebug_log(159,0) << "Global, SegmentFsm: RipupPerpandiculars." << endl;
|
||||
}
|
||||
nextState = DataNegociate::Slacken;
|
||||
break;
|
||||
case DataNegociate::Slacken:
|
||||
cdebug_log(159,0) << "Global, SegmentFsm: Slacken "
|
||||
<< ((manipulator.getEvent())
|
||||
? manipulator.getEvent()->getConstraints() : "(not event yet)") << endl;
|
||||
? manipulator.getEvent()->getConstraints() : "(no event yet)") << endl;
|
||||
if ( manipulator.getEvent()
|
||||
and manipulator.getEvent()->getConstraints().isPonctual()
|
||||
and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) {
|
||||
|
|
Loading…
Reference in New Issue