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;
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 )
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;
357 std::shared_ptr<FROM_TO_CACHE> ftCache =
m_board->GetConnectivity()->GetFromToCache();
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,
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 MINOPTMAX< int > & GetValue() const
bool GetOption(OPTIONS option) const
DRC_RULE * GetParentRule() const
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
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()
DRC_LENGTH_REPORT::ENTRY CONNECTION
void checkLengths(const DRC_CONSTRAINT &aConstraint, const std::vector< CONNECTION > &aMatchedConnections)
virtual bool reportPhase(const wxString &aStageName)
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, const LSET &aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
REPORTER * getLogReporter() const
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, const std::vector< PCB_SHAPE > &aShapes={})
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.
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.
@ 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)