VIS
|
00001 00033 #include "partInt.h" 00034 00035 static char rcsid[] UNUSED = "$Id: partInOut.c,v 1.15 2005/04/16 14:52:45 fabio Exp $"; 00036 00039 /*---------------------------------------------------------------------------*/ 00040 /* Static function prototypes */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 00047 /*---------------------------------------------------------------------------*/ 00048 /* Definition of exported functions */ 00049 /*---------------------------------------------------------------------------*/ 00050 00073 graph_t * 00074 Part_CreatePartitionFromMvfs( 00075 mdd_manager *manager, 00076 st_table *nameToMvf, 00077 st_table *nameToId, 00078 st_table *leafTable, 00079 char *partName) 00080 { 00081 graph_t *partition; 00082 Mvf_Function_t *mddFunction; 00083 vertex_t *toVertex; 00084 lsList sinkList; 00085 lsGen gen; 00086 st_table *mddIdToNodeName; 00087 st_generator *stGen; 00088 char *str; 00089 long mddId; 00090 00091 /* Initialize variables */ 00092 mddIdToNodeName = leafTable; 00093 00094 /* Allocate the new partition to be returned */ 00095 partition = g_alloc(); 00096 if (partName) { 00097 partition->user_data = 00098 (gGeneric)PartPartitionInfoCreate(partName,manager,Part_InOut_c); 00099 } /* End of if */ 00100 else { 00101 partition->user_data = 00102 (gGeneric)PartPartitionInfoCreate("dummy",manager,Part_InOut_c); 00103 } /* End of if-then-else */ 00104 00105 /* Create vertices for the functions in nameToMvf */ 00106 st_foreach_item(nameToMvf,stGen,&str,&mddFunction) { 00107 toVertex = g_add_vertex(partition); 00108 00109 /* Update the look-up tables in the graph */ 00110 st_insert(PartPartitionReadNameToVertex(partition),str,toVertex); 00111 if (nameToId) { 00112 if (st_lookup(nameToId, str, &mddId)) { 00113 st_insert(PartPartitionReadMddIdToVertex(partition), 00114 (char *)mddId, toVertex); 00115 } /* End of if */ 00116 } /* End of if */ 00117 00118 /* Fill in the fields of the data attached to the vertex */ 00119 toVertex->user_data = 00120 (gGeneric)PartVertexInfoCreateSingle(str, 00121 Mvf_FunctionDuplicate(mddFunction), 00122 mddId); 00123 } 00124 00125 /* Read the list of vertices on the graph */ 00126 sinkList = lsCopy(g_get_vertices(partition), (lsGeneric (*)(lsGeneric))0); 00127 00128 /* 00129 * For every function on every combinational output, compute the 00130 * support and create vertices in the graph when needed 00131 */ 00132 lsForEachItem(sinkList, gen, toVertex) { 00133 st_table *mddSupport; /* Support of the Mvf_Function */ 00134 st_generator *stGen; /* To iterate over the MddIds of the support */ 00135 vertex_t *fromVertex; /* Holds the current vertex in the support */ 00136 00137 /* Obtain an array of mdd_t * */ 00138 mddFunction = PartVertexReadFunction(toVertex); 00139 00140 /* Compute the support of the set of mdds*/ 00141 mddSupport = PartCreateFunctionSupportTable(mddFunction); 00142 00143 /* 00144 * Create one edge (and one vertex if necessary) for every element 00145 * in mddSupport 00146 */ 00147 st_foreach_item(mddSupport, stGen, &mddId, NULL) { 00148 char *name; 00149 00150 /* Create vertex with the information if needed */ 00151 if (st_lookup(PartPartitionReadMddIdToVertex(partition), 00152 (char *)mddId, &fromVertex) == 0) { 00153 fromVertex = g_add_vertex(partition); 00154 00155 st_lookup(mddIdToNodeName, (char *)mddId, &name); 00156 00157 /* Update the look-up tables in the graph */ 00158 st_insert(PartPartitionReadNameToVertex(partition), 00159 name, (char *)fromVertex); 00160 st_insert(PartPartitionReadMddIdToVertex(partition), 00161 (char *)(long) mddId, (char *)fromVertex); 00162 00163 /* Create vertex data */ 00164 fromVertex->user_data = 00165 (gGeneric)PartVertexInfoCreateSingle(name, 00166 Mvf_FunctionCreateFromVariable(manager,mddId), 00167 mddId); 00168 } /* End of if */ 00169 00170 /* 00171 * Add the edge to the graph. Make sure a self loop is not added. 00172 * The self loop may be produced by a mdd that has in its support 00173 * the same variables that represent the mddId of the node. 00174 */ 00175 if (fromVertex != toVertex) { 00176 g_add_edge(fromVertex, toVertex); 00177 } /* End of if */ 00178 00179 } /* End of st_foreach_item */ 00180 00181 /* Clean the support table */ 00182 st_free_table(mddSupport); 00183 } /* End of lsForEachItem */ 00184 00185 lsDestroy(sinkList, (void (*)(lsGeneric))0); 00186 00187 return partition; 00188 } /* End of Part_CreatePartitionFromMvfs */ 00189 00211 graph_t * 00212 Part_NetworkCreatePartitionFromMvfs( 00213 Ntk_Network_t *network, 00214 st_table *nameToMvf) 00215 { 00216 graph_t *partition; 00217 Ntk_Node_t *node; 00218 Mvf_Function_t *mddFunction; 00219 vertex_t *toVertex; 00220 mdd_manager *manager; 00221 lsList sinkList; 00222 lsGen gen; 00223 st_table *mddIdToNodeName; 00224 st_generator *stGen; 00225 char *ntkName; 00226 char *str; 00227 long mddId; 00228 00229 /* Initialize variables */ 00230 manager = Ntk_NetworkReadMddManager(network); 00231 ntkName = Ntk_NetworkReadName(network); 00232 00233 /* Allocate the new partition to be returned */ 00234 partition = g_alloc(); 00235 partition->user_data = 00236 (gGeneric)PartPartitionInfoCreate(ntkName,manager,Part_InOut_c); 00237 00238 /* Create vertices for the functions in nameToMvf */ 00239 st_foreach_item(nameToMvf,stGen,&str,&mddFunction) { 00240 node = Ntk_NetworkFindNodeByName(network,str); 00241 if (node == NIL(Ntk_Node_t)) { 00242 fprintf(vis_stderr,"%s has no corresponding node in network \n", 00243 str); 00244 Part_PartitionFree(partition); 00245 return NIL(graph_t); 00246 } 00247 mddId = Ntk_NodeReadMddId(node); 00248 toVertex = g_add_vertex(partition); 00249 00250 /* Update the look-up tables in the graph */ 00251 st_insert(PartPartitionReadNameToVertex(partition),str, 00252 (char *)toVertex); 00253 00254 if (mddId != NTK_UNASSIGNED_MDD_ID) { 00255 st_insert(PartPartitionReadMddIdToVertex(partition), 00256 (char *)(long) mddId, (char *)toVertex); 00257 } 00258 00259 /* Fill in the fields of the data attached to the vertex */ 00260 toVertex->user_data = 00261 (gGeneric)PartVertexInfoCreateSingle(str, 00262 Mvf_FunctionDuplicate(mddFunction), 00263 mddId); 00264 } 00265 00266 /* Create a table for all the combinational inputs */ 00267 mddIdToNodeName = st_init_table(st_numcmp, st_numhash); 00268 Ntk_NetworkForEachCombInput(network, gen, node) { 00269 st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 00270 Ntk_NodeReadName(node)); 00271 } 00272 00273 /* Read the list of vertices on the graph */ 00274 sinkList = lsCopy(g_get_vertices(partition), (lsGeneric (*)(lsGeneric))0); 00275 00276 /* 00277 * For every function on every combinational output, compute the 00278 * support and create vertices in the graph when needed 00279 */ 00280 lsForEachItem(sinkList, gen, toVertex) { 00281 st_table *mddSupport; /* Support of the Mvf_Function */ 00282 st_generator *stGen; /* To iterate over the MddIds of the support */ 00283 vertex_t *fromVertex; /* Holds the current vertex in the support */ 00284 00285 /* Obtain an array of mdd_t * */ 00286 mddFunction = PartVertexReadFunction(toVertex); 00287 00288 /* Compute the support of the set of mdds*/ 00289 mddSupport = PartCreateFunctionSupportTable(mddFunction); 00290 00291 /* 00292 * Create one edge (and one vertex if necessary) for every element 00293 * in mddSupport 00294 */ 00295 st_foreach_item(mddSupport, stGen, &mddId, NULL) { 00296 char *name; 00297 00298 /* Create vertex with the information if needed */ 00299 if (st_lookup(PartPartitionReadMddIdToVertex(partition), 00300 (char *)mddId, &fromVertex) == 0) { 00301 fromVertex = g_add_vertex(partition); 00302 00303 st_lookup(mddIdToNodeName, (char *)mddId, &name); 00304 00305 /* Update the look-up tables in the graph */ 00306 st_insert(PartPartitionReadNameToVertex(partition), 00307 name, (char *)fromVertex); 00308 st_insert(PartPartitionReadMddIdToVertex(partition), 00309 (char *)(long) mddId, (char *)fromVertex); 00310 00311 /* Create vertex data */ 00312 fromVertex->user_data = 00313 (gGeneric)PartVertexInfoCreateSingle(name, 00314 Mvf_FunctionCreateFromVariable(manager,mddId), 00315 mddId); 00316 } /* End of if */ 00317 00318 /* 00319 * Add the edge to the graph. Make sure a self loop is not added. 00320 * The self loop may be produced by a mdd that has in its support 00321 * the same variables that represent the mddId of the node. 00322 */ 00323 if (fromVertex != toVertex) { 00324 g_add_edge(fromVertex, toVertex); 00325 } /* End of if */ 00326 00327 } /* End of st_foreach_item */ 00328 00329 /* Clean the support table */ 00330 st_free_table(mddSupport); 00331 } /* End of lsForEachItem */ 00332 00333 st_free_table(mddIdToNodeName); 00334 lsDestroy(sinkList, (void (*)(lsGeneric))0); 00335 00336 return partition; 00337 } /* End of Part_NetworkCreatePartitionFromMvfs */ 00338 00339 /*---------------------------------------------------------------------------*/ 00340 /* Definition of internal functions */ 00341 /*---------------------------------------------------------------------------*/ 00342 00363 void 00364 PartPartitionInputsOutputs( 00365 Ntk_Network_t *network, 00366 graph_t *partition, 00367 lsList rootList, 00368 lsList leaveList, 00369 mdd_t *careSet) 00370 { 00371 Ntk_Node_t *node; /* Pointer to iterate over nodes */ 00372 Mvf_Function_t *mddFunction; /* Pointer to a MDD */ 00373 mdd_manager *manager; /* Mdd manager in the partition */ 00374 st_table *tableOfLeaves; /* To store the leaves of the graph */ 00375 st_table *mddIdToNodeName; /* For quick lookup of node's name */ 00376 array_t *arrayOfMvf; /* To store the next state functions */ 00377 array_t *arrayOfRoots; /* To store the roots of the graph */ 00378 lsList sinkList; /* Vertices representing comb. outputs */ 00379 lsGen gen; /* To iterate over lists */ 00380 vertex_t *toVertex; /* Will hold the current function vertex */ 00381 int i; /* Index for loops */ 00382 long mddId; /* Will hold the mddId being processed */ 00383 00384 00385 manager = PartPartitionReadMddManager(partition); 00386 00387 /* Take the nodes in leaveList as the leaves */ 00388 tableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash); 00389 mddIdToNodeName = st_init_table(st_numcmp, st_numhash); 00390 if (leaveList == (lsList)0) { 00391 Ntk_NetworkForEachCombInput(network, gen, node) { 00392 st_insert(tableOfLeaves, (char *)node, (char *) (long) (-1) ); 00393 st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 00394 Ntk_NodeReadName(node)); 00395 } 00396 } /* End of then */ 00397 else { 00398 lsForEachItem(leaveList, gen, node) { 00399 st_insert(tableOfLeaves, (char *)node, (char *) (long) (-1) ); 00400 st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 00401 Ntk_NodeReadName(node)); 00402 } 00403 } /* End of if-then-else */ 00404 00405 /* Take the nodes in rootList as the roots */ 00406 if (rootList == (lsList)0) { 00407 arrayOfRoots = array_alloc(Ntk_Node_t *, 00408 Ntk_NetworkReadNumCombOutputs(network)); 00409 i = 0; 00410 Ntk_NetworkForEachCombOutput(network, gen, node) { 00411 array_insert(Ntk_Node_t *, arrayOfRoots, i++, node); 00412 } 00413 } /* End of then */ 00414 else { 00415 arrayOfRoots = array_alloc(Ntk_Node_t *, lsLength(rootList)); 00416 i = 0; 00417 lsForEachItem(rootList, gen, node) { 00418 array_insert(Ntk_Node_t *, arrayOfRoots, i++, node); 00419 } 00420 } /* End of if-then-else */ 00421 00422 /* Build the next state functions as a function of the inputs */ 00423 arrayOfMvf = Ntm_NetworkBuildMvfs(network, arrayOfRoots, tableOfLeaves, 00424 careSet); 00425 00426 /* Create one vertex for every component of arrayOfMvf */ 00427 for (i=0; i < array_n(arrayOfRoots); i++) { 00428 node = array_fetch(Ntk_Node_t *, arrayOfRoots, i); 00429 00430 mddId = Ntk_NodeReadMddId(node); 00431 00432 /* obtain the function attached to the node */ 00433 mddFunction = array_fetch(Mvf_Function_t *, arrayOfMvf, i); 00434 toVertex = g_add_vertex(partition); 00435 00436 /* Update the look-up tables in the graph */ 00437 st_insert(PartPartitionReadNameToVertex(partition), 00438 Ntk_NodeReadName(node), (char *)toVertex); 00439 if (mddId != NTK_UNASSIGNED_MDD_ID) { 00440 st_insert(PartPartitionReadMddIdToVertex(partition), 00441 (char *)(long) mddId, (char *)toVertex); 00442 } /* End of if */ 00443 toVertex->user_data = 00444 (gGeneric)PartVertexInfoCreateSingle(Ntk_NodeReadName(node), 00445 mddFunction, 00446 mddId); 00447 } /* End of for */ 00448 00449 /* Read the list of vertices on the graph */ 00450 sinkList = lsCopy(g_get_vertices(partition), (lsGeneric (*)(lsGeneric))0); 00451 00452 /* 00453 * For every function on every combinational output, compute the 00454 * support and create vertices in the graph when needed 00455 */ 00456 lsForEachItem(sinkList, gen, toVertex) { 00457 st_table *mddSupport; /* To store the support of the Mvf_Function */ 00458 st_generator *stGen; /* To iterate over the MddIds of the support */ 00459 vertex_t *fromVertex; /* Will hold the current vertex in the support */ 00460 00461 /* Obtain an array of mdd_t * */ 00462 mddFunction = PartVertexReadFunction(toVertex); 00463 00464 /* Compute the support of the set of mdds*/ 00465 mddSupport = PartCreateFunctionSupportTable(mddFunction); 00466 00467 /* 00468 * Create one edge (and one vertex if necessary) for every element 00469 * in mddSupport 00470 */ 00471 st_foreach_item(mddSupport, stGen, &mddId, NULL) { 00472 char *name; 00473 00474 /* Create vertex with the information if needed */ 00475 if (st_lookup(PartPartitionReadMddIdToVertex(partition), 00476 (char *)mddId, &fromVertex) == 0) { 00477 fromVertex = g_add_vertex(partition); 00478 00479 st_lookup(mddIdToNodeName, (char *)mddId, &name); 00480 00481 /* Update the look-up tables in the graph */ 00482 st_insert(PartPartitionReadNameToVertex(partition), 00483 name, (char *)fromVertex); 00484 st_insert(PartPartitionReadMddIdToVertex(partition), 00485 (char *)(long) mddId, (char *)fromVertex); 00486 00487 /* Create vertex data */ 00488 fromVertex->user_data = 00489 (gGeneric)PartVertexInfoCreateSingle(name, 00490 Mvf_FunctionCreateFromVariable(manager,mddId), 00491 mddId); 00492 } /* End of if */ 00493 00494 /* 00495 * Add the edge to the graph. Make sure a self loop is not added. The 00496 * self loop may be produced by a mdd that has in its support the same 00497 * variables that represent the mddId of the node. 00498 */ 00499 if (fromVertex != toVertex) { 00500 g_add_edge(fromVertex, toVertex); 00501 } /* End of if */ 00502 00503 } /* End of st_foreach_item */ 00504 00505 /* Clean the support table */ 00506 st_free_table(mddSupport); 00507 } /* End of lsForEachItem */ 00508 00509 /* Clean up */ 00510 st_free_table(mddIdToNodeName); 00511 st_free_table(tableOfLeaves); 00512 array_free(arrayOfRoots); 00513 lsDestroy(sinkList, (void (*)(lsGeneric))0); 00514 /* 00515 * The contents of this array (array of mdds) is not deallocated because the 00516 * information has been transferred to the partition structure. All the 00517 * functions are stored now as part of the vertex information. 00518 */ 00519 array_free(arrayOfMvf); 00520 00521 } /* End of PartPartitionInputsOutputs */ 00522 00523 00544 int 00545 PartPartitionInOutChangeRoots( 00546 Ntk_Network_t *network, 00547 graph_t *partition, 00548 lsList rootList, 00549 int verbosity) 00550 { 00551 Ntk_Node_t *node; /* Pointer to iterate over nodes */ 00552 mdd_manager *manager; /* Mdd manager in the partition */ 00553 lsList newRootList; 00554 lsList vertexList; 00555 lsGen gen; /* To iterate over lists */ 00556 vertex_t *vertex; 00557 char *vertexName; 00558 long initialTime, finalTime; 00559 st_table *rootNodesTable = st_init_table(st_ptrcmp, st_ptrhash); 00560 mdd_t *careSet; 00561 00562 int prevNumOfLatchDataInput = 0; 00563 int prevNumOfPrimaryOutput = 0; 00564 int newNumOfLatchDataInput = 0; 00565 int newNumOfPrimaryOutput = 0; 00566 int overlapNumOfLatchDataInput = 0; 00567 int overlapNumOfPrimaryOutPut = 0; 00568 00569 initialTime = util_cpu_time(); 00570 00571 manager = PartPartitionReadMddManager(partition); 00572 vertexList = g_get_vertices(partition); 00573 00574 lsForEachItem(vertexList, gen, vertex){ 00575 vertexName = PartVertexReadName(vertex); 00576 node = Ntk_NetworkFindNodeByName(network, vertexName); 00577 if (Ntk_NodeTestIsCombOutput(node)){ 00578 st_insert(rootNodesTable, (char *)node, (char *)(long)(-1)); 00579 if (Ntk_NodeTestIsLatchDataInput(node)){ 00580 prevNumOfLatchDataInput++; 00581 }else if (Ntk_NodeTestIsPrimaryOutput(node)){ 00582 prevNumOfPrimaryOutput++; 00583 } 00584 } 00585 } 00586 00587 newRootList = lsCreate(); 00588 lsForEachItem(rootList, gen, node){ 00589 if (!(st_is_member(rootNodesTable, (char *)node))){ 00590 lsNewEnd(newRootList, (lsGeneric)node, LS_NH); 00591 if (Ntk_NodeTestIsLatchDataInput(node)){ 00592 newNumOfLatchDataInput++; 00593 }else if (Ntk_NodeTestIsPrimaryOutput(node)){ 00594 newNumOfPrimaryOutput++; 00595 } 00596 }else{ 00597 if (Ntk_NodeTestIsLatchDataInput(node)){ 00598 overlapNumOfLatchDataInput++; 00599 }else if (Ntk_NodeTestIsPrimaryOutput(node)){ 00600 overlapNumOfPrimaryOutPut++; 00601 } 00602 } 00603 } 00604 00605 st_free_table(rootNodesTable); 00606 00607 if (lsLength(newRootList) > 0){ 00608 careSet = mdd_one(manager); 00609 PartPartitionInputsOutputs(network, partition, newRootList, 00610 (lsList)0, careSet); 00611 mdd_free(careSet); 00612 } 00613 00614 lsDestroy(newRootList, (void (*)(lsGeneric))0); 00615 00616 finalTime = util_cpu_time(); 00617 00618 if (verbosity >= 2){ 00619 fprintf(vis_stdout, "PART: Partition is changed.\n"); 00620 fprintf(vis_stdout, "PART: Old - %d next state functions\n", 00621 prevNumOfLatchDataInput); 00622 fprintf(vis_stdout, "PART: Old - %d primary outputs\n", 00623 prevNumOfPrimaryOutput); 00624 fprintf(vis_stdout, "PART: New - %d next state functions\n", 00625 prevNumOfLatchDataInput + newNumOfLatchDataInput); 00626 fprintf(vis_stdout, "PART: New - %d primary outputs\n", 00627 prevNumOfPrimaryOutput + newNumOfPrimaryOutput); 00628 fprintf(vis_stdout, "PART: Partitioning time = %10ld\n", 00629 (finalTime - initialTime) / 1000); 00630 Part_PartitionPrintStats(vis_stdout, partition, FALSE); 00631 } 00632 00633 /* 00634 * Is partition increased? 00635 */ 00636 if (newNumOfLatchDataInput + newNumOfPrimaryOutput > 0){ 00637 return 1; 00638 }else{ 00639 return 0; 00640 } 00641 } /* End of PartPartitionInOutChangeRoots */ 00642 00643 /*---------------------------------------------------------------------------*/ 00644 /* Definition of static functions */ 00645 /*---------------------------------------------------------------------------*/ 00646 00647 00648 00649 00650 00651 00652 00653 00654 00655 00656