From 867600b766cc37218d619bec0c3fbbc1f700d72e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 5 Jun 2018 16:23:04 -0700 Subject: Supporting the decoder primitive in NDR and bit-blasting. --- src/base/wlc/wlc.h | 3 ++- src/base/wlc/wlcBlast.c | 21 +++++++++++++++++++++ src/base/wlc/wlcCom.c | 2 +- src/base/wlc/wlcNdr.c | 2 ++ src/base/wlc/wlcNtk.c | 5 ++++- src/base/wlc/wlcWriteVer.c | 39 ++++++++++++++++++++++++++++++++++++++- 6 files changed, 68 insertions(+), 4 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index aacd27a7..e947e36b 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -100,7 +100,8 @@ typedef enum { WLC_OBJ_WRITE, // 55: write port WLC_OBJ_ARI_ADDSUB, // 56: adder-subtractor WLC_OBJ_SEL, // 57: positionally encoded selector - WLC_OBJ_NUMBER // 57: unused + WLC_OBJ_DEC, // 58: decoder + WLC_OBJ_NUMBER // 59: unused } Wlc_ObjType_t; // when adding new types, remember to update table Wlc_Names in "wlcNtk.c" diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 8ced5b60..13d23fba 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -836,6 +836,18 @@ void Wlc_BlastSquare( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_WecFree( vProds ); Vec_WecFree( vLevels ); } +void Wlc_BlastDecoder( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes ) +{ + int i, k, nMints = 1 << nNum; + Vec_IntClear( vRes ); + for ( i = 0; i < nMints; i++ ) + { + int iMint = 1; + for ( k = 0; k < nNum; k++ ) + iMint = Gia_ManHashAnd( pNew, iMint, Abc_LitNotCond(pNum[k], !((i >> k) & 1)) ); + Vec_IntPush( vRes, iMint ); + } +} void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla ) { Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 ); @@ -1514,6 +1526,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) else Vec_IntShrink( vRes, nRange ); } + else if ( pObj->Type == WLC_OBJ_DEC ) + { + int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange0, 0 ); + Wlc_BlastDecoder( pNew, pArg0, nRange0, vTemp2, vRes ); + if ( nRange > Vec_IntSize(vRes) ) + Vec_IntFillExtra( vRes, nRange, 0 ); + else + Vec_IntShrink( vRes, nRange ); + } else if ( pObj->Type == WLC_OBJ_TABLE ) Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes ); else assert( 0 ); diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 73b130e7..52214d2d 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -1676,7 +1676,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc ); //pNtk = Wlc_NtkDupSingleNodes( pNtk ); //Wlc_AbcUpdateNtk( pAbc, pNtk ); - Ndr_ModuleTestSelSel(); + Ndr_ModuleTestDec(); //pNtk = Wlc_NtkMemAbstractTest( pNtk ); //Wlc_AbcUpdateNtk( pAbc, pNtk ); return 0; diff --git a/src/base/wlc/wlcNdr.c b/src/base/wlc/wlcNdr.c index 3e6600c3..5f3bc12a 100644 --- a/src/base/wlc/wlcNdr.c +++ b/src/base/wlc/wlcNdr.c @@ -71,6 +71,7 @@ int Ndr_TypeNdr2Wlc( int Type ) if ( Type == ABC_OPER_LOGIC_XOR ) return WLC_OBJ_LOGIC_XOR; // 30: logic XOR if ( Type == ABC_OPER_SEL_NMUX ) return WLC_OBJ_MUX; // 08: multiplexer if ( Type == ABC_OPER_SEL_SEL ) return WLC_OBJ_SEL; // 57: selector + if ( Type == ABC_OPER_SEL_DEC ) return WLC_OBJ_DEC; // 58: decoder if ( Type == ABC_OPER_COMP_EQU ) return WLC_OBJ_COMP_EQU; // 31: compare equal if ( Type == ABC_OPER_COMP_NOTEQU ) return WLC_OBJ_COMP_NOTEQU; // 32: compare not equal if ( Type == ABC_OPER_COMP_LESS ) return WLC_OBJ_COMP_LESS; // 33: compare less @@ -129,6 +130,7 @@ int Ndr_TypeWlc2Ndr( int Type ) if ( Type == WLC_OBJ_LOGIC_OR ) return ABC_OPER_LOGIC_OR; // 29: logic OR if ( Type == WLC_OBJ_LOGIC_XOR ) return ABC_OPER_LOGIC_XOR; // 30: logic XOR if ( Type == WLC_OBJ_SEL ) return ABC_OPER_SEL_SEL; // 57: selector + if ( Type == WLC_OBJ_DEC ) return ABC_OPER_SEL_DEC; // 58: decoder if ( Type == WLC_OBJ_COMP_EQU ) return ABC_OPER_COMP_EQU; // 31: compare equal if ( Type == WLC_OBJ_COMP_NOTEQU ) return ABC_OPER_COMP_NOTEQU; // 32: compare not equal if ( Type == WLC_OBJ_COMP_LESS ) return ABC_OPER_COMP_LESS; // 33: compare less diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index b8a4b9b1..0d8374c7 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -87,7 +87,10 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { "table", // 53: bit table "READ", // 54: mem read port "WRITE", // 55: mem write port - NULL // 56: unused + "addsub", // 56: adder/subtractor + "sel", // 57: selector + "dec", // 58: decoder + NULL // 58: unused }; char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index dbf24e68..a7d29187 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -192,7 +192,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) continue; fprintf( pFile, " assign " ); } - else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_FF ) + else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_FF || pObj->Type == WLC_OBJ_SEL ) fprintf( pFile, "reg %s ", Range ); else fprintf( pFile, "wire %s ", Range ); @@ -275,12 +275,49 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, " : %s = ", Wlc_ObjName(p, i) ); fprintf( pFile, "%s ;\n", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) ); } + fprintf( pFile, " " ); + fprintf( pFile, "default" ); + fprintf( pFile, " : %s = ", Wlc_ObjName(p, i) ); + fprintf( pFile, "%d\'b", Wlc_ObjRange(pObj) ); + for ( j = Wlc_ObjRange(pObj)-1; j >= 0; j-- ) + fprintf( pFile, "%d", 0 ); + fprintf( pFile, " ;\n" ); fprintf( pFile, " " ); fprintf( pFile, "endcase\n" ); fprintf( pFile, " " ); fprintf( pFile, "end\n" ); continue; } + else if ( pObj->Type == WLC_OBJ_DEC ) + { + int nRange = Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)); + assert( (1 << nRange) == Wlc_ObjRange(pObj) ); + fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) ); + for ( k = 0; k < Wlc_ObjRange(pObj); k++ ) + { + fprintf( pFile, " " ); + fprintf( pFile, "wire " ); + fprintf( pFile, "%s_", Wlc_ObjName(p, i) ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 ); + fprintf( pFile, " = " ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%s%s%s[%d]", + j ? " & ":"", ((k >> (nRange-1-j)) & 1) ? " ":"~", + Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 0)), nRange-1-j ); + fprintf( pFile, " ;\n" ); + } + fprintf( pFile, " " ); + fprintf( pFile, "assign %s = { ", Wlc_ObjName(p, i) ); + for ( k = Wlc_ObjRange(pObj)-1; k >= 0; k-- ) + { + fprintf( pFile, "%s%s_", k < Wlc_ObjRange(pObj)-1 ? ", ":"", Wlc_ObjName(p, i) ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 ); + } + fprintf( pFile, " } ;\n" ); + continue; + } else if ( pObj->Type == WLC_OBJ_READ || pObj->Type == WLC_OBJ_WRITE ) { if ( p->fMemPorts ) -- cgit v1.2.3