P&S: cleaner placement of DP segments/vias. Speed improvements too.

This commit is contained in:
Tomasz Wlostowski 2016-08-15 17:16:49 +02:00 committed by Maciej Suminski
parent 4cbb0aebfd
commit a2ac1cd087
3 changed files with 98 additions and 57 deletions

View File

@ -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 );
} }
} }
} }

View File

@ -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;

View File

@ -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() );