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

📄 xml_arch.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
📖 第 1 页 / 共 4 页
字号:
		    IsGlobal = TRUE;		}	    ezxml_set_attr(Cur, "type", NULL);	    		/* Itterate over pins in the class */ 		Tokens = GetNodeTokens(Cur);	    assert(CountTokens(Tokens) ==		    Type->class_inf[CurClass].num_pins);	    for(j = 0; j < Type->class_inf[CurClass].num_pins; ++j)		{		    CurPin = my_atoi(Tokens[j]);		    			/* Check for duplicate pin names */ 			if(pin_used[CurPin])			{			    printf(ERRTAG				    "Pin %d is defined in two different classes in type '%s'.\n",				    CurPin, Type->name);			    exit(1);			}		    pin_used[CurPin] = TRUE;		    			/* Set the pin class and is_global status */ 			for(i = 0; i < Type->capacity; ++i)			{			    Type->pin_class[CurPin + (i * PinsPerSubtile)] =				CurClass + (i * ClassesPerSubtile);			    Type->is_global_pin[CurPin +						 (i * PinsPerSubtile)] =				IsGlobal;			}		}	    FreeTokens(&Tokens);	    ++CurClass;	    Prev = Cur;	    Cur = Cur->next;	    FreeNode(Prev);	}    if(pin_used)	{	    free(pin_used);	    pin_used = NULL;	}}/* Sets up the pinloc map for the type. Unlinks the loc nodes * from the XML tree. * Pins and pin classses must already be setup by SetupPinClasses */     static voidSetupPinLocations(ezxml_t Locations,		  t_type_descriptor * Type){    int i, j, k, l, PinsPerSubtile;    ezxml_t Cur, Prev;    const char *Prop;    char **Tokens, **CurTokens;    PinsPerSubtile = Type->num_pins / Type->capacity;    	/* Alloc and clear pin locations */ 	Type->pinloc = (int ***)my_malloc(Type->height * sizeof(int **));    for(i = 0; i < Type->height; ++i)	{	    Type->pinloc[i] = (int **)my_malloc(4 * sizeof(int *));	    for(j = 0; j < 4; ++j)		{		    Type->pinloc[i][j] =			(int *)my_malloc(Type->num_pins * sizeof(int));		    for(k = 0; k < Type->num_pins; ++k)			{			    Type->pinloc[i][j][k] = 0;			}		}	}    	/* Load the pin locations */ 	Cur = Locations->child;    while(Cur)	{	    CheckElement(Cur, "loc");	    		/* Get offset */ 		i = 0;	    Prop = FindProperty(Cur, "offset", FALSE);	    if(Prop)		{		    i = my_atoi(Prop);		    if((i < 0) || (i >= Type->height))			{			    printf(ERRTAG				    "%d is an invalid offset for type '%s'.\n",				    i, Type->name);			    exit(1);			}		    ezxml_set_attr(Cur, "offset", NULL);		}	    		/* Get side */ 		Prop = FindProperty(Cur, "side", TRUE);	    if(0 == strcmp(Prop, "left"))		{		    j = LEFT;		}	    	    else if(0 == strcmp(Prop, "top"))		{		    j = TOP;		}	    	    else if(0 == strcmp(Prop, "right"))		{		    j = RIGHT;		}	    	    else if(0 == strcmp(Prop, "bottom"))		{		    j = BOTTOM;		}	    	    else		{		    printf(ERRTAG "'%s' is not a valid side.\n", Prop);		    exit(1);		}	    ezxml_set_attr(Cur, "side", NULL);	    		/* Check location is on perimeter */ 		if((TOP == j) && (i != (Type->height - 1)))		{		    printf(ERRTAG			    "Locations are only allowed on large block " 			    "perimeter. 'top' side should be at offset %d only.\n",			    (Type->height - 1));		    exit(1);		}	    if((BOTTOM == j) && (i != 0))		{		    printf(ERRTAG			    "Locations are only allowed on large block " 			    "perimeter. 'bottom' side should be at offset 0 only.\n");		    exit(1);		}	    		/* Go through lists of pins */ 		Tokens = GetNodeTokens(Cur);	    CurTokens = Tokens;	    while(*CurTokens)		{		    			/* Get pin */ 			k = my_atoi(*CurTokens);		    if(k >= Type->num_pins)			{			    printf(ERRTAG				    "Pin %d of type '%s' is not a valid pin.\n",				    k, Type->name);			    exit(1);			}		    			/* Set pin location */ 			for(l = 0; l < Type->capacity; ++l)			{			    Type->pinloc[i][j][k + (l * PinsPerSubtile)] = 1;			}		    			/* Advance through list of pins in this location */ 			++CurTokens;		}	    FreeTokens(&Tokens);	    Prev = Cur;	    Cur = Cur->next;	    FreeNode(Prev);	}}/* Sets up the grid_loc_def for the type. Unlinks the loc nodes * from the XML tree. */     static voidSetupGridLocations(ezxml_t Locations,		   t_type_descriptor * Type){    int i;    ezxml_t Cur, Prev;    const char *Prop;    Type->num_grid_loc_def = CountChildren(Locations, "loc");    Type->grid_loc_def = 	(struct s_grid_loc_def *)my_calloc(Type->num_grid_loc_def,					   sizeof(struct s_grid_loc_def));    	/* Load the pin locations */ 	Cur = Locations->child;    i = 0;    while(Cur)	{	    CheckElement(Cur, "loc");	    		/* loc index */ 		Prop = FindProperty(Cur, "type", TRUE);	    if(Prop)		{		    if(strcmp(Prop, "fill") == 0)			{			    if(Type->num_grid_loc_def != 1)				{				    printf(ERRTAG					    "Another loc specified for fill.\n");				    exit(1);				}			    Type->grid_loc_def[i].grid_loc_type = FILL;			    FILL_TYPE = Type;			}		    else if(strcmp(Prop, "col") == 0)			{			    Type->grid_loc_def[i].grid_loc_type = COL_REPEAT;			}		    else if(strcmp(Prop, "rel") == 0)			{			    Type->grid_loc_def[i].grid_loc_type = COL_REL;			}		    else			{			    printf(ERRTAG				    "Unknown grid location type '%s' for type '%s'.\n",				    Prop, Type->name);			    exit(1);			}		    ezxml_set_attr(Cur, "type", NULL);		}	    Prop = FindProperty(Cur, "start", FALSE);	    if(Type->grid_loc_def[i].grid_loc_type == COL_REPEAT)		{		    if(Prop == NULL)			{			    printf(ERRTAG				    "grid location property 'start' must be specified for grid location type 'col'.\n");			    exit(1);			}		    Type->grid_loc_def[i].start_col = my_atoi(Prop);		    ezxml_set_attr(Cur, "start", NULL);		}	    else if(Prop != NULL)		{		    printf(ERRTAG			    "grid location property 'start' valid for grid location type 'col' only.\n");		    exit(1);		}	    Prop = FindProperty(Cur, "repeat", FALSE);	    if(Type->grid_loc_def[i].grid_loc_type == COL_REPEAT)		{		    if(Prop != NULL)			{			    Type->grid_loc_def[i].repeat = my_atoi(Prop);			    ezxml_set_attr(Cur, "repeat", NULL);			}		}	    else if(Prop != NULL)		{		    printf(ERRTAG			    "grid location property 'repeat' valid for grid location type 'col' only.\n");		    exit(1);		}	    Prop = FindProperty(Cur, "pos", FALSE);	    if(Type->grid_loc_def[i].grid_loc_type == COL_REL)		{		    if(Prop == NULL)			{			    printf(ERRTAG				    "grid location property 'pos' must be specified for grid location type 'rel'.\n");			    exit(1);			}		    Type->grid_loc_def[i].col_rel = atof(Prop);		    ezxml_set_attr(Cur, "pos", NULL);		}	    else if(Prop != NULL)		{		    printf(ERRTAG			    "grid location property 'pos' valid for grid location type 'rel' only.\n");		    exit(1);		}	    Prop = FindProperty(Cur, "priority", FALSE);	    if(Prop)		{		    Type->grid_loc_def[i].priority = my_atoi(Prop);		    ezxml_set_attr(Cur, "priority", NULL);		}	    Prev = Cur;	    Cur = Cur->next;	    FreeNode(Prev);	    i++;	}}static voidSetupTypeTiming(ezxml_t timing,		t_type_descriptor * Type){    ezxml_t Cur, Prev;    const char *Prop;    float value;    char **Tokens;    	/* Clear timing info for type */ 	Type->type_timing_inf.T_fb_ipin_to_sblk_ipin = 0;    Type->type_timing_inf.T_sblk_opin_to_fb_opin = 0;    Type->type_timing_inf.T_sblk_opin_to_sblk_ipin = 0;    	/* Load the timing info */ 	Cur = timing->child;    while(Cur)	{	    CheckElement(Cur, "tedge");	    		/* Get timing type */ 		Prop = FindProperty(Cur, "type", TRUE);	    Tokens = GetNodeTokens(Cur);	    if(CountTokens(Tokens) != 1)		{		    printf(ERRTAG			    "Timing for sequential subblock edges not a number.");		}	    value = atof(Tokens[0]);	    if(0 == strcmp(Prop, "T_fb_ipin_to_sblk_ipin"))		{		    Type->type_timing_inf.T_fb_ipin_to_sblk_ipin = value;		}	    else if(0 == strcmp(Prop, "T_sblk_opin_to_fb_opin"))		{		    Type->type_timing_inf.T_sblk_opin_to_fb_opin = value;		}	    else if(0 == strcmp(Prop, "T_sblk_opin_to_sblk_ipin"))		{		    Type->type_timing_inf.T_sblk_opin_to_sblk_ipin = value;		}	    else		{		    printf(ERRTAG "'%s' is an unrecognized timing edge.\n",			    Prop);		    exit(1);		}	    ezxml_set_attr(Cur, "type", NULL);	    Prev = Cur;	    Cur = Cur->next;	    FreeNode(Prev);		FreeTokens(&Tokens);	}}static voidSetupSubblocksTcomb(ezxml_t timing,		    t_type_descriptor * Type){    ezxml_t Cur, prev;    t_T_subblock ** T_subblock_ptr;    float **t_comb;    int i, j;    char **Tokens;    T_subblock_ptr = &Type->type_timing_inf.T_subblock;    t_comb =	(float **)alloc_matrix(0, Type->max_subblock_inputs - 1, 0,			       Type->max_subblock_outputs - 1, sizeof(float));    for(i = 0; i < Type->max_subblock_inputs; i++)	{	    for(j = 0; j < Type->max_subblock_outputs; j++)		{		    t_comb[i][j] = 0;		}	}    	/* Load the timing info */ 	Cur = timing->child;    i = 0;    while(Cur)	{	    CheckElement(Cur, "trow");	    Tokens = GetNodeTokens(Cur);	    if(CountTokens(Tokens) != Type->max_subblock_outputs)		{		    printf(ERRTAG			    "Number of tokens %d not equal number of subblock outputs %d.",			    CountTokens(Tokens),			    Type->max_subblock_outputs);		    exit(1);		}	    for(j = 0; j < Type->max_subblock_outputs; j++)		{		    t_comb[i][j] = atof(Tokens[j]);		}	    i++;	    prev = Cur;	    Cur = Cur->next;	    FreeNode(prev);		FreeTokens(&Tokens);	}    if(i != Type->max_subblock_inputs)	{	    printf(ERRTAG		    "Number of trow %d not equal number of subblock inputs %d.",		    i, Type->max_subblock_inputs);	    exit(1);	}    for(i = 0; i < Type->max_subblocks; i++)	{	    (*T_subblock_ptr)[i].T_comb = t_comb;	}}static voidSetupSubblocksTSeq(ezxml_t timing_seq_in,		   ezxml_t timing_seq_out,		   t_type_descriptor * Type){    ezxml_t Cur, prev;    t_T_subblock ** T_subblock_ptr;    int i, j;    float *t_seq[2];    ezxml_t seq_timing[2];    char **Tokens;    T_subblock_ptr = &Type->type_timing_inf.T_subblock;    seq_timing[0] = timing_seq_in;    seq_timing[1] = timing_seq_out;    t_seq[0] = (float *)my_calloc(Type->max_subblock_inputs, sizeof(float));    t_seq[1] = (float *)my_calloc(Type->max_subblock_outputs, sizeof(float));    	/* Load the timing info */ 	for(i = 0; i < 2; i++)	{	    Cur = seq_timing[i]->child;	    j = 0;	    while(Cur)		{		    CheckElement(Cur, "trow");		    Tokens = GetNodeTokens(Cur);		    if(CountTokens(Tokens) != 1)			{			    printf(ERRTAG				    "Timing for sequential subblock edges not a number.");			}		    t_seq[i][j] = atof(Tokens[0]);		    j++;		    prev = Cur;		    Cur = Cur->next;		    FreeNode(prev);			FreeTokens(&Tokens);		}	    if(j != Type->max_subblock_outputs)		{		    printf(ERRTAG			    "Number of trow %d not equal number of subblock outputs %d.",			    j, Type->max_subblock_outputs);		    exit(1);		}	}    for(i = 0; i < Type->max_subblocks; i++)	{	    (*T_subblock_ptr)[i].T_seq_in = t_seq[0];	    (*T_subblock_ptr)[i].T_seq_out = t_seq[1];	}}/* Takes in the node ptr for the 'fc_in' and 'fc_out' elements and initializes * the appropriate fields of type. Unlinks the contents of the nodes. */     static voidProcess_Fc(ezxml_t Fc_in_node,	   ezxml_t Fc_out_node,	   t_type_descriptor * Type){    enum Fc_type Type_in;    enum Fc_type Type_out;    ParseFc(Fc_in_node, &Type_in, &Type->Fc_in);    ParseFc(Fc_out_node, &Type_out, &Type->Fc_out);    if(FC_FULL == Type_in)	{	    printf(ERRTAG "'full' Fc type isn't allowed for Fc_in.\n");	    exit(1);	}    Type->is_Fc_out_full_flex = FALSE;    Type->is_Fc_frac = FALSE;    if(FC_FULL == Type_out)	{	    Type->is_Fc_out_full_flex = TRUE;	}        else if(Type_in != Type_out)	{	    printf(ERRTAG		    "Fc_in and Fc_out must have same type unless Fc_out has type 'full'.\n");	    exit(1);	}    if(FC_FRAC == Type_in)	{	    Type->is_Fc_frac = TRUE;	}}/* This parses contents of the 'subblocks' element and unlinks from tree */     static voidProcessSubblocks(INOUT ezxml_t Parent,		 INOUT t_type_descriptor * Type,		 boolean timing_enabled){    const char *Prop;    ezxml_t CurType, Cur, Cur2;    Type->max_subblocks = 1;    Prop = FindProperty(Parent, "max_subblocks", FALSE);    if(Prop)	{	    Type->max_subblocks = my_atoi(Prop);	    ezxml_set_attr(Parent, "max_subblocks", NULL);	}    Type->max_subblock_inputs = 1;    Prop = FindProperty(Parent, "max_subblock_inputs", FALSE);    if(Prop)	{	    Type->max_subblock_inputs = my_atoi(Prop);	    ezxml_set_attr(Parent, "max_subblock_inputs", NULL);	}    Type->max_subblock_outputs = 1;    Prop = FindProperty(Parent, "max_subblock_outputs", FALSE);    if(Prop)	{	    Type->max_subblock_outputs = my_atoi(Prop);	    ezxml_set_attr(Parent, "max_subblock_outputs", NULL);	}    CurType = FindElement(Parent, "timing", timing_enabled);    if(CurType != NULL)	{	    Type->type_timing_inf.T_subblock = 		(t_T_subblock *) my_malloc(Type->max_subblocks *					   sizeof(t_T_subblock));	    		/* Load T_comb timing for subblock */ 		Cur = FindElement(CurType, "T_comb", TRUE);	    SetupSubblocksTcomb(Cur, Type);

⌨️ 快捷键说明

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