⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read_arch.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <string.h>#include <stdio.h>#include <math.h>#include "util.h"#include "vpr_types.h"#include "globals.h"#include "read_arch.h"/* This source file reads in the architectural description of an FPGA.       * * A # symbol anywhere in the input file denotes a comment to the end        * * of the line.  Put a \ at the end of a line if you want to continue        * * a command across multiple lines.   Non-comment lines are in the           * * format keyword value(s).  The entire file should be lower case.           * * The keywords and their arguments are:                                     * *                                                                           * *   io_rat integer (sets the number of io pads which fit into the           * *                  space one CLB would use).                                * *   chan_width_io float   (Width of the channels between the pads and       * *                          core relative to the widest core channel.)       * *   chan_width_x [gaussian|uniform|pulse] peak <width> <xpeak> <dc>.        * *       (<> bracketed quantities needed only for pulse and gaussian.        * *       Width and xpeak values from 0 to 1.  Sets the distribution of       * *       tracks for the x-directed channels.)                                * *       Other possibility:  delta peak xpeak dc.                            * *   chan_width_y [gaussian|uniform|pulse] peak <width> <xpeak> <dc>.        * *       (Sets the distribution of tracks for the y-directed channels.)      * *   outpin class: integer [top|bottom|left|right] [top|bottom|left|         * *       right] ...                                                          * *       (Sets the class to which each pin belongs and the side(s) of        * *       CLBs on which the physical output pin connection(s) is (are).       * *       All pins with the same class number are logically equivalent        * *       -- such as all the inputs of a LUT.  Class numbers must start       * *       at zero and be consecutive.)                                        * *   inpin class: integer <global> [top|bottom|left|right] [top|bottom|left| * *       right] ...                                                          * *       (All parameters have the same meanings as their counterparts        * *       in the outpin statement, except the optional global keyword.  If    * *       global is specified, this inpin can connect only to global nets.    * *       Global nets are not routed by the router, and are normally only     * *       things like clock nets.  A global pin has no switches connecting it * *       to the regular routing, so it takes up no area in the area model.)  * *                                                                           * *   NOTE:  The order in which your inpin and outpin statements appear       * *      must be the same as the order in which your netlist (.net)           * *      file lists the connections to the clbs.  For example, if the         * *      first pin on each clb in the netlist file is the clock pin,          * *      your first pin statement in the architecture file must be            * *      an inpin statement defining the clock pin.                           * *                                                                           * *   subblocks_per_clb <int>  (Number of LUT + ff logic blocks in each clb   *  *      at most).                                                            * *   subblock_lut_size <int>  (Number of inputs to each LUT in the           * *      clbs.  Each subblock has subblock_lut_size inputs, one output        * *      and a clock input.)                                                  * *                                                                           * *  The following parameters only need to be in the architecture             * *  file if detailed routing is going to be performed (i.e. route_type       * *  == DETAILED).                                                            * *                                                                           * *   Fc_type [absolute|fractional]  (Are the 3 Fc values absolute            * *      numbers of tracks to connect to, or the fraction of the W            * *      tracks to which each pin can connect?)                               * *   Fc_output float (Sets the value of Fc -- the number of tracks           * *      each pin can connect to in each channel bordering the pin --         * *      for output pins.  The Fc_output value used is always                 * *      min(W,Fc_selected), so set Fc to be huge if you want Fc = W.)        * *   Fc_input float (Sets the value of Fc for input pins.)                   * *   Fc_pad float (Sets the value of Fc for pads.)                           * *   switch_block_type [subset|wilton|universal] (Chooses the type of        * *      switch block used.  See vpr_types.h for details.)                    * *   segment frequency: <float> length: <int | longline> wire_switch: <int>  * *      opin_switch: <int> Frac_cb: <float> Frac_sb: <float> Rmetal: <float> * *      Cmetal: <float>                                                      * *      Describes one type of segment.  wire_switch is the type of           * *      switch used when going *to* a segment of this type from any CHANX or * *      CHANY routing segment.  opin_switch is the type of switch used       * *      by a clb or pad output driver (OPIN) to connect to segments of this  * *      type.  Cmetal is the capacitance per logic block spanned (i.e. per   * *      channel segment) of a routing track of this segment type.            * *      Similarly, Rmetal is the resistance per logic block spanned.         * *   switch  <int> buffered: {yes|no} R: <float> Cin: <float>                * *      Cout: <float> Tdel: <float>.  Describes a type of switch.            * *   R_minW_nmos <float>   Resistance, in Ohms, of a minimum width nmos      * *      transistor.  Used only in the transistor-level area model.           *   *   R_minW_pmos <float>   Resistance, in Ohms, of a minimum width pmos      *  *      transistor.  Used only in the transistor-level area model.           * *                                                                           * * The following parameters allow timing analysis.                           * *   C_ipin_cblock <float>: Input capacitance of the buffer isolating a      * *      routing track from the input pin Cboxes connected to it at each      * *      (i,j) location.                                                      * *   T_ipin_cblock <float>: Delay to go through a connection block to a      * *      logic block (clb) input pin.                                         * *   T_sblk_opin_to_sblk_ipin <float>: Delay through the local interconnect  * *      (muxes, wires or whatever) in a clb containing multiple subblocks.   * *      That is, the delay from a subblock output to the input of another    * *      subblock in the same clb.                                            * *   T_clb_ipin_to_sblk_ipin <float>: Delay from a clb input pin to any      * *      subblock input pin (e.g. the mux delay in an Altera 8K clb).         * *   T_sblk_opin_to_clb_opin <float>: Delay from a subblock output to a clb  * *      output.  Will be 0 in many architectures.                            * *   T_ipad:  Delay through an input pad.                                    * *   T_opad:  Delay through an output pad (setup time if you assume the      * *               outputs are registered before being sent out).              * *   T_subblock T_comb: <float>  T_seq_in: <float> T_seq_out: <float>        * *      The combinational delay through a subblock combinational mode), the  * *      delay from subblock input to data being latched (including setup     * *      time), and the delay from clock to data coming out of the subblock   * *      output (i.e. clk_to_Q plus any delays due to muxes, etc.).  If a     * *      subblock is being used in combinational mode (clock input is open)   * *      then Tcomb is used to find the delay through it.  If the subblock    * *      is being used in sequential mode (clock input not open) then         * *      T_seq_in gives the delay to the storage element and T_seq_out gives  * *      the delay from storage element to subblock output.  You need one     * *      of these T_subblock lines for each of the subblocks_per_clb          * *      subblocks in your architecture.  The first line gives the delays for * *      subblock 0 (first one listed for each logic block in the netlist     * *      file) and so on.                                                     *//******************* Defines and types local to this module *****************/#define NUM_REQUIRED 8    /* Number of parameters that are always required. */#define NUM_DETAILED 9  /* Number needed only if detailed routing used. */#define NUM_TIMING 8   /* Number needed only if timing analysis used.  */#define DETAILED_START NUM_REQUIRED#define TIMING_START (NUM_REQUIRED + NUM_DETAILED)/* Total number of different parameters in arch file. */#define NUMINP (NUM_REQUIRED + NUM_DETAILED + NUM_TIMING)/******************** Variables local to this module. **********************/static int isread[NUMINP];static const char *names[NUMINP] = {"io_rat", "chan_width_x", "chan_width_y",    "chan_width_io", "outpin", "inpin", "subblocks_per_clb",    "subblock_lut_size", "Fc_output", "Fc_input", "Fc_pad", "Fc_type",    "switch_block_type", "segment", "switch", "R_minW_nmos", "R_minW_pmos",   "C_ipin_cblock", "T_ipin_cblock", "T_sblk_opin_to_sblk_ipin",    "T_clb_ipin_to_sblk_ipin", "T_sblk_opin_to_clb_opin", "T_ipad", "T_opad",   "T_subblock"};/********************** Subroutines local to this module. ******************/static float get_float (char *ptr, int inp_num, float llim, float ulim,            FILE *fp_arch, char *buf); static float get_one_float (char *ptr, int inp_num, float low_lim,            float upp_lim, FILE *fp_arch, char *buf); static int get_int (char *ptr, int inp_num, FILE *fp_arch, char *buf,             int min_val);static char *get_middle_token (FILE *fp, char *buf); static char *get_last_token (FILE *fp, char *buf); static void check_keyword (FILE *fp, char *buf, const char *keyword); static void check_arch (char *arch_file, enum e_route_type route_type,            struct s_det_routing_arch det_routing_arch, t_segment_inf            *segment_inf, t_timing_inf timing_inf, int             max_subblocks_per_block, t_chan_width_dist chan_width_dist); static void fill_arch (void);static void get_chan (char *ptr, t_chan *chan, int inp_num, FILE *fp_arch,             char *buf); static void get_pin (char *ptr, int pinnum, enum e_pin_type type,             FILE *fp_arch, char *buf);static enum e_Fc_type get_Fc_type (char *ptr, FILE *fp_arch, char *buf); static enum e_switch_block_type get_switch_block_type (FILE *fp_arch,            char *buf); static void get_segment_inf (FILE *fp_arch, char *buf,            t_segment_inf *seg_ptr, int num_switch, enum e_route_type             route_type); static void get_switch_inf (FILE *fp_arch, char *buf, int num_switch,             enum e_route_type route_type); static void get_T_subblock (FILE *fp_arch, char *buf, t_T_subblock            *T_subblock); static int get_class (FILE *fp_arch, char *buf);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); static void load_extra_switch_types (struct s_det_routing_arch *            det_routing_arch, t_timing_inf *timing_inf); static void countpass (FILE *fp_arch, enum e_route_type route_type,             t_segment_inf **segment_inf_ptr, struct             s_det_routing_arch *det_routing_arch_ptr, t_timing_inf             *timing_inf); /****************** Subroutine definitions **********************************/void read_arch (char *arch_file, enum e_route_type route_type,       struct s_det_routing_arch *det_routing_arch, t_segment_inf        **segment_inf_ptr, t_timing_inf *timing_inf_ptr, t_subblock_data        *subblock_data_ptr, t_chan_width_dist *chan_width_dist_ptr) {/* Reads in the architecture description file for the FPGA. */ int i, j, pinnum, next_segment; char *ptr, buf[BUFSIZE]; FILE *fp_arch; t_T_subblock *next_T_subblock_ptr; fp_arch = my_fopen (arch_file, "r", 0); countpass (fp_arch, route_type, segment_inf_ptr, det_routing_arch,             timing_inf_ptr); rewind (fp_arch); linenum = 0; pinnum = 0; next_segment = 0; for (i=0;i<NUMINP;i++)     isread[i] = 0; pinloc = (int **) alloc_matrix (0, 3, 0, pins_per_clb-1, sizeof (int)); for (i=0;i<=3;i++)     for (j=0;j<pins_per_clb;j++)        pinloc[i][j] = 0; /* Initialize these two things to zero, since they're used in graph building * * and they needn't be set by the user if timing_analysis isn't enabled.     */ timing_inf_ptr->C_ipin_cblock = 0.; timing_inf_ptr->T_ipin_cblock = 0.;/* Start the main pass (pass 2).   */ while ((ptr = my_fgets(buf, BUFSIZE, fp_arch)) != NULL) {     ptr = my_strtok(ptr, TOKENS, fp_arch, buf);    if (ptr == NULL) continue;                   /* Empty or comment line *//* This linear compare is getting pretty long.  Could speed up with a hash * * table search -- do that if this starts getting slow.                    */    if (strcmp(ptr,names[0]) == 0) {  /* io_rat */       io_rat = get_int (ptr, 0, fp_arch, buf, 1);       continue;    }    if (strcmp(ptr,names[1]) == 0) { /*chan_width_x */       get_chan(ptr, &chan_width_dist_ptr->chan_x_dist, 1, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[2]) == 0) { /* chan_width_y */       get_chan(ptr, &chan_width_dist_ptr->chan_y_dist, 2, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[3]) == 0) { /* chan_width_io */       chan_width_dist_ptr->chan_width_io = get_one_float (ptr, 3, 0. ,5000.,                     fp_arch, buf);       continue;    }    if (strcmp(ptr,names[4]) == 0) { /* outpin */       get_pin (ptr, pinnum, DRIVER, fp_arch, buf);       pinnum++;       isread[4]++;       continue;       }    if (strcmp(ptr,names[5]) == 0) { /* inpin */       get_pin (ptr, pinnum, RECEIVER, fp_arch, buf);       pinnum++;       isread[5]++;       continue;    }    if (strcmp(ptr,names[6]) == 0) {  /* subblocks_per_clb */       subblock_data_ptr->max_subblocks_per_block = get_int (ptr, 6, fp_arch,                 buf, 1);       continue;    }    if (strcmp(ptr,names[7]) == 0) {  /* subblock_lut_size */       subblock_data_ptr->subblock_lut_size = get_int (ptr, 7, fp_arch, buf,                 1);       continue;    }    if (strcmp(ptr,names[DETAILED_START]) == 0) {  /* Fc_output */       det_routing_arch->Fc_output = get_one_float (ptr, DETAILED_START, 0.,                       1.e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[DETAILED_START + 1]) == 0) {  /* Fc_input */       det_routing_arch->Fc_input = get_one_float (ptr, DETAILED_START + 1, 0.,                        1.e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[DETAILED_START + 2]) == 0) {  /* Fc_pad */       det_routing_arch->Fc_pad = get_one_float (ptr, DETAILED_START + 2, 0.,                        1.e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[DETAILED_START + 3]) == 0) {   /* Fc_type */       det_routing_arch->Fc_type = get_Fc_type (ptr, fp_arch, buf);       isread[DETAILED_START + 3]++;       continue;    }    if (strcmp(ptr,names[DETAILED_START + 4]) == 0) {  /* switch_block_type */       det_routing_arch->switch_block_type =  get_switch_block_type (fp_arch,                   buf);       isread[DETAILED_START + 4]++;       continue;    }    if (strcmp(ptr,names[DETAILED_START + 5]) == 0) {  /* segment */       get_segment_inf (fp_arch, buf, *segment_inf_ptr + next_segment,               det_routing_arch->num_switch, route_type);       next_segment++;       isread[DETAILED_START + 5]++;       continue;    }    if (strcmp(ptr,names[DETAILED_START + 6]) == 0) {  /* switch */       get_switch_inf (fp_arch, buf, det_routing_arch->num_switch, route_type);       isread[DETAILED_START + 6]++;       continue;    }    if (strcmp(ptr,names[DETAILED_START + 7]) == 0) {  /* R_minW_nmos */       det_routing_arch->R_minW_nmos = get_one_float (ptr, DETAILED_START + 7,                        0., 1.e20, fp_arch, buf);       continue;    }        if (strcmp(ptr,names[DETAILED_START + 8]) == 0) {  /* R_minW_pmos */       det_routing_arch->R_minW_pmos = get_one_float (ptr, DETAILED_START + 8,                        0., 1.e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[TIMING_START]) == 0) {  /* C_ipin_cblock */       timing_inf_ptr->C_ipin_cblock = get_one_float (ptr, TIMING_START,                         -1e-30, 1e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[TIMING_START + 1]) == 0) {  /* T_ipin_cblock */       timing_inf_ptr->T_ipin_cblock = get_one_float (ptr, TIMING_START + 1,                        -1e-30, 1e20, fp_arch, buf);       continue;    }        if (strcmp(ptr,names[TIMING_START + 2]) == 0) {        /* T_sblk_opin_to_sblk_ipin */       timing_inf_ptr->T_sblk_opin_to_sblk_ipin = get_one_float (ptr,                TIMING_START + 2, -1e-30, 1e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[TIMING_START + 3]) == 0) {        /* T_clb_ipin_to_sblk_ipin */       timing_inf_ptr->T_clb_ipin_to_sblk_ipin = get_one_float (ptr,                TIMING_START + 3, -1e-30, 1e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[TIMING_START + 4]) == 0) {        /* T_sblk_opin_to_clb_opin */       timing_inf_ptr->T_sblk_opin_to_clb_opin = get_one_float (ptr,                TIMING_START + 4, -1e-30, 1e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[TIMING_START + 5]) == 0) {  /* T_ipad */       timing_inf_ptr->T_ipad = get_one_float (ptr, TIMING_START + 5,                         -1e-30, 1e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[TIMING_START + 6]) == 0) {  /* T_opad */       timing_inf_ptr->T_opad = get_one_float (ptr, TIMING_START + 6,                     -1e-30, 1e20, fp_arch, buf);       continue;    }    if (strcmp(ptr,names[TIMING_START + 7]) == 0) {  /* T_subblock */       next_T_subblock_ptr = timing_inf_ptr->T_subblock +                              isread[TIMING_START + 7];       get_T_subblock (fp_arch, buf, next_T_subblock_ptr);       isread[TIMING_START + 7]++;       continue;    }        printf ("Error:  unrecognized keyword (%s) on line %d.\n", ptr, linenum);    exit (1); } if (route_type == GLOBAL) {    load_global_segment_and_switch (det_routing_arch, *segment_inf_ptr,           timing_inf_ptr); } else {    load_extra_switch_types (det_routing_arch, timing_inf_ptr); }                check_arch (arch_file, route_type, *det_routing_arch, *segment_inf_ptr,       *timing_inf_ptr, subblock_data_ptr->max_subblocks_per_block,       *chan_width_dist_ptr); fclose (fp_arch);}static void countpass (FILE *fp_arch, enum e_route_type route_type,     t_segment_inf **segment_inf_ptr, struct s_det_routing_arch     *det_routing_arch_ptr, t_timing_inf *timing_inf_ptr) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -