#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"
Go to the source code of this file.
Defines | |
#define | EMPTY_TYPE_INDEX 0 |
#define | IO_TYPE_INDEX 1 |
Enumerations | |
enum | Fc_type { FC_ABS, FC_FRAC, FC_FULL } |
Functions | |
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) |
static void | ProcessSubblocks (INOUT ezxml_t Parent, INOUT t_type_descriptor *Type, boolean timing_enabled) |
static void | ProcessTypes (INOUT ezxml_t Node, OUT t_type_descriptor **Types, OUT int *NumTypes, boolean timing_enabled) |
void | XmlReadArch (IN const char *ArchFile, IN boolean timing_enabled, OUT struct s_arch *arch, OUT t_type_descriptor **Types, OUT int *NumTypes) |
void | EchoArch (IN const char *EchoFile, IN const t_type_descriptor *Types, IN int NumTypes) |
#define EMPTY_TYPE_INDEX 0 |
Definition at line 12 of file xml_arch.c.
#define IO_TYPE_INDEX 1 |
Definition at line 13 of file xml_arch.c.
enum Fc_type |
Definition at line 14 of file xml_arch.c.
static void CheckElement | ( | IN ezxml_t | Node, | |
IN const char * | Name | |||
) | [static] |
Definition at line 216 of file xml_arch.c.
00218 { 00219 if(0 != strcmp(Node->name, Name)) 00220 { 00221 printf(ERRTAG 00222 "Element '%s' within element '%s' does match expected " 00223 "element type of '%s'\n", Node->name, Node->parent->name, 00224 Name); 00225 exit(1); 00226 } 00227 }
static void CheckText | ( | IN ezxml_t | Node | ) | [static] |
static int CountChildren | ( | IN ezxml_t | Node, | |
IN const char * | Name | |||
) | [static] |
Definition at line 335 of file xml_arch.c.
00337 { 00338 ezxml_t Cur, sibling; 00339 int Count; 00340 00341 Count = 0; 00342 Cur = Node->child; 00343 while(Cur) 00344 { 00345 if(strcmp(Cur->name, Name) == 0) 00346 { 00347 ++Count; 00348 } 00349 sibling = Cur->sibling; 00350 Cur = Cur->next; 00351 if(Cur == NULL) 00352 { 00353 Cur = sibling; 00354 } 00355 } 00356 00357 /* Error if no occurances found */ 00358 if(Count < 1) 00359 { 00360 printf(ERRTAG "Expected node '%s' to have " 00361 "child elements, but none found.\n", Node->name); 00362 exit(1); 00363 } 00364 return Count; 00365 }
static void CountTokensInString | ( | IN const char * | Str, | |
OUT int * | Num, | |||
OUT int * | Len | |||
) | [static] |
Definition at line 112 of file xml_arch.c.
00115 { 00116 boolean InToken; 00117 *Num = 0; 00118 *Len = 0; 00119 InToken = FALSE; 00120 while(*Str) 00121 { 00122 if(IsWhitespace(*Str)) 00123 { 00124 InToken = FALSE; 00125 } 00126 00127 else 00128 00129 { 00130 if(!InToken) 00131 { 00132 ++(*Num); 00133 } 00134 ++(*Len); 00135 InToken = TRUE; 00136 } 00137 ++Str; /* Advance pointer */ 00138 } 00139 }
void EchoArch | ( | IN const char * | EchoFile, | |
IN const t_type_descriptor * | Types, | |||
IN int | NumTypes | |||
) |
Definition at line 2080 of file xml_arch.c.
02083 { 02084 int i, j, k; 02085 02086 FILE * Echo; 02087 Echo = my_fopen(EchoFile, "w"); 02088 for(i = 0; i < NumTypes; ++i) 02089 { 02090 fprintf(Echo, "Type: \"%s\"\n", Types[i].name); 02091 fprintf(Echo, "\tcapacity: %d\n", Types[i].capacity); 02092 fprintf(Echo, "\theight: %d\n", Types[i].height); 02093 if(Types[i].num_pins > 0) 02094 { 02095 for(j = 0; j < Types[i].height; ++j) 02096 { 02097 fprintf(Echo, 02098 "\tpinloc[%d] TOP LEFT BOTTOM RIGHT:\n", 02099 j); 02100 for(k = 0; k < Types[i].num_pins; ++k) 02101 { 02102 fprintf(Echo, "\t\t%d %d %d %d\n", 02103 Types[i].pinloc[j][TOP][k], 02104 Types[i].pinloc[j][LEFT][k], 02105 Types[i].pinloc[j][BOTTOM][k], 02106 Types[i].pinloc[j][RIGHT][k]); 02107 } 02108 } 02109 } 02110 fprintf(Echo, "\tnum_pins (scaled for capacity): %d\n", 02111 Types[i].num_pins); 02112 if(Types[i].num_pins > 0) 02113 { 02114 fprintf(Echo, "\tPins: NAME CLASS IS_GLOBAL\n"); 02115 for(j = 0; j < Types[i].num_pins; ++j) 02116 { 02117 fprintf(Echo, "\t\t%d %d %s\n", j, 02118 Types[i].pin_class[j], 02119 (Types[i]. 02120 is_global_pin[j] ? "TRUE" : "FALSE")); 02121 } 02122 } 02123 fprintf(Echo, "\tnum_class: %d\n", Types[i].num_class); 02124 if(Types[i].num_class > 0) 02125 { 02126 for(j = 0; j < Types[i].num_class; ++j) 02127 { 02128 switch (Types[i].class_inf[j].type) 02129 { 02130 case RECEIVER: 02131 fprintf(Echo, "\t\tType: RECEIVER\n"); 02132 break; 02133 case DRIVER: 02134 fprintf(Echo, "\t\tType: DRIVER\n"); 02135 break; 02136 case OPEN: 02137 fprintf(Echo, "\t\tType: OPEN\n"); 02138 break; 02139 default: 02140 fprintf(Echo, "\t\tType: UNKNOWN\n"); 02141 break; 02142 } 02143 fprintf(Echo, "\t\t\tnum_pins: %d\n", 02144 Types[i].class_inf[j].num_pins); 02145 fprintf(Echo, "\t\t\tpins: "); /* No \n */ 02146 for(k = 0; k < Types[i].class_inf[j].num_pins; 02147 ++k) 02148 { 02149 fprintf(Echo, "%d ", Types[i].class_inf[j].pinlist[k]); /* No \n */ 02150 } 02151 fprintf(Echo, "\n"); /* End current line */ 02152 } 02153 } 02154 fprintf(Echo, "\tis_Fc_frac: %s\n", 02155 (Types[i].is_Fc_frac ? "TRUE" : "FALSE")); 02156 fprintf(Echo, "\tis_Fc_out_full_flex: %s\n", 02157 (Types[i].is_Fc_out_full_flex ? "TRUE" : "FALSE")); 02158 fprintf(Echo, "\tFc_in: %f\n", Types[i].Fc_in); 02159 fprintf(Echo, "\tFc_out: %f\n", Types[i].Fc_out); 02160 fprintf(Echo, "\tmax_subblocks: %d\n", Types[i].max_subblocks); 02161 fprintf(Echo, "\tmax_subblock_inputs: %d\n", 02162 Types[i].max_subblock_inputs); 02163 fprintf(Echo, "\tmax_subblock_outputs: %d\n", 02164 Types[i].max_subblock_outputs); 02165 fprintf(Echo, "\tnum_drivers: %d\n", Types[i].num_drivers); 02166 fprintf(Echo, "\tnum_receivers: %d\n", Types[i].num_receivers); 02167 fprintf(Echo, "\tindex: %d\n", Types[i].index); 02168 fprintf(Echo, "\n"); 02169 } 02170 fclose(Echo); 02171 }
static ezxml_t FindElement | ( | IN ezxml_t | Parent, | |
IN const char * | Name, | |||
IN boolean | Required | |||
) | [static] |
Definition at line 279 of file xml_arch.c.
00282 { 00283 ezxml_t Cur; 00284 00285 /* Find the first node of correct name */ 00286 Cur = ezxml_child(Parent, Name); 00287 00288 /* Error out if node isn't found but they required it */ 00289 if(Required) 00290 { 00291 if(NULL == Cur) 00292 { 00293 printf(ERRTAG 00294 "Element '%s' not found within element '%s'.\n", 00295 Name, Parent->name); 00296 exit(1); 00297 } 00298 } 00299 00300 /* Look at next tag with same name and error out if exists */ 00301 if(Cur != NULL && Cur->next) 00302 { 00303 printf(ERRTAG "Element '%s' found twice within element '%s'.\n", 00304 Name, Parent->name); 00305 exit(1); 00306 } 00307 return Cur; 00308 }
static const char * FindProperty | ( | IN ezxml_t | Parent, | |
IN const char * | Name, | |||
IN boolean | Required | |||
) | [static] |
Definition at line 310 of file xml_arch.c.
00313 { 00314 const char *Res; 00315 00316 Res = ezxml_attr(Parent, Name); 00317 if(Required) 00318 { 00319 if(NULL == Res) 00320 { 00321 printf(ERRTAG 00322 "Required property '%s' not found for element '%s'.\n", 00323 Name, Parent->name); 00324 exit(1); 00325 } 00326 } 00327 return Res; 00328 }
static void FreeNode | ( | INOUT ezxml_t | Node | ) | [static] |
Definition at line 234 of file xml_arch.c.
00235 { 00236 ezxml_t Cur; 00237 char *Txt; 00238 00239 00240 /* Shouldn't have unprocessed properties */ 00241 if(Node->attr[0]) 00242 { 00243 printf(ERRTAG "Node '%s' has invalid property %s=\"%s\".\n", 00244 Node->name, Node->attr[0], Node->attr[1]); 00245 exit(1); 00246 } 00247 00248 /* Shouldn't have non-whitespace text */ 00249 Txt = Node->txt; 00250 while(*Txt) 00251 { 00252 if(!IsWhitespace(*Txt)) 00253 { 00254 printf(ERRTAG 00255 "Node '%s' has unexpected text '%s' within it.\n", 00256 Node->name, Node->txt); 00257 exit(1); 00258 } 00259 ++Txt; 00260 } 00261 00262 /* We shouldn't have child items left */ 00263 Cur = Node->child; 00264 if(Cur) 00265 { 00266 printf(ERRTAG "Node '%s' on has invalid child node '%s'.\n", 00267 Node->name, Cur->name); 00268 exit(1); 00269 } 00270 00271 /* Now actually unlink and free the node */ 00272 ezxml_remove(Node); 00273 }
static char ** GetNodeTokens | ( | IN ezxml_t | Node | ) | [static] |
Definition at line 145 of file xml_arch.c.
00146 { 00147 int Count, Len; 00148 char *Cur, *Dst; 00149 00150 boolean InToken; 00151 char **Tokens; 00152 00153 00154 /* Count the tokens and find length of token data */ 00155 CountTokensInString(Node->txt, &Count, &Len); 00156 00157 /* Error out if no tokens found */ 00158 if(Count < 1) 00159 { 00160 printf(ERRTAG "Tag '%s' expected enclosed text data " 00161 "but none was found.\n", Node->name); 00162 exit(1); 00163 } 00164 Len = (sizeof(char) * Len) + /* Length of actual data */ 00165 (sizeof(char) * Count); /* Null terminators */ 00166 00167 /* Alloc the pointer list and data list. Count the final 00168 * empty string we will use as list terminator */ 00169 Tokens = (char **)my_malloc(sizeof(char *) * (Count + 1)); 00170 Dst = (char *)my_malloc(sizeof(char) * Len); 00171 Count = 0; 00172 00173 /* Copy data to tokens */ 00174 Cur = Node->txt; 00175 InToken = FALSE; 00176 while(*Cur) 00177 { 00178 if(IsWhitespace(*Cur)) 00179 { 00180 if(InToken) 00181 { 00182 *Dst = '\0'; 00183 ++Dst; 00184 } 00185 InToken = FALSE; 00186 } 00187 00188 else 00189 { 00190 if(!InToken) 00191 { 00192 Tokens[Count] = Dst; 00193 ++Count; 00194 } 00195 *Dst = *Cur; 00196 ++Dst; 00197 InToken = TRUE; 00198 } 00199 ++Cur; 00200 } 00201 if(InToken) 00202 { /* Null term final token */ 00203 *Dst = '\0'; 00204 ++Dst; 00205 } 00206 ezxml_set_txt(Node, ""); 00207 Tokens[Count] = NULL; /* End of tokens marker is a NULL */ 00208 00209 /* Return the list */ 00210 return Tokens; 00211 }
static boolean IsWhitespace | ( | char | c | ) | [static] |
Definition at line 95 of file xml_arch.c.
00096 { 00097 switch (c) 00098 { 00099 case ' ': 00100 case '\t': 00101 case '\r': 00102 case '\n': 00103 return TRUE; 00104 default: 00105 return FALSE; 00106 } 00107 }
Definition at line 371 of file xml_arch.c.
00374 { 00375 const char *Prop; 00376 00377 Prop = FindProperty(Node, "type", TRUE); 00378 if(0 == strcmp(Prop, "abs")) 00379 { 00380 *Fc = FC_ABS; 00381 } 00382 00383 else if(0 == strcmp(Prop, "frac")) 00384 { 00385 *Fc = FC_FRAC; 00386 } 00387 00388 else if(0 == strcmp(Prop, "full")) 00389 { 00390 *Fc = FC_FULL; 00391 } 00392 00393 else 00394 { 00395 printf(ERRTAG "Invalid type '%s' for Fc. Only abs, frac " 00396 "and full are allowed.\n", Prop); 00397 exit(1); 00398 } 00399 switch (*Fc) 00400 { 00401 case FC_FULL: 00402 *Val = 0.0; 00403 break; 00404 case FC_ABS: 00405 case FC_FRAC: 00406 *Val = atof(Node->txt); 00407 ezxml_set_attr(Node, "type", NULL); 00408 ezxml_set_txt(Node, ""); 00409 break; 00410 default: 00411 assert(0); 00412 } 00413 00414 /* Release the property */ 00415 ezxml_set_attr(Node, "type", NULL); 00416 }
static void Process_Fc | ( | ezxml_t | Fc_in_node, | |
ezxml_t | Fc_out_node, | |||
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 1018 of file xml_arch.c.
01021 { 01022 enum Fc_type Type_in; 01023 enum Fc_type Type_out; 01024 01025 ParseFc(Fc_in_node, &Type_in, &Type->Fc_in); 01026 ParseFc(Fc_out_node, &Type_out, &Type->Fc_out); 01027 if(FC_FULL == Type_in) 01028 { 01029 printf(ERRTAG "'full' Fc type isn't allowed for Fc_in.\n"); 01030 exit(1); 01031 } 01032 Type->is_Fc_out_full_flex = FALSE; 01033 Type->is_Fc_frac = FALSE; 01034 if(FC_FULL == Type_out) 01035 { 01036 Type->is_Fc_out_full_flex = TRUE; 01037 } 01038 01039 else if(Type_in != Type_out) 01040 { 01041 printf(ERRTAG 01042 "Fc_in and Fc_out must have same type unless Fc_out has type 'full'.\n"); 01043 exit(1); 01044 } 01045 if(FC_FRAC == Type_in) 01046 { 01047 Type->is_Fc_frac = TRUE; 01048 } 01049 }
Definition at line 1882 of file xml_arch.c.
01885 { 01886 const char *tmp = NULL; 01887 int i; 01888 01889 01890 /* Check the type. We only support 'pattern' for now. 01891 * Should add frac back eventually. */ 01892 tmp = FindProperty(Node, "type", TRUE); 01893 if(0 == strcmp(tmp, "pattern")) 01894 { 01895 i = 0; 01896 01897 /* Get the content string */ 01898 tmp = Node->txt; 01899 while(*tmp) 01900 { 01901 switch (*tmp) 01902 { 01903 case ' ': 01904 break; 01905 case 'T': 01906 case '1': 01907 if(i >= len) 01908 { 01909 printf(ERRTAG 01910 "CB or SB depopulation is too long. It " 01911 01912 "should be (length) symbols for CBs and (length+1) " 01913 "symbols for SBs.\n"); 01914 exit(1); 01915 } 01916 list[i] = TRUE; 01917 ++i; 01918 break; 01919 case 'F': 01920 case '0': 01921 if(i >= len) 01922 { 01923 printf(ERRTAG 01924 "CB or SB depopulation is too long. It " 01925 01926 "should be (length) symbols for CBs and (length+1) " 01927 "symbols for SBs.\n"); 01928 exit(1); 01929 } 01930 list[i] = FALSE; 01931 ++i; 01932 break; 01933 default: 01934 printf(ERRTAG "Invalid character %c in CB or " 01935 "SB depopulation list.\n", *tmp); 01936 exit(1); 01937 } 01938 ++tmp; 01939 } 01940 if(i < len) 01941 { 01942 printf(ERRTAG "CB or SB depopulation is too short. It " 01943 "should be (length) symbols for CBs and (length+1) " 01944 "symbols for SBs.\n"); 01945 exit(1); 01946 } 01947 01948 /* Free content string */ 01949 ezxml_set_txt(Node, ""); 01950 } 01951 01952 else 01953 { 01954 printf(ERRTAG "'%s' is not a valid type for specifying " 01955 "cb and sb depopulation.\n", tmp); 01956 exit(1); 01957 } 01958 ezxml_set_attr(Node, "type", NULL); 01959 }
Definition at line 1273 of file xml_arch.c.
01275 { 01276 const char *Prop; 01277 01278 ezxml_t Cur; 01279 Cur = FindElement(Node, "io", TRUE); 01280 Prop = FindProperty(Cur, "width", TRUE); 01281 arch->Chans.chan_width_io = atof(Prop); 01282 ezxml_set_attr(Cur, "width", NULL); 01283 FreeNode(Cur); 01284 Cur = FindElement(Node, "x", TRUE); 01285 ProcessChanWidthDistrDir(Cur, &arch->Chans.chan_x_dist); 01286 FreeNode(Cur); 01287 Cur = FindElement(Node, "y", TRUE); 01288 ProcessChanWidthDistrDir(Cur, &arch->Chans.chan_y_dist); 01289 FreeNode(Cur); 01290 }
Definition at line 1296 of file xml_arch.c.
01298 { 01299 const char *Prop; 01300 01301 boolean hasXpeak, hasWidth, hasDc; 01302 hasXpeak = hasWidth = hasDc = FALSE; 01303 Prop = FindProperty(Node, "distr", TRUE); 01304 if(strcmp(Prop, "uniform") == 0) 01305 { 01306 chan->type = UNIFORM; 01307 } 01308 else if(strcmp(Prop, "gaussian") == 0) 01309 { 01310 chan->type = GAUSSIAN; 01311 hasXpeak = hasWidth = hasDc = TRUE; 01312 } 01313 else if(strcmp(Prop, "pulse") == 0) 01314 { 01315 chan->type = PULSE; 01316 hasXpeak = hasWidth = hasDc = TRUE; 01317 } 01318 else if(strcmp(Prop, "delta") == 0) 01319 { 01320 hasXpeak = hasDc = TRUE; 01321 chan->type = DELTA; 01322 } 01323 else 01324 { 01325 printf(ERRTAG "Unknown property %s for chan_width_distr x\n", 01326 Prop); 01327 exit(1); 01328 } 01329 ezxml_set_attr(Node, "distr", NULL); 01330 Prop = FindProperty(Node, "peak", TRUE); 01331 chan->peak = atof(Prop); 01332 ezxml_set_attr(Node, "peak", NULL); 01333 Prop = FindProperty(Node, "width", hasWidth); 01334 if(hasWidth) 01335 { 01336 chan->width = atof(Prop); 01337 ezxml_set_attr(Node, "width", NULL); 01338 } 01339 Prop = FindProperty(Node, "xpeak", hasXpeak); 01340 if(hasXpeak) 01341 { 01342 chan->xpeak = atof(Prop); 01343 ezxml_set_attr(Node, "xpeak", NULL); 01344 } 01345 Prop = FindProperty(Node, "dc", hasDc); 01346 if(hasDc) 01347 { 01348 chan->dc = atof(Prop); 01349 ezxml_set_attr(Node, "dc", NULL); 01350 } 01351 }
static void ProcessDevice | ( | INOUT ezxml_t | Node, | |
OUT struct s_arch * | arch, | |||
IN boolean | timing_enabled | |||
) | [static] |
Definition at line 1177 of file xml_arch.c.
01180 { 01181 const char *Prop; 01182 01183 ezxml_t Cur; 01184 Cur = FindElement(Node, "sizing", TRUE); 01185 arch->R_minW_nmos = 0; 01186 Prop = FindProperty(Cur, "R_minW_nmos", timing_enabled); 01187 if(Prop != NULL) 01188 { 01189 arch->R_minW_nmos = atof(Prop); 01190 ezxml_set_attr(Cur, "R_minW_nmos", NULL); 01191 } 01192 arch->R_minW_pmos = 0; 01193 Prop = FindProperty(Cur, "R_minW_pmos", timing_enabled); 01194 if(Prop != NULL) 01195 { 01196 arch->R_minW_pmos = atof(Prop); 01197 ezxml_set_attr(Cur, "R_minW_pmos", NULL); 01198 } 01199 arch->ipin_mux_trans_size = 0; 01200 Prop = FindProperty(Cur, "ipin_mux_trans_size", FALSE); 01201 if(Prop != NULL) 01202 { 01203 arch->ipin_mux_trans_size = atof(Prop); 01204 ezxml_set_attr(Cur, "ipin_mux_trans_size", NULL); 01205 } 01206 FreeNode(Cur); 01207 Cur = FindElement(Node, "timing", timing_enabled); 01208 if(Cur != NULL) 01209 { 01210 arch->C_ipin_cblock = 0; 01211 Prop = FindProperty(Cur, "C_ipin_cblock", FALSE); 01212 if(Prop != NULL) 01213 { 01214 arch->C_ipin_cblock = atof(Prop); 01215 ezxml_set_attr(Cur, "C_ipin_cblock", NULL); 01216 } 01217 arch->T_ipin_cblock = 0; 01218 Prop = FindProperty(Cur, "T_ipin_cblock", FALSE); 01219 if(Prop != NULL) 01220 { 01221 arch->T_ipin_cblock = atof(Prop); 01222 ezxml_set_attr(Cur, "T_ipin_cblock", NULL); 01223 } 01224 FreeNode(Cur); 01225 } 01226 Cur = FindElement(Node, "area", TRUE); 01227 Prop = FindProperty(Cur, "grid_logic_tile_area", FALSE); 01228 arch->grid_logic_tile_area = 0; 01229 if(Prop != NULL) 01230 { 01231 arch->grid_logic_tile_area = atof(Prop); 01232 ezxml_set_attr(Cur, "grid_logic_tile_area", NULL); 01233 } 01234 FreeNode(Cur); 01235 Cur = FindElement(Node, "chan_width_distr", FALSE); 01236 if(Cur != NULL) 01237 { 01238 ProcessChanWidthDistr(Cur, arch); 01239 FreeNode(Cur); 01240 } 01241 Cur = FindElement(Node, "switch_block", TRUE); 01242 Prop = FindProperty(Cur, "type", TRUE); 01243 if(strcmp(Prop, "wilton") == 0) 01244 { 01245 arch->SBType = WILTON; 01246 } 01247 else if(strcmp(Prop, "universal") == 0) 01248 { 01249 arch->SBType = UNIVERSAL; 01250 } 01251 else if(strcmp(Prop, "subset") == 0) 01252 { 01253 arch->SBType = SUBSET; 01254 } 01255 else 01256 { 01257 printf(ERRTAG "Unknown property %s for switch block type x\n", 01258 Prop); 01259 exit(1); 01260 } 01261 ezxml_set_attr(Cur, "type", NULL); 01262 Prop = FindProperty(Cur, "fs", TRUE); 01263 arch->Fs = my_atoi(Prop); 01264 ezxml_set_attr(Cur, "fs", NULL); 01265 FreeNode(Cur); 01266 }
Definition at line 1386 of file xml_arch.c.
01388 { 01389 const char *Prop; 01390 01391 ezxml_t Cur, Cur2; 01392 int i, j; 01393 01394 t_type_descriptor * type; 01395 int num_inputs, num_outputs, num_clocks, num_pins, capacity, t_in, t_out; 01396 enum 01397 { INCLASS = 0, OUTCLASS = 1, CLKCLASS = 2 }; 01398 01399 type = &type_descriptors[IO_TYPE->index]; 01400 num_inputs = 1; 01401 num_outputs = 1; 01402 num_clocks = 1; 01403 CheckElement(Node, "io"); 01404 type->name = ".io"; 01405 type->height = 1; 01406 01407 /* Load capacity */ 01408 Prop = FindProperty(Node, "capacity", TRUE); 01409 capacity = my_atoi(Prop); 01410 type->capacity = capacity; 01411 ezxml_set_attr(Node, "capacity", NULL); 01412 01413 /* Load Fc */ 01414 Cur = FindElement(Node, "fc_in", TRUE); 01415 Cur2 = FindElement(Node, "fc_out", TRUE); 01416 Process_Fc(Cur, Cur2, type); 01417 FreeNode(Cur); 01418 FreeNode(Cur2); 01419 01420 /* Initialize and setup type */ 01421 num_pins = 3 * capacity; 01422 type->num_pins = num_pins; 01423 type->num_drivers = num_outputs * capacity; 01424 type->num_receivers = num_inputs * capacity; 01425 type->pinloc = 01426 (int ***)alloc_matrix3(0, 0, 0, 3, 0, num_pins - 1, sizeof(int)); 01427 01428 /* Jason Luu - September 5, 2007 01429 * To treat IOs as any other block in routing, need to blackbox 01430 * as having physical pins on all sides. This is a hack. */ 01431 for(i = 0; i < num_pins; ++i) 01432 { 01433 for(j = 0; j < 4; ++j) 01434 { 01435 type->pinloc[0][j][i] = 1; 01436 } 01437 } 01438 01439 /* Three fixed classes. In, Out, Clock */ 01440 type->num_class = 3 * capacity; 01441 type->class_inf = 01442 (struct s_class *)my_malloc(sizeof(struct s_class) * 3 * capacity); 01443 type->pin_class = (int *)my_malloc(sizeof(int) * num_pins); 01444 type->is_global_pin = (boolean *) my_malloc(sizeof(boolean) * num_pins); 01445 for(j = 0; j < capacity; ++j) 01446 { 01447 01448 /* Three fixed classes. In, Out, Clock */ 01449 type->class_inf[3 * j + INCLASS].num_pins = num_inputs; 01450 type->class_inf[3 * j + INCLASS].type = RECEIVER; 01451 type->class_inf[3 * j + INCLASS].pinlist = 01452 (int *)my_malloc(sizeof(int) * num_inputs); 01453 for(i = 0; i < num_inputs; ++i) 01454 { 01455 type->class_inf[3 * j + INCLASS].pinlist[i] = 01456 num_pins * j / capacity + i; 01457 type->pin_class[num_pins * j / capacity + i] = 01458 3 * j + INCLASS; 01459 type->is_global_pin[num_pins * j / capacity + i] = FALSE; 01460 } 01461 type->class_inf[3 * j + OUTCLASS].num_pins = num_outputs; 01462 type->class_inf[3 * j + OUTCLASS].type = DRIVER; 01463 type->class_inf[3 * j + OUTCLASS].pinlist = 01464 (int *)my_malloc(sizeof(int) * num_outputs); 01465 for(i = 0; i < num_outputs; ++i) 01466 { 01467 type->class_inf[3 * j + OUTCLASS].pinlist[i] = 01468 num_pins * j / capacity + i + num_inputs; 01469 type->pin_class[num_pins * j / capacity + i + 01470 num_inputs] = 3 * j + OUTCLASS; 01471 type->is_global_pin[num_pins * j / capacity + i + 01472 num_inputs] = FALSE; 01473 } 01474 type->class_inf[3 * j + CLKCLASS].num_pins = num_clocks; 01475 type->class_inf[3 * j + CLKCLASS].type = RECEIVER; 01476 type->class_inf[3 * j + CLKCLASS].pinlist = 01477 (int *)my_malloc(sizeof(int) * num_clocks); 01478 for(i = 0; i < num_clocks; ++i) 01479 { 01480 type->class_inf[3 * j + CLKCLASS].pinlist[i] = 01481 num_pins * j / capacity + i + num_inputs + 01482 num_outputs; 01483 type->pin_class[num_pins * j / capacity + i + 01484 num_inputs + num_outputs] = 01485 3 * j + CLKCLASS; 01486 type->is_global_pin[num_pins * j / capacity + i + 01487 num_inputs + num_outputs] = TRUE; 01488 } 01489 } 01490 type->max_subblocks = 1; 01491 type->max_subblock_inputs = 1; 01492 type->max_subblock_outputs = 1; 01493 01494 /* Always at boundary */ 01495 type->num_grid_loc_def = 1; 01496 type->grid_loc_def = 01497 (struct s_grid_loc_def *)my_calloc(1, sizeof(struct s_grid_loc_def)); 01498 type->grid_loc_def[0].grid_loc_type = BOUNDARY; 01499 type->grid_loc_def[0].priority = 0; 01500 t_in = -1; 01501 t_out = -1; 01502 Prop = FindProperty(Node, "t_inpad", timing_enabled); 01503 if(Prop != NULL) 01504 { 01505 t_in = atof(Prop); 01506 ezxml_set_attr(Node, "t_inpad", NULL); 01507 } 01508 Prop = FindProperty(Node, "t_outpad", timing_enabled); 01509 if(Prop != NULL) 01510 { 01511 t_out = atof(Prop); 01512 ezxml_set_attr(Node, "t_outpad", NULL); 01513 } 01514 if(timing_enabled) 01515 { 01516 type->type_timing_inf.T_fb_ipin_to_sblk_ipin = 0; 01517 type->type_timing_inf.T_sblk_opin_to_fb_opin = 0; 01518 type->type_timing_inf.T_sblk_opin_to_sblk_ipin = 0; 01519 type->type_timing_inf.T_subblock = 01520 (t_T_subblock *) my_malloc(sizeof(t_T_subblock)); 01521 type->type_timing_inf.T_subblock[0].T_comb = 01522 (float **)my_malloc(sizeof(float *)); 01523 type->type_timing_inf.T_subblock[0].T_comb[0] = 01524 (float *)my_malloc(sizeof(float)); 01525 type->type_timing_inf.T_subblock[0].T_comb[0][0] = t_out; 01526 type->type_timing_inf.T_subblock[0].T_seq_in = 01527 (float *)my_malloc(sizeof(float)); 01528 type->type_timing_inf.T_subblock[0].T_seq_in[0] = 0; 01529 type->type_timing_inf.T_subblock[0].T_seq_out = 01530 (float *)my_malloc(sizeof(float)); 01531 type->type_timing_inf.T_subblock[0].T_seq_out[0] = t_in; 01532 } 01533 }
Definition at line 1136 of file xml_arch.c.
01138 { 01139 const char *Prop; 01140 01141 arch->clb_grid.IsAuto = TRUE; 01142 01143 /* Load width and height if applicable */ 01144 Prop = FindProperty(Node, "width", FALSE); 01145 if(Prop != NULL) 01146 { 01147 arch->clb_grid.IsAuto = FALSE; 01148 arch->clb_grid.W = my_atoi(Prop); 01149 ezxml_set_attr(Node, "width", NULL); 01150 Prop = FindProperty(Node, "height", TRUE); 01151 if(Prop != NULL) 01152 { 01153 arch->clb_grid.H = my_atoi(Prop); 01154 ezxml_set_attr(Node, "height", NULL); 01155 } 01156 } 01157 01158 /* Load aspect ratio if applicable */ 01159 Prop = FindProperty(Node, "auto", arch->clb_grid.IsAuto); 01160 if(Prop != NULL) 01161 { 01162 if(arch->clb_grid.IsAuto == FALSE) 01163 { 01164 printf(ERRTAG 01165 "Auto-sizing, width and height cannot be specified\n"); 01166 } 01167 arch->clb_grid.Aspect = atof(Prop); 01168 ezxml_set_attr(Node, "auto", NULL); 01169 } 01170 }
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] |
Definition at line 1679 of file xml_arch.c.
01685 { 01686 int i, j, length; 01687 const char *tmp; 01688 01689 ezxml_t SubElem; 01690 ezxml_t Node; 01691 01692 /* Count the number of segs and check they are in fact 01693 * of segment elements. */ 01694 *NumSegs = CountChildren(Parent, "segment"); 01695 01696 /* Alloc segment list */ 01697 *Segs = NULL; 01698 if(*NumSegs > 0) 01699 { 01700 *Segs = 01701 (struct s_segment_inf *)my_malloc(*NumSegs * 01702 sizeof(struct 01703 s_segment_inf)); 01704 memset(*Segs, 0, (*NumSegs * sizeof(struct s_segment_inf))); 01705 } 01706 01707 /* Load the segments. */ 01708 for(i = 0; i < *NumSegs; ++i) 01709 { 01710 Node = ezxml_child(Parent, "segment"); 01711 01712 /* Get segment length */ 01713 length = 1; /* DEFAULT */ 01714 tmp = FindProperty(Node, "length", FALSE); 01715 if(tmp) 01716 { 01717 if(strcmp(tmp, "longline") == 0) 01718 { 01719 (*Segs)[i].longline = TRUE; 01720 } 01721 else 01722 { 01723 length = my_atoi(tmp); 01724 } 01725 } 01726 (*Segs)[i].length = length; 01727 ezxml_set_attr(Node, "length", NULL); 01728 01729 /* Get the frequency */ 01730 (*Segs)[i].frequency = 1; /* DEFAULT */ 01731 tmp = FindProperty(Node, "freq", FALSE); 01732 if(tmp) 01733 { 01734 (*Segs)[i].frequency = (int) (atof(tmp) * MAX_CHANNEL_WIDTH); 01735 } 01736 ezxml_set_attr(Node, "freq", NULL); 01737 01738 /* Get timing info */ 01739 (*Segs)[i].Rmetal = 0; /* DEFAULT */ 01740 tmp = FindProperty(Node, "Rmetal", timing_enabled); 01741 if(tmp) 01742 { 01743 (*Segs)[i].Rmetal = atof(tmp); 01744 } 01745 ezxml_set_attr(Node, "Rmetal", NULL); 01746 (*Segs)[i].Cmetal = 0; /* DEFAULT */ 01747 tmp = FindProperty(Node, "Cmetal", timing_enabled); 01748 if(tmp) 01749 { 01750 (*Segs)[i].Cmetal = atof(tmp); 01751 } 01752 ezxml_set_attr(Node, "Cmetal", NULL); 01753 01754 /* Get the type */ 01755 tmp = FindProperty(Node, "type", TRUE); 01756 if(0 == strcmp(tmp, "bidir")) 01757 { 01758 (*Segs)[i].directionality = BI_DIRECTIONAL; 01759 } 01760 01761 else if(0 == strcmp(tmp, "unidir")) 01762 { 01763 (*Segs)[i].directionality = UNI_DIRECTIONAL; 01764 } 01765 01766 else 01767 { 01768 printf(ERRTAG "Invalid switch type '%s'.\n", tmp); 01769 exit(1); 01770 } 01771 ezxml_set_attr(Node, "type", NULL); 01772 01773 /* Get the wire and opin switches, or mux switch if unidir */ 01774 if(UNI_DIRECTIONAL == (*Segs)[i].directionality) 01775 { 01776 SubElem = FindElement(Node, "mux", TRUE); 01777 tmp = FindProperty(SubElem, "name", TRUE); 01778 01779 /* Match names */ 01780 for(j = 0; j < NumSwitches; ++j) 01781 { 01782 if(0 == strcmp(tmp, Switches[j].name)) 01783 { 01784 break; /* End loop so j is where we want it */ 01785 } 01786 } 01787 if(j >= NumSwitches) 01788 { 01789 printf(ERRTAG "'%s' is not a valid mux name.\n", 01790 tmp); 01791 exit(1); 01792 } 01793 ezxml_set_attr(SubElem, "name", NULL); 01794 FreeNode(SubElem); 01795 01796 /* Unidir muxes must have the same switch 01797 * for wire and opin fanin since there is 01798 * really only the mux in unidir. */ 01799 (*Segs)[i].wire_switch = j; 01800 (*Segs)[i].opin_switch = j; 01801 } 01802 01803 else 01804 { 01805 assert(BI_DIRECTIONAL == (*Segs)[i].directionality); 01806 SubElem = FindElement(Node, "wire_switch", TRUE); 01807 tmp = FindProperty(SubElem, "name", TRUE); 01808 01809 /* Match names */ 01810 for(j = 0; j < NumSwitches; ++j) 01811 { 01812 if(0 == strcmp(tmp, Switches[j].name)) 01813 { 01814 break; /* End loop so j is where we want it */ 01815 } 01816 } 01817 if(j >= NumSwitches) 01818 { 01819 printf(ERRTAG 01820 "'%s' is not a valid wire_switch name.\n", 01821 tmp); 01822 exit(1); 01823 } 01824 (*Segs)[i].wire_switch = j; 01825 ezxml_set_attr(SubElem, "name", NULL); 01826 FreeNode(SubElem); 01827 SubElem = FindElement(Node, "opin_switch", TRUE); 01828 tmp = FindProperty(SubElem, "name", TRUE); 01829 01830 /* Match names */ 01831 for(j = 0; j < NumSwitches; ++j) 01832 { 01833 if(0 == strcmp(tmp, Switches[j].name)) 01834 { 01835 break; /* End loop so j is where we want it */ 01836 } 01837 } 01838 if(j >= NumSwitches) 01839 { 01840 printf(ERRTAG 01841 "'%s' is not a valid opin_switch name.\n", 01842 tmp); 01843 exit(1); 01844 } 01845 (*Segs)[i].opin_switch = j; 01846 ezxml_set_attr(SubElem, "name", NULL); 01847 FreeNode(SubElem); 01848 } 01849 01850 /* Setup the CB list if they give one, otherwise use full */ 01851 (*Segs)[i].cb_len = length; 01852 (*Segs)[i].cb = (boolean *) my_malloc(length * sizeof(boolean)); 01853 for(j = 0; j < length; ++j) 01854 { 01855 (*Segs)[i].cb[j] = TRUE; 01856 } 01857 SubElem = FindElement(Node, "cb", FALSE); 01858 if(SubElem) 01859 { 01860 ProcessCB_SB(SubElem, (*Segs)[i].cb, length); 01861 FreeNode(SubElem); 01862 } 01863 01864 /* Setup the SB list if they give one, otherwise use full */ 01865 (*Segs)[i].sb_len = (length + 1); 01866 (*Segs)[i].sb = 01867 (boolean *) my_malloc((length + 1) * sizeof(boolean)); 01868 for(j = 0; j < (length + 1); ++j) 01869 { 01870 (*Segs)[i].sb[j] = TRUE; 01871 } 01872 SubElem = FindElement(Node, "sb", FALSE); 01873 if(SubElem) 01874 { 01875 ProcessCB_SB(SubElem, (*Segs)[i].sb, (length + 1)); 01876 FreeNode(SubElem); 01877 } 01878 FreeNode(Node); 01879 } 01880 }
static void ProcessSubblocks | ( | INOUT ezxml_t | Parent, | |
INOUT t_type_descriptor * | Type, | |||
boolean | timing_enabled | |||
) | [static] |
Definition at line 1054 of file xml_arch.c.
01057 { 01058 const char *Prop; 01059 01060 ezxml_t CurType, Cur, Cur2; 01061 Type->max_subblocks = 1; 01062 Prop = FindProperty(Parent, "max_subblocks", FALSE); 01063 if(Prop) 01064 { 01065 Type->max_subblocks = my_atoi(Prop); 01066 ezxml_set_attr(Parent, "max_subblocks", NULL); 01067 } 01068 Type->max_subblock_inputs = 1; 01069 Prop = FindProperty(Parent, "max_subblock_inputs", FALSE); 01070 if(Prop) 01071 { 01072 Type->max_subblock_inputs = my_atoi(Prop); 01073 ezxml_set_attr(Parent, "max_subblock_inputs", NULL); 01074 } 01075 Type->max_subblock_outputs = 1; 01076 Prop = FindProperty(Parent, "max_subblock_outputs", FALSE); 01077 if(Prop) 01078 { 01079 Type->max_subblock_outputs = my_atoi(Prop); 01080 ezxml_set_attr(Parent, "max_subblock_outputs", NULL); 01081 } 01082 CurType = FindElement(Parent, "timing", timing_enabled); 01083 if(CurType != NULL) 01084 { 01085 Type->type_timing_inf.T_subblock = 01086 (t_T_subblock *) my_malloc(Type->max_subblocks * 01087 sizeof(t_T_subblock)); 01088 01089 /* Load T_comb timing for subblock */ 01090 Cur = FindElement(CurType, "T_comb", TRUE); 01091 SetupSubblocksTcomb(Cur, Type); 01092 FreeNode(Cur); 01093 01094 /* Load Fc */ 01095 Cur = FindElement(CurType, "T_seq_in", TRUE); 01096 Cur2 = FindElement(CurType, "T_seq_out", TRUE); 01097 SetupSubblocksTSeq(Cur, Cur2, Type); 01098 FreeNode(Cur); 01099 FreeNode(Cur2); 01100 FreeNode(CurType); 01101 } 01102 }
static void ProcessSubblocks | ( | INOUT ezxml_t | Parent, | |
INOUT t_type_descriptor * | Type, | |||
IN boolean | timing_enabled | |||
) | [static] |
static void ProcessSwitches | ( | INOUT ezxml_t | Node, | |
OUT struct s_switch_inf ** | Switches, | |||
OUT int * | NumSwitches, | |||
IN boolean | timing_enabled | |||
) | [static] |
Definition at line 1961 of file xml_arch.c.
01965 { 01966 int i, j; 01967 const char *type_name; 01968 const char *switch_name; 01969 const char *Prop; 01970 01971 boolean has_buf_size; 01972 ezxml_t Node; 01973 has_buf_size = FALSE; 01974 01975 /* Count the children and check they are switches */ 01976 *NumSwitches = CountChildren(Parent, "switch"); 01977 01978 /* Alloc switch list */ 01979 *Switches = NULL; 01980 if(*NumSwitches > 0) 01981 { 01982 *Switches = 01983 (struct s_switch_inf *)my_malloc(*NumSwitches * 01984 sizeof(struct 01985 s_switch_inf)); 01986 memset(*Switches, 0, 01987 (*NumSwitches * sizeof(struct s_switch_inf))); 01988 } 01989 01990 /* Load the switches. */ 01991 for(i = 0; i < *NumSwitches; ++i) 01992 { 01993 Node = ezxml_child(Parent, "switch"); 01994 switch_name = FindProperty(Node, "name", TRUE); 01995 type_name = FindProperty(Node, "type", TRUE); 01996 01997 /* Check for switch name collisions */ 01998 for(j = 0; j < i; ++j) 01999 { 02000 if(0 == strcmp((*Switches)[j].name, switch_name)) 02001 { 02002 printf(ERRTAG 02003 "Two switches with the same name '%s' were " 02004 "found.\n", switch_name); 02005 exit(1); 02006 } 02007 } 02008 (*Switches)[i].name = my_strdup(switch_name); 02009 ezxml_set_attr(Node, "name", NULL); 02010 02011 /* Figure out the type of switch. */ 02012 if(0 == strcmp(type_name, "mux")) 02013 { 02014 (*Switches)[i].buffered = TRUE; 02015 has_buf_size = TRUE; 02016 } 02017 02018 else if(0 == strcmp(type_name, "pass_trans")) 02019 { 02020 (*Switches)[i].buffered = FALSE; 02021 } 02022 02023 else if(0 == strcmp(type_name, "buffer")) 02024 { 02025 (*Switches)[i].buffered = TRUE; 02026 } 02027 02028 else 02029 { 02030 printf(ERRTAG "Invalid switch type '%s'.\n", type_name); 02031 exit(1); 02032 } 02033 ezxml_set_attr(Node, "type", NULL); 02034 Prop = FindProperty(Node, "R", timing_enabled); 02035 if(Prop != NULL) 02036 { 02037 (*Switches)[i].R = atof(Prop); 02038 ezxml_set_attr(Node, "R", NULL); 02039 } 02040 Prop = FindProperty(Node, "Cin", timing_enabled); 02041 if(Prop != NULL) 02042 { 02043 (*Switches)[i].Cin = atof(Prop); 02044 ezxml_set_attr(Node, "Cin", NULL); 02045 } 02046 Prop = FindProperty(Node, "Cout", timing_enabled); 02047 if(Prop != NULL) 02048 { 02049 (*Switches)[i].Cout = atof(Prop); 02050 ezxml_set_attr(Node, "Cout", NULL); 02051 } 02052 Prop = FindProperty(Node, "Tdel", timing_enabled); 02053 if(Prop != NULL) 02054 { 02055 (*Switches)[i].Tdel = atof(Prop); 02056 ezxml_set_attr(Node, "Tdel", NULL); 02057 } 02058 Prop = FindProperty(Node, "buf_size", has_buf_size); 02059 if(has_buf_size) 02060 { 02061 (*Switches)[i].buf_size = atof(Prop); 02062 ezxml_set_attr(Node, "buf_size", NULL); 02063 } 02064 Prop = FindProperty(Node, "mux_trans_size", FALSE); 02065 if(Prop != NULL) 02066 { 02067 (*Switches)[i].mux_trans_size = atof(Prop); 02068 ezxml_set_attr(Node, "mux_trans_size", NULL); 02069 } 02070 02071 /* Remove the switch element from parse tree */ 02072 FreeNode(Node); 02073 } 02074 }
static void ProcessTypeProps | ( | ezxml_t | Node, | |
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 1107 of file xml_arch.c.
01109 { 01110 const char *Prop; 01111 01112 01113 /* Load type name */ 01114 Prop = FindProperty(Node, "name", TRUE); 01115 Type->name = my_strdup(Prop); 01116 ezxml_set_attr(Node, "name", NULL); 01117 01118 /* Load capacity */ 01119 Type->capacity = 1; /* DEFAULT */ 01120 01121 /* Load height */ 01122 Type->height = 1; /* DEFAULT */ 01123 Prop = FindProperty(Node, "height", FALSE); 01124 if(Prop) 01125 { 01126 Type->height = my_atoi(Prop); 01127 ezxml_set_attr(Node, "height", NULL); 01128 } 01129 }
static void ProcessTypes | ( | INOUT ezxml_t | Node, | |
OUT t_type_descriptor ** | Types, | |||
OUT int * | NumTypes, | |||
boolean | timing_enabled | |||
) | [static] |
Definition at line 1540 of file xml_arch.c.
01544 { 01545 ezxml_t CurType, Prev; 01546 ezxml_t Cur, Cur2; 01547 t_type_descriptor * Type; 01548 int i; 01549 01550 01551 /* Alloc the type list. Need two additional t_type_desctiptors: 01552 * 1: empty psuedo-type 01553 * 2: IO type 01554 */ 01555 *NumTypes = CountChildren(Node, "type") + 2; 01556 *Types = (t_type_descriptor *) 01557 my_malloc(sizeof(t_type_descriptor) * (*NumTypes)); 01558 EMPTY_TYPE = &type_descriptors[EMPTY_TYPE_INDEX]; 01559 IO_TYPE = &type_descriptors[IO_TYPE_INDEX]; 01560 type_descriptors[EMPTY_TYPE_INDEX].index = EMPTY_TYPE_INDEX; 01561 type_descriptors[IO_TYPE_INDEX].index = IO_TYPE_INDEX; 01562 SetupEmptyType(); 01563 Cur = FindElement(Node, "io", TRUE); 01564 ProcessIO(Cur, timing_enabled); 01565 FreeNode(Cur); 01566 01567 /* Process the types */ 01568 i = 2; /* Skip over 'empty' and 'io' type */ 01569 CurType = Node->child; 01570 while(CurType) 01571 { 01572 CheckElement(CurType, "type"); 01573 01574 /* Alias to current type */ 01575 Type = &(*Types)[i]; 01576 01577 /* Parses the properties fields of the type */ 01578 ProcessTypeProps(CurType, Type); 01579 01580 /* Load subblock info */ 01581 Cur = FindElement(CurType, "subblocks", TRUE); 01582 ProcessSubblocks(Cur, Type, timing_enabled); 01583 FreeNode(Cur); 01584 01585 /* Load Fc */ 01586 Cur = FindElement(CurType, "fc_in", TRUE); 01587 Cur2 = FindElement(CurType, "fc_out", TRUE); 01588 Process_Fc(Cur, Cur2, Type); 01589 FreeNode(Cur); 01590 FreeNode(Cur2); 01591 01592 /* Load pin names and classes and locations */ 01593 Cur = FindElement(CurType, "pinclasses", TRUE); 01594 SetupPinClasses(Cur, Type); 01595 FreeNode(Cur); 01596 Cur = FindElement(CurType, "pinlocations", TRUE); 01597 SetupPinLocations(Cur, Type); 01598 FreeNode(Cur); 01599 Cur = FindElement(CurType, "gridlocations", TRUE); 01600 SetupGridLocations(Cur, Type); 01601 FreeNode(Cur); 01602 Cur = FindElement(CurType, "timing", timing_enabled); 01603 if(Cur) 01604 { 01605 SetupTypeTiming(Cur, Type); 01606 FreeNode(Cur); 01607 } 01608 Type->index = i; 01609 01610 /* Type fully read */ 01611 ++i; 01612 01613 /* Free this node and get its next sibling node */ 01614 Prev = CurType; 01615 CurType = CurType->next; 01616 FreeNode(Prev); 01617 } 01618 if(FILL_TYPE == NULL) 01619 { 01620 printf(ERRTAG "grid location type 'fill' must be specified.\n"); 01621 exit(1); 01622 } 01623 }
static void ProcessTypes | ( | INOUT ezxml_t | Node, | |
OUT t_type_descriptor ** | Types, | |||
OUT int * | NumTypes, | |||
IN boolean | timing_enabled | |||
) | [static] |
static void SetupClassInf | ( | ezxml_t | Classes, | |
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 424 of file xml_arch.c.
00426 { 00427 int i, k, CurClass, CurPin, NumClassPins; 00428 00429 ezxml_t Cur; 00430 const char *Prop; 00431 00432 00433 /* Alloc class_inf structs */ 00434 Type->num_class = Type->capacity * CountChildren(Classes, "class"); 00435 Type->class_inf = 00436 (t_class *) my_malloc(Type->num_class * sizeof(t_class)); 00437 00438 /* Make multiple passes to handle capacity with index increased each pass */ 00439 CurPin = 0; 00440 CurClass = 0; 00441 Type->num_pins = 0; 00442 Type->num_drivers = 0; 00443 Type->num_receivers = 0; 00444 for(i = 0; i < Type->capacity; ++i) 00445 { 00446 00447 /* Restart the parse tree at each node */ 00448 Cur = Classes->child; 00449 while(Cur) 00450 { 00451 CheckElement(Cur, "class"); 00452 00453 /* Count the number of pins in this class */ 00454 CountTokensInString(Cur->txt, &NumClassPins, &k); 00455 Type->num_pins += NumClassPins; 00456 00457 /* Alloc class structures */ 00458 Type->class_inf[CurClass].num_pins = NumClassPins; 00459 Type->class_inf[CurClass].pinlist = 00460 (int *)my_malloc(NumClassPins * sizeof(int)); 00461 for(k = 0; k < NumClassPins; ++k) 00462 { 00463 Type->class_inf[CurClass].pinlist[k] = CurPin; 00464 ++CurPin; 00465 } 00466 00467 /* Figure out class type */ 00468 Prop = FindProperty(Cur, "type", TRUE); 00469 if(0 == strcmp(Prop, "in")) 00470 { 00471 Type->num_receivers += NumClassPins; 00472 Type->class_inf[CurClass].type = RECEIVER; 00473 } 00474 00475 else if(0 == strcmp(Prop, "out")) 00476 { 00477 Type->num_drivers += NumClassPins; 00478 Type->class_inf[CurClass].type = DRIVER; 00479 } 00480 00481 else if(0 == strcmp(Prop, "global")) 00482 { 00483 Type->class_inf[CurClass].type = RECEIVER; 00484 } 00485 00486 else 00487 { 00488 printf(ERRTAG "Invalid pin class type '%s'.\n", 00489 Prop); 00490 exit(1); 00491 } 00492 ++CurClass; 00493 Cur = Cur->next; 00494 } 00495 } 00496 }
static void SetupEmptyType | ( | ) | [static] |
Definition at line 1353 of file xml_arch.c.
01354 { 01355 t_type_descriptor * type; 01356 type = &type_descriptors[EMPTY_TYPE->index]; 01357 type->name = "<EMPTY>"; 01358 type->num_pins = 0; 01359 type->height = 1; 01360 type->capacity = 0; 01361 type->num_drivers = 0; 01362 type->num_receivers = 0; 01363 type->pinloc = NULL; 01364 type->num_class = 0; 01365 type->class_inf = NULL; 01366 type->pin_class = NULL; 01367 type->is_global_pin = NULL; 01368 type->is_Fc_frac = TRUE; 01369 type->is_Fc_out_full_flex = FALSE; 01370 type->Fc_in = 0; 01371 type->Fc_out = 0; 01372 type->max_subblocks = 0; 01373 type->max_subblock_inputs = 0; 01374 type->max_subblock_outputs = 0; 01375 01376 /* Used as lost area filler, no definition */ 01377 type->grid_loc_def = NULL; 01378 type->num_grid_loc_def = 0; 01379 }
static void SetupGridLocations | ( | ezxml_t | Locations, | |
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 730 of file xml_arch.c.
00732 { 00733 int i; 00734 00735 ezxml_t Cur, Prev; 00736 const char *Prop; 00737 00738 Type->num_grid_loc_def = CountChildren(Locations, "loc"); 00739 Type->grid_loc_def = 00740 (struct s_grid_loc_def *)my_calloc(Type->num_grid_loc_def, 00741 sizeof(struct s_grid_loc_def)); 00742 00743 /* Load the pin locations */ 00744 Cur = Locations->child; 00745 i = 0; 00746 while(Cur) 00747 { 00748 CheckElement(Cur, "loc"); 00749 00750 /* loc index */ 00751 Prop = FindProperty(Cur, "type", TRUE); 00752 if(Prop) 00753 { 00754 if(strcmp(Prop, "fill") == 0) 00755 { 00756 if(Type->num_grid_loc_def != 1) 00757 { 00758 printf(ERRTAG 00759 "Another loc specified for fill.\n"); 00760 exit(1); 00761 } 00762 Type->grid_loc_def[i].grid_loc_type = FILL; 00763 FILL_TYPE = Type; 00764 } 00765 else if(strcmp(Prop, "col") == 0) 00766 { 00767 Type->grid_loc_def[i].grid_loc_type = COL_REPEAT; 00768 } 00769 else if(strcmp(Prop, "rel") == 0) 00770 { 00771 Type->grid_loc_def[i].grid_loc_type = COL_REL; 00772 } 00773 else 00774 { 00775 printf(ERRTAG 00776 "Unknown grid location type '%s' for type '%s'.\n", 00777 Prop, Type->name); 00778 exit(1); 00779 } 00780 ezxml_set_attr(Cur, "type", NULL); 00781 } 00782 Prop = FindProperty(Cur, "start", FALSE); 00783 if(Type->grid_loc_def[i].grid_loc_type == COL_REPEAT) 00784 { 00785 if(Prop == NULL) 00786 { 00787 printf(ERRTAG 00788 "grid location property 'start' must be specified for grid location type 'col'.\n"); 00789 exit(1); 00790 } 00791 Type->grid_loc_def[i].start_col = my_atoi(Prop); 00792 ezxml_set_attr(Cur, "start", NULL); 00793 } 00794 else if(Prop != NULL) 00795 { 00796 printf(ERRTAG 00797 "grid location property 'start' valid for grid location type 'col' only.\n"); 00798 exit(1); 00799 } 00800 Prop = FindProperty(Cur, "repeat", FALSE); 00801 if(Type->grid_loc_def[i].grid_loc_type == COL_REPEAT) 00802 { 00803 if(Prop != NULL) 00804 { 00805 Type->grid_loc_def[i].repeat = my_atoi(Prop); 00806 ezxml_set_attr(Cur, "repeat", NULL); 00807 } 00808 } 00809 else if(Prop != NULL) 00810 { 00811 printf(ERRTAG 00812 "grid location property 'repeat' valid for grid location type 'col' only.\n"); 00813 exit(1); 00814 } 00815 Prop = FindProperty(Cur, "pos", FALSE); 00816 if(Type->grid_loc_def[i].grid_loc_type == COL_REL) 00817 { 00818 if(Prop == NULL) 00819 { 00820 printf(ERRTAG 00821 "grid location property 'pos' must be specified for grid location type 'rel'.\n"); 00822 exit(1); 00823 } 00824 Type->grid_loc_def[i].col_rel = atof(Prop); 00825 ezxml_set_attr(Cur, "pos", NULL); 00826 } 00827 else if(Prop != NULL) 00828 { 00829 printf(ERRTAG 00830 "grid location property 'pos' valid for grid location type 'rel' only.\n"); 00831 exit(1); 00832 } 00833 Prop = FindProperty(Cur, "priority", FALSE); 00834 if(Prop) 00835 { 00836 Type->grid_loc_def[i].priority = my_atoi(Prop); 00837 ezxml_set_attr(Cur, "priority", NULL); 00838 } 00839 Prev = Cur; 00840 Cur = Cur->next; 00841 FreeNode(Prev); 00842 i++; 00843 } 00844 }
static void SetupPinClasses | ( | ezxml_t | Classes, | |
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 505 of file xml_arch.c.
00507 { 00508 int CurClass, i, j, CurPin, PinsPerSubtile, ClassesPerSubtile; 00509 00510 ezxml_t Cur, Prev; 00511 const char *Prop; 00512 00513 boolean IsGlobal; 00514 char **Tokens; 00515 int *pin_used = NULL; 00516 00517 00518 /* Allocs and sets up the classinf data and counts pins */ 00519 SetupClassInf(Classes, Type); 00520 PinsPerSubtile = Type->num_pins / Type->capacity; 00521 ClassesPerSubtile = Type->num_class / Type->capacity; 00522 00523 /* Alloc num_pin sized lists. Replicated pins don't have new names. */ 00524 Type->is_global_pin = 00525 (boolean *) my_malloc(Type->num_pins * sizeof(boolean)); 00526 Type->pin_class = (int *)my_malloc(Type->num_pins * sizeof(int)); 00527 pin_used = (int *)my_malloc(Type->num_pins * sizeof(int)); 00528 for(i = 0; i < Type->num_pins; ++i) 00529 { 00530 pin_used[i] = FALSE; 00531 } 00532 00533 /* Iterate over all pins */ 00534 CurClass = 0; 00535 Cur = Classes->child; 00536 while(Cur) 00537 { 00538 CheckElement(Cur, "class"); 00539 00540 /* Figure out if global class */ 00541 IsGlobal = FALSE; 00542 Prop = FindProperty(Cur, "type", TRUE); 00543 if(0 == strcmp(Prop, "global")) 00544 { 00545 IsGlobal = TRUE; 00546 } 00547 ezxml_set_attr(Cur, "type", NULL); 00548 00549 /* Itterate over pins in the class */ 00550 Tokens = GetNodeTokens(Cur); 00551 assert(CountTokens(Tokens) == 00552 Type->class_inf[CurClass].num_pins); 00553 for(j = 0; j < Type->class_inf[CurClass].num_pins; ++j) 00554 { 00555 CurPin = my_atoi(Tokens[j]); 00556 00557 /* Check for duplicate pin names */ 00558 if(pin_used[CurPin]) 00559 { 00560 printf(ERRTAG 00561 "Pin %d is defined in two different classes in type '%s'.\n", 00562 CurPin, Type->name); 00563 exit(1); 00564 } 00565 pin_used[CurPin] = TRUE; 00566 00567 /* Set the pin class and is_global status */ 00568 for(i = 0; i < Type->capacity; ++i) 00569 { 00570 Type->pin_class[CurPin + (i * PinsPerSubtile)] = 00571 CurClass + (i * ClassesPerSubtile); 00572 Type->is_global_pin[CurPin + 00573 (i * PinsPerSubtile)] = 00574 IsGlobal; 00575 } 00576 } 00577 FreeTokens(&Tokens); 00578 ++CurClass; 00579 Prev = Cur; 00580 Cur = Cur->next; 00581 FreeNode(Prev); 00582 } 00583 if(pin_used) 00584 { 00585 free(pin_used); 00586 pin_used = NULL; 00587 } 00588 }
static void SetupPinLocations | ( | ezxml_t | Locations, | |
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 595 of file xml_arch.c.
00597 { 00598 int i, j, k, l, PinsPerSubtile, Count, Len; 00599 00600 ezxml_t Cur, Prev; 00601 const char *Prop; 00602 char **Tokens, **CurTokens; 00603 00604 PinsPerSubtile = Type->num_pins / Type->capacity; 00605 00606 /* Alloc and clear pin locations */ 00607 Type->pinloc = (int ***)my_malloc(Type->height * sizeof(int **)); 00608 for(i = 0; i < Type->height; ++i) 00609 { 00610 Type->pinloc[i] = (int **)my_malloc(4 * sizeof(int *)); 00611 for(j = 0; j < 4; ++j) 00612 { 00613 Type->pinloc[i][j] = 00614 (int *)my_malloc(Type->num_pins * sizeof(int)); 00615 for(k = 0; k < Type->num_pins; ++k) 00616 { 00617 Type->pinloc[i][j][k] = 0; 00618 } 00619 } 00620 } 00621 00622 /* Load the pin locations */ 00623 Cur = Locations->child; 00624 while(Cur) 00625 { 00626 CheckElement(Cur, "loc"); 00627 00628 /* Get offset */ 00629 i = 0; 00630 Prop = FindProperty(Cur, "offset", FALSE); 00631 if(Prop) 00632 { 00633 i = my_atoi(Prop); 00634 if((i < 0) || (i >= Type->height)) 00635 { 00636 printf(ERRTAG 00637 "%d is an invalid offset for type '%s'.\n", 00638 i, Type->name); 00639 exit(1); 00640 } 00641 ezxml_set_attr(Cur, "offset", NULL); 00642 } 00643 00644 /* Get side */ 00645 Prop = FindProperty(Cur, "side", TRUE); 00646 if(0 == strcmp(Prop, "left")) 00647 { 00648 j = LEFT; 00649 } 00650 00651 else if(0 == strcmp(Prop, "top")) 00652 { 00653 j = TOP; 00654 } 00655 00656 else if(0 == strcmp(Prop, "right")) 00657 { 00658 j = RIGHT; 00659 } 00660 00661 else if(0 == strcmp(Prop, "bottom")) 00662 { 00663 j = BOTTOM; 00664 } 00665 00666 else 00667 { 00668 printf(ERRTAG "'%s' is not a valid side.\n", Prop); 00669 exit(1); 00670 } 00671 ezxml_set_attr(Cur, "side", NULL); 00672 00673 /* Check location is on perimeter */ 00674 if((TOP == j) && (i != (Type->height - 1))) 00675 { 00676 printf(ERRTAG 00677 "Locations are only allowed on large block " 00678 "perimeter. 'top' side should be at offset %d only.\n", 00679 (Type->height - 1)); 00680 exit(1); 00681 } 00682 if((BOTTOM == j) && (i != 0)) 00683 { 00684 printf(ERRTAG 00685 "Locations are only allowed on large block " 00686 "perimeter. 'bottom' side should be at offset 0 only.\n"); 00687 exit(1); 00688 } 00689 00690 /* Go through lists of pins */ 00691 CountTokensInString(Cur->txt, &Count, &Len); 00692 if(Count > 0) 00693 { 00694 Tokens = GetNodeTokens(Cur); 00695 CurTokens = Tokens; 00696 while(*CurTokens) 00697 { 00698 00699 /* Get pin */ 00700 k = my_atoi(*CurTokens); 00701 if(k >= Type->num_pins) 00702 { 00703 printf(ERRTAG 00704 "Pin %d of type '%s' is not a valid pin.\n", 00705 k, Type->name); 00706 exit(1); 00707 } 00708 00709 /* Set pin location */ 00710 for(l = 0; l < Type->capacity; ++l) 00711 { 00712 Type->pinloc[i][j][k + (l * PinsPerSubtile)] = 1; 00713 } 00714 00715 /* Advance through list of pins in this location */ 00716 ++CurTokens; 00717 } 00718 FreeTokens(&Tokens); 00719 } 00720 Prev = Cur; 00721 Cur = Cur->next; 00722 FreeNode(Prev); 00723 } 00724 }
static void SetupSubblocksTcomb | ( | ezxml_t | timing, | |
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 901 of file xml_arch.c.
00903 { 00904 ezxml_t Cur, prev; 00905 t_T_subblock ** T_subblock_ptr; 00906 float **t_comb; 00907 int i, j; 00908 char **Tokens; 00909 00910 T_subblock_ptr = &Type->type_timing_inf.T_subblock; 00911 t_comb = 00912 (float **)alloc_matrix(0, Type->max_subblock_inputs - 1, 0, 00913 Type->max_subblock_outputs - 1, sizeof(float)); 00914 for(i = 0; i < Type->max_subblock_inputs; i++) 00915 { 00916 for(j = 0; j < Type->max_subblock_outputs; j++) 00917 { 00918 t_comb[i][j] = 0; 00919 } 00920 } 00921 00922 /* Load the timing info */ 00923 Cur = timing->child; 00924 i = 0; 00925 while(Cur) 00926 { 00927 CheckElement(Cur, "trow"); 00928 Tokens = GetNodeTokens(Cur); 00929 if(CountTokens(Tokens) != Type->max_subblock_outputs) 00930 { 00931 printf(ERRTAG 00932 "Number of tokens %d not equal number of subblock outputs %d.", 00933 CountTokens(Tokens), 00934 Type->max_subblock_outputs); 00935 exit(1); 00936 } 00937 for(j = 0; j < Type->max_subblock_outputs; j++) 00938 { 00939 t_comb[i][j] = atof(Tokens[j]); 00940 } 00941 i++; 00942 prev = Cur; 00943 Cur = Cur->next; 00944 FreeNode(prev); 00945 FreeTokens(&Tokens); 00946 } 00947 if(i != Type->max_subblock_inputs) 00948 { 00949 printf(ERRTAG 00950 "Number of trow %d not equal number of subblock inputs %d.", 00951 i, Type->max_subblock_inputs); 00952 exit(1); 00953 } 00954 for(i = 0; i < Type->max_subblocks; i++) 00955 { 00956 (*T_subblock_ptr)[i].T_comb = t_comb; 00957 } 00958 }
static void SetupSubblocksTSeq | ( | ezxml_t | timing_seq_in, | |
ezxml_t | timing_seq_out, | |||
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 960 of file xml_arch.c.
00963 { 00964 ezxml_t Cur, prev; 00965 t_T_subblock ** T_subblock_ptr; 00966 int i, j; 00967 float *t_seq[2]; 00968 00969 ezxml_t seq_timing[2]; 00970 char **Tokens; 00971 00972 T_subblock_ptr = &Type->type_timing_inf.T_subblock; 00973 seq_timing[0] = timing_seq_in; 00974 seq_timing[1] = timing_seq_out; 00975 t_seq[0] = (float *)my_calloc(Type->max_subblock_inputs, sizeof(float)); 00976 t_seq[1] = (float *)my_calloc(Type->max_subblock_outputs, sizeof(float)); 00977 00978 /* Load the timing info */ 00979 for(i = 0; i < 2; i++) 00980 { 00981 Cur = seq_timing[i]->child; 00982 j = 0; 00983 while(Cur) 00984 { 00985 CheckElement(Cur, "trow"); 00986 Tokens = GetNodeTokens(Cur); 00987 if(CountTokens(Tokens) != 1) 00988 { 00989 printf(ERRTAG 00990 "Timing for sequential subblock edges not a number."); 00991 } 00992 t_seq[i][j] = atof(Tokens[0]); 00993 j++; 00994 prev = Cur; 00995 Cur = Cur->next; 00996 FreeNode(prev); 00997 FreeTokens(&Tokens); 00998 } 00999 if(j != Type->max_subblock_outputs) 01000 { 01001 printf(ERRTAG 01002 "Number of trow %d not equal number of subblock outputs %d.", 01003 j, Type->max_subblock_outputs); 01004 exit(1); 01005 } 01006 } 01007 for(i = 0; i < Type->max_subblocks; i++) 01008 { 01009 (*T_subblock_ptr)[i].T_seq_in = t_seq[0]; 01010 (*T_subblock_ptr)[i].T_seq_out = t_seq[1]; 01011 } 01012 }
static void SetupTypeTiming | ( | ezxml_t | timing, | |
t_type_descriptor * | Type | |||
) | [static] |
Definition at line 846 of file xml_arch.c.
00848 { 00849 ezxml_t Cur, Prev; 00850 const char *Prop; 00851 float value; 00852 char **Tokens; 00853 00854 00855 /* Clear timing info for type */ 00856 Type->type_timing_inf.T_fb_ipin_to_sblk_ipin = 0; 00857 Type->type_timing_inf.T_sblk_opin_to_fb_opin = 0; 00858 Type->type_timing_inf.T_sblk_opin_to_sblk_ipin = 0; 00859 00860 /* Load the timing info */ 00861 Cur = timing->child; 00862 while(Cur) 00863 { 00864 CheckElement(Cur, "tedge"); 00865 00866 /* Get timing type */ 00867 Prop = FindProperty(Cur, "type", TRUE); 00868 Tokens = GetNodeTokens(Cur); 00869 if(CountTokens(Tokens) != 1) 00870 { 00871 printf(ERRTAG 00872 "Timing for sequential subblock edges not a number."); 00873 } 00874 value = atof(Tokens[0]); 00875 if(0 == strcmp(Prop, "T_fb_ipin_to_sblk_ipin")) 00876 { 00877 Type->type_timing_inf.T_fb_ipin_to_sblk_ipin = value; 00878 } 00879 else if(0 == strcmp(Prop, "T_sblk_opin_to_fb_opin")) 00880 { 00881 Type->type_timing_inf.T_sblk_opin_to_fb_opin = value; 00882 } 00883 else if(0 == strcmp(Prop, "T_sblk_opin_to_sblk_ipin")) 00884 { 00885 Type->type_timing_inf.T_sblk_opin_to_sblk_ipin = value; 00886 } 00887 else 00888 { 00889 printf(ERRTAG "'%s' is an unrecognized timing edge.\n", 00890 Prop); 00891 exit(1); 00892 } 00893 ezxml_set_attr(Cur, "type", NULL); 00894 Prev = Cur; 00895 Cur = Cur->next; 00896 FreeNode(Prev); 00897 FreeTokens(&Tokens); 00898 } 00899 }
void XmlReadArch | ( | IN const char * | ArchFile, | |
IN boolean | timing_enabled, | |||
OUT struct s_arch * | arch, | |||
OUT t_type_descriptor ** | Types, | |||
OUT int * | NumTypes | |||
) |
Definition at line 1629 of file xml_arch.c.
01634 { 01635 ezxml_t Cur, Next; 01636 01637 /* Parse the file */ 01638 Cur = ezxml_parse_file(ArchFile); 01639 if(NULL == Cur) 01640 { 01641 printf(ERRTAG "Unable to load architecture file '%s'.\n", 01642 ArchFile); 01643 } 01644 01645 /* Root node should be architecture */ 01646 CheckElement(Cur, "architecture"); 01647 01648 /* Process layout */ 01649 Next = FindElement(Cur, "layout", TRUE); 01650 ProcessLayout(Next, arch); 01651 FreeNode(Next); 01652 01653 /* Process device */ 01654 Next = FindElement(Cur, "device", TRUE); 01655 ProcessDevice(Next, arch, timing_enabled); 01656 FreeNode(Next); 01657 01658 /* Process types */ 01659 Next = FindElement(Cur, "typelist", TRUE); 01660 ProcessTypes(Next, Types, NumTypes, timing_enabled); 01661 FreeNode(Next); 01662 01663 /* Process switches */ 01664 Next = FindElement(Cur, "switchlist", TRUE); 01665 ProcessSwitches(Next, &(arch->Switches), &(arch->num_switches), 01666 timing_enabled); 01667 FreeNode(Next); 01668 01669 /* Process segments. This depends on switches */ 01670 Next = FindElement(Cur, "segmentlist", TRUE); 01671 ProcessSegments(Next, &(arch->Segments), &(arch->num_segments), 01672 arch->Switches, arch->num_switches, timing_enabled); 01673 FreeNode(Next); 01674 01675 /* Release the full XML tree */ 01676 FreeNode(Cur); 01677 }