VIS

src/synth/synth.c

Go to the documentation of this file.
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 }