VIS
|
00001 00017 #include "absInt.h" 00018 00019 static char rcsid[] UNUSED = "$Id: absInternal.c,v 1.30 2005/04/16 04:22:21 fabio Exp $"; 00020 00021 00022 /*---------------------------------------------------------------------------*/ 00023 /* Macro declarations */ 00024 /*---------------------------------------------------------------------------*/ 00025 00026 /*---------------------------------------------------------------------------*/ 00027 /* Variable declarations */ 00028 /*---------------------------------------------------------------------------*/ 00029 static int vertexCounter = 0; 00030 00033 /*---------------------------------------------------------------------------*/ 00034 /* Static function prototypes */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 static mdd_t * ComputeEGtrue(Abs_VerificationInfo_t *absInfo, mdd_t *careStates); 00038 static void SelectIdentifierVertices(AbsVertexInfo_t *vertexPtr, array_t *result, st_table *visited); 00039 00043 /*---------------------------------------------------------------------------*/ 00044 /* Definition of exported functions */ 00045 /*---------------------------------------------------------------------------*/ 00046 00055 Abs_VerificationInfo_t * 00056 Abs_VerificationComputeInfo( 00057 Ntk_Network_t *network) 00058 { 00059 Abs_VerificationInfo_t *absInfo; 00060 Ntk_Node_t *nodePtr; 00061 graph_t *partition; 00062 mdd_manager *mddManager; 00063 st_table *table; 00064 lsGen lsgen; 00065 00066 00067 /* Create the data structure to store all the needed info */ 00068 absInfo = AbsVerificationInfoInitialize(); 00069 00070 /* Fill the data structure in */ 00071 AbsVerificationInfoSetNetwork(absInfo, network); 00072 partition = Part_NetworkReadPartition(network); 00073 AbsVerificationInfoSetPartition(absInfo, partition); 00074 mddManager = Part_PartitionReadMddManager(partition); 00075 AbsVerificationInfoSetMddManager(absInfo, mddManager); 00076 00077 /* Compute the state variable pairs */ 00078 table = st_init_table(st_numcmp, st_numhash); 00079 Ntk_NetworkForEachLatch(network, lsgen, nodePtr) { 00080 Ntk_Node_t *latchInputPtr; 00081 int mddId, mddId2; 00082 00083 mddId = Ntk_NodeReadMddId(nodePtr); 00084 latchInputPtr = Ntk_NodeReadShadow(nodePtr); 00085 mddId2 = Ntk_NodeReadMddId(latchInputPtr); 00086 st_insert(table, (char *)(long)mddId, (char *)(long)mddId2); 00087 } 00088 AbsVerificationInfoSetStateVars(absInfo, table); 00089 00090 /* Compute the quantify variables */ 00091 table = st_init_table(st_numcmp, st_numhash); 00092 Ntk_NetworkForEachInput(network, lsgen, nodePtr) { 00093 int mddId; 00094 00095 mddId = Ntk_NodeReadMddId(nodePtr); 00096 st_insert(table, (char *)(long)mddId, NIL(char)); 00097 } 00098 AbsVerificationInfoSetQuantifyVars(absInfo, table); 00099 00100 /* Initalize the catalog to detect common expressions */ 00101 AbsVerificationInfoSetCatalog(absInfo, AbsVertexCatalogInitialize()); 00102 00103 return absInfo; 00104 } /* End of Abs_VerificationComputeInfo */ 00105 00106 00107 /*---------------------------------------------------------------------------*/ 00108 /* Definition of internal functions */ 00109 /*---------------------------------------------------------------------------*/ 00110 00121 AbsVertexInfo_t * 00122 AbsVertexInitialize(void) 00123 { 00124 AbsVertexInfo_t *result; 00125 00126 result = ALLOC(AbsVertexInfo_t, 1); 00127 00128 AbsVertexSetType(result, false_c); 00129 AbsVertexSetId(result, vertexCounter++); 00130 AbsVertexSetSat(result, NIL(mdd_t)); 00131 AbsVertexSetRefs(result, 1); 00132 AbsVertexSetServed(result, 0); 00133 AbsVertexSetPolarity(result, FALSE); 00134 AbsVertexSetDepth(result, -1); 00135 AbsVertexSetLocalApprox(result, FALSE); 00136 AbsVertexSetGlobalApprox(result, FALSE); 00137 AbsVertexSetConstant(result, FALSE); 00138 AbsVertexSetTrueRefine(result, FALSE); 00139 AbsVertexSetLeftKid(result, NIL(AbsVertexInfo_t)); 00140 AbsVertexSetRightKid(result, NIL(AbsVertexInfo_t)); 00141 result->parent = lsCreate(); 00142 00143 /* Not all of these need to be initialized, but to be sure... */ 00144 AbsVertexSetSolutions(result, NIL(st_table)); 00145 AbsVertexSetVarId(result, 0); 00146 AbsVertexSetFpVar(result, NIL(AbsVertexInfo_t)); 00147 AbsVertexSetVarId(result, 0); 00148 AbsVertexSetGoalSet(result, NIL(mdd_t)); 00149 AbsVertexSetRings(result, NIL(array_t)); 00150 AbsVertexSetRingApprox(result, NIL(array_t)); 00151 AbsVertexSetSubApprox(result, NIL(array_t)); 00152 AbsVertexSetUseExtraCareSet(result, FALSE); 00153 AbsVertexSetName(result, NIL(char)); 00154 AbsVertexSetValue(result, NIL(char)); 00155 00156 return result; 00157 } /* End of AbsVertexInitialize */ 00158 00170 void 00171 AbsVertexFree( 00172 AbsVertexCatalog_t *catalog, 00173 AbsVertexInfo_t *v, 00174 AbsVertexInfo_t *fromVertex) 00175 { 00176 /* Decrement the number of references */ 00177 AbsVertexReadRefs(v)--; 00178 00179 /* Remove the pointer from its parent to itself */ 00180 if (fromVertex != NIL(AbsVertexInfo_t)) { 00181 AbsVertexInfo_t *result; 00182 lsGen listGen; 00183 lsHandle item, toDelete; 00184 lsGeneric userData; 00185 00186 listGen = lsStart(AbsVertexReadParent(v)); 00187 toDelete = (lsHandle) 0; 00188 while(toDelete == (lsHandle) 0 && 00189 lsNext(listGen, &result, &item) == LS_OK) { 00190 if (result == fromVertex) { 00191 toDelete = item; 00192 } 00193 } 00194 lsFinish(listGen); 00195 00196 if (toDelete != (lsHandle)0) { 00197 lsRemoveItem(toDelete, &userData); 00198 } 00199 } 00200 00201 /* If it is not the last reference we are done */ 00202 if (AbsVertexReadRefs(v) != 0) { 00203 return; 00204 } 00205 00206 /* Vertices that need recursion over the leftKid */ 00207 if (AbsVertexReadType(v) == fixedPoint_c || 00208 AbsVertexReadType(v) == and_c || 00209 AbsVertexReadType(v) == xor_c || 00210 AbsVertexReadType(v) == xnor_c || 00211 AbsVertexReadType(v) == not_c || 00212 AbsVertexReadType(v) == preImage_c) { 00213 AbsVertexFree(catalog, AbsVertexReadLeftKid(v), v); 00214 } 00215 00216 /* Vertices that need recursion over the rightKid */ 00217 if (AbsVertexReadType(v) == and_c || 00218 AbsVertexReadType(v) == xor_c || 00219 AbsVertexReadType(v) == xnor_c) { 00220 AbsVertexFree(catalog, AbsVertexReadRightKid(v), v); 00221 } 00222 00223 /* Remove the vertex from the catalog */ 00224 AbsCatalogDelete(catalog, v); 00225 00226 /* The variable vertex does not reference the sat set */ 00227 if (AbsVertexReadType(v) != variable_c && 00228 AbsVertexReadSat(v) != NIL(mdd_t)) { 00229 mdd_free(AbsVertexReadSat(v)); 00230 } 00231 00232 if (AbsVertexReadType(v) == variable_c && 00233 AbsVertexReadGoalSet(v) != NIL(mdd_t)) { 00234 mdd_free(AbsVertexReadGoalSet(v)); 00235 } 00236 00237 lsDestroy(AbsVertexReadParent(v), (void (*)(lsGeneric))0); 00238 00239 /* Free the union fields depending on the type of vertex */ 00240 if (AbsVertexReadType(v) == preImage_c) { 00241 if (AbsVertexReadSolutions(v) != NIL(st_table)) { 00242 AbsEvalCacheEntry_t *value; 00243 bdd_node *key; 00244 st_generator *stgen; 00245 00246 st_foreach_item(AbsVertexReadSolutions(v), stgen, &key, &value) { 00247 AbsCacheEntryFree(value); 00248 } 00249 st_free_table(AbsVertexReadSolutions(v)); 00250 } 00251 } 00252 else if (AbsVertexReadType(v) == fixedPoint_c) { 00253 if (AbsVertexReadRings(v) != NIL(array_t)) { 00254 mdd_t *unit; 00255 int i; 00256 00257 arrayForEachItem(mdd_t *, AbsVertexReadRings(v), i, unit) { 00258 mdd_free(unit); 00259 } 00260 array_free(AbsVertexReadRings(v)); 00261 } 00262 if (AbsVertexReadRingApprox(v) != NIL(array_t)) { 00263 array_free(AbsVertexReadRingApprox(v)); 00264 } 00265 if (AbsVertexReadSubApprox(v) != NIL(array_t)) { 00266 array_free(AbsVertexReadSubApprox(v)); 00267 } 00268 } 00269 else if (AbsVertexReadType(v) == identifier_c) { 00270 FREE(AbsVertexReadName(v)); 00271 FREE(AbsVertexReadValue(v)); 00272 } 00273 00274 /* Deallocate the memory for the structure itself */ 00275 FREE(v); 00276 } /* End of AbsVertexFree */ 00277 00288 Abs_VerificationInfo_t * 00289 AbsVerificationInfoInitialize(void) 00290 { 00291 Abs_VerificationInfo_t *result; 00292 00293 result = ALLOC(Abs_VerificationInfo_t, 1); 00294 00295 AbsVerificationInfoSetNetwork(result, NIL(Ntk_Network_t)); 00296 AbsVerificationInfoSetPartition(result, NIL(graph_t)); 00297 AbsVerificationInfoSetFsm(result, NIL(Fsm_Fsm_t)); 00298 AbsVerificationInfoSetNumStateVars(result, 0); 00299 AbsVerificationInfoSetApproxFsm(result, NIL(Fsm_Fsm_t)); 00300 AbsVerificationInfoSetStateVars(result, NIL(st_table)); 00301 AbsVerificationInfoSetQuantifyVars(result, NIL(st_table)); 00302 AbsVerificationInfoSetCareSet(result, NIL(mdd_t)); 00303 AbsVerificationInfoSetTmpCareSet(result, NIL(mdd_t)); 00304 AbsVerificationInfoSetImageCache(result, NIL(st_table)); 00305 AbsVerificationInfoSetMddManager(result, NIL(mdd_manager)); 00306 AbsVerificationInfoSetCatalog(result, NIL(AbsVertexCatalog_t)); 00307 AbsVerificationInfoSetStats(result, AbsStatsInitialize()); 00308 AbsVerificationInfoSetOptions(result, NIL(AbsOptions_t)); 00309 00310 return result; 00311 } /* End of AbsVerificationInfoInitialize */ 00312 00328 void 00329 AbsVerificationInfoFree( 00330 Abs_VerificationInfo_t *v) 00331 { 00332 if (AbsVerificationInfoReadStateVars(v) != NIL(st_table)) { 00333 st_free_table(AbsVerificationInfoReadStateVars(v)); 00334 } 00335 00336 if (AbsVerificationInfoReadQuantifyVars(v) != NIL(st_table)) { 00337 st_free_table(AbsVerificationInfoReadQuantifyVars(v)); 00338 } 00339 00340 if (AbsVerificationInfoReadImageCache(v) != NIL(st_table)) { 00341 AbsEvalCacheEntry_t *value; 00342 bdd_node *key; 00343 st_generator *stgen; 00344 00345 st_foreach_item(AbsVerificationInfoReadImageCache(v), stgen, 00346 &key, &value) { 00347 AbsCacheEntryFree(value); 00348 } 00349 st_free_table(AbsVerificationInfoReadImageCache(v)); 00350 } 00351 00352 if (AbsVerificationInfoReadCareSet(v) != NIL(mdd_t)) { 00353 mdd_free(AbsVerificationInfoReadCareSet(v)); 00354 } 00355 00356 if (AbsVerificationInfoReadTmpCareSet(v) != NIL(mdd_t)) { 00357 mdd_free(AbsVerificationInfoReadTmpCareSet(v)); 00358 } 00359 00360 if (AbsVerificationInfoReadCatalog(v) != NIL(AbsVertexCatalog_t)) { 00361 AbsVertexCatalogFree(AbsVerificationInfoReadCatalog(v)); 00362 } 00363 00364 AbsStatsFree(AbsVerificationInfoReadStats(v)); 00365 00366 FREE(v); 00367 00368 /* 00369 * The options field is not freed since it is assumed that it has been 00370 * allocated outside the AbsVerificationInitialize procedure 00371 */ 00372 00373 return; 00374 } /* End of AbsVerificationInfoFree */ 00375 00385 AbsOptions_t * 00386 AbsOptionsInitialize(void) 00387 { 00388 AbsOptions_t *result; 00389 00390 result = ALLOC(AbsOptions_t, 1); 00391 00392 AbsOptionsSetVerbosity(result, 0); 00393 AbsOptionsSetTimeOut(result, 0); 00394 AbsOptionsSetFileName(result, NIL(char)); 00395 AbsOptionsSetReachability(result, FALSE); 00396 AbsOptionsSetFairFileName(result, NIL(char)); 00397 AbsOptionsSetExact(result, FALSE); 00398 AbsOptionsSetPrintStats(result, FALSE); 00399 AbsOptionsSetMinimizeIterate(result, FALSE); 00400 AbsOptionsSetNegateFormula(result, FALSE); 00401 AbsOptionsSetPartApprox(result, FALSE); 00402 00403 return result; 00404 } /* End of AbsOptionsInitialize */ 00405 00415 void 00416 AbsOptionsFree(AbsOptions_t *unit) 00417 { 00418 if (AbsOptionsReadFileName(unit) != NIL(char)) { 00419 FREE(AbsOptionsReadFileName(unit)); 00420 } 00421 00422 if (AbsOptionsReadFairFileName(unit) != NIL(char)) { 00423 FREE(AbsOptionsReadFairFileName(unit)); 00424 } 00425 00426 FREE(unit); 00427 00428 return; 00429 } /* End of AbsOptionsInitialize */ 00430 00431 00442 AbsStats_t * 00443 AbsStatsInitialize(void) 00444 { 00445 AbsStats_t *result; 00446 00447 result = ALLOC(AbsStats_t, 1); 00448 00449 AbsStatsSetNumReorderings(result, 0); 00450 AbsStatsSetEvalFixedPoint(result, 0); 00451 AbsStatsSetEvalAnd(result, 0); 00452 AbsStatsSetEvalNot(result, 0); 00453 AbsStatsSetEvalPreImage(result, 0); 00454 AbsStatsSetEvalIdentifier(result, 0); 00455 AbsStatsSetEvalVariable(result, 0); 00456 AbsStatsSetRefineFixedPoint(result, 0); 00457 AbsStatsSetRefineAnd(result, 0); 00458 AbsStatsSetRefineNot(result, 0); 00459 AbsStatsSetRefinePreImage(result, 0); 00460 AbsStatsSetRefineIdentifier(result, 0); 00461 AbsStatsSetRefineVariable(result, 0); 00462 AbsStatsSetExactPreImage(result, 0); 00463 AbsStatsSetApproxPreImage(result, 0); 00464 AbsStatsSetExactImage(result, 0); 00465 AbsStatsSetPreImageCacheEntries(result, 0); 00466 AbsStatsSetImageCacheEntries(result, 0); 00467 AbsStatsSetImageCpuTime(result, 0); 00468 AbsStatsSetPreImageCpuTime(result, 0); 00469 AbsStatsSetAppPreCpuTime(result, 0); 00470 00471 return result; 00472 00473 } /* End of AbsStatsInitialize */ 00474 00484 void 00485 AbsStatsFree( 00486 AbsStats_t *unit) 00487 { 00488 FREE(unit); 00489 } /* End of AbsStatsFree */ 00490 00500 AbsEvalCacheEntry_t * 00501 AbsCacheEntryInitialize(void) 00502 { 00503 AbsEvalCacheEntry_t *result; 00504 00505 result = ALLOC(AbsEvalCacheEntry_t, 1); 00506 00507 AbsEvalCacheEntrySetKey(result, NIL(mdd_t)); 00508 AbsEvalCacheEntrySetApprox(result, FALSE); 00509 AbsEvalCacheEntrySetComplement(result, 0); 00510 AbsEvalCacheEntrySetResult(result, NIL(mdd_t)); 00511 AbsEvalCacheEntrySetCareSet(result, NIL(mdd_t)); 00512 00513 return result; 00514 } /* End of AbsCacheEntryInitialize */ 00515 00525 void 00526 AbsCacheEntryFree( 00527 AbsEvalCacheEntry_t *unit) 00528 { 00529 mdd_free(AbsEvalCacheEntryReadKey(unit)); 00530 mdd_free(AbsEvalCacheEntryReadResult(unit)); 00531 mdd_free(AbsEvalCacheEntryReadCareSet(unit)); 00532 00533 FREE(unit); 00534 } /* End of AbsCacheEntryFree */ 00535 00545 void 00546 AbsEvalCacheInsert( 00547 st_table *solutions, 00548 mdd_t *key, 00549 mdd_t *result, 00550 mdd_t *careSet, 00551 boolean approx, 00552 boolean replace) 00553 { 00554 AbsEvalCacheEntry_t *entry; 00555 int complement; 00556 bdd_node *f; 00557 00558 entry = NIL(AbsEvalCacheEntry_t); 00559 f = bdd_get_node(key, &complement); 00560 00561 /* If the replacement is required, delete the element from the table */ 00562 if (replace) { 00563 st_delete(solutions, &f, &entry); 00564 00565 mdd_free(AbsEvalCacheEntryReadKey(entry)); 00566 mdd_free(AbsEvalCacheEntryReadResult(entry)); 00567 mdd_free(AbsEvalCacheEntryReadCareSet(entry)); 00568 } 00569 00570 assert(!st_is_member(solutions, (char *)f)); 00571 00572 if (entry == NIL(AbsEvalCacheEntry_t)) { 00573 entry = AbsCacheEntryInitialize(); 00574 } 00575 00576 AbsEvalCacheEntrySetKey(entry, mdd_dup(key)); 00577 AbsEvalCacheEntrySetApprox(entry, approx); 00578 AbsEvalCacheEntrySetComplement(entry, complement); 00579 AbsEvalCacheEntrySetResult(entry, mdd_dup(result)); 00580 AbsEvalCacheEntrySetCareSet(entry, mdd_dup(careSet)); 00581 00582 /* Insert the new entry in the cache */ 00583 st_insert(solutions, (char *)f, (char *)entry); 00584 00585 return; 00586 } /* End of AbsEvalCacheInsert */ 00587 00597 boolean 00598 AbsEvalCacheLookup( 00599 st_table *solutions, 00600 mdd_t *key, 00601 mdd_t *careSet, 00602 boolean approx, 00603 mdd_t **result, 00604 boolean *storedApprox) 00605 { 00606 AbsEvalCacheEntry_t *entry; 00607 bdd_node *f; 00608 int complement; 00609 00610 f = bdd_get_node(key, &complement); 00611 00612 if (st_lookup(solutions, f, &entry)) { 00613 if (complement == AbsEvalCacheEntryReadComplement(entry) && 00614 (approx || !AbsEvalCacheEntryReadApprox(entry)) && 00615 mdd_lequal(careSet, AbsEvalCacheEntryReadCareSet(entry), 1, 1)) { 00616 *result = AbsEvalCacheEntryReadResult(entry); 00617 if (storedApprox != 0) { 00618 *storedApprox = AbsEvalCacheEntryReadApprox(entry); 00619 } 00620 return TRUE; 00621 } 00622 else { 00623 st_delete(solutions, &f, &entry); 00624 AbsCacheEntryFree(entry); 00625 } 00626 } 00627 00628 return FALSE; 00629 } /* End of AbsEvalCacheLookup */ 00630 00640 void 00641 AbsVerificationFlushCache( 00642 Abs_VerificationInfo_t *absInfo) 00643 { 00644 AbsEvalCacheEntry_t *value; 00645 st_table *table; 00646 bdd_node *key; 00647 st_generator *stgen; 00648 00649 table = AbsVerificationInfoReadImageCache(absInfo); 00650 00651 if (table == NIL(st_table)) { 00652 return; 00653 } 00654 00655 st_foreach_item(table, stgen, &key, &value) { 00656 AbsCacheEntryFree(value); 00657 } 00658 00659 st_free_table(table); 00660 AbsVerificationInfoSetImageCache(absInfo, NIL(st_table)); 00661 00662 return; 00663 } /* End of AbsVerificationFlushCache */ 00664 00675 void 00676 AbsVertexFlushCache( 00677 AbsVertexInfo_t *vertexPtr) 00678 { 00679 if (AbsVertexReadType(vertexPtr) == preImage_c) { 00680 if (AbsVertexReadSolutions(vertexPtr) != NIL(st_table)) { 00681 AbsEvalCacheEntry_t *value; 00682 bdd_node *key; 00683 st_generator *stgen; 00684 00685 st_foreach_item(AbsVertexReadSolutions(vertexPtr), stgen, &key, 00686 &value) { 00687 AbsCacheEntryFree(value); 00688 } 00689 st_free_table(AbsVertexReadSolutions(vertexPtr)); 00690 AbsVertexSetSolutions(vertexPtr, NIL(st_table)); 00691 } 00692 } 00693 00694 if (AbsVertexReadLeftKid(vertexPtr) != NIL(AbsVertexInfo_t)) { 00695 AbsVertexFlushCache(AbsVertexReadLeftKid(vertexPtr)); 00696 } 00697 00698 if (AbsVertexReadRightKid(vertexPtr) != NIL(AbsVertexInfo_t)) { 00699 AbsVertexFlushCache(AbsVertexReadRightKid(vertexPtr)); 00700 } 00701 00702 return; 00703 } /* End of AbsVertexFlushCache */ 00704 00715 mdd_t * 00716 AbsImageReadOrCompute( 00717 Abs_VerificationInfo_t *absInfo, 00718 Img_ImageInfo_t *imageInfo, 00719 mdd_t *set, 00720 mdd_t *careSet 00721 ) 00722 { 00723 AbsEvalCacheEntry_t *entry; 00724 st_table *table; 00725 bdd_node *f; 00726 mdd_t *result; 00727 long cpuTime; 00728 int complement; 00729 00730 entry = NIL(AbsEvalCacheEntry_t); 00731 table = AbsVerificationInfoReadImageCache(absInfo); 00732 f = bdd_get_node(set, &complement); 00733 00734 /* See if the table has been created */ 00735 if (table == NIL(st_table)) { 00736 table = st_init_table(st_ptrcmp, st_ptrhash); 00737 AbsVerificationInfoSetImageCache(absInfo, table); 00738 } 00739 else { 00740 /* Look up for the operation */ 00741 if (st_lookup(table, f, &entry)) { 00742 if (complement == AbsEvalCacheEntryReadComplement(entry) && 00743 mdd_lequal(careSet, AbsEvalCacheEntryReadCareSet(entry), 1, 1)) { 00744 result = mdd_dup(AbsEvalCacheEntryReadResult(entry)); 00745 return result; 00746 } 00747 else { 00748 st_delete(table, &f, &entry); 00749 00750 mdd_free(AbsEvalCacheEntryReadKey(entry)); 00751 mdd_free(AbsEvalCacheEntryReadResult(entry)); 00752 mdd_free(AbsEvalCacheEntryReadCareSet(entry)); 00753 } 00754 } 00755 } 00756 00757 /* The result has not been found. Compute it and insert it in the cache */ 00758 cpuTime = util_cpu_time(); 00759 result = Img_ImageInfoComputeFwdWithDomainVars(imageInfo, set, set, careSet); 00760 AbsStatsReadImageCpuTime(AbsVerificationInfoReadStats(absInfo))+= 00761 util_cpu_time() - cpuTime; 00762 AbsStatsReadExactImage(AbsVerificationInfoReadStats(absInfo))++; 00763 00764 if (entry == NIL(AbsEvalCacheEntry_t)) { 00765 entry = AbsCacheEntryInitialize(); 00766 } 00767 00768 AbsEvalCacheEntrySetKey(entry, mdd_dup(set)); 00769 AbsEvalCacheEntrySetComplement(entry, complement); 00770 AbsEvalCacheEntrySetResult(entry, mdd_dup(result)); 00771 AbsEvalCacheEntrySetCareSet(entry, mdd_dup(careSet)); 00772 00773 /* Insert the new entry in the cache */ 00774 st_insert(table, (char *)f, (char *)entry); 00775 00776 AbsStatsReadImageCacheEntries(AbsVerificationInfoReadStats(absInfo))++; 00777 00778 return result; 00779 } /* End of AbsImageReadOrCompute */ 00780 00793 array_t * 00794 AbsFormulaArrayVerify( 00795 Abs_VerificationInfo_t *absInfo, 00796 array_t *formulaArray) 00797 { 00798 AbsOptions_t *options; 00799 AbsVertexInfo_t *formulaPtr; 00800 Fsm_Fsm_t *fsm; 00801 array_t *result; 00802 mdd_manager *mddManager; 00803 int fIndex; 00804 int numReorderings; 00805 00806 /* Initialize some variables */ 00807 options = AbsVerificationInfoReadOptions(absInfo); 00808 mddManager = AbsVerificationInfoReadMddManager(absInfo); 00809 numReorderings = bdd_read_reorderings(mddManager); 00810 00811 /* Print the configuration of the system */ 00812 if (AbsOptionsReadVerbosity(options) & ABS_VB_PIFF) { 00813 (void) fprintf(vis_stdout, "ABS: System with (PI,FF) = (%d,%d)\n", 00814 st_count(AbsVerificationInfoReadQuantifyVars(absInfo)), 00815 st_count(AbsVerificationInfoReadStateVars(absInfo))); 00816 } 00817 00818 /* Create the array of results */ 00819 result = array_alloc(AbsVerificationResult_t, array_n(formulaArray)); 00820 00821 /* Obtain the fsm representing the complete circuit */ 00822 fsm = Fsm_FsmCreateFromNetworkWithPartition( 00823 AbsVerificationInfoReadNetwork(absInfo), NIL(graph_t)); 00824 00825 /* Traverse the array of formulas and verify all of them */ 00826 arrayForEachItem(AbsVertexInfo_t *, formulaArray, fIndex, formulaPtr) { 00827 Fsm_Fsm_t *localSystem; 00828 Fsm_Fsm_t *approxSystem; 00829 array_t *stateVarIds; 00830 mdd_t *initialStates; 00831 mdd_t *careStates; 00832 long cpuTime; 00833 int numBddVars; 00834 int mddId; 00835 int i; 00836 00837 /* Variable Initialization */ 00838 approxSystem = NIL(Fsm_Fsm_t); 00839 00840 /* Set the cpu-time lap */ 00841 cpuTime = util_cpu_time(); 00842 00843 /* Print the labeled operational graph */ 00844 if (AbsOptionsReadVerbosity(options) & ABS_VB_GRAPH) { 00845 (void) fprintf(vis_stdout, "ABS: === Labeled Operational Graph ===\n"); 00846 AbsVertexPrint(formulaPtr, NIL(st_table), TRUE, 00847 AbsOptionsReadVerbosity(options)); 00848 (void) fprintf(vis_stdout, "ABS: === End of Graph ===\n"); 00849 } 00850 00851 /* Simplify the system with respect to the given formula */ 00852 localSystem = AbsCreateReducedFsm(absInfo, formulaPtr, &approxSystem); 00853 if (localSystem == NIL(Fsm_Fsm_t)) { 00854 localSystem = fsm; 00855 } 00856 if (approxSystem == NIL(Fsm_Fsm_t)) { 00857 approxSystem = fsm; 00858 } 00859 00860 AbsVerificationInfoSetFsm(absInfo, localSystem); 00861 00862 /* Compute the number of bdd variables needed to encode the state space */ 00863 stateVarIds = Fsm_FsmReadPresentStateVars(localSystem); 00864 numBddVars = 0; 00865 arrayForEachItem(int, stateVarIds, i, mddId) { 00866 array_t *mvarList = mdd_ret_mvar_list(mddManager); 00867 mvar_type mddVar = array_fetch(mvar_type, mvarList, mddId); 00868 numBddVars += mddVar.encode_length; 00869 } 00870 AbsVerificationInfoSetNumStateVars(absInfo, numBddVars); 00871 00872 AbsVerificationInfoSetApproxFsm(absInfo, approxSystem); 00873 00874 if (AbsOptionsReadVerbosity(options) & ABS_VB_SIMPLE) { 00875 (void) fprintf(vis_stdout, 00876 "ABS: System Simplified from %d to %d latches\n", 00877 array_n(Fsm_FsmReadPresentStateVars(fsm)), 00878 array_n(Fsm_FsmReadPresentStateVars(localSystem))); 00879 (void) fprintf(vis_stdout, 00880 "ABS: System Approximated by %d of %d latches\n", 00881 array_n(Fsm_FsmReadPresentStateVars(approxSystem)), 00882 array_n(Fsm_FsmReadPresentStateVars(localSystem))); 00883 } 00884 00885 /* Compute reachability if requested */ 00886 if (AbsOptionsReadReachability(options)) { 00887 mdd_t *reachableStates; 00888 long cpuTime; 00889 00890 cpuTime = util_cpu_time(); 00891 00892 reachableStates = Fsm_FsmComputeReachableStates(localSystem, 0, 1, 0, 0, 00893 0, 0, 0,Fsm_Rch_Default_c, 0, 0, NIL(array_t), FALSE, 00894 NIL(array_t)); 00895 if (AbsOptionsReadVerbosity(options) & ABS_VB_PPROGR) { 00896 (void) fprintf(vis_stdout, "ABS: %7.1f secs spent in reachability \n", 00897 (util_cpu_time() - cpuTime)/1000.0); 00898 } 00899 00900 /* Print the number of reachable states */ 00901 if (AbsOptionsReadVerbosity(options) & ABS_VB_PRCH) { 00902 array_t *sVars; 00903 00904 sVars = Fsm_FsmReadPresentStateVars(localSystem); 00905 (void) fprintf(vis_stdout, "ABS: System with %.0f reachable states.\n", 00906 mdd_count_onset(mddManager, reachableStates, sVars)); 00907 } 00908 00909 careStates = reachableStates; 00910 } /* End of reachability analysis */ 00911 else { 00912 careStates = mdd_one(mddManager); 00913 } 00914 00915 /* Compute the initial states */ 00916 initialStates = Fsm_FsmComputeInitialStates(localSystem); 00917 if (initialStates == NIL(mdd_t)) { 00918 (void) fprintf(vis_stdout, "** abs error: Unable to compute initial states.\n"); 00919 (void) fprintf(vis_stdout, "ABS: %s\n", error_string()); 00920 00921 AbsVerificationInfoFree(absInfo); 00922 array_free(result); 00923 /* Deallocate the FSM if the system was reduced */ 00924 if (localSystem != fsm) { 00925 Fsm_FsmFree(localSystem); 00926 } 00927 return NIL(array_t); 00928 } 00929 00930 /* Set the don't care information */ 00931 if (AbsVerificationInfoReadCareSet(absInfo) != NIL(mdd_t)) { 00932 mdd_free(AbsVerificationInfoReadCareSet(absInfo)); 00933 } 00934 AbsVerificationInfoSetCareSet(absInfo, careStates); 00935 if (AbsVerificationInfoReadTmpCareSet(absInfo) != NIL(mdd_t)) { 00936 mdd_free(AbsVerificationInfoReadTmpCareSet(absInfo)); 00937 } 00938 AbsVerificationInfoSetTmpCareSet(absInfo, mdd_one(mddManager)); 00939 00940 /* Compute the formula EG(true) if required */ 00941 if (AbsOptionsReadEnvelope(options)) { 00942 mdd_t *newCareStates; 00943 mdd_t *tmp1; 00944 00945 newCareStates = ComputeEGtrue(absInfo, careStates); 00946 tmp1 = mdd_and(newCareStates, careStates, 1, 1); 00947 mdd_free(careStates); 00948 mdd_free(newCareStates); 00949 careStates = tmp1; 00950 AbsVerificationInfoSetCareSet(absInfo, careStates); 00951 } 00952 00953 /* Print verbosity message */ 00954 if (AbsOptionsReadVerbosity(options) & ABS_VB_VTXCNT) { 00955 (void) fprintf(vis_stdout, "ABS: === Initial Verification ===\n"); 00956 } 00957 00958 /* Create the initial evaluation of the formula */ 00959 AbsSubFormulaVerify(absInfo, formulaPtr); 00960 00961 assert(!AbsVertexReadTrueRefine(formulaPtr)); 00962 00963 /* Print verbosity message */ 00964 if (AbsOptionsReadVerbosity(options) & ABS_VB_VTXCNT) { 00965 (void) fprintf(vis_stdout, "ABS: === End of Initial Verification ===\n"); 00966 } 00967 00968 /* Print cpu-time information */ 00969 if (AbsOptionsReadVerbosity(options) & ABS_VB_PPROGR) { 00970 (void) fprintf(vis_stdout, "ABS: Initial verification: %7.1f secs.\n", 00971 (util_cpu_time() - cpuTime)/1000.0); 00972 } 00973 00974 /* Check if the initial states satisfy the formula */ 00975 if (mdd_lequal(initialStates, AbsVertexReadSat(formulaPtr), 1, 1)) { 00976 array_insert(int, result, fIndex, trueVerification_c); 00977 } 00978 else { 00979 if (AbsVertexReadGlobalApprox(formulaPtr)) { 00980 mdd_t *goalSet; 00981 mdd_t *refinement; 00982 00983 /* 00984 * Compute the set of states remaining in the goal. We are assuming 00985 * that the parity of the top vertex is negative 00986 */ 00987 assert(!AbsVertexReadPolarity(formulaPtr)); 00988 00989 /* Compute the initial goal set */ 00990 goalSet = mdd_and(initialStates, AbsVertexReadSat(formulaPtr), 1, 0); 00991 00992 /* Notify that the refinement process is beginning */ 00993 if (AbsOptionsReadVerbosity(options) &ABS_VB_PPROGR) { 00994 (void) fprintf(vis_stdout, 00995 "ABS: Verification has been approximated. "); 00996 (void) fprintf(vis_stdout, "Beginning approximation refinement\n"); 00997 } 00998 00999 /* Print the number of states to refine */ 01000 if (AbsOptionsReadVerbosity(options) & ABS_VB_PRINIT) { 01001 array_t *sVars; 01002 01003 sVars = Fsm_FsmReadPresentStateVars(fsm); 01004 (void) fprintf(vis_stdout, 01005 "ABS: %.0f states out of %.0f to be refined\n", 01006 mdd_count_onset(mddManager, goalSet, sVars), 01007 mdd_count_onset(mddManager, initialStates, sVars)); 01008 } 01009 01010 /* Effectively perform the refinement */ 01011 refinement = AbsSubFormulaRefine(absInfo, formulaPtr, goalSet); 01012 01013 /* Insert the outcome of the refinement in the solution */ 01014 if (mdd_is_tautology(refinement, 0)) { 01015 array_insert(int, result, fIndex, trueVerification_c); 01016 } 01017 else { 01018 if (!AbsVertexReadTrueRefine(formulaPtr)) { 01019 array_insert(int, result, fIndex, inconclusiveVerification_c); 01020 } 01021 else { 01022 array_insert(int, result, fIndex, falseVerification_c); 01023 } 01024 } 01025 mdd_free(goalSet); 01026 mdd_free(refinement); 01027 } 01028 else { 01029 array_insert(int, result, fIndex, falseVerification_c); 01030 } 01031 } 01032 mdd_free(initialStates); 01033 01034 /* Print cpu-time information */ 01035 if (AbsOptionsReadVerbosity(options) & ABS_VB_PPROGR) { 01036 (void) fprintf(vis_stdout, "ABS: Formula #%d verified in %7.1f secs.\n", 01037 fIndex + 1, (util_cpu_time() - cpuTime)/1000.0); 01038 } 01039 01040 /* Print the number of states in the on set of Sat */ 01041 if (AbsOptionsReadVerbosity(options) & ABS_VB_TSAT) { 01042 array_t *sVars; 01043 01044 sVars = Fsm_FsmReadPresentStateVars(localSystem); 01045 (void) fprintf(vis_stdout, "ABS: %.0f States in sat of the formula.\n", 01046 mdd_count_onset(mddManager, AbsVertexReadSat(formulaPtr), 01047 sVars)); 01048 } 01049 01050 /* Clean up */ 01051 AbsVertexFlushCache(formulaPtr); 01052 AbsVerificationFlushCache(absInfo); 01053 if (approxSystem != fsm) { 01054 Fsm_FsmFree(approxSystem); 01055 } 01056 if (localSystem != fsm) { 01057 Fsm_FsmFree(localSystem); 01058 } 01059 } /* End of the loop over the array of formulas to be verified */ 01060 01061 /* Set the number of reorderings in the stats */ 01062 AbsStatsSetNumReorderings(AbsVerificationInfoReadStats(absInfo), 01063 bdd_read_reorderings(mddManager) - numReorderings); 01064 01065 /* Clean up */ 01066 Fsm_FsmFree(fsm); 01067 01068 return result; 01069 } 01070 01079 Fsm_Fsm_t * 01080 AbsCreateReducedFsm( 01081 Abs_VerificationInfo_t *absInfo, 01082 AbsVertexInfo_t *vertexPtr, 01083 Fsm_Fsm_t **approxFsm) 01084 { 01085 AbsVertexInfo_t *vPtr; 01086 Ntk_Network_t *network; 01087 Ntk_Node_t *nodePtr; 01088 Fsm_Fsm_t *result; 01089 lsGen gen; 01090 array_t *vertexArray; 01091 array_t *nodeArray; 01092 array_t *supportArray; 01093 array_t *inputs; 01094 array_t *latches; 01095 st_table *visited; 01096 int i; 01097 01098 if (vertexPtr == NIL(AbsVertexInfo_t)) { 01099 return NIL(Fsm_Fsm_t); 01100 } 01101 01102 network = AbsVerificationInfoReadNetwork(absInfo); 01103 01104 /* Select the vertices of type "identifier" */ 01105 visited = st_init_table(st_ptrcmp, st_ptrhash); 01106 vertexArray = array_alloc(AbsVertexInfo_t *, 0); 01107 SelectIdentifierVertices(vertexPtr, vertexArray, visited); 01108 st_free_table(visited); 01109 01110 if (array_n(vertexArray) == 0) { 01111 array_free(vertexArray); 01112 return NIL(Fsm_Fsm_t); 01113 } 01114 01115 /* Create the array of network nodes corresponding to the identifiers */ 01116 visited = st_init_table(st_ptrcmp, st_ptrhash); 01117 nodeArray = array_alloc(Ntk_Node_t *, 0); 01118 arrayForEachItem(AbsVertexInfo_t *, vertexArray, i, vPtr) { 01119 nodePtr = Ntk_NetworkFindNodeByName(network, AbsVertexReadName(vPtr)); 01120 01121 assert(nodePtr != NIL(Ntk_Node_t)); 01122 01123 if (!st_is_member(visited, (char *)nodePtr)) { 01124 array_insert_last(Ntk_Node_t *, nodeArray, nodePtr); 01125 st_insert(visited, (char *)nodePtr, NIL(char)); 01126 } 01127 } 01128 array_free(vertexArray); 01129 01130 /* Create the input and array latches to compute the approxFsm */ 01131 inputs = array_alloc(Ntk_Node_t *, 0); 01132 Ntk_NetworkForEachInput(network, gen, nodePtr) { 01133 array_insert_last(Ntk_Node_t *, inputs, nodePtr); 01134 } 01135 latches = array_alloc(Ntk_Node_t *, 0); 01136 Ntk_NetworkForEachLatch(network, gen, nodePtr) { 01137 if (st_is_member(visited, (char *)nodePtr)) { 01138 array_insert_last(Ntk_Node_t *, latches, nodePtr); 01139 } 01140 else { 01141 array_insert_last(Ntk_Node_t *, inputs, nodePtr); 01142 } 01143 } 01144 st_free_table(visited); 01145 01146 /* Obtain the approximated system */ 01147 *approxFsm = Fsm_FsmCreateReducedFsm(network, NIL(graph_t), latches, inputs, 01148 NIL(array_t)); 01149 array_free(inputs); 01150 array_free(latches); 01151 01152 /* Obtain the transitive fanin of the nodes */ 01153 supportArray = Ntk_NodeComputeCombinationalSupport(network, nodeArray, FALSE); 01154 array_free(nodeArray); 01155 01156 /* If the transitive fanin of the nodes is empty, return */ 01157 if (array_n(supportArray) == 0) { 01158 array_free(supportArray); 01159 return NIL(Fsm_Fsm_t); 01160 } 01161 01162 /* Divide the nodes between inputs and latches and create the final FSM */ 01163 inputs = array_alloc(Ntk_Node_t *, 0); 01164 latches = array_alloc(Ntk_Node_t *, 0); 01165 arrayForEachItem(Ntk_Node_t *, supportArray, i, nodePtr) { 01166 if (Ntk_NodeTestIsInput(nodePtr)) { 01167 array_insert_last(Ntk_Node_t *, inputs, nodePtr); 01168 } 01169 else { 01170 assert(Ntk_NodeTestIsLatch(nodePtr)); 01171 array_insert_last(Ntk_Node_t *, latches, nodePtr); 01172 } 01173 } 01174 array_free(supportArray); 01175 01176 /* If the collection of inputs and latches is the whole FSM, return */ 01177 if (array_n(inputs) == Ntk_NetworkReadNumInputs(network) && 01178 array_n(latches) == Ntk_NetworkReadNumLatches(network)) { 01179 array_free(inputs); 01180 array_free(latches); 01181 return NIL(Fsm_Fsm_t); 01182 } 01183 01184 result = Fsm_FsmCreateReducedFsm(network, NIL(graph_t), latches, inputs, 01185 NIL(array_t)); 01186 01187 /* Clean up */ 01188 array_free(inputs); 01189 array_free(latches); 01190 01191 return result; 01192 } /* End of AbsCreateReducedFsm */ 01193 01202 boolean 01203 AbsMddEqualModCareSet( 01204 mdd_t *f, 01205 mdd_t *g, 01206 mdd_t *careSet) 01207 { 01208 boolean result = mdd_equal_mod_care_set(f, g, careSet); 01209 return result; 01210 } /* End of AbsMddEqualModCareSet */ 01211 01220 boolean 01221 AbsMddLEqualModCareSet( 01222 mdd_t *f, 01223 mdd_t *g, 01224 mdd_t *careSet) 01225 { 01226 boolean result = mdd_lequal_mod_care_set(f, g, 1, 1, careSet); 01227 return result; 01228 } /* End of AbsMddLEqualModCareSet */ 01229 01230 /*---------------------------------------------------------------------------*/ 01231 /* Definition of static functions */ 01232 /*---------------------------------------------------------------------------*/ 01233 01249 static mdd_t * 01250 ComputeEGtrue( 01251 Abs_VerificationInfo_t *absInfo, 01252 mdd_t *careStates) 01253 { 01254 AbsOptions_t *options; 01255 AbsVertexInfo_t *vertex; 01256 Ctlp_Formula_t *egFormula; 01257 Ctlp_Formula_t *trueFormula; 01258 mdd_manager *mddManager; 01259 array_t *inputTranslation; 01260 array_t *outputTranslation; 01261 mdd_t *envelope; 01262 long cpuTime; 01263 01264 cpuTime = util_cpu_time(); 01265 options = AbsVerificationInfoReadOptions(absInfo); 01266 mddManager = AbsVerificationInfoReadMddManager(absInfo); 01267 01268 /* Compute the EG(true) fixed point */ 01269 trueFormula = Ctlp_FormulaCreate(Ctlp_TRUE_c, NIL(void), NIL(void)); 01270 egFormula = Ctlp_FormulaCreate(Ctlp_EG_c, trueFormula, NIL(void)); 01271 01272 /* Translate into the graph representation */ 01273 inputTranslation = array_alloc(Ctlp_Formula_t *, 1); 01274 array_insert(Ctlp_Formula_t *, inputTranslation, 0, egFormula); 01275 outputTranslation = AbsCtlFormulaArrayTranslate(absInfo, inputTranslation, 01276 NIL(array_t)); 01277 vertex = array_fetch(AbsVertexInfo_t *, outputTranslation, 0); 01278 array_free(inputTranslation); 01279 array_free(outputTranslation); 01280 01281 /* Evaluate the formula */ 01282 AbsSubFormulaVerify(absInfo, vertex); 01283 01284 envelope = mdd_dup(AbsVertexReadSat(vertex)); 01285 01286 /* Clean up */ 01287 Ctlp_FormulaFree(egFormula); 01288 AbsVertexFree(AbsVerificationInfoReadCatalog(absInfo), vertex, 01289 NIL(AbsVertexInfo_t)); 01290 01291 /* Print the number of envelope states */ 01292 if (AbsOptionsReadVerbosity(options) & ABS_VB_PENV) { 01293 array_t *sVars; 01294 mdd_t *states; 01295 01296 sVars = Fsm_FsmReadPresentStateVars(AbsVerificationInfoReadFsm(absInfo)); 01297 states = mdd_and(envelope, careStates, 1, 1); 01298 (void) fprintf(vis_stdout, "ABS: Envelope with %.0f care states.\n", 01299 mdd_count_onset(mddManager, states, sVars)); 01300 mdd_free(states); 01301 } 01302 01303 if (AbsOptionsReadVerbosity(options) & ABS_VB_PENV) { 01304 (void) fprintf(vis_stdout, "ABS: %7.1f secs computing EG(TRUE)\n", 01305 (util_cpu_time() - cpuTime)/1000.0); 01306 } 01307 01308 return envelope; 01309 } /* End of ComputeEGtrue */ 01310 01319 static void 01320 SelectIdentifierVertices( 01321 AbsVertexInfo_t *vertexPtr, 01322 array_t *result, 01323 st_table *visited) 01324 { 01325 assert(result != NIL(array_t)); 01326 01327 if (vertexPtr == NIL(AbsVertexInfo_t)) { 01328 return; 01329 } 01330 01331 if (st_is_member(visited, (char *)vertexPtr)) { 01332 return; 01333 } 01334 01335 if (AbsVertexReadType(vertexPtr) == identifier_c) { 01336 array_insert_last(AbsVertexInfo_t *, result, vertexPtr); 01337 st_insert(visited, (char *)vertexPtr, NIL(char)); 01338 return; 01339 } 01340 else { 01341 SelectIdentifierVertices(AbsVertexReadLeftKid(vertexPtr), result, visited); 01342 SelectIdentifierVertices(AbsVertexReadRightKid(vertexPtr), result, visited); 01343 } 01344 01345 st_insert(visited, (char *)vertexPtr, NIL(char)); 01346 01347 return; 01348 } /* End of SelectIdentifierVertices */