summaryrefslogtreecommitdiffstats
path: root/src/misc/extra
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2019-01-08 12:06:50 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2019-01-08 12:06:50 -0800
commitc2c87aa66c84f0466906c170a956424c35df78c0 (patch)
treea9772da854f4528697233c65d69cad2a07a473df /src/misc/extra
parent65e2add5f9ff804c64303c1c7b36141a25ea21b7 (diff)
downloadabc-c2c87aa66c84f0466906c170a956424c35df78c0.tar.gz
abc-c2c87aa66c84f0466906c170a956424c35df78c0.tar.bz2
abc-c2c87aa66c84f0466906c170a956424c35df78c0.zip
Procedures to generate constant-argument multipliers.
Diffstat (limited to 'src/misc/extra')
-rw-r--r--src/misc/extra/extraUtilMacc.c301
-rw-r--r--src/misc/extra/module.make1
2 files changed, 302 insertions, 0 deletions
diff --git a/src/misc/extra/extraUtilMacc.c b/src/misc/extra/extraUtilMacc.c
new file mode 100644
index 00000000..1d058f3b
--- /dev/null
+++ b/src/misc/extra/extraUtilMacc.c
@@ -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
+
diff --git a/src/misc/extra/module.make b/src/misc/extra/module.make
index 9db290e5..3d54796b 100644
--- a/src/misc/extra/module.make
+++ b/src/misc/extra/module.make
@@ -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 \