Commit 1a55882a by Alan Mishchenko

Adding new (un)buffering with phase information.

parent 1558fe61
...@@ -204,6 +204,7 @@ struct Abc_Ntk_t_ ...@@ -204,6 +204,7 @@ struct Abc_Ntk_t_
void * pExcare; // the EXDC network (if given) void * pExcare; // the EXDC network (if given)
void * pData; // misc void * pData; // misc
Abc_Ntk_t * pCopy; // copy of this network 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 float * pLutTimes; // arrivals/requireds/slacks using LUT-delay model
Vec_Ptr_t * vOnehots; // names of one-hot-encoded registers Vec_Ptr_t * vOnehots; // names of one-hot-encoded registers
Vec_Int_t * vObjPerm; // permutation saved Vec_Int_t * vObjPerm; // permutation saved
...@@ -386,6 +387,8 @@ static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj ) { return Ab ...@@ -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_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 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_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 // 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; } 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 ); ...@@ -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_NtkPrintCiLevels( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkReverseTopoOrder( 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 int Abc_NtkIsTopo( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk );
/*=== abcVerify.c ==========================================================*/ /*=== abcVerify.c ==========================================================*/
......
...@@ -323,6 +323,8 @@ void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) ...@@ -323,6 +323,8 @@ void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
// duplicate timing manager // duplicate timing manager
if ( pNtk->pManTime ) if ( pNtk->pManTime )
Abc_NtkTimeInitialize( pNtkNew, pNtk ); Abc_NtkTimeInitialize( pNtkNew, pNtk );
if ( pNtk->vPhases )
Abc_NtkTransferPhases( pNtkNew, pNtk );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -478,6 +480,8 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) ...@@ -478,6 +480,8 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
// duplicate timing manager // duplicate timing manager
if ( pNtk->pManTime ) if ( pNtk->pManTime )
Abc_NtkTimeInitialize( pNtkNew, pNtk ); Abc_NtkTimeInitialize( pNtkNew, pNtk );
if ( pNtk->vPhases )
Abc_NtkTransferPhases( pNtkNew, pNtk );
// check correctness // check correctness
if ( !Abc_NtkCheck( pNtkNew ) ) if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
...@@ -514,6 +518,8 @@ Abc_Ntk_t * Abc_NtkDupDfs( Abc_Ntk_t * pNtk ) ...@@ -514,6 +518,8 @@ Abc_Ntk_t * Abc_NtkDupDfs( Abc_Ntk_t * pNtk )
// duplicate timing manager // duplicate timing manager
if ( pNtk->pManTime ) if ( pNtk->pManTime )
Abc_NtkTimeInitialize( pNtkNew, pNtk ); Abc_NtkTimeInitialize( pNtkNew, pNtk );
if ( pNtk->vPhases )
Abc_NtkTransferPhases( pNtkNew, pNtk );
// check correctness // check correctness
if ( !Abc_NtkCheck( pNtkNew ) ) if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
...@@ -1310,6 +1316,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) ...@@ -1310,6 +1316,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
// free the timing manager // free the timing manager
if ( pNtk->pManTime ) if ( pNtk->pManTime )
Abc_ManTimeStop( pNtk->pManTime ); Abc_ManTimeStop( pNtk->pManTime );
Vec_IntFreeP( &pNtk->vPhases );
// start the functionality manager // start the functionality manager
if ( Abc_NtkIsStrash(pNtk) ) if ( Abc_NtkIsStrash(pNtk) )
Abc_AigFree( (Abc_Aig_t *)pNtk->pManFunc ); Abc_AigFree( (Abc_Aig_t *)pNtk->pManFunc );
......
...@@ -2698,6 +2698,30 @@ int Abc_NtkIsTopo( Abc_Ntk_t * pNtk ) ...@@ -2698,6 +2698,30 @@ int Abc_NtkIsTopo( Abc_Ntk_t * pNtk )
return (int)(Counter == 0); 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 /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -571,16 +571,17 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -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 * pNtk = Abc_FrameReadNtk(pAbc);
Abc_Ntk_t * pNtkRes; Abc_Ntk_t * pNtkRes;
int FanMin, FanMax, fUseInvs, fBufPis; int FanMin, FanMax, fAddInvs, fUseInvs, fBufPis;
int c, fVerbose; int c, fVerbose;
int fOldAlgo = 0; int fOldAlgo = 0;
FanMin = 6; FanMin = 6;
FanMax = 14; FanMax = 14;
fAddInvs = 0;
fUseInvs = 0; fUseInvs = 0;
fBufPis = 0; fBufPis = 0;
fVerbose = 0; fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "NMaipvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "NMaixpvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -610,6 +611,9 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -610,6 +611,9 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
fOldAlgo ^= 1; fOldAlgo ^= 1;
break; break;
case 'i': case 'i':
fAddInvs ^= 1;
break;
case 'x':
fUseInvs ^= 1; fUseInvs ^= 1;
break; break;
case 'p': case 'p':
...@@ -635,9 +639,16 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -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" ); Abc_Print( -1, "This command can only be applied to a logic network.\n" );
return 1; return 1;
} }
if ( fAddInvs && pNtk->vPhases == NULL )
{
Abc_Print( -1, "Fanin phase information is not avaiable.\n" );
return 1;
}
// modify the current network // modify the current network
if ( fOldAlgo ) if ( fAddInvs )
pNtkRes = Abc_SclBufferPhase( pNtk, fVerbose );
else if ( fOldAlgo )
pNtkRes = Abc_SclPerformBuffering( pNtk, FanMax, fUseInvs, fVerbose ); pNtkRes = Abc_SclPerformBuffering( pNtk, FanMax, fUseInvs, fVerbose );
else else
pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fBufPis, fVerbose ); pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fBufPis, fVerbose );
...@@ -651,12 +662,13 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -651,12 +662,13 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: 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 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-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-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-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-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-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-h : print the command usage\n"); fprintf( pAbc->Err, "\t-h : print the command usage\n");
...@@ -677,12 +689,15 @@ usage: ...@@ -677,12 +689,15 @@ usage:
int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv ) int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc);
int c, fVerbose = 0; int c, fRemInv = 0, fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "ivh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
case 'i':
fRemInv ^= 1;
break;
case 'v': case 'v':
fVerbose ^= 1; fVerbose ^= 1;
break; break;
...@@ -703,6 +718,9 @@ int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -703,6 +718,9 @@ int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv )
fprintf( pAbc->Err, "The current network is not a logic network.\n" ); fprintf( pAbc->Err, "The current network is not a logic network.\n" );
return 1; return 1;
} }
if ( fRemInv )
pNtkRes = Abc_SclUnBufferPhase( pNtk, fVerbose );
else
pNtkRes = Abc_SclUnBufferPerform( pNtk, fVerbose ); pNtkRes = Abc_SclUnBufferPerform( pNtk, fVerbose );
if ( pNtkRes == NULL ) if ( pNtkRes == NULL )
{ {
...@@ -713,8 +731,9 @@ int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -713,8 +731,9 @@ int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv )
return 0; return 0;
usage: 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 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-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-h : print the command usage\n"); fprintf( pAbc->Err, "\t-h : print the command usage\n");
return 1; return 1;
......
...@@ -147,6 +147,83 @@ Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose ) ...@@ -147,6 +147,83 @@ Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose )
/**Function************************************************************* /**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.] Synopsis [Make sure the network is in topo order without dangling nodes.]
Description [Returns 1 iff the network is fine.] Description [Returns 1 iff the network is fine.]
......
...@@ -394,6 +394,8 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time ...@@ -394,6 +394,8 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
/*=== sclBuffer.c ===============================================================*/ /*=== sclBuffer.c ===============================================================*/
extern Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose ); 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 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_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 ); extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis, int fVerbose );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment