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 <tomasz.wlostowski@cern.ch>
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 
29 #include "pns_router.h"
30 #include "pns_debug_decorator.h"
31 
32 namespace PNS {
33 
35  MEANDER_PLACER ( aRouter )
36 {
37  // Init temporary variables (do not leave uninitialized members)
38  m_coupledLength = 0;
39  m_padToDieN = 0;
40  m_padToDieP = 0;
41 }
42 
43 
45 {
46 }
47 
48 
49 bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
50 {
51  VECTOR2I p;
52 
53  if( !aStartItem || !aStartItem->OfKind( ITEM::SEGMENT_T ) )
54  {
55  Router()->SetFailureReason( _( "Please select a differential pair trace you want to tune." ) );
56  return false;
57  }
58 
59  m_initialSegment = static_cast<SEGMENT*>( aStartItem );
60 
61  p = m_initialSegment->Seg().NearestPoint( aP );
62 
63  m_currentNode = NULL;
64  m_currentStart = p;
65 
66  m_world = Router()->GetWorld( )->Branch();
68 
69  TOPOLOGY topo( m_world );
71 
73  {
74  Router()->SetFailureReason( _( "Unable to find complementary differential pair "
75  "net for skew tuning. Make sure the names of the nets belonging "
76  "to a differential pair end with either _N/_P or +/-." ) );
77  return false;
78  }
79 
80  if( m_originPair.Gap() < 0 )
81  m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
82 
83  if( !m_originPair.PLine().SegmentCount() ||
85  return false;
86 
89 
91 
93  m_currentEnd = VECTOR2I( 0, 0 );
96 
97  if ( m_originPair.PLine().Net() == m_originLine.Net() )
98  {
101  }
102  else
103  {
106  }
107 
108  return true;
109 }
110 
111 
113 {
114  return itemsetLength ( m_tunedPath );
115 }
116 
117 
118 long long int MEANDER_SKEW_PLACER::itemsetLength( const ITEM_SET& aSet ) const
119 {
120  long long int total = m_padToDieLenth;
121  for( const ITEM* item : aSet.CItems() )
122  {
123  if( const LINE* l = dyn_cast<const LINE*>( item ) )
124  {
125  total += l->CLine().Length();
126  }
127  }
128 
129  return total;
130 }
131 
132 
133 long long int MEANDER_SKEW_PLACER::currentSkew() const
134 {
135  return m_lastLength - m_coupledLength;
136 }
137 
138 
139 bool MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
140 {
141  for( const ITEM* item : m_tunedPathP.CItems() )
142  {
143  if( const LINE* l = dyn_cast<const LINE*>( item ) )
144  Dbg()->AddLine( l->CLine(), 5, 10000 );
145  }
146 
147  for( const ITEM* item : m_tunedPathN.CItems() )
148  {
149  if( const LINE* l = dyn_cast<const LINE*>( item ) )
150  Dbg()->AddLine( l->CLine(), 4, 10000 );
151  }
152 
153  return doMove( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew );
154 }
155 
156 
157 const wxString MEANDER_SKEW_PLACER::TuningInfo( EDA_UNITS_T aUnits ) const
158 {
159  wxString status;
160 
161  switch( m_lastStatus )
162  {
163  case TOO_LONG:
164  status = _( "Too long: skew " );
165  break;
166  case TOO_SHORT:
167  status = _( "Too short: skew " );
168  break;
169  case TUNED:
170  status = _( "Tuned: skew " );
171  break;
172  default:
173  return _( "?" );
174  }
175 
176  status += ::MessageTextFromValue( aUnits, m_lastLength - m_coupledLength, false );
177  status += "/";
178  status += ::MessageTextFromValue( aUnits, m_settings.m_targetSkew, false );
179 
180  return status;
181 }
182 
183 }
int GetTotalPadToDieLength(const LINE &aLine) const
Class ITEM.
Definition: pns_item.h:53
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:49
SEGMENT * GetLink(int aIndex) const
Definition: pns_line.h:219
Implementation of conversion functions that require both schematic and board internal units.
int Gap() const
int SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:145
long long int itemsetLength(const ITEM_SET &aSet) const
const LINE AssembleLine(SEGMENT *aSeg, int *aOriginSegmentIndex=NULL, bool aStopAtLockedJoints=false)
Function AssembleLine()
Definition: pns_node.cpp:820
const DIFF_PAIR AssembleDiffPair(SEGMENT *aStart)
const wxString TuningInfo(EDA_UNITS_T aUnits) const override
Function TuningInfo()
TUNING_STATUS m_lastStatus
VECTOR2I m_currentEnd
current end point
long long int m_lastLength
int m_targetSkew
target skew value for diff pair de-skewing
Definition: pns_meander.h:97
const SEG & Seg() const
Definition: pns_segment.h:93
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:104
int m_currentWidth
width of the meandered trace(s)
wxString MessageTextFromValue(EDA_UNITS_T aUnits, int aValue, bool aUseMils)
Definition: base_units.cpp:125
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0)
void SetGap(int aGap)
const ITEM_SET AssembleTrivialPath(ITEM *aStart)
int Net() const
Definition: pns_item.h:148
NODE * m_world
pointer to world to search colliding items
bool doMove(const VECTOR2I &aP, ITEM *aEndItem, long long int aTargetLength)
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:70
void SetFailureReason(const wxString &aReason)
Definition: pns_router.h:216
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Function NearestPoint()
Definition: seg.h:374
Class MEANDER_PLACER.
#define _(s)
void Remove(SOLID *aSolid)
Function Remove()
Definition: pns_node.cpp:715
int m_padToDieLenth
total length added by pad to die size
VECTOR2I m_currentStart
current routing start point (end of tail, beginning of head)
MEANDER_SETTINGS m_settings
meandering settings
bool Start(const VECTOR2I &aP, ITEM *aStartItem) override
Function Start()
NODE * m_currentNode
Current world state
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:132
const ENTRIES & CItems() const
Definition: pns_itemset.h:141
int Width() const
Returns line width
Definition: pns_line.h:175
long long int origPathLength() const override
Push and Shove diff pair dimensions (gap) settings dialog.
NODE * GetWorld() const
Definition: pns_router.h:146
EDA_UNITS_T
Definition: common.h:133
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Function Move()