KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_twistedpair.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// Cat5e-style polyethylene-jacketed copper pair. AWG 24 conductor (0.511 mm) under a
36// 0.245 mm PE sheath (Dout = 1.0 mm), 49 twists/m. Individual tests override twist,
37// dielectric, and frequency.
38void SetCat5eLike( TWISTEDPAIR& aCalc )
39{
40 aCalc.SetParameter( TCP::EPSILONR, 2.3 );
41 aCalc.SetParameter( TCP::TAND, 0.0 );
42 aCalc.SetParameter( TCP::SIGMA, 5.8e7 );
43 aCalc.SetParameter( TCP::MURC, 1.0 );
46 aCalc.SetParameter( TCP::PHYS_LEN, 1.000 * TC::UNIT_M );
48 aCalc.SetParameter( TCP::Z0, 0.0 );
49 aCalc.SetParameter( TCP::ANG_L, 0.0 );
52}
53} // namespace
54
55
56BOOST_AUTO_TEST_SUITE( TwistedPairCalculations )
57
58
59// Cat5e-geometry pair using the Lefferson 1971 model with theta in degrees. At 49
60// twists/m and a 1.0 mm outer diameter the pitch angle is only ~8.75 deg, so the
61// twist raises epsEff from 1.325 to ~1.395 and drops Z0 from ~134.5 to ~131.2.
62// Real Cat5e reaches 100 ohm through tighter pair pitch and thinner insulation than
63// what this reference geometry exercises. We pin the math-core value so future
64// Lefferson refactors are caught immediately.
65BOOST_AUTO_TEST_CASE( Cat5eReferenceAnalysis )
66{
67 TWISTEDPAIR calc;
68 SetCat5eLike( calc );
69
70 calc.Analyse();
71
72 auto& results = calc.GetAnalysisResults();
73
74 const double Z0 = results.at(TCP::Z0).first;
75 BOOST_TEST( std::isfinite( Z0 ) );
76 BOOST_TEST( Z0 > 0.0 );
77 BOOST_TEST( Z0 == 131.16, boost::test_tools::tolerance( 0.01 ) );
78
79 const double epsEff = results.at(TCP::EPSILON_EFF).first;
80 BOOST_TEST( epsEff == 1.3947, boost::test_tools::tolerance( 0.01 ) );
81}
82
83
84// Air-spaced parallel wires with T=0 collapse to the untwisted TEM two-wire line and must
85// match (ZF0/π)·acosh(Dout/Din) exactly.
86BOOST_AUTO_TEST_CASE( DegenerateAirSpacedParallelWires )
87{
88 TWISTEDPAIR calc;
89 SetCat5eLike( calc );
90 calc.SetParameter( TCP::EPSILONR, 1.0 );
93
94 calc.Analyse();
95
96 auto& results = calc.GetAnalysisResults();
97
98 const double Din = 0.511e-3;
99 const double Dout = 1.000e-3;
100 const double expected = ( TC::ZF0 / M_PI ) * std::acosh( Dout / Din );
101
102 BOOST_TEST( results.at(TCP::Z0).first == expected, boost::test_tools::tolerance( 1e-9 ) );
103 BOOST_TEST( results.at(TCP::EPSILON_EFF).first == 1.0, boost::test_tools::tolerance( 1e-12 ) );
104}
105
106
107// Dielectric loss scales linearly with tan δ. Zero tan δ gives zero dielectric loss.
108BOOST_AUTO_TEST_CASE( DielectricLossScalesWithTanDelta )
109{
110 TWISTEDPAIR calc;
111 SetCat5eLike( calc );
112 calc.SetParameter( TCP::TAND, 0.0 );
113
114 calc.Analyse();
115 const double loss_zero = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
116 BOOST_TEST( loss_zero == 0.0, boost::test_tools::tolerance( 1e-12 ) );
117
118 calc.SetParameter( TCP::TAND, 0.001 );
119 calc.Analyse();
120 const double loss_lo = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
121 BOOST_TEST( std::isfinite( loss_lo ) );
122 BOOST_TEST( loss_lo > 0.0 );
123
124 // Double tan δ → loss_d doubles (α_d is linear in tan δ).
125 calc.SetParameter( TCP::TAND, 0.002 );
126 calc.Analyse();
127 const double loss_hi = calc.GetAnalysisResults()[TCP::LOSS_DIELECTRIC].first;
128 BOOST_TEST( loss_hi == 2.0 * loss_lo, boost::test_tools::tolerance( 1e-9 ) );
129}
130
131
132// Round-trip synthesis. Set Z0 target, solve for Dout, re-analyse, confirm Z0 hits.
133BOOST_AUTO_TEST_CASE( SynthesisRoundTripSolveForDout )
134{
135 TWISTEDPAIR calc;
136 SetCat5eLike( calc );
137
138 // Ask for a 100 ohm pair. At 1.0 mm Dout the model sits near 131 ohm, so the
139 // solver will shrink Dout (expect ~0.78 mm) to hit the target.
140 constexpr double Z0_target = 100.0;
141 calc.SetParameter( TCP::Z0, Z0_target );
142 calc.SetParameter( TCP::ANG_L, M_PI / 2.0 );
143
146
147 const double Dout_synth = calc.GetParameter( TCP::PHYS_DIAM_OUT );
148 BOOST_TEST( std::isfinite( Dout_synth ) );
149 BOOST_TEST( Dout_synth > 0.0 );
150
151 // Re-analyse and verify Z0 is within 1 Ω of the 100 Ω target.
152 calc.SetParameter( TCP::Z0, 0.0 );
153 calc.Analyse();
154 const double Z0_check = calc.GetAnalysisResults()[TCP::Z0].first;
155 BOOST_TEST( Z0_check == Z0_target, boost::test_tools::tolerance( 1.0 / Z0_target ) );
156}
157
158
159// Increasing the twist count raises the pitch angle, which raises the twist weight
160// on (epsr - epsr_env) and therefore raises epsEff while lowering Z0. Monotonic in
161// both directions for epsr > epsr_env.
162BOOST_AUTO_TEST_CASE( TwistRaisesEpsEffLowersZ0 )
163{
164 TWISTEDPAIR calc;
165 SetCat5eLike( calc );
166
168 calc.Analyse();
169 const double eps0 = calc.GetAnalysisResults()[TCP::EPSILON_EFF].first;
170 const double z0_0 = calc.GetAnalysisResults()[TCP::Z0].first;
171
173 calc.Analyse();
174 const double eps49 = calc.GetAnalysisResults()[TCP::EPSILON_EFF].first;
175 const double z0_49 = calc.GetAnalysisResults()[TCP::Z0].first;
176
177 calc.SetParameter( TCP::TWISTEDPAIR_TWIST, 1000.0 );
178 calc.Analyse();
179 const double eps1000 = calc.GetAnalysisResults()[TCP::EPSILON_EFF].first;
180 const double z0_1000 = calc.GetAnalysisResults()[TCP::Z0].first;
181
182 BOOST_TEST( eps49 > eps0 );
183 BOOST_TEST( eps1000 > eps49 );
184 BOOST_TEST( z0_49 < z0_0 );
185 BOOST_TEST( z0_1000 < z0_49 );
186}
187
188
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.
Twisted-pair transmission line calculation.
bool Synthesize(SYNTHESIZE_OPTS aOpts) override
Synthesize Din or Dout to hit the target Z0. Length is recomputed from ANG_L.
void SetSynthesizeTarget(TRANSLINE_PARAMETERS aTarget) override
Choose which geometry parameter will be solved for during synthesis.
void Analyse() override
Analyse pair geometry to output Z0, electrical length, losses, skin depth, εeff.
TRANSLINE_PARAMETERS TCP
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)
VECTOR3I expected(15, 30, 45)
BOOST_AUTO_TEST_CASE(Cat5eReferenceAnalysis)
#define M_PI
TRANSLINE_PARAMETERS
All possible parameters used (as inputs or outputs) by the transmission line calculations.