/**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