⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rr_graph_sbox.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
字号:
#include <assert.h>#include "util.h"#include "vpr_types.h"#include "rr_graph_sbox.h"#include "rr_graph_util.h"/* Switch box:                                                             * *                    TOP (CHANY)                                          * *                    | | | | | |                                          * *                   +-----------+                                         * *                 --|           |--                                       * *                 --|           |--                                       * *           LEFT  --|           |-- RIGHT                                 * *          (CHANX)--|           |--(CHANX)                                * *                 --|           |--                                       * *                 --|           |--                                       * *                   +-----------+                                         * *                    | | | | | |                                          * *                   BOTTOM (CHANY)                                        *//* [0..3][0..3][0..nodes_per_chan-1].  Structure below is indexed as:       * * [from_side][to_side][from_track].  That yields an integer vector (ivec)  * * of the tracks to which from_track connects in the proper to_location.    * * For simple switch boxes this is overkill, but it will allow complicated  * * switch boxes with Fs > 3, etc. without trouble.                          */int get_simple_switch_block_track(IN enum e_side from_side,				  IN enum e_side to_side,				  IN int from_track,				  IN enum e_switch_block_type				  switch_block_type,				  IN int nodes_per_chan);static enum e_side get_sbox_side(IN int get_i,				 IN int get_j,				 IN t_rr_type get_type,				 IN int comp_i,				 IN int comp_j);/* 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. */struct s_ivec ***alloc_and_load_switch_block_conn(IN int nodes_per_chan,				 IN enum				 e_switch_block_type switch_block_type,				 IN int Fs){    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");    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;}voidfree_switch_block_conn(struct s_ivec ***switch_block_conn,		       int nodes_per_chan){    /* Frees the switch_block_conn data structure. */    free_ivec_matrix3(switch_block_conn, 0, 3, 0, 3, 0, nodes_per_chan - 1);}#define SBOX_ERROR -1/* 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) */intget_simple_switch_block_track(IN enum e_side from_side,			      IN enum e_side to_side,			      IN int from_track,			      IN enum e_switch_block_type switch_block_type,			      IN int nodes_per_chan){/* This routine returns the track number to which the from_track should     * * connect.  It supports three simple, Fs = 3, switch blocks.               */    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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -