00001
00021 #include "ivy.h"
00022
00026
00027
00028 static inline int Ivy_ObjIsExorType( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Obj_t ** ppFan0, Ivy_Obj_t ** ppFan1 )
00029 {
00030 if ( !Ivy_IsComplement(p0) || !Ivy_IsComplement(p1) )
00031 return 0;
00032 p0 = Ivy_Regular(p0);
00033 p1 = Ivy_Regular(p1);
00034 if ( !Ivy_ObjIsAnd(p0) || !Ivy_ObjIsAnd(p1) )
00035 return 0;
00036 if ( Ivy_ObjFanin0(p0) != Ivy_ObjFanin0(p1) || Ivy_ObjFanin1(p0) != Ivy_ObjFanin1(p1) )
00037 return 0;
00038 if ( Ivy_ObjFaninC0(p0) == Ivy_ObjFaninC0(p1) || Ivy_ObjFaninC1(p0) == Ivy_ObjFaninC1(p1) )
00039 return 0;
00040 *ppFan0 = Ivy_ObjChild0(p0);
00041 *ppFan1 = Ivy_ObjChild1(p0);
00042 return 1;
00043 }
00044
00048
00060 Ivy_Obj_t * Ivy_Oper( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type )
00061 {
00062 if ( Type == IVY_AND )
00063 return Ivy_And( p, p0, p1 );
00064 if ( Type == IVY_EXOR )
00065 return Ivy_Exor( p, p0, p1 );
00066 assert( 0 );
00067 return NULL;
00068 }
00069
00081 Ivy_Obj_t * Ivy_And( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
00082 {
00083
00084
00085 if ( p0 == p1 )
00086 return p0;
00087 if ( p0 == Ivy_Not(p1) )
00088 return Ivy_Not(p->pConst1);
00089 if ( Ivy_Regular(p0) == p->pConst1 )
00090 return p0 == p->pConst1 ? p1 : Ivy_Not(p->pConst1);
00091 if ( Ivy_Regular(p1) == p->pConst1 )
00092 return p1 == p->pConst1 ? p0 : Ivy_Not(p->pConst1);
00093
00094
00095
00096 return Ivy_CanonAnd( p, p0, p1 );
00097 }
00098
00110 Ivy_Obj_t * Ivy_Exor( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
00111 {
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 return Ivy_Or( p, Ivy_And(p, p0, Ivy_Not(p1)), Ivy_And(p, Ivy_Not(p0), p1) );
00126 }
00127
00139 Ivy_Obj_t * Ivy_Or( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
00140 {
00141 return Ivy_Not( Ivy_And( p, Ivy_Not(p0), Ivy_Not(p1) ) );
00142 }
00143
00155 Ivy_Obj_t * Ivy_Mux( Ivy_Man_t * p, Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 )
00156 {
00157 Ivy_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp;
00158 int Count0, Count1;
00159
00160 if ( p0 == Ivy_Not(p1) )
00161 return Ivy_Exor( p, pC, p0 );
00162
00163
00164 pTempA1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pC, p1, IVY_AND, IVY_INIT_NONE) );
00165 pTempA2 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pC), p0, IVY_AND, IVY_INIT_NONE) );
00166 if ( pTempA1 && pTempA2 )
00167 {
00168 pTemp = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pTempA1), Ivy_Not(pTempA2), IVY_AND, IVY_INIT_NONE) );
00169 if ( pTemp ) return Ivy_Not(pTemp);
00170 }
00171 Count0 = (pTempA1 != NULL) + (pTempA2 != NULL);
00172
00173 pTempB1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pC, Ivy_Not(p1), IVY_AND, IVY_INIT_NONE) );
00174 pTempB2 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pC), Ivy_Not(p0), IVY_AND, IVY_INIT_NONE) );
00175 if ( pTempB1 && pTempB2 )
00176 {
00177 pTemp = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pTempB1), Ivy_Not(pTempB2), IVY_AND, IVY_INIT_NONE) );
00178 if ( pTemp ) return pTemp;
00179 }
00180 Count1 = (pTempB1 != NULL) + (pTempB2 != NULL);
00181
00182 if ( Count0 >= Count1 )
00183 {
00184 pTempA1 = pTempA1? pTempA1 : Ivy_And(p, pC, p1);
00185 pTempA2 = pTempA2? pTempA2 : Ivy_And(p, Ivy_Not(pC), p0);
00186 return Ivy_Or( p, pTempA1, pTempA2 );
00187 }
00188 pTempB1 = pTempB1? pTempB1 : Ivy_And(p, pC, Ivy_Not(p1));
00189 pTempB2 = pTempB2? pTempB2 : Ivy_And(p, Ivy_Not(pC), Ivy_Not(p0));
00190 return Ivy_Not( Ivy_Or( p, pTempB1, pTempB2 ) );
00191
00192
00193 }
00194
00206 Ivy_Obj_t * Ivy_Maj( Ivy_Man_t * p, Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC )
00207 {
00208 return Ivy_Or( p, Ivy_Or(p, Ivy_And(p, pA, pB), Ivy_And(p, pA, pC)), Ivy_And(p, pB, pC) );
00209 }
00210
00222 Ivy_Obj_t * Ivy_Multi_rec( Ivy_Man_t * p, Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type )
00223 {
00224 Ivy_Obj_t * pObj1, * pObj2;
00225 if ( nObjs == 1 )
00226 return ppObjs[0];
00227 pObj1 = Ivy_Multi_rec( p, ppObjs, nObjs/2, Type );
00228 pObj2 = Ivy_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type );
00229 return Ivy_Oper( p, pObj1, pObj2, Type );
00230 }
00231
00243 Ivy_Obj_t * Ivy_Multi( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
00244 {
00245 assert( Type == IVY_AND || Type == IVY_EXOR );
00246 assert( nArgs > 0 );
00247 return Ivy_Multi_rec( p, pArgs, nArgs, Type );
00248 }
00249
00261 Ivy_Obj_t * Ivy_Miter( Ivy_Man_t * p, Vec_Ptr_t * vPairs )
00262 {
00263 int i;
00264 assert( vPairs->nSize > 0 );
00265 assert( vPairs->nSize % 2 == 0 );
00266
00267 for ( i = 0; i < vPairs->nSize; i += 2 )
00268 vPairs->pArray[i/2] = Ivy_Not( Ivy_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) );
00269 vPairs->nSize = vPairs->nSize/2;
00270 return Ivy_Not( Ivy_Multi_rec( p, (Ivy_Obj_t **)vPairs->pArray, vPairs->nSize, IVY_AND ) );
00271 }
00272
00284 Ivy_Obj_t * Ivy_Latch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init )
00285 {
00286 return Ivy_CanonLatch( p, pObj, Init );
00287 }
00288
00292
00293