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

📄 xml_arch.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <string.h>#include <assert.h>#include "util.h"#include "vpr_types.h"#include "ReadLine.h"#include "ezxml.h"#include "globals.h"#include "xml_arch.h"/* special type indexes, necessary for initialization initialization, everything afterwards   should use the pointers to these type indices*/ #define EMPTY_TYPE_INDEX 0#define IO_TYPE_INDEX 1    enum Fc_type{ FC_ABS, FC_FRAC, FC_FULL };/* Function prototypes */ static boolean IsWhitespace(char c);static void CountTokensInString(IN const char *Str,				 OUT int *Num,				 OUT int *Len);static char **GetNodeTokens(IN ezxml_t Node);static void CheckElement(IN ezxml_t Node,			  IN const char *Name);static void CheckText(IN ezxml_t Node);static void FreeNode(INOUT ezxml_t Node);static ezxml_t FindElement(IN ezxml_t Parent,			    IN const char *Name,			    IN boolean Required);static const char *FindProperty(IN ezxml_t Parent,				 IN const char *Name,				 IN boolean Required);static int CountChildren(IN ezxml_t Node,			  IN const char *Name);static void ParseFc(ezxml_t Node,		     enum Fc_type *Fc,		     float *Val);static void SetupEmptyType();static void SetupClassInf(ezxml_t Classes,			   t_type_descriptor * Type);static void SetupPinClasses(ezxml_t Classes,			     t_type_descriptor * Type);static void SetupPinLocations(ezxml_t Locations,			       t_type_descriptor * Type);static void SetupGridLocations(ezxml_t Locations,				t_type_descriptor * Type);static void SetupTypeTiming(ezxml_t timing,			     t_type_descriptor * Type);static void SetupSubblocksTcomb(ezxml_t timing,				 t_type_descriptor * Type);static void SetupSubblocksTSeq(ezxml_t timing_seq_in,				ezxml_t timing_seq_out,				t_type_descriptor * Type);static void Process_Fc(ezxml_t Fc_in_node,			ezxml_t Fc_out_node,			t_type_descriptor * Type);static void ProcessSubblocks(INOUT ezxml_t Parent,			      INOUT t_type_descriptor * Type,			      IN boolean timing_enabled);static void ProcessTypeProps(ezxml_t Node,			      t_type_descriptor * Type);static void ProcessChanWidthDistr(INOUT ezxml_t Node,				   OUT struct s_arch *arch);static void ProcessChanWidthDistrDir(INOUT ezxml_t Node,				      OUT t_chan * chan);static void ProcessLayout(INOUT ezxml_t Node,			   OUT struct s_arch *arch);static void ProcessDevice(INOUT ezxml_t Node,			   OUT struct s_arch *arch,			   IN boolean timing_enabled);static void ProcessIO(INOUT ezxml_t Node,		       IN boolean timing_enabled);static void ProcessTypes(INOUT ezxml_t Node,			  OUT t_type_descriptor ** Types,			  OUT int *NumTypes,			  IN boolean timing_enabled);static void ProcessSwitches(INOUT ezxml_t Node,			     OUT struct s_switch_inf **Switches,			     OUT int *NumSwitches,			     IN boolean timing_enabled);static void ProcessSegments(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);static void ProcessCB_SB(INOUT ezxml_t Node,			  INOUT boolean * list,			  IN int len);/* Returns TRUE if character is whatspace between tokens */     static booleanIsWhitespace(char c){    switch (c)	{	case ' ':	case '\t':	case '\r':	case '\n':	    return TRUE;	default:	    return FALSE;	}}/* Count tokens and length in all the Text children nodes of current node. */     static voidCountTokensInString(IN const char *Str,		    OUT int *Num,		    OUT int *Len){    boolean InToken;    *Num = 0;    *Len = 0;    InToken = FALSE;    while(*Str)	{	    if(IsWhitespace(*Str))		{		    InToken = FALSE;		}	    	    else				{		    if(!InToken)			{			    ++(*Num);			}		    ++(*Len);		    InToken = TRUE;		}	    ++Str;		/* Advance pointer */	}}/* Returns a token list of the text nodes of a given node. This * unlinks all the text nodes from the document */ static char **GetNodeTokens(IN ezxml_t Node){    int Count, Len;    char *Cur, *Dst;    boolean InToken;    char **Tokens;    	/* Count the tokens and find length of token data */ 	CountTokensInString(Node->txt, &Count, &Len);    	/* Error out if no tokens found */ 	if(Count < 1)	{	    printf(ERRTAG "Node '%s' on expected text data " 		    "but none was found.\n", Node->name);	}    Len = (sizeof(char) * Len) + /* Length of actual data */ 	(sizeof(char) * Count);	/* Null terminators */    	/* Alloc the pointer list and data list. Count the final 	 * empty string we will use as list terminator */ 	Tokens = (char **)my_malloc(sizeof(char *) * (Count + 1));    Dst = (char *)my_malloc(sizeof(char) * Len);    Count = 0;    	/* Copy data to tokens */ 	Cur = Node->txt;    InToken = FALSE;    while(*Cur)	{	    if(IsWhitespace(*Cur))		{		    if(InToken)			{			    *Dst = '\0';			    ++Dst;			}		    InToken = FALSE;		}	    	    else		{		    if(!InToken)			{			    Tokens[Count] = Dst;			    ++Count;			}		    *Dst = *Cur;		    ++Dst;		    InToken = TRUE;		}	    ++Cur;	}    if(InToken)	{			/* Null term final token */	    *Dst = '\0';	    ++Dst;	}    ezxml_set_txt(Node, "");    Tokens[Count] = NULL;	/* End of tokens marker is a NULL */    	/* Return the list */ 	return Tokens;}/* Checks the node is an element with name equal to one given */     static voidCheckElement(IN ezxml_t Node,	     IN const char *Name){    if(0 != strcmp(Node->name, Name))	{	    printf(ERRTAG		    "Element '%s' within element '%s' does match expected " 		    "element type of '%s'\n", Node->name, Node->parent->name,		    Name);	    exit(1);	}}/* Checks that the node has no remaining child nodes or property nodes,  * then unlinks the node from the tree which updates pointers and  * frees the memory */     static voidFreeNode(INOUT ezxml_t Node){    ezxml_t Cur;    char *Txt;    	/* Shouldn't have unprocessed properties */ 	if(Node->attr[0])	{	    printf(ERRTAG "Node '%s' has invalid property %s=\"%s\".\n",		    Node->name, Node->attr[0], Node->attr[1]);	    exit(1);	}    	/* Shouldn't have non-whitespace text */ 	Txt = Node->txt;    while(*Txt)	{	    if(!IsWhitespace(*Txt))		{		    printf(ERRTAG			    "Node '%s' has unexpected text '%s' within it.\n",			    Node->name, Node->txt);		    exit(1);		}	    ++Txt;	}    	/* We shouldn't have child items left */ 	Cur = Node->child;    if(Cur)	{	    printf(ERRTAG "Node '%s' on has invalid child node '%s'.\n",		    Node->name, Cur->name);	    exit(1);	}    	/* Now actually unlink and free the node */ 	ezxml_remove(Node);}/* Finds child element with given name and returns it. Errors out if * more than one instance exists. */ static ezxml_tFindElement(IN ezxml_t Parent,	    IN const char *Name,	    IN boolean Required){    ezxml_t Cur;    	/* Find the first node of correct name */ 	Cur = ezxml_child(Parent, Name);    	/* Error out if node isn't found but they required it */ 	if(Required)	{	    if(NULL == Cur)		{		    printf(ERRTAG			    "Element '%s' not found within element '%s'.\n",			    Name, Parent->name);		    exit(1);		}	}    	/* Look at next tag with same name and error out if exists */ 	if(Cur != NULL && Cur->next)	{	    printf(ERRTAG "Element '%s' found twice within element '%s'.\n",		    Name, Parent->name);	    exit(1);	}    return Cur;}static const char *FindProperty(IN ezxml_t Parent,	     IN const char *Name,	     IN boolean Required){    const char *Res;    Res = ezxml_attr(Parent, Name);    if(Required)	{	    if(NULL == Res)		{		    printf(ERRTAG			    "Required property '%s' not found for element '%s'.\n",			    Name, Parent->name);		    exit(1);		}	}    return Res;}/* Counts number of child elements in a container element.  * Name is the name of the child element.  * Errors if no occurances found. */     static intCountChildren(IN ezxml_t Node,	      IN const char *Name){    ezxml_t Cur, sibling;    int Count;    Count = 0;    Cur = Node->child;    while(Cur)	{	    if(strcmp(Cur->name, Name) == 0)		{		    ++Count;		}	    sibling = Cur->sibling;	    Cur = Cur->next;	    if(Cur == NULL)		{		    Cur = sibling;		}	}    	/* Error if no occurances found */ 	if(Count < 1)	{	    printf(ERRTAG "Expected node '%s' to have " 		    "child elements, but none found.\n", Node->name);	    exit(1);	}    return Count;}/* Figures out the Fc type and value for the given node. Unlinks the  * type and value. */     static voidParseFc(ezxml_t Node,	enum Fc_type *Fc,	float *Val){    const char *Prop;    Prop = FindProperty(Node, "type", TRUE);    if(0 == strcmp(Prop, "abs"))	{	    *Fc = FC_ABS;	}        else if(0 == strcmp(Prop, "frac"))	{	    *Fc = FC_FRAC;	}        else if(0 == strcmp(Prop, "full"))	{	    *Fc = FC_FULL;	}        else	{	    printf(ERRTAG "Invalid type '%s' for Fc. Only abs, frac " 		    "and full are allowed.\n", Prop);	    exit(1);	}    switch (*Fc)	{	case FC_FULL:	    *Val = 0.0;	    break;	case FC_ABS:	case FC_FRAC:	    *Val = atof(Node->txt);	    ezxml_set_attr(Node, "type", NULL);	    ezxml_set_txt(Node, "");	    break;	default:	    assert(0);	}    	/* Release the property */ 	ezxml_set_attr(Node, "type", NULL);}/* Set's up the classinf data of a type and counts the number of  * pins the type has. If capacity > 1, we need multiple sets of classes. * This correctly sets num_pins to include all the replicated but * unique pins that give the capacity. */     static voidSetupClassInf(ezxml_t Classes,	      t_type_descriptor * Type){    int i, k, CurClass, CurPin, NumClassPins;    ezxml_t Cur;    const char *Prop;    	/* Alloc class_inf structs */ 	Type->num_class = Type->capacity * CountChildren(Classes, "class");    Type->class_inf =	(t_class *) my_malloc(Type->num_class * sizeof(t_class));    	/* Make multiple passes to handle capacity with index increased each pass */ 	CurPin = 0;    CurClass = 0;    Type->num_pins = 0;    Type->num_drivers = 0;    Type->num_receivers = 0;    for(i = 0; i < Type->capacity; ++i)	{	    		/* Restart the parse tree at each node */ 		Cur = Classes->child;	    while(Cur)		{		    CheckElement(Cur, "class");		    			/* Count the number of pins in this class */ 			CountTokensInString(Cur->txt, &NumClassPins, &k);		    Type->num_pins += NumClassPins;		    			/* Alloc class structures */ 			Type->class_inf[CurClass].num_pins = NumClassPins;		    Type->class_inf[CurClass].pinlist =			(int *)my_malloc(NumClassPins * sizeof(int));		    for(k = 0; k < NumClassPins; ++k)			{			    Type->class_inf[CurClass].pinlist[k] = CurPin;			    ++CurPin;			}		    			/* Figure out class type */ 			Prop = FindProperty(Cur, "type", TRUE);		    if(0 == strcmp(Prop, "in"))			{			    Type->num_receivers += NumClassPins;			    Type->class_inf[CurClass].type = RECEIVER;			}		    		    else if(0 == strcmp(Prop, "out"))			{			    Type->num_drivers += NumClassPins;			    Type->class_inf[CurClass].type = DRIVER;			}		    		    else if(0 == strcmp(Prop, "global"))			{			    Type->class_inf[CurClass].type = RECEIVER;			}		    		    else			{			    printf(ERRTAG "Invalid pin class type '%s'.\n",				    Prop);			    exit(1);			}		    ++CurClass;		    Cur = Cur->next;		}	}}/* Allocs structures that describe pins and reads pin names. Sets * pin/class mappings. Unliinks the class descriptor nodes from XML. * For capacity > 1 pins and pinclasses are replicated because while * they share the same properties and setup, they are treated as  * being unique. */     static voidSetupPinClasses(ezxml_t Classes,		t_type_descriptor * Type){    int CurClass, i, j, CurPin, PinsPerSubtile, ClassesPerSubtile;    ezxml_t Cur, Prev;    const char *Prop;    boolean IsGlobal;    char **Tokens;    int *pin_used = NULL;    	/* Allocs and sets up the classinf data and counts pins */ 	SetupClassInf(Classes, Type);    PinsPerSubtile = Type->num_pins / Type->capacity;    ClassesPerSubtile = Type->num_class / Type->capacity;    	/* Alloc num_pin sized lists. Replicated pins don't have new names. */ 	Type->is_global_pin =	(boolean *) my_malloc(Type->num_pins * sizeof(boolean));    Type->pin_class = (int *)my_malloc(Type->num_pins * sizeof(int));    pin_used = (int *)my_malloc(Type->num_pins * sizeof(int));    for(i = 0; i < Type->num_pins; ++i)	{	    pin_used[i] = FALSE;	}    	/* Iterate over all pins */ 	CurClass = 0;    Cur = Classes->child;    while(Cur)	{	    CheckElement(Cur, "class");	    		/* Figure out if global class */ 		IsGlobal = FALSE;	    Prop = FindProperty(Cur, "type", TRUE);	    if(0 == strcmp(Prop, "global"))		{

⌨️ 快捷键说明

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