abc/src/aig/cec/cecClass.c

909 lines
26 KiB
C
Raw Normal View History

2009-01-18 17:01:00 +01:00
/**CFile****************************************************************
FileName [cecClass.c]
SystemName [ABC: Logic synthesis and verification system.]
2009-04-05 17:01:00 +02:00
PackageName [Combinational equivalence checking.]
2009-01-18 17:01:00 +01:00
2009-04-05 17:01:00 +02:00
Synopsis [Equivalence class refinement.]
2009-01-18 17:01:00 +01:00
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cecClass.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "cecInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
2009-03-10 16:01:00 +01:00
static inline unsigned * Cec_ObjSim( Cec_ManSim_t * p, int Id ) { return p->pMems + p->pSimInfo[Id] + 1; }
static inline void Cec_ObjSetSim( Cec_ManSim_t * p, int Id, int n ) { p->pSimInfo[Id] = n; }
static inline float Cec_MemUsage( Cec_ManSim_t * p ) { return 1.0*p->nMemsMax*(p->pPars->nWords+1)/(1<<20); }
2009-02-15 17:01:00 +01:00
2009-01-18 17:01:00 +01:00
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
2009-02-15 17:01:00 +01:00
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Compares simulation info of one node with constant 0.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimCompareConst( unsigned * p, int nWords )
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
int w;
if ( p[0] & 1 )
2009-02-15 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
for ( w = 0; w < nWords; w++ )
if ( p[w] != ~0 )
return 0;
return 1;
2009-02-15 17:01:00 +01:00
}
2009-03-10 16:01:00 +01:00
else
2009-02-15 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
for ( w = 0; w < nWords; w++ )
if ( p[w] != 0 )
return 0;
return 1;
2009-02-15 17:01:00 +01:00
}
2009-01-18 17:01:00 +01:00
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Compares simulation info of two nodes.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimCompareEqual( unsigned * p0, unsigned * p1, int nWords )
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
int w;
if ( (p0[0] & 1) == (p1[0] & 1) )
2009-02-15 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
for ( w = 0; w < nWords; w++ )
if ( p0[w] != p1[w] )
return 0;
return 1;
2009-02-15 17:01:00 +01:00
}
2009-03-10 16:01:00 +01:00
else
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
for ( w = 0; w < nWords; w++ )
if ( p0[w] != ~p1[w] )
return 0;
return 1;
2009-01-18 17:01:00 +01:00
}
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Returns the number of the first non-equal bit.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimCompareConstFirstBit( unsigned * p, int nWords )
2009-01-18 17:01:00 +01:00
{
int w;
2009-03-10 16:01:00 +01:00
if ( p[0] & 1 )
2009-01-18 17:01:00 +01:00
{
for ( w = 0; w < nWords; w++ )
2009-03-10 16:01:00 +01:00
if ( p[w] != ~0 )
2009-04-08 17:01:00 +02:00
return 32*w + Gia_WordFindFirstBit( ~p[w] );
2009-03-10 16:01:00 +01:00
return -1;
2009-01-18 17:01:00 +01:00
}
else
{
for ( w = 0; w < nWords; w++ )
2009-03-10 16:01:00 +01:00
if ( p[w] != 0 )
2009-04-08 17:01:00 +02:00
return 32*w + Gia_WordFindFirstBit( p[w] );
2009-03-10 16:01:00 +01:00
return -1;
2009-01-18 17:01:00 +01:00
}
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Compares simulation info of two nodes.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimCompareEqualFirstBit( unsigned * p0, unsigned * p1, int nWords )
2009-01-18 17:01:00 +01:00
{
int w;
2009-03-10 16:01:00 +01:00
if ( (p0[0] & 1) == (p1[0] & 1) )
2009-01-18 17:01:00 +01:00
{
for ( w = 0; w < nWords; w++ )
2009-03-10 16:01:00 +01:00
if ( p0[w] != p1[w] )
2009-04-08 17:01:00 +02:00
return 32*w + Gia_WordFindFirstBit( p0[w] ^ p1[w] );
2009-03-10 16:01:00 +01:00
return -1;
2009-01-18 17:01:00 +01:00
}
else
{
for ( w = 0; w < nWords; w++ )
2009-03-10 16:01:00 +01:00
if ( p0[w] != ~p1[w] )
2009-04-08 17:01:00 +02:00
return 32*w + Gia_WordFindFirstBit( p0[w] ^ ~p1[w] );
2009-03-10 16:01:00 +01:00
return -1;
2009-01-18 17:01:00 +01:00
}
}
2009-03-11 16:01:00 +01:00
/**Function*************************************************************
Synopsis [Returns the number of the first non-equal bit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManSimCompareConstScore( unsigned * p, int nWords, int * pScores )
{
int w, b;
if ( p[0] & 1 )
{
for ( w = 0; w < nWords; w++ )
if ( p[w] != ~0 )
for ( b = 0; b < 32; b++ )
if ( ((~p[w]) >> b ) & 1 )
pScores[32*w + b]++;
}
else
{
for ( w = 0; w < nWords; w++ )
if ( p[w] != 0 )
for ( b = 0; b < 32; b++ )
if ( ((p[w]) >> b ) & 1 )
pScores[32*w + b]++;
}
}
/**Function*************************************************************
Synopsis [Compares simulation info of two nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManSimCompareEqualScore( unsigned * p0, unsigned * p1, int nWords, int * pScores )
{
int w, b;
if ( (p0[0] & 1) == (p1[0] & 1) )
{
for ( w = 0; w < nWords; w++ )
if ( p0[w] != p1[w] )
for ( b = 0; b < 32; b++ )
if ( ((p0[w] ^ p1[w]) >> b ) & 1 )
pScores[32*w + b]++;
}
else
{
for ( w = 0; w < nWords; w++ )
if ( p0[w] != ~p1[w] )
for ( b = 0; b < 32; b++ )
if ( ((p0[w] ^ ~p1[w]) >> b ) & 1 )
pScores[32*w + b]++;
}
}
2009-01-18 17:01:00 +01:00
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Creates equivalence class.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
void Cec_ManSimClassCreate( Gia_Man_t * p, Vec_Int_t * vClass )
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
int Repr = GIA_VOID, EntPrev = -1, Ent, i;
2009-01-18 17:01:00 +01:00
assert( Vec_IntSize(vClass) > 0 );
Vec_IntForEachEntry( vClass, Ent, i )
{
if ( i == 0 )
{
Repr = Ent;
2009-03-10 16:01:00 +01:00
Gia_ObjSetRepr( p, Ent, GIA_VOID );
2009-02-15 17:01:00 +01:00
EntPrev = Ent;
2009-01-18 17:01:00 +01:00
}
else
{
2009-03-13 16:01:00 +01:00
assert( Repr < Ent );
2009-03-10 16:01:00 +01:00
Gia_ObjSetRepr( p, Ent, Repr );
Gia_ObjSetNext( p, EntPrev, Ent );
2009-02-15 17:01:00 +01:00
EntPrev = Ent;
2009-01-18 17:01:00 +01:00
}
}
2009-03-10 16:01:00 +01:00
Gia_ObjSetNext( p, EntPrev, 0 );
2009-01-18 17:01:00 +01:00
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Refines one equivalence class.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i )
2009-01-18 17:01:00 +01:00
{
unsigned * pSim0, * pSim1;
2009-02-15 17:01:00 +01:00
int Ent;
2009-01-18 17:01:00 +01:00
Vec_IntClear( p->vClassOld );
Vec_IntClear( p->vClassNew );
Vec_IntPush( p->vClassOld, i );
2009-03-10 16:01:00 +01:00
pSim0 = Cec_ObjSim(p, i);
Gia_ClassForEachObj1( p->pAig, i, Ent )
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
pSim1 = Cec_ObjSim(p, Ent);
if ( Cec_ManSimCompareEqual( pSim0, pSim1, p->nWords ) )
2009-01-18 17:01:00 +01:00
Vec_IntPush( p->vClassOld, Ent );
else
2009-03-11 16:01:00 +01:00
{
2009-01-18 17:01:00 +01:00
Vec_IntPush( p->vClassNew, Ent );
2009-03-11 16:01:00 +01:00
if ( p->pBestState )
Cec_ManSimCompareEqualScore( pSim0, pSim1, p->nWords, p->pScores );
}
2009-01-18 17:01:00 +01:00
}
2009-02-15 17:01:00 +01:00
if ( Vec_IntSize( p->vClassNew ) == 0 )
2009-01-18 17:01:00 +01:00
return 0;
2009-03-10 16:01:00 +01:00
Cec_ManSimClassCreate( p->pAig, p->vClassOld );
Cec_ManSimClassCreate( p->pAig, p->vClassNew );
2009-01-18 17:01:00 +01:00
if ( Vec_IntSize(p->vClassNew) > 1 )
2009-03-10 16:01:00 +01:00
return 1 + Cec_ManSimClassRefineOne( p, Vec_IntEntry(p->vClassNew,0) );
2009-01-18 17:01:00 +01:00
return 1;
}
2009-03-29 17:01:00 +02:00
/**Function*************************************************************
Synopsis [Refines one equivalence class.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i )
{
int iRepr, Ent;
if ( Gia_ObjIsConst(p->pAig, i) )
{
Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
return 1;
}
if ( !Gia_ObjIsClass(p->pAig, i) )
return 0;
assert( Gia_ObjIsClass(p->pAig, i) );
iRepr = Gia_ObjRepr( p->pAig, i );
if ( iRepr == GIA_VOID )
iRepr = i;
// collect nodes
Vec_IntClear( p->vClassOld );
Vec_IntClear( p->vClassNew );
Gia_ClassForEachObj( p->pAig, iRepr, Ent )
{
if ( Ent == i )
Vec_IntPush( p->vClassNew, Ent );
else
Vec_IntPush( p->vClassOld, Ent );
}
assert( Vec_IntSize( p->vClassNew ) == 1 );
Cec_ManSimClassCreate( p->pAig, p->vClassOld );
Cec_ManSimClassCreate( p->pAig, p->vClassNew );
assert( !Gia_ObjIsClass(p->pAig, i) );
return 1;
}
2009-01-18 17:01:00 +01:00
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Computes hash key of the simuation info.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimHashKey( unsigned * pSim, int nWords, int nTableSize )
2009-01-18 17:01:00 +01:00
{
static int s_Primes[16] = {
1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
unsigned uHash = 0;
int i;
if ( pSim[0] & 1 )
for ( i = 0; i < nWords; i++ )
uHash ^= ~pSim[i] * s_Primes[i & 0xf];
else
for ( i = 0; i < nWords; i++ )
uHash ^= pSim[i] * s_Primes[i & 0xf];
return (int)(uHash % nTableSize);
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Resets pointers to the simulation memory.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
void Cec_ManSimMemRelink( Cec_ManSim_t * p )
2009-02-15 17:01:00 +01:00
{
unsigned * pPlace, Ent;
pPlace = &p->MemFree;
for ( Ent = p->nMems * (p->nWords + 1);
Ent + p->nWords + 1 < (unsigned)p->nWordsAlloc;
Ent += p->nWords + 1 )
{
*pPlace = Ent;
pPlace = p->pMems + Ent;
}
*pPlace = 0;
2009-03-10 16:01:00 +01:00
p->nWordsOld = p->nWords;
2009-02-15 17:01:00 +01:00
}
/**Function*************************************************************
Synopsis [References simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
unsigned * Cec_ManSimSimRef( Cec_ManSim_t * p, int i )
2009-02-15 17:01:00 +01:00
{
unsigned * pSim;
2009-03-10 16:01:00 +01:00
assert( p->pSimInfo[i] == 0 );
2009-02-15 17:01:00 +01:00
if ( p->MemFree == 0 )
2009-01-18 17:01:00 +01:00
{
2009-02-15 17:01:00 +01:00
if ( p->nWordsAlloc == 0 )
2009-01-18 17:01:00 +01:00
{
2009-02-15 17:01:00 +01:00
assert( p->pMems == NULL );
p->nWordsAlloc = (1<<17); // -> 1Mb
p->nMems = 1;
2009-01-18 17:01:00 +01:00
}
2009-02-15 17:01:00 +01:00
p->nWordsAlloc *= 2;
p->pMems = ABC_REALLOC( unsigned, p->pMems, p->nWordsAlloc );
2009-03-10 16:01:00 +01:00
Cec_ManSimMemRelink( p );
2009-01-18 17:01:00 +01:00
}
2009-03-10 16:01:00 +01:00
p->pSimInfo[i] = p->MemFree;
2009-02-15 17:01:00 +01:00
pSim = p->pMems + p->MemFree;
p->MemFree = pSim[0];
pSim[0] = Gia_ObjValue( Gia_ManObj(p->pAig, i) );
p->nMems++;
if ( p->nMemsMax < p->nMems )
p->nMemsMax = p->nMems;
return pSim;
2009-01-18 17:01:00 +01:00
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Dereferences simulaton info.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
unsigned * Cec_ManSimSimDeref( Cec_ManSim_t * p, int i )
2009-01-18 17:01:00 +01:00
{
2009-02-15 17:01:00 +01:00
unsigned * pSim;
2009-03-10 16:01:00 +01:00
assert( p->pSimInfo[i] > 0 );
pSim = p->pMems + p->pSimInfo[i];
2009-02-15 17:01:00 +01:00
if ( --pSim[0] == 0 )
{
pSim[0] = p->MemFree;
2009-03-10 16:01:00 +01:00
p->MemFree = p->pSimInfo[i];
p->pSimInfo[i] = 0;
2009-02-15 17:01:00 +01:00
p->nMems--;
}
return pSim;
2009-01-18 17:01:00 +01:00
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Refines nodes belonging to candidate constant class.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
void Cec_ManSimProcessRefined( Cec_ManSim_t * p, Vec_Int_t * vRefined )
2009-01-18 17:01:00 +01:00
{
unsigned * pSim;
2009-02-15 17:01:00 +01:00
int * pTable, nTableSize, i, k, Key;
2009-01-18 17:01:00 +01:00
if ( Vec_IntSize(vRefined) == 0 )
return;
2009-04-08 17:01:00 +02:00
nTableSize = Gia_PrimeCudd( 100 + Vec_IntSize(vRefined) / 3 );
2009-02-15 17:01:00 +01:00
pTable = ABC_CALLOC( int, nTableSize );
Vec_IntForEachEntry( vRefined, i, k )
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
pSim = Cec_ObjSim( p, i );
assert( !Cec_ManSimCompareConst( pSim, p->nWords ) );
Key = Cec_ManSimHashKey( pSim, p->nWords, nTableSize );
2009-01-18 17:01:00 +01:00
if ( pTable[Key] == 0 )
{
2009-03-10 16:01:00 +01:00
assert( Gia_ObjRepr(p->pAig, i) == 0 );
assert( Gia_ObjNext(p->pAig, i) == 0 );
Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
2009-01-18 17:01:00 +01:00
}
else
{
2009-03-10 16:01:00 +01:00
Gia_ObjSetNext( p->pAig, pTable[Key], i );
Gia_ObjSetRepr( p->pAig, i, Gia_ObjRepr(p->pAig, pTable[Key]) );
if ( Gia_ObjRepr(p->pAig, i) == GIA_VOID )
Gia_ObjSetRepr( p->pAig, i, pTable[Key] );
assert( Gia_ObjRepr(p->pAig, i) > 0 );
2009-01-18 17:01:00 +01:00
}
2009-02-15 17:01:00 +01:00
pTable[Key] = i;
2009-01-18 17:01:00 +01:00
}
2009-02-15 17:01:00 +01:00
Vec_IntForEachEntry( vRefined, i, k )
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
if ( Gia_ObjIsHead( p->pAig, i ) )
Cec_ManSimClassRefineOne( p, i );
2009-02-15 17:01:00 +01:00
}
Vec_IntForEachEntry( vRefined, i, k )
2009-03-10 16:01:00 +01:00
Cec_ManSimSimDeref( p, i );
2009-02-15 17:01:00 +01:00
ABC_FREE( pTable );
}
2009-03-10 16:01:00 +01:00
/**Function*************************************************************
Synopsis [Saves the input pattern with the given number.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManSimSavePattern( Cec_ManSim_t * p, int iPat )
{
unsigned * pInfo;
int i;
assert( p->pCexComb == NULL );
assert( iPat >= 0 && iPat < 32 * p->nWords );
p->pCexComb = (Gia_Cex_t *)ABC_CALLOC( char,
2009-04-08 17:01:00 +02:00
sizeof(Gia_Cex_t) + sizeof(unsigned) * Gia_BitWordNum(Gia_ManCiNum(p->pAig)) );
2009-03-10 16:01:00 +01:00
p->pCexComb->iPo = p->iOut;
p->pCexComb->nPis = Gia_ManCiNum(p->pAig);
p->pCexComb->nBits = Gia_ManCiNum(p->pAig);
for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
{
pInfo = Vec_PtrEntry( p->vCiSimInfo, i );
2009-04-08 17:01:00 +02:00
if ( Gia_InfoHasBit( pInfo, iPat ) )
Gia_InfoSetBit( p->pCexComb->pData, i );
2009-03-10 16:01:00 +01:00
}
}
2009-03-11 16:01:00 +01:00
/**Function*************************************************************
Synopsis [Find the best pattern using the scores.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManSimFindBestPattern( Cec_ManSim_t * p )
2009-03-13 16:01:00 +01:00
{
2009-03-11 16:01:00 +01:00
unsigned * pInfo;
int i, ScoreBest = 0, iPatBest = 1;
// find the best pattern
for ( i = 0; i < 32 * p->nWords; i++ )
if ( ScoreBest < p->pScores[i] )
{
ScoreBest = p->pScores[i];
iPatBest = i;
}
// compare this with the available patterns - and save
if ( p->pBestState->iPo <= ScoreBest )
{
assert( p->pBestState->nRegs == Gia_ManRegNum(p->pAig) );
for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
{
pInfo = Vec_PtrEntry( p->vCiSimInfo, Gia_ManPiNum(p->pAig) + i );
2009-04-08 17:01:00 +02:00
if ( Gia_InfoHasBit(p->pBestState->pData, i) != Gia_InfoHasBit(pInfo, iPatBest) )
Gia_InfoXorBit( p->pBestState->pData, i );
2009-03-11 16:01:00 +01:00
}
p->pBestState->iPo = ScoreBest;
}
}
2009-03-10 16:01:00 +01:00
/**Function*************************************************************
Synopsis [Returns 1 if computation should stop.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cec_ManSimAnalyzeOutputs( Cec_ManSim_t * p )
{
unsigned * pInfo, * pInfo2;
int i;
2009-03-11 16:01:00 +01:00
if ( !p->pPars->fCheckMiter )
2009-03-10 16:01:00 +01:00
return 0;
2009-03-11 16:01:00 +01:00
assert( p->vCoSimInfo != NULL );
2009-03-10 16:01:00 +01:00
// compare outputs with 0
2009-03-11 16:01:00 +01:00
if ( p->pPars->fDualOut )
2009-03-10 16:01:00 +01:00
{
assert( (Gia_ManCoNum(p->pAig) & 1) == 0 );
for ( i = 0; i < Gia_ManCoNum(p->pAig); i++ )
{
pInfo = Vec_PtrEntry( p->vCoSimInfo, i );
pInfo2 = Vec_PtrEntry( p->vCoSimInfo, ++i );
if ( !Cec_ManSimCompareEqual( pInfo, pInfo2, p->nWords ) )
{
if ( p->iOut == -1 )
{
p->iOut = i/2;
Cec_ManSimSavePattern( p, Cec_ManSimCompareEqualFirstBit(pInfo, pInfo2, p->nWords) );
}
if ( p->pCexes == NULL )
p->pCexes = ABC_CALLOC( void *, Gia_ManCoNum(p->pAig)/2 );
if ( p->pCexes[i/2] == NULL )
{
p->nOuts++;
p->pCexes[i/2] = (void *)1;
}
}
}
}
else
{
for ( i = 0; i < Gia_ManCoNum(p->pAig); i++ )
{
pInfo = Vec_PtrEntry( p->vCoSimInfo, i );
if ( !Cec_ManSimCompareConst( pInfo, p->nWords ) )
{
if ( p->iOut == -1 )
{
p->iOut = i;
Cec_ManSimSavePattern( p, Cec_ManSimCompareConstFirstBit(pInfo, p->nWords) );
}
if ( p->pCexes == NULL )
p->pCexes = ABC_CALLOC( void *, Gia_ManCoNum(p->pAig) );
if ( p->pCexes[i] == NULL )
{
p->nOuts++;
p->pCexes[i] = (void *)1;
}
}
}
}
return p->pCexes != NULL && p->pPars->fFirstStop;
}
2009-02-15 17:01:00 +01:00
/**Function*************************************************************
Synopsis [Simulates one round.]
Description [Returns the number of PO entry if failed; 0 otherwise.]
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos )
2009-02-15 17:01:00 +01:00
{
Gia_Obj_t * pObj;
unsigned * pRes0, * pRes1, * pRes;
int i, k, w, Ent, iCiId = 0, iCoId = 0;
2009-03-10 16:01:00 +01:00
// prepare internal storage
if ( p->nWordsOld != p->nWords )
Cec_ManSimMemRelink( p );
2009-02-15 17:01:00 +01:00
p->nMemsMax = 0;
2009-03-11 16:01:00 +01:00
// allocate score counters
ABC_FREE( p->pScores );
if ( p->pBestState )
p->pScores = ABC_CALLOC( int, 32 * p->nWords );
2009-03-10 16:01:00 +01:00
// simulate nodes
2009-02-15 17:01:00 +01:00
Vec_IntClear( p->vRefinedC );
if ( Gia_ObjValue(Gia_ManConst0(p->pAig)) )
{
2009-03-10 16:01:00 +01:00
pRes = Cec_ManSimSimRef( p, 0 );
2009-02-15 17:01:00 +01:00
for ( w = 1; w <= p->nWords; w++ )
pRes[w] = 0;
}
Gia_ManForEachObj1( p->pAig, pObj, i )
{
if ( Gia_ObjIsCi(pObj) )
{
if ( Gia_ObjValue(pObj) == 0 )
{
iCiId++;
continue;
}
2009-03-10 16:01:00 +01:00
pRes = Cec_ManSimSimRef( p, i );
2009-02-15 17:01:00 +01:00
if ( vInfoCis )
{
pRes0 = Vec_PtrEntry( vInfoCis, iCiId++ );
for ( w = 1; w <= p->nWords; w++ )
2009-03-10 16:01:00 +01:00
pRes[w] = pRes0[w-1];
2009-02-15 17:01:00 +01:00
}
else
{
for ( w = 1; w <= p->nWords; w++ )
2009-04-08 17:01:00 +02:00
pRes[w] = Gia_ManRandom( 0 );
2009-02-15 17:01:00 +01:00
}
// make sure the first pattern is always zero
pRes[1] ^= (pRes[1] & 1);
goto references;
}
if ( Gia_ObjIsCo(pObj) ) // co always has non-zero 1st fanin and zero 2nd fanin
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) );
2009-02-15 17:01:00 +01:00
if ( vInfoCos )
{
pRes = Vec_PtrEntry( vInfoCos, iCoId++ );
if ( Gia_ObjFaninC0(pObj) )
for ( w = 1; w <= p->nWords; w++ )
pRes[w-1] = ~pRes0[w];
else
for ( w = 1; w <= p->nWords; w++ )
pRes[w-1] = pRes0[w];
}
2009-01-18 17:01:00 +01:00
continue;
}
2009-02-15 17:01:00 +01:00
assert( Gia_ObjValue(pObj) );
2009-03-10 16:01:00 +01:00
pRes = Cec_ManSimSimRef( p, i );
pRes0 = Cec_ManSimSimDeref( p, Gia_ObjFaninId0(pObj,i) );
pRes1 = Cec_ManSimSimDeref( p, Gia_ObjFaninId1(pObj,i) );
2009-04-13 17:01:00 +02:00
2009-04-24 17:01:00 +02:00
// printf( "%d,%d ", Gia_ObjValue( Gia_ObjFanin0(pObj) ), Gia_ObjValue( Gia_ObjFanin1(pObj) ) );
2009-02-15 17:01:00 +01:00
if ( Gia_ObjFaninC0(pObj) )
{
if ( Gia_ObjFaninC1(pObj) )
for ( w = 1; w <= p->nWords; w++ )
pRes[w] = ~(pRes0[w] | pRes1[w]);
else
for ( w = 1; w <= p->nWords; w++ )
pRes[w] = ~pRes0[w] & pRes1[w];
}
else
{
if ( Gia_ObjFaninC1(pObj) )
for ( w = 1; w <= p->nWords; w++ )
pRes[w] = pRes0[w] & ~pRes1[w];
else
for ( w = 1; w <= p->nWords; w++ )
pRes[w] = pRes0[w] & pRes1[w];
}
2009-04-13 17:01:00 +02:00
2009-02-15 17:01:00 +01:00
references:
// if this node is candidate constant, collect it
2009-03-10 16:01:00 +01:00
if ( Gia_ObjIsConst(p->pAig, i) && !Cec_ManSimCompareConst(pRes + 1, p->nWords) )
2009-02-15 17:01:00 +01:00
{
pRes[0]++;
Vec_IntPush( p->vRefinedC, i );
2009-03-11 16:01:00 +01:00
if ( p->pBestState )
Cec_ManSimCompareConstScore( pRes + 1, p->nWords, p->pScores );
2009-02-15 17:01:00 +01:00
}
// if the node belongs to a class, save it
2009-03-10 16:01:00 +01:00
if ( Gia_ObjIsClass(p->pAig, i) )
2009-02-15 17:01:00 +01:00
pRes[0]++;
// if this is the last node of the class, process it
2009-03-10 16:01:00 +01:00
if ( Gia_ObjIsTail(p->pAig, i) )
2009-02-15 17:01:00 +01:00
{
Vec_IntClear( p->vClassTemp );
2009-03-10 16:01:00 +01:00
Gia_ClassForEachObj( p->pAig, Gia_ObjRepr(p->pAig, i), Ent )
2009-02-15 17:01:00 +01:00
Vec_IntPush( p->vClassTemp, Ent );
2009-03-10 16:01:00 +01:00
Cec_ManSimClassRefineOne( p, Gia_ObjRepr(p->pAig, i) );
2009-02-15 17:01:00 +01:00
Vec_IntForEachEntry( p->vClassTemp, Ent, k )
2009-03-10 16:01:00 +01:00
Cec_ManSimSimDeref( p, Ent );
2009-02-15 17:01:00 +01:00
}
2009-01-18 17:01:00 +01:00
}
2009-02-15 17:01:00 +01:00
if ( Vec_IntSize(p->vRefinedC) > 0 )
2009-03-10 16:01:00 +01:00
Cec_ManSimProcessRefined( p, p->vRefinedC );
2009-02-15 17:01:00 +01:00
assert( vInfoCis == NULL || iCiId == Gia_ManCiNum(p->pAig) );
assert( vInfoCos == NULL || iCoId == Gia_ManCoNum(p->pAig) );
assert( p->nMems == 1 );
2009-03-10 16:01:00 +01:00
if ( p->nMems != 1 )
printf( "Cec_ManSimSimulateRound(): Memory management error!\n" );
2009-02-15 17:01:00 +01:00
if ( p->pPars->fVeryVerbose )
2009-03-10 16:01:00 +01:00
Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
2009-03-11 16:01:00 +01:00
if ( p->pBestState )
Cec_ManSimFindBestPattern( p );
2009-02-15 17:01:00 +01:00
/*
2009-03-10 16:01:00 +01:00
if ( p->nMems > 1 ) {
2009-02-15 17:01:00 +01:00
for ( i = 1; i < p->nObjs; i++ )
2009-03-10 16:01:00 +01:00
if ( p->pSims[i] ) {
2009-02-15 17:01:00 +01:00
int x = 0;
}
}
*/
2009-03-10 16:01:00 +01:00
return Cec_ManSimAnalyzeOutputs( p );
2009-01-18 17:01:00 +01:00
}
2009-03-10 16:01:00 +01:00
2009-01-18 17:01:00 +01:00
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Creates simulation info for this round.]
2009-01-18 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
void Cec_ManSimCreateInfo( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos )
2009-01-18 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
unsigned * pRes0, * pRes1;
int i, w;
if ( p->pPars->fSeqSimulate && Gia_ManRegNum(p->pAig) > 0 )
2009-02-15 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
assert( vInfoCis && vInfoCos );
for ( i = 0; i < Gia_ManPiNum(p->pAig); i++ )
{
pRes0 = Vec_PtrEntry( vInfoCis, i );
for ( w = 0; w < p->nWords; w++ )
2009-04-08 17:01:00 +02:00
pRes0[w] = Gia_ManRandom( 0 );
2009-03-10 16:01:00 +01:00
}
for ( i = 0; i < Gia_ManRegNum(p->pAig); i++ )
{
pRes0 = Vec_PtrEntry( vInfoCis, Gia_ManPiNum(p->pAig) + i );
pRes1 = Vec_PtrEntry( vInfoCos, Gia_ManPoNum(p->pAig) + i );
for ( w = 0; w < p->nWords; w++ )
pRes0[w] = pRes1[w];
}
}
else
{
for ( i = 0; i < Gia_ManCiNum(p->pAig); i++ )
{
pRes0 = Vec_PtrEntry( vInfoCis, i );
for ( w = 0; w < p->nWords; w++ )
2009-04-08 17:01:00 +02:00
pRes0[w] = Gia_ManRandom( 0 );
2009-03-10 16:01:00 +01:00
}
2009-02-15 17:01:00 +01:00
}
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Returns 1 if the bug is found.]
2009-02-15 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimClassesPrepare( Cec_ManSim_t * p )
2009-02-15 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
Gia_Obj_t * pObj;
int i;
assert( p->pAig->pReprs == NULL );
// allocate representation
p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) );
p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) );
2009-04-05 17:01:00 +02:00
// create references
Gia_ManSetRefs( p->pAig );
2009-03-11 16:01:00 +01:00
// set starting representative of internal nodes to be constant 0
2009-03-29 17:01:00 +02:00
if ( p->pPars->fLatchCorr )
Gia_ManForEachObj( p->pAig, pObj, i )
Gia_ObjSetRepr( p->pAig, i, GIA_VOID );
else
Gia_ManForEachObj( p->pAig, pObj, i )
Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID );
2009-03-11 16:01:00 +01:00
// if sequential simulation, set starting representative of ROs to be constant 0
if ( p->pPars->fSeqSimulate )
Gia_ManForEachRo( p->pAig, pObj, i )
2009-04-05 17:01:00 +02:00
if ( pObj->Value )
Gia_ObjSetRepr( p->pAig, Gia_ObjId(p->pAig, pObj), 0 );
2009-03-10 16:01:00 +01:00
// perform simulation
p->nWords = 1;
do {
if ( p->pPars->fVerbose )
Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
for ( i = 0; i < 4; i++ )
{
Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
return 1;
}
p->nWords = 2 * p->nWords + 1;
}
while ( p->nWords <= p->pPars->nWords );
return 0;
2009-02-15 17:01:00 +01:00
}
/**Function*************************************************************
2009-03-10 16:01:00 +01:00
Synopsis [Returns 1 if the bug is found.]
2009-02-15 17:01:00 +01:00
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2009-03-10 16:01:00 +01:00
int Cec_ManSimClassesRefine( Cec_ManSim_t * p )
2009-02-15 17:01:00 +01:00
{
2009-03-10 16:01:00 +01:00
int i;
Gia_ManSetRefs( p->pAig );
p->nWords = p->pPars->nWords;
for ( i = 0; i < p->pPars->nRounds; i++ )
2009-02-15 17:01:00 +01:00
{
2009-03-13 16:01:00 +01:00
if ( (i % (p->pPars->nRounds / 5)) == 0 && p->pPars->fVerbose )
2009-03-10 16:01:00 +01:00
Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
Cec_ManSimCreateInfo( p, p->vCiSimInfo, p->vCoSimInfo );
if ( Cec_ManSimSimulateRound( p, p->vCiSimInfo, p->vCoSimInfo ) )
return 1;
2009-02-15 17:01:00 +01:00
}
2009-03-10 16:01:00 +01:00
if ( p->pPars->fVerbose )
Gia_ManEquivPrintClasses( p->pAig, 0, Cec_MemUsage(p) );
2009-02-15 17:01:00 +01:00
return 0;
2009-01-18 17:01:00 +01:00
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////