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

📄 read_blif.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>#include <stdio.h>#include "util.h"#include "vpack.h"#include "globals.h"#include "read_blif.h"/* This source file will read in a FLAT blif netlist consisting     ** of .inputs, .outputs, .names and .latch commands.  It currently   ** does not handle hierarchical blif files.  Hierarchical            ** blif files can be flattened via the read_blif and write_blif      ** commands of sis.  LUT circuits should only have .names commands;  ** there should be no gates.  This parser performs limited error     ** checking concerning the consistency of the netlist it obtains.    ** .inputs and .outputs statements must be given; this parser does   ** not infer primary inputs and outputs from non-driven and fanout   ** free nodes.  This parser can be extended to do this if necessary, ** or the sis read_blif and write_blif commands can be used to put a ** netlist into the standard format.                                 ** V. Betz, August 25, 1994.                                         ** Added more error checking, March 30, 1995, V. Betz                */static int *num_driver, *temp_num_pins;/* # of .input, .output, .model and .end lines */static int ilines, olines, model_lines, endlines;  static struct hash_nets **hash;static char *model;static FILE *blif;static int add_net (char *ptr, int type, int bnum, int doall); static void get_tok(char *buffer, int pass, int doall, int *done,         int lut_size);static void init_parse(int doall);static void check_net (int lut_size);static void free_parse (void);static void io_line (int in_or_out, int doall);static void add_lut (int doall, int lut_size);static void add_latch (int doall, int lut_size);static void dum_parse (char *buf);static int hash_value (char *name);void read_blif (char *blif_file, int lut_size) { char buffer[BUFSIZE]; int pass, done, doall; blif = my_fopen (blif_file, "r", 0); for (doall=0;doall<=1;doall++) {    init_parse(doall);/* Three passes to ensure inputs are first blocks, outputs second and    * * LUTs and latches third.  Just makes the output netlist more readable. */    for (pass=1;pass<=3;pass++) {        linenum = 0;   /* Reset line number. */       done = 0;       while((my_fgets(buffer,BUFSIZE,blif) != NULL) && !done) {          get_tok(buffer, pass, doall, &done, lut_size);       }       rewind (blif);  /* Start at beginning of file again */    } }  fclose(blif); check_net(lut_size); free_parse();}static void init_parse(int doall) {/* Allocates and initializes the data structures needed for the parse. */ int i, len; struct hash_nets *h_ptr; if (!doall) {  /* Initialization before first (counting) pass */    num_nets = 0;      hash = (struct hash_nets **) my_calloc(sizeof(struct hash_nets *),            HASHSIZE); }/* Allocate memory for second (load) pass */  else {       net = (struct s_net *) my_malloc(num_nets*sizeof(struct s_net));    block = (struct s_block *) my_malloc(num_blocks*        sizeof(struct s_block));       num_driver = (int *) my_malloc(num_nets * sizeof(int));    temp_num_pins = (int *) my_malloc(num_nets*sizeof(int));    for (i=0;i<num_nets;i++) {       num_driver[i] = 0;       net[i].num_pins = 0;    }    for (i=0;i<HASHSIZE;i++) {       h_ptr = hash[i];          while (h_ptr != NULL) {          net[h_ptr->index].pins = (int *) my_malloc(h_ptr->count*sizeof(int));/* For avoiding assigning values beyond end of pins array. */          temp_num_pins[h_ptr->index] = h_ptr->count;          len = strlen (h_ptr->name);          net[h_ptr->index].name = (char *) my_malloc ((len + 1)* sizeof(char));          strcpy (net[h_ptr->index].name, h_ptr->name);          h_ptr = h_ptr->next;       }    }/*    printf("i\ttemp_num_pins\n\n");    for (i=0;i<num_nets;i++) {       printf("%d\t%d\n",i,temp_num_pins[i]);    }  */ }/* Initializations for both passes. */ ilines = 0; olines = 0; model_lines = 0; endlines = 0; num_p_inputs = 0; num_p_outputs = 0; num_luts = 0; num_latches = 0; num_blocks = 0;}static void get_tok (char *buffer, int pass, int doall, int *done,       int lut_size) {/* Figures out which, if any token is at the start of this line and * * takes the appropriate action.                                    */#define TOKENS " \t\n" char *ptr;   ptr = my_strtok(buffer,TOKENS,blif,buffer); if (ptr == NULL) return;   if (strcmp(ptr,".names") == 0) {    if (pass == 3) {       add_lut(doall, lut_size);    }    else {       dum_parse(buffer);    }    return; } if (strcmp(ptr,".latch") == 0) {    if (pass == 3) {       add_latch (doall, lut_size);    }    else {       dum_parse(buffer);    }    return; } if (strcmp(ptr,".model") == 0) {    ptr = my_strtok(NULL,TOKENS,blif,buffer);    if (doall && pass == 3) { /* Only bother on main second pass. */       if (ptr != NULL) {          model = (char *) my_malloc ((strlen(ptr)+1) * sizeof(char));          strcpy(model,ptr);       }       else {          model = (char *) my_malloc (sizeof(char));          model[0] = '\0';       }       model_lines++;              /* For error checking only */    }    return; } if (strcmp(ptr,".inputs") == 0) {    if (pass == 1) {       io_line(DRIVER, doall);       *done = 1;    }    else {       dum_parse(buffer);       if (pass == 3 && doall) ilines++;    /* Error checking only */    }    return; } if (strcmp(ptr,".outputs") == 0) {    if (pass == 2) {       io_line(RECEIVER, doall);       *done = 1;    }    else {       dum_parse(buffer);       if (pass == 3 && doall) olines++;  /* Make sure only one .output line */    }                            /* For error checking only */    return; } if (strcmp(ptr,".end") == 0) {    if (pass == 3 && doall) endlines++;   /* Error checking only */    return; }/* Could have numbers following a .names command, so not matching any * * of the tokens above is not an error.                               */}static void dum_parse (char *buf) {/* Continue parsing to the end of this (possibly continued) line. */ while (my_strtok(NULL,TOKENS,blif,buf) != NULL)       ;}static void add_lut (int doall, int lut_size) {/* Adds a LUT (.names) 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, saved_names[MAXLUT+2][BUFSIZE], buf[BUFSIZE]; int i, j, len; num_blocks++;/* Count # nets connecting */ i=0; while ((ptr = my_strtok(NULL,TOKENS,blif,buf)) != NULL)  {    if (i == MAXLUT+1) {       fprintf(stderr,"Error:  LUT #%d has %d inputs.  Increase MAXLUT or"            " check the netlist, line %d.\n",num_blocks-1,i-1,linenum);       exit(1);    }    strcpy (saved_names[i], ptr);    i++; } if (!doall) {          /* Counting pass only ... */    for (j=0;j<i;j++)        add_net(saved_names[j],RECEIVER,num_blocks-1,doall);    return; } block[num_blocks-1].num_nets = i; block[num_blocks-1].type = LUT; for (i=0;i<block[num_blocks-1].num_nets-1;i++)   /* Do inputs */    block[num_blocks-1].nets[i+1] = add_net (saved_names[i],RECEIVER,                                    num_blocks-1,doall);  block[num_blocks-1].nets[0] = add_net (       saved_names[block[num_blocks-1].num_nets-1], DRIVER,num_blocks-1,doall); for (i=block[num_blocks-1].num_nets; i<lut_size+2; i++)    block[num_blocks-1].nets[i] = OPEN; len = strlen (saved_names[block[num_blocks-1].num_nets-1]); block[num_blocks-1].name = (char *) my_malloc ((len+1) * sizeof (char)); strcpy(block[num_blocks-1].name, saved_names[block[num_blocks-1].num_nets-1]); num_luts++;}static void add_latch (int doall, int lut_size) {/* Adds the flipflop (.latch) 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.  Blif format for a latch is:                           * * .latch <input> <output> <type (latch on)> <control (clock)> <init_val> * * The latch pins are in .nets 0 to 2 in the order: Q D CLOCK.            */ char *ptr, buf[BUFSIZE], saved_names[6][BUFSIZE]; int i, len; num_blocks++;/* Count # parameters, making sure we don't go over 6 (avoids memory corr.) *//* Note that we can't rely on the tokens being around unless we copy them.  */ for (i=0;i<6;i++) {    ptr = my_strtok (NULL,TOKENS,blif,buf);    if (ptr == NULL)        break;    strcpy (saved_names[i], ptr); } if (i != 5) {    fprintf(stderr,"Error:  .latch does not have 5 parameters.\n"            "check the netlist, line %d.\n",linenum);    exit(1); } if (!doall) {   /* If only a counting pass ... */    add_net(saved_names[0],RECEIVER,num_blocks-1,doall);  /* D */    add_net(saved_names[1],DRIVER,num_blocks-1,doall);    /* Q */    add_net(saved_names[3],RECEIVER,num_blocks-1,doall);  /* Clock */    return; } block[num_blocks-1].num_nets = 3; block[num_blocks-1].type = LATCH; block[num_blocks-1].nets[0] = add_net(saved_names[1],DRIVER,num_blocks-1,     doall);                                                        /* Q */ block[num_blocks-1].nets[1] = add_net(saved_names[0],RECEIVER,num_blocks-1,     doall);                                                        /* D */ block[num_blocks-1].nets[lut_size+1] = add_net(saved_names[3],RECEIVER,          num_blocks-1,doall);                                           /* Clock */ for (i=2;i<lut_size+1;i++)     block[num_blocks-1].nets[i] = OPEN;     len = strlen (saved_names[1]); block[num_blocks-1].name = (char *) my_malloc ((len+1) * sizeof (char)); strcpy(block[num_blocks-1].name,saved_names[1]); num_latches++;}static void io_line(int in_or_out, int doall) {  /* Adds an input or output block to the block data structures.           * * in_or_out:  DRIVER for input, RECEIVER for output.                    * * doall:  1 for final pass when structures are loaded.  0 for           * * first pass when hash table is built and pins, nets, etc. are counted. */  char *ptr; char buf2[BUFSIZE]; int nindex, len;  

⌨️ 快捷键说明

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