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

📄 check_netlist.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
📖 第 1 页 / 共 2 页
字号:
	return (error);    load_one_fb_fanout_count(subblock_inf,			     num_subblocks, num_uses_of_fb_pin,			     num_uses_of_sblk_opin, iblk);    error += check_fb_to_subblock_connections(iblk, subblock_inf,					      num_subblocks,					      num_uses_of_fb_pin);    error += check_internal_subblock_connections(subblock_data_ptr, iblk,						 num_uses_of_sblk_opin);    return (error);}static intcheck_subblock_pin(int fb_pin,		   int min_val,		   int max_val,		   enum e_pin_type pin_type,		   int iblk,		   int isubblk,		   t_subblock * subblock_inf){/* Checks that this subblock pin connects to a valid clb pin or BLE output * * within the clb.  Returns the number of errors found.                    */    int iclass;    t_type_ptr type;    type = block[iblk].type;    if(fb_pin != OPEN)	{	    if(fb_pin < min_val || fb_pin > max_val)		{		    printf("Error:  Block #%d (%s) subblock #%d (%s)"			   "connects to nonexistent clb pin #%d.\n", iblk,			   block[iblk].name, isubblk,			   subblock_inf[isubblk].name, fb_pin);		    return (1);		}	    if(fb_pin < type->num_pins)		{		/* clb pin */		    iclass = type->pin_class[fb_pin];		    if(type->class_inf[iclass].type != pin_type)			{			    printf				("Error:  Block #%d (%s) subblock #%d (%s) pin connects\n"				 "\tto clb pin (#%d) of wrong input/output type.\n",				 iblk, block[iblk].name, isubblk,				 subblock_inf[isubblk].name, fb_pin);			    return (1);			}		}	}    return (0);}static voidcheck_for_multiple_sink_connections(void){/* The check is for nets that connect more than once to the same class of  * * pins on the same block.  For LUTs and cluster-based logic blocks that   * * doesn't make sense, although for some logic blocks it does.  The router * * can now handle this case, so maybe I should get rid of this check.      */    int iblk, ipin, inet, iclass, class_pin;    int *num_pins_connected;    t_type_ptr type;    num_pins_connected = my_calloc(num_nets, sizeof(int));/* Have to do the check block by block, rather than net by net, for speed. * * This makes the code a bit messy.                                        */    for(iblk = 0; iblk < num_blocks; iblk++)	{	    type = block[iblk].type;	    for(iclass = 0; iclass < type->num_class; iclass++)		{/* Two DRIVER pins can never connect to the same net (already checked by    * * the multiple driver check) so skip that check.                           */		    if(type->class_inf[iclass].type == DRIVER)			continue;		    for(class_pin = 0;			class_pin < type->class_inf[iclass].num_pins;			class_pin++)			{			    ipin = type->class_inf[iclass].pinlist[class_pin];			    inet = block[iblk].nets[ipin];			    if(inet != OPEN)				num_pins_connected[inet]++;			}		    for(class_pin = 0;			class_pin < type->class_inf[iclass].num_pins;			class_pin++)			{			    ipin = type->class_inf[iclass].pinlist[class_pin];			    inet = block[iblk].nets[ipin];			    if(inet != OPEN)				{				    if(num_pins_connected[inet] > 1)					{					    printf						("Warning:  block %d (%s) connects %d pins of class "						 "%d to net %d (%s).\n", iblk,						 block[iblk].name,						 num_pins_connected[inet],						 iclass, inet,						 net[inet].name);					    printf						("\tThis does not make sense for many logic blocks "						 "(e.g. LUTs).\n"						 "\tBe sure you really want this.\n");					}				    num_pins_connected[inet] = 0;				}			}		}	}    free(num_pins_connected);}static intget_num_conn(int bnum){/* This routine returns the number of connections to a block. */    int i, num_conn;    t_type_ptr type;    type = block[bnum].type;    num_conn = 0;    for(i = 0; i < type->num_pins; i++)	{	    if(block[bnum].nets[i] != OPEN)		num_conn++;	}    return (num_conn);}static intcheck_internal_subblock_connections(t_subblock_data * subblock_data_ptr,				    int iblk,				    int **num_uses_of_sblk_opin){/* This routine checks that all subblocks in this block are either           * * completely empty (no pins hooked to anything) or have their output used   * * somewhere.  It also counts the number of constant generators (no input    * * sblks) and the number of FFs used in the circuit.                         */    int num_const_gen, num_ff, isub, ipin, error, opin, i;    boolean has_inputs, has_outputs;    int subblock_lut_size;    int num_subblocks;    t_subblock *subblock_inf;    t_type_ptr type;    type = block[iblk].type;    subblock_lut_size = type->max_subblock_inputs;    num_subblocks = subblock_data_ptr->num_subblocks_per_block[iblk];    subblock_inf = subblock_data_ptr->subblock_inf[iblk];    num_const_gen = 0;    num_ff = 0;    error = 0;    for(isub = 0; isub < num_subblocks; isub++)	{	    has_inputs = FALSE;	    for(ipin = 0; ipin < subblock_lut_size; ipin++)		{		    if(subblock_inf[isub].inputs[ipin] != OPEN)			{			    has_inputs = TRUE;			    break;			}		}	    has_outputs = FALSE;	    for(opin = 0; opin < type->max_subblock_outputs; opin++)		{		    if(num_uses_of_sblk_opin[isub][opin] != 0)			{			    has_outputs = TRUE;			    break;			}		}	    if(type == IO_TYPE)		{		    /* Subblock inputs and outputs are faked for I/O's so this is an internal error */		    assert((has_inputs && !has_outputs)			   || (!has_inputs && has_outputs));		}	    else if(!has_outputs)		{		/* Output unused */		    if(has_inputs || subblock_inf[isub].clock != OPEN)			{			    printf				("Error:  output of subblock #%d (%s) of block #%d (%s) is "				 "never used.\n", isub,				 subblock_inf[isub].name, iblk,				 block[iblk].name);			    error++;			}		}	    /* End if output unused */	    /* Check that subblocks whose output is used have inputs. */	    else		{		/* Subblock output is used. */		    if(!has_inputs)			{	/* No inputs are used */			    if(subblock_inf[isub].clock == OPEN)				{				    printf					("Warning:  block #%d (%s), subblock #%d (%s) is a "					 "constant generator.\n\t(Has no inputs.)\n",					 iblk, block[iblk].name, isub,					 subblock_inf[isub].name);				    num_const_gen++;				}			    else				{				    printf					("Error:  block #%d (%s), subblock #%d (%s) is a CLOCKED "					 "\n\tconstant generator.\n\t(Has no inputs but is clocked.)\n",					 iblk, block[iblk].name, isub,					 subblock_inf[isub].name);				    num_const_gen++;				    error++;				}			}		    else			{	/* Both input and output are used */			    if(subblock_inf[isub].clock != OPEN)				{				    for(i = 0; i < type->max_subblock_outputs;					i++)					{					    if(subblock_inf[isub].					       outputs[i] != OPEN)						{						    num_ff++;						}					}				}			}		}	}			/* End for all subblocks */    subblock_data_ptr->num_const_gen += num_const_gen;    subblock_data_ptr->num_ff += num_ff;    return (error);}static intcheck_fb_to_subblock_connections(int iblk,				 t_subblock * subblock_inf,				 int num_subblocks,				 int *num_uses_of_fb_pin){/* This routine checks that each non-OPEN clb input pin connects to some    * * subblock inputs, and that each non-OPEN clb output pin is driven by      * * exactly one subblock output. It returns the number of errors found.      * * Note that num_uses_of_fb_pin is used to store the number of out-edges   * * (fanout) for a FB ipin, and the number of in-edges (fanin) for a FB    * * opin.                                                                    */    int ipin, isub, fb_pin, error;    int num_outputs;    error = 0;    num_outputs = block[iblk].type->max_subblock_outputs;/* Count how many things connect to each clb output pin. */    for(isub = 0; isub < num_subblocks; isub++)	{	    for(ipin = 0; ipin < num_outputs; ++ipin)		{		    fb_pin = subblock_inf[isub].outputs[ipin];		    if(fb_pin != OPEN)	/* Guaranteed to connect to DRIVER pin only */			num_uses_of_fb_pin[fb_pin]++;		}	}    for(ipin = 0; ipin < block[iblk].type->num_pins; ipin++)	{	    if(block[iblk].nets[ipin] != OPEN)		{		    if(is_opin(ipin, block[iblk].type))			{	/* FB output */			    if(num_uses_of_fb_pin[ipin] == 0)				{	/* No driver? */				    printf					("Error:  output pin %d on block #%d (%s) is not driven "					 "by any subblock.\n", ipin, iblk,					 block[iblk].name);				    error++;				}			    else if(num_uses_of_fb_pin[ipin] > 1)				{	/* Multiple drivers? */				    printf					("Error:  output pin %d on block #%d (%s) is driven "					 "by %d subblocks.\n", ipin, iblk,					 block[iblk].name,					 num_uses_of_fb_pin[ipin]);				    error++;				}			}		    else			{	/* FB ipin */			    if(num_uses_of_fb_pin[ipin] <= 0)				{	/* Fans out? */				    printf					("Error:  pin %d on block #%d (%s) does not fanout to any "					 "subblocks.\n", ipin, iblk,					 block[iblk].name);				    error++;				}			}		}	    /* End if not OPEN */	    else if(is_opin(ipin, block[iblk].type))		{		/* OPEN FB output pin */		    if(num_uses_of_fb_pin[ipin] > 1)			{			    printf				("Error:  pin %d on block #%d (%s) is driven by %d "				 "subblocks.\n", ipin, iblk, block[iblk].name,				 num_uses_of_fb_pin[ipin]);			    error++;			}		}	}    return (error);}

⌨️ 快捷键说明

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