VIS

src/ntmaig/ntmaig.c

Go to the documentation of this file.
00001 
00018 #include "ntmaigInt.h"
00019 #include "baig.h"
00020 
00021 static char rcsid[] UNUSED = "$Id: ntmaig.c,v 1.15 2005/04/28 08:54:35 bli Exp $";
00022 
00025 /*---------------------------------------------------------------------------*/
00026 /* Static function prototypes                                                */
00027 /*---------------------------------------------------------------------------*/
00028 
00029 static MvfAig_Function_t * NodeBuildMvfAigRecursively(Ntk_Node_t * node, st_table * leaves, st_table * nodeToMvfTable, mAig_Manager_t *manager);
00030 static MvfAig_Function_t * NodeBuildInputMvfAig(mAig_Manager_t *manager, Ntk_Node_t * node);
00031 static MvfAig_Function_t * NodeBuildPseudoInputMvfAigNew(mAig_Manager_t *manager, Ntk_Node_t * node);
00032 /*static MvfAig_Function_t * NodeBuildPseudoInputMvfAig(mAig_Manager_t *manager, Ntk_Node_t * node);*/
00033 static MvfAig_Function_t * NodeBuildConstantMvfAig(Ntk_Node_t * node, int constantValue, mAig_Manager_t *manager);
00034 static MvfAig_Function_t * NodeBuildInternalMvfAig(Ntk_Node_t * node, st_table * leaves, st_table * nodeToMvfAigTable, mAig_Manager_t *manager);
00035 static MvfAig_Function_t * NodeReadMvfAig(Ntk_Node_t * node, st_table * nodeToMvfAigTable);
00036 static void NodeSetMvfAig(Ntk_Node_t * node, st_table * nodeToMvfAigTable, MvfAig_Function_t * MvfAig);
00037 static void RegionInitializeReferenceCounts(array_t *roots, st_table *leaves);
00038 static void NodeDecrementRefCount(Ntk_Node_t *node, st_table *nodeToMvfTable);
00039 
00043 /*---------------------------------------------------------------------------*/
00044 /* Definition of exported functions                                          */
00045 /*---------------------------------------------------------------------------*/
00046 
00079 array_t *
00080 ntmaig_NetworkBuildMvfAigs(
00081   Ntk_Network_t * network,
00082   array_t       * roots,
00083   st_table      * leaves)
00084 {
00085   int               i;
00086   MvfAig_Function_t *MvfAig;
00087   st_table          *nodeToMvfAigTable;  /* mapes each node with its mvfAig */
00088   int                numRoots = array_n(roots);
00089   array_t           *result   = array_alloc(MvfAig_Function_t *, numRoots);
00090   mAig_Manager_t    *manager  = Ntk_NetworkReadMAigManager(network);
00091   MvfAig_Function_t *tmpMvf;
00092 
00093   
00094   /*
00095    * Before initializing the reference counts, verify that the leaves form a
00096    * support set for the roots.
00097    */
00098   if (!Ntk_NetworkTestLeavesCoverSupportOfRoots(network, roots, leaves)) {
00099     fail("Leaves do not cover support of roots");
00100   }
00101   /*
00102    * Each node in the region defined by the roots and leaves is assigned a
00103    * reference count equaling the number of fanouts within the region.  As a
00104    * special case, the roots are initialized to MAX_INT.
00105    */
00106   RegionInitializeReferenceCounts(roots, leaves);
00107   /*
00108    * For each root, compute its MvfAig and store a duplicate copy of it in the
00109    * result array. The nodeToMvfAigTable is used to keep track of intermediate
00110    * computations. Intermediate MvfAigs are freed as soon as possible by using
00111    * the reference count mechanism.
00112    */
00113   nodeToMvfAigTable = (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY);
00114   if (nodeToMvfAigTable == NIL(st_table)){
00115     nodeToMvfAigTable = st_init_table(st_ptrcmp, st_ptrhash);
00116     /* Register the MvfAig Table in the network*/
00117     Ntk_NetworkAddApplInfo(network, MVFAIG_NETWORK_APPL_KEY,
00118                          (Ntk_ApplInfoFreeFn) ntmAig_MvfAigTableFreeCallback,
00119                          (void *) nodeToMvfAigTable);
00120   }
00121   for (i = 0; i < numRoots; i++) {
00122     Ntk_Node_t        *root   = array_fetch(Ntk_Node_t *, roots, i);
00123     tmpMvf = NodeBuildMvfAigRecursively(root, leaves,
00124                                      nodeToMvfAigTable, manager);
00125     MvfAig = MvfAig_FunctionDuplicate(tmpMvf);
00126     array_insert(MvfAig_Function_t *, result, i, MvfAig);
00127   }
00128 
00129   return result;
00130 }
00131 
00146 void
00147 ntmAig_MvfAigTableFreeCallback(
00148    void *data)
00149 {
00150   st_generator      *stGen;
00151   MvfAig_Function_t *MvfAig;
00152   Ntk_Node_t        *node;
00153   st_table          *nodeToMvfAigTable = (st_table*) data;
00154 
00155   st_foreach_item(nodeToMvfAigTable, stGen,  &node,  &MvfAig) {
00156     MvfAig_FunctionFree(MvfAig);
00157   }
00158   st_free_table(nodeToMvfAigTable);
00159 } /* End of ntmAig_MvfAigTableFreeCallback */
00160 
00161 
00162 /*---------------------------------------------------------------------------*/
00163 /* Definition of internal functions                                          */
00164 /*---------------------------------------------------------------------------*/
00165 
00166 
00167 /*---------------------------------------------------------------------------*/
00168 /* Definition of static functions                                            */
00169 /*---------------------------------------------------------------------------*/
00170 
00171 
00187 static MvfAig_Function_t *
00188 NodeBuildMvfAigRecursively(
00189   Ntk_Node_t * node,
00190   st_table * leaves,
00191   st_table * nodeToMvfTable,
00192   mAig_Manager_t *manager)
00193 {
00194   MvfAig_Function_t *MvfAig = NodeReadMvfAig(node, nodeToMvfTable);
00195   
00196   /* If the MvfAig for this node has already been computed, then just return it. */
00197 
00198   if (MvfAig != NIL(MvfAig_Function_t)) {
00199     return MvfAig;
00200   }
00201   if (Ntk_NodeTestIsConstant(node)) {
00202     /* Doesn't matter if constant is a leaf or not. */
00203     MvfAig = NodeBuildConstantMvfAig(node, ntmaig_UNUSED, manager);
00204   }
00205   else {
00206     int constValue;
00207   
00208     if (st_lookup_int(leaves,  node, &constValue)) { 
00209       if (constValue == ntmaig_UNUSED) {
00210         /* Node is a leaf. */
00211         if ((Ntk_NodeTestIsPrimaryInput(node)) ||
00212             (Ntk_NodeTestIsLatch(node)) ||
00213             (Ntk_NodeTestIsCombinational(node))) {
00214           /* Node can assume any value. */
00215           MvfAig = NodeBuildInputMvfAig(manager, node);
00216         }
00217         else if (Ntk_NodeTestIsPseudoInput(node)) {
00218           /* Node may assume only a subset of possible values. */
00219           MvfAig = NodeBuildPseudoInputMvfAigNew(manager, node);
00220         }
00221         else {
00222           fail("Encountered unknown type in MvfAig recursion\n");
00223         }
00224       }
00225       else {
00226         /* treat the leaf node as being a constant taking the value constValue */
00227         MvfAig = NodeBuildConstantMvfAig(node, constValue, manager);
00228       }
00229     }
00230     else {
00231 
00232       /* Node is not a leaf.  If it is a combinational input, then fail. */
00233       if (Ntk_NodeTestIsCombInput(node)) {
00234         fail("Encountered combinational input not in leaves table\n");
00235       }
00236       else {
00237         MvfAig = NodeBuildInternalMvfAig(node, leaves, nodeToMvfTable, manager);
00238       }
00239     }
00240   }
00241   NodeSetMvfAig(node, nodeToMvfTable, MvfAig);
00242   return MvfAig;
00243 
00244 }
00245 
00246 
00254 static MvfAig_Function_t *
00255 NodeBuildInputMvfAig(
00256   mAig_Manager_t *manager,
00257   Ntk_Node_t * node)
00258 {
00259   int mAigId = Ntk_NodeReadMAigId(node);
00260 
00261   assert(mAigId != NTK_UNASSIGNED_MAIG_ID);
00262   return MvfAig_FunctionCreateFromVariable(manager, mAigId);
00263 }
00264 
00284 static MvfAig_Function_t *
00285 NodeBuildPseudoInputMvfAigNew(
00286   mAig_Manager_t *manager,
00287   Ntk_Node_t * node)
00288 {
00289   int lIndex=0, needProcess, i;
00290   mAigEdge_t  mAig, tmpAig;
00291   MvfAig_Function_t *MvfAig;
00292   int                columnIndex = Ntk_NodeReadOutputIndex(node);
00293   Tbl_Table_t       *table       = Ntk_NodeReadTable(node);
00294   int                mAigId      = Ntk_NodeReadMAigId(node);
00295 
00296   assert(mAigId != NTK_UNASSIGNED_MAIG_ID);
00297   MvfAig = Tbl_TableBuildNonDetConstantMvfAig(table, columnIndex,
00298 mAigId,
00299                                               manager);
00300   needProcess = 0;
00301   tmpAig = mAig_Zero;
00302   for(i=0; i<MvfAig->num; i++) {
00303     mAig = array_fetch(mAigEdge_t, MvfAig, i);
00304     if(mAig == tmpAig) {
00305       needProcess = 1;
00306     }
00307     else {
00308       lIndex = i;
00309     }
00310   }
00311   if(needProcess) {
00312     for(i=0; i<lIndex; i++) {
00313       mAig   = array_fetch(mAigEdge_t, MvfAig, i);
00314       tmpAig = mAig_Or(manager, tmpAig, mAig);
00315     }
00316     array_insert(mAigEdge_t, MvfAig, lIndex, mAig_Not(tmpAig));
00317   }
00318   
00319   return MvfAig;
00320 }
00321 
00341 /*static MvfAig_Function_t *
00342 NodeBuildPseudoInputMvfAig(
00343   mAig_Manager_t *manager,
00344   Ntk_Node_t * node)
00345 {
00346   MvfAig_Function_t *MvfAig;
00347   int                columnIndex = Ntk_NodeReadOutputIndex(node);
00348   Tbl_Table_t       *table       = Ntk_NodeReadTable(node);
00349   int                mAigId      = Ntk_NodeReadMAigId(node);
00350 
00351   assert(mAigId != NTK_UNASSIGNED_MAIG_ID);
00352   MvfAig = Tbl_TableBuildNonDetConstantMvfAig(table, columnIndex, mAigId, manager);
00353   return MvfAig;
00354 }*/
00355 
00356 
00375 static MvfAig_Function_t *
00376 NodeBuildConstantMvfAig(
00377   Ntk_Node_t * node,
00378   int constantValue,
00379   mAig_Manager_t *manager)
00380 {
00381   int             value        = 0; /* initialized to stop lint complaining */
00382   Var_Variable_t *variable     = Ntk_NodeReadVariable(node);
00383   int             numVarValues = Var_VariableReadNumValues(variable);
00384   MvfAig_Function_t *MvfAig    = MvfAig_FunctionAlloc(numVarValues);
00385 
00386   if (constantValue != ntmaig_UNUSED) {
00387     /* Use the given value. */
00388     assert((constantValue >= 0) && (constantValue < numVarValues));
00389     value = constantValue;
00390   }
00391   else {
00392     int          outputIndex = Ntk_NodeReadOutputIndex(node);
00393     Tbl_Table_t *table       = Ntk_NodeReadTable(node);
00394 
00395     assert(Ntk_NodeTestIsConstant(node));
00396     value = Tbl_TableReadConstValue(table, outputIndex);
00397     assert(value != -1);
00398   }
00399   
00400   MvfAig_FunctionAddMintermsToComponent(manager, MvfAig, value, bAig_One);
00401   return MvfAig;
00402 }
00403 
00404 
00416 static MvfAig_Function_t *
00417 NodeBuildInternalMvfAig(
00418   Ntk_Node_t * node,
00419   st_table   * leaves,
00420   st_table   * nodeToMvfAigTable,
00421   mAig_Manager_t *manager)
00422 {
00423   int               i;
00424   MvfAig_Function_t *resultMvfAig;
00425   Ntk_Node_t        *faninNode;
00426   array_t           *faninMvfAigs = array_alloc(MvfAig_Function_t *, Ntk_NodeReadNumFanins(node));
00427   int               outputIndex   = Ntk_NodeReadOutputIndex(node);
00428   Tbl_Table_t       *table        = Ntk_NodeReadTable(node);
00429 
00430   Ntk_NodeForEachFanin(node, i, faninNode) {
00431     MvfAig_Function_t *tmpMvfAig = NodeBuildMvfAigRecursively(faninNode, leaves,
00432                                                               nodeToMvfAigTable, manager);
00433     array_insert(MvfAig_Function_t *, faninMvfAigs, i, tmpMvfAig);
00434   }
00435   resultMvfAig = Tbl_TableBuildMvfAigFromFanins(table, outputIndex, faninMvfAigs, manager); 
00436   Ntk_NodeForEachFanin(node, i, faninNode) {
00437     NodeDecrementRefCount(faninNode, nodeToMvfAigTable);
00438   }
00439   /* Don't free the MvfAigs themselves, but just free the array. */
00440   array_free(faninMvfAigs);
00441   return resultMvfAig;
00442 }
00443 
00444 
00453 static MvfAig_Function_t *
00454 NodeReadMvfAig(
00455   Ntk_Node_t * node,
00456   st_table   * nodeToMvfAigTable)
00457 {
00458   MvfAig_Function_t *result = NIL(MvfAig_Function_t);
00459   st_lookup(nodeToMvfAigTable,  node,  &result);
00460 
00461   return result;
00462 }
00463 
00464 
00472 static void
00473 NodeSetMvfAig(
00474   Ntk_Node_t * node,
00475   st_table   * nodeToMvfAigTable,
00476   MvfAig_Function_t * MvfAig)
00477 {
00478   st_insert(nodeToMvfAigTable,  node,  MvfAig);
00479 }
00480 
00496 static void
00497 RegionInitializeReferenceCounts(
00498   array_t *roots, 
00499   st_table *leaves)
00500 {
00501   int           i;
00502   Ntk_Node_t   *node;
00503   st_generator *stGen;
00504   st_table     *regionNodes = Ntk_RegionFindNodes(roots, leaves);
00505 
00506   st_foreach_item(regionNodes, stGen,  &node, NIL(char *)) {
00507     Ntk_Node_t *fanoutNode;
00508     long        refCount = 0;
00509 
00510     Ntk_NodeForEachFanout(node, i, fanoutNode) {
00511       if (st_is_member(regionNodes,  fanoutNode)
00512           && !st_is_member(leaves,  fanoutNode)
00513           && !Ntk_NodeTestIsConstant(fanoutNode)) {
00514         refCount++;
00515       }
00516     }
00517     Ntk_NodeSetUndef(node, (void *) refCount);
00518   }
00519 
00520   for(i = 0; i < array_n(roots); i++) {
00521     node = array_fetch(Ntk_Node_t *, roots, i);
00522     Ntk_NodeSetUndef(node, (char *) MAXINT);
00523   }
00524 
00525   st_free_table(regionNodes);
00526 }
00527 
00539 static void
00540 NodeDecrementRefCount(
00541   Ntk_Node_t *node, 
00542   st_table *nodeToMvfTable)
00543 {
00544   long              refCount = (long) Ntk_NodeReadUndef(node);
00545 
00546   assert(refCount != 0);
00547 
00548   refCount--;
00549   /*  
00550     Want to keep the entry of this node, so we may get the MvfAig of this node
00551     whenever we need it.  The pointer to the nodeToMvfTable is stored in the network
00552     information.
00553    */
00554   /*  
00555   if (refCount == 0) {
00556     st_delete(nodeToMvfTable, (char **) &node, (char **) &mvf);
00557     MvfAig_FunctionFree(mvf);
00558   }
00559   */
00560   Ntk_NodeSetUndef(node, (void *) refCount);
00561 }
00562 
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573