📄 xml_arch.c
字号:
FreeNode(Cur); /* Load Fc */ Cur = FindElement(CurType, "T_seq_in", TRUE); Cur2 = FindElement(CurType, "T_seq_out", TRUE); SetupSubblocksTSeq(Cur, Cur2, Type); FreeNode(Cur); FreeNode(Cur2); FreeNode(CurType); }}/* Thie processes attributes of the 'type' tag and then unlinks them */ static voidProcessTypeProps(ezxml_t Node, t_type_descriptor * Type){ const char *Prop; /* Load type name */ Prop = FindProperty(Node, "name", TRUE); Type->name = my_strdup(Prop); ezxml_set_attr(Node, "name", NULL); /* Load capacity */ Type->capacity = 1; /* DEFAULT */ /* Load height */ Type->height = 1; /* DEFAULT */ Prop = FindProperty(Node, "height", FALSE); if(Prop) { Type->height = my_atoi(Prop); ezxml_set_attr(Node, "height", NULL); }}/* Takes in node pointing to <layout> and loads all the * child type objects. Unlinks the entire <layout> node * when complete. */ static voidProcessLayout(INOUT ezxml_t Node, OUT struct s_arch *arch){ const char *Prop; arch->clb_grid.IsAuto = TRUE; /* Load width and height if applicable */ Prop = FindProperty(Node, "width", FALSE); if(Prop != NULL) { arch->clb_grid.IsAuto = FALSE; arch->clb_grid.W = my_atoi(Prop); ezxml_set_attr(Node, "width", NULL); Prop = FindProperty(Node, "height", TRUE); if(Prop != NULL) { arch->clb_grid.H = my_atoi(Prop); ezxml_set_attr(Node, "height", NULL); } } /* Load aspect ratio if applicable */ Prop = FindProperty(Node, "auto", arch->clb_grid.IsAuto); if(Prop != NULL) { if(arch->clb_grid.IsAuto == FALSE) { printf(ERRTAG "Auto-sizing, width and height cannot be specified\n"); } arch->clb_grid.Aspect = atof(Prop); ezxml_set_attr(Node, "auto", NULL); }}/* Takes in node pointing to <device> and loads all the * child type objects. Unlinks the entire <device> node * when complete. */ static voidProcessDevice(INOUT ezxml_t Node, OUT struct s_arch *arch, IN boolean timing_enabled){ const char *Prop; ezxml_t Cur; Cur = FindElement(Node, "sizing", TRUE); arch->R_minW_nmos = 0; Prop = FindProperty(Cur, "R_minW_nmos", timing_enabled); if(Prop != NULL) { arch->R_minW_nmos = atof(Prop); ezxml_set_attr(Cur, "R_minW_nmos", NULL); } arch->R_minW_pmos = 0; Prop = FindProperty(Cur, "R_minW_pmos", timing_enabled); if(Prop != NULL) { arch->R_minW_pmos = atof(Prop); ezxml_set_attr(Cur, "R_minW_pmos", NULL); } arch->ipin_mux_trans_size = 0; Prop = FindProperty(Cur, "ipin_mux_trans_size", FALSE); if(Prop != NULL) { arch->ipin_mux_trans_size = atof(Prop); ezxml_set_attr(Cur, "ipin_mux_trans_size", NULL); } FreeNode(Cur); Cur = FindElement(Node, "timing", timing_enabled); if(Cur != NULL) { arch->C_ipin_cblock = 0; Prop = FindProperty(Cur, "C_ipin_cblock", FALSE); if(Prop != NULL) { arch->C_ipin_cblock = atof(Prop); ezxml_set_attr(Cur, "C_ipin_cblock", NULL); } arch->T_ipin_cblock = 0; Prop = FindProperty(Cur, "T_ipin_cblock", FALSE); if(Prop != NULL) { arch->T_ipin_cblock = atof(Prop); ezxml_set_attr(Cur, "T_ipin_cblock", NULL); } FreeNode(Cur); } Cur = FindElement(Node, "area", TRUE); Prop = FindProperty(Cur, "grid_logic_tile_area", FALSE); arch->grid_logic_tile_area = 0; if(Prop != NULL) { arch->grid_logic_tile_area = atof(Prop); ezxml_set_attr(Cur, "grid_logic_tile_area", NULL); } FreeNode(Cur); Cur = FindElement(Node, "chan_width_distr", FALSE); if(Cur != NULL) { ProcessChanWidthDistr(Cur, arch); FreeNode(Cur); } Cur = FindElement(Node, "switch_block", TRUE); Prop = FindProperty(Cur, "type", TRUE); if(strcmp(Prop, "wilton") == 0) { arch->SBType = WILTON; } else if(strcmp(Prop, "universal") == 0) { arch->SBType = UNIVERSAL; } else if(strcmp(Prop, "subset") == 0) { arch->SBType = SUBSET; } else { printf(ERRTAG "Unknown property %s for switch block type x\n", Prop); exit(1); } ezxml_set_attr(Cur, "type", NULL); Prop = FindProperty(Cur, "fs", TRUE); arch->Fs = my_atoi(Prop); ezxml_set_attr(Cur, "fs", NULL); FreeNode(Cur);}/* Takes in node pointing to <chan_width_distr> and loads all the * child type objects. Unlinks the entire <chan_width_distr> node * when complete. */ static voidProcessChanWidthDistr(INOUT ezxml_t Node, OUT struct s_arch *arch){ const char *Prop; ezxml_t Cur; Cur = FindElement(Node, "io", TRUE); Prop = FindProperty(Cur, "width", TRUE); arch->Chans.chan_width_io = atof(Prop); ezxml_set_attr(Cur, "width", NULL); FreeNode(Cur); Cur = FindElement(Node, "x", TRUE); ProcessChanWidthDistrDir(Cur, &arch->Chans.chan_x_dist); FreeNode(Cur); Cur = FindElement(Node, "y", TRUE); ProcessChanWidthDistrDir(Cur, &arch->Chans.chan_y_dist); FreeNode(Cur);}/* Takes in node within <chan_width_distr> and loads all the * child type objects. Unlinks the entire node when complete. */ static voidProcessChanWidthDistrDir(INOUT ezxml_t Node, OUT t_chan * chan){ const char *Prop; boolean hasXpeak, hasWidth, hasDc; hasXpeak = hasWidth = hasDc = FALSE; Prop = FindProperty(Node, "distr", TRUE); if(strcmp(Prop, "uniform") == 0) { chan->type = UNIFORM; } else if(strcmp(Prop, "gaussian") == 0) { chan->type = GAUSSIAN; hasXpeak = hasWidth = hasDc = TRUE; } else if(strcmp(Prop, "pulse") == 0) { chan->type = PULSE; hasXpeak = hasWidth = hasDc = TRUE; } else if(strcmp(Prop, "delta") == 0) { hasXpeak = hasDc = TRUE; chan->type = DELTA; } else { printf(ERRTAG "Unknown property %s for chan_width_distr x\n", Prop); exit(1); } ezxml_set_attr(Node, "distr", NULL); Prop = FindProperty(Node, "peak", TRUE); chan->peak = atof(Prop); ezxml_set_attr(Node, "peak", NULL); Prop = FindProperty(Node, "width", hasWidth); if(hasWidth) { chan->width = atof(Prop); ezxml_set_attr(Node, "width", NULL); } Prop = FindProperty(Node, "xpeak", hasXpeak); if(hasXpeak) { chan->xpeak = atof(Prop); ezxml_set_attr(Node, "xpeak", NULL); } Prop = FindProperty(Node, "dc", hasDc); if(hasDc) { chan->dc = atof(Prop); ezxml_set_attr(Node, "dc", NULL); }}static voidSetupEmptyType(){ t_type_descriptor * type; type = &type_descriptors[EMPTY_TYPE->index]; type->name = "<EMPTY>"; type->num_pins = 0; type->height = 1; type->capacity = 0; type->num_drivers = 0; type->num_receivers = 0; type->pinloc = NULL; type->num_class = 0; type->class_inf = NULL; type->pin_class = NULL; type->is_global_pin = NULL; type->is_Fc_frac = TRUE; type->is_Fc_out_full_flex = FALSE; type->Fc_in = 0; type->Fc_out = 0; type->max_subblocks = 0; type->max_subblock_inputs = 0; type->max_subblock_outputs = 0; /* Used as lost area filler, no definition */ type->grid_loc_def = NULL; type->num_grid_loc_def = 0;}/* Takes in node pointing to <io> and loads all the * child type objects. Unlinks the entire <io> node * when complete. */ static voidProcessIO(INOUT ezxml_t Node, IN boolean timing_enabled){ const char *Prop; ezxml_t Cur, Cur2; int i, j; t_type_descriptor * type; int num_inputs, num_outputs, num_clocks, num_pins, capacity, t_in, t_out; enum { INCLASS = 0, OUTCLASS = 1, CLKCLASS = 2 }; type = &type_descriptors[IO_TYPE->index]; num_inputs = 1; num_outputs = 1; num_clocks = 1; CheckElement(Node, "io"); type->name = ".io"; type->height = 1; /* Load capacity */ Prop = FindProperty(Node, "capacity", TRUE); capacity = my_atoi(Prop); type->capacity = capacity; ezxml_set_attr(Node, "capacity", NULL); /* Load Fc */ Cur = FindElement(Node, "fc_in", TRUE); Cur2 = FindElement(Node, "fc_out", TRUE); Process_Fc(Cur, Cur2, type); FreeNode(Cur); FreeNode(Cur2); /* Initialize and setup type */ num_pins = 3 * capacity; type->num_pins = num_pins; type->num_drivers = num_outputs * capacity; type->num_receivers = num_inputs * capacity; type->pinloc = (int ***)alloc_matrix3(0, 0, 0, 3, 0, num_pins - 1, sizeof(int)); /* Jason Luu - September 5, 2007 * To treat IOs as any other block in routing, need to blackbox * as having physical pins on all sides. This is a hack. */ for(i = 0; i < num_pins; ++i) { for(j = 0; j < 4; ++j) { type->pinloc[0][j][i] = 1; } } /* Three fixed classes. In, Out, Clock */ type->num_class = 3 * capacity; type->class_inf = (struct s_class *)my_malloc(sizeof(struct s_class) * 3 * capacity); type->pin_class = (int *)my_malloc(sizeof(int) * num_pins); type->is_global_pin = (boolean *) my_malloc(sizeof(boolean) * num_pins); for(j = 0; j < capacity; ++j) { /* Three fixed classes. In, Out, Clock */ type->class_inf[3 * j + INCLASS].num_pins = num_inputs; type->class_inf[3 * j + INCLASS].type = RECEIVER; type->class_inf[3 * j + INCLASS].pinlist = (int *)my_malloc(sizeof(int) * num_inputs); for(i = 0; i < num_inputs; ++i) { type->class_inf[3 * j + INCLASS].pinlist[i] = num_pins * j / capacity + i; type->pin_class[num_pins * j / capacity + i] = 3 * j + INCLASS; type->is_global_pin[num_pins * j / capacity + i] = FALSE; } type->class_inf[3 * j + OUTCLASS].num_pins = num_outputs; type->class_inf[3 * j + OUTCLASS].type = DRIVER; type->class_inf[3 * j + OUTCLASS].pinlist = (int *)my_malloc(sizeof(int) * num_outputs); for(i = 0; i < num_outputs; ++i) { type->class_inf[3 * j + OUTCLASS].pinlist[i] = num_pins * j / capacity + i + num_inputs; type->pin_class[num_pins * j / capacity + i + num_inputs] = 3 * j + OUTCLASS; type->is_global_pin[num_pins * j / capacity + i + num_inputs] = FALSE; } type->class_inf[3 * j + CLKCLASS].num_pins = num_clocks; type->class_inf[3 * j + CLKCLASS].type = RECEIVER; type->class_inf[3 * j + CLKCLASS].pinlist = (int *)my_malloc(sizeof(int) * num_clocks); for(i = 0; i < num_clocks; ++i) { type->class_inf[3 * j + CLKCLASS].pinlist[i] = num_pins * j / capacity + i + num_inputs + num_outputs; type->pin_class[num_pins * j / capacity + i + num_inputs + num_outputs] = 3 * j + CLKCLASS; type->is_global_pin[num_pins * j / capacity + i + num_inputs + num_outputs] = TRUE; } } type->max_subblocks = 1; type->max_subblock_inputs = 1; type->max_subblock_outputs = 1; /* Always at boundary */ type->num_grid_loc_def = 1; type->grid_loc_def = (struct s_grid_loc_def *)my_calloc(1, sizeof(struct s_grid_loc_def)); type->grid_loc_def[0].grid_loc_type = BOUNDARY; type->grid_loc_def[0].priority = 0; t_in = -1; t_out = -1; Prop = FindProperty(Node, "t_inpad", timing_enabled); if(Prop != NULL) { t_in = atof(Prop); ezxml_set_attr(Node, "t_inpad", NULL); } Prop = FindProperty(Node, "t_outpad", timing_enabled); if(Prop != NULL) { t_out = atof(Prop); ezxml_set_attr(Node, "t_outpad", NULL); } if(timing_enabled) { 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; type->type_timing_inf.T_subblock = (t_T_subblock *) my_malloc(sizeof(t_T_subblock)); type->type_timing_inf.T_subblock[0].T_comb = (float **)my_malloc(sizeof(float *)); type->type_timing_inf.T_subblock[0].T_comb[0] = (float *)my_malloc(sizeof(float)); type->type_timing_inf.T_subblock[0].T_comb[0][0] = t_out; type->type_timing_inf.T_subblock[0].T_seq_in = (float *)my_malloc(sizeof(float)); type->type_timing_inf.T_subblock[0].T_seq_in[0] = 0; type->type_timing_inf.T_subblock[0].T_seq_out = (float *)my_malloc(sizeof(float)); type->type_timing_inf.T_subblock[0].T_seq_out[0] = t_in; }}/* Takes in node pointing to <typelist> and loads all the * child type objects. Unlinks the entire <typelist> node * when complete. */ static voidProcessTypes(INOUT ezxml_t Node, OUT t_type_descriptor ** Types, OUT int *NumTypes, boolean timing_enabled){ ezxml_t CurType, Prev; ezxml_t Cur, Cur2; t_type_descriptor * Type; int i; /* Alloc the type list. Need two additional t_type_desctiptors: * 1: empty psuedo-type * 2: IO type */ *NumTypes = CountChildren(Node, "type") + 2; *Types = (t_type_descriptor *) my_malloc(sizeof(t_type_descriptor) * (*NumTypes)); EMPTY_TYPE = &type_descriptors[EMPTY_TYPE_INDEX]; IO_TYPE = &type_descriptors[IO_TYPE_INDEX]; type_descriptors[EMPTY_TYPE_INDEX].index = EMPTY_TYPE_INDEX; type_descriptors[IO_TYPE_INDEX].index = IO_TYPE_INDEX; SetupEmptyType(); Cur = FindElement(Node, "io", TRUE); ProcessIO(Cur, timing_enabled); FreeNode(Cur); /* Process the types */ i = 2; /* Skip over 'empty' and 'io' type */ CurType = Node->child; while(CurType) { CheckElement(CurType, "type"); /* Alias to current type */ Type = &(*Types)[i]; /* Parses the properties fields of the type */ ProcessTypeProps(CurType, Type); /* Load subblock info */ Cur = FindElement(CurType, "subblocks", TRUE); ProcessSubblocks(Cur, Type, timing_enabled); FreeNode(Cur); /* Load Fc */ Cur = FindElement(CurType, "fc_in", TRUE); Cur2 = FindElement(CurType, "fc_out", TRUE); Process_Fc(Cur, Cur2, Type); FreeNode(Cur); FreeNode(Cur2); /* Load pin names and classes and locations */ Cur = FindElement(CurType, "pinclasses", TRUE); SetupPinClasses(Cur, Type); FreeNode(Cur); Cur = FindElement(CurType, "pinlocations", TRUE); SetupPinLocations(Cur, Type); FreeNode(Cur); Cur = FindElement(CurType, "gridlocations", TRUE); SetupGridLocations(Cur, Type); FreeNode(Cur); Cur = FindElement(CurType, "timing", timing_enabled); if(Cur) { SetupTypeTiming(Cur, Type); FreeNode(Cur); } Type->index = i; /* Type fully read */ ++i; /* Free this node and get its next sibling node */ Prev = CurType; CurType = CurType->next; FreeNode(Prev); } if(FILL_TYPE == NULL) { printf(ERRTAG "grid location type 'fill' must be specified.\n"); exit(1); }}/* Loads the given architecture file. Currently only * handles type information */ voidXmlReadArch(IN const char *ArchFile, IN boolean timing_enabled, OUT struct s_arch *arch, OUT t_type_descriptor ** Types, OUT int *NumTypes){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -