|
VPR-6.0
|
#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 SBOX_ERROR -1 |
Definition at line 135 of file rr_graph_sbox.c.
| 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: