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

📄 check_netlist.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Subblock output pin. */     clb_pin = subblock_inf[isub].output;    error += check_subblock_pin (clb_pin, 0, pins_per_clb - 1,             DRIVER, iblk, isub, subblock_inf);              /* Subblock clock pin. */     clb_pin = subblock_inf[isub].clock;    error += check_subblock_pin (clb_pin, 0, pins_per_clb +             num_subblocks - 1, RECEIVER, iblk, isub,             subblock_inf);               }  /* End subblock for loop. */ /* If pins out of range, return.  Could get seg faults otherwise. */ if (error != 0)       return (error);/* Reset fanout counts. */ for (i=0;i<pins_per_clb;i++)     num_uses_of_clb_pin[i] = 0; for (i=0;i<num_subblocks;i++)     num_uses_of_sblk_opin[i] = 0; load_one_clb_fanout_count (subblock_lut_size, subblock_inf,         num_subblocks, num_uses_of_clb_pin,         num_uses_of_sblk_opin, iblk); error += check_clb_to_subblock_connections (iblk, subblock_inf,         num_subblocks, num_uses_of_clb_pin);  error += check_internal_subblock_connections (subblock_data_ptr, iblk,         num_uses_of_sblk_opin); return (error);}static int check_subblock_pin (int clb_pin, int min_val, int max_val,     enum e_pin_type pin_type, int iblk, int isubblk, t_subblock      *subblock_inf) { /* Checks that this subblock pin connects to a valid clb pin or BLE output * * within the clb.  Returns the number of errors found.                    */  int iclass;  if (clb_pin != OPEN) {    if (clb_pin < min_val || clb_pin > max_val) {       printf("Error:  Block #%d (%s) subblock #%d (%s)"             "connects to nonexistent clb pin #%d.\n", iblk, block[iblk].name,             isubblk, subblock_inf[isubblk].name, clb_pin);       return (1);    }     if (clb_pin < pins_per_clb) {  /* clb pin */       iclass = clb_pin_class[clb_pin];       if (class_inf[iclass].type != pin_type) {          printf ("Error:  Block #%d (%s) subblock #%d (%s) pin connects\n"               "\tto clb pin (#%d) of wrong input/output type.\n", iblk,               block[iblk].name, isubblk, subblock_inf[isubblk].name,               clb_pin);          return (1);       }    } }       return (0);}static void check_for_multiple_sink_connections (void) { /* The check is for nets that connect more than once to the same class of  * * pins on the same block.  For LUTs and cluster-based logic blocks that   * * doesn't make sense, although for some logic blocks it does.  The router * * can now handle this case, so maybe I should get rid of this check.      */  int iblk, ipin, inet, iclass, class_pin; int *num_pins_connected;  num_pins_connected = my_calloc (num_nets, sizeof (int)); /* Have to do the check block by block, rather than net by net, for speed. * * This makes the code a bit messy.                                        */  for (iblk=0;iblk<num_blocks;iblk++) {    for (iclass=0;iclass<num_class;iclass++) { /* Two DRIVER pins can never connect to the same net (already checked by    * * the multiple driver check) so skip that check.                           */        if (class_inf[iclass].type == DRIVER)          continue;        for (class_pin=0;class_pin<class_inf[iclass].num_pins;class_pin++) {          ipin = class_inf[iclass].pinlist[class_pin];          inet = block[iblk].nets[ipin];           if (inet != OPEN)             num_pins_connected[inet]++;       }              for (class_pin=0;class_pin<class_inf[iclass].num_pins;class_pin++) {           ipin = class_inf[iclass].pinlist[class_pin];          inet = block[iblk].nets[ipin];           if (inet != OPEN) {             if (num_pins_connected[inet] > 1) {                printf("Warning:  block %d (%s) connects %d pins of class "                     "%d to net %d (%s).\n", iblk, block[iblk].name,                      num_pins_connected[inet], iclass, inet, net[inet].name);                printf("\tThis does not make sense for many logic blocks "                       "(e.g. LUTs).\n"                       "\tBe sure you really want this.\n");             }                           num_pins_connected[inet] = 0;          }       }    }      }       free (num_pins_connected);}static int get_num_conn (int bnum) {/* This routine returns the number of connections to a block. */ int i, num_conn; num_conn = 0; for (i=0;i<pins_per_clb;i++) {    if (block[bnum].nets[i] != OPEN)       num_conn++; } return (num_conn);}static int check_internal_subblock_connections (t_subblock_data         *subblock_data_ptr, int iblk, int *num_uses_of_sblk_opin) {/* This routine checks that all subblocks in this block are either           * * completely empty (no pins hooked to anything) or have their output used   * * somewhere.  It also counts the number of constant generators (no input    * * sblks) and the number of FFs used in the circuit.                         */ int num_const_gen, num_ff, isub, ipin, error; boolean has_inputs; int subblock_lut_size; int num_subblocks; t_subblock *subblock_inf;   subblock_lut_size = subblock_data_ptr->subblock_lut_size; num_subblocks = subblock_data_ptr->num_subblocks_per_block[iblk]; subblock_inf = subblock_data_ptr->subblock_inf[iblk];  num_const_gen = 0; num_ff = 0; error = 0;  for (isub=0;isub<num_subblocks;isub++) {     has_inputs = FALSE;    for (ipin=0;ipin<subblock_lut_size;ipin++) {       if (subblock_inf[isub].inputs[ipin] != OPEN) {          has_inputs = TRUE;          break;       }    }    if (num_uses_of_sblk_opin[isub] == 0) {   /* Output unused */       if (has_inputs || subblock_inf[isub].clock != OPEN) {          printf ("Error:  output of subblock #%d (%s) of block #%d (%s) is "                  "never used.\n", isub, subblock_inf[isub].name, iblk,                   block[iblk].name);          error++;       }    }     /* End if output unused */       /* Check that subblocks whose output is used have inputs. */      else {   /* Subblock output is used. */        if (!has_inputs) {   /* No inputs are used */          if (subblock_inf[isub].clock == OPEN) {             printf ("Warning:  block #%d (%s), subblock #%d (%s) is a "                 "constant generator.\n\t(Has no inputs.)\n", iblk,                  block[iblk].name, isub, subblock_inf[isub].name);             num_const_gen++;          }          else {             printf ("Error:  block #%d (%s), subblock #%d (%s) is a CLOCKED "               "\n\tconstant generator.\n\t(Has no inputs but is clocked.)\n",                  iblk, block[iblk].name, isub, subblock_inf[isub].name);             num_const_gen++;             error++;          }       }        else {   /* Both input and output are used */          if (subblock_inf[isub].clock != OPEN)             num_ff++;       }    } }   /* End for all subblocks */  subblock_data_ptr->num_const_gen += num_const_gen; subblock_data_ptr->num_ff += num_ff; return (error);}static int check_clb_to_subblock_connections (int iblk, t_subblock          *subblock_inf, int num_subblocks, int *num_uses_of_clb_pin) {/* This routine checks that each non-OPEN clb input pin connects to some    * * subblock inputs, and that each non-OPEN clb output pin is driven by      * * exactly one subblock output. It returns the number of errors found.      * * Note that num_uses_of_clb_pin is used to store the number of out-edges   * * (fanout) for a CLB ipin, and the number of in-edges (fanin) for a CLB    * * opin.                                                                    */ int ipin, isub, clb_pin, error; error = 0;/* Count how many things connect to each clb output pin. */ for (isub=0;isub<num_subblocks;isub++) {    clb_pin = subblock_inf[isub].output;     if (clb_pin != OPEN)   /* Guaranteed to connect to DRIVER pin only */       num_uses_of_clb_pin[clb_pin]++; } for (ipin=0;ipin<pins_per_clb;ipin++) {    if (block[iblk].nets[ipin] != OPEN) {       if (is_opin(ipin)) {   /* CLB output */          if (num_uses_of_clb_pin[ipin] == 0) {  /* No driver? */             printf ("Error:  output pin %d on block #%d (%s) is not driven "                     "by any subblock.\n", ipin, iblk, block[iblk].name);             error++;          }          else if (num_uses_of_clb_pin[ipin] > 1) {  /* Multiple drivers? */             printf ("Error:  output pin %d on block #%d (%s) is driven "                     "by %d subblocks.\n", ipin, iblk, block[iblk].name,                      num_uses_of_clb_pin[ipin]);             error++;          }       }       else {   /* CLB ipin */          if (num_uses_of_clb_pin[ipin] <= 0) {    /* Fans out? */             printf ("Error:  pin %d on block #%d (%s) does not fanout to any "                     "subblocks.\n", ipin, iblk, block[iblk].name);             error++;          }       }    }   /* End if not OPEN */    else if (is_opin(ipin)) {   /* OPEN CLB output pin */       if (num_uses_of_clb_pin[ipin] > 1) {          printf ("Error:  pin %d on block #%d (%s) is driven by %d "                  "subblocks.\n", ipin, iblk, block[iblk].name,                   num_uses_of_clb_pin[ipin]);          error++;       }    } }       return (error);}

⌨️ 快捷键说明

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