Generating AIGs for adders.

This commit is contained in:
Alan Mishchenko 2025-05-22 23:56:13 -07:00
parent 32fe49b6d1
commit 716314d835
2 changed files with 198 additions and 0 deletions

View File

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

View File

@ -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 <num>] [-sbhcv] <file>\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 []