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

📄 read_netlist.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 2 页
字号:
 ptr = my_strtok(NULL,TOKENS,fp_net,temp_buf); while (ptr != NULL) {    /* For each subblock pin. */    if (doall == 1) {       connect_to = get_pin_number (ptr);       if (ipin < subblock_lut_size) {      /* LUT input. */          subblock_inf[bnum][num_subblocks-1].inputs[ipin] = connect_to;       }       else if (ipin == subblock_lut_size) {   /* LUT output. */          subblock_inf[bnum][num_subblocks-1].output = connect_to;       }       else if (ipin == subblock_lut_size+1) {   /* Clock input. */          subblock_inf[bnum][num_subblocks-1].clock = connect_to;       }    }    ipin++;    ptr = my_strtok(NULL,TOKENS,fp_net,temp_buf); } if (ipin != subblock_lut_size + 2) {    printf("Error in load_subblock_array at line %d of netlist file.\n",            linenum);     printf("Subblock had %d pins, expected %d.\n", ipin,             subblock_lut_size+2);    printf("Aborting.\n\n");    exit (1); }}static void set_subblock_count (int bnum, int num_subblocks) {/* Sets the temporary subblock count for block bnum to num_subblocks. * * Properly allocates whatever temporary storage is needed.           */  if (bnum >= temp_block_storage) {    temp_block_storage *= 2;    num_subblocks_per_block = (int *) my_realloc             (num_subblocks_per_block, temp_block_storage * sizeof (int)); }  num_subblocks_per_block[bnum] = num_subblocks;}static char *parse_subblocks (int doall, FILE *fp_net, char *buf,               int bnum) {/* Loads the subblock arrays with the proper values. */ char temp_buf[BUFSIZE], *ptr; int num_subblocks; num_subblocks = 0; while (1) {    ptr = my_fgets (temp_buf, BUFSIZE, fp_net);    if (ptr == NULL)          break;          /* EOF */  /* Save line in case it's not a sublock */    strcpy (buf, temp_buf);    ptr = my_strtok(temp_buf,TOKENS,fp_net,temp_buf);    if (ptr == NULL)        continue;       /* Blank or comment line.  Skip. */    if (strcmp("subblock:", ptr) == 0) {       num_subblocks++;        load_subblock_array (doall, fp_net, temp_buf, num_subblocks,               bnum);    }    else {       break;  /* Subblock list has ended.  Buf contains next line. */    } }   /* End infinite while */ if (num_subblocks < 1 || num_subblocks > max_subblocks_per_block) {    printf("Error in parse_subblocks on line %d of netlist file.\n",         linenum);    printf("Block #%d has %d subblocks.  Out of range.\n",         bnum, num_subblocks);    printf("Aborting.\n\n");    exit (1); } if (doall == 0)    set_subblock_count (bnum, num_subblocks); else     assert (num_subblocks == num_subblocks_per_block[bnum]); return (ptr);}static char *add_clb (int doall, FILE *fp_net, char *buf) {/* Adds the clb (.clb) currently being parsed to the block array.  Adds * * its pins to the nets data structure by calling add_net.  If doall is * * zero this is a counting pass; if it is 1 this is the final (loading) * * pass.                                                                */ char *ptr; int pin_index, iclass, inet; enum e_pin_type type; num_blocks++; parse_name_and_pinlist (doall, fp_net, buf); num_clbs++; if (doall)     block[num_blocks - 1].type = CLB; pin_index = -1; ptr = my_strtok(NULL,TOKENS,fp_net,buf); while (ptr != NULL) {    pin_index++;    if (pin_index >= pins_per_clb) {       printf("Error in add_clb on line %d of netlist file.\n",linenum);       printf("Too many pins on this clb.  Expected %d.\n",pins_per_clb);       exit (1);    }        iclass = clb_pin_class[pin_index];    type = class_inf[iclass].type;      /* DRIVER or RECEIVER */    if (strcmp(ptr,"open") != 0) {     /* Pin is connected. */       inet = add_net (ptr, type, num_blocks-1, pin_index, doall);       if (doall)                      /* Loading pass only */          block[num_blocks - 1].nets[pin_index] = inet;     }    else {                             /* Pin is unconnected (open) */       if (doall)           block[num_blocks - 1].nets[pin_index] = OPEN;    }    ptr = my_strtok(NULL,TOKENS,fp_net,buf); } if (pin_index != pins_per_clb - 1) {    printf("Error in add_clb on line %d of netlist file.\n",linenum);    printf("Expected %d pins on clb, got %d.\n", pins_per_clb, pin_index + 1);    exit (1); } ptr = parse_subblocks (doall, fp_net, buf, num_blocks-1); return (ptr);}static void add_io (int doall, int block_type, FILE *fp_net, char *buf) {/* Adds the INPAD or OUTPAD (specified by block_type)  currently being  * * parsed to the block array.  Adds its pin to the nets data structure  * * by calling add_net.  If doall is zero this is a counting pass; if it * * is 1 this is the final (loading) pass.                               */ char *ptr; int inet, pin_index, i; enum e_pin_type type;  num_blocks++; if (doall == 0)    set_subblock_count (num_blocks-1, 0);    /* No subblocks for IO */ parse_name_and_pinlist (doall, fp_net, buf);  if (block_type == INPAD) {    num_p_inputs++;    type = DRIVER; } else {    num_p_outputs++;    type = RECEIVER; }  if (doall)    block[num_blocks - 1].type = block_type;  pin_index = -1; ptr = my_strtok(NULL,TOKENS,fp_net,buf);  while (ptr != NULL) {    pin_index++;    if (pin_index >= 1) {       printf("Error in add_io on line %d of netlist file.\n",linenum);       printf("Too many pins on this io.  Expected 1.\n");       exit (1);    }     if (strcmp(ptr,"open") == 0) {     /* Pin unconnected. */       printf("Error in add_io, line %d of netlist file.\n",linenum);       printf("Inputs and Outputs cannot have open pins.\n");       exit (1);    }   /* Note the dummy pin number for IO pins.  Change this if necessary. I set * * them to OPEN because I want the code to crash if I try to look up the   * * class of an I/O pin (since I/O pins don't have classes).                */    inet = add_net (ptr, type, num_blocks-1, OPEN, doall);     if (doall)                      /* Loading pass only */       block[num_blocks - 1].nets[pin_index] = inet;    ptr = my_strtok(NULL,TOKENS,fp_net,buf); }  if (pin_index != 0) {    printf("Error in add_io on line %d of netlist file.\n",linenum);    printf("Expected 1 pin on pad, got %d.\n", pin_index + 1);    exit (1); }  if (doall) {    for (i=1;i<pins_per_clb;i++)        block[num_blocks-1].nets[i] = OPEN; }}static void parse_name_and_pinlist (int doall, FILE *fp_net, char *buf) {/* This routine does the first part of the parsing of a block.  It is * * called whenever any type of block (.clb, .input or .output) is to  * * be parsed.  It increments the block count (num_blocks), and checks * * that the block has a name.  If doall is 1, this is the loading     * * pass and it copies the name to the block data structure.  Finally  * * it checks that the pinlist: keyword exists.  On return, my_strtok  * * is set so that the next call will get the first net connected to   * * this block.                                                        */ char *ptr; int len; /* Get block name. */  ptr = my_strtok(NULL,TOKENS,fp_net,buf); if (ptr == NULL) {    printf("Error in parse_name_and_pinlist on line %d of netlist file.\n",       linenum);    printf(".clb, .input or .output line has no associated name.\n");    exit (1); }  if (doall == 1) {    /* Second (loading) pass, store block name */    len = strlen (ptr);    block[num_blocks-1].name = my_chunk_malloc ((len + 1) * sizeof(char),                  NULL, &chunk_bytes_avail, &chunk_next_avail_mem);    strcpy (block[num_blocks-1].name, ptr); }  ptr = my_strtok (NULL,TOKENS,fp_net,buf); if (ptr != NULL) {    printf("Error in parse_name_and_pinlist on line %d of netlist file.\n",       linenum);    printf("Extra characters at end of line.\n");    exit (1); } /* Now get pinlist from the next line.  Note that a NULL return value * * from my_gets means EOF, while a NULL return from my_strtok just    * * means we had a blank or comment line.                              */  do {    ptr = my_fgets (buf, BUFSIZE, fp_net);    if (ptr == NULL) {       printf("Error in parse_name_and_pinlist on line %d of netlist file.\n",          linenum);       printf("Missing pinlist: keyword.\n");       exit (1);    }    ptr = my_strtok(buf,TOKENS,fp_net,buf); } while (ptr == NULL);  if (strcmp (ptr, "pinlist:") != 0) {    printf("Error in parse_name_and_pinlist on line %d of netlist file.\n",       linenum);    printf("Expected pinlist: keyword, got %s.\n",ptr);    exit (1); }}static void add_global (int doall, FILE *fp_net, char *buf) {/* Doall is 0 for the first (counting) pass and 1 for the second           * * (loading) pass.  fp_net is a pointer to the netlist file.  This         * * routine sets the proper entry(ies) in is_global to TRUE during the      * * loading pass.  The routine does nothing during the counting pass. If    * * is_global = TRUE for a net, it will not be considered in the placement  * * cost function, nor will it be routed.  This is useful for global        * * signals like clocks that generally have dedicated routing in FPGAs.     */ char *ptr; struct s_hash *h_ptr; int nindex;/* Do nothing if this is the counting pass. */ if (doall == 0)     return;  ptr = my_strtok(NULL,TOKENS,fp_net,buf); while (ptr != NULL) {     /* For each .global signal */    num_globals++;    h_ptr = get_hash_entry (hash_table, ptr);    if (h_ptr == NULL) {        /* Net was not found in list! */       printf("Error in add_global on netlist file line %d.\n",linenum);       printf("Global signal %s does not exist.\n",ptr);       exit(1);    }       nindex = h_ptr->index;    is_global[nindex] = TRUE;    /* Flagged as global net */    ptr = my_strtok(NULL,TOKENS,fp_net,buf); }}static int add_net (char *ptr, enum e_pin_type type, int bnum, int blk_pnum,           int doall) {   /* This routine is given a net name in *ptr, either DRIVER or RECEIVER * * specifying whether the block number given by bnum is driving this   * * net or in the fan-out and doall, which is 0 for the counting pass   * * and 1 for the loading pass.  It updates the net data structure and  * * returns the net number so the calling routine can update the block  * * data structure.                                                     */ struct s_hash *h_ptr; int j, nindex; if (doall == 0) {             /* Counting pass only */    h_ptr = insert_in_hash_table (hash_table, ptr, num_nets);    nindex = h_ptr->index;    if (nindex == num_nets)    /* Net was not in the hash table */       num_nets++;    return (nindex); } else {                        /* Load pass */    h_ptr = get_hash_entry (hash_table, ptr);    nindex = h_ptr->index;    if (h_ptr == NULL) {       printf("Error in add_net:  the second (load) pass found could not\n");        printf("find net %s in the symbol table.\n", ptr);       exit(1);    }    net[nindex].num_pins++;    if (type == DRIVER) {       num_driver[nindex]++;       j=0;           /* Driver always in position 0 of pinlist */    }        else {       j = net[nindex].num_pins - num_driver[nindex];   /* num_driver is the number of signal drivers of this net. *    * should always be zero or 1 unless the netlist is bad.   */       if (j >= temp_num_pins[nindex]) {          printf("Error:  Net #%d (%s) has no driver and will cause\n",             nindex, ptr);          printf("memory corruption.\n");          exit(1);       }     }       net[nindex].blocks[j] = bnum;    net[nindex].blk_pin[j] = blk_pnum;    return (nindex); }}static void free_parse (void) {  /* Release memory needed only during circuit netlist parsing. */ free (num_driver); free_hash_table (hash_table); free (temp_num_pins);}

⌨️ 快捷键说明

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