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

📄 check_netlist.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include "util.h"#include "vpr_types.h"#include "globals.h"#include "hash.h"#include "vpr_utils.h"#include "check_netlist.h"/**************** Subroutines local to this module **************************/static int check_connections_to_global_clb_pins (int inet);static int check_clb_conn (int iblk, int num_conn);static void check_for_multiple_sink_connections (void);static int check_for_duplicate_block_names (void);static int get_num_conn (int bnum);static int check_subblocks (int iblk, t_subblock_data *subblock_data_ptr,           int *num_uses_of_clb_pin, int *num_uses_of_sblk_opin); 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);static int check_internal_subblock_connections (t_subblock_data         *subblock_data_ptr, int iblk, int *num_uses_of_sblk_opin); static int check_clb_to_subblock_connections (int iblk, t_subblock         *subblock_inf, int num_subblocks, int *num_uses_of_clb_pin);/*********************** Subroutine definitions *****************************/void check_netlist (t_subblock_data *subblock_data_ptr, int *num_driver) {/* This routine checks that the netlist makes sense, and sets the num_ff    * * and num_const_gen members of subblock_data.                              */ int i, error, num_conn; int *num_uses_of_clb_pin, *num_uses_of_sblk_opin, *num_subblocks_per_block; num_subblocks_per_block = subblock_data_ptr->num_subblocks_per_block; subblock_data_ptr->num_ff = 0; subblock_data_ptr->num_const_gen = 0; error = 0; num_uses_of_clb_pin = (int *) my_malloc (pins_per_clb * sizeof (int)); num_uses_of_sblk_opin = (int *) my_malloc (                 subblock_data_ptr->max_subblocks_per_block * sizeof (int));/* Check that nets fanout and have a driver. */ for (i=0;i<num_nets;i++) {    if (num_driver[i] != 1) {       printf ("Error:  net %s has %d signals driving it.\n",           net[i].name,num_driver[i]);       error++;    }    if ((net[i].num_pins - num_driver[i]) < 1) {       printf("Error:  net %s has no fanout.\n",net[i].name);       error++;    }        error += check_connections_to_global_clb_pins (i); }/* Check that each block makes sense. */  for (i=0;i<num_blocks;i++) {    num_conn = get_num_conn (i);    if (block[i].type == CLB) {       error += check_clb_conn (i, num_conn);       error += check_subblocks (i, subblock_data_ptr, num_uses_of_clb_pin,                        num_uses_of_sblk_opin);    }        else {    /* IO block *//* This error check is a redundant double check.                 */       if (num_conn != 1) {          printf("Error:  io block #%d (%s) of type %d"             "has %d pins.\n", i, block[i].name, block[i].type,             num_conn);          error++;       }   /* IO blocks must have no subblock information. */       if (num_subblocks_per_block[i] != 0) {          printf("Error:  IO block #%d (%s) contains %d subblocks.\n"              "Expected 0.\n", i, block[i].name, num_subblocks_per_block[i]);          error++;       }    } }       check_for_multiple_sink_connections ();  error += check_for_duplicate_block_names (); free (num_uses_of_clb_pin); free (num_uses_of_sblk_opin);  if (error != 0) {    printf("Found %d fatal Errors in the input netlist.\n",error);    exit(1); }}static int check_connections_to_global_clb_pins (int inet) {/* Checks that a global net (inet) connects only to global CLB input pins  * * and that non-global nets never connects to a global CLB pin.  Either    * * global or non-global nets are allowed to connect to pads.               */ int ipin, num_pins, iblk, blk_pin, error; num_pins = net[inet].num_pins; error = 0;/* For now global signals can be driven by an I/O pad or any CLB output       * * although a CLB output generates a warning.  I could make a global CLB      * * output pin type to allow people to make architectures that didn't have     * * this warning.                                                              */ for (ipin=0;ipin<num_pins;ipin++) {    iblk = net[inet].blocks[ipin];    if (block[iblk].type == CLB) {  /* I/O pads are exempt. */       blk_pin = net[inet].blk_pin[ipin];       if (is_global_clb_pin[blk_pin] != is_global[inet]) {         /* Allow a CLB output pin to drive a global net (warning only). */          if (ipin == 0 && is_global[inet]) {                 printf ("Warning in check_connections_to_global_clb_pins:\n"                     "\tnet #%d (%s) is driven by CLB output pin (#%d)\n"                     "\ton block #%d (%s).\n", inet, net[inet].name,                     blk_pin, iblk, block[iblk].name);          }          else {      /* Otherwise -> Error */             printf ("Error in check_connections_to_global_clb_pins:\n"                   "\tpin %d on net #%d (%s) connects to CLB input pin (#%d)\n"                   "\ton block #%d (%s).\n", ipin, inet, net[inet].name,                    blk_pin, iblk, block[iblk].name);             error++;          }          if (is_global[inet])             printf ("\tNet is global, but CLB pin is not.\n\n");          else              printf ("\tCLB pin is global, but net is not.\n\n");       }    } }   /* End for all pins */  return (error);}static int check_clb_conn (int iblk, int num_conn) { /* Checks that the connections into and out of the clb make sense.  */  int iclass, ipin, error;  error = 0;  if (num_conn < 2) {    printf("Warning:  logic block #%d (%s) has only %d pin.\n",       iblk, block[iblk].name,num_conn); /* Allow the case where we have only one OUTPUT pin connected to continue. * * This is used sometimes as a constant generator for a primary output,    * * but I will still warn the user.  If the only pin connected is an input, * * abort.                                                                  */     if (num_conn == 1) {       for (ipin=0;ipin<pins_per_clb;ipin++) {          if (block[iblk].nets[ipin] != OPEN) {             iclass = clb_pin_class[ipin];                           if (class_inf[iclass].type != DRIVER) {                error++;             }             else {                printf("\tPin is an output -- may be a constant generator.\n"                       "\tNon-fatal, but check this.\n");             }                           break;          }       }      }         else {       error++;    }     } /* This case should already have been flagged as an error -- this is * * just a redundant double check.                                    */  if (num_conn > pins_per_clb) {    printf("Error:  logic block #%d with output %s has %d pins.\n",       iblk, block[iblk].name,num_conn);    error++; }  return (error);}static int check_for_duplicate_block_names (void) { /* Checks that all blocks have duplicate names.  Returns the number of     * * duplicate names.                                                        */  int error, iblk; struct s_hash **block_hash_table, *h_ptr; struct s_hash_iterator hash_iterator;  error = 0; block_hash_table = alloc_hash_table ();  for (iblk=0;iblk<num_blocks;iblk++)    h_ptr = insert_in_hash_table (block_hash_table, block[iblk].name, iblk);  hash_iterator = start_hash_table_iterator (); h_ptr = get_next_hash (block_hash_table, &hash_iterator);  while (h_ptr != NULL) {    if (h_ptr->count != 1) {       printf ("Error:  %d blocks are named %s.  Block names must be unique."               "\n", h_ptr->count, h_ptr->name);       error++;    }        h_ptr = get_next_hash (block_hash_table, &hash_iterator); }  free_hash_table (block_hash_table); return (error);} static int check_subblocks (int iblk, t_subblock_data *subblock_data_ptr,           int *num_uses_of_clb_pin, int *num_uses_of_sblk_opin) { /* This routine checks the subblocks of iblk (which must be a CLB).  It    * * returns the number of errors found.                                     */  int error, isub, ipin, clb_pin, i; int num_subblocks, max_subblocks_per_block, subblock_lut_size; t_subblock *subblock_inf;  error = 0; subblock_inf = subblock_data_ptr->subblock_inf[iblk]; num_subblocks = subblock_data_ptr->num_subblocks_per_block[iblk]; max_subblocks_per_block = subblock_data_ptr->max_subblocks_per_block; subblock_lut_size = subblock_data_ptr->subblock_lut_size;  if (num_subblocks < 1 || num_subblocks > max_subblocks_per_block) {    printf("Error:  block #%d (%s) contains %d subblocks.\n",           iblk, block[iblk].name, num_subblocks);    error++;   } /* Check that all pins connect to the proper type of CLB pin and are in the * * correct range.                                                           */ for (isub=0;isub<num_subblocks;isub++) {     for (ipin=0;ipin<subblock_lut_size;ipin++) {  /* Input pins */       clb_pin = subblock_inf[isub].inputs[ipin];       error += check_subblock_pin (clb_pin, 0, pins_per_clb +            num_subblocks - 1, RECEIVER, iblk, isub,             subblock_inf);    }              

⌨️ 快捷键说明

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