00001
00021 #include "abc.h"
00022
00026
00027 static int Abc_NodeSupport( DdNode * bFunc, Vec_Str_t * vSupport, int nVars );
00028
00032
00044 int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk )
00045 {
00046 Abc_Obj_t * pNode;
00047 int i, Counter;
00048 assert( Abc_NtkIsBddLogic(pNtk) );
00049 Counter = 0;
00050 Abc_NtkForEachNode( pNtk, pNode, i )
00051 Counter += Abc_NodeMinimumBase( pNode );
00052 return Counter;
00053 }
00054
00066 int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
00067 {
00068 Vec_Str_t * vSupport;
00069 Vec_Ptr_t * vFanins;
00070 DdNode * bTemp;
00071 int i, nVars;
00072
00073 assert( Abc_NtkIsBddLogic(pNode->pNtk) );
00074 assert( Abc_ObjIsNode(pNode) );
00075
00076
00077 vSupport = Vec_StrAlloc( 10 );
00078 nVars = Abc_NodeSupport( Cudd_Regular(pNode->pData), vSupport, Abc_ObjFaninNum(pNode) );
00079 if ( nVars == Abc_ObjFaninNum(pNode) )
00080 {
00081 Vec_StrFree( vSupport );
00082 return 0;
00083 }
00084
00085
00086 vFanins = Vec_PtrAlloc( Abc_ObjFaninNum(pNode) );
00087 Abc_NodeCollectFanins( pNode, vFanins );
00088 for ( i = 0; i < vFanins->nSize; i++ )
00089 if ( vSupport->pArray[i] == 0 )
00090 Abc_ObjDeleteFanin( pNode, vFanins->pArray[i] );
00091 assert( nVars == Abc_ObjFaninNum(pNode) );
00092
00093
00094 pNode->pData = Extra_bddRemapUp( pNode->pNtk->pManFunc, bTemp = pNode->pData ); Cudd_Ref( pNode->pData );
00095 Cudd_RecursiveDeref( pNode->pNtk->pManFunc, bTemp );
00096 Vec_PtrFree( vFanins );
00097 Vec_StrFree( vSupport );
00098 return 1;
00099 }
00100
00112 int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk )
00113 {
00114 Abc_Obj_t * pNode;
00115 int i, Counter;
00116 assert( Abc_NtkIsBddLogic(pNtk) );
00117 Counter = 0;
00118 Abc_NtkForEachNode( pNtk, pNode, i )
00119 Counter += Abc_NodeRemoveDupFanins( pNode );
00120 return Counter;
00121 }
00122
00134 int Abc_NodeRemoveDupFanins_int( Abc_Obj_t * pNode )
00135 {
00136 Abc_Obj_t * pFanin1, * pFanin2;
00137 int i, k;
00138 assert( Abc_NtkIsBddLogic(pNode->pNtk) );
00139 assert( Abc_ObjIsNode(pNode) );
00140
00141 Abc_ObjForEachFanin( pNode, pFanin2, i )
00142 {
00143 Abc_ObjForEachFanin( pNode, pFanin1, k )
00144 {
00145 if ( k >= i )
00146 break;
00147 if ( pFanin1 == pFanin2 )
00148 {
00149 DdManager * dd = pNode->pNtk->pManFunc;
00150 DdNode * bVar1 = Cudd_bddIthVar( dd, i );
00151 DdNode * bVar2 = Cudd_bddIthVar( dd, k );
00152 DdNode * bTrans, * bTemp;
00153 bTrans = Cudd_bddXnor( dd, bVar1, bVar2 ); Cudd_Ref( bTrans );
00154 pNode->pData = Cudd_bddAndAbstract( dd, bTemp = pNode->pData, bTrans, bVar2 ); Cudd_Ref( pNode->pData );
00155 Cudd_RecursiveDeref( dd, bTemp );
00156 Cudd_RecursiveDeref( dd, bTrans );
00157 Abc_NodeMinimumBase( pNode );
00158 return 1;
00159 }
00160 }
00161 }
00162 return 0;
00163 }
00164
00176 int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode )
00177 {
00178 int Counter = 0;
00179 while ( Abc_NodeRemoveDupFanins_int(pNode) )
00180 Counter++;
00181 return Counter;
00182 }
00194 void Abc_NodeSupport_rec( DdNode * bFunc, Vec_Str_t * vSupport )
00195 {
00196 if ( cuddIsConstant(bFunc) || Cudd_IsComplement(bFunc->next) )
00197 return;
00198 vSupport->pArray[ bFunc->index ] = 1;
00199 Abc_NodeSupport_rec( cuddT(bFunc), vSupport );
00200 Abc_NodeSupport_rec( Cudd_Regular(cuddE(bFunc)), vSupport );
00201 bFunc->next = Cudd_Not(bFunc->next);
00202 }
00203
00215 void Abc_NodeSupportClear_rec( DdNode * bFunc )
00216 {
00217 if ( !Cudd_IsComplement(bFunc->next) )
00218 return;
00219 bFunc->next = Cudd_Regular(bFunc->next);
00220 if ( cuddIsConstant(bFunc) )
00221 return;
00222 Abc_NodeSupportClear_rec( cuddT(bFunc) );
00223 Abc_NodeSupportClear_rec( Cudd_Regular(cuddE(bFunc)) );
00224 }
00225
00237 int Abc_NodeSupport( DdNode * bFunc, Vec_Str_t * vSupport, int nVars )
00238 {
00239 int Counter, i;
00240
00241 Vec_StrFill( vSupport, nVars, 0 );
00242 Abc_NodeSupport_rec( bFunc, vSupport );
00243
00244 Abc_NodeSupportClear_rec( bFunc );
00245
00246 Counter = 0;
00247 for ( i = 0; i < nVars; i++ )
00248 Counter += vSupport->pArray[i];
00249 return Counter;
00250 }
00251
00255
00256