source: vis_dev/vis-2.3/src/io/ioCmd.c @ 40

Last change on this file since 40 was 14, checked in by cecile, 13 years ago

vis2.3

File size: 35.0 KB
Line 
1/**CFile***********************************************************************
2
3  FileName      [ioCmd.c]
4
5  PackageName   [io]
6
7  Synopsis      [Top-level routines for reading and writing files.]
8
9  Description   [This file contains top-level routines for I/O functions of VIS.]
10
11  Author        [Yuji Kukimoto, Rajeev K. Ranjan, Sunil P. Khatri, Huey-Yih Wang]
12
13  Copyright   [Copyright (c) 1994-1996 The Regents of the Univ. of California.
14  All rights reserved.
15
16  Permission is hereby granted, without written agreement and without license
17  or royalty fees, to use, copy, modify, and distribute this software and its
18  documentation for any purpose, provided that the above copyright notice and
19  the following two paragraphs appear in all copies of this software.
20
21  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
22  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
23  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
24  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
27  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
29  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
30  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
31
32******************************************************************************/
33
34#include "ioInt.h"
35
36static char rcsid[] UNUSED = "$Id: ioCmd.c,v 1.16 2005/05/19 02:34:33 awedh Exp $";
37
38/*---------------------------------------------------------------------------*/
39/* Constant declarations                                                     */
40/*---------------------------------------------------------------------------*/
41#ifndef NAWK
42#define NAWK "gawk"
43#endif
44/*---------------------------------------------------------------------------*/
45/* Stucture declarations                                                     */
46/*---------------------------------------------------------------------------*/
47
48/*---------------------------------------------------------------------------*/
49/* Type declarations                                                         */
50/*---------------------------------------------------------------------------*/
51
52/*---------------------------------------------------------------------------*/
53/* Variable declarations                                                     */
54/*---------------------------------------------------------------------------*/
55extern FILE *yyin;
56
57/*---------------------------------------------------------------------------*/
58/* Macro declarations                                                        */
59/*---------------------------------------------------------------------------*/
60
61
62/**AutomaticStart*************************************************************/
63
64/*---------------------------------------------------------------------------*/
65/* Static function prototypes                                                */
66/*---------------------------------------------------------------------------*/
67
68static int CommandReadBlifMv(Hrc_Manager_t **hmgr, int argc, char **argv);
69static int CommandWriteBlifMv(Hrc_Manager_t **hmgr, int argc, char **argv);
70static int CommandReadVerilog(Hrc_Manager_t **hmgr, int argc, char **argv);
71static int CommandReadBlif(Hrc_Manager_t **hmgr, int argc, char **argv);
72static int CommandWriteBlif(Hrc_Manager_t **hmgr, int argc, char **argv);
73static int CommandWriteSmv(Hrc_Manager_t **hmgr, int argc, char **argv);
74 
75/**AutomaticEnd***************************************************************/
76
77
78/*---------------------------------------------------------------------------*/
79/* Definition of exported functions                                          */
80/*---------------------------------------------------------------------------*/
81
82/**Function********************************************************************
83
84  Synopsis    [Initializes the I/O package.]
85
86  SideEffects []
87
88  SeeAlso     [Io_End]
89
90******************************************************************************/
91void
92Io_Init(void)
93{
94  Cmd_CommandAdd("read_blif_mv", CommandReadBlifMv, 0);
95  Cmd_CommandAdd("write_blif_mv", CommandWriteBlifMv, 0);
96  Cmd_CommandAdd("write_smv", CommandWriteSmv, 0);
97  Cmd_CommandAdd("read_verilog", CommandReadVerilog, 0);
98  Cmd_CommandAdd("read_blif", CommandReadBlif, 0);
99  Cmd_CommandAdd("write_blif", CommandWriteBlif, 0);
100}
101
102/**Function********************************************************************
103
104  Synopsis    [Ends the I/O package.]
105
106  SideEffects []
107
108  SeeAlso     [Io_Init]
109
110******************************************************************************/
111void
112Io_End(void)
113{
114}
115
116/*---------------------------------------------------------------------------*/
117/* Definition of static functions                                            */
118/*---------------------------------------------------------------------------*/
119
120/**Function********************************************************************
121
122  Synopsis    [The top-level routine for read_blif_mv.]
123
124  Description []
125
126  SideEffects []
127
128  CommandName [read_blif_mv]
129  CommandSynopsis [read a blif-mv file]
130  CommandArguments [\[-c\] \[-h\] \[-r\] \[-v\] <file_name>]
131  CommandDescription [Reads a blif-mv file into VIS. The existing
132  hierarchy for the blif-mv file
133  previously read in is overwritten upon a successful read. If
134  an error is detected while reading a file, the previous hierarchy is
135  preserved.<p>
136  Command options:<p>
137  <dl><dt> -c
138  <dd> Semi-canonicalize all the tables in each model. The canonicalization
139  process, assigns a linear order to the table rows and columns, based on the
140  value of their entries. For a table with binary valued entries, this value
141  is exactly the number of 1's in the row or column. Once this linear
142  order is assigned, the rows and columns of the table are swapped so as to
143  order rows and columns with higher value at the beginning of the
144  corresponding row or column order. It is called semi-canonicalization
145  because two tables representing the same logic function need not have the
146  same canonical form.
147  </dl>
148  <dl><dt> -h
149  <dd> Print the command usage.
150  </dl>
151  <dl><dt> -r
152  <dd> If set, the program replaces the subhierarchy rooted at
153  the current node with a new hierarchy specified by a blif-mv file.
154  The file to be read in has to be compatible with the i/o interface
155  of the current hnode (the same i/o names with the same domains).
156  Otherwise, the current hierarchy is kept intact. If -r is not specified,
157  the entire hierarchy is replaced, not just the subhierarchy at the current
158  node.
159  </dl>
160  <dl><dt> -v
161  <dd> If set, the program prints out all the unused variables
162  in the blif-mv file. Otherwise, only a warning is printed that
163  some variables are not used.
164  </dl>
165  <dl><dt> &lt;file_name&gt;
166  <dd> blif-mv file to be read in.
167  </dl>
168
169  For more information on blif-mv, refer to the
170  <A HREF="http://www-cad.eecs.berkeley.edu/Respep/Research/vis/doc/blifmv/blifmv/blifmv.html">blif-mv manual</A>.]
171
172  SeeAlso     []
173
174******************************************************************************/
175static int
176CommandReadBlifMv(
177  Hrc_Manager_t **hmgr,
178  int argc,
179  char **argv)
180{
181  int status, c;
182  boolean isCanonical, isIncremental, isVerbose;
183  char *fileName;
184  FILE *fp;
185  Hrc_Manager_t *newHmgr;
186 
187  isCanonical = 0;
188  isIncremental = 0;
189  isVerbose = 0;
190  util_getopt_reset();
191  while ((c = util_getopt(argc,argv,"chrv")) != EOF){
192    switch(c){
193      case 'c':
194        isCanonical = 1;
195        break;
196      case 'h':
197        goto usage;
198      case 'r':
199        isIncremental = 1;
200        break;
201      case 'v':
202        isVerbose = 1;
203        break;
204      default:
205        goto usage;
206    }
207  }
208 
209  /* check to see if there is only one argument left for a file name */
210  if (argc-1 != util_optind){
211    goto usage;
212  }
213  fileName = argv[util_optind];
214
215  fp = Cmd_FileOpen(fileName, "r", NIL(char *), 1);
216 
217  if (fp == NIL(FILE)){
218    (void)fprintf(vis_stderr,"File %s cannot be opened\n", fileName);
219    return 1;
220  }
221  error_init();
222
223  newHmgr = Io_BlifMvRead(fp,*hmgr,isCanonical,isIncremental,isVerbose);
224  /* success */
225  if (newHmgr != NIL(Hrc_Manager_t)){
226    status = 0;
227    if (isIncremental == 0){
228      Hrc_ManagerFree(*hmgr);
229      *hmgr = newHmgr;
230    }
231  }
232  /* failure */
233  else {
234    status = 1;
235  }
236  (void)fprintf(vis_stderr,"%s",error_string());
237  fflush(vis_stderr);
238  if (fp != stdin) {
239    (void) fclose(fp);
240  }
241  return (status);
242
243  usage:
244    (void)fprintf(vis_stderr, "usage: read_blif_mv [-c] [-h] [-r] [-v] file\n");
245    (void)fprintf(vis_stderr, "   -c  semi-canonicalize all the tables\n");
246    (void)fprintf(vis_stderr, "   -h  print the command usage\n"); 
247    (void)fprintf(vis_stderr, "   -r  replace the current subhierarchy\n");
248    (void)fprintf(vis_stderr, "   -v  verbose\n");
249    return 1 ;
250}
251
252
253/**Function********************************************************************
254
255  Synopsis    [The top-level routine for write_blif_mv.]
256
257  Description []
258
259  SideEffects []
260
261  CommandName [write_blif_mv]
262  CommandSynopsis [write a blif-mv file]
263  CommandArguments [\[-h\] \[&lt;file&gt;\]]
264  CommandDescription [Writes out the hierarchy below the current
265  node in blif-mv format to the file specified as an argument.
266  If no argument is specified,
267  the output is available at the standard output.<p>
268  Command options:<p>
269  <dl><dt> -h
270  <dd> Print the command usage.
271  </dl>
272  <dl><dt> &lt;file&gt;
273  <dd> name of blif-mv file to be written.
274  </dl>
275  For more information on blif-mv, refer to the
276  <A HREF="http://www-cad.eecs.berkeley.edu/Respep/Research/vis/doc/blifmv/blifmv/blifmv.html">blif-mv manual</A>.]
277
278  SeeAlso     []
279
280******************************************************************************/
281static int
282CommandWriteBlifMv(
283  Hrc_Manager_t **hmgr,
284  int argc,
285  char **argv)
286{
287  FILE *fp;
288  int c;
289  Hrc_Node_t *currentNode;
290
291  util_getopt_reset();
292  while ((c = util_getopt(argc,argv,"h")) != EOF){
293    switch(c){
294      case 'h':
295        goto usage;
296      default:
297        goto usage;
298    }
299  }
300
301  currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
302  if (currentNode == NIL(Hrc_Node_t)){
303    (void)fprintf(vis_stderr,"No file has been read in.\n");
304    return 1;
305  }
306
307  if (argc == 1){
308    fp = stdout;
309  }
310  else if (argc == 2){
311    fp = Cmd_FileOpen(*(++argv), "w", NIL(char *), 1);
312    if (fp == NIL(FILE)){
313      (void)fprintf(vis_stderr,"Cannot write to %s\n", *argv);
314      return 1;
315    }
316  }
317  else {
318    goto usage; 
319  }
320 
321  error_init();
322  IoBlifMvWrite(fp,*hmgr);
323  (void)fprintf(vis_stderr,"%s",error_string());
324  fflush(fp);
325  if (fp != stdout) {
326    (void) fclose(fp);
327  }
328  return 0;
329
330  usage:
331    (void)fprintf(vis_stderr, "usage: write_blif_mv [-h] [file]\n");
332    (void)fprintf(vis_stderr, "   -h  print the command usage\n"); 
333    return 1;
334}
335
336/**Function********************************************************************
337 
338  Synopsis    [The top-level routine for write_smv.]
339
340  Description []
341
342  SideEffects []
343
344  CommandName [write_smv]
345  CommandSynopsis [write an smv file]
346  CommandArguments [\[-h\] \[&lt;file&gt;\]]
347  CommandDescription [Writes out the hierarchy below the current
348  node in smv format to the file specified as an argument.
349  If no argument is specified,
350  the output is available at the standard output.<p>
351  Command options:<p>
352  <dl><dt> -h
353  <dd> Print the command usage.
354  </dl>
355  <dl><dt> &lt;file&gt;
356  <dd> name of smv file to be written.
357  </dl>
358  For more information on smv, refer to the
359 <A HREF="http://www-2.cs.cmu.edu/~modelcheck/smv.html">smv manual</A>.]
360
361  SeeAlso     []
362
363******************************************************************************/
364static int
365CommandWriteSmv(
366  Hrc_Manager_t **hmgr,
367  int argc,
368  char **argv)
369{
370  FILE *fp;
371  int c;
372  Hrc_Node_t *currentNode;
373
374  util_getopt_reset();
375  while ((c = util_getopt(argc,argv,"h")) != EOF){
376    switch(c){
377      case 'h':
378        goto usage;
379      default:
380        goto usage;
381    }
382  }
383
384  currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
385  if (currentNode == NIL(Hrc_Node_t)){
386    (void)fprintf(vis_stderr,"No file has been read in.\n");
387    return 1;
388  }
389
390  if (argc == 1){
391    fp = stdout;
392  }else if (argc == 2){
393    fp = Cmd_FileOpen(*(++argv), "w", NIL(char *), 1);
394    if (fp == NIL(FILE)){
395      (void)fprintf(vis_stderr,"Cannot write to %s\n", *argv);
396      return 1;
397    }
398  }else {
399    goto usage; 
400  }
401 
402  error_init();
403  IoSmvWrite(fp,*hmgr);
404  (void)fprintf(vis_stderr,"%s",error_string());
405  fflush(fp);
406  if (fp != stdout) {
407    (void) fclose(fp);
408  }
409  return 0;
410
411  usage:
412    (void)fprintf(vis_stderr, "usage: write_smv [-h] [file]\n");
413    (void)fprintf(vis_stderr, "   -h  print the command usage\n"); 
414    return 1;
415}
416
417
418/**Function********************************************************************
419
420  Synopsis    [The top-level routine for read_verilog.]
421
422  Description []
423
424  SideEffects []
425
426  CommandName [read_verilog]
427  CommandSynopsis [read a verilog file]
428  CommandArguments [\[-c\] \[-h\] \[-u\] \[-F\] &lt;file_name&gt;]
429  CommandDescription [Reads a verilog file into VIS. Internally
430  the file is transformed into an equivalent blif-mv file, which is
431  then read into VIS. The existing hierarchy for the blif-mv file
432  previously read in is
433  overwritten upon a successful read. If an error is detected while
434  reading a file, the previous hierarchy is preserved.<p>
435  Command options:<p>
436  <dl><dt> -c
437  <dd> Use explicit clocking.
438  </dl>
439  <dl><dt> -h
440  <dd> Print the command usage.
441  </dl>
442  <dl><dt> -u
443  <dd> Turn off loop unroling.
444  </dl>
445  <dl><dt> -F
446  <dd> Ignore all timing.
447  </dl>
448  <dl><dt> &lt;file_name&gt;
449  <dd> Verilog file to be read in.
450  </dl>]
451
452  SeeAlso     []
453
454******************************************************************************/
455static int
456CommandReadVerilog(Hrc_Manager_t **hmgr, int argc, char **argv)
457{
458  int c;
459  char *realFileName, *verilogFileName;
460#if HAVE_MKSTEMP && HAVE_CLOSE
461  char outFileName[] = "/tmp/vis.XXXXXX";
462  int  fd;
463#else
464  char *outFileName;
465  char buffer[512];
466#endif
467  FILE *fp;
468  static char parseBuffer[1024];
469  int vl2mvStatus;
470  int cSet = 0;
471  int uSet = 0;
472  int FSet = 0;
473
474  util_getopt_reset();
475  while ((c = util_getopt(argc,argv,"chuF")) != EOF){
476    switch(c){
477      case 'c':
478        cSet = 1;
479        break;
480      case 'h': 
481        goto usage;
482      case 'u':
483        uSet = 1;
484        break;
485      case 'F':
486        FSet = 1;
487        break;
488      default:
489        goto usage;
490    }
491  }
492 
493  /* check to see if there is only one argument left for a file name */
494  if (argc-1 != util_optind){
495    goto usage;
496  }
497  verilogFileName = argv[util_optind];
498
499  fp = Cmd_FileOpen(verilogFileName, "r", &realFileName, /* silent */ 1);
500 
501  if (fp == NIL(FILE)){
502    FREE(realFileName);
503    (void)fprintf(vis_stderr,"File %s  cannot be opened\n", verilogFileName);
504    return 1;
505  }
506  fclose(fp);
507
508#if HAVE_MKSTEMP && HAVE_CLOSE
509  fd = mkstemp(outFileName);
510  if (fd == -1){
511#else
512  outFileName = util_strsav(tmpnam(buffer));
513  if (outFileName == NIL(char)){
514#endif
515    FREE(realFileName);
516    (void)fprintf(vis_stderr,"Can not create temporary file. ");
517    (void)fprintf(vis_stderr,"Clean up /tmp an try again.\n");
518    return  1;
519  } 
520 
521  strcpy(parseBuffer,"vl2mv ");
522  strcat(parseBuffer,"-o ");
523  strcat(parseBuffer,outFileName);
524  strcat(parseBuffer," ");
525  /* start inserting options for vl2mv */
526  if (cSet){
527    strcat(parseBuffer,"-c ");
528  }
529  if (uSet){
530    strcat(parseBuffer,"-u ");
531  }
532  if (FSet){
533    strcat(parseBuffer,"-F ");
534  }
535  strcat(parseBuffer, realFileName);
536  FREE(realFileName);
537#if HAVE_MKSTEMP && HAVE_CLOSE
538  close(fd);
539#endif
540  vl2mvStatus = system(parseBuffer);
541  if (vl2mvStatus != 0){
542    return 1;
543  }
544  sprintf(parseBuffer,"read_blif_mv %s",outFileName);
545  Cmd_CommandExecute(hmgr, parseBuffer);
546#if HAVE_UNLINK
547  unlink(outFileName);
548#endif
549  return 0;
550 
551  usage:
552    (void)fprintf(vis_stderr, "usage: read_verilog [-c] [-h] [-u] [-F] file\n");
553    (void)fprintf(vis_stderr, "   -c  use explicit clocking\n");
554    (void)fprintf(vis_stderr, "   -h  print the command usage\n");
555    (void)fprintf(vis_stderr, "   -u  turn off unroling\n");
556    (void)fprintf(vis_stderr, "   -F  ignore all timing\n");
557    return 1;
558}
559
560/**Function********************************************************************
561
562  Synopsis    [The top-level routine for read_blif.]
563
564  Description []
565
566  SideEffects []
567
568  CommandName [read_blif]
569  CommandSynopsis [read a blif file]
570  CommandArguments [\[-c\] \[-e &lt;encoding_file_name&gt;\] \[-h\] [-v\] &lt;file_name&gt;]
571  CommandDescription [Reads a file in blif format into VIS.
572  All the synthesis-specific constructs of blif are ignored.
573  Internally the blif file is automatically translated into an equivalent
574  blif-mv file, which is then read in with read_blif_mv. Note that,
575  currently this command cannot read blif files which describe mapped
576  circuits. To get around this problem, please use SIS synthesis tool
577  to generate an ordinary  blif file.
578 
579  Command options:<p>
580  <dl><dt> -c
581  <dd> Semi-canonicalize all the tables in each model. See the documentation
582  of <A HREF=./read_blif_mvCmd.html> read_blif_mv </A> for details.
583  </dl>
584  <dl><dt> -e &lt;encoding_file_name&gt;
585  <dd> If set, the program reads in a blif file using the encoding
586  information specified in the encoding_file_name. Only the current
587  hnode is altered in the process, and hence the read is incremental.
588  Typically the encoding file is written out by a write_blif operation.
589  Note that this option cannot be used if no file has been read in.
590  Internally, the encoding file is used in combination with the blif file
591  to create a blif-mv file which is compatible with the I/O interface
592  of the current node.
593  </dl>
594  <dl><dt> -h
595  <dd> Print the command usage.
596  </dl>
597  <dl><dt> -v
598  <dd> If set, the program prints out all the unused variables
599  in the blif file.
600  </dl>
601  <dl><dt> &lt;file_name&gt;
602  <dd> Name of a blif file to be read in. This can be the output written by SIS.
603  in the blif file.
604  </dl>
605  ]
606
607  SeeAlso     []
608
609******************************************************************************/
610static int
611CommandReadBlif(
612  Hrc_Manager_t **hmgr,
613  int argc,
614  char **argv)
615{
616  int c, status;
617  boolean isCanonical = 0;
618  boolean isIncremental = 0;
619  boolean isVerbose = 0;
620  char *fileName, *realFileName, *visDirectoryName, *blifMvFileName;
621  char *encodingFileName;
622  char command[512];
623  FILE *fp;
624#if HAVE_MKSTEMP && HAVE_CLOSE
625  int  fd;
626#else
627  char buffer[512];
628#endif
629  Hrc_Manager_t *newHmgr;
630 
631  util_getopt_reset();
632  while ((c = util_getopt(argc,argv,"ce:hv")) != EOF){
633    switch(c){
634      case 'c':
635        isCanonical = 1;
636        break;
637      case 'e':
638        isIncremental = 1;
639        fp = Cmd_FileOpen(util_optarg, "r", &encodingFileName, 1);
640        if (fp == NIL(FILE)){
641          (void)fprintf(vis_stderr,"Encoding file %s is not found\n", util_optarg);
642          return 1;
643        }
644        if (fp != stdin){
645          (void)fclose(fp);
646        }
647        break;
648      case 'h':
649        goto usage;
650      case 'v':
651        isVerbose = 1;
652        break;
653      default:
654        goto usage;
655    }
656  }
657
658  /* check to see if there is only one argument left for a file name */
659  if (argc-1 != util_optind){
660    goto usage;
661  }
662  fileName = argv[util_optind];
663
664  fp = Cmd_FileOpen(fileName, "r", &realFileName, 1);
665 
666  if (fp == NIL(FILE)){
667    /*
668    FREE(realFileName);
669    */
670    (void)fprintf(vis_stderr,"File %s cannot be opened\n", fileName);
671    return 1;
672  }
673  if (fp != stdin){
674    (void)fclose(fp);
675  }
676
677#if HAVE_MKSTEMP && HAVE_CLOSE
678  blifMvFileName = util_strsav("/tmp/vis.XXXXXX");
679  fd = mkstemp(blifMvFileName);
680  if (fd == -1){
681#else
682  blifMvFileName = util_strsav(tmpnam(buffer));
683  if (blifMvFileName == NIL(char)){
684#endif
685    FREE(realFileName);
686    (void)fprintf(vis_stderr,"Could not create temporary file. ");
687    (void)fprintf(vis_stderr,"Clean up /tmp an try again.\n");
688    return 1;
689  }
690#if HAVE_MKSTEMP && HAVE_CLOSE
691  close(fd);
692#endif
693  /* Invoking an awk script */
694  visDirectoryName = Vm_VisObtainLibrary();
695  if (isIncremental == 0){
696    (void)sprintf(command,"sed 's/^\\./@/g' %s | sed 's/\\./$/g' | sed 's/^@/\\./g' | sed 's/{/</g' | sed 's/}/>/g'| sed 's/(/<</g' | sed 's/)/>>/g'| %s -f %s/ioBlifToMv.nawk > %s", realFileName, NAWK, visDirectoryName, blifMvFileName);
697  }
698  else {
699    (void)sprintf(command,"sed 's/^\\./@/g' %s | sed 's/\\./$/g' | sed 's/^@/\\./g' | sed 's/{/</g' | sed 's/}/>/g'| %s -f %s/ioBlifToMvForIncremental.nawk > %s", realFileName, NAWK, visDirectoryName, blifMvFileName);
700  }
701  (void)system(command);
702  FREE(visDirectoryName);
703  FREE(realFileName);
704
705  error_init();
706
707  if (isIncremental == 0){
708    fp = Cmd_FileOpen(blifMvFileName, "r", NIL(char *), 1);
709  }
710  else {
711    char *finalBlifMvFileName;
712   
713#if HAVE_MKSTEMP && HAVE_CLOSE
714    finalBlifMvFileName = util_strsav("/tmp/vis.XXXXXX");
715    fd = mkstemp(finalBlifMvFileName);
716    if (fd == -1){
717#else
718    finalBlifMvFileName = util_strsav(tmpnam(buffer));
719    if (finalBlifMvFileName == NIL(char)){
720#endif
721      FREE(blifMvFileName);
722      (void)fprintf(vis_stderr,"Could not create temporary file. ");
723      (void)fprintf(vis_stderr,"Clean up /tmp an try again.\n");
724      return 1;
725    }
726#if HAVE_MKSTEMP && HAVE_CLOSE
727    close(fd);
728#endif
729
730    (void)sprintf(command,"cat %s %s > %s",encodingFileName,blifMvFileName,finalBlifMvFileName);
731    (void)system(command);
732    FREE(encodingFileName);
733#if HAVE_UNLINK
734    unlink(blifMvFileName);
735#endif
736    FREE(blifMvFileName);
737    blifMvFileName = finalBlifMvFileName;
738
739    fp = Cmd_FileOpen(blifMvFileName, "r", NIL(char *), 1);
740  }
741  assert(fp != NIL(FILE));
742  newHmgr = Io_BlifMvRead(fp,*hmgr,isCanonical,isIncremental,isVerbose);
743  if (newHmgr != NIL(Hrc_Manager_t)){
744    status = 0;
745    if (isIncremental == 0){
746      Hrc_ManagerFree(*hmgr);
747      *hmgr = newHmgr;
748    }
749  }
750  else {
751    status = 1;
752  }
753
754  (void)fprintf(vis_stderr,"%s",error_string());
755  fflush(vis_stderr);
756  if (fp != stdin) {
757    (void) fclose(fp);
758#if HAVE_UNLINK
759    unlink(blifMvFileName);
760#endif
761  }
762  FREE(blifMvFileName);
763  return (status);
764
765  usage:
766    (void)fprintf(vis_stderr, "usage: read_blif [-c] [-e encoding_file] [-h] [-v] file\n");
767    (void)fprintf(vis_stderr, "   -c  table canonicalization\n");
768    (void)fprintf(vis_stderr, "   -e  read a file into the current node using encoding file\n");
769    (void)fprintf(vis_stderr, "   -h  print the command usage\n");   
770    (void)fprintf(vis_stderr, "   -v  verbose\n");
771    return 1 ;
772}
773
774
775/**Function********************************************************************
776
777  Synopsis    [The top-level routine for write_blif]
778
779  Description [Determinizes, encodes and writes a set of tables into blif]
780
781  SideEffects []
782
783  CommandName [write_blif]
784  CommandSynopsis [determinize, encode and write an hnode to a blif file]
785  CommandArguments [\[-c\] \[-l\] \[-e &lt;encoding_file_name&gt;\] \[-R\] \[-h\] \[-v &lt;verbosity_value&gt;\] \[&lt;file&gt;\]]
786  CommandDescription [Encodes, determinizes, and writes all tables in the current hnode
787  to a BLIF file. With the '-l' or '-c' options, or when 'write_blif'
788  is used with no options, only the current hnode is written out as
789  a blif file. The '-R' option writes the entire hierarchy rooted at the
790  current hnode to the blif file, assuming all tables are deterministic
791  and all variables are boolean. <p>
792 
793
794  Encoding the Multi-Valued Variables: <p>
795 
796  First, all multi-valued variables in the hnode are binary
797  encoded. Each multi-valued variable requires 'm' binary variables in
798  its encoding, where m = log2(n). Here 'n' is the number of values in
799  the domain of the multi-valued variable. If variable X has n binary
800  variables in its encoding, these are called X0, X1, ... X<n-1>. X0
801  is the least significant encoding variable. The value i of multi-valued
802  variable X is encoded such that
803   X0 + 2^1 * X1 + ... + 2^(n-1) * X<n-1> = i.
804  After encoding, each table in the hnode is written out to the blif file.
805  <p>
806  Determinizing Non-Deterministic Tables:<p>
807
808 
809  Non-deterministic tables are determinized by adding more binary variables
810  to a particular variable's encoding. The variable that is chosen is the
811  one that has the smallest number of binary variables in its encoding.
812  Determinization is explained by means of an example:
813  <p>
814  Consider the BLIF-MV table, where each of a, b, and c can have 4 values.
815  Each multi-valued variable has two binary variables in its encoding. These
816  are called a0, a1, b0, b1, c0 and c1.
817  <p>
818  .model foo<p>
819  .inputs a b<p>
820  .outputs c<p>
821  .mv a, b, c 4<p>
822  .table a b ->c<p>
823  2 1 (1,2)<p>
824  (1,2) 1 3<p>
825  .end<p>
826  <p>
827  The first row of this table represents non-determinism, since for a
828  given assignment of input values (i.e. a=2, b=1), the output can take
829  on two values (1 or 2). To determinize this row, it is split into two
830  rows, each with a unique singleton output value. A new binary variable
831  is added to the encoding of a (or b, since in this case each of them has
832  the same number of binary variables in its encoding). The new variable
833  a2 is given separate values in each of the new rows. The resulting blif
834  table looks like:
835  <p>
836  .model foo<p>
837  .inputs a0 a1 a2 b0 b1 <p>
838  .outputs c0 c1<p>
839  .names a0 a1 a2 b0 b1 ->c0 c1<p>
840  0 1 0 1 0 1 0          (these two rows represent<p>
841  0 1 1 1 0 0 1          row 1 of the MV table)<p>
842  1 0 - 1 0 1 1          (these two rows represent            <p>
843  0 1 - 1 0 1 1          row 2 of the MV table)<p>
844  .end<p>
845  <p>
846  Note that this table is still not deterministic, since rows 1 and
847  4 have input minterm(s) in common, but the corresponding outputs
848  are different. To resolve this, a new binary variable is added to
849  the encoding for b (since b currently has the smallest encoding).
850  For the conflicting rows, this variable b2 is assigned different
851  values, and for all other rows, it is assigned a '-' value. After
852  this change, rows 1 and 4 no longer have common input minterm(s).
853  The intermediate table now looks like:
854  <p>
855  .model foo<p>
856  .inputs a0 a1 a2 b0 b1 b2<p>
857  .outputs c0 c1<p>
858  .names a0 a1 a2 b0 b1 b2->c0 c1<p>
859  0 1 0 1 0 1 1 0<p>
860  0 1 1 1 0 - 0 1<p>
861  1 0 - 1 0 - 1 1<p>
862  0 1 - 1 0 0 1 1<p>
863  .end<p>
864  <p>
865  This process is continued until the table is determinized. In this
866  example, the final blif file looks like:
867  <p>
868  .model foo<p>
869  .inputs a0 a1 a2 a3 b0 b1 b2<p>
870  .outputs c0 c1<p>
871  .table a0 a1 a2 a3 b0 b1 b2 ->c0 c1 <p>
872  0 1 0 - 1 0 1 1 0 <p>
873  0 1 1 1 1 0 - 0 1 <p>
874  1 0 - - 1 0 - 1 1 <p>
875  0 1 - 0 1 0 0 1 1 <p>
876  .end<p>
877  <p>
878  Blif allows only single output tables, so in reality the above table
879  is split into two single output tables before being written out to
880  the blif file. The new binary variables that are thus introduced are
881  treated as primary inputs in the blif file.
882  <p>
883  We make no claim on the optimality of this process, just that it is
884  simple. It may turn out that the number of new variables is much larger than
885  the optimum one.
886  <p>
887  Interfacing Between Binary and Multi-Valued Variables:<p>
888  <p>
889  In order for the SIS-optimized version of this file to be read back into
890  VIS, we need to re-create the corresponding multi-valued variables. For
891  this purpose, interface information (model name, input and output
892  declarations for the hnode) is written out to a special encoding file
893  (e.g. foo.enc).
894  Additionally, binary->multi-valued encoding tables are written to the
895  encoding file for each PO. In the above example, the binary->multi-valued
896  table for variable c looks like<p>
897  .table c0 c1 -> c<p>
898  0 0 0<p>
899  1 0 1<p>
900  0 1 2<p>
901  1 1 3<p>
902  and this can be seen as a decoder of the binary variables.
903  Similarly, multi-valued->binary encoding tables are written to the encoding
904  file for each PI. The multi-valued->binary table for variable b in the above
905  example is:<p>
906  .table b -> b0 b1<p>
907  0 0 0  <p>
908  1 1 0<p>
909  2 0 1<p>
910  3 1 1<p>
911  and this can be seen as an encoder of the multi-valued variables.
912  Similar tables are written to the encoding file for sub-circuit inputs and
913  outputs. Likewise, such tables are written out for latch inputs and outputs.
914  This is needed so that the original multi-valued latches can be reinstated
915  while the blif file is being read back into VIS. These multi-valued latch
916  declarations are written to the encoding file during the write_blif process.
917  <p>
918  The combination of this encoding file and the blif file results in a legal
919  BLIF-MV hnode description.
920  <p>
921  If no file is specified, the blif file is written out to the standard output.
922  If the encoding file is not specified, encoding information is written out
923  to <modelname>.enc.
924  <p>
925  Options:<p>
926  <p>
927  The '-R' option writes the entire hierarchy rooted at the current hnode to
928  the blif file, first checking that all tables are deterministic and all variables are
929  boolean. Other options ('-c', '-l', or write_blif with no options) only write
930  out the current hnode. Also, when the '-R' option is specified, no encoding
931  file is written since none is needed.
932 
933  <p>
934  Command options:<p>
935  <dl><dt> -c
936  <dd> Writes only combinational part to blif file.
937  </dl>
938  <dl><dt> -l
939  <dd> Writes out latches, making latch IOs primary outputs in the blif file.
940  </dl>
941  <dl><dt> -e &lt;encoding_file_name&gt;
942  <dd> If set, the program writes the encoding information into this
943  file. The default is the model name for the current node
944  extended by .enc.
945  </dl>
946  <dl><dt> -R
947  <dd> Recursively writes out the entire hierarchy rooted at the current hnode to the blif file.
948  In this sub-hierarchy, all tables must be deterministic and all variables must be boolean.
949  Either of the -c, -l or -e options cannot be used together with this option.
950  </dl>
951  <dl><dt> -h
952  <dd> Prints the command usage.
953  </dl>
954  <dl><dt> -v &lt;verbosity_value&gt;
955  <dd> Specifies verbosity level, an integer less than 3.
956  </dl>
957  <dl><dt> &lt;file&gt;
958  <dd> name of blif file to be written, default is standard output.
959  </dl>
960  <dl><dt>
961  <dd> Note that if neither the -c or the -l options are chosen, then latches are written out,
962  without making latch IOs primary outputs in the blif file. Currently the files written out
963  using this option cannot be read back into VIS.
964  </dl>
965  ]
966
967  SeeAlso     []
968
969
970  SeeAlso     []
971
972******************************************************************************/
973static int
974CommandWriteBlif(
975  Hrc_Manager_t **hmgr,
976  int argc, 
977  char **argv)
978{
979  FILE *enc_fp, *fp;
980  char *modelName, *dupname;
981  int status, verbosity, combinationalOnly, makeLatchIOsPOs;
982  Io_Encoding_Type_t encoding_type;
983  Hrc_Node_t *hnode;
984  int c;
985  boolean recursive;
986
987  fp = stdout;
988  enc_fp = NIL(FILE);
989  verbosity = 0;
990  combinationalOnly = 0;
991  makeLatchIOsPOs = 0;
992  recursive = 0;
993
994  util_getopt_reset();
995  while ((c = util_getopt(argc, argv, "clRe:hv:")) != EOF) {
996      switch(c) {
997      case 'c':
998          combinationalOnly = 1;
999          break;
1000      case 'l':
1001          makeLatchIOsPOs = 1;
1002          break;
1003      case 'R':
1004          recursive = 1;
1005          break;
1006      case 'e':
1007          enc_fp = Cmd_FileOpen(util_optarg, "w", NIL(char *), 1);
1008          if (enc_fp == NIL(FILE)){
1009              (void)fprintf(vis_stderr,"Cannot write to %s\n", util_optarg);
1010              return 1;
1011          }
1012          break;
1013      case 'h':
1014          goto usage;
1015      case 'v':
1016          verbosity = atoi(util_optarg);
1017          break;
1018      default:
1019          goto usage;
1020      }
1021  }
1022
1023  if(makeLatchIOsPOs && combinationalOnly){
1024    (void)fprintf(vis_stderr,"Cannot use -c and -l options simultaneously.\n");
1025    goto usage;
1026  }
1027  if(recursive){
1028    if(makeLatchIOsPOs || combinationalOnly){
1029      (void)fprintf(vis_stderr,"Cannot use -c or -l options with -R option.\n");     
1030      goto usage;
1031    }
1032    if(enc_fp != NIL(FILE)){
1033      (void)fprintf(vis_stderr,"Cannot use -e option with -R option.\n");           
1034      goto usage;
1035    }
1036  }
1037  hnode = Hrc_ManagerReadCurrentNode(*hmgr);
1038  if (hnode == NIL(Hrc_Node_t)){
1039    (void)fprintf(vis_stderr,"No file has been read in.\n");
1040    return 1;
1041  }
1042
1043  /* check to see if there is only one argument left for a file name */
1044  if (argc == util_optind){
1045    fp = stdout;
1046  }
1047  else if (argc-1 == util_optind){
1048    fp = Cmd_FileOpen(argv[util_optind], "w", NIL(char *), 1);
1049    if (fp == NIL(FILE)){
1050      (void)fprintf(vis_stderr,"Cannot write to %s\n", argv[util_optind]);
1051       if (enc_fp != NIL(FILE)){
1052         fclose(enc_fp);
1053       }
1054       return 1;
1055    }
1056  }
1057  else {
1058    if (enc_fp != NIL(FILE)){
1059      fclose(enc_fp);
1060    }
1061    goto usage;
1062  }
1063
1064  if((enc_fp == NIL(FILE)) && !recursive){
1065      modelName = Hrc_NodeReadModelName(hnode);
1066      dupname = ALLOC(char, strlen(modelName) + strlen(".enc") + 1);
1067      sprintf(dupname, "%s%s", modelName, ".enc");
1068      enc_fp = Cmd_FileOpen(dupname, "w", NIL(char *), 1);
1069      if (enc_fp == NIL(FILE)){
1070        (void)fprintf(vis_stderr,"Cannot write to %s\n", dupname);
1071        return 1;
1072      }
1073      (void)fprintf(stdout, "Writing encoding information to %s\n",dupname);
1074      FREE(dupname);
1075  }
1076
1077  if(!recursive){
1078    if(!(makeLatchIOsPOs || combinationalOnly)){
1079      (void)fprintf(vis_stderr,"Warning - The blif and encoding files generated cannot be read back into \n");
1080      (void)fprintf(vis_stderr, "VIS. If you would like to read the optimized blif file back into VIS, then \n");
1081      (void)fprintf(vis_stderr, "please use 'write_blif -l' or 'write_blif -c' instead.\n");
1082    }
1083  }
1084
1085  error_init();
1086  encoding_type = SIMPLE;
1087  if(recursive){
1088    status = Io_HnodeWriteBlifTotal(encoding_type, hnode, fp, verbosity);
1089  }
1090  else{
1091    status = Io_HnodeWriteBlif(encoding_type, hnode, fp, enc_fp, verbosity, combinationalOnly, makeLatchIOsPOs);
1092  }
1093  (void)fprintf(vis_stderr,"%s",error_string());
1094  fflush(fp);
1095  if (fp != stdout) {
1096    (void) fclose(fp);
1097  }
1098
1099  if(status == 0){
1100    return 0;
1101  }
1102  else{
1103    return 1;
1104  }
1105
1106  usage:
1107    (void)fprintf(vis_stderr, "usage: write_blif [-c] [-l] [-e encoding_file] [-R] [-h] [-v verbosity] [blif_file]\n");
1108    (void)fprintf(vis_stderr, "   -c write only combinational part to blif file\n"); 
1109    (void)fprintf(vis_stderr, "   -l make latch IOs primary outputs in the blif file\n"); 
1110    (void)fprintf(vis_stderr, "   -e encoding_file, default is <model_name>.enc\n");
1111    (void)fprintf(vis_stderr, "   -R recursively write out the hierarchy rooted at the current hnode.\n");
1112    (void)fprintf(vis_stderr, "      In this sub-hierarchy, all tables must be deterministic and all\n");
1113    (void)fprintf(vis_stderr, "      variables must be boolean. Either of the -c, -l, or -e options \n");
1114    (void)fprintf(vis_stderr, "      cannot be simultaneously with the -R option \n");
1115    (void)fprintf(vis_stderr, "   -h print this usage message\n"); 
1116    (void)fprintf(vis_stderr, "   -v verbosity, an integer < 3, default is 0\n");
1117    (void)fprintf(vis_stderr, "Note: * If neither the -c or -l options are chosen, then latches will \n");
1118    (void)fprintf(vis_stderr, "        be written out to the blif file. Latch IOs will not be made\n");
1119    (void)fprintf(vis_stderr, "        into primary outputs in the blif file\n");
1120    (void)fprintf(vis_stderr, "      * After optimizing the blif file in SIS, do not write out the\n");
1121    (void)fprintf(vis_stderr, "        optimized file using 'write_blif -s' if you want to read\n");
1122    (void)fprintf(vis_stderr, "        it back into VIS. Use 'write_blif' instead \n");
1123    return 1 ;
1124   
1125}
1126
Note: See TracBrowser for help on using the repository browser.