TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
diff_pair.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// Differential pairs (design doc 05 §9 phase 3, §15): the geometry rule a pair is routed at, and a measurement of
4// how a routed pair came out (coupled share, gap, intra-pair skew). The coupled search itself lives in the router
5// (route/router.cpp, `route_pair`), which owns the lattice and the transaction state.
6#include <algorithm>
7#include <optional>
8#include <string>
9#include <vector>
10
11#include "drc/rule_engine.hpp"
12#include "geom/point.hpp"
13#include "model/board.hpp"
14#include "model/rules.hpp"
15
16namespace tmk::route {
17
18// What a pair is routed at. Sources, highest first: a custom rule's `diff_pair_gap` (opt, else min) and
19// `diff_pair_uncoupled` (max); the net class's diff-pair width/gap/via gap when the project sets them; else the net
20// class width and the clearance between the two halves (the tightest legal coupling). Never below the board minimums
21// or the clearance KiCad requires between the halves (the class diff-pair gap relaxes it only for pairs KiCad
22// recognises by name, `inDiffPair`).
23struct PairRule {
24 Coord width = 0; // track width of each half
25 Coord gap = 0; // edge-to-edge gap of the coupled section (target; >= required)
26 Coord required_gap = 0; // smallest gap the rules allow between the halves
27 Coord offset = 0; // centreline to each track centre: (width + gap) / 2, rounded up, plus a rounding margin
29 Coord via_offset = 0; // centreline to each via centre in a coupled via pair (>= offset)
30 std::optional<Coord> max_uncoupled; // per half, both ends together
31 std::string source; // "rule", "net class" or "clearance" (for the report)
32};
33
34// `via_mask`: solder-mask expansion of untented vias (route::Obstacles::via_mask()); two vias then need their mask
35// openings apart as well.
37 Coord via_mask = 0);
38
39// Octilinear unit direction d (0..7, E, NE, N, NW, W, SW, S, SE with y down) and its left normal, as doubles.
40struct Dir2 { double x, y; };
43// p + s * v, rounded half away from zero (KiCad's KiROUND), so offsets are symmetric about the centreline.
45// Miter corner of a polyline offset by `s` (signed: + left) where the centreline turns from direction d1 to d2.
46geom::Point miter_point(geom::Point c, int d1, int d2, double s);
47
48// A routed pair, measured on its tracks: a sample of one half counts as coupled where a parallel track of the
49// other half on the same layer lies within `coupled_gap` edge to edge.
50struct PairStats {
51 std::string net_a, net_b;
52 double length_a = 0, length_b = 0; // track length, nm
53 double coupled_a = 0, coupled_b = 0; // coupled track length, nm
54 int vias_a = 0, vias_b = 0;
55 double gap_min = 0, gap_median = 0; // edge gap over coupled samples, nm (0 when nothing is coupled)
56 double coupled_share() const { return length_a + length_b > 0 ? (coupled_a + coupled_b) / (length_a + length_b) : 0.0; }
57 double skew() const { return length_a > length_b ? length_a - length_b : length_b - length_a; }
58};
59// Edge gap up to which a sample counts as coupled: the pair's gap plus a quarter of it (at least 50 um), so lattice
60// rounding and the miter at bends do not count as uncoupled while a single track wandering off does.
61inline Coord coupled_threshold(const PairRule& r) { return r.gap + std::max<Coord>(r.gap / 4, 50'000); }
62PairStats measure_pair(const std::vector<model::Track>& tracks, const std::vector<model::Via>& vias, model::NetId a, model::NetId c,
63 Coord coupled_gap);
64
65// Net pairs KiCad treats as differential pairs (names ending in P/N or +/-), in net order.
66std::vector<std::pair<model::NetId, model::NetId>> named_pairs(const model::Board& b, const drc::RuleEngine& re);
67
68} // namespace tmk::route
The board model (design doc 02 §3): every object TraceMaker reads from a .kicad_pcb,...
compiled custom-rule condition
std::int32_t NetId
0 = no net
Definition board.hpp:21
PairStats measure_pair(const std::vector< model::Track > &tracks, const std::vector< model::Via > &vias, model::NetId a, model::NetId c, Coord coupled_gap)
geom::Point offset_point(geom::Point p, Dir2 v, double s)
p + s * v, rounded half away from zero (KiCad's KiROUND), so offsets are symmetric about the centreli...
PairRule pair_rule(const model::Board &b, const model::DesignRules &rules, const drc::RuleEngine &re, model::NetId a, model::NetId c, Coord via_mask=0)
via_mask: solder-mask expansion of untented vias (route::Obstacles::via_mask()); two vias then need t...
geom::Point miter_point(geom::Point c, int d1, int d2, double s)
Miter corner of a polyline offset by s (signed: + left) where the centreline turns from direction d1 ...
Dir2 unit_dir(int d)
std::vector< std::pair< model::NetId, model::NetId > > named_pairs(const model::Board &b, const drc::RuleEngine &re)
Net pairs KiCad treats as differential pairs (names ending in P/N or +/-), in net order.
Coord coupled_threshold(const PairRule &r)
Edge gap up to which a sample counts as coupled: the pair's gap plus a quarter of it (at least 50 um)...
Definition diff_pair.hpp:61
Dir2 left_normal(int d)
std::int64_t Coord
Engine coordinate: signed 64-bit nanometres.
Definition units.hpp:12
Integer-nanometre points and KiCad-compatible rotation.
Resolves KiCad constraints for pairs of copper items (design doc 03 §6): net-class clearances,...
Design rules as KiCad defines them (design doc 08 §3–4): board minimums and net classes from the ....
Octilinear unit direction d (0..7, E, NE, N, NW, W, SW, S, SE with y down) and its left normal,...
Definition diff_pair.hpp:40
What a pair is routed at.
Definition diff_pair.hpp:23
Coord gap
edge-to-edge gap of the coupled section (target; >= required)
Definition diff_pair.hpp:25
Coord via_offset
centreline to each via centre in a coupled via pair (>= offset)
Definition diff_pair.hpp:29
Coord width
track width of each half
Definition diff_pair.hpp:24
std::optional< Coord > max_uncoupled
per half, both ends together
Definition diff_pair.hpp:30
Coord required_gap
smallest gap the rules allow between the halves
Definition diff_pair.hpp:26
std::string source
"rule", "net class" or "clearance" (for the report)
Definition diff_pair.hpp:31
Coord offset
centreline to each track centre: (width + gap) / 2, rounded up, plus a rounding margin
Definition diff_pair.hpp:27
A routed pair, measured on its tracks: a sample of one half counts as coupled where a parallel track ...
Definition diff_pair.hpp:50
double coupled_share() const
Definition diff_pair.hpp:56
double skew() const
Definition diff_pair.hpp:57
double gap_median
edge gap over coupled samples, nm (0 when nothing is coupled)
Definition diff_pair.hpp:55
double length_b
track length, nm
Definition diff_pair.hpp:52
double coupled_b
coupled track length, nm
Definition diff_pair.hpp:53