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 );
350 std::map< DRC_RULE*, std::vector<CONNECTION> > matches;
352 for(
const auto& [rule, ruleItems] : itemSets )
354 std::map<int, std::set<BOARD_CONNECTED_ITEM*> > netMap;
357 netMap[item->GetNetCode()].insert( item );
359 for(
const auto& [netCode, netItems] : netMap )
361 std::vector<LENGTH_CALCULATION_ITEM> lengthItems;
362 lengthItems.reserve( netItems.size() );
365 ent.
items = netItems;
381 if( lengthItem.
Type() != LENGTH_CALCULATION_ITEM::TYPE::UNKNOWN )
382 lengthItems.emplace_back( lengthItem );
386 .
OptimiseViaLayers =
true, .MergeTracks =
true, .OptimiseTracesInPads =
true, .InferViaInPad =
false
388 LENGTH_DETAILS details = calc->CalculateLengthDetails( lengthItems, opts );
397 auto ftPath = ftCache->QueryFromToPath( ent.
items );
401 ent.
from = ftPath->fromName;
402 ent.
to = ftPath->toName;
406 ent.
from = ent.
to =
_(
"<unconstrained>" );
410 matches[rule].push_back( ent );
414 if( !aDelayReportMode )
416 if( !
reportPhase(
_(
"Checking length constraints..." ) ) )
420 count = matches.size();
422 for( std::pair<
DRC_RULE*
const, std::vector<CONNECTION> > it : matches )
425 auto& matchedConnections = it.second;
430 std::sort( matchedConnections.begin(), matchedConnections.end(),
433 return a.netname < b.netname;
436 reportAux( wxString::Format( wxT(
"Length-constrained traces for rule '%s':" ),
437 it.first->m_Name ) );
441 reportAux( wxString::Format( wxT(
" - net: %s, from: %s, to: %s, "
442 "%d matching items, "
443 "total: %s (tracks: %s, vias: %s, pad-to-die: %s), "
445 ent.netname, ent.from, ent.to,
static_cast<int>( ent.items.size() ),
460 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,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
const NETINFO_LIST & GetNetInfo() const
NETINFO_ITEM * DpCoupledNet(const NETINFO_ITEM *aNet)
LENGTH_CALCULATION * GetLengthCalculation() const
Returns the track length calculator.
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)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, DRC_CUSTOM_MARKER_HANDLER *aCustomHandler=nullptr)
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, const LSET &aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
void reportAux(const wxString &aMsg)
virtual void reportRuleStatistics()
virtual bool reportProgress(size_t aCount, size_t aSize, size_t aDelta=1)
Lightweight class which holds a pad, via, or a routed trace outline.
TYPE Type() const
Gets the routing item type.
Class which calculates lengths (and associated routing statistics) in a BOARD context.
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
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
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
Holds length measurement result details and statistics.
Struct to control which optimisations the length calculation code runs on the given path objects.
bool OptimiseViaLayers
Optimise via layers for height calculations, ensuring only the distance between routed segments is co...
@ 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)