📄 read_arch.c
字号:
} check_keyword (fp_arch, buf, "Frac_cb:"); ptr = get_middle_token (fp_arch, buf); seg_ptr->frac_cb = atof (ptr); if (seg_ptr->frac_cb < 0. || seg_ptr->frac_cb > 1.) { printf ("Error on line %d: Frac_cb value (%g) is out of range.\n", linenum, seg_ptr->frac_cb); exit (1); } check_keyword (fp_arch, buf, "Frac_sb:"); ptr = get_middle_token (fp_arch, buf); seg_ptr->frac_sb = atof (ptr); if (seg_ptr->frac_sb < 0. || seg_ptr->frac_sb > 1.) { printf ("Error on line %d: Frac_sb value (%g) is out of range.\n", linenum, seg_ptr->frac_sb); exit (1); } if (seg_ptr->longline == FALSE) {/* Need at least two switch boxes along the length of non-longline segments * * to ensure all switches line up (at least for planar sboxes). */ num_sb = nint ((seg_ptr->length + 1) * seg_ptr->frac_sb); if (num_sb < 2) { printf ("Error on line %d: Frac_sb value results in only %d switch " "boxes.\n" "Minimum 2 switch boxes on non-longline segments.\n", linenum, num_sb); exit (1); } } check_keyword (fp_arch, buf, "Rmetal:"); ptr = get_middle_token (fp_arch, buf); seg_ptr->Rmetal = atof (ptr); if (seg_ptr->Rmetal < 0.) { printf ("Error on line %d: Rmetal value (%g) is out of range.\n", linenum, seg_ptr->Rmetal); exit (1); } check_keyword (fp_arch, buf, "Cmetal:"); ptr = get_last_token (fp_arch, buf); seg_ptr->Cmetal = atof (ptr); if (seg_ptr->Cmetal < 0.) { printf ("Error on line %d: Cmetal value (%g) is out of range.\n", linenum, seg_ptr->Cmetal); exit (1); }}static void get_switch_inf (FILE *fp_arch, char *buf, int num_switch, enum e_route_type route_type) {/* Loads up all the switch information. */ char *ptr; int index; 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; } ptr = get_middle_token (fp_arch, buf); index = my_atoi (ptr); if (index < 0) { printf ("Error on line %d: switch number (%d) is out of range.\n", linenum, index); exit (1); } if (index >= num_switch) { printf ("Error on line %d: switch numbers are not consecutive or do \n" "\tnot start at 0.\n", linenum); exit (1); } if (switch_inf[index].R >= 0.) { printf ("Error on line %d: switch %d properties already set.\n", linenum, index); exit (1); } check_keyword (fp_arch, buf, "buffered:"); ptr = get_middle_token (fp_arch, buf); if (strcmp (ptr, "yes") == 0) { switch_inf[index].buffered = TRUE; } else if (strcmp (ptr, "no") == 0) { switch_inf[index].buffered = FALSE; } else { printf ("Error on line %d: invalid buffered value: %s.\n", linenum, ptr); exit (1); } check_keyword (fp_arch, buf, "R:"); ptr = get_middle_token (fp_arch, buf); switch_inf[index].R = atof (ptr); if (switch_inf[index].R < 0) { printf ("Error on line %d: resistance value (%g) is negative.\n", linenum, switch_inf[index].R); exit (1); } check_keyword (fp_arch, buf, "Cin:"); ptr = get_middle_token (fp_arch, buf); switch_inf[index].Cin = atof (ptr); if (switch_inf[index].Cin < 0) { printf ("Error on line %d: capacitance value (%g) is negative.\n", linenum, switch_inf[index].Cin); exit (1); } check_keyword (fp_arch, buf, "Cout:"); ptr = get_middle_token (fp_arch, buf); switch_inf[index].Cout = atof (ptr); if (switch_inf[index].Cout < 0) { printf ("Error on line %d: capacitance value (%g) is negative.\n", linenum, switch_inf[index].Cout); exit (1); } if (switch_inf[index].buffered == FALSE && switch_inf[index].Cout != switch_inf[index].Cin) { printf ("Error on line %d: Cin (%g) and Cout (%g) differ for a " "pass transitor (switch #%d).\n", linenum, switch_inf[index].Cin, switch_inf[index].Cout, index); exit (1); } check_keyword (fp_arch, buf, "Tdel:"); ptr = get_last_token (fp_arch, buf); switch_inf[index].Tdel = atof (ptr); if (switch_inf[index].Tdel < 0) { printf ("Error on line %d: delay value (%g) is negative.\n", linenum, switch_inf[index].Tdel); exit (1); }}static void load_global_segment_and_switch (struct s_det_routing_arch * det_routing_arch, t_segment_inf *segment_inf, t_timing_inf *timing_inf) {/* Loads up the one segment type (unit length segment) and one switch type * * (pass transistor) needed to make the graph builder allow global routing. * * Also sets the switch block type to SUBSET (works for global routing). */ det_routing_arch->switch_block_type = SUBSET; det_routing_arch->Fc_output = 1.; det_routing_arch->Fc_input = 1.; det_routing_arch->Fc_pad = 1.; det_routing_arch->Fc_type = ABSOLUTE; det_routing_arch->delayless_switch = 0; det_routing_arch->wire_to_ipin_switch = 0; segment_inf[0].frequency = 1.; segment_inf[0].length = 1; segment_inf[0].wire_switch = 0; segment_inf[0].opin_switch = 0; segment_inf[0].frac_cb = 1.; segment_inf[0].frac_sb = 1.; segment_inf[0].longline = FALSE; segment_inf[0].Rmetal = 0.; segment_inf[0].Cmetal = 0.; switch_inf[0].buffered = TRUE; switch_inf[0].R = 0.; switch_inf[0].Cin = 0.; switch_inf[0].Cout = 0.; switch_inf[0].Tdel = 1.; /* Need increasing delay with distance from */ /* source or the timing-driven router won't work for global routing. */}static void load_extra_switch_types (struct s_det_routing_arch * det_routing_arch, t_timing_inf *timing_inf) {/* Adds two extra switches to the routing architecture. One is a zero delay, * * zero C switch that I use to make connections that should have no delay. * * The other is a switch that models the buffer + connection block delay * * that occurs when one goes from wire segments to IPINs. */ int delayless_switch, wire_to_ipin_switch; delayless_switch = det_routing_arch->num_switch - 1; det_routing_arch->delayless_switch = delayless_switch; wire_to_ipin_switch = det_routing_arch->num_switch - 2; det_routing_arch->wire_to_ipin_switch = wire_to_ipin_switch; if (switch_inf[delayless_switch].R >= 0. || switch_inf[wire_to_ipin_switch].R >= 0.) { printf ("Error: switch indices are not consecutive or do not start at 0." "\n"); exit (1); } switch_inf[delayless_switch].buffered = TRUE; switch_inf[delayless_switch].R = 0.; switch_inf[delayless_switch].Cin = 0.; switch_inf[delayless_switch].Cout = 0.; switch_inf[delayless_switch].Tdel = 0.; switch_inf[wire_to_ipin_switch].buffered = TRUE; switch_inf[wire_to_ipin_switch].R = 0.; switch_inf[wire_to_ipin_switch].Cin = timing_inf->C_ipin_cblock; switch_inf[wire_to_ipin_switch].Cout = 0.; switch_inf[wire_to_ipin_switch].Tdel = timing_inf->T_ipin_cblock;}static void check_keyword (FILE *fp, char *buf, const char *keyword) {/* Checks that the next token (which must be a middle token) is the proper * * keyword. */ char *ptr; ptr = get_middle_token (fp, buf); if (strcmp (ptr, keyword) != 0) { printf ("Error on line %d: Expected keyword %s, got %s.\n", linenum, keyword, ptr); exit (1); }}static char *get_middle_token (FILE *fp, char *buf) {/* Gets the next token and prints an error message if it is the last one. * * This token also can't be the first token. */ char *ptr; ptr = my_strtok (NULL, TOKENS, fp, buf); if (ptr == NULL) { printf("Error: line %d is incomplete.\n", linenum); exit (1); } return (ptr);}static char *get_last_token (FILE *fp, char *buf) {/* Gets the next token and prints an error message if it isn't the last one. */ char *ptr, *ptr2; ptr = get_middle_token (fp, buf); ptr2 = my_strtok (NULL, TOKENS, fp, buf); if (ptr2 != NULL) { printf("Error: Extra characters at end of line %d.\n", linenum); exit (1); } return (ptr);}static int get_int (char *ptr, int inp_num, FILE *fp_arch, char *buf, int min_val) {/* This routine gets the next integer on the line. It must be greater * * than or equal to min_val or an error message is printed. */ int val; ptr = my_strtok(NULL,TOKENS,fp_arch,buf); if (ptr == NULL) { printf("Error: missing %s value on line %d.\n", names[inp_num],linenum); exit(1); } val = my_atoi(ptr); if (val < min_val) { printf("Error: Bad value. %s = %d on line %d.\n", names[inp_num],val,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); } isread[inp_num]++; return(val);}static float get_one_float (char *ptr, int inp_num, float low_lim, float upp_lim, FILE *fp_arch, char *buf) {/* This routine gets one floating point number from ptr. It checks that * * there are no extra characters at the end of the line, and updates isread. * * Use this routine when you need to only read "var = float" type lines. */ float val; val = get_float (ptr, inp_num, low_lim, upp_lim, fp_arch, buf); ptr = my_strtok (NULL, TOKENS, fp_arch, buf); if (ptr != NULL) { printf("Error: extra characters at end of line %d.\n", linenum); exit (1); } isread[inp_num]++; return (val);}static float get_float (char *ptr, int inp_num, float low_lim, float upp_lim, FILE *fp_arch, char *buf) {/* This routine gets the floating point number that is next on the line. * * low_lim and upp_lim specify the allowable range of numbers, while * * inp_num gives the type of input line being parsed. */ float val; ptr = my_strtok(NULL,TOKENS,fp_arch,buf); if (ptr == NULL) { printf("Error: missing %s value on line %d.\n", names[inp_num],linenum); exit(1); } val = atof(ptr); if (val <= low_lim || val > upp_lim) { printf("Error: Bad value parsing %s. %g on line %d.\n", names[inp_num],val,linenum); exit(1); } return(val);}/* Order: chan_width_x [gaussian|uniform|pulse] peak <width> * * <xpeak> <dc>. (Bracketed quantities needed only for pulse * * and gaussian). All values from 0 to 1, except peak and dc, * * which can be anything. * * Other possibility: chan_width_x delta peak xpeak dc */static void get_chan (char *ptr, t_chan *chan, int inp_num, FILE *fp_arch, char *buf) {/* This routine parses a channel functional description line. chan * * is the channel data structure to be loaded, while inp_num is the * * type of input line being parsed. */ ptr = my_strtok(NULL,TOKENS,fp_arch,buf); if (ptr == NULL) { printf("Error: missing %s value on line %d.\n", names[inp_num],linenum); exit(1); } if (strcmp(ptr,"uniform") == 0) { isread[inp_num]++; chan->type = UNIFORM; chan->peak = get_float(ptr,inp_num,0.,1., fp_arch, buf); chan->dc = OPEN; chan->width = OPEN; chan->xpeak = OPEN; } else if (strcmp(ptr,"delta") == 0) { isread[inp_num]++; chan->type = DELTA; chan->peak = get_float(ptr,inp_num,-1.e5,1.e5, fp_arch, buf); chan->xpeak = get_float(ptr,inp_num,-1e-30,1., fp_arch, buf); chan->dc = get_float(ptr,inp_num,-1e-30,1., fp_arch, buf); chan->width = OPEN; } else { if (strcmp(ptr,"gaussian") == 0) chan->type = GAUSSIAN; if (strcmp(ptr,"pulse") == 0) chan->type = PULSE; if (chan->type == GAUSSIAN || chan->type == PULSE) { isread[inp_num]++; chan->peak = get_float(ptr,inp_num,-1.,1., fp_arch, buf); chan->width = get_float(ptr,inp_num,0.,1.e10, fp_arch, buf); chan->xpeak = get_float(ptr,inp_num,-1e-30,1., fp_arch, buf); chan->dc = get_float(ptr,inp_num,-1e-30,1., fp_arch, buf); } } if (isread[inp_num] == 0) { printf("Error: %s distribution keyword: %s unknown.\n", names[inp_num],ptr); exit(1); } if (my_strtok(NULL,TOKENS,fp_arch,buf) != NULL) { printf("Error: extra value for %s at end of line %d.\n", names[inp_num],linenum); exit(1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -