VIS
|
00001 00029 #include "synthInt.h" 00030 00031 static char rcsid[] UNUSED = "$Id: synth.c,v 1.60 2005/05/16 06:22:00 fabio Exp $"; 00032 00033 /*---------------------------------------------------------------------------*/ 00034 /* Constant declarations */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 00038 /*---------------------------------------------------------------------------*/ 00039 /* Stucture declarations */ 00040 /*---------------------------------------------------------------------------*/ 00041 00042 00043 /*---------------------------------------------------------------------------*/ 00044 /* Type declarations */ 00045 /*---------------------------------------------------------------------------*/ 00046 00047 00048 /*---------------------------------------------------------------------------*/ 00049 /* Variable declarations */ 00050 /*---------------------------------------------------------------------------*/ 00051 00052 extern int VerifyTreeMode; 00053 00054 static jmp_buf timeOutEnv; 00055 00056 /*---------------------------------------------------------------------------*/ 00057 /* Macro declarations */ 00058 /*---------------------------------------------------------------------------*/ 00059 00060 00063 /*---------------------------------------------------------------------------*/ 00064 /* Static function prototypes */ 00065 /*---------------------------------------------------------------------------*/ 00066 00067 static int CommandSynthesizeNetwork(Hrc_Manager_t **hmgr, int argc, char **argv); 00068 static void TimeOutHandle(void); 00069 static int TestIsNetworkMultipleValued(Ntk_Network_t *network); 00070 00074 /*---------------------------------------------------------------------------*/ 00075 /* Definition of exported functions */ 00076 /*---------------------------------------------------------------------------*/ 00077 00089 void 00090 Synth_Init(void) 00091 { 00092 Cmd_CommandAdd("synthesize_network", CommandSynthesizeNetwork, 0); 00093 } 00094 00106 void 00107 Synth_End(void) 00108 { 00109 } 00110 00111 /*---------------------------------------------------------------------------*/ 00112 /* Definition of internal functions */ 00113 /*---------------------------------------------------------------------------*/ 00114 00115 /*---------------------------------------------------------------------------*/ 00116 /* Definition of static functions */ 00117 /*---------------------------------------------------------------------------*/ 00118 00274 static int 00275 CommandSynthesizeNetwork(Hrc_Manager_t **hmgr, 00276 int argc, 00277 char **argv) 00278 { 00279 Ntk_Network_t *network1; 00280 Ntk_Node_t *node; 00281 bdd_manager *ddManager; 00282 int timeOutPeriod; 00283 int createdMgr; 00284 int factoring, divisor; 00285 int unreachDC, verbosity; 00286 int result, varOrdered; 00287 long initialTime, finalTime; 00288 char *filehead,*filename; 00289 char *prefix; 00290 FILE *fp; 00291 int c; 00292 lsList dummy = (lsList) 0; 00293 lsGen gen; 00294 Synth_InfoData_t *synthInfo; 00295 char *reorder = NIL(char); 00296 int reordering; 00297 int trySharing; 00298 int realign; 00299 int outputOrdering; 00300 boolean eqn; 00301 00302 if (bdd_get_package_name() != CUDD) { 00303 (void) fprintf(vis_stderr, 00304 "** synth error: synthesize_network can be used only with the CUDD package\n"); 00305 (void) fprintf(vis_stderr, 00306 "** synth error: Please link with CUDD package\n"); 00307 return 1; 00308 } 00309 00310 /* To keep the Alpha compilers happy. */ 00311 network1 = NIL(Ntk_Network_t); 00312 node = NIL(Ntk_Node_t); 00313 ddManager = NIL(bdd_manager); 00314 synthInfo = NIL(Synth_InfoData_t); 00315 00316 /* These are the default values. */ 00317 timeOutPeriod = 0; 00318 createdMgr = 0; 00319 factoring = 0; /* Simple factoring algorithm. */ 00320 divisor = 1; /* Quick divisor */ 00321 unreachDC = 0; /* Do not use unreachable states as DCs */ 00322 filehead = NIL(char); 00323 filename = NIL(char); 00324 prefix = NIL(char); 00325 fp = NIL(FILE); 00326 reordering = 0; 00327 trySharing = 0; 00328 realign = 0; 00329 verbosity = 0; 00330 varOrdered = 0; 00331 outputOrdering = 0; 00332 eqn = 0; 00333 util_getopt_reset(); 00334 00335 while((c = util_getopt(argc, argv, "d:ef:hi:o:r:t:vAO:R:TV:")) != EOF) { 00336 switch(c) { 00337 case 'd': 00338 divisor = atoi(util_optarg); 00339 if (divisor < 0 || divisor > 3) 00340 goto usage; 00341 break; 00342 case 'e': 00343 eqn = 1; 00344 break; 00345 case 'f': 00346 factoring = atoi(util_optarg); 00347 if (factoring < 0 || factoring > 1) 00348 goto usage; 00349 break; 00350 case 'h': 00351 goto usage; 00352 case 'i': 00353 prefix = util_strsav(util_optarg); 00354 break; 00355 case 'o': 00356 filehead = util_strsav(util_optarg); 00357 break; 00358 case 'r': 00359 unreachDC = atoi(util_optarg); 00360 break; 00361 case 't': 00362 timeOutPeriod = atoi(util_optarg); 00363 break; 00364 case 'v': 00365 verbosity = 1; 00366 break; 00367 case 'A': 00368 realign = 1; 00369 break; 00370 case 'O': 00371 outputOrdering = atoi(util_optarg); 00372 if (outputOrdering < 0 || outputOrdering > 2) 00373 goto usage; 00374 SynthSetOutputOrdering(outputOrdering); 00375 break; 00376 case 'R': 00377 reorder = util_strsav(util_optarg); 00378 if (reorder[0] == '0' || reorder[0] == 'n') 00379 reordering = 0; 00380 else if (reorder[0] == '1' || reorder[0] == 'b') 00381 reordering = 1; 00382 else if (reorder[0] == '2' || reorder[0] == 'z') 00383 reordering = 2; 00384 else if (reorder[0] == '3' || reorder[0] == 'a') 00385 reordering = 3; 00386 else 00387 goto usage; 00388 break; 00389 case 'T': 00390 trySharing = 1; 00391 break; 00392 case 'V': 00393 VerifyTreeMode = atoi(util_optarg); 00394 break; 00395 default: 00396 if (util_optarg) 00397 (void) fprintf(vis_stderr, 00398 "** synth error: Unknown option %s\n",util_optarg); 00399 else 00400 (void) fprintf(vis_stderr,"** synth error: Unknown option ?\n"); 00401 goto usage; 00402 } 00403 } 00404 00405 if(Hrc_ManagerReadCurrentNode(*hmgr) == NIL(Hrc_Node_t)) { 00406 (void)fprintf(vis_stderr,"** synth error: The hierarchy manager is empty."); 00407 (void)fprintf(vis_stderr,"** synth error: Read in design.\n"); 00408 goto endgame; 00409 } 00410 00411 network1 = (Ntk_Network_t *) 00412 Hrc_NodeReadApplInfo(Hrc_ManagerReadCurrentNode(*hmgr), 00413 NTK_HRC_NODE_APPL_KEY); 00414 00415 if(network1 == NIL(Ntk_Network_t)) { 00416 (void) fprintf(vis_stderr, "** synth error: There is no network. "); 00417 (void) fprintf(vis_stderr,"** synth error:Use flatten_hierarchy.\n"); 00418 goto endgame; 00419 } 00420 00421 /* Check if the current network has signals with multiple values. */ 00422 if (TestIsNetworkMultipleValued(network1)) { 00423 (void) fprintf(vis_stderr, 00424 "** synth error: Circuit has multiple valued variables.\n"); 00425 (void) fprintf(vis_stderr, 00426 "** synth error: This command works with boolean signals only.\n"); 00427 goto endgame; 00428 } 00429 00430 if (!filehead) 00431 filehead = util_strsav(Ntk_NetworkReadName(network1)); 00432 00433 /* Check if the output equation file already exists */ 00434 if (eqn) { 00435 filename = util_strcat3(filehead,".eq",""); 00436 fp = Cmd_FileOpen(filename,"r",NIL(char *),1); 00437 if (fp) { 00438 (void) fprintf(vis_stderr, 00439 "** synth error: Output equation file %s already exists.\n", 00440 filename); 00441 (void) fprintf(vis_stderr, 00442 "** synth error: Please specify another name.\n"); 00443 fclose(fp); 00444 FREE(filename); 00445 goto endgame; 00446 } 00447 FREE(filename); 00448 } 00449 /* Check if the output blif file already exists */ 00450 filename = util_strcat3(filehead,".ml.blif",""); 00451 fp = Cmd_FileOpen(filename,"r",NIL(char *),1); 00452 if (fp) { 00453 (void) fprintf(vis_stderr, 00454 "** synth error: Output blif file %s already exists.\n", 00455 filename); 00456 (void) fprintf(vis_stderr,"** synth error: Please specify another name.\n"); 00457 fclose(fp); 00458 FREE(filename); 00459 goto endgame; 00460 } 00461 FREE(filename); 00462 00463 if(Ntk_NetworkReadNumPrimaryInputs(network1) != 00464 Ntk_NetworkReadNumInputs(network1)) { 00465 (void) fprintf(vis_stderr, 00466 "** synth error: Pseudo inputs present in the network.\n"); 00467 (void) fprintf(vis_stderr, 00468 "** synth error: Cannot synthesize the network\n"); 00469 goto endgame; 00470 } 00471 00472 ddManager = (bdd_manager *) Ntk_NetworkReadMddManager(network1); 00473 if (ddManager == NIL(bdd_manager)) { 00474 ddManager = (bdd_manager *)Ntk_NetworkInitializeMddManager(network1); 00475 if (ddManager == NIL(bdd_manager)) { 00476 (void) fprintf(vis_stderr, 00477 "** synth error: Could not create Mdd Manager\n"); 00478 goto endgame; 00479 } 00480 createdMgr = 1; 00481 } 00482 00483 /* Check if the network has the variables ordered. 00484 * For combinational synthesis we are only interested in the primary 00485 * input variables. But for sequential synthesis we need primary inputs, 00486 * present state variables and next state variables (to use in 00487 * reachability analysis and use the unreachable states as dont cares). 00488 */ 00489 00490 if (Ord_NetworkTestAreVariablesOrdered(network1, Ord_InputAndLatch_c) == 00491 FALSE) { 00492 Ord_NetworkOrderVariables(network1,Ord_RootsByDefault_c, 00493 Ord_NodesByDefault_c, FALSE, 00494 Ord_InputAndLatch_c,Ord_Unassigned_c, 00495 dummy,0); 00496 varOrdered = 1; 00497 } 00498 00499 /* Start the timer. */ 00500 if (timeOutPeriod > 0){ 00501 (void) signal(SIGALRM, (void(*)(int))TimeOutHandle); 00502 (void) alarm(timeOutPeriod); 00503 if (setjmp(timeOutEnv) > 0) { 00504 (void) fprintf(vis_stderr, "** synth warning: Timeout occurred after "); 00505 (void) fprintf(vis_stderr, "%d seconds.\n", timeOutPeriod); 00506 alarm(0); 00507 goto endgame; 00508 } 00509 } 00510 00511 synthInfo = Synth_InitializeInfo(factoring,divisor,unreachDC, 00512 reordering,trySharing,realign, 00513 filehead,prefix,eqn); 00514 if (!synthInfo) 00515 goto endgame; 00516 00517 /* Synthesize.*/ 00518 initialTime = util_cpu_time(); 00519 00520 result = Synth_SynthesizeNetwork(network1,NIL(graph_t), 00521 NIL(st_table),synthInfo, 00522 verbosity); 00523 00524 finalTime = util_cpu_time(); 00525 00526 if (result) { 00527 (void) fprintf(vis_stdout, "%-20s%10ld\n", "analysis time =", 00528 (finalTime-initialTime)/1000); 00529 } else { 00530 (void) fprintf(vis_stdout, "** synth error: Could not synthesize.\n"); 00531 } 00532 00533 /* Set the mdd id's for all the nodes to unassigned if it 00534 * was specifically set in this routine. 00535 */ 00536 if (varOrdered) { 00537 Ntk_NetworkForEachPrimaryInput(network1,gen,node) { 00538 Ntk_NodeSetMddId(node,NTK_UNASSIGNED_MDD_ID); 00539 } 00540 Ntk_NetworkForEachLatch(network1,gen,node) { 00541 Ntk_Node_t *shadow; 00542 shadow = Ntk_NodeReadShadow(node); 00543 Ntk_NodeSetMddId(node,NTK_UNASSIGNED_MDD_ID); 00544 Ntk_NodeSetMddId(shadow,NTK_UNASSIGNED_MDD_ID); 00545 } 00546 } 00547 00548 if (createdMgr) { 00549 mdd_quit((mdd_manager *)ddManager); 00550 Ntk_NetworkSetMddManager(network1,NIL(mdd_manager)); 00551 } 00552 00553 if (reorder) 00554 FREE(reorder); 00555 if (filehead) 00556 FREE(filehead); 00557 if (prefix) 00558 FREE(prefix); 00559 00560 if (synthInfo) 00561 Synth_FreeInfo(synthInfo); 00562 00563 alarm(0); 00564 return 0; /* normal exit */ 00565 00566 endgame: 00567 if (varOrdered) { 00568 Ntk_NetworkForEachNode(network1,gen,node) { 00569 Ntk_NodeSetMddId(node,NTK_UNASSIGNED_MDD_ID); 00570 } 00571 } 00572 00573 if (createdMgr) { 00574 mdd_quit((mdd_manager *)ddManager); 00575 Ntk_NetworkSetMddManager(network1,NIL(mdd_manager)); 00576 } 00577 00578 if (reorder) 00579 FREE(reorder); 00580 if(filehead) 00581 FREE(filehead); 00582 if(prefix) 00583 FREE(prefix); 00584 00585 if (synthInfo) 00586 Synth_FreeInfo(synthInfo); 00587 00588 return 1; 00589 00590 usage: 00591 (void) fprintf(vis_stderr, "usage: synthesize_network [-d divisor] [-e] [-f factoringMethod] [-h] [-i prefix] [-o fileHead] [-r reachMethod] [-t timeOut] [-v] [-A] [-O outputOrdering] [-R reorder] [-T]\n"); 00592 (void) fprintf(vis_stderr, " -d n\t\tChoose a divisor function (0-4)\n"); 00593 (void) fprintf(vis_stderr, " \t\t\t0: Fast divisor\n"); 00594 (void) fprintf(vis_stderr, 00595 " \t\t\t1: Least occuring literal divisor (default)\n"); 00596 (void) fprintf(vis_stderr, " \t\t\t2: Most occuring literal divisor\n"); 00597 (void) fprintf(vis_stderr, " \t\t\t3: Level-0 kernel divisor\n"); 00598 (void) fprintf(vis_stderr, " -e n\t\tOutput equation format file\n"); 00599 (void) fprintf(vis_stderr, " -f n\t\tChoose a factoring method(0-1)\n"); 00600 (void) fprintf(vis_stderr, " \t\t\t0: Simple factoring (default)\n"); 00601 (void) fprintf(vis_stderr, " \t\t\t1: Generic factoring\n"); 00602 (void) fprintf(vis_stderr, " -h\t\tPrint the command usage\n"); 00603 (void) fprintf(vis_stderr, " -i prefix\tPrefix of internal node names.\n"); 00604 (void) fprintf(vis_stderr, 00605 " -o name\tName of output file (without extension)\n"); 00606 (void) fprintf(vis_stderr, 00607 " -r n\t\tUse unreachable states for sequential circuits\n"); 00608 (void) fprintf(vis_stderr, " \t\tas dont cares(0-3)\n"); 00609 (void) fprintf(vis_stderr, 00610 " \t\t\t0: Do not use unreachable states (default).\n"); 00611 (void) fprintf(vis_stderr, 00612 " \t\t\t1: Use normal BFS method for reachability analysis.\n"); 00613 (void) fprintf(vis_stderr, 00614 " \t\t\t2: Use high density method for reachability analysis.\n"); 00615 (void) fprintf(vis_stderr, 00616 " \t\t\t3: Use approximate unreachable states as dont cares.\n"); 00617 (void) fprintf(vis_stderr, " -t time\tTime out period (in seconds)\n"); 00618 (void) fprintf(vis_stderr, " -v \t\tVerbosity On.\n"); 00619 (void) fprintf(vis_stderr, 00620 " -A \t\tAllow realignment after BDD/ZDD reordering.\n"); 00621 (void) fprintf(vis_stderr, 00622 " -O n\t\tChoose an output ordering method(0-2)\n"); 00623 (void) fprintf(vis_stderr, " \t\t\t0: no ordering\n"); 00624 (void) fprintf(vis_stderr, " \t\t\t1: support variable set (default)\n"); 00625 (void) fprintf(vis_stderr, " \t\t\t2: BDD size\n"); 00626 (void) fprintf(vis_stderr, " -R n\t\tSet reordering (0-3)\n"); 00627 (void) fprintf(vis_stderr, " \t\t\t0 or n: no reordering (default)\n"); 00628 (void) fprintf(vis_stderr, " \t\t\t1 or b: reordering in only BDD\n"); 00629 (void) fprintf(vis_stderr, " \t\t\t2 or z: reordering on only ZDD\n"); 00630 (void) fprintf(vis_stderr, " \t\t\t3 or a: reordering on both\n"); 00631 (void) fprintf(vis_stderr, " -T \t\tTry to share mode nodes.\n"); 00632 return 1; /* error exit */ 00633 } 00634 00646 static void 00647 TimeOutHandle(void) 00648 { 00649 longjmp(timeOutEnv, 1); 00650 } 00651 00652 00665 static int 00666 TestIsNetworkMultipleValued(Ntk_Network_t *network) 00667 { 00668 Ntk_Node_t *node; 00669 lsGen gen; 00670 Var_Variable_t *var; 00671 int numValues; 00672 00673 Ntk_NetworkForEachNode(network,gen,node) { 00674 var = Ntk_NodeReadVariable(node); 00675 numValues = Var_VariableReadNumValues(var); 00676 if (numValues > 2) { 00677 lsFinish(gen); 00678 return 1; 00679 } 00680 } 00681 return 0; 00682 }