Commit 5b588e09 by Alan Mishchenko

Exposing a switch to generate carry-lookahead adder during bit-blasting.

parent 812a1bb3
...@@ -208,6 +208,7 @@ struct Wlc_BstPar_t_ ...@@ -208,6 +208,7 @@ struct Wlc_BstPar_t_
int fAddOutputs; int fAddOutputs;
int fMulti; int fMulti;
int fBooth; int fBooth;
int fCla;
int fNoCleanup; int fNoCleanup;
int fCreateMiter; int fCreateMiter;
int fDecMuxes; int fDecMuxes;
...@@ -226,6 +227,7 @@ static inline void Wlc_BstParDefault( Wlc_BstPar_t * pPar ) ...@@ -226,6 +227,7 @@ static inline void Wlc_BstParDefault( Wlc_BstPar_t * pPar )
pPar->fAddOutputs = 0; pPar->fAddOutputs = 0;
pPar->fMulti = 0; pPar->fMulti = 0;
pPar->fBooth = 0; pPar->fBooth = 0;
pPar->fCla = 0;
pPar->fCreateMiter = 0; pPar->fCreateMiter = 0;
pPar->fDecMuxes = 0; pPar->fDecMuxes = 0;
pPar->fVerbose = 0; pPar->fVerbose = 0;
......
...@@ -375,7 +375,7 @@ void Wlc_BlastAdderCLA_rec( Gia_Man_t * pNew, int * pGen, int * pPro, int * pCar ...@@ -375,7 +375,7 @@ void Wlc_BlastAdderCLA_rec( Gia_Man_t * pNew, int * pGen, int * pPro, int * pCar
Wlc_BlastAdderCLA_one( pNew, pGen2, pPro2, pCar, pGen1, pPro1, pCar+nBits/2 ); // returns *pGen1, *pPro1, pCar[nBits/2] Wlc_BlastAdderCLA_one( pNew, pGen2, pPro2, pCar, pGen1, pPro1, pCar+nBits/2 ); // returns *pGen1, *pPro1, pCar[nBits/2]
} }
} }
void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0 void Wlc_BlastAdderCLA_int( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0
{ {
int * pGen = ABC_CALLOC( int, nBits ); int * pGen = ABC_CALLOC( int, nBits );
int * pPro = ABC_CALLOC( int, nBits ); int * pPro = ABC_CALLOC( int, nBits );
...@@ -401,6 +401,27 @@ void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) ...@@ -401,6 +401,27 @@ void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits )
ABC_FREE(pPro); ABC_FREE(pPro);
ABC_FREE(pCar); ABC_FREE(pCar);
} }
void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int fSign ) // result is in pAdd0
{
int i, Log2 = Abc_Base2Log(nBits);
int * pAdd0n = ABC_CALLOC( int, 1<<Log2 );
int * pAdd1n = ABC_CALLOC( int, 1<<Log2 );
for ( i = 0; i < nBits; i++ )
{
pAdd0n[i] = pAdd0[i];
pAdd1n[i] = pAdd1[i];
}
for ( ; i < (1<<Log2); i++ )
{
pAdd0n[i] = fSign ? pAdd0[nBits-1] : 0;
pAdd1n[i] = fSign ? pAdd1[nBits-1] : 0;
}
Wlc_BlastAdderCLA_int( pNew, pAdd0n, pAdd1n, 1<<Log2 );
for ( i = 0; i < nBits; i++ )
pAdd0[i] = pAdd0n[i];
ABC_FREE(pAdd0n);
ABC_FREE(pAdd1n);
}
void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes ) void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes )
{ {
int * pRes = Wlc_VecCopy( vRes, pNum, nNum ); int * pRes = Wlc_VecCopy( vRes, pNum, nNum );
...@@ -700,7 +721,7 @@ void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) ...@@ -700,7 +721,7 @@ void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds )
Vec_IntFree( vSupp ); Vec_IntFree( vSupp );
Vec_WrdFree( vTemp ); Vec_WrdFree( vTemp );
} }
void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes ) void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes, int fSigned, int fCla )
{ {
Vec_Int_t * vLevel, * vProd; Vec_Int_t * vLevel, * vProd;
int i, NodeS, NodeC, LevelS, LevelC, Node1, Node2, Node3, Level1, Level2, Level3; int i, NodeS, NodeC, LevelS, LevelC, Node1, Node2, Node3, Level1, Level2, Level3;
...@@ -758,9 +779,13 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL ...@@ -758,9 +779,13 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL
} }
Vec_IntPush( vRes, 0 ); Vec_IntPush( vRes, 0 );
Vec_IntPush( vLevel, 0 ); Vec_IntPush( vLevel, 0 );
Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 );
if ( fCla )
Wlc_BlastAdderCLA( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), fSigned );
else
Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 );
} }
void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes ) void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla )
{ {
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB ); Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB );
Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB ); Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB );
...@@ -768,11 +793,20 @@ void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA ...@@ -768,11 +793,20 @@ void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA
for ( i = 0; i < nArgA; i++ ) for ( i = 0; i < nArgA; i++ )
for ( k = 0; k < nArgB; k++ ) for ( k = 0; k < nArgB; k++ )
{ {
Vec_WecPush( vProds, i+k, Gia_ManHashAnd(pNew, pArgA[i], pArgB[k]) ); int fCompl = fSigned && ((i == nArgA-1) ^ (k == nArgB-1));
Vec_WecPush( vProds, i+k, Abc_LitNotCond(Gia_ManHashAnd(pNew, pArgA[i], pArgB[k]), fCompl) );
Vec_WecPush( vLevels, i+k, 0 ); Vec_WecPush( vLevels, i+k, 0 );
} }
if ( fSigned )
{
Vec_WecPush( vProds, nArgA, 1 );
Vec_WecPush( vLevels, nArgA, 0 );
Vec_WecPush( vProds, nArgA+nArgB-1, 1 );
Vec_WecPush( vLevels, nArgA+nArgB-1, 0 );
}
Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
Vec_WecFree( vProds ); Vec_WecFree( vProds );
Vec_WecFree( vLevels ); Vec_WecFree( vLevels );
...@@ -797,12 +831,12 @@ void Wlc_BlastSquare( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, ...@@ -797,12 +831,12 @@ void Wlc_BlastSquare( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp,
} }
} }
Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, 0, 0 );
Vec_WecFree( vProds ); Vec_WecFree( vProds );
Vec_WecFree( vLevels ); Vec_WecFree( vLevels );
} }
void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned ) void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla )
{ {
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 ); Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 );
Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB + 3 ); Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB + 3 );
...@@ -871,7 +905,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int ...@@ -871,7 +905,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
//Vec_WecPrint( vProds, 0 ); //Vec_WecPrint( vProds, 0 );
//Wlc_BlastPrintMatrix( pNew, vProds ); //Wlc_BlastPrintMatrix( pNew, vProds );
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) ); //printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
Vec_WecFree( vProds ); Vec_WecFree( vProds );
Vec_WecFree( vLevels ); Vec_WecFree( vLevels );
...@@ -1391,8 +1425,12 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) ...@@ -1391,8 +1425,12 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
int CarryIn = Wlc_ObjFaninNum(pObj) == 3 ? pFans2[0] : 0; int CarryIn = Wlc_ObjFaninNum(pObj) == 3 ? pFans2[0] : 0;
if ( pObj->Type == WLC_OBJ_ARI_ADD ) if ( pObj->Type == WLC_OBJ_ARI_ADD )
Wlc_BlastAdder( pNew, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes) {
// Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) if ( pPar->fCla )
Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRange, Wlc_ObjIsSignedFanin01(p, pObj) ); // result is in pFan0 (vRes)
else
Wlc_BlastAdder( pNew, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes)
}
else else
Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes)
Vec_IntShrink( vRes, nRange ); Vec_IntShrink( vRes, nRange );
...@@ -1416,10 +1454,11 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) ...@@ -1416,10 +1454,11 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
if ( Wlc_NtkCountConstBits(pArg0, nRangeMax) < Wlc_NtkCountConstBits(pArg1, nRangeMax) ) if ( Wlc_NtkCountConstBits(pArg0, nRangeMax) < Wlc_NtkCountConstBits(pArg1, nRangeMax) )
ABC_SWAP( int *, pArg0, pArg1 ); ABC_SWAP( int *, pArg0, pArg1 );
if ( pPar->fBooth ) if ( pPar->fBooth )
Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned ); Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla );
else if ( pPar->fCla )
Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla );
else else
Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned ); Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned );
//Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes );
if ( nRange > Vec_IntSize(vRes) ) if ( nRange > Vec_IntSize(vRes) )
Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 ); Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 );
else else
......
...@@ -972,7 +972,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -972,7 +972,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
Wlc_BstParDefault( pPar ); Wlc_BstParDefault( pPar );
pPar->nOutputRange = 2; pPar->nOutputRange = 2;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombdsvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombadsvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -1032,6 +1032,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -1032,6 +1032,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'b': case 'b':
pPar->fBooth ^= 1; pPar->fBooth ^= 1;
break; break;
case 'a':
pPar->fCla ^= 1;
break;
case 'd': case 'd':
pPar->fCreateMiter ^= 1; pPar->fCreateMiter ^= 1;
break; break;
...@@ -1083,7 +1086,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -1083,7 +1086,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_FrameUpdateGia( pAbc, pNew ); Abc_FrameUpdateGia( pAbc, pNew );
return 0; return 0;
usage: usage:
Abc_Print( -2, "usage: %%blast [-ORAM num] [-combdsvh]\n" ); Abc_Print( -2, "usage: %%blast [-ORAM num] [-combadsvh]\n" );
Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" ); Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" );
Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput ); Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput );
Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange ); Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange );
...@@ -1093,6 +1096,7 @@ usage: ...@@ -1093,6 +1096,7 @@ usage:
Abc_Print( -2, "\t-o : toggle using additional POs on the word-level boundaries [default = %s]\n", pPar->fAddOutputs? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using additional POs on the word-level boundaries [default = %s]\n", pPar->fAddOutputs? "yes": "no" );
Abc_Print( -2, "\t-m : toggle creating boxes for all multipliers in the design [default = %s]\n", pPar->fMulti? "yes": "no" ); Abc_Print( -2, "\t-m : toggle creating boxes for all multipliers in the design [default = %s]\n", pPar->fMulti? "yes": "no" );
Abc_Print( -2, "\t-b : toggle generating radix-4 Booth multipliers [default = %s]\n", pPar->fBooth? "yes": "no" ); Abc_Print( -2, "\t-b : toggle generating radix-4 Booth multipliers [default = %s]\n", pPar->fBooth? "yes": "no" );
Abc_Print( -2, "\t-a : toggle generating carry-look-ahead adder [default = %s]\n", pPar->fCla? "yes": "no" );
Abc_Print( -2, "\t-d : toggle creating dual-output miter [default = %s]\n", pPar->fCreateMiter? "yes": "no" ); Abc_Print( -2, "\t-d : toggle creating dual-output miter [default = %s]\n", pPar->fCreateMiter? "yes": "no" );
Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPar->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPar->fVerbose? "yes": "no" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment