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

📄 path_delay.c

📁 VPR布局布线源码
💻 C
📖 第 1 页 / 共 4 页
字号:
}static voidfree_pin_mappings(int **block_pin_to_tnode,		  int ****snode_block_pin_to_tnode,		  int *num_subblocks_per_block){/* Frees the arrays that map from pins to tnode coordinates. */    int isub, iblk, isubtype, num_subblocks;    for(iblk = 0; iblk < num_blocks; iblk++)	{	    num_subblocks = num_subblocks_per_block[iblk];	    for(isub = 0; isub < num_subblocks; isub++)		{		    for(isubtype = 0; isubtype < NUM_SUB_PIN_TYPES;			isubtype++)			{			    free(snode_block_pin_to_tnode[iblk][isub]				 [isubtype]);			}		}	    free_matrix(snode_block_pin_to_tnode[iblk], 0,			num_subblocks_per_block[iblk] - 1, 0, sizeof(int *));	    free(block_pin_to_tnode[iblk]);	}    free(block_pin_to_tnode);    free(snode_block_pin_to_tnode);}static voidalloc_and_load_fanout_counts(int ***num_uses_of_fb_ipin_ptr,			     int ****num_uses_of_sblk_opin_ptr,			     t_subblock_data subblock_data){/* Allocates and loads two arrays that say how many points each fb input    * * pin and each subblock output fan out to.                                 */    int iblk;    int **num_uses_of_fb_ipin, ***num_uses_of_sblk_opin;    int *num_subblocks_per_block;    t_subblock **subblock_inf;    num_subblocks_per_block = subblock_data.num_subblocks_per_block;    subblock_inf = subblock_data.subblock_inf;    num_uses_of_fb_ipin = (int **)my_malloc(num_blocks * sizeof(int *));    num_uses_of_sblk_opin = (int ***)my_malloc(num_blocks * sizeof(int **));    for(iblk = 0; iblk < num_blocks; iblk++)	{	    num_uses_of_fb_ipin[iblk] =		(int *)my_calloc(block[iblk].type->num_pins, sizeof(int));	    num_uses_of_sblk_opin[iblk] =		(int **)alloc_matrix(0, block[iblk].type->max_subblocks - 1,				     0,				     block[iblk].type->max_subblock_outputs -				     1, sizeof(int));	    load_one_fb_fanout_count(subblock_inf[iblk],				     num_subblocks_per_block[iblk],				     num_uses_of_fb_ipin[iblk],				     num_uses_of_sblk_opin[iblk], iblk);	}			/* End for all blocks */    *num_uses_of_fb_ipin_ptr = num_uses_of_fb_ipin;    *num_uses_of_sblk_opin_ptr = num_uses_of_sblk_opin;}static voidfree_fanout_counts(int **num_uses_of_fb_ipin,		   int ***num_uses_of_sblk_opin){/* Frees the fanout count arrays. */    int iblk;    t_type_ptr type;    for(iblk = 0; iblk < num_blocks; iblk++)	{	    type = block[iblk].type;	    free(num_uses_of_fb_ipin[iblk]);	    free_matrix(num_uses_of_sblk_opin[iblk], 0,			type->max_subblocks - 1, 0, sizeof(int));	}    free(num_uses_of_fb_ipin);    free(num_uses_of_sblk_opin);}static voidalloc_and_load_tnodes_and_net_mapping(int **num_uses_of_fb_ipin,				      int ***num_uses_of_sblk_opin,				      int **block_pin_to_tnode,				      int ****snode_block_pin_to_tnode,				      t_subblock_data subblock_data,				      t_timing_inf timing_inf){    int iblk;    int *num_subblocks_per_block;    t_subblock **subblock_inf;    tnode = (t_tnode *) my_malloc(num_tnodes * sizeof(t_tnode));    tnode_descript = (t_tnode_descript *) my_malloc(num_tnodes *						    sizeof(t_tnode_descript));    net_to_driver_tnode = (int *)my_malloc(num_nets * sizeof(int));    subblock_inf = subblock_data.subblock_inf;    num_subblocks_per_block = subblock_data.num_subblocks_per_block;    for(iblk = 0; iblk < num_blocks; iblk++)	{	    build_fb_tnodes(iblk, num_uses_of_fb_ipin[iblk],			    block_pin_to_tnode,			    snode_block_pin_to_tnode[iblk],			    num_subblocks_per_block[iblk], subblock_inf[iblk],			    block[iblk].type->type_timing_inf.			    T_fb_ipin_to_sblk_ipin);	    build_subblock_tnodes(num_uses_of_sblk_opin[iblk],				  block_pin_to_tnode[iblk],				  snode_block_pin_to_tnode[iblk],				  num_subblocks_per_block, subblock_inf,				  timing_inf, iblk);	}}static voidbuild_fb_tnodes(int iblk,		int *n_uses_of_fb_ipin,		int **block_pin_to_tnode,		int ***sub_pin_to_tnode,		int num_subs,		t_subblock * sub_inf,		float T_fb_ipin_to_sblk_ipin){/* This routine builds the tnodes corresponding to the fb pins of this      * block, and properly hooks them up to the rest of the graph. Note that     * only the snode_block_pin_to_tnode, etc. element for this block is passed in.     * Assumes that pins are ordered as [inputs][outputs][clk] */    int isub, ipin, iedge, from_pin, opin;    int inode, to_node, num_edges;    t_tedge *tedge;    int clk_pin;    t_type_ptr type;    int *next_ipin_edge;    type = block[iblk].type;    next_ipin_edge = (int *)my_malloc(type->num_pins * sizeof(int));    clk_pin = 0;/* Start by allocating the edge arrays, and for opins, loading them.    */    for(ipin = 0; ipin < block[iblk].type->num_pins; ipin++)	{	    inode = block_pin_to_tnode[iblk][ipin];	    if(inode != OPEN)		{		/* Pin is used -> put in graph */		    if(is_opin(ipin, block[iblk].type))			{			    build_block_output_tnode(inode, iblk, ipin,						     block_pin_to_tnode);			    tnode_descript[inode].type = FB_OPIN;			}		    else			{	/* FB ipin */			    next_ipin_edge[ipin] = 0;	/* Reset */			    num_edges = n_uses_of_fb_ipin[ipin];			    /* if clock pin, timing edges go to each subblock output used */			    for(isub = 0; isub < num_subs; isub++)				{				    if(sub_inf[isub].clock == ipin)					{					    for(opin = 0;						opin <						type->max_subblock_outputs;						opin++)						{						    if(sub_inf[isub].						       outputs[opin] != OPEN)							{							    num_edges++;							}						}					    num_edges--;	/* Remove clock_pin count, replaced by outputs */					}				}			    tnode[inode].num_edges = num_edges;			    tnode[inode].out_edges =				(t_tedge *) my_chunk_malloc(num_edges *							    sizeof(t_tedge),							    &tedge_ch_list_head,							    &tedge_ch_bytes_avail,							    &tedge_ch_next_avail);			    tnode_descript[inode].type = FB_IPIN;			}		    tnode_descript[inode].ipin = ipin;		    tnode_descript[inode].isubblk = OPEN;		    tnode_descript[inode].iblk = iblk;		}	}/* Now load the edge arrays for the FB input pins. Do this by looking at   * * where the subblock input and clock pins are driven from.                 */    for(isub = 0; isub < num_subs; isub++)	{	    for(ipin = 0; ipin < type->max_subblock_inputs; ipin++)		{		    from_pin = sub_inf[isub].inputs[ipin];		    /* Not OPEN and comes from fb ipin? */		    if(from_pin != OPEN		       && from_pin < block[iblk].type->num_pins)			{			    inode = block_pin_to_tnode[iblk][from_pin];			    assert(inode != OPEN);			    to_node = sub_pin_to_tnode[isub][SUB_INPUT][ipin];			    tedge = tnode[inode].out_edges;			    iedge = next_ipin_edge[from_pin]++;			    tedge[iedge].to_node = to_node;			    tedge[iedge].Tdel = T_fb_ipin_to_sblk_ipin;			}		}	    from_pin = sub_inf[isub].clock;	    if(from_pin != OPEN && from_pin < block[iblk].type->num_pins)		{		    inode = block_pin_to_tnode[iblk][from_pin];		    to_node = sub_pin_to_tnode[isub][SUB_CLOCK][clk_pin];	/* Feeds seq. output */		    /* connect to each output flip flop */		    for(opin = 0; opin < type->max_subblock_outputs; opin++)			{			    if(sub_inf[isub].outputs[opin] != OPEN)				{				    tedge = tnode[inode].out_edges;				    iedge = next_ipin_edge[from_pin]++;				    tedge[iedge].to_node = to_node;				    /* For the earliest possible clock I want this delay to be zero, so it       *				     * * arrives at flip flops at T = 0.  For later clocks or locally generated    *				     * * clocks that may accumulate delay (like the clocks in a ripple counter),   *				     * * I might want to make this delay nonzero.  Not worth bothering about now.  */				    tedge[iedge].Tdel = 0.;				    to_node += 2;				}			}		}	}    free(next_ipin_edge);}static voidbuild_block_output_tnode(int inode,			 int iblk,			 int ipin,			 int **block_pin_to_tnode){/* Sets the number of edges and the edge array for an output pin from a      * * block.  This pin must be hooked to something -- i.e. not OPEN.            */    int iedge, to_blk, to_pin, to_node, num_edges, inet;    t_tedge *tedge;    inet = block[iblk].nets[ipin];	/* Won't be OPEN, as inode exists */    assert(inet != OPEN);	/* Sanity check. */    net_to_driver_tnode[inet] = inode;    num_edges = (net[inet].num_sinks + 1) - 1;    tnode[inode].num_edges = num_edges;    tnode[inode].out_edges = (t_tedge *) my_chunk_malloc(num_edges *							 sizeof(t_tedge),							 &tedge_ch_list_head,							 &tedge_ch_bytes_avail,							 &tedge_ch_next_avail);    tedge = tnode[inode].out_edges;    for(iedge = 0; iedge < (net[inet].num_sinks + 1) - 1; iedge++)	{	    to_blk = net[inet].node_block[iedge + 1];	    to_pin = net[inet].node_block_pin[iedge + 1];	    to_node = block_pin_to_tnode[to_blk][to_pin];	    tedge[iedge].to_node = to_node;	    /* Set delay from net delays with a later call */	}}static voidbuild_subblock_tnodes(int **n_uses_of_sblk_opin,		      int *node_block_pin_to_tnode,		      int ***sub_pin_to_tnode,		      int *num_subblocks_per_block,		      t_subblock ** subblock_inf,		      t_timing_inf timing_inf,		      int iblk){/* This routine builds the tnodes of the subblock pins within one FB. Note * * that only the block_pin_to_tnode, etc. data for *this* block are passed  * * in.                                                                      */    int isub, ipin, inode, to_node, from_pin, to_pin, opin, from_opin,	clk_pin, used_opin_count;    int num_subs, from_sub;    t_subblock *sub_inf;    int iedge, num_edges;    float sink_delay;    t_tedge *tedge;    boolean has_inputs, has_outputs;    int **next_sblk_opin_edge;	/* [0..max_subblocks-1][0..max_subblock_outputs-1] */    int *num_opin_used_in_sblk;	/* [0..max_subblocks-1] */    t_type_ptr type = block[iblk].type;    sub_inf = subblock_inf[iblk];    num_subs = num_subblocks_per_block[iblk];    next_sblk_opin_edge =	(int **)alloc_matrix(0, type->max_subblocks - 1, 0,			     type->max_subblock_outputs - 1, sizeof(int));    num_opin_used_in_sblk =	(int *)my_malloc(type->max_subblocks * sizeof(int));    clk_pin = 0;/* Allocate memory for output pins first. */    for(isub = 0; isub < num_subs; isub++)	{	    num_opin_used_in_sblk[isub] = 0;	    for(opin = 0; opin < type->max_subblock_outputs; opin++)		{		    inode = sub_pin_to_tnode[isub][SUB_OUTPUT][opin];		    if(inode != OPEN)			{	/* Output is used -> timing node exists. */			    num_opin_used_in_sblk[isub]++;			    next_sblk_opin_edge[isub][opin] = 0;	/* Reset */			    num_edges = n_uses_of_sblk_opin[isub][opin];			    tnode[inode].num_edges = num_edges;			    tnode[inode].out_edges =				(t_tedge *) my_chunk_malloc(num_edges *							    sizeof(t_tedge),							    &tedge_ch_list_head,							    &tedge_ch_bytes_avail,							    &tedge_ch_next_avail);			    if(IO_TYPE == type)				{				    tnode_descript[inode].type = INPAD_OPIN;				    tnode[inode + 1].num_edges = 1;				    tnode[inode + 1].out_edges = (t_tedge *)					my_chunk_malloc(sizeof(t_tedge),							&tedge_ch_list_head,							&tedge_ch_bytes_avail,							&tedge_ch_next_avail);				    tedge = tnode[inode + 1].out_edges;				    tedge[0].to_node = inode;				    /* For input pads, use sequential output for source timing delay (treat as register) */				    if(is_global_clock				       (iblk, isub, opin,					num_subblocks_per_block,					subblock_inf))					tedge[0].Tdel = 0.;				    else					tedge[0].Tdel =					    type->type_timing_inf.					    T_subblock[isub].T_seq_out[opin];				    tnode_descript[inode + 1].type =					INPAD_SOURCE;				    tnode_descript[inode + 1].ipin = OPEN;				    tnode_descript[inode + 1].isubblk = isub;				    tnode_descript[inode + 1].iblk = iblk;				}			    else				{				    tnode_descript[inode].type = SUBBLK_OPIN;				}			    tnode_descript[inode].ipin = opin;			    tnode_descript[inode].isubblk = isub;			    tnode_descript[inode].iblk = iblk;			}		}

⌨️ 快捷键说明

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