📄 read_arch.c
字号:
/* This routine parses the input architecture file in order to count the * * number of pinclasses, pins, segments, etc. so storage can be allocated * * for them before the second (loading) pass begins. */ char buf[BUFSIZE], *ptr; int *pins_per_class, iclass, i, num_segment, num_switch, num_T_subblock; linenum = 0; num_class = 1; /* Must be at least 1 class */ num_segment = 0; num_switch = 0; num_T_subblock = 0; pins_per_class = (int *) my_calloc (num_class, sizeof (int)); while ((ptr = my_fgets(buf, BUFSIZE, fp_arch)) != NULL) { ptr = my_strtok (ptr, TOKENS, fp_arch, buf); if (ptr == NULL) /* Empty or comment line. */ continue; if (strcmp (ptr, "inpin") == 0 || strcmp (ptr, "outpin") == 0 || strcmp (ptr, "global_inpin") == 0) { iclass = get_class (fp_arch, buf); if (iclass >= num_class) { pins_per_class = (int *) my_realloc (pins_per_class, (iclass + 1) * sizeof (int)); for (i=num_class;i<=iclass;i++) pins_per_class[i] = 0; num_class = iclass + 1; } pins_per_class[iclass]++; } else if (strcmp (ptr, "segment") == 0) { num_segment++; } else if (strcmp (ptr, "switch") == 0) { num_switch++; } else if (strcmp (ptr, "T_subblock") == 0) { num_T_subblock++; } /* Go to end of line (possibly continued) */ while (ptr != NULL) { ptr = my_strtok (NULL, TOKENS, fp_arch, buf); } }/* Check for missing classes. */ for (i=0;i<num_class;i++) { if (pins_per_class[i] == 0) { printf("\nError: class index %d not used in architecture " "file.\n", i); printf(" Specified class indices are not consecutive.\n"); exit (1); } }/* I've now got a count of how many classes there are and how many * * pins belong to each class. Allocate the proper memory. */ class_inf = (struct s_class *) my_malloc (num_class * sizeof (struct s_class)); pins_per_clb = 0; for (i=0;i<num_class;i++) { class_inf[i].type = OPEN; /* Flag for not set yet. */ class_inf[i].num_pins = 0; class_inf[i].pinlist = (int *) my_malloc (pins_per_class[i] * sizeof (int)); pins_per_clb += pins_per_class[i]; } free (pins_per_class); clb_pin_class = (int *) my_malloc (pins_per_clb * sizeof (int)); is_global_clb_pin = (boolean *) my_malloc (pins_per_clb * sizeof (int));/* Now allocate space for segment and switch information if the route_type * * is DETAILED. Otherwise ignore the segment and switch information, and * * create only one segment and one switch. */ if (route_type == GLOBAL) { num_segment = 1; num_switch = 1; } else { /* route_type == DETAILED */ num_switch += 2; /* Two extra switch types: 1 for zero delay, */ /* 1 for connections from wires to IPINs. */ } if (num_segment < 1) { printf ("Error: No segment information specified in architecture.\n"); exit (1); } *segment_inf_ptr = (t_segment_inf *) my_malloc (num_segment * sizeof (t_segment_inf)); det_routing_arch_ptr->num_segment = num_segment; if (num_switch < 1) { printf ("Error: No switch information specified in architecture.\n"); exit (1); } switch_inf = (struct s_switch_inf *) my_malloc (num_switch * sizeof (struct s_switch_inf)); for (i=0;i<num_switch;i++) switch_inf[i].R = -1.; /* Flag to show it's not set yet. */ det_routing_arch_ptr->num_switch = num_switch; if (num_T_subblock != 0) timing_inf_ptr->T_subblock = (t_T_subblock *) my_malloc (num_T_subblock * sizeof (t_T_subblock)); else timing_inf_ptr->T_subblock = NULL;}static int get_class (FILE *fp_arch, char *buf) {/* This routine is called when strtok has moved the pointer to just before * * the class: keyword. It advances the pointer to after the class * * descriptor and returns the class number. */ int iclass; char *ptr; ptr = my_strtok (NULL, TOKENS, fp_arch, buf); if (ptr == NULL) { printf("Error in get_class on line %d of architecture file.\n",linenum); printf("Expected class: keyword.\n"); exit (1); } if (strcmp (ptr, "class:") != 0) { printf("Error in get_class on line %d of architecture file.\n",linenum); printf("Expected class: keyword.\n"); exit (1); }/* Now get class number. */ ptr = my_strtok (NULL, TOKENS, fp_arch, buf); if (ptr == NULL) { printf("Error in get_class on line %d of architecture file.\n",linenum); printf("Expected class number.\n"); exit (1); } iclass = my_atoi (ptr); if (iclass < 0) { printf("Error in get_class on line %d of architecture file.\n",linenum); printf("Expected class number >= 0, got %d.\n", iclass); exit (1); } return (iclass);}static void get_pin (char *ptr, int pinnum, enum e_pin_type type, FILE *fp_arch, char *buf) {/* This routine parses an ipin or outpin line. It should be called right * * after the inpin, global_inpin, or outpin keyword has been parsed. */ int i, valid, iclass, ipin; char *position[4] = {"top", "bottom", "left", "right"}; iclass = get_class (fp_arch, buf); if (class_inf[iclass].type == OPEN) { /* First time through this class. */ class_inf[iclass].type = type; } else { if (class_inf[iclass].type != type) { printf("Error in get_pin: architecture file, line %d.\n", linenum); printf("Class %d contains both input and output pins.\n", iclass); exit (1); } } ipin = class_inf[iclass].num_pins; class_inf[iclass].pinlist[ipin] = pinnum; class_inf[iclass].num_pins++; clb_pin_class[pinnum] = iclass; ptr = my_strtok(NULL,TOKENS,fp_arch,buf); if (ptr == NULL) { printf("Error: pin statement specifies no locations, line %d.\n", linenum); exit(1); } if (type == RECEIVER && strcmp (ptr, "global") == 0) { is_global_clb_pin[pinnum] = TRUE; ptr = my_strtok (NULL, TOKENS, fp_arch, buf); if (ptr == NULL) { printf("Error: pin statement specifies no locations, line %d.\n", linenum); exit(1); } } else { is_global_clb_pin[pinnum] = FALSE; } do { valid = 0; for (i=0;i<=3;i++) { if (strcmp (ptr, position[i]) == 0) { pinloc[i][pinnum] = 1; valid = 1; break; } } if (valid != 1) { printf("Error: bad pin location on line %d.\n", linenum); exit(1); } } while((ptr = my_strtok(NULL,TOKENS,fp_arch,buf)) != NULL);}static enum e_Fc_type get_Fc_type (char *ptr, FILE *fp_arch, char *buf) {/* Sets the Fc_type to either ABSOLUTE or FRACTIONAL. */ enum e_Fc_type Fc_type; ptr = my_strtok (NULL, TOKENS, fp_arch, buf); if (ptr == NULL) { printf("Error: missing Fc_type value on line %d of " "architecture file.\n", linenum); exit (1); } if (strcmp (ptr, "absolute") == 0) { Fc_type = ABSOLUTE; } else if (strcmp (ptr, "fractional") == 0) { Fc_type = FRACTIONAL; } else { printf("Error: Bad Fc_type value (%s) on line %d of " "architecture file.\n", ptr, linenum); exit (1); } ptr = my_strtok (NULL, TOKENS, fp_arch, buf); if (ptr != NULL) { printf("Error: extra characters at end of line %d.\n", linenum); exit (1); } return (Fc_type);}static enum e_switch_block_type get_switch_block_type (FILE *fp_arch, char *buf) {/* Returns the proper value for the switch_block_type member of * * det_routing_arch. */ char *ptr; enum e_switch_block_type sblock_type; ptr = my_strtok (NULL, TOKENS, fp_arch, buf); if (ptr == NULL) { printf("Error: missing switch_block_type value on line %d of " "architecture file.\n", linenum); exit (1); } if (strcmp (ptr, "subset") == 0) { sblock_type = SUBSET; } else if (strcmp (ptr, "wilton") == 0) { sblock_type = WILTON; } else if (strcmp (ptr, "universal") == 0) { sblock_type = UNIVERSAL; } else { printf("Error: Bad switch_block_type value (%s) on line %d of " "architecture file.\n", ptr, linenum); exit (1); } ptr = my_strtok (NULL, TOKENS, fp_arch, buf); if (ptr != NULL) { printf("Error: extra characters at end of line %d.\n", linenum); exit (1); } return (sblock_type);}static void get_T_subblock (FILE *fp_arch, char *buf, t_T_subblock *T_subblock) {/* Parses one T_subblock line, and loads it into the t_T_subblock structure * * pointed to by T_subblock. */ char *ptr; check_keyword (fp_arch, buf, "T_comb:"); ptr = get_middle_token (fp_arch, buf); T_subblock->T_comb = atof (ptr); if (T_subblock->T_comb < 0.) { printf ("Error on line %d: T_comb value (%g) is negative.\n", linenum, T_subblock->T_comb); exit (1); } check_keyword (fp_arch, buf, "T_seq_in:"); ptr = get_middle_token (fp_arch, buf); T_subblock->T_seq_in = atof (ptr); if (T_subblock->T_seq_in < 0.) { printf ("Error on line %d: T_seq_in value (%g) is negative.\n", linenum, T_subblock->T_seq_in); exit (1); } check_keyword (fp_arch, buf, "T_seq_out:"); ptr = get_last_token (fp_arch, buf); T_subblock->T_seq_out = atof (ptr); if (T_subblock->T_seq_out < 0.) { printf ("Error on line %d: T_seq_out value (%g) is negative.\n", linenum, T_subblock->T_seq_out); exit (1); } }static void get_segment_inf (FILE *fp_arch, char *buf, t_segment_inf *seg_ptr, int num_switch, enum e_route_type route_type) {/* Loads the segment data structure pointed to by seg_ptr with the proper * * values from fp_arch, if route_type == DETAILED. */ char *ptr; int num_sb; if (route_type != DETAILED) { ptr = my_strtok (NULL, TOKENS, fp_arch, buf); while (ptr != NULL) /* Skip to the end of the line. */ ptr = my_strtok (NULL, TOKENS, fp_arch, buf); return; } check_keyword (fp_arch, buf, "frequency:"); ptr = get_middle_token (fp_arch, buf); seg_ptr->frequency = atof (ptr); if (seg_ptr->frequency <= 0. || seg_ptr->frequency > 1.) { printf ("Error on line %d: Frequency value (%g) is out of range.\n", linenum, seg_ptr->frequency); exit (1); } check_keyword (fp_arch, buf, "length:"); ptr = get_middle_token (fp_arch, buf); if (strcmp(ptr, "longline") == 0) { seg_ptr->length = -1; seg_ptr->longline = TRUE; } else { seg_ptr->length = my_atoi (ptr); seg_ptr->longline = FALSE; if (seg_ptr->length < 1) { printf ("Error on line %d: Length value (%d) is less than 1.\n", linenum, seg_ptr->length); exit (1); } } check_keyword (fp_arch, buf, "wire_switch:"); ptr = get_middle_token (fp_arch, buf); seg_ptr->wire_switch = my_atoi (ptr);/* Note: last two switch types are generated automatically. Shouldn't be * * used in the architecture file. */ if (seg_ptr->wire_switch < 0 || seg_ptr->wire_switch >= num_switch - 2) { printf ("Error on line %d: wire_switch value (%d) is out of range.\n", linenum, seg_ptr->wire_switch); exit (1); } check_keyword (fp_arch, buf, "opin_switch:"); ptr = get_middle_token (fp_arch, buf); seg_ptr->opin_switch = my_atoi (ptr);/* Note: last two switch types are generated automatically. Shouldn't be * * used in the architecture file. */ if (seg_ptr->opin_switch < 0 || seg_ptr->opin_switch >= num_switch - 2) { printf ("Error on line %d: opin_switch value (%d) is out of range.\n", linenum, seg_ptr->opin_switch); exit (1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -