VIS

src/spfd/spfdUtil.c

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