diff options
author | Yen-Sheng Ho <ysho@berkeley.edu> | 2017-06-06 23:16:55 -0700 |
---|---|---|
committer | Yen-Sheng Ho <ysho@berkeley.edu> | 2017-06-06 23:16:55 -0700 |
commit | 584e28e8f4f8beb70e577c38719f8e7b532123e1 (patch) | |
tree | d8a78ae811e2a1cd14f88518d574e90a58d0aed2 /src/base | |
parent | 10f5e944c99626d5f8e68aa874e43462569cabf7 (diff) | |
parent | e140ef7e5a45b23823bdf1189070573439966ac8 (diff) | |
download | abc-584e28e8f4f8beb70e577c38719f8e7b532123e1.tar.gz abc-584e28e8f4f8beb70e577c38719f8e7b532123e1.tar.bz2 abc-584e28e8f4f8beb70e577c38719f8e7b532123e1.zip |
merge
Diffstat (limited to 'src/base')
-rw-r--r-- | src/base/abc/abcUtil.c | 79 | ||||
-rw-r--r-- | src/base/abci/abc.c | 74 | ||||
-rw-r--r-- | src/base/acb/acb.h | 53 | ||||
-rw-r--r-- | src/base/acb/acbAbc.c | 22 | ||||
-rw-r--r-- | src/base/acb/acbMfs.c | 12 | ||||
-rw-r--r-- | src/base/acb/acbPush.c | 372 | ||||
-rw-r--r-- | src/base/acb/module.make | 1 | ||||
-rw-r--r-- | src/base/wlc/wlc.h | 2 | ||||
-rw-r--r-- | src/base/wlc/wlcAbs.c | 10 | ||||
-rw-r--r-- | src/base/wlc/wlcAbs2.c | 2 | ||||
-rw-r--r-- | src/base/wlc/wlcBlast.c | 134 | ||||
-rw-r--r-- | src/base/wlc/wlcCom.c | 12 | ||||
-rw-r--r-- | src/base/wlc/wlcGraft.c | 4 | ||||
-rw-r--r-- | src/base/wlc/wlcReadSmt.c | 2 | ||||
-rw-r--r-- | src/base/wlc/wlcReadVer.c | 2 | ||||
-rw-r--r-- | src/base/wlc/wlcSim.c | 2 |
16 files changed, 728 insertions, 55 deletions
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index dc6cd3b3..6b67d82a 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -3109,7 +3109,9 @@ int Abc_GateToType( Abc_Obj_t * pObj ) if ( !strncmp(pGateName, "or", 2) ) return ABC_OPER_BIT_OR; if ( !strncmp(pGateName, "nor", 3) ) return ABC_OPER_BIT_NOR; if ( !strncmp(pGateName, "xor", 3) ) return ABC_OPER_BIT_XOR; - if ( !strncmp(pGateName, "nxor", 4) ) return ABC_OPER_BIT_NXOR; + if ( !strncmp(pGateName, "xnor", 4) ) return ABC_OPER_BIT_NXOR; + if ( !strncmp(pGateName, "zero", 4) ) return ABC_OPER_CONST_F; + if ( !strncmp(pGateName, "one", 3) ) return ABC_OPER_CONST_T; assert( 0 ); return -1; } @@ -3141,6 +3143,81 @@ Vec_Wec_t * Abc_SopSynthesize( Vec_Ptr_t * vSops ) return vRes; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkClpOneGia_rec( Gia_Man_t * pNew, Abc_Obj_t * pNode ) +{ + int iLit0, iLit1; + if ( Abc_NodeIsTravIdCurrent(pNode) || Abc_ObjFaninNum(pNode) == 0 || Abc_ObjIsCi(pNode) ) + return pNode->iTemp; + assert( Abc_ObjIsNode( pNode ) ); + Abc_NodeSetTravIdCurrent( pNode ); + iLit0 = Abc_NtkClpOneGia_rec( pNew, Abc_ObjFanin0(pNode) ); + iLit1 = Abc_NtkClpOneGia_rec( pNew, Abc_ObjFanin1(pNode) ); + iLit0 = Abc_LitNotCond( iLit0, Abc_ObjFaninC0(pNode) ); + iLit1 = Abc_LitNotCond( iLit1, Abc_ObjFaninC1(pNode) ); + return (pNode->iTemp = Gia_ManHashAnd(pNew, iLit0, iLit1)); +} +Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk ) +{ + int i, iLit; + Abc_Obj_t * pNode; + Gia_Man_t * pNew, * pTemp; + assert( Abc_NtkIsStrash(pNtk) ); + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->iTemp = -1; + // start new manager + pNew = Gia_ManStart( Abc_NtkObjNum(pNtk) ); + pNew->pName = Abc_UtilStrsav( pNtk->pName ); + pNew->pSpec = Abc_UtilStrsav( pNtk->pSpec ); + Gia_ManHashStart( pNew ); + // primary inputs + Abc_AigConst1(pNtk)->iTemp = 1; + Abc_NtkForEachCi( pNtk, pNode, i ) + pNode->iTemp = Gia_ManAppendCi(pNew); + // create the first cone + Abc_NtkIncrementTravId( pNtk ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + iLit = Abc_NtkClpOneGia_rec( pNew, Abc_ObjFanin0(pNode) ); + iLit = Abc_LitNotCond( iLit, Abc_ObjFaninC0(pNode) ); + Gia_ManAppendCo( pNew, iLit ); + } + // perform cleanup + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} +Gia_Man_t * Abc_SopSynthesizeOne( Vec_Ptr_t * vSops ) +{ + Abc_Ntk_t * pNtkNew, * pNtk; + char * pSop = (char *)Vec_PtrEntry(vSops, 0); + assert( Vec_PtrSize(vSops) == 1 ); + if ( strlen(pSop) == 3 ) + { + Gia_Man_t * pNew = Gia_ManStart( 1 ); + pNew->pName = Abc_UtilStrsav( "top" ); + //Gia_ManAppendCi( pNew ); + assert( pSop[1] == '0' || pSop[1] == '1' ); + Gia_ManAppendCo( pNew, pSop[1] == '1' ); + return pNew; + } + pNtk = Abc_NtkCreateFromSops( "top", vSops ); + Abc_FrameReplaceCurrentNetwork( Abc_FrameReadGlobalFrame(), pNtk ); + Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "fx; strash; dc2" ); + pNtkNew = Abc_FrameReadNtk( Abc_FrameReadGlobalFrame() ); + return Abc_NtkStrashToGia( pNtkNew ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f9f2f2e0..7055bf59 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -124,6 +124,7 @@ static int Abc_CommandMfs ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandMfs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMfs3 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMfse ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandLogicPush ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTrace ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandGlitch ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSpeedup ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -781,6 +782,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Synthesis", "mfs2", Abc_CommandMfs2, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "mfs3", Abc_CommandMfs3, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "mfse", Abc_CommandMfse, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "logicpush", Abc_CommandLogicPush, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "trace", Abc_CommandTrace, 0 ); Cmd_CommandAdd( pAbc, "Synthesis", "glitch", Abc_CommandGlitch, 0 ); Cmd_CommandAdd( pAbc, "Synthesis", "speedup", Abc_CommandSpeedup, 1 ); @@ -4151,7 +4153,7 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Empty network.\n" ); return 1; } - if ( Abc_NtkNodeNum(pNtk) == 0 ) + if ( Abc_NtkNodeNum(pNtk) == 0 || Abc_NtkPiNum(pNtk) == 0 ) { Abc_Print( -1, "The network does not have internal nodes.\n" ); return 1; @@ -5807,6 +5809,74 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandLogicPush( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Abc_Ntk_t * Abc_NtkOptPush( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose ); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + Abc_Ntk_t * pNtkRes; + int nLutSize = 4; + int fVerbose = 0; + int c; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by a positive integer.\n" ); + goto usage; + } + nLutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLutSize < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + if ( !Abc_NtkIsLogic(pNtk) ) + { + Abc_Print( -1, "This command can only be applied to a logic network.\n" ); + return 1; + } + nLutSize = Abc_MaxInt( nLutSize, Abc_NtkGetFaninMax(pNtk) ); + Abc_NtkToSop( pNtk, -1, ABC_INFINITY ); + pNtkRes = Abc_NtkOptPush( pNtk, nLutSize, fVerbose ); + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; +usage: + Abc_Print( -2, "usage: logicpush [-K num] [-vh]\n" ); + Abc_Print( -2, "\t performs logic pushing to reduce structural bias\n" ); + Abc_Print( -2, "\t-K <num> : the LUT size used in the mapping [default = %d]\n", nLutSize ); + Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* @@ -18315,7 +18385,7 @@ int Abc_CommandDsdFilter( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fInvMarks ) If_DsdManInvertMarks( pDsd, fVerbose ); #ifdef ABC_USE_CUDD - else + else if ( nLimit == 0 ) Id_DsdManTuneThresh( pDsd, fUnate, fThresh, fThreshHeuristic, fVerbose ); #endif return 0; diff --git a/src/base/acb/acb.h b/src/base/acb/acb.h index 7c228acb..baecd161 100644 --- a/src/base/acb/acb.h +++ b/src/base/acb/acb.h @@ -256,7 +256,8 @@ static inline int * Acb_ObjFanins( Acb_Ntk_t * p, int i ) static inline int Acb_ObjFanin( Acb_Ntk_t * p, int i, int k ) { return Acb_ObjFanins(p, i)[k+1]; } static inline int Acb_ObjFaninNum( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[0]; } static inline int Acb_ObjFanoutNum( Acb_Ntk_t * p, int i ) { return Vec_IntSize( Vec_WecEntry(&p->vFanouts, i) ); } -static inline Vec_Int_t * Acb_ObjFanoutVec( Acb_Ntk_t * p, int i ) { return Vec_WecEntry( &p->vFanouts, i ); } +static inline Vec_Int_t * Acb_ObjFanoutVec( Acb_Ntk_t * p, int i ) { assert(i>0); return Vec_WecEntry( &p->vFanouts, i ); } +static inline int Acb_ObjFanout( Acb_Ntk_t * p, int i, int k ) { return Vec_IntEntry( Acb_ObjFanoutVec(p, i), k ); } static inline int Acb_ObjFanin0( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[1]; } static inline int Acb_ObjCioId( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[2]; } @@ -276,7 +277,6 @@ static inline int Acb_ObjLevelR( Acb_Ntk_t * p, int i ) static inline int Acb_ObjPathD( Acb_Ntk_t * p, int i ) { assert(i>0); return Vec_IntEntry(&p->vPathD, i); } static inline int Acb_ObjPathR( Acb_Ntk_t * p, int i ) { assert(i>0); return Vec_IntEntry(&p->vPathR, i); } static inline float Acb_ObjCounts( Acb_Ntk_t * p, int i ) { assert(i>0); return Vec_FltEntry(&p->vCounts, i); } -static inline Vec_Int_t * Acb_ObjFanout( Acb_Ntk_t * p, int i ) { assert(i>0); return Vec_WecEntry(&p->vFanouts, i); } static inline Vec_Str_t * Acb_ObjCnfs( Acb_Ntk_t * p, int i ) { assert(i>0); return (Vec_Str_t *)Vec_WecEntry(&p->vCnfs, i); } static inline void Acb_ObjSetCopy( Acb_Ntk_t * p, int i, int x ) { assert(Acb_ObjCopy(p, i) == -1); Vec_IntWriteEntry( &p->vObjCopy, i, x ); } @@ -361,6 +361,8 @@ static inline void Acb_NtkIncTravId( Acb_Ntk_t * p ) for ( i = Vec_StrSize(&p->vObjType)-1; i > 0; i-- ) if ( !Acb_ObjType(p, i) ) {} else #define Acb_NtkForEachNode( p, i ) \ for ( i = 1; i < Vec_StrSize(&p->vObjType); i++ ) if ( !Acb_ObjType(p, i) || Acb_ObjIsCio(p, i) ) {} else +#define Acb_NtkForEachNodeSupp( p, i, nSuppSize ) \ + for ( i = 1; i < Vec_StrSize(&p->vObjType); i++ ) if ( !Acb_ObjType(p, i) || Acb_ObjIsCio(p, i) || Acb_ObjFaninNum(p, i) != nSuppSize ) {} else #define Acb_NtkForEachNodeReverse( p, i ) \ for ( i = Vec_StrSize(&p->vObjType)-1; i > 0; i-- ) if ( !Acb_ObjType(p, i) || Acb_ObjIsCio(p, i) ) {} else #define Acb_NtkForEachObjType( p, Type, i ) \ @@ -403,12 +405,35 @@ static inline int Acb_ObjFonNum( Acb_Ntk_t * p, int iObj ) Count++; return Count; } +static inline int Acb_ObjWhatFanin( Acb_Ntk_t * p, int iObj, int iFaninGiven ) +{ + int k, iFanin, * pFanins; + Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k ) + if ( iFanin == iFaninGiven ) + return k; + return -1; +} static inline void Acb_ObjAddFanin( Acb_Ntk_t * p, int iObj, int iFanin ) { int * pFanins = Acb_ObjFanins( p, iObj ); assert( pFanins[ 1 + pFanins[0] ] == -1 ); pFanins[ 1 + pFanins[0]++ ] = iFanin; } +static inline void Acb_ObjDeleteFaninIndex( Acb_Ntk_t * p, int iObj, int iFaninIndex ) +{ + int i, * pFanins = Acb_ObjFanins( p, iObj ); + pFanins[0]--; + for ( i = iFaninIndex; i < pFanins[0]; i++ ) + pFanins[ 1 + i ] = pFanins[ 2 + i ]; + pFanins[ 1 + pFanins[0] ] = -1; +} +static inline void Acb_ObjDeleteFanin( Acb_Ntk_t * p, int iObj, int iFanin ) +{ + int * pFanins = Acb_ObjFanins( p, iObj ); + int iFaninIndex = Acb_ObjWhatFanin( p, iObj, iFanin ); + assert( pFanins[ 1 + iFaninIndex ] == iFanin ); + Acb_ObjDeleteFaninIndex( p, iObj, iFaninIndex ); +} static inline void Acb_ObjAddFanins( Acb_Ntk_t * p, int iObj, Vec_Int_t * vFanins ) { int i, iFanin; @@ -495,12 +520,23 @@ static inline void Acb_ObjDelete( Acb_Ntk_t * p, int iObj ) Acb_ObjForEachFon( p, iObj, i ) Acb_ObjCleanType( p, i ); } +static inline void Acb_ObjAddFaninFanoutOne( Acb_Ntk_t * p, int iObj, int iFanin ) +{ + Vec_IntPush( Vec_WecEntry(&p->vFanouts, iFanin), iObj ); + Acb_ObjAddFanin( p, iObj, iFanin ); +} static inline void Acb_ObjAddFaninFanout( Acb_Ntk_t * p, int iObj ) { int k, iFanin, * pFanins; Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k ) Vec_IntPush( Vec_WecEntry(&p->vFanouts, iFanin), iObj ); } +static inline void Acb_ObjRemoveFaninFanoutOne( Acb_Ntk_t * p, int iObj, int iFanin ) +{ + int RetValue = Vec_IntRemove( Vec_WecEntry(&p->vFanouts, iFanin), iObj ); + assert( RetValue ); + Acb_ObjDeleteFanin( p, iObj, iFanin ); +} static inline void Acb_ObjRemoveFaninFanout( Acb_Ntk_t * p, int iObj ) { int k, iFanin, * pFanins; @@ -510,6 +546,19 @@ static inline void Acb_ObjRemoveFaninFanout( Acb_Ntk_t * p, int iObj ) assert( RetValue ); } } +static inline void Acb_ObjPatchFanin( Acb_Ntk_t * p, int iObj, int iFanin, int iFaninNew ) +{ + int i, RetValue, * pFanins = Acb_ObjFanins( p, iObj ); + assert( iFanin != iFaninNew ); + for ( i = 0; i < pFanins[0]; i++ ) + if ( pFanins[ 1 + i ] == iFanin ) + pFanins[ 1 + i ] = iFaninNew; + if ( !Acb_NtkHasObjFanout(p) ) + return; + RetValue = Vec_IntRemove( Vec_WecEntry(&p->vFanouts, iFanin), iObj ); + assert( RetValue ); + Vec_IntPush( Vec_WecEntry(&p->vFanouts, iFaninNew), iObj ); +} static inline void Acb_NtkCreateFanout( Acb_Ntk_t * p ) { int iObj; diff --git a/src/base/acb/acbAbc.c b/src/base/acb/acbAbc.c index 2b07a202..7b215a56 100644 --- a/src/base/acb/acbAbc.c +++ b/src/base/acb/acbAbc.c @@ -271,6 +271,28 @@ Abc_Ntk_t * Abc_NtkOptMfse( Abc_Ntk_t * pNtk, Acb_Par_t * pPars ) return pNtkNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkOptPush( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose ) +{ + extern void Acb_NtkPushLogic( Acb_Ntk_t * p, int nLutSize, int fVerbose ); + Abc_Ntk_t * pNtkNew; + Acb_Ntk_t * p = Acb_NtkFromAbc( pNtk ); + Acb_NtkPushLogic( p, nLutSize, fVerbose ); + pNtkNew = Acb_NtkToAbc( pNtk, p ); + Acb_ManFree( p->pDesign ); + return pNtkNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/acb/acbMfs.c b/src/base/acb/acbMfs.c index d8c6fb16..9fce00f8 100644 --- a/src/base/acb/acbMfs.c +++ b/src/base/acb/acbMfs.c @@ -1576,7 +1576,7 @@ cleanup: void Acb_NtkOpt( Acb_Ntk_t * pNtk, Acb_Par_t * pPars ) { Acb_Mfs_t * pMan = Acb_MfsStart( pNtk, pPars ); - //if ( pPars->fVerbose ) + if ( pPars->fVerbose ) printf( "%s-optimization parameters: TfiLev(I) = %d TfoLev(O) = %d WinMax(W) = %d LutSize = %d\n", pMan->pPars->fArea ? "Area" : "Delay", pMan->pPars->nTfiLevMax, pMan->pPars->nTfoLevMax, pMan->pPars->nWinNodeMax, pMan->pPars->nLutSize ); Acb_NtkCreateFanout( pNtk ); // fanout data structure @@ -1592,8 +1592,8 @@ void Acb_NtkOpt( Acb_Ntk_t * pNtk, Acb_Par_t * pPars ) if ( iObj < nNodes && !Vec_BitEntry(vVisited, iObj) && Acb_NtkObjMffcEstimate(pNtk, iObj) >= n ) { pMan->nNodes++; - if ( iObj != 103 ) - continue; + //if ( iObj != 103 ) + // continue; //Acb_NtkOptNode( pMan, iObj ); while ( (RetValue = Acb_NtkOptNode(pMan, iObj)) && Acb_ObjFaninNum(pNtk, iObj) ); Vec_BitWriteEntry( vVisited, iObj, 1 ); @@ -1609,13 +1609,13 @@ void Acb_NtkOpt( Acb_Ntk_t * pNtk, Acb_Par_t * pPars ) int iObj = Vec_QuePop(pNtk->vQue); if ( !Acb_ObjType(pNtk, iObj) ) continue; - if ( iObj != 103 ) - continue; + //if ( iObj != 103 ) + // continue; //printf( "Trying node %4d (%4d) ", iObj, Value ); Acb_NtkOptNode( pMan, iObj ); } } - //if ( pPars->fVerbose ) + if ( pPars->fVerbose ) { pMan->timeTotal = Abc_Clock() - pMan->timeTotal; printf( "Node = %d Win = %d (Ave = %d) DivAve = %d Change = %d C = %d N1 = %d N2 = %d N3 = %d Over = %d Str = %d 2Node = %d.\n", diff --git a/src/base/acb/acbPush.c b/src/base/acb/acbPush.c new file mode 100644 index 00000000..01de31db --- /dev/null +++ b/src/base/acb/acbPush.c @@ -0,0 +1,372 @@ +/**CFile**************************************************************** + + FileName [acbPush.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [Implementation of logic pushing.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - July 21, 2015.] + + Revision [$Id: acbPush.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acb.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Pushing logic to the fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acb_ObjPushToFanout( Acb_Ntk_t * p, int iObj, int iFaninIndex, int iFanout ) +{ + word c0, uTruthObjNew = 0, uTruthObj = Acb_ObjTruth( p, iObj ), Gate; + word c1, uTruthFanNew = 0, uTruthFan = Acb_ObjTruth( p, iFanout ); + int DecType = Abc_TtCheckOutAnd( uTruthObj, iFaninIndex, &uTruthObjNew ); + int iFanin = Acb_ObjFanin( p, iObj, iFaninIndex ); + int iFanoutObjIndex = Acb_ObjWhatFanin( p, iFanout, iObj ); + int iFanoutFaninIndex = Acb_ObjWhatFanin( p, iFanout, iFanin ); + if ( iFanoutFaninIndex == -1 ) + iFanoutFaninIndex = Acb_ObjFaninNum(p, iFanout); + assert( !Acb_ObjIsCio(p, iObj) ); + assert( !Acb_ObjIsCio(p, iFanout) ); + assert( iFanoutFaninIndex >= 0 ); + assert( iFaninIndex < Acb_ObjFaninNum(p, iObj) ); + assert( Acb_ObjFanoutNum(p, iObj) == 1 ); + // compute new function of the fanout + c0 = Abc_Tt6Cofactor0( uTruthFan, iFanoutObjIndex ); + c1 = Abc_Tt6Cofactor1( uTruthFan, iFanoutObjIndex ); + if ( DecType == 0 ) // F = i * G + Gate = s_Truths6[iFanoutFaninIndex] & s_Truths6[iFanoutObjIndex]; + else if ( DecType == 1 ) // F = ~i * G + Gate = ~s_Truths6[iFanoutFaninIndex] & s_Truths6[iFanoutObjIndex]; + else if ( DecType == 2 ) // F = ~i + G + Gate = ~s_Truths6[iFanoutFaninIndex] | s_Truths6[iFanoutObjIndex]; + else if ( DecType == 3 ) // F = i + G + Gate = s_Truths6[iFanoutFaninIndex] | s_Truths6[iFanoutObjIndex]; + else if ( DecType == 4 ) // F = i # G + Gate = s_Truths6[iFanoutFaninIndex] ^ s_Truths6[iFanoutObjIndex]; + else assert( 0 ); + uTruthFanNew = (~Gate & c0) | (Gate & c1); + // update functions + Vec_WrdWriteEntry( &p->vObjTruth, iObj, Abc_Tt6RemoveVar(uTruthObjNew, iFaninIndex) ); + Vec_WrdWriteEntry( &p->vObjTruth, iFanout, uTruthFanNew ); + // update fanins + Acb_ObjRemoveFaninFanoutOne( p, iObj, iFanin ); + if ( iFanoutFaninIndex == Acb_ObjFaninNum(p, iFanout) ) // adding new + Acb_ObjAddFaninFanoutOne( p, iFanout, iFanin ); +} + +/**Function************************************************************* + + Synopsis [Pushing logic to the fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acb_ObjPushToFanin( Acb_Ntk_t * p, int iObj, int iFaninIndex2, int iFanin ) +{ + word uTruthObjNew = 0, uTruthObj = Acb_ObjTruth( p, iObj ); + word uTruthFanNew = 0, uTruthFan = Acb_ObjTruth( p, iFanin ); + int iFaninIndex = Acb_ObjWhatFanin( p, iObj, iFanin ); + int DecType = Abc_TtCheckDsdAnd( uTruthObj, iFaninIndex, iFaninIndex2, &uTruthObjNew ); + int iFanin2 = Acb_ObjFanin( p, iObj, iFaninIndex2 ); + int iFaninFaninIndex = Acb_ObjWhatFanin( p, iFanin, iFanin2 ); + if ( iFaninFaninIndex == -1 ) + iFaninFaninIndex = Acb_ObjFaninNum(p, iFanin); + assert( !Acb_ObjIsCio(p, iObj) ); + assert( !Acb_ObjIsCio(p, iFanin) ); + assert( iFaninIndex < Acb_ObjFaninNum(p, iObj) ); + assert( iFaninIndex2 < Acb_ObjFaninNum(p, iObj) ); + assert( iFaninIndex != iFaninIndex2 ); + assert( Acb_ObjFanoutNum(p, iFanin) == 1 ); + // compute new function of the fanout + if ( DecType == 0 ) // i * j + uTruthFanNew = uTruthFan & s_Truths6[iFaninFaninIndex]; + else if ( DecType == 1 ) // i * !j + uTruthFanNew = ~uTruthFan & s_Truths6[iFaninFaninIndex]; + else if ( DecType == 2 ) // !i * j + uTruthFanNew = uTruthFan & ~s_Truths6[iFaninFaninIndex]; + else if ( DecType == 3 ) // !i * !j + uTruthFanNew = ~uTruthFan & ~s_Truths6[iFaninFaninIndex]; + else if ( DecType == 4 ) // i # j + uTruthFanNew = uTruthFan ^ s_Truths6[iFaninFaninIndex]; + else assert( 0 ); + // update functions + Vec_WrdWriteEntry( &p->vObjTruth, iObj, Abc_Tt6RemoveVar(uTruthObjNew, iFaninIndex2) ); + Vec_WrdWriteEntry( &p->vObjTruth, iFanin, uTruthFanNew ); + // update fanins + Acb_ObjRemoveFaninFanoutOne( p, iObj, iFanin2 ); + if ( iFaninFaninIndex == Acb_ObjFaninNum(p, iFanin) ) // adding new + Acb_ObjAddFaninFanoutOne( p, iFanin, iFanin2 ); +} + +/**Function************************************************************* + + Synopsis [Removing constants, buffers, duplicated fanins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Acb_ObjFindNodeFanout( Acb_Ntk_t * p, int iObj ) +{ + int i, iFanout; + Acb_ObjForEachFanout( p, iObj, iFanout, i ) + if ( !Acb_ObjIsCio(p, iFanout) ) + return iFanout; + return -1; +} +int Acb_ObjSuppMin_int( Acb_Ntk_t * p, int iObj ) +{ + int k, iFanin, * pFanins; + word uTruth = Acb_ObjTruth( p, iObj ); + Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k ) + { + if ( Abc_Tt6HasVar(uTruth, k) ) + continue; + Acb_ObjDeleteFaninIndex( p, iObj, k ); + Vec_IntRemove( Vec_WecEntry(&p->vFanouts, iFanin), iObj ); + Vec_WrdWriteEntry( &p->vObjTruth, iObj, Abc_Tt6RemoveVar(uTruth, k) ); + return 1; + } + return 0; +} +void Acb_ObjSuppMin( Acb_Ntk_t * p, int iObj ) +{ + while ( Acb_ObjSuppMin_int(p, iObj) ); +} +void Acb_ObjRemoveDup( Acb_Ntk_t * p, int iObj, int i, int j ) +{ + word c00, c11, uTruthNew, uTruth = Acb_ObjTruth( p, iObj ); + assert( !Acb_ObjIsCio(p, iObj) ); + assert( Acb_ObjFanin(p, iObj, i) == Acb_ObjFanin(p, iObj, j) ); + c00 = Abc_Tt6Cofactor0( Abc_Tt6Cofactor0(uTruth, i), j ); + c11 = Abc_Tt6Cofactor1( Abc_Tt6Cofactor1(uTruth, i), j ); + uTruthNew = (~s_Truths6[i] & c00) | (s_Truths6[i] & c11); + Vec_WrdWriteEntry( &p->vObjTruth, iObj, Abc_Tt6RemoveVar(uTruthNew, j) ); + Acb_ObjDeleteFaninIndex( p, iObj, j ); + Vec_IntRemove( Vec_WecEntry(&p->vFanouts, iObj), Acb_ObjFanin(p, iObj, j) ); + Acb_ObjSuppMin( p, iObj ); +} +int Acb_ObjRemoveDupFanins_int( Acb_Ntk_t * p, int iObj ) +{ + int i, k, * pFanins = Acb_ObjFanins( p, iObj ); + for ( i = 0; i < pFanins[0]; i++ ) + for ( k = i+1; k < pFanins[0]; k++ ) + { + if ( pFanins[1+i] != pFanins[1+k] ) + continue; + Acb_ObjRemoveDup( p, iObj, i, k ); + return 1; + } + return 0; +} +void Acb_ObjRemoveDupFanins( Acb_Ntk_t * p, int iObj ) +{ + assert( !Acb_ObjIsCio(p, iObj) ); + while ( Acb_ObjRemoveDupFanins_int(p, iObj) ); +} +void Acb_ObjRemoveConst( Acb_Ntk_t * p, int iObj ) +{ + int iFanout; + word uTruth = Acb_ObjTruth( p, iObj ); + assert( !Acb_ObjIsCio(p, iObj) ); + assert( Acb_ObjFaninNum(p, iObj) == 0 ); + assert( uTruth == 0 || ~uTruth == 0 ); + while ( (iFanout = Acb_ObjFindNodeFanout(p, iObj)) >= 0 ) + { + int iObjIndex = Acb_ObjWhatFanin( p, iFanout, iObj ); + word uTruthF = Acb_ObjTruth( p, iFanout ); + Acb_ObjRemoveFaninFanoutOne( p, iFanout, iObj ); + uTruthF = (uTruth & 1) ? Abc_Tt6Cofactor1(uTruthF, iObjIndex) : Abc_Tt6Cofactor0(uTruthF, iObjIndex); + Vec_WrdWriteEntry( &p->vObjTruth, iFanout, Abc_Tt6RemoveVar(uTruthF, iObjIndex) ); + Acb_ObjSuppMin( p, iFanout ); + } + if ( Acb_ObjFanoutNum(p, iObj) == 0 ) + Acb_ObjCleanType( p, iObj ); +} +void Acb_ObjRemoveBufInv( Acb_Ntk_t * p, int iObj ) +{ + int iFanout; + word uTruth = Acb_ObjTruth( p, iObj ); + assert( !Acb_ObjIsCio(p, iObj) ); + assert( Acb_ObjFaninNum(p, iObj) == 1 ); + assert( uTruth == s_Truths6[0] || ~uTruth == s_Truths6[0] ); + while ( (iFanout = Acb_ObjFindNodeFanout(p, iObj)) >= 0 ) + { + int iFanin = Acb_ObjFanin( p, iObj, 0 ); + int iObjIndex = Acb_ObjWhatFanin( p, iFanout, iObj ); + Acb_ObjPatchFanin( p, iFanout, iObj, iFanin ); + if ( uTruth & 1 ) // inv + { + word uTruthF = Acb_ObjTruth( p, iFanout ); + Vec_WrdWriteEntry( &p->vObjTruth, iFanout, Abc_Tt6Flip(uTruthF, iObjIndex) ); + } + Acb_ObjRemoveDupFanins( p, iFanout ); + } + while ( (uTruth & 1) == 0 && Acb_ObjFanoutNum(p, iObj) > 0 ) + { + int iFanin = Acb_ObjFanin( p, iObj, 0 ); + int iFanout = Acb_ObjFanout( p, iObj, 0 ); + assert( Acb_ObjIsCo(p, iFanout) ); + Acb_ObjPatchFanin( p, iFanout, iObj, iFanin ); + } + if ( Acb_ObjFanoutNum(p, iObj) == 0 ) + { + Acb_ObjRemoveFaninFanout( p, iObj ); + Acb_ObjRemoveFanins( p, iObj ); + Acb_ObjCleanType( p, iObj ); + } +} + +/**Function************************************************************* + + Synopsis [Check if the node can have its logic pushed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Acb_ObjFindFaninPushableIndex( Acb_Ntk_t * p, int iObj, int iFanIndex ) +{ + int k, iFanin, * pFanins; + Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k ) + if ( k != iFanIndex && Abc_TtCheckDsdAnd(Acb_ObjTruth(p, iObj), k, iFanIndex, NULL) >= 0 ) + return k; + return -1; +} +static inline int Acb_ObjFindFanoutPushableIndex( Acb_Ntk_t * p, int iObj ) +{ + int k, iFanin, * pFanins; + Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k ) + if ( Abc_TtCheckOutAnd(Acb_ObjTruth(p, iObj), k, NULL) >= 0 ) + return k; + return -1; +} +int Acb_ObjPushToFanins( Acb_Ntk_t * p, int iObj, int nLutSize ) +{ + int k, k2, iFanin, * pFanins; + if ( Acb_ObjFaninNum(p, iObj) < 2 ) + return 0; + Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k ) + { + if ( Acb_ObjIsCi(p, iFanin) ) + continue; + if ( Acb_ObjFanoutNum(p, iFanin) > 1 ) + continue; + if ( Acb_ObjFaninNum(p, iFanin) == nLutSize ) + continue; + if ( (k2 = Acb_ObjFindFaninPushableIndex(p, iObj, k)) == -1 ) + continue; + //printf( "Object %4d : Pushing fanin %d (%d) into fanin %d.\n", iObj, Acb_ObjFanin(p, iObj, k2), k2, iFanin ); + Acb_ObjPushToFanin( p, iObj, k2, iFanin ); + return 1; + } + if ( Acb_ObjFaninNum(p, iObj) == 2 && Acb_ObjFanoutNum(p, iObj) == 1 ) + { + int iFanout = Acb_ObjFanout( p, iObj, 0 ); + if ( !Acb_ObjIsCo(p, iFanout) && Acb_ObjFaninNum(p, iFanout) < nLutSize ) + { + k2 = Acb_ObjFindFanoutPushableIndex( p, iObj ); + //printf( "Object %4d : Pushing fanin %d (%d) into fanout %d.\n", iObj, Acb_ObjFanin(p, iObj, k2), k2, iFanout ); + Acb_ObjPushToFanout( p, iObj, k2, iFanout ); + return 1; + } + } + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acb_NtkPushLogic( Acb_Ntk_t * p, int nLutSize, int fVerbose ) +{ + int n = 0, iObj, nNodes = Acb_NtkNodeNum(p), nPushes = 0; + Acb_NtkCreateFanout( p ); // fanout data structure + Acb_NtkForEachNodeSupp( p, iObj, 0 ) + Acb_ObjRemoveConst( p, iObj ); + Acb_NtkForEachNodeSupp( p, iObj, 1 ) + Acb_ObjRemoveBufInv( p, iObj ); + for ( n = 2; n <= nLutSize; n++ ) + Acb_NtkForEachNodeSupp( p, iObj, n ) + { + while ( Acb_ObjPushToFanins(p, iObj, nLutSize) ) + nPushes++; + if ( Acb_ObjFaninNum(p, iObj) == 1 ) + Acb_ObjRemoveBufInv( p, iObj ); + } + printf( "Saved %d nodes after %d pushes.\n", nNodes - Acb_NtkNodeNum(p), nPushes ); +} + +/**Function************************************************************* + + Synopsis [Pushing logic to the fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acb_NtkPushLogic2( Acb_Ntk_t * p, int nLutSize, int fVerbose ) +{ + int iObj; + Acb_NtkCreateFanout( p ); // fanout data structure + Acb_NtkForEachObj( p, iObj ) + if ( !Acb_ObjIsCio(p, iObj) ) + break; + Acb_ObjPushToFanout( p, iObj, Acb_ObjFaninNum(p, iObj)-1, Acb_ObjFanout(p, iObj, 0) ); +// Acb_ObjPushToFanin( p, Acb_ObjFanout(p, iObj, 0), Acb_ObjFaninNum(p, iObj)-1, iObj ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/acb/module.make b/src/base/acb/module.make index 06affeff..46294f9f 100644 --- a/src/base/acb/module.make +++ b/src/base/acb/module.make @@ -3,5 +3,6 @@ SRC += src/base/acb/acbAbc.c \ src/base/acb/acbCom.c \ src/base/acb/acbFunc.c \ src/base/acb/acbMfs.c \ + src/base/acb/acbPush.c \ src/base/acb/acbSets.c \ src/base/acb/acbUtil.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 7086cc9f..eff3acba 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -325,7 +325,7 @@ extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ -extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth, int fNoCleanup ); +extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth, int fNoCleanup, int fCreateMiter ); /*=== wlcCom.c ========================================================*/ extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index d0ef1f07..a183fb5f 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -320,7 +320,7 @@ static Vec_Int_t * Wlc_NtkGetCoreSels( Gia_Man_t * pFrames, int nFrames, int fir static Gia_Man_t * Wlc_NtkUnrollWoCex(Wlc_Ntk_t * pChoice, int nFrames, int first_sel_pi, int num_sel_pis) { - Gia_Man_t * pGiaChoice = Wlc_NtkBitBlast( pChoice, NULL, -1, 0, 0, 0, 0, 0 ); + Gia_Man_t * pGiaChoice = Wlc_NtkBitBlast( pChoice, NULL, -1, 0, 0, 0, 0, 0, 0 ); Gia_Man_t * pFrames = NULL, * pGia; Gia_Obj_t * pObj, * pObjRi; int f, i; @@ -366,7 +366,7 @@ static Gia_Man_t * Wlc_NtkUnrollWoCex(Wlc_Ntk_t * pChoice, int nFrames, int firs static Gia_Man_t * Wlc_NtkUnrollWithCex(Wlc_Ntk_t * pChoice, Abc_Cex_t * pCex, int nbits_old_pis, int num_sel_pis, int * p_num_ppis, int sel_pi_first, int fUsePPI) { - Gia_Man_t * pGiaChoice = Wlc_NtkBitBlast( pChoice, NULL, -1, 0, 0, 0, 0, 0 ); + Gia_Man_t * pGiaChoice = Wlc_NtkBitBlast( pChoice, NULL, -1, 0, 0, 0, 0, 0, 0 ); int nbits_new_pis = Wlc_NtkNumPiBits( pChoice ); int num_ppis = nbits_new_pis - nbits_old_pis - num_sel_pis; int num_undc_pis = Gia_ManPiNum(pGiaChoice) - nbits_new_pis; @@ -560,7 +560,7 @@ Wlc_Ntk_t * Wlc_NtkIntroduceChoices( Wlc_Ntk_t * pNtk, Vec_Int_t * vBlacks, Vec_ static Abc_Cex_t * Wlc_NtkCexIsReal( Wlc_Ntk_t * pOrig, Abc_Cex_t * pCex ) { - Gia_Man_t * pGiaOrig = Wlc_NtkBitBlast( pOrig, NULL, -1, 0, 0, 0, 0, 0 ); + Gia_Man_t * pGiaOrig = Wlc_NtkBitBlast( pOrig, NULL, -1, 0, 0, 0, 0, 0, 0 ); int f, i; Gia_Obj_t * pObj, * pObjRi; Abc_Cex_t * pCexReal = Abc_CexAlloc( Gia_ManRegNum(pGiaOrig), Gia_ManPiNum(pGiaOrig), pCex->iFrame + 1 ); @@ -1401,7 +1401,7 @@ Aig_Man_t * Wla_ManBitBlast( Wla_Man_t * pWla, Wlc_Ntk_t * pAbs ) Gia_Man_t * pTemp; Aig_Man_t * pAig; - pWla->pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0, 0 ); + pWla->pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0, 0, 0 ); // if the abstraction has flops with DC-init state, // new PIs were introduced by bit-blasting at the end of the PI list @@ -1829,7 +1829,7 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, NULL, pPars->fVerbose ); } - pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0, 0 ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0, 0, 0 ); // if the abstraction has flops with DC-init state, // new PIs were introduced by bit-blasting at the end of the PI list diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c index ff0092e6..4b2e6740 100644 --- a/src/base/wlc/wlcAbs2.c +++ b/src/base/wlc/wlcAbs2.c @@ -328,7 +328,7 @@ int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // get abstracted GIA and the set of pseudo-PIs (vPisNew) pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); - pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0, 0 ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0, 0, 0 ); // if the abstraction has flops with DC-init state, // new PIs were introduced by bit-blasting at the end of the PI list diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 02cb2b1c..b2d0e287 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -868,14 +868,14 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int SeeAlso [] ***********************************************************************/ -Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nOutputRange, int fGiaSimple, int fAddOutputs, int fBooth, int fNoCleanup ) +Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nOutputRange, int fGiaSimple, int fAddOutputs, int fBooth, int fNoCleanup, int fCreateMiter ) { int fVerbose = 0; int fUseOldMultiplierBlasting = 0; int fSkipBitRange = 0; Tim_Man_t * pManTime = NULL; Gia_Man_t * pTemp, * pNew, * pExtra = NULL; - Wlc_Obj_t * pObj; + 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; @@ -1211,6 +1211,31 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in for ( k = 1; k < nRange; k++ ) Vec_IntPush( vRes, 0 ); } + else if ( pObj->Type == WLC_OBJ_COMP_NOTEQU && Wlc_ObjFaninNum(pObj) > 2 ) + { + // find the max range + int a, b, iRes = 1, nRangeMax = Abc_MaxInt( nRange0, nRange1 ); + for ( k = 2; k < Wlc_ObjFaninNum(pObj); k++ ) + nRangeMax = Abc_MaxInt( nRangeMax, Wlc_ObjRange( Wlc_NtkObj(p, Wlc_ObjFaninId(pObj, k)) ) ); + // create pairwise distinct + for ( a = 0; a < Wlc_ObjFaninNum(pObj); a++ ) + for ( b = a+1; b < Wlc_ObjFaninNum(pObj); b++ ) + { + int nRange0 = Wlc_ObjRange( Wlc_NtkObj(p, Wlc_ObjFaninId(pObj, a)) ); + int nRange1 = Wlc_ObjRange( Wlc_NtkObj(p, Wlc_ObjFaninId(pObj, b)) ); + int * pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj, a)) ); + int * pFans1 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj, b)) ); + int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, 0 ); + int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, 0 ); + int iLit = 0; + for ( k = 0; k < nRangeMax; k++ ) + iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, pArg0[k], pArg1[k]) ); + iRes = Gia_ManHashAnd( pNew, iRes, iLit ); + } + Vec_IntFill( vRes, 1, iRes ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + } else if ( pObj->Type == WLC_OBJ_COMP_EQU || pObj->Type == WLC_OBJ_COMP_NOTEQU ) { int iLit = 0, nRangeMax = Abc_MaxInt( nRange0, nRange1 ); @@ -1363,38 +1388,91 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in Vec_IntFree( vTemp2 ); Vec_IntFree( vRes ); // create COs - Wlc_NtkForEachCo( p, pObj, i ) + if ( fCreateMiter ) { - // skip all outputs except the given ones - if ( iOutput >= 0 && (i < iOutput || i >= iOutput + nOutputRange) ) - continue; - // create additional PO literals - if ( vAddOutputs && pObj->fIsFi ) - { - Vec_IntForEachEntry( vAddOutputs, iLit, k ) - Gia_ManAppendCo( pNew, iLit ); - printf( "Created %d additional POs for %d interesting internal word-level variables.\n", Vec_IntSize(vAddOutputs), Vec_IntSize(vAddObjs) ); - Vec_IntFreeP( &vAddOutputs ); - } - nRange = Wlc_ObjRange( pObj ); - pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) ); - if ( fVerbose ) - printf( "%s(%d) ", Wlc_ObjName(p, Wlc_ObjId(p, pObj)), Gia_ManCoNum(pNew) ); - if ( Wlc_ObjRangeIsReversed(pObj) ) + int nPairs = 0, nBits = 0; + assert( Wlc_NtkPoNum(p) % 2 == 0 ); + Wlc_NtkForEachCo( p, pObj, i ) { - for ( k = 0; k < nRange; k++ ) - Gia_ManAppendCo( pNew, pFans0[nRange-1-k] ); + if ( pObj->fIsFi ) + { + nRange = Wlc_ObjRange( pObj ); + pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) ); + if ( Wlc_ObjRangeIsReversed(pObj) ) + { + for ( k = 0; k < nRange; k++ ) + Gia_ManAppendCo( pNew, pFans0[nRange-1-k] ); + } + else + { + for ( k = 0; k < nRange; k++ ) + Gia_ManAppendCo( pNew, pFans0[k] ); + } + nFFins += nRange; + continue; + } + pObj2 = Wlc_NtkCo( p, ++i ); + nRange1 = Wlc_ObjRange( pObj ); + nRange2 = Wlc_ObjRange( pObj2 ); + assert( nRange1 == nRange2 ); + pFans1 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) ); + pFans2 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj2)) ); + if ( Wlc_ObjRangeIsReversed(pObj) ) + { + for ( k = 0; k < nRange1; k++ ) + { + Gia_ManAppendCo( pNew, pFans1[nRange1-1-k] ); + Gia_ManAppendCo( pNew, pFans2[nRange2-1-k] ); + } + } + else + { + for ( k = 0; k < nRange1; k++ ) + { + Gia_ManAppendCo( pNew, pFans1[k] ); + Gia_ManAppendCo( pNew, pFans2[k] ); + } + } + nPairs++; + nBits += nRange1; } - else + printf( "Derived a dual-output miter with %d pairs of bits belonging to %d pairs of word-level outputs.\n", nBits, nPairs ); + } + else + { + Wlc_NtkForEachCo( p, pObj, i ) { - for ( k = 0; k < nRange; k++ ) - Gia_ManAppendCo( pNew, pFans0[k] ); + // skip all outputs except the given ones + if ( iOutput >= 0 && (i < iOutput || i >= iOutput + nOutputRange) ) + continue; + // create additional PO literals + if ( vAddOutputs && pObj->fIsFi ) + { + Vec_IntForEachEntry( vAddOutputs, iLit, k ) + Gia_ManAppendCo( pNew, iLit ); + printf( "Created %d additional POs for %d interesting internal word-level variables.\n", Vec_IntSize(vAddOutputs), Vec_IntSize(vAddObjs) ); + Vec_IntFreeP( &vAddOutputs ); + } + nRange = Wlc_ObjRange( pObj ); + pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) ); + if ( fVerbose ) + printf( "%s(%d) ", Wlc_ObjName(p, Wlc_ObjId(p, pObj)), Gia_ManCoNum(pNew) ); + if ( Wlc_ObjRangeIsReversed(pObj) ) + { + for ( k = 0; k < nRange; k++ ) + Gia_ManAppendCo( pNew, pFans0[nRange-1-k] ); + } + else + { + for ( k = 0; k < nRange; k++ ) + Gia_ManAppendCo( pNew, pFans0[k] ); + } + if ( pObj->fIsFi ) + nFFins += nRange; } - if ( pObj->fIsFi ) - nFFins += nRange; + if ( fVerbose ) + printf( "\n" ); } - if ( fVerbose ) - printf( "\n" ); //Vec_IntErase( vBits ); //Vec_IntErase( &p->vCopies ); // set the number of registers diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 16ed29cc..abcb9e19 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -885,9 +885,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); Vec_Int_t * vBoxIds = NULL; Gia_Man_t * pNew = NULL; - int c, iOutput = -1, nOutputRange = 2, fGiaSimple = 0, fAddOutputs = 0, fMulti = 0, fBooth = 0, fVerbose = 0; + int c, iOutput = -1, nOutputRange = 2, fGiaSimple = 0, fAddOutputs = 0, fMulti = 0, fBooth = 0, fCreateMiter = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORcombvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORcombdvh" ) ) != EOF ) { switch ( c ) { @@ -925,6 +925,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'b': fBooth ^= 1; break; + case 'd': + fCreateMiter ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -951,7 +954,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // transform - pNew = Wlc_NtkBitBlast( pNtk, vBoxIds, iOutput, nOutputRange, fGiaSimple, fAddOutputs, fBooth, 0 ); + pNew = Wlc_NtkBitBlast( pNtk, vBoxIds, iOutput, nOutputRange, fGiaSimple, fAddOutputs, fBooth, 0, fCreateMiter ); Vec_IntFreeP( &vBoxIds ); if ( pNew == NULL ) { @@ -961,7 +964,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameUpdateGia( pAbc, pNew ); return 0; usage: - Abc_Print( -2, "usage: %%blast [-OR num] [-combvh]\n" ); + Abc_Print( -2, "usage: %%blast [-OR num] [-combdvh]\n" ); Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" ); Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", iOutput ); Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", nOutputRange ); @@ -969,6 +972,7 @@ usage: Abc_Print( -2, "\t-o : toggle using additional POs on the word-level boundaries [default = %s]\n", fAddOutputs? "yes": "no" ); Abc_Print( -2, "\t-m : toggle creating boxes for all multipliers in the design [default = %s]\n", fMulti? "yes": "no" ); Abc_Print( -2, "\t-b : toggle generating radix-4 Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle creating dual-output miter [default = %s]\n", fCreateMiter? "yes": "no" ); 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; diff --git a/src/base/wlc/wlcGraft.c b/src/base/wlc/wlcGraft.c index 33de00c5..f1f55eb3 100644 --- a/src/base/wlc/wlcGraft.c +++ b/src/base/wlc/wlcGraft.c @@ -210,7 +210,7 @@ Wlc_Ntk_t * Wlc_NtkGraftMulti( Wlc_Ntk_t * p, int fVerbose ) Gia_Obj_t * pObj; Vec_Int_t * vObjsLHS = Wlc_NtkCollectObjs( p, 0, &nMultiLHS ); Vec_Int_t * vObjsRHS = Wlc_NtkCollectObjs( p, 1, &nMultiRHS ); - Gia_Man_t * pGia = Wlc_NtkBitBlast( p, NULL, -1, 0, 0, 0, 0, 1 ); + Gia_Man_t * pGia = Wlc_NtkBitBlast( p, NULL, -1, 0, 0, 0, 0, 1, 0 ); Vec_Mem_t * vTtMem = Vec_MemAlloc( nWords, 10 ); Vec_MemHashAlloc( vTtMem, 10000 ); @@ -540,7 +540,7 @@ int Sbc_ManWlcNodes( Wlc_Ntk_t * pNtk, Gia_Man_t * p, Vec_Int_t * vGia2Out, int void Sbc_ManDetectMultTest( Wlc_Ntk_t * pNtk, int fVerbose ) { extern Vec_Int_t * Sdb_StoComputeCutsDetect( Gia_Man_t * pGia ); - Gia_Man_t * p = Wlc_NtkBitBlast( pNtk, NULL, -1, 0, 0, 0, 0, 1 ); + Gia_Man_t * p = Wlc_NtkBitBlast( pNtk, NULL, -1, 0, 0, 0, 0, 1, 0 ); Vec_Int_t * vIns, * vGia2Out; int iObjFound = -1; // Gia_Obj_t * pObj; int i; diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index 69a01ab0..230b34ad 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -331,7 +331,7 @@ static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, in Type == WLC_OBJ_LOGIC_OR || // 29: logic OR Type == WLC_OBJ_LOGIC_XOR || // 30: logic XOR Type == WLC_OBJ_COMP_EQU || // 31: compare equal - Type == WLC_OBJ_COMP_NOTEQU || // 32: compare not equal +// Type == WLC_OBJ_COMP_NOTEQU || // 32: compare not equal -- bug fix Type == WLC_OBJ_COMP_LESS || // 33: compare less Type == WLC_OBJ_COMP_MORE || // 34: compare more Type == WLC_OBJ_COMP_LESSEQU || // 35: compare less or equal diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 63a6926b..a829e0fd 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1292,7 +1292,7 @@ void Io_ReadWordTest( char * pFileName ) return; Wlc_WriteVer( pNtk, "test.v", 0, 0 ); - pNew = Wlc_NtkBitBlast( pNtk, NULL, -1, 0, 0, 0, 0, 0 ); + pNew = Wlc_NtkBitBlast( pNtk, NULL, -1, 0, 0, 0, 0, 0, 0 ); Gia_AigerWrite( pNew, "test.aig", 0, 0 ); Gia_ManStop( pNew ); diff --git a/src/base/wlc/wlcSim.c b/src/base/wlc/wlcSim.c index 2ae3c86e..31a8a4a0 100644 --- a/src/base/wlc/wlcSim.c +++ b/src/base/wlc/wlcSim.c @@ -129,7 +129,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int { Gia_Obj_t * pObj; Vec_Ptr_t * vOne, * vRes; - Gia_Man_t * pGia = Wlc_NtkBitBlast( p, NULL, -1, 0, 0, 0, 0, 0 ); + Gia_Man_t * pGia = Wlc_NtkBitBlast( p, NULL, -1, 0, 0, 0, 0, 0, 0 ); Wlc_Obj_t * pWlcObj; int f, i, k, w, nBits, Counter = 0; // allocate simulation info for one timeframe |