56 virtual bool Run()
override;
58 virtual const wxString
GetName()
const override
60 return wxT(
"length" );
65 return wxT(
"Tests matched track lengths." );
75 const std::vector<CONNECTION>& aMatchedConnections );
77 const std::vector<CONNECTION>& aMatchedConnections );
79 const std::vector<CONNECTION>& aMatchedConnections );
87 const std::vector<CONNECTION>& aMatchedConnections )
91 bool minViolation =
false;
92 bool maxViolation =
false;
107 if( ( minViolation || maxViolation ) )
114 msg =
formatMsg(
_(
"(%s min length %s; actual %s)" ),
119 else if( maxViolation )
121 msg =
formatMsg(
_(
"(%s max length %s; actual %s)" ),
127 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS(
" " ) + msg );
129 for(
auto offendingTrack : ent.items )
130 drcItem->AddItem( offendingTrack );
135 ( *ent.items.begin() )->GetLayer() );
141 const std::vector<CONNECTION>& aMatchedConnections )
143 double avgLength = 0;
146 avgLength += ent.total;
148 avgLength /= (double) aMatchedConnections.size();
150 for(
const auto& ent : aMatchedConnections )
152 int skew =
KiROUND( ent.total - avgLength );
153 bool fail_min =
false;
154 bool fail_max =
false;
161 if( fail_min || fail_max )
168 msg.Printf(
_(
"(%s min skew %s; actual %s; average net length %s; actual %s)" ),
177 msg.Printf(
_(
"(%s max skew %s; actual %s; average net length %s; actual %s)" ),
185 drcItem->SetErrorMessage( drcItem->GetErrorText() +
" " + msg );
188 drcItem->SetItems( offendingTrack );
193 ( *ent.items.begin() )->GetLayer() );
200 const std::vector<CONNECTION>& aMatchedConnections )
202 for(
const auto& ent : aMatchedConnections )
204 std::shared_ptr<DRC_ITEM> drcItem =
nullptr;
209 wxString msg = wxString::Format(
_(
"(%s max count %d; actual %d)" ),
214 drcItem->SetErrorMessage(
_(
"Too many vias on a connection" ) + wxS(
" " ) + msg );
219 wxString msg = wxString::Format(
_(
"(%s min count %d; actual %d)" ),
224 drcItem->SetErrorMessage(
_(
"Too few vias on a connection" ) + wxS(
" " ) + msg );
229 for(
auto offendingTrack : ent.items )
230 drcItem->SetItems( offendingTrack );
235 ( *ent.items.begin() )->GetLayer() );
252 if( !aDelayReportMode )
254 if( !
reportPhase(
_(
"Gathering length-constrained connections..." ) ) )
258 std::map<DRC_RULE*, std::set<BOARD_CONNECTED_ITEM*> > itemSets;
264 const size_t progressDelta = 100;
287 for(
int i = 0; i < 3; i++ )
292 if( constraint.IsNull() )
297 itemSets[ constraint.GetParentRule() ].insert( citem );
303 std::map< DRC_RULE*, std::vector<CONNECTION> > matches;
305 for(
const std::pair<
DRC_RULE*
const, std::set<BOARD_CONNECTED_ITEM*> >& it : itemSets )
307 std::map<int, std::set<BOARD_CONNECTED_ITEM*> > netMap;
310 netMap[ citem->
GetNetCode() ].insert( citem );
312 for(
const std::pair<
const int, std::set<BOARD_CONNECTED_ITEM*> >& nitem : netMap )
315 ent.
items = nitem.second;
365 auto ftPath = ftCache->QueryFromToPath( ent.
items );
369 ent.
from = ftPath->fromName;
370 ent.
to = ftPath->toName;
374 ent.
from = ent.
to =
_(
"<unconstrained>" );
378 matches[ it.first ].push_back(ent);
382 if( !aDelayReportMode )
384 if( !
reportPhase(
_(
"Checking length constraints..." ) ) )
388 count = matches.size();
390 for( std::pair<
DRC_RULE*
const, std::vector<CONNECTION> > it : matches )
393 auto& matchedConnections = it.second;
398 std::sort( matchedConnections.begin(), matchedConnections.end(),
401 return a.netname < b.netname;
404 reportAux( wxString::Format( wxT(
"Length-constrained traces for rule '%s':" ),
405 it.first->m_Name ) );
409 reportAux(wxString::Format( wxT(
" - net: %s, from: %s, to: %s, "
410 "%d matching items, "
411 "total: %s (tracks: %s, vias: %s, pad-to-die: %s), "
416 (
int) ent.items.size(),
433 checkSkews( *skewConstraint, matchedConnections );
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Container for design settings for a BOARD object.
BOARD_STACKUP & GetStackupDescriptor()
bool m_UseHeightForLengthCalcs
Enable inclusion of stackup height in track length measurements and length tuning.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Manage layers needed to make a physical board.
int GetLayerDistance(PCB_LAYER_ID aFirstLayer, PCB_LAYER_ID aSecondLayer) const
Calculate the distance (height) between the two given copper layers.
Information pertinent to a Pcbnew printed circuit board.
const NETINFO_LIST & GetNetInfo() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
const MINOPTMAX< int > & GetValue() const
DRC_RULE * GetParentRule() const
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
void Add(const ENTRY &ent)
std::optional< DRC_CONSTRAINT > FindConstraint(DRC_CONSTRAINT_T aType)
bool runInternal(bool aDelayReportMode=false)
virtual const wxString GetName() const override
virtual ~DRC_TEST_PROVIDER_MATCHED_LENGTH()
void checkSkews(const DRC_CONSTRAINT &aConstraint, const std::vector< CONNECTION > &aMatchedConnections)
virtual const wxString GetDescription() const override
void checkViaCounts(const DRC_CONSTRAINT &aConstraint, const std::vector< CONNECTION > &aMatchedConnections)
DRC_LENGTH_REPORT m_report
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
DRC_TEST_PROVIDER_MATCHED_LENGTH()
void checkLengths(const DRC_CONSTRAINT &aConstraint, const std::vector< CONNECTION > &aMatchedConnections)
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out DRC_ITEM and posi...
wxString formatMsg(const wxString &aFormatString, const wxString &aSource, double aConstraint, double aActual)
virtual bool reportPhase(const wxString &aStageName)
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, LSET aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer)
void reportAux(const wxString &aMsg)
virtual void reportRuleStatistics()
virtual bool reportProgress(size_t aCount, size_t aSize, size_t aDelta=1)
KICAD_T Type() const
Returns the type of object.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
const wxString & GetNetname() const
NETINFO_ITEM * GetNetItem(int aNetCode) const
void GetOutermostConnectedLayers(PCB_LAYER_ID *aTopmost, PCB_LAYER_ID *aBottommost) const
Return the top-most and bottom-most connected layers.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
@ DRCE_LENGTH_OUT_OF_RANGE
@ DRCE_VIA_COUNT_OUT_OF_RANGE
PCB_LAYER_ID
A quick note on layer IDs:
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
BOARD_CONNECTED_ITEM * fromItem
BOARD_CONNECTED_ITEM * toItem
std::set< BOARD_CONNECTED_ITEM * > items
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".