Skip to content

Some clean ups in RR graph generation and custom switch block parsing #3166

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Jun 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 116 additions & 77 deletions libs/libarchfpga/src/parse_switchblocks.cpp

Large diffs are not rendered by default.

44 changes: 37 additions & 7 deletions libs/libarchfpga/src/parse_switchblocks.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
#pragma once

#include "physical_types.h"
#include "pugixml.hpp"
#include "pugixml_loc.hpp"
#include "vtr_expr_eval.h"

/**** Function Declarations ****/
/* Loads permutation funcs specified under Node into t_switchblock_inf */
void read_sb_switchfuncs(pugi::xml_node Node, t_switchblock_inf* sb, const pugiutil::loc_data& loc_data);
/**
* @brief Loads permutation functions from an XML node into a switchblock structure.
*
* This function parses an XML `<switchfuncs>` node, extracts all `<func>` child elements,
* and populates the corresponding entries in the `t_switchblock_inf::permutation_map`.
* Each `<func>` element must have a `type` attribute indicating the connection type
* (e.g., side-to-side) and a `formula` attribute specifying the permutation function.
*
* @param node XML node containing the `<switchfuncs>` specification.
* @param sb The switchblock structure where permutation functions will be stored.
* @param loc_data Location data used for error reporting during XML parsing.
*
* The function expects the following XML structure:
* @code{.xml}
* <switchfuncs>
* <func type="..." formula="..."/>
* ...
* </switchfuncs>
* @endcode
*/
void read_sb_switchfuncs(pugi::xml_node node, t_switchblock_inf& sb, const pugiutil::loc_data& loc_data);

/* Reads-in the wire connections specified for the switchblock in the xml arch file */
void read_sb_wireconns(const std::vector<t_arch_switch_inf>& switches, pugi::xml_node Node, t_switchblock_inf* sb, const pugiutil::loc_data& loc_data);
/**
* @brief Reads wire connections for a switch block from the XML architecture file.
*
* This function parses all `<wireconn>` elements under the given `<switchblock>` XML node.
* Each parsed connection is stored in the provided `t_switchblock_inf` structure.
*
* @param switches List of architecture switch definitions.
* @param node XML node representing the switchblock.
* @param sb The switchblock structure to populate.
* @param loc_data Location data for error reporting.
*/
void read_sb_wireconns(const std::vector<t_arch_switch_inf>& switches,
pugi::xml_node node,
t_switchblock_inf& sb,
const pugiutil::loc_data& loc_data);

/* checks for correctness of switch block read-in from the XML architecture file */
void check_switchblock(const t_switchblock_inf* sb, const t_arch* arch);
void check_switchblock(const t_switchblock_inf& sb, const t_arch* arch);

/* returns integer result according to the specified formula and data */
int get_sb_formula_raw_result(vtr::FormulaParser& formula_parser, const char* formula, const vtr::t_formula_data& mydata);
3 changes: 1 addition & 2 deletions libs/libarchfpga/src/physical_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ static bool switch_type_is_configurable(SwitchType type) {
}

static e_directionality switch_type_directionality(SwitchType type) {
if (type == SwitchType::SHORT
|| type == SwitchType::PASS_GATE) {
if (type == SwitchType::SHORT || type == SwitchType::PASS_GATE) {
//Shorts and pass gates can conduct in either direction
return e_directionality::BI_DIRECTIONAL;
} else {
Expand Down
184 changes: 16 additions & 168 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

#include "logic_types.h"
#include "clock_types.h"
#include "switchblock_types.h"

//Forward declarations
struct t_clock_network;
Expand Down Expand Up @@ -171,24 +172,6 @@ enum e_interconnect {
MUX_INTERC = 3
};

/* Orientations. */
enum e_side : unsigned char {
TOP = 0,
RIGHT = 1,
BOTTOM = 2,
LEFT = 3,
NUM_2D_SIDES = 4,
ABOVE = 5,
UNDER = 7,
NUM_3D_SIDES = 6,
};

constexpr std::array<e_side, NUM_2D_SIDES> TOTAL_2D_SIDES = {{TOP, RIGHT, BOTTOM, LEFT}}; //Set of all side orientations
constexpr std::array<const char*, NUM_2D_SIDES> TOTAL_2D_SIDE_STRINGS = {{"TOP", "RIGHT", "BOTTOM", "LEFT"}}; //String versions of side orientations

constexpr std::array<e_side, NUM_3D_SIDES> TOTAL_3D_SIDES = {{TOP, RIGHT, BOTTOM, LEFT, ABOVE, UNDER}}; //Set of all side orientations including different layers
constexpr std::array<const char*, NUM_3D_SIDES> TOTAL_3D_SIDE_STRINGS = {{"TOP", "RIGHT", "BOTTOM", "LEFT", "ABOVE", "UNDER"}}; //String versions of side orientations including different layers

/* pin location distributions */
enum class e_pin_location_distr {
SPREAD,
Expand Down Expand Up @@ -253,26 +236,6 @@ enum e_power_estimation_method_ {
typedef enum e_power_estimation_method_ e_power_estimation_method;
typedef enum e_power_estimation_method_ t_power_estimation_method;

/* Specifies what part of the FPGA a custom switchblock should be built in (i.e. perimeter, core, everywhere) */
enum class e_sb_location {
E_PERIMETER = 0,
E_CORNER,
E_FRINGE, /* perimeter minus corners */
E_CORE,
E_EVERYWHERE,
E_XY_SPECIFIED
};

/**
* @brief Describes regions that a specific switch block specifications should be applied to
*/
struct t_sb_loc_spec {
int start = -1;
int repeat = -1;
int incr = -1;
int end = -1;
};

/*************************************************************************************************/
/* FPGA grid layout data types */
/*************************************************************************************************/
Expand Down Expand Up @@ -614,9 +577,6 @@ enum class e_sb_type {

};

constexpr int NO_SWITCH = -1;
constexpr int DEFAULT_SWITCH = -2;

/* Describes the type for a physical tile
* name: unique identifier for type
* num_pins: Number of pins for the block
Expand Down Expand Up @@ -1668,11 +1628,6 @@ struct t_chan_width_dist {
t_chan chan_y_dist;
};

enum e_directionality {
UNI_DIRECTIONAL,
BI_DIRECTIONAL
};

/* X_AXIS: Data that describes an x-directed wire segment (CHANX) *
* 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 */
Expand Down Expand Up @@ -1730,95 +1685,83 @@ enum e_Fc_type {
* used if the route_type is DETAILED. [0 .. det_routing_arch.num_segment]
*/
struct t_segment_inf {
/**
* @brief The name of the segment type
*/
/// 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.
*/
/// Length (in clbs) of the segment.
int length;

/**
* @brief Index of the switch type that connects other wires to this segment.
* @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.
* @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
* @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
* @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
* @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.
* @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.
* @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;

bool longline;

/**
* @brief The resistance of a routing track, per unit logic block length. */
/// The resistance of a routing track, per unit logic block length.
float Rmetal;

/**
* @brief The capacitance of a routing track, per unit logic block length. */
/// The capacitance of a routing track, per unit logic block length.
float Cmetal;

enum e_directionality directionality;

/**
* @brief Defines what axis the segment is parallel to. See e_parallel_axis
* @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.
*/
/// A vector of booleans indicating whether the segment can connect to a logic block.
std::vector<bool> cb;

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

/**
Expand Down Expand Up @@ -2084,101 +2027,6 @@ struct t_direct_inf {
int line;
};

enum class SwitchPointOrder {
FIXED, //Switchpoints are ordered as specified in architecture
SHUFFLED //Switchpoints are shuffled (more diversity)
};

//A collection of switchpoints associated with a segment
struct t_wire_switchpoints {
std::string segment_name; //The type of segment
std::vector<int> switchpoints; //The indices of wire points along the segment
};

/* Used to list information about a set of track segments that should connect through a switchblock */
struct t_wireconn_inf {
std::vector<t_wire_switchpoints> from_switchpoint_set; //The set of segment/wirepoints representing the 'from' set (union of all t_wire_switchpoints in vector)
std::vector<t_wire_switchpoints> to_switchpoint_set; //The set of segment/wirepoints representing the 'to' set (union of all t_wire_switchpoints in vector)
SwitchPointOrder from_switchpoint_order = SwitchPointOrder::FIXED; //The desired from_switchpoint_set ordering
SwitchPointOrder to_switchpoint_order = SwitchPointOrder::FIXED; //The desired to_switchpoint_set ordering
int switch_override_indx = DEFAULT_SWITCH; // index in switch array of the switch used to override wire_switch of the 'to' set.
// DEFAULT_SWITCH is a sentinel value (i.e. the usual driving switch from a wire for the receiving wire will be used)

std::string num_conns_formula; /* Specifies how many connections should be made for this wireconn.
*
* '<int>': A specific number of connections
* 'from': The number of generated connections between the 'from' and 'to' sets equals the
* size of the 'from' set. This ensures every element in the from set is connected
* to an element of the 'to' set.
* Note: this it may result in 'to' elements being driven by multiple 'from'
* elements (if 'from' is larger than 'to'), or in some elements of 'to' having
* no driving connections (if 'to' is larger than 'from').
* 'to': The number of generated connections is set equal to the size of the 'to' set.
* This ensures that each element of the 'to' set has precisely one incoming connection.
* Note: this may result in 'from' elements driving multiple 'to' elements (if 'to' is
* larger than 'from'), or some 'from' elements driving to 'to' elements (if 'from' is
* larger than 'to')
*/
};

/* represents a connection between two sides of a switchblock */
class SB_Side_Connection {
public:
/* specify the two SB sides that form a connection */
enum e_side from_side = TOP;
enum e_side to_side = TOP;

void set_sides(enum e_side from, enum e_side to) {
from_side = from;
to_side = to;
}

SB_Side_Connection() = default;

SB_Side_Connection(enum e_side from, enum e_side to)
: from_side(from)
, to_side(to) {
}

/* overload < operator which will be used by std::map */
bool operator<(const SB_Side_Connection& obj) const {
bool result;

if (from_side < obj.from_side) {
result = true;
} else {
if (from_side == obj.from_side) {
result = (to_side < obj.to_side) ? true : false;
} else {
result = false;
}
}

return result;
}
};

/* Use a map to index into the string permutation functions used to connect from one side to another */
typedef std::map<SB_Side_Connection, std::vector<std::string>> t_permutation_map;

/* Lists all information about a particular switch block specified in the architecture file */
struct t_switchblock_inf {
std::string name; /* the name of this switchblock */
e_sb_location location; /* where on the FPGA this switchblock should be built (i.e. perimeter, core, everywhere) */
e_directionality directionality; /* the directionality of this switchblock (unidir/bidir) */

int x = -1; /* The exact x-axis location that this SB is used, meaningful when type is set to E_XY_specified */
int y = -1; /* The exact y-axis location that this SB is used, meaningful when type is set to E_XY_specified */

/* We can also define a region to apply this SB to all locations falls into this region using regular expression in the architecture file*/
t_sb_loc_spec reg_x;
t_sb_loc_spec reg_y;

t_permutation_map permutation_map; /* map holding the permutation functions attributed to this switchblock */

std::vector<t_wireconn_inf> wireconns; /* list of wire types/groups this SB will connect */
};

/* Clock related data types used for building a dedicated clock network */
struct t_clock_arch_spec {
std::vector<t_clock_network_arch> clock_networks_arch;
Expand Down
4 changes: 2 additions & 2 deletions libs/libarchfpga/src/read_fpga_interchange_arch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
#include <map>
#include <regex>
#include <set>
#include <stdlib.h>
#include <cstdlib>
#include <string>
#include <string.h>
#include <cstring>
#include <zlib.h>
#include <sstream>

Expand Down
Loading