Use Track::repair() to solve overlaps.

* New: In Track::repair(), the gapset was used to *close* same-net gaps
   is now alos used to restore minimal spacing between different nets.
   Seems to be not fully working yet.
This commit is contained in:
Jean-Paul Chaput 2021-04-21 13:51:33 +02:00
parent a05bd81bab
commit f4514cecf3
1 changed files with 69 additions and 22 deletions

View File

@ -48,7 +48,12 @@ namespace {
span ( size_t ) const; span ( size_t ) const;
inline DbU::Unit sourceU ( size_t ) const; inline DbU::Unit sourceU ( size_t ) const;
inline DbU::Unit targetU ( size_t ) const; inline DbU::Unit targetU ( size_t ) const;
inline DbU::Unit spansSourceU () const;
inline DbU::Unit spansTargetU () const;
inline size_t spansSourceI () const;
inline size_t spansTargetI () const;
void merge ( size_t ); void merge ( size_t );
void swap ( GapSet& );
inline void clear (); inline void clear ();
private: private:
const Track* _track; const Track* _track;
@ -76,6 +81,18 @@ namespace {
_spans.clear(); _spans.clear();
} }
inline size_t GapSet::spansSourceI () const { return _spans.empty() ? 0 : _spans.front().first; }
inline size_t GapSet::spansTargetI () const { return _spans.empty() ? 0 : _spans.back().second; }
inline DbU::Unit GapSet::spansSourceU () const { return _spans.empty() ? 0 : sourceU(0); }
inline DbU::Unit GapSet::spansTargetU () const { return _spans.empty() ? 0 : targetU(_spans.size()-1); }
void GapSet::swap ( GapSet& other )
{
std::swap( _track , other._track );
std::swap( _halfSpacing, other._halfSpacing );
std::swap( _spans , other._spans );
}
inline const pair<size_t,size_t>& GapSet::span ( size_t i ) const inline const pair<size_t,size_t>& GapSet::span ( size_t i ) const
{ {
static pair<size_t,size_t> nospan = make_pair(0,0); static pair<size_t,size_t> nospan = make_pair(0,0);
@ -962,28 +979,57 @@ namespace Katana {
DbU::Unit minSpacing = getLayer()->getMinimalSpacing(); DbU::Unit minSpacing = getLayer()->getMinimalSpacing();
uint32_t gaps = 0; uint32_t gaps = 0;
GapSet gapset ( this ); GapSet gapsetPrev ( this );
GapSet gapsetCurr ( this );
for ( size_t i=0 ; i<_segments.size()-1 ; i++ ) { for ( size_t i=0 ; i<_segments.size()-1 ; i++ ) {
gapset.merge( i ); gapsetCurr.merge( i );
if ( (_segments[i]->getNet() != _segments[i+1]->getNet()) if ( (_segments[i]->getNet() != _segments[i+1]->getNet())
or _segments[i]->getLayer()->isBlockage() ) { or _segments[i]->getLayer()->isBlockage() ) {
if (gapset.size() > 1) { if (gapsetPrev.size() and gapsetCurr.size()) {
DbU::Unit spacing = gapsetCurr.spansSourceU() - gapsetPrev.spansTargetU();
if (spacing < minSpacing) {
spacing = minSpacing - spacing;
AutoSegment* prev = _segments[ gapsetPrev.span(gapsetPrev.size()-1).second ]->base();
if (prev and (prev->getDuTarget() >= spacing)) {
prev->setDuSource( prev->getDuSource() - spacing );
prev->setDuTarget( prev->getDuTarget() - spacing );
cerr << Warning( " Track::repair(): Enlarging narrow gap in %s near (shift left):\n %s"
, getString(this).c_str()
, getString(prev).c_str() ) << endl;
} else {
AutoSegment* curr = _segments[ gapsetCurr.span(0).first ]->base();
if (curr and (-curr->getDuSource() >= spacing)) {
curr->setDuSource( curr->getDuSource() + spacing );
curr->setDuTarget( curr->getDuTarget() + spacing );
cerr << Warning( " Track::repair(): Enlarging narrow gap in %s near (shift right):\n %s"
, getString(this).c_str()
, getString(curr).c_str() ) << endl;
}
}
}
}
if (gapsetCurr.size() > 1) {
// cerr << "potential gap around " << _segments[i] << endl; // cerr << "potential gap around " << _segments[i] << endl;
for ( size_t j=0 ; j+1 < gapset.size() ; ++j ) { for ( size_t j=0 ; j+1 < gapsetCurr.size() ; ++j ) {
// cerr << j << "=[" << DbU::getValueString(gapset.sourceU(j)) // cerr << j << "=[" << DbU::getValueString(gapsetCurr.sourceU(j))
// << " " << DbU::getValueString(gapset.targetU(j)) << "], " // << " " << DbU::getValueString(gapsetCurr.targetU(j)) << "], "
// << j+1 << "=[" << DbU::getValueString(gapset.sourceU(j+1)) // << j+1 << "=[" << DbU::getValueString(gapsetCurr.sourceU(j+1))
// << " " << DbU::getValueString(gapset.targetU(j+1)) << "]" << endl; // << " " << DbU::getValueString(gapsetCurr.targetU(j+1)) << "]" << endl;
DbU::Unit spacing = gapset.sourceU(j+1) - gapset.targetU(j); DbU::Unit spacing = gapsetCurr.sourceU(j+1) - gapsetCurr.targetU(j);
// cerr << "| spacing=" << DbU::getValueString(spacing) << endl; // cerr << "| spacing=" << DbU::getValueString(spacing) << endl;
if (spacing < minSpacing) { if (spacing < minSpacing) {
AutoSegment* first = _segments[gapset.span(j+1).first]->base(); // cerr << j << "=[" << DbU::getValueString(gapsetCurr.sourceU(j))
// << " " << DbU::getValueString(gapsetCurr.targetU(j)) << "], "
// << j+1 << "=[" << DbU::getValueString(gapsetCurr.sourceU(j+1))
// << " " << DbU::getValueString(gapsetCurr.targetU(j+1)) << "]" << endl;
AutoSegment* first = _segments[gapsetCurr.span(j+1).first]->base();
for ( AutoSegment* segment : first->getAligneds() ) { for ( AutoSegment* segment : first->getAligneds() ) {
if (segment->getSourcePosition() < first->getSourcePosition()) if (segment->getSourcePosition() < first->getSourcePosition())
first = segment; first = segment;
} }
//cerr << "spacing:" << DbU::getValueString(spacing) << " " << first << endl; // cerr << "duSource:" << DbU::getValueString(first->getDuSource()) << endl;
first->setDuSource( first->getDuSource() - spacing ); first->setDuSource( first->getDuSource() - spacing - minSpacing/2 );
++gaps; ++gaps;
cerr << Warning( " Track::repair(): Closing same net gap in %s near:\n %s" cerr << Warning( " Track::repair(): Closing same net gap in %s near:\n %s"
, getString(this).c_str() , getString(this).c_str()
@ -992,7 +1038,8 @@ namespace Katana {
} }
} }
} }
gapset.clear(); gapsetPrev.swap( gapsetCurr );
gapsetCurr.clear();
} }
} }