KiCad PCB EDA Suite
Loading...
Searching...
No Matches
common/transline_calculations/stripline.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2001 Gopal Narayanan <[email protected]>
3 * Copyright (C) 2002 Claudio Girardi <[email protected]>
4 * Copyright (C) 2005, 2006 Stefan Jahn <[email protected]>
5 * Modified for Kicad: 2018 Jean-Pierre Charras <jp.charras at wanadoo.fr>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
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 package; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
26
27
28namespace TC = TRANSLINE_CALCULATIONS;
30
31
33{
34 SetParameter( TCP::SKIN_DEPTH, SkinDepth() );
35 SetParameter( TCP::EPSILON_EFF, GetParameter( TCP::EPSILONR ) ); // no dispersion
36
37 double ac1, ac2;
38 double t = GetParameter( TCP::T );
39 double a = GetParameter( TCP::STRIPLINE_A );
40 double h = GetParameter( TCP::H );
41 SetParameter( TCP::Z0,
42 2.0 / ( 1.0 / lineImpedance( 2.0 * a + t, ac1 ) + 1.0 / lineImpedance( 2.0 * ( h - a ) - t, ac2 ) ) );
43 SetParameter( TCP::LOSS_CONDUCTOR, GetParameter( TCP::PHYS_LEN ) * ( ac1 + ac2 ) );
44 SetParameter( TCP::LOSS_DIELECTRIC, TC::LOG2DB * GetParameter( TCP::PHYS_LEN ) * ( M_PI / TC::C0 )
45 * GetParameter( TCP::FREQUENCY ) * sqrt( GetParameter( TCP::EPSILONR ) )
46 * GetParameter( TCP::TAND ) );
47
48 SetParameter( TCP::ANG_L, 2.0 * M_PI * GetParameter( TCP::PHYS_LEN ) * sqrt( GetParameter( TCP::EPSILONR ) )
49 * GetParameter( TCP::FREQUENCY ) / TC::C0 ); // in radians
50
51 unit_prop_delay = UnitPropagationDelay( GetParameter( TCP::EPSILON_EFF ) );
52}
53
54
56{
57 return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0 );
58}
59
60
62{
63 SetAnalysisResult( TCP::EPSILON_EFF, GetParameter( TCP::EPSILON_EFF ) );
64 SetAnalysisResult( TCP::UNIT_PROP_DELAY, unit_prop_delay );
65 SetAnalysisResult( TCP::LOSS_CONDUCTOR, GetParameter( TCP::LOSS_CONDUCTOR ) );
66 SetAnalysisResult( TCP::LOSS_DIELECTRIC, GetParameter( TCP::LOSS_DIELECTRIC ) );
67 SetAnalysisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
68
69 const double Z0 = GetParameter( TCP::Z0 );
70 const double ANG_L = GetParameter( TCP::ANG_L );
71 const double L = GetParameter( TCP::PHYS_LEN );
72 const double W = GetParameter( TCP::PHYS_WIDTH );
73
74 const bool Z0_invalid = !std::isfinite( Z0 ) || Z0 < 0;
75 const bool ANG_L_invalid = !std::isfinite( ANG_L ) || ANG_L < 0;
76 const bool L_invalid = !std::isfinite( L ) || L < 0;
77 const bool W_invalid = !std::isfinite( W ) || W <= 0;
78
79 bool invalid = false;
80
81 if( GetParameter( TCP::STRIPLINE_A ) + GetParameter( TCP::T ) >= GetParameter( TCP::H ) )
82 invalid = true;
83
84 SetAnalysisResult( TCP::Z0, Z0, Z0_invalid || invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
85 SetAnalysisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
86 SetAnalysisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
87 SetAnalysisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
88 SetAnalysisResult( TCP::STRIPLINE_A, GetParameter( TCP::STRIPLINE_A ),
89 invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
90 SetAnalysisResult( TCP::T, GetParameter( TCP::T ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
91 SetAnalysisResult( TCP::H, GetParameter( TCP::H ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
92 SetAnalysisResult( TCP::Z0, GetParameter( TCP::Z0 ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
93}
94
95
97{
98 SetSynthesisResult( TCP::EPSILON_EFF, GetParameter( TCP::EPSILON_EFF ) );
99 SetSynthesisResult( TCP::UNIT_PROP_DELAY, unit_prop_delay );
100 SetSynthesisResult( TCP::LOSS_CONDUCTOR, GetParameter( TCP::LOSS_CONDUCTOR ) );
101 SetSynthesisResult( TCP::LOSS_DIELECTRIC, GetParameter( TCP::LOSS_DIELECTRIC ) );
102 SetSynthesisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
103
104 const double Z0 = GetParameter( TCP::Z0 );
105 const double ANG_L = GetParameter( TCP::ANG_L );
106 const double L = GetParameter( TCP::PHYS_LEN );
107 const double W = GetParameter( TCP::PHYS_WIDTH );
108
109 const bool Z0_invalid = !std::isfinite( Z0 ) || Z0 < 0;
110 const bool ANG_L_invalid = !std::isfinite( ANG_L ) || ANG_L < 0;
111 const bool L_invalid = !std::isfinite( L ) || L < 0;
112 const bool W_invalid = !std::isfinite( W ) || W <= 0;
113
114 bool invalid = false;
115
116 if( GetParameter( TCP::STRIPLINE_A ) + GetParameter( TCP::T ) >= GetParameter( TCP::H ) )
117 invalid = true;
118
119 SetSynthesisResult( TCP::Z0, Z0, Z0_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
120 SetSynthesisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
121 SetSynthesisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
122 SetSynthesisResult( TCP::PHYS_WIDTH, W, W_invalid || invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
123 SetSynthesisResult( TCP::STRIPLINE_A, GetParameter( TCP::STRIPLINE_A ),
124 invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
125 SetSynthesisResult( TCP::T, GetParameter( TCP::T ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
126 SetSynthesisResult( TCP::H, GetParameter( TCP::H ), invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
127}
128
129
130double STRIPLINE::lineImpedance( double aHeight, double& aAc ) const
131{
132 double ZL;
133 const double hmt = aHeight - GetParameter( TCP::T );
134
135 aAc = sqrt( GetParameter( TCP::FREQUENCY ) / GetParameter( TCP::SIGMA ) / 17.2 );
136
137 if( GetParameter( TCP::PHYS_WIDTH ) / hmt >= 0.35 )
138 {
139 ZL = GetParameter( TCP::PHYS_WIDTH )
140 + ( 2.0 * aHeight * log( ( 2.0 * aHeight - GetParameter( TCP::T ) ) / hmt )
141 - GetParameter( TCP::T ) * log( aHeight * aHeight / hmt / hmt - 1.0 ) )
142 / M_PI;
143 ZL = TC::ZF0 * hmt / sqrt( GetParameter( TCP::EPSILONR ) ) / 4.0 / ZL;
144
145 aAc *= 2.02e-6 * GetParameter( TCP::EPSILONR ) * ZL / hmt;
146 aAc *= 1.0 + 2.0 * GetParameter( TCP::PHYS_WIDTH ) / hmt
147 + ( aHeight + GetParameter( TCP::T ) ) / hmt / M_PI
148 * log( 2.0 * aHeight / GetParameter( TCP::T ) - 1.0 );
149 }
150 else
151 {
152 double tdw = GetParameter( TCP::T ) / GetParameter( TCP::PHYS_WIDTH );
153
154 if( GetParameter( TCP::T ) / GetParameter( TCP::PHYS_WIDTH ) > 1.0 )
155 tdw = GetParameter( TCP::PHYS_WIDTH ) / GetParameter( TCP::T );
156
157 double de = 1.0 + tdw / M_PI * ( 1.0 + log( 4.0 * M_PI / tdw ) ) + 0.236 * pow( tdw, 1.65 );
158
159 if( GetParameter( TCP::T ) / GetParameter( TCP::PHYS_WIDTH ) > 1.0 )
160 de *= GetParameter( TCP::T ) / 2.0;
161 else
162 de *= GetParameter( TCP::PHYS_WIDTH ) / 2.0;
163
164 ZL = TC::ZF0 / 2.0 / M_PI / sqrt( GetParameter( TCP::EPSILONR ) ) * log( 4.0 * aHeight / M_PI / de );
165
166 aAc *= 0.01141 / ZL / de;
167 aAc *= de / aHeight + 0.5 + tdw / 2.0 / M_PI + 0.5 / M_PI * log( 4.0 * M_PI / tdw ) + 0.1947 * pow( tdw, 0.65 )
168 - 0.0767 * pow( tdw, 1.65 );
169 }
170
171 return ZL;
172}
bool Synthesize(SYNTHESIZE_OPTS aOpts) override
Synthesis track geometry parameters to match given Z0.
void SetAnalysisResults() override
Sets the output values and status following analysis.
void SetSynthesisResults() override
Sets the output values and status following synthesis.
double lineImpedance(double aHeight, double &aAc) const
Calculate characteristic impedance and conductor loss (in db/meter)
void Analyse() override
Analyse track geometry parameters to output Z0 and Ang_L.
double GetParameter(const TRANSLINE_PARAMETERS aParam) const
Gets the given calculation property.
void SetParameter(const TRANSLINE_PARAMETERS aParam, const double aValue)
Sets the given calculation property.
void SetSynthesisResult(TRANSLINE_PARAMETERS aParam, const double aValue, const TRANSLINE_STATUS aStatus=TRANSLINE_STATUS::OK)
Sets a synthesis result.
bool MinimiseZ0Error1D(TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure)
minimizeZ0Error1D
double SkinDepth() const
Calculate skin depth.
void SetAnalysisResult(TRANSLINE_PARAMETERS aParam, const double aValue, const TRANSLINE_STATUS aStatus=TRANSLINE_STATUS::OK)
Sets an analysis result.
static double UnitPropagationDelay(double aEpsilonEff)
Calculates the unit propagation delay (ps/cm) for the given effective permittivity.
SYNTHESIZE_OPTS
Options for specifying synthesis inputs, targets, or strategies.
TRANSLINE_PARAMETERS
All possible parameters used (as inputs or outputs) by the transmission line calculations.