VIS
|
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