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:
Jean-Paul Chaput 2023-02-14 22:35:56 +01:00
parent 77afb7cba4
commit 07f269196b
7 changed files with 75 additions and 4 deletions

View File

@ -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;

View File

@ -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() ) {

View File

@ -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) );
}

View File

@ -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
{

View File

@ -92,7 +92,7 @@ namespace Katana {
track = track->getNextTrack();
_refcount++;
}
}
}
Net* TrackMarker::getNet () const

View File

@ -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 ();

View File

@ -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;