/**Function************************************************************* Synopsis [Checks if node with the given attributes is in the hash table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost ) { Aig_Obj_t * pEntry; assert( !Aig_IsComplement(pGhost) ); if ( pGhost->Type == AIG_OBJ_LATCH ) { assert( Aig_ObjChild0(pGhost) && Aig_ObjChild1(pGhost) == NULL ); if ( !Aig_ObjRefs(Aig_ObjFanin0(pGhost)) ) return NULL; } else { assert( pGhost->Type == AIG_OBJ_AND ); assert( Aig_ObjChild0(pGhost) && Aig_ObjChild1(pGhost) ); assert( Aig_ObjFanin0(pGhost)->Id < Aig_ObjFanin1(pGhost)->Id ); if ( !Aig_ObjRefs(Aig_ObjFanin0(pGhost)) || !Aig_ObjRefs(Aig_ObjFanin1(pGhost)) ) return NULL; } for ( pEntry = p->pTable[Aig_Hash(pGhost, p->nTableSize)]; pEntry; pEntry = pEntry->pNext ) { if ( Aig_ObjChild0(pEntry) == Aig_ObjChild0(pGhost) && Aig_ObjChild1(pEntry) == Aig_ObjChild1(pGhost) && Aig_ObjType(pEntry) == Aig_ObjType(pGhost) ) return pEntry; } return NULL; }
/**Function************************************************************* Synopsis [Replaces node with a buffer fanin by a node without them.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_NodeFixBufferFanins( Aig_Man_t * p, Aig_Obj_t * pObj, int fNodesOnly, int fUpdateLevel ) { Aig_Obj_t * pFanReal0, * pFanReal1, * pResult; p->nBufFixes++; if ( Aig_ObjIsPo(pObj) ) { assert( Aig_ObjIsBuf(Aig_ObjFanin0(pObj)) ); pFanReal0 = Aig_ObjReal_rec( Aig_ObjChild0(pObj) ); assert( Aig_ObjPhaseReal(Aig_ObjChild0(pObj)) == Aig_ObjPhaseReal(pFanReal0) ); Aig_ObjPatchFanin0( p, pObj, pFanReal0 ); return; } assert( Aig_ObjIsNode(pObj) ); assert( Aig_ObjIsBuf(Aig_ObjFanin0(pObj)) || Aig_ObjIsBuf(Aig_ObjFanin1(pObj)) ); // get the real fanins pFanReal0 = Aig_ObjReal_rec( Aig_ObjChild0(pObj) ); pFanReal1 = Aig_ObjReal_rec( Aig_ObjChild1(pObj) ); // get the new node if ( Aig_ObjIsNode(pObj) ) pResult = Aig_Oper( p, pFanReal0, pFanReal1, Aig_ObjType(pObj) ); // else if ( Aig_ObjIsLatch(pObj) ) // pResult = Aig_Latch( p, pFanReal0, Aig_ObjInit(pObj) ); else assert( 0 ); // replace the node with buffer by the node without buffer Aig_ObjReplace( p, pObj, pResult, fNodesOnly, fUpdateLevel ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Detects multi-input AND gate rooted at this node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManFindImplications_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vImplics ) { if ( Aig_IsComplement(pObj) || Aig_ObjIsCi(pObj) ) { Vec_PtrPushUnique( vImplics, pObj ); return; } Aig_ManFindImplications_rec( Aig_ObjChild0(pObj), vImplics ); Aig_ManFindImplications_rec( Aig_ObjChild1(pObj), vImplics ); }
// add fanouts Aig_ManForEachObj( p, pObj, i ) { if ( Aig_ObjChild0(pObj) ) Aig_ObjSetFanoutStatic( Aig_ObjFanin0(pObj), pObj ); if ( Aig_ObjChild1(pObj) ) Aig_ObjSetFanoutStatic( Aig_ObjFanin1(pObj), pObj ); }
/**Function************************************************************* Synopsis [Checks if node with the given attributes is in the hash table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost ) { Aig_Obj_t * pEntry; assert( !Aig_IsComplement(pGhost) ); assert( Aig_ObjIsNode(pGhost) ); assert( Aig_ObjChild0(pGhost) && Aig_ObjChild1(pGhost) ); assert( Aig_ObjFanin0(pGhost)->Id < Aig_ObjFanin1(pGhost)->Id ); if ( p->pTable == NULL || !Aig_ObjRefs(Aig_ObjFanin0(pGhost)) || !Aig_ObjRefs(Aig_ObjFanin1(pGhost)) ) return NULL; for ( pEntry = p->pTable[Aig_Hash(pGhost, p->nTableSize)]; pEntry; pEntry = pEntry->pNext ) { if ( Aig_ObjChild0(pEntry) == Aig_ObjChild0(pGhost) && Aig_ObjChild1(pEntry) == Aig_ObjChild1(pGhost) && Aig_ObjType(pEntry) == Aig_ObjType(pGhost) ) return pEntry; } return NULL; }
/**Function************************************************************* Synopsis [Collects the supergate.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Ptr_t * Saig_DetectConstrCollectSuper( Aig_Obj_t * pObj ) { Vec_Ptr_t * vSuper; assert( !Aig_IsComplement(pObj) ); assert( Aig_ObjIsAnd(pObj) ); vSuper = Vec_PtrAlloc( 4 ); Saig_DetectConstrCollectSuper_rec( Aig_ObjChild0(pObj), vSuper ); Saig_DetectConstrCollectSuper_rec( Aig_ObjChild1(pObj), vSuper ); return vSuper; }
/**Function************************************************************* Synopsis [Collects the nodes of the supergate.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Dar_BalanceCone_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) { if ( pObj != pRoot && (Aig_IsComplement(pObj) || Aig_ObjType(pObj) != Aig_ObjType(pRoot) || Aig_ObjRefs(pObj) > 1 || Vec_PtrSize(vSuper) > 10000) ) Vec_PtrPush( vSuper, pObj ); else { assert( !Aig_IsComplement(pObj) ); assert( Aig_ObjIsNode(pObj) ); // go through the branches Dar_BalanceCone_rec( pRoot, Aig_ObjReal_rec( Aig_ObjChild0(pObj) ), vSuper ); Dar_BalanceCone_rec( pRoot, Aig_ObjReal_rec( Aig_ObjChild1(pObj) ), vSuper ); } }
// procedure to detect an EXOR gate static inline int Aig_ObjIsExorType( Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Obj_t ** ppFan0, Aig_Obj_t ** ppFan1 ) { if ( !Aig_IsComplement(p0) || !Aig_IsComplement(p1) ) return 0; p0 = Aig_Regular(p0); p1 = Aig_Regular(p1); if ( !Aig_ObjIsAnd(p0) || !Aig_ObjIsAnd(p1) ) return 0; if ( Aig_ObjFanin0(p0) != Aig_ObjFanin0(p1) || Aig_ObjFanin1(p0) != Aig_ObjFanin1(p1) ) return 0; if ( Aig_ObjFaninC0(p0) == Aig_ObjFaninC0(p1) || Aig_ObjFaninC1(p0) == Aig_ObjFaninC1(p1) ) return 0; *ppFan0 = Aig_ObjChild0(p0); *ppFan1 = Aig_ObjChild1(p0); return 1; }
/**Function************************************************************* Synopsis [Checks the consistency of phase assignment.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManCheckPhase( Aig_Man_t * p ) { Aig_Obj_t * pObj; int i; Aig_ManForEachObj( p, pObj, i ) if ( Aig_ObjIsCi(pObj) ) assert( (int)pObj->fPhase == 0 ); else assert( (int)pObj->fPhase == (Aig_ObjPhaseReal(Aig_ObjChild0(pObj)) & Aig_ObjPhaseReal(Aig_ObjChild1(pObj))) ); }
/**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; }
ABC_NAMESPACE_IMPL_START /* Property holds iff it is const 0. Constraint holds iff it is const 0. The following structure is used for folding constraints: - the output of OR gate is 0 as long as all constraints hold - as soon as one constraint fail, the property output becomes 0 forever because the flop becomes 1 and it stays 1 forever property output | |-----| | and | |-----| | | | / \ | /inv\ | ----- ____| |_________________________ | | | / \ ----------- | / \ | or | | / \ ----------- | / logic \ | | | | / cone \ | | | | /___________\ | | | | | | ------ | | | |flop| (init=0) | | | ------ | | | | | | | |______________| | | c1 c2 */ //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Collects the supergate.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Saig_DetectConstrCollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) { // if the new node is complemented or a PI, another gate begins if ( Aig_IsComplement(pObj) || !Aig_ObjIsNode(pObj) )//|| (Aig_ObjRefs(pObj) > 1) ) { Vec_PtrPushUnique( vSuper, Aig_Not(pObj) ); return; } // go through the branches Saig_DetectConstrCollectSuper_rec( Aig_ObjChild0(pObj), vSuper ); Saig_DetectConstrCollectSuper_rec( Aig_ObjChild1(pObj), vSuper ); }