diff --git a/libs/libarchfpga/src/arch_util.cpp b/libs/libarchfpga/src/arch_util.cpp index c6c8d65fff..b09bddb038 100644 --- a/libs/libarchfpga/src/arch_util.cpp +++ b/libs/libarchfpga/src/arch_util.cpp @@ -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; diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h index ace0f5be50..c2459721d9 100644 --- a/libs/libarchfpga/src/physical_types.h +++ b/libs/libarchfpga/src/physical_types.h @@ -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 @@ -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; } @@ -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, @@ -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; @@ -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 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 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; @@ -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; @@ -1778,12 +1797,12 @@ constexpr std::array 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 in arch XML) - * + * */ constexpr const char* VPR_DELAYLESS_SWITCH_NAME = "__vpr_delayless_switch__"; diff --git a/libs/libarchfpga/src/read_xml_arch_file.cpp b/libs/libarchfpga/src/read_xml_arch_file.cpp index 9d54b9e2a4..3661516a53 100644 --- a/libs/libarchfpga/src/read_xml_arch_file.cpp +++ b/libs/libarchfpga/src/read_xml_arch_file.cpp @@ -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]; diff --git a/vpr/src/analytical_place/flat_placement_mass_calculator.cpp b/vpr/src/analytical_place/flat_placement_mass_calculator.cpp index d9978cdad8..3581c4ce86 100644 --- a/vpr/src/analytical_place/flat_placement_mass_calculator.cpp +++ b/vpr/src/analytical_place/flat_placement_mass_calculator.cpp @@ -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); diff --git a/vpr/src/base/netlist_walker.cpp b/vpr/src/base/netlist_walker.cpp index 3411210f3c..4539ed078a 100644 --- a/vpr/src/base/netlist_walker.cpp +++ b/vpr/src/base/netlist_walker.cpp @@ -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++) { diff --git a/vpr/src/base/read_netlist.cpp b/vpr/src/base/read_netlist.cpp index b498b8671b..eb2638ee4c 100644 --- a/vpr/src/base/read_netlist.cpp +++ b/vpr/src/base/read_netlist.cpp @@ -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) { diff --git a/vpr/src/draw/intra_logic_block.cpp b/vpr/src/draw/intra_logic_block.cpp index e253bcdafe..48993eaf8a 100644 --- a/vpr/src/draw/intra_logic_block.cpp +++ b/vpr/src/draw/intra_logic_block.cpp @@ -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) { @@ -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], @@ -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; } diff --git a/vpr/src/pack/cluster_legalizer.cpp b/vpr/src/pack/cluster_legalizer.cpp index 0c0040ac3e..7256a2c84f 100644 --- a/vpr/src/pack/cluster_legalizer.cpp +++ b/vpr/src/pack/cluster_legalizer.cpp @@ -65,7 +65,7 @@ static void check_cluster_atom_blocks(t_pb* pb, std::unordered_set& 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) { @@ -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) { @@ -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()); @@ -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(); } @@ -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) { @@ -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]; @@ -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++) { @@ -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; } diff --git a/vpr/src/pack/cluster_util.cpp b/vpr/src/pack/cluster_util.cpp index fcb4f88f92..e3361971b3 100644 --- a/vpr/src/pack/cluster_util.cpp +++ b/vpr/src/pack/cluster_util.cpp @@ -215,7 +215,7 @@ size_t update_pb_type_count(const t_pb* pb, std::map& 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) { @@ -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) { diff --git a/vpr/src/pack/lb_type_rr_graph.cpp b/vpr/src/pack/lb_type_rr_graph.cpp index 1208238627..99a859c3ab 100644 --- a/vpr/src/pack/lb_type_rr_graph.cpp +++ b/vpr/src/pack/lb_type_rr_graph.cpp @@ -296,7 +296,7 @@ static void alloc_and_load_lb_type_rr_graph_for_pb_graph_node(const t_pb_graph_n parent_node = pb_graph_node->parent_pb_graph_node; int num_modes; - if (pb_type->num_modes == 0) { + if (pb_type->is_primitive()) { /* This pb_graph_node is a terminating leaf node (primitive) */ /* alloc and load input pins that connect to sinks */ diff --git a/vpr/src/pack/output_clustering.cpp b/vpr/src/pack/output_clustering.cpp index 60a371aee4..28582294ce 100644 --- a/vpr/src/pack/output_clustering.cpp +++ b/vpr/src/pack/output_clustering.cpp @@ -229,7 +229,7 @@ static std::string clustering_xml_interconnect_text(t_logical_block_type_ptr typ if (prev_node == OPEN) { /* No previous driver implies that this is either a top-level input pin or a primitive output pin */ const t_pb_graph_pin* cur_pin = pb_graph_pin_lookup_from_index_by_type.pb_gpin(type->index, inode); - VTR_ASSERT(cur_pin->parent_node->pb_type->parent_mode == nullptr || (cur_pin->is_primitive_pin() && cur_pin->port->type == OUT_PORT)); + VTR_ASSERT(cur_pin->parent_node->pb_type->is_root() || (cur_pin->is_primitive_pin() && cur_pin->port->type == OUT_PORT)); return clustering_xml_net_text(pb_route[inode].atom_net_id); } else { const t_pb_graph_pin* cur_pin = pb_graph_pin_lookup_from_index_by_type.pb_gpin(type->index, inode); @@ -291,7 +291,7 @@ static void clustering_xml_open_block(pugi::xml_node& parent_node, t_logical_blo for (j = 0; j < pb_type->ports[i].num_pins; j++) { const t_pb_graph_pin* pin = &pb_graph_node->output_pins[port_index][j]; node_index = pin->pin_count_in_cluster; - if (pb_type->num_modes > 0 && pb_route.count(node_index) && pb_route[node_index].atom_net_id) { + if (!pb_type->is_primitive() && pb_route.count(node_index) && pb_route[node_index].atom_net_id) { prev_node = pb_route[node_index].driver_pb_pin_id; const t_pb_graph_pin* prev_pin = pb_graph_pin_lookup_from_index_by_type.pb_gpin(type->index, prev_node); const t_pb_graph_edge* edge = get_edge_between_pins(prev_pin, pin); @@ -330,7 +330,7 @@ static void clustering_xml_open_block(pugi::xml_node& parent_node, t_logical_blo for (j = 0; j < pb_type->ports[i].num_pins; j++) { node_index = pb_graph_node->input_pins[port_index][j].pin_count_in_cluster; - if (pb_type->parent_mode == nullptr) { + if (pb_type->is_root()) { pins.push_back(clustering_xml_net_text(pb_route[node_index].atom_net_id)); } else { pins.push_back(clustering_xml_interconnect_text(type, pb_graph_pin_lookup_from_index_by_type, node_index, pb_route)); @@ -371,7 +371,7 @@ static void clustering_xml_open_block(pugi::xml_node& parent_node, t_logical_blo std::vector pins; for (j = 0; j < pb_type->ports[i].num_pins; j++) { node_index = pb_graph_node->clock_pins[port_index][j].pin_count_in_cluster; - if (pb_type->parent_mode == nullptr) { + if (pb_type->is_root()) { pins.push_back(clustering_xml_net_text(pb_route[node_index].atom_net_id)); } else { pins.push_back(clustering_xml_interconnect_text(type, pb_graph_pin_lookup_from_index_by_type, node_index, pb_route)); @@ -382,7 +382,7 @@ static void clustering_xml_open_block(pugi::xml_node& parent_node, t_logical_blo } } - if (pb_type->num_modes > 0) { + if (!pb_type->is_primitive()) { for (i = 0; i < mode->num_pb_type_children; i++) { child_pb_type = &mode->pb_type_children[i]; for (j = 0; j < mode->pb_type_children[i].num_pb; j++) { @@ -426,7 +426,7 @@ static void clustering_xml_block(pugi::xml_node& parent_node, t_logical_block_ty block_node.append_attribute("name") = pb->name; block_node.append_attribute("instance") = vtr::string_fmt("%s[%d]", pb_type->name, pb_index).c_str(); - if (pb_type->num_modes > 0) { + if (!pb_type->is_primitive()) { block_node.append_attribute("mode") = mode->name; } else { const auto& atom_ctx = g_vpr_ctx.atom(); @@ -460,7 +460,7 @@ static void clustering_xml_block(pugi::xml_node& parent_node, t_logical_block_ty for (j = 0; j < pb_type->ports[i].num_pins; j++) { node_index = pb->pb_graph_node->input_pins[port_index][j].pin_count_in_cluster; - if (pb_type->parent_mode == nullptr) { + if (pb_type->is_root()) { if (pb_route.count(node_index)) { pins.push_back(clustering_xml_net_text(pb_route[node_index].atom_net_id)); } else { @@ -475,7 +475,7 @@ static void clustering_xml_block(pugi::xml_node& parent_node, t_logical_block_ty //The cluster router may have rotated equivalent pins (e.g. LUT inputs), //record the resulting rotation here so it can be unambigously mapped //back to the atom netlist - if (pb_type->ports[i].equivalent != PortEquivalence::NONE && pb_type->parent_mode != nullptr && pb_type->num_modes == 0) { + if (pb_type->ports[i].equivalent != PortEquivalence::NONE && pb_type->parent_mode != nullptr && pb_type->is_primitive()) { //This is a primitive with equivalent inputs auto& atom_ctx = g_vpr_ctx.atom(); @@ -560,7 +560,7 @@ static void clustering_xml_block(pugi::xml_node& parent_node, t_logical_block_ty std::vector pins; for (j = 0; j < pb_type->ports[i].num_pins; j++) { node_index = pb->pb_graph_node->clock_pins[port_index][j].pin_count_in_cluster; - if (pb_type->parent_mode == nullptr) { + if (pb_type->is_root()) { if (pb_route.count(node_index)) { pins.push_back(clustering_xml_net_text(pb_route[node_index].atom_net_id)); } else { @@ -575,7 +575,7 @@ static void clustering_xml_block(pugi::xml_node& parent_node, t_logical_block_ty } } - if (pb_type->num_modes > 0) { + if (!pb_type->is_primitive()) { for (i = 0; i < mode->num_pb_type_children; i++) { for (j = 0; j < mode->pb_type_children[i].num_pb; j++) { /* If child pb is not used but routing is used, I must print things differently */ diff --git a/vpr/src/pack/pb_type_graph.cpp b/vpr/src/pack/pb_type_graph.cpp index 266f3d38f7..6bd874f6e2 100644 --- a/vpr/src/pack/pb_type_graph.cpp +++ b/vpr/src/pack/pb_type_graph.cpp @@ -281,7 +281,7 @@ static void alloc_and_load_pb_graph(t_pb_graph_node* pb_graph_node, pb_graph_node->pin_num_range.low = pin_count_in_cluster; for (i = 0; i < pb_type->num_ports; i++) { if (pb_type->ports[i].model_port) { - VTR_ASSERT(pb_type->num_modes == 0); + VTR_ASSERT(pb_type->is_primitive()); } else { VTR_ASSERT(pb_type->num_modes != 0 || pb_type->ports[i].is_clock); } @@ -1645,7 +1645,7 @@ static void echo_pb_rec(const t_pb_graph_node* pb_graph_node, const int level, F } fprintf(fp, "\n"); - if (pb_graph_node->pb_type->num_modes > 0) { + if (!pb_graph_node->pb_type->is_primitive()) { print_tabs(fp, level); fprintf(fp, "Children:\n"); } diff --git a/vpr/src/pack/pb_type_graph_annotations.cpp b/vpr/src/pack/pb_type_graph_annotations.cpp index 63a60188f2..a01fec982b 100644 --- a/vpr/src/pack/pb_type_graph_annotations.cpp +++ b/vpr/src/pack/pb_type_graph_annotations.cpp @@ -47,7 +47,7 @@ void load_pb_graph_pin_to_pin_annotations(t_pb_graph_node* pb_graph_node) { pb_type = pb_graph_node->pb_type; /* Load primitive critical path delays */ - if (pb_type->num_modes == 0) { + if (pb_type->is_primitive()) { annotations = pb_type->annotations; for (i = 0; i < pb_type->num_annotations; i++) { if (annotations[i].type == E_ANNOT_PIN_TO_PIN_DELAY) { diff --git a/vpr/src/pack/prepack.cpp b/vpr/src/pack/prepack.cpp index 344d8184a8..4f14aa9483 100644 --- a/vpr/src/pack/prepack.cpp +++ b/vpr/src/pack/prepack.cpp @@ -726,7 +726,7 @@ static void backward_expand_pack_pattern_from_edge(const t_pb_graph_edge* expans // check if this input pin of the expansion edge has no driving pin if (expansion_edge->input_pins[i]->num_input_edges == 0) { // check if this input pin of the expansion edge belongs to a root block (i.e doesn't have a parent block) - if (expansion_edge->input_pins[i]->parent_node->pb_type->parent_mode == nullptr) { + if (expansion_edge->input_pins[i]->parent_node->pb_type->is_root()) { // This pack pattern extends to CLB (root pb block) input pin, // thus it extends across multiple logic blocks, treat as a chain packing_pattern.is_chain = true; diff --git a/vpr/src/power/power_sizing.cpp b/vpr/src/power/power_sizing.cpp index 9f35996eb2..31738a8eb6 100644 --- a/vpr/src/power/power_sizing.cpp +++ b/vpr/src/power/power_sizing.cpp @@ -312,7 +312,7 @@ static double power_count_transistors_pb_node(t_pb_graph_node* pb_node) { t_pb_type* pb_type = pb_node->pb_type; /* Check if this is a leaf node, or whether it has children */ - if (pb_type->num_modes == 0) { + if (pb_type->is_primitive()) { /* Leaf node */ tc_interc_max = 0; tc_children_max = power_count_transistors_primitive(pb_type); diff --git a/vpr/src/util/vpr_utils.cpp b/vpr/src/util/vpr_utils.cpp index c31c7ab08b..34c2156b98 100644 --- a/vpr/src/util/vpr_utils.cpp +++ b/vpr/src/util/vpr_utils.cpp @@ -708,7 +708,7 @@ static bool pb_type_contains_blif_model(const t_pb_type* pb_type, const std::reg if (pb_type->blif_model != nullptr) { //Leaf pb_type - VTR_ASSERT(pb_type->num_modes == 0); + VTR_ASSERT(pb_type->is_primitive()); if (std::regex_match(pb_type->blif_model, blif_model_regex)) { return true; } else { @@ -769,7 +769,7 @@ int get_max_nets_in_pb_type(const t_pb_type* pb_type) { } } } - if (pb_type->parent_mode == nullptr) { + if (pb_type->is_root()) { max_nets += pb_type->num_input_pins + pb_type->num_output_pins + pb_type->num_clock_pins; } @@ -1169,7 +1169,7 @@ static void load_pin_id_to_pb_mapping_rec(t_pb* cur_pb, t_pb** pin_id_to_pb_mapp } } - if (pb_type->num_modes == 0 || cur_pb->child_pbs == nullptr) { + if (pb_type->is_primitive() || cur_pb->child_pbs == nullptr) { return; } diff --git a/vpr/test/test_vpr.cpp b/vpr/test/test_vpr.cpp index 99651bfe5c..2a4f7a7fc4 100644 --- a/vpr/test/test_vpr.cpp +++ b/vpr/test/test_vpr.cpp @@ -71,7 +71,7 @@ TEST_CASE("read_arch_metadata", "[vpr]") { REQUIRE(pb_type_value != nullptr); CHECK_THAT(pb_type_value->as_string().get(&arch.strings), Equals("pb_type = io")); - REQUIRE(type.pb_type->num_modes > 0); + REQUIRE(!type.pb_type->is_primitive()); REQUIRE(type.pb_type->modes != nullptr); for (int imode = 0; imode < type.pb_type->num_modes; ++imode) {