From 6e58cf3d22be72bf65c173d47be55d3c4d4dfb75 Mon Sep 17 00:00:00 2001 From: AlexandreSinger Date: Fri, 31 Oct 2025 16:53:20 -0400 Subject: [PATCH 1/3] [Pack] Cleaned Up Read Netlist Code The code for reading a netlist file was very hard to follow and made it challenging to try and improve the pb interface. Went through and cleaned up the code to make it a bit more obvious what it is trying to do. --- vpr/src/base/read_netlist.cpp | 765 +++++++++++++++++----------------- 1 file changed, 375 insertions(+), 390 deletions(-) diff --git a/vpr/src/base/read_netlist.cpp b/vpr/src/base/read_netlist.cpp index 7b5bed8a4a..7ee40e97c9 100644 --- a/vpr/src/base/read_netlist.cpp +++ b/vpr/src/base/read_netlist.cpp @@ -3,20 +3,28 @@ * @author Jason Luu * @date May 2009 * - * @brief Read a circuit netlist in XML format and populate the netlist data structures for VPR + * Refarctored by Alex Singer November 2025. + * + * @brief Read a circuit netlist in XML format and populate the netlist data + * structures for VPR */ #include #include #include #include +#include +#include +#include "atom_lookup.h" +#include "atom_pb_bimap.h" #include "physical_types.h" #include "physical_types_util.h" #include "pugixml.hpp" #include "pugixml_loc.hpp" #include "pugixml_util.hpp" +#include "vpr_context.h" #include "vtr_assert.h" #include "vtr_util.h" #include "vtr_log.h" @@ -27,7 +35,6 @@ #include "vpr_error.h" #include "vpr_utils.h" -#include "hash.h" #include "globals.h" #include "atom_netlist.h" #include "read_netlist.h" @@ -35,19 +42,30 @@ static const char* netlist_file_name = nullptr; -static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, const pugiutil::loc_data& loc_data); +static void processPorts(pugi::xml_node Parent, + t_pb* pb, + t_pb_routes& pb_route, + const pugiutil::loc_data& loc_data); -static void processPb(pugi::xml_node Parent, const ClusterBlockId index, t_pb* pb, t_pb_routes& pb_route, int* num_primitives, const pugiutil::loc_data& loc_data, ClusteredNetlist* clb_nlist); +static void processPb(pugi::xml_node Parent, + const ClusterBlockId index, + t_pb* pb, + t_pb_routes& pb_route, + int& num_primitives, + const pugiutil::loc_data& loc_data); static void processComplexBlock(pugi::xml_node Parent, const ClusterBlockId index, - int* num_primitives, + int& num_primitives, const pugiutil::loc_data& loc_data, - ClusteredNetlist* clb_nlist); + const std::unordered_map& logical_block_type_name_to_index, + ClusteredNetlist& clb_nlist); -static int add_net_to_hash(t_hash** nhash, const char* net_name, int* ncount); +static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, + AtomNetlist& atom_netlist, + AtomLookup& atom_lookup); -static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist); +static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, const AtomNetlist& atom_netlist); static void load_internal_to_block_net_nums(const t_logical_block_type_ptr type, t_pb_routes& pb_route); @@ -57,8 +75,6 @@ static void mark_constant_generators(const ClusteredNetlist& clb_nlist, int verb static size_t mark_constant_generators_rec(const t_pb* pb, const t_pb_routes& pb_route, int verbosity); -static t_pb_routes alloc_pb_route(t_pb_graph_node* pb_graph_node); - static void load_atom_pin_mapping(const ClusteredNetlist& clb_nlist); /** @@ -70,17 +86,23 @@ ClusteredNetlist read_netlist(const char* net_file, const t_arch* arch, bool verify_file_digests, int verbosity) { - clock_t begin = clock(); - size_t bcount = 0; - std::vector circuit_inputs, circuit_outputs, circuit_clocks; - - auto& atom_ctx = g_vpr_ctx.mutable_atom(); + AtomNetlist& atom_netlist = g_vpr_ctx.mutable_atom().mutable_netlist(); + AtomLookup& atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); + const auto& logical_block_types = g_vpr_ctx.device().logical_block_types; - int num_primitives = 0; + clock_t begin = clock(); /* Parse the file */ VTR_LOG("Begin loading packed FPGA netlist file.\n"); + // Prepare a lookup between the logical block type name and the block type's index. + // This is used when parsing the blocks for their type. + std::unordered_map logical_block_type_name_to_index; + for (const t_logical_block_type& logical_block_type : logical_block_types) { + logical_block_type_name_to_index.insert(std::make_pair(logical_block_type.name, + logical_block_type.index)); + } + //Save an identifier for the netlist based on it's contents auto clb_nlist = ClusteredNetlist(net_file, vtr::secure_digest_file(net_file)); @@ -151,11 +173,11 @@ ClusteredNetlist read_netlist(const char* net_file, //Note that we currently don't require that the atom_netlist_id exists, //to remain compatible with old .net files std::string atom_nl_id = atom_netlist_id.value(); - if (atom_nl_id != atom_ctx.netlist().netlist_id()) { + if (atom_nl_id != atom_netlist.netlist_id()) { auto msg = vtr::string_fmt( "Netlist was generated from a different atom netlist file" " (loaded atom netlist ID: %s, packed netlist atom netlist ID: %s)", - atom_nl_id.c_str(), atom_ctx.netlist().netlist_id().c_str()); + atom_nl_id.c_str(), atom_netlist.netlist_id().c_str()); if (verify_file_digests) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(top), msg.c_str()); } else { @@ -166,48 +188,57 @@ ClusteredNetlist read_netlist(const char* net_file, //Collect top level I/Os auto top_inputs = pugiutil::get_single_child(top, "inputs", loc_data); - circuit_inputs = vtr::StringToken(top_inputs.text().get()).split(" \t\n"); + auto circuit_inputs = vtr::StringToken(top_inputs.text().get()).split(" \t\n"); auto top_outputs = pugiutil::get_single_child(top, "outputs", loc_data); - circuit_outputs = vtr::StringToken(top_outputs.text().get()).split(" \t\n"); + auto circuit_outputs = vtr::StringToken(top_outputs.text().get()).split(" \t\n"); auto top_clocks = pugiutil::get_single_child(top, "clocks", loc_data); - circuit_clocks = vtr::StringToken(top_clocks.text().get()).split(" \t\n"); + auto circuit_clocks = vtr::StringToken(top_clocks.text().get()).split(" \t\n"); /* Parse all CLB blocks and all nets*/ //Reset atom/pb mapping (it is reloaded from the packed netlist file) - for (auto blk_id : atom_ctx.netlist().blocks()) - atom_ctx.mutable_lookup().mutable_atom_pb_bimap().set_atom_pb(blk_id, nullptr); + atom_lookup.mutable_atom_pb_bimap().reset_bimap(); //Count the number of blocks for allocation - bcount = pugiutil::count_children(top, "block", loc_data, pugiutil::ReqOpt::OPTIONAL); + size_t bcount = pugiutil::count_children(top, "block", loc_data, pugiutil::ReqOpt::OPTIONAL); if (bcount == 0) VTR_LOG_WARN("Packed netlist contains no clustered blocks\n"); /* Process netlist */ unsigned i = 0; + int num_primitives = 0; for (auto curr_block = top.child("block"); curr_block; curr_block = curr_block.next_sibling("block")) { - processComplexBlock(curr_block, ClusterBlockId(i), &num_primitives, loc_data, &clb_nlist); + processComplexBlock(curr_block, + ClusterBlockId(i), + num_primitives, + loc_data, + logical_block_type_name_to_index, + clb_nlist); i++; } VTR_ASSERT(bcount == i); VTR_ASSERT(clb_nlist.blocks().size() == i); VTR_ASSERT(num_primitives >= 0); - VTR_ASSERT(static_cast(num_primitives) == atom_ctx.netlist().blocks().size()); + VTR_ASSERT(static_cast(num_primitives) == atom_netlist.blocks().size()); /* Error check */ - for (auto blk_id : atom_ctx.netlist().blocks()) { - if (atom_ctx.lookup().atom_pb_bimap().atom_pb(blk_id) == nullptr) { + for (auto blk_id : atom_netlist.blocks()) { + if (atom_lookup.atom_pb_bimap().atom_pb(blk_id) == nullptr) { VPR_FATAL_ERROR(VPR_ERROR_NET_F, ".blif file and .net file do not match, .net file missing atom %s.\n", - atom_ctx.netlist().block_name(blk_id).c_str()); + atom_netlist.block_name(blk_id).c_str()); } } /* TODO: Add additional check to make sure net connections match */ + mark_constant_generators(clb_nlist, verbosity); - load_external_nets_and_cb(clb_nlist); + load_external_nets_and_cb(clb_nlist, atom_netlist); + + sync_clustered_and_atom_netlists(clb_nlist, atom_netlist, atom_lookup); + } catch (pugiutil::XmlError& e) { vpr_throw(VPR_ERROR_NET_F, e.filename_c_str(), e.line(), "Error loading post-pack netlist (%s)", e.what()); @@ -216,42 +247,45 @@ ClusteredNetlist read_netlist(const char* net_file, /* TODO: create this function later * check_top_IO_matches_IO_blocks(circuit_inputs, circuit_outputs, circuit_clocks, blist, bcount); */ + clock_t end = clock(); + + VTR_LOG("Finished loading packed FPGA netlist file (took %g seconds).\n", (float)(end - begin) / CLOCKS_PER_SEC); + + return clb_nlist; +} + +static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, + AtomNetlist& atom_netlist, + AtomLookup& atom_lookup) { /* load mapping between external nets and all nets */ - for (auto net_id : atom_ctx.netlist().nets()) { - atom_ctx.mutable_lookup().remove_atom_net(net_id); + for (AtomNetId net_id : atom_netlist.nets()) { + atom_lookup.remove_atom_net(net_id); } //Save the mapping between clb and atom nets - for (auto clb_net_id : clb_nlist.nets()) { - AtomNetId net_id = atom_ctx.netlist().find_net(clb_nlist.net_name(clb_net_id)); + for (ClusterNetId clb_net_id : clb_nlist.nets()) { + AtomNetId net_id = atom_netlist.find_net(clb_nlist.net_name(clb_net_id)); VTR_ASSERT(net_id); - atom_ctx.mutable_lookup().add_atom_clb_net(net_id, clb_net_id); + atom_lookup.add_atom_clb_net(net_id, clb_net_id); } // Mark ignored and global atom nets /* We have to make set the following variables after the mapping between cluster nets and atom nets * is created */ - const AtomNetlist atom_nlist = g_vpr_ctx.atom().netlist(); - for (auto clb_net : clb_nlist.nets()) { - AtomNetId atom_net = atom_ctx.lookup().atom_net(clb_net); + for (ClusterNetId clb_net : clb_nlist.nets()) { + AtomNetId atom_net = atom_lookup.atom_net(clb_net); VTR_ASSERT(atom_net != AtomNetId::INVALID()); if (clb_nlist.net_is_global(clb_net)) { - atom_ctx.mutable_netlist().set_net_is_global(atom_net, true); + atom_netlist.set_net_is_global(atom_net, true); } if (clb_nlist.net_is_ignored(clb_net)) { - atom_ctx.mutable_netlist().set_net_is_ignored(atom_net, true); + atom_netlist.set_net_is_ignored(atom_net, true); } } /* load mapping between atom pins and pb_graph_pins */ load_atom_pin_mapping(clb_nlist); - - clock_t end = clock(); - - VTR_LOG("Finished loading packed FPGA netlist file (took %g seconds).\n", (float)(end - begin) / CLOCKS_PER_SEC); - - return clb_nlist; } /** @@ -263,13 +297,11 @@ ClusteredNetlist read_netlist(const char* net_file, */ static void processComplexBlock(pugi::xml_node clb_block, const ClusterBlockId index, - int* num_primitives, + int& num_primitives, const pugiutil::loc_data& loc_data, - ClusteredNetlist* clb_nlist) { - const t_pb_type* pb_type = nullptr; - - auto& device_ctx = g_vpr_ctx.device(); - auto& atom_ctx = g_vpr_ctx.mutable_atom(); + const std::unordered_map& logical_block_type_name_to_index, + ClusteredNetlist& clb_nlist) { + const auto& logical_block_types = g_vpr_ctx.device().logical_block_types; //Parse cb attributes auto block_name = pugiutil::get_attribute(clb_block, "name", loc_data); @@ -285,46 +317,78 @@ static void processComplexBlock(pugi::xml_node clb_block, } VTR_ASSERT(ClusterBlockId(vtr::atoi(tokens[2].data)) == index); - bool found = false; - for (const t_logical_block_type& type : device_ctx.logical_block_types) { - if (type.name == tokens[0].data) { - t_pb* pb = new t_pb; - pb->name = vtr::strdup(block_name.value()); - clb_nlist->create_block(block_name.value(), pb, &type); - pb_type = clb_nlist->block_type(index)->pb_type; - found = true; - break; - } - } - if (!found) { + // Find the logical block type of this complex block. + auto found_logical_block_index = logical_block_type_name_to_index.find(tokens[0].data); + if (found_logical_block_index == logical_block_type_name_to_index.end()) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(clb_block), - "Unknown cb type %s for cb %s #%lu.\n", block_inst.value(), clb_nlist->block_name(index).c_str(), size_t(index)); + "Unknown cb type %s for cb %s #%lu.\n", + block_inst.value(), + block_name.value(), + size_t(index)); } + int complex_block_type_index = found_logical_block_index->second; + VTR_ASSERT_SAFE(complex_block_type_index < (int)logical_block_types.size()); + const t_logical_block_type& complex_block_type = logical_block_types[complex_block_type_index]; - //Parse all pbs and CB internal nets - atom_ctx.mutable_lookup().mutable_atom_pb_bimap().set_atom_pb(AtomBlockId::INVALID(), clb_nlist->block_pb(index)); - - clb_nlist->block_pb(index)->pb_graph_node = clb_nlist->block_type(index)->pb_graph_head; - clb_nlist->block_pb(index)->pb_route = alloc_pb_route(clb_nlist->block_pb(index)->pb_graph_node); + // Use the logical block type to create the physical block. + t_pb* pb = new t_pb; + pb->name = vtr::strdup(block_name.value()); + pb->pb_graph_node = complex_block_type.pb_graph_head; + // Set the mode of the physical block. auto clb_mode = pugiutil::get_attribute(clb_block, "mode", loc_data); - - found = false; - for (int i = 0; i < pb_type->num_modes; i++) { - if (strcmp(clb_mode.value(), pb_type->modes[i].name) == 0) { - clb_nlist->block_pb(index)->mode = i; + t_pb_type* complex_block_pb_type = complex_block_type.pb_type; + bool found = false; + for (int i = 0; i < complex_block_type.pb_type->num_modes; i++) { + if (strcmp(clb_mode.value(), complex_block_pb_type->modes[i].name) == 0) { + pb->mode = i; found = true; + break; } } if (!found) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(clb_block), - "Unknown mode %s for cb %s #%d.\n", clb_mode.value(), clb_nlist->block_name(index).c_str(), index); + "Unknown mode %s for cb %s #%d.\n", + clb_mode.value(), + block_name.value(), + index); + } + + // Create the clustered block in the netlist for this complex block. + ClusterBlockId new_block_id = clb_nlist.create_block(block_name.value(), + pb, + &complex_block_type); + VTR_ASSERT(new_block_id == index); + + // Create the ports in the clb_nlist for the top-level pb + for (int i = 0; i < complex_block_pb_type->num_ports; i++) { + const t_port& port = complex_block_pb_type->ports[i]; + + // Get the type of this new port. + PortType new_port_type; + if (port.is_clock && port.type == IN_PORT) { + new_port_type = PortType::CLOCK; + } else if (!port.is_clock && port.type == IN_PORT) { + new_port_type = PortType::INPUT; + } else { + VTR_ASSERT(port.type == OUT_PORT); + new_port_type = PortType::OUTPUT; + } + + // Add this port to the clustered netlist. + clb_nlist.create_port(index, port.name, port.num_pins, new_port_type); } + VTR_ASSERT(clb_nlist.block_ports(index).size() == (unsigned)complex_block_pb_type->num_ports); - processPb(clb_block, index, clb_nlist->block_pb(index), clb_nlist->block_pb(index)->pb_route, num_primitives, loc_data, clb_nlist); - load_internal_to_block_net_nums(clb_nlist->block_type(index), clb_nlist->block_pb(index)->pb_route); + // Process the rest of the contents of the cluster block and the pb. + processPb(clb_block, + index, + pb, + pb->pb_route, + num_primitives, + loc_data); - //clb_nlist->block_pb(index)->pb_route.shrink_to_fit(); + load_internal_to_block_net_nums(&complex_block_type, pb->pb_route); } /** @@ -377,13 +441,17 @@ void processAttrsParams(pugi::xml_node Parent, const char* child_name, T& atom_n * @param pb physical block to use * @param loc_data xml location info for error reporting */ -static void processPb(pugi::xml_node Parent, const ClusterBlockId index, t_pb* pb, t_pb_routes& pb_route, int* num_primitives, const pugiutil::loc_data& loc_data, ClusteredNetlist* clb_nlist) { - int i, j, pb_index; - bool found; - const t_pb_type* pb_type; - - auto& atom_ctx = g_vpr_ctx.mutable_atom(); - +static void processPb(pugi::xml_node Parent, + const ClusterBlockId index, + t_pb* pb, + t_pb_routes& pb_route, + int& num_primitives, + const pugiutil::loc_data& loc_data) { + const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); + AtomLookup& atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); + AtomPBBimap& atom_pb_bimap = atom_lookup.mutable_atom_pb_bimap(); + + // Process the ports. auto inputs = pugiutil::get_single_child(Parent, "inputs", loc_data); processPorts(inputs, pb, pb_route, loc_data); @@ -393,213 +461,142 @@ static void processPb(pugi::xml_node Parent, const ClusterBlockId index, t_pb* p auto clocks = pugiutil::get_single_child(Parent, "clocks", loc_data); processPorts(clocks, pb, pb_route, loc_data); - int num_in_ports = 0; - int begin_out_port; - int end_out_port; - int begin_clock_port; - int end_clock_port; - - { - int num_out_ports = 0; - int num_clock_ports = 0; - for (i = 0; i < pb->pb_graph_node->pb_type->num_ports; i++) { - if (pb->pb_graph_node->pb_type->ports[i].is_clock - && pb->pb_graph_node->pb_type->ports[i].type == IN_PORT) { - num_clock_ports++; - } else if (!pb->pb_graph_node->pb_type->ports[i].is_clock - && pb->pb_graph_node->pb_type->ports[i].type == IN_PORT) { - num_in_ports++; - } else { - VTR_ASSERT(pb->pb_graph_node->pb_type->ports[i].type == OUT_PORT); - num_out_ports++; - } - } - - begin_out_port = num_in_ports; - end_out_port = begin_out_port + num_out_ports; - begin_clock_port = end_out_port; - end_clock_port = begin_clock_port + num_clock_ports; - } - - auto attrs = pugiutil::get_single_child(Parent, "attributes", loc_data, pugiutil::OPTIONAL); - auto params = pugiutil::get_single_child(Parent, "parameters", loc_data, pugiutil::OPTIONAL); - - pb_type = pb->pb_graph_node->pb_type; - - //Create the ports in the clb_nlist for the top-level pb - if (pb->is_root()) { - for (i = 0; i < num_in_ports; i++) { - clb_nlist->create_port(index, pb_type->ports[i].name, pb_type->ports[i].num_pins, PortType::INPUT); - } - for (i = begin_out_port; i < end_out_port; i++) { - clb_nlist->create_port(index, pb_type->ports[i].name, pb_type->ports[i].num_pins, PortType::OUTPUT); - } - for (i = begin_clock_port; i < end_clock_port; i++) { - clb_nlist->create_port(index, pb_type->ports[i].name, pb_type->ports[i].num_pins, PortType::CLOCK); - } - - VTR_ASSERT(clb_nlist->block_ports(index).size() == (unsigned)pb_type->num_ports); - } - + // Base-case: This is a primitive. + const t_pb_type* pb_type = pb->pb_graph_node->pb_type; if (pb_type->is_primitive()) { - /* A primitive type */ - AtomBlockId blk_id = atom_ctx.netlist().find_block(pb->name); + AtomBlockId blk_id = atom_netlist.find_block(pb->name); if (!blk_id) { VPR_FATAL_ERROR(VPR_ERROR_NET_F, ".net file and .blif file do not match, encountered unknown primitive %s in .net file.\n", pb->name); } - //Update atom netlist mapping + // Update atom netlist mapping VTR_ASSERT(blk_id); - atom_ctx.mutable_lookup().mutable_atom_pb_bimap().set_atom_pb(blk_id, pb); - atom_ctx.mutable_lookup().set_atom_clb(blk_id, index); - - auto atom_attrs = atom_ctx.netlist().block_attrs(blk_id); - auto atom_params = atom_ctx.netlist().block_params(blk_id); + atom_pb_bimap.set_atom_pb(blk_id, pb); + atom_lookup.set_atom_clb(blk_id, index); + + // Process the attributes and params. + auto atom_attrs = atom_netlist.block_attrs(blk_id); + auto atom_params = atom_netlist.block_params(blk_id); + auto attrs = pugiutil::get_single_child(Parent, "attributes", loc_data, pugiutil::OPTIONAL); + auto params = pugiutil::get_single_child(Parent, "parameters", loc_data, pugiutil::OPTIONAL); processAttrsParams(attrs, "attribute", atom_attrs, loc_data); processAttrsParams(params, "parameter", atom_params, loc_data); - (*num_primitives)++; - } else { - /* process children of child if exists */ + num_primitives++; + return; + } + + // This is not a primitive. Process children of child if exists. + + // Allocate the children for this pb. + const t_mode& pb_mode = pb_type->modes[pb->mode]; + int num_pb_type_children = pb_mode.num_pb_type_children; + pb->child_pbs = new t_pb*[num_pb_type_children]; + for (int i = 0; i < num_pb_type_children; i++) { + int num_child_pbs = pb_mode.pb_type_children[i].num_pb; + pb->child_pbs[i] = new t_pb[num_child_pbs]; + } - pb->child_pbs = new t_pb*[pb_type->modes[pb->mode].num_pb_type_children]; - for (i = 0; i < pb_type->modes[pb->mode].num_pb_type_children; i++) { - pb->child_pbs[i] = new t_pb[pb_type->modes[pb->mode].pb_type_children[i].num_pb]; + // Populate info for each physical block. + for (auto child = Parent.child("block"); child; child = child.next_sibling("block")) { + VTR_ASSERT(strcmp(child.name(), "block") == 0); + + auto instance_type = pugiutil::get_attribute(child, "instance", loc_data); + const Tokens tokens(instance_type.value()); + if (tokens.size() != 4 || tokens[0].type != e_token_type::STRING + || tokens[1].type != e_token_type::OPEN_SQUARE_BRACKET + || tokens[2].type != e_token_type::INT + || tokens[3].type != e_token_type::CLOSE_SQUARE_BRACKET) { + vpr_throw(VPR_ERROR_NET_F, loc_data.filename_c_str(), loc_data.line(child), + "Unknown syntax for instance %s in %s. Expected pb_type[instance_number].\n", + instance_type.value(), child.name()); } - /* Populate info for each physical block */ - for (auto child = Parent.child("block"); child; child = child.next_sibling("block")) { - VTR_ASSERT(strcmp(child.name(), "block") == 0); - - auto instance_type = pugiutil::get_attribute(child, "instance", loc_data); - const Tokens tokens(instance_type.value()); - if (tokens.size() != 4 || tokens[0].type != e_token_type::STRING - || tokens[1].type != e_token_type::OPEN_SQUARE_BRACKET - || tokens[2].type != e_token_type::INT - || tokens[3].type != e_token_type::CLOSE_SQUARE_BRACKET) { - vpr_throw(VPR_ERROR_NET_F, loc_data.filename_c_str(), loc_data.line(child), - "Unknown syntax for instance %s in %s. Expected pb_type[instance_number].\n", - instance_type.value(), child.name()); + t_pb* new_child_pb = nullptr; + int pb_index = UNDEFINED; + for (int i = 0; i < num_pb_type_children; i++) { + if (pb_mode.pb_type_children[i].name != tokens[0].data) { + continue; } - found = false; - pb_index = UNDEFINED; - for (i = 0; i < pb_type->modes[pb->mode].num_pb_type_children; i++) { - if (pb_type->modes[pb->mode].pb_type_children[i].name == tokens[0].data) { - pb_index = vtr::atoi(tokens[2].data); - if (pb_index < 0) { - vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), - "Instance number %d is negative instance %s in %s.\n", - pb_index, instance_type.value(), child.name()); - } - if (pb_index >= pb_type->modes[pb->mode].pb_type_children[i].num_pb) { - vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), - "Instance number exceeds # of pb available for instance %s in %s.\n", - instance_type.value(), child.name()); - } - if (pb->child_pbs[i][pb_index].pb_graph_node != nullptr) { - vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), - "node is used by two different blocks %s and %s.\n", - instance_type.value(), - pb->child_pbs[i][pb_index].name); - } - pb->child_pbs[i][pb_index].pb_graph_node = &pb->pb_graph_node->child_pb_graph_nodes[pb->mode][i][pb_index]; - found = true; - break; - } + pb_index = vtr::atoi(tokens[2].data); + if (pb_index < 0) { + vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), + "Instance number %d is negative instance %s in %s.\n", + pb_index, instance_type.value(), child.name()); } - if (!found) { + if (pb_index >= pb_mode.pb_type_children[i].num_pb) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), - "Unknown pb type %s.\n", instance_type.value()); + "Instance number exceeds # of pb available for instance %s in %s.\n", + instance_type.value(), child.name()); } + if (pb->child_pbs[i][pb_index].pb_graph_node != nullptr) { + vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), + "node is used by two different blocks %s and %s.\n", + instance_type.value(), + pb->child_pbs[i][pb_index].name); + } + new_child_pb = &pb->child_pbs[i][pb_index]; + new_child_pb->pb_graph_node = &pb->pb_graph_node->child_pb_graph_nodes[pb->mode][i][pb_index]; + new_child_pb->parent_pb = pb; + break; + } + if (new_child_pb == nullptr) { + vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), + "Unknown pb type %s.\n", instance_type.value()); + } - auto name = pugiutil::get_attribute(child, "name", loc_data); - if (0 != strcmp(name.value(), "open")) { - pb->child_pbs[i][pb_index].name = vtr::strdup(name.value()); - - /* Parse all pbs and CB internal nets*/ - atom_ctx.mutable_lookup().mutable_atom_pb_bimap().set_atom_pb(AtomBlockId::INVALID(), &pb->child_pbs[i][pb_index]); - - auto mode = child.attribute("mode"); - pb->child_pbs[i][pb_index].mode = 0; - found = false; - for (j = 0; j < pb->child_pbs[i][pb_index].pb_graph_node->pb_type->num_modes; j++) { - if (strcmp(mode.value(), pb->child_pbs[i][pb_index].pb_graph_node->pb_type->modes[j].name) == 0) { - pb->child_pbs[i][pb_index].mode = j; - found = true; - } - } - if (!found && !pb->child_pbs[i][pb_index].is_primitive()) { - vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), - "Unknown mode %s for cb %s #%d.\n", mode.value(), - pb->child_pbs[i][pb_index].name, pb_index); - } - pb->child_pbs[i][pb_index].parent_pb = pb; + atom_pb_bimap.set_atom_pb(AtomBlockId::INVALID(), new_child_pb); - processPb(child, index, &pb->child_pbs[i][pb_index], pb_route, num_primitives, loc_data, clb_nlist); - } else { - /* physical block has no used primitives but it may have used routing */ - pb->child_pbs[i][pb_index].name = nullptr; - atom_ctx.mutable_lookup().mutable_atom_pb_bimap().set_atom_pb(AtomBlockId::INVALID(), &pb->child_pbs[i][pb_index]); - - auto lookahead1 = pugiutil::get_first_child(child, "outputs", loc_data, pugiutil::OPTIONAL); - if (lookahead1) { - pugiutil::get_first_child(lookahead1, "port", loc_data); //Check that port child tag exists - auto mode = pugiutil::get_attribute(child, "mode", loc_data); - - pb->child_pbs[i][pb_index].mode = 0; - found = false; - for (j = 0; j < pb->child_pbs[i][pb_index].pb_graph_node->pb_type->num_modes; j++) { - if (strcmp(mode.value(), pb->child_pbs[i][pb_index].pb_graph_node->pb_type->modes[j].name) == 0) { - pb->child_pbs[i][pb_index].mode = j; - found = true; - } - } - if (!found && !pb->child_pbs[i][pb_index].is_primitive()) { - vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), - "Unknown mode %s for cb %s #%d.\n", mode.value(), - pb->child_pbs[i][pb_index].name, pb_index); - } - pb->child_pbs[i][pb_index].parent_pb = pb; - processPb(child, index, &pb->child_pbs[i][pb_index], pb_route, num_primitives, loc_data, clb_nlist); - } + // Set the name of the new pb. + pugi::xml_attribute mode; + auto name = pugiutil::get_attribute(child, "name", loc_data); + if (0 != strcmp(name.value(), "open")) { + new_child_pb->name = vtr::strdup(name.value()); + mode = child.attribute("mode"); + } else { + // hysical block has no used primitives but it may have used routing. + new_child_pb->name = nullptr; + auto lookahead1 = pugiutil::get_first_child(child, "outputs", loc_data, pugiutil::OPTIONAL); + if (!lookahead1) { + // If not used for routing, skip recursing into the pb. + continue; } + // Check that port child tag exists + pugiutil::get_first_child(lookahead1, "port", loc_data); + mode = pugiutil::get_attribute(child, "mode", loc_data); } - } -} - -/** - * @brief Adds net to hashtable of nets. - * - * If the net is "open", then this is a keyword so do not add it. - * If the net already exists, increase the count on that net - */ -static int add_net_to_hash(t_hash** nhash, const char* net_name, int* ncount) { - t_hash* hash_value; - if (strcmp(net_name, "open") == 0) { - return UNDEFINED; - } + // Set the mode of the new child pb. + const t_pb_type* new_child_pb_type = new_child_pb->pb_graph_node->pb_type; + new_child_pb->mode = 0; + bool found = false; + for (int j = 0; j < new_child_pb_type->num_modes; j++) { + if (strcmp(mode.value(), new_child_pb_type->modes[j].name) == 0) { + new_child_pb->mode = j; + found = true; + break; + } + } + if (!found && !new_child_pb->is_primitive()) { + vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(child), + "Unknown mode %s for cb %s #%d.\n", mode.value(), + new_child_pb->name, pb_index); + } - hash_value = insert_in_hash_table(nhash, net_name, *ncount); - if (hash_value->count == 1) { - VTR_ASSERT(*ncount == hash_value->index); - (*ncount)++; + processPb(child, index, new_child_pb, pb_route, num_primitives, loc_data); } - return hash_value->index; } -static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, const pugiutil::loc_data& loc_data) { - int i, j, num_tokens; - int in_port = 0, out_port = 0, clock_port = 0; - std::vector pins; - t_pb_graph_pin*** pin_node; - int *num_ptrs, num_sets; - bool found; +static void processPorts(pugi::xml_node Parent, + t_pb* pb, + t_pb_routes& pb_route, + const pugiutil::loc_data& loc_data) { + const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); - auto& atom_ctx = g_vpr_ctx.atom(); + const t_pb_type* pb_type = pb->pb_graph_node->pb_type; for (auto Cur = pugiutil::get_first_child(Parent, "port", loc_data, pugiutil::OPTIONAL); Cur; Cur = Cur.next_sibling("port")) { auto port_name = pugiutil::get_attribute(Cur, "name", loc_data); @@ -609,34 +606,35 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, //Traverse all the ports on the pb until we find the matching port name, //at that point in_port/clock_port/output_port will be the index associated //with that port - in_port = out_port = clock_port = 0; - found = false; - for (i = 0; i < pb->pb_graph_node->pb_type->num_ports; i++) { - if (0 == strcmp(pb->pb_graph_node->pb_type->ports[i].name, port_name.value())) { - found = true; + int in_port = 0; + int out_port = 0; + int clock_port = 0; + bool found_port_idx = false; + for (int i = 0; i < pb_type->num_ports; i++) { + const t_port& port = pb_type->ports[i]; + if (0 == strcmp(port.name, port_name.value())) { + found_port_idx = true; break; } - if (pb->pb_graph_node->pb_type->ports[i].is_clock - && pb->pb_graph_node->pb_type->ports[i].type == IN_PORT) { + if (port.is_clock && port.type == IN_PORT) { clock_port++; - } else if (!pb->pb_graph_node->pb_type->ports[i].is_clock - && pb->pb_graph_node->pb_type->ports[i].type == IN_PORT) { + } else if (!port.is_clock && port.type == IN_PORT) { in_port++; } else { - VTR_ASSERT(pb->pb_graph_node->pb_type->ports[i].type == OUT_PORT); + VTR_ASSERT(port.type == OUT_PORT); out_port++; } } - if (!found) { + if (!found_port_idx) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(Cur), "Unknown port %s for pb %s[%d].\n", port_name.value(), - pb->pb_graph_node->pb_type->name, + pb_type->name, pb->pb_graph_node->placement_index); } //Extract all the pins for this port - pins = vtr::StringToken(Cur.text().get()).split(" \t\n"); - num_tokens = pins.size(); + auto pins = vtr::StringToken(Cur.text().get()).split(" \t\n"); + int num_tokens = pins.size(); //Check that the number of pins from the netlist file matches the pb port's number of pins if (0 == strcmp(Parent.name(), "inputs")) { @@ -667,7 +665,7 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, if (0 == strcmp(Parent.name(), "inputs") || 0 == strcmp(Parent.name(), "clocks")) { if (pb->is_root()) { //We are processing a top-level pb, so these pins connect to inter-block nets - for (i = 0; i < num_tokens; i++) { + for (int i = 0; i < num_tokens; i++) { //Set rr_node_index to the pb_route for the appropriate port const t_pb_graph_pin* pb_gpin = nullptr; if (0 == strcmp(Parent.name(), "inputs")) { @@ -681,7 +679,7 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, if (strcmp(pins[i].c_str(), "open") != 0) { //For connected pins look-up the inter-block net index associated with it - AtomNetId net_id = atom_ctx.netlist().find_net(pins[i].c_str()); + AtomNetId net_id = atom_netlist.find_net(pins[i].c_str()); if (!net_id) { VPR_FATAL_ERROR(VPR_ERROR_NET_F, ".blif and .net do not match, unknown net %s found in .net file.\n.", @@ -695,7 +693,7 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, } } else { //We are processing an internal pb - for (i = 0; i < num_tokens; i++) { + for (int i = 0; i < num_tokens; i++) { if (0 == strcmp(pins[i].c_str(), "open")) { continue; } @@ -712,7 +710,9 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, std::string interconnect_name = pins[i].substr(loc, std::string::npos); // Interconnect name is the net name - pin_node = alloc_and_load_port_pin_ptrs_from_string( + int* num_ptrs = nullptr; + int num_sets = 0; + t_pb_graph_pin*** pin_node = alloc_and_load_port_pin_ptrs_from_string( pb->pb_graph_node->pb_type->parent_mode->interconnect[0].line_num, pb->pb_graph_node->parent_pb_graph_node, pb->pb_graph_node->parent_pb_graph_node->child_pb_graph_nodes[pb->parent_pb->mode], @@ -734,14 +734,14 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, pb_route[rr_node_index].pb_graph_pin = pb_gpin; VTR_ASSERT(pb_route[rr_node_index].pb_graph_pin->pin_number == i); - found = false; - for (j = 0; j < pin_node[0][0]->num_output_edges; j++) { + bool found = false; + for (int j = 0; j < pin_node[0][0]->num_output_edges; j++) { if (0 == strcmp(interconnect_name.c_str(), pin_node[0][0]->output_edges[j]->interconnect->name)) { found = true; break; } } - for (j = 0; j < num_sets; j++) { + for (int j = 0; j < num_sets; j++) { delete[] pin_node[j]; } delete[] pin_node; @@ -758,11 +758,11 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, if (0 == strcmp(Parent.name(), "outputs")) { if (pb->pb_graph_node->is_primitive()) { /* primitives are drivers of nets */ - for (i = 0; i < num_tokens; i++) { + for (int i = 0; i < num_tokens; i++) { const t_pb_graph_pin* pb_gpin = &pb->pb_graph_node->output_pins[out_port][i]; int rr_node_index = pb_gpin->pin_count_in_cluster; if (strcmp(pins[i].c_str(), "open") != 0) { - AtomNetId net_id = atom_ctx.netlist().find_net(pins[i].c_str()); + AtomNetId net_id = atom_netlist.find_net(pins[i].c_str()); if (!net_id) { VPR_FATAL_ERROR(VPR_ERROR_NET_F, ".blif and .net do not match, unknown net %s found in .net file.\n", @@ -774,7 +774,7 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, } } } else { - for (i = 0; i < num_tokens; i++) { + for (int i = 0; i < num_tokens; i++) { if (0 == strcmp(pins[i].c_str(), "open")) { continue; } @@ -789,7 +789,9 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, loc += 2; //Skip over the '->' std::string interconnect_name = pins[i].substr(loc, std::string::npos); - pin_node = alloc_and_load_port_pin_ptrs_from_string( + int* num_ptrs = nullptr; + int num_sets = 0; + t_pb_graph_pin*** pin_node = alloc_and_load_port_pin_ptrs_from_string( pb->pb_graph_node->pb_type->modes[pb->mode].interconnect->line_num, pb->pb_graph_node, pb->pb_graph_node->child_pb_graph_nodes[pb->mode], @@ -803,14 +805,14 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, pb_route[rr_node_index].driver_pb_pin_id = pin_node[0][0]->pin_count_in_cluster; pb_route[rr_node_index].pb_graph_pin = &pb->pb_graph_node->output_pins[out_port][i]; - found = false; - for (j = 0; j < pin_node[0][0]->num_output_edges; j++) { + bool found = false; + for (int j = 0; j < pin_node[0][0]->num_output_edges; j++) { if (0 == strcmp(interconnect_name.c_str(), pin_node[0][0]->output_edges[j]->interconnect->name)) { found = true; break; } } - for (j = 0; j < num_sets; j++) { + for (int j = 0; j < num_sets; j++) { delete[] pin_node[j]; } delete[] pin_node; @@ -837,7 +839,7 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(pin_rot_map), "Failed to find port with name '%s' on pb %s[%d]\n", port_name, - pb->pb_graph_node->pb_type->name, pb->pb_graph_node->placement_index); + pb_type->name, pb->pb_graph_node->placement_index); } auto pin_mapping = vtr::StringToken(pin_rot_map.text().get()).split(" \t\n"); @@ -845,11 +847,11 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, if (size_t(pb_gport->num_pins) != pin_mapping.size()) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(pin_rot_map), "Incorrect # pins %zu (expected %d) found for port %s rotation map in pb %s[%d].\n", - pin_mapping.size(), pb_gport->num_pins, port_name, pb->pb_graph_node->pb_type->name, + pin_mapping.size(), pb_gport->num_pins, port_name, pb_type->name, pb->pb_graph_node->placement_index); } - for (int ipin = 0; ipin < (int)pins.size(); ++ipin) { + for (size_t ipin = 0; ipin < pin_mapping.size(); ++ipin) { if (pin_mapping[ipin] == "open") continue; //No mapping for this physical pin to atom pin int atom_pin_index = vtr::atoi(pin_mapping[ipin]); @@ -874,29 +876,24 @@ static void processPorts(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, * @brief This function updates the nets list and the connections between * that list and the complex block */ -static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) { - int j, k, ipin; - int ext_ncount = 0; - t_hash** ext_nhash; - t_pb_graph_pin* pb_graph_pin; - ClusterNetId clb_net_id; - - auto& atom_ctx = g_vpr_ctx.atom(); - - ext_nhash = alloc_hash_table(); - - t_logical_block_type_ptr block_type; +static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, + const AtomNetlist& atom_netlist) { + // Create a set of all unique net names that we can see. We want to ignore + // any nets with the name "open", so we insert that into the map and later + // we just ignore it if it was seen, + std::unordered_set seen_net_names; + seen_net_names.insert("open"); /* Assumes that complex block pins are ordered inputs, outputs, globals */ clb_nlist.verify(); /* Determine the external nets of complex block */ - for (auto blk_id : clb_nlist.blocks()) { - block_type = clb_nlist.block_type(blk_id); + for (ClusterBlockId blk_id : clb_nlist.blocks()) { + t_logical_block_type_ptr block_type = clb_nlist.block_type(blk_id); const t_pb* pb = clb_nlist.block_pb(blk_id); - ipin = 0; + int ipin = 0; VTR_ASSERT(block_type->pb_type->num_input_pins + block_type->pb_type->num_output_pins + block_type->pb_type->num_clock_pins @@ -907,17 +904,17 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) { int num_clock_ports = pb->pb_graph_node->num_clock_ports; //Load the external nets connected to input ports - for (j = 0; j < num_input_ports; j++) { + for (int j = 0; j < num_input_ports; j++) { ClusterPortId input_port_id = clb_nlist.find_port(blk_id, block_type->pb_type->ports[j].name); - for (k = 0; k < pb->pb_graph_node->num_input_pins[j]; k++) { - pb_graph_pin = &pb->pb_graph_node->input_pins[j][k]; + for (int k = 0; k < pb->pb_graph_node->num_input_pins[j]; k++) { + t_pb_graph_pin* pb_graph_pin = &pb->pb_graph_node->input_pins[j][k]; VTR_ASSERT(pb_graph_pin->pin_count_in_cluster == ipin); if (pb->pb_route.count(pb_graph_pin->pin_count_in_cluster)) { AtomNetId atom_net_id = pb->pb_route[pb_graph_pin->pin_count_in_cluster].atom_net_id; if (atom_net_id) { - add_net_to_hash(ext_nhash, atom_ctx.netlist().net_name(atom_net_id).c_str(), &ext_ncount); - clb_net_id = clb_nlist.create_net(atom_ctx.netlist().net_name(atom_net_id)); + seen_net_names.insert(atom_netlist.net_name(atom_net_id)); + ClusterNetId clb_net_id = clb_nlist.create_net(atom_netlist.net_name(atom_net_id)); clb_nlist.create_pin(input_port_id, (BitIndex)k, clb_net_id, PinType::SINK, ipin); } } @@ -926,20 +923,20 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) { } //Load the external nets connected to output ports - for (j = 0; j < num_output_ports; j++) { + for (int j = 0; j < num_output_ports; j++) { ClusterPortId output_port_id = clb_nlist.find_port(blk_id, block_type->pb_type->ports[j + num_input_ports].name); - for (k = 0; k < pb->pb_graph_node->num_output_pins[j]; k++) { - pb_graph_pin = &pb->pb_graph_node->output_pins[j][k]; + for (int k = 0; k < pb->pb_graph_node->num_output_pins[j]; k++) { + t_pb_graph_pin* pb_graph_pin = &pb->pb_graph_node->output_pins[j][k]; VTR_ASSERT(pb_graph_pin->pin_count_in_cluster == ipin); if (pb->pb_route.count(pb_graph_pin->pin_count_in_cluster)) { AtomNetId atom_net_id = pb->pb_route[pb_graph_pin->pin_count_in_cluster].atom_net_id; if (atom_net_id) { - add_net_to_hash(ext_nhash, atom_ctx.netlist().net_name(atom_net_id).c_str(), &ext_ncount); - clb_net_id = clb_nlist.create_net(atom_ctx.netlist().net_name(atom_net_id)); + seen_net_names.insert(atom_netlist.net_name(atom_net_id)); + ClusterNetId clb_net_id = clb_nlist.create_net(atom_netlist.net_name(atom_net_id)); - AtomPinId atom_net_driver = atom_ctx.netlist().net_driver(atom_net_id); - bool driver_is_constant = atom_ctx.netlist().pin_is_constant(atom_net_driver); + AtomPinId atom_net_driver = atom_netlist.net_driver(atom_net_id); + bool driver_is_constant = atom_netlist.pin_is_constant(atom_net_driver); clb_nlist.create_pin(output_port_id, (BitIndex)k, clb_net_id, PinType::DRIVER, ipin, driver_is_constant); @@ -951,17 +948,17 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) { } //Load the external nets connected to clock ports - for (j = 0; j < num_clock_ports; j++) { + for (int j = 0; j < num_clock_ports; j++) { ClusterPortId clock_port_id = clb_nlist.find_port(blk_id, block_type->pb_type->ports[j + num_input_ports + num_output_ports].name); - for (k = 0; k < pb->pb_graph_node->num_clock_pins[j]; k++) { - pb_graph_pin = &pb->pb_graph_node->clock_pins[j][k]; + for (int k = 0; k < pb->pb_graph_node->num_clock_pins[j]; k++) { + t_pb_graph_pin* pb_graph_pin = &pb->pb_graph_node->clock_pins[j][k]; VTR_ASSERT(pb_graph_pin->pin_count_in_cluster == ipin); if (pb->pb_route.count(pb_graph_pin->pin_count_in_cluster)) { AtomNetId atom_net_id = pb->pb_route[pb_graph_pin->pin_count_in_cluster].atom_net_id; if (atom_net_id) { - add_net_to_hash(ext_nhash, atom_ctx.netlist().net_name(atom_net_id).c_str(), &ext_ncount); - clb_net_id = clb_nlist.create_net(atom_ctx.netlist().net_name(atom_net_id)); + seen_net_names.insert(atom_netlist.net_name(atom_net_id)); + ClusterNetId clb_net_id = clb_nlist.create_net(atom_netlist.net_name(atom_net_id)); clb_nlist.create_pin(clock_port_id, (BitIndex)k, clb_net_id, PinType::SINK, ipin); } } @@ -972,18 +969,17 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) { clb_nlist.verify(); - vtr::vector count(ext_ncount); - /* complete load of external nets so that each net points back to the blocks, * and blocks point back to net pins */ - for (auto blk_id : clb_nlist.blocks()) { - block_type = clb_nlist.block_type(blk_id); + vtr::vector count(clb_nlist.nets().size(), 0); + for (ClusterBlockId blk_id : clb_nlist.blocks()) { + t_logical_block_type_ptr block_type = clb_nlist.block_type(blk_id); auto tile_type = pick_physical_type(block_type); - for (j = 0; j < block_type->pb_type->num_pins; j++) { + for (int j = 0; j < block_type->pb_type->num_pins; j++) { int physical_pin = get_physical_pin(tile_type, block_type, j); //Iterate through each pin of the block, and see if there is a net allocated/used for it - clb_net_id = clb_nlist.block_net(blk_id, j); + ClusterNetId clb_net_id = clb_nlist.block_net(blk_id, j); if (clb_net_id != ClusterNetId::INVALID()) { //Verify old and new CLB netlists have the same # of pins per net @@ -1023,11 +1019,14 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) { } /* Error check global and non global signals */ - VTR_ASSERT(ext_ncount == static_cast(clb_nlist.nets().size())); + // The number of unique net names seen is the number of names in the net names + // set, minus the "open" nets. + int num_unique_net_names = seen_net_names.size() - 1; + VTR_ASSERT(static_cast(clb_nlist.nets().size()) == num_unique_net_names); for (auto net_id : clb_nlist.nets()) { for (auto pin_id : clb_nlist.net_sinks(net_id)) { bool is_ignored_net = clb_nlist.net_is_ignored(net_id); - block_type = clb_nlist.block_type(clb_nlist.pin_block(pin_id)); + t_logical_block_type_ptr block_type = clb_nlist.block_type(clb_nlist.pin_block(pin_id)); auto tile_type = pick_physical_type(block_type); int logical_pin = clb_nlist.pin_logical_index(pin_id); int physical_pin = get_physical_pin(tile_type, block_type, logical_pin); @@ -1039,8 +1038,6 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist) { } } } - - free_hash_table(ext_nhash); } static void mark_constant_generators(const ClusteredNetlist& clb_nlist, int verbosity) { @@ -1053,27 +1050,25 @@ static void mark_constant_generators(const ClusteredNetlist& clb_nlist, int verb } static size_t mark_constant_generators_rec(const t_pb* pb, const t_pb_routes& pb_route, int verbosity) { - int i, j; - t_pb_type* pb_type; - bool const_gen; - size_t const_gen_count = 0; + const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); - auto& atom_ctx = g_vpr_ctx.atom(); + const t_pb_type* pb_type = pb->pb_graph_node->pb_type; - if (pb->pb_graph_node->pb_type->blif_model == nullptr) { + size_t const_gen_count = 0; + if (pb_type->blif_model == nullptr) { // Check the model name to see if it exists, iterate through children if it does - for (i = 0; i < pb->pb_graph_node->pb_type->modes[pb->mode].num_pb_type_children; i++) { - pb_type = &(pb->pb_graph_node->pb_type->modes[pb->mode].pb_type_children[i]); - for (j = 0; j < pb_type->num_pb; j++) { + for (int i = 0; i < pb_type->modes[pb->mode].num_pb_type_children; i++) { + const t_pb_type* child_pb_type = &(pb_type->modes[pb->mode].pb_type_children[i]); + for (int j = 0; j < child_pb_type->num_pb; j++) { if (pb->child_pbs[i][j].name != nullptr) { const_gen_count += mark_constant_generators_rec(&(pb->child_pbs[i][j]), pb_route, verbosity); } } } - } else if (strcmp(pb->pb_graph_node->pb_type->blif_model, LogicalModels::MODEL_INPUT) != 0) { - const_gen = true; - for (i = 0; i < pb->pb_graph_node->num_input_ports && const_gen == true; i++) { - for (j = 0; j < pb->pb_graph_node->num_input_pins[i] && const_gen == true; j++) { + } else if (strcmp(pb_type->blif_model, LogicalModels::MODEL_INPUT) != 0) { + bool const_gen = true; + for (int i = 0; i < pb->pb_graph_node->num_input_ports && const_gen == true; i++) { + for (int j = 0; j < pb->pb_graph_node->num_input_pins[i] && const_gen == true; j++) { int cluster_pin_idx = pb->pb_graph_node->input_pins[i][j].pin_count_in_cluster; if (!pb_route.count(cluster_pin_idx)) continue; if (pb_route[cluster_pin_idx].atom_net_id) { @@ -1081,8 +1076,8 @@ static size_t mark_constant_generators_rec(const t_pb* pb, const t_pb_routes& pb } } } - for (i = 0; i < pb->pb_graph_node->num_clock_ports && const_gen == true; i++) { - for (j = 0; j < pb->pb_graph_node->num_clock_pins[i] && const_gen == true; j++) { + for (int i = 0; i < pb->pb_graph_node->num_clock_ports && const_gen == true; i++) { + for (int j = 0; j < pb->pb_graph_node->num_clock_pins[i] && const_gen == true; j++) { int cluster_pin_idx = pb->pb_graph_node->clock_pins[i][j].pin_count_in_cluster; if (!pb_route.count(cluster_pin_idx)) continue; if (pb_route[cluster_pin_idx].atom_net_id) { @@ -1092,15 +1087,15 @@ static size_t mark_constant_generators_rec(const t_pb* pb, const t_pb_routes& pb } if (const_gen == true) { VTR_LOGV(verbosity > 2, "%s is a constant generator.\n", pb->name); - ++const_gen_count; - for (i = 0; i < pb->pb_graph_node->num_output_ports; i++) { - for (j = 0; j < pb->pb_graph_node->num_output_pins[i]; j++) { + const_gen_count++; + for (int i = 0; i < pb->pb_graph_node->num_output_ports; i++) { + for (int j = 0; j < pb->pb_graph_node->num_output_pins[i]; j++) { int cluster_pin_idx = pb->pb_graph_node->output_pins[i][j].pin_count_in_cluster; if (!pb_route.count(cluster_pin_idx)) continue; if (pb_route[cluster_pin_idx].atom_net_id) { AtomNetId net_id = pb_route[pb->pb_graph_node->output_pins[i][j].pin_count_in_cluster].atom_net_id; - AtomPinId driver_pin_id = atom_ctx.netlist().net_driver(net_id); - VTR_ASSERT(atom_ctx.netlist().pin_is_constant(driver_pin_id)); + AtomPinId driver_pin_id = atom_netlist.net_driver(net_id); + VTR_ASSERT(atom_netlist.pin_is_constant(driver_pin_id)); } } } @@ -1109,18 +1104,6 @@ static size_t mark_constant_generators_rec(const t_pb* pb, const t_pb_routes& pb return const_gen_count; } -static t_pb_routes alloc_pb_route(t_pb_graph_node* /*pb_graph_node*/) { - t_pb_routes pb_routes; - //t_pb_route *pb_route; - //int num_pins = pb_graph_node->total_pb_pins; - - //VTR_ASSERT(pb_graph_node->parent_pb_graph_node == nullptr); [> This function only operates on top-level pb_graph_node <] - - //pb_route = new t_pb_route[num_pins]; - - return pb_routes; -} - static void load_internal_to_block_net_nums(const t_logical_block_type_ptr type, t_pb_routes& pb_route) { int num_pins = type->pb_graph_head->total_pb_pins; @@ -1155,23 +1138,24 @@ static void load_atom_index_for_pb_pin(t_pb_routes& pb_route, int ipin) { * associated with each connected AtomPinId */ static void load_atom_pin_mapping(const ClusteredNetlist& clb_nlist) { - auto& atom_ctx = g_vpr_ctx.atom(); + const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); + const AtomPBBimap& atom_pb_bimap = g_vpr_ctx.atom().lookup().atom_pb_bimap(); - for (const AtomBlockId blk : atom_ctx.netlist().blocks()) { - const t_pb* pb = atom_ctx.lookup().atom_pb_bimap().atom_pb(blk); + for (AtomBlockId blk : atom_netlist.blocks()) { + const t_pb* pb = atom_pb_bimap.atom_pb(blk); VTR_ASSERT_MSG(pb, "Atom block must have a matching PB"); const t_pb_graph_node* gnode = pb->pb_graph_node; - VTR_ASSERT_MSG(gnode->pb_type->model_id == atom_ctx.netlist().block_model(blk), + VTR_ASSERT_MSG(gnode->pb_type->model_id == atom_netlist.block_model(blk), "Atom block PB must match BLIF model"); - for (int iport = 0; iport < gnode->num_input_ports; ++iport) { + for (int iport = 0; iport < gnode->num_input_ports; iport++) { if (gnode->num_input_pins[iport] <= 0) continue; - const AtomPortId port = atom_ctx.netlist().find_atom_port(blk, gnode->input_pins[iport][0].port->model_port); + const AtomPortId port = atom_netlist.find_atom_port(blk, gnode->input_pins[iport][0].port->model_port); if (!port) continue; - for (int ipin = 0; ipin < gnode->num_input_pins[iport]; ++ipin) { + for (int ipin = 0; ipin < gnode->num_input_pins[iport]; ipin++) { const t_pb_graph_pin* gpin = &gnode->input_pins[iport][ipin]; VTR_ASSERT(gpin); @@ -1179,13 +1163,13 @@ static void load_atom_pin_mapping(const ClusteredNetlist& clb_nlist) { } } - for (int iport = 0; iport < gnode->num_output_ports; ++iport) { + for (int iport = 0; iport < gnode->num_output_ports; iport++) { if (gnode->num_output_pins[iport] <= 0) continue; - const AtomPortId port = atom_ctx.netlist().find_atom_port(blk, gnode->output_pins[iport][0].port->model_port); + const AtomPortId port = atom_netlist.find_atom_port(blk, gnode->output_pins[iport][0].port->model_port); if (!port) continue; - for (int ipin = 0; ipin < gnode->num_output_pins[iport]; ++ipin) { + for (int ipin = 0; ipin < gnode->num_output_pins[iport]; ipin++) { const t_pb_graph_pin* gpin = &gnode->output_pins[iport][ipin]; VTR_ASSERT(gpin); @@ -1193,10 +1177,10 @@ static void load_atom_pin_mapping(const ClusteredNetlist& clb_nlist) { } } - for (int iport = 0; iport < gnode->num_clock_ports; ++iport) { + for (int iport = 0; iport < gnode->num_clock_ports; iport++) { if (gnode->num_clock_pins[iport] <= 0) continue; - const AtomPortId port = atom_ctx.netlist().find_atom_port(blk, gnode->clock_pins[iport][0].port->model_port); + const AtomPortId port = atom_netlist.find_atom_port(blk, gnode->clock_pins[iport][0].port->model_port); if (!port) continue; for (int ipin = 0; ipin < gnode->num_clock_pins[iport]; ++ipin) { @@ -1210,11 +1194,12 @@ static void load_atom_pin_mapping(const ClusteredNetlist& clb_nlist) { } void set_atom_pin_mapping(const ClusteredNetlist& clb_nlist, const AtomBlockId atom_blk, const AtomPortId atom_port, const t_pb_graph_pin* gpin) { - auto& atom_ctx = g_vpr_ctx.mutable_atom(); + const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); + AtomLookup& atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); - VTR_ASSERT(atom_ctx.netlist().port_block(atom_port) == atom_blk); + VTR_ASSERT(atom_netlist.port_block(atom_port) == atom_blk); - ClusterBlockId clb_index = atom_ctx.lookup().atom_clb(atom_blk); + ClusterBlockId clb_index = atom_lookup.atom_clb(atom_blk); VTR_ASSERT(clb_index != ClusterBlockId::INVALID()); const t_pb* clb_pb = clb_nlist.block_pb(clb_index); @@ -1222,23 +1207,23 @@ void set_atom_pin_mapping(const ClusteredNetlist& clb_nlist, const AtomBlockId a return; } - const t_pb_route* pb_route = &clb_pb->pb_route[gpin->pin_count_in_cluster]; + const t_pb_route& pb_route = clb_pb->pb_route[gpin->pin_count_in_cluster]; - if (!pb_route->atom_net_id) { + if (!pb_route.atom_net_id) { return; } - const t_pb* atom_pb = atom_ctx.lookup().atom_pb_bimap().atom_pb(atom_blk); + const t_pb* atom_pb = atom_lookup.atom_pb_bimap().atom_pb(atom_blk); //This finds the index within the atom port to which the current gpin //is mapped. Note that this accounts for any applied pin rotations //(e.g. on LUT inputs) BitIndex atom_pin_bit_index = atom_pb->atom_pin_bit_index(gpin); - AtomPinId atom_pin = atom_ctx.netlist().port_pin(atom_port, atom_pin_bit_index); + AtomPinId atom_pin = atom_netlist.port_pin(atom_port, atom_pin_bit_index); - VTR_ASSERT(pb_route->atom_net_id == atom_ctx.netlist().pin_net(atom_pin)); + VTR_ASSERT(pb_route.atom_net_id == atom_netlist.pin_net(atom_pin)); //Save the mapping - atom_ctx.mutable_lookup().set_atom_pin_pb_graph_pin(atom_pin, gpin); + atom_lookup.set_atom_pin_pb_graph_pin(atom_pin, gpin); } From 5ad099b81fbb1eff02429d43d2ccb215d60b8da0 Mon Sep 17 00:00:00 2001 From: AlexandreSinger Date: Sat, 1 Nov 2025 22:57:44 -0400 Subject: [PATCH 2/3] [Pack] Renamed Functions and Removed Auto Uses in Read Netlist --- vpr/src/base/read_netlist.cpp | 196 ++++++++++++++++++---------------- 1 file changed, 102 insertions(+), 94 deletions(-) diff --git a/vpr/src/base/read_netlist.cpp b/vpr/src/base/read_netlist.cpp index 7ee40e97c9..6337f839ab 100644 --- a/vpr/src/base/read_netlist.cpp +++ b/vpr/src/base/read_netlist.cpp @@ -18,6 +18,7 @@ #include "atom_lookup.h" #include "atom_pb_bimap.h" +#include "clustered_netlist_fwd.h" #include "physical_types.h" #include "physical_types_util.h" #include "pugixml.hpp" @@ -26,6 +27,7 @@ #include "vpr_context.h" #include "vtr_assert.h" +#include "vtr_time.h" #include "vtr_util.h" #include "vtr_log.h" #include "vtr_digest.h" @@ -42,24 +44,24 @@ static const char* netlist_file_name = nullptr; -static void processPorts(pugi::xml_node Parent, - t_pb* pb, - t_pb_routes& pb_route, - const pugiutil::loc_data& loc_data); - -static void processPb(pugi::xml_node Parent, - const ClusterBlockId index, - t_pb* pb, - t_pb_routes& pb_route, - int& num_primitives, - const pugiutil::loc_data& loc_data); - -static void processComplexBlock(pugi::xml_node Parent, - const ClusterBlockId index, - int& num_primitives, - const pugiutil::loc_data& loc_data, - const std::unordered_map& logical_block_type_name_to_index, - ClusteredNetlist& clb_nlist); +static void process_ports(pugi::xml_node Parent, + t_pb* pb, + t_pb_routes& pb_route, + const pugiutil::loc_data& loc_data); + +static void process_pb(pugi::xml_node Parent, + const ClusterBlockId index, + t_pb* pb, + t_pb_routes& pb_route, + int& num_primitives, + const pugiutil::loc_data& loc_data); + +static void process_complex_block(pugi::xml_node Parent, + const ClusterBlockId index, + int& num_primitives, + const pugiutil::loc_data& loc_data, + const std::unordered_map& logical_block_type_name_to_index, + ClusteredNetlist& clb_nlist); static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, AtomNetlist& atom_netlist, @@ -90,10 +92,9 @@ ClusteredNetlist read_netlist(const char* net_file, AtomLookup& atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); const auto& logical_block_types = g_vpr_ctx.device().logical_block_types; - clock_t begin = clock(); + vtr::ScopedStartFinishTimer read_netlist_timer("Loading packed FPGA netlist file."); /* Parse the file */ - VTR_LOG("Begin loading packed FPGA netlist file.\n"); // Prepare a lookup between the logical block type name and the block type's index. // This is used when parsing the blocks for their type. @@ -120,14 +121,14 @@ ClusteredNetlist read_netlist(const char* net_file, netlist_file_name = net_file; /* Root node should be block */ - auto top = doc.child("block"); + pugi::xml_node top = doc.child("block"); if (!top) { vpr_throw(VPR_ERROR_NET_F, net_file, loc_data.line(top), "Root element must be 'block'.\n"); } /* Check top-level netlist attributes */ - auto top_name = top.attribute("name"); + pugi::xml_attribute top_name = top.attribute("name"); if (!top_name) { vpr_throw(VPR_ERROR_NET_F, net_file, loc_data.line(top), "Root element must have a 'name' attribute.\n"); @@ -136,7 +137,7 @@ ClusteredNetlist read_netlist(const char* net_file, VTR_LOG("Netlist generated from file '%s'.\n", top_name.value()); //Verify top level attributes - auto top_instance = pugiutil::get_attribute(top, "instance", loc_data); + pugi::xml_attribute top_instance = pugiutil::get_attribute(top, "instance", loc_data); if (strcmp(top_instance.value(), "FPGA_packed_netlist[0]") != 0) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(top), @@ -144,7 +145,7 @@ ClusteredNetlist read_netlist(const char* net_file, top_instance.value()); } - auto architecture_id = top.attribute("architecture_id"); + pugi::xml_attribute architecture_id = top.attribute("architecture_id"); if (architecture_id) { //Netlist file has an architecture id, make sure it is //consistent with the loaded architecture file. @@ -153,7 +154,7 @@ ClusteredNetlist read_netlist(const char* net_file, //to remain compatible with old .net files std::string arch_id = architecture_id.value(); if (arch_id != arch->architecture_id) { - auto msg = vtr::string_fmt( + std::string msg = vtr::string_fmt( "Netlist was generated from a different architecture file" " (loaded architecture ID: %s, netlist file architecture ID: %s)", arch->architecture_id.c_str(), arch_id.c_str()); @@ -165,7 +166,7 @@ ClusteredNetlist read_netlist(const char* net_file, } } - auto atom_netlist_id = top.attribute("atom_netlist_id"); + pugi::xml_attribute atom_netlist_id = top.attribute("atom_netlist_id"); if (atom_netlist_id) { //Netlist file has an_atom netlist_id, make sure it is //consistent with the loaded atom netlist. @@ -174,7 +175,7 @@ ClusteredNetlist read_netlist(const char* net_file, //to remain compatible with old .net files std::string atom_nl_id = atom_netlist_id.value(); if (atom_nl_id != atom_netlist.netlist_id()) { - auto msg = vtr::string_fmt( + std::string msg = vtr::string_fmt( "Netlist was generated from a different atom netlist file" " (loaded atom netlist ID: %s, packed netlist atom netlist ID: %s)", atom_nl_id.c_str(), atom_netlist.netlist_id().c_str()); @@ -187,13 +188,13 @@ ClusteredNetlist read_netlist(const char* net_file, } //Collect top level I/Os - auto top_inputs = pugiutil::get_single_child(top, "inputs", loc_data); + pugi::xml_node top_inputs = pugiutil::get_single_child(top, "inputs", loc_data); auto circuit_inputs = vtr::StringToken(top_inputs.text().get()).split(" \t\n"); - auto top_outputs = pugiutil::get_single_child(top, "outputs", loc_data); + pugi::xml_node top_outputs = pugiutil::get_single_child(top, "outputs", loc_data); auto circuit_outputs = vtr::StringToken(top_outputs.text().get()).split(" \t\n"); - auto top_clocks = pugiutil::get_single_child(top, "clocks", loc_data); + pugi::xml_node top_clocks = pugiutil::get_single_child(top, "clocks", loc_data); auto circuit_clocks = vtr::StringToken(top_clocks.text().get()).split(" \t\n"); /* Parse all CLB blocks and all nets*/ @@ -209,13 +210,13 @@ ClusteredNetlist read_netlist(const char* net_file, /* Process netlist */ unsigned i = 0; int num_primitives = 0; - for (auto curr_block = top.child("block"); curr_block; curr_block = curr_block.next_sibling("block")) { - processComplexBlock(curr_block, - ClusterBlockId(i), - num_primitives, - loc_data, - logical_block_type_name_to_index, - clb_nlist); + for (pugi::xml_node curr_block = top.child("block"); curr_block; curr_block = curr_block.next_sibling("block")) { + process_complex_block(curr_block, + ClusterBlockId(i), + num_primitives, + loc_data, + logical_block_type_name_to_index, + clb_nlist); i++; } VTR_ASSERT(bcount == i); @@ -224,7 +225,7 @@ ClusteredNetlist read_netlist(const char* net_file, VTR_ASSERT(static_cast(num_primitives) == atom_netlist.blocks().size()); /* Error check */ - for (auto blk_id : atom_netlist.blocks()) { + for (AtomBlockId blk_id : atom_netlist.blocks()) { if (atom_lookup.atom_pb_bimap().atom_pb(blk_id) == nullptr) { VPR_FATAL_ERROR(VPR_ERROR_NET_F, ".blif file and .net file do not match, .net file missing atom %s.\n", @@ -247,22 +248,23 @@ ClusteredNetlist read_netlist(const char* net_file, /* TODO: create this function later * check_top_IO_matches_IO_blocks(circuit_inputs, circuit_outputs, circuit_clocks, blist, bcount); */ - clock_t end = clock(); - - VTR_LOG("Finished loading packed FPGA netlist file (took %g seconds).\n", (float)(end - begin) / CLOCKS_PER_SEC); - return clb_nlist; } +/** + * @brief After the clustered netlist has been created, many of the atom + * netlist datastructures will become out of date. Need to sync the + * clustered netlist with the atom netlist. + */ static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, AtomNetlist& atom_netlist, AtomLookup& atom_lookup) { - /* load mapping between external nets and all nets */ + // Load mapping between external nets and all nets. for (AtomNetId net_id : atom_netlist.nets()) { atom_lookup.remove_atom_net(net_id); } - //Save the mapping between clb and atom nets + // Save the mapping between clb and atom nets for (ClusterNetId clb_net_id : clb_nlist.nets()) { AtomNetId net_id = atom_netlist.find_net(clb_nlist.net_name(clb_net_id)); VTR_ASSERT(net_id); @@ -270,9 +272,8 @@ static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, } // Mark ignored and global atom nets - /* We have to make set the following variables after the mapping between cluster nets and atom nets - * is created - */ + // We have to make set the following variables after the mapping between cluster nets and atom nets + // is created for (ClusterNetId clb_net : clb_nlist.nets()) { AtomNetId atom_net = atom_lookup.atom_net(clb_net); VTR_ASSERT(atom_net != AtomNetId::INVALID()); @@ -284,7 +285,7 @@ static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, } } - /* load mapping between atom pins and pb_graph_pins */ + // Load mapping between atom pins and pb_graph_pins load_atom_pin_mapping(clb_nlist); } @@ -295,7 +296,7 @@ static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, * @param index index of the CLB to allocate and load information into * @param loc_data xml location info for error reporting */ -static void processComplexBlock(pugi::xml_node clb_block, +static void process_complex_block(pugi::xml_node clb_block, const ClusterBlockId index, int& num_primitives, const pugiutil::loc_data& loc_data, @@ -304,8 +305,8 @@ static void processComplexBlock(pugi::xml_node clb_block, const auto& logical_block_types = g_vpr_ctx.device().logical_block_types; //Parse cb attributes - auto block_name = pugiutil::get_attribute(clb_block, "name", loc_data); - auto block_inst = pugiutil::get_attribute(clb_block, "instance", loc_data); + pugi::xml_attribute block_name = pugiutil::get_attribute(clb_block, "name", loc_data); + pugi::xml_attribute block_inst = pugiutil::get_attribute(clb_block, "instance", loc_data); const Tokens tokens(block_inst.value()); if (tokens.size() != 4 || tokens[0].type != e_token_type::STRING || tokens[1].type != e_token_type::OPEN_SQUARE_BRACKET @@ -336,7 +337,7 @@ static void processComplexBlock(pugi::xml_node clb_block, pb->pb_graph_node = complex_block_type.pb_graph_head; // Set the mode of the physical block. - auto clb_mode = pugiutil::get_attribute(clb_block, "mode", loc_data); + pugi::xml_attribute clb_mode = pugiutil::get_attribute(clb_block, "mode", loc_data); t_pb_type* complex_block_pb_type = complex_block_type.pb_type; bool found = false; for (int i = 0; i < complex_block_type.pb_type->num_modes; i++) { @@ -381,12 +382,12 @@ static void processComplexBlock(pugi::xml_node clb_block, VTR_ASSERT(clb_nlist.block_ports(index).size() == (unsigned)complex_block_pb_type->num_ports); // Process the rest of the contents of the cluster block and the pb. - processPb(clb_block, - index, - pb, - pb->pb_route, - num_primitives, - loc_data); + process_pb(clb_block, + index, + pb, + pb->pb_route, + num_primitives, + loc_data); load_internal_to_block_net_nums(&complex_block_type, pb->pb_route); } @@ -398,10 +399,10 @@ static void processComplexBlock(pugi::xml_node clb_block, * `attrValue ... ` */ template -void processAttrsParams(pugi::xml_node Parent, const char* child_name, T& atom_net_range, const pugiutil::loc_data& loc_data) { +void process_attrs_params(pugi::xml_node Parent, const char* child_name, T& atom_net_range, const pugiutil::loc_data& loc_data) { std::map kvs; if (Parent) { - for (auto Cur = pugiutil::get_first_child(Parent, child_name, loc_data, pugiutil::OPTIONAL); Cur; Cur = Cur.next_sibling(child_name)) { + for (pugi::xml_node Cur = pugiutil::get_first_child(Parent, child_name, loc_data, pugiutil::OPTIONAL); Cur; Cur = Cur.next_sibling(child_name)) { std::string cname = pugiutil::get_attribute(Cur, "name", loc_data).value(); std::string cval = Cur.text().get(); bool found = false; @@ -441,25 +442,25 @@ void processAttrsParams(pugi::xml_node Parent, const char* child_name, T& atom_n * @param pb physical block to use * @param loc_data xml location info for error reporting */ -static void processPb(pugi::xml_node Parent, - const ClusterBlockId index, - t_pb* pb, - t_pb_routes& pb_route, - int& num_primitives, - const pugiutil::loc_data& loc_data) { +static void process_pb(pugi::xml_node Parent, + const ClusterBlockId index, + t_pb* pb, + t_pb_routes& pb_route, + int& num_primitives, + const pugiutil::loc_data& loc_data) { const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); AtomLookup& atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); AtomPBBimap& atom_pb_bimap = atom_lookup.mutable_atom_pb_bimap(); // Process the ports. - auto inputs = pugiutil::get_single_child(Parent, "inputs", loc_data); - processPorts(inputs, pb, pb_route, loc_data); + pugi::xml_node inputs = pugiutil::get_single_child(Parent, "inputs", loc_data); + process_ports(inputs, pb, pb_route, loc_data); - auto outputs = pugiutil::get_single_child(Parent, "outputs", loc_data); - processPorts(outputs, pb, pb_route, loc_data); + pugi::xml_node outputs = pugiutil::get_single_child(Parent, "outputs", loc_data); + process_ports(outputs, pb, pb_route, loc_data); - auto clocks = pugiutil::get_single_child(Parent, "clocks", loc_data); - processPorts(clocks, pb, pb_route, loc_data); + pugi::xml_node clocks = pugiutil::get_single_child(Parent, "clocks", loc_data); + process_ports(clocks, pb, pb_route, loc_data); // Base-case: This is a primitive. const t_pb_type* pb_type = pb->pb_graph_node->pb_type; @@ -479,10 +480,10 @@ static void processPb(pugi::xml_node Parent, // Process the attributes and params. auto atom_attrs = atom_netlist.block_attrs(blk_id); auto atom_params = atom_netlist.block_params(blk_id); - auto attrs = pugiutil::get_single_child(Parent, "attributes", loc_data, pugiutil::OPTIONAL); - auto params = pugiutil::get_single_child(Parent, "parameters", loc_data, pugiutil::OPTIONAL); - processAttrsParams(attrs, "attribute", atom_attrs, loc_data); - processAttrsParams(params, "parameter", atom_params, loc_data); + pugi::xml_node attrs = pugiutil::get_single_child(Parent, "attributes", loc_data, pugiutil::OPTIONAL); + pugi::xml_node params = pugiutil::get_single_child(Parent, "parameters", loc_data, pugiutil::OPTIONAL); + process_attrs_params(attrs, "attribute", atom_attrs, loc_data); + process_attrs_params(params, "parameter", atom_params, loc_data); num_primitives++; return; @@ -500,10 +501,10 @@ static void processPb(pugi::xml_node Parent, } // Populate info for each physical block. - for (auto child = Parent.child("block"); child; child = child.next_sibling("block")) { + for (pugi::xml_node child = Parent.child("block"); child; child = child.next_sibling("block")) { VTR_ASSERT(strcmp(child.name(), "block") == 0); - auto instance_type = pugiutil::get_attribute(child, "instance", loc_data); + pugi::xml_attribute instance_type = pugiutil::get_attribute(child, "instance", loc_data); const Tokens tokens(instance_type.value()); if (tokens.size() != 4 || tokens[0].type != e_token_type::STRING || tokens[1].type != e_token_type::OPEN_SQUARE_BRACKET @@ -552,14 +553,14 @@ static void processPb(pugi::xml_node Parent, // Set the name of the new pb. pugi::xml_attribute mode; - auto name = pugiutil::get_attribute(child, "name", loc_data); + pugi::xml_attribute name = pugiutil::get_attribute(child, "name", loc_data); if (0 != strcmp(name.value(), "open")) { new_child_pb->name = vtr::strdup(name.value()); mode = child.attribute("mode"); } else { // hysical block has no used primitives but it may have used routing. new_child_pb->name = nullptr; - auto lookahead1 = pugiutil::get_first_child(child, "outputs", loc_data, pugiutil::OPTIONAL); + pugi::xml_node lookahead1 = pugiutil::get_first_child(child, "outputs", loc_data, pugiutil::OPTIONAL); if (!lookahead1) { // If not used for routing, skip recursing into the pb. continue; @@ -586,20 +587,23 @@ static void processPb(pugi::xml_node Parent, new_child_pb->name, pb_index); } - processPb(child, index, new_child_pb, pb_route, num_primitives, loc_data); + process_pb(child, index, new_child_pb, pb_route, num_primitives, loc_data); } } -static void processPorts(pugi::xml_node Parent, - t_pb* pb, - t_pb_routes& pb_route, - const pugiutil::loc_data& loc_data) { +/** + * @brief XML parser to populate the routing represented on the ports of the pb. + */ +static void process_ports(pugi::xml_node Parent, + t_pb* pb, + t_pb_routes& pb_route, + const pugiutil::loc_data& loc_data) { const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); const t_pb_type* pb_type = pb->pb_graph_node->pb_type; - for (auto Cur = pugiutil::get_first_child(Parent, "port", loc_data, pugiutil::OPTIONAL); Cur; Cur = Cur.next_sibling("port")) { - auto port_name = pugiutil::get_attribute(Cur, "name", loc_data); + for (pugi::xml_node Cur = pugiutil::get_first_child(Parent, "port", loc_data, pugiutil::OPTIONAL); Cur; Cur = Cur.next_sibling("port")) { + pugi::xml_attribute port_name = pugiutil::get_attribute(Cur, "name", loc_data); //Determine the port index on the pb // @@ -828,10 +832,10 @@ static void processPorts(pugi::xml_node Parent, } //Record any port rotation mappings - for (auto pin_rot_map = pugiutil::get_first_child(Parent, "port_rotation_map", loc_data, pugiutil::OPTIONAL); + for (pugi::xml_node pin_rot_map = pugiutil::get_first_child(Parent, "port_rotation_map", loc_data, pugiutil::OPTIONAL); pin_rot_map; pin_rot_map = pin_rot_map.next_sibling("port_rotation_map")) { - auto port_name = pugiutil::get_attribute(pin_rot_map, "name", loc_data).value(); + const char* port_name = pugiutil::get_attribute(pin_rot_map, "name", loc_data).value(); const t_port* pb_gport = find_pb_graph_port(pb->pb_graph_node, port_name); @@ -974,7 +978,7 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, vtr::vector count(clb_nlist.nets().size(), 0); for (ClusterBlockId blk_id : clb_nlist.blocks()) { t_logical_block_type_ptr block_type = clb_nlist.block_type(blk_id); - auto tile_type = pick_physical_type(block_type); + t_physical_tile_type_ptr tile_type = pick_physical_type(block_type); for (int j = 0; j < block_type->pb_type->num_pins; j++) { int physical_pin = get_physical_pin(tile_type, block_type, j); @@ -1023,11 +1027,11 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, // set, minus the "open" nets. int num_unique_net_names = seen_net_names.size() - 1; VTR_ASSERT(static_cast(clb_nlist.nets().size()) == num_unique_net_names); - for (auto net_id : clb_nlist.nets()) { - for (auto pin_id : clb_nlist.net_sinks(net_id)) { + for (ClusterNetId net_id : clb_nlist.nets()) { + for (ClusterPinId pin_id : clb_nlist.net_sinks(net_id)) { bool is_ignored_net = clb_nlist.net_is_ignored(net_id); t_logical_block_type_ptr block_type = clb_nlist.block_type(clb_nlist.pin_block(pin_id)); - auto tile_type = pick_physical_type(block_type); + t_physical_tile_type_ptr tile_type = pick_physical_type(block_type); int logical_pin = clb_nlist.pin_logical_index(pin_id); int physical_pin = get_physical_pin(tile_type, block_type, logical_pin); @@ -1040,9 +1044,13 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, } } +/** + * @brief Counts the number of constant generators in the design and displays + * this information to the log files. + */ static void mark_constant_generators(const ClusteredNetlist& clb_nlist, int verbosity) { size_t const_gen_count = 0; - for (auto blk_id : clb_nlist.blocks()) { + for (ClusterBlockId blk_id : clb_nlist.blocks()) { const_gen_count += mark_constant_generators_rec(clb_nlist.block_pb(blk_id), clb_nlist.block_pb(blk_id)->pb_route, verbosity); } From a2293821f4764e45e33f85f19968557a5798373b Mon Sep 17 00:00:00 2001 From: AlexandreSinger Date: Sun, 2 Nov 2025 17:43:10 -0500 Subject: [PATCH 3/3] [Pack] Removed More Auto and Moved Comments --- vpr/src/base/read_netlist.cpp | 118 +++++++++++++++++----------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/vpr/src/base/read_netlist.cpp b/vpr/src/base/read_netlist.cpp index 6337f839ab..b70cdafe54 100644 --- a/vpr/src/base/read_netlist.cpp +++ b/vpr/src/base/read_netlist.cpp @@ -44,11 +44,21 @@ static const char* netlist_file_name = nullptr; +/** + * @brief XML parser to populate the routing represented on the ports of the pb. + */ static void process_ports(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, const pugiutil::loc_data& loc_data); +/** + * @brief XML parser to populate pb info and to update internal nets of the parent CLB + * + * @param Parent XML tag for this pb_type + * @param pb physical block to use + * @param loc_data xml location info for error reporting + */ static void process_pb(pugi::xml_node Parent, const ClusterBlockId index, t_pb* pb, @@ -56,6 +66,13 @@ static void process_pb(pugi::xml_node Parent, int& num_primitives, const pugiutil::loc_data& loc_data); +/** + * @brief XML parser to populate CLB info and to update nets with the nets of this CLB + * + * @param clb_nlist Array of CLBs in the netlist + * @param index index of the CLB to allocate and load information into + * @param loc_data xml location info for error reporting + */ static void process_complex_block(pugi::xml_node Parent, const ClusterBlockId index, int& num_primitives, @@ -63,20 +80,37 @@ static void process_complex_block(pugi::xml_node Parent, const std::unordered_map& logical_block_type_name_to_index, ClusteredNetlist& clb_nlist); +/** + * @brief After the clustered netlist has been created, many of the atom + * netlist datastructures will become out of date. Need to sync the + * clustered netlist with the atom netlist. + */ static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, AtomNetlist& atom_netlist, AtomLookup& atom_lookup); +/** + * @brief This function updates the nets list and the connections between + * that list and the complex block + */ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, const AtomNetlist& atom_netlist); static void load_internal_to_block_net_nums(const t_logical_block_type_ptr type, t_pb_routes& pb_route); static void load_atom_index_for_pb_pin(t_pb_routes& pb_route, int ipin); +/** + * @brief Counts the number of constant generators in the design and displays + * this information to the log files. + */ static void mark_constant_generators(const ClusteredNetlist& clb_nlist, int verbosity); static size_t mark_constant_generators_rec(const t_pb* pb, const t_pb_routes& pb_route, int verbosity); +/** + * @brief Walk through the atom netlist looking up and storing the t_pb_graph_pin + * associated with each connected AtomPinId + */ static void load_atom_pin_mapping(const ClusteredNetlist& clb_nlist); /** @@ -88,8 +122,8 @@ ClusteredNetlist read_netlist(const char* net_file, const t_arch* arch, bool verify_file_digests, int verbosity) { - AtomNetlist& atom_netlist = g_vpr_ctx.mutable_atom().mutable_netlist(); - AtomLookup& atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); + AtomNetlist& mutable_atom_netlist = g_vpr_ctx.mutable_atom().mutable_netlist(); + AtomLookup& mutable_atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); const auto& logical_block_types = g_vpr_ctx.device().logical_block_types; vtr::ScopedStartFinishTimer read_netlist_timer("Loading packed FPGA netlist file."); @@ -174,11 +208,11 @@ ClusteredNetlist read_netlist(const char* net_file, //Note that we currently don't require that the atom_netlist_id exists, //to remain compatible with old .net files std::string atom_nl_id = atom_netlist_id.value(); - if (atom_nl_id != atom_netlist.netlist_id()) { + if (atom_nl_id != mutable_atom_netlist.netlist_id()) { std::string msg = vtr::string_fmt( "Netlist was generated from a different atom netlist file" " (loaded atom netlist ID: %s, packed netlist atom netlist ID: %s)", - atom_nl_id.c_str(), atom_netlist.netlist_id().c_str()); + atom_nl_id.c_str(), mutable_atom_netlist.netlist_id().c_str()); if (verify_file_digests) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(top), msg.c_str()); } else { @@ -189,18 +223,18 @@ ClusteredNetlist read_netlist(const char* net_file, //Collect top level I/Os pugi::xml_node top_inputs = pugiutil::get_single_child(top, "inputs", loc_data); - auto circuit_inputs = vtr::StringToken(top_inputs.text().get()).split(" \t\n"); + std::vector circuit_inputs = vtr::StringToken(top_inputs.text().get()).split(" \t\n"); pugi::xml_node top_outputs = pugiutil::get_single_child(top, "outputs", loc_data); - auto circuit_outputs = vtr::StringToken(top_outputs.text().get()).split(" \t\n"); + std::vector circuit_outputs = vtr::StringToken(top_outputs.text().get()).split(" \t\n"); pugi::xml_node top_clocks = pugiutil::get_single_child(top, "clocks", loc_data); - auto circuit_clocks = vtr::StringToken(top_clocks.text().get()).split(" \t\n"); + std::vector circuit_clocks = vtr::StringToken(top_clocks.text().get()).split(" \t\n"); /* Parse all CLB blocks and all nets*/ //Reset atom/pb mapping (it is reloaded from the packed netlist file) - atom_lookup.mutable_atom_pb_bimap().reset_bimap(); + mutable_atom_lookup.mutable_atom_pb_bimap().reset_bimap(); //Count the number of blocks for allocation size_t bcount = pugiutil::count_children(top, "block", loc_data, pugiutil::ReqOpt::OPTIONAL); @@ -222,23 +256,23 @@ ClusteredNetlist read_netlist(const char* net_file, VTR_ASSERT(bcount == i); VTR_ASSERT(clb_nlist.blocks().size() == i); VTR_ASSERT(num_primitives >= 0); - VTR_ASSERT(static_cast(num_primitives) == atom_netlist.blocks().size()); + VTR_ASSERT(static_cast(num_primitives) == mutable_atom_netlist.blocks().size()); /* Error check */ - for (AtomBlockId blk_id : atom_netlist.blocks()) { - if (atom_lookup.atom_pb_bimap().atom_pb(blk_id) == nullptr) { + for (AtomBlockId blk_id : mutable_atom_netlist.blocks()) { + if (mutable_atom_lookup.atom_pb_bimap().atom_pb(blk_id) == nullptr) { VPR_FATAL_ERROR(VPR_ERROR_NET_F, ".blif file and .net file do not match, .net file missing atom %s.\n", - atom_netlist.block_name(blk_id).c_str()); + mutable_atom_netlist.block_name(blk_id).c_str()); } } /* TODO: Add additional check to make sure net connections match */ mark_constant_generators(clb_nlist, verbosity); - load_external_nets_and_cb(clb_nlist, atom_netlist); + load_external_nets_and_cb(clb_nlist, mutable_atom_netlist); - sync_clustered_and_atom_netlists(clb_nlist, atom_netlist, atom_lookup); + sync_clustered_and_atom_netlists(clb_nlist, mutable_atom_netlist, mutable_atom_lookup); } catch (pugiutil::XmlError& e) { vpr_throw(VPR_ERROR_NET_F, e.filename_c_str(), e.line(), @@ -251,11 +285,6 @@ ClusteredNetlist read_netlist(const char* net_file, return clb_nlist; } -/** - * @brief After the clustered netlist has been created, many of the atom - * netlist datastructures will become out of date. Need to sync the - * clustered netlist with the atom netlist. - */ static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, AtomNetlist& atom_netlist, AtomLookup& atom_lookup) { @@ -289,13 +318,6 @@ static void sync_clustered_and_atom_netlists(ClusteredNetlist& clb_nlist, load_atom_pin_mapping(clb_nlist); } -/** - * @brief XML parser to populate CLB info and to update nets with the nets of this CLB - * - * @param clb_nlist Array of CLBs in the netlist - * @param index index of the CLB to allocate and load information into - * @param loc_data xml location info for error reporting - */ static void process_complex_block(pugi::xml_node clb_block, const ClusterBlockId index, int& num_primitives, @@ -435,13 +457,6 @@ void process_attrs_params(pugi::xml_node Parent, const char* child_name, T& atom } } -/** - * @brief XML parser to populate pb info and to update internal nets of the parent CLB - * - * @param Parent XML tag for this pb_type - * @param pb physical block to use - * @param loc_data xml location info for error reporting - */ static void process_pb(pugi::xml_node Parent, const ClusterBlockId index, t_pb* pb, @@ -449,8 +464,8 @@ static void process_pb(pugi::xml_node Parent, int& num_primitives, const pugiutil::loc_data& loc_data) { const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); - AtomLookup& atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); - AtomPBBimap& atom_pb_bimap = atom_lookup.mutable_atom_pb_bimap(); + AtomLookup& mutable_atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); + AtomPBBimap& mutable_atom_pb_bimap = mutable_atom_lookup.mutable_atom_pb_bimap(); // Process the ports. pugi::xml_node inputs = pugiutil::get_single_child(Parent, "inputs", loc_data); @@ -474,8 +489,8 @@ static void process_pb(pugi::xml_node Parent, // Update atom netlist mapping VTR_ASSERT(blk_id); - atom_pb_bimap.set_atom_pb(blk_id, pb); - atom_lookup.set_atom_clb(blk_id, index); + mutable_atom_pb_bimap.set_atom_pb(blk_id, pb); + mutable_atom_lookup.set_atom_clb(blk_id, index); // Process the attributes and params. auto atom_attrs = atom_netlist.block_attrs(blk_id); @@ -549,7 +564,7 @@ static void process_pb(pugi::xml_node Parent, "Unknown pb type %s.\n", instance_type.value()); } - atom_pb_bimap.set_atom_pb(AtomBlockId::INVALID(), new_child_pb); + mutable_atom_pb_bimap.set_atom_pb(AtomBlockId::INVALID(), new_child_pb); // Set the name of the new pb. pugi::xml_attribute mode; @@ -591,9 +606,6 @@ static void process_pb(pugi::xml_node Parent, } } -/** - * @brief XML parser to populate the routing represented on the ports of the pb. - */ static void process_ports(pugi::xml_node Parent, t_pb* pb, t_pb_routes& pb_route, @@ -637,7 +649,7 @@ static void process_ports(pugi::xml_node Parent, } //Extract all the pins for this port - auto pins = vtr::StringToken(Cur.text().get()).split(" \t\n"); + std::vector pins = vtr::StringToken(Cur.text().get()).split(" \t\n"); int num_tokens = pins.size(); //Check that the number of pins from the netlist file matches the pb port's number of pins @@ -846,7 +858,7 @@ static void process_ports(pugi::xml_node Parent, pb_type->name, pb->pb_graph_node->placement_index); } - auto pin_mapping = vtr::StringToken(pin_rot_map.text().get()).split(" \t\n"); + std::vector pin_mapping = vtr::StringToken(pin_rot_map.text().get()).split(" \t\n"); if (size_t(pb_gport->num_pins) != pin_mapping.size()) { vpr_throw(VPR_ERROR_NET_F, netlist_file_name, loc_data.line(pin_rot_map), @@ -876,10 +888,6 @@ static void process_ports(pugi::xml_node Parent, } } -/** - * @brief This function updates the nets list and the connections between - * that list and the complex block - */ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, const AtomNetlist& atom_netlist) { // Create a set of all unique net names that we can see. We want to ignore @@ -1044,10 +1052,6 @@ static void load_external_nets_and_cb(ClusteredNetlist& clb_nlist, } } -/** - * @brief Counts the number of constant generators in the design and displays - * this information to the log files. - */ static void mark_constant_generators(const ClusteredNetlist& clb_nlist, int verbosity) { size_t const_gen_count = 0; for (ClusterBlockId blk_id : clb_nlist.blocks()) { @@ -1141,10 +1145,6 @@ static void load_atom_index_for_pb_pin(t_pb_routes& pb_route, int ipin) { pb_route[driver].sink_pb_pin_ids.push_back(ipin); } -/** - * @brief Walk through the atom netlist looking up and storing the t_pb_graph_pin - * associated with each connected AtomPinId - */ static void load_atom_pin_mapping(const ClusteredNetlist& clb_nlist) { const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); const AtomPBBimap& atom_pb_bimap = g_vpr_ctx.atom().lookup().atom_pb_bimap(); @@ -1203,11 +1203,11 @@ static void load_atom_pin_mapping(const ClusteredNetlist& clb_nlist) { void set_atom_pin_mapping(const ClusteredNetlist& clb_nlist, const AtomBlockId atom_blk, const AtomPortId atom_port, const t_pb_graph_pin* gpin) { const AtomNetlist& atom_netlist = g_vpr_ctx.atom().netlist(); - AtomLookup& atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); + AtomLookup& mutable_atom_lookup = g_vpr_ctx.mutable_atom().mutable_lookup(); VTR_ASSERT(atom_netlist.port_block(atom_port) == atom_blk); - ClusterBlockId clb_index = atom_lookup.atom_clb(atom_blk); + ClusterBlockId clb_index = mutable_atom_lookup.atom_clb(atom_blk); VTR_ASSERT(clb_index != ClusterBlockId::INVALID()); const t_pb* clb_pb = clb_nlist.block_pb(clb_index); @@ -1221,7 +1221,7 @@ void set_atom_pin_mapping(const ClusteredNetlist& clb_nlist, const AtomBlockId a return; } - const t_pb* atom_pb = atom_lookup.atom_pb_bimap().atom_pb(atom_blk); + const t_pb* atom_pb = mutable_atom_lookup.atom_pb_bimap().atom_pb(atom_blk); //This finds the index within the atom port to which the current gpin //is mapped. Note that this accounts for any applied pin rotations @@ -1233,5 +1233,5 @@ void set_atom_pin_mapping(const ClusteredNetlist& clb_nlist, const AtomBlockId a VTR_ASSERT(pb_route.atom_net_id == atom_netlist.pin_net(atom_pin)); //Save the mapping - atom_lookup.set_atom_pin_pb_graph_pin(atom_pin, gpin); + mutable_atom_lookup.set_atom_pin_pb_graph_pin(atom_pin, gpin); }