TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
bus.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// Buses (design doc 05 §38): groups of nets that belong together (a data bus, an address bus, a parallel display
4// interface). This file holds what does not need the router: how a group is named on the command line, how groups
5// are found in the net names, which skew limit the board's rules give a group, and the measurement of a routed
6// group. The routing of a group lives in the router (route/router.cpp, "buses").
7#include <optional>
8#include <string>
9#include <string_view>
10#include <vector>
11
12#include "drc/length.hpp"
13#include "drc/rule_engine.hpp"
14#include "model/board.hpp"
15#include "model/rules.hpp"
16
17namespace tmk::route {
18
19struct BusGroup {
20 std::string name;
21 std::vector<model::NetId> members; // in bus order: natural sort of the net names (D2 before D10)
22 std::string source; // "option" (--bus) or "detected" (--buses)
23 Coord skew_limit = 0; // largest allowed difference in length between members; 0 = none
24 std::string skew_source; // "rule" (a custom skew rule of the board), "option" (--bus-skew-mm) or empty
25};
26
27// Natural order of two names: runs of digits compare as numbers, everything else byte by byte.
28bool natural_less(std::string_view a, std::string_view b);
29
30// Bus patterns select nets by their full name (KiCad's, with the sheet path: "/D0", "/MEM/DQ3").
31// [N-M] or [N..M], N <= M decimal numbers: an index range, matching any decimal number in it ("D[0-15]" matches
32// D0 .. D15, and D07 too). A range needs both bounds; "[[0-7]]" is a range in literal brackets,
33// for nets named A[0] .. A[7].
34// * and ?: as in KiCad's net-class patterns (any run of characters, any one character).
35// A pattern without an index range is matched exactly as a KiCad net-class pattern (model::pattern_match: wildcards,
36// or a full regular expression). In a pattern with a range everything outside the range and the wildcards is literal.
37bool bus_pattern_match(const std::string& pattern, const std::string& net_name);
38
39// "NAME=PATTERN" as given to --bus. Throws std::runtime_error when there is no '=', the name or pattern is empty, or
40// fewer than two nets with pads match.
41BusGroup bus_from_option(const model::Board& b, const std::string& spec);
42
43// Automatic detection (--buses), conservative: nets whose names differ only in a trailing decimal index ("D0", "A[3]",
44// "/MEM/DQ12"), at least `min_members` of them with pads on the same two components. KiCad's generated names
45// ("Net-(U1-Pad3)", "unconnected-...") are never grouped. One stem may give several groups (D0-7 to one memory,
46// D8-15 to another); they are then named STEM(REF-REF). Groups come in natural order of their names.
47std::vector<BusGroup> detect_buses(const model::Board& b, int min_members = 4);
48
49// The skew limit the board's custom rules give a group: every member must match a rule with a `skew` constraint
50// (the smallest maximum wins); rules restricted to differential pairs (`within_diff_pairs`) do not count.
51std::optional<Coord> bus_rule_skew(const drc::RuleEngine& re, const BusGroup& g);
52
53// What a via adds to a net's length (drc/length.hpp, where KiCad's length check lives).
54using drc::ViaHeights;
56// The via length of one net on the given copper, as KiCad sums it: each via counts between the outermost layers on
57// which a track of the net ends inside the via's pad, or a pad of the net touches the via (a surface pad's own
58// layer, its footprint's side for a through-hole pad); a via that joins nothing on a second layer adds nothing.
59double net_via_length(const model::Board& b, const ViaHeights& vh, model::NetId net, const std::vector<model::Track>& tracks,
60 const std::vector<model::ArcTrack>& arcs, const std::vector<model::Via>& vias);
61
62// A group as routed, measured on copper. Length is what KiCad's skew check compares: track length (arcs included)
63// plus the via length above, so a member with more vias than the others is longer by their height. KiCad also
64// adds pad-to-die lengths and shortens a track end inside a pad or via; neither is modelled (micrometres, or zero).
65struct BusMember {
67 bool routed = false; // every pad of the net is joined
68 double length = 0; // nm, tracks and vias
69 double via_length = 0; // nm, the vias' part of `length`
70 int vias = 0;
71 model::LayerMask layers = 0; // copper layers carrying tracks of the net
72 bool followed = false; // routed with the group's reference via count and layers
73};
74struct BusStats {
75 std::vector<BusMember> members; // group order
76 int routed = 0;
77 // The reference is the via count and layer set most members share (ties: the first member's in group order).
78 // `followed` members have exactly that; `left` are routed otherwise ("left the bus").
79 int followed = 0, left = 0;
80 int ref_vias = 0;
82 int vias_min = 0, vias_max = 0; // over routed members
83 double length_min = 0, length_max = 0;
84 double skew() const { return length_max - length_min; } // over routed members
85};
86// `net_routed[net]`: nets_joined() of the board the copper belongs to; `b` gives the pads, `vh` its via heights.
87BusStats measure_bus(const model::Board& b, const ViaHeights& vh, const std::vector<model::Track>& tracks, const std::vector<model::ArcTrack>& arcs, const std::vector<model::Via>& vias,
88 const std::vector<std::uint8_t>& net_routed, const BusGroup& g);
89
90// Per net: 1 when all its pads are joined by copper (the router's own connectivity; nets without pads count as joined).
91std::vector<std::uint8_t> nets_joined(const model::Board& b, const model::DesignRules& rules);
92
93} // namespace tmk::route
The board model (design doc 02 §3): every object TraceMaker reads from a .kicad_pcb,...
Net length and propagation delay as KiCad 10.0.6 measures them for its length and skew checks (design...
ViaHeights via_heights(const model::Board &b, const model::DesignRules &rules)
std::int32_t NetId
0 = no net
Definition board.hpp:21
std::uint64_t LayerMask
bit i = copper layer i in stack order (0 = F.Cu, last = B.Cu)
Definition board.hpp:22
std::optional< Coord > bus_rule_skew(const drc::RuleEngine &re, const BusGroup &g)
The skew limit the board's custom rules give a group: every member must match a rule with a skew cons...
BusStats measure_bus(const model::Board &b, const ViaHeights &vh, const std::vector< model::Track > &tracks, const std::vector< model::ArcTrack > &arcs, const std::vector< model::Via > &vias, const std::vector< std::uint8_t > &net_routed, const BusGroup &g)
net_routed[net]: nets_joined() of the board the copper belongs to; b gives the pads,...
BusGroup bus_from_option(const model::Board &b, const std::string &spec)
"NAME=PATTERN" as given to –bus.
std::vector< BusGroup > detect_buses(const model::Board &b, int min_members=4)
Automatic detection (–buses), conservative: nets whose names differ only in a trailing decimal index ...
bool bus_pattern_match(const std::string &pattern, const std::string &net_name)
Bus patterns select nets by their full name (KiCad's, with the sheet path: "/D0", "/MEM/DQ3").
std::vector< std::uint8_t > nets_joined(const model::Board &b, const model::DesignRules &rules)
Per net: 1 when all its pads are joined by copper (the router's own connectivity; nets without pads c...
bool natural_less(std::string_view a, std::string_view b)
Natural order of two names: runs of digits compare as numbers, everything else byte by byte.
double net_via_length(const model::Board &b, const ViaHeights &vh, model::NetId net, const std::vector< model::Track > &tracks, const std::vector< model::ArcTrack > &arcs, const std::vector< model::Via > &vias)
The via length of one net on the given copper, as KiCad sums it: each via counts between the outermos...
std::int64_t Coord
Engine coordinate: signed 64-bit nanometres.
Definition units.hpp:12
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 ....
The length a via adds to its net in KiCad's length calculation (KiCad 10, BOARD_STACKUP::GetLayerDist...
Definition length.hpp:18
Coord skew_limit
largest allowed difference in length between members; 0 = none
Definition bus.hpp:23
std::string source
"option" (–bus) or "detected" (–buses)
Definition bus.hpp:22
std::string skew_source
"rule" (a custom skew rule of the board), "option" (–bus-skew-mm) or empty
Definition bus.hpp:24
std::string name
Definition bus.hpp:20
std::vector< model::NetId > members
in bus order: natural sort of the net names (D2 before D10)
Definition bus.hpp:21
A group as routed, measured on copper.
Definition bus.hpp:65
model::NetId net
Definition bus.hpp:66
model::LayerMask layers
copper layers carrying tracks of the net
Definition bus.hpp:71
bool routed
every pad of the net is joined
Definition bus.hpp:67
double via_length
nm, the vias' part of length
Definition bus.hpp:69
bool followed
routed with the group's reference via count and layers
Definition bus.hpp:72
double length
nm, tracks and vias
Definition bus.hpp:68
int followed
The reference is the via count and layer set most members share (ties: the first member's in group or...
Definition bus.hpp:79
double length_min
Definition bus.hpp:83
double length_max
Definition bus.hpp:83
int vias_max
over routed members
Definition bus.hpp:82
model::LayerMask ref_layers
Definition bus.hpp:81
double skew() const
Definition bus.hpp:84
std::vector< BusMember > members
group order
Definition bus.hpp:75