From 07f269196b1911cd941440f90cde4248c3bc0b2a Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 14 Feb 2023 22:35:56 +0100 Subject: [PATCH] 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. --- katana/src/Manipulator.cpp | 43 +++++++++++++++++++++++++++++++++ katana/src/NegociateWindow.cpp | 2 +- katana/src/SegmentFsm.cpp | 11 ++++++++- katana/src/Track.cpp | 19 ++++++++++++++- katana/src/TrackMarker.cpp | 2 +- katana/src/katana/Manipulator.h | 1 + katana/src/katana/Track.h | 1 + 7 files changed, 75 insertions(+), 4 deletions(-) diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index 7c3b35ac..0c23f06c 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -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& perpandiculars = _event->getPerpandiculars(); + for ( size_t iperpand=0 ; iperpandgetDataNegociate(); + + 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; diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 4e71a9e4..ddf701bb 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -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() ) { diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index f759b79c..633bb953 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -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) ); } diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 6b39e332..ae442b4a 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -418,6 +418,23 @@ namespace Katana { } + bool Track::hasViaMarker ( Net* net, Interval span ) + { + vector::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 { diff --git a/katana/src/TrackMarker.cpp b/katana/src/TrackMarker.cpp index 30d30c99..d541e79f 100644 --- a/katana/src/TrackMarker.cpp +++ b/katana/src/TrackMarker.cpp @@ -92,7 +92,7 @@ namespace Katana { track = track->getNextTrack(); _refcount++; } - } + } Net* TrackMarker::getNet () const diff --git a/katana/src/katana/Manipulator.h b/katana/src/katana/Manipulator.h index f15385f2..77bba74e 100644 --- a/katana/src/katana/Manipulator.h +++ b/katana/src/katana/Manipulator.h @@ -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 (); diff --git a/katana/src/katana/Track.h b/katana/src/katana/Track.h index 9864b6bc..d504d62a 100644 --- a/katana/src/katana/Track.h +++ b/katana/src/katana/Track.h @@ -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;