mirror of https://github.com/YosysHQ/abc.git
318 lines
9.0 KiB
C
318 lines
9.0 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [amapUniq.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Technology mapper for standard cells.]
|
|
|
|
Synopsis [Checks if the structural node already exists.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: amapUniq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "amapInt.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Checks if the entry exists and returns value.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Vec_IntCheckWithMask( Vec_Int_t * p, int Entry )
|
|
{
|
|
int i;
|
|
for ( i = 0; i < p->nSize; i++ )
|
|
if ( (0xffff & p->pArray[i]) == (0xffff & Entry) )
|
|
return p->pArray[i] >> 16;
|
|
return -1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Pushes entry in the natural order.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_IntPushOrderWithMask( Vec_Int_t * p, int Entry )
|
|
{
|
|
int i;
|
|
if ( p->nSize == p->nCap )
|
|
Vec_IntGrow( p, 2 * p->nCap );
|
|
p->nSize++;
|
|
for ( i = p->nSize-2; i >= 0; i-- )
|
|
if ( (0xffff & p->pArray[i]) > (0xffff & Entry) )
|
|
p->pArray[i+1] = p->pArray[i];
|
|
else
|
|
break;
|
|
p->pArray[i+1] = Entry;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Amap_LibFindNode( Amap_Lib_t * pLib, int iFan0, int iFan1, int fXor )
|
|
{
|
|
if ( fXor )
|
|
return Vec_IntCheckWithMask( (Vec_Int_t *)Vec_PtrEntry(pLib->vRulesX, iFan0), iFan1 );
|
|
else
|
|
return Vec_IntCheckWithMask( (Vec_Int_t *)Vec_PtrEntry(pLib->vRules, iFan0), iFan1 );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Checks if the three-argument rule exist.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Amap_LibFindMux( Amap_Lib_t * p, int iFan0, int iFan1, int iFan2 )
|
|
{
|
|
int x;
|
|
for ( x = 0; x < Vec_IntSize(p->vRules3); x += 4 )
|
|
{
|
|
if ( Vec_IntEntry(p->vRules3, x) == iFan0 &&
|
|
Vec_IntEntry(p->vRules3, x+1) == iFan1 &&
|
|
Vec_IntEntry(p->vRules3, x+2) == iFan2 )
|
|
{
|
|
return Vec_IntEntry(p->vRules3, x+3);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Creates a new node.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Amap_Nod_t * Amap_LibCreateObj( Amap_Lib_t * p )
|
|
{
|
|
Amap_Nod_t * pNode;
|
|
if ( p->nNodes == p->nNodesAlloc )
|
|
{
|
|
p->pNodes = ABC_REALLOC( Amap_Nod_t, p->pNodes, 2*p->nNodesAlloc );
|
|
p->nNodesAlloc *= 2;
|
|
}
|
|
pNode = Amap_LibNod( p, p->nNodes );
|
|
memset( pNode, 0, sizeof(Amap_Nod_t) );
|
|
pNode->Id = p->nNodes++;
|
|
Vec_PtrPush( p->vRules, Vec_IntAlloc(8) );
|
|
Vec_PtrPush( p->vRules, Vec_IntAlloc(8) );
|
|
Vec_PtrPush( p->vRulesX, Vec_IntAlloc(8) );
|
|
Vec_PtrPush( p->vRulesX, Vec_IntAlloc(8) );
|
|
return pNode;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Creates a new node.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Amap_LibCreateVar( Amap_Lib_t * p )
|
|
{
|
|
Amap_Nod_t * pNode;
|
|
// start the manager
|
|
assert( p->pNodes == NULL );
|
|
p->nNodesAlloc = 256;
|
|
p->pNodes = ABC_ALLOC( Amap_Nod_t, p->nNodesAlloc );
|
|
// create the first node
|
|
pNode = Amap_LibCreateObj( p );
|
|
p->pNodes->Type = AMAP_OBJ_PI;
|
|
p->pNodes->nSuppSize = 1;
|
|
return 0;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Creates a new node.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Amap_LibCreateNode( Amap_Lib_t * p, int iFan0, int iFan1, int fXor )
|
|
{
|
|
Amap_Nod_t * pNode;
|
|
int iFan;
|
|
if ( iFan0 < iFan1 )
|
|
{
|
|
iFan = iFan0;
|
|
iFan0 = iFan1;
|
|
iFan1 = iFan;
|
|
}
|
|
pNode = Amap_LibCreateObj( p );
|
|
pNode->Type = fXor? AMAP_OBJ_XOR : AMAP_OBJ_AND;
|
|
pNode->nSuppSize = p->pNodes[Abc_Lit2Var(iFan0)].nSuppSize + p->pNodes[Abc_Lit2Var(iFan1)].nSuppSize;
|
|
pNode->iFan0 = iFan0;
|
|
pNode->iFan1 = iFan1;
|
|
if ( p->fVerbose )
|
|
printf( "Creating node %5d %c : iFan0 = %5d%c iFan1 = %5d%c\n",
|
|
pNode->Id, (fXor?'x':' '),
|
|
Abc_Lit2Var(iFan0), (Abc_LitIsCompl(iFan0)?'-':'+'),
|
|
Abc_Lit2Var(iFan1), (Abc_LitIsCompl(iFan1)?'-':'+') );
|
|
|
|
if ( fXor )
|
|
{
|
|
if ( iFan0 == iFan1 )
|
|
Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRulesX, iFan0), (pNode->Id << 16) | iFan1 );
|
|
else
|
|
{
|
|
Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRulesX, iFan0), (pNode->Id << 16) | iFan1 );
|
|
Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRulesX, iFan1), (pNode->Id << 16) | iFan0 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( iFan0 == iFan1 )
|
|
Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRules, iFan0), (pNode->Id << 16) | iFan1 );
|
|
else
|
|
{
|
|
Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRules, iFan0), (pNode->Id << 16) | iFan1 );
|
|
Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRules, iFan1), (pNode->Id << 16) | iFan0 );
|
|
}
|
|
}
|
|
return pNode->Id;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Creates a new node.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Amap_LibCreateMux( Amap_Lib_t * p, int iFan0, int iFan1, int iFan2 )
|
|
{
|
|
Amap_Nod_t * pNode;
|
|
pNode = Amap_LibCreateObj( p );
|
|
pNode->Type = AMAP_OBJ_MUX;
|
|
pNode->nSuppSize = p->pNodes[Abc_Lit2Var(iFan0)].nSuppSize + p->pNodes[Abc_Lit2Var(iFan1)].nSuppSize + p->pNodes[Abc_Lit2Var(iFan2)].nSuppSize;
|
|
pNode->iFan0 = iFan0;
|
|
pNode->iFan1 = iFan1;
|
|
pNode->iFan2 = iFan2;
|
|
if ( p->fVerbose )
|
|
printf( "Creating node %5d %c : iFan0 = %5d%c iFan1 = %5d%c iFan2 = %5d%c\n",
|
|
pNode->Id, 'm',
|
|
Abc_Lit2Var(iFan0), (Abc_LitIsCompl(iFan0)?'-':'+'),
|
|
Abc_Lit2Var(iFan1), (Abc_LitIsCompl(iFan1)?'-':'+'),
|
|
Abc_Lit2Var(iFan2), (Abc_LitIsCompl(iFan2)?'-':'+') );
|
|
|
|
Vec_IntPush( p->vRules3, iFan0 );
|
|
Vec_IntPush( p->vRules3, iFan1 );
|
|
Vec_IntPush( p->vRules3, iFan2 );
|
|
Vec_IntPush( p->vRules3, pNode->Id );
|
|
return pNode->Id;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Allocates triangular lookup table.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int ** Amap_LibLookupTableAlloc( Vec_Ptr_t * vVec, int fVerbose )
|
|
{
|
|
Vec_Int_t * vOne;
|
|
int ** pRes, * pBuffer;
|
|
int i, k, nTotal, nSize, nEntries, Value;
|
|
// count the total size
|
|
nEntries = nSize = Vec_PtrSize( vVec );
|
|
Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i )
|
|
nEntries += Vec_IntSize(vOne);
|
|
pBuffer = ABC_ALLOC( int, nSize * sizeof(void *) + nEntries );
|
|
pRes = (int **)pBuffer;
|
|
pRes[0] = pBuffer + nSize * sizeof(void *);
|
|
nTotal = 0;
|
|
Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i )
|
|
{
|
|
pRes[i] = pRes[0] + nTotal;
|
|
nTotal += Vec_IntSize(vOne) + 1;
|
|
if ( fVerbose )
|
|
printf( "%d : ", i );
|
|
Vec_IntForEachEntry( vOne, Value, k )
|
|
{
|
|
pRes[i][k] = Value;
|
|
if ( fVerbose )
|
|
printf( "%d(%d) ", Value&0xffff, Value>>16 );
|
|
}
|
|
if ( fVerbose )
|
|
printf( "\n" );
|
|
pRes[i][k] = 0;
|
|
}
|
|
assert( nTotal == nEntries );
|
|
return pRes;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|