KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_coplanar.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <cmath>
27
31
32
33namespace TC = TRANSLINE_CALCULATIONS;
35
36
37namespace
38{
39// Common geometry used across the Coplanar test suite. FR-4-ish substrate, modest
40// conductor thickness, 1 GHz.
41void SetDefaults( COPLANAR& aCalc )
42{
43 aCalc.SetParameter( TCP::EPSILONR, 4.4 );
44 aCalc.SetParameter( TCP::TAND, 0.0 );
45 aCalc.SetParameter( TCP::MURC, 1.0 );
46 aCalc.SetParameter( TCP::SIGMA, 5.8e7 );
47 aCalc.SetParameter( TCP::H, 0.8 * TC::UNIT_MM );
48 aCalc.SetParameter( TCP::T, 35.0 * TC::UNIT_MICRON );
50 aCalc.SetParameter( TCP::PHYS_S, 0.3 * TC::UNIT_MM );
51 aCalc.SetParameter( TCP::PHYS_LEN, 100.0 * TC::UNIT_MM );
52 aCalc.SetParameter( TCP::FREQUENCY, 1.0e9 );
53 aCalc.SetParameter( TCP::Z0, 0.0 );
54 aCalc.SetParameter( TCP::ANG_L, 0.0 );
55 aCalc.SetParameter( TCP::CPW_BACKMETAL, 0.0 );
56}
57} // namespace
58
59
60BOOST_AUTO_TEST_SUITE( CoplanarCalculations )
61
62
63// Ungrounded CPW on FR-4. Pinned to the implementation output at 1 GHz with ±2 % tolerance.
64BOOST_AUTO_TEST_CASE( UngroundedImpedance )
65{
66 COPLANAR calc;
67 SetDefaults( calc );
68
69 calc.Analyse();
70
71 const double Z0 = calc.GetAnalysisResults()[TCP::Z0].first;
72 BOOST_TEST( std::isfinite( Z0 ) );
73 BOOST_TEST( Z0 > 40.0 );
74 BOOST_TEST( Z0 < 90.0 );
75
76 // Pinned value from the conformal-mapping solution at f = 1 GHz. Tolerance 2 %.
77 BOOST_TEST( Z0 == 72.30, boost::test_tools::tolerance( 0.02 ) );
78}
79
80
81// Conductor-backed CPW pulls Z0 lower (closer to microstrip-like loading) than the
82// ungrounded case with the same geometry. A thin substrate is used so the back plane
83// has a noticeable effect.
84BOOST_AUTO_TEST_CASE( BackMetalLowersImpedance )
85{
86 COPLANAR calc_cpw;
87 SetDefaults( calc_cpw );
88 calc_cpw.SetParameter( TCP::H, 0.25 * TC::UNIT_MM );
89 calc_cpw.Analyse();
90 const double Z0_cpw = calc_cpw.GetAnalysisResults()[TCP::Z0].first;
91
92 COPLANAR calc_cbcpw;
93 SetDefaults( calc_cbcpw );
94 calc_cbcpw.SetParameter( TCP::H, 0.25 * TC::UNIT_MM );
95 calc_cbcpw.SetParameter( TCP::CPW_BACKMETAL, 1.0 );
96 calc_cbcpw.Analyse();
97 const double Z0_cbcpw = calc_cbcpw.GetAnalysisResults()[TCP::Z0].first;
98
99 BOOST_TEST( std::isfinite( Z0_cbcpw ) );
100 BOOST_TEST( ( Z0_cpw - Z0_cbcpw ) >= 2.0 );
101}
102
103
104// Dielectric loss should be finite, positive, and broadly consistent with the quasi-TEM
105// closed-form alpha_d = pi * f * sqrt(eps_eff) * tan(delta) / c within a generous
106// tolerance (the implementation applies an additional (eps_r / (eps_r - 1)) weighting).
107BOOST_AUTO_TEST_CASE( DielectricLossIsFiniteAndPositive )
108{
109 COPLANAR calc;
110 SetDefaults( calc );
111 calc.SetParameter( TCP::TAND, 0.02 );
112
113 calc.Analyse();
114
115 const double loss_d = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
116 const double eps_eff = calc.GetAnalysisResults()[TCP::EPSILON_EFF].first;
117
118 BOOST_TEST( std::isfinite( loss_d ) );
119 BOOST_TEST( loss_d > 0.0 );
120
121 // Reference closed form for the coplanar-waveguide dielectric loss used by the
122 // implementation. alpha_d = (eps_r / (eps_r - 1)) * (eps_eff - 1) / sqrt(eps_eff) *
123 // pi * f * tan(delta) / c [Np/m]; multiply by length and LOG2DB for dB.
124 const double epsr = 4.4;
125 const double tand = 0.02;
126 const double freq = 1.0e9;
127 const double len = 100.0 * TC::UNIT_MM;
128 const double ad_factor = ( epsr / ( epsr - 1.0 ) ) * tand * M_PI / TC::C0;
129 const double expected_dB = TC::LOG2DB * len * ad_factor * freq * ( eps_eff - 1.0 ) / std::sqrt( eps_eff );
130
131 BOOST_TEST( loss_d == expected_dB, boost::test_tools::tolerance( 0.05 ) );
132}
133
134
135// Synthesis round-trip. Given a target Z0, solve for PHYS_WIDTH with the gap fixed,
136// then re-analyse and confirm the resulting Z0 is within 0.5 Ω.
137BOOST_AUTO_TEST_CASE( SynthesisRoundTripSolveForWidth )
138{
139 COPLANAR calc;
140 SetDefaults( calc );
141 calc.SetParameter( TCP::Z0, 50.0 );
142 calc.SetParameter( TCP::ANG_L, M_PI / 2.0 );
143
146
147 const double W_synth = calc.GetParameter( TCP::PHYS_WIDTH );
148 BOOST_TEST( std::isfinite( W_synth ) );
149 BOOST_TEST( W_synth > 0.0 );
150
151 calc.Analyse();
152 const double Z0_check = calc.GetAnalysisResults()[TCP::Z0].first;
153 BOOST_TEST( std::abs( Z0_check - 50.0 ) < 0.5 );
154}
155
156
157// The CPW_BACKMETAL parameter is honoured on each call to Analyse: toggling it produces
158// different Z0 results without the calc needing to be re-created.
159BOOST_AUTO_TEST_CASE( BackMetalParameterRoundTrip )
160{
161 COPLANAR calc;
162 SetDefaults( calc );
163
164 calc.SetParameter( TCP::CPW_BACKMETAL, 0.0 );
165 calc.Analyse();
166 const double Z0_cpw = calc.GetAnalysisResults()[TCP::Z0].first;
167
168 calc.SetParameter( TCP::CPW_BACKMETAL, 1.0 );
169 calc.Analyse();
170 const double Z0_cbcpw = calc.GetAnalysisResults()[TCP::Z0].first;
171
172 calc.SetParameter( TCP::CPW_BACKMETAL, 0.0 );
173 calc.Analyse();
174 const double Z0_cpw_again = calc.GetAnalysisResults()[TCP::Z0].first;
175
176 BOOST_TEST( std::abs( Z0_cpw - Z0_cbcpw ) > 1.0 );
177 BOOST_TEST( Z0_cpw == Z0_cpw_again, boost::test_tools::tolerance( 1.0e-9 ) );
178}
179
180
Coplanar waveguide (CPW) and conductor-backed coplanar waveguide (CBCPW) calculation.
void SetSynthesizeTarget(TRANSLINE_PARAMETERS aTarget) override
Choose which geometry parameter will be solved for during synthesis.
void Analyse() override
Analyse trace geometry to produce Z0, electrical length, effective permittivity, and losses.
bool Synthesize(SYNTHESIZE_OPTS aOpts) override
Synthesize the unknown geometry parameter to match the Z0 target.
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.
std::unordered_map< TRANSLINE_PARAMETERS, std::pair< double, TRANSLINE_STATUS > > & GetAnalysisResults()
Gets the output parameters following analysis.
TRANSLINE_PARAMETERS TCP
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(UngroundedImpedance)
BOOST_TEST(contains==c.ExpectedContains)
BOOST_AUTO_TEST_SUITE_END()
#define M_PI
TRANSLINE_PARAMETERS
All possible parameters used (as inputs or outputs) by the transmission line calculations.