diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2018-06-14 21:13:54 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2018-06-14 21:13:54 -0700 |
commit | 15939511df8ff1ce15f2112cee01d7693234f2a4 (patch) | |
tree | 08dae14efc2b74928dcc23702506d48f34abbfbd | |
parent | baab8c11f2769c29963bb0c6b2989203288a9b69 (diff) | |
download | abc-15939511df8ff1ce15f2112cee01d7693234f2a4.tar.gz abc-15939511df8ff1ce15f2112cee01d7693234f2a4.tar.bz2 abc-15939511df8ff1ce15f2112cee01d7693234f2a4.zip |
Extending NDR to support adder/subtractor.
-rw-r--r-- | src/aig/miniaig/ndr.h | 36 | ||||
-rw-r--r-- | src/base/wlc/wlcBlast.c | 28 | ||||
-rw-r--r-- | src/base/wlc/wlcWriteVer.c | 14 |
3 files changed, 72 insertions, 6 deletions
diff --git a/src/aig/miniaig/ndr.h b/src/aig/miniaig/ndr.h index 71a9d5ac..b33d9c6d 100644 --- a/src/aig/miniaig/ndr.h +++ b/src/aig/miniaig/ndr.h @@ -1044,6 +1044,42 @@ static inline void Ndr_ModuleTestDec() Ndr_Delete( pDesign ); } +// This testing procedure creates and writes into a Verilog file +// the following design composed of one adder/subtractor + +// module addsub ( input mode, input cin, input [2:0] a, input [2:0] b, output [3:0] out ); +// assign out = mode ? a+b+cin : a-b-cin ; +// endmodule + +static inline void Ndr_ModuleTestAddSub() +{ + // map name IDs into char strings + //char * ppNames[12] = { NULL, "addsub", "mode", "cin", "a", "b", "out" }; + // name IDs + int NameIdInMode = 2; + int NameIdInCin = 3; + int NameIdInA = 4; + int NameIdInB = 5; + int NameIdOut = 6; + int Fanins[8] = { 2, 3, 4, 5 }; + + // 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, 0, 0, 0, 0, NULL, 1, &NameIdInMode, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdInCin, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdInA, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdInB, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADDSUB, 0, 3, 0, 0, 4, Fanins, 1, &NameIdOut, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL ); + + Ndr_Write( "addsub.ndr", pDesign ); + Ndr_Delete( pDesign ); +} + ABC_NAMESPACE_HEADER_END #endif diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index c16c89c6..2efed1f8 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -345,9 +345,9 @@ void Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int for ( b = 0; b < nBits; b++ ) Wlc_BlastFullAdder( pNew, pAdd0[b], pAdd1[b], Carry, &Carry, &pAdd0[b] ); } -void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0 +void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0 { - int b, Carry = 1; + int b; for ( b = 0; b < nBits; b++ ) Wlc_BlastFullAdder( pNew, pAdd0[b], Abc_LitNot(pAdd1[b]), Carry, &Carry, &pAdd0[b] ); } @@ -1138,8 +1138,8 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) Wlc_Obj_t * pObj, * pObj2; Vec_Int_t * vBits = &p->vBits, * vTemp0, * vTemp1, * vTemp2, * vRes, * vAddOutputs = NULL, * vAddObjs = NULL; int nBits = Wlc_NtkPrepareBits( p ); - int nRange, nRange0, nRange1, nRange2; - int i, k, b, iFanin, iLit, nAndPrev, * pFans0, * pFans1, * pFans2; + int nRange, nRange0, nRange1, nRange2, nRange3; + int i, k, b, iFanin, iLit, nAndPrev, * pFans0, * pFans1, * pFans2, * pFans3; int nFFins = 0, nFFouts = 0, curPi = 0, curPo = 0; int nBitCis = 0, nBitCos = 0, fAdded = 0; Wlc_BstPar_t Par, * pPar = &Par; @@ -1209,9 +1209,11 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1; nRange1 = Wlc_ObjFaninNum(pObj) > 1 ? Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) ) : -1; nRange2 = Wlc_ObjFaninNum(pObj) > 2 ? Wlc_ObjRange( Wlc_ObjFanin2(p, pObj) ) : -1; + nRange3 = Wlc_ObjFaninNum(pObj) > 3 ? Wlc_ObjRange( Wlc_ObjFanin(p, pObj, 3) ) : -1; pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL; pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL; pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL; + pFans3 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; Vec_IntClear( vRes ); assert( nRange > 0 ); if ( pPar->vBoxIds && pObj->Mark ) @@ -1280,7 +1282,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) if ( pObj->Type == WLC_OBJ_ARI_ADD ) Wlc_BlastAdder( pExtra, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes) else - Wlc_BlastSubtract( pExtra, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) + Wlc_BlastSubtract( pExtra, pArg0, pArg1, nRange, 1 ); // result is in pFan0 (vRes) Vec_IntShrink( vRes, nRange ); } else if ( fUseOldMultiplierBlasting ) @@ -1636,9 +1638,23 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) Wlc_BlastAdder( pNew, pArg0, pArg1, nRangeMax, CarryIn ); // result is in pFan0 (vRes) } else - Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) + Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange, 1 ); // result is in pFan0 (vRes) Vec_IntShrink( vRes, nRange ); } + else if ( pObj->Type == WLC_OBJ_ARI_ADDSUB ) + { + int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange2, nRange3) ); + int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans2, nRange2, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); + int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans2, nRange2, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); + int * pArg2 = Wlc_VecLoadFanins( vTemp2, pFans3, nRange3, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); + int ModeIn = pFans0[0]; + int CarryIn = pFans1[0]; int j; + Wlc_BlastAdder ( pNew, pArg0, pArg2, nRangeMax, CarryIn ); // result is in pArg0 (vTemp0) + Wlc_BlastSubtract( pNew, pArg1, pArg2, nRangeMax, Abc_LitNot(CarryIn) ); // result is in pArg1 (vTemp1) + Vec_IntClear( vRes ); + for ( j = 0; j < nRange; j++ ) + Vec_IntPush( vRes, Gia_ManHashMux(pNew, ModeIn, pArg0[j], pArg1[j]) ); + } else if ( pObj->Type == WLC_OBJ_ARI_MULTI ) { if ( fUseOldMultiplierBlasting ) diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index a7d29187..45ce31e4 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -318,6 +318,20 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, " } ;\n" ); continue; } + else if ( pObj->Type == WLC_OBJ_ARI_ADDSUB ) + { + // out = mode ? a+b+cin : a-b-cin + int nRange = Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)); + fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) ); + fprintf( pFile, " " ); + fprintf( pFile, "assign " ); + fprintf( pFile, "%s = %s ? %s + %s + %s : %s - %s - %s ;\n", + Wlc_ObjName(p, i), Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)), + Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)), Wlc_ObjName(p, Wlc_ObjFaninId(pObj,3)), Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)), + Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)), Wlc_ObjName(p, Wlc_ObjFaninId(pObj,3)), Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) + ); + continue; + } else if ( pObj->Type == WLC_OBJ_READ || pObj->Type == WLC_OBJ_WRITE ) { if ( p->fMemPorts ) |