summaryrefslogtreecommitdiffstats
path: root/src/base/wlc/wlcMem.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2018-06-16 18:47:23 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2018-06-16 18:47:23 -0700
commit28a1307a61cbc5b3a027f21a3b1ce74c58a52d03 (patch)
tree72cc915495dad48cba2bd663f57dbf21dbeee3bf /src/base/wlc/wlcMem.c
parentf4a267d5815e5041c499e12322d70d7996093473 (diff)
downloadabc-28a1307a61cbc5b3a027f21a3b1ce74c58a52d03.tar.gz
abc-28a1307a61cbc5b3a027f21a3b1ce74c58a52d03.tar.bz2
abc-28a1307a61cbc5b3a027f21a3b1ce74c58a52d03.zip
Command %blastmem for bit-blasting small memories.
Diffstat (limited to 'src/base/wlc/wlcMem.c')
-rw-r--r--src/base/wlc/wlcMem.c127
1 files changed, 127 insertions, 0 deletions
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 []