VIS
|
00001 00036 #include "eqvInt.h" 00037 00038 static char rcsid[] UNUSED = "$Id: eqvCmd.c,v 1.20 2009/04/11 18:26:04 fabio Exp $"; 00039 00040 /*---------------------------------------------------------------------------*/ 00041 /* Variable declarations */ 00042 /*---------------------------------------------------------------------------*/ 00043 static jmp_buf timeOutEnv; 00044 00045 00048 /*---------------------------------------------------------------------------*/ 00049 /* Static function prototypes */ 00050 /*---------------------------------------------------------------------------*/ 00051 00052 static int CommandCombEquivalence(Hrc_Manager_t **hmgr, int argc, char **argv); 00053 static int CommandSeqEquivalence(Hrc_Manager_t **hmgr, int argc, char **argv); 00054 static void TimeOutHandle(void); 00055 00059 /*---------------------------------------------------------------------------*/ 00060 /* Definition of exported functions */ 00061 /*---------------------------------------------------------------------------*/ 00062 00072 void 00073 Eqv_Init(void) 00074 { 00075 Cmd_CommandAdd("comb_verify", CommandCombEquivalence, 0); 00076 Cmd_CommandAdd("seq_verify", CommandSeqEquivalence, 0); 00077 } 00078 00088 void 00089 Eqv_End(void) 00090 { 00091 } 00092 00093 /*---------------------------------------------------------------------------*/ 00094 /* Definition of internal functions */ 00095 /*---------------------------------------------------------------------------*/ 00096 00097 /*---------------------------------------------------------------------------*/ 00098 /* Definition of static functions */ 00099 /*---------------------------------------------------------------------------*/ 00100 00224 static int 00225 CommandCombEquivalence( 00226 Hrc_Manager_t **hmgr, 00227 int argc, 00228 char **argv) 00229 { 00230 static int timeOutPeriod; 00231 static Hrc_Manager_t *hmgr1; 00232 static Hrc_Manager_t *hmgr2; 00233 static Ntk_Network_t *network1; 00234 static Ntk_Network_t *network2; 00235 int c; 00236 int check; 00237 FILE *fp; 00238 FILE *inputFile = NIL(FILE); 00239 char *fileName1; 00240 char *fileName2; 00241 char *name1; 00242 char *name2; 00243 st_generator *gen; 00244 static Part_PartitionMethod partMethod1; 00245 static Part_PartitionMethod partMethod2; 00246 static OFT AssignCommonOrder; 00247 static st_table *inputMap; 00248 static st_table *outputMap; 00249 st_table *rootsTable = NIL(st_table); 00250 st_table *leavesTable = NIL(st_table); 00251 boolean fileFlag = FALSE; 00252 boolean equivalent; 00253 boolean printBddInfo = FALSE; 00254 static boolean execMode; /* FALSE: verify against current network, 00255 TRUE: verify the two given networks */ 00256 boolean isBlif = FALSE; 00257 00258 /* 00259 * These are the default values. These variables must be declared static 00260 * to avoid lint warnings. Since they are static, we must reinitialize 00261 * them outside of the variable declarations. 00262 */ 00263 timeOutPeriod = 0; 00264 hmgr1 = NIL(Hrc_Manager_t); 00265 hmgr2 = NIL(Hrc_Manager_t); 00266 partMethod1 = Part_Default_c; 00267 partMethod2 = Part_Default_c; 00268 AssignCommonOrder = DefaultCommonOrder; 00269 inputMap = NIL(st_table); 00270 outputMap = NIL(st_table); 00271 00272 error_init(); 00273 util_getopt_reset(); 00274 while((c = util_getopt(argc, argv, "bf:o:1:2:ht:i")) != EOF) { 00275 switch(c) { 00276 case 'b': 00277 isBlif = TRUE; 00278 break; 00279 case 'f': 00280 if((inputFile = Cmd_FileOpen(util_optarg, "r", NIL(char *), 1)) == 00281 NIL(FILE)) { 00282 (void) fprintf(vis_stderr, "** eqv error: File %s not found.\n", util_optarg); 00283 goto usage; 00284 } 00285 fileFlag = 1; 00286 break; 00287 case 'o': 00288 /* The following line causes a seg fault, because 00289 FindOrderingMethod() always returns NULL, and currently 00290 only DefaultCommonOrder is used. 00291 AssignCommonOrder = FindOrderingMethod(); 00292 */ 00293 /* The programmer supplies and modifies this function if any new 00294 ordering method is introduced. FindOrderingMethod() should return 00295 the type OFT. */ 00296 break; 00297 case 't': 00298 timeOutPeriod = atoi(util_optarg); 00299 break; 00300 case '1': 00301 if(!strcmp(util_optarg, "total")) { 00302 partMethod1 = Part_Total_c; 00303 } 00304 else 00305 if(!strcmp(util_optarg, "partial")) { 00306 partMethod1 = Part_Partial_c; 00307 } 00308 else 00309 if(!strcmp(util_optarg, "inout")) { 00310 partMethod1 = Part_InOut_c; 00311 } 00312 else { 00313 (void) fprintf(vis_stderr, "** eqv error: Unknown partition method 1\n"); 00314 goto usage; 00315 } 00316 break; 00317 case '2': 00318 if(!strcmp(util_optarg, "total")) { 00319 partMethod2 = Part_Total_c; 00320 } 00321 else 00322 if(!strcmp(util_optarg, "partial")) { 00323 partMethod2 = Part_Partial_c; 00324 } 00325 else 00326 if(!strcmp(util_optarg, "inout")) { 00327 partMethod2 = Part_InOut_c; 00328 } 00329 else { 00330 (void) fprintf(vis_stderr, "** eqv error: Unknown partition method 2\n"); 00331 goto usage; 00332 } 00333 break; 00334 case 'i': 00335 printBddInfo = TRUE; 00336 break; 00337 case 'h': 00338 goto usage; 00339 default : 00340 goto usage; 00341 } 00342 } 00343 if(argc == 1) { 00344 goto usage; 00345 } 00346 00347 if(argc == util_optind+1) { 00348 execMode = FALSE; 00349 } 00350 else 00351 if(argc == util_optind+2) { 00352 execMode = TRUE; 00353 } 00354 else { 00355 error_append("** eqv error: Improper number of arguments.\n"); 00356 (void) fprintf(vis_stderr, "%s", error_string()); 00357 goto usage; 00358 } 00359 if(execMode == FALSE) { 00360 hmgr1 = *hmgr; 00361 if(Hrc_ManagerReadCurrentNode(hmgr1) == NIL(Hrc_Node_t)) { 00362 (void) fprintf(vis_stderr, "** eqv error: The hierarchy manager is empty. Read in design.\n"); 00363 return 1; 00364 } 00365 network1 = (Ntk_Network_t *) Hrc_NodeReadApplInfo( 00366 Hrc_ManagerReadCurrentNode(hmgr1), NTK_HRC_NODE_APPL_KEY); 00367 if(network1 == NIL(Ntk_Network_t)) { 00368 (void) fprintf(vis_stderr, "** eqv error: There is no network. Use flatten_hierarchy.\n"); 00369 return 1; 00370 } 00371 if(Ntk_NetworkReadApplInfo(network1, PART_NETWORK_APPL_KEY) == NIL(void)) { 00372 (void) fprintf(vis_stderr, "** eqv error: Network has not been partitioned. Use build_partition_mdds.\n"); 00373 return 1; 00374 } 00375 fileName2 = argv[util_optind]; 00376 if(isBlif) { 00377 if((hmgr2 = Io_BlifRead(fileName2, FALSE)) == NIL(Hrc_Manager_t)) { 00378 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName2); 00379 goto usage; 00380 } 00381 } 00382 else { 00383 if((fp = Cmd_FileOpen(fileName2, "r", NIL(char *), 1)) == NIL(FILE)) { 00384 (void) fprintf(vis_stderr, "** eqv error: File %s not found\n", fileName2); 00385 return 1; 00386 } 00387 hmgr2 = Io_BlifMvRead(fp, NIL(Hrc_Manager_t), FALSE, FALSE, FALSE); 00388 fclose(fp); 00389 if(hmgr2 == NIL(Hrc_Manager_t)) { 00390 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName2); 00391 return 1; 00392 } 00393 } 00394 network2 = Ntk_HrcNodeConvertToNetwork(Hrc_ManagerReadCurrentNode(hmgr2), 00395 TRUE, (lsList) NULL); 00396 if(network2 == NIL(Ntk_Network_t)) { 00397 Hrc_ManagerFree(hmgr2); 00398 (void) fprintf(vis_stderr, "** eqv error: Error in network2.\n"); 00399 return 1; 00400 } 00401 00402 } 00403 else { 00404 fileName1 = argv[util_optind]; 00405 fileName2 = argv[util_optind+1]; 00406 if(isBlif) { 00407 if((hmgr1 = Io_BlifRead(fileName1, FALSE)) == NIL(Hrc_Manager_t)) { 00408 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName1); 00409 return 1; 00410 } 00411 if((hmgr2 = Io_BlifRead(fileName2, FALSE)) == NIL(Hrc_Manager_t)) { 00412 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName2); 00413 if(hmgr1) { 00414 Hrc_ManagerFree(hmgr1); 00415 } 00416 return 1; 00417 } 00418 } 00419 else { 00420 if((fp = Cmd_FileOpen(fileName1, "r", NIL(char *), 1)) == NIL(FILE)) { 00421 (void) fprintf(vis_stderr, "** eqv error: File %s not found\n", fileName1); 00422 return 1; 00423 } 00424 hmgr1 = Io_BlifMvRead(fp, NIL(Hrc_Manager_t), FALSE, FALSE, FALSE); 00425 fclose(fp); 00426 if(hmgr1 == NIL(Hrc_Manager_t)) { 00427 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName1); 00428 goto usage; 00429 } 00430 if((fp = Cmd_FileOpen(fileName2, "r", NIL(char *), 1)) == NIL(FILE)) { 00431 (void) fprintf(vis_stderr, "** eqv error: File %s not found\n", fileName2); 00432 if(hmgr1) { 00433 Hrc_ManagerFree(hmgr1); 00434 } 00435 return 1; 00436 } 00437 hmgr2 = Io_BlifMvRead(fp, NIL(Hrc_Manager_t), FALSE, FALSE, FALSE); 00438 fclose(fp); 00439 if(hmgr2 == NIL(Hrc_Manager_t)) { 00440 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName2); 00441 if(hmgr1) { 00442 Hrc_ManagerFree(hmgr1); 00443 } 00444 return 1; 00445 } 00446 } 00447 network1 = Ntk_HrcNodeConvertToNetwork(Hrc_ManagerReadCurrentNode(hmgr1), 00448 TRUE, (lsList) NULL); 00449 network2 = Ntk_HrcNodeConvertToNetwork(Hrc_ManagerReadCurrentNode(hmgr2), 00450 TRUE, (lsList) NULL); 00451 00452 if((network1 == NIL(Ntk_Network_t)) || (network2 == NIL(Ntk_Network_t))) { 00453 if(network1 == NIL(Ntk_Network_t)) { 00454 (void) fprintf(vis_stderr, "** eqv error: Error in network1.\n"); 00455 } 00456 if(network2 == NIL(Ntk_Network_t)) { 00457 (void) fprintf(vis_stderr, "** eqv error: Error in network2.\n"); 00458 } 00459 Hrc_ManagerFree(hmgr1); 00460 Hrc_ManagerFree(hmgr2); 00461 return 1; 00462 } 00463 if((network1 == NIL(Ntk_Network_t)) || (network2 == NIL(Ntk_Network_t))) { 00464 if(network1 == NIL(Ntk_Network_t)) { 00465 (void) fprintf(vis_stderr, "** eqv error: Error in network1.\n"); 00466 } 00467 if(network2 == NIL(Ntk_Network_t)) { 00468 (void) fprintf(vis_stderr, "** eqv error: Error in network2.\n"); 00469 } 00470 Hrc_ManagerFree(hmgr1); 00471 Hrc_ManagerFree(hmgr2); 00472 return 1; 00473 } 00474 } 00475 00476 if(Ntk_NetworkReadNumCombInputs(network1) != 00477 Ntk_NetworkReadNumCombInputs(network2)) { 00478 error_append("** eqv error: Different number of inputs in the two networks.\n"); 00479 if(!fileFlag) { 00480 if(execMode) { 00481 Hrc_ManagerFree(hmgr1); 00482 Ntk_NetworkFree(network1); 00483 } 00484 Hrc_ManagerFree(hmgr2); 00485 Ntk_NetworkFree(network2); 00486 (void) fprintf(vis_stderr, "%s", error_string()); 00487 return 1; 00488 } 00489 } 00490 00491 if(fileFlag) { 00492 rootsTable = st_init_table(strcmp, st_strhash); 00493 leavesTable = st_init_table(strcmp, st_strhash); 00494 check = ReadRootLeafMap(inputFile, rootsTable, leavesTable); 00495 fclose(inputFile); 00496 switch (check) { 00497 case 0 : /* error */ 00498 st_free_table(rootsTable); 00499 st_free_table(leavesTable); 00500 (void) fprintf(vis_stderr, "** eqv error: No data in the input file.\n"); 00501 if(execMode) { 00502 Hrc_ManagerFree(hmgr1); 00503 Ntk_NetworkFree(network1); 00504 } 00505 Hrc_ManagerFree(hmgr2); 00506 Ntk_NetworkFree(network2); 00507 return 1; 00508 case 1 : /* leaves only */ 00509 st_free_table(rootsTable); 00510 inputMap = MapNamesToNodes(network1, network2, leavesTable); 00511 st_foreach_item(leavesTable, gen, &name1, &name2) { 00512 FREE(name1); 00513 FREE(name2); 00514 } 00515 st_free_table(leavesTable); 00516 if(inputMap == NIL(st_table)) { 00517 (void) fprintf(vis_stderr, "%s", error_string()); 00518 if(execMode) { 00519 Hrc_ManagerFree(hmgr1); 00520 Ntk_NetworkFree(network1); 00521 } 00522 Hrc_ManagerFree(hmgr2); 00523 Ntk_NetworkFree(network2); 00524 return 1; 00525 } 00526 if((outputMap = MapCombOutputsByName(network1, network2)) == 00527 NIL(st_table)) { 00528 st_free_table(inputMap); 00529 if(execMode) { 00530 Hrc_ManagerFree(hmgr1); 00531 Ntk_NetworkFree(network1); 00532 } 00533 Hrc_ManagerFree(hmgr2); 00534 Ntk_NetworkFree(network2); 00535 (void) fprintf(vis_stderr, "%s", error_string()); 00536 return 1; 00537 } 00538 if(!TestRootsAndLeavesAreValid(network1, network2, inputMap, 00539 outputMap)){ 00540 st_free_table(inputMap); 00541 st_free_table(outputMap); 00542 if(execMode) { 00543 Hrc_ManagerFree(hmgr1); 00544 Ntk_NetworkFree(network1); 00545 } 00546 Hrc_ManagerFree(hmgr2); 00547 Ntk_NetworkFree(network2); 00548 (void) fprintf(vis_stderr, "%s", error_string()); 00549 return 1; 00550 } 00551 break; 00552 case 2 : /* roots only */ 00553 st_free_table(leavesTable); 00554 outputMap = MapNamesToNodes(network1, network2, rootsTable); 00555 st_foreach_item(rootsTable, gen, &name1, &name2) { 00556 FREE(name1); 00557 FREE(name2); 00558 } 00559 st_free_table(rootsTable); 00560 if(outputMap ==NIL(st_table)) { 00561 (void) fprintf(vis_stderr, "%s", error_string()); 00562 if(execMode) { 00563 Hrc_ManagerFree(hmgr1); 00564 Ntk_NetworkFree(network1); 00565 } 00566 Hrc_ManagerFree(hmgr2); 00567 Ntk_NetworkFree(network2); 00568 return 1; 00569 } 00570 if((inputMap = MapCombInputsByName(network1, network2)) == 00571 NIL(st_table)) { 00572 st_free_table(outputMap); 00573 if(execMode) { 00574 Hrc_ManagerFree(hmgr1); 00575 Ntk_NetworkFree(network1); 00576 } 00577 Hrc_ManagerFree(hmgr2); 00578 Ntk_NetworkFree(network2); 00579 (void) fprintf(vis_stderr, "%s", error_string()); 00580 return 1; 00581 } 00582 if(!TestRootsAndLeavesAreValid(network1, network2, inputMap, 00583 outputMap)){ 00584 st_free_table(inputMap); 00585 st_free_table(outputMap); 00586 if(execMode) { 00587 Hrc_ManagerFree(hmgr1); 00588 Ntk_NetworkFree(network1); 00589 } 00590 Hrc_ManagerFree(hmgr2); 00591 Ntk_NetworkFree(network2); 00592 return 1; 00593 } 00594 break; 00595 case 3 : /* both leaves and roots */ 00596 inputMap = MapNamesToNodes(network1, network2, leavesTable); 00597 st_foreach_item(leavesTable, gen, &name1, &name2) { 00598 FREE(name1); 00599 FREE(name2); 00600 } 00601 st_free_table(leavesTable); 00602 outputMap = MapNamesToNodes(network1, network2, rootsTable); 00603 st_foreach_item(rootsTable, gen, &name1, &name2) { 00604 FREE(name1); 00605 FREE(name2); 00606 } 00607 st_free_table(rootsTable); 00608 if((inputMap == NIL(st_table)) || (outputMap == NIL(st_table))) { 00609 (void) fprintf(vis_stderr, "%s", error_string()); 00610 if(inputMap) { 00611 st_free_table(inputMap); 00612 } 00613 if(outputMap) { 00614 st_free_table(outputMap); 00615 } 00616 if(execMode) { 00617 Hrc_ManagerFree(hmgr1); 00618 Ntk_NetworkFree(network1); 00619 } 00620 Hrc_ManagerFree(hmgr2); 00621 Ntk_NetworkFree(network2); 00622 return 1; 00623 } 00624 if(!TestRootsAndLeavesAreValid(network1, network2, inputMap, 00625 outputMap)){ 00626 st_free_table(inputMap); 00627 st_free_table(outputMap); 00628 if(execMode) { 00629 Hrc_ManagerFree(hmgr1); 00630 Ntk_NetworkFree(network1); 00631 } 00632 Hrc_ManagerFree(hmgr2); 00633 Ntk_NetworkFree(network2); 00634 (void) fprintf(vis_stderr, "%s", error_string()); 00635 return 1; 00636 } 00637 break; 00638 } 00639 } 00640 else { 00641 inputMap = MapCombInputsByName(network1, network2); 00642 outputMap = MapCombOutputsByName(network1, network2); 00643 if((inputMap == NIL(st_table)) || (outputMap == NIL(st_table))) { 00644 if(inputMap) { 00645 st_free_table(inputMap); 00646 } 00647 if(outputMap) { 00648 st_free_table(outputMap); 00649 } 00650 if(execMode) { 00651 Hrc_ManagerFree(hmgr1); 00652 Ntk_NetworkFree(network1); 00653 } 00654 Hrc_ManagerFree(hmgr2); 00655 Ntk_NetworkFree(network2); 00656 (void) fprintf(vis_stderr, "%s", error_string()); 00657 return 1; 00658 } 00659 } 00660 00661 /* Start the timer before calling the equivalence checker. */ 00662 if (timeOutPeriod > 0){ 00663 (void) signal(SIGALRM, (void(*)(int))TimeOutHandle); 00664 (void) alarm(timeOutPeriod); 00665 if (setjmp(timeOutEnv) > 0) { 00666 (void) fprintf(vis_stderr, "Timeout occurred after %d seconds.\n", timeOutPeriod); 00667 alarm(0); 00668 return 1; 00669 } 00670 } 00671 00672 equivalent = Eqv_NetworkVerifyCombinationalEquivalence(network1, network2, 00673 inputMap, outputMap, 00674 AssignCommonOrder, 00675 partMethod1, 00676 partMethod2); 00677 00678 if(equivalent) { 00679 (void) fprintf(vis_stdout, "Networks are combinationally equivalent.\n\n"); 00680 } 00681 else { 00682 (void) fprintf(vis_stdout, "%s", error_string()); 00683 (void) fprintf(vis_stdout, "Networks are NOT combinationally equivalent.\n\n"); 00684 } 00685 00686 if (printBddInfo) { 00687 bdd_print_stats(Ntk_NetworkReadMddManager(network1), vis_stdout); 00688 } 00689 00690 st_free_table(inputMap); 00691 st_free_table(outputMap); 00692 if(execMode) { 00693 Hrc_ManagerFree(hmgr1); 00694 Ntk_NetworkFree(network1); 00695 } 00696 Hrc_ManagerFree(hmgr2); 00697 Ntk_NetworkFree(network2); 00698 00699 alarm(0); 00700 return 0; /* normal exit */ 00701 00702 usage: 00703 (void) fprintf(vis_stderr, "usage: comb_verify [-b] [-f filename] [-h] [-o ordering method] [-t time]\n"); 00704 (void) fprintf(vis_stderr, " [-1 partMethod1] [-2 partMethod2] [-i] file1 [file2]\n"); 00705 (void) fprintf(vis_stderr, " -b input files are BLIF\n"); 00706 (void) fprintf(vis_stderr, " -f file variable name correspondence file\n"); 00707 (void) fprintf(vis_stderr, " -h print the command usage\n"); 00708 (void) fprintf(vis_stderr, " -o method variable ordering method\n"); 00709 (void) fprintf(vis_stderr, " -t time time out period (in seconds)\n"); 00710 (void) fprintf(vis_stderr, " -1 method partitioning method for network1\n"); 00711 (void) fprintf(vis_stderr, " -2 method partitioning method for network2\n"); 00712 (void) fprintf(vis_stderr, " -i print Bdd statistics\n"); 00713 return 1; /* error exit */ 00714 } 00715 00819 static int 00820 CommandSeqEquivalence( 00821 Hrc_Manager_t **hmgr, 00822 int argc, 00823 char **argv) 00824 { 00825 static int timeOutPeriod; 00826 static Hrc_Manager_t *hmgr1; 00827 static Hrc_Manager_t *hmgr2; 00828 static Ntk_Network_t *network1; 00829 static Ntk_Network_t *network2; 00830 int c; 00831 int check; 00832 FILE *fp; 00833 static FILE *inputFile; 00834 char *fileName1; 00835 char *fileName2; 00836 char *name1; 00837 char *name2; 00838 st_generator *gen; 00839 static Part_PartitionMethod partMethod; 00840 st_table *outputMap = NIL(st_table); 00841 st_table *inputMap = NIL(st_table); 00842 st_table *rootsTable = NIL(st_table); 00843 st_table *leavesTable = NIL(st_table); 00844 static boolean fileFlag; 00845 static boolean execMode; /* FALSE: verify against the current network, 00846 TRUE: verify the two networks */ 00847 static boolean equivalent; 00848 boolean isBlif = FALSE; 00849 boolean printBddInfo = FALSE; 00850 static boolean useBackwardReach; 00851 boolean reordering = FALSE; 00852 00853 /* 00854 * These are the default values. These variables must be declared static 00855 * to avoid lint warnings. Since they are static, we must reinitialize 00856 * them outside of the variable declarations. 00857 */ 00858 timeOutPeriod = 0; 00859 hmgr1 = NIL(Hrc_Manager_t); 00860 hmgr2 = NIL(Hrc_Manager_t); 00861 inputFile = NIL(FILE); 00862 partMethod = Part_Default_c; 00863 fileFlag = FALSE; 00864 equivalent = FALSE; 00865 useBackwardReach = FALSE; 00866 00867 error_init(); 00868 util_getopt_reset(); 00869 while((c = util_getopt(argc, argv, "bBf:p:hFt:ir")) != EOF) { 00870 switch(c) { 00871 case 'b': 00872 isBlif = TRUE; 00873 break; 00874 case 'f': 00875 if((inputFile = Cmd_FileOpen(util_optarg, "r", NIL(char *), 1)) == 00876 NIL(FILE)) { 00877 (void) fprintf(vis_stderr, 00878 "** eqv error: File %s not found.\n", util_optarg); 00879 return 1; 00880 } 00881 fileFlag = 1; 00882 break; 00883 case 'p': 00884 if(!strcmp(util_optarg, "total")) { 00885 partMethod = Part_Total_c; 00886 } else { 00887 if(!strcmp(util_optarg, "partial")) { 00888 partMethod = Part_Partial_c; 00889 } else { 00890 if(!strcmp(util_optarg, "inout")) { 00891 partMethod = Part_InOut_c; 00892 } else { 00893 (void) fprintf(vis_stderr, 00894 "** eqv error: Unknown partition method\n"); 00895 goto usage; 00896 } 00897 } 00898 } 00899 break; 00900 case 't': 00901 timeOutPeriod = atoi(util_optarg); 00902 break; 00903 case 'B': 00904 useBackwardReach = TRUE; 00905 break; 00906 case 'h': 00907 goto usage; 00908 case 'i': 00909 printBddInfo = TRUE; 00910 break; 00911 case 'r': 00912 reordering = TRUE; 00913 break; 00914 default: 00915 goto usage; 00916 } 00917 } 00918 if(argc == 1) { 00919 goto usage; 00920 } 00921 if(argc == util_optind+1) { 00922 execMode = FALSE; 00923 } 00924 else 00925 if(argc == util_optind+2) { 00926 execMode = TRUE; 00927 } 00928 else { 00929 error_append("** eqv error: Improper number of arguments.\n"); 00930 (void) fprintf(vis_stderr, "%s", error_string()); 00931 goto usage; 00932 } 00933 if(execMode == FALSE) { 00934 hmgr1 = *hmgr; 00935 if(Hrc_ManagerReadCurrentNode(hmgr1) == NIL(Hrc_Node_t)) { 00936 (void) fprintf(vis_stderr, "** eqv error: The hierarchy manager is empty. Read in design.\n"); 00937 return 1; 00938 } 00939 network1 = (Ntk_Network_t *) Hrc_NodeReadApplInfo( 00940 Hrc_ManagerReadCurrentNode(hmgr1), NTK_HRC_NODE_APPL_KEY); 00941 if(network1 == NIL(Ntk_Network_t)) { 00942 (void) fprintf(vis_stderr, "** eqv error: There is no network. Use flatten_hierarchy.\n"); 00943 return 1; 00944 } 00945 if(!Ntk_NetworkReadNumLatches(network1)) { 00946 (void) fprintf(vis_stderr, "** eqv error: No latches present in the current network. Use comb_verify.\n"); 00947 return 1; 00948 } 00949 fileName2 = argv[util_optind]; 00950 if(isBlif) { 00951 if((hmgr2 = Io_BlifRead(fileName2, FALSE)) == NIL(Hrc_Manager_t)) { 00952 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName2); 00953 goto usage; 00954 } 00955 } 00956 else { 00957 if((fp = Cmd_FileOpen(fileName2, "r", NIL(char *), 1)) == NIL(FILE)) { 00958 (void) fprintf(vis_stderr, "** eqv error: File %s not found\n", fileName2); 00959 return 1; 00960 } 00961 hmgr2 = Io_BlifMvRead(fp, NIL(Hrc_Manager_t), FALSE, FALSE, FALSE); 00962 fclose(fp); 00963 if(hmgr2 == NIL(Hrc_Manager_t)) { 00964 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName2); 00965 return 1; 00966 } 00967 } 00968 network2 = Ntk_HrcNodeConvertToNetwork(Hrc_ManagerReadCurrentNode(hmgr2), 00969 TRUE, (lsList) NULL); 00970 if(network2 == NIL(Ntk_Network_t)) { 00971 Hrc_ManagerFree(hmgr2); 00972 (void) fprintf(vis_stderr, "** eqv error: Error in network2.\n"); 00973 return 1; 00974 } 00975 if(!Ntk_NetworkReadNumLatches(network2)) { 00976 (void) fprintf(vis_stderr, "** eqv error: No latches present in %s. Use comb_verify.\n", fileName2); 00977 Hrc_ManagerFree(hmgr2); 00978 Ntk_NetworkFree(network2); 00979 return 1; 00980 } 00981 } 00982 else { 00983 fileName1 = argv[util_optind]; 00984 fileName2 = argv[util_optind+1]; 00985 if(isBlif) { 00986 if((hmgr1 = Io_BlifRead(fileName1, FALSE)) == NIL(Hrc_Manager_t)) { 00987 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName1); 00988 return 1; 00989 } 00990 if((hmgr2 = Io_BlifRead(fileName2, FALSE)) == NIL(Hrc_Manager_t)) { 00991 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName2); 00992 if(hmgr1) { 00993 Hrc_ManagerFree(hmgr1); 00994 } 00995 return 1; 00996 } 00997 } 00998 else { 00999 if((fp = Cmd_FileOpen(fileName1, "r", NIL(char *), 1)) == NIL(FILE)) { 01000 (void) fprintf(vis_stderr, "** eqv error: File %s not found\n", fileName1); 01001 return 1; 01002 } 01003 hmgr1 = Io_BlifMvRead(fp, NIL(Hrc_Manager_t), FALSE, FALSE, FALSE); 01004 fclose(fp); 01005 if(hmgr1 == NIL(Hrc_Manager_t)) { 01006 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName1); 01007 goto usage; 01008 } 01009 if((fp = Cmd_FileOpen(fileName2, "r", NIL(char *), 1)) == NIL(FILE)) { 01010 (void) fprintf(vis_stderr, "** eqv error: File %s not found\n", fileName2); 01011 if(hmgr1) { 01012 Hrc_ManagerFree(hmgr1); 01013 } 01014 return 1; 01015 } 01016 hmgr2 = Io_BlifMvRead(fp, NIL(Hrc_Manager_t), FALSE, FALSE, FALSE); 01017 fclose(fp); 01018 if(hmgr2 == NIL(Hrc_Manager_t)) { 01019 (void) fprintf(vis_stderr, "** eqv error: Error in reading file %s\n", fileName2); 01020 if(hmgr1) { 01021 Hrc_ManagerFree(hmgr1); 01022 } 01023 return 1; 01024 } 01025 } 01026 network1 = Ntk_HrcNodeConvertToNetwork(Hrc_ManagerReadCurrentNode(hmgr1), 01027 TRUE, (lsList) NULL); 01028 network2 = Ntk_HrcNodeConvertToNetwork(Hrc_ManagerReadCurrentNode(hmgr2), 01029 TRUE, (lsList) NULL); 01030 if((network1 == NIL(Ntk_Network_t)) || (network2 == NIL(Ntk_Network_t))) { 01031 if(network1 == NIL(Ntk_Network_t)) { 01032 (void) fprintf(vis_stderr, "** eqv error: Error in network1.\n"); 01033 } 01034 if(network2 == NIL(Ntk_Network_t)) { 01035 (void) fprintf(vis_stderr, "** eqv error: Error in network2.\n"); 01036 } 01037 Hrc_ManagerFree(hmgr1); 01038 Hrc_ManagerFree(hmgr2); 01039 return 1; 01040 } 01041 01042 if(!Ntk_NetworkReadNumLatches(network1)) { 01043 (void) fprintf(vis_stderr, "** eqv error: No latches present in %s. Use comb_verify.\n", fileName1); 01044 Hrc_ManagerFree(hmgr1); 01045 Ntk_NetworkFree(network1); 01046 Hrc_ManagerFree(hmgr2); 01047 Ntk_NetworkFree(network2); 01048 return 1; 01049 } 01050 if(!Ntk_NetworkReadNumLatches(network2)) { 01051 (void) fprintf(vis_stderr, "** eqv error: No latches present in %s. Use comb_verify.\n", fileName2); 01052 Hrc_ManagerFree(hmgr1); 01053 Ntk_NetworkFree(network1); 01054 Hrc_ManagerFree(hmgr2); 01055 Ntk_NetworkFree(network2); 01056 return 1; 01057 } 01058 } 01059 if(Ntk_NetworkReadNumPrimaryInputs(network1) != 01060 Ntk_NetworkReadNumInputs(network1)) { 01061 error_append("** eqv error: Pseudo inputs present in network1. Unable to do verification.\n"); 01062 (void) fprintf(vis_stderr, "%s", error_string()); 01063 if(execMode) { 01064 Hrc_ManagerFree(hmgr1); 01065 Ntk_NetworkFree(network1); 01066 } 01067 Hrc_ManagerFree(hmgr2); 01068 Ntk_NetworkFree(network2); 01069 return 1; 01070 } 01071 if(Ntk_NetworkReadNumPrimaryInputs(network2) != 01072 Ntk_NetworkReadNumInputs(network2)) { 01073 error_append("** eqv error: Pseudo inputs present in network2. Unable to do verification.\n"); 01074 (void) fprintf(vis_stderr, "%s", error_string()); 01075 if(execMode) { 01076 Hrc_ManagerFree(hmgr1); 01077 Ntk_NetworkFree(network1); 01078 } 01079 Hrc_ManagerFree(hmgr2); 01080 Ntk_NetworkFree(network2); 01081 return 1; 01082 } 01083 if(Ntk_NetworkReadNumPrimaryInputs(network1) != 01084 Ntk_NetworkReadNumPrimaryInputs(network2)) { 01085 error_append("** eqv error: Different number of inputs in the two networks.\n"); 01086 (void) fprintf(vis_stderr, "%s", error_string()); 01087 if(execMode) { 01088 Hrc_ManagerFree(hmgr1); 01089 Ntk_NetworkFree(network1); 01090 } 01091 Hrc_ManagerFree(hmgr2); 01092 Ntk_NetworkFree(network2); 01093 return 1; 01094 } 01095 01096 /* Start the timer before calling the equivalence checker. */ 01097 if (timeOutPeriod > 0){ 01098 (void) signal(SIGALRM, (void(*)(int))TimeOutHandle); 01099 (void) alarm(timeOutPeriod); 01100 if (setjmp(timeOutEnv) > 0) { 01101 (void) fprintf(vis_stderr, "Timeout occurred after %d seconds.\n", 01102 timeOutPeriod); 01103 alarm(0); 01104 return 1; 01105 } 01106 } 01107 01108 if(fileFlag) { 01109 rootsTable = st_init_table(strcmp, st_strhash); 01110 leavesTable = st_init_table(strcmp, st_strhash); 01111 check = ReadRootLeafMap(inputFile, rootsTable, leavesTable); 01112 fclose(inputFile); 01113 if(check == 0) { 01114 st_free_table(rootsTable); 01115 st_free_table(leavesTable); 01116 (void) fprintf(vis_stderr, "** eqv error: No data in the input file\n"); 01117 alarm(0); 01118 return 1; 01119 } 01120 switch (check) { 01121 case 1 : 01122 st_free_table(rootsTable); 01123 outputMap = MapPrimaryOutputsByName(network1, network2); 01124 if((outputMap == NIL(st_table)) || !TestLeavesAreValid(network1, 01125 network2, 01126 leavesTable)) { 01127 st_foreach_item(leavesTable, gen, &name1, &name2) { 01128 FREE(name1); 01129 FREE(name2); 01130 } 01131 st_free_table(leavesTable); 01132 if(outputMap) { 01133 st_free_table(outputMap); 01134 } 01135 (void) fprintf(vis_stderr, "%s", error_string()); 01136 if(execMode) { 01137 Hrc_ManagerFree(hmgr1); 01138 Ntk_NetworkFree(network1); 01139 } 01140 Hrc_ManagerFree(hmgr2); 01141 Ntk_NetworkFree(network2); 01142 (void) fprintf(vis_stderr, "%s", error_string()); 01143 alarm(0); 01144 return 1; 01145 } 01146 equivalent = Eqv_NetworkVerifySequentialEquivalence(network1, 01147 network2, 01148 NIL(st_table), 01149 leavesTable, 01150 partMethod, 01151 useBackwardReach, 01152 reordering); 01153 st_foreach_item(leavesTable, gen, &name1, &name2) { 01154 FREE(name1); 01155 FREE(name2); 01156 } 01157 st_free_table(leavesTable); 01158 break; 01159 case 2 : 01160 st_free_table(leavesTable); 01161 inputMap = MapPrimaryInputsByName(network1, network2); 01162 01163 if((inputMap == NIL(st_table)) || !TestRootsAreValid(network1, 01164 network2, 01165 rootsTable)) { 01166 st_foreach_item(rootsTable, gen, &name1, &name2) { 01167 FREE(name1); 01168 FREE(name2); 01169 } 01170 st_free_table(rootsTable); 01171 if(inputMap) { 01172 st_free_table(inputMap); 01173 } 01174 (void) fprintf(vis_stderr, "%s", error_string()); 01175 if(execMode) { 01176 Hrc_ManagerFree(hmgr1); 01177 Ntk_NetworkFree(network1); 01178 } 01179 Hrc_ManagerFree(hmgr2); 01180 Ntk_NetworkFree(network2); 01181 alarm(0); 01182 return 1; 01183 } 01184 equivalent = Eqv_NetworkVerifySequentialEquivalence(network1, 01185 network2, 01186 rootsTable, 01187 NIL(st_table), 01188 partMethod, 01189 useBackwardReach, 01190 reordering); 01191 st_foreach_item(rootsTable, gen, &name1, &name2) { 01192 FREE(name1); 01193 FREE(name2); 01194 } 01195 st_free_table(rootsTable); 01196 break; 01197 case 3 : 01198 if(TestRootsAreValid(network1, network2, rootsTable) && 01199 TestLeavesAreValid(network1, network2, leavesTable)) { 01200 equivalent = Eqv_NetworkVerifySequentialEquivalence(network1, 01201 network2, 01202 rootsTable, 01203 leavesTable, 01204 partMethod, 01205 useBackwardReach, 01206 reordering); 01207 st_foreach_item(rootsTable, gen, &name1, &name2) { 01208 FREE(name1); 01209 FREE(name2); 01210 } 01211 st_free_table(rootsTable); 01212 st_foreach_item(leavesTable, gen, &name1, &name2) { 01213 FREE(name1); 01214 FREE(name2); 01215 } 01216 st_free_table(leavesTable); 01217 } 01218 else { 01219 if(execMode) { 01220 Hrc_ManagerFree(hmgr1); 01221 Ntk_NetworkFree(network1); 01222 } 01223 Hrc_ManagerFree(hmgr2); 01224 Ntk_NetworkFree(network2); 01225 st_foreach_item(rootsTable, gen, &name1, &name2) { 01226 FREE(name1); 01227 FREE(name2); 01228 } 01229 st_free_table(rootsTable); 01230 st_foreach_item(leavesTable, gen, &name1, &name2) { 01231 FREE(name1); 01232 FREE(name2); 01233 } 01234 st_free_table(leavesTable); 01235 (void) fprintf(vis_stderr, "%s", error_string()); 01236 alarm(0); 01237 return 1; 01238 } 01239 } 01240 } 01241 else { 01242 outputMap = MapPrimaryOutputsByName(network1, network2); 01243 inputMap = MapPrimaryInputsByName(network1, network2); 01244 if((inputMap == NIL(st_table)) || (outputMap == NIL(st_table))) { 01245 if(inputMap) { 01246 st_free_table(inputMap); 01247 } 01248 if(outputMap) { 01249 st_free_table(outputMap); 01250 } 01251 if(execMode) { 01252 Hrc_ManagerFree(hmgr1); 01253 Ntk_NetworkFree(network1); 01254 } 01255 Hrc_ManagerFree(hmgr2); 01256 Ntk_NetworkFree(network2); 01257 (void) fprintf(vis_stderr, "%s", error_string()); 01258 alarm(0); 01259 return 1; /* all primary outputs do not match */ 01260 } 01261 st_free_table(inputMap); 01262 st_free_table(outputMap); 01263 equivalent = Eqv_NetworkVerifySequentialEquivalence(network1, network2, 01264 NIL(st_table), 01265 NIL(st_table), 01266 partMethod, 01267 useBackwardReach, 01268 reordering); 01269 } 01270 if(equivalent) { 01271 (void) fprintf(vis_stdout, "Networks are sequentially equivalent.\n\n"); 01272 } 01273 else { 01274 (void) fprintf(vis_stdout, 01275 "Networks are NOT sequentially equivalent.\n\n"); 01276 } 01277 01278 if (printBddInfo) { 01279 bdd_print_stats(Ntk_NetworkReadMddManager(network2), vis_stdout); 01280 } 01281 01282 if(execMode) { 01283 Hrc_ManagerFree(hmgr1); 01284 Ntk_NetworkFree(network1); 01285 } 01286 Hrc_ManagerFree(hmgr2); 01287 Ntk_NetworkFree(network2); 01288 01289 alarm(0); 01290 return 0; /* normal exit */ 01291 01292 usage : 01293 (void) fprintf(vis_stderr, "usage: seq_verify [-b] [-f filename] [-h] [-p partition method] [-t time] [-B]\n\t\t [-i] [-r] file1 [file2]\n"); 01294 (void) fprintf(vis_stderr, " -b input files are BLIF\n"); 01295 (void) fprintf(vis_stderr, " -f file variable name correspondence file\n"); 01296 (void) fprintf(vis_stderr, " -h print the command usage\n"); 01297 (void) fprintf(vis_stderr, " -p method partitioning method for product machine\n"); 01298 (void) fprintf(vis_stderr, " -t time time out period (in seconds)\n"); 01299 (void) fprintf(vis_stderr, " -B use backward image computation\n"); 01300 (void) fprintf(vis_stderr, " -i print BDD statistics\n"); 01301 (void) fprintf(vis_stderr, " -r enable BDD variable reordering\n"); 01302 return 1; /* error exit */ 01303 } 01304 01314 static void 01315 TimeOutHandle(void) 01316 { 01317 longjmp(timeOutEnv, 1); 01318 }