/*
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 "vpr_error.h"

#include "build_switchblocks.h"
#include "physical_types.h"
#include "parse_switchblocks.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);
	}
};


/************ 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(t_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);

/* ... 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);

/* returns the wire indices belonging to the types in 'wire_type_vec' and switchpoints in 'points' at the given channel segment */ 
static void get_switchpoint_wires(const DeviceGrid& grid, const t_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, vector<int> *wires);

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_seg_details &wire_details, int seg_coord);

int get_wire_segment_length(const DeviceGrid& grid, e_rr_type chan_type, const t_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_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){

	/* 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], 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);
                        
                    }
                }
			}
		}
	}
#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 = NULL;
	/* 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(t_seg_details *channel, int nodes_per_chan, 
			t_wire_type_sizes *wire_type_sizes){
	string wire_type;
	const char * new_type;
	int new_length, length;
	int new_start, start;
	int num_wires = 0;
	Wire_Info wire_info;	

	wire_type = channel[0].type_name_ptr;
	length = channel[0].length;
	start = 0;
	for (int iwire = 0; iwire < nodes_per_chan; iwire++){
		new_type = channel[iwire].type_name_ptr;
		new_length = channel[iwire].length;
		new_start = iwire;
		if (strcmp(new_type, wire_type.c_str()) != 0){
			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 void get_switchpoint_wires(const DeviceGrid& grid, const t_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, vector<int> *wires){

	wires->clear();

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

	for (const t_wire_switchpoints& wire_switchpoints : wire_switchpoints_vec){

		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 */
		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 ( find( points.begin(), points.end(), wire_switchpoint ) != points.end() ){
				wires->push_back( iwire );
			}
		}
	}
	sort(wires->begin(), wires->end());
}


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

	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);
	}

	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){

	/* vectors that will contain indices of the wires belonging to the source/dest wire types/points */
	vector<int> potential_src_wires;
	vector<int> potential_dest_wires;

	get_switchpoint_wires(grid, from_chan_details[from_x][from_y], from_chan_type, from_x, from_y, sb_conn.from_side, 
			wireconn_ptr->from_switchpoint_set, wire_type_sizes, false, &potential_src_wires);

	get_switchpoint_wires(grid, to_chan_details[to_x][to_y], to_chan_type, to_x, to_y, sb_conn.to_side, 
			wireconn_ptr->to_switchpoint_set, wire_type_sizes, true, &potential_dest_wires);

    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 = 0;
    if (wireconn_ptr->num_conns_type == WireConnType::FROM) {
        num_conns = potential_src_wires.size();

    } else if (wireconn_ptr->num_conns_type == WireConnType::TO) {
        num_conns = potential_dest_wires.size();

    } else if (wireconn_ptr->num_conns_type == WireConnType::MIN) {
        num_conns = std::min(potential_src_wires.size(), potential_dest_wires.size());

    } else if (wireconn_ptr->num_conns_type == WireConnType::MAX) {
        num_conns = std::max(potential_src_wires.size(), potential_dest_wires.size());

    } else {
        vpr_throw(VPR_ERROR_ARCH, __FILE__, __LINE__, "Unrecognized wireconn type"); 
    }


    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]; //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]; //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;

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


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

