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, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <cmath>
23
27
28
29namespace TC = TRANSLINE_CALCULATIONS;
31
32
33namespace
34{
35// Common geometry used across the Coplanar test suite. FR-4-ish substrate, modest
36// conductor thickness, 1 GHz.
37void SetDefaults( COPLANAR& aCalc )
38{
39 aCalc.SetParameter( TCP::EPSILONR, 4.4 );
40 aCalc.SetParameter( TCP::TAND, 0.0 );
41 aCalc.SetParameter( TCP::MURC, 1.0 );
42 aCalc.SetParameter( TCP::SIGMA, 5.8e7 );
43 aCalc.SetParameter( TCP::H, 0.8 * TC::UNIT_MM );
44 aCalc.SetParameter( TCP::T, 35.0 * TC::UNIT_MICRON );
46 aCalc.SetParameter( TCP::PHYS_S, 0.3 * TC::UNIT_MM );
47 aCalc.SetParameter( TCP::PHYS_LEN, 100.0 * TC::UNIT_MM );
48 aCalc.SetParameter( TCP::FREQUENCY, 1.0e9 );
49 aCalc.SetParameter( TCP::Z0, 0.0 );
50 aCalc.SetParameter( TCP::ANG_L, 0.0 );
51 aCalc.SetParameter( TCP::CPW_BACKMETAL, 0.0 );
52}
53} // namespace
54
55
56BOOST_AUTO_TEST_SUITE( CoplanarCalculations )
57
58
59// Ungrounded CPW on FR-4. Pinned to the implementation output at 1 GHz with ±2 % tolerance.
60BOOST_AUTO_TEST_CASE( UngroundedImpedance )
61{
62 COPLANAR calc;
63 SetDefaults( calc );
64
65 calc.Analyse();
66
67 const double Z0 = calc.GetAnalysisResults()[TCP::Z0].first;
68 BOOST_TEST( std::isfinite( Z0 ) );
69 BOOST_TEST( Z0 > 40.0 );
70 BOOST_TEST( Z0 < 90.0 );
71
72 // Pinned value from the conformal-mapping solution at f = 1 GHz. Tolerance 2 %.
73 BOOST_TEST( Z0 == 72.30, boost::test_tools::tolerance( 0.02 ) );
74}
75
76
77// Conductor-backed CPW pulls Z0 lower (closer to microstrip-like loading) than the
78// ungrounded case with the same geometry. A thin substrate is used so the back plane
79// has a noticeable effect.
80BOOST_AUTO_TEST_CASE( BackMetalLowersImpedance )
81{
82 COPLANAR calc_cpw;
83 SetDefaults( calc_cpw );
84 calc_cpw.SetParameter( TCP::H, 0.25 * TC::UNIT_MM );
85 calc_cpw.Analyse();
86 const double Z0_cpw = calc_cpw.GetAnalysisResults()[TCP::Z0].first;
87
88 COPLANAR calc_cbcpw;
89 SetDefaults( calc_cbcpw );
90 calc_cbcpw.SetParameter( TCP::H, 0.25 * TC::UNIT_MM );
91 calc_cbcpw.SetParameter( TCP::CPW_BACKMETAL, 1.0 );
92 calc_cbcpw.Analyse();
93 const double Z0_cbcpw = calc_cbcpw.GetAnalysisResults()[TCP::Z0].first;
94
95 BOOST_TEST( std::isfinite( Z0_cbcpw ) );
96 BOOST_TEST( ( Z0_cpw - Z0_cbcpw ) >= 2.0 );
97}
98
99
100// Dielectric loss should be finite, positive, and broadly consistent with the quasi-TEM
101// closed-form alpha_d = pi * f * sqrt(eps_eff) * tan(delta) / c within a generous
102// tolerance (the implementation applies an additional (eps_r / (eps_r - 1)) weighting).
103BOOST_AUTO_TEST_CASE( DielectricLossIsFiniteAndPositive )
104{
105 COPLANAR calc;
106 SetDefaults( calc );
107 calc.SetParameter( TCP::TAND, 0.02 );
108
109 calc.Analyse();
110
111 const double loss_d = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
112 const double eps_eff = calc.GetAnalysisResults()[TCP::EPSILON_EFF].first;
113
114 BOOST_TEST( std::isfinite( loss_d ) );
115 BOOST_TEST( loss_d > 0.0 );
116
117 // Reference closed form for the coplanar-waveguide dielectric loss used by the
118 // implementation. alpha_d = (eps_r / (eps_r - 1)) * (eps_eff - 1) / sqrt(eps_eff) *
119 // pi * f * tan(delta) / c [Np/m]; multiply by length and LOG2DB for dB.
120 const double epsr = 4.4;
121 const double tand = 0.02;
122 const double freq = 1.0e9;
123 const double len = 100.0 * TC::UNIT_MM;
124 const double ad_factor = ( epsr / ( epsr - 1.0 ) ) * tand * M_PI / TC::C0;
125 const double expected_dB = TC::LOG2DB * len * ad_factor * freq * ( eps_eff - 1.0 ) / std::sqrt( eps_eff );
126
127 BOOST_TEST( loss_d == expected_dB, boost::test_tools::tolerance( 0.05 ) );
128}
129
130
131// Synthesis round-trip. Given a target Z0, solve for PHYS_WIDTH with the gap fixed,
132// then re-analyse and confirm the resulting Z0 is within 0.5 Ω.
133BOOST_AUTO_TEST_CASE( SynthesisRoundTripSolveForWidth )
134{
135 COPLANAR calc;
136 SetDefaults( calc );
137 calc.SetParameter( TCP::Z0, 50.0 );
138 calc.SetParameter( TCP::ANG_L, M_PI / 2.0 );
139
142
143 const double W_synth = calc.GetParameter( TCP::PHYS_WIDTH );
144 BOOST_TEST( std::isfinite( W_synth ) );
145 BOOST_TEST( W_synth > 0.0 );
146
147 calc.Analyse();
148 const double Z0_check = calc.GetAnalysisResults()[TCP::Z0].first;
149 BOOST_TEST( std::abs( Z0_check - 50.0 ) < 0.5 );
150}
151
152
153// The CPW_BACKMETAL parameter is honoured on each call to Analyse: toggling it produces
154// different Z0 results without the calc needing to be re-created.
155BOOST_AUTO_TEST_CASE( BackMetalParameterRoundTrip )
156{
157 COPLANAR calc;
158 SetDefaults( calc );
159
160 calc.SetParameter( TCP::CPW_BACKMETAL, 0.0 );
161 calc.Analyse();
162 const double Z0_cpw = calc.GetAnalysisResults()[TCP::Z0].first;
163
164 calc.SetParameter( TCP::CPW_BACKMETAL, 1.0 );
165 calc.Analyse();
166 const double Z0_cbcpw = calc.GetAnalysisResults()[TCP::Z0].first;
167
168 calc.SetParameter( TCP::CPW_BACKMETAL, 0.0 );
169 calc.Analyse();
170 const double Z0_cpw_again = calc.GetAnalysisResults()[TCP::Z0].first;
171
172 BOOST_TEST( std::abs( Z0_cpw - Z0_cbcpw ) > 1.0 );
173 BOOST_TEST( Z0_cpw == Z0_cpw_again, boost::test_tools::tolerance( 1.0e-9 ) );
174}
175
176
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_AUTO_TEST_SUITE_END()
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)
#define M_PI
TRANSLINE_PARAMETERS
All possible parameters used (as inputs or outputs) by the transmission line calculations.