summaryrefslogtreecommitdiffstats
path: root/src/base/wln/wlnBlast.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2022-01-21 11:09:10 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2022-01-21 11:09:10 -0800
commit79f04c66534c1a517481a2006dcbbb8e27d1688c (patch)
tree175da1084db4b1374df2e6fdeb995cd56d5ba1c1 /src/base/wln/wlnBlast.c
parent48498af8189ef321ee876065d8947875cf711294 (diff)
downloadabc-79f04c66534c1a517481a2006dcbbb8e27d1688c.tar.gz
abc-79f04c66534c1a517481a2006dcbbb8e27d1688c.tar.bz2
abc-79f04c66534c1a517481a2006dcbbb8e27d1688c.zip
Experiments with word-level data structures.
Diffstat (limited to 'src/base/wln/wlnBlast.c')
-rw-r--r--src/base/wln/wlnBlast.c388
1 files changed, 388 insertions, 0 deletions
diff --git a/src/base/wln/wlnBlast.c b/src/base/wln/wlnBlast.c
new file mode 100644
index 00000000..a3ac73c0
--- /dev/null
+++ b/src/base/wln/wlnBlast.c
@@ -0,0 +1,388 @@
+/**CFile****************************************************************
+
+ FileName [wlnBlast.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnBlast.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "base/wlc/wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_VecExtend( Vec_Int_t * p, int nRange, int fSigned )
+{
+ Vec_IntFillExtra( p, nRange, fSigned ? Vec_IntEntryLast(p) : 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 )
+{
+ extern void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes );
+ extern int Wlc_BlastReduction( Gia_Man_t * pNew, int * pFans, int nFans, int Type );
+ extern int Wlc_BlastLess( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits );
+ extern int Wlc_BlastLessSigned( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits );
+ extern void Wlc_BlastShiftRight( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes );
+ extern void Wlc_BlastShiftLeft( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes );
+ extern int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
+ extern void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
+ extern int Wlc_NtkCountConstBits( int * pArray, int nSize );
+ extern 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 ** pvProds );
+ extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
+ extern void Wlc_BlastZeroCondition( Gia_Man_t * pNew, int * pDiv, int nDiv, Vec_Int_t * vRes );
+ extern void Wlc_BlastDivider( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes );
+ extern void Wlc_BlastDividerSigned( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes );
+ extern void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes );
+
+ int k, iLit, iLit0, iLit1;
+ if ( nIns == 1 )
+ {
+ Vec_Int_t * vArg = vDatas;
+ Vec_Int_t * vRes = vDatas+3;
+ assert( Vec_IntSize(vRes) == 0 );
+ if ( Type == ABC_OPER_BIT_INV ) // Y = ~A $not
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Vec_IntForEachEntry( vArg, iLit, k )
+ Vec_IntPush( vRes, Abc_LitNot(iLit) );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_BUF ) // Y = +A $pos
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Vec_IntForEachEntry( vArg, iLit, k )
+ Vec_IntPush( vRes, iLit );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_MIN ) // Y = -A $neg
+ {
+ assert( Vec_IntSize(vArg) == nRange );
+ Wlc_BlastMinus( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), vRes );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_AND ) // Y = &A $reduce_and
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_AND ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_OR ) // Y = |A $reduce_or $reduce_bool
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_XOR ) // Y = ^A $reduce_xor
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_XOR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_RED_NXOR ) // Y = ~^A $reduce_xnor
+ {
+ assert( nRange == 1 );
+ Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_NXOR ) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_LOGIC_NOT ) // Y = !A $logic_not
+ {
+ int iLit = Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR );
+ assert( nRange == 1 );
+ Vec_IntFill( vRes, 1, Abc_LitNot(iLit) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ assert( 0 );
+ return;
+ }
+
+ if ( nIns == 2 )
+ {
+ Vec_Int_t * vArg0 = vDatas;
+ Vec_Int_t * vArg1 = vDatas+1;
+ Vec_Int_t * vRes = vDatas+3;
+ int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(Vec_IntSize(vArg0), Vec_IntSize(vArg1)) );
+ int nSizeArg0 = Vec_IntSize(vArg0);
+ int nSizeArg1 = Vec_IntSize(vArg1);
+ Rtl_VecExtend( vArg0, nRangeMax, fSign0 );
+ Rtl_VecExtend( vArg1, nRangeMax, fSign1 );
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( Vec_IntSize(vRes) == 0 );
+ if ( Type == ABC_OPER_LOGIC_AND ) // Y = A && B $logic_and
+ {
+ int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR );
+ int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR );
+ assert( 1 == nRange );
+ Vec_IntFill( vRes, 1, Gia_ManHashAnd(pNew, iLit0, iLit1) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_LOGIC_OR ) // Y = A || B $logic_or
+ {
+ int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR );
+ int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR );
+ assert( 1 == nRange );
+ Vec_IntFill( vRes, 1, Gia_ManHashOr(pNew, iLit0, iLit1) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+
+ if ( Type == ABC_OPER_BIT_AND ) // Y = A & B $and
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashAnd(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_OR ) // Y = A | B $or
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashOr(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_XOR ) // Y = A ^ B $xor
+ {
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashXor(pNew, iLit0, iLit1) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_BIT_NXOR ) // Y = A ~^ B $xnor
+ {
+ assert( Vec_IntSize(vArg0) == nRange );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Abc_LitNot(Gia_ManHashXor(pNew, iLit0, iLit1)) );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$lt") ) return ABC_OPER_COMP_LESS; // Y = A < B $lt
+ if ( !strcmp(pType, "$le") ) return ABC_OPER_COMP_LESSEQU; // Y = A <= B $le
+ if ( !strcmp(pType, "$ge") ) return ABC_OPER_COMP_MOREEQU; // Y = A >= B $ge
+ if ( !strcmp(pType, "$gt") ) return ABC_OPER_COMP_MORE; // Y = A > B $gt
+ if ( !strcmp(pType, "$eq") ) return ABC_OPER_COMP_EQU; // Y = A == B $eq
+ if ( !strcmp(pType, "$ne") ) return ABC_OPER_COMP_NOTEQU; // Y = A != B $ne
+*/
+ if ( Type == ABC_OPER_COMP_EQU || Type == ABC_OPER_COMP_NOTEQU )
+ {
+ iLit = 0;
+ assert( nRange == 1 );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, iLit0, iLit1) );
+ Vec_IntFill( vRes, 1, Abc_LitNotCond(iLit, Type == ABC_OPER_COMP_EQU) );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+ if ( Type == ABC_OPER_COMP_LESS || Type == ABC_OPER_COMP_LESSEQU ||
+ Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_MOREEQU )
+ {
+ int fSigned = fSign0 && fSign1;
+ int fSwap = (Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_LESSEQU);
+ int fCompl = (Type == ABC_OPER_COMP_MOREEQU || Type == ABC_OPER_COMP_LESSEQU);
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( nRange == 1 );
+ if ( fSwap )
+ ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 )
+ if ( fSigned )
+ iLit = Wlc_BlastLessSigned( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) );
+ else
+ iLit = Wlc_BlastLess( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) );
+ iLit = Abc_LitNotCond( iLit, fCompl );
+ Vec_IntFill( vRes, 1, iLit );
+ for ( k = 1; k < nRange; k++ )
+ Vec_IntPush( vRes, 0 );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$shl") ) return ABC_OPER_SHIFT_L; // Y = A << B $shl
+ if ( !strcmp(pType, "$shr") ) return ABC_OPER_SHIFT_R; // Y = A >> B $shr
+ if ( !strcmp(pType, "$sshl") ) return ABC_OPER_SHIFT_LA; // Y = A <<< B $sshl
+ if ( !strcmp(pType, "$sshr") ) return ABC_OPER_SHIFT_RA; // Y = A >>> B $sshr
+*/
+ if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA ||
+ Type == ABC_OPER_SHIFT_L || Type == ABC_OPER_SHIFT_LA )
+ {
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA )
+ Wlc_BlastShiftRight( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, fSign0 && Type == ABC_OPER_SHIFT_RA, vRes );
+ else
+ Wlc_BlastShiftLeft( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, 0, vRes );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+/*
+ if ( !strcmp(pType, "$add") ) return ABC_OPER_ARI_ADD; // Y = A + B $add
+ if ( !strcmp(pType, "$sub") ) return ABC_OPER_ARI_SUB; // Y = A - B $sub
+ if ( !strcmp(pType, "$mul") ) return ABC_OPER_ARI_MUL; // Y = A * B $mul
+ if ( !strcmp(pType, "$div") ) return ABC_OPER_ARI_DIV; // Y = A / B $div
+ if ( !strcmp(pType, "$mod") ) return ABC_OPER_ARI_MOD; // Y = A % B $mod
+ if ( !strcmp(pType, "$pow") ) return ABC_OPER_ARI_POW; // Y = A ** B $pow
+*/
+ if ( Type == ABC_OPER_ARI_ADD || Type == ABC_OPER_ARI_SUB )
+ {
+ //Vec_IntPrint( vArg0 );
+ //Vec_IntPrint( vArg1 );
+ Vec_IntAppend( vRes, vArg0 );
+ if ( Type == ABC_OPER_ARI_ADD )
+ Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 0 ); // result is in pFan0 (vRes)
+ else
+ Wlc_BlastSubtract( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 1 ); // result is in pFan0 (vRes)
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_MUL )
+ {
+ int fBooth = 1;
+ int fCla = 0;
+ int fSigned = fSign0 && fSign1;
+ Vec_IntShrink( vArg0, nSizeArg0 );
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ if ( Wlc_NtkCountConstBits(Vec_IntArray(vArg0), Vec_IntSize(vArg0)) < Wlc_NtkCountConstBits(Vec_IntArray(vArg1), Vec_IntSize(vArg1)) )
+ ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 )
+ if ( fBooth )
+ Wlc_BlastBooth( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL );
+ else
+ Wlc_BlastMultiplier3( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL );
+ if ( nRange > Vec_IntSize(vRes) )
+ Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 );
+ else
+ Vec_IntShrink( vRes, nRange );
+ assert( Vec_IntSize(vRes) == nRange );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_DIV || Type == ABC_OPER_ARI_MOD )
+ {
+ int fDivBy0 = 1; // correct with 1
+ int fSigned = fSign0 && fSign1;
+ if ( fSigned )
+ Wlc_BlastDividerSigned( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes );
+ else
+ Wlc_BlastDivider( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes );
+ Vec_IntShrink( vRes, nRange );
+ if ( !fDivBy0 )
+ Wlc_BlastZeroCondition( pNew, Vec_IntArray(vArg1), nRange, vRes );
+ return;
+ }
+ if ( Type == ABC_OPER_ARI_POW )
+ {
+ Vec_Int_t * vTemp = vDatas+4;
+ Vec_IntGrow( vTemp, nRangeMax );
+ Vec_IntGrow( vRes, nRangeMax );
+ Vec_IntShrink( vArg1, nSizeArg1 );
+ Wlc_BlastPower( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), Vec_IntSize(vArg1), vTemp, vRes );
+ Vec_IntShrink( vRes, nRange );
+ return;
+ }
+ }
+
+ if ( nIns == 3 )
+ {
+ if ( Type == ABC_OPER_SEL_NMUX ) // $mux
+ {
+ Vec_Int_t * vArg0 = vDatas;
+ Vec_Int_t * vArg1 = vDatas+1;
+ Vec_Int_t * vArgS = vDatas+2;
+ Vec_Int_t * vRes = vDatas+3;
+ int iCtrl = Vec_IntEntry(vArgS, 0);
+ //Vec_IntPrint( vArg0 );
+ //Vec_IntPrint( vArg1 );
+ //Vec_IntPrint( vArgS );
+ assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) );
+ assert( Vec_IntSize(vArg0) == nRange );
+ assert( Vec_IntSize(vArgS) == 1 );
+ assert( Vec_IntSize(vRes) == 0 );
+ Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k )
+ Vec_IntPush( vRes, Gia_ManHashMux(pNew, iCtrl, iLit1, iLit0) );
+ return;
+ }
+ if ( Type == ABC_OPER_SEL_SEL ) // $pmux
+ {
+ int i, k, iLit;
+ Vec_Int_t * vArgA = vDatas;
+ Vec_Int_t * vArgB = vDatas+1;
+ Vec_Int_t * vArgS = vDatas+2;
+ Vec_Int_t * vRes = vDatas+3;
+ Vec_Int_t * vTemp = vDatas+4;
+ assert( Vec_IntSize(vArgA) == nRange ); // widthA = widthY
+ assert( Vec_IntSize(vArgB) == Vec_IntSize(vArgA)*Vec_IntSize(vArgS) ); // widthB == widthA*widthS
+ assert( Vec_IntSize(vRes) == 0 );
+ for ( i = 0; i < nRange; i++ )
+ {
+ int iCond = 1;
+ Vec_IntClear( vTemp );
+ Vec_IntForEachEntry( vArgS, iLit, k ) // iLit = S[i]
+ {
+ //Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*(Vec_IntSize(vArgS)-1-k)+i)) ) ); // B[widthA*k+i]
+ Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*k+i)) ) ); // B[widthA*k+i]
+ iCond = Gia_ManHashAnd( pNew, iCond, Abc_LitNot(iLit) );
+ }
+ Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iCond, Vec_IntEntry(vArgA, i)) ) );
+ Vec_IntPush( vRes, Abc_LitNot( Gia_ManHashAndMulti(pNew, vTemp) ) );
+ }
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+