VIS

src/truesim/truesimUtil.c

Go to the documentation of this file.
00001 
00023 #include "truesimInt.h"
00024 
00025 /*---------------------------------------------------------------------------*/
00026 /* Constant declarations                                                     */
00027 /*---------------------------------------------------------------------------*/
00028 
00029 #define MAX_LENGTH 20000 /* Max. length of a string while reading a file */
00030 #define UNASSIGNED_DEPTH -1 /* Unassigned depth for a node */
00031 #define TOKENS " \t\n" /* For parsing delay-load file */
00032 #define DEFAULT_PROB 0.5
00033 
00034 /*---------------------------------------------------------------------------*/
00035 /* Type declarations                                                         */
00036 /*---------------------------------------------------------------------------*/
00037 
00038 
00039 /*---------------------------------------------------------------------------*/
00040 /* Structure declarations                                                    */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 
00044 /*---------------------------------------------------------------------------*/
00045 /* Variable declarations                                                     */
00046 /*---------------------------------------------------------------------------*/
00047 
00048 extern int truesimVerbose;
00049 
00052 /*---------------------------------------------------------------------------*/
00053 /* Static function prototypes                                                */
00054 /*---------------------------------------------------------------------------*/
00055 
00056 static void GetInputs(char *buffer, Ntk_Network_t *network, array_t *inputArray);
00057 static void GetPatternVectors(FILE *fp, int vecLen, array_t *patternArray);
00058 static long NodeComputeDepth(Ntk_Node_t * node);
00059 static long NodeReadDepth(Ntk_Node_t * node);
00060 static void NodeSetDepth(Ntk_Node_t * node, long depth);
00061 static enum st_retval stFloatFree(char *key, char *value, char *arg);
00062 static float computeProbabilityRecur(Ntk_Network_t *network, st_table *nodeToSimTable, st_table *seenTable, bdd_node *bddNode);
00063 
00067 /*---------------------------------------------------------------------------*/
00068 /* Definition of exported functions                                          */
00069 /*---------------------------------------------------------------------------*/
00070 
00081 void
00082 Truesim_NetworkUpdateNodeTopologicalDepth(
00083   Ntk_Network_t *network)
00084 {
00085   array_t *depthArray,*levelArray;
00086   Ntk_Node_t *node;
00087   st_table *nodeToSimTable;
00088   Truesim_Info_t *simInfo;
00089   int i,j;
00090   
00091   simInfo = (Truesim_Info_t *)
00092     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00093   nodeToSimTable = simInfo->nodeToSimTable;
00094   depthArray = simInfo->depthArray;
00095 
00096   if (depthArray) {
00097     arrayForEachItem(array_t *,depthArray,i,levelArray) {
00098       array_free(levelArray);
00099     }
00100     array_free(depthArray);
00101   }
00102   
00103   depthArray = Truesim_NetworkComputeNodeDepths(network);
00104   simInfo->depthArray = depthArray;
00105   arrayForEachItem(array_t *,depthArray,i,levelArray) {
00106     arrayForEachItem(Ntk_Node_t *,levelArray,j,node) {
00107       TrueSim_t *sim;
00108       st_lookup(nodeToSimTable,(char *)node,&sim);
00109       sim->depth = i;
00110     }
00111   }
00112 
00113   return;
00114 } /* End of Truesim_NetworkUpdateNodeTopologicalDepth */
00115 
00116 
00126 void
00127 Truesim_ReadInputProbabilities(
00128   Ntk_Network_t *network,
00129   char *probFile,
00130   array_t *inputArray,
00131   array_t *probArray)
00132 {
00133   char str[MAX_LENGTH];
00134   float prob;
00135   FILE *fp;
00136   Ntk_Node_t *node;
00137 
00138   if(probFile == 0 || probFile[0] == '\0') {
00139     (void) fprintf(vis_stderr,
00140                    "** truesim warning: Probability file was not specified.\n");
00141     return;    
00142   }
00143   /* Read the probabilities. */
00144   if ((fp = Cmd_FileOpen(probFile,"r",NIL(char *),1)) == NIL(FILE)) {
00145     lsGen gen;
00146     (void) fprintf(vis_stderr,
00147                    "** truesim warning: Could not open %s for reading.\n", probFile);
00148     (void) fprintf(vis_stderr,
00149                    "** truesim warning: Using probability as 0.5 for all inputs.\n");
00150     Ntk_NetworkForEachPrimaryInput(network,gen,node) {
00151       array_insert_last(float,probArray,DEFAULT_PROB);
00152       array_insert_last(Ntk_Node_t *,inputArray,node);      
00153     }
00154   } else {
00155     while (fscanf(fp,"%s %f\n",str,&prob) != EOF) {
00156       node = Ntk_NetworkFindNodeByName(network,str);
00157       if (!node || !Ntk_NodeTestIsPrimaryInput(node)) {
00158         (void) fprintf(vis_stderr,
00159                        "** truesim warning: No PI with name %s. Ignored.\n",str);
00160       } else {
00161         if (prob > 1.0 || prob < 0.0) {
00162           (void) fprintf(vis_stderr,
00163                          "** truesim warning: %s has invalid prob. %f\n",
00164                          str,prob);
00165           (void) fprintf(vis_stderr,
00166                         "** truesim warning: Assuming 0.5 instead\n");
00167           prob = DEFAULT_PROB;
00168         }
00169         array_insert_last(float,probArray,prob);
00170         array_insert_last(Ntk_Node_t *,inputArray,node);
00171       }
00172     }
00173     fclose(fp);
00174   }
00175 } /* End of Truesim_ReadInputProbabilities */
00176 
00177 
00188 void
00189 Truesim_GeneratePrimaryInputProbs(
00190   Ntk_Network_t *network,
00191   char *probFile)
00192 {
00193   FILE *fp;
00194   Ntk_Node_t *node;
00195   lsGen gen;
00196 
00197   if ((fp = Cmd_FileOpen(probFile,"w",NIL(char *),1)) == NIL(FILE)) {
00198     fprintf(vis_stderr,"** truesim error: Cannot open %s for writing\n",probFile);
00199     return;
00200   }
00201   Ntk_NetworkForEachPrimaryInput(network,gen,node) {
00202     fprintf(fp,"%s %f\n",
00203             Ntk_NodeReadName(node),
00204             ((double)util_random()/(double)(MODULUS1 - 2)));
00205   }
00206   fclose(fp);
00207 
00208 } /* End of Truesim_GeneratePrimaryInputProbs */
00209 
00210 
00239 int
00240 Truesim_ReadSimulationVectors(
00241   Ntk_Network_t *network,
00242   char *simFile,
00243   array_t *inputArray,
00244   array_t *patternArray)
00245 {
00246 
00247   char buffer[MAX_LENGTH];
00248   FILE *fp;
00249   boolean readInputs;
00250   
00251   fp = Cmd_FileOpen(simFile,"r",NIL(char *),1);
00252   if (fp == NIL(FILE)) {
00253     (void) fprintf(vis_stderr,
00254                    "** truesim error: Cannot open %s for reading sim. vectors.\n",
00255                    simFile);
00256     return 0;
00257   }
00258 
00259   readInputs = TRUE;
00260   while (fgets(buffer,MAX_LENGTH - 1,fp) != NULL) {
00261     if (buffer[0] == '#' || buffer[0] == '\n') 
00262       continue;
00263     if (buffer[0] == '.' && buffer[1] == 'i') {
00264       if (!readInputs) {
00265         (void) fprintf(vis_stderr,
00266                        "** spfd error: .i statement encountered earlier.\n");
00267         fclose(fp);
00268         return 0;
00269       }
00270       GetInputs(buffer,network,inputArray);
00271       readInputs = FALSE;
00272     } else if (buffer[0] == '.' && buffer[1] == 's') {
00273         int vecLen = array_n(inputArray);
00274         if (!vecLen) {
00275           /* Error reading pattern file. */
00276           fclose(fp);
00277           return 0;
00278         }
00279         GetPatternVectors(fp,vecLen,patternArray);
00280         break;
00281     } else {
00282       (void) fprintf(vis_stdout,
00283                      "** spfd warning: Skipping %s\n",buffer);
00284     }
00285   } /* End of while */
00286   fclose(fp);
00287 
00288   return 1;
00289 } /* End of Truesim_ReadSimulationVectors */
00290 
00291 
00306 array_t *
00307 Truesim_GenerateRandomVectors(
00308   Ntk_Network_t *network,
00309   array_t *probArray,
00310   array_t *patternArray,
00311   int numInputs,
00312   int N)
00313 {
00314   char *strPtr;
00315   float prob;
00316   double randomValue;
00317   int i,j;
00318 
00319   /* We generate N+1 vectors as the first one is an initialization vector */
00320   for (i = 0; i <= N; i++) {
00321     strPtr = ALLOC(char,numInputs+1);
00322     strPtr[numInputs] = '\0';
00323     for (j = 0; j < numInputs; j++) {
00324       prob = array_fetch(float,probArray,j);
00325       randomValue = ((double)util_random()/(double)(MODULUS1 - 2));
00326       if ((double) prob < randomValue)
00327         strPtr[j] = '0';
00328       else 
00329         strPtr[j] = '1';
00330     }
00331     array_insert_last(char *,patternArray,strPtr);
00332   }
00333   return patternArray;
00334 } /* End of Truesim_GenerateRandomVectors */
00335 
00336 
00346 void
00347 Truesim_DumpSimulationVectors(
00348   Ntk_Network_t *network,                         
00349   array_t *inputArray,
00350   array_t *patternArray,
00351   char *outFile)
00352 {
00353   FILE *fp;
00354   int i; unsigned int j;
00355   char *str;
00356   Ntk_Node_t *node;
00357   
00358   if ((fp = Cmd_FileOpen(outFile,"w",NIL(char *),1)) == NIL(FILE)) {
00359     fprintf(vis_stderr,
00360             "** truesim error: Could not open %s for writing\n",outFile);
00361     return;
00362   }
00363   /* Print the intput array */
00364   fprintf(fp,".i ");
00365   arrayForEachItem(Ntk_Node_t *,inputArray,i,node) {
00366     fprintf(fp,"%s ",Ntk_NodeReadName(node));
00367   }
00368   fprintf(fp,"\n");
00369 
00370   /* Print the pattern vectors */
00371   fprintf(fp,".s\n");
00372   arrayForEachItem(char *,patternArray,i,str) {
00373     for (j = 0; j < strlen(str); j++)
00374       fprintf(fp,"%c ",str[j]);
00375     fprintf(fp,";\n");
00376   }
00377   fclose(fp);
00378 } /* End of Truesim_DumpSimulationVectors */
00379 
00380 
00404 array_t *
00405 Truesim_NetworkComputeNodeDepths(
00406   Ntk_Network_t *network)
00407 {
00408   lsList rootList;
00409   lsGen       gen;
00410   Ntk_Node_t *node;
00411   long maxDepth;
00412   int i;
00413   array_t *tempArray,*depthArray;
00414   long noDepthCount = 0;
00415 
00416   rootList = Ntk_NetworkReadPrimaryOutputs(network);
00417   
00418   /* Initialize the depth of each node to unassigned.  */
00419   Ntk_NetworkForEachNode(network, gen, node) {
00420     NodeSetDepth(node, UNASSIGNED_DEPTH);
00421   }
00422 
00423   /* Start the recursive computation from each root.  */
00424   lsForEachItem(rootList, gen, node) {
00425     (void) NodeComputeDepth(node);
00426   }
00427 
00428   /* Now segregate the nodes according to their depth */
00429   /* Find the maximum depth */
00430   maxDepth = UNASSIGNED_DEPTH;
00431   lsForEachItem(rootList,gen,node) {
00432     long depth = NodeReadDepth(node);
00433     if (depth > maxDepth)
00434       maxDepth = depth;
00435   }
00436   /* Put the nodes in an array according to their depths. */
00437   depthArray = array_alloc(array_t *, maxDepth+1);
00438   for (i = 0; i < maxDepth+1; i++) {
00439     tempArray = array_alloc(Ntk_Node_t *, 0);
00440     array_insert_last(array_t *,depthArray,tempArray);
00441   }
00442   Ntk_NetworkForEachNode(network,gen,node) {
00443     long depth = NodeReadDepth(node);
00444     array_t *temp = NIL(array_t);
00445 
00446     if (depth != UNASSIGNED_DEPTH) {
00447       temp = array_fetch(array_t *,depthArray,depth);
00448       array_insert_last(Ntk_Node_t *,temp,node);
00449     }else
00450       noDepthCount++;
00451   }
00452   if (noDepthCount > 0)
00453     fprintf(vis_stderr, "Truesim Warning: %ld nodes have no computed depth.\n",
00454             noDepthCount);
00455 
00456   return depthArray;
00457 }
00458 
00459 
00469 int
00470 Truesim_NetworkReadNodeDepth(
00471   Ntk_Network_t *network,
00472   Ntk_Node_t *node)
00473 {
00474   Truesim_Info_t *simInfo;
00475   st_table *nodeToSimTable;
00476   TrueSim_t *sim;
00477   
00478   simInfo = (Truesim_Info_t *)
00479     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00480   nodeToSimTable = simInfo->nodeToSimTable;
00481 
00482   if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00483     return TRUESIM_ERROR_VALUE;
00484   } else {
00485     return sim->depth;
00486   }
00487   
00488 } /* End of Truesim_NetworkReadNodeDepth */
00489 
00490 
00500 float
00501 Truesim_NetworkReadNodeProbability(
00502   Ntk_Network_t *network,
00503   Ntk_Node_t *node)
00504 {
00505   Truesim_Info_t *simInfo;
00506   st_table *nodeToSimTable;
00507   TrueSim_t *sim;
00508   
00509   simInfo = (Truesim_Info_t *)
00510     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00511   nodeToSimTable = simInfo->nodeToSimTable;
00512 
00513   if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00514     return (float) TRUESIM_ERROR_VALUE;
00515   } else {
00516     return sim->prob;
00517   }
00518   
00519 } /* End of Truesim_NetworkReadNodeProbability */
00520 
00521 
00531 float
00532 Truesim_NetworkReadNodeSwitchingProb(
00533   Ntk_Network_t *network,
00534   Ntk_Node_t *node)
00535 {
00536   Truesim_Info_t *simInfo;
00537   st_table *nodeToSimTable;
00538   TrueSim_t *sim;
00539   
00540   simInfo = (Truesim_Info_t *)
00541     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00542   nodeToSimTable = simInfo->nodeToSimTable;
00543 
00544   if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00545     return (float) TRUESIM_ERROR_VALUE;
00546   } else {
00547     return sim->switching;
00548   }
00549   
00550 } /* End of Truesim_NetworkReadNodeSwitchingProb */
00551 
00552 
00562 float
00563 Truesim_NetworkReadNodeLoad(
00564   Ntk_Network_t *network,
00565   Ntk_Node_t *node)
00566 {
00567   Truesim_Info_t *simInfo;
00568   st_table *nodeToSimTable;
00569   TrueSim_t *sim;
00570   
00571   simInfo = (Truesim_Info_t *)
00572     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00573   nodeToSimTable = simInfo->nodeToSimTable;
00574 
00575   if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00576     return (float) TRUESIM_ERROR_VALUE;
00577   } else {
00578     return sim->load;
00579   }
00580   
00581 } /* End of Truesim_NetworkReadNodeLoad */
00582 
00583 
00593 float
00594 Truesim_NetworkReadNodeDelay(
00595   Ntk_Network_t *network,
00596   Ntk_Node_t *node)
00597 {
00598   Truesim_Info_t *simInfo;
00599   st_table *nodeToSimTable;
00600   TrueSim_t *sim;
00601   
00602   simInfo = (Truesim_Info_t *)
00603     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00604   nodeToSimTable = simInfo->nodeToSimTable;
00605 
00606   if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00607     return (float) TRUESIM_ERROR_VALUE;
00608   } else {
00609     return sim->delay;
00610   }
00611   
00612 } /* End of Truesim_NetworkReadNodeDelay */
00613 
00614 
00624 boolean
00625 Truesim_NetworkSetNodeLoad(
00626   Ntk_Network_t *network,
00627   Ntk_Node_t *node,
00628   float load)
00629 {
00630   Truesim_Info_t *simInfo;
00631   st_table *nodeToSimTable;
00632   TrueSim_t *sim;
00633   
00634   simInfo = (Truesim_Info_t *)
00635     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00636   if (!simInfo)
00637     goto error;
00638   
00639   nodeToSimTable = simInfo->nodeToSimTable;
00640   if (!nodeToSimTable)
00641     goto error;
00642   
00643   if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00644     goto error;
00645   } else {
00646     sim->load = load;
00647   }
00648   return TRUE;
00649 
00650  error:
00651   (void) fprintf(vis_stderr,
00652                  "** truesim error: Network not initialized for simulation.\n");
00653   (void) fprintf(vis_stderr,
00654                  "** truesim error: Call Truesim_InitializeSimulation.\n");
00655   return FALSE;
00656   
00657 } /* End of Truesim_NetworkSetNodeLoad */
00658 
00659 
00669 boolean
00670 Truesim_NetworkSetNodeDelay(
00671   Ntk_Network_t *network,
00672   Ntk_Node_t *node,
00673   float delay)
00674 {
00675   Truesim_Info_t *simInfo;
00676   st_table *nodeToSimTable;
00677   TrueSim_t *sim;
00678   
00679   simInfo = (Truesim_Info_t *)
00680     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00681   if (!simInfo)
00682     goto error;
00683   
00684   nodeToSimTable = simInfo->nodeToSimTable;
00685   if (!nodeToSimTable)
00686     goto error;
00687   
00688   if (!st_lookup(nodeToSimTable,node,&sim)) {
00689     goto error;
00690   } else {
00691     sim->delay = delay;
00692   }
00693   return TRUE;
00694 
00695  error:
00696   (void) fprintf(vis_stderr,
00697                  "** truesim error: Network not initialized for simulation.\n");
00698   (void) fprintf(vis_stderr,
00699                  "** truesim error: Call Truesim_InitializeSimulation.\n");
00700   return FALSE;
00701   
00702 } /* End of Truesim_NetworkSetNodeDelay */
00703 
00704 
00714 boolean
00715 Truesim_NetworkSetNodeStaticProb(
00716   Ntk_Network_t *network,
00717   Ntk_Node_t *node,
00718   float prob)
00719 {
00720   Truesim_Info_t *simInfo;
00721   st_table *nodeToSimTable;
00722   TrueSim_t *sim;
00723   
00724   simInfo = (Truesim_Info_t *)
00725     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00726   if (!simInfo)
00727     goto error;
00728   
00729   nodeToSimTable = simInfo->nodeToSimTable;
00730   if (!nodeToSimTable)
00731     goto error;
00732   
00733   if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00734     goto error;
00735   } else {
00736     sim->prob = prob;
00737   }
00738   return TRUE;
00739 
00740  error:
00741   (void) fprintf(vis_stderr,
00742                  "** truesim error: Network not initialized for simulation.\n");
00743   (void) fprintf(vis_stderr,
00744                  "** truesim error: Call Truesim_InitializeSimulation.\n");
00745   return FALSE;
00746   
00747 } /* End of Truesim_NetworkSetNodeStaticProb */
00748 
00749 
00759 boolean
00760 Truesim_NetworkSetNodeSwitchingProb(
00761   Ntk_Network_t *network,
00762   Ntk_Node_t *node,
00763   float switching)
00764 {
00765   Truesim_Info_t *simInfo;
00766   st_table *nodeToSimTable;
00767   TrueSim_t *sim;
00768   
00769   simInfo = (Truesim_Info_t *)
00770     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00771   if (!simInfo)
00772     goto error;
00773   
00774   nodeToSimTable = simInfo->nodeToSimTable;
00775   if (!nodeToSimTable)
00776     goto error;
00777   
00778   if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00779     goto error;
00780   } else {
00781     sim->switching = switching;
00782   }
00783   return TRUE;
00784 
00785  error:
00786   (void) fprintf(vis_stderr,
00787                  "** truesim error: Network not initialized for simulation.\n");
00788   (void) fprintf(vis_stderr,
00789                  "** truesim error: Call Truesim_InitializeSimulation.\n");
00790   return FALSE;
00791   
00792 } /* End of Truesim_NetworkSetNodeSwitchingProb */
00793 
00794 
00806 float
00807 Truesim_BddNodeComputeProbability(
00808   Ntk_Network_t *network,
00809   bdd_node *func)
00810 {
00811   bdd_manager *ddManager = Ntk_NetworkReadMddManager(network);
00812   Truesim_Info_t *simInfo;
00813   st_table *nodeToSimTable;
00814   float prob,*dummy;
00815   st_table *table;
00816   bdd_node *one,*zero;
00817   
00818   simInfo = (Truesim_Info_t *)
00819     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00820   nodeToSimTable = simInfo->nodeToSimTable;
00821 
00822   one = bdd_read_one(ddManager);
00823   zero = bdd_read_logic_zero(ddManager);
00824   
00825   if (func == zero)
00826     return 0.0;
00827   if (func == one)
00828     return 1.0;
00829 
00830   table = st_init_table(st_ptrcmp,st_ptrhash);
00831   dummy = ALLOC(float,1);
00832   *dummy = 1.0;
00833   st_insert(table,(char *)one,(char *)dummy);
00834 
00835   prob = computeProbabilityRecur(network,nodeToSimTable,table,func);
00836   st_foreach(table,stFloatFree,NIL(char));
00837   st_free_table(table);
00838 
00839   return prob;
00840   
00841 } /* End of Truesim_BddNodeComputeProbability */
00842 
00843 /*---------------------------------------------------------------------------*/
00844 /* Definition of internal functions                                          */
00845 /*---------------------------------------------------------------------------*/
00861 char 
00862 TruesimEvaluateNode(
00863   Ntk_Node_t *node,
00864   graph_t *partition,
00865   bdd_manager *ddManager,
00866   st_table *nodeToSimTable)
00867 {
00868   bdd_t *faninBdd,*nodeBdd,*tempBdd;
00869   vertex_t *vertex;
00870   Mvf_Function_t *nodeMvf;
00871   char next;
00872   
00873   /* Compute the cube for the fanin of node. For ex. if y = a + b, and a =
00874   '1' and b = '0', the cube faninBdd is ab' */
00875   faninBdd = TruesimComputeFaninMinterm(ddManager,node,nodeToSimTable);
00876   vertex = Part_PartitionFindVertexByMddId(partition,
00877                                            Ntk_NodeReadMddId(node));
00878   nodeMvf = Part_VertexReadFunction(vertex);
00879   nodeBdd = array_fetch(bdd_t *,nodeMvf,1);
00880 
00881   /* Evaluate the node */
00882   tempBdd = bdd_cofactor(nodeBdd,faninBdd);
00883   next = bdd_is_tautology(tempBdd,TRUE) ? '1' : '0';
00884 
00885   bdd_free(tempBdd);
00886   bdd_free(faninBdd);
00887   
00888   return next;
00889   
00890 } /* End of TruesimEvaluateNode */
00891 
00892 
00902 st_table *
00903 TruesimNetworkReadSimTable(
00904   Ntk_Network_t *network)
00905 {
00906   Truesim_Info_t *simInfo;
00907 
00908   simInfo = (Truesim_Info_t *)
00909     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00910 
00911   return simInfo->nodeToSimTable;
00912   
00913 } /* End of TruesimNetworkReadSimTable */
00914 
00915 
00925 array_t *
00926 TruesimNetworkReadDepthArray(Ntk_Network_t *network)
00927 {
00928   Truesim_Info_t *simInfo;
00929 
00930   simInfo = (Truesim_Info_t *)
00931     Ntk_NetworkReadApplInfo(network,TRUESIM_NETWORK_APPL_KEY);
00932   return simInfo->depthArray;
00933   
00934 }
00935 
00936 
00946 void
00947 TruesimInitializeActivityFields(
00948   Ntk_Network_t *network,                        
00949   st_table *nodeToSimTable)
00950 {
00951   Ntk_Node_t *node;
00952   lsGen gen;
00953 
00954   Ntk_NetworkForEachNode(network,gen,node) {
00955     TrueSim_t *sim;
00956     if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
00957       (void) fprintf(vis_stderr,"** truesim fatal: In TruesimInitializeActitivyFields\n");
00958       assert(0);
00959     }
00960     sim->value = '0';
00961     sim->prob = 0.0;
00962     sim->switching = 0.0;
00963     sim->event = NIL(Event);
00964   }
00965 } /* End of TruesimInitializeActivityFields */
00966 
00967 
00982 bdd_t *
00983 TruesimComputeFaninMinterm(
00984   bdd_manager *ddManager,
00985   Ntk_Node_t *node,
00986   st_table *nodeToSimTable)
00987 {
00988   int numFanin = Ntk_NodeReadNumFanins(node);
00989   int *phase;
00990   bdd_node **vars,*temp;
00991   Ntk_Node_t *fanin;
00992   TrueSim_t *sim;
00993   int i;
00994 
00995   vars = ALLOC(bdd_node *,numFanin);
00996   phase = ALLOC(int,numFanin);
00997   Ntk_NodeForEachFanin(node,i,fanin) {
00998     int id;
00999 
01000     if (!st_lookup(nodeToSimTable,(char *)fanin,&sim)) {
01001       (void) fprintf(vis_stderr,"** truesim fatal: In TruesimComputeFaninMinterm\n");      
01002       assert(0);
01003     }
01004     id = Ntk_NodeReadMddId(fanin);
01005     vars[i] = bdd_bdd_ith_var(ddManager,id);
01006     phase[i] = (sim->value == '1') ? 1:0;
01007   }
01008   temp = bdd_bdd_compute_cube(ddManager,vars,phase,numFanin);
01009   bdd_ref(temp);
01010 
01011   FREE(phase);
01012   FREE(vars);
01013 
01014   return (bdd_construct_bdd_t(ddManager,temp));
01015 
01016 } /* End of TruesimComputeFaninMinterm */
01017 
01018 
01028 void
01029 TruesimPrintNameHeader(Ntk_Network_t *network)
01030 {
01031   lsGen gen;
01032   Ntk_Node_t *node;
01033 
01034   /* Print PIs first */
01035   Ntk_NetworkForEachPrimaryInput(network,gen,node) {
01036     (void) fprintf(vis_stdout,"%s ",Ntk_NodeReadName(node));
01037   }
01038 
01039   if (truesimVerbose > 3) {
01040     (void) fprintf(vis_stdout," -- ");
01041     /* Print internal nodes next */
01042     Ntk_NetworkForEachNode(network,gen,node) {
01043       if (!Ntk_NodeTestIsPrimaryInput(node) &&
01044           !Ntk_NodeTestIsPrimaryOutput(node)) {
01045         (void) fprintf(vis_stdout,"%s ",Ntk_NodeReadName(node));
01046       }
01047     }
01048   }
01049   
01050   /* Print POs last */
01051   (void) fprintf(vis_stdout," -- ");
01052   Ntk_NetworkForEachPrimaryOutput(network,gen,node) {
01053     (void) fprintf(vis_stdout,"%s ",Ntk_NodeReadName(node));
01054   }
01055   (void) fprintf(vis_stdout,"\n");
01056 
01057   return ;
01058   
01059 } /* End of TruesimPrintNameHeader  */
01060 
01061 
01071 void
01072 TruesimPrintNetworkNodeLogicState(Ntk_Network_t *network)
01073 {
01074   st_table *nodeToSimTable;
01075   TrueSim_t *sim;
01076   lsGen gen;
01077   Ntk_Node_t *node;
01078 
01079   nodeToSimTable = TruesimNetworkReadSimTable(network);
01080 
01081   /* Print PIs first */
01082   Ntk_NetworkForEachPrimaryInput(network,gen,node) {
01083     if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
01084       (void) fprintf(vis_stderr,
01085                      "** truesim fatal: In TruesimPrintNetworkNodeLogicState\n");
01086       assert(0);
01087     }
01088     (void) fprintf(vis_stdout,"%c ",sim->value);
01089   }
01090 
01091   if (truesimVerbose > 3) {
01092     (void) fprintf(vis_stdout," -- ");
01093     /* Print internal nodes next */
01094     Ntk_NetworkForEachNode(network,gen,node) {
01095       if (!Ntk_NodeTestIsPrimaryInput(node) &&
01096           !Ntk_NodeTestIsPrimaryOutput(node)) {
01097         if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
01098           (void) fprintf(vis_stderr,
01099                          "** truesim fatal: In TruesimPrintNetworkNodeLogicState\n");
01100           assert(0);
01101         }
01102         (void) fprintf(vis_stdout,"%c ",sim->value);
01103       }
01104     }
01105   }
01106 
01107   /* Print POs last */
01108   (void) fprintf(vis_stdout," -- ");
01109   Ntk_NetworkForEachPrimaryOutput(network,gen,node) {
01110     if (!st_lookup(nodeToSimTable,(char *)node,&sim)) {
01111       (void) fprintf(vis_stderr,
01112                      "** truesim fatal: In TruesimPrintNetworkNodeLogicState\n");
01113       assert(0);
01114     }
01115     (void) fprintf(vis_stdout,"%c ",sim->value);
01116   }
01117   (void) fprintf(vis_stdout,"\n");
01118 
01119   return ;
01120   
01121 } /* End of TruesimPrintNodeLogicState  */
01122 
01123 
01139 void
01140 TruesimReadDelayFile(
01141   Ntk_Network_t *network,
01142   char *delayFile,
01143   st_table *nodeToSimTable)
01144 {
01145   char buffer[MAX_LENGTH], *ptr;
01146   FILE *fp;
01147   lsGen gen;
01148   TrueSim_t *sim;
01149   Ntk_Node_t *node;
01150 
01151   fp = Cmd_FileOpen(delayFile,"r",NIL(char *),1);
01152   while (fgets(buffer,MAX_LENGTH - 1,fp) != NULL) {
01153     if (buffer[0] == '#' || buffer[0] == '\n') 
01154       continue;
01155     if (truesimVerbose > 10) {
01156       (void) fprintf(vis_stdout,"%s",buffer);
01157     }
01158     ptr = strtok(buffer,TOKENS);
01159     node = Ntk_NetworkFindNodeByName(network,ptr);
01160     if (!node) {
01161       (void) fprintf(vis_stderr, "** truesim warning: %s not in the network\n",
01162                      ptr);
01163       (void) fprintf(vis_stderr, "** truesim warning: Values ignored ...\n");
01164       continue;
01165     }
01166     sim = ALLOC(TrueSim_t,1);
01167     ptr = strtok(NIL(char),TOKENS);
01168     if (ptr) {
01169       sim->delay = atof(ptr);
01170     }
01171     ptr = strtok(NIL(char),TOKENS);
01172     if (ptr) {
01173       sim->load = atof(ptr);
01174     }
01175     st_insert(nodeToSimTable, (char *)node, (char *)sim);
01176     if (truesimVerbose > 10) {
01177       (void) fprintf(vis_stdout,"%s %f %f\n",Ntk_NodeReadName(node),
01178                      sim->delay,sim->load);
01179     }
01180   }
01181 
01182   /* Now check that all the nodes have load and delay values. If a
01183      node delay/load value is not initialized, set it to default. */
01184 
01185   Ntk_NetworkForEachNode(network,gen,node) {
01186     if (!st_lookup(nodeToSimTable,(char *)node, &sim)) {
01187       sim = ALLOC(TrueSim_t,1);
01188       sim->delay = 1.0;
01189       sim->load = 0.0;
01190       st_insert(nodeToSimTable, (char *)node, (char *)sim);
01191     }
01192     if (sim->delay == 0.0)
01193       sim->delay = 1.0;
01194     /* if (Ntk_NodeTestIsPrimaryInput(node))
01195        sim->delay = 0.0; */
01196   }
01197   fclose(fp);
01198   return;
01199 } /* End of TruesimReadDelayFile */
01200 
01201 
01202 /*---------------------------------------------------------------------------*/
01203 /* Definition of static functions                                            */
01204 /*---------------------------------------------------------------------------*/
01205 
01218 static void
01219 GetInputs(
01220   char *buffer,
01221   Ntk_Network_t *network,
01222   array_t *inputArray)
01223 {
01224   char internalBuf[MAX_LENGTH];
01225   long i,index;
01226   Ntk_Node_t *node;
01227 
01228   index = 2;
01229   while (buffer[index] != '\0') {
01230     if (buffer[index] == ' ' ||
01231         buffer[index] == '\t' ||
01232         buffer[index] == '\n') {
01233       index++;
01234       continue;
01235     }
01236     i = 0;
01237     while (buffer[index] != ' ' && buffer[index] != '\t'
01238            && buffer[index] != '\n') {
01239       internalBuf[i] = buffer[index];
01240       i++;
01241       index++;
01242     } /* End of while */
01243     if (i > 0); {
01244       internalBuf[i] = '\0';
01245       node = Ntk_NetworkFindNodeByName(network,internalBuf);
01246       if (node)
01247         array_insert_last(Ntk_Node_t *,inputArray,node);
01248       else {
01249         (void) fprintf(vis_stderr,
01250                        "** truesim error: %s not found in the circuit.\n", 
01251                        internalBuf);
01252       }
01253       index++;
01254     }
01255   } /* End of while */
01256 } /* End of GetInputs */
01257 
01258 
01272 static void
01273 GetPatternVectors(
01274   FILE *fp,
01275   int vecLen,
01276   array_t *patternArray)
01277 {
01278   char buffer[MAX_LENGTH];
01279   char internalBuf[MAX_LENGTH];
01280   char *str;
01281   int index,i,j;
01282   boolean skip;
01283 
01284   while (fgets(buffer,MAX_LENGTH - 1,fp) != NULL) {
01285     index = i = 0;
01286     if (buffer[0] == '\n' ||
01287         buffer[0] == '#')
01288       continue;
01289     while (buffer[index] != '\0') {
01290       if (buffer[index] == ' ' ||
01291           buffer[index] == ';' ||
01292           buffer[index] == '\n') {
01293         index++;
01294         continue;
01295       }
01296       internalBuf[i] = buffer[index];
01297       i++;
01298       index++;
01299     }
01300     if (i > 0) {
01301       internalBuf[i] = '\0';
01302       /* Ascertain that internalBuf has only '0's and '1's. */
01303       skip = FALSE;      j = 0;
01304       while (internalBuf[j] != '\0') {
01305         if ((internalBuf[j] != '0') && (internalBuf[j] != '1')) {
01306           skip = TRUE;
01307           break;
01308         }
01309         j++;
01310       }
01311       if (skip) {
01312         (void) fprintf(vis_stdout,
01313                        "** spfd warning: Invalid vector < %s > is ignored.\n",
01314                        internalBuf);
01315       } else if ((unsigned) vecLen != strlen(internalBuf)) {
01316         (void) fprintf(vis_stdout,
01317                        "** spfd warning: Length < %ld > of < %s > incorrect.\n",
01318                        (long) strlen(internalBuf), internalBuf);
01319         (void) fprintf(vis_stdout,
01320                        "** spfd warning: Ignoring < %s > .\n",internalBuf);
01321       } else {
01322         str = util_strsav(internalBuf);
01323         array_insert_last(char *,patternArray,str);
01324       }
01325     }
01326   }
01327 } /* End of GetPatternVectors */
01328 
01329 
01349 static long
01350 NodeComputeDepth(
01351   Ntk_Node_t * node)
01352 {
01353   long depth = NodeReadDepth(node);
01354 
01355   /* If the node's depth has already been computed (i.e. it's not
01356    unassigned), then just return it below.  If it's unassigned, then
01357    recursively compute it.  */
01358   if (depth == UNASSIGNED_DEPTH) {
01359     if (Ntk_NodeTestIsCombInput(node) || Ntk_NodeTestIsConstant(node)) {
01360       /* PI and nodes with no fanins, get depth 0. This is the
01361         terminal case of recursion.  */
01362       depth = 0;
01363     } else {
01364       int i;
01365       Ntk_Node_t *fanin;
01366       /* Compute the depth of each fanin node in the support of node,
01367         and maintain the maximum.  We start depth at 0 for max
01368         calculation.  */
01369       depth = 0;
01370       Ntk_NodeForEachFanin(node, i, fanin) {  
01371         long faninDepth = NodeComputeDepth(fanin);
01372 
01373         depth = (depth > faninDepth) ? depth:faninDepth;
01374       }
01375       
01376       /* The depth of node is one more than the max depths of its
01377        fanins.  */
01378       depth++;
01379     }
01380 
01381     /* Store the depth.  */
01382     NodeSetDepth(node, depth);
01383   }
01384   
01385   return depth;
01386 }
01387 
01388 
01398 static long
01399 NodeReadDepth(
01400   Ntk_Node_t * node)
01401 {
01402   return ((long) Ntk_NodeReadUndef(node));
01403 }
01404 
01405 
01415 static void
01416 NodeSetDepth(
01417   Ntk_Node_t * node,
01418   long depth)
01419 {
01420   Ntk_NodeSetUndef(node, (void *) depth);
01421 }
01422 
01432 static enum st_retval
01433 stFloatFree(
01434   char *key,
01435   char *value,
01436   char *arg)
01437 {
01438   float *dummy;
01439   dummy = (float *)value;
01440 
01441   if (dummy)
01442     FREE(dummy);
01443 
01444   return (ST_CONTINUE);
01445 
01446 } /* End of stFloatFree */
01447 
01448 
01467 static float
01468 computeProbabilityRecur(
01469   Ntk_Network_t *network,
01470   st_table *nodeToSimTable,
01471   st_table *seenTable,
01472   bdd_node *bddNode)
01473 {
01474   float value,*probability,*dummy;
01475   float valueL,valueR;
01476   Ntk_Node_t *networkNode;
01477   TrueSim_t *sim;
01478   bdd_node *N,*Nv,*Nnv;
01479 
01480   N = bdd_regular(bddNode);
01481 
01482   if (st_lookup(seenTable,(char *)N,&dummy)) {
01483     return ((N != bddNode) ? 1.0 - *dummy : *dummy);
01484   }
01485   
01486   Nv = bdd_bdd_T(N);
01487   Nnv = bdd_bdd_E(N);
01488 
01489   /* Recur on the children */
01490   valueR = computeProbabilityRecur(network,nodeToSimTable,seenTable,Nv);
01491   valueL = computeProbabilityRecur(network,nodeToSimTable,seenTable,Nnv);
01492 
01493   networkNode = Ntk_NetworkFindNodeByMddId(network,bdd_node_read_index(N));
01494   if (st_lookup(nodeToSimTable,(char *)networkNode,&sim)) {
01495     value = sim->prob;
01496     probability = ALLOC(float,1);
01497     *probability = value * valueR + (1.0 - value) * valueL;
01498   } else {
01499     fprintf(vis_stderr,
01500             "** truesim error: Could not find prob. for node %s\n",
01501             Ntk_NodeReadName(networkNode));
01502     return (float) TRUESIM_ERROR_VALUE;
01503   }
01504 
01505   st_insert(seenTable,(char *)N,(char *)probability);
01506 
01507   return ((N != bddNode) ? 1.0 - *probability : *probability);
01508 
01509 } /* End of computeProbabilityRecur */