1
- #include < cmath>
1
+
2
+ #include " stats.h"
3
+
2
4
#include < set>
5
+ #include < fstream>
6
+ #include < string>
7
+ #include < iomanip>
3
8
4
9
#include " physical_types_util.h"
5
10
#include " route_tree.h"
15
20
#include " rr_graph_area.h"
16
21
#include " segment_stats.h"
17
22
#include " channel_stats.h"
18
- #include " stats.h"
19
23
20
24
/* ********************* Subroutines local to this module *********************/
21
25
26
+ /* *
27
+ * @brief Loads the two arrays passed in with the total occupancy at each of the
28
+ * channel segments in the FPGA.
29
+ */
22
30
static void load_channel_occupancies (const Netlist<>& net_list,
23
31
vtr::Matrix<int >& chanx_occ,
24
32
vtr::Matrix<int >& chany_occ);
25
33
34
+ /* *
35
+ * @brief Writes channel occupancy data to a file.
36
+ *
37
+ * Each row contains:
38
+ * - (x, y) coordinate
39
+ * - Occupancy count
40
+ * - Occupancy percentage (occupancy / capacity)
41
+ * - Channel capacity
42
+ *
43
+ * @param filename Output file path.
44
+ * @param occupancy Matrix of occupancy counts.
45
+ * @param capacity_list List of channel capacities (per y for chanx, per x for chany).
46
+ */
47
+ static void write_channel_occupancy_table (const std::string_view filename,
48
+ const vtr::Matrix<int >& occupancy,
49
+ const std::vector<int >& capacity_list);
50
+
51
+ /* *
52
+ * @brief Figures out maximum, minimum and average number of bends
53
+ * and net length in the routing.
54
+ */
26
55
static void length_and_bends_stats (const Netlist<>& net_list, bool is_flat);
27
56
57
+ // /@brief Determines how many tracks are used in each channel.
28
58
static void get_channel_occupancy_stats (const Netlist<>& net_list, bool /* **/ );
29
59
30
60
/* ************************ Subroutine definitions ****************************/
31
61
32
- /* *
33
- * @brief Prints out various statistics about the current routing.
34
- *
35
- * Both a routing and an rr_graph must exist when you call this routine.
36
- */
37
62
void routing_stats (const Netlist<>& net_list,
38
63
bool full_stats,
39
64
enum e_route_type route_type,
@@ -105,10 +130,6 @@ void routing_stats(const Netlist<>& net_list,
105
130
}
106
131
}
107
132
108
- /* *
109
- * @brief Figures out maximum, minimum and average number of bends
110
- * and net length in the routing.
111
- */
112
133
void length_and_bends_stats (const Netlist<>& net_list, bool is_flat) {
113
134
int max_bends = 0 ;
114
135
int total_bends = 0 ;
@@ -168,9 +189,8 @@ void length_and_bends_stats(const Netlist<>& net_list, bool is_flat) {
168
189
VTR_LOG (" Total number of nets absorbed: %d\n " , num_absorbed_nets);
169
190
}
170
191
171
- // /@brief Determines how many tracks are used in each channel.
172
192
static void get_channel_occupancy_stats (const Netlist<>& net_list, bool /* **/ ) {
173
- auto & device_ctx = g_vpr_ctx.device ();
193
+ const auto & device_ctx = g_vpr_ctx.device ();
174
194
175
195
auto chanx_occ = vtr::Matrix<int >({{
176
196
device_ctx.grid .width (), // [0 .. device_ctx.grid.width() - 1] (length of x channel)
@@ -183,8 +203,12 @@ static void get_channel_occupancy_stats(const Netlist<>& net_list, bool /***/) {
183
203
device_ctx.grid .height () // [0 .. device_ctx.grid.height() - 1] (length of y channel)
184
204
}},
185
205
0 );
206
+
186
207
load_channel_occupancies (net_list, chanx_occ, chany_occ);
187
208
209
+ write_channel_occupancy_table (" chanx_occupancy.txt" , chanx_occ, device_ctx.chan_width .x_list );
210
+ write_channel_occupancy_table (" chany_occupancy.txt" , chany_occ, device_ctx.chan_width .y_list );
211
+
188
212
VTR_LOG (" \n " );
189
213
VTR_LOG (" X - Directed channels: j max occ ave occ capacity\n " );
190
214
VTR_LOG (" ---- ------- ------- --------\n " );
@@ -225,16 +249,50 @@ static void get_channel_occupancy_stats(const Netlist<>& net_list, bool /***/) {
225
249
VTR_LOG (" \n " );
226
250
}
227
251
228
- /* *
229
- * @brief Loads the two arrays passed in with the total occupancy at each of the
230
- * channel segments in the FPGA.
231
- */
252
+ static void write_channel_occupancy_table (const std::string_view filename,
253
+ const vtr::Matrix<int >& occupancy,
254
+ const std::vector<int >& capacity_list) {
255
+ constexpr int w_coord = 6 ;
256
+ constexpr int w_value = 12 ;
257
+ constexpr int w_percent = 12 ;
258
+
259
+ std::ofstream file (filename.data ());
260
+ if (!file.is_open ()) {
261
+ VTR_LOG_WARN (" Failed to open %s for writing.\n " , filename.data ());
262
+ return ;
263
+ }
264
+
265
+ file << std::setw (w_coord) << " x"
266
+ << std::setw (w_coord) << " y"
267
+ << std::setw (w_value) << " occupancy"
268
+ << std::setw (w_percent) << " %"
269
+ << std::setw (w_value) << " capacity"
270
+ << " \n " ;
271
+
272
+ for (size_t y = 0 ; y < occupancy.dim_size (1 ); ++y) {
273
+ int capacity = capacity_list[y];
274
+ for (size_t x = 0 ; x < occupancy.dim_size (0 ); ++x) {
275
+ int occ = occupancy[x][y];
276
+ float percent = capacity > 0 ? static_cast <float >(occ) / capacity * 100 .0f : 0 .0f ;
277
+
278
+ file << std::setw (w_coord) << x
279
+ << std::setw (w_coord) << y
280
+ << std::setw (w_value) << occ
281
+ << std::setw (w_percent) << std::fixed << std::setprecision (3 ) << percent
282
+ << std::setw (w_value) << capacity
283
+ << " \n " ;
284
+ }
285
+ }
286
+
287
+ file.close ();
288
+ }
289
+
232
290
static void load_channel_occupancies (const Netlist<>& net_list,
233
291
vtr::Matrix<int >& chanx_occ,
234
292
vtr::Matrix<int >& chany_occ) {
235
- auto & device_ctx = g_vpr_ctx.device ();
293
+ const auto & device_ctx = g_vpr_ctx.device ();
236
294
const auto & rr_graph = device_ctx.rr_graph ;
237
- auto & route_ctx = g_vpr_ctx.routing ();
295
+ const auto & route_ctx = g_vpr_ctx.routing ();
238
296
239
297
/* First set the occupancy of everything to zero. */
240
298
chanx_occ.fill (0 );
@@ -250,7 +308,7 @@ static void load_channel_occupancies(const Netlist<>& net_list,
250
308
if (!tree)
251
309
continue ;
252
310
253
- for (auto & rt_node : tree.value ().all_nodes ()) {
311
+ for (const RouteTreeNode & rt_node : tree.value ().all_nodes ()) {
254
312
RRNodeId inode = rt_node.inode ;
255
313
t_rr_type rr_type = rr_graph.node_type (inode);
256
314
@@ -276,11 +334,9 @@ void get_num_bends_and_length(ParentNetId inet, int* bends_ptr, int* len_ptr, in
276
334
auto & device_ctx = g_vpr_ctx.device ();
277
335
const auto & rr_graph = device_ctx.rr_graph ;
278
336
279
- int bends, length, segments;
280
-
281
- bends = 0 ;
282
- length = 0 ;
283
- segments = 0 ;
337
+ int bends = 0 ;
338
+ int length = 0 ;
339
+ int segments = 0 ;
284
340
285
341
const vtr::optional<RouteTree>& tree = route_ctx.route_trees [inet];
286
342
if (!tree) {
0 commit comments