/*
 * 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"

using namespace std;

/************ 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 map<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 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,
                                                             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_throw(VPR_ERROR_ARCH, __FILE__, __LINE__, "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_throw(VPR_ERROR_ARCH, __FILE__, __LINE__, "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_throw(VPR_ERROR_ARCH, __FILE__, __LINE__, "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) {
    string wire_type;
    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 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
    size_t num_conns = evaluate_num_conns_formula(wireconn_ptr->num_conns_formula, potential_src_wires.size(), potential_dest_wires.size());

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

    for (size_t iconn = 0; iconn < 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);
        vector<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_throw(VPR_ERROR_ARCH, __FILE__, __LINE__, "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_throw(VPR_ERROR_ARCH, __FILE__, __LINE__, "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_throw(VPR_ERROR_ARCH, __FILE__, __LINE__, "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;
}
