Commit c065b2c5 by Alan Mishchenko

Version abc50912

parent 798bbfc5
......@@ -270,15 +270,23 @@ SOURCE=.\src\base\abci\abcVerify.c
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\base\abcs\abcForBack.c
SOURCE=.\src\base\abcs\abcRetCore.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcLogic.c
SOURCE=.\src\base\abcs\abcRetDelay.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcRetime.c
SOURCE=.\src\base\abcs\abcRetImpl.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcRetUtil.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcs.h
# End Source File
# Begin Source File
......@@ -286,6 +294,10 @@ SOURCE=.\src\base\abcs\abcSeq.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcShare.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abcs\abcUtils.c
# End Source File
# End Group
......
No preview for this file type
......@@ -6,13 +6,23 @@
--------------------Configuration: abc - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1AD8.tmp" with contents
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1CE4.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\base\abcs\abcLogic.c"
"C:\_projects\abc\src\base\abc\abcNetlist.c"
"C:\_projects\abc\src\base\abc\abcUtil.c"
"C:\_projects\abc\src\base\abci\abc.c"
"C:\_projects\abc\src\base\abci\abcPrint.c"
"C:\_projects\abc\src\base\abcs\abcSeq.c"
"C:\_projects\abc\src\base\abcs\abcUtils.c"
"C:\_projects\abc\src\base\abcs\abcShare.c"
"C:\_projects\abc\src\base\abcs\abcRetDelay.c"
"C:\_projects\abc\src\base\abcs\abcRetImpl.c"
"C:\_projects\abc\src\base\abcs\abcRetUtil.c"
"C:\_projects\abc\src\base\abcs\abcRetCore.c"
]
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
Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1CE4.tmp"
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1CE5.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
......@@ -55,8 +65,8 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
.\Debug\abcTiming.obj
.\Debug\abcUnreach.obj
.\Debug\abcVerify.obj
.\Debug\abcRetime.obj
.\Debug\abcSeq.obj
.\Debug\abcUtils.obj
.\Debug\cmd.obj
.\Debug\cmdAlias.obj
.\Debug\cmdApi.obj
......@@ -310,16 +320,28 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
.\Debug\mvcPrint.obj
.\Debug\mvcSort.obj
.\Debug\mvcUtils.obj
.\Debug\abcLogic.obj
.\Debug\abcUtils.obj
.\Debug\abcForBack.obj
.\Debug\abcShare.obj
.\Debug\abcRetDelay.obj
.\Debug\abcRetImpl.obj
.\Debug\abcRetUtil.obj
.\Debug\abcRetCore.obj
]
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1AD9.tmp"
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1CE5.tmp"
<h3>Output Window</h3>
Compiling...
abcLogic.c
abcNetlist.c
abcUtil.c
abc.c
abcPrint.c
abcSeq.c
abcUtils.c
abcShare.c
abcRetDelay.c
abcRetImpl.c
abcRetUtil.c
abcRetCore.c
Linking...
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1ADA.tmp" with contents
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1CE6.tmp" with contents
[
/nologo /o"Debug/abc.bsc"
.\Debug\abcAig.sbr
......@@ -362,8 +384,8 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1ADA.tmp" with cont
.\Debug\abcTiming.sbr
.\Debug\abcUnreach.sbr
.\Debug\abcVerify.sbr
.\Debug\abcRetime.sbr
.\Debug\abcSeq.sbr
.\Debug\abcUtils.sbr
.\Debug\cmd.sbr
.\Debug\cmdAlias.sbr
.\Debug\cmdApi.sbr
......@@ -617,10 +639,12 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1ADA.tmp" with cont
.\Debug\mvcPrint.sbr
.\Debug\mvcSort.sbr
.\Debug\mvcUtils.sbr
.\Debug\abcLogic.sbr
.\Debug\abcUtils.sbr
.\Debug\abcForBack.sbr]
Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1ADA.tmp"
.\Debug\abcShare.sbr
.\Debug\abcRetDelay.sbr
.\Debug\abcRetImpl.sbr
.\Debug\abcRetUtil.sbr
.\Debug\abcRetCore.sbr]
Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP1CE6.tmp"
Creating browse info file...
<h3>Output Window</h3>
......
......@@ -43,7 +43,7 @@
// network types
typedef enum {
ABC_TYPE_NONE, // 0: unknown
ABC_TYPE_NONE = 0, // 0: unknown
ABC_TYPE_NETLIST, // 1: network with PIs/POs, latches, nodes, and nets
ABC_TYPE_LOGIC, // 2: network with PIs/POs, latches, and nodes
ABC_TYPE_STRASH, // 3: structurally hashed AIG (two input AND gates with c-attributes on edges)
......@@ -53,7 +53,7 @@ typedef enum {
// network functionality
typedef enum {
ABC_FUNC_NONE, // 0: unknown
ABC_FUNC_NONE = 0, // 0: unknown
ABC_FUNC_SOP, // 1: sum-of-products
ABC_FUNC_BDD, // 2: binary decision diagrams
ABC_FUNC_AIG, // 3: and-inverter graphs
......@@ -76,7 +76,7 @@ typedef enum {
// object types
typedef enum {
ABC_OBJ_NONE, // 0: unknown
ABC_OBJ_NONE = 0, // 0: unknown
ABC_OBJ_NET, // 1: net
ABC_OBJ_NODE, // 2: node
ABC_OBJ_LATCH, // 3: latch
......@@ -85,6 +85,14 @@ typedef enum {
ABC_OBJ_OTHER // 6: unused
} Abc_ObjType_t;
// latch initial values
typedef enum {
ABC_INIT_NONE = 0, // 0: unknown
ABC_INIT_ZERO, // 1: zero
ABC_INIT_ONE, // 2: one
ABC_INIT_DC // 3: don't-care
} Abc_InitType_t;
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
......@@ -317,13 +325,6 @@ static inline void Abc_ObjSetFaninL1( Abc_Obj_t * pObj, int nLats )
static inline void Abc_ObjAddFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats += nLats; }
static inline void Abc_ObjAddFaninL0( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[0].nLats += nLats; }
static inline void Abc_ObjAddFaninL1( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[1].nLats += nLats; }
extern int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout );
extern void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats );
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; }
......@@ -342,12 +343,12 @@ 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 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 void Abc_LatchSetInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_ZERO; }
static inline void Abc_LatchSetInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_ONE; }
static inline void Abc_LatchSetInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_DC; }
static inline bool Abc_LatchIsInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_ZERO; }
static inline bool Abc_LatchIsInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_ONE; }
static inline bool Abc_LatchIsInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_DC; }
static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return (int)pLatch->pData; }
// outputs the runtime in seconds
......@@ -409,7 +410,6 @@ extern int Abc_AigCleanup( Abc_Aig_t * pMan );
extern bool Abc_AigCheck( Abc_Aig_t * pMan );
extern int Abc_AigGetLevelNum( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan );
extern Abc_Obj_t * Abc_AigReset( Abc_Aig_t * pMan );
extern Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
extern Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
extern Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
......@@ -515,6 +515,7 @@ extern char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pNam
extern char * Abc_ObjName( Abc_Obj_t * pNode );
extern char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix );
extern char * Abc_ObjNameUnique( Abc_Ntk_t * pNtk, char * pName );
extern char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits );
extern char * Abc_NtkLogicStoreName( Abc_Obj_t * pNodeNew, char * pNameOld );
extern char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pNodeNew, char * pNameOld, char * pSuffix );
extern void Abc_NtkCreateCioNamesTable( Abc_Ntk_t * pNtk );
......@@ -585,20 +586,6 @@ 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 );
/*=== 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 );
......
......@@ -49,7 +49,7 @@ struct Abc_Aig_t_
{
Abc_Ntk_t * pNtkAig; // the AIG network
Abc_Obj_t * pConst1; // the constant 1 node
Abc_Obj_t * pReset; // the sequential reset node
// Abc_Obj_t * pReset; // the sequential reset node
Abc_Obj_t ** pBins; // the table bins
int nBins; // the size of the table
int nEntries; // the total number of entries in the table
......@@ -125,9 +125,8 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig )
pMan->pNtkAig = pNtkAig;
// allocate constant nodes
pMan->pConst1 = Abc_NtkCreateNode( pNtkAig );
pMan->pReset = Abc_NtkCreateNode( pNtkAig );
// subtract these nodes from the total number
pNtkAig->nNodes -= 2;
pNtkAig->nNodes -= 1;
return pMan;
}
......@@ -153,7 +152,6 @@ Abc_Aig_t * Abc_AigDup( Abc_Aig_t * pMan, Abc_Aig_t * pManNew )
assert( Abc_NtkLatchNum(pMan->pNtkAig) == Abc_NtkLatchNum(pManNew->pNtkAig) );
// set mapping of the constant nodes
Abc_AigConst1( pMan )->pCopy = Abc_AigConst1( pManNew );
Abc_AigReset( pMan )->pCopy = Abc_AigReset( pManNew );
// set the mapping of CIs/COs
Abc_NtkForEachPi( pMan->pNtkAig, pObj, i )
pObj->pCopy = Abc_NtkPi( pManNew->pNtkAig, i );
......@@ -264,7 +262,7 @@ bool Abc_AigCheck( Abc_Aig_t * pMan )
nFanins = Abc_ObjFaninNum(pObj);
if ( nFanins == 0 )
{
if ( pObj != pMan->pConst1 && pObj != pMan->pReset )
if ( pObj != pMan->pConst1 )
{
printf( "Abc_AigCheck: The AIG has non-standard constant nodes.\n" );
return 0;
......@@ -340,22 +338,6 @@ Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan )
return pMan->pConst1;
}
/**Function*************************************************************
Synopsis [Read the reset node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_AigReset( Abc_Aig_t * pMan )
{
return pMan->pReset;
}
/**Function*************************************************************
......
......@@ -565,7 +565,7 @@ bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch )
Value = 0;
}
// make sure the latch has a reasonable return value
if ( (int)pLatch->pData < 0 || (int)pLatch->pData > 2 )
if ( (int)pLatch->pData < ABC_INIT_ZERO || (int)pLatch->pData > ABC_INIT_DC )
{
fprintf( stdout, "NodeCheck: Latch \"%s\" has incorrect reset value (%d).\n",
Abc_ObjName(pLatch), (int)pLatch->pData );
......
......@@ -162,6 +162,24 @@ char * Abc_ObjNameUnique( Abc_Ntk_t * pNtk, char * pName )
return NULL;
}
/**Function*************************************************************
Synopsis [Returns the dummy PI name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits )
{
static char Buffer[100];
sprintf( Buffer, "%s%0*d", pPrefix, nDigits, Num );
return Buffer;
}
/**Function*************************************************************
......
......@@ -19,6 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
......@@ -504,6 +504,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
Vec_PtrFree( pNtk->vPtrTemp );
Vec_IntFree( pNtk->vIntTemp );
Vec_StrFree( pNtk->vStrTemp );
if ( pNtk->vInits ) Vec_IntFree( pNtk->vInits );
// free the hash table of Obj name into Obj ID
stmm_free_table( pNtk->tName2Net );
stmm_free_table( pNtk->tObj2Name );
......
......@@ -196,34 +196,6 @@ Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew )
/**Function*************************************************************
Synopsis [Creates a new constant node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew )
{
Abc_Obj_t * pReset, * pConst1;
assert( Abc_NtkHasAig(pNtkAig) );
assert( Abc_NtkIsLogic(pNtkNew) );
pReset = Abc_AigReset(pNtkAig->pManFunc);
if ( Abc_ObjFanoutNum(pReset) > 0 )
{
// create new latch with reset value 0
pReset->pCopy = Abc_NtkCreateLatch( pNtkNew );
// add constant node fanin to the latch
pConst1 = Abc_NodeCreateConst1( pNtkNew );
Abc_ObjAddFanin( pReset->pCopy, pConst1 );
}
return pReset->pCopy;
}
/**Function*************************************************************
Synopsis [Deletes the object from the network.]
Description []
......@@ -493,6 +465,7 @@ Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_LATCH );
pObj->pData = (void *)ABC_INIT_NONE;
Abc_ObjAdd( pObj );
return pObj;
}
......
......@@ -22,6 +22,7 @@
#include "main.h"
#include "mio.h"
#include "dec.h"
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -931,9 +932,6 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk )
pConst1 = Abc_AigConst1(pNtk->pManFunc);
pConst1->Id = Vec_PtrSize( vObjsNew );
Vec_PtrPush( vObjsNew, pConst1 );
pReset = Abc_AigReset(pNtk->pManFunc);
pReset->Id = Vec_PtrSize( vObjsNew );
Vec_PtrPush( vObjsNew, pReset );
}
// put PI nodes next
Abc_NtkForEachPi( pNtk, pNode, i )
......
......@@ -25,6 +25,7 @@
#include "fpga.h"
#include "pga.h"
#include "cut.h"
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -3981,6 +3982,7 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
int fForward;
int fBackward;
int fInitial;
extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk );
......@@ -3989,10 +3991,11 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fForward = 0;
fForward = 0;
fBackward = 0;
fInitial = 0;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "fbh" ) ) != EOF )
while ( ( c = util_getopt( argc, argv, "fbih" ) ) != EOF )
{
switch ( c )
{
......@@ -4002,6 +4005,9 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'b':
fBackward ^= 1;
break;
case 'i':
fInitial ^= 1;
break;
case 'h':
goto usage;
default:
......@@ -4030,15 +4036,18 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_NtkSeqRetimeForward( pNtk );
else if ( fBackward )
Abc_NtkSeqRetimeBackward( pNtk );
else if ( fInitial )
Abc_NtkSeqRetimeInitial( pNtk );
else
Abc_NtkSeqRetimeDelay( pNtk );
return 0;
usage:
fprintf( pErr, "usage: retime [-fbh]\n" );
fprintf( pErr, "\t retimes sequential AIG (default is Pan's algorithm)\n" );
fprintf( pErr, "usage: retime [-fbih]\n" );
fprintf( pErr, "\t retimes sequential AIG (default is Pan's delay-optimal retiming)\n" );
fprintf( pErr, "\t-f : toggle forward retiming [default = %s]\n", fForward? "yes": "no" );
fprintf( pErr, "\t-b : toggle backward retiming [default = %s]\n", fBackward? "yes": "no" );
fprintf( pErr, "\t-i : toggle retiming for initial state [default = %s]\n", fInitial? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
......
......@@ -88,7 +88,7 @@ void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes )
ProgressBar * pProgress;
Fraig_Node_t * pNodeFraig;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pConst1, * pReset;
Abc_Obj_t * pNode, * pConst1;
int fInternal = ((Fraig_Params_t *)pParams)->fInternal;
int i;
......@@ -102,7 +102,6 @@ void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes )
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i);
pConst1 = Abc_AigConst1( pNtk->pManFunc );
pReset = Abc_AigReset( pNtk->pManFunc );
// perform strashing
vNodes = Abc_AigDfs( pNtk, fAllNodes, 0 );
......@@ -114,8 +113,6 @@ void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes )
Extra_ProgressBarUpdate( pProgress, i, NULL );
if ( pNode == pConst1 )
pNodeFraig = Fraig_ManReadConst1(pMan);
else if ( pNode == pReset )
continue;
else
pNodeFraig = Fraig_NodeAnd( pMan,
Fraig_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
......
......@@ -20,6 +20,7 @@
#include "abc.h"
#include "dec.h"
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 ///
////////////////////////////////////////////////////////////////////////
/**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 "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*
Retiming can be represented in three equivalent forms:
- as a set of integer lags for each node (array of chars by node ID)
- as a set of node numbers with lag for each, fwd and bwd (two arrays of Abc_RetStep_t_)
- as a set of node moves, fwd and bwd (two arrays arrays of Abc_Obj_t *)
*/
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs most forward retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i;
// get the forward moves
vMoves = Abc_NtkUtilRetimingTry( pNtk, 1 );
// undo the forward moves
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeBackwardTry( pNode, 1 );
// implement this forward retiming
Abc_NtkImplementRetimingForward( pNtk, vMoves );
Vec_PtrFree( vMoves );
}
/**Function*************************************************************
Synopsis [Performs most backward retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i, RetValue;
// get the backward moves
vMoves = Abc_NtkUtilRetimingTry( pNtk, 0 );
// undo the backward moves
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeForwardTry( pNode, 1 );
// implement this backward retiming
RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves );
Vec_PtrFree( vMoves );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
}
/**Function*************************************************************
Synopsis [Performs performs optimal delay retiming.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk )
{
Vec_Str_t * vLags;
int RetValue;
// get the retiming vector
vLags = Abc_NtkSeqRetimeDelayLags( pNtk );
// implement this retiming
RetValue = Abc_NtkImplementRetiming( pNtk, vLags );
Vec_StrFree( vLags );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
}
/**Function*************************************************************
Synopsis [Performs retiming for initial state computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk )
{
Vec_Str_t * vLags;
int RetValue;
// get the retiming vector
vLags = Abc_NtkSeqRetimeDelayLags( pNtk );
// implement this retiming
RetValue = Abc_NtkImplementRetiming( pNtk, vLags );
Vec_StrFree( vLags );
if ( RetValue == 0 )
printf( "Retiming completed but initial state computation has failed.\n" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -18,7 +18,7 @@
***********************************************************************/
#include "abc.h"
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -51,9 +51,11 @@ enum { ABC_UPDATE_FAIL, ABC_UPDATE_NO, ABC_UPDATE_YES };
SeeAlso []
***********************************************************************/
void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk )
Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk )
{
int FiMax, FiBest;
Vec_Str_t * vLags;
Abc_Obj_t * pNode;
int i, FiMax, FiBest;
assert( Abc_NtkIsSeq( pNtk ) );
// start storage for sequential arrival times
......@@ -71,9 +73,15 @@ void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk )
// print the result
printf( "The best clock period is %3d.\n", FiBest );
// convert to lags
vLags = Vec_StrStart( Abc_NtkObjNumMax(pNtk) );
Abc_AigForEachAnd( pNtk, pNode, i )
Vec_StrWriteEntry( vLags, i, (char)(Abc_NodeReadLValue(pNode) / FiBest) );
// free storage
Vec_IntFree( pNtk->pData );
pNtk->pData = NULL;
return vLags;
}
/**Function*************************************************************
......
/**CFile****************************************************************
FileName [abcRetImpl.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Implementation of retiming.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcRetImpl.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Abc_ObjRetimeForward( Abc_Obj_t * pObj );
static int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtk, stmm_table * tTable, Vec_Int_t * vValues );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Implements the retiming on the sequential AIG.]
Description [Split the retiming into forward and backward.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags )
{
Vec_Int_t * vSteps;
Vec_Ptr_t * vMoves;
int RetValue;
// forward retiming
vSteps = Abc_NtkUtilRetimingSplit( vLags, 1 );
// translate each set of steps into moves
vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 1 );
// implement this retiming
Abc_NtkImplementRetimingForward( pNtk, vMoves );
Vec_IntFree( vSteps );
Vec_PtrFree( vMoves );
// backward retiming
vSteps = Abc_NtkUtilRetimingSplit( vLags, 0 );
// translate each set of steps into moves
vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 0 );
// implement this retiming
RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves );
Vec_IntFree( vSteps );
Vec_PtrFree( vMoves );
return RetValue;
}
/**Function*************************************************************
Synopsis [Implements the given retiming on the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves )
{
Abc_Obj_t * pNode;
int i;
Vec_PtrForEachEntry( vMoves, pNode, i )
Abc_ObjRetimeForward( pNode );
}
/**Function*************************************************************
Synopsis [Implements the given retiming on the sequential AIG.]
Description [Returns 0 of initial state computation fails.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves )
{
Abc_RetEdge_t RetEdge;
stmm_table * tTable;
stmm_generator * gen;
Vec_Int_t * vValues;
Abc_Ntk_t * pNtkProb, * pNtkMiter, * pNtkCnf;
Abc_Obj_t * pNode, * pNodeNew;
int * pModel, Init, nDigits, RetValue, i;
// return if the retiming is trivial
if ( Vec_PtrSize(vMoves) == 0 )
return 1;
// start the table and the array of PO values
tTable = stmm_init_table( stmm_numcmp, stmm_numhash );
vValues = Vec_IntAlloc( 100 );
// create the network for the initial state computation
pNtkProb = Abc_NtkAlloc( ABC_TYPE_LOGIC, ABC_FUNC_SOP );
// perform the backward moves and build the network
Vec_PtrForEachEntry( vMoves, pNode, i )
Abc_ObjRetimeBackward( pNode, pNtkProb, tTable, vValues );
// add the PIs corresponding to the white spots
stmm_foreach_item( tTable, gen, (char **)&RetEdge, (char **)&pNodeNew )
Abc_ObjAddFanin( pNodeNew, Abc_NtkCreatePi(pNtkProb) );
// add the PI/PO names
nDigits = Extra_Base10Log( Abc_NtkPiNum(pNtkProb) );
Abc_NtkForEachPi( pNtkProb, pNodeNew, i )
Abc_NtkLogicStoreName( pNodeNew, Abc_ObjNameDummy("pi", i, nDigits) );
nDigits = Extra_Base10Log( Abc_NtkPoNum(pNtkProb) );
Abc_NtkForEachPo( pNtkProb, pNodeNew, i )
Abc_NtkLogicStoreName( pNodeNew, Abc_ObjNameDummy("po", i, nDigits) );
// make sure everything is okay with the network structure
if ( !Abc_NtkDoCheck( pNtkProb ) )
{
printf( "Abc_NtkImplementRetimingBackward: The internal network check has failed.\n" );
return 0;
}
// get the miter cone
pNtkMiter = Abc_NtkCreateCone( pNtkProb, pNtkProb->vCos, vValues );
Abc_NtkDelete( pNtkProb );
Vec_IntFree( vValues );
// transform the miter into a logic network for efficient CNF construction
pNtkCnf = Abc_NtkRenode( pNtkMiter, 0, 100, 1, 0, 0 );
Abc_NtkDelete( pNtkMiter );
// solve the miter
RetValue = Abc_NtkMiterSat( pNtkCnf, 30, 0 );
pModel = pNtkCnf->pModel; pNtkCnf->pModel = NULL;
Abc_NtkDelete( pNtkCnf );
// analyze the result
if ( RetValue == -1 || RetValue == 1 )
{
stmm_free_table( tTable );
return 0;
}
// set the values of the latches
i = 0;
stmm_foreach_item( tTable, gen, (char **)&RetEdge, (char **)&pNodeNew )
{
pNode = Abc_NtkObj( pNtk, RetEdge.iNode );
Init = pModel[i]? ABC_INIT_ONE : ABC_INIT_ZERO;
Abc_ObjFaninLSetInitOne( pNode, RetEdge.iEdge, RetEdge.iLatch, Init );
i++;
}
stmm_free_table( tTable );
free( pModel );
return 1;
}
/**Function*************************************************************
Synopsis [Retimes node forward by one latch.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ObjRetimeForward( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int Init0, Init1, Init, i;
assert( Abc_ObjFaninNum(pObj) == 2 );
assert( Abc_ObjFaninL0(pObj) >= 1 );
assert( Abc_ObjFaninL1(pObj) >= 1 );
// remove the init values from the fanins
Init0 = Abc_ObjFaninLDeleteFirst( pObj, 0 );
Init1 = Abc_ObjFaninLDeleteFirst( pObj, 1 );
assert( Init0 != ABC_INIT_NONE );
assert( Init1 != ABC_INIT_NONE );
// take into account the complements in the node
if ( Abc_ObjFaninC0(pObj) )
{
if ( Init0 == ABC_INIT_ZERO )
Init0 = ABC_INIT_ONE;
else if ( Init0 == ABC_INIT_ONE )
Init0 = ABC_INIT_ZERO;
}
if ( Abc_ObjFaninC1(pObj) )
{
if ( Init1 == ABC_INIT_ZERO )
Init1 = ABC_INIT_ONE;
else if ( Init1 == ABC_INIT_ONE )
Init1 = ABC_INIT_ZERO;
}
// compute the value at the output of the node
if ( Init0 == ABC_INIT_ZERO || Init1 == ABC_INIT_ZERO )
Init = ABC_INIT_ZERO;
else if ( Init0 == ABC_INIT_ONE && Init1 == ABC_INIT_ONE )
Init = ABC_INIT_ONE;
else
Init = ABC_INIT_DC;
// add the init values to the fanouts
Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_ObjFaninLInsertLast( pFanout, Abc_ObjEdgeNum(pFanout, pObj), Init );
}
/**Function*************************************************************
Synopsis [Retimes node backward by one latch.]
Description [Constructs the problem for initial state computation.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtkNew, stmm_table * tTable, Vec_Int_t * vValues )
{
Abc_Obj_t * pFanout;
Abc_InitType_t Init, Value;
Abc_RetEdge_t Edge;
Abc_Obj_t * pNodeNew, * pFanoutNew, * pBuf;
unsigned Entry;
int i, fMet0, fMet1, fMetX;
// make sure the node can be retimed
assert( Abc_ObjFanoutLMin(pObj) > 0 );
// get the fanout values
fMet0 = fMet1 = fMetX = 0;
Abc_ObjForEachFanout( pObj, pFanout, i )
{
Init = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pObj, pFanout) );
if ( Init == ABC_INIT_ZERO )
fMet0 = 1;
else if ( Init == ABC_INIT_ONE )
fMet1 = 1;
else if ( Init == ABC_INIT_NONE )
fMetX = 1;
}
// quit if conflict is found
if ( fMet0 && fMet1 )
return 0;
// get the new initial value
if ( !fMet0 && !fMet1 && !fMetX )
{
Init = ABC_INIT_DC;
// do not add the node
pNodeNew = NULL;
}
else
{
Init = ABC_INIT_NONE;
// add the node to the network
pNodeNew = Abc_NtkCreateNode( pNtkNew );
pNodeNew->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
}
// perform the changes
Abc_ObjForEachFanout( pObj, pFanout, i )
{
Edge.iNode = pFanout->Id;
Edge.iEdge = Abc_ObjEdgeNum(pObj, pFanout);
Edge.iLatch = Abc_ObjFaninL( pFanout, Edge.iEdge ) - 1;
// try to delete this edge
stmm_delete( tTable, (char **)&Edge, (char **)&pFanoutNew );
// delete the entry
Value = Abc_ObjFaninLDeleteLast( pFanout, Edge.iEdge );
if ( Value == ABC_INIT_NONE )
Abc_ObjAddFanin( pFanoutNew, pNodeNew );
}
// update the table for each of the edges
Abc_ObjFaninLForEachValue( pObj, 0, Entry, i, Value )
{
if ( Value != ABC_INIT_NONE )
continue;
if ( !stmm_delete( tTable, (char **)&Edge, (char **)&pFanoutNew ) )
assert( 0 );
Edge.iLatch++;
if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(Edge), (char *)pFanoutNew ) )
assert( 0 );
}
Abc_ObjFaninLForEachValue( pObj, 1, Entry, i, Value )
{
if ( Value != ABC_INIT_NONE )
continue;
if ( !stmm_delete( tTable, (char **)&Edge, (char **)&pFanoutNew ) )
assert( 0 );
Edge.iLatch++;
if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(Edge), (char *)pFanoutNew ) )
assert( 0 );
}
Abc_ObjFaninLInsertFirst( pObj, 0, Init );
Abc_ObjFaninLInsertFirst( pObj, 1, Init );
// do not insert the don't-care node into the network
if ( Init == ABC_INIT_DC )
return 1;
// add the buffer
pBuf = Abc_NtkCreateNode( pNtkNew );
pBuf->pData = Abc_SopCreateBuf( pNtkNew->pManFunc );
Abc_ObjAddFanin( pNodeNew, pBuf );
// point to it from the table
Edge.iNode = pObj->Id;
Edge.iEdge = 0;
Edge.iLatch = 0;
if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(Edge), (char *)pBuf ) )
assert( 0 );
// add the buffer
pBuf = Abc_NtkCreateNode( pNtkNew );
pBuf->pData = Abc_SopCreateBuf( pNtkNew->pManFunc );
Abc_ObjAddFanin( pNodeNew, pBuf );
// point to it from the table
Edge.iNode = pObj->Id;
Edge.iEdge = 1;
Edge.iLatch = 0;
if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(Edge), (char *)pBuf ) )
assert( 0 );
// check if the output value is required
if ( fMet0 || fMet1 )
{
// add the PO and the value
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
Vec_IntPush( vValues, fMet1 );
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [abcRetUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Retiming utilities.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcRetUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs forward retiming of the sequential AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward )
{
Vec_Ptr_t * vNodes, * vMoves;
Abc_Obj_t * pNode, * pFanout, * pFanin;
int i, k, nLatches;
assert( Abc_NtkIsSeq( pNtk ) );
// assume that all nodes can be retimed
vNodes = Vec_PtrAlloc( 100 );
Abc_AigForEachAnd( pNtk, pNode, i )
{
Vec_PtrPush( vNodes, pNode );
pNode->fMarkA = 1;
}
// process the nodes
vMoves = Vec_PtrAlloc( 100 );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) );
// unmark the node as processed
pNode->fMarkA = 0;
// get the number of latches to retime
if ( fForward )
nLatches = Abc_ObjFaninLMin(pNode);
else
nLatches = Abc_ObjFanoutLMin(pNode);
if ( nLatches == 0 )
continue;
assert( nLatches > 0 );
// retime the latches forward
if ( fForward )
Abc_ObjRetimeForwardTry( pNode, nLatches );
else
Abc_ObjRetimeBackwardTry( pNode, nLatches );
// write the moves
for ( k = 0; k < nLatches; k++ )
Vec_PtrPush( vMoves, pNode );
// schedule fanouts for updating
if ( fForward )
{
Abc_ObjForEachFanout( pNode, pFanout, k )
{
if ( Abc_ObjFaninNum(pFanout) != 2 || pFanout->fMarkA )
continue;
pFanout->fMarkA = 1;
Vec_PtrPush( vNodes, pFanout );
}
}
else
{
Abc_ObjForEachFanin( pNode, pFanin, k )
{
if ( Abc_ObjFaninNum(pFanin) != 2 || pFanin->fMarkA )
continue;
pFanin->fMarkA = 1;
Vec_PtrPush( vNodes, pFanin );
}
}
}
Vec_PtrFree( vNodes );
// make sure the marks are clean the the retiming is final
Abc_AigForEachAnd( pNtk, pNode, i )
{
assert( pNode->fMarkA == 0 );
if ( fForward )
assert( Abc_ObjFaninLMin(pNode) == 0 );
else
assert( Abc_ObjFanoutLMin(pNode) == 0 );
}
return vMoves;
}
/**Function*************************************************************
Synopsis [Translates retiming steps into retiming moves.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, bool fForward )
{
Abc_RetStep_t RetStep;
Vec_Ptr_t * vMoves;
Abc_Obj_t * pNode;
int i, k, iNode, nLatches, Number;
assert( Abc_NtkIsSeq( pNtk ) );
// process the nodes
vMoves = Vec_PtrAlloc( 100 );
while ( Vec_IntSize(vSteps) > 0 )
{
iNode = 0;
Vec_IntForEachEntry( vSteps, Number, i )
{
// get the retiming step
RetStep = Abc_Int2RetStep( Number );
// get the node to be retimed
pNode = Abc_NtkObj( pNtk, RetStep.iNode );
assert( RetStep.nLatches > 0 );
// get the number of latches that can be retimed
if ( fForward )
nLatches = Abc_ObjFaninLMin(pNode);
else
nLatches = Abc_ObjFanoutLMin(pNode);
if ( nLatches == 0 )
{
Vec_IntWriteEntry( vSteps, iNode++, Abc_RetStep2Int(RetStep) );
continue;
}
assert( nLatches > 0 );
// get the number of latches to be retimed over this node
nLatches = ABC_MIN( nLatches, (int)RetStep.nLatches );
// retime the latches forward
if ( fForward )
Abc_ObjRetimeForwardTry( pNode, nLatches );
else
Abc_ObjRetimeBackwardTry( pNode, nLatches );
// write the moves
for ( k = 0; k < nLatches; k++ )
Vec_PtrPush( vMoves, pNode );
// subtract the retiming performed
RetStep.nLatches -= nLatches;
// store the node if it is not retimed completely
if ( RetStep.nLatches > 0 )
Vec_IntWriteEntry( vSteps, iNode++, Abc_RetStep2Int(RetStep) );
}
// reduce the array
Vec_IntShrink( vSteps, iNode );
}
// undo the tentative retiming
if ( fForward )
{
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeBackwardTry( pNode, 1 );
}
else
{
Vec_PtrForEachEntryReverse( vMoves, pNode, i )
Abc_ObjRetimeForwardTry( pNode, 1 );
}
return vMoves;
}
/**Function*************************************************************
Synopsis [Splits retiming into forward and backward.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward )
{
Vec_Int_t * vNodes;
Abc_RetStep_t RetStep;
int Value, i;
vNodes = Vec_IntAlloc( 100 );
Vec_StrForEachEntry( vLags, Value, i )
{
if ( Value < 0 && fForward )
{
RetStep.iNode = i;
RetStep.nLatches = -Value;
Vec_IntPush( vNodes, Abc_RetStep2Int(RetStep) );
}
else if ( Value > 0 && !fForward )
{
RetStep.iNode = i;
RetStep.nLatches = Value;
Vec_IntPush( vNodes, Abc_RetStep2Int(RetStep) );
}
}
return vNodes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -18,20 +18,23 @@
***********************************************************************/
#include "abc.h"
#include "abcs.h"
/*
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.
When converting AIG into sequential AIG:
- 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
......@@ -46,7 +49,8 @@
////////////////////////////////////////////////////////////////////////
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 );
static Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pAnd, int Num, int * pnLatches, unsigned * pnInit );
static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLatches, unsigned Init );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -54,11 +58,11 @@ static Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pAnd, int Num, int * pnLatches,
/**Function*************************************************************
Synopsis [Converts a normal AIG into a sequential AIG.]
Synopsis [Converts combinational AIG with latches into sequential AIG.]
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.]
are not duplicated. The choice nodes are duplicated.]
SideEffects []
......@@ -69,8 +73,8 @@ Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj, * pFanin0, * pFanin1;
int i, nLatches0, nLatches1, Init0, Init1;
Abc_Obj_t * pObj, * pFanin;
int i, Init, nLatches;
// make sure it is an AIG without self-feeding latches
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkCountSelfFeedLatches(pNtk) == 0 );
......@@ -93,32 +97,35 @@ Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk )
// copy the internal nodes, including choices, excluding dangling
vNodes = Abc_AigDfs( pNtk, 0, 0 );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
Abc_NtkDupObj(pNtkNew, pObj);
pObj->pCopy->fPhase = pObj->fPhase; // needed for choices
}
// relink the choice nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
if ( pObj->pData )
pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
Vec_PtrFree( vNodes );
// start the storage for initial states
pNtkNew->vInits = Vec_IntStart( Abc_NtkObjNumMax(pNtkNew) );
pNtkNew->vInits = Vec_IntStart( 2 * 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 )
Abc_NtkForEachObj( 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 );
// skip the constant and the PIs
if ( Abc_ObjFaninNum(pObj) == 0 )
continue;
// process the first fanin
pFanin = Abc_NodeAigToSeq( pObj, 0, &nLatches, &Init );
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjGetCopy(pFanin) );
Abc_ObjAddFaninL0( pObj->pCopy, nLatches );
Vec_IntWriteEntry( pNtkNew->vInits, 2 * i + 0, Init );
if ( Abc_ObjFaninNum(pObj) == 1 )
continue;
// process the second fanin
pFanin = Abc_NodeAigToSeq( pObj, 1, &nLatches, &Init );
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjGetCopy(pFanin) );
Abc_ObjAddFaninL1( pObj->pCopy, nLatches );
Vec_IntWriteEntry( pNtkNew->vInits, 2 * i + 1, Init );
}
// set the cutset composed of latch drivers
pNtkNew->vLats = Abc_NtkAigCutsetCopy( pNtk );
......@@ -170,24 +177,31 @@ Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, int * pnInit )
Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, unsigned * pnInit )
{
Abc_Obj_t * pFanin;
int Init;
Abc_InitType_t Init;
// get the given fanin of the node
pFanin = Abc_ObjFanin( pObj, Num );
if ( !Abc_ObjIsLatch(pFanin) )
{
*pnLatches = *pnInit = 0;
*pnLatches = 0;
*pnInit = 0;
return Abc_ObjChild( pObj, Num );
}
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;
if ( Abc_ObjIsComplement(pFanin) )
{
if ( Init == ABC_INIT_ZERO )
Init = ABC_INIT_ONE;
else if ( Init == ABC_INIT_ONE )
Init = ABC_INIT_ZERO;
else if ( Init != ABC_INIT_DC )
assert( 0 );
}
// update the latch number and initial state
(*pnLatches)++;
(*pnInit) = ((*pnInit) << 2) | Init;
......@@ -195,6 +209,120 @@ Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, int *
}
/**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;
int i, nCutNodes, nDigits;
unsigned Init;
assert( Abc_NtkIsSeq(pNtk) );
// start the network without latches
nCutNodes = pNtk->vLats->nSize; pNtk->vLats->nSize = 0;
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP );
pNtk->vLats->nSize = nCutNodes;
// create the constant node
Abc_NtkDupConst1( pNtk, pNtkNew );
// duplicate the nodes, create node functions
Abc_NtkForEachNode( pNtk, pObj, i )
{
// skip the constant
if ( Abc_ObjFaninNum(pObj) == 0 )
continue;
// duplicate the node
Abc_NtkDupObj(pNtkNew, pObj);
if ( Abc_ObjFaninNum(pObj) == 1 )
{
assert( !Abc_ObjFaninC0(pObj) );
pObj->pCopy->pData = Abc_SopCreateBuf( pNtkNew->pManFunc );
continue;
}
pObj->pCopy->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
}
// connect the objects
Abc_NtkForEachObj( pNtk, pObj, i )
{
// skip PIs and the constant
if ( Abc_ObjFaninNum(pObj) == 0 )
continue;
// get the initial states of the latches on the fanin edge of this node
Init = Vec_IntEntry( pNtk->vInits, 2 * pObj->Id );
// create the edge
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninL0(pObj), Init );
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
if ( Abc_ObjFaninNum(pObj) == 1 )
{
// create the complemented edge
if ( Abc_ObjFaninC0(pObj) )
Abc_ObjSetFaninC( pObj->pCopy, 0 );
continue;
}
// get the initial states of the latches on the fanin edge of this node
Init = Vec_IntEntry( pNtk->vInits, 2 * pObj->Id + 1 );
// create the edge
pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin1(pObj), Abc_ObjFaninL1(pObj), Init );
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
// the complemented edges are subsumed by the node function
}
// 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
Abc_NtkLogicStoreName( pObjNew, Abc_ObjNameDummy("L", i, nDigits) );
}
// 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, unsigned 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 ///
////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [abcShare.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Procedures for latch sharing on the fanout edges.]
Synopsis [Utilities working sequential AIGs.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcShare.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
static void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, int Init, Vec_Ptr_t * vNodes );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Transforms the sequential AIG to take fanout sharing into account.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSeqShareFanouts( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj;
int i;
vNodes = Vec_PtrAlloc( 10 );
Abc_NtkForEachNode( pNtk, pObj, i )
Abc_NodeSeqShareFanouts( pObj, vNodes );
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis [Transforms the node to take fanout sharing into account.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Abc_Obj_t * pFanout;
Abc_InitType_t Type;
int nLatches[4], i;
// skip the node with only one fanout
if ( Abc_ObjFanoutNum(pNode) < 2 )
return;
// clean the the fanout counters
for ( i = 0; i < 4; i++ )
nLatches[i] = 0;
// find the number of fanouts having latches of each type
Abc_ObjForEachFanout( pNode, pFanout, i )
{
if ( Abc_ObjFanoutL(pNode, pFanout) == 0 )
continue;
Type = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) );
nLatches[Type]++;
}
// decide what to do
if ( nLatches[ABC_INIT_ZERO] > 1 && nLatches[ABC_INIT_ONE] > 1 ) // 0-group and 1-group
{
Abc_NodeSeqShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
Abc_NodeSeqShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
}
else if ( nLatches[ABC_INIT_ZERO] > 1 ) // 0-group
Abc_NodeSeqShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
else if ( nLatches[ABC_INIT_ONE] > 1 ) // 1-group
Abc_NodeSeqShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
else if ( nLatches[ABC_INIT_DC] > 1 ) // DC-group
{
if ( nLatches[ABC_INIT_ZERO] > 0 )
Abc_NodeSeqShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
else
Abc_NodeSeqShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
}
}
/**Function*************************************************************
Synopsis [Transforms the node to take fanout sharing into account.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes )
{
Vec_Int_t * vInits = pNode->pNtk->vInits;
Abc_Obj_t * pFanout, * pBuffer;
Abc_InitType_t Type, InitNew;
int i;
// collect the fanouts that satisfy the property (have initial value Init or DC)
InitNew = ABC_INIT_DC;
Vec_PtrClear( vNodes );
Abc_ObjForEachFanout( pNode, pFanout, i )
{
Type = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) );
if ( Type == Init )
InitNew = Init;
if ( Type == Init || Type == ABC_INIT_DC )
{
Vec_PtrPush( vNodes, pFanout );
Abc_ObjFaninLDeleteLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) );
}
}
// create the new buffer
pBuffer = Abc_NtkCreateNode( pNode->pNtk );
Abc_ObjAddFanin( pBuffer, pNode );
Abc_ObjSetFaninL( pBuffer, 0, 1 );
// add the initial state
assert( Vec_IntSize(vInits) == 2 * (int)pBuffer->Id );
Vec_IntPush( vInits, InitNew );
Vec_IntPush( vInits, 0 );
// redirect the fanouts
Vec_PtrForEachEntry( vNodes, pFanout, i )
Abc_ObjPatchFanin( pFanout, pNode, pBuffer );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -18,7 +18,7 @@
***********************************************************************/
#include "abc.h"
#include "abcs.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -30,166 +30,7 @@
/**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.]
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
......@@ -213,7 +54,7 @@ int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Counters the number of latches in the sequential AIG.]
Synopsis [Counts the number of latches in the sequential AIG.]
Description []
......
/**CFile****************************************************************
FileName [abcs.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Sequential synthesis package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __ABCS_H__
#define __ABCS_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
// the maximum number of latches on the edge
#define ABC_MAX_EDGE_LATCH 16
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
// representation of latch on the edge
typedef struct Abc_RetEdge_t_ Abc_RetEdge_t;
struct Abc_RetEdge_t_ // 1 word
{
unsigned iNode : 24; // the ID of the node
unsigned iEdge : 1; // the edge of the node
unsigned iLatch : 7; // the latch number counting from the node
};
// representation of one retiming step
typedef struct Abc_RetStep_t_ Abc_RetStep_t;
struct Abc_RetStep_t_ // 1 word
{
unsigned iNode : 24; // the ID of the node
unsigned nLatches : 8; // the number of latches to retime
};
static inline int Abc_RetEdge2Int( Abc_RetEdge_t Str ) { return *((int *)&Str); }
static inline Abc_RetEdge_t Abc_Int2RetEdge( int Num ) { return *((Abc_RetEdge_t *)&Num); }
static inline int Abc_RetStep2Int( Abc_RetStep_t Str ) { return *((int *)&Str); }
static inline Abc_RetStep_t Abc_Int2RetStep( int Num ) { return *((Abc_RetStep_t *)&Num); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
// getting the number of the edge for this fanout
static inline int Abc_ObjEdgeNum( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
{
assert( Abc_NtkIsSeq(pObj->pNtk) );
if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id )
return 0;
else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id )
return 1;
assert( 0 );
return -1;
}
// getting the latch number of the fanout
static inline int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
{
return Abc_ObjFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout) );
}
// setting the latch number of the fanout
static inline void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats )
{
Abc_ObjSetFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout), nLats );
}
// adding to the latch number of the fanout
static inline void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats )
{
Abc_ObjAddFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout), nLats );
}
// returns the latch number of the fanout
static inline 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;
}
// returns the latch number of the fanout
static inline 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;
}
// returns the sum of latches on the fanout edges
static inline 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;
}
// returns the sum of latches on the fanin edges
static inline 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;
}
// getting the bit-string of init values of the edge
static inline unsigned Abc_ObjFaninLGetInit( Abc_Obj_t * pObj, int Edge )
{
return (unsigned)Vec_IntEntry( pObj->pNtk->vInits, 2 * pObj->Id + Edge );
}
// setting bit-string of init values of the edge
static inline void Abc_ObjFaninLSetInit( Abc_Obj_t * pObj, int Edge, unsigned Init )
{
Vec_IntWriteEntry( pObj->pNtk->vInits, 2 * pObj->Id + Edge, Init );
}
// setting the init value of the given latch on the edge
static inline void Abc_ObjFaninLSetInitOne( Abc_Obj_t * pObj, int Edge, int iLatch, Abc_InitType_t Init )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
unsigned EntryNew = (EntryCur & ~(0x3 << iLatch)) | (Init << iLatch);
assert( iLatch < Abc_ObjFaninL(pObj, Edge) );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
}
// geting the init value of the first latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLGetInitFirst( Abc_Obj_t * pObj, int Edge )
{
return 0x3 & Abc_ObjFaninLGetInit( pObj, Edge );
}
// geting the init value of the last latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLGetInitLast( Abc_Obj_t * pObj, int Edge )
{
assert( Abc_ObjFaninL(pObj, Edge) > 0 );
return 0x3 & (Abc_ObjFaninLGetInit(pObj, Edge) >> (2 * (Abc_ObjFaninL(pObj, Edge) - 1)));
}
// insert the first latch on the edge
static inline void Abc_ObjFaninLInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
unsigned EntryNew = ((EntryCur << 2) | Init);
assert( Init >= 0 && Init < 4 );
assert( Abc_ObjFaninL(pObj, Edge) < ABC_MAX_EDGE_LATCH );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
Abc_ObjAddFaninL( pObj, Edge, 1 );
}
// insert the last latch on the edge
static inline void Abc_ObjFaninLInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
unsigned EntryNew = EntryCur | (Init << (2 * Abc_ObjFaninL(pObj, Edge)));
assert( Init >= 0 && Init < 4 );
assert( Abc_ObjFaninL(pObj, Edge) < ABC_MAX_EDGE_LATCH );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
Abc_ObjAddFaninL( pObj, Edge, 1 );
}
// delete the first latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLDeleteFirst( Abc_Obj_t * pObj, int Edge )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
Abc_InitType_t Init = 0x3 & EntryCur;
unsigned EntryNew = EntryCur >> 2;
assert( Abc_ObjFaninL(pObj, Edge) > 0 );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
Abc_ObjAddFaninL( pObj, Edge, -1 );
return Init;
}
// delete the last latch on the edge
static inline Abc_InitType_t Abc_ObjFaninLDeleteLast( Abc_Obj_t * pObj, int Edge )
{
unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge);
Abc_InitType_t Init = 0x3 & (EntryCur >> (2 * (Abc_ObjFaninL(pObj, Edge) - 1)));
unsigned EntryNew = EntryCur & ~(((unsigned)0x3) << (2 * (Abc_ObjFaninL(pObj, Edge)-1)));
assert( Abc_ObjFaninL(pObj, Edge) > 0 );
Abc_ObjFaninLSetInit( pObj, Edge, EntryNew );
Abc_ObjAddFaninL( pObj, Edge, -1 );
return Init;
}
// retime node forward without initial states
static inline void Abc_ObjRetimeForwardTry( Abc_Obj_t * pObj, int nLatches )
{
Abc_Obj_t * pFanout;
int i;
// make sure it is an AND gate
assert( Abc_ObjFaninNum(pObj) == 2 );
// make sure it has enough latches
assert( Abc_ObjFaninL0(pObj) >= nLatches );
assert( Abc_ObjFaninL1(pObj) >= nLatches );
// subtract these latches on the fanin side
Abc_ObjAddFaninL0( pObj, -nLatches );
Abc_ObjAddFaninL1( pObj, -nLatches );
// add these latches on the fanout size
Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_ObjAddFanoutL( pObj, pFanout, nLatches );
}
// retime node backward without initial states
static inline void Abc_ObjRetimeBackwardTry( Abc_Obj_t * pObj, int nLatches )
{
Abc_Obj_t * pFanout;
int i;
// make sure it is an AND gate
assert( Abc_ObjFaninNum(pObj) == 2 );
// subtract these latches on the fanout side
Abc_ObjForEachFanout( pObj, pFanout, i )
{
assert( Abc_ObjFanoutL(pObj, pFanout) >= nLatches );
Abc_ObjAddFanoutL( pObj, pFanout, -nLatches );
}
// add these latches on the fanin size
Abc_ObjAddFaninL0( pObj, nLatches );
Abc_ObjAddFaninL1( pObj, nLatches );
}
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
// iterating through the initial values of the edge
#define Abc_ObjFaninLForEachValue( pObj, Edge, Init, i, Value ) \
for ( i = 0, Init = Abc_ObjFaninLGetInit(pObj, Edge); \
i < Abc_ObjFaninL(pObj, Edge) && ((Value = ((Init >> i) & 3)), 1); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== abcRetCore.c ===========================================================*/
extern void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk );
extern void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk );
extern void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk );
extern void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk );
/*=== abcRetDelay.c ==========================================================*/
extern Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk );
/*=== abcRetImpl.c ===========================================================*/
extern int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags );
extern void Abc_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves );
extern int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves );
/*=== abcRetUtil.c ===========================================================*/
extern Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward );
extern Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vNodes, bool fForward );
extern Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward );
/*=== abcSeq.c ===============================================================*/
extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk );
/*=== abcShare.c =============================================================*/
extern void Abc_NtkSeqShareFanouts( Abc_Ntk_t * pNtk );
/*=== abcUtil.c ==============================================================*/
extern int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkSeqLatchNumShared( Abc_Ntk_t * pNtk );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif
......@@ -114,7 +114,10 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
// get the node name and the node type
pType = vTokens->pArray[1];
if ( strcmp(pType, "DFF") == 0 )
Io_ReadCreateLatch( pNtk, vTokens->pArray[2], vTokens->pArray[0] );
{
pNode = Io_ReadCreateLatch( pNtk, vTokens->pArray[2], vTokens->pArray[0] );
Abc_LatchSetInit0( pNode );
}
else
{
// create a new node and add it to the network
......
......@@ -395,7 +395,6 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
Abc_Ntk_t * pNtk = p->pNtk;
Abc_Obj_t * pLatch;
int ResetValue;
if ( vTokens->nSize < 3 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
......@@ -407,7 +406,7 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
pLatch = Io_ReadCreateLatch( pNtk, vTokens->pArray[1], vTokens->pArray[2] );
// get the latch reset value
if ( vTokens->nSize == 3 )
ResetValue = 2;
Abc_LatchSetInitDc( pLatch );
else
{
ResetValue = atoi(vTokens->pArray[3]);
......@@ -418,8 +417,13 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
if ( ResetValue == 0 )
Abc_LatchSetInit0( pLatch );
else if ( ResetValue == 1 )
Abc_LatchSetInit1( pLatch );
else if ( ResetValue == 2 )
Abc_LatchSetInitDc( pLatch );
}
Abc_ObjSetData( pLatch, (void *)ResetValue );
return 0;
}
......
......@@ -114,7 +114,10 @@ Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p )
vTokens = Extra_FileReaderGetTokens(p);
pGateName = vTokens->pArray[1];
if ( strncmp( pGateName, "Flip", 4 ) == 0 )
{
pObj = Abc_NtkCreateLatch( pNtk );
Abc_LatchSetInit0( pObj );
}
else
{
pObj = Abc_NtkCreateNode( pNtk );
......
......@@ -82,7 +82,7 @@ Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName )
Synopsis [Create a latch with the given input/output.]
Description []
Description [By default, the latch value is unknown (ABC_INIT_NONE).]
SideEffects []
......
......@@ -300,7 +300,7 @@ void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch )
fprintf( pFile, ".latch" );
fprintf( pFile, " %10s", Abc_ObjName(pNetLi) );
fprintf( pFile, " %10s", Abc_ObjName(pNetLo) );
fprintf( pFile, " %d\n", Reset );
fprintf( pFile, " %d\n", Reset-1 );
}
......
......@@ -515,7 +515,7 @@ enum CSAT_StatusT CSAT_Solve( CSAT_Manager mng )
if ( mng->mode == 0 ) // brute-force SAT
{
// transfor the AIG into a logic network for efficient CNF construction
// transform the AIG into a logic network for efficient CNF construction
pCnf = Abc_NtkRenode( mng->pTarget, 0, 100, 1, 0, 0 );
RetValue = Abc_NtkMiterSat( pCnf, mng->nSeconds, 0 );
......
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