diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2019-11-18 00:17:40 +0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2019-11-18 00:17:40 +0800 |
commit | dd5a1f5d3001429bc3abb6fd3a7fc04ff28ee6c5 (patch) | |
tree | ae6dbbb0f84d1a24e2a3e9490e4f1858d21f260a | |
parent | 548fa9d45bb389fe388892ec7b2dd17727b06dc5 (diff) | |
download | abc-dd5a1f5d3001429bc3abb6fd3a7fc04ff28ee6c5.tar.gz abc-dd5a1f5d3001429bc3abb6fd3a7fc04ff28ee6c5.tar.bz2 abc-dd5a1f5d3001429bc3abb6fd3a7fc04ff28ee6c5.zip |
Enable blasting LUTs in NDR.
-rw-r--r-- | src/aig/miniaig/ndr.h | 51 | ||||
-rw-r--r-- | src/base/wlc/wlc.h | 1 | ||||
-rw-r--r-- | src/base/wlc/wlcBlast.c | 16 | ||||
-rw-r--r-- | src/base/wlc/wlcNdr.c | 25 | ||||
-rw-r--r-- | src/base/wlc/wlcNtk.c | 1 | ||||
-rw-r--r-- | src/base/wlc/wlcWriteVer.c | 6 |
6 files changed, 93 insertions, 7 deletions
diff --git a/src/aig/miniaig/ndr.h b/src/aig/miniaig/ndr.h index 05b7fef0..8d630159 100644 --- a/src/aig/miniaig/ndr.h +++ b/src/aig/miniaig/ndr.h @@ -207,17 +207,25 @@ static inline void Ndr_DataPushArray( Ndr_Data_t * p, int Type, int nArray, int memcpy( p->pBody + p->nSize, pArray, (size_t)4*nArray ); p->nSize += nArray; } -static inline void Ndr_DataPushString( Ndr_Data_t * p, int Type, char * pFunc ) +static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, char * pFunc ) { int nBuffInts; int * pBuff; if ( !pFunc ) return; - nBuffInts = ((int)strlen(pFunc) + 4) / 4; - pBuff = (int *)calloc( 1, 4*nBuffInts ); - memcpy( pBuff, pFunc, strlen(pFunc) ); - Ndr_DataPushArray( p, Type, nBuffInts, pBuff ); - free( pBuff ); + if ( ObjType == ABC_OPER_LUT ) + { + word Truth = (word)pFunc; + Ndr_DataPushArray( p, Type, 2, (int *)&Truth ); + } + else + { + nBuffInts = ((int)strlen(pFunc) + 4) / 4; + pBuff = (int *)calloc( 1, 4*nBuffInts ); + memcpy( pBuff, pFunc, strlen(pFunc) ); + Ndr_DataPushArray( p, Type, nBuffInts, pBuff ); + free( pBuff ); + } } //////////////////////////////////////////////////////////////////////// @@ -554,7 +562,7 @@ static inline void Ndr_AddObject( void * pDesign, int ModuleId, Ndr_DataPush( p, NDR_NAME, InstName ); Ndr_DataPushArray( p, NDR_INPUT, nInputs, pInputs ); Ndr_DataPushArray( p, NDR_OUTPUT, nOutputs, pOutputs ); - Ndr_DataPushString( p, NDR_FUNCTION, pFunction ); + Ndr_DataPushString( p, ObjType, NDR_FUNCTION, pFunction ); Ndr_DataAddTo( p, Obj, p->nSize - Obj ); Ndr_DataAddTo( p, Mod, p->nSize - Obj ); Ndr_DataAddTo( p, 0, p->nSize - Obj ); @@ -1088,6 +1096,35 @@ static inline void Ndr_ModuleTestAddSub() Ndr_Delete( pDesign ); } +// This testing procedure creates and writes into a Verilog file +// the following design composed of one lookup table with function of AND2 + +// module lut_test ( input [1:0] in, output out ); +// assign out = LUT #(TT=4'h8) lut_inst { in[0], in[1], out } ; +// endmodule + +static inline void Ndr_ModuleTestLut() +{ + // map name IDs into char strings + //char * ppNames[12] = { NULL, "lut_test", "in", "out" }; + // name IDs + int NameIdIn = 2; + int NameIdOut = 3; + + // create a new module + void * pDesign = Ndr_Create( 1 ); + + int ModuleID = Ndr_AddModule( pDesign, 1 ); + + // add objects to the modele + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)(ABC_CONST(0x8)) ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &NameIdOut, 0, NULL, NULL ); + + Ndr_Write( "lut_test.ndr", pDesign ); + Ndr_Delete( pDesign ); +} + ABC_NAMESPACE_HEADER_END #endif diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 27ce427a..0a4f745c 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -160,6 +160,7 @@ struct Wlc_Ntk_t_ Mem_Flex_t * pMemFanin; Mem_Flex_t * pMemTable; Vec_Ptr_t * vTables; + Vec_Wrd_t * vLutTruths; // object names Abc_Nam_t * pManName; // object names Vec_Int_t vNameIds; // object name IDs diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 6eb5a5c4..3a01e238 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -718,6 +718,20 @@ void Wlc_BlastTable( Gia_Man_t * pNew, word * pTable, int * pFans, int nFans, in Vec_IntFree( vMemory ); ABC_FREE( pTruth ); } +void Wlc_BlastLut( Gia_Man_t * pNew, word Truth, int * pFans, int nFans, int nOuts, Vec_Int_t * vRes ) +{ + extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + Vec_Int_t * vMemory = Vec_IntAlloc( 0 ); + Vec_Int_t vLeaves = { nFans, nFans, pFans }; + int iLit; + Vec_IntClear( vRes ); + assert( nOuts == 1 ); + if ( nFans < 6 ) + Truth = Abc_Tt6Stretch( Truth, nFans ); + iLit = Kit_TruthToGia( pNew, (unsigned *)&Truth, nFans, vMemory, &vLeaves, 1 ); + Vec_IntPush( vRes, iLit ); + Vec_IntFree( vMemory ); +} void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes ) { Vec_Int_t * vDegrees = Vec_IntAlloc( 2*nNum ); @@ -1852,6 +1866,8 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) } else if ( pObj->Type == WLC_OBJ_TABLE ) Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes ); + else if ( pObj->Type == WLC_OBJ_LUT && p->vLutTruths ) + Wlc_BlastLut( pNew, Vec_WrdEntry(p->vLutTruths, Wlc_ObjId(p, pObj)), pFans0, nRange0, nRange, vRes ); else assert( 0 ); assert( Vec_IntSize(vBits) == Wlc_ObjCopy(p, i) ); Vec_IntAppend( vBits, vRes ); diff --git a/src/base/wlc/wlcNdr.c b/src/base/wlc/wlcNdr.c index c70e4a6d..e0be9002 100644 --- a/src/base/wlc/wlcNdr.c +++ b/src/base/wlc/wlcNdr.c @@ -368,6 +368,7 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) Ndr_Data_t * p = (Ndr_Data_t *)pData; Wlc_Obj_t * pObj; Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 ); int Mod = 2, i, k, Obj, * pArray, nDigits, fFound, NameId, NameIdMax; + Vec_Wrd_t * vTruths = NULL; Wlc_Ntk_t * pTemp, * pNtk = Wlc_NtkAlloc( "top", Ndr_DataObjNum(p, Mod)+1 ); Wlc_NtkCheckIntegrity( pData ); Vec_IntClear( &pNtk->vFfs ); @@ -412,6 +413,14 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) } if ( Type == ABC_OPER_DFFRSE ) Vec_IntPush( &pNtk->vFfs2, iObj ); + if ( Type == ABC_OPER_LUT ) + { + if ( vTruths == NULL ) + vTruths = Vec_WrdStart( 1000 ); + if ( NameId >= Vec_WrdSize(vTruths) ) + Vec_WrdFillExtra( vTruths, 2*NameId, 0 ); + Vec_WrdWriteEntry( vTruths, NameId, *((word *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION)) ); + } if ( Type == ABC_OPER_SLICE ) Vec_IntPushTwo( vFanins, End, Beg ); else if ( Type == ABC_OPER_CONST ) @@ -487,6 +496,22 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) // derive topological order pNtk = Wlc_NtkDupDfs( pTemp = pNtk, 0, 1 ); Wlc_NtkFree( pTemp ); + // copy truth tables + if ( vTruths ) + { + pNtk->vLutTruths = Vec_WrdStart( Wlc_NtkObjNumMax(pNtk) ); + Wlc_NtkForEachObj( pNtk, pObj, i ) + { + int iObj = Wlc_ObjId(pNtk, pObj); + int NameId = Wlc_ObjNameId(pNtk, iObj); + word Truth = Vec_WrdEntry(vTruths, NameId); + if ( pObj->Type != WLC_OBJ_LUT || NameId == 0 ) + continue; + assert( sizeof(void *) == 8 || Wlc_ObjFaninNum(pObj) < 6 ); + Vec_WrdWriteEntry( pNtk->vLutTruths, iObj, Truth ); + } + Vec_WrdFreeP( &vTruths ); + } //Ndr_NtkPrintNodes( pNtk ); pNtk->fMemPorts = 1; // the network contains memory ports pNtk->fEasyFfs = 1; // the network contains simple flops diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index a61d72f0..7d246c0f 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -259,6 +259,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) Mem_FlexStop( p->pMemTable, 0 ); ABC_FREE( p->vPoPairs.pArray ); Vec_PtrFreeP( &p->vTables ); + Vec_WrdFreeP( &p->vLutTruths ); ABC_FREE( p->vPis.pArray ); ABC_FREE( p->vPos.pArray ); ABC_FREE( p->vCis.pArray ); diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index 13bc3b26..c6763e93 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -211,6 +211,12 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) for ( k = 1; k < Wlc_ObjFaninNum(pObj); k++ ) fprintf( pFile, "%s, ", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) ); fprintf( pFile, "%s)", Wlc_ObjName(p, i) ); + if ( p->vLutTruths ) + { + word Truth = Vec_WrdEntry( p->vLutTruths, Wlc_ObjId(p, pObj) ); + fprintf( pFile, " ; // TT = " ); + Extra_PrintHex( pFile, (unsigned *)&Truth, Wlc_ObjFaninNum(pObj) ); + } } else if ( pObj->Type == WLC_OBJ_CONST ) { |