VIS

src/ord/ordIo.c

Go to the documentation of this file.
00001 
00032 #include "ordInt.h"
00033 
00034 static char rcsid[] UNUSED = "$Id: ordIo.c,v 1.15 2004/07/28 20:42:10 jinh Exp $";
00035 
00036 /*---------------------------------------------------------------------------*/
00037 /* Constant declarations                                                     */
00038 /*---------------------------------------------------------------------------*/
00039 /*
00040  * States of the state machine used to parse the input node list file.
00041  */
00042 #define STATE_TEST 0 /* next char is in first column */
00043 #define STATE_WAIT 1 /* wait until end of line '\n' is reached */
00044 #define STATE_IN   2 /* parsing a node name */
00045 
00046 /*
00047  * Maximum permissible length of a node name in the input node list file.
00048  */
00049 #define MAX_NAME_LENGTH 32768
00050 
00051 
00054 /*---------------------------------------------------------------------------*/
00055 /* Static function prototypes                                                */
00056 /*---------------------------------------------------------------------------*/
00057 
00058 static array_t * NodeBuildBddLevelArrayFromNtkNode(Ntk_Node_t * node);
00059 static array_t * NodeBuildBddIdArrayFromNtkNode(Ntk_Node_t * node);
00060 static int IntegersCompare(const void * obj1, const void * obj2);
00061 static int NodesCompareBddLevelArray(lsGeneric node1, lsGeneric node2);
00062 static array_t * NodeReadBddLevelArray(Ntk_Node_t * node);
00063 static void NodeSetBddLevelArray(Ntk_Node_t * node, array_t * bddLevelArray);
00064 static boolean NameStringProcess(char * nameString, Ntk_Network_t * network, lsList nodeList, int verbose);
00065 
00069 /*---------------------------------------------------------------------------*/
00070 /* Definition of exported functions                                          */
00071 /*---------------------------------------------------------------------------*/
00072 
00092 int
00093 Ord_NetworkPrintVariableOrder(
00094   FILE * fp,
00095   Ntk_Network_t * network,
00096   Ord_OrderType  orderType /* Ord_All_c, Ord_InputAndLatch_c or Ord_NextStateNode_c */)
00097 {
00098   lsGen        gen;
00099   lsList       nodeList;
00100   Ntk_Node_t  *node;
00101   int          maxNameLength;
00102   time_t       now;
00103   struct tm   *nowStructPtr;
00104   char        *nowTxt;
00105 
00106   assert((orderType == Ord_All_c) || (orderType == Ord_InputAndLatch_c)
00107          || (orderType == Ord_NextStateNode_c));
00108 
00109   /*
00110    * First, build up a list of all the nodes covered by orderType.
00111    */
00112   if (orderType == Ord_All_c) {
00113     nodeList = lsCopy(Ntk_NetworkReadNodes(network),
00114                       (lsGeneric (*) (lsGeneric)) NULL);
00115   }
00116   else {
00117     nodeList = lsCreate();
00118     Ntk_NetworkForEachNode(network, gen, node) {
00119       if (Ntk_NodeTestIsNextStateNode(node)
00120           || ((orderType == Ord_InputAndLatch_c) && Ntk_NodeTestIsCombInput(node))) {
00121         (void) lsNewEnd(nodeList, (lsGeneric) node, LS_NH);
00122       }
00123     }
00124   }
00125   
00126   /*
00127    * As a sanity check, make sure that all the variables in orderType have an
00128    * MDD id.
00129    */
00130   lsForEachItem(nodeList, gen, node) {
00131     if (Ntk_NodeReadMddId(node) == NTK_UNASSIGNED_MDD_ID) {
00132       error_append("node ");
00133       error_append(Ntk_NodeReadName(node));
00134       error_append(" not ordered\n");
00135 
00136       (void) lsFinish(gen);
00137       (void) lsDestroy(nodeList, (void (*) (lsGeneric)) NULL);
00138       return (0);
00139     }
00140   }
00141 
00142   /*
00143    * For each node in nodeList, get the array of levels of the BDD variables
00144    * which make up the MDD variable of node.
00145    */
00146   lsForEachItem(nodeList, gen, node) {
00147     array_t *bddLevelArray = NodeBuildBddLevelArrayFromNtkNode(node);
00148 
00149     NodeSetBddLevelArray(node, bddLevelArray);
00150   }
00151 
00152   /*
00153    * Sort the nodes of nodeList in ascending order of the lowest level BDD
00154    * variable corresponding to a node's MDD variable.
00155    */
00156   (void) lsSort(nodeList, NodesCompareBddLevelArray);
00157 
00158   /*
00159    * Compute the maximum length of a node name, for pretty printing.
00160    */
00161   maxNameLength = 0;
00162   lsForEachItem(nodeList, gen, node) {
00163     int nameLength = strlen(Ntk_NodeReadName(node));
00164     maxNameLength = (nameLength > maxNameLength) ? nameLength : maxNameLength;
00165   }
00166   
00167   /*
00168    * Write out the header for the output file.
00169    */
00170   now = time(0);
00171   nowStructPtr = localtime(& now);
00172   nowTxt = asctime(nowStructPtr);
00173   
00174   (void) fprintf(fp, "# %s\n", Vm_VisReadVersion());
00175   (void) fprintf(fp, "# network name: %s\n", Ntk_NetworkReadName(network));
00176   (void) fprintf(fp, "# generated: %s", nowTxt);
00177   (void) fprintf(fp, "#\n");
00178   (void) fprintf(fp, "# %-*s type            mddId vals levs\n",
00179                  maxNameLength, "name");
00180   
00181   /*
00182    * Write out the nodes in order.
00183    */
00184   lsForEachItem(nodeList, gen, node) {
00185     int i;
00186     array_t *bddLevelArray = NodeReadBddLevelArray(node);
00187     char *nodeType = Ntk_NodeObtainTypeAsString(node);
00188     
00189     (void) fprintf(fp, "%-*s  %-16s %5d %4d ",
00190                    maxNameLength,
00191                    Ntk_NodeReadName(node),
00192                    nodeType,
00193                    Ntk_NodeReadMddId(node),
00194                    Var_VariableReadNumValues(Ntk_NodeReadVariable(node)));
00195     FREE(nodeType);
00196 
00197     (void) fprintf(fp, "(");
00198     for (i = 0; i < array_n(bddLevelArray); i++) {
00199       int level = array_fetch(int, bddLevelArray, i);
00200       
00201       if (i == 0) {
00202         (void) fprintf(fp, "%d", level);
00203       }
00204       else {
00205         (void) fprintf(fp, ", %d", level);
00206       }
00207     }
00208     (void) fprintf(fp, ")\n");
00209     array_free(bddLevelArray);
00210   }
00211 
00212   (void) lsDestroy(nodeList, (void (*) (lsGeneric)) NULL);
00213   return (1);
00214 }
00215   
00216 
00224 char **
00225 Ord_NetworkGetCombInputNamesInOrder(
00226   Ntk_Network_t *network)
00227 {
00228   lsGen         gen;
00229   lsList        nodeList;
00230   Ntk_Node_t    *node;
00231   int           i;
00232   char          **names;
00233 
00234   i = 0;
00235   nodeList = lsCreate();
00236   Ntk_NetworkForEachNode(network, gen, node) {
00237     if (Ntk_NodeTestIsCombInput(node)) {
00238       (void) lsNewEnd(nodeList, (lsGeneric) node, LS_NH);
00239       i++;
00240     }
00241   }
00242 
00243   names = (char **)ALLOC(char *, i);
00244   if (!names)
00245     return(NULL);
00246   
00247   /*
00248    * For each node in nodeList, get the array of levels of the BDD variables
00249    * which make up the MDD variable of node.
00250    */
00251   lsForEachItem(nodeList, gen, node) {
00252     array_t *bddLevelArray = NodeBuildBddLevelArrayFromNtkNode(node);
00253 
00254     NodeSetBddLevelArray(node, bddLevelArray);
00255   }
00256 
00257   /*
00258    * Sort the nodes of nodeList in ascending order of the lowest level BDD
00259    * variable corresponding to a node's MDD variable.
00260    */
00261   (void) lsSort(nodeList, NodesCompareBddLevelArray);
00262 
00263   /*
00264    * Write out the nodes in order.
00265    */
00266   i = 0;
00267   lsForEachItem(nodeList, gen, node) {
00268     names[i] = (char *)malloc(strlen(Ntk_NodeReadName(node)) + 1);
00269     strcpy(names[i], Ntk_NodeReadName(node));
00270     i++;
00271   }
00272 
00273   (void) lsDestroy(nodeList, (void (*) (lsGeneric)) NULL);
00274   return(names);
00275 }
00276 
00277 
00296 boolean
00297 Ord_FileReadNodeList(
00298   FILE * fp,
00299   Ntk_Network_t * network,
00300   lsList * nodeList /* of Ntk_Node_t , for return */,
00301   int verbose)
00302 {
00303   int     c;
00304   int     state;
00305   int     curPosition = 0;
00306   boolean status;
00307   char    nameString[MAX_NAME_LENGTH];
00308   boolean returnFlag = TRUE;
00309   
00310   *nodeList = lsCreate();
00311 
00312   state = STATE_TEST;
00313   while ((c = fgetc(fp)) != EOF) {
00314 
00315     switch (state) {
00316         case STATE_TEST:
00317           /* At start of a new line. */
00318           if (c == '#') {
00319             /* Line starting with comment character; wait for newline */
00320             state = STATE_WAIT;
00321           }
00322           else if ((c == ' ') || (c == '\t')) {
00323             /* Line starting with white space; wait for newline */
00324             state = STATE_WAIT;
00325           }
00326           else if (c == '\n') {
00327             /* Line starting newline; go to next line */
00328             state = STATE_TEST;
00329           }
00330           else {
00331             /* Assume starting a node name. */
00332             curPosition = 0;
00333             nameString[curPosition++] = c;
00334             state = STATE_IN;
00335           }
00336           break;
00337         case STATE_WAIT:
00338           /*
00339            * Waiting for the newline character.
00340            */
00341           state = (c == '\n') ? STATE_TEST : STATE_WAIT;
00342           break;
00343         case STATE_IN:
00344           /*
00345            * Parsing a node name.  If white space reached, then terminate the
00346            * node name and process it.  Else, continue parsing.
00347            */
00348           if ((c == ' ') || (c == '\n') || (c == '\t')) {
00349             nameString[curPosition] = '\0';
00350             status = NameStringProcess(nameString, network, *nodeList, verbose);
00351             if (status == FALSE) {
00352               returnFlag = FALSE;
00353             }
00354             state = (c == '\n') ? STATE_TEST : STATE_WAIT;
00355           }
00356           else {
00357             nameString[curPosition++] = c;
00358             if (curPosition >= MAX_NAME_LENGTH) {
00359               error_append("maximum node name length exceeded");
00360               returnFlag = FALSE;
00361             }
00362             state = STATE_IN; /* redundant, but be explicit */
00363           }
00364           break;
00365         default:
00366           fail("unrecognized state");
00367     }
00368   }
00369 
00370   /*
00371    * Handle case where EOF terminates a name.
00372    */
00373   if (state == STATE_IN) {
00374     nameString[curPosition] = '\0';
00375     status = NameStringProcess(nameString, network, *nodeList, verbose);
00376     if (status == FALSE) {
00377       returnFlag = FALSE;
00378     }
00379   }
00380 
00381   if (returnFlag) {
00382     return TRUE;
00383   }
00384   else {
00385     (void) lsDestroy(*nodeList, (void (*) (lsGeneric)) NULL);
00386     return FALSE;
00387   }
00388 }
00389 
00390 
00391 /*---------------------------------------------------------------------------*/
00392 /* Definition of internal functions                                          */
00393 /*---------------------------------------------------------------------------*/
00394 
00395 
00405 int
00406 OrdMakeNewVariableOrder(mdd_manager *mddMgr, lsList suppliedNodeList,
00407                      int group, int verbose)
00408 {
00409   int           i, nVars;
00410   int           *invPerm = NIL(int);
00411   int           *groupInfo = NIL(int);
00412   int           length, bddId, mvLen;
00413   lsGen         gen;
00414   Ntk_Node_t    *node;
00415   array_t       *bddIdArray;
00416   char          *name = NIL(char), *prevName = NIL(char), *longName;
00417   int           len1, len2, minLen;
00418 
00419   nVars = bdd_num_vars(mddMgr);
00420   invPerm = ALLOC(int, nVars);
00421 
00422   length = 0;
00423   if (group) {
00424     prevName = NIL(char);
00425     groupInfo = ALLOC(int, nVars);
00426     memset(groupInfo, 0, sizeof(int) * nVars);
00427   }
00428   lsForEachItem(suppliedNodeList, gen, node) {
00429     bddIdArray = NodeBuildBddIdArrayFromNtkNode(node);
00430     mvLen = array_n(bddIdArray);
00431     if (group) {
00432       name = Ntk_NodeReadName(node);
00433       if (prevName) {
00434         len1 = strlen(prevName);
00435         len2 = strlen(name);
00436         if (len1 < len2) {
00437           minLen = len1;
00438           longName = name;
00439         } else {
00440           minLen = len2;
00441           longName = prevName;
00442         }
00443         if (strncmp(name, prevName, minLen) == 0) {
00444           if (strcmp(longName + minLen, "$NS") == 0)
00445             groupInfo[length - mvLen] = mvLen * 2;
00446         }
00447       }
00448     }
00449     for (i = 0; i < mvLen; i++) {
00450       bddId = array_fetch(int, bddIdArray, i);
00451       invPerm[length] = bddId;
00452       length++;
00453     }
00454     array_free(bddIdArray);
00455     if (group)
00456       prevName = name;
00457   }
00458 
00459   if (length != nVars) {
00460     fprintf(vis_stderr,
00461             "** ord error: the number of variables does not match\n");
00462     FREE(invPerm);
00463     if (group)
00464       FREE(groupInfo);
00465     return(1);
00466   }
00467 
00468   bdd_discard_all_var_groups(mddMgr);
00469   bdd_shuffle_heap(mddMgr, invPerm);
00470 
00471   if (group) {
00472     mdd_t       *var;
00473 
00474     for (i = 0; i < nVars; i++) {
00475       if (groupInfo[i]) {
00476         var = bdd_var_with_index(mddMgr, invPerm[i]);
00477         bdd_new_var_block(var, groupInfo[i]);
00478         i += groupInfo[i] - 1;
00479       }
00480     }
00481     FREE(groupInfo);
00482   }
00483 
00484   FREE(invPerm);
00485   return(0);
00486 }
00487 
00488 
00489 /*---------------------------------------------------------------------------*/
00490 /* Definition of static functions                                            */
00491 /*---------------------------------------------------------------------------*/
00492 
00507 static array_t *
00508 NodeBuildBddLevelArrayFromNtkNode(
00509   Ntk_Node_t * node)
00510 {
00511   int            i;
00512   Ntk_Network_t *network       = Ntk_NodeReadNetwork(node);
00513   mdd_manager   *mddManager    = Ntk_NetworkReadMddManager(network);
00514   array_t       *mvarArray     = mdd_ret_mvar_list(mddManager);
00515   int            mddId         = Ntk_NodeReadMddId(node);
00516   mvar_type      mv;
00517   array_t       *bddLevelArray;
00518 
00519   mv            = array_fetch(mvar_type, mvarArray, mddId);
00520   bddLevelArray = array_alloc(int, mv.encode_length);
00521 
00522   for (i = 0; i < mv.encode_length; i++) {
00523     int    bddId    = mdd_ret_bvar_id(&mv, i);
00524     bdd_t *varBdd   = bdd_get_variable((bdd_manager *) mddManager, bddId);
00525     int    varLevel = (int) bdd_top_var_level((bdd_manager *) mddManager, varBdd);
00526 
00527     bdd_free(varBdd);
00528     array_insert_last(int, bddLevelArray, varLevel);
00529   }
00530   array_sort(bddLevelArray, IntegersCompare);
00531 
00532   return (bddLevelArray);
00533 }
00534 
00535 
00548 static array_t *
00549 NodeBuildBddIdArrayFromNtkNode(
00550   Ntk_Node_t * node)
00551 {
00552   int            i, bddId;
00553   Ntk_Network_t *network    = Ntk_NodeReadNetwork(node);
00554   mdd_manager   *mddManager = Ntk_NetworkReadMddManager(network);
00555   array_t       *mvarArray  = mdd_ret_mvar_list(mddManager);
00556   int            mddId      = Ntk_NodeReadMddId(node);
00557   mvar_type      mv;
00558   array_t       *bddIdArray;
00559 
00560   mv         = array_fetch(mvar_type, mvarArray, mddId);
00561   bddIdArray = array_alloc(int, mv.encode_length);
00562 
00563   for (i = 0; i < mv.encode_length; i++) {
00564     bddId = mdd_ret_bvar_id(&mv, i);
00565     array_insert_last(int, bddIdArray, bddId);
00566   }
00567 
00568   return (bddIdArray);
00569 }
00570 
00571 
00579 static int
00580 IntegersCompare(
00581   const void * obj1,
00582   const void * obj2)
00583 {
00584   int int1 = *(int *) obj1;
00585   int int2 = *(int *) obj2;
00586   
00587   if (int1 < int2) {
00588     return -1;
00589   }
00590   else if (int1 == int2) {
00591     return 0;
00592   }
00593   else {
00594     return 1;
00595   }
00596 }
00597 
00598 
00607 static int
00608 NodesCompareBddLevelArray(
00609   lsGeneric node1,
00610   lsGeneric node2)
00611 {
00612   array_t *bddLevelArray1 = NodeReadBddLevelArray((Ntk_Node_t *) node1);
00613   array_t *bddLevelArray2 = NodeReadBddLevelArray((Ntk_Node_t *) node2);
00614   int      firstLevel1    = array_fetch(int, bddLevelArray1, 0);
00615   int      firstLevel2    = array_fetch(int, bddLevelArray2, 0);
00616   
00617   if (firstLevel1 < firstLevel2) {
00618     return -1;
00619   }
00620   else if (firstLevel1 == firstLevel2) {
00621     return 0;
00622   }
00623   else {
00624     return 1;
00625   }
00626 }
00627 
00628 
00638 static array_t *
00639 NodeReadBddLevelArray(
00640   Ntk_Node_t * node)
00641 {
00642   return ((array_t *) Ntk_NodeReadUndef(node));
00643 }
00644 
00645 
00655 static void
00656 NodeSetBddLevelArray(
00657   Ntk_Node_t * node,
00658   array_t * bddLevelArray)
00659 {
00660   Ntk_NodeSetUndef(node, (void *) bddLevelArray);
00661 }
00662 
00663 
00677 static boolean
00678 NameStringProcess(
00679   char * nameString,
00680   Ntk_Network_t * network,
00681   lsList  nodeList,
00682   int verbose)
00683 {
00684   Ntk_Node_t *node = Ntk_NetworkFindNodeByActualName(network, nameString);
00685 
00686   if (node == NIL(Ntk_Node_t)) {
00687     error_append("Node not found for name: ");
00688     error_append(nameString);
00689     error_append("\n");
00690     return FALSE;
00691   }
00692 
00693   if (verbose > 1) {
00694     (void) fprintf(vis_stdout, "Reading node: %s\n", Ntk_NodeReadName(node));
00695   }
00696 
00697   (void) lsNewEnd(nodeList, (lsGeneric) node, LS_NH);  
00698   return TRUE;
00699 }
00700 
00701 
00702 
00703 
00704 
00705 
00706 
00707 
00708 
00709 
00710 
00711