#include <stdio.h>
#include <assert.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "rr_graph_util.h"
#include "rr_graph2.h"
#include "rr_graph_sbox.h"

#define ALLOW_SWITCH_OFF

/* WMF: May 07 I put this feature in, but on May 09 in my testing phase
 * I found that for Wilton, this feature is bad, since Wilton is already doing
 * a reverse. */
#define ENABLE_REVERSE 0


#define SAME_TRACK -5
#define UN_SET -1
/* Variables below are the global variables shared only amongst the rr_graph *
 ************************************ routines. ******************************/

/* [0..num_rr_nodes-1].  TRUE if a node is already listed in the edges array *
 * that's being constructed.  This allows me to ensure that there are never  *
 *  duplicate edges (two edges between the same thing).                      */

boolean *rr_edge_done;


/* Used to keep my own list of free linked integers, for speed reasons.     */

t_linked_edge *free_edge_list_head = NULL;



/*************************** Variables local to this module *****************/

/* Two arrays below give the rr_node_index of the channel segment at        *
 * (i,j,track) for fast index lookup.                                       */

/* UDSD Modifications by WMF Begin */

/* The sblock_pattern_init_mux_lookup contains the assignment of incoming
 * wires to muxes. More specifically, it only contains the assignment of 
 * M-to-N cases. WMF_BETTER_COMMENTS */

/* UDSD MOdifications by WMF End */


/************************** Subroutines local to this module ****************/

static void get_switch_type(boolean is_from_sbox,
			    boolean is_to_sbox,
			    short from_node_switch,
			    short to_node_switch,
			    short switch_types[2]);

static void load_chan_rr_indices(IN int nodes_per_chan,
				 IN int chan_len,
				 IN int num_chans,
				 IN t_rr_type type,
				 IN t_seg_details * seg_details,
				 INOUT int *index,
				 INOUT t_ivec *** indices);

static int get_bidir_track_to_chan_seg(IN struct s_ivec conn_tracks,
				       IN t_ivec *** rr_node_indices,
				       IN int to_chan,
				       IN int to_seg,
				       IN int to_sb,
				       IN t_rr_type to_type,
				       IN t_seg_details * seg_details,
				       IN boolean from_is_sbox,
				       IN int from_switch,
				       INOUT boolean * rr_edge_done,
				       IN enum e_directionality
				       directionality,
				       INOUT struct s_linked_edge
				       **edge_list);

static int get_unidir_track_to_chan_seg(IN boolean is_end_sb,
					IN int from_track,
					IN int to_chan,
					IN int to_seg,
					IN int to_sb,
					IN t_rr_type to_type,
					IN int nodes_per_chan,
					IN int nx,
					IN int ny,
					IN enum e_side from_side,
					IN enum e_side to_side,
					IN int Fs_per_side,
					IN int *opin_mux_size,
					IN short *****sblock_pattern,
					IN t_ivec *** rr_node_indices,
					IN t_seg_details * seg_details,
					INOUT boolean * rr_edge_done,
					OUT boolean * Fs_clipped,
					INOUT struct s_linked_edge
					**edge_list);

static int vpr_to_phy_track(IN int itrack,
			    IN int chan_num,
			    IN int seg_num,
			    IN t_seg_details * seg_details,
			    IN enum e_directionality directionality);

static int *get_seg_track_counts(IN int num_sets,
				 IN int num_seg_types,
				 IN t_segment_inf * segment_inf,
				 IN boolean use_full_seg_groups);

static int *label_wire_muxes(IN int chan_num,
			     IN int seg_num,
			     IN t_seg_details * seg_details,
			     IN int max_len,
			     IN enum e_direction dir,
			     IN int nodes_per_chan,
			     OUT int *num_wire_muxes);

static int *label_wire_muxes_for_balance(IN int chan_num,
					 IN int seg_num,
					 IN t_seg_details * seg_details,
					 IN int max_len,
					 IN enum e_direction direction,
					 IN int nodes_per_chan,
					 IN int *num_wire_muxes,
					 IN t_rr_type chan_type,
					 IN int *opin_mux_size,
					 IN t_ivec *** rr_node_indices);

static int *label_incoming_wires(IN int chan_num,
				 IN int seg_num,
				 IN int sb_seg,
				 IN t_seg_details * seg_details,
				 IN int max_len,
				 IN enum e_direction dir,
				 IN int nodes_per_chan,
				 OUT int *num_incoming_wires,
				 OUT int *num_ending_wires);

static int find_label_of_track(int *wire_mux_on_track,
			       int num_wire_muxes,
			       int from_track);

/******************** Subroutine definitions *******************************/

/* This assigns tracks (individually or pairs) to segment types.
 * It tries to match requested ratio. If use_full_seg_groups is
 * true, then segments are assigned only in multiples of their
 * length. This is primarily used for making a tileable unidir
 * layout. The effect of using this is that the number of tracks
 * requested will not always be met and the result will sometimes
 * be over and sometimes under.
 * The pattern when using use_full_seg_groups is to keep adding
 * one group of the track type that wants the largest number of
 * groups of tracks. Each time a group is assigned, the types
 * demand is reduced by 1 unit. The process stops when we are
 * no longer less than the requested number of tracks. As a final
 * step, if we were closer to target before last more, undo it
 * and end up with a result that uses fewer tracks than given. */
static int *
get_seg_track_counts(IN int num_sets,
		     IN int num_seg_types,
		     IN t_segment_inf * segment_inf,
		     IN boolean use_full_seg_groups)
{
    int *result;
	double *demand;
    int i, imax, freq_sum, assigned, size;
	double scale, max, reduce;

    result = (int *)my_malloc(sizeof(int) * num_seg_types);
    demand = (double *)my_malloc(sizeof(double) * num_seg_types);

    /* Scale factor so we can divide by any length
     * and still use integers */
    scale = 1;
    freq_sum = 0;
    for(i = 0; i < num_seg_types; ++i)
	{
	    scale *= segment_inf[i].length;
	    freq_sum += segment_inf[i].frequency;
	}
    reduce = scale * freq_sum;

    /* Init assignments to 0 and set the demand values */
    for(i = 0; i < num_seg_types; ++i)
	{
	    result[i] = 0;
	    demand[i] = scale * num_sets * segment_inf[i].frequency;
	    if(use_full_seg_groups)
		{
		    demand[i] /= segment_inf[i].length;
		}
	}

    /* Keep assigning tracks until we use them up */
    assigned = 0;
    size = 0;
    imax = 0;
    while(assigned < num_sets)
	{
	    /* Find current maximum demand */
	    max = 0;
	    for(i = 0; i < num_seg_types; ++i)
		{
		    if(demand[i] > max)
			{
			    imax = i;
			    max = demand[i];
			}
		}

	    /* Assign tracks to the type and reduce the types demand */
	    size = (use_full_seg_groups ? segment_inf[imax].length : 1);
	    demand[imax] -= reduce;
	    result[imax] += size;
	    assigned += size;
	}

    /* Undo last assignment if we were closer to goal without it */
    if((assigned - num_sets) > (size / 2))
	{
	    result[imax] -= size;
	}

    /* Free temps */
    if(demand)
	{
	    free(demand);
	    demand = NULL;
	}

    /* This must be freed by caller */
    return result;
}


t_seg_details *
alloc_and_load_seg_details(INOUT int *nodes_per_chan,
			   IN int max_len,
			   IN int num_seg_types,
			   IN t_segment_inf * segment_inf,
			   IN boolean use_full_seg_groups,
			   IN boolean is_global_graph,
			   IN enum e_directionality directionality)
{

    /* Allocates and loads the seg_details data structure.  Max_len gives the   *
     * maximum length of a segment (dimension of array).  The code below tries  *
     * to:                                                                      *
     * (1) stagger the start points of segments of the same type evenly;        *
     * (2) spread out the limited number of connection boxes or switch boxes    *
     *     evenly along the length of a segment, starting at the segment ends;  *
     * (3) stagger the connection and switch boxes on different long lines,     *
     *     as they will not be staggered by different segment start points.     */

    int i, cur_track, ntracks, itrack, length, j, index;
    int wire_switch, opin_switch, fac, num_sets, tmp;
    int group_start, first_track;
    int *sets_per_seg_type = NULL;
    t_seg_details *seg_details = NULL;
    boolean longline;

    /* Unidir tracks are assigned in pairs, and bidir tracks individually */
    if(directionality == BI_DIRECTIONAL)
	{
	    fac = 1;
	}
    else
	{
	    assert(directionality == UNI_DIRECTIONAL);
	    fac = 2;
	}
    assert(*nodes_per_chan % fac == 0);

    /* Map segment type fractions and groupings to counts of tracks */
    sets_per_seg_type = get_seg_track_counts((*nodes_per_chan / fac),
					     num_seg_types,
					     segment_inf,
					     use_full_seg_groups);

    /* Count the number tracks actually assigned. */
    tmp = 0;
    for(i = 0; i < num_seg_types; ++i)
	{
	    tmp += sets_per_seg_type[i] * fac;
	}
    assert(use_full_seg_groups || (tmp == *nodes_per_chan));
    *nodes_per_chan = tmp;

    seg_details = (t_seg_details *)
	my_malloc(*nodes_per_chan * sizeof(t_seg_details));

    /* Setup the seg_details data */
    cur_track = 0;
    for(i = 0; i < num_seg_types; ++i)
	{
	    first_track = cur_track;

	    num_sets = sets_per_seg_type[i];
	    ntracks = fac * num_sets;
	    if(ntracks < 1)
		{
		    continue;
		}
	    /* Avoid divide by 0 if ntracks */
	    longline = segment_inf[i].longline;
	    length = segment_inf[i].length;
	    if(longline)
		{
		    length = max_len;
		}

	    wire_switch = segment_inf[i].wire_switch;
	    opin_switch = segment_inf[i].opin_switch;
	    assert((wire_switch == opin_switch)
		   || (directionality != UNI_DIRECTIONAL));

	    /* Set up the tracks of same type */
	    group_start = 0;
	    for(itrack = 0; itrack < ntracks; itrack++)
		{

		    /* Remember the start track of the current wire group */
		    if((itrack / fac) % length == 0 && (itrack % fac) == 0)
			{
			    group_start = cur_track;
			}

		    seg_details[cur_track].length = length;
		    seg_details[cur_track].longline = longline;

		    /* Stagger the start points in for each track set. The 
		     * pin mappings should be aware of this when chosing an
		     * intelligent way of connecting pins and tracks.
		     * cur_track is used as an offset so that extra tracks
		     * from different segment types are hopefully better
		     * balanced. */
		    seg_details[cur_track].start =
			(cur_track / fac) % length + 1;

		    /* These properties are used for vpr_to_phy_track to determine
		     * * twisting of wires. */
		    seg_details[cur_track].group_start = group_start;
		    seg_details[cur_track].group_size =
			min(ntracks + first_track - group_start,
			    length * fac);
		    assert(0 == seg_details[cur_track].group_size % fac);
		    if(0 == seg_details[cur_track].group_size)
			{
			    seg_details[cur_track].group_size = length * fac;
			}

		    /* Setup the cb and sb patterns. Global route graphs can't depopulate cb and sb
		     * since this is a property of a detailed route. */
		    seg_details[cur_track].cb =
			(boolean *) my_malloc(length * sizeof(boolean));
		    seg_details[cur_track].sb =
			(boolean *) my_malloc((length + 1) * sizeof(boolean));
		    for(j = 0; j < length; ++j)
			{
			    if(is_global_graph)
				{
				    seg_details[cur_track].cb[j] = TRUE;
				}
			    else
				{
				    index = j;

				    /* Rotate longline's so they vary across the FPGA */
				    if(longline)
					{
					    index = (index + itrack) % length;
					}

				    /* Reverse the order for tracks going in DEC_DIRECTION */
				    if(itrack % fac == 1)
					{
					    index = (length - 1) - j;
					}

				    /* Use the segment's pattern. */
				    index = j % segment_inf[i].cb_len;
				    seg_details[cur_track].cb[j] =
					segment_inf[i].cb[index];
				}
			}
		    for(j = 0; j < (length + 1); ++j)
			{
			    if(is_global_graph)
				{
				    seg_details[cur_track].sb[j] = TRUE;
				}
			    else
				{
				    index = j;

				    /* Rotate longline's so they vary across the FPGA */
				    if(longline)
					{
					    index =
						(index + itrack) % (length +
								    1);
					}

				    /* Reverse the order for tracks going in DEC_DIRECTION */
				    if(itrack % fac == 1)
					{
					    index = ((length + 1) - 1) - j;
					}

				    /* Use the segment's pattern. */
				    index = j % segment_inf[i].sb_len;
				    seg_details[cur_track].sb[j] =
					segment_inf[i].sb[index];
				}
			}

		    seg_details[cur_track].Rmetal = segment_inf[i].Rmetal;
		    seg_details[cur_track].Cmetal = segment_inf[i].Cmetal;

		    seg_details[cur_track].wire_switch = wire_switch;
		    seg_details[cur_track].opin_switch = opin_switch;

		    if(BI_DIRECTIONAL == directionality)
			{
			    seg_details[cur_track].direction = BI_DIRECTION;
			}
		    else
			{
			    assert(UNI_DIRECTIONAL == directionality);
			    seg_details[cur_track].direction =
				(itrack % 2) ? DEC_DIRECTION : INC_DIRECTION;
			}

		    switch (segment_inf[i].directionality)
			{
			case UNI_DIRECTIONAL:
			    seg_details[cur_track].drivers = SINGLE;
			    break;
			case BI_DIRECTIONAL:
			    seg_details[cur_track].drivers = MULTI_BUFFERED;
			    break;
			}

		    seg_details[cur_track].index = i;

		    ++cur_track;
		}
	}			/* End for each segment type. */

	/* free variables */
	free(sets_per_seg_type);

    return seg_details;
}

void
free_seg_details(t_seg_details * seg_details,
		 int nodes_per_chan)
{

    /* Frees all the memory allocated to an array of seg_details structures. */

    int i;

    for(i = 0; i < nodes_per_chan; i++)
	{
	    free(seg_details[i].cb);
	    free(seg_details[i].sb);
	}
    free(seg_details);
}


/* Dumps out an array of seg_details structures to file fname.  Used only   *
 * for debugging.                                                           */
void
dump_seg_details(t_seg_details * seg_details,
		 int nodes_per_chan,
		 char *fname)
{

    FILE *fp;
    int i, j;
    const char *drivers_names[] = { "multi_buffered",
	"multi_muxed",
	"multi_merged",
	"single"
    };
    const char *direction_names[] = { "inc_direction",
	"dec_direction",
	"bi_direction"
    };

    fp = my_fopen(fname, "w");

    for(i = 0; i < nodes_per_chan; i++)
	{
	    fprintf(fp, "Track: %d.\n", i);
	    fprintf(fp, "Length: %d,  Start: %d,  Long line: %d  "
		    "wire_switch: %d  opin_switch: %d.\n",
		    seg_details[i].length,
		    seg_details[i].start,
		    seg_details[i].longline,
		    seg_details[i].wire_switch, seg_details[i].opin_switch);

	    fprintf(fp, "Rmetal: %g  Cmetal: %g\n",
		    seg_details[i].Rmetal, seg_details[i].Cmetal);

	    fprintf(fp, "Direction: %s  Drivers: %s\n",
		    direction_names[seg_details[i].direction],
		    drivers_names[seg_details[i].drivers]);

	    fprintf(fp, "Start Track: %d  End Track: %d\n",
		    seg_details[i].start_track, seg_details[i].end_track);

	    fprintf(fp, "cb list:  ");
	    for(j = 0; j < seg_details[i].length; j++)
		fprintf(fp, "%d ", seg_details[i].cb[j]);
	    fprintf(fp, "\n");

	    fprintf(fp, "sb list: ");
	    for(j = 0; j <= seg_details[i].length; j++)
		fprintf(fp, "%d ", seg_details[i].sb[j]);
	    fprintf(fp, "\n");

	    fprintf(fp, "\n");
	}

    fclose(fp);
}



/* Returns the segment number at which the segment this track lies on        *
 * started.                                                                  */
int
get_seg_start(IN t_seg_details * seg_details,
	      IN int itrack,
	      IN int chan_num,
	      IN int seg_num)
{

    int seg_start, length, start;

    seg_start = 1;
    if(FALSE == seg_details[itrack].longline)
	{

	    length = seg_details[itrack].length;
	    start = seg_details[itrack].start;

	    /* Start is guaranteed to be between 1 and length.  Hence adding length to *
	     * the quantity in brackets below guarantees it will be nonnegative.       */

	    assert(start > 0);
	    assert(start <= length);

	    /* NOTE: Start points are staggered between different channels.
	     * The start point must stagger backwards as chan_num increases.
	     * Unidirectional routing expects this to allow the N-to-N 
	     * assumption to be made with respect to ending wires in the core. */
	    seg_start =
		seg_num - (seg_num + length + chan_num - start) % length;
	    if(seg_start < 1)
		{
		    seg_start = 1;
		}
	}

    return seg_start;
}

int
get_seg_end(IN t_seg_details * seg_details,
	    IN int itrack,
	    IN int istart,
	    IN int chan_num,
	    IN int seg_max)
{
    int len, ofs, end, first_full;

    len = seg_details[itrack].length;
    ofs = seg_details[itrack].start;

    /* Normal endpoint */
    end = istart + len - 1;

    /* If start is against edge it may have been clipped */
    if(1 == istart)
	{
	    /* If the (staggered) startpoint of first full wire wasn't
	     * also 1, we must be the clipped wire */
	    first_full = (len - (chan_num % len) + ofs - 1) % len + 1;
	    if(first_full > 1)
		{
		    /* then we stop just before the first full seg */
		    end = first_full - 1;
		}
	}

    /* Clip against far edge */
    if(end > seg_max)
	{
	    end = seg_max;
	}

    return end;
}




/* Returns the number of tracks to which clb opin #ipin at (i,j) connects.   *
 * Also stores the nodes to which this pin connects in the linked list       *
 * pointed to by *edge_list_ptr.                                             */
int
get_bidir_opin_connections(IN int i,
			   IN int j,
			   IN int ipin,
			   IN struct s_linked_edge **edge_list,
			   IN int *****opin_to_track_map,
			   IN int Fc,
			   IN boolean * rr_edge_done,
			   IN t_ivec *** rr_node_indices,
			   IN t_seg_details * seg_details)
{

    int iside, num_conn, ofs, tr_i, tr_j, chan, seg;
    int to_track, to_switch, to_node, iconn;
	int is_connected_track;
    t_type_ptr type;
    t_rr_type to_type;

    type = grid[i][j].type;
    ofs = grid[i][j].offset;

    num_conn = 0;

    /* [0..num_types-1][0..num_pins-1][0..height][0..3][0..Fc-1] */
    for(iside = 0; iside < 4; iside++)
	{

	    /* Figure out coords of channel segment based on side */
	    tr_i = ((iside == LEFT) ? (i - 1) : i);
	    tr_j = ((iside == BOTTOM) ? (j - 1) : j);

	    to_type = ((iside == LEFT) || (iside == RIGHT)) ? CHANY : CHANX;

	    chan = ((to_type == CHANX) ? tr_j : tr_i);
	    seg = ((to_type == CHANX) ? tr_i : tr_j);

	    /* Don't connect where no tracks on fringes */
	    if((tr_i < 0) || (tr_i > nx))
		{
		    continue;
		}
	    if((tr_j < 0) || (tr_j > ny))
		{
		    continue;
		}
	    if((CHANX == to_type) && (tr_i < 1))
		{
		    continue;
		}
	    if((CHANY == to_type) && (tr_j < 1))
		{
		    continue;
		}

		is_connected_track = FALSE;

	    /* Itterate of the opin to track connections */
	    for(iconn = 0; iconn < Fc; ++iconn)
		{
		    to_track =
			opin_to_track_map[type->
					  index][ipin][ofs][iside][iconn];

		    /* Skip unconnected connections */
		    if(OPEN == to_track || is_connected_track)
			{
				is_connected_track = TRUE;
			    assert(OPEN ==
				   opin_to_track_map[type->
						     index][ipin][ofs][iside]
				   [0]);
			    continue;
			}

		    /* Only connect to wire if there is a CB */
		    if(is_cbox
		       (chan, seg, to_track, seg_details, BI_DIRECTIONAL))
			{
			    to_switch = seg_details[to_track].wire_switch;
			    to_node =
				get_rr_node_index(tr_i, tr_j, to_type,
						  to_track, rr_node_indices);

			    *edge_list =
				insert_in_edge_list(*edge_list, to_node,
						    to_switch);
			    rr_edge_done[to_node] = TRUE;
			    ++num_conn;
			}
		}
	}

    return num_conn;
}



int
get_unidir_opin_connections(IN int chan,
			    IN int seg,
			    IN int Fc,
			    IN t_rr_type chan_type,
			    IN t_seg_details * seg_details,
			    INOUT t_linked_edge ** edge_list_ptr,
			    INOUT int **Fc_ofs,
			    INOUT boolean * rr_edge_done,
			    IN int max_len,
			    IN int nodes_per_chan,
			    IN t_ivec *** rr_node_indices,
			    OUT boolean * Fc_clipped)
{
    /* Gets a linked list of Fc nodes to connect to in given
     * chan seg.  Fc_ofs is used for the for the opin staggering
     * pattern. */

    int *inc_muxes = NULL;
    int *dec_muxes = NULL;
    int num_inc_muxes, num_dec_muxes, iconn;
    int inc_inode, dec_inode;
    int inc_mux, dec_mux;
    int inc_track, dec_track;
    int x, y;
    int num_edges;

    *Fc_clipped = FALSE;

    /* Fc is assigned in pairs so check it is even. */
    assert(Fc % 2 == 0);

    /* get_rr_node_indices needs x and y coords. */
    x = ((CHANX == chan_type) ? seg : chan);
    y = ((CHANX == chan_type) ? chan : seg);

    /* Get the lists of possible muxes. */
    inc_muxes = label_wire_muxes(chan, seg, seg_details, max_len,
				 INC_DIRECTION, nodes_per_chan,
				 &num_inc_muxes);
    dec_muxes =
	label_wire_muxes(chan, seg, seg_details, max_len, DEC_DIRECTION,
			 nodes_per_chan, &num_dec_muxes);

    /* Clip Fc to the number of muxes. */
    if(((Fc / 2) > num_inc_muxes) || ((Fc / 2) > num_dec_muxes))
	{
	    *Fc_clipped = TRUE;
	    Fc = 2 * min(num_inc_muxes, num_dec_muxes);
	}

    /* Assign tracks to meet Fc demand */
    num_edges = 0;
    for(iconn = 0; iconn < (Fc / 2); ++iconn)
	{
	    /* Figure of the next mux to use */
	    inc_mux = Fc_ofs[chan][seg] % num_inc_muxes;
	    dec_mux = Fc_ofs[chan][seg] % num_dec_muxes;
	    ++Fc_ofs[chan][seg];

	    /* Figure out the track it corresponds to. */
	    inc_track = inc_muxes[inc_mux];
	    dec_track = dec_muxes[dec_mux];

	    /* Figure the inodes of those muxes */
	    inc_inode =
		get_rr_node_index(x, y, chan_type, inc_track,
				  rr_node_indices);
	    dec_inode =
		get_rr_node_index(x, y, chan_type, dec_track,
				  rr_node_indices);

	    /* Add to the list. */
	    if(FALSE == rr_edge_done[inc_inode])
		{
		    rr_edge_done[inc_inode] = TRUE;
		    *edge_list_ptr = insert_in_edge_list(*edge_list_ptr,
							 inc_inode,
							 seg_details
							 [inc_track].
							 opin_switch);
		    ++num_edges;
		}
	    if(FALSE == rr_edge_done[dec_inode])
		{
		    rr_edge_done[dec_inode] = TRUE;
		    *edge_list_ptr = insert_in_edge_list(*edge_list_ptr,
							 dec_inode,
							 seg_details
							 [dec_track].
							 opin_switch);
		    ++num_edges;
		}
	}

    if(inc_muxes)
	{
	    free(inc_muxes);
	    inc_muxes = NULL;
	}
    if(dec_muxes)
	{
	    free(dec_muxes);
	    dec_muxes = NULL;
	}

    return num_edges;
}

boolean
is_cbox(IN int chan,
	IN int seg,
	IN int track,
	IN t_seg_details * seg_details,
	IN enum e_directionality directionality)
{

    int start, length, ofs, fac, start_seg;

    fac = 1;
    if(UNI_DIRECTIONAL == directionality)
	{
	    fac = 2;
	}

    start = seg_details[track].start;
    length = seg_details[track].length;

    /* Make sure they gave us correct start */
    start_seg = get_seg_start(seg_details, track, chan, seg);

    ofs = seg - start_seg;

    assert(ofs >= 0);
    assert(ofs < length);

    /* If unidir segment that is going backwards, we need to flip the ofs */
    if(DEC_DIRECTION == seg_details[track].direction)
	{
	    ofs = (length - 1) - ofs;
	}

    return seg_details[track].cb[ofs];
}


static void
load_chan_rr_indices(IN int nodes_per_chan,
		     IN int chan_len,
		     IN int num_chans,
		     IN t_rr_type type,
		     IN t_seg_details * seg_details,
		     INOUT int *index,
		     INOUT t_ivec *** indices)
{
    int chan, seg, track, start, inode;

    indices[type] = (t_ivec **) my_malloc(sizeof(t_ivec *) * num_chans);
    for(chan = 0; chan < num_chans; ++chan)
	{
	    indices[type][chan] =
		(t_ivec *) my_malloc(sizeof(t_ivec) * chan_len);

	    indices[type][chan][0].nelem = 0;
	    indices[type][chan][0].list = NULL;

	    for(seg = 1; seg < chan_len; ++seg)
		{
		    /* Alloc the track inode lookup list */
		    indices[type][chan][seg].nelem = nodes_per_chan;
		    indices[type][chan][seg].list =
			(int *)my_malloc(sizeof(int) * nodes_per_chan);
		    for(track = 0; track < nodes_per_chan; ++track)
			{
			    indices[type][chan][seg].list[track] = OPEN;
			}
		}
	}

    for(chan = 0; chan < num_chans; ++chan)
	{
	    for(seg = 1; seg < chan_len; ++seg)
		{
		    /* Assign an inode to the starts of tracks */
		    for(track = 0; track < indices[type][chan][seg].nelem;
			++track)
			{
			    start =
				get_seg_start(seg_details, track, chan, seg);

			    /* If the start of the wire doesn't have a inode, 
			     * assign one to it. */
			    inode = indices[type][chan][start].list[track];
			    if(OPEN == inode)
				{
				    inode = *index;
				    ++(*index);

				    indices[type][chan][start].list[track] =
					inode;
				}

			    /* Assign inode of start of wire to current position */
			    indices[type][chan][seg].list[track] = inode;
			}
		}
	}
}


struct s_ivec ***
alloc_and_load_rr_node_indices(IN int nodes_per_chan,
			       IN int nx,
			       IN int ny,
			       INOUT int *index,
			       IN t_seg_details * seg_details)
{

    /* Allocates and loads all the structures needed for fast lookups of the   *
     * index of an rr_node.  rr_node_indices is a matrix containing the index  *
     * of the *first* rr_node at a given (i,j) location.                       */

    int i, j, k, ofs;
    t_ivec ***indices;
    t_ivec tmp;
    t_type_ptr type;

    /* Alloc the lookup table */
    indices = (t_ivec ***) my_malloc(sizeof(t_ivec **) * NUM_RR_TYPES);
    indices[IPIN] = (t_ivec **) my_malloc(sizeof(t_ivec *) * (nx + 2));
    indices[SINK] = (t_ivec **) my_malloc(sizeof(t_ivec *) * (nx + 2));
    for(i = 0; i <= (nx + 1); ++i)
	{
	    indices[IPIN][i] =
		(t_ivec *) my_malloc(sizeof(t_ivec) * (ny + 2));
	    indices[SINK][i] =
		(t_ivec *) my_malloc(sizeof(t_ivec) * (ny + 2));
	    for(j = 0; j <= (ny + 1); ++j)
		{
		    indices[IPIN][i][j].nelem = 0;
		    indices[IPIN][i][j].list = NULL;

		    indices[SINK][i][j].nelem = 0;
		    indices[SINK][i][j].list = NULL;
		}
	}


    /* Count indices for block nodes */
    for(i = 0; i <= (nx + 1); i++)
	{
	    for(j = 0; j <= (ny + 1); j++)
		{
		    ofs = grid[i][j].offset;
		    if(0 == ofs)
			{
			    type = grid[i][j].type;

			    /* Load the pin class lookups. The ptc nums for SINK and SOURCE
			     * are disjoint so they can share the list. */
			    tmp.nelem = type->num_class;
			    tmp.list = NULL;
			    if(tmp.nelem > 0)
				{
				    tmp.list =
					(int *)my_malloc(sizeof(int) *
							 tmp.nelem);
				    for(k = 0; k < tmp.nelem; ++k)
					{
					    tmp.list[k] = *index;
					    ++(*index);
					}
				}
			    indices[SINK][i][j] = tmp;

			    /* Load the pin lookups. The ptc nums for IPIN and OPIN
			     * are disjoint so they can share the list. */
			    tmp.nelem = type->num_pins;
			    tmp.list = NULL;
			    if(tmp.nelem > 0)
				{
				    tmp.list =
					(int *)my_malloc(sizeof(int) *
							 tmp.nelem);
				    for(k = 0; k < tmp.nelem; ++k)
					{
					    tmp.list[k] = *index;
					    ++(*index);
					}
				}
			    indices[IPIN][i][j] = tmp;
			}
		}
	}

    /* Point offset blocks of a large block to base block */
    for(i = 0; i <= (nx + 1); i++)
	{
	    for(j = 0; j <= (ny + 1); j++)
		{
		    ofs = grid[i][j].offset;
		    if(ofs > 0)
			{
			    /* NOTE: this only supports vertical large blocks */
			    indices[SINK][i][j] = indices[SINK][i][j - ofs];
			    indices[IPIN][i][j] = indices[IPIN][i][j - ofs];
			}
		}
	}

    /* SOURCE and SINK have unique ptc values so their data can be shared.
     * IPIN and OPIN have unique ptc values so their data can be shared. */
    indices[SOURCE] = indices[SINK];
    indices[OPIN] = indices[IPIN];

    /* Load the data for x and y channels */
    load_chan_rr_indices(nodes_per_chan, nx + 1, ny + 1, CHANX,
			 seg_details, index, indices);
    load_chan_rr_indices(nodes_per_chan, ny + 1, nx + 1, CHANY,
			 seg_details, index, indices);

    return indices;
}


void
free_rr_node_indices(IN t_ivec *** rr_node_indices)
{
	int i, j, ofs;
    /* This function must unallocate the structure allocated in 
     * alloc_and_load_rr_node_indices. */
	for(i = 0; i <= (nx + 1); ++i)
	{
		for(j = 0; j <= (ny + 1); ++j)
		{
			ofs = grid[i][j].offset;
		    if(ofs > 0)
			{
			    /* Vertical large blocks reference is same as offset 0 */
			    rr_node_indices[SINK][i][j].list = NULL;
				rr_node_indices[IPIN][i][j].list = NULL;
				continue;
			}
			if(rr_node_indices[SINK][i][j].list != NULL) {
				free(rr_node_indices[SINK][i][j].list);
			}
			if(rr_node_indices[IPIN][i][j].list != NULL) {
				free(rr_node_indices[IPIN][i][j].list);
			}
		}
		free(rr_node_indices[SINK][i]);
		free(rr_node_indices[IPIN][i]);
	}
	free(rr_node_indices[SINK]);
	free(rr_node_indices[IPIN]);

	for(i = 0; i < (nx + 1); ++i)
	{
		for(j = 0; j < (ny + 1); ++j)
		{
			if(rr_node_indices[CHANY][i][j].list != NULL) {
				free(rr_node_indices[CHANY][i][j].list);
			}
		}
		free(rr_node_indices[CHANY][i]);
	}
	free(rr_node_indices[CHANY]);

	for(i = 0; i < (ny + 1); ++i)
	{
		for(j = 0; j < (nx + 1); ++j)
		{
			if(rr_node_indices[CHANX][i][j].list != NULL) {
				free(rr_node_indices[CHANX][i][j].list);
			}
		}
		free(rr_node_indices[CHANX][i]);
	}
	free(rr_node_indices[CHANX]);

	free(rr_node_indices);
}


int
get_rr_node_index(int x,
		  int y,
		  t_rr_type rr_type,
		  int ptc,
		  t_ivec *** rr_node_indices)
{
    /* Returns the index of the specified routing resource node.  (x,y) are     *
     * the location within the FPGA, rr_type specifies the type of resource,    *
     * and ptc gives the number of this resource.  ptc is the class number,   *
     * pin number or track number, depending on what type of resource this      *
     * is.  All ptcs start at 0 and go up to pins_per_clb-1 or the equivalent. *
     * The order within a clb is:  SOURCEs + SINKs (type->num_class of them); IPINs,  *
     * and OPINs (pins_per_clb of them); CHANX; and CHANY (nodes_per_chan of    *
     * each).  For (x,y) locations that point at pads the order is:  type->capacity     *
     * occurances of SOURCE, SINK, OPIN, IPIN (one for each pad), then one      *
     * associated channel (if there is a channel at (x,y)).  All IO pads are    *
     * bidirectional, so while each will be used only as an INPAD or as an      *
     * OUTPAD, all the switches necessary to do both must be in each pad.       *
     *                                                                          *
     * Note that for segments (CHANX and CHANY) of length > 1, the segment is   *
     * given an rr_index based on the (x,y) location at which it starts (i.e.   *
     * lowest (x,y) location at which this segment exists).                     *
     * This routine also performs error checking to make sure the node in       *
     * question exists.                                                         */

    int iclass, tmp;
    t_type_ptr type;
    t_ivec lookup;

    assert(ptc >= 0);
    assert(x >= 0 && x <= (nx + 1));
    assert(y >= 0 && y <= (ny + 1));

    type = grid[x][y].type;

    /* Currently need to swap x and y for CHANX because of chan, seg convention */
    if(CHANX == rr_type)
	{
	    tmp = x;
	    x = y;
	    y = tmp;
	}

    /* Start of that block.  */
    lookup = rr_node_indices[rr_type][x][y];

    /* Check valid ptc num */
    assert(ptc >= 0);
    assert(ptc < lookup.nelem);

#ifdef DEBUG
    switch (rr_type)
	{
	case SOURCE:
	    assert(ptc < type->num_class);
	    assert(type->class_inf[ptc].type == DRIVER);
	    break;

	case SINK:
	    assert(ptc < type->num_class);
	    assert(type->class_inf[ptc].type == RECEIVER);
	    break;

	case OPIN:
	    assert(ptc < type->num_pins);
	    iclass = type->pin_class[ptc];
	    assert(type->class_inf[iclass].type == DRIVER);
	    break;

	case IPIN:
	    assert(ptc < type->num_pins);
	    iclass = type->pin_class[ptc];
	    assert(type->class_inf[iclass].type == RECEIVER);
	    break;

	case CHANX:
	case CHANY:
	    break;

	default:
	    printf("Error:  Bad rr_node passed to get_rr_node_index.\n"
		   "Request for type=%d ptc=%d at (%d, %d).\n",
		   rr_type, ptc, x, y);
	    exit(1);
	}
#endif

    return lookup.list[ptc];
}


int
get_track_to_ipins(int seg,
		   int chan,
		   int track,
		   t_linked_edge ** edge_list_ptr,
		   t_ivec *** rr_node_indices,
		   struct s_ivec ****track_to_ipin_lookup,
		   t_seg_details * seg_details,
		   enum e_rr_type chan_type,
		   int chan_length,
		   int wire_to_ipin_switch,
		   enum e_directionality directionality)
{

    /* This counts the fan-out from wire segment (chan, seg, track) to blocks on either side */

    t_linked_edge *edge_list_head;
    int j, pass, iconn, phy_track, end, to_node, max_conn, ipin, side, x,
	y, num_conn;
    t_type_ptr type;
    int off;

    /* End of this wire */
    end = get_seg_end(seg_details, track, seg, chan, chan_length);

    edge_list_head = *edge_list_ptr;
    num_conn = 0;

    for(j = seg; j <= end; j++)
	{
	    if(is_cbox(chan, j, track, seg_details, directionality))
		{
		    for(pass = 0; pass < 2; ++pass)
			{
			    if(CHANX == chan_type)
				{
				    x = j;
				    y = chan + pass;
				    side = (0 == pass ? TOP : BOTTOM);
				}
			    else
				{
				    assert(CHANY == chan_type);
				    x = chan + pass;
				    y = j;
				    side = (0 == pass ? RIGHT : LEFT);
				}

			    /* PAJ - if the pointed to is an EMPTY then shouldn't look for ipins */
			    if(grid[x][y].type == EMPTY_TYPE)
				continue;

			    /* Move from logical (straight) to physical (twisted) track index 
			     * - algorithm assigns ipin connections to same physical track index
			     * so that the logical track gets distributed uniformly */
			    phy_track =
				vpr_to_phy_track(track, chan, j, seg_details,
						 directionality);

			    /* We need the type to find the ipin map for this type */
			    type = grid[x][y].type;
			    off = grid[x][y].offset;

			    max_conn =
				track_to_ipin_lookup[type->
						     index][phy_track][off]
				[side].nelem;
			    for(iconn = 0; iconn < max_conn; iconn++)
				{
				    ipin =
					track_to_ipin_lookup[type->
							     index][phy_track]
					[off][side].list[iconn];

				    /* Check there is a connection and Fc map isn't wrong */
				    assert(type->pinloc[off][side][ipin]);
				    assert(type->is_global_pin[ipin] ==
					   FALSE);

				    to_node =
					get_rr_node_index(x, y, IPIN, ipin,
							  rr_node_indices);
				    edge_list_head =
					insert_in_edge_list(edge_list_head,
							    to_node,
							    wire_to_ipin_switch);
				}
			    num_conn += max_conn;
			}
		}
	}

    *edge_list_ptr = edge_list_head;
    return (num_conn);
}


/* Counts how many connections should be made from this segment to the y-   *
 * segments in the adjacent channels at to_j.  It returns the number of     *
 * connections, and updates edge_list_ptr to point at the head of the       *
 * (extended) linked list giving the nodes to which this segment connects   *
 * and the switch type used to connect to each.                             *
 *                                                                          *
 * An edge is added from this segment to a y-segment if:                    *
 * (1) this segment should have a switch box at that location, or           *
 * (2) the y-segment to which it would connect has a switch box, and the    *
 *     switch type of that y-segment is unbuffered (bidirectional pass      *
 *     transistor).                                                         *
 *                                                                          *
 * For bidirectional:                                                       *
 * If the switch in each direction is a pass transistor (unbuffered), both  *
 * switches are marked as being of the types of the larger (lower R) pass   *
 * transistor.                                                              */
int
get_track_to_tracks(IN int from_chan,
		    IN int from_seg,
		    IN int from_track,
		    IN t_rr_type from_type,
		    IN int to_seg,
		    IN t_rr_type to_type,
		    IN int chan_len,
		    IN int nodes_per_chan,
		    IN int *opin_mux_size,
		    IN int Fs_per_side,
		    IN short *****sblock_pattern,
		    INOUT struct s_linked_edge **edge_list,
		    IN t_seg_details * seg_details,
		    IN enum e_directionality directionality,
		    IN t_ivec *** rr_node_indices,
		    INOUT boolean * rr_edge_done,
		    IN struct s_ivec ***switch_block_conn)
{
    int num_conn;
    int from_switch, from_end, from_sb, from_first;
    int to_chan, to_sb;
    int start, end;
    struct s_ivec conn_tracks;
    boolean from_is_sbox, is_behind, Fs_clipped;
    enum e_side from_side_a, from_side_b, to_side;

    assert(from_seg ==
	   get_seg_start(seg_details, from_track, from_chan, from_seg));

    from_switch = seg_details[from_track].wire_switch;
    from_end =
	get_seg_end(seg_details, from_track, from_seg, from_chan, chan_len);
    from_first = from_seg - 1;

    /* Figure out the sides of SB the from_wire will use */
    if(CHANX == from_type)
	{
	    from_side_a = RIGHT;
	    from_side_b = LEFT;
	}
    else
	{
	    assert(CHANY == from_type);
	    from_side_a = TOP;
	    from_side_b = BOTTOM;
	}

    /* Figure out if the to_wire is connecting to a SB 
     * that is behind it. */
    is_behind = FALSE;
    if(to_type == from_type)
	{
	    /* If inline, check that they only are trying
	     * to connect at endpoints. */
	    assert((to_seg == (from_end + 1)) || (to_seg == (from_seg - 1)));
	    if(to_seg > from_end)
		{
		    is_behind = TRUE;
		}
	}
    else
	{
	    /* If bending, check that they are adjacent to
	     * our channel. */
	    assert((to_seg == from_chan) || (to_seg == (from_chan + 1)));
	    if(to_seg > from_chan)
		{
		    is_behind = TRUE;
		}
	}

    /* Figure out the side of SB the to_wires will use.
     * The to_seg and from_chan are in same direction. */
    if(CHANX == to_type)
	{
	    to_side = (is_behind ? RIGHT : LEFT);
	}
    else
	{
	    assert(CHANY == to_type);
	    to_side = (is_behind ? TOP : BOTTOM);
	}

    /* Set the loop bounds */
    start = from_first;
    end = from_end;

    /* If we are connecting in same direction the connection is 
     * on one of the two sides so clip the bounds to the SB of
     * interest and proceed normally. */
    if(to_type == from_type)
	{
	    start = (is_behind ? end : start);
	    end = start;
	}

    /* Iterate over the SBs */
    num_conn = 0;
    for(from_sb = start; from_sb <= end; ++from_sb)
	{
	    /* Figure out if we are at a sbox */
	    from_is_sbox = is_sbox(from_chan, from_seg, from_sb, from_track,
				   seg_details, directionality);
	    /* end of wire must be an sbox */
	    if(from_sb == from_end || from_sb == from_first)
		{
		    from_is_sbox = TRUE;	/* Endpoints always default to true */
		}

	    /* to_chan is the current segment if different directions,
	     * otherwise to_chan is the from_chan */
	    to_chan = from_sb;
	    to_sb = from_chan;
	    if(from_type == to_type)
		{
		    to_chan = from_chan;
		    to_sb = from_sb;
		}

	    /* Do the edges going to the left or down */
	    if(from_sb < from_end)
		{
		    if(BI_DIRECTIONAL == directionality)
			{
			    conn_tracks =
				switch_block_conn[from_side_a][to_side]
				[from_track];
			    num_conn +=
				get_bidir_track_to_chan_seg(conn_tracks,
							    rr_node_indices,
							    to_chan, to_seg,
							    to_sb, to_type,
							    seg_details,
							    from_is_sbox,
							    from_switch,
							    rr_edge_done,
							    directionality,
							    edge_list);
			}
		    if(UNI_DIRECTIONAL == directionality)
			{
			    /* No fanout if no SB. */
			    /* We are connecting from the top or right of SB so it
			     * makes the most sense to only there from DEC_DIRECTION wires. */
			    if((from_is_sbox) &&
			       (DEC_DIRECTION ==
				seg_details[from_track].direction))
				{
				    num_conn +=
					get_unidir_track_to_chan_seg((from_sb
								      ==
								      from_first),
								     from_track,
								     to_chan,
								     to_seg,
								     to_sb,
								     to_type,
								     nodes_per_chan,
								     nx, ny,
								     from_side_a,
								     to_side,
								     Fs_per_side,
								     opin_mux_size,
								     sblock_pattern,
								     rr_node_indices,
								     seg_details,
								     rr_edge_done,
								     &Fs_clipped,
								     edge_list);
				}
			}
		}

	    /* Do the edges going to the right or up */
	    if(from_sb > from_first)
		{
		    if(BI_DIRECTIONAL == directionality)
			{
			    conn_tracks =
				switch_block_conn[from_side_b][to_side]
				[from_track];
			    num_conn +=
				get_bidir_track_to_chan_seg(conn_tracks,
							    rr_node_indices,
							    to_chan, to_seg,
							    to_sb, to_type,
							    seg_details,
							    from_is_sbox,
							    from_switch,
							    rr_edge_done,
							    directionality,
							    edge_list);
			}
		    if(UNI_DIRECTIONAL == directionality)
			{
			    /* No fanout if no SB. */
			    /* We are connecting from the bottom or left of SB so it
			     * makes the most sense to only there from INC_DIRECTION wires. */
			    if((from_is_sbox) &&
			       (INC_DIRECTION ==
				seg_details[from_track].direction))
				{
				    num_conn +=
					get_unidir_track_to_chan_seg((from_sb
								      ==
								      from_end),
								     from_track,
								     to_chan,
								     to_seg,
								     to_sb,
								     to_type,
								     nodes_per_chan,
								     nx, ny,
								     from_side_b,
								     to_side,
								     Fs_per_side,
								     opin_mux_size,
								     sblock_pattern,
								     rr_node_indices,
								     seg_details,
								     rr_edge_done,
								     &Fs_clipped,
								     edge_list);
				}
			}
		}
	}

    return num_conn;
}



static int
get_bidir_track_to_chan_seg(IN struct s_ivec conn_tracks,
			    IN t_ivec *** rr_node_indices,
			    IN int to_chan,
			    IN int to_seg,
			    IN int to_sb,
			    IN t_rr_type to_type,
			    IN t_seg_details * seg_details,
			    IN boolean from_is_sbox,
			    IN int from_switch,
			    INOUT boolean * rr_edge_done,
			    IN enum e_directionality directionality,
			    INOUT struct s_linked_edge **edge_list)
{
    int iconn, to_track, to_node, to_switch, num_conn, to_x, to_y, i;
    boolean to_is_sbox;
    short switch_types[2];

    /* x, y coords for get_rr_node lookups */
    if(CHANX == to_type)
	{
	    to_x = to_seg;
	    to_y = to_chan;
	}
    else
	{
	    assert(CHANY == to_type);
	    to_x = to_chan;
	    to_y = to_seg;
	}

    /* Go through the list of tracks we can connect to */
    num_conn = 0;
    for(iconn = 0; iconn < conn_tracks.nelem; ++iconn)
	{
	    to_track = conn_tracks.list[iconn];
	    to_node = get_rr_node_index(to_x, to_y, to_type, to_track,
					rr_node_indices);

	    /* Skip edge if already done */
	    if(rr_edge_done[to_node])
		{
		    continue;
		}

	    /* Get the switches for any edges between the two tracks */
	    to_switch = seg_details[to_track].wire_switch;

	    to_is_sbox = is_sbox(to_chan, to_seg, to_sb, to_track,
				 seg_details, directionality);
	    get_switch_type(from_is_sbox, to_is_sbox,
			    from_switch, to_switch, switch_types);

	    /* There are up to two switch edges allowed from track to track */
	    for(i = 0; i < 2; ++i)
		{
		    /* If the switch_type entry is empty, skip it */
		    if(OPEN == switch_types[i])
			{
			    continue;
			}

		    /* Add the edge to the list */
		    *edge_list = insert_in_edge_list(*edge_list,
						     to_node,
						     switch_types[i]);
		    /* Mark the edge as now done */
		    rr_edge_done[to_node] = TRUE;
		    ++num_conn;
		}
	}

    return num_conn;
}

static int
get_unidir_track_to_chan_seg(IN boolean is_end_sb,
			     IN int from_track,
			     IN int to_chan,
			     IN int to_seg,
			     IN int to_sb,
			     IN t_rr_type to_type,
			     IN int nodes_per_chan,
			     IN int nx,
			     IN int ny,
			     IN enum e_side from_side,
			     IN enum e_side to_side,
			     IN int Fs_per_side,
			     IN int *opin_mux_size,
			     IN short *****sblock_pattern,
			     IN t_ivec *** rr_node_indices,
			     IN t_seg_details * seg_details,
			     INOUT boolean * rr_edge_done,
			     OUT boolean * Fs_clipped,
			     INOUT struct s_linked_edge **edge_list)
{
    int to_track, to_mux, to_node, to_x, to_y, i, max_len, num_labels;
    int sb_x, sb_y, count;
    int *mux_labels = NULL;
    enum e_direction to_dir;
    boolean is_fringe, is_core, is_corner, is_straight;

    /* x, y coords for get_rr_node lookups */
    if(CHANX == to_type)
	{
	    to_x = to_seg;
	    to_y = to_chan;
	    sb_x = to_sb;
	    sb_y = to_chan;
	    max_len = nx;
	}
    else
	{
	    assert(CHANY == to_type);
	    to_x = to_chan;
	    to_y = to_seg;
	    sb_x = to_chan;
	    sb_y = to_sb;
	    max_len = ny;
	}


    to_dir = DEC_DIRECTION;
    if(to_sb < to_seg)
	{
	    to_dir = INC_DIRECTION;
	}

    *Fs_clipped = FALSE;

    /* SBs go from (0, 0) to (nx, ny) */
    is_corner = ((sb_x < 1) || (sb_x >= nx)) && ((sb_y < 1) || (sb_y >= ny));
    is_fringe = (FALSE == is_corner) && ((sb_x < 1) || (sb_y < 1)
					 || (sb_x >= nx) || (sb_y >= ny));
    is_core = (FALSE == is_corner) && (FALSE == is_fringe);
    is_straight = (from_side == RIGHT && to_side == LEFT) ||
	(from_side == LEFT && to_side == RIGHT) ||
	(from_side == TOP && to_side == BOTTOM) ||
	(from_side == BOTTOM && to_side == TOP);

    /* Ending wires use N-to-N mapping if not fringe or if goes straight */
    if(is_end_sb && (is_core || is_corner || is_straight))
	{
	    /* Get the list of possible muxes for the N-to-N mapping. */
	    mux_labels = label_wire_muxes(to_chan, to_seg, seg_details,
					  max_len, to_dir, nodes_per_chan,
					  &num_labels);
	}
    else
	{
	    assert(is_fringe || !is_end_sb);

	    mux_labels = label_wire_muxes_for_balance(to_chan, to_seg,
						      seg_details, max_len,
						      to_dir, nodes_per_chan,
						      &num_labels, to_type,
						      opin_mux_size,
						      rr_node_indices);
	}

    /* Can't connect if no muxes. */
    if(num_labels < 1)
	{
	    if(mux_labels)
		{
		    free(mux_labels);
		    mux_labels = NULL;
		}
	    return 0;
	}

    /* Check if Fs demand was too high. */
    if(Fs_per_side > num_labels)
	{
	    *Fs_clipped = TRUE;
	}

    /* Get the target label */
    to_mux = sblock_pattern[sb_x][sb_y][from_side][to_side][from_track];
    assert(to_mux != UN_SET);

    /* Handle Fs > 3 but assigning consecutive muxes. */
    count = 0;
    for(i = 0; i < Fs_per_side; ++i)
	{
	    /* Use the balanced labeling for passing and fringe wires */
	    to_track = mux_labels[(to_mux + i) % num_labels];
	    to_node =
		get_rr_node_index(to_x, to_y, to_type, to_track,
				  rr_node_indices);

	    /* Add edge to list. */
	    if(FALSE == rr_edge_done[to_node])
		{
		    rr_edge_done[to_node] = TRUE;
		    *edge_list =
			insert_in_edge_list(*edge_list, to_node,
					    seg_details[to_track].
					    wire_switch);
		    ++count;
		}
	}

    if(mux_labels)
	{
	    free(mux_labels);
	    mux_labels = NULL;
	}

    return count;
}

boolean
is_sbox(IN int chan,
	IN int wire_seg,
	IN int sb_seg,
	IN int track,
	IN t_seg_details * seg_details,
	IN enum e_directionality directionality)
{

    int start, length, ofs, fac;

    fac = 1;
    if(UNI_DIRECTIONAL == directionality)
	{
	    fac = 2;
	}

    start = seg_details[track].start;
    length = seg_details[track].length;

    /* Make sure they gave us correct start */
    wire_seg = get_seg_start(seg_details, track, chan, wire_seg);

    ofs = sb_seg - wire_seg + 1;	/* Ofset 0 is behind us, so add 1 */

    assert(ofs >= 0);
    assert(ofs < (length + 1));

    /* If unidir segment that is going backwards, we need to flip the ofs */
    if((ofs % fac) > 0)
	{
	    ofs = length - ofs;
	}

    return seg_details[track].sb[ofs];
}



static void
get_switch_type(boolean is_from_sbox,
		boolean is_to_sbox,
		short from_node_switch,
		short to_node_switch,
		short switch_types[2])
{
    /* This routine looks at whether the from_node and to_node want a switch,  *
     * and what type of switch is used to connect *to* each type of node       *
     * (from_node_switch and to_node_switch).  It decides what type of switch, *
     * if any, should be used to go from from_node to to_node.  If no switch   *
     * should be inserted (i.e. no connection), it returns OPEN.  Its returned *
     * values are in the switch_types array.  It needs to return an array      *
     * because one topology (a buffer in the forward direction and a pass      *
     * transistor in the backward direction) results in *two* switches.        */

    boolean forward_pass_trans;
    boolean backward_pass_trans;
    int used, min, max;

    switch_types[0] = OPEN;	/* No switch */
    switch_types[1] = OPEN;
    used = 0;
    forward_pass_trans = FALSE;
    backward_pass_trans = FALSE;

    /* Connect forward if we are a sbox */
    if(is_from_sbox)
	{
	    switch_types[used] = to_node_switch;
	    if(FALSE == switch_inf[to_node_switch].buffered)
		{
		    forward_pass_trans = TRUE;
		}
	    ++used;
	}

    /* Check for pass_trans coming backwards */
    if(is_to_sbox)
	{
	    if(FALSE == switch_inf[from_node_switch].buffered)
		{
		    switch_types[used] = from_node_switch;
		    backward_pass_trans = TRUE;
		    ++used;
		}
	}

    /* Take the larger pass trans if there are two */
    if(forward_pass_trans && backward_pass_trans)
	{
	    min = min(to_node_switch, from_node_switch);
	    max = max(to_node_switch, from_node_switch);

	    /* Take the smaller index unless the other 
	     * pass_trans is bigger (smaller R). */
	    switch_types[used] = min;
	    if(switch_inf[max].R < switch_inf[min].R)
		{
		    switch_types[used] = max;
		}
	    ++used;
	}
}

static int
vpr_to_phy_track(IN int itrack,
		 IN int chan_num,
		 IN int seg_num,
		 IN t_seg_details * seg_details,
		 IN enum e_directionality directionality)
{
    int group_start, group_size;
    int vpr_offset_for_first_phy_track;
    int vpr_offset, phy_offset;
    int phy_track;
    int fac;

    /* Assign in pairs if unidir. */
    fac = 1;
    if(UNI_DIRECTIONAL == directionality)
	{
	    fac = 2;
	}

    group_start = seg_details[itrack].group_start;
    group_size = seg_details[itrack].group_size;

    vpr_offset_for_first_phy_track =
	(chan_num + seg_num - 1) % (group_size / fac);
    vpr_offset = (itrack - group_start) / fac;
    phy_offset =
	(vpr_offset_for_first_phy_track + vpr_offset) % (group_size / fac);
    phy_track =
	group_start + (fac * phy_offset) + (itrack - group_start) % fac;

    return phy_track;
}



short *****
alloc_sblock_pattern_lookup(IN int nx,
			    IN int ny,
			    IN int nodes_per_chan)
{
    int i, j, from_side, to_side, itrack, items;
    short *****result;
    short *****i_list;
    short ****j_list;
    short ***from_list;
    short **to_list;
    short *track_list;

    /* loading up the sblock connection pattern matrix. It's a huge matrix because
     * for nonquantized W, it's impossible to make simple permutations to figure out
     * where muxes are and how to connect to them such that their sizes are balanced */

    /* Do chunked allocations to make freeing easier, speed up malloc and free, and
     * reduce some of the memory overhead. Could use fewer malloc's but this way
     * avoids all considerations of pointer sizes and allignment. */

    /* Alloc each list of pointers in one go. items is a running product that increases
     * with each new dimension of the matrix. */
    items = 1;
    items *= (nx + 1);
    i_list = (short *****)my_malloc(sizeof(short ****) * items);
    items *= (ny + 1);
    j_list = (short ****)my_malloc(sizeof(short ***) * items);
    items *= (4);
    from_list = (short ***)my_malloc(sizeof(short **) * items);
    items *= (4);
    to_list = (short **)my_malloc(sizeof(short *) * items);
    items *= (nodes_per_chan);
    track_list = (short *)my_malloc(sizeof(short) * items);

    /* Build the pointer lists to form the multidimensional array */
    result = i_list;
    i_list += (nx + 1);		/* Skip forward nx+1 items */
    for(i = 0; i < (nx + 1); ++i)
	{

	    result[i] = j_list;
	    j_list += (ny + 1);	/* Skip forward ny+1 items */
	    for(j = 0; j < (ny + 1); ++j)
		{

		    result[i][j] = from_list;
		    from_list += (4);	/* Skip forward 4 items */
		    for(from_side = 0; from_side < 4; ++from_side)
			{

			    result[i][j][from_side] = to_list;
			    to_list += (4);	/* Skip forward 4 items */
			    for(to_side = 0; to_side < 4; ++to_side)
				{

				    result[i][j][from_side][to_side] =
					track_list;
				    track_list += (nodes_per_chan);	/* Skip forward nodes_per_chan items */
				    for(itrack = 0; itrack < nodes_per_chan;
					itrack++)
					{

					    /* Set initial value to be unset */
					    result[i][j][from_side][to_side]
						[itrack] = UN_SET;
					}
				}
			}
		}
	}

    /* This is the outer pointer to the full matrix */
    return result;
}


void
free_sblock_pattern_lookup(INOUT short *****sblock_pattern)
{
    /* This free function corresponds to the chunked matrix 
     * allocation above and there should only be one free
     * call for each dimension. */

    /* Free dimensions from the inner one, outwards so
     * we can still access them. The comments beside
     * each one indicate the corresponding name used when
     * allocating them. */
    free(****sblock_pattern);	/* track_list */
    free(***sblock_pattern);	/* to_list */
    free(**sblock_pattern);	/* from_list */
    free(*sblock_pattern);	/* j_list */
    free(sblock_pattern);	/* i_list */
}


void
load_sblock_pattern_lookup(IN int i,
			   IN int j,
			   IN int nodes_per_chan,
			   IN t_seg_details * seg_details,
			   IN int Fs,
			   IN enum e_switch_block_type switch_block_type,
			   INOUT short *****sblock_pattern)
{

    /* This routine loads a lookup table for sblock topology. The lookup table is huge
     * because the sblock varies from location to location. The i, j means the owning
     * location of the sblock under investigation. */

    int side_cw_incoming_wire_count, side_ccw_incoming_wire_count,
	opp_incoming_wire_count;
    int to_side, side, side_cw, side_ccw, side_opp, itrack;
    int Fs_per_side, chan, seg, chan_len, sb_seg;
    boolean is_core_sblock, is_corner_sblock, x_edge, y_edge;
    int *incoming_wire_label[4];
    int *wire_mux_on_track[4];
    int num_incoming_wires[4];
    int num_ending_wires[4];
    int num_wire_muxes[4];
    boolean skip, vert, pos_dir;
    enum e_direction dir;

    Fs_per_side = 1;
    if(Fs != -1)
	{
	    Fs_per_side = Fs / 3;
	}

    /* SB's have coords from (0, 0) to (nx, ny) */
    assert(i >= 0);
    assert(i <= nx);
    assert(j >= 0);
    assert(j <= ny);

    /* May 12 - 15, 2007
     *
     * I identify three types of sblocks in the chip: 1) The core sblock, whose special
     * property is that the number of muxes (and ending wires) on each side is the same (very useful
     * property, since it leads to a N-to-N assignment problem with ending wires). 2) The corner sblock
     * which is same as a L=1 core sblock with 2 sides only (again N-to-N assignment problem). 3) The
     * fringe / chip edge sblock which is most troublesome, as balance in each side of muxes is 
     * attainable but balance in the entire sblock is not. The following code first identifies the
     * incoming wires, which can be classified into incoming passing wires with sbox and incoming
     * ending wires (the word "incoming" is sometimes dropped for ease of discussion). It appropriately 
     * labels all the wires on each side by the following order: By the call to label_incoming_wires, 
     * which labels for one side, the order is such that the incoming ending wires (always with sbox) 
     * are labelled first 0,1,2,... p-1, then the incoming passing wires with sbox are labelled 
     * p,p+1,p+2,... k-1 (for total of k). By this convention, one can easily distinguish the ending
     * wires from the passing wires by checking a label against num_ending_wires variable. 
     *
     * After labelling all the incoming wires, this routine labels the muxes on the side we're currently
     * connecting to (iterated for four sides of the sblock), called the to_side. The label scheme is
     * the natural order of the muxes by their track #. Also we find the number of muxes.
     *
     * For each to_side, the total incoming wires that connect to the muxes on to_side 
     * come from three sides: side_1 (to_side's right), side_2 (to_side's left) and opp_side.
     * The problem of balancing mux size is then: considering all incoming passing wires
     * with sbox on side_1, side_2 and opp_side, how to assign them to the muxes on to_side
     * (with specified Fs) in a way that mux size is imbalanced by at most 1. I solve this
     * problem by this approach: the first incoming passing wire will connect to 0, 1, 2, 
     * ..., Fs_per_side - 1, then the next incoming passing wire will connect to 
     * Fs_per_side, Fs_per_side+1, ..., Fs_per_side*2-1, and so on. This consistent STAGGERING
     * ensures N-to-N assignment is perfectly balanced and M-to-N assignment is imbalanced by no
     * more than 1.
     *
     * For the sblock_pattern_init_mux_lookup lookup table, I will only need the lookup
     * table to remember the first/init mux to connect, since the convention is Fs_per_side consecutive
     * muxes to connect. Then how do I determine the order of the incoming wires? I use the labels
     * on side_1, then labels on side_2, then labels on opp_side. Effectively I listed all
     * incoming passing wires from the three sides, and order them to each make Fs_per_side
     * consecutive connections to muxes, and use % to rotate to keep imbalance at most 1. 
     */

    /* SB's range from (0, 0) to (nx, ny) */
    /* First find all four sides' incoming wires */
    x_edge = ((i < 1) || (i >= nx));
    y_edge = ((j < 1) || (j >= ny));

    is_corner_sblock = (x_edge && y_edge);
    is_core_sblock = (!x_edge && !y_edge);

    /* "Label" the wires around the switch block by connectivity. */
    for(side = 0; side < 4; ++side)
	{
	    /* Assume the channel segment doesn't exist. */
	    wire_mux_on_track[side] = NULL;
	    incoming_wire_label[side] = NULL;
	    num_incoming_wires[side] = 0;
	    num_ending_wires[side] = 0;
	    num_wire_muxes[side] = 0;

	    /* Skip the side and leave the zero'd value if the
	     * channel segment doesn't exist. */
	    skip = TRUE;
	    switch (side)
		{
		case TOP:
		    if(j < ny)
			{
			    skip = FALSE;
			};
		    break;
		case RIGHT:
		    if(i < nx)
			{
			    skip = FALSE;
			}
		    break;
		case BOTTOM:
		    if(j > 0)
			{
			    skip = FALSE;
			}
		    break;
		case LEFT:
		    if(i > 0)
			{
			    skip = FALSE;
			}
		    break;
		}
	    if(skip)
		{
		    continue;
		}

	    /* Figure out the channel and segment for a certain direction */
	    vert = ((side == TOP) || (side == BOTTOM));
	    pos_dir = ((side == TOP) || (side == RIGHT));
	    chan = (vert ? i : j);
	    sb_seg = (vert ? j : i);
	    seg = (pos_dir ? (sb_seg + 1) : sb_seg);
	    chan_len = (vert ? ny : nx);

	    /* Figure out all the tracks on a side that are ending and the
	     * ones that are passing through and have a SB. */
	    dir = (pos_dir ? DEC_DIRECTION : INC_DIRECTION);
	    incoming_wire_label[side] =
		label_incoming_wires(chan, seg, sb_seg, seg_details, chan_len,
				     dir, nodes_per_chan,
				     &num_incoming_wires[side],
				     &num_ending_wires[side]);

	    /* Figure out all the tracks on a side that are starting. */
	    dir = (pos_dir ? INC_DIRECTION : DEC_DIRECTION);
	    wire_mux_on_track[side] = label_wire_muxes(chan, seg,
						       seg_details, chan_len,
						       dir, nodes_per_chan,
						       &num_wire_muxes[side]);
	}

    for(to_side = 0; to_side < 4; to_side++)
	{
	    /* Can't do anything if no muxes on this side. */
	    if(0 == num_wire_muxes[to_side])
		{
		    continue;
		}

	    /* Figure out side rotations */
	    assert((TOP == 0) && (RIGHT == 1) && (BOTTOM == 2)
		   && (LEFT == 3));
	    side_cw = (to_side + 1) % 4;
	    side_opp = (to_side + 2) % 4;
	    side_ccw = (to_side + 3) % 4;

	    /* For the core sblock:
	     * The new order for passing wires should appear as
	     * 0,1,2..,scw-1, for passing wires with sbox on side_cw 
	     * scw,scw+1,...,sccw-1, for passing wires with sbox on side_ccw
	     * sccw,sccw+1,... for passing wires with sbox on side_opp.
	     * This way, I can keep the imbalance to at most 1.
	     *
	     * For the fringe sblocks, I don't distinguish between
	     * passing and ending wires so the above statement still holds
	     * if you replace "passing" by "incoming" */

	    side_cw_incoming_wire_count = 0;
	    if(incoming_wire_label[side_cw])
		{
		    for(itrack = 0; itrack < nodes_per_chan; itrack++)
			{
			    /* Ending wire, or passing wire with sbox. */
			    if(incoming_wire_label[side_cw][itrack] != UN_SET)
				{

				    if((is_corner_sblock || is_core_sblock) &&
				       (incoming_wire_label[side_cw][itrack] <
					num_ending_wires[side_cw]))
					{
					    /* The ending wires in core sblocks form N-to-N assignment 
					     * problem, so can use any pattern such as Wilton. This N-to-N 
					     * mapping depends on the fact that start points stagger across
					     * channels. */
					    assert(num_ending_wires[side_cw]
						   ==
						   num_wire_muxes[to_side]);
					    sblock_pattern[i][j][side_cw]
						[to_side][itrack] =
						get_simple_switch_block_track
						(side_cw, to_side,
						 incoming_wire_label[side_cw]
						 [itrack], switch_block_type,
						 num_wire_muxes[to_side]);

					}
				    else
					{

					    /* These are passing wires with sbox only for core sblocks
					     * or passing and ending wires (for fringe cases). */
					    sblock_pattern[i][j][side_cw]
						[to_side][itrack] =
						(side_cw_incoming_wire_count *
						 Fs_per_side) %
						num_wire_muxes[to_side];
					    side_cw_incoming_wire_count++;
					}
				}
			}
		}


	    side_ccw_incoming_wire_count = 0;
	    for(itrack = 0; itrack < nodes_per_chan; itrack++)
		{

		    /* if that side has no channel segment skip it */
		    if(incoming_wire_label[side_ccw] == NULL)
			break;

		    /* not ending wire nor passing wire with sbox */
		    if(incoming_wire_label[side_ccw][itrack] != UN_SET)
			{

			    if((is_corner_sblock || is_core_sblock) &&
			       (incoming_wire_label[side_ccw][itrack] <
				num_ending_wires[side_ccw]))
				{
				    /* The ending wires in core sblocks form N-to-N assignment problem, so can
				     * use any pattern such as Wilton */
				    assert(incoming_wire_label[side_ccw]
					   [itrack] <
					   num_wire_muxes[to_side]);
				    sblock_pattern[i][j][side_ccw][to_side]
					[itrack] =
					get_simple_switch_block_track
					(side_ccw, to_side,
					 incoming_wire_label[side_ccw]
					 [itrack], switch_block_type,
					 num_wire_muxes[to_side]);
				}
			    else
				{

				    /* These are passing wires with sbox only for core sblocks
				     * or passing and ending wires (for fringe cases). */
				    sblock_pattern[i][j][side_ccw][to_side]
					[itrack] =
					((side_ccw_incoming_wire_count +
					  side_cw_incoming_wire_count) *
					 Fs_per_side) %
					num_wire_muxes[to_side];
				    side_ccw_incoming_wire_count++;
				}
			}
		}


	    opp_incoming_wire_count = 0;
	    if(incoming_wire_label[side_opp])
		{
		    for(itrack = 0; itrack < nodes_per_chan; itrack++)
			{
			    /* not ending wire nor passing wire with sbox */
			    if(incoming_wire_label[side_opp][itrack] !=
			       UN_SET)
				{

				    /* corner sblocks for sure have no opposite channel segments so don't care about them */
				    if(is_core_sblock)
					{
					    if(incoming_wire_label[side_opp]
					       [itrack] <
					       num_ending_wires[side_opp])
						{
						    /* The ending wires in core sblocks form N-to-N assignment problem, so can
						     * use any pattern such as Wilton */
						    /* In the direct connect case, I know for sure the init mux is at the same track #
						     * as this ending wire, but still need to find the init mux label for Fs > 3 */
						    sblock_pattern[i][j]
							[side_opp][to_side]
							[itrack] =
							find_label_of_track
							(wire_mux_on_track
							 [to_side],
							 num_wire_muxes
							 [to_side], itrack);
						}
					    else
						{
						    /* These are passing wires with sbox for core sblocks */
						    sblock_pattern[i][j]
							[side_opp][to_side]
							[itrack] =
							((side_ccw_incoming_wire_count + side_cw_incoming_wire_count) * Fs_per_side + opp_incoming_wire_count * (Fs_per_side - 1)) % num_wire_muxes[to_side];
						    opp_incoming_wire_count++;
						}
					}
				    else
					{
					    if(incoming_wire_label[side_opp]
					       [itrack] <
					       num_ending_wires[side_opp])
						{
						    sblock_pattern[i][j]
							[side_opp][to_side]
							[itrack] =
							find_label_of_track
							(wire_mux_on_track
							 [to_side],
							 num_wire_muxes
							 [to_side], itrack);
						}
					    else
						{
						    /* These are passing wires with sbox for fringe sblocks */
						    sblock_pattern[i][j]
							[side_opp][to_side]
							[itrack] =
							((side_ccw_incoming_wire_count + side_cw_incoming_wire_count) * Fs_per_side + opp_incoming_wire_count * (Fs_per_side - 1)) % num_wire_muxes[to_side];
						    opp_incoming_wire_count++;
						}
					}
				}
			}
		}
	}

    for(side = 0; side < 4; ++side)
	{
	    if(incoming_wire_label[side])
		{
		    free(incoming_wire_label[side]);
		}
	    if(wire_mux_on_track[side])
		{
		    free(wire_mux_on_track[side]);
		}
	}
}

static int *
label_wire_muxes_for_balance(IN int chan_num,
			     IN int seg_num,
			     IN t_seg_details * seg_details,
			     IN int max_len,
			     IN enum e_direction direction,
			     IN int nodes_per_chan,
			     IN int *num_wire_muxes,
			     IN t_rr_type chan_type,
			     IN int *opin_mux_size,
			     IN t_ivec *** rr_node_indices)
{

    /* Labels the muxes on that side (seg_num, chan_num, direction). The returned array
     * maps a label to the actual track #: array[0] = <the track number of the first mux> */

    /* Sblock (aka wire2mux) pattern generation occurs after opin2mux connections have been 
     * made. Since opin2muxes are done with a pattern with which I guarantee imbalance of at most 1 due 
     * to them, we will observe that, for each side of an sblock some muxes have one fewer size 
     * than the others, considering only the contribution from opins. I refer to these muxes as "holes"
     * as they have one fewer opin connection going to them than the rest (like missing one electron)*/

    /* Before May 14, I was labelling wire muxes in the natural order of their track # (lowest first). 
     * Now I want to label wire muxes like this: first label the holes in order of their track #,
     * then label the non-holes in order of their track #. This way the wire2mux generation will 
     * not overlap its own "holes" with the opin "holes", thus creating imbalance greater than 1. */

    /* The best approach in sblock generation is do one assignment of all incoming wires from 3 other
     * sides to the muxes on the fourth side, connecting the "opin hole" muxes first (i.e. filling
     * the holes) then the rest -> this means after all opin2mux and wire2mux connections the 
     * mux size imbalance on one side is at most 1. The mux size imbalance in one sblock is thus
     * also one, since the number of muxes per side is identical for all four sides, and they number
     * of incoming wires per side is identical for full pop, and almost the same for depop (due to 
     * staggering) within +1 or -1. For different tiles (different sblocks) the imbalance is irrelevant,
     * since if the tiles are different in mux count then they have to be designed with a different
     * physical tile. */

    int num_labels, max_opin_mux_size, min_opin_mux_size;
    int inode, i, j, x, y;
    int *pre_labels, *final_labels;

	if (chan_type == CHANX){
		x = seg_num;
		y = chan_num;
	}
	else if (chan_type == CHANY){
		x = chan_num;
		y = seg_num;
	}
	else {
		printf("Error: Bad channel type (%d).\n", chan_type);
		exit(1);
	}

    /* Generate the normal labels list as the baseline. */
    pre_labels =
	label_wire_muxes(chan_num, seg_num, seg_details, max_len,
			 direction, nodes_per_chan, &num_labels);

    /* Find the min and max mux size. */
    min_opin_mux_size = MAX_SHORT;
    max_opin_mux_size = 0;
    for(i = 0; i < num_labels; ++i)
	{
	    inode = get_rr_node_index(x, y, chan_type, pre_labels[i],
				  rr_node_indices);
	    if(opin_mux_size[inode] < min_opin_mux_size)
		{
		    min_opin_mux_size = opin_mux_size[inode];
		}
	    if(opin_mux_size[inode] > max_opin_mux_size)
		{
		    max_opin_mux_size = opin_mux_size[inode];
		}
	}
    if(max_opin_mux_size > (min_opin_mux_size + 1))
	{
	    printf(ERRTAG "opin muxes are not balanced!\n");
		printf("max_opin_mux_size %d min_opin_mux_size %d chan_type %d x %d y %d\n", 
		max_opin_mux_size, min_opin_mux_size, chan_type, x, y);
	    exit(1);
	}
	
    /* Create a new list that we will move the muxes with 'holes' to the start of list. */
    final_labels = (int *)my_malloc(sizeof(int) * num_labels);
    j = 0;
    for(i = 0; i < num_labels; ++i)
	{
	    inode = pre_labels[i];
	    if(opin_mux_size[inode] < max_opin_mux_size)
		{
		    final_labels[j] = inode;
		    ++j;
		}
	}
    for(i = 0; i < num_labels; ++i)
	{
	    inode = pre_labels[i];
	    if(opin_mux_size[inode] >= max_opin_mux_size)
		{
		    final_labels[j] = inode;
		    ++j;
		}
	}

    /* Free the baseline labelling. */
    if(pre_labels)
	{
	    free(pre_labels);
	    pre_labels = NULL;
	}

    *num_wire_muxes = num_labels;
    return final_labels;
}


static int *
label_wire_muxes(IN int chan_num,
		 IN int seg_num,
		 IN t_seg_details * seg_details,
		 IN int max_len,
		 IN enum e_direction dir,
		 IN int nodes_per_chan,
		 OUT int *num_wire_muxes)
{

    /* Labels the muxes on that side (seg_num, chan_num, direction). The returned array
     * maps a label to the actual track #: array[0] = <the track number of the first/lowest mux> 
     * This routine orders wire muxes by their natural order, i.e. track # */

    int itrack, start, end, num_labels, pass;
    int *labels = NULL;
    boolean is_endpoint;

    /* COUNT pass then a LOAD pass */
    num_labels = 0;
    for(pass = 0; pass < 2; ++pass)
	{
	    /* Alloc the list on LOAD pass */
	    if(pass > 0)
		{
		    labels = (int *)my_malloc(sizeof(int) * num_labels);
		    num_labels = 0;
		}

	    /* Find the tracks that are starting. */
	    for(itrack = 0; itrack < nodes_per_chan; ++itrack)
		{
		    start =
			get_seg_start(seg_details, itrack, chan_num, seg_num);
		    end =
			get_seg_end(seg_details, itrack, start, chan_num,
				    max_len);

		    /* Skip tracks going the wrong way */
		    if(seg_details[itrack].direction != dir)
			{
			    continue;
			}

		    /* Determine if we are a wire startpoint */
		    is_endpoint = (seg_num == start);
		    if(DEC_DIRECTION == seg_details[itrack].direction)
			{
			    is_endpoint = (seg_num == end);
			}

		    /* Count the labels and load if LOAD pass */
		    if(is_endpoint)
			{
			    if(pass > 0)
				{
				    labels[num_labels] = itrack;
				}
			    ++num_labels;
			}
		}
	}

    *num_wire_muxes = num_labels;
    return labels;
}



static int *
label_incoming_wires(IN int chan_num,
		     IN int seg_num,
		     IN int sb_seg,
		     IN t_seg_details * seg_details,
		     IN int max_len,
		     IN enum e_direction dir,
		     IN int nodes_per_chan,
		     OUT int *num_incoming_wires,
		     OUT int *num_ending_wires)
{

    /* Labels the incoming wires on that side (seg_num, chan_num, direction). 
     * The returned array maps a track # to a label: array[0] = <the new hash value/label for track 0>,
     * the labels 0,1,2,.. identify consecutive incoming wires that have sbox (passing wires with sbox and ending wires) */

    int itrack, start, end, i, num_passing, num_ending, pass;
    int *labels;
    boolean sbox_exists, is_endpoint;

    /* Alloc the list of labels for the tracks */
    labels = (int *)my_malloc(nodes_per_chan * sizeof(int));
    for(i = 0; i < nodes_per_chan; ++i)
	{
	    labels[i] = UN_SET;	/* crash hard if unset */
	}

    num_ending = 0;
    num_passing = 0;
    for(pass = 0; pass < 2; ++pass)
	{
	    for(itrack = 0; itrack < nodes_per_chan; ++itrack)
		{
		    if(seg_details[itrack].direction == dir)
			{
			    start =
				get_seg_start(seg_details, itrack, chan_num,
					      seg_num);
			    end =
				get_seg_end(seg_details, itrack, start,
					    chan_num, max_len);

			    /* Determine if we are a wire endpoint */
			    is_endpoint = (seg_num == end);
			    if(DEC_DIRECTION == seg_details[itrack].direction)
				{
				    is_endpoint = (seg_num == start);
				}

			    /* Determine if we have a sbox on the wire */
			    sbox_exists = is_sbox(chan_num, seg_num, sb_seg,
						  itrack, seg_details,
						  UNI_DIRECTIONAL);

			    switch (pass)
				{
				    /* On first pass, only load ending wire labels. */
				case 0:
				    if(is_endpoint)
					{
					    labels[itrack] = num_ending;
					    ++num_ending;
					}
				    break;

				    /* On second pass, load the passing wire labels. They
				     * will follow after the ending wire labels. */
				case 1:
				    if((FALSE == is_endpoint) && sbox_exists)
					{
					    labels[itrack] =
						num_ending + num_passing;
					    ++num_passing;
					}
				    break;
				}
			}
		}
	}

    *num_incoming_wires = num_passing + num_ending;
    *num_ending_wires = num_ending;
    return labels;
}



static int
find_label_of_track(int *wire_mux_on_track,
		    int num_wire_muxes,
		    int from_track)
{
    int i, max_label, nearest_label, max_entry, nearest_entry;

    /* Returns the index/label in array wire_mux_on_track whose entry equals from_track. If none are
     * found, then returns the index of the entry whose value is the largest */

    max_label = nearest_label = max_entry = nearest_entry = -1;

    for(i = 0; i < num_wire_muxes; i++)
	{
	    if(wire_mux_on_track[i] == from_track)
		{
		    return i;	/* matched, return now */
		}
	}

    printf("Error: Expected mux not found.\n");
    exit(1);
}
