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 }
40 
41 
43 {
44 }
45 
46 
47 bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
48 {
49  VECTOR2I p;
50 
51  if( !aStartItem || !aStartItem->OfKind( ITEM::SEGMENT_T ) )
52  {
53  Router()->SetFailureReason( _( "Please select a differential pair trace you want to tune." ) );
54  return false;
55  }
56 
57  m_initialSegment = static_cast<SEGMENT*>( aStartItem );
58 
59  p = m_initialSegment->Seg().NearestPoint( aP );
60 
61  m_currentNode = NULL;
62  m_currentStart = p;
63 
64  m_world = Router()->GetWorld( )->Branch();
66 
67  TOPOLOGY topo( m_world );
69 
71  {
72  Router()->SetFailureReason( _( "Unable to find complementary differential pair "
73  "net for skew tuning. Make sure the names of the nets belonging "
74  "to a differential pair end with either _N/_P or +/-." ) );
75  return false;
76  }
77 
78  if( m_originPair.Gap() < 0 )
79  m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
80 
81  if( !m_originPair.PLine().SegmentCount() ||
83  return false;
84 
87 
89 
91  m_currentEnd = VECTOR2I( 0, 0 );
92 
93  if ( m_originPair.PLine().Net() == m_originLine.Net() )
95  else
97 
98  return true;
99 }
100 
101 
103 {
104  return itemsetLength ( m_tunedPath );
105 }
106 
107 
109 {
110  int total = 0;
111  for( const ITEM* item : aSet.CItems() )
112  {
113  if( const LINE* l = dyn_cast<const LINE*>( item ) )
114  {
115  total += l->CLine().Length();
116  }
117  }
118 
119  return total;
120 }
121 
122 
124 {
125  return m_lastLength - m_coupledLength;
126 }
127 
128 
129 bool MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
130 {
131  for( const ITEM* item : m_tunedPathP.CItems() )
132  {
133  if( const LINE* l = dyn_cast<const LINE*>( item ) )
134  Dbg()->AddLine( l->CLine(), 5, 10000 );
135  }
136 
137  for( const ITEM* item : m_tunedPathN.CItems() )
138  {
139  if( const LINE* l = dyn_cast<const LINE*>( item ) )
140  Dbg()->AddLine( l->CLine(), 4, 10000 );
141  }
142 
143  return doMove( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew );
144 }
145 
146 
147 const wxString MEANDER_SKEW_PLACER::TuningInfo() const
148 {
149  wxString status;
150 
151  switch( m_lastStatus )
152  {
153  case TOO_LONG:
154  status = _( "Too long: skew " );
155  break;
156  case TOO_SHORT:
157  status = _( "Too short: skew " );
158  break;
159  case TUNED:
160  status = _( "Tuned: skew " );
161  break;
162  default:
163  return _( "?" );
164  }
165 
166  status += LengthDoubleToString( (double) m_lastLength - m_coupledLength, false );
167  status += "/";
168  status += LengthDoubleToString( (double) m_settings.m_targetSkew, false );
169 
170  return status;
171 }
172 
173 }
Class ITEM.
Definition: pns_item.h:53
const ENTRIES & CItems() const
Definition: pns_itemset.h:138
Implementation of conversion functions that require both schematic and board internal units...
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:70
const LINE AssembleLine(SEGMENT *aSeg, int *aOriginSegmentIndex=NULL, bool aStopAtLockedJoints=false)
Function AssembleLine()
Definition: pns_node.cpp:834
const DIFF_PAIR AssembleDiffPair(SEGMENT *aStart)
TUNING_STATUS m_lastStatus
VECTOR2I m_currentEnd
current end point
int m_targetSkew
target skew value for diff pair de-skewing
Definition: pns_meander.h:94
SEGMENT * GetLink(int aIndex) const
Definition: pns_line.h:203
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
int Width() const
Returns line width
Definition: pns_line.h:159
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:109
NODE * GetWorld() const
Definition: pns_router.h:134
int m_currentWidth
width of the meandered trace(s)
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:130
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 SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:129
int Gap() const
bool doMove(const VECTOR2I &aP, ITEM *aEndItem, int aTargetLength)
void SetFailureReason(const wxString &aReason)
Definition: pns_router.h:204
const wxString TuningInfo() const override
Function TuningInfo()
Class MEANDER_PLACER.
wxString LengthDoubleToString(double aValue, bool aConvertToMils)
Function LengthDoubleToString is a helper to convert the double length aValue to a string in inches...
Definition: base_units.cpp:122
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:49
void Remove(SOLID *aSolid)
Function Remove()
Definition: pns_node.cpp:729
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Function NearestPoint()
Definition: seg.h:354
VECTOR2I m_currentStart
current routing start point (end of tail, beginning of head)
NODE * m_world
pointer to world to search colliding items
MEANDER_SETTINGS m_settings
meandering settings
bool Start(const VECTOR2I &aP, ITEM *aStartItem) override
Function Start()
NODE * m_currentNode
Current world state
int Net() const
Function Net()
Definition: pns_item.h:177
const SEG & Seg() const
Definition: pns_segment.h:93
Push and Shove diff pair dimensions (gap) settings dialog.
int itemsetLength(const ITEM_SET &aSet) const
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Function Move()