blob: a6aced1de78c988c119de2caca3a54753b35c300 [file] [log] [blame]
/**CFile****************************************************************
FileName [resSim.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Resynthesis package.]
Synopsis [Simulation engine.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - January 15, 2007.]
Revision [$Id: resSim.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $]
***********************************************************************/
#include "base/abc/abc.h"
#include "resInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocate simulation engine.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Res_Sim_t * Res_SimAlloc( int nWords )
{
Res_Sim_t * p;
p = ALLOC( Res_Sim_t, 1 );
memset( p, 0, sizeof(Res_Sim_t) );
// simulation parameters
p->nWords = nWords;
p->nPats = 8 * sizeof(unsigned) * p->nWords;
p->nWordsOut = p->nPats * p->nWords;
p->nPatsOut = p->nPats * p->nPats;
// simulation info
p->vPats = Vec_PtrAllocSimInfo( 1024, p->nWords );
p->vPats0 = Vec_PtrAllocSimInfo( 128, p->nWords );
p->vPats1 = Vec_PtrAllocSimInfo( 128, p->nWords );
p->vOuts = Vec_PtrAllocSimInfo( 128, p->nWordsOut );
// resub candidates
p->vCands = Vec_VecStart( 16 );
return p;
}
/**Function*************************************************************
Synopsis [Allocate simulation engine.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimAdjust( Res_Sim_t * p, Abc_Ntk_t * pAig )
{
srand( 0xABC );
assert( Abc_NtkIsStrash(pAig) );
p->pAig = pAig;
if ( Vec_PtrSize(p->vPats) < Abc_NtkObjNumMax(pAig)+1 )
{
Vec_PtrFree( p->vPats );
p->vPats = Vec_PtrAllocSimInfo( Abc_NtkObjNumMax(pAig)+1, p->nWords );
}
if ( Vec_PtrSize(p->vPats0) < Abc_NtkPiNum(pAig) )
{
Vec_PtrFree( p->vPats0 );
p->vPats0 = Vec_PtrAllocSimInfo( Abc_NtkPiNum(pAig), p->nWords );
}
if ( Vec_PtrSize(p->vPats1) < Abc_NtkPiNum(pAig) )
{
Vec_PtrFree( p->vPats1 );
p->vPats1 = Vec_PtrAllocSimInfo( Abc_NtkPiNum(pAig), p->nWords );
}
if ( Vec_PtrSize(p->vOuts) < Abc_NtkPoNum(pAig) )
{
Vec_PtrFree( p->vOuts );
p->vOuts = Vec_PtrAllocSimInfo( Abc_NtkPoNum(pAig), p->nWordsOut );
}
// clean storage info for patterns
Abc_InfoClear( Vec_PtrEntry(p->vPats0,0), p->nWords * Abc_NtkPiNum(pAig) );
Abc_InfoClear( Vec_PtrEntry(p->vPats1,0), p->nWords * Abc_NtkPiNum(pAig) );
p->nPats0 = 0;
p->nPats1 = 0;
}
/**Function*************************************************************
Synopsis [Free simulation engine.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimFree( Res_Sim_t * p )
{
Vec_PtrFree( p->vPats );
Vec_PtrFree( p->vPats0 );
Vec_PtrFree( p->vPats1 );
Vec_PtrFree( p->vOuts );
Vec_VecFree( p->vCands );
free( p );
}
/**Function*************************************************************
Synopsis [Sets random PI simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimSetRandom( Res_Sim_t * p )
{
Abc_Obj_t * pObj;
unsigned * pInfo;
int i;
Abc_NtkForEachPi( p->pAig, pObj, i )
{
pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
Abc_InfoRandom( pInfo, p->nWords );
}
}
/**Function*************************************************************
Synopsis [Sets given PI simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimSetGiven( Res_Sim_t * p, Vec_Ptr_t * vInfo )
{
Abc_Obj_t * pObj;
unsigned * pInfo, * pInfo2;
int i, w;
Abc_NtkForEachPi( p->pAig, pObj, i )
{
pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
pInfo2 = Vec_PtrEntry( vInfo, i );
for ( w = 0; w < p->nWords; w++ )
pInfo[w] = pInfo2[w];
}
}
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimPerformOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords )
{
unsigned * pInfo, * pInfo1, * pInfo2;
int k, fComp1, fComp2;
// simulate the internal nodes
assert( Abc_ObjIsNode(pNode) );
pInfo = Vec_PtrEntry(vSimInfo, pNode->Id);
pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode));
pInfo2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode));
fComp1 = Abc_ObjFaninC0(pNode);
fComp2 = Abc_ObjFaninC1(pNode);
if ( fComp1 && fComp2 )
for ( k = 0; k < nSimWords; k++ )
pInfo[k] = ~pInfo1[k] & ~pInfo2[k];
else if ( fComp1 && !fComp2 )
for ( k = 0; k < nSimWords; k++ )
pInfo[k] = ~pInfo1[k] & pInfo2[k];
else if ( !fComp1 && fComp2 )
for ( k = 0; k < nSimWords; k++ )
pInfo[k] = pInfo1[k] & ~pInfo2[k];
else // if ( fComp1 && fComp2 )
for ( k = 0; k < nSimWords; k++ )
pInfo[k] = pInfo1[k] & pInfo2[k];
}
/**Function*************************************************************
Synopsis [Simulates one CO node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimTransferOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords )
{
unsigned * pInfo, * pInfo1;
int k, fComp1;
// simulate the internal nodes
assert( Abc_ObjIsCo(pNode) );
pInfo = Vec_PtrEntry(vSimInfo, pNode->Id);
pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode));
fComp1 = Abc_ObjFaninC0(pNode);
if ( fComp1 )
for ( k = 0; k < nSimWords; k++ )
pInfo[k] = ~pInfo1[k];
else
for ( k = 0; k < nSimWords; k++ )
pInfo[k] = pInfo1[k];
}
/**Function*************************************************************
Synopsis [Performs one round of simulation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimPerformRound( Res_Sim_t * p )
{
Abc_Obj_t * pObj;
int i;
Abc_InfoFill( Vec_PtrEntry(p->vPats,0), p->nWords );
Abc_AigForEachAnd( p->pAig, pObj, i )
Res_SimPerformOne( pObj, p->vPats, p->nWords );
Abc_NtkForEachPo( p->pAig, pObj, i )
Res_SimTransferOne( pObj, p->vPats, p->nWords );
}
/**Function*************************************************************
Synopsis [Processes simulation patterns.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimProcessPats( Res_Sim_t * p )
{
Abc_Obj_t * pObj;
unsigned * pInfoCare, * pInfoNode;
int i, j, nDcs = 0;
pInfoCare = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id );
pInfoNode = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id );
for ( i = 0; i < p->nPats; i++ )
{
// skip don't-care patterns
if ( !Abc_InfoHasBit(pInfoCare, i) )
{
nDcs++;
continue;
}
// separate offset and onset patterns
if ( !Abc_InfoHasBit(pInfoNode, i) )
{
if ( p->nPats0 >= p->nPats )
continue;
Abc_NtkForEachPi( p->pAig, pObj, j )
if ( Abc_InfoHasBit( Vec_PtrEntry(p->vPats, pObj->Id), i ) )
Abc_InfoSetBit( Vec_PtrEntry(p->vPats0, j), p->nPats0 );
p->nPats0++;
}
else
{
if ( p->nPats1 >= p->nPats )
continue;
Abc_NtkForEachPi( p->pAig, pObj, j )
if ( Abc_InfoHasBit( Vec_PtrEntry(p->vPats, pObj->Id), i ) )
Abc_InfoSetBit( Vec_PtrEntry(p->vPats1, j), p->nPats1 );
p->nPats1++;
}
}
}
/**Function*************************************************************
Synopsis [Pads the extra space with duplicated simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimPadSimInfo( Vec_Ptr_t * vPats, int nPats, int nWords )
{
unsigned * pInfo;
int i, w, iWords;
assert( nPats > 0 && nPats < nWords * 8 * (int) sizeof(unsigned) );
// pad the first word
if ( nPats < 8 * sizeof(unsigned) )
{
Vec_PtrForEachEntry( unsigned *, vPats, pInfo, i )
if ( pInfo[0] & 1 )
pInfo[0] |= ((~0) << nPats);
nPats = 8 * sizeof(unsigned);
}
// pad the empty words
iWords = nPats / (8 * sizeof(unsigned));
Vec_PtrForEachEntry( unsigned *, vPats, pInfo, i )
{
for ( w = iWords; w < nWords; w++ )
pInfo[w] = pInfo[0];
}
}
/**Function*************************************************************
Synopsis [Duplicates the simulation info to fill the space.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimDeriveInfoReplicate( Res_Sim_t * p )
{
unsigned * pInfo, * pInfo2;
Abc_Obj_t * pObj;
int i, j, w;
Abc_NtkForEachPo( p->pAig, pObj, i )
{
pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
pInfo2 = Vec_PtrEntry( p->vOuts, i );
for ( j = 0; j < p->nPats; j++ )
for ( w = 0; w < p->nWords; w++ )
*pInfo2++ = pInfo[w];
}
}
/**Function*************************************************************
Synopsis [Complement the simulation info if necessary.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimDeriveInfoComplement( Res_Sim_t * p )
{
unsigned * pInfo, * pInfo2;
Abc_Obj_t * pObj;
int i, j, w;
Abc_NtkForEachPo( p->pAig, pObj, i )
{
pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
pInfo2 = Vec_PtrEntry( p->vOuts, i );
for ( j = 0; j < p->nPats; j++, pInfo2 += p->nWords )
if ( Abc_InfoHasBit( pInfo, j ) )
for ( w = 0; w < p->nWords; w++ )
pInfo2[w] = ~pInfo2[w];
}
}
/**Function*************************************************************
Synopsis [Free simulation engine.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimReportOne( Res_Sim_t * p )
{
unsigned * pInfoCare, * pInfoNode;
int i, nDcs, nOnes, nZeros;
pInfoCare = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id );
pInfoNode = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id );
nDcs = nOnes = nZeros = 0;
for ( i = 0; i < p->nPats; i++ )
{
// skip don't-care patterns
if ( !Abc_InfoHasBit(pInfoCare, i) )
{
nDcs++;
continue;
}
// separate offset and onset patterns
if ( !Abc_InfoHasBit(pInfoNode, i) )
nZeros++;
else
nOnes++;
}
printf( "On = %3d (%7.2f %%) ", nOnes, 100.0*nOnes/p->nPats );
printf( "Off = %3d (%7.2f %%) ", nZeros, 100.0*nZeros/p->nPats );
printf( "Dc = %3d (%7.2f %%) ", nDcs, 100.0*nDcs/p->nPats );
printf( "P0 = %3d ", p->nPats0 );
printf( "P1 = %3d ", p->nPats1 );
if ( p->nPats0 < 4 || p->nPats1 < 4 )
printf( "*" );
printf( "\n" );
}
/**Function*************************************************************
Synopsis [Prints output patterns.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_SimPrintOutPatterns( Res_Sim_t * p, Abc_Ntk_t * pAig )
{
Abc_Obj_t * pObj;
unsigned * pInfo2;
int i;
Abc_NtkForEachPo( pAig, pObj, i )
{
pInfo2 = Vec_PtrEntry( p->vOuts, i );
Extra_PrintBinary( stdout, pInfo2, p->nPatsOut );
printf( "\n" );
}
}
/**Function*************************************************************
Synopsis [Prepares simulation info for candidate filtering.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Res_SimPrepare( Res_Sim_t * p, Abc_Ntk_t * pAig, int nTruePis, int fVerbose )
{
int Limit;
// prepare the manager
Res_SimAdjust( p, pAig );
// collect 0/1 simulation info
for ( Limit = 0; Limit < 10; Limit++ )
{
Res_SimSetRandom( p );
Res_SimPerformRound( p );
Res_SimProcessPats( p );
if ( !(p->nPats0 < p->nPats || p->nPats1 < p->nPats) )
break;
}
// printf( "%d ", Limit );
// report the last set of patterns
// Res_SimReportOne( p );
// printf( "\n" );
// quit if there is not enough
// if ( p->nPats0 < 4 || p->nPats1 < 4 )
if ( p->nPats0 < 4 || p->nPats1 < 4 )
{
// Res_SimReportOne( p );
return 0;
}
// create bit-matrix info
if ( p->nPats0 < p->nPats )
Res_SimPadSimInfo( p->vPats0, p->nPats0, p->nWords );
if ( p->nPats1 < p->nPats )
Res_SimPadSimInfo( p->vPats1, p->nPats1, p->nWords );
// resimulate 0-patterns
Res_SimSetGiven( p, p->vPats0 );
Res_SimPerformRound( p );
Res_SimDeriveInfoReplicate( p );
// resimulate 1-patterns
Res_SimSetGiven( p, p->vPats1 );
Res_SimPerformRound( p );
Res_SimDeriveInfoComplement( p );
// print output patterns
// Res_SimPrintOutPatterns( p, pAig );
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END