source: vis_dev/vis-2.3/src/hrc/hrcMemUtil.c @ 53

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

vis2.3

File size: 19.9 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [hrcMemUtil.c]
4
5  PackageName [hrc]
6
7  Synopsis    [This file deals with the memory utilities for the hrc package.]
8
9  Description []
10
11  SeeAlso     []
12
13  Author      [Shaz Qadeer]
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 "hrcInt.h"
37
38static char rcsid[] UNUSED = "$Id: hrcMemUtil.c,v 1.3 2005/04/16 04:23:47 fabio Exp $";
39
40/*---------------------------------------------------------------------------*/
41/* Constant declarations                                                     */
42/*---------------------------------------------------------------------------*/
43
44
45/*---------------------------------------------------------------------------*/
46/* Type declarations                                                         */
47/*---------------------------------------------------------------------------*/
48
49
50/*---------------------------------------------------------------------------*/
51/* Stucture declarations                                                     */
52/*---------------------------------------------------------------------------*/
53
54
55/*---------------------------------------------------------------------------*/
56/* Variable declarations                                                     */
57/*---------------------------------------------------------------------------*/
58
59
60/*---------------------------------------------------------------------------*/
61/* Macro declarations                                                        */
62/*---------------------------------------------------------------------------*/
63
64
65/**AutomaticStart*************************************************************/
66
67/*---------------------------------------------------------------------------*/
68/* Static function prototypes                                                */
69/*---------------------------------------------------------------------------*/
70
71static void ModelFree(Hrc_Model_t *model);
72static void SubcktFree(Hrc_Subckt_t *subckt);
73static void LatchFree(Hrc_Latch_t *latch);
74
75/**AutomaticEnd***************************************************************/
76
77
78/*---------------------------------------------------------------------------*/
79/* Definition of exported functions                                          */
80/*---------------------------------------------------------------------------*/
81/**Function********************************************************************
82
83  Synopsis    [Allocates a hierarchy manager.]
84
85  Description [The function allocates memory for a hierarchy manager. It
86               initializes the model table of the manager and sets rootNode
87               and currentNode to NULL.]
88
89  SideEffects []
90
91  SeeAlso     []
92******************************************************************************/
93Hrc_Manager_t *
94Hrc_ManagerAlloc(
95  void)
96{
97  Hrc_Manager_t *manager = ALLOC(Hrc_Manager_t, 1);
98 
99  manager->rootNode = NIL(Hrc_Node_t);
100  manager->currentNode = NIL(Hrc_Node_t);
101  manager->modelTable = st_init_table(strcmp, st_strhash);
102  return manager;
103}
104
105/**Function********************************************************************
106
107  Synopsis    [Allocates a model with a given name.]
108
109  Description [The function checks if a model by the name modelName already
110               exists. If it does NULL is returned otherwise memory for a
111               new model is allocated. A copy of modelName is made and stored
112               in the model. Therefore, the string modelName should be freed
113               by the user. The subcircuit table and the master node of the
114               model are initialized. The model is registered with the
115               manager.]
116
117  SideEffects []
118
119  SeeAlso     []
120******************************************************************************/
121Hrc_Model_t *
122Hrc_ModelAlloc(
123  Hrc_Manager_t *manager,
124  char *modelName)
125{
126  Hrc_Model_t *model;
127 
128  if(!st_is_member(manager->modelTable,modelName)){
129    model = ALLOC(Hrc_Model_t, 1);
130    model->modelName = util_strsav(modelName);
131    st_insert(manager->modelTable, model->modelName, (char *) model);
132    model->subcktTable = st_init_table(strcmp, st_strhash);
133    model->masterNode = Hrc_NodeAlloc(manager, model->modelName,
134                                      NIL(char), NIL(Hrc_Node_t));
135    return model;
136  }
137  else {
138    return NIL(Hrc_Model_t);
139  }
140}
141
142/**Function********************************************************************
143
144  Synopsis    [Allocates a node for a particular instantiation of a model.]
145
146  Description [The function allocates memory for a node and initializes all
147               the arrays and hash tables inside the node. Note that the user
148               must free the strings modelName and instanceName because
149               copies of these strings are made and stored. The undef field
150               is set to NULL.]
151
152  SideEffects []
153
154  SeeAlso     []
155
156******************************************************************************/
157Hrc_Node_t *
158Hrc_NodeAlloc(
159  Hrc_Manager_t *manager,
160  char *modelName,
161  char *instanceName,
162  Hrc_Node_t *parentNode)
163{
164  Hrc_Node_t *node = ALLOC(Hrc_Node_t, 1);
165  /* The manager field is needed only for allocating the parent node. For
166     allocating any other node in the hierarchy, the manager can be obtained
167     from the parent node. */
168  node->manager = manager;
169  node->modelName = util_strsav(modelName);
170  node->instanceName = util_strsav(instanceName);
171  node->parentNode = parentNode;
172  node->formalInputs = array_alloc(Var_Variable_t *, 0);
173  node->formalOutputs = array_alloc(Var_Variable_t *, 0);
174  /* The arrays actualInputs and actualOutputs do not need to be allocated
175     because 1) they are never needed for the master node of a model, and
176     2) they are written over whenever a new node is added to the hierarchy
177     by using Hrc_NodeAddChild() */
178  node->actualInputs = NIL(array_t);
179  node->actualOutputs = NIL(array_t);
180  node->nameTables = array_alloc(Tbl_Table_t *, 0);
181  node->childTable = st_init_table(strcmp, st_strhash);
182  node->latchTable = st_init_table(strcmp, st_strhash);
183  node->varTable = st_init_table(strcmp, st_strhash);
184  node->applInfoTable = st_init_table(strcmp, st_strhash);
185  node->undef = NIL(void);
186  return node;
187}
188
189/**Function********************************************************************
190
191  Synopsis    [Duplicates a node with a new instance name.]
192
193  Description [The function duplicates a node. The manager, parentNode,
194               and undef fields are simply copied into the duplicated
195               node. All the other fields viz. hash tables and arrays are
196               allocated anew. All the variables and tables are duplicated.
197               Note that actualInputs and actualOutputs are not copied. They
198               are initialized to NULL. The latches are also duplicated (the
199               reset table is duplicated and the undef field is copied). The
200               applInfoTable is duplicated along with its keys. The
201               user should free instanceName because it is copied.]
202
203  SideEffects []
204
205  SeeAlso     []
206
207******************************************************************************/
208Hrc_Node_t *
209Hrc_NodeDup(
210  Hrc_Node_t *node,
211  char *instanceName)
212{
213  Hrc_Node_t *dupNode = ALLOC(Hrc_Node_t, 1);
214  st_generator *gen;
215  int i, index;
216  Var_Variable_t *var, *dupVar;
217  Tbl_Table_t *table, *dupTable;
218  Hrc_Latch_t *latch, *dupLatch;
219  st_table *varToDupVar;
220  char *name, *dupName;
221  char *key, *dupKey;
222  ApplInfo_t *applInfo;
223 
224  dupNode->manager = node->manager;
225  dupNode->modelName = util_strsav(node->modelName);
226  dupNode->instanceName = util_strsav(instanceName);
227  dupNode->parentNode = node->parentNode;
228  dupNode->formalInputs = array_alloc(Var_Variable_t *, 0);
229  dupNode->formalOutputs = array_alloc(Var_Variable_t *, 0);
230  dupNode->actualInputs = NIL(array_t);
231  dupNode->actualOutputs = NIL(array_t);
232  /*
233  dupNode->actualInputs = array_alloc(Var_Variable_t *, 0);
234  Hrc_NodeForEachActualInput(node, i, var) {
235    dupVar = Var_VariableDup(var, dupNode);
236    array_insert_last(Var_Variable_t *, dupNode->actualInputs, dupVar);
237  }
238  dupNode->actualOutputs = array_alloc(Var_Variable_t *, 0);
239  Hrc_NodeForEachActualOutput(node, i, var) {
240    dupVar = Var_VariableDup(var, dupNode);
241    array_insert_last(Var_Variable_t *, dupNode->actualOutputs, dupVar);
242  }
243  */
244  dupNode->varTable = st_init_table(strcmp, st_strhash);
245  varToDupVar = st_init_table(st_ptrcmp, st_ptrhash);
246  Hrc_NodeForEachVariable(node, gen, name, var) {
247    dupVar = Var_VariableDup(var, dupNode);
248    dupName = Var_VariableReadName(dupVar);
249    st_insert(dupNode->varTable, dupName, dupVar);
250    st_insert(varToDupVar, var, dupVar);
251  }
252  Hrc_NodeForEachFormalInput(node, i, var) {
253    st_lookup(varToDupVar, var, &dupVar);
254    array_insert_last(Var_Variable_t *, dupNode->formalInputs, dupVar);
255  }
256  Hrc_NodeForEachFormalOutput(node, i, var) {
257    st_lookup(varToDupVar, var, &dupVar);
258    array_insert_last(Var_Variable_t *, dupNode->formalOutputs, dupVar);
259  }
260  dupNode->nameTables = array_alloc(Tbl_Table_t *, 0);
261  Hrc_NodeForEachNameTable(node, i, table) {
262    dupTable = Tbl_TableSoftDup(table);
263    /*dupTable = Tbl_TableHardDup(table);*/
264    Tbl_TableForEachInputVar(dupTable, index, var) {
265      st_lookup(varToDupVar, var, &dupVar);
266      Tbl_TableSubstituteVar(dupTable, var, dupVar);
267    }
268    Tbl_TableForEachOutputVar(dupTable, index, var) {
269      st_lookup(varToDupVar, var, &dupVar);
270      Tbl_TableSubstituteVar(dupTable, var, dupVar);
271    }
272    array_insert_last(Tbl_Table_t *, dupNode->nameTables, dupTable);
273  }
274  dupNode->latchTable = st_init_table(strcmp, st_strhash);
275  Hrc_NodeForEachLatch(node, gen, name, latch) {
276    dupLatch = ALLOC(Hrc_Latch_t, 1);
277    st_lookup(varToDupVar, latch->latchInput, &(dupLatch->latchInput));
278    st_lookup(varToDupVar, latch->latchOutput, &(dupLatch->latchOutput));
279    dupLatch->resetTable = Tbl_TableSoftDup(latch->resetTable);
280    /*dupLatch->resetTable = Tbl_TableHardDup(latch->resetTable);*/
281    Tbl_TableForEachInputVar(dupLatch->resetTable, index, var) {
282      st_lookup(varToDupVar, var, &dupVar);
283      Tbl_TableSubstituteVar(dupLatch->resetTable, var, dupVar);
284    }
285    Tbl_TableForEachOutputVar(dupLatch->resetTable, index, var) {
286      st_lookup(varToDupVar, var, &dupVar);
287      Tbl_TableSubstituteVar(dupLatch->resetTable, var, dupVar);
288    }
289    dupLatch->undef = latch->undef;
290    st_insert(dupNode->latchTable, Var_VariableReadName(dupLatch->latchOutput), dupLatch);
291  }
292  dupNode->childTable = st_copy(node->childTable);
293  dupNode->applInfoTable = st_init_table(strcmp, st_strhash);
294  st_foreach_item(node->applInfoTable, gen, &key, &applInfo) {
295    dupKey = util_strsav(key);
296    st_insert(dupNode->applInfoTable, dupKey, applInfo);
297  }
298  dupNode->undef = node->undef;
299  st_free_table(varToDupVar);
300  return dupNode;
301}
302
303   
304/**Function********************************************************************
305
306  Synopsis    [Creates a latch and registers it with a model.]
307
308  Description [The function looks up the latch in the hash table of latches
309               in the master node of model. If a latch with the same output
310               variable name is not present in the table memory for a new
311               latch is allocated. The resetTable and undef fields of the
312               latch are initialized to NULL and the latch is returned.
313               Otherwise, NULL is returned.]
314
315  SideEffects []
316
317  SeeAlso     []
318******************************************************************************/
319Hrc_Latch_t *
320Hrc_LatchCreate(
321  Hrc_Model_t *model,
322  Var_Variable_t *latchInput,
323  Var_Variable_t *latchOutput)
324{
325  Hrc_Latch_t *latch;
326  char *outputName = Var_VariableReadName(latchOutput);
327 
328  if(!st_is_member(model->masterNode->latchTable, outputName)) {
329    latch = ALLOC(Hrc_Latch_t, 1);
330    latch->latchInput = latchInput;
331    latch->latchOutput = latchOutput;
332    latch->resetTable = NIL(Tbl_Table_t);
333    latch->undef = NIL(void);
334    st_insert(model->masterNode->latchTable, outputName, (char *) latch);
335    return latch;
336  }
337  else {
338    return NIL(Hrc_Latch_t);
339  }
340}
341
342/**Function********************************************************************
343
344  Synopsis    [Frees a hierarchy manager.]
345
346  Description [The function frees every node in the hierarchy recursively
347               starting from the root node if it is not NULL. All models in
348               the model table are freed and model table itself is freed.]
349
350  SideEffects []
351
352  SeeAlso     []
353******************************************************************************/
354void
355Hrc_ManagerFree(
356  Hrc_Manager_t *manager)
357{
358  st_generator *gen;
359  char *name;
360  Hrc_Model_t *model;
361 
362  if(manager->rootNode != NIL(Hrc_Node_t)) {
363    HrcNodeFreeRecursively(manager->rootNode);
364  }
365  Hrc_ManagerForEachModel(manager, gen, name, model){
366    ModelFree(model);
367  }
368  st_free_table(manager->modelTable);
369  FREE(manager);
370}
371
372/**Function********************************************************************
373
374  Synopsis    [Deletes a model from the manager.]
375
376  Description [The function looks up the entry for model in the hash table
377               of models in the manager. If the entry is not found, FALSE is
378               returned otherwise it is removed, model is freed, and TRUE is
379               returned. Note that the corresponding master node is freed too.]
380
381  SideEffects []
382
383  SeeAlso     [ModelFree()]
384******************************************************************************/
385boolean
386Hrc_ModelDelete(
387  Hrc_Manager_t *manager,
388  char *modelName)
389{
390  Hrc_Model_t *model;
391 
392  if(st_delete(manager->modelTable, &(modelName), &model)) {
393    ModelFree(model);
394    return TRUE;
395  }
396  else {
397    return FALSE;
398  }
399}
400
401/*---------------------------------------------------------------------------*/
402/* Definition of internal functions                                          */
403/*---------------------------------------------------------------------------*/
404/**Function********************************************************************
405
406  Synopsis    [Frees a tree hanging from a node.]
407
408  Description [The subtree hanging down from node is freed recursively node
409               by node. In each node, all tables, latches and formal variables
410               are freed and the freeFn is called for all the entries in
411               applInfoTable.
412               The function also frees the memory allocated to the internal
413               fields of all the nodes it frees.]
414
415  SideEffects [The rootNode and currentNode fields in the hierarchy manager
416               are set to NULL if either of these are freed.]
417
418  SeeAlso     [HrcNodeFreeInternalMemory(), Hrc_TreeReplace()]
419
420******************************************************************************/
421void
422HrcNodeFreeRecursively(
423  Hrc_Node_t *node)
424{
425  st_generator *gen;
426  char *name;
427  Hrc_Node_t *childNode;
428 
429  if(node == node->manager->rootNode) {
430    node->manager->rootNode = NIL(Hrc_Node_t);
431  }
432  if(node == node->manager->currentNode) {
433    node->manager->currentNode = NIL(Hrc_Node_t);
434  }
435  HrcNodeFreeInternalMemory(node);
436  Hrc_NodeForEachChild(node, gen, name, childNode) {
437    HrcNodeFreeRecursively(childNode);
438  }
439  st_free_table(node->childTable);
440  FREE(node);
441}
442
443/**Function********************************************************************
444
445  Synopsis    [Frees the memory allocated to the internal fields of a node.]
446 
447  Description [The function frees  all tables, latches and formal variables
448               in the node. The keys in applInfoTable and the applInfoTable
449               itself are also freed.]
450
451  SideEffects []
452
453  SeeAlso     [HrcNodeFreeRecursively()]
454
455******************************************************************************/
456void
457HrcNodeFreeInternalMemory(
458  Hrc_Node_t *node)
459{
460  char *name;
461  st_generator *gen;
462  int i;
463  Tbl_Table_t *table;
464  Hrc_Latch_t *latch;
465  Var_Variable_t *var;
466  ApplInfo_t *applInfo;
467  char *key;
468 
469  FREE(node->modelName);
470  FREE(node->instanceName);
471  array_free(node->formalInputs);
472  array_free(node->formalOutputs);
473  /* In a master node of a model, actualInputs and actualOutputs are NULL.
474     That is why the following two checks are needed. */
475  if(node->actualInputs != NIL(array_t)) {
476    array_free(node->actualInputs);
477  }
478  if(node->actualOutputs != NIL(array_t)) {
479    array_free(node->actualOutputs);
480  }
481  Hrc_NodeForEachNameTable(node, i, table) {
482    Tbl_TableFree(table);
483  }
484  array_free(node->nameTables);
485  Hrc_NodeForEachLatch(node, gen, name, latch) {
486    LatchFree(latch);
487  }
488  st_free_table(node->latchTable);
489  Hrc_NodeForEachVariable(node, gen, name, var) {
490    Var_VariableFree(var);
491  }
492  st_free_table(node->varTable);
493  if(node->applInfoTable) {
494    st_foreach_item(node->applInfoTable, gen, &key, &applInfo) {
495      FREE(key);
496      (*applInfo->freeFn)(applInfo->data);
497      FREE(applInfo);
498    }
499    st_free_table(node->applInfoTable);
500  }
501}
502
503
504/*---------------------------------------------------------------------------*/
505/* Definition of static functions                                            */
506/*---------------------------------------------------------------------------*/
507/**Function********************************************************************
508
509  Synopsis    [Frees the memory allocated to a model and its master node.]
510
511  Description [The function frees model. It also frees the master node
512               and all the sub-circuits of the model.]
513               
514
515  SideEffects []
516
517  SeeAlso     [Hrc_ModelDelete(), Hrc_ManagerFree()]
518
519******************************************************************************/
520static void
521ModelFree(
522  Hrc_Model_t *model)
523{
524  st_generator *gen;
525  char *name;
526  Hrc_Subckt_t *subckt;
527 
528  FREE(model->modelName);
529  HrcNodeFreeInternalMemory(model->masterNode);
530  st_free_table(model->masterNode->childTable);
531  FREE(model->masterNode);
532  st_foreach_item(model->subcktTable, gen, &name, &subckt) {
533    SubcktFree(subckt);
534  }
535  st_free_table(model->subcktTable);
536  FREE(model);
537}
538
539/**Function********************************************************************
540
541  Synopsis    [Frees a sub-circuit.]
542
543  Description [This function frees a sub-circuit. Note that all the variables
544              inside a sub-circuit are freed.]
545
546  SideEffects []
547
548  SeeAlso     [ModelFree()]
549
550******************************************************************************/
551static void
552SubcktFree(
553  Hrc_Subckt_t *subckt)
554{
555  FREE(subckt->instanceName);
556  array_free(subckt->actualInputVars);
557  array_free(subckt->actualOutputVars);
558  FREE(subckt);
559}
560
561/**Function********************************************************************
562
563  Synopsis    [Frees a latch.]
564
565  Description [The function frees the latch. If resetTable is not NULL, it
566               is freed. Note that the input and output variables of latch
567               are not freed.]
568
569  SideEffects []
570
571  SeeAlso     [HrcNodeFreeInternalMemory()]
572******************************************************************************/
573static void
574LatchFree(
575  Hrc_Latch_t *latch)
576{
577  if(latch->resetTable != NIL(Tbl_Table_t)){   
578    Tbl_TableFree(latch->resetTable);
579  }
580  FREE(latch);
581}       
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
Note: See TracBrowser for help on using the repository browser.