/**Function************************************************************* Synopsis [Creates the canonical form of the node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Aig_Latch( Aig_Man_t * p, Aig_Obj_t * pObj, int fInitOne ) { Aig_Obj_t * pGhost, * pResult; pGhost = Aig_ObjCreateGhost( p, Aig_NotCond(pObj, fInitOne), NULL, AIG_OBJ_LATCH ); pResult = Aig_TableLookup( p, pGhost ); if ( pResult == NULL ) pResult = Aig_ObjCreate( p, pGhost ); return Aig_NotCond( pResult, fInitOne ); }
/**Function************************************************************* Synopsis [Moves closer to the end the node that is best for sharing.] Description [If there is no node with sharing, randomly chooses one of the legal nodes.] SideEffects [] SeeAlso [] ***********************************************************************/ void Dar_BalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor ) { Aig_Obj_t * pObj1, * pObj2, * pObj3, * pGhost; int RightBound, i; // get the right bound RightBound = Vec_PtrSize(vSuper) - 2; assert( LeftBound <= RightBound ); if ( LeftBound == RightBound ) return; // get the two last nodes pObj1 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, RightBound + 1 ); pObj2 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, RightBound ); if ( Aig_Regular(pObj1) == p->pConst1 || Aig_Regular(pObj2) == p->pConst1 || Aig_Regular(pObj1) == Aig_Regular(pObj2) ) return; // find the first node that can be shared for ( i = RightBound; i >= LeftBound; i-- ) { pObj3 = (Aig_Obj_t *)Vec_PtrEntry( vSuper, i ); if ( Aig_Regular(pObj3) == p->pConst1 ) { Vec_PtrWriteEntry( vSuper, i, pObj2 ); Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); return; } if ( Aig_Regular(pObj1) == Aig_Regular(pObj3) ) { if ( pObj3 == pObj2 ) return; Vec_PtrWriteEntry( vSuper, i, pObj2 ); Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); return; } pGhost = Aig_ObjCreateGhost( p, pObj1, pObj3, fExor? AIG_OBJ_EXOR : AIG_OBJ_AND ); if ( Aig_TableLookup( p, pGhost ) ) { if ( pObj3 == pObj2 ) return; Vec_PtrWriteEntry( vSuper, i, pObj2 ); Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); return; } } /* // we did not find the node to share, randomize choice { int Choice = Aig_ManRandom(0) % (RightBound - LeftBound + 1); pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice ); if ( pObj3 == pObj2 ) return; Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 ); Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); } */ }
/**Function************************************************************* Synopsis [Checks if node with the given attributes is in the hash table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Aig_TableLookupTwo( Aig_Man_t * p, Aig_Obj_t * pFanin0, Aig_Obj_t * pFanin1 ) { Aig_Obj_t * pGhost; // consider simple cases if ( pFanin0 == pFanin1 ) return pFanin0; if ( pFanin0 == Aig_Not(pFanin1) ) return Aig_ManConst0(p); if ( Aig_Regular(pFanin0) == Aig_ManConst1(p) ) return pFanin0 == Aig_ManConst1(p) ? pFanin1 : Aig_ManConst0(p); if ( Aig_Regular(pFanin1) == Aig_ManConst1(p) ) return pFanin1 == Aig_ManConst1(p) ? pFanin0 : Aig_ManConst0(p); pGhost = Aig_ObjCreateGhost( p, pFanin0, pFanin1, AIG_OBJ_AND ); return Aig_TableLookup( p, pGhost ); }
/**Function************************************************************* Synopsis [Performs canonicization step.] Description [The argument nodes can be complemented.] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Aig_And( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ) { Aig_Obj_t * pGhost, * pResult; // Aig_Obj_t * pFan0, * pFan1; // check trivial cases if ( p0 == p1 ) return p0; if ( p0 == Aig_Not(p1) ) return Aig_Not(p->pConst1); if ( Aig_Regular(p0) == p->pConst1 ) return p0 == p->pConst1 ? p1 : Aig_Not(p->pConst1); if ( Aig_Regular(p1) == p->pConst1 ) return p1 == p->pConst1 ? p0 : Aig_Not(p->pConst1); // check not so trivial cases if ( p->fAddStrash && (Aig_ObjIsNode(Aig_Regular(p0)) || Aig_ObjIsNode(Aig_Regular(p1))) ) { // http://fmv.jku.at/papers/BrummayerBiere-MEMICS06.pdf Aig_Obj_t * pFanA, * pFanB, * pFanC, * pFanD; pFanA = Aig_ObjChild0(Aig_Regular(p0)); pFanB = Aig_ObjChild1(Aig_Regular(p0)); pFanC = Aig_ObjChild0(Aig_Regular(p1)); pFanD = Aig_ObjChild1(Aig_Regular(p1)); if ( Aig_IsComplement(p0) ) { if ( pFanA == Aig_Not(p1) || pFanB == Aig_Not(p1) ) return p1; if ( pFanB == p1 ) return Aig_And( p, Aig_Not(pFanA), pFanB ); if ( pFanA == p1 ) return Aig_And( p, Aig_Not(pFanB), pFanA ); } else { if ( pFanA == Aig_Not(p1) || pFanB == Aig_Not(p1) ) return Aig_Not(p->pConst1); if ( pFanA == p1 || pFanB == p1 ) return p0; } if ( Aig_IsComplement(p1) ) { if ( pFanC == Aig_Not(p0) || pFanD == Aig_Not(p0) ) return p0; if ( pFanD == p0 ) return Aig_And( p, Aig_Not(pFanC), pFanD ); if ( pFanC == p0 ) return Aig_And( p, Aig_Not(pFanD), pFanC ); } else { if ( pFanC == Aig_Not(p0) || pFanD == Aig_Not(p0) ) return Aig_Not(p->pConst1); if ( pFanC == p0 || pFanD == p0 ) return p1; } if ( !Aig_IsComplement(p0) && !Aig_IsComplement(p1) ) { if ( pFanA == Aig_Not(pFanC) || pFanA == Aig_Not(pFanD) || pFanB == Aig_Not(pFanC) || pFanB == Aig_Not(pFanD) ) return Aig_Not(p->pConst1); if ( pFanA == pFanC || pFanB == pFanC ) return Aig_And( p, p0, pFanD ); if ( pFanB == pFanC || pFanB == pFanD ) return Aig_And( p, pFanA, p1 ); if ( pFanA == pFanD || pFanB == pFanD ) return Aig_And( p, p0, pFanC ); if ( pFanA == pFanC || pFanA == pFanD ) return Aig_And( p, pFanB, p1 ); } else if ( Aig_IsComplement(p0) && !Aig_IsComplement(p1) ) { if ( pFanA == Aig_Not(pFanC) || pFanA == Aig_Not(pFanD) || pFanB == Aig_Not(pFanC) || pFanB == Aig_Not(pFanD) ) return p1; if ( pFanB == pFanC || pFanB == pFanD ) return Aig_And( p, Aig_Not(pFanA), p1 ); if ( pFanA == pFanC || pFanA == pFanD ) return Aig_And( p, Aig_Not(pFanB), p1 ); } else if ( !Aig_IsComplement(p0) && Aig_IsComplement(p1) ) { if ( pFanC == Aig_Not(pFanA) || pFanC == Aig_Not(pFanB) || pFanD == Aig_Not(pFanA) || pFanD == Aig_Not(pFanB) ) return p0; if ( pFanD == pFanA || pFanD == pFanB ) return Aig_And( p, Aig_Not(pFanC), p0 ); if ( pFanC == pFanA || pFanC == pFanB ) return Aig_And( p, Aig_Not(pFanD), p0 ); } else // if ( Aig_IsComplement(p0) && Aig_IsComplement(p1) ) { if ( pFanA == pFanD && pFanB == Aig_Not(pFanC) ) return Aig_Not(pFanA); if ( pFanB == pFanC && pFanA == Aig_Not(pFanD) ) return Aig_Not(pFanB); if ( pFanA == pFanC && pFanB == Aig_Not(pFanD) ) return Aig_Not(pFanA); if ( pFanB == pFanD && pFanA == Aig_Not(pFanC) ) return Aig_Not(pFanB); } } // check if it can be an EXOR gate // if ( Aig_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) ) // return Aig_Exor( p, pFan0, pFan1 ); pGhost = Aig_ObjCreateGhost( p, p0, p1, AIG_OBJ_AND ); pResult = Aig_CanonPair_rec( p, pGhost ); return pResult; }