TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
impedance.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// Closed-form transmission-line impedance for PCB traces (design doc 15 §5.3) and the IPC-2221 width for
4// current (§5.4). Quasi-static (no dispersion: the targets are 45-100 ohm lines below a few GHz), lossless,
5// no solder mask (it lowers outer-layer impedance by roughly 1-3 ohm; KiCad's calculator also leaves it off
6// by default). Geometry in integer nanometres; impedances in ohm.
7//
8// Models (each cited at its definition in impedance.cpp):
9// microstrip Hammerstad & Jensen 1980, with their finite-thickness correction
10// stripline Cohn 1954 (wide strip, thick) / Wheeler 1978 (narrow strip), asymmetric by the image
11// split of Wadell 1991 §3.5.3 (two virtual centred striplines in parallel)
12// coupled microstrip Kirschning & Jansen 1984 static even/odd mode, Jansen 1978 thickness correction,
13// Bahl & Garg 1977 thickness filling-factor term
14// coupled stripline Cohn 1955 zero-thickness even/odd, Cohn 1960 thickness correction, asymmetric by the
15// same image split
16// grounded coplanar Ghione & Naldi 1983/1984 conformal mapping, Gupta et al. 1996 thickness correction
17// Solving for a width or gap is a bisection on integer nanometres: deterministic and exact to 1 nm.
18#include <functional>
19#include <string>
20
21#include "core/units.hpp"
22
24
25inline constexpr double kEta0 = 376.730313668; // free-space wave impedance, ohm
26inline constexpr double kC0MmPerPs = 0.299792458; // speed of light, mm/ps
27
28struct Line { // single-ended line
29 double z0 = 0; // characteristic impedance, ohm
30 double eps_eff = 0; // effective relative permittivity (sets the propagation delay)
31};
32
33struct Pair { // symmetric edge-coupled pair
34 double z_even = 0, z_odd = 0;
35 double eps_eff_even = 0, eps_eff_odd = 0;
36 double zdiff() const { return 2.0 * z_odd; } // differential = 2 x odd mode
37};
38
39// Microstrip: strip of width w and thickness t on a dielectric of height h (strip bottom to plane), εr er.
40Line microstrip(Coord w, Coord h, Coord t, double er);
41// Stripline between two planes: h1 dielectric from the upper plane to the strip, h2 from the strip to the lower
42// plane (the plane spacing is h1 + t + h2); symmetric when h1 == h2. Homogeneous dielectric: eps_eff = er.
43Line stripline(Coord w, Coord h1, Coord h2, Coord t, double er);
44// Edge-coupled microstrip: two strips of width w, edge-to-edge gap s.
46// Edge-coupled stripline (broadside layout not modelled).
47Pair coupled_stripline(Coord w, Coord s, Coord h1, Coord h2, Coord t, double er);
48// Grounded (conductor-backed) coplanar waveguide: strip w, gap g to the coplanar ground on both sides, plane at h.
49Line gcpw(Coord w, Coord g, Coord h, Coord t, double er);
50
51// IPC-2141A's simple forms (the industry rule of thumb, ±5-10 %), used only as an independent cross-check.
52double ipc2141_microstrip(Coord w, Coord h, Coord t, double er);
53double ipc2141_stripline(Coord w, Coord b, Coord t, double er); // b = plane spacing, strip centred
54
55// Propagation delay in ps/mm for an effective permittivity: sqrt(eps_eff) / c.
56double prop_delay_ps_per_mm(double eps_eff);
57
58// Complete elliptic integral ratio K(k) / K(k'), k' = sqrt(1 - k^2), by the arithmetic-geometric mean
59// (K(k) = pi / (2 AGM(1, k'))). Exposed for tests.
60double k_ratio(double k);
61
62// ---- solving -----------------------------------------------------------------------------------------------
63
64struct Solved {
65 bool ok = false;
66 Coord value = 0; // the solved width or gap, nm
67 double z = 0; // impedance at `value`
68 std::string why; // set when !ok: target below/above what [lo, hi] can reach
69};
70
71// Bisection on integer nm for a function that decreases (decreasing = true, e.g. Z(width)) or increases
72// (Z(gap)) monotonically on [lo, hi]. Returns the integer closest to the crossing (ties: the smaller value).
73Solved solve_monotone(const std::function<double(Coord)>& z_of, double target, Coord lo, Coord hi, bool decreasing);
74
75// ---- stated formula accuracy -------------------------------------------------------------------------------
76
77enum class Structure : std::uint8_t { Microstrip, Stripline, Gcpw };
79// Formula error stated in the report, percent (doc 15 §5.3 point 3; dev/assumptions-m13.md).
80double formula_error_pct(Structure s, bool differential, bool asymmetric);
81
82// ---- IPC-2221 width for current (doc 15 §5.4) ----------------------------------------------------------------
83
84// IPC-2221B §6.2 (from the IPC-D-275 charts): I = k * dT^0.44 * A^0.725, A cross-section in mil^2,
85// k = 0.048 external / 0.024 internal layers. Width for `amps` at temperature rise `delta_t_c` with copper
86// thickness `copper` (nm), rounded up to the next nm.
87Coord width_for_current(double amps, double delta_t_c, Coord copper, bool external);
88double current_for_width(Coord width, double delta_t_c, Coord copper, bool external);
89
90} // namespace tmk::crules::imp
double current_for_width(Coord width, double delta_t_c, Coord copper, bool external)
double prop_delay_ps_per_mm(double eps_eff)
Propagation delay in ps/mm for an effective permittivity: sqrt(eps_eff) / c.
double ipc2141_stripline(Coord w, Coord b, Coord t, double er)
b = plane spacing, strip centred
Coord width_for_current(double amps, double delta_t_c, Coord copper, bool external)
IPC-2221B §6.2 (from the IPC-D-275 charts): I = k * dT^0.44 * A^0.725, A cross-section in mil^2,...
double k_ratio(double k)
Complete elliptic integral ratio K(k) / K(k'), k' = sqrt(1 - k^2), by the arithmetic-geometric mean (...
Solved solve_monotone(const std::function< double(Coord)> &z_of, double target, Coord lo, Coord hi, bool decreasing)
Bisection on integer nm for a function that decreases (decreasing = true, e.g.
Pair coupled_microstrip(Coord w, Coord s, Coord h, Coord t, double er)
Edge-coupled microstrip: two strips of width w, edge-to-edge gap s.
Line gcpw(Coord w, Coord g, Coord h, Coord t, double er)
Grounded (conductor-backed) coplanar waveguide: strip w, gap g to the coplanar ground on both sides,...
const char * structure_name(Structure s)
double ipc2141_microstrip(Coord w, Coord h, Coord t, double er)
IPC-2141A's simple forms (the industry rule of thumb, ±5-10 %), used only as an independent cross-che...
constexpr double kC0MmPerPs
speed of light, mm/ps
Definition impedance.hpp:26
Pair coupled_stripline(Coord w, Coord s, Coord h1, Coord h2, Coord t, double er)
Edge-coupled stripline (broadside layout not modelled).
Line microstrip(Coord w, Coord h, Coord t, double er)
Microstrip: strip of width w and thickness t on a dielectric of height h (strip bottom to plane),...
constexpr double kEta0
free-space wave impedance, ohm
Definition impedance.hpp:25
double formula_error_pct(Structure s, bool differential, bool asymmetric)
Formula error stated in the report, percent (doc 15 §5.3 point 3; dev/assumptions-m13....
Line stripline(Coord w, Coord h1, Coord h2, Coord t, double er)
Stripline between two planes: h1 dielectric from the upper plane to the strip, h2 from the strip to t...
std::int64_t Coord
Engine coordinate: signed 64-bit nanometres.
Definition units.hpp:12
double eps_eff
effective relative permittivity (sets the propagation delay)
Definition impedance.hpp:30
double z0
< single-ended line
Definition impedance.hpp:29
double zdiff() const
Definition impedance.hpp:36
double z_even
< symmetric edge-coupled pair
Definition impedance.hpp:34
std::string why
set when !ok: target below/above what [lo, hi] can reach
Definition impedance.hpp:68
double z
impedance at value
Definition impedance.hpp:67
Coord value
the solved width or gap, nm
Definition impedance.hpp:66