VIS

src/sim/simMain.c File Reference

#include "simInt.h"
Include dependency graph for simMain.c:

Go to the source code of this file.

Functions

static int CommandSimulate (Hrc_Manager_t **hmgr, int argc, char **argv)
static int EvaluateBinaryFunction (mdd_t *functionMdd, mdd_t *vectorMdd)
static int NodeLexCmp (const void *node1, const void *node2)
static mdd_t * StatesMddFromVector (Sim_Sim_t *sim, mdd_manager *mddManager)
static void GenerateInitState (Sim_Sim_t *sim, boolean random)
void Sim_Init (void)
void Sim_End (void)
Sim_Sim_t * Sim_SimCreate (Ntk_Network_t *network, st_table *nodeToMvfTable, char *inputFile, int lineNumber, array_t *nodesArray, int currentStateHead, int internalPartitionHead, int nextStateHead, int outputHead, array_t *initState, array_t *vectorArray, boolean verbose)
void Sim_SimReset (Sim_Sim_t *sim)
void Sim_SimFree (Sim_Sim_t *sim)
array_t * Sim_NetworkCreateNodesArray (Ntk_Network_t *network, int *currentStateHead, int *internalPartitionHead, int *nextStateHead, int *outputHead)
void Sim_SimGenerateRandomVectors (Sim_Sim_t *sim, int numberVector, Sim_PseudoSrc pseudoInputSource)
void Sim_SimGenerateRandomInitState (Sim_Sim_t *sim)
void Sim_SimSimulate (Sim_Sim_t *sim)
int Sim_nodeToMvfTableEvaluateNode (st_table *nodeToMvfTable, Ntk_Node_t *node, mdd_t *vectorMdd)
array_t * Sim_nodeToMvfTableEvaluateNodesArray (st_table *nodeToMvfTable, array_t *nodesArray, mdd_t *vectorMdd)
mdd_t * Sim_RandomSimulate (Ntk_Network_t *network, int num, boolean verbose)
void SimSimInitializeCurrentState (Sim_Sim_t *sim)
boolean SimRandomSimulateAndPrint (Ntk_Network_t *network, int num, char *outputFile, Sim_PseudoSrc pseudoInputSource, int printInputsFlag, int printOutputsFlag, int printPseudoInputsFlag, int printStatesFlag, boolean verbose)
boolean SimFileSimulateAndPrint (Ntk_Network_t *network, int num, char *inputFile, char *outputFile, Sim_PseudoSrc pseudoInputSource, int printInputsFlag, int printOutputsFlag, int printPseudoInputsFlag, int printStatesFlag, boolean verbose)

Variables

static char rcsid[] UNUSED = "$Id: simMain.c,v 1.19 2005/04/23 14:31:51 jinh Exp $"

Function Documentation

static int CommandSimulate ( Hrc_Manager_t **  hmgr,
int  argc,
char **  argv 
) [static]

AutomaticStart

Function********************************************************************

Synopsis [implement the simulate command.]

CommandName [simulate]

CommandSynopsis [simulate the flattened network]

CommandArguments [\[ -I <0/1> \] \[ -O <0/1> \] \[ -P <0/1> \] \[ -S <0/1> \] \[ -h \] \[ -i <vectors_file> \] \[ -n <vectors_number> \] \[ -o <output_file> \] \[ -p <0|1> \] \[ -v \]]

CommandDescription [Simulates a network with a set of input vectors. Before calling this command, the user should create a partition (using the command build_partition_mdds). The simulation vectors can be provided by the user (using -i vectors_file), or generated randomly.

Command options:

-I <0/1>

This option controls the printing the primary input variables. 0 implies printing is disabled, enabled otherwise. The default value is 1. The output file generated with this flag set to 0 may not be used as input file for simulation (if there are some primary inputs to the system).

-O <0/1>

This option controls the printing the primary output variables. 0 implies printing is disabled, enabled otherwise. The default value is 1.

-P <0/1>

This option controls the printing the pseudo input variables. 0 implies printing is disabled, enabled otherwise. The default value is 1. The output file generated with this flag set to 0 may not be used as input file for simulation (if there are some pseudo-inputs to the system).

-S <0/1>

This option controls the printing the state variables. 0 implies printing is disabled, enabled otherwise. The default value is 1.

-h

Print a help message that details all options.

-i <vectors_file>

Give the simulation vector file name. If this option is not used, vectors are generated randomly.

-n <N>

Simulate N vectors. This option should be used if vectors_file is not specified. If a vectors_file is given, and if there are more than N vectors in the file, only the first N vectors are simulated.

-o <output_file>

Give the name of a file where the simulation result should be written. If this option is not used, the simulation result is directed to standard output.

-p <0|1|2>

This option is available only with random vector generation mode, and affects how values for pseudo-inputs (non-deterministic constants) are generated.

0: pseudo-inputs are treated by user.

1: pseudo-inputs are treated randomly.

2: pseudo-inputs are treated by choosing the first possibility.

-v
Enable verbose mode. Prints CPU time usage.

The vectors_file has two main parts:

Declarations:

Inputs list:

Gives an ordering of the primary and pseudo inputs. Every input must be reported in this field.

Latches list:

Gives an ordering of the latches. Every latch must be reported in this field.

Outputs list:

Gives an ordering of the outputs. This list may be incomplete. Simulation is performed only on outputs present in this list.

Initial state:

Value of an initial state. This value is given with respect to the latch ordering.

Simulation Vectors:

One vector per line according to the given order of inputs.

Final State:
Prints the value of state variables after the last simulation vector is applied.

An example of a simulation vectors file is:

----> Declarations

.inputs X1 X2
.latches L1 L2
.outputs O
.initial green 0
.start_vectors
# ----> Vectors
0 1
1 0
1 1

Note the keywords: .inputs, .latches, .outputs, .initial, .start_vectors. A line started by a '#' is a comment line.

The simulation result is printed either in a file (using -o output_file) or to standard output. It has the same format as vectors_file with additional fields for latches and outputs. Here is the result of simulation on last vectors_file example:

inputs X1 X2
.latches L1 L2
.outputs O
.initial green 0
.start_vectors
#input; current_state; output
0 1 ; green 0 ; 0
1 0 ; blue 0 ; 1
1 1 ; red 1 ; 1
#Final State : green 1

Note that each input line has been extended by its simulation result with current states and outputs listed in order. The output_file can be read by simulate as vectors_file (latches and outputs values are ignored). When starting simulation a good trick is to run simulate with random vectors generation mode; the resulting can be used as a template to write a vectors_file. For example, executing "simulate -n 1 -o foo.output" will generate a representative file.

]

SideEffects []

Initialization for random values generation

Definition at line 1079 of file simMain.c.

{
  int            c;
  unsigned int   i;
  long           startTime        = 0;
  long           endTime          = 0;
  long           cpuTime          = 0;
  int            numberVector      = 0;
  FILE          *inputFp           = NIL(FILE);
  Sim_PseudoSrc  pseudoInputSource = Sim_Undef_c;          /* default */
  boolean        verbose           = FALSE;                /* default */
  char          *inputFile         = NIL(char);
  char          *outputFile        = NIL(char);
  Ntk_Network_t *network           = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
  int printInputsFlag = 1; /*default*/
  int printOutputsFlag = 1;/*default*/
  int printPseudoInputsFlag = 1;/*default*/
  int printStatesFlag = 1;/*default*/
  
  /*
   * Parse command line options.
   */

  util_getopt_reset();
  while ((c = util_getopt(argc, argv, "I:O:P:S:hvi:o:n:p:s")) != EOF) {
    switch(c) {
      case 'I':
        printInputsFlag = atoi(util_optarg);
        break;
      case 'O':
        printOutputsFlag = atoi(util_optarg);
        break;
      case 'P':
        printPseudoInputsFlag = atoi(util_optarg);
        break;
      case 'S':
        printStatesFlag = atoi(util_optarg);
        break;
      case 'h':
        goto usage;
      case 'i':
        inputFile = util_optarg;
        break;
      case 'n':
        for (i = 0; i < strlen(util_optarg); i++) {
          if (!isdigit((int)util_optarg[i])) {
            goto usage;
          }
        }
        numberVector = atoi(util_optarg);
        break;
      case 'o':
        outputFile = util_optarg;        
        break;
      case 'p':
        if (!strcmp("0", util_optarg)) {
          pseudoInputSource = Sim_User_c;
        }
        else if (!strcmp("1", util_optarg)) {
          pseudoInputSource = Sim_Random_c;
        }
        else if (!strcmp("2", util_optarg)) {
          pseudoInputSource = Sim_First_c;
        }
        else {
          goto usage;
        }
        break;
      case 'v':
        verbose = 1;
        break;
      default:
        goto usage;
    }
  }

  if (network == NIL(Ntk_Network_t)) {
    return 1;
  }

  if (Ord_NetworkTestAreVariablesOrdered(network,Ord_InputAndLatch_c) == FALSE){
    (void) fprintf(vis_stdout, "The MDD variables have not been ordered. Use static_order.\n");
    return 1;
  }

  if (Part_NetworkReadPartition(network) == NIL(graph_t)) {
    (void) fprintf(vis_stderr, "Network has not been partitioned. Use build_partition_mdds.\n");
    return 1;
  }
  
  util_srandom(SimComputeRandomInteger());

  /* Parameters verification */

  if (numberVector <= 0 && inputFile == NIL(char)) {
    (void) fprintf(vis_stderr, "Simulate: specify an input file with -i or use -n option to set\n");
    (void) fprintf(vis_stderr, "the number of vectors randomly generated\n");
    return(1);
  }
  if (pseudoInputSource == Sim_User_c && inputFile == NIL(char)) {
    (void) fprintf(vis_stderr, "Simulate: '-p 0' option and random vectors\n");
    (void) fprintf(vis_stderr, "           generation are incompatible\n");
    return(1);
  }
  if ((pseudoInputSource != Sim_Undef_c) && inputFile != NIL(char)) {
    (void) fprintf(vis_stderr, "Simulate: '-p' option is available only if vectors\n");
    (void) fprintf(vis_stderr, "           are generated randomly.\n");
    return(1);
  }

  if (numberVector == 0 && inputFile == NIL(char)) {
    (void) fprintf(vis_stderr, "Simulate: number of vectors not specified.\nUsing 10 random vectors\n");
    numberVector = 10;
  }
  if (inputFile != NIL(char)) {
    inputFp = Cmd_FileOpen(inputFile, "r", NIL(char *), 0);
    if (inputFp == NIL(FILE)) {
      return (1);
    }
  }

  /* CPU-Time print with verbose option */
  if (verbose) {
    startTime = util_cpu_time();
  }

  
  /************** Random Vectors generation **************/
  error_init();

  if (inputFile == NIL(char)) {
    if (SimRandomSimulateAndPrint(network, numberVector, outputFile,
                                  pseudoInputSource, printInputsFlag,
                                  printOutputsFlag,
                                  printPseudoInputsFlag, 
                                  printStatesFlag,
                                  verbose) == 0) {
      (void) fprintf(vis_stdout, "%s", error_string());      
      return (1);
    }
  }
  
/************* Read vectors from a file ***************/
  
  else {
    if (SimFileSimulateAndPrint(network, numberVector, inputFile, outputFile,
                                pseudoInputSource, printInputsFlag,
                                printOutputsFlag, printPseudoInputsFlag,
                                printStatesFlag, verbose) == 0) {
      (void) fprintf(vis_stdout, "%s", error_string());      
      return(1);
    }
  }
  
  if (verbose) {
    endTime = util_cpu_time();
    cpuTime = endTime - startTime;    
    (void) fprintf(vis_stdout, "====> Simulation time: %d ms\n", (int)cpuTime);
  }

  return 0;             /* normal exit */

  usage:
  (void) fprintf(vis_stderr, "usage: simulate [-I <0/1>][-O <0/1>][-P <0/1>][-S <0/1>][-h][-i vectors_file]\n");
  (void) fprintf(vis_stderr, "                [-n number-vectors][-o output_file][-p <0/1/2>] [-v]\n");

  (void) fprintf(vis_stderr, "    -I <0/1>\t\tControls printing of primary input variables\n");
  (void) fprintf(vis_stderr, "            \t\t(0:no print, 1:print, default is 1)\n");
  (void) fprintf(vis_stderr, "    -O <0/1>\t\tControls printing of output variables\n");
  (void) fprintf(vis_stderr, "            \t\t(0:no print, 1:print, default is 1)\n");
  (void) fprintf(vis_stderr, "    -P <0/1>\t\tControls printing of pseudo input variables\n");
  (void) fprintf(vis_stderr, "            \t\t(0:no print, 1:print, default is 1)\n");
  (void) fprintf(vis_stderr, "    -S <0/1>\t\tControls printing of state variables\n");
  (void) fprintf(vis_stderr, "            \t\t(0:no print, 1:print, default is 1)\n");
  (void) fprintf(vis_stderr, "    -h \tPrints this usage message.\n");
  (void) fprintf(vis_stderr, "    -i <vectors_file>\tThe input file containing simulation vectors.\n");
  (void) fprintf(vis_stderr, "                   \tIf not specified, N vectors are generated randomly.\n");
  (void) fprintf(vis_stderr, "                   \tN is given by the option '-n'.\n");
  (void) fprintf(vis_stderr, "    -n <N>\t\tWith this option, only the first N vectors\n");
  (void) fprintf(vis_stderr, "          \t\twill be simulated. If '-i' option is not used,\n");
  (void) fprintf(vis_stderr, "           \t\tN is the number of random vectors.\n");
  (void) fprintf(vis_stderr, "    -o <output_file>\tThe output file. If not specified, the output\n");
  (void) fprintf(vis_stderr, "                    \twill be directed to stdout.\n");
  (void) fprintf(vis_stderr, "    -p <0|1|2>\t\tIf 0 : non-deterministic cases are treated\n");
  (void) fprintf(vis_stderr, "              \t\tas specified by user.\n");
  (void) fprintf(vis_stderr, "              \t\tIf 1: non-deterministic cases are treated randomly.\n");
  (void) fprintf(vis_stderr, "              \t\tIf 2: non-deterministic cases are treated by\n");
  (void) fprintf(vis_stderr, "              \t\tchoosing the first possibility.\n");
  (void) fprintf(vis_stderr, "    -v \tVerbose. Print CPU time usage.\n");

  return 1;             /* error exit */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int EvaluateBinaryFunction ( mdd_t *  functionMdd,
mdd_t *  vectorMdd 
) [static]

Function********************************************************************

Synopsis [Evaluates a binary-valued function.]

Description [Evaluates a binary-valued function on a vector given by its MDD representation. Returns 1 (0) if the result of the evaluation is equal to one (zero), otherwise returns -1.]

SideEffects []

SeeAlso [Sim_nodeToMvfTableEvaluateNode]

Definition at line 1291 of file simMain.c.

{
  mdd_t       * result = mdd_cofactor_minterm(functionMdd, vectorMdd);

  if (mdd_is_tautology(result, 1)) {
    mdd_free(result);
    return (1);
  }
  else if (mdd_is_tautology(result, 0)) {
    mdd_free(result);
    return (0);
  }
  else {
    mdd_free(result);
    return (-1);
  }
}

Here is the caller graph for this function:

static void GenerateInitState ( Sim_Sim_t *  sim,
boolean  random 
) [static]

Function********************************************************************

Synopsis [Generates the initial state.]

Description [Generates the initial state, input values in the first input vector of the sim structure. sim->initState is reset by this function.]

SideEffects []

Definition at line 1400 of file simMain.c.

{
  int            i;
  array_t       *mvfArray;
  array_t       *initState   = array_alloc(int, 0);
  array_t       *nodesArray  = sim->nodesArray;
  array_t       *vectorArray = sim->vectorArray;
  array_t       *firstVector = array_fetch(array_t *, vectorArray, 0);
  st_table      *leaves      = st_init_table(st_ptrcmp, st_ptrhash);
  int            numLatches  = sim->internalPartitionHead - sim->currentStateHead;
  array_t       *rootArray   = array_alloc(Ntk_Node_t *, numLatches);
  
  /* Free old initState */
  if (sim->initState != NIL(array_t)) {
    array_free(sim->initState);
  }
  sim->initState = initState;

  /*
   * Load a symbol table with the initial values of the primary and pseudo
   * inputs.
   */
  for (i = 0; i < sim->currentStateHead; i++) {
    Ntk_Node_t *node  = array_fetch(Ntk_Node_t *, nodesArray, i);
    if (random) {
      int         value = array_fetch(int, firstVector, i); 
      st_insert(leaves, (char *) node, (char *) (long) value);
    } else {
      st_insert(leaves, (char *) node, (char *) (long) NTM_UNUSED);
    }
  }
  
  /*
   * Create an array containing the initialization function for all the
   * latches. This array has the same order as the simulation vector.
   */
  for (i = sim->currentStateHead; i < sim->internalPartitionHead; i++) {
    Ntk_Node_t     *latch      = array_fetch(Ntk_Node_t *, nodesArray, i);
    Ntk_Node_t     *initNode   = Ntk_LatchReadInitialInput(latch);
    
    array_insert_last(Ntk_Node_t *, rootArray, initNode);
  }

  /*
   * Build the MVFs for the initialization functions, using the initial input
   * values.
   */
  mvfArray = Ntm_NetworkBuildMvfs(sim->network, rootArray, leaves, NIL(mdd_t));
  array_free(rootArray);
  st_free_table(leaves);

  /*
   * Get the initial value of each latch from the MVF of the corresponding
   * initialization function.  Since the initialization functions are in terms
   * of primary and pseudo input values, and we have completely specified
   * values for all inputs, each initialization function should have evaluated
   * to a constant (i.e. exactly one non-zero component, and that component is
   * the tautology.
   */
  for (i = 0; i < numLatches; i++) {
    int             j;
    int             value = 0;  /* initialized to avoid lint complaint */
    Mvf_Function_t *initMvf;
    mdd_t          *component;
    int             numNonZero = 0;
    
    initMvf = array_fetch(Mvf_Function_t *, mvfArray, i);
    Mvf_FunctionForEachComponent(initMvf, j, component) { 
      if (!mdd_is_tautology(component, 0)) {
        assert(mdd_is_tautology(component, 1));
        numNonZero++;
        value = j;
      }
    }

    assert(numNonZero == 1);
    array_insert_last(int, initState, value);
  }

  Mvf_FunctionArrayFree(mvfArray);
  return;
} /* end of GenerateInitState */

Here is the call graph for this function:

Here is the caller graph for this function:

static int NodeLexCmp ( const void *  node1,
const void *  node2 
) [static]

Function********************************************************************

Synopsis [Compare two nodes based on the lexigraphic order of their names.]

SeeAlso []

SideEffects []

Definition at line 1322 of file simMain.c.

{
  char *name1 = Ntk_NodeReadName(*(Ntk_Node_t **)node1);
  char *name2 = Ntk_NodeReadName(*(Ntk_Node_t **)node2);

  return strcmp(name1, name2);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Sim_End ( void  )

Function********************************************************************

Synopsis [Ends the sim package.]

SideEffects []

SeeAlso [Sim_Init]

Definition at line 83 of file simMain.c.

{
}

Here is the caller graph for this function:

void Sim_Init ( void  )

AutomaticEnd Function********************************************************************

Synopsis [Initializes the sim package.]

SideEffects []

SeeAlso [Sim_End]

Definition at line 67 of file simMain.c.

{
  Cmd_CommandAdd("simulate", CommandSimulate, /* doesn't changes_network */ 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

array_t* Sim_NetworkCreateNodesArray ( Ntk_Network_t *  network,
int *  currentStateHead,
int *  internalPartitionHead,
int *  nextStateHead,
int *  outputHead 
)

Function********************************************************************

Synopsis [Allocates and initializes an array of nodes of every input, current-state, next-state, output.]

SideEffects []

Definition at line 236 of file simMain.c.

{
  int            i;
  lsGen          inputGen;
  lsGen          latchGen;
  lsGen          outputGen;  
  Ntk_Node_t    *node;
  array_t       *nodesArray = array_alloc(Ntk_Node_t *, 0);
  graph_t       *partition;
  vertex_t      *vertex;
  array_t *dfsarray;

  /* Input Nodes */

  { 
        array_t *tmpArray= array_alloc(Ntk_Node_t *, 0);
    Ntk_NetworkForEachInput(network, inputGen, node) {
          array_insert_last(Ntk_Node_t *, tmpArray, node);
        }
        array_sort(tmpArray, NodeLexCmp);
        array_append(nodesArray, tmpArray);
        array_free(tmpArray);
  }
  
  
  *currentStateHead = array_n(nodesArray);  /* Initialize currentStateHead */

  /* Adding latches */
  
  {
        array_t *tmpArray= array_alloc(Ntk_Node_t *, 0);
    Ntk_NetworkForEachLatch(network, latchGen, node) {
          array_insert_last(Ntk_Node_t *, tmpArray, node);
        }
        array_sort(tmpArray, NodeLexCmp);
        array_append(nodesArray, tmpArray);
        array_free(tmpArray);
  }
  
  *internalPartitionHead = array_n(nodesArray);  /* Initialize internalPartitionHead */

  /* Add internal partition nodes */

  partition = Part_NetworkReadPartition(network);
  dfsarray = g_dfs(partition);
  for(i=0; i< array_n(dfsarray); i++){
    vertex = array_fetch(vertex_t *, dfsarray, i);
    node = Ntk_NetworkFindNodeByName(network, Part_VertexReadName(vertex));
    if(!(Ntk_NodeTestIsCombInput(node) || Ntk_NodeTestIsCombOutput(node))){
      array_insert_last(Ntk_Node_t *, nodesArray, node);
    }
  }
  array_free(dfsarray);
  
  *nextStateHead = array_n(nodesArray);  /* Initialize nextStateHead */

  /* Add data-input of latches as next state node */

  for (i = *currentStateHead; i < *internalPartitionHead; i++) {
    node = array_fetch(Ntk_Node_t *, nodesArray, i);
    node = Ntk_LatchReadDataInput(node);
    array_insert_last(Ntk_Node_t *, nodesArray, node);
  }
  
  *outputHead = array_n(nodesArray);  /* Initialize outputHead */
  
          
  /* Adding outputs */
  
  {
        array_t *tmpArray= array_alloc(Ntk_Node_t *, 0);
    Ntk_NetworkForEachPrimaryOutput(network, outputGen, node) {
      array_insert_last(Ntk_Node_t *, tmpArray, node);
        }
        array_sort(tmpArray, NodeLexCmp);
        array_append(nodesArray, tmpArray);
        array_free(tmpArray);
  }

  return(nodesArray);
}  

Here is the call graph for this function:

Here is the caller graph for this function:

int Sim_nodeToMvfTableEvaluateNode ( st_table *  nodeToMvfTable,
Ntk_Node_t *  node,
mdd_t *  vectorMdd 
)

Function********************************************************************

Synopsis [Evaluates the function of a node on a minterm.]

Description [Evaluates the function of a node on a minterm. This node must have an entry in nodeToMvfTable. The node may represent a binary or multi-valued function. The result is returned as an integer. If the node represents a binary function, 0 or 1 will be returned.

NOTE : WE ASSUME THAT THE FUNCTION IS COMPLETELY SPECIFIED. WE ASSUME ALSO THAT THE VECTOR IS "COMPLETE". AS A CONSEQUENCE, IF THE VECTOR IS NOT IN THE ONSET OF ONE OF THE FIRST n-1 VALUES OF THE FUNCTION, THEN IT IS ASSUMED THAT THE FUNCTION TAKES ITS LAST VALUE ON THIS VECTOR.]

SideEffects []

SeeAlso [Sim_nodeToMvfTableEvaluateNodesArray]

Definition at line 502 of file simMain.c.

{
  int             i;
  Mvf_Function_t *mvFunction = NIL(Mvf_Function_t);

  (void) st_lookup(nodeToMvfTable, (char *) node,  &mvFunction);

  /*
   * For a binary function the array contains 2 MDDs for off-set and
   * on-set, with the indices 0 or 1.
   */

  for (i = 0; i < Mvf_FunctionReadNumComponents(mvFunction) - 1; i++) {
    if (EvaluateBinaryFunction(Mvf_FunctionReadComponent(mvFunction, i),
                               vectorMdd) == 1) {
      return(i);
    }
  }
  /* Return last value without evaluation */
  return(i);
}

Here is the call graph for this function:

Here is the caller graph for this function:

array_t* Sim_nodeToMvfTableEvaluateNodesArray ( st_table *  nodeToMvfTable,
array_t *  nodesArray,
mdd_t *  vectorMdd 
)

Function********************************************************************

Synopsis [Evaluates every node of an array on a minterm.]

Description [Evaluates every node of an array on a minterm. The input values are given by an MDD. Nodes, to be evaluated, must have an entry in nodeToMvfTable. The nodes may represent a binary or multi-valued function. The result is returned as an array of integers. If a node represents a binary function, the integer is equal to either 0 or 1.

NOTE : WE ASSUME THAT THE FUNCTION IS COMPLETELY SPECIFIED. WE ASSUME ALSO THAT THE VECTOR IS "COMPLETE". AS A CONSEQUENCE, IF THE VECTOR IS NOT IN THE ONSET OF ONE OF THE FIRST n-1 VALUES OF THE FUNCTION, THEN IT IS ASSUMED THAT THE FUNCTION TAKES ITS LAST VALUE ON THIS VECTOR.]

SideEffects []

SeeAlso [Sim_nodeToMvfTableEvaluateNode]

Definition at line 548 of file simMain.c.

{
  int          i, value;
  Ntk_Node_t  *node;
  array_t     *resultArray = array_alloc(int, 0);

  for (i = 0; i < array_n(nodesArray); i++) {
    node  = array_fetch(Ntk_Node_t *, nodesArray, i);
    value = Sim_nodeToMvfTableEvaluateNode(nodeToMvfTable, node, vectorMdd);
    array_insert(int, resultArray, i, value);
  }
  return(resultArray);
}

Here is the call graph for this function:

mdd_t* Sim_RandomSimulate ( Ntk_Network_t *  network,
int  num,
boolean  verbose 
)

Function********************************************************************

Synopsis [Generates random vectors, performs simulation.]

Devscription [Generates num random vectors, performs simulation. These vectors form only one thread of simulation. Returns an mdd_t of simulated states.]

SideEffects []

Definition at line 577 of file simMain.c.

{
  int        numRemainingVector;
  st_table  *nodeToMvfTable;
  Sim_Sim_t *sim;
  int        currentStateHead    = 0;
  int        internalPartitionHead    = 0;
  int        nextStateHead       = 0;  
  int        outputHead          = 0;
  int firstTime = 1;
  mdd_t *states, *simStates;
  mdd_manager *mddManager = Ntk_NetworkReadMddManager(network);
  Sim_PseudoSrc pseudoInputSource = Sim_Random_c;
  array_t   *nodesArray          = Sim_NetworkCreateNodesArray(network,
                                             &currentStateHead, &internalPartitionHead, 
                                             &nextStateHead, &outputHead); 

  /* Building nodeToMvfTable */
  nodeToMvfTable = Sim_NetworkBuildNodeToMvfTable(network, nodesArray,
                                                  internalPartitionHead,
                                                  nextStateHead);
    
  sim = Sim_SimCreate(network, nodeToMvfTable, NULL, 0, nodesArray,
                      currentStateHead, internalPartitionHead, nextStateHead, outputHead, 
                      NULL, NULL, verbose);

  /* If partition method was partial/boundary, and -i was used, then dont simulate*/
  if(SimTestPartInTermsOfCI(sim)){
    fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n");
    fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n");
    fprintf(stdout, "without the -i option and then re-run simulatate.\n");
    Sim_SimFree(sim);
    return(0);
  }
  
  /* Simulation by packet */  
  simStates = mdd_zero(mddManager);
  numRemainingVector = num;
  do {
    mdd_t *tmp;
    /* Number of vectors to be simulated in current pass. */
    num = (numRemainingVector > SIMPACKET_SIZE)
        ? SIMPACKET_SIZE
        :  numRemainingVector;

    Sim_SimGenerateRandomVectors(sim, num, pseudoInputSource);

    /*
     * Random init state generation. This must follow generation of input
     * vectors, because init state depends on inputs.
     */
    if (firstTime) {
      GenerateInitState(sim, FALSE);
    }
    
    /* SIMULATION */
    Sim_SimSimulate(sim);
    
    /* Print simulation vectors. On first pass, file must be created. */
    states = StatesMddFromVector(sim, mddManager);
    tmp = mdd_or(states, simStates, 1, 1);
    mdd_free(states);
    mdd_free(simStates);
    simStates = tmp;
    firstTime = 0;
    
    /* Reset Vectors */
    Sim_SimReset(sim);

    numRemainingVector -= num;
  } while(numRemainingVector > 0);

  Sim_SimFree(sim);
  return(simStates);
} /* end of Sim_RandomSimulate */

Here is the call graph for this function:

Here is the caller graph for this function:

Sim_Sim_t* Sim_SimCreate ( Ntk_Network_t *  network,
st_table *  nodeToMvfTable,
char *  inputFile,
int  lineNumber,
array_t *  nodesArray,
int  currentStateHead,
int  internalPartitionHead,
int  nextStateHead,
int  outputHead,
array_t *  initState,
array_t *  vectorArray,
boolean  verbose 
)

Function********************************************************************

Synopsis [Allocates and initializes the SimSimStruct struct.]

Description [Allocates and initializes the SimSimStruct struct. Internally, sim deals with nodes of a network instead the name(string) of a variable, and with integers representing the value of a variable instead the value as a string. nodeToMvfTable provides MDDs of primary outputs and next-state functions. External function is provided by sim package that builds nodeToMvfTable from network and nodesArray. inputFile is the name of the file containing the simulation vectors. lineNumber is the current line number while parsing inputFile, it is used to print error messages. nodesArray is an array of network nodes of every inputs, current and next state, and partial outputs. Only outputs contained in nodesArray are simulated. currentStateHead, nextStateHead, outputHead are the index of first current state, next state, and output, in nodesArray. initState is an array of values representing initial state according to the current state order in nodesArray. vectorArray is an array of array of values representing vectors to be simulated. if verbose is TRUE, then messages like begin of simulation procedure and printing procedure as well as the cpu-time spent while simulation are directed to vis_stdout.]

SideEffects []

Definition at line 113 of file simMain.c.

{
  Sim_Sim_t *sim         = ALLOC(Sim_Sim_t, 1);
  
  sim->network           = network;
  sim->nodeToMvfTable    = nodeToMvfTable;
  sim->inputFile         = inputFile;
  sim->lineNumber        = lineNumber;
  sim->nodesArray        = nodesArray;
  sim->currentStateHead  = currentStateHead;
  sim->internalPartitionHead  = internalPartitionHead,
  sim->nextStateHead     = nextStateHead;
  sim->outputHead        = outputHead;
  sim->initState         = initState;
  sim->vectorArray       = vectorArray;
  sim->verbose           = verbose;
  
  return(sim);
}

Here is the caller graph for this function:

void Sim_SimFree ( Sim_Sim_t *  sim)

Function********************************************************************

Synopsis [Frees a sim Structure.]

SideEffects []

Definition at line 195 of file simMain.c.

{
  int             i;
  array_t        *vector;
  Ntk_Node_t     *node;
  Mvf_Function_t *mvFunction;
  st_generator   *stGen;

  if (sim->nodesArray != NULL) {
    array_free(sim->nodesArray);
  }
  if (sim->initState != NIL(array_t)) {
    array_free(sim->initState);
  }

  if (sim->vectorArray != NIL(array_t)) {
    for (i = 0; i < array_n(sim->vectorArray); i++) {
      vector = array_fetch(array_t *, sim->vectorArray, i);
      array_free(vector);
    }
    array_free(sim->vectorArray);
  }
  if(sim->nodeToMvfTable != NIL(st_table)) {
    st_foreach_item(sim->nodeToMvfTable, stGen, &node, &mvFunction) {
      Mvf_FunctionFree(mvFunction);
    }
  }
  st_free_table(sim->nodeToMvfTable);
  FREE(sim);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Sim_SimGenerateRandomInitState ( Sim_Sim_t *  sim)

Function********************************************************************

Synopsis [Generates a random initial state.]

Description [Generates a random initial state, using the primary and pseudo input values in the first input vector of the sim structure. sim->initState is reset by this function.]

SideEffects []

Definition at line 382 of file simMain.c.

{
  GenerateInitState(sim, TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Sim_SimGenerateRandomVectors ( Sim_Sim_t *  sim,
int  numberVector,
Sim_PseudoSrc  pseudoInputSource 
)

Function********************************************************************

Synopsis [Generates random simulation vectors.]

Description [Generates numberVector random simulation vectors. sim->vectorArray is re-initialized by this function. If sim->vectorArray already contains vectors, they will be lost and cause a memory leak.]

SideEffects []

Definition at line 335 of file simMain.c.

{
  int            i;
  int            j;
  array_t       *vector;
  array_t       *vectorArray = array_alloc(array_t *, 0);
  array_t       *nodesArray  = sim->nodesArray;


  /* Initialization with empty vectors */
  for (j = 0; j < numberVector; j++) {
    vector = array_alloc(int, 0);
    array_insert_last(array_t *, vectorArray, vector);
  } 

  /* For every input node */
  for (i = 0; i < sim->currentStateHead; i++) {
    Ntk_Node_t *node = array_fetch(Ntk_Node_t *, nodesArray, i);

    /* For every vector */
    for (j = 0; j < numberVector; j++) {
      int value = SimNodeComputeRandomValue(node, pseudoInputSource);
      
      vector = array_fetch(array_t *, vectorArray, j);
      /* vector is empty => array_insert_last is convenient */
      array_insert_last(int, vector, value);
    }
  }

  sim->vectorArray = vectorArray;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Sim_SimReset ( Sim_Sim_t *  sim)

Function********************************************************************

Synopsis [Resets the sim structure.]

Description [Resets the sim structure. Frees the vectors, and makes it equal to NULL. Sets also the initState as the nextState of last vector in vectorArray. sim->vectorArray must be != NULL, and contain valid vectors.]

SideEffects []

Definition at line 157 of file simMain.c.

{
  int       i, value;
  array_t  *lastVector;

  assert(sim->initState != NIL(array_t));
  
  /* Reset initState */

  if (sim->initState != NIL(array_t)) {
    array_free(sim->initState);
  }
  
  sim->initState = array_alloc(int, 0);
  lastVector = array_fetch_last(array_t *,sim->vectorArray);
  for (i = sim->nextStateHead; i < sim->outputHead; i++) {
    value = array_fetch(int, lastVector, i);
    array_insert_last(int, sim->initState, value);
  }

  /* Free vectorArray */
  for (i = 0; i < array_n(sim->vectorArray); i++) {/* Free Vectors */
    array_t *vector = array_fetch(array_t *, sim->vectorArray, i);
    array_free(vector);
  }
  array_free(sim->vectorArray);
  sim->vectorArray = NIL(array_t);
}

Here is the caller graph for this function:

void Sim_SimSimulate ( Sim_Sim_t *  sim)

Function********************************************************************

Synopsis [Does a simulation on a sim structure.]

Description [Does a simulation on a sim structure. The sim structure must previously be initialized by valid vectors. If vectors are not valid, bad evaluations should be expected. There are two kinds of invalid vectors :

1- The vector is incomplete : f = a+b+c, and vector = not(a) (a = 0)

2- The vector is not in the domain of the function : F_red = a.b, F_blue = a.c, vector = not(a).]

SideEffects []

Definition at line 406 of file simMain.c.

{
  Ntk_Node_t    *node;
  array_t       *vector;
  array_t       *partitionVector;
  int            i, j;
  int            value;
  mdd_t         *vectorMdd;
  int            numberVector = array_n(sim->vectorArray);
  
  if(sim->verbose) {
    (void) fprintf(vis_stdout, "Simulating %d vectors ...\n", numberVector);
    fflush(vis_stdout);
  }

  /* Initialization with initState */
  SimSimInitializeCurrentState(sim);

  /*
  for (j = sim->internalPartitionHead; j < sim->nextStateHead; j++) {
    node =  array_fetch(Ntk_Node_t *, sim->nodesArray, j);
    fprintf(stdout, "%s \t", Ntk_NodeReadName(node));
  }
  if(sim->internalPartitionHead < sim->nextStateHead){
    fprintf(stdout, "\n");
  }
  */
  
  for (i = 0; i < numberVector; i++) { /* For every vector */
    if (i > 0) {         /* Put the current-state = last-next-state */
      SimSimVectorFillCurrentState(sim, i);
    }
    else {
      SimSimInitializeCurrentState(sim);
    }

    vector = array_fetch(array_t *, sim->vectorArray, i);

    /* partitionVector represents the values of the internal nodes
       of the partition, induced by the values of the vector array.
    */

    partitionVector = array_alloc(int, 0);
    
    /* simulate internal nodes first. As these internal nodes are 
       simulated, the vectorMdd is updated to reflect the newly computed
       values
    */

    for (j = sim->internalPartitionHead; j < sim->nextStateHead; j++) {
      vectorMdd = SimSimVectorBuildMdd(sim, vector, partitionVector);
      node =  array_fetch(Ntk_Node_t *, sim->nodesArray, j);
      value = Sim_nodeToMvfTableEvaluateNode(sim->nodeToMvfTable, node, vectorMdd);
      array_insert(int, partitionVector, j - sim->internalPartitionHead, value);
      mdd_free(vectorMdd);
    }
    /*
    if(sim->internalPartitionHead < sim->nextStateHead){
      fprintf(stdout, "\n");
    }
    */
    /* simulate the rest of the nodes */
    vectorMdd = SimSimVectorBuildMdd(sim, vector, partitionVector);
    array_free(partitionVector);

    for (j = sim->nextStateHead; j < array_n(sim->nodesArray); j++) {
      node =  array_fetch(Ntk_Node_t *, sim->nodesArray, j);
      value = Sim_nodeToMvfTableEvaluateNode(sim->nodeToMvfTable, node, vectorMdd);
      array_insert(int, vector, j, value);
    }

    mdd_free(vectorMdd);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

boolean SimFileSimulateAndPrint ( Ntk_Network_t *  network,
int  num,
char *  inputFile,
char *  outputFile,
Sim_PseudoSrc  pseudoInputSource,
int  printInputsFlag,
int  printOutputsFlag,
int  printPseudoInputsFlag,
int  printStatesFlag,
boolean  verbose 
)

Function********************************************************************

Synopsis [Parses the simulation vectors file, builds a SimSimStruct, simulate and prints the result into the output file.]

Description [Parses the simulation vectors file, builds a SimSimStruct, simulate and prints the result into the output file. The header of a simulation-vectors file contains .inputs, .pseudo-inputs, .latches, .outputs, and .initial fields and ends with .start_vectors. If a variable is found for which there doesn't exist a corresponding node in the network, or a value is found that does not belong to the domain of its specific variable, then an error message is writen in error_string, the partial simStruct is freed, and the function returns 0. The simulation file must contain each category of declaration in a line(Two ".inputs" is not allowed in the same file). initial-state declaration must be writen after the latches declaration. Vectors are simulated by "packet": When SIMPACKET_SIZE vectors are read, they are simulated and the result is printed. Only "num" vectors are read and simulated(even if the number of vectors in the file is greater than this number). If num is 0, then all vectors in the file are simulated. The function returns 1 if it ends normally, else returns 0.]

SideEffects []

Definition at line 822 of file simMain.c.

{
  int        numRemainingVector, packet;
  int        ioStatus;
  FILE      *outFile;
  int        printFlag  = 1;
  FILE      *inFile     = Cmd_FileOpen(inputFile, "r", NIL(char *), 0);
  Sim_Sim_t *sim        = Sim_FileParseDeclaration(network, inFile, inputFile, verbose);

  if (sim == NIL(Sim_Sim_t)) {
    return(0);
  }

  /* If partition method was partial/boundary, and -i was used, then dont simulate*/
  if(SimTestPartInTermsOfCI(sim)){
    fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n");
    fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n");
    fprintf(stdout, "without the -i option and then re-run simulatate.\n");
    Sim_SimFree(sim);
    return(0);
  }

  if (outputFile == NIL(char)) {
    outFile    = vis_stdout;
  }
  else {
    outFile    = Cmd_FileOpen(outputFile, "w", NIL(char *), 0);
    if (outFile == NIL(FILE)){
      return(0);
    }
  }
  
  /* Simulation by packet */  
  numRemainingVector = num;
  do {

    /********** Number of vectors to be simulated in current pass **********/
    /* num == 0 => simulate all vectors of the file => packet = SIMPACKET_SIZE */
    if (numRemainingVector > SIMPACKET_SIZE || num == 0) {
      packet = SIMPACKET_SIZE;
    }
    else {
      packet = numRemainingVector;
    }

    ioStatus = Sim_FileParseVectors(inFile, sim, numRemainingVector);
    if (ioStatus == 0) { /* Error case */
      Sim_SimFree(sim);
      fclose(inFile);
      if (outputFile != NIL(char)) {
        fclose(outFile);
      }
      return(0);
    }
      

    /*************************** SIMULATION  ****************************/

    Sim_SimSimulate(sim);
    
    /******************* Print Simulation Vectors **********************/

    Sim_SimPrint(sim, outFile, printFlag, printInputsFlag,
                 printOutputsFlag, printPseudoInputsFlag,
                 printStatesFlag);
    printFlag = 0;

    Sim_SimReset(sim);
    numRemainingVector -= packet;
  } while(ioStatus != 2 && (num == 0 || numRemainingVector > 0));

  Sim_SimFree(sim);
  fclose(inFile);
  if (outputFile != NIL(char)) {
    fclose(outFile);
  }
  return(1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

boolean SimRandomSimulateAndPrint ( Ntk_Network_t *  network,
int  num,
char *  outputFile,
Sim_PseudoSrc  pseudoInputSource,
int  printInputsFlag,
int  printOutputsFlag,
int  printPseudoInputsFlag,
int  printStatesFlag,
boolean  verbose 
)

Function********************************************************************

Synopsis [Generates random vectors, performs simulation, and prints the result.]

Devscription [Generates num random vectors, performs simulation, and prints the result. Returns 1 if function ends normally, else returns 0. If statesPrint is 1, then current and next state are also printed, else it is not. See Sim_SimInitialize for further information about arguments.]

SideEffects []

Definition at line 704 of file simMain.c.

{
  int        numRemainingVector;
  FILE      *outFile;
  st_table  *nodeToMvfTable;
  Sim_Sim_t *sim;
  int        firstTime           = 1;
  int        currentStateHead    = 0;
  int        internalPartitionHead    = 0;
  int        nextStateHead       = 0;  
  int        outputHead          = 0;  
  array_t   *nodesArray          = Sim_NetworkCreateNodesArray(network,
                                             &currentStateHead, &internalPartitionHead, 
                                             &nextStateHead, &outputHead); 

  /* Building nodeToMvfTable */
  nodeToMvfTable = Sim_NetworkBuildNodeToMvfTable(network, nodesArray,
                                                  internalPartitionHead,
                                                  nextStateHead);
    
  sim = Sim_SimCreate(network, nodeToMvfTable, NULL, 0, nodesArray,
                      currentStateHead, internalPartitionHead, nextStateHead, outputHead, 
                      NULL, NULL, verbose);

  /* If partition method was partial/boundary, and -i was used, then dont simulate*/
  if(SimTestPartInTermsOfCI(sim)){
    fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n");
    fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n");
    fprintf(stdout, "without the -i option and then re-run simulatate.\n");
    Sim_SimFree(sim);
    return(0);
  }
  
  if (outputFile == NIL(char)) {
    outFile = vis_stdout;
  }
  else {
    outFile = Cmd_FileOpen(outputFile, "w", NIL(char *), 0);
    if (outFile == NIL(FILE)){
      return(0);
    }
  }

  /* Simulation by packet */  
  numRemainingVector = num;
  do {

    /* Number of vectors to be simulated in current pass. */
    num = (numRemainingVector > SIMPACKET_SIZE)
        ? SIMPACKET_SIZE
        :  numRemainingVector;

    Sim_SimGenerateRandomVectors(sim, num, pseudoInputSource);

    /*
     * Random init state generation. This must follow generation of input
     * vectors, because init state depends on inputs.
     */
    if (firstTime) {
      Sim_SimGenerateRandomInitState(sim);
    }
    
    /* SIMULATION */
    Sim_SimSimulate(sim);
    
    /* Print simulation vectors. On first pass, file must be created. */
    Sim_SimPrint(sim, outFile, firstTime, printInputsFlag,
                 printOutputsFlag, printPseudoInputsFlag,
                 printStatesFlag);
    firstTime = 0;

    /* Reset Vectors */
    Sim_SimReset(sim);

    numRemainingVector -= num;
  } while(numRemainingVector > 0);

  if (outputFile != NIL(char)) {
    fclose(outFile);
  }
  Sim_SimFree(sim);
  return(1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SimSimInitializeCurrentState ( Sim_Sim_t *  sim)

Function********************************************************************

Synopsis [Sets the current state of the first vector in vectorArray using initState.]

Description [Sets the current state of the first vector in vectorArray using initState. vectorArray must contain already the inputs value(AND only the inputs value). It is an error to call this function with a sim structure that contains a wrong vectorArray or a wrong initState.]

SideEffects []

Definition at line 676 of file simMain.c.

{
  int       i, value;
  
  /* Get the first vector from vectorArray */
  array_t  *vector = array_fetch(array_t *, sim->vectorArray, 0);
  
  for (i = 0; i < array_n(sim->initState); i++) {
    value = array_fetch(int, sim->initState, i);
    array_insert_last(int, vector, value);
  }
}

Here is the caller graph for this function:

static mdd_t * StatesMddFromVector ( Sim_Sim_t *  sim,
mdd_manager *  mddManager 
) [static]

Function********************************************************************

Synopsis [Builds an mdd of simulated states from the array of values.]

Description [Builds an mdd of simulated states from the array of values in the sim structure.]

SideEffects []

Definition at line 1342 of file simMain.c.

{
  int             i, j;
  array_t        *vector;
  Ntk_Node_t     *node;
  mdd_t *state, *simStates, *tmp, *mddLiteral;
  int value;
  array_t *valueArray;
  int mddId;

  /* start with zero */
  simStates = mdd_zero(mddManager);
  valueArray = array_alloc(int, 1);
  for (i = 0; i < array_n(sim->vectorArray); i++) {
      /* add every state in the vector */
    vector = array_fetch(array_t *, sim->vectorArray, i);
    state = mdd_one(mddManager);
    for (j = sim->currentStateHead; j < sim->internalPartitionHead; j++){
      /* Build the state */
      node = array_fetch(Ntk_Node_t *, sim->nodesArray, j);
      mddId = Ntk_NodeReadMddId(node);
      value = array_fetch(int, vector, j);
      array_insert(int, valueArray, 0, value);
      mddLiteral = mdd_literal(mddManager, mddId, valueArray);
      
      tmp = mdd_and(state, mddLiteral, 1, 1);
      mdd_free(state);
      mdd_free(mddLiteral);
      state = tmp;
    }

    tmp = mdd_or(simStates, state, 1, 1);
    mdd_free(simStates);
    mdd_free(state);
    simStates = tmp;

  }
  array_free(valueArray);
  return simStates;
} /* end of StatesMddFromVector */

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char rcsid [] UNUSED = "$Id: simMain.c,v 1.19 2005/04/23 14:31:51 jinh Exp $" [static]

CFile***********************************************************************

FileName [simMain.c]

PackageName [sim]

Synopsis [simulation of a Network.]

Description [simulation of a Network. This file contains simulate command and main simulation functions.]

Author [Shaker Sarwary, Tom Shiple and Rajeev Ranjan]

Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. All rights reserved.

Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software.

IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]

Definition at line 36 of file simMain.c.