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