VIS
|
00001 00032 #include "fsmInt.h" 00033 00034 static char rcsid[] UNUSED = "$Id: fsmFsm.c,v 1.88 2007/04/02 17:03:13 hhkim Exp $"; 00035 00038 /*---------------------------------------------------------------------------*/ 00039 /* Static function prototypes */ 00040 /*---------------------------------------------------------------------------*/ 00041 00042 static Fsm_Fsm_t * FsmStructAlloc(Ntk_Network_t *network, graph_t *partition); 00043 static void FsmCreateVariableCubes(Fsm_Fsm_t *fsm); 00044 static int nameCompare(const void * name1, const void * name2); 00045 static boolean VarIdArrayCompare(mdd_manager *mddMgr, array_t *vars1, array_t *vars2); 00046 static boolean NSFunctionNamesCompare(mdd_manager *mddMgr, array_t *names1, array_t *names2); 00047 static array_t * GetMddSupportIdArray(Fsm_Fsm_t *fsm, st_table *mddIdTable, st_table *pseudoMddIdTable); 00048 00052 /*---------------------------------------------------------------------------*/ 00053 /* Definition of exported functions */ 00054 /*---------------------------------------------------------------------------*/ 00055 00084 Fsm_Fsm_t * 00085 Fsm_FsmCreateFromNetworkWithPartition( 00086 Ntk_Network_t *network, 00087 graph_t *partition) 00088 { 00089 lsGen gen; 00090 Ntk_Node_t *latch; 00091 Ntk_Node_t *input; 00092 Fsm_Fsm_t *fsm; 00093 int i; 00094 00095 fsm = FsmStructAlloc(network, partition); 00096 if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t); 00097 fsm->fairnessInfo.constraint = FsmFsmCreateDefaultFairnessConstraint(fsm); 00098 00099 /* sort by name of latch */ 00100 Ntk_NetworkForEachLatch(network, gen, latch){ 00101 array_insert_last(char*, fsm->fsmData.nextStateFunctions, 00102 Ntk_NodeReadName(latch)); 00103 } 00104 00105 array_sort(fsm->fsmData.nextStateFunctions, nameCompare); 00106 00107 for (i = 0; i < array_n(fsm->fsmData.nextStateFunctions); i ++) { 00108 char *nodeName; 00109 nodeName = array_fetch(char *, fsm->fsmData.nextStateFunctions, i); 00110 latch = Ntk_NetworkFindNodeByName(network, nodeName); 00111 array_insert(char*, fsm->fsmData.nextStateFunctions, i, 00112 Ntk_NodeReadName(Ntk_LatchReadDataInput(latch))); 00113 array_insert_last(int, fsm->fsmData.presentStateVars, 00114 Ntk_NodeReadMddId(latch)); 00115 array_insert_last(int, fsm->fsmData.nextStateVars, 00116 Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch))); 00117 } 00118 00119 Ntk_NetworkForEachInput(network, gen, input){ 00120 array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(input)); 00121 } 00122 00123 FsmCreateVariableCubes(fsm); 00124 return (fsm); 00125 } 00126 00127 00128 00149 Fsm_Fsm_t * 00150 Fsm_FsmCreateReducedFsm( 00151 Ntk_Network_t *network, 00152 graph_t *partition, 00153 array_t *latches, 00154 array_t *inputs, 00155 array_t *fairArray) 00156 { 00157 Ntk_Node_t *latch; 00158 Ntk_Node_t *input; 00159 Fsm_Fsm_t *fsm; 00160 Fsm_Fairness_t *fairness; 00161 int i,j; 00162 00163 if (array_n(latches) == 0){ 00164 error_append("Number of latches passed = 0. Cannot create sub-FSM."); 00165 return (NIL(Fsm_Fsm_t)); 00166 } 00167 00168 fsm = FsmStructAlloc(network, partition); 00169 if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t); 00170 00171 /* initialize fairness constraints */ 00172 if (fairArray != NIL(array_t)){ 00173 fairness = FsmFairnessAlloc(fsm); 00174 for (j = 0; j < array_n(fairArray); j++) { 00175 Ctlp_Formula_t *formula = array_fetch(Ctlp_Formula_t *, fairArray, j); 00176 00177 FsmFairnessAddConjunct(fairness, formula, NIL(Ctlp_Formula_t), 0, j); 00178 } 00179 fsm->fairnessInfo.constraint = fairness; 00180 } 00181 else { 00182 fsm->fairnessInfo.constraint = 00183 FsmFsmCreateDefaultFairnessConstraint(fsm); 00184 } 00185 00186 /* sort latches by name */ 00187 for(i=0; i<array_n(latches); i++){ 00188 latch = array_fetch(Ntk_Node_t*, latches, i); 00189 array_insert_last(char*, fsm->fsmData.nextStateFunctions, 00190 Ntk_NodeReadName(latch)); 00191 } 00192 array_sort(fsm->fsmData.nextStateFunctions, nameCompare); 00193 00194 for(i=0; i<array_n(latches); i++){ 00195 char *nodeName; 00196 nodeName = array_fetch(char *, fsm->fsmData.nextStateFunctions, i); 00197 latch = Ntk_NetworkFindNodeByName(network, nodeName); 00198 array_insert_last(int, fsm->fsmData.presentStateVars, 00199 Ntk_NodeReadMddId(latch)); 00200 array_insert_last(int, fsm->fsmData.nextStateVars, 00201 Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch))); 00202 array_insert(char*, fsm->fsmData.nextStateFunctions, i, 00203 Ntk_NodeReadName(Ntk_LatchReadDataInput(latch))); 00204 } 00205 00206 for(i=0; i<array_n(inputs); i++){ 00207 input = array_fetch(Ntk_Node_t*, inputs, i); 00208 array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(input)); 00209 } 00210 00211 FsmCreateVariableCubes(fsm); 00212 return (fsm); 00213 } 00214 00255 Fsm_Fsm_t * 00256 Fsm_FsmCreateAbstractFsm( 00257 Ntk_Network_t *network, 00258 graph_t *partition, 00259 array_t *latches, 00260 array_t *invisibleVars, 00261 array_t *inputs, 00262 array_t *fairArray, 00263 boolean independentFlag) 00264 { 00265 Ntk_Node_t *latch; 00266 Ntk_Node_t *input; 00267 Ntk_Node_t *node; 00268 Fsm_Fsm_t *fsm; 00269 Fsm_Fairness_t *fairness; 00270 int i,j; 00271 00272 if (FALSE && array_n(latches) == 0){ 00273 error_append("Number of latches passed = 0. Cannot create sub-FSM."); 00274 return (NIL(Fsm_Fsm_t)); 00275 } 00276 00277 fsm = FsmStructAlloc(network, partition); 00278 if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t); 00279 00280 /* initialize fairness constraints */ 00281 if (fairArray != NIL(array_t)){ 00282 fairness = FsmFairnessAlloc(fsm); 00283 for (j = 0; j < array_n(fairArray); j++) { 00284 Ctlp_Formula_t *formula = array_fetch(Ctlp_Formula_t *, fairArray, j); 00285 00286 FsmFairnessAddConjunct(fairness, formula, NIL(Ctlp_Formula_t), 0, j); 00287 } 00288 fsm->fairnessInfo.constraint = fairness; 00289 } 00290 else { 00291 fsm->fairnessInfo.constraint = 00292 FsmFsmCreateDefaultFairnessConstraint(fsm); 00293 } 00294 00295 /* when independentFlag==FALSE, use globalPsVars and 00296 * primaryInputVars (instead of presentStateVars and inputVars) to 00297 * build the transition relation 00298 */ 00299 if (!independentFlag) { 00300 fsm->fsmData.globalPsVars = array_alloc(int, 0); 00301 fsm->fsmData.primaryInputVars = array_alloc(int, 0); 00302 } 00303 00304 00305 /* sort latches by name */ 00306 for(i=0; i<array_n(latches); i++){ 00307 latch = array_fetch(Ntk_Node_t*, latches, i); 00308 array_insert_last(char*, fsm->fsmData.nextStateFunctions, 00309 Ntk_NodeReadName(latch)); 00310 } 00311 array_sort(fsm->fsmData.nextStateFunctions, nameCompare); 00312 00313 for(i=0; i<array_n(latches); i++){ 00314 char *nodeName; 00315 nodeName = array_fetch(char *, fsm->fsmData.nextStateFunctions, i); 00316 latch = Ntk_NetworkFindNodeByName(network, nodeName); 00317 array_insert_last(int, fsm->fsmData.presentStateVars, 00318 Ntk_NodeReadMddId(latch)); 00319 array_insert_last(int, fsm->fsmData.nextStateVars, 00320 Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch))); 00321 array_insert(char*, fsm->fsmData.nextStateFunctions, i, 00322 Ntk_NodeReadName(Ntk_LatchReadDataInput(latch))); 00323 00324 if (!independentFlag) 00325 array_insert_last(int, fsm->fsmData.globalPsVars, 00326 Ntk_NodeReadMddId(latch)); 00327 } 00328 00329 for(i=0; i<array_n(inputs); i++){ 00330 input = array_fetch(Ntk_Node_t*, inputs, i); 00331 array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(input)); 00332 00333 if (!independentFlag) 00334 array_insert_last(int, fsm->fsmData.primaryInputVars, 00335 Ntk_NodeReadMddId(input)); 00336 } 00337 00338 00339 arrayForEachItem(Ntk_Node_t *, invisibleVars, i, node) { 00340 array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(node)); 00341 00342 if (!independentFlag) { 00343 array_insert_last(int, fsm->fsmData.globalPsVars, 00344 Ntk_NodeReadMddId(node)); 00345 } 00346 } 00347 00348 00349 FsmCreateVariableCubes(fsm); 00350 return (fsm); 00351 } 00352 00353 00367 void 00368 Fsm_FsmFree( 00369 Fsm_Fsm_t * fsm) 00370 { 00371 Part_PartitionFree(fsm->partition); 00372 Fsm_FsmSubsystemFree(fsm); 00373 } 00374 00386 void 00387 Fsm_FsmSubsystemFree( 00388 Fsm_Fsm_t * fsm) 00389 { 00390 00391 Fsm_FsmFreeImageInfo(fsm); 00392 00393 /* Free reachability info. */ 00394 if (fsm->reachabilityInfo.initialStates != NIL(mdd_t)){ 00395 mdd_free(fsm->reachabilityInfo.initialStates); 00396 } 00397 if (fsm->reachabilityInfo.reachableStates != NIL(mdd_t)){ 00398 mdd_free(fsm->reachabilityInfo.reachableStates); 00399 } 00400 if (fsm->reachabilityInfo.apprReachableStates != NIL(array_t)) 00401 mdd_array_free(fsm->reachabilityInfo.apprReachableStates); 00402 if (fsm->reachabilityInfo.subPsVars != NIL(array_t)){ 00403 int i; 00404 array_t *psVars; 00405 arrayForEachItem(array_t *, fsm->reachabilityInfo.subPsVars, i, psVars) { 00406 array_free(psVars); 00407 } 00408 array_free(fsm->reachabilityInfo.subPsVars); 00409 } 00410 if (Fsm_FsmReadReachabilityOnionRings(fsm) != NIL(array_t)){ 00411 mdd_array_free(Fsm_FsmReadReachabilityOnionRings(fsm)); 00412 } 00413 00414 /* Free fairness info. */ 00415 FsmFsmFairnessInfoUpdate(fsm, NIL(mdd_t), NIL(Fsm_Fairness_t), NIL(array_t)); 00416 00417 array_free(fsm->fsmData.presentStateVars); 00418 array_free(fsm->fsmData.nextStateVars); 00419 array_free(fsm->fsmData.inputVars); 00420 array_free(fsm->fsmData.nextStateFunctions); 00421 if (fsm->fsmData.pseudoInputVars) 00422 array_free(fsm->fsmData.pseudoInputVars); 00423 if (fsm->fsmData.primaryInputVars) 00424 array_free(fsm->fsmData.primaryInputVars); 00425 if (fsm->fsmData.globalPsVars) 00426 array_free(fsm->fsmData.globalPsVars); 00427 00428 if (fsm->fsmData.presentStateCube) 00429 mdd_free(fsm->fsmData.presentStateCube); 00430 if (fsm->fsmData.nextStateCube) 00431 mdd_free(fsm->fsmData.nextStateCube); 00432 if (fsm->fsmData.inputCube) 00433 mdd_free(fsm->fsmData.inputCube); 00434 if (fsm->fsmData.pseudoInputCube) 00435 mdd_free(fsm->fsmData.pseudoInputCube); 00436 if (fsm->fsmData.primaryInputCube) 00437 mdd_free(fsm->fsmData.primaryInputCube); 00438 if (fsm->fsmData.globalPsCube) 00439 mdd_free(fsm->fsmData.globalPsCube); 00440 00441 if (fsm->fsmData.pseudoInputBddVars) 00442 mdd_array_free(fsm->fsmData.pseudoInputBddVars); 00443 if (fsm->fsmData.presentStateBddVars) 00444 mdd_array_free(fsm->fsmData.presentStateBddVars); 00445 00446 FREE(fsm); 00447 } 00448 00462 void 00463 Fsm_FsmFreeCallback( 00464 void * data /* an object of type Fsm_Fsm_t* type casted to void* */) 00465 { 00466 Fsm_FsmFree((Fsm_Fsm_t *) data); 00467 } 00468 00469 00479 Ntk_Network_t * 00480 Fsm_FsmReadNetwork( 00481 Fsm_Fsm_t * fsm) 00482 { 00483 return (fsm->network); 00484 } 00485 00497 boolean 00498 Fsm_FsmReadUseUnquantifiedFlag( 00499 Fsm_Fsm_t * fsm) 00500 { 00501 return (fsm->useUnquantifiedFlag); 00502 } 00503 00513 mdd_manager * 00514 Fsm_FsmReadMddManager( 00515 Fsm_Fsm_t * fsm) 00516 { 00517 return (Ntk_NetworkReadMddManager(fsm->network)); 00518 } 00519 00520 00537 Fsm_Fsm_t * 00538 Fsm_NetworkReadOrCreateFsm( 00539 Ntk_Network_t * network) 00540 { 00541 Fsm_Fsm_t *fsm = (Fsm_Fsm_t*) Ntk_NetworkReadApplInfo(network, FSM_NETWORK_APPL_KEY); 00542 00543 if (fsm == NIL(Fsm_Fsm_t)) { 00544 fsm = Fsm_FsmCreateFromNetworkWithPartition(network, NIL(graph_t)); 00545 if (fsm != NIL(Fsm_Fsm_t)) { 00546 (void) Ntk_NetworkAddApplInfo(network, FSM_NETWORK_APPL_KEY, 00547 (Ntk_ApplInfoFreeFn) Fsm_FsmFreeCallback, 00548 (void *) fsm); 00549 } 00550 } 00551 00552 return fsm; 00553 } 00554 00555 00568 Fsm_Fsm_t * 00569 Fsm_NetworkReadFsm( 00570 Ntk_Network_t * network) 00571 { 00572 return ((Fsm_Fsm_t*) Ntk_NetworkReadApplInfo(network, 00573 FSM_NETWORK_APPL_KEY)); 00574 } 00575 00576 00589 Img_ImageInfo_t * 00590 Fsm_FsmReadImageInfo( 00591 Fsm_Fsm_t *fsm) 00592 { 00593 return (fsm->imageInfo); 00594 } 00595 00607 void 00608 Fsm_FsmSetImageInfo( 00609 Fsm_Fsm_t *fsm, Img_ImageInfo_t *imageInfo) 00610 { 00611 fsm->imageInfo = imageInfo; 00612 } 00613 00626 void 00627 Fsm_FsmFreeImageInfo( 00628 Fsm_Fsm_t *fsm) 00629 { 00630 if(fsm->imageInfo) { 00631 Img_ImageInfoFree(fsm->imageInfo); 00632 fsm->imageInfo = NIL(Img_ImageInfo_t); 00633 } 00634 00635 if(fsm->unquantifiedImageInfo) { 00636 Img_ImageInfoFree(fsm->unquantifiedImageInfo); 00637 fsm->unquantifiedImageInfo = NIL(Img_ImageInfo_t); 00638 } 00639 } 00640 00653 graph_t * 00654 Fsm_FsmReadPartition( 00655 Fsm_Fsm_t *fsm) 00656 { 00657 return (fsm->partition); 00658 } 00659 00671 boolean 00672 Fsm_FsmTestIsReachabilityDone( 00673 Fsm_Fsm_t *fsm) 00674 { 00675 00676 if (Fsm_FsmReadReachableStates(fsm) != NIL(mdd_t)) { 00677 return TRUE; 00678 } 00679 return FALSE; 00680 } 00681 00694 boolean 00695 Fsm_FsmTestIsOverApproximateReachabilityDone( 00696 Fsm_Fsm_t *fsm) 00697 { 00698 00699 if (Fsm_FsmReadOverApproximateReachableStates(fsm) != NIL(array_t)) { 00700 return TRUE; 00701 } 00702 return FALSE; 00703 } 00704 00705 00715 mdd_t * 00716 Fsm_FsmReadReachableStates( 00717 Fsm_Fsm_t *fsm) 00718 { 00719 if (fsm->reachabilityInfo.rchStatus == Fsm_Rch_Exact_c) 00720 return(fsm->reachabilityInfo.reachableStates); 00721 else 00722 return(NIL(mdd_t)); 00723 } 00724 00725 00736 mdd_t * 00737 Fsm_FsmReadCurrentReachableStates( 00738 Fsm_Fsm_t *fsm) 00739 { 00740 return(fsm->reachabilityInfo.reachableStates); 00741 } 00742 00743 00753 array_t * 00754 Fsm_FsmReadOverApproximateReachableStates( 00755 Fsm_Fsm_t *fsm) 00756 { 00757 if (fsm->reachabilityInfo.overApprox >= 2) 00758 return(fsm->reachabilityInfo.apprReachableStates); 00759 else 00760 return(NIL(array_t)); 00761 } 00762 00763 00773 array_t * 00774 Fsm_FsmReadCurrentOverApproximateReachableStates( 00775 Fsm_Fsm_t *fsm) 00776 { 00777 return(fsm->reachabilityInfo.apprReachableStates); 00778 } 00779 00793 array_t * 00794 Fsm_FsmReadReachabilityOnionRings( 00795 Fsm_Fsm_t *fsm) 00796 { 00797 return fsm->reachabilityInfo.onionRings; 00798 } 00799 00814 boolean 00815 Fsm_FsmReachabilityOnionRingsStates( 00816 Fsm_Fsm_t *fsm, 00817 mdd_t ** result) 00818 { 00819 int i; 00820 mdd_t *tmpMdd; 00821 mdd_t *ring; 00822 array_t *onionRings; 00823 00824 onionRings = Fsm_FsmReadReachabilityOnionRings(fsm); 00825 if ( onionRings == NIL(array_t) ) { 00826 *result = NIL(mdd_t); 00827 return 0; 00828 } 00829 00830 *result = bdd_zero(Fsm_FsmReadMddManager(fsm)); 00831 arrayForEachItem(mdd_t *, onionRings, i, ring) { 00832 tmpMdd = mdd_or(*result, ring, 1, 1); 00833 mdd_free(*result); 00834 *result = tmpMdd; 00835 } 00836 if (Fsm_FsmReadCurrentReachableStates(fsm)) { 00837 if (mdd_lequal(Fsm_FsmReadCurrentReachableStates(fsm), *result, 1,1)) { 00838 FsmSetReachabilityOnionRingsUpToDateFlag(fsm, TRUE); 00839 } 00840 } 00841 return (Fsm_FsmTestReachabilityOnionRingsUpToDate(fsm)); 00842 } 00843 00857 boolean 00858 Fsm_FsmTestReachabilityOnionRingsUpToDate( 00859 Fsm_Fsm_t *fsm) 00860 { 00861 return fsm->reachabilityInfo.onionRingsUpToDate; 00862 } 00863 00875 Fsm_RchType_t 00876 Fsm_FsmReadReachabilityOnionRingsMode( 00877 Fsm_Fsm_t *fsm) 00878 { 00879 return fsm->reachabilityInfo.onionRingsMode; 00880 } 00881 00882 00900 Img_ImageInfo_t * 00901 Fsm_FsmReadOrCreateImageInfo(Fsm_Fsm_t *fsm, int bwdImgFlag, int fwdImgFlag) 00902 { 00903 Img_DirectionType imgFlag = Img_Forward_c; 00904 array_t *presentStateVars, *inputVars; 00905 mdd_t *presentStateCube, *inputCube; 00906 00907 if (bwdImgFlag && fwdImgFlag) 00908 imgFlag = Img_Both_c; 00909 else if (bwdImgFlag) 00910 imgFlag = Img_Backward_c; 00911 00912 if (fsm->fsmData.globalPsVars) { 00913 presentStateVars = fsm->fsmData.globalPsVars; 00914 inputVars = fsm->fsmData.primaryInputVars; 00915 presentStateCube = fsm->fsmData.globalPsCube; 00916 inputCube = fsm->fsmData.primaryInputCube; 00917 } else { 00918 presentStateVars = fsm->fsmData.presentStateVars; 00919 inputVars = fsm->fsmData.inputVars; 00920 presentStateCube = fsm->fsmData.presentStateCube; 00921 inputCube = fsm->fsmData.inputCube; 00922 } 00923 00924 fsm->imageInfo = Img_ImageInfoInitialize(fsm->imageInfo, 00925 fsm->partition, 00926 fsm->fsmData.nextStateFunctions, 00927 presentStateVars, 00928 fsm->fsmData.nextStateVars, 00929 inputVars, 00930 presentStateCube, 00931 fsm->fsmData.nextStateCube, 00932 inputCube, 00933 fsm->network, 00934 Img_Default_c, imgFlag, 0, 0); 00935 00936 if (fsm->fsmData.globalPsVars) { 00937 Img_ImageInfoUpdateVariables(fsm->imageInfo, 00938 fsm->partition, 00939 fsm->fsmData.presentStateVars, 00940 fsm->fsmData.inputVars, 00941 fsm->fsmData.presentStateCube, 00942 fsm->fsmData.inputCube); 00943 } 00944 00945 return(fsm->imageInfo); 00946 } 00947 00966 Img_ImageInfo_t * 00967 Fsm_FsmReadOrCreateImageInfoFAFW(Fsm_Fsm_t *fsm, int bwdImgFlag, int fwdImgFlag) 00968 { 00969 Img_DirectionType imgFlag = Img_Forward_c; 00970 array_t *presentStateVars, *inputVars; 00971 mdd_t *presentStateCube, *inputCube; 00972 mdd_manager *mgr; 00973 00974 mgr = Fsm_FsmReadMddManager(fsm); 00975 00976 if (bwdImgFlag && fwdImgFlag) 00977 imgFlag = Img_Both_c; 00978 else if (bwdImgFlag) 00979 imgFlag = Img_Backward_c; 00980 00981 presentStateVars = fsm->fsmData.presentStateVars; 00982 inputVars = array_alloc(int , 0); 00983 presentStateCube = fsm->fsmData.presentStateCube; 00984 inputCube = mdd_one(mgr); 00985 00986 fsm->unquantifiedImageInfo = Img_ImageInfoInitialize( 00987 fsm->unquantifiedImageInfo, 00988 fsm->partition, 00989 fsm->fsmData.nextStateFunctions, 00990 presentStateVars, 00991 fsm->fsmData.nextStateVars, 00992 inputVars, 00993 presentStateCube, 00994 fsm->fsmData.nextStateCube, 00995 inputCube, 00996 fsm->network, 00997 Img_Default_c, imgFlag, 1, 0); 00998 00999 if(!Img_IsQuantifyArraySame(fsm->unquantifiedImageInfo, inputVars)) { 01000 array_free(inputVars); 01001 } 01002 01003 if(!Img_IsQuantifyCubeSame(fsm->unquantifiedImageInfo, inputCube)) { 01004 mdd_free(inputCube); 01005 } 01006 01007 return(fsm->unquantifiedImageInfo); 01008 } 01009 01028 Img_ImageInfo_t * 01029 Fsm_FsmReadOrCreateImageInfoPrunedFAFW(Fsm_Fsm_t *fsm, mdd_t *Winning, int bwdImgFlag, int fwdImgFlag) 01030 { 01031 Img_DirectionType imgFlag = Img_Forward_c; 01032 array_t *presentStateVars, *inputVars; 01033 mdd_t *presentStateCube, *inputCube; 01034 mdd_manager *mgr; 01035 Img_ImageInfo_t *imageInfo; 01036 01037 mgr = Fsm_FsmReadMddManager(fsm); 01038 01039 if (bwdImgFlag && fwdImgFlag) 01040 imgFlag = Img_Both_c; 01041 else if (bwdImgFlag) 01042 imgFlag = Img_Backward_c; 01043 01044 presentStateVars = fsm->fsmData.presentStateVars; 01045 inputVars = array_alloc(int , 0); 01046 presentStateCube = fsm->fsmData.presentStateCube; 01047 inputCube = mdd_one(mgr); 01048 01049 imageInfo = Img_ImageInfoInitialize( 01050 0, 01051 fsm->partition, 01052 fsm->fsmData.nextStateFunctions, 01053 presentStateVars, 01054 fsm->fsmData.nextStateVars, 01055 inputVars, 01056 presentStateCube, 01057 fsm->fsmData.nextStateCube, 01058 inputCube, 01059 fsm->network, 01060 Img_Default_c, imgFlag, 0, Winning); 01061 01062 if(!Img_IsQuantifyArraySame(imageInfo, inputVars)) { 01063 array_free(inputVars); 01064 } 01065 01066 if(!Img_IsQuantifyCubeSame(imageInfo, inputCube)) { 01067 mdd_free(inputCube); 01068 } 01069 01070 return(imageInfo); 01071 } 01072 01073 01092 Img_ImageInfo_t * 01093 Fsm_FsmReadOrCreateImageInfoForComputingRange(Fsm_Fsm_t *fsm, int bwdImgFlag, int fwdImgFlag) 01094 { 01095 Img_DirectionType imgFlag = Img_Forward_c; 01096 array_t *presentStateVars, *inputVars; 01097 mdd_t *presentStateCube, *inputCube; 01098 01099 if (bwdImgFlag && fwdImgFlag) 01100 imgFlag = Img_Both_c; 01101 else if (bwdImgFlag) 01102 imgFlag = Img_Backward_c; 01103 01104 if (fsm->fsmData.globalPsVars) { 01105 presentStateVars = fsm->fsmData.globalPsVars; 01106 inputVars = fsm->fsmData.primaryInputVars; 01107 presentStateCube = fsm->fsmData.globalPsCube; 01108 inputCube = fsm->fsmData.primaryInputCube; 01109 } else { 01110 presentStateVars = fsm->fsmData.presentStateVars; 01111 inputVars = fsm->fsmData.inputVars; 01112 presentStateCube = fsm->fsmData.presentStateCube; 01113 inputCube = fsm->fsmData.inputCube; 01114 } 01115 01116 fsm->imageInfo = Img_ImageInfoInitialize(fsm->imageInfo, 01117 fsm->partition, 01118 fsm->fsmData.nextStateFunctions, 01119 presentStateVars, 01120 fsm->fsmData.nextStateVars, 01121 inputVars, 01122 presentStateCube, 01123 fsm->fsmData.nextStateCube, 01124 inputCube, 01125 fsm->network, 01126 Img_Linear_Range_c, imgFlag, 0, 0); 01127 01128 if (fsm->fsmData.globalPsVars) { 01129 Img_ImageInfoUpdateVariables(fsm->imageInfo, 01130 fsm->partition, 01131 fsm->fsmData.presentStateVars, 01132 fsm->fsmData.inputVars, 01133 fsm->fsmData.presentStateCube, 01134 fsm->fsmData.inputCube); 01135 } 01136 01137 return(fsm->imageInfo); 01138 } 01139 01167 mdd_t * 01168 Fsm_FsmComputeInitialStates(Fsm_Fsm_t *fsm) 01169 { 01170 int i = 0; 01171 lsGen gen; 01172 mdd_t *initStates; 01173 Ntk_Node_t *node; 01174 array_t *initRelnArray; 01175 array_t *initMvfs; 01176 array_t *initNodes; 01177 array_t *initVertices; 01178 array_t *latchMddIds; 01179 st_table *supportNodes; 01180 st_table *supportVertices; 01181 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 01182 graph_t *partition = fsm->partition; 01183 Ntk_Network_t *network = fsm->network; 01184 int numLatches; 01185 array_t *psVars; 01186 Img_MethodType imageMethod; 01187 01188 /* If already computed, just return a copy. */ 01189 if (fsm->reachabilityInfo.initialStates != NIL(mdd_t)){ 01190 return (mdd_dup(fsm->reachabilityInfo.initialStates)); 01191 } 01192 01193 psVars = fsm->fsmData.presentStateVars; 01194 numLatches = array_n(psVars); 01195 01196 /* 01197 * Get the array of initial nodes, both as network nodes and as partition 01198 * vertices. 01199 */ 01200 initNodes = array_alloc(Ntk_Node_t *, numLatches); 01201 initVertices = array_alloc(vertex_t *, numLatches); 01202 latchMddIds = array_alloc(int, numLatches); 01203 for (i=0; i<numLatches; i++){ 01204 int latchMddId = array_fetch(int, psVars, i); 01205 Ntk_Node_t *latch = Ntk_NetworkFindNodeByMddId(network, latchMddId); 01206 Ntk_Node_t *initNode = Ntk_LatchReadInitialInput(latch); 01207 vertex_t *initVertex = Part_PartitionFindVertexByName(partition, 01208 Ntk_NodeReadName(initNode)); 01209 array_insert(Ntk_Node_t *, initNodes, i, initNode); 01210 array_insert(vertex_t *, initVertices, i, initVertex); 01211 array_insert(int, latchMddIds, i, Ntk_NodeReadMddId(latch)); 01212 } 01213 01214 /* 01215 * Get the table of legal support nodes, both as network nodes and 01216 * as partition vertices. Inputs (both primary and pseudo) and constants 01217 * constitute the legal support nodes. 01218 */ 01219 supportNodes = st_init_table(st_ptrcmp, st_ptrhash); 01220 supportVertices = st_init_table(st_ptrcmp, st_ptrhash); 01221 Ntk_NetworkForEachNode(network, gen, node) { 01222 vertex_t *vertex = Part_PartitionFindVertexByName(partition, 01223 Ntk_NodeReadName(node)); 01224 01225 if (Ntk_NodeTestIsConstant(node) || Ntk_NodeTestIsInput(node)) { 01226 st_insert(supportNodes, (char *) node, NIL(char)); 01227 st_insert(supportVertices, (char *) vertex, NIL(char)); 01228 } 01229 } 01230 01231 /* 01232 * If the initial nodes are not covered by the legal support nodes, then 01233 * return NIL. 01234 */ 01235 if (!Ntk_NetworkTestLeavesCoverSupportOfRoots(network, initNodes, 01236 supportNodes)) { 01237 array_free(initNodes); 01238 array_free(initVertices); 01239 array_free(latchMddIds); 01240 st_free_table(supportNodes); 01241 st_free_table(supportVertices); 01242 return NIL(mdd_t); 01243 } 01244 01245 /* 01246 * At this point, we are certain that the initialization functions are 01247 * well-defined. Get the MVF for each initialization node, in terms of the 01248 * support vertices. Note that the MVF for each initial node is guaranteed to 01249 * exist in the partition, since an initial node is a combinational 01250 * output. 01251 */ 01252 array_free(initNodes); 01253 st_free_table(supportNodes); 01254 initMvfs = Part_PartitionCollapse(partition, initVertices, 01255 supportVertices, NIL(mdd_t)); 01256 array_free(initVertices); 01257 st_free_table(supportVertices); 01258 01259 /* Compute the relation (x_i = g_i(u)) for each latch. */ 01260 initRelnArray = array_alloc(mdd_t*, numLatches); 01261 for (i = 0; i < numLatches; i++) { 01262 int latchMddId = array_fetch(int, latchMddIds, i); 01263 Mvf_Function_t *initMvf = array_fetch(Mvf_Function_t *, initMvfs, i); 01264 mdd_t *initLatchReln = Mvf_FunctionBuildRelationWithVariable(initMvf, 01265 latchMddId); 01266 array_insert(mdd_t *, initRelnArray, i, initLatchReln); 01267 } 01268 01269 array_free(latchMddIds); 01270 Mvf_FunctionArrayFree(initMvfs); 01271 01272 /* init_states(x) = \exists u \[\prod (x_i = g_i(u))\] */ 01273 /*initStates = Fsm_MddMultiwayAndSmooth(mddManager, initRelnArray, 01274 fsm->fsmData.inputVars); 01275 */ 01276 01277 imageMethod = Img_UserSpecifiedMethod(); 01278 if (imageMethod != Img_Iwls95_c && imageMethod != Img_Mlp_c) 01279 imageMethod = Img_Iwls95_c; 01280 initStates = Img_MultiwayLinearAndSmooth(mddManager, initRelnArray, 01281 fsm->fsmData.inputVars, psVars, 01282 imageMethod, Img_Forward_c); 01283 01284 mdd_array_free(initRelnArray); 01285 01286 fsm->reachabilityInfo.initialStates = initStates; 01287 return mdd_dup(initStates); 01288 } 01289 01290 01291 01306 array_t * 01307 Fsm_FsmReadPresentStateVars(Fsm_Fsm_t *fsm) 01308 { 01309 return fsm->fsmData.presentStateVars; 01310 } 01311 01326 array_t * 01327 Fsm_FsmReadNextStateVars(Fsm_Fsm_t *fsm) 01328 { 01329 return fsm->fsmData.nextStateVars; 01330 } 01331 01347 array_t * 01348 Fsm_FsmReadNextStateFunctionNames(Fsm_Fsm_t *fsm) 01349 { 01350 return fsm->fsmData.nextStateFunctions; 01351 } 01352 01368 array_t * 01369 Fsm_FsmReadInputVars(Fsm_Fsm_t *fsm) 01370 { 01371 return fsm->fsmData.inputVars; 01372 } 01373 01374 array_t * 01375 Fsm_FsmReadPrimaryInputVars(Fsm_Fsm_t *fsm) 01376 { 01377 return fsm->fsmData.primaryInputVars; 01378 } 01379 01380 01395 array_t * 01396 Fsm_FsmReadPseudoInputVars(Fsm_Fsm_t *fsm) 01397 { 01398 return fsm->fsmData.pseudoInputVars; 01399 } 01400 01412 void 01413 Fsm_FsmSetInputVars(Fsm_Fsm_t *fsm, array_t *inputVars) 01414 { 01415 fsm->fsmData.inputVars = inputVars; 01416 } 01417 01429 void 01430 Fsm_FsmSetUseUnquantifiedFlag(Fsm_Fsm_t *fsm, boolean value) 01431 { 01432 fsm->useUnquantifiedFlag = value; 01433 } 01434 01447 void 01448 Fsm_FsmSetInitialStates(Fsm_Fsm_t *fsm, mdd_t *initStates) 01449 { 01450 mdd_t *init; 01451 01452 init = fsm->reachabilityInfo.initialStates; 01453 if (init != NIL(mdd_t)) { 01454 mdd_free(init); 01455 } 01456 fsm->reachabilityInfo.initialStates = initStates; 01457 } 01458 01470 int 01471 Fsm_FsmReadFAFWFlag(Fsm_Fsm_t *fsm) 01472 { 01473 return((int)(fsm->FAFWFlag)); 01474 } 01475 01487 void 01488 Fsm_FsmSetFAFWFlag(Fsm_Fsm_t *fsm, boolean FAFWFlag) 01489 { 01490 fsm->FAFWFlag = FAFWFlag; 01491 } 01492 01505 void 01506 Fsm_FsmSetSystemVariableFAFW(Fsm_Fsm_t *fsm, st_table *bddIdTable) 01507 { 01508 mdd_manager *mgr; 01509 array_t *inputVars, *bddIdArray; 01510 bdd_t *extCube, *uniCube; 01511 bdd_t *newCube, *varBdd; 01512 st_generator *gen; 01513 int mddId, bddId, tbddId, i, j; 01514 01515 if(bddIdTable == 0 && fsm->FAFWFlag == 0) { 01516 if(fsm->extQuantifyInputCube) 01517 bdd_free(fsm->extQuantifyInputCube); 01518 if(fsm->uniQuantifyInputCube) 01519 bdd_free(fsm->uniQuantifyInputCube); 01520 fsm->extQuantifyInputCube = 0; 01521 fsm->uniQuantifyInputCube = 0; 01522 return; 01523 } 01524 01525 mgr = Fsm_FsmReadMddManager(fsm); 01526 inputVars = Fsm_FsmReadInputVars(fsm); 01527 01528 extCube = mdd_one(mgr); 01529 for(i=0; i<array_n(inputVars); i++) { 01530 mddId = array_fetch(int, inputVars, i); 01531 bddIdArray = mdd_id_to_bdd_id_array(mgr, mddId); 01532 for(j=0; j<array_n(bddIdArray); j++) { 01533 bddId = array_fetch(int, bddIdArray, j); 01534 if(bddIdTable && st_lookup_int(bddIdTable, (char *)(long)bddId, &tbddId)) { 01535 continue; 01536 } 01537 varBdd = bdd_get_variable(mgr, bddId); 01538 newCube = bdd_and(extCube, varBdd, 1, 1); 01539 bdd_free(extCube); bdd_free(varBdd); 01540 extCube = newCube; 01541 } 01542 array_free(bddIdArray); 01543 } 01544 uniCube = mdd_one(mgr); 01545 if(bddIdTable) { 01546 st_foreach_item(bddIdTable, gen, &bddId, &bddId) { 01547 varBdd = bdd_get_variable(mgr, bddId); 01548 newCube = bdd_and(uniCube, varBdd, 1, 1); 01549 bdd_free(uniCube); bdd_free(varBdd); 01550 uniCube = newCube; 01551 } 01552 } 01553 fsm->extQuantifyInputCube = extCube; 01554 fsm->uniQuantifyInputCube = uniCube; 01555 } 01556 01569 bdd_t * 01570 Fsm_FsmReadExtQuantifyInputCube(Fsm_Fsm_t *fsm) 01571 { 01572 return(fsm->extQuantifyInputCube); 01573 } 01574 01587 bdd_t * 01588 Fsm_FsmReadUniQuantifyInputCube(Fsm_Fsm_t *fsm) 01589 { 01590 return(fsm->uniQuantifyInputCube); 01591 } 01592 01611 Fsm_Fsm_t * 01612 Fsm_HrcManagerReadCurrentFsm(Hrc_Manager_t *hmgr) 01613 { 01614 Fsm_Fsm_t *fsm; 01615 Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(hmgr); 01616 01617 if (network == NIL(Ntk_Network_t)) { 01618 return NIL(Fsm_Fsm_t); 01619 } 01620 01621 if (Ord_NetworkTestAreVariablesOrdered(network, Ord_InputAndLatch_c) == FALSE) { 01622 (void) fprintf(vis_stderr, "** fsm error: The MDD variables have not been ordered. "); 01623 (void) fprintf(vis_stderr, "Use static_order.\n"); 01624 return NIL(Fsm_Fsm_t); 01625 } 01626 01627 if (Part_NetworkReadPartition(network) == NIL(graph_t)){ 01628 (void) fprintf(vis_stderr, "** fsm error: Network has not been partitioned. "); 01629 (void) fprintf(vis_stderr, "Use build_partition_mdds.\n"); 01630 return NIL(Fsm_Fsm_t); 01631 } 01632 01633 error_init(); 01634 fsm = Fsm_NetworkReadOrCreateFsm(network); 01635 if (fsm == NIL(Fsm_Fsm_t)) { 01636 (void) fprintf(vis_stderr, "%s", error_string()); 01637 (void) fprintf(vis_stderr, "\n"); 01638 } 01639 01640 return fsm; 01641 } 01642 01658 Fsm_Fsm_t * 01659 Fsm_FsmCreateSubsystemFromNetwork( 01660 Ntk_Network_t *network, 01661 graph_t *partition, 01662 st_table *vertexTable, 01663 boolean independentFlag, 01664 int createPseudoVarMode) 01665 { 01666 lsGen gen; 01667 Ntk_Node_t *latch; 01668 Ntk_Node_t *input; 01669 Fsm_Fsm_t *fsm; 01670 char *latchName; 01671 int i; 01672 st_table *pseudoMddIdTable = NIL(st_table); 01673 01674 fsm = FsmStructAlloc(network, partition); 01675 if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t); 01676 fsm->fairnessInfo.constraint = FsmFsmCreateDefaultFairnessConstraint(fsm); 01677 01678 /* 01679 * Creates an FSM for the subsystem. 01680 */ 01681 /* sort latches by name. */ 01682 Ntk_NetworkForEachLatch(network, gen, latch) { 01683 latchName = Ntk_NodeReadName(latch); 01684 if(st_lookup(vertexTable, latchName, (char **)0)) { 01685 array_insert_last(char*, fsm->fsmData.nextStateFunctions, latchName); 01686 } /* end of if(st_lookup(vertexTable)) */ 01687 } 01688 01689 if (independentFlag && createPseudoVarMode) { 01690 fsm->fsmData.pseudoInputVars = array_alloc(int, 0); 01691 fsm->fsmData.primaryInputVars = array_alloc(int, 0); 01692 fsm->fsmData.globalPsVars = array_alloc(int, 0); 01693 if (createPseudoVarMode == 2) 01694 pseudoMddIdTable = st_init_table(st_numcmp, st_numhash); 01695 } 01696 01697 array_sort(fsm->fsmData.nextStateFunctions, nameCompare); 01698 01699 arrayForEachItem(char *, fsm->fsmData.nextStateFunctions, i, latchName) { 01700 latch = Ntk_NetworkFindNodeByName(network, latchName); 01701 array_insert(char*, fsm->fsmData.nextStateFunctions, i, 01702 Ntk_NodeReadName(Ntk_LatchReadDataInput(latch))); 01703 array_insert_last(int, fsm->fsmData.nextStateVars, 01704 Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch))); 01705 array_insert_last(int, fsm->fsmData.presentStateVars, 01706 Ntk_NodeReadMddId(latch)); 01707 } /* end of Ntk_NetworkForEachLatch(network, gen, latch) */ 01708 01709 /* Fill in remaining latch for nextStateVars */ 01710 if (!independentFlag || createPseudoVarMode) { 01711 Ntk_NetworkForEachLatch(network, gen, latch) { 01712 char *latchName = Ntk_NodeReadName(latch); 01713 if(!st_lookup(vertexTable, latchName, (char **)0)) { 01714 if (independentFlag) { 01715 if (createPseudoVarMode == 1) { 01716 array_insert_last(int, fsm->fsmData.pseudoInputVars, 01717 Ntk_NodeReadMddId(latch)); 01718 array_insert_last(int, fsm->fsmData.inputVars, 01719 Ntk_NodeReadMddId(latch)); 01720 } else { 01721 st_insert(pseudoMddIdTable, (char *)(long)Ntk_NodeReadMddId(latch), 01722 NIL(char)); 01723 } 01724 } else { 01725 array_insert_last(int, fsm->fsmData.nextStateVars, 01726 Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch))); 01727 array_insert_last(int, fsm->fsmData.presentStateVars, 01728 Ntk_NodeReadMddId(latch)); 01729 } 01730 } 01731 } 01732 } 01733 01734 /* Input variables are identical for every subsystems */ 01735 Ntk_NetworkForEachInput(network, gen, input){ 01736 array_insert_last(int, fsm->fsmData.inputVars, Ntk_NodeReadMddId(input)); 01737 if (independentFlag && createPseudoVarMode) { 01738 array_insert_last(int, fsm->fsmData.primaryInputVars, 01739 Ntk_NodeReadMddId(input)); 01740 } 01741 } 01742 01743 if (independentFlag && createPseudoVarMode) { 01744 if (createPseudoVarMode == 2) { 01745 int mddId; 01746 array_t *supportMddIdArray; 01747 st_table *mddIdTable; 01748 01749 mddIdTable = st_init_table(st_numcmp, st_numhash); 01750 arrayForEachItem(int, fsm->fsmData.presentStateVars, i, mddId) { 01751 st_insert(mddIdTable, (char *)(long)mddId, NIL(char)); 01752 } 01753 arrayForEachItem(int, fsm->fsmData.inputVars, i, mddId) { 01754 st_insert(mddIdTable, (char *)(long)mddId, NIL(char)); 01755 } 01756 01757 supportMddIdArray = GetMddSupportIdArray(fsm, mddIdTable, 01758 pseudoMddIdTable); 01759 01760 arrayForEachItem(int, supportMddIdArray, i, mddId) { 01761 if (!st_lookup(mddIdTable, (char *)(long)mddId, NIL(char *))) { 01762 array_insert_last(int, fsm->fsmData.pseudoInputVars, mddId); 01763 array_insert_last(int, fsm->fsmData.inputVars, mddId); 01764 } 01765 } 01766 st_free_table(mddIdTable); 01767 st_free_table(pseudoMddIdTable); 01768 array_free(supportMddIdArray); 01769 } 01770 01771 array_append(fsm->fsmData.globalPsVars, fsm->fsmData.presentStateVars); 01772 array_append(fsm->fsmData.globalPsVars, fsm->fsmData.pseudoInputVars); 01773 } 01774 01775 FsmCreateVariableCubes(fsm); 01776 fsm->fsmData.presentStateBddVars = mdd_id_array_to_bdd_array( 01777 Fsm_FsmReadMddManager(fsm), fsm->fsmData.presentStateVars); 01778 return (fsm); 01779 } 01780 01801 void 01802 Fsm_InstantiateHint( 01803 Fsm_Fsm_t *fsm, 01804 mdd_t *hint, 01805 int fwdFlag, 01806 int bwdFlag, 01807 Ctlp_Approx_t type, 01808 int printStatus) 01809 { 01810 boolean underApprox = FALSE; 01811 Img_DirectionType imgFlag = Img_Forward_c; 01812 01813 assert(type != Ctlp_Incomparable_c); 01814 01815 if (bwdFlag && fwdFlag) 01816 imgFlag = Img_Both_c; 01817 else if (bwdFlag) 01818 imgFlag = Img_Backward_c; 01819 01820 switch (type) { 01821 case (Ctlp_Underapprox_c): underApprox = TRUE; break; 01822 case (Ctlp_Overapprox_c): underApprox = FALSE; break; 01823 case (Ctlp_Exact_c): 01824 underApprox = TRUE; 01825 hint = mdd_one(Fsm_FsmReadMddManager(fsm)); 01826 break; 01827 default: assert(0); break; 01828 } 01829 /* If we reach this point, underApprox has been explicitly assigned 01830 * by the switch. */ 01831 01832 Img_ImageConstrainAndClusterTransitionRelation( 01833 Fsm_FsmReadOrCreateImageInfo(fsm, bwdFlag, fwdFlag), 01834 imgFlag, 01835 hint, 01836 ((underApprox == TRUE) ? 01837 Img_GuidedSearchReadUnderApproxMinimizeMethod() : 01838 Img_GuidedSearchReadOverApproxMinimizeMethod()), 01839 underApprox, /* underapprox */ 01840 0, /* dont clean up */ 01841 0, /* no variable reordering */ 01842 printStatus); 01843 01844 Fsm_MinimizeTransitionRelationWithReachabilityInfo(fsm, imgFlag, 01845 printStatus); 01846 01847 if (type == Ctlp_Exact_c) mdd_free(hint); 01848 01849 return; 01850 } 01851 01863 void 01864 Fsm_CleanUpHints( Fsm_Fsm_t *fsm, int fwdFlag, int bwdFlag, int printStatus) 01865 { 01866 Img_DirectionType imgFlag = Img_Forward_c; 01867 mdd_t *one = bdd_one(Fsm_FsmReadMddManager(fsm)); 01868 if (bwdFlag && fwdFlag) 01869 imgFlag = Img_Both_c; 01870 else if (bwdFlag) 01871 imgFlag = Img_Backward_c; 01872 01873 Img_ImageConstrainAndClusterTransitionRelation(fsm->imageInfo, 01874 imgFlag, 01875 one, 01876 Img_GuidedSearchReadUnderApproxMinimizeMethod(), 01877 1, /* under approx */ 01878 1, /* clean up */ 01879 0, /* no variable reordering */ 01880 printStatus); 01881 mdd_free(one); 01882 return; 01883 } 01884 01885 01897 void 01898 Fsm_FsmFreeReachableStates(Fsm_Fsm_t *fsm) 01899 { 01900 if (fsm->reachabilityInfo.reachableStates) { 01901 mdd_free(fsm->reachabilityInfo.reachableStates); 01902 fsm->reachabilityInfo.reachableStates = NIL(mdd_t); 01903 } 01904 } 01905 01917 void 01918 Fsm_FsmFreeOverApproximateReachableStates(Fsm_Fsm_t *fsm) 01919 { 01920 if (fsm->reachabilityInfo.apprReachableStates) { 01921 mdd_array_free(fsm->reachabilityInfo.apprReachableStates); 01922 fsm->reachabilityInfo.apprReachableStates = NIL(array_t); 01923 fsm->reachabilityInfo.overApprox = Fsm_Ardc_NotConverged_c; 01924 } 01925 if (fsm->reachabilityInfo.subPsVars) { 01926 int i; 01927 array_t *psVars; 01928 01929 for (i = 0; i < array_n(fsm->reachabilityInfo.subPsVars); i++) { 01930 psVars = array_fetch(array_t *, fsm->reachabilityInfo.subPsVars, i); 01931 array_free(psVars); 01932 } 01933 array_free(fsm->reachabilityInfo.subPsVars); 01934 fsm->reachabilityInfo.subPsVars = NIL(array_t); 01935 } 01936 } 01937 01938 01950 int 01951 Fsm_FsmGetReachableDepth(Fsm_Fsm_t *fsm) 01952 { 01953 return(fsm->reachabilityInfo.depth); 01954 } 01955 01974 boolean 01975 Fsm_FsmCheckSameSubFsmInTotalFsm(Fsm_Fsm_t *fsm, 01976 Fsm_Fsm_t *subFsm1, 01977 Fsm_Fsm_t *subFsm2) 01978 { 01979 mdd_manager *mddMgr = Fsm_FsmReadMddManager(fsm); 01980 boolean result; 01981 01982 assert(Fsm_FsmReadNetwork(fsm) == Fsm_FsmReadNetwork(subFsm1)); 01983 assert(Fsm_FsmReadNetwork(fsm) == Fsm_FsmReadNetwork(subFsm2)); 01984 assert(Fsm_FsmReadMddManager(subFsm1) == mddMgr); 01985 assert(Fsm_FsmReadMddManager(subFsm2) == mddMgr); 01986 01987 /* compare present state variables */ 01988 result = VarIdArrayCompare(mddMgr, 01989 Fsm_FsmReadPresentStateVars(subFsm1), 01990 Fsm_FsmReadPresentStateVars(subFsm2)); 01991 if (!result) return FALSE; 01992 01993 /* compare next state variables */ 01994 result = VarIdArrayCompare(mddMgr, 01995 Fsm_FsmReadNextStateVars(subFsm1), 01996 Fsm_FsmReadNextStateVars(subFsm2)); 01997 if (!result) return FALSE; 01998 01999 /* compare input variables */ 02000 result = VarIdArrayCompare(mddMgr, 02001 Fsm_FsmReadInputVars(subFsm1), 02002 Fsm_FsmReadInputVars(subFsm2)); 02003 if (!result) return FALSE; 02004 02005 /* compare the pseudo input variables */ 02006 result = VarIdArrayCompare(mddMgr, 02007 Fsm_FsmReadPseudoInputVars(subFsm1), 02008 Fsm_FsmReadPseudoInputVars(subFsm2)); 02009 if (!result) return FALSE; 02010 02011 /* compare next state functions */ 02012 result = NSFunctionNamesCompare(mddMgr, 02013 Fsm_FsmReadNextStateFunctionNames(subFsm1), 02014 Fsm_FsmReadNextStateFunctionNames(subFsm2)); 02015 if (!result) return FALSE; 02016 02017 return TRUE; 02018 } 02019 02033 Fsm_RchStatus_t 02034 Fsm_FsmReadReachabilityApproxComputationStatus(Fsm_Fsm_t *fsm) 02035 { 02036 return fsm->reachabilityInfo.rchStatus; 02037 } 02038 02052 void 02053 Fsm_MinimizeTransitionRelationWithReachabilityInfo( 02054 Fsm_Fsm_t *fsm, 02055 Img_DirectionType fwdbwd, 02056 boolean verbosity) 02057 { 02058 Img_ImageInfo_t *imageInfo; 02059 array_t *minimizeArray = NIL(array_t); 02060 boolean fwd = FALSE; 02061 boolean bwd = FALSE; 02062 int oldVerbosity; 02063 Fsm_RchStatus_t status; 02064 boolean freeArray; 02065 mdd_t *exactrdc; 02066 02067 switch (fwdbwd) { 02068 case Img_Forward_c: 02069 fwd = 1; 02070 break; 02071 case Img_Backward_c: 02072 bwd = 1; 02073 break; 02074 case Img_Both_c: 02075 fwd = 1; 02076 bwd= 1; 02077 break; 02078 default: 02079 assert(0); 02080 break; 02081 } 02082 02083 imageInfo = Fsm_FsmReadOrCreateImageInfo(fsm, bwd, fwd); 02084 oldVerbosity = Img_ReadPrintMinimizeStatus(imageInfo); 02085 02086 status = Fsm_FsmReadReachabilityApproxComputationStatus(fsm); 02087 exactrdc = Fsm_FsmReadCurrentReachableStates(fsm); 02088 02089 if((status == Fsm_Rch_Exact_c || status == Fsm_Rch_Over_c) && 02090 exactrdc != NIL(mdd_t) ){ 02091 freeArray = TRUE; 02092 minimizeArray = array_alloc(mdd_t *, 1); 02093 array_insert_last(mdd_t *, minimizeArray, mdd_dup(exactrdc)); 02094 }else{ 02095 freeArray = FALSE; 02096 minimizeArray = Fsm_FsmReadCurrentOverApproximateReachableStates(fsm); 02097 if(minimizeArray == NIL(array_t)) 02098 return; 02099 } 02100 02101 if(verbosity) 02102 Img_SetPrintMinimizeStatus(imageInfo, 1); 02103 02104 /* We never reorder the clusters of the iwls structure. It is probably 02105 better to reorder them, but as this is written, there is no time to 02106 evaluate the effect of reordering. */ 02107 Img_MinimizeTransitionRelation(imageInfo, minimizeArray, 02108 Img_DefaultMinimizeMethod_c, fwdbwd, FALSE); 02109 02110 if(verbosity) 02111 Img_SetPrintMinimizeStatus(imageInfo, oldVerbosity); 02112 02113 if(freeArray) 02114 mdd_array_free(minimizeArray); 02115 02116 return; 02117 } 02118 02119 02120 02121 /*---------------------------------------------------------------------------*/ 02122 /* Definition of internal functions */ 02123 /*---------------------------------------------------------------------------*/ 02124 02137 void 02138 FsmSetReachabilityOnionRings( 02139 Fsm_Fsm_t *fsm, array_t *onionRings) 02140 { 02141 fsm->reachabilityInfo.onionRings = onionRings; 02142 } 02143 02155 void 02156 FsmSetReachabilityOnionRingsMode( 02157 Fsm_Fsm_t *fsm, Fsm_RchType_t value) 02158 { 02159 fsm->reachabilityInfo.onionRingsMode = value; 02160 } 02161 02173 void 02174 FsmSetReachabilityOnionRingsUpToDateFlag( 02175 Fsm_Fsm_t *fsm, boolean value) 02176 { 02177 fsm->reachabilityInfo.onionRingsUpToDate = value; 02178 } 02179 02191 void 02192 FsmSetReachabilityApproxComputationStatus( 02193 Fsm_Fsm_t *fsm, Fsm_RchStatus_t value) 02194 { 02195 fsm->reachabilityInfo.rchStatus = value; 02196 } 02197 02209 void 02210 FsmSetReachabilityOverApproxComputationStatus( 02211 Fsm_Fsm_t *fsm, Fsm_Ardc_StatusType_t status) 02212 { 02213 fsm->reachabilityInfo.overApprox = status; 02214 } 02215 02227 Fsm_Ardc_StatusType_t 02228 FsmReadReachabilityOverApproxComputationStatus(Fsm_Fsm_t *fsm) 02229 { 02230 return(fsm->reachabilityInfo.overApprox); 02231 } 02232 02246 void 02247 FsmSetReachabilityComputationMode( 02248 Fsm_Fsm_t *fsm, Fsm_RchType_t value) 02249 { 02250 fsm->reachabilityInfo.reachabilityMode = value; 02251 } 02252 02266 Fsm_RchType_t 02267 FsmReadReachabilityComputationMode( 02268 Fsm_Fsm_t *fsm) 02269 { 02270 return fsm->reachabilityInfo.reachabilityMode; 02271 } 02272 02273 02285 void 02286 FsmResetReachabilityFields(Fsm_Fsm_t *fsm, Fsm_RchType_t approxFlag) 02287 { 02288 int i; 02289 mdd_t *reachableStates; 02290 /* free reachable states if it is necessary to recompute anyway. */ 02291 if (approxFlag != Fsm_Rch_Oa_c) { 02292 if (Fsm_FsmReadCurrentReachableStates(fsm)) { 02293 Fsm_FsmFreeReachableStates(fsm); 02294 } 02295 } else if (Fsm_FsmReadCurrentOverApproximateReachableStates(fsm)) { 02296 Fsm_FsmFreeOverApproximateReachableStates(fsm); 02297 } 02298 02299 /* free onion rings */ 02300 if (Fsm_FsmReadReachabilityOnionRings(fsm) != NIL(array_t)) { 02301 arrayForEachItem(mdd_t *, Fsm_FsmReadReachabilityOnionRings(fsm), i, 02302 reachableStates) { 02303 mdd_free(reachableStates); 02304 } 02305 array_free(Fsm_FsmReadReachabilityOnionRings(fsm)); 02306 FsmSetReachabilityOnionRings(fsm, NIL(array_t)); 02307 } 02308 fsm->reachabilityInfo.depth = 0; 02309 FsmSetReachabilityComputationMode(fsm, Fsm_Rch_Default_c); 02310 FsmSetReachabilityApproxComputationStatus(fsm, Fsm_Rch_Under_c); 02311 FsmSetReachabilityOnionRingsUpToDateFlag(fsm, FALSE); 02312 FsmSetReachabilityOnionRingsMode(fsm, Fsm_Rch_Default_c); 02313 return; 02314 } /* end of FsmResetReachabilityFields */ 02315 02316 02317 /*---------------------------------------------------------------------------*/ 02318 /* Definition of internal functions */ 02319 /*---------------------------------------------------------------------------*/ 02331 FsmHdStruct_t * 02332 FsmHdStructAlloc(int nvars) 02333 { 02334 FsmHdStruct_t *hdInfo = ALLOC(FsmHdStruct_t, 1); 02335 if (hdInfo == NIL(FsmHdStruct_t)) return hdInfo; 02336 hdInfo->numDeadEnds = 0; 02337 hdInfo->firstSubset = TRUE; 02338 hdInfo->lastIter = -1; 02339 hdInfo->partialImage = FALSE; 02340 hdInfo->residueCount = 0; 02341 hdInfo->interiorStates = NIL(mdd_t); 02342 hdInfo->interiorStateCandidate = NIL(mdd_t); 02343 hdInfo->deadEndResidue = NIL(mdd_t); 02344 hdInfo->options = Fsm_FsmHdGetTravOptions(nvars); 02345 hdInfo->stats = FsmHdStatsStructAlloc(); 02346 hdInfo->imageOfReachedComputed = FALSE; 02347 hdInfo->onlyPartialImage = FALSE; 02348 hdInfo->slowGrowth = 0; 02349 hdInfo->deadEndWithOriginalTR = FALSE; 02350 hdInfo->deadEndComputation = FALSE; 02351 return hdInfo; 02352 } 02353 02354 02366 void 02367 FsmHdStructFree(FsmHdStruct_t *hdInfo) 02368 { 02369 if (hdInfo->interiorStates != NULL) mdd_free(hdInfo->interiorStates); 02370 if (hdInfo->interiorStateCandidate != NULL) 02371 mdd_free(hdInfo->interiorStateCandidate); 02372 if (hdInfo->deadEndResidue != NULL) mdd_free(hdInfo->deadEndResidue); 02373 02374 FsmHdStatsStructFree(hdInfo->stats); 02375 Fsm_FsmHdFreeTravOptions(hdInfo->options); 02376 FREE(hdInfo); 02377 return; 02378 } 02379 02391 void 02392 FsmGuidedSearchPrintOptions(void) 02393 { 02394 char *string = Cmd_FlagReadByName("guided_search_hint_type"); 02395 if (string == NIL(char)) string = "local"; 02396 fprintf(vis_stdout, "Flag guided_search_hint_type is set to %s.\n", string); 02397 string = Cmd_FlagReadByName("guided_search_underapprox_minimize_method"); 02398 if (string == NIL(char)) string = "and"; 02399 fprintf(vis_stdout, "Flag guided_search_underapprox_minimize_method is set to %s.\n", string); 02400 string = Cmd_FlagReadByName("guided_search_overapprox_minimize_method"); 02401 if (string == NIL(char)) string = "ornot"; 02402 fprintf(vis_stdout, "Flag guided_search_overapprox_minimize_method is set to %s.\n", string); 02403 string = Cmd_FlagReadByName("guided_search_sequence"); 02404 if (string == NIL(char)) string = "all hints to convergence"; 02405 fprintf(vis_stdout, "Flag guided_search_overapprox_minimize_method is set to %s.\n", string); 02406 return; 02407 } 02408 02409 02410 02411 /*---------------------------------------------------------------------------*/ 02412 /* Definition of static functions */ 02413 /*---------------------------------------------------------------------------*/ 02425 static Fsm_Fsm_t * 02426 FsmStructAlloc(Ntk_Network_t *network, 02427 graph_t *partition) 02428 { 02429 Fsm_Fsm_t *fsm; 02430 if (Ntk_NetworkReadNumLatches(network) == 0) { 02431 error_append("Network has no latches. Cannot create FSM."); 02432 return (NIL(Fsm_Fsm_t)); 02433 } 02434 02435 fsm = ALLOC(Fsm_Fsm_t, 1); 02436 if (fsm == NIL(Fsm_Fsm_t)) return NIL(Fsm_Fsm_t); 02437 memset(fsm, 0, sizeof(Fsm_Fsm_t)); 02438 02439 fsm->network = network; 02440 02441 if (partition == NIL(graph_t)) { 02442 partition = Part_NetworkReadPartition(network); 02443 02444 if (partition == NIL(graph_t)) { 02445 error_append("Network has no partition. Cannot create FSM."); 02446 return (NIL(Fsm_Fsm_t)); 02447 } else { 02448 fsm->partition = Part_PartitionDuplicate(partition); 02449 } 02450 } else { 02451 fsm->partition = partition; 02452 } 02453 02454 FsmSetReachabilityOnionRings(fsm, NIL(array_t)); 02455 FsmSetReachabilityOnionRingsUpToDateFlag(fsm, FALSE); 02456 FsmSetReachabilityOnionRingsMode(fsm, Fsm_Rch_Default_c); 02457 FsmSetReachabilityApproxComputationStatus(fsm, Fsm_Rch_Under_c); 02458 FsmSetReachabilityComputationMode(fsm, Fsm_Rch_Default_c); 02459 FsmSetReachabilityOverApproxComputationStatus(fsm, Fsm_Ardc_NotConverged_c); 02460 02461 fsm->fsmData.presentStateVars = array_alloc(int, 0); 02462 fsm->fsmData.nextStateVars = array_alloc(int, 0); 02463 fsm->fsmData.inputVars = array_alloc(int, 0); 02464 fsm->fsmData.nextStateFunctions = array_alloc(char *, 0); 02465 02466 return (fsm); 02467 } /* end of FsmStructAlloc */ 02468 02469 02481 static void 02482 FsmCreateVariableCubes(Fsm_Fsm_t *fsm) 02483 { 02484 mdd_manager *manager = Fsm_FsmReadMddManager(fsm); 02485 char *flagValue; 02486 boolean createVariableCubesFlag = TRUE; 02487 02488 if (bdd_get_package_name() != CUDD) 02489 return; 02490 02491 flagValue = Cmd_FlagReadByName("fsm_create_var_cubes"); 02492 if (flagValue != NIL(char)) { 02493 if (strcmp(flagValue, "yes") == 0) 02494 createVariableCubesFlag = TRUE; 02495 else if (strcmp(flagValue, "no") == 0) 02496 createVariableCubesFlag = FALSE; 02497 else { 02498 fprintf(vis_stderr, 02499 "** ardc error : invalid value %s for create_var_cubes[yes/no]. **\n", 02500 flagValue); 02501 } 02502 } 02503 02504 if (!createVariableCubesFlag) 02505 return; 02506 02507 fsm->fsmData.createVarCubesFlag = TRUE; 02508 fsm->fsmData.presentStateCube = 02509 mdd_id_array_to_bdd_cube(manager, fsm->fsmData.presentStateVars); 02510 fsm->fsmData.nextStateCube = 02511 mdd_id_array_to_bdd_cube(manager, fsm->fsmData.nextStateVars); 02512 fsm->fsmData.inputCube = 02513 mdd_id_array_to_bdd_cube(manager, fsm->fsmData.inputVars); 02514 if (fsm->fsmData.pseudoInputVars) { 02515 fsm->fsmData.pseudoInputCube = 02516 mdd_id_array_to_bdd_cube(manager, fsm->fsmData.pseudoInputVars); 02517 } 02518 if (fsm->fsmData.primaryInputVars) { 02519 fsm->fsmData.primaryInputCube = 02520 mdd_id_array_to_bdd_cube(manager, fsm->fsmData.primaryInputVars); 02521 } 02522 if (fsm->fsmData.globalPsVars) { 02523 fsm->fsmData.globalPsCube = 02524 mdd_id_array_to_bdd_cube(manager, fsm->fsmData.globalPsVars); 02525 } 02526 } 02527 02528 02538 static int 02539 nameCompare( 02540 const void * name1, 02541 const void * name2) 02542 { 02543 return(strcmp(*(char **)name1, *(char **)name2)); 02544 02545 } /* end of signatureCompare */ 02546 02547 02560 static boolean 02561 VarIdArrayCompare(mdd_manager *mddMgr, 02562 array_t *vars1, 02563 array_t *vars2) 02564 { 02565 02566 mdd_t *cube1, *cube2; 02567 boolean result = FALSE; 02568 cube1 = bdd_compute_cube(mddMgr, vars1); 02569 cube2 = bdd_compute_cube(mddMgr, vars2); 02570 if ((cube1 == NIL(mdd_t)) || (cube2 == NIL(mdd_t))) { 02571 result = (cube1 == cube2) ? TRUE : FALSE; 02572 } else { 02573 result = bdd_equal(cube1, cube2) ? TRUE : FALSE; 02574 } 02575 if (cube1 != NIL(bdd_t)) bdd_free(cube1); 02576 if (cube2 != NIL(bdd_t)) bdd_free(cube2); 02577 return result; 02578 } /* end of VarIdArrayCompare */ 02579 02580 02593 static boolean 02594 NSFunctionNamesCompare(mdd_manager *mddMgr, 02595 array_t *names1, 02596 array_t *names2) 02597 { 02598 int sizeArray = array_n(names1); 02599 int i, count; 02600 char *name; 02601 st_table *nameTable = st_init_table(strcmp, st_strhash); 02602 02603 if (sizeArray != array_n(names2)) return FALSE; 02604 /* check if elements in names2 is in names1 */ 02605 arrayForEachItem(char *, names1, i, name) { 02606 if (st_lookup_int(nameTable, name, &count)) { 02607 count++; 02608 } else { 02609 count = 1; 02610 } 02611 st_insert(nameTable, name, (char *)(long)count); 02612 } 02613 02614 arrayForEachItem(char *, names2, i, name) { 02615 if (!st_lookup_int(nameTable, name, &count)) { 02616 st_free_table(nameTable); 02617 return FALSE; 02618 } else if (count == 0) { 02619 st_free_table(nameTable); 02620 return FALSE; 02621 } else { 02622 count--; 02623 st_insert(nameTable, name, (char *)(long)count); 02624 } 02625 } 02626 st_free_table(nameTable); 02627 02628 /* check if elements in names1 is in names2 */ 02629 nameTable = st_init_table(strcmp, st_strhash); 02630 arrayForEachItem(char *, names2, i, name) { 02631 if (st_lookup_int(nameTable, name, &count)) { 02632 count++; 02633 } else { 02634 count = 1; 02635 } 02636 st_insert(nameTable, name, (char *)(long)count); 02637 } 02638 02639 arrayForEachItem(char *, names1, i, name) { 02640 if (!st_lookup_int(nameTable, name, &count)) { 02641 st_free_table(nameTable); 02642 return FALSE; 02643 } else if (count == 0) { 02644 st_free_table(nameTable); 02645 return FALSE; 02646 } else { 02647 count--; 02648 st_insert(nameTable, name, (char *)(long)count); 02649 } 02650 } 02651 st_free_table(nameTable); 02652 return TRUE; 02653 } /* end of NSFunctionNamesCompare */ 02654 02655 02667 static array_t * 02668 GetMddSupportIdArray(Fsm_Fsm_t *fsm, st_table *mddIdTable, 02669 st_table *pseudoMddIdTable) 02670 { 02671 mdd_t *func; 02672 char *nodeName; 02673 vertex_t *vertex; 02674 Mvf_Function_t *mvf; 02675 int i, j, k; 02676 long mddId; 02677 array_t *varBddFunctionArray; 02678 mdd_manager *mddManager; 02679 array_t *supportMddIdArray, *support; 02680 st_table *supportMddIdTable; 02681 st_generator *stGen; 02682 02683 supportMddIdTable = st_init_table(st_numcmp, st_numhash); 02684 mddManager = Part_PartitionReadMddManager(fsm->partition); 02685 02686 for (i = 0; i < array_n(fsm->fsmData.nextStateFunctions); i++) { 02687 nodeName = array_fetch(char*, fsm->fsmData.nextStateFunctions, i); 02688 vertex = Part_PartitionFindVertexByName(fsm->partition, nodeName); 02689 mvf = Part_VertexReadFunction(vertex); 02690 mddId = (long) array_fetch(int, fsm->fsmData.nextStateVars, i); 02691 varBddFunctionArray = mdd_fn_array_to_bdd_fn_array(mddManager, 02692 (int) mddId, mvf); 02693 02694 for (j = 0; j < array_n(varBddFunctionArray); j++) { 02695 func = array_fetch(mdd_t *, varBddFunctionArray, j); 02696 support = mdd_get_support(mddManager, func); 02697 arrayForEachItem(int, support, k, mddId) { 02698 if (!st_lookup(supportMddIdTable, (char *)mddId, NIL(char *))) { 02699 if (st_lookup(mddIdTable, (char *)mddId, NIL(char *)) || 02700 st_lookup(pseudoMddIdTable, (char *)mddId, NIL(char *))) { 02701 st_insert(supportMddIdTable, (char *)mddId, NIL(char)); 02702 } else { /* intermediate variables */ 02703 /* NEEDS to get the supports of an intermediate variable */ 02704 assert(0); 02705 } 02706 } 02707 } 02708 } 02709 array_free(varBddFunctionArray); 02710 } 02711 02712 supportMddIdArray = array_alloc(int, 0); 02713 st_foreach_item(supportMddIdTable, stGen, &mddId, NIL(char *)) { 02714 array_insert_last(int, supportMddIdArray, (int) mddId); 02715 } 02716 02717 return(supportMddIdArray); 02718 } 02719 02720