Skip to content

RR graph generation directory #3050

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 20, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion libs/libarchfpga/src/physical_types.cpp
Original file line number Diff line number Diff line change
@@ -252,7 +252,71 @@ const t_port* t_logical_block_type::get_port_by_pin(int pin) const {
return nullptr;
}

/**
/*
* t_pb_type
*/

int t_pb_type::get_max_primitives() const {
int max_size;

if (modes == nullptr) {
max_size = 1;
} else {
max_size = 0;
int temp_size = 0;
for (int i = 0; i < num_modes; i++) {
for (int j = 0; j < modes[i].num_pb_type_children; j++) {
temp_size += modes[i].pb_type_children[j].num_pb * modes[i].pb_type_children[j].get_max_primitives();
}
if (temp_size > max_size) {
max_size = temp_size;
}
}
}

return max_size;
}

/* finds maximum number of nets that can be contained in pb_type, this is bounded by the number of driving pins */
int t_pb_type::get_max_nets() const {
int max_nets;
if (modes == nullptr) {
max_nets = num_output_pins;
} else {
max_nets = 0;

for (int i = 0; i < num_modes; i++) {
int temp_nets = 0;
for (int j = 0; j < modes[i].num_pb_type_children; j++) {
temp_nets += modes[i].pb_type_children[j].num_pb * modes[i].pb_type_children[j].get_max_nets();
}

if (temp_nets > max_nets) {
max_nets = temp_nets;
}
}
}

if (is_root()) {
max_nets += num_input_pins + num_output_pins + num_clock_pins;
}

return max_nets;
}

int t_pb_type::get_max_depth() const {
int max_depth = depth;

for (int i = 0; i < num_modes; i++) {
for (int j = 0; j < modes[i].num_pb_type_children; j++) {
int temp_depth = modes[i].pb_type_children[j].get_max_depth();
max_depth = std::max(max_depth, temp_depth);
}
}
return max_depth;
}

/*
* t_pb_graph_node
*/

9 changes: 9 additions & 0 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
@@ -725,6 +725,11 @@ struct t_physical_tile_type {
///@brief Is this t_physical_tile_type an empty type?
bool is_empty() const;

///@brief Returns true if the physical tile type can implement either a .input or .output block type
inline bool is_io() const {
return is_input_type || is_output_type;
}

///@brief Returns the relative pin index within a sub tile that corresponds to the pin within the given port and its index in the port
int find_pin(std::string_view port_name, int pin_index_in_port) const;

@@ -1087,6 +1092,10 @@ struct t_pb_type {
inline bool is_primitive() const {
return num_modes == 0;
}

int get_max_primitives() const;
int get_max_depth() const;
int get_max_nets() const;
};

/** Describes an operational mode of a clustered logic block
15 changes: 0 additions & 15 deletions libs/libarchfpga/src/physical_types_util.cpp
Original file line number Diff line number Diff line change
@@ -637,21 +637,6 @@ bool is_pin_conencted_to_layer(t_physical_tile_type_ptr type, int ipin, int from
return false;
}

// TODO: Remove is_input_type / is_output_type / is_io_type as part of
// https://github.com/verilog-to-routing/vtr-verilog-to-routing/issues/1193
bool is_input_type(t_physical_tile_type_ptr type) {
return type->is_input_type;
}

bool is_output_type(t_physical_tile_type_ptr type) {
return type->is_output_type;
}

bool is_io_type(t_physical_tile_type_ptr type) {
return is_input_type(type)
|| is_output_type(type);
}

std::string block_type_pin_index_to_name(t_physical_tile_type_ptr type, int pin_physical_num, bool is_flat) {
int max_ptc = get_tile_pin_max_ptc(type, is_flat);
VTR_ASSERT(pin_physical_num < max_ptc);
7 changes: 0 additions & 7 deletions libs/libarchfpga/src/physical_types_util.h
Original file line number Diff line number Diff line change
@@ -120,13 +120,6 @@ bool is_opin(int ipin, t_physical_tile_type_ptr type);
///@brief Returns true if the specified pin is located at "from_layer" and it is connected to "to_layer"
bool is_pin_conencted_to_layer(t_physical_tile_type_ptr type, int ipin, int from_layer, int to_layer, int num_of_avail_layer);

///@brief Returns true if the given physical tile type can implement a .input block type
bool is_input_type(t_physical_tile_type_ptr type);
///@brief Returns true if the given physical tile type can implement a .output block type
bool is_output_type(t_physical_tile_type_ptr type);
///@brief Returns true if the given physical tile type can implement either a .input or .output block type
bool is_io_type(t_physical_tile_type_ptr type);

/**
* @brief Returns the corresponding physical pin based on the input parameters:
*
2 changes: 1 addition & 1 deletion vpr/src/base/ShowSetup.cpp
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@ ClusteredNetlistStats::ClusteredNetlistStats() {
auto logical_block = cluster_ctx.clb_nlist.block_type(blk_id);
auto physical_tile = pick_physical_type(logical_block);
num_blocks_type[logical_block->index]++;
if (is_io_type(physical_tile)) {
if (physical_tile->is_io()) {
for (int j = 0; j < logical_block->pb_type->num_pins; j++) {
int physical_pin = get_physical_pin(physical_tile, logical_block, j);

3 changes: 1 addition & 2 deletions vpr/src/base/check_netlist.cpp
Original file line number Diff line number Diff line change
@@ -110,8 +110,7 @@ static int check_connections_to_global_clb_pins(ClusterNetId net_id, int verbosi
int log_index = cluster_ctx.clb_nlist.pin_logical_index(pin_id);
int pin_index = get_physical_pin(physical_type, logical_type, log_index);

if (physical_type->is_ignored_pin[pin_index] != net_is_ignored
&& !is_io_type(physical_type)) {
if (physical_type->is_ignored_pin[pin_index] != net_is_ignored && !physical_type->is_io()) {
VTR_LOGV_WARN(verbosity > 2,
"Global net '%s' connects to non-global architecture pin '%s' (netlist pin '%s')\n",
cluster_ctx.clb_nlist.net_name(net_id).c_str(),
14 changes: 8 additions & 6 deletions vpr/src/base/read_route.cpp
Original file line number Diff line number Diff line change
@@ -296,7 +296,7 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN
/* Verify types and ptc*/
if (tokens[2] == "SOURCE" || tokens[2] == "SINK" || tokens[2] == "OPIN" || tokens[2] == "IPIN") {
const auto& type = device_ctx.grid.get_physical_type({x, y, layer_num});
if (tokens[4 + offset] == "Pad:" && !is_io_type(type)) {
if (tokens[4 + offset] == "Pad:" && !type->is_io()) {
vpr_throw(VPR_ERROR_ROUTE, filename, lineno,
"Node %d is of the wrong type", inode);
}
@@ -319,7 +319,7 @@ static void process_nodes(const Netlist<>& net_list, std::ifstream& fp, ClusterN
if (tokens[6 + offset] != "Switch:") {
/*This is an opin or ipin, process its pin nums*/
auto type = device_ctx.grid.get_physical_type({x, y, layer_num});
if (!is_io_type(type) && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) {
if (!type->is_io() && (tokens[2] == "IPIN" || tokens[2] == "OPIN")) {
int pin_num = rr_graph.node_pin_num(RRNodeId(inode));
int width_offset = device_ctx.grid.get_width_offset({x, y, layer_num});
int height_offset = device_ctx.grid.get_height_offset({x, y, layer_num});
@@ -592,10 +592,13 @@ void print_route(const Netlist<>& net_list,
fprintf(fp, "to (%d,%d,%d) ", rr_graph.node_xhigh(inode),
rr_graph.node_yhigh(inode), layer_num);

t_physical_tile_type_ptr physical_tile = device_ctx.grid.get_physical_type({ilow, jlow, layer_num});

switch (rr_type) {
case e_rr_type::IPIN:
case e_rr_type::OPIN:
if (is_io_type(device_ctx.grid.get_physical_type({ilow, jlow, layer_num}))) {

if (physical_tile->is_io()) {
fprintf(fp, " Pad: ");
} else { /* IO Pad. */
fprintf(fp, " Pin: ");
@@ -609,7 +612,7 @@ void print_route(const Netlist<>& net_list,

case e_rr_type::SOURCE:
case e_rr_type::SINK:
if (is_io_type(device_ctx.grid.get_physical_type({ilow, jlow, layer_num}))) {
if (physical_tile->is_io()) {
fprintf(fp, " Pad: ");
} else { /* IO Pad. */
fprintf(fp, " Class: ");
@@ -625,8 +628,7 @@ void print_route(const Netlist<>& net_list,

fprintf(fp, "%d ", rr_graph.node_ptc_num(inode));

auto physical_tile = device_ctx.grid.get_physical_type({ilow, jlow, layer_num});
if (!is_io_type(physical_tile) && (rr_type == e_rr_type::IPIN || rr_type == e_rr_type::OPIN)) {
if (!physical_tile->is_io() && (rr_type == e_rr_type::IPIN || rr_type == e_rr_type::OPIN)) {
int pin_num = rr_graph.node_pin_num(inode);
int xoffset = device_ctx.grid.get_width_offset({ilow, jlow, layer_num});
int yoffset = device_ctx.grid.get_height_offset({ilow, jlow, layer_num});
9 changes: 3 additions & 6 deletions vpr/src/base/stats.cpp
Original file line number Diff line number Diff line change
@@ -91,10 +91,7 @@ void routing_stats(const Netlist<>& net_list,
auto type = device_ctx.grid.get_physical_type({i, j, layer_num});
int width_offset = device_ctx.grid.get_width_offset({i, j, layer_num});
int height_offset = device_ctx.grid.get_height_offset({i, j, layer_num});
if (width_offset == 0
&& height_offset == 0
&& !is_io_type(type)
&& type != device_ctx.EMPTY_PHYSICAL_TILE_TYPE) {
if (width_offset == 0 && height_offset == 0 && !type->is_io() && !type->is_empty()) {
if (type->area == UNDEFINED) {
area += grid_logic_tile_area * type->width * type->height;
} else {
@@ -111,7 +108,7 @@ void routing_stats(const Netlist<>& net_list,
for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
t_pl_loc block_loc = block_locs[blk_id].loc;
auto type = physical_tile_type(block_loc);
if (!is_io_type(type)) {
if (!type->is_io()) {
if (type->area == UNDEFINED) {
used_area += grid_logic_tile_area * type->width * type->height;
} else {
@@ -473,7 +470,7 @@ void print_lambda() {
t_pl_loc block_loc = block_locs[blk_id].loc;
auto type = physical_tile_type(block_loc);
VTR_ASSERT(type != nullptr);
if (!is_io_type(type)) {
if (!type->is_io()) {
for (int ipin = 0; ipin < type->num_pins; ipin++) {
if (get_pin_type_from_pin_physical_num(type, ipin) == RECEIVER) {
ClusterNetId net_id = cluster_ctx.clb_nlist.block_net(blk_id, ipin);
2 changes: 1 addition & 1 deletion vpr/src/pack/appack_max_dist_th_manager.cpp
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ void APPackMaxDistThManager::auto_set_max_distance_thresholds(const std::vector<
// Find which type(s) this logical block type looks like.
bool has_memory = has_memory_pbs(lb_ty.pb_type);
bool is_logic_block_type = (lb_ty.index == logic_block_type->index);
bool is_io_block = is_io_type(pick_physical_type(&lb_ty));
bool is_io_block = pick_physical_type(&lb_ty)->is_io();

// Update the max distance threshold based on the type. If the logical
// block type looks like many block types at the same time (for example
8 changes: 4 additions & 4 deletions vpr/src/place/initial_placement.cpp
Original file line number Diff line number Diff line change
@@ -1012,10 +1012,10 @@ static inline void fix_IO_block_types(const t_pl_macro& pl_macro,
vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs) {
const auto& device_ctx = g_vpr_ctx.device();

//If the user marked the IO block pad_loc_type as RANDOM, that means it should be randomly
//placed and then stay fixed to that location, which is why the macro members are marked as fixed.
const auto& type = device_ctx.grid.get_physical_type({loc.x, loc.y, loc.layer});
if (is_io_type(type) && pad_loc_type == e_pad_loc_type::RANDOM) {
// If the user marked the IO block pad_loc_type as RANDOM, that means it should be randomly
// placed and then stay fixed to that location, which is why the macro members are marked as fixed.
const t_physical_tile_type_ptr type = device_ctx.grid.get_physical_type({loc.x, loc.y, loc.layer});
if (type->is_io() && pad_loc_type == e_pad_loc_type::RANDOM) {
for (const t_pl_macro_member& pl_macro_member : pl_macro.members) {
block_locs[pl_macro_member.blk_index].is_fixed = true;
}
2 changes: 1 addition & 1 deletion vpr/src/route/route_common.cpp
Original file line number Diff line number Diff line change
@@ -358,7 +358,7 @@ static t_clb_opins_used alloc_and_load_clb_opins_used_locally() {

clb_opins_used_locally[blk_id].resize((int)type->class_inf.size());

if (is_io_type(type)) continue;
if (type->is_io()) continue;

const auto [pin_low, pin_high] = get_pin_range_for_block(blk_id);

2 changes: 1 addition & 1 deletion vpr/src/route/router_lookahead_map.cpp
Original file line number Diff line number Diff line change
@@ -89,7 +89,7 @@ static void compute_tiles_lookahead(std::unordered_map<int, util::t_ipin_primiti
const t_det_routing_arch& det_routing_arch,
const DeviceContext& device_ctx);
/***
* @brief Compute the cose from tile pins to tile sinks
* @brief Compute the cost from tile pins to tile sinks
* @param intra_tile_pin_primitive_pin_delay [physical_tile_type_idx][from_pin_ptc_num][sink_ptc_num] -> cost
* @param physical_tile
* @param det_routing_arch
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@
#include "edge_groups.h"
#include "rr_graph_builder.h"
#include "rr_types.h"
#include "rr_node_indices.h"

//#define VERBOSE
//used for getting the exact count of each edge type and printing it to std out.
File renamed without changes.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -14,62 +14,6 @@

/******************* Subroutines exported by rr_graph2.c *********************/

/**
* @brief Allocates and populates data structures for efficient rr_node index lookups.
*
* This function sets up the `rr_node_indices` structure, which maps a physical location
* and type to the index of the first corresponding rr_node.
*/
void alloc_and_load_rr_node_indices(RRGraphBuilder& rr_graph_builder,
const t_chan_width& nodes_per_chan,
const DeviceGrid& grid,
int* index,
const t_chan_details& chan_details_x,
const t_chan_details& chan_details_y);

/**
* @brief Allocates extra nodes within the RR graph to support 3D custom switch blocks for multi-die FPGAs
*
* @param rr_graph_builder RRGraphBuilder data structure which allows data modification on a routing resource graph
* @param nodes_per_chan number of tracks per channel (x, y)
* @param grid device grid
* @param extra_nodes_per_switchblock keeps how many extra length-0 CHANX node is required for each unique (x,y) location within the grid.
* Number of these extra nodes are exactly the same for all layers. Hence, we only keep it for one layer. ([0..grid.width-1][0..grid.height-1)
* @param index RRNodeId that should be assigned to add a new RR node to the RR graph
*/
void alloc_and_load_inter_die_rr_node_indices(RRGraphBuilder& rr_graph_builder,
const t_chan_width& nodes_per_chan,
const DeviceGrid& grid,
const vtr::NdMatrix<int, 2>& extra_nodes_per_switchblock,
int* index);

void alloc_and_load_tile_rr_node_indices(RRGraphBuilder& rr_graph_builder,
t_physical_tile_type_ptr physical_tile,
int layer,
int x,
int y,
int* num_rr_nodes);

void alloc_and_load_intra_cluster_rr_node_indices(RRGraphBuilder& rr_graph_builder,
const DeviceGrid& grid,
const vtr::vector<ClusterBlockId, t_cluster_pin_chain>& pin_chains,
const vtr::vector<ClusterBlockId, std::unordered_set<int>>& pin_chains_num,
int* index);

/**
* Validate the node look-up matches all the node-level information
* in the storage of a routing resource graph
* This function will check the following aspects:
* - The type of each node matches its type that is indexed in the node look-up
* - For bounding box (xlow, ylow, xhigh, yhigh) of each node is indexable in the node look-up
* - The number of unique indexable nodes in the node look up matches the number of nodes in the storage
* This ensures that every node in the storage is indexable and there are no hidden nodes in the look-up
*/
bool verify_rr_node_indices(const DeviceGrid& grid,
const RRGraphView& rr_graph,
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
const t_rr_graph_storage& rr_nodes,
bool is_flat);
/**
* @brief goes through 3D custom switch blocks and counts how many connections are crossing dice for each switch block.
*
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
613 changes: 613 additions & 0 deletions vpr/src/route/rr_graph_generation/rr_node_indices.cpp

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions vpr/src/route/rr_graph_generation/rr_node_indices.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#pragma once

#include "rr_graph_builder.h"
#include "rr_graph_view.h"
#include "device_grid.h"
#include "rr_types.h"
#include "rr_graph_type.h"
#include "rr_graph_utils.h"
#include "clustered_netlist_fwd.h"

/**
* @brief Allocates and populates data structures for efficient rr_node index lookups.
*
* This function sets up the `rr_node_indices` structure, which maps a physical location
* and type to the index of the first corresponding rr_node.
*
* @param rr_graph_builder Reference to the RRGraphBuilder used to construct and populate RR node spatial lookups.
* @param nodes_per_chan Specifies the maximum number of routing tracks per channel in the x and y directions.
* @param grid The device grid representing the physical layout of tiles in the FPGA fabric.
* @param index Pointer to the global RR node index counter; incremented as new RR nodes are assigned.
* @param chan_details_x Channel details describing segment and track properties for CHANX (horizontal) routing tracks.
* @param chan_details_y Channel details describing segment and track properties for CHANY (vertical) routing tracks.
*/
void alloc_and_load_rr_node_indices(RRGraphBuilder& rr_graph_builder,
const t_chan_width& nodes_per_chan,
const DeviceGrid& grid,
int* index,
const t_chan_details& chan_details_x,
const t_chan_details& chan_details_y);

/**
* @brief Allocates extra nodes within the RR graph to support 3D custom switch blocks for multi-die FPGAs
*
* @param rr_graph_builder RRGraphBuilder data structure which allows data modification on a routing resource graph
* @param nodes_per_chan number of tracks per channel (x, y)
* @param grid The device grid representing the physical layout of tiles in the FPGA fabric.
* @param extra_nodes_per_switchblock keeps how many extra length-0 CHANX node is required for each unique (x,y) location within the grid.
* Number of these extra nodes are exactly the same for all layers. Hence, we only keep it for one layer. ([0..grid.width-1][0..grid.height-1)
* @param index Pointer to the global RR node index counter; incremented as new RR nodes are assigned.
*/
void alloc_and_load_inter_die_rr_node_indices(RRGraphBuilder& rr_graph_builder,
const t_chan_width& nodes_per_chan,
const DeviceGrid& grid,
const vtr::NdMatrix<int, 2>& extra_nodes_per_switchblock,
int* index);

/**
* @brief Allocates and loads RR node indices for a specific tile.
*
* This function assigns RR node IDs to all classes (SOURCE/SINK) and pins (IPIN/OPIN)
* associated with a given physical tile at a specific grid location and layer.
* It is primarily used in scenarios where a standalone tile's routing resources
* need to be initialized independently.
*
* @param rr_graph_builder Reference to the RR graph builder with spatial lookup.
* @param physical_tile Pointer to the physical tile type being processed.
* @param layer Layer index of the tile in the device grid.
* @param x X-coordinate of the tile's root position in the grid.
* @param y Y-coordinate of the tile's root position in the grid.
* @param num_rr_nodes Pointer to the global RR node index counter (will be incremented).
*/
void alloc_and_load_tile_rr_node_indices(RRGraphBuilder& rr_graph_builder,
t_physical_tile_type_ptr physical_tile,
int layer,
int x,
int y,
int* num_rr_nodes);

void alloc_and_load_intra_cluster_rr_node_indices(RRGraphBuilder& rr_graph_builder,
const DeviceGrid& grid,
const vtr::vector<ClusterBlockId, t_cluster_pin_chain>& pin_chains,
const vtr::vector<ClusterBlockId, std::unordered_set<int>>& pin_chains_num,
int* index);

/**
* Validate the node look-up matches all the node-level information
* in the storage of a routing resource graph
* This function will check the following aspects:
* - The type of each node matches its type that is indexed in the node look-up
* - For bounding box (xlow, ylow, xhigh, yhigh) of each node is indexable in the node look-up
* - The number of unique indexable nodes in the node look up matches the number of nodes in the storage
* This ensures that every node in the storage is indexable and there are no hidden nodes in the look-up
*/
bool verify_rr_node_indices(const DeviceGrid& grid,
const RRGraphView& rr_graph,
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
const t_rr_graph_storage& rr_nodes,
bool is_flat);
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef RR_TYPES_H
#define RR_TYPES_H

#include <vector>
#include "vtr_ndmatrix.h"

@@ -14,7 +15,7 @@

typedef std::vector<vtr::NdMatrix<std::vector<int>, 5>> t_pin_to_track_lookup;

/* AA: t_pin_to_track_lookup is alloacted first and is then converted to t_track_to_pin lookup by simply redefining the accessing order.
/* AA: t_pin_to_track_lookup is alloacted first and is then converted to t_track_to_pin lookup by simply redefining the accessing order.
* As a result, the matrix should be accessed as follow as a result after allocation in rr_graph.cpp: alloc_track_to_pin_lookup (used by unidir and bidir)
* [0..device_ctx.physical_tile_types.size()-1][0..max_chan_width-1][0..width][0..height][0..layer-1][0..3]
*
60 changes: 0 additions & 60 deletions vpr/src/util/vpr_utils.cpp
Original file line number Diff line number Diff line change
@@ -729,66 +729,6 @@ static bool pb_type_contains_blif_model(const t_pb_type* pb_type, const std::reg
return false;
}

int get_max_primitives_in_pb_type(t_pb_type* pb_type) {
int max_size;
if (pb_type->modes == nullptr) {
max_size = 1;
} else {
max_size = 0;
int temp_size = 0;
for (int i = 0; i < pb_type->num_modes; i++) {
for (int j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
temp_size += pb_type->modes[i].pb_type_children[j].num_pb
* get_max_primitives_in_pb_type(
&pb_type->modes[i].pb_type_children[j]);
}
if (temp_size > max_size) {
max_size = temp_size;
}
}
}
return max_size;
}

/* finds maximum number of nets that can be contained in pb_type, this is bounded by the number of driving pins */
int get_max_nets_in_pb_type(const t_pb_type* pb_type) {
int max_nets;
if (pb_type->modes == nullptr) {
max_nets = pb_type->num_output_pins;
} else {
max_nets = 0;
for (int i = 0; i < pb_type->num_modes; i++) {
int temp_nets = 0;
for (int j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
temp_nets += pb_type->modes[i].pb_type_children[j].num_pb
* get_max_nets_in_pb_type(
&pb_type->modes[i].pb_type_children[j]);
}
if (temp_nets > max_nets) {
max_nets = temp_nets;
}
}
}
if (pb_type->is_root()) {
max_nets += pb_type->num_input_pins + pb_type->num_output_pins
+ pb_type->num_clock_pins;
}
return max_nets;
}

int get_max_depth_of_pb_type(t_pb_type* pb_type) {
int max_depth = pb_type->depth;
for (int i = 0; i < pb_type->num_modes; i++) {
for (int j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
int temp_depth = get_max_depth_of_pb_type(&pb_type->modes[i].pb_type_children[j]);
if (temp_depth > max_depth) {
max_depth = temp_depth;
}
}
}
return max_depth;
}

/**
* given an atom block and physical primitive type, is the mapping legal
*/
15 changes: 1 addition & 14 deletions vpr/src/util/vpr_utils.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef VPR_UTILS_H
#define VPR_UTILS_H
#pragma once

#include "arch_util.h"
#include "atom_netlist.h"
@@ -181,9 +180,6 @@ InstPort parse_inst_port(const std::string& str);
//Returns the block type which is most likely the logic block
t_logical_block_type_ptr infer_logic_block_type(const DeviceGrid& grid);

int get_max_primitives_in_pb_type(t_pb_type* pb_type);
int get_max_depth_of_pb_type(t_pb_type* pb_type);
int get_max_nets_in_pb_type(const t_pb_type* pb_type);
bool primitive_type_feasible(AtomBlockId blk_id, const t_pb_type* cur_pb_type);
t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin(const t_model_ports* model_port, const int model_pin, const t_pb_graph_node* pb_graph_node);
/// @brief Gets the pb_graph_node pin at the given pin index for the given
@@ -287,13 +283,6 @@ std::vector<int> get_cluster_netlist_intra_tile_classes_at_loc(int layer,

/**
* @brief Returns the list of pins inside the tile located at (layer, i, j), except for the ones which are on a chain
* @param layer
* @param i
* @param j
* @param pin_chains
* @param pin_chains_num
* @param physical_type
* @return
*/
std::vector<int> get_cluster_netlist_intra_tile_pins_at_loc(const int layer,
const int i,
@@ -362,5 +351,3 @@ class PortPinToBlockPinConverter {
*/
std::vector<std::vector<std::vector<std::vector<int>>>> blk_pin_from_port_pin_;
};

#endif