abc/src/temp/player/playerCore.c

377 lines
12 KiB
C

/**CFile****************************************************************
FileName [playerCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [PLA decomposition package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006.]
Revision [$Id: playerCore.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "player.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Pla_ManDecomposeInt( Pla_Man_t * p );
static int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj );
static void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level,
Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fVerbose )
{
Pla_Man_t * p;
p = Pla_ManAlloc( pAig, nLutMax, nPlaMax );
if ( !Pla_ManDecomposeInt( p ) )
{
printf( "Decomposition/mapping failed.\n" );
Pla_ManFree( p );
return NULL;
}
return p;
}
/**Function*************************************************************
Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Pla_ManDecomposeInt( Pla_Man_t * p )
{
Ivy_Man_t * pAig = p->pManAig;
Ivy_Obj_t * pObj;
Pla_Obj_t * pStr;
int i;
// prepare the PI structures
Ivy_ManForEachPi( pAig, pObj, i )
{
pStr = Ivy_ObjPlaStr( pAig, pObj );
pStr->fFixed = 1;
pStr->Depth = 0;
pStr->nRefs = (unsigned)pObj->nRefs;
pStr->pCover[0] = PLA_EMPTY;
pStr->pCover[1] = PLA_EMPTY;
}
// assuming DFS ordering of nodes in the manager
Ivy_ManForEachNode( pAig, pObj, i )
if ( !Pla_ManDecomposeNode(p, pObj) )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Records decomposition statistics for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Pla_ManCountDecNodes( Pla_Man_t * p, Pla_Obj_t * pStr )
{
if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax && pStr->pCover[1] != PLA_EMPTY )
p->nNodesBoth++;
else if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax )
p->nNodesLut++;
else if ( pStr->pCover[1] != PLA_EMPTY )
p->nNodesPla++;
}
/**Function*************************************************************
Synopsis [Performs decomposition/mapping for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj )
{
Pla_Obj_t * pStr, * pStr0, * pStr1;
Vec_Int_t * vSuppA, * vSuppB, * vSupp0, * vSupp1;
Esop_Cube_t * pCovA, * pCovB;
int nSuppSize1, nSuppSize2;
assert( pObj->nRefs > 0 );
p->nNodes++;
// get the structures
pStr = Ivy_ObjPlaStr( p->pManAig, pObj );
pStr0 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin0( pObj ) );
pStr1 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin1( pObj ) );
vSupp0 = &pStr->vSupp[0];
vSupp1 = &pStr->vSupp[1];
pStr->pCover[0] = PLA_EMPTY;
pStr->pCover[1] = PLA_EMPTY;
// process level 1
Pla_NodeGetSuppsAndCovers( p, pObj, 1, &vSuppA, &vSuppB, &pCovA, &pCovB );
nSuppSize1 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 );
if ( nSuppSize1 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
pStr->pCover[0] = PLA_EMPTY;
else if ( Ivy_ObjIsAnd(pObj) )
pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 );
else
pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 );
// process level 2
if ( PLA_MAX(pStr0->Depth, pStr1->Depth) > 1 )
{
Pla_NodeGetSuppsAndCovers( p, pObj, 2, &vSuppA, &vSuppB, &pCovA, &pCovB );
nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp1 );
if ( nSuppSize2 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
pStr->pCover[1] = PLA_EMPTY;
else if ( Ivy_ObjIsAnd(pObj) )
pStr->pCover[1] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 );
else
pStr->pCover[1] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 );
}
// determine the level of this node
pStr->nRefs = (unsigned)pObj->nRefs;
pStr->Depth = PLA_MAX( pStr0->Depth, pStr1->Depth );
pStr->Depth = pStr->Depth? pStr->Depth : 1;
if ( nSuppSize1 > p->nLutMax && pStr->pCover[1] == PLA_EMPTY )
{
pStr->Depth++;
// free second level
if ( pStr->pCover[1] != PLA_EMPTY )
Esop_CoverRecycle( p->pManMin, pStr->pCover[1] );
vSupp1->nCap = 0;
vSupp1->nSize = 0;
FREE( vSupp1->pArray );
pStr->pCover[1] = PLA_EMPTY;
// move first to second
pStr->vSupp[1] = pStr->vSupp[0];
pStr->pCover[1] = pStr->pCover[0];
vSupp0->nCap = 0;
vSupp0->nSize = 0;
vSupp0->pArray = NULL;
pStr->pCover[0] = PLA_EMPTY;
// get zero level
Pla_NodeGetSuppsAndCovers( p, pObj, 0, &vSuppA, &vSuppB, &pCovA, &pCovB );
nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 );
assert( nSuppSize2 == 2 );
if ( pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
pStr->pCover[0] = PLA_EMPTY;
else if ( Ivy_ObjIsAnd(pObj) )
pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 );
else
pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 );
// count stats
if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 );
if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 );
// mark the nodes
pStr0->fFixed = 1;
pStr1->fFixed = 1;
}
else if ( pStr0->Depth < pStr1->Depth )
{
if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 );
pStr0->fFixed = 1;
}
else // if ( pStr0->Depth > pStr1->Depth )
{
if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 );
pStr1->fFixed = 1;
}
assert( pStr->Depth );
// free some of the covers to save memory
assert( pStr0->nRefs > 0 );
assert( pStr1->nRefs > 0 );
pStr0->nRefs--;
pStr1->nRefs--;
if ( pStr0->nRefs == 0 && !pStr0->fFixed )
Pla_ManFreeStr( p, pStr0 ), p->nNodesDeref++;
if ( pStr1->nRefs == 0 && !pStr1->fFixed )
Pla_ManFreeStr( p, pStr1 ), p->nNodesDeref++;
return 1;
}
/**Function*************************************************************
Synopsis [Returns pointers to the support arrays on the given level.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level,
Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB )
{
Ivy_Obj_t * pFan0, * pFan1;
Pla_Obj_t * pStr, * pStr0, * pStr1;
Esop_Cube_t * pCovA, * pCovB;
int fCompl0, fCompl1;
assert( Level >= 0 && Level <= 2 );
// get the complemented attributes
fCompl0 = Ivy_ObjFaninC0( pObj );
fCompl1 = Ivy_ObjFaninC1( pObj );
// get the fanins
pFan0 = Ivy_ObjFanin0( pObj );
pFan1 = Ivy_ObjFanin1( pObj );
// get the structures
pStr = Ivy_ObjPlaStr( p->pManAig, pObj );
pStr0 = Ivy_ObjPlaStr( p->pManAig, pFan0 );
pStr1 = Ivy_ObjPlaStr( p->pManAig, pFan1 );
// make sure the fanins are processed
assert( Ivy_ObjIsPi(pFan0) || pStr0->Depth > 0 );
assert( Ivy_ObjIsPi(pFan1) || pStr1->Depth > 0 );
// prepare the return values depending on the level
Vec_IntWriteEntry( p->vTriv0, 0, pFan0->Id );
Vec_IntWriteEntry( p->vTriv1, 0, pFan1->Id );
*pvSuppA = p->vTriv0;
*pvSuppB = p->vTriv1;
pCovA = p->pManMin->pTriv0;
pCovB = p->pManMin->pTriv1;
if ( Level == 1 )
{
if ( pStr0->Depth == pStr1->Depth )
{
if ( pStr0->Depth > 0 )
{
*pvSuppA = &pStr0->vSupp[0];
*pvSuppB = &pStr1->vSupp[0];
pCovA = pStr0->pCover[0];
pCovB = pStr1->pCover[0];
}
}
else if ( pStr0->Depth < pStr1->Depth )
{
*pvSuppB = &pStr1->vSupp[0];
pCovB = pStr1->pCover[0];
}
else // if ( pStr0->Depth > pStr1->Depth )
{
*pvSuppA = &pStr0->vSupp[0];
pCovA = pStr0->pCover[0];
}
}
else if ( Level == 2 )
{
if ( pStr0->Depth == pStr1->Depth )
{
*pvSuppA = &pStr0->vSupp[1];
*pvSuppB = &pStr1->vSupp[1];
pCovA = pStr0->pCover[1];
pCovB = pStr1->pCover[1];
}
else if ( pStr0->Depth + 1 == pStr1->Depth )
{
*pvSuppA = &pStr0->vSupp[0];
*pvSuppB = &pStr1->vSupp[1];
pCovA = pStr0->pCover[0];
pCovB = pStr1->pCover[1];
}
else if ( pStr0->Depth == pStr1->Depth + 1 )
{
*pvSuppA = &pStr0->vSupp[1];
*pvSuppB = &pStr1->vSupp[0];
pCovA = pStr0->pCover[1];
pCovB = pStr1->pCover[0];
}
else if ( pStr0->Depth < pStr1->Depth )
{
*pvSuppB = &pStr1->vSupp[1];
pCovB = pStr1->pCover[1];
}
else // if ( pStr0->Depth > pStr1->Depth )
{
*pvSuppA = &pStr0->vSupp[1];
pCovA = pStr0->pCover[1];
}
}
// complement the first if needed
if ( pCovA == PLA_EMPTY || !fCompl0 )
*pvCovA = pCovA;
else if ( pCovA && pCovA->nLits == 0 ) // topmost one is the tautology cube
*pvCovA = pCovA->pNext;
else
*pvCovA = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCovA;
// complement the second if needed
if ( pCovB == PLA_EMPTY || !fCompl1 )
*pvCovB = pCovB;
else if ( pCovB && pCovB->nLits == 0 ) // topmost one is the tautology cube
*pvCovB = pCovB->pNext;
else
*pvCovB = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCovB;
}
/*
if ( pObj->Id == 1371 )
{
int k;
printf( "Zero : " );
for ( k = 0; k < vSuppA->nSize; k++ )
printf( "%d ", vSuppA->pArray[k] );
printf( "\n" );
printf( "One : " );
for ( k = 0; k < vSuppB->nSize; k++ )
printf( "%d ", vSuppB->pArray[k] );
printf( "\n" );
printf( "Node : " );
for ( k = 0; k < vSupp0->nSize; k++ )
printf( "%d ", vSupp0->pArray[k] );
printf( "\n" );
printf( "\n" );
printf( "\n" );
Esop_CoverWrite( stdout, pCovA );
printf( "\n" );
Esop_CoverWrite( stdout, pCovB );
printf( "\n" );
}
*/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////