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

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

vis2.3

File size: 18.4 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [ioReadBlifMv.c]
4
5  PackageName [io]
6
7  Synopsis    [Routines related to reading in blif-mv files.]
8
9  Description []
10
11  SeeAlso     []
12
13  Author      [Yuji Kukimoto, Rajeev Ranjan, Huey-Yih Wang]
14
15  Copyright   [Copyright (c) 1994-1996 The Regents of the Univ. of California.
16  All rights reserved.
17
18  Permission is hereby granted, without written agreement and without license
19  or royalty fees, to use, copy, modify, and distribute this software and its
20  documentation for any purpose, provided that the above copyright notice and
21  the following two paragraphs appear in all copies of this software.
22
23  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
24  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
25  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
26  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
29  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
30  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
31  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
32  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
33
34******************************************************************************/
35
36#include "ioInt.h"
37
38static char rcsid[] UNUSED = "$Id: ioReadBlifMv.c,v 1.12 2002/09/10 04:35:24 fabio Exp $";
39
40/*---------------------------------------------------------------------------*/
41/* Constant declarations                                                     */
42/*---------------------------------------------------------------------------*/
43#ifndef NAWK
44#define NAWK "gawk"
45#endif
46
47
48/*---------------------------------------------------------------------------*/
49/* Type declarations                                                         */
50/*---------------------------------------------------------------------------*/
51
52
53/*---------------------------------------------------------------------------*/
54/* Stucture declarations                                                     */
55/*---------------------------------------------------------------------------*/
56
57
58/*---------------------------------------------------------------------------*/
59/* Variable declarations                                                     */
60/*---------------------------------------------------------------------------*/
61static jmp_buf env;
62extern FILE *IoYyin;
63extern int globalCurrentStackDepth;
64#ifdef IODEBUG
65extern int IoYydebug;
66#endif /*IODEBUG */
67
68/*---------------------------------------------------------------------------*/
69/* Macro declarations                                                        */
70/*---------------------------------------------------------------------------*/
71
72
73/**AutomaticStart*************************************************************/
74
75/*---------------------------------------------------------------------------*/
76/* Static function prototypes                                                */
77/*---------------------------------------------------------------------------*/
78
79static void _IoGlobalVariablesInitialize(void);
80static void _IoGlobalVariablesFree(void);
81static void _IoGlobalSubcktInfoFree(void);
82static void _IoSubcktArrayFree(array_t *array);
83static void _IoSubcktFree(IoSubckt_t *subckt);
84static void _IoGlobalResetInfoFree(void);
85static boolean _IoNodeTestCompatibilityAux(Hrc_Manager_t *hmgr, Hrc_Node_t *hnode1, Hrc_Node_t *hnode2, boolean mode);
86static void _IoManagerCanonicalize(Hrc_Manager_t *hmgr);
87
88/**AutomaticEnd***************************************************************/
89
90
91/*---------------------------------------------------------------------------*/
92/* Definition of exported functions                                          */
93/*---------------------------------------------------------------------------*/
94/**Function********************************************************************
95
96  Synopsis    [Reads in a blif-mv file.]
97
98  Description [Reads in a blif-mv file. Returns a pointer to a new hierarchy
99  manager if isIncremental == 0. If isIncremental == 1, hmgr should
100  be set to the current manager and will be updated by this function call.
101  If isCanonical == 1, then all the tables in each model will be
102  canonicalized with Tbl_TableCanonicalize(). If isVerbose == 1,
103  all the unused variables are listed for each model while if isVerbose == 0,
104  all the models that have an unused variable are simply listed.
105  These messages can be referred to by error_string() after the call.
106  Returns NIL(Hrc_Manager_t) if failure.]
107
108  SideEffects []
109
110  SeeAlso     []
111
112******************************************************************************/
113Hrc_Manager_t *
114Io_BlifMvRead(
115  FILE *fp, 
116  Hrc_Manager_t *hmgr, 
117  boolean isCanonical,
118  boolean isIncremental,
119  boolean isVerbose)
120{
121  Hrc_Node_t *root;
122  static Hrc_Manager_t *newHmgr;
123
124  if (isIncremental == 0){
125    newHmgr = Hrc_ManagerAlloc(); 
126  }
127  else { /* isIncremental == 1 */
128    if (Hrc_ManagerReadCurrentNode(hmgr) == NIL(Hrc_Node_t)){
129      (void)fprintf(vis_stderr,"No hierarchy has been created. Cannot do inremental read-in.\n");
130      return NIL(Hrc_Manager_t);
131    }
132    newHmgr = hmgr;
133  }
134
135  if (setjmp(env)){
136    if (isIncremental == 0){
137      Hrc_ManagerFree(newHmgr);
138    }
139    else {
140      int i;
141      /* free all the new models defined in an incremental file */
142      for (i=0; i < array_n(globalNewModelArray); i++){
143        Hrc_ModelDelete(hmgr,Hrc_ModelReadName(array_fetch(Hrc_Model_t *,globalNewModelArray,i)));
144      }
145    }
146    _IoGlobalVariablesFree();
147    return NIL(Hrc_Manager_t);
148  }
149  else {
150    _IoGlobalVariablesInitialize();
151    if (isIncremental == 0){
152      globalYaccHmgr = newHmgr;
153    }
154    else {
155      globalYaccHmgr = hmgr;
156    }
157#ifdef IODEBUG
158    IoYydebug = 1;
159#endif /* IODEBUG */
160    IoYyin = fp;
161    IoYyrestart(IoYyin);
162    if (IoYyparse() == 1){
163      IoError();
164    }
165
166    /* globalNewModelArray contains all the models defined in the previous
167    IoYyparse(). If isIncremental==0, then they are simply all the models.
168    If isIncremental==1, then they are new models defined in the file. */
169
170    if (IoNetworkTestConsistency(newHmgr,globalNewModelArray,globalParserSubcktInfo,globalParserResetInfo,isVerbose) == 0){
171      IoError();
172    }
173
174    if (globalRootModel == NIL(Hrc_Model_t)){
175      globalRootModel = globalFirstModel;
176      globalRootInstanceName = util_strsav(Hrc_ModelReadName(globalRootModel));
177    }
178    else if (globalRootInstanceName == NIL(char)){
179      globalRootInstanceName = util_strsav(Hrc_ModelReadName(globalRootModel));
180    }
181
182    if (isCanonical == 1){
183      _IoManagerCanonicalize(newHmgr);
184    }
185
186    root = Hrc_ModelCreateHierarchy(newHmgr,globalRootModel,globalRootInstanceName);
187    FREE(globalRootInstanceName);
188
189    if (isIncremental == 0){
190      Hrc_ManagerSetRootNode(newHmgr,root);
191      Hrc_ManagerSetCurrentNode(newHmgr,root);
192      _IoGlobalVariablesFree();
193      return newHmgr;
194    }   
195    else { /* isIncremental == 1, note that newHmgr == hmgr  */
196      if (_IoNodeTestCompatibility(hmgr,Hrc_ManagerReadCurrentNode(hmgr),root) == 0){
197        int i;
198        (void)fprintf(vis_stderr,"The blif-mv file is not compatible with the existing hierarchy.\n");
199        Hrc_TreeReplace(NIL(Hrc_Node_t),root);
200        /* free all the new models defined in an incremental file */
201        for (i=0; i < array_n(globalNewModelArray); i++){
202          Hrc_ModelDelete(hmgr,Hrc_ModelReadName(array_fetch(Hrc_Model_t *,globalNewModelArray,i)));
203        }
204        _IoGlobalVariablesFree();
205        return NIL(Hrc_Manager_t);
206      }
207      Hrc_TreeReplace(Hrc_ManagerReadCurrentNode(hmgr),root);
208      Hrc_ManagerSetCurrentNode(hmgr,root);
209      _IoGlobalVariablesFree();
210      return hmgr;
211    }
212  }
213}
214
215/**Function********************************************************************
216
217  Synopsis    [Reads in a blif file.]
218
219  Description [Reads in a blif file specified by its file name. Returns
220  a pointer to a new hierarchy manager. All the error/warning messages
221  obtained while  parsing the file are stored in error_string().
222  isVerbose should be set either to one or to zero depending on how much
223  detailed error/warning information is needed. Returns NIL(Hrc_Manager_t)
224  if failure.]
225
226  SideEffects []
227
228  SeeAlso     []
229
230******************************************************************************/
231Hrc_Manager_t *
232Io_BlifRead(
233  char *fileName,
234  boolean isVerbose)
235{
236  FILE *fp;
237#if HAVE_MKSTEMP && HAVE_CLOSE
238  int  fd;
239#else
240  char buffer[512];
241#endif
242  char *realFileName, *blifMvFileName, *visDirectoryName;
243  char command[512];
244  Hrc_Manager_t *hmgr;
245 
246  fp = Cmd_FileOpen(fileName, "r", &realFileName, /* silent */ 1);
247
248  if (fp == NIL(FILE)){
249    FREE(realFileName);
250    (void)fprintf(vis_stderr,"File %s is not found.\n", fileName);
251    return NIL(Hrc_Manager_t);
252  }
253  if (fp != stdin){
254    (void)fclose(fp);
255  }
256
257#if HAVE_MKSTEMP && HAVE_CLOSE
258  blifMvFileName = util_strsav("/tmp/vis.XXXXXX");
259  fd = mkstemp(blifMvFileName);
260  if (fd == -1){
261#else
262  blifMvFileName = util_strsav(tmpnam(buffer));
263  if (blifMvFileName == NIL(char)){
264#endif
265    FREE(realFileName);
266    (void)fprintf(vis_stderr,"Could not create temporary file. ");
267    (void)fprintf(vis_stderr,"Clean up /tmp an try again.\n");
268    return NIL(Hrc_Manager_t);
269  }
270#if HAVE_MKSTEMP && HAVE_CLOSE
271  close(fd);
272#endif
273  /* Invoking an awk script */
274  visDirectoryName = Vm_VisObtainLibrary();
275  (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);
276  /* the following is missing two new sed processings
277  (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);
278  */
279  (void)system(command);
280  FREE(visDirectoryName);
281  FREE(realFileName);
282
283  error_init();
284
285  fp = Cmd_FileOpen(blifMvFileName, "r", NIL(char *), 1);
286  assert(fp != NIL(FILE));
287  hmgr = Io_BlifMvRead(fp,NIL(Hrc_Manager_t),0,0,isVerbose);
288  fclose(fp);
289#if HAVE_UNLINK
290  unlink(blifMvFileName);
291#endif
292  FREE(blifMvFileName);
293  return hmgr;
294}
295
296/*---------------------------------------------------------------------------*/
297/* Definition of internal functions                                          */
298/*---------------------------------------------------------------------------*/
299
300/**Function********************************************************************
301
302  Synopsis    [Jumps out of an error state.]
303
304  Description []
305
306  SideEffects []
307
308  SeeAlso     []
309
310******************************************************************************/
311void
312IoError(void)
313{
314  longjmp(env,1);
315}
316
317/*---------------------------------------------------------------------------*/
318/* Definition of static functions                                            */
319/*---------------------------------------------------------------------------*/
320
321
322/**Function********************************************************************
323
324  Synopsis    [Initilizes all the global variables used in the parser.]
325
326  Description []
327
328  SideEffects []
329
330  SeeAlso     []
331
332******************************************************************************/
333static void
334_IoGlobalVariablesInitialize(void)
335{
336  globalLineNumber = 1;
337  globalModel = NIL(Hrc_Model_t);
338  globalHnode = NIL(Hrc_Node_t);
339  globalFirstModel = NIL(Hrc_Model_t); /* set once */
340  globalRootModel = NIL(Hrc_Model_t); /* set once */
341  globalRootInstanceName = NIL(char); /* set once */
342  globalMvNameArray = NIL(array_t);
343  globalSymValueArray = NIL(array_t);
344  globalTableInputArray = NIL(array_t);
345  globalTableOutputArray = NIL(array_t);
346  globalTableDefaultArray = NIL(array_t);
347  globalTableSymCubeArray = NIL(array_t);
348  globalFormalNameArray = NIL(array_t);
349  globalActualNameArray = NIL(array_t);
350
351  globalSubcktArray = NIL(array_t);
352  globalResetArray = NIL(array_t);
353
354  globalNewModelArray = array_alloc(Hrc_Model_t *,0);
355
356  globalCurrentStackDepth = 0;
357
358  /* a hash table from a model name to an array of resets/subcircuits in the model */
359  globalParserResetInfo = st_init_table(st_ptrcmp,st_ptrhash);
360  globalParserSubcktInfo = st_init_table(st_ptrcmp,st_ptrhash);
361}
362
363/**Function********************************************************************
364
365  Synopsis    [Frees all the global data structures used in the parser.]
366
367  Description []
368
369  SideEffects []
370
371  SeeAlso     []
372
373******************************************************************************/
374static void
375_IoGlobalVariablesFree(void)
376{
377   array_free(globalNewModelArray);
378   _IoGlobalResetInfoFree(); 
379   _IoGlobalSubcktInfoFree();
380}
381
382
383/**Function********************************************************************
384
385  Synopsis    [Frees the subckt information only used by the parser.]
386
387  Description []
388
389  SideEffects []
390
391  SeeAlso     []
392
393******************************************************************************/
394static void
395_IoGlobalSubcktInfoFree(void)
396{
397  st_generator *gen;
398  char *key, *val;
399
400  st_foreach_item(globalParserSubcktInfo,gen,&key,&val){
401    if ((array_t *)val != NIL(array_t)){
402      _IoSubcktArrayFree((array_t *)val);
403    }
404  }
405  st_free_table(globalParserSubcktInfo);
406}
407
408
409/**Function********************************************************************
410
411  Synopsis    [Frees an array of the subckt data structure only used by the parser.]
412
413  Description []
414
415  SideEffects []
416
417  SeeAlso     []
418
419******************************************************************************/
420static void
421_IoSubcktArrayFree(array_t *array)
422{
423  int i;
424
425  for (i=0; i < array_n(array); i++){
426    _IoSubcktFree(array_fetch(IoSubckt_t *,array,i));
427  }
428  array_free(array);
429}
430
431/**Function********************************************************************
432
433  Synopsis    [Frees the subckt data structure used by the parser.]
434
435  Description []
436
437  SideEffects []
438
439  SeeAlso     []
440
441******************************************************************************/
442static void
443_IoSubcktFree(IoSubckt_t *subckt)
444{
445  FREE(subckt->modelName);
446  FREE(subckt->instanceName);
447  IoStringArrayFree(subckt->formalNameArray);
448  IoStringArrayFree(subckt->actualNameArray);
449  FREE(subckt);
450}
451
452
453/**Function********************************************************************
454
455  Synopsis    [Frees the reset data structure used only by the parser.]
456
457  Description []
458
459  SideEffects []
460
461  SeeAlso     []
462
463******************************************************************************/
464static void
465_IoGlobalResetInfoFree(void)
466{
467  st_generator *gen;
468  char *key, *val;
469  int i;
470  Tbl_Table_t *resetTable;
471
472  st_foreach_item(globalParserResetInfo,gen,&key,&val){
473    if ((array_t *)val != NIL(array_t)){
474      for (i=0; i < array_n((array_t *)val); i++){
475        resetTable = array_fetch(Tbl_Table_t *,(array_t *)val,i);
476        if (resetTable != NIL(Tbl_Table_t)){
477          Tbl_TableFree(resetTable);
478        }
479      }
480      array_free((array_t *)val);
481    }
482  }
483  st_free_table(globalParserResetInfo);
484}
485
486
487/**Function********************************************************************
488
489  Synopsis    [Checks if two hnodes are compatible with respect to their i/o
490  interface.]
491
492  Description [Checks if two hnodes are compatible with respect to their i/o
493  interface. Used in incremental read-in.]
494
495  SideEffects []
496
497  SeeAlso     [_IoNodeTestCompatibilityAux]
498
499******************************************************************************/
500boolean
501_IoNodeTestCompatibility(
502  Hrc_Manager_t *hmgr,
503  Hrc_Node_t *hnode1,
504  Hrc_Node_t *hnode2)
505{
506  return (_IoNodeTestCompatibilityAux(hmgr,hnode1,hnode2,0)
507          && _IoNodeTestCompatibilityAux(hmgr,hnode1,hnode2,1));
508}
509
510/**Function********************************************************************
511
512  Synopsis    [Checks if two hnodes are compatible with respect to their input
513  or output interface depending on the last boolean flag.]
514
515  Description [Checks if two hnodes are compatible with respect to their input
516  or output interface depending on the last boolean flag. 0 for input and 1
517  for output.]
518
519  SideEffects []
520
521  SeeAlso     []
522
523******************************************************************************/
524static boolean
525_IoNodeTestCompatibilityAux(
526  Hrc_Manager_t *hmgr,
527  Hrc_Node_t *hnode1,
528  Hrc_Node_t *hnode2,
529  boolean mode)
530{
531  int i, n;
532  array_t *formalVars1, *formalVars2;
533  Var_Variable_t *var1, *var2;
534
535  if (mode == 0){
536    formalVars1 = Hrc_NodeReadFormalInputs(hnode1);
537    formalVars2 = Hrc_NodeReadFormalInputs(hnode2);
538  }
539  else {
540    formalVars1 = Hrc_NodeReadFormalOutputs(hnode1);
541    formalVars2 = Hrc_NodeReadFormalOutputs(hnode2);
542  }
543  if ((n = array_n(formalVars1)) != array_n(formalVars2)){
544    error_append("Two hnodes have different number of formal ");
545    if (mode == 0){
546      error_append("inputs.\n");
547    }
548    else {
549      error_append("outputs.\n");
550    }
551    return 0;
552  } 
553  for (i=0; i < n; i++){
554    var1 = array_fetch(Var_Variable_t *,formalVars1,i);
555    var2 = array_fetch(Var_Variable_t *,formalVars2,i);
556    if (strcmp(Var_VariableReadName(var1),Var_VariableReadName(var2)) != 0){
557      error_append("Two hnodes have different ports, ");
558      error_append(Var_VariableReadName(var1));
559      error_append(" and ");
560      error_append(Var_VariableReadName(var2));
561      error_append("\n");
562      return 0; 
563    }
564    if (Var_VariablesTestHaveSameDomain(var1,var2) == 0){
565      error_append("Two hnodes have ports defined over different domains, ");
566      error_append(Var_VariableReadName(var1));
567      error_append(" and ");
568      error_append(Var_VariableReadName(var2));
569      error_append("\n");
570      return 0; 
571    }
572  }
573  return 1;
574}
575
576
577/**Function********************************************************************
578
579  Synopsis    [Canonicalizes all the tables in a given manager using
580  Tbl_TableCanonicalize().]
581
582  SideEffects [The original tables will be overwritten.]
583
584  SeeAlso     []
585
586******************************************************************************/
587static void
588_IoManagerCanonicalize(
589  Hrc_Manager_t *hmgr)
590{
591  int i;
592  Hrc_Model_t *model;
593  Hrc_Node_t *node;
594  Tbl_Table_t *table;
595  st_generator *gen, *gen2;
596  char *modelName, *latchName;
597  Hrc_Latch_t *latch;
598
599  Hrc_ManagerForEachModel(hmgr,gen,modelName,model){
600    node = Hrc_ModelReadMasterNode(model);
601    Hrc_NodeForEachNameTable(node,i,table){
602      Tbl_TableCanonicalize(table);
603    }
604    Hrc_NodeForEachLatch(node,gen2,latchName,latch){
605      Tbl_TableCanonicalize(Hrc_LatchReadResetTable(latch));
606    }
607  }
608}
Note: See TracBrowser for help on using the repository browser.