summaryrefslogtreecommitdiffstats
path: root/src/map/cov/covBuild.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/cov/covBuild.c')
-rw-r--r--src/map/cov/covBuild.c539
1 files changed, 539 insertions, 0 deletions
diff --git a/src/map/cov/covBuild.c b/src/map/cov/covBuild.c
new file mode 100644
index 00000000..560178be
--- /dev/null
+++ b/src/map/cov/covBuild.c
@@ -0,0 +1,539 @@
+/**CFile****************************************************************
+
+ FileName [covBuild.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Mapping into network of SOPs/ESOPs.]
+
+ Synopsis [Network construction procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: covBuild.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cov.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCovDeriveCube( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp, int fCompl )
+{
+ Vec_Int_t * vLits;
+ Abc_Obj_t * pNodeNew, * pFanin;
+ int i, iFanin, Lit;
+ // create empty cube
+ if ( pCube->nLits == 0 )
+ {
+ if ( fCompl )
+ return Abc_NtkCreateNodeConst0(pNtkNew);
+ return Abc_NtkCreateNodeConst1(pNtkNew);
+ }
+ // get the literals of this cube
+ vLits = Vec_IntAlloc( 10 );
+ Min_CubeGetLits( pCube, vLits );
+ assert( pCube->nLits == (unsigned)vLits->nSize );
+ // create special case when there is only one literal
+ if ( pCube->nLits == 1 )
+ {
+ iFanin = Vec_IntEntry(vLits,0);
+ pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
+ Lit = Min_CubeGetVar(pCube, iFanin);
+ assert( Lit == 1 || Lit == 2 );
+ Vec_IntFree( vLits );
+ if ( (Lit == 1) ^ fCompl )// negative
+ return Abc_NtkCreateNodeInv( pNtkNew, pFanin->pCopy );
+ return pFanin->pCopy;
+ }
+ assert( pCube->nLits > 1 );
+ // create the AND cube
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < vLits->nSize; i++ )
+ {
+ iFanin = Vec_IntEntry(vLits,i);
+ pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
+ Lit = Min_CubeGetVar(pCube, iFanin);
+ assert( Lit == 1 || Lit == 2 );
+ Vec_IntWriteEntry( vLits, i, Lit==1 );
+ Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
+ }
+ pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray );
+ if ( fCompl )
+ Abc_SopComplement( pNodeNew->pData );
+ Vec_IntFree( vLits );
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCovDeriveNode_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int Level )
+{
+ Min_Cube_t * pCover, * pCube;
+ Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin;
+ Vec_Int_t * vSupp;
+ int Entry, nCubes, i;
+
+ if ( Abc_ObjIsCi(pObj) )
+ return pObj->pCopy;
+ assert( Abc_ObjIsNode(pObj) );
+ // skip if already computed
+ if ( pObj->pCopy )
+ return pObj->pCopy;
+
+ // get the support and the cover
+ vSupp = Abc_ObjGetSupp( pObj );
+ pCover = Abc_ObjGetCover2( pObj );
+ assert( vSupp );
+/*
+ if ( pCover && pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) > 0 )
+ {
+ printf( "%d\n ", pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) );
+ Min_CoverWrite( stdout, pCover );
+ }
+*/
+/*
+ // print the support of this node
+ printf( "{ " );
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ printf( "%d ", Entry );
+ printf( "} cubes = %d\n", Min_CoverCountCubes( pCover ) );
+*/
+ // process the fanins
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ {
+ pFanin = Abc_NtkObj(pObj->pNtk, Entry);
+ Abc_NtkCovDeriveNode_rec( p, pNtkNew, pFanin, Level+1 );
+ }
+
+ // for each cube, construct the node
+ nCubes = Min_CoverCountCubes( pCover );
+ if ( nCubes == 0 )
+ pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew);
+ else if ( nCubes == 1 )
+ pNodeNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCover, vSupp, 0 );
+ else
+ {
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ Min_CoverForEachCube( pCover, pCube )
+ {
+ pFaninNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCube, vSupp, 0 );
+ Abc_ObjAddFanin( pNodeNew, pFaninNew );
+ }
+ pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes );
+ }
+/*
+ printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level );
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ {
+ pFanin = Abc_NtkObj(pObj->pNtk, Entry);
+ printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id );
+ }
+ printf( "\n" );
+ Min_CoverWrite( stdout, pCover );
+*/
+ pObj->pCopy = pNodeNew;
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCovDerive( Cov_Man_t * p, Abc_Ntk_t * pNtk )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj;
+ int i;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // perform strashing
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ // reconstruct the network
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ {
+ Abc_NtkCovDeriveNode_rec( p, pNtkNew, Abc_ObjFanin0(pObj), 0 );
+// printf( "*** CO %s : %d -> %d \n", Abc_ObjName(pObj), pObj->pCopy->Id, Abc_ObjFanin0(pObj)->pCopy->Id );
+ }
+ // add the COs
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
+ // make sure everything is okay
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkCovDerive: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCovDeriveInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl )
+{
+ assert( pObj->pCopy );
+ if ( !fCompl )
+ return pObj->pCopy;
+ if ( pObj->pCopy->pCopy == NULL )
+ pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
+ return pObj->pCopy->pCopy;
+ }
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCovDeriveCubeInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp )
+{
+ Vec_Int_t * vLits;
+ Abc_Obj_t * pNodeNew, * pFanin;
+ int i, iFanin, Lit;
+ // create empty cube
+ if ( pCube->nLits == 0 )
+ return Abc_NtkCreateNodeConst1(pNtkNew);
+ // get the literals of this cube
+ vLits = Vec_IntAlloc( 10 );
+ Min_CubeGetLits( pCube, vLits );
+ assert( pCube->nLits == (unsigned)vLits->nSize );
+ // create special case when there is only one literal
+ if ( pCube->nLits == 1 )
+ {
+ iFanin = Vec_IntEntry(vLits,0);
+ pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
+ Lit = Min_CubeGetVar(pCube, iFanin);
+ assert( Lit == 1 || Lit == 2 );
+ Vec_IntFree( vLits );
+// if ( Lit == 1 )// negative
+// return Abc_NtkCreateNodeInv( pNtkNew, pFanin->pCopy );
+// return pFanin->pCopy;
+ return Abc_NtkCovDeriveInv( pNtkNew, pFanin, Lit==1 );
+ }
+ assert( pCube->nLits > 1 );
+ // create the AND cube
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < vLits->nSize; i++ )
+ {
+ iFanin = Vec_IntEntry(vLits,i);
+ pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
+ Lit = Min_CubeGetVar(pCube, iFanin);
+ assert( Lit == 1 || Lit == 2 );
+ Vec_IntWriteEntry( vLits, i, Lit==1 );
+// Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
+ Abc_ObjAddFanin( pNodeNew, Abc_NtkCovDeriveInv( pNtkNew, pFanin, Lit==1 ) );
+ }
+// pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray );
+ pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, NULL );
+ Vec_IntFree( vLits );
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCovDeriveNodeInv_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl )
+{
+ Min_Cube_t * pCover, * pCube;
+ Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin;
+ Vec_Int_t * vSupp;
+ int Entry, nCubes, i;
+
+ // skip if already computed
+ if ( pObj->pCopy )
+ return Abc_NtkCovDeriveInv( pNtkNew, pObj, fCompl );
+ assert( Abc_ObjIsNode(pObj) );
+
+ // get the support and the cover
+ vSupp = Abc_ObjGetSupp( pObj );
+ pCover = Abc_ObjGetCover2( pObj );
+ assert( vSupp );
+
+ // process the fanins
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ {
+ pFanin = Abc_NtkObj(pObj->pNtk, Entry);
+ Abc_NtkCovDeriveNodeInv_rec( p, pNtkNew, pFanin, 0 );
+ }
+
+ // for each cube, construct the node
+ nCubes = Min_CoverCountCubes( pCover );
+ if ( nCubes == 0 )
+ pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew);
+ else if ( nCubes == 1 )
+ pNodeNew = Abc_NtkCovDeriveCubeInv( pNtkNew, pObj, pCover, vSupp );
+ else
+ {
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ Min_CoverForEachCube( pCover, pCube )
+ {
+ pFaninNew = Abc_NtkCovDeriveCubeInv( pNtkNew, pObj, pCube, vSupp );
+ Abc_ObjAddFanin( pNodeNew, pFaninNew );
+ }
+ pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes );
+ }
+
+ pObj->pCopy = pNodeNew;
+ return Abc_NtkCovDeriveInv( pNtkNew, pObj, fCompl );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description [The resulting network contains only pure AND/OR/EXOR gates
+ and inverters. This procedure is usedful to generate Verilog.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCovDeriveClean( Cov_Man_t * p, Abc_Ntk_t * pNtk )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pNodeNew;
+ int i;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // perform strashing
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ // reconstruct the network
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ {
+ pNodeNew = Abc_NtkCovDeriveNodeInv_rec( p, pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) );
+ Abc_ObjAddFanin( pObj->pCopy, pNodeNew );
+ }
+ // add the COs
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
+ // make sure everything is okay
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkCovDeriveInv: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCovDerive_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
+{
+ int fVerbose = 0;
+ Min_Cube_t * pCover, * pCovers[3];
+ Abc_Obj_t * pNodeNew, * pFanin;
+ Vec_Int_t * vSupp;
+ Vec_Str_t * vCover;
+ int i, Entry, nCubes, Type;
+ // skip if already computed
+ if ( pObj->pCopy )
+ return pObj->pCopy;
+ assert( Abc_ObjIsNode(pObj) );
+ // get the support and the cover
+ vSupp = Abc_ObjGetSupp( pObj );
+ assert( vSupp );
+ // choose the cover to implement
+ pCovers[0] = Abc_ObjGetCover( pObj, 0 );
+ pCovers[1] = Abc_ObjGetCover( pObj, 1 );
+ pCovers[2] = Abc_ObjGetCover2( pObj );
+ // use positive polarity
+ if ( pCovers[0]
+ && (!pCovers[1] || Min_CoverCountCubes(pCovers[0]) <= Min_CoverCountCubes(pCovers[1]))
+ && (!pCovers[2] || Min_CoverCountCubes(pCovers[0]) <= Min_CoverCountCubes(pCovers[2])) )
+ {
+ pCover = pCovers[0];
+ Type = '1';
+ }
+ else
+ // use negative polarity
+ if ( pCovers[1]
+ && (!pCovers[0] || Min_CoverCountCubes(pCovers[1]) <= Min_CoverCountCubes(pCovers[0]))
+ && (!pCovers[2] || Min_CoverCountCubes(pCovers[1]) <= Min_CoverCountCubes(pCovers[2])) )
+ {
+ pCover = pCovers[1];
+ Type = '0';
+ }
+ else
+ // use XOR polarity
+ if ( pCovers[2]
+ && (!pCovers[0] || Min_CoverCountCubes(pCovers[2]) < Min_CoverCountCubes(pCovers[0]))
+ && (!pCovers[1] || Min_CoverCountCubes(pCovers[2]) < Min_CoverCountCubes(pCovers[1])) )
+ {
+ pCover = pCovers[2];
+ Type = 'x';
+ }
+ else
+ assert( 0 );
+ // print the support of this node
+ if ( fVerbose )
+ {
+ printf( "{ " );
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ printf( "%d ", Entry );
+ printf( "} cubes = %d\n", Min_CoverCountCubes( pCover ) );
+ }
+ // process the fanins
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ {
+ pFanin = Abc_NtkObj(pObj->pNtk, Entry);
+ Abc_NtkCovDerive_rec( p, pNtkNew, pFanin );
+ }
+ // for each cube, construct the node
+ nCubes = Min_CoverCountCubes( pCover );
+ if ( nCubes == 0 )
+ pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew);
+ else if ( nCubes == 1 )
+ pNodeNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCover, vSupp, Type == '0' );
+ else
+ {
+ // create the node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ {
+ pFanin = Abc_NtkObj(pObj->pNtk, Entry);
+ Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
+ }
+ // derive the function
+ vCover = Vec_StrAlloc( 100 );
+ Min_CoverCreate( vCover, pCover, (char)Type );
+ pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Vec_StrArray(vCover) );
+ Vec_StrFree( vCover );
+ }
+
+/*
+ printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level );
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ {
+ pFanin = Abc_NtkObj(pObj->pNtk, Entry);
+ printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id );
+ }
+ printf( "\n" );
+ Min_CoverWrite( stdout, pCover );
+*/
+ return pObj->pCopy = pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCovDeriveRegular( Cov_Man_t * p, Abc_Ntk_t * pNtk )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pNodeNew;
+ int i;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // perform strashing
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ // reconstruct the network
+ if ( Abc_ObjFanoutNum(Abc_AigConst1(pNtk)) > 0 )
+ Abc_AigConst1(pNtk)->pCopy = Abc_NtkCreateNodeConst1(pNtkNew);
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ {
+ pNodeNew = Abc_NtkCovDerive_rec( p, pNtkNew, Abc_ObjFanin0(pObj) );
+ if ( Abc_ObjFaninC0(pObj) )
+ {
+ if ( pNodeNew->pData && Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 1 )
+ Abc_SopComplement( pNodeNew->pData );
+ else
+ pNodeNew = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew );
+ }
+ Abc_ObjAddFanin( pObj->pCopy, pNodeNew );
+ }
+ // add the COs
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
+ // make sure everything is okay
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkCovDerive: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+