PNS: Handle via-in-pad distances when tuning

Tuning with a via in pad, the via isn't a part of the full line.  But we
still need to account for the line length distance of the
starting/ending vias.  To do this, we simply measure the height from
the ending track to the ending pad and starting track to starting pad

(cherry picked from commit 82e8e38054)
This commit is contained in:
Seth Hillbrand 2022-08-01 20:23:07 -07:00
parent cc78997386
commit e0b3f6c258
5 changed files with 89 additions and 43 deletions

View File

@ -100,28 +100,25 @@ bool DP_MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
if( !m_originPair.PLine().SegmentCount() || !m_originPair.NLine().SegmentCount() )
return false;
SOLID* padA = nullptr;
SOLID* padB = nullptr;
m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &padA, &padB );
m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &m_startPad_p, &m_endPad_p );
m_padToDieP = 0;
if( padA )
m_padToDieP += padA->GetPadToDie();
if( m_startPad_p )
m_padToDieP += m_startPad_p->GetPadToDie();
if( padB )
m_padToDieP += padB->GetPadToDie();
if( m_endPad_p )
m_padToDieP += m_endPad_p->GetPadToDie();
m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &padA, &padB );
m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &m_startPad_n, &m_endPad_n );
m_padToDieN = 0;
if( padA )
m_padToDieN += padA->GetPadToDie();
if( m_startPad_n )
m_padToDieN += m_startPad_n->GetPadToDie();
if( padB )
m_padToDieN += padB->GetPadToDie();
if( m_endPad_n )
m_padToDieN += m_endPad_n->GetPadToDie();
m_padToDieLength = std::max( m_padToDieP, m_padToDieN );
@ -141,8 +138,8 @@ void DP_MEANDER_PLACER::release()
long long int DP_MEANDER_PLACER::origPathLength() const
{
long long int totalP = m_padToDieLength + lineLength( m_tunedPathP );
long long int totalN = m_padToDieLength + lineLength( m_tunedPathN );
long long int totalP = m_padToDieLength + lineLength( m_tunedPathP, m_startPad_p, m_endPad_p );
long long int totalN = m_padToDieLength + lineLength( m_tunedPathN, m_startPad_n, m_endPad_n );
return std::max( totalP, totalN );
}

View File

@ -72,19 +72,16 @@ bool MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
m_world = Router()->GetWorld()->Branch();
m_originLine = m_world->AssembleLine( m_initialSegment );
SOLID* padA = nullptr;
SOLID* padB = nullptr;
TOPOLOGY topo( m_world );
m_tunedPath = topo.AssembleTuningPath( m_initialSegment, &padA, &padB );
m_tunedPath = topo.AssembleTuningPath( m_initialSegment, &m_startPad_n, &m_endPad_n );
m_padToDieLength = 0;
if( padA )
m_padToDieLength += padA->GetPadToDie();
if( m_startPad_n )
m_padToDieLength += m_startPad_n->GetPadToDie();
if( padB )
m_padToDieLength += padB->GetPadToDie();
if( m_endPad_n )
m_padToDieLength += m_endPad_n->GetPadToDie();
m_world->Remove( m_originLine );
@ -97,7 +94,7 @@ bool MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
long long int MEANDER_PLACER::origPathLength() const
{
return m_padToDieLength + lineLength( m_tunedPath );
return m_padToDieLength + lineLength( m_tunedPath, m_startPad_n, m_endPad_n );
}

View File

@ -33,6 +33,10 @@ MEANDER_PLACER_BASE::MEANDER_PLACER_BASE( ROUTER* aRouter ) :
m_world = nullptr;
m_currentWidth = 0;
m_padToDieLength = 0;
m_startPad_n = nullptr;
m_startPad_p = nullptr;
m_endPad_n = nullptr;
m_endPad_p = nullptr;
}
@ -278,10 +282,36 @@ VECTOR2I MEANDER_PLACER_BASE::getSnappedStartPoint( LINKED_ITEM* aStartItem, VEC
}
long long int MEANDER_PLACER_BASE::lineLength( const ITEM_SET& aLine ) const
long long int MEANDER_PLACER_BASE::lineLength( const ITEM_SET& aLine, const SOLID* aStartPad, const SOLID* aEndPad ) const
{
long long int total = 0;
if( aLine.Empty() )
return 0;
const ITEM* start_item = aLine[0];
const ITEM* end_item = aLine[aLine.Size() - 1];
bool start_via = false;
bool end_via = false;
int start_layer = -1;
int end_layer = -1;
std::set<int> layer_set;
for( int idx = 0; idx < aLine.Size(); idx++ )
{
const ITEM* item = aLine[idx];
layer_set.insert( item->Layer() );
}
/**
* If there is a start pad but the pad's layers do not overlap the first track layer, then there must be a
* fanout via on the line. If there isn't, we still need to have the via back to the pad, so count the distance
* in the line tuning
*/
start_via = aStartPad && ( !aStartPad->LayersOverlap( start_item ) );
end_via = aEndPad && ( !aEndPad->LayersOverlap( end_item ) );
for( int idx = 0; idx < aLine.Size(); idx++ )
{
const ITEM* item = aLine[idx];
@ -300,6 +330,22 @@ long long int MEANDER_PLACER_BASE::lineLength( const ITEM_SET& aLine ) const
}
}
if( start_via )
{
int layerPrev = aStartPad->Layer();
int layerNext = start_item->Layer();
total += m_router->GetInterface()->StackupHeight( layerPrev, layerNext );
}
if( end_via )
{
int layerPrev = end_item->Layer();
int layerNext = aEndPad->Layer();
total += m_router->GetInterface()->StackupHeight( layerPrev, layerNext );
}
return total;
}

View File

@ -149,7 +149,7 @@ protected:
* @param aLine
* @return
*/
long long int lineLength( const ITEM_SET& aLine ) const;
long long int lineLength( const ITEM_SET& aLine, const SOLID* aStartPad, const SOLID* aEndPad ) const;
///< Pointer to world to search colliding items.
NODE* m_world;
@ -165,6 +165,11 @@ protected:
///< The current end point.
VECTOR2I m_currentEnd;
SOLID* m_startPad_p;
SOLID* m_endPad_p;
SOLID* m_startPad_n;
SOLID* m_endPad_n;
};
}

View File

@ -80,44 +80,41 @@ bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
!m_originPair.NLine().SegmentCount() )
return false;
SOLID* padA = nullptr;
SOLID* padB = nullptr;
m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &padA, &padB );
m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &m_startPad_p, &m_endPad_p );
m_padToDieP = 0;
if( padA )
m_padToDieP += padA->GetPadToDie();
if( m_startPad_p )
m_padToDieP += m_startPad_p->GetPadToDie();
if( padB )
m_padToDieP += padB->GetPadToDie();
if( m_endPad_p )
m_padToDieP += m_endPad_p->GetPadToDie();
m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &padA, &padB );
m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &m_startPad_n, &m_endPad_n );
m_padToDieN = 0;
if( padA )
m_padToDieN += padA->GetPadToDie();
if( m_startPad_n )
m_padToDieN += m_startPad_n->GetPadToDie();
if( padB )
m_padToDieN += padB->GetPadToDie();
if( m_endPad_n )
m_padToDieN += m_endPad_n->GetPadToDie();
m_world->Remove( m_originLine );
m_currentWidth = m_originLine.Width();
m_currentEnd = VECTOR2I( 0, 0 );
if ( m_originPair.PLine().Net() == m_originLine.Net() )
if ( m_originPair.NetP() == m_originLine.Net() )
{
m_padToDieLength = m_padToDieP;
m_coupledLength = m_padToDieN + lineLength( m_tunedPathN );
m_coupledLength = m_padToDieN + lineLength( m_tunedPathN, m_startPad_n, m_endPad_n );
m_tunedPath = m_tunedPathP;
}
else
{
m_padToDieLength = m_padToDieN;
m_coupledLength = m_padToDieP + lineLength( m_tunedPathP );
m_coupledLength = m_padToDieP + lineLength( m_tunedPathP, m_startPad_p, m_endPad_p );
m_tunedPath = m_tunedPathN;
}
@ -127,7 +124,11 @@ bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
long long int MEANDER_SKEW_PLACER::origPathLength() const
{
return m_padToDieLength + lineLength( m_tunedPath );
if ( m_originPair.NetP() == m_originLine.Net() )
return m_padToDieLength + lineLength( m_tunedPath, m_startPad_p, m_endPad_p );
return m_padToDieLength + lineLength( m_tunedPath, m_startPad_n, m_endPad_n );
}