mirror of https://github.com/YosysHQ/abc.git
267 lines
7.4 KiB
C
267 lines
7.4 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [aigTable.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Minimalistic And-Inverter Graph package.]
|
|
|
|
Synopsis [Structural hashing table.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - May 11, 2006. ]
|
|
|
|
Revision [$Id: aigTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "aig.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// hashing the node
|
|
static unsigned long Aig_Hash( Aig_Obj_t * pObj, int TableSize )
|
|
{
|
|
unsigned long Key = Aig_ObjIsExor(pObj) * 1699;
|
|
Key ^= (long)Aig_ObjFanin0(pObj) * 7937;
|
|
Key ^= (long)Aig_ObjFanin1(pObj) * 2971;
|
|
Key ^= Aig_ObjFaninC0(pObj) * 911;
|
|
Key ^= Aig_ObjFaninC1(pObj) * 353;
|
|
return Key % TableSize;
|
|
}
|
|
|
|
// returns the place where this node is stored (or should be stored)
|
|
static Aig_Obj_t ** Aig_TableFind( Aig_Man_t * p, Aig_Obj_t * pObj )
|
|
{
|
|
int i;
|
|
assert( Aig_ObjChild0(pObj) && Aig_ObjChild1(pObj) );
|
|
assert( Aig_ObjChild0(pObj) < Aig_ObjChild1(pObj) );
|
|
for ( i = Aig_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
|
|
if ( p->pTable[i] == pObj )
|
|
break;
|
|
return p->pTable + i;
|
|
}
|
|
|
|
static void Aig_TableResize( Aig_Man_t * p );
|
|
static unsigned int Cudd_PrimeAig( unsigned int p );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Checks if node with the given attributes is in the hash table.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost )
|
|
{
|
|
int i;
|
|
assert( !Aig_IsComplement(pGhost) );
|
|
assert( Aig_ObjChild0(pGhost) && Aig_ObjChild1(pGhost) );
|
|
assert( Aig_ObjChild0(pGhost) < Aig_ObjChild1(pGhost) );
|
|
if ( p->fRefCount && (!Aig_ObjRefs(Aig_ObjFanin0(pGhost)) || !Aig_ObjRefs(Aig_ObjFanin1(pGhost))) )
|
|
return NULL;
|
|
for ( i = Aig_Hash(pGhost, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
|
|
{
|
|
if ( Aig_ObjChild0(p->pTable[i]) == Aig_ObjChild0(pGhost) &&
|
|
Aig_ObjChild1(p->pTable[i]) == Aig_ObjChild1(pGhost) &&
|
|
Aig_ObjType(p->pTable[i]) == Aig_ObjType(pGhost) )
|
|
return p->pTable[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Adds the new node to the hash table.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Aig_TableInsert( Aig_Man_t * p, Aig_Obj_t * pObj )
|
|
{
|
|
Aig_Obj_t ** ppPlace;
|
|
assert( !Aig_IsComplement(pObj) );
|
|
assert( Aig_TableLookup(p, pObj) == NULL );
|
|
if ( p->nTableSize < 2 * Aig_ManNodeNum(p) )
|
|
Aig_TableResize( p );
|
|
ppPlace = Aig_TableFind( p, pObj );
|
|
assert( *ppPlace == NULL );
|
|
*ppPlace = pObj;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Deletes the node from the hash table.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Aig_TableDelete( Aig_Man_t * p, Aig_Obj_t * pObj )
|
|
{
|
|
Aig_Obj_t * pEntry, ** ppPlace;
|
|
int i;
|
|
assert( !Aig_IsComplement(pObj) );
|
|
ppPlace = Aig_TableFind( p, pObj );
|
|
assert( *ppPlace == pObj ); // node should be in the table
|
|
*ppPlace = NULL;
|
|
// rehash the adjacent entries
|
|
i = ppPlace - p->pTable;
|
|
for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize )
|
|
{
|
|
pEntry = p->pTable[i];
|
|
p->pTable[i] = 0;
|
|
Aig_TableInsert( p, pEntry );
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Count the number of nodes in the table.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Aig_TableCountEntries( Aig_Man_t * p )
|
|
{
|
|
int i, Counter = 0;
|
|
for ( i = 0; i < p->nTableSize; i++ )
|
|
Counter += (p->pTable[i] != NULL);
|
|
return Counter;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Resizes the table.]
|
|
|
|
Description [Typically this procedure should not be called.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Aig_TableResize( Aig_Man_t * p )
|
|
{
|
|
Aig_Obj_t ** pTableOld, ** ppPlace;
|
|
int nTableSizeOld, Counter, nEntries, e, clk;
|
|
clk = clock();
|
|
// save the old table
|
|
pTableOld = p->pTable;
|
|
nTableSizeOld = p->nTableSize;
|
|
// get the new table
|
|
p->nTableSize = Cudd_PrimeAig( 5 * Aig_ManNodeNum(p) );
|
|
p->pTable = ALLOC( Aig_Obj_t *, p->nTableSize );
|
|
memset( p->pTable, 0, sizeof(Aig_Obj_t *) * p->nTableSize );
|
|
// rehash the entries from the old table
|
|
Counter = 0;
|
|
for ( e = 0; e < nTableSizeOld; e++ )
|
|
{
|
|
if ( pTableOld[e] == 0 )
|
|
continue;
|
|
Counter++;
|
|
// get the place where this entry goes in the table table
|
|
ppPlace = Aig_TableFind( p, pTableOld[e] );
|
|
assert( *ppPlace == NULL ); // should not be in the table
|
|
*ppPlace = pTableOld[e];
|
|
}
|
|
nEntries = Aig_ManNodeNum(p);
|
|
// assert( Counter == nEntries );
|
|
// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
|
|
// PRT( "Time", clock() - clk );
|
|
// replace the table and the parameters
|
|
free( pTableOld );
|
|
}
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Profiles the hash table.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
******************************************************************************/
|
|
void Aig_TableProfile( Aig_Man_t * p )
|
|
{
|
|
int i, Counter = 0;
|
|
for ( i = 0; i < p->nTableSize; i++ )
|
|
{
|
|
if ( p->pTable[i] )
|
|
Counter++;
|
|
else if ( Counter )
|
|
{
|
|
printf( "%d ", Counter );
|
|
Counter = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**Function********************************************************************
|
|
|
|
Synopsis [Returns the next prime >= p.]
|
|
|
|
Description [Copied from CUDD, for stand-aloneness.]
|
|
|
|
SideEffects [None]
|
|
|
|
SeeAlso []
|
|
|
|
******************************************************************************/
|
|
unsigned int Cudd_PrimeAig( unsigned int p)
|
|
{
|
|
int i,pn;
|
|
|
|
p--;
|
|
do {
|
|
p++;
|
|
if (p&1) {
|
|
pn = 1;
|
|
i = 3;
|
|
while ((unsigned) (i * i) <= p) {
|
|
if (p % i == 0) {
|
|
pn = 0;
|
|
break;
|
|
}
|
|
i += 2;
|
|
}
|
|
} else {
|
|
pn = 0;
|
|
}
|
|
} while (!pn);
|
|
return(p);
|
|
|
|
} /* end of Cudd_Prime */
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|