From c2c87aa66c84f0466906c170a956424c35df78c0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 8 Jan 2019 12:06:50 -0800 Subject: Procedures to generate constant-argument multipliers. --- src/base/abci/abcPrint.c | 3 +- src/misc/extra/extraUtilMacc.c | 301 +++++++++++++++++++++++++++++++++++++++++ src/misc/extra/module.make | 1 + 3 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 src/misc/extra/extraUtilMacc.c diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index ea91619c..708b8946 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -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; } 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 +#include +#include +#include + +#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<= -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 \ -- cgit v1.2.3