TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
global_router.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// Global routing on a coarse 3-D tile graph (design doc 05 §4 and §19, roadmap M6; CPU, the only path: §19 shows
4// why there is no GPU version).
5//
6// The board is cut into square tiles about eight track pitches wide. Each tile edge on each copper layer gets a
7// capacity: how many tracks fit across the narrowest cut between the two tile centres, measured with the exact
8// obstacle model; each tile gets a via capacity (free via sites). Every two-pin connection is routed on the tile
9// graph with A* (length + via cost + congestion), then negotiated congestion (PathFinder: McMurchie and Ebeling,
10// FPGA 1995) rips up connections on overflowed edges or via tiles and re-routes them with growing history costs.
11// Connections of one net share edges: an edge carries a net once however many of its connections use it, and a
12// connection pays no congestion on an edge its net already holds, so a net's connections merge into a tree with
13// shared trunks (the demand side of a Steiner topology). All costs are integers. The result is a corridor per
14// connection: the tiles of its path on the layers it uses, widened by one tile, which the detailed router uses as
15// soft guidance.
16#include <array>
17#include <cstdint>
18#include <vector>
19
20#include "core/units.hpp"
21#include "geom/point.hpp"
22#include "model/board.hpp"
23
24namespace tmk::route {
25
26class Obstacles;
27
28struct GlobalNet { // one two-pin connection
30 model::LayerMask layers_a = 0, layers_b = 0; // copper layers each end can start on
32 int net = 0; // connections with the same net (> 0) share edges; 0 = shares with nothing
33 geom::Box box_a, box_b; // copper of the two end pads (cut lines: which side of a line an end is on)
34};
35
37 Coord tile = 0; // tile size; 0 = 8 x (narrowest width + clearance), clamped to 1.5..5 mm
38 Coord pitch = 0; // track pitch (width + clearance) used for capacities
39 double via_cost_tiles = 2.0; // cost of a via, in tile lengths
40 int iterations = 8; // negotiation rounds after the first pass
41 Coord via_diameter = 0, via_drill = 0; // via used for the via capacity of a tile; 0 = no via capacity
42 // Every pad of the nets being routed, as (net, copper box): a pad that straddles a cut line carries its net
43 // across without a track, so that net is not counted there.
44 std::vector<std::pair<int, geom::Box>> pads;
45 Coord via_pitch = 0; // spacing of the via sites sampled in a tile (via diameter + clearance)
46};
47
48// A straight line across the whole board and what has to cross it (escalation rung R6, doc 05 §20; the cut argument
49// of Maley, "Single-Layer Wire Routing and Compaction", 1990, at the resolution of the capacity samples). Every net
50// with a planned connection whose two end pads lie wholly on opposite sides, and no pad across the line, crosses it at
51// least once, on some layer; `capacity` is an upper bound of the tracks
52// that fit across it on all layers past the fixed copper. demand > capacity proves the placement unroutable.
53struct CutLine {
54 bool vertical = true; // a line x = at (false: y = at)
55 Coord at = 0;
56 int capacity = 0, demand = 0;
57};
58
60 int tiles_x = 0, tiles_y = 0, layers = 0;
63 // corridor[k][(l * tiles_y + ty) * tiles_x + tx] != 0: tile on layer l is in connection k's corridor.
64 std::vector<std::vector<std::uint8_t>> corridor;
65 // Bounding box of each corridor in tiles (x0, y0, x1, y1, inclusive); the detailed router's confined window.
66 std::vector<std::array<int, 4>> corridor_box;
67 std::vector<int> vias; // global vias per connection
68 // util[(l * tiles_y + ty) * tiles_x + tx]: planned tracks through the tile's four boundaries on layer l, in
69 // eighths of their capacity (8 = full, capped at 255). The detailed router's congestion map.
70 std::vector<std::uint8_t> util;
71 int overflow_edges = 0; // edges still over capacity after negotiation
73 int overflow_via_tiles = 0; // tiles with more planned vias than free via sites
74 std::vector<CutLine> over_cuts; // lines with demand > capacity, tightest line of each over-full tile boundary
75 CutLine tightest; // the line with the highest demand / capacity (capacity 0 counts as over-full)
76 double seconds_capacity = 0, seconds_route = 0; // set-up (obstacle sampling) and routing + negotiation
77 int tile_of_x(Coord x) const { return static_cast<int>((x - origin.x) / tile); }
78 int tile_of_y(Coord y) const { return static_cast<int>((y - origin.y) / tile); }
79};
80
81GlobalResult global_route(const Obstacles& obs, const geom::Box& bounds, int layers, const std::vector<GlobalNet>& nets,
82 const GlobalOptions& opt);
83
84} // namespace tmk::route
The board model (design doc 02 §3): every object TraceMaker reads from a .kicad_pcb,...
std::uint64_t LayerMask
bit i = copper layer i in stack order (0 = F.Cu, last = B.Cu)
Definition board.hpp:22
GlobalResult global_route(const Obstacles &obs, const geom::Box &bounds, int layers, const std::vector< GlobalNet > &nets, const GlobalOptions &opt)
std::int64_t Coord
Engine coordinate: signed 64-bit nanometres.
Definition units.hpp:12
Integer-nanometre points and KiCad-compatible rotation.
A straight line across the whole board and what has to cross it (escalation rung R6,...
bool vertical
a line x = at (false: y = at)
geom::Box box_b
copper of the two end pads (cut lines: which side of a line an end is on)
int net
connections with the same net (> 0) share edges; 0 = shares with nothing
model::LayerMask layers_b
copper layers each end can start on
model::LayerMask layers_a
geom::Point a
< one two-pin connection
Coord pitch
track pitch (width + clearance) used for capacities
Coord tile
tile size; 0 = 8 x (narrowest width + clearance), clamped to 1.5..5 mm
Coord via_pitch
spacing of the via sites sampled in a tile (via diameter + clearance)
double via_cost_tiles
cost of a via, in tile lengths
int iterations
negotiation rounds after the first pass
std::vector< std::pair< int, geom::Box > > pads
Every pad of the nets being routed, as (net, copper box): a pad that straddles a cut line carries its...
Coord via_drill
via used for the via capacity of a tile; 0 = no via capacity
std::vector< int > vias
global vias per connection
double seconds_route
set-up (obstacle sampling) and routing + negotiation
std::vector< std::array< int, 4 > > corridor_box
Bounding box of each corridor in tiles (x0, y0, x1, y1, inclusive); the detailed router's confined wi...
int tile_of_y(Coord y) const
CutLine tightest
the line with the highest demand / capacity (capacity 0 counts as over-full)
int overflow_via_tiles
tiles with more planned vias than free via sites
std::vector< CutLine > over_cuts
lines with demand > capacity, tightest line of each over-full tile boundary
int overflow_edges
edges still over capacity after negotiation
std::vector< std::vector< std::uint8_t > > corridor
corridor[k][(l * tiles_y + ty) * tiles_x + tx] != 0: tile on layer l is in connection k's corridor.
int tile_of_x(Coord x) const
std::vector< std::uint8_t > util
util[(l * tiles_y + ty) * tiles_x + tx]: planned tracks through the tile's four boundaries on layer l...