50 virtual bool Run()
override;
52 virtual const wxString
GetName()
const override {
return wxT(
"length" ); };
61 const std::vector<CONNECTION>& aMatchedConnections );
63 const std::vector<CONNECTION>& aMatchedConnections );
65 const std::vector<CONNECTION>& aMatchedConnections );
73 const std::vector<CONNECTION>& aMatchedConnections )
77 bool minViolation =
false;
78 bool maxViolation =
false;
83 const EDA_DATA_TYPE dataType = isTimeDomain ? EDA_DATA_TYPE::TIME : EDA_DATA_TYPE::DISTANCE;
112 if( ( minViolation || maxViolation ) )
121 msg =
formatMsg(
_(
"(%s min length %s; actual %s)" ),
129 msg =
formatMsg(
_(
"(%s min length %s; actual %s)" ),
136 else if( maxViolation )
140 msg =
formatMsg(
_(
"(%s max length %s; actual %s)" ),
148 msg =
formatMsg(
_(
"(%s max length %s; actual %s)" ),
156 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS(
" " ) + msg );
158 for(
auto offendingTrack : ent.items )
159 drcItem->AddItem( offendingTrack );
163 reportViolation( drcItem, ( *ent.items.begin() )->GetPosition(), ( *ent.items.begin() )->GetLayer() );
169 const std::vector<CONNECTION>& aMatchedConnections )
171 auto checkSkewsImpl = [
this, &aConstraint](
const std::vector<CONNECTION>& connections )
174 const EDA_DATA_TYPE dataType = isTimeDomain ? EDA_DATA_TYPE::TIME : EDA_DATA_TYPE::DISTANCE;
176 double maxLength = 0;
183 if( ent.total > maxLength )
185 maxLength = ent.total;
186 maxNetname = ent.netname;
194 if( ent.totalDelay > maxLength )
196 maxLength = ent.totalDelay;
197 maxNetname = ent.netname;
204 int skew = isTimeDomain ?
KiROUND( ent.totalDelay - maxLength )
205 :
KiROUND( ent.total - maxLength );
207 bool fail_min =
false;
208 bool fail_max =
false;
215 if( fail_min || fail_max )
220 double reportTotal = isTimeDomain ? ent.totalDelay : ent.total;
224 msg.Printf(
_(
"(%s min skew %s; actual %s; target net length %s (from %s); "
235 msg.Printf(
_(
"(%s max skew %s; actual %s; target net length %s (from %s); "
245 drcItem->SetErrorMessage( drcItem->GetErrorText() +
" " + msg );
248 drcItem->SetItems( offendingTrack );
252 reportViolation( drcItem, ( *ent.items.begin() )->GetPosition(), ( *ent.items.begin() )->GetLayer() );
260 std::map<int, CONNECTION> netcodeMap;
263 netcodeMap[ent.netcode] = ent;
265 std::vector<std::vector<CONNECTION>> matchedDiffPairs;
267 for(
auto& [netcode, connection] : netcodeMap )
273 int matchedNetcode = matchedNet->
GetNetCode();
275 if( netcodeMap.count( matchedNetcode ) )
277 std::vector<CONNECTION> pair{ connection, netcodeMap[matchedNetcode] };
278 matchedDiffPairs.emplace_back( std::move( pair ) );
279 netcodeMap.erase( matchedNetcode );
285 for(
const std::vector<CONNECTION>& matchedDiffPair : matchedDiffPairs )
286 checkSkewsImpl( matchedDiffPair );
291 checkSkewsImpl( aMatchedConnections );
297 const std::vector<CONNECTION>& aMatchedConnections )
299 for(
const auto& ent : aMatchedConnections )
301 std::shared_ptr<DRC_ITEM> drcItem =
nullptr;
306 wxString msg = wxString::Format(
_(
"(%s max count %d; actual %d)" ),
311 drcItem->SetErrorMessage(
_(
"Too many vias on a connection" ) + wxS(
" " ) + msg );
316 wxString msg = wxString::Format(
_(
"(%s min count %d; actual %d)" ),
321 drcItem->SetErrorMessage(
_(
"Too few vias on a connection" ) + wxS(
" " ) + msg );
327 drcItem->SetItems( offendingTrack );
331 reportViolation( drcItem, ( *ent.items.begin() )->GetPosition(), ( *ent.items.begin() )->GetLayer() );
348 if( !aDelayReportMode )
350 if( !
reportPhase(
_(
"Gathering length-constrained connections..." ) ) )
355 std::map<DRC_RULE*, std::set<BOARD_CONNECTED_ITEM*> > itemSets;
361 const size_t progressDelta = 100;
395 std::map< DRC_RULE*, std::vector<CONNECTION> > matches;
397 for(
const auto& [rule, ruleItems] : itemSets )
399 std::map<int, std::set<BOARD_CONNECTED_ITEM*> > netMap;
402 netMap[item->GetNetCode()].insert( item );
404 for(
const auto& [netCode, netItems] : netMap )
406 std::vector<LENGTH_DELAY_CALCULATION_ITEM> lengthItems;
407 lengthItems.reserve( netItems.size() );
410 ent.
items = netItems;
426 if( lengthItem.
Type() != LENGTH_DELAY_CALCULATION_ITEM::TYPE::UNKNOWN )
427 lengthItems.emplace_back( lengthItem );
431 .
OptimiseViaLayers =
true, .MergeTracks =
true, .OptimiseTracesInPads =
true, .InferViaInPad =
false
433 LENGTH_DELAY_STATS details = calc->CalculateLengthDetails( lengthItems, opts,
nullptr,
nullptr,
434 LENGTH_DELAY_LAYER_OPT::NO_LAYER_DETAIL,
435 LENGTH_DELAY_DOMAIN_OPT::WITH_DELAY_DETAIL );
450 ent.
from = ftPath->fromName;
451 ent.
to = ftPath->toName;
455 ent.
from = ent.
to =
_(
"<unconstrained>" );
459 matches[rule].push_back( ent );
463 if( !aDelayReportMode )
465 if( !
reportPhase(
_(
"Checking length constraints..." ) ) )
469 count = matches.size();
471 for( std::pair<
DRC_RULE*
const, std::vector<CONNECTION> > it : matches )
474 auto& matchedConnections = it.second;
479 std::sort( matchedConnections.begin(), matchedConnections.end(),
482 return a.netname < b.netname;
487 REPORT_AUX( wxString::Format( wxT(
"Length-constrained traces for rule '%s':" ),
488 it.first->m_Name ) );
492 REPORT_AUX( wxString::Format( wxT(
" - net: %s, from: %s, to: %s, %d matching items, "
493 "total: %s (tracks: %s, vias: %s, pad-to-die: %s), "
497 static_cast<int>( ent.items.size() ),
514 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_DELAY_CALCULATION * GetLengthCalculation() const
Returns the track length calculator.
int GetCopperLayerCount() 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
void checkSkews(const DRC_CONSTRAINT &aConstraint, const std::vector< CONNECTION > &aMatchedConnections)
virtual ~DRC_TEST_PROVIDER_MATCHED_LENGTH()=default
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...
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)
REPORTER * getLogReporter() const
wxString formatMsg(const wxString &aFormatString, const wxString &aSource, double aConstraint, double aActual, EDA_DATA_TYPE aDataType=EDA_DATA_TYPE::DISTANCE)
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.
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
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
EDA_DATA_TYPE
The type of unit.
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
int64_t totalPadToDieDelay
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)