VPR-6.0

vpr/SRC/route/rr_graph_sbox.c File Reference

#include <assert.h>
#include "util.h"
#include "vpr_types.h"
#include "rr_graph_sbox.h"
#include "rr_graph_util.h"
Include dependency graph for rr_graph_sbox.c:

Go to the source code of this file.

Defines

#define SBOX_ERROR   -1

Functions

int get_simple_switch_block_track (INP enum e_side from_side, INP enum e_side to_side, INP int from_track, INP enum e_switch_block_type switch_block_type, INP int nodes_per_chan)
struct s_ivec *** alloc_and_load_switch_block_conn (INP int nodes_per_chan, INP enum e_switch_block_type switch_block_type, INP int Fs)
void free_switch_block_conn (struct s_ivec ***switch_block_conn, int nodes_per_chan)

Define Documentation

#define SBOX_ERROR   -1

Definition at line 135 of file rr_graph_sbox.c.


Function Documentation

struct s_ivec*** alloc_and_load_switch_block_conn ( INP int  nodes_per_chan,
INP enum e_switch_block_type  switch_block_type,
INP int  Fs 
) [read]

Allocates and loads the switch_block_conn data structure. This structure lists which tracks connect to which at each switch block. This is for bidir.

Definition at line 42 of file rr_graph_sbox.c.

{
    enum e_side from_side, to_side;
    int from_track;
    struct s_ivec ***switch_block_conn = NULL;

#ifdef CREATE_ECHO_FILES
    int i, j, k, l;
    FILE *out;
#endif /* CREATE_ECHO_FILES */

    /* Currently Fs must be 3 since each track maps once to each other side */
    assert(3 == Fs);

    switch_block_conn =
        (struct s_ivec ***)alloc_matrix3(0, 3,
                                         0, 3,
                                         0, (nodes_per_chan - 1),
                                         sizeof(struct s_ivec));

    for(from_side = 0; from_side < 4; from_side++)
        {
            for(to_side = 0; to_side < 4; to_side++)
                {
                    for(from_track = 0; from_track < nodes_per_chan;
                        from_track++)
                        {
                            if(from_side != to_side)
                                {
                                    switch_block_conn[from_side][to_side]
                                        [from_track].nelem = 1;
                                    switch_block_conn[from_side][to_side]
                                        [from_track].list =
                                        (int *)my_malloc(sizeof(int));

                                    switch_block_conn[from_side][to_side]
                                        [from_track].list[0] =
                                        get_simple_switch_block_track
                                        (from_side, to_side, from_track,
                                         switch_block_type, nodes_per_chan);
                                }
                            else
                                {       /* from_side == to_side -> no connection. */
                                    switch_block_conn[from_side][to_side]
                                        [from_track].nelem = 0;
                                    switch_block_conn[from_side][to_side]
                                        [from_track].list = NULL;
                                }
                        }
                }
        }

#ifdef CREATE_ECHO_FILES
    out = my_fopen("switch_block_conn.echo", "w", 0);
    for(l = 0; l < 4; ++l)
        {
            for(k = 0; k < 4; ++k)
                {
                    fprintf(out, "Side %d to %d\n", l, k);
                    for(j = 0; j < nodes_per_chan; ++j)
                        {
                            fprintf(out, "%d: ", j);
                            for(i = 0; i < switch_block_conn[l][k][j].nelem;
                                ++i)
                                {
                                    fprintf(out, "%d ",
                                            switch_block_conn[l][k][j].
                                            list[i]);
                                }
                            fprintf(out, "\n");
                        }
                    fprintf(out, "\n");
                }
        }
    fclose(out);
#endif /* CREATE_ECHO_FILES */

    return switch_block_conn;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void free_switch_block_conn ( struct s_ivec ***  switch_block_conn,
int  nodes_per_chan 
)

Frees the switch_block_conn data structure.

Definition at line 128 of file rr_graph_sbox.c.

{
    free_ivec_matrix3(switch_block_conn, 0, 3, 0, 3, 0, nodes_per_chan - 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int get_simple_switch_block_track ( INP enum e_side  from_side,
INP enum e_side  to_side,
INP int  from_track,
INP enum e_switch_block_type  switch_block_type,
INP int  nodes_per_chan 
)

This routine permutes the track number to connect for topologies SUBSET, UNIVERSAL, and WILTON. I added FULL (for fully flexible topology) but the returned value is simply a dummy, since we don't need to permute what connections to make for FULL (connect to EVERYTHING) This routine returns the track number to which the from_track should connect. It supports three simple, Fs = 3, switch blocks.

Definition at line 146 of file rr_graph_sbox.c.

{

    int to_track;

    to_track = SBOX_ERROR;      /* Can check to see if it's not set later. */

    if(switch_block_type == SUBSET)
        {                       /* NB:  Global routing uses SUBSET too */
            to_track = from_track;
        }


/* See S. Wilton Phd thesis, U of T, 1996 p. 103 for details on following. */

    else if(switch_block_type == WILTON)
        {

            if(from_side == LEFT)
                {

                    if(to_side == RIGHT)
                        {       /* CHANX to CHANX */
                            to_track = from_track;
                        }
                    else if(to_side == TOP)
                        {       /* from CHANX to CHANY */
                            to_track =
                                (nodes_per_chan -
                                 from_track) % nodes_per_chan;
                        }
                    else if(to_side == BOTTOM)
                        {
                            to_track =
                                (nodes_per_chan + from_track -
                                 1) % nodes_per_chan;
                        }
                }

            else if(from_side == RIGHT)
                {
                    if(to_side == LEFT)
                        {       /* CHANX to CHANX */
                            to_track = from_track;
                        }
                    else if(to_side == TOP)
                        {       /* from CHANX to CHANY */
                            to_track =
                                (nodes_per_chan + from_track -
                                 1) % nodes_per_chan;
                        }
                    else if(to_side == BOTTOM)
                        {
                            to_track =
                                (2 * nodes_per_chan - 2 -
                                 from_track) % nodes_per_chan;
                        }
                }

            else if(from_side == BOTTOM)
                {
                    if(to_side == TOP)
                        {       /* CHANY to CHANY */
                            to_track = from_track;
                        }
                    else if(to_side == LEFT)
                        {       /* from CHANY to CHANX */
                            to_track = (from_track + 1) % nodes_per_chan;
                        }
                    else if(to_side == RIGHT)
                        {
                            to_track =
                                (2 * nodes_per_chan - 2 -
                                 from_track) % nodes_per_chan;
                        }
                }

            else if(from_side == TOP)
                {
                    if(to_side == BOTTOM)
                        {       /* CHANY to CHANY */
                            to_track = from_track;
                        }
                    else if(to_side == LEFT)
                        {       /* from CHANY to CHANX */
                            to_track =
                                (nodes_per_chan -
                                 from_track) % nodes_per_chan;
                        }
                    else if(to_side == RIGHT)
                        {
                            to_track = (from_track + 1) % nodes_per_chan;
                        }
                }

        }
    /* End switch_block_type == WILTON case. */
    else if(switch_block_type == UNIVERSAL)
        {

            if(from_side == LEFT)
                {

                    if(to_side == RIGHT)
                        {       /* CHANX to CHANX */
                            to_track = from_track;
                        }
                    else if(to_side == TOP)
                        {       /* from CHANX to CHANY */
                            to_track = nodes_per_chan - 1 - from_track;
                        }
                    else if(to_side == BOTTOM)
                        {
                            to_track = from_track;
                        }
                }

            else if(from_side == RIGHT)
                {
                    if(to_side == LEFT)
                        {       /* CHANX to CHANX */
                            to_track = from_track;
                        }
                    else if(to_side == TOP)
                        {       /* from CHANX to CHANY */
                            to_track = from_track;
                        }
                    else if(to_side == BOTTOM)
                        {
                            to_track = nodes_per_chan - 1 - from_track;
                        }
                }

            else if(from_side == BOTTOM)
                {
                    if(to_side == TOP)
                        {       /* CHANY to CHANY */
                            to_track = from_track;
                        }
                    else if(to_side == LEFT)
                        {       /* from CHANY to CHANX */
                            to_track = from_track;
                        }
                    else if(to_side == RIGHT)
                        {
                            to_track = nodes_per_chan - 1 - from_track;
                        }
                }

            else if(from_side == TOP)
                {
                    if(to_side == BOTTOM)
                        {       /* CHANY to CHANY */
                            to_track = from_track;
                        }
                    else if(to_side == LEFT)
                        {       /* from CHANY to CHANX */
                            to_track = nodes_per_chan - 1 - from_track;
                        }
                    else if(to_side == RIGHT)
                        {
                            to_track = from_track;
                        }
                }
        }

    /* End switch_block_type == UNIVERSAL case. */
    /* UDSD Modification by WMF Begin */
    if(switch_block_type == FULL)
        {                       /* Just a placeholder. No meaning in reality */
            to_track = from_track;
        }
/* UDSD Modification by WMF End */

    if(to_track == SBOX_ERROR)
        {
            printf
                ("Error in get_simple_switch_block_track.  Unexpected connection.\n"
                 "from_side: %d  to_side: %d  switch_block_type: %d.\n",
                 from_side, to_side, switch_block_type);
            exit(1);
        }

    return (to_track);
}

Here is the caller graph for this function: