KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pns_diff_pair.h
Go to the documentation of this file.
1/*
2 * KiRouter - a push-and-(sometimes-)shove PCB router
3 *
4 * Copyright (C) 2013-2015 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * Author: Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22
23#ifndef __PNS_DIFF_PAIR_H
24#define __PNS_DIFF_PAIR_H
25
26#include <vector>
27
28#include "pns_line.h"
29#include "pns_via.h"
30#include "pns_link_holder.h"
31
32#include "ranged_num.h"
33
34namespace PNS {
35
36class DIFF_PAIR;
37
44{
45public:
46 DP_GATEWAY( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN, bool aIsDiagonal,
47 int aAllowedEntryAngles = DIRECTION_45::ANG_OBTUSE, int aPriority = 0 ) :
48 m_anchorP( aAnchorP ),
49 m_anchorN( aAnchorN ), m_isDiagonal( aIsDiagonal ),
50 m_allowedEntryAngles( aAllowedEntryAngles ), m_priority( aPriority )
51 {
52 m_hasEntryLines = false;
53 }
54
56 {
57 }
58
62 bool IsDiagonal() const
63 {
64 return m_isDiagonal;
65 }
66
67 const VECTOR2I& AnchorP() const { return m_anchorP; }
68
69 const VECTOR2I& AnchorN() const { return m_anchorN; }
70
74 int AllowedAngles () const { return m_allowedEntryAngles; }
75
79 int Priority() const
80 {
81 return m_priority;
82 }
83
84 void SetPriority(int aPriority)
85 {
86 m_priority = aPriority;
87 }
88
89 void SetEntryLines( const SHAPE_LINE_CHAIN& aEntryP, const SHAPE_LINE_CHAIN& aEntryN )
90 {
91 m_entryP = aEntryP;
92 m_entryN = aEntryN;
93 m_hasEntryLines = true;
94 }
95
96 const SHAPE_LINE_CHAIN& EntryP() const { return m_entryP; }
97 const SHAPE_LINE_CHAIN& EntryN() const { return m_entryN; }
98 const DIFF_PAIR Entry() const ;
99
100 void Reverse();
101
102 bool HasEntryLines () const
103 {
104 return m_hasEntryLines;
105 }
106
107private:
114};
115
120{
121public:
123 m_primP( nullptr ), m_primN( nullptr ) {};
124
125 DP_PRIMITIVE_PAIR( const DP_PRIMITIVE_PAIR& aOther );
126 DP_PRIMITIVE_PAIR( ITEM* aPrimP, ITEM* aPrimN );
127 DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
128
130
131 void SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
132
133 const VECTOR2I& AnchorP() const { return m_anchorP; }
134 const VECTOR2I& AnchorN() const { return m_anchorN; }
135
137
138 ITEM* PrimP() const { return m_primP; }
139 ITEM* PrimN() const { return m_primN; }
140
141 bool Directional() const;
142
143 DIRECTION_45 DirP() const;
144 DIRECTION_45 DirN() const;
145
146
147 void CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint,
148 VECTOR2I& aDirection ) const;
149
150 void dump()
151 {
152 printf( "-- Prim-P %p anchor [%d, %d]\n", m_primP, m_anchorP.x, m_anchorP.y );
153 printf( "-- Prim-N %p anchor [%d, %d]\n", m_primN, m_anchorN.x, m_anchorN.y );
154 }
155
156private:
157 DIRECTION_45 anchorDirection( const ITEM* aItem, const VECTOR2I& aP ) const;
158
162};
163
168{
169public:
170 DP_GATEWAYS( int aGap ):
171 m_gap( aGap ),
172 m_viaGap( aGap )
173 {
174 // Do not leave uninitialized members, and keep static analyzer quiet:
175 m_viaDiameter = 0;
176 m_fitVias = true;
177 }
178
179 void Clear() { m_gateways.clear(); }
180
181 void SetFitVias( bool aEnable, int aDiameter = 0, int aViaGap = -1 )
182 {
183 m_fitVias = aEnable;
184 m_viaDiameter = aDiameter;
185
186 if( aViaGap < 0 )
187 m_viaGap = m_gap;
188 else
189 m_viaGap = aViaGap;
190 }
191
192
193 void BuildForCursor( const VECTOR2I& aCursorPos );
194 void BuildOrthoProjections( DP_GATEWAYS& aEntries, const VECTOR2I& aCursorPos,
195 int aOrthoScore );
196 void BuildGeneric( const VECTOR2I& p0_p, const VECTOR2I& p0_n, bool aBuildEntries = false,
197 bool aViaMode = false );
198 void BuildFromPrimitivePair( const DP_PRIMITIVE_PAIR& aPair, bool aPreferDiagonal );
199
200 bool FitGateways( DP_GATEWAYS& aEntry, DP_GATEWAYS& aTarget, bool aPrefDiagonal,
201 DIFF_PAIR& aDp );
202
203 std::vector<DP_GATEWAY>& Gateways() { return m_gateways; }
204
205 const std::vector<DP_GATEWAY>& CGateways() const { return m_gateways; }
206
207 void FilterByOrientation( int aAngleMask, DIRECTION_45 aRefOrientation );
208
209private:
216
217 bool checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I& b ) const;
218 void buildDpContinuation( const DP_PRIMITIVE_PAIR& aPair, bool aIsDiagonal );
219 void buildEntries( const VECTOR2I& p0_p, const VECTOR2I& p0_n );
220
221 int m_gap;
225
226 std::vector<DP_GATEWAY> m_gateways;
227};
228
229
234class DIFF_PAIR : public LINK_HOLDER
235{
236public:
238 {
239 COUPLED_SEGMENTS ( const SEG& aCoupledP, const SEG& aParentP, int aIndexP,
240 const SEG& aCoupledN, const SEG& aParentN, int aIndexN ) :
241 coupledP( aCoupledP ),
242 coupledN( aCoupledN ),
243 parentP( aParentP ),
244 parentN( aParentN ),
245 indexP( aIndexP ),
246 indexN( aIndexN )
247 {}
248
255 };
256
257 typedef std::vector<COUPLED_SEGMENTS> COUPLED_SEGMENTS_VEC;
258
261 m_hasVias( false )
262 {
263 // Initialize some members, to avoid uninitialized variables.
264 m_net_p = nullptr;
265 m_net_n = nullptr;
266 m_width = 0;
267 m_gap = 0;
268 m_viaGap = 0;
270 m_chamferLimit = 0;
271 }
272
273 DIFF_PAIR( int aGap ) :
275 m_hasVias( false )
276 {
277 m_gapConstraint = aGap;
278
279 // Initialize other members, to avoid uninitialized variables.
280 m_net_p = nullptr;
281 m_net_n = nullptr;
282 m_width = 0;
283 m_gap = 0;
284 m_viaGap = 0;
286 m_chamferLimit = 0;
287 }
288
289 DIFF_PAIR( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, int aGap = 0 ) :
291 m_n( aN ),
292 m_p( aP ),
293 m_hasVias( false )
294 {
295 m_gapConstraint = aGap;
296
297 // Initialize other members, to avoid uninitialized variables.
298 m_net_p = nullptr;
299 m_net_n = nullptr;
300 m_width = 0;
301 m_gap = 0;
302 m_viaGap = 0;
304 m_chamferLimit = 0;
305 }
306
307 DIFF_PAIR( const LINE &aLineP, const LINE &aLineN, int aGap = 0 ) :
309 m_line_p( aLineP ),
310 m_line_n( aLineN ),
311 m_hasVias( false )
312 {
313 m_gapConstraint = aGap;
314 m_net_p = aLineP.Net();
315 m_net_n = aLineN.Net();
316 m_p = aLineP.CLine();
317 m_n = aLineN.CLine();
318
319 // Do not leave uninitialized members, and keep static analyzer quiet:
320 m_width = 0;
321 m_gap = 0;
322 m_viaGap = 0;
324 m_chamferLimit = 0;
325 }
326
327 DIFF_PAIR( const DIFF_PAIR& aOther ) :
329 {
330 *this = aOther;
331 }
332
333 static inline bool ClassOf( const ITEM* aItem )
334 {
335 return aItem && ITEM::DIFF_PAIR_T == aItem->Kind();
336 }
337
338 DIFF_PAIR* Clone() const override
339 {
340 assert( false );
341 return nullptr;
342 }
343
344 // Copy operator
345 DIFF_PAIR& operator=( const DIFF_PAIR& aOther )
346 {
347 m_n = aOther.m_n;
348 m_p = aOther.m_p;
349 m_line_n = aOther.m_line_n;
350 m_line_p = aOther.m_line_p;
351 m_via_n = aOther.m_via_n;
352 m_via_p = aOther.m_via_p;
353
354 m_hasVias = aOther.m_hasVias;
355 m_net_n = aOther.m_net_n;
356 m_net_p = aOther.m_net_p;
357 m_width = aOther.m_width;
358 m_gap = aOther.m_gap;
359 m_viaGap = aOther.m_viaGap;
363 return *this;
364 }
365
366 // Move assignment operator
367 DIFF_PAIR& operator=( DIFF_PAIR&& aOther ) noexcept
368 {
369 if (this != &aOther)
370 {
371 m_n = std::move( aOther.m_n );
372 m_p = std::move( aOther.m_p );
373 m_line_n = std::move( aOther.m_line_n );
374 m_line_p = std::move( aOther.m_line_p );
375 m_via_n = aOther.m_via_n;
376 m_via_p = aOther.m_via_p;
377
378 m_hasVias = aOther.m_hasVias;
379 m_net_n = aOther.m_net_n;
380 m_net_p = aOther.m_net_p;
381 m_width = aOther.m_width;
382 m_gap = aOther.m_gap;
383 m_viaGap = aOther.m_viaGap;
384 m_maxUncoupledLength = aOther.m_maxUncoupledLength;
385 m_chamferLimit = aOther.m_chamferLimit;
386 m_gapConstraint = aOther.m_gapConstraint;
387 }
388
389 return *this;
390 }
391
392 virtual void ClearLinks() override
393 {
394 m_links.clear();
395 m_line_p.ClearLinks();
396 m_line_n.ClearLinks();
397 }
398
399 void SetShape( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, bool aSwapLanes = false )
400 {
401 if( aSwapLanes )
402 {
403 m_p = aN;
404 m_n = aP;
405 }
406 else
407 {
408 m_p = aP;
409 m_n = aN;
410 }
411 }
412
413 void SetShape( const DIFF_PAIR& aPair )
414 {
415 m_p = aPair.m_p;
416 m_n = aPair.m_n;
417 }
418
420 {
421 m_net_p = aP;
422 m_net_n = aN;
423 }
424
425 void SetWidth( int aWidth )
426 {
427 m_width = aWidth;
428 m_n.SetWidth( aWidth );
429 m_p.SetWidth( aWidth );
430 }
431
432 int Width() const { return m_width; }
433
434 void SetGap( int aGap )
435 {
436 m_gap = aGap;
437 m_gapConstraint = RANGED_NUM<int>( m_gap, 10000, 10000 );
438 }
439
440 int Gap() const
441 {
442 return m_gap;
443 }
444
445 void AppendVias( const VIA &aViaP, const VIA& aViaN )
446 {
447 m_hasVias = true;
448 m_via_p = aViaP;
449 m_via_p.SetHole( aViaP.Hole()->Clone() );
450 m_via_n = aViaN;
451 m_via_n.SetHole( aViaN.Hole()->Clone() );
452 }
453
455 {
456 m_hasVias = false;
457 m_line_n.RemoveVia();
458 m_line_p.RemoveVia();
459 }
460
461 bool EndsWithVias() const
462 {
463 return m_hasVias;
464 }
465
466 void SetViaDiameter( int aDiameter )
467 {
468 m_via_p.SetDiameter( VIA::ALL_LAYERS, aDiameter );
469 m_via_n.SetDiameter( VIA::ALL_LAYERS, aDiameter );
470 }
471
472 void SetViaDrill( int aDrill )
473 {
474 m_via_p.SetDrill( aDrill );
475 m_via_n.SetDrill( aDrill );
476 }
477
479 {
480 return m_net_p;
481 }
482
484 {
485 return m_net_n;
486 }
487
489 {
490 if( !m_line_p.IsLinked() )
492
493 return m_line_p;
494 }
495
497 {
498 if( !m_line_n.IsLinked() )
500
501 return m_line_n;
502 }
503
505
506 double CoupledLength() const;
507 double TotalLength() const;
508 double CoupledLengthFactor() const;
509 double Skew() const;
510
511 void CoupledSegmentPairs( COUPLED_SEGMENTS_VEC& aPairs ) const;
512
513 void Clear()
514 {
515 m_n.Clear();
516 m_p.Clear();
517 }
518
519 void Append( const DIFF_PAIR& aOther )
520 {
521 m_n.Append( aOther.m_n );
522 m_p.Append( aOther.m_p );
523 }
524
525 bool Empty() const
526 {
527 return ( m_n.SegmentCount() == 0 ) || ( m_p.SegmentCount() == 0 );
528 }
529
530 const SHAPE_LINE_CHAIN& CP() const { return m_p; }
531 const SHAPE_LINE_CHAIN& CN() const { return m_n; }
532
533 bool BuildInitial( const DP_GATEWAY& aEntry, const DP_GATEWAY& aTarget, bool aPrefDiagonal );
534 bool CheckConnectionAngle( const DIFF_PAIR &aOther, int allowedAngles ) const;
535 int CoupledLength( const SEG& aP, const SEG& aN ) const;
536
537 int64_t CoupledLength( const SHAPE_LINE_CHAIN& aP, const SHAPE_LINE_CHAIN& aN ) const;
538
540 {
541 return m_gapConstraint;
542 }
543
544private:
545 void updateLine( LINE &aLine, const SHAPE_LINE_CHAIN& aShape, NET_HANDLE aNet, const VIA& aVia )
546 {
547 aLine.SetShape( aShape );
548 aLine.SetWidth( m_width );
549 aLine.SetNet( aNet );
550 aLine.SetLayer( Layers().Start() );
551 aLine.SetParent( m_parent );
553
554 if( m_hasVias )
555 aLine.AppendVia( aVia );
556 }
557
561
565 int m_gap;
570};
571
572}
573
574#endif
Represent route directions & corner angles in a 45-degree metric.
Definition direction45.h:37
Basic class for a differential pair.
bool CheckConnectionAngle(const DIFF_PAIR &aOther, int allowedAngles) const
void AppendVias(const VIA &aViaP, const VIA &aViaN)
SHAPE_LINE_CHAIN m_p
const SHAPE_LINE_CHAIN & CN() const
DP_PRIMITIVE_PAIR EndingPrimitives()
int Width() const
std::vector< COUPLED_SEGMENTS > COUPLED_SEGMENTS_VEC
NET_HANDLE m_net_p
const RANGED_NUM< int > GapConstraint() const
double CoupledLength() const
bool BuildInitial(const DP_GATEWAY &aEntry, const DP_GATEWAY &aTarget, bool aPrefDiagonal)
void Append(const DIFF_PAIR &aOther)
double Skew() const
void SetViaDiameter(int aDiameter)
DIFF_PAIR(int aGap)
RANGED_NUM< int > m_gapConstraint
void updateLine(LINE &aLine, const SHAPE_LINE_CHAIN &aShape, NET_HANDLE aNet, const VIA &aVia)
double TotalLength() const
void SetViaDrill(int aDrill)
virtual void ClearLinks() override
Return the number of segments that were assembled together to form this line.
void SetShape(const DIFF_PAIR &aPair)
double CoupledLengthFactor() const
void SetShape(const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN &aN, bool aSwapLanes=false)
int Gap() const
bool EndsWithVias() const
NET_HANDLE NetP() const
DIFF_PAIR(const LINE &aLineP, const LINE &aLineN, int aGap=0)
DIFF_PAIR & operator=(const DIFF_PAIR &aOther)
NET_HANDLE m_net_n
bool Empty() const
DIFF_PAIR * Clone() const override
Return a deep copy of the item.
static bool ClassOf(const ITEM *aItem)
void SetGap(int aGap)
SHAPE_LINE_CHAIN m_n
void SetNets(NET_HANDLE aP, NET_HANDLE aN)
DIFF_PAIR(const DIFF_PAIR &aOther)
DIFF_PAIR & operator=(DIFF_PAIR &&aOther) noexcept
const SHAPE_LINE_CHAIN & CP() const
DIFF_PAIR(const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN &aN, int aGap=0)
void CoupledSegmentPairs(COUPLED_SEGMENTS_VEC &aPairs) const
NET_HANDLE NetN() const
void SetWidth(int aWidth)
A set of gateways calculated for the cursor or starting/ending primitive pair.
void SetFitVias(bool aEnable, int aDiameter=0, int aViaGap=-1)
void BuildFromPrimitivePair(const DP_PRIMITIVE_PAIR &aPair, bool aPreferDiagonal)
DP_GATEWAYS(int aGap)
bool FitGateways(DP_GATEWAYS &aEntry, DP_GATEWAYS &aTarget, bool aPrefDiagonal, DIFF_PAIR &aDp)
void BuildGeneric(const VECTOR2I &p0_p, const VECTOR2I &p0_n, bool aBuildEntries=false, bool aViaMode=false)
std::vector< DP_GATEWAY > & Gateways()
bool checkDiagonalAlignment(const VECTOR2I &a, const VECTOR2I &b) const
void BuildOrthoProjections(DP_GATEWAYS &aEntries, const VECTOR2I &aCursorPos, int aOrthoScore)
void buildDpContinuation(const DP_PRIMITIVE_PAIR &aPair, bool aIsDiagonal)
std::vector< DP_GATEWAY > m_gateways
const std::vector< DP_GATEWAY > & CGateways() const
void FilterByOrientation(int aAngleMask, DIRECTION_45 aRefOrientation)
void BuildForCursor(const VECTOR2I &aCursorPos)
void buildEntries(const VECTOR2I &p0_p, const VECTOR2I &p0_n)
Define a "gateway" for routing a differential pair - e.g.
SHAPE_LINE_CHAIN m_entryP
bool IsDiagonal() const
const SHAPE_LINE_CHAIN & EntryP() const
bool HasEntryLines() const
int AllowedAngles() const
const VECTOR2I & AnchorN() const
SHAPE_LINE_CHAIN m_entryN
void SetEntryLines(const SHAPE_LINE_CHAIN &aEntryP, const SHAPE_LINE_CHAIN &aEntryN)
const VECTOR2I & AnchorP() const
const SHAPE_LINE_CHAIN & EntryN() const
const DIFF_PAIR Entry() const
DP_GATEWAY(const VECTOR2I &aAnchorP, const VECTOR2I &aAnchorN, bool aIsDiagonal, int aAllowedEntryAngles=DIRECTION_45::ANG_OBTUSE, int aPriority=0)
int Priority() const
void SetPriority(int aPriority)
Store starting/ending primitives (pads, vias or segments) for a differential pair.
DIRECTION_45 DirN() const
const VECTOR2I & AnchorN() const
const VECTOR2I & AnchorP() const
DIRECTION_45 anchorDirection(const ITEM *aItem, const VECTOR2I &aP) const
void CursorOrientation(const VECTOR2I &aCursorPos, VECTOR2I &aMidpoint, VECTOR2I &aDirection) const
DP_PRIMITIVE_PAIR & operator=(const DP_PRIMITIVE_PAIR &aOther)
void SetAnchors(const VECTOR2I &aAnchorP, const VECTOR2I &aAnchorN)
DIRECTION_45 DirP() const
virtual HOLE * Clone() const override
Return a deep copy of the item.
Definition pns_hole.cpp:41
Base class for PNS router board items.
Definition pns_item.h:98
BOARD_ITEM * m_sourceItem
Definition pns_item.h:319
void SetSourceItem(BOARD_ITEM *aSourceItem)
Definition pns_item.h:201
const PNS_LAYER_RANGE & Layers() const
Definition pns_item.h:212
virtual NET_HANDLE Net() const
Definition pns_item.h:210
PnsKind Kind() const
Return the type (kind) of the item.
Definition pns_item.h:173
void SetNet(NET_HANDLE aNet)
Definition pns_item.h:209
void SetLayer(int aLayer)
Definition pns_item.h:215
@ DIFF_PAIR_T
Definition pns_item.h:110
void SetParent(BOARD_ITEM *aParent)
Definition pns_item.h:191
BOARD_ITEM * m_parent
Definition pns_item.h:317
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition pns_line.h:62
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Return the shape of the line.
Definition pns_line.h:131
const SHAPE_LINE_CHAIN & CLine() const
Definition pns_line.h:142
void AppendVia(const VIA &aVia)
void SetWidth(int aWidth)
Return line width.
Definition pns_line.h:155
virtual HOLE * Hole() const override
Definition pns_via.h:285
static constexpr int ALL_LAYERS
Definition pns_via.h:76
Definition seg.h:42
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Push and Shove diff pair dimensions (gap) settings dialog.
void * NET_HANDLE
Definition pns_item.h:55
COUPLED_SEGMENTS(const SEG &aCoupledP, const SEG &aParentP, int aIndexP, const SEG &aCoupledN, const SEG &aParentN, int aIndexN)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695