KiCad PCB EDA Suite
Loading...
Searching...
No Matches
diff_phase_skew_tool.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * @author James Jackson
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#ifndef DIFF_PHASE_SKEW_TOOL_H
27#define DIFF_PHASE_SKEW_TOOL_H
28
31
32#include <router/pns_itemset.h>
34#include <router/pns_solid.h>
35
36#include <drc/drc_engine.h>
37#include <tools/pcb_tool_base.h>
38
39#include <vector>
40
41class TOOL_EVENT;
42class BOARD;
44
45namespace PNS
46{
47class ROUTER;
48}
49
50class PNS_KICAD_IFACE;
51
52
58{
61
64
67
70
72 size_t segA;
73
75 size_t segB;
76
79 double ta0, ta1, tb0, tb1;
80
82 double startLenA;
83
85 double endLenA;
86
88 double startLenB;
89
91 double endLenB;
92
95
97 double endDelayA;
98
101
103 double endDelayB;
104
106 double overlapFractionA() const { return std::abs( ta1 - ta0 ); }
107
109 double overlapFractionB() const { return std::abs( tb1 - tb0 ); }
110
114 std::pair<double, double> pathLengthDelta() const { return { startLenB - startLenA, endLenB - endLenA }; }
115
119 std::pair<double, double> pathDelayDelta() const { return { startDelayB - startDelayA, endDelayB - endDelayA }; }
120};
121
122
128{
131
134
137};
138
139
141constexpr double EPS = 1e-9;
142
143
149{
150public:
151 explicit KnownValueInterpolator( const std::vector<KNOWN_RELATIVE_POINT>& pts ) :
152 m_pts( pts )
153 {
154 }
155
156 std::optional<std::pair<double, double>> ValueAt( const double s )
157 {
158 if( m_pts.empty() )
159 return std::nullopt;
160
161 // Unknown before first known point
162 if( s < m_pts.front().LinearDistance - EPS )
163 return std::nullopt;
164
165 // Unknown after last known point
166 if( s > m_pts.back().LinearDistance + EPS )
167 return std::nullopt;
168
169 // Find known value point window
170 while( ( m_idx + 1 ) < m_pts.size() && s > m_pts[m_idx + 1].LinearDistance + EPS )
171 {
172 ++m_idx;
173 }
174
175 // Exact last point
176 if( m_idx + 1 >= m_pts.size() )
177 {
178 const auto& p = m_pts.back();
179 return std::pair{ p.RelativeLength, p.RelativeDelay };
180 }
181
182 // Interpolate between known points
183 const auto& a = m_pts[m_idx];
184 const auto& b = m_pts[m_idx + 1];
185
186 const double len = b.LinearDistance - a.LinearDistance;
187
188 // Degenerate interval
189 if( len <= EPS )
190 {
191 return std::pair{ a.RelativeLength, a.RelativeDelay };
192 }
193
194 const double t = ( s - a.LinearDistance ) / len;
195 const double relativeLength = a.RelativeLength + t * ( b.RelativeLength - a.RelativeLength );
196 const double relativeDelay = a.RelativeDelay + t * ( b.RelativeDelay - a.RelativeDelay );
197
198 return std::pair{ relativeLength, relativeDelay };
199 }
200
201private:
202 const std::vector<KNOWN_RELATIVE_POINT>& m_pts;
203 std::size_t m_idx{ 0 };
204};
205
206
211{
212public:
215
217 bool Init() override;
218
220 void Reset( RESET_REASON aReason ) override;
221
223 enum class MODE
224 {
225 // Initial hover state to identify diff pair / first track
227
228 // First track was selected and wasn't a diff pair
230
231 // Both tracks selected
233 };
234
236 MODE GetMode() const { return m_mode; }
237
239 void SetMode( const MODE aMode ) { m_mode = aMode; }
240
242 int ShowDiffPhaseSkew( const TOOL_EVENT& aEvent );
243
254
255protected:
257 void setTransitions() override;
258
260 void updateNetHighlights( bool aRefresh = true ) const;
261
263 void doInitialHover( const PCB_SELECTION_TOOL* aSelectionTool, GENERAL_COLLECTORS_GUIDE aGuide );
264
266 void doDisplayOverlay();
267
269 void getNetPaths();
270
272 static void normalisePathItems( const PNS::ITEM_SET& aPath, const PNS::SOLID* aStartPad );
273
276
279 static void reversePath( PNS::ITEM_SET& aPath, PNS::SOLID** aStartPad, PNS::SOLID** aEndPad );
280
283 bool reportValidityErrors( DIFF_PAIR_VALIDITY aDirection ) const;
284
287 {
288 int64_t m_Length{ 0 };
289 int64_t m_Delay{ 0 };
290 LENGTH_DELAY_CALCULATION_ITEM::TYPE m_SourceType{ LENGTH_DELAY_CALCULATION_ITEM::TYPE::UNKNOWN };
291 };
292
294 void buildLengthDelayItems( const PNS::ITEM_SET& aPath, const PNS::SOLID* aStartPad, const PNS::SOLID* aEndPad,
295 const NETINFO_ITEM* aNet, std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems,
296 LENGTH_DELAY_ITEM_DETAILS& aItemDetails ) const;
297
300 {
301 int64_t StartPadLength{ 0 };
302 int64_t EndPadLength{ 0 };
303 int64_t StartPadDelay{ 0 };
304 int64_t EndPadDelay{ 0 };
305 };
306
310 static std::vector<CUMULATIVE_ENTRY>
311 buildCumulativeLengthsAndDelays( const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems,
312 const LENGTH_DELAY_ITEM_DETAILS& aLengthDelayDetails, const PNS::SOLID* aStartPad,
313 const PNS::SOLID* aEndPad, START_END_DETAILS& aStartEndDetails );
314
316 static void splitLengthItems( std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems );
317
319 std::vector<PARALLEL_RUN> findParallelRuns( const std::vector<CUMULATIVE_ENTRY>& aSelectedCumulative,
320 const std::vector<CUMULATIVE_ENTRY>& aCoupledCumulative ) const;
321
324 void findParallelRunsImpl( const std::vector<CUMULATIVE_ENTRY>& aSelectedCumulative,
325 const std::vector<CUMULATIVE_ENTRY>& aCoupledCumulative,
326 std::pair<std::size_t, std::size_t> aRangeA, std::pair<std::size_t, std::size_t> aRangeB,
327 double aMaxSpacing, std::vector<PARALLEL_RUN>& aRuns ) const;
328
330 static VECTOR2D lerp( const VECTOR2D aA, const VECTOR2D aB, const double aT )
331 {
332 return { aA.x + ( aB.x - aA.x ) * aT, aA.y + ( aB.y - aA.y ) * aT };
333 }
334
336 static std::pair<int64_t, int64_t>
338 const START_END_DETAILS& aPadDetails,
339 const std::vector<CUMULATIVE_ENTRY>& aCumulative, std::size_t aSegIdx, double aT );
340
342 int getMaxDiffPairGap( const BOARD_CONNECTED_ITEM* aItem ) const;
343
365
367 std::vector<OUTPUT_SEGMENT> buildDiffOverlaySegments( const std::vector<CUMULATIVE_ENTRY>& aSegments,
368 const LENGTH_DELAY_ITEM_DETAILS& aSourceItemDetails,
369 const std::vector<PARALLEL_RUN>& aKnownRuns,
370 double aTargetSubsegmentSize, bool isCoupledTrack );
371
373 std::vector<KNOWN_RELATIVE_POINT> buildKnownRelativePoints( const std::vector<CUMULATIVE_ENTRY>& aSegments,
374 const LENGTH_DELAY_ITEM_DETAILS& aSourceItemDetails,
375 const std::vector<PARALLEL_RUN>& aKnownRuns,
376 bool isCoupledTrack ) const;
377
379 static std::vector<double> buildSplitPositions( const std::vector<CUMULATIVE_ENTRY>& aSegments,
380 double aTargetSubsegmentSize );
381
384 static std::pair<VECTOR2D, std::size_t>
385 pointAtDistance( const std::vector<CUMULATIVE_ENTRY>& aSegments,
386 const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aSourceItemDetails, double aDist );
387
390 COLOR4D interpolateColours( const COLOR4D& aColour1, const COLOR4D& aColour2, double aS, bool aUseLogScale ) const;
391
393 void drawDiffOverlay() const;
394
396 void doShowStatsAtCursor();
397
399 std::pair<std::size_t, bool> getNearestDiffSegments( const VECTOR2D& aCursorPos, double aHitTestDistance ) const;
400
402 void getOverlay();
403
405 void updateOverlay() const;
406
408 void clearOverlay() const;
409
411 void resetStateVariables();
412
414 void updateMessagePanel() const;
415
416private:
417 KIGFX::VIEW* m_view{ nullptr };
418 std::shared_ptr<KIGFX::VIEW_OVERLAY> m_viewOverlay{ nullptr };
420 BOARD* m_board{ nullptr };
422 std::shared_ptr<DRC_ENGINE> m_drcEngine{ nullptr };
424 bool m_inDiffPhaseSkewTool{ false }; // Re-entrancy guard
426
427 // Data for the candidate track selection
431 int m_netcodeP{ 0 };
432 int m_netcodeN{ 0 };
435 bool m_timeDomain{ false };
436
437 // Router for path extraction
440 PNS::SIZES_SETTINGS m_savedSizes; // Stores sizes settings between router invocations
441
442 // Extracted diff net paths
449
450 // Extracted diff net start / end pads
455
456 // Length and delay items from extracted paths
457 std::vector<LENGTH_DELAY_CALCULATION_ITEM> m_selectedLengthDelayItems;
458 std::vector<LENGTH_DELAY_CALCULATION_ITEM> m_coupledLengthDelayItems;
461
462 // Length and delay details for start and end pads
465
466 // The final calculated path diffs
467 std::vector<OUTPUT_SEGMENT> m_selectedDiffs;
468 std::vector<OUTPUT_SEGMENT> m_coupledDiffs;
469
470 // Flags for interactive display of diff values
471 std::optional<int> m_maxSkew;
472 std::pair<std::size_t, bool> m_segmentForStatisticsDisplay{ std::numeric_limits<std::size_t>::max(), false };
473
474 // Configuration parameters. These are taken from the advanced config to ensure we can
475 // tweak them during initial user usage.
477 double m_trackGapInflation{ 1.2 };
480 double m_targetDiffSegmentSize{ 50000.0 };
481};
482
483#endif /* DIFF_PHASE_SKEW_TOOL_H */
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
std::vector< OUTPUT_SEGMENT > buildDiffOverlaySegments(const std::vector< CUMULATIVE_ENTRY > &aSegments, const LENGTH_DELAY_ITEM_DETAILS &aSourceItemDetails, const std::vector< PARALLEL_RUN > &aKnownRuns, double aTargetSubsegmentSize, bool isCoupledTrack)
Builds a vector of known relative points for the given track and identified parallel segments.
void SetMode(const MODE aMode)
The tool entry point.
void setTransitions() override
< Set up handlers for tool events
std::vector< KNOWN_RELATIVE_POINT > buildKnownRelativePoints(const std::vector< CUMULATIVE_ENTRY > &aSegments, const LENGTH_DELAY_ITEM_DETAILS &aSourceItemDetails, const std::vector< PARALLEL_RUN > &aKnownRuns, bool isCoupledTrack) const
Determines where to apply overlay segment subsections on the source segments.
std::vector< PARALLEL_RUN > findParallelRuns(const std::vector< CUMULATIVE_ENTRY > &aSelectedCumulative, const std::vector< CUMULATIVE_ENTRY > &aCoupledCumulative) const
Finds all parallel segment runs in the selected and coupled tracks within the given segment ranges an...
DIFF_PAIR_VALIDITY determinePathDirections()
Reverses the direction of the selected and coupled paths (including swapping start / end pads.
bool reportValidityErrors(DIFF_PAIR_VALIDITY aDirection) const
Struct to represent one cumulative length and delay point.
START_END_DETAILS m_coupledStartEndDetails
LENGTH_DELAY_ITEM_DETAILS m_coupledLengthDelayDetails
static void reversePath(PNS::ITEM_SET &aPath, PNS::SOLID **aStartPad, PNS::SOLID **aEndPad)
Report to the user any errors after determining the signal direction.
static VECTOR2D lerp(const VECTOR2D aA, const VECTOR2D aB, const double aT)
Gets the cumulative length and delay at the given fractional coordinate in the given segment.
std::pair< std::size_t, bool > m_segmentForStatisticsDisplay
static void normalisePathItems(const PNS::ITEM_SET &aPath, const PNS::SOLID *aStartPad)
Determine which end of the extracted paths we are defining as the signal start point.
int getMaxDiffPairGap(const BOARD_CONNECTED_ITEM *aItem) const
Struct containing a final computed output diff segment.
static std::vector< double > buildSplitPositions(const std::vector< CUMULATIVE_ENTRY > &aSegments, double aTargetSubsegmentSize)
Returns the coordinate at the given linear distance along the line, along with the segment index the ...
MODE GetMode() const
Set the current mode of the tool.
void clearOverlay() const
Resets all select-specific variables.
std::vector< LENGTH_DELAY_CALCULATION_ITEM > m_selectedLengthDelayItems
void doDisplayOverlay()
Use the router to get the +ve and -ve paths from the selected item.
bool Init() override
Init() is called once upon a registration of the tool.
void getNetPaths()
Normalises the path to ensure SHAPE_LINE_CHAIN points are in overall path walk order.
BOARD_CONNECTED_ITEM * m_pickerItemFirst
KIGFX::VIEW_CONTROLS * m_controls
static void splitLengthItems(std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aItems)
Finds all parallel segment runs in the selected and coupled tracks.
std::vector< OUTPUT_SEGMENT > m_selectedDiffs
void buildLengthDelayItems(const PNS::ITEM_SET &aPath, const PNS::SOLID *aStartPad, const PNS::SOLID *aEndPad, const NETINFO_ITEM *aNet, std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aItems, LENGTH_DELAY_ITEM_DETAILS &aItemDetails) const
Start and end pad lengths and delays (pad-to-die + infered via-in-pad)
void doInitialHover(const PCB_SELECTION_TOOL *aSelectionTool, GENERAL_COLLECTORS_GUIDE aGuide)
Display the phase overlay for the current hover item.
PCB_BASE_EDIT_FRAME * m_frame
int ShowDiffPhaseSkew(const TOOL_EVENT &aEvent)
Flags for the analysis state of the selected tracks.
void doShowStatsAtCursor()
Determines the nearest points to the cursor from the diff segments.
void findParallelRunsImpl(const std::vector< CUMULATIVE_ENTRY > &aSelectedCumulative, const std::vector< CUMULATIVE_ENTRY > &aCoupledCumulative, std::pair< std::size_t, std::size_t > aRangeA, std::pair< std::size_t, std::size_t > aRangeB, double aMaxSpacing, std::vector< PARALLEL_RUN > &aRuns) const
Linear interpolate from point A to B at line fraction T.
std::vector< OUTPUT_SEGMENT > m_coupledDiffs
COLOR4D interpolateColours(const COLOR4D &aColour1, const COLOR4D &aColour2, double aS, bool aUseLogScale) const
Draws the visual skew overlay.
static std::vector< CUMULATIVE_ENTRY > buildCumulativeLengthsAndDelays(const std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aItems, const LENGTH_DELAY_ITEM_DETAILS &aLengthDelayDetails, const PNS::SOLID *aStartPad, const PNS::SOLID *aEndPad, START_END_DETAILS &aStartEndDetails)
Splits the calculation items from compound segments in to individual items.
std::pair< std::size_t, bool > getNearestDiffSegments(const VECTOR2D &aCursorPos, double aHitTestDistance) const
Ensures we have an active VIEW_OVERLAY to display the diff graphics.
static std::pair< int64_t, int64_t > getCumulativeLengthAndDelayAt(const LENGTH_DELAY_ITEM_DETAILS &aLengthDelayDetails, const START_END_DETAILS &aPadDetails, const std::vector< CUMULATIVE_ENTRY > &aCumulative, std::size_t aSegIdx, double aT)
Gets the maximum diff pair gap for the given item, taken from DRC rules.
static std::pair< VECTOR2D, std::size_t > pointAtDistance(const std::vector< CUMULATIVE_ENTRY > &aSegments, const std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aSourceItemDetails, double aDist)
Linearly interpolates between colour1 and colour2, with interpolation point given by aS [0-1].
void updateOverlay() const
Clears the VIEW_OVERLAY.
std::optional< int > m_maxSkew
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_viewOverlay
PNS::SIZES_SETTINGS m_savedSizes
void getOverlay()
Refreshes the VIEW_OVERLAY in the active VIEW.
BOARD_CONNECTED_ITEM * m_pickerItemSecond
void updateNetHighlights(bool aRefresh=true) const
Handle hover events before a DP pair is selected.
void resetStateVariables()
Updates the message panel.
LENGTH_DELAY_ITEM_DETAILS m_selectedLengthDelayDetails
START_END_DETAILS m_selectedStartEndDetails
std::vector< LENGTH_DELAY_CALCULATION_ITEM > m_coupledLengthDelayItems
void drawDiffOverlay() const
Shows the diff stats nearest the cursor.
std::shared_ptr< DRC_ENGINE > m_drcEngine
A general implementation of a COLLECTORS_GUIDE.
Definition collectors.h:324
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:105
An interface for classes handling user events controlling the view behavior such as zooming,...
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:67
KnownValueInterpolator(const std::vector< KNOWN_RELATIVE_POINT > &pts)
const std::vector< KNOWN_RELATIVE_POINT > & m_pts
std::optional< std::pair< double, double > > ValueAt(const double s)
TYPE
The type of routing object this item proxies.
Handle the data for a net.
Definition netinfo.h:50
Common, abstract interface for edit frames.
The selection tool: currently supports:
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:78
Generic, UI-independent tool event.
Definition tool_event.h:171
constexpr double EPS
Floating point comparison epsilon.
void Reset() override
Push and Shove diff pair dimensions (gap) settings dialog.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
Builds the length / delay calculation items from a given path.
int64_t m_Length
int64_t m_Delay
LENGTH_DELAY_CALCULATION_ITEM::TYPE m_SourceType
Builds the final overlay output segments for plotting.
VECTOR2D Start
The start point of the segment.
VECTOR2D End
The end point of the segment.
bool RelativeValueKnown
Flag whether the diff value is valid at this segment.
double RelativeValueAtMid
The value of the diff at the beginning of this segment.
Builds a vector in which each entry represents the cumulative length and delay at the start of a give...
Represents a point on a track where the length and delay relative to the coupled track can be calcula...
double RelativeLength
The length relative to the coupled track.
double LinearDistance
The distance (in IU) along the track.
double RelativeDelay
The propagation delay relative to the coupled track.
Used to represent the results of a call to CalculateLengthDetails, including inferred via-in-pad deta...
Struct to represent one segment where tracks run parallel, including information about absolute and r...
std::pair< double, double > pathLengthDelta() const
Calculates the {start, end} track length delta relative to the selected track.
VECTOR2I endA
The ending coordinate of the run on track A.
double endDelayA
Cumulative delay of track A at the start of the parallel run.
double startLenA
Cumulative length of track A at the start of the parallel run.
size_t segB
The index of the parallel segment on track B.
VECTOR2I startA
The starting coordinate of the run on track A.
VECTOR2I startB
The starting coordinate of the run on track B.
double ta0
Normalised values of the start (0) and end (1) coordinates on track A and B These are normalised to t...
double startDelayA
Cumulative delay of track A at the start of the parallel run.
double startLenB
Cumulative length of track B at the start of the parallel run.
double endLenA
Cumulative length of track A at the end of the parallel run.
double endDelayB
Cumulative delay of track A at the start of the parallel run.
double startDelayB
Cumulative delay of track A at the start of the parallel run.
double endLenB
Cumulative length of track B at the end of the parallel run.
double overlapFractionB() const
Calculate the fraction of track B that overlaps track A.
size_t segA
The index of the parallel segment on track A.
VECTOR2I endB
The ending coordinate of the run on track B.
std::pair< double, double > pathDelayDelta() const
Calculates the {start, end} track delay delta relative to the selected track.
double overlapFractionA() const
Calculate the fraction of track A that overlaps track B.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687
VECTOR2< double > VECTOR2D
Definition vector2d.h:686