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, see <https://www.gnu.org/licenses/>.
20 */
21
22#ifndef DIFF_PHASE_SKEW_TOOL_H
23#define DIFF_PHASE_SKEW_TOOL_H
24
27
28#include <router/pns_itemset.h>
30#include <router/pns_solid.h>
31
32#include <drc/drc_engine.h>
33#include <tools/pcb_tool_base.h>
34
35#include <optional>
36#include <vector>
37
38class TOOL_EVENT;
39class BOARD;
41
42namespace PNS
43{
44class ROUTER;
45}
46
47class PNS_KICAD_IFACE;
48
49
55{
58
61
64
67
69 size_t segA;
70
72 size_t segB;
73
76 double ta0, ta1, tb0, tb1;
77
79 double startLenA;
80
82 double endLenA;
83
85 double startLenB;
86
88 double endLenB;
89
92
94 double endDelayA;
95
98
100 double endDelayB;
101
102 std::optional<double> startViaLengthA;
103 std::optional<double> endViaLengthA;
104 std::optional<double> startViaLengthB;
105 std::optional<double> endViaLengthB;
106 std::optional<double> startViaDelayA;
107 std::optional<double> endViaDelayA;
108 std::optional<double> startViaDelayB;
109 std::optional<double> endViaDelayB;
110
112 double overlapFractionA() const { return std::abs( ta1 - ta0 ); }
113
115 double overlapFractionB() const { return std::abs( tb1 - tb0 ); }
116
120 std::pair<double, double> pathLengthDelta() const { return { startLenB - startLenA, endLenB - endLenA }; }
121
125 std::pair<double, double> pathDelayDelta() const { return { startDelayB - startDelayA, endDelayB - endDelayA }; }
126};
127
128
150
151
153constexpr double EPS = 1e-9;
154
155
161{
162public:
163 explicit KnownValueInterpolator( const std::vector<KNOWN_RELATIVE_POINT>& pts ) :
164 m_pts( pts )
165 {
166 }
167
168 std::optional<std::pair<double, double>> ValueAt( const double s )
169 {
170 if( m_pts.empty() )
171 return std::nullopt;
172
173 // Unknown before first known point
174 if( s < m_pts.front().LinearDistance - EPS )
175 return std::nullopt;
176
177 // Unknown after last known point
178 if( s > m_pts.back().LinearDistance + EPS )
179 return std::nullopt;
180
181 // Find known value point window
182 while( ( m_idx + 1 ) < m_pts.size() && s > m_pts[m_idx + 1].LinearDistance + EPS )
183 {
184 ++m_idx;
185 }
186
187 // Exact last point
188 if( m_idx + 1 >= m_pts.size() )
189 {
190 const auto& p = m_pts.back();
191 return std::pair{ p.RelativeLengthBefore, p.RelativeDelayBefore };
192 }
193
194 // Interpolate between known points
195 const auto& a = m_pts[m_idx];
196 const auto& b = m_pts[m_idx + 1];
197
198 const double len = b.LinearDistance - a.LinearDistance;
199
200 // Degenerate interval
201 if( len <= EPS )
202 {
203 return std::pair{ a.RelativeLengthBefore, a.RelativeDelayBefore };
204 }
205
206 const double t = ( s - a.LinearDistance ) / len;
207 const double relativeLength = a.RelativeLengthAfter + t * ( b.RelativeLengthBefore - a.RelativeLengthAfter );
208 const double relativeDelay = a.RelativeDelayAfter + t * ( b.RelativeDelayBefore - a.RelativeDelayAfter );
209
210 return std::pair{ relativeLength, relativeDelay };
211 }
212
213private:
214 const std::vector<KNOWN_RELATIVE_POINT>& m_pts;
215 std::size_t m_idx{ 0 };
216};
217
218
223{
224public:
227
229 bool Init() override;
230
232 void Reset( RESET_REASON aReason ) override;
233
235 enum class MODE
236 {
237 // Initial hover state to identify diff pair / first track
239
240 // First track was selected and wasn't a diff pair
242
243 // Both tracks selected
245 };
246
248 MODE GetMode() const { return m_mode; }
249
251 void SetMode( const MODE aMode ) { m_mode = aMode; }
252
254 int ShowDiffPhaseSkew( const TOOL_EVENT& aEvent );
255
266
267protected:
269 void setTransitions() override;
270
272 void updateNetHighlights( bool aRefresh = true ) const;
273
275 void doInitialHover( const PCB_SELECTION_TOOL* aSelectionTool, GENERAL_COLLECTORS_GUIDE aGuide );
276
278 void doDisplayOverlay();
279
281 void getNetPaths();
282
284 static void normalisePathItems( const PNS::ITEM_SET& aPath, const PNS::SOLID* aStartPad );
285
288
291 static void reversePath( PNS::ITEM_SET& aPath, PNS::SOLID** aStartPad, PNS::SOLID** aEndPad );
292
295 bool reportValidityErrors( DIFF_PAIR_VALIDITY aDirection ) const;
296
299 {
300 int64_t m_Length{ 0 };
301 int64_t m_Delay{ 0 };
302 LENGTH_DELAY_CALCULATION_ITEM::TYPE m_SourceType{ LENGTH_DELAY_CALCULATION_ITEM::TYPE::UNKNOWN };
305 };
306
308 void buildLengthDelayItems( const PNS::ITEM_SET& aPath, const PNS::SOLID* aStartPad, const PNS::SOLID* aEndPad,
309 const NETINFO_ITEM* aNet, std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems,
310 LENGTH_DELAY_ITEM_DETAILS& aItemDetails ) const;
311
314 {
315 int64_t StartPadLength{ 0 };
316 int64_t EndPadLength{ 0 };
317 int64_t StartPadDelay{ 0 };
318 int64_t EndPadDelay{ 0 };
319 };
320
324 static std::vector<CUMULATIVE_ENTRY>
325 buildCumulativeLengthsAndDelays( const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems,
326 const LENGTH_DELAY_ITEM_DETAILS& aLengthDelayDetails, const PNS::SOLID* aStartPad,
327 const PNS::SOLID* aEndPad, START_END_DETAILS& aStartEndDetails );
328
330 static void splitLengthItems( std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems );
331
333 std::vector<PARALLEL_RUN> findParallelRuns() const;
334
337 void findParallelRunsImpl( std::pair<std::size_t, std::size_t> aRangeA, std::pair<std::size_t, std::size_t> aRangeB,
338 double aMaxSpacing, std::vector<PARALLEL_RUN>& aRuns ) const;
339
341 static VECTOR2D lerp( const VECTOR2D aA, const VECTOR2D aB, const double aT )
342 {
343 return { aA.x + ( aB.x - aA.x ) * aT, aA.y + ( aB.y - aA.y ) * aT };
344 }
345
347 static std::pair<int64_t, int64_t>
349 const START_END_DETAILS& aPadDetails,
350 const std::vector<CUMULATIVE_ENTRY>& aCumulative, std::size_t aSegIdx, double aT );
351
353 int getMaxDiffPairGap( const BOARD_CONNECTED_ITEM* aItem ) const;
354
376
378 void buildDiffOverlaySegments( double aTargetSubsegmentSize );
379
380 std::vector<OUTPUT_SEGMENT>
381 buildDiffOverlaySegmentsImpl( const std::vector<CUMULATIVE_ENTRY>& aSegments,
382 const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aSourceItemDetails,
383 const std::vector<KNOWN_RELATIVE_POINT>& aKnownPoints, double aTargetSubsegmentSize );
384
386 void buildKnownRelativePoints( const std::vector<PARALLEL_RUN>& aKnownRuns );
387
389 static std::vector<double> buildSplitPositions( const std::vector<CUMULATIVE_ENTRY>& aSegments,
390 double aTargetSubsegmentSize );
391
394 static std::pair<VECTOR2D, std::size_t>
395 pointAtDistance( const std::vector<CUMULATIVE_ENTRY>& aSegments,
396 const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aSourceItemDetails, double aDist );
397
400 COLOR4D interpolateColours( const COLOR4D& aColour1, const COLOR4D& aColour2, double aS, bool aUseLogScale ) const;
401
403 void drawDiffOverlay() const;
404
406 void doShowStatsAtCursor();
407
409 std::pair<std::size_t, bool> getNearestDiffSegments( const VECTOR2D& aCursorPos, double aHitTestDistance ) const;
410
412 void getOverlay();
413
415 void updateOverlay() const;
416
418 void clearOverlay() const;
419
421 void resetStateVariables();
422
424 void updateMessagePanel() const;
425
426private:
427 KIGFX::VIEW* m_view{ nullptr };
428 std::shared_ptr<KIGFX::VIEW_OVERLAY> m_viewOverlay{ nullptr };
430 BOARD* m_board{ nullptr };
432 std::shared_ptr<DRC_ENGINE> m_drcEngine{ nullptr };
434 bool m_inDiffPhaseSkewTool{ false }; // Re-entrancy guard
436
437 // Data for the candidate track selection
441 int m_netcodeP{ 0 };
442 int m_netcodeN{ 0 };
445 bool m_timeDomain{ false };
446
447 // Router for path extraction
450 PNS::SIZES_SETTINGS m_savedSizes; // Stores sizes settings between router invocations
451
452 // Extracted diff net paths
459
460 // Extracted diff net start / end pads
465
466 // Length and delay items from extracted paths
467 std::vector<LENGTH_DELAY_CALCULATION_ITEM> m_selectedLengthDelayItems;
468 std::vector<LENGTH_DELAY_CALCULATION_ITEM> m_coupledLengthDelayItems;
471
472 // Length and delay details for start and end pads
475
476 // Cumulative length and delay details for each track
477 std::vector<CUMULATIVE_ENTRY> m_selectedCumulative;
478 std::vector<CUMULATIVE_ENTRY> m_coupledCumulative;
479
480 // The known relative delay points for each track
481 std::vector<KNOWN_RELATIVE_POINT> m_selectedKnownPoints;
482 std::vector<KNOWN_RELATIVE_POINT> m_coupledKnownPoints;
483
484 // The final calculated path diffs
485 std::vector<OUTPUT_SEGMENT> m_selectedDiffs;
486 std::vector<OUTPUT_SEGMENT> m_coupledDiffs;
487
488 // Flags for interactive display of diff values
489 std::optional<int> m_maxSkew;
490 std::pair<std::size_t, bool> m_segmentForStatisticsDisplay{ std::numeric_limits<std::size_t>::max(), false };
491
492 // Configuration parameters. These are taken from the advanced config to ensure we can
493 // tweak them during initial user usage.
495 double m_trackGapInflation{ 1.2 };
498 double m_targetDiffSegmentSize{ 50000.0 };
499};
500
501#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:372
void SetMode(const MODE aMode)
The tool entry point.
void setTransitions() override
< Set up handlers for tool events
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< KNOWN_RELATIVE_POINT > m_selectedKnownPoints
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.
std::vector< CUMULATIVE_ENTRY > m_selectedCumulative
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 + inferred 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.
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.
void findParallelRunsImpl(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::pair< std::size_t, bool > getNearestDiffSegments(const VECTOR2D &aCursorPos, double aHitTestDistance) const
Ensures we have an active VIEW_OVERLAY to display the diff graphics.
std::vector< OUTPUT_SEGMENT > buildDiffOverlaySegmentsImpl(const std::vector< CUMULATIVE_ENTRY > &aSegments, const std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aSourceItemDetails, const std::vector< KNOWN_RELATIVE_POINT > &aKnownPoints, double aTargetSubsegmentSize)
Builds a vector of known relative skew points on each track.
std::vector< KNOWN_RELATIVE_POINT > m_coupledKnownPoints
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.
void buildDiffOverlaySegments(double aTargetSubsegmentSize)
std::optional< int > m_maxSkew
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_viewOverlay
void buildKnownRelativePoints(const std::vector< PARALLEL_RUN > &aKnownRuns)
Determines where to apply overlay segment subsections on the source segments.
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.
std::vector< PARALLEL_RUN > findParallelRuns() const
Finds all parallel segment runs in the selected and coupled tracks within the given segment ranges an...
LENGTH_DELAY_ITEM_DETAILS m_selectedLengthDelayDetails
START_END_DETAILS m_selectedStartEndDetails
std::vector< LENGTH_DELAY_CALCULATION_ITEM > m_coupledLengthDelayItems
std::vector< CUMULATIVE_ENTRY > m_coupledCumulative
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:320
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
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:63
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:46
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:74
Generic, UI-independent tool event.
Definition tool_event.h:167
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
VECTOR2I m_Start
int64_t m_Delay
VECTOR2I m_End
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 RelativeLengthAfter
The length relative to the coupled track.
double RelativeDelayAfter
The propagation delay relative to the coupled track.
double RelativeLengthBefore
The length relative to the coupled track.
double LinearDistance
The distance (in IU) along the track.
double RelativeDelayBefore
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.
std::optional< double > startViaLengthB
std::optional< double > endViaDelayA
std::optional< double > startViaLengthA
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.
std::optional< double > startViaDelayB
std::optional< double > startViaDelayA
VECTOR2I startB
The starting coordinate of the run on track B.
std::optional< double > endViaDelayB
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.
std::optional< double > endViaLengthA
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.
std::optional< double > endViaLengthB
double overlapFractionA() const
Calculate the fraction of track A that overlaps track B.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682