VIS
|
00001 00021 #include "spfdInt.h" 00022 00023 /*---------------------------------------------------------------------------*/ 00024 /* Constant declarations */ 00025 /*---------------------------------------------------------------------------*/ 00026 00027 00028 /*---------------------------------------------------------------------------*/ 00029 /* Type declarations */ 00030 /*---------------------------------------------------------------------------*/ 00031 00032 00033 /*---------------------------------------------------------------------------*/ 00034 /* Structure declarations */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 00038 /*---------------------------------------------------------------------------*/ 00039 /* Variable declarations */ 00040 /*---------------------------------------------------------------------------*/ 00041 00042 00043 /*---------------------------------------------------------------------------*/ 00044 /* Macro declarations */ 00045 /*---------------------------------------------------------------------------*/ 00046 00047 00050 /*---------------------------------------------------------------------------*/ 00051 /* Static function prototypes */ 00052 /*---------------------------------------------------------------------------*/ 00053 00054 00058 /*---------------------------------------------------------------------------*/ 00059 /* Definition of exported functions */ 00060 /*---------------------------------------------------------------------------*/ 00061 00062 /*---------------------------------------------------------------------------*/ 00063 /* Definition of internal functions */ 00064 /*---------------------------------------------------------------------------*/ 00065 00073 SpfdApplData_t * 00074 SpfdInitializeApplData( 00075 Ntk_Network_t *network) 00076 { 00077 SpfdApplData_t *applData; 00078 SpfdNodeData_t *data; 00079 st_table *nodeToData; 00080 lsGen gen; 00081 Ntk_Node_t *node; 00082 00083 applData = ALLOC(SpfdApplData_t, 1); 00084 00085 Ntk_NetworkAddApplInfo(network, SPFD_NETWORK_APPL_KEY, 00086 (Ntk_ApplInfoFreeFn) SpfdApplFreeCallback, 00087 (void *) applData); 00088 00089 nodeToData = applData->nodeToData = st_init_table(st_ptrcmp, st_ptrhash); 00090 applData->ddManager = Ntk_NetworkReadMddManager(network); 00091 applData->currXCube = NIL(bdd_node); 00092 applData->currRegionNodes = NIL(st_table); 00093 applData->currBddReq = NIL(st_table); 00094 applData->currInUseVars = NIL(st_table); 00095 applData->currPiAltVars = NIL(st_table); 00096 /* Will be freed when the application quits */ 00097 applData->currWireTable = st_init_table(st_ptrcmp,st_ptrhash); 00098 applData->currReplaceTable = st_init_table(st_ptrcmp,st_ptrhash); 00099 applData->wiresRemoved = st_init_table(st_ptrcmp,st_ptrhash); 00100 applData->nodesRemoved = st_init_table(st_ptrcmp,st_ptrhash); 00101 applData->placeData = NIL(SpfdPlaceData_t); 00102 00103 Ntk_NetworkForEachNode(network,gen,node) { 00104 data = ALLOC(SpfdNodeData_t,1); 00105 data->spfd = NIL(bdd_node); 00106 data->localAlt = NIL(bdd_node); 00107 data->alternative = NIL(bdd_node); 00108 data->faninOrder = NIL(array_t); 00109 data->parameters = NIL(bdd_node *); 00110 data->numParams = 0; 00111 data->auxId = -1; 00112 data->locked = FALSE; 00113 00114 st_insert(nodeToData,(char *)node,(char *)data); 00115 } 00116 00117 return applData; 00118 00119 } /* End of SpfdInitializeApplData */ 00120 00121 00132 bdd_node ** 00133 SpfdComputeParameters( 00134 SpfdApplData_t *applData, 00135 st_table *SCC) 00136 { 00137 bdd_manager *ddManager = applData->ddManager; 00138 st_table *inUseVars = applData->currInUseVars; 00139 int id,i,minLevel,size,used; 00140 int index,numIsfs; 00141 char *dummy; 00142 st_generator *stGen; 00143 bdd_node *bdd1,*bdd0; 00144 bdd_node **parameters; 00145 00146 minLevel = bdd_num_vars(ddManager); 00147 /* Find the topmost level among the SCC components SCC(Y,P) */ 00148 st_foreach_item(SCC,stGen,&bdd1,&bdd0) { 00149 int level1,level0,tempInt; 00150 level1 = bdd_get_level_from_id(ddManager,bdd_node_read_index(bdd1)); 00151 level0 = bdd_get_level_from_id(ddManager,bdd_node_read_index(bdd0)); 00152 tempInt = (level1 < level0) ? level1 : level0; 00153 minLevel = (minLevel < tempInt) ? minLevel : tempInt; 00154 } 00155 00156 numIsfs = st_count(SCC); 00157 size = bdd_num_vars(ddManager); 00158 used = st_count(inUseVars); 00159 00160 /* Allocate required number of new variables above minLevel */ 00161 if (size - used < numIsfs) { 00162 SpfdMddCreateVariables(ddManager,(numIsfs)-(size-used),minLevel); 00163 } 00164 00165 /* Assign the parameters */ 00166 size = bdd_num_vars(ddManager); 00167 index = numIsfs; 00168 parameters = ALLOC(bdd_node *,numIsfs); 00169 /* Assign the parameter variables */ 00170 for (i = 0; i < size; i++) { 00171 if (index == 0) 00172 break; 00173 id = bdd_get_id_from_level(ddManager,i); 00174 if (!st_lookup(inUseVars,(char *)(long)id,(char **)&dummy)) { 00175 parameters[numIsfs-index] = bdd_bdd_ith_var(ddManager,id); 00176 st_insert(inUseVars,(char *)(long)id,(char *)-1); 00177 index--; 00178 } 00179 } 00180 00181 return parameters; 00182 } /* End of SpfdComputeParameters */ 00183 00184 00192 bdd_node ** 00193 SpfdAllocateTemporaryVariables( 00194 bdd_manager *ddManager, 00195 st_table *inUseVars, 00196 int num) 00197 { 00198 int size,used,i,index,id; 00199 char *dummy; 00200 bdd_node **tempVars; 00201 00202 tempVars = ALLOC(bdd_node *,num); 00203 size = bdd_num_vars(ddManager); 00204 used = st_count(inUseVars); 00205 if (size - used < num) { 00206 /* Create variables at the end */ 00207 SpfdMddCreateVariables(ddManager,num-(size-used),size); 00208 } 00209 size = bdd_num_vars(ddManager); 00210 index = num; 00211 /* Assign the temporary variables */ 00212 for (i = size-1; i >= 0; i--) { 00213 if (index == 0) 00214 break; 00215 id = bdd_get_id_from_level(ddManager,i); 00216 if (!st_lookup(inUseVars,(char *)(long)id,(char **)&dummy)) { 00217 tempVars[num-index] = bdd_bdd_ith_var(ddManager,id); 00218 st_insert(inUseVars,(char *)(long)id,(char *)-1); 00219 index--; 00220 } 00221 } 00222 00223 return tempVars; 00224 } /* End of SpfdAllocateTemporaryVariables */ 00225 00226 00235 void 00236 SpfdAllocateOrReuseAuxVariables( 00237 Ntk_Network_t *network, 00238 SpfdApplData_t *applData) 00239 { 00240 st_table *currBddReq = applData->currBddReq; 00241 bdd_manager *ddManager = applData->ddManager; 00242 bdd_node *bdd1,*piSupport; 00243 int numBdds,piSize,regSize,size,newVars; 00244 int level,regNumVars; 00245 int numPiAlt,index; 00246 int *piIds; 00247 Ntk_Node_t *node; 00248 st_generator *stGen; 00249 st_table *inUseVars,*nodeToData,*piAltVars; 00250 lsGen gen; 00251 00252 numBdds = st_count(currBddReq); 00253 00254 /* Check if any region nodes are PIs */ 00255 piAltVars = st_init_table(st_numcmp,st_numhash); 00256 numPiAlt = 0; 00257 st_foreach_item(currBddReq,stGen,&node,&bdd1) { 00258 if (Ntk_NodeTestIsPrimaryInput(node)) { 00259 int id = Ntk_NodeReadMddId(node); 00260 st_insert(piAltVars,(char *)(long)id,(char *)(long)id); 00261 numPiAlt++; 00262 } 00263 } 00264 00265 /* Put the variable ids in piSupport in inUseVars */ 00266 inUseVars = st_init_table(st_numcmp,st_numhash); 00267 00268 /* To be on the safe side we do not reuse PI bdd ids */ 00269 piSize = Ntk_NetworkReadNumPrimaryInputs(network); 00270 piIds = ALLOC(int,piSize); 00271 index = 0; 00272 Ntk_NetworkForEachPrimaryInput(network,gen,node) { 00273 int id; 00274 id = Ntk_NodeReadMddId(node); 00275 st_insert(inUseVars,(char *)(long)id,(char *)-1); 00276 piIds[index] = id; 00277 index++; 00278 } 00279 bdd_ref(piSupport = bdd_indices_to_cube(ddManager,piIds,piSize)); 00280 FREE(piIds); 00281 00282 if (applData->currXCube) { 00283 (void) fprintf(vis_stdout, 00284 "** spfd warning: Possible memory leak.\n"); 00285 } 00286 applData->currXCube = piSupport; 00287 00288 regSize = numBdds; 00289 size = bdd_num_vars(ddManager); 00290 regNumVars = 2*regSize+piSize+numPiAlt; 00291 if (size < regNumVars) { 00292 newVars = regNumVars - size; 00293 SpfdMddCreateVariables(ddManager,newVars,0); 00294 } 00295 00296 /* Put the BDD ids of regionNodes and their immediate fanin in inUseVars */ 00297 st_foreach_item(currBddReq,stGen,&node,NIL(char *)) { 00298 st_insert(inUseVars,(char *)(long)Ntk_NodeReadMddId(node),(char *)-1); 00299 } 00300 00301 /* Assign auxillary ids to region nodes and their immediate fanin. */ 00302 nodeToData = applData->nodeToData; 00303 level = 0; 00304 size = bdd_num_vars(ddManager); 00305 st_foreach_item(currBddReq,stGen,&node,NIL(char *)) { 00306 int id; 00307 while (level < size) { 00308 id = bdd_get_id_from_level(ddManager,level); 00309 if (!st_lookup(inUseVars,(char *)(long)id,NIL(char *))) { 00310 SpfdNodeData_t *nodeData; 00311 st_lookup(nodeToData,(char *)node,&nodeData); 00312 nodeData->auxId = id; 00313 st_insert(inUseVars,(char *)(long)id,(char *)-1); 00314 level++; 00315 break; 00316 } 00317 level++; 00318 } 00319 } 00320 00321 /* Assign alternate ids (these are in addition to auxIds) to those nodes in 00322 currBddReq which are PIs */ 00323 st_foreach_item(currBddReq,stGen,&node,NIL(char *)) { 00324 if (Ntk_NodeTestIsPrimaryInput(node)) { 00325 int nodeId = Ntk_NodeReadMddId(node); 00326 while (level < size) { 00327 int id = bdd_get_id_from_level(ddManager,level); 00328 if (!st_lookup(inUseVars,(char *)(long)id,NIL(char *))) { 00329 st_insert(piAltVars,(char *)(long)nodeId,(char *)(long)id); 00330 st_insert(inUseVars,(char *)(long)id,(char *)-1); 00331 level++; 00332 break; 00333 } 00334 level++; 00335 } 00336 } 00337 } 00338 00339 if (applData->currInUseVars) { 00340 (void) fprintf(vis_stdout, 00341 "** spfd warning: Possible memory leak.\n"); 00342 } 00343 applData->currInUseVars = inUseVars; 00344 00345 if (applData->currPiAltVars) { 00346 (void) fprintf(vis_stdout, 00347 "** spfd warning: Possible memory leak.\n"); 00348 } 00349 applData->currPiAltVars = piAltVars; 00350 00351 return; 00352 00353 } /* End of SpfdAllocateOrReuseAuxVariables */ 00354 00355 00365 void 00366 SpfdOrderFaninOfRegionNodes( 00367 Ntk_Network_t *network, 00368 SpfdApplData_t *applData, 00369 int (*compareFunc)(const void *, const void *)) 00370 { 00371 SpfdNodeData_t *nodeData; 00372 st_table *nodeToData = applData->nodeToData; 00373 st_table *regionNodes = applData->currRegionNodes; 00374 st_generator *stGen; 00375 Ntk_Node_t *regNode,*fanin; 00376 int i,bound; 00377 boolean found; 00378 00379 st_foreach_item(regionNodes,stGen,®Node,NIL(char *)) { 00380 array_t *tempArray; 00381 /* Atleast one fanin of regNode should be in regionNodes */ 00382 found = FALSE; 00383 Ntk_NodeForEachFanin(regNode,i,fanin) { 00384 if (st_lookup(regionNodes,(char *)fanin,&bound) && 00385 !bound && 00386 !Ntk_NodeTestIsPrimaryInput(fanin) && 00387 !Ntk_NodeTestIsPrimaryOutput(fanin)) { 00388 found = TRUE; 00389 break; 00390 } 00391 } 00392 if (found) { 00393 tempArray = array_dup(Ntk_NodeReadFanins(regNode)); 00394 array_sort(tempArray,compareFunc); 00395 st_lookup(nodeToData,(char *)regNode,&nodeData); 00396 if (nodeData->faninOrder) { 00397 (void) fprintf(vis_stdout, 00398 "** spfd warning: Possible memory leak.\n"); 00399 } 00400 nodeData->faninOrder = tempArray; 00401 } 00402 } 00403 00404 return; 00405 } /* End of SpfdOrderFaninOfRegionNodes */ 00406 00407 00416 int 00417 SpfdSwitchedCapAndDepthCompare( 00418 const void *obj1, 00419 const void *obj2) 00420 { 00421 SpfdApplData_t *applData; 00422 st_table *regionNodes; 00423 Ntk_Node_t *node1,*node2; 00424 Ntk_Network_t *network; 00425 float weight1,weight2; 00426 float switch1,switch2; 00427 float load1,load2; 00428 int depth1,depth2; 00429 int status; 00430 int dummy; 00431 00432 node1 = *(Ntk_Node_t **)obj1; 00433 node2 = *(Ntk_Node_t **)obj2; 00434 assert(Ntk_NodeReadNetwork(node1) == Ntk_NodeReadNetwork(node2)); 00435 network = Ntk_NodeReadNetwork(node1); 00436 applData = (SpfdApplData_t *) Ntk_NetworkReadApplInfo(network, 00437 SPFD_NETWORK_APPL_KEY); 00438 regionNodes = applData->currRegionNodes; 00439 00440 status = st_lookup(regionNodes,(char *)node1,&dummy); 00441 if (!status || dummy || 00442 Ntk_NodeTestIsPrimaryOutput(node1) || 00443 Ntk_NodeTestIsPrimaryInput(node1)) { 00444 weight1 = -1.0; 00445 } else { 00446 switch1 = Truesim_NetworkReadNodeSwitchingProb(network,node1); 00447 load1 = Truesim_NetworkReadNodeLoad(network,node1); 00448 depth1 = Truesim_NetworkReadNodeDepth(network,node1); 00449 weight1 = spfdAlpha * load1 * switch1 + (1.0-spfdAlpha)*depth1; 00450 } 00451 00452 status = st_lookup(regionNodes,(char *)node2,&dummy); 00453 if (!status || dummy || 00454 Ntk_NodeTestIsPrimaryOutput(node2) || 00455 Ntk_NodeTestIsPrimaryInput(node2)) { 00456 weight2 = -1.0; 00457 } else { 00458 switch2 = Truesim_NetworkReadNodeSwitchingProb(network,node2); 00459 load2 = Truesim_NetworkReadNodeLoad(network,node2); 00460 depth2 = Truesim_NetworkReadNodeDepth(network,node2); 00461 weight2 = spfdAlpha * load2 * switch2 + (1.0-spfdAlpha)*depth2; 00462 } 00463 00464 if (weight1 > weight2) 00465 return -1; 00466 else if (weight1 == weight2) 00467 return 0; 00468 else 00469 return 1; 00470 00471 } /* End of SpfdSwitchedCapAndDepthCompare */ 00472 00473 00482 int 00483 SpfdFanoutCountAndDepthCompare( 00484 const void *obj1, 00485 const void *obj2) 00486 { 00487 SpfdApplData_t *applData; 00488 st_table *regionNodes; 00489 Ntk_Node_t *node1,*node2; 00490 Ntk_Network_t *network; 00491 float weight1,weight2; 00492 float load1,load2; 00493 int depth1,depth2; 00494 int status; 00495 int dummy; 00496 00497 node1 = *(Ntk_Node_t **)obj1; 00498 node2 = *(Ntk_Node_t **)obj2; 00499 assert(Ntk_NodeReadNetwork(node1) == Ntk_NodeReadNetwork(node2)); 00500 network = Ntk_NodeReadNetwork(node1); 00501 applData = (SpfdApplData_t *) Ntk_NetworkReadApplInfo(network, 00502 SPFD_NETWORK_APPL_KEY); 00503 regionNodes = applData->currRegionNodes; 00504 00505 status = st_lookup(regionNodes,(char *)node1,&dummy); 00506 if (!status || dummy || 00507 Ntk_NodeTestIsPrimaryOutput(node1) || 00508 Ntk_NodeTestIsPrimaryInput(node1)) { 00509 weight1 = -1.0; 00510 } else { 00511 load1 = Ntk_NodeReadNumFanouts(node1); 00512 depth1 = Truesim_NetworkReadNodeDepth(network,node1); 00513 weight1 = spfdAlpha * load1 + (1.0-spfdAlpha)*depth1; 00514 } 00515 00516 status = st_lookup(regionNodes,(char *)node2,&dummy); 00517 if (!status || dummy || 00518 Ntk_NodeTestIsPrimaryOutput(node2) || 00519 Ntk_NodeTestIsPrimaryInput(node2)) { 00520 weight2 = -1.0; 00521 } else { 00522 load2 = Ntk_NodeReadNumFanouts(node2); 00523 depth2 = Truesim_NetworkReadNodeDepth(network,node2); 00524 weight2 = spfdAlpha * load2 + (1.0-spfdAlpha)*depth2; 00525 } 00526 00527 if (weight1 > weight2) 00528 return -1; 00529 else if (weight1 == weight2) 00530 return 0; 00531 else 00532 return 1; 00533 00534 } /* End of SpfdFanoutContAndDepthCompare */ 00535 00536 00544 int 00545 SpfdDepthCompare( 00546 const void *obj1, 00547 const void *obj2) 00548 { 00549 Ntk_Network_t *network; 00550 Ntk_Node_t *node1 = *(Ntk_Node_t **)obj1; 00551 Ntk_Node_t *node2 = *(Ntk_Node_t **)obj2; 00552 int depth1,depth2; 00553 00554 assert(Ntk_NodeReadNetwork(node1) == Ntk_NodeReadNetwork(node2)); 00555 network = Ntk_NodeReadNetwork(node1); 00556 00557 depth1 = Truesim_NetworkReadNodeDepth(network,node1); 00558 depth2 = Truesim_NetworkReadNodeDepth(network,node2); 00559 00560 if (depth1 < depth2) 00561 return -1; 00562 else if (depth1 == depth2) 00563 return 0; 00564 else 00565 return 1; 00566 00567 } /* End of SpfdDepthCompare */ 00568 00569 00578 int 00579 SpfdDescendDepthCompare( 00580 const void *obj1, 00581 const void *obj2) 00582 { 00583 Ntk_Network_t *network; 00584 Ntk_Node_t *node1 = *(Ntk_Node_t **)obj1; 00585 Ntk_Node_t *node2 = *(Ntk_Node_t **)obj2; 00586 int depth1,depth2; 00587 00588 assert(Ntk_NodeReadNetwork(node1) == Ntk_NodeReadNetwork(node2)); 00589 network = Ntk_NodeReadNetwork(node1); 00590 00591 depth1 = Truesim_NetworkReadNodeDepth(network,node1); 00592 depth2 = Truesim_NetworkReadNodeDepth(network,node2); 00593 00594 if (depth1 > depth2) 00595 return -1; 00596 else if (depth1 == depth2) 00597 return 0; 00598 else 00599 return 1; 00600 00601 } /* End of SpfdDescendDepthCompare */ 00602 00603 00621 void 00622 SpfdMddCreateVariables(mdd_manager *mgr, 00623 int numVarsToBeAdded, 00624 int level) 00625 { 00626 array_t *mvar_values; 00627 array_t *mvar_names = NIL(array_t); 00628 array_t *mvar_strides = NIL(array_t); 00629 int i,two_values,idBeforeLevel,size; 00630 00631 if (level > (size = bdd_num_vars(mgr))) 00632 level = size; 00633 if (level <= 0) 00634 idBeforeLevel = bdd_get_id_from_level(mgr,0); 00635 else 00636 idBeforeLevel = bdd_get_id_from_level(mgr,level-1); 00637 00638 if (numVarsToBeAdded <= 0) return; 00639 00640 /* Create 2 mvar values 0,1 */ 00641 mvar_values = array_alloc(int, numVarsToBeAdded); 00642 00643 /* Assume we create only Bdd variables here */ 00644 two_values = 2; 00645 for(i = 0; i < numVarsToBeAdded; i++) { 00646 array_insert(int, mvar_values, i, two_values); 00647 } 00648 00649 /* creates the mdd variables and updates the mvar_list field */ 00650 mdd_create_variables_after(mgr, idBeforeLevel,mvar_values, 00651 mvar_names, mvar_strides); 00652 00653 array_free(mvar_values); 00654 00655 } /* End of SpfdMddCreateVariables */ 00656 00657 00671 bdd_node * 00672 SpfdAddEqual( 00673 bdd_manager *ddManager, 00674 bdd_node **f, 00675 bdd_node **g) 00676 { 00677 bdd_node *zero, *one; 00678 00679 zero = bdd_read_zero(ddManager); 00680 one = bdd_read_one(ddManager); 00681 00682 if(*f == *g) { 00683 return one; 00684 } 00685 00686 if(bdd_is_constant(*f) && bdd_is_constant(*g)) { 00687 return zero; 00688 } 00689 return NULL; 00690 } 00691 00699 int 00700 SpfdNetworkWriteBlifFile( 00701 Ntk_Network_t *network, 00702 char *fileName) 00703 { 00704 lsGen gen; 00705 Ntk_Node_t *node; 00706 FILE *fp; 00707 int nameLen; 00708 char *name; 00709 00710 if ((fp = Cmd_FileOpen(fileName,"w",NIL(char *),1)) == NIL(FILE)) { 00711 (void) fprintf(vis_stderr, 00712 "** spfd error: Could not open %s for writing.\n", 00713 fileName); 00714 return 0; 00715 } 00716 00717 (void) fprintf(fp,".model %s\n",Ntk_NetworkReadName(network)); 00718 (void) fprintf(fp,".inputs "); 00719 nameLen = 0; 00720 Ntk_NetworkForEachPrimaryInput(network,gen,node) { 00721 name = Ntk_NodeReadName(node); 00722 (void) fprintf(fp,"%s ",name); 00723 nameLen += (strlen(name)); 00724 if (nameLen > 65) { 00725 (void) fprintf(fp,"\\\n"); 00726 nameLen = 0; 00727 } 00728 } 00729 (void) fprintf(fp,"\n"); 00730 00731 nameLen = 0; 00732 (void) fprintf(fp,".outputs "); 00733 Ntk_NetworkForEachPrimaryOutput(network,gen,node) { 00734 name = Ntk_NodeReadName(node); 00735 (void) fprintf(fp,"%s ",name); 00736 nameLen += (strlen(name)); 00737 if (nameLen > 65) { 00738 (void) fprintf(fp,"\\\n"); 00739 nameLen = 0; 00740 } 00741 } 00742 (void) fprintf(fp,"\n"); 00743 00744 Ntk_NetworkForEachNode(network,gen,node) { 00745 if (!Ntk_NodeTestIsPrimaryInput(node)) { 00746 if (Ntk_NodeReadNumFanins(node) > 0 || 00747 Ntk_NodeReadNumFanouts(node) > 0) { 00748 Tbl_TableWriteBlifToFile(Ntk_NodeReadTable(node),fp); 00749 } else if (Ntk_NodeTestIsPrimaryOutput(node)) { 00750 /* Sometimes output node can be redundant. Very unlikely, 00751 but output it anyway because we cannot skip primary 00752 outputs of a network. */ 00753 (void) fprintf(fp,".names %s\n",Ntk_NodeReadName(node)); 00754 } 00755 } 00756 } 00757 00758 (void) fprintf(fp,".end\n"); 00759 00760 fclose(fp); 00761 00762 return 1; 00763 00764 } /* End of SpfdNetworkWriteBlifFile */ 00765 00766 00779 bdd_node * 00780 SpfdComputeNodeArrayRelation( 00781 SpfdApplData_t *applData, 00782 st_table *currBddReq, 00783 array_t *nodeBdds, 00784 array_t *nodeArray, 00785 boolean useMddIds, 00786 int *piSwap) 00787 { 00788 bdd_manager *ddManager = applData->ddManager; 00789 st_table *piAltVars = applData->currPiAltVars; 00790 Ntk_Node_t *node; 00791 array_t *idArray; 00792 bdd_node *ddTemp,*ddTemp2,*result; 00793 bdd_node *bdd1,*var; 00794 int j,id; 00795 00796 *piSwap = 0; 00797 00798 if (currBddReq) { 00799 nodeBdds = array_alloc(bdd_node *,0); 00800 arrayForEachItem(Ntk_Node_t *,nodeArray,j,node) { 00801 st_lookup(currBddReq,(char *)node,&bdd1); 00802 array_insert_last(bdd_node *,nodeBdds,bdd1); 00803 } 00804 } 00805 idArray = array_alloc(int,0); 00806 if (useMddIds) { /* Use node MDD Ids or alternate Ids for PIs */ 00807 int altId; 00808 arrayForEachItem(Ntk_Node_t *,nodeArray,j,node) { 00809 id = Ntk_NodeReadMddId(node); 00810 if (Ntk_NodeTestIsPrimaryInput(node)) { 00811 st_lookup(piAltVars,(char *)(long)id,&altId); 00812 array_insert_last(int,idArray,altId); 00813 *piSwap = 1; 00814 } else { 00815 array_insert_last(int,idArray,id); 00816 } 00817 } 00818 } else { /* Use node Aux Ids */ 00819 arrayForEachItem(Ntk_Node_t *,nodeArray,j,node) { 00820 array_insert_last(int,idArray,SpfdNodeReadAuxId(applData,node)); 00821 } 00822 } 00823 bdd_ref(result = bdd_not_bdd_node(bdd_read_logic_zero(ddManager))); 00824 arrayForEachItem(Ntk_Node_t *,nodeArray,j,node) { 00825 bdd1 = array_fetch(bdd_node *,nodeBdds,j); 00826 var = bdd_bdd_ith_var(ddManager,array_fetch(int,idArray,j)); 00827 bdd_ref(ddTemp = bdd_bdd_xnor(ddManager,var,bdd1)); 00828 bdd_ref(ddTemp2 = bdd_bdd_and(ddManager,ddTemp,result)); 00829 bdd_recursive_deref(ddManager,result); 00830 bdd_recursive_deref(ddManager,ddTemp); 00831 result = ddTemp2; 00832 } 00833 00834 if (currBddReq) 00835 array_free(nodeBdds); 00836 array_free(idArray); 00837 00838 return result; 00839 00840 } /* End of SpfdComputeNodeArrayRelation */ 00841 00842 00851 bdd_node * 00852 SpfdSwapPiAndAltPi( 00853 SpfdApplData_t *applData, 00854 bdd_node *fun) 00855 { 00856 bdd_manager *ddManager = applData->ddManager; 00857 bdd_node **fromVars; 00858 bdd_node **toVars; 00859 bdd_node *ddTemp; 00860 st_table *piAltVars = applData->currPiAltVars; 00861 st_generator *stGen; 00862 int i,num = st_count(piAltVars); 00863 int id,altId; 00864 00865 fromVars = ALLOC(bdd_node *,num); 00866 toVars = ALLOC(bdd_node *,num); 00867 i = 0; 00868 st_foreach_item_int(piAltVars,stGen,&id,&altId) { 00869 fromVars[i] = bdd_bdd_ith_var(ddManager,altId); 00870 toVars[i] = bdd_bdd_ith_var(ddManager,id); 00871 i++; 00872 } 00873 bdd_ref(ddTemp = bdd_bdd_swap_variables(ddManager,fun,fromVars,toVars,num)); 00874 00875 FREE(fromVars); 00876 FREE(toVars); 00877 00878 return ddTemp; 00879 } /* End of SpfdSwapPiAndAltPi */ 00880 00881 00890 bdd_node * 00891 SpfdNodeReadLocalBdd( 00892 Ntk_Network_t *network, 00893 Ntk_Node_t *node) 00894 { 00895 vertex_t *vertexPtr; 00896 Mvf_Function_t *mvf; 00897 graph_t *partition = 00898 (graph_t *) Ntk_NetworkReadApplInfo(network,PART_NETWORK_APPL_KEY); 00899 bdd_node *bdd1; 00900 00901 vertexPtr = Part_PartitionFindVertexByMddId(partition, 00902 Ntk_NodeReadMddId(node)); 00903 mvf = Part_VertexReadFunction(vertexPtr); 00904 bdd1 = bdd_extract_node_as_is(array_fetch(bdd_t *,mvf,1)); 00905 00906 return bdd1; 00907 } 00908 00909 00917 array_t * 00918 SpfdFetchInternalPatternArray( 00919 array_t *patternArray, 00920 int percent, 00921 double randomValue) 00922 { 00923 array_t *returnArray; 00924 int numVectors,start,end,i; 00925 00926 /* For internal simulations use 1/10th of the total input pattern vectors */ 00927 numVectors = array_n(patternArray); 00928 00929 start = (int)(randomValue*(double)numVectors); 00930 end = start + (int)(numVectors*percent/100); 00931 00932 returnArray = array_alloc(char *,0); 00933 if (end == start) { 00934 array_insert_last(char *,returnArray, 00935 array_fetch(char *,patternArray,start)); 00936 return returnArray; 00937 } 00938 00939 /* Allocate end - start + 1 size of returnArray */ 00940 for (i = start; i < end; i++) { 00941 array_insert_last(char *,returnArray, 00942 array_fetch(char *,patternArray,i)); 00943 } 00944 00945 return returnArray; 00946 } 00947 00960 Ntk_Node_t * 00961 SpfdFindNode( 00962 Ntk_Network_t *network, 00963 array_t *nodeArray) 00964 { 00965 Ntk_Node_t *node1,*maxNode = NIL(Ntk_Node_t); 00966 int i; 00967 00968 if (!array_n(nodeArray)) 00969 return maxNode; 00970 00971 if (spfdSortNodes == RANDOM) { 00972 int index,num; 00973 float randomValue; 00974 00975 num = array_n(nodeArray); 00976 if (num < 5) { 00977 index = 0; 00978 } else { 00979 randomValue = ((double)util_random()/(double)(MODULUS1 - 2)); 00980 index = (int) (randomValue * (double)num); 00981 } 00982 maxNode = array_fetch(Ntk_Node_t *,nodeArray,index); 00983 } else if (spfdSortNodes == MAXSWCAP) { 00984 float swc1,maxSwc; 00985 float switch1,load1; 00986 00987 maxSwc = 0.0; 00988 arrayForEachItem(Ntk_Node_t *,nodeArray,i,node1) { 00989 switch1 = Truesim_NetworkReadNodeSwitchingProb(network,node1); 00990 load1 = Truesim_NetworkReadNodeLoad(network,node1); 00991 swc1 = load1 * switch1; 00992 00993 if (swc1 > maxSwc) { 00994 maxNode = node1; 00995 maxSwc = swc1; 00996 } 00997 } 00998 } else if (spfdSortNodes == MINSWCAP) { 00999 float swc1,maxSwc; 01000 float switch1,load1; 01001 01002 maxSwc = MAXINT; 01003 arrayForEachItem(Ntk_Node_t *,nodeArray,i,node1) { 01004 switch1 = Truesim_NetworkReadNodeSwitchingProb(network,node1); 01005 load1 = Truesim_NetworkReadNodeLoad(network,node1); 01006 swc1 = load1 * switch1; 01007 01008 if (swc1 < maxSwc) { 01009 maxNode = node1; 01010 maxSwc = swc1; 01011 } 01012 } 01013 } else if (spfdSortNodes == MAXFANOUT) { 01014 int numFanout,maxFanout; 01015 01016 maxFanout = 0; 01017 arrayForEachItem(Ntk_Node_t *,nodeArray,i,node1) { 01018 numFanout = Ntk_NodeReadNumFanouts(node1); 01019 if (numFanout > maxFanout) { 01020 maxNode = node1; 01021 maxFanout = numFanout; 01022 } 01023 } 01024 } else if (spfdSortNodes == MINFANOUT) { 01025 int numFanout,minFanout; 01026 01027 minFanout = MAXINT; 01028 arrayForEachItem(Ntk_Node_t *,nodeArray,i,node1) { 01029 numFanout = Ntk_NodeReadNumFanouts(node1); 01030 if (numFanout < minFanout) { 01031 maxNode = node1; 01032 minFanout = numFanout; 01033 } 01034 } 01035 } 01036 01037 return maxNode; 01038 01039 } /* End of SpfdFindNode */ 01040 01041 01042 /*---------------------------------------------------------------------------*/ 01043 /* Definition of static functions */ 01044 /*---------------------------------------------------------------------------*/ 01045