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

