Version abc60822

This commit is contained in:
Alan Mishchenko 2006-08-22 08:01:00 -07:00
parent 2fd3c1a25b
commit 956842d9cc
120 changed files with 6977 additions and 7170 deletions

View File

@ -9,7 +9,7 @@ PROG := abc
MODULES := src/base/abc src/base/abci src/base/seq src/base/cmd src/base/io src/base/main \
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse src/bdd/reo \
src/map/fpga src/map/pga src/map/mapper src/map/mio src/map/super \
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/espresso src/misc/nm src/misc/vec \
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/espresso src/misc/nm src/misc/vec src/misc/hash \
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim \
src/sat/asat src/sat/csat src/sat/msat src/sat/fraig

172
abc.dsp
View File

@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /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\aig" /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\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /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\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\temp\ivy" /I "src\temp\esop" /I "src\temp\rwt" /I "src\temp\deco" /I "src\temp\mem" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /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\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /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\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\temp\ivy" /I "src\temp\esop" /I "src\temp\rwt" /I "src\temp\deco" /I "src\temp\mem" /I "src\temp\aig" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /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\aig" /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\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /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\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\temp\ivy" /I "src\temp\esop" /I "src\temp\rwt" /I "src\temp\deco" /I "src\temp\mem" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /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\sim" /I "src\opt\rwr" /I "src\map\fpga" /I "src\map\pga" /I "src\map\mapper" /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\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\temp\ivy" /I "src\temp\esop" /I "src\temp\rwt" /I "src\temp\deco" /I "src\temp\mem" /I "src\temp\aig" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
# SUBTRACT CPP /X
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
@ -126,6 +126,10 @@ SOURCE=.\src\base\abc\abcLatch.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcLib.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcMinBase.c
# End Source File
# Begin Source File
@ -230,6 +234,10 @@ SOURCE=.\src\base\abci\abcMap.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMini.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMiter.c
# End Source File
# Begin Source File
@ -306,10 +314,6 @@ SOURCE=.\src\base\abci\abcTiming.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcTrace.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcUnate.c
# End Source File
# Begin Source File
@ -378,6 +382,10 @@ SOURCE=.\src\base\seq\seqMapIter.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqMaxMeanCycle.c
# End Source File
# Begin Source File
SOURCE=.\src\base\seq\seqRetCore.c
# End Source File
# Begin Source File
@ -1121,94 +1129,6 @@ SOURCE=.\src\sat\csat\csat_apis.c
SOURCE=.\src\sat\csat\csat_apis.h
# End Source File
# End Group
# Begin Group "aig"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\sat\aig\aig.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigBalance.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigCheck.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigFanout.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigMan.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigMem.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigNode.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigOper.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigReplace.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigTable.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\aigUtil.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\fraigClass.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\fraigCnf.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\fraigCore.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\fraigEngine.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\fraigProve.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\fraigSim.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\fraigSolver.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\fraigTrav.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\rwrMffc.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\aig\rwrTruth.c
# End Source File
# End Group
# End Group
# Begin Group "opt"
@ -2077,6 +1997,26 @@ SOURCE=.\src\misc\nm\nmInt.h
SOURCE=.\src\misc\nm\nmTable.c
# End Source File
# End Group
# Begin Group "hash"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\misc\hash\hash.h
# End Source File
# Begin Source File
SOURCE=.\src\misc\hash\hashFlt.h
# End Source File
# Begin Source File
SOURCE=.\src\misc\hash\hashInt.h
# End Source File
# Begin Source File
SOURCE=.\src\misc\hash\hashPtr.h
# End Source File
# End Group
# End Group
# Begin Group "temp"
@ -2285,6 +2225,50 @@ SOURCE=.\src\temp\ver\verParse.c
SOURCE=.\src\temp\ver\verStream.c
# End Source File
# End Group
# Begin Group "aig"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\temp\aig\aig.h
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigBalance.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigCheck.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigDfs.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigMan.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigMem.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigObj.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigOper.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigTable.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\aig\aigUtil.c
# End Source File
# End Group
# End Group
# End Group
# Begin Group "Header Files"

View File

@ -36,6 +36,7 @@ extern "C" {
#include <time.h>
#include "cuddInt.h"
#include "aig.h"
#include "extra.h"
#include "solver.h"
#include "vec.h"
@ -71,9 +72,9 @@ typedef enum {
/*------------------------------------------|
| | SOP | BDD | AIG | Map |
|-----------|-------|-------|-------|-------|
| Netlist | x | | | x |
| Netlist | x | | x | x |
|-----------|-------|-------|-------|-------|
| Logic | x | x | | x |
| Logic | x | x | x | x |
|-----------|-------|-------|-------|-------|
| Strash | | | x | |
|-----------|-------|-------|-------|-------|
@ -82,15 +83,19 @@ typedef enum {
// object types
typedef enum {
ABC_OBJ_NONE = 0, // 0: unknown
ABC_OBJ_NET, // 1: net
ABC_OBJ_NODE, // 2: node
ABC_OBJ_LATCH, // 3: latch
ABC_OBJ_PI, // 4: primary input terminal
ABC_OBJ_PO, // 5: primary output terminal
ABC_OBJ_ASSERT, // 6: assertion output
ABC_OBJ_BOX, // 7: box
ABC_OBJ_OTHER // 8: unused
ABC_OBJ_NONE = 0, // 0: unknown
ABC_OBJ_CONST1, // 1: constant 1 node (AIG only)
ABC_OBJ_PIO, // 2: inout terminal
ABC_OBJ_PI, // 3: primary input terminal
ABC_OBJ_PO, // 4: primary output terminal
ABC_OBJ_BI, // 5: box input terminal
ABC_OBJ_BO, // 6: box output terminal
ABC_OBJ_NET, // 7: net
ABC_OBJ_NODE, // 8: node
ABC_OBJ_LATCH, // 9: latch
ABC_OBJ_ASSERT, // 10: assertion output
ABC_OBJ_BOX, // 11: box
ABC_OBJ_OTHER // 12: unused
} Abc_ObjType_t;
// latch initial values
@ -113,8 +118,9 @@ typedef enum {
#endif
#endif
typedef struct Abc_Obj_t_ Abc_Obj_t;
typedef struct Abc_Lib_t_ Abc_Lib_t;
typedef struct Abc_Ntk_t_ Abc_Ntk_t;
typedef struct Abc_Obj_t_ Abc_Obj_t;
typedef struct Abc_Aig_t_ Abc_Aig_t;
typedef struct Abc_ManTime_t_ Abc_ManTime_t;
typedef struct Abc_ManCut_t_ Abc_ManCut_t;
@ -133,7 +139,7 @@ struct Abc_Obj_t_ // 12 words
Abc_Ntk_t * pNtk; // the host network
int Id; // the object ID
// internal information
unsigned Type : 3; // the object type
unsigned Type : 4; // the object type
unsigned fMarkA : 1; // the multipurpose mark
unsigned fMarkB : 1; // the multipurpose mark
unsigned fMarkC : 1; // the multipurpose mark
@ -142,7 +148,7 @@ struct Abc_Obj_t_ // 12 words
unsigned fPersist: 1; // marks the persistant AIG node
unsigned fCompl0 : 1; // complemented attribute of the first fanin in the AIG
unsigned fCompl1 : 1; // complemented attribute of the second fanin in the AIG
unsigned TravId : 9; // the traversal ID (if changed, update Abc_NtkIncrementTravId)
unsigned TravId : 8; // the traversal ID (if changed, update Abc_NtkIncrementTravId)
unsigned Level : 12; // the level of the node
// connectivity
Vec_Int_t vFanins; // the array of fanins
@ -168,8 +174,10 @@ struct Abc_Ntk_t_
Vec_Ptr_t * vCos; // the array of combinational outputs (POs, asserts, latches)
Vec_Ptr_t * vPis; // the array of PIs
Vec_Ptr_t * vPos; // the array of POs
Vec_Ptr_t * vPios; // the array of PIOs
Vec_Ptr_t * vLatches; // the array of latches (or the cutset in the sequential network)
Vec_Ptr_t * vAsserts; // the array of assertions
Vec_Ptr_t * vBoxes; // the array of boxes
Vec_Ptr_t * vCutSet; // the array of cutset nodes (used in the sequential AIG)
// the number of living objects
int nObjs; // the number of live objs
@ -198,6 +206,17 @@ struct Abc_Ntk_t_
Vec_Ptr_t * vSupps; // CO support information
int * pModel; // counter-example (for miters)
Abc_Ntk_t * pExdc; // the EXDC network (if given)
// skew values (for latches)
float maxMeanCycle; // maximum mean cycle time
float globalSkew; // global skewing
Vec_Flt_t * vSkews; // endpoint skewing
};
struct Abc_Lib_t_
{
char * pName; // the name of the library
void * pManFunc; // functionality manager for the gates
st_table * tModules; // the table hashing gate/module names into their networks
};
////////////////////////////////////////////////////////////////////////
@ -227,9 +246,11 @@ static inline bool Abc_NtkHasMapping( Abc_Ntk_t * pNtk ) { return pN
static inline bool Abc_NtkHasBlackbox( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLACKBOX; }
static inline bool Abc_NtkIsSopNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_NTK_NETLIST; }
static inline bool Abc_NtkIsAigNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG && pNtk->ntkType == ABC_NTK_NETLIST; }
static inline bool Abc_NtkIsMappedNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_NETLIST; }
static inline bool Abc_NtkIsSopLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_NTK_LOGIC ; }
static inline bool Abc_NtkIsBddLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD && pNtk->ntkType == ABC_NTK_LOGIC ; }
static inline bool Abc_NtkIsAigLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG && pNtk->ntkType == ABC_NTK_LOGIC ; }
static inline bool Abc_NtkIsMappedLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_LOGIC ; }
static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vLatches) == 0; }
@ -240,7 +261,6 @@ static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pN
static inline Abc_Ntk_t * Abc_NtkExdc( Abc_Ntk_t * pNtk ) { return pNtk->pExdc; }
static inline Abc_Ntk_t * Abc_NtkBackup( Abc_Ntk_t * pNtk ) { return pNtk->pNetBackup; }
static inline int Abc_NtkStep ( Abc_Ntk_t * pNtk ) { return pNtk->iStep; }
static inline Abc_Obj_t * Abc_NtkConst1( Abc_Ntk_t * pNtk ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vObjs, 0 ); }
// setting data members of the network
static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; }
@ -260,6 +280,7 @@ static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return Ve
static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vPos); }
static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCis); }
static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCos); }
static inline int Abc_NtkBoxNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vBoxes); }
// reading objects
static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vObjs, i ); }
@ -292,21 +313,23 @@ static inline Abc_Obj_t * Abc_ObjNot( Abc_Obj_t * p ) { return (A
static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (Abc_Obj_t *)((unsigned long)p ^ (unsigned long)(c!=0)); }
// checking the object type
static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; }
static inline bool Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BOX; }
static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; }
static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH; }
static inline bool Abc_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsPi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI; }
static inline bool Abc_ObjIsPo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO; }
static inline bool Abc_ObjIsBi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BI; }
static inline bool Abc_ObjIsBo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BO; }
static inline bool Abc_ObjIsPio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO; }
static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_LATCH; }
static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_BI || pObj->Type == ABC_OBJ_LATCH; }
static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_BO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsCio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; }
static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; }
static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH; }
static inline bool Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BOX; }
// working with fanin/fanout edges
static inline int Abc_ObjFaninNum( Abc_Obj_t * pObj ) { return pObj->vFanins.nSize; }
static inline int Abc_ObjFanoutNum( Abc_Obj_t * pObj ) { return pObj->vFanouts.nSize; }
static inline int Abc_ObjFaninNum( Abc_Obj_t * pObj ) { return pObj->vFanins.nSize; }
static inline int Abc_ObjFanoutNum( Abc_Obj_t * pObj ) { return pObj->vFanouts.nSize; }
static inline int Abc_ObjFaninId( Abc_Obj_t * pObj, int i) { return pObj->vFanins.pArray[i]; }
static inline int Abc_ObjFaninId0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0]; }
static inline int Abc_ObjFaninId1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1]; }
@ -330,19 +353,15 @@ static inline Abc_Obj_t * Abc_ObjChildCopy( Abc_Obj_t * pObj, int i ){ return Ab
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) ); }
// checking the node type
static inline bool Abc_NodeIsAigAnd( Abc_Obj_t * pNode ) { assert(Abc_NtkHasAig(pNode->pNtk)); return Abc_ObjFaninNum(pNode) == 2; }
static inline bool Abc_NodeIsAigChoice( Abc_Obj_t * pNode ) { assert(Abc_NtkHasAig(pNode->pNtk)); return pNode->pData != NULL && Abc_ObjFanoutNum(pNode) > 0; }
static inline bool Abc_NodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_ObjIsNode(Abc_ObjRegular(pNode))); return Abc_ObjFaninNum(Abc_ObjRegular(pNode)) == 0; }
extern bool Abc_NodeIsConst0( Abc_Obj_t * pNode );
extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode );
extern bool Abc_NodeIsBuf( Abc_Obj_t * pNode );
extern bool Abc_NodeIsInv( Abc_Obj_t * pNode );
// checking the AIG node types
static inline bool Abc_AigNodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_NtkIsStrash(Abc_ObjRegular(pNode)->pNtk)||Abc_NtkIsSeq(Abc_ObjRegular(pNode)->pNtk)); return Abc_ObjRegular(pNode)->Type == ABC_OBJ_CONST1; }
static inline bool Abc_AigNodeIsAnd( Abc_Obj_t * pNode ) { assert(!Abc_ObjIsComplement(pNode)); assert(Abc_NtkIsStrash(pNode->pNtk)||Abc_NtkIsSeq(pNode->pNtk)); return Abc_ObjFaninNum(pNode) == 2; }
static inline bool Abc_AigNodeIsChoice( Abc_Obj_t * pNode ) { assert(!Abc_ObjIsComplement(pNode)); assert(Abc_NtkIsStrash(pNode->pNtk)||Abc_NtkIsSeq(pNode->pNtk)); return pNode->pData != NULL && Abc_ObjFanoutNum(pNode) > 0; }
// handling persistent nodes
static inline int Abc_NodeIsPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); return pNode->fPersist; }
static inline void Abc_NodeSetPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); pNode->fPersist = 1; }
static inline void Abc_NodeClearPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); pNode->fPersist = 0; }
static inline int Abc_NodeIsPersistant( Abc_Obj_t * pNode ) { assert( Abc_AigNodeIsAnd(pNode) ); return pNode->fPersist; }
static inline void Abc_NodeSetPersistant( Abc_Obj_t * pNode ) { assert( Abc_AigNodeIsAnd(pNode) ); pNode->fPersist = 1; }
static inline void Abc_NodeClearPersistant( Abc_Obj_t * pNode ) { assert( Abc_AigNodeIsAnd(pNode) ); pNode->fPersist = 0; }
// working with the traversal ID
static inline void Abc_NodeSetTravId( Abc_Obj_t * pNode, int TravId ) { pNode->TravId = TravId; }
@ -362,6 +381,10 @@ static inline bool Abc_LatchIsInit1( Abc_Obj_t * pLatch ) { assert(Ab
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; }
// skewing latches
static inline void Abc_NtkSetLatSkew ( Abc_Ntk_t * pNtk, int lat, float skew ) { Vec_FltWriteEntry( pNtk->vSkews, lat, skew ); }
static inline float Abc_NtkGetLatSkew ( Abc_Ntk_t * pNtk, int lat ) { if (lat >= Vec_FltSize( pNtk->vSkews )) return 0; else return Vec_FltEntry( pNtk->vSkews, lat ); }
// outputs the runtime in seconds
#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
@ -381,7 +404,7 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab
if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else
#define Abc_AigForEachAnd( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_NodeIsAigAnd(pNode) ) {} else
if ( (pNode) == NULL || !Abc_AigNodeIsAnd(pNode) ) {} else
#define Abc_NtkForEachBox( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_ObjIsBox(pNode) ) {} else
@ -423,6 +446,7 @@ extern void Abc_AigFree( Abc_Aig_t * pMan );
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_Ntk_t * pNtk );
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_AigXorLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, int * pType );
@ -491,12 +515,20 @@ extern int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect );
extern void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, char ** ppSop0, char ** ppSop1 );
extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover );
extern void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk );
extern int Abc_NtkSopToAig( Abc_Ntk_t * pNtk );
extern int Abc_NtkAigToBdd( Abc_Ntk_t * pNtk );
extern int Abc_NtkMapToSop( Abc_Ntk_t * pNtk );
extern int Abc_NtkLogicToSop( Abc_Ntk_t * pNtk, int fDirect );
extern int Abc_NtkLogicToBdd( Abc_Ntk_t * pNtk );
extern int Abc_NtkLogicToAig( Abc_Ntk_t * pNtk );
/*=== abcLatch.c ==========================================================*/
extern bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch );
extern int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk );
extern int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk );
/*=== abcMap.c ==========================================================*/
extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
/*=== abcLib.c ==========================================================*/
extern Abc_Lib_t * Abc_LibCreate( char * pName );
extern void Abc_LibFree( Abc_Lib_t * pLib );
extern Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib );
/*=== abcMiter.c ==========================================================*/
extern int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk );
extern int Abc_NodeMinimumBase( Abc_Obj_t * pNode );
@ -515,11 +547,14 @@ extern void Abc_NtkMiterReport( Abc_Ntk_t * pMiter );
extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
extern Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial );
/*=== abcObj.c ==========================================================*/
extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
extern void Abc_ObjAdd( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pNode );
extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj );
extern void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindTerm( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName );
@ -535,11 +570,14 @@ extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFani
extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
extern Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
extern Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode );
extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
extern void Abc_ObjAdd( Abc_Obj_t * pObj );
extern bool Abc_NodeIsConst( Abc_Obj_t * pNode );
extern bool Abc_NodeIsConst0( Abc_Obj_t * pNode );
extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode );
extern bool Abc_NodeIsBuf( Abc_Obj_t * pNode );
extern bool Abc_NodeIsInv( Abc_Obj_t * pNode );
extern void Abc_NodeComplement( Abc_Obj_t * pNode );
/*=== abcNames.c ====================================================*/
extern char * Abc_ObjName( Abc_Obj_t * pNode );
extern char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix );
@ -598,6 +636,7 @@ extern void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, in
extern void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames );
extern void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes );
extern void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode );
extern void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll);
/*=== abcProve.c ==========================================================*/
extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pParams );
/*=== abcReconv.c ==========================================================*/
@ -657,6 +696,7 @@ extern bool Abc_SopIsBuf( char * pSop );
extern bool Abc_SopIsInv( char * pSop );
extern bool Abc_SopIsAndType( char * pSop );
extern bool Abc_SopIsOrType( char * pSop );
extern int Abc_SopIsExorType( char * pSop );
extern bool Abc_SopCheck( char * pSop, int nFanins );
extern void Abc_SopWriteCnf( FILE * pFile, char * pClauses, Vec_Int_t * vVars );
extern void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses, Vec_Int_t * vVars, Vec_Int_t * vTemp );
@ -692,19 +732,6 @@ extern void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk );
extern void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR );
extern int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj );
extern int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj );
/*=== abcTrace.c ==========================================================*/
extern void Abc_HManStart();
extern void Abc_HManStop();
extern int Abc_HManIsRunning();
extern int Abc_HManGetNewNtkId();
extern void Abc_HManAddObj( Abc_Obj_t * pObj );
extern void Abc_HManAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin );
extern void Abc_HManXorFaninC( Abc_Obj_t * pObj, int iFanin );
extern void Abc_HManRemoveFanins( Abc_Obj_t * pObj );
extern void Abc_HManAddProto( Abc_Obj_t * pObj, Abc_Obj_t * pProto );
extern void Abc_HManMapAddEqu( Abc_Obj_t * pObj, Abc_Obj_t * pEqu );
extern int Abc_HManPopulate( Abc_Ntk_t * pNtk );
extern int Abc_HManVerify( int NtkIdOld, int NtkIdNew );
/*=== abcUtil.c ==========================================================*/
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
extern void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk );
@ -712,6 +739,7 @@ extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk );
extern double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk );

View File

@ -50,6 +50,7 @@
struct Abc_Aig_t_
{
Abc_Ntk_t * pNtkAig; // the AIG network
Abc_Obj_t * pConst1; // the constant 1 object (not a 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
@ -130,10 +131,17 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig )
pMan->pBins = ALLOC( Abc_Obj_t *, pMan->nBins );
memset( pMan->pBins, 0, sizeof(Abc_Obj_t *) * pMan->nBins );
pMan->vNodes = Vec_PtrAlloc( 100 );
pMan->vLevels = Vec_VecAlloc( 100 );
pMan->vLevelsR = Vec_VecAlloc( 100 );
pMan->vStackReplaceOld = Vec_PtrAlloc( 100 );
pMan->vStackReplaceNew = Vec_PtrAlloc( 100 );
pMan->vLevels = Vec_VecAlloc( 100 );
pMan->vLevelsR = Vec_VecAlloc( 100 );
// create the constant node
pMan->pConst1 = Abc_ObjAlloc( pNtkAig, ABC_OBJ_CONST1 );
// add to the array of objects, count it as object but not as node
assert( pNtkAig->vObjs->nSize == 0 );
pMan->pConst1->Id = pNtkAig->vObjs->nSize;
Vec_PtrPush( pNtkAig->vObjs, pMan->pConst1 );
pNtkAig->nObjs++;
// save the current network
pMan->pNtkAig = pNtkAig;
return pMan;
@ -216,7 +224,7 @@ bool Abc_AigCheck( Abc_Aig_t * pMan )
nFanins = Abc_ObjFaninNum(pObj);
if ( nFanins == 0 )
{
if ( pObj != Abc_NtkConst1(pMan->pNtkAig) )
if ( !Abc_AigNodeIsConst(pObj) )
{
printf( "Abc_AigCheck: The AIG has non-standard constant nodes.\n" );
return 0;
@ -370,7 +378,7 @@ Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
Abc_Obj_t * pAnd, * pConst1;
unsigned Key;
// check for trivial cases
pConst1 = Abc_NtkConst1(pMan->pNtkAig);
pConst1 = Abc_AigConst1(pMan->pNtkAig);
if ( p0 == p1 )
return p0;
if ( p0 == Abc_ObjNot(p1) )
@ -631,6 +639,23 @@ void Abc_AigRehash( Abc_Aig_t * pMan )
/**Function*************************************************************
Synopsis [Performs canonicization step.]
Description [The argument nodes can be complemented.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_AigConst1( Abc_Ntk_t * pNtk )
{
assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) );
return ((Abc_Aig_t *)pNtk->pManFunc)->pConst1;
}
/**Function*************************************************************
Synopsis [Performs canonicization step.]
@ -719,7 +744,7 @@ Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
{
int i;
if ( vPairs->nSize == 0 )
return Abc_ObjNot( Abc_NtkConst1(pMan->pNtkAig) );
return Abc_ObjNot( Abc_AigConst1(pMan->pNtkAig) );
assert( vPairs->nSize % 2 == 0 );
// go through the cubes of the node's SOP
for ( i = 0; i < vPairs->nSize; i += 2 )
@ -745,7 +770,7 @@ Abc_Obj_t * Abc_AigMiter2( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
int i;
assert( vPairs->nSize % 2 == 0 );
// go through the cubes of the node's SOP
pMiter = Abc_ObjNot( Abc_NtkConst1(pMan->pNtkAig) );
pMiter = Abc_ObjNot( Abc_AigConst1(pMan->pNtkAig) );
for ( i = 0; i < vPairs->nSize; i += 2 )
{
pXor = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] );
@ -850,7 +875,6 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i
Abc_AigAndDelete( pMan, pFanout );
// remove the fanins of the old fanout
Abc_ObjRemoveFanins( pFanout );
Abc_HManRemoveFanins( pFanout );
// recreate the old fanout with new fanins and add it to the table
Abc_AigAndCreateFrom( pMan, pFanin1, pFanin2, pFanout );
assert( Abc_AigNodeIsAcyclic(pFanout, pFanout) );
@ -872,7 +896,7 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i
// the fanout has changed, update EXOR status of its fanouts
Abc_ObjForEachFanout( pFanout, pFanoutFanout, v )
if ( Abc_NodeIsAigAnd(pFanoutFanout) )
if ( Abc_AigNodeIsAnd(pFanoutFanout) )
pFanoutFanout->fExor = Abc_NodeIsExorType(pFanoutFanout);
}
// if the node has no fanouts left, remove its MFFC
@ -1199,7 +1223,7 @@ void Abc_AigPrintNode( Abc_Obj_t * pNode )
printf( "CI %4s%s.\n", Abc_ObjName(pNodeR), Abc_ObjIsComplement(pNode)? "\'" : "" );
return;
}
if ( Abc_NodeIsConst(pNodeR) )
if ( Abc_AigNodeIsConst(pNodeR) )
{
printf( "Constant 1 %s.\n", Abc_ObjIsComplement(pNode)? "(complemented)" : "" );
return;
@ -1230,7 +1254,7 @@ bool Abc_AigNodeIsAcyclic( Abc_Obj_t * pNode, Abc_Obj_t * pRoot )
Abc_Obj_t * pFanin0, * pFanin1;
Abc_Obj_t * pChild00, * pChild01;
Abc_Obj_t * pChild10, * pChild11;
if ( !Abc_NodeIsAigAnd(pNode) )
if ( !Abc_AigNodeIsAnd(pNode) )
return 1;
pFanin0 = Abc_ObjFanin0(pNode);
pFanin1 = Abc_ObjFanin1(pNode);
@ -1306,7 +1330,7 @@ void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsDfsOrdered(pNtk) );
Abc_NtkConst1(pNtk)->fPhase = 1;
Abc_AigConst1(pNtk)->fPhase = 1;
// Abc_NtkForEachCi( pNtk, pObj, i )
// pObj->fPhase = 0;
Abc_NtkForEachPi( pNtk, pObj, i )

View File

@ -127,7 +127,7 @@ void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// skip the CI
if ( Abc_ObjIsCi(pNode) )
if ( Abc_ObjIsCi(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
return;
assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
// visit the transitive fanin of the node
@ -167,9 +167,10 @@ Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk )
Abc_NtkDfsReverse_rec( pFanout, vNodes );
}
// add constant nodes in the end
Abc_NtkForEachNode( pNtk, pObj, i )
if ( Abc_NodeIsConst(pObj) )
Vec_PtrPush( vNodes, pObj );
if ( !Abc_NtkIsStrash(pNtk) )
Abc_NtkForEachNode( pNtk, pObj, i )
if ( Abc_NodeIsConst(pObj) )
Vec_PtrPush( vNodes, pObj );
return vNodes;
}
@ -235,7 +236,7 @@ bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk )
if ( !Abc_NodeIsTravIdCurrent(pFanin) )
return 0;
// check the choices of the node
if ( Abc_NtkIsStrash(pNtk) && Abc_NodeIsAigChoice(pNode) )
if ( Abc_NtkIsStrash(pNtk) && Abc_AigNodeIsChoice(pNode) )
for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData )
if ( !Abc_NodeIsTravIdCurrent(pFanin) )
return 0;
@ -399,14 +400,14 @@ void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// skip the PI
if ( Abc_ObjIsCi(pNode) )
if ( Abc_ObjIsCi(pNode) || Abc_AigNodeIsConst(pNode) )
return;
assert( Abc_ObjIsNode( pNode ) );
// visit the transitive fanin of the node
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_AigDfs_rec( pFanin, vNodes );
// visit the equivalent nodes
if ( Abc_NodeIsAigChoice( pNode ) )
if ( Abc_AigNodeIsChoice( pNode ) )
for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData )
Abc_AigDfs_rec( pFanin, vNodes );
// add the node after the fanins have been added
@ -712,7 +713,7 @@ int Abc_AigSetChoiceLevels( Abc_Ntk_t * pNtk )
Abc_NodeSetTravIdCurrent( pObj );
pObj->pCopy = NULL;
}
pObj = Abc_NtkConst1( pNtk );
pObj = Abc_AigConst1( pNtk );
Abc_NodeSetTravIdCurrent( pObj );
pObj->pCopy = NULL;
// set levels of all other nodes

View File

@ -50,7 +50,6 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id );
if ( Abc_ObjIsComplement(pFanin) )
Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
// Abc_HManAddFanin( pObj, pFanin );
}

View File

@ -19,6 +19,8 @@
***********************************************************************/
#include "abc.h"
#include "main.h"
#include "mio.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -26,7 +28,9 @@
#define ABC_MUX_CUBES 100000
static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
static DdNode * Abc_ConvertAigToBdd( DdManager * dd, Aig_Obj_t * pRoot);
static Aig_Obj_t * Abc_ConvertSopToAig( Aig_Man_t * pMan, char * pSop );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@ -95,7 +99,6 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop )
DdNode * bSum, * bCube, * bTemp, * bVar;
char * pCube;
int nVars, Value, v;
extern int Abc_SopIsExorType( char * pSop );
// start the cover
nVars = Abc_SopGetVarNum(pSop);
@ -516,6 +519,374 @@ int Abc_CountZddCubes( DdManager * dd, DdNode * zCover )
}
/**Function*************************************************************
Synopsis [Converts the network from SOP to AIG representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkSopToAig( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
Aig_Man_t * pMan;
int i;
assert( Abc_NtkIsSopLogic(pNtk) );
// start the functionality manager
pMan = Aig_ManStart();
// convert each node from SOP to BDD
Abc_NtkForEachNode( pNtk, pNode, i )
{
assert( pNode->pData );
pNode->pData = Abc_ConvertSopToAig( pMan, pNode->pData );
if ( pNode->pData == NULL )
{
printf( "Abc_NtkSopToAig: Error while converting SOP into AIG.\n" );
return 0;
}
}
Extra_MmFlexStop( pNtk->pManFunc, 0 );
pNtk->pManFunc = pMan;
// update the network type
pNtk->ntkFunc = ABC_FUNC_AIG;
return 1;
}
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t * Abc_ConvertSopToAigInternal( Aig_Man_t * pMan, char * pSop )
{
Aig_Obj_t * pAnd, * pSum;
int i, Value, nFanins;
char * pCube;
// get the number of variables
nFanins = Abc_SopGetVarNum(pSop);
// go through the cubes of the node's SOP
pSum = Aig_ManConst0(pMan);
Abc_SopForEachCube( pSop, nFanins, pCube )
{
// create the AND of literals
pAnd = Aig_ManConst1(pMan);
Abc_CubeForEachVar( pCube, Value, i )
{
if ( Value == '1' )
pAnd = Aig_And( pMan, pAnd, Aig_IthVar(pMan,i) );
else if ( Value == '0' )
pAnd = Aig_And( pMan, pAnd, Aig_Not(Aig_IthVar(pMan,i)) );
}
// add to the sum of cubes
pSum = Aig_Or( pMan, pSum, pAnd );
}
// decide whether to complement the result
if ( Abc_SopIsComplement(pSop) )
pSum = Aig_Not(pSum);
return pSum;
}
/**Function*************************************************************
Synopsis [Converts the network from AIG to BDD representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t * Abc_ConvertSopToAig( Aig_Man_t * pMan, char * pSop )
{
extern Aig_Obj_t * Dec_GraphFactorSop( Aig_Man_t * pMan, char * pSop );
int fUseFactor = 1;
// consider the constant node
if ( Abc_SopGetVarNum(pSop) == 0 )
return Aig_NotCond( Aig_ManConst1(pMan), Abc_SopIsConst0(pSop) );
// consider the special case of EXOR function
if ( Abc_SopIsExorType(pSop) )
return Aig_NotCond( Aig_CreateExor(pMan, Abc_SopGetVarNum(pSop)), Abc_SopIsComplement(pSop) );
// decide when to use factoring
if ( fUseFactor && Abc_SopGetVarNum(pSop) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
return Dec_GraphFactorSop( pMan, pSop );
return Abc_ConvertSopToAigInternal( pMan, pSop );
}
/**Function*************************************************************
Synopsis [Converts the network from AIG to BDD representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkAigToBdd( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
Aig_Man_t * pMan;
DdManager * dd;
int nFaninsMax, i;
assert( Abc_NtkIsAigLogic(pNtk) );
// start the functionality manager
nFaninsMax = Abc_NtkGetFaninMax( pNtk );
if ( nFaninsMax == 0 )
printf( "Warning: The network has only constant nodes.\n" );
dd = Cudd_Init( nFaninsMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
// set the mapping of AIG nodes into the BDD nodes
pMan = pNtk->pManFunc;
assert( Aig_ManPiNum(pMan) >= nFaninsMax );
for ( i = 0; i < nFaninsMax; i++ )
Aig_ManPi(pMan, i)->pData = Cudd_bddIthVar(dd, i);
// convert each node from SOP to BDD
Abc_NtkForEachNode( pNtk, pNode, i )
{
assert( pNode->pData );
pNode->pData = Abc_ConvertAigToBdd( dd, pNode->pData );
if ( pNode->pData == NULL )
{
printf( "Abc_NtkSopToBdd: Error while converting SOP into BDD.\n" );
return 0;
}
Cudd_Ref( pNode->pData );
}
Aig_ManStop( pNtk->pManFunc );
pNtk->pManFunc = dd;
// update the network type
pNtk->ntkFunc = ABC_FUNC_BDD;
return 1;
}
/**Function*************************************************************
Synopsis [Construct BDDs and mark AIG nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ConvertAigToBdd_rec1( DdManager * dd, Aig_Obj_t * pObj )
{
assert( !Aig_IsComplement(pObj) );
if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
return;
Abc_ConvertAigToBdd_rec1( dd, Aig_ObjFanin0(pObj) );
Abc_ConvertAigToBdd_rec1( dd, Aig_ObjFanin1(pObj) );
pObj->pData = Cudd_bddAnd( dd, (DdNode *)Aig_ObjChild0Copy(pObj), (DdNode *)Aig_ObjChild1Copy(pObj) );
Cudd_Ref( pObj->pData );
assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
Aig_ObjSetMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Dereference BDDs and unmark AIG nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ConvertAigToBdd_rec2( DdManager * dd, Aig_Obj_t * pObj )
{
assert( !Aig_IsComplement(pObj) );
if ( !Aig_ObjIsNode(pObj) || !Aig_ObjIsMarkA(pObj) )
return;
Abc_ConvertAigToBdd_rec2( dd, Aig_ObjFanin0(pObj) );
Abc_ConvertAigToBdd_rec2( dd, Aig_ObjFanin1(pObj) );
Cudd_RecursiveDeref( dd, pObj->pData );
pObj->pData = NULL;
assert( Aig_ObjIsMarkA(pObj) ); // loop detection
Aig_ObjClearMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Converts the network from AIG to BDD representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode * Abc_ConvertAigToBdd( DdManager * dd, Aig_Obj_t * pRoot )
{
DdNode * bFunc;
// construct BDD
Abc_ConvertAigToBdd_rec1( dd, Aig_Regular(pRoot) );
// hold on to the result
bFunc = Cudd_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) ); Cudd_Ref( bFunc );
// dereference BDD
Abc_ConvertAigToBdd_rec2( dd, Aig_Regular(pRoot) );
// return the result
Cudd_Deref( bFunc );
return bFunc;
}
/**Function*************************************************************
Synopsis [Unmaps the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkMapToSop( Abc_Ntk_t * pNtk )
{
extern void * Abc_FrameReadLibGen();
Abc_Obj_t * pNode;
char * pSop;
int i;
assert( Abc_NtkIsMappedLogic(pNtk) );
// update the functionality manager
assert( pNtk->pManFunc == Abc_FrameReadLibGen() );
pNtk->pManFunc = Extra_MmFlexStart();
pNtk->ntkFunc = ABC_FUNC_SOP;
// update the nodes
Abc_NtkForEachNode( pNtk, pNode, i )
{
pSop = Mio_GateReadSop(pNode->pData);
assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) );
pNode->pData = Abc_SopRegister( pNtk->pManFunc, pSop );
}
return 1;
}
/**Function*************************************************************
Synopsis [Convers logic network to the SOP form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkLogicToSop( Abc_Ntk_t * pNtk, int fDirect )
{
assert( Abc_NtkIsLogic(pNtk) );
if ( Abc_NtkIsSopLogic(pNtk) )
{
if ( !fDirect )
return 1;
if ( !Abc_NtkSopToBdd(pNtk) )
return 0;
return Abc_NtkBddToSop(pNtk, fDirect);
}
if ( Abc_NtkIsMappedLogic(pNtk) )
return Abc_NtkMapToSop(pNtk);
if ( Abc_NtkIsBddLogic(pNtk) )
return Abc_NtkBddToSop(pNtk, fDirect);
if ( Abc_NtkIsAigLogic(pNtk) )
{
if ( !Abc_NtkAigToBdd(pNtk) )
return 0;
return Abc_NtkBddToSop(pNtk, fDirect);
}
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis [Convers logic network to the SOP form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkLogicToBdd( Abc_Ntk_t * pNtk )
{
assert( Abc_NtkIsLogic(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
return 1;
if ( Abc_NtkIsMappedLogic(pNtk) )
{
Abc_NtkMapToSop(pNtk);
return Abc_NtkSopToBdd(pNtk);
}
if ( Abc_NtkIsSopLogic(pNtk) )
return Abc_NtkSopToBdd(pNtk);
if ( Abc_NtkIsAigLogic(pNtk) )
return Abc_NtkAigToBdd(pNtk);
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis [Convers logic network to the SOP form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkLogicToAig( Abc_Ntk_t * pNtk )
{
assert( Abc_NtkIsLogic(pNtk) );
if ( Abc_NtkIsAigLogic(pNtk) )
return 1;
if ( Abc_NtkIsMappedLogic(pNtk) )
{
Abc_NtkMapToSop(pNtk);
return Abc_NtkSopToAig(pNtk);
}
if ( Abc_NtkIsBddLogic(pNtk) )
{
if ( !Abc_NtkBddToSop(pNtk,0) )
return 0;
return Abc_NtkSopToAig(pNtk);
}
if ( Abc_NtkIsSopLogic(pNtk) )
return Abc_NtkSopToAig(pNtk);
assert( 0 );
return 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -110,14 +110,18 @@ int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk )
***********************************************************************/
int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pLatch;
Abc_Obj_t * pLatch, * pConst1;
int i, Counter;
Counter = 0;
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
if ( Abc_NtkLatchIsSelfFeed( pLatch ) )
{
Abc_ObjPatchFanin( pLatch, Abc_ObjFanin0(pLatch), Abc_NtkConst1(pNtk) );
if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) )
pConst1 = Abc_AigConst1(pNtk);
else
pConst1 = Abc_NodeCreateConst1(pNtk);
Abc_ObjPatchFanin( pLatch, Abc_ObjFanin0(pLatch), pConst1 );
Counter++;
}
}

116
src/base/abc/abcLib.c Normal file
View File

@ -0,0 +1,116 @@
/**CFile****************************************************************
FileName [abcLib.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Functions to manipulate verilog libraries.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcLib.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Create the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Lib_t * Abc_LibCreate( char * pName )
{
Abc_Lib_t * p;
p = ALLOC( Abc_Lib_t, 1 );
memset( p, 0, sizeof(Abc_Lib_t) );
p->pName = Extra_UtilStrsav( pName );
p->tModules = st_init_table( strcmp, st_strhash );
p->pManFunc = Aig_ManStart();
return p;
}
/**Function*************************************************************
Synopsis [Frees the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_LibFree( Abc_Lib_t * pLib )
{
st_generator * gen;
Abc_Ntk_t * pNtk;
char * pName;
if ( pLib->pName )
free( pLib->pName );
if ( pLib->pManFunc )
Aig_ManStop( pLib->pManFunc );
if ( pLib->tModules )
{
st_foreach_item( pLib->tModules, gen, (char**)&pName, (char**)&pNtk )
Abc_NtkDelete( pNtk );
st_free_table( pLib->tModules );
}
free( pLib );
}
/**Function*************************************************************
Synopsis [Frees the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib )
{
st_generator * gen;
Abc_Ntk_t * pNtk;
char * pName;
if ( st_count(pLib->tModules) > 1 )
{
printf( "The design includes more than one module and is currently not used.\n" );
return NULL;
}
// find the network
st_foreach_item( pLib->tModules, gen, (char**)&pName, (char**)&pNtk )
{
st_free_gen(gen);
break;
}
return pNtk;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -45,6 +45,7 @@ char * Abc_ObjName( Abc_Obj_t * pObj )
{
static char Buffer[500];
char * pName;
int Counter;
// check if the object is in the lookup table
// if ( stmm_lookup( pObj->pNtk->tObj2Name, (char *)pObj, &pName ) )
@ -63,7 +64,11 @@ char * Abc_ObjName( Abc_Obj_t * pObj )
if ( pObj->pData )
sprintf( Buffer, "%s", pObj->pData );
else
{
sprintf( Buffer, "[%d]", pObj->Id ); // make sure this name is unique!!!
for ( Counter = 1; Nm_ManFindIdByName(pObj->pNtk->pManName, Buffer, NULL) >= 0; Counter++ )
sprintf( Buffer, "[%d]_%d", pObj->Id, Counter );
}
}
else
{
@ -71,6 +76,8 @@ char * Abc_ObjName( Abc_Obj_t * pObj )
// internal nodes have made up names
assert( Abc_ObjIsNode(pObj) || Abc_ObjIsLatch(pObj) );
sprintf( Buffer, "[%d]", pObj->Id );
for ( Counter = 1; Nm_ManFindIdByName(pObj->pNtk->pManName, Buffer, NULL) >= 0; Counter++ )
sprintf( Buffer, "[%d]_%d", pObj->Id, Counter );
}
return Buffer;
}

View File

@ -264,8 +264,18 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk, int fDirect )
pNtkNew = Abc_NtkLogicSopToNetlist( pNtk );
Abc_NtkSopToBdd(pNtk);
}
else
else if ( Abc_NtkIsAigLogic(pNtk) )
{
if ( !Abc_NtkAigToBdd(pNtk) )
return NULL;
if ( !Abc_NtkBddToSop(pNtk, fDirect) )
return NULL;
pNtkNew = Abc_NtkLogicSopToNetlist( pNtk );
Abc_NtkSopToAig(pNtk);
}
else if ( Abc_NtkIsSopLogic(pNtk) || Abc_NtkIsMappedLogic(pNtk) )
pNtkNew = Abc_NtkLogicSopToNetlist( pNtk );
else assert( 0 );
return pNtkNew;
}
@ -408,20 +418,20 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsStrash(pNtk) );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
// if the constant node is used, duplicate it
pObj = Abc_AigConst1(pNtk);
if ( Abc_ObjFanoutNum(pObj) > 0 )
pObj->pCopy = Abc_NodeCreateConst1(pNtkNew);
// duplicate the nodes and create node functions
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 the choice nodes
Abc_NtkForEachNode( pNtk, pObj, i )
{
if ( Abc_NodeIsConst(pObj) )
continue;
if ( !Abc_NodeIsAigChoice(pObj) )
if ( !Abc_AigNodeIsChoice(pObj) )
continue;
// create an OR gate
pNodeNew = Abc_NtkCreateNode(pNtkNew);
@ -497,17 +507,20 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk )
// collect the nodes to be used (marks all nodes with current TravId)
vNodes = Abc_NtkDfs( pNtk, 0 );
// create inverters for the CI and remember them
pObj = Abc_AigConst1(pNtk);
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
{
pObj->pCopy = Abc_NodeCreateConst1(pNtkNew);
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
}
Abc_NtkForEachCi( pNtk, pObj, i )
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
// duplicate the nodes, create node functions, and inverters
Vec_PtrForEachEntry( vNodes, pObj, i )
{
if ( !Abc_NodeIsConst(pObj) )
{
Abc_NtkDupObj( pNtkNew, pObj );
pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2, NULL );
}
Abc_NtkDupObj( pNtkNew, pObj );
pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2, NULL );
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
}

View File

@ -50,49 +50,40 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
memset( pNtk, 0, sizeof(Abc_Ntk_t) );
pNtk->ntkType = Type;
pNtk->ntkFunc = Func;
pNtk->Id = !Abc_HManIsRunning()? 0 : Abc_HManGetNewNtkId();
// start the object storage
pNtk->vObjs = Vec_PtrAlloc( 100 );
pNtk->vLatches = Vec_PtrAlloc( 100 );
pNtk->vAsserts = Vec_PtrAlloc( 100 );
pNtk->vPios = Vec_PtrAlloc( 100 );
pNtk->vPis = Vec_PtrAlloc( 100 );
pNtk->vPos = Vec_PtrAlloc( 100 );
pNtk->vCis = Vec_PtrAlloc( 100 );
pNtk->vCos = Vec_PtrAlloc( 100 );
pNtk->vCutSet = Vec_PtrAlloc( 100 );
pNtk->vBoxes = Vec_PtrAlloc( 100 );
pNtk->vSkews = Vec_FltAlloc( 100 );
// start the memory managers
pNtk->pMmObj = Extra_MmFixedStart( sizeof(Abc_Obj_t) );
pNtk->pMmStep = Extra_MmStepStart( ABC_NUM_STEPS );
// get ready to assign the first Obj ID
pNtk->nTravIds = 1;
// start the functionality manager
if ( Abc_NtkHasSop(pNtk) )
if ( Abc_NtkIsStrash(pNtk) )
pNtk->pManFunc = Abc_AigAlloc( pNtk );
else if ( Abc_NtkIsSeq(pNtk) )
pNtk->pManFunc = Seq_Create( pNtk );
else if ( Abc_NtkHasSop(pNtk) )
pNtk->pManFunc = Extra_MmFlexStart();
else if ( Abc_NtkHasBdd(pNtk) )
pNtk->pManFunc = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
else if ( Abc_NtkHasAig(pNtk) )
{
if ( Abc_NtkIsStrash(pNtk) )
pNtk->pManFunc = Abc_AigAlloc( pNtk );
else
pNtk->pManFunc = Seq_Create( pNtk );
}
pNtk->pManFunc = Aig_ManStart();
else if ( Abc_NtkHasMapping(pNtk) )
pNtk->pManFunc = Abc_FrameReadLibGen();
else if ( !Abc_NtkHasBlackbox(pNtk) )
assert( 0 );
// allocate constant node
if ( !Abc_NtkIsNetlist(pNtk) )
{
Abc_NodeCreateConst1( pNtk );
// do not count this node towards the total number of nodes
pNtk->nNodes -= 1;
}
else
Vec_PtrPush( pNtk->vObjs, NULL );
// name manager
pNtk->pManName = Nm_ManCreate( 1000 );
//printf( "Allocated newtork %p\n", pNtk );
return pNtk;
}
@ -123,8 +114,8 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = NULL;
// map the constant nodes
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// clone the PIs/POs/latches
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
@ -134,14 +125,6 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
Abc_NtkDupObj(pNtkNew, pObj);
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() )
{
Abc_HManAddProto( Abc_NtkConst1(pNtk)->pCopy, Abc_NtkConst1(pNtk) );
Abc_NtkForEachCi( pNtk, pObj, i )
Abc_HManAddProto( pObj->pCopy, pObj );
Abc_NtkForEachCo( pNtk, pObj, i )
Abc_HManAddProto( pObj->pCopy, pObj );
}
// transfer the names
if ( Type != ABC_NTK_NETLIST )
Abc_NtkDupCioNamesTable( pNtk, pNtkNew );
@ -180,8 +163,8 @@ Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = NULL;
// map the constant nodes
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// clone the PIs/POs/latches
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
@ -226,8 +209,8 @@ Abc_Ntk_t * Abc_NtkStartFromDual( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkF
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = NULL;
// map the constant nodes
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// clone the PIs/POs/latches
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
@ -412,11 +395,6 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
}
if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() )
{
Abc_AigForEachAnd( pNtk, pObj, i )
Abc_HManAddProto( pObj->pCopy, pObj );
}
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
@ -454,7 +432,8 @@ Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNode
pNtkNew->pName = Extra_UtilStrsav(Buffer);
// establish connection between the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// collect the nodes in the TFI of the output (mark the TFI)
vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 );
@ -523,7 +502,8 @@ Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNode
pNtkNew->pName = Extra_UtilStrsav(Buffer);
// establish connection between the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// collect the nodes in MFFC
vCone = Vec_PtrAlloc( 100 );
@ -584,6 +564,10 @@ Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t
int i;
assert( Abc_NtkIsLogic(pNtk) );
// convert the network into the AIG form
if ( !Abc_NtkLogicToAig(pNtk) )
return NULL;
// start the network
Abc_NtkCleanCopy( pNtk );
@ -604,7 +588,7 @@ Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t
Vec_PtrFree( vNodes );
// add the PO
pFinal = Abc_NtkConst1( pNtkNew );
pFinal = Abc_AigConst1( pNtkNew );
Vec_PtrForEachEntry( vRoots, pObj, i )
{
if ( Abc_ObjIsCo(pObj) )
@ -746,6 +730,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
if ( pNtk->pExdc )
Abc_NtkDelete( pNtk->pExdc );
// free the arrays
Vec_PtrFree( pNtk->vPios );
Vec_PtrFree( pNtk->vPis );
Vec_PtrFree( pNtk->vPos );
Vec_PtrFree( pNtk->vCis );
@ -754,6 +739,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
Vec_PtrFree( pNtk->vLatches );
Vec_PtrFree( pNtk->vObjs );
Vec_PtrFree( pNtk->vCutSet );
Vec_PtrFree( pNtk->vBoxes );
Vec_FltFree( pNtk->vSkews );
if ( pNtk->pModel ) free( pNtk->pModel );
TotalMemory = 0;
TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj);
@ -762,25 +749,26 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
// free the storage
Extra_MmFixedStop( pNtk->pMmObj, 0 );
Extra_MmStepStop ( pNtk->pMmStep, 0 );
// name manager
Nm_ManFree( pNtk->pManName );
// free the timing manager
if ( pNtk->pManTime )
Abc_ManTimeStop( pNtk->pManTime );
// start the functionality manager
if ( Abc_NtkHasSop(pNtk) )
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigFree( pNtk->pManFunc );
else if ( Abc_NtkIsSeq(pNtk) )
Seq_Delete( pNtk->pManFunc );
else if ( Abc_NtkHasSop(pNtk) )
Extra_MmFlexStop( pNtk->pManFunc, 0 );
else if ( Abc_NtkHasBdd(pNtk) )
Extra_StopManager( pNtk->pManFunc );
else if ( Abc_NtkHasAig(pNtk) )
{
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigFree( pNtk->pManFunc );
else
Seq_Delete( pNtk->pManFunc );
}
else if ( !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlackbox(pNtk) )
Aig_ManStop( pNtk->pManFunc );
else if ( Abc_NtkHasMapping(pNtk) )
pNtk->pManFunc = NULL;
else if ( !Abc_NtkHasBlackbox(pNtk) )
assert( 0 );
// name manager
Nm_ManFree( pNtk->pManName );
// free the hierarchy
if ( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model )
{
@ -820,9 +808,7 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
if ( Abc_ObjFaninNum(pNet) > 0 )
continue;
// add the constant 0 driver
pNode = Abc_NtkCreateNode( pNtk );
// set the constant function
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") );
pNode = Abc_NodeCreateConst0( pNtk );
// add the fanout net
Abc_ObjAddFanin( pNet, pNode );
// add the net to those for which the warning will be printed

View File

@ -50,8 +50,6 @@ Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
pObj->pNtk = pNtk;
pObj->Type = Type;
pObj->Id = -1;
if ( pNtk->ntkType != ABC_NTK_NETLIST )
Abc_HManAddObj( pObj );
return pObj;
}
@ -99,14 +97,14 @@ void Abc_ObjAdd( Abc_Obj_t * pObj )
Vec_PtrPush( pNtk->vObjs, pObj );
pNtk->nObjs++;
// perform specialized operations depending on the object type
if ( Abc_ObjIsNet(pObj) )
{
pNtk->nNets++;
}
else if ( Abc_ObjIsNode(pObj) )
if ( Abc_ObjIsNode(pObj) )
{
pNtk->nNodes++;
}
else if ( Abc_ObjIsNet(pObj) )
{
pNtk->nNets++;
}
else if ( Abc_ObjIsPi(pObj) )
{
Vec_PtrPush( pNtk->vPis, pObj );
@ -128,14 +126,20 @@ void Abc_ObjAdd( Abc_Obj_t * pObj )
Vec_PtrPush( pNtk->vAsserts, pObj );
Vec_PtrPush( pNtk->vCos, pObj );
}
else if ( Abc_ObjIsBi(pObj) )
{
Vec_PtrPush( pNtk->vCis, pObj );
}
else if ( Abc_ObjIsBo(pObj) )
{
Vec_PtrPush( pNtk->vCos, pObj );
}
else if ( Abc_ObjIsBox(pObj) )
{
pNtk->nBoxes++;
Vec_PtrPush( pNtk->vBoxes, pObj );
}
else
{
assert( 0 );
}
else assert( 0 );
}
/**Function*************************************************************
@ -161,14 +165,17 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
{
if ( pNtkNew->ntkFunc == pObj->pNtk->ntkFunc )
{
if ( Abc_NtkHasSop(pNtkNew) )
if ( Abc_NtkIsStrash(pNtkNew) || Abc_NtkIsSeq(pNtkNew) )
{}
else if ( Abc_NtkHasSop(pNtkNew) )
pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pObj->pData );
else if ( Abc_NtkHasBdd(pNtkNew) )
pObjNew->pData = Cudd_bddTransfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData), Cudd_Ref(pObjNew->pData);
else if ( Abc_NtkHasAig(pNtkNew) )
pObjNew->pData = Aig_Transfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData, Abc_ObjFaninNum(pObj));
else if ( Abc_NtkHasMapping(pNtkNew) )
pObjNew->pData = pObj->pData;
else if ( !Abc_NtkHasAig(pNtkNew) )
assert( 0 );
else assert( 0 );
}
}
else if ( Abc_ObjIsNet(pObj) ) // copy the name
@ -181,6 +188,27 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
return pObjNew;
}
/**Function*************************************************************
Synopsis [Clones the objects in the same network but does not assign its function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pObj )
{
Abc_Obj_t * pClone, * pFanin;
int i;
pClone = Abc_ObjAlloc( pObj->pNtk, pObj->Type );
Abc_ObjAdd( pClone );
Abc_ObjForEachFanin( pObj, pFanin, i )
Abc_ObjAddFanin( pClone, pFanin );
return pClone;
}
/**Function*************************************************************
@ -249,6 +277,14 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
Vec_PtrRemove( pObj->pNtk->vPos, pObj );
Vec_PtrRemove( pObj->pNtk->vCos, pObj );
}
else if ( Abc_ObjIsBi(pObj) )
{
Vec_PtrRemove( pObj->pNtk->vCis, pObj );
}
else if ( Abc_ObjIsBo(pObj) )
{
Vec_PtrRemove( pObj->pNtk->vCos, pObj );
}
else if ( Abc_ObjIsAssert(pObj) )
{
Vec_PtrRemove( pObj->pNtk->vAsserts, pObj );
@ -257,6 +293,7 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
else if ( Abc_ObjIsBox(pObj) )
{
pNtk->nBoxes--;
Vec_PtrRemove( pObj->pNtk->vBoxes, pObj );
}
else
assert( 0 );
@ -360,30 +397,6 @@ Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName )
return pObj;
}
/**Function*************************************************************
Synopsis [Returns the net with the given name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName )
{
Abc_Obj_t * pNode;
int i;
// search the node among COs
Abc_NtkForEachCo( pNtk, pNode, i )
{
if ( strcmp( Abc_ObjName(pNode), pName ) == 0 )
return pNode;
}
return NULL;
}
/**Function*************************************************************
Synopsis [Returns the net with the given name.]
@ -409,7 +422,7 @@ Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName )
/**Function*************************************************************
Synopsis [Returns the net with the given name.]
Synopsis [Returns the CI/CO terminal with the given name.]
Description []
@ -456,7 +469,7 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
/**Function*************************************************************
Synopsis [Create the new node.]
Synopsis [Create node.]
Description []
@ -472,10 +485,10 @@ Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk )
Abc_ObjAdd( pObj );
return pObj;
}
/**Function*************************************************************
Synopsis [Create the new node.]
Synopsis [Create multi-input/multi-output box.]
Description []
@ -494,7 +507,7 @@ Abc_Obj_t * Abc_NtkCreateBox( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Create the new node.]
Synopsis [Create primary input.]
Description []
@ -513,7 +526,7 @@ Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Create the new node.]
Synopsis [Create primary output.]
Description []
@ -532,7 +545,7 @@ Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Create the new node.]
Synopsis [Creates latch.]
Description []
@ -552,7 +565,7 @@ Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Create the new node.]
Synopsis [Creates assert.]
Description []
@ -571,7 +584,7 @@ Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Creates inverter.]
Synopsis [Creates constant 0 node.]
Description []
@ -583,12 +596,14 @@ Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
assert( !Abc_NtkHasAig(pNtk) );
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
if ( Abc_NtkHasSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 0\n" );
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_ReadLogicZero(pNtk->pManFunc), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasAig(pNtk) )
pNode->pData = Aig_ManConst0(pNtk->pManFunc);
else if ( Abc_NtkHasMapping(pNtk) )
pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen());
else if ( !Abc_NtkHasBlackbox(pNtk) )
@ -598,7 +613,7 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Creates inverter.]
Synopsis [Creates constant 1 node.]
Description []
@ -610,13 +625,14 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
if ( Abc_NtkHasAig(pNtk) )
return pNode;
if ( Abc_NtkHasSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 1\n" );
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasAig(pNtk) )
pNode->pData = Aig_ManConst1(pNtk->pManFunc);
else if ( Abc_NtkHasMapping(pNtk) )
pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen());
else if ( !Abc_NtkHasBlackbox(pNtk) )
@ -645,6 +661,8 @@ Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 1\n" );
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_Not(Cudd_bddIthVar(pNtk->pManFunc,0)), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasAig(pNtk) )
pNode->pData = Aig_Not(Aig_IthVar(pNtk->pManFunc,0));
else if ( Abc_NtkHasMapping(pNtk) )
pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen());
else
@ -673,6 +691,8 @@ Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" );
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_bddIthVar(pNtk->pManFunc,0), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasAig(pNtk) )
pNode->pData = Aig_IthVar(pNtk->pManFunc,0);
else if ( Abc_NtkHasMapping(pNtk) )
pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen());
else
@ -682,7 +702,7 @@ Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
/**Function*************************************************************
Synopsis [Creates inverter.]
Synopsis [Creates AND.]
Description []
@ -695,35 +715,16 @@ Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
{
Abc_Obj_t * pNode;
int i;
assert( Abc_NtkIsLogic(pNtk) );
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
for ( i = 0; i < vFanins->nSize; i++ )
Abc_ObjAddFanin( pNode, vFanins->pArray[i] );
if ( Abc_NtkHasSop(pNtk) )
{
char * pSop;
pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 );
for ( i = 0; i < vFanins->nSize; i++ )
pSop[i] = '1';
pSop[i++] = ' ';
pSop[i++] = '1';
pSop[i++] = '\n';
pSop[i++] = 0;
assert( i == vFanins->nSize + 4 );
pNode->pData = pSop;
}
pNode->pData = Abc_SopCreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins), NULL );
else if ( Abc_NtkHasBdd(pNtk) )
{
DdManager * dd = pNtk->pManFunc;
DdNode * bFunc, * bTemp;
bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc );
for ( i = 0; i < vFanins->nSize; i++ )
{
bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc );
Cudd_RecursiveDeref( dd, bTemp );
}
pNode->pData = bFunc;
}
pNode->pData = Extra_bddCreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref(pNode->pData);
else if ( Abc_NtkHasAig(pNtk) )
pNode->pData = Aig_CreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins) );
else
assert( 0 );
return pNode;
@ -731,7 +732,7 @@ Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
/**Function*************************************************************
Synopsis [Creates inverter.]
Synopsis [Creates OR.]
Description []
@ -744,35 +745,16 @@ Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
{
Abc_Obj_t * pNode;
int i;
assert( Abc_NtkIsLogic(pNtk) );
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
for ( i = 0; i < vFanins->nSize; i++ )
Abc_ObjAddFanin( pNode, vFanins->pArray[i] );
if ( Abc_NtkHasSop(pNtk) )
{
char * pSop;
pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 );
for ( i = 0; i < vFanins->nSize; i++ )
pSop[i] = '0';
pSop[i++] = ' ';
pSop[i++] = '0';
pSop[i++] = '\n';
pSop[i++] = 0;
assert( i == vFanins->nSize + 4 );
pNode->pData = pSop;
}
pNode->pData = Abc_SopCreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins), NULL );
else if ( Abc_NtkHasBdd(pNtk) )
{
DdManager * dd = pNtk->pManFunc;
DdNode * bFunc, * bTemp;
bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
for ( i = 0; i < vFanins->nSize; i++ )
{
bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc );
Cudd_RecursiveDeref( dd, bTemp );
}
pNode->pData = bFunc;
}
pNode->pData = Extra_bddCreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref(pNode->pData);
else if ( Abc_NtkHasAig(pNtk) )
pNode->pData = Aig_CreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins) );
else
assert( 0 );
return pNode;
@ -780,7 +762,37 @@ Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
/**Function*************************************************************
Synopsis [Creates inverter.]
Synopsis [Creates EXOR.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
{
Abc_Obj_t * pNode;
int i;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
for ( i = 0; i < vFanins->nSize; i++ )
Abc_ObjAddFanin( pNode, vFanins->pArray[i] );
if ( Abc_NtkHasSop(pNtk) )
pNode->pData = Abc_SopCreateXorSpecial( pNtk->pManFunc, Vec_PtrSize(vFanins) );
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Extra_bddCreateExor( pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref(pNode->pData);
else if ( Abc_NtkHasAig(pNtk) )
pNode->pData = Aig_CreateExor( pNtk->pManFunc, Vec_PtrSize(vFanins) );
else
assert( 0 );
return pNode;
}
/**Function*************************************************************
Synopsis [Creates MUX.]
Description []
@ -801,14 +813,17 @@ Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t *
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "11- 1\n0-1 1\n" );
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_bddIte(pNtk->pManFunc,Cudd_bddIthVar(pNtk->pManFunc,0),Cudd_bddIthVar(pNtk->pManFunc,1),Cudd_bddIthVar(pNtk->pManFunc,2)), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasAig(pNtk) )
pNode->pData = Aig_Mux(pNtk->pManFunc,Aig_IthVar(pNtk->pManFunc,0),Aig_IthVar(pNtk->pManFunc,1),Aig_IthVar(pNtk->pManFunc,2));
else
assert( 0 );
return pNode;
}
/**Function*************************************************************
Synopsis [Clones the given node but does not assign the function.]
Synopsis [Returns 1 if the node is a constant 0 node.]
Description []
@ -817,22 +832,16 @@ Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t *
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode )
{
Abc_Obj_t * pClone, * pFanin;
int i;
assert( Abc_ObjIsNode(pNode) );
pClone = Abc_NtkCreateNode( pNode->pNtk );
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_ObjAddFanin( pClone, pFanin );
return pClone;
bool Abc_NodeIsConst( Abc_Obj_t * pNode )
{
assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) );
assert( Abc_ObjIsNode(pNode) );
return Abc_ObjFaninNum(pNode) == 0;
}
/**Function*************************************************************
Synopsis []
Synopsis [Returns 1 if the node is a constant 0 node.]
Description []
@ -844,23 +853,25 @@ Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode )
bool Abc_NodeIsConst0( Abc_Obj_t * pNode )
{
Abc_Ntk_t * pNtk = pNode->pNtk;
assert(Abc_ObjIsNode(pNode));
assert(Abc_NodeIsConst(pNode));
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
assert( Abc_ObjIsNode(pNode) );
if ( !Abc_NodeIsConst(pNode) )
return 0;
if ( Abc_NtkHasSop(pNtk) )
return Abc_SopIsConst0(pNode->pData);
if ( Abc_NtkHasBdd(pNtk) )
return Cudd_IsComplement(pNode->pData);
if ( Abc_NtkHasAig(pNtk) )
return Abc_ObjNot(pNode) == Abc_NtkConst1(pNode->pNtk);
return Aig_IsComplement(pNode->pData);
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper());
return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibGen());
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis []
Synopsis [Returns 1 if the node is a constant 1 node.]
Description []
@ -872,23 +883,25 @@ bool Abc_NodeIsConst0( Abc_Obj_t * pNode )
bool Abc_NodeIsConst1( Abc_Obj_t * pNode )
{
Abc_Ntk_t * pNtk = pNode->pNtk;
assert(Abc_ObjIsNode(pNode));
assert(Abc_NodeIsConst(pNode));
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
assert( Abc_ObjIsNode(pNode) );
if ( !Abc_NodeIsConst(pNode) )
return 0;
if ( Abc_NtkHasSop(pNtk) )
return Abc_SopIsConst1(pNode->pData);
if ( Abc_NtkHasBdd(pNtk) )
return !Cudd_IsComplement(pNode->pData);
if ( Abc_NtkHasAig(pNtk) )
return pNode == Abc_NtkConst1(pNode->pNtk);
return !Aig_IsComplement(pNode->pData);
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper());
return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibGen());
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis []
Synopsis [Returns 1 if the node is a buffer.]
Description []
@ -900,7 +913,8 @@ bool Abc_NodeIsConst1( Abc_Obj_t * pNode )
bool Abc_NodeIsBuf( Abc_Obj_t * pNode )
{
Abc_Ntk_t * pNtk = pNode->pNtk;
assert(Abc_ObjIsNode(pNode));
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
assert( Abc_ObjIsNode(pNode) );
if ( Abc_ObjFaninNum(pNode) != 1 )
return 0;
if ( Abc_NtkHasSop(pNtk) )
@ -908,16 +922,16 @@ bool Abc_NodeIsBuf( Abc_Obj_t * pNode )
if ( Abc_NtkHasBdd(pNtk) )
return !Cudd_IsComplement(pNode->pData);
if ( Abc_NtkHasAig(pNtk) )
return 0;
return !Aig_IsComplement(pNode->pData);
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper());
return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibGen());
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis []
Synopsis [Returns 1 if the node is an inverter.]
Description []
@ -929,7 +943,8 @@ bool Abc_NodeIsBuf( Abc_Obj_t * pNode )
bool Abc_NodeIsInv( Abc_Obj_t * pNode )
{
Abc_Ntk_t * pNtk = pNode->pNtk;
assert(Abc_ObjIsNode(pNode));
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
assert( Abc_ObjIsNode(pNode) );
if ( Abc_ObjFaninNum(pNode) != 1 )
return 0;
if ( Abc_NtkHasSop(pNtk) )
@ -937,13 +952,38 @@ bool Abc_NodeIsInv( Abc_Obj_t * pNode )
if ( Abc_NtkHasBdd(pNtk) )
return Cudd_IsComplement(pNode->pData);
if ( Abc_NtkHasAig(pNtk) )
return 0;
return Aig_IsComplement(pNode->pData);
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper());
return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibGen());
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis [Complements the local functions of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeComplement( Abc_Obj_t * pNode )
{
assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) );
assert( Abc_ObjIsNode(pNode) );
if ( Abc_NtkHasSop(pNode->pNtk) )
Abc_SopComplement( pNode->pData );
else if ( Abc_NtkHasBdd(pNode->pNtk) )
pNode->pData = Cudd_Not( pNode->pData );
else if ( Abc_NtkHasAig(pNode->pNtk) )
pNode->pData = Aig_Not( pNode->pData );
else
assert( 0 );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -47,7 +47,7 @@ void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i;
if ( pNtk->nTravIds == (1<<9)-1 )
if ( pNtk->nTravIds == (1<<8)-1 )
{
pNtk->nTravIds = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
@ -183,14 +183,40 @@ int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsBddLogic(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
assert( pNode->pData );
if ( Abc_NodeIsConst(pNode) )
continue;
assert( pNode->pData );
nNodes += pNode->pData? Cudd_DagSize( pNode->pData ) : 0;
}
return nNodes;
}
/**Function*************************************************************
Synopsis [Reads the number of BDD nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i, nNodes = 0;
assert( Abc_NtkIsAigLogic(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
assert( pNode->pData );
if ( Abc_NodeIsConst(pNode) )
continue;
nNodes += pNode->pData? Aig_DagSize( pNode->pData ) : 0;
}
return nNodes;
}
/**Function*************************************************************
Synopsis [Reads the number of BDD nodes.]
@ -321,7 +347,7 @@ int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk )
return 0;
Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i )
Counter += Abc_NodeIsAigChoice( pNode );
Counter += Abc_AigNodeIsChoice( pNode );
return Counter;
}
@ -525,13 +551,8 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate )
if ( Abc_ObjFaninC0(pNode) )
{
// change polarity of the duplicated driver
if ( Abc_NtkHasSop(pNtk) )
Abc_SopComplement( pDriverNew->pData );
else if ( Abc_NtkHasBdd(pNtk) )
pDriverNew->pData = Cudd_Not( pDriverNew->pData );
else
assert( 0 );
Abc_ObjXorFaninC(pNode, 0);
Abc_NodeComplement( pDriverNew );
Abc_ObjXorFaninC( pNode, 0 );
}
}
else
@ -605,7 +626,7 @@ bool Abc_NodeIsExorType( Abc_Obj_t * pNode )
// check that the node is regular
assert( !Abc_ObjIsComplement(pNode) );
// if the node is not AND, this is not EXOR
if ( !Abc_NodeIsAigAnd(pNode) )
if ( !Abc_AigNodeIsAnd(pNode) )
return 0;
// if the children are not complemented, this is not EXOR
if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
@ -638,7 +659,7 @@ bool Abc_NodeIsMuxType( Abc_Obj_t * pNode )
// check that the node is regular
assert( !Abc_ObjIsComplement(pNode) );
// if the node is not AND, this is not MUX
if ( !Abc_NodeIsAigAnd(pNode) )
if ( !Abc_AigNodeIsAnd(pNode) )
return 0;
// if the children are not complemented, this is not MUX
if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
@ -1049,7 +1070,7 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk )
// start the array of objects with new IDs
vObjsNew = Vec_PtrAlloc( pNtk->nObjs );
// put constant node first
pConst1 = Abc_NtkConst1(pNtk);
pConst1 = Abc_AigConst1(pNtk);
assert( pConst1->Id == 0 );
Vec_PtrPush( vObjsNew, pConst1 );
// put PI nodes next

View File

@ -4,6 +4,7 @@ SRC += src/base/abc/abcAig.c \
src/base/abc/abcFanio.c \
src/base/abc/abcFunc.c \
src/base/abc/abcLatch.c \
src/base/abc/abcLib.c \
src/base/abc/abcMinBase.c \
src/base/abc/abcNames.c \
src/base/abc/abcNetlist.c \

View File

@ -45,6 +45,7 @@ static int Abc_CommandPrintAuto ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandPrintKMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintGates ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintSharing ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintSkews ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandShowBdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandShowCut ( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -73,6 +74,7 @@ static int Abc_CommandOrPos ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandFrames ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSop ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandBdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandReorder ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandOrder ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMuxes ( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -95,6 +97,7 @@ static int Abc_CommandIRewrite ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandIRewriteSeq ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIResyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -131,6 +134,9 @@ static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandTraceStart ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTraceCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandHoward ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSkewForward ( Abc_Frame_t * pAbc, int argc, char ** argv );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@ -164,6 +170,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Printing", "print_kmap", Abc_CommandPrintKMap, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_gates", Abc_CommandPrintGates, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_sharing", Abc_CommandPrintSharing, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_skews", Abc_CommandPrintSkews, 0 );
Cmd_CommandAdd( pAbc, "Printing", "show_bdd", Abc_CommandShowBdd, 0 );
Cmd_CommandAdd( pAbc, "Printing", "show_cut", Abc_CommandShowCut, 0 );
@ -192,6 +199,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "frames", Abc_CommandFrames, 1 );
Cmd_CommandAdd( pAbc, "Various", "sop", Abc_CommandSop, 0 );
Cmd_CommandAdd( pAbc, "Various", "bdd", Abc_CommandBdd, 0 );
Cmd_CommandAdd( pAbc, "Various", "aig", Abc_CommandAig, 0 );
Cmd_CommandAdd( pAbc, "Various", "reorder", Abc_CommandReorder, 0 );
Cmd_CommandAdd( pAbc, "Various", "order", Abc_CommandOrder, 0 );
Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 1 );
@ -214,6 +222,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "New AIG", "irws", Abc_CommandIRewriteSeq, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "iresyn", Abc_CommandIResyn, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "haig", Abc_CommandHaig, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "mini", Abc_CommandMini, 1 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 );
@ -247,8 +256,11 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 );
Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 );
Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 );
// Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 );
// Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 );
Cmd_CommandAdd( pAbc, "Sequential", "howard", Abc_CommandHoward, 0 );
Cmd_CommandAdd( pAbc, "Sequential", "skew_fwd", Abc_CommandSkewForward, 0 );
// Rwt_Man4ExploreStart();
// Map_Var3Print();
@ -1286,6 +1298,74 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandPrintSkews( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
int fPrintAll;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fPrintAll = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF )
{
switch ( c )
{
case 'a':
fPrintAll = 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsSeq(pNtk) && Abc_NtkLatchNum(pNtk) == 0 )
{
fprintf( pErr, "The network has no latches.\n" );
return 0;
}
if ( pNtk->vSkews == NULL || pNtk->vSkews->nSize == 0 )
{
fprintf( pErr, "The network has no clock skew schedule.\n" );
return 0;
}
Abc_NtkPrintSkews( pOut, pNtk, fPrintAll );
return 0;
usage:
fprintf( pErr, "usage: print_skews [-h] [-a]\n" );
fprintf( pErr, "\t prints information about a clock skew schedule\n" );
fprintf( pErr, "\t-a : dumps the skew of every latch [default = no]\n");
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
@ -3309,29 +3389,26 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
// get the new network
if ( !Abc_NtkIsBddLogic(pNtk) )
if ( !Abc_NtkIsLogic(pNtk) )
{
fprintf( pErr, "Converting to SOP is possible when node functions are BDDs.\n" );
fprintf( pErr, "Converting to SOP is possible only for logic networks.\n" );
return 1;
}
if ( !Abc_NtkBddToSop( pNtk, fDirect ) )
if ( !Abc_NtkLogicToSop(pNtk, fDirect) )
{
fprintf( pErr, "Converting to SOP has failed.\n" );
fprintf( pErr, "Converting to BDD has failed.\n" );
return 1;
}
return 0;
usage:
fprintf( pErr, "usage: sop [-dh]\n" );
fprintf( pErr, "\t converts node functions from BDD to SOP\n" );
fprintf( pErr, "\t converts node functions to SOP\n" );
fprintf( pErr, "\t-d : toggles using both phases or only positive [default = %s]\n", fDirect? "direct": "both" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@ -3370,19 +3447,22 @@ int Abc_CommandBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsSopLogic(pNtk) )
if ( !Abc_NtkIsLogic(pNtk) )
{
fprintf( pErr, "Converting to BDD is possible when node functions are SOPs.\n" );
fprintf( pErr, "Converting to BDD is possible only for logic networks.\n" );
return 1;
}
if ( !Abc_NtkSopToBdd( pNtk ) )
if ( Abc_NtkIsBddLogic(pNtk) )
{
fprintf( pOut, "The logic network is already in the BDD form.\n" );
return 0;
}
if ( !Abc_NtkLogicToBdd(pNtk) )
{
fprintf( pErr, "Converting to BDD has failed.\n" );
return 1;
@ -3391,7 +3471,69 @@ int Abc_CommandBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
fprintf( pErr, "usage: bdd [-h]\n" );
fprintf( pErr, "\t converts node functions from SOP to BDD\n" );
fprintf( pErr, "\t converts node functions to BDD\n" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAig( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsLogic(pNtk) )
{
fprintf( pErr, "Converting to AIG is possible only for logic networks.\n" );
return 1;
}
if ( Abc_NtkIsAigLogic(pNtk) )
{
fprintf( pOut, "The logic network is already in the AIG form.\n" );
return 0;
}
if ( !Abc_NtkLogicToAig(pNtk) )
{
fprintf( pErr, "Converting to AIG has failed.\n" );
return 1;
}
return 0;
usage:
fprintf( pErr, "usage: aig [-h]\n" );
fprintf( pErr, "\t converts node functions to AIG\n" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
@ -3759,7 +3901,7 @@ int Abc_CommandOneOutput( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( argc == globalUtilOptind + 1 )
{
pNodeCo = Abc_NtkFindCo( pNtk, argv[globalUtilOptind] );
pNodeCo = Abc_NtkFindTerm( pNtk, argv[globalUtilOptind] );
pNode = Abc_NtkFindNode( pNtk, argv[globalUtilOptind] );
if ( pNode == NULL )
{
@ -5271,6 +5413,73 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandMini( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
int c;
extern Abc_Ntk_t * Abc_NtkMiniBalance( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( Abc_NtkIsSeq(pNtk) )
{
fprintf( pErr, "Only works for non-sequential networks.\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
fprintf( pErr, "Only works for combinatinally strashed AIG networks.\n" );
return 1;
}
pNtkRes = Abc_NtkMiniBalance( pNtk );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Command has failed.\n" );
return 0;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
fprintf( pErr, "usage: mini [-h]\n" );
fprintf( pErr, "\t perform balancing using new package\n" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
@ -5913,7 +6122,6 @@ int Abc_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv )
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
@ -5944,7 +6152,7 @@ int Abc_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// get the new network
if ( !Abc_NtkUnmap( pNtk ) )
if ( !Abc_NtkMapToSop( pNtk ) )
{
fprintf( pErr, "Unmapping has failed.\n" );
return 1;
@ -5974,7 +6182,6 @@ int Abc_CommandAttach( Abc_Frame_t * pAbc, int argc, char ** argv )
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
@ -7982,13 +8189,14 @@ int Abc_CommandTraceStart( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "This command is applicable to AIGs.\n" );
return 1;
}
/*
Abc_HManStart();
if ( !Abc_HManPopulate( pNtk ) )
{
fprintf( pErr, "Failed to start the tracing database.\n" );
return 1;
}
*/
return 0;
usage:
@ -8042,7 +8250,7 @@ int Abc_CommandTraceCheck( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "This command is applicable to AIGs.\n" );
return 1;
}
/*
if ( !Abc_HManIsRunning(pNtk) )
{
fprintf( pErr, "The tracing database is not available.\n" );
@ -8052,6 +8260,7 @@ int Abc_CommandTraceCheck( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( !Abc_HManVerify( 1, pNtk->Id ) )
fprintf( pErr, "Verification failed.\n" );
Abc_HManStop();
*/
return 0;
usage:
@ -8060,6 +8269,168 @@ usage:
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandHoward( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
int fVerbose;
double result;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{
switch ( c )
{
case 'v':
fVerbose ^= 1;
break;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsSeq(pNtk) && Abc_NtkLatchNum(pNtk) == 0 )
{
fprintf( pErr, "The network has no latches. Analysis is not performed.\n" );
return 0;
}
if ( Abc_NtkHasAig(pNtk) )
{
// quit if there are choice nodes
if ( Abc_NtkGetChoiceNum(pNtk) )
{
fprintf( pErr, "Currently cannot analyze networks with choice nodes.\n" );
return 0;
}
/*
if ( Abc_NtkIsStrash(pNtk) )
pNtkRes = Abc_NtkAigToSeq(pNtk);
else
pNtkRes = Abc_NtkDup(pNtk);
*/
fprintf( pErr, "Currently cannot analyze unmapped networks.\n" );
return 0;
}
result = Seq_NtkHoward( pNtk, fVerbose );
if (result < 0) {
fprintf( pErr, "Analysis failed.\n" );
return 0;
}
printf("Maximum mean cycle time = %.2f\n", result);
return 1;
usage:
fprintf( pErr, "usage: howard [-h]\n" );
fprintf( pErr, "\t computes the maximum mean cycle time using Howard's algorithm\n" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandSkewForward( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
int fMinimize;
float target;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
target = pNtk->maxMeanCycle;
fMinimize = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "mh" ) ) != EOF )
{
switch ( c )
{
case 'm':
fMinimize ^= 1;
break;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsSeq(pNtk) && Abc_NtkLatchNum(pNtk) == 0 )
{
fprintf( pErr, "The network has no latches.\n" );
return 0;
}
if ( pNtk->vSkews == NULL || pNtk->vSkews->nSize == 0 )
{
fprintf( pErr, "The network has no clock skew schedule.\n" );
return 0;
}
Seq_NtkSkewForward( pNtk, target, fMinimize );
return 1;
usage:
fprintf( pErr, "usage: skew_fwd [-h] [-m] [-t float]\n" );
fprintf( pErr, "\t converts a skew schedule into a set of forward skews 0<skew<T\n" );
fprintf( pErr, "\t-m : minimizes sum of skews [default = %s]\n", fMinimize? "yes": "no" );
fprintf( pErr, "\t-t : clock period, T [default = maxMeanCycle] (unimplemented)\n");
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -233,7 +233,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, Level, fDuplicate, fSelective );
if ( vSuper->nSize == 0 )
{ // it means that the supergate contains two nodes in the opposite polarity
pNodeOld->pCopy = Abc_ObjNot(Abc_NtkConst1(pNtkNew));
pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pNtkNew));
return pNodeOld->pCopy;
}
// for each old node, derive the new well-balanced node
@ -263,9 +263,8 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
assert( pNodeOld->pCopy == NULL );
// mark the old node with the new node
pNodeOld->pCopy = vSuper->pArray[0];
Abc_HManAddProto( pNodeOld->pCopy, pNodeOld );
vSuper->nSize = 0;
// if ( Abc_ObjRegular(pNodeOld->pCopy) == Abc_NtkConst1(pNtkNew) )
// if ( Abc_ObjRegular(pNodeOld->pCopy) == Abc_AigConst1(pNtkNew) )
// printf( "Constant node\n" );
// assert( pNodeOld->Level >= Abc_ObjRegular(pNodeOld->pCopy)->Level );
return pNodeOld->pCopy;

View File

@ -95,8 +95,8 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
continue;
}
// skip constant node, it has no cuts
if ( Abc_NodeIsConst(pObj) )
continue;
// if ( Abc_NodeIsConst(pObj) )
// continue;
Extra_ProgressBarUpdate( pProgress, i, NULL );
// compute the cuts to the internal node
Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
@ -107,7 +107,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
}
// add cuts due to choices
if ( Abc_NodeIsAigChoice(pObj) )
if ( Abc_AigNodeIsChoice(pObj) )
{
Vec_IntClear( vChoices );
for ( pNode = pObj; pNode; pNode = pNode->pData )
@ -171,8 +171,8 @@ void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p )
continue;
}
// skip constant node, it has no cuts
if ( Abc_NodeIsConst(pObj) )
continue;
// if ( Abc_NodeIsConst(pObj) )
// continue;
// compute the cuts to the internal node
Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
@ -218,7 +218,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
p = Cut_ManStart( pParams );
// set cuts for the constant node and the PIs
pObj = Abc_NtkConst1(pNtk);
pObj = Abc_AigConst1(pNtk);
if ( Abc_ObjFanoutNum(pObj) > 0 )
Cut_NodeSetTriv( p, pObj->Id );
Abc_NtkForEachPi( pNtk, pObj, i )
@ -247,7 +247,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
{
Abc_NodeGetCutsSeq( p, pObj, nIters==0 );
// add cuts due to choices
if ( Abc_NodeIsAigChoice(pObj) )
if ( Abc_AigNodeIsChoice(pObj) )
{
Vec_IntClear( vChoices );
for ( pNode = pObj; pNode; pNode = pNode->pData )

View File

@ -172,7 +172,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t *
int i, nNodesDsd;
// save the CI nodes in the DSD nodes
Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_NtkConst1(pNtk)->pCopy );
Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_AigConst1(pNtkNew) );
Abc_NtkForEachCi( pNtk, pNode, i )
{
pNodeDsd = Dsd_ManagerReadInput( pManDsd, i );
@ -191,7 +191,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t *
pDriver = Abc_ObjFanin0( pNode );
if ( !Abc_ObjIsNode(pDriver) )
continue;
if ( !Abc_NodeIsAigAnd(pDriver) )
if ( !Abc_AigNodeIsAnd(pDriver) )
continue;
pNodeDsd = Dsd_ManagerReadRoot( pManDsd, i );
pNodeNew = (Abc_Obj_t *)Dsd_NodeReadMark( Dsd_Regular(pNodeDsd) );
@ -419,14 +419,14 @@ void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager
pNodeC = Abc_ObjFanin( pNode, iVar );
// get the negative cofactor
pNode1 = Abc_NodeClone( pNode );
pNode1 = Abc_NtkCloneObj( pNode );
pNode1->pData = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(dd->vars[iVar]) ); Cudd_Ref( pNode1->pData );
Abc_NodeMinimumBase( pNode1 );
if ( Abc_NodeIsForDsd(pNode1) )
Vec_PtrPush( vNodes, pNode1 );
// get the positive cofactor
pNode2 = Abc_NodeClone( pNode );
pNode2 = Abc_NtkCloneObj( pNode );
pNode2->pData = Cudd_Cofactor( dd, pNode->pData, dd->vars[iVar] ); Cudd_Ref( pNode2->pData );
Abc_NodeMinimumBase( pNode2 );
if ( Abc_NodeIsForDsd(pNode2) )

View File

@ -52,12 +52,12 @@ void Abc_NtkEspresso( Abc_Ntk_t * pNtk, int fVerbose )
assert( Abc_NtkIsLogic(pNtk) );
// convert the network to have SOPs
if ( Abc_NtkHasMapping(pNtk) )
Abc_NtkUnmap(pNtk);
Abc_NtkMapToSop(pNtk);
else if ( Abc_NtkHasBdd(pNtk) )
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
printf( "Abc_NtkEspresso(): Converting to SOPs has failed.\n" );
return;
}
}

View File

@ -143,6 +143,7 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching,
// create PIs and remember them in the old nodes
Abc_NtkCleanCopy( pNtk );
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan);
Abc_NtkForEachCi( pNtk, pNode, i )
{
pNodeFpga = Fpga_ManReadInputs(pMan)[i];
@ -157,12 +158,6 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching,
Vec_PtrForEachEntry( vNodes, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// consider the case of a constant
if ( Abc_NodeIsConst(pNode) )
{
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan);
continue;
}
// add the node to the mapper
pNodeFpga = Fpga_NodeAnd( pMan,
Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
@ -173,7 +168,7 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching,
if ( pSwitching )
Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
// set up the choice node
if ( Abc_NodeIsAigChoice( pNode ) )
if ( Abc_AigNodeIsChoice( pNode ) )
for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
{
Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy );
@ -214,7 +209,7 @@ Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_NtkForEachCi( pNtk, pNode, i )
Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy );
// set the constant node
Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NtkConst1(pNtkNew) );
Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) );
// process the nodes in topological order
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )

View File

@ -113,7 +113,7 @@ void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExd
// map the constant node
Abc_NtkCleanCopy( pNtk );
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
// create PIs and remember them in the old nodes
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i);
@ -168,7 +168,7 @@ Fraig_Node_t * Abc_NtkToFraigExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtkMain, Abc
// strash the EXDC network
pNtkStrash = Abc_NtkStrash( pNtkExdc, 0, 0 );
Abc_NtkCleanCopy( pNtkStrash );
Abc_NtkConst1(pNtkStrash)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
Abc_AigConst1(pNtkStrash)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
// set the mapping of the PI nodes
ppNames = Abc_NtkCollectCioNames( pNtkMain, 0 );
Abc_NtkForEachCi( pNtkStrash, pObj, i )
@ -285,7 +285,7 @@ Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_NtkForEachCi( pNtk, pNode, i )
Fraig_NodeSetData1( Fraig_ManReadIthVar(pMan, i), (Fraig_Node_t *)pNode->pCopy );
// set the constant node
Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_NtkConst1(pNtkNew) );
Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_AigConst1(pNtkNew) );
// process the nodes in topological order
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
@ -384,7 +384,7 @@ Abc_Ntk_t * Abc_NtkFromFraig2( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
// map the nodes into their lowest level representives
tTable = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
pNode = Abc_NtkConst1(pNtk);
pNode = Abc_AigConst1(pNtk);
if ( !stmm_find_or_add( tTable, (char *)Fraig_Regular(pNode->pCopy), (char ***)&ppSlot ) )
*ppSlot = pNode;
Abc_NtkForEachCi( pNtk, pNode, i )
@ -607,7 +607,7 @@ Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
assert( nFanins == Abc_SopGetVarNum(pNode->pData) );
// check if it is a constant
if ( nFanins == 0 )
return Abc_ObjNotCond( Abc_NtkConst1(pNtkNew), Abc_SopIsConst0(pNode->pData) );
return Abc_ObjNotCond( Abc_AigConst1(pNtkNew), Abc_SopIsConst0(pNode->pData) );
if ( nFanins == 1 )
return Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_SopIsInv(pNode->pData) );
if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) )

View File

@ -53,22 +53,19 @@ static void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
{
assert( Abc_NtkIsLogic(pNtk) );
// convert nodes to SOPs
if ( Abc_NtkIsMappedLogic(pNtk) )
Abc_NtkUnmap(pNtk);
else if ( Abc_NtkIsBddLogic(pNtk) )
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return 0;
}
}
else
// if the network is already in the SOP form, it may come from BLIF file
// and it may not be SCC-free, in which case FXU will not work correctly
if ( Abc_NtkIsSopLogic(pNtk) )
{ // to make sure the SOPs are SCC-free
// Abc_NtkSopToBdd(pNtk);
// Abc_NtkBddToSop(pNtk);
}
// get the network in the SOP form
if ( !Abc_NtkLogicToSop(pNtk, 0) )
{
printf( "Abc_NtkFastExtract(): Converting to SOPs has failed.\n" );
return 0;
}
// check if the network meets the requirements
if ( !Abc_NtkFxuCheck(pNtk) )
{

View File

@ -77,7 +77,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
printf( "Abc_NtkIvyBefore(): Converting to SOPs has failed.\n" );
return NULL;
}
}
@ -329,7 +329,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
FREE( pInit );
printf( "Converting to SOPs has failed.\n" );
printf( "Abc_NtkIvy(): Converting to SOPs has failed.\n" );
return NULL;
}
}
@ -437,7 +437,7 @@ Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
// perform strashing
pNtk = Abc_NtkStartFrom( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG );
// transfer the pointers to the basic nodes
Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_NtkConst1(pNtk) );
Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_AigConst1(pNtk) );
Abc_NtkForEachCi( pNtkOld, pObj, i )
Ivy_ManPi(pMan, i)->TravId = Abc_EdgeFromNode( pObj->pCopy );
// rebuild the AIG
@ -494,7 +494,7 @@ Abc_Ntk_t * Abc_NtkFromAigSeq( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan, int fHaig
// perform strashing
pNtk = Abc_NtkStartFromNoLatches( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG );
// transfer the pointers to the basic nodes
Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_NtkConst1(pNtk) );
Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_AigConst1(pNtk) );
Abc_NtkForEachPi( pNtkOld, pObj, i )
Ivy_ManPi(pMan, i)->TravId = Abc_EdgeFromNode( pObj->pCopy );
// create latches of the new network
@ -583,10 +583,11 @@ Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld )
Ivy_Obj_t * pFanin;
int i;
// create the manager
assert( Abc_NtkHasSop(pNtkOld) || Abc_NtkHasAig(pNtkOld) );
assert( Abc_NtkHasSop(pNtkOld) || Abc_NtkIsStrash(pNtkOld) );
pMan = Ivy_ManStart();
// create the PIs
Abc_NtkConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
if ( Abc_NtkIsStrash(pNtkOld) )
Abc_AigConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
Abc_NtkForEachCi( pNtkOld, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Ivy_ObjCreatePi(pMan);
// perform the conversion of the internal nodes
@ -646,14 +647,13 @@ Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode )
int fUseFactor = 1;
char * pSop;
Ivy_Obj_t * pFanin0, * pFanin1;
extern int Abc_SopIsExorType( char * pSop );
assert( Abc_ObjIsNode(pNode) );
// consider the case when the graph is an AIG
if ( Abc_NtkIsStrash(pNode->pNtk) )
{
if ( Abc_NodeIsConst(pNode) )
if ( Abc_AigNodeIsConst(pNode) )
return Ivy_ManConst1(pMan);
pFanin0 = (Ivy_Obj_t *)Abc_ObjFanin0(pNode)->pCopy;
pFanin0 = Ivy_NotCond( pFanin0, Abc_ObjFaninC0(pNode) );

View File

@ -159,6 +159,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
// create PIs and remember them in the old nodes
Abc_NtkCleanCopy( pNtk );
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
Abc_NtkForEachCi( pNtk, pNode, i )
{
pNodeMap = Map_ManReadInputs(pMan)[i];
@ -173,12 +174,6 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
Vec_PtrForEachEntry( vNodes, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// consider the case of a constant
if ( Abc_NodeIsConst(pNode) )
{
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
continue;
}
// add the node to the mapper
pNodeMap = Map_NodeAnd( pMan,
Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
@ -189,7 +184,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
if ( pSwitching )
Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
// set up the choice node
if ( Abc_NodeIsAigChoice( pNode ) )
if ( Abc_AigNodeIsChoice( pNode ) )
for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
{
Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy );
@ -223,16 +218,12 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
Map_Node_t * pNodeMap;
Abc_Obj_t * pNode, * pNodeNew;
int i, nDupGates;
// create the new network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_MAP );
// make the mapper point to the new network
Map_ManCleanData( pMan );
Abc_NtkForEachCi( pNtk, pNode, i )
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
// set the constant node
Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NtkConst1(pNtkNew) );
// assign the mapping of the required phase to the POs
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
@ -266,6 +257,10 @@ Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int
{
Abc_Obj_t * pNodeNew, * pNodeInv;
// check the case of constant node
if ( Map_NodeIsConst(pNodeMap) )
return fPhase? Abc_NodeCreateConst1(pNtkNew) : Abc_NodeCreateConst0(pNtkNew);
// check if the phase is already implemented
pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
if ( pNodeNew )
@ -393,38 +388,6 @@ Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
}
/**Function*************************************************************
Synopsis [Unmaps the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkUnmap( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
char * pSop;
int i;
assert( Abc_NtkIsMappedLogic(pNtk) );
// update the functionality manager
assert( pNtk->pManFunc == Abc_FrameReadLibGen() );
pNtk->pManFunc = Extra_MmFlexStart();
pNtk->ntkFunc = ABC_FUNC_SOP;
// update the nodes
Abc_NtkForEachNode( pNtk, pNode, i )
{
pSop = Mio_GateReadSop(pNode->pData);
assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) );
pNode->pData = Abc_SopRegister( pNtk->pManFunc, pSop );
}
return 1;
}
@ -524,7 +487,7 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
pNtkNew = Abc_NtkRenode( pNtkNew2, 0, 20, 0, 0, 1, 0 );
if ( !Abc_NtkBddToSop( pNtkNew, 0 ) )
{
printf( "Converting to SOPs has failed.\n" );
printf( "Abc_NtkFromMapSuperChoice(): Converting to SOPs has failed.\n" );
return NULL;
}
@ -545,8 +508,8 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
}
Abc_NtkForEachNode( pNtk, pNode, i )
{
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy );
}
@ -556,8 +519,8 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
Abc_NodeSuperChoice( pNtkNew, pNode );
}
Extra_ProgressBarStop( pProgress );

152
src/base/abci/abcMini.c Normal file
View File

@ -0,0 +1,152 @@
/**CFile****************************************************************
FileName [abcMini.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Interface to the minimalistic AIG package.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcMini.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Aig_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtk );
static Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiniBalance( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkAig;
Aig_Man_t * pMan, * pTemp;
assert( Abc_NtkIsStrash(pNtk) );
// convert to the AIG manager
pMan = Abc_NtkToAig( pNtk );
if ( pMan == NULL )
return NULL;
if ( !Aig_ManCheck( pMan ) )
{
printf( "AIG check has failed.\n" );
Aig_ManStop( pMan );
return NULL;
}
// perform balance
Aig_ManPrintStats( pMan );
pMan = Aig_ManBalance( pTemp = pMan, 1 );
Aig_ManStop( pTemp );
Aig_ManPrintStats( pMan );
// convert from the AIG manager
pNtkAig = Abc_NtkFromAig( pNtk, pMan );
if ( pNtkAig == NULL )
return NULL;
Aig_ManStop( pMan );
// make sure everything is okay
if ( !Abc_NtkCheck( pNtkAig ) )
{
printf( "Abc_NtkStrash: The network check has failed.\n" );
Abc_NtkDelete( pNtkAig );
return NULL;
}
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Converts the network from the AIG manager into ABC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtk )
{
Aig_Man_t * pMan;
Abc_Obj_t * pObj;
int i;
// create the manager
pMan = Aig_ManStart();
// transfer the pointers to the basic nodes
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Aig_ManConst1(pMan);
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Aig_ObjCreatePi(pMan);
// perform the conversion of the internal nodes (assumes DFS ordering)
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Aig_And( pMan, (Aig_Obj_t *)Abc_ObjChild0Copy(pObj), (Aig_Obj_t *)Abc_ObjChild1Copy(pObj) );
// create the POs
Abc_NtkForEachCo( pNtk, pObj, i )
Aig_ObjCreatePo( pMan, (Aig_Obj_t *)Abc_ObjChild0Copy(pObj) );
Aig_ManCleanup( pMan );
return pMan;
}
/**Function*************************************************************
Synopsis [Converts the network from the AIG manager into ABC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtk, Aig_Man_t * pMan )
{
Vec_Ptr_t * vNodes;
Abc_Ntk_t * pNtkNew;
Aig_Obj_t * pObj;
int i;
// perform strashing
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
// transfer the pointers to the basic nodes
Aig_ManConst1(pMan)->pData = Abc_AigConst1(pNtkNew);
Aig_ManForEachPi( pMan, pObj, i )
pObj->pData = Abc_NtkCi(pNtkNew, i);
// rebuild the AIG
vNodes = Aig_ManDfs( pMan );
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->pData = Abc_AigAnd( pNtkNew->pManFunc, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj), (Abc_Obj_t *)Aig_ObjChild1Copy(pObj) );
Vec_PtrFree( vNodes );
// connect the PO nodes
Aig_ManForEachPo( pMan, pObj, i )
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkFromAig(): Network check has failed.\n" );
return pNtkNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -125,8 +125,8 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk
// clean the copy field in all objects
// Abc_NtkCleanCopy( pNtk1 );
// Abc_NtkCleanCopy( pNtk2 );
Abc_NtkConst1(pNtk1)->pCopy = Abc_NtkConst1(pNtkMiter);
Abc_NtkConst1(pNtk2)->pCopy = Abc_NtkConst1(pNtkMiter);
Abc_AigConst1(pNtk1)->pCopy = Abc_AigConst1(pNtkMiter);
Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtkMiter);
if ( fComb )
{
@ -216,11 +216,11 @@ void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * p
Abc_Obj_t * pNode;
int i;
// map the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkMiter);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkMiter);
// perform strashing
vNodes = Abc_NtkDfsNodes( pNtk, &pRoot, 1 );
Vec_PtrForEachEntry( vNodes, pNode, i )
if ( Abc_NodeIsAigAnd(pNode) )
if ( Abc_AigNodeIsAnd(pNode) )
pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
Vec_PtrFree( vNodes );
}
@ -372,12 +372,12 @@ Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues )
continue;
if ( Value == 0 )
{
Abc_NtkCi(pNtk, i)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) );
Abc_NtkCi(pNtk, i)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) );
continue;
}
if ( Value == 1 )
{
Abc_NtkCi(pNtk, i)->pCopy = Abc_NtkConst1(pNtkMiter);
Abc_NtkCi(pNtk, i)->pCopy = Abc_AigConst1(pNtkMiter);
continue;
}
assert( 0 );
@ -433,9 +433,9 @@ Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In
// perform strashing
Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 );
// set the first cofactor
Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) );
Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) );
if ( In2 >= 0 )
Abc_NtkCi(pNtk, In2)->pCopy = Abc_NtkConst1( pNtkMiter );
Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1(pNtkMiter);
// add the first cofactor
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
@ -443,9 +443,9 @@ Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In
pOutput1 = Abc_ObjFanin0(pRoot)->pCopy;
// set the second cofactor
Abc_NtkCi(pNtk, In1)->pCopy = Abc_NtkConst1( pNtkMiter );
Abc_NtkCi(pNtk, In1)->pCopy = Abc_AigConst1(pNtkMiter);
if ( In2 >= 0 )
Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) );
Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) );
// add the second cofactor
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
@ -497,7 +497,7 @@ Abc_Ntk_t * Abc_NtkMiterQuantify( Abc_Ntk_t * pNtk, int In, int fExist )
// perform strashing
Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 );
// set the first cofactor
Abc_NtkCi(pNtk, In)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) );
Abc_NtkCi(pNtk, In)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) );
// add the first cofactor
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
// save the output
@ -505,7 +505,7 @@ Abc_Ntk_t * Abc_NtkMiterQuantify( Abc_Ntk_t * pNtk, int In, int fExist )
pOutput1 = Abc_ObjNotCond( Abc_ObjFanin0(pRoot)->pCopy, Abc_ObjFaninC0(pRoot) );
// set the second cofactor
Abc_NtkCi(pNtk, In)->pCopy = Abc_NtkConst1( pNtkMiter );
Abc_NtkCi(pNtk, In)->pCopy = Abc_AigConst1(pNtkMiter);
// add the second cofactor
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
// save the output
@ -581,9 +581,9 @@ int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter )
Abc_NtkForEachPo( pMiter, pNodePo, i )
{
pChild = Abc_ObjChild0( pNodePo );
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) )
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) )
{
assert( Abc_ObjRegular(pChild) == Abc_NtkConst1(pMiter) );
assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter) );
if ( !Abc_ObjIsComplement(pChild) )
{
// if the miter is constant 1, return immediately
@ -617,7 +617,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
if ( Abc_NtkPoNum(pMiter) == 1 )
{
pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) );
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) )
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) )
{
if ( Abc_ObjIsComplement(pChild) )
printf( "Unsatisfiable.\n" );
@ -633,7 +633,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
{
pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) );
printf( "Output #%2d : ", i );
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) )
if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) )
{
if ( Abc_ObjIsComplement(pChild) )
printf( "Unsatisfiable.\n" );
@ -690,7 +690,7 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
Counter++;
}
else
pLatch->pCopy = Abc_ObjNotCond( Abc_NtkConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) );
pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) );
}
if ( Counter )
printf( "Warning: %d uninitialized latches are replaced by free PI variables.\n", Counter );
@ -756,7 +756,7 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame )
// create the prefix to be added to the node names
sprintf( Buffer, "_%02d", iFrame );
// map the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkFrames);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkFrames);
// add the new PI nodes
Abc_NtkForEachPi( pNtk, pNode, i )
Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer );
@ -829,7 +829,7 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram
Counter++;
}
else {
pLatch->pCopy = Abc_ObjNotCond( Abc_NtkConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) );
pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) );
}
if (addFrameMapping) addFrameMapping(pLatch->pCopy, pLatch, 0, arg);
@ -899,8 +899,8 @@ void Abc_NtkAddFrame2( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec
Abc_Obj_t * pConst1, * pConst1New;
int i;
// get the constant nodes
pConst1 = Abc_NtkConst1( pNtk );
pConst1New = Abc_NtkConst1( pNtkFrames );
pConst1 = Abc_AigConst1(pNtk);
pConst1New = Abc_AigConst1(pNtkFrames);
// create the prefix to be added to the node names
sprintf( Buffer, "_%02d", iFrame );
// add the new PI nodes
@ -1037,7 +1037,7 @@ int Abc_NtkOrPos( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkLatchNum(pNtk) == 0 );
// OR the POs
pMiter = Abc_ObjNot( Abc_NtkConst1(pNtk) );
pMiter = Abc_ObjNot( Abc_AigConst1(pNtk) );
Abc_NtkForEachPo( pNtk, pNode, i )
pMiter = Abc_AigOr( pNtk->pManFunc, pMiter, Abc_ObjChild0(pNode) );
// remove the POs and their names

View File

@ -1,391 +0,0 @@
/**CFile****************************************************************
FileName [aigNewAig.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Strashing of the current network.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigNewAig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "extra.h"
#include "dec.h"
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan );
static Aig_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld );
static void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Aig_Man_t * pMan );
static Aig_Node_t * Abc_NodeStrashAig( Aig_Man_t * pMan, Abc_Obj_t * pNode );
static Aig_Node_t * Abc_NodeStrashAigSopAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop );
static Aig_Node_t * Abc_NodeStrashAigExorAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop );
static Aig_Node_t * Abc_NodeStrashAigFactorAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop );
extern char * Mio_GateReadSop( void * pGate );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk )
{
Aig_Man_t * pMan;
Abc_Ntk_t * pNtkAig;
// Aig_ProofType_t RetValue;
int fCleanup = 1;
int nNodes;
extern void Aig_MffcTest( Aig_Man_t * pMan );
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return;
}
}
// print warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
// convert to the AIG manager
pMan = Abc_NtkToAig( pNtk );
Aig_MffcTest( pMan );
/*
// execute a command in the AIG manager
RetValue = Aig_FraigProve( pMan );
if ( RetValue == AIG_PROOF_SAT )
printf( "Satisfiable.\n" );
else if ( RetValue == AIG_PROOF_UNSAT )
printf( "Unsatisfiable.\n" );
else if ( RetValue == AIG_PROOF_TIMEOUT )
printf( "Undecided.\n" );
else
assert( 0 );
*/
// convert from the AIG manager
pNtkAig = Abc_NtkFromAig( pNtk, pMan );
Aig_ManStop( pMan );
// report the cleanup results
if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
// duplicate EXDC
if ( pNtk->pExdc )
pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
// make sure everything is okay
if ( !Abc_NtkCheck( pNtkAig ) )
{
printf( "Abc_NtkStrash: The network check has failed.\n" );
Abc_NtkDelete( pNtkAig );
return NULL;
}
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Converts the network from the AIG manager into ABC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
{
Abc_Ntk_t * pNtk;
Abc_Obj_t * pObj, * pObjNew, * pFaninNew, * pFaninNew0, * pFaninNew1;
Aig_Node_t * pAnd;
int i;
// perform strashing
pNtk = Abc_NtkStartFrom( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG );
// transfer the pointers to the basic nodes
Aig_ManConst1(pMan)->Data = Abc_NtkConst1(pNtk)->Id;
Abc_NtkForEachCi( pNtkOld, pObj, i )
Aig_ManPi(pMan, i)->Data = pObj->pCopy->Id;
// rebuild the AIG
Aig_ManForEachAnd( pMan, pAnd, i )
{
// add the first fanins
pFaninNew0 = Abc_NtkObj( pNtk, Aig_NodeFanin0(pAnd)->Data );
pFaninNew0 = Abc_ObjNotCond( pFaninNew0, Aig_NodeFaninC0(pAnd) );
// add the first second
pFaninNew1 = Abc_NtkObj( pNtk, Aig_NodeFanin1(pAnd)->Data );
pFaninNew1 = Abc_ObjNotCond( pFaninNew1, Aig_NodeFaninC1(pAnd) );
// create the new node
pObjNew = Abc_AigAnd( pNtk->pManFunc, pFaninNew0, pFaninNew1 );
pAnd->Data = pObjNew->Id;
}
// connect the PO nodes
Abc_NtkForEachCo( pNtkOld, pObj, i )
{
pAnd = Aig_ManPo( pMan, i );
pFaninNew = Abc_NtkObj( pNtk, Aig_NodeFanin0(pAnd)->Data );
pFaninNew = Abc_ObjNotCond( pFaninNew, Aig_NodeFaninC0(pAnd) );
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
}
return pNtk;
}
/**Function*************************************************************
Synopsis [Converts the network from the AIG manager into ABC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld )
{
Aig_Param_t Params;
Aig_Man_t * pMan;
Abc_Obj_t * pObj;
Aig_Node_t * pFanin;
int i;
// create the manager
Aig_ManSetDefaultParams( &Params );
pMan = Aig_ManStart( &Params );
// create the PIs
Abc_NtkConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Aig_ManConst1(pMan);
Abc_NtkForEachCi( pNtkOld, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Aig_NodeCreatePi(pMan);
Abc_NtkForEachCo( pNtkOld, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Aig_NodeCreatePo(pMan);
// perform the conversion of the internal nodes
Abc_NtkStrashPerformAig( pNtkOld, pMan );
// create the POs
Abc_NtkForEachCo( pNtkOld, pObj, i )
{
pFanin = (Aig_Node_t *)Abc_ObjFanin0(pObj)->pCopy;
pFanin = Aig_NotCond( pFanin, Abc_ObjFaninC0(pObj) );
Aig_NodeConnectPo( pMan, (Aig_Node_t *)pObj->pCopy, pFanin );
}
return pMan;
}
/**Function*************************************************************
Synopsis [Prepares the network for strashing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Aig_Man_t * pMan )
{
// ProgressBar * pProgress;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode;
int i;
vNodes = Abc_NtkDfs( pNtk, 0 );
// pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
// Extra_ProgressBarUpdate( pProgress, i, NULL );
pNode->pCopy = (Abc_Obj_t *)Abc_NodeStrashAig( pMan, pNode );
}
// Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis [Strashes one logic node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Abc_NodeStrashAig( Aig_Man_t * pMan, Abc_Obj_t * pNode )
{
int fUseFactor = 1;
char * pSop;
Aig_Node_t * pFanin0, * pFanin1;
extern int Abc_SopIsExorType( char * pSop );
assert( Abc_ObjIsNode(pNode) );
// consider the case when the graph is an AIG
if ( Abc_NtkIsStrash(pNode->pNtk) )
{
if ( Abc_NodeIsConst(pNode) )
return Aig_ManConst1(pMan);
pFanin0 = (Aig_Node_t *)Abc_ObjFanin0(pNode)->pCopy;
pFanin0 = Aig_NotCond( pFanin0, Abc_ObjFaninC0(pNode) );
pFanin1 = (Aig_Node_t *)Abc_ObjFanin1(pNode)->pCopy;
pFanin1 = Aig_NotCond( pFanin1, Abc_ObjFaninC1(pNode) );
return Aig_And( pMan, pFanin0, pFanin1 );
}
// get the SOP of the node
if ( Abc_NtkHasMapping(pNode->pNtk) )
pSop = Mio_GateReadSop(pNode->pData);
else
pSop = pNode->pData;
// consider the constant node
if ( Abc_NodeIsConst(pNode) )
return Aig_NotCond( Aig_ManConst1(pMan), Abc_SopIsConst0(pSop) );
// consider the special case of EXOR function
if ( Abc_SopIsExorType(pSop) )
return Abc_NodeStrashAigExorAig( pMan, pNode, pSop );
// decide when to use factoring
if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
return Abc_NodeStrashAigFactorAig( pMan, pNode, pSop );
return Abc_NodeStrashAigSopAig( pMan, pNode, pSop );
}
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Abc_NodeStrashAigSopAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop )
{
Abc_Obj_t * pFanin;
Aig_Node_t * pAnd, * pSum;
char * pCube;
int i, nFanins;
// get the number of node's fanins
nFanins = Abc_ObjFaninNum( pNode );
assert( nFanins == Abc_SopGetVarNum(pSop) );
// go through the cubes of the node's SOP
pSum = Aig_Not( Aig_ManConst1(pMan) );
Abc_SopForEachCube( pSop, nFanins, pCube )
{
// create the AND of literals
pAnd = Aig_ManConst1(pMan);
Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net
{
if ( pCube[i] == '1' )
pAnd = Aig_And( pMan, pAnd, (Aig_Node_t *)pFanin->pCopy );
else if ( pCube[i] == '0' )
pAnd = Aig_And( pMan, pAnd, Aig_Not((Aig_Node_t *)pFanin->pCopy) );
}
// add to the sum of cubes
pSum = Aig_Or( pMan, pSum, pAnd );
}
// decide whether to complement the result
if ( Abc_SopIsComplement(pSop) )
pSum = Aig_Not(pSum);
return pSum;
}
/**Function*************************************************************
Synopsis [Strashed n-input XOR function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Abc_NodeStrashAigExorAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop )
{
Abc_Obj_t * pFanin;
Aig_Node_t * pSum;
int i, nFanins;
// get the number of node's fanins
nFanins = Abc_ObjFaninNum( pNode );
assert( nFanins == Abc_SopGetVarNum(pSop) );
// go through the cubes of the node's SOP
pSum = Aig_Not( Aig_ManConst1(pMan) );
for ( i = 0; i < nFanins; i++ )
{
pFanin = Abc_ObjFanin( pNode, i );
pSum = Aig_Xor( pMan, pSum, (Aig_Node_t *)pFanin->pCopy );
}
if ( Abc_SopIsComplement(pSop) )
pSum = Aig_Not(pSum);
return pSum;
}
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Abc_NodeStrashAigFactorAig( Aig_Man_t * pMan, Abc_Obj_t * pRoot, char * pSop )
{
Dec_Graph_t * pFForm;
Dec_Node_t * pNode;
Aig_Node_t * pAnd;
int i;
extern Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph );
// perform factoring
pFForm = Dec_Factor( pSop );
// collect the fanins
Dec_GraphForEachLeaf( pFForm, pNode, i )
pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy;
// perform strashing
pAnd = Dec_GraphToNetworkAig( pMan, pFForm );
Dec_GraphFree( pFForm );
return pAnd;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -189,7 +189,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew )
// create the table mapping BDD nodes into the ABC nodes
tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash );
// add the constant and the elementary vars
st_insert( tBdd2Node, (char *)b1, (char *)Abc_NtkConst1(pNtkNew) );
st_insert( tBdd2Node, (char *)b1, (char *)Abc_AigConst1(pNtkNew) );
Abc_ObjForEachFanin( pNodeOld, pFaninOld, i )
st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy );
// create the new nodes recursively
@ -271,7 +271,7 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly
Cudd_Ref( dd->vars[i] );
}
// assign the constant node BDD
pNode = Abc_NtkConst1( pNtk );
pNode = Abc_AigConst1(pNtk);
if ( Abc_ObjFanoutNum(pNode) > 0 )
{
pNode->pCopy = (Abc_Obj_t *)dd->one;

View File

@ -68,7 +68,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
fprintf( pFile, " net = %5d", Abc_NtkNetNum(pNtk) );
fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
}
else if ( Abc_NtkHasAig(pNtk) )
else if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) )
{
fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
if ( Num = Abc_NtkGetChoiceNum(pNtk) )
@ -83,7 +83,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
else
fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
if ( Abc_NtkHasSop(pNtk) )
if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) )
{
}
else if ( Abc_NtkHasSop(pNtk) )
{
fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) );
@ -91,6 +94,8 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
if ( fFactored )
fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) );
}
else if ( Abc_NtkHasAig(pNtk) )
fprintf( pFile, " aig = %5d", Abc_NtkGetAigNodeNum(pNtk) );
else if ( Abc_NtkHasBdd(pNtk) )
fprintf( pFile, " bdd = %5d", Abc_NtkGetBddNodeNum(pNtk) );
else if ( Abc_NtkHasMapping(pNtk) )
@ -98,7 +103,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
fprintf( pFile, " area = %5.2f", Abc_NtkGetMappedArea(pNtk) );
fprintf( pFile, " delay = %5.2f", Abc_NtkDelayTrace(pNtk) );
}
else if ( !Abc_NtkHasAig(pNtk) )
else if ( !Abc_NtkHasBlackbox(pNtk) )
{
assert( 0 );
}
@ -661,12 +666,15 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary )
return;
}
if ( Abc_NtkIsAigLogic(pNtk) )
return;
// transform logic functions from BDD to SOP
if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
printf( "Abc_NtkPrintGates(): Converting to SOPs has failed.\n" );
return;
}
}
@ -785,6 +793,40 @@ void Abc_NtkPrintStrSupports( Abc_Ntk_t * pNtk )
}
}
/**Function*************************************************************
Synopsis [Prints information about the clock skew schedule.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll ) {
Abc_Obj_t * pObj;
int i;
int nNonZero = 0;
float skew, sum = 0.0, avg;
if (fPrintAll) fprintf( pFile, "Full Clock Skew Schedule:\n\tGlobal Skew = %.2f\n", pNtk->globalSkew );
Abc_NtkForEachLatch( pNtk, pObj, i ) {
skew = Abc_NtkGetLatSkew( pNtk, i );
if ( skew != 0.0 ) {
nNonZero++;
sum += ABS( skew );
}
if (fPrintAll) fprintf( pFile, "\tLatch %d (Id = %d) \t Endpoint Skew = %.2f\n", i, pObj->Id, skew);
}
avg = sum / Abc_NtkLatchNum( pNtk );
fprintf( pFile, "Endpoint Skews : Total |Skew| = %.2f\t Avg |Skew| = %.2f\t Non-Zero Skews = %d\n",
sum, avg, nNonZero );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -109,8 +109,8 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
// skip persistant nodes
if ( Abc_NodeIsPersistant(pNode) )
continue;

View File

@ -124,7 +124,7 @@ void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
int i;
// set the constant node
pConst1 = Abc_NtkConst1(pNtk);
pConst1 = Abc_AigConst1(pNtk);
if ( Abc_ObjFanoutNum(pConst1) > 0 )
{
pNodeNew = Abc_NtkCreateNode( pNtkNew );
@ -173,7 +173,7 @@ Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld )
if ( pNodeOld->pCopy )
return pNodeOld->pCopy;
assert( Abc_ObjIsNode(pNodeOld) );
assert( !Abc_NodeIsConst(pNodeOld) );
assert( !Abc_AigNodeIsConst(pNodeOld) );
assert( pNodeOld->fMarkA );
//printf( "%d ", Abc_NodeMffcSizeSupp(pNodeOld) );
@ -214,7 +214,7 @@ DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t
Abc_Obj_t * pFaninOld;
DdNode * bFunc;
int i;
assert( !Abc_NodeIsConst(pNodeOld) );
assert( !Abc_AigNodeIsConst(pNodeOld) );
assert( Abc_ObjIsNode(pNodeOld) );
// set the elementary BDD variables for the input nodes
for ( i = 0; i < vFaninsOld->nSize; i++ )
@ -389,8 +389,8 @@ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax )
Abc_NtkForEachNode( pNtk, pNode, i )
{
// skip PI/PO nodes
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
nFanouts = Abc_ObjFanoutNum(pNode);
nConeSize = Abc_NodeMffcSize(pNode);
@ -406,8 +406,8 @@ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax )
Abc_NtkForEachNode( pNtk, pNode, i )
{
// skip PI/PO nodes
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
if ( pNode->fMarkA == 0 )
continue;
// continue cutting branches until it meets the fanin limit
@ -420,8 +420,8 @@ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax )
Abc_NtkForEachNode( pNtk, pNode, i )
{
// skip PI/PO nodes
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
if ( pNode->fMarkA == 0 )
continue;
Abc_NtkRenodeCone( pNode, vCone );
@ -455,8 +455,8 @@ void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pNode, i )
{
// skip PI/PO nodes
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
if ( Abc_ObjFanoutNum(pNode) > 1 )
pNode->fMarkA = 1;
@ -487,8 +487,8 @@ void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pNode, i )
{
// skip PI/PO nodes
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
if ( Abc_NodeIsMuxType(pNode) &&
Abc_ObjFanin0(pNode)->fMarkA == 0 &&
Abc_ObjFanin1(pNode)->fMarkA == 0 )
@ -521,8 +521,8 @@ void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk, int nThresh )
Abc_NtkForEachNode( pNtk, pNode, i )
{
// skip PI/PO nodes
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
// if ( Abc_ObjFanoutNum(pNode) > 1 )
// pNode->fMarkA = 1;

View File

@ -132,8 +132,8 @@ pManRst->timeCut += clock() - clk;
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
// skip persistant nodes
if ( Abc_NodeIsPersistant(pNode) )
continue;

View File

@ -158,8 +158,8 @@ int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, bool fUpd
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
// skip persistant nodes
if ( Abc_NodeIsPersistant(pNode) )
continue;

View File

@ -86,8 +86,8 @@ Rwr_ManAddTimeCuts( pManRwr, clock() - clk );
if ( i >= nNodes )
break;
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
// skip persistant nodes
if ( Abc_NodeIsPersistant(pNode) )
continue;

View File

@ -120,8 +120,8 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa
if ( i >= nNodes )
break;
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
// skip persistant nodes
if ( Abc_NodeIsPersistant(pNode) )
continue;
@ -680,8 +680,7 @@ Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vC
// duplicate the name and the spec
pNtkNew->pName = Extra_UtilStrsav( "temp" );
// map the constant nodes
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// create and map the PIs
Vec_PtrForEachEntry( vLeaves, pObj, i )
pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
@ -728,7 +727,7 @@ void Abc_NtkRRSimulateStart( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
unsigned uData, uData0, uData1;
int i;
Abc_NtkConst1(pNtk)->pData = (void *)~((unsigned)0);
Abc_AigConst1(pNtk)->pData = (void *)~((unsigned)0);
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pData = (void *)SIM_RANDOM_UNSIGNED;
Abc_NtkForEachNode( pNtk, pObj, i )
@ -801,7 +800,7 @@ Vec_Str_t * Abc_NtkRRSimulate( Abc_Ntk_t * pNtk )
}
// simulate patters and store them in copy
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)~((unsigned)0);
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)~((unsigned)0);
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)SIM_RANDOM_UNSIGNED;
Abc_NtkForEachNode( pNtk, pObj, i )

View File

@ -452,7 +452,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
// vCircuit = Vec_VecStart( 184 );
// add the clause for the constant node
pNode = Abc_NtkConst1(pNtk);
pNode = Abc_AigConst1(pNtk);
pNode->fMarkA = 1;
pNode->pCopy = (Abc_Obj_t *)vNodes->nSize;
Vec_PtrPush( vNodes, pNode );
@ -488,7 +488,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
Vec_PtrForEachEntry( vNodes, pNode, i )
{
assert( !Abc_ObjIsComplement(pNode) );
if ( !Abc_NodeIsAigAnd(pNode) )
if ( !Abc_AigNodeIsAnd(pNode) )
continue;
//printf( "%d ", pNode->Id );

View File

@ -26,13 +26,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// static functions
static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fAllNodes );
static Abc_Obj_t * Abc_NodeStrashSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop );
static Abc_Obj_t * Abc_NodeStrashExor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop );
static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop );
extern char * Mio_GateReadSop( void * pGate );
static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@ -40,10 +34,57 @@ extern char * Mio_GateReadSop( void * pGate );
/**Function*************************************************************
Synopsis [Creates the strashed AIG network.]
Synopsis [Reapplies structural hashing to the AIG.]
Description [Converts the logic network or the AIG into a
structurally hashed AIG.]
Description [Because of the structural hashing, this procedure should not
change the number of nodes. It is useful to detect the bugs in the original AIG.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkRestrash( Abc_Ntk_t * pNtk, bool fCleanup )
{
Abc_Ntk_t * pNtkAig;
Abc_Obj_t * pObj;
int i, nNodes;
assert( Abc_NtkIsStrash(pNtk) );
// print warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" );
// start the new network (constants and CIs are already mappined after this step
pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
// restrash the nodes (assuming a topological order of the old network)
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = Abc_AigAnd( pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
// finalize the network
Abc_NtkFinalize( pNtk, pNtkAig );
// print warning about self-feed latches
// if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
// printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
// perform cleanup if requested
if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
printf( "Abc_NtkRestrash(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes );
// duplicate EXDC
if ( pNtk->pExdc )
pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
// make sure everything is okay
if ( !Abc_NtkCheck( pNtkAig ) )
{
printf( "Abc_NtkStrash: The network check has failed.\n" );
Abc_NtkDelete( pNtkAig );
return NULL;
}
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Transforms logic network into structurally hashed AIG.]
Description []
SideEffects []
@ -54,33 +95,28 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
{
Abc_Ntk_t * pNtkAig;
int nNodes;
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
// consider the special case when the network is already structurally hashed
if ( Abc_NtkIsStrash(pNtk) )
return Abc_NtkRestrash( pNtk, fCleanup );
// convert the node representation in the logic network to the AIG form
if ( !Abc_NtkLogicToAig(pNtk) )
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return NULL;
}
printf( "Converting to AIGs has failed.\n" );
return NULL;
}
// print warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
// perform strashing
Abc_NtkCleanCopy( pNtk );
pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = NULL;
Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes );
Abc_NtkFinalize( pNtk, pNtkAig );
// print warning about self-feed latches
// if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
// printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
{
// perform cleanup if requested
nNodes = fCleanup? Abc_AigCleanup(pNtkAig->pManFunc) : 0;
// if ( nNodes )
// printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
}
// duplicate EXDC
if ( pNtk->pExdc )
pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
@ -115,13 +151,10 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
// the first network should be an AIG
assert( Abc_NtkIsStrash(pNtk1) );
assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) );
if ( Abc_NtkIsBddLogic(pNtk2) )
if ( Abc_NtkIsLogic(pNtk2) && !Abc_NtkLogicToAig(pNtk2) )
{
if ( !Abc_NtkBddToSop(pNtk2, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return 0;
}
printf( "Converting to AIGs has failed.\n" );
return 0;
}
// check that the networks have the same PIs
// reorder PIs of pNtk2 according to pNtk1
@ -132,7 +165,11 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
Abc_NtkForEachCi( pNtk2, pObj, i )
pObj->pCopy = Abc_NtkCi(pNtk1, i);
// add pNtk2 to pNtk1 while strashing
Abc_NtkStrashPerform( pNtk2, pNtk1, 1 );
if ( Abc_NtkIsLogic(pNtk2) )
Abc_NtkStrashPerform( pNtk2, pNtk1, 1 );
else
Abc_NtkForEachNode( pNtk2, pObj, i )
pObj->pCopy = Abc_AigAnd( pNtk1->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtk1 ) )
{
@ -142,7 +179,6 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
return 1;
}
/**Function*************************************************************
Synopsis [Prepares the network for strashing.]
@ -154,186 +190,89 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
SeeAlso []
***********************************************************************/
void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes )
void Abc_NtkStrashPerform( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew, bool fAllNodes )
{
ProgressBar * pProgress;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pNodeNew, * pObj;
Abc_Obj_t * pNodeOld;
int i;
// perform strashing
vNodes = Abc_NtkDfs( pNtk, fAllNodes );
assert( Abc_NtkIsLogic(pNtkOld) );
assert( Abc_NtkIsStrash(pNtkNew) );
vNodes = Abc_NtkDfs( pNtkOld, fAllNodes );
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
Vec_PtrForEachEntry( vNodes, pNode, i )
Vec_PtrForEachEntry( vNodes, pNodeOld, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// get the node
assert( Abc_ObjIsNode(pNode) );
// strash the node
pNodeNew = Abc_NodeStrash( pNtkNew, pNode );
// get the old object
pObj = Abc_ObjFanout0Ntk( pNode );
// make sure the node is not yet strashed
assert( pObj->pCopy == NULL );
// mark the old object with the new AIG node
pObj->pCopy = pNodeNew;
Abc_HManAddProto( pObj->pCopy, pObj );
pNodeOld->pCopy = Abc_NodeStrash( pNtkNew, pNodeOld );
}
Vec_PtrFree( vNodes );
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis [Transfers the AIG from one manager into another.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeStrash_rec( Abc_Aig_t * pMan, Aig_Obj_t * pObj )
{
assert( !Aig_IsComplement(pObj) );
if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
return;
Abc_NodeStrash_rec( pMan, Aig_ObjFanin0(pObj) );
Abc_NodeStrash_rec( pMan, Aig_ObjFanin1(pObj) );
pObj->pData = Abc_AigAnd( pMan, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj), (Abc_Obj_t *)Aig_ObjChild1Copy(pObj) );
assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
Aig_ObjSetMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Strashes one logic node.]
Description []
Description [Assume the network is in the AIG form]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld )
{
int fUseFactor = 1;
char * pSop;
extern int Abc_SopIsExorType( char * pSop );
assert( Abc_ObjIsNode(pNode) );
// consider the case when the graph is an AIG
if ( Abc_NtkIsStrash(pNode->pNtk) )
{
if ( Abc_NodeIsConst(pNode) )
return Abc_NtkConst1(pNtkNew);
return Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
}
// get the SOP of the node
if ( Abc_NtkHasMapping(pNode->pNtk) )
pSop = Mio_GateReadSop(pNode->pData);
else
pSop = pNode->pData;
// consider the constant node
if ( Abc_NodeIsConst(pNode) )
return Abc_ObjNotCond( Abc_NtkConst1(pNtkNew), Abc_SopIsConst0(pSop) );
// consider the special case of EXOR function
if ( Abc_SopIsExorType(pSop) )
return Abc_NodeStrashExor( pNtkNew, pNode, pSop );
// decide when to use factoring
if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
return Abc_NodeStrashFactor( pNtkNew, pNode, pSop );
return Abc_NodeStrashSop( pNtkNew, pNode, pSop );
}
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop )
{
Abc_Aig_t * pMan = pNtkNew->pManFunc;
Abc_Obj_t * pFanin, * pAnd, * pSum;
char * pCube;
int i, nFanins;
// get the number of node's fanins
nFanins = Abc_ObjFaninNum( pNode );
assert( nFanins == Abc_SopGetVarNum(pSop) );
// go through the cubes of the node's SOP
pSum = Abc_ObjNot( Abc_NtkConst1(pNtkNew) );
Abc_SopForEachCube( pSop, nFanins, pCube )
{
// create the AND of literals
pAnd = Abc_NtkConst1(pNtkNew);
Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net
{
if ( pCube[i] == '1' )
pAnd = Abc_AigAnd( pMan, pAnd, pFanin->pCopy );
else if ( pCube[i] == '0' )
pAnd = Abc_AigAnd( pMan, pAnd, Abc_ObjNot(pFanin->pCopy) );
}
// add to the sum of cubes
pSum = Abc_AigOr( pMan, pSum, pAnd );
}
// decide whether to complement the result
if ( Abc_SopIsComplement(pSop) )
pSum = Abc_ObjNot(pSum);
return pSum;
}
/**Function*************************************************************
Synopsis [Strashed n-input XOR function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashExor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop )
{
Abc_Aig_t * pMan = pNtkNew->pManFunc;
Abc_Obj_t * pFanin, * pSum;
int i, nFanins;
// get the number of node's fanins
nFanins = Abc_ObjFaninNum( pNode );
assert( nFanins == Abc_SopGetVarNum(pSop) );
// go through the cubes of the node's SOP
pSum = Abc_ObjNot( Abc_NtkConst1(pNtkNew) );
for ( i = 0; i < nFanins; i++ )
{
pFanin = Abc_ObjFanin( pNode, i );
pSum = Abc_AigXor( pMan, pSum, pFanin->pCopy );
}
if ( Abc_SopIsComplement(pSop) )
pSum = Abc_ObjNot(pSum);
return pSum;
}
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeStrashFactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pRoot, char * pSop )
{
Dec_Graph_t * pFForm;
Dec_Node_t * pNode;
Abc_Obj_t * pAnd;
Aig_Man_t * pMan;
Aig_Obj_t * pRoot;
Abc_Obj_t * pFanin;
int i;
// perform factoring
pFForm = Dec_Factor( pSop );
// collect the fanins
Dec_GraphForEachLeaf( pFForm, pNode, i )
pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy;
// perform strashing
pAnd = Dec_GraphToNetwork( pNtkNew, pFForm );
Dec_GraphFree( pFForm );
return pAnd;
assert( Abc_ObjIsNode(pNodeOld) );
assert( Abc_NtkIsAigLogic(pNodeOld->pNtk) );
// get the local AIG manager and the local root node
pMan = pNodeOld->pNtk->pManFunc;
pRoot = pNodeOld->pData;
// check the constant case
if ( Abc_NodeIsConst(pNodeOld) )
return Abc_ObjNotCond( Abc_AigConst1(pNtkNew), Aig_IsComplement(pRoot) );
// set elementary variables
Abc_ObjForEachFanin( pNodeOld, pFanin, i )
Aig_IthVar(pMan, i)->pData = pFanin->pCopy;
// strash the AIG of this node
Abc_NodeStrash_rec( pNtkNew->pManFunc, Aig_Regular(pRoot) );
Aig_ConeUnmark_rec( Aig_Regular(pRoot) );
// return the final node
return Abc_ObjNotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) );
}
/**Function*************************************************************
Synopsis [Copies the topmost levels of the network.]
@ -380,7 +319,7 @@ Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels )
// start the network
pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG );
pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// create PIs below the cut and nodes above the cut
Abc_NtkCleanCopy( pNtk );
pObjNew = Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(Abc_NtkPo(pNtk, 0)), LevelCut );

View File

@ -448,7 +448,7 @@ int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose )
{
Vec_Ptr_t * vNodes;
int Counter;
assert( !Abc_NtkHasAig(pNtk) );
assert( Abc_NtkIsLogic(pNtk) );
// mark the nodes reachable from the POs
vNodes = Abc_NtkDfs( pNtk, 0 );
Counter = Abc_NtkReduceNodes( pNtk, vNodes );
@ -473,7 +473,7 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
{
Abc_Obj_t * pNode;
int i, Counter;
assert( !Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkIsLogic(pNtk) );
// mark the nodes reachable from the POs
for ( i = 0; i < vNodes->nSize; i++ )
{
@ -481,9 +481,6 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
assert( Abc_ObjIsNode(pNode) );
pNode->fMarkA = 1;
}
// if it is an AIG, also mark the constant 1 node
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->fMarkA = 1;
// remove the non-marked nodes
Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i )

View File

@ -37,9 +37,9 @@ struct Abc_ManTime_t_
// static functions
static Abc_ManTime_t * Abc_ManTimeStart();
static void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive );
static void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk );
void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk );
static void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode );
void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode );
// accessing the arrival and required times of a node
static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; }
@ -595,13 +595,12 @@ void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode )
// start the arrival time of the node
pTimeOut = Abc_NodeArrival(pNode);
pTimeOut->Rise = pTimeOut->Fall = 0;
pTimeOut->Rise = pTimeOut->Fall = -ABC_INFINITY;
// go through the pins of the gate
pPin = Mio_GateReadPins(pNode->pData);
Abc_ObjForEachFanin( pNode, pFanin, i )
{
pTimeIn = Abc_NodeArrival(pFanin);
assert( pTimeIn->Worst != -ABC_INFINITY );
// get the interesting parameters of this pin
PinPhase = Mio_PinReadPhase(pPin);
tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin );
@ -647,7 +646,7 @@ void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk )
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj, * pFanout;
int i, k, nLevelsCur;
// assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkIsStrash(pNtk) );
// remember the maximum number of direct levels
// pNtk->LevelMax = Abc_AigGetLevelNum(pNtk);
pNtk->LevelMax = Abc_NtkGetLevelNum(pNtk);

View File

@ -1,804 +0,0 @@
/**CFile****************************************************************
FileName [abcHistory.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: abcHistory.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define ABC_SIM_VARS 16 // the max number of variables in the cone
#define ABC_SIM_OBJS 200 // the max number of objects in the cone
typedef struct Abc_HMan_t_ Abc_HMan_t;
typedef struct Abc_HObj_t_ Abc_HObj_t;
typedef struct Abc_HNum_t_ Abc_HNum_t;
struct Abc_HNum_t_
{
unsigned fCompl : 1; // set to 1 if the node is complemented
unsigned NtkId : 6; // the network ID
unsigned ObjId : 24; // the node ID
};
struct Abc_HObj_t_
{
// object info
unsigned fProof : 1; // set to 1 if the node is proved
unsigned fPhase : 1; // set to 1 if the node's phase differs from Old
unsigned fPi : 1; // the node is a PI
unsigned fPo : 1; // the node is a PO
unsigned fConst : 1; // the node is a constant
unsigned fVisited: 1; // the flag shows if the node is visited
unsigned NtkId : 10; // the network ID
unsigned Num : 16; // a temporary number
// history record
Abc_HNum_t Fan0; // immediate fanin
Abc_HNum_t Fan1; // immediate fanin
Abc_HNum_t Proto; // old node if present
// Abc_HNum_t Equ; // equiv node if present
};
struct Abc_HMan_t_
{
// storage for history information
Vec_Vec_t * vNtks; // the history nodes belonging to each network
Vec_Int_t * vProof; // flags showing if the network is proved
// storage for simulation info
int nVarsMax; // the max number of cone leaves
int nObjsMax; // the max number of cone nodes
Vec_Ptr_t * vObjs; // the cone nodes
int nBits; // the number of simulation bits
int nWords; // the number of unsigneds for siminfo
int nWordsCur; // the current number of words
Vec_Ptr_t * vSims; // simulation info
unsigned * pInfo; // pointer to simulation info
// other info
Vec_Ptr_t * vCone0;
Vec_Ptr_t * vCone1;
// memory manager
Extra_MmFixed_t* pMmObj; // memory manager for objects
};
static Abc_HMan_t * s_pHMan = NULL;
static inline int Abc_HObjProof( Abc_HObj_t * p ) { return p->fProof; }
static inline int Abc_HObjPhase( Abc_HObj_t * p ) { return p->fPhase; }
static inline int Abc_HObjPi ( Abc_HObj_t * p ) { return p->fPi; }
static inline int Abc_HObjPo ( Abc_HObj_t * p ) { return p->fPo; }
static inline int Abc_HObjConst( Abc_HObj_t * p ) { return p->fConst; }
static inline int Abc_HObjNtkId( Abc_HObj_t * p ) { return p->NtkId; }
static inline int Abc_HObjNum ( Abc_HObj_t * p ) { return p->Num; }
static inline Abc_HObj_t * Abc_HObjFanin0( Abc_HObj_t * p ) { return !p->Fan0.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Fan0.NtkId), p->Fan0.ObjId ); }
static inline Abc_HObj_t * Abc_HObjFanin1( Abc_HObj_t * p ) { return !p->Fan1.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Fan1.NtkId), p->Fan1.ObjId ); }
static inline Abc_HObj_t * Abc_HObjProto ( Abc_HObj_t * p ) { return !p->Proto.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Proto.NtkId), p->Proto.ObjId ); }
static inline int Abc_HObjFaninC0( Abc_HObj_t * p ) { return p->Fan0.fCompl; }
static inline int Abc_HObjFaninC1( Abc_HObj_t * p ) { return p->Fan1.fCompl; }
static inline Abc_HObj_t * Abc_ObjHObj( Abc_Obj_t * p ) { return Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->pNtk->Id), p->Id ); }
static int Abc_HManVerifyPair( int NtkIdOld, int NtkIdNew );
static int Abc_HManVerifyNodes_rec( Abc_HObj_t * pHOld, Abc_HObj_t * pHNew );
static Vec_Ptr_t * Abc_HManCollectLeaves( Abc_HObj_t * pHNew );
static Vec_Ptr_t * Abc_HManCollectCone( Abc_HObj_t * pHOld, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone );
static int Abc_HManSimulate( Vec_Ptr_t * vCone0, Vec_Ptr_t * vCone1, int nLeaves, int * pPhase );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManStart()
{
Abc_HMan_t * p;
unsigned * pData;
int i, k;
assert( s_pHMan == NULL );
assert( sizeof(unsigned) == 4 );
// allocate manager
p = ALLOC( Abc_HMan_t, 1 );
memset( p, 0, sizeof(Abc_HMan_t) );
// allocate storage for all nodes
p->vNtks = Vec_VecStart( 1 );
p->vProof = Vec_IntStart( 1 );
// allocate temporary storage for objects
p->nVarsMax = ABC_SIM_VARS;
p->nObjsMax = ABC_SIM_OBJS;
p->vObjs = Vec_PtrAlloc( p->nObjsMax );
// allocate simulation info
p->nBits = (1 << p->nVarsMax);
p->nWords = (p->nBits <= 32)? 1 : (p->nBits / 32);
p->pInfo = ALLOC( unsigned, p->nWords * p->nObjsMax );
memset( p->pInfo, 0, sizeof(unsigned) * p->nWords * p->nVarsMax );
p->vSims = Vec_PtrAlloc( p->nObjsMax );
for ( i = 0; i < p->nObjsMax; i++ )
Vec_PtrPush( p->vSims, p->pInfo + i * p->nWords );
// set elementary truth tables
for ( k = 0; k < p->nVarsMax; k++ )
{
pData = p->vSims->pArray[k];
for ( i = 0; i < p->nBits; i++ )
if ( i & (1 << k) )
pData[i>>5] |= (1 << (i&31));
}
// allocate storage for the nodes
p->pMmObj = Extra_MmFixedStart( sizeof(Abc_HObj_t) );
p->vCone0 = Vec_PtrAlloc( p->nObjsMax );
p->vCone1 = Vec_PtrAlloc( p->nObjsMax );
s_pHMan = p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManStop()
{
assert( s_pHMan != NULL );
Extra_MmFixedStop( s_pHMan->pMmObj, 0 );
Vec_PtrFree( s_pHMan->vObjs );
Vec_PtrFree( s_pHMan->vSims );
Vec_VecFree( s_pHMan->vNtks );
Vec_IntFree( s_pHMan->vProof );
Vec_PtrFree( s_pHMan->vCone0 );
Vec_PtrFree( s_pHMan->vCone1 );
free( s_pHMan->pInfo );
free( s_pHMan );
s_pHMan = NULL;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManIsRunning()
{
return s_pHMan != NULL;
}
/**Function*************************************************************
Synopsis [Called when a new network is created.]
Description [Returns the new ID for the network.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManGetNewNtkId()
{
if ( s_pHMan == NULL )
return 0;
return Vec_VecSize( s_pHMan->vNtks ); // what if the new network has no nodes?
}
/**Function*************************************************************
Synopsis [Called when the object is created.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManAddObj( Abc_Obj_t * pObj )
{
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
pHObj = (Abc_HObj_t *)Extra_MmFixedEntryFetch( s_pHMan->pMmObj );
memset( pHObj, 0, sizeof(Abc_HObj_t) );
// set the object type
pHObj->NtkId = pObj->pNtk->Id;
if ( Abc_ObjIsCi(pObj) )
pHObj->fPi = 1;
else if ( Abc_ObjIsCo(pObj) )
pHObj->fPo = 1;
Vec_VecPush( s_pHMan->vNtks, pObj->pNtk->Id, pHObj );
// set the proof parameter for the network
if ( Vec_IntSize( s_pHMan->vProof ) == pObj->pNtk->Id )
Vec_IntPush( s_pHMan->vProof, 0 );
}
/**Function*************************************************************
Synopsis [Called when the fanin is added to the object.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
{
Abc_HObj_t * pHObj;
int fCompl;
if ( s_pHMan == NULL )
return;
// take off the complemented attribute
assert( !Abc_ObjIsComplement(pObj) );
fCompl = Abc_ObjIsComplement(pFanin);
pFanin = Abc_ObjRegular(pFanin);
// add the fanin
assert( pObj->pNtk == pFanin->pNtk );
pHObj = Abc_ObjHObj(pObj);
if ( pHObj->Fan0.NtkId == 0 )
{
pHObj->Fan0.NtkId = pFanin->pNtk->Id;
pHObj->Fan0.ObjId = pFanin->Id;
pHObj->Fan0.fCompl = fCompl;
}
else if ( pHObj->Fan1.NtkId == 0 )
{
pHObj->Fan1.NtkId = pFanin->pNtk->Id;
pHObj->Fan1.ObjId = pFanin->Id;
pHObj->Fan1.fCompl = fCompl;
}
else assert( 0 );
}
/**Function*************************************************************
Synopsis [Called when the fanin's input should be complemented.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManXorFaninC( Abc_Obj_t * pObj, int iFanin )
{
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
assert( iFanin < 2 );
pHObj = Abc_ObjHObj(pObj);
if ( iFanin == 0 )
pHObj->Fan0.fCompl ^= 1;
else if ( iFanin == 1 )
pHObj->Fan1.fCompl ^= 1;
}
/**Function*************************************************************
Synopsis [Called when the fanin is added to the object.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManRemoveFanins( Abc_Obj_t * pObj )
{
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
assert( !Abc_ObjIsComplement(pObj) );
pHObj = Abc_ObjHObj(pObj);
pHObj->Fan0.NtkId = 0;
pHObj->Fan0.ObjId = 0;
pHObj->Fan0.fCompl = 0;
pHObj->Fan1.NtkId = 0;
pHObj->Fan1.ObjId = 0;
pHObj->Fan1.fCompl = 0;
}
/**Function*************************************************************
Synopsis [Called when a new prototype of the old object is set.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManAddProto( Abc_Obj_t * pObj, Abc_Obj_t * pProto )
{
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
// ignore polarity for now
pObj = Abc_ObjRegular(pObj);
pProto = Abc_ObjRegular(pProto);
// set the prototype
assert( pObj->pNtk != pProto->pNtk );
if ( pObj->pNtk->Id == 0 )
return;
pHObj = Abc_ObjHObj(pObj);
pHObj->Proto.NtkId = pProto->pNtk->Id;
pHObj->Proto.ObjId = pProto->Id;
}
/**Function*************************************************************
Synopsis [Called when an equivalent node is created.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManMapAddEqu( Abc_Obj_t * pObj, Abc_Obj_t * pEqu )
{
/*
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
// ignore polarity for now
pObj = Abc_ObjRegular(pObj);
pEqu = Abc_ObjRegular(pEqu);
// set the equivalent node
assert( pObj->pNtk == pEqu->pNtk );
pHObj = Abc_ObjHObj(pObj);
Abc_ObjHObj(pObj)->Equ.NtkId = pEqu->pNtk->Id;
Abc_ObjHObj(pObj)->Equ.ObjId = pEqu->Id;
*/
}
/**Function*************************************************************
Synopsis [Starts the verification procedure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManPopulate( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i;
if ( !Abc_NtkIsStrash(pNtk) )
return 0;
// allocate the network ID
pNtk->Id = Abc_HManGetNewNtkId();
assert( pNtk->Id == 1 );
// create the objects
Abc_NtkForEachObj( pNtk, pObj, i )
{
Abc_HManAddObj( pObj );
if ( Abc_ObjFaninNum(pObj) > 0 )
Abc_HManAddFanin( pObj, Abc_ObjChild0(pObj) );
if ( Abc_ObjFaninNum(pObj) > 1 )
Abc_HManAddFanin( pObj, Abc_ObjChild1(pObj) );
}
return 1;
}
/**Function*************************************************************
Synopsis [The main verification procedure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManVerify( int NtkIdOld, int NtkIdNew )
{
int i;
// prove the equality pairwise
for ( i = NtkIdOld; i < NtkIdNew; i++ )
{
if ( Vec_IntEntry(s_pHMan->vProof, i) )
continue;
if ( !Abc_HManVerifyPair( i, i+1 ) )
return 0;
Vec_IntWriteEntry( s_pHMan->vProof, i, 1 );
}
return 1;
}
/**Function*************************************************************
Synopsis [Verifies two networks.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManVerifyPair( int NtkIdOld, int NtkIdNew )
{
Vec_Ptr_t * vNtkNew, * vNtkOld, * vPosNew;
Abc_HObj_t * pHObj;
int i;
// get hold of the network nodes
vNtkNew = Vec_VecEntry( s_pHMan->vNtks, NtkIdNew );
vNtkOld = Vec_VecEntry( s_pHMan->vNtks, NtkIdOld );
Vec_PtrForEachEntry( vNtkNew, pHObj, i )
pHObj->fVisited = 0;
Vec_PtrForEachEntry( vNtkOld, pHObj, i )
pHObj->fVisited = 0;
// collect new POs
vPosNew = Vec_PtrAlloc( 100 );
Vec_PtrForEachEntry( vNtkNew, pHObj, i )
if ( pHObj->fPo )
Vec_PtrPush( vPosNew, pHObj );
// prove them recursively (assuming PO ordering is the same)
Vec_PtrForEachEntry( vPosNew, pHObj, i )
{
if ( Abc_HObjProto(pHObj) == NULL )
{
printf( "History: PO %d has no prototype\n", i );
return 0;
}
if ( !Abc_HManVerifyNodes_rec( Abc_HObjProto(pHObj), pHObj ) )
{
printf( "History: Verification failed for outputs of PO pair number %d\n", i );
return 0;
}
}
printf( "History: Verification succeeded.\n" );
return 1;
}
/**Function*************************************************************
Synopsis [Recursively verifies two nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManVerifyNodes_rec( Abc_HObj_t * pHOld, Abc_HObj_t * pHNew )
{
Vec_Ptr_t * vLeaves;
Abc_HObj_t * pHObj, * pHPro0, * pHPro1;
int i, fPhase;
assert( Abc_HObjProto(pHNew) == pHOld );
if ( pHNew->fProof )
return 1;
pHNew->fProof = 1;
// consider simple cases
if ( pHNew->fPi || pHNew->fConst )
return 1;
if ( pHNew->fPo )
{
if ( !Abc_HManVerifyNodes_rec( Abc_HObjFanin0(pHOld), Abc_HObjFanin0(pHNew) ) )
return 0;
if ( (Abc_HObjFaninC0(pHOld) ^ Abc_HObjFaninC0(pHNew)) != (int)pHNew->fPhase )
{
printf( "History: Phase of PO nodes does not agree.\n" );
return 0;
}
return 1;
}
// the elementary node
pHPro0 = Abc_HObjProto( Abc_HObjFanin0(pHNew) );
pHPro1 = Abc_HObjProto( Abc_HObjFanin1(pHNew) );
if ( pHPro0 && pHPro1 )
{
if ( !Abc_HManVerifyNodes_rec( pHPro0, Abc_HObjFanin0(pHNew) ) )
return 0;
if ( !Abc_HManVerifyNodes_rec( pHPro1, Abc_HObjFanin1(pHNew) ) )
return 0;
if ( Abc_HObjFanin0(pHOld) != pHPro0 || Abc_HObjFanin1(pHOld) != pHPro1 )
{
printf( "History: Internal node does not match.\n" );
return 0;
}
if ( Abc_HObjFaninC0(pHOld) != Abc_HObjFaninC0(pHNew) ||
Abc_HObjFaninC1(pHOld) != Abc_HObjFaninC1(pHNew) )
{
printf( "History: Phase of internal node does not match.\n" );
return 0;
}
return 1;
}
// collect the leaves
vLeaves = Abc_HManCollectLeaves( pHNew );
if ( Vec_PtrSize(vLeaves) > 16 )
{
printf( "History: The bound on the number of inputs is exceeded.\n" );
return 0;
}
s_pHMan->nWordsCur = ((1 << Vec_PtrSize(vLeaves)) <= 32)? 1 : ((1 << Vec_PtrSize(vLeaves)) / 32);
// prove recursively
Vec_PtrForEachEntry( vLeaves, pHObj, i )
if ( !Abc_HManVerifyNodes_rec( Abc_HObjProto(pHObj), pHObj ) )
{
Vec_PtrFree( vLeaves );
return 0;
}
// get the first node
Abc_HManCollectCone( pHNew, vLeaves, s_pHMan->vCone1 );
if ( Vec_PtrSize(s_pHMan->vCone1) > ABC_SIM_OBJS - ABC_SIM_VARS - 1 )
{
printf( "History: The bound on the number of cone nodes is exceeded.\n" );
return 0;
}
// get the second cone
Vec_PtrForEachEntry( vLeaves, pHObj, i )
Vec_PtrWriteEntry( vLeaves, i, Abc_HObjProto(pHObj) );
Abc_HManCollectCone( pHOld, vLeaves, s_pHMan->vCone0 );
if ( Vec_PtrSize(s_pHMan->vCone0) > ABC_SIM_OBJS - ABC_SIM_VARS - 1 )
{
printf( "History: The bound on the number of cone nodes is exceeded.\n" );
return 0;
}
// compare the truth tables
if ( !Abc_HManSimulate( s_pHMan->vCone0, s_pHMan->vCone1, Vec_PtrSize(vLeaves), &fPhase ) )
{
Vec_PtrFree( vLeaves );
printf( "History: Verification failed at an internal node.\n" );
return 0;
}
printf( "Succeeded.\n" );
pHNew->fPhase = fPhase;
Vec_PtrFree( vLeaves );
return 1;
}
/**Function*************************************************************
Synopsis [Finds the leaves of the TFI cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManCollectLeaves_rec( Abc_HObj_t * pHNew, Vec_Ptr_t * vLeaves )
{
Abc_HObj_t * pHPro;
if ( pHPro = Abc_HObjProto( pHNew ) )
{
Vec_PtrPushUnique( vLeaves, pHNew );
return;
}
assert( !pHNew->fPi && !pHNew->fPo && !pHNew->fConst );
Abc_HManCollectLeaves_rec( Abc_HObjFanin0(pHNew), vLeaves );
Abc_HManCollectLeaves_rec( Abc_HObjFanin1(pHNew), vLeaves );
}
/**Function*************************************************************
Synopsis [Finds the leaves of the TFI cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_HManCollectLeaves( Abc_HObj_t * pHNew )
{
Vec_Ptr_t * vLeaves;
vLeaves = Vec_PtrAlloc( 100 );
Abc_HManCollectLeaves_rec( Abc_HObjFanin0(pHNew), vLeaves );
Abc_HManCollectLeaves_rec( Abc_HObjFanin1(pHNew), vLeaves );
return vLeaves;
}
/**Function*************************************************************
Synopsis [Collects the TFI cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManCollectCone_rec( Abc_HObj_t * pHObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
{
if ( pHObj->fVisited )
return;
pHObj->fVisited = 1;
assert( !pHObj->fPi && !pHObj->fPo && !pHObj->fConst );
Abc_HManCollectCone_rec( Abc_HObjFanin0(pHObj), vLeaves, vCone );
Abc_HManCollectCone_rec( Abc_HObjFanin1(pHObj), vLeaves, vCone );
pHObj->Num = Vec_PtrSize(vCone);
Vec_PtrPush( vCone, pHObj );
}
/**Function*************************************************************
Synopsis [Collects the TFI cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_HManCollectCone( Abc_HObj_t * pHRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
{
Abc_HObj_t * pHObj;
int i;
Vec_PtrClear( vCone );
Vec_PtrForEachEntry( vLeaves, pHObj, i )
{
pHObj->fVisited = 1;
pHObj->Num = Vec_PtrSize(vCone);
Vec_PtrPush( vCone, pHObj );
}
Abc_HManCollectCone_rec( Abc_HObjFanin0(pHRoot), vLeaves, vCone );
Abc_HManCollectCone_rec( Abc_HObjFanin1(pHRoot), vLeaves, vCone );
return vCone;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManSimulateOne( Vec_Ptr_t * vCone, int nLeaves, int fUsePhase )
{
Abc_HObj_t * pHObj, * pHFan0, * pHFan1;
unsigned * puData0, * puData1, * puData;
int k, i, fComp0, fComp1;
// set the leaves
Vec_PtrForEachEntryStart( vCone, pHObj, i, nLeaves )
{
pHFan0 = Abc_HObjFanin0(pHObj);
pHFan1 = Abc_HObjFanin1(pHObj);
// consider the case of interver or buffer
if ( pHFan1 == NULL )
{
puData = Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+i-nLeaves);
puData0 = ((int)pHFan0->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan0->Num) :
Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan0->Num-nLeaves);
fComp0 = Abc_HObjFaninC0(pHObj) ^ (fUsePhase && (int)pHFan0->Num < nLeaves && pHFan0->fPhase);
if ( fComp0 )
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = ~puData0[k];
else
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = puData0[k];
continue;
}
// get the pointers to simulation data
puData = Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+i-nLeaves);
puData0 = ((int)pHFan0->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan0->Num) :
Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan0->Num-nLeaves);
puData1 = ((int)pHFan1->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan1->Num) :
Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan1->Num-nLeaves);
// here are the phases
fComp0 = Abc_HObjFaninC0(pHObj) ^ (fUsePhase && (int)pHFan0->Num < nLeaves && pHFan0->fPhase);
fComp1 = Abc_HObjFaninC1(pHObj) ^ (fUsePhase && (int)pHFan1->Num < nLeaves && pHFan1->fPhase);
// simulate
if ( fComp0 && fComp1 )
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = ~puData0[k] & ~puData1[k];
else if ( fComp0 )
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = ~puData0[k] & puData1[k];
else if ( fComp1 )
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = puData0[k] & ~puData1[k];
else
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = puData0[k] & puData1[k];
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManSimulate( Vec_Ptr_t * vCone0, Vec_Ptr_t * vCone1, int nLeaves, int * pPhase )
{
unsigned * pDataTop, * pDataLast;
int w;
// simulate the first one
Abc_HManSimulateOne( vCone0, nLeaves, 0 );
// save the last simulation value
pDataTop = Vec_PtrEntry( s_pHMan->vSims, ((Abc_HObj_t *)Vec_PtrEntryLast(vCone0))->Num );
pDataLast = Vec_PtrEntry( s_pHMan->vSims, Vec_PtrSize(s_pHMan->vSims)-1 );
for ( w = 0; w < s_pHMan->nWordsCur; w++ )
pDataLast[w] = pDataTop[w];
// simulate the other one
Abc_HManSimulateOne( vCone1, nLeaves, 1 );
// complement the output if needed
pDataTop = Vec_PtrEntry( s_pHMan->vSims, ((Abc_HObj_t *)Vec_PtrEntryLast(vCone1))->Num );
// mask unused bits
if ( nLeaves < 5 )
{
pDataTop[0] &= ((~((unsigned)0)) >> (32-(1<<nLeaves)));
pDataLast[0] &= ((~((unsigned)0)) >> (32-(1<<nLeaves)));
}
if ( *pPhase = ((pDataTop[0] & 1) != (pDataLast[0] & 1)) )
for ( w = 0; w < s_pHMan->nWordsCur; w++ )
pDataTop[w] = ~pDataTop[w];
// compare
for ( w = 0; w < s_pHMan->nWordsCur; w++ )
if ( pDataLast[w] != pDataTop[w] )
return 0;
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -333,7 +333,7 @@ Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUn
// transform the network to the SOP representation
if ( !Abc_NtkBddToSop( pNtkNew, 0 ) )
{
printf( "Converting to SOPs has failed.\n" );
printf( "Abc_NtkConstructExdc(): Converting to SOPs has failed.\n" );
return NULL;
}
return pNtkNew;

View File

@ -526,7 +526,7 @@ Abc_Ntk_t * Abc_NtkVanEijkFrames( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCorresp, int nF
pNtkFrames->pName = Extra_UtilStrsav(Buffer);
}
// map the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkFrames);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkFrames);
// create new latches and remember them in the new latches
Abc_NtkForEachLatch( pNtk, pLatch, i )
Abc_NtkDupObj( pNtkFrames, pLatch );
@ -589,7 +589,7 @@ void Abc_NtkVanEijkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFram
// remember the CI mapping
if ( vCorresp )
{
pNode = Abc_NtkConst1(pNtk);
pNode = Abc_AigConst1(pNtk);
Abc_NodeVanEijkWriteCorresp( pNode, vCorresp, iFrame, Abc_ObjRegular(pNode->pCopy) );
Abc_NtkForEachCi( pNtk, pNode, i )
Abc_NodeVanEijkWriteCorresp( pNode, vCorresp, iFrame, Abc_ObjRegular(pNode->pCopy) );
@ -667,7 +667,7 @@ Fraig_Man_t * Abc_NtkVanEijkFraig( Abc_Ntk_t * pMulti, int fInit )
// clean the copy fields in the old network
Abc_NtkCleanCopy( pMulti );
// map the constant nodes
Abc_NtkConst1(pMulti)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
Abc_AigConst1(pMulti)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan);
if ( fInit )
{
// map the PI nodes
@ -724,14 +724,14 @@ Abc_Ntk_t * Abc_NtkVanEijkDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vClasses )
pNtkNew->pSpec = NULL;
// map the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// for each CI, create PI
Abc_NtkForEachCi( pNtk, pObj, i )
Abc_NtkLogicStoreName( pObj->pCopy = Abc_NtkCreatePi(pNtkNew), Abc_ObjName(pObj) );
// cannot add latches here because pLatch->pCopy pointers are used
// create the cones for each pair of nodes in an equivalence class
pTotal = Abc_ObjNot( Abc_NtkConst1(pNtkNew) );
pTotal = Abc_ObjNot( Abc_AigConst1(pNtkNew) );
Vec_PtrForEachEntry( vClasses, pClass, i )
{
assert( pClass->pNext );
@ -783,7 +783,7 @@ Abc_Ntk_t * Abc_NtkVanEijkDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vClasses )
Abc_NtkDeleteObj( pObjNew );
// make the old network point to the new things
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy = Abc_NtkPi( pNtkNew, i );
*/

View File

@ -487,7 +487,7 @@ printf( "PO = %d\n", pNode1->Id );
// go through the pairs of signals in the frames
pProgress = Extra_ProgressBarStart( stdout, p->nIdMax );
pConst1 = Abc_NtkConst1( p->pNtkSingle );
pConst1 = Abc_AigConst1(p->pNtkSingle);
p->vImps = Vec_IntAlloc( 100 );
p->vZeros = Vec_PtrAlloc( 100 );
Abc_NtkForEachObj( p->pNtkSingle, pNode1, i )
@ -882,14 +882,14 @@ Abc_Ntk_t * Abc_NtkVanImpDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vZeros, Vec_I
pNtkNew->pSpec = NULL;
// map the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// for each CI, create PI
Abc_NtkForEachCi( pNtk, pObj, i )
Abc_NtkLogicStoreName( pObj->pCopy = Abc_NtkCreatePi(pNtkNew), Abc_ObjName(pObj) );
// cannot add latches here because pLatch->pCopy pointers are used
// build logic cone for zero nodes
pTotal = Abc_ObjNot( Abc_NtkConst1(pNtkNew) );
pTotal = Abc_ObjNot( Abc_AigConst1(pNtkNew) );
Vec_PtrForEachEntry( vZeros, pNode, i )
{
// build the logic cone for the node
@ -961,7 +961,7 @@ Abc_Ntk_t * Abc_NtkVanImpDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vZeros, Vec_I
Abc_NtkDeleteObj( pObjNew );
// make the old network point to the new things
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy = Abc_NtkPi( pNtkNew, i );
*/

View File

@ -422,9 +422,9 @@ int * Abc_NtkVerifySimulatePattern( Abc_Ntk_t * pNtk, int * pModel )
vNodes = Abc_NtkDfs( pNtk, 1 );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
if ( Abc_NodeIsConst(pNode) )
pNode->pCopy = NULL;
else
// if ( Abc_NodeIsConst(pNode) )
// pNode->pCopy = NULL;
// else
{
Value0 = ((int)Abc_ObjFanin0(pNode)->pCopy) ^ Abc_ObjFaninC0(pNode);
Value1 = ((int)Abc_ObjFanin1(pNode)->pCopy) ^ Abc_ObjFaninC1(pNode);

View File

@ -31,7 +31,6 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcSweep.c \
src/base/abci/abcSymm.c \
src/base/abci/abcTiming.c \
src/base/abci/abcTrace.c \
src/base/abci/abcUnate.c \
src/base/abci/abcUnreach.c \
src/base/abci/abcVanEijk.c \

View File

@ -1261,7 +1261,7 @@ int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv )
if ( Abc_NtkIsMappedLogic(pNtk) )
{
Abc_NtkUnmap(pNtk);
Abc_NtkMapToSop(pNtk);
printf( "The current network is unmapped before calling SIS.\n" );
}
@ -1402,7 +1402,7 @@ int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv )
if ( Abc_NtkIsMappedLogic(pNtk) )
{
Abc_NtkUnmap(pNtk);
Abc_NtkMapToSop(pNtk);
printf( "The current network is unmapped before calling MVSIS.\n" );
}
@ -1548,7 +1548,7 @@ int CmdCommandCapo( Abc_Frame_t * pAbc, int argc, char **argv )
if ( Abc_NtkIsMappedLogic(pNtk) )
{
Abc_NtkUnmap(pNtk);
Abc_NtkMapToSop(pNtk);
printf( "The current network is unmapped before calling Capo.\n" );
}

View File

@ -667,13 +667,13 @@ usage:
***********************************************************************/
int IoCommandReadVer( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk, * pTemp;
st_table * tDesign;
Abc_Ntk_t * pNtk;
Abc_Lib_t * pDesign;
char * FileName;
FILE * pFile;
int fCheck;
int c;
extern st_table * Ver_ParseFile( char * pFileName, st_table * pGateLib, int fCheck );
extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck );
fCheck = 1;
Extra_UtilGetoptReset();
@ -709,41 +709,21 @@ int IoCommandReadVer( Abc_Frame_t * pAbc, int argc, char ** argv )
fclose( pFile );
// set the new network
tDesign = Ver_ParseFile( FileName, Abc_FrameReadLibVer(), fCheck );
if ( tDesign == NULL )
pDesign = Ver_ParseFile( FileName, Abc_FrameReadLibVer(), fCheck );
if ( pDesign == NULL )
{
fprintf( pAbc->Err, "Reading network from the verilog file has failed.\n" );
return 1;
}
if ( st_count(tDesign) == 1 )
// derive root design
pNtk = Abc_LibDeriveRoot( pDesign );
if ( pNtk == NULL )
{
st_generator * gen;
char * pName;
// find the network
st_foreach_item( tDesign, gen, (char**)&pName, (char**)&pNtk )
{
st_free_gen(gen);
break;
}
st_free_table( tDesign );
// convert it into a logic network
pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
Abc_NtkDelete( pTemp );
if ( pNtk == NULL )
{
fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" );
return 1;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
fprintf( pAbc->Err, "Deriving root module has failed.\n" );
return 1;
}
else
{
printf( "The design includes more than one module and is currently not used.\n" );
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
return 0;
usage:
@ -768,14 +748,12 @@ usage:
***********************************************************************/
int IoCommandReadVerLib( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk, * pTemp;
st_table * tDesign;
Abc_Lib_t * pLibrary;
char * FileName;
FILE * pFile;
int fCheck;
int c;
extern st_table * Ver_ParseFile( char * pFileName, st_table * pGateLib, int fCheck );
extern void Ver_ParseFreeLibrary( st_table * pLibVer );
extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck );
fCheck = 1;
Extra_UtilGetoptReset();
@ -811,41 +789,18 @@ int IoCommandReadVerLib( Abc_Frame_t * pAbc, int argc, char ** argv )
fclose( pFile );
// set the new network
tDesign = Ver_ParseFile( FileName, NULL, fCheck );
if ( tDesign == NULL )
pLibrary = Ver_ParseFile( FileName, NULL, fCheck );
if ( pLibrary == NULL )
{
fprintf( pAbc->Err, "Reading library from the verilog file has failed.\n" );
return 1;
}
printf( "The library contains %d gates.\n", st_count(tDesign) );
// convert gates into AIGs
{
st_table * tLibrary;
st_generator * gen;
char * pName;
// transform the gates into the library AIGs
tLibrary = st_init_table( strcmp, st_strhash );
st_foreach_item( tDesign, gen, (char**)&pName, (char**)&pNtk )
{
// convert the netlist into SOP logic network
pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
Abc_NtkDelete( pTemp );
// perform structural hashing
pNtk = Abc_NtkStrash( pTemp = pNtk, 0, 1 );
Abc_NtkDelete( pTemp );
// insert the new network into the new library
st_insert( tLibrary, pNtk->pName, (char *)pNtk );
}
st_free_table( tDesign );
// free old library
if ( Abc_FrameReadLibVer() )
Ver_ParseFreeLibrary( Abc_FrameReadLibVer() );
// read new library
Abc_FrameSetLibVer( tLibrary );
}
printf( "The library contains %d gates.\n", st_count(pLibrary->tModules) );
// free old library
if ( Abc_FrameReadLibVer() )
Abc_LibFree( Abc_FrameReadLibVer() );
// read new library
Abc_FrameSetLibVer( pLibrary );
return 0;
usage:

View File

@ -79,7 +79,7 @@ Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck )
// prepare the array of nodes
vNodes = Vec_PtrAlloc( 1 + nInputs + nLatches + nAnds );
Vec_PtrPush( vNodes, Abc_NtkConst1(pNtkNew) );
Vec_PtrPush( vNodes, Abc_AigConst1(pNtkNew) );
// create the PIs
for ( i = 0; i < nInputs; i++ )

View File

@ -415,7 +415,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
return;
}
}

View File

@ -117,8 +117,8 @@ void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost )
fprintf( pFile, "# written by ABC on %s\n", Extra_TimeStamp() );
// write the constant node
if ( Abc_ObjFanoutNum( Abc_NtkConst1(pNtk) ) > 0 )
Io_WriteListEdge( pFile, Abc_NtkConst1(pNtk) );
if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk) ) > 0 )
Io_WriteListEdge( pFile, Abc_AigConst1(pNtk) );
// write the PI edges
Abc_NtkForEachPi( pNtk, pObj, i )

View File

@ -265,7 +265,6 @@ void Io_WriteVerilogAuxNodes( FILE * pFile, Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
int i, nCubes, nFanins, Counter, nDigits, fPadZeros;
char * pName;
extern int Abc_SopIsExorType( char * pSop );
nDigits = Extra_Base10Log( Abc_NtkNodeNum(pNtk) );
Counter = 1;

View File

@ -137,13 +137,12 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
{
extern void Rwt_ManGlobalStop();
extern void undefine_cube_size();
extern void Ver_ParseFreeLibrary( st_table * pLibVer );
// extern void Ivy_TruthManStop();
// Abc_HManStop();
undefine_cube_size();
Rwt_ManGlobalStop();
// Ivy_TruthManStop();
if ( p->pLibVer ) Ver_ParseFreeLibrary( p->pLibVer );
if ( p->pLibVer ) Abc_LibFree( p->pLibVer );
if ( p->pManDec ) Dec_ManStop( p->pManDec );
if ( p->dd ) Extra_StopManager( p->dd );
Abc_FrameDeleteAllNetworks( p );
@ -427,7 +426,7 @@ void Abc_FrameUnmapAllNetworks( Abc_Frame_t * p )
Abc_Ntk_t * pNtk;
for ( pNtk = p->pNtkCur; pNtk; pNtk = Abc_NtkBackup(pNtk) )
if ( Abc_NtkHasMapping(pNtk) )
Abc_NtkUnmap( pNtk );
Abc_NtkMapToSop( pNtk );
}
/**Function*************************************************************

View File

@ -7,6 +7,7 @@ SRC += src/base/seq/seqAigCore.c \
src/base/seq/seqMan.c \
src/base/seq/seqMapCore.c \
src/base/seq/seqMapIter.c \
src/base/seq/seqMaxMeanCycle.c \
src/base/seq/seqRetCore.c \
src/base/seq/seqRetIter.c \
src/base/seq/seqShare.c \

View File

@ -64,6 +64,9 @@ extern int Seq_NodeCompareLats( Abc_Obj_t * pObj1, int Edge1, Abc_Ob
extern Abc_Seq_t * Seq_Create( Abc_Ntk_t * pNtk );
extern void Seq_Resize( Abc_Seq_t * p, int nMaxId );
extern void Seq_Delete( Abc_Seq_t * p );
/*=== seqMaxMeanCycle.c ======================================================*/
extern float Seq_NtkHoward( Abc_Ntk_t * pNtk, int fVerbose );
extern void Seq_NtkSkewForward( Abc_Ntk_t * pNtk, float period, int fMinimize );
/*=== abcSeq.c ===============================================================*/
extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk );

View File

@ -93,11 +93,11 @@ Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk )
// map the constant nodes
Abc_NtkCleanCopy( pNtk );
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// copy all objects, except the latches and constant
Vec_PtrFill( pNtkNew->vObjs, Abc_NtkObjNumMax(pNtk), NULL );
Vec_PtrWriteEntry( pNtkNew->vObjs, 0, Abc_NtkConst1(pNtk)->pCopy );
Vec_PtrWriteEntry( pNtkNew->vObjs, 0, Abc_AigConst1(pNtk)->pCopy );
Abc_NtkForEachObj( pNtk, pObj, i )
{
if ( i == 0 || Abc_ObjIsLatch(pObj) )
@ -236,7 +236,7 @@ void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk )
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
pDriver = Abc_ObjFanin0(pLatch);
if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_NodeIsAigAnd(pDriver) )
if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_AigNodeIsAnd(pDriver) )
continue;
Abc_NodeSetTravIdCurrent(pDriver);
pDriverNew = pDriver->pCopy;
@ -428,7 +428,7 @@ bool Abc_NtkSeqCheck( Abc_Ntk_t * pNtk )
nFanins = Abc_ObjFaninNum(pObj);
if ( nFanins == 0 )
{
if ( pObj != Abc_NtkConst1(pNtk) )
if ( pObj != Abc_AigConst1(pNtk) )
{
printf( "Abc_SeqCheck: The AIG has non-standard constant nodes.\n" );
return 0;

View File

@ -382,7 +382,7 @@ int Seq_FpgaMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vL
if ( SeqEdge == (unsigned)pLeaf )
return 0;
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
@ -417,7 +417,7 @@ Abc_Obj_t * Seq_FpgaMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, uns
if ( SeqEdge == (unsigned)pLeaf )
return pObj->pCopy;
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
@ -464,7 +464,7 @@ DdNode * Seq_FpgaMappingBdd_rec( DdManager * dd, Abc_Ntk_t * pNtk, unsigned SeqE
if ( SeqEdge == (unsigned)pLeaf )
return Cudd_bddIthVar( dd, i );
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
@ -514,7 +514,7 @@ void Seq_FpgaMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * p
}
}
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
@ -564,7 +564,7 @@ void Seq_FpgaMappingConnect_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t *
}
}
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
@ -616,7 +616,7 @@ DdNode * Seq_FpgaMappingConnectBdd_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_
}
}
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );

View File

@ -116,7 +116,7 @@ void Seq_FpgaMappingCollectNode_rec( Abc_Obj_t * pAnd, Vec_Ptr_t * vMapping, Vec
int k;
// skip if this is a non-PI node
if ( !Abc_NodeIsAigAnd(pAnd) )
if ( !Abc_AigNodeIsAnd(pAnd) )
return;
// skip a visited node
if ( Abc_NodeIsTravIdCurrent(pAnd) )
@ -203,7 +203,7 @@ static inline int Seq_FpgaCutUpdateLValue( Cut_Cut_t * pCut, Abc_Obj_t * pObj, i
{
Abc_Obj_t * pFanin;
int i, lValueMax, lValueCur;
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
lValueMax = -ABC_INFINITY;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
{

View File

@ -474,7 +474,7 @@ int Seq_MapMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLe
if ( SeqEdge == (unsigned)pLeaf )
return 0;
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
@ -519,7 +519,7 @@ Abc_Obj_t * Seq_MapMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsi
return pObj->pCopy;
}
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
@ -572,7 +572,7 @@ void Seq_MapMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pP
}
}
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
@ -625,7 +625,7 @@ DdNode * Seq_MapMappingConnectBdd_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_O
}
}
// continue unfolding
assert( Abc_NodeIsAigAnd(pObj) );
assert( Abc_AigNodeIsAnd(pObj) );
// get new sequential edges
assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
assert( Lag + Seq_ObjFaninL1(pObj) < 255 );

View File

@ -540,7 +540,7 @@ float Seq_MapCollectNode_rec( Abc_Obj_t * pAnd, float FiBest, Vec_Ptr_t * vMappi
}
// skip if this is a PI or a constant
if ( !Abc_NodeIsAigAnd(pAnd) )
if ( !Abc_AigNodeIsAnd(pAnd) )
{
if ( Abc_ObjIsPi(pAnd) && fCompl )
return AreaInv;

View File

@ -0,0 +1,567 @@
/**CFile****************************************************************
FileName [seqMaxMeanCycle.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Construction and manipulation of sequential AIGs.]
Synopsis [Efficient computation of maximum mean cycle times.]
Author [Aaron P. Hurst]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 15, 2006.]
Revision [$Id: seqMaxMeanCycle.c,v 1.00 2005/05/15 00:00:00 ahurst Exp $]
***********************************************************************/
#include "seqInt.h"
#include "hash.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
struct Abc_ManTime_t_
{
Abc_Time_t tArrDef;
Abc_Time_t tReqDef;
Vec_Ptr_t * vArrs;
Vec_Ptr_t * vReqs;
};
typedef struct Seq_HowardData_t_
{
char visited;
int mark;
int policy;
float cycle;
float skew;
float delay;
} Seq_HowardData_t;
// accessing the arrival and required times of a node
static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; }
static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vReqs->pArray[pNode->Id]; }
Hash_Ptr_t * Seq_NtkPathDelays( Abc_Ntk_t * pNtk, int fVerbose );
void Seq_NtkMergePios( Abc_Ntk_t * pNtk, Hash_Ptr_t * hFwdDelays, int fVerbose );
void Seq_NtkHowardLoop( Abc_Ntk_t * pNtk, Hash_Ptr_t * hFwdDelays,
Hash_Ptr_t * hNodeData, int node,
int *howardDepth, float *howardDelay, int *howardSink,
float *maxMeanCycle);
void Abc_NtkDfsReverse_rec2( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vEndpoints );
#define Seq_NtkGetPathDelay( hFwdDelays, from, to ) \
(Hash_PtrExists(hFwdDelays, from)?Hash_FltEntry( ((Hash_Flt_t *)Hash_PtrEntry(hFwdDelays, from, 0)), to, 0):0 )
#define HOWARD_EPSILON 1e-3
#define ZERO_SLOP 1e-5
#define REMOVE_ZERO_SLOP( x ) \
(x = (x > -ZERO_SLOP && x < ZERO_SLOP)?0:x)
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes maximum mean cycle time.]
Description [Uses Howard's algorithm.]
SideEffects []
SeeAlso []
***********************************************************************/
float Seq_NtkHoward( Abc_Ntk_t * pNtk, int fVerbose ) {
Abc_Obj_t * pObj;
Hash_Ptr_t * hFwdDelays;
Hash_Flt_t * hOutgoing;
Hash_Ptr_Entry_t * pSourceEntry, * pNodeEntry;
Hash_Flt_Entry_t * pSinkEntry;
int i, j, iteration = 0;
int source, sink;
int fChanged;
int howardDepth, howardSink = 0;
float delay, howardDelay, t;
float maxMeanCycle = -ABC_INFINITY;
Hash_Ptr_t * hNodeData;
Seq_HowardData_t * pNodeData, * pSourceData, * pSinkData;
// gather timing constraints
hFwdDelays = Seq_NtkPathDelays( pNtk, fVerbose );
Seq_NtkMergePios( pNtk, hFwdDelays, fVerbose );
// initialize data, create initial policy
hNodeData = Hash_PtrAlloc( hFwdDelays->nSize );
Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) {
Hash_PtrWriteEntry( hNodeData, pSourceEntry->key,
(pNodeData = ALLOC(Seq_HowardData_t, 1)) );
pNodeData->skew = 0.0;
pNodeData->policy = 0;
hOutgoing = (Hash_Flt_t *)(pSourceEntry->data);
assert(hOutgoing);
Hash_FltForEachEntry( hOutgoing, pSinkEntry, j ) {
sink = pSinkEntry->key;
delay = pSinkEntry->data;
if (delay > pNodeData->skew) {
pNodeData->policy = sink;
pNodeData->skew = delay;
}
}
}
// iteratively refine policy
do {
iteration++;
fChanged = 0;
howardDelay = 0.0;
howardDepth = 0;
// reset data
Hash_PtrForEachEntry( hNodeData, pNodeEntry, i ) {
pNodeData = (Seq_HowardData_t *)pNodeEntry->data;
pNodeData->skew = -ABC_INFINITY;
pNodeData->cycle = -ABC_INFINITY;
pNodeData->mark = 0;
pNodeData->visited = 0;
}
// find loops in policy graph
Hash_PtrForEachEntry( hNodeData, pNodeEntry, i ) {
pNodeData = (Seq_HowardData_t *)(pNodeEntry->data);
assert(pNodeData);
if (!pNodeData->visited)
Seq_NtkHowardLoop( pNtk, hFwdDelays,
hNodeData, pNodeEntry->key,
&howardDepth, &howardDelay, &howardSink, &maxMeanCycle);
}
if (!howardSink) {
return -1;
}
// improve policy by tightening loops
Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) {
source = pSourceEntry->key;
pSourceData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, source, 0 );
assert(pSourceData);
hOutgoing = (Hash_Flt_t *)(pSourceEntry->data);
assert(hOutgoing);
Hash_FltForEachEntry( hOutgoing, pSinkEntry, j ) {
sink = pSinkEntry->key;
pSinkData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, sink, 0 );
assert(pSinkData);
delay = pSinkEntry->data;
if (pSinkData->cycle > pSourceData->cycle + HOWARD_EPSILON) {
fChanged = 1;
pSourceData->cycle = pSinkData->cycle;
pSourceData->policy = sink;
}
}
}
// improve policy by correcting skews
if (!fChanged) {
Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) {
source = pSourceEntry->key;
pSourceData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, source, 0 );
assert(pSourceData);
hOutgoing = (Hash_Flt_t *)(pSourceEntry->data);
assert(hOutgoing);
Hash_FltForEachEntry( hOutgoing, pSinkEntry, j ) {
sink = pSinkEntry->key;
pSinkData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, sink, 0 );
assert(pSinkData);
delay = pSinkEntry->data;
if (pSinkData->cycle < 0.0 || pSinkData->cycle < pSourceData->cycle)
continue;
t = delay - pSinkData->cycle + pSinkData->skew;
if (t > pSourceData->skew + HOWARD_EPSILON) {
fChanged = 1;
pSourceData->skew = t;
pSourceData->policy = sink;
}
}
}
}
if (fVerbose) printf("Iteration %d \t Period = %.2f\n", iteration, maxMeanCycle);
} while (fChanged);
// set global skew, mmct
pNodeData = Hash_PtrEntry( hNodeData, -1, 0 );
pNtk->globalSkew = -pNodeData->skew;
pNtk->maxMeanCycle = maxMeanCycle;
// set endpoint skews
Vec_FltGrow( pNtk->vSkews, Abc_NtkLatchNum( pNtk ) );
pNtk->vSkews->nSize = Abc_NtkLatchNum( pNtk );
Abc_NtkForEachLatch( pNtk, pObj, i ) {
pNodeData = Hash_PtrEntry( hNodeData, pObj->Id, 0 );
// skews are set based on latch # NOT id #
Abc_NtkSetLatSkew( pNtk, i, pNodeData->skew );
}
// free node data
Hash_PtrForEachEntry( hNodeData, pNodeEntry, i ) {
pNodeData = (Seq_HowardData_t *)(pNodeEntry->data);
FREE( pNodeData );
}
Hash_PtrFree(hNodeData);
// free delay data
Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) {
Hash_FltFree( (Hash_Flt_t *)(pSourceEntry->data) );
}
Hash_PtrFree(hFwdDelays);
return maxMeanCycle;
}
/**Function*************************************************************
Synopsis [Computes the mean cycle times of current policy graph.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkHowardLoop( Abc_Ntk_t * pNtk, Hash_Ptr_t * hFwdDelays,
Hash_Ptr_t * hNodeData, int node,
int *howardDepth, float *howardDelay, int *howardSink,
float *maxMeanCycle) {
Seq_HowardData_t * pNodeData, *pToData;
float delay, t;
pNodeData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, node, 0 );
assert(pNodeData);
pNodeData->visited = 1;
pNodeData->mark = ++(*howardDepth);
pNodeData->delay = (*howardDelay);
if (pNodeData->policy) {
pToData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, pNodeData->policy, 0 );
assert(pToData);
delay = Seq_NtkGetPathDelay( hFwdDelays, node, pNodeData->policy );
assert(delay > 0.0);
(*howardDelay) += delay;
if (pToData->mark) {
t = (*howardDelay - pToData->delay) / (*howardDepth - pToData->mark + 1);
pNodeData->cycle = t;
pNodeData->skew = 0.0;
if (*maxMeanCycle < t) {
*maxMeanCycle = t;
*howardSink = pNodeData->policy;
}
} else {
if(!pToData->visited) {
Seq_NtkHowardLoop(pNtk, hFwdDelays, hNodeData, pNodeData->policy,
howardDepth, howardDelay, howardSink, maxMeanCycle);
}
if(pToData->cycle > 0) {
t = delay - pToData->cycle + pToData->skew;
pNodeData->skew = t;
pNodeData->cycle = pToData->cycle;
}
}
}
*howardDelay = pNodeData->delay;
pNodeData->mark = 0;
--(*howardDepth);
}
/**Function*************************************************************
Synopsis [Computes the register-to-register delays.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Hash_Ptr_t * Seq_NtkPathDelays( Abc_Ntk_t * pNtk, int fVerbose ) {
Abc_Time_t * pTime, ** ppTimes;
Abc_Obj_t * pObj, * pDriver, * pStart, * pFanout;
Vec_Ptr_t * vNodes, * vEndpoints;
int i, j, nPaths = 0;
Hash_Flt_t * hOutgoing;
Hash_Ptr_t * hFwdDelays;
float nMaxPath = 0, nSumPath = 0;
extern void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk );
extern void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode );
if (fVerbose) printf("Gathering path delays...\n");
hFwdDelays = Hash_PtrAlloc( Abc_NtkCiNum( pNtk ) );
assert( Abc_NtkIsMappedLogic(pNtk) );
Abc_NtkTimePrepare( pNtk );
ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
vNodes = Vec_PtrAlloc( 100 );
vEndpoints = Vec_PtrAlloc( 100 );
// set the initial times (i.e. ignore all inputs)
Abc_NtkForEachObj( pNtk, pObj, i) {
pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
}
// starting at each Ci, compute timing forward
Abc_NtkForEachCi( pNtk, pStart, j ) {
hOutgoing = Hash_FltAlloc( 10 );
Hash_PtrWriteEntry( hFwdDelays, pStart->Id, (void *)(hOutgoing) );
// seed the starting point of interest
pTime = ppTimes[pStart->Id];
pTime->Fall = pTime->Rise = pTime->Worst = 0.0;
// find a DFS ordering from the start
Abc_NtkIncrementTravId( pNtk );
Abc_NodeSetTravIdCurrent( pStart );
pObj = Abc_ObjFanout0Ntk(pStart);
Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_NtkDfsReverse_rec2( pFanout, vNodes, vEndpoints );
if ( Abc_ObjIsCo( pStart ) )
Vec_PtrPush( vEndpoints, pStart );
// do timing analysis
for ( i = vNodes->nSize-1; i >= 0; --i )
Abc_NodeDelayTraceArrival( vNodes->pArray[i] );
// there is a path to each set of Co endpoints
Vec_PtrForEachEntry( vEndpoints, pObj, i )
{
assert(pObj);
assert( Abc_ObjIsCo( pObj ) );
pDriver = Abc_ObjFanin0(pObj);
pTime = Abc_NodeArrival(pDriver);
if ( pTime->Worst > 0 ) {
Hash_FltWriteEntry( hOutgoing, pObj->Id, pTime->Worst );
nPaths++;
// if (fVerbose) printf("\tpath %d,%d delay = %f\n", pStart->Id, pObj->Id, pTime->Worst);
nSumPath += pTime->Worst;
if (pTime->Worst > nMaxPath)
nMaxPath = pTime->Worst;
}
}
// clear the times that were altered
for ( i = 0; i < vNodes->nSize; i++ ) {
pObj = (Abc_Obj_t *)(vNodes->pArray[i]);
pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
}
pTime = ppTimes[pStart->Id];
pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
Vec_PtrClear( vNodes );
Vec_PtrClear( vEndpoints );
}
Vec_PtrFree( vNodes );
// rezero Cis (note: these should be restored to values if they were nonzero)
Abc_NtkForEachCi( pNtk, pObj, i) {
pTime = ppTimes[pObj->Id];
pTime->Fall = pTime->Rise = pTime->Worst = 0.0;
}
if (fVerbose) printf("Num. paths = %d\tMax. Path Delay = %.2f\tAvg. Path Delay = %.2f\n", nPaths, nMaxPath, nSumPath / nPaths);
return hFwdDelays;
}
/**Function*************************************************************
Synopsis [Merges all the Pios together into one ID = -1.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkMergePios( Abc_Ntk_t * pNtk, Hash_Ptr_t * hFwdDelays,
int fVerbose ) {
Abc_Obj_t * pObj;
Hash_Flt_Entry_t * pSinkEntry;
Hash_Ptr_Entry_t * pSourceEntry;
Hash_Flt_t * hOutgoing, * hPioSource;
int i, j;
int source, sink, nMerges = 0;
float delay = 0, max_delay = 0;
Vec_Int_t * vFreeList;
vFreeList = Vec_IntAlloc( 10 );
// create a new "-1" source entry for the Pios
hPioSource = Hash_FltAlloc( 100 );
Hash_PtrWriteEntry( hFwdDelays, -1, (void *)(hPioSource) );
// merge all edges with a Pio as a source
Abc_NtkForEachPi( pNtk, pObj, i ) {
source = pObj->Id;
hOutgoing = (Hash_Flt_t *)Hash_PtrEntry( hFwdDelays, source, 0 );
if (!hOutgoing) continue;
Hash_PtrForEachEntry( hOutgoing, pSinkEntry, j ) {
nMerges++;
sink = pSinkEntry->key;
delay = pSinkEntry->data;
if (Hash_FltEntry( hPioSource, sink, 1 ) < delay) {
Hash_FltWriteEntry( hPioSource, sink, delay );
}
}
Hash_FltFree( hOutgoing );
Hash_PtrRemove( hFwdDelays, source );
}
// merge all edges with a Pio as a sink
Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) {
hOutgoing = (Hash_Flt_t *)(pSourceEntry->data);
Hash_FltForEachEntry( hOutgoing, pSinkEntry, j ) {
sink = pSinkEntry->key;
delay = pSinkEntry->data;
max_delay = -ABC_INFINITY;
if (Abc_ObjIsPo( Abc_NtkObj( pNtk, sink ) )) {
nMerges++;
if (delay > max_delay)
max_delay = delay;
Vec_IntPush( vFreeList, sink );
}
}
if (max_delay != -ABC_INFINITY)
Hash_FltWriteEntry( hOutgoing, -1, delay );
// do freeing
while( vFreeList->nSize > 0 ) {
Hash_FltRemove( hOutgoing, Vec_IntPop( vFreeList ) );
}
}
if (fVerbose) printf("Merged %d paths into one Pio node\n", nMerges);
}
/**Function*************************************************************
Synopsis [This is a modification of routine from abcDfs.c]
Description [Recursive DFS from a starting point. Keeps the endpoints.]
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkDfsReverse_rec2( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vEndpoints )
{
Abc_Obj_t * pFanout;
int i;
assert( !Abc_ObjIsNet(pNode) );
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// terminate at the Co
if ( Abc_ObjIsCo(pNode) ) {
Vec_PtrPush( vEndpoints, pNode );
return;
}
assert( Abc_ObjIsNode( pNode ) );
// visit the transitive fanin of the node
pNode = Abc_ObjFanout0Ntk(pNode);
Abc_ObjForEachFanout( pNode, pFanout, i )
Abc_NtkDfsReverse_rec2( pFanout, vNodes, vEndpoints );
// add the node after the fanins have been added
Vec_PtrPush( vNodes, pNode );
}
/**Function*************************************************************
Synopsis [Converts all skews into forward skews 0<skew<T.]
Description [Can also minimize total skew by changing global skew.]
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NtkSkewForward( Abc_Ntk_t * pNtk, float period, int fMinimize ) {
Abc_Obj_t * pObj;
int i;
float skew;
float currentSum = 0, bestSum = ABC_INFINITY;
float currentOffset = 0, nextStep, bestOffset = 0;
assert( pNtk->vSkews->nSize >= Abc_NtkLatchNum( pNtk )-1 );
if (fMinimize) {
// search all offsets for the one that minimizes sum of skews
while(currentOffset < period) {
currentSum = 0;
nextStep = period;
Abc_NtkForEachLatch( pNtk, pObj, i ) {
skew = Abc_NtkGetLatSkew( pNtk, i ) + currentOffset;
skew = (float)(skew - period*floor(skew/period));
currentSum += skew;
if (skew > ZERO_SLOP && skew < nextStep) {
nextStep = skew;
}
}
if (currentSum < bestSum) {
bestSum = currentSum;
bestOffset = currentOffset;
}
currentOffset += nextStep;
}
printf("Offseting all skews by %.2f\n", bestOffset);
}
// convert global skew into forward skew
pNtk->globalSkew = pNtk->globalSkew - bestOffset;
pNtk->globalSkew = (float)(pNtk->globalSkew - period*floor(pNtk->globalSkew/period));
assert(pNtk->globalSkew>= 0 && pNtk->globalSkew < period);
// convert endpoint skews into forward skews
Abc_NtkForEachLatch( pNtk, pObj, i ) {
skew = Abc_NtkGetLatSkew( pNtk, i ) + bestOffset;
skew = (float)(skew - period*floor(skew/period));
REMOVE_ZERO_SLOP( skew );
assert(skew >=0 && skew < period);
Abc_NtkSetLatSkew( pNtk, i, skew );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -110,7 +110,7 @@ Abc_Ntk_t * Seq_NtkRetimeDerive( Abc_Ntk_t * pNtk, int fVerbose )
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
printf( "Seq_NtkRetimeDerive(): Converting to SOPs has failed.\n" );
return NULL;
}
}
@ -140,7 +140,7 @@ Abc_Ntk_t * Seq_NtkRetimeDerive( Abc_Ntk_t * pNtk, int fVerbose )
{
if ( pObj->Id == 0 )
{
pObj->pCopy = Abc_NtkConst1(pNtkNew);
pObj->pCopy = Abc_AigConst1(pNtkNew);
continue;
}
pObj->pCopy = Abc_NtkCreateNode( pNtkNew );
@ -275,9 +275,9 @@ Abc_Obj_t * Seq_NodeRetimeDerive( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pRoot, char *
if ( nFanins < 2 )
{
if ( Abc_SopIsConst1(pSop) )
pFanin = Abc_NtkConst1(pNtkNew);
pFanin = Abc_AigConst1(pNtkNew);
else if ( Abc_SopIsConst0(pSop) )
pFanin = Abc_ObjNot( Abc_NtkConst1(pNtkNew) );
pFanin = Abc_ObjNot( Abc_AigConst1(pNtkNew) );
else if ( Abc_SopIsBuf(pSop) )
pFanin = Abc_ObjFanin0(pRoot)->pCopy;
else if ( Abc_SopIsInv(pSop) )
@ -342,8 +342,8 @@ Abc_Ntk_t * Seq_NtkRetimeReconstruct( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkSeq )
pNtkNew = Abc_NtkStartFrom( pNtkSeq, pNtkOld->ntkType, pNtkOld->ntkFunc );
// transfer the pointers to the old network
if ( Abc_NtkConst1(pNtkOld) )
Abc_NtkConst1(pNtkOld)->pCopy = Abc_NtkConst1(pNtkNew);
if ( Abc_AigConst1(pNtkOld) )
Abc_AigConst1(pNtkOld)->pCopy = Abc_AigConst1(pNtkNew);
Abc_NtkForEachPi( pNtkOld, pObj, i )
pObj->pCopy = pObj->pNext->pCopy;
Abc_NtkForEachPo( pNtkOld, pObj, i )
@ -433,7 +433,7 @@ Abc_Obj_t * Seq_EdgeReconstruct_rec( Abc_Obj_t * pGoal, Abc_Obj_t * pNode )
Seq_Lat_t * pRing;
Abc_Obj_t * pFanin, * pRes = NULL;
if ( !Abc_NodeIsAigAnd(pNode) )
if ( !Abc_AigNodeIsAnd(pNode) )
return NULL;
// consider the first fanin

View File

@ -316,7 +316,7 @@ int Seq_NtkNodeUpdateLValue( Abc_Obj_t * pObj, float Fi, Vec_Ptr_t * vLeaves, Ve
void Seq_NodeRetimeSetLag_rec( Abc_Obj_t * pNode, char Lag )
{
Abc_Obj_t * pFanin;
if ( !Abc_NodeIsAigAnd(pNode) )
if ( !Abc_AigNodeIsAnd(pNode) )
return;
Seq_NodeSetLag( pNode, Lag );
// consider the first fanin

View File

@ -319,7 +319,7 @@ void Seq_NtkShareLatchesMapping( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_
// create the array of all nodes with sharable fanouts
vNodes = Vec_PtrAlloc( 100 );
Vec_PtrPush( vNodes, Abc_NtkConst1(pNtk) );
Vec_PtrPush( vNodes, Abc_AigConst1(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
Vec_PtrPush( vNodes, pObj );
if ( fFpga )

View File

@ -476,7 +476,7 @@ int Seq_MapComputeAreaFlows( Abc_Ntk_t * pNtk, int fVerbose )
void Seq_NtkReachNodesFromPos_rec( Abc_Obj_t * pAnd, Vec_Ptr_t * vNodes )
{
// skip if this is a non-PI node
if ( !Abc_NodeIsAigAnd(pAnd) )
if ( !Abc_AigNodeIsAnd(pAnd) )
return;
// skip a visited node
if ( Abc_NodeIsTravIdCurrent(pAnd) )
@ -505,7 +505,7 @@ void Seq_NtkReachNodesFromPis_rec( Abc_Obj_t * pAnd, Vec_Ptr_t * vNodes )
Abc_Obj_t * pFanout;
int k;
// skip if this is a non-PI node
if ( !Abc_NodeIsAigAnd(pAnd) )
if ( !Abc_AigNodeIsAnd(pAnd) )
return;
// skip a visited node
if ( Abc_NodeIsTravIdCurrent(pAnd) )
@ -546,7 +546,7 @@ Vec_Ptr_t * Seq_NtkReachNodes( Abc_Ntk_t * pNtk, int fFromPos )
else
{
// tranvers the reverse cone of the constant node
pObj = Abc_NtkConst1( pNtk );
pObj = Abc_AigConst1( pNtk );
Abc_ObjForEachFanout( pObj, pFanout, k )
Seq_NtkReachNodesFromPis_rec( pFanout, vNodes );
// tranvers the reverse cone of the PIs

View File

@ -69,8 +69,8 @@ void Pga_MappingMatches( Pga_Man_t * p, int Mode )
continue;
}
// skip constant node, it has no cuts
if ( Abc_NodeIsConst(pObj) )
continue;
// if ( Abc_NodeIsConst(pObj) )
// continue;
// get the cuts
clk = clock();
pList = Abc_NodeGetCutsRecursive( p->pManCut, pObj, 0, 0 );

View File

@ -166,6 +166,9 @@ extern DdNode * Extra_bddComputeRangeCube( DdManager * dd, int iStart, int i
extern DdNode * Extra_bddBitsToCube( DdManager * dd, int Code, int CodeWidth, DdNode ** pbVars, int fMsbFirst );
extern DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f );
extern int Extra_bddIsVar( DdNode * bFunc );
extern DdNode * Extra_bddCreateAnd( DdManager * dd, int nVars );
extern DdNode * Extra_bddCreateOr( DdManager * dd, int nVars );
extern DdNode * Extra_bddCreateExor( DdManager * dd, int nVars );
/*=== extraBddKmap.c ================================================================*/
@ -525,6 +528,18 @@ extern unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, i
/*=== extraUtilUtil.c ================================================================*/
#ifndef ABS
#define ABS(a) ((a) < 0 ? -(a) : (a))
#endif
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef ALLOC
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
#endif

View File

@ -802,9 +802,9 @@ DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f )
Description []
SideEffects [None]
SideEffects []
SeeAlso [Cudd_VectorSupport Cudd_Support]
SeeAlso []
******************************************************************************/
int Extra_bddIsVar( DdNode * bFunc )
@ -815,6 +815,82 @@ int Extra_bddIsVar( DdNode * bFunc )
return cuddIsConstant( cuddT(bFunc) ) && cuddIsConstant( Cudd_Regular(cuddE(bFunc)) );
}
/**Function********************************************************************
Synopsis [Creates AND composed of the first nVars of the manager.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
DdNode * Extra_bddCreateAnd( DdManager * dd, int nVars )
{
DdNode * bFunc, * bTemp;
int i;
bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc );
for ( i = 0; i < nVars; i++ )
{
bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
Cudd_RecursiveDeref( dd, bTemp );
}
Cudd_Deref( bFunc );
return bFunc;
}
/**Function********************************************************************
Synopsis [Creates OR composed of the first nVars of the manager.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
DdNode * Extra_bddCreateOr( DdManager * dd, int nVars )
{
DdNode * bFunc, * bTemp;
int i;
bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
for ( i = 0; i < nVars; i++ )
{
bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
Cudd_RecursiveDeref( dd, bTemp );
}
Cudd_Deref( bFunc );
return bFunc;
}
/**Function********************************************************************
Synopsis [Creates EXOR composed of the first nVars of the manager.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
DdNode * Extra_bddCreateExor( DdManager * dd, int nVars )
{
DdNode * bFunc, * bTemp;
int i;
bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
for ( i = 0; i < nVars; i++ )
{
bFunc = Cudd_bddXor( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
Cudd_RecursiveDeref( dd, bTemp );
}
Cudd_Deref( bFunc );
return bFunc;
}
/*---------------------------------------------------------------------------*/
/* Definition of internal functions */
/*---------------------------------------------------------------------------*/

65
src/misc/hash/hash.h Normal file
View File

@ -0,0 +1,65 @@
/**CFile****************************************************************
FileName [hash.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hash map.]
Synopsis [External declarations.]
Author [Aaron P. Hurst]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 16, 2005.]
Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $]
***********************************************************************/
#ifndef __HASH_H__
#define __HASH_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#define inline __inline // compatible with MS VS 6.0
#endif
#include "hashInt.h"
#include "hashFlt.h"
#include "hashPtr.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#ifndef ABS
#define ABS(a) ((a) < 0 ? -(a) : (a))
#endif
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
int Hash_DefaultHashFunc(int key, int nBins) {
return ABS( ( (key+11)*(key)*7+3 ) % nBins );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif

330
src/misc/hash/hashFlt.h Normal file
View File

@ -0,0 +1,330 @@
/**CFile****************************************************************
FileName [hashFlt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hash maps.]
Synopsis [Hash maps.]
Author [Aaron P. Hurst]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 16, 2006.]
Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $]
***********************************************************************/
#ifndef __HASH_FLT_H__
#define __HASH_FLT_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "extra.h"
extern int Hash_DefaultHashFunc(int key, int nBins);
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Hash_Flt_t_ Hash_Flt_t;
typedef struct Hash_Flt_Entry_t_ Hash_Flt_Entry_t;
struct Hash_Flt_Entry_t_
{
int key;
float data;
struct Hash_Flt_Entry_t_ * pNext;
};
struct Hash_Flt_t_
{
int nSize;
int nBins;
int (* fHash)(int key, int nBins);
Hash_Flt_Entry_t ** pArray;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define Hash_FltForEachEntry( pHash, pEntry, bin) \
for(bin=-1, pEntry=NULL; bin < pHash->nBins; (!pEntry)?(pEntry=pHash->pArray[++bin]):(pEntry=pEntry->pNext)) \
if (pEntry)
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates a hash map with the given number of bins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Hash_Flt_t * Hash_FltAlloc( int nBins )
{
Hash_Flt_t * p;
int i;
assert(nBins > 0);
p = ALLOC( Hash_Flt_t, 1);
p->nBins = nBins;
p->fHash = Hash_DefaultHashFunc;
p->nSize = 0;
p->pArray = ALLOC( Hash_Flt_Entry_t *, nBins );
for(i=0; i<nBins; i++)
p->pArray[i] = NULL;
return p;
}
/**Function*************************************************************
Synopsis [Returns 1 if a key already exists.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Hash_FltExists( Hash_Flt_t *p, int key )
{
int bin;
Hash_Flt_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
return 1;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
return 0;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key and writes value.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_FltWriteEntry( Hash_Flt_t *p, int key, float data )
{
int bin;
Hash_Flt_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
pEntry->data = data;
return;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Flt_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = data;
return;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key.]
Description [fCreate specifies whether new entries should be created.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline float Hash_FltEntry( Hash_Flt_t *p, int key, int fCreate )
{
int bin;
Hash_Flt_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key)
return pEntry->data;
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
if (fCreate) {
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Flt_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = 0.0;
return pEntry->data;
}
return 0.0;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key and returns the pointer to it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline float* Hash_FltEntryPtr( Hash_Flt_t *p, int key )
{
int bin;
Hash_Flt_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key)
return &(pEntry->data);
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Flt_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = 0.0;
return &(pEntry->data);
}
/**Function*************************************************************
Synopsis [Deletes an entry.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_FltRemove( Hash_Flt_t *p, int key )
{
int bin;
Hash_Flt_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
p->nSize--;
*pLast = pEntry->pNext;
FREE( pEntry );
return;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// could not find key
return;
}
/**Function*************************************************************
Synopsis [Frees the hash.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_FltFree( Hash_Flt_t *p ) {
int bin;
Hash_Flt_Entry_t *pEntry;
// free bins
for(bin = 0; bin < p->nBins; bin++) {
pEntry = p->pArray[bin];
while(pEntry) {
pEntry = pEntry->pNext;
FREE( pEntry );
}
}
// free hash
FREE( p->pArray );
FREE( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif

293
src/misc/hash/hashInt.h Normal file
View File

@ -0,0 +1,293 @@
/**CFile****************************************************************
FileName [hashInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hash maps.]
Synopsis [Hash maps.]
Author [Aaron P. Hurst]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 16, 2006.]
Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $]
***********************************************************************/
#ifndef __HASH_INT_H__
#define __HASH_INT_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "extra.h"
extern int Hash_DefaultHashFunc(int key, int nBins);
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Hash_Int_t_ Hash_Int_t;
typedef struct Hash_Int_Entry_t_ Hash_Int_Entry_t;
struct Hash_Int_Entry_t_
{
int key;
int data;
struct Hash_Int_Entry_t_ * pNext;
};
struct Hash_Int_t_
{
int nSize;
int nBins;
int (* fHash)(int key, int nBins);
Hash_Int_Entry_t ** pArray;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define Hash_IntForEachEntry( pHash, pEntry, bin) \
for(bin=-1, pEntry=NULL; bin < pHash->nBins; (!pEntry)?(pEntry=pHash->pArray[++bin]):(pEntry=pEntry->pNext)) \
if (pEntry)
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates a hash map with the given number of bins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Hash_Int_t * Hash_IntAlloc( int nBins )
{
Hash_Int_t * p;
int i;
assert(nBins > 0);
p = ALLOC( Hash_Int_t, 1);
p->nBins = nBins;
p->fHash = Hash_DefaultHashFunc;
p->nSize = 0;
p->pArray = ALLOC( Hash_Int_Entry_t *, nBins );
for(i=0; i<nBins; i++)
p->pArray[i] = NULL;
return p;
}
/**Function*************************************************************
Synopsis [Returns 1 if a key already exists.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Hash_IntExists( Hash_Int_t *p, int key)
{
int bin;
Hash_Int_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
return 1;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
return 0;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key and writes value.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_IntWriteEntry( Hash_Int_t *p, int key, int data )
{
int bin;
Hash_Int_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
pEntry->data = data;
return;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Int_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = data;
return;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key.]
Description [fCreate specifies whether new entries will be created.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Hash_IntEntry( Hash_Int_t *p, int key, int fCreate )
{
int bin;
Hash_Int_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key)
return pEntry->data;
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
if (fCreate) {
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Int_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = 0;
return pEntry->data;
}
return 0;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key and returns the pointer to it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int* Hash_IntEntryPtr( Hash_Int_t *p, int key )
{
int bin;
Hash_Int_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key)
return &(pEntry->data);
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Int_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = 0;
return &(pEntry->data);
}
/**Function*************************************************************
Synopsis [Frees the hash.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_IntFree( Hash_Int_t *p ) {
int bin;
Hash_Int_Entry_t *pEntry;
// free bins
for(bin = 0; bin < p->nBins; bin++) {
pEntry = p->pArray[bin];
while(pEntry) {
pEntry = pEntry->pNext;
FREE( pEntry );
}
}
// free hash
FREE( p->pArray );
FREE( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif

331
src/misc/hash/hashPtr.h Normal file
View File

@ -0,0 +1,331 @@
/**CFile****************************************************************
FileName [hashFlt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hash maps.]
Synopsis [Hash maps.]
Author [Aaron P. Hurst]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 16, 2006.]
Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $]
***********************************************************************/
#ifndef __HASH_PTR_H__
#define __HASH_PTR_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "extra.h"
extern int Hash_DefaultHashFunc(int key, int nBins);
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Hash_Ptr_t_ Hash_Ptr_t;
typedef struct Hash_Ptr_Entry_t_ Hash_Ptr_Entry_t;
struct Hash_Ptr_Entry_t_
{
int key;
void * data;
struct Hash_Ptr_Entry_t_ * pNext;
};
struct Hash_Ptr_t_
{
int nSize;
int nBins;
int (* fHash)(int key, int nBins);
Hash_Ptr_Entry_t ** pArray;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define Hash_PtrForEachEntry( pHash, pEntry, bin ) \
for(bin=-1, pEntry=NULL; bin < pHash->nBins; (!pEntry)?(pEntry=pHash->pArray[++bin]):(pEntry=pEntry->pNext)) \
if (pEntry)
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates a hash map with the given number of bins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Hash_Ptr_t * Hash_PtrAlloc( int nBins )
{
Hash_Ptr_t * p;
int i;
assert(nBins > 0);
p = ALLOC( Hash_Ptr_t, 1);
p->nBins = nBins;
p->fHash = Hash_DefaultHashFunc;
p->nSize = 0;
p->pArray = ALLOC( Hash_Ptr_Entry_t *, nBins );
for(i=0; i<nBins; i++)
p->pArray[i] = NULL;
return p;
}
/**Function*************************************************************
Synopsis [Returns 1 if a key already exists.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Hash_PtrExists( Hash_Ptr_t *p, int key )
{
int bin;
Hash_Ptr_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
return 1;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
return 0;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key and writes value.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_PtrWriteEntry( Hash_Ptr_t *p, int key, void * data )
{
int bin;
Hash_Ptr_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
pEntry->data = data;
return;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = data;
return;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key.]
Description [fCreate specifies whether a new entry should be created.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void * Hash_PtrEntry( Hash_Ptr_t *p, int key, int fCreate )
{
int bin;
Hash_Ptr_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key)
return pEntry->data;
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
if (fCreate) {
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = NULL;
return pEntry->data;
}
return NULL;
}
/**Function*************************************************************
Synopsis [Finds or creates an entry with a key and returns the pointer to it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void** Hash_PtrEntryPtr( Hash_Ptr_t *p, int key )
{
int bin;
Hash_Ptr_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key)
return &(pEntry->data);
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// this key does not currently exist
// create a new entry and add to bin
p->nSize++;
(*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 );
pEntry->pNext = NULL;
pEntry->key = key;
pEntry->data = NULL;
return &(pEntry->data);
}
/**Function*************************************************************
Synopsis [Deletes an entry.]
Description [Returns data, if there was any.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void* Hash_PtrRemove( Hash_Ptr_t *p, int key )
{
int bin;
void * data;
Hash_Ptr_Entry_t *pEntry, **pLast;
// find the bin where this key would live
bin = (*(p->fHash))(key, p->nBins);
// search for key
pLast = &(p->pArray[bin]);
pEntry = p->pArray[bin];
while(pEntry) {
if (pEntry->key == key) {
p->nSize--;
data = pEntry->data;
*pLast = pEntry->pNext;
return data;
}
pLast = &(pEntry->pNext);
pEntry = pEntry->pNext;
}
// could not find key
return NULL;
}
/**Function*************************************************************
Synopsis [Frees the hash.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Hash_PtrFree( Hash_Ptr_t *p ) {
int bin;
Hash_Ptr_Entry_t *pEntry;
// free bins
for(bin = 0; bin < p->nBins; bin++) {
pEntry = p->pArray[bin];
while(pEntry) {
pEntry = pEntry->pNext;
FREE( pEntry );
}
}
// free hash
FREE( p->pArray );
FREE( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif

View File

@ -0,0 +1 @@
SRC +=

View File

@ -34,6 +34,7 @@ extern "C" {
#endif
#include "vecInt.h"
#include "vecFlt.h"
#include "vecStr.h"
#include "vecPtr.h"
#include "vecVec.h"

666
src/misc/vec/vecFlt.h Normal file
View File

@ -0,0 +1,666 @@
/**CFile****************************************************************
FileName [vecFlt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Resizable arrays.]
Synopsis [Resizable arrays of floats.]
Author [Aaron P. Hurst]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __VEC_FLT_H__
#define __VEC_FLT_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "extra.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Vec_Flt_t_ Vec_Flt_t;
struct Vec_Flt_t_
{
int nCap;
int nSize;
float * pArray;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define Vec_FltForEachEntry( vVec, Entry, i ) \
for ( i = 0; (i < Vec_FltSize(vVec)) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
#define Vec_FltForEachEntryStart( vVec, Entry, i, Start ) \
for ( i = Start; (i < Vec_FltSize(vVec)) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
#define Vec_FltForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \
for ( i = Start; (i < Stop) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
#define Vec_FltForEachEntryReverse( vVec, pEntry, i ) \
for ( i = Vec_FltSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_FltEntry(vVec, i)), 1); i-- )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates a vector with the given capacity.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Flt_t * Vec_FltAlloc( int nCap )
{
Vec_Flt_t * p;
p = ALLOC( Vec_Flt_t, 1 );
if ( nCap > 0 && nCap < 16 )
nCap = 16;
p->nSize = 0;
p->nCap = nCap;
p->pArray = p->nCap? ALLOC( float, p->nCap ) : NULL;
return p;
}
/**Function*************************************************************
Synopsis [Allocates a vector with the given size and cleans it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Flt_t * Vec_FltStart( int nSize )
{
Vec_Flt_t * p;
p = Vec_FltAlloc( nSize );
p->nSize = nSize;
memset( p->pArray, 0, sizeof(float) * nSize );
return p;
}
/**Function*************************************************************
Synopsis [Creates the vector from a float array of the given size.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Flt_t * Vec_FltAllocArray( float * pArray, int nSize )
{
Vec_Flt_t * p;
p = ALLOC( Vec_Flt_t, 1 );
p->nSize = nSize;
p->nCap = nSize;
p->pArray = pArray;
return p;
}
/**Function*************************************************************
Synopsis [Creates the vector from a float array of the given size.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Flt_t * Vec_FltAllocArrayCopy( float * pArray, int nSize )
{
Vec_Flt_t * p;
p = ALLOC( Vec_Flt_t, 1 );
p->nSize = nSize;
p->nCap = nSize;
p->pArray = ALLOC( float, nSize );
memcpy( p->pArray, pArray, sizeof(float) * nSize );
return p;
}
/**Function*************************************************************
Synopsis [Duplicates the float array.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Flt_t * Vec_FltDup( Vec_Flt_t * pVec )
{
Vec_Flt_t * p;
p = ALLOC( Vec_Flt_t, 1 );
p->nSize = pVec->nSize;
p->nCap = pVec->nCap;
p->pArray = p->nCap? ALLOC( float, p->nCap ) : NULL;
memcpy( p->pArray, pVec->pArray, sizeof(float) * pVec->nSize );
return p;
}
/**Function*************************************************************
Synopsis [Transfers the array into another vector.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Flt_t * Vec_FltDupArray( Vec_Flt_t * pVec )
{
Vec_Flt_t * p;
p = ALLOC( Vec_Flt_t, 1 );
p->nSize = pVec->nSize;
p->nCap = pVec->nCap;
p->pArray = pVec->pArray;
pVec->nSize = 0;
pVec->nCap = 0;
pVec->pArray = NULL;
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltFree( Vec_Flt_t * p )
{
FREE( p->pArray );
FREE( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline float * Vec_FltReleaseArray( Vec_Flt_t * p )
{
float * pArray = p->pArray;
p->nCap = 0;
p->nSize = 0;
p->pArray = NULL;
return pArray;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline float * Vec_FltArray( Vec_Flt_t * p )
{
return p->pArray;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_FltSize( Vec_Flt_t * p )
{
return p->nSize;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline float Vec_FltEntry( Vec_Flt_t * p, int i )
{
assert( i >= 0 && i < p->nSize );
return p->pArray[i];
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltWriteEntry( Vec_Flt_t * p, int i, float Entry )
{
assert( i >= 0 && i < p->nSize );
p->pArray[i] = Entry;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltAddToEntry( Vec_Flt_t * p, int i, float Addition )
{
assert( i >= 0 && i < p->nSize );
p->pArray[i] += Addition;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline float Vec_FltEntryLast( Vec_Flt_t * p )
{
return p->pArray[p->nSize-1];
}
/**Function*************************************************************
Synopsis [Resizes the vector to the given capacity.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltGrow( Vec_Flt_t * p, int nCapMin )
{
if ( p->nCap >= nCapMin )
return;
p->pArray = REALLOC( float, p->pArray, nCapMin );
p->nCap = nCapMin;
}
/**Function*************************************************************
Synopsis [Fills the vector with given number of entries.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltFill( Vec_Flt_t * p, int nSize, float Entry )
{
int i;
Vec_FltGrow( p, nSize );
for ( i = 0; i < nSize; i++ )
p->pArray[i] = Entry;
p->nSize = nSize;
}
/**Function*************************************************************
Synopsis [Fills the vector with given number of entries.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltFillExtra( Vec_Flt_t * p, int nSize, float Entry )
{
int i;
if ( p->nSize >= nSize )
return;
Vec_FltGrow( p, nSize );
for ( i = p->nSize; i < nSize; i++ )
p->pArray[i] = Entry;
p->nSize = nSize;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltShrink( Vec_Flt_t * p, int nSizeNew )
{
assert( p->nSize >= nSizeNew );
p->nSize = nSizeNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltClear( Vec_Flt_t * p )
{
p->nSize = 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltPush( Vec_Flt_t * p, float Entry )
{
if ( p->nSize == p->nCap )
{
if ( p->nCap < 16 )
Vec_FltGrow( p, 16 );
else
Vec_FltGrow( p, 2 * p->nCap );
}
p->pArray[p->nSize++] = Entry;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltPushMem( Extra_MmStep_t * pMemMan, Vec_Flt_t * p, float Entry )
{
if ( p->nSize == p->nCap )
{
float * pArray;
int i;
if ( p->nSize == 0 )
p->nCap = 1;
pArray = (float *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
// pArray = ALLOC( float, p->nCap * 2 );
if ( p->pArray )
{
for ( i = 0; i < p->nSize; i++ )
pArray[i] = p->pArray[i];
Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
// free( p->pArray );
}
p->nCap *= 2;
p->pArray = pArray;
}
p->pArray[p->nSize++] = Entry;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltPushOrder( Vec_Flt_t * p, float Entry )
{
int i;
if ( p->nSize == p->nCap )
{
if ( p->nCap < 16 )
Vec_FltGrow( p, 16 );
else
Vec_FltGrow( p, 2 * p->nCap );
}
p->nSize++;
for ( i = p->nSize-2; i >= 0; i-- )
if ( p->pArray[i] > Entry )
p->pArray[i+1] = p->pArray[i];
else
break;
p->pArray[i+1] = Entry;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_FltPushUnique( Vec_Flt_t * p, float Entry )
{
int i;
for ( i = 0; i < p->nSize; i++ )
if ( p->pArray[i] == Entry )
return 1;
Vec_FltPush( p, Entry );
return 0;
}
/**Function*************************************************************
Synopsis [Returns the last entry and removes it from the list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline float Vec_FltPop( Vec_Flt_t * p )
{
assert( p->nSize > 0 );
return p->pArray[--p->nSize];
}
/**Function*************************************************************
Synopsis [Find entry.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_FltFind( Vec_Flt_t * p, float Entry )
{
int i;
for ( i = 0; i < p->nSize; i++ )
if ( p->pArray[i] == Entry )
return i;
return -1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_FltRemove( Vec_Flt_t * p, float Entry )
{
int i;
for ( i = 0; i < p->nSize; i++ )
if ( p->pArray[i] == Entry )
break;
if ( i == p->nSize )
return 0;
assert( i < p->nSize );
for ( i++; i < p->nSize; i++ )
p->pArray[i-1] = p->pArray[i];
p->nSize--;
return 1;
}
/**Function*************************************************************
Synopsis [Comparison procedure for two floats.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_FltSortCompare1( float * pp1, float * pp2 )
{
// for some reason commenting out lines (as shown) led to crashing of the release version
if ( *pp1 < *pp2 )
return -1;
if ( *pp1 > *pp2 ) //
return 1;
return 0; //
}
/**Function*************************************************************
Synopsis [Comparison procedure for two floats.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_FltSortCompare2( float * pp1, float * pp2 )
{
// for some reason commenting out lines (as shown) led to crashing of the release version
if ( *pp1 > *pp2 )
return -1;
if ( *pp1 < *pp2 ) //
return 1;
return 0; //
}
/**Function*************************************************************
Synopsis [Sorting the entries by their value.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_FltSort( Vec_Flt_t * p, int fReverse )
{
if ( fReverse )
qsort( (void *)p->pArray, p->nSize, sizeof(float),
(int (*)(const void *, const void *)) Vec_FltSortCompare2 );
else
qsort( (void *)p->pArray, p->nSize, sizeof(float),
(int (*)(const void *, const void *)) Vec_FltSortCompare1 );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif

View File

@ -113,8 +113,8 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
continue;
}
// skip constant node, it has no cuts
if ( Abc_NodeIsConst(pObj) )
continue;
// if ( Abc_NodeIsConst(pObj) )
// continue;
Extra_ProgressBarUpdate( pProgress, i, NULL );
// compute the cuts to the internal node
Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
@ -125,7 +125,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
}
// add cuts due to choices
if ( Abc_NodeIsAigChoice(pObj) )
if ( Abc_AigNodeIsChoice(pObj) )
{
Vec_IntClear( vChoices );
for ( pNode = pObj; pNode; pNode = pNode->pData )
@ -187,8 +187,8 @@ void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p )
continue;
}
// skip constant node, it has no cuts
if ( Abc_NodeIsConst(pObj) )
continue;
// if ( Abc_NodeIsConst(pObj) )
// continue;
// compute the cuts to the internal node
Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
@ -234,7 +234,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
p = Cut_ManStart( pParams );
// set cuts for the constant node and the PIs
pObj = Abc_NtkConst1(pNtk);
pObj = Abc_AigConst1(pNtk);
if ( Abc_ObjFanoutNum(pObj) > 0 )
Cut_NodeSetTriv( p, pObj->Id );
Abc_NtkForEachPi( pNtk, pObj, i )
@ -263,7 +263,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
{
Abc_NodeGetCutsSeq( p, pObj, nIters==0 );
// add cuts due to choices
if ( Abc_NodeIsAigChoice(pObj) )
if ( Abc_AigNodeIsChoice(pObj) )
{
Vec_IntClear( vChoices );
for ( pNode = pObj; pNode; pNode = pNode->pData )

View File

@ -18,7 +18,6 @@
#include "abc.h"
#include "dec.h"
//#include "aig.h"
#include "ivy.h"
////////////////////////////////////////////////////////////////////////
@ -48,7 +47,7 @@ Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph )
int i;
// check for constant function
if ( Dec_GraphIsConst(pGraph) )
return Abc_ObjNotCond( Abc_NtkConst1(pNtk), Dec_GraphIsComplement(pGraph) );
return Abc_ObjNotCond( Abc_AigConst1(pNtk), Dec_GraphIsComplement(pGraph) );
// check for a literal
if ( Dec_GraphIsVar(pGraph) )
return Abc_ObjNotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
@ -82,7 +81,7 @@ Abc_Obj_t * Dec_GraphToNetworkNoStrash( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph )
int i;
// check for constant function
if ( Dec_GraphIsConst(pGraph) )
return Abc_ObjNotCond( Abc_NtkConst1(pNtk), Dec_GraphIsComplement(pGraph) );
return Abc_ObjNotCond( Abc_AigConst1(pNtk), Dec_GraphIsComplement(pGraph) );
// check for a literal
if ( Dec_GraphIsVar(pGraph) )
return Abc_ObjNotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
@ -159,7 +158,7 @@ int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa
LevelNew = 1 + ABC_MAX( pNode0->Level, pNode1->Level );
if ( pAnd )
{
if ( Abc_ObjRegular(pAnd) == Abc_NtkConst1(pRoot->pNtk) )
if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pRoot->pNtk) )
LevelNew = 0;
else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd0) )
LevelNew = (int)Abc_ObjRegular(pAnd0)->Level;
@ -215,11 +214,10 @@ void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, bool fUpda
SeeAlso []
***********************************************************************/
/*
Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph )
Aig_Obj_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph )
{
Dec_Node_t * pNode;
Aig_Node_t * pAnd0, * pAnd1;
Aig_Obj_t * pAnd0, * pAnd1;
int i;
// check for constant function
if ( Dec_GraphIsConst(pGraph) )
@ -237,7 +235,34 @@ Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph )
// complement the result if necessary
return Aig_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
}
*/
/**Function*************************************************************
Synopsis [Strashes one logic node using its SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t * Dec_GraphFactorSop( Aig_Man_t * pMan, char * pSop )
{
Aig_Obj_t * pFunc;
Dec_Graph_t * pFForm;
Dec_Node_t * pNode;
int i;
// perform factoring
pFForm = Dec_Factor( pSop );
// collect the fanins
Dec_GraphForEachLeaf( pFForm, pNode, i )
pNode->pFunc = Aig_IthVar( pMan, i );
// perform strashing
pFunc = Dec_GraphToNetworkAig( pMan, pFForm );
Dec_GraphFree( pFForm );
return pFunc;
}
/**Function*************************************************************
@ -250,7 +275,6 @@ Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph )
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
{
Dec_Node_t * pNode;

View File

@ -53,7 +53,7 @@ Vec_Ptr_t * Sim_SimulateSeqRandom( Abc_Ntk_t * pNtk, int nFrames, int nWords )
assert( Abc_NtkIsStrash(pNtk) );
vInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nWords * nFrames, 0 );
// set the constant data
pNode = Abc_NtkConst1(pNtk);
pNode = Abc_AigConst1(pNtk);
Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nWords * nFrames, 1 );
// set the random PI data
Abc_NtkForEachPi( pNtk, pNode, i )
@ -94,7 +94,7 @@ Vec_Ptr_t * Sim_SimulateSeqModel( Abc_Ntk_t * pNtk, int nFrames, int * pModel )
int i, k;
vInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nFrames, 0 );
// set the constant data
pNode = Abc_NtkConst1(pNtk);
pNode = Abc_AigConst1(pNtk);
Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nFrames, 1 );
// set the random PI data
Abc_NtkForEachPi( pNtk, pNode, i )

View File

@ -66,8 +66,8 @@ Vec_Ptr_t * Sim_ComputeStrSupp( Abc_Ntk_t * pNtk )
// derive the structural supports of the internal nodes
Abc_NtkForEachNode( pNtk, pNode, i )
{
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
pSimmNode = vSuppStr->pArray[ pNode->Id ];
pSimmNode1 = vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ];
pSimmNode2 = vSuppStr->pArray[ Abc_ObjFaninId1(pNode) ];

View File

@ -55,8 +55,8 @@ void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPat, Vec_Ptr_t * vMatrsNonSym
clk = clock();
Vec_PtrForEachEntry( p->vNodes, pNode, i )
{
if ( Abc_NodeIsConst(pNode) )
continue;
// if ( Abc_NodeIsConst(pNode) )
// continue;
Sim_UtilSimulateNodeOne( pNode, p->vSim, p->nSimWords, 0 );
}
p->timeSim += clock() - clk;
@ -65,7 +65,7 @@ clk = clock();
Abc_NtkForEachCo( p->pNtk, pNode, i )
{
pNode = Abc_ObjFanin0(pNode);
if ( Abc_ObjIsCi(pNode) || Abc_NodeIsConst(pNode) )
if ( Abc_ObjIsCi(pNode) || Abc_AigNodeIsConst(pNode) )
continue;
nPairsTotal = Vec_IntEntry(p->vPairsTotal, i);
nPairsSym = Vec_IntEntry(p->vPairsSym, i);

View File

@ -74,8 +74,8 @@ void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * v
vNodes = Abc_NtkDfs( pNtk, 0 );
Vec_PtrForEachEntry( vNodes, pTemp, i )
{
if ( Abc_NodeIsConst(pTemp) )
continue;
// if ( Abc_NodeIsConst(pTemp) )
// continue;
Sim_SymmsStructComputeOne( pNtk, pTemp, pMap );
}
// collect the results for the COs;
@ -83,7 +83,7 @@ void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * v
{
//printf( "Output %d:\n", i );
pTemp = Abc_ObjFanin0(pTemp);
if ( Abc_ObjIsCi(pTemp) || Abc_NodeIsConst(pTemp) )
if ( Abc_ObjIsCi(pTemp) || Abc_AigNodeIsConst(pTemp) )
continue;
Sim_SymmsTransferToMatrix( Vec_PtrEntry(vMatrs, i), SIM_READ_SYMMS(pTemp), Vec_PtrEntry(vSuppFun, i) );
}
@ -93,7 +93,7 @@ void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * v
Abc_NtkForEachCi( pNtk, pTemp, i )
Vec_IntFree( SIM_READ_SYMMS(pTemp) );
Vec_PtrForEachEntry( vNodes, pTemp, i )
if ( !Abc_NodeIsConst(pTemp) )
// if ( !Abc_NodeIsConst(pTemp) )
Vec_IntFree( SIM_READ_SYMMS(pTemp) );
Vec_PtrFree( vNodes );
free( pMap );

View File

@ -232,9 +232,6 @@ void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fT
// simulate the internal nodes
if ( Abc_ObjIsNode(pNode) )
{
if ( Abc_NodeIsConst(pNode) )
return;
if ( fType )
pSimmNode = p->vSim1->pArray[ pNode->Id ];
else
@ -305,8 +302,6 @@ void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimW
int k, fComp1, fComp2;
// simulate the internal nodes
assert( Abc_ObjIsNode(pNode) );
if ( Abc_NodeIsConst(pNode) )
return;
pSimmNode = Vec_PtrEntry(vSimInfo, pNode->Id);
pSimmNode1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode));
pSimmNode2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode));

View File

@ -1,377 +0,0 @@
/**CFile****************************************************************
FileName [aig.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aig.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __AIG_H__
#define __AIG_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
AIG is an And-Inv Graph with structural hashing.
It is always structurally hashed. It means that at any time:
- for each AND gate, there are no other AND gates with the same children
- the constants are propagated
- there is no single-input nodes (inverters/buffers)
Additionally the following invariants are satisfied:
- there are no dangling nodes (the nodes without fanout)
- the level of each AND gate reflects the levels of this fanins
- the AND nodes are in the topological order
- the constant 1 node has always number 0 in the object list
The operations that are performed on AIGs:
- building new nodes (Aig_And)
- performing elementary Boolean operations (Aig_Or, Aig_Xor, etc)
- replacing one node by another (Abc_AigReplace)
- propagating constants (Abc_AigReplace)
- deleting dangling nodes (Abc_AigDelete)
When AIG is duplicated, the new graph is structurally hashed too.
If this repeated hashing leads to fewer nodes, it means the original
AIG was not strictly hashed (one of the conditions above is violated).
*/
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "solver.h"
#include "vec.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
//typedef int bool;
#ifndef __cplusplus
#ifndef bool
#define bool int
#endif
#endif
typedef struct Aig_Param_t_ Aig_Param_t;
typedef struct Aig_Man_t_ Aig_Man_t;
typedef struct Aig_Node_t_ Aig_Node_t;
typedef struct Aig_Edge_t_ Aig_Edge_t;
typedef struct Aig_MemFixed_t_ Aig_MemFixed_t;
typedef struct Aig_SimInfo_t_ Aig_SimInfo_t;
typedef struct Aig_Table_t_ Aig_Table_t;
typedef struct Aig_Pattern_t_ Aig_Pattern_t;
// network types
typedef enum {
AIG_NONE = 0, // 0: unknown
AIG_PI, // 1: primary input
AIG_PO, // 2: primary output
AIG_AND // 3: internal node
} Aig_NodeType_t;
// proof outcomes
typedef enum {
AIG_PROOF_NONE = 0, // 0: unknown
AIG_PROOF_SAT, // 1: primary input
AIG_PROOF_UNSAT, // 2: primary output
AIG_PROOF_TIMEOUT, // 3: primary output
AIG_PROOF_FAIL // 4: internal node
} Aig_ProofType_t;
// the AIG parameters
struct Aig_Param_t_
{
int nPatsRand; // the number of random patterns
int nBTLimit; // backtrack limit at the intermediate nodes
int nSeconds; // the runtime limit at the final miter
int fVerbose; // verbosity
int fSatVerbose; // verbosity of SAT
};
// the AIG edge
struct Aig_Edge_t_
{
unsigned iNode : 31; // the node
unsigned fComp : 1; // the complemented attribute
};
// the AIG node
struct Aig_Node_t_ // 8 words
{
// various numbers associated with the node
int Id; // the unique number (SAT var number) of this node
int nRefs; // the reference counter
unsigned Type : 2; // the node type
unsigned fPhase : 1; // the phase of this node
unsigned fMarkA : 1; // the mask
unsigned fMarkB : 1; // the mask
unsigned fMarkC : 1; // the mask
unsigned TravId : 26; // the traversal ID
unsigned Level : 16; // the direct level of the node
unsigned LevelR : 16; // the reverse level of the node
Aig_Edge_t Fans[2]; // the fanins
int NextH; // next node in the hash table
int Data; // miscelleneous data
Aig_Man_t * pMan; // the parent manager
};
// the AIG manager
struct Aig_Man_t_
{
// the AIG parameters
Aig_Param_t Param; // the full set of AIG parameters
Aig_Param_t * pParam; // the pointer to the above set
// the nodes
Aig_Node_t * pConst1; // the constant 1 node (ID=0)
Vec_Ptr_t * vNodes; // all nodes by ID
Vec_Ptr_t * vPis; // all PIs
Vec_Ptr_t * vPos; // all POs
Aig_Table_t * pTable; // structural hash table
int nLevelMax; // the maximum level
// SAT solver and related structures
solver * pSat;
Vec_Int_t * vVar2Sat; // mapping of nodes into their SAT var numbers (for each node num)
Vec_Int_t * vSat2Var; // mapping of the SAT var numbers into nodes (for each SAT var)
Vec_Int_t * vPiSatNums; // the SAT variable numbers (for each PI)
int * pModel; // the satisfying assignment (for each PI)
int nMuxes; // the number of MUXes
// fanout representation
Vec_Ptr_t * vFanPivots; // fanout pivots
Vec_Ptr_t * vFanFans0; // the next fanout of the first fanin
Vec_Ptr_t * vFanFans1; // the next fanout of the second fanin
// the memory managers
Aig_MemFixed_t * mmNodes; // the memory manager for nodes
int nTravIds; // the traversal ID
// simulation info
Aig_SimInfo_t * pInfo; // random and systematic sim info for PIs
Aig_SimInfo_t * pInfoPi; // temporary sim info for the PI nodes
Aig_SimInfo_t * pInfoTemp; // temporary sim info for all nodes
Aig_Pattern_t * pPatMask; // the mask which shows what patterns are used
// simulation patterns
int nPiWords; // the number of words in the PI info
int nPatsMax; // the max number of patterns
Vec_Ptr_t * vPats; // simulation patterns to try
// equivalence classes
Vec_Vec_t * vClasses; // the non-trival equivalence classes of nodes
// temporary data
Vec_Ptr_t * vFanouts; // temporary storage for fanouts of a node
Vec_Ptr_t * vToReplace; // the nodes to replace
Vec_Int_t * vClassTemp; // temporary class representatives
};
// the simulation patter
struct Aig_Pattern_t_
{
int nBits;
int nWords;
unsigned * pData;
};
// the AIG simulation info
struct Aig_SimInfo_t_
{
int Type; // the type (0 = PI, 1 = all)
int nNodes; // the number of nodes for which allocated
int nWords; // the number of words for each node
int nPatsMax; // the maximum number of patterns
int nPatsCur; // the current number of patterns
unsigned * pData; // the simulation data
};
// iterators over nodes, PIs, POs, ANDs
#define Aig_ManForEachNode( pMan, pNode, i ) \
for ( i = 0; (i < Aig_ManNodeNum(pMan)) && (((pNode) = Aig_ManNode(pMan, i)), 1); i++ )
#define Aig_ManForEachPi( pMan, pNode, i ) \
for ( i = 0; (i < Aig_ManPiNum(pMan)) && (((pNode) = Aig_ManPi(pMan, i)), 1); i++ )
#define Aig_ManForEachPo( pMan, pNode, i ) \
for ( i = 0; (i < Aig_ManPoNum(pMan)) && (((pNode) = Aig_ManPo(pMan, i)), 1); i++ )
#define Aig_ManForEachAnd( pMan, pNode, i ) \
for ( i = 0; (i < Aig_ManNodeNum(pMan)) && (((pNode) = Aig_ManNode(pMan, i)), 1); i++ ) \
if ( !Aig_NodeIsAnd(pNode) ) {} else
// maximum/minimum operators
#define AIG_MIN(a,b) (((a) < (b))? (a) : (b))
#define AIG_MAX(a,b) (((a) > (b))? (a) : (b))
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
static inline int Aig_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
static inline void Aig_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
static inline void Aig_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
static inline Aig_Node_t * Aig_ManConst1( Aig_Man_t * pMan ) { return pMan->pConst1; }
static inline Aig_Node_t * Aig_ManNode( Aig_Man_t * pMan, int i ) { return Vec_PtrEntry(pMan->vNodes, i); }
static inline Aig_Node_t * Aig_ManPi( Aig_Man_t * pMan, int i ) { return Vec_PtrEntry(pMan->vPis, i); }
static inline Aig_Node_t * Aig_ManPo( Aig_Man_t * pMan, int i ) { return Vec_PtrEntry(pMan->vPos, i); }
static inline int Aig_ManNodeNum( Aig_Man_t * pMan ) { return Vec_PtrSize(pMan->vNodes); }
static inline int Aig_ManPiNum( Aig_Man_t * pMan ) { return Vec_PtrSize(pMan->vPis); }
static inline int Aig_ManPoNum( Aig_Man_t * pMan ) { return Vec_PtrSize(pMan->vPos); }
static inline int Aig_ManAndNum( Aig_Man_t * pMan ) { return Aig_ManNodeNum(pMan)-Aig_ManPiNum(pMan)-Aig_ManPoNum(pMan)-1; }
static inline Aig_Node_t * Aig_Regular( Aig_Node_t * p ) { return (Aig_Node_t *)((unsigned)(p) & ~01); }
static inline Aig_Node_t * Aig_Not( Aig_Node_t * p ) { return (Aig_Node_t *)((unsigned)(p) ^ 01); }
static inline Aig_Node_t * Aig_NotCond( Aig_Node_t * p, int c ) { return (Aig_Node_t *)((unsigned)(p) ^ (c)); }
static inline bool Aig_IsComplement( Aig_Node_t * p ) { return (bool)(((unsigned)p) & 01); }
static inline bool Aig_NodeIsConst( Aig_Node_t * pNode ) { return Aig_Regular(pNode)->Id == 0; }
static inline bool Aig_NodeIsPi( Aig_Node_t * pNode ) { return Aig_Regular(pNode)->Type == AIG_PI; }
static inline bool Aig_NodeIsPo( Aig_Node_t * pNode ) { return Aig_Regular(pNode)->Type == AIG_PO; }
static inline bool Aig_NodeIsAnd( Aig_Node_t * pNode ) { return Aig_Regular(pNode)->Type == AIG_AND; }
static inline int Aig_NodeId( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Id; }
static inline int Aig_NodeRefs( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->nRefs; }
static inline bool Aig_NodePhase( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->fPhase; }
static inline int Aig_NodeLevel( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Level; }
static inline int Aig_NodeLevelR( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->LevelR; }
static inline int Aig_NodeData( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Data; }
static inline Aig_Man_t * Aig_NodeMan( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->pMan; }
static inline int Aig_NodeFaninId0( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Fans[0].iNode; }
static inline int Aig_NodeFaninId1( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Fans[1].iNode; }
static inline bool Aig_NodeFaninC0( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Fans[0].fComp; }
static inline bool Aig_NodeFaninC1( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Fans[1].fComp; }
static inline Aig_Node_t * Aig_NodeFanin0( Aig_Node_t * pNode ) { return Aig_ManNode( Aig_NodeMan(pNode), Aig_NodeFaninId0(pNode) ); }
static inline Aig_Node_t * Aig_NodeFanin1( Aig_Node_t * pNode ) { return Aig_ManNode( Aig_NodeMan(pNode), Aig_NodeFaninId1(pNode) ); }
static inline Aig_Node_t * Aig_NodeChild0( Aig_Node_t * pNode ) { return Aig_NotCond( Aig_NodeFanin0(pNode), Aig_NodeFaninC0(pNode) ); }
static inline Aig_Node_t * Aig_NodeChild1( Aig_Node_t * pNode ) { return Aig_NotCond( Aig_NodeFanin1(pNode), Aig_NodeFaninC1(pNode) ); }
static inline Aig_Node_t * Aig_NodeNextH( Aig_Node_t * pNode ) { return pNode->NextH? Aig_ManNode(pNode->pMan, pNode->NextH) : NULL; }
static inline int Aig_NodeWhatFanin( Aig_Node_t * pNode, Aig_Node_t * pFanin ) { if ( Aig_NodeFaninId0(pNode) == pFanin->Id ) return 0; if ( Aig_NodeFaninId1(pNode) == pFanin->Id ) return 1; assert(0); return -1; }
static inline int Aig_NodeGetLevelNew( Aig_Node_t * pNode ) { return 1 + AIG_MAX(Aig_NodeFanin0(pNode)->Level, Aig_NodeFanin1(pNode)->Level); }
static inline int Aig_NodeRequiredLevel( Aig_Node_t * pNode ) { return pNode->pMan->nLevelMax + 1 - pNode->LevelR; }
static inline unsigned * Aig_SimInfoForNodeId( Aig_SimInfo_t * p, int NodeId ) { assert( p->Type ); return p->pData + p->nWords * NodeId; }
static inline unsigned * Aig_SimInfoForNode( Aig_SimInfo_t * p, Aig_Node_t * pNode ) { assert( p->Type ); return p->pData + p->nWords * pNode->Id; }
static inline unsigned * Aig_SimInfoForPi( Aig_SimInfo_t * p, int Num ) { assert( !p->Type ); return p->pData + p->nWords * Num; }
static inline void Aig_NodeSetTravId( Aig_Node_t * pNode, int TravId ) { pNode->TravId = TravId; }
static inline void Aig_NodeSetTravIdCurrent( Aig_Node_t * pNode ) { pNode->TravId = pNode->pMan->nTravIds; }
static inline void Aig_NodeSetTravIdPrevious( Aig_Node_t * pNode ) { pNode->TravId = pNode->pMan->nTravIds - 1; }
static inline bool Aig_NodeIsTravIdCurrent( Aig_Node_t * pNode ) { return (bool)((int)pNode->TravId == pNode->pMan->nTravIds); }
static inline bool Aig_NodeIsTravIdPrevious( Aig_Node_t * pNode ) { return (bool)((int)pNode->TravId == pNode->pMan->nTravIds - 1); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== aigCheck.c ==========================================================*/
extern bool Aig_ManCheck( Aig_Man_t * pMan );
extern bool Aig_NodeIsAcyclic( Aig_Node_t * pNode, Aig_Node_t * pRoot );
/*=== aigFanout.c ==========================================================*/
extern void Aig_ManCreateFanouts( Aig_Man_t * p );
extern void Aig_NodeAddFaninFanout( Aig_Node_t * pFanin, Aig_Node_t * pFanout );
extern void Aig_NodeRemoveFaninFanout( Aig_Node_t * pFanin, Aig_Node_t * pFanoutToRemove );
extern int Aig_NodeGetFanoutNum( Aig_Node_t * pNode );
extern Vec_Ptr_t * Aig_NodeGetFanouts( Aig_Node_t * pNode );
extern int Aig_NodeGetLevelRNew( Aig_Node_t * pNode );
extern int Aig_ManSetLevelR( Aig_Man_t * pMan );
extern int Aig_ManGetLevelMax( Aig_Man_t * pMan );
extern int Aig_NodeUpdateLevel_int( Aig_Node_t * pNode );
extern int Aig_NodeUpdateLevelR_int( Aig_Node_t * pNode );
/*=== aigMem.c =============================================================*/
extern Aig_MemFixed_t * Aig_MemFixedStart( int nEntrySize );
extern void Aig_MemFixedStop( Aig_MemFixed_t * p, int fVerbose );
extern char * Aig_MemFixedEntryFetch( Aig_MemFixed_t * p );
extern void Aig_MemFixedEntryRecycle( Aig_MemFixed_t * p, char * pEntry );
extern void Aig_MemFixedRestart( Aig_MemFixed_t * p );
extern int Aig_MemFixedReadMemUsage( Aig_MemFixed_t * p );
/*=== aigMan.c =============================================================*/
extern void Aig_ManSetDefaultParams( Aig_Param_t * pParam );
extern Aig_Man_t * Aig_ManStart( Aig_Param_t * pParam );
extern int Aig_ManCleanup( Aig_Man_t * pMan );
extern void Aig_ManStop( Aig_Man_t * p );
/*=== aigNode.c =============================================================*/
extern Aig_Node_t * Aig_NodeCreateConst( Aig_Man_t * p );
extern Aig_Node_t * Aig_NodeCreatePi( Aig_Man_t * p );
extern Aig_Node_t * Aig_NodeCreatePo( Aig_Man_t * p );
extern Aig_Node_t * Aig_NodeCreateAnd( Aig_Man_t * p, Aig_Node_t * pFanin0, Aig_Node_t * pFanin1 );
extern Aig_Node_t * Aig_NodeConnectPo( Aig_Man_t * p, Aig_Node_t * pNode, Aig_Node_t * pFanin );
extern void Aig_NodeConnectAnd( Aig_Node_t * pFanin0, Aig_Node_t * pFanin1, Aig_Node_t * pNode );
extern void Aig_NodeDisconnectAnd( Aig_Node_t * pNode );
extern void Aig_NodeDeleteAnd_rec( Aig_Man_t * pMan, Aig_Node_t * pRoot );
extern void Aig_NodePrint( Aig_Node_t * pNode );
extern char * Aig_NodeName( Aig_Node_t * pNode );
extern void Aig_PrintNode( Aig_Node_t * pNode );
/*=== aigOper.c ==========================================================*/
extern Aig_Node_t * Aig_And( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 );
extern Aig_Node_t * Aig_Or( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 );
extern Aig_Node_t * Aig_Xor( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 );
extern Aig_Node_t * Aig_Mux( Aig_Man_t * pMan, Aig_Node_t * pC, Aig_Node_t * p1, Aig_Node_t * p0 );
extern Aig_Node_t * Aig_Miter( Aig_Man_t * pMan, Vec_Ptr_t * vPairs );
/*=== aigReplace.c ==========================================================*/
extern void Aig_ManReplaceNode( Aig_Man_t * pMan, Aig_Node_t * pOld, Aig_Node_t * pNew, int fUpdateLevel );
/*=== aigTable.c ==========================================================*/
extern Aig_Table_t * Aig_TableCreate( int nSize );
extern void Aig_TableFree( Aig_Table_t * p );
extern int Aig_TableNumNodes( Aig_Table_t * p );
extern Aig_Node_t * Aig_TableLookupNode( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 );
extern Aig_Node_t * Aig_TableInsertNode( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1, Aig_Node_t * pAnd );
extern void Aig_TableDeleteNode( Aig_Man_t * pMan, Aig_Node_t * pThis );
extern void Aig_TableResize( Aig_Man_t * pMan );
extern void Aig_TableRehash( Aig_Man_t * pMan );
/*=== aigUtil.c ==========================================================*/
extern void Aig_ManIncrementTravId( Aig_Man_t * pMan );
extern bool Aig_NodeIsMuxType( Aig_Node_t * pNode );
extern Aig_Node_t * Aig_NodeRecognizeMux( Aig_Node_t * pNode, Aig_Node_t ** ppNodeT, Aig_Node_t ** ppNodeE );
/*=== fraigCore.c ==========================================================*/
extern Aig_ProofType_t Aig_FraigProve( Aig_Man_t * pMan );
/*=== fraigClasses.c ==========================================================*/
extern Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfoAll );
extern int Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses, Aig_Pattern_t * pPatMask );
extern void Aig_ManCollectPatterns( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Aig_Pattern_t * pMask, Vec_Ptr_t * vPats );
/*=== fraigCnf.c ==========================================================*/
extern Aig_ProofType_t Aig_ClauseSolverStart( Aig_Man_t * pMan );
/*=== fraigEngine.c ==========================================================*/
extern void Aig_EngineSimulateRandomFirst( Aig_Man_t * p );
extern void Aig_EngineSimulateFirst( Aig_Man_t * p );
extern int Aig_EngineSimulate( Aig_Man_t * p );
/*=== fraigSim.c ==========================================================*/
extern Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nBits, int Type );
extern void Aig_SimInfoClean( Aig_SimInfo_t * p );
extern void Aig_SimInfoRandom( Aig_SimInfo_t * p );
extern void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat );
extern void Aig_SimInfoResize( Aig_SimInfo_t * p );
extern void Aig_SimInfoFree( Aig_SimInfo_t * p );
extern void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t * pInfoAll );
extern Aig_Pattern_t * Aig_PatternAlloc( int nBits );
extern void Aig_PatternClean( Aig_Pattern_t * pPat );
extern void Aig_PatternFill( Aig_Pattern_t * pPat );
extern int Aig_PatternCount( Aig_Pattern_t * pPat );
extern void Aig_PatternRandom( Aig_Pattern_t * pPat );
extern void Aig_PatternFree( Aig_Pattern_t * pPat );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,47 +0,0 @@
/**CFile****************************************************************
FileName [aigBalance.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigBalance.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,146 +0,0 @@
/**CFile****************************************************************
FileName [aigCheck.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigCheck.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Makes sure that every node in the table is in the network and vice versa.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Aig_ManCheck( Aig_Man_t * pMan )
{
Aig_Node_t * pObj, * pAnd;
int i;
Aig_ManForEachNode( pMan, pObj, i )
{
if ( pObj == pMan->pConst1 || Aig_NodeIsPi(pObj) )
{
if ( pObj->Fans[0].iNode || pObj->Fans[1].iNode || pObj->Level )
{
printf( "Aig_ManCheck: The AIG has non-standard constant or PI node \"%d\".\n", pObj->Id );
return 0;
}
continue;
}
if ( Aig_NodeIsPo(pObj) )
{
if ( pObj->Fans[1].iNode )
{
printf( "Aig_ManCheck: The AIG has non-standard PO node \"%d\".\n", pObj->Id );
return 0;
}
continue;
}
// consider the AND node
if ( !pObj->Fans[0].iNode || !pObj->Fans[1].iNode )
{
printf( "Aig_ManCheck: The AIG has node \"%d\" with a constant fanin.\n", pObj->Id );
return 0;
}
if ( pObj->Fans[0].iNode > pObj->Fans[1].iNode )
{
printf( "Aig_ManCheck: The AIG has node \"%d\" with a wrong ordering of fanins.\n", pObj->Id );
return 0;
}
if ( pObj->Level != 1 + AIG_MAX(Aig_NodeFanin0(pObj)->Level, Aig_NodeFanin1(pObj)->Level) )
printf( "Aig_ManCheck: Node \"%d\" has level that does not agree with the fanin levels.\n", pObj->Id );
pAnd = Aig_TableLookupNode( pMan, Aig_NodeChild0(pObj), Aig_NodeChild1(pObj) );
if ( pAnd != pObj )
printf( "Aig_ManCheck: Node \"%d\" is not in the structural hashing table.\n", pObj->Id );
}
// count the number of nodes in the table
if ( Aig_TableNumNodes(pMan->pTable) != Aig_ManAndNum(pMan) )
{
printf( "Aig_ManCheck: The number of nodes in the structural hashing table is wrong.\n" );
return 0;
}
return 1;
}
/**Function*************************************************************
Synopsis [Check if the node has a combination loop of depth 1 or 2.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Aig_NodeIsAcyclic( Aig_Node_t * pNode, Aig_Node_t * pRoot )
{
Aig_Node_t * pFanin0, * pFanin1;
Aig_Node_t * pChild00, * pChild01;
Aig_Node_t * pChild10, * pChild11;
if ( !Aig_NodeIsAnd(pNode) )
return 1;
pFanin0 = Aig_NodeFanin0(pNode);
pFanin1 = Aig_NodeFanin1(pNode);
if ( pRoot == pFanin0 || pRoot == pFanin1 )
return 0;
if ( Aig_NodeIsPi(pFanin0) )
{
pChild00 = NULL;
pChild01 = NULL;
}
else
{
pChild00 = Aig_NodeFanin0(pFanin0);
pChild01 = Aig_NodeFanin1(pFanin0);
if ( pRoot == pChild00 || pRoot == pChild01 )
return 0;
}
if ( Aig_NodeIsPi(pFanin1) )
{
pChild10 = NULL;
pChild11 = NULL;
}
else
{
pChild10 = Aig_NodeFanin0(pFanin1);
pChild11 = Aig_NodeFanin1(pFanin1);
if ( pRoot == pChild10 || pRoot == pChild11 )
return 0;
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,423 +0,0 @@
/**CFile****************************************************************
FileName [aigFanout.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigFanout.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static inline Aig_Node_t * Aig_NodeFanPivot( Aig_Node_t * pNode ) { return Vec_PtrEntry(pNode->pMan->vFanPivots, pNode->Id); }
static inline Aig_Node_t * Aig_NodeFanFan0( Aig_Node_t * pNode ) { return Vec_PtrEntry(pNode->pMan->vFanFans0, pNode->Id); }
static inline Aig_Node_t * Aig_NodeFanFan1( Aig_Node_t * pNode ) { return Vec_PtrEntry(pNode->pMan->vFanFans1, pNode->Id); }
static inline Aig_Node_t ** Aig_NodeFanPivotPlace( Aig_Node_t * pNode ) { return ((Aig_Node_t **)pNode->pMan->vFanPivots->pArray) + pNode->Id; }
static inline Aig_Node_t ** Aig_NodeFanFan0Place( Aig_Node_t * pNode ) { return ((Aig_Node_t **)pNode->pMan->vFanFans0->pArray) + pNode->Id; }
static inline Aig_Node_t ** Aig_NodeFanFan1Place( Aig_Node_t * pNode ) { return ((Aig_Node_t **)pNode->pMan->vFanFans1->pArray) + pNode->Id; }
static inline void Aig_NodeSetFanPivot( Aig_Node_t * pNode, Aig_Node_t * pNode2 ) { Vec_PtrWriteEntry(pNode->pMan->vFanPivots, pNode->Id, pNode2); }
static inline void Aig_NodeSetFanFan0( Aig_Node_t * pNode, Aig_Node_t * pNode2 ) { Vec_PtrWriteEntry(pNode->pMan->vFanFans0, pNode->Id, pNode2); }
static inline void Aig_NodeSetFanFan1( Aig_Node_t * pNode, Aig_Node_t * pNode2 ) { Vec_PtrWriteEntry(pNode->pMan->vFanFans1, pNode->Id, pNode2); }
static inline Aig_Node_t * Aig_NodeNextFanout( Aig_Node_t * pNode, Aig_Node_t * pFanout ) { if ( pFanout == NULL ) return NULL; return Aig_NodeFaninId0(pFanout) == pNode->Id? Aig_NodeFanFan0(pFanout) : Aig_NodeFanFan1(pFanout); }
static inline Aig_Node_t ** Aig_NodeNextFanoutPlace( Aig_Node_t * pNode, Aig_Node_t * pFanout ) { return Aig_NodeFaninId0(pFanout) == pNode->Id? Aig_NodeFanFan0Place(pFanout) : Aig_NodeFanFan1Place(pFanout); }
// iterator through the fanouts of the node
#define Aig_NodeForEachFanout( pNode, pFanout ) \
for ( pFanout = Aig_NodeFanPivot(pNode); pFanout; \
pFanout = Aig_NodeNextFanout(pNode, pFanout) )
// safe iterator through the fanouts of the node
#define Aig_NodeForEachFanoutSafe( pNode, pFanout, pFanout2 ) \
for ( pFanout = Aig_NodeFanPivot(pNode), \
pFanout2 = Aig_NodeNextFanout(pNode, pFanout); \
pFanout; \
pFanout = pFanout2, \
pFanout2 = Aig_NodeNextFanout(pNode, pFanout) )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates the fanouts for all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManCreateFanouts( Aig_Man_t * p )
{
Aig_Node_t * pNode;
int i;
assert( p->vFanPivots == NULL );
p->vFanPivots = Vec_PtrStart( Aig_ManNodeNum(p) );
p->vFanFans0 = Vec_PtrStart( Aig_ManNodeNum(p) );
p->vFanFans1 = Vec_PtrStart( Aig_ManNodeNum(p) );
Aig_ManForEachNode( p, pNode, i )
{
if ( Aig_NodeIsPi(pNode) || i == 0 )
continue;
Aig_NodeAddFaninFanout( Aig_NodeFanin0(pNode), pNode );
if ( Aig_NodeIsPo(pNode) )
continue;
Aig_NodeAddFaninFanout( Aig_NodeFanin1(pNode), pNode );
}
}
/**Function*************************************************************
Synopsis [Creates the fanouts for all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Aig_ManResizeFanouts( Aig_Man_t * p, int nSizeNew )
{
assert( p->vFanPivots );
if ( Vec_PtrSize(p->vFanPivots) < nSizeNew )
{
Vec_PtrFillExtra( p->vFanPivots, nSizeNew + 1000, NULL );
Vec_PtrFillExtra( p->vFanFans0, nSizeNew + 1000, NULL );
Vec_PtrFillExtra( p->vFanFans1, nSizeNew + 1000, NULL );
}
}
/**Function*************************************************************
Synopsis [Add the fanout to the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeAddFaninFanout( Aig_Node_t * pFanin, Aig_Node_t * pFanout )
{
Aig_Node_t * pPivot;
// check that they are not complemented
assert( !Aig_IsComplement(pFanin) );
assert( !Aig_IsComplement(pFanout) );
// check that pFanins is a fanin of pFanout
assert( Aig_NodeFaninId0(pFanout) == pFanin->Id || Aig_NodeFaninId1(pFanout) == pFanin->Id );
// resize the fanout manager
Aig_ManResizeFanouts( pFanin->pMan, 1 + AIG_MAX(pFanin->Id, pFanout->Id) );
// consider the case of the first fanout
pPivot = Aig_NodeFanPivot(pFanin);
if ( pPivot == NULL )
{
Aig_NodeSetFanPivot( pFanin, pFanout );
return;
}
// consider the case of more than one fanouts
if ( Aig_NodeFaninId0(pPivot) == pFanin->Id )
{
if ( Aig_NodeFaninId0(pFanout) == pFanin->Id )
{
Aig_NodeSetFanFan0( pFanout, Aig_NodeFanFan0(pPivot) );
Aig_NodeSetFanFan0( pPivot, pFanout );
}
else // if ( Aig_NodeFaninId1(pFanout) == pFanin->Id )
{
Aig_NodeSetFanFan1( pFanout, Aig_NodeFanFan0(pPivot) );
Aig_NodeSetFanFan0( pPivot, pFanout );
}
}
else // if ( Aig_NodeFaninId1(pPivot) == pFanin->Id )
{
assert( Aig_NodeFaninId1(pPivot) == pFanin->Id );
if ( Aig_NodeFaninId0(pFanout) == pFanin->Id )
{
Aig_NodeSetFanFan0( pFanout, Aig_NodeFanFan1(pPivot) );
Aig_NodeSetFanFan1( pPivot, pFanout );
}
else // if ( Aig_NodeFaninId1(pFanout) == pFanin->Id )
{
Aig_NodeSetFanFan1( pFanout, Aig_NodeFanFan1(pPivot) );
Aig_NodeSetFanFan1( pPivot, pFanout );
}
}
}
/**Function*************************************************************
Synopsis [Add the fanout to the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeRemoveFaninFanout( Aig_Node_t * pFanin, Aig_Node_t * pFanoutToRemove )
{
Aig_Node_t * pFanout, * pFanout2, ** ppFanList;
// start the linked list of fanouts
ppFanList = Aig_NodeFanPivotPlace(pFanin);
// go through the fanouts
Aig_NodeForEachFanoutSafe( pFanin, pFanout, pFanout2 )
{
// skip the fanout-to-remove
if ( pFanout == pFanoutToRemove )
continue;
// add useful fanouts to the list
*ppFanList = pFanout;
ppFanList = Aig_NodeNextFanoutPlace( pFanin, pFanout );
}
*ppFanList = NULL;
}
/**Function*************************************************************
Synopsis [Returns the number of fanouts of a node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_NodeGetFanoutNum( Aig_Node_t * pNode )
{
Aig_Node_t * pFanout;
int Counter = 0;
Aig_NodeForEachFanout( pNode, pFanout )
Counter++;
return Counter;
}
/**Function*************************************************************
Synopsis [Collect fanouts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Aig_NodeGetFanouts( Aig_Node_t * pNode )
{
Aig_Node_t * pFanout;
Vec_PtrClear( pNode->pMan->vFanouts );
Aig_NodeForEachFanout( pNode, pFanout )
Vec_PtrPush( pNode->pMan->vFanouts, pFanout );
return pNode->pMan->vFanouts;
}
/**Function*************************************************************
Synopsis [Returns 1 if the node has at least one complemented fanout.]
Description [A fanout is complemented if the fanout's fanin edge pointing
to the given node is complemented.]
SideEffects []
SeeAlso []
***********************************************************************/
bool Aig_NodeHasComplFanoutEdge( Aig_Node_t * pNode )
{
Aig_Node_t * pFanout;
int iFanin;
Aig_NodeForEachFanout( pNode, pFanout )
{
iFanin = Aig_NodeWhatFanin( pFanout, pNode );
assert( iFanin >= 0 );
if ( iFanin && Aig_NodeFaninC1(pFanout) || !iFanin && Aig_NodeFaninC0(pFanout) )
return 1;
}
return 0;
}
/**Function*************************************************************
Synopsis [Recursively computes and assigns the reverse level of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static int Aig_NodeSetLevelR_rec( Aig_Node_t * pNode )
{
Aig_Node_t * pFanout;
int LevelR = 0;
if ( Aig_NodeIsPo(pNode) )
return pNode->LevelR = 0;
Aig_NodeForEachFanout( pNode, pFanout )
if ( LevelR < Aig_NodeSetLevelR_rec(pFanout) )
LevelR = pFanout->LevelR;
return pNode->LevelR = 1 + LevelR;
}
/**Function*************************************************************
Synopsis [Computes the reverse level of all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManSetLevelR( Aig_Man_t * pMan )
{
Aig_Node_t * pNode;
int i, LevelR = 0;
Aig_ManForEachPi( pMan, pNode, i )
if ( LevelR < Aig_NodeSetLevelR_rec(pNode) )
LevelR = pNode->LevelR;
return LevelR;
}
/**Function*************************************************************
Synopsis [Computes the global number of logic levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManGetLevelMax( Aig_Man_t * pMan )
{
Aig_Node_t * pNode;
int i, LevelsMax = 0;
Aig_ManForEachPo( pMan, pNode, i )
if ( LevelsMax < (int)pNode->Level )
LevelsMax = (int)pNode->Level;
return LevelsMax;
}
/**Function*************************************************************
Synopsis [Computes but does not assign the reverse level of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_NodeGetLevelRNew( Aig_Node_t * pNode )
{
Aig_Node_t * pFanout;
unsigned LevelR = 0;
Aig_NodeForEachFanout( pNode, pFanout )
LevelR = AIG_MAX( LevelR, pFanout->LevelR );
return LevelR + !Aig_NodeIsPi(pNode);
}
/**Function*************************************************************
Synopsis [Updates the direct level of one node.]
Description [Returns 1 if direct level of at least one CO was changed.]
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_NodeUpdateLevel_int( Aig_Node_t * pNode )
{
Aig_Node_t * pFanout;
unsigned LevelNew, fStatus = 0;
Aig_NodeForEachFanout( pNode, pFanout )
{
LevelNew = Aig_NodeGetLevelNew( pFanout );
if ( pFanout->Level == LevelNew )
continue;
// the level has changed
pFanout->Level = LevelNew;
if ( Aig_NodeIsPo(pNode) )
fStatus = 1;
else
fStatus |= Aig_NodeUpdateLevel_int( pFanout );
}
return fStatus;
}
/**Function*************************************************************
Synopsis [Updates the reverse level of one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_NodeUpdateLevelR_int( Aig_Node_t * pNode )
{
Aig_Node_t * pFanin;
unsigned LevelNew;
assert( !Aig_NodeIsPo(pNode) );
pFanin = Aig_NodeFanin0(pNode);
LevelNew = Aig_NodeGetLevelRNew(pFanin);
if ( pFanin->LevelR != LevelNew )
{
pFanin->LevelR = LevelNew;
if ( Aig_NodeIsAnd(pFanin) )
Aig_NodeUpdateLevelR_int( pFanin );
}
pFanin = Aig_NodeFanin1(pNode);
LevelNew = Aig_NodeGetLevelRNew(pFanin);
if ( pFanin->LevelR != LevelNew )
{
pFanin->LevelR = LevelNew;
if ( Aig_NodeIsAnd(pFanin) )
Aig_NodeUpdateLevelR_int( pFanin );
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,157 +0,0 @@
/**CFile****************************************************************
FileName [aigMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Sets the default parameters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManSetDefaultParams( Aig_Param_t * pParam )
{
memset( pParam, 0, sizeof(Aig_Param_t) );
pParam->nPatsRand = 4096; // the number of random patterns
pParam->nBTLimit = 99; // backtrack limit at the intermediate nodes
pParam->nSeconds = 1; // the timeout for the final miter in seconds
}
/**Function*************************************************************
Synopsis [Starts the AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManStart( Aig_Param_t * pParam )
{
Aig_Man_t * p;
// set the random seed for simulation
srand( 0xDEADCAFE );
// start the manager
p = ALLOC( Aig_Man_t, 1 );
memset( p, 0, sizeof(Aig_Man_t) );
p->pParam = &p->Param;
p->nTravIds = 1;
p->nPatsMax = 25;
// set the defaults
*p->pParam = *pParam;
// start memory managers
p->mmNodes = Aig_MemFixedStart( sizeof(Aig_Node_t) );
// allocate node arrays
p->vPis = Vec_PtrAlloc( 1000 ); // the array of primary inputs
p->vPos = Vec_PtrAlloc( 1000 ); // the array of primary outputs
p->vNodes = Vec_PtrAlloc( 1000 ); // the array of internal nodes
// start the table
p->pTable = Aig_TableCreate( 1000 );
// create the constant node
p->pConst1 = Aig_NodeCreateConst( p );
// initialize other variables
p->vFanouts = Vec_PtrAlloc( 10 );
p->vToReplace = Vec_PtrAlloc( 10 );
p->vClassTemp = Vec_IntAlloc( 10 );
p->vPats = Vec_PtrAlloc( p->nPatsMax );
return p;
}
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManCleanup( Aig_Man_t * pMan )
{
Aig_Node_t * pAnd;
int i, nNodesOld;
nNodesOld = Aig_ManAndNum(pMan);
Aig_ManForEachAnd( pMan, pAnd, i )
if ( pAnd->nRefs == 0 )
Aig_NodeDeleteAnd_rec( pMan, pAnd );
return nNodesOld - Aig_ManAndNum(pMan);
}
/**Function*************************************************************
Synopsis [Stops the AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManStop( Aig_Man_t * p )
{
// SAT solver
if ( p->pSat ) solver_delete( p->pSat );
if ( p->vVar2Sat ) Vec_IntFree( p->vVar2Sat );
if ( p->vSat2Var ) Vec_IntFree( p->vSat2Var );
if ( p->vPiSatNums ) Vec_IntFree( p->vPiSatNums );
// fanouts
if ( p->vFanPivots ) Vec_PtrFree( p->vFanPivots );
if ( p->vFanFans0 ) Vec_PtrFree( p->vFanFans0 );
if ( p->vFanFans1 ) Vec_PtrFree( p->vFanFans1 );
if ( p->vClasses ) Vec_VecFree( p->vClasses );
// patterns
if ( p->vPats ) Vec_PtrFree( p->vPats );
if ( p->pPatMask ) Aig_PatternFree( p->pPatMask );
// nodes
Aig_MemFixedStop( p->mmNodes, 0 );
Vec_PtrFree( p->vNodes );
Vec_PtrFree( p->vPis );
Vec_PtrFree( p->vPos );
// temporary
Vec_PtrFree( p->vFanouts );
Vec_PtrFree( p->vToReplace );
Vec_IntFree( p->vClassTemp );
Aig_TableFree( p->pTable );
free( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,246 +0,0 @@
/**CFile****************************************************************
FileName [aigMem.c]
PackageName [ABC: Logic synthesis and verification system.]
Synopsis [Fixed-size-entry memory manager for the AIG package.]
Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>]
Affiliation [UC Berkeley]
Date [Ver. 2.0. Started - October 1, 2004]
Revision [$Id: aigMem.c,v 1.4 2005/07/08 01:01:31 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
struct Aig_MemFixed_t_
{
// information about individual entries
int nEntrySize; // the size of one entry
int nEntriesAlloc; // the total number of entries allocated
int nEntriesUsed; // the number of entries in use
int nEntriesMax; // the max number of entries in use
char * pEntriesFree; // the linked list of free entries
// this is where the memory is stored
int nChunkSize; // the size of one chunk
int nChunksAlloc; // the maximum number of memory chunks
int nChunks; // the current number of memory chunks
char ** pChunks; // the allocated memory
// statistics
int nMemoryUsed; // memory used in the allocated entries
int nMemoryAlloc; // memory allocated
};
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the internal memory manager.]
Description [Can only work with entry size at least 4 byte long.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_MemFixed_t * Aig_MemFixedStart( int nEntrySize )
{
Aig_MemFixed_t * p;
p = ALLOC( Aig_MemFixed_t, 1 );
memset( p, 0, sizeof(Aig_MemFixed_t) );
p->nEntrySize = nEntrySize;
p->nEntriesAlloc = 0;
p->nEntriesUsed = 0;
p->pEntriesFree = NULL;
if ( nEntrySize * (1 << 10) < (1<<16) )
p->nChunkSize = (1 << 10);
else
p->nChunkSize = (1<<16) / nEntrySize;
if ( p->nChunkSize < 8 )
p->nChunkSize = 8;
p->nChunksAlloc = 64;
p->nChunks = 0;
p->pChunks = ALLOC( char *, p->nChunksAlloc );
p->nMemoryUsed = 0;
p->nMemoryAlloc = 0;
return p;
}
/**Function*************************************************************
Synopsis [Stops the internal memory manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_MemFixedStop( Aig_MemFixed_t * p, int fVerbose )
{
int i;
if ( p == NULL )
return;
if ( fVerbose )
{
printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
p->nEntrySize, p->nChunkSize, p->nChunks );
printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
}
for ( i = 0; i < p->nChunks; i++ )
free( p->pChunks[i] );
free( p->pChunks );
free( p );
}
/**Function*************************************************************
Synopsis [Extracts one entry from the memory manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Aig_MemFixedEntryFetch( Aig_MemFixed_t * p )
{
char * pTemp;
int i;
// check if there are still free entries
if ( p->nEntriesUsed == p->nEntriesAlloc )
{ // need to allocate more entries
assert( p->pEntriesFree == NULL );
if ( p->nChunks == p->nChunksAlloc )
{
p->nChunksAlloc *= 2;
p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
}
p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
// transform these entries into a linked list
pTemp = p->pEntriesFree;
for ( i = 1; i < p->nChunkSize; i++ )
{
*((char **)pTemp) = pTemp + p->nEntrySize;
pTemp += p->nEntrySize;
}
// set the last link
*((char **)pTemp) = NULL;
// add the chunk to the chunk storage
p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
// add to the number of entries allocated
p->nEntriesAlloc += p->nChunkSize;
}
// incrememt the counter of used entries
p->nEntriesUsed++;
if ( p->nEntriesMax < p->nEntriesUsed )
p->nEntriesMax = p->nEntriesUsed;
// return the first entry in the free entry list
pTemp = p->pEntriesFree;
p->pEntriesFree = *((char **)pTemp);
return pTemp;
}
/**Function*************************************************************
Synopsis [Returns one entry into the memory manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_MemFixedEntryRecycle( Aig_MemFixed_t * p, char * pEntry )
{
// decrement the counter of used entries
p->nEntriesUsed--;
// add the entry to the linked list of free entries
*((char **)pEntry) = p->pEntriesFree;
p->pEntriesFree = pEntry;
}
/**Function*************************************************************
Synopsis [Frees all associated memory and resets the manager.]
Description [Relocates all the memory except the first chunk.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_MemFixedRestart( Aig_MemFixed_t * p )
{
int i;
char * pTemp;
// deallocate all chunks except the first one
for ( i = 1; i < p->nChunks; i++ )
free( p->pChunks[i] );
p->nChunks = 1;
// transform these entries into a linked list
pTemp = p->pChunks[0];
for ( i = 1; i < p->nChunkSize; i++ )
{
*((char **)pTemp) = pTemp + p->nEntrySize;
pTemp += p->nEntrySize;
}
// set the last link
*((char **)pTemp) = NULL;
// set the free entry list
p->pEntriesFree = p->pChunks[0];
// set the correct statistics
p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
p->nMemoryUsed = 0;
p->nEntriesAlloc = p->nChunkSize;
p->nEntriesUsed = 0;
}
/**Function*************************************************************
Synopsis [Reports the memory usage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_MemFixedReadMemUsage( Aig_MemFixed_t * p )
{
return p->nMemoryAlloc;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,316 +0,0 @@
/**CFile****************************************************************
FileName [aigNode.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigNode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Aig_Node_t * Aig_NodeCreate( Aig_Man_t * p )
{
Aig_Node_t * pNode;
// create the node
pNode = (Aig_Node_t *)Aig_MemFixedEntryFetch( p->mmNodes );
memset( pNode, 0, sizeof(Aig_Node_t) );
// assign the number and add to the array of nodes
pNode->pMan = p;
pNode->Id = p->vNodes->nSize;
Vec_PtrPush( p->vNodes, pNode );
return pNode;
}
/**Function*************************************************************
Synopsis [Creates the constant 1 node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeCreateConst( Aig_Man_t * p )
{
Aig_Node_t * pNode;
pNode = Aig_NodeCreate( p );
pNode->Type = AIG_NONE;
pNode->fPhase = 1; // sim value for 000... pattern
return pNode;
}
/**Function*************************************************************
Synopsis [Creates a primary input node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeCreatePi( Aig_Man_t * p )
{
Aig_Node_t * pNode;
pNode = Aig_NodeCreate( p );
Vec_PtrPush( p->vPis, pNode );
pNode->Type = AIG_PI;
pNode->fPhase = 0; // sim value for 000... pattern
return pNode;
}
/**Function*************************************************************
Synopsis [Creates a primary output node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeCreatePo( Aig_Man_t * p )
{
Aig_Node_t * pNode;
pNode = Aig_NodeCreate( p );
pNode->Type = AIG_PO;
Vec_PtrPush( p->vPos, pNode );
return pNode;
}
/**Function*************************************************************
Synopsis [Creates a primary output node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeConnectPo( Aig_Man_t * p, Aig_Node_t * pNode, Aig_Node_t * pFanin )
{
assert( Aig_NodeIsPo(pNode) );
assert( !Aig_IsComplement(pNode) );
// connect to the fanin
pNode->Fans[0].fComp = Aig_IsComplement(pFanin);
pNode->Fans[0].iNode = Aig_Regular(pFanin)->Id;
pNode->fPhase = pNode->Fans[0].fComp ^ Aig_Regular(pFanin)->fPhase; // sim value for 000... pattern
pNode->Level = Aig_Regular(pFanin)->Level;
Aig_Regular(pFanin)->nRefs++;
if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin, pNode );
// update global level if needed
if ( p->nLevelMax < (int)pNode->Level )
p->nLevelMax = pNode->Level;
return pNode;
}
/**Function*************************************************************
Synopsis [Creates a new node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeCreateAnd( Aig_Man_t * p, Aig_Node_t * pFanin0, Aig_Node_t * pFanin1 )
{
Aig_Node_t * pNode;
pNode = Aig_NodeCreate( p );
pNode->Type = AIG_AND;
Aig_NodeConnectAnd( pFanin0, pFanin1, pNode );
return pNode;
}
/**Function*************************************************************
Synopsis [Connects the nodes to the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeConnectAnd( Aig_Node_t * pFanin0, Aig_Node_t * pFanin1, Aig_Node_t * pNode )
{
assert( !Aig_IsComplement(pNode) );
assert( Aig_NodeIsAnd(pNode) );
// add the fanins
pNode->Fans[0].fComp = Aig_IsComplement(pFanin0);
pNode->Fans[0].iNode = Aig_Regular(pFanin0)->Id;
pNode->Fans[1].fComp = Aig_IsComplement(pFanin1);
pNode->Fans[1].iNode = Aig_Regular(pFanin1)->Id;
// compute the phase (sim value for 000... pattern)
pNode->fPhase = (pNode->Fans[0].fComp ^ Aig_Regular(pFanin0)->fPhase) &
(pNode->Fans[1].fComp ^ Aig_Regular(pFanin1)->fPhase);
pNode->Level = Aig_NodeGetLevelNew(pNode);
// reference the fanins
Aig_Regular(pFanin0)->nRefs++;
Aig_Regular(pFanin1)->nRefs++;
// add the fanouts
if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin0, pNode );
if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin1, pNode );
// add the node to the structural hash table
Aig_TableInsertNode( pNode->pMan, pFanin0, pFanin1, pNode );
}
/**Function*************************************************************
Synopsis [Connects the nodes to the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeDisconnectAnd( Aig_Node_t * pNode )
{
Aig_Node_t * pFanin0, * pFanin1;
assert( !Aig_IsComplement(pNode) );
assert( Aig_NodeIsAnd(pNode) );
// get the fanins
pFanin0 = Aig_NodeFanin0(pNode);
pFanin1 = Aig_NodeFanin1(pNode);
// dereference the fanins
pFanin0->nRefs--;
pFanin0->nRefs--;
// remove the fanouts
if ( pNode->pMan->vFanPivots ) Aig_NodeRemoveFaninFanout( pFanin0, pNode );
if ( pNode->pMan->vFanPivots ) Aig_NodeRemoveFaninFanout( pFanin1, pNode );
// remove the node from the structural hash table
Aig_TableDeleteNode( pNode->pMan, pNode );
}
/**Function*************************************************************
Synopsis [Performs internal deletion step.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeDeleteAnd_rec( Aig_Man_t * pMan, Aig_Node_t * pRoot )
{
Aig_Node_t * pNode0, * pNode1;
// make sure the node is regular and dangling
assert( !Aig_IsComplement(pRoot) );
assert( pRoot->nRefs == 0 );
assert( Aig_NodeIsAnd(pRoot) );
// remember the children
pNode0 = Aig_NodeFanin0(pRoot);
pNode1 = Aig_NodeFanin1(pRoot);
// disconnect the node
Aig_NodeDisconnectAnd( pRoot );
// recycle the node
Vec_PtrWriteEntry( pMan->vNodes, pRoot->Id, NULL );
memset( pRoot, 0, sizeof(Aig_Node_t) ); // this is a temporary hack to skip dead children below!!!
Aig_MemFixedEntryRecycle( pMan->mmNodes, (char *)pRoot );
// call recursively
if ( Aig_NodeIsAnd(pNode0) && pNode0->nRefs == 0 )
Aig_NodeDeleteAnd_rec( pMan, pNode0 );
if ( Aig_NodeIsAnd(pNode1) && pNode1->nRefs == 0 )
Aig_NodeDeleteAnd_rec( pMan, pNode1 );
}
/**Function*************************************************************
Synopsis [Prints the AIG node for debugging purposes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodePrint( Aig_Node_t * pNode )
{
Aig_Node_t * pNodeR = Aig_Regular(pNode);
if ( Aig_NodeIsPi(pNode) )
{
printf( "PI %4s%s.\n", Aig_NodeName(pNode), Aig_IsComplement(pNode)? "\'" : "" );
return;
}
if ( Aig_NodeIsConst(pNode) )
{
printf( "Constant 1 %s.\n", Aig_IsComplement(pNode)? "(complemented)" : "" );
return;
}
// print the node's function
printf( "%7s%s", Aig_NodeName(pNodeR), Aig_IsComplement(pNode)? "\'" : "" );
printf( " = " );
printf( "%7s%s", Aig_NodeName(Aig_NodeFanin0(pNodeR)), Aig_NodeFaninC0(pNodeR)? "\'" : "" );
printf( " * " );
printf( "%7s%s", Aig_NodeName(Aig_NodeFanin1(pNodeR)), Aig_NodeFaninC1(pNodeR)? "\'" : "" );
printf( "\n" );
}
/**Function*************************************************************
Synopsis [Returns the name of the node.]
Description [The name should be used before this procedure is called again.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Aig_NodeName( Aig_Node_t * pNode )
{
static char Buffer[100];
sprintf( Buffer, "%d", Aig_Regular(pNode)->Id );
return Buffer;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,175 +0,0 @@
/**CFile****************************************************************
FileName [aigOper.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigOper.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs canonicization step.]
Description [The argument nodes can be complemented.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_And( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 )
{
Aig_Node_t * pAnd;
// check for trivial cases
if ( p0 == p1 )
return p0;
if ( p0 == Aig_Not(p1) )
return Aig_Not(pMan->pConst1);
if ( Aig_Regular(p0) == pMan->pConst1 )
{
if ( p0 == pMan->pConst1 )
return p1;
return Aig_Not(pMan->pConst1);
}
if ( Aig_Regular(p1) == pMan->pConst1 )
{
if ( p1 == pMan->pConst1 )
return p0;
return Aig_Not(pMan->pConst1);
}
// order the arguments
if ( Aig_Regular(p0)->Id > Aig_Regular(p1)->Id )
{
if ( pAnd = Aig_TableLookupNode( pMan, p1, p0 ) )
return pAnd;
return Aig_NodeCreateAnd( pMan, p1, p0 );
}
else
{
if ( pAnd = Aig_TableLookupNode( pMan, p0, p1 ) )
return pAnd;
return Aig_NodeCreateAnd( pMan, p0, p1 );
}
}
/**Function*************************************************************
Synopsis [Implements Boolean OR.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_Or( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 )
{
return Aig_Not( Aig_And( pMan, Aig_Not(p0), Aig_Not(p1) ) );
}
/**Function*************************************************************
Synopsis [Implements Boolean XOR.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_Xor( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 )
{
return Aig_Or( pMan, Aig_And(pMan, p0, Aig_Not(p1)),
Aig_And(pMan, p1, Aig_Not(p0)) );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_Mux( Aig_Man_t * pMan, Aig_Node_t * pC, Aig_Node_t * p1, Aig_Node_t * p0 )
{
return Aig_Or( pMan, Aig_And(pMan, pC, p1), Aig_And(pMan, Aig_Not(pC), p0) );
}
/**Function*************************************************************
Synopsis [Implements the miter.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_Miter_rec( Aig_Man_t * pMan, Aig_Node_t ** ppObjs, int nObjs )
{
Aig_Node_t * pObj1, * pObj2;
if ( nObjs == 1 )
return ppObjs[0];
pObj1 = Aig_Miter_rec( pMan, ppObjs, nObjs/2 );
pObj2 = Aig_Miter_rec( pMan, ppObjs + nObjs/2, nObjs - nObjs/2 );
return Aig_Or( pMan, pObj1, pObj2 );
}
/**Function*************************************************************
Synopsis [Implements the miter.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_Miter( Aig_Man_t * pMan, Vec_Ptr_t * vPairs )
{
int i;
if ( vPairs->nSize == 0 )
return Aig_Not( pMan->pConst1 );
assert( vPairs->nSize % 2 == 0 );
// go through the cubes of the node's SOP
for ( i = 0; i < vPairs->nSize; i += 2 )
vPairs->pArray[i/2] = Aig_Xor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] );
vPairs->nSize = vPairs->nSize/2;
return Aig_Miter_rec( pMan, (Aig_Node_t **)vPairs->pArray, vPairs->nSize );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,133 +0,0 @@
/**CFile****************************************************************
FileName [aigUpdate.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigUpdate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs internal replacement step.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static void Abc_AigReplace_int( Aig_Man_t * pMan, int fUpdateLevel )
{
Vec_Ptr_t * vFanouts;
Aig_Node_t * pOld, * pNew, * pFanin0, * pFanin1, * pFanout, * pTemp, * pFanoutNew;
int k, iFanin;
// get the pair of nodes to replace
assert( Vec_PtrSize(pMan->vToReplace) > 0 );
pNew = Vec_PtrPop( pMan->vToReplace );
pOld = Vec_PtrPop( pMan->vToReplace );
// make sure the old node is internal, regular, and has fanouts
// (the new node can be PI or internal, is complemented, and can have fanouts)
assert( !Aig_IsComplement(pOld) );
assert( pOld->nRefs > 0 );
assert( Aig_NodeIsAnd(pOld) );
assert( Aig_NodeIsPo(pNew) );
// look at the fanouts of old node
vFanouts = Aig_NodeGetFanouts( pOld );
Vec_PtrForEachEntry( vFanouts, pFanout, k )
{
if ( Aig_NodeIsPo(pFanout) )
{
// patch the first fanin of the PO
pFanout->Fans[0].iNode = Aig_Regular(pNew)->Id;
pFanout->Fans[0].fComp ^= Aig_IsComplement(pNew);
continue;
}
// find the old node as a fanin of this fanout
iFanin = Aig_NodeWhatFanin( pFanout, pOld );
assert( iFanin == 0 || iFanin == 1 );
// get the new fanin
pFanin0 = Aig_NotCond( pNew, pFanout->Fans[iFanin].fComp );
assert( Aig_Regular(pFanin0) != pFanout );
// get another fanin
pFanin1 = iFanin? Aig_NodeChild0(pFanout) : Aig_NodeChild1(pFanout);
assert( Aig_Regular(pFanin1) != pFanout );
assert( Aig_Regular(pFanin0) != Aig_Regular(pFanin1) );
// order them
if ( Aig_Regular(pFanin0)->Id > Aig_Regular(pFanin1)->Id )
pTemp = pFanin0, pFanin0 = pFanin1, pFanin1 = pTemp;
// check if the node with these fanins exists
if ( pFanoutNew = Aig_TableLookupNode( pMan, pFanin0, pFanin1 ) )
{ // such node exists (it may be a constant)
// schedule replacement of the old fanout by the new fanout
Vec_PtrPush( pMan->vToReplace, pFanout );
Vec_PtrPush( pMan->vToReplace, pFanoutNew );
continue;
}
// such node does not exist - modify the old fanout node
// (this way the change will not propagate all the way to the COs)
Aig_NodeDisconnectAnd( pFanout );
Aig_NodeConnectAnd( pFanin0, pFanin1, pFanout );
// recreate the old fanout with new fanins and add it to the table
assert( Aig_NodeIsAcyclic(pFanout, pFanout) );
// update the level if requested
if ( fUpdateLevel )
{
if ( Aig_NodeUpdateLevel_int(pFanout) )
pMan->nLevelMax = Aig_ManGetLevelMax( pMan );
//Aig_NodeGetLevelRNew( pFanout );
Aig_NodeUpdateLevelR_int( pFanout );
}
}
// if the node has no fanouts left, remove its MFFC
if ( pOld->nRefs == 0 )
Aig_NodeDeleteAnd_rec( pMan, pOld );
}
/**Function*************************************************************
Synopsis [Replaces one AIG node by the other.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManReplaceNode( Aig_Man_t * pMan, Aig_Node_t * pOld, Aig_Node_t * pNew, int fUpdateLevel )
{
assert( Vec_PtrSize(pMan->vToReplace) == 0 );
Vec_PtrPush( pMan->vToReplace, pOld );
Vec_PtrPush( pMan->vToReplace, pNew );
while ( Vec_PtrSize(pMan->vToReplace) )
Abc_AigReplace_int( pMan, fUpdateLevel );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,334 +0,0 @@
/**CFile****************************************************************
FileName [aigTable.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigTable.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// the hash table
struct Aig_Table_t_
{
Aig_Node_t ** pBins; // the table bins
int nBins; // the size of the table
int nEntries; // the total number of entries in the table
};
// iterators through the entries in the linked lists of nodes
#define Aig_TableBinForEachEntry( pBin, pEnt ) \
for ( pEnt = pBin; \
pEnt; \
pEnt = Aig_NodeNextH(pEnt) )
#define Aig_TableBinForEachEntrySafe( pBin, pEnt, pEnt2 ) \
for ( pEnt = pBin, \
pEnt2 = pEnt? Aig_NodeNextH(pEnt) : NULL; \
pEnt; \
pEnt = pEnt2, \
pEnt2 = pEnt? Aig_NodeNextH(pEnt) : NULL )
// hash key for the structural hash table
static inline unsigned Abc_HashKey2( Aig_Node_t * p0, Aig_Node_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; }
//static inline unsigned Abc_HashKey2( Aig_Node_t * p0, Aig_Node_t * p1, int TableSize ) { return ((unsigned)((a)->Id + (b)->Id) * ((a)->Id + (b)->Id + 1) / 2) % TableSize; }
static unsigned int Cudd_PrimeAig( unsigned int p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Table_t * Aig_TableCreate( int nSize )
{
Aig_Table_t * p;
// allocate the table
p = ALLOC( Aig_Table_t, 1 );
memset( p, 0, sizeof(Aig_Table_t) );
// allocate and clean the bins
p->nBins = Cudd_PrimeAig(nSize);
p->pBins = ALLOC( Aig_Node_t *, p->nBins );
memset( p->pBins, 0, sizeof(Aig_Node_t *) * p->nBins );
return p;
}
/**Function*************************************************************
Synopsis [Deallocates the supergate hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_TableFree( Aig_Table_t * p )
{
FREE( p->pBins );
FREE( p );
}
/**Function*************************************************************
Synopsis [Returns the number of nodes in the table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_TableNumNodes( Aig_Table_t * p )
{
return p->nEntries;
}
/**Function*************************************************************
Synopsis [Performs canonicization step.]
Description [The argument nodes can be complemented.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_TableLookupNode( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 )
{
Aig_Node_t * pAnd;
unsigned Key;
assert( Aig_Regular(p0)->Id < Aig_Regular(p1)->Id );
// get the hash key for these two nodes
Key = Abc_HashKey2( p0, p1, pMan->pTable->nBins );
// find the matching node in the table
Aig_TableBinForEachEntry( pMan->pTable->pBins[Key], pAnd )
if ( p0 == Aig_NodeChild0(pAnd) && p1 == Aig_NodeChild1(pAnd) )
return pAnd;
return NULL;
}
/**Function*************************************************************
Synopsis [Performs canonicization step.]
Description [The argument nodes can be complemented.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_TableInsertNode( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1, Aig_Node_t * pAnd )
{
unsigned Key;
assert( Aig_Regular(p0)->Id < Aig_Regular(p1)->Id );
// check if it is a good time for table resizing
if ( pMan->pTable->nEntries > 2 * pMan->pTable->nBins )
Aig_TableResize( pMan );
// add the node to the corresponding linked list in the table
Key = Abc_HashKey2( p0, p1, pMan->pTable->nBins );
pAnd->NextH = pMan->pTable->pBins[Key]? pMan->pTable->pBins[Key]->Id : 0;
pMan->pTable->pBins[Key] = pAnd;
pMan->pTable->nEntries++;
return pAnd;
}
/**Function*************************************************************
Synopsis [Deletes an AIG node from the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_TableDeleteNode( Aig_Man_t * pMan, Aig_Node_t * pThis )
{
Aig_Node_t * pAnd, * pPlace = NULL;
unsigned Key;
assert( !Aig_IsComplement(pThis) );
assert( Aig_NodeIsAnd(pThis) );
assert( pMan == pThis->pMan );
// get the hash key for these two nodes
Key = Abc_HashKey2( Aig_NodeChild0(pThis), Aig_NodeChild1(pThis), pMan->pTable->nBins );
// find the matching node in the table
Aig_TableBinForEachEntry( pMan->pTable->pBins[Key], pAnd )
{
if ( pThis != pAnd )
{
pPlace = pAnd;
continue;
}
if ( pPlace == NULL )
pMan->pTable->pBins[Key] = Aig_NodeNextH(pThis);
else
pPlace->NextH = pThis->NextH;
break;
}
assert( pThis == pAnd );
pMan->pTable->nEntries--;
}
/**Function*************************************************************
Synopsis [Resizes the hash table of AIG nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_TableResize( Aig_Man_t * pMan )
{
Aig_Node_t ** pBinsNew;
Aig_Node_t * pEnt, * pEnt2;
int nBinsNew, Counter, i, clk;
unsigned Key;
clk = clock();
// get the new table size
nBinsNew = Cudd_PrimeCopy( 3 * pMan->pTable->nBins );
// allocate a new array
pBinsNew = ALLOC( Aig_Node_t *, nBinsNew );
memset( pBinsNew, 0, sizeof(Aig_Node_t *) * nBinsNew );
// rehash the entries from the old table
Counter = 0;
for ( i = 0; i < pMan->pTable->nBins; i++ )
Aig_TableBinForEachEntrySafe( pMan->pTable->pBins[i], pEnt, pEnt2 )
{
Key = Abc_HashKey2( Aig_NodeChild0(pEnt), Aig_NodeChild1(pEnt), nBinsNew );
pEnt->NextH = pBinsNew[Key]? pBinsNew[Key]->Id : 0;
pBinsNew[Key] = pEnt;
Counter++;
}
assert( Counter == pMan->pTable->nEntries );
// printf( "Increasing the structural table size from %6d to %6d. ", pMan->nBins, nBinsNew );
// PRT( "Time", clock() - clk );
// replace the table and the parameters
free( pMan->pTable->pBins );
pMan->pTable->pBins = pBinsNew;
pMan->pTable->nBins = nBinsNew;
}
/**Function*************************************************************
Synopsis [Resizes the hash table of AIG nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_TableRehash( Aig_Man_t * pMan )
{
Aig_Node_t ** pBinsNew;
Aig_Node_t * pEnt, * pEnt2;
unsigned Key;
int Counter, Temp, i;
// allocate a new array
pBinsNew = ALLOC( Aig_Node_t *, pMan->pTable->nBins );
memset( pBinsNew, 0, sizeof(Aig_Node_t *) * pMan->pTable->nBins );
// rehash the entries from the old table
Counter = 0;
for ( i = 0; i < pMan->pTable->nBins; i++ )
Aig_TableBinForEachEntrySafe( pMan->pTable->pBins[i], pEnt, pEnt2 )
{
// swap the fanins if needed
if ( pEnt->Fans[0].iNode > pEnt->Fans[1].iNode )
{
Temp = pEnt->Fans[0].iNode;
pEnt->Fans[0].iNode = pEnt->Fans[1].iNode;
pEnt->Fans[1].iNode = Temp;
Temp = pEnt->Fans[0].fComp;
pEnt->Fans[0].fComp = pEnt->Fans[1].fComp;
pEnt->Fans[1].fComp = Temp;
}
// rehash the node
Key = Abc_HashKey2( Aig_NodeChild0(pEnt), Aig_NodeChild1(pEnt), pMan->pTable->nBins );
pEnt->NextH = pBinsNew[Key]? pBinsNew[Key]->Id : 0;
pBinsNew[Key] = pEnt;
Counter++;
}
assert( Counter == pMan->pTable->nEntries );
// replace the table and the parameters
free( pMan->pTable->pBins );
pMan->pTable->pBins = pBinsNew;
}
/**Function*************************************************************
Synopsis [Returns the smallest prime larger than the number.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned int Cudd_PrimeAig( unsigned int p )
{
int i,pn;
p--;
do {
p++;
if (p&1) {
pn = 1;
i = 3;
while ((unsigned) (i * i) <= p) {
if (p % i == 0) {
pn = 0;
break;
}
i += 2;
}
} else {
pn = 0;
}
} while (!pn);
return(p);
} /* end of Cudd_Prime */
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,190 +0,0 @@
/**CFile****************************************************************
FileName [aigUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: aigUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Increments the current traversal ID of the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManIncrementTravId( Aig_Man_t * pMan )
{
Aig_Node_t * pObj;
int i;
if ( pMan->nTravIds == (1<<24)-1 )
{
pMan->nTravIds = 0;
Aig_ManForEachNode( pMan, pObj, i )
pObj->TravId = 0;
}
pMan->nTravIds++;
}
/**Function*************************************************************
Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Aig_NodeIsMuxType( Aig_Node_t * pNode )
{
Aig_Node_t * pNode0, * pNode1;
// check that the node is regular
assert( !Aig_IsComplement(pNode) );
// if the node is not AND, this is not MUX
if ( !Aig_NodeIsAnd(pNode) )
return 0;
// if the children are not complemented, this is not MUX
if ( !Aig_NodeFaninC0(pNode) || !Aig_NodeFaninC1(pNode) )
return 0;
// get children
pNode0 = Aig_NodeFanin0(pNode);
pNode1 = Aig_NodeFanin1(pNode);
// if the children are not ANDs, this is not MUX
if ( !Aig_NodeIsAnd(pNode0) || !Aig_NodeIsAnd(pNode1) )
return 0;
// otherwise the node is MUX iff it has a pair of equal grandchildren
return (Aig_NodeFaninId0(pNode0) == Aig_NodeFaninId0(pNode1) && (Aig_NodeFaninC0(pNode0) ^ Aig_NodeFaninC0(pNode1))) ||
(Aig_NodeFaninId0(pNode0) == Aig_NodeFaninId1(pNode1) && (Aig_NodeFaninC0(pNode0) ^ Aig_NodeFaninC1(pNode1))) ||
(Aig_NodeFaninId1(pNode0) == Aig_NodeFaninId0(pNode1) && (Aig_NodeFaninC1(pNode0) ^ Aig_NodeFaninC0(pNode1))) ||
(Aig_NodeFaninId1(pNode0) == Aig_NodeFaninId1(pNode1) && (Aig_NodeFaninC1(pNode0) ^ Aig_NodeFaninC1(pNode1)));
}
/**Function*************************************************************
Synopsis [Recognizes what nodes are control and data inputs of a MUX.]
Description [If the node is a MUX, returns the control variable C.
Assigns nodes T and E to be the then and else variables of the MUX.
Node C is never complemented. Nodes T and E can be complemented.
This function also recognizes EXOR/NEXOR gates as MUXes.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Node_t * Aig_NodeRecognizeMux( Aig_Node_t * pNode, Aig_Node_t ** ppNodeT, Aig_Node_t ** ppNodeE )
{
Aig_Node_t * pNode0, * pNode1;
assert( !Aig_IsComplement(pNode) );
assert( Aig_NodeIsMuxType(pNode) );
// get children
pNode0 = Aig_NodeFanin0(pNode);
pNode1 = Aig_NodeFanin1(pNode);
// find the control variable
// if ( pNode1->p1 == Fraig_Not(pNode2->p1) )
if ( Aig_NodeFaninId0(pNode0) == Aig_NodeFaninId0(pNode1) && (Aig_NodeFaninC0(pNode0) ^ Aig_NodeFaninC0(pNode1)) )
{
// if ( Fraig_IsComplement(pNode1->p1) )
if ( Aig_NodeFaninC0(pNode0) )
{ // pNode2->p1 is positive phase of C
*ppNodeT = Aig_Not(Aig_NodeChild1(pNode1));//pNode2->p2);
*ppNodeE = Aig_Not(Aig_NodeChild1(pNode0));//pNode1->p2);
return Aig_NodeChild0(pNode1);//pNode2->p1;
}
else
{ // pNode1->p1 is positive phase of C
*ppNodeT = Aig_Not(Aig_NodeChild1(pNode0));//pNode1->p2);
*ppNodeE = Aig_Not(Aig_NodeChild1(pNode1));//pNode2->p2);
return Aig_NodeChild0(pNode0);//pNode1->p1;
}
}
// else if ( pNode1->p1 == Fraig_Not(pNode2->p2) )
else if ( Aig_NodeFaninId0(pNode0) == Aig_NodeFaninId1(pNode1) && (Aig_NodeFaninC0(pNode0) ^ Aig_NodeFaninC1(pNode1)) )
{
// if ( Fraig_IsComplement(pNode1->p1) )
if ( Aig_NodeFaninC0(pNode0) )
{ // pNode2->p2 is positive phase of C
*ppNodeT = Aig_Not(Aig_NodeChild0(pNode1));//pNode2->p1);
*ppNodeE = Aig_Not(Aig_NodeChild1(pNode0));//pNode1->p2);
return Aig_NodeChild1(pNode1);//pNode2->p2;
}
else
{ // pNode1->p1 is positive phase of C
*ppNodeT = Aig_Not(Aig_NodeChild1(pNode0));//pNode1->p2);
*ppNodeE = Aig_Not(Aig_NodeChild0(pNode1));//pNode2->p1);
return Aig_NodeChild0(pNode0);//pNode1->p1;
}
}
// else if ( pNode1->p2 == Fraig_Not(pNode2->p1) )
else if ( Aig_NodeFaninId1(pNode0) == Aig_NodeFaninId0(pNode1) && (Aig_NodeFaninC1(pNode0) ^ Aig_NodeFaninC0(pNode1)) )
{
// if ( Fraig_IsComplement(pNode1->p2) )
if ( Aig_NodeFaninC1(pNode0) )
{ // pNode2->p1 is positive phase of C
*ppNodeT = Aig_Not(Aig_NodeChild1(pNode1));//pNode2->p2);
*ppNodeE = Aig_Not(Aig_NodeChild0(pNode0));//pNode1->p1);
return Aig_NodeChild0(pNode1);//pNode2->p1;
}
else
{ // pNode1->p2 is positive phase of C
*ppNodeT = Aig_Not(Aig_NodeChild0(pNode0));//pNode1->p1);
*ppNodeE = Aig_Not(Aig_NodeChild1(pNode1));//pNode2->p2);
return Aig_NodeChild1(pNode0);//pNode1->p2;
}
}
// else if ( pNode1->p2 == Fraig_Not(pNode2->p2) )
else if ( Aig_NodeFaninId1(pNode0) == Aig_NodeFaninId1(pNode1) && (Aig_NodeFaninC1(pNode0) ^ Aig_NodeFaninC1(pNode1)) )
{
// if ( Fraig_IsComplement(pNode1->p2) )
if ( Aig_NodeFaninC1(pNode0) )
{ // pNode2->p2 is positive phase of C
*ppNodeT = Aig_Not(Aig_NodeChild0(pNode1));//pNode2->p1);
*ppNodeE = Aig_Not(Aig_NodeChild0(pNode0));//pNode1->p1);
return Aig_NodeChild1(pNode1);//pNode2->p2;
}
else
{ // pNode1->p2 is positive phase of C
*ppNodeT = Aig_Not(Aig_NodeChild0(pNode0));//pNode1->p1);
*ppNodeE = Aig_Not(Aig_NodeChild0(pNode1));//pNode2->p1);
return Aig_NodeChild1(pNode0);//pNode1->p2;
}
}
assert( 0 ); // this is not MUX
return NULL;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,320 +0,0 @@
/**CFile****************************************************************
FileName [fraigClass.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: fraigClass.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
#include "stmm.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static unsigned Aig_ManHashKey( unsigned * pData, int nWords, bool fPhase );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates the equivalence classes of patterns.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfo )
{
Vec_Vec_t * vClasses; // equivalence classes
stmm_table * tSim2Node; // temporary hash table hashing key into the class number
Aig_Node_t * pNode;
unsigned uKey;
int i, * pSpot, Entry, ClassNum;
assert( pInfo->Type == 1 );
// fill in the hash table
tSim2Node = stmm_init_table( stmm_numcmp, stmm_numhash );
vClasses = Vec_VecAlloc( 100 );
// enumerate the nodes considered in the equivalence classes
// Aig_ManForEachNode( p, pNode, i )
Vec_IntForEachEntry( p->vSat2Var, Entry, i )
{
pNode = Aig_ManNode( p, Entry );
if ( Aig_NodeIsPo(pNode) )
continue;
uKey = Aig_ManHashKey( Aig_SimInfoForNode(pInfo, pNode), pInfo->nWords, pNode->fPhase );
if ( !stmm_find_or_add( tSim2Node, (char *)uKey, (char ***)&pSpot ) ) // does not exist
*pSpot = (pNode->Id << 1) | 1; // save the node, and do nothing
else if ( (*pSpot) & 1 ) // this is a node
{
// create the class
ClassNum = Vec_VecSize( vClasses );
Vec_VecPush( vClasses, ClassNum, (void *)((*pSpot) >> 1) );
Vec_VecPush( vClasses, ClassNum, (void *)pNode->Id );
// save the class
*pSpot = (ClassNum << 1);
}
else // this is a class
{
ClassNum = ((*pSpot) >> 1);
Vec_VecPush( vClasses, ClassNum, (void *)pNode->Id );
}
}
stmm_free_table( tSim2Node );
/*
// print the classes
{
Vec_Ptr_t * vVec;
printf( "PI/PO = %4d/%4d. Nodes = %7d. SatVars = %7d. Non-trivial classes = %5d: \n",
Aig_ManPiNum(p), Aig_ManPoNum(p),
Aig_ManNodeNum(p) - Aig_ManPoNum(p),
Vec_IntSize(p->vSat2Var), Vec_VecSize(vClasses) );
Vec_VecForEachLevel( vClasses, vVec, i )
printf( "%d ", Vec_PtrSize(vVec) );
printf( "\n" );
}
*/
printf( "Classes = %6d. Pairs = %6d.\n", Vec_VecSize(vClasses), Vec_VecSizeSize(vClasses) - Vec_VecSize(vClasses) );
return vClasses;
}
/**Function*************************************************************
Synopsis [Computes the hash key of the simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Aig_ManHashKey( unsigned * pData, int nWords, bool fPhase )
{
static int Primes[10] = { 1009, 2207, 3779, 4001, 4877, 5381, 6427, 6829, 7213, 7919 };
unsigned uKey;
int i;
uKey = 0;
if ( fPhase )
for ( i = 0; i < nWords; i++ )
uKey ^= i * Primes[i%10] * pData[i];
else
for ( i = 0; i < nWords; i++ )
uKey ^= i * Primes[i%10] * ~pData[i];
return uKey;
}
/**Function*************************************************************
Synopsis [Splits the equivalence class.]
Description [Given an equivalence class (vClass) and the simulation info,
split the class into two based on the info.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManSplitClass( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Int_t * vClass, Vec_Int_t * vClass2, Aig_Pattern_t * pPat )
{
int NodeId, i, k, w;
Aig_Node_t * pRoot, * pTemp;
unsigned * pRootData, * pTempData;
assert( Vec_IntSize(vClass) > 1 );
assert( pInfo->nPatsCur == pPat->nBits );
// printf( "Class = %5d. --> ", Vec_IntSize(vClass) );
// clear storage for the new classes
Vec_IntClear( vClass2 );
// get the root member of the class
pRoot = Aig_ManNode( p, Vec_IntEntry(vClass, 0) );
pRootData = Aig_SimInfoForNode( pInfo, pRoot );
// sort the class members:
// (1) with the same siminfo as pRoot remain in vClass
// (2) nodes with other siminfo go to vClass2
k = 1;
Vec_IntForEachEntryStart( vClass, NodeId, i, 1 )
{
NodeId = Vec_IntEntry(vClass, i);
pTemp = Aig_ManNode( p, NodeId );
pTempData = Aig_SimInfoForNode( pInfo, pTemp );
if ( pRoot->fPhase == pTemp->fPhase )
{
for ( w = 0; w < pInfo->nWords; w++ )
if ( pRootData[w] != pTempData[w] )
break;
if ( w == pInfo->nWords ) // the same info
Vec_IntWriteEntry( vClass, k++, NodeId );
else
{
Vec_IntPush( vClass2, NodeId );
// record the diffs if they are not distinguished by the first pattern
if ( ((pRootData[0] ^ pTempData[0]) & 1) == 0 )
for ( w = 0; w < pInfo->nWords; w++ )
pPat->pData[w] |= (pRootData[w] ^ pTempData[w]);
}
}
else
{
for ( w = 0; w < pInfo->nWords; w++ )
if ( pRootData[w] != ~pTempData[w] )
break;
if ( w == pInfo->nWords ) // the same info
Vec_IntWriteEntry( vClass, k++, NodeId );
else
{
Vec_IntPush( vClass2, NodeId );
// record the diffs if they are not distinguished by the first pattern
if ( ((pRootData[0] ^ ~pTempData[0]) & 1) == 0 )
for ( w = 0; w < pInfo->nWords; w++ )
pPat->pData[w] |= (pRootData[w] ^ ~pTempData[w]);
}
}
}
Vec_IntShrink( vClass, k );
// printf( "Class1 = %5d. Class2 = %5d.\n", Vec_IntSize(vClass), Vec_IntSize(vClass2) );
}
/**Function*************************************************************
Synopsis [Updates the equivalence classes using the simulation info.]
Description [Records successful simulation patterns into the pattern
storage.]
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses, Aig_Pattern_t * pPatMask )
{
Vec_Ptr_t * vClass;
int i, k, fSplit = 0;
assert( Vec_VecSize(vClasses) > 0 );
// collect patterns that lead to changes
Aig_PatternClean( pPatMask );
// split the classes using the new symmetry info
Vec_VecForEachLevel( vClasses, vClass, i )
{
if ( i == 0 )
continue;
// split vClass into two parts (vClass and vClassTemp)
Aig_ManSplitClass( p, pInfo, (Vec_Int_t *)vClass, p->vClassTemp, pPatMask );
// check if there is any splitting
if ( Vec_IntSize(p->vClassTemp) > 0 )
fSplit = 1;
// skip the new class if it is empty or trivial
if ( Vec_IntSize(p->vClassTemp) < 2 )
continue;
// consider replacing the current class with the new one
if ( Vec_PtrSize(vClass) == 1 )
{
assert( vClasses->pArray[i] == vClass );
vClasses->pArray[i] = p->vClassTemp;
p->vClassTemp = (Vec_Int_t *)vClass;
i--;
continue;
}
// add the new non-trival class in the end
Vec_PtrPush( (Vec_Ptr_t *)vClasses, p->vClassTemp );
p->vClassTemp = Vec_IntAlloc( 10 );
}
// free trivial classes
k = 0;
Vec_VecForEachLevel( vClasses, vClass, i )
{
assert( Vec_PtrSize(vClass) > 0 );
if ( Vec_PtrSize(vClass) == 1 )
Vec_PtrFree(vClass);
else
vClasses->pArray[k++] = vClass;
}
Vec_PtrShrink( (Vec_Ptr_t *)vClasses, k );
// catch the patterns which led to splitting
printf( "Classes = %6d. Pairs = %6d. Patterns = %3d.\n",
Vec_VecSize(vClasses),
Vec_VecSizeSize(vClasses) - Vec_VecSize(vClasses),
Vec_PtrSize(p->vPats) );
return fSplit;
}
/**Function*************************************************************
Synopsis [Collects useful patterns.]
Description [If the flag fAddToVector is 1, creates and adds new patterns
to the internal storage of patterns.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManCollectPatterns( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Aig_Pattern_t * pMask, Vec_Ptr_t * vPats )
{
Aig_SimInfo_t * pInfoRes = p->pInfo;
Aig_Pattern_t * pPatNew;
Aig_Node_t * pNode;
int i, k;
assert( Aig_InfoHasBit(pMask->pData, 0) == 0 );
for ( i = 0; i < pMask->nBits; i++ )
{
if ( vPats && Vec_PtrSize(vPats) >= p->nPatsMax )
break;
if ( i == 0 || Aig_InfoHasBit(pMask->pData, i) )
{
// expand storage if needed
if ( pInfoRes->nPatsCur == pInfoRes->nPatsMax )
Aig_SimInfoResize( pInfoRes );
// create a new pattern
if ( vPats )
{
pPatNew = Aig_PatternAlloc( Aig_ManPiNum(p) );
Aig_PatternClean( pPatNew );
}
// go through the PIs
Aig_ManForEachPi( p, pNode, k )
{
if ( Aig_InfoHasBit( Aig_SimInfoForNode(pInfo, pNode), i ) )
{
Aig_InfoSetBit( Aig_SimInfoForPi(pInfoRes, k), pInfoRes->nPatsCur );
if ( vPats ) Aig_InfoSetBit( pPatNew->pData, k );
}
}
// store the new pattern
if ( vPats ) Vec_PtrPush( vPats, pPatNew );
// increment the number of patterns stored
pInfoRes->nPatsCur++;
}
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,476 +0,0 @@
/**CFile****************************************************************
FileName [fraigCnf.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: fraigCnf.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Adds trivial clause.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ClauseTriv( solver * pSat, Aig_Node_t * pNode, Vec_Int_t * vVars )
{
//printf( "Adding triv %d. %d\n", Aig_Regular(pNode)->Id, (int)pSat->solver_stats.clauses );
vVars->nSize = 0;
Vec_IntPush( vVars, toLitCond( Aig_Regular(pNode)->Data, Aig_IsComplement(pNode) ) );
// Vec_IntPush( vVars, toLitCond( (int)Aig_Regular(pNode)->Id, Aig_IsComplement(pNode) ) );
return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
}
/**Function*************************************************************
Synopsis [Adds trivial clause.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ClauseAnd( solver * pSat, Aig_Node_t * pNode, Vec_Ptr_t * vSuper, Vec_Int_t * vVars )
{
int fComp1, Var, Var1, i;
//printf( "Adding AND %d. (%d) %d\n", pNode->Id, vSuper->nSize+1, (int)pSat->solver_stats.clauses );
assert( !Aig_IsComplement( pNode ) );
assert( Aig_NodeIsAnd( pNode ) );
// nVars = solver_nvars(pSat);
Var = pNode->Data;
// Var = pNode->Id;
// assert( Var < nVars );
for ( i = 0; i < vSuper->nSize; i++ )
{
// get the predecessor nodes
// get the complemented attributes of the nodes
fComp1 = Aig_IsComplement(vSuper->pArray[i]);
// determine the variable numbers
Var1 = Aig_Regular(vSuper->pArray[i])->Data;
// Var1 = (int)Aig_Regular(vSuper->pArray[i])->Id;
// check that the variables are in the SAT manager
// assert( Var1 < nVars );
// suppose the AND-gate is A * B = C
// add !A => !C or A + !C
// fprintf( pFile, "%d %d 0%c", Var1, -Var, 10 );
vVars->nSize = 0;
Vec_IntPush( vVars, toLitCond(Var1, fComp1) );
Vec_IntPush( vVars, toLitCond(Var, 1 ) );
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
return 0;
}
// add A & B => C or !A + !B + C
// fprintf( pFile, "%d %d %d 0%c", -Var1, -Var2, Var, 10 );
vVars->nSize = 0;
for ( i = 0; i < vSuper->nSize; i++ )
{
// get the predecessor nodes
// get the complemented attributes of the nodes
fComp1 = Aig_IsComplement(vSuper->pArray[i]);
// determine the variable numbers
Var1 = Aig_Regular(vSuper->pArray[i])->Data;
// Var1 = (int)Aig_Regular(vSuper->pArray[i])->Id;
// add this variable to the array
Vec_IntPush( vVars, toLitCond(Var1, !fComp1) );
}
Vec_IntPush( vVars, toLitCond(Var, 0) );
return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
}
/**Function*************************************************************
Synopsis [Adds trivial clause.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ClauseMux( solver * pSat, Aig_Node_t * pNode, Aig_Node_t * pNodeC, Aig_Node_t * pNodeT, Aig_Node_t * pNodeE, Vec_Int_t * vVars )
{
int VarF, VarI, VarT, VarE, fCompT, fCompE;
//printf( "Adding mux %d. %d\n", pNode->Id, (int)pSat->solver_stats.clauses );
assert( !Aig_IsComplement( pNode ) );
assert( Aig_NodeIsMuxType( pNode ) );
// get the variable numbers
VarF = pNode->Data;
VarI = pNodeC->Data;
VarT = Aig_Regular(pNodeT)->Data;
VarE = Aig_Regular(pNodeE)->Data;
// VarF = (int)pNode->Id;
// VarI = (int)pNodeC->Id;
// VarT = (int)Aig_Regular(pNodeT)->Id;
// VarE = (int)Aig_Regular(pNodeE)->Id;
// get the complementation flags
fCompT = Aig_IsComplement(pNodeT);
fCompE = Aig_IsComplement(pNodeE);
// f = ITE(i, t, e)
// i' + t' + f
// i' + t + f'
// i + e' + f
// i + e + f'
// create four clauses
vVars->nSize = 0;
Vec_IntPush( vVars, toLitCond(VarI, 1) );
Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) );
Vec_IntPush( vVars, toLitCond(VarF, 0) );
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
return 0;
vVars->nSize = 0;
Vec_IntPush( vVars, toLitCond(VarI, 1) );
Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) );
Vec_IntPush( vVars, toLitCond(VarF, 1) );
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
return 0;
vVars->nSize = 0;
Vec_IntPush( vVars, toLitCond(VarI, 0) );
Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) );
Vec_IntPush( vVars, toLitCond(VarF, 0) );
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
return 0;
vVars->nSize = 0;
Vec_IntPush( vVars, toLitCond(VarI, 0) );
Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) );
Vec_IntPush( vVars, toLitCond(VarF, 1) );
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
return 0;
if ( VarT == VarE )
{
// assert( fCompT == !fCompE );
return 1;
}
// two additional clauses
// t' & e' -> f' t + e + f'
// t & e -> f t' + e' + f
vVars->nSize = 0;
Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) );
Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) );
Vec_IntPush( vVars, toLitCond(VarF, 1) );
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
return 0;
vVars->nSize = 0;
Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) );
Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) );
Vec_IntPush( vVars, toLitCond(VarF, 0) );
return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
}
/**Function*************************************************************
Synopsis [Returns the array of nodes to be combined into one multi-input AND-gate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ClauseCollectSupergate_rec( Aig_Node_t * pNode, Vec_Ptr_t * vSuper, int fFirst, int fStopAtMux )
{
int RetValue1, RetValue2, i;
// check if the node is visited
if ( Aig_Regular(pNode)->fMarkB )
{
// check if the node occurs in the same polarity
for ( i = 0; i < vSuper->nSize; i++ )
if ( vSuper->pArray[i] == pNode )
return 1;
// check if the node is present in the opposite polarity
for ( i = 0; i < vSuper->nSize; i++ )
if ( vSuper->pArray[i] == Aig_Not(pNode) )
return -1;
assert( 0 );
return 0;
}
// if the new node is complemented or a PI, another gate begins
if ( !fFirst )
if ( Aig_IsComplement(pNode) || !Aig_NodeIsAnd(pNode) || Aig_NodeRefs(pNode) > 1 || fStopAtMux && Aig_NodeIsMuxType(pNode) )
{
Vec_PtrPush( vSuper, pNode );
Aig_Regular(pNode)->fMarkB = 1;
return 0;
}
assert( !Aig_IsComplement(pNode) );
assert( Aig_NodeIsAnd(pNode) );
// go through the branches
RetValue1 = Aig_ClauseCollectSupergate_rec( Aig_NodeChild0(pNode), vSuper, 0, fStopAtMux );
RetValue2 = Aig_ClauseCollectSupergate_rec( Aig_NodeChild1(pNode), vSuper, 0, fStopAtMux );
if ( RetValue1 == -1 || RetValue2 == -1 )
return -1;
// return 1 if at least one branch has a duplicate
return RetValue1 || RetValue2;
}
/**Function*************************************************************
Synopsis [Returns the array of nodes to be combined into one multi-input AND-gate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ClauseCollectSupergate( Aig_Node_t * pNode, int fStopAtMux, Vec_Ptr_t * vNodes )
{
int RetValue, i;
assert( !Aig_IsComplement(pNode) );
// collect the nodes in the implication supergate
Vec_PtrClear( vNodes );
RetValue = Aig_ClauseCollectSupergate_rec( pNode, vNodes, 1, fStopAtMux );
assert( vNodes->nSize > 1 );
// unmark the visited nodes
for ( i = 0; i < vNodes->nSize; i++ )
Aig_Regular((Aig_Node_t *)vNodes->pArray[i])->fMarkB = 0;
// if we found the node and its complement in the same implication supergate,
// return empty set of nodes (meaning that we should use constant-0 node)
if ( RetValue == -1 )
vNodes->nSize = 0;
}
/**Function*************************************************************
Synopsis [Sets up the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ClauseCreateCnfInt( solver * pSat, Aig_Man_t * pNtk )
{
Aig_Node_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE;
Vec_Ptr_t * vNodes, * vSuper;
Vec_Int_t * vVars;
int i, k, fUseMuxes = 1;
// start the data structures
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver
vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
// add the clause for the constant node
pNode = Aig_ManConst1(pNtk);
pNode->fMarkA = 1;
pNode->Data = vNodes->nSize;
Vec_PtrPush( vNodes, pNode );
Aig_ClauseTriv( pSat, pNode, vVars );
// collect the nodes that need clauses and top-level assignments
Aig_ManForEachPo( pNtk, pNode, i )
{
// get the fanin
pFanin = Aig_NodeFanin0(pNode);
// create the node's variable
if ( pFanin->fMarkA == 0 )
{
pFanin->fMarkA = 1;
pFanin->Data = vNodes->nSize;
Vec_PtrPush( vNodes, pFanin );
}
// add the trivial clause
if ( !Aig_ClauseTriv( pSat, Aig_NodeChild0(pNode), vVars ) )
return 0;
}
// add the clauses
Vec_PtrForEachEntry( vNodes, pNode, i )
{
assert( !Aig_IsComplement(pNode) );
if ( !Aig_NodeIsAnd(pNode) )
continue;
//printf( "%d ", pNode->Id );
// add the clauses
if ( fUseMuxes && Aig_NodeIsMuxType(pNode) )
{
pNode->pMan->nMuxes++;
pNodeC = Aig_NodeRecognizeMux( pNode, &pNodeT, &pNodeE );
Vec_PtrClear( vSuper );
Vec_PtrPush( vSuper, pNodeC );
Vec_PtrPush( vSuper, pNodeT );
Vec_PtrPush( vSuper, pNodeE );
// add the fanin nodes to explore
Vec_PtrForEachEntry( vSuper, pFanin, k )
{
pFanin = Aig_Regular(pFanin);
if ( pFanin->fMarkA == 0 )
{
pFanin->fMarkA = 1;
pFanin->Data = vNodes->nSize;
Vec_PtrPush( vNodes, pFanin );
}
}
// add the clauses
if ( !Aig_ClauseMux( pSat, pNode, pNodeC, pNodeT, pNodeE, vVars ) )
return 0;
}
else
{
// get the supergate
Aig_ClauseCollectSupergate( pNode, fUseMuxes, vSuper );
// add the fanin nodes to explore
Vec_PtrForEachEntry( vSuper, pFanin, k )
{
pFanin = Aig_Regular(pFanin);
if ( pFanin->fMarkA == 0 )
{
pFanin->fMarkA = 1;
pFanin->Data = vNodes->nSize;
Vec_PtrPush( vNodes, pFanin );
}
}
// add the clauses
if ( vSuper->nSize == 0 )
{
if ( !Aig_ClauseTriv( pSat, Aig_Not(pNode), vVars ) )
return 0;
}
else
{
if ( !Aig_ClauseAnd( pSat, pNode, vSuper, vVars ) )
return 0;
}
}
}
// delete
Vec_IntFree( vVars );
Vec_PtrFree( vNodes );
Vec_PtrFree( vSuper );
return 1;
}
/**Function*************************************************************
Synopsis [Sets up the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
solver * Aig_ClauseCreateCnf( Aig_Man_t * pMan )
{
solver * pSat;
Aig_Node_t * pNode;
int RetValue, i, clk = clock();
// clean the marks
Aig_ManForEachNode( pMan, pNode, i )
pNode->fMarkA = 0, pNode->Data = -1;
// create the solver
pMan->nMuxes = 0;
pSat = solver_new();
RetValue = Aig_ClauseCreateCnfInt( pSat, pMan );
// Asat_SolverWriteDimacs( pSat, "temp_sat.cnf", NULL, NULL, 1 );
if ( RetValue == 0 )
{
solver_delete(pSat);
Aig_ManForEachNode( pMan, pNode, i )
pNode->fMarkA = 0;
return NULL;
}
printf( "The number of MUXes detected = %d (%5.2f %% of logic). ",
pNode->pMan->nMuxes, 300.0*pNode->pMan->nMuxes/Aig_ManNodeNum(pMan) );
PRT( "Creating solver", clock() - clk );
return pSat;
}
/**Function*************************************************************
Synopsis [Starts the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_ProofType_t Aig_ClauseSolverStart( Aig_Man_t * pMan )
{
Aig_Node_t * pNode;
int i;
// make sure it has one PO
if ( Aig_ManPoNum(pMan) != 1 )
{
printf( "The miter has other than 1 output.\n" );
return AIG_PROOF_FAIL;
}
// get the solver
assert( pMan->pSat == NULL );
pMan->pSat = Aig_ClauseCreateCnf( pMan );
if ( pMan->pSat == NULL )
return AIG_PROOF_UNSAT;
// get the variable mappings
pMan->vVar2Sat = Vec_IntStart( Aig_ManNodeNum(pMan) );
pMan->vSat2Var = Vec_IntStart( solver_nvars(pMan->pSat) );
Aig_ManForEachNode( pMan, pNode, i )
{
Vec_IntWriteEntry( pMan->vVar2Sat, i, pNode->Data );
if ( pNode->Data >= 0 ) Vec_IntWriteEntry( pMan->vSat2Var, pNode->Data, i );
}
// get the SAT var numbers of the primary inputs
pMan->vPiSatNums = Vec_IntAlloc( Aig_ManPiNum(pMan) );
Aig_ManForEachPi( pMan, pNode, i )
Vec_IntPush( pMan->vPiSatNums, (pNode->Data >= 0)? pNode->Data : 0 );
return AIG_PROOF_NONE;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,129 +0,0 @@
/**CFile****************************************************************
FileName [fraigCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: fraigCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Aig_ProofType_t Aig_FraigProveOutput( Aig_Man_t * pMan );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Top-level equivalence checking procedure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_ProofType_t Aig_FraigProve( Aig_Man_t * pMan )
{
Aig_ProofType_t RetValue;
int clk, status;
// create the solver
RetValue = Aig_ClauseSolverStart( pMan );
if ( RetValue != AIG_PROOF_NONE )
return RetValue;
// perform solving
// simplify the problem
clk = clock();
status = solver_simplify(pMan->pSat);
if ( status == 0 )
{
// printf( "The problem is UNSATISFIABLE after simplification.\n" );
return AIG_PROOF_UNSAT;
}
// try to prove the output
RetValue = Aig_FraigProveOutput( pMan );
if ( RetValue != AIG_PROOF_TIMEOUT )
return RetValue;
// create equivalence classes
Aig_EngineSimulateRandomFirst( pMan );
// reduce equivalence classes using simulation
Aig_EngineSimulateFirst( pMan );
return RetValue;
}
/**Function*************************************************************
Synopsis [Top-level equivalence checking procedure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_ProofType_t Aig_FraigProveOutput( Aig_Man_t * pMan )
{
Aig_ProofType_t RetValue;
int clk, status;
// solve the miter
clk = clock();
pMan->pSat->verbosity = pMan->pParam->fSatVerbose;
status = solver_solve( pMan->pSat, NULL, NULL, 0, 0 );//pMan->pParam->nConfLimit, pMan->pParam->nInsLimit );
if ( status == l_Undef )
{
// printf( "The problem timed out.\n" );
RetValue = AIG_PROOF_TIMEOUT;
}
else if ( status == l_True )
{
// printf( "The problem is SATISFIABLE.\n" );
RetValue = AIG_PROOF_SAT;
}
else if ( status == l_False )
{
// printf( "The problem is UNSATISFIABLE.\n" );
RetValue = AIG_PROOF_UNSAT;
}
else
assert( 0 );
// PRT( "SAT solver time", clock() - clk );
// if the problem is SAT, get the counterexample
if ( status == l_True )
{
if ( pMan->pModel ) free( pMan->pModel );
pMan->pModel = solver_get_model( pMan->pSat, pMan->vPiSatNums->pArray, pMan->vPiSatNums->nSize );
printf( "%d %d %d %d\n", pMan->pModel[0], pMan->pModel[1], pMan->pModel[2], pMan->pModel[3] );
}
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,174 +0,0 @@
/**CFile****************************************************************
FileName [fraigEngine.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: fraigEngine.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Simulates all nodes using random simulation for the first time.]
Description [Assigns the original simulation info and the storage for the
future simulation info.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_EngineSimulateRandomFirst( Aig_Man_t * p )
{
Aig_SimInfo_t * pInfoPi, * pInfoAll;
assert( !p->pInfo && !p->pInfoTemp );
// create random PI info
pInfoPi = Aig_SimInfoAlloc( Aig_ManPiNum(p), p->pParam->nPatsRand, 0 );
Aig_SimInfoRandom( pInfoPi );
// allocate sim info for all nodes
pInfoAll = Aig_SimInfoAlloc( Aig_ManNodeNum(p), p->pParam->nPatsRand, 1 );
// simulate though the circuit
Aig_ManSimulateInfo( p, pInfoPi, pInfoAll );
// detect classes
p->vClasses = Aig_ManDeriveClassesFirst( p, pInfoAll );
Aig_SimInfoFree( pInfoAll );
// save simulation info
p->pInfo = pInfoPi;
p->pInfoPi = Aig_SimInfoAlloc( Aig_ManPiNum(p), Aig_ManPiNum(p)+1, 0 );
p->pInfoTemp = Aig_SimInfoAlloc( Aig_ManNodeNum(p), Aig_ManPiNum(p)+1, 1 );
p->pPatMask = Aig_PatternAlloc( Aig_ManPiNum(p)+1 );
}
/**Function*************************************************************
Synopsis [Starts the simulation engine for the first time.]
Description [Tries several random patterns and their distance-1
minterms hoping to get simulation started.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_EngineSimulateFirst( Aig_Man_t * p )
{
Aig_Pattern_t * pPat;
int i, Counter;
// simulate the pattern of all zeros
pPat = Aig_PatternAlloc( Aig_ManPiNum(p) );
Aig_PatternClean( pPat );
Vec_PtrPush( p->vPats, pPat );
if ( !Aig_EngineSimulate( p ) )
return;
// simulate the pattern of all ones
pPat = Aig_PatternAlloc( Aig_ManPiNum(p) );
Aig_PatternFill( pPat );
Vec_PtrPush( p->vPats, pPat );
if ( !Aig_EngineSimulate( p ) )
return;
// simulate random until the number of new patterns is reasonable
do {
// generate random PI siminfo
Aig_SimInfoRandom( p->pInfoPi );
// simulate this info
Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp );
// split the classes and collect the new patterns
if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) )
Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, NULL );
if ( Vec_VecSize(p->vClasses) == 0 )
return;
// count the number of useful patterns
Counter = Aig_PatternCount(p->pPatMask);
}
while ( Counter > p->nPatsMax/2 );
// perform targetted simulation
for ( i = 0; i < 3; i++ )
{
assert( Vec_PtrSize(p->vPats) == 0 );
// generate random PI siminfo
Aig_SimInfoRandom( p->pInfoPi );
// simulate this info
Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp );
// split the classes and collect the new patterns
if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) )
Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, p->vPats );
if ( Vec_VecSize(p->vClasses) == 0 )
return;
// simulate the remaining patters
if ( Vec_PtrSize(p->vPats) > 0 )
if ( !Aig_EngineSimulate( p ) )
return;
}
}
/**Function*************************************************************
Synopsis [Implements intelligent simulation engine.]
Description [Assumes that the good simulation patterns have been
assigned (p->vPats). Simulates until all of them are gone. Returns 1
if some classes are left. Returns 0 if there is no more classes.]
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_EngineSimulate( Aig_Man_t * p )
{
Aig_Pattern_t * pPat;
if ( Vec_VecSize(p->vClasses) == 0 )
return 0;
assert( Vec_PtrSize(p->vPats) > 0 );
// process patterns
while ( Vec_PtrSize(p->vPats) > 0 && Vec_VecSize(p->vClasses) > 0 )
{
// get the pattern and create new siminfo
pPat = Vec_PtrPop(p->vPats);
assert( pPat->nBits == Aig_ManPiNum(p) );
// create the new siminfo
Aig_SimInfoFromPattern( p->pInfoPi, pPat );
// free the pattern
Aig_PatternFree( pPat );
// simulate this info
Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp );
// split the classes and collect the new patterns
if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) )
Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, p->vPats );
}
return Vec_VecSize(p->vClasses) > 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,47 +0,0 @@
/**CFile****************************************************************
FileName [fraigProve.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: fraigProve.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,361 +0,0 @@
/**CFile****************************************************************
FileName [fraigSim.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: fraigSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Simulates all nodes using the given simulation info.]
Description [Returns the simulation info for all nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t * pInfoAll )
{
Aig_Node_t * pNode;
unsigned * pDataPi, * pDataPo, * pData0, * pData1, * pDataAnd;
int i, k, fComp0, fComp1;
assert( !pInfoPi->Type ); // PI siminfo
// set the constant sim info
pData1 = Aig_SimInfoForNode( pInfoAll, p->pConst1 );
for ( k = 0; k < pInfoPi->nWords; k++ )
pData1[k] = ~((unsigned)0);
// set the PI siminfo
Aig_ManForEachPi( p, pNode, i )
{
pDataPi = Aig_SimInfoForPi( pInfoPi, i );
pDataAnd = Aig_SimInfoForNode( pInfoAll, pNode );
for ( k = 0; k < pInfoPi->nWords; k++ )
pDataAnd[k] = pDataPi[k];
}
// simulate the nodes
Aig_ManForEachAnd( p, pNode, i )
{
pData0 = Aig_SimInfoForNode( pInfoAll, Aig_NodeFanin0(pNode) );
pData1 = Aig_SimInfoForNode( pInfoAll, Aig_NodeFanin1(pNode) );
pDataAnd = Aig_SimInfoForNode( pInfoAll, pNode );
fComp0 = Aig_NodeFaninC0(pNode);
fComp1 = Aig_NodeFaninC1(pNode);
if ( fComp0 && fComp1 )
for ( k = 0; k < pInfoPi->nWords; k++ )
pDataAnd[k] = ~pData0[k] & ~pData1[k];
else if ( fComp0 )
for ( k = 0; k < pInfoPi->nWords; k++ )
pDataAnd[k] = ~pData0[k] & pData1[k];
else if ( fComp1 )
for ( k = 0; k < pInfoPi->nWords; k++ )
pDataAnd[k] = pData0[k] & ~pData1[k];
else
for ( k = 0; k < pInfoPi->nWords; k++ )
pDataAnd[k] = pData0[k] & pData1[k];
}
// derive the PO siminfo
Aig_ManForEachPo( p, pNode, i )
{
pDataPo = Aig_SimInfoForNode( pInfoAll, pNode );
pDataAnd = Aig_SimInfoForNode( pInfoAll, Aig_NodeFanin0(pNode) );
if ( Aig_NodeFaninC0(pNode) )
for ( k = 0; k < pInfoPi->nWords; k++ )
pDataPo[k] = ~pDataAnd[k];
else
for ( k = 0; k < pInfoPi->nWords; k++ )
pDataPo[k] = pDataAnd[k];
}
}
/**Function*************************************************************
Synopsis [Allocates the simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nBits, int Type )
{
Aig_SimInfo_t * p;
p = ALLOC( Aig_SimInfo_t, 1 );
memset( p, 0, sizeof(Aig_SimInfo_t) );
p->Type = Type;
p->nNodes = nNodes;
p->nWords = Aig_BitWordNum(nBits);
p->nPatsCur = nBits;
p->nPatsMax = p->nWords * sizeof(unsigned) * 8;
p->pData = ALLOC( unsigned, nNodes * p->nWords );
return p;
}
/**Function*************************************************************
Synopsis [Sets the simulation info to zero.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_SimInfoClean( Aig_SimInfo_t * p )
{
int i, Size = p->nNodes * p->nWords;
p->nPatsCur = 0;
for ( i = 0; i < Size; i++ )
p->pData[i] = 0;
}
/**Function*************************************************************
Synopsis [Sets the random simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_SimInfoRandom( Aig_SimInfo_t * p )
{
int i, Size = p->nNodes * p->nWords;
unsigned * pData;
for ( i = 0; i < Size; i++ )
p->pData[i] = ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()));
// make sure the first bit of all nodes is 0
for ( i = 0; i < p->nNodes; i++ )
{
pData = p->pData + p->nWords * i;
*pData <<= 1;
}
}
/**Function*************************************************************
Synopsis [Sets the random simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat )
{
unsigned * pData;
int i, k;
assert( p->Type == 0 );
assert( p->nPatsCur == pPat->nBits+1 );
for ( i = 0; i < p->nPatsCur; i++ )
{
// get the pointer to the bitdata for node i
pData = p->pData + p->nWords * i;
// fill in the bit data according to the pattern
if ( Aig_InfoHasBit(pPat->pData, i) ) // PI has bit set to 1
for ( k = 0; k < p->nWords; k++ )
pData[k] = ~((unsigned)0);
else
for ( k = 0; k < p->nWords; k++ )
pData[k] = 0;
// flip one bit, starting from the first pattern
if ( i ) Aig_InfoXorBit( pData, i-1 );
}
}
/**Function*************************************************************
Synopsis [Resizes the simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_SimInfoResize( Aig_SimInfo_t * p )
{
unsigned * pData;
int i, k;
assert( p->nPatsCur == p->nPatsMax );
pData = ALLOC( unsigned, 2 * p->nNodes * p->nWords );
for ( i = 0; i < p->nNodes; i++ )
{
for ( k = 0; k < p->nWords; k++ )
pData[2 * p->nWords * i + k] = p->pData[p->nWords * i + k];
for ( k = 0; k < p->nWords; k++ )
pData[2 * p->nWords * i + k + p->nWords] = 0;
}
p->nWords *= 2;
p->nPatsMax *= 2;
free( p->pData );
p->pData = pData;
}
/**Function*************************************************************
Synopsis [Deallocates the simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_SimInfoFree( Aig_SimInfo_t * p )
{
free( p->pData );
free( p );
}
/**Function*************************************************************
Synopsis [Allocates the simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Pattern_t * Aig_PatternAlloc( int nBits )
{
Aig_Pattern_t * pPat;
pPat = ALLOC( Aig_Pattern_t, 1 );
memset( pPat, 0, sizeof(Aig_Pattern_t) );
pPat->nBits = nBits;
pPat->nWords = Aig_BitWordNum(nBits);
pPat->pData = ALLOC( unsigned, pPat->nWords );
return pPat;
}
/**Function*************************************************************
Synopsis [Cleans the pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_PatternClean( Aig_Pattern_t * pPat )
{
memset( pPat->pData, 0, sizeof(unsigned) * pPat->nWords );
}
/**Function*************************************************************
Synopsis [Cleans the pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_PatternFill( Aig_Pattern_t * pPat )
{
memset( pPat->pData, 0xff, sizeof(unsigned) * pPat->nWords );
}
/**Function*************************************************************
Synopsis [Sets the random pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_PatternRandom( Aig_Pattern_t * pPat )
{
int i;
for ( i = 0; i < pPat->nWords; i++ )
pPat->pData[i] = ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()));
}
/**Function*************************************************************
Synopsis [Counts the number of 1s in the pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_PatternCount( Aig_Pattern_t * pPat )
{
int i, Counter = 0;
for ( i = 0; i < pPat->nBits; i++ )
Counter += Aig_InfoHasBit( pPat->pData, i );
return Counter;
}
/**Function*************************************************************
Synopsis [Deallocates the pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_PatternFree( Aig_Pattern_t * pPat )
{
free( pPat->pData );
free( pPat );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,47 +0,0 @@
/**CFile****************************************************************
FileName [fraigSolver.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: fraigSolver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

Some files were not shown because too many files have changed in this diff Show More