VIS
|
00001 00026 #include "grabInt.h" 00027 #include "bmcInt.h" 00028 00029 /*---------------------------------------------------------------------------*/ 00030 /* Constant declarations */ 00031 /*---------------------------------------------------------------------------*/ 00032 00033 /*---------------------------------------------------------------------------*/ 00034 /* Structure declarations */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 /*---------------------------------------------------------------------------*/ 00038 /* Type declarations */ 00039 /*---------------------------------------------------------------------------*/ 00040 00041 /*---------------------------------------------------------------------------*/ 00042 /* Variable declarations */ 00043 /*---------------------------------------------------------------------------*/ 00044 00045 /*---------------------------------------------------------------------------*/ 00046 /* Macro declarations */ 00047 /*---------------------------------------------------------------------------*/ 00048 00051 /*---------------------------------------------------------------------------*/ 00052 /* Static function prototypes */ 00053 /*---------------------------------------------------------------------------*/ 00054 00055 static bAigEdge_t GrabConvertBddToBaig(bAig_Manager_t *bAigManager, bdd_t *fn, st_table *bddidToNames); 00056 static st_table * GrabBddGetSupportBaigNames(mdd_manager *mddManager, mdd_t *f); 00057 static char * GrabBddIdToBaigNames(mdd_manager *mddManager, int bddid); 00058 00061 /*---------------------------------------------------------------------------*/ 00062 /* Definition of exported functions */ 00063 /*---------------------------------------------------------------------------*/ 00064 00076 boolean 00077 Bmc_AbstractCheckAbstractTraces( 00078 Ntk_Network_t *network, 00079 array_t *synOnionRings, 00080 st_table *absLatches, 00081 int verbose, 00082 int dbgLevel, 00083 int printInputs) 00084 { 00085 int pathLength = array_n(synOnionRings) -1; 00086 mAig_Manager_t *maigManager = Ntk_NetworkReadMAigManager(network); 00087 st_table *nodeToMvfAigTable = NIL(st_table); 00088 BmcCnfClauses_t *cnfClauses; 00089 FILE *cnfFile; 00090 BmcOption_t *options; 00091 array_t *result; 00092 int i; 00093 boolean CexExit = FALSE; 00094 00095 nodeToMvfAigTable = 00096 (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY); 00097 if (nodeToMvfAigTable == NIL(st_table)){ 00098 fprintf(vis_stderr, 00099 "** bmc error: please run buid_partiton_maigs first\n"); 00100 return CexExit; 00101 } 00102 00103 options = BmcOptionAlloc(); 00104 if (verbose) { 00105 options->dbgLevel = dbgLevel; 00106 options->printInputs = printInputs; 00107 } 00108 options->satInFile = BmcCreateTmpFile(); 00109 if (options->satInFile == NIL(char)){ 00110 BmcOptionFree(options); 00111 return CexExit; 00112 } 00113 00114 /* create SAT Solver output file */ 00115 options->satOutFile = BmcCreateTmpFile(); 00116 if (options->satOutFile == NIL(char)){ 00117 BmcOptionFree(options); 00118 fprintf(vis_stderr, "** bmc error: Cannot allocate a temp file name\n"); 00119 return CexExit; 00120 } 00121 cnfFile = Cmd_FileOpen(options->satInFile, "w", NIL(char *), 0); 00122 if (cnfFile == NIL(FILE)) { 00123 BmcOptionFree(options); 00124 fprintf(vis_stderr, "** bmc error: Cannot create CNF output file %s\n", 00125 options->satInFile); 00126 return CexExit; 00127 } 00128 00129 /* Unroll the model exactly 'pathLength' time frames 00130 */ 00131 cnfClauses = BmcCnfClausesAlloc(); 00132 BmcCnfGenerateClausesForPath(network, 0, pathLength, BMC_INITIAL_STATES, 00133 cnfClauses, nodeToMvfAigTable, absLatches); 00134 00135 /* Generate the constraints from the abstract paths 00136 * (1) build a bAigEdge_t (graph) for each ring 00137 * (2) add all the cnf clauses that describe this graph 00138 * (3) make the output bAigEdge_t equals to 1 00139 */ 00140 { 00141 bAigEdge_t bAigState; 00142 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 00143 array_t *clause = array_alloc(int, 1); 00144 mdd_t *ring; 00145 00146 arrayForEachItem(mdd_t *, synOnionRings, i, ring) { 00147 st_table *bddidTobAigNames; 00148 bddidTobAigNames = GrabBddGetSupportBaigNames(mddManager, ring); 00149 bAigState = GrabConvertBddToBaig(maigManager, ring, bddidTobAigNames); 00150 { 00151 st_generator *stgen; 00152 long tmpId; 00153 char *tmpStr; 00154 st_foreach_item(bddidTobAigNames, stgen, &tmpId, &tmpStr) { 00155 FREE(tmpStr); 00156 } 00157 st_free_table(bddidTobAigNames); 00158 } 00159 array_insert(int, clause, 0, BmcGenerateCnfFormulaForAigFunction( 00160 maigManager, bAigState, i, cnfClauses)); 00161 BmcCnfInsertClause(cnfClauses, clause); 00162 } 00163 00164 array_free(clause); 00165 } 00166 00167 /* Call the SAT solver 00168 */ 00169 BmcWriteClauses(maigManager, cnfFile, cnfClauses, options); 00170 fclose(cnfFile); 00171 result = BmcCheckSAT(options); 00172 if(result != NIL(array_t)){ 00173 if (verbose >= 1 && dbgLevel ==1) { 00174 fprintf(vis_stdout,"Found Counterexample of length = %d\n", pathLength); 00175 BmcPrintCounterExample(network, nodeToMvfAigTable, cnfClauses, 00176 result, pathLength+1, absLatches, options, 00177 NIL(array_t)); 00178 } 00179 if (verbose >=1 && dbgLevel == 2) { 00180 BmcPrintCounterExampleAiger(network, nodeToMvfAigTable, cnfClauses, 00181 result, pathLength+1, absLatches, options, 00182 NIL(array_t)); 00183 } 00184 CexExit = TRUE; 00185 } 00186 00187 /* free all used memories */ 00188 BmcCnfClausesFree(cnfClauses); 00189 array_free(result); 00190 BmcOptionFree(options); 00191 00192 return CexExit; 00193 } 00194 00195 00214 boolean 00215 Bmc_AbstractCheckAbstractTracesWithFineGrain( 00216 Ntk_Network_t *network, 00217 st_table *coiBnvTable, 00218 array_t *synOnionRings, 00219 st_table *absLatches, 00220 st_table *absBnvs) 00221 { 00222 boolean result; 00223 mAigManagerState_t oldMaigState; /* to store the previous AIG */ 00224 mAig_Manager_t *maigManager; 00225 lsGen lsgen; 00226 Ntk_Node_t *node; 00227 int mAigId; 00228 int i; 00229 st_generator *stgen; 00230 st_table *leaves; 00231 array_t *roots, *combInputs; 00232 00233 /* save the existing maigManager */ 00234 oldMaigState.manager = Ntk_NetworkReadMAigManager(network); 00235 oldMaigState.nodeToMvfAigTable = 00236 (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY); 00237 oldMaigState.nodeToMAigIdTable = st_init_table(st_ptrcmp, st_ptrhash); 00238 Ntk_NetworkForEachNode(network, lsgen, node) { 00239 mAigId = Ntk_NodeReadMAigId(node); 00240 st_insert(oldMaigState.nodeToMAigIdTable, node, (char *)(long)mAigId); 00241 Ntk_NodeSetMAigId(node, ntmaig_UNUSED); 00242 } 00243 00244 /* create a new maigManager */ 00245 maigManager = mAig_initAig(); 00246 Ntk_NetworkSetMAigManager(network, maigManager); 00247 Ntk_NetworkSetApplInfo(network, MVFAIG_NETWORK_APPL_KEY, 00248 (Ntk_ApplInfoFreeFn) ntmAig_MvfAigTableFreeCallback, 00249 (void *) st_init_table(st_ptrcmp, st_ptrhash)); 00250 00251 /* roots are the visible latches, and the visible bnvs (some bnvs 00252 * may not be in the transitive fan-in cone of the visible latches 00253 */ 00254 roots = array_alloc(Ntk_Node_t *, 0); 00255 st_foreach_item(absLatches, stgen, &node, NIL(char *)) { 00256 array_insert_last(Ntk_Node_t *, roots, Ntk_LatchReadDataInput(node)); 00257 array_insert_last(Ntk_Node_t *, roots, Ntk_LatchReadInitialInput(node)); 00258 } 00259 st_foreach_item(absBnvs, stgen, &node, NIL(char *)) { 00260 array_insert_last(Ntk_Node_t *, roots, node); 00261 } 00262 00263 combInputs = Ntk_NodeComputeTransitiveFaninNodes(network, roots, 00264 TRUE, /* stopAtLatches */ 00265 FALSE /* combInputsOnly*/ 00266 ); 00267 00268 /* leaves are the combinational inputs or the invisible bnvs */ 00269 leaves = st_init_table(st_ptrcmp, st_ptrhash); 00270 arrayForEachItem(Ntk_Node_t *, combInputs, i, node) { 00271 if ( Ntk_NodeTestIsCombInput(node) || 00272 ( st_is_member(coiBnvTable, node) && 00273 !st_is_member(absBnvs, node) ) ) { 00274 st_insert(leaves, node, (char *) ntmaig_UNUSED); 00275 Ntk_NodeSetMAigId(node, mAig_CreateVar(maigManager, 00276 Ntk_NodeReadName(node), 00277 Var_VariableReadNumValues(Ntk_NodeReadVariable(node)))); 00278 } 00279 } 00280 st_foreach_item(absLatches, stgen, &node, NIL(char *)) { 00281 if (!st_is_member(leaves, node)) { 00282 st_insert(leaves, node, (char *) ntmaig_UNUSED); 00283 Ntk_NodeSetMAigId(node, mAig_CreateVar(maigManager, 00284 Ntk_NodeReadName(node), 00285 Var_VariableReadNumValues(Ntk_NodeReadVariable(node)))); 00286 } 00287 } 00288 array_free(combInputs); 00289 00290 #if 1 00291 /* THIS SEEMS UNNECESSARY---IT'S HERE TO AVOID ERRORS IN CALLING 00292 * ntmaig_NetworkBuildMvfAigs() 00293 */ 00294 Ntk_NetworkForEachCombInput(network, lsgen, node) { 00295 if (Ntk_NodeReadMAigId(node) == NTK_UNASSIGNED_MAIG_ID) { 00296 Ntk_NodeSetMAigId(node, mAig_CreateVar(maigManager, 00297 Ntk_NodeReadName(node), 00298 Var_VariableReadNumValues(Ntk_NodeReadVariable(node)))); 00299 } 00300 } 00301 #endif 00302 00303 /* build the new AIG graph */ 00304 ntmaig_NetworkBuildMvfAigs(network, roots, leaves); 00305 00306 array_free(roots); 00307 st_free_table(leaves); 00308 00309 00310 /* check the existence of the abstract path on the new AIG graph */ 00311 result = Bmc_AbstractCheckAbstractTraces(network, 00312 synOnionRings, 00313 absLatches, 00314 0, 0, 0); 00315 00316 /* restore the previous maigManager */ 00317 mAig_quit(maigManager); 00318 Ntk_NetworkFreeApplInfo(network, MVFAIG_NETWORK_APPL_KEY); 00319 Ntk_NetworkSetMAigManager(network, oldMaigState.manager); 00320 Ntk_NetworkSetApplInfo(network, MVFAIG_NETWORK_APPL_KEY, 00321 (Ntk_ApplInfoFreeFn) ntmAig_MvfAigTableFreeCallback, 00322 (void *) oldMaigState.nodeToMvfAigTable); 00323 st_foreach_item(oldMaigState.nodeToMAigIdTable, stgen, &node, 00324 &mAigId) { 00325 Ntk_NodeSetMAigId(node, mAigId); 00326 } 00327 st_free_table(oldMaigState.nodeToMAigIdTable); 00328 00329 return result; 00330 } 00331 00332 /*---------------------------------------------------------------------------*/ 00333 /* Definition of static functions */ 00334 /*---------------------------------------------------------------------------*/ 00335 00354 static bAigEdge_t 00355 GrabConvertBddToBaig( 00356 bAig_Manager_t *bAigManager, 00357 bdd_t *fn, 00358 st_table *bddidToNames) 00359 { 00360 bdd_gen *gen; 00361 bdd_node *node, *thenNode, *elseNode, *funcNode; 00362 bdd_manager *bddManager = bdd_get_manager(fn); 00363 bdd_node *one = bdd_read_one(bddManager); 00364 /*bdd_node *zero = bdd_read_logic_zero(bddManager);*/ 00365 int is_complemented; 00366 int flag; 00367 bAigEdge_t var, left, right, result; 00368 char *name; 00369 st_table *bddTObaigTable; 00370 00371 bddTObaigTable = st_init_table(st_numcmp, st_numhash); 00372 00373 if (fn == NULL){ 00374 return bAig_NULL; 00375 } 00376 00377 st_insert(bddTObaigTable, (char *) (long) bdd_regular(one), 00378 (char *) bAig_One); 00379 00380 funcNode = bdd_get_node(fn, &is_complemented); 00381 00382 if (bdd_is_constant(funcNode)){ 00383 flag = st_lookup(bddTObaigTable, 00384 (char *) (long) (funcNode), 00385 &result); 00386 assert(flag); 00387 st_free_table(bddTObaigTable); 00388 00389 if (is_complemented) 00390 return bAig_Not(result); 00391 else 00392 return result; 00393 } 00394 00395 foreach_bdd_node(fn, gen, node){ 00396 /* if the node has been processed, skip it. (the constant ONE 00397 * should be the only node falls into this category). 00398 */ 00399 if (st_is_member(bddTObaigTable, (char *) (long) bdd_regular(node))) 00400 continue; 00401 00402 /* bdd_node_read_index() return the current level's bddId */ 00403 if (bddidToNames) { 00404 flag = st_lookup(bddidToNames, (char *)(long)bdd_node_read_index(node), 00405 &name); 00406 assert(flag); 00407 name = util_strsav(name); 00408 }else { 00409 char tempString[1024]; 00410 sprintf(tempString, "BDD%d", bdd_node_read_index(node)); 00411 name = util_strsav(tempString); 00412 } 00413 00414 /* Create or Retrieve the bAigEdge_t w.r.t. 'name' */ 00415 var = bAig_CreateVarNode(bAigManager, name); 00416 FREE(name); 00417 00418 thenNode = bdd_bdd_T(node); 00419 flag = st_lookup(bddTObaigTable, (char *) (long) bdd_regular(thenNode), 00420 &left); 00421 assert(flag); 00422 00423 elseNode = bdd_bdd_E(node); 00424 flag = st_lookup(bddTObaigTable, (char *) (long) bdd_regular(elseNode), 00425 &right); 00426 assert(flag); 00427 00428 /* should we test here whether elseNode is complemented arc? */ 00429 if (bdd_is_complement(elseNode)) 00430 right = bAig_Not(right); 00431 00432 result = bAig_Or(bAigManager, bAig_And(bAigManager, var, left), 00433 bAig_And(bAigManager, bAig_Not(var), right)); 00434 st_insert(bddTObaigTable, (char *) (long) bdd_regular(node), 00435 (char *) (long) result); 00436 } 00437 flag = st_lookup(bddTObaigTable, (char *) (long) bdd_regular(funcNode), 00438 &result); 00439 assert(flag); 00440 st_free_table(bddTObaigTable); 00441 00442 if (is_complemented){ 00443 return bAig_Not(result); 00444 } else { 00445 return result; 00446 } 00447 } /* end of bAig_bddtobAig() */ 00448 00449 00461 static st_table * 00462 GrabBddGetSupportBaigNames( 00463 mdd_manager *mddManager, 00464 mdd_t *f) 00465 { 00466 int numOfVars = bdd_num_vars(mddManager); 00467 st_table *bddidTObaigNames = st_init_table(st_numcmp, st_numhash); 00468 var_set_t *vset; 00469 int i; 00470 00471 vset = bdd_get_support(f); 00472 for (i=0; i<numOfVars; i++) { 00473 if (var_set_get_elt(vset, i) == 1) { 00474 st_insert(bddidTObaigNames, (char *)(long)i, 00475 GrabBddIdToBaigNames(mddManager, i)); 00476 } 00477 } 00478 var_set_free(vset); 00479 00480 return bddidTObaigNames; 00481 } 00482 00494 static char * 00495 GrabBddIdToBaigNames( 00496 mdd_manager *mddManager, 00497 int bddid) 00498 { 00499 array_t *mvar_list = mdd_ret_mvar_list(mddManager); 00500 array_t *bvar_list = mdd_ret_bvar_list(mddManager); 00501 bvar_type bv; 00502 mvar_type mv; 00503 int mddid, index, id; 00504 char *nodeName; 00505 char baigName[1024]; 00506 00507 /* 1. from bddid, get mddid and the index of this bddid in the mddid 00508 */ 00509 bv = array_fetch(bvar_type, bvar_list, bddid); 00510 mddid = bv.mvar_id; 00511 mv = array_fetch(mvar_type, mvar_list, mddid); 00512 arrayForEachItem(int, mv.bvars, index, id) { 00513 if (id == bddid) 00514 break; 00515 } 00516 assert(index <= mv.encode_length -1); 00517 00518 /* 2. assumptions: (1) mv.name = nodeName, 00519 * (2) index is the same for MDD and MAIG 00520 */ 00521 nodeName = mv.name; 00522 00523 /* 3. the baigEdge_t's name is ("%s_%d",nodeName,index) 00524 */ 00525 sprintf(baigName, "%s_%d", nodeName, index); 00526 00527 return util_strsav(baigName); 00528 } 00529 00530 00531 00532 00533 00534