Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion libs/libarchfpga/src/arch_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,7 @@ bool pb_type_contains_blif_model(const t_pb_type* pb_type, const std::string& bl

if (pb_type->blif_model != nullptr) {
//Leaf pb_type
VTR_ASSERT(pb_type->num_modes == 0);
VTR_ASSERT(pb_type->is_primitive());
if (blif_model_name == pb_type->blif_model
|| ".subckt " + blif_model_name == pb_type->blif_model) {
return true;
Expand Down
93 changes: 56 additions & 37 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,25 @@ struct t_pb_type {
t_pb_type_power* pb_type_power = nullptr;

t_metadata_dict meta;

/**
* @brief Check if t_pb_type is the root of the pb graph. Root pb_types correspond to a single top level block type and map to a particular type
* of location in the FPGA device grid (e.g. Logic, DSP, RAM etc.)
*
* @return if t_pb_type is root ot not
*/
inline bool is_root() const {
return parent_mode == nullptr;
}

/**
* @brief Check if t_pb_type is a primitive block or equivalently a leaf of the pb graph.
*
* @return if t_pb_type is primitive/leaf ot not
*/
inline bool is_primitive() const {
return num_modes == 0;
}
};

/** Describes an operational mode of a clustered logic block
Expand Down Expand Up @@ -1353,7 +1372,7 @@ class t_pb_graph_node {
t_interconnect_pins** interconnect_pins; /* [0..num_modes-1][0..num_interconnect_in_mode] */

// Returns true if this pb_graph_node represents a primitive type (primitives have 0 modes)
bool is_primitive() const { return this->pb_type->num_modes == 0; }
bool is_primitive() const { return this->pb_type->is_primitive(); }

// Returns true if this pb_graph_node represents a root graph node (ex. clb)
bool is_root() const { return this->parent_pb_graph_node == nullptr; }
Expand Down Expand Up @@ -1567,7 +1586,7 @@ enum e_directionality {
};

/* X_AXIS: Data that describes an x-directed wire segment (CHANX) *
* Y_AXIS: Data that describes an y-directed wire segment (CHANY) *
* Y_AXIS: Data that describes an y-directed wire segment (CHANY) *
* BOTH_AXIS: Data that can be applied to both x-directed and y-directed wire segment */
enum e_parallel_axis {
X_AXIS,
Expand Down Expand Up @@ -1624,65 +1643,65 @@ enum e_Fc_type {
*/
struct t_segment_inf {
/**
* @brief The name of the segment type
* @brief The name of the segment type
*/
std::string name;

/**
* @brief ratio of tracks which are of this segment type.
* @brief ratio of tracks which are of this segment type.
*/
int frequency;

/**
* @brief Length (in clbs) of the segment.
* @brief Length (in clbs) of the segment.
*/
int length;

/**
* @brief Index of the switch type that connects other wires to this segment.
* Note that this index is in relation to the switches from the architecture file,
* not the expanded list of switches that is built at the end of build_rr_graph.
* @brief Index of the switch type that connects other wires to this segment.
* Note that this index is in relation to the switches from the architecture file,
* not the expanded list of switches that is built at the end of build_rr_graph.
*/
short arch_wire_switch;

/**
* @brief Index of the switch type that connects output pins to this segment.
* Note that this index is in relation to the switches from the architecture file,
* not the expanded list of switches that is built at the end of build_rr_graph.
* @brief Index of the switch type that connects output pins to this segment.
* Note that this index is in relation to the switches from the architecture file,
* not the expanded list of switches that is built at the end of build_rr_graph.
*/
short arch_opin_switch;

/**
* @brief Same as arch_wire_switch but used only for decremental tracks if it is
* specified in the architecture file. If -1, this value was not set in the
* architecture file and arch_wire_switch should be used for "DEC_DIR" wire segments.
* @brief Same as arch_wire_switch but used only for decremental tracks if it is
* specified in the architecture file. If -1, this value was not set in the
* architecture file and arch_wire_switch should be used for "DEC_DIR" wire segments.
*/
short arch_wire_switch_dec = -1;

/**
* @brief Same as arch_opin_switch but used only for decremental tracks if
* it is specified in the architecture file. If -1, this value was not set in
* the architecture file and arch_opin_switch should be used for "DEC_DIR" wire segments.
* @brief Same as arch_opin_switch but used only for decremental tracks if
* it is specified in the architecture file. If -1, this value was not set in
* the architecture file and arch_opin_switch should be used for "DEC_DIR" wire segments.
*/
short arch_opin_switch_dec = -1;

/**
* @brief Index of the switch type that connects output pins (OPINs) to this
* segment from another die (layer). Note that this index is in relation to
* the switches from the architecture file, not the expanded list of switches
* that is built at the end of build_rr_graph.
* @brief Index of the switch type that connects output pins (OPINs) to this
* segment from another die (layer). Note that this index is in relation to
* the switches from the architecture file, not the expanded list of switches
* that is built at the end of build_rr_graph.
*/
short arch_inter_die_switch = -1;

/**
* @brief The fraction of logic blocks along its length to which this segment can connect.
* (i.e. internal population).
* @brief The fraction of logic blocks along its length to which this segment can connect.
* (i.e. internal population).
*/
float frac_cb;

/**
* @brief The fraction of the length + 1 switch blocks along the segment to which the segment can connect.
* Segments that aren't long lines must connect to at least two switch boxes.
* @brief The fraction of the length + 1 switch blocks along the segment to which the segment can connect.
* Segments that aren't long lines must connect to at least two switch boxes.
*/
float frac_sb;

Expand All @@ -1699,27 +1718,27 @@ struct t_segment_inf {
enum e_directionality directionality;

/**
* @brief Defines what axis the segment is parallel to. See e_parallel_axis
* comments for more details on the values.
* @brief Defines what axis the segment is parallel to. See e_parallel_axis
* comments for more details on the values.
*/
enum e_parallel_axis parallel_axis;

/**
* @brief A vector of booleans indicating whether the segment can connect to a logic block.
* @brief A vector of booleans indicating whether the segment can connect to a logic block.
*/
std::vector<bool> cb;

/**
* @brief A vector of booleans indicating whether the segment can connect to a switch block.
* @brief A vector of booleans indicating whether the segment can connect to a switch block.
*/
std::vector<bool> sb;

/**
* @brief The index of the segment as stored in the appropriate Segs list.
* Upon loading the architecture, we use this field to keep track of the
* segment's index in the unified segment_inf vector. This is useful when
* building the rr_graph for different Y & X channels in terms of track
* distribution and segment type.
* Upon loading the architecture, we use this field to keep track of the
* segment's index in the unified segment_inf vector. This is useful when
* building the rr_graph for different Y & X channels in terms of track
* distribution and segment type.
*/
int seg_index;

Expand All @@ -1728,7 +1747,7 @@ struct t_segment_inf {
* Possible values are:
* - GENERAL: The segment is part of the general routing resources.
* - GCLK: The segment is part of the global routing network.
* For backward compatibility, this attribute is optional. If not specified,
* For backward compatibility, this attribute is optional. If not specified,
* the resource type for the segment is considered to be GENERAL.
*/
enum SegResType res_type = SegResType::GENERAL;
Expand Down Expand Up @@ -1778,12 +1797,12 @@ constexpr std::array<const char*, size_t(SwitchType::NUM_SWITCH_TYPES)> SWITCH_T

/* Constant/Reserved names for switches in architecture XML
* Delayless switch:
* The zero-delay switch created by VPR internally
* The zero-delay switch created by VPR internally
* This is a special switch just to ease CAD algorithms
* It is mainly used in
* - the edges between SOURCE and SINK nodes in routing resource graphs
* - the edges between SOURCE and SINK nodes in routing resource graphs
* - the edges in CLB-to-CLB connections (defined by <directlist> in arch XML)
*
*
*/
constexpr const char* VPR_DELAYLESS_SWITCH_NAME = "__vpr_delayless_switch__";

Expand Down
2 changes: 1 addition & 1 deletion libs/libarchfpga/src/read_xml_arch_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,7 @@ static void ProcessPb_Type(pugi::xml_node Parent,
pb_type->pb_type_power->leakage_default_mode = 0;
int mode_idx = 0;

if (pb_type->num_modes == 0) {
if (pb_type->is_primitive()) {
/* The pb_type operates in an implied one mode */
pb_type->num_modes = 1;
pb_type->modes = new t_mode[pb_type->num_modes];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static PrimitiveVector calc_pb_type_capacity(const t_pb_type* pb_type) {
// capacities as if the pb could choose either one.
PrimitiveVector capacity;
// If this is a leaf / primitive, create the base PrimitiveVector capacity.
if (pb_type->num_modes == 0) {
if (pb_type->is_primitive()) {
LogicalModelId model_id = pb_type->model_id;
VTR_ASSERT(model_id.is_valid());
capacity.add_val_to_dim(get_model_mass(model_id), (size_t)model_id);
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/netlist_walker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void NetlistWalker::walk_blocks(const t_pb_routes& top_pb_route, const t_pb* pb)

//Recurse
const t_pb_type* pb_type = pb->pb_graph_node->pb_type;
if (pb_type->num_modes > 0) {
if (!pb_type->is_primitive()) {
const t_mode* mode = &pb_type->modes[pb->mode];
for (int i = 0; i < mode->num_pb_type_children; i++) {
for (int j = 0; j < mode->pb_type_children[i].num_pb; j++) {
Expand Down
2 changes: 1 addition & 1 deletion vpr/src/base/read_netlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ static void processPb(pugi::xml_node Parent, const ClusterBlockId index, t_pb* p
VTR_ASSERT(clb_nlist->block_ports(index).size() == (unsigned)pb_type->num_ports);
}

if (pb_type->num_modes == 0) {
if (pb_type->is_primitive()) {
/* A primitive type */
AtomBlockId blk_id = atom_ctx.netlist().find_block(pb->name);
if (!blk_id) {
Expand Down
33 changes: 14 additions & 19 deletions vpr/src/draw/intra_logic_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ static int draw_internal_find_max_lvl(const t_pb_type& pb_type) {
t_mode mode;
int max_levels = 0;

/* If no modes, we have reached the end of pb_graph */
if (pb_type.num_modes == 0)
/* If pb_type is a primitive, we have reached the end of pb_graph */
if (pb_type.is_primitive())
return (pb_type.depth);

for (i = 0; i < pb_type.num_modes; ++i) {
Expand All @@ -221,30 +221,25 @@ static int draw_internal_find_max_lvl(const t_pb_type& pb_type) {
* calls helper function to compute bounding box values.
*/
static void draw_internal_load_coords(int type_descrip_index, t_pb_graph_node* pb_graph_node, float parent_width, float parent_height) {
int i, j, k;
t_pb_type* pb_type;
int num_modes, num_children, num_pb;
t_mode mode;
float blk_width = 0.;
float blk_height = 0.;

/* Get information about the pb_type */
pb_type = pb_graph_node->pb_type;
num_modes = pb_type->num_modes;

/* If no modes, we have reached the end of pb_graph */
if (num_modes == 0)
t_pb_type* pb_type = pb_graph_node->pb_type;
int num_modes = pb_type->num_modes;
/* If pb_type is primitive, we have reached the end of pb_graph */
if (pb_type->is_primitive()) {
return;
}

for (i = 0; i < num_modes; ++i) {
mode = pb_type->modes[i];
num_children = mode.num_pb_type_children;
for (int i = 0; i < num_modes; ++i) {
t_mode mode = pb_type->modes[i];
int num_children = mode.num_pb_type_children;

for (j = 0; j < num_children; ++j) {
for (int j = 0; j < num_children; ++j) {
/* Find the number of instances for each child pb_type. */
num_pb = mode.pb_type_children[j].num_pb;
int num_pb = mode.pb_type_children[j].num_pb;

for (k = 0; k < num_pb; ++k) {
for (int k = 0; k < num_pb; ++k) {
/* Compute bound box for block. Don't call if pb_type is root-level pb. */
draw_internal_calc_coords(type_descrip_index,
&pb_graph_node->child_pb_graph_nodes[i][j][k],
Expand Down Expand Up @@ -721,7 +716,7 @@ t_pb* highlight_sub_block_helper(const ClusterBlockId clb_index, t_pb* pb, const
// and if pb is dud
if (pb_type->depth + 1 > max_depth
|| pb->child_pbs == nullptr
|| pb_type->num_modes == 0) {
|| pb_type->is_primitive()) {
return nullptr;
}

Expand Down
18 changes: 8 additions & 10 deletions vpr/src/pack/cluster_legalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static void check_cluster_atom_blocks(t_pb* pb, std::unordered_set<AtomBlockId>&
const AtomContext& atom_ctx = g_vpr_ctx.atom();

const t_pb_type* pb_type = pb->pb_graph_node->pb_type;
if (pb_type->num_modes == 0) {
if (pb_type->is_primitive()) {
/* primitive */
AtomBlockId blk_id = atom_pb_lookup.pb_atom(pb);
if (blk_id) {
Expand Down Expand Up @@ -396,7 +396,7 @@ static bool primitive_memory_sibling_feasible(const AtomBlockId blk_id, const t_
static bool primitive_feasible(const AtomBlockId blk_id, t_pb* cur_pb, const AtomPBBimap& atom_to_pb) {
const t_pb_type* cur_pb_type = cur_pb->pb_graph_node->pb_type;

VTR_ASSERT(cur_pb_type->num_modes == 0); /* primitive */
VTR_ASSERT(cur_pb_type->is_primitive()); /* primitive */

AtomBlockId cur_pb_blk_id = atom_to_pb.pb_atom(cur_pb);
if (cur_pb_blk_id && cur_pb_blk_id != blk_id) {
Expand Down Expand Up @@ -511,9 +511,7 @@ try_place_atom_block_rec(const t_pb_graph_node* pb_graph_node,
return e_block_pack_status::BLK_FAILED_FEASIBLE;
}

bool is_primitive = (pb_type->num_modes == 0);

if (is_primitive) {
if (pb_type->is_primitive()) {
VTR_ASSERT(!atom_to_pb.pb_atom(pb)
&& atom_to_pb.atom_pb(blk_id) == nullptr
&& atom_cluster[blk_id] == LegalizationClusterId::INVALID());
Expand Down Expand Up @@ -576,7 +574,7 @@ static void reset_lookahead_pins_used(t_pb* cur_pb) {
return; /* No pins used, no need to continue */
}

if (pb_type->num_modes > 0 && cur_pb->name != nullptr) {
if (!pb_type->is_primitive() && cur_pb->name != nullptr) {
for (int i = 0; i < cur_pb->pb_graph_node->num_input_pin_class; i++) {
cur_pb->pb_stats->lookahead_input_pins_used[i].clear();
}
Expand Down Expand Up @@ -821,7 +819,7 @@ static void try_update_lookahead_pins_used(t_pb* cur_pb,
const AtomPBBimap& atom_to_pb) {
// run recursively till a leaf (primitive) pb block is reached
const t_pb_type* pb_type = cur_pb->pb_graph_node->pb_type;
if (pb_type->num_modes > 0 && cur_pb->name != nullptr) {
if (!pb_type->is_primitive() && cur_pb->name != nullptr) {
if (cur_pb->child_pbs != nullptr) {
for (int i = 0; i < pb_type->modes[cur_pb->mode].num_pb_type_children; i++) {
if (cur_pb->child_pbs[i] != nullptr) {
Expand All @@ -848,7 +846,7 @@ static void try_update_lookahead_pins_used(t_pb* cur_pb,
static bool check_lookahead_pins_used(t_pb* cur_pb, t_ext_pin_util max_external_pin_util) {
const t_pb_type* pb_type = cur_pb->pb_graph_node->pb_type;

if (pb_type->num_modes > 0 && cur_pb->name) {
if (!pb_type->is_primitive() && cur_pb->name) {
for (int i = 0; i < cur_pb->pb_graph_node->num_input_pin_class; i++) {
size_t class_size = cur_pb->pb_graph_node->input_pin_class_size[i];

Expand Down Expand Up @@ -1015,7 +1013,7 @@ static void revert_place_atom_block(const AtomBlockId blk_id,
static void commit_lookahead_pins_used(t_pb* cur_pb) {
const t_pb_type* pb_type = cur_pb->pb_graph_node->pb_type;

if (pb_type->num_modes > 0 && cur_pb->name) {
if (!pb_type->is_primitive() && cur_pb->name) {
for (int i = 0; i < cur_pb->pb_graph_node->num_input_pin_class; i++) {
VTR_ASSERT(cur_pb->pb_stats->lookahead_input_pins_used[i].size() <= (unsigned int)cur_pb->pb_graph_node->input_pin_class_size[i]);
for (size_t j = 0; j < cur_pb->pb_stats->lookahead_input_pins_used[i].size(); j++) {
Expand Down Expand Up @@ -1076,7 +1074,7 @@ static bool cleanup_pb(t_pb* pb) {
t_pb_type* pb_type = pb_child->pb_graph_node->pb_type;

/* Primitive, check occupancy */
if (pb_type->num_modes == 0) {
if (pb_type->is_primitive()) {
if (pb_child->name != nullptr) {
can_free = false;
}
Expand Down
4 changes: 2 additions & 2 deletions vpr/src/pack/cluster_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ size_t update_pb_type_count(const t_pb* pb, std::map<t_pb_type*, int>& pb_type_c

pb_type_count[pb_type]++;

if (pb_type->num_modes > 0) {
if (!pb_type->is_primitive()) {
for (int i = 0; i < mode->num_pb_type_children; i++) {
for (int j = 0; j < mode->pb_type_children[i].num_pb; j++) {
if (pb->child_pbs[i] && pb->child_pbs[i][j].name) {
Expand Down Expand Up @@ -365,7 +365,7 @@ bool pb_used_for_blif_model(const t_pb* pb, const std::string& blif_model_name)
}
}

if (pb_type->num_modes > 0) {
if (!pb_type->is_primitive()) {
for (int i = 0; i < mode->num_pb_type_children; i++) {
for (int j = 0; j < mode->pb_type_children[i].num_pb; j++) {
if (pb->child_pbs[i] && pb->child_pbs[i][j].name) {
Expand Down
Loading