mirror of https://github.com/YosysHQ/abc.git
Version abc50911
This commit is contained in:
parent
e52e48c364
commit
798bbfc5a9
12
abc.dsp
12
abc.dsp
|
|
@ -270,12 +270,24 @@ SOURCE=.\src\base\abci\abcVerify.c
|
|||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abcs\abcForBack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abcs\abcLogic.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abcs\abcRetime.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abcs\abcSeq.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abcs\abcUtils.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "cmd"
|
||||
|
||||
|
|
|
|||
42
abc.plg
42
abc.plg
|
|
@ -6,13 +6,13 @@
|
|||
--------------------Configuration: abc - Win32 Debug--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1748.tmp" with contents
|
||||
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1AD8.tmp" with contents
|
||||
[
|
||||
/nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /I "src\map\mapp" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR"Debug/" /Fp"Debug/abc.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
|
||||
"C:\_projects\abc\src\map\pga\pgaMan.c"
|
||||
"C:\_projects\abc\src\base\abcs\abcLogic.c"
|
||||
]
|
||||
Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1748.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1749.tmp" with contents
|
||||
Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1AD8.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1AD9.tmp" with contents
|
||||
[
|
||||
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/abc.pdb" /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept
|
||||
.\Debug\abcAig.obj
|
||||
|
|
@ -42,6 +42,7 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
|
|||
.\Debug\abcMap.obj
|
||||
.\Debug\abcMiter.obj
|
||||
.\Debug\abcNtbdd.obj
|
||||
.\Debug\abcPga.obj
|
||||
.\Debug\abcPrint.obj
|
||||
.\Debug\abcReconv.obj
|
||||
.\Debug\abcRefactor.obj
|
||||
|
|
@ -270,6 +271,10 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
|
|||
.\Debug\superAnd.obj
|
||||
.\Debug\superGate.obj
|
||||
.\Debug\superWrite.obj
|
||||
.\Debug\pgaCore.obj
|
||||
.\Debug\pgaMan.obj
|
||||
.\Debug\pgaMatch.obj
|
||||
.\Debug\pgaUtil.obj
|
||||
.\Debug\extraBddMisc.obj
|
||||
.\Debug\extraBddSymm.obj
|
||||
.\Debug\extraUtilBitMatrix.obj
|
||||
|
|
@ -305,18 +310,16 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
|
|||
.\Debug\mvcPrint.obj
|
||||
.\Debug\mvcSort.obj
|
||||
.\Debug\mvcUtils.obj
|
||||
.\Debug\pgaMan.obj
|
||||
.\Debug\pgaUtil.obj
|
||||
.\Debug\pgaMatch.obj
|
||||
.\Debug\pgaCore.obj
|
||||
.\Debug\abcPga.obj
|
||||
.\Debug\abcLogic.obj
|
||||
.\Debug\abcUtils.obj
|
||||
.\Debug\abcForBack.obj
|
||||
]
|
||||
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1749.tmp"
|
||||
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1AD9.tmp"
|
||||
<h3>Output Window</h3>
|
||||
Compiling...
|
||||
pgaMan.c
|
||||
abcLogic.c
|
||||
Linking...
|
||||
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP174A.tmp" with contents
|
||||
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1ADA.tmp" with contents
|
||||
[
|
||||
/nologo /o"Debug/abc.bsc"
|
||||
.\Debug\abcAig.sbr
|
||||
|
|
@ -346,6 +349,7 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP174A.tmp" with cont
|
|||
.\Debug\abcMap.sbr
|
||||
.\Debug\abcMiter.sbr
|
||||
.\Debug\abcNtbdd.sbr
|
||||
.\Debug\abcPga.sbr
|
||||
.\Debug\abcPrint.sbr
|
||||
.\Debug\abcReconv.sbr
|
||||
.\Debug\abcRefactor.sbr
|
||||
|
|
@ -574,6 +578,10 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP174A.tmp" with cont
|
|||
.\Debug\superAnd.sbr
|
||||
.\Debug\superGate.sbr
|
||||
.\Debug\superWrite.sbr
|
||||
.\Debug\pgaCore.sbr
|
||||
.\Debug\pgaMan.sbr
|
||||
.\Debug\pgaMatch.sbr
|
||||
.\Debug\pgaUtil.sbr
|
||||
.\Debug\extraBddMisc.sbr
|
||||
.\Debug\extraBddSymm.sbr
|
||||
.\Debug\extraUtilBitMatrix.sbr
|
||||
|
|
@ -609,12 +617,10 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP174A.tmp" with cont
|
|||
.\Debug\mvcPrint.sbr
|
||||
.\Debug\mvcSort.sbr
|
||||
.\Debug\mvcUtils.sbr
|
||||
.\Debug\pgaMan.sbr
|
||||
.\Debug\pgaUtil.sbr
|
||||
.\Debug\pgaMatch.sbr
|
||||
.\Debug\pgaCore.sbr
|
||||
.\Debug\abcPga.sbr]
|
||||
Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP174A.tmp"
|
||||
.\Debug\abcLogic.sbr
|
||||
.\Debug\abcUtils.sbr
|
||||
.\Debug\abcForBack.sbr]
|
||||
Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1ADA.tmp"
|
||||
Creating browse info file...
|
||||
<h3>Output Window</h3>
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,8 @@ struct Abc_Ntk_t_
|
|||
Vec_Ptr_t * vSupps;
|
||||
// the satisfiable assignment of the miter
|
||||
int * pModel;
|
||||
// initial states
|
||||
Vec_Int_t * vInits;
|
||||
// the external don't-care if given
|
||||
Abc_Ntk_t * pExdc; // the EXDC network
|
||||
// miscellaneous data members
|
||||
|
|
@ -305,6 +307,7 @@ static inline Abc_Obj_t * Abc_ObjChild1( Abc_Obj_t * pObj ) { return Ab
|
|||
static inline Abc_Obj_t * Abc_ObjChildCopy( Abc_Obj_t * pObj, int i ){ return Abc_ObjNotCond( Abc_ObjFanin(pObj,i)->pCopy, Abc_ObjFaninC(pObj,i) );}
|
||||
static inline Abc_Obj_t * Abc_ObjChild0Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); }
|
||||
static inline Abc_Obj_t * Abc_ObjChild1Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC1(pObj) ); }
|
||||
static inline Abc_Obj_t * Abc_ObjGetCopy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjRegular(pObj)->pCopy, Abc_ObjIsComplement(pObj) ); }
|
||||
static inline Abc_Obj_t * Abc_ObjFanoutFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( !Abc_NtkIsLogic(pObj->pNtk) ); return (Abc_ObjFaninId0(pFanout) == (int)pObj->Id)? Abc_ObjChild0(pFanout) : Abc_ObjChild1(pFanout); }
|
||||
static inline void Abc_ObjSetFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl = 1; }
|
||||
static inline void Abc_ObjXorFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl ^= 1; }
|
||||
|
|
@ -319,6 +322,8 @@ extern void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFano
|
|||
extern void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats );
|
||||
extern int Abc_ObjFanoutLMin( Abc_Obj_t * pObj );
|
||||
extern int Abc_ObjFanoutLMax( Abc_Obj_t * pObj );
|
||||
extern int Abc_ObjFanoutLSum( Abc_Obj_t * pObj );
|
||||
extern int Abc_ObjFaninLSum( Abc_Obj_t * pObj );
|
||||
|
||||
// checking the node type
|
||||
static inline bool Abc_NodeIsAigAnd( Abc_Obj_t * pNode ) { assert(Abc_NtkHasAig(pNode->pNtk)); return Abc_ObjFaninNum(pNode) == 2; }
|
||||
|
|
@ -337,12 +342,13 @@ static inline bool Abc_NodeIsTravIdCurrent( Abc_Obj_t * pNode ) { r
|
|||
static inline bool Abc_NodeIsTravIdPrevious( Abc_Obj_t * pNode ) { return (bool)(pNode->TravId == pNode->pNtk->nTravIds - 1); }
|
||||
|
||||
// checking initial state of the latches
|
||||
static inline void Abc_LatchSetInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)0; }
|
||||
static inline void Abc_LatchSetInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)1; }
|
||||
static inline void Abc_LatchSetInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)2; }
|
||||
static inline void Abc_LatchSetInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)0; }
|
||||
static inline void Abc_LatchSetInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)1; }
|
||||
static inline void Abc_LatchSetInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)2; }
|
||||
static inline bool Abc_LatchIsInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)0; }
|
||||
static inline bool Abc_LatchIsInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)1; }
|
||||
static inline bool Abc_LatchIsInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)2; }
|
||||
static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return (int)pLatch->pData; }
|
||||
|
||||
// outputs the runtime in seconds
|
||||
#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
|
||||
|
|
@ -364,6 +370,12 @@ static inline bool Abc_LatchIsInitDc( Abc_Obj_t * pLatch ) { assert(Abc
|
|||
#define Abc_NtkForEachLatch( pNtk, pObj, i ) \
|
||||
for ( i = 0; i < Vec_PtrSize(pNtk->vLats); i++ ) \
|
||||
if ( pObj = Abc_NtkLatch(pNtk, i) )
|
||||
#define Abc_AigForEachAnd( pNtk, pNode, i ) \
|
||||
for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \
|
||||
if ( (pNode = Abc_NtkObj(pNtk, i)) && Abc_NodeIsAigAnd(pNode) )
|
||||
#define Abc_SeqForEachCutsetNode( pNtk, pNode, i ) \
|
||||
for ( i = 0; i < Vec_PtrSize(pNtk->vLats); i++ ) \
|
||||
if ( (pNode = Abc_NtkLatch(pNtk, i)) )
|
||||
// inputs and outputs
|
||||
#define Abc_NtkForEachPi( pNtk, pPi, i ) \
|
||||
for ( i = 0; (i < Abc_NtkPiNum(pNtk)) && (((pPi) = Abc_NtkPi(pNtk, i)), 1); i++ )
|
||||
|
|
@ -529,6 +541,7 @@ extern void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk );
|
|||
/*=== abcNtk.c ==========================================================*/
|
||||
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
||||
extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
||||
extern Abc_Ntk_t * Abc_NtkStartFromSeq( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
||||
extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
|
||||
extern void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
|
||||
extern void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk );
|
||||
|
|
@ -572,13 +585,20 @@ extern DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pN
|
|||
/*=== abcSat.c ==========================================================*/
|
||||
extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nSeconds, int fVerbose );
|
||||
extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk );
|
||||
/*=== abcSeq.c ==========================================================*/
|
||||
extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk );
|
||||
extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk );
|
||||
|
||||
/*=== abcForBack.c ==========================================================*/
|
||||
extern void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk );
|
||||
/*=== abcLogic.c ==========================================================*/
|
||||
extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk );
|
||||
/*=== abcRetime.c ==========================================================*/
|
||||
extern void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk );
|
||||
/*=== abcSeq.c ==========================================================*/
|
||||
extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk );
|
||||
/*=== abcUtil.c ==========================================================*/
|
||||
extern int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkSeqLatchNumShared( Abc_Ntk_t * pNtk );
|
||||
|
||||
/*=== abcSop.c ==========================================================*/
|
||||
extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
|
||||
extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars );
|
||||
|
|
|
|||
|
|
@ -160,9 +160,10 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
|
|||
}
|
||||
|
||||
// check the latches
|
||||
Abc_NtkForEachLatch( pNtk, pNode, i )
|
||||
if ( !Abc_NtkCheckLatch( pNtk, pNode ) )
|
||||
return 0;
|
||||
if ( !Abc_NtkIsSeq(pNtk) )
|
||||
Abc_NtkForEachLatch( pNtk, pNode, i )
|
||||
if ( !Abc_NtkCheckLatch( pNtk, pNode ) )
|
||||
return 0;
|
||||
|
||||
// finally, check for combinational loops
|
||||
// clk = clock();
|
||||
|
|
|
|||
|
|
@ -186,8 +186,8 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
|
|||
Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew )
|
||||
{
|
||||
Abc_Obj_t * pConst1;
|
||||
assert( Abc_NtkIsStrash(pNtkAig) );
|
||||
assert( Abc_NtkIsSopLogic(pNtkNew) );
|
||||
assert( Abc_NtkHasAig(pNtkAig) );
|
||||
assert( Abc_NtkIsLogic(pNtkNew) );
|
||||
pConst1 = Abc_AigConst1(pNtkAig->pManFunc);
|
||||
if ( Abc_ObjFanoutNum(pConst1) > 0 )
|
||||
pConst1->pCopy = Abc_NodeCreateConst1( pNtkNew );
|
||||
|
|
@ -208,8 +208,8 @@ Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew )
|
|||
Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew )
|
||||
{
|
||||
Abc_Obj_t * pReset, * pConst1;
|
||||
assert( Abc_NtkIsStrash(pNtkAig) );
|
||||
assert( Abc_NtkIsSopLogic(pNtkNew) );
|
||||
assert( Abc_NtkHasAig(pNtkAig) );
|
||||
assert( Abc_NtkIsLogic(pNtkNew) );
|
||||
pReset = Abc_AigReset(pNtkAig->pManFunc);
|
||||
if ( Abc_ObjFanoutNum(pReset) > 0 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3939,6 +3939,12 @@ int Abc_CommandSeq( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ( Abc_NtkCountSelfFeedLatches(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Works AIG has self-feeding latches. Cannot continue.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkAigToSeq( pNtk );
|
||||
if ( pNtkRes == NULL )
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
|
|||
if ( !Abc_NtkIsSeq(pNtk) )
|
||||
fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) );
|
||||
else
|
||||
fprintf( pFile, " lat = %4d", Abc_NtkSeqLatchNum(pNtk) );
|
||||
fprintf( pFile, " lat = %4d(%d)", Abc_NtkSeqLatchNum(pNtk), Abc_NtkSeqLatchNumShared(pNtk) );
|
||||
|
||||
if ( Abc_NtkIsNetlist(pNtk) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,161 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abcForBack.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Simple forward/backward retiming procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abcForBack.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs forward retiming of the sequential AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pNode, * pFanout;
|
||||
int i, k, nLatches;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
// assume that all nodes can be retimed
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
pNode->fMarkA = 1;
|
||||
}
|
||||
// process the nodes
|
||||
Vec_PtrForEachEntry( vNodes, pNode, i )
|
||||
{
|
||||
// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) );
|
||||
// get the number of latches to retime
|
||||
nLatches = Abc_ObjFaninLMin(pNode);
|
||||
if ( nLatches == 0 )
|
||||
continue;
|
||||
assert( nLatches > 0 );
|
||||
// subtract these latches on the fanin side
|
||||
Abc_ObjAddFaninL0( pNode, -nLatches );
|
||||
Abc_ObjAddFaninL1( pNode, -nLatches );
|
||||
// add these latches on the fanout size
|
||||
Abc_ObjForEachFanout( pNode, pFanout, k )
|
||||
{
|
||||
Abc_ObjAddFanoutL( pNode, pFanout, nLatches );
|
||||
if ( pFanout->fMarkA == 0 )
|
||||
{ // schedule the node for updating
|
||||
Vec_PtrPush( vNodes, pFanout );
|
||||
pFanout->fMarkA = 1;
|
||||
}
|
||||
}
|
||||
// unmark the node as processed
|
||||
pNode->fMarkA = 0;
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// clean the marks
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
pNode->fMarkA = 0;
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
assert( Abc_ObjFaninLMin(pNode) == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs forward retiming of the sequential AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pNode, * pFanin, * pFanout;
|
||||
int i, k, nLatches;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
// assume that all nodes can be retimed
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
pNode->fMarkA = 1;
|
||||
}
|
||||
// process the nodes
|
||||
Vec_PtrForEachEntry( vNodes, pNode, i )
|
||||
{
|
||||
// get the number of latches to retime
|
||||
nLatches = Abc_ObjFanoutLMin(pNode);
|
||||
if ( nLatches == 0 )
|
||||
continue;
|
||||
assert( nLatches > 0 );
|
||||
// subtract these latches on the fanout side
|
||||
Abc_ObjForEachFanout( pNode, pFanout, k )
|
||||
Abc_ObjAddFanoutL( pNode, pFanout, -nLatches );
|
||||
// add these latches on the fanin size
|
||||
Abc_ObjForEachFanin( pNode, pFanin, k )
|
||||
{
|
||||
Abc_ObjAddFaninL( pNode, k, nLatches );
|
||||
if ( Abc_ObjIsPi(pFanin) || Abc_NodeIsConst(pFanin) )
|
||||
continue;
|
||||
if ( pFanin->fMarkA == 0 )
|
||||
{ // schedule the node for updating
|
||||
Vec_PtrPush( vNodes, pFanin );
|
||||
pFanin->fMarkA = 1;
|
||||
}
|
||||
}
|
||||
// unmark the node as processed
|
||||
pNode->fMarkA = 0;
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// clean the marks
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
pNode->fMarkA = 0;
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
// assert( Abc_ObjFanoutLMin(pNode) == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abcSeq.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abcSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLatches, int Init );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts a sequential AIG into a logic SOP network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObj, * pObjNew, * pFaninNew;
|
||||
Vec_Ptr_t * vCutset;
|
||||
char Buffer[100];
|
||||
int i, Init, nDigits;
|
||||
assert( Abc_NtkIsSeq(pNtk) );
|
||||
// start the network
|
||||
vCutset = pNtk->vLats; pNtk->vLats = Vec_PtrAlloc( 0 );
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP );
|
||||
Vec_PtrFree( pNtk->vLats ); pNtk->vLats = vCutset;
|
||||
// create the constant node
|
||||
Abc_NtkDupConst1( pNtk, pNtkNew );
|
||||
// duplicate the nodes, create node functions and latches
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
{
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
pObj->pCopy->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
||||
}
|
||||
// connect the objects
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
{
|
||||
// get the initial states of the latches on the fanin edge of this node
|
||||
Init = Vec_IntEntry( pNtk->vInits, pObj->Id );
|
||||
// create the edge
|
||||
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninL0(pObj), Init & 0xFFFF );
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
||||
// create the edge
|
||||
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin1(pObj), Abc_ObjFaninL1(pObj), Init >> 16 );
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
||||
// the complemented edges are subsumed by node function
|
||||
}
|
||||
// set the complemented attributed of CO edges (to be fixed by making simple COs)
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
{
|
||||
// get the initial states of the latches on the fanin edge of this node
|
||||
Init = Vec_IntEntry( pNtk->vInits, pObj->Id );
|
||||
// create the edge
|
||||
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninL0(pObj), Init & 0xFFFF );
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
||||
// create the complemented edge
|
||||
if ( Abc_ObjFaninC0(pObj) )
|
||||
Abc_ObjSetFaninC( pObj->pCopy, 0 );
|
||||
}
|
||||
// count the number of digits in the latch names
|
||||
nDigits = Extra_Base10Log( Abc_NtkLatchNum(pNtkNew) );
|
||||
// add the latches and their names
|
||||
Abc_NtkForEachLatch( pNtkNew, pObjNew, i )
|
||||
{
|
||||
// add the latch to the CI/CO arrays
|
||||
Vec_PtrPush( pNtkNew->vCis, pObjNew );
|
||||
Vec_PtrPush( pNtkNew->vCos, pObjNew );
|
||||
// create latch name
|
||||
sprintf( Buffer, "L%0*d", nDigits, i );
|
||||
Abc_NtkLogicStoreName( pObjNew, Buffer );
|
||||
}
|
||||
// fix the problem with complemented and duplicated CO edges
|
||||
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
|
||||
// duplicate the EXDC network
|
||||
if ( pNtk->pExdc )
|
||||
fprintf( stdout, "Warning: EXDC network is not copied.\n" );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
fprintf( stdout, "Abc_NtkSeqToLogic(): Network check has failed.\n" );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates latches on one edge.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLatches, int Init )
|
||||
{
|
||||
Abc_Obj_t * pLatch;
|
||||
if ( nLatches == 0 )
|
||||
return pFanin->pCopy;
|
||||
pFanin = Abc_NodeSeqToLogic( pNtkNew, pFanin, nLatches - 1, Init >> 2 );
|
||||
pLatch = Abc_NtkCreateLatch( pNtkNew );
|
||||
pLatch->pData = (void *)(Init & 3);
|
||||
Abc_ObjAddFanin( pLatch, pFanin );
|
||||
return pLatch;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Procedures to derive sequential AIG from combinational AIG with latches.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
|
@ -21,27 +21,32 @@
|
|||
#include "abc.h"
|
||||
|
||||
/*
|
||||
A sequential network is an AIG whose edges have number-of-latches attributes,
|
||||
in addition to the complemented attibutes.
|
||||
|
||||
The sets of PIs/POs remain the same as in logic network.
|
||||
Constant 1 node can only be used as a fanin of a PO node and the reset node.
|
||||
The reset node produces sequence (01111...). It is used to create the
|
||||
initialization logic of all latches.
|
||||
The latches do not have explicit initial state but they are implicitly
|
||||
reset by the reset node.
|
||||
|
||||
A sequential network is similar to AIG in that it contains only
|
||||
AND gates. However, the AND-gates are currently not hashed.
|
||||
Const1/PIs/POs remain the same as in the original AIG.
|
||||
Instead of the latches, a new cutset is added, which is currently
|
||||
defined as a set of AND gates that have a latch among their fanouts.
|
||||
The edges of a sequential AIG are labeled with latch attributes
|
||||
in addition to the complementation attibutes.
|
||||
The attributes contain information about the number of latches
|
||||
and their initial states.
|
||||
The number of latches is stored directly on the edges. The initial
|
||||
states are stored in a special array associated with the network.
|
||||
The AIG of sequential network is static in the sense that the
|
||||
new AIG nodes are never created.
|
||||
The retiming (or retiming/mapping) is performed by moving the
|
||||
latches over the static nodes of the AIG.
|
||||
The new initial state after forward retiming is computed in a
|
||||
straight-forward manner. After backward retiming it is computed
|
||||
by setting up a SAT problem.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Vec_Int_t * Abc_NtkSeqCountLatches( Abc_Ntk_t * pNtk );
|
||||
static void Abc_NodeSeqCountLatches( Abc_Obj_t * pObj, Vec_Int_t * vNumbers );
|
||||
|
||||
static void Abc_NtkSeqCreateLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
|
||||
static void Abc_NodeSeqCreateLatches( Abc_Obj_t * pObj, int nLatches );
|
||||
static Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk );
|
||||
static Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pAnd, int Num, int * pnLatches, int * pnInit );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
|
|
@ -51,7 +56,9 @@ static void Abc_NodeSeqCreateLatches( Abc_Obj_t * pObj, int nLatches );
|
|||
|
||||
Synopsis [Converts a normal AIG into a sequential AIG.]
|
||||
|
||||
Description []
|
||||
Description [The const/PI/PO nodes are duplicated. The internal
|
||||
nodes are duplicated in the topological order. The dangling nodes
|
||||
are not copies. The choice nodes are copied.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
|
|
@ -61,119 +68,62 @@ static void Abc_NodeSeqCreateLatches( Abc_Obj_t * pObj, int nLatches );
|
|||
Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Aig_t * pManNew;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj, * pConst, * pFanout, * pFaninNew, * pLatch;
|
||||
int i, k, fChange, Counter;
|
||||
|
||||
Abc_Obj_t * pObj, * pFanin0, * pFanin1;
|
||||
int i, nLatches0, nLatches1, Init0, Init1;
|
||||
// make sure it is an AIG without self-feeding latches
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
assert( Abc_NtkCountSelfFeedLatches(pNtk) == 0 );
|
||||
// start the network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_SEQ, ABC_FUNC_AIG );
|
||||
pManNew = pNtkNew->pManFunc;
|
||||
|
||||
// set mapping of the constant nodes
|
||||
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1( pManNew );
|
||||
Abc_AigReset(pNtk->pManFunc)->pCopy = Abc_AigReset( pManNew );
|
||||
|
||||
// get rid of initial states
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
{
|
||||
pObj->pNext = pObj->pCopy;
|
||||
if ( Abc_LatchIsInit0(pObj) )
|
||||
pObj->pCopy = Abc_AigAnd( pManNew, pObj->pCopy, Abc_AigReset(pManNew) );
|
||||
else if ( Abc_LatchIsInit1(pObj) )
|
||||
pObj->pCopy = Abc_AigOr( pManNew, pObj->pCopy, Abc_ObjNot( Abc_AigReset(pManNew) ) );
|
||||
}
|
||||
|
||||
// copy internal nodes
|
||||
vNodes = Abc_AigDfs( pNtk, 1, 0 );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
if ( Abc_ObjFaninNum(pObj) == 2 )
|
||||
pObj->pCopy = Abc_AigAnd( pManNew, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
||||
// relink the CO nodes
|
||||
pNtkNew = Abc_NtkAlloc( ABC_TYPE_SEQ, ABC_FUNC_AIG );
|
||||
// duplicate the name and the spec
|
||||
pNtkNew->pName = util_strsav(pNtk->pName);
|
||||
pNtkNew->pSpec = util_strsav(pNtk->pSpec);
|
||||
// clone const/PIs/POs
|
||||
Abc_NtkDupObj(pNtkNew, Abc_AigConst1(pNtk->pManFunc) );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjAddFanin( pObj->pNext, Abc_ObjChild0Copy(pObj) );
|
||||
|
||||
// propagate constant input latches in the new network
|
||||
Counter = 0;
|
||||
fChange = 1;
|
||||
while ( fChange )
|
||||
{
|
||||
fChange = 0;
|
||||
Abc_NtkForEachLatch( pNtkNew, pLatch, i )
|
||||
{
|
||||
if ( Abc_ObjFanoutNum(pLatch) == 0 )
|
||||
continue;
|
||||
pFaninNew = Abc_ObjFanin0(pLatch);
|
||||
if ( Abc_ObjIsCi(pFaninNew) || !Abc_NodeIsConst(pFaninNew) )
|
||||
continue;
|
||||
pConst = Abc_ObjNotCond( Abc_AigConst1(pManNew), Abc_ObjFaninC0(pLatch) );
|
||||
Abc_AigReplace( pManNew, pLatch, pConst, 0 );
|
||||
fChange = 1;
|
||||
Counter++;
|
||||
}
|
||||
}
|
||||
if ( Counter )
|
||||
fprintf( stdout, "Latch sweeping removed %d latches (out of %d).\n", Counter, Abc_NtkLatchNum(pNtk) );
|
||||
|
||||
// redirect fanouts of each latch to the latch fanins
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachLatch( pNtkNew, pLatch, i )
|
||||
{
|
||||
//printf( "Latch %s. Fanouts = %d.\n", Abc_ObjName(pLatch), Abc_ObjFanoutNum(pLatch) );
|
||||
|
||||
Abc_NodeCollectFanouts( pLatch, vNodes );
|
||||
Vec_PtrForEachEntry( vNodes, pFanout, k )
|
||||
{
|
||||
if ( Abc_ObjFaninId0(pFanout) == Abc_ObjFaninId1(pFanout))
|
||||
printf( " ******* Identical fanins!!! ******* \n" );
|
||||
|
||||
if ( Abc_ObjFaninId0(pFanout) == (int)pLatch->Id )
|
||||
{
|
||||
// pFaninNew = Abc_ObjNotCond( Abc_ObjChild0(pLatch), Abc_ObjFaninC0(pFanout) );
|
||||
pFaninNew = Abc_ObjChild0(pLatch);
|
||||
Abc_ObjPatchFanin( pFanout, pLatch, pFaninNew );
|
||||
Abc_ObjAddFaninL0( pFanout, 1 );
|
||||
}
|
||||
else if ( Abc_ObjFaninId1(pFanout) == (int)pLatch->Id )
|
||||
{
|
||||
// pFaninNew = Abc_ObjNotCond( Abc_ObjChild0(pLatch), Abc_ObjFaninC1(pFanout) );
|
||||
pFaninNew = Abc_ObjChild0(pLatch);
|
||||
Abc_ObjPatchFanin( pFanout, pLatch, pFaninNew );
|
||||
Abc_ObjAddFaninL1( pFanout, 1 );
|
||||
}
|
||||
else
|
||||
assert( 0 );
|
||||
}
|
||||
assert( Abc_ObjFanoutNum(pLatch) == 0 );
|
||||
Abc_NtkDeleteObj( pLatch );
|
||||
}
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
// copy the PI/PO names
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pObj) );
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pObj) );
|
||||
// copy the internal nodes, including choices, excluding dangling
|
||||
vNodes = Abc_AigDfs( pNtk, 0, 0 );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
Vec_PtrFree( vNodes );
|
||||
// get rid of latches altogether
|
||||
// Abc_NtkForEachLatch( pNtkNew, pObj, i )
|
||||
// Abc_NtkDeleteObj( pObj );
|
||||
assert( pNtkNew->nLatches == 0 );
|
||||
Vec_PtrClear( pNtkNew->vLats );
|
||||
Vec_PtrShrink( pNtkNew->vCis, pNtk->nPis );
|
||||
Vec_PtrShrink( pNtkNew->vCos, pNtk->nPos );
|
||||
|
||||
/*
|
||||
/////////////////////////////////////////////
|
||||
Abc_NtkForEachNode( pNtkNew, pObj, i )
|
||||
if ( !Abc_NodeIsConst(pObj) )
|
||||
if ( Abc_ObjFaninL0(pObj) + Abc_ObjFaninL1(pObj) > 20 )
|
||||
printf( "(%d,%d) ", Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj) );
|
||||
Abc_NtkForEachCo( pNtkNew, pObj, i )
|
||||
printf( "(%d) ", Abc_ObjFaninL0(pObj) );
|
||||
/////////////////////////////////////////////
|
||||
printf( "\n" );
|
||||
*/
|
||||
|
||||
if ( pNtk->pExdc )
|
||||
// start the storage for initial states
|
||||
pNtkNew->vInits = Vec_IntStart( Abc_NtkObjNumMax(pNtkNew) );
|
||||
// reconnect the internal nodes
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
{
|
||||
// process the fanins of the AND gate (pObj)
|
||||
pFanin0 = Abc_NodeAigToSeq( pObj, 0, &nLatches0, &Init0 );
|
||||
pFanin1 = Abc_NodeAigToSeq( pObj, 1, &nLatches1, &Init1 );
|
||||
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjGetCopy(pFanin0) );
|
||||
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjGetCopy(pFanin1) );
|
||||
Abc_ObjAddFaninL0( pObj->pCopy, nLatches0 );
|
||||
Abc_ObjAddFaninL1( pObj->pCopy, nLatches1 );
|
||||
// add the initial state
|
||||
Vec_IntWriteEntry( pNtkNew->vInits, pObj->pCopy->Id, (Init1 << 16) | Init0 );
|
||||
}
|
||||
// reconnect the POs
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
{
|
||||
// process the fanins
|
||||
pFanin0 = Abc_NodeAigToSeq( pObj, 0, &nLatches0, &Init0 );
|
||||
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjGetCopy(pFanin0) );
|
||||
Abc_ObjAddFaninL0( pObj->pCopy, nLatches0 );
|
||||
// add the initial state
|
||||
Vec_IntWriteEntry( pNtkNew->vInits, pObj->pCopy->Id, Init0 );
|
||||
}
|
||||
// set the cutset composed of latch drivers
|
||||
pNtkNew->vLats = Abc_NtkAigCutsetCopy( pNtk );
|
||||
// copy EXDC and check correctness
|
||||
if ( pNtkNew->pExdc )
|
||||
fprintf( stdout, "Warning: EXDC is dropped when converting to sequential AIG.\n" );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
fprintf( stdout, "Abc_NtkAigToSeq(): Network check has failed.\n" );
|
||||
|
|
@ -182,92 +132,36 @@ printf( "\n" );
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts a sequential AIG into a logic SOP network.]
|
||||
Synopsis [Collects the cut set nodes.]
|
||||
|
||||
Description []
|
||||
Description [These are internal AND gates that fanins into latches.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
|
||||
Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObj, * pFanin, * pFaninNew;
|
||||
int i, k, c;
|
||||
assert( Abc_NtkIsSeq(pNtk) );
|
||||
// start the network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP );
|
||||
// create the constant and reset nodes
|
||||
Abc_NtkDupConst1( pNtk, pNtkNew );
|
||||
Abc_NtkDupReset( pNtk, pNtkNew );
|
||||
// duplicate the nodes, create node functions and latches
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_NodeIsConst(pObj) )
|
||||
continue;
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
pObj->pCopy->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
||||
}
|
||||
// create latches for the new nodes
|
||||
Abc_NtkSeqCreateLatches( pNtk, pNtkNew );
|
||||
// connect the objects
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
{
|
||||
// find the fanin
|
||||
pFaninNew = pFanin->pCopy;
|
||||
for ( c = 0; c < Abc_ObjFaninL(pObj, k); c++ )
|
||||
pFaninNew = pFaninNew->pCopy;
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
||||
}
|
||||
// set the complemented attributed of CO edges (to be fixed by making simple COs)
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
if ( Abc_ObjFaninC0(pObj) )
|
||||
Abc_ObjSetFaninC( pObj->pCopy, 0 );
|
||||
// fix the problem with complemented and duplicated CO edges
|
||||
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
|
||||
// duplicate the EXDC network
|
||||
if ( pNtk->pExdc )
|
||||
fprintf( stdout, "Warning: EXDC network is not copied.\n" );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
fprintf( stdout, "Abc_NtkSeqToLogic(): Network check has failed.\n" );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds max number of latches on the fanout edges of each node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkSeqCountLatches( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vNumbers;
|
||||
Abc_Obj_t * pObj;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pLatch, * pDriver;
|
||||
int i;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
// start the array of counters
|
||||
vNumbers = Vec_IntAlloc( 0 );
|
||||
Vec_IntFill( vNumbers, Abc_NtkObjNumMax(pNtk), 0 );
|
||||
// count for each edge
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
Abc_NodeSeqCountLatches( pObj, vNumbers );
|
||||
return vNumbers;
|
||||
vNodes = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) );
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
{
|
||||
pDriver = Abc_ObjFanin0(pLatch);
|
||||
if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_NodeIsAigAnd(pDriver) )
|
||||
continue;
|
||||
Abc_NodeSetTravIdCurrent(pDriver);
|
||||
Vec_PtrPush( vNodes, pDriver->pCopy );
|
||||
}
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Countes the latch numbers due to the fanins edges of the given node.]
|
||||
Synopsis [Determines the fanin that is transparent for latches.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -276,362 +170,28 @@ Vec_Int_t * Abc_NtkSeqCountLatches( Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeSeqCountLatches( Abc_Obj_t * pObj, Vec_Int_t * vNumbers )
|
||||
Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, int * pnInit )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int k, nLatches;
|
||||
// go through each fanin edge
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
int Init;
|
||||
// get the given fanin of the node
|
||||
pFanin = Abc_ObjFanin( pObj, Num );
|
||||
if ( !Abc_ObjIsLatch(pFanin) )
|
||||
{
|
||||
nLatches = Abc_ObjFaninL( pObj, k );
|
||||
if ( nLatches == 0 )
|
||||
continue;
|
||||
if ( Vec_IntEntry( vNumbers, pFanin->Id ) < nLatches )
|
||||
Vec_IntWriteEntry( vNumbers, pFanin->Id, nLatches );
|
||||
*pnLatches = *pnInit = 0;
|
||||
return Abc_ObjChild( pObj, Num );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkSeqCreateLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
|
||||
{
|
||||
Vec_Int_t * vNumbers;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
// create latches for each new object according to the counters
|
||||
vNumbers = Abc_NtkSeqCountLatches( pNtk );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
if ( pObj->pCopy == NULL )
|
||||
continue;
|
||||
Abc_NodeSeqCreateLatches( pObj->pCopy, Vec_IntEntry(vNumbers, (int)pObj->Id) );
|
||||
}
|
||||
Vec_IntFree( vNumbers );
|
||||
// add latch to the PI/PO lists, create latch names
|
||||
Abc_NtkFinalizeLatches( pNtkNew );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the given number of latches for this object.]
|
||||
|
||||
Description [The latches are attached to the node and to each other
|
||||
through the pCopy field.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeSeqCreateLatches( Abc_Obj_t * pObj, int nLatches )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = pObj->pNtk;
|
||||
Abc_Obj_t * pLatch, * pFanin;
|
||||
int i;
|
||||
pFanin = pObj;
|
||||
for ( i = 0, pFanin = pObj; i < nLatches; pFanin = pLatch, i++ )
|
||||
{
|
||||
pLatch = Abc_NtkCreateLatch( pNtk );
|
||||
Abc_LatchSetInitDc(pLatch);
|
||||
Abc_ObjAddFanin( pLatch, pFanin );
|
||||
pFanin->pCopy = pLatch;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counters the number of latches in the sequential AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vNumbers;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, Counter;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
// create latches for each new object according to the counters
|
||||
Counter = 0;
|
||||
vNumbers = Abc_NtkSeqCountLatches( pNtk );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
{
|
||||
assert( Abc_ObjFanoutLMax(pObj) == Vec_IntEntry(vNumbers, (int)pObj->Id) );
|
||||
Counter += Vec_IntEntry(vNumbers, (int)pObj->Id);
|
||||
}
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_NodeIsConst(pObj) )
|
||||
continue;
|
||||
assert( Abc_ObjFanoutLMax(pObj) == Vec_IntEntry(vNumbers, (int)pObj->Id) );
|
||||
Counter += Vec_IntEntry(vNumbers, (int)pObj->Id);
|
||||
}
|
||||
Vec_IntFree( vNumbers );
|
||||
if ( Abc_ObjFanoutNum( Abc_AigReset(pNtk->pManFunc) ) > 0 )
|
||||
Counter++;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs forward retiming of the sequential AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pNode, * pFanout;
|
||||
int i, k, nLatches;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
// assume that all nodes can be retimed
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
pNode->fMarkA = 1;
|
||||
}
|
||||
// process the nodes
|
||||
Vec_PtrForEachEntry( vNodes, pNode, i )
|
||||
{
|
||||
// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) );
|
||||
// get the number of latches to retime
|
||||
nLatches = Abc_ObjFaninLMin(pNode);
|
||||
if ( nLatches == 0 )
|
||||
continue;
|
||||
assert( nLatches > 0 );
|
||||
// subtract these latches on the fanin side
|
||||
Abc_ObjAddFaninL0( pNode, -nLatches );
|
||||
Abc_ObjAddFaninL1( pNode, -nLatches );
|
||||
// add these latches on the fanout size
|
||||
Abc_ObjForEachFanout( pNode, pFanout, k )
|
||||
{
|
||||
Abc_ObjAddFanoutL( pNode, pFanout, nLatches );
|
||||
if ( pFanout->fMarkA == 0 )
|
||||
{ // schedule the node for updating
|
||||
Vec_PtrPush( vNodes, pFanout );
|
||||
pFanout->fMarkA = 1;
|
||||
}
|
||||
}
|
||||
// unmark the node as processed
|
||||
pNode->fMarkA = 0;
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// clean the marks
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
pNode->fMarkA = 0;
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
assert( Abc_ObjFaninLMin(pNode) == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs forward retiming of the sequential AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pNode, * pFanin, * pFanout;
|
||||
int i, k, nLatches;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
// assume that all nodes can be retimed
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
pNode->fMarkA = 1;
|
||||
}
|
||||
// process the nodes
|
||||
Vec_PtrForEachEntry( vNodes, pNode, i )
|
||||
{
|
||||
// get the number of latches to retime
|
||||
nLatches = Abc_ObjFanoutLMin(pNode);
|
||||
if ( nLatches == 0 )
|
||||
continue;
|
||||
assert( nLatches > 0 );
|
||||
// subtract these latches on the fanout side
|
||||
Abc_ObjForEachFanout( pNode, pFanout, k )
|
||||
Abc_ObjAddFanoutL( pNode, pFanout, -nLatches );
|
||||
// add these latches on the fanin size
|
||||
Abc_ObjForEachFanin( pNode, pFanin, k )
|
||||
{
|
||||
Abc_ObjAddFaninL( pNode, k, nLatches );
|
||||
if ( Abc_ObjIsPi(pFanin) || Abc_NodeIsConst(pFanin) )
|
||||
continue;
|
||||
if ( pFanin->fMarkA == 0 )
|
||||
{ // schedule the node for updating
|
||||
Vec_PtrPush( vNodes, pFanin );
|
||||
pFanin->fMarkA = 1;
|
||||
}
|
||||
}
|
||||
// unmark the node as processed
|
||||
pNode->fMarkA = 0;
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
// clean the marks
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
pNode->fMarkA = 0;
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
// assert( Abc_ObjFanoutLMin(pNode) == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
|
||||
{
|
||||
assert( Abc_NtkIsSeq(pObj->pNtk) );
|
||||
if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id )
|
||||
return Abc_ObjFaninL0(pFanout);
|
||||
else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id )
|
||||
return Abc_ObjFaninL1(pFanout);
|
||||
else
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats )
|
||||
{
|
||||
assert( Abc_NtkIsSeq(pObj->pNtk) );
|
||||
if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id )
|
||||
Abc_ObjSetFaninL0(pFanout, nLats);
|
||||
else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id )
|
||||
Abc_ObjSetFaninL1(pFanout, nLats);
|
||||
else
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds to the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats )
|
||||
{
|
||||
assert( Abc_NtkIsSeq(pObj->pNtk) );
|
||||
if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id )
|
||||
Abc_ObjAddFaninL0(pFanout, nLats);
|
||||
else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id )
|
||||
Abc_ObjAddFaninL1(pFanout, nLats);
|
||||
else
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjFanoutLMax( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
int i, nLatch, nLatchRes;
|
||||
nLatchRes = 0;
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
if ( nLatchRes < (nLatch = Abc_ObjFanoutL(pObj, pFanout)) )
|
||||
nLatchRes = nLatch;
|
||||
assert( nLatchRes >= 0 );
|
||||
return nLatchRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjFanoutLMin( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
int i, nLatch, nLatchRes;
|
||||
nLatchRes = ABC_INFINITY;
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
if ( nLatchRes > (nLatch = Abc_ObjFanoutL(pObj, pFanout)) )
|
||||
nLatchRes = nLatch;
|
||||
assert( nLatchRes < ABC_INFINITY );
|
||||
return nLatchRes;
|
||||
pFanin = Abc_NodeAigToSeq( pFanin, 0, pnLatches, pnInit );
|
||||
// get the new initial state
|
||||
Init = Abc_LatchInit(pObj);
|
||||
assert( Init >= 0 && Init <= 3 );
|
||||
// complement the initial state if the inv is retimed over the latch
|
||||
if ( Abc_ObjIsComplement(pFanin) && Init < 2 ) // not a don't-care
|
||||
Init ^= 3;
|
||||
// update the latch number and initial state
|
||||
(*pnLatches)++;
|
||||
(*pnInit) = ((*pnInit) << 2) | Init;
|
||||
return Abc_ObjNotCond( pFanin, Abc_ObjFaninC(pObj,Num) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,243 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abcUtils.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Utilities working sequential AIGs.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abcUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
|
||||
{
|
||||
assert( Abc_NtkIsSeq(pObj->pNtk) );
|
||||
if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id )
|
||||
return Abc_ObjFaninL0(pFanout);
|
||||
else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id )
|
||||
return Abc_ObjFaninL1(pFanout);
|
||||
else
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats )
|
||||
{
|
||||
assert( Abc_NtkIsSeq(pObj->pNtk) );
|
||||
if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id )
|
||||
Abc_ObjSetFaninL0(pFanout, nLats);
|
||||
else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id )
|
||||
Abc_ObjSetFaninL1(pFanout, nLats);
|
||||
else
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds to the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats )
|
||||
{
|
||||
assert( Abc_NtkIsSeq(pObj->pNtk) );
|
||||
if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id )
|
||||
Abc_ObjAddFaninL0(pFanout, nLats);
|
||||
else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id )
|
||||
Abc_ObjAddFaninL1(pFanout, nLats);
|
||||
else
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjFanoutLMax( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
int i, nLatchCur, nLatchRes;
|
||||
nLatchRes = 0;
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
{
|
||||
nLatchCur = Abc_ObjFanoutL(pObj, pFanout);
|
||||
if ( nLatchRes < nLatchCur )
|
||||
nLatchRes = nLatchCur;
|
||||
}
|
||||
assert( nLatchRes >= 0 );
|
||||
return nLatchRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the latch number of the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjFanoutLMin( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
int i, nLatchCur, nLatchRes;
|
||||
nLatchRes = ABC_INFINITY;
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
{
|
||||
nLatchCur = Abc_ObjFanoutL(pObj, pFanout);
|
||||
if ( nLatchRes > nLatchCur )
|
||||
nLatchRes = nLatchCur;
|
||||
}
|
||||
assert( nLatchRes < ABC_INFINITY );
|
||||
return nLatchRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the sum of latches on the fanout edges.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjFanoutLSum( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
int i, nSum = 0;
|
||||
Abc_ObjForEachFanout( pObj, pFanout, i )
|
||||
nSum += Abc_ObjFanoutL(pObj, pFanout);
|
||||
return nSum;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the sum of latches on the fanin edges.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_ObjFaninLSum( Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i, nSum = 0;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
nSum += Abc_ObjFaninL(pObj, i);
|
||||
return nSum;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counters the number of latches in the sequential AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i, Counter;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
Counter = 0;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
Counter += Abc_ObjFaninLSum( pObj );
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Counter += Abc_ObjFaninLSum( pObj );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counters the number of latches in the sequential AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkSeqLatchNumShared( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i, Counter;
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
Counter = 0;
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Counter += Abc_ObjFanoutLMax( pObj );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
Counter += Abc_ObjFanoutLMax( pObj );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Loading…
Reference in New Issue