mirror of https://github.com/YosysHQ/abc.git
Procedures to generate constant-argument multipliers.
This commit is contained in:
parent
65e2add5f9
commit
c2c87aa66c
|
|
@ -247,7 +247,8 @@ void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDum
|
|||
Abc_Print( 1, "XMA stats: " );
|
||||
Abc_Print( 1,"Xor =%7d (%6.2f %%) ", nXors, 300.0 * nXors / Abc_NtkNodeNum(pNtk) );
|
||||
Abc_Print( 1,"Mux =%7d (%6.2f %%) ", nMuxs, 300.0 * nMuxs / Abc_NtkNodeNum(pNtk) );
|
||||
Abc_Print( 1,"And =%7d (%6.2f %%)", nAnds, 100.0 * nAnds / Abc_NtkNodeNum(pNtk) );
|
||||
Abc_Print( 1,"And =%7d (%6.2f %%) ", nAnds, 100.0 * nAnds / Abc_NtkNodeNum(pNtk) );
|
||||
Abc_Print( 1,"Total =%7d", nAnds + nXors + nMuxs );
|
||||
Abc_Print( 1,"\n" );
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,301 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [extraUtilMacc.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [extra]
|
||||
|
||||
Synopsis [Generates multiplier accumulators.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: extraUtilMacc.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "misc/vec/vec.h"
|
||||
#include "misc/vec/vecMem.h"
|
||||
#include "misc/extra/extra.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Wlc_ConstMultSpecOne( FILE * pFile, int n, int nBits, int nWidth )
|
||||
{
|
||||
int nTotal = nWidth+nBits;
|
||||
int Bound = 1 << (nBits-1);
|
||||
char Sign = n < 0 ? '_' : ' ';
|
||||
assert( -Bound <= n && n < Bound );
|
||||
fprintf( pFile, "// %d-bit multiplier by %d-bit constant %d generated by ABC\n", nWidth, nBits, n );
|
||||
fprintf( pFile, "module mul%03d%s (\n", Abc_AbsInt(n), n < 0 ? "_neg" : "_pos" );
|
||||
fprintf( pFile, " input [%d:0] i,\n", nWidth-1 );
|
||||
fprintf( pFile, " output [%d:0] o\n", nWidth-1 );
|
||||
fprintf( pFile, ");\n" );
|
||||
fprintf( pFile, " wire [%d:0] c = %d\'h%x;\n", nBits-1, nBits, Abc_AbsInt(n) );
|
||||
fprintf( pFile, " wire [%d:0] I = {{%d{i[%d]}}, i};\n", nTotal-1, nBits, nWidth-1 );
|
||||
fprintf( pFile, " wire [%d:0] m = I * c;\n", nTotal-1 );
|
||||
fprintf( pFile, " wire [%d:0] t = %cm;\n", nTotal-1, n < 0 ? '-' : ' ' );
|
||||
fprintf( pFile, " assign o = t[%d:%d];\n", nTotal-1, nBits );
|
||||
fprintf( pFile, "endmodule\n\n" );
|
||||
}
|
||||
void Wlc_ConstMultSpecTest()
|
||||
{
|
||||
int nBits = 8;
|
||||
int nWidth = 16;
|
||||
int Bound = 1 << (nBits-1);
|
||||
int i;
|
||||
char Buffer[100];
|
||||
FILE * pFile;
|
||||
for ( i = -Bound; i < Bound; i++ )
|
||||
{
|
||||
sprintf( Buffer, "const_mul//spec%03d.v", 0xFF & i );
|
||||
pFile = fopen( Buffer, "wb" );
|
||||
Wlc_ConstMultSpecOne( pFile, i, nBits, nWidth );
|
||||
fclose( pFile );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Wlc_ConstMultGenerate( int nBits )
|
||||
{
|
||||
unsigned Mask = Abc_InfoMask( nBits );
|
||||
Vec_Wec_t * vDivs = Vec_WecStart( 2*nBits );
|
||||
Vec_Int_t * vOne, * vTwo, * vThree;
|
||||
unsigned * pPlace = ABC_CALLOC( unsigned, (1 << nBits) );
|
||||
int n, a, b, One, Two, i, k, New, Bound = 1 << (nBits-1);
|
||||
// skip trivial
|
||||
pPlace[0] = ~0;
|
||||
pPlace[1] = ~0;
|
||||
pPlace[Mask & (-1)] = ~0;
|
||||
// skip div by 2
|
||||
for ( i = 2; i < (1 << nBits); i++ )
|
||||
if ( (i & 1) == 0 )
|
||||
pPlace[i] = ~0;
|
||||
// collect trivial
|
||||
printf( "Generating numbers using %d adders:\n", 0 );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
{
|
||||
Vec_WecPush( vDivs, 0, 1<<i );
|
||||
printf( "%d = %d << %d\n", 1<<i, 1, i );
|
||||
}
|
||||
// generate for each adder count
|
||||
for ( n = 1; n < nBits; n++ )
|
||||
{
|
||||
// quit if all of them are finished
|
||||
for ( a = 1; a < (1 << nBits); a++ )
|
||||
if ( pPlace[a] == 0 )
|
||||
break;
|
||||
if ( a == (1 << nBits) )
|
||||
break;
|
||||
|
||||
printf( "Generating numbers using %d adders:\n", n );
|
||||
vThree = Vec_WecEntry( vDivs, n );
|
||||
for ( a = 0; a < nBits; a++ )
|
||||
for ( b = 0; b < nBits; b++ )
|
||||
{
|
||||
if ( a + b != n-1 )
|
||||
continue;
|
||||
vOne = Vec_WecEntry( vDivs, a );
|
||||
vTwo = Vec_WecEntry( vDivs, b );
|
||||
Vec_IntForEachEntry( vOne, One, i )
|
||||
Vec_IntForEachEntry( vTwo, Two, k )
|
||||
{
|
||||
New = One + Two;
|
||||
if ( New >= -Bound && New < Bound && pPlace[Mask & New] == 0 )
|
||||
{
|
||||
if ( New > 0 )
|
||||
Vec_IntPush( vThree, New );
|
||||
|
||||
pPlace[Mask & New] = (One << 16) | Two;
|
||||
printf( "%d = %d + %d\n", New, One, Two );
|
||||
}
|
||||
New = One - Two;
|
||||
if ( New >= -Bound && New < Bound && pPlace[Mask & New] == 0 )
|
||||
{
|
||||
if ( New > 0 )
|
||||
Vec_IntPush( vThree, New );
|
||||
|
||||
pPlace[Mask & New] = (One << 16) | Two | (1 << 15);
|
||||
printf( "%d = %d - %d\n", New, One, Two );
|
||||
}
|
||||
New = Two - One;
|
||||
if ( New >= -Bound && New < Bound && pPlace[Mask & New] == 0 )
|
||||
{
|
||||
if ( New > 0 )
|
||||
Vec_IntPush( vThree, New );
|
||||
|
||||
pPlace[Mask & New] = (Two << 16) | One | (1 << 15);
|
||||
printf( "%d = %d - %d\n", New, Two, One );
|
||||
}
|
||||
}
|
||||
printf( "Adding one incrementor:\n" );
|
||||
Vec_IntForEachEntry( vThree, One, i )
|
||||
{
|
||||
if ( One < 0 )
|
||||
continue;
|
||||
New = -One;
|
||||
if ( pPlace[Mask & New] == 0 )
|
||||
{
|
||||
pPlace[Mask & New] = One << 16;
|
||||
printf( "-%d = ~%d + 1\n", One, One );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vec_WecPrint( vDivs, 0 );
|
||||
Vec_WecFree( vDivs );
|
||||
//ABC_FREE( pPlace );
|
||||
return pPlace;
|
||||
}
|
||||
void Wlc_ConstMultGenTest0()
|
||||
{
|
||||
int nBits = 8;
|
||||
unsigned * p = Wlc_ConstMultGenerate( nBits );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
void Wlc_ConstMultGenOne_rec( FILE * pFile, unsigned * p, int n, int nBits, int nWidth )
|
||||
{
|
||||
unsigned Mask = Abc_InfoMask( nBits );
|
||||
unsigned New = Mask & (unsigned)n;
|
||||
int nTotal = nWidth+nBits;
|
||||
int One = p[New] >> 16;
|
||||
int Two = p[New] & 0x7FFF;
|
||||
char Sign = n < 0 ? 'N' : 'n';
|
||||
char Oper = ((p[New] >> 15) & 1) ? '-' : '+';
|
||||
if ( p[New] == ~0 )
|
||||
{
|
||||
// count trailing zeros
|
||||
int nn, nZeros;
|
||||
for ( nZeros = 0; nZeros < nBits; nZeros++ )
|
||||
if ( (n >> nZeros) & 1 )
|
||||
break;
|
||||
nn = n >> nZeros;
|
||||
if ( nn == -1 )
|
||||
fprintf( pFile, " wire [%d:0] N1 = -n1;\n", nTotal-1 );
|
||||
if ( Abc_AbsInt(nn) != 1 )
|
||||
Wlc_ConstMultGenOne_rec( pFile, p, nn, nBits, nWidth );
|
||||
if ( nZeros > 0 )
|
||||
fprintf( pFile, " wire [%d:0] %c%d = %c%d << %d;\n", nTotal-1, Sign, Abc_AbsInt(n), Sign, Abc_AbsInt(nn), nZeros );
|
||||
}
|
||||
else if ( One && Two ) // add/sub
|
||||
{
|
||||
Wlc_ConstMultGenOne_rec( pFile, p, One, nBits, nWidth );
|
||||
Wlc_ConstMultGenOne_rec( pFile, p, Two, nBits, nWidth );
|
||||
fprintf( pFile, " wire [%d:0] %c%d = n%d %c n%d;\n", nTotal-1, Sign, Abc_AbsInt(n), One, Oper, Two );
|
||||
}
|
||||
else if ( Two == 0 ) // minus
|
||||
{
|
||||
Wlc_ConstMultGenOne_rec( pFile, p, One, nBits, nWidth );
|
||||
fprintf( pFile, " wire [%d:0] N%d = -n%d;\n", nTotal-1, One, One );
|
||||
}
|
||||
}
|
||||
void Wlc_ConstMultGenMult( FILE * pFile, unsigned * p, int n, int nBits, int nWidth )
|
||||
{
|
||||
int nTotal = nWidth+nBits;
|
||||
int Bound = 1 << (nBits-1);
|
||||
char Sign = n < 0 ? 'N' : 'n';
|
||||
assert( -Bound <= n && n < Bound );
|
||||
fprintf( pFile, "// %d-bit multiplier by %d-bit constant %d generated by ABC\n", nWidth, nBits, n );
|
||||
fprintf( pFile, "module mul%03d%s (\n", Abc_AbsInt(n), n < 0 ? "_neg" : "_pos" );
|
||||
fprintf( pFile, " input [%d:0] i,\n", nWidth-1 );
|
||||
fprintf( pFile, " output [%d:0] o\n", nWidth-1 );
|
||||
fprintf( pFile, ");\n" );
|
||||
if ( n == 0 )
|
||||
fprintf( pFile, " assign o = %d\'h0;\n", nWidth );
|
||||
else
|
||||
{
|
||||
fprintf( pFile, " wire [%d:0] n1 = {{%d{i[%d]}}, i};\n", nTotal-1, nBits, nWidth-1 );
|
||||
Wlc_ConstMultGenOne_rec( pFile, p, n, nBits, nWidth );
|
||||
fprintf( pFile, " assign o = %c%d[%d:%d];\n", Sign, Abc_AbsInt(n), nTotal-1, nBits );
|
||||
}
|
||||
fprintf( pFile, "endmodule\n\n" );
|
||||
}
|
||||
void Wlc_ConstMultGenMacc( FILE * pFile, unsigned * p, int n, int nBits, int nWidth )
|
||||
{
|
||||
int nTotal = nWidth+nBits;
|
||||
int Bound = 1 << (nBits-1);
|
||||
char Sign = n < 0 ? 'N' : 'n';
|
||||
assert( -Bound <= n && n < Bound );
|
||||
fprintf( pFile, "// %d-bit multiplier-accumulator by %d-bit constant %d generated by ABC\n", nWidth, nBits, n );
|
||||
fprintf( pFile, "module macc%03d%s (\n", Abc_AbsInt(n), n < 0 ? "_neg" : "_pos" );
|
||||
fprintf( pFile, " input [%d:0] i,\n", nWidth-1 );
|
||||
fprintf( pFile, " input [%d:0] c,\n", nWidth-1 );
|
||||
fprintf( pFile, " output [%d:0] o\n", nWidth-1 );
|
||||
fprintf( pFile, ");\n" );
|
||||
if ( n == 0 )
|
||||
fprintf( pFile, " assign o = %d\'h0;\n", nWidth );
|
||||
else
|
||||
{
|
||||
fprintf( pFile, " wire [%d:0] n1 = {{%d{i[%d]}}, i};\n", nTotal-1, nBits, nWidth-1 );
|
||||
Wlc_ConstMultGenOne_rec( pFile, p, n, nBits, nWidth );
|
||||
fprintf( pFile, " wire [%d:0] s = %c%d[%d:%d];\n", nWidth-1, Sign, Abc_AbsInt(n), nTotal-1, nBits );
|
||||
fprintf( pFile, " assign o = s + c;\n" );
|
||||
}
|
||||
fprintf( pFile, "endmodule\n\n" );
|
||||
}
|
||||
void Wlc_ConstMultGenTest()
|
||||
{
|
||||
int nBits = 8;
|
||||
int nWidth = 16;
|
||||
int Bound = 1 << (nBits-1);
|
||||
unsigned * p = Wlc_ConstMultGenerate( nBits );
|
||||
int i;
|
||||
char Buffer[100];
|
||||
FILE * pFile;
|
||||
for ( i = -Bound; i < Bound; i++ )
|
||||
{
|
||||
sprintf( Buffer, "const_mul//macc%03d.v", 0xFF & i );
|
||||
pFile = fopen( Buffer, "wb" );
|
||||
Wlc_ConstMultGenMacc( pFile, p, i, nBits, nWidth );
|
||||
fclose( pFile );
|
||||
}
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -4,6 +4,7 @@ SRC += src/misc/extra/extraUtilBitMatrix.c \
|
|||
src/misc/extra/extraUtilDsd.c \
|
||||
src/misc/extra/extraUtilEnum.c \
|
||||
src/misc/extra/extraUtilFile.c \
|
||||
src/misc/extra/extraUtilMacc.c \
|
||||
src/misc/extra/extraUtilMaj.c \
|
||||
src/misc/extra/extraUtilMemory.c \
|
||||
src/misc/extra/extraUtilMisc.c \
|
||||
|
|
|
|||
Loading…
Reference in New Issue