diff options
Diffstat (limited to 'src/base/cba/cbaNtk.c')
-rw-r--r-- | src/base/cba/cbaNtk.c | 572 |
1 files changed, 572 insertions, 0 deletions
diff --git a/src/base/cba/cbaNtk.c b/src/base/cba/cbaNtk.c index 821e9cfd..5ed4542a 100644 --- a/src/base/cba/cbaNtk.c +++ b/src/base/cba/cbaNtk.c @@ -32,6 +32,161 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* + Synopsis [Returns 1 if the manager is in the topo order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cba_NtkIsTopoOrder( Cba_Ntk_t * p, int(* pFuncIsSeq)(Cba_Ntk_t*, int) ) +{ + int i, iObj, iFin, iFanin, fTopo = 1; + Vec_Bit_t * vVisited = Vec_BitStart( Cba_NtkObjNum(p) + 1 ); + // mark PIs and seq objects + Cba_NtkForEachObj( p, iObj ) + if ( Cba_ObjIsPi(p, iObj) || pFuncIsSeq(p, iObj) ) + Vec_BitWriteEntry( vVisited, iObj, 1 ); + // visit combinational nodes + Cba_NtkForEachBox( p, iObj ) + if ( !pFuncIsSeq(p, iObj) ) + { + Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, i ) + if ( !Vec_BitEntry(vVisited, iFanin) ) + fTopo = 0; + if ( !fTopo ) + break; + Vec_BitWriteEntry( vVisited, iObj, 1 ); + } + // visit POs and seq objects + Cba_NtkForEachObj( p, iObj ) + if ( Cba_ObjIsPo(p, iObj) || pFuncIsSeq(p, iObj) ) + { + Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, i ) + if ( !Vec_BitEntry(vVisited, iFanin) ) + fTopo = 0; + if ( !fTopo ) + break; + } + Vec_BitFree( vVisited ); + return fTopo; +} +int Cba_ManIsTopOrder( Cba_Man_t * p, int(* pFuncIsSeq)(Cba_Ntk_t*, int) ) +{ + Cba_Ntk_t * pNtk; int i; + Cba_ManForEachNtk( p, pNtk, i ) + if ( !Cba_NtkIsTopoOrder(pNtk, pFuncIsSeq) ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Collect nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cba_NtkCollectDfs_rec( Cba_Ntk_t * p, int iObj, Vec_Int_t * vObjs ) +{ + int iFin, iFanin, k; + if ( !Cba_ObjCopy(p, iObj) ) + return; + Cba_ObjSetCopy( p, iObj, 0 ); + Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k ) + Cba_NtkCollectDfs_rec( p, iFanin, vObjs ); + Vec_IntPush( vObjs, iObj ); +} +Vec_Int_t * Cba_NtkCollectDfs( Cba_Ntk_t * p ) +{ + int i, k, iObj, iFin, iFanin; + Vec_Int_t * vObjs = Vec_IntAlloc( Cba_NtkObjNum(p) ); + // collect PIs + Cba_NtkForEachPi( p, iObj, i ) + Vec_IntPush( vObjs, iObj ); + // prepare leaves + Cba_NtkCleanObjCopies( p ); + Vec_IntForEachEntry( vObjs, iObj, i ) + Cba_ObjSetCopy( p, iObj, 0 ); + // collect internal + Cba_NtkForEachPo( p, iObj, i ) + Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k ) + Cba_NtkCollectDfs_rec( p, iFanin, vObjs ); + // additionally collect user modules without outputs + Cba_NtkForEachBoxUser( p, iObj ) + if ( Cba_ObjFonNum(p, iObj) == 0 ) + Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k ) + Cba_NtkCollectDfs_rec( p, iFanin, vObjs ); + // collect POs + Cba_NtkForEachPo( p, iObj, i ) + Vec_IntPush( vObjs, iObj ); + // collect user boxes without fanouts + Cba_NtkForEachBoxUser( p, iObj ) + if ( Cba_ObjFonNum(p, iObj) == 0 ) + Vec_IntPush( vObjs, iObj ); + assert( Vec_IntSize(vObjs) <= Cba_NtkObjNum(p) ); + if ( Vec_IntSize(vObjs) != Cba_NtkObjNum(p) ) + printf( "Warning: DSF ordering collected %d out of %d objects.\n", Vec_IntSize(vObjs), Cba_NtkObjNum(p) ); + return vObjs; +} + + +/**Function************************************************************* + + Synopsis [Count number of objects after collapsing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cba_ManGetClpStats_rec( Cba_Ntk_t * p, int * pCountN, int * pCountI, int * pCountO ) +{ + int iObj, Id = Cba_NtkId(p); + if ( pCountN[Id] >= 0 ) + return; + pCountN[Id] = pCountI[Id] = pCountO[Id] = 0; + Cba_NtkForEachObj( p, iObj ) + if ( Cba_ObjIsBoxPrim(p, iObj) ) + { + pCountN[Id] += 1; + pCountI[Id] += Cba_ObjFinNum(p, iObj); + pCountO[Id] += Cba_ObjFonNum(p, iObj); + } + else if ( Cba_ObjIsBoxUser(p, iObj) ) + { + int NtkId = Cba_ObjNtkId(p, iObj); + Cba_ManGetClpStats_rec( Cba_ObjNtk(p, iObj), pCountN, pCountI, pCountO ); + pCountN[Id] += pCountN[NtkId] + Cba_ObjFonNum(p, iObj); + pCountI[Id] += pCountI[NtkId] + Cba_ObjFonNum(p, iObj); + pCountO[Id] += pCountO[NtkId] + Cba_ObjFonNum(p, iObj); + } +} +void Cba_ManGetClpStats( Cba_Man_t * p, int * nObjs, int * nFins, int * nFons ) +{ + int * pCountN = ABC_FALLOC( int, Cba_ManNtkNum(p) + 1 ); + int * pCountI = ABC_FALLOC( int, Cba_ManNtkNum(p) + 1 ); + int * pCountO = ABC_FALLOC( int, Cba_ManNtkNum(p) + 1 ); + Cba_Ntk_t * pRoot = Cba_ManRoot(p); + Cba_ManGetClpStats_rec( pRoot, pCountN, pCountI, pCountO ); + *nObjs = Cba_NtkPioNum(pRoot) + pCountN[Cba_NtkId(pRoot)]; + *nFins = Cba_NtkPoNum(pRoot) + pCountI[Cba_NtkId(pRoot)]; + *nFons = Cba_NtkPiNum(pRoot) + pCountO[Cba_NtkId(pRoot)]; + ABC_FREE( pCountN ); + ABC_FREE( pCountI ); + ABC_FREE( pCountO ); +} + +/**Function************************************************************* + Synopsis [] Description [] @@ -41,6 +196,423 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ +void Cba_NtkCollapse_rec( Cba_Ntk_t * pNew, Cba_Ntk_t * p, Vec_Int_t * vSigs, int TypeBuf ) +{ + int i, iObj, iObjNew, iFin, iFon; + Cba_NtkCleanObjCopies( p ); + Cba_NtkCleanFonCopies( p ); + // set PI copies + assert( Vec_IntSize(vSigs) == Cba_NtkPiNum(p) ); + Cba_NtkForEachPiFon( p, iObj, iFon, i ) + Cba_FonSetCopy( p, iFon, Vec_IntEntry(vSigs, i) ); + // duplicate primitives and create buffers for user instances + Cba_NtkForEachObj( p, iObj ) + if ( Cba_ObjIsBoxPrim( p, iObj ) ) + { + iObjNew = Cba_ObjDup( pNew, p, iObj ); + Cba_ObjForEachFon( p, iObj, iFon, i ) + Cba_FonSetCopy( p, iFon, Cba_ObjFon(pNew, iObjNew, i) ); + if ( Cba_ObjAttr(p, iObj) ) + Cba_ObjSetAttrs( pNew, iObjNew, Cba_ObjAttrArray(p, iObj), Cba_ObjAttrSize(p, iObj) ); + } + else if ( Cba_ObjIsBoxUser( p, iObj ) ) + { + Cba_ObjForEachFon( p, iObj, iFon, i ) + { + iObjNew = Cba_ObjAlloc( pNew, TypeBuf, 1, 1 ); + Cba_FonSetCopy( p, iFon, Cba_ObjFon0(pNew, iObjNew) ); + } + } + // connect primitives and collapse user instances + Cba_NtkForEachObj( p, iObj ) + if ( Cba_ObjIsBoxPrim( p, iObj ) ) + { + iObjNew = Cba_ObjCopy( p, iObj ); + Cba_ObjForEachFinFon( p, iObj, iFin, iFon, i ) + Cba_ObjSetFinFon( pNew, iObjNew, i, Cba_FonCopy(p, iFon) ); + } + else if ( Cba_ObjIsBoxUser( p, iObj ) ) + { + Vec_IntClear( vSigs ); + Cba_ObjForEachFinFon( p, iObj, iFin, iFon, i ) + Vec_IntPush( vSigs, Cba_FonCopy(p, iFon) ); + assert( Vec_IntSize(vSigs) == Cba_ObjFinNum(p, iObj) ); + Cba_NtkCollapse_rec( pNew, Cba_ObjNtk(p, iObj), vSigs, TypeBuf ); + assert( Vec_IntSize(vSigs) == Cba_ObjFonNum(p, iObj) ); + Cba_ObjForEachFon( p, iObj, iFon, i ) + { + iObjNew = Cba_FonObj( pNew, Cba_FonCopy(p, iFon) ); // buffer + Cba_ObjSetFinFon( pNew, iObjNew, 0, Vec_IntEntry(vSigs, i) ); + } + } + // collect POs + Vec_IntClear( vSigs ); + Cba_NtkForEachPoDriverFon( p, iObj, iFon, i ) + Vec_IntPush( vSigs, Cba_FonCopy(p, iFon) ); +} +Cba_Man_t * Cba_ManCollapse( Cba_Man_t * p, int TypeBuf ) +{ + Cba_Man_t * pNew = Cba_ManAlloc( p->pSpec, 1, Abc_NamRef(p->pStrs), Abc_NamStart(100, 24) ); + Cba_Ntk_t * pRoot = Cba_ManRoot( p ), * pRootNew; + Vec_Int_t * vSigs = Vec_IntAlloc( 1000 ); + int i, iObj, iObjNew, iFon, nObjs = 0, nFins = 0, nFons = 0; + Cba_ManGetClpStats( p, &nObjs, &nFins, &nFons ); + pRootNew = Cba_NtkAlloc( pNew, Cba_NtkNameId(pRoot), Cba_NtkPiNum(pRoot), Cba_NtkPoNum(pRoot), nObjs, nFins, nFons ); + Cba_NtkAdd( pNew, pRootNew ); + if ( Cba_NtkHasObjNames(pRoot) ) + Cba_NtkCleanObjNames( pRootNew ); + if ( Cba_NtkHasFonNames(pRoot) ) + Cba_NtkCleanFonNames( pRootNew ); + if ( Cba_NtkHasObjAttrs(pRoot) ) + Cba_NtkCleanObjAttrs( pRootNew ); + if ( Cba_ObjAttr(pRoot, 0) ) + Cba_ObjSetAttrs( pRootNew, 0, Cba_ObjAttrArray(pRoot, 0), Cba_ObjAttrSize(pRoot, 0) ); + Cba_NtkCleanObjCopies( pRoot ); + Cba_NtkForEachPiFon( pRoot, iObj, iFon, i ) + { + iObjNew = Cba_ObjDup( pRootNew, pRoot, iObj ); + Vec_IntPush( vSigs, Cba_ObjFon0(pRootNew, iObjNew) ); + if ( Cba_NtkHasObjNames(pRoot) ) + Cba_ObjSetName( pRootNew, iObjNew, Cba_ObjName(pRoot, iObj) ); + if ( Cba_NtkHasFonNames(pRoot) ) + Cba_FonSetName( pRootNew, Cba_ObjFon0(pRootNew, iObjNew), Cba_FonName(pRoot, iFon) ); + if ( Cba_ObjAttr(pRoot, iObj) ) + Cba_ObjSetAttrs( pRootNew, iObjNew, Cba_ObjAttrArray(pRoot, iObj), Cba_ObjAttrSize(pRoot, iObj) ); + } + assert( Vec_IntSize(vSigs) == Cba_NtkPiNum(pRoot) ); + Cba_NtkCollapse_rec( pRootNew, pRoot, vSigs, TypeBuf ); + assert( Vec_IntSize(vSigs) == Cba_NtkPoNum(pRoot) ); + Cba_NtkForEachPoDriverFon( pRoot, iObj, iFon, i ) + { + iObjNew = Cba_ObjDup( pRootNew, pRoot, iObj ); + Cba_ObjSetFinFon( pRootNew, iObjNew, 0, Vec_IntEntry(vSigs, i) ); + if ( Cba_NtkHasObjNames(pRoot) ) + Cba_ObjSetName( pRootNew, iObjNew, Cba_ObjName(pRoot, iObj) ); + if ( Cba_NtkHasFonNames(pRoot) ) + Cba_FonSetName( pRootNew, Vec_IntEntry(vSigs, i), Cba_FonName(pRoot, iFon) ); + if ( Cba_ObjAttr(pRoot, iObj) ) + Cba_ObjSetAttrs( pRootNew, iObjNew, Cba_ObjAttrArray(pRoot, iObj), Cba_ObjAttrSize(pRoot, iObj) ); + } + Vec_IntFree( vSigs ); + assert( Cba_NtkObjNum(pRootNew) == Cba_NtkObjNumAlloc(pRootNew) ); + assert( Cba_NtkFinNum(pRootNew) == Cba_NtkFinNumAlloc(pRootNew) ); + assert( Cba_NtkFonNum(pRootNew) == Cba_NtkFonNumAlloc(pRootNew) ); + // create internal node names + Cba_NtkMissingFonNames( pRootNew, "m" ); + return pNew; +} + + + +/**Function************************************************************* + + Synopsis [Performs the reverse of collapsing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Cba_NtkCollectInFons( Cba_Ntk_t * p, Vec_Int_t * vObjs ) +{ + Vec_Int_t * vFons = Vec_IntAlloc( 100 ); + Vec_Bit_t * vVisFons = Vec_BitStart( Cba_NtkFonNum(p) + 1 ); + int i, k, iObj, iFin, iFon, Entry; + // mark fanin fons + Vec_IntForEachEntry( vObjs, iObj, i ) + Cba_ObjForEachFinFon( p, iObj, iFin, iFon, k ) + if ( iFon > 0 ) + Vec_BitWriteEntry( vVisFons, iFon, 1 ); + // unmark internal fons + Vec_IntForEachEntry( vObjs, iObj, i ) + Cba_ObjForEachFon( p, iObj, iFon, k ) + Vec_BitWriteEntry( vVisFons, iFon, 0 ); + // collect fons + Vec_BitForEachEntry( vVisFons, Entry, iFon ) + if ( Entry ) + Vec_IntPush( vFons, iFon ); + Vec_BitFree( vVisFons ); + return vFons; +} +Vec_Int_t * Cba_NtkCollectOutFons( Cba_Ntk_t * p, Vec_Int_t * vObjs ) +{ + Vec_Int_t * vFons = Vec_IntAlloc( 100 ); + Vec_Bit_t * vMapObjs = Vec_BitStart( Cba_NtkObjNum(p) + 1 ); + Vec_Bit_t * vVisFons = Vec_BitStart( Cba_NtkFonNum(p) + 1 ); + int i, k, iObj, iFin, iFon; + // map objects + Vec_IntForEachEntry( vObjs, iObj, i ) + Vec_BitWriteEntry( vMapObjs, iObj, 1 ); + // mark those used by non-objects + Cba_NtkForEachObj( p, iObj ) + if ( !Vec_BitEntry(vMapObjs, iObj) ) + Cba_ObjForEachFinFon( p, iObj, iFin, iFon, k ) + if ( iFon > 0 ) + Vec_BitWriteEntry( vVisFons, iFon, 1 ); + // collect pointed fons among those in objects + Vec_IntForEachEntry( vObjs, iObj, i ) + Cba_ObjForEachFon( p, iObj, iFon, k ) + if ( Vec_BitEntry(vVisFons, iFon) ) + Vec_IntPush( vFons, iFon ); + Vec_BitFree( vMapObjs ); + Vec_BitFree( vVisFons ); + return vFons; +} +void Cba_NtkCollectGroupStats( Cba_Ntk_t * p, Vec_Int_t * vObjs, int * pnFins, int * pnFons ) +{ + int i, iObj, nFins = 0, nFons = 0; + Vec_IntForEachEntry( vObjs, iObj, i ) + { + nFins += Cba_ObjFinNum(p, iObj); + nFons += Cba_ObjFonNum(p, iObj); + } + *pnFins = nFins; + *pnFons = nFons; +} +void Cba_ManExtractGroupInt( Cba_Ntk_t * pNew, Cba_Ntk_t * p, Vec_Int_t * vObjs, Vec_Int_t * vFonIns, Vec_Int_t * vFonOuts ) +{ + int i, k, iObj, iObjNew, iFin, iFon; + Cba_NtkCleanObjCopies( p ); + Cba_NtkCleanFonCopies( p ); + // create inputs and map fons + Vec_IntForEachEntry( vFonIns, iFon, i ) + { + iObjNew = Cba_ObjAlloc( pNew, CBA_OBJ_PI, 0, 1 ); + Cba_FonSetCopy( p, iFon, Cba_ObjFon0(pNew, iObjNew) ); + if ( Cba_NtkHasObjNames(p) ) + Cba_ObjSetName( pNew, iObjNew, Cba_ObjName(p, Cba_FonObj(p, iFon)) ); + if ( Cba_NtkHasFonNames(p) ) + Cba_FonSetName( pNew, Cba_ObjFon0(pNew, iObjNew), Cba_FonName(p, iFon) ); + + } + // create internal + Vec_IntForEachEntry( vObjs, iObj, i ) + { + iObjNew = Cba_ObjDup( pNew, p, iObj ); + if ( Cba_NtkHasObjNames(p) ) + Cba_ObjSetName( pNew, iObjNew, Cba_ObjName(p, iObj) ); + Cba_ObjForEachFon( p, iObj, iFon, k ) + { + Cba_FonSetCopy( p, iFon, Cba_ObjFon(pNew, iObjNew, k) ); + if ( Cba_NtkHasFonNames(p) ) + Cba_FonSetName( pNew, Cba_ObjFon(pNew, iObjNew, k), Cba_FonName(p, iFon) ); + } + } + // connect internal + Vec_IntForEachEntry( vObjs, iObj, i ) + { + iObjNew = Cba_ObjCopy( p, iObj ); + Cba_ObjForEachFinFon( p, iObj, iFin, iFon, k ) + Cba_ObjSetFinFon( pNew, iObjNew, k, Cba_FonCopy(p, iFon) ); + } + // create POs + Vec_IntForEachEntry( vFonOuts, iFon, i ) + { + iObjNew = Cba_ObjAlloc( pNew, CBA_OBJ_PO, 1, 0 ); + if ( Cba_NtkHasObjNames(p) ) + Cba_ObjSetName( pNew, iObjNew, Cba_FonName(p, iFon) ); + Cba_ObjSetFinFon( pNew, iObjNew, 0, Cba_FonCopy(p, iFon) ); + } + assert( Cba_NtkObjNum(pNew) == Cba_NtkObjNumAlloc(pNew) ); + assert( Cba_NtkFinNum(pNew) == Cba_NtkFinNumAlloc(pNew) ); + assert( Cba_NtkFonNum(pNew) == Cba_NtkFonNumAlloc(pNew) ); +} +Cba_Man_t * Cba_ManExtractGroup( Cba_Man_t * p, Vec_Int_t * vObjs ) +{ + Cba_Man_t * pNew = Cba_ManAlloc( p->pSpec, 1, Abc_NamRef(p->pStrs), Abc_NamStart(100, 24) ); + Cba_Ntk_t * pRoot = Cba_ManRoot( p ), * pRootNew; + Vec_Int_t * vFonIns = Cba_NtkCollectInFons( pRoot, vObjs ); + Vec_Int_t * vFonOuts = Cba_NtkCollectOutFons( pRoot, vObjs ); + int nObjs, nFins, nFons; + // collect stats + Cba_NtkCollectGroupStats( pRoot, vObjs, &nFins, &nFons ); + nObjs = Vec_IntSize(vObjs) + Vec_IntSize(vFonIns) + Vec_IntSize(vFonOuts); + nFins += Vec_IntSize(vFonOuts); + nFons += Vec_IntSize(vFonIns); + // create network + pRootNew = Cba_NtkAlloc( pNew, Cba_NtkNameId(pRoot), Vec_IntSize(vFonIns), Vec_IntSize(vFonOuts), nObjs, nFins, nFons ); + Cba_NtkAdd( pNew, pRootNew ); + if ( Cba_NtkHasObjNames(pRoot) ) + Cba_NtkCleanObjNames( pRootNew ); + if ( Cba_NtkHasFonNames(pRoot) ) + Cba_NtkCleanFonNames( pRootNew ); + // add group nodes + Cba_ManExtractGroupInt( pRootNew, pRoot, vObjs, vFonIns, vFonOuts ); + Cba_NtkMissingFonNames( pRootNew, "b" ); + // cleanup + Vec_IntFree( vFonIns ); + Vec_IntFree( vFonOuts ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [Derives the design from the GIA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cba_NtkInsertGiaLit( Cba_Ntk_t * p, int iLit, Vec_Int_t * vLit2Fon ) +{ + int iObjNew; + if ( iLit == 0 || iLit == 1 ) + return Cba_FonFromConst(iLit); + if ( Vec_IntEntry(vLit2Fon, iLit) >= 0 ) + return Vec_IntEntry(vLit2Fon, iLit); + assert( Abc_LitIsCompl(iLit) ); + assert( Vec_IntEntry(vLit2Fon, Abc_LitNot(iLit)) >= 0 ); + iObjNew = Cba_ObjAlloc( p, CBA_BOX_INV, 1, 1 ); + Cba_ObjSetFinFon( p, iObjNew, 0, Vec_IntEntry(vLit2Fon, Abc_LitNot(iLit)) ); + Vec_IntWriteEntry( vLit2Fon, iLit, Cba_ObjFon0(p, iObjNew) ); + return Cba_ObjFon0(p, iObjNew); +} +static inline int Cba_NtkInsertGiaObj( Cba_Ntk_t * p, Gia_Man_t * pGia, int iObj, Vec_Int_t * vLit2Fon ) +{ + Gia_Obj_t * pObj = Gia_ManObj( pGia, iObj ); + int iLit0 = Gia_ObjFaninLit0( pObj, iObj ); + int iLit1 = Gia_ObjFaninLit1( pObj, iObj ); + int iFon0 = Cba_NtkInsertGiaLit( p, iLit0, vLit2Fon ); + int iFon1 = Cba_NtkInsertGiaLit( p, iLit1, vLit2Fon ); + int iObjNew; + if ( Gia_ObjIsMux(pGia, pObj) ) + { + int iLit2 = Gia_ObjFaninLit2( pGia, iObj ); + int iFon2 = Cba_NtkInsertGiaLit( p, iLit2, vLit2Fon ); + iObjNew = Cba_ObjAlloc( p, CBA_BOX_MUX, 3, 1 ); + Cba_ObjSetFinFon( p, iObjNew, 0, iFon2 ); + Cba_ObjSetFinFon( p, iObjNew, 1, iFon1 ); + Cba_ObjSetFinFon( p, iObjNew, 2, iFon0 ); + } + else + { + assert( Gia_ObjIsAnd(pObj) ); + iObjNew = Cba_ObjAlloc( p, Gia_ObjIsXor(pObj) ? CBA_BOX_XOR : CBA_BOX_AND, 2, 1 ); + Cba_ObjSetFinFon( p, iObjNew, 0, iFon0 ); + Cba_ObjSetFinFon( p, iObjNew, 1, iFon1 ); + } + Vec_IntWriteEntry( vLit2Fon, Abc_Var2Lit(iObj, 0), Cba_ObjFon0(p, iObjNew) ); + return iObjNew; +} +Cba_Man_t * Cba_ManDeriveFromGia( Gia_Man_t * pGia ) +{ + Cba_Man_t * p = Cba_ManAlloc( pGia->pSpec, 1, NULL, NULL ); + Cba_Ntk_t * pNtk = Cba_NtkAlloc( p, Abc_NamStrFindOrAdd(p->pStrs, pGia->pName, NULL), Gia_ManCiNum(pGia), Gia_ManCoNum(pGia), 1000, 2000, 1000 ); + Vec_Int_t * vLit2Fon = Vec_IntStartFull( 2*Gia_ManObjNum(pGia) ); + int i, iObj, iObjNew, NameId, iLit0, iFon0; + Gia_Obj_t * pObj; + Cba_NtkAdd( p, pNtk ); + Cba_NtkCleanObjNames( pNtk ); + Gia_ManForEachCiId( pGia, iObj, i ) + { + NameId = pGia->vNamesIn? Abc_NamStrFindOrAdd(p->pStrs, Vec_PtrEntry(pGia->vNamesIn, i), NULL) : Cba_ManNewStrId(p, "i", i, NULL); + iObjNew = Cba_ObjAlloc( pNtk, CBA_OBJ_PI, 0, 1 ); + Cba_ObjSetName( pNtk, iObjNew, NameId ); + Vec_IntWriteEntry( vLit2Fon, Abc_Var2Lit(iObj, 0), Cba_ObjFon0(pNtk, iObjNew) ); + } + Gia_ManForEachAndId( pGia, iObj ) + Cba_NtkInsertGiaObj( pNtk, pGia, iObj, vLit2Fon ); + // create inverters if needed + Gia_ManForEachCoId( pGia, iObj, i ) + { + pObj = Gia_ManObj( pGia, iObj ); + iLit0 = Gia_ObjFaninLit0( pObj, iObj ); + iFon0 = Cba_NtkInsertGiaLit( pNtk, iLit0, vLit2Fon ); // can be const! + } + Gia_ManForEachCoId( pGia, iObj, i ) + { + pObj = Gia_ManObj( pGia, iObj ); + iLit0 = Gia_ObjFaninLit0( pObj, iObj ); + iFon0 = Cba_NtkInsertGiaLit( pNtk, iLit0, vLit2Fon ); // can be const! + NameId = pGia->vNamesOut? Abc_NamStrFindOrAdd(p->pStrs, Vec_PtrEntry(pGia->vNamesOut, i), NULL) : Cba_ManNewStrId(p, "o", i, NULL); + iObjNew = Cba_ObjAlloc( pNtk, CBA_OBJ_PO, 1, 0 ); + Cba_ObjSetName( pNtk, iObjNew, NameId ); + Cba_ObjSetFinFon( pNtk, iObjNew, 0, iFon0 ); + } + Cba_NtkCleanFonNames( pNtk ); + Cba_NtkCreateFonNames( pNtk, "a" ); + Vec_IntFree( vLit2Fon ); + return p; +} + + +/**Function************************************************************* + + Synopsis [Inserts the network into the root module instead of objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cba_NtkInsertGroup( Cba_Ntk_t * p, Vec_Int_t * vObjs, Cba_Ntk_t * pSyn ) +{ + Vec_Int_t * vFonIns = Cba_NtkCollectInFons( p, vObjs ); + Vec_Int_t * vFonOuts = Cba_NtkCollectOutFons( p, vObjs ); + int i, iObj, iObjNew, iFin, iFon; + assert( Cba_NtkPiNum(pSyn) == Vec_IntSize(vFonIns) ); + assert( Cba_NtkPoNum(pSyn) == Vec_IntSize(vFonOuts) ); + // mark AIG with the input fons + Cba_NtkCleanFonCopies( pSyn ); + Cba_NtkForEachPiFon( pSyn, iObj, iFon, i ) + Cba_FonSetCopy( pSyn, iFon, Vec_IntEntry(vFonIns, i) ); + Vec_IntFree( vFonIns ); + // build up internal nodes + Cba_NtkCleanObjCopies( pSyn ); + Cba_NtkForEachBox( pSyn, iObj ) + { + iObjNew = Cba_ObjDup( p, pSyn, iObj ); + Cba_ObjForEachFon( pSyn, iObj, iFon, i ) + Cba_FonSetCopy( pSyn, iFon, Cba_ObjFon(p, iObjNew, i) ); + } + // connect internal nodes + Cba_NtkForEachBox( pSyn, iObj ) + { + iObjNew = Cba_ObjCopy( pSyn, iObj ); + Cba_ObjForEachFinFon( pSyn, iObj, iFin, iFon, i ) + Cba_ObjSetFinFon( p, iObjNew, i, Cba_FonCopy(pSyn, iFon) ); + } + // connect output fons + Cba_NtkCleanFonCopies( p ); + Cba_NtkForEachPoDriverFon( pSyn, iObj, iFon, i ) + Cba_FonSetCopy( p, Vec_IntEntry(vFonOuts, i), Cba_FonCopy(pSyn, iFon) ); + Vec_IntFree( vFonOuts ); + // update fins pointing to output fons to point to the new fons + if ( Cba_NtkHasFonNames(p) ) + Vec_IntFillExtra( &p->vFonName, Cba_NtkFonNum(p) + 1, 0 ); + Cba_NtkForEachFinFon( p, iFon, iFin ) + if ( Cba_FonIsReal(iFon) && Cba_FonCopy(p, iFon) ) + { + Cba_PatchFinFon( p, iFin, Cba_FonCopy(p, iFon) ); + if ( Cba_NtkHasFonNames(p) && Cba_FonIsReal(Cba_FonCopy(p, iFon)) ) + { + Cba_FonSetName( p, Cba_FonCopy(p, iFon), Cba_FonName(p, iFon) ); + Cba_FonCleanName( p, iFon ); + } + } + Cba_NtkMissingFonNames( p, "j" ); +/* + // duplicate in DFS order + pNew = Cba_NtkDupOrder( p->pDesign, p, Cba_NtkCollectDfs ); + Cba_NtkDupAttrs( pNew, p ); + // replace "p" with "pNew" + Cba_NtkUpdate( Cba_NtkMan(p), pNew ); // removes "p" + return pNew; +*/ +} +Cba_Man_t * Cba_ManInsertGroup( Cba_Man_t * p, Vec_Int_t * vObjs, Cba_Ntk_t * pSyn ) +{ + Cba_NtkInsertGroup( Cba_ManRoot(p), vObjs, pSyn ); + return Cba_ManDup( p, Cba_NtkCollectDfs ); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// |