3030 * channel segments in the FPGA.
3131 */
3232static void load_channel_occupancies (const Netlist<>& net_list,
33- vtr::Matrix <int >& chanx_occ,
34- vtr::Matrix <int >& chany_occ);
33+ vtr::NdMatrix <int , 3 >& chanx_occ,
34+ vtr::NdMatrix <int , 3 >& chany_occ);
3535
3636/* *
3737 * @brief Writes channel occupancy data to a file.
3838 *
3939 * Each row contains:
40- * - (x, y) coordinate
40+ * - (layer, x, y) coordinate
4141 * - Occupancy count
4242 * - Occupancy percentage (occupancy / capacity)
4343 * - Channel capacity
4444 *
4545 * @param filename Output file path.
4646 * @param occupancy Matrix of occupancy counts.
47- * @param capacity_list List of channel capacities (per y for chanx, per x for chany) .
47+ * @param capacity Channel capacities .
4848 */
49- static void write_channel_occupancy_table (const std::string_view filename,
50- const vtr::Matrix <int >& occupancy,
51- const std::vector <int >& capacity_list );
49+ static void write_channel_occupancy_table ( std::string_view filename,
50+ const vtr::NdMatrix <int , 3 >& occupancy,
51+ const vtr::NdMatrix <int , 3 >& capacity );
5252
5353/* *
5454 * @brief Figures out maximum, minimum and average number of bends
@@ -188,66 +188,94 @@ void length_and_bends_stats(const Netlist<>& net_list, bool is_flat) {
188188static void get_channel_occupancy_stats (const Netlist<>& net_list, bool /* **/ ) {
189189 const auto & device_ctx = g_vpr_ctx.device ();
190190
191- auto chanx_occ = vtr::Matrix<int >({{
191+ auto chanx_occ = vtr::NdMatrix<int , 3 >({{
192+ device_ctx.grid .get_num_layers (),
192193 device_ctx.grid .width (), // [0 .. device_ctx.grid.width() - 1] (length of x channel)
193194 device_ctx.grid .height () - 1 // [0 .. device_ctx.grid.height() - 2] (# x channels)
194195 }},
195196 0 );
196197
197- auto chany_occ = vtr::Matrix<int >({{
198+ auto chany_occ = vtr::NdMatrix<int , 3 >({{
199+ device_ctx.grid .get_num_layers (),
198200 device_ctx.grid .width () - 1 , // [0 .. device_ctx.grid.width() - 2] (# y channels)
199201 device_ctx.grid .height () // [0 .. device_ctx.grid.height() - 1] (length of y channel)
200202 }},
201203 0 );
202204
203205 load_channel_occupancies (net_list, chanx_occ, chany_occ);
204206
205- write_channel_occupancy_table (" chanx_occupancy.txt" , chanx_occ, device_ctx.chan_width .x_list );
206- write_channel_occupancy_table (" chany_occupancy.txt" , chany_occ, device_ctx.chan_width .y_list );
207+ write_channel_occupancy_table (" chanx_occupancy.txt" , chanx_occ, device_ctx.rr_chanx_width );
208+ write_channel_occupancy_table (" chany_occupancy.txt" , chany_occ, device_ctx.rr_chany_width );
209+
210+ int total_cap_x = 0 ;
211+ int total_used_x = 0 ;
212+ int total_cap_y = 0 ;
213+ int total_used_y = 0 ;
207214
208215 VTR_LOG (" \n " );
209- VTR_LOG (" X - Directed channels: j max occ ave occ capacity\n " );
210- VTR_LOG (" ---- ------- ------- --------\n " );
211-
212- int total_x = 0 ;
213- for (size_t j = 0 ; j < device_ctx.grid .height () - 1 ; ++j) {
214- total_x += device_ctx.chan_width .x_list [j];
215- float ave_occ = 0.0 ;
216- int max_occ = -1 ;
217-
218- for (size_t i = 1 ; i < device_ctx.grid .width (); ++i) {
219- max_occ = std::max (chanx_occ[i][j], max_occ);
220- ave_occ += chanx_occ[i][j];
216+ VTR_LOG (" X - Directed channels: layer j max occ ave occ ave cap\n " );
217+ VTR_LOG (" ----- ---- -------- -------- --------\n " );
218+
219+ for (size_t layer = 0 ; layer < device_ctx.grid .get_num_layers (); ++layer) {
220+ for (size_t j = 0 ; j < device_ctx.grid .height () - 1 ; ++j) {
221+ float ave_occ = 0 .0f ;
222+ float ave_cap = 0 .0f ;
223+ int max_occ = -1 ;
224+
225+ for (size_t i = 1 ; i < device_ctx.grid .width (); ++i) {
226+ max_occ = std::max (chanx_occ[layer][i][j], max_occ);
227+ ave_occ += chanx_occ[layer][i][j];
228+ ave_cap += device_ctx.rr_chanx_width [layer][i][j];
229+
230+ total_cap_x += chanx_occ[layer][i][j];
231+ total_used_x += chanx_occ[layer][i][j];
232+ }
233+ ave_occ /= device_ctx.grid .width () - 2 ;
234+ ave_cap /= device_ctx.grid .width () - 2 ;
235+ VTR_LOG (" %5zu %4zu %8d %8.3f %8.0f\n " ,
236+ layer, j, max_occ, ave_occ, ave_cap);
221237 }
222- ave_occ /= device_ctx.grid .width ();
223- VTR_LOG (" %4d %7d %7.3f %8d\n " , j, max_occ, ave_occ, device_ctx.chan_width .x_list [j]);
224238 }
225239
226- VTR_LOG (" Y - Directed channels: i max occ ave occ capacity\n " );
227- VTR_LOG (" ---- ------- ------- --------\n " );
240+ VTR_LOG (" Y - Directed channels: layer i max occ ave occ ave cap\n " );
241+ VTR_LOG (" ----- ---- -------- -------- --------\n " );
242+
243+ for (size_t layer = 0 ; layer < device_ctx.grid .get_num_layers (); ++layer) {
244+ for (size_t i = 0 ; i < device_ctx.grid .width () - 1 ; ++i) {
245+ float ave_occ = 0.0 ;
246+ float ave_cap = 0.0 ;
247+ int max_occ = -1 ;
228248
229- int total_y = 0 ;
230- for (size_t i = 0 ; i < device_ctx.grid .width () - 1 ; ++i) {
231- total_y += device_ctx.chan_width .y_list [i];
232- float ave_occ = 0.0 ;
233- int max_occ = -1 ;
249+ for (size_t j = 1 ; j < device_ctx.grid .height (); ++j) {
250+ max_occ = std::max (chany_occ[layer][i][j], max_occ);
251+ ave_occ += chany_occ[layer][i][j];
252+ ave_cap += device_ctx.rr_chany_width [layer][i][j];
234253
235- for (size_t j = 1 ; j < device_ctx.grid .height (); ++j) {
236- max_occ = std::max (chany_occ[i][j], max_occ);
237- ave_occ += chany_occ[i][j];
254+ total_cap_y += chany_occ[layer][i][j];
255+ total_used_y += chany_occ[layer][i][j];
256+ }
257+ ave_occ /= device_ctx.grid .height () - 2 ;
258+ ave_cap /= device_ctx.grid .height () - 2 ;
259+ VTR_LOG (" %5zu %4zu %8d %8.3f %8.0f\n " ,
260+ layer, i, max_occ, ave_occ, ave_cap);
238261 }
239- ave_occ /= device_ctx.grid .height ();
240- VTR_LOG (" %4d %7d %7.3f %8d\n " , i, max_occ, ave_occ, device_ctx.chan_width .y_list [i]);
241262 }
242263
243264 VTR_LOG (" \n " );
244- VTR_LOG (" Total tracks in x-direction: %d, in y-direction: %d\n " , total_x, total_y);
265+
266+ VTR_LOG (" Total existing wires segments: CHANX %d, CHANY %d, ALL %d\n " ,
267+ total_cap_x, total_cap_y, total_cap_x + total_cap_y);
268+ VTR_LOG (" Total used wires segments: CHANX %d, CHANY %d, ALL %d\n " ,
269+ total_used_x, total_used_y, total_used_x + total_used_y);
270+ VTR_LOG (" Usage percentage: CHANX %d%%, CHANY %d%%, ALL %d%%\n " ,
271+ (float )total_used_x / total_cap_x, (float )total_used_y / total_cap_y, (float )(total_used_x + total_used_y) / (total_cap_x + total_cap_y));
272+
245273 VTR_LOG (" \n " );
246274}
247275
248- static void write_channel_occupancy_table (const std::string_view filename,
249- const vtr::Matrix <int >& occupancy,
250- const std::vector <int >& capacity_list ) {
276+ static void write_channel_occupancy_table (std::string_view filename,
277+ const vtr::NdMatrix <int , 3 >& occupancy,
278+ const vtr::NdMatrix <int , 3 >& capacity ) {
251279 constexpr int w_coord = 6 ;
252280 constexpr int w_value = 12 ;
253281 constexpr int w_percent = 12 ;
@@ -258,64 +286,72 @@ static void write_channel_occupancy_table(const std::string_view filename,
258286 return ;
259287 }
260288
261- file << std::setw (w_coord) << " x"
262- << std::setw (w_coord) << " y"
263- << std::setw (w_value) << " occupancy"
289+ file << std::setw (w_coord) << " layer"
290+ << std::setw (w_coord) << " x"
291+ << std::setw (w_coord) << " y"
292+ << std::setw (w_value) << " occupancy"
264293 << std::setw (w_percent) << " %"
265- << std::setw (w_value) << " capacity"
294+ << std::setw (w_value) << " capacity"
266295 << " \n " ;
267296
268- for (size_t y = 0 ; y < occupancy.dim_size (1 ); ++y) {
269- int capacity = capacity_list[y];
270- for (size_t x = 0 ; x < occupancy.dim_size (0 ); ++x) {
271- int occ = occupancy[x][y];
272- float percent = capacity > 0 ? static_cast <float >(occ) / capacity * 100 .0f : 0 .0f ;
273-
274- file << std::setw (w_coord) << x
275- << std::setw (w_coord) << y
276- << std::setw (w_value) << occ
277- << std::setw (w_percent) << std::fixed << std::setprecision (3 ) << percent
278- << std::setw (w_value) << capacity
279- << " \n " ;
297+ for (size_t layer = 0 ; layer < occupancy.dim_size (0 ); ++layer) {
298+ for (size_t x = 0 ; x < occupancy.dim_size (1 ); ++x) {
299+ for (size_t y = 0 ; y < occupancy.dim_size (2 ); ++y) {
300+ int occ = occupancy[layer][x][y];
301+ int cap = capacity[layer][x][y];
302+ float percent = (cap > 0 ) ? static_cast <float >(occ) / cap * 100 .0f : 0 .0f ;
303+
304+ file << std::setw (w_coord) << layer
305+ << std::setw (w_coord) << x
306+ << std::setw (w_coord) << y
307+ << std::setw (w_value) << occ
308+ << std::setw (w_percent) << std::fixed << std::setprecision (3 ) << percent
309+ << std::setw (w_value) << cap
310+ << " \n " ;
311+ }
280312 }
281313 }
282314
283315 file.close ();
284316}
285317
286318static void load_channel_occupancies (const Netlist<>& net_list,
287- vtr::Matrix <int >& chanx_occ,
288- vtr::Matrix <int >& chany_occ) {
289- const auto & device_ctx = g_vpr_ctx.device ();
319+ vtr::NdMatrix <int , 3 >& chanx_occ,
320+ vtr::NdMatrix <int , 3 >& chany_occ) {
321+ const DeviceContext & device_ctx = g_vpr_ctx.device ();
290322 const auto & rr_graph = device_ctx.rr_graph ;
291- const auto & route_ctx = g_vpr_ctx.routing ();
323+ const RoutingContext & route_ctx = g_vpr_ctx.routing ();
292324
293- /* First set the occupancy of everything to zero. */
325+ // First set the occupancy of everything to zero.
294326 chanx_occ.fill (0 );
295327 chany_occ.fill (0 );
296328
297- /* Now go through each net and count the tracks and pins used everywhere */
298- for (auto net_id : net_list.nets ()) {
299- /* Skip global and empty nets. */
300- if (net_list.net_is_ignored (net_id) && net_list.net_sinks (net_id).size () != 0 )
329+ // Now go through each net and count the tracks and pins used everywhere
330+ for (ParentNetId net_id : net_list.nets ()) {
331+ // Skip global and empty nets.
332+ if (net_list.net_is_ignored (net_id) && net_list.net_sinks (net_id).size () != 0 ) {
301333 continue ;
334+ }
302335
303- auto & tree = route_ctx.route_trees [net_id];
304- if (!tree)
336+ const vtr::optional<RouteTree> & tree = route_ctx.route_trees [net_id];
337+ if (!tree) {
305338 continue ;
339+ }
306340
307341 for (const RouteTreeNode& rt_node : tree.value ().all_nodes ()) {
308342 RRNodeId inode = rt_node.inode ;
309343 e_rr_type rr_type = rr_graph.node_type (inode);
310344
311345 if (rr_type == e_rr_type::CHANX) {
312346 int j = rr_graph.node_ylow (inode);
347+ int layer = rr_graph.node_layer_low (inode);
313348 for (int i = rr_graph.node_xlow (inode); i <= rr_graph.node_xhigh (inode); i++)
314- chanx_occ[i][j]++;
349+ chanx_occ[layer][ i][j]++;
315350 } else if (rr_type == e_rr_type::CHANY) {
316351 int i = rr_graph.node_xlow (inode);
352+ int layer = rr_graph.node_layer_low (inode);
317353 for (int j = rr_graph.node_ylow (inode); j <= rr_graph.node_yhigh (inode); j++)
318- chany_occ[i][j]++;
354+ chany_occ[layer][ i][j]++;
319355 }
320356 }
321357 }
0 commit comments