VIS
|
00001 00030 #include "grabInt.h" 00031 00032 /*---------------------------------------------------------------------------*/ 00033 /* Constant declarations */ 00034 /*---------------------------------------------------------------------------*/ 00035 00036 /*---------------------------------------------------------------------------*/ 00037 /* Structure declarations */ 00038 /*---------------------------------------------------------------------------*/ 00039 00040 /*---------------------------------------------------------------------------*/ 00041 /* Type declarations */ 00042 /*---------------------------------------------------------------------------*/ 00043 00044 /*---------------------------------------------------------------------------*/ 00045 /* Variable declarations */ 00046 /*---------------------------------------------------------------------------*/ 00047 00048 /*---------------------------------------------------------------------------*/ 00049 /* Macro declarations */ 00050 /*---------------------------------------------------------------------------*/ 00051 00054 /*---------------------------------------------------------------------------*/ 00055 /* Static function prototypes */ 00056 /*---------------------------------------------------------------------------*/ 00057 00058 static void GetFormulaNodes(Ntk_Network_t *network, Ctlp_Formula_t *F, array_t *formulaNodes); 00059 static void GetFaninLatches(Ntk_Node_t *node, st_table *visited, st_table *absVarTable); 00060 static void NodeTableAddCtlFormulaNodes(Ntk_Network_t *network, Ctlp_Formula_t *formula, st_table * nodesTable); 00061 00064 /*---------------------------------------------------------------------------*/ 00065 /* Definition of internal functions */ 00066 /*---------------------------------------------------------------------------*/ 00067 00078 st_table * 00079 GrabComputeCOIAbstraction( 00080 Ntk_Network_t *network, 00081 Ctlp_Formula_t *invFormula) 00082 { 00083 st_table *formulaNodes; 00084 array_t *formulaCombNodes; 00085 Ntk_Node_t *node; 00086 array_t *nodeArray; 00087 int i; 00088 st_generator *stGen; 00089 st_table *absVarTable; 00090 00091 /* find network nodes in the immediate support of the property */ 00092 formulaNodes = st_init_table(st_ptrcmp, st_ptrhash); 00093 NodeTableAddCtlFormulaNodes(network, invFormula, formulaNodes); 00094 00095 /* find network nodes in the transitive fan-in */ 00096 nodeArray = array_alloc(Ntk_Node_t *, 0); 00097 st_foreach_item(formulaNodes, stGen, & node, NIL(char *)) { 00098 array_insert_last( Ntk_Node_t *, nodeArray, node); 00099 } 00100 st_free_table(formulaNodes); 00101 formulaCombNodes = Ntk_NodeComputeTransitiveFaninNodes(network, nodeArray, 00102 FALSE, TRUE); 00103 array_free(nodeArray); 00104 00105 /* extract all the latches */ 00106 absVarTable = st_init_table(st_ptrcmp, st_ptrhash); 00107 arrayForEachItem(Ntk_Node_t *, formulaCombNodes, i, node) { 00108 if (Ntk_NodeTestIsLatch(node) == TRUE) { 00109 st_insert(absVarTable, node, (char *)0); 00110 } 00111 } 00112 array_free(formulaCombNodes); 00113 00114 return absVarTable; 00115 } 00116 00127 st_table * 00128 GrabComputeInitialAbstraction( 00129 Ntk_Network_t *network, 00130 Ctlp_Formula_t *invFormula) 00131 { 00132 array_t *formulaNodes = array_alloc(Ntk_Node_t *, 0); 00133 Ntk_Node_t *node; 00134 int i; 00135 st_table *absVarTable, *visited; 00136 00137 GetFormulaNodes(network, invFormula, formulaNodes); 00138 00139 absVarTable = st_init_table(st_ptrcmp, st_ptrhash); 00140 visited = st_init_table(st_ptrcmp, st_ptrhash); 00141 arrayForEachItem(Ntk_Node_t *, formulaNodes, i, node) { 00142 GetFaninLatches(node, visited, absVarTable); 00143 } 00144 00145 st_free_table(visited); 00146 array_free(formulaNodes); 00147 00148 return absVarTable; 00149 } 00150 00170 void 00171 GrabUpdateAbstractPartition( 00172 Ntk_Network_t *network, 00173 st_table *coiBnvTable, 00174 st_table *absVarTable, 00175 st_table *absBnvTable, 00176 int partitionFlag) 00177 { 00178 graph_t *newPart; 00179 st_table *useAbsBnvTable = absBnvTable? absBnvTable:coiBnvTable; 00180 00181 if (partitionFlag == GRAB_PARTITION_BUILD) { 00182 00183 /* free the existing partition */ 00184 Ntk_NetworkFreeApplInfo(network, PART_NETWORK_APPL_KEY); 00185 00186 /* insert bnvs whenever necessary. Note that when the current 00187 * partition is not available, this function will create new bnvs 00188 * and put them into the coiBnvTable. Otherwise, it retrieves 00189 * existing bnvs from the current partiton */ 00190 Part_PartitionReadOrCreateBnvs(network, absVarTable, coiBnvTable); 00191 00192 /* create the new partition */ 00193 newPart = g_alloc(); 00194 newPart->user_data = (gGeneric)PartPartitionInfoCreate("default", 00195 Ntk_NetworkReadMddManager(network), 00196 Part_Frontier_c); 00197 Part_PartitionWithExistingBnvs(network, newPart, coiBnvTable, 00198 absVarTable, useAbsBnvTable); 00199 Ntk_NetworkAddApplInfo(network, PART_NETWORK_APPL_KEY, 00200 (Ntk_ApplInfoFreeFn) Part_PartitionFreeCallback, 00201 (void *) newPart); 00202 00203 }else if (partitionFlag == GRAB_PARTITION_UPDATE) { 00204 fprintf(vis_stdout, 00205 "\n ** grab error: GRAB_PARTITION_UPDATE not implemented\n"); 00206 assert(0); 00207 } 00208 00209 } 00210 00229 Fsm_Fsm_t * 00230 GrabCreateAbstractFsm( 00231 Ntk_Network_t *network, 00232 st_table *coiBnvTable, 00233 st_table *absVarTable, 00234 st_table *absBnvTable, 00235 int partitionFlag, 00236 int independentFlag) 00237 { 00238 Fsm_Fsm_t *fsm; 00239 array_t *absLatches = array_alloc(Ntk_Node_t *, 0); 00240 array_t *invisibleVars = array_alloc(Ntk_Node_t *, 0); 00241 array_t *absInputs = array_alloc(Ntk_Node_t *, 0); 00242 array_t *rootNodesArray = array_alloc(Ntk_Node_t *, 0); 00243 st_table *rawLeafNodesTable = st_init_table(st_ptrcmp, st_ptrhash); 00244 lsList topologicalNodeList; 00245 lsGen lsgen; 00246 st_generator *stgen; 00247 Ntk_Node_t *node; 00248 00249 GrabUpdateAbstractPartition(network, coiBnvTable, absVarTable, absBnvTable, 00250 partitionFlag); 00251 00252 /* first, compute the absLatches, invisibleVars, and absInputs: 00253 * absLatches includes all the visible latch variables; 00254 * invisibleVars includes all the invisible latches variables; 00255 * absInputs includes all the primary and pseudo inputs. 00256 */ 00257 st_foreach_item(absVarTable, stgen, &node, NIL(char *)) { 00258 array_insert_last(Ntk_Node_t *, absLatches, node); 00259 array_insert_last(Ntk_Node_t *, rootNodesArray, 00260 Ntk_LatchReadDataInput(node)); 00261 array_insert_last(Ntk_Node_t *, rootNodesArray, 00262 Ntk_LatchReadInitialInput(node)); 00263 } 00264 00265 Ntk_NetworkForEachCombInput(network, lsgen, node) { 00266 st_insert(rawLeafNodesTable, node, (char *) (long) (-1) ); 00267 } 00268 st_foreach_item(coiBnvTable, stgen, &node, NIL(char *)) { 00269 /* unless it blongs to the current Abstract Model */ 00270 if (absBnvTable && !st_is_member(absBnvTable, node)) 00271 st_insert(rawLeafNodesTable, node, (char *) (long) (-1) ); 00272 } 00273 00274 topologicalNodeList = Ntk_NetworkComputeTopologicalOrder(network, 00275 rootNodesArray, 00276 rawLeafNodesTable); 00277 lsForEachItem(topologicalNodeList, lsgen, node){ 00278 if (st_is_member(rawLeafNodesTable, node) && 00279 !st_is_member(absVarTable, node) ) { 00280 /*if (Ntk_NodeTestIsLatch(node) || 00281 coiBnvTable && st_is_member(coiBnvTable, node))*/ 00282 if (Ntk_NodeTestIsLatch(node) || 00283 (coiBnvTable && st_is_member(coiBnvTable, node))) 00284 array_insert_last(Ntk_Node_t *, invisibleVars, node); 00285 else 00286 array_insert_last(Ntk_Node_t *, absInputs, node); 00287 } 00288 } 00289 00290 lsDestroy(topologicalNodeList, (void (*)(lsGeneric))0); 00291 st_free_table(rawLeafNodesTable); 00292 array_free(rootNodesArray); 00293 00294 00295 /* now, create the abstract Fsm according to the value of 00296 * independentFlag when independentFlag is TRUE, the present state 00297 * varaibles are absLatches; otherwise, they contain both absLatches 00298 * and invisibleVars (with such a FSM, preimages may contain 00299 * invisible vars in their supports) 00300 */ 00301 fsm = Fsm_FsmCreateAbstractFsm(network, NIL(graph_t), 00302 absLatches, invisibleVars, absInputs, 00303 NIL(array_t), independentFlag); 00304 00305 #if 0 00306 /* for debugging */ 00307 if (partitionFlag == GRAB_PARTITION_NOCHANGE) { 00308 GrabPrintNodeArray("absLatches", absLatches); 00309 GrabPrintNodeArray("invisibleVars", invisibleVars); 00310 GrabPrintNodeArray("absInputs", absInputs); 00311 } 00312 #endif 00313 00314 array_free(invisibleVars); 00315 array_free(absInputs); 00316 array_free(absLatches); 00317 00318 00319 return fsm; 00320 } 00321 00346 mdd_t * 00347 GrabComputeInitialStates( 00348 Ntk_Network_t *network, 00349 array_t *psVars) 00350 { 00351 int i = 0; 00352 mdd_t *initStates; 00353 Ntk_Node_t *node; 00354 array_t *initRelnArray; 00355 array_t *initMvfs; 00356 array_t *initNodes; 00357 array_t *initVertices; 00358 array_t *latchMddIds; 00359 array_t *inputVars = array_alloc(int, 0); 00360 array_t *combArray; 00361 st_table *supportNodes; 00362 st_table *supportVertices; 00363 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 00364 graph_t *partition = 00365 (graph_t *) Ntk_NetworkReadApplInfo(network, PART_NETWORK_APPL_KEY); 00366 int numLatches; 00367 Img_MethodType imageMethod; 00368 00369 numLatches = array_n(psVars); 00370 00371 /* Get the array of initial nodes, both as network nodes and as 00372 * partition vertices. 00373 */ 00374 initNodes = array_alloc(Ntk_Node_t *, numLatches); 00375 initVertices = array_alloc(vertex_t *, numLatches); 00376 latchMddIds = array_alloc(int, numLatches); 00377 for (i=0; i<numLatches; i++){ 00378 int latchMddId = array_fetch(int, psVars, i); 00379 Ntk_Node_t *latch = Ntk_NetworkFindNodeByMddId(network, latchMddId); 00380 Ntk_Node_t *initNode = Ntk_LatchReadInitialInput(latch); 00381 vertex_t *initVertex = Part_PartitionFindVertexByName(partition, 00382 Ntk_NodeReadName(initNode)); 00383 array_insert(Ntk_Node_t *, initNodes, i, initNode); 00384 array_insert(vertex_t *, initVertices, i, initVertex); 00385 array_insert(int, latchMddIds, i, Ntk_NodeReadMddId(latch)); 00386 } 00387 00388 /* Get the table of legal support nodes, both as network nodes and 00389 * as partition vertices. Inputs (both primary and pseudo) and 00390 * constants constitute the legal support nodes. 00391 */ 00392 supportNodes = st_init_table(st_ptrcmp, st_ptrhash); 00393 supportVertices = st_init_table(st_ptrcmp, st_ptrhash); 00394 combArray = Ntk_NodeComputeTransitiveFaninNodes(network, initNodes, TRUE, 00395 TRUE); 00396 arrayForEachItem(Ntk_Node_t *, combArray, i, node) { 00397 vertex_t *vertex = Part_PartitionFindVertexByName(partition, 00398 Ntk_NodeReadName(node)); 00399 if (Ntk_NodeTestIsConstant(node) || Ntk_NodeTestIsInput(node)) { 00400 st_insert(supportNodes, node, NIL(char)); 00401 st_insert(supportVertices, vertex, NIL(char)); 00402 } 00403 if (Ntk_NodeTestIsInput(node)) { 00404 assert(Ntk_NodeReadMddId(node) != -1); 00405 array_insert_last(int, inputVars, Ntk_NodeReadMddId(node)); 00406 } 00407 } 00408 array_free(combArray); 00409 array_free(initNodes); 00410 st_free_table(supportNodes); 00411 00412 /* Compute the initial states 00413 */ 00414 initMvfs = Part_PartitionCollapse(partition, initVertices, 00415 supportVertices, NIL(mdd_t)); 00416 array_free(initVertices); 00417 st_free_table(supportVertices); 00418 00419 /* Compute the relation (x_i = g_i(u)) for each latch. */ 00420 initRelnArray = array_alloc(mdd_t*, numLatches); 00421 for (i = 0; i < numLatches; i++) { 00422 int latchMddId = array_fetch(int, latchMddIds, i); 00423 Mvf_Function_t *initMvf = array_fetch(Mvf_Function_t *, initMvfs, i); 00424 mdd_t *initLatchReln = Mvf_FunctionBuildRelationWithVariable(initMvf, 00425 latchMddId); 00426 array_insert(mdd_t *, initRelnArray, i, initLatchReln); 00427 } 00428 00429 array_free(latchMddIds); 00430 Mvf_FunctionArrayFree(initMvfs); 00431 00432 imageMethod = Img_UserSpecifiedMethod(); 00433 if (imageMethod != Img_Iwls95_c && imageMethod != Img_Mlp_c) 00434 imageMethod = Img_Iwls95_c; 00435 00436 initStates = Img_MultiwayLinearAndSmooth(mddManager, initRelnArray, 00437 inputVars, psVars, 00438 imageMethod, Img_Forward_c); 00439 00440 mdd_array_free(initRelnArray); 00441 00442 array_free(inputVars); 00443 00444 return (initStates); 00445 } 00446 00456 mdd_t * 00457 GrabFsmComputeReachableStates( 00458 Fsm_Fsm_t *absFsm, 00459 st_table *absVarTable, 00460 st_table *absBnvTable, 00461 array_t *invStatesArray, 00462 int verbose) 00463 { 00464 mdd_manager *mddManager = Fsm_FsmReadMddManager(absFsm); 00465 Img_ImageInfo_t *imageInfo; 00466 array_t *fwdOnionRings; 00467 mdd_t *initStates, *mdd1, *mddOne, *rchStates, *frontier; 00468 00469 imageInfo = Fsm_FsmReadOrCreateImageInfo(absFsm, 0, 1); 00470 00471 fwdOnionRings = array_alloc(mdd_t *, 0); 00472 mddOne = mdd_one(mddManager); 00473 initStates = Fsm_FsmComputeInitialStates(absFsm); 00474 array_insert_last(mdd_t *, fwdOnionRings, initStates); 00475 rchStates = mdd_dup(initStates); 00476 00477 frontier = initStates; 00478 while(TRUE) { 00479 mdd1 = Img_ImageInfoComputeFwdWithDomainVars(imageInfo, frontier, 00480 rchStates, mddOne); 00481 frontier = mdd_and(mdd1, rchStates, 1, 0); 00482 mdd_free(mdd1); 00483 00484 mdd1 = rchStates; 00485 rchStates = mdd_or(rchStates, frontier, 1, 1); 00486 mdd_free(mdd1); 00487 00488 if (mdd_is_tautology(frontier, 0)) { 00489 mdd_free(frontier); 00490 break; 00491 } 00492 array_insert_last(mdd_t *, fwdOnionRings, frontier); 00493 00494 /* if this happens, the invariant is voilated */ 00495 if (!mdd_lequal_array(frontier, invStatesArray, 1, 1)) 00496 break; 00497 } 00498 00499 mdd_free(mddOne); 00500 00501 FsmSetReachabilityOnionRings(absFsm, fwdOnionRings); 00502 00503 return rchStates; 00504 } 00505 00515 mdd_t * 00516 GrabFsmComputeConstrainedReachableStates( 00517 Fsm_Fsm_t *absFsm, 00518 st_table *absVarTable, 00519 st_table *absBnvTable, 00520 array_t *SORs, 00521 int verbose) 00522 { 00523 mdd_manager *mddManager = Fsm_FsmReadMddManager(absFsm); 00524 Img_ImageInfo_t *imageInfo; 00525 array_t *rchOnionRings; 00526 mdd_t *mdd1, *mdd2, *mdd3, *mdd4; 00527 mdd_t *mddOne, *initStates, *rchStates; 00528 int i; 00529 00530 assert (SORs != NIL(array_t)); 00531 00532 imageInfo = Fsm_FsmReadOrCreateImageInfo(absFsm, 0, 1); 00533 00534 rchOnionRings = array_alloc(mdd_t *, 0); 00535 mddOne = mdd_one(mddManager); 00536 00537 /* the new initial states */ 00538 mdd2 = array_fetch(mdd_t *, SORs, 0); 00539 mdd1 = Fsm_FsmComputeInitialStates(absFsm); 00540 initStates = mdd_and(mdd1, mdd2, 1, 1); 00541 mdd_free(mdd1); 00542 array_insert(mdd_t *, rchOnionRings, 0, initStates); 00543 00544 /* compute the reachable states inside the previous SORs */ 00545 rchStates = mdd_dup(initStates); 00546 for (i=0; i<array_n(SORs)-1; i++) { 00547 mdd1 = array_fetch(mdd_t *, rchOnionRings, i); 00548 mdd2 = Img_ImageInfoComputeFwdWithDomainVars(imageInfo, 00549 mdd1, 00550 rchStates, 00551 mddOne); 00552 00553 mdd3 = array_fetch(mdd_t *, SORs, i+1); 00554 mdd4 = mdd_and(mdd2, mdd3, 1, 1); 00555 mdd_free(mdd2); 00556 00557 /* if this happens, the last ring is no longer reachable */ 00558 if (mdd_is_tautology(mdd4, 0)) { 00559 mdd_free(mdd4); 00560 break; 00561 } 00562 array_insert(mdd_t *, rchOnionRings, i+1, mdd4); 00563 00564 mdd1 = rchStates; 00565 rchStates = mdd_or(rchStates, mdd4, 1, 1); 00566 mdd_free(mdd1); 00567 } 00568 00569 mdd_free(mddOne); 00570 00571 FsmSetReachabilityOnionRings(absFsm, rchOnionRings); 00572 00573 return rchStates; 00574 } 00575 00595 array_t * 00596 GrabFsmComputeSynchronousOnionRings( 00597 Fsm_Fsm_t *absFsm, 00598 st_table *absVarTable, 00599 st_table *absBnvTable, 00600 array_t *oldRings, 00601 mdd_t *inv_states, 00602 int cexType, 00603 int verbose) 00604 { 00605 mdd_manager *mddManager = Fsm_FsmReadMddManager(absFsm); 00606 Img_ImageInfo_t *imageInfo; 00607 array_t *onionRings, *synOnionRings; 00608 array_t *allPSVars; 00609 mdd_t *mddOne, *ring; 00610 mdd_t *mdd1, *mdd2, *mdd3, *mdd4; 00611 int j; 00612 00613 imageInfo = Fsm_FsmReadOrCreateImageInfo(absFsm, 1, 0); 00614 00615 /* get the forward reachability onion rings */ 00616 onionRings = oldRings; 00617 if (onionRings == NIL(array_t)) 00618 onionRings = Fsm_FsmReadReachabilityOnionRings(absFsm); 00619 assert(onionRings); 00620 00621 synOnionRings = array_alloc(mdd_t *, array_n(onionRings)); 00622 00623 mddOne = mdd_one(mddManager); 00624 allPSVars = Fsm_FsmReadPresentStateVars(absFsm); 00625 00626 /* the last ring */ 00627 mdd2 = array_fetch_last(mdd_t *, onionRings); 00628 mdd1 = mdd_and(mdd2, inv_states, 1, 0); 00629 if (cexType == GRAB_CEX_MINTERM) 00630 ring = Mc_ComputeAMinterm(mdd1, allPSVars, mddManager); 00631 else if (cexType == GRAB_CEX_CUBE) { 00632 array_t *bddIds = mdd_get_bdd_support_ids(mddManager, mdd1); 00633 int nvars = array_n(bddIds); 00634 array_free(bddIds); 00635 ring = bdd_approx_remap_ua(mdd1, (bdd_approx_dir_t)BDD_UNDER_APPROX, 00636 nvars, 1024, 1); 00637 if (ring == NIL(mdd_t)) 00638 ring = mdd_dup(mdd1); 00639 }else 00640 ring = mdd_dup(mdd1); 00641 mdd_free(mdd1); 00642 array_insert(mdd_t *, synOnionRings, array_n(onionRings)-1, ring); 00643 00644 /* the rest rings */ 00645 for (j=array_n(onionRings)-2; j>=0; j--) { 00646 mdd1 = array_fetch(mdd_t *, synOnionRings, j+1); 00647 mdd2 = Img_ImageInfoComputeBwdWithDomainVars(imageInfo, 00648 mdd1, 00649 mdd1, 00650 mddOne); 00651 00652 mdd3 = array_fetch(mdd_t *, onionRings, j); 00653 mdd4 = mdd_and(mdd2, mdd3, 1, 1); 00654 mdd_free(mdd2); 00655 00656 if (cexType == GRAB_CEX_MINTERM) 00657 ring = Mc_ComputeAMinterm(mdd4, allPSVars, mddManager); 00658 else if (cexType == GRAB_CEX_CUBE) { 00659 array_t *bddIds = mdd_get_bdd_support_ids(mddManager, mdd4); 00660 int nvars = array_n(bddIds); 00661 array_free(bddIds); 00662 ring = bdd_approx_remap_ua(mdd4, (bdd_approx_dir_t)BDD_UNDER_APPROX, 00663 nvars, 1024, 1); 00664 if (ring == NIL(mdd_t)) 00665 ring = mdd_dup(mdd4); 00666 }else 00667 ring = mdd_dup(mdd4); 00668 mdd_free(mdd4); 00669 array_insert(mdd_t *, synOnionRings, j, ring); 00670 } 00671 00672 mdd_free(mddOne); 00673 00674 return synOnionRings; 00675 } 00676 00687 array_t * 00688 GrabGetVisibleVarMddIds ( 00689 Fsm_Fsm_t *absFsm, 00690 st_table *absVarTable) 00691 { 00692 array_t *visibleVarMddIds = array_alloc(int, 0); 00693 st_generator *stgen; 00694 Ntk_Node_t *node; 00695 int mddId; 00696 00697 st_foreach_item(absVarTable, stgen, &node, NIL(char *)) { 00698 mddId = Ntk_NodeReadMddId(node); 00699 array_insert_last(int, visibleVarMddIds, mddId); 00700 } 00701 00702 return visibleVarMddIds; 00703 } 00704 00705 00717 array_t * 00718 GrabGetInvisibleVarMddIds( 00719 Fsm_Fsm_t *absFsm, 00720 st_table *absVarTable, 00721 st_table *absBnvTable) 00722 { 00723 Ntk_Network_t *network = Fsm_FsmReadNetwork(absFsm); 00724 array_t *inputVars = Fsm_FsmReadInputVars(absFsm); 00725 array_t *invisibleVarMddIds = array_alloc(int, 0); 00726 Ntk_Node_t *node; 00727 int i, mddId; 00728 00729 arrayForEachItem(int, inputVars, i, mddId) { 00730 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00731 if ( !Ntk_NodeTestIsInput(node) && 00732 !st_is_member(absVarTable, node) ) { 00733 if (absBnvTable != NIL(st_table)) { 00734 if (!st_is_member(absBnvTable, node)) { 00735 array_insert_last(int, invisibleVarMddIds, mddId); 00736 } 00737 }else 00738 array_insert_last(int, invisibleVarMddIds, mddId); 00739 } 00740 } 00741 00742 return invisibleVarMddIds; 00743 } 00744 00754 int 00755 GrabTestRefinementSetSufficient( 00756 Ntk_Network_t *network, 00757 array_t *SORs, 00758 st_table *absVarTable, 00759 int verbose) 00760 { 00761 int is_sufficient; 00762 00763 is_sufficient = !Bmc_AbstractCheckAbstractTraces(network, 00764 SORs, 00765 absVarTable, 00766 0, 0, 0); 00767 return is_sufficient; 00768 } 00769 00779 int 00780 GrabTestRefinementBnvSetSufficient( 00781 Ntk_Network_t *network, 00782 st_table *coiBnvTable, 00783 array_t *SORs, 00784 st_table *absVarTable, 00785 st_table *absBnvTable, 00786 int verbose) 00787 { 00788 int is_sufficient; 00789 00790 assert(absBnvTable && coiBnvTable); 00791 00792 is_sufficient = 00793 !Bmc_AbstractCheckAbstractTracesWithFineGrain(network, 00794 coiBnvTable, 00795 SORs, 00796 absVarTable, 00797 absBnvTable); 00798 return is_sufficient; 00799 } 00800 00812 void 00813 GrabMinimizeLatchRefinementSet( 00814 Ntk_Network_t *network, 00815 st_table **absVarTable, 00816 st_table **absBnvTable, 00817 array_t *newlyAddedLatches, 00818 array_t **newlyAddedBnvs, 00819 array_t *SORs, 00820 int verbose) 00821 { 00822 st_table *newVertexTable, *oldBnvTable, *transFaninTable; 00823 array_t *rootArray, *transFanins, *oldNewlyAddedBnvs; 00824 st_generator *stgen; 00825 Ntk_Node_t *node; 00826 int i, flag, n_size, mddId; 00827 00828 n_size = array_n(newlyAddedLatches); 00829 00830 if (verbose >= 3) 00831 fprintf(vis_stdout, 00832 "-- grab: minimize latch refinement set: previous size is %d\n", 00833 n_size); 00834 00835 arrayForEachItem(int, newlyAddedLatches, i, mddId) { 00836 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00837 /* first, try to drop it */ 00838 newVertexTable = st_copy(*absVarTable); 00839 flag = st_delete(newVertexTable, &node, NIL(char *)); 00840 assert(flag); 00841 /* if the counter-example does not come back, drop it officially */ 00842 flag = Bmc_AbstractCheckAbstractTraces(network,SORs, 00843 newVertexTable, 0, 0, 0); 00844 if (!flag) { 00845 st_free_table(*absVarTable); 00846 *absVarTable = newVertexTable; 00847 n_size--; 00848 }else { 00849 st_free_table(newVertexTable); 00850 if (verbose >= 3) 00851 fprintf(vis_stdout," add back %s (latch)\n", 00852 Ntk_NodeReadName(node)); 00853 } 00854 } 00855 00856 if (verbose >= 3) 00857 fprintf(vis_stdout, 00858 "-- grab: minimize latch refinement set: current size is %d\n", 00859 n_size); 00860 00861 /* prune away irrelevant BNVs */ 00862 if (*absBnvTable != NIL(st_table) && st_count(*absBnvTable)>0) { 00863 00864 rootArray = array_alloc(Ntk_Node_t *, 0); 00865 st_foreach_item(*absVarTable, stgen, &node, NIL(char *)) { 00866 array_insert_last(Ntk_Node_t *, rootArray, Ntk_LatchReadDataInput(node)); 00867 array_insert_last(Ntk_Node_t *, rootArray, 00868 Ntk_LatchReadInitialInput(node)); 00869 } 00870 transFanins = Ntk_NodeComputeTransitiveFaninNodes(network, rootArray, 00871 TRUE, /*stopAtLatch*/ 00872 FALSE /*combInputsOnly*/ 00873 ); 00874 array_free(rootArray); 00875 00876 transFaninTable = st_init_table(st_ptrcmp, st_ptrhash); 00877 arrayForEachItem(Ntk_Node_t *, transFanins, i, node) { 00878 st_insert(transFaninTable, node, NIL(char)); 00879 } 00880 array_free(transFanins); 00881 00882 oldBnvTable = *absBnvTable; 00883 oldNewlyAddedBnvs = *newlyAddedBnvs; 00884 *absBnvTable = st_init_table(st_ptrcmp, st_ptrhash); 00885 *newlyAddedBnvs = array_alloc(int, 0); 00886 st_foreach_item(oldBnvTable, stgen, &node, NIL(char *)) { 00887 if (st_is_member(transFaninTable, node)) 00888 st_insert(*absBnvTable, node, NIL(char)); 00889 } 00890 arrayForEachItem(int, oldNewlyAddedBnvs, i, mddId) { 00891 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00892 if (st_is_member(transFaninTable, node)) 00893 array_insert_last(int, *newlyAddedBnvs, mddId); 00894 } 00895 st_free_table(transFaninTable); 00896 00897 if (verbose >= 5) { 00898 st_foreach_item(oldBnvTable, stgen, &node, NIL(char *)) { 00899 if (!st_is_member(*absBnvTable, node)) 00900 fprintf(vis_stdout, " prune away BNV %s\n", Ntk_NodeReadName(node)); 00901 } 00902 } 00903 00904 array_free(oldNewlyAddedBnvs); 00905 st_free_table(oldBnvTable); 00906 } 00907 00908 } 00909 00910 00922 void 00923 GrabMinimizeBnvRefinementSet( 00924 Ntk_Network_t *network, 00925 st_table *coiBnvTable, 00926 st_table *absVarTable, 00927 st_table **absBnvTable, 00928 array_t *newlyAddedBnvs, 00929 array_t *SORs, 00930 int verbose) 00931 { 00932 st_table *newBnvTable; 00933 Ntk_Node_t *node; 00934 int i, flag, n_size, mddId; 00935 00936 n_size = array_n(newlyAddedBnvs); 00937 00938 if (verbose >= 3) 00939 fprintf(vis_stdout, 00940 "-- grab: minimize bnv refinement set: previous size is %d\n", 00941 n_size); 00942 00943 arrayForEachItem(int, newlyAddedBnvs, i, mddId) { 00944 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00945 /* first, try to drop it */ 00946 newBnvTable = st_copy(*absBnvTable); 00947 flag = st_delete(newBnvTable, &node, NIL(char *)); 00948 assert(flag); 00949 /* if the counter-example does not come back, drop it officially */ 00950 flag = Bmc_AbstractCheckAbstractTracesWithFineGrain(network, 00951 coiBnvTable, 00952 SORs, 00953 absVarTable, 00954 newBnvTable); 00955 if (!flag) { 00956 st_free_table(*absBnvTable); 00957 *absBnvTable = newBnvTable; 00958 n_size--; 00959 }else { 00960 st_free_table(newBnvTable); 00961 if (verbose >= 3) 00962 fprintf(vis_stdout," add back %s (BNV)\n", 00963 Ntk_NodeReadName(node)); 00964 } 00965 } 00966 00967 if (verbose >= 3) 00968 fprintf(vis_stdout, 00969 "-- grab: minimize bnv refinement set: current size is %d\n", 00970 n_size); 00971 } 00972 00982 void 00983 GrabNtkClearAllMddIds( 00984 Ntk_Network_t *network) 00985 { 00986 #ifndef NDEBUG 00987 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 00988 #endif 00989 Ntk_Node_t *node; 00990 lsGen lsgen; 00991 00992 assert(mddManager == NIL(mdd_manager)); 00993 00994 Ntk_NetworkForEachNode(network, lsgen, node) { 00995 Ntk_NodeSetMddId(node, NTK_UNASSIGNED_MDD_ID); 00996 } 00997 } 00998 01008 void 01009 GrabPrintNodeArray( 01010 char *caption, 01011 array_t *theArray) 01012 { 01013 Ntk_Node_t *node; 01014 char string[32]; 01015 int i; 01016 01017 fprintf(vis_stdout, "\n%s[%d] =\n", caption, theArray?array_n(theArray):0); 01018 01019 if (!theArray) return; 01020 01021 arrayForEachItem(Ntk_Node_t *, theArray, i, node) { 01022 if (Ntk_NodeTestIsLatch(node)) 01023 strcpy(string, "latch"); 01024 else if (Ntk_NodeTestIsInput(node)) 01025 strcpy(string, "input"); 01026 else if (Ntk_NodeTestIsLatchDataInput(node)) 01027 strcpy(string, "latchDataIn"); 01028 else if (Ntk_NodeTestIsLatchInitialInput(node)) 01029 strcpy(string, "latchInitIn"); 01030 else if (Ntk_NodeTestIsConstant(node)) 01031 strcpy(string, "const"); 01032 else 01033 strcpy(string, "BNV"); 01034 01035 fprintf(vis_stdout, "%s\t(%s)\n", Ntk_NodeReadName(node), string); 01036 } 01037 } 01038 01048 void 01049 GrabPrintMddIdArray( 01050 Ntk_Network_t *network, 01051 char *caption, 01052 array_t *mddIdArray) 01053 { 01054 Ntk_Node_t *node; 01055 array_t *theArray = array_alloc(Ntk_Node_t *, array_n(mddIdArray)); 01056 int i, mddId; 01057 01058 arrayForEachItem(int, mddIdArray, i, mddId) { 01059 node = Ntk_NetworkFindNodeByMddId(network, mddId); 01060 array_insert(Ntk_Node_t *, theArray, i, node); 01061 } 01062 01063 GrabPrintNodeArray(caption, theArray); 01064 01065 array_free(theArray); 01066 01067 } 01068 01078 void 01079 GrabPrintNodeList( 01080 char *caption, 01081 lsList theList) 01082 { 01083 Ntk_Node_t *node; 01084 char string[32]; 01085 lsGen lsgen; 01086 01087 fprintf(vis_stdout, "\n%s[%d] =\n", caption, theList?lsLength(theList):0); 01088 01089 if (!theList) return; 01090 01091 lsForEachItem(theList, lsgen, node) { 01092 if (Ntk_NodeTestIsLatch(node)) 01093 strcpy(string, "latch"); 01094 else if (Ntk_NodeTestIsInput(node)) 01095 strcpy(string, "input"); 01096 else if (Ntk_NodeTestIsLatchDataInput(node)) 01097 strcpy(string, "latchDataIn"); 01098 else if (Ntk_NodeTestIsLatchInitialInput(node)) 01099 strcpy(string, "latchInitIn"); 01100 else if (Ntk_NodeTestIsConstant(node)) 01101 strcpy(string, "const"); 01102 else 01103 strcpy(string, "BNV"); 01104 01105 fprintf(vis_stdout, " %s\t %s\n", string, Ntk_NodeReadName(node)); 01106 } 01107 } 01108 01118 void 01119 GrabPrintNodeHashTable( 01120 char *caption, 01121 st_table *theTable) 01122 { 01123 Ntk_Node_t *node; 01124 char string[32]; 01125 long value; 01126 st_generator *stgen; 01127 01128 fprintf(vis_stdout, "\n%s[%d] =\n", caption, theTable?st_count(theTable):0); 01129 01130 if (!theTable) return; 01131 01132 st_foreach_item(theTable, stgen, &node, &value) { 01133 if (Ntk_NodeTestIsLatch(node)) 01134 strcpy(string, "latch"); 01135 else if (Ntk_NodeTestIsInput(node)) 01136 strcpy(string, "input"); 01137 else if (Ntk_NodeTestIsLatchDataInput(node)) 01138 strcpy(string, "latchDataIn"); 01139 else if (Ntk_NodeTestIsLatchInitialInput(node)) 01140 strcpy(string, "latchInitIn"); 01141 else if (Ntk_NodeTestIsConstant(node)) 01142 strcpy(string, "const"); 01143 else 01144 strcpy(string, "BNV"); 01145 01146 if (value != 0) 01147 fprintf(vis_stdout, " %s\t %s\t %ld\n", string, Ntk_NodeReadName(node), 01148 value); 01149 else 01150 fprintf(vis_stdout, " %s\t %s \n", string, Ntk_NodeReadName(node)); 01151 } 01152 } 01153 01154 /*---------------------------------------------------------------------------*/ 01155 /* Definition of static functions */ 01156 /*---------------------------------------------------------------------------*/ 01157 01167 static void 01168 GetFormulaNodes( 01169 Ntk_Network_t *network, 01170 Ctlp_Formula_t *F, 01171 array_t *formulaNodes) 01172 { 01173 01174 if (F == NIL(Ctlp_Formula_t)) 01175 return; 01176 01177 if (Ctlp_FormulaReadType(F) == Ctlp_ID_c) { 01178 char *nodeNameString = Ctlp_FormulaReadVariableName(F); 01179 Ntk_Node_t *node = Ntk_NetworkFindNodeByName(network, nodeNameString); 01180 assert(node); 01181 array_insert_last(Ntk_Node_t *, formulaNodes, node); 01182 return; 01183 } 01184 01185 GetFormulaNodes(network, Ctlp_FormulaReadRightChild(F), formulaNodes); 01186 GetFormulaNodes(network, Ctlp_FormulaReadLeftChild(F), formulaNodes); 01187 } 01188 01189 01199 static void 01200 GetFaninLatches( 01201 Ntk_Node_t *node, 01202 st_table *visited, 01203 st_table *absVarTable) 01204 { 01205 if (st_is_member(visited, node)) 01206 return; 01207 01208 st_insert(visited, node, (char *)0); 01209 01210 if (Ntk_NodeTestIsLatch(node)) 01211 st_insert(absVarTable, node, (char *)0); 01212 else { 01213 int i; 01214 Ntk_Node_t *fanin; 01215 Ntk_NodeForEachFanin(node, i, fanin) { 01216 GetFaninLatches(fanin, visited, absVarTable); 01217 } 01218 } 01219 } 01220 01228 static void 01229 NodeTableAddCtlFormulaNodes( 01230 Ntk_Network_t *network, 01231 Ctlp_Formula_t *formula, 01232 st_table * nodesTable ) 01233 { 01234 if (formula == NIL(Ctlp_Formula_t)) 01235 return; 01236 01237 if ( Ctlp_FormulaReadType( formula ) == Ctlp_ID_c ) { 01238 char *nodeNameString = Ctlp_FormulaReadVariableName( formula ); 01239 Ntk_Node_t *node = Ntk_NetworkFindNodeByName( network, nodeNameString ); 01240 if( node ) 01241 st_insert( nodesTable, ( char *) node, NIL(char) ); 01242 return; 01243 } 01244 01245 NodeTableAddCtlFormulaNodes( network, Ctlp_FormulaReadRightChild( formula ), nodesTable ); 01246 NodeTableAddCtlFormulaNodes( network, Ctlp_FormulaReadLeftChild( formula ), nodesTable ); 01247 } 01248 01249