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_solid.h"
|
||||
#include "pns_utils.h"
|
||||
|
||||
#include "pns_debug_decorator.h"
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
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 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 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++ )
|
||||
{
|
||||
int score = ( attempt == 1 ? -3 : 0 );
|
||||
score += g_entry.Priority();
|
||||
score += g_target.Priority();
|
||||
|
||||
if( score < bestScore )
|
||||
continue;
|
||||
|
||||
PNS_DIFF_PAIR l( m_gap );
|
||||
|
||||
if( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ ( attempt ? true : false ) ) )
|
||||
{
|
||||
int score = ( attempt == 1 ? -3 : 0 );
|
||||
score +=g_entry.Priority();
|
||||
score +=g_target.Priority();
|
||||
|
||||
DP_CANDIDATE c;
|
||||
c.score = score;
|
||||
c.p = l.CP();
|
||||
c.n = l.CN();
|
||||
candidates.push_back( c );
|
||||
best.p = l.CP();
|
||||
best.n = l.CN();
|
||||
bestScore = score;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
VECTOR2I majorDirection;
|
||||
|
@ -519,8 +546,6 @@ void PNS_DP_GATEWAYS::BuildForCursor( const VECTOR2I& aCursorPos )
|
|||
m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir,
|
||||
aCursorPos - dir, attempt ? true : false ) );
|
||||
|
||||
drawGw ( aCursorPos + dir, 2 );
|
||||
drawGw ( aCursorPos - dir, 3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,6 +157,9 @@ public:
|
|||
DIRECTION_45 DirP() const;
|
||||
DIRECTION_45 DirN() const;
|
||||
|
||||
|
||||
void CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const;
|
||||
|
||||
void dump()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
const std::vector<PNS_DP_GATEWAY>& CGateways() const
|
||||
{
|
||||
return m_gateways;
|
||||
}
|
||||
|
||||
void FilterByOrientation ( int aAngleMask, DIRECTION_45 aRefOrientation );
|
||||
|
||||
private:
|
||||
|
||||
struct DP_CANDIDATE
|
||||
|
@ -460,7 +470,7 @@ public:
|
|||
const SHAPE_LINE_CHAIN& CP() const { return m_p; }
|
||||
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;
|
||||
int CoupledLength ( const SEG& aP, const SEG& aN ) const;
|
||||
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
* 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_item.h>
|
||||
#include <class_netinfo.h>
|
||||
|
@ -37,8 +34,6 @@
|
|||
#include "pns_topology.h"
|
||||
#include "pns_debug_decorator.h"
|
||||
|
||||
using boost::optional;
|
||||
|
||||
PNS_DIFF_PAIR_PLACER::PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter ) :
|
||||
PNS_PLACEMENT_ALGO( aRouter )
|
||||
{
|
||||
|
@ -664,10 +659,6 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
|
|||
|
||||
gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );
|
||||
|
||||
// m_prevPair->dump();
|
||||
|
||||
// printf("Entry %d\n", gwsEntry.Gateways().size());
|
||||
|
||||
PNS_DP_PRIMITIVE_PAIR target;
|
||||
|
||||
if( findDpPrimitivePair ( aP, m_currentEndItem, target ) )
|
||||
|
@ -680,10 +671,23 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
|
|||
if( !propagateDpHeadForces( aP, fp ) )
|
||||
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.BuildForCursor( fp );
|
||||
gwsTarget.BuildOrthoProjections( gwsEntry, fp, m_orthoMode ? 200 : -200 );
|
||||
// printf("Target %d\n", gwsTarget.Gateways().size());
|
||||
|
||||
if (lead_dist > m_sizes.DiffPairGap() + m_sizes.DiffPairWidth() )
|
||||
{
|
||||
gwsTarget.BuildForCursor( fp );
|
||||
} else {
|
||||
gwsTarget.BuildForCursor( fpProj );
|
||||
gwsTarget.FilterByOrientation ( DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_HALF_FULL, DIRECTION_45 ( dirV ) );
|
||||
}
|
||||
|
||||
m_snapOnTarget = false;
|
||||
}
|
||||
|
||||
|
@ -691,7 +695,9 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
|
|||
m_currentTrace.SetGap( gap() );
|
||||
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.SetWidth( m_sizes.DiffPairWidth() );
|
||||
|
|
Loading…
Reference in New Issue