P&S: cleaner placement of DP segments/vias. Speed improvements too.
This commit is contained in:
parent
4cbb0aebfd
commit
a2ac1cd087
|
@ -34,7 +34,7 @@
|
||||||
#include "pns_router.h"
|
#include "pns_router.h"
|
||||||
#include "pns_solid.h"
|
#include "pns_solid.h"
|
||||||
#include "pns_utils.h"
|
#include "pns_utils.h"
|
||||||
|
#include "pns_debug_decorator.h"
|
||||||
|
|
||||||
class PNS_LINE;
|
class PNS_LINE;
|
||||||
|
|
||||||
|
@ -121,6 +121,42 @@ DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::anchorDirection( PNS_ITEM* aItem, const VECT
|
||||||
return DIRECTION_45( s->Seg().B - s->Seg().A );
|
return DIRECTION_45( s->Seg().B - s->Seg().A );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PNS_DP_PRIMITIVE_PAIR::CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const
|
||||||
|
{
|
||||||
|
assert (m_primP && m_primN);
|
||||||
|
|
||||||
|
VECTOR2I aP, aN, dir, midpoint;
|
||||||
|
|
||||||
|
if ( m_primP->OfKind(PNS_ITEM::SEGMENT) && m_primN->OfKind(PNS_ITEM::SEGMENT) )
|
||||||
|
{
|
||||||
|
aP = m_primP->Anchor( 1 );
|
||||||
|
aN = m_primN->Anchor( 1 );
|
||||||
|
midpoint = ( aP + aN ) / 2;
|
||||||
|
SEG s = static_cast <PNS_SEGMENT*> (m_primP)->Seg();
|
||||||
|
if ( s.B != s.A )
|
||||||
|
{
|
||||||
|
dir = s.B - s.A;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dir = VECTOR2I(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dir = dir.Resize( (aP - aN).EuclideanNorm() );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
aP = m_primP->Anchor( 0 );
|
||||||
|
aN = m_primN->Anchor( 0 );
|
||||||
|
midpoint = ( aP + aN ) / 2;
|
||||||
|
dir = ( aP - aN ).Perpendicular();
|
||||||
|
|
||||||
|
if ( dir.Dot( aCursorPos - midpoint ) < 0 )
|
||||||
|
dir = -dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
aMidpoint = midpoint;
|
||||||
|
aDirection = dir;
|
||||||
|
}
|
||||||
|
|
||||||
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirP() const
|
DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirP() const
|
||||||
{
|
{
|
||||||
|
@ -134,19 +170,6 @@ DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirN() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void drawGw( VECTOR2I p, int color )
|
|
||||||
{
|
|
||||||
SHAPE_LINE_CHAIN l;
|
|
||||||
|
|
||||||
l.Append( p - VECTOR2I( -50000, -50000 ) );
|
|
||||||
l.Append( p + VECTOR2I( -50000, -50000 ) );
|
|
||||||
|
|
||||||
l.Clear();
|
|
||||||
l.Append( p - VECTOR2I( 50000, -50000 ) );
|
|
||||||
l.Append( p + VECTOR2I( 50000, -50000 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static DIRECTION_45::AngleType angle( const VECTOR2I &a, const VECTOR2I &b )
|
static DIRECTION_45::AngleType angle( const VECTOR2I &a, const VECTOR2I &b )
|
||||||
{
|
{
|
||||||
DIRECTION_45 dir_a( a );
|
DIRECTION_45 dir_a( a );
|
||||||
|
@ -182,7 +205,7 @@ void PNS_DP_GATEWAY::Reverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PNS_DIFF_PAIR::BuildInitial( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal )
|
bool PNS_DIFF_PAIR::BuildInitial( const PNS_DP_GATEWAY& aEntry, const PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal )
|
||||||
{
|
{
|
||||||
SHAPE_LINE_CHAIN p = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorP(), aTarget.AnchorP(), aPrefDiagonal );
|
SHAPE_LINE_CHAIN p = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorP(), aTarget.AnchorP(), aPrefDiagonal );
|
||||||
SHAPE_LINE_CHAIN n = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorN(), aTarget.AnchorN(), aPrefDiagonal );
|
SHAPE_LINE_CHAIN n = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorN(), aTarget.AnchorN(), aPrefDiagonal );
|
||||||
|
@ -314,45 +337,41 @@ void PNS_DP_GATEWAYS::BuildOrthoProjections( PNS_DP_GATEWAYS& aEntries,
|
||||||
bool PNS_DP_GATEWAYS::FitGateways( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget,
|
bool PNS_DP_GATEWAYS::FitGateways( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget,
|
||||||
bool aPrefDiagonal, PNS_DIFF_PAIR& aDp )
|
bool aPrefDiagonal, PNS_DIFF_PAIR& aDp )
|
||||||
{
|
{
|
||||||
std::vector<DP_CANDIDATE> candidates;
|
DP_CANDIDATE best;
|
||||||
|
|
||||||
for( PNS_DP_GATEWAY g_entry : aEntry.Gateways() )
|
int n = 0;
|
||||||
|
int bestScore = -1000;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for( const PNS_DP_GATEWAY& g_entry : aEntry.Gateways() )
|
||||||
{
|
{
|
||||||
for( PNS_DP_GATEWAY g_target : aTarget.Gateways() )
|
for( const PNS_DP_GATEWAY& g_target : aTarget.Gateways() )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
n++;
|
||||||
|
|
||||||
for( int attempt = 0; attempt < 2; attempt++ )
|
for( int attempt = 0; attempt < 2; attempt++ )
|
||||||
{
|
{
|
||||||
|
int score = ( attempt == 1 ? -3 : 0 );
|
||||||
|
score += g_entry.Priority();
|
||||||
|
score += g_target.Priority();
|
||||||
|
|
||||||
|
if( score < bestScore )
|
||||||
|
continue;
|
||||||
|
|
||||||
PNS_DIFF_PAIR l( m_gap );
|
PNS_DIFF_PAIR l( m_gap );
|
||||||
|
|
||||||
if( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ ( attempt ? true : false ) ) )
|
if( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ ( attempt ? true : false ) ) )
|
||||||
{
|
{
|
||||||
int score = ( attempt == 1 ? -3 : 0 );
|
best.p = l.CP();
|
||||||
score +=g_entry.Priority();
|
best.n = l.CN();
|
||||||
score +=g_target.Priority();
|
bestScore = score;
|
||||||
|
found = true;
|
||||||
DP_CANDIDATE c;
|
|
||||||
c.score = score;
|
|
||||||
c.p = l.CP();
|
|
||||||
c.n = l.CN();
|
|
||||||
candidates.push_back( c );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int bestScore = -1000;
|
|
||||||
DP_CANDIDATE best;
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for( DP_CANDIDATE c : candidates )
|
|
||||||
{
|
|
||||||
if( c.score > bestScore )
|
|
||||||
{
|
|
||||||
bestScore = c.score;
|
|
||||||
best = c;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( found )
|
if( found )
|
||||||
{
|
{
|
||||||
|
@ -373,6 +392,14 @@ bool PNS_DP_GATEWAYS::checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PNS_DP_GATEWAYS::FilterByOrientation ( int aAngleMask, DIRECTION_45 aRefOrientation )
|
||||||
|
{
|
||||||
|
std::remove_if( m_gateways.begin(), m_gateways.end(), [aAngleMask, aRefOrientation] ( const PNS_DP_GATEWAY& dp) {
|
||||||
|
DIRECTION_45 orient ( dp.AnchorP() - dp.AnchorN() );
|
||||||
|
return ! (orient.Angle ( aRefOrientation ) & aAngleMask );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
void PNS_DP_GATEWAYS::BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal )
|
void PNS_DP_GATEWAYS::BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal )
|
||||||
{
|
{
|
||||||
VECTOR2I majorDirection;
|
VECTOR2I majorDirection;
|
||||||
|
@ -519,8 +546,6 @@ void PNS_DP_GATEWAYS::BuildForCursor( const VECTOR2I& aCursorPos )
|
||||||
m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir,
|
m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir,
|
||||||
aCursorPos - dir, attempt ? true : false ) );
|
aCursorPos - dir, attempt ? true : false ) );
|
||||||
|
|
||||||
drawGw ( aCursorPos + dir, 2 );
|
|
||||||
drawGw ( aCursorPos - dir, 3 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,9 @@ public:
|
||||||
DIRECTION_45 DirP() const;
|
DIRECTION_45 DirP() const;
|
||||||
DIRECTION_45 DirN() const;
|
DIRECTION_45 DirN() const;
|
||||||
|
|
||||||
|
|
||||||
|
void CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const;
|
||||||
|
|
||||||
void dump()
|
void dump()
|
||||||
{
|
{
|
||||||
printf("-- Prim-P %p anchor [%d, %d]\n", m_primP, m_anchorP.x, m_anchorP.y);
|
printf("-- Prim-P %p anchor [%d, %d]\n", m_primP, m_anchorP.x, m_anchorP.y);
|
||||||
|
@ -223,6 +226,13 @@ class PNS_DP_GATEWAYS
|
||||||
return m_gateways;
|
return m_gateways;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<PNS_DP_GATEWAY>& CGateways() const
|
||||||
|
{
|
||||||
|
return m_gateways;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterByOrientation ( int aAngleMask, DIRECTION_45 aRefOrientation );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct DP_CANDIDATE
|
struct DP_CANDIDATE
|
||||||
|
@ -460,7 +470,7 @@ public:
|
||||||
const SHAPE_LINE_CHAIN& CP() const { return m_p; }
|
const SHAPE_LINE_CHAIN& CP() const { return m_p; }
|
||||||
const SHAPE_LINE_CHAIN& CN() const { return m_n; }
|
const SHAPE_LINE_CHAIN& CN() const { return m_n; }
|
||||||
|
|
||||||
bool BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal );
|
bool BuildInitial ( const PNS_DP_GATEWAY& aEntry, const PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal );
|
||||||
bool CheckConnectionAngle ( const PNS_DIFF_PAIR &aOther, int allowedAngles ) const;
|
bool CheckConnectionAngle ( const PNS_DIFF_PAIR &aOther, int allowedAngles ) const;
|
||||||
int CoupledLength ( const SEG& aP, const SEG& aN ) const;
|
int CoupledLength ( const SEG& aP, const SEG& aN ) const;
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
|
|
||||||
#include <colors.h>
|
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
#include <class_board_item.h>
|
#include <class_board_item.h>
|
||||||
#include <class_netinfo.h>
|
#include <class_netinfo.h>
|
||||||
|
@ -37,8 +34,6 @@
|
||||||
#include "pns_topology.h"
|
#include "pns_topology.h"
|
||||||
#include "pns_debug_decorator.h"
|
#include "pns_debug_decorator.h"
|
||||||
|
|
||||||
using boost::optional;
|
|
||||||
|
|
||||||
PNS_DIFF_PAIR_PLACER::PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter ) :
|
PNS_DIFF_PAIR_PLACER::PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter ) :
|
||||||
PNS_PLACEMENT_ALGO( aRouter )
|
PNS_PLACEMENT_ALGO( aRouter )
|
||||||
{
|
{
|
||||||
|
@ -486,7 +481,7 @@ bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aI
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int refNet = aItem->Net();
|
int refNet = aItem->Net();
|
||||||
int coupledNet = (refNet == netP) ? netN : netP;
|
int coupledNet = (refNet == netP) ? netN : netP;
|
||||||
|
|
||||||
|
@ -664,10 +659,6 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
|
||||||
|
|
||||||
gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );
|
gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );
|
||||||
|
|
||||||
// m_prevPair->dump();
|
|
||||||
|
|
||||||
// printf("Entry %d\n", gwsEntry.Gateways().size());
|
|
||||||
|
|
||||||
PNS_DP_PRIMITIVE_PAIR target;
|
PNS_DP_PRIMITIVE_PAIR target;
|
||||||
|
|
||||||
if( findDpPrimitivePair ( aP, m_currentEndItem, target ) )
|
if( findDpPrimitivePair ( aP, m_currentEndItem, target ) )
|
||||||
|
@ -680,10 +671,23 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
|
||||||
if( !propagateDpHeadForces( aP, fp ) )
|
if( !propagateDpHeadForces( aP, fp ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
VECTOR2I midp, dirV;
|
||||||
|
m_prevPair->CursorOrientation(fp, midp, dirV);
|
||||||
|
|
||||||
|
VECTOR2I fpProj = SEG( midp, midp+dirV ).LineProject ( fp );
|
||||||
|
int lead_dist = (fpProj - fp).EuclideanNorm();
|
||||||
|
|
||||||
gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() );
|
gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() );
|
||||||
gwsTarget.BuildForCursor( fp );
|
|
||||||
gwsTarget.BuildOrthoProjections( gwsEntry, fp, m_orthoMode ? 200 : -200 );
|
if (lead_dist > m_sizes.DiffPairGap() + m_sizes.DiffPairWidth() )
|
||||||
// printf("Target %d\n", gwsTarget.Gateways().size());
|
{
|
||||||
|
gwsTarget.BuildForCursor( fp );
|
||||||
|
} else {
|
||||||
|
gwsTarget.BuildForCursor( fpProj );
|
||||||
|
gwsTarget.FilterByOrientation ( DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_HALF_FULL, DIRECTION_45 ( dirV ) );
|
||||||
|
}
|
||||||
|
|
||||||
m_snapOnTarget = false;
|
m_snapOnTarget = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,7 +695,9 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
|
||||||
m_currentTrace.SetGap( gap() );
|
m_currentTrace.SetGap( gap() );
|
||||||
m_currentTrace.SetLayer( m_currentLayer );
|
m_currentTrace.SetLayer( m_currentLayer );
|
||||||
|
|
||||||
if ( gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace ) )
|
bool result = gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace );
|
||||||
|
|
||||||
|
if ( result )
|
||||||
{
|
{
|
||||||
m_currentTrace.SetNets( m_netP, m_netN );
|
m_currentTrace.SetNets( m_netP, m_netN );
|
||||||
m_currentTrace.SetWidth( m_sizes.DiffPairWidth() );
|
m_currentTrace.SetWidth( m_sizes.DiffPairWidth() );
|
||||||
|
|
Loading…
Reference in New Issue