VIS

src/synth/synthSynth.c

Go to the documentation of this file.
00001 
00023 #include "synthInt.h"
00024 
00025 static char rcsid[] UNUSED = "$Id: synthSynth.c,v 1.47 2005/04/23 14:37:51 jinh Exp $";
00026 
00027 
00028 /*---------------------------------------------------------------------------*/
00029 /* Constant declarations                                                     */
00030 /*---------------------------------------------------------------------------*/
00031 
00032 
00033 /*---------------------------------------------------------------------------*/
00034 /* Type declarations                                                         */
00035 /*---------------------------------------------------------------------------*/
00036 
00037 
00038 /*---------------------------------------------------------------------------*/
00039 /* Structure declarations                                                    */
00040 /*---------------------------------------------------------------------------*/
00041 
00042 
00043 /*---------------------------------------------------------------------------*/
00044 /* Variable declarations                                                     */
00045 /*---------------------------------------------------------------------------*/
00046 
00047 
00048 /*---------------------------------------------------------------------------*/
00049 /* Macro declarations                                                        */
00050 /*---------------------------------------------------------------------------*/
00051 
00052 
00055 /*---------------------------------------------------------------------------*/
00056 /* Static function prototypes                                                */
00057 /*---------------------------------------------------------------------------*/
00058 
00059 static int synthesizeNetwork(Ntk_Network_t *network, graph_t *partition, Fsm_Fsm_t *fsm, st_table *careBddTable, Synth_InfoData_t *synthInfo, int verbosity);
00060 static int IsPartitionValid(Ntk_Network_t *network, graph_t *partition);
00061 static array_t * GetCombOutputNameArray(Ntk_Network_t *network);
00062 static array_t * GetCombInputIdArray(Ntk_Network_t *network);
00063 static bdd_node ** GetBddArray(Mvf_Function_t *combMvfs);
00064 
00068 /*---------------------------------------------------------------------------*/
00069 /* Definition of exported functions                                          */
00070 /*---------------------------------------------------------------------------*/
00071 
00084 Synth_InfoData_t *
00085 Synth_InitializeInfo(int factoring,
00086                      int divisor,
00087                      int unreachDC,
00088                      int reordering,
00089                      int trySharing,
00090                      int realign,
00091                      char *filehead,
00092                      char *prefix,
00093                      boolean eqn)
00094 {
00095 
00096   Synth_InfoData_t *synthInfo;
00097 
00098   synthInfo = ALLOC(Synth_InfoData_t, 1);
00099   if (!synthInfo) {
00100     (void) fprintf(vis_stderr,
00101                    "** synth error: Could not initialize info structure.\n");
00102     return NIL(Synth_InfoData_t);
00103   }
00104   synthInfo->factoring = factoring;
00105   synthInfo->divisor = divisor;
00106   synthInfo->unreachDC = unreachDC;
00107   synthInfo->reordering = reordering;
00108   synthInfo->trySharing = trySharing;
00109   synthInfo->realign = realign;
00110   synthInfo->filehead = filehead;
00111   synthInfo->prefix = prefix;
00112   synthInfo->eqn = eqn;
00113   return synthInfo;
00114 }
00115 
00127 void
00128 Synth_FreeInfo(Synth_InfoData_t *synthInfo)
00129 {
00130   FREE(synthInfo);
00131 }
00132 
00148 int
00149 Synth_SynthesizeNetwork(Ntk_Network_t *network,
00150                         graph_t *partition,
00151                         st_table *careTable,
00152                         Synth_InfoData_t *synthInfo,
00153                         int verbosity)
00154 {
00155   graph_t *newPartition = NIL(graph_t);
00156   Fsm_Fsm_t *fsm = NIL(Fsm_Fsm_t);
00157   st_table *careBddTable;
00158   int status;
00159   int createdPart = 0;
00160   int createdFsm = 0;
00161   int ntkIsSeq = 1;
00162 
00163   if (bdd_get_package_name() != CUDD) {
00164     (void) fprintf(vis_stderr,
00165   "** synth error: The synthesis package can be used only with CUDD package\n");
00166     (void) fprintf(vis_stderr,
00167                    "** synth error: Please link with the CUDD package\n");
00168     return 0;
00169   }
00170   if (partition == NIL(graph_t)) {
00171     newPartition = (graph_t *) Ntk_NetworkReadApplInfo(network, 
00172                                                        PART_NETWORK_APPL_KEY);
00173     createdPart = 0; /* Using partition of the network. */
00174     if (newPartition == NIL(graph_t) || 
00175         (!IsPartitionValid(network,newPartition))) {
00176       newPartition = Part_NetworkCreatePartition(network, 
00177                                                  NIL(Hrc_Node_t),
00178                                                  "dummy", (lsList) 0, 
00179                                                  (lsList) 0, NIL(mdd_t),
00180                                                  Part_InOut_c,
00181                                                  (lsList) 0, 
00182                                                  FALSE, FALSE, TRUE);
00183       if (newPartition == NIL(graph_t)) {
00184         (void) fprintf(vis_stderr,"** synth error: Could not create an InOut");
00185         (void) fprintf(vis_stderr,"partition.\n");
00186         return 0;
00187       }
00188       createdPart = 1; /* Using new partition */
00189     }
00190   } else {
00191     if (IsPartitionValid(network,partition)) {
00192       newPartition = partition;
00193       createdPart = 2; /* Using the partition provided. */
00194     } else {
00195       newPartition = Part_NetworkCreatePartition(network, 
00196                                                  NIL(Hrc_Node_t),
00197                                                  "dummy", (lsList) 0, 
00198                                                  (lsList) 0, NIL(mdd_t),
00199                                                  Part_InOut_c,
00200                                                  (lsList) 0, 
00201                                                  FALSE, FALSE, TRUE);
00202       if (newPartition == NIL(graph_t)) {
00203         (void) fprintf(vis_stderr,"** synth error: Could not create an InOut");
00204         (void) fprintf(vis_stderr,"partition.\n");
00205         return 0;
00206       }
00207       createdPart = 1;    
00208     }
00209   }
00210 
00211 
00212   if(!Ntk_NetworkReadNumLatches(network)) {
00213     (void) fprintf(vis_stdout, "** synth info: No latches present in the ");
00214     (void) fprintf(vis_stdout, "current network.\n");
00215     (void) fprintf(vis_stdout,
00216                    "** synth info: Proceeding with combinational synthesis.\n");
00217     ntkIsSeq = 0;
00218   }
00219 
00220   if (ntkIsSeq) {
00221     switch (createdPart) {
00222     case 0:
00223       /* Check if there is already an Fsm attached to 
00224        * the network.
00225        */
00226       fsm = (Fsm_Fsm_t *) Ntk_NetworkReadApplInfo(network, 
00227                                                   FSM_NETWORK_APPL_KEY);
00228       if (fsm == NIL(Fsm_Fsm_t)) {
00229         fsm = Fsm_FsmCreateFromNetworkWithPartition(network, 
00230                                                     NIL(graph_t));
00231         if (fsm == NIL(Fsm_Fsm_t)) {
00232           (void) fprintf(vis_stderr,"** synth error: Could not create ");
00233           (void) fprintf(vis_stderr,"an Fsm\n");
00234           goto endgame;
00235         }
00236         createdFsm = 1;
00237       } else {
00238         createdFsm = 0;
00239       }
00240       break;
00241     case 1:
00242     case 2:
00243       fsm = Fsm_FsmCreateFromNetworkWithPartition(network,
00244                                   Part_PartitionDuplicate(newPartition));
00245 
00246       if (fsm == NIL(Fsm_Fsm_t)) {
00247         (void) fprintf(vis_stderr,"** synth error: Could not create ");
00248         (void) fprintf(vis_stderr,"an Fsm\n");
00249         goto endgame;
00250       }
00251       createdFsm = 1;
00252       break;
00253     }
00254   }
00255 
00256   careBddTable = NIL(st_table);
00257   if (careTable != NIL(st_table)) {
00258     mdd_t *mddTemp;
00259     bdd_node *ddNode;
00260     char *name;
00261     st_generator *stGen;
00262 
00263     careBddTable = st_init_table(strcmp, st_strhash);
00264     st_foreach_item(careTable,stGen,&name,&mddTemp) {
00265       ddNode = bdd_extract_node_as_is(mddTemp);
00266       st_insert(careBddTable,name,(char *)ddNode);
00267     }
00268   }
00269   if (fsm)
00270     status = synthesizeNetwork(network, newPartition,
00271                                fsm, careBddTable, synthInfo,
00272                                verbosity);
00273   else
00274     status = synthesizeNetwork(network,newPartition,
00275                                NIL(Fsm_Fsm_t), careBddTable,
00276                                synthInfo, verbosity);
00277 
00278   if (careBddTable)
00279     st_free_table(careBddTable);
00280   if (createdPart == 1)
00281     Part_PartitionFree(newPartition);
00282   if (createdFsm == 1)
00283     Fsm_FsmFree(fsm);
00284 
00285   return status;
00286 
00287  endgame:
00288   if (createdPart == 1)
00289     Part_PartitionFree(newPartition);
00290   if (createdFsm == 1)
00291     Fsm_FsmFree(fsm);
00292 
00293   return 0;
00294 
00295 }
00296 
00310 int
00311 Synth_SynthesizeFsm(Fsm_Fsm_t *fsm,
00312                     st_table *careTable,
00313                     Synth_InfoData_t *synthInfo,
00314                     int verbosity)
00315 {
00316   Ntk_Network_t *network;
00317   graph_t *partition;
00318   st_table *careBddTable;
00319   int status;
00320 
00321   network = Fsm_FsmReadNetwork(fsm);
00322   partition = Fsm_FsmReadPartition(fsm);
00323 
00324   careBddTable = NIL(st_table);
00325   if (careTable != NIL(st_table)) {
00326     mdd_t *mddTemp;
00327     bdd_node *ddNode;
00328     char *name;
00329     st_generator *stGen;
00330 
00331     careBddTable = st_init_table(strcmp, st_strhash);
00332     st_foreach_item(careTable,stGen,&name,&mddTemp) {
00333       ddNode = bdd_extract_node_as_is(mddTemp);
00334       st_insert(careBddTable,name,(char *)ddNode);
00335     }
00336   }
00337     
00338   status = synthesizeNetwork(network,partition,fsm,careBddTable,synthInfo,
00339                              verbosity);
00340   if (careBddTable)
00341     st_free_table(careBddTable);
00342 
00343   return status;
00344 }
00345 
00346 /*---------------------------------------------------------------------------*/
00347 /* Definition of internal functions                                          */
00348 /*---------------------------------------------------------------------------*/
00349 
00350 
00351 /*---------------------------------------------------------------------------*/
00352 /* Definition of static functions                                            */
00353 /*---------------------------------------------------------------------------*/
00354 
00367 static int
00368 synthesizeNetwork(Ntk_Network_t *network,
00369                   graph_t *partition,
00370                   Fsm_Fsm_t *fsm,
00371                   st_table *careBddTable,
00372                   Synth_InfoData_t *synthInfo,
00373                   int verbosity)
00374 {
00375   bdd_manager *ddManager = (bdd_manager *) Ntk_NetworkReadMddManager(network);
00376   int i, numOut;
00377   int *initStates = NIL(int);
00378   Mvf_Function_t *combMvfs;
00379   array_t *inputIds, *combOutNamesArray;
00380   bdd_node **combOutBdds, *ddTemp;
00381   bdd_node *unReachable = NIL(bdd_node), *reachable = NIL(bdd_node);
00382   bdd_node **combUpperBdds;
00383   bdd_node *initBdd = NIL(bdd_node), *temp;
00384   char **combOutNames;
00385   char *str;
00386   int realign_bdd, realign_zdd;
00387   Fsm_RchType_t reachMethod;
00388 
00389   /* Save current values of realignment flags. */
00390   realign_zdd = bdd_zdd_realignment_enabled(ddManager);
00391   realign_bdd = bdd_realignment_enabled(ddManager);
00392 
00393   if (synthInfo->reordering == 1) {
00394     if (synthInfo->realign)
00395       bdd_zdd_realign_enable(ddManager);
00396     else
00397       bdd_zdd_realign_disable(ddManager);
00398     bdd_realign_disable(ddManager);
00399   } else if (synthInfo->reordering == 2) {
00400     bdd_zdd_realign_disable(ddManager);
00401     if (synthInfo->realign)
00402       bdd_realign_enable(ddManager);
00403     else
00404       bdd_realign_disable(ddManager);
00405   } else {
00406     bdd_zdd_realign_disable(ddManager);
00407     bdd_realign_disable(ddManager);
00408   }
00409 
00410   /* Get the names of the combinational outputs, i.e, next state functions
00411    * as well as primary outputs. In VIS even latch initial inputs are
00412    * considered combinational outputs. Since, we support only blif files,
00413    * latch initial inputs are not present in combOutNamesArray.
00414    */
00415   combOutNamesArray = GetCombOutputNameArray(network);
00416   if (combOutNamesArray == NIL(array_t)) {
00417     if (realign_zdd == 1)
00418       bdd_zdd_realign_enable(ddManager);
00419     else
00420       bdd_zdd_realign_disable(ddManager);
00421     if (realign_bdd == 1)
00422       bdd_realign_enable(ddManager);
00423     else
00424       bdd_realign_disable(ddManager);
00425     return 0;
00426   }
00427   /* Get the array of combinational inputs, i.e., primary inputs, 
00428    * present state variables.
00429    */
00430   inputIds = GetCombInputIdArray(network);
00431   if (inputIds == NIL(array_t)) {
00432     array_free(combOutNamesArray);
00433     /* Restore values of realignment flags. */
00434     if (realign_zdd == 1)
00435       bdd_zdd_realign_enable(ddManager);
00436     else
00437       bdd_zdd_realign_disable(ddManager);
00438     if (realign_bdd == 1)
00439       bdd_realign_enable(ddManager);
00440     else
00441       bdd_realign_disable(ddManager);
00442     return 0;
00443   }
00444   /* Compute the Bdds */
00445   combMvfs = Part_PartitionBuildFunctions(partition,combOutNamesArray,
00446                                           inputIds,NIL(mdd_t));
00447   combOutBdds = (bdd_node **) GetBddArray(combMvfs);
00448   if (combOutBdds == NIL(bdd_node *)) {
00449     array_free(combOutNamesArray);
00450     array_free(inputIds);
00451     Mvf_FunctionArrayFree(combMvfs);
00452     if (realign_zdd == 1)
00453       bdd_zdd_realign_enable(ddManager);
00454     else
00455       bdd_zdd_realign_disable(ddManager);
00456     if (realign_bdd == 1)
00457       bdd_realign_enable(ddManager);
00458     else
00459       bdd_realign_disable(ddManager);
00460     return 0;
00461   }
00462   Mvf_FunctionArrayFree(combMvfs);
00463 
00464   numOut = array_n(combOutNamesArray); 
00465   combOutNames = ALLOC(char *, numOut);
00466   if (combOutNames == NIL(char *)) {
00467     (void) fprintf(vis_stderr,"** synth error: Could not allocate memory\n");
00468     array_free(combOutNamesArray);
00469     array_free(inputIds);
00470 
00471     for (i = 0; i < numOut; i++) {
00472       bdd_recursive_deref(ddManager,combOutBdds[i]);
00473     }
00474     FREE(combOutBdds);
00475     if (realign_zdd == 1)
00476       bdd_zdd_realign_enable(ddManager);
00477     else
00478       bdd_zdd_realign_disable(ddManager);
00479     if (realign_bdd == 1)
00480       bdd_realign_enable(ddManager);
00481     else
00482       bdd_realign_disable(ddManager);
00483     return 0;
00484   }
00485   arrayForEachItem(char *, combOutNamesArray, i, str) {
00486     combOutNames[i] = str;
00487   }
00488   array_free(combOutNamesArray);
00489 
00490 
00491   combUpperBdds = ALLOC(bdd_node *,numOut);
00492   /* Initialize the upper bound to be the lower bound */
00493   for (i = 0; i < numOut; i++) {
00494     bdd_ref(combUpperBdds[i] = combOutBdds[i]);
00495   }
00496 
00497   if (fsm) {
00498     mdd_t *initMdd;
00499     /* Duplicate copy of initial States is returned */
00500     initMdd = Fsm_FsmComputeInitialStates(fsm);
00501     initBdd = (bdd_node *)bdd_extract_node_as_is(initMdd);
00502     bdd_ref(initBdd);
00503     mdd_free(initMdd);
00504 
00505     if (synthInfo->unreachDC) {
00506       mdd_t *reachStates;
00507 
00508       (void) fprintf(vis_stdout,
00509                      "** synth info: Using unreachable states as dont cares\n");
00510       if (synthInfo->unreachDC == 1) {
00511         reachMethod = Fsm_Rch_Bfs_c;
00512       } else if (synthInfo->unreachDC == 2) {
00513         reachMethod = Fsm_Rch_Hd_c;
00514       } else if (synthInfo->unreachDC == 3) {
00515         reachMethod = Fsm_Rch_Oa_c;
00516       } else {
00517         reachMethod = Fsm_Rch_Default_c;
00518       }
00519       reachStates = Fsm_FsmComputeReachableStates(fsm,0,0,0,0,
00520                                                   0,0,1000,reachMethod,
00521                                                   0,0,NIL(array_t), FALSE,
00522                                                   NIL(array_t));
00523       reachable = (bdd_node *)bdd_extract_node_as_is(reachStates);
00524       bdd_ref(reachable);
00525       unReachable = bdd_not_bdd_node(reachable);
00526       bdd_ref(unReachable);
00527       mdd_free(reachStates);
00528     }
00529   }
00530 
00531   if (careBddTable == NIL(st_table)) {
00532     if (fsm && synthInfo->unreachDC) {
00533       /* Upper bound = LowerBould + DC */
00534       for (i = 0; i < numOut; i++) {
00535         bdd_recursive_deref(ddManager,combUpperBdds[i]);
00536         combUpperBdds[i] = bdd_bdd_or(ddManager,combOutBdds[i],
00537                                       unReachable);
00538         bdd_ref(combUpperBdds[i]);
00539       }
00540       
00541       /* LowerBound = OutputFuns . Care */
00542       bdd_recursive_deref(ddManager,unReachable);
00543       for (i = 0; i < numOut; i++) {
00544         bdd_node *temp;
00545         temp = bdd_bdd_and(ddManager,combOutBdds[i],reachable);
00546         bdd_ref(temp);
00547         bdd_recursive_deref(ddManager,combOutBdds[i]);
00548         combOutBdds[i] = temp;
00549       }
00550       bdd_recursive_deref(ddManager,reachable);
00551     }
00552   } else { /* Use the cares supplied. */
00553     if (fsm && synthInfo->unreachDC) {
00554       bdd_recursive_deref(ddManager,unReachable);
00555     }
00556     for (i = 0; i < numOut; i++) {
00557       bdd_node *dontCare,*care;
00558 
00559       if (st_lookup(careBddTable,combOutNames[i],&ddTemp) == 1) {
00560         if (fsm && synthInfo->unreachDC) {
00561           bdd_ref(care = bdd_bdd_or(ddManager,ddTemp,reachable));
00562         } else {
00563           bdd_ref(care = ddTemp);
00564         }
00565         bdd_ref(dontCare = bdd_not_bdd_node(care));
00566         
00567         /* Update the upper bound for each combinational output */
00568         bdd_recursive_deref(ddManager,combUpperBdds[i]);
00569         combUpperBdds[i] = bdd_bdd_or(ddManager,combOutBdds[i],dontCare);
00570         bdd_ref(combUpperBdds[i]);
00571         bdd_recursive_deref(ddManager,dontCare);
00572         
00573         /* Update the lower bound */
00574         bdd_ref(temp = bdd_bdd_and(ddManager,combOutBdds[i],care));
00575         bdd_recursive_deref(ddManager,combOutBdds[i]);
00576         bdd_recursive_deref(ddManager,care);
00577         combOutBdds[i]=temp;
00578       }
00579     }
00580   }
00581 
00582   if (fsm) {
00583     bdd_t *bddVar, *bddTInit, *bddTtemp;
00584     int id, i = 0;
00585     lsGen gen;
00586     Ntk_Node_t *node;
00587     bdd_node *logicZero = bdd_read_logic_zero(ddManager);
00588 
00589     bddTInit = bdd_construct_bdd_t(ddManager,initBdd);
00590     initStates = ALLOC(int, Ntk_NetworkReadNumLatches(network));
00591     Ntk_NetworkForEachLatch(network,gen,node) {
00592       id = Ntk_NodeReadMddId(node);
00593       bddVar = bdd_get_variable(ddManager,id);
00594       bddTtemp = bdd_cofactor(bddTInit, bddVar);
00595       if (bdd_extract_node_as_is(bddTtemp) == logicZero) 
00596         initStates[i] = 0;
00597       else
00598         initStates[i] = 1;
00599       i++;
00600       bdd_free(bddVar);
00601       bdd_free(bddTtemp);
00602     }
00603     /* This will free initBdd too. So, no need to deref it again.  */
00604     bdd_free(bddTInit);
00605   }
00606 
00607   SynthMultiLevelOptimize(network,combOutBdds,combUpperBdds,
00608                           combOutNames, initStates,synthInfo,
00609                           verbosity);
00610 
00611   /* Clean up. */
00612   if (fsm) {
00613     FREE(initStates);
00614   }
00615   for (i = 0; i < numOut; i++) {
00616     bdd_recursive_deref(ddManager,combUpperBdds[i]);
00617     bdd_recursive_deref(ddManager,combOutBdds[i]);
00618   }
00619   FREE(combOutNames);
00620   FREE(combOutBdds);
00621   FREE(combUpperBdds);
00622   array_free(inputIds);
00623   if (realign_zdd == 1)
00624     bdd_zdd_realign_enable(ddManager);
00625   else
00626     bdd_zdd_realign_disable(ddManager);
00627   if (realign_bdd == 1)
00628     bdd_realign_enable(ddManager);
00629   else
00630     bdd_realign_disable(ddManager);
00631   return(1);
00632 }
00633 
00648 static int
00649 IsPartitionValid(Ntk_Network_t *network,
00650                  graph_t *partition)
00651 {
00652   Ntk_Node_t *node;
00653   lsGen gen;
00654   char *name;
00655 
00656   Ntk_NetworkForEachCombOutput(network, gen, node) {
00657     name = Ntk_NodeReadName(node);
00658     if(Part_PartitionFindVertexByName(partition, name) == NIL(vertex_t)) {
00659       return(0);
00660     }
00661   }
00662   Ntk_NetworkForEachCombInput(network, gen, node) {
00663     name = Ntk_NodeReadName(node);
00664     if(Part_PartitionFindVertexByName(partition, name) == NIL(vertex_t)) {
00665       return(0);
00666     }
00667   }
00668 
00669   return 1;
00670 }
00671 
00672 
00684 static array_t *
00685 GetCombOutputNameArray(Ntk_Network_t *network)
00686 {
00687   array_t *outputFunNames;
00688   lsGen gen;
00689   Ntk_Node_t *node;
00690     
00691   outputFunNames = array_alloc(char *, 0);
00692   if (outputFunNames == NIL(array_t)) {
00693     (void) fprintf(vis_stderr,"** synth error: Could not allocate space ");
00694     (void) fprintf(vis_stderr,"for the names of combinational outputs\n");
00695     return NIL(array_t);
00696   }
00697   Ntk_NetworkForEachCombOutput(network, gen, node){
00698     if (Ntk_NodeTestIsLatchInitialInput(node))
00699       continue;
00700     array_insert_last(char *, outputFunNames, 
00701                       Ntk_NodeReadName(node));
00702   }
00703   return outputFunNames;
00704 }
00705 
00717 static array_t *
00718 GetCombInputIdArray(Ntk_Network_t *network)
00719 {
00720   array_t *inputIds;
00721   lsGen gen;
00722   Ntk_Node_t *node;
00723     
00724   inputIds = array_alloc(int, 0);
00725   if (inputIds == NIL(array_t)) {
00726     (void) fprintf(vis_stderr,"** synth error: Could not allocate space ");
00727     (void) fprintf(vis_stderr,"for an array of ids of comb. inputs\n");
00728     return NIL(array_t);
00729   }
00730   Ntk_NetworkForEachCombInput(network, gen, node){
00731     array_insert_last(int, inputIds, Ntk_NodeReadMddId(node));
00732   }
00733   return inputIds;
00734 }
00735 
00736 
00748 static bdd_node **
00749 GetBddArray(Mvf_Function_t *combMvfs)
00750 {
00751   bdd_node **bddArray;
00752   Mvf_Function_t *mvf;
00753   int i;
00754 
00755   bddArray = ALLOC(bdd_node *,array_n(combMvfs));
00756   if (bddArray == NIL(bdd_node *)) {
00757     (void) fprintf(vis_stderr,"** synth error: Could not allocate space ");
00758     (void) fprintf(vis_stderr,"for an array of Bdd nodes.\n");
00759     return NIL(bdd_node *);
00760   }
00761   arrayForEachItem(Mvf_Function_t *, combMvfs, i, mvf) {
00762     mdd_t *mddTemp;
00763 
00764     mddTemp = array_fetch(mdd_t *, mvf, 1);
00765     bddArray[i] = (bdd_node *) bdd_extract_node_as_is(mddTemp);
00766     bdd_ref(bddArray[i]);
00767   }
00768   return bddArray;
00769 }
00770