diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2018-06-16 18:47:23 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2018-06-16 18:47:23 -0700 |
commit | 28a1307a61cbc5b3a027f21a3b1ce74c58a52d03 (patch) | |
tree | 72cc915495dad48cba2bd663f57dbf21dbeee3bf /src/base/wlc | |
parent | f4a267d5815e5041c499e12322d70d7996093473 (diff) | |
download | abc-28a1307a61cbc5b3a027f21a3b1ce74c58a52d03.tar.gz abc-28a1307a61cbc5b3a027f21a3b1ce74c58a52d03.tar.bz2 abc-28a1307a61cbc5b3a027f21a3b1ce74c58a52d03.zip |
Command %blastmem for bit-blasting small memories.
Diffstat (limited to 'src/base/wlc')
-rw-r--r-- | src/base/wlc/wlcCom.c | 48 | ||||
-rw-r--r-- | src/base/wlc/wlcMem.c | 127 | ||||
-rw-r--r-- | src/base/wlc/wlcNtk.c | 5 | ||||
-rw-r--r-- | src/base/wlc/wlcWriteVer.c | 3 |
4 files changed, 182 insertions, 1 deletions
diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 52214d2d..06c2346b 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -38,6 +38,7 @@ static int Abc_CommandPdrAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMemAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandBlastMem ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandGraft ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -82,6 +83,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%memabs", Abc_CommandMemAbs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%blastmem", Abc_CommandBlastMem, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); @@ -1115,6 +1117,52 @@ usage: SeeAlso [] ******************************************************************************/ +int Abc_CommandBlastMem( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Wlc_Ntk_t * Wlc_NtkMemBlast( Wlc_Ntk_t * p ); + 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_CommandGraft(): There is no current design.\n" ); + return 0; + } + pNtk = Wlc_NtkMemBlast( pNtk ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%blastmem [-vh]\n" ); + Abc_Print( -2, "\t performs blasting of memory read/write ports\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 [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Wlc_Ntk_t * Wlc_NtkGraftMulti( Wlc_Ntk_t * p, int fVerbose ); diff --git a/src/base/wlc/wlcMem.c b/src/base/wlc/wlcMem.c index 9ce1764a..ccc319e5 100644 --- a/src/base/wlc/wlcMem.c +++ b/src/base/wlc/wlcMem.c @@ -35,6 +35,133 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* + Synopsis [Memory blasting.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkMemBlast_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins ) +{ + Wlc_Obj_t * pObj; + int i, iFanin; + if ( Wlc_ObjCopy(p, iObj) ) + return; + pObj = Wlc_NtkObj( p, iObj ); + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkMemBlast_rec( pNew, p, iFanin, vFanins ); + if ( pObj->Type == WLC_OBJ_WRITE ) + { + Vec_Int_t * vTemp = Vec_IntAlloc( 1 ); + Vec_Int_t * vBits = Vec_IntAlloc( 100 ); + Wlc_Obj_t * pMem = Wlc_ObjFanin0(p, pObj); + Wlc_Obj_t * pAddr = Wlc_ObjFanin1(p, pObj); + Wlc_Obj_t * pData = Wlc_ObjFanin2(p, pObj); + int DataW = Wlc_ObjRange(pData); + int AddrW = Wlc_ObjRange(pAddr); + int nRegs = 1 << AddrW, iObjNew, iObjDec; + assert( nRegs * DataW == Wlc_ObjRange(pMem) ); + assert( Wlc_ObjRange(pObj) == Wlc_ObjRange(pMem) ); + // create decoder + iObjDec = Wlc_ObjAlloc( pNew, WLC_OBJ_DEC, 0, nRegs-1, 0 ); + Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pAddr)) ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjDec), vTemp ); + // create decoder bits + for ( i = 0; i < nRegs; i++ ) + { + int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i, i ); + Vec_IntFill( vTemp, 1, iObjDec ); + Vec_IntPushTwo( vTemp, i, i ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp ); + Vec_IntPush( vBits, iObj2 ); + } + // create data words + Vec_IntClear( vFanins ); + for ( i = 0; i < nRegs; i++ ) + { + int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i*DataW+DataW-1, i*DataW ); + Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pMem)) ); + Vec_IntPushTwo( vTemp, i*DataW+DataW-1, i*DataW ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp ); + Vec_IntPush( vFanins, iObj2 ); + } + // create MUXes of data words controlled by decoder bits + for ( i = 0; i < nRegs; i++ ) + { + int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_MUX, 0, DataW-1, 0 ); + Vec_IntFill( vTemp, 1, Vec_IntEntry(vBits, i) ); + Vec_IntPushTwo( vTemp, Wlc_ObjCopy(p, Wlc_ObjId(p, pData)), Vec_IntEntry(vFanins, i) ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp ); + Vec_IntWriteEntry( vFanins, i, iObj2 ); + } + // concatenate the results + iObjNew = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_CONCAT, 0, nRegs*DataW-1, 0 ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjNew), vFanins ); + Wlc_ObjSetCopy( p, iObj, iObjNew ); + Vec_IntFree( vTemp ); + Vec_IntFree( vBits ); + } + else if ( pObj->Type == WLC_OBJ_READ ) + { + Vec_Int_t * vTemp = Vec_IntAlloc( 1 ); + Wlc_Obj_t * pMem = Wlc_ObjFanin0(p, pObj); + Wlc_Obj_t * pAddr = Wlc_ObjFanin1(p, pObj); + int DataW = Wlc_ObjRange(pObj); + int AddrW = Wlc_ObjRange(pAddr); + int nRegs = 1 << AddrW, iObjNew; + assert( nRegs * DataW == Wlc_ObjRange(pMem) ); + Vec_IntClear( vFanins ); + Vec_IntPush( vFanins, Wlc_ObjCopy(p, Wlc_ObjId(p, pAddr)) ); + for ( i = 0; i < nRegs; i++ ) + { + int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i*DataW+DataW-1, i*DataW ); + Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pMem)) ); + Vec_IntPushTwo( vTemp, i*DataW+DataW-1, i*DataW ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp ); + Vec_IntPush( vFanins, iObj2 ); + } + iObjNew = Wlc_ObjAlloc( pNew, WLC_OBJ_MUX, 0, DataW-1, 0 ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjNew), vFanins ); + Wlc_ObjSetCopy( p, iObj, iObjNew ); + Vec_IntFree( vTemp ); + } + else + Wlc_ObjDup( pNew, p, iObj, vFanins ); +} +Wlc_Ntk_t * Wlc_NtkMemBlast( Wlc_Ntk_t * p ) +{ + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + Vec_Int_t * vFanins; + int i; + Wlc_NtkCleanCopy( p ); + vFanins = Vec_IntAlloc( 100 ); + pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); + pNew->fSmtLib = p->fSmtLib; + pNew->fMemPorts = p->fMemPorts; + pNew->fEasyFfs = p->fEasyFfs; + Wlc_NtkForEachCi( p, pObj, i ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_NtkMemBlast_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); + if ( p->vInits ) + pNew->vInits = Vec_IntDup( p->vInits ); + if ( p->pInits ) + pNew->pInits = Abc_UtilStrsav( p->pInits ); + Vec_IntFree( vFanins ); + if ( p->pSpec ) + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + return pNew; +} + + +/**Function************************************************************* + Synopsis [Collect memory nodes.] Description [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 0d8374c7..7f562072 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -640,6 +640,11 @@ void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) printf( "FO\n" ); return; } + if ( pObj->Type != WLC_OBJ_CONST && Wlc_ObjFaninNum(pObj) == 0 ) + { + printf( "Unknown object without fanins\n" ); + return; + } if ( pObj->Type != WLC_OBJ_CONST ) { printf( "%6d%s %5s ", Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin0(p, pObj)) ? "s" : " ", Wlc_Names[(int)pObj->Type] ); diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index 93e2c2c6..dd25196c 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -475,7 +475,8 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, "#" ); else { - assert( 0 ); + //assert( 0 ); + printf( "Failed to write node \"%s\" with unknown operator type (%d).\n", Wlc_ObjName(p, i), pObj->Type ); fprintf( pFile, "???\n" ); continue; } |