/**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.] ******************************************************************************/ #include "simInt.h" static char rcsid[] UNUSED = "$Id: simMain.c,v 1.19 2005/04/23 14:31:51 jinh Exp $"; /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ 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); /**AutomaticEnd***************************************************************/ /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Initializes the sim package.] SideEffects [] SeeAlso [Sim_End] ******************************************************************************/ void Sim_Init(void) { Cmd_CommandAdd("simulate", CommandSimulate, /* doesn't changes_network */ 0); } /**Function******************************************************************** Synopsis [Ends the sim package.] SideEffects [] SeeAlso [Sim_Init] ******************************************************************************/ void Sim_End(void) { } /**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 [] ******************************************************************************/ 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) { 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); } /**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 [] ******************************************************************************/ void Sim_SimReset( Sim_Sim_t * sim) { 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); } /**Function******************************************************************** Synopsis [Frees a sim Structure.] SideEffects [] ******************************************************************************/ void Sim_SimFree( Sim_Sim_t * sim) { 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); } /**Function******************************************************************** Synopsis [Allocates and initializes an array of nodes of every input, current-state, next-state, output.] SideEffects [] ******************************************************************************/ array_t * Sim_NetworkCreateNodesArray( Ntk_Network_t * network, int * currentStateHead, int * internalPartitionHead, int * nextStateHead, int * outputHead) { 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); } /**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 [] ******************************************************************************/ void Sim_SimGenerateRandomVectors( Sim_Sim_t * sim, int numberVector, Sim_PseudoSrc pseudoInputSource) { 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; } /**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 [] ******************************************************************************/ void Sim_SimGenerateRandomInitState( Sim_Sim_t * sim) { GenerateInitState(sim, TRUE); } /**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 [] ******************************************************************************/ void Sim_SimSimulate( Sim_Sim_t * sim) { 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); } } /**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] ******************************************************************************/ int Sim_nodeToMvfTableEvaluateNode( st_table * nodeToMvfTable, Ntk_Node_t * node, mdd_t * vectorMdd) { 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); } /**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] ******************************************************************************/ array_t * Sim_nodeToMvfTableEvaluateNodesArray( st_table * nodeToMvfTable, array_t * nodesArray, mdd_t * vectorMdd) { 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); } /**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 [] ******************************************************************************/ mdd_t * Sim_RandomSimulate( Ntk_Network_t * network, int num, boolean verbose) { 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, ¤tStateHead, &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 */ /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ /**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 [] ******************************************************************************/ void SimSimInitializeCurrentState( Sim_Sim_t * sim) { 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); } } /**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 [] ******************************************************************************/ boolean SimRandomSimulateAndPrint( Ntk_Network_t * network, int num, char * outputFile, Sim_PseudoSrc pseudoInputSource, int printInputsFlag, int printOutputsFlag, int printPseudoInputsFlag, int printStatesFlag, boolean verbose) { 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, ¤tStateHead, &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); } /**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 [] ******************************************************************************/ 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) { 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); } /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ /**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:
.inputs X1 X2
.latches L1 L2
.outputs O
.initial green 0
.start_vectors
# ----> Vectors
0 1
1 0
1 1
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:
]
SideEffects []
******************************************************************************/
static int
CommandSimulate(
Hrc_Manager_t ** hmgr,
int argc,
char ** argv)
{
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;
}
/** Initialization for random values generation **/
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