From de71ef44cd679a4277c869e759bc9bccc3dbb417 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 26 Nov 2016 17:06:54 -0800 Subject: New command to profile arithmetic logic cones. --- abclib.dsp | 4 ++ src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 6 ++ src/base/wlc/wlcCom.c | 48 +++++++++++++- src/base/wlc/wlcNtk.c | 73 ++++++++++++++++----- src/base/wlc/wlcWin.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 282 insertions(+), 16 deletions(-) create mode 100644 src/base/wlc/wlcWin.c diff --git a/abclib.dsp b/abclib.dsp index 513bef97..a098dfc2 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -807,6 +807,10 @@ SOURCE=.\src\base\wlc\wlcStdin.c # End Source File # Begin Source File +SOURCE=.\src\base\wlc\wlcWin.c +# End Source File +# Begin Source File + SOURCE=.\src\base\wlc\wlcWriteVer.c # End Source File # End Group diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index 081be200..5a95a63f 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -8,4 +8,5 @@ SRC += src/base/wlc/wlcAbs.c \ src/base/wlc/wlcReadVer.c \ src/base/wlc/wlcSim.c \ src/base/wlc/wlcStdin.c \ + src/base/wlc/wlcWin.c \ src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 90596093..1df3e5e9 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -244,6 +244,8 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) #define Wlc_ObjForEachFanin( pObj, iFanin, i ) \ for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ ) +#define Wlc_ObjForEachFaninObj( p, pObj, pFanin, i ) \ + for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((pFanin) = Wlc_NtkObj(p, Wlc_ObjFaninId(pObj, i))), 1); i++ ) #define Wlc_ObjForEachFaninReverse( pObj, iFanin, i ) \ for ( i = Wlc_ObjFaninNum(pObj) - 1; (i >= 0) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i-- ) @@ -272,6 +274,8 @@ extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj ); extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type ); extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ); extern void Wlc_NtkFree( Wlc_Ntk_t * p ); +extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ); +extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray ); extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ); extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ); @@ -287,6 +291,8 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p ); extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd ); /*=== wlcReadVer.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ); +/*=== wlcWin.c =============================================================*/ +extern void Wlc_WinProfileArith( Wlc_Ntk_t * p ); /*=== wlcWriteVer.c ========================================================*/ extern void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName, int fAddCos, int fNoFlops ); diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 7856fae8..f3eb6dd7 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -34,6 +34,7 @@ static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } @@ -67,6 +68,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); } @@ -543,6 +545,50 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" ); + return 0; + } + Wlc_WinProfileArith( pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%profile [-vh]\n" ); + Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] @@ -575,7 +621,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pNtk == NULL ) { - Abc_Print( 1, "Abc_CommandBlast(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" ); return 0; } // transform diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 5a08cd99..6f396771 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -44,8 +44,8 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { ">>>", // 10: shift right (arithmetic) "<<", // 11: shift left "<<<", // 12: shift left (arithmetic) - "rotateR", // 13: rotate right - "rotateL", // 14: rotate left + "rotR", // 13: rotate right + "rotL", // 14: rotate left "~", // 15: bitwise NOT "&", // 16: bitwise AND "|", // 17: bitwise OR @@ -55,8 +55,8 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { "~^", // 21: bitwise NXOR "[:]", // 22: bit selection "{,}", // 23: bit concatenation - "zeroPad", // 24: zero padding - "signExt", // 25: sign extension + "zPad", // 24: zero padding + "sExt", // 25: sign extension "!", // 26: logic NOT "=>", // 27: logic implication "&&", // 28: logic AND @@ -83,7 +83,7 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { "**", // 49: arithmetic power "-", // 50: arithmetic minus "sqrt", // 51: integer square root - "square", // 52: integer square + "squar", // 52: integer square "table", // 53: bit table NULL // 54: unused }; @@ -471,6 +471,57 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) Vec_VecFree( (Vec_Vec_t *)vOccurs ); Vec_IntFree( vAnds ); } +void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) +{ + printf( "%8d : ", Wlc_ObjId(p, pObj) ); + printf( "%3d%s", Wlc_ObjRange(pObj), Wlc_ObjIsSigned(pObj) ? "s" : " " ); + if ( pObj->Type == WLC_OBJ_CONST ) + printf( " " ); + else + { + printf( " = %3d%s %5s ", Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin0(p, pObj)) ? "s" : " ", Wlc_Names[(int)pObj->Type] ); + if ( Wlc_ObjFaninNum(pObj) > 1 ) + printf( "%3d%s ", Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin1(p, pObj)) ? "s" : " " ); + else + printf( " " ); + if ( Wlc_ObjFaninNum(pObj) > 2 ) + printf( "%3d%s ", Wlc_ObjRange(Wlc_ObjFanin2(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin2(p, pObj)) ? "s" : " " ); + else + printf( " " ); + } + printf( " : " ); + printf( "%-12s", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) ); + if ( pObj->Type == WLC_OBJ_CONST ) + { + printf( " = %d\'%sh", Wlc_ObjRange(pObj), Wlc_ObjIsSigned(pObj) ? "s":"" ); + if ( pObj->fXConst ) + { + int k; + for ( k = 0; k < (Wlc_ObjRange(pObj) + 3) / 4; k++ ) + printf( "x" ); + } + else + Abc_TtPrintHexArrayRev( stdout, (word *)Wlc_ObjConstValue(pObj), (Wlc_ObjRange(pObj) + 3) / 4 ); + } + else + { + printf( " = %-12s %5s ", Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)), Wlc_Names[(int)pObj->Type] ); + if ( Wlc_ObjFaninNum(pObj) > 1 ) + printf( "%-12s ", Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) ); + else + printf( " " ); + if ( Wlc_ObjFaninNum(pObj) > 2 ) + printf( "%-12s ", Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)) ); + } + printf( "\n" ); +} +void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray ) +{ + Wlc_Obj_t * pObj; + int i; + Wlc_NtkForEachObjVec( vArray, p, pObj, i ) + Wlc_NtkPrintNode( p, pObj ); +} void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ) { Wlc_Obj_t * pObj; @@ -480,16 +531,8 @@ void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ) { if ( (int)pObj->Type != Type ) continue; - printf( "%8d :", Counter++ ); - printf( "%8d : ", i ); - printf( "%3d%s = ", Wlc_ObjRange(pObj), Wlc_ObjIsSigned(pObj) ? "s" : " " ); - printf( "%3d%s %s ", Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin0(p, pObj)) ? "s" : " ", Wlc_Names[Type] ); - printf( "%3d%s ", Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin1(p, pObj)) ? "s" : " " ); - printf( " : " ); - printf( "%-12s = ", Wlc_ObjName(p, i) ); - printf( "%-12s %s ", Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)), Wlc_Names[Type] ); - printf( "%-12s ", Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) ); - printf( "\n" ); + printf( "%8d :", Counter++ ); + Wlc_NtkPrintNode( p, pObj ); } } void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) diff --git a/src/base/wlc/wlcWin.c b/src/base/wlc/wlcWin.c new file mode 100644 index 00000000..4dc748f4 --- /dev/null +++ b/src/base/wlc/wlcWin.c @@ -0,0 +1,166 @@ +/**CFile**************************************************************** + + FileName [wlcWin.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Parses several flavors of word-level Verilog.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcWin.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" +#include "base/abc/abc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collect arithmetic nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_ObjIsArithm( Wlc_Obj_t * pObj ) +{ + return pObj->Type == WLC_OBJ_CONST || + pObj->Type == WLC_OBJ_BUF || pObj->Type == WLC_OBJ_BIT_NOT || + pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT || +// pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_BIT_CONCAT || + pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || + pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_MINUS; +} +int Wlc_ObjIsArithmReal( Wlc_Obj_t * pObj ) +{ + return pObj->Type == WLC_OBJ_BIT_NOT || + pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || + pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_MINUS; +} +int Wlc_ManCountArithmReal( Wlc_Ntk_t * p, Vec_Int_t * vNodes ) +{ + Wlc_Obj_t * pObj; + int i, Counter = 0; + Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) + Counter += Wlc_ObjIsArithmReal( pObj ); + return Counter; +} +int Wlc_ObjHasArithm_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) +{ + if ( pObj->Type == WLC_OBJ_CONST ) + return 0; + if ( pObj->Type == WLC_OBJ_BUF || pObj->Type == WLC_OBJ_BIT_NOT || + pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT ) + return Wlc_ObjHasArithm_rec( p, Wlc_ObjFanin0(p, pObj) ); + return pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || + pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_MINUS; +} +int Wlc_ObjHasArithmFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) +{ + Wlc_Obj_t * pFanin; int i; + assert( !Wlc_ObjHasArithm_rec(p, pObj) ); + Wlc_ObjForEachFaninObj( p, pObj, pFanin, i ) + if ( Wlc_ObjHasArithm_rec(p, pFanin) ) + return 1; + return 0; +} +void Wlc_WinCompute_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vLeaves, Vec_Int_t * vNodes ) +{ + Wlc_Obj_t * pFanin; int i; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( !Wlc_ObjIsArithm(pObj) ) + { + Vec_IntPush( vLeaves, Wlc_ObjId(p, pObj) ); + return; + } + Wlc_ObjForEachFaninObj( p, pObj, pFanin, i ) + Wlc_WinCompute_rec( p, pFanin, vLeaves, vNodes ); + Vec_IntPush( vNodes, Wlc_ObjId(p, pObj) ); +} +void Wlc_WinCleanMark_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) +{ + Wlc_Obj_t * pFanin; int i; + if ( !pObj->Mark ) + return; + pObj->Mark = 0; + Wlc_ObjForEachFaninObj( p, pObj, pFanin, i ) + Wlc_WinCleanMark_rec( p, pFanin ); +} +void Wlc_WinCompute( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vLeaves, Vec_Int_t * vNodes ) +{ + Vec_IntClear( vLeaves ); + Vec_IntClear( vNodes ); + if ( Wlc_ObjHasArithm_rec(p, pObj) ) + { + Wlc_WinCompute_rec( p, pObj, vLeaves, vNodes ); + Wlc_WinCleanMark_rec( p, pObj ); + } + else if ( Wlc_ObjHasArithmFanins(p, pObj) ) + { + Wlc_Obj_t * pFanin; int i; + Wlc_ObjForEachFaninObj( p, pObj, pFanin, i ) + if ( Wlc_ObjHasArithm_rec(p, pFanin) ) + Wlc_WinCompute_rec( p, pFanin, vLeaves, vNodes ); + Wlc_ObjForEachFaninObj( p, pObj, pFanin, i ) + if ( Wlc_ObjHasArithm_rec(p, pFanin) ) + Wlc_WinCleanMark_rec( p, pFanin ); + } + else assert( 0 ); +} +void Wlc_WinProfileArith( Wlc_Ntk_t * p ) +{ + Vec_Int_t * vLeaves = Vec_IntAlloc( 1000 ); + Vec_Int_t * vNodes = Vec_IntAlloc( 1000 ); + Wlc_Obj_t * pObj; int i, Count = 0; + Wlc_NtkForEachObj( p, pObj, i ) + pObj->Mark = 0; + Wlc_NtkForEachObj( p, pObj, i ) + if ( Wlc_ObjHasArithm_rec(p, pObj) ? Wlc_ObjIsCo(pObj) : Wlc_ObjHasArithmFanins(p, pObj) ) + { + Wlc_WinCompute( p, pObj, vLeaves, vNodes ); + if ( Wlc_ManCountArithmReal(p, vNodes) < 2 ) + continue; + + printf( "Arithmetic cone of node %d (%s):\n", Wlc_ObjId(p, pObj), Wlc_ObjName(p, Wlc_ObjId(p, pObj)) ); + Wlc_NtkPrintNode( p, pObj ); + Vec_IntReverseOrder( vNodes ); + Wlc_NtkPrintNodeArray( p, vNodes ); + printf( "\n" ); + Count++; + } + Wlc_NtkForEachObj( p, pObj, i ) + assert( pObj->Mark == 0 ); + printf( "Finished printing %d arithmetic cones.\n", Count ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vNodes ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3