/*
 * 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_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) {
    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
    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);
        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_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;
}
