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

📄 xml_arch.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
📖 第 1 页 / 共 4 页
字号:
    ezxml_t Cur, Next;    	/* Parse the file */ 	Cur = ezxml_parse_file(ArchFile);    if(NULL == Cur)	{	    printf(ERRTAG "Unable to load architecture file '%s'.\n",		    ArchFile);	}    	/* Root node should be architecture */ 	CheckElement(Cur, "architecture");    	/* Process layout */ 	Next = FindElement(Cur, "layout", TRUE);    ProcessLayout(Next, arch);    FreeNode(Next);    	/* Process device */ 	Next = FindElement(Cur, "device", TRUE);    ProcessDevice(Next, arch, timing_enabled);    FreeNode(Next);    	/* Process types */ 	Next = FindElement(Cur, "typelist", TRUE);    ProcessTypes(Next, Types, NumTypes, timing_enabled);    FreeNode(Next);    	/* Process switches */ 	Next = FindElement(Cur, "switchlist", TRUE);    ProcessSwitches(Next, &(arch->Switches), &(arch->num_switches),		     timing_enabled);    FreeNode(Next);    	/* Process segments. This depends on switches */ 	Next = FindElement(Cur, "segmentlist", TRUE);    ProcessSegments(Next, &(arch->Segments), &(arch->num_segments),		     arch->Switches, arch->num_switches, timing_enabled);    FreeNode(Next);    	/* Release the full XML tree */ 	FreeNode(Cur);}static voidProcessSegments(INOUT ezxml_t Parent,		OUT struct s_segment_inf **Segs,		OUT int *NumSegs,		IN struct s_switch_inf *Switches,		IN int NumSwitches,		IN boolean timing_enabled){    int i, j, length;    const char *tmp;    ezxml_t SubElem;    ezxml_t Node;    	/* Count the number of segs and check they are in fact	 * of segment elements. */ 	*NumSegs = CountChildren(Parent, "segment");    	/* Alloc segment list */ 	*Segs = NULL;    if(*NumSegs > 0)	{	    *Segs =		(struct s_segment_inf *)my_malloc(*NumSegs *						   sizeof(struct							  s_segment_inf));	    memset(*Segs, 0, (*NumSegs * sizeof(struct s_segment_inf)));	}    	/* Load the segments. */ 	for(i = 0; i < *NumSegs; ++i)	{	    Node = ezxml_child(Parent, "segment");	    		/* Get segment length */ 		length = 1;	/* DEFAULT */	    tmp = FindProperty(Node, "length", FALSE);	    if(tmp)		{		    if(strcmp(tmp, "longline") == 0)			{			    (*Segs)[i].longline = TRUE;			}		    else			{			    length = my_atoi(tmp);			}		}	    (*Segs)[i].length = length;	    ezxml_set_attr(Node, "length", NULL);	    		/* Get the frequency */ 		(*Segs)[i].frequency = 1;	/* DEFAULT */	    tmp = FindProperty(Node, "freq", FALSE);	    if(tmp)		{		    (*Segs)[i].frequency = my_atoi(tmp);		}	    ezxml_set_attr(Node, "freq", NULL);	    		/* Get timing info */ 		(*Segs)[i].Rmetal = 0;	/* DEFAULT */	    tmp = FindProperty(Node, "Rmetal", timing_enabled);	    if(tmp)		{		    (*Segs)[i].Rmetal = atof(tmp);		}	    ezxml_set_attr(Node, "Rmetal", NULL);	    (*Segs)[i].Cmetal = 0;	/* DEFAULT */	    tmp = FindProperty(Node, "Cmetal", timing_enabled);	    if(tmp)		{		    (*Segs)[i].Cmetal = atof(tmp);		}	    ezxml_set_attr(Node, "Cmetal", NULL);	    		/* Get the type */ 		tmp = FindProperty(Node, "type", TRUE);	    if(0 == strcmp(tmp, "bidir"))		{		    (*Segs)[i].directionality = BI_DIRECTIONAL;		}	    	    else if(0 == strcmp(tmp, "unidir"))		{		    (*Segs)[i].directionality = UNI_DIRECTIONAL;		}	    	    else		{		    printf(ERRTAG "Invalid switch type '%s'.\n", tmp);		    exit(1);		}	    ezxml_set_attr(Node, "type", NULL);	    		/* Get the wire and opin switches, or mux switch if unidir */ 		if(UNI_DIRECTIONAL == (*Segs)[i].directionality)		{		    SubElem = FindElement(Node, "mux", TRUE);		    tmp = FindProperty(SubElem, "name", TRUE);		    			/* Match names */ 			for(j = 0; j < NumSwitches; ++j)			{			    if(0 == strcmp(tmp, Switches[j].name))				{				    break;	/* End loop so j is where we want it */				}			}		    if(j >= NumSwitches)			{			    printf(ERRTAG "'%s' is not a valid mux name.\n",				    tmp);			    exit(1);			}		    ezxml_set_attr(SubElem, "name", NULL);		    FreeNode(SubElem);		    			/* Unidir muxes must have the same switch			 * for wire and opin fanin since there is 			 * really only the mux in unidir. */ 			(*Segs)[i].wire_switch = j;		    (*Segs)[i].opin_switch = j;		}	    	    else		{		    assert(BI_DIRECTIONAL == (*Segs)[i].directionality);		    SubElem = FindElement(Node, "wire_switch", TRUE);		    tmp = FindProperty(SubElem, "name", TRUE);		    			/* Match names */ 			for(j = 0; j < NumSwitches; ++j)			{			    if(0 == strcmp(tmp, Switches[j].name))				{				    break;	/* End loop so j is where we want it */				}			}		    if(j >= NumSwitches)			{			    printf(ERRTAG				    "'%s' is not a valid wire_switch name.\n",				    tmp);			    exit(1);			}		    (*Segs)[i].wire_switch = j;		    ezxml_set_attr(SubElem, "name", NULL);		    FreeNode(SubElem);		    SubElem = FindElement(Node, "opin_switch", TRUE);		    tmp = FindProperty(SubElem, "name", TRUE);		    			/* Match names */ 			for(j = 0; j < NumSwitches; ++j)			{			    if(0 == strcmp(tmp, Switches[j].name))				{				    break;	/* End loop so j is where we want it */				}			}		    if(j >= NumSwitches)			{			    printf(ERRTAG				    "'%s' is not a valid opin_switch name.\n",				    tmp);			    exit(1);			}		    (*Segs)[i].opin_switch = j;		    ezxml_set_attr(SubElem, "name", NULL);		    FreeNode(SubElem);		}	    		/* Setup the CB list if they give one, otherwise use full */ 		(*Segs)[i].cb_len = length;	    (*Segs)[i].cb = (boolean *) my_malloc(length * sizeof(boolean));	    for(j = 0; j < length; ++j)		{		    (*Segs)[i].cb[j] = TRUE;		}	    SubElem = FindElement(Node, "cb", FALSE);	    if(SubElem)		{		    ProcessCB_SB(SubElem, (*Segs)[i].cb, length);		    FreeNode(SubElem);		}	    		/* Setup the SB list if they give one, otherwise use full */ 		(*Segs)[i].sb_len = (length + 1);	    (*Segs)[i].sb =		(boolean *) my_malloc((length + 1) * sizeof(boolean));	    for(j = 0; j < (length + 1); ++j)		{		    (*Segs)[i].sb[j] = TRUE;		}	    SubElem = FindElement(Node, "sb", FALSE);	    if(SubElem)		{		    ProcessCB_SB(SubElem, (*Segs)[i].sb, (length + 1));		    FreeNode(SubElem);		}	    FreeNode(Node);	}}static voidProcessCB_SB(INOUT ezxml_t Node,	     INOUT boolean * list,	     IN int len){    const char *tmp = NULL;    int i;    	/* Check the type. We only support 'pattern' for now. 	 * Should add frac back eventually. */ 	tmp = FindProperty(Node, "type", TRUE);    if(0 == strcmp(tmp, "pattern"))	{	    i = 0;	    		/* Get the content string */ 		tmp = Node->txt;	    while(*tmp)		{		    switch (*tmp)			{			case ' ':			    break;			case 'T':			case '1':			    if(i >= len)				{				    printf(ERRTAG					    "CB or SB depopulation is too long. It "					    					    "should be (length) symbols for CBs and (length+1) "					     "symbols for SBs.\n");				    exit(1);				}			    list[i] = TRUE;			    ++i;			    break;			case 'F':			case '0':			    if(i >= len)				{				    printf(ERRTAG					    "CB or SB depopulation is too long. It "					    					    "should be (length) symbols for CBs and (length+1) "					     "symbols for SBs.\n");				    exit(1);				}			    list[i] = FALSE;			    ++i;			    break;			default:			    printf(ERRTAG "Invalid character %c in CB or " 				    "SB depopulation list.\n", *tmp);			    exit(1);			}		    ++tmp;		}	    if(i < len)		{		    printf(ERRTAG "CB or SB depopulation is too short. It " 			    "should be (length) symbols for CBs and (length+1) "			     "symbols for SBs.\n");		    exit(1);		}	    		/* Free content string */ 		ezxml_set_txt(Node, "");	}        else	{	    printf(ERRTAG "'%s' is not a valid type for specifying " 		    "cb and sb depopulation.\n", tmp);	    exit(1);	}    ezxml_set_attr(Node, "type", NULL);}static voidProcessSwitches(INOUT ezxml_t Parent,		OUT struct s_switch_inf **Switches,		OUT int *NumSwitches,		IN boolean timing_enabled){    int i, j;    const char *type_name;    const char *switch_name;    const char *Prop;    boolean has_buf_size;    ezxml_t Node;    has_buf_size = FALSE;    	/* Count the children and check they are switches */ 	*NumSwitches = CountChildren(Parent, "switch");    	/* Alloc switch list */ 	*Switches = NULL;    if(*NumSwitches > 0)	{	    *Switches =		(struct s_switch_inf *)my_malloc(*NumSwitches *						  sizeof(struct							 s_switch_inf));	    memset(*Switches, 0,		    (*NumSwitches * sizeof(struct s_switch_inf)));	}    	/* Load the switches. */ 	for(i = 0; i < *NumSwitches; ++i)	{	    Node = ezxml_child(Parent, "switch");	    switch_name = FindProperty(Node, "name", TRUE);	    type_name = FindProperty(Node, "type", TRUE);	    		/* Check for switch name collisions */ 		for(j = 0; j < i; ++j)		{		    if(0 == strcmp((*Switches)[j].name, switch_name))			{			    printf(ERRTAG				    "Two switches with the same name '%s' were "				     "found.\n", switch_name);			    exit(1);			}		}	    (*Switches)[i].name = my_strdup(switch_name);	    ezxml_set_attr(Node, "name", NULL);	    		/* Figure out the type of switch. */ 		if(0 == strcmp(type_name, "mux"))		{		    (*Switches)[i].buffered = TRUE;		    has_buf_size = TRUE;		}	    	    else if(0 == strcmp(type_name, "pass_trans"))		{		    (*Switches)[i].buffered = FALSE;		}	    	    else if(0 == strcmp(type_name, "buffer"))		{		    (*Switches)[i].buffered = TRUE;		}	    	    else		{		    printf(ERRTAG "Invalid switch type '%s'.\n", type_name);		    exit(1);		}	    ezxml_set_attr(Node, "type", NULL);	    Prop = FindProperty(Node, "R", timing_enabled);	    if(Prop != NULL)		{		    (*Switches)[i].R = atof(Prop);		    ezxml_set_attr(Node, "R", NULL);		}	    Prop = FindProperty(Node, "Cin", timing_enabled);	    if(Prop != NULL)		{		    (*Switches)[i].Cin = atof(Prop);		    ezxml_set_attr(Node, "Cin", NULL);		}	    Prop = FindProperty(Node, "Cout", timing_enabled);	    if(Prop != NULL)		{		    (*Switches)[i].Cout = atof(Prop);		    ezxml_set_attr(Node, "Cout", NULL);		}	    Prop = FindProperty(Node, "Tdel", timing_enabled);	    if(Prop != NULL)		{		    (*Switches)[i].Tdel = atof(Prop);		    ezxml_set_attr(Node, "Tdel", NULL);		}	    Prop = FindProperty(Node, "buf_size", has_buf_size);	    if(has_buf_size)		{		    (*Switches)[i].buf_size = atof(Prop);		    ezxml_set_attr(Node, "buf_size", NULL);		}	    Prop = FindProperty(Node, "mux_trans_size", FALSE);	    if(Prop != NULL)		{		    (*Switches)[i].mux_trans_size = atof(Prop);		    ezxml_set_attr(Node, "mux_trans_size", NULL);		}	    		/* Remove the switch element from parse tree */ 		FreeNode(Node);	}}/* Output the data from architecture data so user can verify it * was interpretted correctly. */     voidEchoArch(IN const char *EchoFile,	 IN const t_type_descriptor * Types,	 IN int NumTypes){    int i, j, k;    FILE * Echo;    Echo = my_fopen(EchoFile, "w");    for(i = 0; i < NumTypes; ++i)	{	    fprintf(Echo, "Type: \"%s\"\n", Types[i].name);	    fprintf(Echo, "\tcapacity: %d\n", Types[i].capacity);	    fprintf(Echo, "\theight: %d\n", Types[i].height);	    if(Types[i].num_pins > 0)		{		    for(j = 0; j < Types[i].height; ++j)			{			    fprintf(Echo,				     "\tpinloc[%d] TOP LEFT BOTTOM RIGHT:\n",				     j);			    for(k = 0; k < Types[i].num_pins; ++k)				{				    fprintf(Echo, "\t\t%d %d %d %d\n",					     Types[i].pinloc[j][TOP][k],					     Types[i].pinloc[j][LEFT][k],					     Types[i].pinloc[j][BOTTOM][k],					     Types[i].pinloc[j][RIGHT][k]);				}			}		}	    fprintf(Echo, "\tnum_pins (scaled for capacity): %d\n",		      Types[i].num_pins);	    if(Types[i].num_pins > 0)		{		    fprintf(Echo, "\tPins: NAME CLASS IS_GLOBAL\n");		    for(j = 0; j < Types[i].num_pins; ++j)			{			    fprintf(Echo, "\t\t%d %d %s\n", j,				     Types[i].pin_class[j],				     (Types[i].				       is_global_pin[j] ? "TRUE" : "FALSE"));			}		}	    fprintf(Echo, "\tnum_class: %d\n", Types[i].num_class);	    if(Types[i].num_class > 0)		{		    for(j = 0; j < Types[i].num_class; ++j)			{			    switch (Types[i].class_inf[j].type)				{				case RECEIVER:				    fprintf(Echo, "\t\tType: RECEIVER\n");				    break;				case DRIVER:				    fprintf(Echo, "\t\tType: DRIVER\n");				    break;				case OPEN:				    fprintf(Echo, "\t\tType: OPEN\n");				    break;				default:				    fprintf(Echo, "\t\tType: UNKNOWN\n");				    break;				}			    fprintf(Echo, "\t\t\tnum_pins: %d\n",				     Types[i].class_inf[j].num_pins);			    fprintf(Echo, "\t\t\tpins: ");	/* No \n */			    for(k = 0; k < Types[i].class_inf[j].num_pins;				 ++k)				{				    fprintf(Echo, "%d ", Types[i].class_inf[j].pinlist[k]);	/* No \n */				}			    fprintf(Echo, "\n");	/* End current line */			}		}	    fprintf(Echo, "\tis_Fc_frac: %s\n",		      (Types[i].is_Fc_frac ? "TRUE" : "FALSE"));	    fprintf(Echo, "\tis_Fc_out_full_flex: %s\n",		     (Types[i].is_Fc_out_full_flex ? "TRUE" : "FALSE"));	    fprintf(Echo, "\tFc_in: %f\n", Types[i].Fc_in);	    fprintf(Echo, "\tFc_out: %f\n", Types[i].Fc_out);	    fprintf(Echo, "\tmax_subblocks: %d\n", Types[i].max_subblocks);	    fprintf(Echo, "\tmax_subblock_inputs: %d\n",		     Types[i].max_subblock_inputs);	    fprintf(Echo, "\tmax_subblock_outputs: %d\n",		     Types[i].max_subblock_outputs);	    fprintf(Echo, "\tnum_drivers: %d\n", Types[i].num_drivers);	    fprintf(Echo, "\tnum_receivers: %d\n", Types[i].num_receivers);	    fprintf(Echo, "\tindex: %d\n", Types[i].index);	    fprintf(Echo, "\n");	}    fclose(Echo);}

⌨️ 快捷键说明

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