diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c index a807fe60f..088b64191 100644 --- a/src/aig/gia/giaGen.c +++ b/src/aig/gia/giaGen.c @@ -1360,6 +1360,130 @@ Gia_Man_t * Gia_ManGenSorter( int LogN ) return p; } +/**Function************************************************************* + + Synopsis [Generates brand-name adders.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManGenPrep( int nVars, int ** p ) +{ + int i, k; + for ( i = 0; i < nVars; i++ ) + for ( k = 0; k < nVars; k++ ) + p[i][k] = -1; +} +void Gia_ManGenSK( int nVars, int ** p ) +{ + int i, k, nBits = Abc_Base2Log(nVars); + for ( i = 0; i < nBits; i++ ) + for ( k = 0; k < nVars; k++ ) + if ( (k >> i) & 1 ) + p[i+1][k] = ((1 << i) - 1) | ((k >> (i+1)) << (i+1)); +} +void Gia_ManGenBK( int nVars, int ** p ) +{ + int i, k, nBits = Abc_Base2Log(nVars); + nVars = 1 << nBits; + for ( i = 1; i < nBits; i++ ) + for ( k = (1 << i) - 1; k < nVars; k += (1 << i) ) + p[i][k] = k - (1 << (i-1)); + p[nBits][nVars-1] = (1<<(nBits-1))-1; + for ( i = 1; i < nBits; i++ ) + for ( k = (1 << i) - 1; k < nVars-(1 << i); k += (1 << i) ) + p[2*nBits-1-i][nVars-1-k+((1<<(i-1))-1)] = nVars-1-k+((1<<(i-1))-1) - (1 << (i-1)); +} +void Gia_ManGenHC( int nVars, int ** p ) +{ + int i, k, nBits = Abc_Base2Log(nVars); + nVars = 1 << nBits; + for ( k = 1; k < nVars; k += 2 ) + p[1][k] = k - 1; + for ( i = 2; i <= nBits; i++ ) + for ( k = 1 + (1 << (i-1)); k < nVars; k += 2 ) + p[i][k] = k - (1 << (i-1)); + for ( k = 2; k < nVars; k += 2 ) + p[nBits+1][k] = k - 1; +} +void Gia_ManGenRca( int nVars, int ** p ) +{ + int i; + for ( i = 1; i < nVars; i++ ) + p[i][i] = i-1; +} +void Gia_ManGenPrint( int nVars, int ** p ) +{ + int i, k; + for ( i = nVars-1; i >= 0; i-- ) + printf( "%2d ", i ); + printf( "\n" ); + for ( i = 0; i < nVars; i++ ) { + for ( k = nVars-1; k >= 0; k-- ) + if ( p[i][k] >= 0 ) + break; + for ( k = nVars-1; k >= 0; k-- ) + if ( p[i][k] == -1 ) + printf( " - " ); + else + printf( "%2d ", p[i][k] ); + printf("\n"); + } +} +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 ) +{ + 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 ); + 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 "); + 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 ); + Gia_Man_t * p = Gia_ManStart( 1000 ), * pTemp; + p->pName = Abc_UtilStrsav( "adder" ); + int * pLitsI = ABC_CALLOC( int, 2*nVars+10 ); + for ( k = 0; k < nVars; k++ ) + pLitsI[2*k] = Gia_ManAppendCi(p); + for ( k = 0; k < nVars; k++ ) + pLitsI[2*k+1] = Gia_ManAppendCi(p); + int Carry = fCarries ? Gia_ManAppendCi(p) : 0; + Gia_ManHashStart( 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 ); + memcpy( pLits, pLitsI, sizeof(int)*2*nVars ); + for ( i = 1; i < nVars; i++ ) + for ( k = 1; k < nVars; k++ ) + if ( pStore[i][k] >= 0 ) + Gia_ManGenPrefix( p, &pLits[2*k], &pLits[2*k+1], pLits[2*pStore[i][k]], pLits[2*pStore[i][k]+1] ); + for ( k = 0; k < nVars; k++ ) + Gia_ManAppendCo( p, k ? Gia_ManHashXor(p, pLitsI[2*k], pLits[2*(k-1)+1]) : pLitsI[2*k] ); + if ( fCarries ) + Gia_ManAppendCo( p, pLits[2*(k-1)+1] ); + ABC_FREE( pStore ); + ABC_FREE( pLitsI ); + ABC_FREE( pLits ); + p = Gia_ManCleanup( pTemp = p ); + Gia_ManStop( pTemp ); + return p; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f85e14179..e9a21e0d8 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -635,6 +635,7 @@ static int Abc_CommandAbc9GenMux ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9GenComp ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GenSorter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GenNeuron ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9GenAdder ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Window ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9FunAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9DsdInfo ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1458,6 +1459,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&gencomp", Abc_CommandAbc9GenComp, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&gensorter", Abc_CommandAbc9GenSorter, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&genneuron", Abc_CommandAbc9GenNeuron, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&genadder", Abc_CommandAbc9GenAdder, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&window", Abc_CommandAbc9Window, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&funabs", Abc_CommandAbc9FunAbs, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&dsdinfo", Abc_CommandAbc9DsdInfo, 0 ); @@ -56568,6 +56570,78 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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 ); + Gia_Man_t * pTemp = NULL; + int c, nBits = 0, fSK = 0, fBK = 0, fHC = 0, fCarries = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Nsbhcv" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nBits = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nBits < 0 ) + goto usage; + break; + case 's': + fSK ^= 1; + break; + case 'b': + fBK ^= 1; + break; + case 'h': + fHC ^= 1; + break; + case 'c': + fCarries ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + default: + goto usage; + } + } + if ( nBits < 1 ) + { + 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 ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &genadder [-N ] [-sbhcv] \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-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; +} + /**Function************************************************************* Synopsis []