/**Function************************************************************* Synopsis [Recognizes what nodes are inputs of the EXOR.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Hop_ObjRecognizeExor( Hop_Obj_t * pObj, Hop_Obj_t ** ppFan0, Hop_Obj_t ** ppFan1 ) { Hop_Obj_t * p0, * p1; assert( !Hop_IsComplement(pObj) ); if ( !Hop_ObjIsNode(pObj) ) return 0; if ( Hop_ObjIsExor(pObj) ) { *ppFan0 = Hop_ObjChild0(pObj); *ppFan1 = Hop_ObjChild1(pObj); return 1; } assert( Hop_ObjIsAnd(pObj) ); p0 = Hop_ObjChild0(pObj); p1 = Hop_ObjChild1(pObj); if ( !Hop_IsComplement(p0) || !Hop_IsComplement(p1) ) return 0; p0 = Hop_Regular(p0); p1 = Hop_Regular(p1); if ( !Hop_ObjIsAnd(p0) || !Hop_ObjIsAnd(p1) ) return 0; if ( Hop_ObjFanin0(p0) != Hop_ObjFanin0(p1) || Hop_ObjFanin1(p0) != Hop_ObjFanin1(p1) ) return 0; if ( Hop_ObjFaninC0(p0) == Hop_ObjFaninC0(p1) || Hop_ObjFaninC1(p0) == Hop_ObjFaninC1(p1) ) return 0; *ppFan0 = Hop_ObjChild0(p0); *ppFan1 = Hop_ObjChild1(p0); return 1; }
word Hop_ManComputeTruth6( Hop_Man_t * p, Hop_Obj_t * pObj, int nVars ) { word Truth; int i; if ( Hop_ObjIsConst1( Hop_Regular(pObj) ) ) return Hop_IsComplement(pObj) ? 0 : ~(word)0; for ( i = 0; i < nVars; i++ ) Hop_ManPi( p, i )->iData = i; Truth = Hop_ManComputeTruth6_rec( p, Hop_Regular(pObj) ); return Hop_IsComplement(pObj) ? ~Truth : Truth; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Collects internal nodes in the DFS order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Hop_ManDfs_rec( Hop_Obj_t * pObj, Vec_Ptr_t * vNodes ) { assert( !Hop_IsComplement(pObj) ); if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) return; Hop_ManDfs_rec( Hop_ObjFanin0(pObj), vNodes ); Hop_ManDfs_rec( Hop_ObjFanin1(pObj), vNodes ); assert( !Hop_ObjIsMarkA(pObj) ); // loop detection Hop_ObjSetMarkA(pObj); Vec_PtrPush( vNodes, pObj ); }
/**Function************************************************************* Synopsis [Computes truth table of the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned * Hop_ManConvertAigToTruth_rec2( Hop_Obj_t * pObj, Vec_Int_t * vTruth, int nWords ) { unsigned * pTruth, * pTruth0, * pTruth1; int i; assert( !Hop_IsComplement(pObj) ); if ( !Hop_ObjIsNode(pObj) || !Hop_ObjIsMarkA(pObj) ) return (unsigned *)pObj->pData; // compute the truth tables of the fanins pTruth0 = Hop_ManConvertAigToTruth_rec2( Hop_ObjFanin0(pObj), vTruth, nWords ); pTruth1 = Hop_ManConvertAigToTruth_rec2( Hop_ObjFanin1(pObj), vTruth, nWords ); // creat the truth table of the node pTruth = Vec_IntFetch( vTruth, nWords ); if ( Hop_ObjIsExor(pObj) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = pTruth0[i] ^ pTruth1[i]; else if ( !Hop_ObjFaninC0(pObj) && !Hop_ObjFaninC1(pObj) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = pTruth0[i] & pTruth1[i]; else if ( !Hop_ObjFaninC0(pObj) && Hop_ObjFaninC1(pObj) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = pTruth0[i] & ~pTruth1[i]; else if ( Hop_ObjFaninC0(pObj) && !Hop_ObjFaninC1(pObj) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = ~pTruth0[i] & pTruth1[i]; else // if ( Hop_ObjFaninC0(pObj) && Hop_ObjFaninC1(pObj) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = ~pTruth0[i] & ~pTruth1[i]; assert( Hop_ObjIsMarkA(pObj) ); // loop detection Hop_ObjClearMarkA( pObj ); pObj->pData = pTruth; return pTruth; }
/**Function************************************************************* Synopsis [Converts the network from AIG to BDD representation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_MfsConvertHopToAig( Abc_Obj_t * pObjOld, Aig_Man_t * pMan ) { Hop_Man_t * pHopMan; Hop_Obj_t * pRoot; Abc_Obj_t * pFanin; int i; // get the local AIG pHopMan = (Hop_Man_t *)pObjOld->pNtk->pManFunc; pRoot = (Hop_Obj_t *)pObjOld->pData; // check the case of a constant if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) ) { pObjOld->pCopy = (Abc_Obj_t *)Aig_NotCond( Aig_ManConst1(pMan), Hop_IsComplement(pRoot) ); pObjOld->pNext = pObjOld->pCopy; return; } // assign the fanin nodes Abc_ObjForEachFanin( pObjOld, pFanin, i ) Hop_ManPi(pHopMan, i)->pData = pFanin->pCopy; // construct the AIG Abc_MfsConvertHopToAig_rec( Hop_Regular(pRoot), pMan ); pObjOld->pCopy = (Abc_Obj_t *)Aig_NotCond( (Aig_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); // assign the fanin nodes Abc_ObjForEachFanin( pObjOld, pFanin, i ) Hop_ManPi(pHopMan, i)->pData = pFanin->pNext; // construct the AIG Abc_MfsConvertHopToAig_rec( Hop_Regular(pRoot), pMan ); pObjOld->pNext = (Abc_Obj_t *)Aig_NotCond( (Aig_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); }
/**Function************************************************************* Synopsis [Prints Eqn formula for the AIG rooted at this node.] Description [The formula is in terms of PIs, which should have their names assigned in pObj->pData fields.] SideEffects [] SeeAlso [] ***********************************************************************/ void Hop_ObjPrintEqn( FILE * pFile, Hop_Obj_t * pObj, Vec_Vec_t * vLevels, int Level ) { Vec_Ptr_t * vSuper; Hop_Obj_t * pFanin; int fCompl, i; // store the complemented attribute fCompl = Hop_IsComplement(pObj); pObj = Hop_Regular(pObj); // constant case if ( Hop_ObjIsConst1(pObj) ) { fprintf( pFile, "%d", !fCompl ); return; } // PI case if ( Hop_ObjIsPi(pObj) ) { fprintf( pFile, "%s%s", fCompl? "!" : "", (char*)pObj->pData ); return; } // AND case Vec_VecExpand( vLevels, Level ); vSuper = Vec_VecEntry(vLevels, Level); Hop_ObjCollectMulti( pObj, vSuper ); fprintf( pFile, "%s", (Level==0? "" : "(") ); Vec_PtrForEachEntry( Hop_Obj_t *, vSuper, pFanin, i ) { Hop_ObjPrintEqn( pFile, Hop_NotCond(pFanin, fCompl), vLevels, Level+1 ); if ( i < Vec_PtrSize(vSuper) - 1 ) fprintf( pFile, " %s ", fCompl? "+" : "*" ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Recursively converts AIG from Aig_Man_t into Hop_Obj_t.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_MfsConvertAigToHop_rec( Aig_Obj_t * pObj, Hop_Man_t * pHop ) { assert( !Aig_IsComplement(pObj) ); if ( pObj->pData ) return; Abc_MfsConvertAigToHop_rec( Aig_ObjFanin0(pObj), pHop ); Abc_MfsConvertAigToHop_rec( Aig_ObjFanin1(pObj), pHop ); pObj->pData = Hop_And( pHop, (Hop_Obj_t *)Aig_ObjChild0Copy(pObj), (Hop_Obj_t *)Aig_ObjChild1Copy(pObj) ); assert( !Hop_IsComplement((Hop_Obj_t *)pObj->pData) ); }
/**Function************************************************************* Synopsis [Deletes the node from the hash table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Hop_TableDelete( Hop_Man_t * p, Hop_Obj_t * pObj ) { Hop_Obj_t ** ppPlace; assert( !Hop_IsComplement(pObj) ); ppPlace = Hop_TableFind( p, pObj ); assert( *ppPlace == pObj ); // node should be in the table // remove the node *ppPlace = pObj->pNext; pObj->pNext = NULL; }
/**Function************************************************************* Synopsis [Detects multi-input gate rooted at this node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Hop_ObjCollectMulti_rec( Hop_Obj_t * pRoot, Hop_Obj_t * pObj, Vec_Ptr_t * vSuper ) { if ( pRoot != pObj && (Hop_IsComplement(pObj) || Hop_ObjIsPi(pObj) || Hop_ObjType(pRoot) != Hop_ObjType(pObj)) ) { Vec_PtrPushUnique(vSuper, pObj); return; } Hop_ObjCollectMulti_rec( pRoot, Hop_ObjChild0(pObj), vSuper ); Hop_ObjCollectMulti_rec( pRoot, Hop_ObjChild1(pObj), vSuper ); }
/**Function************************************************************* Synopsis [Recursively cleans the data pointers in the cone of the node.] Description [Applicable to small AIGs only because no caching is performed.] SideEffects [] SeeAlso [] ***********************************************************************/ void Hop_ObjCleanData_rec( Hop_Obj_t * pObj ) { assert( !Hop_IsComplement(pObj) ); assert( !Hop_ObjIsPo(pObj) ); if ( Hop_ObjIsAnd(pObj) ) { Hop_ObjCleanData_rec( Hop_ObjFanin0(pObj) ); Hop_ObjCleanData_rec( Hop_ObjFanin1(pObj) ); } pObj->pData = NULL; }
/**Function************************************************************* Synopsis [Derives GIA for the output of the local function of one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkTestTimNodeStrash_rec( Gia_Man_t * pGia, Hop_Obj_t * pObj ) { assert( !Hop_IsComplement(pObj) ); if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) return; Abc_NtkTestTimNodeStrash_rec( pGia, Hop_ObjFanin0(pObj) ); Abc_NtkTestTimNodeStrash_rec( pGia, Hop_ObjFanin1(pObj) ); pObj->iData = Gia_ManHashAnd( pGia, Hop_ObjChild0CopyI(pObj), Hop_ObjChild1CopyI(pObj) ); assert( !Hop_ObjIsMarkA(pObj) ); // loop detection Hop_ObjSetMarkA( pObj ); }
/**Function************************************************************* Synopsis [Adds the new node to the hash table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Hop_TableInsert( Hop_Man_t * p, Hop_Obj_t * pObj ) { Hop_Obj_t ** ppPlace; assert( !Hop_IsComplement(pObj) ); assert( Hop_TableLookup(p, pObj) == NULL ); if ( (pObj->Id & 0xFF) == 0 && 2 * p->nTableSize < Hop_ManNodeNum(p) ) Hop_TableResize( p ); ppPlace = Hop_TableFind( p, pObj ); assert( *ppPlace == NULL ); *ppPlace = pObj; }
/**Function************************************************************* Synopsis [Construct BDDs and mark AIG nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_MfsConvertHopToAig_rec( Hop_Obj_t * pObj, Aig_Man_t * pMan ) { assert( !Hop_IsComplement(pObj) ); if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) return; Abc_MfsConvertHopToAig_rec( Hop_ObjFanin0(pObj), pMan ); Abc_MfsConvertHopToAig_rec( Hop_ObjFanin1(pObj), pMan ); pObj->pData = Aig_And( pMan, (Aig_Obj_t *)Hop_ObjChild0Copy(pObj), (Aig_Obj_t *)Hop_ObjChild1Copy(pObj) ); assert( !Hop_ObjIsMarkA(pObj) ); // loop detection Hop_ObjSetMarkA( pObj ); }
/**Function************************************************************* Synopsis [Collects internal nodes in the DFS order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Hop_ManDfs_rec( Hop_Obj_t * pObj, Vec_Ptr_t * vNodes ) { assert( !Hop_IsComplement(pObj) ); if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) return; Hop_ManDfs_rec( Hop_ObjFanin0(pObj), vNodes ); Hop_ManDfs_rec( Hop_ObjFanin1(pObj), vNodes ); assert( !Hop_ObjIsMarkA(pObj) ); // loop detection Hop_ObjSetMarkA(pObj); Vec_PtrPush( vNodes, pObj ); }
/**Function************************************************************* Synopsis [Collects internal nodes in the DFS order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Ptr_t * Hop_ManDfsNode( Hop_Man_t * p, Hop_Obj_t * pNode ) { Vec_Ptr_t * vNodes; Hop_Obj_t * pObj; int i; assert( !Hop_IsComplement(pNode) ); vNodes = Vec_PtrAlloc( 16 ); Hop_ManDfs_rec( pNode, vNodes ); Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i ) Hop_ObjClearMarkA(pObj); return vNodes; }
/**Function************************************************************* Synopsis [Construct BDDs and mark AIG nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Hop_ManConvertAigToTruth_rec1( Hop_Obj_t * pObj ) { int Counter = 0; assert( !Hop_IsComplement(pObj) ); if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) return 0; Counter += Hop_ManConvertAigToTruth_rec1( Hop_ObjFanin0(pObj) ); Counter += Hop_ManConvertAigToTruth_rec1( Hop_ObjFanin1(pObj) ); assert( !Hop_ObjIsMarkA(pObj) ); // loop detection Hop_ObjSetMarkA( pObj ); return Counter + 1; }
int Abc_NtkTestTimNodeStrash( Gia_Man_t * pGia, Abc_Obj_t * pNode ) { Hop_Man_t * pMan; Hop_Obj_t * pRoot; Abc_Obj_t * pFanin; int i; assert( Abc_ObjIsNode(pNode) ); assert( Abc_NtkIsAigLogic(pNode->pNtk) ); // get the local AIG manager and the local root node pMan = (Hop_Man_t *)pNode->pNtk->pManFunc; pRoot = (Hop_Obj_t *)pNode->pData; // check the constant case if ( Abc_NodeIsConst(pNode) || Hop_Regular(pRoot) == Hop_ManConst1(pMan) ) return !Hop_IsComplement(pRoot); // set elementary variables Abc_ObjForEachFanin( pNode, pFanin, i ) Hop_IthVar(pMan, i)->iData = pFanin->iTemp; // strash the AIG of this node Abc_NtkTestTimNodeStrash_rec( pGia, Hop_Regular(pRoot) ); Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); // return the final node with complement if needed return Abc_LitNotCond( Hop_Regular(pRoot)->iData, Hop_IsComplement(pRoot) ); }
/**Function************************************************************* Synopsis [Checks if a node with the given attributes is in the hash table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_TableLookup( Hop_Man_t * p, Hop_Obj_t * pGhost ) { Hop_Obj_t * pEntry; assert( !Hop_IsComplement(pGhost) ); assert( Hop_ObjChild0(pGhost) && Hop_ObjChild1(pGhost) ); assert( Hop_ObjFanin0(pGhost)->Id < Hop_ObjFanin1(pGhost)->Id ); if ( p->fRefCount && (!Hop_ObjRefs(Hop_ObjFanin0(pGhost)) || !Hop_ObjRefs(Hop_ObjFanin1(pGhost))) ) return NULL; for ( pEntry = p->pTable[Hop_Hash(pGhost, p->nTableSize)]; pEntry; pEntry = pEntry->pNext ) { if ( Hop_ObjChild0(pEntry) == Hop_ObjChild0(pGhost) && Hop_ObjChild1(pEntry) == Hop_ObjChild1(pGhost) && Hop_ObjType(pEntry) == Hop_ObjType(pGhost) ) return pEntry; } return NULL; }
/**Function************************************************************* Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Hop_ObjIsMuxType( Hop_Obj_t * pNode ) { Hop_Obj_t * pNode0, * pNode1; // check that the node is regular assert( !Hop_IsComplement(pNode) ); // if the node is not AND, this is not MUX if ( !Hop_ObjIsAnd(pNode) ) return 0; // if the children are not complemented, this is not MUX if ( !Hop_ObjFaninC0(pNode) || !Hop_ObjFaninC1(pNode) ) return 0; // get children pNode0 = Hop_ObjFanin0(pNode); pNode1 = Hop_ObjFanin1(pNode); // if the children are not ANDs, this is not MUX if ( !Hop_ObjIsAnd(pNode0) || !Hop_ObjIsAnd(pNode1) ) return 0; // otherwise the node is MUX iff it has a pair of equal grandchildren return (Hop_ObjFanin0(pNode0) == Hop_ObjFanin0(pNode1) && (Hop_ObjFaninC0(pNode0) ^ Hop_ObjFaninC0(pNode1))) || (Hop_ObjFanin0(pNode0) == Hop_ObjFanin1(pNode1) && (Hop_ObjFaninC0(pNode0) ^ Hop_ObjFaninC1(pNode1))) || (Hop_ObjFanin1(pNode0) == Hop_ObjFanin0(pNode1) && (Hop_ObjFaninC1(pNode0) ^ Hop_ObjFaninC0(pNode1))) || (Hop_ObjFanin1(pNode0) == Hop_ObjFanin1(pNode1) && (Hop_ObjFaninC1(pNode0) ^ Hop_ObjFaninC1(pNode1))); }
/**Function************************************************************* Synopsis [Computes truth table of the node.] Description [Assumes that the structural support is no more than 8 inputs. Uses array vTruth to store temporary truth tables. The returned pointer should be used immediately.] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned * Hop_ManConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, int fMsbFirst ) { static unsigned uTruths[8][8] = { // elementary truth tables { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA }, { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC }, { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 }, { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 }, { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } }; Hop_Obj_t * pObj; unsigned * pTruth, * pTruth2; int i, nWords, nNodes; Vec_Ptr_t * vTtElems; // if the number of variables is more than 8, allocate truth tables if ( nVars > 8 ) vTtElems = Vec_PtrAllocTruthTables( nVars ); else vTtElems = NULL; // clear the data fields and set marks nNodes = Hop_ManConvertAigToTruth_rec1( Hop_Regular(pRoot) ); // prepare memory nWords = Hop_TruthWordNum( nVars ); Vec_IntClear( vTruth ); Vec_IntGrow( vTruth, nWords * (nNodes+1) ); pTruth = Vec_IntFetch( vTruth, nWords ); // check the case of a constant if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) ) { assert( nNodes == 0 ); if ( Hop_IsComplement(pRoot) ) Hop_ManTruthClear( pTruth, nVars ); else Hop_ManTruthFill( pTruth, nVars ); return pTruth; } // set elementary truth tables at the leaves assert( nVars <= Hop_ManPiNum(p) ); // assert( Hop_ManPiNum(p) <= 8 ); if ( fMsbFirst ) { // Hop_ManForEachPi( p, pObj, i ) for ( i = 0; i < nVars; i++ ) { pObj = Hop_ManPi( p, i ); if ( vTtElems ) pObj->pData = Vec_PtrEntry(vTtElems, nVars-1-i); else pObj->pData = (void *)uTruths[nVars-1-i]; } } else { // Hop_ManForEachPi( p, pObj, i ) for ( i = 0; i < nVars; i++ ) { pObj = Hop_ManPi( p, i ); if ( vTtElems ) pObj->pData = Vec_PtrEntry(vTtElems, i); else pObj->pData = (void *)uTruths[i]; } } // clear the marks and compute the truth table pTruth2 = Hop_ManConvertAigToTruth_rec2( Hop_Regular(pRoot), vTruth, nWords ); // copy the result Hop_ManTruthCopy( pTruth, pTruth2, nVars ); if ( Hop_IsComplement(pRoot) ) Hop_ManTruthNot( pTruth, pTruth, nVars ); if ( vTtElems ) Vec_PtrFree( vTtElems ); return pTruth; }
/**Function************************************************************* Synopsis [Detects multi-input gate rooted at this node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Hop_ObjCollectMulti( Hop_Obj_t * pRoot, Vec_Ptr_t * vSuper ) { assert( !Hop_IsComplement(pRoot) ); Vec_PtrClear( vSuper ); Hop_ObjCollectMulti_rec( pRoot, pRoot, vSuper ); }
/**Function************************************************************* Synopsis [Recognizes what nodes are control and data inputs of a MUX.] Description [If the node is a MUX, returns the control variable C. Assigns nodes T and E to be the then and else variables of the MUX. Node C is never complemented. Nodes T and E can be complemented. This function also recognizes EXOR/NEXOR gates as MUXes.] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Hop_ObjRecognizeMux( Hop_Obj_t * pNode, Hop_Obj_t ** ppNodeT, Hop_Obj_t ** ppNodeE ) { Hop_Obj_t * pNode0, * pNode1; assert( !Hop_IsComplement(pNode) ); assert( Hop_ObjIsMuxType(pNode) ); // get children pNode0 = Hop_ObjFanin0(pNode); pNode1 = Hop_ObjFanin1(pNode); // find the control variable if ( Hop_ObjFanin1(pNode0) == Hop_ObjFanin1(pNode1) && (Hop_ObjFaninC1(pNode0) ^ Hop_ObjFaninC1(pNode1)) ) { // if ( Fraig_IsComplement(pNode1->p2) ) if ( Hop_ObjFaninC1(pNode0) ) { // pNode2->p2 is positive phase of C *ppNodeT = Hop_Not(Hop_ObjChild0(pNode1));//pNode2->p1); *ppNodeE = Hop_Not(Hop_ObjChild0(pNode0));//pNode1->p1); return Hop_ObjChild1(pNode1);//pNode2->p2; } else { // pNode1->p2 is positive phase of C *ppNodeT = Hop_Not(Hop_ObjChild0(pNode0));//pNode1->p1); *ppNodeE = Hop_Not(Hop_ObjChild0(pNode1));//pNode2->p1); return Hop_ObjChild1(pNode0);//pNode1->p2; } } else if ( Hop_ObjFanin0(pNode0) == Hop_ObjFanin0(pNode1) && (Hop_ObjFaninC0(pNode0) ^ Hop_ObjFaninC0(pNode1)) ) { // if ( Fraig_IsComplement(pNode1->p1) ) if ( Hop_ObjFaninC0(pNode0) ) { // pNode2->p1 is positive phase of C *ppNodeT = Hop_Not(Hop_ObjChild1(pNode1));//pNode2->p2); *ppNodeE = Hop_Not(Hop_ObjChild1(pNode0));//pNode1->p2); return Hop_ObjChild0(pNode1);//pNode2->p1; } else { // pNode1->p1 is positive phase of C *ppNodeT = Hop_Not(Hop_ObjChild1(pNode0));//pNode1->p2); *ppNodeE = Hop_Not(Hop_ObjChild1(pNode1));//pNode2->p2); return Hop_ObjChild0(pNode0);//pNode1->p1; } } else if ( Hop_ObjFanin0(pNode0) == Hop_ObjFanin1(pNode1) && (Hop_ObjFaninC0(pNode0) ^ Hop_ObjFaninC1(pNode1)) ) { // if ( Fraig_IsComplement(pNode1->p1) ) if ( Hop_ObjFaninC0(pNode0) ) { // pNode2->p2 is positive phase of C *ppNodeT = Hop_Not(Hop_ObjChild0(pNode1));//pNode2->p1); *ppNodeE = Hop_Not(Hop_ObjChild1(pNode0));//pNode1->p2); return Hop_ObjChild1(pNode1);//pNode2->p2; } else { // pNode1->p1 is positive phase of C *ppNodeT = Hop_Not(Hop_ObjChild1(pNode0));//pNode1->p2); *ppNodeE = Hop_Not(Hop_ObjChild0(pNode1));//pNode2->p1); return Hop_ObjChild0(pNode0);//pNode1->p1; } } else if ( Hop_ObjFanin1(pNode0) == Hop_ObjFanin0(pNode1) && (Hop_ObjFaninC1(pNode0) ^ Hop_ObjFaninC0(pNode1)) ) { // if ( Fraig_IsComplement(pNode1->p2) ) if ( Hop_ObjFaninC1(pNode0) ) { // pNode2->p1 is positive phase of C *ppNodeT = Hop_Not(Hop_ObjChild1(pNode1));//pNode2->p2); *ppNodeE = Hop_Not(Hop_ObjChild0(pNode0));//pNode1->p1); return Hop_ObjChild0(pNode1);//pNode2->p1; } else { // pNode1->p2 is positive phase of C *ppNodeT = Hop_Not(Hop_ObjChild0(pNode0));//pNode1->p1); *ppNodeE = Hop_Not(Hop_ObjChild1(pNode1));//pNode2->p2); return Hop_ObjChild1(pNode0);//pNode1->p2; } } assert( 0 ); // this is not MUX return NULL; }