mirror of https://github.com/YosysHQ/abc.git
1215 lines
38 KiB
C
1215 lines
38 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [abcGen.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Network and node package.]
|
|
|
|
Synopsis [Procedures to generate various type of circuits.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: abcGen.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "base/abc/abc.h"
|
|
#include "aig/miniaig/miniaig.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_WriteFullAdder( FILE * pFile )
|
|
{
|
|
int fNaive = 0;
|
|
fprintf( pFile, ".model FA\n" );
|
|
fprintf( pFile, ".inputs a b cin\n" );
|
|
fprintf( pFile, ".outputs s cout\n" );
|
|
if ( fNaive )
|
|
{
|
|
fprintf( pFile, ".names a b k\n" );
|
|
fprintf( pFile, "10 1\n" );
|
|
fprintf( pFile, "01 1\n" );
|
|
fprintf( pFile, ".names k cin s\n" );
|
|
fprintf( pFile, "10 1\n" );
|
|
fprintf( pFile, "01 1\n" );
|
|
fprintf( pFile, ".names a b cin cout\n" );
|
|
fprintf( pFile, "11- 1\n" );
|
|
fprintf( pFile, "1-1 1\n" );
|
|
fprintf( pFile, "-11 1\n" );
|
|
}
|
|
else
|
|
{
|
|
fprintf( pFile, ".names a b and1\n" );
|
|
fprintf( pFile, "11 1\n" );
|
|
fprintf( pFile, ".names a b and1_\n" );
|
|
fprintf( pFile, "00 1\n" );
|
|
fprintf( pFile, ".names and1 and1_ xor\n" );
|
|
fprintf( pFile, "00 1\n" );
|
|
|
|
fprintf( pFile, ".names cin xor and2\n" );
|
|
fprintf( pFile, "11 1\n" );
|
|
fprintf( pFile, ".names cin xor and2_\n" );
|
|
fprintf( pFile, "00 1\n" );
|
|
fprintf( pFile, ".names and2 and2_ s\n" );
|
|
fprintf( pFile, "00 1\n" );
|
|
|
|
fprintf( pFile, ".names and1 and2 cout\n" );
|
|
fprintf( pFile, "00 0\n" );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
void Abc_WriteAdder( FILE * pFile, int nVars )
|
|
{
|
|
int i, nDigits = Abc_Base10Log( nVars );
|
|
|
|
assert( nVars > 0 );
|
|
fprintf( pFile, ".model ADD%d\n", nVars );
|
|
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " a%0*d", nDigits, i );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " b%0*d", nDigits, i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".outputs" );
|
|
for ( i = 0; i <= nVars; i++ )
|
|
fprintf( pFile, " s%0*d", nDigits, i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".names c\n" );
|
|
if ( nVars == 1 )
|
|
fprintf( pFile, ".subckt FA a=a0 b=b0 cin=c s=y0 cout=s1\n" );
|
|
else
|
|
{
|
|
fprintf( pFile, ".subckt FA a=a%0*d b=b%0*d cin=c s=s%0*d cout=%0*d\n", nDigits, 0, nDigits, 0, nDigits, 0, nDigits, 0 );
|
|
for ( i = 1; i < nVars-1; i++ )
|
|
fprintf( pFile, ".subckt FA a=a%0*d b=b%0*d cin=%0*d s=s%0*d cout=%0*d\n", nDigits, i, nDigits, i, nDigits, i-1, nDigits, i, nDigits, i );
|
|
fprintf( pFile, ".subckt FA a=a%0*d b=b%0*d cin=%0*d s=s%0*d cout=s%0*d\n", nDigits, i, nDigits, i, nDigits, i-1, nDigits, i, nDigits, i+1 );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
Abc_WriteFullAdder( pFile );
|
|
}
|
|
void Abc_GenAdder( char * pFileName, int nVars )
|
|
{
|
|
FILE * pFile;
|
|
assert( nVars > 0 );
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# %d-bit ripple-carry adder generated by ABC on %s\n", nVars, Extra_TimeStamp() );
|
|
Abc_WriteAdder( pFile, nVars );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_WriteMulti( FILE * pFile, int nVars )
|
|
{
|
|
int i, k, nDigits = Abc_Base10Log( nVars ), nDigits2 = Abc_Base10Log( 2*nVars );
|
|
|
|
assert( nVars > 0 );
|
|
fprintf( pFile, ".model Multi%d\n", nVars );
|
|
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " a%0*d", nDigits, i );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " b%0*d", nDigits, i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".outputs" );
|
|
for ( i = 0; i < 2*nVars; i++ )
|
|
fprintf( pFile, " m%0*d", nDigits2, i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
for ( i = 0; i < 2*nVars; i++ )
|
|
fprintf( pFile, ".names x%0*d_%0*d\n", nDigits, 0, nDigits2, i );
|
|
for ( k = 0; k < nVars; k++ )
|
|
{
|
|
for ( i = 0; i < 2 * nVars; i++ )
|
|
if ( i >= k && i < k + nVars )
|
|
fprintf( pFile, ".names b%0*d a%0*d y%0*d_%0*d\n11 1\n", nDigits, k, nDigits, i-k, nDigits, k, nDigits2, i );
|
|
else
|
|
fprintf( pFile, ".names y%0*d_%0*d\n", nDigits, k, nDigits2, i );
|
|
fprintf( pFile, ".subckt ADD%d", 2*nVars );
|
|
for ( i = 0; i < 2*nVars; i++ )
|
|
fprintf( pFile, " a%0*d=x%0*d_%0*d", nDigits2, i, nDigits, k, nDigits2, i );
|
|
for ( i = 0; i < 2*nVars; i++ )
|
|
fprintf( pFile, " b%0*d=y%0*d_%0*d", nDigits2, i, nDigits, k, nDigits2, i );
|
|
for ( i = 0; i <= 2*nVars; i++ )
|
|
fprintf( pFile, " s%0*d=x%0*d_%0*d", nDigits2, i, nDigits, k+1, nDigits2, i );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
for ( i = 0; i < 2 * nVars; i++ )
|
|
fprintf( pFile, ".names x%0*d_%0*d m%0*d\n1 1\n", nDigits, k, nDigits2, i, nDigits2, i );
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
Abc_WriteAdder( pFile, 2*nVars );
|
|
}
|
|
void Abc_GenMulti( char * pFileName, int nVars )
|
|
{
|
|
FILE * pFile;
|
|
assert( nVars > 0 );
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# %d-bit multiplier generated by ABC on %s\n", nVars, Extra_TimeStamp() );
|
|
Abc_WriteMulti( pFile, nVars );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_WriteComp( FILE * pFile )
|
|
{
|
|
fprintf( pFile, ".model Comp\n" );
|
|
fprintf( pFile, ".inputs a b\n" );
|
|
fprintf( pFile, ".outputs x y\n" );
|
|
fprintf( pFile, ".names a b x\n" );
|
|
fprintf( pFile, "11 1\n" );
|
|
fprintf( pFile, ".names a b y\n" );
|
|
fprintf( pFile, "1- 1\n" );
|
|
fprintf( pFile, "-1 1\n" );
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
void Abc_WriteLayer( FILE * pFile, int nVars, int fSkip1 )
|
|
{
|
|
int i;
|
|
fprintf( pFile, ".model Layer%d\n", fSkip1 );
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " x%02d", i );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".outputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " y%02d", i );
|
|
fprintf( pFile, "\n" );
|
|
if ( fSkip1 )
|
|
{
|
|
fprintf( pFile, ".names x00 y00\n" );
|
|
fprintf( pFile, "1 1\n" );
|
|
i = 1;
|
|
}
|
|
else
|
|
i = 0;
|
|
for ( ; i + 1 < nVars; i += 2 )
|
|
fprintf( pFile, ".subckt Comp a=x%02d b=x%02d x=y%02d y=y%02d\n", i, i+1, i, i+1 );
|
|
if ( i < nVars )
|
|
{
|
|
fprintf( pFile, ".names x%02d y%02d\n", i, i );
|
|
fprintf( pFile, "1 1\n" );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_GenSorter( char * pFileName, int nVars )
|
|
{
|
|
FILE * pFile;
|
|
int i, k, Counter, nDigits;
|
|
|
|
assert( nVars > 1 );
|
|
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# %d-bit sorter generated by ABC on %s\n", nVars, Extra_TimeStamp() );
|
|
fprintf( pFile, ".model Sorter%02d\n", nVars );
|
|
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " x%02d", i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".outputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " y%02d", i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
Counter = 0;
|
|
nDigits = Abc_Base10Log( (nVars-2)*nVars );
|
|
if ( nVars == 2 )
|
|
fprintf( pFile, ".subckt Comp a=x00 b=x01 x=y00 y=y01\n" );
|
|
else
|
|
{
|
|
fprintf( pFile, ".subckt Layer0" );
|
|
for ( k = 0; k < nVars; k++ )
|
|
fprintf( pFile, " x%02d=x%02d", k, k );
|
|
for ( k = 0; k < nVars; k++ )
|
|
fprintf( pFile, " y%02d=%0*d", k, nDigits, Counter++ );
|
|
fprintf( pFile, "\n" );
|
|
Counter -= nVars;
|
|
for ( i = 1; i < 2*nVars-2; i++ )
|
|
{
|
|
fprintf( pFile, ".subckt Layer%d", (i&1) );
|
|
for ( k = 0; k < nVars; k++ )
|
|
fprintf( pFile, " x%02d=%0*d", k, nDigits, Counter++ );
|
|
for ( k = 0; k < nVars; k++ )
|
|
fprintf( pFile, " y%02d=%0*d", k, nDigits, Counter++ );
|
|
fprintf( pFile, "\n" );
|
|
Counter -= nVars;
|
|
}
|
|
fprintf( pFile, ".subckt Layer%d", (i&1) );
|
|
for ( k = 0; k < nVars; k++ )
|
|
fprintf( pFile, " x%02d=%0*d", k, nDigits, Counter++ );
|
|
for ( k = 0; k < nVars; k++ )
|
|
fprintf( pFile, " y%02d=y%02d", k, k );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
|
|
Abc_WriteLayer( pFile, nVars, 0 );
|
|
Abc_WriteLayer( pFile, nVars, 1 );
|
|
Abc_WriteComp( pFile );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_WriteCell( FILE * pFile )
|
|
{
|
|
fprintf( pFile, ".model cell\n" );
|
|
fprintf( pFile, ".inputs px1 px2 py1 py2 x y\n" );
|
|
fprintf( pFile, ".outputs fx fy\n" );
|
|
fprintf( pFile, ".names x y a\n" );
|
|
fprintf( pFile, "11 1\n" );
|
|
fprintf( pFile, ".names px1 a x nx\n" );
|
|
fprintf( pFile, "11- 1\n" );
|
|
fprintf( pFile, "0-1 1\n" );
|
|
fprintf( pFile, ".names py1 a y ny\n" );
|
|
fprintf( pFile, "11- 1\n" );
|
|
fprintf( pFile, "0-1 1\n" );
|
|
fprintf( pFile, ".names px2 nx fx\n" );
|
|
fprintf( pFile, "10 1\n" );
|
|
fprintf( pFile, "01 1\n" );
|
|
fprintf( pFile, ".names py2 ny fy\n" );
|
|
fprintf( pFile, "10 1\n" );
|
|
fprintf( pFile, "01 1\n" );
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_GenMesh( char * pFileName, int nVars )
|
|
{
|
|
FILE * pFile;
|
|
int i, k;
|
|
|
|
assert( nVars > 0 );
|
|
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# %dx%d mesh generated by ABC on %s\n", nVars, nVars, Extra_TimeStamp() );
|
|
fprintf( pFile, ".model mesh%d\n", nVars );
|
|
|
|
for ( i = 0; i < nVars; i++ )
|
|
for ( k = 0; k < nVars; k++ )
|
|
{
|
|
fprintf( pFile, ".inputs" );
|
|
fprintf( pFile, " p%d%dx1", i, k );
|
|
fprintf( pFile, " p%d%dx2", i, k );
|
|
fprintf( pFile, " p%d%dy1", i, k );
|
|
fprintf( pFile, " p%d%dy2", i, k );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " v%02d v%02d", 2*i, 2*i+1 );
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".outputs" );
|
|
fprintf( pFile, " fx00" );
|
|
fprintf( pFile, "\n" );
|
|
|
|
for ( i = 0; i < nVars; i++ ) // horizontal
|
|
for ( k = 0; k < nVars; k++ ) // vertical
|
|
{
|
|
fprintf( pFile, ".subckt cell" );
|
|
fprintf( pFile, " px1=p%d%dx1", i, k );
|
|
fprintf( pFile, " px2=p%d%dx2", i, k );
|
|
fprintf( pFile, " py1=p%d%dy1", i, k );
|
|
fprintf( pFile, " py2=p%d%dy2", i, k );
|
|
if ( k == nVars - 1 )
|
|
fprintf( pFile, " x=v%02d", i );
|
|
else
|
|
fprintf( pFile, " x=fx%d%d", i, k+1 );
|
|
if ( i == nVars - 1 )
|
|
fprintf( pFile, " y=v%02d", nVars+k );
|
|
else
|
|
fprintf( pFile, " y=fy%d%d", i+1, k );
|
|
// outputs
|
|
fprintf( pFile, " fx=fx%d%d", i, k );
|
|
fprintf( pFile, " fy=fy%d%d", i, k );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, "\n" );
|
|
|
|
Abc_WriteCell( pFile );
|
|
fclose( pFile );
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_WriteKLut( FILE * pFile, int nLutSize )
|
|
{
|
|
int i, iVar, iNext, nPars = (1 << nLutSize);
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".model lut%d\n", nLutSize );
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nPars; i++ )
|
|
fprintf( pFile, " p%02d", i );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nLutSize; i++ )
|
|
fprintf( pFile, " i%d", i );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".outputs o\n" );
|
|
fprintf( pFile, ".names n01 o\n" );
|
|
fprintf( pFile, "1 1\n" );
|
|
// write internal MUXes
|
|
iVar = 0;
|
|
iNext = 2;
|
|
for ( i = 1; i < nPars; i++ )
|
|
{
|
|
if ( i == iNext )
|
|
{
|
|
iNext *= 2;
|
|
iVar++;
|
|
}
|
|
if ( iVar == nLutSize - 1 )
|
|
fprintf( pFile, ".names i%d p%02d p%02d n%02d\n", iVar, 2*(i-nPars/2), 2*(i-nPars/2)+1, i );
|
|
else
|
|
fprintf( pFile, ".names i%d n%02d n%02d n%02d\n", iVar, 2*i, 2*i+1, i );
|
|
fprintf( pFile, "01- 1\n" );
|
|
fprintf( pFile, "1-1 1\n" );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generates structure of L K-LUTs implementing an N-var function.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_GenFpga( char * pFileName, int nLutSize, int nLuts, int nVars )
|
|
{
|
|
int fGenerateFunc = 1;
|
|
FILE * pFile;
|
|
int nVarsLut = (1 << nLutSize); // the number of LUT variables
|
|
int nVarsLog = Abc_Base2Log( nVars + nLuts - 1 ); // the number of encoding vars
|
|
int nVarsDeg = (1 << nVarsLog); // the number of LUT variables (total)
|
|
int nParsLut = nLuts * (1 << nLutSize); // the number of LUT params
|
|
int nParsVar = nLuts * nLutSize * nVarsLog; // the number of var params
|
|
int i, j, k;
|
|
|
|
assert( nVars > 0 );
|
|
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# Structure with %d %d-LUTs for %d-var function generated by ABC on %s\n", nLuts, nLutSize, nVars, Extra_TimeStamp() );
|
|
fprintf( pFile, ".model struct%dx%d_%d\n", nLuts, nLutSize, nVars );
|
|
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nParsLut; i++ )
|
|
{
|
|
// if ( i % (1 << nLutSize) == 0 && i != (nLuts - 1) * (1 << nLutSize) )
|
|
// continue;
|
|
fprintf( pFile, " pl%02d", i );
|
|
}
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nParsVar; i++ )
|
|
fprintf( pFile, " pv%02d", i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " v%02d", i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".outputs" );
|
|
// fprintf( pFile, " v%02d", nVars + nLuts - 1 );
|
|
fprintf( pFile, " out" );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".names Gnd\n" );
|
|
fprintf( pFile, " 0\n" );
|
|
|
|
// generate function
|
|
if ( fGenerateFunc )
|
|
{
|
|
fprintf( pFile, ".names v%02d func out\n", nVars + nLuts - 1 );
|
|
fprintf( pFile, "00 1\n11 1\n" );
|
|
fprintf( pFile, ".names" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " v%02d", i );
|
|
fprintf( pFile, " func\n" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, "1" );
|
|
fprintf( pFile, " 1\n" );
|
|
}
|
|
else
|
|
fprintf( pFile, ".names v%02d out\n1 1\n", nVars + nLuts - 1 );
|
|
|
|
// generate LUTs
|
|
for ( i = 0; i < nLuts; i++ )
|
|
{
|
|
fprintf( pFile, ".subckt lut%d", nLutSize );
|
|
// generate config parameters
|
|
for ( k = 0; k < nVarsLut; k++ )
|
|
fprintf( pFile, " p%02d=pl%02d", k, i * nVarsLut + k );
|
|
// generate the inputs
|
|
for ( k = 0; k < nLutSize; k++ )
|
|
fprintf( pFile, " i%d=s%02d", k, i * nLutSize + k );
|
|
// generate the output
|
|
fprintf( pFile, " o=v%02d", nVars + i );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
|
|
// generate LUT inputs
|
|
for ( i = 0; i < nLuts; i++ )
|
|
{
|
|
for ( j = 0; j < nLutSize; j++ )
|
|
{
|
|
fprintf( pFile, ".subckt lut%d", nVarsLog );
|
|
// generate config parameters
|
|
for ( k = 0; k < nVarsDeg; k++ )
|
|
{
|
|
if ( k < nVars + nLuts - 1 && k < nVars + i )
|
|
fprintf( pFile, " p%02d=v%02d", k, k );
|
|
else
|
|
fprintf( pFile, " p%02d=Gnd", k );
|
|
}
|
|
// generate the inputs
|
|
for ( k = 0; k < nVarsLog; k++ )
|
|
fprintf( pFile, " i%d=pv%02d", k, (i * nLutSize + j) * nVarsLog + k );
|
|
// generate the output
|
|
fprintf( pFile, " o=s%02d", i * nLutSize + j );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
}
|
|
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
|
|
// generate LUTs
|
|
Abc_WriteKLut( pFile, nLutSize );
|
|
if ( nVarsLog != nLutSize )
|
|
Abc_WriteKLut( pFile, nVarsLog );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generates structure of L K-LUTs implementing an N-var function.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_GenOneHot( char * pFileName, int nVars )
|
|
{
|
|
FILE * pFile;
|
|
int i, k, Counter, nDigitsIn, nDigitsOut;
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# One-hotness condition for %d vars generated by ABC on %s\n", nVars, Extra_TimeStamp() );
|
|
fprintf( pFile, ".model 1hot_%dvars\n", nVars );
|
|
fprintf( pFile, ".inputs" );
|
|
nDigitsIn = Abc_Base10Log( nVars );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " i%0*d", nDigitsIn, i );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".outputs" );
|
|
nDigitsOut = Abc_Base10Log( nVars * (nVars - 1) / 2 );
|
|
for ( i = 0; i < nVars * (nVars - 1) / 2; i++ )
|
|
fprintf( pFile, " o%0*d", nDigitsOut, i );
|
|
fprintf( pFile, "\n" );
|
|
Counter = 0;
|
|
for ( i = 0; i < nVars; i++ )
|
|
for ( k = i+1; k < nVars; k++ )
|
|
{
|
|
fprintf( pFile, ".names i%0*d i%0*d o%0*d\n", nDigitsIn, i, nDigitsIn, k, nDigitsOut, Counter );
|
|
fprintf( pFile, "11 0\n" );
|
|
Counter++;
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generates structure of L K-LUTs implementing an N-var function.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_GenOneHotIntervals( char * pFileName, int nPis, int nRegs, Vec_Ptr_t * vOnehots )
|
|
{
|
|
Vec_Int_t * vLine;
|
|
FILE * pFile;
|
|
int i, j, k, iReg1, iReg2, Counter, Counter2, nDigitsIn, nDigitsOut;
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# One-hotness with %d vars and %d regs generated by ABC on %s\n", nPis, nRegs, Extra_TimeStamp() );
|
|
fprintf( pFile, "# Used %d intervals of 1-hot registers: { ", Vec_PtrSize(vOnehots) );
|
|
Counter = 0;
|
|
Vec_PtrForEachEntry( Vec_Int_t *, vOnehots, vLine, k )
|
|
{
|
|
fprintf( pFile, "%d ", Vec_IntSize(vLine) );
|
|
Counter += Vec_IntSize(vLine) * (Vec_IntSize(vLine) - 1) / 2;
|
|
}
|
|
fprintf( pFile, "}\n" );
|
|
fprintf( pFile, ".model 1hot_%dvars_%dregs\n", nPis, nRegs );
|
|
fprintf( pFile, ".inputs" );
|
|
nDigitsIn = Abc_Base10Log( nPis+nRegs );
|
|
for ( i = 0; i < nPis+nRegs; i++ )
|
|
fprintf( pFile, " i%0*d", nDigitsIn, i );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".outputs" );
|
|
nDigitsOut = Abc_Base10Log( Counter );
|
|
for ( i = 0; i < Counter; i++ )
|
|
fprintf( pFile, " o%0*d", nDigitsOut, i );
|
|
fprintf( pFile, "\n" );
|
|
Counter2 = 0;
|
|
Vec_PtrForEachEntry( Vec_Int_t *, vOnehots, vLine, k )
|
|
{
|
|
Vec_IntForEachEntry( vLine, iReg1, i )
|
|
Vec_IntForEachEntryStart( vLine, iReg2, j, i+1 )
|
|
{
|
|
fprintf( pFile, ".names i%0*d i%0*d o%0*d\n", nDigitsIn, nPis+iReg1, nDigitsIn, nPis+iReg2, nDigitsOut, Counter2 );
|
|
fprintf( pFile, "11 0\n" );
|
|
Counter2++;
|
|
}
|
|
}
|
|
assert( Counter == Counter2 );
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
fclose( pFile );
|
|
}
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
#include "aig/aig/aig.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generates structure of L K-LUTs implementing an N-var function.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_GenRandom( char * pFileName, int nPis )
|
|
{
|
|
FILE * pFile;
|
|
unsigned * pTruth;
|
|
int i, b, w, nWords = Abc_TruthWordNum( nPis );
|
|
int nDigitsIn;
|
|
//Aig_ManRandom( 1 );
|
|
pTruth = ABC_ALLOC( unsigned, nWords );
|
|
for ( w = 0; w < nWords; w++ )
|
|
pTruth[w] = Aig_ManRandom( 0 );
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# Random function with %d inputs generated by ABC on %s\n", nPis, Extra_TimeStamp() );
|
|
fprintf( pFile, ".model rand%d\n", nPis );
|
|
fprintf( pFile, ".inputs" );
|
|
nDigitsIn = Abc_Base10Log( nPis );
|
|
for ( i = 0; i < nPis; i++ )
|
|
fprintf( pFile, " i%0*d", nDigitsIn, i );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".outputs f\n" );
|
|
fprintf( pFile, ".names" );
|
|
nDigitsIn = Abc_Base10Log( nPis );
|
|
for ( i = 0; i < nPis; i++ )
|
|
fprintf( pFile, " i%0*d", nDigitsIn, i );
|
|
fprintf( pFile, " f\n" );
|
|
for ( i = 0; i < (1<<nPis); i++ )
|
|
if ( Abc_InfoHasBit(pTruth, i) )
|
|
{
|
|
for ( b = nPis-1; b >= 0; b-- )
|
|
fprintf( pFile, "%d", (i>>b)&1 );
|
|
fprintf( pFile, " 1\n" );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
fclose( pFile );
|
|
ABC_FREE( pTruth );
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generates structure of L K-LUTs implementing an N-var function.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_GenFsmCond( Vec_Str_t * vCond, int nPis, int Prob )
|
|
{
|
|
int i, Rand;
|
|
Vec_StrClear( vCond );
|
|
for ( i = 0; i < nPis; i++ )
|
|
{
|
|
Rand = Aig_ManRandom( 0 );
|
|
if ( Rand % 100 > Prob )
|
|
Vec_StrPush( vCond, '-' );
|
|
else if ( Rand & 1 )
|
|
Vec_StrPush( vCond, '1' );
|
|
else
|
|
Vec_StrPush( vCond, '0' );
|
|
}
|
|
Vec_StrPush( vCond, '\0' );
|
|
}
|
|
void Abc_GenFsm( char * pFileName, int nPis, int nPos, int nStates, int nLines, int ProbI, int ProbO )
|
|
{
|
|
FILE * pFile;
|
|
Vec_Wrd_t * vStates;
|
|
Vec_Str_t * vCond;
|
|
int i, iState, iState2;
|
|
int nDigits = Abc_Base10Log( nStates );
|
|
Aig_ManRandom( 1 );
|
|
vStates = Vec_WrdAlloc( nLines );
|
|
vCond = Vec_StrAlloc( 1000 );
|
|
for ( i = 0; i < nStates; )
|
|
{
|
|
iState = Aig_ManRandom( 0 ) % nStates;
|
|
if ( iState == i )
|
|
continue;
|
|
Vec_WrdPush( vStates, ((word)i << 32) | iState );
|
|
i++;
|
|
}
|
|
for ( ; i < nLines; )
|
|
{
|
|
iState = Aig_ManRandom( 0 ) % nStates;
|
|
iState2 = Aig_ManRandom( 0 ) % nStates;
|
|
if ( iState2 == iState )
|
|
continue;
|
|
Vec_WrdPush( vStates, ((word)iState << 32) | iState2 );
|
|
i++;
|
|
}
|
|
Vec_WrdSort( vStates, 0 );
|
|
// write the file
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# This random FSM was generated by ABC on %s\n", Extra_TimeStamp() );
|
|
fprintf( pFile, "# Command line was: \"genfsm -I %d -O %d -S %d -L %d -P %d -Q %d %s\"\n", nPis, nPos, nStates, nLines, ProbI, ProbO, pFileName );
|
|
fprintf( pFile, "# FSM has %d inputs, %d outputs, %d states, and %d products\n", nPis, nPos, nStates, nLines );
|
|
fprintf( pFile, ".i %d\n", nPis );
|
|
fprintf( pFile, ".o %d\n", nPos );
|
|
fprintf( pFile, ".p %d\n", nLines );
|
|
fprintf( pFile, ".s %d\n", nStates );
|
|
for ( i = 0; i < nLines; i++ )
|
|
{
|
|
Abc_GenFsmCond( vCond, nPis, ProbI );
|
|
fprintf( pFile, "%s ", Vec_StrArray(vCond) );
|
|
fprintf( pFile, "%0*d ", nDigits, (int)(Vec_WrdEntry(vStates, i) >> 32) );
|
|
fprintf( pFile, "%0*d ", nDigits, (int)(Vec_WrdEntry(vStates, i)) );
|
|
if ( nPos > 0 )
|
|
{
|
|
Abc_GenFsmCond( vCond, nPos, ProbO );
|
|
fprintf( pFile, "%s", Vec_StrArray(vCond) );
|
|
}
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
fprintf( pFile, ".e" );
|
|
fprintf( pFile, "\n" );
|
|
fclose( pFile );
|
|
Vec_WrdFree( vStates );
|
|
Vec_StrFree( vCond );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_AdderTree( FILE * pFile, int nArgs, int nBits )
|
|
{
|
|
int i, k, nDigits = Abc_Base10Log( nBits ), Log2 = Abc_Base2Log( nArgs );
|
|
assert( nArgs > 1 && nBits > 1 );
|
|
fprintf( pFile, "module adder_tree_%d_%d (\n ", nArgs, nBits );
|
|
for ( i = 0; i < nBits; i++, fprintf(pFile, "\n ") )
|
|
for ( k = 0; k < nArgs; k++ )
|
|
fprintf( pFile, " i%0*d_%0*d,", nDigits, k, nDigits, nBits-1-i );
|
|
fprintf( pFile, " z\n" );
|
|
fprintf( pFile, " );\n" );
|
|
for ( i = 0; i < nBits; i++ )
|
|
{
|
|
fprintf( pFile, " input" );
|
|
for ( k = 0; k < nArgs; k++ )
|
|
fprintf( pFile, " i%0*d_%0*d%s", nDigits, k, nDigits, nBits-1-i, k==nArgs-1 ? "":"," );
|
|
fprintf( pFile, ";\n" );
|
|
}
|
|
fprintf( pFile, " output [%d:0] z;\n", nBits+Log2-1 );
|
|
for ( i = 0; i < nArgs; i++ )
|
|
{
|
|
fprintf( pFile, " wire [%d:0] t%d = {", nBits-1, i );
|
|
for ( k = 0; k < nBits; k++ )
|
|
fprintf( pFile, " i%0*d_%0*d%s", nDigits, i, nDigits, nBits-1-k, k==nBits-1 ? "":"," );
|
|
fprintf( pFile, " };\n" );
|
|
}
|
|
for ( i = 0; i < nArgs-1; i++ )
|
|
fprintf( pFile, " wire [%d:0] s%d = t%d + %s%d;\n", nBits+Log2-1, i+1, i+1, i ? "s":"t", i );
|
|
fprintf( pFile, " assign z = s%d;\n", nArgs-1 );
|
|
fprintf( pFile, "endmodule\n\n" );
|
|
}
|
|
void Abc_GenAdderTree( char * pFileName, int nArgs, int nBits )
|
|
{
|
|
FILE * pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "// %d-argument %d-bit adder-tree generated by ABC on %s\n", nArgs, nBits, Extra_TimeStamp() );
|
|
Abc_AdderTree( pFile, nArgs, nBits );
|
|
fclose( pFile );
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generating signed Booth multiplier.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_GenSignedBoothPP( Gia_Man_t * p, int a, int b, int c, int d, int e )
|
|
{
|
|
/*
|
|
abc> lutexact -I 5 -N 7 -g F335ACC0
|
|
|
|
05 = 4'b0110( d e )
|
|
06 = 4'b0110( c d )
|
|
07 = 4'b0100( a 06 )
|
|
08 = 4'b1000( b 06 )
|
|
09 = 4'b0100( 05 07 )
|
|
10 = 4'b0110( 08 09 )
|
|
11 = 4'b0110( d 10 )
|
|
*/
|
|
int n05 = Gia_ManHashXor( p, d, e );
|
|
int n06 = Gia_ManHashXor( p, c, d );
|
|
int n07 = Gia_ManHashAnd( p, a, Abc_LitNot(n06) );
|
|
int n08 = Gia_ManHashAnd( p, b, n06 );
|
|
int n09 = Gia_ManHashAnd( p, n05, Abc_LitNot(n07) );
|
|
int n10 = Gia_ManHashXor( p, n08, n09 );
|
|
int n11 = Gia_ManHashXor( p, d, n10 );
|
|
return n11;
|
|
}
|
|
Gia_Man_t * Abc_GenSignedBoothPPTest( int nArgA, int nArgB )
|
|
{
|
|
Gia_Man_t * pNew; int i, iLit;
|
|
pNew = Gia_ManStart( 1000 );
|
|
pNew->pName = Abc_UtilStrsav( "booth" );
|
|
for ( i = 0; i < 5; i++ )
|
|
Gia_ManAppendCi(pNew);
|
|
iLit = Abc_GenSignedBoothPP( pNew, 2, 4, 6, 8, 10 );
|
|
Gia_ManAppendCo(pNew, iLit);
|
|
return pNew;
|
|
}
|
|
|
|
/*
|
|
// parametrized implementation of signed Booth multiplier
|
|
module booth #(
|
|
parameter N = 4 // bit-width of input a
|
|
,parameter M = 4 // bit-width of input b
|
|
)(
|
|
input [N-1:0] a // input data
|
|
,input [M-1:0] b // input data
|
|
,output [N+M-1:0] z // output data
|
|
);
|
|
|
|
localparam TT = 32'hF335ACC0;
|
|
localparam W = N+M+1;
|
|
localparam L = (M+1)/2;
|
|
|
|
wire [W-1:0] data1[L:0];
|
|
wire [W-1:0] data2[L:0];
|
|
|
|
assign data2[0] = data1[0];
|
|
assign z = data2[L][N+M-1:0];
|
|
|
|
wire [N+1:0] a2 = {a[N-1], a, 1'b0};
|
|
wire [M+1:0] b2 = {b[M-1], b, 1'b0};
|
|
|
|
genvar j;
|
|
generate
|
|
for ( j = 0; j < W; j = j + 1 ) begin : J
|
|
assign data1[0][j] = (j%2 == 0 && j/2 < L) ? b2[j+2] : 1'b0;
|
|
end
|
|
endgenerate
|
|
|
|
genvar k, i0, i1, i2;
|
|
generate
|
|
for ( k = 0; k < 2*L; k = k + 2 ) begin : K
|
|
|
|
for ( i0 = 0; i0 < k; i0 = i0 + 1 ) begin : I0
|
|
assign data1[k/2+1][i0] = 1'b0;
|
|
end
|
|
|
|
for ( i1 = 0; i1 <= N; i1 = i1 + 1 ) begin : I1
|
|
wire [4:0] in = {b2[k+2], b2[k+1], b2[k], a2[i1+1], a2[i1]};
|
|
assign data1[k/2+1][k+i1] = (k > 0 && i1 == N) ? ~TT[in] : TT[in];
|
|
end
|
|
|
|
assign data1[k/2+1][k+N+1] = k > 0 ? 1'b1 : data1[k/2+1][k+N];
|
|
for ( i2 = k+N+2; i2 < W; i2 = i2 + 1 ) begin : I2
|
|
assign data1[k/2+1][i2] = (k > 0 || i2 > k+N+2)? 1'b0 : ~data1[k/2+1][k+N];
|
|
end
|
|
|
|
assign data2[k/2+1] = data2[k/2] + data1[k/2+1];
|
|
|
|
end
|
|
endgenerate
|
|
|
|
endmodule
|
|
*/
|
|
|
|
Gia_Man_t * Abc_GenSignedBooth( int nArgN, int nArgM )
|
|
{
|
|
int nWidth = nArgN + nArgM + 1;
|
|
int Length = (nArgM + 1) / 2;
|
|
int i, k, iLit;
|
|
|
|
Vec_Int_t * vPPs = Vec_IntAlloc( nWidth * (Length + 1) );
|
|
Vec_Int_t * vArgN = Vec_IntAlloc( nArgN + 2 );
|
|
Vec_Int_t * vArgM = Vec_IntAlloc( nArgM + 2 );
|
|
int * pArgN = Vec_IntArray( vArgN );
|
|
int * pArgM = Vec_IntArray( vArgM );
|
|
|
|
Gia_Man_t * pTemp, * pNew;
|
|
pNew = Gia_ManStart( 1000 );
|
|
pNew->pName = Abc_UtilStrsav( "booth" );
|
|
|
|
Vec_IntPush( vArgN, 0 );
|
|
for ( i = 0; i < nArgN; i++ )
|
|
Vec_IntPush( vArgN, Gia_ManAppendCi(pNew) );
|
|
Vec_IntPush( vArgN, Vec_IntEntryLast(vArgN) );
|
|
|
|
Vec_IntPush( vArgM, 0 );
|
|
for ( i = 0; i < nArgM; i++ )
|
|
Vec_IntPush( vArgM, Gia_ManAppendCi(pNew) );
|
|
Vec_IntPush( vArgM, Vec_IntEntryLast(vArgM) );
|
|
|
|
for ( i = 0; i < nWidth; i++ )
|
|
Vec_IntPush( vPPs, (i%2 == 0 && i/2 < Length) ? pArgM[i+2] : 0 );
|
|
|
|
Gia_ManHashAlloc( pNew );
|
|
for ( k = 0; k < 2*Length; k += 2 )
|
|
{
|
|
for ( i = 0; i < k; i++ )
|
|
Vec_IntPush( vPPs, 0 );
|
|
for ( i = 0; i <= nArgN; i++ )
|
|
{
|
|
iLit = Abc_GenSignedBoothPP( pNew, pArgN[i], pArgN[i+1], pArgM[k], pArgM[k+1], pArgM[k+2] );
|
|
Vec_IntPush( vPPs, Abc_LitNotCond( iLit, k > 0 && i == nArgN ) );
|
|
}
|
|
iLit = Vec_IntEntryLast(vPPs);
|
|
Vec_IntPush( vPPs, k > 0 ? 1 : iLit );
|
|
for ( i = k+nArgN+2; i < nWidth; i++ )
|
|
Vec_IntPush( vPPs, (k > 0 || i > k+nArgN+2) ? 0 : Abc_LitNot(iLit) );
|
|
}
|
|
Gia_ManHashStop( pNew );
|
|
|
|
for ( k = 0; k <= Length; k++ )
|
|
for ( i = 0; i < nArgN+nArgM; i++ )
|
|
Gia_ManAppendCo( pNew, Vec_IntEntry(vPPs, k*(nArgN+nArgM+1) + i) );
|
|
Vec_IntFree( vPPs );
|
|
Vec_IntFree( vArgN );
|
|
Vec_IntFree( vArgM );
|
|
|
|
pNew = Gia_ManCleanup( pTemp = pNew );
|
|
Gia_ManStop( pTemp );
|
|
return pNew;
|
|
}
|
|
Mini_Aig_t * Abc_GenSignedBoothMini( int nArgN, int nArgM )
|
|
{
|
|
extern Mini_Aig_t * Gia_ManToMiniAig( Gia_Man_t * pGia );
|
|
Gia_Man_t * pGia = Abc_GenSignedBooth( nArgN, nArgM );
|
|
Mini_Aig_t * pMini = Gia_ManToMiniAig( pGia );
|
|
Gia_ManStop( pGia );
|
|
return pMini;
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_WriteBoothPartialProducts( FILE * pFile, int nVars )
|
|
{
|
|
Mini_Aig_t * p = Abc_GenSignedBoothMini( nVars, nVars );
|
|
int i, nNodes = Mini_AigNodeNum(p);
|
|
int nDigits = Abc_Base10Log( nVars );
|
|
int nDigits2 = Abc_Base10Log( 2*nVars );
|
|
int nDigits3 = Abc_Base10Log( nNodes );
|
|
int nOut = 0;
|
|
fprintf( pFile, ".names pp%0*d\n", nDigits3, 0 );
|
|
for ( i = 1; i < nNodes; i++ )
|
|
{
|
|
if ( Mini_AigNodeIsPi( p, i ) )
|
|
{
|
|
if ( i > 0 && i <= nVars )
|
|
fprintf( pFile, ".names a%0*d pp%0*d\n1 1\n", nDigits, i-1, nDigits3, i );
|
|
else if ( i > nVars && i <= 2*nVars )
|
|
fprintf( pFile, ".names b%0*d pp%0*d\n1 1\n", nDigits, i-1-nVars, nDigits3, i );
|
|
else assert( 0 );
|
|
}
|
|
else if ( Mini_AigNodeIsPo( p, i ) )
|
|
{
|
|
int Lit = Mini_AigNodeFanin0( p, i );
|
|
fprintf( pFile, ".names pp%0*d y%0*d_%0*d\n%d 1\n", nDigits3, Abc_Lit2Var(Lit), nDigits, nOut/(2*nVars), nDigits2, nOut%(2*nVars), !Abc_LitIsCompl(Lit) );
|
|
nOut++;
|
|
}
|
|
else if ( Mini_AigNodeIsAnd( p, i ) )
|
|
{
|
|
int Lit0 = Mini_AigNodeFanin0( p, i );
|
|
int Lit1 = Mini_AigNodeFanin1( p, i );
|
|
fprintf( pFile, ".names pp%0*d pp%0*d pp%0*d\n%d%d 1\n",
|
|
nDigits3, Abc_Lit2Var(Lit0), nDigits3, Abc_Lit2Var(Lit1), nDigits3, i, !Abc_LitIsCompl(Lit0), !Abc_LitIsCompl(Lit1) );
|
|
}
|
|
else assert( 0 );
|
|
}
|
|
Mini_AigStop( p );
|
|
}
|
|
void Abc_WriteBooth( FILE * pFile, int nVars )
|
|
{
|
|
int i, k, nDigits = Abc_Base10Log( nVars ), nDigits2 = Abc_Base10Log( 2*nVars );
|
|
int Length = 1+(nVars + 1)/2;
|
|
|
|
assert( nVars > 0 );
|
|
fprintf( pFile, ".model Multi%d\n", nVars );
|
|
|
|
fprintf( pFile, ".inputs" );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " a%0*d", nDigits, i );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " b%0*d", nDigits, i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
fprintf( pFile, ".outputs" );
|
|
for ( i = 0; i < 2*nVars; i++ )
|
|
fprintf( pFile, " m%0*d", nDigits2, i );
|
|
fprintf( pFile, "\n" );
|
|
|
|
Abc_WriteBoothPartialProducts( pFile, nVars );
|
|
|
|
for ( i = 0; i < 2*nVars; i++ )
|
|
fprintf( pFile, ".names x%0*d_%0*d\n", nDigits, 0, nDigits2, i );
|
|
for ( k = 0; k < Length; k++ )
|
|
{
|
|
fprintf( pFile, ".subckt ADD%d", 2*nVars );
|
|
for ( i = 0; i < 2*nVars; i++ )
|
|
fprintf( pFile, " a%0*d=x%0*d_%0*d", nDigits2, i, nDigits, k, nDigits2, i );
|
|
for ( i = 0; i < 2*nVars; i++ )
|
|
fprintf( pFile, " b%0*d=y%0*d_%0*d", nDigits2, i, nDigits, k, nDigits2, i );
|
|
for ( i = 0; i <= 2*nVars; i++ )
|
|
fprintf( pFile, " s%0*d=x%0*d_%0*d", nDigits2, i, nDigits, k+1, nDigits2, i );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
for ( i = 0; i < 2 * nVars; i++ )
|
|
fprintf( pFile, ".names x%0*d_%0*d m%0*d\n1 1\n", nDigits, k, nDigits2, i, nDigits2, i );
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
Abc_WriteAdder( pFile, 2*nVars );
|
|
}
|
|
void Abc_GenBooth( char * pFileName, int nVars )
|
|
{
|
|
FILE * pFile;
|
|
assert( nVars > 0 );
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# %d-bit signed Booth multiplier generated by ABC on %s\n", nVars, Extra_TimeStamp() );
|
|
Abc_WriteBooth( pFile, nVars );
|
|
fclose( pFile );
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_GenGraph( char * pFileName, int nPis )
|
|
{
|
|
FILE * pFile;
|
|
int i, a, b, w, nDigitsIn, nWords = Abc_TruthWordNum( nPis*(nPis-1)/2 );
|
|
unsigned * pTruth = ABC_CALLOC( unsigned, nWords );
|
|
unsigned char M[10][10] = {{0}}, C[100][2] = {{0}}, nVars = 0;
|
|
assert( nPis <= 8 );
|
|
for ( a = 0; a < nPis; a++ )
|
|
for ( b = a+1; b < nPis; b++ )
|
|
C[nVars][0] = a, C[nVars][1] = b, nVars++;
|
|
for ( i = 0; i < (1<<nVars); i++ )
|
|
{
|
|
int fChanges = 1;
|
|
for ( w = 0; w < nVars; w++ )
|
|
M[C[w][0]][C[w][1]] = M[C[w][1]][C[w][0]] = (i >> w) & 1;
|
|
while ( fChanges && !M[0][1] ) {
|
|
fChanges = 0;
|
|
for ( a = 0; a < nPis; a++ )
|
|
for ( b = 0; b < nPis; b++ )
|
|
if ( M[a][b] )
|
|
for ( w = 0; w < nPis; w++ )
|
|
if ( M[b][w] && !M[a][w] )
|
|
M[a][w] = 1, fChanges = 1;
|
|
}
|
|
if ( M[0][1] )
|
|
Abc_InfoSetBit(pTruth, i);
|
|
}
|
|
pFile = fopen( pFileName, "w" );
|
|
fprintf( pFile, "# Function with %d inputs generated by ABC on %s\n", nVars, Extra_TimeStamp() );
|
|
fprintf( pFile, ".model fun%d\n", nVars );
|
|
fprintf( pFile, ".inputs" );
|
|
nDigitsIn = Abc_Base10Log( nVars );
|
|
for ( i = 0; i < nVars; i++ )
|
|
fprintf( pFile, " i%0*d", nDigitsIn, i );
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, ".outputs f\n" );
|
|
fprintf( pFile, ".names" );
|
|
nDigitsIn = Abc_Base10Log( nVars );
|
|
for ( b = nVars-1; b >= 0; b-- )
|
|
fprintf( pFile, " i%0*d", nDigitsIn, b );
|
|
fprintf( pFile, " f\n" );
|
|
for ( i = 0; i < (1<<nVars); i++ )
|
|
if ( Abc_InfoHasBit(pTruth, i) )
|
|
{
|
|
for ( b = nVars-1; b >= 0; b-- )
|
|
fprintf( pFile, "%d", (i>>b)&1 );
|
|
fprintf( pFile, " 1\n" );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fprintf( pFile, "\n" );
|
|
fclose( pFile );
|
|
ABC_FREE( pTruth );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|