mirror of https://github.com/YosysHQ/abc.git
Add MM-based adder generation to &genadder.
This commit is contained in:
parent
26567123a7
commit
7bf1177d39
|
|
@ -1446,23 +1446,76 @@ void Gia_ManGenPrefix( Gia_Man_t * pNew, int * p, int * g, int p2, int g2 )
|
|||
*g = Gia_ManHashOr(pNew, *g, Gia_ManHashAnd(pNew, *p, g2));
|
||||
*p = Gia_ManHashAnd(pNew, *p, p2);
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenAdder( int nVars, int fSK, int fBK, int fHC, int fCarries, int fVerbose )
|
||||
static int Gia_ManGenAdderMaj( Gia_Man_t * p, int a, int b, int c )
|
||||
{
|
||||
int ab = Gia_ManHashAnd( p, a, b );
|
||||
int ac = Gia_ManHashAnd( p, a, c );
|
||||
int bc = Gia_ManHashAnd( p, b, c );
|
||||
return Gia_ManHashOr( p, ab, Gia_ManHashOr( p, ac, bc ) );
|
||||
}
|
||||
static int Gia_ManGenAdderFloorPow2( int n )
|
||||
{
|
||||
int r = 1;
|
||||
assert( n > 0 );
|
||||
while ( r <= n / 2 )
|
||||
r *= 2;
|
||||
return r;
|
||||
}
|
||||
static void Gia_ManGenAdderMMRange( Gia_Man_t * p, int nVars, int * pLitsI, int * pM0, int * pM1, int i, int k )
|
||||
{
|
||||
int Index = i * nVars + k;
|
||||
int nRange, nLeft, j;
|
||||
assert( 0 <= i && i <= k && k < nVars );
|
||||
if ( pM0[Index] >= 0 )
|
||||
return;
|
||||
if ( i == k )
|
||||
{
|
||||
pM0[Index] = pLitsI[2*i];
|
||||
pM1[Index] = pLitsI[2*i+1];
|
||||
return;
|
||||
}
|
||||
nRange = k - i + 1;
|
||||
nLeft = Gia_ManGenAdderFloorPow2( nRange - 1 );
|
||||
j = i + nLeft - 1;
|
||||
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, i, j );
|
||||
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, j+1, k );
|
||||
pM0[Index] = Gia_ManGenAdderMaj( p, pM0[(j+1)*nVars+k], pM1[(j+1)*nVars+k], pM0[i*nVars+j] );
|
||||
pM1[Index] = Gia_ManGenAdderMaj( p, pM0[(j+1)*nVars+k], pM1[(j+1)*nVars+k], pM1[i*nVars+j] );
|
||||
}
|
||||
static int Gia_ManGenAdderMMCarry( Gia_Man_t * p, int nVars, int * pLitsI, int * pM0, int * pM1, int * pCarries, int iCarry )
|
||||
{
|
||||
int nBase, iBeg;
|
||||
assert( 0 <= iCarry && iCarry <= nVars );
|
||||
if ( pCarries[iCarry] >= 0 )
|
||||
return pCarries[iCarry];
|
||||
nBase = Gia_ManGenAdderFloorPow2( iCarry );
|
||||
iBeg = nBase - 1;
|
||||
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, iBeg, iCarry-1 );
|
||||
pCarries[iCarry] = Gia_ManGenAdderMaj( p, pM0[iBeg*nVars+iCarry-1], pM1[iBeg*nVars+iCarry-1], Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, iBeg ) );
|
||||
return pCarries[iCarry];
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenAdder( int nVars, int fSK, int fBK, int fHC, int fMM, int fCarries, int fVerbose )
|
||||
{
|
||||
extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps );
|
||||
int i, k, nBits = Abc_Base2Log(nVars), nVarsAlloc = (1 << nBits) + 2;
|
||||
int ** pStore = (int **)Extra_ArrayAlloc( nVarsAlloc, nVarsAlloc, 4 );
|
||||
int ** pStore = fMM ? NULL : (int **)Extra_ArrayAlloc( nVarsAlloc, nVarsAlloc, 4 );
|
||||
printf( "Generating %d-bit ", nVars );
|
||||
Gia_ManGenPrep( nVars+2, pStore );
|
||||
if ( fSK )
|
||||
Gia_ManGenSK( nVars, pStore ), printf("Sklansky ");
|
||||
else if ( fBK )
|
||||
Gia_ManGenBK( nVars, pStore ), printf("Brent-Kung ");
|
||||
else if ( fHC )
|
||||
Gia_ManGenHC( nVars, pStore ), printf("Huan-Carlsson ");
|
||||
if ( fMM )
|
||||
printf("M/M ");
|
||||
else
|
||||
Gia_ManGenRca( nVars, pStore ), printf("ripple-carry ");
|
||||
{
|
||||
Gia_ManGenPrep( nVars+2, pStore );
|
||||
if ( fSK )
|
||||
Gia_ManGenSK( nVars, pStore ), printf("Sklansky ");
|
||||
else if ( fBK )
|
||||
Gia_ManGenBK( nVars, pStore ), printf("Brent-Kung ");
|
||||
else if ( fHC )
|
||||
Gia_ManGenHC( nVars, pStore ), printf("Huan-Carlsson ");
|
||||
else
|
||||
Gia_ManGenRca( nVars, pStore ), printf("ripple-carry ");
|
||||
}
|
||||
printf( "adder with%s carry-in and carry-out\n", fCarries ? "":"out" );
|
||||
if ( fVerbose ) Gia_ManGenPrint( nVars, pStore );
|
||||
if ( fVerbose && !fMM ) Gia_ManGenPrint( nVars, pStore );
|
||||
Gia_Man_t * p = Gia_ManStart( 1000 ), * pTemp;
|
||||
p->pName = Abc_UtilStrsav( "adder" );
|
||||
int * pLitsI = ABC_CALLOC( int, 2*nVars+10 );
|
||||
|
|
@ -1472,6 +1525,33 @@ Gia_Man_t * Gia_ManGenAdder( int nVars, int fSK, int fBK, int fHC, int fCarries,
|
|||
pLitsI[2*k+1] = Gia_ManAppendCi(p);
|
||||
int Carry = fCarries ? Gia_ManAppendCi(p) : 0;
|
||||
Gia_ManHashStart( p );
|
||||
if ( fMM )
|
||||
{
|
||||
int nPairs = nVars * nVars;
|
||||
int * pM0 = ABC_ALLOC( int, nPairs );
|
||||
int * pM1 = ABC_ALLOC( int, nPairs );
|
||||
int * pCarries = ABC_ALLOC( int, nVars + 1 );
|
||||
int * pProps = ABC_ALLOC( int, nVars );
|
||||
for ( k = 0; k < nPairs; k++ )
|
||||
pM0[k] = pM1[k] = -1;
|
||||
for ( k = 0; k <= nVars; k++ )
|
||||
pCarries[k] = -1;
|
||||
pCarries[0] = Carry;
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
pProps[k] = Gia_ManHashXor( p, pLitsI[2*k], pLitsI[2*k+1] );
|
||||
if ( fCarries )
|
||||
Gia_ManAppendCo( p, Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, nVars ) );
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
Gia_ManAppendCo( p, Gia_ManHashXor( p, pProps[k], Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, k ) ) );
|
||||
ABC_FREE( pM0 );
|
||||
ABC_FREE( pM1 );
|
||||
ABC_FREE( pCarries );
|
||||
ABC_FREE( pProps );
|
||||
ABC_FREE( pLitsI );
|
||||
p = Gia_ManCleanup( pTemp = p );
|
||||
Gia_ManStop( pTemp );
|
||||
return p;
|
||||
}
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
Wlc_BlastFullAdder( p, pLitsI[2*k], pLitsI[2*k+1], k ? 0 : Carry, &pLitsI[2*k+1], &pLitsI[2*k] );
|
||||
int * pLits = ABC_CALLOC( int, 2*nVars+10 );
|
||||
|
|
@ -1498,4 +1578,3 @@ Gia_Man_t * Gia_ManGenAdder( int nVars, int fSK, int fBK, int fHC, int fCarries,
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -58734,11 +58734,11 @@ usage:
|
|||
***********************************************************************/
|
||||
int Abc_CommandAbc9GenAdder( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Gia_Man_t * Gia_ManGenAdder( int nVars, int fSK, int fBK, int fHC, int fCarries, int fVerbose );
|
||||
extern Gia_Man_t * Gia_ManGenAdder( int nVars, int fSK, int fBK, int fHC, int fMM, int fCarries, int fVerbose );
|
||||
Gia_Man_t * pTemp = NULL;
|
||||
int c, nBits = 0, fSK = 0, fBK = 0, fHC = 0, fCarries = 0, fVerbose = 0;
|
||||
int c, nBits = 0, fSK = 0, fBK = 0, fHC = 0, fMM = 0, fCarries = 0, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nsbhcv" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nsbhmcv" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -58762,6 +58762,9 @@ int Abc_CommandAbc9GenAdder( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'h':
|
||||
fHC ^= 1;
|
||||
break;
|
||||
case 'm':
|
||||
fMM ^= 1;
|
||||
break;
|
||||
case 'c':
|
||||
fCarries ^= 1;
|
||||
break;
|
||||
|
|
@ -58777,17 +58780,18 @@ int Abc_CommandAbc9GenAdder( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "Abc_CommandAbc9GenAdder(): The number of inputs should be defined on the command line \"-N num\".\n" );
|
||||
return 0;
|
||||
}
|
||||
pTemp = Gia_ManGenAdder( nBits, fSK, fBK, fHC, fCarries, fVerbose );
|
||||
pTemp = Gia_ManGenAdder( nBits, fSK, fBK, fHC, fMM, fCarries, fVerbose );
|
||||
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &genadder [-N <num>] [-sbhcv]\n" );
|
||||
Abc_Print( -2, "usage: &genadder [-N <num>] [-sbhmcv]\n" );
|
||||
Abc_Print( -2, "\t generates a prefix adder (by default, the ripple carry adder)\n" );
|
||||
Abc_Print( -2, "\t-N num : the bit-width of the adder [default = undefined]\n" );
|
||||
Abc_Print( -2, "\t-s : toggles using Sklansky adder [default = %s]\n", fSK ? "yes": "no" );
|
||||
Abc_Print( -2, "\t-b : toggles using Brent-Kung adder [default = %s]\n", fBK ? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : toggles using Huan-Carlsson adder [default = %s]\n", fHC ? "yes": "no" );
|
||||
Abc_Print( -2, "\t-m : toggles using majority-based M/M adder [default = %s]\n", fMM ? "yes": "no" );
|
||||
Abc_Print( -2, "\t-c : toggles using carry-in and carry-out [default = %s]\n", fCarries ? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose ? "yes": "no" );
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue