/**CFile*********************************************************************** FileName [ioCmd.c] PackageName [io] Synopsis [Top-level routines for reading and writing files.] Description [This file contains top-level routines for I/O functions of VIS.] Author [Yuji Kukimoto, Rajeev K. Ranjan, Sunil P. Khatri, Huey-Yih Wang] Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. All rights reserved. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] ******************************************************************************/ #include "ioInt.h" static char rcsid[] UNUSED = "$Id: ioCmd.c,v 1.16 2005/05/19 02:34:33 awedh Exp $"; /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ #ifndef NAWK #define NAWK "gawk" #endif /*---------------------------------------------------------------------------*/ /* Stucture declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Type declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ extern FILE *yyin; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ static int CommandReadBlifMv(Hrc_Manager_t **hmgr, int argc, char **argv); static int CommandWriteBlifMv(Hrc_Manager_t **hmgr, int argc, char **argv); static int CommandReadVerilog(Hrc_Manager_t **hmgr, int argc, char **argv); static int CommandReadBlif(Hrc_Manager_t **hmgr, int argc, char **argv); static int CommandWriteBlif(Hrc_Manager_t **hmgr, int argc, char **argv); static int CommandWriteSmv(Hrc_Manager_t **hmgr, int argc, char **argv); /**AutomaticEnd***************************************************************/ /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Initializes the I/O package.] SideEffects [] SeeAlso [Io_End] ******************************************************************************/ void Io_Init(void) { Cmd_CommandAdd("read_blif_mv", CommandReadBlifMv, 0); Cmd_CommandAdd("write_blif_mv", CommandWriteBlifMv, 0); Cmd_CommandAdd("write_smv", CommandWriteSmv, 0); Cmd_CommandAdd("read_verilog", CommandReadVerilog, 0); Cmd_CommandAdd("read_blif", CommandReadBlif, 0); Cmd_CommandAdd("write_blif", CommandWriteBlif, 0); } /**Function******************************************************************** Synopsis [Ends the I/O package.] SideEffects [] SeeAlso [Io_Init] ******************************************************************************/ void Io_End(void) { } /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [The top-level routine for read_blif_mv.] Description [] SideEffects [] CommandName [read_blif_mv] CommandSynopsis [read a blif-mv file] CommandArguments [\[-c\] \[-h\] \[-r\] \[-v\] <file_name>] CommandDescription [Reads a blif-mv file into VIS. The existing hierarchy for the blif-mv file previously read in is overwritten upon a successful read. If an error is detected while reading a file, the previous hierarchy is preserved.

Command options:

-c
Semi-canonicalize all the tables in each model. The canonicalization process, assigns a linear order to the table rows and columns, based on the value of their entries. For a table with binary valued entries, this value is exactly the number of 1's in the row or column. Once this linear order is assigned, the rows and columns of the table are swapped so as to order rows and columns with higher value at the beginning of the corresponding row or column order. It is called semi-canonicalization because two tables representing the same logic function need not have the same canonical form.
-h
Print the command usage.
-r
If set, the program replaces the subhierarchy rooted at the current node with a new hierarchy specified by a blif-mv file. The file to be read in has to be compatible with the i/o interface of the current hnode (the same i/o names with the same domains). Otherwise, the current hierarchy is kept intact. If -r is not specified, the entire hierarchy is replaced, not just the subhierarchy at the current node.
-v
If set, the program prints out all the unused variables in the blif-mv file. Otherwise, only a warning is printed that some variables are not used.
<file_name>
blif-mv file to be read in.
For more information on blif-mv, refer to the blif-mv manual.] SeeAlso [] ******************************************************************************/ static int CommandReadBlifMv( Hrc_Manager_t **hmgr, int argc, char **argv) { int status, c; boolean isCanonical, isIncremental, isVerbose; char *fileName; FILE *fp; Hrc_Manager_t *newHmgr; isCanonical = 0; isIncremental = 0; isVerbose = 0; util_getopt_reset(); while ((c = util_getopt(argc,argv,"chrv")) != EOF){ switch(c){ case 'c': isCanonical = 1; break; case 'h': goto usage; case 'r': isIncremental = 1; break; case 'v': isVerbose = 1; break; default: goto usage; } } /* check to see if there is only one argument left for a file name */ if (argc-1 != util_optind){ goto usage; } fileName = argv[util_optind]; fp = Cmd_FileOpen(fileName, "r", NIL(char *), 1); if (fp == NIL(FILE)){ (void)fprintf(vis_stderr,"File %s cannot be opened\n", fileName); return 1; } error_init(); newHmgr = Io_BlifMvRead(fp,*hmgr,isCanonical,isIncremental,isVerbose); /* success */ if (newHmgr != NIL(Hrc_Manager_t)){ status = 0; if (isIncremental == 0){ Hrc_ManagerFree(*hmgr); *hmgr = newHmgr; } } /* failure */ else { status = 1; } (void)fprintf(vis_stderr,"%s",error_string()); fflush(vis_stderr); if (fp != stdin) { (void) fclose(fp); } return (status); usage: (void)fprintf(vis_stderr, "usage: read_blif_mv [-c] [-h] [-r] [-v] file\n"); (void)fprintf(vis_stderr, " -c semi-canonicalize all the tables\n"); (void)fprintf(vis_stderr, " -h print the command usage\n"); (void)fprintf(vis_stderr, " -r replace the current subhierarchy\n"); (void)fprintf(vis_stderr, " -v verbose\n"); return 1 ; } /**Function******************************************************************** Synopsis [The top-level routine for write_blif_mv.] Description [] SideEffects [] CommandName [write_blif_mv] CommandSynopsis [write a blif-mv file] CommandArguments [\[-h\] \[<file>\]] CommandDescription [Writes out the hierarchy below the current node in blif-mv format to the file specified as an argument. If no argument is specified, the output is available at the standard output.

Command options:

-h
Print the command usage.
<file>
name of blif-mv file to be written.
For more information on blif-mv, refer to the blif-mv manual.] SeeAlso [] ******************************************************************************/ static int CommandWriteBlifMv( Hrc_Manager_t **hmgr, int argc, char **argv) { FILE *fp; int c; Hrc_Node_t *currentNode; util_getopt_reset(); while ((c = util_getopt(argc,argv,"h")) != EOF){ switch(c){ case 'h': goto usage; default: goto usage; } } currentNode = Hrc_ManagerReadCurrentNode(*hmgr); if (currentNode == NIL(Hrc_Node_t)){ (void)fprintf(vis_stderr,"No file has been read in.\n"); return 1; } if (argc == 1){ fp = stdout; } else if (argc == 2){ fp = Cmd_FileOpen(*(++argv), "w", NIL(char *), 1); if (fp == NIL(FILE)){ (void)fprintf(vis_stderr,"Cannot write to %s\n", *argv); return 1; } } else { goto usage; } error_init(); IoBlifMvWrite(fp,*hmgr); (void)fprintf(vis_stderr,"%s",error_string()); fflush(fp); if (fp != stdout) { (void) fclose(fp); } return 0; usage: (void)fprintf(vis_stderr, "usage: write_blif_mv [-h] [file]\n"); (void)fprintf(vis_stderr, " -h print the command usage\n"); return 1; } /**Function******************************************************************** Synopsis [The top-level routine for write_smv.] Description [] SideEffects [] CommandName [write_smv] CommandSynopsis [write an smv file] CommandArguments [\[-h\] \[<file>\]] CommandDescription [Writes out the hierarchy below the current node in smv format to the file specified as an argument. If no argument is specified, the output is available at the standard output.

Command options:

-h
Print the command usage.
<file>
name of smv file to be written.
For more information on smv, refer to the smv manual.] SeeAlso [] ******************************************************************************/ static int CommandWriteSmv( Hrc_Manager_t **hmgr, int argc, char **argv) { FILE *fp; int c; Hrc_Node_t *currentNode; util_getopt_reset(); while ((c = util_getopt(argc,argv,"h")) != EOF){ switch(c){ case 'h': goto usage; default: goto usage; } } currentNode = Hrc_ManagerReadCurrentNode(*hmgr); if (currentNode == NIL(Hrc_Node_t)){ (void)fprintf(vis_stderr,"No file has been read in.\n"); return 1; } if (argc == 1){ fp = stdout; }else if (argc == 2){ fp = Cmd_FileOpen(*(++argv), "w", NIL(char *), 1); if (fp == NIL(FILE)){ (void)fprintf(vis_stderr,"Cannot write to %s\n", *argv); return 1; } }else { goto usage; } error_init(); IoSmvWrite(fp,*hmgr); (void)fprintf(vis_stderr,"%s",error_string()); fflush(fp); if (fp != stdout) { (void) fclose(fp); } return 0; usage: (void)fprintf(vis_stderr, "usage: write_smv [-h] [file]\n"); (void)fprintf(vis_stderr, " -h print the command usage\n"); return 1; } /**Function******************************************************************** Synopsis [The top-level routine for read_verilog.] Description [] SideEffects [] CommandName [read_verilog] CommandSynopsis [read a verilog file] CommandArguments [\[-c\] \[-h\] \[-u\] \[-F\] <file_name>] CommandDescription [Reads a verilog file into VIS. Internally the file is transformed into an equivalent blif-mv file, which is then read into VIS. The existing hierarchy for the blif-mv file previously read in is overwritten upon a successful read. If an error is detected while reading a file, the previous hierarchy is preserved.

Command options:

-c
Use explicit clocking.
-h
Print the command usage.
-u
Turn off loop unroling.
-F
Ignore all timing.
<file_name>
Verilog file to be read in.
] SeeAlso [] ******************************************************************************/ static int CommandReadVerilog(Hrc_Manager_t **hmgr, int argc, char **argv) { int c; char *realFileName, *verilogFileName; #if HAVE_MKSTEMP && HAVE_CLOSE char outFileName[] = "/tmp/vis.XXXXXX"; int fd; #else char *outFileName; char buffer[512]; #endif FILE *fp; static char parseBuffer[1024]; int vl2mvStatus; int cSet = 0; int uSet = 0; int FSet = 0; util_getopt_reset(); while ((c = util_getopt(argc,argv,"chuF")) != EOF){ switch(c){ case 'c': cSet = 1; break; case 'h': goto usage; case 'u': uSet = 1; break; case 'F': FSet = 1; break; default: goto usage; } } /* check to see if there is only one argument left for a file name */ if (argc-1 != util_optind){ goto usage; } verilogFileName = argv[util_optind]; fp = Cmd_FileOpen(verilogFileName, "r", &realFileName, /* silent */ 1); if (fp == NIL(FILE)){ FREE(realFileName); (void)fprintf(vis_stderr,"File %s cannot be opened\n", verilogFileName); return 1; } fclose(fp); #if HAVE_MKSTEMP && HAVE_CLOSE fd = mkstemp(outFileName); if (fd == -1){ #else outFileName = util_strsav(tmpnam(buffer)); if (outFileName == NIL(char)){ #endif FREE(realFileName); (void)fprintf(vis_stderr,"Can not create temporary file. "); (void)fprintf(vis_stderr,"Clean up /tmp an try again.\n"); return 1; } strcpy(parseBuffer,"vl2mv "); strcat(parseBuffer,"-o "); strcat(parseBuffer,outFileName); strcat(parseBuffer," "); /* start inserting options for vl2mv */ if (cSet){ strcat(parseBuffer,"-c "); } if (uSet){ strcat(parseBuffer,"-u "); } if (FSet){ strcat(parseBuffer,"-F "); } strcat(parseBuffer, realFileName); FREE(realFileName); #if HAVE_MKSTEMP && HAVE_CLOSE close(fd); #endif vl2mvStatus = system(parseBuffer); if (vl2mvStatus != 0){ return 1; } sprintf(parseBuffer,"read_blif_mv %s",outFileName); Cmd_CommandExecute(hmgr, parseBuffer); #if HAVE_UNLINK unlink(outFileName); #endif return 0; usage: (void)fprintf(vis_stderr, "usage: read_verilog [-c] [-h] [-u] [-F] file\n"); (void)fprintf(vis_stderr, " -c use explicit clocking\n"); (void)fprintf(vis_stderr, " -h print the command usage\n"); (void)fprintf(vis_stderr, " -u turn off unroling\n"); (void)fprintf(vis_stderr, " -F ignore all timing\n"); return 1; } /**Function******************************************************************** Synopsis [The top-level routine for read_blif.] Description [] SideEffects [] CommandName [read_blif] CommandSynopsis [read a blif file] CommandArguments [\[-c\] \[-e <encoding_file_name>\] \[-h\] [-v\] <file_name>] CommandDescription [Reads a file in blif format into VIS. All the synthesis-specific constructs of blif are ignored. Internally the blif file is automatically translated into an equivalent blif-mv file, which is then read in with read_blif_mv. Note that, currently this command cannot read blif files which describe mapped circuits. To get around this problem, please use SIS synthesis tool to generate an ordinary blif file. Command options:

-c
Semi-canonicalize all the tables in each model. See the documentation of read_blif_mv for details.
-e <encoding_file_name>
If set, the program reads in a blif file using the encoding information specified in the encoding_file_name. Only the current hnode is altered in the process, and hence the read is incremental. Typically the encoding file is written out by a write_blif operation. Note that this option cannot be used if no file has been read in. Internally, the encoding file is used in combination with the blif file to create a blif-mv file which is compatible with the I/O interface of the current node.
-h
Print the command usage.
-v
If set, the program prints out all the unused variables in the blif file.
<file_name>
Name of a blif file to be read in. This can be the output written by SIS. in the blif file.
] SeeAlso [] ******************************************************************************/ static int CommandReadBlif( Hrc_Manager_t **hmgr, int argc, char **argv) { int c, status; boolean isCanonical = 0; boolean isIncremental = 0; boolean isVerbose = 0; char *fileName, *realFileName, *visDirectoryName, *blifMvFileName; char *encodingFileName; char command[512]; FILE *fp; #if HAVE_MKSTEMP && HAVE_CLOSE int fd; #else char buffer[512]; #endif Hrc_Manager_t *newHmgr; util_getopt_reset(); while ((c = util_getopt(argc,argv,"ce:hv")) != EOF){ switch(c){ case 'c': isCanonical = 1; break; case 'e': isIncremental = 1; fp = Cmd_FileOpen(util_optarg, "r", &encodingFileName, 1); if (fp == NIL(FILE)){ (void)fprintf(vis_stderr,"Encoding file %s is not found\n", util_optarg); return 1; } if (fp != stdin){ (void)fclose(fp); } break; case 'h': goto usage; case 'v': isVerbose = 1; break; default: goto usage; } } /* check to see if there is only one argument left for a file name */ if (argc-1 != util_optind){ goto usage; } fileName = argv[util_optind]; fp = Cmd_FileOpen(fileName, "r", &realFileName, 1); if (fp == NIL(FILE)){ /* FREE(realFileName); */ (void)fprintf(vis_stderr,"File %s cannot be opened\n", fileName); return 1; } if (fp != stdin){ (void)fclose(fp); } #if HAVE_MKSTEMP && HAVE_CLOSE blifMvFileName = util_strsav("/tmp/vis.XXXXXX"); fd = mkstemp(blifMvFileName); if (fd == -1){ #else blifMvFileName = util_strsav(tmpnam(buffer)); if (blifMvFileName == NIL(char)){ #endif FREE(realFileName); (void)fprintf(vis_stderr,"Could not create temporary file. "); (void)fprintf(vis_stderr,"Clean up /tmp an try again.\n"); return 1; } #if HAVE_MKSTEMP && HAVE_CLOSE close(fd); #endif /* Invoking an awk script */ visDirectoryName = Vm_VisObtainLibrary(); if (isIncremental == 0){ (void)sprintf(command,"sed 's/^\\./@/g' %s | sed 's/\\./$/g' | sed 's/^@/\\./g' | sed 's/{//g'| sed 's/(/<>/g'| %s -f %s/ioBlifToMv.nawk > %s", realFileName, NAWK, visDirectoryName, blifMvFileName); } else { (void)sprintf(command,"sed 's/^\\./@/g' %s | sed 's/\\./$/g' | sed 's/^@/\\./g' | sed 's/{//g'| %s -f %s/ioBlifToMvForIncremental.nawk > %s", realFileName, NAWK, visDirectoryName, blifMvFileName); } (void)system(command); FREE(visDirectoryName); FREE(realFileName); error_init(); if (isIncremental == 0){ fp = Cmd_FileOpen(blifMvFileName, "r", NIL(char *), 1); } else { char *finalBlifMvFileName; #if HAVE_MKSTEMP && HAVE_CLOSE finalBlifMvFileName = util_strsav("/tmp/vis.XXXXXX"); fd = mkstemp(finalBlifMvFileName); if (fd == -1){ #else finalBlifMvFileName = util_strsav(tmpnam(buffer)); if (finalBlifMvFileName == NIL(char)){ #endif FREE(blifMvFileName); (void)fprintf(vis_stderr,"Could not create temporary file. "); (void)fprintf(vis_stderr,"Clean up /tmp an try again.\n"); return 1; } #if HAVE_MKSTEMP && HAVE_CLOSE close(fd); #endif (void)sprintf(command,"cat %s %s > %s",encodingFileName,blifMvFileName,finalBlifMvFileName); (void)system(command); FREE(encodingFileName); #if HAVE_UNLINK unlink(blifMvFileName); #endif FREE(blifMvFileName); blifMvFileName = finalBlifMvFileName; fp = Cmd_FileOpen(blifMvFileName, "r", NIL(char *), 1); } assert(fp != NIL(FILE)); newHmgr = Io_BlifMvRead(fp,*hmgr,isCanonical,isIncremental,isVerbose); if (newHmgr != NIL(Hrc_Manager_t)){ status = 0; if (isIncremental == 0){ Hrc_ManagerFree(*hmgr); *hmgr = newHmgr; } } else { status = 1; } (void)fprintf(vis_stderr,"%s",error_string()); fflush(vis_stderr); if (fp != stdin) { (void) fclose(fp); #if HAVE_UNLINK unlink(blifMvFileName); #endif } FREE(blifMvFileName); return (status); usage: (void)fprintf(vis_stderr, "usage: read_blif [-c] [-e encoding_file] [-h] [-v] file\n"); (void)fprintf(vis_stderr, " -c table canonicalization\n"); (void)fprintf(vis_stderr, " -e read a file into the current node using encoding file\n"); (void)fprintf(vis_stderr, " -h print the command usage\n"); (void)fprintf(vis_stderr, " -v verbose\n"); return 1 ; } /**Function******************************************************************** Synopsis [The top-level routine for write_blif] Description [Determinizes, encodes and writes a set of tables into blif] SideEffects [] CommandName [write_blif] CommandSynopsis [determinize, encode and write an hnode to a blif file] CommandArguments [\[-c\] \[-l\] \[-e <encoding_file_name>\] \[-R\] \[-h\] \[-v <verbosity_value>\] \[<file>\]] CommandDescription [Encodes, determinizes, and writes all tables in the current hnode to a BLIF file. With the '-l' or '-c' options, or when 'write_blif' is used with no options, only the current hnode is written out as a blif file. The '-R' option writes the entire hierarchy rooted at the current hnode to the blif file, assuming all tables are deterministic and all variables are boolean.

Encoding the Multi-Valued Variables:

First, all multi-valued variables in the hnode are binary encoded. Each multi-valued variable requires 'm' binary variables in its encoding, where m = log2(n). Here 'n' is the number of values in the domain of the multi-valued variable. If variable X has n binary variables in its encoding, these are called X0, X1, ... X. X0 is the least significant encoding variable. The value i of multi-valued variable X is encoded such that X0 + 2^1 * X1 + ... + 2^(n-1) * X = i. After encoding, each table in the hnode is written out to the blif file.

Determinizing Non-Deterministic Tables:

Non-deterministic tables are determinized by adding more binary variables to a particular variable's encoding. The variable that is chosen is the one that has the smallest number of binary variables in its encoding. Determinization is explained by means of an example:

Consider the BLIF-MV table, where each of a, b, and c can have 4 values. Each multi-valued variable has two binary variables in its encoding. These are called a0, a1, b0, b1, c0 and c1.

.model foo

.inputs a b

.outputs c

.mv a, b, c 4

.table a b ->c

2 1 (1,2)

(1,2) 1 3

.end

The first row of this table represents non-determinism, since for a given assignment of input values (i.e. a=2, b=1), the output can take on two values (1 or 2). To determinize this row, it is split into two rows, each with a unique singleton output value. A new binary variable is added to the encoding of a (or b, since in this case each of them has the same number of binary variables in its encoding). The new variable a2 is given separate values in each of the new rows. The resulting blif table looks like:

.model foo

.inputs a0 a1 a2 b0 b1

.outputs c0 c1

.names a0 a1 a2 b0 b1 ->c0 c1

0 1 0 1 0 1 0 (these two rows represent

0 1 1 1 0 0 1 row 1 of the MV table)

1 0 - 1 0 1 1 (these two rows represent

0 1 - 1 0 1 1 row 2 of the MV table)

.end

Note that this table is still not deterministic, since rows 1 and 4 have input minterm(s) in common, but the corresponding outputs are different. To resolve this, a new binary variable is added to the encoding for b (since b currently has the smallest encoding). For the conflicting rows, this variable b2 is assigned different values, and for all other rows, it is assigned a '-' value. After this change, rows 1 and 4 no longer have common input minterm(s). The intermediate table now looks like:

.model foo

.inputs a0 a1 a2 b0 b1 b2

.outputs c0 c1

.names a0 a1 a2 b0 b1 b2->c0 c1

0 1 0 1 0 1 1 0

0 1 1 1 0 - 0 1

1 0 - 1 0 - 1 1

0 1 - 1 0 0 1 1

.end

This process is continued until the table is determinized. In this example, the final blif file looks like:

.model foo

.inputs a0 a1 a2 a3 b0 b1 b2

.outputs c0 c1

.table a0 a1 a2 a3 b0 b1 b2 ->c0 c1

0 1 0 - 1 0 1 1 0

0 1 1 1 1 0 - 0 1

1 0 - - 1 0 - 1 1

0 1 - 0 1 0 0 1 1

.end

Blif allows only single output tables, so in reality the above table is split into two single output tables before being written out to the blif file. The new binary variables that are thus introduced are treated as primary inputs in the blif file.

We make no claim on the optimality of this process, just that it is simple. It may turn out that the number of new variables is much larger than the optimum one.

Interfacing Between Binary and Multi-Valued Variables:

In order for the SIS-optimized version of this file to be read back into VIS, we need to re-create the corresponding multi-valued variables. For this purpose, interface information (model name, input and output declarations for the hnode) is written out to a special encoding file (e.g. foo.enc). Additionally, binary->multi-valued encoding tables are written to the encoding file for each PO. In the above example, the binary->multi-valued table for variable c looks like

.table c0 c1 -> c

0 0 0

1 0 1

0 1 2

1 1 3

and this can be seen as a decoder of the binary variables. Similarly, multi-valued->binary encoding tables are written to the encoding file for each PI. The multi-valued->binary table for variable b in the above example is:

.table b -> b0 b1

0 0 0

1 1 0

2 0 1

3 1 1

and this can be seen as an encoder of the multi-valued variables. Similar tables are written to the encoding file for sub-circuit inputs and outputs. Likewise, such tables are written out for latch inputs and outputs. This is needed so that the original multi-valued latches can be reinstated while the blif file is being read back into VIS. These multi-valued latch declarations are written to the encoding file during the write_blif process.

The combination of this encoding file and the blif file results in a legal BLIF-MV hnode description.

If no file is specified, the blif file is written out to the standard output. If the encoding file is not specified, encoding information is written out to .enc.

Options:

The '-R' option writes the entire hierarchy rooted at the current hnode to the blif file, first checking that all tables are deterministic and all variables are boolean. Other options ('-c', '-l', or write_blif with no options) only write out the current hnode. Also, when the '-R' option is specified, no encoding file is written since none is needed.

Command options:

-c
Writes only combinational part to blif file.
-l
Writes out latches, making latch IOs primary outputs in the blif file.
-e <encoding_file_name>
If set, the program writes the encoding information into this file. The default is the model name for the current node extended by .enc.
-R
Recursively writes out the entire hierarchy rooted at the current hnode to the blif file. In this sub-hierarchy, all tables must be deterministic and all variables must be boolean. Either of the -c, -l or -e options cannot be used together with this option.
-h
Prints the command usage.
-v <verbosity_value>
Specifies verbosity level, an integer less than 3.
<file>
name of blif file to be written, default is standard output.
Note that if neither the -c or the -l options are chosen, then latches are written out, without making latch IOs primary outputs in the blif file. Currently the files written out using this option cannot be read back into VIS.
] SeeAlso [] SeeAlso [] ******************************************************************************/ static int CommandWriteBlif( Hrc_Manager_t **hmgr, int argc, char **argv) { FILE *enc_fp, *fp; char *modelName, *dupname; int status, verbosity, combinationalOnly, makeLatchIOsPOs; Io_Encoding_Type_t encoding_type; Hrc_Node_t *hnode; int c; boolean recursive; fp = stdout; enc_fp = NIL(FILE); verbosity = 0; combinationalOnly = 0; makeLatchIOsPOs = 0; recursive = 0; util_getopt_reset(); while ((c = util_getopt(argc, argv, "clRe:hv:")) != EOF) { switch(c) { case 'c': combinationalOnly = 1; break; case 'l': makeLatchIOsPOs = 1; break; case 'R': recursive = 1; break; case 'e': enc_fp = Cmd_FileOpen(util_optarg, "w", NIL(char *), 1); if (enc_fp == NIL(FILE)){ (void)fprintf(vis_stderr,"Cannot write to %s\n", util_optarg); return 1; } break; case 'h': goto usage; case 'v': verbosity = atoi(util_optarg); break; default: goto usage; } } if(makeLatchIOsPOs && combinationalOnly){ (void)fprintf(vis_stderr,"Cannot use -c and -l options simultaneously.\n"); goto usage; } if(recursive){ if(makeLatchIOsPOs || combinationalOnly){ (void)fprintf(vis_stderr,"Cannot use -c or -l options with -R option.\n"); goto usage; } if(enc_fp != NIL(FILE)){ (void)fprintf(vis_stderr,"Cannot use -e option with -R option.\n"); goto usage; } } hnode = Hrc_ManagerReadCurrentNode(*hmgr); if (hnode == NIL(Hrc_Node_t)){ (void)fprintf(vis_stderr,"No file has been read in.\n"); return 1; } /* check to see if there is only one argument left for a file name */ if (argc == util_optind){ fp = stdout; } else if (argc-1 == util_optind){ fp = Cmd_FileOpen(argv[util_optind], "w", NIL(char *), 1); if (fp == NIL(FILE)){ (void)fprintf(vis_stderr,"Cannot write to %s\n", argv[util_optind]); if (enc_fp != NIL(FILE)){ fclose(enc_fp); } return 1; } } else { if (enc_fp != NIL(FILE)){ fclose(enc_fp); } goto usage; } if((enc_fp == NIL(FILE)) && !recursive){ modelName = Hrc_NodeReadModelName(hnode); dupname = ALLOC(char, strlen(modelName) + strlen(".enc") + 1); sprintf(dupname, "%s%s", modelName, ".enc"); enc_fp = Cmd_FileOpen(dupname, "w", NIL(char *), 1); if (enc_fp == NIL(FILE)){ (void)fprintf(vis_stderr,"Cannot write to %s\n", dupname); return 1; } (void)fprintf(stdout, "Writing encoding information to %s\n",dupname); FREE(dupname); } if(!recursive){ if(!(makeLatchIOsPOs || combinationalOnly)){ (void)fprintf(vis_stderr,"Warning - The blif and encoding files generated cannot be read back into \n"); (void)fprintf(vis_stderr, "VIS. If you would like to read the optimized blif file back into VIS, then \n"); (void)fprintf(vis_stderr, "please use 'write_blif -l' or 'write_blif -c' instead.\n"); } } error_init(); encoding_type = SIMPLE; if(recursive){ status = Io_HnodeWriteBlifTotal(encoding_type, hnode, fp, verbosity); } else{ status = Io_HnodeWriteBlif(encoding_type, hnode, fp, enc_fp, verbosity, combinationalOnly, makeLatchIOsPOs); } (void)fprintf(vis_stderr,"%s",error_string()); fflush(fp); if (fp != stdout) { (void) fclose(fp); } if(status == 0){ return 0; } else{ return 1; } usage: (void)fprintf(vis_stderr, "usage: write_blif [-c] [-l] [-e encoding_file] [-R] [-h] [-v verbosity] [blif_file]\n"); (void)fprintf(vis_stderr, " -c write only combinational part to blif file\n"); (void)fprintf(vis_stderr, " -l make latch IOs primary outputs in the blif file\n"); (void)fprintf(vis_stderr, " -e encoding_file, default is .enc\n"); (void)fprintf(vis_stderr, " -R recursively write out the hierarchy rooted at the current hnode.\n"); (void)fprintf(vis_stderr, " In this sub-hierarchy, all tables must be deterministic and all\n"); (void)fprintf(vis_stderr, " variables must be boolean. Either of the -c, -l, or -e options \n"); (void)fprintf(vis_stderr, " cannot be simultaneously with the -R option \n"); (void)fprintf(vis_stderr, " -h print this usage message\n"); (void)fprintf(vis_stderr, " -v verbosity, an integer < 3, default is 0\n"); (void)fprintf(vis_stderr, "Note: * If neither the -c or -l options are chosen, then latches will \n"); (void)fprintf(vis_stderr, " be written out to the blif file. Latch IOs will not be made\n"); (void)fprintf(vis_stderr, " into primary outputs in the blif file\n"); (void)fprintf(vis_stderr, " * After optimizing the blif file in SIS, do not write out the\n"); (void)fprintf(vis_stderr, " optimized file using 'write_blif -s' if you want to read\n"); (void)fprintf(vis_stderr, " it back into VIS. Use 'write_blif' instead \n"); return 1 ; }