source: vis_dev/vis-2.3/src/hrc/hrcMisc.c @ 30

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

vis2.3

File size: 30.7 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [hrcMisc.c]
4
5  PackageName [hrc]
6
7  Synopsis    [This file provides some miscellaneous functions.]
8
9  SeeAlso     []
10
11  Author      [Shaz Qadeer]
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 "hrcInt.h"
35
36static char rcsid[] UNUSED = "$Id: hrcMisc.c,v 1.4 2005/04/27 00:10:58 fabio Exp $";
37
38/*---------------------------------------------------------------------------*/
39/* Constant declarations                                                     */
40/*---------------------------------------------------------------------------*/
41
42
43/*---------------------------------------------------------------------------*/
44/* Type declarations                                                         */
45/*---------------------------------------------------------------------------*/
46
47
48/*---------------------------------------------------------------------------*/
49/* Stucture declarations                                                     */
50/*---------------------------------------------------------------------------*/
51
52
53/*---------------------------------------------------------------------------*/
54/* Variable declarations                                                     */
55/*---------------------------------------------------------------------------*/
56
57
58/*---------------------------------------------------------------------------*/
59/* Macro declarations                                                        */
60/*---------------------------------------------------------------------------*/
61
62
63/**AutomaticStart*************************************************************/
64
65/*---------------------------------------------------------------------------*/
66/* Static function prototypes                                                */
67/*---------------------------------------------------------------------------*/
68
69static void NodeObtainComponentModels(Hrc_Node_t *node, st_table *models);
70
71/**AutomaticEnd***************************************************************/
72
73
74/*---------------------------------------------------------------------------*/
75/* Definition of exported functions                                          */
76/*---------------------------------------------------------------------------*/
77
78/**Function********************************************************************
79
80  Synopsis    [Returns pointer to the node corresponding to a path name.]
81
82  Description [The function returns a pointer to the node corresponding to
83               a path name. If pathFlag is TRUE it is assumed that the name
84               begins from the current node otherwise the name is assumed to
85               begin from the root node. If the pathname is correct, the
86               corresponding node is returned otherwise NULL is returned.
87               Note that the pathname should start with instance name of the
88               child of the current node or the root node as the case may be.
89               The individual instance names are separated by ".".]
90
91  SideEffects []
92
93  SeeAlso     []
94
95******************************************************************************/
96Hrc_Node_t *
97Hrc_ManagerFindNodeByPathName(
98  Hrc_Manager_t *manager, 
99  char *path,
100  boolean pathFlag)
101{
102  int position, count;
103  int i = 0;
104  Hrc_Node_t *presentNode;
105  char *name;
106 
107  /* Check whether the pathname begins from the root node or the current node
108     and initialize presentNode accordingly. */
109  if(pathFlag == FALSE) { 
110    /* Hierarchy will be traversed beginning from root node. */
111    presentNode = manager->rootNode;
112  }
113  else {
114    /* Hierarchy will be traversed beginning from current node. */
115    presentNode = manager->currentNode;
116  }
117
118  position = i;
119/* The name of a particular node in the pathname begins at position.
120   position is updated every time presentNode is updated to a child from
121   the parent. */
122 
123  count = 0;
124  while(path[i] != '\0') {
125    if(path[i] == '.') {
126      name = ALLOC(char, count+1);
127      strncpy(name, path+position, count);
128      name[count] = '\0';
129      if((presentNode = Hrc_NodeFindChildByName(presentNode, name)) ==
130         NIL(Hrc_Node_t)) {
131        FREE(name);
132        return NIL(Hrc_Node_t);
133      }
134      position += count + 1;
135      count = 0;
136      FREE(name);
137    }
138    else {
139      count++;
140    }
141    i++;
142  }
143  name = ALLOC(char, count+1);
144  strncpy(name, path+position, count);
145  name[count] = '\0';
146  if((presentNode = Hrc_NodeFindChildByName(presentNode, name)) ==
147     NIL(Hrc_Node_t)) {
148    FREE(name);
149    return NIL(Hrc_Node_t);
150  }
151  FREE(name);
152  return presentNode;
153}
154
155/**Function********************************************************************
156
157  Synopsis    [Returns pointer to the actual variable corresponding to
158               a formal variable of a node.]
159
160  Description [The function tracks a formal variable up in the hierarchy
161               until that variable becomes an internal variable of a node.
162               While traversing the hierarchy upwards it does not go beyond
163               the specified reference node. If node is identical to reference
164               node, formalVar is returned. If any error occurs a NULL
165               pointer is returned]
166               
167  SideEffects []
168
169  SeeAlso     []
170
171******************************************************************************/
172Var_Variable_t *
173Hrc_VariableFindActualFromFormal(
174  Hrc_Node_t *node,
175  Var_Variable_t *formalVar,
176  Hrc_Node_t *referenceNode)
177{
178  int position = -1;
179  int i;
180  Var_Variable_t *var;
181  Hrc_Node_t *presentNode;
182  Var_Variable_t *presentVar;
183  char *varName;
184 
185  if(node == referenceNode) {
186    return formalVar;
187  }
188  else {
189    presentNode = node;
190    presentVar = formalVar;
191  }
192 
193  /* A variable at position i in formalInputs corresponds to a varible at
194     position i in actualInputs. The variables in actualInputs in a node
195     are actually formal variables (could be I/O or internal) of the parent
196     of the node. Given a formal variable and a node, search for the
197     variable in formalInputs and formalOutputs. If it is not present in
198     either then check if it is an internal variable of the node. If it is
199     present, get the corresponding variable from actualInputs or
200     actualOutputs as the case may be. Update presentVar to this variable
201     and presentNode to the parent of the node. Repeat the process until
202     presentVar is an internal variable of presentNode or presentNode
203     becomes the same as referenceNode. */
204
205  while(presentNode != referenceNode) {
206    Hrc_NodeForEachFormalInput(presentNode, i, var) {
207      if(var == presentVar) {
208        position = i;
209      }
210    }
211    if(position != -1) {
212      presentVar = array_fetch(Var_Variable_t *,
213                               presentNode->actualInputs, position);
214    }
215    else {
216      Hrc_NodeForEachFormalOutput(presentNode, i, var) {
217        if(var == presentVar) {
218          position = i;
219        }
220      }
221      if(position != -1) {
222        presentVar = array_fetch(Var_Variable_t *,
223                                 presentNode->actualOutputs, position);
224      }
225      else {
226        varName = Var_VariableReadName(presentVar);
227        if(st_is_member(presentNode->varTable, varName)) {
228          return presentVar;
229        }
230        else {
231          return NIL(Var_Variable_t);
232        }
233      }
234    }
235    presentNode = presentNode->parentNode;
236/* The following check is just to make sure that the function does not try
237   to access the parent of the root node. */
238    if(presentNode == NIL(Hrc_Node_t )) {
239      return NIL(Var_Variable_t);
240    }
241    position = -1;
242  }
243  return presentVar;
244}
245
246/**Function********************************************************************
247
248  Synopsis    [Returns an array of models being used in the hierarchy
249               below the current node.]
250
251  SideEffects []
252
253  SeeAlso     []
254
255******************************************************************************/
256array_t *
257Hrc_ManagerObtainComponentModels(
258  Hrc_Manager_t *manager)
259{
260  st_generator *gen;
261  char *modelName;
262  char *dummy;
263  Hrc_Model_t *model;
264  st_table *modelTable = st_init_table(strcmp, st_strhash);
265  array_t *modelArray = array_alloc(Hrc_Model_t *, 0);
266 
267  NodeObtainComponentModels(manager->currentNode, modelTable);
268  st_foreach_item(modelTable, gen, &modelName, &dummy) {
269    st_lookup(manager->modelTable, modelName, &model);
270    array_insert_last(Hrc_Model_t *, modelArray, model);
271  }
272  st_free_table(modelTable);
273  return modelArray;
274}
275
276/**Function********************************************************************
277 
278  Synopsis    [Returns the hierarchical name of a node.]
279 
280  Description [A pointer to a string containing the hierarchical name
281               is returned. The user is responsible for freeing this string.
282               If pathFlag is set to TRUE the name is found relative to the
283               current node otherwise the name is found relative to the
284               root node. The path name of root node relative to the root node
285               and the current node relative to the current node is "".
286               If there is any error NULL is returned. Note
287               that for each level of hierarchy that is traversed there is an
288               instance name and these are separated by ".".]
289
290  SideEffects []
291
292  SeeAlso     [Hrc_ManagerFindNodeByPathName()]
293
294******************************************************************************/
295char *
296Hrc_NodeFindHierarchicalName(
297  Hrc_Node_t *node,
298  boolean pathFlag)
299{
300  Hrc_Manager_t *manager = Hrc_NodeReadManager(node);
301  Hrc_Node_t *currentNode, *rootNode, *tempNode;
302  char *name;
303  char *parentName;
304  char *temp;
305
306  rootNode = Hrc_ManagerReadRootNode(manager);
307  currentNode = Hrc_ManagerReadCurrentNode(manager);
308 
309  if(pathFlag == FALSE) {
310    if(node == rootNode) {
311      name = util_strsav("");
312    }
313    else {
314      tempNode = node;
315      name = util_strsav(Hrc_NodeReadInstanceName(tempNode));
316      while((tempNode = Hrc_NodeReadParentNode(tempNode)) != rootNode) {
317        parentName = util_strsav(Hrc_NodeReadInstanceName(tempNode));
318        temp = util_strcat3(parentName, ".", name);
319        FREE(parentName);
320        FREE(name);
321        name = temp;     
322      }
323    }
324  }
325  else {
326    if(node == currentNode) {
327    name = util_strsav("");
328    }
329    else {
330      tempNode = node;
331      name = util_strsav(Hrc_NodeReadInstanceName(tempNode));
332      if(tempNode == rootNode) {
333        /* return NULL. In this case, the function is being asked to find the
334           pathname of root node relative to the current node, when the
335           current node is not the root node */
336        FREE(name);
337        return NIL(char);
338      }
339      while((tempNode = Hrc_NodeReadParentNode(tempNode)) != currentNode) {
340        if(tempNode == rootNode) {
341          FREE(name);
342          return NIL(char);
343        }
344        parentName = util_strsav(Hrc_NodeReadInstanceName(tempNode));
345        temp = util_strcat3(parentName, ".", name);
346        FREE(parentName);
347        FREE(name);
348        name = temp;     
349      }
350    }
351  }
352  return name;
353}
354
355/**Function********************************************************************
356
357  Synopsis    [Returns pointer to a hash table from global path name of a
358               formal variable to actual variable]
359
360  Description [The hash table returned is from the global path name of a
361               formal variable to the global path name of its corresponding
362               actual variable. While traversing up the hierarchy, the
363               function will not go beyond rootNode.]
364
365  SideEffects [None]
366
367  SeeAlso     [optional]
368
369******************************************************************************/
370/*st_table *
371Hrc_TableCreateFormalToActual(
372  Hrc_Node_t *rootNode)
373{
374}*/
375
376
377/**Function********************************************************************
378
379  Synopsis    [Replaces a sub-tree in the hierarchy with a another tree.]
380             
381  Description [The function replaces a sub-tree in the hierarchy whose root
382               is oldNode by another tree whose root node is specified by
383               newNode. It is illegal for newNode to be NULL. If oldNode is
384               NULL, the tree hanging from newNode is freed recursively and
385               TRUE is returned. Otherwise, it is checked whether newNode is
386               a part of the existing hierarchy. If it is, FALSE is returned
387               and nothing is done. If it is not, oldNode is replaced
388               by newNode in the hierarchy and TRUE is returned. To effect the
389               replacement, the applInfoTable of newNode is freed and a copy
390               of applInfoTable of oldNode is stored in its place.
391               Then changeFn is called for each entry in the table.
392               The hierarchy is traversed towards the root node
393               starting from the parent of oldNode. At each step, a new model
394               is created and registered with the hierarchy manager. The new
395               model names are obtained by appending a '~' to the name of the
396               model which was modified. Finally, oldNode is freed
397               recursively.]
398
399  SideEffects [The hierarchy tree is modified and new models are added.]
400
401  SeeAlso     []
402
403******************************************************************************/
404boolean
405Hrc_TreeReplace(
406  Hrc_Node_t *oldNode,
407  Hrc_Node_t *newNode)
408{
409  Hrc_Node_t *tempNode, *presentNode;
410  char *newName, *instanceName;
411  char *newInstanceName;
412  int i, num, index;
413  Hrc_Model_t *prevOldModel, *prevNewModel;
414  Hrc_Model_t *oldModel, *newModel;
415  Hrc_Model_t *calleeModel;
416  Hrc_Subckt_t *subckt;
417  st_table *varToDupVar;
418  Tbl_Table_t *table, *dupTable;
419  Var_Variable_t *var, *dupVar;
420  char *name, *dupName;
421  st_generator *gen;
422  Hrc_Latch_t *latch, *dupLatch;
423  array_t *newActualInputVars, *newActualOutputVars;
424  char *key;
425  ApplInfo_t *applInfo;
426 
427  /* It is illegal to pass NULL as newNode. */
428  assert(newNode != NIL(Hrc_Node_t));
429 
430  if(oldNode == NIL(Hrc_Node_t)) {
431    HrcNodeFreeRecursively(newNode);
432    return TRUE;
433  }
434 
435  if(Hrc_NodeTestIsInTree(newNode, oldNode->manager->rootNode)) {
436    return FALSE;
437  }
438
439  /* free applInfo strutures all the way to the root since
440     flattened networks get invalidated with this tree-replace. */
441  presentNode = oldNode;
442  while(presentNode != NIL(Hrc_Node_t)) {
443    st_foreach_item(presentNode->applInfoTable, gen, &key, &applInfo) {
444      (*applInfo->freeFn)(applInfo->data);
445      FREE(key);
446      FREE(applInfo);
447    }
448    st_free_table(presentNode->applInfoTable);
449    presentNode->applInfoTable = st_init_table(strcmp, st_strhash);
450    presentNode = Hrc_NodeReadParentNode(presentNode);
451  }
452
453  /* If oldNode is the root node of the hierarchy, simply set the root node
454     and current node of the hierarchy to newNode. */
455
456  if(oldNode->parentNode == NIL(Hrc_Node_t)) {
457    Hrc_ManagerSetRootNode(oldNode->manager, newNode);
458    Hrc_ManagerSetCurrentNode(oldNode->manager, newNode);
459  }
460  else {
461    /* First, remove the connection between oldNode and its parent and
462       establish connection between newNode and oldNode's parent. */
463    tempNode = HrcNodeDeleteChild(oldNode->parentNode, oldNode->instanceName);
464    assert(oldNode == tempNode);
465    FREE(newNode->instanceName);
466    newNode->instanceName = util_strsav(oldNode->instanceName);
467    newNode->parentNode = oldNode->parentNode;
468    st_insert(newNode->parentNode->childTable, newNode->instanceName,
469              (char *) newNode);
470    newNode->actualInputs = array_dup(oldNode->actualInputs);
471    newNode->actualOutputs = array_dup(oldNode->actualOutputs);
472
473    /* Starting from the parent of oldNode (now the parent of newNode), go
474       up the hierarchy and at each node generate a new model by modifying
475       the model corresponding to the node appropriately. The new model name
476       is obtained from the old one by appending a '~' to it. The model names
477       in the nodes traversed have to be modified.
478       
479       The three variables newInstanceName, prevOldModel and prevNewModel
480       keep information needed to generate new models by modifying already
481       existing ones. */
482    newInstanceName = newNode->instanceName;
483    presentNode = newNode->parentNode;
484    st_lookup(presentNode->manager->modelTable, oldNode->modelName,
485              &prevOldModel);
486    st_lookup(presentNode->manager->modelTable, newNode->modelName,
487              &prevNewModel);
488    while(presentNode != NIL(Hrc_Node_t)) {
489      oldModel = Hrc_ManagerFindModelByName(presentNode->manager,
490                                            presentNode->modelName);
491      newName = ALLOC(char, strlen(presentNode->modelName) + 2);
492      strcpy(newName, presentNode->modelName);
493      strcat(newName, "~");
494      FREE(presentNode->modelName);
495      presentNode->modelName = newName;
496
497      /* Allocate a new model and fill up its fields by copying and
498         modifying appropriately the fields from the old model */
499      newModel = Hrc_ModelAlloc(presentNode->manager, presentNode->modelName);
500
501      /* Fill in the entries of the master node of newModel. I couldn't
502         use Hrc_NodeDup() to duplicate the master node of the oldModel here
503         because that function does some other things too. All the variables
504         of the masterNode of oldModel are duplicated. Note that masterNode
505         and the nodes in the hierarchy corresponding to the model do not
506         share variables. */
507
508      varToDupVar = st_init_table(st_ptrcmp, st_ptrhash);
509      Hrc_NodeForEachVariable(oldModel->masterNode, gen, name, var) {
510        dupVar = Var_VariableDup(var, newModel->masterNode);
511        dupName = Var_VariableReadName(dupVar);
512        st_insert(newModel->masterNode->varTable, dupName, dupVar);
513        st_insert(varToDupVar, var, dupVar);
514      }
515      Hrc_NodeForEachFormalInput(oldModel->masterNode, i, var) {
516        st_lookup(varToDupVar, var, &dupVar);
517        array_insert_last(Var_Variable_t *,
518                          newModel->masterNode->formalInputs, dupVar);
519      }
520      Hrc_NodeForEachFormalOutput(oldModel->masterNode, i, var) {
521        st_lookup(varToDupVar, var, &dupVar);
522        array_insert_last(Var_Variable_t *,
523                          newModel->masterNode->formalOutputs, dupVar);
524      }
525      Hrc_NodeForEachNameTable(oldModel->masterNode, i, table) {
526        dupTable = Tbl_TableSoftDup(table);
527        Tbl_TableForEachInputVar(dupTable, index, var) {
528          st_lookup(varToDupVar, var, &dupVar);
529          Tbl_TableSubstituteVar(dupTable, var, dupVar);
530        }
531        Tbl_TableForEachOutputVar(dupTable, index, var) {
532          st_lookup(varToDupVar, var, &dupVar);
533          Tbl_TableSubstituteVar(dupTable, var, dupVar);
534        }
535        array_insert_last(Tbl_Table_t *, newModel->masterNode->nameTables,
536                          dupTable);
537      }
538      Hrc_NodeForEachLatch(oldModel->masterNode, gen, name, latch) {
539        dupLatch = ALLOC(Hrc_Latch_t, 1);
540        st_lookup(varToDupVar, latch->latchInput, &(dupLatch->latchInput));
541        st_lookup(varToDupVar, latch->latchOutput, &(dupLatch->latchOutput));
542        dupLatch->resetTable = Tbl_TableSoftDup(latch->resetTable);
543        Tbl_TableForEachInputVar(dupLatch->resetTable, index, var) {
544          st_lookup(varToDupVar, var, &dupVar);
545          Tbl_TableSubstituteVar(dupLatch->resetTable, var, dupVar);
546        }
547        Tbl_TableForEachOutputVar(dupLatch->resetTable, index, var) {
548          st_lookup(varToDupVar, var, &dupVar);
549          Tbl_TableSubstituteVar(dupLatch->resetTable, var, dupVar);
550        }
551        dupLatch->undef = latch->undef;
552        st_insert(newModel->masterNode->latchTable, Var_VariableReadName(dupLatch->latchOutput), dupLatch);
553      }
554
555      /* For each subckt entry in oldModel, add a corresponding entry to
556         newModel except for the entry corresponding to the modified child
557         of presentNode. This particular subckt is recognized by its
558         instanceName. */
559      Hrc_ModelForEachSubckt(oldModel, gen, name, subckt) {
560        if(!strcmp(subckt->instanceName, newInstanceName)) {
561          calleeModel = prevNewModel;
562        }
563        else {
564          calleeModel = subckt->model;
565        }
566        instanceName = subckt->instanceName;
567        newActualInputVars = array_alloc(Var_Variable_t *, 0);
568        num = array_n(subckt->actualInputVars);
569        for(i =0; i < num; ++i) {
570          var = array_fetch(Var_Variable_t *, subckt->actualInputVars, i);
571          st_lookup(varToDupVar, var, &dupVar);
572          array_insert_last(Var_Variable_t *, newActualInputVars, dupVar);
573        }
574        newActualOutputVars = array_alloc(Var_Variable_t *, 0);
575        num = array_n(subckt->actualOutputVars);
576        for(i =0; i < num; ++i) {
577          var = array_fetch(Var_Variable_t *, subckt->actualOutputVars, i);
578          st_lookup(varToDupVar, var, &dupVar);
579          array_insert_last(Var_Variable_t *, newActualOutputVars, dupVar);
580        }
581        Hrc_ModelAddSubckt(newModel, calleeModel, instanceName,
582                           newActualInputVars, newActualOutputVars);
583      }
584     
585      st_free_table(varToDupVar);
586     
587      newInstanceName = presentNode->instanceName;
588      /* Right now, I am not modifying the instance names. */
589      prevOldModel = oldModel;
590      prevNewModel = newModel;
591      presentNode = presentNode->parentNode;
592    }
593  }
594  HrcNodeFreeRecursively(oldNode);
595  return TRUE;
596}
597/**Function********************************************************************
598
599  Synopsis    [Checks whether node1 is part of the tree whose root is node2.]
600
601  Description [The function returns TRUE if node1 is part of the sub-tree
602               whose root is node2. Otherwise, it returns FALSE.]
603
604  SideEffects []
605
606  SeeAlso     [Hrc_TreeReplace()]
607
608******************************************************************************/
609boolean
610Hrc_NodeTestIsInTree(
611  Hrc_Node_t *node1,     
612  Hrc_Node_t *node2)     
613{
614/* node1 is the node whose membership is to be tested */
615/* node2 is the root of the tree which is to be searched */
616  st_generator *gen;
617  char *name;
618  Hrc_Node_t *childNode;
619 
620  if(node1 == node2) {
621    return TRUE;
622  }
623  else {
624    Hrc_NodeForEachChild(node2, gen, name, childNode) {
625      if(Hrc_NodeTestIsInTree(node1, childNode)) {
626        return TRUE;
627      }
628    }
629    return FALSE;
630  }
631}
632
633/**Function********************************************************************
634
635  Synopsis    [ Test whether a hnode is uninterpreted]
636
637  Description [ An uninterpreted node does not have tables, latches or
638                children. This type of  node is defined in BLIF-MV
639                as follows:
640                                   
641                syntax/example:
642                                                                 
643                .subckt f1 t1 a <= x c => z b <= y
644                                                                           
645                this represents an instance of the uninterpreted function
646                z = f1( x, y ).
647
648               
649                a <= b  denotes formal variable a and actual variable b.  Where
650                        a is a subckt input.
651
652                       
653                a => b  denotes formal variable a and actual variable b.  Where
654                        a is a subckt output.
655
656                All subckts, with the same model name, should have identical
657                formal parameters.
658               
659               Note:  previous .subckt syntax is still be supported. There is
660                      no model definition for uninterpreted subckt.
661                                ]
662
663  SideEffects []
664
665  SeeAlso     [Hrc_ModelTestIsUninterpreted]
666
667******************************************************************************/
668boolean
669Hrc_NodeTestIsUninterpreted(
670  Hrc_Node_t *node )
671
672{
673  if( st_count( Hrc_NodeReadLatchTable( node ) ) ||
674      array_n(  Hrc_NodeReadNameTables( node ) ) ||
675      st_count( Hrc_NodeReadChildTable( node ) ) ) return FALSE;
676
677  return TRUE;
678
679}
680
681
682/**Function********************************************************************
683
684  Synopsis    [Checks if  a model is uninterpreted.]
685
686  Description []
687
688  SideEffects []
689
690  SeeAlso     [Hrc_NodeTestIsUninterpreted]
691
692******************************************************************************/
693boolean
694Hrc_ModelTestIsUninterpreted(
695        Hrc_Model_t* model )
696
697{
698  Hrc_Node_t* node;
699
700  node = Hrc_ModelReadMasterNode( model );
701
702  if( st_count( Hrc_NodeReadLatchTable( node ) ) ||
703      array_n(  Hrc_NodeReadNameTables( node ) ) ||
704      st_count( Hrc_ModelReadSubcktTable( model ) ) ) return FALSE;
705 
706  return TRUE;
707}
708
709
710/**Function********************************************************************
711
712  Synopsis    [ Checks for the existence of an uninterpreted node in the
713                hierarchy below the parent.]
714
715  Description [ Determines if there is a child hnode below the parent
716                is uninterpreted.]
717
718  SideEffects []
719
720  SeeAlso     []
721
722******************************************************************************/
723boolean
724Hrc_NodeTestRecursivelyIsUninterpreted(
725        Hrc_Node_t* parent )
726{
727  st_generator* gen;
728  char*         childName;
729  Hrc_Node_t*   child;
730 
731  if( Hrc_NodeTestIsUninterpreted( parent )) return TRUE;
732 
733  Hrc_NodeForEachChild( parent, gen, childName, child) {
734
735    if( Hrc_NodeTestRecursivelyIsUninterpreted( child ) ) return TRUE;
736
737  }
738
739  return FALSE;
740
741}
742
743
744/**Function********************************************************************
745
746  Synopsis    [ Checks for an uninterpreted node in hierarchy.]
747
748  Description [ Determines if there is a node in the hierarchy that is
749                uninterpreted.]
750
751  SideEffects []
752
753  SeeAlso     []
754
755*****************************************************************************/
756boolean
757Hrc_NodeTestIsUninterpretedNodeInHierarchy(
758  Hrc_Manager_t* hmgr )
759
760{
761
762  return Hrc_NodeTestRecursivelyIsUninterpreted( Hrc_ManagerReadRootNode( hmgr ) );
763
764}
765
766
767/**Function********************************************************************
768
769  Synopsis    [Returns 1 if all the variables of a given node are consistent.
770  Otherwise 0 is returned.]
771
772  Description [Checks if all the variables in a given node are consistent
773  in terms of labeling of six attributes (PI,PO,PS,NS,SI,SO) and the
774  numFanoutTables field. Returns 1 if consistent. Otherwise 0 is returned.
775  The function can be used for a sanity check after restructuring the hrc
776  data structure.]
777
778  SideEffects [None]
779
780  SeeAlso     []
781
782******************************************************************************/
783boolean
784Hrc_NodeCheckVariableConsistency(
785  Hrc_Node_t *node)
786{
787  boolean success = TRUE;
788  int i, j;
789  st_generator *gen;
790  Var_Variable_t *var;
791  Hrc_Latch_t *latch;
792  char *latchName, *varName;
793  st_table *varToNumFanoutTables;
794  Tbl_Table_t *table;
795  long num;
796
797  Hrc_NodeForEachFormalInput(node,i,var){
798    if (Var_VariableTestIsPI(var) == 0){
799      fprintf(vis_stderr, "Input variable %s is not labeled as PI.\n",
800        Var_VariableReadName(var));
801      success = FALSE;
802    }
803  }
804  Hrc_NodeForEachFormalOutput(node,i,var){
805    if (Var_VariableTestIsPO(var) == 0){
806      fprintf(vis_stderr, "Output variable %s is not labeled as PO.\n",
807        Var_VariableReadName(var));
808      success = FALSE;
809    }
810  }
811  /* if the node is not the root node, check consistency of actual variables */
812  if (Hrc_NodeReadParentNode(node) != NIL(Hrc_Node_t)){
813    Hrc_NodeForEachActualInput(node,i,var){
814      if (Var_VariableTestIsSI(var) == 0){
815        fprintf(vis_stderr, "Subcircuit input variable %s is not labeled as SI.\n",
816          Var_VariableReadName(var));
817        success = FALSE;
818      }
819    }
820    Hrc_NodeForEachActualOutput(node,i,var){
821      if (Var_VariableTestIsSO(var) == 0){
822        fprintf(vis_stderr, "Subcircuit output variable %s is not labeled as SO.\n",
823          Var_VariableReadName(var));
824        success = FALSE;
825      }
826    }
827  }
828
829  Hrc_NodeForEachLatch(node,gen,latchName,latch){
830    var = Hrc_LatchReadOutput(latch);
831    if (Var_VariableTestIsPS(var) == 0){
832      fprintf(vis_stderr, "Latch output variable %s is not labeled as PS.\n",
833        Var_VariableReadName(var));
834      success = FALSE;
835    }
836    var = Hrc_LatchReadInput(latch);
837    if (Var_VariableTestIsNS(var) == 0){
838      fprintf(vis_stderr, "Latch input variable %s is not labeled as NS.\n",
839        Var_VariableReadName(var));
840      success = FALSE;
841    }
842  }
843
844  varToNumFanoutTables = st_init_table(st_ptrcmp,st_ptrhash);
845  Hrc_NodeForEachVariable(node,gen,varName,var){
846    if (Var_VariableTestTypeConsistency(var) == 0){
847      success = FALSE;
848    }
849    (void)st_insert(varToNumFanoutTables, (char *)var, (char *)((long)0));
850  }
851
852  Hrc_NodeForEachNameTable(node,i,table){
853    Tbl_TableForEachInputVar(table,j,var){
854      (void)st_lookup(varToNumFanoutTables,var,&num);
855      st_insert(varToNumFanoutTables,var,(char *) ++num);
856    } 
857  }
858
859  Hrc_NodeForEachVariable(node,gen,varName,var){
860    (void)st_lookup(varToNumFanoutTables,var,&num);
861    if (num != (long)Var_VariableReadNumFanoutTables(var)){
862      fprintf(vis_stderr,"numFanoutTables field of variable %s is inconsistent.  (True value = %d, Registered value = %d)\n", 
863        Var_VariableReadName(var), (int)num, Var_VariableReadNumFanoutTables(var));
864      success = FALSE;
865    }
866  }
867
868  st_free_table(varToNumFanoutTables);
869  return success;
870}
871
872/*---------------------------------------------------------------------------*/
873/* Definition of internal functions                                          */
874/*---------------------------------------------------------------------------*/
875
876
877/*---------------------------------------------------------------------------*/
878/* Definition of static functions                                            */
879/*---------------------------------------------------------------------------*/
880/**Function********************************************************************
881
882  Synopsis    [A recursive function which inserts the names of all models
883               used in the construction of a node into the hash table models.]
884
885  SideEffects []
886
887  SeeAlso     [Hrc_ManagerObtainComponentModels()]
888
889******************************************************************************/
890
891static void
892NodeObtainComponentModels(
893    Hrc_Node_t *node,
894    st_table *models)
895{
896    char *name;
897    Hrc_Node_t *child;
898    st_generator *gen;
899   
900    st_insert(models, node->modelName, (char *) 0);
901    Hrc_NodeForEachChild(node, gen, name, child){
902        NodeObtainComponentModels(child, models);
903    }
904}
Note: See TracBrowser for help on using the repository browser.