Ejemplo n.º 1
0
const PNS_DIFF_PAIR PNS_DP_GATEWAY::Entry() const
{
    return PNS_DIFF_PAIR( m_entryP, m_entryN, 0 );
}
Ejemplo n.º 2
0
bool PNS_TOPOLOGY::AssembleDiffPair( PNS_ITEM* aStart, PNS_DIFF_PAIR& aPair )
{
    int refNet = aStart->Net();
    int coupledNet = DpCoupledNet( refNet );

    if( coupledNet < 0 )
        return false;

    std::set<PNS_ITEM*> coupledItems;

    m_world->AllItemsInNet( coupledNet, coupledItems );

    PNS_SEGMENT* coupledSeg = NULL, *refSeg;
    int minDist = std::numeric_limits<int>::max();

    if( ( refSeg = dyn_cast<PNS_SEGMENT*>( aStart ) ) != NULL )
    {
        for( PNS_ITEM* item : coupledItems )
        {
            if( PNS_SEGMENT* s = dyn_cast<PNS_SEGMENT*>( item ) )
            {
                if( s->Layers().Start() == refSeg->Layers().Start() && s->Width() == refSeg->Width() )
                {
                    int dist = s->Seg().Distance( refSeg->Seg() );
		    		bool isParallel = refSeg->Seg().ApproxParallel( s->Seg() );
                    SEG p_clip, n_clip;

                    bool isCoupled = commonParallelProjection( refSeg->Seg(), s->Seg(), p_clip, n_clip );

                    if( isParallel && isCoupled && dist < minDist )
                    {
                        minDist = dist;
                        coupledSeg = s;
                    }
                }
            }
        }
    }
    else
    {
        return false;
    }

    if( !coupledSeg )
        return false;

    PNS_LINE lp = m_world->AssembleLine( refSeg );
    PNS_LINE ln = m_world->AssembleLine( coupledSeg );

    if( DpNetPolarity( refNet ) < 0 )
    {
        std::swap( lp, ln );
    }

    int gap = -1;

    if( refSeg->Seg().ApproxParallel( coupledSeg->Seg() ) )
    {
        // Segments are parallel -> compute pair gap
        const VECTOR2I refDir       = refSeg->Anchor( 1 ) - refSeg->Anchor( 0 );
        const VECTOR2I displacement = refSeg->Anchor( 1 ) - coupledSeg->Anchor( 1 );
        gap = (int) std::abs( refDir.Cross( displacement ) / refDir.EuclideanNorm() ) - lp.Width();
    }

    aPair = PNS_DIFF_PAIR( lp, ln );
    aPair.SetWidth( lp.Width() );
    aPair.SetLayers( lp.Layers() );
    aPair.SetGap( gap );

    return true;
}
bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
{
    m_fitOk = false;

    PNS_DP_GATEWAYS gwsEntry( gap() );
    PNS_DP_GATEWAYS gwsTarget( gap() );

    if( !m_prevPair )
        m_prevPair = m_start;

    gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );

    PNS_DP_PRIMITIVE_PAIR target;

    if( findDpPrimitivePair( aP, m_currentEndItem, target ) )
    {
        gwsTarget.BuildFromPrimitivePair( target, m_startDiagonal );
        m_snapOnTarget = true;
    }
    else
    {
        VECTOR2I fp;

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

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

    m_currentTrace = PNS_DIFF_PAIR();
    m_currentTrace.SetGap( gap() );
    m_currentTrace.SetLayer( m_currentLayer );

    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() );
        m_currentTrace.SetGap( m_sizes.DiffPairGap() );

        if( m_placingVia )
        {
            m_currentTrace.AppendVias ( makeVia( m_currentTrace.CP().CPoint( -1 ), m_netP ),
                                        makeVia( m_currentTrace.CN().CPoint( -1 ), m_netN ) );
        }

        return true;
    }

    return false;
}