VIS
|
00001 00034 #include "simInt.h" 00035 00036 static char rcsid[] UNUSED = "$Id: simMain.c,v 1.19 2005/04/23 14:31:51 jinh Exp $"; 00037 00040 /*---------------------------------------------------------------------------*/ 00041 /* Static function prototypes */ 00042 /*---------------------------------------------------------------------------*/ 00043 00044 static int CommandSimulate(Hrc_Manager_t ** hmgr, int argc, char ** argv); 00045 static int EvaluateBinaryFunction(mdd_t * functionMdd, mdd_t * vectorMdd); 00046 static int NodeLexCmp(const void *node1, const void *node2); 00047 static mdd_t * StatesMddFromVector(Sim_Sim_t * sim, mdd_manager *mddManager); 00048 static void GenerateInitState(Sim_Sim_t * sim, boolean random); 00049 00053 /*---------------------------------------------------------------------------*/ 00054 /* Definition of exported functions */ 00055 /*---------------------------------------------------------------------------*/ 00056 00066 void 00067 Sim_Init(void) 00068 { 00069 Cmd_CommandAdd("simulate", CommandSimulate, /* doesn't changes_network */ 0); 00070 } 00071 00072 00082 void 00083 Sim_End(void) 00084 { 00085 } 00086 00112 Sim_Sim_t * 00113 Sim_SimCreate( 00114 Ntk_Network_t * network, 00115 st_table * nodeToMvfTable, 00116 char * inputFile, 00117 int lineNumber, 00118 array_t * nodesArray, 00119 int currentStateHead, 00120 int internalPartitionHead, 00121 int nextStateHead, 00122 int outputHead, 00123 array_t * initState, 00124 array_t * vectorArray, 00125 boolean verbose) 00126 { 00127 Sim_Sim_t *sim = ALLOC(Sim_Sim_t, 1); 00128 00129 sim->network = network; 00130 sim->nodeToMvfTable = nodeToMvfTable; 00131 sim->inputFile = inputFile; 00132 sim->lineNumber = lineNumber; 00133 sim->nodesArray = nodesArray; 00134 sim->currentStateHead = currentStateHead; 00135 sim->internalPartitionHead = internalPartitionHead, 00136 sim->nextStateHead = nextStateHead; 00137 sim->outputHead = outputHead; 00138 sim->initState = initState; 00139 sim->vectorArray = vectorArray; 00140 sim->verbose = verbose; 00141 00142 return(sim); 00143 } 00144 00156 void 00157 Sim_SimReset( 00158 Sim_Sim_t * sim) 00159 { 00160 int i, value; 00161 array_t *lastVector; 00162 00163 assert(sim->initState != NIL(array_t)); 00164 00165 /* Reset initState */ 00166 00167 if (sim->initState != NIL(array_t)) { 00168 array_free(sim->initState); 00169 } 00170 00171 sim->initState = array_alloc(int, 0); 00172 lastVector = array_fetch_last(array_t *,sim->vectorArray); 00173 for (i = sim->nextStateHead; i < sim->outputHead; i++) { 00174 value = array_fetch(int, lastVector, i); 00175 array_insert_last(int, sim->initState, value); 00176 } 00177 00178 /* Free vectorArray */ 00179 for (i = 0; i < array_n(sim->vectorArray); i++) {/* Free Vectors */ 00180 array_t *vector = array_fetch(array_t *, sim->vectorArray, i); 00181 array_free(vector); 00182 } 00183 array_free(sim->vectorArray); 00184 sim->vectorArray = NIL(array_t); 00185 } 00186 00194 void 00195 Sim_SimFree( 00196 Sim_Sim_t * sim) 00197 { 00198 int i; 00199 array_t *vector; 00200 Ntk_Node_t *node; 00201 Mvf_Function_t *mvFunction; 00202 st_generator *stGen; 00203 00204 if (sim->nodesArray != NULL) { 00205 array_free(sim->nodesArray); 00206 } 00207 if (sim->initState != NIL(array_t)) { 00208 array_free(sim->initState); 00209 } 00210 00211 if (sim->vectorArray != NIL(array_t)) { 00212 for (i = 0; i < array_n(sim->vectorArray); i++) { 00213 vector = array_fetch(array_t *, sim->vectorArray, i); 00214 array_free(vector); 00215 } 00216 array_free(sim->vectorArray); 00217 } 00218 if(sim->nodeToMvfTable != NIL(st_table)) { 00219 st_foreach_item(sim->nodeToMvfTable, stGen, &node, &mvFunction) { 00220 Mvf_FunctionFree(mvFunction); 00221 } 00222 } 00223 st_free_table(sim->nodeToMvfTable); 00224 FREE(sim); 00225 } 00226 00235 array_t * 00236 Sim_NetworkCreateNodesArray( 00237 Ntk_Network_t * network, 00238 int * currentStateHead, 00239 int * internalPartitionHead, 00240 int * nextStateHead, 00241 int * outputHead) 00242 { 00243 int i; 00244 lsGen inputGen; 00245 lsGen latchGen; 00246 lsGen outputGen; 00247 Ntk_Node_t *node; 00248 array_t *nodesArray = array_alloc(Ntk_Node_t *, 0); 00249 graph_t *partition; 00250 vertex_t *vertex; 00251 array_t *dfsarray; 00252 00253 /* Input Nodes */ 00254 00255 { 00256 array_t *tmpArray= array_alloc(Ntk_Node_t *, 0); 00257 Ntk_NetworkForEachInput(network, inputGen, node) { 00258 array_insert_last(Ntk_Node_t *, tmpArray, node); 00259 } 00260 array_sort(tmpArray, NodeLexCmp); 00261 array_append(nodesArray, tmpArray); 00262 array_free(tmpArray); 00263 } 00264 00265 00266 *currentStateHead = array_n(nodesArray); /* Initialize currentStateHead */ 00267 00268 /* Adding latches */ 00269 00270 { 00271 array_t *tmpArray= array_alloc(Ntk_Node_t *, 0); 00272 Ntk_NetworkForEachLatch(network, latchGen, node) { 00273 array_insert_last(Ntk_Node_t *, tmpArray, node); 00274 } 00275 array_sort(tmpArray, NodeLexCmp); 00276 array_append(nodesArray, tmpArray); 00277 array_free(tmpArray); 00278 } 00279 00280 *internalPartitionHead = array_n(nodesArray); /* Initialize internalPartitionHead */ 00281 00282 /* Add internal partition nodes */ 00283 00284 partition = Part_NetworkReadPartition(network); 00285 dfsarray = g_dfs(partition); 00286 for(i=0; i< array_n(dfsarray); i++){ 00287 vertex = array_fetch(vertex_t *, dfsarray, i); 00288 node = Ntk_NetworkFindNodeByName(network, Part_VertexReadName(vertex)); 00289 if(!(Ntk_NodeTestIsCombInput(node) || Ntk_NodeTestIsCombOutput(node))){ 00290 array_insert_last(Ntk_Node_t *, nodesArray, node); 00291 } 00292 } 00293 array_free(dfsarray); 00294 00295 *nextStateHead = array_n(nodesArray); /* Initialize nextStateHead */ 00296 00297 /* Add data-input of latches as next state node */ 00298 00299 for (i = *currentStateHead; i < *internalPartitionHead; i++) { 00300 node = array_fetch(Ntk_Node_t *, nodesArray, i); 00301 node = Ntk_LatchReadDataInput(node); 00302 array_insert_last(Ntk_Node_t *, nodesArray, node); 00303 } 00304 00305 *outputHead = array_n(nodesArray); /* Initialize outputHead */ 00306 00307 00308 /* Adding outputs */ 00309 00310 { 00311 array_t *tmpArray= array_alloc(Ntk_Node_t *, 0); 00312 Ntk_NetworkForEachPrimaryOutput(network, outputGen, node) { 00313 array_insert_last(Ntk_Node_t *, tmpArray, node); 00314 } 00315 array_sort(tmpArray, NodeLexCmp); 00316 array_append(nodesArray, tmpArray); 00317 array_free(tmpArray); 00318 } 00319 00320 return(nodesArray); 00321 } 00322 00334 void 00335 Sim_SimGenerateRandomVectors( 00336 Sim_Sim_t * sim, 00337 int numberVector, 00338 Sim_PseudoSrc pseudoInputSource) 00339 { 00340 int i; 00341 int j; 00342 array_t *vector; 00343 array_t *vectorArray = array_alloc(array_t *, 0); 00344 array_t *nodesArray = sim->nodesArray; 00345 00346 00347 /* Initialization with empty vectors */ 00348 for (j = 0; j < numberVector; j++) { 00349 vector = array_alloc(int, 0); 00350 array_insert_last(array_t *, vectorArray, vector); 00351 } 00352 00353 /* For every input node */ 00354 for (i = 0; i < sim->currentStateHead; i++) { 00355 Ntk_Node_t *node = array_fetch(Ntk_Node_t *, nodesArray, i); 00356 00357 /* For every vector */ 00358 for (j = 0; j < numberVector; j++) { 00359 int value = SimNodeComputeRandomValue(node, pseudoInputSource); 00360 00361 vector = array_fetch(array_t *, vectorArray, j); 00362 /* vector is empty => array_insert_last is convenient */ 00363 array_insert_last(int, vector, value); 00364 } 00365 } 00366 00367 sim->vectorArray = vectorArray; 00368 } 00369 00381 void 00382 Sim_SimGenerateRandomInitState( 00383 Sim_Sim_t * sim) 00384 { 00385 GenerateInitState(sim, TRUE); 00386 } 00387 00388 00405 void 00406 Sim_SimSimulate( 00407 Sim_Sim_t * sim) 00408 { 00409 Ntk_Node_t *node; 00410 array_t *vector; 00411 array_t *partitionVector; 00412 int i, j; 00413 int value; 00414 mdd_t *vectorMdd; 00415 int numberVector = array_n(sim->vectorArray); 00416 00417 if(sim->verbose) { 00418 (void) fprintf(vis_stdout, "Simulating %d vectors ...\n", numberVector); 00419 fflush(vis_stdout); 00420 } 00421 00422 /* Initialization with initState */ 00423 SimSimInitializeCurrentState(sim); 00424 00425 /* 00426 for (j = sim->internalPartitionHead; j < sim->nextStateHead; j++) { 00427 node = array_fetch(Ntk_Node_t *, sim->nodesArray, j); 00428 fprintf(stdout, "%s \t", Ntk_NodeReadName(node)); 00429 } 00430 if(sim->internalPartitionHead < sim->nextStateHead){ 00431 fprintf(stdout, "\n"); 00432 } 00433 */ 00434 00435 for (i = 0; i < numberVector; i++) { /* For every vector */ 00436 if (i > 0) { /* Put the current-state = last-next-state */ 00437 SimSimVectorFillCurrentState(sim, i); 00438 } 00439 else { 00440 SimSimInitializeCurrentState(sim); 00441 } 00442 00443 vector = array_fetch(array_t *, sim->vectorArray, i); 00444 00445 /* partitionVector represents the values of the internal nodes 00446 of the partition, induced by the values of the vector array. 00447 */ 00448 00449 partitionVector = array_alloc(int, 0); 00450 00451 /* simulate internal nodes first. As these internal nodes are 00452 simulated, the vectorMdd is updated to reflect the newly computed 00453 values 00454 */ 00455 00456 for (j = sim->internalPartitionHead; j < sim->nextStateHead; j++) { 00457 vectorMdd = SimSimVectorBuildMdd(sim, vector, partitionVector); 00458 node = array_fetch(Ntk_Node_t *, sim->nodesArray, j); 00459 value = Sim_nodeToMvfTableEvaluateNode(sim->nodeToMvfTable, node, vectorMdd); 00460 array_insert(int, partitionVector, j - sim->internalPartitionHead, value); 00461 mdd_free(vectorMdd); 00462 } 00463 /* 00464 if(sim->internalPartitionHead < sim->nextStateHead){ 00465 fprintf(stdout, "\n"); 00466 } 00467 */ 00468 /* simulate the rest of the nodes */ 00469 vectorMdd = SimSimVectorBuildMdd(sim, vector, partitionVector); 00470 array_free(partitionVector); 00471 00472 for (j = sim->nextStateHead; j < array_n(sim->nodesArray); j++) { 00473 node = array_fetch(Ntk_Node_t *, sim->nodesArray, j); 00474 value = Sim_nodeToMvfTableEvaluateNode(sim->nodeToMvfTable, node, vectorMdd); 00475 array_insert(int, vector, j, value); 00476 } 00477 00478 mdd_free(vectorMdd); 00479 } 00480 } 00481 00501 int 00502 Sim_nodeToMvfTableEvaluateNode( 00503 st_table * nodeToMvfTable, 00504 Ntk_Node_t * node, 00505 mdd_t * vectorMdd) 00506 { 00507 int i; 00508 Mvf_Function_t *mvFunction = NIL(Mvf_Function_t); 00509 00510 (void) st_lookup(nodeToMvfTable, (char *) node, &mvFunction); 00511 00512 /* 00513 * For a binary function the array contains 2 MDDs for off-set and 00514 * on-set, with the indices 0 or 1. 00515 */ 00516 00517 for (i = 0; i < Mvf_FunctionReadNumComponents(mvFunction) - 1; i++) { 00518 if (EvaluateBinaryFunction(Mvf_FunctionReadComponent(mvFunction, i), 00519 vectorMdd) == 1) { 00520 return(i); 00521 } 00522 } 00523 /* Return last value without evaluation */ 00524 return(i); 00525 } 00526 00547 array_t * 00548 Sim_nodeToMvfTableEvaluateNodesArray( 00549 st_table * nodeToMvfTable, 00550 array_t * nodesArray, 00551 mdd_t * vectorMdd) 00552 { 00553 int i, value; 00554 Ntk_Node_t *node; 00555 array_t *resultArray = array_alloc(int, 0); 00556 00557 for (i = 0; i < array_n(nodesArray); i++) { 00558 node = array_fetch(Ntk_Node_t *, nodesArray, i); 00559 value = Sim_nodeToMvfTableEvaluateNode(nodeToMvfTable, node, vectorMdd); 00560 array_insert(int, resultArray, i, value); 00561 } 00562 return(resultArray); 00563 } 00564 00576 mdd_t * 00577 Sim_RandomSimulate( 00578 Ntk_Network_t * network, 00579 int num, 00580 boolean verbose) 00581 { 00582 int numRemainingVector; 00583 st_table *nodeToMvfTable; 00584 Sim_Sim_t *sim; 00585 int currentStateHead = 0; 00586 int internalPartitionHead = 0; 00587 int nextStateHead = 0; 00588 int outputHead = 0; 00589 int firstTime = 1; 00590 mdd_t *states, *simStates; 00591 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 00592 Sim_PseudoSrc pseudoInputSource = Sim_Random_c; 00593 array_t *nodesArray = Sim_NetworkCreateNodesArray(network, 00594 ¤tStateHead, &internalPartitionHead, 00595 &nextStateHead, &outputHead); 00596 00597 /* Building nodeToMvfTable */ 00598 nodeToMvfTable = Sim_NetworkBuildNodeToMvfTable(network, nodesArray, 00599 internalPartitionHead, 00600 nextStateHead); 00601 00602 sim = Sim_SimCreate(network, nodeToMvfTable, NULL, 0, nodesArray, 00603 currentStateHead, internalPartitionHead, nextStateHead, outputHead, 00604 NULL, NULL, verbose); 00605 00606 /* If partition method was partial/boundary, and -i was used, then dont simulate*/ 00607 if(SimTestPartInTermsOfCI(sim)){ 00608 fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n"); 00609 fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n"); 00610 fprintf(stdout, "without the -i option and then re-run simulatate.\n"); 00611 Sim_SimFree(sim); 00612 return(0); 00613 } 00614 00615 /* Simulation by packet */ 00616 simStates = mdd_zero(mddManager); 00617 numRemainingVector = num; 00618 do { 00619 mdd_t *tmp; 00620 /* Number of vectors to be simulated in current pass. */ 00621 num = (numRemainingVector > SIMPACKET_SIZE) 00622 ? SIMPACKET_SIZE 00623 : numRemainingVector; 00624 00625 Sim_SimGenerateRandomVectors(sim, num, pseudoInputSource); 00626 00627 /* 00628 * Random init state generation. This must follow generation of input 00629 * vectors, because init state depends on inputs. 00630 */ 00631 if (firstTime) { 00632 GenerateInitState(sim, FALSE); 00633 } 00634 00635 /* SIMULATION */ 00636 Sim_SimSimulate(sim); 00637 00638 /* Print simulation vectors. On first pass, file must be created. */ 00639 states = StatesMddFromVector(sim, mddManager); 00640 tmp = mdd_or(states, simStates, 1, 1); 00641 mdd_free(states); 00642 mdd_free(simStates); 00643 simStates = tmp; 00644 firstTime = 0; 00645 00646 /* Reset Vectors */ 00647 Sim_SimReset(sim); 00648 00649 numRemainingVector -= num; 00650 } while(numRemainingVector > 0); 00651 00652 Sim_SimFree(sim); 00653 return(simStates); 00654 } /* end of Sim_RandomSimulate */ 00655 00656 00657 00658 /*---------------------------------------------------------------------------*/ 00659 /* Definition of internal functions */ 00660 /*---------------------------------------------------------------------------*/ 00661 00675 void 00676 SimSimInitializeCurrentState( 00677 Sim_Sim_t * sim) 00678 { 00679 int i, value; 00680 00681 /* Get the first vector from vectorArray */ 00682 array_t *vector = array_fetch(array_t *, sim->vectorArray, 0); 00683 00684 for (i = 0; i < array_n(sim->initState); i++) { 00685 value = array_fetch(int, sim->initState, i); 00686 array_insert_last(int, vector, value); 00687 } 00688 } 00689 00703 boolean 00704 SimRandomSimulateAndPrint( 00705 Ntk_Network_t * network, 00706 int num, 00707 char * outputFile, 00708 Sim_PseudoSrc pseudoInputSource, 00709 int printInputsFlag, 00710 int printOutputsFlag, 00711 int printPseudoInputsFlag, 00712 int printStatesFlag, 00713 boolean verbose) 00714 { 00715 int numRemainingVector; 00716 FILE *outFile; 00717 st_table *nodeToMvfTable; 00718 Sim_Sim_t *sim; 00719 int firstTime = 1; 00720 int currentStateHead = 0; 00721 int internalPartitionHead = 0; 00722 int nextStateHead = 0; 00723 int outputHead = 0; 00724 array_t *nodesArray = Sim_NetworkCreateNodesArray(network, 00725 ¤tStateHead, &internalPartitionHead, 00726 &nextStateHead, &outputHead); 00727 00728 /* Building nodeToMvfTable */ 00729 nodeToMvfTable = Sim_NetworkBuildNodeToMvfTable(network, nodesArray, 00730 internalPartitionHead, 00731 nextStateHead); 00732 00733 sim = Sim_SimCreate(network, nodeToMvfTable, NULL, 0, nodesArray, 00734 currentStateHead, internalPartitionHead, nextStateHead, outputHead, 00735 NULL, NULL, verbose); 00736 00737 /* If partition method was partial/boundary, and -i was used, then dont simulate*/ 00738 if(SimTestPartInTermsOfCI(sim)){ 00739 fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n"); 00740 fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n"); 00741 fprintf(stdout, "without the -i option and then re-run simulatate.\n"); 00742 Sim_SimFree(sim); 00743 return(0); 00744 } 00745 00746 if (outputFile == NIL(char)) { 00747 outFile = vis_stdout; 00748 } 00749 else { 00750 outFile = Cmd_FileOpen(outputFile, "w", NIL(char *), 0); 00751 if (outFile == NIL(FILE)){ 00752 return(0); 00753 } 00754 } 00755 00756 /* Simulation by packet */ 00757 numRemainingVector = num; 00758 do { 00759 00760 /* Number of vectors to be simulated in current pass. */ 00761 num = (numRemainingVector > SIMPACKET_SIZE) 00762 ? SIMPACKET_SIZE 00763 : numRemainingVector; 00764 00765 Sim_SimGenerateRandomVectors(sim, num, pseudoInputSource); 00766 00767 /* 00768 * Random init state generation. This must follow generation of input 00769 * vectors, because init state depends on inputs. 00770 */ 00771 if (firstTime) { 00772 Sim_SimGenerateRandomInitState(sim); 00773 } 00774 00775 /* SIMULATION */ 00776 Sim_SimSimulate(sim); 00777 00778 /* Print simulation vectors. On first pass, file must be created. */ 00779 Sim_SimPrint(sim, outFile, firstTime, printInputsFlag, 00780 printOutputsFlag, printPseudoInputsFlag, 00781 printStatesFlag); 00782 firstTime = 0; 00783 00784 /* Reset Vectors */ 00785 Sim_SimReset(sim); 00786 00787 numRemainingVector -= num; 00788 } while(numRemainingVector > 0); 00789 00790 if (outputFile != NIL(char)) { 00791 fclose(outFile); 00792 } 00793 Sim_SimFree(sim); 00794 return(1); 00795 } 00796 00821 boolean 00822 SimFileSimulateAndPrint( 00823 Ntk_Network_t * network, 00824 int num, 00825 char * inputFile, 00826 char * outputFile, 00827 Sim_PseudoSrc pseudoInputSource, 00828 int printInputsFlag, 00829 int printOutputsFlag, 00830 int printPseudoInputsFlag, 00831 int printStatesFlag, 00832 boolean verbose) 00833 { 00834 int numRemainingVector, packet; 00835 int ioStatus; 00836 FILE *outFile; 00837 int printFlag = 1; 00838 FILE *inFile = Cmd_FileOpen(inputFile, "r", NIL(char *), 0); 00839 Sim_Sim_t *sim = Sim_FileParseDeclaration(network, inFile, inputFile, verbose); 00840 00841 if (sim == NIL(Sim_Sim_t)) { 00842 return(0); 00843 } 00844 00845 /* If partition method was partial/boundary, and -i was used, then dont simulate*/ 00846 if(SimTestPartInTermsOfCI(sim)){ 00847 fprintf(stdout, "The partition contains internal nodes, and all partition functions are \n"); 00848 fprintf(stdout, "in terms of combinational inputs - quitting. Re-create the partition \n"); 00849 fprintf(stdout, "without the -i option and then re-run simulatate.\n"); 00850 Sim_SimFree(sim); 00851 return(0); 00852 } 00853 00854 if (outputFile == NIL(char)) { 00855 outFile = vis_stdout; 00856 } 00857 else { 00858 outFile = Cmd_FileOpen(outputFile, "w", NIL(char *), 0); 00859 if (outFile == NIL(FILE)){ 00860 return(0); 00861 } 00862 } 00863 00864 /* Simulation by packet */ 00865 numRemainingVector = num; 00866 do { 00867 00868 /********** Number of vectors to be simulated in current pass **********/ 00869 /* num == 0 => simulate all vectors of the file => packet = SIMPACKET_SIZE */ 00870 if (numRemainingVector > SIMPACKET_SIZE || num == 0) { 00871 packet = SIMPACKET_SIZE; 00872 } 00873 else { 00874 packet = numRemainingVector; 00875 } 00876 00877 ioStatus = Sim_FileParseVectors(inFile, sim, numRemainingVector); 00878 if (ioStatus == 0) { /* Error case */ 00879 Sim_SimFree(sim); 00880 fclose(inFile); 00881 if (outputFile != NIL(char)) { 00882 fclose(outFile); 00883 } 00884 return(0); 00885 } 00886 00887 00888 /*************************** SIMULATION ****************************/ 00889 00890 Sim_SimSimulate(sim); 00891 00892 /******************* Print Simulation Vectors **********************/ 00893 00894 Sim_SimPrint(sim, outFile, printFlag, printInputsFlag, 00895 printOutputsFlag, printPseudoInputsFlag, 00896 printStatesFlag); 00897 printFlag = 0; 00898 00899 Sim_SimReset(sim); 00900 numRemainingVector -= packet; 00901 } while(ioStatus != 2 && (num == 0 || numRemainingVector > 0)); 00902 00903 Sim_SimFree(sim); 00904 fclose(inFile); 00905 if (outputFile != NIL(char)) { 00906 fclose(outFile); 00907 } 00908 return(1); 00909 } 00910 00911 /*---------------------------------------------------------------------------*/ 00912 /* Definition of static functions */ 00913 /*---------------------------------------------------------------------------*/ 00914 01078 static int 01079 CommandSimulate( 01080 Hrc_Manager_t ** hmgr, 01081 int argc, 01082 char ** argv) 01083 { 01084 int c; 01085 unsigned int i; 01086 long startTime = 0; 01087 long endTime = 0; 01088 long cpuTime = 0; 01089 int numberVector = 0; 01090 FILE *inputFp = NIL(FILE); 01091 Sim_PseudoSrc pseudoInputSource = Sim_Undef_c; /* default */ 01092 boolean verbose = FALSE; /* default */ 01093 char *inputFile = NIL(char); 01094 char *outputFile = NIL(char); 01095 Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr); 01096 int printInputsFlag = 1; /*default*/ 01097 int printOutputsFlag = 1;/*default*/ 01098 int printPseudoInputsFlag = 1;/*default*/ 01099 int printStatesFlag = 1;/*default*/ 01100 01101 /* 01102 * Parse command line options. 01103 */ 01104 01105 util_getopt_reset(); 01106 while ((c = util_getopt(argc, argv, "I:O:P:S:hvi:o:n:p:s")) != EOF) { 01107 switch(c) { 01108 case 'I': 01109 printInputsFlag = atoi(util_optarg); 01110 break; 01111 case 'O': 01112 printOutputsFlag = atoi(util_optarg); 01113 break; 01114 case 'P': 01115 printPseudoInputsFlag = atoi(util_optarg); 01116 break; 01117 case 'S': 01118 printStatesFlag = atoi(util_optarg); 01119 break; 01120 case 'h': 01121 goto usage; 01122 case 'i': 01123 inputFile = util_optarg; 01124 break; 01125 case 'n': 01126 for (i = 0; i < strlen(util_optarg); i++) { 01127 if (!isdigit((int)util_optarg[i])) { 01128 goto usage; 01129 } 01130 } 01131 numberVector = atoi(util_optarg); 01132 break; 01133 case 'o': 01134 outputFile = util_optarg; 01135 break; 01136 case 'p': 01137 if (!strcmp("0", util_optarg)) { 01138 pseudoInputSource = Sim_User_c; 01139 } 01140 else if (!strcmp("1", util_optarg)) { 01141 pseudoInputSource = Sim_Random_c; 01142 } 01143 else if (!strcmp("2", util_optarg)) { 01144 pseudoInputSource = Sim_First_c; 01145 } 01146 else { 01147 goto usage; 01148 } 01149 break; 01150 case 'v': 01151 verbose = 1; 01152 break; 01153 default: 01154 goto usage; 01155 } 01156 } 01157 01158 if (network == NIL(Ntk_Network_t)) { 01159 return 1; 01160 } 01161 01162 if (Ord_NetworkTestAreVariablesOrdered(network,Ord_InputAndLatch_c) == FALSE){ 01163 (void) fprintf(vis_stdout, "The MDD variables have not been ordered. Use static_order.\n"); 01164 return 1; 01165 } 01166 01167 if (Part_NetworkReadPartition(network) == NIL(graph_t)) { 01168 (void) fprintf(vis_stderr, "Network has not been partitioned. Use build_partition_mdds.\n"); 01169 return 1; 01170 } 01171 01173 util_srandom(SimComputeRandomInteger()); 01174 01175 /* Parameters verification */ 01176 01177 if (numberVector <= 0 && inputFile == NIL(char)) { 01178 (void) fprintf(vis_stderr, "Simulate: specify an input file with -i or use -n option to set\n"); 01179 (void) fprintf(vis_stderr, "the number of vectors randomly generated\n"); 01180 return(1); 01181 } 01182 if (pseudoInputSource == Sim_User_c && inputFile == NIL(char)) { 01183 (void) fprintf(vis_stderr, "Simulate: '-p 0' option and random vectors\n"); 01184 (void) fprintf(vis_stderr, " generation are incompatible\n"); 01185 return(1); 01186 } 01187 if ((pseudoInputSource != Sim_Undef_c) && inputFile != NIL(char)) { 01188 (void) fprintf(vis_stderr, "Simulate: '-p' option is available only if vectors\n"); 01189 (void) fprintf(vis_stderr, " are generated randomly.\n"); 01190 return(1); 01191 } 01192 01193 if (numberVector == 0 && inputFile == NIL(char)) { 01194 (void) fprintf(vis_stderr, "Simulate: number of vectors not specified.\nUsing 10 random vectors\n"); 01195 numberVector = 10; 01196 } 01197 if (inputFile != NIL(char)) { 01198 inputFp = Cmd_FileOpen(inputFile, "r", NIL(char *), 0); 01199 if (inputFp == NIL(FILE)) { 01200 return (1); 01201 } 01202 } 01203 01204 /* CPU-Time print with verbose option */ 01205 if (verbose) { 01206 startTime = util_cpu_time(); 01207 } 01208 01209 01210 /************** Random Vectors generation **************/ 01211 error_init(); 01212 01213 if (inputFile == NIL(char)) { 01214 if (SimRandomSimulateAndPrint(network, numberVector, outputFile, 01215 pseudoInputSource, printInputsFlag, 01216 printOutputsFlag, 01217 printPseudoInputsFlag, 01218 printStatesFlag, 01219 verbose) == 0) { 01220 (void) fprintf(vis_stdout, "%s", error_string()); 01221 return (1); 01222 } 01223 } 01224 01225 /************* Read vectors from a file ***************/ 01226 01227 else { 01228 if (SimFileSimulateAndPrint(network, numberVector, inputFile, outputFile, 01229 pseudoInputSource, printInputsFlag, 01230 printOutputsFlag, printPseudoInputsFlag, 01231 printStatesFlag, verbose) == 0) { 01232 (void) fprintf(vis_stdout, "%s", error_string()); 01233 return(1); 01234 } 01235 } 01236 01237 if (verbose) { 01238 endTime = util_cpu_time(); 01239 cpuTime = endTime - startTime; 01240 (void) fprintf(vis_stdout, "====> Simulation time: %d ms\n", (int)cpuTime); 01241 } 01242 01243 return 0; /* normal exit */ 01244 01245 usage: 01246 (void) fprintf(vis_stderr, "usage: simulate [-I <0/1>][-O <0/1>][-P <0/1>][-S <0/1>][-h][-i vectors_file]\n"); 01247 (void) fprintf(vis_stderr, " [-n number-vectors][-o output_file][-p <0/1/2>] [-v]\n"); 01248 01249 (void) fprintf(vis_stderr, " -I <0/1>\t\tControls printing of primary input variables\n"); 01250 (void) fprintf(vis_stderr, " \t\t(0:no print, 1:print, default is 1)\n"); 01251 (void) fprintf(vis_stderr, " -O <0/1>\t\tControls printing of output variables\n"); 01252 (void) fprintf(vis_stderr, " \t\t(0:no print, 1:print, default is 1)\n"); 01253 (void) fprintf(vis_stderr, " -P <0/1>\t\tControls printing of pseudo input variables\n"); 01254 (void) fprintf(vis_stderr, " \t\t(0:no print, 1:print, default is 1)\n"); 01255 (void) fprintf(vis_stderr, " -S <0/1>\t\tControls printing of state variables\n"); 01256 (void) fprintf(vis_stderr, " \t\t(0:no print, 1:print, default is 1)\n"); 01257 (void) fprintf(vis_stderr, " -h \tPrints this usage message.\n"); 01258 (void) fprintf(vis_stderr, " -i <vectors_file>\tThe input file containing simulation vectors.\n"); 01259 (void) fprintf(vis_stderr, " \tIf not specified, N vectors are generated randomly.\n"); 01260 (void) fprintf(vis_stderr, " \tN is given by the option '-n'.\n"); 01261 (void) fprintf(vis_stderr, " -n <N>\t\tWith this option, only the first N vectors\n"); 01262 (void) fprintf(vis_stderr, " \t\twill be simulated. If '-i' option is not used,\n"); 01263 (void) fprintf(vis_stderr, " \t\tN is the number of random vectors.\n"); 01264 (void) fprintf(vis_stderr, " -o <output_file>\tThe output file. If not specified, the output\n"); 01265 (void) fprintf(vis_stderr, " \twill be directed to stdout.\n"); 01266 (void) fprintf(vis_stderr, " -p <0|1|2>\t\tIf 0 : non-deterministic cases are treated\n"); 01267 (void) fprintf(vis_stderr, " \t\tas specified by user.\n"); 01268 (void) fprintf(vis_stderr, " \t\tIf 1: non-deterministic cases are treated randomly.\n"); 01269 (void) fprintf(vis_stderr, " \t\tIf 2: non-deterministic cases are treated by\n"); 01270 (void) fprintf(vis_stderr, " \t\tchoosing the first possibility.\n"); 01271 (void) fprintf(vis_stderr, " -v \tVerbose. Print CPU time usage.\n"); 01272 01273 return 1; /* error exit */ 01274 } 01275 01276 01290 static int 01291 EvaluateBinaryFunction( 01292 mdd_t * functionMdd, 01293 mdd_t * vectorMdd) 01294 { 01295 mdd_t * result = mdd_cofactor_minterm(functionMdd, vectorMdd); 01296 01297 if (mdd_is_tautology(result, 1)) { 01298 mdd_free(result); 01299 return (1); 01300 } 01301 else if (mdd_is_tautology(result, 0)) { 01302 mdd_free(result); 01303 return (0); 01304 } 01305 else { 01306 mdd_free(result); 01307 return (-1); 01308 } 01309 } 01310 01311 01321 static int 01322 NodeLexCmp( 01323 const void *node1, 01324 const void *node2) 01325 { 01326 char *name1 = Ntk_NodeReadName(*(Ntk_Node_t **)node1); 01327 char *name2 = Ntk_NodeReadName(*(Ntk_Node_t **)node2); 01328 01329 return strcmp(name1, name2); 01330 } 01331 01341 static mdd_t * 01342 StatesMddFromVector( 01343 Sim_Sim_t * sim, 01344 mdd_manager *mddManager 01345 ) 01346 01347 { 01348 int i, j; 01349 array_t *vector; 01350 Ntk_Node_t *node; 01351 mdd_t *state, *simStates, *tmp, *mddLiteral; 01352 int value; 01353 array_t *valueArray; 01354 int mddId; 01355 01356 /* start with zero */ 01357 simStates = mdd_zero(mddManager); 01358 valueArray = array_alloc(int, 1); 01359 for (i = 0; i < array_n(sim->vectorArray); i++) { 01360 /* add every state in the vector */ 01361 vector = array_fetch(array_t *, sim->vectorArray, i); 01362 state = mdd_one(mddManager); 01363 for (j = sim->currentStateHead; j < sim->internalPartitionHead; j++){ 01364 /* Build the state */ 01365 node = array_fetch(Ntk_Node_t *, sim->nodesArray, j); 01366 mddId = Ntk_NodeReadMddId(node); 01367 value = array_fetch(int, vector, j); 01368 array_insert(int, valueArray, 0, value); 01369 mddLiteral = mdd_literal(mddManager, mddId, valueArray); 01370 01371 tmp = mdd_and(state, mddLiteral, 1, 1); 01372 mdd_free(state); 01373 mdd_free(mddLiteral); 01374 state = tmp; 01375 } 01376 01377 tmp = mdd_or(simStates, state, 1, 1); 01378 mdd_free(simStates); 01379 mdd_free(state); 01380 simStates = tmp; 01381 01382 } 01383 array_free(valueArray); 01384 return simStates; 01385 } /* end of StatesMddFromVector */ 01386 01387 01399 static void 01400 GenerateInitState( 01401 Sim_Sim_t * sim, boolean random) 01402 { 01403 int i; 01404 array_t *mvfArray; 01405 array_t *initState = array_alloc(int, 0); 01406 array_t *nodesArray = sim->nodesArray; 01407 array_t *vectorArray = sim->vectorArray; 01408 array_t *firstVector = array_fetch(array_t *, vectorArray, 0); 01409 st_table *leaves = st_init_table(st_ptrcmp, st_ptrhash); 01410 int numLatches = sim->internalPartitionHead - sim->currentStateHead; 01411 array_t *rootArray = array_alloc(Ntk_Node_t *, numLatches); 01412 01413 /* Free old initState */ 01414 if (sim->initState != NIL(array_t)) { 01415 array_free(sim->initState); 01416 } 01417 sim->initState = initState; 01418 01419 /* 01420 * Load a symbol table with the initial values of the primary and pseudo 01421 * inputs. 01422 */ 01423 for (i = 0; i < sim->currentStateHead; i++) { 01424 Ntk_Node_t *node = array_fetch(Ntk_Node_t *, nodesArray, i); 01425 if (random) { 01426 int value = array_fetch(int, firstVector, i); 01427 st_insert(leaves, (char *) node, (char *) (long) value); 01428 } else { 01429 st_insert(leaves, (char *) node, (char *) (long) NTM_UNUSED); 01430 } 01431 } 01432 01433 /* 01434 * Create an array containing the initialization function for all the 01435 * latches. This array has the same order as the simulation vector. 01436 */ 01437 for (i = sim->currentStateHead; i < sim->internalPartitionHead; i++) { 01438 Ntk_Node_t *latch = array_fetch(Ntk_Node_t *, nodesArray, i); 01439 Ntk_Node_t *initNode = Ntk_LatchReadInitialInput(latch); 01440 01441 array_insert_last(Ntk_Node_t *, rootArray, initNode); 01442 } 01443 01444 /* 01445 * Build the MVFs for the initialization functions, using the initial input 01446 * values. 01447 */ 01448 mvfArray = Ntm_NetworkBuildMvfs(sim->network, rootArray, leaves, NIL(mdd_t)); 01449 array_free(rootArray); 01450 st_free_table(leaves); 01451 01452 /* 01453 * Get the initial value of each latch from the MVF of the corresponding 01454 * initialization function. Since the initialization functions are in terms 01455 * of primary and pseudo input values, and we have completely specified 01456 * values for all inputs, each initialization function should have evaluated 01457 * to a constant (i.e. exactly one non-zero component, and that component is 01458 * the tautology. 01459 */ 01460 for (i = 0; i < numLatches; i++) { 01461 int j; 01462 int value = 0; /* initialized to avoid lint complaint */ 01463 Mvf_Function_t *initMvf; 01464 mdd_t *component; 01465 int numNonZero = 0; 01466 01467 initMvf = array_fetch(Mvf_Function_t *, mvfArray, i); 01468 Mvf_FunctionForEachComponent(initMvf, j, component) { 01469 if (!mdd_is_tautology(component, 0)) { 01470 assert(mdd_is_tautology(component, 1)); 01471 numNonZero++; 01472 value = j; 01473 } 01474 } 01475 01476 assert(numNonZero == 1); 01477 array_insert_last(int, initState, value); 01478 } 01479 01480 Mvf_FunctionArrayFree(mvfArray); 01481 return; 01482 } /* end of GenerateInitState */ 01483