blob: 91a0c941d18675b1ce2e4e8fe87ab3afe55d19a3 [file] [log] [blame]
/**CFile****************************************************************
FileName [cecPat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Combinational equivalence checking.]
Synopsis [Simulation pattern manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cecPat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "cecInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Cec_ManPatStoreNum( Cec_ManPat_t * p, int Num )
{
unsigned x = (unsigned)Num;
assert( Num >= 0 );
while ( x & ~0x7f )
{
Vec_StrPush( p->vStorage, (char)((x & 0x7f) | 0x80) );
x >>= 7;
}
Vec_StrPush( p->vStorage, (char)x );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Cec_ManPatRestoreNum( Cec_ManPat_t * p )
{
int ch, i, x = 0;
for ( i = 0; (ch = Vec_StrEntry(p->vStorage, p->iStart++)) & 0x80; i++ )
x |= (ch & 0x7f) << (7 * i);
return x | (ch << (7 * i));
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Cec_ManPatStore( Cec_ManPat_t * p, Vec_Int_t * vPat )
{
int i, Number, NumberPrev;
assert( Vec_IntSize(vPat) > 0 );
Cec_ManPatStoreNum( p, Vec_IntSize(vPat) );
NumberPrev = Vec_IntEntry( vPat, 0 );
Cec_ManPatStoreNum( p, NumberPrev );
Vec_IntForEachEntryStart( vPat, Number, i, 1 )
{
assert( NumberPrev < Number );
Cec_ManPatStoreNum( p, Number - NumberPrev );
NumberPrev = Number;
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Cec_ManPatRestore( Cec_ManPat_t * p, Vec_Int_t * vPat )
{
int i, Size, Number;
Vec_IntClear( vPat );
Size = Cec_ManPatRestoreNum( p );
Number = Cec_ManPatRestoreNum( p );
Vec_IntPush( vPat, Number );
for ( i = 1; i < Size; i++ )
{
Number += Cec_ManPatRestoreNum( p );
Vec_IntPush( vPat, Number );
}
assert( Vec_IntSize(vPat) == Size );
}
/**Function*************************************************************
Synopsis [Derives satisfying assignment.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cec_ManPatComputePattern_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj )
{
int Counter = 0;
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return 0;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( Gia_ObjIsCi(pObj) )
{
pObj->fMark1 = Cec_ObjSatVarValue( pSat, pObj );
return 1;
}
assert( Gia_ObjIsAnd(pObj) );
Counter += Cec_ManPatComputePattern_rec( pSat, p, Gia_ObjFanin0(pObj) );
Counter += Cec_ManPatComputePattern_rec( pSat, p, Gia_ObjFanin1(pObj) );
pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) &
(Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj));
return Counter;
}
/**Function*************************************************************
Synopsis [Derives satisfying assignment.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManPatComputePattern1_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat )
{
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( Gia_ObjIsCi(pObj) )
{
Vec_IntPush( vPat, Abc_Var2Lit( Gia_ObjCioId(pObj), pObj->fMark1==0 ) );
return;
}
assert( Gia_ObjIsAnd(pObj) );
if ( pObj->fMark1 == 1 )
{
Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin0(pObj), vPat );
Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin1(pObj), vPat );
}
else
{
assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 ||
(Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 );
if ( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 )
Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin0(pObj), vPat );
else
Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin1(pObj), vPat );
}
}
/**Function*************************************************************
Synopsis [Derives satisfying assignment.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManPatComputePattern2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat )
{
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( Gia_ObjIsCi(pObj) )
{
Vec_IntPush( vPat, Abc_Var2Lit( Gia_ObjCioId(pObj), pObj->fMark1==0 ) );
return;
}
assert( Gia_ObjIsAnd(pObj) );
if ( pObj->fMark1 == 1 )
{
Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin0(pObj), vPat );
Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin1(pObj), vPat );
}
else
{
assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 ||
(Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 );
if ( (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 )
Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin1(pObj), vPat );
else
Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin0(pObj), vPat );
}
}
/**Function*************************************************************
Synopsis [Derives satisfying assignment.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cec_ManPatComputePattern3_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
{
int Value0, Value1, Value;
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return (pObj->fMark1 << 1) | pObj->fMark0;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( Gia_ObjIsCi(pObj) )
{
pObj->fMark0 = 1;
pObj->fMark1 = 1;
return GIA_UND;
}
assert( Gia_ObjIsAnd(pObj) );
Value0 = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) );
Value1 = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin1(pObj) );
Value = Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) );
pObj->fMark0 = (Value & 1);
pObj->fMark1 = ((Value >> 1) & 1);
return Value;
}
/**Function*************************************************************
Synopsis [Derives satisfying assignment.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManPatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat )
{
Gia_Obj_t * pTemp;
int i, Value;
Gia_ManIncrementTravId( p );
Vec_IntForEachEntry( vPat, Value, i )
{
pTemp = Gia_ManCi( p, Abc_Lit2Var(Value) );
// assert( Abc_LitIsCompl(Value) != (int)pTemp->fMark1 );
if ( pTemp->fMark1 )
{
pTemp->fMark0 = 0;
pTemp->fMark1 = 1;
}
else
{
pTemp->fMark0 = 1;
pTemp->fMark1 = 0;
}
Gia_ObjSetTravIdCurrent( p, pTemp );
}
Value = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) );
Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pObj) );
if ( Value != GIA_ONE )
Abc_Print( 1, "Cec_ManPatVerifyPattern(): Verification failed.\n" );
assert( Value == GIA_ONE );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManPatComputePattern4_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
{
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
pObj->fMark0 = 0;
if ( Gia_ObjIsCi(pObj) )
return;
assert( Gia_ObjIsAnd(pObj) );
Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin0(pObj) );
Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin1(pObj) );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManPatCleanMark0( Gia_Man_t * p, Gia_Obj_t * pObj )
{
assert( Gia_ObjIsCo(pObj) );
Gia_ManIncrementTravId( p );
Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin0(pObj) );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManPatSavePattern( Cec_ManPat_t * pMan, Cec_ManSat_t * p, Gia_Obj_t * pObj )
{
Vec_Int_t * vPat;
int nPatLits;
abctime clkTotal = Abc_Clock();
// abctime clk;
assert( Gia_ObjIsCo(pObj) );
pMan->nPats++;
pMan->nPatsAll++;
// compute values in the cone of influence
//clk = Abc_Clock();
Gia_ManIncrementTravId( p->pAig );
nPatLits = Cec_ManPatComputePattern_rec( p, p->pAig, Gia_ObjFanin0(pObj) );
assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 1 );
pMan->nPatLits += nPatLits;
pMan->nPatLitsAll += nPatLits;
//pMan->timeFind += Abc_Clock() - clk;
// compute sensitizing path
//clk = Abc_Clock();
Vec_IntClear( pMan->vPattern1 );
Gia_ManIncrementTravId( p->pAig );
Cec_ManPatComputePattern1_rec( p->pAig, Gia_ObjFanin0(pObj), pMan->vPattern1 );
// compute sensitizing path
Vec_IntClear( pMan->vPattern2 );
Gia_ManIncrementTravId( p->pAig );
Cec_ManPatComputePattern2_rec( p->pAig, Gia_ObjFanin0(pObj), pMan->vPattern2 );
// compare patterns
vPat = Vec_IntSize(pMan->vPattern1) < Vec_IntSize(pMan->vPattern2) ? pMan->vPattern1 : pMan->vPattern2;
pMan->nPatLitsMin += Vec_IntSize(vPat);
pMan->nPatLitsMinAll += Vec_IntSize(vPat);
//pMan->timeShrink += Abc_Clock() - clk;
// verify pattern using ternary simulation
//clk = Abc_Clock();
// Cec_ManPatVerifyPattern( p->pAig, pObj, vPat );
//pMan->timeVerify += Abc_Clock() - clk;
// sort pattern
//clk = Abc_Clock();
Vec_IntSort( vPat, 0 );
//pMan->timeSort += Abc_Clock() - clk;
// save pattern
Cec_ManPatStore( pMan, vPat );
pMan->timeTotal += Abc_Clock() - clkTotal;
}
void Cec_ManPatSavePatternCSat( Cec_ManPat_t * pMan, Vec_Int_t * vPat )
{
// sort pattern
Vec_IntSort( vPat, 0 );
// save pattern
Cec_ManPatStore( pMan, vPat );
}
/**Function*************************************************************
Synopsis [Packs patterns into array of simulation info.]
Description []
SideEffects []
SeeAlso []
*************************************`**********************************/
int Cec_ManPatCollectTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits )
{
unsigned * pInfo, * pPres;
int i;
for ( i = 0; i < nLits; i++ )
{
pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i]));
pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i]));
if ( Abc_InfoHasBit( pPres, iBit ) &&
Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) )
return 0;
}
for ( i = 0; i < nLits; i++ )
{
pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i]));
pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i]));
Abc_InfoSetBit( pPres, iBit );
if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) )
Abc_InfoXorBit( pInfo, iBit );
}
return 1;
}
/**Function*************************************************************
Synopsis [Packs patterns into array of simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWordsInit )
{
Vec_Int_t * vPat = pMan->vPattern1;
Vec_Ptr_t * vInfo, * vPres;
int k, kMax = -1, nPatterns = 0;
int iStartOld = pMan->iStart;
int nWords = nWordsInit;
int nBits = 32 * nWords;
abctime clk = Abc_Clock();
vInfo = Vec_PtrAllocSimInfo( nInputs, nWords );
Gia_ManRandomInfo( vInfo, 0, 0, nWords );
vPres = Vec_PtrAllocSimInfo( nInputs, nWords );
Vec_PtrCleanSimInfo( vPres, 0, nWords );
while ( pMan->iStart < Vec_StrSize(pMan->vStorage) )
{
nPatterns++;
Cec_ManPatRestore( pMan, vPat );
for ( k = 1; k < nBits; k++, k += ((k % (32 * nWordsInit)) == 0) )
if ( Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) )
break;
kMax = Abc_MaxInt( kMax, k );
if ( k == nBits-1 )
{
Vec_PtrReallocSimInfo( vInfo );
Gia_ManRandomInfo( vInfo, 0, nWords, 2*nWords );
Vec_PtrReallocSimInfo( vPres );
Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords );
nWords *= 2;
nBits *= 2;
}
}
Vec_PtrFree( vPres );
pMan->nSeries = Vec_PtrReadWordsSimInfo(vInfo) / nWordsInit;
pMan->timePack += Abc_Clock() - clk;
pMan->timeTotal += Abc_Clock() - clk;
pMan->iStart = iStartOld;
if ( pMan->fVerbose )
{
Abc_Print( 1, "Total = %5d. Max used = %5d. Full = %5d. Series = %d. ",
nPatterns, kMax, nWordsInit*32, pMan->nSeries );
ABC_PRT( "Time", Abc_Clock() - clk );
Cec_ManPatPrintStats( pMan );
}
return vInfo;
}
/**Function*************************************************************
Synopsis [Packs patterns into array of simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit )
{
Vec_Int_t * vPat;
Vec_Ptr_t * vInfo, * vPres;
int k, nSize, iStart, kMax = 0, nPatterns = 0;
int nWords = nWordsInit;
int nBits = 32 * nWords;
// int RetValue;
assert( nRegs <= nInputs );
vPat = Vec_IntAlloc( 100 );
vInfo = Vec_PtrAllocSimInfo( nInputs, nWords );
Vec_PtrCleanSimInfo( vInfo, 0, nWords );
Gia_ManRandomInfo( vInfo, nRegs, 0, nWords );
vPres = Vec_PtrAllocSimInfo( nInputs, nWords );
Vec_PtrCleanSimInfo( vPres, 0, nWords );
iStart = 0;
while ( iStart < Vec_IntSize(vCexStore) )
{
nPatterns++;
// skip the output number
iStart++;
// get the number of items
nSize = Vec_IntEntry( vCexStore, iStart++ );
if ( nSize <= 0 )
continue;
// extract pattern
Vec_IntClear( vPat );
for ( k = 0; k < nSize; k++ )
Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) );
// add pattern to storage
for ( k = 1; k < nBits; k++, k += ((k % (32 * nWordsInit)) == 0) )
if ( Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) )
break;
// k = kMax + 1;
// RetValue = Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) );
// assert( RetValue == 1 );
kMax = Abc_MaxInt( kMax, k );
if ( k == nBits-1 )
{
Vec_PtrReallocSimInfo( vInfo );
Vec_PtrCleanSimInfo( vInfo, nWords, 2*nWords );
Gia_ManRandomInfo( vInfo, nRegs, nWords, 2*nWords );
Vec_PtrReallocSimInfo( vPres );
Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords );
nWords *= 2;
nBits *= 2;
}
}
// Abc_Print( 1, "packed %d patterns into %d vectors (out of %d)\n", nPatterns, kMax, nBits );
Vec_PtrFree( vPres );
Vec_IntFree( vPat );
return vInfo;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END