2014-11-29 23:36:26 +01:00
|
|
|
/**CFile****************************************************************
|
|
|
|
|
|
2015-07-22 02:42:49 +02:00
|
|
|
FileName [cba.c]
|
2014-11-29 23:36:26 +01:00
|
|
|
|
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
|
|
2015-07-22 02:42:49 +02:00
|
|
|
PackageName [Verilog parser.]
|
2014-11-29 23:36:26 +01:00
|
|
|
|
2015-07-22 02:42:49 +02:00
|
|
|
Synopsis [Parses several flavors of word-level Verilog.]
|
2014-11-29 23:36:26 +01:00
|
|
|
|
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
|
|
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
|
|
2015-07-22 02:42:49 +02:00
|
|
|
Date [Ver. 1.0. Started - July 21, 2015.]
|
2014-11-29 23:36:26 +01:00
|
|
|
|
2015-07-22 02:42:49 +02:00
|
|
|
Revision [$Id: cba.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
|
2014-11-29 23:36:26 +01:00
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "cba.h"
|
|
|
|
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// DECLARATIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// FUNCTION DEFINITIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2015-07-24 06:33:52 +02:00
|
|
|
/**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 );
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-27 05:45:28 +01:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2015-07-24 06:33:52 +02:00
|
|
|
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 );
|
|
|
|
|
}
|
2015-01-27 05:45:28 +01:00
|
|
|
|
2014-11-29 23:36:26 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// END OF FILE ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|
|