diff --git a/pcbnew/dialogs/panel_setup_rules_help.md b/pcbnew/dialogs/panel_setup_rules_help.md index cf75729ab4..01756aa1ba 100644 --- a/pcbnew/dialogs/panel_setup_rules_help.md +++ b/pcbnew/dialogs/panel_setup_rules_help.md @@ -119,7 +119,12 @@ True if `A` has a net that is part of a differential pair. A.inDiffPair('') True if `A` has net that is part of the specified differential pair. `` is the base name of the differential pair. For example, `inDiffPair('CLK')` -matches items in the `CLK_P` and `CLK_N` nets.
+matches items in the `CLK_P` and `CLK_N` nets. +

+ + A.isCoupledDiffPair() +True if `A` and `B` are members of the same diff pair. +

A.memberOf('') True if `A` is a member of the given group. Includes nested membership. diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index 4811f7a3df..b2c60be9e0 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -295,9 +295,7 @@ void DRC_ENGINE::loadImplicitRules() ncName ); netclassRule->m_Implicit = true; - expr = wxString::Format( "A.NetClass == '%s' && A.isDiffPair() " - "&& B.NetClass == '%s' && B.isDiffPair()", - ncName, + expr = wxString::Format( "A.NetClass == '%s' && A.isCoupledDiffPair()", ncName ); netclassRule->m_Condition = new DRC_RULE_CONDITION( expr ); netclassItemSpecificRules.push_back( netclassRule ); diff --git a/pcbnew/pcb_expr_evaluator.cpp b/pcbnew/pcb_expr_evaluator.cpp index 8608b5b904..fecb65202b 100644 --- a/pcbnew/pcb_expr_evaluator.cpp +++ b/pcbnew/pcb_expr_evaluator.cpp @@ -728,6 +728,30 @@ static void isDiffPair( LIBEVAL::CONTEXT* aCtx, void* self ) } +static void isCoupledDiffPair( LIBEVAL::CONTEXT* aCtx, void* self ) +{ + PCB_EXPR_CONTEXT* context = static_cast( aCtx ); + BOARD_CONNECTED_ITEM* a = dynamic_cast( context->GetItem( 0 ) ); + BOARD_CONNECTED_ITEM* b = dynamic_cast( context->GetItem( 1 ) ); + LIBEVAL::VALUE* result = aCtx->AllocValue(); + + result->Set( 0.0 ); + aCtx->Push( result ); + + if( a && b ) + { + NETINFO_ITEM* netinfo = a->GetNet(); + wxString coupledNet, dummy; + + if( netinfo && DRC_ENGINE::MatchDpSuffix( netinfo->GetNetname(), coupledNet, dummy ) != 0 ) + { + if( b->GetNetname() == coupledNet ) + result->Set( 1.0 ); + } + } +} + + static void inDiffPair( LIBEVAL::CONTEXT* aCtx, void* self ) { LIBEVAL::VALUE* arg = aCtx->Pop(); @@ -783,6 +807,7 @@ void PCB_EXPR_BUILTIN_FUNCTIONS::RegisterAllFunctions() RegisterFunc( "memberOf('x')", memberOf ); RegisterFunc( "fromTo('x','y')", exprFromTo ); RegisterFunc( "isDiffPair()", isDiffPair ); + RegisterFunc( "isCoupledDiffPair()", isCoupledDiffPair ); RegisterFunc( "inDiffPair('x')", inDiffPair ); }