VIS
|
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