diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2013-08-05 18:33:38 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2013-08-05 18:33:38 -0700 |
commit | 1a55882ad98d849f49205f09d9606d11aa609a89 (patch) | |
tree | 4d00bc66a817b5555671ce10bc54afd52a94df94 /src | |
parent | 1558fe6110554c7c732070ef3d6581c963d4ecb3 (diff) | |
download | abc-1a55882ad98d849f49205f09d9606d11aa609a89.tar.gz abc-1a55882ad98d849f49205f09d9606d11aa609a89.tar.bz2 abc-1a55882ad98d849f49205f09d9606d11aa609a89.zip |
Adding new (un)buffering with phase information.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abc/abc.h | 5 | ||||
-rw-r--r-- | src/base/abc/abcNtk.c | 7 | ||||
-rw-r--r-- | src/base/abc/abcUtil.c | 24 | ||||
-rw-r--r-- | src/map/scl/scl.c | 37 | ||||
-rw-r--r-- | src/map/scl/sclBuffer.c | 77 | ||||
-rw-r--r-- | src/map/scl/sclSize.h | 2 |
6 files changed, 142 insertions, 10 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index bba7c9c6..bd0c5bba 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -204,6 +204,7 @@ struct Abc_Ntk_t_ void * pExcare; // the EXDC network (if given) void * pData; // misc Abc_Ntk_t * pCopy; // copy of this network + Vec_Int_t * vPhases; // fanins phases in the mapped netlist float * pLutTimes; // arrivals/requireds/slacks using LUT-delay model Vec_Ptr_t * vOnehots; // names of one-hot-encoded registers Vec_Int_t * vObjPerm; // permutation saved @@ -386,6 +387,8 @@ static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj ) { return Ab static inline Abc_Obj_t * Abc_ObjChild1Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Abc_ObjFanin1(pObj)->pData, Abc_ObjFaninC1(pObj) ); } static inline Abc_Obj_t * Abc_ObjFromLit( Abc_Ntk_t * p, int iLit ) { return Abc_ObjNotCond( Abc_NtkObj(p, Abc_Lit2Var(iLit)), Abc_LitIsCompl(iLit) ); } static inline int Abc_ObjToLit( Abc_Obj_t * p ) { return Abc_Var2Lit( Abc_ObjId(Abc_ObjRegular(p)), Abc_ObjIsComplement(p) ); } +static inline int Abc_ObjFaninPhase( Abc_Obj_t * p, int i ) { assert(p->pNtk->vPhases); return (Vec_IntEntry(p->pNtk->vPhases, Abc_ObjId(p)) >> i) & 1; } +static inline void Abc_ObjFaninFlipPhase( Abc_Obj_t * p,int i){ assert(p->pNtk->vPhases); *Vec_IntEntryP(p->pNtk->vPhases, Abc_ObjId(p)) ^= (1 << i); } // checking the AIG node types static inline int Abc_AigNodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_NtkIsStrash(Abc_ObjRegular(pNode)->pNtk)); return Abc_ObjRegular(pNode)->Type == ABC_OBJ_CONST1; } @@ -999,7 +1002,7 @@ extern ABC_DLL void Abc_NtkInvertConstraints( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkPrintCiLevels( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkReverseTopoOrder( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkIsTopo( Abc_Ntk_t * pNtk ); - +extern ABC_DLL void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk ); /*=== abcVerify.c ==========================================================*/ diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index 3d68871a..1c85efc8 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -323,6 +323,8 @@ void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) // duplicate timing manager if ( pNtk->pManTime ) Abc_NtkTimeInitialize( pNtkNew, pNtk ); + if ( pNtk->vPhases ) + Abc_NtkTransferPhases( pNtkNew, pNtk ); } /**Function************************************************************* @@ -478,6 +480,8 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) // duplicate timing manager if ( pNtk->pManTime ) Abc_NtkTimeInitialize( pNtkNew, pNtk ); + if ( pNtk->vPhases ) + Abc_NtkTransferPhases( pNtkNew, pNtk ); // check correctness if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); @@ -514,6 +518,8 @@ Abc_Ntk_t * Abc_NtkDupDfs( Abc_Ntk_t * pNtk ) // duplicate timing manager if ( pNtk->pManTime ) Abc_NtkTimeInitialize( pNtkNew, pNtk ); + if ( pNtk->vPhases ) + Abc_NtkTransferPhases( pNtkNew, pNtk ); // check correctness if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); @@ -1310,6 +1316,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) // free the timing manager if ( pNtk->pManTime ) Abc_ManTimeStop( pNtk->pManTime ); + Vec_IntFreeP( &pNtk->vPhases ); // start the functionality manager if ( Abc_NtkIsStrash(pNtk) ) Abc_AigFree( (Abc_Aig_t *)pNtk->pManFunc ); diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 892dfee7..bf41ad45 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -2698,6 +2698,30 @@ int Abc_NtkIsTopo( Abc_Ntk_t * pNtk ) return (int)(Counter == 0); } +/**Function************************************************************* + + Synopsis [Transfers phase information to the new network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + assert( pNtk->vPhases != NULL ); + assert( Vec_IntSize(pNtk->vPhases) == Abc_NtkObjNumMax(pNtk) ); + assert( pNtkNew->vPhases == NULL ); + pNtkNew->vPhases = Vec_IntStart( Abc_NtkObjNumMax(pNtkNew) ); + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( pObj->pCopy && !Abc_ObjIsNone( (Abc_Obj_t *)pObj->pCopy ) ) + Vec_IntWriteEntry( pNtkNew->vPhases, Abc_ObjId( (Abc_Obj_t *)pObj->pCopy ), Vec_IntEntry(pNtk->vPhases, i) ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index ac7fa827..e9c4d22c 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -571,16 +571,17 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtkRes; - int FanMin, FanMax, fUseInvs, fBufPis; + int FanMin, FanMax, fAddInvs, fUseInvs, fBufPis; int c, fVerbose; int fOldAlgo = 0; FanMin = 6; FanMax = 14; + fAddInvs = 0; fUseInvs = 0; fBufPis = 0; fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "NMaipvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NMaixpvh" ) ) != EOF ) { switch ( c ) { @@ -610,6 +611,9 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) fOldAlgo ^= 1; break; case 'i': + fAddInvs ^= 1; + break; + case 'x': fUseInvs ^= 1; break; case 'p': @@ -635,9 +639,16 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "This command can only be applied to a logic network.\n" ); return 1; } + if ( fAddInvs && pNtk->vPhases == NULL ) + { + Abc_Print( -1, "Fanin phase information is not avaiable.\n" ); + return 1; + } // modify the current network - if ( fOldAlgo ) + if ( fAddInvs ) + pNtkRes = Abc_SclBufferPhase( pNtk, fVerbose ); + else if ( fOldAlgo ) pNtkRes = Abc_SclPerformBuffering( pNtk, FanMax, fUseInvs, fVerbose ); else pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fBufPis, fVerbose ); @@ -651,12 +662,13 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pAbc->Err, "usage: buffer [-NM num] [-aipvh]\n" ); + fprintf( pAbc->Err, "usage: buffer [-NM num] [-aixpvh]\n" ); fprintf( pAbc->Err, "\t performs buffering of the mapped network\n" ); fprintf( pAbc->Err, "\t-N <num> : the min fanout considered by the algorithm [default = %d]\n", FanMin ); fprintf( pAbc->Err, "\t-M <num> : the max allowed fanout count of node/buffer [default = %d]\n", FanMax ); fprintf( pAbc->Err, "\t-a : toggle using old algorithm [default = %s]\n", fOldAlgo? "yes": "no" ); - fprintf( pAbc->Err, "\t-i : toggle using interters instead of buffers [default = %s]\n", fUseInvs? "yes": "no" ); + fprintf( pAbc->Err, "\t-i : toggle adding interters instead of buffering [default = %s]\n", fAddInvs? "yes": "no" ); + fprintf( pAbc->Err, "\t-x : toggle using interters instead of buffers [default = %s]\n", fUseInvs? "yes": "no" ); fprintf( pAbc->Err, "\t-p : toggle buffering primary inputs [default = %s]\n", fBufPis? "yes": "no" ); fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pAbc->Err, "\t-h : print the command usage\n"); @@ -677,12 +689,15 @@ usage: int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv ) { Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc); - int c, fVerbose = 0; + int c, fRemInv = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ivh" ) ) != EOF ) { switch ( c ) { + case 'i': + fRemInv ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -703,7 +718,10 @@ int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv ) fprintf( pAbc->Err, "The current network is not a logic network.\n" ); return 1; } - pNtkRes = Abc_SclUnBufferPerform( pNtk, fVerbose ); + if ( fRemInv ) + pNtkRes = Abc_SclUnBufferPhase( pNtk, fVerbose ); + else + pNtkRes = Abc_SclUnBufferPerform( pNtk, fVerbose ); if ( pNtkRes == NULL ) { Abc_Print( -1, "The command has failed.\n" ); @@ -713,8 +731,9 @@ int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv ) return 0; usage: - fprintf( pAbc->Err, "usage: unbuffer [-vh]\n" ); + fprintf( pAbc->Err, "usage: unbuffer [-ivh]\n" ); fprintf( pAbc->Err, "\t collapses buffer/inverter trees\n" ); + fprintf( pAbc->Err, "\t-i : toggle removing interters [default = %s]\n", fRemInv? "yes": "no" ); fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pAbc->Err, "\t-h : print the command usage\n"); return 1; diff --git a/src/map/scl/sclBuffer.c b/src/map/scl/sclBuffer.c index f7097fb1..2e82d207 100644 --- a/src/map/scl/sclBuffer.c +++ b/src/map/scl/sclBuffer.c @@ -147,6 +147,83 @@ Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose ) /**Function************************************************************* + Synopsis [Removes buffers and inverters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_SclBufferPhase( Abc_Ntk_t * pNtk, int fVerbose ) +{ + Abc_Ntk_t * pNtkNew; + Vec_Int_t * vInvs; + Abc_Obj_t * pObj, * pFanin, * pFaninNew; + int nNodesOld = Abc_NtkObjNumMax(pNtk); + int i, k, Counter = 0; + assert( pNtk->vPhases != NULL ); + vInvs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + Abc_NtkForEachNodeCo( pNtk, pObj, i ) + { + if ( i >= nNodesOld ) + break; + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + if ( !Abc_ObjFaninPhase(pObj, k) ) + continue; + if ( Vec_IntEntry(vInvs, Abc_ObjId(pFanin)) == 0 ) + { + pFaninNew = Abc_NtkCreateNodeInv( pNtk, pFanin ); + Vec_IntWriteEntry( vInvs, Abc_ObjId(pFanin), Abc_ObjId(pFaninNew) ); + Counter++; + } + pFaninNew = Abc_NtkObj( pNtk, Vec_IntEntry(vInvs, Abc_ObjId(pFanin)) ); + Abc_ObjPatchFanin( pObj, pFanin, pFaninNew ); + } + } +// printf( "Added %d inverters.\n", Counter ); + Vec_IntFree( vInvs ); + Vec_IntFillExtra( pNtk->vPhases, Abc_NtkObjNumMax(pNtk), 0 ); + // duplicate network in topo order + vInvs = pNtk->vPhases; + pNtk->vPhases = NULL; + pNtkNew = Abc_NtkDupDfs( pNtk ); + pNtk->vPhases = vInvs; + return pNtkNew; +} +Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose ) +{ + Abc_Obj_t * pObj, * pFanin, * pFaninNew; + int i, k, iLit, Counter = 0; + assert( pNtk->vPhases == NULL ); + pNtk->vPhases = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + Abc_NtkForEachNodeCo( pNtk, pObj, i ) + { + if ( Abc_SclObjIsBufInv(pObj) ) + continue; + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + iLit = Abc_SclGetRealFaninLit( pFanin ); + pFaninNew = Abc_NtkObj( pNtk, Abc_Lit2Var(iLit) ); + if ( pFaninNew == pFanin ) + continue; + // skip fanins which are already fanins of the node + if ( Abc_NodeFindFanin( pObj, pFaninNew ) >= 0 ) + continue; + Abc_ObjPatchFanin( pObj, pFanin, pFaninNew ); + if ( Abc_LitIsCompl(iLit) ) + Abc_ObjFaninFlipPhase( pObj, k ), Counter++; + } + } +// printf( "Saved %d fanin phase bits.\n", Counter ); + // duplicate network in topo order + return Abc_NtkDupDfs( pNtk ); +} + +/**Function************************************************************* + Synopsis [Make sure the network is in topo order without dangling nodes.] Description [Returns 1 iff the network is fine.] diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index 81d85143..c467ba1c 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -394,6 +394,8 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time /*=== sclBuffer.c ===============================================================*/ extern Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose ); +extern Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose ); +extern Abc_Ntk_t * Abc_SclBufferPhase( Abc_Ntk_t * pNtk, int fVerbose ); extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ); extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose ); extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis, int fVerbose ); |