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
This commit is contained in:
Seth Hillbrand 2022-08-01 20:23:07 -07:00
parent 57de5a6b65
commit 82e8e38054
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 );
}