VIS

src/res/res.c

Go to the documentation of this file.
00001 
00019 #include "resInt.h"
00020 
00021 static char rcsid[] UNUSED = "$Id: res.c,v 1.55 2009/04/11 21:31:29 fabio Exp $";
00022 
00023 /*---------------------------------------------------------------------------*/
00024 /* Constant declarations                                                     */
00025 /*---------------------------------------------------------------------------*/
00026 #define RES_VERIFY_NOTHING 0
00027 #define RES_VERIFY_DONE 1
00028 #define RES_VERIFY_IGNORE_PREV_RESULTS 2
00029 #define LOG2_FIRST_PRIME 8
00030 
00031 /*---------------------------------------------------------------------------*/
00032 /* Structure declarations                                                    */
00033 /*---------------------------------------------------------------------------*/
00034 
00035 /*---------------------------------------------------------------------------*/
00036 /* Type declarations                                                         */
00037 /*---------------------------------------------------------------------------*/
00038 
00039 /*---------------------------------------------------------------------------*/
00040 /* Variable declarations                                                     */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 
00044 static int PrimePool [] = { 5,   7,  9, 11, 13, 17,  19,  23,  29,
00045                             31,  37,  41,  43,  47,  53,  59,  61,  67,  71,
00046                             73,  79,  83,  89,  97, 101, 103, 107, 109, 113,
00047                             127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
00048                             179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
00049                             233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
00050                             283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
00051                             353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
00052                             419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
00053                             467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
00054                             547};
00055 static int PrimePoolSize = 100;    /* Number of elements of the array above */
00056 
00057 /*---------------------------------------------------------------------------*/
00058 /* Macro declarations                                                        */
00059 /*---------------------------------------------------------------------------*/
00060 
00063 /*---------------------------------------------------------------------------*/
00064 /* Static function prototypes                                                */
00065 /*---------------------------------------------------------------------------*/
00066 
00067 static int ChoosePrimes(int numOutputs, int **pool, int numDirectVerify);
00068 static int ComputeMaxNumberOfOutputs(void);
00069 static void RestoreOldMddIds(Ntk_Network_t *network, st_table *table);
00070 static st_table * GeneratePointerMatchTableFromNameMatch(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, st_table *nameMatchTable);
00071 static st_table * GenerateDirectVerifyPointerTable(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, st_table *outputMatch, array_t *outputOrderArray, int numDirectVerify);
00072 static st_table * GenerateIdentityMatchTable(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, int inputOrOutput);
00073 static bdd_manager * Initializebdd_manager(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, int *initManagerHere);
00074 static int SetBasicResultInfo(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, int numDirectVerify);
00075 static void Cleanup(int error, Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, int initManagerHere, int done, st_table *outputMatch, st_table *inputMatch, st_table *directVerifyMatch, st_table *oldSpecMddIdTable, st_table *oldImplMddIdTable, array_t *specLayerArray, array_t *implLayerArray);
00076 static st_table * SaveOldMddIds(Ntk_Network_t *network);
00077 static int DirectVerification(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, st_table *directVerifyMatch, st_table *inputMatch, st_table *outputMatch, array_t *outputOrderArray);
00078 static bdd_reorder_type_t DecodeDynMethod(char *dynMethodString);
00079 static int ResidueVerification(Ntk_Network_t *specNetwork, Ntk_Network_t *implNetwork, st_table *outputMatch, st_table *inputMatch, int numDirectVerify, array_t *specLayerArray, array_t *implLayerArray, array_t *outputArray);
00080 static void ExtractACubeOfDifference(bdd_manager *mgr, Ntk_Network_t *specNetwork, bdd_node *fn1, bdd_node *fn2);
00081 
00085 /*---------------------------------------------------------------------------*/
00086 /* Definition of exported functions                                          */
00087 /*---------------------------------------------------------------------------*/
00088 
00119 int
00120 Res_NetworkResidueVerify(
00121          Ntk_Network_t *specNetwork,
00122          Ntk_Network_t *implNetwork,
00123          int numDirectVerify,
00124          array_t *outputOrderArray,
00125          st_table *outputNameMatch,
00126          st_table *inputNameMatch)
00127 {
00128   Ntk_Node_t *nodePtr;           /* To iterate over nodes */
00129   Ntk_Node_t *implNodePtr;       /* To iterate over nodes */
00130   Res_ResidueInfo_t *resultSpec; /* Structure holding all the info */
00131   Res_ResidueInfo_t *resultImpl; /* Structure holding all the info */
00132   array_t *specLayerArray;       /* array containing the reverse
00133                                   * topological layers of the spec.
00134                                   */
00135   array_t *implLayerArray;       /* array containing the reverse
00136                                   * topological layers of the impl.
00137                                   */
00138   st_table *oldSpecMddIdTable;   /* Tables to store MDD IDs of the spec
00139                                   * if already assigned
00140                                   */
00141   st_table *oldImplMddIdTable;   /* Tables to store MDD IDs of the impl.
00142                                   * if already assigned
00143                                   */
00144 
00145   st_table *outputMatch;         /* Output match table with node
00146                                   * pointers, spec node pointer is
00147                                   * the key
00148                                   */
00149   st_table *inputMatch;          /* Input match table with node
00150                                   * pointers, spec node pointer is
00151                                   * the key
00152                                   */
00153 
00154   bdd_manager *ddManager;          /* Manager read from the network */
00155   int initManagerHere;           /* Flag to indicate the network Mdd
00156                                   * managers initialized here
00157                                   */
00158 
00159   lsGen listGen;                 /* To iterate over outputList */
00160   long overallLap;               /* To measure overall execution time */
00161   int maxNumberOfOutputs;        /* max number of outputs that can be
00162                                   * verified here
00163                                   * = product(100 primes)
00164                                   */
00165   int numOutputs;                /* Store the number of outputs in spec.,
00166                                   * impl
00167                                   */
00168   int done;                      /* flag to determine the status of
00169                                   * previous verification
00170                                   */
00171   int error;                     /* error flag, set for cleanup, 1 failed,
00172                                   * 0 if successful
00173                                   */
00174   int status;                    /* error status of residue verification */
00175   int directVerifyStatus;        /* direct verification status, 1 if failed,
00176                                   * 0 if successful
00177                                   */
00178   st_table *directVerifyMatch;   /* match table with pointers for the
00179                                   * directly verified outputs, spec pointer
00180                                   * is key
00181                                   */
00182   char *name;                    /* variable to store name of node */
00183   array_t *outputArray;          /* array to store output nodes */
00184   array_t *ignoreOutputArray;    /* array to store outputs nodes to be
00185                                   * ignored
00186                                   */
00187   int verbose;                   /* variable to read residue_verbosity value */
00188   char *flagValue;               /* string to read flag values */
00189   int i;                         /* Loop iterators */
00190   int unassignedValue;           /* NTK_UNASSIGNED_MDD_ID value holder */
00191 
00192   /* Initialize some variables to default values */
00193 
00194   overallLap = 0;
00195   initManagerHere = 0;
00196   ddManager = NIL(bdd_manager);
00197   done = RES_VERIFY_NOTHING;
00198   error = 0;
00199   status = 1;
00200   verbose = 0;
00201 
00202   unassignedValue =  NTK_UNASSIGNED_MDD_ID;
00203   directVerifyStatus = 1;
00204   directVerifyMatch = NIL(st_table);
00205   specLayerArray = NIL(array_t);
00206   implLayerArray = NIL(array_t);
00207   outputArray = NIL(array_t);
00208   ignoreOutputArray = NIL(array_t);
00209   outputMatch = NIL(st_table);
00210   inputMatch = NIL(st_table);
00211   oldSpecMddIdTable = NIL(st_table);
00212   oldImplMddIdTable = NIL(st_table);
00213   resultSpec = NIL(Res_ResidueInfo_t);
00214   resultImpl = NIL(Res_ResidueInfo_t);
00215 
00216 
00217   /* Initialize global time values*/
00218   Res_composeTime = 0;
00219   Res_smartVarTime = 0;
00220   Res_shuffleTime = 0;
00221   Res_orderTime = 0;
00222 
00223 
00224   /* Read verbosity value */
00225   flagValue = Cmd_FlagReadByName("residue_verbosity");
00226   if (flagValue != NIL(char)) {
00227     verbose = atoi(flagValue);
00228   }
00229 
00230   /* Read the mdd Manager (or create it if necessary) */
00231   ddManager = Initializebdd_manager(specNetwork, implNetwork, &initManagerHere);
00232   if (ddManager == NIL(bdd_manager)) {
00233     /* error, but nothing allocated, so no cleanup */
00234     return 1;
00235   }
00236 
00237   /* Set up the correct maximum number of outputs */
00238   maxNumberOfOutputs  = ComputeMaxNumberOfOutputs();
00239   if (verbose >= 2) {
00240     fprintf(vis_stdout, "The Maximum Number of outputs that can be");
00241     fprintf(vis_stdout, " verified are %d.\n", maxNumberOfOutputs);
00242   }
00243 
00244   /* check number of outputs */
00245   numOutputs = Ntk_NetworkReadNumCombOutputs(specNetwork);
00246   /* Check if the circuit has too many outputs */
00247   if (numOutputs >= maxNumberOfOutputs) {
00248     error_append("Circuit with too many outputs.\n");
00249     /* Clean up before you leave */
00250     error = 1;
00251     Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00252             outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00253             oldImplMddIdTable, specLayerArray, implLayerArray);
00254     return 1;
00255   } /* End of if */
00256 
00257   /* Create result data structure for both the spec and the implementation */
00258   done = SetBasicResultInfo(specNetwork, implNetwork, numDirectVerify);
00259   if (done ==  RES_VERIFY_DONE) {/* same verification as previous time */
00260     /* Clean up before you leave */
00261     fprintf(vis_stdout, "Verification has been previously performed\n");
00262     error = 0;
00263     Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00264             outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00265             oldImplMddIdTable, specLayerArray, implLayerArray);
00266     return 0; /* success */
00267   } /* end of case RES_VERIFY_DONE */
00268 
00269   /* if output match table does not exist, create one with matching names
00270    * in the two networks. Insert with spec network node pointer as key
00271    * in the outputMatch table. If match table does exist, convert name table
00272    * to pointer table.
00273    */
00274   if(outputNameMatch == NIL(st_table)) {
00275     outputMatch = GenerateIdentityMatchTable(specNetwork, implNetwork, PRIMARY_OUTPUTS);
00276   } else {
00277     outputMatch = GeneratePointerMatchTableFromNameMatch(specNetwork,
00278                                                          implNetwork,outputNameMatch);
00279     if (outputMatch == NIL(st_table)) {
00280       error_append("Output pointer table is NULL\n");
00281       /* Clean up before you leave */
00282       error = 1;
00283       Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00284               outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00285               oldImplMddIdTable, specLayerArray, implLayerArray);
00286       return 1; /* error return */
00287     }
00288   }
00289 
00290   /* if input match table does not exist, create one with matching names
00291    * in the two networks. Insert with spec network node pointer as key
00292    * in the inputMatch table. If match table does exist, convert name table
00293    * to pointer table.
00294    */
00295   if(inputNameMatch == NIL(st_table)) {
00296     inputMatch = GenerateIdentityMatchTable(specNetwork, implNetwork, PRIMARY_INPUTS);
00297   } else {
00298     inputMatch = GeneratePointerMatchTableFromNameMatch(specNetwork,
00299                                                         implNetwork,inputNameMatch);
00300     if (inputMatch == NIL(st_table)) {
00301       error_append("Input pointer table is NULL\n");
00302       /* Clean up before you leave */
00303       error = 1;
00304       Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00305               outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00306               oldImplMddIdTable, specLayerArray, implLayerArray);
00307       return 1; /* error return */
00308     }
00309   }
00310 
00311   /* Save the old MDD IDs in a st_table */
00312   oldSpecMddIdTable = SaveOldMddIds(specNetwork);
00313   if (oldSpecMddIdTable == NIL(st_table)) {
00314     error_append("Unable to save old Mdd Ids for spec\n");
00315     /* Clean up before you leave */
00316     error = 1;
00317     Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00318             outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00319             oldImplMddIdTable, specLayerArray, implLayerArray);
00320     return 1;
00321   }
00322 
00323   /* Save the old MDD IDs in a st_table */
00324   oldImplMddIdTable = SaveOldMddIds(implNetwork);
00325   if (oldImplMddIdTable == NIL(st_table)) {
00326     error_append("Unable to save old Mdd Ids for impl\n");
00327     /* Clean up before you leave */
00328     error = 1;
00329     Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00330             outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00331             oldImplMddIdTable, specLayerArray, implLayerArray);
00332     return 1;
00333   }
00334 
00335   /* Initialize time to measure overall lap time */
00336   overallLap = util_cpu_time();
00337 
00338   /* Perform direct verification of the given outputs. */
00339   if (numDirectVerify) {
00340     /* generate output match table for outputs to be directly verified */
00341     directVerifyMatch = GenerateDirectVerifyPointerTable(specNetwork,
00342          implNetwork, outputMatch, outputOrderArray, numDirectVerify);
00343     if (directVerifyMatch == NIL(st_table)) {
00344       error_append("Directly verify  pointer table is NULL\n");
00345       /* Clean up before you leave */
00346       error = 1;
00347       Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00348               outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00349               oldImplMddIdTable, specLayerArray, implLayerArray);
00350       return 1; /* error return */
00351     }
00352 
00353     /* perform direct verification of the outputs in the match table */
00354     directVerifyStatus = DirectVerification(specNetwork, implNetwork,
00355                     directVerifyMatch, inputMatch, outputMatch, outputOrderArray);
00356     /* Direct verification error */
00357     if (directVerifyStatus == 1) {
00358       error_append("Direct Verification error\n");
00359       /* Clean up before you leave */
00360       error = 1;
00361       Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00362       outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00363               oldImplMddIdTable, specLayerArray, implLayerArray);
00364       return 1; /* error return */
00365     }
00366 
00367     resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork,
00368                                             RES_NETWORK_APPL_KEY);
00369     resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork,
00370                                             RES_NETWORK_APPL_KEY);
00371     /* Direct verification failed */
00372     if ((ResResidueInfoReadDirectVerificationSuccess(resultSpec) == RES_FAIL) &&
00373         (ResResidueInfoReadDirectVerificationSuccess(resultImpl) == RES_FAIL)) {
00374       ResResidueInfoSetSuccess(resultSpec, RES_FAIL);
00375       ResResidueInfoSetSuccess(resultImpl, RES_FAIL);
00376       /*  Clean up before you leave */
00377       error = 0;
00378       Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00379       outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00380               oldImplMddIdTable, specLayerArray, implLayerArray);
00381       return 0;
00382     } else if (numDirectVerify == numOutputs) {
00383       if ((ResResidueInfoReadDirectVerificationSuccess(resultSpec) == RES_PASS) &&
00384           (ResResidueInfoReadDirectVerificationSuccess(resultImpl) == RES_PASS)) {
00385         /* if all outputs are directly verified */
00386         ResResidueInfoSetSuccess(resultSpec, RES_PASS);
00387         ResResidueInfoSetSuccess(resultImpl, RES_PASS);
00388       }
00389     } /* end of else */
00390 
00391 
00392   } /* Direct Verification, done and successful */
00393 
00394   (void) fprintf(vis_stdout, "Total Direct Verification Time = %.3f (secs).\n",
00395                  (util_cpu_time() - overallLap)/1000.0);
00396 
00397   if (verbose >= 1) {
00398     util_print_cpu_stats(vis_stdout);
00399   }
00400 
00401 
00402   /* RESIDUE VERIFICATION starts here */
00403 
00404   if (numOutputs - numDirectVerify) { /* if residue verification required */
00405     /* reset all Ids after direct verification as residue verification
00406      * assigns new Ids.
00407      */
00408     Ntk_NetworkForEachNode(specNetwork, listGen, nodePtr) {
00409       Ntk_NodeSetMddId(nodePtr, unassignedValue);
00410     }
00411     Ntk_NetworkForEachNode(implNetwork, listGen, nodePtr) {
00412       Ntk_NodeSetMddId(nodePtr, unassignedValue);
00413     }
00414 
00415     /* check if directly verified outputs are to be involved in residue
00416      * verification
00417      */
00418     flagValue = Cmd_FlagReadByName("residue_ignore_direct_verified_outputs");
00419     if (flagValue != NIL(char)) {
00420       if ((strcmp(flagValue, "1") == 0) && (numDirectVerify)) {
00421         ignoreOutputArray = array_alloc(Ntk_Node_t *, numDirectVerify);
00422       }
00423     }
00424     if (ignoreOutputArray == NIL(array_t)) {
00425       /* fill the output array with all output nodes */
00426       outputArray = array_alloc(Ntk_Node_t *, array_n(outputOrderArray));
00427       arrayForEachItem(char *, outputOrderArray, i, name) {
00428         nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name);
00429         st_lookup(outputMatch, (char *)nodePtr, &implNodePtr);
00430         array_insert(Ntk_Node_t *, outputArray, i, implNodePtr);
00431       }
00432     } else {
00433       outputArray = array_alloc(Ntk_Node_t *, array_n(outputOrderArray)-numDirectVerify);
00434       /* fill the output array with nodes not directly verified */
00435       for (i = 0; i < (array_n(outputOrderArray) - numDirectVerify); i++) {
00436         name = array_fetch(char *, outputOrderArray, i);
00437         nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name);
00438         st_lookup(outputMatch, (char *)nodePtr, &implNodePtr);
00439         array_insert(Ntk_Node_t *, outputArray, i, implNodePtr);
00440       }
00441       /* fill ignore array with outputs directly verified. */
00442       for (i = (array_n(outputOrderArray) - numDirectVerify); i < array_n(outputOrderArray); i++) {
00443         name = array_fetch(char *, outputOrderArray, i);
00444         nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name);
00445         st_lookup(outputMatch, (char *)nodePtr, &implNodePtr);
00446         array_insert(Ntk_Node_t *, ignoreOutputArray, (i-array_n(outputOrderArray)+numDirectVerify) , implNodePtr);
00447       }
00448     }
00449 
00450 
00451     /* Compute the layers to be used for function composition */
00452     implLayerArray = ResComputeCompositionLayers(implNetwork, outputArray, ignoreOutputArray);
00453 
00454     /* create the output array for the spec. */
00455     if (ignoreOutputArray == NIL(array_t)) {
00456       /* fill the output array with all output nodes */
00457       arrayForEachItem(char *, outputOrderArray, i, name) {
00458         nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name);
00459         array_insert(Ntk_Node_t *, outputArray, i, nodePtr);
00460       }
00461     } else {
00462       /* fill the output array with nodes not directly verified */
00463       for (i = 0; i < (array_n(outputOrderArray) - numDirectVerify); i++) {
00464         name = array_fetch(char *, outputOrderArray, i);
00465         nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name);
00466         array_insert(Ntk_Node_t *, outputArray, i, nodePtr);
00467       }
00468       /* fill ignore array with outputs directly verified. */
00469       for (i = (array_n(outputOrderArray) - numDirectVerify); i < array_n(outputOrderArray); i++) {
00470         name = array_fetch(char *, outputOrderArray, i);
00471         nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name);
00472         array_insert(Ntk_Node_t *, ignoreOutputArray, (i-array_n(outputOrderArray)+numDirectVerify), nodePtr);
00473       }
00474     }
00475 
00476     /* Compute the layers to be used for function composition */
00477     specLayerArray = ResComputeCompositionLayers(specNetwork, outputArray, ignoreOutputArray);
00478 
00479     /* print the array */
00480     if (verbose >=3) {
00481       ResLayerPrintInfo(specNetwork, specLayerArray);
00482       ResLayerPrintInfo(implNetwork, implLayerArray);
00483     }
00484 
00485     /* free the ignore array */
00486     if (ignoreOutputArray != NIL(array_t)) {
00487       array_free(ignoreOutputArray);
00488     }
00489 
00490     /* Perform residue verification on the spec. and impl. */
00491     status = ResidueVerification(specNetwork, implNetwork, outputMatch, inputMatch, numDirectVerify, specLayerArray, implLayerArray, outputArray);
00492 
00493     /* free output array */
00494     array_free(outputArray);
00495 
00496     if (status) {
00497       error_append("Residue Verification error\n");
00498       /* Clean up before you leave */
00499       error = 1;
00500       Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00501               outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00502               oldImplMddIdTable, specLayerArray, implLayerArray);
00503       return 1; /* error return */
00504     }
00505 
00506 
00507     resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork,
00508                                               RES_NETWORK_APPL_KEY);
00509     resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork,
00510                                             RES_NETWORK_APPL_KEY);
00511     /* Print success message and info */
00512     if ((ResResidueInfoReadSuccess(resultSpec) == RES_FAIL) &&
00513         (ResResidueInfoReadSuccess(resultImpl) == RES_FAIL)) {
00514       /* Clean up before you leave */
00515       error = 0;
00516             Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00517               outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00518               oldImplMddIdTable, specLayerArray, implLayerArray);
00519       return 0;
00520     }
00521 
00522     if(verbose >= 2) {
00523       (void) fprintf(vis_stdout, "Total Compose Time = %3f(secs).\n",
00524                      Res_composeTime/1000.0);
00525       (void) fprintf(vis_stdout, "Total Order Time = %3f(secs).\n",
00526                      Res_orderTime/1000.0);
00527       (void) fprintf(vis_stdout, "Total Shuffle Time = %3f(secs).\n",
00528                      Res_shuffleTime/1000.0);
00529 
00530       (void) fprintf(vis_stdout, "Total Smart Var Time = %3f(secs).\n",
00531                      Res_smartVarTime/1000.0);
00532     }
00533 
00534 
00535   } /* end of residue verification */
00536 
00537   /* Print success message and info */
00538   if ((ResResidueInfoReadSuccess(resultSpec) == RES_PASS) &&
00539       (ResResidueInfoReadSuccess(resultImpl) == RES_PASS))
00540     (void) fprintf(vis_stdout, "Verification of %s and %s successful.\n",
00541                    Res_ResidueInfoReadName(resultSpec),
00542                    Res_ResidueInfoReadName(resultImpl));
00543 
00544 
00545   if (verbose >= 1) {
00546     fprintf(vis_stdout, "Specification:\n");
00547     (void) Res_ResidueInfoPrint(resultSpec);
00548     fprintf(vis_stdout, "Implementation:\n");
00549     (void) Res_ResidueInfoPrint(resultImpl);
00550   }
00551   if (verbose >= 1) {
00552     util_print_cpu_stats(vis_stdout);
00553   }
00554 
00555   (void) fprintf(vis_stdout, "Total Time = %.3f (secs).\n",
00556                  (util_cpu_time() - overallLap)/1000.0);
00557 
00558   /* no error */
00559   error = 0;
00560   Cleanup(error, specNetwork, implNetwork, initManagerHere, done,
00561           outputMatch, inputMatch, directVerifyMatch, oldSpecMddIdTable,
00562           oldImplMddIdTable, specLayerArray, implLayerArray);
00563 
00564   /* End of clean up */
00565 
00566   return 0;
00567 } /* End of Res_NetworkResidueVerify */
00568 
00569 /*---------------------------------------------------------------------------*/
00570 /* Definition of internal functions                                          */
00571 /*---------------------------------------------------------------------------*/
00572 
00573 
00574 
00575 /*---------------------------------------------------------------------------*/
00576 /* Definition of static functions                                            */
00577 /*---------------------------------------------------------------------------*/
00578 
00596 static int
00597 ChoosePrimes(int numOutputs,
00598              int **pool,
00599              int numDirectVerify)
00600 {
00601   double accumulator = 0.0;
00602   int i,max, index = 0;
00603   double factor = log10((double)2.0);
00604 
00605   assert(*pool == NIL(int));
00606 
00607   if (numDirectVerify) {
00608     accumulator = (double)numDirectVerify;
00609   } else {
00610     /* make first prime 2^LOG2_FIRST_PRIME */
00611     if (numOutputs >= LOG2_FIRST_PRIME) {
00612       accumulator = (double)LOG2_FIRST_PRIME;
00613     } else {
00614       accumulator = (double)numOutputs;
00615     }
00616   }
00617 
00618   /* step through primes till their product exceeds the max value of outputs */
00619   max = 0;
00620   while (accumulator < ((double)numOutputs)) {
00621     accumulator += log10((double)PrimePool[max])/factor;
00622     max++;
00623   }
00624 
00625   index = 0;
00626   /* if no direct verification, then set the first prime to be 2^LOG2_FIRST_PRIME */
00627   if (!numDirectVerify) {
00628     *pool = ALLOC(int, max+1);
00629     if (numOutputs >= LOG2_FIRST_PRIME) {
00630       (*pool)[index++] = (int)pow((double)2.0, (double)LOG2_FIRST_PRIME);
00631     } else {
00632       (*pool)[index++] = (int)pow((double)2.0, (double)numOutputs);
00633     }
00634   } else {
00635     *pool = ALLOC(int, max);
00636   }
00637 
00638   /* fill the array with other primes */
00639   for(i=0; i < max; i++) {
00640    (*pool)[index++] = PrimePool[i];
00641   }
00642 
00643   return index;
00644 } /* End of ChoosePrimes */
00645 
00646 
00661 static int
00662 ComputeMaxNumberOfOutputs(void)
00663 {
00664   int i;
00665   double result = 0;
00666   int maxNumberOfOutputs;
00667 
00668   result = LOG2_FIRST_PRIME;
00669   for(i = 0; i < PrimePoolSize; i++) {
00670     result += log10((double)PrimePool[i]);
00671   } /* End of for */
00672 
00673   maxNumberOfOutputs = (int) (result/log10((double) 2.0)) - 1;
00674 
00675   return (maxNumberOfOutputs);
00676 } /* End of ComputeMaxNumberOfOutputs */
00677 
00678 
00693 static void
00694 RestoreOldMddIds(Ntk_Network_t *network,
00695                  st_table *table)
00696 {
00697   lsGen listGen;
00698   Ntk_Node_t *nodePtr;
00699   int value;
00700   if (table != NULL) {
00701     Ntk_NetworkForEachNode(network, listGen, nodePtr) {
00702       if(st_lookup_int(table, (char *)nodePtr, &value)) {
00703         Ntk_NodeSetMddId(nodePtr, value);
00704       } else {
00705         error_append("Node");
00706         error_append(Ntk_NetworkReadName(network));
00707         error_append("should have been in the table.\n");
00708         (void) lsFinish(listGen);
00709       }
00710     }
00711   }
00712 } /* End of RestoreOldMddIds */
00713 
00714 
00734 static st_table *
00735 GeneratePointerMatchTableFromNameMatch(
00736                        Ntk_Network_t *specNetwork,
00737                        Ntk_Network_t *implNetwork,
00738                        st_table *nameMatchTable)
00739 {
00740   st_table *pointerMatch;
00741   Ntk_Node_t *nodePtr, *implNodePtr;
00742   st_generator *stGen;
00743   char *key, *value;
00744 
00745   pointerMatch = st_init_table( st_ptrcmp, st_ptrhash);
00746   st_foreach_item(nameMatchTable, stGen, &key, &value) {
00747     /* find node in spec */
00748     nodePtr = Ntk_NetworkFindNodeByName(specNetwork, key);
00749     if (nodePtr == NIL(Ntk_Node_t)) {
00750       /* if node not in spec, find in impl */
00751       implNodePtr = Ntk_NetworkFindNodeByName(implNetwork, key);
00752       nodePtr = Ntk_NetworkFindNodeByName(specNetwork, value);
00753     } else {
00754       implNodePtr = Ntk_NetworkFindNodeByName(implNetwork,value);
00755     }
00756     if ((nodePtr == NIL(Ntk_Node_t)) || (implNodePtr == NIL(Ntk_Node_t))) {
00757       /* error */
00758       error_append("Nodes not found by the keys in match table.\n");
00759       st_free_gen(stGen);
00760       return NIL(st_table);
00761     }
00762     st_insert(pointerMatch, (char *)nodePtr, (char *)implNodePtr);
00763   } /* end of st_foreach_item */
00764 
00765   return(pointerMatch);
00766 } /* End of GeneratePointerMatchTableFromNameMatch */
00767 
00768 
00784 static st_table *
00785 GenerateDirectVerifyPointerTable(Ntk_Network_t *specNetwork,
00786                                  Ntk_Network_t *implNetwork,
00787                                  st_table *outputMatch,
00788                                  array_t *outputOrderArray,
00789                                  int numDirectVerify)
00790 
00791 {
00792   char *specName;
00793   int i;
00794   Ntk_Node_t *nodePtr, *implNodePtr;
00795   st_table *directVerifyMatch;
00796 
00797   directVerifyMatch = st_init_table(st_ptrcmp, st_ptrhash);
00798   for (i = 0; i < numDirectVerify; i++) {
00799     specName = array_fetch(char *, outputOrderArray, array_n(outputOrderArray) - 1 - i);
00800     nodePtr = Ntk_NetworkFindNodeByName(specNetwork, specName);
00801     st_lookup(outputMatch, (char *)nodePtr, &implNodePtr);
00802     if ((nodePtr == NIL(Ntk_Node_t)) || (implNodePtr == NIL(Ntk_Node_t))) {
00803       error_append("Couldn't find nodes to directly verify\n");
00804       st_free_table(directVerifyMatch);
00805       return NIL(st_table);
00806     }
00807     st_insert(directVerifyMatch, (char *)nodePtr, (char *)implNodePtr);
00808   }
00809   return (directVerifyMatch);
00810 } /* End of GenerateDirectVerifyPointerTable */
00811 
00812 
00830 static st_table *
00831 GenerateIdentityMatchTable(Ntk_Network_t *specNetwork,
00832                            Ntk_Network_t *implNetwork,
00833                            int inputOrOutput)
00834 {
00835   Ntk_Node_t *nodePtr, *implNodePtr;
00836   st_table *matchTable;
00837   lsGen listGen;
00838   char *name;
00839 
00840   matchTable = st_init_table(st_ptrcmp, st_ptrhash);
00841   if (matchTable == NULL) return(NIL(st_table));
00842 
00843   if (inputOrOutput == PRIMARY_INPUTS) {
00844     Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) {
00845       name = Ntk_NodeReadName(nodePtr);
00846       implNodePtr = Ntk_NetworkFindNodeByName(implNetwork, name);
00847       if (implNodePtr == NIL(Ntk_Node_t)) {
00848         error_append(name);
00849         error_append(" node does not have corresponding node in impl.");
00850         st_free_table(matchTable);
00851         return (NIL(st_table));
00852       }
00853       st_insert(matchTable, (char *)nodePtr, (char *)implNodePtr);
00854     }
00855   } else if (inputOrOutput == PRIMARY_OUTPUTS) {
00856     Ntk_NetworkForEachCombOutput(specNetwork, listGen, nodePtr) {
00857       name = Ntk_NodeReadName(nodePtr);
00858       implNodePtr = Ntk_NetworkFindNodeByName(implNetwork,name);
00859       if (implNodePtr == NIL(Ntk_Node_t)) {
00860         error_append(name);
00861         error_append(" node does not have corresponding node in impl.");
00862         st_free_table(matchTable);
00863         return (NIL(st_table));
00864       }
00865       st_insert(matchTable, (char *)nodePtr, (char *)implNodePtr);
00866     }
00867   }
00868   return (matchTable);
00869 } /* End of GenerateIdentityMatchTable */
00870 
00887 static bdd_manager *
00888 Initializebdd_manager(Ntk_Network_t *specNetwork,
00889                     Ntk_Network_t *implNetwork,
00890                     int *initManagerHere)
00891 {
00892   bdd_manager *ddManager;
00893 
00894   /* Read the mdd Manager (or create it if necessary) */
00895   ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork);
00896 
00897   /* To set the spec manager the same as the impl. manager, either
00898    * both are nil, or the impl manager is freed and set to the
00899    * spec manager
00900    */
00901   if(ddManager != (bdd_manager *)Ntk_NetworkReadMddManager(implNetwork)) {
00902     if ((bdd_manager *)Ntk_NetworkReadMddManager(implNetwork) != NIL(bdd_manager)) {
00903       /* unacceptable if the impl. manager is different from NIl or
00904        * from the spec manager
00905        */
00906       mdd_quit(Ntk_NetworkReadMddManager(implNetwork));
00907     }
00908     Ntk_NetworkSetMddManager(implNetwork, (mdd_manager *)ddManager);
00909   }
00910 
00911   /* if the spec. manager is NIL, then network initialize manager */
00912   if (ddManager ==  NIL(bdd_manager)) {
00913     /* flag to say that manager is verified here */
00914     *initManagerHere = 1;
00915     ddManager = (bdd_manager *)Ntk_NetworkInitializeMddManager(specNetwork);
00916     Ntk_NetworkSetMddManager(implNetwork, (mdd_manager *)ddManager);
00917   }
00918   return (ddManager);
00919 } /* End of Initializebdd_manager */
00920 
00943 static int
00944 SetBasicResultInfo (Ntk_Network_t *specNetwork,
00945                     Ntk_Network_t *implNetwork,
00946                     int numDirectVerify)
00947 {
00948   int numInputs;
00949   int numOutputs;
00950   char *specName;
00951   char *implName;
00952   Res_ResidueInfo_t *resultSpec;
00953   Res_ResidueInfo_t *resultImpl;
00954 
00955   /* if previous verification to be considered, make sure the
00956    *  verification was with the same spec network and the number
00957    *  of directly verified outputs are the same.
00958    */
00959   resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork,
00960                                                     RES_NETWORK_APPL_KEY);
00961 
00962   if (resultSpec != NIL(Res_ResidueInfo_t)) {
00963     if ((strcmp(ResResidueInfoReadNameVerifiedAgainst(resultSpec),
00964               Ntk_NetworkReadName(implNetwork)) == 0) &&
00965         (ResResidueInfoReadNumDirectVerifiedOutputs(resultSpec) ==
00966                                                  numDirectVerify) &&
00967         (ResResidueInfoReadSuccess(resultSpec) == RES_PASS)) {
00968       /* if already verified then done, return success (0) */
00969       return RES_VERIFY_DONE;
00970     }
00971     /* if the above conditions are not satisfied, attempt
00972      * verification again
00973      */
00974     Ntk_NetworkFreeApplInfo(specNetwork, RES_NETWORK_APPL_KEY );
00975   }
00976 
00977 
00978   /* create result structure */
00979   resultSpec = (Res_ResidueInfo_t *)
00980     ResNetworkResidueInfoReadOrCreate(specNetwork);
00981   /* add hook to network */
00982   Ntk_NetworkAddApplInfo(specNetwork, RES_NETWORK_APPL_KEY,
00983                  (Ntk_ApplInfoFreeFn) Res_ResidueInfoFreeCallback,
00984                  (void *)resultSpec);
00985 
00986   /* number of outputs */
00987   numOutputs = Ntk_NetworkReadNumCombOutputs(specNetwork);
00988   ResResidueInfoSetNumOutputs(resultSpec, numOutputs);
00989   /* number of Inputs */
00990   numInputs = Ntk_NetworkReadNumCombInputs(specNetwork);
00991   ResResidueInfoSetNumInputs(resultSpec, numInputs);
00992   /* impl name */
00993   implName = util_strsav(Ntk_NetworkReadName(implNetwork));
00994   ResResidueInfoSetNameVerifiedAgainst(resultSpec, implName);
00995   /* number of directly verified outputs */
00996   ResResidueInfoSetNumDirectVerifiedOutputs(resultSpec, numDirectVerify);
00997 
00998   /*
00999    * Assumption: The implementation residue information is invalid even
01000    * if it does exist and will be overwritten
01001    */
01002   resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork,
01003                                         RES_NETWORK_APPL_KEY);
01004   /* free existing structure */
01005   if (resultImpl != NIL(Res_ResidueInfo_t)) {
01006     Ntk_NetworkFreeApplInfo(implNetwork,RES_NETWORK_APPL_KEY);
01007   }
01008 
01009   /* create a new structure for the implementation network */
01010   resultImpl = (Res_ResidueInfo_t *)
01011     ResNetworkResidueInfoReadOrCreate(implNetwork);
01012   Ntk_NetworkAddApplInfo(implNetwork, RES_NETWORK_APPL_KEY,
01013                 (Ntk_ApplInfoFreeFn) Res_ResidueInfoFreeCallback,
01014                 (void *)resultImpl);
01015 
01016 
01017   /*
01018    * Get some information about the network  and initialize the residue
01019    * information for the implementation network.
01020    */
01021 
01022   /* number of outputs */
01023   assert (numOutputs == Ntk_NetworkReadNumCombOutputs(implNetwork));
01024   ResResidueInfoSetNumOutputs(resultImpl, numOutputs);
01025   /* number of Inputs */
01026   assert (numInputs == Ntk_NetworkReadNumCombInputs(implNetwork));
01027   ResResidueInfoSetNumInputs(resultImpl, numInputs);
01028   /* spec name */
01029   specName = util_strsav(Ntk_NetworkReadName(specNetwork));
01030   ResResidueInfoSetNameVerifiedAgainst(resultImpl, specName);
01031   /* number of directly verified outputs */
01032   ResResidueInfoSetNumDirectVerifiedOutputs(resultImpl, numDirectVerify);
01033 
01034   return RES_VERIFY_IGNORE_PREV_RESULTS;
01035 } /* End of SetBasicResultInfo */
01036 
01058 static void
01059 Cleanup(int error,
01060         Ntk_Network_t *specNetwork,
01061         Ntk_Network_t *implNetwork,
01062         int initManagerHere,
01063         int done,
01064         st_table *outputMatch,
01065         st_table *inputMatch,
01066         st_table *directVerifyMatch,
01067         st_table *oldSpecMddIdTable,
01068         st_table *oldImplMddIdTable,
01069         array_t *specLayerArray,
01070         array_t *implLayerArray)
01071 {
01072   bdd_manager *ddManager;
01073 
01074   if (initManagerHere) {
01075     ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork);
01076     if (ddManager != NIL(bdd_manager)) {
01077       mdd_quit(ddManager);
01078       Ntk_NetworkSetMddManager(specNetwork, NIL(mdd_manager));
01079       Ntk_NetworkSetMddManager(implNetwork, NIL(mdd_manager));
01080     }
01081   }
01082 
01083   if (done != RES_VERIFY_NOTHING) {  /* if result structure allocated */
01084     if (error) { /* on error free results */
01085       if (done == RES_VERIFY_IGNORE_PREV_RESULTS) {
01086         /* if spec result was created here */
01087         Ntk_NetworkFreeApplInfo(specNetwork,RES_NETWORK_APPL_KEY);
01088       }
01089       Ntk_NetworkFreeApplInfo(implNetwork,RES_NETWORK_APPL_KEY);
01090     }
01091   }
01092   if (outputMatch != NIL(st_table)) {
01093     st_free_table(outputMatch);
01094   }
01095   if (inputMatch != NIL(st_table)) {
01096     st_free_table(inputMatch);
01097   }
01098   if (directVerifyMatch != NIL(st_table)) {
01099     st_free_table(directVerifyMatch);
01100   }
01101 
01102   if (oldSpecMddIdTable != NIL(st_table)) {
01103     RestoreOldMddIds(specNetwork, oldSpecMddIdTable);
01104     st_free_table(oldSpecMddIdTable);
01105   }
01106   if (oldImplMddIdTable != NIL(st_table)) {
01107     RestoreOldMddIds(implNetwork, oldImplMddIdTable);
01108     st_free_table(oldImplMddIdTable);
01109   }
01110   if (specLayerArray != NULL) {
01111     ResLayerArrayFree(specLayerArray);
01112   }
01113   if (implLayerArray != NULL) {
01114     ResLayerArrayFree(implLayerArray);
01115   }
01116   return;
01117 } /* End of Cleanup */
01118 
01119 
01132 static st_table *
01133 SaveOldMddIds(Ntk_Network_t *network)
01134 {
01135   st_table *oldMddIdTable;
01136   Ntk_Node_t *nodePtr;
01137   lsGen listGen;             /* To iterate over outputList */
01138 
01139   oldMddIdTable = st_init_table(st_ptrcmp, st_ptrhash);
01140   if (oldMddIdTable == NULL) return NIL(st_table);
01141 
01142   Ntk_NetworkForEachNode(network, listGen, nodePtr) {
01143     st_insert(oldMddIdTable, (char *)nodePtr,
01144               (char *)(long)Ntk_NodeReadMddId(nodePtr));
01145   }
01146   return(oldMddIdTable);
01147 }
01148 
01174 static int
01175 DirectVerification(Ntk_Network_t *specNetwork,
01176                    Ntk_Network_t *implNetwork,
01177                    st_table *directVerifyMatch,
01178                    st_table *inputMatch,
01179                    st_table *outputMatch,
01180                    array_t *outputOrderArray)
01181 {
01182 
01183     Ntk_Node_t *nodePtr, *implNodePtr;         /* node variables */
01184     long startTime, endTime, directVerifyTime; /* to measure elapsed time */
01185     long lapTimeSpec, lapTimeImpl;             /* to measure elapsed time */
01186     bdd_node *specBDD, *implBDD, *permutedBDD;   /* bdds of direct verified outputs */
01187     lsGen listGen;                             /* To iterate over outputList */
01188     int *permut;                              /* permutation array to store
01189                                                * correspondence of inputs
01190                                                */
01191     int specMddId, implMddId;
01192     Ntk_Node_t **specArray, **implArray;      /* arrays to store the
01193                                                * corresponding nodes of the
01194                                                * spec. and the impl.
01195                                                */
01196     st_generator *stGen;
01197     lsList dummy;                               /* dummy list fed to the ord
01198                                                  * package.
01199                                                  */
01200     char *key, *value;                          /* variables to read values
01201                                                  * from the st_table
01202                                                  */
01203     int index, i;                               /* iterators */
01204     char *name;                                 /* variable to read node name */
01205     int numOutputs;                             /* total number of outputs of
01206                                                  * the spec.(impl).
01207                                                  */
01208     bdd_manager *ddManager;                     /* the bdd manager */
01209     bdd_reorder_type_t oldDynMethod, dynMethod = BDD_REORDER_SAME;
01210                                                 /* dynamic reordering methods */
01211     int dynStatus = 0;                          /* original status of the manager
01212                                                  * w. r. t. dynamic reordering
01213                                                  */
01214     boolean dyn;                                /* current dynamic reordering
01215                                                  * status
01216                                                  */
01217     int verbose;                                /* verbosity level */
01218     char  *flagValue;                           /* string to hold "Set" variable
01219                                                  * value
01220                                                  */
01221     Res_ResidueInfo_t *resultSpec;              /* result structure for the
01222                                                  * spec.
01223                                                  */
01224     Res_ResidueInfo_t *resultImpl;              /* result structure for the
01225                                                  * impl.
01226                                                  */
01227     int specSize, implSize;                     /* sizes of bdds */
01228     mdd_t *fnMddT;                              /* mdd_t structure to calculate sizes */
01229 
01230 
01231     /* Initializations */
01232     dummy = (lsList)0;
01233     lapTimeSpec = 0;
01234     lapTimeImpl = 0;
01235     dyn = FALSE;
01236     verbose = 0;
01237 
01238     /* read verbosity value */
01239     flagValue = Cmd_FlagReadByName("residue_verbosity");
01240     if (flagValue != NIL(char)) {
01241       verbose = atoi(flagValue);
01242     }
01243 
01244     /* read if dynamic ordering is required */
01245     flagValue = Cmd_FlagReadByName("residue_autodyn_direct_verif");
01246     if (flagValue != NIL(char)) {
01247       dyn = (strcmp(flagValue, "1") == 0) ? TRUE : FALSE;
01248     }
01249     /* read method for dynamic reordering */
01250     if (dyn == TRUE) {
01251       flagValue = Cmd_FlagReadByName("residue_direct_dyn_method");
01252       if (flagValue != NULL) {
01253         dynMethod = DecodeDynMethod(flagValue);
01254       } else {
01255         dynMethod = BDD_REORDER_SAME;
01256       }
01257     }
01258 
01259     /* read manager from network */
01260     ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork);
01261     /* save old values for dynamic reordering */
01262     if (dyn == TRUE) {
01263       dynStatus = bdd_reordering_status(ddManager, &oldDynMethod);
01264       bdd_dynamic_reordering(ddManager, dynMethod, BDD_REORDER_VERBOSITY_DEFAULT);
01265     }
01266 
01267     /* find total time elapsed */
01268     directVerifyTime = util_cpu_time();
01269 
01270     /* find number of outputs to be directly verified */
01271     numOutputs = st_count(directVerifyMatch);
01272 
01273     /*
01274      * Order primary input variables in the network to build the BDDs for
01275      * outputs to be directly verified.
01276      */
01277     if (Ord_NetworkTestAreVariablesOrdered(specNetwork,
01278                                            Ord_InputAndLatch_c) == FALSE) {
01279       /* order the variables in the network since not done */
01280       startTime = util_cpu_time();
01281       Ord_NetworkOrderVariables(specNetwork, Ord_RootsByDefault_c,
01282                       Ord_NodesByDefault_c, FALSE, Ord_InputAndLatch_c,
01283                       Ord_Unassigned_c, dummy, 0);
01284 
01285       endTime = util_cpu_time();
01286       lapTimeSpec += endTime - startTime;
01287 
01288       startTime = endTime;
01289       Ord_NetworkOrderVariables(implNetwork, Ord_RootsByDefault_c,
01290                       Ord_NodesByDefault_c, FALSE, Ord_InputAndLatch_c,
01291                       Ord_Unassigned_c, dummy, 0);
01292       lapTimeImpl += endTime - startTime;
01293 
01294     } else {
01295       /* if order is not specified, assume the same order for spec.
01296        * and implementation
01297        */
01298       Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) {
01299         assert(Ntk_NodeReadMddId(nodePtr) != NTK_UNASSIGNED_MDD_ID);
01300         st_lookup(inputMatch, (char *)nodePtr, &implNodePtr);
01301         Ntk_NodeSetMddId(implNodePtr, Ntk_NodeReadMddId(nodePtr));
01302       }
01303     }
01304 
01305     if (verbose >= 5) {
01306       Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) {
01307         specMddId = Ntk_NodeReadMddId(nodePtr);
01308         if (specMddId != NTK_UNASSIGNED_MDD_ID) {
01309           fprintf(vis_stdout, "%s ", Ntk_NodeReadName(nodePtr));
01310         }
01311       }
01312       fprintf(vis_stdout, "\n");
01313       Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) {
01314         specMddId = Ntk_NodeReadMddId(nodePtr);
01315         if (specMddId != NTK_UNASSIGNED_MDD_ID) {
01316           fprintf(vis_stdout, "%d ", specMddId);
01317         }
01318       }
01319       fprintf(vis_stdout, "\n");
01320     }
01321 
01322     /* build arrays of corresponding nodes to be directly verified */
01323     specArray = ALLOC(Ntk_Node_t *, numOutputs);
01324     implArray = ALLOC(Ntk_Node_t *, numOutputs);
01325     index = 0;
01326     /* Order array starting from the LSB, so direct verification is performed
01327      * starting from the inputs.
01328      */
01329     for (i = 0; i < array_n(outputOrderArray); i++) {
01330       name = array_fetch(char *, outputOrderArray, array_n(outputOrderArray)-1-i);
01331       nodePtr = Ntk_NetworkFindNodeByName(specNetwork, name);
01332       /* find node in direct verify match table */
01333       if (st_lookup(directVerifyMatch, (char *)nodePtr, (char **)&value)) {
01334         specArray[index] = (Ntk_Node_t *)nodePtr;
01335         implArray[index] = (Ntk_Node_t *)value;
01336         index++;
01337       }
01338     }
01339     /* number of outputs in the arrays should be as many entries as the match
01340      * table.
01341      */
01342     assert(numOutputs == index);
01343 
01344     /* Create a permutation array for the specMddId and implMddId input nodes */
01345     permut = ALLOC(int, bdd_num_vars(ddManager));
01346     for (i= 0; (unsigned) i < bdd_num_vars(ddManager); i++) {
01347       permut[i] = i;
01348     }
01349     st_foreach_item(inputMatch, stGen, &key, &value) {
01350       nodePtr = (Ntk_Node_t *)key;
01351       implNodePtr = (Ntk_Node_t *)value;
01352       if ((nodePtr == NIL(Ntk_Node_t)) || (implNodePtr == NIL(Ntk_Node_t))){
01353         error_append("Input match values do not return");
01354         error_append("valid node pointers.\n");
01355         /* Clean up */
01356         FREE(permut);
01357         FREE(specArray);
01358         FREE(implArray);
01359         st_free_gen(stGen);
01360         return 1;
01361       }
01362       /* create the array with the impl. vars to be composed with spec. vars. */
01363       specMddId = Ntk_NodeReadMddId(nodePtr);
01364       implMddId = Ntk_NodeReadMddId(implNodePtr);
01365       /* there should be no node with NTK_UNASSIGNED_MDD_ID due to the
01366        * ordering above
01367        */
01368       assert(specMddId != NTK_UNASSIGNED_MDD_ID);
01369       assert(implMddId != NTK_UNASSIGNED_MDD_ID);
01370       permut[implMddId] = specMddId;
01371 
01372     } /* end of input match */
01373 
01374     /*
01375      * Build BDDs for each output to be directly verified and check
01376      * for identical BDDs in spec. and impl.
01377      */
01378     for (i = 0; i < numOutputs; i++) {
01379       /* build the spec BDD */
01380       startTime = util_cpu_time();
01381       specBDD = BuildBDDforNode(specNetwork, specArray[i], PRIMARY_INPUTS);
01382       if (specBDD == NIL(bdd_node)) {
01383         error_append("Unable to build spec. BDD for the direct verification output");
01384         error_append(Ntk_NodeReadName(specArray[i]));
01385         error_append(".\n");
01386         /* Clean up */
01387         FREE(permut);
01388         FREE(specArray);
01389         FREE(implArray);
01390         return 1; /* error status */
01391       } /* end of if spec BDD is NIL */
01392       endTime = util_cpu_time();
01393       lapTimeSpec += endTime - startTime;
01394 
01395       /* build the impl BDD */
01396       startTime = endTime;
01397       implBDD = BuildBDDforNode(implNetwork, implArray[i], PRIMARY_INPUTS);
01398       if (implBDD == NIL(bdd_node)) {
01399         error_append("Unable to build spec. BDD for the direct verification output");
01400         error_append(Ntk_NodeReadName(implArray[i]));
01401         error_append(".\n");
01402         /* Clean up */
01403         bdd_recursive_deref(ddManager, specBDD);
01404         FREE(permut);
01405         FREE(specArray);
01406         FREE(implArray);
01407         return 1; /* error status */
01408       } /* end of if spec BDD is NIL */
01409       endTime = util_cpu_time();
01410       lapTimeImpl += endTime - startTime;
01411 
01412       /* call bdd permute to compose the impl variables with the spec
01413        * variables.
01414        */
01415       startTime = endTime;
01416       bdd_ref(permutedBDD = bdd_bdd_permute(ddManager, implBDD, permut));
01417       bdd_recursive_deref(ddManager, implBDD);
01418       endTime = util_cpu_time();
01419       lapTimeSpec += (endTime - startTime)/2;
01420       lapTimeImpl += (endTime - startTime)/2;
01421       implBDD = permutedBDD;
01422       if (implBDD == NIL(bdd_node)) {
01423         error_append("Permuting the impl bdd in terms of spec bdd vars failed\n");
01424         /* Clean up */
01425         bdd_recursive_deref(ddManager, specBDD);
01426         FREE(permut);
01427         FREE(specArray);
01428         FREE(implArray);
01429         return 1; /* error status */
01430       }
01431 
01432       /* compare the bdds */
01433       if(specBDD != implBDD)  {
01434         /* error since spec and impl are not the same */
01435         /* update result structure */
01436         if (verbose >= 2) {
01437           (void)fprintf(vis_stdout, "Vector where the two networks differ :\n");
01438           (void)fprintf(vis_stdout, "Specification Input Names :\n");
01439           ExtractACubeOfDifference(ddManager, specNetwork, specBDD, implBDD);
01440         }
01441         resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork,
01442                                           RES_NETWORK_APPL_KEY);
01443         resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork,
01444                                           RES_NETWORK_APPL_KEY);
01445         ResResidueInfoSetDirectVerificationSuccess(resultSpec, RES_FAIL);
01446         ResResidueInfoSetDirectVerificationSuccess(resultImpl, RES_FAIL);
01447         (void) fprintf(vis_stdout, "%.2f (secs) spent in failed direct verification.\n",
01448                        (util_cpu_time() - directVerifyTime)/1000.0);
01449         fprintf(vis_stdout, "Residue Direct Verification failed at output node ");
01450         fprintf(vis_stdout, "%s", Ntk_NodeReadName(specArray[i]));
01451         fprintf(vis_stdout, " of the spec.\n");
01452         fprintf(vis_stdout, "Spec. did not match Impl.\n");
01453         /* Clean up */
01454         /* free the bdds just created */
01455         bdd_recursive_deref(ddManager, specBDD);
01456         bdd_recursive_deref(ddManager, implBDD);
01457         FREE(permut);
01458         FREE(specArray);
01459         FREE(implArray);
01460         return 0;
01461       } /* end if spec BDD != impl BDD */
01462 
01463       /* if the bdds are equal, print some information */
01464       if (verbose >= 2) {
01465         fprintf(vis_stdout, "%d out of %d ", i + 1 ,numOutputs);
01466         fprintf(vis_stdout, "direct verification outputs done.\n");
01467       }
01468       if (verbose >= 3) {
01469         fprintf(vis_stdout, "%s(spec)/%s(impl) output verified. \n",
01470                 Ntk_NodeReadName(specArray[i]), Ntk_NodeReadName(implArray[i]));
01471         bdd_ref(specBDD);
01472         fnMddT = bdd_construct_bdd_t(ddManager, specBDD);
01473         specSize = bdd_size(fnMddT);
01474         bdd_free(fnMddT);
01475         bdd_ref(implBDD);
01476         fnMddT = bdd_construct_bdd_t(ddManager, implBDD);
01477         implSize = bdd_size(fnMddT);
01478         bdd_free(fnMddT);
01479         fprintf(vis_stdout, "Size of %s(spec) = %d, Size of %s(impl) = %d\n",
01480          Ntk_NodeReadName(specArray[i]) ,specSize, Ntk_NodeReadName(implArray[i]), implSize);
01481         fprintf(vis_stdout, "%.3f spec time elapsed, %.3f impl. time elapsed.\n", lapTimeSpec/1000.0,
01482                 lapTimeImpl/1000.0);
01483       }
01484       /* free the bdds just created */
01485       bdd_recursive_deref(ddManager, specBDD);
01486       bdd_recursive_deref(ddManager, implBDD);
01487 
01488     } /* end of for-loop that iterates through the nodes to be directly
01489        * verified.
01490        */
01491 
01492     FREE(permut);
01493     FREE(specArray);
01494     FREE(implArray);
01495 
01496     /* set direct verification success info */
01497     /* update result structure */
01498     resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork,
01499                                                         RES_NETWORK_APPL_KEY);
01500     resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork,
01501                                                         RES_NETWORK_APPL_KEY);
01502     ResResidueInfoSetDirectVerificationSuccess(resultSpec, RES_PASS);
01503     ResResidueInfoSetCpuDirectVerif(resultSpec, (float) lapTimeSpec);
01504     ResResidueInfoSetDirectVerificationSuccess(resultImpl, RES_PASS);
01505     ResResidueInfoSetCpuDirectVerif(resultImpl, (float) lapTimeImpl);
01506 
01507     /* Print success message */
01508     fprintf(vis_stdout, "Residue Direct Verification successful.\n");
01509 
01510     /* Print Time taken for direct verification */
01511     if (verbose >= 1) {
01512       (void) fprintf(vis_stdout, "%.2f (secs) spent in Direct verification.\n",
01513                        (util_cpu_time() - directVerifyTime)/1000.0);
01514     }
01515 
01516     /* Print which outputs were directly verified and time spent for
01517      * the spec and the impl
01518      */
01519     if (verbose >= 2) {
01520       fprintf(vis_stdout, "Time taken to build spec. BDD = %.3f\n",
01521               ResResidueInfoReadCpuDirectVerif(resultSpec)/1000.0);
01522       fprintf(vis_stdout, "Time taken to build impl. BDD = %.3f\n",
01523               ResResidueInfoReadCpuDirectVerif(resultImpl)/1000.0);
01524       st_foreach_item(directVerifyMatch, stGen, &key, &value) {
01525         fprintf(vis_stdout, "%s ", Ntk_NodeReadName((Ntk_Node_t *)key));
01526       }
01527       fprintf(vis_stdout, "verified successfully.\n");
01528     }
01529 
01530     /* Print order of variables of this verification */
01531     if (verbose >= 3) {
01532       Ord_NetworkPrintVariableOrder(vis_stdout, specNetwork,
01533       Ord_InputAndLatch_c);
01534       Ord_NetworkPrintVariableOrder(vis_stdout, implNetwork,
01535       Ord_InputAndLatch_c);
01536     }
01537 
01538     /* restore the old values for dynamic reordering */
01539     if(dyn == TRUE) {
01540       bdd_dynamic_reordering(ddManager, oldDynMethod, BDD_REORDER_VERBOSITY_DEFAULT);
01541       if (!dynStatus) {
01542         bdd_dynamic_reordering_disable(ddManager);
01543       }
01544     }
01545 
01546     return 0; /* direct verification success */
01547 } /* End of Direct Verification */
01548 
01549 
01559 static bdd_reorder_type_t
01560 DecodeDynMethod(char *dynMethodString)
01561 {
01562   bdd_reorder_type_t dynMethod;
01563 
01564   /* Translate reordering string to specifying method */
01565   if (dynMethodString == NIL(char)) {
01566     dynMethod = BDD_REORDER_SIFT;
01567   } else if (strcmp(dynMethodString, "same") == 0) {
01568     dynMethod = BDD_REORDER_SAME;
01569   } else if (strcmp(dynMethodString, "none") == 0) {
01570     dynMethod = BDD_REORDER_NONE;
01571   } else if (strcmp(dynMethodString, "random") == 0) {
01572     dynMethod = BDD_REORDER_RANDOM;
01573   } else if (strcmp(dynMethodString, "randompivot") == 0) {
01574     dynMethod = BDD_REORDER_RANDOM_PIVOT;
01575   } else if (strcmp(dynMethodString, "sift") == 0) {
01576     dynMethod = BDD_REORDER_SIFT;
01577   } else if (strcmp(dynMethodString, "siftconverge") == 0) {
01578     dynMethod = BDD_REORDER_SIFT_CONVERGE;
01579   } else if (strcmp(dynMethodString, "symmsift") == 0) {
01580     dynMethod = BDD_REORDER_SYMM_SIFT;
01581   } else if (strcmp(dynMethodString, "symmsiftconverge") == 0) {
01582     dynMethod = BDD_REORDER_SYMM_SIFT_CONV;
01583   } else if (strcmp(dynMethodString, "window2") == 0) {
01584     dynMethod = BDD_REORDER_WINDOW2;
01585   } else if (strcmp(dynMethodString, "window3") == 0) {
01586     dynMethod = BDD_REORDER_WINDOW3;
01587   } else if (strcmp(dynMethodString, "window4") == 0) {
01588     dynMethod = BDD_REORDER_WINDOW4;
01589   } else if (strcmp(dynMethodString, "window2converge") == 0) {
01590     dynMethod = BDD_REORDER_WINDOW2_CONV;
01591   } else if (strcmp(dynMethodString, "window3converge") == 0) {
01592     dynMethod = BDD_REORDER_WINDOW3_CONV;
01593   } else if (strcmp(dynMethodString, "window4converge") == 0) {
01594     dynMethod = BDD_REORDER_WINDOW4_CONV;
01595   } else if (strcmp(dynMethodString, "groupsift") == 0) {
01596     dynMethod = BDD_REORDER_GROUP_SIFT;
01597   } else if (strcmp(dynMethodString, "groupsiftconverge") == 0) {
01598     dynMethod = BDD_REORDER_GROUP_SIFT_CONV;
01599   } else if (strcmp(dynMethodString, "anneal") == 0) {
01600     dynMethod = BDD_REORDER_ANNEALING;
01601   } else if (strcmp(dynMethodString, "genetic") == 0) {
01602     dynMethod = BDD_REORDER_GENETIC;
01603   } else if (strcmp(dynMethodString, "linear") == 0) {
01604     dynMethod = BDD_REORDER_LINEAR;
01605   } else if (strcmp(dynMethodString, "linearconverge") == 0) {
01606     dynMethod = BDD_REORDER_LINEAR_CONVERGE;
01607   } else if (strcmp(dynMethodString, "exact") == 0) {
01608     dynMethod = BDD_REORDER_EXACT;
01609   } else {
01610     dynMethod = BDD_REORDER_SIFT;
01611   }
01612   return dynMethod;
01613 } /* End of DecodeDynMethod */
01614 
01615 
01616 
01643 static int
01644 ResidueVerification(Ntk_Network_t *specNetwork,
01645                     Ntk_Network_t *implNetwork,
01646                     st_table *outputMatch,
01647                     st_table *inputMatch,
01648                     int numDirectVerify,
01649                     array_t *specLayerArray,
01650                     array_t *implLayerArray,
01651                     array_t *outputArray)
01652 {
01653   int numOutputs;                 /* number of outputs in the networks */
01654   int actualOutputs;                 /* number of outputs in the networks */
01655   int msbId;                      /* stores the top Id available */
01656   int msbLsb;                     /* 1 means Msb on top */
01657 
01658   Ntk_Node_t *nodePtr, *implNodePtr; /* variables to store nodes in networks */
01659 
01660   Res_ResidueInfo_t *resultSpec;   /* spec. result structure */
01661   Res_ResidueInfo_t *resultImpl;   /* impl. result structure */
01662 
01663   int verbose;                     /* verbosity value */
01664   char *flagValue;                 /* string to store flag values */
01665   int i;                           /* iterating index */
01666 
01667   lsGen listGen;                   /* list generator for looping over nodes
01668                                     * in a network.
01669                                     */
01670   st_generator *stGen;     /* generator to step through st_table */
01671   char *key, *value;               /* variables to read in st-table values */
01672   long overallLap;      /* to measure elapsed time */
01673   long lap;     /* to measure elapsed time */
01674   int primeIndex;       /* index to iterate over prime array */
01675   bdd_manager *ddManager;      /* Manager read from the network */
01676   bdd_node *implADD, *specADD, *tmpDd; /* final ADDs after composition */
01677   int specSize, implSize;               /* sizes of bdds */
01678   int specMddId, implMddId;  /* id variables for nodes */
01679   bdd_node *residueDd;  /* residue ADD (n x m) */
01680   int *permut;  /* array to permute impl ADD variables to spec.
01681                                  * ADD variables.
01682                                  */
01683   int numOfPrimes;      /* Number of primes needed for verification */
01684   int *primeTable;      /* array to store primes needed for current
01685                                  * verification
01686                                  */
01687   bdd_reorder_type_t oldDynMethod, dynMethod; /* dynamic reordering
01688                                                * methods
01689                                                */
01690   int dynStatus;                /* Status of manager w.r.t. original
01691                                  * reordering
01692                                  */
01693   boolean dyn;          /* flag to indicate dynamic reordering
01694                                  * is turned on.
01695                                  */
01696   mdd_t *fnMddT;                /* mdd_t structure to calculate sizes */
01697   int unassignedValue;          /* NTK_UNASSIGNED_MDD_ID value holder */
01698   array_t *implOutputArray;     /* array of output nodes of the impl.in consideration
01699                                  * for composition
01700                                  */
01701 
01702   /* Initialization */
01703   verbose = 0;
01704   unassignedValue =  NTK_UNASSIGNED_MDD_ID;
01705   numOfPrimes = 0;
01706   msbLsb = 1; /* default value msb is on top */
01707   primeTable = NULL;
01708   overallLap = util_cpu_time();
01709   dyn = FALSE; /* default dynamic reordering disabled */
01710   permut = NULL;
01711 
01712   /* specify if the top var of the residue ADD is the MSB/LSB */
01713   flagValue = Cmd_FlagReadByName("residue_top_var");
01714   if (flagValue != NIL(char) && strcmp(flagValue,"lsb") == 0) {
01715     msbLsb = 0;
01716   } else {
01717     msbLsb = 1;
01718   }
01719 
01720   /* initialize number of outputs */
01721   actualOutputs = Ntk_NetworkReadNumCombOutputs(specNetwork);
01722 
01723   /* Read the mdd Manager (or create it if necessary) */
01724   ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork);
01725     /* save old dynamic reordering values */
01726   dynStatus = bdd_reordering_status(ddManager, &oldDynMethod);
01727 
01728   /* read verbosity value */
01729   flagValue = Cmd_FlagReadByName("residue_verbosity");
01730   if (flagValue != NIL(char)) {
01731     verbose = atoi(flagValue);
01732   }
01733 
01734   /* read if dynamic ordering is required */
01735   flagValue = Cmd_FlagReadByName("residue_autodyn_residue_verif");
01736   if (flagValue != NIL(char)) {
01737     dyn = (strcmp(flagValue,"1")==0) ? TRUE : FALSE;
01738   }
01739   /* read method of dynamic reordering */
01740   if (dyn == TRUE) {
01741     flagValue = Cmd_FlagReadByName("residue_residue_dyn_method");
01742     if ( flagValue != NULL) {
01743       dynMethod = DecodeDynMethod(flagValue);
01744     } else {
01745       dynMethod = BDD_REORDER_SAME;
01746     }
01747     /* update manager with dynamic reordering and the method */
01748     bdd_dynamic_reordering(ddManager, dynMethod, BDD_REORDER_VERBOSITY_DEFAULT);
01749   } else {
01750     /* unless specified, TURN REORDERING OFF for residue verification */
01751     bdd_dynamic_reordering_disable(ddManager);
01752   }
01753 
01754   /*
01755    * Choose the set of primes that will be used, primeTable is allocated
01756    * here.
01757    */
01758   numOfPrimes = ChoosePrimes(actualOutputs,  &primeTable, numDirectVerify);
01759 
01760   /* get result structures */
01761   resultSpec = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(specNetwork,
01762                                                     RES_NETWORK_APPL_KEY);
01763   resultImpl = (Res_ResidueInfo_t *)Ntk_NetworkReadApplInfo(implNetwork,
01764                                                     RES_NETWORK_APPL_KEY);
01765 
01766   /* update result with primes info */
01767   if ((resultSpec  != NIL(Res_ResidueInfo_t)) && (resultImpl != NIL(Res_ResidueInfo_t))) {
01768     ResResidueInfoAllocatePrimeInfoArray(resultSpec, numOfPrimes, primeTable);
01769     ResResidueInfoAllocatePrimeInfoArray(resultImpl, numOfPrimes, primeTable);
01770     ResResidueInfoSetNumOfPrimes(resultSpec, numOfPrimes);
01771     ResResidueInfoSetNumOfPrimes(resultImpl, numOfPrimes);
01772   } else {
01773     /* error - the result structure should be there */
01774     error_append("Result structures are missing\n");
01775     FREE(primeTable);
01776     return 1;
01777   }
01778 
01779   /* Print the list of primes depending on the verbosity level*/
01780   if (verbose >= 0) {
01781     (void) fprintf(vis_stdout, "List of Primes used: ");
01782     for(i=0; i<numOfPrimes; i++) {
01783       (void) fprintf(vis_stdout, "%d ", primeTable[i]);
01784     }
01785     (void) fprintf(vis_stdout, "\n");
01786   } /* End of if */
01787 
01788   /* form impl Output Array */
01789   implOutputArray = array_alloc(Ntk_Node_t *, array_n(outputArray));
01790   arrayForEachItem(Ntk_Node_t *, outputArray, i, nodePtr) {
01791     st_lookup(outputMatch, (char *)nodePtr, &implNodePtr);
01792     array_insert(Ntk_Node_t *, implOutputArray, i, implNodePtr);
01793   }
01794 
01795   /* number of outputs in consideration */
01796   numOutputs = array_n(outputArray);
01797 
01798 
01799   /* Main Loop in which the verification is done for each prime. */
01800   for(primeIndex = 0; primeIndex < numOfPrimes; primeIndex++) {
01801     int currentPrime;
01802 
01803     /* Read current prime from table */
01804     currentPrime = primeTable[primeIndex];
01805     if (verbose >=2)
01806       (void) fprintf(vis_stdout, "Processing prime %d:\n", currentPrime);
01807 
01808     /* update the mdd manager with the first set of output variables */
01809     MddCreateVariables((mdd_manager *)ddManager, numOutputs-bdd_num_vars(ddManager));
01810 
01811 
01812     /* Obtain the residue bdd for the given prime, assume top id is
01813      * always 0i.e. msbId = 0;
01814      */
01815     msbId = 0;
01816     bdd_ref(residueDd = bdd_add_residue(ddManager, numOutputs, currentPrime,
01817                                          msbLsb, msbId));
01818 
01819     /*  Set the output Id. Needs to be set each time because it gets
01820      * cleared each time.
01821      */
01822     arrayForEachItem(Ntk_Node_t *, outputArray, i , nodePtr) {
01823       st_lookup(outputMatch, (char *)nodePtr, &implNodePtr);
01824       if (msbLsb == 1) {
01825         Ntk_NodeSetMddId(nodePtr, i);
01826         Ntk_NodeSetMddId(implNodePtr, i);
01827       } else {
01828         Ntk_NodeSetMddId(nodePtr, numOutputs - i);
01829         Ntk_NodeSetMddId(implNodePtr, numOutputs - i);
01830       }
01831     }
01832 
01833 
01834     /* Set the cpu usage lap */
01835     lap = util_cpu_time();
01836 
01837     if (verbose >= 1) {
01838       fprintf(vis_stdout, "Specification being built\n");
01839     }
01840     /* the actual composition of the spec. network into the residue ADD
01841      * is done here. The composed ADD return is referenced
01842      */
01843     specADD = ComposeLayersIntoResidue(specNetwork, specLayerArray, residueDd, outputArray);
01844     if (specADD == NIL(bdd_node)) {
01845       error_append("Composition of spec. failed.\n");
01846       /* Clean up before you leave */
01847       array_free(implOutputArray);
01848       FREE(primeTable);
01849       bdd_recursive_deref(ddManager, residueDd);
01850       return 1; /* error return */
01851     }
01852 
01853     /* Store the information in the result structure of the spec.*/
01854     bdd_ref(specADD);
01855     fnMddT = bdd_construct_bdd_t(ddManager, specADD);
01856     specSize = bdd_size(fnMddT);
01857     bdd_free(fnMddT);
01858     ResResidueInfoSetPerPrimeInfo(resultSpec, primeIndex, currentPrime,
01859                                   (util_cpu_time() - lap)/1000.0, specSize, specADD);
01860     /* Print info regarding this prime if pertinent */
01861     if (verbose >=3) {
01862       (void) fprintf(vis_stdout, "%.2f (secs) spent in composing prime\n",
01863                      ResResidueInfoReadPerPrimeInfo(resultSpec, primeIndex)->cpuTime);
01864       (void) fprintf(vis_stdout, "Composed Dd with %d nodes\n", specSize);
01865     }
01866 
01867     /* Set the cpu usage lap */
01868     lap = util_cpu_time();
01869 
01870     /*
01871      * the actual composition of the impl. network into the residue ADD
01872      * is done here. The composed ADD return is referenced
01873      */
01874     if (verbose >= 1) {
01875       fprintf(vis_stdout, "Implementation being built\n");
01876     }
01877     implADD = ComposeLayersIntoResidue(implNetwork, implLayerArray, residueDd, implOutputArray);
01878 
01879     bdd_recursive_deref(ddManager, residueDd);
01880     if (implADD == NIL(bdd_node)) {
01881       error_append("Composition of spec. failed.\n");
01882       /* Clean up before you leave */
01883       bdd_recursive_deref(ddManager, specADD);
01884       array_free(implOutputArray);
01885       FREE(primeTable);
01886       return 1; /* error return */
01887     }
01888 
01889     /* Create a permutation array for the specMddId and implMddId input nodes */
01890     permut = ALLOC(int, bdd_num_vars(ddManager));
01891     for (i= 0; (unsigned) i < bdd_num_vars(ddManager); i++) {
01892       permut[i] = i;
01893     }
01894     st_foreach_item(inputMatch, stGen, &key, &value) {
01895       nodePtr = (Ntk_Node_t *)key;
01896       implNodePtr = (Ntk_Node_t *)value;
01897       if ((nodePtr == NIL(Ntk_Node_t)) || (implNodePtr == NIL(Ntk_Node_t))){
01898         error_append("Input match values do not return");
01899         error_append("valid node pointers.\n");
01900         /* Clean up */
01901         FREE(permut);
01902         FREE(primeTable);
01903         array_free(implOutputArray);
01904         bdd_recursive_deref(ddManager, specADD);
01905         bdd_recursive_deref(ddManager, implADD);
01906         st_free_gen(stGen);
01907         return 1;
01908       }
01909       /* create the array with the impl. vars to be composed with spec. vars. */
01910       specMddId = Ntk_NodeReadMddId(nodePtr);
01911       implMddId = Ntk_NodeReadMddId(implNodePtr);
01912 
01913       /* there should be no node with NTK_UNASSIGNED_MDD_ID due to the
01914        * ordering above
01915        */
01916 
01917 #if 0
01918       if (Ntk_NodeReadNumFanouts(nodePtr) != 0) {
01919         assert(specMddId != NTK_UNASSIGNED_MDD_ID);
01920       }
01921       if (Ntk_NodeReadNumFanouts(implNodePtr) != 0) {
01922         assert(implMddId != NTK_UNASSIGNED_MDD_ID);
01923       }
01924 #endif
01925 
01926       if ((specMddId != NTK_UNASSIGNED_MDD_ID) &&
01927           (implMddId != NTK_UNASSIGNED_MDD_ID)) {
01928         permut[implMddId] = specMddId;
01929       } else {
01930         assert(specMddId == implMddId);
01931       }
01932 
01933     } /* end of st_foreach_item */
01934 
01935     /* permute the variables so that the impl variables are replaced by
01936      * spec. variables
01937      */
01938     bdd_ref(tmpDd = bdd_add_permute(ddManager, implADD, permut));
01939     bdd_recursive_deref(ddManager, implADD);
01940     FREE(permut);
01941     implADD = tmpDd;
01942     if(implADD == NIL(bdd_node)) { /* error */
01943       error_append("Last composition failed,");
01944       error_append("Cannot compose spec. ADD PI vars into Impl. ADD.\n");
01945       FREE(primeTable);
01946       array_free(implOutputArray);
01947       return 1; /* error return */
01948     }
01949 
01950     if (verbose > 0) {
01951       (void) fprintf(vis_stdout, "%.2f (secs) spent in residue verification.\n",
01952                      (util_cpu_time() - overallLap)/1000.0);
01953     }
01954 
01955     /* Store the information in the result structure of the impl.*/
01956     bdd_ref(implADD);
01957     fnMddT = bdd_construct_bdd_t(ddManager, implADD);
01958     implSize = bdd_size(fnMddT);
01959     bdd_free(fnMddT);
01960     ResResidueInfoSetPerPrimeInfo(resultImpl, primeIndex, currentPrime,
01961          (util_cpu_time() - lap)/1000.0, implSize, implADD);
01962     /* Print info regarding this prime if pertinent */
01963     if (verbose >=3) {
01964       (void) fprintf(vis_stdout, "%.2f (secs) spent in composing prime\n",
01965                      ResResidueInfoReadPerPrimeInfo(resultImpl, primeIndex)->cpuTime);
01966       (void) fprintf(vis_stdout, "Composed Dd with %d nodes\n", implSize);
01967     }
01968 
01969 
01970     /* Compare the Spec and the Impl composed Dds */
01971     if (ResResidueInfoReadPerPrimeInfo(resultSpec, primeIndex)->residueDd !=
01972         ResResidueInfoReadPerPrimeInfo(resultImpl, primeIndex)->residueDd) {
01973       ResResidueInfoSetSuccess(resultSpec, RES_FAIL);
01974       ResResidueInfoSetSuccess(resultImpl, RES_FAIL);
01975       (void) fprintf(vis_stdout, "Verification of %s and %s failed.\n",
01976                      Res_ResidueInfoReadName(resultSpec),
01977                      Res_ResidueInfoReadName(resultImpl));
01978       (void)fprintf(vis_stdout,"The composed ADDs with residue are not the same.\n");
01979       (void)fprintf(vis_stdout,"Verification failed at prime %d.\n", currentPrime);
01980       if (verbose >= 2) {
01981         (void)fprintf(vis_stdout, "Vector where the two networks differ :\n");
01982         (void)fprintf(vis_stdout, "Specification Input Names :\n");
01983         ExtractACubeOfDifference(ddManager, specNetwork, specADD, implADD);
01984       }
01985 
01986       /* Clean up before you leave */
01987       bdd_recursive_deref(ddManager, ResResidueInfoReadPerPrimeInfo(resultSpec, primeIndex)->residueDd);
01988       ResResidueInfoSetPerPrimeDd(resultSpec, primeIndex, NIL(bdd_node));
01989 
01990       bdd_recursive_deref(ddManager, ResResidueInfoReadPerPrimeInfo(resultImpl, primeIndex)->residueDd);
01991       ResResidueInfoSetPerPrimeDd(resultImpl, primeIndex, NIL(bdd_node));
01992       array_free(implOutputArray);
01993       FREE(primeTable);
01994       return 0;
01995     } else {
01996 
01997       /* free the result Dd*/
01998       bdd_recursive_deref(ddManager, ResResidueInfoReadPerPrimeInfo(resultSpec, primeIndex)->residueDd);
01999       ResResidueInfoSetPerPrimeDd(resultSpec, primeIndex, NIL(bdd_node));
02000 
02001       bdd_recursive_deref(ddManager, ResResidueInfoReadPerPrimeInfo(resultImpl, primeIndex)->residueDd);
02002       ResResidueInfoSetPerPrimeDd(resultImpl, primeIndex, NIL(bdd_node));
02003     }
02004 
02005 
02006     /* reset node Ids of primary inputs */
02007     Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) {
02008       Ntk_NodeSetMddId(nodePtr, unassignedValue);
02009     }
02010     Ntk_NetworkForEachCombInput(implNetwork, listGen, nodePtr) {
02011       Ntk_NodeSetMddId(nodePtr, unassignedValue);
02012     }
02013 
02014 
02015   } /* End of the main for-loop */
02016   FREE(primeTable);
02017   array_free(implOutputArray);
02018 
02019   /* restore old dynamic reordering values */
02020   bdd_dynamic_reordering(ddManager, oldDynMethod, BDD_REORDER_VERBOSITY_DEFAULT);
02021   if (!dynStatus) {
02022     bdd_dynamic_reordering_disable(ddManager);
02023   }
02024 
02025   /* set pass flag if residue verification success and direct verification
02026    * success.
02027    */
02028   if (((numDirectVerify) &&
02029        (ResResidueInfoReadDirectVerificationSuccess(resultSpec) == RES_PASS)) ||
02030        (ResResidueInfoReadDirectVerificationSuccess(resultSpec) != RES_FAIL)) {
02031     ResResidueInfoSetSuccess(resultSpec, RES_PASS);
02032   }
02033   if (((numDirectVerify) &&
02034        (ResResidueInfoReadDirectVerificationSuccess(resultImpl) == RES_PASS)) ||
02035       (ResResidueInfoReadDirectVerificationSuccess(resultImpl) != RES_FAIL)) {
02036     ResResidueInfoSetSuccess(resultImpl, RES_PASS);
02037   }
02038   return 0;
02039 } /* End of ResidueVerification */
02040 
02053 static void
02054 ExtractACubeOfDifference(bdd_manager *mgr,
02055                          Ntk_Network_t *specNetwork,
02056                          bdd_node *fn1,
02057                          bdd_node *fn2)
02058 {
02059   bdd_t *fnMddT, *fnMddT1;      /* mdd_t structure to calculate sizes */
02060   bdd_t *fnMddT2, *fnMddT3;     /* mdd_t structure to calculate sizes */
02061   bdd_gen *gen;
02062   array_t *cube, *namesArray;
02063   lsGen listGen;
02064   int i, literal;
02065   Ntk_Node_t *nodePtr;
02066 
02067   /* make bdd_ts of the two functions */
02068   bdd_ref(fn2);
02069   fnMddT = bdd_construct_bdd_t(mgr, fn2);
02070   bdd_ref(fn1);
02071   fnMddT1 = bdd_construct_bdd_t(mgr, fn1);
02072   fnMddT2 = bdd_not(fnMddT1);
02073   /* extracts some cubes in the intersection of fn1' and fn2 */
02074   fnMddT3 = bdd_intersects(fnMddT, fnMddT2);
02075   /* check not zero */
02076   if (bdd_is_tautology(fnMddT3, 0)) {
02077     bdd_free(fnMddT3);
02078     bdd_free(fnMddT2);
02079     /* extracts some cubes in the intersection of fn2' and fn1 */
02080     fnMddT2 = bdd_not(fnMddT);
02081     fnMddT3 = bdd_intersects(fnMddT1, fnMddT2);
02082   }
02083   assert(!bdd_is_tautology(fnMddT3, 0));
02084   bdd_free(fnMddT);
02085   bdd_free(fnMddT1);
02086   bdd_free(fnMddT2);
02087 
02088   /* pick a cube from the xor of fn1 and fn2 */
02089   gen = bdd_first_cube(fnMddT3, &cube);
02090   bdd_free(fnMddT3);
02091 
02092   /* store the names to be printed out later */
02093   namesArray = array_alloc(char *, array_n(cube));
02094   Ntk_NetworkForEachCombInput(specNetwork, listGen, nodePtr) {
02095     array_insert(char *, namesArray , Ntk_NodeReadMddId(nodePtr),  Ntk_NodeReadName(nodePtr));
02096   }
02097 
02098   /* print out the cube */
02099   arrayForEachItem(int, cube, i, literal) {
02100     if (literal != 2) {
02101       (void) fprintf(vis_stdout, "%s ", array_fetch(char *, namesArray, i));
02102     }
02103   }
02104   fprintf(vis_stdout, "\n");
02105   arrayForEachItem(int, cube, i, literal) {
02106     if (literal != 2) {
02107       (void) fprintf(vis_stdout, "%1d", literal);
02108     }
02109   }
02110   fprintf(vis_stdout, "\n");
02111   array_free(namesArray);
02112   bdd_gen_free(gen);
02113   return;
02114 }