|
1 | 1 | #pragma once |
2 | 2 |
|
3 | 3 | #include <string> |
| 4 | +#include <vector> |
4 | 5 |
|
| 6 | +#include "switchblock_types.h" |
| 7 | + |
| 8 | +/// @brief The topology of a dedicated clock network, as declared by a <clock_network>'s type attribute. |
5 | 9 | enum class e_clock_type { |
6 | | - SPINE, |
7 | | - RIB, |
8 | | - H_TREE |
| 10 | + SPINE, ///< A single horizontal wire, tapped by vertical spines (see e_clock_type::RIB below). |
| 11 | + RIB, ///< A single vertical wire, tapped from/tapping into horizontal spines. |
| 12 | + H_TREE, ///< Not yet implemented. |
| 13 | + SWITCH_GRID ///< A grid of clock switch boxes; see t_clock_switch_grid_arch. |
9 | 14 | }; |
10 | 15 |
|
| 16 | +/// @brief Metal layer electrical properties for a clock network's wires. |
11 | 17 | struct t_metal_layer { |
12 | | - float r_metal; |
13 | | - float c_metal; |
| 18 | + float r_metal; ///< Resistance per unit length. |
| 19 | + float c_metal; ///< Capacitance per unit length. |
14 | 20 | }; |
15 | 21 |
|
| 22 | +/// @brief How a rib/spine's wire repeats (tiles) across the device. |
16 | 23 | struct t_wire_repeat { |
17 | | - std::string x; |
18 | | - std::string y; |
| 24 | + std::string x; ///< Repeat pitch in the x direction. |
| 25 | + std::string y; ///< Repeat pitch in the y direction. |
| 26 | + |
| 27 | + /// @brief Upper bound for how far this network repeats, in whichever axis is its own |
| 28 | + /// tiling direction (x for a spine's column-tiling repeatx, y for a rib's row-tiling |
| 29 | + /// repeaty). Defaults to the full device width/height, preserving the "tile all the way |
| 30 | + /// to the device edge" behavior; a smaller bound lets a rib/spine repeat within only part |
| 31 | + /// of the device (e.g. one clock quadrant) instead of needing a network that spans the |
| 32 | + /// whole device and is shared/cheated across quadrants. |
| 33 | + std::string end_x = "W"; |
| 34 | + std::string end_y = "H"; |
19 | 35 | }; |
20 | 36 |
|
| 37 | +/// @brief The extent of a single rib/spine wire segment. |
21 | 38 | struct t_wire { |
22 | | - std::string start; |
23 | | - std::string end; |
24 | | - std::string position; |
| 39 | + std::string start; ///< Start coordinate along the wire's own axis. |
| 40 | + std::string end; ///< End coordinate along the wire's own axis. |
| 41 | + std::string position; ///< Coordinate along the wire's perpendicular axis. |
25 | 42 | }; |
26 | 43 |
|
| 44 | +/// @brief Where and how a rib/spine is driven from another clock network. |
27 | 45 | struct t_clock_drive { |
28 | | - std::string name; |
29 | | - std::string offset; |
30 | | - int arch_switch_idx; |
| 46 | + std::string name; ///< Name of the switch point other networks connect to when driving this one. |
| 47 | + std::string offset; ///< Coordinate, along the wire's own axis, of the drive point. |
| 48 | + int arch_switch_idx; ///< Index into the architecture's switch list of the driving switch. |
31 | 49 | }; |
32 | 50 |
|
| 51 | +/// @brief Where and how often a rib/spine exposes tap points to other clock networks. |
33 | 52 | struct t_clock_taps { |
34 | | - std::string name; |
35 | | - std::string offset; |
36 | | - std::string increment; |
| 53 | + std::string name; ///< Name of the switch point other networks tap into. |
| 54 | + std::string offset; ///< Coordinate, along the wire's own axis, of the first tap. |
| 55 | + std::string increment; ///< Spacing between repeated taps; empty/absent means a single tap. |
| 56 | +}; |
| 57 | + |
| 58 | +/// @brief Whether a <switch_point> in a <clock_switch_grid> is a drive or a tap point. |
| 59 | +enum class e_clock_switch_grid_point_type { |
| 60 | + DRIVE, |
| 61 | + TAP |
| 62 | +}; |
| 63 | + |
| 64 | +/// @brief A single <switch_point> entry within a <clock_switch_grid>. Unlike the rib/spine |
| 65 | +/// drive/tap, offsets are 2D (a switch box location on the grid) and multiple drive and/or |
| 66 | +/// tap points are allowed. |
| 67 | +struct t_clock_switch_grid_point { |
| 68 | + std::string name; ///< Name other clock connections reference this point by. |
| 69 | + e_clock_switch_grid_point_type type; ///< DRIVE or TAP. |
| 70 | + std::string xoffset; ///< Switch box column this point sits at. |
| 71 | + std::string yoffset; ///< Switch box row this point sits at. |
| 72 | + |
| 73 | + /// @brief Repeat this tap point across the grid every xincr/yincr switch boxes (like the |
| 74 | + /// rib/spine tap xincr/yincr), instead of at just one location. "0" (the default) means no |
| 75 | + /// repeat, i.e. a single point. Only meaningful for TAP points; DRIVE points are always a |
| 76 | + /// single location. |
| 77 | + std::string xincr = "0"; |
| 78 | + std::string yincr = "0"; |
| 79 | + |
| 80 | + int arch_switch_idx = -1; ///< Index into the architecture's switch list; only set for DRIVE points. |
| 81 | +}; |
| 82 | + |
| 83 | +/// @brief One <switch_pattern> under a custom clock_switch_grid: which built-in switch-block |
| 84 | +/// permutation type applies, and where. Formula strings are resolved later (setup_clocks.cpp) |
| 85 | +/// against the same W/H vars as the rest of this grid. This is the same deferred-formula convention as |
| 86 | +/// startx/repeatx/chan_w below, so this still works with "auto" device layouts (general |
| 87 | +/// routing's own <switchblock_location> XY_SPECIFIED explicitly rejects "auto" layouts; clock |
| 88 | +/// networks don't need that restriction). Fully independent of general routing's |
| 89 | +/// <switchblocklist>/<switch_block type="custom">: different XML location, different struct, |
| 90 | +/// no shared namespace. |
| 91 | +struct t_clock_switch_pattern { |
| 92 | + std::string name; ///< Name for error messages; not otherwise referenced. |
| 93 | + e_switch_block_type switch_block_type; ///< WILTON/SUBSET/UNIVERSAL/FULL/CUSTOM. |
| 94 | + e_sb_location location = e_sb_location::E_EVERYWHERE; ///< Which switch boxes this pattern applies to. |
| 95 | + |
| 96 | + // Only meaningful when location == E_XY_SPECIFIED. |
| 97 | + std::string x, y; ///< Exact location; empty means "use the region below". |
| 98 | + std::string startx = "0", endx = "W-1", repeatx = "0", incrx = "1"; ///< X region, when location == E_XY_SPECIFIED and x/y are empty. |
| 99 | + std::string starty = "0", endy = "H-1", repeaty = "0", incry = "1"; ///< Y region, when location == E_XY_SPECIFIED and x/y are empty. |
| 100 | + |
| 101 | + /// @brief Turn permutation formulas parsed from this pattern's <switchfuncs> child, reusing |
| 102 | + /// general routing's own <switchblock> grammar/types verbatim (see parse_switchblocks.h's |
| 103 | + /// read_sb_switchfuncs/t_permutation_map). Formulas stay as strings here; t/W are only |
| 104 | + /// known per-track at RR-graph build time, same as general routing. Only meaningful when |
| 105 | + /// switch_block_type == CUSTOM. |
| 106 | + t_permutation_map permutation_map; |
| 107 | +}; |
| 108 | + |
| 109 | +/// @brief Architecture description of a grid of clock switch boxes: at every |
| 110 | +/// (repeatx, repeaty)-spaced location, clock wires connect to their adjacent switch boxes' |
| 111 | +/// wires according to switch_block_type (or switch_patterns, if CUSTOM). |
| 112 | +struct t_clock_switch_grid_arch { |
| 113 | + std::string metal_layer; ///< Name of the metal layer this grid's wires are drawn on. |
| 114 | + std::string startx; ///< X coordinate of the grid's first switch box. |
| 115 | + std::string starty; ///< Y coordinate of the grid's first switch box. |
| 116 | + std::string repeatx; ///< Switch box column pitch. |
| 117 | + std::string repeaty; ///< Switch box row pitch. |
| 118 | + std::string chan_w; ///< Number of tracks per inter-switch-box wire segment. |
| 119 | + std::string switch_name; ///< Name of the switch used for wire-to-wire connections within a switch box. |
| 120 | + int arch_switch_idx = -1; ///< Index into the architecture's switch list, resolved from switch_name. |
| 121 | + |
| 122 | + /// @brief How the wires incident to each switch box connect to one another. Defaults to |
| 123 | + /// FULL (every incident wire mutually reachable), matching the original minimal |
| 124 | + /// implementation. CUSTOM picks a per-location built-in type from switch_patterns below |
| 125 | + /// instead of a single type for the whole grid. |
| 126 | + e_switch_block_type switch_block_type = e_switch_block_type::FULL; |
| 127 | + |
| 128 | + /// @brief Only populated when switch_block_type == CUSTOM. Matched in list order; first |
| 129 | + /// match wins. |
| 130 | + std::vector<t_clock_switch_pattern> switch_patterns; |
| 131 | + |
| 132 | + /// @brief Wire length, in switch-box hops (not tiles), i.e. how many repeatx/repeaty |
| 133 | + /// pitches a hop wire spans before terminating at a switch box. Defaults to "1", matching |
| 134 | + /// the original one-hop-per-switch-box implementation. Expressed in hop units (rather than |
| 135 | + /// tiles) so it stays independent of repeatx/repeaty: changing the switch-box pitch doesn't |
| 136 | + /// require also rescaling length to keep the same topology. |
| 137 | + std::string length = "1"; |
| 138 | + |
| 139 | + /// @brief Whether the grid's hop wires are BI_DIRECTIONAL (one node per track, entered and |
| 140 | + /// exited from either end) or UNI_DIRECTIONAL (each track flows one way, like general |
| 141 | + /// routing's unidirectional segments). Unidirectional requires an even chan_w (half the |
| 142 | + /// tracks INC, half DEC). Required in the arch XML, matching how <segment type=.../> works |
| 143 | + /// in general routing. |
| 144 | + e_directionality directionality = BI_DIRECTIONAL; |
| 145 | + |
| 146 | + std::vector<t_clock_switch_grid_point> switch_points; ///< This grid's <switch_point> drive/tap entries. |
37 | 147 | }; |
38 | 148 |
|
| 149 | +/// @brief Architecture description of one <clock_network>, as parsed from the arch XML. |
39 | 150 | struct t_clock_network_arch { |
40 | | - std::string name; |
41 | | - int num_inst; |
| 151 | + std::string name; ///< Unique name, referenced by <clock_routing> connections. |
| 152 | + int num_inst; ///< Number of instances of this network to create (e.g. one per clock quadrant). |
| 153 | + |
| 154 | + e_clock_type type; ///< SPINE, RIB, H_TREE, or SWITCH_GRID; determines which of the fields below apply. |
42 | 155 |
|
43 | | - e_clock_type type; |
| 156 | + std::string metal_layer; ///< Name of the metal layer this network's wire is drawn on. Unused when type == SWITCH_GRID. |
| 157 | + t_wire wire; ///< Wire extent. Unused when type == SWITCH_GRID. |
| 158 | + t_wire_repeat repeat; ///< Repeat/tiling parameters. Unused when type == SWITCH_GRID. |
| 159 | + t_clock_drive drive; ///< Drive point. Unused when type == SWITCH_GRID. |
| 160 | + t_clock_taps tap; ///< Tap point(s). Unused when type == SWITCH_GRID. |
44 | 161 |
|
45 | | - std::string metal_layer; |
46 | | - t_wire wire; |
47 | | - t_wire_repeat repeat; |
48 | | - t_clock_drive drive; |
49 | | - t_clock_taps tap; |
| 162 | + t_clock_switch_grid_arch switch_grid; ///< Switch grid parameters; only used when type == SWITCH_GRID. |
50 | 163 | }; |
51 | 164 |
|
| 165 | +/// @brief Architecture description of one <clock_routing> connection, wiring a clock network's |
| 166 | +/// tap/drive point either to/from general-purpose routing or to/from another clock network. |
52 | 167 | struct t_clock_connection_arch { |
53 | | - std::string from; |
54 | | - std::string to; |
55 | | - int arch_switch_idx; |
56 | | - std::string locationx; |
57 | | - std::string locationy; |
58 | | - float fc; |
| 168 | + std::string from; ///< Source: a clock network's switch point name, or a routing/tile pin reference. |
| 169 | + std::string to; ///< Destination: a clock network's switch point name, or a routing/tile pin reference. |
| 170 | + int arch_switch_idx; ///< Index into the architecture's switch list of the connecting switch. |
| 171 | + std::string locationx; ///< X coordinate this connection is made at. |
| 172 | + std::string locationy; ///< Y coordinate this connection is made at. |
| 173 | + float fc; ///< Fraction of source tracks/pins each destination connects to. |
59 | 174 | }; |
0 commit comments