VIS
|
00001 00019 #include "resInt.h" 00020 00021 static char rcsid[] UNUSED = "$Id: res.c,v 1.55 2009/04/11 21:31:29 fabio Exp $"; 00022 00023 /*---------------------------------------------------------------------------*/ 00024 /* Constant declarations */ 00025 /*---------------------------------------------------------------------------*/ 00026 #define RES_VERIFY_NOTHING 0 00027 #define RES_VERIFY_DONE 1 00028 #define RES_VERIFY_IGNORE_PREV_RESULTS 2 00029 #define LOG2_FIRST_PRIME 8 00030 00031 /*---------------------------------------------------------------------------*/ 00032 /* Structure declarations */ 00033 /*---------------------------------------------------------------------------*/ 00034 00035 /*---------------------------------------------------------------------------*/ 00036 /* Type declarations */ 00037 /*---------------------------------------------------------------------------*/ 00038 00039 /*---------------------------------------------------------------------------*/ 00040 /* Variable declarations */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 00044 static int PrimePool [] = { 5, 7, 9, 11, 13, 17, 19, 23, 29, 00045 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 00046 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 00047 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 00048 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 00049 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 00050 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 00051 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 00052 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 00053 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 00054 547}; 00055 static int PrimePoolSize = 100; /* Number of elements of the array above */ 00056 00057 /*---------------------------------------------------------------------------*/ 00058 /* Macro declarations */ 00059 /*---------------------------------------------------------------------------*/ 00060 00063 /*---------------------------------------------------------------------------*/ 00064 /* Static function prototypes */ 00065 /*---------------------------------------------------------------------------*/ 00066 00067 static int ChoosePrimes(int numOutputs, int **pool, int numDirectVerify); 00068 static int ComputeMaxNumberOfOutputs(void); 00069 static void RestoreOldMddIds(Ntk_Network_t *network, st_table *table); 00070 static st_table * GeneratePointerMatchTableFromNameMatch(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, st_table *nameMatchTable); 00071 static st_table * GenerateDirectVerifyPointerTable(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, st_table *outputMatch, array_t *outputOrderArray, int numDirectVerify); 00072 static st_table * GenerateIdentityMatchTable(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, int inputOrOutput); 00073 static bdd_manager * Initializebdd_manager(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, int *initManagerHere); 00074 static int SetBasicResultInfo(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, int numDirectVerify); 00075 static void Cleanup(int error, Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, int initManagerHere, int done, st_table *outputMatch, st_table *inputMatch, st_table *directVerifyMatch, st_table *oldSpecMddIdTable, st_table *oldImplMddIdTable, array_t *specLayerArray, array_t *implLayerArray); 00076 static st_table * SaveOldMddIds(Ntk_Network_t *network); 00077 static int DirectVerification(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, st_table *directVerifyMatch, st_table *inputMatch, st_table *outputMatch, array_t *outputOrderArray); 00078 static bdd_reorder_type_t DecodeDynMethod(char *dynMethodString); 00079 static int ResidueVerification(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, st_table *outputMatch, st_table *inputMatch, int numDirectVerify, array_t *specLayerArray, array_t *implLayerArray, array_t *outputArray); 00080 static void ExtractACubeOfDifference(bdd_manager *mgr, Ntk_Network_t *specNetwork, bdd_node *fn1, bdd_node *fn2); 00081 00085 /*---------------------------------------------------------------------------*/ 00086 /* Definition of exported functions */ 00087 /*---------------------------------------------------------------------------*/ 00088 00119 int 00120 Res_NetworkResidueVerify( 00121 Ntk_Network_t *specNetwork, 00122 Ntk_Network_t *implNetwork, 00123 int numDirectVerify, 00124 array_t *outputOrderArray, 00125 st_table *outputNameMatch, 00126 st_table *inputNameMatch) 00127 { 00128 Ntk_Node_t *nodePtr; /* To iterate over nodes */ 00129 Ntk_Node_t *implNodePtr; /* To iterate over nodes */ 00130 Res_ResidueInfo_t *resultSpec; /* Structure holding all the info */ 00131 Res_ResidueInfo_t *resultImpl; /* Structure holding all the info */ 00132 array_t *specLayerArray; /* array containing the reverse 00133 * topological layers of the spec. 00134 */ 00135 array_t *implLayerArray; /* array containing the reverse 00136 * topological layers of the impl. 00137 */ 00138 st_table *oldSpecMddIdTable; /* Tables to store MDD IDs of the spec 00139 * if already assigned 00140 */ 00141 st_table *oldImplMddIdTable; /* Tables to store MDD IDs of the impl. 00142 * if already assigned 00143 */ 00144 00145 st_table *outputMatch; /* Output match table with node 00146 * pointers, spec node pointer is 00147 * the key 00148 */ 00149 st_table *inputMatch; /* Input match table with node 00150 * pointers, spec node pointer is 00151 * the key 00152 */ 00153 00154 bdd_manager *ddManager; /* Manager read from the network */ 00155 int initManagerHere; /* Flag to indicate the network Mdd 00156 * managers initialized here 00157 */ 00158 00159 lsGen listGen; /* To iterate over outputList */ 00160 long overallLap; /* To measure overall execution time */ 00161 int maxNumberOfOutputs; /* max number of outputs that can be 00162 * verified here 00163 * = product(100 primes) 00164 */ 00165 int numOutputs; /* Store the number of outputs in spec., 00166 * impl 00167 */ 00168 int done; /* flag to determine the status of 00169 * previous verification 00170 */ 00171 int error; /* error flag, set for cleanup, 1 failed, 00172 * 0 if successful 00173 */ 00174 int status; /* error status of residue verification */ 00175 int directVerifyStatus; /* direct verification status, 1 if failed, 00176 * 0 if successful 00177 */ 00178 st_table *directVerifyMatch; /* match table with pointers for the 00179 * directly verified outputs, spec pointer 00180 * is key 00181 */ 00182 char *name; /* variable to store name of node */ 00183 array_t *outputArray; /* array to store output nodes */ 00184 array_t *ignoreOutputArray; /* array to store outputs nodes to be 00185 * ignored 00186 */ 00187 int verbose; /* variable to read residue_verbosity value */ 00188 char *flagValue; /* string to read flag values */ 00189 int i; /* Loop iterators */ 00190 int unassignedValue; /* NTK_UNASSIGNED_MDD_ID value holder */ 00191 00192 /* Initialize some variables to default values */ 00193 00194 overallLap = 0; 00195 initManagerHere = 0; 00196 ddManager = NIL(bdd_manager); 00197 done = RES_VERIFY_NOTHING; 00198 error = 0; 00199 status = 1; 00200 verbose = 0; 00201 00202 unassignedValue = NTK_UNASSIGNED_MDD_ID; 00203 directVerifyStatus = 1; 00204 directVerifyMatch = NIL(st_table); 00205 specLayerArray = NIL(array_t); 00206 implLayerArray = NIL(array_t); 00207 outputArray = NIL(array_t); 00208 ignoreOutputArray = NIL(array_t); 00209 outputMatch = NIL(st_table); 00210 inputMatch = NIL(st_table); 00211 oldSpecMddIdTable = NIL(st_table); 00212 oldImplMddIdTable = NIL(st_table); 00213 resultSpec = NIL(Res_ResidueInfo_t); 00214 resultImpl = NIL(Res_ResidueInfo_t); 00215 00216 00217 /* Initialize global time values*/ 00218 Res_composeTime = 0; 00219 Res_smartVarTime = 0; 00220 Res_shuffleTime = 0; 00221 Res_orderTime = 0; 00222 00223 00224 /* Read verbosity value */ 00225 flagValue = Cmd_FlagReadByName("residue_verbosity"); 00226 if (flagValue != NIL(char)) { 00227 verbose = atoi(flagValue); 00228 } 00229 00230 /* Read the mdd Manager (or create it if necessary) */ 00231 ddManager = Initializebdd_manager(specNetwork, implNetwork, &initManagerHere); 00232 if (ddManager == NIL(bdd_manager)) { 00233 /* error, but nothing allocated, so no cleanup */ 00234 return 1; 00235 } 00236 00237 /* Set up the correct maximum number of outputs */ 00238 maxNumberOfOutputs = ComputeMaxNumberOfOutputs(); 00239 if (verbose >= 2) { 00240 fprintf(vis_stdout, "The Maximum Number of outputs that can be"); 00241 fprintf(vis_stdout, " verified are %d.\n", maxNumberOfOutputs); 00242 } 00243 00244 /* check number of outputs */ 00245 numOutputs = Ntk_NetworkReadNumCombOutputs(specNetwork); 00246 /* Check if the circuit has too many outputs */ 00247 if (numOutputs >= maxNumberOfOutputs) { 00248 error_append("Circuit with too many outputs.\n"); 00249 /* Clean up before you leave */ 00250 error = 1; 00251 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00252 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00253 oldImplMddIdTable, specLayerArray, implLayerArray); 00254 return 1; 00255 } /* End of if */ 00256 00257 /* Create result data structure for both the spec and the implementation */ 00258 done = SetBasicResultInfo(specNetwork, implNetwork, numDirectVerify); 00259 if (done == RES_VERIFY_DONE) {/* same verification as previous time */ 00260 /* Clean up before you leave */ 00261 fprintf(vis_stdout, "Verification has been previously performed\n"); 00262 error = 0; 00263 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00264 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00265 oldImplMddIdTable, specLayerArray, implLayerArray); 00266 return 0; /* success */ 00267 } /* end of case RES_VERIFY_DONE */ 00268 00269 /* if output match table does not exist, create one with matching names 00270 * in the two networks. Insert with spec network node pointer as key 00271 * in the outputMatch table. If match table does exist, convert name table 00272 * to pointer table. 00273 */ 00274 if(outputNameMatch == NIL(st_table)) { 00275 outputMatch = GenerateIdentityMatchTable(specNetwork, implNetwork, PRIMARY_OUTPUTS); 00276 } else { 00277 outputMatch = GeneratePointerMatchTableFromNameMatch(specNetwork, 00278 implNetwork,outputNameMatch); 00279 if (outputMatch == NIL(st_table)) { 00280 error_append("Output pointer table is NULL\n"); 00281 /* Clean up before you leave */ 00282 error = 1; 00283 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00284 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00285 oldImplMddIdTable, specLayerArray, implLayerArray); 00286 return 1; /* error return */ 00287 } 00288 } 00289 00290 /* if input match table does not exist, create one with matching names 00291 * in the two networks. Insert with spec network node pointer as key 00292 * in the inputMatch table. If match table does exist, convert name table 00293 * to pointer table. 00294 */ 00295 if(inputNameMatch == NIL(st_table)) { 00296 inputMatch = GenerateIdentityMatchTable(specNetwork, implNetwork, PRIMARY_INPUTS); 00297 } else { 00298 inputMatch = GeneratePointerMatchTableFromNameMatch(specNetwork, 00299 implNetwork,inputNameMatch); 00300 if (inputMatch == NIL(st_table)) { 00301 error_append("Input pointer table is NULL\n"); 00302 /* Clean up before you leave */ 00303 error = 1; 00304 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00305 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00306 oldImplMddIdTable, specLayerArray, implLayerArray); 00307 return 1; /* error return */ 00308 } 00309 } 00310 00311 /* Save the old MDD IDs in a st_table */ 00312 oldSpecMddIdTable = SaveOldMddIds(specNetwork); 00313 if (oldSpecMddIdTable == NIL(st_table)) { 00314 error_append("Unable to save old Mdd Ids for spec\n"); 00315 /* Clean up before you leave */ 00316 error = 1; 00317 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00318 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00319 oldImplMddIdTable, specLayerArray, implLayerArray); 00320 return 1; 00321 } 00322 00323 /* Save the old MDD IDs in a st_table */ 00324 oldImplMddIdTable = SaveOldMddIds(implNetwork); 00325 if (oldImplMddIdTable == NIL(st_table)) { 00326 error_append("Unable to save old Mdd Ids for impl\n"); 00327 /* Clean up before you leave */ 00328 error = 1; 00329 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00330 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00331 oldImplMddIdTable, specLayerArray, implLayerArray); 00332 return 1; 00333 } 00334 00335 /* Initialize time to measure overall lap time */ 00336 overallLap = util_cpu_time(); 00337 00338 /* Perform direct verification of the given outputs. */ 00339 if (numDirectVerify) { 00340 /* generate output match table for outputs to be directly verified */ 00341 directVerifyMatch = GenerateDirectVerifyPointerTable(specNetwork, 00342 implNetwork, outputMatch, outputOrderArray, numDirectVerify); 00343 if (directVerifyMatch == NIL(st_table)) { 00344 error_append("Directly verify pointer table is NULL\n"); 00345 /* Clean up before you leave */ 00346 error = 1; 00347 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00348 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00349 oldImplMddIdTable, specLayerArray, implLayerArray); 00350 return 1; /* error return */ 00351 } 00352 00353 /* perform direct verification of the outputs in the match table */ 00354 directVerifyStatus = DirectVerification(specNetwork, implNetwork, 00355 directVerifyMatch, inputMatch, outputMatch, outputOrderArray); 00356 /* Direct verification error */ 00357 if (directVerifyStatus == 1) { 00358 error_append("Direct Verification error\n"); 00359 /* Clean up before you leave */ 00360 error = 1; 00361 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00362 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00363 oldImplMddIdTable, specLayerArray, implLayerArray); 00364 return 1; /* error return */ 00365 } 00366 00367 resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork, 00368 RES_NETWORK_APPL_KEY); 00369 resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork, 00370 RES_NETWORK_APPL_KEY); 00371 /* Direct verification failed */ 00372 if ((ResResidueInfoReadDirectVerificationSuccess(resultSpec) == RES_FAIL) && 00373 (ResResidueInfoReadDirectVerificationSuccess(resultImpl) == RES_FAIL)) { 00374 ResResidueInfoSetSuccess(resultSpec, RES_FAIL); 00375 ResResidueInfoSetSuccess(resultImpl, RES_FAIL); 00376 /* Clean up before you leave */ 00377 error = 0; 00378 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00379 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00380 oldImplMddIdTable, specLayerArray, implLayerArray); 00381 return 0; 00382 } else if (numDirectVerify == numOutputs) { 00383 if ((ResResidueInfoReadDirectVerificationSuccess(resultSpec) == RES_PASS) && 00384 (ResResidueInfoReadDirectVerificationSuccess(resultImpl) == RES_PASS)) { 00385 /* if all outputs are directly verified */ 00386 ResResidueInfoSetSuccess(resultSpec, RES_PASS); 00387 ResResidueInfoSetSuccess(resultImpl, RES_PASS); 00388 } 00389 } /* end of else */ 00390 00391 00392 } /* Direct Verification, done and successful */ 00393 00394 (void) fprintf(vis_stdout, "Total Direct Verification Time = %.3f (secs).\n", 00395 (util_cpu_time() - overallLap)/1000.0); 00396 00397 if (verbose >= 1) { 00398 util_print_cpu_stats(vis_stdout); 00399 } 00400 00401 00402 /* RESIDUE VERIFICATION starts here */ 00403 00404 if (numOutputs - numDirectVerify) { /* if residue verification required */ 00405 /* reset all Ids after direct verification as residue verification 00406 * assigns new Ids. 00407 */ 00408 Ntk_NetworkForEachNode(specNetwork, listGen, nodePtr) { 00409 Ntk_NodeSetMddId(nodePtr, unassignedValue); 00410 } 00411 Ntk_NetworkForEachNode(implNetwork, listGen, nodePtr) { 00412 Ntk_NodeSetMddId(nodePtr, unassignedValue); 00413 } 00414 00415 /* check if directly verified outputs are to be involved in residue 00416 * verification 00417 */ 00418 flagValue = Cmd_FlagReadByName("residue_ignore_direct_verified_outputs"); 00419 if (flagValue != NIL(char)) { 00420 if ((strcmp(flagValue, "1") == 0) && (numDirectVerify)) { 00421 ignoreOutputArray = array_alloc(Ntk_Node_t *, numDirectVerify); 00422 } 00423 } 00424 if (ignoreOutputArray == NIL(array_t)) { 00425 /* fill the output array with all output nodes */ 00426 outputArray = array_alloc(Ntk_Node_t *, array_n(outputOrderArray)); 00427 arrayForEachItem(char *, outputOrderArray, i, name) { 00428 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name); 00429 st_lookup(outputMatch, (char *)nodePtr, &implNodePtr); 00430 array_insert(Ntk_Node_t *, outputArray, i, implNodePtr); 00431 } 00432 } else { 00433 outputArray = array_alloc(Ntk_Node_t *, array_n(outputOrderArray)-numDirectVerify); 00434 /* fill the output array with nodes not directly verified */ 00435 for (i = 0; i < (array_n(outputOrderArray) - numDirectVerify); i++) { 00436 name = array_fetch(char *, outputOrderArray, i); 00437 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name); 00438 st_lookup(outputMatch, (char *)nodePtr, &implNodePtr); 00439 array_insert(Ntk_Node_t *, outputArray, i, implNodePtr); 00440 } 00441 /* fill ignore array with outputs directly verified. */ 00442 for (i = (array_n(outputOrderArray) - numDirectVerify); i < array_n(outputOrderArray); i++) { 00443 name = array_fetch(char *, outputOrderArray, i); 00444 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name); 00445 st_lookup(outputMatch, (char *)nodePtr, &implNodePtr); 00446 array_insert(Ntk_Node_t *, ignoreOutputArray, (i-array_n(outputOrderArray)+numDirectVerify) , implNodePtr); 00447 } 00448 } 00449 00450 00451 /* Compute the layers to be used for function composition */ 00452 implLayerArray = ResComputeCompositionLayers(implNetwork, outputArray, ignoreOutputArray); 00453 00454 /* create the output array for the spec. */ 00455 if (ignoreOutputArray == NIL(array_t)) { 00456 /* fill the output array with all output nodes */ 00457 arrayForEachItem(char *, outputOrderArray, i, name) { 00458 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name); 00459 array_insert(Ntk_Node_t *, outputArray, i, nodePtr); 00460 } 00461 } else { 00462 /* fill the output array with nodes not directly verified */ 00463 for (i = 0; i < (array_n(outputOrderArray) - numDirectVerify); i++) { 00464 name = array_fetch(char *, outputOrderArray, i); 00465 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name); 00466 array_insert(Ntk_Node_t *, outputArray, i, nodePtr); 00467 } 00468 /* fill ignore array with outputs directly verified. */ 00469 for (i = (array_n(outputOrderArray) - numDirectVerify); i < array_n(outputOrderArray); i++) { 00470 name = array_fetch(char *, outputOrderArray, i); 00471 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name); 00472 array_insert(Ntk_Node_t *, ignoreOutputArray, (i-array_n(outputOrderArray)+numDirectVerify), nodePtr); 00473 } 00474 } 00475 00476 /* Compute the layers to be used for function composition */ 00477 specLayerArray = ResComputeCompositionLayers(specNetwork, outputArray, ignoreOutputArray); 00478 00479 /* print the array */ 00480 if (verbose >=3) { 00481 ResLayerPrintInfo(specNetwork, specLayerArray); 00482 ResLayerPrintInfo(implNetwork, implLayerArray); 00483 } 00484 00485 /* free the ignore array */ 00486 if (ignoreOutputArray != NIL(array_t)) { 00487 array_free(ignoreOutputArray); 00488 } 00489 00490 /* Perform residue verification on the spec. and impl. */ 00491 status = ResidueVerification(specNetwork, implNetwork, outputMatch, inputMatch, numDirectVerify, specLayerArray, implLayerArray, outputArray); 00492 00493 /* free output array */ 00494 array_free(outputArray); 00495 00496 if (status) { 00497 error_append("Residue Verification error\n"); 00498 /* Clean up before you leave */ 00499 error = 1; 00500 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00501 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00502 oldImplMddIdTable, specLayerArray, implLayerArray); 00503 return 1; /* error return */ 00504 } 00505 00506 00507 resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork, 00508 RES_NETWORK_APPL_KEY); 00509 resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork, 00510 RES_NETWORK_APPL_KEY); 00511 /* Print success message and info */ 00512 if ((ResResidueInfoReadSuccess(resultSpec) == RES_FAIL) && 00513 (ResResidueInfoReadSuccess(resultImpl) == RES_FAIL)) { 00514 /* Clean up before you leave */ 00515 error = 0; 00516 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00517 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00518 oldImplMddIdTable, specLayerArray, implLayerArray); 00519 return 0; 00520 } 00521 00522 if(verbose >= 2) { 00523 (void) fprintf(vis_stdout, "Total Compose Time = %3f(secs).\n", 00524 Res_composeTime/1000.0); 00525 (void) fprintf(vis_stdout, "Total Order Time = %3f(secs).\n", 00526 Res_orderTime/1000.0); 00527 (void) fprintf(vis_stdout, "Total Shuffle Time = %3f(secs).\n", 00528 Res_shuffleTime/1000.0); 00529 00530 (void) fprintf(vis_stdout, "Total Smart Var Time = %3f(secs).\n", 00531 Res_smartVarTime/1000.0); 00532 } 00533 00534 00535 } /* end of residue verification */ 00536 00537 /* Print success message and info */ 00538 if ((ResResidueInfoReadSuccess(resultSpec) == RES_PASS) && 00539 (ResResidueInfoReadSuccess(resultImpl) == RES_PASS)) 00540 (void) fprintf(vis_stdout, "Verification of %s and %s successful.\n", 00541 Res_ResidueInfoReadName(resultSpec), 00542 Res_ResidueInfoReadName(resultImpl)); 00543 00544 00545 if (verbose >= 1) { 00546 fprintf(vis_stdout, "Specification:\n"); 00547 (void) Res_ResidueInfoPrint(resultSpec); 00548 fprintf(vis_stdout, "Implementation:\n"); 00549 (void) Res_ResidueInfoPrint(resultImpl); 00550 } 00551 if (verbose >= 1) { 00552 util_print_cpu_stats(vis_stdout); 00553 } 00554 00555 (void) fprintf(vis_stdout, "Total Time = %.3f (secs).\n", 00556 (util_cpu_time() - overallLap)/1000.0); 00557 00558 /* no error */ 00559 error = 0; 00560 Cleanup(error, specNetwork, implNetwork, initManagerHere, done, 00561 outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable, 00562 oldImplMddIdTable, specLayerArray, implLayerArray); 00563 00564 /* End of clean up */ 00565 00566 return 0; 00567 } /* End of Res_NetworkResidueVerify */ 00568 00569 /*---------------------------------------------------------------------------*/ 00570 /* Definition of internal functions */ 00571 /*---------------------------------------------------------------------------*/ 00572 00573 00574 00575 /*---------------------------------------------------------------------------*/ 00576 /* Definition of static functions */ 00577 /*---------------------------------------------------------------------------*/ 00578 00596 static int 00597 ChoosePrimes(int numOutputs, 00598 int **pool, 00599 int numDirectVerify) 00600 { 00601 double accumulator = 0.0; 00602 int i,max, index = 0; 00603 double factor = log10((double)2.0); 00604 00605 assert(*pool == NIL(int)); 00606 00607 if (numDirectVerify) { 00608 accumulator = (double)numDirectVerify; 00609 } else { 00610 /* make first prime 2^LOG2_FIRST_PRIME */ 00611 if (numOutputs >= LOG2_FIRST_PRIME) { 00612 accumulator = (double)LOG2_FIRST_PRIME; 00613 } else { 00614 accumulator = (double)numOutputs; 00615 } 00616 } 00617 00618 /* step through primes till their product exceeds the max value of outputs */ 00619 max = 0; 00620 while (accumulator < ((double)numOutputs)) { 00621 accumulator += log10((double)PrimePool[max])/factor; 00622 max++; 00623 } 00624 00625 index = 0; 00626 /* if no direct verification, then set the first prime to be 2^LOG2_FIRST_PRIME */ 00627 if (!numDirectVerify) { 00628 *pool = ALLOC(int, max+1); 00629 if (numOutputs >= LOG2_FIRST_PRIME) { 00630 (*pool)[index++] = (int)pow((double)2.0, (double)LOG2_FIRST_PRIME); 00631 } else { 00632 (*pool)[index++] = (int)pow((double)2.0, (double)numOutputs); 00633 } 00634 } else { 00635 *pool = ALLOC(int, max); 00636 } 00637 00638 /* fill the array with other primes */ 00639 for(i=0; i < max; i++) { 00640 (*pool)[index++] = PrimePool[i]; 00641 } 00642 00643 return index; 00644 } /* End of ChoosePrimes */ 00645 00646 00661 static int 00662 ComputeMaxNumberOfOutputs(void) 00663 { 00664 int i; 00665 double result = 0; 00666 int maxNumberOfOutputs; 00667 00668 result = LOG2_FIRST_PRIME; 00669 for(i = 0; i < PrimePoolSize; i++) { 00670 result += log10((double)PrimePool[i]); 00671 } /* End of for */ 00672 00673 maxNumberOfOutputs = (int) (result/log10((double) 2.0)) - 1; 00674 00675 return (maxNumberOfOutputs); 00676 } /* End of ComputeMaxNumberOfOutputs */ 00677 00678 00693 static void 00694 RestoreOldMddIds(Ntk_Network_t *network, 00695 st_table *table) 00696 { 00697 lsGen listGen; 00698 Ntk_Node_t *nodePtr; 00699 int value; 00700 if (table != NULL) { 00701 Ntk_NetworkForEachNode(network, listGen, nodePtr) { 00702 if(st_lookup_int(table, (char *)nodePtr, &value)) { 00703 Ntk_NodeSetMddId(nodePtr, value); 00704 } else { 00705 error_append("Node"); 00706 error_append(Ntk_NetworkReadName(network)); 00707 error_append("should have been in the table.\n"); 00708 (void) lsFinish(listGen); 00709 } 00710 } 00711 } 00712 } /* End of RestoreOldMddIds */ 00713 00714 00734 static st_table * 00735 GeneratePointerMatchTableFromNameMatch( 00736 Ntk_Network_t *specNetwork, 00737 Ntk_Network_t *implNetwork, 00738 st_table *nameMatchTable) 00739 { 00740 st_table *pointerMatch; 00741 Ntk_Node_t *nodePtr, *implNodePtr; 00742 st_generator *stGen; 00743 char *key, *value; 00744 00745 pointerMatch = st_init_table( st_ptrcmp, st_ptrhash); 00746 st_foreach_item(nameMatchTable, stGen, &key, &value) { 00747 /* find node in spec */ 00748 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, key); 00749 if (nodePtr == NIL(Ntk_Node_t)) { 00750 /* if node not in spec, find in impl */ 00751 implNodePtr = Ntk_NetworkFindNodeByName(implNetwork, key); 00752 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, value); 00753 } else { 00754 implNodePtr = Ntk_NetworkFindNodeByName(implNetwork,value); 00755 } 00756 if ((nodePtr == NIL(Ntk_Node_t)) || (implNodePtr == NIL(Ntk_Node_t))) { 00757 /* error */ 00758 error_append("Nodes not found by the keys in match table.\n"); 00759 st_free_gen(stGen); 00760 return NIL(st_table); 00761 } 00762 st_insert(pointerMatch, (char *)nodePtr, (char *)implNodePtr); 00763 } /* end of st_foreach_item */ 00764 00765 return(pointerMatch); 00766 } /* End of GeneratePointerMatchTableFromNameMatch */ 00767 00768 00784 static st_table * 00785 GenerateDirectVerifyPointerTable(Ntk_Network_t *specNetwork, 00786 Ntk_Network_t *implNetwork, 00787 st_table *outputMatch, 00788 array_t *outputOrderArray, 00789 int numDirectVerify) 00790 00791 { 00792 char *specName; 00793 int i; 00794 Ntk_Node_t *nodePtr, *implNodePtr; 00795 st_table *directVerifyMatch; 00796 00797 directVerifyMatch = st_init_table(st_ptrcmp, st_ptrhash); 00798 for (i = 0; i < numDirectVerify; i++) { 00799 specName = array_fetch(char *, outputOrderArray, array_n(outputOrderArray) - 1 - i); 00800 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, specName); 00801 st_lookup(outputMatch, (char *)nodePtr, &implNodePtr); 00802 if ((nodePtr == NIL(Ntk_Node_t)) || (implNodePtr == NIL(Ntk_Node_t))) { 00803 error_append("Couldn't find nodes to directly verify\n"); 00804 st_free_table(directVerifyMatch); 00805 return NIL(st_table); 00806 } 00807 st_insert(directVerifyMatch, (char *)nodePtr, (char *)implNodePtr); 00808 } 00809 return (directVerifyMatch); 00810 } /* End of GenerateDirectVerifyPointerTable */ 00811 00812 00830 static st_table * 00831 GenerateIdentityMatchTable(Ntk_Network_t *specNetwork, 00832 Ntk_Network_t *implNetwork, 00833 int inputOrOutput) 00834 { 00835 Ntk_Node_t *nodePtr, *implNodePtr; 00836 st_table *matchTable; 00837 lsGen listGen; 00838 char *name; 00839 00840 matchTable = st_init_table(st_ptrcmp, st_ptrhash); 00841 if (matchTable == NULL) return(NIL(st_table)); 00842 00843 if (inputOrOutput == PRIMARY_INPUTS) { 00844 Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) { 00845 name = Ntk_NodeReadName(nodePtr); 00846 implNodePtr = Ntk_NetworkFindNodeByName(implNetwork, name); 00847 if (implNodePtr == NIL(Ntk_Node_t)) { 00848 error_append(name); 00849 error_append(" node does not have corresponding node in impl."); 00850 st_free_table(matchTable); 00851 return (NIL(st_table)); 00852 } 00853 st_insert(matchTable, (char *)nodePtr, (char *)implNodePtr); 00854 } 00855 } else if (inputOrOutput == PRIMARY_OUTPUTS) { 00856 Ntk_NetworkForEachCombOutput(specNetwork, listGen, nodePtr) { 00857 name = Ntk_NodeReadName(nodePtr); 00858 implNodePtr = Ntk_NetworkFindNodeByName(implNetwork,name); 00859 if (implNodePtr == NIL(Ntk_Node_t)) { 00860 error_append(name); 00861 error_append(" node does not have corresponding node in impl."); 00862 st_free_table(matchTable); 00863 return (NIL(st_table)); 00864 } 00865 st_insert(matchTable, (char *)nodePtr, (char *)implNodePtr); 00866 } 00867 } 00868 return (matchTable); 00869 } /* End of GenerateIdentityMatchTable */ 00870 00887 static bdd_manager * 00888 Initializebdd_manager(Ntk_Network_t *specNetwork, 00889 Ntk_Network_t *implNetwork, 00890 int *initManagerHere) 00891 { 00892 bdd_manager *ddManager; 00893 00894 /* Read the mdd Manager (or create it if necessary) */ 00895 ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork); 00896 00897 /* To set the spec manager the same as the impl. manager, either 00898 * both are nil, or the impl manager is freed and set to the 00899 * spec manager 00900 */ 00901 if(ddManager != (bdd_manager *)Ntk_NetworkReadMddManager(implNetwork)) { 00902 if ((bdd_manager *)Ntk_NetworkReadMddManager(implNetwork) != NIL(bdd_manager)) { 00903 /* unacceptable if the impl. manager is different from NIl or 00904 * from the spec manager 00905 */ 00906 mdd_quit(Ntk_NetworkReadMddManager(implNetwork)); 00907 } 00908 Ntk_NetworkSetMddManager(implNetwork, (mdd_manager *)ddManager); 00909 } 00910 00911 /* if the spec. manager is NIL, then network initialize manager */ 00912 if (ddManager == NIL(bdd_manager)) { 00913 /* flag to say that manager is verified here */ 00914 *initManagerHere = 1; 00915 ddManager = (bdd_manager *)Ntk_NetworkInitializeMddManager(specNetwork); 00916 Ntk_NetworkSetMddManager(implNetwork, (mdd_manager *)ddManager); 00917 } 00918 return (ddManager); 00919 } /* End of Initializebdd_manager */ 00920 00943 static int 00944 SetBasicResultInfo (Ntk_Network_t *specNetwork, 00945 Ntk_Network_t *implNetwork, 00946 int numDirectVerify) 00947 { 00948 int numInputs; 00949 int numOutputs; 00950 char *specName; 00951 char *implName; 00952 Res_ResidueInfo_t *resultSpec; 00953 Res_ResidueInfo_t *resultImpl; 00954 00955 /* if previous verification to be considered, make sure the 00956 * verification was with the same spec network and the number 00957 * of directly verified outputs are the same. 00958 */ 00959 resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork, 00960 RES_NETWORK_APPL_KEY); 00961 00962 if (resultSpec != NIL(Res_ResidueInfo_t)) { 00963 if ((strcmp(ResResidueInfoReadNameVerifiedAgainst(resultSpec), 00964 Ntk_NetworkReadName(implNetwork)) == 0) && 00965 (ResResidueInfoReadNumDirectVerifiedOutputs(resultSpec) == 00966 numDirectVerify) && 00967 (ResResidueInfoReadSuccess(resultSpec) == RES_PASS)) { 00968 /* if already verified then done, return success (0) */ 00969 return RES_VERIFY_DONE; 00970 } 00971 /* if the above conditions are not satisfied, attempt 00972 * verification again 00973 */ 00974 Ntk_NetworkFreeApplInfo(specNetwork, RES_NETWORK_APPL_KEY ); 00975 } 00976 00977 00978 /* create result structure */ 00979 resultSpec = (Res_ResidueInfo_t *) 00980 ResNetworkResidueInfoReadOrCreate(specNetwork); 00981 /* add hook to network */ 00982 Ntk_NetworkAddApplInfo(specNetwork, RES_NETWORK_APPL_KEY, 00983 (Ntk_ApplInfoFreeFn) Res_ResidueInfoFreeCallback, 00984 (void *)resultSpec); 00985 00986 /* number of outputs */ 00987 numOutputs = Ntk_NetworkReadNumCombOutputs(specNetwork); 00988 ResResidueInfoSetNumOutputs(resultSpec, numOutputs); 00989 /* number of Inputs */ 00990 numInputs = Ntk_NetworkReadNumCombInputs(specNetwork); 00991 ResResidueInfoSetNumInputs(resultSpec, numInputs); 00992 /* impl name */ 00993 implName = util_strsav(Ntk_NetworkReadName(implNetwork)); 00994 ResResidueInfoSetNameVerifiedAgainst(resultSpec, implName); 00995 /* number of directly verified outputs */ 00996 ResResidueInfoSetNumDirectVerifiedOutputs(resultSpec, numDirectVerify); 00997 00998 /* 00999 * Assumption: The implementation residue information is invalid even 01000 * if it does exist and will be overwritten 01001 */ 01002 resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork, 01003 RES_NETWORK_APPL_KEY); 01004 /* free existing structure */ 01005 if (resultImpl != NIL(Res_ResidueInfo_t)) { 01006 Ntk_NetworkFreeApplInfo(implNetwork,RES_NETWORK_APPL_KEY); 01007 } 01008 01009 /* create a new structure for the implementation network */ 01010 resultImpl = (Res_ResidueInfo_t *) 01011 ResNetworkResidueInfoReadOrCreate(implNetwork); 01012 Ntk_NetworkAddApplInfo(implNetwork, RES_NETWORK_APPL_KEY, 01013 (Ntk_ApplInfoFreeFn) Res_ResidueInfoFreeCallback, 01014 (void *)resultImpl); 01015 01016 01017 /* 01018 * Get some information about the network and initialize the residue 01019 * information for the implementation network. 01020 */ 01021 01022 /* number of outputs */ 01023 assert (numOutputs == Ntk_NetworkReadNumCombOutputs(implNetwork)); 01024 ResResidueInfoSetNumOutputs(resultImpl, numOutputs); 01025 /* number of Inputs */ 01026 assert (numInputs == Ntk_NetworkReadNumCombInputs(implNetwork)); 01027 ResResidueInfoSetNumInputs(resultImpl, numInputs); 01028 /* spec name */ 01029 specName = util_strsav(Ntk_NetworkReadName(specNetwork)); 01030 ResResidueInfoSetNameVerifiedAgainst(resultImpl, specName); 01031 /* number of directly verified outputs */ 01032 ResResidueInfoSetNumDirectVerifiedOutputs(resultImpl, numDirectVerify); 01033 01034 return RES_VERIFY_IGNORE_PREV_RESULTS; 01035 } /* End of SetBasicResultInfo */ 01036 01058 static void 01059 Cleanup(int error, 01060 Ntk_Network_t *specNetwork, 01061 Ntk_Network_t *implNetwork, 01062 int initManagerHere, 01063 int done, 01064 st_table *outputMatch, 01065 st_table *inputMatch, 01066 st_table *directVerifyMatch, 01067 st_table *oldSpecMddIdTable, 01068 st_table *oldImplMddIdTable, 01069 array_t *specLayerArray, 01070 array_t *implLayerArray) 01071 { 01072 bdd_manager *ddManager; 01073 01074 if (initManagerHere) { 01075 ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork); 01076 if (ddManager != NIL(bdd_manager)) { 01077 mdd_quit(ddManager); 01078 Ntk_NetworkSetMddManager(specNetwork, NIL(mdd_manager)); 01079 Ntk_NetworkSetMddManager(implNetwork, NIL(mdd_manager)); 01080 } 01081 } 01082 01083 if (done != RES_VERIFY_NOTHING) { /* if result structure allocated */ 01084 if (error) { /* on error free results */ 01085 if (done == RES_VERIFY_IGNORE_PREV_RESULTS) { 01086 /* if spec result was created here */ 01087 Ntk_NetworkFreeApplInfo(specNetwork,RES_NETWORK_APPL_KEY); 01088 } 01089 Ntk_NetworkFreeApplInfo(implNetwork,RES_NETWORK_APPL_KEY); 01090 } 01091 } 01092 if (outputMatch != NIL(st_table)) { 01093 st_free_table(outputMatch); 01094 } 01095 if (inputMatch != NIL(st_table)) { 01096 st_free_table(inputMatch); 01097 } 01098 if (directVerifyMatch != NIL(st_table)) { 01099 st_free_table(directVerifyMatch); 01100 } 01101 01102 if (oldSpecMddIdTable != NIL(st_table)) { 01103 RestoreOldMddIds(specNetwork, oldSpecMddIdTable); 01104 st_free_table(oldSpecMddIdTable); 01105 } 01106 if (oldImplMddIdTable != NIL(st_table)) { 01107 RestoreOldMddIds(implNetwork, oldImplMddIdTable); 01108 st_free_table(oldImplMddIdTable); 01109 } 01110 if (specLayerArray != NULL) { 01111 ResLayerArrayFree(specLayerArray); 01112 } 01113 if (implLayerArray != NULL) { 01114 ResLayerArrayFree(implLayerArray); 01115 } 01116 return; 01117 } /* End of Cleanup */ 01118 01119 01132 static st_table * 01133 SaveOldMddIds(Ntk_Network_t *network) 01134 { 01135 st_table *oldMddIdTable; 01136 Ntk_Node_t *nodePtr; 01137 lsGen listGen; /* To iterate over outputList */ 01138 01139 oldMddIdTable = st_init_table(st_ptrcmp, st_ptrhash); 01140 if (oldMddIdTable == NULL) return NIL(st_table); 01141 01142 Ntk_NetworkForEachNode(network, listGen, nodePtr) { 01143 st_insert(oldMddIdTable, (char *)nodePtr, 01144 (char *)(long)Ntk_NodeReadMddId(nodePtr)); 01145 } 01146 return(oldMddIdTable); 01147 } 01148 01174 static int 01175 DirectVerification(Ntk_Network_t *specNetwork, 01176 Ntk_Network_t *implNetwork, 01177 st_table *directVerifyMatch, 01178 st_table *inputMatch, 01179 st_table *outputMatch, 01180 array_t *outputOrderArray) 01181 { 01182 01183 Ntk_Node_t *nodePtr, *implNodePtr; /* node variables */ 01184 long startTime, endTime, directVerifyTime; /* to measure elapsed time */ 01185 long lapTimeSpec, lapTimeImpl; /* to measure elapsed time */ 01186 bdd_node *specBDD, *implBDD, *permutedBDD; /* bdds of direct verified outputs */ 01187 lsGen listGen; /* To iterate over outputList */ 01188 int *permut; /* permutation array to store 01189 * correspondence of inputs 01190 */ 01191 int specMddId, implMddId; 01192 Ntk_Node_t **specArray, **implArray; /* arrays to store the 01193 * corresponding nodes of the 01194 * spec. and the impl. 01195 */ 01196 st_generator *stGen; 01197 lsList dummy; /* dummy list fed to the ord 01198 * package. 01199 */ 01200 char *key, *value; /* variables to read values 01201 * from the st_table 01202 */ 01203 int index, i; /* iterators */ 01204 char *name; /* variable to read node name */ 01205 int numOutputs; /* total number of outputs of 01206 * the spec.(impl). 01207 */ 01208 bdd_manager *ddManager; /* the bdd manager */ 01209 bdd_reorder_type_t oldDynMethod, dynMethod = BDD_REORDER_SAME; 01210 /* dynamic reordering methods */ 01211 int dynStatus = 0; /* original status of the manager 01212 * w. r. t. dynamic reordering 01213 */ 01214 boolean dyn; /* current dynamic reordering 01215 * status 01216 */ 01217 int verbose; /* verbosity level */ 01218 char *flagValue; /* string to hold "Set" variable 01219 * value 01220 */ 01221 Res_ResidueInfo_t *resultSpec; /* result structure for the 01222 * spec. 01223 */ 01224 Res_ResidueInfo_t *resultImpl; /* result structure for the 01225 * impl. 01226 */ 01227 int specSize, implSize; /* sizes of bdds */ 01228 mdd_t *fnMddT; /* mdd_t structure to calculate sizes */ 01229 01230 01231 /* Initializations */ 01232 dummy = (lsList)0; 01233 lapTimeSpec = 0; 01234 lapTimeImpl = 0; 01235 dyn = FALSE; 01236 verbose = 0; 01237 01238 /* read verbosity value */ 01239 flagValue = Cmd_FlagReadByName("residue_verbosity"); 01240 if (flagValue != NIL(char)) { 01241 verbose = atoi(flagValue); 01242 } 01243 01244 /* read if dynamic ordering is required */ 01245 flagValue = Cmd_FlagReadByName("residue_autodyn_direct_verif"); 01246 if (flagValue != NIL(char)) { 01247 dyn = (strcmp(flagValue, "1") == 0) ? TRUE : FALSE; 01248 } 01249 /* read method for dynamic reordering */ 01250 if (dyn == TRUE) { 01251 flagValue = Cmd_FlagReadByName("residue_direct_dyn_method"); 01252 if (flagValue != NULL) { 01253 dynMethod = DecodeDynMethod(flagValue); 01254 } else { 01255 dynMethod = BDD_REORDER_SAME; 01256 } 01257 } 01258 01259 /* read manager from network */ 01260 ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork); 01261 /* save old values for dynamic reordering */ 01262 if (dyn == TRUE) { 01263 dynStatus = bdd_reordering_status(ddManager, &oldDynMethod); 01264 bdd_dynamic_reordering(ddManager, dynMethod, BDD_REORDER_VERBOSITY_DEFAULT); 01265 } 01266 01267 /* find total time elapsed */ 01268 directVerifyTime = util_cpu_time(); 01269 01270 /* find number of outputs to be directly verified */ 01271 numOutputs = st_count(directVerifyMatch); 01272 01273 /* 01274 * Order primary input variables in the network to build the BDDs for 01275 * outputs to be directly verified. 01276 */ 01277 if (Ord_NetworkTestAreVariablesOrdered(specNetwork, 01278 Ord_InputAndLatch_c) == FALSE) { 01279 /* order the variables in the network since not done */ 01280 startTime = util_cpu_time(); 01281 Ord_NetworkOrderVariables(specNetwork, Ord_RootsByDefault_c, 01282 Ord_NodesByDefault_c, FALSE, Ord_InputAndLatch_c, 01283 Ord_Unassigned_c, dummy, 0); 01284 01285 endTime = util_cpu_time(); 01286 lapTimeSpec += endTime - startTime; 01287 01288 startTime = endTime; 01289 Ord_NetworkOrderVariables(implNetwork, Ord_RootsByDefault_c, 01290 Ord_NodesByDefault_c, FALSE, Ord_InputAndLatch_c, 01291 Ord_Unassigned_c, dummy, 0); 01292 lapTimeImpl += endTime - startTime; 01293 01294 } else { 01295 /* if order is not specified, assume the same order for spec. 01296 * and implementation 01297 */ 01298 Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) { 01299 assert(Ntk_NodeReadMddId(nodePtr) != NTK_UNASSIGNED_MDD_ID); 01300 st_lookup(inputMatch, (char *)nodePtr, &implNodePtr); 01301 Ntk_NodeSetMddId(implNodePtr, Ntk_NodeReadMddId(nodePtr)); 01302 } 01303 } 01304 01305 if (verbose >= 5) { 01306 Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) { 01307 specMddId = Ntk_NodeReadMddId(nodePtr); 01308 if (specMddId != NTK_UNASSIGNED_MDD_ID) { 01309 fprintf(vis_stdout, "%s ", Ntk_NodeReadName(nodePtr)); 01310 } 01311 } 01312 fprintf(vis_stdout, "\n"); 01313 Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) { 01314 specMddId = Ntk_NodeReadMddId(nodePtr); 01315 if (specMddId != NTK_UNASSIGNED_MDD_ID) { 01316 fprintf(vis_stdout, "%d ", specMddId); 01317 } 01318 } 01319 fprintf(vis_stdout, "\n"); 01320 } 01321 01322 /* build arrays of corresponding nodes to be directly verified */ 01323 specArray = ALLOC(Ntk_Node_t *, numOutputs); 01324 implArray = ALLOC(Ntk_Node_t *, numOutputs); 01325 index = 0; 01326 /* Order array starting from the LSB, so direct verification is performed 01327 * starting from the inputs. 01328 */ 01329 for (i = 0; i < array_n(outputOrderArray); i++) { 01330 name = array_fetch(char *, outputOrderArray, array_n(outputOrderArray)-1-i); 01331 nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name); 01332 /* find node in direct verify match table */ 01333 if (st_lookup(directVerifyMatch, (char *)nodePtr, (char **)&value)) { 01334 specArray[index] = (Ntk_Node_t *)nodePtr; 01335 implArray[index] = (Ntk_Node_t *)value; 01336 index++; 01337 } 01338 } 01339 /* number of outputs in the arrays should be as many entries as the match 01340 * table. 01341 */ 01342 assert(numOutputs == index); 01343 01344 /* Create a permutation array for the specMddId and implMddId input nodes */ 01345 permut = ALLOC(int, bdd_num_vars(ddManager)); 01346 for (i= 0; (unsigned) i < bdd_num_vars(ddManager); i++) { 01347 permut[i] = i; 01348 } 01349 st_foreach_item(inputMatch, stGen, &key, &value) { 01350 nodePtr = (Ntk_Node_t *)key; 01351 implNodePtr = (Ntk_Node_t *)value; 01352 if ((nodePtr == NIL(Ntk_Node_t)) || (implNodePtr == NIL(Ntk_Node_t))){ 01353 error_append("Input match values do not return"); 01354 error_append("valid node pointers.\n"); 01355 /* Clean up */ 01356 FREE(permut); 01357 FREE(specArray); 01358 FREE(implArray); 01359 st_free_gen(stGen); 01360 return 1; 01361 } 01362 /* create the array with the impl. vars to be composed with spec. vars. */ 01363 specMddId = Ntk_NodeReadMddId(nodePtr); 01364 implMddId = Ntk_NodeReadMddId(implNodePtr); 01365 /* there should be no node with NTK_UNASSIGNED_MDD_ID due to the 01366 * ordering above 01367 */ 01368 assert(specMddId != NTK_UNASSIGNED_MDD_ID); 01369 assert(implMddId != NTK_UNASSIGNED_MDD_ID); 01370 permut[implMddId] = specMddId; 01371 01372 } /* end of input match */ 01373 01374 /* 01375 * Build BDDs for each output to be directly verified and check 01376 * for identical BDDs in spec. and impl. 01377 */ 01378 for (i = 0; i < numOutputs; i++) { 01379 /* build the spec BDD */ 01380 startTime = util_cpu_time(); 01381 specBDD = BuildBDDforNode(specNetwork, specArray[i], PRIMARY_INPUTS); 01382 if (specBDD == NIL(bdd_node)) { 01383 error_append("Unable to build spec. BDD for the direct verification output"); 01384 error_append(Ntk_NodeReadName(specArray[i])); 01385 error_append(".\n"); 01386 /* Clean up */ 01387 FREE(permut); 01388 FREE(specArray); 01389 FREE(implArray); 01390 return 1; /* error status */ 01391 } /* end of if spec BDD is NIL */ 01392 endTime = util_cpu_time(); 01393 lapTimeSpec += endTime - startTime; 01394 01395 /* build the impl BDD */ 01396 startTime = endTime; 01397 implBDD = BuildBDDforNode(implNetwork, implArray[i], PRIMARY_INPUTS); 01398 if (implBDD == NIL(bdd_node)) { 01399 error_append("Unable to build spec. BDD for the direct verification output"); 01400 error_append(Ntk_NodeReadName(implArray[i])); 01401 error_append(".\n"); 01402 /* Clean up */ 01403 bdd_recursive_deref(ddManager, specBDD); 01404 FREE(permut); 01405 FREE(specArray); 01406 FREE(implArray); 01407 return 1; /* error status */ 01408 } /* end of if spec BDD is NIL */ 01409 endTime = util_cpu_time(); 01410 lapTimeImpl += endTime - startTime; 01411 01412 /* call bdd permute to compose the impl variables with the spec 01413 * variables. 01414 */ 01415 startTime = endTime; 01416 bdd_ref(permutedBDD = bdd_bdd_permute(ddManager, implBDD, permut)); 01417 bdd_recursive_deref(ddManager, implBDD); 01418 endTime = util_cpu_time(); 01419 lapTimeSpec += (endTime - startTime)/2; 01420 lapTimeImpl += (endTime - startTime)/2; 01421 implBDD = permutedBDD; 01422 if (implBDD == NIL(bdd_node)) { 01423 error_append("Permuting the impl bdd in terms of spec bdd vars failed\n"); 01424 /* Clean up */ 01425 bdd_recursive_deref(ddManager, specBDD); 01426 FREE(permut); 01427 FREE(specArray); 01428 FREE(implArray); 01429 return 1; /* error status */ 01430 } 01431 01432 /* compare the bdds */ 01433 if(specBDD != implBDD) { 01434 /* error since spec and impl are not the same */ 01435 /* update result structure */ 01436 if (verbose >= 2) { 01437 (void)fprintf(vis_stdout, "Vector where the two networks differ :\n"); 01438 (void)fprintf(vis_stdout, "Specification Input Names :\n"); 01439 ExtractACubeOfDifference(ddManager, specNetwork, specBDD, implBDD); 01440 } 01441 resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork, 01442 RES_NETWORK_APPL_KEY); 01443 resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork, 01444 RES_NETWORK_APPL_KEY); 01445 ResResidueInfoSetDirectVerificationSuccess(resultSpec, RES_FAIL); 01446 ResResidueInfoSetDirectVerificationSuccess(resultImpl, RES_FAIL); 01447 (void) fprintf(vis_stdout, "%.2f (secs) spent in failed direct verification.\n", 01448 (util_cpu_time() - directVerifyTime)/1000.0); 01449 fprintf(vis_stdout, "Residue Direct Verification failed at output node "); 01450 fprintf(vis_stdout, "%s", Ntk_NodeReadName(specArray[i])); 01451 fprintf(vis_stdout, " of the spec.\n"); 01452 fprintf(vis_stdout, "Spec. did not match Impl.\n"); 01453 /* Clean up */ 01454 /* free the bdds just created */ 01455 bdd_recursive_deref(ddManager, specBDD); 01456 bdd_recursive_deref(ddManager, implBDD); 01457 FREE(permut); 01458 FREE(specArray); 01459 FREE(implArray); 01460 return 0; 01461 } /* end if spec BDD != impl BDD */ 01462 01463 /* if the bdds are equal, print some information */ 01464 if (verbose >= 2) { 01465 fprintf(vis_stdout, "%d out of %d ", i + 1 ,numOutputs); 01466 fprintf(vis_stdout, "direct verification outputs done.\n"); 01467 } 01468 if (verbose >= 3) { 01469 fprintf(vis_stdout, "%s(spec)/%s(impl) output verified. \n", 01470 Ntk_NodeReadName(specArray[i]), Ntk_NodeReadName(implArray[i])); 01471 bdd_ref(specBDD); 01472 fnMddT = bdd_construct_bdd_t(ddManager, specBDD); 01473 specSize = bdd_size(fnMddT); 01474 bdd_free(fnMddT); 01475 bdd_ref(implBDD); 01476 fnMddT = bdd_construct_bdd_t(ddManager, implBDD); 01477 implSize = bdd_size(fnMddT); 01478 bdd_free(fnMddT); 01479 fprintf(vis_stdout, "Size of %s(spec) = %d, Size of %s(impl) = %d\n", 01480 Ntk_NodeReadName(specArray[i]) ,specSize, Ntk_NodeReadName(implArray[i]), implSize); 01481 fprintf(vis_stdout, "%.3f spec time elapsed, %.3f impl. time elapsed.\n", lapTimeSpec/1000.0, 01482 lapTimeImpl/1000.0); 01483 } 01484 /* free the bdds just created */ 01485 bdd_recursive_deref(ddManager, specBDD); 01486 bdd_recursive_deref(ddManager, implBDD); 01487 01488 } /* end of for-loop that iterates through the nodes to be directly 01489 * verified. 01490 */ 01491 01492 FREE(permut); 01493 FREE(specArray); 01494 FREE(implArray); 01495 01496 /* set direct verification success info */ 01497 /* update result structure */ 01498 resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork, 01499 RES_NETWORK_APPL_KEY); 01500 resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork, 01501 RES_NETWORK_APPL_KEY); 01502 ResResidueInfoSetDirectVerificationSuccess(resultSpec, RES_PASS); 01503 ResResidueInfoSetCpuDirectVerif(resultSpec, (float) lapTimeSpec); 01504 ResResidueInfoSetDirectVerificationSuccess(resultImpl, RES_PASS); 01505 ResResidueInfoSetCpuDirectVerif(resultImpl, (float) lapTimeImpl); 01506 01507 /* Print success message */ 01508 fprintf(vis_stdout, "Residue Direct Verification successful.\n"); 01509 01510 /* Print Time taken for direct verification */ 01511 if (verbose >= 1) { 01512 (void) fprintf(vis_stdout, "%.2f (secs) spent in Direct verification.\n", 01513 (util_cpu_time() - directVerifyTime)/1000.0); 01514 } 01515 01516 /* Print which outputs were directly verified and time spent for 01517 * the spec and the impl 01518 */ 01519 if (verbose >= 2) { 01520 fprintf(vis_stdout, "Time taken to build spec. BDD = %.3f\n", 01521 ResResidueInfoReadCpuDirectVerif(resultSpec)/1000.0); 01522 fprintf(vis_stdout, "Time taken to build impl. BDD = %.3f\n", 01523 ResResidueInfoReadCpuDirectVerif(resultImpl)/1000.0); 01524 st_foreach_item(directVerifyMatch, stGen, &key, &value) { 01525 fprintf(vis_stdout, "%s ", Ntk_NodeReadName((Ntk_Node_t *)key)); 01526 } 01527 fprintf(vis_stdout, "verified successfully.\n"); 01528 } 01529 01530 /* Print order of variables of this verification */ 01531 if (verbose >= 3) { 01532 Ord_NetworkPrintVariableOrder(vis_stdout, specNetwork, 01533 Ord_InputAndLatch_c); 01534 Ord_NetworkPrintVariableOrder(vis_stdout, implNetwork, 01535 Ord_InputAndLatch_c); 01536 } 01537 01538 /* restore the old values for dynamic reordering */ 01539 if(dyn == TRUE) { 01540 bdd_dynamic_reordering(ddManager, oldDynMethod, BDD_REORDER_VERBOSITY_DEFAULT); 01541 if (!dynStatus) { 01542 bdd_dynamic_reordering_disable(ddManager); 01543 } 01544 } 01545 01546 return 0; /* direct verification success */ 01547 } /* End of Direct Verification */ 01548 01549 01559 static bdd_reorder_type_t 01560 DecodeDynMethod(char *dynMethodString) 01561 { 01562 bdd_reorder_type_t dynMethod; 01563 01564 /* Translate reordering string to specifying method */ 01565 if (dynMethodString == NIL(char)) { 01566 dynMethod = BDD_REORDER_SIFT; 01567 } else if (strcmp(dynMethodString, "same") == 0) { 01568 dynMethod = BDD_REORDER_SAME; 01569 } else if (strcmp(dynMethodString, "none") == 0) { 01570 dynMethod = BDD_REORDER_NONE; 01571 } else if (strcmp(dynMethodString, "random") == 0) { 01572 dynMethod = BDD_REORDER_RANDOM; 01573 } else if (strcmp(dynMethodString, "randompivot") == 0) { 01574 dynMethod = BDD_REORDER_RANDOM_PIVOT; 01575 } else if (strcmp(dynMethodString, "sift") == 0) { 01576 dynMethod = BDD_REORDER_SIFT; 01577 } else if (strcmp(dynMethodString, "siftconverge") == 0) { 01578 dynMethod = BDD_REORDER_SIFT_CONVERGE; 01579 } else if (strcmp(dynMethodString, "symmsift") == 0) { 01580 dynMethod = BDD_REORDER_SYMM_SIFT; 01581 } else if (strcmp(dynMethodString, "symmsiftconverge") == 0) { 01582 dynMethod = BDD_REORDER_SYMM_SIFT_CONV; 01583 } else if (strcmp(dynMethodString, "window2") == 0) { 01584 dynMethod = BDD_REORDER_WINDOW2; 01585 } else if (strcmp(dynMethodString, "window3") == 0) { 01586 dynMethod = BDD_REORDER_WINDOW3; 01587 } else if (strcmp(dynMethodString, "window4") == 0) { 01588 dynMethod = BDD_REORDER_WINDOW4; 01589 } else if (strcmp(dynMethodString, "window2converge") == 0) { 01590 dynMethod = BDD_REORDER_WINDOW2_CONV; 01591 } else if (strcmp(dynMethodString, "window3converge") == 0) { 01592 dynMethod = BDD_REORDER_WINDOW3_CONV; 01593 } else if (strcmp(dynMethodString, "window4converge") == 0) { 01594 dynMethod = BDD_REORDER_WINDOW4_CONV; 01595 } else if (strcmp(dynMethodString, "groupsift") == 0) { 01596 dynMethod = BDD_REORDER_GROUP_SIFT; 01597 } else if (strcmp(dynMethodString, "groupsiftconverge") == 0) { 01598 dynMethod = BDD_REORDER_GROUP_SIFT_CONV; 01599 } else if (strcmp(dynMethodString, "anneal") == 0) { 01600 dynMethod = BDD_REORDER_ANNEALING; 01601 } else if (strcmp(dynMethodString, "genetic") == 0) { 01602 dynMethod = BDD_REORDER_GENETIC; 01603 } else if (strcmp(dynMethodString, "linear") == 0) { 01604 dynMethod = BDD_REORDER_LINEAR; 01605 } else if (strcmp(dynMethodString, "linearconverge") == 0) { 01606 dynMethod = BDD_REORDER_LINEAR_CONVERGE; 01607 } else if (strcmp(dynMethodString, "exact") == 0) { 01608 dynMethod = BDD_REORDER_EXACT; 01609 } else { 01610 dynMethod = BDD_REORDER_SIFT; 01611 } 01612 return dynMethod; 01613 } /* End of DecodeDynMethod */ 01614 01615 01616 01643 static int 01644 ResidueVerification(Ntk_Network_t *specNetwork, 01645 Ntk_Network_t *implNetwork, 01646 st_table *outputMatch, 01647 st_table *inputMatch, 01648 int numDirectVerify, 01649 array_t *specLayerArray, 01650 array_t *implLayerArray, 01651 array_t *outputArray) 01652 { 01653 int numOutputs; /* number of outputs in the networks */ 01654 int actualOutputs; /* number of outputs in the networks */ 01655 int msbId; /* stores the top Id available */ 01656 int msbLsb; /* 1 means Msb on top */ 01657 01658 Ntk_Node_t *nodePtr, *implNodePtr; /* variables to store nodes in networks */ 01659 01660 Res_ResidueInfo_t *resultSpec; /* spec. result structure */ 01661 Res_ResidueInfo_t *resultImpl; /* impl. result structure */ 01662 01663 int verbose; /* verbosity value */ 01664 char *flagValue; /* string to store flag values */ 01665 int i; /* iterating index */ 01666 01667 lsGen listGen; /* list generator for looping over nodes 01668 * in a network. 01669 */ 01670 st_generator *stGen; /* generator to step through st_table */ 01671 char *key, *value; /* variables to read in st-table values */ 01672 long overallLap; /* to measure elapsed time */ 01673 long lap; /* to measure elapsed time */ 01674 int primeIndex; /* index to iterate over prime array */ 01675 bdd_manager *ddManager; /* Manager read from the network */ 01676 bdd_node *implADD, *specADD, *tmpDd; /* final ADDs after composition */ 01677 int specSize, implSize; /* sizes of bdds */ 01678 int specMddId, implMddId; /* id variables for nodes */ 01679 bdd_node *residueDd; /* residue ADD (n x m) */ 01680 int *permut; /* array to permute impl ADD variables to spec. 01681 * ADD variables. 01682 */ 01683 int numOfPrimes; /* Number of primes needed for verification */ 01684 int *primeTable; /* array to store primes needed for current 01685 * verification 01686 */ 01687 bdd_reorder_type_t oldDynMethod, dynMethod; /* dynamic reordering 01688 * methods 01689 */ 01690 int dynStatus; /* Status of manager w.r.t. original 01691 * reordering 01692 */ 01693 boolean dyn; /* flag to indicate dynamic reordering 01694 * is turned on. 01695 */ 01696 mdd_t *fnMddT; /* mdd_t structure to calculate sizes */ 01697 int unassignedValue; /* NTK_UNASSIGNED_MDD_ID value holder */ 01698 array_t *implOutputArray; /* array of output nodes of the impl.in consideration 01699 * for composition 01700 */ 01701 01702 /* Initialization */ 01703 verbose = 0; 01704 unassignedValue = NTK_UNASSIGNED_MDD_ID; 01705 numOfPrimes = 0; 01706 msbLsb = 1; /* default value msb is on top */ 01707 primeTable = NULL; 01708 overallLap = util_cpu_time(); 01709 dyn = FALSE; /* default dynamic reordering disabled */ 01710 permut = NULL; 01711 01712 /* specify if the top var of the residue ADD is the MSB/LSB */ 01713 flagValue = Cmd_FlagReadByName("residue_top_var"); 01714 if (flagValue != NIL(char) && strcmp(flagValue,"lsb") == 0) { 01715 msbLsb = 0; 01716 } else { 01717 msbLsb = 1; 01718 } 01719 01720 /* initialize number of outputs */ 01721 actualOutputs = Ntk_NetworkReadNumCombOutputs(specNetwork); 01722 01723 /* Read the mdd Manager (or create it if necessary) */ 01724 ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork); 01725 /* save old dynamic reordering values */ 01726 dynStatus = bdd_reordering_status(ddManager, &oldDynMethod); 01727 01728 /* read verbosity value */ 01729 flagValue = Cmd_FlagReadByName("residue_verbosity"); 01730 if (flagValue != NIL(char)) { 01731 verbose = atoi(flagValue); 01732 } 01733 01734 /* read if dynamic ordering is required */ 01735 flagValue = Cmd_FlagReadByName("residue_autodyn_residue_verif"); 01736 if (flagValue != NIL(char)) { 01737 dyn = (strcmp(flagValue,"1")==0) ? TRUE : FALSE; 01738 } 01739 /* read method of dynamic reordering */ 01740 if (dyn == TRUE) { 01741 flagValue = Cmd_FlagReadByName("residue_residue_dyn_method"); 01742 if ( flagValue != NULL) { 01743 dynMethod = DecodeDynMethod(flagValue); 01744 } else { 01745 dynMethod = BDD_REORDER_SAME; 01746 } 01747 /* update manager with dynamic reordering and the method */ 01748 bdd_dynamic_reordering(ddManager, dynMethod, BDD_REORDER_VERBOSITY_DEFAULT); 01749 } else { 01750 /* unless specified, TURN REORDERING OFF for residue verification */ 01751 bdd_dynamic_reordering_disable(ddManager); 01752 } 01753 01754 /* 01755 * Choose the set of primes that will be used, primeTable is allocated 01756 * here. 01757 */ 01758 numOfPrimes = ChoosePrimes(actualOutputs, &primeTable, numDirectVerify); 01759 01760 /* get result structures */ 01761 resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork, 01762 RES_NETWORK_APPL_KEY); 01763 resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork, 01764 RES_NETWORK_APPL_KEY); 01765 01766 /* update result with primes info */ 01767 if ((resultSpec != NIL(Res_ResidueInfo_t)) && (resultImpl != NIL(Res_ResidueInfo_t))) { 01768 ResResidueInfoAllocatePrimeInfoArray(resultSpec, numOfPrimes, primeTable); 01769 ResResidueInfoAllocatePrimeInfoArray(resultImpl, numOfPrimes, primeTable); 01770 ResResidueInfoSetNumOfPrimes(resultSpec, numOfPrimes); 01771 ResResidueInfoSetNumOfPrimes(resultImpl, numOfPrimes); 01772 } else { 01773 /* error - the result structure should be there */ 01774 error_append("Result structures are missing\n"); 01775 FREE(primeTable); 01776 return 1; 01777 } 01778 01779 /* Print the list of primes depending on the verbosity level*/ 01780 if (verbose >= 0) { 01781 (void) fprintf(vis_stdout, "List of Primes used: "); 01782 for(i=0; i<numOfPrimes; i++) { 01783 (void) fprintf(vis_stdout, "%d ", primeTable[i]); 01784 } 01785 (void) fprintf(vis_stdout, "\n"); 01786 } /* End of if */ 01787 01788 /* form impl Output Array */ 01789 implOutputArray = array_alloc(Ntk_Node_t *, array_n(outputArray)); 01790 arrayForEachItem(Ntk_Node_t *, outputArray, i, nodePtr) { 01791 st_lookup(outputMatch, (char *)nodePtr, &implNodePtr); 01792 array_insert(Ntk_Node_t *, implOutputArray, i, implNodePtr); 01793 } 01794 01795 /* number of outputs in consideration */ 01796 numOutputs = array_n(outputArray); 01797 01798 01799 /* Main Loop in which the verification is done for each prime. */ 01800 for(primeIndex = 0; primeIndex < numOfPrimes; primeIndex++) { 01801 int currentPrime; 01802 01803 /* Read current prime from table */ 01804 currentPrime = primeTable[primeIndex]; 01805 if (verbose >=2) 01806 (void) fprintf(vis_stdout, "Processing prime %d:\n", currentPrime); 01807 01808 /* update the mdd manager with the first set of output variables */ 01809 MddCreateVariables((mdd_manager *)ddManager, numOutputs-bdd_num_vars(ddManager)); 01810 01811 01812 /* Obtain the residue bdd for the given prime, assume top id is 01813 * always 0i.e. msbId = 0; 01814 */ 01815 msbId = 0; 01816 bdd_ref(residueDd = bdd_add_residue(ddManager, numOutputs, currentPrime, 01817 msbLsb, msbId)); 01818 01819 /* Set the output Id. Needs to be set each time because it gets 01820 * cleared each time. 01821 */ 01822 arrayForEachItem(Ntk_Node_t *, outputArray, i , nodePtr) { 01823 st_lookup(outputMatch, (char *)nodePtr, &implNodePtr); 01824 if (msbLsb == 1) { 01825 Ntk_NodeSetMddId(nodePtr, i); 01826 Ntk_NodeSetMddId(implNodePtr, i); 01827 } else { 01828 Ntk_NodeSetMddId(nodePtr, numOutputs - i); 01829 Ntk_NodeSetMddId(implNodePtr, numOutputs - i); 01830 } 01831 } 01832 01833 01834 /* Set the cpu usage lap */ 01835 lap = util_cpu_time(); 01836 01837 if (verbose >= 1) { 01838 fprintf(vis_stdout, "Specification being built\n"); 01839 } 01840 /* the actual composition of the spec. network into the residue ADD 01841 * is done here. The composed ADD return is referenced 01842 */ 01843 specADD = ComposeLayersIntoResidue(specNetwork, specLayerArray, residueDd, outputArray); 01844 if (specADD == NIL(bdd_node)) { 01845 error_append("Composition of spec. failed.\n"); 01846 /* Clean up before you leave */ 01847 array_free(implOutputArray); 01848 FREE(primeTable); 01849 bdd_recursive_deref(ddManager, residueDd); 01850 return 1; /* error return */ 01851 } 01852 01853 /* Store the information in the result structure of the spec.*/ 01854 bdd_ref(specADD); 01855 fnMddT = bdd_construct_bdd_t(ddManager, specADD); 01856 specSize = bdd_size(fnMddT); 01857 bdd_free(fnMddT); 01858 ResResidueInfoSetPerPrimeInfo(resultSpec, primeIndex, currentPrime, 01859 (util_cpu_time() - lap)/1000.0, specSize, specADD); 01860 /* Print info regarding this prime if pertinent */ 01861 if (verbose >=3) { 01862 (void) fprintf(vis_stdout, "%.2f (secs) spent in composing prime\n", 01863 ResResidueInfoReadPerPrimeInfo(resultSpec, primeIndex)->cpuTime); 01864 (void) fprintf(vis_stdout, "Composed Dd with %d nodes\n", specSize); 01865 } 01866 01867 /* Set the cpu usage lap */ 01868 lap = util_cpu_time(); 01869 01870 /* 01871 * the actual composition of the impl. network into the residue ADD 01872 * is done here. The composed ADD return is referenced 01873 */ 01874 if (verbose >= 1) { 01875 fprintf(vis_stdout, "Implementation being built\n"); 01876 } 01877 implADD = ComposeLayersIntoResidue(implNetwork, implLayerArray, residueDd, implOutputArray); 01878 01879 bdd_recursive_deref(ddManager, residueDd); 01880 if (implADD == NIL(bdd_node)) { 01881 error_append("Composition of spec. failed.\n"); 01882 /* Clean up before you leave */ 01883 bdd_recursive_deref(ddManager, specADD); 01884 array_free(implOutputArray); 01885 FREE(primeTable); 01886 return 1; /* error return */ 01887 } 01888 01889 /* Create a permutation array for the specMddId and implMddId input nodes */ 01890 permut = ALLOC(int, bdd_num_vars(ddManager)); 01891 for (i= 0; (unsigned) i < bdd_num_vars(ddManager); i++) { 01892 permut[i] = i; 01893 } 01894 st_foreach_item(inputMatch, stGen, &key, &value) { 01895 nodePtr = (Ntk_Node_t *)key; 01896 implNodePtr = (Ntk_Node_t *)value; 01897 if ((nodePtr == NIL(Ntk_Node_t)) || (implNodePtr == NIL(Ntk_Node_t))){ 01898 error_append("Input match values do not return"); 01899 error_append("valid node pointers.\n"); 01900 /* Clean up */ 01901 FREE(permut); 01902 FREE(primeTable); 01903 array_free(implOutputArray); 01904 bdd_recursive_deref(ddManager, specADD); 01905 bdd_recursive_deref(ddManager, implADD); 01906 st_free_gen(stGen); 01907 return 1; 01908 } 01909 /* create the array with the impl. vars to be composed with spec. vars. */ 01910 specMddId = Ntk_NodeReadMddId(nodePtr); 01911 implMddId = Ntk_NodeReadMddId(implNodePtr); 01912 01913 /* there should be no node with NTK_UNASSIGNED_MDD_ID due to the 01914 * ordering above 01915 */ 01916 01917 #if 0 01918 if (Ntk_NodeReadNumFanouts(nodePtr) != 0) { 01919 assert(specMddId != NTK_UNASSIGNED_MDD_ID); 01920 } 01921 if (Ntk_NodeReadNumFanouts(implNodePtr) != 0) { 01922 assert(implMddId != NTK_UNASSIGNED_MDD_ID); 01923 } 01924 #endif 01925 01926 if ((specMddId != NTK_UNASSIGNED_MDD_ID) && 01927 (implMddId != NTK_UNASSIGNED_MDD_ID)) { 01928 permut[implMddId] = specMddId; 01929 } else { 01930 assert(specMddId == implMddId); 01931 } 01932 01933 } /* end of st_foreach_item */ 01934 01935 /* permute the variables so that the impl variables are replaced by 01936 * spec. variables 01937 */ 01938 bdd_ref(tmpDd = bdd_add_permute(ddManager, implADD, permut)); 01939 bdd_recursive_deref(ddManager, implADD); 01940 FREE(permut); 01941 implADD = tmpDd; 01942 if(implADD == NIL(bdd_node)) { /* error */ 01943 error_append("Last composition failed,"); 01944 error_append("Cannot compose spec. ADD PI vars into Impl. ADD.\n"); 01945 FREE(primeTable); 01946 array_free(implOutputArray); 01947 return 1; /* error return */ 01948 } 01949 01950 if (verbose > 0) { 01951 (void) fprintf(vis_stdout, "%.2f (secs) spent in residue verification.\n", 01952 (util_cpu_time() - overallLap)/1000.0); 01953 } 01954 01955 /* Store the information in the result structure of the impl.*/ 01956 bdd_ref(implADD); 01957 fnMddT = bdd_construct_bdd_t(ddManager, implADD); 01958 implSize = bdd_size(fnMddT); 01959 bdd_free(fnMddT); 01960 ResResidueInfoSetPerPrimeInfo(resultImpl, primeIndex, currentPrime, 01961 (util_cpu_time() - lap)/1000.0, implSize, implADD); 01962 /* Print info regarding this prime if pertinent */ 01963 if (verbose >=3) { 01964 (void) fprintf(vis_stdout, "%.2f (secs) spent in composing prime\n", 01965 ResResidueInfoReadPerPrimeInfo(resultImpl, primeIndex)->cpuTime); 01966 (void) fprintf(vis_stdout, "Composed Dd with %d nodes\n", implSize); 01967 } 01968 01969 01970 /* Compare the Spec and the Impl composed Dds */ 01971 if (ResResidueInfoReadPerPrimeInfo(resultSpec, primeIndex)->residueDd != 01972 ResResidueInfoReadPerPrimeInfo(resultImpl, primeIndex)->residueDd) { 01973 ResResidueInfoSetSuccess(resultSpec, RES_FAIL); 01974 ResResidueInfoSetSuccess(resultImpl, RES_FAIL); 01975 (void) fprintf(vis_stdout, "Verification of %s and %s failed.\n", 01976 Res_ResidueInfoReadName(resultSpec), 01977 Res_ResidueInfoReadName(resultImpl)); 01978 (void)fprintf(vis_stdout,"The composed ADDs with residue are not the same.\n"); 01979 (void)fprintf(vis_stdout,"Verification failed at prime %d.\n", currentPrime); 01980 if (verbose >= 2) { 01981 (void)fprintf(vis_stdout, "Vector where the two networks differ :\n"); 01982 (void)fprintf(vis_stdout, "Specification Input Names :\n"); 01983 ExtractACubeOfDifference(ddManager, specNetwork, specADD, implADD); 01984 } 01985 01986 /* Clean up before you leave */ 01987 bdd_recursive_deref(ddManager, ResResidueInfoReadPerPrimeInfo(resultSpec, primeIndex)->residueDd); 01988 ResResidueInfoSetPerPrimeDd(resultSpec, primeIndex, NIL(bdd_node)); 01989 01990 bdd_recursive_deref(ddManager, ResResidueInfoReadPerPrimeInfo(resultImpl, primeIndex)->residueDd); 01991 ResResidueInfoSetPerPrimeDd(resultImpl, primeIndex, NIL(bdd_node)); 01992 array_free(implOutputArray); 01993 FREE(primeTable); 01994 return 0; 01995 } else { 01996 01997 /* free the result Dd*/ 01998 bdd_recursive_deref(ddManager, ResResidueInfoReadPerPrimeInfo(resultSpec, primeIndex)->residueDd); 01999 ResResidueInfoSetPerPrimeDd(resultSpec, primeIndex, NIL(bdd_node)); 02000 02001 bdd_recursive_deref(ddManager, ResResidueInfoReadPerPrimeInfo(resultImpl, primeIndex)->residueDd); 02002 ResResidueInfoSetPerPrimeDd(resultImpl, primeIndex, NIL(bdd_node)); 02003 } 02004 02005 02006 /* reset node Ids of primary inputs */ 02007 Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) { 02008 Ntk_NodeSetMddId(nodePtr, unassignedValue); 02009 } 02010 Ntk_NetworkForEachCombInput(implNetwork, listGen, nodePtr) { 02011 Ntk_NodeSetMddId(nodePtr, unassignedValue); 02012 } 02013 02014 02015 } /* End of the main for-loop */ 02016 FREE(primeTable); 02017 array_free(implOutputArray); 02018 02019 /* restore old dynamic reordering values */ 02020 bdd_dynamic_reordering(ddManager, oldDynMethod, BDD_REORDER_VERBOSITY_DEFAULT); 02021 if (!dynStatus) { 02022 bdd_dynamic_reordering_disable(ddManager); 02023 } 02024 02025 /* set pass flag if residue verification success and direct verification 02026 * success. 02027 */ 02028 if (((numDirectVerify) && 02029 (ResResidueInfoReadDirectVerificationSuccess(resultSpec) == RES_PASS)) || 02030 (ResResidueInfoReadDirectVerificationSuccess(resultSpec) != RES_FAIL)) { 02031 ResResidueInfoSetSuccess(resultSpec, RES_PASS); 02032 } 02033 if (((numDirectVerify) && 02034 (ResResidueInfoReadDirectVerificationSuccess(resultImpl) == RES_PASS)) || 02035 (ResResidueInfoReadDirectVerificationSuccess(resultImpl) != RES_FAIL)) { 02036 ResResidueInfoSetSuccess(resultImpl, RES_PASS); 02037 } 02038 return 0; 02039 } /* End of ResidueVerification */ 02040 02053 static void 02054 ExtractACubeOfDifference(bdd_manager *mgr, 02055 Ntk_Network_t *specNetwork, 02056 bdd_node *fn1, 02057 bdd_node *fn2) 02058 { 02059 bdd_t *fnMddT, *fnMddT1; /* mdd_t structure to calculate sizes */ 02060 bdd_t *fnMddT2, *fnMddT3; /* mdd_t structure to calculate sizes */ 02061 bdd_gen *gen; 02062 array_t *cube, *namesArray; 02063 lsGen listGen; 02064 int i, literal; 02065 Ntk_Node_t *nodePtr; 02066 02067 /* make bdd_ts of the two functions */ 02068 bdd_ref(fn2); 02069 fnMddT = bdd_construct_bdd_t(mgr, fn2); 02070 bdd_ref(fn1); 02071 fnMddT1 = bdd_construct_bdd_t(mgr, fn1); 02072 fnMddT2 = bdd_not(fnMddT1); 02073 /* extracts some cubes in the intersection of fn1' and fn2 */ 02074 fnMddT3 = bdd_intersects(fnMddT, fnMddT2); 02075 /* check not zero */ 02076 if (bdd_is_tautology(fnMddT3, 0)) { 02077 bdd_free(fnMddT3); 02078 bdd_free(fnMddT2); 02079 /* extracts some cubes in the intersection of fn2' and fn1 */ 02080 fnMddT2 = bdd_not(fnMddT); 02081 fnMddT3 = bdd_intersects(fnMddT1, fnMddT2); 02082 } 02083 assert(!bdd_is_tautology(fnMddT3, 0)); 02084 bdd_free(fnMddT); 02085 bdd_free(fnMddT1); 02086 bdd_free(fnMddT2); 02087 02088 /* pick a cube from the xor of fn1 and fn2 */ 02089 gen = bdd_first_cube(fnMddT3, &cube); 02090 bdd_free(fnMddT3); 02091 02092 /* store the names to be printed out later */ 02093 namesArray = array_alloc(char *, array_n(cube)); 02094 Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) { 02095 array_insert(char *, namesArray , Ntk_NodeReadMddId(nodePtr), Ntk_NodeReadName(nodePtr)); 02096 } 02097 02098 /* print out the cube */ 02099 arrayForEachItem(int, cube, i, literal) { 02100 if (literal != 2) { 02101 (void) fprintf(vis_stdout, "%s ", array_fetch(char *, namesArray, i)); 02102 } 02103 } 02104 fprintf(vis_stdout, "\n"); 02105 arrayForEachItem(int, cube, i, literal) { 02106 if (literal != 2) { 02107 (void) fprintf(vis_stdout, "%1d", literal); 02108 } 02109 } 02110 fprintf(vis_stdout, "\n"); 02111 array_free(namesArray); 02112 bdd_gen_free(gen); 02113 return; 02114 }