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 auto checkSkewsImpl = [
this, &aConstraint](
const std::vector<CONNECTION>& connections )
145 double maxLength = 0;
150 if( ent.total > maxLength )
152 maxLength = ent.total;
153 maxNetname = ent.netname;
157 for(
const auto& ent : connections )
159 int skew =
KiROUND( ent.total - maxLength );
160 bool fail_min =
false;
161 bool fail_max =
false;
168 if( fail_min || fail_max )
175 msg.Printf(
_(
"(%s min skew %s; actual %s; target net length %s (from %s); "
184 msg.Printf(
_(
"(%s max skew %s; actual %s; target net length %s (from %s); "
192 drcItem->SetErrorMessage( drcItem->GetErrorText() +
" " + msg );
195 drcItem->SetItems( offendingTrack );
200 ( *ent.items.begin() )->GetLayer() );
208 std::map<int, CONNECTION> netcodeMap;
211 netcodeMap[ent.netcode] = ent;
213 std::vector<std::vector<CONNECTION>> matchedDiffPairs;
215 for(
auto& [netcode, connection] : netcodeMap )
221 int matchedNetcode = matchedNet->
GetNetCode();
223 if( netcodeMap.count( matchedNetcode ) )
225 std::vector<CONNECTION> pair{ connection, netcodeMap[matchedNetcode] };
226 matchedDiffPairs.emplace_back( std::move( pair ) );
227 netcodeMap.erase( matchedNetcode );
233 for(
const std::vector<CONNECTION>& matchedDiffPair : matchedDiffPairs )
234 checkSkewsImpl( matchedDiffPair );
239 checkSkewsImpl( aMatchedConnections );
245 const std::vector<CONNECTION>& aMatchedConnections )
247 for(
const auto& ent : aMatchedConnections )
249 std::shared_ptr<DRC_ITEM> drcItem =
nullptr;
254 wxString msg = wxString::Format(
_(
"(%s max count %d; actual %d)" ),
259 drcItem->SetErrorMessage(
_(
"Too many vias on a connection" ) + wxS(
" " ) + msg );
264 wxString msg = wxString::Format(
_(
"(%s min count %d; actual %d)" ),
269 drcItem->SetErrorMessage(
_(
"Too few vias on a connection" ) + wxS(
" " ) + msg );
274 for(
auto offendingTrack : ent.items )
275 drcItem->SetItems( offendingTrack );
280 ( *ent.items.begin() )->GetLayer() );
297 if( !aDelayReportMode )
299 if( !
reportPhase(
_(
"Gathering length-constrained connections..." ) ) )
303 std::map<DRC_RULE*, std::set<BOARD_CONNECTED_ITEM*> > itemSets;
309 const size_t progressDelta = 100;
332 for(
int i = 0; i < 3; i++ )
337 if( constraint.IsNull() )
342 itemSets[ constraint.GetParentRule() ].insert( citem );
348 std::map< DRC_RULE*, std::vector<CONNECTION> > matches;
350 for(
const std::pair<
DRC_RULE*
const, std::set<BOARD_CONNECTED_ITEM*> >& it : itemSets )
352 std::map<int, std::set<BOARD_CONNECTED_ITEM*> > netMap;
355 netMap[ citem->
GetNetCode() ].insert( citem );
357 for(
const std::pair<
const int, std::set<BOARD_CONNECTED_ITEM*> >& nitem : netMap )
360 ent.
items = nitem.second;
411 auto ftPath = ftCache->QueryFromToPath( ent.
items );
415 ent.
from = ftPath->fromName;
416 ent.
to = ftPath->toName;
420 ent.
from = ent.
to =
_(
"<unconstrained>" );
424 matches[ it.first ].push_back(ent);
428 if( !aDelayReportMode )
430 if( !
reportPhase(
_(
"Checking length constraints..." ) ) )
434 count = matches.size();
436 for( std::pair<
DRC_RULE*
const, std::vector<CONNECTION> > it : matches )
439 auto& matchedConnections = it.second;
444 std::sort( matchedConnections.begin(), matchedConnections.end(),
447 return a.netname < b.netname;
450 reportAux( wxString::Format( wxT(
"Length-constrained traces for rule '%s':" ),
451 it.first->m_Name ) );
455 reportAux(wxString::Format( wxT(
" - net: %s, from: %s, to: %s, "
456 "%d matching items, "
457 "total: %s (tracks: %s, vias: %s, pad-to-die: %s), "
462 (
int) ent.items.size(),
479 checkSkews( *skewConstraint, matchedConnections );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
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
NETINFO_ITEM * DpCoupledNet(const NETINFO_ITEM *aNet)
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
bool GetOption(OPTIONS option) 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.
Handle the data for a net.
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)