| /**CFile**************************************************************** |
| |
| FileName [gia.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Scalable AIG package.] |
| |
| Synopsis [Structural detection of enables, sets and resets.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "gia.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Collects the supergate.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_CollectSuper_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper ) |
| { |
| // if the new node is complemented or a PI, another gate begins |
| if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ) |
| { |
| Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_Regular(pObj)) ); |
| return; |
| } |
| assert( Gia_ObjIsAnd(pObj) ); |
| // go through the branches |
| Gia_CollectSuper_rec( p, Gia_ObjChild0(pObj), vSuper ); |
| Gia_CollectSuper_rec( p, Gia_ObjChild1(pObj), vSuper ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Collects the supergate.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_CollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSuper ) |
| { |
| assert( !Gia_IsComplement(pObj) ); |
| Vec_IntClear( vSuper ); |
| // Gia_CollectSuper_rec( p, pObj, vSuper ); |
| if ( Gia_ObjIsAnd(pObj) ) |
| { |
| Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_ObjFanin0(pObj)) ); |
| Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_ObjFanin1(pObj)) ); |
| } |
| else |
| Vec_IntPushUnique( vSuper, Gia_ObjId(p, Gia_Regular(pObj)) ); |
| |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManPrintSignals( Gia_Man_t * p, int * pFreq, char * pStr ) |
| { |
| Vec_Int_t * vObjs; |
| int i, Counter = 0, nTotal = 0; |
| vObjs = Vec_IntAlloc( 100 ); |
| for ( i = 0; i < Gia_ManObjNum(p); i++ ) |
| if ( pFreq[i] > 1 ) |
| { |
| nTotal += pFreq[i]; |
| Counter++; |
| } |
| printf( "%s (total = %d driven = %d)\n", pStr, Counter, nTotal ); |
| Counter = 0; |
| for ( i = 0; i < Gia_ManObjNum(p); i++ ) |
| if ( pFreq[i] > 10 ) |
| { |
| printf( "%3d : Obj = %6d Refs = %6d Freq = %6d\n", |
| ++Counter, i, Gia_ObjRefNum(p, Gia_ManObj(p,i)), pFreq[i] ); |
| Vec_IntPush( vObjs, i ); |
| } |
| Vec_IntFree( vObjs ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset, int fVerbose ) |
| { |
| Vec_Int_t * vSuper; |
| Gia_Obj_t * pFlop, * pObjC, * pObj0, * pObj1, * pNode, * pTemp; |
| int i, k, Ent, * pSets, * pResets, * pEnables; |
| int nHaveSetReset = 0, nHaveEnable = 0; |
| assert( Gia_ManRegNum(p) > 0 ); |
| pSets = ABC_CALLOC( int, Gia_ManObjNum(p) ); |
| pResets = ABC_CALLOC( int, Gia_ManObjNum(p) ); |
| pEnables = ABC_CALLOC( int, Gia_ManObjNum(p) ); |
| vSuper = Vec_IntAlloc( 100 ); |
| Gia_ManForEachRi( p, pFlop, i ) |
| { |
| pNode = Gia_ObjFanin0(pFlop); |
| if ( !Gia_ObjIsAnd(pNode) ) |
| continue; |
| // detect sets/resets |
| Gia_CollectSuper( p, pNode, vSuper ); |
| if ( Gia_ObjFaninC0(pFlop) ) |
| Vec_IntForEachEntry( vSuper, Ent, k ) |
| pSets[Ent]++; |
| else |
| Vec_IntForEachEntry( vSuper, Ent, k ) |
| pResets[Ent]++; |
| // detect enables |
| if ( !Gia_ObjIsMuxType(pNode) ) |
| continue; |
| pObjC = Gia_ObjRecognizeMux( pNode, &pObj0, &pObj1 ); |
| pTemp = Gia_ObjRiToRo( p, pFlop ); |
| if ( Gia_Regular(pObj0) != pTemp && Gia_Regular(pObj1) != pTemp ) |
| continue; |
| if ( !Gia_ObjFaninC0(pFlop) ) |
| { |
| pObj0 = Gia_Not(pObj0); |
| pObj1 = Gia_Not(pObj1); |
| } |
| if ( Gia_IsComplement(pObjC) ) |
| { |
| pObjC = Gia_Not(pObjC); |
| pTemp = pObj0; |
| pObj0 = pObj1; |
| pObj1 = pTemp; |
| } |
| // detect controls |
| // Gia_CollectSuper( p, pObjC, vSuper ); |
| // Vec_IntForEachEntry( vSuper, Ent, k ) |
| // pEnables[Ent]++; |
| pEnables[Gia_ObjId(p, pObjC)]++; |
| nHaveEnable++; |
| } |
| Gia_ManForEachRi( p, pFlop, i ) |
| { |
| pNode = Gia_ObjFanin0(pFlop); |
| if ( !Gia_ObjIsAnd(pNode) ) |
| continue; |
| // detect sets/resets |
| Gia_CollectSuper( p, pNode, vSuper ); |
| Vec_IntForEachEntry( vSuper, Ent, k ) |
| if ( pSets[Ent] > 1 || pResets[Ent] > 1 ) |
| { |
| nHaveSetReset++; |
| break; |
| } |
| } |
| Vec_IntFree( vSuper ); |
| ABC_FREE( p->pRefs ); |
| Gia_ManCreateRefs( p ); |
| if ( fVerbose ) |
| { |
| printf( "Flops with set/reset = %6d. Flops with enable = %6d.\n", nHaveSetReset, nHaveEnable ); |
| if ( fSetReset ) |
| { |
| Gia_ManPrintSignals( p, pSets, "Set signals" ); |
| Gia_ManPrintSignals( p, pResets, "Reset signals" ); |
| } |
| Gia_ManPrintSignals( p, pEnables, "Enable signals" ); |
| } |
| ABC_FREE( p->pRefs ); |
| ABC_FREE( pSets ); |
| ABC_FREE( pResets ); |
| ABC_FREE( pEnables ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Gia_ManDetectSeqSignalsWithFanout( Gia_Man_t * p, int nFanMax, int fVerbose ) |
| { |
| Vec_Int_t * vResult; |
| Vec_Int_t * vSuper; |
| Gia_Obj_t * pFlop, * pObjC, * pObj0, * pObj1, * pNode, * pTemp; |
| int i, k, Ent, * pSets, * pResets, * pEnables; |
| int nHaveSetReset = 0, nHaveEnable = 0; |
| assert( Gia_ManRegNum(p) > 0 ); |
| pSets = ABC_CALLOC( int, Gia_ManObjNum(p) ); |
| pResets = ABC_CALLOC( int, Gia_ManObjNum(p) ); |
| pEnables = ABC_CALLOC( int, Gia_ManObjNum(p) ); |
| vSuper = Vec_IntAlloc( 100 ); |
| Gia_ManForEachRi( p, pFlop, i ) |
| { |
| pNode = Gia_ObjFanin0(pFlop); |
| if ( !Gia_ObjIsAnd(pNode) ) |
| continue; |
| // detect sets/resets |
| Gia_CollectSuper( p, pNode, vSuper ); |
| if ( Gia_ObjFaninC0(pFlop) ) |
| Vec_IntForEachEntry( vSuper, Ent, k ) |
| pSets[Ent]++; |
| else |
| Vec_IntForEachEntry( vSuper, Ent, k ) |
| pResets[Ent]++; |
| // detect enables |
| if ( !Gia_ObjIsMuxType(pNode) ) |
| continue; |
| pObjC = Gia_ObjRecognizeMux( pNode, &pObj0, &pObj1 ); |
| pTemp = Gia_ObjRiToRo( p, pFlop ); |
| if ( Gia_Regular(pObj0) != pTemp && Gia_Regular(pObj1) != pTemp ) |
| continue; |
| if ( !Gia_ObjFaninC0(pFlop) ) |
| { |
| pObj0 = Gia_Not(pObj0); |
| pObj1 = Gia_Not(pObj1); |
| } |
| if ( Gia_IsComplement(pObjC) ) |
| { |
| pObjC = Gia_Not(pObjC); |
| pTemp = pObj0; |
| pObj0 = pObj1; |
| pObj1 = pTemp; |
| } |
| // detect controls |
| // Gia_CollectSuper( p, pObjC, vSuper ); |
| // Vec_IntForEachEntry( vSuper, Ent, k ) |
| // pEnables[Ent]++; |
| pEnables[Gia_ObjId(p, pObjC)]++; |
| nHaveEnable++; |
| } |
| Gia_ManForEachRi( p, pFlop, i ) |
| { |
| pNode = Gia_ObjFanin0(pFlop); |
| if ( !Gia_ObjIsAnd(pNode) ) |
| continue; |
| // detect sets/resets |
| Gia_CollectSuper( p, pNode, vSuper ); |
| Vec_IntForEachEntry( vSuper, Ent, k ) |
| if ( pSets[Ent] > 1 || pResets[Ent] > 1 ) |
| { |
| nHaveSetReset++; |
| break; |
| } |
| } |
| Vec_IntFree( vSuper ); |
| vResult = Vec_IntAlloc( 100 ); |
| for ( i = 1; i < Gia_ManObjNum(p); i++ ) |
| if ( pSets[i] > nFanMax ) |
| { |
| if ( fVerbose ) |
| printf( "Adding set signal %d related to %d flops.\n", i, pSets[i] ); |
| Vec_IntPushUnique( vResult, i ); |
| } |
| for ( i = 1; i < Gia_ManObjNum(p); i++ ) |
| if ( pResets[i] > nFanMax ) |
| { |
| if ( fVerbose ) |
| printf( "Adding reset signal %d related to %d flops.\n", i, pResets[i] ); |
| Vec_IntPushUnique( vResult, i ); |
| } |
| for ( i = 1; i < Gia_ManObjNum(p); i++ ) |
| if ( pEnables[i] > nFanMax ) |
| { |
| if ( fVerbose ) |
| printf( "Adding enable signal %d related to %d flops.\n", i, pEnables[i] ); |
| Vec_IntPushUnique( vResult, i ); |
| } |
| ABC_FREE( pSets ); |
| ABC_FREE( pResets ); |
| ABC_FREE( pEnables ); |
| return vResult; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Transfers attributes from the original one to the final one.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Gia_ManTransferFrames( Gia_Man_t * pAig, Gia_Man_t * pFrames, int nFrames, Gia_Man_t * pNew, Vec_Int_t * vSigs ) |
| { |
| Vec_Int_t * vSigsNew; |
| Gia_Obj_t * pObj, * pObjF; |
| int k, f; |
| vSigsNew = Vec_IntAlloc( 100 ); |
| Gia_ManForEachObjVec( vSigs, pAig, pObj, k ) |
| { |
| assert( Gia_ObjIsCand(pObj) ); |
| for ( f = 0; f < nFrames; f++ ) |
| { |
| pObjF = Gia_ManObj( pFrames, Abc_Lit2Var(Gia_ObjCopyF( pAig, f, pObj )) ); |
| if ( pObjF->Value && ~pObjF->Value ) |
| Vec_IntPushUnique( vSigsNew, Abc_Lit2Var(pObjF->Value) ); |
| } |
| } |
| return vSigsNew; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManUnrollInit( Gia_Man_t * p, int nFrames ) |
| { |
| Gia_Man_t * pNew; |
| Gia_Obj_t * pObj, * pObjRi, * pObjRo; |
| int f, i; |
| Vec_IntFill( &p->vCopies, nFrames * Gia_ManObjNum(p), -1 ); |
| pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) ); |
| pNew->pName = Abc_UtilStrsav( p->pName ); |
| pNew->pSpec = Abc_UtilStrsav( p->pSpec ); |
| Gia_ManHashAlloc( pNew ); |
| Gia_ManForEachRo( p, pObj, i ) |
| Gia_ObjSetCopyF( p, 0, pObj, 0 ); |
| for ( f = 0; f < nFrames; f++ ) |
| { |
| Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 ); |
| Gia_ManForEachPi( p, pObj, i ) |
| Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) ); |
| Gia_ManForEachAnd( p, pObj, i ) |
| Gia_ObjSetCopyF( p, f, pObj, Gia_ManHashAnd(pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj)) ); |
| Gia_ManForEachCo( p, pObj, i ) |
| Gia_ObjSetCopyF( p, f, pObj, Gia_ObjFanin0CopyF(p, f, pObj) ); |
| Gia_ManForEachPo( p, pObj, i ) |
| Gia_ManAppendCo( pNew, Gia_ObjCopyF(p, f, pObj) ); |
| if ( f == nFrames - 1 ) |
| break; |
| Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) |
| Gia_ObjSetCopyF( p, f+1, pObjRo, Gia_ObjCopyF(p, f, pObjRi) ); |
| } |
| Gia_ManHashStop( pNew ); |
| return pNew; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Unrolls initialized timeframes while cofactoring some vars.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManUnrollAndCofactor( Gia_Man_t * p, int nFrames, int nFanMax, int fVerbose ) |
| { |
| Vec_Int_t * vCofSigs, * vTemp; |
| Gia_Man_t * pAig, * pFrames, * pNew; |
| // compute initialized timeframes |
| pFrames = Gia_ManUnrollInit( p, nFrames ); |
| pAig = Gia_ManCleanup( pFrames ); |
| // compute and remap set/reset/enable signals |
| vCofSigs = Gia_ManDetectSeqSignalsWithFanout( p, nFanMax, fVerbose ); |
| vCofSigs = Gia_ManTransferFrames( p, pFrames, nFrames, pAig, vTemp = vCofSigs ); |
| Vec_IntFree( vTemp ); |
| Gia_ManStop( pFrames ); |
| Vec_IntErase( &p->vCopies ); |
| // cofactor all these variables |
| pNew = Gia_ManDupCofAllInt( pAig, vCofSigs, fVerbose ); |
| Vec_IntFree( vCofSigs ); |
| Gia_ManStop( pAig ); |
| return pNew; |
| } |
| |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Transform seq circuits with enables by removing enables.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManRemoveEnables2( Gia_Man_t * p ) |
| { |
| Gia_Man_t * pNew, * pAux; |
| Gia_Obj_t * pTemp, * pObjC, * pObj0, * pObj1, * pFlopIn, * pFlopOut; |
| Gia_Obj_t * pThis, * pNode; |
| int i; |
| pNew = Gia_ManStart( Gia_ManObjNum(p) ); |
| pNew->pName = Abc_UtilStrsav( p->pName ); |
| pNew->pSpec = Abc_UtilStrsav( p->pSpec ); |
| Gia_ManHashAlloc( pNew ); |
| Gia_ManFillValue( p ); |
| Gia_ManConst0(p)->Value = 0; |
| Gia_ManForEachCi( p, pThis, i ) |
| pThis->Value = Gia_ManAppendCi( pNew ); |
| Gia_ManForEachAnd( p, pThis, i ) |
| pThis->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pThis), Gia_ObjFanin1Copy(pThis) ); |
| Gia_ManForEachPo( p, pThis, i ) |
| pThis->Value = Gia_ObjFanin0Copy(pThis); |
| Gia_ManForEachRi( p, pFlopIn, i ) |
| { |
| pNode = Gia_ObjFanin0(pFlopIn); |
| if ( !Gia_ObjIsMuxType(pNode) ) |
| { |
| printf( "Cannot recognize enable of flop %d.\n", i ); |
| continue; |
| } |
| pObjC = Gia_ObjRecognizeMux( pNode, &pObj1, &pObj0 ); |
| pFlopOut = Gia_ObjRiToRo( p, pFlopIn ); |
| if ( Gia_Regular(pObj0) != pFlopOut && Gia_Regular(pObj1) != pFlopOut ) |
| { |
| printf( "Cannot recognize self-loop of enable flop %d.\n", i ); |
| continue; |
| } |
| if ( !Gia_ObjFaninC0(pFlopIn) ) |
| { |
| pObj0 = Gia_Not(pObj0); |
| pObj1 = Gia_Not(pObj1); |
| } |
| if ( Gia_IsComplement(pObjC) ) |
| { |
| pObjC = Gia_Not(pObjC); |
| pTemp = pObj0; |
| pObj0 = pObj1; |
| pObj1 = pTemp; |
| } |
| if ( Gia_Regular(pObj0) == pFlopOut ) |
| { |
| // printf( "FlopIn compl = %d. FlopOut is d0. Complement = %d.\n", |
| // Gia_ObjFaninC0(pFlopIn), Gia_IsComplement(pObj0) ); |
| pFlopIn->Value = Abc_LitNotCond(Gia_Regular(pObj1)->Value, !Gia_IsComplement(pObj1)); |
| } |
| else if ( Gia_Regular(pObj1) == pFlopOut ) |
| { |
| // printf( "FlopIn compl = %d. FlopOut is d1. Complement = %d.\n", |
| // Gia_ObjFaninC0(pFlopIn), Gia_IsComplement(pObj1) ); |
| pFlopIn->Value = Abc_LitNotCond(Gia_Regular(pObj0)->Value, !Gia_IsComplement(pObj0)); |
| } |
| } |
| Gia_ManForEachCo( p, pThis, i ) |
| Gia_ManAppendCo( pNew, pThis->Value ); |
| Gia_ManHashStop( pNew ); |
| Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); |
| pNew = Gia_ManCleanup( pAux = pNew ); |
| Gia_ManStop( pAux ); |
| return pNew; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Transform seq circuits with enables by removing enables.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManRemoveEnables( Gia_Man_t * p ) |
| { |
| Vec_Ptr_t * vCtrls, * vDatas; |
| Vec_Int_t * vFlopClasses; |
| Gia_Man_t * pNew, * pAux; |
| Gia_Obj_t * pFlopIn, * pFlopOut, * pDriver, * pFan0, * pFan1, * pCtrl = NULL, * pData, * pObj; |
| int i, iClass, fCompl, Counter = 0; |
| vCtrls = Vec_PtrAlloc( 100 ); |
| Vec_PtrPush( vCtrls, NULL ); |
| vDatas = Vec_PtrAlloc( Gia_ManRegNum(p) ); |
| vFlopClasses = Vec_IntAlloc( Gia_ManRegNum(p) ); |
| Gia_ManForEachRi( p, pFlopIn, i ) |
| { |
| fCompl = Gia_ObjFaninC0(pFlopIn); |
| pDriver = Gia_ObjFanin0(pFlopIn); |
| if ( !Gia_ObjIsAnd(pDriver) ) |
| { |
| printf( "The flop driver %d is not a node.\n", i ); |
| Vec_PtrPush( vDatas, NULL ); |
| Vec_IntPush( vFlopClasses, 0 ); |
| Counter++; |
| continue; |
| } |
| if ( !Gia_ObjFaninC0(pDriver) || !Gia_ObjFaninC1(pDriver) ) |
| { |
| printf( "The flop driver %d is not an OR gate.\n", i ); |
| Vec_PtrPush( vDatas, NULL ); |
| Vec_IntPush( vFlopClasses, 0 ); |
| Counter++; |
| continue; |
| } |
| pFan0 = Gia_ObjFanin0(pDriver); |
| pFan1 = Gia_ObjFanin1(pDriver); |
| if ( !Gia_ObjIsAnd(pFan0) || !Gia_ObjIsAnd(pFan1) ) |
| { |
| printf( "The flop driver fanin %d is not a node.\n", i ); |
| Vec_PtrPush( vDatas, NULL ); |
| Vec_IntPush( vFlopClasses, 0 ); |
| Counter++; |
| continue; |
| } |
| pFlopOut = Gia_ObjRiToRo( p, pFlopIn ); |
| pFlopOut = Gia_NotCond( pFlopOut, !fCompl ); |
| if ( Gia_ObjChild0(pFan0) != pFlopOut && Gia_ObjChild1(pFan0) != pFlopOut && |
| Gia_ObjChild0(pFan1) != pFlopOut && Gia_ObjChild1(pFan1) != pFlopOut ) |
| { |
| printf( "The flop %d does not have a self-loop.\n", i ); |
| Vec_PtrPush( vDatas, NULL ); |
| Vec_IntPush( vFlopClasses, 0 ); |
| Counter++; |
| continue; |
| } |
| pData = NULL; |
| if ( Gia_ObjChild0(pFan0) == pFlopOut ) |
| { |
| pCtrl = Gia_Not( Gia_ObjChild1(pFan0) ); |
| if ( Gia_ObjFanin0(pFan1) == Gia_Regular(pCtrl) ) |
| pData = Gia_ObjChild1(pFan1); |
| else |
| pData = Gia_ObjChild0(pFan1); |
| } |
| else if ( Gia_ObjChild1(pFan0) == pFlopOut ) |
| { |
| pCtrl = Gia_Not( Gia_ObjChild0(pFan0) ); |
| if ( Gia_ObjFanin0(pFan1) == Gia_Regular(pCtrl) ) |
| pData = Gia_ObjChild1(pFan1); |
| else |
| pData = Gia_ObjChild0(pFan1); |
| } |
| else if ( Gia_ObjChild0(pFan1) == pFlopOut ) |
| { |
| pCtrl = Gia_Not( Gia_ObjChild1(pFan1) ); |
| if ( Gia_ObjFanin0(pFan0) == Gia_Regular(pCtrl) ) |
| pData = Gia_ObjChild1(pFan0); |
| else |
| pData = Gia_ObjChild0(pFan0); |
| } |
| else if ( Gia_ObjChild1(pFan1) == pFlopOut ) |
| { |
| pCtrl = Gia_Not( Gia_ObjChild0(pFan1) ); |
| if ( Gia_ObjFanin0(pFan0) == Gia_Regular(pCtrl) ) |
| pData = Gia_ObjChild1(pFan0); |
| else |
| pData = Gia_ObjChild0(pFan0); |
| } |
| else assert( 0 ); |
| if ( Vec_PtrFind( vCtrls, pCtrl ) == -1 ) |
| Vec_PtrPush( vCtrls, pCtrl ); |
| iClass = Vec_PtrFind( vCtrls, pCtrl ); |
| pData = Gia_NotCond( pData, !fCompl ); |
| Vec_PtrPush( vDatas, pData ); |
| Vec_IntPush( vFlopClasses, iClass ); |
| } |
| assert( Vec_PtrSize( vDatas ) == Gia_ManRegNum(p) ); |
| assert( Vec_IntSize( vFlopClasses ) == Gia_ManRegNum(p) ); |
| printf( "Detected %d classes.\n", Vec_PtrSize(vCtrls) - (Counter == 0) ); |
| Vec_PtrFree( vCtrls ); |
| |
| |
| pNew = Gia_ManStart( Gia_ManObjNum(p) ); |
| pNew->pName = Abc_UtilStrsav( p->pName ); |
| pNew->pSpec = Abc_UtilStrsav( p->pSpec ); |
| Gia_ManConst0(p)->Value = 0; |
| Gia_ManForEachObj1( p, pObj, i ) |
| { |
| if ( Gia_ObjIsAnd(pObj) ) |
| pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); |
| else if ( Gia_ObjIsCi(pObj) ) |
| pObj->Value = Gia_ManAppendCi( pNew ); |
| else if ( Gia_ObjIsPo(p, pObj) ) |
| pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); |
| } |
| Gia_ManForEachRi( p, pObj, i ) |
| { |
| pData = (Gia_Obj_t *)Vec_PtrEntry(vDatas, i); |
| if ( pData == NULL ) |
| pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); |
| else |
| pObj->Value = Gia_ManAppendCo( pNew, Abc_LitNotCond(Gia_Regular(pData)->Value, Gia_IsComplement(pData)) ); |
| } |
| Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); |
| Vec_PtrFree( vDatas ); |
| |
| |
| pNew = Gia_ManCleanup( pAux = pNew ); |
| Gia_ManStop( pAux ); |
| pNew->vFlopClasses = vFlopClasses; |
| return pNew; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |