source: vis_dev/vis-2.3/src/sim/simMain.c @ 84

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

vis2.3

File size: 48.0 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [simMain.c]
4
5  PackageName [sim]
6
7  Synopsis    [simulation of a Network.]
8
9  Description [simulation of a Network. This file contains simulate command and
10  main simulation functions.]
11 
12  Author      [Shaker Sarwary, Tom Shiple and Rajeev Ranjan]
13
14  Copyright   [Copyright (c) 1994-1996 The Regents of the Univ. of California.
15  All rights reserved.
16
17  Permission is hereby granted, without written agreement and without license
18  or royalty fees, to use, copy, modify, and distribute this software and its
19  documentation for any purpose, provided that the above copyright notice and
20  the following two paragraphs appear in all copies of this software.
21
22  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
23  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
24  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
25  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
28  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
30  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
31  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
32
33******************************************************************************/
34#include "simInt.h"
35
36static char rcsid[] UNUSED = "$Id: simMain.c,v 1.19 2005/04/23 14:31:51 jinh Exp $";
37
38/**AutomaticStart*************************************************************/
39
40/*---------------------------------------------------------------------------*/
41/* Static function prototypes                                                */
42/*---------------------------------------------------------------------------*/
43
44static int CommandSimulate(Hrc_Manager_t ** hmgr, int argc, char ** argv);
45static int EvaluateBinaryFunction(mdd_t * functionMdd, mdd_t * vectorMdd);
46static int NodeLexCmp(const void *node1, const void *node2);
47static mdd_t * StatesMddFromVector(Sim_Sim_t * sim, mdd_manager *mddManager);
48static void GenerateInitState(Sim_Sim_t * sim, boolean random);
49
50/**AutomaticEnd***************************************************************/
51
52
53/*---------------------------------------------------------------------------*/
54/* Definition of exported functions                                          */
55/*---------------------------------------------------------------------------*/
56
57/**Function********************************************************************
58
59  Synopsis    [Initializes the sim package.]
60
61  SideEffects []
62
63  SeeAlso     [Sim_End]
64
65******************************************************************************/
66void
67Sim_Init(void)
68{
69  Cmd_CommandAdd("simulate", CommandSimulate, /* doesn't changes_network */ 0);
70}
71
72
73/**Function********************************************************************
74
75  Synopsis    [Ends the sim package.]
76
77  SideEffects []
78
79  SeeAlso     [Sim_Init]
80
81******************************************************************************/
82void
83Sim_End(void)
84{
85}
86
87/**Function********************************************************************
88
89  Synopsis    [Allocates and initializes the SimSimStruct struct.]
90
91  Description [Allocates and initializes the SimSimStruct struct. Internally,
92  sim deals with nodes of a network instead the name(string) of a variable,
93  and with integers representing the value of a variable instead the value as
94  a string. nodeToMvfTable provides MDDs of primary outputs and next-state
95  functions. External function is provided by sim package that builds
96  nodeToMvfTable from network and nodesArray. inputFile is the name of the file
97  containing the simulation vectors. lineNumber is the current line number
98  while parsing inputFile, it is used to print error messages. nodesArray is
99  an array of network nodes of every inputs, current and next state, and
100  partial outputs. Only outputs contained in nodesArray are
101  simulated. currentStateHead, nextStateHead, outputHead are the index of
102  first current state, next state, and output, in nodesArray. initState is an
103  array of values representing initial state according to the current state
104  order in nodesArray. vectorArray is an array of array of values representing
105  vectors to be simulated. if verbose is TRUE, then messages like begin of
106  simulation procedure and printing procedure as well as the cpu-time spent
107  while simulation are directed to vis_stdout.]
108
109  SideEffects []
110
111******************************************************************************/
112Sim_Sim_t *
113Sim_SimCreate(
114  Ntk_Network_t * network,
115  st_table      * nodeToMvfTable,
116  char          * inputFile,
117  int             lineNumber,
118  array_t       * nodesArray,
119  int             currentStateHead,
120  int             internalPartitionHead,
121  int             nextStateHead,
122  int             outputHead,
123  array_t       * initState,
124  array_t       * vectorArray,
125  boolean         verbose)
126{
127  Sim_Sim_t *sim         = ALLOC(Sim_Sim_t, 1);
128 
129  sim->network           = network;
130  sim->nodeToMvfTable    = nodeToMvfTable;
131  sim->inputFile         = inputFile;
132  sim->lineNumber        = lineNumber;
133  sim->nodesArray        = nodesArray;
134  sim->currentStateHead  = currentStateHead;
135  sim->internalPartitionHead  = internalPartitionHead,
136  sim->nextStateHead     = nextStateHead;
137  sim->outputHead        = outputHead;
138  sim->initState         = initState;
139  sim->vectorArray       = vectorArray;
140  sim->verbose           = verbose;
141 
142  return(sim);
143}
144
145/**Function********************************************************************
146
147  Synopsis    [Resets the sim structure.]
148
149  Description [Resets the sim structure. Frees the vectors, and makes it equal
150  to NULL. Sets also the initState as the nextState of last vector in
151  vectorArray. sim->vectorArray must be != NULL, and contain valid vectors.]
152
153  SideEffects []
154
155******************************************************************************/
156void
157Sim_SimReset(
158  Sim_Sim_t * sim)
159{
160  int       i, value;
161  array_t  *lastVector;
162
163  assert(sim->initState != NIL(array_t));
164 
165  /* Reset initState */
166
167  if (sim->initState != NIL(array_t)) {
168    array_free(sim->initState);
169  }
170 
171  sim->initState = array_alloc(int, 0);
172  lastVector = array_fetch_last(array_t *,sim->vectorArray);
173  for (i = sim->nextStateHead; i < sim->outputHead; i++) {
174    value = array_fetch(int, lastVector, i);
175    array_insert_last(int, sim->initState, value);
176  }
177
178  /* Free vectorArray */
179  for (i = 0; i < array_n(sim->vectorArray); i++) {/* Free Vectors */
180    array_t *vector = array_fetch(array_t *, sim->vectorArray, i);
181    array_free(vector);
182  }
183  array_free(sim->vectorArray);
184  sim->vectorArray = NIL(array_t);
185}
186
187/**Function********************************************************************
188
189  Synopsis    [Frees a sim Structure.]
190
191  SideEffects []
192
193******************************************************************************/
194void
195Sim_SimFree(
196  Sim_Sim_t * sim)
197{
198  int             i;
199  array_t        *vector;
200  Ntk_Node_t     *node;
201  Mvf_Function_t *mvFunction;
202  st_generator   *stGen;
203
204  if (sim->nodesArray != NULL) {
205    array_free(sim->nodesArray);
206  }
207  if (sim->initState != NIL(array_t)) {
208    array_free(sim->initState);
209  }
210
211  if (sim->vectorArray != NIL(array_t)) {
212    for (i = 0; i < array_n(sim->vectorArray); i++) {
213      vector = array_fetch(array_t *, sim->vectorArray, i);
214      array_free(vector);
215    }
216    array_free(sim->vectorArray);
217  }
218  if(sim->nodeToMvfTable != NIL(st_table)) {
219    st_foreach_item(sim->nodeToMvfTable, stGen, &node, &mvFunction) {
220      Mvf_FunctionFree(mvFunction);
221    }
222  }
223  st_free_table(sim->nodeToMvfTable);
224  FREE(sim);
225}
226
227/**Function********************************************************************
228
229  Synopsis    [Allocates and initializes an array of nodes of every input,
230  current-state, next-state, output.]
231
232  SideEffects []
233
234******************************************************************************/
235array_t *
236Sim_NetworkCreateNodesArray(
237  Ntk_Network_t * network,
238  int           * currentStateHead,
239  int           * internalPartitionHead,
240  int           * nextStateHead,
241  int           * outputHead)
242{
243  int            i;
244  lsGen          inputGen;
245  lsGen          latchGen;
246  lsGen          outputGen; 
247  Ntk_Node_t    *node;
248  array_t       *nodesArray = array_alloc(Ntk_Node_t *, 0);
249  graph_t       *partition;
250  vertex_t      *vertex;
251  array_t *dfsarray;
252
253  /* Input Nodes */
254
255  { 
256        array_t *tmpArray= array_alloc(Ntk_Node_t *, 0);
257    Ntk_NetworkForEachInput(network, inputGen, node) {
258          array_insert_last(Ntk_Node_t *, tmpArray, node);
259        }
260        array_sort(tmpArray, NodeLexCmp);
261        array_append(nodesArray, tmpArray);
262        array_free(tmpArray);
263  }
264 
265 
266  *currentStateHead = array_n(nodesArray);  /* Initialize currentStateHead */
267
268  /* Adding latches */
269 
270  {
271        array_t *tmpArray= array_alloc(Ntk_Node_t *, 0);
272    Ntk_NetworkForEachLatch(network, latchGen, node) {
273          array_insert_last(Ntk_Node_t *, tmpArray, node);
274        }
275        array_sort(tmpArray, NodeLexCmp);
276        array_append(nodesArray, tmpArray);
277        array_free(tmpArray);
278  }
279 
280  *internalPartitionHead = array_n(nodesArray);  /* Initialize internalPartitionHead */
281
282  /* Add internal partition nodes */
283
284  partition = Part_NetworkReadPartition(network);
285  dfsarray = g_dfs(partition);
286  for(i=0; i< array_n(dfsarray); i++){
287    vertex = array_fetch(vertex_t *, dfsarray, i);
288    node = Ntk_NetworkFindNodeByName(network, Part_VertexReadName(vertex));
289    if(!(Ntk_NodeTestIsCombInput(node) || Ntk_NodeTestIsCombOutput(node))){
290      array_insert_last(Ntk_Node_t *, nodesArray, node);
291    }
292  }
293  array_free(dfsarray);
294 
295  *nextStateHead = array_n(nodesArray);  /* Initialize nextStateHead */
296
297  /* Add data-input of latches as next state node */
298
299  for (i = *currentStateHead; i < *internalPartitionHead; i++) {
300    node = array_fetch(Ntk_Node_t *, nodesArray, i);
301    node = Ntk_LatchReadDataInput(node);
302    array_insert_last(Ntk_Node_t *, nodesArray, node);
303  }
304 
305  *outputHead = array_n(nodesArray);  /* Initialize outputHead */
306 
307         
308  /* Adding outputs */
309 
310  {
311        array_t *tmpArray= array_alloc(Ntk_Node_t *, 0);
312    Ntk_NetworkForEachPrimaryOutput(network, outputGen, node) {
313      array_insert_last(Ntk_Node_t *, tmpArray, node);
314        }
315        array_sort(tmpArray, NodeLexCmp);
316        array_append(nodesArray, tmpArray);
317        array_free(tmpArray);
318  }
319
320  return(nodesArray);
321} 
322
323/**Function********************************************************************
324
325  Synopsis    [Generates random simulation vectors.]
326
327  Description [Generates numberVector random simulation vectors.
328  sim->vectorArray is re-initialized by this function.  If sim->vectorArray
329  already contains vectors, they will be lost and cause a memory leak.]
330
331  SideEffects []
332
333******************************************************************************/
334void
335Sim_SimGenerateRandomVectors(
336  Sim_Sim_t    * sim,
337  int            numberVector,
338  Sim_PseudoSrc  pseudoInputSource)
339{
340  int            i;
341  int            j;
342  array_t       *vector;
343  array_t       *vectorArray = array_alloc(array_t *, 0);
344  array_t       *nodesArray  = sim->nodesArray;
345
346
347  /* Initialization with empty vectors */
348  for (j = 0; j < numberVector; j++) {
349    vector = array_alloc(int, 0);
350    array_insert_last(array_t *, vectorArray, vector);
351  } 
352
353  /* For every input node */
354  for (i = 0; i < sim->currentStateHead; i++) {
355    Ntk_Node_t *node = array_fetch(Ntk_Node_t *, nodesArray, i);
356
357    /* For every vector */
358    for (j = 0; j < numberVector; j++) {
359      int value = SimNodeComputeRandomValue(node, pseudoInputSource);
360     
361      vector = array_fetch(array_t *, vectorArray, j);
362      /* vector is empty => array_insert_last is convenient */
363      array_insert_last(int, vector, value);
364    }
365  }
366
367  sim->vectorArray = vectorArray;
368}
369
370/**Function********************************************************************
371
372  Synopsis    [Generates a random initial state.]
373
374  Description [Generates a random initial state, using the primary and pseudo
375  input values in the first input vector of the sim structure. sim->initState
376  is reset by this function.]
377
378  SideEffects []
379
380******************************************************************************/
381void
382Sim_SimGenerateRandomInitState(
383  Sim_Sim_t * sim)
384{
385  GenerateInitState(sim, TRUE);
386}
387
388
389/**Function********************************************************************
390
391  Synopsis    [Does a simulation on a sim structure.]
392
393  Description [Does a simulation on a sim structure. The sim structure must
394  previously be initialized by valid vectors. If vectors are not valid, bad
395  evaluations should be expected. There are two kinds of invalid vectors :
396  <p>
397  1- The vector is incomplete : f = a+b+c, and vector = not(a) (a = 0)
398  <p>
399  2- The vector is not in the domain of the function : F_red = a.b, F_blue =
400  a.c, vector = not(a).]
401 
402  SideEffects []
403
404******************************************************************************/
405void
406Sim_SimSimulate(
407  Sim_Sim_t * sim)
408{
409  Ntk_Node_t    *node;
410  array_t       *vector;
411  array_t       *partitionVector;
412  int            i, j;
413  int            value;
414  mdd_t         *vectorMdd;
415  int            numberVector = array_n(sim->vectorArray);
416 
417  if(sim->verbose) {
418    (void) fprintf(vis_stdout, "Simulating %d vectors ...\n", numberVector);
419    fflush(vis_stdout);
420  }
421
422  /* Initialization with initState */
423  SimSimInitializeCurrentState(sim);
424
425  /*
426  for (j = sim->internalPartitionHead; j < sim->nextStateHead; j++) {
427    node =  array_fetch(Ntk_Node_t *, sim->nodesArray, j);
428    fprintf(stdout, "%s \t", Ntk_NodeReadName(node));
429  }
430  if(sim->internalPartitionHead < sim->nextStateHead){
431    fprintf(stdout, "\n");
432  }
433  */
434 
435  for (i = 0; i < numberVector; i++) { /* For every vector */
436    if (i > 0) {         /* Put the current-state = last-next-state */
437      SimSimVectorFillCurrentState(sim, i);
438    }
439    else {
440      SimSimInitializeCurrentState(sim);
441    }
442
443    vector = array_fetch(array_t *, sim->vectorArray, i);
444
445    /* partitionVector represents the values of the internal nodes
446       of the partition, induced by the values of the vector array.
447    */
448
449    partitionVector = array_alloc(int, 0);
450   
451    /* simulate internal nodes first. As these internal nodes are
452       simulated, the vectorMdd is updated to reflect the newly computed
453       values
454    */
455
456    for (j = sim->internalPartitionHead; j < sim->nextStateHead; j++) {
457      vectorMdd = SimSimVectorBuildMdd(sim, vector, partitionVector);
458      node =  array_fetch(Ntk_Node_t *, sim->nodesArray, j);
459      value = Sim_nodeToMvfTableEvaluateNode(sim->nodeToMvfTable, node, vectorMdd);
460      array_insert(int, partitionVector, j - sim->internalPartitionHead, value);
461      mdd_free(vectorMdd);
462    }
463    /*
464    if(sim->internalPartitionHead < sim->nextStateHead){
465      fprintf(stdout, "\n");
466    }
467    */
468    /* simulate the rest of the nodes */
469    vectorMdd = SimSimVectorBuildMdd(sim, vector, partitionVector);
470    array_free(partitionVector);
471
472    for (j = sim->nextStateHead; j < array_n(sim->nodesArray); j++) {
473      node =  array_fetch(Ntk_Node_t *, sim->nodesArray, j);
474      value = Sim_nodeToMvfTableEvaluateNode(sim->nodeToMvfTable, node, vectorMdd);
475      array_insert(int, vector, j, value);
476    }
477
478    mdd_free(vectorMdd);
479  }
480}
481
482/**Function********************************************************************
483
484  Synopsis    [Evaluates the function of a node on a minterm.]
485
486  Description [Evaluates the function of a node on a minterm. This node must
487  have an entry in nodeToMvfTable. The node may represent a binary or
488  multi-valued function. The result is returned as an integer. If the node
489  represents a binary function, 0 or 1 will be returned.
490  <p>
491  NOTE : WE ASSUME THAT THE FUNCTION IS COMPLETELY SPECIFIED. WE ASSUME ALSO
492  THAT THE VECTOR IS "COMPLETE". AS A CONSEQUENCE, IF THE VECTOR IS NOT IN THE
493  ONSET OF ONE OF THE FIRST n-1 VALUES OF THE FUNCTION, THEN IT IS ASSUMED
494  THAT THE FUNCTION TAKES ITS LAST VALUE ON THIS VECTOR.]
495
496  SideEffects []
497
498  SeeAlso     [Sim_nodeToMvfTableEvaluateNodesArray]
499
500******************************************************************************/
501int
502Sim_nodeToMvfTableEvaluateNode(
503  st_table   * nodeToMvfTable,
504  Ntk_Node_t * node,
505  mdd_t      * vectorMdd)
506{
507  int             i;
508  Mvf_Function_t *mvFunction = NIL(Mvf_Function_t);
509
510  (void) st_lookup(nodeToMvfTable, (char *) node,  &mvFunction);
511
512  /*
513   * For a binary function the array contains 2 MDDs for off-set and
514   * on-set, with the indices 0 or 1.
515   */
516
517  for (i = 0; i < Mvf_FunctionReadNumComponents(mvFunction) - 1; i++) {
518    if (EvaluateBinaryFunction(Mvf_FunctionReadComponent(mvFunction, i),
519                               vectorMdd) == 1) {
520      return(i);
521    }
522  }
523  /* Return last value without evaluation */
524  return(i);
525}
526
527/**Function********************************************************************
528
529  Synopsis    [Evaluates every node of an array on a minterm.]
530
531  Description [Evaluates every node of an array on a minterm. The input values
532  are given by an MDD. Nodes, to be evaluated, must have an entry in
533  nodeToMvfTable. The nodes may represent a binary or multi-valued
534  function. The result is returned as an array of integers. If a node
535  represents a binary function, the integer is equal to either 0 or 1.
536  <p>
537  NOTE : WE ASSUME THAT THE FUNCTION IS COMPLETELY SPECIFIED. WE ASSUME ALSO
538  THAT THE VECTOR IS "COMPLETE". AS A CONSEQUENCE, IF THE VECTOR IS NOT IN THE
539  ONSET OF ONE OF THE FIRST n-1 VALUES OF THE FUNCTION, THEN IT IS ASSUMED
540  THAT THE FUNCTION TAKES ITS LAST VALUE ON THIS VECTOR.]
541
542  SideEffects []
543
544  SeeAlso     [Sim_nodeToMvfTableEvaluateNode]
545
546******************************************************************************/
547array_t *
548Sim_nodeToMvfTableEvaluateNodesArray(
549  st_table  * nodeToMvfTable,
550  array_t   * nodesArray,
551  mdd_t     * vectorMdd)
552{
553  int          i, value;
554  Ntk_Node_t  *node;
555  array_t     *resultArray = array_alloc(int, 0);
556
557  for (i = 0; i < array_n(nodesArray); i++) {
558    node  = array_fetch(Ntk_Node_t *, nodesArray, i);
559    value = Sim_nodeToMvfTableEvaluateNode(nodeToMvfTable, node, vectorMdd);
560    array_insert(int, resultArray, i, value);
561  }
562  return(resultArray);
563}
564 
565/**Function********************************************************************
566
567  Synopsis [Generates random vectors, performs simulation.]
568
569  Devscription [Generates num random vectors, performs
570  simulation. These vectors form only one thread of
571  simulation. Returns an mdd_t of simulated states.]
572 
573  SideEffects []
574
575******************************************************************************/
576mdd_t *
577Sim_RandomSimulate(
578  Ntk_Network_t * network,
579  int             num,
580  boolean         verbose)
581{
582  int        numRemainingVector;
583  st_table  *nodeToMvfTable;
584  Sim_Sim_t *sim;
585  int        currentStateHead    = 0;
586  int        internalPartitionHead    = 0;
587  int        nextStateHead       = 0; 
588  int        outputHead          = 0;
589  int firstTime = 1;
590  mdd_t *states, *simStates;
591  mdd_manager *mddManager = Ntk_NetworkReadMddManager(network);
592  Sim_PseudoSrc pseudoInputSource = Sim_Random_c;
593  array_t   *nodesArray          = Sim_NetworkCreateNodesArray(network,
594                                             &currentStateHead, &internalPartitionHead, 
595                                             &nextStateHead, &outputHead); 
596
597  /* Building nodeToMvfTable */
598  nodeToMvfTable = Sim_NetworkBuildNodeToMvfTable(network, nodesArray,
599                                                  internalPartitionHead,
600                                                  nextStateHead);
601   
602  sim = Sim_SimCreate(network, nodeToMvfTable, NULL, 0, nodesArray,
603                      currentStateHead, internalPartitionHead, nextStateHead, outputHead, 
604                      NULL, NULL, verbose);
605
606  /* If partition method was partial/boundary, and -i was used, then dont simulate*/
607  if(SimTestPartInTermsOfCI(sim)){
608    fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n");
609    fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n");
610    fprintf(stdout, "without the -i option and then re-run simulatate.\n");
611    Sim_SimFree(sim);
612    return(0);
613  }
614 
615  /* Simulation by packet */ 
616  simStates = mdd_zero(mddManager);
617  numRemainingVector = num;
618  do {
619    mdd_t *tmp;
620    /* Number of vectors to be simulated in current pass. */
621    num = (numRemainingVector > SIMPACKET_SIZE)
622        ? SIMPACKET_SIZE
623        :  numRemainingVector;
624
625    Sim_SimGenerateRandomVectors(sim, num, pseudoInputSource);
626
627    /*
628     * Random init state generation. This must follow generation of input
629     * vectors, because init state depends on inputs.
630     */
631    if (firstTime) {
632      GenerateInitState(sim, FALSE);
633    }
634   
635    /* SIMULATION */
636    Sim_SimSimulate(sim);
637   
638    /* Print simulation vectors. On first pass, file must be created. */
639    states = StatesMddFromVector(sim, mddManager);
640    tmp = mdd_or(states, simStates, 1, 1);
641    mdd_free(states);
642    mdd_free(simStates);
643    simStates = tmp;
644    firstTime = 0;
645   
646    /* Reset Vectors */
647    Sim_SimReset(sim);
648
649    numRemainingVector -= num;
650  } while(numRemainingVector > 0);
651
652  Sim_SimFree(sim);
653  return(simStates);
654} /* end of Sim_RandomSimulate */
655
656
657
658/*---------------------------------------------------------------------------*/
659/* Definition of internal functions                                          */
660/*---------------------------------------------------------------------------*/
661
662/**Function********************************************************************
663
664  Synopsis    [Sets the current state of the first vector in vectorArray using
665  initState.]
666
667  Description [Sets the current state of the first vector in vectorArray using
668  initState. vectorArray must contain already the inputs value(AND only the
669  inputs value). It is an error to call this function with a sim structure
670  that contains a wrong vectorArray or a wrong initState.]
671
672  SideEffects []
673
674******************************************************************************/
675void
676SimSimInitializeCurrentState(
677  Sim_Sim_t * sim)
678{
679  int       i, value;
680 
681  /* Get the first vector from vectorArray */
682  array_t  *vector = array_fetch(array_t *, sim->vectorArray, 0);
683 
684  for (i = 0; i < array_n(sim->initState); i++) {
685    value = array_fetch(int, sim->initState, i);
686    array_insert_last(int, vector, value);
687  }
688}
689
690/**Function********************************************************************
691
692  Synopsis [Generates random vectors, performs simulation, and prints the
693  result.]
694
695  Devscription [Generates num random vectors, performs simulation, and prints
696  the result. Returns 1 if function ends normally, else returns 0. If
697  statesPrint is 1, then current and next state are also printed, else it is
698  not. See Sim_SimInitialize for further information about arguments.]
699 
700  SideEffects []
701
702******************************************************************************/
703boolean
704SimRandomSimulateAndPrint(
705  Ntk_Network_t * network,
706  int             num,
707  char          * outputFile,
708  Sim_PseudoSrc   pseudoInputSource,
709  int             printInputsFlag,
710  int             printOutputsFlag,
711  int             printPseudoInputsFlag,
712  int             printStatesFlag,
713  boolean         verbose)
714{
715  int        numRemainingVector;
716  FILE      *outFile;
717  st_table  *nodeToMvfTable;
718  Sim_Sim_t *sim;
719  int        firstTime           = 1;
720  int        currentStateHead    = 0;
721  int        internalPartitionHead    = 0;
722  int        nextStateHead       = 0; 
723  int        outputHead          = 0; 
724  array_t   *nodesArray          = Sim_NetworkCreateNodesArray(network,
725                                             &currentStateHead, &internalPartitionHead, 
726                                             &nextStateHead, &outputHead); 
727
728  /* Building nodeToMvfTable */
729  nodeToMvfTable = Sim_NetworkBuildNodeToMvfTable(network, nodesArray,
730                                                  internalPartitionHead,
731                                                  nextStateHead);
732   
733  sim = Sim_SimCreate(network, nodeToMvfTable, NULL, 0, nodesArray,
734                      currentStateHead, internalPartitionHead, nextStateHead, outputHead, 
735                      NULL, NULL, verbose);
736
737  /* If partition method was partial/boundary, and -i was used, then dont simulate*/
738  if(SimTestPartInTermsOfCI(sim)){
739    fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n");
740    fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n");
741    fprintf(stdout, "without the -i option and then re-run simulatate.\n");
742    Sim_SimFree(sim);
743    return(0);
744  }
745 
746  if (outputFile == NIL(char)) {
747    outFile = vis_stdout;
748  }
749  else {
750    outFile = Cmd_FileOpen(outputFile, "w", NIL(char *), 0);
751    if (outFile == NIL(FILE)){
752      return(0);
753    }
754  }
755
756  /* Simulation by packet */ 
757  numRemainingVector = num;
758  do {
759
760    /* Number of vectors to be simulated in current pass. */
761    num = (numRemainingVector > SIMPACKET_SIZE)
762        ? SIMPACKET_SIZE
763        :  numRemainingVector;
764
765    Sim_SimGenerateRandomVectors(sim, num, pseudoInputSource);
766
767    /*
768     * Random init state generation. This must follow generation of input
769     * vectors, because init state depends on inputs.
770     */
771    if (firstTime) {
772      Sim_SimGenerateRandomInitState(sim);
773    }
774   
775    /* SIMULATION */
776    Sim_SimSimulate(sim);
777   
778    /* Print simulation vectors. On first pass, file must be created. */
779    Sim_SimPrint(sim, outFile, firstTime, printInputsFlag,
780                 printOutputsFlag, printPseudoInputsFlag,
781                 printStatesFlag);
782    firstTime = 0;
783
784    /* Reset Vectors */
785    Sim_SimReset(sim);
786
787    numRemainingVector -= num;
788  } while(numRemainingVector > 0);
789
790  if (outputFile != NIL(char)) {
791    fclose(outFile);
792  }
793  Sim_SimFree(sim);
794  return(1);
795}
796
797/**Function********************************************************************
798 
799  Synopsis    [Parses the simulation vectors file, builds a SimSimStruct,
800  simulate and prints the result into the output file.]
801
802  Description [Parses the simulation vectors file, builds a SimSimStruct,
803  simulate and prints the result into the output file. The header of a
804  simulation-vectors file contains .inputs, .pseudo-inputs, .latches,
805  .outputs, and .initial fields and ends with .start_vectors. If a variable is
806  found for which there doesn't exist a corresponding node in the network, or
807  a value is found that does not belong to the domain of its specific
808  variable, then an error message is writen in error_string, the partial
809  simStruct is freed, and the function returns 0. The simulation file must
810  contain each category of declaration in a line(Two ".inputs" is not allowed
811  in the same file). initial-state declaration must be writen after the
812  latches declaration. Vectors are simulated by "packet": When SIMPACKET_SIZE
813  vectors are read, they are simulated and the result is printed. Only "num"
814  vectors are read and simulated(even if the number of vectors in the file is
815  greater than this number). If num is 0, then all vectors in the file are
816  simulated. The function returns 1 if it ends normally, else returns 0.]
817 
818  SideEffects []
819
820******************************************************************************/
821boolean
822SimFileSimulateAndPrint(
823  Ntk_Network_t * network,
824  int             num,
825  char          * inputFile,
826  char          * outputFile,
827  Sim_PseudoSrc   pseudoInputSource,
828  int             printInputsFlag,
829  int             printOutputsFlag,
830  int             printPseudoInputsFlag,
831  int             printStatesFlag,
832  boolean         verbose)
833{
834  int        numRemainingVector, packet;
835  int        ioStatus;
836  FILE      *outFile;
837  int        printFlag  = 1;
838  FILE      *inFile     = Cmd_FileOpen(inputFile, "r", NIL(char *), 0);
839  Sim_Sim_t *sim        = Sim_FileParseDeclaration(network, inFile, inputFile, verbose);
840
841  if (sim == NIL(Sim_Sim_t)) {
842    return(0);
843  }
844
845  /* If partition method was partial/boundary, and -i was used, then dont simulate*/
846  if(SimTestPartInTermsOfCI(sim)){
847    fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n");
848    fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n");
849    fprintf(stdout, "without the -i option and then re-run simulatate.\n");
850    Sim_SimFree(sim);
851    return(0);
852  }
853
854  if (outputFile == NIL(char)) {
855    outFile    = vis_stdout;
856  }
857  else {
858    outFile    = Cmd_FileOpen(outputFile, "w", NIL(char *), 0);
859    if (outFile == NIL(FILE)){
860      return(0);
861    }
862  }
863 
864  /* Simulation by packet */ 
865  numRemainingVector = num;
866  do {
867
868    /********** Number of vectors to be simulated in current pass **********/
869    /* num == 0 => simulate all vectors of the file => packet = SIMPACKET_SIZE */
870    if (numRemainingVector > SIMPACKET_SIZE || num == 0) {
871      packet = SIMPACKET_SIZE;
872    }
873    else {
874      packet = numRemainingVector;
875    }
876
877    ioStatus = Sim_FileParseVectors(inFile, sim, numRemainingVector);
878    if (ioStatus == 0) { /* Error case */
879      Sim_SimFree(sim);
880      fclose(inFile);
881      if (outputFile != NIL(char)) {
882        fclose(outFile);
883      }
884      return(0);
885    }
886     
887
888    /*************************** SIMULATION  ****************************/
889
890    Sim_SimSimulate(sim);
891   
892    /******************* Print Simulation Vectors **********************/
893
894    Sim_SimPrint(sim, outFile, printFlag, printInputsFlag,
895                 printOutputsFlag, printPseudoInputsFlag,
896                 printStatesFlag);
897    printFlag = 0;
898
899    Sim_SimReset(sim);
900    numRemainingVector -= packet;
901  } while(ioStatus != 2 && (num == 0 || numRemainingVector > 0));
902
903  Sim_SimFree(sim);
904  fclose(inFile);
905  if (outputFile != NIL(char)) {
906    fclose(outFile);
907  }
908  return(1);
909}
910
911/*---------------------------------------------------------------------------*/
912/* Definition of static functions                                            */
913/*---------------------------------------------------------------------------*/
914
915/**Function********************************************************************
916
917  Synopsis    [implement the simulate command.]
918
919  CommandName [simulate]
920
921  CommandSynopsis [simulate the flattened network]
922
923  CommandArguments [\[ -I &lt;0/1&gt; \] \[ -O &lt;0/1&gt; \] \[ -P
924  &lt;0/1&gt; \] \[ -S &lt;0/1&gt; \] \[ -h \]  \[ -i &lt;vectors_file&gt; \] \[ -n &lt;vectors_number&gt; \] \[ -o
925  &lt;output_file&gt; \] \[ -p &lt;0|1&gt; \]
926  \[ -v \]]
927
928  CommandDescription [Simulates a network with a set of input
929  vectors. Before calling this command, the user should create a partition
930  (using the command <tt>build_partition_mdds</tt>). The simulation
931  vectors can be provided by  the user (using -i vectors_file), or
932  generated randomly. <p>
933
934  Command options:<p>
935
936  <dl>
937  <dt>-I &lt;0/1&gt;
938
939  <dd>This option controls the printing the
940  primary input variables. 0 implies printing is disabled, enabled
941  otherwise. The default value is 1. The output file generated with
942  this flag set to 0 may not be used as input file for simulation (if
943  there are some primary inputs to the system).
944
945  <dt>-O &lt;0/1&gt;
946
947  <dd>This option controls the printing the
948  primary output variables. 0 implies printing is disabled, enabled
949  otherwise. The default value is 1.
950
951  <dt>-P &lt;0/1&gt;
952  <dd> This option controls the printing the
953  pseudo input variables. 0 implies printing is disabled, enabled
954  otherwise. The default value is 1. The output file generated with
955  this flag set to 0 may not be used as input file for simulation (if
956  there are some pseudo-inputs to the system).
957
958
959  <dt>-S &lt;0/1&gt;
960  <dd> This option controls the printing the
961  state variables. 0 implies printing is disabled, enabled
962  otherwise. The default value is 1.
963
964  <dt>-h
965  <dd>Print a help message that details all options.
966
967
968  <dt> -i &lt;vectors_file&gt;
969  <dd>Give the simulation vector file name. If this option
970  is not used, vectors are generated randomly.
971
972  <dt>-n &lt;N&gt;
973  <dd> Simulate N vectors. This option should be used if vectors_file
974  is not specified. If a vectors_file is given, and if there are more than N
975  vectors in the file, only the first N vectors are simulated.
976
977  <dt>-o &lt;output_file&gt;
978  <dd> Give the name of a file where the simulation result
979  should be written. If this option is not used, the simulation result is
980  directed to standard output.
981
982  <dt>-p &lt;0|1|2&gt;
983  <dd> This option is available only with random vector
984  generation mode, and affects how values for pseudo-inputs (non-deterministic
985  constants) are generated.
986
987  0: pseudo-inputs are treated by user.
988 
989  1: pseudo-inputs are treated randomly.
990
991  2: pseudo-inputs are treated by choosing the first possibility.
992
993  <dt>-v
994  <dd>  Enable verbose mode. Prints CPU time usage.
995  </dl>
996
997  The vectors_file  has two main parts:
998  <dl>
999  <dt>Declarations:
1000  <dd>
1001
1002  <dl>
1003  <dt>Inputs list:
1004  <dd> Gives an ordering of the primary and pseudo
1005  inputs. Every input must be reported in this field.
1006
1007  <dt>Latches list:
1008  <dd> Gives an ordering of the latches. Every latch must
1009  be reported in this field.
1010
1011  <dt>Outputs list:
1012  <dd> Gives an ordering of the outputs. This list may be
1013  incomplete. Simulation is performed only on outputs present in this list.
1014 
1015  <dt>Initial state:
1016  <dd> Value of an initial state. This value is given
1017  with respect to the latch ordering.
1018
1019  </dl>
1020
1021  <dt>Simulation Vectors:
1022  <dd>One vector per line according to the given
1023  order of inputs.
1024
1025  <dt>Final State:
1026  <dd>Prints the value of state variables after the last simulation
1027  vector is applied.
1028  </dl>
1029
1030  An example of a simulation vectors file is:
1031
1032  <ul>
1033
1034  # ----> Declarations<p>
1035  .inputs   X1  X2 <br>
1036  .latches  L1  L2 <br>
1037  .outputs  O <br>
1038  .initial green  0 <br>
1039  .start_vectors <br>
1040  # ----> Vectors <br>
1041  0  1 <br>
1042  1  0 <br>
1043  1  1 <br>
1044
1045  </ul>
1046
1047  Note the keywords: .inputs, .latches, .outputs, .initial, .start_vectors. A
1048  line started by a '#' is a comment line.<p> The simulation result is printed
1049  either in a file (using -o output_file) or to standard output. It has
1050  the same format as vectors_file with additional fields for latches and
1051  outputs. Here is the result of simulation on last vectors_file example:
1052
1053  <ul>
1054
1055  .inputs   X1  X2 <br>
1056  .latches  L1  L2 <br>
1057  .outputs  O <br>
1058  .initial green  0 <br>
1059  .start_vectors <br>
1060  #input;  current_state;  output <br>
1061  0 1   ;  green  0     ;  0 <br>
1062  1 0   ;  blue   0     ;  1 <br>
1063  1 1   ;  red    1     ;  1 <br>
1064  #Final State : green 1
1065  </ul>
1066
1067  Note that each input line has been extended by its simulation result with
1068  current states and outputs listed in order.
1069  The output_file can be read by simulate as vectors_file (latches and
1070  outputs values are ignored). When starting simulation a good trick
1071  is to run simulate with random vectors generation mode; the resulting
1072  can be used as a template to write a vectors_file. For example, executing "simulate -n 1
1073  -o foo.output" will generate a representative file.<p>]
1074
1075  SideEffects []
1076
1077******************************************************************************/
1078static int
1079CommandSimulate(
1080  Hrc_Manager_t ** hmgr,
1081  int              argc,
1082  char          ** argv)
1083{
1084  int            c;
1085  unsigned int   i;
1086  long           startTime        = 0;
1087  long           endTime          = 0;
1088  long           cpuTime          = 0;
1089  int            numberVector      = 0;
1090  FILE          *inputFp           = NIL(FILE);
1091  Sim_PseudoSrc  pseudoInputSource = Sim_Undef_c;          /* default */
1092  boolean        verbose           = FALSE;                /* default */
1093  char          *inputFile         = NIL(char);
1094  char          *outputFile        = NIL(char);
1095  Ntk_Network_t *network           = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
1096  int printInputsFlag = 1; /*default*/
1097  int printOutputsFlag = 1;/*default*/
1098  int printPseudoInputsFlag = 1;/*default*/
1099  int printStatesFlag = 1;/*default*/
1100 
1101  /*
1102   * Parse command line options.
1103   */
1104
1105  util_getopt_reset();
1106  while ((c = util_getopt(argc, argv, "I:O:P:S:hvi:o:n:p:s")) != EOF) {
1107    switch(c) {
1108      case 'I':
1109        printInputsFlag = atoi(util_optarg);
1110        break;
1111      case 'O':
1112        printOutputsFlag = atoi(util_optarg);
1113        break;
1114      case 'P':
1115        printPseudoInputsFlag = atoi(util_optarg);
1116        break;
1117      case 'S':
1118        printStatesFlag = atoi(util_optarg);
1119        break;
1120      case 'h':
1121        goto usage;
1122      case 'i':
1123        inputFile = util_optarg;
1124        break;
1125      case 'n':
1126        for (i = 0; i < strlen(util_optarg); i++) {
1127          if (!isdigit((int)util_optarg[i])) {
1128            goto usage;
1129          }
1130        }
1131        numberVector = atoi(util_optarg);
1132        break;
1133      case 'o':
1134        outputFile = util_optarg;       
1135        break;
1136      case 'p':
1137        if (!strcmp("0", util_optarg)) {
1138          pseudoInputSource = Sim_User_c;
1139        }
1140        else if (!strcmp("1", util_optarg)) {
1141          pseudoInputSource = Sim_Random_c;
1142        }
1143        else if (!strcmp("2", util_optarg)) {
1144          pseudoInputSource = Sim_First_c;
1145        }
1146        else {
1147          goto usage;
1148        }
1149        break;
1150      case 'v':
1151        verbose = 1;
1152        break;
1153      default:
1154        goto usage;
1155    }
1156  }
1157
1158  if (network == NIL(Ntk_Network_t)) {
1159    return 1;
1160  }
1161
1162  if (Ord_NetworkTestAreVariablesOrdered(network,Ord_InputAndLatch_c) == FALSE){
1163    (void) fprintf(vis_stdout, "The MDD variables have not been ordered. Use static_order.\n");
1164    return 1;
1165  }
1166
1167  if (Part_NetworkReadPartition(network) == NIL(graph_t)) {
1168    (void) fprintf(vis_stderr, "Network has not been partitioned. Use build_partition_mdds.\n");
1169    return 1;
1170  }
1171 
1172  /** Initialization for random values generation **/
1173  util_srandom(SimComputeRandomInteger());
1174
1175  /* Parameters verification */
1176
1177  if (numberVector <= 0 && inputFile == NIL(char)) {
1178    (void) fprintf(vis_stderr, "Simulate: specify an input file with -i or use -n option to set\n");
1179    (void) fprintf(vis_stderr, "the number of vectors randomly generated\n");
1180    return(1);
1181  }
1182  if (pseudoInputSource == Sim_User_c && inputFile == NIL(char)) {
1183    (void) fprintf(vis_stderr, "Simulate: '-p 0' option and random vectors\n");
1184    (void) fprintf(vis_stderr, "           generation are incompatible\n");
1185    return(1);
1186  }
1187  if ((pseudoInputSource != Sim_Undef_c) && inputFile != NIL(char)) {
1188    (void) fprintf(vis_stderr, "Simulate: '-p' option is available only if vectors\n");
1189    (void) fprintf(vis_stderr, "           are generated randomly.\n");
1190    return(1);
1191  }
1192
1193  if (numberVector == 0 && inputFile == NIL(char)) {
1194    (void) fprintf(vis_stderr, "Simulate: number of vectors not specified.\nUsing 10 random vectors\n");
1195    numberVector = 10;
1196  }
1197  if (inputFile != NIL(char)) {
1198    inputFp = Cmd_FileOpen(inputFile, "r", NIL(char *), 0);
1199    if (inputFp == NIL(FILE)) {
1200      return (1);
1201    }
1202  }
1203
1204  /* CPU-Time print with verbose option */
1205  if (verbose) {
1206    startTime = util_cpu_time();
1207  }
1208
1209 
1210  /************** Random Vectors generation **************/
1211  error_init();
1212
1213  if (inputFile == NIL(char)) {
1214    if (SimRandomSimulateAndPrint(network, numberVector, outputFile,
1215                                  pseudoInputSource, printInputsFlag,
1216                                  printOutputsFlag,
1217                                  printPseudoInputsFlag, 
1218                                  printStatesFlag,
1219                                  verbose) == 0) {
1220      (void) fprintf(vis_stdout, "%s", error_string());     
1221      return (1);
1222    }
1223  }
1224 
1225/************* Read vectors from a file ***************/
1226 
1227  else {
1228    if (SimFileSimulateAndPrint(network, numberVector, inputFile, outputFile,
1229                                pseudoInputSource, printInputsFlag,
1230                                printOutputsFlag, printPseudoInputsFlag,
1231                                printStatesFlag, verbose) == 0) {
1232      (void) fprintf(vis_stdout, "%s", error_string());     
1233      return(1);
1234    }
1235  }
1236 
1237  if (verbose) {
1238    endTime = util_cpu_time();
1239    cpuTime = endTime - startTime;   
1240    (void) fprintf(vis_stdout, "====> Simulation time: %d ms\n", (int)cpuTime);
1241  }
1242
1243  return 0;             /* normal exit */
1244
1245  usage:
1246  (void) fprintf(vis_stderr, "usage: simulate [-I <0/1>][-O <0/1>][-P <0/1>][-S <0/1>][-h][-i vectors_file]\n");
1247  (void) fprintf(vis_stderr, "                [-n number-vectors][-o output_file][-p <0/1/2>] [-v]\n");
1248
1249  (void) fprintf(vis_stderr, "    -I <0/1>\t\tControls printing of primary input variables\n");
1250  (void) fprintf(vis_stderr, "            \t\t(0:no print, 1:print, default is 1)\n");
1251  (void) fprintf(vis_stderr, "    -O <0/1>\t\tControls printing of output variables\n");
1252  (void) fprintf(vis_stderr, "            \t\t(0:no print, 1:print, default is 1)\n");
1253  (void) fprintf(vis_stderr, "    -P <0/1>\t\tControls printing of pseudo input variables\n");
1254  (void) fprintf(vis_stderr, "            \t\t(0:no print, 1:print, default is 1)\n");
1255  (void) fprintf(vis_stderr, "    -S <0/1>\t\tControls printing of state variables\n");
1256  (void) fprintf(vis_stderr, "            \t\t(0:no print, 1:print, default is 1)\n");
1257  (void) fprintf(vis_stderr, "    -h \tPrints this usage message.\n");
1258  (void) fprintf(vis_stderr, "    -i <vectors_file>\tThe input file containing simulation vectors.\n");
1259  (void) fprintf(vis_stderr, "                   \tIf not specified, N vectors are generated randomly.\n");
1260  (void) fprintf(vis_stderr, "                   \tN is given by the option '-n'.\n");
1261  (void) fprintf(vis_stderr, "    -n <N>\t\tWith this option, only the first N vectors\n");
1262  (void) fprintf(vis_stderr, "          \t\twill be simulated. If '-i' option is not used,\n");
1263  (void) fprintf(vis_stderr, "           \t\tN is the number of random vectors.\n");
1264  (void) fprintf(vis_stderr, "    -o <output_file>\tThe output file. If not specified, the output\n");
1265  (void) fprintf(vis_stderr, "                    \twill be directed to stdout.\n");
1266  (void) fprintf(vis_stderr, "    -p <0|1|2>\t\tIf 0 : non-deterministic cases are treated\n");
1267  (void) fprintf(vis_stderr, "              \t\tas specified by user.\n");
1268  (void) fprintf(vis_stderr, "              \t\tIf 1: non-deterministic cases are treated randomly.\n");
1269  (void) fprintf(vis_stderr, "              \t\tIf 2: non-deterministic cases are treated by\n");
1270  (void) fprintf(vis_stderr, "              \t\tchoosing the first possibility.\n");
1271  (void) fprintf(vis_stderr, "    -v \tVerbose. Print CPU time usage.\n");
1272
1273  return 1;             /* error exit */
1274}
1275
1276
1277/**Function********************************************************************
1278
1279  Synopsis    [Evaluates a binary-valued function.]
1280
1281  Description [Evaluates a binary-valued function on a vector given by its MDD
1282  representation. Returns 1 (0) if the result of the evaluation is equal to
1283  one (zero), otherwise returns -1.]
1284
1285  SideEffects []
1286
1287  SeeAlso     [Sim_nodeToMvfTableEvaluateNode]
1288
1289******************************************************************************/
1290static int
1291EvaluateBinaryFunction(
1292  mdd_t * functionMdd,
1293  mdd_t * vectorMdd)
1294{
1295  mdd_t       * result = mdd_cofactor_minterm(functionMdd, vectorMdd);
1296
1297  if (mdd_is_tautology(result, 1)) {
1298    mdd_free(result);
1299    return (1);
1300  }
1301  else if (mdd_is_tautology(result, 0)) {
1302    mdd_free(result);
1303    return (0);
1304  }
1305  else {
1306    mdd_free(result);
1307    return (-1);
1308  }
1309}
1310
1311
1312/**Function********************************************************************
1313
1314  Synopsis    [Compare two nodes based on the lexigraphic order of their names.]
1315
1316  SeeAlso     []
1317
1318  SideEffects     []
1319
1320******************************************************************************/
1321static int
1322NodeLexCmp(
1323  const void *node1,
1324  const void *node2)
1325{
1326  char *name1 = Ntk_NodeReadName(*(Ntk_Node_t **)node1);
1327  char *name2 = Ntk_NodeReadName(*(Ntk_Node_t **)node2);
1328
1329  return strcmp(name1, name2);
1330}
1331
1332/**Function********************************************************************
1333
1334  Synopsis    [Builds an mdd of simulated states from the array of values.]
1335
1336  Description [Builds an mdd of simulated states from the array of values in the sim structure.]
1337
1338  SideEffects []
1339
1340******************************************************************************/
1341static mdd_t *
1342StatesMddFromVector(
1343  Sim_Sim_t       * sim,
1344  mdd_manager *mddManager
1345  )
1346
1347{
1348  int             i, j;
1349  array_t        *vector;
1350  Ntk_Node_t     *node;
1351  mdd_t *state, *simStates, *tmp, *mddLiteral;
1352  int value;
1353  array_t *valueArray;
1354  int mddId;
1355
1356  /* start with zero */
1357  simStates = mdd_zero(mddManager);
1358  valueArray = array_alloc(int, 1);
1359  for (i = 0; i < array_n(sim->vectorArray); i++) {
1360      /* add every state in the vector */
1361    vector = array_fetch(array_t *, sim->vectorArray, i);
1362    state = mdd_one(mddManager);
1363    for (j = sim->currentStateHead; j < sim->internalPartitionHead; j++){
1364      /* Build the state */
1365      node = array_fetch(Ntk_Node_t *, sim->nodesArray, j);
1366      mddId = Ntk_NodeReadMddId(node);
1367      value = array_fetch(int, vector, j);
1368      array_insert(int, valueArray, 0, value);
1369      mddLiteral = mdd_literal(mddManager, mddId, valueArray);
1370     
1371      tmp = mdd_and(state, mddLiteral, 1, 1);
1372      mdd_free(state);
1373      mdd_free(mddLiteral);
1374      state = tmp;
1375    }
1376
1377    tmp = mdd_or(simStates, state, 1, 1);
1378    mdd_free(simStates);
1379    mdd_free(state);
1380    simStates = tmp;
1381
1382  }
1383  array_free(valueArray);
1384  return simStates;
1385} /* end of StatesMddFromVector */
1386
1387
1388/**Function********************************************************************
1389
1390  Synopsis    [Generates the initial state.]
1391
1392  Description [Generates the initial state, input values in the first
1393  input vector of the sim structure. sim->initState is reset by this
1394  function.]
1395
1396  SideEffects []
1397
1398******************************************************************************/
1399static void
1400GenerateInitState(
1401  Sim_Sim_t * sim, boolean random)
1402{
1403  int            i;
1404  array_t       *mvfArray;
1405  array_t       *initState   = array_alloc(int, 0);
1406  array_t       *nodesArray  = sim->nodesArray;
1407  array_t       *vectorArray = sim->vectorArray;
1408  array_t       *firstVector = array_fetch(array_t *, vectorArray, 0);
1409  st_table      *leaves      = st_init_table(st_ptrcmp, st_ptrhash);
1410  int            numLatches  = sim->internalPartitionHead - sim->currentStateHead;
1411  array_t       *rootArray   = array_alloc(Ntk_Node_t *, numLatches);
1412 
1413  /* Free old initState */
1414  if (sim->initState != NIL(array_t)) {
1415    array_free(sim->initState);
1416  }
1417  sim->initState = initState;
1418
1419  /*
1420   * Load a symbol table with the initial values of the primary and pseudo
1421   * inputs.
1422   */
1423  for (i = 0; i < sim->currentStateHead; i++) {
1424    Ntk_Node_t *node  = array_fetch(Ntk_Node_t *, nodesArray, i);
1425    if (random) {
1426      int         value = array_fetch(int, firstVector, i); 
1427      st_insert(leaves, (char *) node, (char *) (long) value);
1428    } else {
1429      st_insert(leaves, (char *) node, (char *) (long) NTM_UNUSED);
1430    }
1431  }
1432 
1433  /*
1434   * Create an array containing the initialization function for all the
1435   * latches. This array has the same order as the simulation vector.
1436   */
1437  for (i = sim->currentStateHead; i < sim->internalPartitionHead; i++) {
1438    Ntk_Node_t     *latch      = array_fetch(Ntk_Node_t *, nodesArray, i);
1439    Ntk_Node_t     *initNode   = Ntk_LatchReadInitialInput(latch);
1440   
1441    array_insert_last(Ntk_Node_t *, rootArray, initNode);
1442  }
1443
1444  /*
1445   * Build the MVFs for the initialization functions, using the initial input
1446   * values.
1447   */
1448  mvfArray = Ntm_NetworkBuildMvfs(sim->network, rootArray, leaves, NIL(mdd_t));
1449  array_free(rootArray);
1450  st_free_table(leaves);
1451
1452  /*
1453   * Get the initial value of each latch from the MVF of the corresponding
1454   * initialization function.  Since the initialization functions are in terms
1455   * of primary and pseudo input values, and we have completely specified
1456   * values for all inputs, each initialization function should have evaluated
1457   * to a constant (i.e. exactly one non-zero component, and that component is
1458   * the tautology.
1459   */
1460  for (i = 0; i < numLatches; i++) {
1461    int             j;
1462    int             value = 0;  /* initialized to avoid lint complaint */
1463    Mvf_Function_t *initMvf;
1464    mdd_t          *component;
1465    int             numNonZero = 0;
1466   
1467    initMvf = array_fetch(Mvf_Function_t *, mvfArray, i);
1468    Mvf_FunctionForEachComponent(initMvf, j, component) { 
1469      if (!mdd_is_tautology(component, 0)) {
1470        assert(mdd_is_tautology(component, 1));
1471        numNonZero++;
1472        value = j;
1473      }
1474    }
1475
1476    assert(numNonZero == 1);
1477    array_insert_last(int, initState, value);
1478  }
1479
1480  Mvf_FunctionArrayFree(mvfArray);
1481  return;
1482} /* end of GenerateInitState */
1483
Note: See TracBrowser for help on using the repository browser.