KiCad PCB EDA Suite
pns_meander_skew_placer.cpp
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 (C) 2016 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 #include <base_units.h> // God forgive me doing this...
23 
24 #include "pns_node.h"
25 #include "pns_itemset.h"
26 #include "pns_topology.h"
28 #include "pns_solid.h"
29 
30 #include "pns_router.h"
31 #include "pns_debug_decorator.h"
32 
33 namespace PNS {
34 
36  MEANDER_PLACER ( aRouter )
37 {
38  // Init temporary variables (do not leave uninitialized members)
39  m_coupledLength = 0;
40  m_padToDieN = 0;
41  m_padToDieP = 0;
42 }
43 
44 
46 {
47 }
48 
49 
50 bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
51 {
52  if( !aStartItem || !aStartItem->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T) )
53  {
54  Router()->SetFailureReason( _( "Please select a differential pair trace you want to tune." ) );
55  return false;
56  }
57 
58  m_initialSegment = static_cast<LINKED_ITEM*>( aStartItem );
59  m_currentNode = nullptr;
61 
62  m_world = Router()->GetWorld( )->Branch();
64 
65  TOPOLOGY topo( m_world );
67 
69  {
70  Router()->SetFailureReason( _( "Unable to find complementary differential pair "
71  "net for skew tuning. Make sure the names of the nets belonging "
72  "to a differential pair end with either _N/_P or +/-." ) );
73  return false;
74  }
75 
76  if( m_originPair.Gap() < 0 )
77  m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
78 
79  if( !m_originPair.PLine().SegmentCount() ||
81  return false;
82 
83  SOLID* padA = nullptr;
84  SOLID* padB = nullptr;
85 
86  m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &padA, &padB );
87 
88  m_padToDieP = 0;
89 
90  if( padA )
91  m_padToDieP += padA->GetPadToDie();
92 
93  if( padB )
94  m_padToDieP += padB->GetPadToDie();
95 
96  m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &padA, &padB );
97 
98  m_padToDieN = 0;
99 
100  if( padA )
101  m_padToDieN += padA->GetPadToDie();
102 
103  if( padB )
104  m_padToDieN += padB->GetPadToDie();
105 
107 
109  m_currentEnd = VECTOR2I( 0, 0 );
110 
111  if ( m_originPair.PLine().Net() == m_originLine.Net() )
112  {
116  }
117  else
118  {
122  }
123 
124  return true;
125 }
126 
127 
129 {
131 }
132 
133 
134 long long int MEANDER_SKEW_PLACER::currentSkew() const
135 {
136  return m_lastLength - m_coupledLength;
137 }
138 
139 
140 bool MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
141 {
142  for( const ITEM* item : m_tunedPathP.CItems() )
143  {
144  if( const LINE* l = dyn_cast<const LINE*>( item ) )
145  PNS_DBG( Dbg(), AddLine, l->CLine(), BLUE, 10000, "tuned-path-skew-p" );
146  }
147 
148  for( const ITEM* item : m_tunedPathN.CItems() )
149  {
150  if( const LINE* l = dyn_cast<const LINE*>( item ) )
151  PNS_DBG( Dbg(), AddLine, l->CLine(), YELLOW, 10000, "tuned-path-skew-n" );
152  }
153 
154  return doMove( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew );
155 }
156 
157 
158 const wxString MEANDER_SKEW_PLACER::TuningInfo( EDA_UNITS aUnits ) const
159 {
160  wxString status;
161 
162  switch( m_lastStatus )
163  {
164  case TOO_LONG:
165  status = _( "Too long: skew " );
166  break;
167  case TOO_SHORT:
168  status = _( "Too short: skew " );
169  break;
170  case TUNED:
171  status = _( "Tuned: skew " );
172  break;
173  default:
174  return _( "?" );
175  }
176 
177  status += ::MessageTextFromValue( aUnits, m_lastLength - m_coupledLength );
178  status += "/";
179  status += ::MessageTextFromValue( aUnits, m_settings.m_targetSkew );
180 
181  return status;
182 }
183 
184 }
Base class for PNS router board items.
Definition: pns_item.h:55
ROUTER * Router() const
Return current router settings.
Definition: pns_algo_base.h:54
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:104
const ITEM_SET AssembleTrivialPath(ITEM *aStart, std::pair< JOINT *, JOINT * > *aTerminalJoints=nullptr)
Assemble a trivial path between two joints given a starting item.
Implementation of conversion functions that require both schematic and board internal units.
int Gap() const
int SegmentCount() const
Definition: pns_line.h:139
const DIFF_PAIR AssembleDiffPair(SEGMENT *aStart)
TUNING_STATUS m_lastStatus
long long int m_lastLength
LINKED_ITEM * m_initialSegment
const ITEM_SET AssembleTuningPath(ITEM *aStart, SOLID **aStartPad=nullptr, SOLID **aEndPad=nullptr)
Like AssembleTrivialPath, but follows the track length algorithm, which discards segments that are fu...
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:60
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
Definition: pns_node.cpp:137
int m_currentWidth
Meander settings.
void Remove(ARC *aArc)
Remove an item from this branch.
Definition: pns_node.cpp:836
Definition: color4d.h:67
int m_padToDieLength
Width of the meandered trace(s).
void SetGap(int aGap)
int GetPadToDie() const
Definition: pns_solid.h:104
int Net() const
Definition: pns_item.h:152
long long int lineLength(const ITEM_SET &aLine) const
Calculate the total length of the line represented by an item set (tracks and vias)
NODE * m_world
Total length added by pad to die size.
bool doMove(const VECTOR2I &aP, ITEM *aEndItem, long long int aTargetLength)
#define PNS_DBG(dbg, method,...)
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:78
void SetFailureReason(const wxString &aReason)
Definition: pns_router.h:202
Single track length matching/meandering tool.
#define _(s)
const wxString TuningInfo(EDA_UNITS aUnits) const override
Return a string describing the status and length of the tuned traces.
VECTOR2I getSnappedStartPoint(LINKED_ITEM *aStartItem, VECTOR2I aStartPoint)
EDA_UNITS
Definition: eda_units.h:38
VECTOR2I m_currentStart
Current world state.
Definition: color4d.h:56
MEANDER_SETTINGS m_settings
The current end point.
bool Start(const VECTOR2I &aP, ITEM *aStartItem) override
Function Start()
bool OfKind(int aKindMask) const
Return true if the item's type matches the mask aKindMask.
Definition: pns_item.h:138
const ENTRIES & CItems() const
Definition: pns_itemset.h:136
int Width() const
Return true if the line is geometrically identical as line aOther.
Definition: pns_line.h:156
long long int origPathLength() const override
current routing start point (end of tail, beginning of head)
Push and Shove diff pair dimensions (gap) settings dialog.
NODE * GetWorld() const
Definition: pns_router.h:153
const LINE AssembleLine(LINKED_ITEM *aSeg, int *aOriginSegmentIndex=nullptr, bool aStopAtLockedJoints=false)
Follow the joint map to assemble a line connecting two non-trivial joints starting from segment aSeg.
Definition: pns_node.cpp:946
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Function Move()