/*
 * Author(s): Oleg Petelin
 * Last revised: September, 2015
 *
 ************ NEW SWITCH BLOCK HIGH-LEVEL DESCRIPTION ************
 * The new switch block description format allows a much finer level of control over the switch blocks generated by VPR.
 * Whereas a user previously only had the choice of 'wilton', 'universal', 'subset', or 'full' switch blocks, the new
 * format allows a user to specify a small set of mathematical formulas that describe the switch block connections. This format
 * allows the specification of all the switch blocks previously available in VPR as well as a great number of new switch block patterns.
 *
 * The new switch block description format is loosely based on chapter 7 of Lemieux' and Lewis' "Design of Interconnection Networks
 * for Programmable Logic" book (2004).
 *
 *
 ************ FILES AND THEIR PURPOSE ************
 * The overall flow of parsing and building the new switch blocks involves reading switch block descriptions from the VPR
 * architecture file and then building the switch blocks according to these descriptions in build_rr_graph (rr_graph.c).
 * This functionality is split across different files which are described below:
 *
 * read_xml_arch_file.c (under libarchfpga):
 * calls ProcessSwitchblocks which fills s_arch-->switchblocks with info about each user-defined switch blocks
 * calls functions from parse_switchblocks.c to build switch block data structures (reads-in permutation functions
 * and wire segment source/dest connection info)
 * ProcessSegments has been modified to give a string name to each segment type (in t_segment_inf).
 * parse_switchblocks.c (under libarchfpga):
 * provides functions to help load switch block data structures during XML parsing of VPR architecture file
 * provides functions to evaluate switch block permutation formulas and return a numeric result
 * SetupVPR.c:
 * SetupRoutingArch copies switch block information from s_arch to s_det_routing_arch
 * physical_types.h (under libarchfpga):
 * defines classes, structs and typedefs for parsing switch blocks from XML architecture file
 * vpr_types.h
 * s_det_routing_arch carries info about custom switch blocks
 * build_switchblocks.c (this file):
 * builds t_sb_connection_map sparse array containing target connections for each wire in each horizontal/vertical channel segment.
 * 'compute_wire_connections' is the most important function here -- it computes the set of wire segments that a given wire at
 * (x, y, from_side, to_side, from_wire) should connect to.
 * rr_graph.c:
 * calls alloc_and_load_switchblock_permutations (from build_switchblocks.c) which creates the t_sb_connection_map
 * rr_graph2.c:
 * get_wire_to_chan_seg is called within get_wire_to_wires which looks at t_sb_connection_map to create the edges that
 * connect a source wire segment into a destination channel segment
 *
 *
 ************ DESCRIPTION OF SWITCH BLOCK SPECIFICATION ************
 * Some terminology:
 *
 * Wire segment type: a named group of wires defined in the architecture file.
 * Wire subsegment number: a number assigned to a wire subsegment relative to the wire's start coordinate (see diagram below).
 * Used to define a collection of wire segments that have a start point in the same column (or row) of the FPGA.
 * Wire switch point: a number assigned to a specific switch block along a wire segment
 *
 * Ex: for a length-4 unidirectional wire segment going in the decreasing direction:
 * wire switch point    0<-------3<-------2<-------1<-------0
 * wire subsegment #         3        2        1        0
 *
 * The new switch block format allows a user to specify mathematical permutation functions that describe how different types of wires will connect at different switchpoinnts. One or more wire types *and* one or more switch points define a set of wires, and each switch block connection is specified in terms of a source and destination set. Specifically, the permutation functions prescribe how a set of from_type/from_switchpoint wires (the source set) in one channel segment should connect to a set of to_type/to_switchpoint wires (the destination set) in an adjacent channel segment. This provides for an abstract but very flexible way of specifying different switch block patterns.
 *
 * An example from an XML VPR architecture file is given below.
 *
 * The 'wireconn' entries define ordered source/destination sets of wire segments that should be connected with the specified permutation functions. The wireconn entries essentially "re-index" the channel so that a permutation function of 't/2' means that the t'th wire segment in the source wireconn set should connect to the [(t/2)%W]'th wire segment in the destination set where W is the size, or effective channel width, of the destination set (note that permutation functions are implicitly modulo W so that all functions evaluate to a number that indexes into the destination set).
 *
 * <!-- Specify that custom switch blocks will be used. This is backwards compatible with VPR's previous wilton/subset/univeral specification,
 * but "custom" is specified instead. -->
 * <switch_block type="custom"/>			<-- backwards-compatible with VPR's previous wilton/subset/universal/full specification
 * ...
 * ...
 * <!-- Segment specification is as before, except that a "name" is also specified for each segment. Each segment defines a type of wire. -->
 * <segmentlist>
 * <segment freq="0.85" name="l4" length="4" type="unidir" Rmetal="232" Cmetal="0.0">
 * <mux name="l4_mux"/>
 * <sb type="pattern">1 1 1 1 1</sb>
 * <cb type="pattern">1 1 1 1</cb>
 * </segment>
 * <segment freq="0.15" name="l8_global" length="8" type="unidir" Rmetal="33.8" Cmetal="0.0">
 * <mux name="l8_mux"/>
 * <sb type="pattern">1 1 1 1 1 1 1 1 1</sb>
 * <cb type="pattern">1 1 1 1 1 1 1 1</cb>
 * </segment>
 * </segmentlist>
 * ...
 * ...
 * <!-- Custom switch blocks are declared here -->
 * <switchblocklist>
 * <!-- Each "switchblock" entry is given a name. Type specifies either a unidirectional or bidirectional switch block -->
 * <switchblock name="my_switchblock" type="unidir">
 * <!-- Location to implement this switch block (EVERYWHERE/CORE/PERIMETER/CORNER/FRINGE) -->
 * <switchblock_location type="EVERYWHERE"/>
 * <!-- A list of permutation functions. Any number can be specified (for instance two "lt" entries can be specified to increase
 * Fs of connections from the left to the top switch block sides -->
 * <switchfuncs>
 * <!-- "lr" means left-to-right, "lt" means left to top, etc. Formulas support different operators which are discussed later -->
 * <func type="lr" formula="t"/>
 * <func type="lt" formula="W-t"/>
 * <func type="lb" formula="W+t-1"/>
 * <func type="rt" formula="W+t-1"/>
 * <func type="br" formula="W-t-2"/>
 * <func type="bt" formula="t"/>
 * <func type="rl" formula="t"/>
 * <func type="tl" formula="W-t"/>
 * <func type="bl" formula="W+t-1"/>
 * <func type="tr" formula="W+t-1"/>
 * <func type="rb" formula="W-t-2"/>
 * <func type="tb" formula="t"/>
 * </switchfuncs>
 * <!-- Wireconn entries define the sets of wires that should be connected with the above permutation functions -->
 * <wireconn from_type="l4" to_type="l4" from_switchpoint="0,1,2,3" to_switchpoint="0"/>
 * <wireconn from_type="l8_global" to_type="l8_global" from_switchpoint="0,4" to_switchpoint="0"/>
 * <wireconn from_type="l8_global" to_type="l4" from_switchpoint="0,4" to_switchpoint="0"/>
 * </switchblock>
 *
 * <switchblock name="another_switch_block" type="unidir">
 * ... switch block description ...
 * </switchblock>
 * </switchblocklist>
 *
 * Allowed symmbols and operators for the switch block permutation functions are described below (recall
 * that formulas are evaluated in 'parse_switchblocks.c'):
 * "+" -- addition
 * "-" -- subtraction
 * "/" -- division
 * "*" -- multiplication
 * "t" -- index of the wire segment in the source set
 * "W" -- size of the destination set
 *
 */

#include <cstring>
#include <algorithm>
#include <iterator>
#include <iostream>

#include "vtr_assert.h"
#include "vtr_memory.h"
#include "vtr_log.h"

#include "vpr_error.h"

#include "build_switchblocks.h"
#include "physical_types.h"
#include "parse_switchblocks.h"
#include "expr_eval.h"

/************ Defines ************/
/* if defined, switch block patterns are loaded by first computing a row of switch blocks and then
 * stamping out the row throughout the FPGA */
//#define FAST_SB_COMPUTATION

/* REF_X/REF_Y set a reference coordinate; some look-up structures in this file are computed relative to
 * this reference */
#define REF_X 1 //constexpr int REX_X = 1;	<-- basically C++11 defines; more type-safe
#define REF_Y 1

/************ Classes ************/
/* contains info about a wire segment type */
class Wire_Info {
  public:
    int length;    /* the length of this type of wire segment in tiles */
    int num_wires; /* total number of wires in a channel segment (basically W) */
    int start;     /* the wire index at which this type starts in the channel segment (0..W-1) */

    void set(int len, int wires, int st) {
        length = len;
        num_wires = wires;
        start = st;
    }
    Wire_Info() {
        this->set(0, 0, 0);
    }
    Wire_Info(int len, int wires, int st) {
        this->set(len, wires, st);
    }
};

struct t_wire_switchpoint {
    int wire;        //Wire index within the channel
    int switchpoint; //Switchpoint of the wire
};

/************ Typedefs ************/
/* Used to get info about a given wire type based on the name */
typedef std::map<std::string, Wire_Info> t_wire_type_sizes;

/************ Function Declarations ************/
/* Counts the number of wires in each wire type in the specified channel */
static void count_wire_type_sizes(const t_chan_seg_details* channel, int nodes_per_chan, t_wire_type_sizes* wire_type_sizes);

#ifdef FAST_SB_COMPUTATION
/* over all connected wire types (i,j), compute the maximum least common multiple of their wire lengths,
 * ie max(LCM(L_i, L_J)) */
static int get_max_lcm(vector<t_switchblock_inf>* switchblocks, t_wire_type_sizes* wire_type_sizes);

/* compute all the switchblocks around the perimeter of the FPGA for the given switchblock and wireconn */
static void compute_perimeter_switchblocks(t_chan_details* chan_details_x, t_chan_details* chan_details_y, vector<t_switchblock_inf>* switchblocks, const DeviceGrid& grid, int nodes_per_chan, t_wire_type_sizes* wire_type_sizes, e_directionality directionality, t_sb_connection_map* sb_conns);

/* computes a horizontal line of switchblocks of size sb_row_size (or of grid.width()-4, whichever is smaller), starting
 * at coordinate (1,1) */
static void compute_switchblock_row(int sb_row_size, t_chan_details* chan_details_x, t_chan_details* chan_details_y, vector<t_switchblock_inf>* switchblocks, const DeviceGrid& grid, int nodes_per_chan, t_wire_type_sizes* wire_type_sizes, e_directionality directionality, t_sb_connection_map* sb_row);

/* stamp out a line of horizontal switchblocks starting at coordinates (ref_x, ref_y) and
 * continuing on for sb_row_size */
static void stampout_switchblocks_from_row(int sb_row_size,
                                           int nodes_per_chan,
                                           const DeviceGrid& grid,
                                           t_wire_type_sizes* wire_type_sizes,
                                           e_directionality directionality,
                                           t_sb_connection_map* sb_row,
                                           t_sb_connection_map* sb_conns);

#endif //FAST_SB_COMPUTATION

/* Compute the wire(s) that the wire at (x, y, from_side, to_side, from_wire) should connect to.
 * sb_conns is updated with the result */
static void compute_wire_connections(int x_coord, int y_coord, enum e_side from_side, enum e_side to_side, const t_chan_details& chan_details_x, const t_chan_details& chan_details_y, t_switchblock_inf* sb, const DeviceGrid& grid, t_wire_type_sizes* wire_type_sizes, e_directionality directionality, t_sb_connection_map* sb_conns, vtr::RandState& rand_state);

/* ... sb_conn represents the 'coordinates' of the desired switch block connections */
static void compute_wireconn_connections(const DeviceGrid& grid, e_directionality directionality, const t_chan_details& from_chan_details, const t_chan_details& to_chan_details, Switchblock_Lookup sb_conn, int from_x, int from_y, int to_x, int to_y, t_rr_type from_chan_type, t_rr_type to_chan_type, t_wire_type_sizes* wire_type_sizes, t_switchblock_inf* sb, t_wireconn_inf* wireconn_ptr, t_sb_connection_map* sb_conns, vtr::RandState& rand_state);

static int evaluate_num_conns_formula(std::string num_conns_formula, int from_wire_count, int to_wire_count);

/* returns the wire indices belonging to the types in 'wire_type_vec' and switchpoints in 'points' at the given channel segment */
static std::vector<t_wire_switchpoint> get_switchpoint_wires(const DeviceGrid& grid, const t_chan_seg_details* chan_details, t_rr_type chan_type, int x, int y, e_side side, const std::vector<t_wire_switchpoints>& wire_switchpoints_vec, t_wire_type_sizes* wire_type_sizes, bool is_dest, SwitchPointOrder order, vtr::RandState& rand_state);

static const t_chan_details& index_into_correct_chan(int tile_x, int tile_y, enum e_side side, const t_chan_details& chan_details_x, const t_chan_details& chan_details_y, int* chan_x, int* chan_y, t_rr_type* chan_type);

/* checks whether the specified coordinates are out of bounds */
static bool coords_out_of_bounds(const DeviceGrid& grid, int x_coord, int y_coord, e_rr_type chan_type);

/* returns the subsegment number of the specified wire at seg_coord*/
static int get_wire_subsegment_num(const DeviceGrid& grid, e_rr_type chan_type, const t_chan_seg_details& wire_details, int seg_coord);

int get_wire_segment_length(const DeviceGrid& grid, e_rr_type chan_type, const t_chan_seg_details& wire_details);

/* Returns the switchpoint of the wire specified by wire_details at a segment coordinate
 * of seg_coord, and connection to the sb_side of the switchblock */
static int get_switchpoint_of_wire(const DeviceGrid& grid, e_rr_type chan_type, const t_chan_seg_details& wire_details, int seg_coord, e_side sb_side);

/* returns true if the coordinates x/y do not correspond to the location specified by 'location' */
static bool sb_not_here(const DeviceGrid& grid, int x, int y, e_sb_location location);

/* checks if the specified coordinates represent a corner of the FPGA */
static bool is_corner(const DeviceGrid& grid, int x, int y);

/* checks if the specified coordinates correspond to one of the perimeter switchblocks */
static bool is_perimeter(const DeviceGrid& grid, int x, int y);

/* checks if the specified coordinates correspond to the core of the FPGA (i.e. not perimeter) */
static bool is_core(const DeviceGrid& grid, int x, int y);

/* adjusts a negative destination wire index calculated from a permutation formula */
static int adjust_formula_result(int dest_wire, int src_W, int dest_W, int connection_ind);

/************ Function Definitions ************/
/* allocate and build the switchblock permutation map */
t_sb_connection_map* alloc_and_load_switchblock_permutations(const t_chan_details& chan_details_x,
                                                             const t_chan_details& chan_details_y,
                                                             const DeviceGrid& grid,
                                                             std::vector<t_switchblock_inf> switchblocks,
                                                             t_chan_width* nodes_per_chan,
                                                             e_directionality directionality,
                                                             vtr::RandState& rand_state) {
    /* get a single number for channel width */
    int channel_width = nodes_per_chan->max;
    if (nodes_per_chan->max != nodes_per_chan->x_min || nodes_per_chan->max != nodes_per_chan->y_min) {
        VPR_FATAL_ERROR(VPR_ERROR_ARCH, "Custom switch blocks currently support consistent channel widths only.");
    }

    /* sparse array that will contain switch block connections */
    t_sb_connection_map* sb_conns = new t_sb_connection_map;

    /* We assume that x & y channels have the same ratios of wire types. i.e., looking at a single
     * channel is representative of all channels in the FPGA -- as of 3/9/2013 this is true in VPR */
    t_wire_type_sizes wire_type_sizes;
    count_wire_type_sizes(chan_details_x[0][0].data(), channel_width, &wire_type_sizes);

#ifdef FAST_SB_COMPUTATION
    /******** fast switch block computation method; computes a row of switchblocks then stamps it out everywhere ********/
    /* figure out max(lcm(L_i, L_j)) for all wire lengths belonging to wire types i & j */
    int max_lcm = get_max_lcm(&switchblocks, &wire_type_sizes);
    t_sb_connection_map sb_row;

    /* compute the perimeter switchblocks. unfortunately we can't just compute corners and stamp out the rest because
     * for a unidirectional architecture corners AND perimeter switchblocks require special treatment */
    compute_perimeter_switchblocks(chan_details_x, chan_details_y, &switchblocks,
                                   grid, channel_width, &wire_type_sizes, directionality, sb_conns);

    /* compute the switchblock row */
    compute_switchblock_row(max_lcm, chan_details_x, chan_details_y, &switchblocks,
                            grid, channel_width, &wire_type_sizes, directionality, &sb_row);

    /* stamp-out the switchblock row throughout the rest of the FPGA */
    stampout_switchblocks_from_row(max_lcm, channel_width,
                                   grid, &wire_type_sizes, directionality, &sb_row, sb_conns);

#else
    /******** slow switch block computation method; computes switchblocks at each coordinate ********/
    /* iterate over all the switchblocks specified in the architecture */
    for (int i_sb = 0; i_sb < (int)switchblocks.size(); i_sb++) {
        t_switchblock_inf sb = switchblocks[i_sb];

        /* verify that switchblock type matches specified directionality -- currently we have to stay consistent */
        if (directionality != sb.directionality) {
            VPR_FATAL_ERROR(VPR_ERROR_ARCH, "alloc_and_load_switchblock_connections: Switchblock %s does not match directionality of architecture\n", sb.name.c_str());
        }
        /* Iterate over the x,y coordinates spanning the FPGA. */
        for (size_t x_coord = 0; x_coord < grid.width(); x_coord++) {
            for (size_t y_coord = 0; y_coord <= grid.height(); y_coord++) {
                if (sb_not_here(grid, x_coord, y_coord, sb.location)) {
                    continue;
                }
                /* now we iterate over all the potential side1->side2 connections */
                for (e_side from_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                    for (e_side to_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                        /* Fill appropriate entry of the sb_conns map with vector specifying the wires
                         * the current wire will connect to */
                        compute_wire_connections(x_coord, y_coord, from_side, to_side,
                                                 chan_details_x, chan_details_y, &sb, grid,
                                                 &wire_type_sizes, directionality, sb_conns, rand_state);
                    }
                }
            }
        }
    }
#endif

    return sb_conns;
}

/* deallocates switch block connections sparse array */
void free_switchblock_permutations(t_sb_connection_map* sb_conns) {
    sb_conns->clear();
    delete sb_conns;
    sb_conns = nullptr;
    /* the switch block unordered_map can get quite large and it doesn't seem like the program
     * is interested in releasing the memory back to the OS after the map is cleared.
     * calling malloc_trim forces the program to give unused heap space back to the OS.
     * this significantly reduces memory usage during the routing stage when running multiple
     * large benchmark circuits in parallel. */
    vtr::malloc_trim(0);
    return;
}

#ifdef FAST_SB_COMPUTATION
/* over all connected wire types (i,j), compute the maximum least common multiple of their wire lengths,
 * ie max(LCM(L_i, L_J)) */
static int get_max_lcm(vector<t_switchblock_inf>* switchblocks, t_wire_type_sizes* wire_type_sizes) {
    int max_lcm = -1;
    int num_sb = (int)switchblocks->size();

    /* over each switchblock */
    for (int isb = 0; isb < num_sb; isb++) {
        t_switchblock_inf* sb = &(switchblocks->at(isb));
        int num_wireconns = (int)sb->wireconns.size();
        /* over each wireconn */
        for (int iwc = 0; iwc < num_wireconns; iwc++) {
            t_wireconn_inf* wc = &(sb->wireconns[iwc]);
            int num_from_types = (int)wc->from_type.size();
            int num_to_types = (int)wc->to_type.size();
            /* over each from type */
            for (int ifrom = 0; ifrom < num_from_types; ifrom++) {
                /* over each to type */
                for (int ito = 0; ito < num_to_types; ito++) {
                    if ((*wire_type_sizes).find(wc->from_type[ifrom]) != (*wire_type_sizes).end() && (*wire_type_sizes).find(wc->to_type[ito]) != (*wire_type_sizes).end()) {
                        // the condition can fail if freq of a seg is 0 (so it is in wc, but not in wire_type_size)
                        int length1 = wire_type_sizes->at(wc->from_type[ifrom]).length;
                        int length2 = wire_type_sizes->at(wc->to_type[ito]).length;
                        int current_lcm = vtr::lcm(length1, length2);
                        if (current_lcm > max_lcm) {
                            max_lcm = current_lcm;
                        }
                    }
                }
            }
        }
    }

    return max_lcm;
}

/* computes a horizontal row of switchblocks of size sb_row_size (or of grid.width()-4, whichever is smaller), starting
 * at coordinate (1,1) */
static void compute_switchblock_row(int sb_row_size, t_chan_details* chan_details_x, t_chan_details* chan_details_y, vector<t_switchblock_inf>* switchblocks, const DeviceGrid& grid, int nodes_per_chan, t_wire_type_sizes* wire_type_sizes, e_directionality directionality, t_sb_connection_map* sb_row) {
    int y = 1;
    for (int isb = 0; isb < (int)switchblocks->size(); isb++) {
        t_switchblock_inf* sb = &(switchblocks->at(isb));
        for (int x = 1; x < 1 + sb_row_size; x++) {
            if (sb_not_here(grid, x, y, sb->location)) {
                continue;
            }
            /* now we iterate over all the potential side1->side2 connections */
            for (e_side from_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                for (e_side to_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                    /* Fill appropriate entry of the sb_conns map with vector specifying the wires
                     * the current wire will connect to */
                    compute_wire_connections(x, y, from_side, to_side,
                                             chan_details_x, chan_details_y, sb, grid,
                                             wire_type_sizes, directionality, sb_row);
                }
            }
        }
    }
}

/* stamp out a row of horizontal switchblocks throughout the FPGA starting at coordinates (ref_x, ref_y) and
 * continuing on for sb_row_size */
static void stampout_switchblocks_from_row(int sb_row_size,
                                           int nodes_per_chan,
                                           const DeviceGrid& grid,
                                           t_wire_type_sizes* wire_type_sizes,
                                           e_directionality directionality,
                                           t_sb_connection_map* sb_row,
                                           t_sb_connection_map* sb_conns) {
    /* over all x coordinates that may need stamping out */
    for (int x = 1; x < grid.width() - 2; x++) { //-2 for no perim channels
        /* over all y coordinates that may need stamping out */
        for (int y = 1; y < grid.height() - 2; y++) { //-2 for no perim channels
            /* perimeter has been precomputed */
            if (is_perimeter(grid, x, y)) {
                continue;
            }
            /* over each source side */
            for (e_side from_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                /* over each destination side */
                for (e_side to_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                    /* can't connect a side to itself */
                    if (from_side == to_side) {
                        continue;
                    }
                    /* over each source wire */
                    for (int iwire = 0; iwire < nodes_per_chan; iwire++) {
                        /* get the total x+y distance of the current switchblock from the reference switchblock */
                        int distance = (x - REF_X) + (y - REF_Y);
                        if (distance < 0) {
                            distance = sb_row_size - ((-1 * distance) % sb_row_size);
                        }
                        /* figure out the coordinates of the switchblock we want to copy */
                        int copy_y = 1;
                        int copy_x = 1 + (distance % sb_row_size); //TODO: based on what? explain staggering pattern

                        /* create the indices to key into the switchblock permutation map */
                        Switchblock_Lookup my_key(x, y, from_side, to_side, iwire);
                        Switchblock_Lookup copy_key(copy_x, copy_y, from_side, to_side, iwire);

                        if (sb_row->count(copy_key) == 0) {
                            continue;
                        }

                        (*sb_conns)[my_key] = sb_row->at(copy_key);
                    }
                }
            }
        }
    }
}

/* compute all the switchblocks around the perimeter of the FPGA for the given switchblock and wireconn */
static void compute_perimeter_switchblocks(t_chan_details* chan_details_x, t_chan_details* chan_details_y, vector<t_switchblock_inf>* switchblocks, const DeviceGrid& grid, int nodes_per_chan, t_wire_type_sizes* wire_type_sizes, e_directionality directionality, t_sb_connection_map* sb_conns) {
    int x, y;

    for (int isb = 0; isb < (int)switchblocks->size(); isb++) {
        /* along left and right edge */
        x = 0;
        t_switchblock_inf* sb = &(switchblocks->at(isb));
        for (int i = 0; i < 2; i++) { //TODO: can use i+=grid.width()-2 to make more explicit what the ranges of the loop are
            for (y = 0; y < grid.height(); y++) {
                if (sb_not_here(grid, x, y, sb->location)) {
                    continue;
                }
                /* now we iterate over all the potential side1->side2 connections */
                for (e_side from_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                    for (e_side to_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                        /* Fill appropriate entry of the sb_conns map with vector specifying the wires
                         * the current wire will connect to */
                        compute_wire_connections(x, y, from_side, to_side,
                                                 chan_details_x, chan_details_y, sb, grid,
                                                 wire_type_sizes, directionality, sb_conns);
                    }
                }
            }
            x = grid.width() - 2; //-2 for no perim channels
        }
    }

    for (int isb = 0; isb < (int)switchblocks->size(); isb++) {
        /* along bottom and top edge */
        y = 0;
        t_switchblock_inf* sb = &(switchblocks->at(isb));
        for (int i = 0; i < 2; i++) {
            for (x = 0; x < grid.width(); x++) {
                if (sb_not_here(grid, x, y, sb->location)) {
                    continue;
                }
                /* now we iterate over all the potential side1->side2 connections */
                for (e_side from_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                    for (e_side to_side : {TOP, RIGHT, BOTTOM, LEFT}) {
                        /* Fill appropriate entry of the sb_conns map with vector specifying the wires
                         * the current wire will connect to */
                        compute_wire_connections(x, y, from_side, to_side,
                                                 chan_details_x, chan_details_y, sb, grid,
                                                 wire_type_sizes, directionality, sb_conns);
                    }
                }
            }
            y = grid.height() - 2; //-2 for no perim channels
        }
    }
}

#endif //FAST_SB_COMPUTATION

/* returns true if the coordinates x/y do not correspond to the location specified by 'location' */
static bool sb_not_here(const DeviceGrid& grid, int x, int y, e_sb_location location) {
    bool sb_not_here = true;

    switch (location) {
        case E_EVERYWHERE:
            sb_not_here = false;
            break;
        case E_PERIMETER:
            if (is_perimeter(grid, x, y)) {
                sb_not_here = false;
            }
            break;
        case E_CORNER:
            if (is_corner(grid, x, y)) {
                sb_not_here = false;
            }
            break;
        case E_CORE:
            if (is_core(grid, x, y)) {
                sb_not_here = false;
            }
            break;
        case E_FRINGE:
            if (is_perimeter(grid, x, y) && !is_corner(grid, x, y)) {
                sb_not_here = false;
            }
            break;
        default:
            VPR_FATAL_ERROR(VPR_ERROR_ARCH, "sb_not_here: unrecognized location enum: %d\n", location);
            break;
    }
    return sb_not_here;
}

/* checks if the specified coordinates represent a corner of the FPGA */
static bool is_corner(const DeviceGrid& grid, int x, int y) {
    bool is_corner = false;
    if ((x == 0 && y == 0) || (x == 0 && y == int(grid.height()) - 2) || //-2 for no perim channels
        (x == int(grid.width()) - 2 && y == 0) ||                        //-2 for no perim channels
        (x == int(grid.width()) - 2 && y == int(grid.height()) - 2)) {   //-2 for no perim channels
        is_corner = true;
    }
    return is_corner;
}

/* checks if the specified coordinates correspond to one of the perimeter switchblocks */
static bool is_perimeter(const DeviceGrid& grid, int x, int y) {
    bool is_perimeter = false;
    if (x == 0 || x == int(grid.width()) - 2 || y == 0 || y == int(grid.height()) - 2) {
        is_perimeter = true;
    }
    return is_perimeter;
}

/* checks if the specified coordinates correspond to the core of the FPGA (i.e. not perimeter) */
static bool is_core(const DeviceGrid& grid, int x, int y) {
    bool is_core = !is_perimeter(grid, x, y);
    return is_core;
}

/* Counts the number of wires in each wire type in the specified channel */
static void count_wire_type_sizes(const t_chan_seg_details* channel, int nodes_per_chan, t_wire_type_sizes* wire_type_sizes) {
    std::string wire_type;
    std::string new_type;
    int new_length, length;
    int new_start, start;
    int num_wires = 0;
    Wire_Info wire_info;

    wire_type = channel[0].type_name();
    length = channel[0].length();
    start = 0;
    for (int iwire = 0; iwire < nodes_per_chan; iwire++) {
        new_type = channel[iwire].type_name();
        new_length = channel[iwire].length();
        new_start = iwire;
        if (new_type != wire_type) {
            wire_info.set(length, num_wires, start);
            (*wire_type_sizes)[wire_type] = wire_info;
            wire_type = new_type;
            length = new_length;
            start = new_start;
            num_wires = 0;
        }
        num_wires++;
    }
    wire_info.set(length, num_wires, start);
    (*wire_type_sizes)[wire_type] = wire_info;

    return;
}

/* returns the wire indices belonging to the types in 'wire_type_vec' and switchpoints in 'points' at the given channel segment */
static std::vector<t_wire_switchpoint> get_switchpoint_wires(const DeviceGrid& grid, const t_chan_seg_details* chan_details, t_rr_type chan_type, int x, int y, e_side side, const std::vector<t_wire_switchpoints>& wire_switchpoints_vec, t_wire_type_sizes* wire_type_sizes, bool is_dest, SwitchPointOrder switchpoint_order, vtr::RandState& rand_state) {
    std::vector<t_wire_switchpoint> all_collected_wire_switchpoints;

    int seg_coord = x;
    if (chan_type == CHANY) {
        seg_coord = y;
    }

    for (const t_wire_switchpoints& wire_switchpoints : wire_switchpoints_vec) {
        std::vector<t_wire_switchpoint> collected_wire_switchpoints;

        const auto& wire_type = wire_switchpoints.segment_name;
        const auto& points = wire_switchpoints.switchpoints;

        if ((*wire_type_sizes).find(wire_type) == (*wire_type_sizes).end()) {
            // wire_type_sizes may not contain wire_type if its seg freq is 0
            continue;
        }
        /* get the number of wires of given type */
        int num_type_wires = wire_type_sizes->at(wire_type).num_wires;
        /* get the last wire belonging to this type */
        int first_type_wire = wire_type_sizes->at(wire_type).start;
        int last_type_wire = first_type_wire + num_type_wires - 1;

        /* Walk through each wire segment of specified type and check whether it matches one
         * of the specified switchpoints.
         *
         * Note that we walk through the points in order, this ensures that returned switchpoints
         * match the order specified in the architecture, which we assume is a priority order specified
         * by the archtitect.
         */
        for (int valid_switchpoint : points) {
            for (int iwire = first_type_wire; iwire <= last_type_wire; iwire++) {
                e_direction seg_direction = chan_details[iwire].direction();

                /* unidirectional wires going in the decreasing direction can have an outgoing edge
                 * only from the top or right switch block sides, and an incoming edge only if they are
                 * at the left or bottom sides (analogous for wires going in INC direction) */
                if (side == TOP || side == RIGHT) {
                    if (seg_direction == DEC_DIRECTION && is_dest) {
                        continue;
                    }
                    if (seg_direction == INC_DIRECTION && !is_dest) {
                        continue;
                    }
                } else {
                    VTR_ASSERT(side == LEFT || side == BOTTOM);
                    if (seg_direction == DEC_DIRECTION && !is_dest) {
                        continue;
                    }
                    if (seg_direction == INC_DIRECTION && is_dest) {
                        continue;
                    }
                }

                int wire_switchpoint = get_switchpoint_of_wire(grid, chan_type, chan_details[iwire], seg_coord, side);

                /* check if this wire belongs to one of the specified switchpoints; add it to our 'wires' vector if so */
                if (wire_switchpoint != valid_switchpoint) continue;

                collected_wire_switchpoints.push_back({iwire, wire_switchpoint});
            }
        }

        all_collected_wire_switchpoints.insert(all_collected_wire_switchpoints.end(),
                                               collected_wire_switchpoints.begin(), collected_wire_switchpoints.end());
    }

    if (switchpoint_order == SwitchPointOrder::SHUFFLED) {
        //We new re-order the switchpoints to try to make adjacent switchpoints have different values

        vtr::shuffle(all_collected_wire_switchpoints.begin(), all_collected_wire_switchpoints.end(), rand_state);
    } else {
        VTR_ASSERT(switchpoint_order == SwitchPointOrder::FIXED);
        //Already ordered so same switchpoints are adjacent by above collection loop
    }

    return all_collected_wire_switchpoints;
}

/* Compute the wire(s) that the wire at (x, y, from_side, to_side) should connect to.
 * sb_conns is updated with the result */
static void compute_wire_connections(int x_coord, int y_coord, enum e_side from_side, enum e_side to_side, const t_chan_details& chan_details_x, const t_chan_details& chan_details_y, t_switchblock_inf* sb, const DeviceGrid& grid, t_wire_type_sizes* wire_type_sizes, e_directionality directionality, t_sb_connection_map* sb_conns, vtr::RandState& rand_state) {
    int from_x, from_y;                     /* index into source channel */
    int to_x, to_y;                         /* index into destination channel */
    t_rr_type from_chan_type, to_chan_type; /* the type of channel - i.e. CHANX or CHANY */
    from_x = from_y = to_x = to_y = UNDEFINED;

    SB_Side_Connection side_conn(from_side, to_side);                 /* for indexing into this switchblock's permutation funcs */
    Switchblock_Lookup sb_conn(x_coord, y_coord, from_side, to_side); /* for indexing into FPGA's switchblock map */

    /* can't connect a switchblock side to itself */
    if (from_side == to_side) {
        return;
    }
    /* check that the permutation map has an entry for this side combination */
    if (sb->permutation_map.count(side_conn) == 0) {
        /* the specified switchblock does not have any permutation funcs for this side1->side2 connection */
        return;
    }

    /* find the correct channel, and the coordinates to index into it for both the source and
     * destination channels. also return the channel type (ie chanx/chany) into which we are
     * indexing */
    /* details for source channel */
    const t_chan_details& from_chan_details = index_into_correct_chan(x_coord, y_coord, from_side, chan_details_x, chan_details_y,
                                                                      &from_x, &from_y, &from_chan_type);

    /* details for destination channel */
    const t_chan_details& to_chan_details = index_into_correct_chan(x_coord, y_coord, to_side, chan_details_x, chan_details_y,
                                                                    &to_x, &to_y, &to_chan_type);

    /* make sure from_x/y and to_x/y aren't out of bounds */
    if (coords_out_of_bounds(grid, to_x, to_y, to_chan_type) || coords_out_of_bounds(grid, from_x, from_y, from_chan_type)) {
        return;
    }

    /* iterate over all the wire connections specified for this switch block */
    for (int iconn = 0; iconn < (int)sb->wireconns.size(); iconn++) {
        /* pointer to a connection specification between wire types/subsegment_nums */
        t_wireconn_inf* wireconn_ptr = &sb->wireconns[iconn];

        /* compute the destination wire segments to which the source wire segment should connect based on the
         * current wireconn */
        compute_wireconn_connections(grid, directionality, from_chan_details, to_chan_details,
                                     sb_conn, from_x, from_y, to_x, to_y, from_chan_type, to_chan_type, wire_type_sizes,
                                     sb, wireconn_ptr, sb_conns, rand_state);
    }

    return;
}

/* computes the destination wire segments that a source wire segment at the coordinate 'sb_conn' (in
 * channel segment with coordinate from_x/from_y) should connect to based on the specified 'wireconn_ptr'.
 * wireconn_ptr defines the source and destination sets of wire segments (based on wire segment type & switchpoint
 * as defined at the top of this file), and the indices of wires to connect to are relative to these sets */
static void compute_wireconn_connections(const DeviceGrid& grid, e_directionality directionality, const t_chan_details& from_chan_details, const t_chan_details& to_chan_details, Switchblock_Lookup sb_conn, int from_x, int from_y, int to_x, int to_y, t_rr_type from_chan_type, t_rr_type to_chan_type, t_wire_type_sizes* wire_type_sizes, t_switchblock_inf* sb, t_wireconn_inf* wireconn_ptr, t_sb_connection_map* sb_conns, vtr::RandState& rand_state) {
    constexpr bool verbose = false;

    /* vectors that will contain indices of the wires belonging to the source/dest wire types/points */

    std::vector<t_wire_switchpoint> potential_src_wires = get_switchpoint_wires(grid, from_chan_details[from_x][from_y].data(), from_chan_type, from_x, from_y, sb_conn.from_side,
                                                                                wireconn_ptr->from_switchpoint_set, wire_type_sizes, false, wireconn_ptr->from_switchpoint_order, rand_state);

    std::vector<t_wire_switchpoint> potential_dest_wires = get_switchpoint_wires(grid, to_chan_details[to_x][to_y].data(), to_chan_type, to_x, to_y, sb_conn.to_side,
                                                                                 wireconn_ptr->to_switchpoint_set, wire_type_sizes, true, wireconn_ptr->to_switchpoint_order, rand_state);

    VTR_LOGV(verbose, "SB_LOC: %d,%d %s->%s\n", sb_conn.x_coord, sb_conn.y_coord, SIDE_STRING[sb_conn.from_side], SIDE_STRING[sb_conn.to_side]);

    //Define to print out specific wire-switchpoints used in to/from sets, if verbose is set true
#if 0
    for (auto from_set : wireconn_ptr->from_switchpoint_set) {
        VTR_LOGV(verbose, "  FROM_SET: %s @", from_set.segment_name.c_str());
        for (int switchpoint : from_set.switchpoints) {
            VTR_LOGV(verbose, "%d ", switchpoint);
        }
    }
    VTR_LOGV(verbose, "\n");

    for (auto to_set : wireconn_ptr->to_switchpoint_set) {
        VTR_LOGV(verbose, "  TO_SET: %s @", to_set.segment_name.c_str());
        for (int switchpoint : to_set.switchpoints) {
            VTR_LOGV(verbose, "%d ", switchpoint);
        }
    }
    VTR_LOGV(verbose, "\n");

    vector<std::string> src_wire_str;
    for (t_wire_switchpoint wire_switchpoint : potential_src_wires) {
        src_wire_str.push_back(std::to_string(wire_switchpoint.wire) + "@" + std::to_string(wire_switchpoint.switchpoint));
    }
    vector<std::string> dst_wire_str;
    for (t_wire_switchpoint wire_switchpoint : potential_dest_wires) {
        dst_wire_str.push_back(std::to_string(wire_switchpoint.wire) + "@" + std::to_string(wire_switchpoint.switchpoint));
    }
    auto src_str = vtr::join(src_wire_str, ", ");
    auto dst_str = vtr::join(dst_wire_str, ", ");
    VTR_LOGV(verbose, "  SRC_WIRES: %s\n", src_str.c_str());
    VTR_LOGV(verbose, "  DST_WIRES: %s\n", dst_str.c_str());
#endif

    if (potential_src_wires.size() == 0 || potential_dest_wires.size() == 0) {
        //Can't make any connections between empty sets
        return;
    }

    /* At this point the vectors 'potential_src_wires' and 'potential_dest_wires' contain the indices of the from_type/from_point
     * and to_type/to_point wire segments. Now we compute the connections between them, according to permutation functions */
    size_t src_W = potential_src_wires.size();
    size_t dest_W = potential_dest_wires.size();

    //TODO: We could add another user-configurable parameter to control ordering of types in the sets.
    //      Currently we just iterate through them in order, but we could:
    //      * randomly shuffle, or
    //      * interleave (to ensure good diversity)

    //Determine how many connections to make
    int num_conns = evaluate_num_conns_formula(wireconn_ptr->num_conns_formula, potential_src_wires.size(), potential_dest_wires.size());
    VTR_ASSERT_MSG(num_conns >= 0, "Number of switchblock connections to create must be non-negative");

    VTR_LOGV(verbose, "  num_conns: %zu\n", num_conns);

    for (size_t iconn = 0; iconn < size_t(num_conns); ++iconn) {
        //Select the from wire
        // We modulo by the src set size to wrap around if there are more connections that src wires
        int src_wire_ind = iconn % potential_src_wires.size();  //Index in src set
        int from_wire = potential_src_wires[src_wire_ind].wire; //Index in channel

        e_direction from_wire_direction = from_chan_details[from_x][from_y][from_wire].direction();
        if (from_wire_direction == INC_DIRECTION) {
            /* if this is a unidirectional wire headed in the increasing direction (relative to coordinate system)
             * then switch block source side should be BOTTOM or LEFT */
            if (sb_conn.from_side == TOP || sb_conn.from_side == RIGHT) {
                continue;
            }
            VTR_ASSERT(sb_conn.from_side == BOTTOM || sb_conn.from_side == LEFT);
        } else if (from_wire_direction == DEC_DIRECTION) {
            /* a wire heading in the decreasing direction can only connect from the TOP or RIGHT sides of a switch block */
            if (sb_conn.from_side == BOTTOM || sb_conn.from_side == LEFT) {
                continue;
            }
            VTR_ASSERT(sb_conn.from_side == TOP || sb_conn.from_side == RIGHT);
        } else {
            VTR_ASSERT(from_wire_direction == BI_DIRECTION);
        }

        //Evaluate permutation functions for the from_wire
        SB_Side_Connection side_conn(sb_conn.from_side, sb_conn.to_side);
        std::vector<std::string>& permutations_ref = sb->permutation_map[side_conn];
        for (int iperm = 0; iperm < (int)permutations_ref.size(); iperm++) {
            /* Convert the symbolic permutation formula to a number */
            t_formula_data formula_data;
            formula_data.set_var_value("W", dest_W);
            formula_data.set_var_value("t", src_wire_ind);
            int raw_dest_wire_ind = get_sb_formula_raw_result(permutations_ref[iperm].c_str(), formula_data);
            int dest_wire_ind = adjust_formula_result(raw_dest_wire_ind, src_W, dest_W, iconn);

            if (dest_wire_ind < 0) {
                VPR_FATAL_ERROR(VPR_ERROR_ARCH, "Got a negative wire from switch block formula %s", permutations_ref[iperm].c_str());
            }

            int to_wire = potential_dest_wires[dest_wire_ind].wire; //Index in channel

            /* create the struct containing information about the target wire segment which will be added to the
             * sb connections map */
            t_switchblock_edge sb_edge;
            sb_edge.from_wire = from_wire;
            sb_edge.to_wire = to_wire;
            sb_edge.switch_ind = to_chan_details[to_x][to_y][to_wire].arch_wire_switch();
            VTR_LOGV(verbose, "  make_conn: %d -> %d switch=%d\n", sb_edge.from_wire, sb_edge.to_wire, sb_edge.switch_ind);

            /* and now, finally, add this switchblock connection to the switchblock connections map */
            (*sb_conns)[sb_conn].push_back(sb_edge);

            /* If bidir architecture, implement the reverse connection as well */
            if (BI_DIRECTIONAL == directionality) {
                t_switchblock_edge sb_reverse_edge = sb_edge;
                std::swap(sb_reverse_edge.from_wire, sb_reverse_edge.to_wire);
                //Since we are implementing the reverse connection we have swapped from and to.
                //
                //Coverity flags this (false positive), so annotatate so coverity ignores it:
                // coverity[swapped_arguments : Intentional]
                Switchblock_Lookup sb_conn_reverse(sb_conn.x_coord, sb_conn.y_coord, sb_conn.to_side, sb_conn.from_side);
                (*sb_conns)[sb_conn_reverse].push_back(sb_reverse_edge);
            }
        }
    }
}

static int evaluate_num_conns_formula(std::string num_conns_formula, int from_wire_count, int to_wire_count) {
    t_formula_data vars;

    vars.set_var_value("from", from_wire_count);
    vars.set_var_value("to", to_wire_count);

    return parse_formula(num_conns_formula, vars);
}

/* Here we find the correct channel (x or y), and the coordinates to index into it based on the
 * specified tile coordinates and the switchblock side. Also returns the type of channel
 * that we are indexing into (ie, CHANX or CHANY */
static const t_chan_details& index_into_correct_chan(int tile_x, int tile_y, enum e_side side, const t_chan_details& chan_details_x, const t_chan_details& chan_details_y, int* set_x, int* set_y, t_rr_type* chan_type) {
    *chan_type = CHANX;

    /* here we use the VPR convention that a tile 'owns' the channels directly to the right
     * and above it */
    switch (side) {
        case TOP:
            /* this is y-channel belonging to tile above */
            *set_x = tile_x;
            *set_y = tile_y + 1;
            *chan_type = CHANY;
            return chan_details_y;
            break;
        case RIGHT:
            /* this is x-channel belonging to tile to the right */
            *set_x = tile_x + 1;
            *set_y = tile_y;
            *chan_type = CHANX;
            return chan_details_x;
            break;
        case BOTTOM:
            /* this is y-channel on the right of the tile */
            *set_x = tile_x;
            *set_y = tile_y;
            *chan_type = CHANY;
            return chan_details_y;
            break;
        case LEFT:
            /* this is x-channel on top of the tile */
            *set_x = tile_x;
            *set_y = tile_y;
            *chan_type = CHANX;
            return chan_details_x;
            break;
        default:
            VPR_FATAL_ERROR(VPR_ERROR_ARCH, "index_into_correct_chan: unknown side specified: %d\n", side);
            break;
    }
    VTR_ASSERT(false);
    return chan_details_x; //Unreachable
}

/* checks whether the specified coordinates are out of bounds */
static bool coords_out_of_bounds(const DeviceGrid& grid, int x_coord, int y_coord, e_rr_type chan_type) {
    bool result = true;

    if (CHANX == chan_type) {
        if (x_coord <= 0 || x_coord >= int(grid.width()) - 1 || /* there is no x-channel at x=0 */
            y_coord < 0 || y_coord >= int(grid.height()) - 1) {
            result = true;
        } else {
            result = false;
        }
    } else if (CHANY == chan_type) {
        if (x_coord < 0 || x_coord >= int(grid.width()) - 1 || y_coord <= 0 || y_coord >= int(grid.height()) - 1) { /* there is no y-channel at y=0 */
            result = true;
        } else {
            result = false;
        }

    } else {
        VPR_FATAL_ERROR(VPR_ERROR_ARCH, "coords_out_of_bounds(): illegal channel type %d\n", chan_type);
    }
    return result;
}

/* returns the subsegment number of the specified wire at seg_coord */
static int get_wire_subsegment_num(const DeviceGrid& grid, e_rr_type chan_type, const t_chan_seg_details& wire_details, int seg_coord) {
    /* We get wire subsegment number by comparing the wire's seg_coord to the seg_start of the wire.
     * The offset between seg_start (or seg_end) and seg_coord is the subsegment number
     *
     * Cases:
     * seg starts at bottom but does not extend all the way to the top -- look at seg_end
     * seg starts > bottom and does not extend all the way to top -- look at seg_start
     * seg starts > bottom but terminates all the way at the top -- look at seg_start
     * seg starts at bottom and extends all the way to the top -- look at seg end
     */

    int subsegment_num;
    int seg_start = wire_details.seg_start();
    int seg_end = wire_details.seg_end();
    e_direction direction = wire_details.direction();
    int wire_length = get_wire_segment_length(grid, chan_type, wire_details);
    int min_seg;

    /* determine the minimum and maximum values that the 'seg' coordinate
     * of a wire can take */
    min_seg = 1;

    if (seg_start != min_seg) {
        subsegment_num = seg_coord - seg_start;
    } else {
        subsegment_num = (wire_length - 1) - (seg_end - seg_coord);
    }

    /* if this wire is going in the decreasing direction, reverse the subsegment num */
    VTR_ASSERT(seg_end >= seg_start);
    if (direction == DEC_DIRECTION) {
        subsegment_num = wire_length - 1 - subsegment_num;
    }

    return subsegment_num;
}

/* returns wire segment length based on either:
 * 1) the wire length specified in the segment details variable for this wire (if this wire segment doesn't span entire FPGA)
 * 2) the seg_start and seg_end coordinates in the segment details for this wire (if this wire segment spans entire FPGA, as might happen for very long wires)
 *
 * Computing the wire segment length in this way help to classify short vs long wire segments according to switchpoint. */
int get_wire_segment_length(const DeviceGrid& grid, e_rr_type chan_type, const t_chan_seg_details& wire_details) {
    int wire_length;

    int min_seg = 1;
    int max_seg = grid.width() - 2; //-2 for no perim channels
    if (chan_type == CHANY) {
        max_seg = grid.height() - 2; //-2 for no perim channels
    }

    int seg_start = wire_details.seg_start();
    int seg_end = wire_details.seg_end();

    if (seg_start == min_seg && seg_end == max_seg) {
        wire_length = seg_end - seg_start + 1;
    } else {
        wire_length = wire_details.length();
    }

    return wire_length;
}

/* Returns the switchpoint of the wire specified by wire_details at a segment coordinate
 * of seg_coord, and connection to the sb_side of the switchblock */
static int get_switchpoint_of_wire(const DeviceGrid& grid, e_rr_type chan_type, const t_chan_seg_details& wire_details, int seg_coord, e_side sb_side) {
    /* this function calculates the switchpoint of a given wire by first calculating
     * the subsegmennt number of the specified wire. For instance, for a wire with L=4:
     *
     * switchpoint:	0-------1-------2-------3-------0
     * subsegment_num:	    0       1       2       3
     *
     * So knowing the wire's subsegment_num and which switchblock side it connects to is
     * enough to calculate the switchpoint
     *
     */

    int switchpoint;

    /* get the minimum and maximum segment coordinate which a wire in this channel type can take */
    int min_seg = 1;
    int max_seg = grid.width() - 2; //-2 for no perim channels
    if (chan_type == CHANY) {
        max_seg = grid.height() - 2; //-2 for no perim channels
    }

    /* check whether the current seg_coord/sb_side coordinate specifies a perimeter switch block side at which all wire segments terminate/start.
     * in this case only segments with switchpoints = 0 can exist */
    bool perimeter_connection = false;
    if ((seg_coord == min_seg && (sb_side == RIGHT || sb_side == TOP)) || (seg_coord == max_seg && (sb_side == LEFT || sb_side == BOTTOM))) {
        perimeter_connection = true;
    }

    if (perimeter_connection) {
        switchpoint = 0;
    } else {
        int wire_length = get_wire_segment_length(grid, chan_type, wire_details);
        int subsegment_num = get_wire_subsegment_num(grid, chan_type, wire_details, seg_coord);

        e_direction direction = wire_details.direction();
        if (LEFT == sb_side || BOTTOM == sb_side) {
            switchpoint = (subsegment_num + 1) % wire_length;
            if (direction == DEC_DIRECTION) {
                switchpoint = subsegment_num;
            }
        } else {
            VTR_ASSERT(RIGHT == sb_side || TOP == sb_side);
            switchpoint = subsegment_num;
            if (direction == DEC_DIRECTION) {
                switchpoint = (subsegment_num + 1) % wire_length;
            }
        }
    }

    return switchpoint;
}

/* adjusts the destination wire calculated from a permutation formula to account for negative indicies,
 * source wire set offset, and modulo by destination wire set size
 * */
static int adjust_formula_result(int dest_wire, int src_W, int dest_W, int connection_ind) {
    int result = dest_wire;

    if (dest_wire < 0) {
        //Adjust for negative indicies
        int mult = (-1 * dest_wire) / dest_W + 1;
        result = dest_wire + mult * dest_W;
    }

    //Offset the destination track by a multiple of src_W to ensure all destination tracks are covered
    //
    // The permutation formula produce a 1-to-1 mapping from src track to dest track (i.e. each source
    // track is mapped to precisely one destination track). This is problematic if we are processing
    // a wireconn which goes through the source set multiple times (e.g. dest set larger than src set while
    // processing a WireConnType::TO), since the permutation formula will only generate src_W track indicies
    // (leaving some of the destination tracks unconnected). To ensure we get different destination tracks on
    // subsequent passes through the same source set, we offset the raw track by a multiple of src_W. Note the
    // use of integer division; src_mult will equal 0 on the first pass, 1 on the second etc.
    int src_mult = connection_ind / src_W;
    result += src_W * src_mult;

    //Final result must be modulo dest_W
    result = (result + dest_W) % dest_W;

    return result;
}
