65 virtual bool Run()
override;
67 virtual const wxString
GetName()
const override 69 return wxT(
"diff_pair_coupling" );
74 return wxT(
"Tests differential pair coupling" );
97 int64_t t_b = p.
TCoef( p.
B );
99 int64_t tproj_a = p.
TCoef( n_proj_p.A );
100 int64_t tproj_b = p.
TCoef( n_proj_p.B );
103 std::swap( t_b, t_a );
105 if( tproj_b < tproj_a )
106 std::swap( tproj_b, tproj_a );
114 int64_t t[4] = { 0, p.
TCoef( p.
B ), p.
TCoef( n_proj_p.A ), p.
TCoef( n_proj_p.B ) };
115 std::vector<int64_t> tv( t, t + 4 );
116 std::sort( tv.begin(), tv.end() );
121 pClip.
A.
x = p.
A.
x +
rescale( (int64_t)dp.
x, tv[1], pLenSq );
122 pClip.
A.
y = p.
A.
y +
rescale( (int64_t)dp.
y, tv[1], pLenSq );
124 pClip.
B.
x = p.
A.
x +
rescale( (int64_t)dp.
x, tv[2], pLenSq );
125 pClip.
B.
y = p.
A.
y +
rescale( (int64_t)dp.
y, tv[2], pLenSq );
183 std::vector<DIFF_PAIR_COUPLED_SEGMENTS>
coupled;
193 PCB_TRACK* sp = dyn_cast<PCB_TRACK*>( itemP );
195 int bestGap = std::numeric_limits<int>::max();
202 PCB_TRACK* sn = dyn_cast<PCB_TRACK*> ( itemN );
215 if( ssp.SquaredLength() > 2 && ssn.SquaredLength() > 2 && ssp.ApproxParallel(ssn) )
242 if( aItem == bestCoupled->parentN || aItem == bestCoupled->parentP )
249 auto bci = static_cast<BOARD_CONNECTED_ITEM*>( aItem );
251 if( bci->GetNetCode() == bestCoupled->parentN->GetNetCode()
252 || bci->GetNetCode() == bestCoupled->parentP->GetNetCode() )
259 SHAPE_SEGMENT checkSegStart( bestCoupled->coupledP.A, bestCoupled->coupledN.A );
260 SHAPE_SEGMENT checkSegEnd( bestCoupled->coupledP.B, bestCoupled->coupledN.B );
268 aDp.
coupled.push_back( *bestCoupled );
282 std::map<DIFF_PAIR_KEY, DIFF_PAIR_ITEMS> dpRuleMatches;
284 auto evaluateDpConstraints =
293 drc_dbg( 10, wxT(
"eval dp %p\n" ), item );
300 for(
int i = 0; i < 2; i++ )
303 nullptr, item->GetLayer() );
305 if( constraint.IsNull() )
308 drc_dbg( 10, wxT(
"cns %d item %p\n" ), constraintsToCheck[i], item );
313 dpRuleMatches[key].itemsN.insert( citem );
315 dpRuleMatches[key].itemsP.insert( citem );
327 drc_dbg( 10, wxT(
"dp rule matches %d\n" ), (
int) dpRuleMatches.size() );
338 copperTree.
Insert( item, layer );
350 for(
auto& it : dpRuleMatches )
362 it.first.parentRule->m_Name,
368 it.second.totalCoupled = 0;
369 it.second.totalLengthN = 0;
370 it.second.totalLengthP = 0;
372 drc_dbg(10, wxT(
" coupled prims : %d\n" ), (
int) it.second.coupled.size() );
382 if(
PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) )
383 it.second.totalLengthN += track->GetLength();
389 if(
PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) )
390 it.second.totalLengthP += track->GetLength();
393 for(
auto& cpair : it.second.coupled )
395 int length = cpair.coupledN.Length();
396 int gap = cpair.coupledN.Distance( cpair.coupledP );
398 gap -= cpair.parentN->GetWidth() / 2;
399 gap -= cpair.parentP->GetWidth() / 2;
401 cpair.computedGap = gap;
410 overlay->SetLineWidth( 100000 );
411 overlay->Line( cpair.coupledP );
413 overlay->Line( cpair.coupledN );
416 drc_dbg( 10, wxT(
" len %d gap %d l %d\n" ),
419 cpair.parentP->GetLayer() );
423 auto val = gapConstraint->GetValue();
424 bool insideRange =
true;
426 if( val.HasMin() && gap < val.Min() )
429 if( val.HasMax() && gap > val.Max() )
435 cpair.couplingOK = insideRange;
439 cpair.couplingOK =
true;
442 if( cpair.couplingOK )
443 it.second.totalCoupled += length;
446 int totalLen = std::max( it.second.totalLengthN, it.second.totalLengthP );
451 int totalUncoupled = totalLen - it.second.totalCoupled;
453 bool uncoupledViolation =
false;
455 if( maxUncoupledConstraint )
457 auto val = maxUncoupledConstraint->GetValue();
459 if ( val.HasMax() && totalUncoupled > val.Max() )
464 maxUncoupledConstraint->GetParentRule()->m_Name,
468 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) +
m_msg );
470 auto pit = it.second.itemsP.begin();
471 auto nit = it.second.itemsN.begin();
473 drce->AddItem( *pit );
474 drce->AddItem( *nit );
476 for( pit++; pit != it.second.itemsP.end(); pit++ )
477 drce->AddItem( *pit );
479 for( nit++; nit != it.second.itemsN.end(); nit++ )
480 drce->AddItem( *nit );
482 uncoupledViolation =
true;
484 drce->SetViolatingRule( maxUncoupledConstraint->GetParentRule() );
490 if ( gapConstraint && ( uncoupledViolation || !maxUncoupledConstraint ) )
492 for(
auto& cpair : it.second.coupled )
494 if( !cpair.couplingOK )
496 auto val = gapConstraint->GetValue();
499 m_msg = drcItem->GetErrorText() + wxT(
" (" ) +
500 gapConstraint->GetParentRule()->m_Name + wxS(
" " );
513 drcItem->SetErrorMessage(
m_msg );
515 drcItem->AddItem( cpair.parentP );
516 drcItem->AddItem( cpair.parentN );
518 drcItem->SetViolatingRule( gapConstraint->GetParentRule() );
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
static bool commonParallelProjection(SEG p, SEG n, SEG &pClip, SEG &nClip)
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
virtual std::set< DRC_CONSTRAINT_T > GetConstraintTypes() const override
std::shared_ptr< PNS_LOG_VIEWER_OVERLAY > overlay
std::shared_ptr< KIGFX::VIEW_OVERLAY > GetDebugOverlay() const
const wxPoint & GetEnd() const
std::set< BOARD_CONNECTED_ITEM * > itemsN
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
ecoord SquaredLength() const
DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING()
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const wxPoint &aMarkerPos)
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
static bool IsNetADiffPair(BOARD *aBoard, NETINFO_ITEM *aNet, int &aNetP, int &aNetN)
std::set< BOARD_CONNECTED_ITEM * > itemsP
bool operator<(const DIFF_PAIR_KEY &b) const
class PCB_ARC, an arc track segment on a copper layer
const NETINFO_LIST & GetNetInfo() const
class PAD, a pad in a footprint
virtual ~DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING()
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual void reportRuleStatistics()
class PCB_TRACK, a track segment (segment on a copper layer)
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
virtual int GetNumPhases() const override
ecoord TCoef(const VECTOR2I &aP) const
bool CheckColliding(SHAPE *aRefShape, PCB_LAYER_ID aTargetLayer, int aClearance=0, std::function< bool(BOARD_ITEM *)> aFilter=nullptr) const
static void extractDiffPairCoupledItems(DIFF_PAIR_ITEMS &aDp, DRC_RTREE &aTree)
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
const wxString & GetNetname() const
virtual const wxString GetDescription() const override
class ZONE, a copper pour area
EDA_UNITS userUnits() const
std::vector< DIFF_PAIR_COUPLED_SEGMENTS > coupled
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, LSET aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out #DRC_ITEMs and po...
Handle the data for a net.
Information pertinent to a Pcbnew printed circuit board.
PCB_LAYER_ID
A quick note on layer IDs:
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
void Insert(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer, int aWorstClearance=0)
Insert an item into the tree on a particular layer with an optional worst clearance.
DIFF_PAIR_COUPLED_SEGMENTS()
class PCB_VIA, a via (like a track segment on a copper layer)
virtual const wxString GetName() const override
#define drc_dbg(level, fmt,...)
NETINFO_ITEM * GetNetItem(int aNetCode) const
Implement an R-tree for fast spatial and layer indexing of connectable items.
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual void reportAux(wxString fmt,...)
const wxPoint & GetStart() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.