4
4
#include " globals.h"
5
5
#include " vtr_log.h"
6
6
7
+ /* *
8
+ * @brief Definitions of global and helper routines related to printing RR node overuse info.
9
+ *
10
+ * All the global routines defined here are declared in the header file overuse_report.h
11
+ * The helper routines that are called by the global routine should stay local to this file.
12
+ * They provide subroutine hierarchy to allow easier customization of the logfile/report format.
13
+ */
14
+
7
15
static void report_overused_ipin_opin (std::ostream& os, RRNodeId node_id);
8
16
static void report_overused_chanx_chany (std::ostream& os, RRNodeId node_id);
9
17
static void report_overused_source_sink (std::ostream& os, RRNodeId node_id);
@@ -12,6 +20,12 @@ static void report_congested_nets(std::ostream& os, const std::set<ClusterNetId>
12
20
static void log_overused_nodes_header ();
13
21
static void log_single_overused_node_status (int overuse_index, RRNodeId inode);
14
22
23
+ /* *
24
+ * @brief Print out RR node overuse info in the VPR logfile.
25
+ *
26
+ * Print out limited amount of overused node info in the vpr.out logfile.
27
+ * The limit is specified by the VPR option --max_logged_overused_rr_nodes
28
+ */
15
29
void log_overused_nodes_status (int max_logged_overused_rr_nodes) {
16
30
const auto & device_ctx = g_vpr_ctx.device ();
17
31
const auto & route_ctx = g_vpr_ctx.routing ();
@@ -36,36 +50,43 @@ void log_overused_nodes_status(int max_logged_overused_rr_nodes) {
36
50
}
37
51
}
38
52
53
+ /* *
54
+ * @brief Print out RR node overuse info in a post-VPR report file.
55
+ *
56
+ * Print all the overused RR nodes' info in the report file report_overused_nodes.rpt.
57
+ * The report generation is turned on by the VPR option: --generate_rr_node_overuse_report on.
58
+ */
39
59
void report_overused_nodes () {
40
60
const auto & device_ctx = g_vpr_ctx.device ();
41
61
const auto & route_ctx = g_vpr_ctx.routing ();
42
62
43
- // Generate overuse info lookup table
63
+ /* Generate overuse info lookup table */
44
64
std::map<RRNodeId, std::set<ClusterNetId>> nodes_to_nets_lookup;
45
65
generate_overused_nodes_to_congested_net_lookup (nodes_to_nets_lookup);
46
66
47
- // Open the report file
67
+ /* Open the report file and print header info */
48
68
std::ofstream os (" report_overused_nodes.rpt" );
49
69
os << " Overused nodes information report on the final failed routing attempt" << ' \n ' ;
50
70
os << " Total number of overused nodes = " << nodes_to_nets_lookup.size () << ' \n ' ;
51
71
72
+ /* Go through each rr node and the nets that pass through it */
52
73
size_t inode = 0 ;
53
74
for (const auto & lookup_pair : nodes_to_nets_lookup) {
54
75
const RRNodeId node_id = lookup_pair.first ;
55
76
const auto & congested_nets = lookup_pair.second ;
56
77
57
- os << " ************************************************\n\n " ; // RR Node Separation line
78
+ os << " ************************************************\n\n " ; // Separation line
58
79
59
- // Report Basic info
80
+ /* Report basic rr node info */
60
81
os << " Overused RR node #" << inode << ' \n ' ;
61
82
os << " Node id = " << size_t (node_id) << ' \n ' ;
62
83
os << " Occupancy = " << route_ctx.rr_node_route_inf [size_t (node_id)].occ () << ' \n ' ;
63
84
os << " Capacity = " << device_ctx.rr_nodes .node_capacity (node_id) << " \n\n " ;
64
85
65
- // Report Selective info
86
+ /* Report selective info based on the rr node type */
87
+ auto node_type = device_ctx.rr_nodes .node_type (node_id);
66
88
os << " Node type = " << device_ctx.rr_nodes .node_type_string (node_id) << ' \n ' ;
67
89
68
- auto node_type = device_ctx.rr_nodes .node_type (node_id);
69
90
switch (node_type) {
70
91
case IPIN:
71
92
case OPIN:
@@ -84,7 +105,9 @@ void report_overused_nodes() {
84
105
break ;
85
106
}
86
107
87
- os << " -----------------------------\n " ; // Node/net info separation line
108
+ /* Finished printing the node info. Now print out the *
109
+ * info on the nets passing through this overused node */
110
+ os << " -----------------------------\n " ; // Separation line
88
111
report_congested_nets (os, congested_nets);
89
112
90
113
++inode;
@@ -93,6 +116,15 @@ void report_overused_nodes() {
93
116
os.close ();
94
117
}
95
118
119
+ /* *
120
+ * @brief Generate a overused RR nodes to congested nets lookup table.
121
+ *
122
+ * Uses map data structure to store a lookup table that matches RR nodes
123
+ * to the nets that pass through them. Only overused nodes and congested
124
+ * nets will be recorded.
125
+ *
126
+ * This routine goes through the trace back linked list of each net.
127
+ */
96
128
void generate_overused_nodes_to_congested_net_lookup (std::map<RRNodeId, std::set<ClusterNetId>>& nodes_to_nets_lookup) {
97
129
const auto & device_ctx = g_vpr_ctx.device ();
98
130
const auto & route_ctx = g_vpr_ctx.routing ();
@@ -112,6 +144,7 @@ void generate_overused_nodes_to_congested_net_lookup(std::map<RRNodeId, std::set
112
144
}
113
145
}
114
146
147
+ // /@brief Print out information specific to IPIN/OPIN type rr nodes
115
148
static void report_overused_ipin_opin (std::ostream& os, RRNodeId node_id) {
116
149
const auto & device_ctx = g_vpr_ctx.device ();
117
150
const auto & place_ctx = g_vpr_ctx.placement ();
@@ -128,33 +161,47 @@ static void report_overused_ipin_opin(std::ostream& os, RRNodeId node_id) {
128
161
// Add block type for IPINs/OPINs in overused rr-node report
129
162
const auto & clb_nlist = g_vpr_ctx.clustering ().clb_nlist ;
130
163
auto & grid_info = place_ctx.grid_blocks [grid_x][grid_y];
131
- auto & grid_blocks = grid_info.blocks ;
132
164
133
165
os << " Grid location: X = " << grid_x << " , Y = " << grid_y << ' \n ' ;
134
- os << " Number of blocks currently at this grid location = " << grid_info.usage << ' \n ' ;
135
- for (size_t iblock = 0 ; iblock < grid_blocks.size (); ++iblock) {
136
- ClusterBlockId block_id = grid_blocks[iblock];
166
+ os << " Number of blocks currently occupying this grid location = " << grid_info.usage << ' \n ' ;
167
+
168
+ size_t iblock = 0 ;
169
+ for (size_t isubtile = 0 ; isubtile < grid_blocks.size (); ++isubtile) {
170
+ // Check if the block is empty
171
+ if (grid_info.subtile_empty [isubtile]) {
172
+ continue ;
173
+ }
174
+
175
+ // Print out the block index, name and type
176
+ ClusterBlockId block_id = grid_info.blocks [isubtile];
137
177
os << " Block #" << iblock << " : " ;
138
178
os << " Block name = " << clb_nlist.block_pb (block_id)->name << " , " ;
139
179
os << " Block type = " << clb_nlist.block_type (block_id)->name << ' \n ' ;
180
+ ++iblock;
140
181
}
141
182
}
142
183
184
+ // /@brief Print out information specific to CHANX/CHANY type rr nodes
143
185
static void report_overused_chanx_chany (std::ostream& os, RRNodeId node_id) {
144
186
const auto & device_ctx = g_vpr_ctx.device ();
145
187
146
188
os << " Track number = " << device_ctx.rr_nodes .node_track_num (node_id) << ' \n ' ;
147
189
os << " Direction = " << device_ctx.rr_nodes .node_direction_string (node_id) << " \n\n " ;
148
190
191
+ // CHANX/CHANY rr nodes span across several grid locations.
192
+ // Need to print out their starting and ending locations.
149
193
os << " Grid location: " << ' \n ' ;
150
194
os << " Xlow = " << device_ctx.rr_nodes .node_xlow (node_id) << " , " ;
151
195
os << " Ylow = " << device_ctx.rr_nodes .node_ylow (node_id) << ' \n ' ;
152
196
os << " Xhigh = " << device_ctx.rr_nodes .node_xhigh (node_id) << " , " ;
153
197
os << " Yhigh = " << device_ctx.rr_nodes .node_yhigh (node_id) << ' \n ' ;
198
+
199
+ // Print out associated RC characteristics as they will be non-zero
154
200
os << " Resistance = " << device_ctx.rr_nodes .node_R (node_id) << ' \n ' ;
155
201
os << " Capacitance = " << device_ctx.rr_nodes .node_C (node_id) << ' \n ' ;
156
202
}
157
203
204
+ // /@brief Print out information specific to SOURCE/SINK type rr nodes
158
205
static void report_overused_source_sink (std::ostream& os, RRNodeId node_id) {
159
206
const auto & device_ctx = g_vpr_ctx.device ();
160
207
@@ -168,7 +215,13 @@ static void report_overused_source_sink(std::ostream& os, RRNodeId node_id) {
168
215
os << " Grid location: X = " << grid_x << " , Y = " << grid_y << ' \n ' ;
169
216
}
170
217
171
- // Reported congested nets at a specific rr node
218
+ /* *
219
+ * @brief Print out info on congested nets in the router.
220
+ *
221
+ * Report information on the congested nets that pass through a specific rr node. *
222
+ * These nets are congested because the number of nets currently passing through *
223
+ * this rr node exceed the node's routing net capacity.
224
+ */
172
225
static void report_congested_nets (std::ostream& os, const std::set<ClusterNetId>& congested_nets) {
173
226
const auto & clb_nlist = g_vpr_ctx.clustering ().clb_nlist ;
174
227
os << " Number of nets passing through this RR node = " << congested_nets.size () << ' \n ' ;
@@ -186,6 +239,7 @@ static void report_congested_nets(std::ostream& os, const std::set<ClusterNetId>
186
239
os << ' \n ' ;
187
240
}
188
241
242
+ // /@brief Print out the header of the overused rr node info in the logfile
189
243
static void log_overused_nodes_header () {
190
244
VTR_LOG (" Routing Failure Diagnostics: Printing Overused Nodes Information\n " );
191
245
VTR_LOG (" ------ ------- ---------- --------- -------- ------------ ------- ------- ------- ------- ------- -------\n " );
@@ -194,6 +248,7 @@ static void log_overused_nodes_header() {
194
248
VTR_LOG (" ------ ------- ---------- --------- -------- ------------ ------- ------- ------- ------- ------- -------\n " );
195
249
}
196
250
251
+ // /@brief Print out a single-line info that corresponds to a single overused rr node in the logfile
197
252
static void log_single_overused_node_status (int overuse_index, RRNodeId node_id) {
198
253
const auto & device_ctx = g_vpr_ctx.device ();
199
254
const auto & route_ctx = g_vpr_ctx.routing ();
0 commit comments