📄 xml_arch.c
字号:
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 + -