mirror of https://github.com/YosysHQ/abc.git
300 lines
8.6 KiB
C
300 lines
8.6 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [satTruth.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [SAT solver.]
|
|
|
|
Synopsis [Truth table computation package.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: satTruth.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "satTruth.h"
|
|
#include "misc/vec/vecSet.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
struct Tru_Man_t_
|
|
{
|
|
int nVars; // the number of variables
|
|
int nWords; // the number of words in the truth table
|
|
int nEntrySize; // the size of one entry in 'int'
|
|
int nTableSize; // hash table size
|
|
int * pTable; // hash table
|
|
Vec_Set_t * pMem; // memory for truth tables
|
|
word * pZero; // temporary truth table
|
|
int hIthVars[16]; // variable handles
|
|
int nTableLookups;
|
|
};
|
|
|
|
typedef struct Tru_One_t_ Tru_One_t; // 16 bytes minimum
|
|
struct Tru_One_t_
|
|
{
|
|
int Handle; // support
|
|
int Next; // next one in the table
|
|
word pTruth[0]; // truth table
|
|
};
|
|
|
|
static inline Tru_One_t * Tru_ManReadOne( Tru_Man_t * p, int h ) { return h ? (Tru_One_t *)Vec_SetEntry(p->pMem, h) : NULL; }
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the hash key.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline unsigned Tru_ManHash( word * pTruth, int nWords, int nBins, int * pPrimes )
|
|
{
|
|
int i;
|
|
unsigned uHash = 0;
|
|
for ( i = 0; i < nWords; i++ )
|
|
uHash ^= pTruth[i] * pPrimes[i & 0x7];
|
|
return uHash % nBins;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the given record.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int * Tru_ManLookup( Tru_Man_t * p, word * pTruth )
|
|
{
|
|
static int s_Primes[10] = { 1291, 1699, 2357, 4177, 5147, 5647, 6343, 7103, 7873, 8147 };
|
|
Tru_One_t * pEntry;
|
|
int * pSpot;
|
|
assert( (pTruth[0] & 1) == 0 );
|
|
pSpot = p->pTable + Tru_ManHash( pTruth, p->nWords, p->nTableSize, s_Primes );
|
|
for ( pEntry = Tru_ManReadOne(p, *pSpot); pEntry; pSpot = &pEntry->Next, pEntry = Tru_ManReadOne(p, *pSpot) )
|
|
if ( Tru_ManEqual(pEntry->pTruth, pTruth, p->nWords) )
|
|
return pSpot;
|
|
return pSpot;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the given record.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Tru_ManResize( Tru_Man_t * p )
|
|
{
|
|
Tru_One_t * pThis;
|
|
int * pTableOld, * pSpot;
|
|
int nTableSizeOld, iNext, Counter, i;
|
|
assert( p->pTable != NULL );
|
|
// replace the table
|
|
pTableOld = p->pTable;
|
|
nTableSizeOld = p->nTableSize;
|
|
p->nTableSize = 2 * p->nTableSize + 1;
|
|
p->pTable = ABC_CALLOC( int, p->nTableSize );
|
|
// rehash the entries from the old table
|
|
Counter = 0;
|
|
for ( i = 0; i < nTableSizeOld; i++ )
|
|
for ( pThis = Tru_ManReadOne(p, pTableOld[i]),
|
|
iNext = (pThis? pThis->Next : 0);
|
|
pThis; pThis = Tru_ManReadOne(p, iNext),
|
|
iNext = (pThis? pThis->Next : 0) )
|
|
{
|
|
assert( pThis->Handle );
|
|
pThis->Next = 0;
|
|
pSpot = Tru_ManLookup( p, pThis->pTruth );
|
|
assert( *pSpot == 0 ); // should not be there
|
|
*pSpot = pThis->Handle;
|
|
Counter++;
|
|
}
|
|
assert( Counter == Vec_SetEntryNum(p->pMem) );
|
|
ABC_FREE( pTableOld );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Adds entry to the hash table.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Tru_ManInsert( Tru_Man_t * p, word * pTruth )
|
|
{
|
|
int fCompl, * pSpot;
|
|
if ( Tru_ManEqual0(pTruth, p->nWords) )
|
|
return 0;
|
|
if ( Tru_ManEqual1(pTruth, p->nWords) )
|
|
return 1;
|
|
p->nTableLookups++;
|
|
if ( Vec_SetEntryNum(p->pMem) > 2 * p->nTableSize )
|
|
Tru_ManResize( p );
|
|
fCompl = pTruth[0] & 1;
|
|
if ( fCompl )
|
|
Tru_ManNot( pTruth, p->nWords );
|
|
pSpot = Tru_ManLookup( p, pTruth );
|
|
if ( *pSpot == 0 )
|
|
{
|
|
Tru_One_t * pEntry;
|
|
*pSpot = Vec_SetAppend( p->pMem, NULL, p->nEntrySize );
|
|
assert( (*pSpot & 1) == 0 );
|
|
pEntry = Tru_ManReadOne( p, *pSpot );
|
|
Tru_ManCopy( pEntry->pTruth, pTruth, p->nWords );
|
|
pEntry->Handle = *pSpot;
|
|
pEntry->Next = 0;
|
|
}
|
|
if ( fCompl )
|
|
Tru_ManNot( pTruth, p->nWords );
|
|
return *pSpot ^ fCompl;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Start the truth table logging.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Tru_Man_t * Tru_ManAlloc( int nVars )
|
|
{
|
|
word Masks[6] =
|
|
{
|
|
ABC_CONST(0xAAAAAAAAAAAAAAAA),
|
|
ABC_CONST(0xCCCCCCCCCCCCCCCC),
|
|
ABC_CONST(0xF0F0F0F0F0F0F0F0),
|
|
ABC_CONST(0xFF00FF00FF00FF00),
|
|
ABC_CONST(0xFFFF0000FFFF0000),
|
|
ABC_CONST(0xFFFFFFFF00000000)
|
|
};
|
|
Tru_Man_t * p;
|
|
int i, w;
|
|
assert( nVars > 0 && nVars <= 16 );
|
|
p = ABC_CALLOC( Tru_Man_t, 1 );
|
|
p->nVars = nVars;
|
|
p->nWords = (nVars < 6) ? 1 : (1 << (nVars-6));
|
|
p->nEntrySize = (sizeof(Tru_One_t) + p->nWords * sizeof(word))/sizeof(int);
|
|
p->nTableSize = 8147;
|
|
p->pTable = ABC_CALLOC( int, p->nTableSize );
|
|
p->pMem = Vec_SetAlloc( 16 );
|
|
// initialize truth tables
|
|
p->pZero = ABC_ALLOC( word, p->nWords );
|
|
for ( i = 0; i < nVars; i++ )
|
|
{
|
|
for ( w = 0; w < p->nWords; w++ )
|
|
if ( i < 6 )
|
|
p->pZero[w] = Masks[i];
|
|
else if ( w & (1 << (i-6)) )
|
|
p->pZero[w] = ~(word)0;
|
|
else
|
|
p->pZero[w] = 0;
|
|
p->hIthVars[i] = Tru_ManInsert( p, p->pZero );
|
|
assert( !i || p->hIthVars[i] > p->hIthVars[i-1] );
|
|
}
|
|
Tru_ManClear( p->pZero, p->nWords );
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Stop the truth table logging.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Tru_ManFree( Tru_Man_t * p )
|
|
{
|
|
printf( "Lookups = %d. Entries = %d.\n", p->nTableLookups, Vec_SetEntryNum(p->pMem) );
|
|
Vec_SetFree( p->pMem );
|
|
ABC_FREE( p->pZero );
|
|
ABC_FREE( p->pTable );
|
|
ABC_FREE( p );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns elementary variable.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
word * Tru_ManVar( Tru_Man_t * p, int v )
|
|
{
|
|
assert( v >= 0 && v < p->nVars );
|
|
return Tru_ManReadOne( p, p->hIthVars[v] )->pTruth;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns stored truth table]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
word * Tru_ManFunc( Tru_Man_t * p, int h )
|
|
{
|
|
assert( (h & 1) == 0 );
|
|
if ( h == 0 )
|
|
return p->pZero;
|
|
return Tru_ManReadOne( p, h )->pTruth;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|