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() ) if( !m_originPair.PLine().SegmentCount() || !m_originPair.NLine().SegmentCount() )
return false; return false;
SOLID* padA = nullptr; m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &m_startPad_p, &m_endPad_p );
SOLID* padB = nullptr;
m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &padA, &padB );
m_padToDieP = 0; m_padToDieP = 0;
if( padA ) if( m_startPad_p )
m_padToDieP += padA->GetPadToDie(); m_padToDieP += m_startPad_p->GetPadToDie();
if( padB ) if( m_endPad_p )
m_padToDieP += padB->GetPadToDie(); 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; m_padToDieN = 0;
if( padA ) if( m_startPad_n )
m_padToDieN += padA->GetPadToDie(); m_padToDieN += m_startPad_n->GetPadToDie();
if( padB ) if( m_endPad_n )
m_padToDieN += padB->GetPadToDie(); m_padToDieN += m_endPad_n->GetPadToDie();
m_padToDieLength = std::max( m_padToDieP, m_padToDieN ); 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 DP_MEANDER_PLACER::origPathLength() const
{ {
long long int totalP = m_padToDieLength + lineLength( m_tunedPathP ); long long int totalP = m_padToDieLength + lineLength( m_tunedPathP, m_startPad_p, m_endPad_p );
long long int totalN = m_padToDieLength + lineLength( m_tunedPathN ); long long int totalN = m_padToDieLength + lineLength( m_tunedPathN, m_startPad_n, m_endPad_n );
return std::max( totalP, totalN ); 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_world = Router()->GetWorld()->Branch();
m_originLine = m_world->AssembleLine( m_initialSegment ); m_originLine = m_world->AssembleLine( m_initialSegment );
SOLID* padA = nullptr;
SOLID* padB = nullptr;
TOPOLOGY topo( m_world ); 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; m_padToDieLength = 0;
if( padA ) if( m_startPad_n )
m_padToDieLength += padA->GetPadToDie(); m_padToDieLength += m_startPad_n->GetPadToDie();
if( padB ) if( m_endPad_n )
m_padToDieLength += padB->GetPadToDie(); m_padToDieLength += m_endPad_n->GetPadToDie();
m_world->Remove( m_originLine ); 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 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_world = nullptr;
m_currentWidth = 0; m_currentWidth = 0;
m_padToDieLength = 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; 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++ ) for( int idx = 0; idx < aLine.Size(); idx++ )
{ {
const ITEM* item = aLine[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; return total;
} }

View File

@ -149,7 +149,7 @@ protected:
* @param aLine * @param aLine
* @return * @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. ///< Pointer to world to search colliding items.
NODE* m_world; NODE* m_world;
@ -165,6 +165,11 @@ protected:
///< The current end point. ///< The current end point.
VECTOR2I m_currentEnd; 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() ) !m_originPair.NLine().SegmentCount() )
return false; return false;
SOLID* padA = nullptr; m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &m_startPad_p, &m_endPad_p );
SOLID* padB = nullptr;
m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &padA, &padB );
m_padToDieP = 0; m_padToDieP = 0;
if( padA ) if( m_startPad_p )
m_padToDieP += padA->GetPadToDie(); m_padToDieP += m_startPad_p->GetPadToDie();
if( padB ) if( m_endPad_p )
m_padToDieP += padB->GetPadToDie(); 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; m_padToDieN = 0;
if( padA ) if( m_startPad_n )
m_padToDieN += padA->GetPadToDie(); m_padToDieN += m_startPad_n->GetPadToDie();
if( padB ) if( m_endPad_n )
m_padToDieN += padB->GetPadToDie(); m_padToDieN += m_endPad_n->GetPadToDie();
m_world->Remove( m_originLine ); m_world->Remove( m_originLine );
m_currentWidth = m_originLine.Width(); m_currentWidth = m_originLine.Width();
m_currentEnd = VECTOR2I( 0, 0 ); 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_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; m_tunedPath = m_tunedPathP;
} }
else else
{ {
m_padToDieLength = m_padToDieN; 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; 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 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 );
} }