Handle DP checks for board minimum rules

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13640
This commit is contained in:
Jon Evans 2023-01-23 17:45:16 -05:00
parent 442ee52905
commit 12b0a12d74
1 changed files with 42 additions and 26 deletions

View File

@ -140,13 +140,20 @@ struct DIFF_PAIR_KEY
return true;
else if( netN > b.netN )
return false;
else if( gapRuleName.IsEmpty() )
return gapRuleName < b.gapRuleName;
else
return parentRule < b.parentRule;
return uncoupledRuleName < b.uncoupledRuleName;
}
}
int netP, netN;
DRC_RULE* parentRule;
wxString gapRuleName;
wxString uncoupledRuleName;
std::optional<MINOPTMAX<int>> gapConstraint;
DRC_RULE* gapRule;
std::optional<MINOPTMAX<int>> uncoupledConstraint;
DRC_RULE* uncoupledRule;
};
struct DIFF_PAIR_COUPLED_SEGMENTS
@ -304,7 +311,26 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
drc_dbg( 10, wxT( "cns %d item %p\n" ), constraintsToCheck[i], item );
key.parentRule = constraint.GetParentRule();
DRC_RULE* parentRule = constraint.GetParentRule();
wxString ruleName = parentRule ? parentRule->m_Name : constraint.GetName();
switch( constraintsToCheck[i] )
{
case DIFF_PAIR_GAP_CONSTRAINT:
key.gapConstraint = constraint.GetValue();
key.gapRule = parentRule;
key.gapRuleName = ruleName;
break;
case DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT:
key.uncoupledConstraint = constraint.GetValue();
key.uncoupledRule = parentRule;
key.uncoupledRuleName = ruleName;
break;
default:
break;
}
if( refNet->GetNetCode() == key.netN )
dpRuleMatches[key].itemsN.insert( citem );
@ -337,9 +363,7 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
wxString nameN = niN->GetNetname();
reportAux( wxString::Format( wxT( "Rule '%s', DP: (+) %s - (-) %s" ),
key.parentRule->m_Name,
nameP,
nameN ) );
key.gapRuleName, nameP, nameN ) );
extractDiffPairCoupledItems( itemSet );
@ -349,12 +373,6 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
drc_dbg(10, wxT( " coupled prims : %d\n" ), (int) itemSet.coupled.size() );
std::optional<DRC_CONSTRAINT> gapConstraint
= key.parentRule->FindConstraint( DIFF_PAIR_GAP_CONSTRAINT );
std::optional<DRC_CONSTRAINT> maxUncoupledConstraint
= key.parentRule->FindConstraint( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT );
for( BOARD_CONNECTED_ITEM* item : itemSet.itemsN )
{
// fixme: include vias
@ -397,14 +415,12 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
gap,
dp.parentP->GetLayer() );
if( gapConstraint )
if( key.gapConstraint )
{
const MINOPTMAX<int>& val = gapConstraint->GetValue();
if( val.HasMin() && gap < val.Min() - epsilon )
if( key.gapConstraint->HasMin() && gap < key.gapConstraint->Min() - epsilon )
dp.couplingFailMin = true;
if( val.HasMax() && gap > val.Max() + epsilon )
if( key.gapConstraint->HasMax() && gap > key.gapConstraint->Max() + epsilon )
dp.couplingFailMax = true;
}
@ -421,15 +437,15 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
bool uncoupledViolation = false;
if( maxUncoupledConstraint && ( !itemSet.itemsP.empty() || !itemSet.itemsN.empty() ) )
if( key.uncoupledConstraint && ( !itemSet.itemsP.empty() || !itemSet.itemsN.empty() ) )
{
const MINOPTMAX<int>& val = maxUncoupledConstraint->GetValue();
const MINOPTMAX<int>& val = *key.uncoupledConstraint;
if ( val.HasMax() && totalUncoupled > val.Max() )
{
auto drce = DRC_ITEM::Create( DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG );
wxString msg = formatMsg( _( "(%s maximum uncoupled length %s; actual %s)" ),
maxUncoupledConstraint->GetParentRule()->m_Name,
key.uncoupledRuleName,
val.Max(),
totalUncoupled );
@ -461,33 +477,33 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
uncoupledViolation = true;
drce->SetViolatingRule( maxUncoupledConstraint->GetParentRule() );
drce->SetViolatingRule( key.uncoupledRule );
reportViolation( drce, item->GetPosition(), item->GetLayer() );
}
}
if( gapConstraint && ( uncoupledViolation || !maxUncoupledConstraint ) )
if( key.gapConstraint && ( uncoupledViolation || !key.uncoupledConstraint ) )
{
for( DIFF_PAIR_COUPLED_SEGMENTS& dp : itemSet.coupled )
{
if( ( dp.couplingFailMin || dp.couplingFailMax ) && ( dp.parentP || dp.parentN ) )
{
MINOPTMAX<int> val = gapConstraint->GetValue();
MINOPTMAX<int> val = *key.gapConstraint;
auto drcItem = DRC_ITEM::Create( DRCE_DIFF_PAIR_GAP_OUT_OF_RANGE );
wxString msg;
if( dp.couplingFailMin )
{
msg = formatMsg( _( "(%s minimum gap %s; actual %s)" ),
gapConstraint->GetParentRule()->m_Name,
key.gapRuleName,
val.Min(),
dp.computedGap );
}
else if( dp.couplingFailMax )
{
msg = formatMsg( _( "(%s maximum gap %s; actual %s)" ),
gapConstraint->GetParentRule()->m_Name,
key.gapRuleName,
val.Max(),
dp.computedGap );
}
@ -508,7 +524,7 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
drcItem->AddItem( dp.parentN );
}
drcItem->SetViolatingRule( gapConstraint->GetParentRule() );
drcItem->SetViolatingRule( key.gapRule );
reportViolation( drcItem, item->GetPosition(), item->GetLayer() );
}