source: vis_dev/vis-2.3/src/sim/simUtil.c @ 23

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

vis2.3

File size: 17.6 KB
RevLine 
[14]1/**CFile***********************************************************************
2
3  FileName    [simUtil.c]
4
5  PackageName [sim]
6
7  Synopsis    [Basic useful functions for the sim package.]
8
9  Author      [Shaker Sarwary and Tom Shiple]
10
11  Copyright   [Copyright (c) 1994-1996 The Regents of the Univ. of California.
12  All rights reserved.
13
14  Permission is hereby granted, without written agreement and without license
15  or royalty fees, to use, copy, modify, and distribute this software and its
16  documentation for any purpose, provided that the above copyright notice and
17  the following two paragraphs appear in all copies of this software.
18
19  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
20  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
21  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
22  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
25  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
26  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
27  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
28  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
29
30******************************************************************************/
31
32#include "simInt.h"
33#include <sys/time.h>
34
35static char rcsid[] UNUSED = "$Id: simUtil.c,v 1.8 2005/04/26 19:10:09 jinh Exp $";
36
37/**AutomaticStart*************************************************************/
38
39/*---------------------------------------------------------------------------*/
40/* Static function prototypes                                                */
41/*---------------------------------------------------------------------------*/
42
43
44/**AutomaticEnd***************************************************************/
45
46
47/*---------------------------------------------------------------------------*/
48/* Definition of exported functions                                          */
49/*---------------------------------------------------------------------------*/
50
51/**Function********************************************************************
52
53  Synopsis [Builds a table mapping a node to a Mvf_Function.]
54
55  Description [Builds a table mapping a node to a Mvf_Function. nodesArray
56  should contain every nodes for which a Mvf_Function is requested. Returns an
57  empty table if nodesArray doesn't contain any node.]
58
59  SideEffects []
60
61******************************************************************************/
62st_table *
63Sim_NetworkBuildNodeToMvfTable(
64  Ntk_Network_t *network,
65  array_t       *nodesArray,
66  int            internalPartitionHead,
67  int            nextStateHead)
68{
69  array_t   *rootsName;
70  array_t   *leavesMddId;
71  array_t   *mvfArray;
72  st_table  *nodeToMvfTable;
73
74  SimNodesArrayBuildRootsAndLeaves(network, nodesArray, internalPartitionHead, nextStateHead, &rootsName, &leavesMddId);
75  mvfArray = Part_PartitionBuildFunctions(Part_NetworkReadPartition(network),
76                                          rootsName, leavesMddId, NIL(mdd_t));
77
78  array_free(leavesMddId);
79  array_free(rootsName);
80  nodeToMvfTable = SimNodesArrayBuildNodeToMvfTable(nodesArray, internalPartitionHead, mvfArray);
81  array_free(mvfArray);
82  return(nodeToMvfTable);
83}
84
85/*---------------------------------------------------------------------------*/
86/* Definition of internal functions                                          */
87/*---------------------------------------------------------------------------*/
88 
89/**Function********************************************************************
90
91  Synopsis    [Returns the integer code of the value of a variable associated
92  to a node.]
93
94  Description [Returns the integer code of the value of a variable associated
95  to a node. If the value does not belong to the domain of the variable, then
96  -1 is returned. It is an error to call this function with a NULL node.]
97
98  SideEffects []
99
100******************************************************************************/
101int
102SimNodeReadValueCode(
103  Ntk_Node_t * node,
104  char       * value)
105{
106  int             index;
107  Var_Variable_t *var = Ntk_NodeReadVariable(node);
108
109  if (Var_VariableTestIsSymbolic(var)) {
110    return(Var_VariableReadIndexFromSymbolicValue(var, value));
111  }
112
113  /* Enumerative or binary variable */
114  else {
115    index = atoi(value);
116    if (index >= Var_VariableReadNumValues(var) || index < 0) {
117      return(-1);
118    }
119    else {
120      return(index);
121    }
122  }
123}
124
125/**Function********************************************************************
126
127  Synopsis [Tests if the partition is in terms of CIs alone, in case internal
128  partition nodes are present.]
129
130  Description [ Returns 1 if internal nodes are present and the partition is in
131  terms of only combinational inputs (and constants)]
132
133  SideEffects []
134
135******************************************************************************/
136boolean
137SimTestPartInTermsOfCI(
138  Sim_Sim_t *sim
139  )
140{
141  int j, k, value, mddId;
142  Ntk_Node_t *node, *supportNode;
143  Mvf_Function_t *mvFunction;
144  array_t *mddIdArray;
145 
146  /* if there are no internal nodes, return FALSE. This allows
147     simulation to proceed when partition method inout is used.
148     */
149  if(sim->internalPartitionHead == sim->nextStateHead){
150    return FALSE;
151  }
152 
153  for (j = sim->nextStateHead; j < array_n(sim->nodesArray); j++) {
154    node =  array_fetch(Ntk_Node_t *, sim->nodesArray, j);
155    (void) st_lookup(sim->nodeToMvfTable, (char *) node, &mvFunction); 
156    mddIdArray = Mvf_FunctionComputeSupport(mvFunction,
157                            Ntk_NetworkReadMddManager(sim->network), &value);
158    if(mddIdArray != NIL(array_t)){
159      for(k = 0; k < array_n(mddIdArray); k++){
160        mddId = array_fetch(int, mddIdArray, k);
161        supportNode = Ntk_NetworkFindNodeByMddId(sim->network, mddId);
162        if(!Ntk_NodeTestIsCombInput(supportNode)){
163          array_free(mddIdArray);
164          return FALSE;
165        }
166      }
167      array_free(mddIdArray);
168    }/* if array not nil */
169  }/* for all nodes */
170 
171  return TRUE;
172}
173
174/**Function********************************************************************
175
176  Synopsis    [Converts integer to string of ASCII characters.]
177
178  Description [Converts integer to string of ASCII characters. It is the
179  responsibility of the user to free the returned string.]
180
181  SideEffects []
182
183******************************************************************************/
184char *
185SimInteger2ASCII(
186  int  number)
187{
188  char * str = ALLOC(char, 21);
189
190  (void) sprintf(str, "%d", number);
191  return(str);
192}
193 
194
195/**Function********************************************************************
196
197  Synopsis    [Print a string according to a given format.]
198
199  Description [Print a string according to a given format. The output file
200  must be valid. The string is formated according to len. If len > strlen(string),
201  then blanks are added]
202
203  SideEffects []
204
205******************************************************************************/
206void
207SimStringPrint(
208  FILE * fp,
209  char * string,
210  int  len)
211{
212  int i;
213 
214  fprintf(fp, "%s", string);
215  for(i = strlen(string); i < len; i++) {
216    fprintf(fp, " ");
217  }
218  fprintf(fp, " ");
219}
220 
221/**Function********************************************************************
222
223  Synopsis    [Returns an integer array that will contain the size of the
224  largest value of a node in the nodesArray.]
225
226  Description [Returns an integer array that will contain the size of the
227  largest value of a node in the nodesArray. It is the responsibility of the
228  user to free the returned array.]
229
230  SideEffects []
231
232******************************************************************************/
233array_t *
234SimSimInitDataFormat(
235  Sim_Sim_t * sim)
236{
237  int           i, j;
238  int           size;
239  int           maxSize;
240  int           numValue;
241  boolean       symbolic;
242  Ntk_Node_t   *node;
243  Var_Variable_t *var;
244  array_t      *formatArray = array_alloc(int, 0);
245 
246  for (j = 0; j < array_n(sim->nodesArray); j++) {
247    node     = array_fetch(Ntk_Node_t *, sim->nodesArray, j);
248    var      = Ntk_NodeReadVariable(node);
249    symbolic = Var_VariableTestIsSymbolic(var);
250    numValue = Var_VariableReadNumValues(var);
251    maxSize = 0;
252    if (symbolic) {
253      for (i = 0; i < numValue; i++) {
254        size = strlen(Var_VariableReadSymbolicValueFromIndex(var, i));
255        if (size > maxSize) {
256          maxSize = size;
257        }
258      }
259    }
260    else { /* Binary or enumertive type */
261      while(numValue != 0) {
262        maxSize++;
263        numValue = numValue/10;
264      }
265    }
266    array_insert_last(int, formatArray, maxSize);
267  }
268  return(formatArray);
269}
270
271/**Function********************************************************************
272
273  Synopsis [Does a copy of the nextState values to the currentState of the
274  next simulation vector.]
275
276  Description [Does a copy of the nextState values to the currentState of the
277  next simulation vector. The current vector must contain the nextState
278  values. The next vector must not contain already a currentState value.]
279
280  SideEffects []
281
282******************************************************************************/
283void
284SimSimVectorFillCurrentState(
285  Sim_Sim_t * sim /* sim data-structure */,
286  int  n /* index of nextState in the vectorArray */)
287{
288  int          i;
289  array_t     *currentVector  = array_fetch(array_t *, sim->vectorArray, n-1);
290  array_t     *nextVector     = array_fetch(array_t *, sim->vectorArray, n);
291 
292  for (i = sim->nextStateHead; i < sim->outputHead; i++) {
293    /* We assume nextVector contains only the inputs : insert_last is convenient */
294    int value = array_fetch(int, currentVector, i);
295    array_insert_last(int, nextVector, value);
296  }
297}
298 
299/**Function********************************************************************
300
301  Synopsis [Returns a random value for a multi-valued variable.]
302
303  Description [Returns a random value for a multi-valued variable.  If the
304  node is of type pseudo-input, then 1) if pseudoInputSource is Sim_First_c,
305  then the first value of the first row is used, else 2) a random row of the
306  table is chosen, and within this row, a random value in the output entry is
307  chosen (this is not exactly random, because a value could appear in more
308  than one row). If the node in not a pseudo-input, then a random value from
309  the domain of the node's variable is chosen. The encoded value is returned.]
310
311  SideEffects []
312
313******************************************************************************/
314int
315SimNodeComputeRandomValue(
316  Ntk_Node_t * node,
317  Sim_PseudoSrc  pseudoInputSource)
318{
319  int value = 0; /* initialize so that lint doesn't complain */ 
320
321  if (Ntk_NodeTestIsPseudoInput(node)) {
322    Tbl_Entry_t *entry;
323    int          rowNum;
324    int          colNum;
325    int          rowChoice;
326    Tbl_Table_t *table     = Ntk_NodeReadTable(node);
327    int          outIndex  = Ntk_NodeReadOutputIndex(node);
328
329    /* Decide which row to take value from. */
330    if (pseudoInputSource == Sim_First_c) {
331      rowChoice = 0;
332    }
333    else {
334      int numRows = Tbl_TableReadNumRows(table);
335      rowChoice = ((int) util_random()) % numRows;
336    }
337   
338    Tbl_TableForEachOutputEntry(table, rowNum, colNum, entry) {
339      if ((colNum == outIndex) && (rowNum == rowChoice)) {
340        Tbl_Range_t *range;
341        lsGen        lsGen;
342        int          tempValue;
343        int          entryChoice;
344        int          i = 0;
345
346        /* We are now in rowChoice. Decide which value of entry to take. */
347        if (pseudoInputSource == Sim_First_c) {
348          entryChoice = 0;
349        }
350        else {
351          int numValues = Tbl_EntryReadNumValues(entry);
352          entryChoice = ((int) util_random()) % numValues;
353        }
354   
355        Tbl_EntryForEachValue(entry, tempValue, lsGen, range) {
356          if(entryChoice == i) {
357            value = tempValue;
358            /*
359             * We could break out of the two FOR loops to avoid unnecessary
360             * work. However, the inner loop has an lsGen that must be freed
361             * if the loop is broken early, and I couldn't get lsFinish to be
362             * called correctly.  Also, the table shouldn't be big to worry
363             * about it.
364             */
365          }
366          i++;
367        }
368      }
369    }
370  }
371  else {
372    Var_Variable_t *var = Ntk_NodeReadVariable(node);
373
374    value = ((int) util_random()) % Var_VariableReadNumValues(var);
375  }
376
377  return value;
378}
379
380
381/**Function********************************************************************
382
383  Synopsis    [Builds the mdd of a simulation vector.]
384
385  Description [Builds the mdd of a simulation vector from an array of
386  integers. The length of this array should be equal to the number of
387  combinational inputs in the sim structure. The ith integer of this array
388  gives the value of the ith node in the sim structure's nodesArray.]
389
390  SideEffects []
391
392******************************************************************************/
393mdd_t *
394SimSimVectorBuildMdd(
395  Sim_Sim_t * sim,
396  array_t * vector,
397  array_t * partitionVector)
398{
399  int            i;
400  int            value;
401  mdd_t         *mddMinterm;
402  Ntk_Node_t    *node;
403  mdd_t         *literalMdd;
404  mdd_t         *tmpMdd;
405  Ntk_Network_t *network = sim->network;
406  mdd_manager   *mddManager = Ntk_NetworkReadMddManager(network);
407
408  mddMinterm = mdd_one(mddManager);
409  for(i = 0; i < sim->internalPartitionHead; i++) { /* For every combinational input */
410
411    node     = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
412    value    = array_fetch(int, vector, i);
413
414    /* LiteralMdd will represent the mdd of  "Node-variable = value" */
415    literalMdd = mdd_eq_c(mddManager, Ntk_NodeReadMddId(node), value);
416    tmpMdd = mdd_and(literalMdd, mddMinterm, 1, 1);
417    mdd_free(mddMinterm);
418    mdd_free(literalMdd);
419    mddMinterm = tmpMdd;
420  }
421
422  for(i = 0; i < array_n(partitionVector); i++) { /* For every internal Partition node */
423
424    node     = array_fetch(Ntk_Node_t *, sim->nodesArray, i + sim->internalPartitionHead);
425    value    = array_fetch(int, partitionVector, i);
426
427    /* LiteralMdd will represent the mdd of  "Node-variable = value" */
428    literalMdd = mdd_eq_c(mddManager, Ntk_NodeReadMddId(node), value);
429    tmpMdd = mdd_and(literalMdd, mddMinterm, 1, 1);
430    mdd_free(mddMinterm);
431    mdd_free(literalMdd);
432    mddMinterm = tmpMdd;
433  }
434
435  return(mddMinterm);
436}
437
438/**Function********************************************************************
439
440  Synopsis    [Write an error message to error_string.]
441
442  Description [Write an error message to error_string. The message will be
443  written as ("%s%s%s", str1, str2, str3).]
444
445  SideEffects []
446
447******************************************************************************/
448void
449SimAppendErrorMsg(
450  char * str1,
451  char * str2,
452  char * str3)
453{
454  error_append(str1);
455  error_append(str2);
456  error_append(str3);
457}
458
459/**Function********************************************************************
460
461  Synopsis    [Returns a random value.]
462
463  Description [Returns a random value. Uses gettimeofday system function.]
464
465  SideEffects []
466
467******************************************************************************/
468int
469SimComputeRandomInteger(void)
470{
471  struct timeval tp;
472  struct timezone tzp;
473
474  if ((int) gettimeofday(&tp,&tzp) == -1) {
475    fprintf (vis_stderr, "sim : Error while calling gettimeofday.\n");
476    exit(-1);
477  }
478  return((int) (tp.tv_sec));
479}
480
481/**Function********************************************************************
482
483  Synopsis    [Builds an array of MddId of primary inputs, pseudo inputs, and
484  current states, and an array of name of next states and outputs.]
485
486  Description [Builds an array of MddId of leaves of a network : primary
487  inputs, pseudo inputs, and current states, and an array of name of roots:
488  next states and outputs. These arrays are returned through the parameteres
489  leaves and roots. We suppose that every primary inputs, pseudo inputs, and
490  current states has an MDD Id.]
491
492  SideEffects []
493
494******************************************************************************/
495void
496SimNodesArrayBuildRootsAndLeaves(
497  Ntk_Network_t *network,                               
498  array_t *  nodesArray,
499  int        internalPartitionHead,
500  int        nextStateHead,
501  array_t ** roots,
502  array_t ** leaves)
503{
504  int         i;
505  Ntk_Node_t *node;
506
507  *roots  = array_alloc(char *, 0);
508  *leaves = array_alloc(int, 0);
509
510  for(i = 0; i < nextStateHead; i++) {
511    node = array_fetch(Ntk_Node_t *, nodesArray, i);
512    array_insert_last(int, *leaves, Ntk_NodeReadMddId(node));
513  }
514
515  for(i = internalPartitionHead; i < array_n(nodesArray); i++) {
516    node = array_fetch(Ntk_Node_t *, nodesArray, i);
517    array_insert_last(char *, *roots, Ntk_NodeReadName(node));
518  }
519
520}
521
522/**Function********************************************************************
523
524  Synopsis [Builds a table mapping a node to its Mvf_Function.]
525
526  Description [Builds a table mapping a node to its Mvf_Function. mvfArray is
527  an array of Mvf_Function.]
528
529  SideEffects []
530
531******************************************************************************/
532st_table *
533SimNodesArrayBuildNodeToMvfTable(
534  array_t  * nodesArray,
535  int        internalPartitionHead,
536  array_t  * mvfArray)
537{
538  int         i;
539  Ntk_Node_t *node;
540  array_t    *mvf;
541  st_table   *nodeToMvfTable = st_init_table(st_ptrcmp, st_ptrhash);
542 
543  for(i = internalPartitionHead; i < array_n(nodesArray); i++) {
544    node = array_fetch(Ntk_Node_t *, nodesArray, i);
545    mvf  = array_fetch(Mvf_Function_t *, mvfArray, i - internalPartitionHead);
546    st_insert(nodeToMvfTable, (char *) node, (char *) mvf);
547  }
548  return(nodeToMvfTable);
549}
550
551/*---------------------------------------------------------------------------*/
552/* Definition of static functions                                            */
553/*---------------------------------------------------------------------------*/
554 
555 
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
Note: See TracBrowser for help on using the repository browser.