From e0616441b3f42131bc2f9cf307ef4e44b29781a7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 12 Feb 2016 09:46:49 -0800 Subject: Adding support for a different bit-blasting of a multiplier and squarer. --- src/base/wlc/wlc.h | 5 +-- src/base/wlc/wlcBlast.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcNtk.c | 2 ++ src/base/wlc/wlcReadVer.c | 2 ++ src/base/wlc/wlcWriteVer.c | 2 ++ 5 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 3c0c9e19..399aa076 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -86,8 +86,9 @@ typedef enum { WLC_OBJ_ARI_POWER, // 42: arithmetic power WLC_OBJ_ARI_MINUS, // 43: arithmetic minus WLC_OBJ_ARI_SQRT, // 44: integer square root - WLC_OBJ_TABLE, // 45: bit table - WLC_OBJ_NUMBER // 46: unused + WLC_OBJ_ARI_SQUARE, // 45: integer square root + WLC_OBJ_TABLE, // 46: bit table + WLC_OBJ_NUMBER // 47: unused } Wlc_ObjType_t; // when adding new types, remember to update table Wlc_Names in "wlcNtk.c" diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index dfe46db5..10753da0 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -577,6 +577,84 @@ void Wlc_BlastSqrt( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Ve } Vec_IntReverseOrder( vRes ); } +void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) +{ + int i; + for ( i = Vec_IntSize(vLevel) - 1; i >= 0; i-- ) + if ( Vec_IntEntry(vLevel, i) > Level ) + break; + Vec_IntInsert( vProd, i + 1, Node ); + Vec_IntInsert( vLevel, i + 1, Level ); +} +void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes ) +{ + Vec_Int_t * vLevel, * vProd; + Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB ); + Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB ); + int i, k, NodeS, NodeC, LevelS, LevelC, Node1, Node2, Node3, Level1, Level2, Level3; + for ( i = 0; i < nArgA; i++ ) + for ( k = 0; k < nArgB; k++ ) + { + Vec_WecPush( vProds, i+k, Gia_ManHashAnd(pNew, pArgA[i], pArgB[k]) ); + Vec_WecPush( vLevels, i+k, 0 ); + } + for ( i = 0; i < nArgA + nArgB; i++ ) + { + while ( 1 ) + { + vProd = Vec_WecEntry( vProds, i ); + if ( Vec_IntSize(vProd) < 3 ) + break; + + Node1 = Vec_IntPop( vProd ); + Node2 = Vec_IntPop( vProd ); + Node3 = Vec_IntPop( vProd ); + + vLevel = Vec_WecEntry( vLevels, i ); + + Level1 = Vec_IntPop( vLevel ); + Level2 = Vec_IntPop( vLevel ); + Level3 = Vec_IntPop( vLevel ); + + Wlc_BlastFullAdder( pNew, Node1, Node2, Node3, &NodeC, &NodeS ); + LevelS = Abc_MaxInt( Abc_MaxInt(Level1, Level2), Level3 ) + 2; + LevelC = LevelS - 1; + + Wlc_IntInsert( vProd, vLevel, NodeS, LevelS ); + + vProd = Vec_WecEntry( vProds, i+1 ); + vLevel = Vec_WecEntry( vLevels, i+1 ); + + Wlc_IntInsert( vProd, vLevel, NodeC, LevelC ); + } + } + + // make all ranks have two products + for ( i = 0; i < nArgA + nArgB; i++ ) + { + vProd = Vec_WecEntry( vProds, i ); + while ( Vec_IntSize(vProd) < 2 ) + Vec_IntPush( vProd, 0 ); + assert( Vec_IntSize(vProd) == 2 ); + } + + vLevel = Vec_WecEntry( vLevels, 0 ); + Vec_IntClear( vRes ); + Vec_IntClear( vLevel ); + for ( i = 0; i < nArgA + nArgB; i++ ) + { + vProd = Vec_WecEntry( vProds, i ); + Vec_IntPush( vRes, Vec_IntEntry(vProd, 0) ); + Vec_IntPush( vLevel, Vec_IntEntry(vProd, 1) ); + } + Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), nArgA + nArgB ); + + Vec_WecFree( vProds ); + Vec_WecFree( vLevels ); +} +void Wlc_BlastSquare( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes ) +{ +} /**Function************************************************************* @@ -959,6 +1037,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds ) int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, fSigned ); int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, fSigned ); Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned ); + //Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes ); if ( nRange > nRangeMax + nRangeMax ) Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 ); else @@ -1005,6 +1084,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds ) else Vec_IntShrink( vRes, nRange ); } + else if ( pObj->Type == WLC_OBJ_ARI_SQUARE ) + { + int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange0, 0 ); + Wlc_BlastSquare( pNew, pArg0, nRange0, vTemp2, vRes ); + if ( nRange > Vec_IntSize(vRes) ) + Vec_IntFillExtra( vRes, nRange, 0 ); + else + Vec_IntShrink( vRes, nRange ); + } else if ( pObj->Type == WLC_OBJ_TABLE ) Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes ); else assert( 0 ); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 94edebae..6e9be0bc 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -407,6 +407,8 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_MINUS, 4 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) ); else if ( pObj->Type == WLC_OBJ_ARI_SQRT ) Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQRT, 11 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) / 8 + 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) / 2 - 5 ); + else if ( pObj->Type == WLC_OBJ_ARI_SQUARE ) + Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQUARE, 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) ); } if ( nCountRange ) { diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index aa72553a..85ea76c0 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -670,6 +670,8 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * Type = WLC_OBJ_BIT_NOT; else if ( pStr[0] == '@' ) Type = WLC_OBJ_ARI_SQRT; + else if ( pStr[0] == '#' ) + Type = WLC_OBJ_ARI_SQUARE; else assert( 0 ); // skip parentheses pStr = Wlc_PrsSkipSpaces( pStr+1 ); diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index 91cbd8ef..bb490a66 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -332,6 +332,8 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, "**" ); else if ( pObj->Type == WLC_OBJ_ARI_SQRT ) fprintf( pFile, "@" ); + else if ( pObj->Type == WLC_OBJ_ARI_SQUARE ) + fprintf( pFile, "#" ); else assert( 0 ); fprintf( pFile, " %s", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 1)) ); } -- cgit v1.2.3