Manage new cases of stacked VIAs potential creation.
When placing a vertical M1 (and setting it's axis), the perpandiculars M2 extremities changes, and they have a VIA. If they are already placed too, they may silently create a stacked VIAs because the track markers of the perpendiculars are not taken into account. Now, force to rip them up so the markers will be re-read. If no stacked VIAs has been created, the segment will be re-put at it's previous place, otherwise it will be placed on another track. * New: Track::hasViaMarker(), check if a marker of a Net is under a given interval (so we can know we are about to create a VIA stack). * New: Manipulator::avoidStackedVias(), ripup perpandiculars to the current segment that *may* create stacked VIAs. That is perpandicular in the *up* layer which begin or end on the moved vertical. * New: In SegmentFsm::insertInTrack(), bindTotrack() & moveToTrack(), call Manipulator::avoidStackedVias(), if activated. * Change: In NegociateWidow/loadRoutingPads(), no longer exclude clock nets. So the TrackMarkers are created for the root net.
This commit is contained in:
parent
77afb7cba4
commit
07f269196b
|
@ -1705,6 +1705,49 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
void Manipulator::avoidStackedVias ( DbU::Unit axis )
|
||||
{
|
||||
cdebug_log(159,1) << "Manipulator::avoidStackedVias()" << endl;
|
||||
|
||||
uint32_t perpandicularActionFlags = SegmentAction::SelfRipupPerpand;
|
||||
|
||||
const vector<TrackElement*>& perpandiculars = _event->getPerpandiculars();
|
||||
for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) {
|
||||
TrackElement* perpandicular = perpandiculars[iperpand];
|
||||
DataNegociate* data = perpandicular->getDataNegociate();
|
||||
|
||||
if (perpandicular->isFixed ()) continue;
|
||||
if (not data) continue;
|
||||
if (data->getState() >= DataNegociate::RepairFailed) continue;
|
||||
if (not perpandicular->getTrack()) continue;
|
||||
if (perpandicular->getDepth() <= _segment->getDepth()) continue;
|
||||
|
||||
cdebug_log(159,0) << "P: " << perpandicular << endl;
|
||||
if (perpandicular->getSourceAxis() == _segment->getAxis()) {
|
||||
if (not perpandicular->getTrack()->hasViaMarker(perpandicular->getNet(),Interval(axis)))
|
||||
continue;
|
||||
} else if (perpandicular->getTargetAxis() == _segment->getAxis()) {
|
||||
if (not perpandicular->getTrack()->hasViaMarker(perpandicular->getNet(),Interval(axis)))
|
||||
continue;
|
||||
} else
|
||||
continue;
|
||||
|
||||
if (RoutingEvent::getStage() == StageRepair) {
|
||||
if (_segment->getDataNegociate()->getState() < DataNegociate::Repair)
|
||||
_segment->getDataNegociate()->resetRipupCount();
|
||||
|
||||
data->setState( DataNegociate::Repair );
|
||||
if (data->getStateCount() > 1) data->resetStateCount();
|
||||
}
|
||||
|
||||
cdebug_log(159,0) << "Stacked VIA ripup: " << perpandicular << endl;
|
||||
_fsm.addAction( perpandicular, perpandicularActionFlags );
|
||||
}
|
||||
|
||||
cdebug_tabw(159,-1);
|
||||
}
|
||||
|
||||
|
||||
bool Manipulator::avoidBlockage ()
|
||||
{
|
||||
cdebug_log(159,1) << "Manipulator::avoidBlockage()" << endl;
|
||||
|
|
|
@ -189,7 +189,7 @@ namespace {
|
|||
for( Net* net : nw->getCell()->getNets() ) {
|
||||
if (net->getType() == Net::Type::POWER ) continue;
|
||||
if (net->getType() == Net::Type::GROUND) continue;
|
||||
if (net->getType() == Net::Type::CLOCK ) continue;
|
||||
//if (net->getType() == Net::Type::CLOCK ) continue;
|
||||
if (af->isBLOCKAGE(net->getName())) continue;
|
||||
|
||||
for( RoutingPad* rp : net->getRoutingPads() ) {
|
||||
|
|
|
@ -759,13 +759,16 @@ namespace Katana {
|
|||
useEvent1();
|
||||
if (_event2) _event2->setInsertState( _event1->getInsertState() );
|
||||
|
||||
if (success and Session::disableStackedVias())
|
||||
Manipulator( _event1->getSegment(), useEvent1() ).avoidStackedVias( getCandidateAxis1(i) );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
void SegmentFsm::bindToTrack ( size_t i )
|
||||
{
|
||||
cdebug_log(159,0) << "SegmentFsm::bindToTrack() :" << " track:" << i << endl;
|
||||
cdebug_log(159,0) << "SegmentFsm::bindToTrack() track:" << i << endl;
|
||||
|
||||
_event1->resetInsertState();
|
||||
_event1->updateAxisHistory();
|
||||
|
@ -785,6 +788,9 @@ namespace Katana {
|
|||
}
|
||||
|
||||
setState( SegmentFsm::SelfInserted );
|
||||
|
||||
if (Session::disableStackedVias())
|
||||
Manipulator( _event1->getSegment(), useEvent1() ).avoidStackedVias( getCandidateAxis1(i) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -800,6 +806,9 @@ namespace Katana {
|
|||
}
|
||||
|
||||
setState( SegmentFsm::SelfInserted );
|
||||
|
||||
if (Session::disableStackedVias())
|
||||
Manipulator( _event1->getSegment(), useEvent1() ).avoidStackedVias( getCandidateAxis1(i) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -418,6 +418,23 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
bool Track::hasViaMarker ( Net* net, Interval span )
|
||||
{
|
||||
vector<TrackMarker*>::const_iterator lowerBound
|
||||
= lower_bound( _markers.begin(), _markers.end(), span.getVMin(), TrackMarker::Compare() );
|
||||
size_t mbegin = lowerBound - _markers.begin();
|
||||
|
||||
for ( ; (mbegin < _markers.size())
|
||||
and (_markers[mbegin]->getSourceU() <= span.getVMax()) ; mbegin++ ) {
|
||||
if (Session::disableStackedVias()
|
||||
and (_markers[mbegin]->getNet() == net) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Track::getBeginIndex ( DbU::Unit position, size_t& begin, uint32_t& state ) const
|
||||
{
|
||||
cdebug_log(155,0) << "Track::getBeginIndex(): @" << DbU::getValueString(position)
|
||||
|
@ -486,7 +503,7 @@ namespace Katana {
|
|||
state = OutsideElement;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Track::getOverlapBounds ( Interval interval, size_t& begin, size_t& end ) const
|
||||
{
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace Katana {
|
|||
track = track->getNextTrack();
|
||||
_refcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net* TrackMarker::getNet () const
|
||||
|
|
|
@ -66,6 +66,7 @@ namespace Katana {
|
|||
void repackPerpandiculars ( uint32_t flags );
|
||||
void reprocessPerpandiculars ();
|
||||
void reprocessParallels ();
|
||||
void avoidStackedVias ( DbU::Unit axis );
|
||||
bool avoidBlockage ();
|
||||
bool ripple ();
|
||||
bool minimize ();
|
||||
|
|
|
@ -93,6 +93,7 @@ namespace Katana {
|
|||
Interval getFreeInterval ( DbU::Unit position, Net* net=NULL ) const;
|
||||
Interval getNextFree ( size_t index, Net* net );
|
||||
Interval getPreviousFree ( size_t index, Net* net );
|
||||
bool hasViaMarker ( Net* net, Interval span );
|
||||
Interval getOccupiedInterval ( size_t& begin ) const;
|
||||
Interval expandFreeInterval ( size_t& begin, size_t& end, uint32_t state, Net* ) const;
|
||||
void getBeginIndex ( DbU::Unit position, size_t& begin, uint32_t& state ) const;
|
||||
|
|
Loading…
Reference in New Issue