mirror of https://github.com/YosysHQ/abc.git
311 lines
9.9 KiB
C
311 lines
9.9 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [sbdSim.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [SAT-based optimization using internal don't-cares.]
|
|
|
|
Synopsis [Simulation.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: sbdSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "sbdInt.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
static inline word * Sbd_ObjSims( Gia_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims, p->iPatsPi * i ); }
|
|
static inline word * Sbd_ObjCtrl( Gia_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSimsPi, p->iPatsPi * i ); }
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [This does not work.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Sbd_GiaSimRoundBack2( Gia_Man_t * p )
|
|
{
|
|
int nWords = p->iPatsPi;
|
|
Gia_Obj_t * pObj;
|
|
int w, i, Id;
|
|
// init primary outputs
|
|
Gia_ManForEachCoId( p, Id, i )
|
|
for ( w = 0; w < nWords; w++ )
|
|
Sbd_ObjSims(p, Id)[w] = Gia_ManRandomW(0);
|
|
// transfer to nodes
|
|
Gia_ManForEachCo( p, pObj, i )
|
|
{
|
|
word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj));
|
|
Abc_TtCopy( Sbd_ObjSims(p, Gia_ObjFaninId0p(p, pObj)), pSims, nWords, Gia_ObjFaninC0(pObj) );
|
|
}
|
|
// simulate nodes
|
|
Gia_ManForEachAndReverse( p, pObj, i )
|
|
{
|
|
word * pSims = Sbd_ObjSims(p, i);
|
|
word * pSims0 = Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i));
|
|
word * pSims1 = Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i));
|
|
word Rand = Gia_ManRandomW(0);
|
|
for ( w = 0; w < nWords; w++ )
|
|
{
|
|
pSims0[w] = pSims[w] | Rand;
|
|
pSims1[w] = pSims[w] | ~Rand;
|
|
}
|
|
if ( Gia_ObjFaninC0(pObj) ) Abc_TtNot( pSims0, nWords );
|
|
if ( Gia_ObjFaninC1(pObj) ) Abc_TtNot( pSims1, nWords );
|
|
}
|
|
// primary inputs are initialized
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Tries to falsify a sequence of two-literal SAT problems.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Sbd_GiaSatOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, int fFirst, int iPat )
|
|
{
|
|
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
|
return (int)pObj->fMark0 == Value;
|
|
Gia_ObjSetTravIdCurrent(p, pObj);
|
|
pObj->fMark0 = Value;
|
|
if ( Gia_ObjIsCi(pObj) )
|
|
{
|
|
word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj));
|
|
if ( Abc_TtGetBit( pSims, iPat ) != Value )
|
|
Abc_TtXorBit( pSims, iPat );
|
|
return 1;
|
|
}
|
|
assert( Gia_ObjIsAnd(pObj) );
|
|
assert( !Gia_ObjIsXor(pObj) );
|
|
if ( Value )
|
|
return Sbd_GiaSatOne_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), fFirst, iPat ) &&
|
|
Sbd_GiaSatOne_rec( p, Gia_ObjFanin1(pObj), !Gia_ObjFaninC1(pObj), fFirst, iPat );
|
|
if ( fFirst )
|
|
return Sbd_GiaSatOne_rec( p, Gia_ObjFanin0(pObj), Gia_ObjFaninC0(pObj), fFirst, iPat );
|
|
else
|
|
return Sbd_GiaSatOne_rec( p, Gia_ObjFanin1(pObj), Gia_ObjFaninC1(pObj), fFirst, iPat );
|
|
}
|
|
int Sbd_GiaSatOne( Gia_Man_t * p, Vec_Int_t * vPairs )
|
|
{
|
|
int k, n, Var1, Var2, iPat = 0;
|
|
//Gia_ManSetPhase( p );
|
|
Vec_IntForEachEntryDouble( vPairs, Var1, Var2, k )
|
|
{
|
|
Gia_Obj_t * pObj1 = Gia_ManObj( p, Var1 );
|
|
Gia_Obj_t * pObj2 = Gia_ManObj( p, Var2 );
|
|
assert( Var2 > 0 );
|
|
if ( Var1 == 0 )
|
|
{
|
|
for ( n = 0; n < 2; n++ )
|
|
{
|
|
Gia_ManIncrementTravId( p );
|
|
if ( Sbd_GiaSatOne_rec(p, pObj2, !pObj2->fPhase, n, iPat) )
|
|
{
|
|
iPat++;
|
|
break;
|
|
}
|
|
}
|
|
printf( "%c", n == 2 ? '.' : 'c' );
|
|
}
|
|
else
|
|
{
|
|
for ( n = 0; n < 2; n++ )
|
|
{
|
|
Gia_ManIncrementTravId( p );
|
|
if ( Sbd_GiaSatOne_rec(p, pObj1, !pObj1->fPhase, n, iPat) && Sbd_GiaSatOne_rec(p, pObj2, pObj2->fPhase, n, iPat) )
|
|
{
|
|
iPat++;
|
|
break;
|
|
}
|
|
Gia_ManIncrementTravId( p );
|
|
if ( Sbd_GiaSatOne_rec(p, pObj1, pObj1->fPhase, n, iPat) && Sbd_GiaSatOne_rec(p, pObj2, !pObj2->fPhase, n, iPat) )
|
|
{
|
|
iPat++;
|
|
break;
|
|
}
|
|
}
|
|
printf( "%c", n == 2 ? '.' : 'e' );
|
|
}
|
|
if ( iPat == 64 * p->iPatsPi - 1 )
|
|
break;
|
|
}
|
|
printf( "\n" );
|
|
return iPat;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Sbd_GiaSimRoundBack( Gia_Man_t * p )
|
|
{
|
|
extern void Sbd_GiaSimRound( Gia_Man_t * p, int fTry, Vec_Int_t ** pvMap );
|
|
Vec_Int_t * vReprs = Vec_IntStart( Gia_ManObjNum(p) );
|
|
Vec_Int_t * vPairs = Vec_IntAlloc( 1000 );
|
|
Vec_Int_t * vMap; // maps each node into its class
|
|
int i, nConsts = 0, nClasses = 0, nPats;
|
|
Sbd_GiaSimRound( p, 0, &vMap );
|
|
Gia_ManForEachAndId( p, i )
|
|
{
|
|
if ( Vec_IntEntry(vMap, i) == 0 )
|
|
Vec_IntPushTwo( vPairs, 0, i ), nConsts++;
|
|
else if ( Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)) == 0 )
|
|
Vec_IntWriteEntry( vReprs, Vec_IntEntry(vMap, i), i );
|
|
else if ( Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)) != -1 )
|
|
{
|
|
Vec_IntPushTwo( vPairs, Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)), i );
|
|
Vec_IntWriteEntry( vReprs, Vec_IntEntry(vMap, i), -1 );
|
|
nClasses++;
|
|
}
|
|
}
|
|
Vec_IntFree( vMap );
|
|
Vec_IntFree( vReprs );
|
|
printf( "Constants = %d. Classes = %d.\n", nConsts, nClasses );
|
|
|
|
nPats = Sbd_GiaSatOne( p, vPairs );
|
|
Vec_IntFree( vPairs );
|
|
|
|
printf( "Generated %d patterns.\n", nPats );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Sbd_GiaSimRound( Gia_Man_t * p, int fTry, Vec_Int_t ** pvMap )
|
|
{
|
|
int nWords = p->iPatsPi;
|
|
Vec_Mem_t * vStore;
|
|
Gia_Obj_t * pObj;
|
|
Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) );
|
|
int w, i, Id, fCompl, RetValue;
|
|
// init primary inputs
|
|
if ( fTry )
|
|
{
|
|
Sbd_GiaSimRoundBack( p );
|
|
Gia_ManForEachCiId( p, Id, i )
|
|
Sbd_ObjSims(p, Id)[0] <<= 1;
|
|
}
|
|
else
|
|
{
|
|
Gia_ManForEachCiId( p, Id, i )
|
|
for ( w = 0; w < nWords; w++ )
|
|
Sbd_ObjSims(p, Id)[w] = Gia_ManRandomW(0) << !w;
|
|
}
|
|
// simulate internal nodes
|
|
vStore = Vec_MemAlloc( nWords, 16 ); // 2^12 N-word entries per page
|
|
Vec_MemHashAlloc( vStore, 1 << 16 );
|
|
RetValue = Vec_MemHashInsert( vStore, Sbd_ObjSims(p, 0) ); // const zero
|
|
assert( RetValue == 0 );
|
|
Gia_ManForEachAnd( p, pObj, i )
|
|
{
|
|
word * pSims = Sbd_ObjSims(p, i);
|
|
if ( Gia_ObjIsXor(pObj) )
|
|
Abc_TtXor( pSims,
|
|
Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i)),
|
|
Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i)),
|
|
nWords,
|
|
Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pObj) );
|
|
else
|
|
Abc_TtAndCompl( pSims,
|
|
Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i)), Gia_ObjFaninC0(pObj),
|
|
Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i)), Gia_ObjFaninC1(pObj),
|
|
nWords );
|
|
// hash sim info
|
|
fCompl = (int)(pSims[0] & 1);
|
|
if ( fCompl ) Abc_TtNot( pSims, nWords );
|
|
Vec_IntWriteEntry( vMap, i, Vec_MemHashInsert(vStore, pSims) );
|
|
if ( fCompl ) Abc_TtNot( pSims, nWords );
|
|
}
|
|
Gia_ManForEachCo( p, pObj, i )
|
|
{
|
|
word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj));
|
|
Abc_TtCopy( pSims, Sbd_ObjSims(p, Gia_ObjFaninId0p(p, pObj)), nWords, Gia_ObjFaninC0(pObj) );
|
|
// printf( "%d ", Abc_TtCountOnesVec(pSims, nWords) );
|
|
assert( Gia_ObjPhase(pObj) == (int)(pSims[0] & 1) );
|
|
}
|
|
// printf( "\n" );
|
|
Vec_MemHashFree( vStore );
|
|
Vec_MemFree( vStore );
|
|
printf( "Objects = %6d. Unique = %6d.\n", Gia_ManAndNum(p), Vec_IntCountUnique(vMap) );
|
|
if ( pvMap )
|
|
*pvMap = vMap;
|
|
else
|
|
Vec_IntFree( vMap );
|
|
}
|
|
void Sbd_GiaSimTest( Gia_Man_t * pGia )
|
|
{
|
|
Gia_ManSetPhase( pGia );
|
|
|
|
// allocate simulation info
|
|
pGia->iPatsPi = 32;
|
|
pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * pGia->iPatsPi );
|
|
pGia->vSimsPi = Vec_WrdStart( Gia_ManObjNum(pGia) * pGia->iPatsPi );
|
|
|
|
Gia_ManRandom( 1 );
|
|
|
|
Sbd_GiaSimRound( pGia, 0, NULL );
|
|
Sbd_GiaSimRound( pGia, 0, NULL );
|
|
Sbd_GiaSimRound( pGia, 0, NULL );
|
|
|
|
printf( "\n" );
|
|
Sbd_GiaSimRound( pGia, 1, NULL );
|
|
printf( "\n" );
|
|
Sbd_GiaSimRound( pGia, 1, NULL );
|
|
printf( "\n" );
|
|
Sbd_GiaSimRound( pGia, 1, NULL );
|
|
|
|
Vec_WrdFreeP( &pGia->vSims );
|
|
Vec_WrdFreeP( &pGia->vSimsPi );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|