diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2008-01-30 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2008-01-30 08:01:00 -0800 |
commit | 4d30a1e4f1edecff86d5066ce4653a370e59e5e1 (patch) | |
tree | 366355938a4af0a92f848841ac65374f338d691b /src/base/abc | |
parent | 6537f941887b06e588d3acfc97b5fdf48875cc4e (diff) | |
download | abc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.tar.gz abc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.tar.bz2 abc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.zip |
Version abc80130
Diffstat (limited to 'src/base/abc')
-rw-r--r-- | src/base/abc/1.txt | 21 | ||||
-rw-r--r-- | src/base/abc/abc.h | 880 | ||||
-rw-r--r-- | src/base/abc/abcAig.c | 769 | ||||
-rw-r--r-- | src/base/abc/abcBlifMv.c | 970 | ||||
-rw-r--r-- | src/base/abc/abcCheck.c | 442 | ||||
-rw-r--r-- | src/base/abc/abcDfs.c | 961 | ||||
-rw-r--r-- | src/base/abc/abcFanio.c | 167 | ||||
-rw-r--r-- | src/base/abc/abcFunc.c | 781 | ||||
-rw-r--r-- | src/base/abc/abcHie.c | 492 | ||||
-rw-r--r-- | src/base/abc/abcInt.h | 10 | ||||
-rw-r--r-- | src/base/abc/abcLatch.c | 238 | ||||
-rw-r--r-- | src/base/abc/abcLib.c | 454 | ||||
-rw-r--r-- | src/base/abc/abcMinBase.c | 288 | ||||
-rw-r--r-- | src/base/abc/abcNames.c | 366 | ||||
-rw-r--r-- | src/base/abc/abcNetlist.c | 201 | ||||
-rw-r--r-- | src/base/abc/abcNtk.c | 970 | ||||
-rw-r--r-- | src/base/abc/abcObj.c | 817 | ||||
-rw-r--r-- | src/base/abc/abcRefs.c | 310 | ||||
-rw-r--r-- | src/base/abc/abcShow.c | 100 | ||||
-rw-r--r-- | src/base/abc/abcSop.c | 470 | ||||
-rw-r--r-- | src/base/abc/abcUtil.c | 1100 | ||||
-rw-r--r-- | src/base/abc/abc_.c | 2 | ||||
-rw-r--r-- | src/base/abc/module.make | 3 |
23 files changed, 1923 insertions, 8889 deletions
diff --git a/src/base/abc/1.txt b/src/base/abc/1.txt deleted file mode 100644 index c0765c2b..00000000 --- a/src/base/abc/1.txt +++ /dev/null @@ -1,21 +0,0 @@ -Comparing files abcDfs.c and C:\_PROJECTS\AARON\FRETIME\SRC\BASE\ABC\ABCDFS.C -***** abcDfs.c - return pNode->Level; - assert( Abc_ObjIsNode( pNode ) ); - // if this node is already visited, return -***** C:\_PROJECTS\AARON\FRETIME\SRC\BASE\ABC\ABCDFS.C - return pNode->Level; - assert( Abc_ObjIsNode( pNode ) || pNode->Type == ABC_OBJ_CONST1); - // if this node is already visited, return -***** - -***** abcDfs.c - return pNode->Level; - assert( Abc_ObjIsNode( pNode ) ); - // if this node is already visited, return -***** C:\_PROJECTS\AARON\FRETIME\SRC\BASE\ABC\ABCDFS.C - return pNode->Level; - assert( Abc_ObjIsNode( pNode ) || pNode->Type == ABC_OBJ_CONST1); - // if this node is already visited, return -***** - diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 11161698..aea5a62d 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -21,10 +21,6 @@ #ifndef __ABC_H__ #define __ABC_H__ -#ifdef __cplusplus -extern "C" { -#endif - //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -36,11 +32,10 @@ extern "C" { #include <time.h> #include "cuddInt.h" -#include "hop.h" #include "extra.h" +#include "solver.h" #include "vec.h" #include "stmm.h" -#include "nm.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// @@ -48,235 +43,181 @@ extern "C" { // network types typedef enum { - ABC_NTK_NONE = 0, // 0: unknown - ABC_NTK_NETLIST, // 1: network with PIs/POs, latches, nodes, and nets - ABC_NTK_LOGIC, // 2: network with PIs/POs, latches, and nodes - ABC_NTK_STRASH, // 3: structurally hashed AIG (two input AND gates with c-attributes on edges) - ABC_NTK_OTHER // 4: unused + ABC_TYPE_NONE, // 0: unknown + ABC_TYPE_NETLIST, // 1: network with PIs/POs, latches, nodes, and nets + ABC_TYPE_LOGIC, // 2: network with PIs/POs, latches, and nodes + ABC_TYPE_STRASH, // 3: structurally hashed AIG (two input AND gates with c-attributes on edges) + ABC_TYPE_SEQ, // 4: sequential AIG (two input AND gates with c- and latch-attributes on edges) + ABC_TYPE_OTHER // 5: unused } Abc_NtkType_t; // network functionality typedef enum { - ABC_FUNC_NONE = 0, // 0: unknown + ABC_FUNC_NONE, // 0: unknown ABC_FUNC_SOP, // 1: sum-of-products ABC_FUNC_BDD, // 2: binary decision diagrams ABC_FUNC_AIG, // 3: and-inverter graphs ABC_FUNC_MAP, // 4: standard cell library - ABC_FUNC_BLIFMV, // 5: BLIF-MV node functions - ABC_FUNC_BLACKBOX, // 6: black box about which nothing is known - ABC_FUNC_OTHER // 7: unused + ABC_FUNC_OTHER // 5: unused } Abc_NtkFunc_t; // Supported type/functionality combinations: /*------------------------------------------| | | SOP | BDD | AIG | Map | |-----------|-------|-------|-------|-------| -| Netlist | x | | x | x | +| Netlist | x | | | x | |-----------|-------|-------|-------|-------| -| Logic | x | x | x | x | +| Logic | x | x | | x | |-----------|-------|-------|-------|-------| | Strash | | | x | | +|-----------|-------|-------|-------|-------| +| Seq | | | x | | --------------------------------------------|*/ // object types typedef enum { - 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_ASSERT, // 7: assertion terminal - ABC_OBJ_NET, // 8: net - ABC_OBJ_NODE, // 9: node - ABC_OBJ_LATCH, // 10: latch - ABC_OBJ_WHITEBOX, // 11: box with known contents - ABC_OBJ_BLACKBOX, // 12: box with unknown contents - ABC_OBJ_NUMBER // 13: unused + ABC_OBJ_NONE, // 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_OTHER // 6: unused } Abc_ObjType_t; -// latch initial values -typedef enum { - ABC_INIT_NONE = 0, // 0: unknown - ABC_INIT_ZERO, // 1: zero - ABC_INIT_ONE, // 2: one - ABC_INIT_DC, // 3: don't-care - ABC_INIT_OTHER // 4: unused -} Abc_InitType_t; - //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// //typedef int bool; -#ifndef __cplusplus #ifndef bool #define bool int #endif -#endif -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; -typedef struct Abc_Time_t_ Abc_Time_t; +typedef struct Abc_Obj_t_ Abc_Obj_t; +typedef struct Abc_Ntk_t_ Abc_Ntk_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; +typedef struct Abc_Time_t_ Abc_Time_t; struct Abc_Time_t_ { - float Rise; - float Fall; - float Worst; + float Rise; + float Fall; + float Worst; }; struct Abc_Obj_t_ // 12 words { // high-level information - Abc_Ntk_t * pNtk; // the host network - int Id; // the object ID - int TravId; // the traversal ID (if changed, update Abc_NtkIncrementTravId) + Abc_Ntk_t * pNtk; // the host network + unsigned Type : 4; // the object type + unsigned fExor : 1; // marks AIG node that is a root of EXOR + unsigned Id : 27; // the ID of the object // internal information - unsigned Type : 4; // the object type - unsigned fMarkA : 1; // the multipurpose mark - unsigned fMarkB : 1; // the multipurpose mark - unsigned fMarkC : 1; // the multipurpose mark - unsigned fPhase : 1; // the flag to mark the phase of equivalent node - unsigned fExor : 1; // marks AIG node that is a root of EXOR - 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 Level : 20; // the level of the node + unsigned fMarkA : 1; // the multipurpose mark + unsigned fMarkB : 1; // the multipurpose mark + unsigned fMarkC : 1; // the multipurpose mark + unsigned fPhase : 1; // the flag to mark the phase of equivalent node + unsigned TravId : 12; // the traversal ID + unsigned Level : 16; // the level of the node // connectivity - Vec_Int_t vFanins; // the array of fanins - Vec_Int_t vFanouts; // the array of fanouts + Vec_Fan_t vFanins; // the array of fanins + Vec_Fan_t vFanouts; // the array of fanouts // miscellaneous - void * pData; // the network specific data (SOP, BDD, gate, equiv class, etc) - Abc_Obj_t * pNext; // the next pointer in the hash table - Abc_Obj_t * pCopy; // the copy of this object - Hop_Obj_t * pEquiv; // pointer to the HAIG node + void * pData; // the network specific data (SOP, BDD, gate, equiv class, etc) + Abc_Obj_t * pNext; // the next pointer in the hash table + Abc_Obj_t * pCopy; // the copy of this object }; struct Abc_Ntk_t_ { // general information - Abc_NtkType_t ntkType; // type of the network - Abc_NtkFunc_t ntkFunc; // functionality of the network - char * pName; // the network name - char * pSpec; // the name of the spec file if present - Nm_Man_t * pManName; // name manager (stores names of objects) + Abc_NtkType_t ntkType; // type of the network + Abc_NtkFunc_t ntkFunc; // functionality of the network + char * pName; // the network name + char * pSpec; // the name of the spec file if present + // name representation + stmm_table * tName2Net; // the table hashing net names into net pointer + stmm_table * tObj2Name; // the table hashing PI/PO/latch pointers into names // components of the network - Vec_Ptr_t * vObjs; // the array of all objects (net, nodes, latches, etc) - Vec_Ptr_t * vPis; // the array of primary inputs - Vec_Ptr_t * vPos; // the array of primary outputs - Vec_Ptr_t * vCis; // the array of combinational inputs (PIs, latches) - Vec_Ptr_t * vCos; // the array of combinational outputs (POs, asserts, latches) - Vec_Ptr_t * vPios; // the array of PIOs - Vec_Ptr_t * vAsserts; // the array of assertions - Vec_Ptr_t * vBoxes; // the array of boxes - // the number of living objects - int nObjs; // the number of live objs - int nObjCounts[ABC_OBJ_NUMBER]; // the number of objects by type - // the backup network and the step number - Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network - int iStep; // the generation number for the given network - // hierarchy - Abc_Lib_t * pDesign; - short fHieVisited; // flag to mark the visited network - short fHiePath; // flag to mark the network on the path + Vec_Ptr_t * vObjs; // the array of all objects (net, nodes, latches) + Vec_Ptr_t * vCis; // the array of combinational inputs (PIs followed by latches) + Vec_Ptr_t * vCos; // the array of combinational outputs (POs followed by latches) + Vec_Ptr_t * vLats; // the array of latches (or the cutset in the sequential network) + // the stats about the number of living objects + int nObjs; // the number of living objs + int nNets; // the number of living nets + int nNodes; // the number of living nodes + int nLatches; // the number of latches + int nPis; // the number of primary inputs + int nPos; // the number of primary outputs + // the functionality manager + void * pManFunc; // AIG manager, BDD manager, or memory manager for SOPs + // the global functions (BDDs) + void * pManGlob; // the BDD manager + Vec_Ptr_t * vFuncsGlob; // the BDDs of CO functions + // the timing manager (for mapped networks) + Abc_ManTime_t * pManTime; // stores arrival/required times for all nodes + // the cut manager (for AIGs) + void * pManCut; // stores information about the cuts computed for the nodes + // level information (for AIGs) + int LevelMax; // maximum number of levels + Vec_Int_t * vLevelsR; // level in the reverse topological order + // support information + Vec_Ptr_t * vSupps; + // the external don't-care if given + Abc_Ntk_t * pExdc; // the EXDC network // miscellaneous data members - int nTravIds; // the unique traversal IDs of nodes - Extra_MmFixed_t * pMmObj; // memory manager for objects - Extra_MmStep_t * pMmStep; // memory manager for arrays - void * pManFunc; // functionality manager (AIG manager, BDD manager, or memory manager for SOPs) -// Abc_Lib_t * pVerLib; // for structural verilog designs - Abc_ManTime_t * pManTime; // the timing manager (for mapped networks) stores arrival/required times for all nodes - void * pManCut; // the cut manager (for AIGs) stores information about the cuts computed for the nodes - int LevelMax; // maximum number of levels - Vec_Int_t * vLevelsR; // level in the reverse topological order (for AIGs) - Vec_Ptr_t * vSupps; // CO support information - int * pModel; // counter-example (for miters) - void * pSeqModel; // counter-example (for sequential miters) - Abc_Ntk_t * pExdc; // the EXDC network (if given) - void * pData; // misc - Abc_Ntk_t * pCopy; - Hop_Man_t * pHaig; // history AIG - // node attributes - Vec_Ptr_t * vAttrs; // managers of various node attributes (node functionality, global BDDs, etc) -}; - -struct Abc_Lib_t_ -{ - char * pName; // the name of the library - void * pManFunc; // functionality manager for the nodes - Vec_Ptr_t * vTops; // the array of top-level modules - Vec_Ptr_t * vModules; // the array of modules - st_table * tModules; // the table hashing module names into their networks - Abc_Lib_t * pLibrary; // the library used to map this design - void * pGenlib; // the genlib library used to map this design + unsigned nTravIds; // the unique traversal IDs of nodes + Vec_Ptr_t * vPtrTemp; // the temporary array + Vec_Int_t * vIntTemp; // the temporary array + Vec_Str_t * vStrTemp; // the temporary array + void * pData; // the temporary pointer + // the backup network and the step number + Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network + int iStep; // the generation number for the given network + // memory management + Extra_MmFlex_t * pMmNames; // memory manager for net names + Extra_MmFixed_t* pMmObj; // memory manager for objects + Extra_MmStep_t * pMmStep; // memory manager for arrays }; //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// // maximum/minimum operators #define ABC_MIN(a,b) (((a) < (b))? (a) : (b)) #define ABC_MAX(a,b) (((a) > (b))? (a) : (b)) -#define ABC_ABS(a) (((a) >= 0)? (a) :-(a)) -#define ABC_INFINITY (100000000) - -// transforming floats into ints and back -static inline int Abc_Float2Int( float Val ) { return *((int *)&Val); } -static inline float Abc_Int2Float( int Num ) { return *((float *)&Num); } -static inline int Abc_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } -static inline int Abc_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } -static inline int Abc_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } -static inline void Abc_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } -static inline void Abc_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } -static inline unsigned Abc_InfoRandomWord() { return ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand())); } // #define RAND_MAX 0x7fff -static inline void Abc_InfoRandom( unsigned * p, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] = Abc_InfoRandomWord(); } -static inline void Abc_InfoClear( unsigned * p, int nWords ) { memset( p, 0, sizeof(unsigned) * nWords ); } -static inline void Abc_InfoFill( unsigned * p, int nWords ) { memset( p, 0xff, sizeof(unsigned) * nWords );} -static inline void Abc_InfoNot( unsigned * p, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] = ~p[i]; } -static inline int Abc_InfoIsZero( unsigned * p, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) if ( p[i] ) return 0; return 1; } -static inline int Abc_InfoIsOne( unsigned * p, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) if ( ~p[i] ) return 0; return 1; } -static inline void Abc_InfoCopy( unsigned * p, unsigned * q, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] = q[i]; } -static inline void Abc_InfoAnd( unsigned * p, unsigned * q, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] &= q[i]; } -static inline void Abc_InfoOr( unsigned * p, unsigned * q, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] |= q[i]; } -static inline void Abc_InfoXor( unsigned * p, unsigned * q, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] ^= q[i]; } -static inline int Abc_InfoIsOrOne( unsigned * p, unsigned * q, int nWords ){ int i; for ( i = nWords - 1; i >= 0; i-- ) if ( ~(p[i] | q[i]) ) return 0; return 1; } -static inline int Abc_InfoIsOrOne3( unsigned * p, unsigned * q, unsigned * r, int nWords ){ int i; for ( i = nWords - 1; i >= 0; i-- ) if ( ~(p[i] | q[i] | r[i]) ) return 0; return 1; } +#define ABC_INFINITY (10000000) // checking the network type -static inline bool Abc_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_NETLIST; } -static inline bool Abc_NtkIsLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_LOGIC; } -static inline bool Abc_NtkIsStrash( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_STRASH; } - -static inline bool Abc_NtkHasSop( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP; } -static inline bool Abc_NtkHasBdd( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD; } -static inline bool Abc_NtkHasAig( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG; } -static inline bool Abc_NtkHasMapping( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP; } -static inline bool Abc_NtkHasBlifMv( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLIFMV; } -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_NtkIsBlifMvNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLIFMV && 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_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_TYPE_NETLIST; } +static inline bool Abc_NtkIsLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_TYPE_LOGIC; } +static inline bool Abc_NtkIsStrash( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_TYPE_STRASH; } +static inline bool Abc_NtkIsSeq( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_TYPE_SEQ; } + +static inline bool Abc_NtkHasSop( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP; } +static inline bool Abc_NtkHasBdd( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD; } +static inline bool Abc_NtkHasAig( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG; } +static inline bool Abc_NtkHasMapping( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP; } + +static inline bool Abc_NtkIsSopNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_TYPE_NETLIST; } +static inline bool Abc_NtkIsMappedNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_TYPE_NETLIST; } +static inline bool Abc_NtkIsSopLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_TYPE_LOGIC ; } +static inline bool Abc_NtkIsBddLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD && pNtk->ntkType == ABC_TYPE_LOGIC ; } +static inline bool Abc_NtkIsMappedLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_TYPE_LOGIC ; } +static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return pNtk->nLatches == 0; } // reading data members of the network -static inline char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; } -static inline char * Abc_NtkSpec( Abc_Ntk_t * pNtk ) { return pNtk->pSpec; } -static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pNtk->nTravIds; } -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 char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; } +static inline char * Abc_NtkSpec( Abc_Ntk_t * pNtk ) { return pNtk->pSpec; } +static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pNtk->nTravIds; } +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; } // setting data members of the network static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; } @@ -285,127 +226,106 @@ static inline void Abc_NtkSetBackup( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNetBa static inline void Abc_NtkSetStep ( Abc_Ntk_t * pNtk, int iStep ) { pNtk->iStep = iStep; } // getting the number of objects -static inline int Abc_NtkObjNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjs; } -static inline int Abc_NtkObjNumMax( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vObjs); } -static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vPis); } -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_NtkAssertNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vAsserts); } -static inline int Abc_NtkBoxNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vBoxes); } -static inline int Abc_NtkBiNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjCounts[ABC_OBJ_BI]; } -static inline int Abc_NtkBoNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjCounts[ABC_OBJ_BO]; } -static inline int Abc_NtkNetNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjCounts[ABC_OBJ_NET]; } -static inline int Abc_NtkNodeNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjCounts[ABC_OBJ_NODE]; } -static inline int Abc_NtkLatchNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjCounts[ABC_OBJ_LATCH]; } -static inline int Abc_NtkWhiteboxNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjCounts[ABC_OBJ_WHITEBOX]; } -static inline int Abc_NtkBlackboxNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjCounts[ABC_OBJ_BLACKBOX]; } -static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return Abc_NtkLatchNum(pNtk) == 0; } -static inline bool Abc_NtkHasOnlyLatchBoxes(Abc_Ntk_t * pNtk ){ return Abc_NtkLatchNum(pNtk) == Abc_NtkBoxNum(pNtk); } - -// creating simple objects -extern Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ); -static inline Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_PI ); } -static inline Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_PO ); } -static inline Abc_Obj_t * Abc_NtkCreateBi( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_BI ); } -static inline Abc_Obj_t * Abc_NtkCreateBo( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_BO ); } -static inline Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_ASSERT ); } -static inline Abc_Obj_t * Abc_NtkCreateNet( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_NET ); } -static inline Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_NODE ); } -static inline Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_LATCH ); } -static inline Abc_Obj_t * Abc_NtkCreateWhitebox( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_WHITEBOX ); } -static inline Abc_Obj_t * Abc_NtkCreateBlackbox( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_BLACKBOX ); } +static inline int Abc_NtkObjNumMax( Abc_Ntk_t * pNtk ) { return pNtk->vObjs->nSize; } +static inline int Abc_NtkObjNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjs; } +static inline int Abc_NtkNetNum( Abc_Ntk_t * pNtk ) { return pNtk->nNets; } +static inline int Abc_NtkNodeNum( Abc_Ntk_t * pNtk ) { return pNtk->nNodes; } +static inline int Abc_NtkLatchNum( Abc_Ntk_t * pNtk ) { return pNtk->nLatches; } +static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return pNtk->nPis; } +static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return pNtk->nPos; } +static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return pNtk->vCis->nSize; } +static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return pNtk->vCos->nSize; } // reading objects -static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vObjs, i ); } -static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPis, i ); } -static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPos, i ); } -static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCis, i ); } -static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCos, i ); } -static inline Abc_Obj_t * Abc_NtkAssert( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vAsserts, i );} -static inline Abc_Obj_t * Abc_NtkBox( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vBoxes, i ); } - -// working with complemented attributes of objects -static inline bool Abc_ObjIsComplement( Abc_Obj_t * p ) { return (bool)((unsigned long)p & (unsigned long)01); } -static inline Abc_Obj_t * Abc_ObjRegular( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned long)p & ~(unsigned long)01); } -static inline Abc_Obj_t * Abc_ObjNot( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned long)p ^ (unsigned long)01); } -static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (Abc_Obj_t *)((unsigned long)p ^ (unsigned long)(c!=0)); } +static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { assert( i < Vec_PtrSize(pNtk->vObjs) ); return pNtk->vObjs->pArray[i]; } +static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { assert( i < Vec_PtrSize(pNtk->vLats) ); return pNtk->vLats->pArray[i]; } +static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPiNum(pNtk) ); return pNtk->vCis->pArray[i]; } +static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPoNum(pNtk) ); return pNtk->vCos->pArray[i]; } +static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkCiNum(pNtk) ); return pNtk->vCis->pArray[i]; } +static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkCoNum(pNtk) ); return pNtk->vCos->pArray[i]; } // reading data members of the object static inline unsigned Abc_ObjType( Abc_Obj_t * pObj ) { return pObj->Type; } static inline unsigned Abc_ObjId( Abc_Obj_t * pObj ) { return pObj->Id; } static inline int Abc_ObjTravId( Abc_Obj_t * pObj ) { return pObj->TravId; } -static inline int Abc_ObjLevel( Abc_Obj_t * pObj ) { return pObj->Level; } -static inline Vec_Int_t * Abc_ObjFaninVec( Abc_Obj_t * pObj ) { return &pObj->vFanins; } -static inline Vec_Int_t * Abc_ObjFanoutVec( Abc_Obj_t * pObj ) { return &pObj->vFanouts; } +static inline Vec_Fan_t * Abc_ObjFaninVec( Abc_Obj_t * pObj ) { return &pObj->vFanins; } +static inline Vec_Fan_t * Abc_ObjFanoutVec( Abc_Obj_t * pObj ) { return &pObj->vFanouts; } static inline Abc_Obj_t * Abc_ObjCopy( Abc_Obj_t * pObj ) { return pObj->pCopy; } static inline Abc_Ntk_t * Abc_ObjNtk( Abc_Obj_t * pObj ) { return pObj->pNtk; } static inline void * Abc_ObjData( Abc_Obj_t * pObj ) { return pObj->pData; } -static inline Hop_Obj_t * Abc_ObjEquiv( Abc_Obj_t * pObj ) { return pObj->pEquiv; } -static inline Abc_Obj_t * Abc_ObjCopyCond( Abc_Obj_t * pObj ) { return Abc_ObjRegular(pObj)->pCopy? Abc_ObjNotCond(Abc_ObjRegular(pObj)->pCopy, Abc_ObjIsComplement(pObj)) : NULL; } // setting data members of the network -static inline void Abc_ObjSetLevel( Abc_Obj_t * pObj, int Level ) { pObj->Level = Level; } -static inline void Abc_ObjSetCopy( Abc_Obj_t * pObj, Abc_Obj_t * pCopy ) { pObj->pCopy = pCopy; } -static inline void Abc_ObjSetData( Abc_Obj_t * pObj, void * pData ) { pObj->pData = pData; } +static inline void Abc_ObjSetCopy( Abc_Obj_t * pObj, Abc_Obj_t * pCopy ) { pObj->pCopy = pCopy; } +static inline void Abc_ObjSetData( Abc_Obj_t * pObj, void * pData ) { pObj->pData = pData; } + +// working with complemented attributes of objects +static inline bool Abc_ObjIsComplement( Abc_Obj_t * p ) { return (bool)(((unsigned)p) & 01); } +static inline Abc_Obj_t * Abc_ObjRegular( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned)(p) & ~01); } +static inline Abc_Obj_t * Abc_ObjNot( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned)(p) ^ 01); } +static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (Abc_Obj_t *)((unsigned)(p) ^ (c)); } // checking the object type -static inline bool Abc_ObjIsPio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PIO; } -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_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; } -static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_BO; } -static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_BI || pObj->Type == ABC_OBJ_ASSERT; } -static inline bool Abc_ObjIsTerm( Abc_Obj_t * pObj ) { return Abc_ObjIsCi(pObj) || Abc_ObjIsCo(pObj); } -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_LATCH || pObj->Type == ABC_OBJ_WHITEBOX || pObj->Type == ABC_OBJ_BLACKBOX; } -static inline bool Abc_ObjIsWhitebox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_WHITEBOX;} -static inline bool Abc_ObjIsBlackbox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BLACKBOX;} -static inline void Abc_ObjBlackboxToWhitebox( Abc_Obj_t * pObj ) { assert( Abc_ObjIsBlackbox(pObj) ); pObj->Type = ABC_OBJ_WHITEBOX; pObj->pNtk->nObjCounts[ABC_OBJ_BLACKBOX]--; pObj->pNtk->nObjCounts[ABC_OBJ_WHITEBOX]++; } +static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; } +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_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_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; } +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; } // 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_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]; } -static inline int Abc_ObjFanoutEdgeNum( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( Abc_NtkHasAig(pObj->pNtk) ); if ( Abc_ObjFaninId0(pFanout) == pObj->Id ) return 0; if ( Abc_ObjFaninId1(pFanout) == pObj->Id ) return 1; assert( 0 ); return -1; } -static inline Abc_Obj_t * Abc_ObjFanout( Abc_Obj_t * pObj, int i ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[i] ]; } -static inline Abc_Obj_t * Abc_ObjFanout0( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[0] ]; } -static inline Abc_Obj_t * Abc_ObjFanin( Abc_Obj_t * pObj, int i ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[i] ]; } -static inline Abc_Obj_t * Abc_ObjFanin0( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[0] ]; } -static inline Abc_Obj_t * Abc_ObjFanin1( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[1] ]; } -static inline Abc_Obj_t * Abc_ObjFanin0Ntk( Abc_Obj_t * pObj ) { return (Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanin0(pObj) : pObj); } -static inline Abc_Obj_t * Abc_ObjFanout0Ntk( Abc_Obj_t * pObj ) { return (Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanout0(pObj) : pObj); } -static inline bool Abc_ObjFaninC0( Abc_Obj_t * pObj ) { return pObj->fCompl0; } -static inline bool Abc_ObjFaninC1( Abc_Obj_t * pObj ) { return pObj->fCompl1; } -static inline bool Abc_ObjFaninC( Abc_Obj_t * pObj, int i ) { assert( i >=0 && i < 2 ); return i? pObj->fCompl1 : pObj->fCompl0; } -static inline void Abc_ObjSetFaninC( Abc_Obj_t * pObj, int i ){ assert( i >=0 && i < 2 ); if ( i ) pObj->fCompl1 = 1; else pObj->fCompl0 = 1; } -static inline void Abc_ObjXorFaninC( Abc_Obj_t * pObj, int i ){ assert( i >=0 && i < 2 ); if ( i ) pObj->fCompl1^= 1; else pObj->fCompl0^= 1; } +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].iFan; } +static inline int Abc_ObjFaninId0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].iFan; } +static inline int Abc_ObjFaninId1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].iFan; } +static inline Abc_Obj_t * Abc_ObjFanout( Abc_Obj_t * pObj, int i ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[i].iFan ]; } +static inline Abc_Obj_t * Abc_ObjFanout0( Abc_Obj_t * pObj ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[0].iFan ]; } +static inline Abc_Obj_t * Abc_ObjFanin( Abc_Obj_t * pObj, int i ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[i].iFan ]; } +static inline Abc_Obj_t * Abc_ObjFanin0( Abc_Obj_t * pObj ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[0].iFan ]; } +static inline Abc_Obj_t * Abc_ObjFanin1( Abc_Obj_t * pObj ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[1].iFan ]; } +static inline Abc_Obj_t * Abc_ObjFanin0Ntk( Abc_Obj_t * pObj ) { return Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanin0(pObj) : pObj; } +static inline Abc_Obj_t * Abc_ObjFanout0Ntk( Abc_Obj_t * pObj ) { return Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanout0(pObj) : pObj; } +static inline bool Abc_ObjFaninC( Abc_Obj_t * pObj, int i ) { return pObj->vFanins.pArray[i].fCompl; } +static inline bool Abc_ObjFaninC0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].fCompl; } +static inline bool Abc_ObjFaninC1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].fCompl; } +static inline bool Abc_ObjFanoutC( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( !Abc_NtkIsLogic(pObj->pNtk) ); return (Abc_ObjFaninId0(pFanout) == (int)pObj->Id)? Abc_ObjFaninC0(pFanout) : Abc_ObjFaninC1(pFanout); } +static inline int Abc_ObjFaninL( Abc_Obj_t * pObj, int i ) { return pObj->vFanins.pArray[i].nLats; } +static inline int Abc_ObjFaninL0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].nLats; } +static inline int Abc_ObjFaninL1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].nLats; } +static inline int Abc_ObjFaninLMin( Abc_Obj_t * pObj ) { assert( Abc_ObjIsNode(pObj) ); return ABC_MIN( Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj) ); } +static inline int Abc_ObjFaninLMax( Abc_Obj_t * pObj ) { assert( Abc_ObjIsNode(pObj) ); return ABC_MAX( Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj) ); } static inline Abc_Obj_t * Abc_ObjChild( Abc_Obj_t * pObj, int i ) { return Abc_ObjNotCond( Abc_ObjFanin(pObj,i), Abc_ObjFaninC(pObj,i) );} static inline Abc_Obj_t * Abc_ObjChild0( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) ); } static inline Abc_Obj_t * Abc_ObjChild1( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj), Abc_ObjFaninC1(pObj) ); } -static inline Abc_Obj_t * Abc_ObjChildCopy( Abc_Obj_t * pObj, int i ){ return Abc_ObjNotCond( Abc_ObjFanin(pObj,i)->pCopy, Abc_ObjFaninC(pObj,i) ); } -static inline Abc_Obj_t * Abc_ObjChild0Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); } -static inline Abc_Obj_t * Abc_ObjChild1Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC1(pObj) ); } -static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Abc_ObjFanin0(pObj)->pData, Abc_ObjFaninC0(pObj) ); } -static inline Abc_Obj_t * Abc_ObjChild1Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Abc_ObjFanin1(pObj)->pData, Abc_ObjFaninC1(pObj) ); } -static inline Hop_Obj_t * Abc_ObjChild0Equiv( Abc_Obj_t * pObj ) { return Hop_NotCond( Abc_ObjFanin0(pObj)->pEquiv, Abc_ObjFaninC0(pObj) ); } -static inline Hop_Obj_t * Abc_ObjChild1Equiv( Abc_Obj_t * pObj ) { return Hop_NotCond( Abc_ObjFanin1(pObj)->pEquiv, Abc_ObjFaninC1(pObj) ); } - -// checking the AIG node types -static inline bool Abc_AigNodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_NtkIsStrash(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)); return Abc_ObjFaninNum(pNode) == 2; } -static inline bool Abc_AigNodeIsChoice( Abc_Obj_t * pNode ) { assert(!Abc_ObjIsComplement(pNode)); assert(Abc_NtkIsStrash(pNode->pNtk)); return pNode->pData != NULL && Abc_ObjFanoutNum(pNode) > 0; } - -// handling persistent nodes -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; } +static inline Abc_Obj_t * Abc_ObjChildCopy( Abc_Obj_t * pObj, int i ){ return Abc_ObjNotCond( Abc_ObjFanin(pObj,i)->pCopy, Abc_ObjFaninC(pObj,i) );} +static inline Abc_Obj_t * Abc_ObjChild0Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); } +static inline Abc_Obj_t * Abc_ObjChild1Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC1(pObj) ); } +static inline Abc_Obj_t * Abc_ObjFanoutFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( !Abc_NtkIsLogic(pObj->pNtk) ); return (Abc_ObjFaninId0(pFanout) == (int)pObj->Id)? Abc_ObjChild0(pFanout) : Abc_ObjChild1(pFanout); } +static inline void Abc_ObjSetFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl = 1; } +static inline void Abc_ObjXorFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl ^= 1; } +static inline void Abc_ObjSetFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats = nLats; } +static inline void Abc_ObjSetFaninL0( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[0].nLats = nLats; } +static inline void Abc_ObjSetFaninL1( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[1].nLats = nLats; } +static inline void Abc_ObjAddFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats += nLats; } +static inline void Abc_ObjAddFaninL0( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[0].nLats += nLats; } +static inline void Abc_ObjAddFaninL1( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[1].nLats += nLats; } +extern int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ); +extern void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ); +extern void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ); +extern int Abc_ObjFanoutLMin( Abc_Obj_t * pObj ); +extern int Abc_ObjFanoutLMax( Abc_Obj_t * pObj ); + +// 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 ); // working with the traversal ID static inline void Abc_NodeSetTravId( Abc_Obj_t * pNode, int TravId ) { pNode->TravId = TravId; } @@ -415,29 +335,12 @@ static inline bool Abc_NodeIsTravIdCurrent( Abc_Obj_t * pNode ) { r static inline bool Abc_NodeIsTravIdPrevious( Abc_Obj_t * pNode ) { return (bool)(pNode->TravId == pNode->pNtk->nTravIds - 1); } // checking initial state of the latches -static inline void Abc_LatchSetInitNone( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_NONE; } -static inline void Abc_LatchSetInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_ZERO; } -static inline void Abc_LatchSetInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_ONE; } -static inline void Abc_LatchSetInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)ABC_INIT_DC; } -static inline bool Abc_LatchIsInitNone( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_NONE; } -static inline bool Abc_LatchIsInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_ZERO; } -static inline bool Abc_LatchIsInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_ONE; } -static inline bool Abc_LatchIsInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_DC; } -static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return (int)pLatch->pData; } - -// global BDDs of the nodes -static inline void * Abc_NtkGlobalBdd( Abc_Ntk_t * pNtk ) { return (void *)Vec_PtrEntry(pNtk->vAttrs, VEC_ATTR_GLOBAL_BDD); } -static inline DdManager * Abc_NtkGlobalBddMan( Abc_Ntk_t * pNtk ) { return (DdManager *)Vec_AttMan( (Vec_Att_t *)Abc_NtkGlobalBdd(pNtk) ); } -static inline DdNode ** Abc_NtkGlobalBddArray( Abc_Ntk_t * pNtk ) { return (DdNode **)Vec_AttArray( (Vec_Att_t *)Abc_NtkGlobalBdd(pNtk) ); } -static inline DdNode * Abc_ObjGlobalBdd( Abc_Obj_t * pObj ) { return (DdNode *)Vec_AttEntry( (Vec_Att_t *)Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id ); } -static inline void Abc_ObjSetGlobalBdd( Abc_Obj_t * pObj, DdNode * bF ) { Vec_AttWriteEntry( (Vec_Att_t *)Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id, bF ); } - -// MV variables of the nodes -static inline void * Abc_NtkMvVar( Abc_Ntk_t * pNtk ) { return Vec_PtrEntry(pNtk->vAttrs, VEC_ATTR_MVVAR); } -static inline void * Abc_NtkMvVarMan( Abc_Ntk_t * pNtk ) { return Abc_NtkMvVar(pNtk)? Vec_AttMan( (Vec_Att_t *)Abc_NtkMvVar(pNtk) ) : NULL; } -static inline void * Abc_ObjMvVar( Abc_Obj_t * pObj ) { return Abc_NtkMvVar(pObj->pNtk)? Vec_AttEntry( (Vec_Att_t *)Abc_NtkMvVar(pObj->pNtk), pObj->Id ) : NULL; } -static inline int Abc_ObjMvVarNum( Abc_Obj_t * pObj ) { return (Abc_NtkMvVar(pObj->pNtk) && Abc_ObjMvVar(pObj))? *((int*)Abc_ObjMvVar(pObj)) : 2; } -static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_AttWriteEntry( (Vec_Att_t *)Abc_NtkMvVar(pObj->pNtk), pObj->Id, pV ); } +static inline void Abc_LatchSetInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)0; } +static inline void Abc_LatchSetInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)1; } +static inline void Abc_LatchSetInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); pLatch->pData = (void *)2; } +static inline bool Abc_LatchIsInit0( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)0; } +static inline bool Abc_LatchIsInit1( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)1; } +static inline bool Abc_LatchIsInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)2; } // outputs the runtime in seconds #define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC)) @@ -447,59 +350,36 @@ static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_At //////////////////////////////////////////////////////////////////////// // objects of the network -#define Abc_NtkForEachObj( pNtk, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pObj) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ - if ( (pObj) == NULL ) {} else -#define Abc_NtkForEachNet( pNtk, pNet, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNet) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ - if ( (pNet) == NULL || !Abc_ObjIsNet(pNet) ) {} else -#define Abc_NtkForEachNode( pNtk, pNode, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ - if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else -#define Abc_NtkForEachGate( pNtk, pNode, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ - if ( (pNode) == NULL || !Abc_ObjIsGate(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_AigNodeIsAnd(pNode) ) {} else -// various boxes -#define Abc_NtkForEachBox( pNtk, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vBoxes)) && (((pObj) = Abc_NtkBox(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachLatch( pNtk, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vBoxes)) && (((pObj) = Abc_NtkBox(pNtk, i)), 1); i++ ) \ - if ( !Abc_ObjIsLatch(pObj) ) {} else -#define Abc_NtkForEachLatchInput( pNtk, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vBoxes)); i++ ) \ - if ( !(Abc_ObjIsLatch(Abc_NtkBox(pNtk, i)) && (((pObj) = Abc_ObjFanin0(Abc_NtkBox(pNtk, i))), 1)) ) {} else -#define Abc_NtkForEachLatchOutput( pNtk, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vBoxes)); i++ ) \ - if ( !(Abc_ObjIsLatch(Abc_NtkBox(pNtk, i)) && (((pObj) = Abc_ObjFanout0(Abc_NtkBox(pNtk, i))), 1)) ) {} else -#define Abc_NtkForEachWhitebox( pNtk, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vBoxes)) && (((pObj) = Abc_NtkBox(pNtk, i)), 1); i++ ) \ - if ( !Abc_ObjIsWhitebox(pObj) ) {} else -#define Abc_NtkForEachBlackbox( pNtk, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vBoxes)) && (((pObj) = Abc_NtkBox(pNtk, i)), 1); i++ ) \ - if ( !Abc_ObjIsBlackbox(pObj) ) {} else +#define Abc_NtkForEachObj( pNtk, pObj, i ) \ + for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \ + if ( pObj = Abc_NtkObj(pNtk, i) ) +#define Abc_NtkForEachNet( pNtk, pNet, i ) \ + for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \ + if ( (pNet = Abc_NtkObj(pNtk, i)) && Abc_ObjIsNet(pNet) ) +#define Abc_NtkForEachNode( pNtk, pNode, i ) \ + for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \ + if ( (pNode = Abc_NtkObj(pNtk, i)) && Abc_ObjIsNode(pNode) ) +#define Abc_NtkForEachLatch( pNtk, pObj, i ) \ + for ( i = 0; i < Vec_PtrSize(pNtk->vLats); i++ ) \ + if ( pObj = Abc_NtkLatch(pNtk, i) ) // inputs and outputs -#define Abc_NtkForEachPi( pNtk, pPi, i ) \ +#define Abc_NtkForEachPi( pNtk, pPi, i ) \ for ( i = 0; (i < Abc_NtkPiNum(pNtk)) && (((pPi) = Abc_NtkPi(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachCi( pNtk, pCi, i ) \ - for ( i = 0; (i < Abc_NtkCiNum(pNtk)) && (((pCi) = Abc_NtkCi(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachPo( pNtk, pPo, i ) \ +#define Abc_NtkForEachPo( pNtk, pPo, i ) \ for ( i = 0; (i < Abc_NtkPoNum(pNtk)) && (((pPo) = Abc_NtkPo(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachCo( pNtk, pCo, i ) \ +#define Abc_NtkForEachCi( pNtk, pCi, i ) \ + for ( i = 0; (i < Abc_NtkCiNum(pNtk)) && (((pCi) = Abc_NtkCi(pNtk, i)), 1); i++ ) +#define Abc_NtkForEachCo( pNtk, pCo, i ) \ for ( i = 0; (i < Abc_NtkCoNum(pNtk)) && (((pCo) = Abc_NtkCo(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachAssert( pNtk, pObj, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vAsserts)) && (((pObj) = Abc_NtkAssert(pNtk, i)), 1); i++ ) // fanin and fanouts -#define Abc_ObjForEachFanin( pObj, pFanin, i ) \ +#define Abc_ObjForEachFanin( pObj, pFanin, i ) \ for ( i = 0; (i < Abc_ObjFaninNum(pObj)) && (((pFanin) = Abc_ObjFanin(pObj, i)), 1); i++ ) -#define Abc_ObjForEachFanout( pObj, pFanout, i ) \ +#define Abc_ObjForEachFanout( pObj, pFanout, i ) \ for ( i = 0; (i < Abc_ObjFanoutNum(pObj)) && (((pFanout) = Abc_ObjFanout(pObj, i)), 1); i++ ) // cubes and literals -#define Abc_SopForEachCube( pSop, nFanins, pCube ) \ +#define Abc_SopForEachCube( pSop, nFanins, pCube ) \ for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 ) -#define Abc_CubeForEachVar( pCube, Value, i ) \ +#define Abc_CubeForEachVar( pCube, Value, i ) \ for ( i = 0; (pCube[i] != ' ') && (Value = pCube[i]); i++ ) @@ -509,92 +389,57 @@ static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_At /*=== abcAig.c ==========================================================*/ extern Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtk ); +extern Abc_Aig_t * Abc_AigDup( Abc_Aig_t * pMan, Abc_Aig_t * pManNew ); 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_AigLevel( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_AigConst1( Abc_Ntk_t * pNtk ); +extern int Abc_AigGetLevelNum( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan ); +extern Abc_Obj_t * Abc_AigReset( Abc_Aig_t * pMan ); extern Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); extern Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); -extern Abc_Obj_t * Abc_AigXorLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, int * pType ); -extern Abc_Obj_t * Abc_AigMuxLookup( Abc_Aig_t * pMan, Abc_Obj_t * pC, Abc_Obj_t * pT, Abc_Obj_t * pE, int * pType ); extern Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); extern Abc_Obj_t * Abc_AigXor( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); extern Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs ); -extern void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, bool fUpdateLevel ); +extern void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew ); extern void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pOld ); -extern void Abc_AigRehash( Abc_Aig_t * pMan ); extern bool Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode ); extern bool Abc_AigNodeHasComplFanoutEdgeTrav( Abc_Obj_t * pNode ); extern void Abc_AigPrintNode( Abc_Obj_t * pNode ); extern bool Abc_AigNodeIsAcyclic( Abc_Obj_t * pNode, Abc_Obj_t * pRoot ); -extern void Abc_AigCheckFaninOrder( Abc_Aig_t * pMan ); -extern void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_AigUpdateStart( Abc_Aig_t * pMan, Vec_Ptr_t ** pvUpdatedNets ); -extern void Abc_AigUpdateStop( Abc_Aig_t * pMan ); -extern void Abc_AigUpdateReset( Abc_Aig_t * pMan ); /*=== abcAttach.c ==========================================================*/ extern int Abc_NtkAttach( Abc_Ntk_t * pNtk ); -/*=== abcBlifMv.c ==========================================================*/ -extern void Abc_NtkStartMvVars( Abc_Ntk_t * pNtk ); -extern void Abc_NtkFreeMvVars( Abc_Ntk_t * pNtk ); -extern void Abc_NtkSetMvVarValues( Abc_Obj_t * pObj, int nValues ); -extern Abc_Ntk_t * Abc_NtkStrashBlifMv( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkInsertBlifMv( Abc_Ntk_t * pNtkBase, Abc_Ntk_t * pNtkLogic ); -extern int Abc_NtkConvertToBlifMv( Abc_Ntk_t * pNtk ); -extern char * Abc_NodeConvertSopToMvSop( int nVars, Vec_Int_t * vSop0, Vec_Int_t * vSop1 ); -extern int Abc_NodeEvalMvCost( int nVars, Vec_Int_t * vSop0, Vec_Int_t * vSop1 ); /*=== abcBalance.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate, bool fSelective, bool fUpdateLevel ); +extern Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate ); /*=== abcCheck.c ==========================================================*/ extern bool Abc_NtkCheck( Abc_Ntk_t * pNtk ); extern bool Abc_NtkCheckRead( Abc_Ntk_t * pNtk ); -extern bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ); extern bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ); -extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fOnlyPis, int fComb ); -extern int Abc_NtkIsAcyclicHierarchy( Abc_Ntk_t * pNtk ); -extern int Abc_NtkCheckUniqueCiNames( Abc_Ntk_t * pNtk ); -extern int Abc_NtkCheckUniqueCoNames( Abc_Ntk_t * pNtk ); -extern int Abc_NtkCheckUniqueCioNames( Abc_Ntk_t * pNtk ); +extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ); /*=== abcCollapse.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose ); +extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose ); /*=== abcCut.c ==========================================================*/ -extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree ); -extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree ); -extern void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fFirst ); +extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj ); +extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj ); extern void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj ); extern void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj ); /*=== abcDfs.c ==========================================================*/ extern Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll ); extern Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes ); extern Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_NtkDfsReverseNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes ); -extern Vec_Ptr_t * Abc_NtkDfsReverseNodesContained( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes ); -extern Vec_Ptr_t * Abc_NtkDfsSeq( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_NtkDfsSeqReverse( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_NtkDfsIter( Abc_Ntk_t * pNtk, int fCollectAll ); -extern Vec_Ptr_t * Abc_NtkDfsHie( Abc_Ntk_t * pNtk, int fCollectAll ); -extern bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_NtkSupport( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes ); extern Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk, int fCollectAll, int fCollectCos ); extern Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi ); -extern int Abc_NtkLevel( Abc_Ntk_t * pNtk ); -extern int Abc_NtkLevelReverse( Abc_Ntk_t * pNtk ); +extern int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk ); extern bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_AigGetLevelizedOrder( Abc_Ntk_t * pNtk, int fCollectCis ); /*=== abcFanio.c ==========================================================*/ extern void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ); extern void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ); extern void Abc_ObjRemoveFanins( Abc_Obj_t * pObj ); extern void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew ); -extern Abc_Obj_t * Abc_ObjInsertBetween( Abc_Obj_t * pNodeIn, Abc_Obj_t * pNodeOut, Abc_ObjType_t Type ); extern void Abc_ObjTransferFanout( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew ); extern void Abc_ObjReplace( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew ); -extern int Abc_ObjFanoutFaninNum( Abc_Obj_t * pFanout, Abc_Obj_t * pFanin ); /*=== abcFraig.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExdc ); -extern void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExdc ); +extern Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes ); extern Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk ); extern int Abc_NtkFraigStore( Abc_Ntk_t * pNtk ); extern Abc_Ntk_t * Abc_NtkFraigRestore(); @@ -602,133 +447,95 @@ extern void Abc_NtkFraigStoreClean(); /*=== abcFunc.c ==========================================================*/ extern int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk ); extern DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ); -extern char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, int fAllPrimes, Vec_Str_t * vCube, int fMode ); -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, int fAllPrimes, char ** ppSop0, char ** ppSop1 ); +extern char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, Vec_Str_t * vCube, int fMode ); +extern int Abc_NtkBddToSop( Abc_Ntk_t * pNtk ); +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 unsigned * Abc_ConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, int fMsbFirst ); -extern int Abc_NtkMapToSop( Abc_Ntk_t * pNtk ); -extern int Abc_NtkToSop( Abc_Ntk_t * pNtk, int fDirect ); -extern int Abc_NtkToBdd( Abc_Ntk_t * pNtk ); -extern int Abc_NtkToAig( Abc_Ntk_t * pNtk ); -/*=== abcHaig.c ==========================================================*/ -extern int Abc_NtkHaigStart( Abc_Ntk_t * pNtk ); -extern int Abc_NtkHaigStop( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkHaigUse( Abc_Ntk_t * pNtk ); -/*=== abcHie.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkFlattenLogicHierarchy( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkConvertBlackboxes( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkInsertNewLogic( Abc_Ntk_t * pNtkH, Abc_Ntk_t * pNtkL ); /*=== 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 ); -extern Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk ); -extern void Abc_NtkInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues ); -extern Abc_Obj_t * Abc_NtkAddLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pDriver, Abc_InitType_t Init ); -extern void Abc_NtkConvertDcLatches( Abc_Ntk_t * pNtk ); - /*=== abcLib.c ==========================================================*/ -extern Abc_Lib_t * Abc_LibCreate( char * pName ); -extern void Abc_LibFree( Abc_Lib_t * pLib, Abc_Ntk_t * pNtk ); -extern void Abc_LibPrint( Abc_Lib_t * pLib ); -extern int Abc_LibAddModel( Abc_Lib_t * pLib, Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_LibFindModelByName( Abc_Lib_t * pLib, char * pName ); -extern int Abc_LibFindTopLevelModels( Abc_Lib_t * pLib ); -extern Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib ); +/*=== abcMap.c ==========================================================*/ +extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk ); /*=== abcMiter.c ==========================================================*/ extern int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk ); extern int Abc_NodeMinimumBase( Abc_Obj_t * pNode ); extern int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk ); extern int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode ); /*=== abcMiter.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb, int nPartSize ); -extern void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode ); -extern Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fOr, int fCompl2 ); -extern Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues ); +extern Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ); extern Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 ); -extern Abc_Ntk_t * Abc_NtkMiterQuantify( Abc_Ntk_t * pNtk, int In, int fExist ); -extern Abc_Ntk_t * Abc_NtkMiterQuantifyPis( Abc_Ntk_t * pNtk ); extern int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter ); 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_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ); +extern Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ); +extern void Abc_NtkDeleteObj( 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_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ); +extern Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ); +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_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 ); /*=== abcNames.c ====================================================*/ +extern char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName ); +extern char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix ); extern char * Abc_ObjName( Abc_Obj_t * pNode ); -extern char * Abc_ObjAssignName( Abc_Obj_t * pObj, char * pName, char * pSuffix ); extern char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix ); -extern char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits ); -extern void Abc_NtkTrasferNames( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -extern void Abc_NtkTrasferNamesNoLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +extern char * Abc_ObjNameUnique( Abc_Ntk_t * pNtk, char * pName ); +extern char * Abc_NtkLogicStoreName( Abc_Obj_t * pNodeNew, char * pNameOld ); +extern char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pNodeNew, char * pNameOld, char * pSuffix ); +extern void Abc_NtkCreateCioNamesTable( Abc_Ntk_t * pNtk ); +extern void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); extern Vec_Ptr_t * Abc_NodeGetFaninNames( Abc_Obj_t * pNode ); extern Vec_Ptr_t * Abc_NodeGetFakeNames( int nNames ); extern void Abc_NodeFreeNames( Vec_Ptr_t * vNames ); extern char ** Abc_NtkCollectCioNames( Abc_Ntk_t * pNtk, int fCollectCos ); extern int Abc_NodeCompareNames( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ); extern void Abc_NtkOrderObjsByName( Abc_Ntk_t * pNtk, int fComb ); -extern void Abc_NtkAddDummyPiNames( Abc_Ntk_t * pNtk ); -extern void Abc_NtkAddDummyPoNames( Abc_Ntk_t * pNtk ); -extern void Abc_NtkAddDummyAssertNames( Abc_Ntk_t * pNtk ); -extern void Abc_NtkAddDummyBoxNames( Abc_Ntk_t * pNtk ); extern void Abc_NtkShortNames( Abc_Ntk_t * pNtk ); /*=== abcNetlist.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkLogicToNetlistBench( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk ); /*=== abcNtbdd.c ==========================================================*/ extern Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ); extern Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk ); -extern DdManager * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose ); -extern DdManager * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ); -extern int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk ); +extern DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fLatchOnly ); +extern void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk ); /*=== abcNtk.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan ); +extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ); extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ); -extern Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ); extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +extern void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +extern void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk ); extern Abc_Ntk_t * Abc_NtkStartRead( char * pName ); extern void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ); extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNodeName, int fUseAllCis ); -extern Abc_Ntk_t * Abc_NtkCreateConeArray( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, int fUseAllCis ); -extern void Abc_NtkAppendToCone( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots ); -extern Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNodeName ); -extern Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ); -extern Abc_Ntk_t * Abc_NtkCreateFromNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ); -extern Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop ); +extern Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis ); +extern Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ); +extern Abc_Ntk_t * Abc_NtkSplitNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ); extern void Abc_NtkDelete( Abc_Ntk_t * pNtk ); extern void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ); -extern void Abc_NtkMakeComb( Abc_Ntk_t * pNtk ); -/*=== 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 Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ); -extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj ); -extern void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes ); -extern void Abc_NtkDeleteAll_rec( Abc_Obj_t * pObj ); -extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName ); -extern Abc_Obj_t * Abc_NtkDupBox( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pBox, int fCopyName ); -extern Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pNode ); -extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkFindCi( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ); -extern Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ); -extern Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); -extern Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); -extern Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); -extern Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 ); -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 ); /*=== abcPrint.c ==========================================================*/ extern void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ); extern void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk ); @@ -737,29 +544,12 @@ extern void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk ); extern void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode ); extern void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames ); 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_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile ); extern void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode ); -extern void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll ); -extern void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj ); -/*=== abcProve.c ==========================================================*/ -extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pParams ); -extern int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars ); -/*=== abcRec.c ==========================================================*/ -extern void Abc_NtkRecStart( Abc_Ntk_t * pNtk, int nVars, int nCuts ); -extern void Abc_NtkRecStop(); -extern void Abc_NtkRecAdd( Abc_Ntk_t * pNtk ); -extern void Abc_NtkRecPs(); -extern void Abc_NtkRecFilter( int iVar, int iPlus ); -extern Abc_Ntk_t * Abc_NtkRecUse(); -extern int Abc_NtkRecIsRunning(); -extern int Abc_NtkRecVarNum(); -extern Vec_Int_t * Abc_NtkRecMemory(); -extern int Abc_NtkRecStrashNode( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, unsigned * pTruth, int nVars ); /*=== abcReconv.c ==========================================================*/ extern Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop ); extern void Abc_NtkManCutStop( Abc_ManCut_t * p ); extern Vec_Ptr_t * Abc_NtkManCutReadCutLarge( Abc_ManCut_t * p ); -extern Vec_Ptr_t * Abc_NtkManCutReadCutSmall( Abc_ManCut_t * p ); extern Vec_Ptr_t * Abc_NtkManCutReadVisited( Abc_ManCut_t * p ); extern Vec_Ptr_t * Abc_NodeFindCut( Abc_ManCut_t * p, Abc_Obj_t * pRoot, bool fContain ); extern void Abc_NodeConeCollect( Abc_Obj_t ** ppRoots, int nRoots, Vec_Ptr_t * vFanins, Vec_Ptr_t * vVisited, int fIncludeFanins ); @@ -768,39 +558,37 @@ extern DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, Dd extern Vec_Ptr_t * Abc_NodeCollectTfoCands( Abc_ManCut_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins, int LevelMax ); /*=== abcRefs.c ==========================================================*/ extern int Abc_NodeMffcSize( Abc_Obj_t * pNode ); -extern int Abc_NodeMffcSizeSupp( Abc_Obj_t * pNode ); extern int Abc_NodeMffcSizeStop( Abc_Obj_t * pNode ); -extern int Abc_NodeMffcLabelAig( Abc_Obj_t * pNode ); extern int Abc_NodeMffcLabel( Abc_Obj_t * pNode ); -extern void Abc_NodeMffsConeSupp( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp ); -extern int Abc_NodeDeref_rec( Abc_Obj_t * pNode ); -extern int Abc_NodeRef_rec( Abc_Obj_t * pNode ); -/*=== abcRefactor.c ==========================================================*/ -extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUpdateLevel, bool fUseZeros, bool fUseDcs, bool fVerbose ); -/*=== abcRewrite.c ==========================================================*/ -extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable ); +extern Vec_Ptr_t * Abc_NodeMffcCollect( Abc_Obj_t * pNode ); +/*=== abcRenode.c ==========================================================*/ +extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple ); +extern DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld ); /*=== abcSat.c ==========================================================*/ -extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects ); -extern void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes ); +extern bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose ); +extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk ); +/*=== abcSeq.c ==========================================================*/ +extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ); +extern int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk ); +extern void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk ); +extern void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk ); +extern void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk ); /*=== abcSop.c ==========================================================*/ extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName ); extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars ); extern char * Abc_SopCreateConst0( Extra_MmFlex_t * pMan ); extern char * Abc_SopCreateConst1( Extra_MmFlex_t * pMan ); extern char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 ); -extern char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ); +extern char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars ); extern char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars ); extern char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ); extern char * Abc_SopCreateOrMultiCube( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ); extern char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars ); extern char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars ); -extern char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars ); extern char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars ); -extern char * Abc_SopCreateMux( Extra_MmFlex_t * pMan ); extern char * Abc_SopCreateInv( Extra_MmFlex_t * pMan ); extern char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan ); -extern char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth ); -extern char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover ); extern int Abc_SopGetCubeNum( char * pSop ); extern int Abc_SopGetLitNum( char * pSop ); extern int Abc_SopGetVarNum( char * pSop ); @@ -814,23 +602,17 @@ 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 char * Abc_SopFromTruthBin( char * pTruth ); -extern char * Abc_SopFromTruthHex( char * pTruth ); -extern char * Abc_SopEncoderPos( Extra_MmFlex_t * pMan, int iValue, int nValues ); -extern char * Abc_SopEncoderLog( Extra_MmFlex_t * pMan, int iBit, int nValues ); -extern char * Abc_SopDecoderPos( Extra_MmFlex_t * pMan, int nValues ); -extern char * Abc_SopDecoderLog( Extra_MmFlex_t * pMan, int nValues ); +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 ); /*=== abcStrash.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, int fAllNodes, int fCleanup, int fRecord ); -extern Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int fRecord ); -extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos ); -extern Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels ); +extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup ); +extern Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ); +extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ); /*=== abcSweep.c ==========================================================*/ -extern int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose ); +extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose ); extern int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose ); -extern int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fLatchSweep, int fAutoSweep, int fVerbose ); +extern int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose ); /*=== abcTiming.c ==========================================================*/ extern Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode ); extern Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode ); @@ -847,73 +629,41 @@ extern void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtk ); extern float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk ); extern Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk ); extern float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk ); -extern int Abc_ObjLevelNew( Abc_Obj_t * pObj ); -extern int Abc_ObjReverseLevelNew( Abc_Obj_t * pObj ); -extern int Abc_ObjRequiredLevel( Abc_Obj_t * pObj ); -extern int Abc_ObjReverseLevel( Abc_Obj_t * pObj ); -extern void Abc_ObjSetReverseLevel( Abc_Obj_t * pObj, int LevelR ); -extern void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk, int nMaxLevelIncrease ); +extern void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk ); extern void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk ); -extern void Abc_NtkUpdateLevel( Abc_Obj_t * pObjNew, Vec_Vec_t * vLevels ); -extern void Abc_NtkUpdateReverseLevel( Abc_Obj_t * pObjNew, Vec_Vec_t * vLevels ); -extern void Abc_NtkUpdate( Abc_Obj_t * pObj, Abc_Obj_t * pObjNew, Vec_Vec_t * vLevels ); +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 ); /*=== abcUtil.c ==========================================================*/ -extern void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFreeMan ); extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk ); -extern void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk ); -extern int Abc_NtkGetCubePairNum( 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 ); -extern int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk ); -extern int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk ); extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk ); -extern void Abc_NtkCleanData( Abc_Ntk_t * pNtk ); -extern void Abc_NtkCleanEquiv( Abc_Ntk_t * pNtk ); -extern int Abc_NtkCountCopy( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_NtkSaveCopy( Abc_Ntk_t * pNtk ); -extern void Abc_NtkLoadCopy( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCopies ); -extern void Abc_NtkCleanNext( Abc_Ntk_t * pNtk ); -extern void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode ); -extern Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode ); extern Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode ); extern bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ); extern int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate ); extern void Abc_VecObjPushUniqueOrderByLevel( Vec_Ptr_t * p, Abc_Obj_t * pNode ); extern bool Abc_NodeIsExorType( Abc_Obj_t * pNode ); extern bool Abc_NodeIsMuxType( Abc_Obj_t * pNode ); -extern bool Abc_NodeIsMuxControlType( Abc_Obj_t * pNode ); extern Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t ** ppNodeT, Abc_Obj_t ** ppNodeE ); extern int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc, Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 ); extern void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); extern void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); -extern Vec_Ptr_t * Abc_NtkCollectLatches( Abc_Ntk_t * pNtk ); extern int Abc_NodeCompareLevelsIncrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ); extern int Abc_NodeCompareLevelsDecrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ); extern Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk ); extern Vec_Ptr_t * Abc_NtkCollectObjects( Abc_Ntk_t * pNtk ); -extern Vec_Int_t * Abc_NtkGetCiIds( Abc_Ntk_t * pNtk ); -extern void Abc_NtkReassignIds( Abc_Ntk_t * pNtk ); -extern int Abc_ObjPointerCompare( void ** pp1, void ** pp2 ); -extern void Abc_NtkTransferCopy( Abc_Ntk_t * pNtk ); -/*=== abcVerify.c ==========================================================*/ -extern int * Abc_NtkVerifyGetCleanModel( Abc_Ntk_t * pNtk, int nFrames ); -extern int * Abc_NtkVerifySimulatePattern( Abc_Ntk_t * pNtk, int * pModel ); - -#ifdef __cplusplus -} -#endif - -#endif //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index 16f66dc6..1d8931ec 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -30,8 +30,6 @@ - there are no dangling nodes (the nodes without fanout) - the level of each AND gate reflects the levels of this fanins - the EXOR-status of each node is up-to-date - - 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 (Abc_AigAnd) - performing elementary Boolean operations (Abc_AigOr, Abc_AigXor, etc) @@ -50,22 +48,17 @@ 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 * pConst1; // the constant 1 node + Abc_Obj_t * pReset; // the sequential reset node Abc_Obj_t ** pBins; // the table bins int nBins; // the size of the table int nEntries; // the total number of entries in the table Vec_Ptr_t * vNodes; // the temporary array of nodes + Vec_Ptr_t * vStackDelete; // the nodes to be deleted Vec_Ptr_t * vStackReplaceOld; // the nodes to be replaced Vec_Ptr_t * vStackReplaceNew; // the nodes to be used for replacement Vec_Vec_t * vLevels; // the nodes to be updated Vec_Vec_t * vLevelsR; // the nodes to be updated - Vec_Ptr_t * vAddedCells; // the added nodes - Vec_Ptr_t * vUpdatedNets; // the nodes whose fanouts have changed - - int nStrash0; - int nStrash1; - int nStrash5; - int nStrash2; }; // iterators through the entries in the linked lists of nodes @@ -81,34 +74,24 @@ struct Abc_Aig_t_ pEnt2 = pEnt? pEnt->pNext: NULL ) // hash key for the structural hash table -//static inline unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; } +static inline unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; } //static inline unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) { return ((unsigned)((a)->Id + (b)->Id) * ((a)->Id + (b)->Id + 1) / 2) % TableSize; } -// hashing the node -static unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) -{ - unsigned Key = 0; - Key ^= Abc_ObjRegular(p0)->Id * 7937; - Key ^= Abc_ObjRegular(p1)->Id * 2971; - Key ^= Abc_ObjIsComplement(p0) * 911; - Key ^= Abc_ObjIsComplement(p1) * 353; - return Key % TableSize; -} - // structural hash table procedures static Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); static Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, Abc_Obj_t * pAnd ); static void Abc_AigAndDelete( Abc_Aig_t * pMan, Abc_Obj_t * pThis ); static void Abc_AigResize( Abc_Aig_t * pMan ); // incremental AIG procedures -static void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel ); +static void Abc_AigReplace_int( Abc_Aig_t * pMan ); +static void Abc_AigDelete_int( Abc_Aig_t * pMan ); static void Abc_AigUpdateLevel_int( Abc_Aig_t * pMan ); static void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan ); static void Abc_AigRemoveFromLevelStructure( Vec_Vec_t * vStruct, Abc_Obj_t * pNode ); static void Abc_AigRemoveFromLevelStructureR( Vec_Vec_t * vStruct, Abc_Obj_t * pNode ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -133,23 +116,83 @@ 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->vStackDelete = Vec_PtrAlloc( 100 ); pMan->vStackReplaceOld = Vec_PtrAlloc( 100 ); pMan->vStackReplaceNew = Vec_PtrAlloc( 100 ); - // create the constant node - assert( pNtkAig->vObjs->nSize == 0 ); - pMan->pConst1 = Abc_NtkCreateObj( pNtkAig, ABC_OBJ_NODE ); - pMan->pConst1->Type = ABC_OBJ_CONST1; - pMan->pConst1->fPhase = 1; - pNtkAig->nObjCounts[ABC_OBJ_NODE]--; + pMan->vLevels = Vec_VecAlloc( 100 ); + pMan->vLevelsR = Vec_VecAlloc( 100 ); // save the current network pMan->pNtkAig = pNtkAig; + // allocate constant nodes + pMan->pConst1 = Abc_NtkCreateNode( pNtkAig ); + pMan->pConst1->fPhase = 1; + pMan->pReset = Abc_NtkCreateNode( pNtkAig ); + // subtract these nodes from the total number + pNtkAig->nNodes -= 2; return pMan; } /**Function************************************************************* + Synopsis [Duplicated the AIG manager.] + + Description [Assumes that CI/CO nodes are already created. + Transfers the latch attributes on the edges.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Aig_t * Abc_AigDup( Abc_Aig_t * pMan, Abc_Aig_t * pManNew ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pObj; + int i; + assert( Abc_NtkCiNum(pMan->pNtkAig) == Abc_NtkCiNum(pManNew->pNtkAig) ); + assert( Abc_NtkCoNum(pMan->pNtkAig) == Abc_NtkCoNum(pManNew->pNtkAig) ); + assert( Abc_NtkLatchNum(pMan->pNtkAig) == Abc_NtkLatchNum(pManNew->pNtkAig) ); + // set mapping of the constant nodes + Abc_AigConst1( pMan )->pCopy = Abc_AigConst1( pManNew ); + Abc_AigReset( pMan )->pCopy = Abc_AigReset( pManNew ); + // set the mapping of CIs/COs + Abc_NtkForEachPi( pMan->pNtkAig, pObj, i ) + pObj->pCopy = Abc_NtkPi( pManNew->pNtkAig, i ); + Abc_NtkForEachPo( pMan->pNtkAig, pObj, i ) + pObj->pCopy = Abc_NtkPo( pManNew->pNtkAig, i ); + Abc_NtkForEachLatch( pMan->pNtkAig, pObj, i ) + pObj->pCopy = Abc_NtkLatch( pManNew->pNtkAig, i ); + // copy internal nodes + vNodes = Abc_AigDfs( pMan->pNtkAig, 1, 0 ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + if ( !Abc_NodeIsAigAnd(pObj) ) + continue; + pObj->pCopy = Abc_AigAnd( pManNew, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); + // transfer latch attributes + Abc_ObjSetFaninL0( pObj->pCopy, Abc_ObjFaninL0(pObj) ); + Abc_ObjSetFaninL1( pObj->pCopy, Abc_ObjFaninL1(pObj) ); + } + // relink the choice nodes + Vec_PtrForEachEntry( vNodes, pObj, i ) + if ( pObj->pData ) + pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy; + Vec_PtrFree( vNodes ); + // relink the CO nodes + Abc_NtkForEachCo( pMan->pNtkAig, pObj, i ) + { + Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); + Abc_ObjSetFaninL0( pObj->pCopy, Abc_ObjFaninL0(pObj) ); + } + // get the number of nodes before and after + if ( Abc_NtkNodeNum(pMan->pNtkAig) != Abc_NtkNodeNum(pManNew->pNtkAig) ) + printf( "Warning: Structural hashing reduced %d nodes (should not happen).\n", + Abc_NtkNodeNum(pMan->pNtkAig) - Abc_NtkNodeNum(pManNew->pNtkAig) ); + return pManNew; +} + +/**Function************************************************************* + Synopsis [Deallocates the local AIG manager.] Description [] @@ -161,15 +204,13 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig ) ***********************************************************************/ void Abc_AigFree( Abc_Aig_t * pMan ) { + assert( Vec_PtrSize( pMan->vStackDelete ) == 0 ); assert( Vec_PtrSize( pMan->vStackReplaceOld ) == 0 ); assert( Vec_PtrSize( pMan->vStackReplaceNew ) == 0 ); // free the table - if ( pMan->vAddedCells ) - Vec_PtrFree( pMan->vAddedCells ); - if ( pMan->vUpdatedNets ) - Vec_PtrFree( pMan->vUpdatedNets ); Vec_VecFree( pMan->vLevels ); Vec_VecFree( pMan->vLevelsR ); + Vec_PtrFree( pMan->vStackDelete ); Vec_PtrFree( pMan->vStackReplaceOld ); Vec_PtrFree( pMan->vStackReplaceNew ); Vec_PtrFree( pMan->vNodes ); @@ -190,23 +231,18 @@ void Abc_AigFree( Abc_Aig_t * pMan ) ***********************************************************************/ int Abc_AigCleanup( Abc_Aig_t * pMan ) { - Vec_Ptr_t * vDangles; Abc_Obj_t * pAnd; - int i, nNodesOld; -// printf( "Strash0 = %d. Strash1 = %d. Strash100 = %d. StrashM = %d.\n", -// pMan->nStrash0, pMan->nStrash1, pMan->nStrash5, pMan->nStrash2 ); - nNodesOld = pMan->nEntries; + int i, Counter; // collect the AND nodes that do not fanout - vDangles = Vec_PtrAlloc( 100 ); + assert( Vec_PtrSize( pMan->vStackDelete ) == 0 ); for ( i = 0; i < pMan->nBins; i++ ) Abc_AigBinForEachEntry( pMan->pBins[i], pAnd ) if ( Abc_ObjFanoutNum(pAnd) == 0 ) - Vec_PtrPush( vDangles, pAnd ); + Vec_PtrPush( pMan->vStackDelete, pAnd ); // process the dangling nodes and their MFFCs - Vec_PtrForEachEntry( vDangles, pAnd, i ) - Abc_AigDeleteNode( pMan, pAnd ); - Vec_PtrFree( vDangles ); - return nNodesOld - pMan->nEntries; + for ( Counter = 0; Vec_PtrSize(pMan->vStackDelete) > 0; Counter++ ) + Abc_AigDelete_int( pMan ); + return Counter; } /**Function************************************************************* @@ -229,7 +265,7 @@ bool Abc_AigCheck( Abc_Aig_t * pMan ) nFanins = Abc_ObjFaninNum(pObj); if ( nFanins == 0 ) { - if ( !Abc_AigNodeIsConst(pObj) ) + if ( pObj != pMan->pConst1 && pObj != pMan->pReset ) { printf( "Abc_AigCheck: The AIG has non-standard constant nodes.\n" ); return 0; @@ -262,16 +298,6 @@ bool Abc_AigCheck( Abc_Aig_t * pMan ) printf( "Abc_AigCheck: The number of nodes in the structural hashing table is wrong.\n" ); return 0; } - // if the node is a choice node, nodes in its class should not have fanouts - Abc_NtkForEachNode( pMan->pNtkAig, pObj, i ) - if ( Abc_AigNodeIsChoice(pObj) ) - for ( pAnd = pObj->pData; pAnd; pAnd = pAnd->pData ) - if ( Abc_ObjFanoutNum(pAnd) > 0 ) - { - printf( "Abc_AigCheck: Representative %s", Abc_ObjName(pAnd) ); - printf( " of choice node %s has %d fanouts.\n", Abc_ObjName(pObj), Abc_ObjFanoutNum(pAnd) ); - return 0; - } return 1; } @@ -286,7 +312,7 @@ bool Abc_AigCheck( Abc_Aig_t * pMan ) SeeAlso [] ***********************************************************************/ -int Abc_AigLevel( Abc_Ntk_t * pNtk ) +int Abc_AigGetLevelNum( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; int i, LevelsMax; @@ -299,6 +325,39 @@ int Abc_AigLevel( Abc_Ntk_t * pNtk ) return LevelsMax; } +/**Function************************************************************* + + Synopsis [Read the constant 1 node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan ) +{ + return pMan->pConst1; +} + +/**Function************************************************************* + + Synopsis [Read the reset node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_AigReset( Abc_Aig_t * pMan ) +{ + return pMan->pReset; +} + + /**Function************************************************************* @@ -326,9 +385,9 @@ Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) Abc_ObjAddFanin( pAnd, p0 ); Abc_ObjAddFanin( pAnd, p1 ); // set the level of the new node - pAnd->Level = 1 + ABC_MAX( Abc_ObjRegular(p0)->Level, Abc_ObjRegular(p1)->Level ); - pAnd->fExor = Abc_NodeIsExorType(pAnd); - pAnd->fPhase = (Abc_ObjIsComplement(p0) ^ Abc_ObjRegular(p0)->fPhase) & (Abc_ObjIsComplement(p1) ^ Abc_ObjRegular(p1)->fPhase); + pAnd->Level = 1 + ABC_MAX( Abc_ObjRegular(p0)->Level, Abc_ObjRegular(p1)->Level ); + pAnd->fExor = Abc_NodeIsExorType(pAnd); + pAnd->fPhase = (Abc_ObjIsComplement(p0) ^ Abc_ObjRegular(p0)->fPhase) & (Abc_ObjIsComplement(p1) ^ Abc_ObjRegular(p1)->fPhase); // add the node to the corresponding linked list in the table Key = Abc_HashKey2( p0, p1, pMan->nBins ); pAnd->pNext = pMan->pBins[Key]; @@ -337,13 +396,6 @@ Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) // create the cuts if defined // if ( pAnd->pNtk->pManCut ) // Abc_NodeGetCuts( pAnd->pNtk->pManCut, pAnd ); - pAnd->pCopy = NULL; - // add the node to the list of updated nodes - if ( pMan->vAddedCells ) - Vec_PtrPush( pMan->vAddedCells, pAnd ); - // create HAIG - if ( pAnd->pNtk->pHaig ) - pAnd->pEquiv = Hop_And( pAnd->pNtk->pHaig, Abc_ObjChild0Equiv(pAnd), Abc_ObjChild1Equiv(pAnd) ); return pAnd; } @@ -376,17 +428,9 @@ Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * Key = Abc_HashKey2( p0, p1, pMan->nBins ); pAnd->pNext = pMan->pBins[Key]; pMan->pBins[Key] = pAnd; - pMan->nEntries++; // create the cuts if defined // if ( pAnd->pNtk->pManCut ) // Abc_NodeGetCuts( pAnd->pNtk->pManCut, pAnd ); - pAnd->pCopy = NULL; - // add the node to the list of updated nodes -// if ( pMan->vAddedCells ) -// Vec_PtrPush( pMan->vAddedCells, pAnd ); - // create HAIG - if ( pAnd->pNtk->pHaig ) - pAnd->pEquiv = Hop_And( pAnd->pNtk->pHaig, Abc_ObjChild0Equiv(pAnd), Abc_ObjChild1Equiv(pAnd) ); return pAnd; } @@ -403,49 +447,25 @@ Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * ***********************************************************************/ Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) { - Abc_Obj_t * pAnd, * pConst1; + Abc_Obj_t * pAnd; unsigned Key; - assert( Abc_ObjRegular(p0)->pNtk->pManFunc == pMan ); - assert( Abc_ObjRegular(p1)->pNtk->pManFunc == pMan ); // check for trivial cases - pConst1 = Abc_AigConst1(pMan->pNtkAig); if ( p0 == p1 ) return p0; if ( p0 == Abc_ObjNot(p1) ) - return Abc_ObjNot(pConst1); - if ( Abc_ObjRegular(p0) == pConst1 ) + return Abc_ObjNot(pMan->pConst1); + if ( Abc_ObjRegular(p0) == pMan->pConst1 ) { - if ( p0 == pConst1 ) + if ( p0 == pMan->pConst1 ) return p1; - return Abc_ObjNot(pConst1); + return Abc_ObjNot(pMan->pConst1); } - if ( Abc_ObjRegular(p1) == pConst1 ) + if ( Abc_ObjRegular(p1) == pMan->pConst1 ) { - if ( p1 == pConst1 ) + if ( p1 == pMan->pConst1 ) return p0; - return Abc_ObjNot(pConst1); - } -/* - { - int nFans0 = Abc_ObjFanoutNum( Abc_ObjRegular(p0) ); - int nFans1 = Abc_ObjFanoutNum( Abc_ObjRegular(p1) ); - if ( nFans0 == 0 || nFans1 == 0 ) - pMan->nStrash0++; - else if ( nFans0 == 1 || nFans1 == 1 ) - pMan->nStrash1++; - else if ( nFans0 <= 100 && nFans1 <= 100 ) - pMan->nStrash5++; - else - pMan->nStrash2++; - } -*/ - { - int nFans0 = Abc_ObjFanoutNum( Abc_ObjRegular(p0) ); - int nFans1 = Abc_ObjFanoutNum( Abc_ObjRegular(p1) ); - if ( nFans0 == 0 || nFans1 == 0 ) - return NULL; + return Abc_ObjNot(pMan->pConst1); } - // order the arguments if ( Abc_ObjRegular(p0)->Id > Abc_ObjRegular(p1)->Id ) pAnd = p0, p0 = p1, p1 = pAnd; @@ -454,78 +474,7 @@ Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) // find the matching node in the table Abc_AigBinForEachEntry( pMan->pBins[Key], pAnd ) if ( p0 == Abc_ObjChild0(pAnd) && p1 == Abc_ObjChild1(pAnd) ) - { -// assert( Abc_ObjFanoutNum(Abc_ObjRegular(p0)) && Abc_ObjFanoutNum(p1) ); return pAnd; - } - return NULL; -} - -/**Function************************************************************* - - Synopsis [Returns the gate implementing EXOR of the two arguments if it exists.] - - Description [The argument nodes can be complemented.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_AigXorLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, int * pType ) -{ - Abc_Obj_t * pNode1, * pNode2, * pNode; - // set the flag to zero - if ( pType ) *pType = 0; - // check the case of XOR(a,b) = OR(ab, a'b')' - if ( (pNode1 = Abc_AigAndLookup(pMan, Abc_ObjNot(p0), Abc_ObjNot(p1))) && - (pNode2 = Abc_AigAndLookup(pMan, p0, p1)) ) - { - pNode = Abc_AigAndLookup( pMan, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) ); - if ( pNode && pType ) *pType = 1; - return pNode; - } - // check the case of XOR(a,b) = OR(a'b, ab') - if ( (pNode1 = Abc_AigAndLookup(pMan, p0, Abc_ObjNot(p1))) && - (pNode2 = Abc_AigAndLookup(pMan, Abc_ObjNot(p0), p1)) ) - { - pNode = Abc_AigAndLookup( pMan, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) ); - return pNode? Abc_ObjNot(pNode) : NULL; - } - return NULL; -} - -/**Function************************************************************* - - Synopsis [Returns the gate implementing EXOR of the two arguments if it exists.] - - Description [The argument nodes can be complemented.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_AigMuxLookup( Abc_Aig_t * pMan, Abc_Obj_t * pC, Abc_Obj_t * pT, Abc_Obj_t * pE, int * pType ) -{ - Abc_Obj_t * pNode1, * pNode2, * pNode; - // set the flag to zero - if ( pType ) *pType = 0; - // check the case of MUX(c,t,e) = OR(ct', c'e')' - if ( (pNode1 = Abc_AigAndLookup(pMan, pC, Abc_ObjNot(pT))) && - (pNode2 = Abc_AigAndLookup(pMan, Abc_ObjNot(pC), Abc_ObjNot(pE))) ) - { - pNode = Abc_AigAndLookup( pMan, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) ); - if ( pNode && pType ) *pType = 1; - return pNode; - } - // check the case of MUX(c,t,e) = OR(ct, c'e) - if ( (pNode1 = Abc_AigAndLookup(pMan, pC, pT)) && - (pNode2 = Abc_AigAndLookup(pMan, Abc_ObjNot(pC), pE)) ) - { - pNode = Abc_AigAndLookup( pMan, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) ); - return pNode? Abc_ObjNot(pNode) : NULL; - } return NULL; } @@ -542,15 +491,13 @@ Abc_Obj_t * Abc_AigMuxLookup( Abc_Aig_t * pMan, Abc_Obj_t * pC, Abc_Obj_t * pT, ***********************************************************************/ void Abc_AigAndDelete( Abc_Aig_t * pMan, Abc_Obj_t * pThis ) { - Abc_Obj_t * pAnd, * pAnd0, * pAnd1, ** ppPlace; + Abc_Obj_t * pAnd, ** ppPlace; unsigned Key; assert( !Abc_ObjIsComplement(pThis) ); assert( Abc_ObjIsNode(pThis) ); assert( Abc_ObjFaninNum(pThis) == 2 ); assert( pMan->pNtkAig == pThis->pNtk ); // get the hash key for these two nodes - pAnd0 = Abc_ObjRegular( Abc_ObjChild0(pThis) ); - pAnd1 = Abc_ObjRegular( Abc_ObjChild1(pThis) ); Key = Abc_HashKey2( Abc_ObjChild0(pThis), Abc_ObjChild1(pThis), pMan->nBins ); // find the matching node in the table ppPlace = pMan->pBins + Key; @@ -614,77 +561,9 @@ clk = clock(); pMan->nBins = nBinsNew; } -/**Function************************************************************* - Synopsis [Resizes the hash table of AIG nodes.] - Description [] - - SideEffects [] - SeeAlso [] - -***********************************************************************/ -void Abc_AigRehash( Abc_Aig_t * pMan ) -{ - Abc_Obj_t ** pBinsNew; - Abc_Obj_t * pEnt, * pEnt2; - int * pArray; - unsigned Key; - int Counter, Temp, i; - - // allocate a new array - pBinsNew = ALLOC( Abc_Obj_t *, pMan->nBins ); - memset( pBinsNew, 0, sizeof(Abc_Obj_t *) * pMan->nBins ); - // rehash the entries from the old table - Counter = 0; - for ( i = 0; i < pMan->nBins; i++ ) - Abc_AigBinForEachEntrySafe( pMan->pBins[i], pEnt, pEnt2 ) - { - // swap the fanins if needed - pArray = pEnt->vFanins.pArray; - if ( pArray[0] > pArray[1] ) - { - Temp = pArray[0]; - pArray[0] = pArray[1]; - pArray[1] = Temp; - Temp = pEnt->fCompl0; - pEnt->fCompl0 = pEnt->fCompl1; - pEnt->fCompl1 = Temp; - } - // rehash the node - Key = Abc_HashKey2( Abc_ObjChild0(pEnt), Abc_ObjChild1(pEnt), pMan->nBins ); - pEnt->pNext = pBinsNew[Key]; - pBinsNew[Key] = pEnt; - Counter++; - } - assert( Counter == pMan->nEntries ); - // replace the table and the parameters - free( pMan->pBins ); - pMan->pBins = pBinsNew; -} - - - - - - -/**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) ); - return ((Abc_Aig_t *)pNtk->pManFunc)->pConst1; -} /**Function************************************************************* @@ -700,7 +579,7 @@ Abc_Obj_t * Abc_AigConst1( Abc_Ntk_t * pNtk ) Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) { Abc_Obj_t * pAnd; - if ( (pAnd = Abc_AigAndLookup( pMan, p0, p1 )) ) + if ( pAnd = Abc_AigAndLookup( pMan, p0, p1 ) ) return pAnd; return Abc_AigAndCreate( pMan, p0, p1 ); } @@ -737,28 +616,7 @@ Abc_Obj_t * Abc_AigXor( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) return Abc_AigOr( pMan, Abc_AigAnd(pMan, p0, Abc_ObjNot(p1)), Abc_AigAnd(pMan, p1, Abc_ObjNot(p0)) ); } - -/**Function************************************************************* - - Synopsis [Implements the miter.] - - Description [] - - SideEffects [] - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_AigMiter_rec( Abc_Aig_t * pMan, Abc_Obj_t ** ppObjs, int nObjs ) -{ - Abc_Obj_t * pObj1, * pObj2; - if ( nObjs == 1 ) - return ppObjs[0]; - pObj1 = Abc_AigMiter_rec( pMan, ppObjs, nObjs/2 ); - pObj2 = Abc_AigMiter_rec( pMan, ppObjs + nObjs/2, nObjs - nObjs/2 ); - return Abc_AigOr( pMan, pObj1, pObj2 ); -} - /**Function************************************************************* Synopsis [Implements the miter.] @@ -772,35 +630,11 @@ Abc_Obj_t * Abc_AigMiter_rec( Abc_Aig_t * pMan, Abc_Obj_t ** ppObjs, int nObjs ) ***********************************************************************/ Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs ) { - int i; - if ( vPairs->nSize == 0 ) - 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 ) - vPairs->pArray[i/2] = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] ); - vPairs->nSize = vPairs->nSize/2; - return Abc_AigMiter_rec( pMan, (Abc_Obj_t **)vPairs->pArray, vPairs->nSize ); -} - -/**Function************************************************************* - - Synopsis [Implements the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_AigMiter2( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs ) -{ Abc_Obj_t * pMiter, * pXor; int i; assert( vPairs->nSize % 2 == 0 ); // go through the cubes of the node's SOP - pMiter = Abc_ObjNot( Abc_AigConst1(pMan->pNtkAig) ); + pMiter = Abc_ObjNot(pMan->pConst1); for ( i = 0; i < vPairs->nSize; i += 2 ) { pXor = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] ); @@ -823,29 +657,17 @@ Abc_Obj_t * Abc_AigMiter2( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs ) SeeAlso [] ***********************************************************************/ -void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, bool fUpdateLevel ) +void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew ) { assert( Vec_PtrSize(pMan->vStackReplaceOld) == 0 ); assert( Vec_PtrSize(pMan->vStackReplaceNew) == 0 ); + assert( Vec_PtrSize(pMan->vStackDelete) == 0 ); Vec_PtrPush( pMan->vStackReplaceOld, pOld ); Vec_PtrPush( pMan->vStackReplaceNew, pNew ); - assert( !Abc_ObjIsComplement(pOld) ); - // create HAIG - if ( pOld->pNtk->pHaig ) - Hop_ObjCreateChoice( pOld->pEquiv, Abc_ObjRegular(pNew)->pEquiv ); - // process the replacements while ( Vec_PtrSize(pMan->vStackReplaceOld) ) - { - pOld = Vec_PtrPop( pMan->vStackReplaceOld ); - pNew = Vec_PtrPop( pMan->vStackReplaceNew ); - Abc_AigReplace_int( pMan, pOld, pNew, fUpdateLevel ); - } - if ( fUpdateLevel ) - { - Abc_AigUpdateLevel_int( pMan ); - if ( pMan->pNtkAig->vLevelsR ) - Abc_AigUpdateLevelR_int( pMan ); - } + Abc_AigReplace_int( pMan ); + Abc_AigUpdateLevel_int( pMan ); + Abc_AigUpdateLevelR_int( pMan ); } /**Function************************************************************* @@ -859,10 +681,14 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, bool SeeAlso [] ***********************************************************************/ -void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel ) +void Abc_AigReplace_int( Abc_Aig_t * pMan ) { - Abc_Obj_t * pFanin1, * pFanin2, * pFanout, * pFanoutNew, * pFanoutFanout; - int k, v, iFanin; + Abc_Obj_t * pOld, * pNew, * pFanin1, * pFanin2, * pFanout, * pFanoutNew, * pFanoutFanout; + int k, v, iFanin; + // get the pair of nodes to replace + assert( Vec_PtrSize(pMan->vStackReplaceOld) > 0 ); + pOld = Vec_PtrPop( pMan->vStackReplaceOld ); + pNew = Vec_PtrPop( pMan->vStackReplaceNew ); // make sure the old node is regular and has fanouts // (the new node can be complemented and can have fanouts) assert( !Abc_ObjIsComplement(pOld) ); @@ -877,7 +703,7 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i continue; } // find the old node as a fanin of this fanout - iFanin = Vec_IntFind( &pFanout->vFanins, pOld->Id ); + iFanin = Vec_FanFindEntry( &pFanout->vFanins, pOld->Id ); assert( iFanin == 0 || iFanin == 1 ); // get the new fanin pFanin1 = Abc_ObjNotCond( pNew, Abc_ObjFaninC(pFanout, iFanin) ); @@ -886,7 +712,7 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i pFanin2 = Abc_ObjChild( pFanout, iFanin ^ 1 ); assert( Abc_ObjRegular(pFanin2) != pFanout ); // check if the node with these fanins exists - if ( (pFanoutNew = Abc_AigAndLookup( pMan, pFanin1, pFanin2 )) ) + if ( pFanoutNew = Abc_AigAndLookup( pMan, pFanin1, pFanin2 ) ) { // such node exists (it may be a constant) // schedule replacement of the old fanout by the new fanout Vec_PtrPush( pMan->vStackReplaceOld, pFanout ); @@ -912,24 +738,18 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i Abc_AigAndCreateFrom( pMan, pFanin1, pFanin2, pFanout ); assert( Abc_AigNodeIsAcyclic(pFanout, pFanout) ); - if ( fUpdateLevel ) - { - // schedule the updated fanout for updating direct level - assert( pFanout->fMarkA == 0 ); - pFanout->fMarkA = 1; - Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout ); - // schedule the updated fanout for updating reverse level - if ( pMan->pNtkAig->vLevelsR ) - { - assert( pFanout->fMarkB == 0 ); - pFanout->fMarkB = 1; - Vec_VecPush( pMan->vLevelsR, Abc_ObjReverseLevel(pFanout), pFanout ); - } - } + // schedule the updated fanout for updating direct level + assert( pFanout->fMarkA == 0 ); + pFanout->fMarkA = 1; + Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout ); + // schedule the updated fanout for updating reverse level + assert( pFanout->fMarkB == 0 ); + pFanout->fMarkB = 1; + Vec_VecPush( pMan->vLevelsR, Abc_NodeReadReverseLevel(pFanout), pFanout ); // the fanout has changed, update EXOR status of its fanouts Abc_ObjForEachFanout( pFanout, pFanoutFanout, v ) - if ( Abc_AigNodeIsAnd(pFanoutFanout) ) + if ( Abc_NodeIsAigAnd(pFanoutFanout) ) pFanoutFanout->fExor = Abc_NodeIsExorType(pFanoutFanout); } // if the node has no fanouts left, remove its MFFC @@ -948,65 +768,88 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i SeeAlso [] ***********************************************************************/ -void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) +void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pOld ) { - Abc_Obj_t * pNode0, * pNode1, * pTemp; - int i, k; + assert( Vec_PtrSize(pMan->vStackDelete) == 0 ); + Vec_PtrPush( pMan->vStackDelete, pOld ); + while ( Vec_PtrSize(pMan->vStackDelete) ) + Abc_AigDelete_int( pMan ); +} + +/**Function************************************************************* + + Synopsis [Performs internal deletion step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_AigDelete_int( Abc_Aig_t * pMan ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pRoot, * pObj; + int k; + // get the node to delete + assert( Vec_PtrSize(pMan->vStackDelete) > 0 ); + pRoot = Vec_PtrPop( pMan->vStackDelete ); // make sure the node is regular and dangling - assert( !Abc_ObjIsComplement(pNode) ); - assert( Abc_ObjIsNode(pNode) ); - assert( Abc_ObjFaninNum(pNode) == 2 ); - assert( Abc_ObjFanoutNum(pNode) == 0 ); - - // when deleting an old node that is scheduled for replacement, remove it from the replacement queue - Vec_PtrForEachEntry( pMan->vStackReplaceOld, pTemp, i ) - if ( pNode == pTemp ) + assert( !Abc_ObjIsComplement(pRoot) ); + assert( Abc_ObjIsNode(pRoot) ); + assert( Abc_ObjFaninNum(pRoot) == 2 ); + assert( Abc_ObjFanoutNum(pRoot) == 0 ); + + // collect the MFFC + vNodes = Abc_NodeMffcCollect( pRoot ); + + // if reverse levels are specified, schedule fanins of MFFC for updating + // currently, we do not do it because we do not know the correct level of the fanins + // also, it is unlikely that this will make a difference since we are + // processing the network forward while at this point fanins are left behind... +/* + if ( pObj->pNtk->vLevelsR ) + Vec_PtrForEachEntry( vNodes, pObj, k ) { - // remove the entry from the replacement array - for ( k = i; k < pMan->vStackReplaceOld->nSize - 1; k++ ) + Abc_Obj_t * pFanin; + if ( Abc_ObjIsCi(pObj) ) + continue; + pFanin = Abc_ObjFanin0(pObj); + if ( pFanin->fMarkB == 0 ) { - pMan->vStackReplaceOld->pArray[k] = pMan->vStackReplaceOld->pArray[k+1]; - pMan->vStackReplaceNew->pArray[k] = pMan->vStackReplaceNew->pArray[k+1]; + pFanin->fMarkB = 1; + Vec_VecPush( pMan->vLevelsR, Abc_NodeReadReverseLevel(pFanin), pFanin ); + } + pFanin = Abc_ObjFanin1(pObj); + if ( pFanin->fMarkB == 0 ) + { + pFanin->fMarkB = 1; + Vec_VecPush( pMan->vLevelsR, Abc_NodeReadReverseLevel(pFanin), pFanin ); } - pMan->vStackReplaceOld->nSize--; - pMan->vStackReplaceNew->nSize--; } +*/ - // when deleting a new node that should replace another node, do not delete - Vec_PtrForEachEntry( pMan->vStackReplaceNew, pTemp, i ) - if ( pNode == Abc_ObjRegular(pTemp) ) - return; - - // remember the node's fanins - pNode0 = Abc_ObjFanin0( pNode ); - pNode1 = Abc_ObjFanin1( pNode ); - - // add the node to the list of updated nodes - if ( pMan->vUpdatedNets ) + // delete the nodes in MFFC + Vec_PtrForEachEntry( vNodes, pObj, k ) { - Vec_PtrPushUnique( pMan->vUpdatedNets, pNode0 ); - Vec_PtrPushUnique( pMan->vUpdatedNets, pNode1 ); + if ( Abc_ObjIsCi(pObj) ) + continue; + assert( Abc_ObjFanoutNum(pObj) == 0 ); + // remove the node from the table + Abc_AigAndDelete( pMan, pObj ); + // if the node is in the level structure, remove it + if ( pObj->fMarkA ) + Abc_AigRemoveFromLevelStructure( pMan->vLevels, pObj ); + if ( pObj->fMarkB ) + Abc_AigRemoveFromLevelStructureR( pMan->vLevelsR, pObj ); + // remove the node from the network + Abc_NtkDeleteObj( pObj ); } - - // remove the node from the table - Abc_AigAndDelete( pMan, pNode ); - // if the node is in the level structure, remove it - if ( pNode->fMarkA ) - Abc_AigRemoveFromLevelStructure( pMan->vLevels, pNode ); - if ( pNode->fMarkB ) - Abc_AigRemoveFromLevelStructureR( pMan->vLevelsR, pNode ); - // remove the node from the network - Abc_NtkDeleteObj( pNode ); - - // call recursively for the fanins - if ( Abc_ObjIsNode(pNode0) && pNode0->vFanouts.nSize == 0 ) - Abc_AigDeleteNode( pMan, pNode0 ); - if ( Abc_ObjIsNode(pNode1) && pNode1->vFanouts.nSize == 0 ) - Abc_AigDeleteNode( pMan, pNode1 ); + Vec_PtrFree( vNodes ); } - /**Function************************************************************* Synopsis [Updates the level of the node after it has changed.] @@ -1094,7 +937,7 @@ void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan ) if ( pNode == NULL ) continue; assert( Abc_ObjIsNode(pNode) ); - assert( Abc_ObjReverseLevel(pNode) == i ); + assert( Abc_NodeReadReverseLevel(pNode) == i ); // clean the mark assert( pNode->fMarkB == 1 ); pNode->fMarkB = 0; @@ -1106,17 +949,17 @@ void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan ) // get the new reverse level of this fanin LevelNew = 0; Abc_ObjForEachFanout( pFanin, pFanout, j ) - if ( LevelNew < Abc_ObjReverseLevel(pFanout) ) - LevelNew = Abc_ObjReverseLevel(pFanout); + if ( LevelNew < Abc_NodeReadReverseLevel(pFanout) ) + LevelNew = Abc_NodeReadReverseLevel(pFanout); LevelNew += 1; assert( LevelNew > i ); - if ( Abc_ObjReverseLevel(pFanin) == LevelNew ) // no change + if ( Abc_NodeReadReverseLevel(pFanin) == LevelNew ) // no change continue; // if the fanin is present in the data structure, pull it out if ( pFanin->fMarkB ) Abc_AigRemoveFromLevelStructureR( pMan->vLevelsR, pFanin ); // update the reverse level - Abc_ObjSetReverseLevel( pFanin, LevelNew ); + Abc_NodeSetReverseLevel( pFanin, LevelNew ); // add the fanin to the data structure to update its fanins assert( pFanin->fMarkB == 0 ); pFanin->fMarkB = 1; @@ -1173,7 +1016,7 @@ void Abc_AigRemoveFromLevelStructureR( Vec_Vec_t * vStruct, Abc_Obj_t * pNode ) Abc_Obj_t * pTemp; int m; assert( pNode->fMarkB ); - vVecTemp = Vec_VecEntry( vStruct, Abc_ObjReverseLevel(pNode) ); + vVecTemp = Vec_VecEntry( vStruct, Abc_NodeReadReverseLevel(pNode) ); Vec_PtrForEachEntry( vVecTemp, pTemp, m ) { if ( pTemp != pNode ) @@ -1206,7 +1049,7 @@ bool Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode ) int i, iFanin; Abc_ObjForEachFanout( pNode, pFanout, i ) { - iFanin = Vec_IntFind( &pFanout->vFanins, pNode->Id ); + iFanin = Vec_FanFindEntry( &pFanout->vFanins, pNode->Id ); assert( iFanin >= 0 ); if ( Abc_ObjFaninC( pFanout, iFanin ) ) return 1; @@ -1235,7 +1078,7 @@ bool Abc_AigNodeHasComplFanoutEdgeTrav( Abc_Obj_t * pNode ) { if ( !Abc_NodeIsTravIdCurrent(pFanout) ) continue; - iFanin = Vec_IntFind( &pFanout->vFanins, pNode->Id ); + iFanin = Vec_FanFindEntry( &pFanout->vFanins, pNode->Id ); assert( iFanin >= 0 ); if ( Abc_ObjFaninC( pFanout, iFanin ) ) return 1; @@ -1263,7 +1106,7 @@ void Abc_AigPrintNode( Abc_Obj_t * pNode ) printf( "CI %4s%s.\n", Abc_ObjName(pNodeR), Abc_ObjIsComplement(pNode)? "\'" : "" ); return; } - if ( Abc_AigNodeIsConst(pNodeR) ) + if ( Abc_NodeIsConst(pNodeR) ) { printf( "Constant 1 %s.\n", Abc_ObjIsComplement(pNode)? "(complemented)" : "" ); return; @@ -1294,7 +1137,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_AigNodeIsAnd(pNode) ) + if ( !Abc_NodeIsAigAnd(pNode) ) return 1; pFanin0 = Abc_ObjFanin0(pNode); pFanin1 = Abc_ObjFanin1(pNode); @@ -1327,148 +1170,6 @@ bool Abc_AigNodeIsAcyclic( Abc_Obj_t * pNode, Abc_Obj_t * pRoot ) return 1; } -/**Function************************************************************* - - Synopsis [Resizes the hash table of AIG nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_AigCheckFaninOrder( Abc_Aig_t * pMan ) -{ - Abc_Obj_t * pEnt; - int i; - for ( i = 0; i < pMan->nBins; i++ ) - Abc_AigBinForEachEntry( pMan->pBins[i], pEnt ) - { - if ( Abc_ObjRegular(Abc_ObjChild0(pEnt))->Id > Abc_ObjRegular(Abc_ObjChild1(pEnt))->Id ) - { -// int i0 = Abc_ObjRegular(Abc_ObjChild0(pEnt))->Id; -// int i1 = Abc_ObjRegular(Abc_ObjChild1(pEnt))->Id; - printf( "Node %d has incorrect ordering of fanins.\n", pEnt->Id ); - } - } -} - -/**Function************************************************************* - - Synopsis [Sets the correct phase of the nodes.] - - Description [The AIG nodes should be in the DFS order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - assert( Abc_NtkIsDfsOrdered(pNtk) ); - Abc_AigConst1(pNtk)->fPhase = 1; - Abc_NtkForEachPi( pNtk, pObj, i ) - pObj->fPhase = 0; - Abc_NtkForEachLatchOutput( pNtk, pObj, i ) - pObj->fPhase = Abc_LatchIsInit1(pObj); - Abc_AigForEachAnd( pNtk, pObj, i ) - pObj->fPhase = (Abc_ObjFanin0(pObj)->fPhase ^ Abc_ObjFaninC0(pObj)) & (Abc_ObjFanin1(pObj)->fPhase ^ Abc_ObjFaninC1(pObj)); - Abc_NtkForEachPo( pNtk, pObj, i ) - pObj->fPhase = (Abc_ObjFanin0(pObj)->fPhase ^ Abc_ObjFaninC0(pObj)); - Abc_NtkForEachLatchInput( pNtk, pObj, i ) - pObj->fPhase = (Abc_ObjFanin0(pObj)->fPhase ^ Abc_ObjFaninC0(pObj)); -} - - - -/**Function************************************************************* - - Synopsis [Start the update list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_AigUpdateStart( Abc_Aig_t * pMan, Vec_Ptr_t ** pvUpdatedNets ) -{ - assert( pMan->vAddedCells == NULL ); - pMan->vAddedCells = Vec_PtrAlloc( 1000 ); - pMan->vUpdatedNets = Vec_PtrAlloc( 1000 ); - *pvUpdatedNets = pMan->vUpdatedNets; - return pMan->vAddedCells; -} - -/**Function************************************************************* - - Synopsis [Start the update list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_AigUpdateStop( Abc_Aig_t * pMan ) -{ - assert( pMan->vAddedCells != NULL ); - Vec_PtrFree( pMan->vAddedCells ); - Vec_PtrFree( pMan->vUpdatedNets ); - pMan->vAddedCells = NULL; - pMan->vUpdatedNets = NULL; -} - -/**Function************************************************************* - - Synopsis [Start the update list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_AigUpdateReset( Abc_Aig_t * pMan ) -{ - assert( pMan->vAddedCells != NULL ); - Vec_PtrClear( pMan->vAddedCells ); - Vec_PtrClear( pMan->vUpdatedNets ); -} - -/**Function************************************************************* - - Synopsis [Start the update list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_AigCountNext( Abc_Aig_t * pMan ) -{ - Abc_Obj_t * pAnd; - int i, Counter = 0, CounterTotal = 0; - // count how many nodes have pNext set - for ( i = 0; i < pMan->nBins; i++ ) - Abc_AigBinForEachEntry( pMan->pBins[i], pAnd ) - { - Counter += (pAnd->pNext != NULL); - CounterTotal++; - } - printf( "Counter = %d. Nodes = %d. Ave = %6.2f\n", Counter, CounterTotal, 1.0 * CounterTotal/pMan->nBins ); - return Counter; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcBlifMv.c b/src/base/abc/abcBlifMv.c deleted file mode 100644 index 48ec58c0..00000000 --- a/src/base/abc/abcBlifMv.c +++ /dev/null @@ -1,970 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcBlifMv.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Procedures to process BLIF-MV networks and AIGs.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcBlifMv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the Mv-Var manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkStartMvVars( Abc_Ntk_t * pNtk ) -{ - Vec_Att_t * pAttMan; - assert( Abc_NtkMvVar(pNtk) == NULL ); - pAttMan = Vec_AttAlloc( 0, Abc_NtkObjNumMax(pNtk) + 1, Extra_MmFlexStart(), Extra_MmFlexStop, NULL, NULL ); - Vec_PtrWriteEntry( pNtk->vAttrs, VEC_ATTR_MVVAR, pAttMan ); -//printf( "allocing attr\n" ); -} - -/**Function************************************************************* - - Synopsis [Stops the Mv-Var manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFreeMvVars( Abc_Ntk_t * pNtk ) -{ - void * pUserMan; - pUserMan = Abc_NtkAttrFree( pNtk, VEC_ATTR_GLOBAL_BDD, 0 ); - Extra_MmFlexStop( pUserMan ); -} - -/**Function************************************************************* - - Synopsis [Duplicate the MV variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSetMvVarValues( Abc_Obj_t * pObj, int nValues ) -{ - Extra_MmFlex_t * pFlex; - struct temp - { - int nValues; - char ** pNames; - } * pVarStruct; - assert( nValues > 1 ); - // skip binary signals - if ( nValues == 2 ) - return; - // skip already assigned signals - if ( Abc_ObjMvVar(pObj) != NULL ) - return; - // create the structure - pFlex = Abc_NtkMvVarMan( pObj->pNtk ); - pVarStruct = (void *)Extra_MmFlexEntryFetch( pFlex, sizeof(struct temp) ); - pVarStruct->nValues = nValues; - pVarStruct->pNames = NULL; - Abc_ObjSetMvVar( pObj, pVarStruct ); -} - -/**Function************************************************************* - - Synopsis [Strashes the BLIF-MV netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Abc_StringGetNumber( char ** ppStr ) -{ - char * pStr = *ppStr; - int Number = 0; - assert( *pStr >= '0' && *pStr <= '9' ); - for ( ; *pStr >= '0' && *pStr <= '9'; pStr++ ) - Number = 10 * Number + *pStr - '0'; - *ppStr = pStr; - return Number; -} - -/**Function************************************************************* - - Synopsis [Strashes one node in the BLIF-MV netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeStrashBlifMv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) -{ - char * pSop; - Abc_Obj_t ** pValues, ** pValuesF, ** pValuesF2; - Abc_Obj_t * pTemp, * pTemp2, * pFanin, * pFanin2, * pNet; - int k, v, Def, DefIndex, Index, nValues, nValuesF, nValuesF2; - - // start the output values - assert( Abc_ObjIsNode(pObj) ); - pNet = Abc_ObjFanout0(pObj); - nValues = Abc_ObjMvVarNum(pNet); - pValues = ALLOC( Abc_Obj_t *, nValues ); - for ( k = 0; k < nValues; k++ ) - pValues[k] = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); - - // get the BLIF-MV formula - pSop = pObj->pData; - // skip the value line -// while ( *pSop++ != '\n' ); - - // handle the constant - if ( Abc_ObjFaninNum(pObj) == 0 ) - { - // skip the default if present - if ( *pSop == 'd' ) - while ( *pSop++ != '\n' ); - // skip space if present - if ( *pSop == ' ' ) - pSop++; - Index = Abc_StringGetNumber( &pSop ); - assert( Index < nValues ); - pValues[Index] = Abc_AigConst1(pNtkNew); - // save the values in the fanout net - pNet->pCopy = (Abc_Obj_t *)pValues; - return 1; - } - - // parse the default line - Def = DefIndex = -1; - if ( *pSop == 'd' ) - { - pSop++; - if ( *pSop == '=' ) - { - pSop++; - DefIndex = Abc_StringGetNumber( &pSop ); - assert( DefIndex < Abc_ObjFaninNum(pObj) ); - } - else if ( *pSop == '-' ) - { - pSop++; - Def = 0; - } - else - { - Def = Abc_StringGetNumber( &pSop ); - assert( Def < nValues ); - } - assert( *pSop == '\n' ); - pSop++; - } - - // convert the values - while ( *pSop ) - { - // extract the values for each cube - pTemp = Abc_AigConst1(pNtkNew); - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - if ( *pSop == '-' ) - { - pSop += 2; - continue; - } - if ( *pSop == '!' ) - { - printf( "Abc_NodeStrashBlifMv(): Cannot handle complement in the MV function of node %s.\n", Abc_ObjName(Abc_ObjFanout0(pObj)) ); - return 0; - } - if ( *pSop == '{' ) - { - printf( "Abc_NodeStrashBlifMv(): Cannot handle braces in the MV function of node %s.\n", Abc_ObjName(Abc_ObjFanout0(pObj)) ); - return 0; - } - // get the value set - nValuesF = Abc_ObjMvVarNum(pFanin); - pValuesF = (Abc_Obj_t **)pFanin->pCopy; - if ( *pSop == '(' ) - { - pSop++; - pTemp2 = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); - while ( *pSop != ')' ) - { - Index = Abc_StringGetNumber( &pSop ); - assert( Index < nValuesF ); - pTemp2 = Abc_AigOr( pNtkNew->pManFunc, pTemp2, pValuesF[Index] ); - assert( *pSop == ')' || *pSop == ',' ); - if ( *pSop == ',' ) - pSop++; - } - assert( *pSop == ')' ); - pSop++; - } - else if ( *pSop == '=' ) - { - pSop++; - // get the fanin index - Index = Abc_StringGetNumber( &pSop ); - assert( Index < Abc_ObjFaninNum(pObj) ); - assert( Index != k ); - // get the fanin - pFanin2 = Abc_ObjFanin( pObj, Index ); - nValuesF2 = Abc_ObjMvVarNum(pFanin2); - pValuesF2 = (Abc_Obj_t **)pFanin2->pCopy; - // create the sum of products of values - assert( nValuesF == nValuesF2 ); - pTemp2 = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); - for ( v = 0; v < nValues; v++ ) - pTemp2 = Abc_AigOr( pNtkNew->pManFunc, pTemp2, Abc_AigAnd(pNtkNew->pManFunc, pValuesF[v], pValuesF2[v]) ); - } - else - { - Index = Abc_StringGetNumber( &pSop ); - assert( Index < nValuesF ); - pTemp2 = pValuesF[Index]; - } - // compute the compute - pTemp = Abc_AigAnd( pNtkNew->pManFunc, pTemp, pTemp2 ); - // advance the reading point - assert( *pSop == ' ' ); - pSop++; - } - // check if the output value is an equal construct - if ( *pSop == '=' ) - { - pSop++; - // get the output value - Index = Abc_StringGetNumber( &pSop ); - assert( Index < Abc_ObjFaninNum(pObj) ); - // add values of the given fanin with the given cube - pFanin = Abc_ObjFanin( pObj, Index ); - nValuesF = Abc_ObjMvVarNum(pFanin); - pValuesF = (Abc_Obj_t **)pFanin->pCopy; - assert( nValuesF == nValues ); // should be guaranteed by the parser - for ( k = 0; k < nValuesF; k++ ) - pValues[k] = Abc_AigOr( pNtkNew->pManFunc, pValues[k], Abc_AigAnd(pNtkNew->pManFunc, pTemp, pValuesF[k]) ); - } - else - { - // get the output value - Index = Abc_StringGetNumber( &pSop ); - assert( Index < nValues ); - pValues[Index] = Abc_AigOr( pNtkNew->pManFunc, pValues[Index], pTemp ); - } - // advance the reading point - assert( *pSop == '\n' ); - pSop++; - } - - // compute the default value - if ( Def >= 0 || DefIndex >= 0 ) - { - pTemp = Abc_AigConst1(pNtkNew); - for ( k = 0; k < nValues; k++ ) - { - if ( k == Def ) - continue; - pTemp = Abc_AigAnd( pNtkNew->pManFunc, pTemp, Abc_ObjNot(pValues[k]) ); - } - - // assign the default value - if ( Def >= 0 ) - pValues[Def] = pTemp; - else - { - assert( DefIndex >= 0 ); - // add values of the given fanin with the given cube - pFanin = Abc_ObjFanin( pObj, DefIndex ); - nValuesF = Abc_ObjMvVarNum(pFanin); - pValuesF = (Abc_Obj_t **)pFanin->pCopy; - assert( nValuesF == nValues ); // should be guaranteed by the parser - for ( k = 0; k < nValuesF; k++ ) - pValues[k] = Abc_AigOr( pNtkNew->pManFunc, pValues[k], Abc_AigAnd(pNtkNew->pManFunc, pTemp, pValuesF[k]) ); - } - - } - - // save the values in the fanout net - pNet->pCopy = (Abc_Obj_t *)pValues; - return 1; -} - -/**Function************************************************************* - - Synopsis [Assigns name with index.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Abc_NtkConvertAssignName( Abc_Obj_t * pObj, Abc_Obj_t * pNet, int Index ) -{ - char Suffix[16]; - assert( Abc_ObjIsTerm(pObj) ); - assert( Abc_ObjIsNet(pNet) ); - sprintf( Suffix, "[%d]", Index ); - Abc_ObjAssignName( pObj, Abc_ObjName(pNet), Suffix ); -} - -/**Function************************************************************* - - Synopsis [Strashes the BLIF-MV netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkStrashBlifMv( Abc_Ntk_t * pNtk ) -{ - int fUsePositional = 0; - Vec_Ptr_t * vNodes; - Abc_Obj_t ** pBits; - Abc_Obj_t ** pValues; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pTemp, * pBit, * pNet; - int i, k, v, nValues, nValuesMax, nBits; - - assert( Abc_NtkIsNetlist(pNtk) ); - assert( Abc_NtkHasBlifMv(pNtk) ); - assert( Abc_NtkWhiteboxNum(pNtk) == 0 ); - assert( Abc_NtkBlackboxNum(pNtk) == 0 ); - - // get the largest number of values - nValuesMax = 2; - Abc_NtkForEachNet( pNtk, pObj, i ) - { - nValues = Abc_ObjMvVarNum(pObj); - if ( nValuesMax < nValues ) - nValuesMax = nValues; - } - nBits = Extra_Base2Log( nValuesMax ); - pBits = ALLOC( Abc_Obj_t *, nBits ); - - // clean the node copy fields - Abc_NtkCleanCopy( pNtk ); - // collect the nodes - vNodes = Abc_NtkDfs( pNtk, 0 ); - - // start the network - pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); - // duplicate the name and the spec - pNtkNew->pName = Extra_UtilStrsav( pNtk->pName ); -// pNtkNew->pSpec = Extra_UtilStrsav( pNtk->pName ); - - // encode the CI nets - Abc_NtkIncrementTravId( pNtk ); - if ( fUsePositional ) - { - Abc_NtkForEachCi( pNtk, pObj, i ) - { - pNet = Abc_ObjFanout0(pObj); - nValues = Abc_ObjMvVarNum(pNet); - pValues = ALLOC( Abc_Obj_t *, nValues ); - // create PIs for the values - for ( v = 0; v < nValues; v++ ) - { - pValues[v] = Abc_NtkCreatePi( pNtkNew ); - Abc_NtkConvertAssignName( pValues[v], pNet, v ); - } - // save the values in the fanout net - pNet->pCopy = (Abc_Obj_t *)pValues; - // mark the net - Abc_NodeSetTravIdCurrent( pNet ); - } - } - else - { - Abc_NtkForEachCi( pNtk, pObj, i ) - { - pNet = Abc_ObjFanout0(pObj); - nValues = Abc_ObjMvVarNum(pNet); - pValues = ALLOC( Abc_Obj_t *, nValues ); - // create PIs for the encoding bits - nBits = Extra_Base2Log( nValues ); - for ( k = 0; k < nBits; k++ ) - { - pBits[k] = Abc_NtkCreatePi( pNtkNew ); - Abc_NtkConvertAssignName( pBits[k], pNet, k ); - } - // encode the values - for ( v = 0; v < nValues; v++ ) - { - pValues[v] = Abc_AigConst1(pNtkNew); - for ( k = 0; k < nBits; k++ ) - { - pBit = Abc_ObjNotCond( pBits[k], (v&(1<<k)) == 0 ); - pValues[v] = Abc_AigAnd( pNtkNew->pManFunc, pValues[v], pBit ); - } - } - // save the values in the fanout net - pNet->pCopy = (Abc_Obj_t *)pValues; - // mark the net - Abc_NodeSetTravIdCurrent( pNet ); - } - } - - // process nodes in the topological order - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( !Abc_NodeStrashBlifMv( pNtkNew, pObj ) ) - { - Abc_NtkDelete( pNtkNew ); - return NULL; - } - Vec_PtrFree( vNodes ); - - // encode the CO nets - if ( fUsePositional ) - { - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pNet = Abc_ObjFanin0(pObj); - // skip marked nets - if ( Abc_NodeIsTravIdCurrent(pNet) ) - continue; - Abc_NodeSetTravIdCurrent( pNet ); - nValues = Abc_ObjMvVarNum(pNet); - pValues = (Abc_Obj_t **)pNet->pCopy; - for ( v = 0; v < nValues; v++ ) - { - pTemp = Abc_NtkCreatePo( pNtkNew ); - Abc_ObjAddFanin( pTemp, pValues[v] ); - Abc_NtkConvertAssignName( pTemp, pNet, v ); - } - } - } - else - { - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pNet = Abc_ObjFanin0(pObj); - // skip marked nets - if ( Abc_NodeIsTravIdCurrent(pNet) ) - continue; - Abc_NodeSetTravIdCurrent( pNet ); - nValues = Abc_ObjMvVarNum(pNet); - pValues = (Abc_Obj_t **)pNet->pCopy; - nBits = Extra_Base2Log( nValues ); - for ( k = 0; k < nBits; k++ ) - { - pBit = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); - for ( v = 0; v < nValues; v++ ) - if ( v & (1<<k) ) - pBit = Abc_AigOr( pNtkNew->pManFunc, pBit, pValues[v] ); - pTemp = Abc_NtkCreatePo( pNtkNew ); - Abc_ObjAddFanin( pTemp, pBit ); - Abc_NtkConvertAssignName( pTemp, pNet, k ); - } - } - } - - // cleanup - free( pBits ); - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( pObj->pCopy ) - free( pObj->pCopy ); - - // remove dangling nodes - i = Abc_AigCleanup(pNtkNew->pManFunc); -// printf( "Cleanup removed %d nodes.\n", i ); -// Abc_NtkReassignIds( pNtkNew ); - - // check integrity - if ( !Abc_NtkCheck( pNtkNew ) ) - { - fprintf( stdout, "Abc_NtkStrashBlifMv(): Network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Extract the MV-skeleton of the BLIF-MV network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkSkeletonBlifMv( Abc_Ntk_t * pNtk ) -{ - int fUsePositional = 0; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pNet, * pNetNew, * pNodeNew, * pTermNew, * pBoxNew; - int i, k, v, nValues, nBits; - - assert( Abc_NtkIsNetlist(pNtk) ); - assert( Abc_NtkHasBlifMv(pNtk) ); - assert( Abc_NtkWhiteboxNum(pNtk) == 0 ); - assert( Abc_NtkBlackboxNum(pNtk) == 0 ); - - // clean the node copy fields - Abc_NtkCleanCopy( pNtk ); - - // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); - // duplicate the name and the spec - pNtkNew->pName = Extra_UtilStrsav( pNtk->pName ); - pNtkNew->pSpec = Extra_UtilStrsav( pNtk->pName ); - // create the internal box (it is important to put it first!) - pBoxNew = Abc_NtkCreateWhitebox( pNtkNew ); - // create PIs and their nets - Abc_NtkForEachPi( pNtk, pObj, i ) - { - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - pNet = Abc_ObjFanout0(pObj); - Abc_NtkDupObj( pNtkNew, pNet, 1 ); - Abc_ObjAddFanin( pNet->pCopy, pObj->pCopy ); - } - // create POs and their nets - Abc_NtkForEachPo( pNtk, pObj, i ) - { - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - pNet = Abc_ObjFanin0(pObj); - if ( pNet->pCopy == NULL ) - Abc_NtkDupObj( pNtkNew, pNet, 1 ); - Abc_ObjAddFanin( pObj->pCopy, pNet->pCopy ); - } - // create latches - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - Abc_NtkDupBox( pNtkNew, pObj, 0 ); - // latch outputs - pNet = Abc_ObjFanout0(Abc_ObjFanout0(pObj)); - assert( pNet->pCopy == NULL ); - Abc_NtkDupObj( pNtkNew, pNet, 1 ); - Abc_ObjAddFanin( pNet->pCopy, Abc_ObjFanout0(pObj)->pCopy ); - // latch inputs - pNet = Abc_ObjFanin0(Abc_ObjFanin0(pObj)); - if ( pNet->pCopy == NULL ) - Abc_NtkDupObj( pNtkNew, pNet, 1 ); - Abc_ObjAddFanin( Abc_ObjFanin0(pObj)->pCopy, pNet->pCopy ); - } - - // encode the CI nets - Abc_NtkIncrementTravId( pNtk ); - if ( fUsePositional ) - { - Abc_NtkForEachCi( pNtk, pObj, i ) - { - pNet = Abc_ObjFanout0(pObj); - nValues = Abc_ObjMvVarNum(pNet); - for ( v = 0; v < nValues; v++ ) - { - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopEncoderPos( pNtkNew->pManFunc, v, nValues ); - pNetNew = Abc_NtkCreateNet( pNtkNew ); - pTermNew = Abc_NtkCreateBi( pNtkNew ); - Abc_ObjAddFanin( pNodeNew, pNet->pCopy ); - Abc_ObjAddFanin( pNetNew, pNodeNew ); - Abc_ObjAddFanin( pTermNew, pNetNew ); - Abc_ObjAddFanin( pBoxNew, pTermNew ); - } - // mark the net - Abc_NodeSetTravIdCurrent( pNet ); - } - } - else - { - Abc_NtkForEachCi( pNtk, pObj, i ) - { - pNet = Abc_ObjFanout0(pObj); - nValues = Abc_ObjMvVarNum(pNet); - nBits = Extra_Base2Log( nValues ); - for ( k = 0; k < nBits; k++ ) - { - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopEncoderLog( pNtkNew->pManFunc, k, nValues ); - pNetNew = Abc_NtkCreateNet( pNtkNew ); - pTermNew = Abc_NtkCreateBi( pNtkNew ); - Abc_ObjAddFanin( pNodeNew, pNet->pCopy ); - Abc_ObjAddFanin( pNetNew, pNodeNew ); - Abc_ObjAddFanin( pTermNew, pNetNew ); - Abc_ObjAddFanin( pBoxNew, pTermNew ); - } - // mark the net - Abc_NodeSetTravIdCurrent( pNet ); - } - } - - // encode the CO nets - if ( fUsePositional ) - { - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pNet = Abc_ObjFanin0(pObj); - // skip marked nets - if ( Abc_NodeIsTravIdCurrent(pNet) ) - continue; - Abc_NodeSetTravIdCurrent( pNet ); - nValues = Abc_ObjMvVarNum(pNet); - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopDecoderPos( pNtkNew->pManFunc, nValues ); - for ( v = 0; v < nValues; v++ ) - { - pTermNew = Abc_NtkCreateBo( pNtkNew ); - pNetNew = Abc_NtkCreateNet( pNtkNew ); - Abc_ObjAddFanin( pTermNew, pBoxNew ); - Abc_ObjAddFanin( pNetNew, pTermNew ); - Abc_ObjAddFanin( pNodeNew, pNetNew ); - } - Abc_ObjAddFanin( pNet->pCopy, pNodeNew ); - } - } - else - { - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pNet = Abc_ObjFanin0(pObj); - // skip marked nets - if ( Abc_NodeIsTravIdCurrent(pNet) ) - continue; - Abc_NodeSetTravIdCurrent( pNet ); - nValues = Abc_ObjMvVarNum(pNet); - nBits = Extra_Base2Log( nValues ); - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopDecoderLog( pNtkNew->pManFunc, nValues ); - for ( k = 0; k < nBits; k++ ) - { - pTermNew = Abc_NtkCreateBo( pNtkNew ); - pNetNew = Abc_NtkCreateNet( pNtkNew ); - Abc_ObjAddFanin( pTermNew, pBoxNew ); - Abc_ObjAddFanin( pNetNew, pTermNew ); - Abc_ObjAddFanin( pNodeNew, pNetNew ); - } - Abc_ObjAddFanin( pNet->pCopy, pNodeNew ); - } - } - - // if it is a BLIF-MV netlist transfer the values of all nets - if ( Abc_NtkHasBlifMv(pNtk) && Abc_NtkMvVar(pNtk) ) - { - if ( Abc_NtkMvVar( pNtkNew ) == NULL ) - Abc_NtkStartMvVars( pNtkNew ); - Abc_NtkForEachNet( pNtk, pObj, i ) - if ( pObj->pCopy ) - Abc_NtkSetMvVarValues( pObj->pCopy, Abc_ObjMvVarNum(pObj) ); - } - - // check integrity - if ( !Abc_NtkCheck( pNtkNew ) ) - { - fprintf( stdout, "Abc_NtkSkeletonBlifMv(): Network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Inserts processed network into original base MV network.] - - Description [The original network remembers the interface of combinational - logic (PIs/POs/latches names and values). The processed network may - be binary or multi-valued (currently, multi-value is not supported). - The resulting network has the same interface as the original network - while the internal logic is the same as that of the processed network.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkInsertBlifMv( Abc_Ntk_t * pNtkBase, Abc_Ntk_t * pNtkLogic ) -{ - Abc_Ntk_t * pNtkSkel, * pNtkNew; - Abc_Obj_t * pBox; - - assert( Abc_NtkIsNetlist(pNtkBase) ); - assert( Abc_NtkHasBlifMv(pNtkBase) ); - assert( Abc_NtkWhiteboxNum(pNtkBase) == 0 ); - assert( Abc_NtkBlackboxNum(pNtkBase) == 0 ); - - assert( Abc_NtkIsNetlist(pNtkLogic) ); - assert( Abc_NtkHasBlifMv(pNtkLogic) ); - assert( Abc_NtkWhiteboxNum(pNtkLogic) == 0 ); - assert( Abc_NtkBlackboxNum(pNtkLogic) == 0 ); - - // extract the skeleton of the old network - pNtkSkel = Abc_NtkSkeletonBlifMv( pNtkBase ); - - // set the implementation of the box to be the same as the processed network - assert( Abc_NtkWhiteboxNum(pNtkSkel) == 1 ); - pBox = Abc_NtkBox( pNtkSkel, 0 ); - assert( Abc_ObjIsWhitebox(pBox) ); - assert( pBox->pData == NULL ); - assert( Abc_ObjFaninNum(pBox) == Abc_NtkPiNum(pNtkLogic) ); - assert( Abc_ObjFanoutNum(pBox) == Abc_NtkPoNum(pNtkLogic) ); - pBox->pData = pNtkLogic; - - // flatten the hierarchy to insert the processed network - pNtkNew = Abc_NtkFlattenLogicHierarchy( pNtkSkel ); - pBox->pData = NULL; - Abc_NtkDelete( pNtkSkel ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Converts SOP netlist into BLIF-MV netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkConvertToBlifMv( Abc_Ntk_t * pNtk ) -{ - Extra_MmFlex_t * pMmFlex; - Abc_Obj_t * pNode; - Vec_Str_t * vCube; - char * pSop0, * pSop1, * pBlifMv, * pCube, * pCur; - int Value, nCubes, nSize, i, k; - - assert( Abc_NtkIsNetlist(pNtk) ); - if ( !Abc_NtkToBdd(pNtk) ) - { - printf( "Converting logic functions to BDDs has failed.\n" ); - return 0; - } - - pMmFlex = Extra_MmFlexStart(); - vCube = Vec_StrAlloc( 100 ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // convert BDD into cubes for on-set and off-set - Abc_NodeBddToCnf( pNode, pMmFlex, vCube, 0, &pSop0, &pSop1 ); - // allocate room for the MV-SOP - nCubes = Abc_SopGetCubeNum(pSop0) + Abc_SopGetCubeNum(pSop1); - nSize = nCubes*(2*Abc_ObjFaninNum(pNode) + 2)+1; - pBlifMv = Extra_MmFlexEntryFetch( pMmFlex, nSize ); - // add the cubes - pCur = pBlifMv; - Abc_SopForEachCube( pSop0, Abc_ObjFaninNum(pNode), pCube ) - { - Abc_CubeForEachVar( pCube, Value, k ) - { - *pCur++ = Value; - *pCur++ = ' '; - } - *pCur++ = '0'; - *pCur++ = '\n'; - } - Abc_SopForEachCube( pSop1, Abc_ObjFaninNum(pNode), pCube ) - { - Abc_CubeForEachVar( pCube, Value, k ) - { - *pCur++ = Value; - *pCur++ = ' '; - } - *pCur++ = '1'; - *pCur++ = '\n'; - } - *pCur++ = 0; - assert( pCur - pBlifMv == nSize ); - // update the node representation - Cudd_RecursiveDeref( pNtk->pManFunc, pNode->pData ); - pNode->pData = pBlifMv; - } - - // update the functionality type - pNtk->ntkFunc = ABC_FUNC_BLIFMV; - Cudd_Quit( pNtk->pManFunc ); - pNtk->pManFunc = pMmFlex; - - Vec_StrFree( vCube ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Converts SOP into MV-SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_NodeConvertSopToMvSop( int nVars, Vec_Int_t * vSop0, Vec_Int_t * vSop1 ) -{ - char * pMvSop, * pCur; - unsigned uCube; - int nCubes, nSize, Value, i, k; - // consider the case of the constant node - if ( Vec_IntSize(vSop0) == 0 || Vec_IntSize(vSop1) == 0 ) - { - // (temporary) create a tautology cube - pMvSop = ALLOC( char, nVars + 3 ); - for ( k = 0; k < nVars; k++ ) - pMvSop[k] = '-'; - pMvSop[nVars] = '0' + (int)(Vec_IntSize(vSop1) > 0); - pMvSop[nVars+1] = '\n'; - pMvSop[nVars+2] = 0; - return pMvSop; - } - // find the total number of cubes - nCubes = Vec_IntSize(vSop0) + Vec_IntSize(vSop1); - // find the size of the MVSOP represented as a C-string - // (each cube has nVars variables + one output literal + end-of-line, - // and the string is zero-terminated) - nSize = nCubes * (nVars + 2) + 1; - // allocate memory - pMvSop = pCur = ALLOC( char, nSize ); - // fill in the negative polarity cubes - Vec_IntForEachEntry( vSop0, uCube, i ) - { - for ( k = 0; k < nVars; k++ ) - { - Value = (uCube >> (2*k)) & 3; - if ( Value == 1 ) - *pCur++ = '0'; - else if ( Value == 2 ) - *pCur++ = '1'; - else if ( Value == 0 ) - *pCur++ = '-'; - else - assert( 0 ); - } - *pCur++ = '0'; - *pCur++ = '\n'; - } - // fill in the positive polarity cubes - Vec_IntForEachEntry( vSop1, uCube, i ) - { - for ( k = 0; k < nVars; k++ ) - { - Value = (uCube >> (2*k)) & 3; - if ( Value == 1 ) - *pCur++ = '0'; - else if ( Value == 2 ) - *pCur++ = '1'; - else if ( Value == 0 ) - *pCur++ = '-'; - else - assert( 0 ); - } - *pCur++ = '1'; - *pCur++ = '\n'; - } - *pCur++ = 0; - assert( pCur - pMvSop == nSize ); - return pMvSop; -} - - -/**Function************************************************************* - - Synopsis [A prototype of internal cost evaluation procedure.] - - Description [This procedure takes the number of variables (nVars), - the array of values of the inputs and the output (pVarValues) - (note that this array has nVars+1 entries), and an MV-SOP represented - as a C-string with one charater for each literal, including inputs - and output. Each cube is terminated with the new-line character ('\n'). - The string is zero-terminated.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeEvalMvCostInternal( int nVars, int * pVarValues, char * pMvSop ) -{ - // for now, return the number of cubes in the MV-SOP - int Counter = 0; - while ( *pMvSop ) Counter += (*pMvSop++ == '\n'); - return Counter; -} - - -/**Function************************************************************* - - Synopsis [Evaluates the cost of the cut.] - - Description [The Boolean function of the cut is specified by two SOPs, - which represent the negative/positive polarities of the cut function. - Converts these two SOPs into a mutually-agreed-upon representation - to be passed to the internal cost-evaluation procedure (see the above - prototype Abc_NodeEvalMvCostInternal).] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeEvalMvCost( int nVars, Vec_Int_t * vSop0, Vec_Int_t * vSop1 ) -{ - char * pMvSop; - int * pVarValues; - int i, RetValue; - // collect the input and output values (currently, they are binary) - pVarValues = ALLOC( int, nVars + 1 ); - for ( i = 0; i <= nVars; i++ ) - pVarValues[i] = 2; - // prepare MV-SOP for evaluation - pMvSop = Abc_NodeConvertSopToMvSop( nVars, vSop0, vSop1 ); - // have a look at the MV-SOP: -// printf( "%s\n", pMvSop ); - // get the result of internal cost evaluation - RetValue = Abc_NodeEvalMvCostInternal( nVars, pVarValues, pMvSop ); - // cleanup - free( pVarValues ); - free( pMvSop ); - return RetValue; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c index 79b76348..1d23d7ed 100644 --- a/src/base/abc/abcCheck.c +++ b/src/base/abc/abcCheck.c @@ -20,12 +20,12 @@ #include "abc.h" #include "main.h" -//#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ); static bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk ); static bool Abc_NtkCheckPis( Abc_Ntk_t * pNtk ); static bool Abc_NtkCheckPos( Abc_Ntk_t * pNtk ); @@ -38,10 +38,8 @@ static bool Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) static bool Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ); static bool Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ); -static inline char * Abc_ObjNameNet( Abc_Obj_t * pObj ) { return (Abc_ObjIsNode(pObj) && Abc_NtkIsNetlist(pObj->pNtk)) ? Abc_ObjName(Abc_ObjFanout0(pObj)) : Abc_ObjName(pObj); } - //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -56,7 +54,7 @@ static inline char * Abc_ObjNameNet( Abc_Obj_t * pObj ) { return (Abc_ObjIsNode( ***********************************************************************/ bool Abc_NtkCheck( Abc_Ntk_t * pNtk ) -{ +{ return !Abc_FrameIsFlagEnabled( "check" ) || Abc_NtkDoCheck( pNtk ); } @@ -92,45 +90,25 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) Abc_Obj_t * pObj, * pNet, * pNode; int i; - // check network types - if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) + if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) ) { fprintf( stdout, "NetworkCheck: Unknown network type.\n" ); return 0; } - if ( !Abc_NtkHasSop(pNtk) && !Abc_NtkHasBdd(pNtk) && !Abc_NtkHasAig(pNtk) && !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlifMv(pNtk) && !Abc_NtkHasBlackbox(pNtk) ) + if ( !Abc_NtkHasSop(pNtk) && !Abc_NtkHasBdd(pNtk) && !Abc_NtkHasAig(pNtk) && !Abc_NtkHasMapping(pNtk) ) { fprintf( stdout, "NetworkCheck: Unknown functionality type.\n" ); return 0; } if ( Abc_NtkHasMapping(pNtk) ) { - if ( pNtk->pManFunc != Abc_FrameReadLibGen() ) + if ( pNtk->pManFunc != Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) ) { fprintf( stdout, "NetworkCheck: The library of the mapped network is not the global library.\n" ); return 0; } } - if ( Abc_NtkHasOnlyLatchBoxes(pNtk) ) - { - // check CI/CO numbers - if ( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCiNum(pNtk) ) - { - fprintf( stdout, "NetworkCheck: Number of CIs does not match number of PIs and latches.\n" ); - fprintf( stdout, "One possible reason is that latches are added twice:\n" ); - fprintf( stdout, "in procedure Abc_NtkCreateObj() and in the user's code.\n" ); - return 0; - } - if ( Abc_NtkPoNum(pNtk) + Abc_NtkAssertNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCoNum(pNtk) ) - { - fprintf( stdout, "NetworkCheck: Number of COs does not match number of POs, asserts, and latches.\n" ); - fprintf( stdout, "One possible reason is that latches are added twice:\n" ); - fprintf( stdout, "in procedure Abc_NtkCreateObj() and in the user's code.\n" ); - return 0; - } - } - // check the names if ( !Abc_NtkCheckNames( pNtk ) ) return 0; @@ -142,9 +120,6 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) if ( !Abc_NtkCheckPos( pNtk ) ) return 0; - if ( Abc_NtkHasBlackbox(pNtk) ) - return 1; - // check the connectivity of objects Abc_NtkForEachObj( pNtk, pObj, i ) if ( !Abc_NtkCheckObj( pNtk, pObj ) ) @@ -173,8 +148,11 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) } // check the nodes - if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigCheck( pNtk->pManFunc ); + if ( Abc_NtkHasAig(pNtk) ) + { + if ( Abc_NtkIsStrash(pNtk) ) + Abc_AigCheck( pNtk->pManFunc ); + } else { Abc_NtkForEachNode( pNtk, pNode, i ) @@ -189,7 +167,7 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) // finally, check for combinational loops // clk = clock(); - if ( !Abc_NtkIsAcyclic( pNtk ) ) + if ( !Abc_NtkIsSeq( pNtk ) && !Abc_NtkIsAcyclic( pNtk ) ) { fprintf( stdout, "NetworkCheck: Network contains a combinational loop.\n" ); return 0; @@ -198,29 +176,14 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) // check the EXDC network if present if ( pNtk->pExdc ) - Abc_NtkCheck( pNtk->pExdc ); -/* - // check the hierarchy - if ( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model ) - { - stmm_generator * gen; - Abc_Ntk_t * pNtkTemp; - char * pName; - // check other networks - stmm_foreach_item( pNtk->tName2Model, gen, &pName, (char **)&pNtkTemp ) - { - pNtkTemp->fHiePath = pNtkTemp->fHieVisited = 0; - if ( !Abc_NtkCheck( pNtkTemp ) ) - return 0; - } - // check acyclic dependency of the models - if ( !Abc_NtkIsAcyclicHierarchy( pNtk ) ) - { - fprintf( stdout, "NetworkCheck: Network hierarchical dependences contains a cycle.\n" ); - return 0; - } + { +// if ( pNtk->Type != pNtk->pExdc->Type ) +// { +// fprintf( stdout, "NetworkCheck: Network and its EXDC have different types.\n" ); +// return 0; +// } + return Abc_NtkCheck( pNtk->pExdc ); } -*/ return 1; } @@ -237,61 +200,73 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) ***********************************************************************/ bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pObj; - Vec_Int_t * vNameIds; + stmm_generator * gen; + Abc_Obj_t * pNet, * pNet2, * pObj; char * pName; - int i, NameId; + int i; if ( Abc_NtkIsNetlist(pNtk) ) - return 1; + { + // check that the nets in the table are also in the network + stmm_foreach_item( pNtk->tName2Net, gen, &pName, (char**)&pNet ) + { + if ( pNet->pData != pName ) + { + fprintf( stdout, "NetworkCheck: Net \"%s\" has different name compared to the one in the name table.\n", pNet->pData ); + return 0; + } + } + // check that the nets with names are also in the table + Abc_NtkForEachNet( pNtk, pNet, i ) + { + if ( pNet->pData && !stmm_lookup( pNtk->tName2Net, pNet->pData, (char**)&pNet2 ) ) + { + fprintf( stdout, "NetworkCheck: Net \"%s\" is in the network but not in the name table.\n", pNet->pData ); + return 0; + } + } + } - // check that each CI/CO has a name - Abc_NtkForEachCi( pNtk, pObj, i ) + // check PI/PO/latch names + Abc_NtkForEachPi( pNtk, pObj, i ) { - pObj = Abc_ObjFanout0Ntk(pObj); - if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) == NULL ) + if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) ) + { + fprintf( stdout, "NetworkCheck: PI \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) ); + return 0; + } + if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanout0(pObj)), pName ) ) { - fprintf( stdout, "NetworkCheck: CI with ID %d is in the network but not in the name table.\n", pObj->Id ); + fprintf( stdout, "NetworkCheck: PI \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) ); return 0; } } - Abc_NtkForEachCo( pNtk, pObj, i ) + Abc_NtkForEachPo( pNtk, pObj, i ) { - pObj = Abc_ObjFanin0Ntk(pObj); - if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) == NULL ) + if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) ) + { + fprintf( stdout, "NetworkCheck: PO \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) ); + return 0; + } + if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanin0(pObj)), pName ) ) { - fprintf( stdout, "NetworkCheck: CO with ID %d is in the network but not in the name table.\n", pObj->Id ); + fprintf( stdout, "NetworkCheck: PO \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) ); return 0; } } - - // return the array of all IDs, which have names - vNameIds = Nm_ManReturnNameIds( pNtk->pManName ); - // make sure that these IDs correspond to live objects - Vec_IntForEachEntry( vNameIds, NameId, i ) + Abc_NtkForEachLatch( pNtk, pObj, i ) { - if ( Vec_PtrEntry( pNtk->vObjs, NameId ) == NULL ) + if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) ) { - Vec_IntFree( vNameIds ); - pName = Nm_ManFindNameById(pObj->pNtk->pManName, NameId); - fprintf( stdout, "NetworkCheck: Object with ID %d is deleted but its name \"%s\" remains in the name table.\n", NameId, pName ); + fprintf( stdout, "NetworkCheck: Latch \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) ); + return 0; + } + if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanout0(pObj)), pName ) ) + { + fprintf( stdout, "NetworkCheck: Latch \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) ); return 0; } } - Vec_IntFree( vNameIds ); - - // make sure the CI names are unique - if ( !Abc_NtkCheckUniqueCiNames(pNtk) ) - return 0; - - // make sure the CO names are unique - if ( !Abc_NtkCheckUniqueCoNames(pNtk) ) - return 0; - - // make sure that if a CO has the same name as a CI, they point directly - if ( !Abc_NtkCheckUniqueCioNames(pNtk) ) - return 0; - return 1; } @@ -312,6 +287,12 @@ bool Abc_NtkCheckPis( Abc_Ntk_t * pNtk ) Abc_Obj_t * pObj; int i; + if ( Abc_NtkCiNum(pNtk) != Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) ) + { + fprintf( stdout, "NetworkCheck: Incorrect size of the PI array.\n" ); + return 0; + } + // check that PIs are indeed PIs Abc_NtkForEachPi( pNtk, pObj, i ) { @@ -360,6 +341,12 @@ bool Abc_NtkCheckPos( Abc_Ntk_t * pNtk ) Abc_Obj_t * pObj; int i; + if ( Abc_NtkCoNum(pNtk) != Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) ) + { + fprintf( stdout, "NetworkCheck: Incorrect size of the PO array.\n" ); + return 0; + } + // check that POs are indeed POs Abc_NtkForEachPo( pNtk, pObj, i ) { @@ -427,14 +414,10 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ) fprintf( stdout, "NetworkCheck: Object \"%s\" has incorrect ID.\n", Abc_ObjName(pObj) ); return 0; } - - if ( !Abc_FrameIsFlagEnabled("checkfio") ) - return Value; - // go through the fanins of the object and make sure fanins have this object as a fanout Abc_ObjForEachFanin( pObj, pFanin, i ) { - if ( Vec_IntFind( &pFanin->vFanouts, pObj->Id ) == -1 ) + if ( Vec_FanFindEntry( &pFanin->vFanouts, pObj->Id ) == -1 ) { fprintf( stdout, "NodeCheck: Object \"%s\" has fanin ", Abc_ObjName(pObj) ); fprintf( stdout, "\"%s\" but the fanin does not have it as a fanout.\n", Abc_ObjName(pFanin) ); @@ -444,7 +427,7 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ) // go through the fanouts of the object and make sure fanouts have this object as a fanin Abc_ObjForEachFanout( pObj, pFanout, i ) { - if ( Vec_IntFind( &pFanout->vFanins, pObj->Id ) == -1 ) + if ( Vec_FanFindEntry( &pFanout->vFanins, pObj->Id ) == -1 ) { fprintf( stdout, "NodeCheck: Object \"%s\" has fanout ", Abc_ObjName(pObj) ); fprintf( stdout, "\"%s\" but the fanout does not have it as a fanin.\n", Abc_ObjName(pFanout) ); @@ -452,10 +435,13 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ) } } + if ( !Abc_FrameIsFlagEnabled("checkfio") ) + return Value; + // make sure fanins are not duplicated for ( i = 0; i < pObj->vFanins.nSize; i++ ) for ( k = i + 1; k < pObj->vFanins.nSize; k++ ) - if ( pObj->vFanins.pArray[k] == pObj->vFanins.pArray[i] ) + if ( pObj->vFanins.pArray[k].iFan == pObj->vFanins.pArray[i].iFan ) { printf( "Warning: Node %s has", Abc_ObjName(pObj) ); printf( " duplicated fanin %s.\n", Abc_ObjName(Abc_ObjFanin(pObj,k)) ); @@ -468,7 +454,7 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ) // make sure fanouts are not duplicated for ( i = 0; i < pObj->vFanouts.nSize; i++ ) for ( k = i + 1; k < pObj->vFanouts.nSize; k++ ) - if ( pObj->vFanouts.pArray[k] == pObj->vFanouts.pArray[i] ) + if ( pObj->vFanouts.pArray[k].iFan == pObj->vFanouts.pArray[i].iFan ) { printf( "Warning: Node %s has", Abc_ObjName(pObj) ); printf( " duplicated fanout %s.\n", Abc_ObjName(Abc_ObjFanout(pObj,k)) ); @@ -525,7 +511,7 @@ bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ) // the node should have a function assigned unless it is an AIG if ( pNode->pData == NULL ) { - fprintf( stdout, "NodeCheck: An internal node \"%s\" does not have a logic function.\n", Abc_ObjNameNet(pNode) ); + fprintf( stdout, "NodeCheck: An internal node \"%s\" does not have a logic function.\n", Abc_ObjName(pNode) ); return 0; } // the netlist and SOP logic network should have SOPs @@ -533,7 +519,7 @@ bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ) { if ( !Abc_SopCheck( pNode->pData, Abc_ObjFaninNum(pNode) ) ) { - fprintf( stdout, "NodeCheck: SOP check for node \"%s\" has failed.\n", Abc_ObjNameNet(pNode) ); + fprintf( stdout, "NodeCheck: SOP check for node \"%s\" has failed.\n", Abc_ObjName(pNode) ); return 0; } } @@ -542,11 +528,11 @@ bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ) int nSuppSize = Cudd_SupportSize(pNtk->pManFunc, pNode->pData); if ( nSuppSize > Abc_ObjFaninNum(pNode) ) { - fprintf( stdout, "NodeCheck: BDD of the node \"%s\" has incorrect support size.\n", Abc_ObjNameNet(pNode) ); + fprintf( stdout, "NodeCheck: BDD of the node \"%s\" has incorrect support size.\n", Abc_ObjName(pNode) ); return 0; } } - else if ( !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlifMv(pNtk) && !Abc_NtkHasAig(pNtk) ) + else if ( !Abc_NtkHasMapping(pNtk) ) { assert( 0 ); } @@ -567,14 +553,19 @@ bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ) bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch ) { int Value = 1; + if ( pNtk->vLats->nSize != Abc_NtkLatchNum(pNtk) ) + { + fprintf( stdout, "NetworkCheck: Incorrect size of the latch array.\n" ); + return 0; + } // check whether the object is a latch if ( !Abc_ObjIsLatch(pLatch) ) { - fprintf( stdout, "NodeCheck: Latch \"%s\" is in a latch list but is not a latch.\n", Abc_ObjName(pLatch) ); + fprintf( stdout, "NodeCheck: Latch \"%s\" is in a latch list but has not latch label.\n", Abc_ObjName(pLatch) ); Value = 0; } // make sure the latch has a reasonable return value - if ( (int)pLatch->pData < ABC_INIT_ZERO || (int)pLatch->pData > ABC_INIT_DC ) + if ( (int)pLatch->pData < 0 || (int)pLatch->pData > 2 ) { fprintf( stdout, "NodeCheck: Latch \"%s\" has incorrect reset value (%d).\n", Abc_ObjName(pLatch), (int)pLatch->pData ); @@ -586,33 +577,6 @@ bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch ) fprintf( stdout, "NodeCheck: Latch \"%s\" has wrong number (%d) of fanins.\n", Abc_ObjName(pLatch), Abc_ObjFaninNum(pLatch) ); Value = 0; } - // make sure the latch has only one fanout - if ( Abc_ObjFanoutNum(pLatch) != 1 ) - { - fprintf( stdout, "NodeCheck: Latch \"%s\" has wrong number (%d) of fanouts.\n", Abc_ObjName(pLatch), Abc_ObjFanoutNum(pLatch) ); - Value = 0; - } - // make sure the latch input has only one fanin - if ( Abc_ObjFaninNum(Abc_ObjFanin0(pLatch)) != 1 ) - { - fprintf( stdout, "NodeCheck: Input of latch \"%s\" has wrong number (%d) of fanins.\n", - Abc_ObjName(Abc_ObjFanin0(pLatch)), Abc_ObjFaninNum(Abc_ObjFanin0(pLatch)) ); - Value = 0; - } - // make sure the latch input has only one fanout - if ( Abc_ObjFanoutNum(Abc_ObjFanin0(pLatch)) != 1 ) - { - fprintf( stdout, "NodeCheck: Input of latch \"%s\" has wrong number (%d) of fanouts.\n", - Abc_ObjName(Abc_ObjFanin0(pLatch)), Abc_ObjFanoutNum(Abc_ObjFanin0(pLatch)) ); - Value = 0; - } - // make sure the latch output has only one fanin - if ( Abc_ObjFaninNum(Abc_ObjFanout0(pLatch)) != 1 ) - { - fprintf( stdout, "NodeCheck: Output of latch \"%s\" has wrong number (%d) of fanins.\n", - Abc_ObjName(Abc_ObjFanout0(pLatch)), Abc_ObjFaninNum(Abc_ObjFanout0(pLatch)) ); - Value = 0; - } return Value; } @@ -696,26 +660,24 @@ bool Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) SeeAlso [] ***********************************************************************/ -bool Abc_NtkCompareBoxes( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) +bool Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) { Abc_Obj_t * pObj1; int i; - assert( Abc_NtkHasOnlyLatchBoxes(pNtk1) ); - assert( Abc_NtkHasOnlyLatchBoxes(pNtk2) ); if ( !fComb ) return 1; - if ( Abc_NtkBoxNum(pNtk1) != Abc_NtkBoxNum(pNtk2) ) + if ( Abc_NtkLatchNum(pNtk1) != Abc_NtkLatchNum(pNtk2) ) { printf( "Networks have different number of latches.\n" ); return 0; } // for each PI of pNet1 find corresponding PI of pNet2 and reorder them - Abc_NtkForEachBox( pNtk1, pObj1, i ) + Abc_NtkForEachLatch( pNtk1, pObj1, i ) { - if ( strcmp( Abc_ObjName(Abc_ObjFanout0(pObj1)), Abc_ObjName(Abc_ObjFanout0(Abc_NtkBox(pNtk2,i))) ) != 0 ) + if ( strcmp( Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkLatch(pNtk2,i)) ) != 0 ) { - printf( "Box #%d is different in network 1 ( \"%s\") and in network 2 (\"%s\").\n", - i, Abc_ObjName(Abc_ObjFanout0(pObj1)), Abc_ObjName(Abc_ObjFanout0(Abc_NtkBox(pNtk2,i))) ); + printf( "Latch #%d is different in network 1 ( \"%s\") and in network 2 (\"%s\").\n", + i, Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkLatch(pNtk2,i)) ); return 0; } } @@ -733,207 +695,19 @@ bool Abc_NtkCompareBoxes( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) SeeAlso [] ***********************************************************************/ -bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fOnlyPis, int fComb ) +bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) { Abc_NtkOrderObjsByName( pNtk1, fComb ); Abc_NtkOrderObjsByName( pNtk2, fComb ); + if ( !Abc_NtkCompareLatches( pNtk1, pNtk2, fComb ) ) + return 0; if ( !Abc_NtkComparePis( pNtk1, pNtk2, fComb ) ) return 0; - if ( !fOnlyPis ) - { - if ( !Abc_NtkCompareBoxes( pNtk1, pNtk2, fComb ) ) - return 0; - if ( !Abc_NtkComparePos( pNtk1, pNtk2, fComb ) ) - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 0 if the network hierachy contains a cycle.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkIsAcyclicHierarchy_rec( Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNext; - Abc_Obj_t * pObj; - int i; - // return if visited - if ( pNtk->fHieVisited ) - return 1; - pNtk->fHieVisited = 1; - // return if black box - if ( Abc_NtkHasBlackbox(pNtk) ) - return 1; - assert( Abc_NtkIsNetlist(pNtk) ); - // go through all the children networks - Abc_NtkForEachBox( pNtk, pObj, i ) - { - if ( Abc_ObjIsLatch(pObj) ) - continue; - pNtkNext = pObj->pData; - assert( pNtkNext != NULL ); - if ( pNtkNext->fHiePath ) - return 0; - pNtk->fHiePath = 1; - if ( !Abc_NtkIsAcyclicHierarchy_rec( pNtkNext ) ) - return 0; - pNtk->fHiePath = 0; - } + if ( !Abc_NtkComparePos( pNtk1, pNtk2, fComb ) ) + return 0; return 1; } -/**Function************************************************************* - - Synopsis [Returns 0 if the network hierachy contains a cycle.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkIsAcyclicHierarchy( Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pTemp; - int i, RetValue; - assert( Abc_NtkIsNetlist(pNtk) && pNtk->pDesign ); - // clear the modules - Vec_PtrForEachEntry( pNtk->pDesign->vModules, pTemp, i ) - pTemp->fHieVisited = pTemp->fHiePath = 0; - // traverse - pNtk->fHiePath = 1; - RetValue = Abc_NtkIsAcyclicHierarchy_rec( pNtk ); - pNtk->fHiePath = 0; - // clear the modules - Vec_PtrForEachEntry( pNtk->pDesign->vModules, pTemp, i ) - pTemp->fHieVisited = pTemp->fHiePath = 0; - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Returns 0 if CI names are repeated.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkNamesCompare( char ** pName1, char ** pName2 ) -{ - return strcmp( *pName1, *pName2 ); -} - -/**Function************************************************************* - - Synopsis [Returns 0 if CI names are repeated.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkCheckUniqueCiNames( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNames; - Abc_Obj_t * pObj; - int i, fRetValue = 1; - assert( !Abc_NtkIsNetlist(pNtk) ); - vNames = Vec_PtrAlloc( Abc_NtkCiNum(pNtk) ); - Abc_NtkForEachCi( pNtk, pObj, i ) - Vec_PtrPush( vNames, Abc_ObjName(pObj) ); - Vec_PtrSort( vNames, Abc_NtkNamesCompare ); - for ( i = 1; i < Abc_NtkCiNum(pNtk); i++ ) - if ( !strcmp( Vec_PtrEntry(vNames,i-1), Vec_PtrEntry(vNames,i) ) ) - { - printf( "Abc_NtkCheck: Repeated CI names: %s and %s.\n", Vec_PtrEntry(vNames,i-1), Vec_PtrEntry(vNames,i) ); - fRetValue = 0; - } - Vec_PtrFree( vNames ); - return fRetValue; -} - -/**Function************************************************************* - - Synopsis [Returns 0 if CO names are repeated.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkCheckUniqueCoNames( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNames; - Abc_Obj_t * pObj; - int i, fRetValue = 1; - assert( !Abc_NtkIsNetlist(pNtk) ); - vNames = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pObj, i ) - Vec_PtrPush( vNames, Abc_ObjName(pObj) ); - Vec_PtrSort( vNames, Abc_NtkNamesCompare ); - for ( i = 1; i < Abc_NtkCoNum(pNtk); i++ ) - { -// printf( "%s\n", Vec_PtrEntry(vNames,i) ); - if ( !strcmp( Vec_PtrEntry(vNames,i-1), Vec_PtrEntry(vNames,i) ) ) - { - printf( "Abc_NtkCheck: Repeated CO names: %s and %s.\n", Vec_PtrEntry(vNames,i-1), Vec_PtrEntry(vNames,i) ); - fRetValue = 0; - } - } - Vec_PtrFree( vNames ); - return fRetValue; -} - -/**Function************************************************************* - - Synopsis [Returns 0 if there is a pair of CI/CO with the same name and logic in between.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkCheckUniqueCioNames( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj, * pObjCi, * pFanin; - int i, nCiId, fRetValue = 1; - assert( !Abc_NtkIsNetlist(pNtk) ); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - nCiId = Nm_ManFindIdByNameTwoTypes( pNtk->pManName, Abc_ObjName(pObj), ABC_OBJ_PI, ABC_OBJ_BO ); - if ( nCiId == -1 ) - continue; - pObjCi = Abc_NtkObj( pNtk, nCiId ); - assert( !strcmp( Abc_ObjName(pObj), Abc_ObjName(pObjCi) ) ); - pFanin = Abc_ObjFanin0(pObj); - if ( pFanin != pObjCi ) - { - printf( "Abc_NtkCheck: A CI/CO pair share the name (%s) but do not link directly. The name of the CO fanin is %s.\n", - Abc_ObjName(pObj), Abc_ObjName(Abc_ObjFanin0(pObj)) ); - fRetValue = 0; - } - } - return fRetValue; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c index af23f18a..2fbbee37 100644 --- a/src/base/abc/abcDfs.c +++ b/src/base/abc/abcDfs.c @@ -24,47 +24,19 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); +static void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); +static void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); +static void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Vec_t * vLevels ); +static int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode ); +static bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode ); + //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Abc_Obj_t * pFanin; - 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 ); - // skip the CI - 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 - Abc_ObjForEachFanin( pNode, pFanin, i ) - { -// pFanin = Abc_ObjFanin( pNode, Abc_ObjFaninNum(pNode)-1-i ); - Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(pFanin), vNodes ); - } - // add the node after the fanins have been added - Vec_PtrPush( vNodes, pNode ); -} - -/**Function************************************************************* - Synopsis [Returns the DFS ordered array of logic nodes.] Description [Collects only the internal nodes, leaving CIs and CO. @@ -132,7 +104,6 @@ Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes return vNodes; } - /**Function************************************************************* Synopsis [Performs DFS for one node.] @@ -144,9 +115,9 @@ Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes SeeAlso [] ***********************************************************************/ -void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) +void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) { - Abc_Obj_t * pFanout; + Abc_Obj_t * pFanin; int i; assert( !Abc_ObjIsNet(pNode) ); // if this node is already visited, skip @@ -155,17 +126,17 @@ void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) // mark the node as visited Abc_NodeSetTravIdCurrent( pNode ); // skip the CI - if ( Abc_ObjIsCo(pNode) ) + if ( Abc_ObjIsCi(pNode) ) return; assert( Abc_ObjIsNode( pNode ) ); // visit the transitive fanin of the node - pNode = Abc_ObjFanout0Ntk(pNode); - Abc_ObjForEachFanout( pNode, pFanout, i ) - Abc_NtkDfsReverse_rec( pFanout, vNodes ); + Abc_ObjForEachFanin( pNode, pFanin, i ) + Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(pFanin), vNodes ); // add the node after the fanins have been added Vec_PtrPush( vNodes, pNode ); } + /**Function************************************************************* Synopsis [Returns the reverse DFS ordered array of logic nodes.] @@ -195,10 +166,9 @@ Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk ) Abc_NtkDfsReverse_rec( pFanout, vNodes ); } // add constant nodes in the end - if ( !Abc_NtkIsStrash(pNtk) ) - Abc_NtkForEachNode( pNtk, pObj, i ) - if ( Abc_NodeIsConst(pObj) ) - Vec_PtrPush( vNodes, pObj ); + Abc_NtkForEachNode( pNtk, pObj, i ) + if ( Abc_NodeIsConst(pObj) ) + Vec_PtrPush( vNodes, pObj ); return vNodes; } @@ -213,7 +183,7 @@ Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -void Abc_NtkDfsReverseNodes_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) +void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) { Abc_Obj_t * pFanout; int i; @@ -230,524 +200,52 @@ void Abc_NtkDfsReverseNodes_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) // visit the transitive fanin of the node pNode = Abc_ObjFanout0Ntk(pNode); Abc_ObjForEachFanout( pNode, pFanout, i ) - Abc_NtkDfsReverseNodes_rec( pFanout, vNodes ); - // add the node after the fanins have been added -// Vec_PtrPush( vNodes, pNode ); - Vec_PtrFillExtra( vNodes, pNode->Level + 1, NULL ); - pNode->pCopy = Vec_PtrEntry( vNodes, pNode->Level ); - Vec_PtrWriteEntry( vNodes, pNode->Level, pNode ); -} - -/**Function************************************************************* - - Synopsis [Returns the levelized array of TFO nodes.] - - Description [Collects the levelized array of internal nodes, leaving out CIs/COs. - However it marks both CIs and COs with the current TravId.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkDfsReverseNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj, * pFanout; - int i, k; - assert( Abc_NtkIsStrash(pNtk) ); - // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrStart( Abc_AigLevel(pNtk) + 1 ); - for ( i = 0; i < nNodes; i++ ) - { - pObj = ppNodes[i]; - assert( Abc_ObjIsCi(pObj) ); - Abc_NodeSetTravIdCurrent( pObj ); - pObj = Abc_ObjFanout0Ntk(pObj); - Abc_ObjForEachFanout( pObj, pFanout, k ) - Abc_NtkDfsReverseNodes_rec( pFanout, vNodes ); - } - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Returns the levelized array of TFO nodes.] - - Description [Collects the levelized array of internal nodes, leaving out CIs/COs. - However it marks both CIs and COs with the current TravId. - Collects only the nodes whose support does not exceed the set of given CI nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkDfsReverseNodesContained( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj, * pFanout, * pFanin; - int i, k, m, nLevels; - // set the levels - nLevels = Abc_NtkLevel( pNtk ); - // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrStart( nLevels + 2 ); - for ( i = 0; i < nNodes; i++ ) - { - pObj = ppNodes[i]; - assert( Abc_ObjIsCi(pObj) ); - Abc_NodeSetTravIdCurrent( pObj ); - // add to the array - assert( pObj->Level == 0 ); - pObj->pCopy = Vec_PtrEntry( vNodes, pObj->Level ); - Vec_PtrWriteEntry( vNodes, pObj->Level, pObj ); - } - // iterate through the levels - for ( i = 0; i <= nLevels; i++ ) - { - // iterate through the nodes on each level - for ( pObj = Vec_PtrEntry(vNodes, i); pObj; pObj = pObj->pCopy ) - { - // iterate through the fanouts of each node - Abc_ObjForEachFanout( pObj, pFanout, k ) - { - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pFanout) ) - continue; - // visit the fanins of this fanout - Abc_ObjForEachFanin( pFanout, pFanin, m ) - { - if ( !Abc_NodeIsTravIdCurrent(pFanin) ) - break; - } - if ( m < Abc_ObjFaninNum(pFanout) ) - continue; - // all fanins are already collected - - // mark the node as visited - Abc_NodeSetTravIdCurrent( pFanout ); - // handle the COs - if ( Abc_ObjIsCo(pFanout) ) - pFanout->Level = nLevels + 1; - // add to the array - pFanout->pCopy = Vec_PtrEntry( vNodes, pFanout->Level ); - Vec_PtrWriteEntry( vNodes, pFanout->Level, pFanout ); - // handle the COs - if ( Abc_ObjIsCo(pFanout) ) - pFanout->Level = 0; - } - } - } - return vNodes; -} - - -/**Function************************************************************* - - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDfsSeq_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Abc_Obj_t * pFanin; - int i; - // if this node is already visited, skip - if ( Abc_NodeIsTravIdCurrent( pNode ) ) - return; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pNode ); - // visit the transitive fanin of the node - Abc_ObjForEachFanin( pNode, pFanin, i ) - Abc_NtkDfsSeq_rec( pFanin, vNodes ); + Abc_NtkDfsReverse_rec( pFanout, vNodes ); // add the node after the fanins have been added Vec_PtrPush( vNodes, pNode ); } -/**Function************************************************************* - - Synopsis [Returns the array of nodes and latches reachable from POs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkDfsSeq( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; - int i; - assert( !Abc_NtkIsNetlist(pNtk) ); - // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDfsSeq_rec( pObj, vNodes ); - // mark the PIs - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkDfsSeq_rec( pObj, vNodes ); - return vNodes; -} - /**Function************************************************************* - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDfsSeqReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Abc_Obj_t * pFanout; - int i; - // if this node is already visited, skip - if ( Abc_NodeIsTravIdCurrent( pNode ) ) - return; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pNode ); - // visit the transitive fanin of the node - Abc_ObjForEachFanout( pNode, pFanout, i ) - Abc_NtkDfsSeqReverse_rec( pFanout, vNodes ); - // add the node after the fanins have been added - Vec_PtrPush( vNodes, pNode ); -} - -/**Function************************************************************* - - Synopsis [Returns the array of nodes and latches reachable from POs.] + Synopsis [Returns the DFS ordered array of logic nodes.] - Description [] + Description [Collects only the internal nodes, leaving out CIs/COs. + However it marks both CIs and COs with the current TravId.] SideEffects [] SeeAlso [] ***********************************************************************/ -Vec_Ptr_t * Abc_NtkDfsSeqReverse( Abc_Ntk_t * pNtk ) +Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk, int fCollectAll, int fCollectCos ) { Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; + Abc_Obj_t * pNode; int i; - assert( !Abc_NtkIsNetlist(pNtk) ); + assert( Abc_NtkIsStrash(pNtk) ); // set the traversal ID Abc_NtkIncrementTravId( pNtk ); // start the array of nodes vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkDfsSeqReverse_rec( pObj, vNodes ); - // mark the logic feeding into POs - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDfsSeq_rec( pObj, vNodes ); - return vNodes; -} - - -/**Function************************************************************* - - Synopsis [Iterative version of the DFS procedure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDfs_iter( Vec_Ptr_t * vStack, Abc_Obj_t * pRoot, Vec_Ptr_t * vNodes ) -{ - Abc_Obj_t * pNode, * pFanin; - int iFanin; - // if this node is already visited, skip - if ( Abc_NodeIsTravIdCurrent( pRoot ) ) - return; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pRoot ); - // skip the CI - if ( Abc_ObjIsCi(pRoot) || (Abc_NtkIsStrash(pRoot->pNtk) && Abc_AigNodeIsConst(pRoot)) ) - return; - // add the CI - Vec_PtrClear( vStack ); - Vec_PtrPush( vStack, pRoot ); - Vec_PtrPush( vStack, (void *)0 ); - while ( Vec_PtrSize(vStack) > 0 ) + // go through the PO nodes and call for each of them + Abc_NtkForEachCo( pNtk, pNode, i ) { - // get the node and its fanin - iFanin = (int)Vec_PtrPop(vStack); - pNode = Vec_PtrPop(vStack); - assert( !Abc_ObjIsNet(pNode) ); - // add it to the array of nodes if we finished - if ( iFanin == Abc_ObjFaninNum(pNode) ) - { + Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes ); + Abc_NodeSetTravIdCurrent( pNode ); + if ( fCollectCos ) Vec_PtrPush( vNodes, pNode ); - continue; - } - // explore the next fanin - Vec_PtrPush( vStack, pNode ); - Vec_PtrPush( vStack, (void *)(iFanin+1) ); - // get the fanin - pFanin = Abc_ObjFanin0Ntk( Abc_ObjFanin(pNode,iFanin) ); - // if this node is already visited, skip - if ( Abc_NodeIsTravIdCurrent( pFanin ) ) - continue; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pFanin ); - // skip the CI - if ( Abc_ObjIsCi(pFanin) || (Abc_NtkIsStrash(pFanin->pNtk) && Abc_AigNodeIsConst(pFanin)) ) - continue; - Vec_PtrPush( vStack, pFanin ); - Vec_PtrPush( vStack, (void *)0 ); } -} - -/**Function************************************************************* - - Synopsis [Returns the DFS ordered array of logic nodes.] - - Description [Collects only the internal nodes, leaving CIs and CO. - However it marks with the current TravId both CIs and COs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkDfsIter( Abc_Ntk_t * pNtk, int fCollectAll ) -{ - Vec_Ptr_t * vNodes, * vStack; - Abc_Obj_t * pObj; - int i; - // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrAlloc( 1000 ); - vStack = Vec_PtrAlloc( 1000 ); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - Abc_NodeSetTravIdCurrent( pObj ); - Abc_NtkDfs_iter( vStack, Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)), vNodes ); - } - // collect dangling nodes if asked to - if ( fCollectAll ) - { - Abc_NtkForEachNode( pNtk, pObj, i ) - if ( !Abc_NodeIsTravIdCurrent(pObj) ) - Abc_NtkDfs_iter( vStack, pObj, vNodes ); - } - Vec_PtrFree( vStack ); - return vNodes; -} - - -/**Function************************************************************* - - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDfsHie_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vNodes ) -{ - Abc_Obj_t * pFanin; - int i; - // if this node is already visited, skip - if ( Abc_NodeIsTravIdCurrent( pObj ) ) - return; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pObj ); - // visit the transitive fanin of the node - Abc_ObjForEachFanin( pObj, pFanin, i ) - Abc_NtkDfsHie_rec( pFanin, vNodes ); - // add the node after the fanins have been added - Vec_PtrPush( vNodes, pObj ); -} - -/**Function************************************************************* - - Synopsis [Returns the DFS ordered array of all objects.] - - Description [This procedure collects everything from POs to PIs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkDfsHie( Abc_Ntk_t * pNtk, int fCollectAll ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; - int i; - // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDfsHie_rec( pObj, vNodes ); // collect dangling nodes if asked to if ( fCollectAll ) { - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( !Abc_NodeIsTravIdCurrent(pObj) ) - Abc_NtkDfs_rec( pObj, vNodes ); - } - return vNodes; -} - - -/**Function************************************************************* - - Synopsis [Returns 1 if the ordering of nodes is DFS.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode, * pFanin; - int i, k; - // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // mark the CIs - Abc_NtkForEachCi( pNtk, pNode, i ) - Abc_NodeSetTravIdCurrent( pNode ); - // go through the nodes - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // check the fanins of the node - Abc_ObjForEachFanin( pNode, pFanin, k ) - if ( !Abc_NodeIsTravIdCurrent(pFanin) ) - return 0; - // check the choices of the node - if ( Abc_NtkIsStrash(pNtk) && Abc_AigNodeIsChoice(pNode) ) - for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData ) - if ( !Abc_NodeIsTravIdCurrent(pFanin) ) - return 0; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pNode ); - } - return 1; -} - - -/**Function************************************************************* - - Synopsis [Performs DFS for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkNodeSupport_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - Abc_Obj_t * pFanin; - 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 ); - // collect the CI - if ( Abc_ObjIsCi(pNode) || Abc_ObjFaninNum(pNode) == 0 ) - { - Vec_PtrPush( vNodes, pNode ); - return; + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( !Abc_NodeIsTravIdCurrent(pNode) ) + Abc_AigDfs_rec( pNode, vNodes ); } - assert( Abc_ObjIsNode( pNode ) ); - // visit the transitive fanin of the node - Abc_ObjForEachFanin( pNode, pFanin, i ) - Abc_NtkNodeSupport_rec( Abc_ObjFanin0Ntk(pFanin), vNodes ); -} - -/**Function************************************************************* - - Synopsis [Returns the set of CI nodes in the support of the given nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkSupport( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode; - int i; - // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrAlloc( 100 ); - // go through the PO nodes and call for each of them - Abc_NtkForEachCo( pNtk, pNode, i ) - Abc_NtkNodeSupport_rec( Abc_ObjFanin0(pNode), vNodes ); - // add unused CIs - Abc_NtkForEachCi( pNtk, pNode, i ) - if ( !Abc_NodeIsTravIdCurrent( pNode ) ) - Vec_PtrPush( vNodes, pNode ); - assert( Vec_PtrSize(vNodes) == Abc_NtkCiNum(pNtk) ); - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Returns the set of CI nodes in the support of the given nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes ) -{ - Vec_Ptr_t * vNodes; - int i; - // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrAlloc( 100 ); - // go through the PO nodes and call for each of them - for ( i = 0; i < nNodes; i++ ) - if ( Abc_ObjIsCo(ppNodes[i]) ) - Abc_NtkNodeSupport_rec( Abc_ObjFanin0(ppNodes[i]), vNodes ); - else - Abc_NtkNodeSupport_rec( ppNodes[i], vNodes ); return vNodes; } - /**Function************************************************************* Synopsis [Performs DFS for one node.] @@ -769,14 +267,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) || Abc_AigNodeIsConst(pNode) ) + if ( Abc_ObjIsCi(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_AigNodeIsChoice( pNode ) ) + if ( Abc_NodeIsAigChoice( pNode ) ) for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData ) Abc_AigDfs_rec( pFanin, vNodes ); // add the node after the fanins have been added @@ -785,45 +283,37 @@ void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) /**Function************************************************************* - Synopsis [Returns the DFS ordered array of logic nodes.] + Synopsis [Collects nodes in the DFS manner by level.] - Description [Collects only the internal nodes, leaving out CIs/COs. - However it marks both CIs and COs with the current TravId.] + Description [The number of levels should be set!!!] SideEffects [] SeeAlso [] ***********************************************************************/ -Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk, int fCollectAll, int fCollectCos ) +Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi ) { - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode; + Vec_Vec_t * vLevels; + Abc_Obj_t * pFanout; int i; - assert( Abc_NtkIsStrash(pNtk) ); + assert( fTfi == 0 ); + assert( !Abc_NtkIsNetlist(pNode->pNtk) ); // set the traversal ID - Abc_NtkIncrementTravId( pNtk ); - // start the array of nodes - vNodes = Vec_PtrAlloc( 100 ); - // go through the PO nodes and call for each of them - Abc_NtkForEachCo( pNtk, pNode, i ) + Abc_NtkIncrementTravId( pNode->pNtk ); + vLevels = Vec_VecAlloc( 100 ); + if ( Abc_ObjIsNode(pNode) ) + Abc_DfsLevelizedTfo_rec( pNode, vLevels ); + else { - Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes ); + assert( Abc_ObjIsCi(pNode) ); Abc_NodeSetTravIdCurrent( pNode ); - if ( fCollectCos ) - Vec_PtrPush( vNodes, pNode ); - } - // collect dangling nodes if asked to - if ( fCollectAll ) - { - Abc_NtkForEachNode( pNtk, pNode, i ) - if ( !Abc_NodeIsTravIdCurrent(pNode) ) - Abc_AigDfs_rec( pNode, vNodes ); + Abc_ObjForEachFanout( pNode, pFanout, i ) + Abc_DfsLevelizedTfo_rec( pFanout, vLevels ); } - return vNodes; + return vLevels; } - /**Function************************************************************* Synopsis [Collects nodes in the DFS manner by level.] @@ -855,43 +345,10 @@ void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Vec_t * vLevels ) Abc_DfsLevelizedTfo_rec( pFanout, vLevels ); } -/**Function************************************************************* - - Synopsis [Collects nodes in the DFS manner by level.] - - Description [The number of levels should be set!!!] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi ) -{ - Vec_Vec_t * vLevels; - Abc_Obj_t * pFanout; - int i; - assert( fTfi == 0 ); - assert( !Abc_NtkIsNetlist(pNode->pNtk) ); - // set the traversal ID - Abc_NtkIncrementTravId( pNode->pNtk ); - vLevels = Vec_VecAlloc( 100 ); - if ( Abc_ObjIsNode(pNode) ) - Abc_DfsLevelizedTfo_rec( pNode, vLevels ); - else - { - assert( Abc_ObjIsCi(pNode) ); - Abc_NodeSetTravIdCurrent( pNode ); - Abc_ObjForEachFanout( pNode, pFanout, i ) - Abc_DfsLevelizedTfo_rec( pFanout, vLevels ); - } - return vLevels; -} - /**Function************************************************************* - Synopsis [Recursively counts the number of logic levels of one node.] + Synopsis [Computes the number of logic levels not counting PIs/POs.] Description [] @@ -900,31 +357,21 @@ Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi ) SeeAlso [] ***********************************************************************/ -int Abc_NtkLevel_rec( Abc_Obj_t * pNode ) +int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pNext; - int i, Level; - assert( !Abc_ObjIsNet(pNode) ); - // skip the PI - if ( Abc_ObjIsCi(pNode) ) - return pNode->Level; - assert( Abc_ObjIsNode( pNode ) || pNode->Type == ABC_OBJ_CONST1); - // if this node is already visited, return - if ( Abc_NodeIsTravIdCurrent( pNode ) ) - return pNode->Level; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pNode ); - // visit the transitive fanin - pNode->Level = 0; - Abc_ObjForEachFanin( pNode, pNext, i ) + Abc_Obj_t * pNode; + int i, LevelsMax; + // set the traversal ID for this traversal + Abc_NtkIncrementTravId( pNtk ); + // perform the traversal + LevelsMax = 0; + Abc_NtkForEachNode( pNtk, pNode, i ) { - Level = Abc_NtkLevel_rec( Abc_ObjFanin0Ntk(pNext) ); - if ( pNode->Level < (unsigned)Level ) - pNode->Level = Level; + Abc_NtkGetLevelNum_rec( pNode ); + if ( LevelsMax < (int)pNode->Level ) + LevelsMax = (int)pNode->Level; } - if ( Abc_ObjFaninNum(pNode) > 0 ) - pNode->Level++; - return pNode->Level; + return LevelsMax; } /**Function************************************************************* @@ -938,15 +385,15 @@ int Abc_NtkLevel_rec( Abc_Obj_t * pNode ) SeeAlso [] ***********************************************************************/ -int Abc_NtkLevelReverse_rec( Abc_Obj_t * pNode ) +int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode ) { - Abc_Obj_t * pNext; + Abc_Obj_t * pFanin; int i, Level; assert( !Abc_ObjIsNet(pNode) ); // skip the PI - if ( Abc_ObjIsCo(pNode) ) - return pNode->Level; - assert( Abc_ObjIsNode( pNode ) || pNode->Type == ABC_OBJ_CONST1); + if ( Abc_ObjIsCi(pNode) ) + return 0; + assert( Abc_ObjIsNode( pNode ) ); // if this node is already visited, return if ( Abc_NodeIsTravIdCurrent( pNode ) ) return pNode->Level; @@ -954,78 +401,62 @@ int Abc_NtkLevelReverse_rec( Abc_Obj_t * pNode ) Abc_NodeSetTravIdCurrent( pNode ); // visit the transitive fanin pNode->Level = 0; - Abc_ObjForEachFanout( pNode, pNext, i ) + Abc_ObjForEachFanin( pNode, pFanin, i ) { - Level = Abc_NtkLevelReverse_rec( Abc_ObjFanout0Ntk(pNext) ); + Level = Abc_NtkGetLevelNum_rec( Abc_ObjFanin0Ntk(pFanin) ); if ( pNode->Level < (unsigned)Level ) pNode->Level = Level; } - if ( Abc_ObjFaninNum(pNode) > 0 ) - pNode->Level++; + pNode->Level++; return pNode->Level; } -/**Function************************************************************* - - Synopsis [Computes the number of logic levels not counting PIs/POs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkLevel( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int i, LevelsMax; - // set the CI levels to zero - Abc_NtkForEachCi( pNtk, pNode, i ) - pNode->Level = 0; - // perform the traversal - LevelsMax = 0; - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - Abc_NtkLevel_rec( pNode ); - if ( LevelsMax < (int)pNode->Level ) - LevelsMax = (int)pNode->Level; - } - return LevelsMax; -} /**Function************************************************************* - Synopsis [Computes the number of logic levels not counting PIs/POs.] + Synopsis [Detects combinational loops.] - Description [] + Description [This procedure is based on the idea suggested by Donald Chai. + As we traverse the network and visit the nodes, we need to distinquish + three types of nodes: (1) those that are visited for the first time, + (2) those that have been visited in this traversal but are currently not + on the traversal path, (3) those that have been visited and are currently + on the travesal path. When the node of type (3) is encountered, it means + that there is a combinational loop. To mark the three types of nodes, + two new values of the traversal IDs are used.] SideEffects [] SeeAlso [] ***********************************************************************/ -int Abc_NtkLevelReverse( Abc_Ntk_t * pNtk ) +bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; - int i, LevelsMax; - // set the CO levels to zero + int fAcyclic, i; + // set the traversal ID for this DFS ordering + Abc_NtkIncrementTravId( pNtk ); + Abc_NtkIncrementTravId( pNtk ); + // pNode->TravId == pNet->nTravIds means "pNode is on the path" + // pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path" + // pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited" + // traverse the network to detect cycles + fAcyclic = 1; Abc_NtkForEachCo( pNtk, pNode, i ) - pNode->Level = 0; - // perform the traversal - LevelsMax = 0; - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachNode( pNtk, pNode, i ) { - Abc_NtkLevelReverse_rec( pNode ); - if ( LevelsMax < (int)pNode->Level ) - LevelsMax = (int)pNode->Level; + pNode = Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode)); + if ( Abc_NodeIsTravIdPrevious(pNode) ) + continue; + // traverse the output logic cone + if ( fAcyclic = Abc_NtkIsAcyclic_rec(pNode) ) + continue; + // stop as soon as the first loop is detected + fprintf( stdout, " (cone of CO \"%s\")\n", Abc_ObjName(pNode) ); + break; } - return LevelsMax; + return fAcyclic; } - /**Function************************************************************* Synopsis [Recursively detects combinational loops.] @@ -1043,16 +474,17 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode ) Abc_Obj_t * pFanin; int fAcyclic, i; assert( !Abc_ObjIsNet(pNode) ); - if ( Abc_ObjIsCi(pNode) || Abc_ObjIsBox(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) ) + if ( Abc_ObjIsCi(pNode) ) return 1; - assert( Abc_ObjIsNode(pNode) ); + assert( Abc_ObjIsNode( pNode ) ); // make sure the node is not visited assert( !Abc_NodeIsTravIdPrevious(pNode) ); // check if the node is part of the combinational loop if ( Abc_NodeIsTravIdCurrent(pNode) ) { - fprintf( stdout, "Network \"%s\" contains combinational loop!\n", Abc_NtkName(pNtk) ); - fprintf( stdout, "Node \"%s\" is encountered twice on the following path to the COs:\n", Abc_ObjName(pNode) ); + fprintf( stdout, "Network \"%s\" contains combinational loop!\n", pNtk->pName ); + fprintf( stdout, "Node \"%s\" is encountered twice on the following path:\n", Abc_ObjName(pNode) ); + fprintf( stdout, " %s", Abc_ObjName(pNode) ); return 0; } // mark this node as a node on the current path @@ -1070,193 +502,14 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode ) if ( fAcyclic = Abc_NtkIsAcyclic_rec(pFanin) ) continue; // return as soon as the loop is detected - fprintf( stdout, " %s ->", Abc_ObjName(pFanin) ); + fprintf( stdout, " <-- %s", Abc_ObjName(pNode) ); return 0; } - // visit choices - if ( Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsChoice(pNode) ) - { - for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData ) - { - // check if the fanin is visited - if ( Abc_NodeIsTravIdPrevious(pFanin) ) - continue; - // traverse the fanin's cone searching for the loop - if ( fAcyclic = Abc_NtkIsAcyclic_rec(pFanin) ) - continue; - // return as soon as the loop is detected - fprintf( stdout, " %s", Abc_ObjName(pFanin) ); - fprintf( stdout, " (choice of %s) -> ", Abc_ObjName(pNode) ); - return 0; - } - } // mark this node as a visited node Abc_NodeSetTravIdPrevious( pNode ); return 1; } -/**Function************************************************************* - - Synopsis [Detects combinational loops.] - - Description [This procedure is based on the idea suggested by Donald Chai. - As we traverse the network and visit the nodes, we need to distinquish - three types of nodes: (1) those that are visited for the first time, - (2) those that have been visited in this traversal but are currently not - on the traversal path, (3) those that have been visited and are currently - on the travesal path. When the node of type (3) is encountered, it means - that there is a combinational loop. To mark the three types of nodes, - two new values of the traversal IDs are used.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int fAcyclic, i; - // set the traversal ID for this DFS ordering - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkIncrementTravId( pNtk ); - // pNode->TravId == pNet->nTravIds means "pNode is on the path" - // pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path" - // pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited" - // traverse the network to detect cycles - fAcyclic = 1; - Abc_NtkForEachCo( pNtk, pNode, i ) - { - pNode = Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode)); - if ( Abc_NodeIsTravIdPrevious(pNode) ) - continue; - // traverse the output logic cone - if ( fAcyclic = Abc_NtkIsAcyclic_rec(pNode) ) - continue; - // stop as soon as the first loop is detected - fprintf( stdout, " CO \"%s\"\n", Abc_ObjName(Abc_ObjFanout0(pNode)) ); - break; - } - return fAcyclic; -} - - -/**Function************************************************************* - - Synopsis [Analyses choice nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeSetChoiceLevel_rec( Abc_Obj_t * pNode, int fMaximum ) -{ - Abc_Obj_t * pTemp; - int Level1, Level2, Level, LevelE; - // skip the visited node - if ( Abc_NodeIsTravIdCurrent( pNode ) ) - return (int)pNode->pCopy; - Abc_NodeSetTravIdCurrent( pNode ); - // compute levels of the children nodes - Level1 = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin0(pNode), fMaximum ); - Level2 = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin1(pNode), fMaximum ); - Level = 1 + ABC_MAX( Level1, Level2 ); - if ( pNode->pData ) - { - LevelE = Abc_NodeSetChoiceLevel_rec( pNode->pData, fMaximum ); - if ( fMaximum ) - Level = ABC_MAX( Level, LevelE ); - else - Level = ABC_MIN( Level, LevelE ); - // set the level of all equivalent nodes to be the same minimum - for ( pTemp = pNode->pData; pTemp; pTemp = pTemp->pData ) - pTemp->pCopy = (void *)Level; - } - pNode->pCopy = (void *)Level; - return Level; -} - -/**Function************************************************************* - - Synopsis [Resets the levels of the nodes in the choice graph.] - - Description [Makes the level of the choice nodes to be equal to the - maximum of the level of the nodes in the equivalence class. This way - sorting by level leads to the reverse topological order, which is - needed for the required time computation.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_AigSetChoiceLevels( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i, LevelMax, LevelCur; - assert( Abc_NtkIsStrash(pNtk) ); - // set the new travid counter - Abc_NtkIncrementTravId( pNtk ); - // set levels of the CI and constant - Abc_NtkForEachCi( pNtk, pObj, i ) - { - Abc_NodeSetTravIdCurrent( pObj ); - pObj->pCopy = NULL; - } - pObj = Abc_AigConst1( pNtk ); - Abc_NodeSetTravIdCurrent( pObj ); - pObj->pCopy = NULL; - // set levels of all other nodes - LevelMax = 0; - Abc_NtkForEachCo( pNtk, pObj, i ) - { - LevelCur = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin0(pObj), 1 ); - LevelMax = ABC_MAX( LevelMax, LevelCur ); - } - return LevelMax; -} - -/**Function************************************************************* - - Synopsis [Returns nodes by level from the smallest to the largest.] - - Description [Correctly handles the case of choice nodes, by first - spreading them out across several levels and then collecting.] - - SideEffects [What happens with dangling nodes???] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_AigGetLevelizedOrder( Abc_Ntk_t * pNtk, int fCollectCis ) -{ - Vec_Ptr_t * vNodes, * vLevels; - Abc_Obj_t * pNode, ** ppHead; - int LevelMax, i; - assert( Abc_NtkIsStrash(pNtk) ); - // set the correct levels - Abc_NtkCleanCopy( pNtk ); - LevelMax = Abc_AigSetChoiceLevels( pNtk ); - // relink nodes by level - vLevels = Vec_PtrStart( LevelMax + 1 ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - ppHead = ((Abc_Obj_t **)vLevels->pArray) + (int)pNode->pCopy; - pNode->pCopy = *ppHead; - *ppHead = pNode; - } - // recollect nodes - vNodes = Vec_PtrStart( Abc_NtkNodeNum(pNtk) ); - Vec_PtrForEachEntryStart( vLevels, pNode, i, !fCollectCis ) - for ( ; pNode; pNode = pNode->pCopy ) - Vec_PtrPush( vNodes, pNode ); - Vec_PtrFree( vLevels ); - return vNodes; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c index c8536695..2bc87c85 100644 --- a/src/base/abc/abcFanio.c +++ b/src/base/abc/abcFanio.c @@ -24,51 +24,14 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define ABC_LARGE_ID ((1<<24)-1) // should correspond to value in "vecFan.h" + //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry ) -{ - if ( p->nSize == p->nCap ) - { - int * pArray; - int i; - - if ( p->nSize == 0 ) - p->nCap = 1; - if ( pMemMan ) - pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 ); - else - pArray = ALLOC( int, p->nCap * 2 ); - if ( p->pArray ) - { - for ( i = 0; i < p->nSize; i++ ) - pArray[i] = p->pArray[i]; - if ( pMemMan ) - Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 ); - else - free( p->pArray ); - } - p->nCap *= 2; - p->pArray = pArray; - } - p->pArray[p->nSize++] = Entry; -} - -/**Function************************************************************* - Synopsis [Creates fanout/fanin relationship between the nodes.] Description [] @@ -84,16 +47,12 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) assert( !Abc_ObjIsComplement(pObj) ); assert( pObj->pNtk == pFaninR->pNtk ); assert( pObj->Id >= 0 && pFaninR->Id >= 0 ); - Vec_IntPushMem( pObj->pNtk->pMmStep, &pObj->vFanins, pFaninR->Id ); - Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id ); + assert( pObj->Id < ABC_LARGE_ID ); // created but forgot to add it to the network? + assert( pFaninR->Id < ABC_LARGE_ID ); // created but forgot to add it to the network? + Vec_FanPush( pObj->pNtk->pMmStep, &pObj->vFanins, Vec_Int2Fan(pFaninR->Id) ); + Vec_FanPush( pObj->pNtk->pMmStep, &pFaninR->vFanouts, Vec_Int2Fan(pObj->Id) ); if ( Abc_ObjIsComplement(pFanin) ) Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 ); - if ( Abc_ObjIsNet(pObj) && Abc_ObjFaninNum(pObj) > 1 ) - { - int x = 0; - } -// printf( "Adding fanin of %s ", Abc_ObjName(pObj) ); -// printf( "to be %s\n", Abc_ObjName(pFanin) ); } @@ -114,12 +73,14 @@ void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) assert( !Abc_ObjIsComplement(pFanin) ); assert( pObj->pNtk == pFanin->pNtk ); assert( pObj->Id >= 0 && pFanin->Id >= 0 ); - if ( !Vec_IntRemove( &pObj->vFanins, pFanin->Id ) ) + assert( pObj->Id < ABC_LARGE_ID ); // created but forgot to add it to the network? + assert( pFanin->Id < ABC_LARGE_ID ); // created but forgot to add it to the network? + if ( !Vec_FanDeleteEntry( &pObj->vFanins, pFanin->Id ) ) { printf( "The obj %d is not found among the fanins of obj %d ...\n", pFanin->Id, pObj->Id ); return; } - if ( !Vec_IntRemove( &pFanin->vFanouts, pObj->Id ) ) + if ( !Vec_FanDeleteEntry( &pFanin->vFanouts, pObj->Id ) ) { printf( "The obj %d is not found among the fanouts of obj %d ...\n", pObj->Id, pFanin->Id ); return; @@ -140,19 +101,16 @@ void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) ***********************************************************************/ void Abc_ObjRemoveFanins( Abc_Obj_t * pObj ) { - Vec_Int_t * vFaninsOld; + Vec_Fan_t * vFaninsOld; Abc_Obj_t * pFanin; int k; // remove old fanins vFaninsOld = &pObj->vFanins; for ( k = vFaninsOld->nSize - 1; k >= 0; k-- ) { - pFanin = Abc_NtkObj( pObj->pNtk, vFaninsOld->pArray[k] ); + pFanin = Abc_NtkObj( pObj->pNtk, vFaninsOld->pArray[k].iFan ); Abc_ObjDeleteFanin( pObj, pFanin ); } - pObj->fCompl0 = 0; - pObj->fCompl1 = 0; - assert( vFaninsOld->nSize == 0 ); } /**Function************************************************************* @@ -172,7 +130,7 @@ void Abc_ObjRemoveFanins( Abc_Obj_t * pObj ) void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew ) { Abc_Obj_t * pFaninNewR = Abc_ObjRegular(pFaninNew); - int iFanin;//, nLats;//, fCompl; + int iFanin, fCompl, nLats; assert( !Abc_ObjIsComplement(pObj) ); assert( !Abc_ObjIsComplement(pFaninOld) ); assert( pFaninOld != pFaninNewR ); @@ -180,74 +138,30 @@ void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFa // assert( pObj != pFaninNewR ); assert( pObj->pNtk == pFaninOld->pNtk ); assert( pObj->pNtk == pFaninNewR->pNtk ); - if ( (iFanin = Vec_IntFind( &pObj->vFanins, pFaninOld->Id )) == -1 ) + if ( (iFanin = Vec_FanFindEntry( &pObj->vFanins, pFaninOld->Id )) == -1 ) { printf( "Node %s is not among", Abc_ObjName(pFaninOld) ); printf( " the fanins of node %s...\n", Abc_ObjName(pObj) ); return; } - // remember the attributes of the old fanin -// fCompl = Abc_ObjFaninC(pObj, iFanin); + fCompl = Abc_ObjFaninC(pObj, iFanin); + nLats = Abc_ObjFaninL(pObj, iFanin); // replace the old fanin entry by the new fanin entry (removes attributes) - Vec_IntWriteEntry( &pObj->vFanins, iFanin, pFaninNewR->Id ); + Vec_FanWriteEntry( &pObj->vFanins, iFanin, Vec_Int2Fan(pFaninNewR->Id) ); // set the attributes of the new fanin -// if ( fCompl ^ Abc_ObjIsComplement(pFaninNew) ) -// Abc_ObjSetFaninC( pObj, iFanin ); - if ( Abc_ObjIsComplement(pFaninNew) ) - Abc_ObjXorFaninC( pObj, iFanin ); - -// if ( Abc_NtkIsSeq(pObj->pNtk) && (nLats = Seq_ObjFaninL(pObj, iFanin)) ) -// Seq_ObjSetFaninL( pObj, iFanin, nLats ); + if ( fCompl ^ Abc_ObjIsComplement(pFaninNew) ) + Abc_ObjSetFaninC( pObj, iFanin ); + if ( nLats ) + Abc_ObjSetFaninL( pObj, iFanin, nLats ); // update the fanout of the fanin - if ( !Vec_IntRemove( &pFaninOld->vFanouts, pObj->Id ) ) + if ( !Vec_FanDeleteEntry( &pFaninOld->vFanouts, pObj->Id ) ) { printf( "Node %s is not among", Abc_ObjName(pObj) ); printf( " the fanouts of its old fanin %s...\n", Abc_ObjName(pFaninOld) ); // return; } - Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninNewR->vFanouts, pObj->Id ); -} - -/**Function************************************************************* - - Synopsis [Inserts one-input node of the type specified between the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_ObjInsertBetween( Abc_Obj_t * pNodeIn, Abc_Obj_t * pNodeOut, Abc_ObjType_t Type ) -{ - Abc_Obj_t * pNodeNew; - int iFanoutIndex, iFaninIndex; - // find pNodeOut among the fanouts of pNodeIn - if ( (iFanoutIndex = Vec_IntFind( &pNodeIn->vFanouts, pNodeOut->Id )) == -1 ) - { - printf( "Node %s is not among", Abc_ObjName(pNodeOut) ); - printf( " the fanouts of node %s...\n", Abc_ObjName(pNodeIn) ); - return NULL; - } - // find pNodeIn among the fanins of pNodeOut - if ( (iFaninIndex = Vec_IntFind( &pNodeOut->vFanins, pNodeIn->Id )) == -1 ) - { - printf( "Node %s is not among", Abc_ObjName(pNodeIn) ); - printf( " the fanins of node %s...\n", Abc_ObjName(pNodeOut) ); - return NULL; - } - // create the new node - pNodeNew = Abc_NtkCreateObj( pNodeIn->pNtk, Type ); - // add pNodeIn as fanin and pNodeOut as fanout - Vec_IntPushMem( pNodeNew->pNtk->pMmStep, &pNodeNew->vFanins, pNodeIn->Id ); - Vec_IntPushMem( pNodeNew->pNtk->pMmStep, &pNodeNew->vFanouts, pNodeOut->Id ); - // update the fanout of pNodeIn - Vec_IntWriteEntry( &pNodeIn->vFanouts, iFanoutIndex, pNodeNew->Id ); - // update the fanin of pNodeOut - Vec_IntWriteEntry( &pNodeOut->vFanins, iFaninIndex, pNodeNew->Id ); - return pNodeNew; + Vec_FanPush( pObj->pNtk->pMmStep, &pFaninNewR->vFanouts, Vec_Int2Fan(pObj->Id) ); } /**Function************************************************************* @@ -263,24 +177,23 @@ Abc_Obj_t * Abc_ObjInsertBetween( Abc_Obj_t * pNodeIn, Abc_Obj_t * pNodeOut, Abc ***********************************************************************/ void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo ) { - Vec_Ptr_t * vFanouts; + Vec_Ptr_t * vFanouts = pNodeFrom->pNtk->vPtrTemp; int nFanoutsOld, i; assert( !Abc_ObjIsComplement(pNodeFrom) ); assert( !Abc_ObjIsComplement(pNodeTo) ); - assert( !Abc_ObjIsPo(pNodeFrom) && !Abc_ObjIsPo(pNodeTo) ); + assert( Abc_ObjIsNode(pNodeFrom) ); + assert( Abc_ObjIsNode(pNodeTo) ); assert( pNodeFrom->pNtk == pNodeTo->pNtk ); assert( pNodeFrom != pNodeTo ); assert( Abc_ObjFanoutNum(pNodeFrom) > 0 ); // get the fanouts of the old node nFanoutsOld = Abc_ObjFanoutNum(pNodeTo); - vFanouts = Vec_PtrAlloc( nFanoutsOld ); Abc_NodeCollectFanouts( pNodeFrom, vFanouts ); // patch the fanin of each of them for ( i = 0; i < vFanouts->nSize; i++ ) Abc_ObjPatchFanin( vFanouts->pArray[i], pNodeFrom, pNodeTo ); assert( Abc_ObjFanoutNum(pNodeFrom) == 0 ); assert( Abc_ObjFanoutNum(pNodeTo) == nFanoutsOld + vFanouts->nSize ); - Vec_PtrFree( vFanouts ); } /**Function************************************************************* @@ -298,34 +211,16 @@ void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew ) { assert( !Abc_ObjIsComplement(pNodeOld) ); assert( !Abc_ObjIsComplement(pNodeNew) ); + assert( Abc_ObjIsNode(pNodeOld) ); + assert( Abc_ObjIsNode(pNodeNew) ); assert( pNodeOld->pNtk == pNodeNew->pNtk ); assert( pNodeOld != pNodeNew ); assert( Abc_ObjFanoutNum(pNodeOld) > 0 ); + assert( Abc_ObjFanoutNum(pNodeNew) == 0 ); // transfer the fanouts to the old node Abc_ObjTransferFanout( pNodeOld, pNodeNew ); // remove the old node - Abc_NtkDeleteObj_rec( pNodeOld, 1 ); -} - -/**Function************************************************************* - - Synopsis [Returns the index of the fanin in the fanin list of the fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ObjFanoutFaninNum( Abc_Obj_t * pFanout, Abc_Obj_t * pFanin ) -{ - Abc_Obj_t * pObj; - int i; - Abc_ObjForEachFanin( pFanout, pObj, i ) - if ( pObj == pFanin ) - return i; - return -1; + Abc_NtkDeleteObj( pNodeOld ); } diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c index f3297d8f..e5af1829 100644 --- a/src/base/abc/abcFunc.c +++ b/src/base/abc/abcFunc.c @@ -19,21 +19,15 @@ ***********************************************************************/ #include "abc.h" -#include "main.h" -#include "mio.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define ABC_MUX_CUBES 100000 - -static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase ); -static DdNode * Abc_ConvertAigToBdd( DdManager * dd, Hop_Obj_t * pRoot); -static Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop ); +static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -52,8 +46,8 @@ int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk ) Abc_Obj_t * pNode; DdManager * dd; int nFaninsMax, i; - - assert( Abc_NtkHasSop(pNtk) ); + + assert( Abc_NtkIsSopLogic(pNtk) ); // start the functionality manager nFaninsMax = Abc_NtkGetFaninMax( pNtk ); @@ -75,7 +69,7 @@ int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk ) Cudd_Ref( pNode->pData ); } - Extra_MmFlexStop( pNtk->pManFunc ); + Extra_MmFlexStop( pNtk->pManFunc, 0 ); pNtk->pManFunc = dd; // update the network type @@ -99,40 +93,27 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ) DdNode * bSum, * bCube, * bTemp, * bVar; char * pCube; int nVars, Value, v; - // start the cover nVars = Abc_SopGetVarNum(pSop); + // check the logic function of the node bSum = Cudd_ReadLogicZero(dd); Cudd_Ref( bSum ); - if ( Abc_SopIsExorType(pSop) ) - { - for ( v = 0; v < nVars; v++ ) - { - bSum = Cudd_bddXor( dd, bTemp = bSum, Cudd_bddIthVar(dd, v) ); Cudd_Ref( bSum ); - Cudd_RecursiveDeref( dd, bTemp ); - } - } - else + Abc_SopForEachCube( pSop, nVars, pCube ) { - // check the logic function of the node - Abc_SopForEachCube( pSop, nVars, pCube ) + bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube ); + Abc_CubeForEachVar( pCube, Value, v ) { - bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube ); - Abc_CubeForEachVar( pCube, Value, v ) - { - if ( Value == '0' ) - bVar = Cudd_Not( Cudd_bddIthVar( dd, v ) ); - else if ( Value == '1' ) - bVar = Cudd_bddIthVar( dd, v ); - else - continue; - bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube ); - Cudd_RecursiveDeref( dd, bTemp ); - } - bSum = Cudd_bddOr( dd, bTemp = bSum, bCube ); - Cudd_Ref( bSum ); + if ( Value == '0' ) + bVar = Cudd_Not( Cudd_bddIthVar( dd, v ) ); + else if ( Value == '1' ) + bVar = Cudd_bddIthVar( dd, v ); + else + continue; + bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube ); Cudd_RecursiveDeref( dd, bTemp ); - Cudd_RecursiveDeref( dd, bCube ); } + bSum = Cudd_bddOr( dd, bTemp = bSum, bCube ); Cudd_Ref( bSum ); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bCube ); } // complement the result if necessary bSum = Cudd_NotCond( bSum, !Abc_SopGetPhase(pSop) ); @@ -159,7 +140,7 @@ void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ) Abc_Obj_t * pNode; int nFaninsMax, fFound, i; - assert( Abc_NtkHasSop(pNtk) ); + assert( Abc_NtkIsSopLogic(pNtk) ); // check if there are nodes with complemented SOPs fFound = 0; @@ -184,7 +165,7 @@ void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ) if ( Abc_SopIsComplement(pNode->pData) ) { bFunc = Abc_ConvertSopToBdd( dd, pNode->pData ); Cudd_Ref( bFunc ); - pNode->pData = Abc_ConvertBddToSop( pNtk->pManFunc, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), 0, vCube, 1 ); + pNode->pData = Abc_ConvertBddToSop( pNtk->pManFunc, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), vCube, 1 ); Cudd_RecursiveDeref( dd, bFunc ); assert( !Abc_SopIsComplement(pNode->pData) ); } @@ -200,32 +181,27 @@ void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ) Synopsis [Converts the network from BDD to SOP representation.] - Description [If the flag is set to 1, forces the direct phase of all covers.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect ) +int Abc_NtkBddToSop( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; - Extra_MmFlex_t * pManNew; DdManager * dd = pNtk->pManFunc; DdNode * bFunc; + int RetValue, i; Vec_Str_t * vCube; - int i, fMode; - - if ( fDirect ) - fMode = 1; - else - fMode = -1; - assert( Abc_NtkHasBdd(pNtk) ); - if ( dd->size > 0 ) + assert( Abc_NtkIsBddLogic(pNtk) ); Cudd_zddVarsFromBddVars( dd, 2 ); - // create the new manager - pManNew = Extra_MmFlexStart(); + // allocate the new manager + pNtk->pManFunc = Extra_MmFlexStart(); + // update the network type + pNtk->ntkFunc = ABC_FUNC_SOP; // go through the objects vCube = Vec_StrAlloc( 100 ); @@ -233,32 +209,19 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect ) { assert( pNode->pData ); bFunc = pNode->pData; - pNode->pNext = (Abc_Obj_t *)Abc_ConvertBddToSop( pManNew, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), 0, vCube, fMode ); - if ( pNode->pNext == NULL ) - { - Extra_MmFlexStop( pManNew ); - Abc_NtkCleanNext( pNtk ); -// printf( "Converting from BDDs to SOPs has failed.\n" ); - Vec_StrFree( vCube ); + pNode->pData = Abc_ConvertBddToSop( pNtk->pManFunc, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), vCube, -1 ); + if ( pNode->pData == NULL ) return 0; - } + Cudd_RecursiveDeref( dd, bFunc ); } Vec_StrFree( vCube ); - // update the network type - pNtk->ntkFunc = ABC_FUNC_SOP; - // set the new manager - pNtk->pManFunc = pManNew; - // transfer from next to data - Abc_NtkForEachNode( pNtk, pNode, i ) - { - Cudd_RecursiveDeref( dd, pNode->pData ); - pNode->pData = pNode->pNext; - pNode->pNext = NULL; - } - // check for remaining references in the package - Extra_StopManager( dd ); + RetValue = Cudd_CheckZeroRef( dd ); + if ( RetValue > 0 ) + printf( "\nThe number of referenced nodes = %d\n\n", RetValue ); +// Cudd_PrintInfo( dd, stdout ); + Cudd_Quit( dd ); return 1; } @@ -273,7 +236,7 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect ) SeeAlso [] ***********************************************************************/ -char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, int fAllPrimes, Vec_Str_t * vCube, int fMode ) +char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, Vec_Str_t * vCube, int fMode ) { int fVerify = 0; char * pSop; @@ -283,25 +246,22 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun assert( bFuncOn == bFuncOnDc || Cudd_bddLeq( dd, bFuncOn, bFuncOnDc ) ); if ( Cudd_IsConstant(bFuncOn) || Cudd_IsConstant(bFuncOnDc) ) { - if ( fMode == -1 ) // if the phase is not known, write constant 1 - fMode = 1; Vec_StrFill( vCube, nFanins, '-' ); Vec_StrPush( vCube, '\0' ); if ( pMan ) pSop = Extra_MmFlexEntryFetch( pMan, nFanins + 4 ); else pSop = ALLOC( char, nFanins + 4 ); - if ( bFuncOn == Cudd_ReadOne(dd) ) - sprintf( pSop, "%s %d\n", vCube->pArray, fMode ); + if ( bFuncOn == Cudd_ReadLogicZero(dd) ) + sprintf( pSop, "%s 0\n", vCube->pArray ); else - sprintf( pSop, "%s %d\n", vCube->pArray, !fMode ); + sprintf( pSop, "%s 1\n", vCube->pArray ); return pSop; } if ( fMode == -1 ) { // try both phases - assert( fAllPrimes == 0 ); // get the ZDD of the negative polarity bCover = Cudd_zddIsop( dd, Cudd_Not(bFuncOnDc), Cudd_Not(bFuncOn), &zCover0 ); @@ -336,36 +296,20 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun else if ( fMode == 0 ) { // get the ZDD of the negative polarity - if ( fAllPrimes ) - { - zCover = Extra_zddPrimes( dd, Cudd_Not(bFuncOnDc) ); - Cudd_Ref( zCover ); - } - else - { - bCover = Cudd_zddIsop( dd, Cudd_Not(bFuncOnDc), Cudd_Not(bFuncOn), &zCover ); - Cudd_Ref( zCover ); - Cudd_Ref( bCover ); - Cudd_RecursiveDeref( dd, bCover ); - } + bCover = Cudd_zddIsop( dd, Cudd_Not(bFuncOnDc), Cudd_Not(bFuncOn), &zCover ); + Cudd_Ref( zCover ); + Cudd_Ref( bCover ); + Cudd_RecursiveDeref( dd, bCover ); nCubes = Abc_CountZddCubes( dd, zCover ); fPhase = 0; } else if ( fMode == 1 ) { // get the ZDD of the positive polarity - if ( fAllPrimes ) - { - zCover = Extra_zddPrimes( dd, bFuncOnDc ); - Cudd_Ref( zCover ); - } - else - { - bCover = Cudd_zddIsop( dd, bFuncOn, bFuncOnDc, &zCover ); - Cudd_Ref( zCover ); - Cudd_Ref( bCover ); - Cudd_RecursiveDeref( dd, bCover ); - } + bCover = Cudd_zddIsop( dd, bFuncOn, bFuncOnDc, &zCover ); + Cudd_Ref( zCover ); + Cudd_Ref( bCover ); + Cudd_RecursiveDeref( dd, bCover ); nCubes = Abc_CountZddCubes( dd, zCover ); fPhase = 1; } @@ -374,13 +318,6 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun assert( 0 ); } - if ( nCubes > ABC_MUX_CUBES ) - { - Cudd_RecursiveDerefZdd( dd, zCover ); - printf( "The number of cubes exceeded the predefined limit (%d).\n", ABC_MUX_CUBES ); - return NULL; - } - // allocate memory for the cover if ( pMan ) pSop = Extra_MmFlexEntryFetch( pMan, (nFanins + 3) * nCubes + 1 ); @@ -479,11 +416,11 @@ int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFani SeeAlso [] ***********************************************************************/ -void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, int fAllPrimes, char ** ppSop0, char ** ppSop1 ) +void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, char ** ppSop0, char ** ppSop1 ) { - assert( Abc_NtkHasBdd(pNode->pNtk) ); - *ppSop0 = Abc_ConvertBddToSop( pMmMan, pNode->pNtk->pManFunc, pNode->pData, pNode->pData, Abc_ObjFaninNum(pNode), fAllPrimes, vCube, 0 ); - *ppSop1 = Abc_ConvertBddToSop( pMmMan, pNode->pNtk->pManFunc, pNode->pData, pNode->pData, Abc_ObjFaninNum(pNode), fAllPrimes, vCube, 1 ); + assert( Abc_NtkIsBddLogic(pNode->pNtk) ); + *ppSop0 = Abc_ConvertBddToSop( pMmMan, pNode->pNtk->pManFunc, pNode->pData, pNode->pData, Abc_ObjFaninNum(pNode), vCube, 0 ); + *ppSop1 = Abc_ConvertBddToSop( pMmMan, pNode->pNtk->pManFunc, pNode->pData, pNode->pData, Abc_ObjFaninNum(pNode), vCube, 1 ); } @@ -510,8 +447,6 @@ void Abc_CountZddCubes_rec( DdManager * dd, DdNode * zCover, int * pnCubes ) (*pnCubes)++; return; } - if ( (*pnCubes) > ABC_MUX_CUBES ) - return; extraDecomposeCover( dd, zCover, &zC0, &zC1, &zC2 ); Abc_CountZddCubes_rec( dd, zC0, pnCubes ); Abc_CountZddCubes_rec( dd, zC1, pnCubes ); @@ -537,616 +472,6 @@ 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; - Hop_Man_t * pMan; - int i; - - assert( Abc_NtkHasSop(pNtk) ); - - // start the functionality manager - pMan = Hop_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 ); - 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 [] - -***********************************************************************/ -Hop_Obj_t * Abc_ConvertSopToAigInternal( Hop_Man_t * pMan, char * pSop ) -{ - Hop_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 = Hop_ManConst0(pMan); - Abc_SopForEachCube( pSop, nFanins, pCube ) - { - // create the AND of literals - pAnd = Hop_ManConst1(pMan); - Abc_CubeForEachVar( pCube, Value, i ) - { - if ( Value == '1' ) - pAnd = Hop_And( pMan, pAnd, Hop_IthVar(pMan,i) ); - else if ( Value == '0' ) - pAnd = Hop_And( pMan, pAnd, Hop_Not(Hop_IthVar(pMan,i)) ); - } - // add to the sum of cubes - pSum = Hop_Or( pMan, pSum, pAnd ); - } - // decide whether to complement the result - if ( Abc_SopIsComplement(pSop) ) - pSum = Hop_Not(pSum); - return pSum; -} - -/**Function************************************************************* - - Synopsis [Converts the network from AIG to BDD representation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop ) -{ - extern Hop_Obj_t * Dec_GraphFactorSop( Hop_Man_t * pMan, char * pSop ); - int fUseFactor = 1; - // consider the constant node - if ( Abc_SopGetVarNum(pSop) == 0 ) - return Hop_NotCond( Hop_ManConst1(pMan), Abc_SopIsConst0(pSop) ); - // consider the special case of EXOR function - if ( Abc_SopIsExorType(pSop) ) - return Hop_NotCond( Hop_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; - Hop_Man_t * pMan; - DdManager * dd; - int nFaninsMax, i; - - assert( Abc_NtkHasAig(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 elementary AIG nodes into the elementary BDD nodes - pMan = pNtk->pManFunc; - assert( Hop_ManPiNum(pMan) >= nFaninsMax ); - for ( i = 0; i < nFaninsMax; i++ ) - { - Hop_ManPi(pMan, i)->pData = Cudd_bddIthVar(dd, i); - Cudd_Ref( Hop_ManPi(pMan, i)->pData ); - } - - // 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 ); - } - - // dereference intermediate BDD nodes - for ( i = 0; i < nFaninsMax; i++ ) - Cudd_RecursiveDeref( dd, Hop_ManPi(pMan, i)->pData ); - - Hop_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, Hop_Obj_t * pObj ) -{ - assert( !Hop_IsComplement(pObj) ); - if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) - return; - Abc_ConvertAigToBdd_rec1( dd, Hop_ObjFanin0(pObj) ); - Abc_ConvertAigToBdd_rec1( dd, Hop_ObjFanin1(pObj) ); - pObj->pData = Cudd_bddAnd( dd, (DdNode *)Hop_ObjChild0Copy(pObj), (DdNode *)Hop_ObjChild1Copy(pObj) ); - Cudd_Ref( pObj->pData ); - assert( !Hop_ObjIsMarkA(pObj) ); // loop detection - Hop_ObjSetMarkA( pObj ); -} - -/**Function************************************************************* - - Synopsis [Dereference BDDs and unmark AIG nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ConvertAigToBdd_rec2( DdManager * dd, Hop_Obj_t * pObj ) -{ - assert( !Hop_IsComplement(pObj) ); - if ( !Hop_ObjIsNode(pObj) || !Hop_ObjIsMarkA(pObj) ) - return; - Abc_ConvertAigToBdd_rec2( dd, Hop_ObjFanin0(pObj) ); - Abc_ConvertAigToBdd_rec2( dd, Hop_ObjFanin1(pObj) ); - Cudd_RecursiveDeref( dd, pObj->pData ); - pObj->pData = NULL; - assert( Hop_ObjIsMarkA(pObj) ); // loop detection - Hop_ObjClearMarkA( pObj ); -} - -/**Function************************************************************* - - Synopsis [Converts the network from AIG to BDD representation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_ConvertAigToBdd( DdManager * dd, Hop_Obj_t * pRoot ) -{ - DdNode * bFunc; - // check the case of a constant - if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) ) - return Cudd_NotCond( Cudd_ReadOne(dd), Hop_IsComplement(pRoot) ); - // construct BDD - Abc_ConvertAigToBdd_rec1( dd, Hop_Regular(pRoot) ); - // hold on to the result - bFunc = Cudd_NotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); Cudd_Ref( bFunc ); - // dereference BDD - Abc_ConvertAigToBdd_rec2( dd, Hop_Regular(pRoot) ); - // return the result - Cudd_Deref( bFunc ); - return bFunc; -} - - - -/**Function************************************************************* - - Synopsis [Construct BDDs and mark AIG nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ConvertAigToTruth_rec1( Hop_Obj_t * pObj ) -{ - int Counter = 0; - assert( !Hop_IsComplement(pObj) ); - if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) - return 0; - Counter += Abc_ConvertAigToTruth_rec1( Hop_ObjFanin0(pObj) ); - Counter += Abc_ConvertAigToTruth_rec1( Hop_ObjFanin1(pObj) ); - assert( !Hop_ObjIsMarkA(pObj) ); // loop detection - Hop_ObjSetMarkA( pObj ); - return Counter + 1; -} - -/**Function************************************************************* - - Synopsis [Computes truth table of the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned * Abc_ConvertAigToTruth_rec2( Hop_Obj_t * pObj, Vec_Int_t * vTruth, int nWords ) -{ - unsigned * pTruth, * pTruth0, * pTruth1; - int i; - assert( !Hop_IsComplement(pObj) ); - if ( !Hop_ObjIsNode(pObj) || !Hop_ObjIsMarkA(pObj) ) - return pObj->pData; - // compute the truth tables of the fanins - pTruth0 = Abc_ConvertAigToTruth_rec2( Hop_ObjFanin0(pObj), vTruth, nWords ); - pTruth1 = Abc_ConvertAigToTruth_rec2( Hop_ObjFanin1(pObj), vTruth, nWords ); - // creat the truth table of the node - pTruth = Vec_IntFetch( vTruth, nWords ); - if ( Hop_ObjIsExor(pObj) ) - for ( i = 0; i < nWords; i++ ) - pTruth[i] = pTruth0[i] ^ pTruth1[i]; - else if ( !Hop_ObjFaninC0(pObj) && !Hop_ObjFaninC1(pObj) ) - for ( i = 0; i < nWords; i++ ) - pTruth[i] = pTruth0[i] & pTruth1[i]; - else if ( !Hop_ObjFaninC0(pObj) && Hop_ObjFaninC1(pObj) ) - for ( i = 0; i < nWords; i++ ) - pTruth[i] = pTruth0[i] & ~pTruth1[i]; - else if ( Hop_ObjFaninC0(pObj) && !Hop_ObjFaninC1(pObj) ) - for ( i = 0; i < nWords; i++ ) - pTruth[i] = ~pTruth0[i] & pTruth1[i]; - else // if ( Hop_ObjFaninC0(pObj) && Hop_ObjFaninC1(pObj) ) - for ( i = 0; i < nWords; i++ ) - pTruth[i] = ~pTruth0[i] & ~pTruth1[i]; - assert( Hop_ObjIsMarkA(pObj) ); // loop detection - Hop_ObjClearMarkA( pObj ); - pObj->pData = pTruth; - return pTruth; -} - -/**Function************************************************************* - - Synopsis [Computes truth table of the node.] - - Description [Assumes that the structural support is no more than 8 inputs. - Uses array vTruth to store temporary truth tables. The returned pointer should - be used immediately.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned * Abc_ConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, int fMsbFirst ) -{ - static unsigned uTruths[8][8] = { // elementary truth tables - { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA }, - { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC }, - { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 }, - { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 }, - { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, - { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, - { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, - { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } - }; - Hop_Obj_t * pObj; - unsigned * pTruth, * pTruth2; - int i, nWords, nNodes; - Vec_Ptr_t * vTtElems; - - // if the number of variables is more than 8, allocate truth tables - if ( nVars > 8 ) - vTtElems = Vec_PtrAllocTruthTables( nVars ); - else - vTtElems = NULL; - - // clear the data fields and set marks - nNodes = Abc_ConvertAigToTruth_rec1( pRoot ); - // prepare memory - nWords = Hop_TruthWordNum( nVars ); - Vec_IntClear( vTruth ); - Vec_IntGrow( vTruth, nWords * (nNodes+1) ); - pTruth = Vec_IntFetch( vTruth, nWords ); - // check the case of a constant - if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) ) - { - assert( nNodes == 0 ); - if ( Hop_IsComplement(pRoot) ) - Extra_TruthClear( pTruth, nVars ); - else - Extra_TruthFill( pTruth, nVars ); - return pTruth; - } - // set elementary truth tables at the leaves - assert( nVars <= Hop_ManPiNum(p) ); -// assert( Hop_ManPiNum(p) <= 8 ); - if ( fMsbFirst ) - { - Hop_ManForEachPi( p, pObj, i ) - { - if ( vTtElems ) - pObj->pData = Vec_PtrEntry(vTtElems, nVars-1-i); - else - pObj->pData = (void *)uTruths[nVars-1-i]; - } - } - else - { - Hop_ManForEachPi( p, pObj, i ) - { - if ( vTtElems ) - pObj->pData = Vec_PtrEntry(vTtElems, i); - else - pObj->pData = (void *)uTruths[i]; - } - } - // clear the marks and compute the truth table - pTruth2 = Abc_ConvertAigToTruth_rec2( pRoot, vTruth, nWords ); - // copy the result - Extra_TruthCopy( pTruth, pTruth2, nVars ); - if ( vTtElems ) - Vec_PtrFree( vTtElems ); - return pTruth; -} - - -/**Function************************************************************* - - Synopsis [Construct BDDs and mark AIG nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ConvertAigToAig_rec( Abc_Ntk_t * pNtkAig, Hop_Obj_t * pObj ) -{ - assert( !Hop_IsComplement(pObj) ); - if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) - return; - Abc_ConvertAigToAig_rec( pNtkAig, Hop_ObjFanin0(pObj) ); - Abc_ConvertAigToAig_rec( pNtkAig, Hop_ObjFanin1(pObj) ); - pObj->pData = Abc_AigAnd( pNtkAig->pManFunc, (Abc_Obj_t *)Hop_ObjChild0Copy(pObj), (Abc_Obj_t *)Hop_ObjChild1Copy(pObj) ); - assert( !Hop_ObjIsMarkA(pObj) ); // loop detection - Hop_ObjSetMarkA( pObj ); -} - -/**Function************************************************************* - - Synopsis [Converts the network from AIG to BDD representation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_ConvertAigToAig( Abc_Ntk_t * pNtkAig, Abc_Obj_t * pObjOld ) -{ - Hop_Man_t * pHopMan; - Hop_Obj_t * pRoot; - Abc_Obj_t * pFanin; - int i; - // get the local AIG - pHopMan = pObjOld->pNtk->pManFunc; - pRoot = pObjOld->pData; - // check the case of a constant - if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) ) - return Abc_ObjNotCond( Abc_AigConst1(pNtkAig), Hop_IsComplement(pRoot) ); - // assign the fanin nodes - Abc_ObjForEachFanin( pObjOld, pFanin, i ) - { - assert( pFanin->pCopy != NULL ); - Hop_ManPi(pHopMan, i)->pData = pFanin->pCopy; - } - // construct the AIG - Abc_ConvertAigToAig_rec( pNtkAig, Hop_Regular(pRoot) ); - Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); - // return the result - return Abc_ObjNotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); -} - - -/**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_NtkHasMapping(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 [Converts SOP functions into BLIF-MV functions.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkSopToBlifMv( Abc_Ntk_t * pNtk ) -{ - return 1; -} - -/**Function************************************************************* - - Synopsis [Convers logic network to the SOP form.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkToSop( Abc_Ntk_t * pNtk, int fDirect ) -{ - assert( !Abc_NtkIsStrash(pNtk) ); - if ( Abc_NtkHasSop(pNtk) ) - { - if ( !fDirect ) - return 1; - if ( !Abc_NtkSopToBdd(pNtk) ) - return 0; - return Abc_NtkBddToSop(pNtk, fDirect); - } - if ( Abc_NtkHasMapping(pNtk) ) - return Abc_NtkMapToSop(pNtk); - if ( Abc_NtkHasBdd(pNtk) ) - return Abc_NtkBddToSop(pNtk, fDirect); - if ( Abc_NtkHasAig(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_NtkToBdd( Abc_Ntk_t * pNtk ) -{ - assert( !Abc_NtkIsStrash(pNtk) ); - if ( Abc_NtkHasBdd(pNtk) ) - return 1; - if ( Abc_NtkHasMapping(pNtk) ) - { - Abc_NtkMapToSop(pNtk); - return Abc_NtkSopToBdd(pNtk); - } - if ( Abc_NtkHasSop(pNtk) ) - return Abc_NtkSopToBdd(pNtk); - if ( Abc_NtkHasAig(pNtk) ) - return Abc_NtkAigToBdd(pNtk); - assert( 0 ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Convers logic network to the SOP form.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkToAig( Abc_Ntk_t * pNtk ) -{ - assert( !Abc_NtkIsStrash(pNtk) ); - if ( Abc_NtkHasAig(pNtk) ) - return 1; - if ( Abc_NtkHasMapping(pNtk) ) - { - Abc_NtkMapToSop(pNtk); - return Abc_NtkSopToAig(pNtk); - } - if ( Abc_NtkHasBdd(pNtk) ) - { - if ( !Abc_NtkBddToSop(pNtk,0) ) - return 0; - return Abc_NtkSopToAig(pNtk); - } - if ( Abc_NtkHasSop(pNtk) ) - return Abc_NtkSopToAig(pNtk); - assert( 0 ); - return 0; -} - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcHie.c b/src/base/abc/abcHie.c deleted file mode 100644 index 56333a36..00000000 --- a/src/base/abc/abcHie.c +++ /dev/null @@ -1,492 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcHie.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Procedures to handle hierarchy.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcHie.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Recursively flattens logic hierarchy of the netlist.] - - Description [When this procedure is called, the PI/PO nets of the old - netlist point to the corresponding nets of the flattened netlist.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFlattenLogicHierarchy_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, int * pCounter ) -{ - char Suffix[1000] = {0}; - Abc_Ntk_t * pNtkModel; - Abc_Obj_t * pObj, * pTerm, * pNet, * pFanin; - int i, k; - - // process the blackbox - if ( Abc_NtkHasBlackbox(pNtk) ) - { - // duplicate the blackbox - assert( Abc_NtkBoxNum(pNtk) == 1 ); - pObj = Abc_NtkBox( pNtk, 0 ); - Abc_NtkDupBox( pNtkNew, pObj, 1 ); - pObj->pCopy->pData = pNtk; - - // connect blackbox fanins to the PI nets - assert( Abc_ObjFaninNum(pObj->pCopy) == Abc_NtkPiNum(pNtk) ); - Abc_NtkForEachPi( pNtk, pTerm, i ) - Abc_ObjAddFanin( Abc_ObjFanin(pObj->pCopy,i), Abc_ObjFanout0(pTerm)->pCopy ); - - // connect blackbox fanouts to the PO nets - assert( Abc_ObjFanoutNum(pObj->pCopy) == Abc_NtkPoNum(pNtk) ); - Abc_NtkForEachPo( pNtk, pTerm, i ) - Abc_ObjAddFanin( Abc_ObjFanin0(pTerm)->pCopy, Abc_ObjFanout(pObj->pCopy,i) ); - return; - } - - (*pCounter)++; - - // create the prefix, which will be appended to the internal names - if ( *pCounter ) - sprintf( Suffix, "_%s_%d", Abc_NtkName(pNtk), *pCounter ); - - // duplicate nets of all boxes, including latches - Abc_NtkForEachBox( pNtk, pObj, i ) - { - Abc_ObjForEachFanin( pObj, pTerm, k ) - { - pNet = Abc_ObjFanin0(pTerm); - if ( pNet->pCopy ) - continue; - pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjNameSuffix(pNet, Suffix) ); - } - Abc_ObjForEachFanout( pObj, pTerm, k ) - { - pNet = Abc_ObjFanout0(pTerm); - if ( pNet->pCopy ) - continue; - pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjNameSuffix(pNet, Suffix) ); - } - } - - // mark objects that will not be used - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachPi( pNtk, pTerm, i ) - Abc_NodeSetTravIdCurrent( pTerm ); - Abc_NtkForEachPo( pNtk, pTerm, i ) - Abc_NodeSetTravIdCurrent( pTerm ); - Abc_NtkForEachBox( pNtk, pObj, i ) - { - if ( Abc_ObjIsLatch(pObj) ) - continue; - Abc_NodeSetTravIdCurrent( pObj ); - Abc_ObjForEachFanin( pObj, pTerm, k ) - Abc_NodeSetTravIdCurrent( pTerm ); - Abc_ObjForEachFanout( pObj, pTerm, k ) - Abc_NodeSetTravIdCurrent( pTerm ); - } - - // duplicate objects that do not have prototypes yet - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( Abc_NodeIsTravIdCurrent(pObj) ) - continue; - if ( pObj->pCopy ) - continue; - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - } - - // connect objects - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( !Abc_NodeIsTravIdCurrent(pObj) ) - Abc_ObjForEachFanin( pObj, pFanin, k ) - if ( !Abc_NodeIsTravIdCurrent(pFanin) ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - - // call recursively - Abc_NtkForEachBox( pNtk, pObj, i ) - { - if ( Abc_ObjIsLatch(pObj) ) - continue; - pNtkModel = pObj->pData; - // check the match between the number of actual and formal parameters - assert( Abc_ObjFaninNum(pObj) == Abc_NtkPiNum(pNtkModel) ); - assert( Abc_ObjFanoutNum(pObj) == Abc_NtkPoNum(pNtkModel) ); - // clean the node copy fields - Abc_NtkCleanCopy( pNtkModel ); - // map PIs/POs - Abc_ObjForEachFanin( pObj, pTerm, k ) - Abc_ObjFanout0( Abc_NtkPi(pNtkModel, k) )->pCopy = Abc_ObjFanin0(pTerm)->pCopy; - Abc_ObjForEachFanout( pObj, pTerm, k ) - Abc_ObjFanin0( Abc_NtkPo(pNtkModel, k) )->pCopy = Abc_ObjFanout0(pTerm)->pCopy; - // call recursively - Abc_NtkFlattenLogicHierarchy_rec( pNtkNew, pNtkModel, pCounter ); - } - - // if it is a BLIF-MV netlist transfer the values of all nets - if ( Abc_NtkHasBlifMv(pNtk) && Abc_NtkMvVar(pNtk) ) - { - if ( Abc_NtkMvVar( pNtkNew ) == NULL ) - Abc_NtkStartMvVars( pNtkNew ); - Abc_NtkForEachNet( pNtk, pObj, i ) - Abc_NtkSetMvVarValues( pObj->pCopy, Abc_ObjMvVarNum(pObj) ); - } -} - -/**Function************************************************************* - - Synopsis [Flattens the logic hierarchy of the netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFlattenLogicHierarchy( Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pTerm, * pNet; - int i, Counter; - extern Abc_Lib_t * Abc_LibDupBlackboxes( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave ); - - assert( Abc_NtkIsNetlist(pNtk) ); - // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); - // duplicate the name and the spec - pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); - pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); - - // clean the node copy fields - Abc_NtkCleanCopy( pNtk ); - - // duplicate PIs/POs and their nets - Abc_NtkForEachPi( pNtk, pTerm, i ) - { - Abc_NtkDupObj( pNtkNew, pTerm, 0 ); - pNet = Abc_ObjFanout0( pTerm ); - pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNet) ); - Abc_ObjAddFanin( pNet->pCopy, pTerm->pCopy ); - } - Abc_NtkForEachPo( pNtk, pTerm, i ) - { - Abc_NtkDupObj( pNtkNew, pTerm, 0 ); - pNet = Abc_ObjFanin0( pTerm ); - pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNet) ); - Abc_ObjAddFanin( pTerm->pCopy, pNet->pCopy ); - } - - // recursively flatten hierarchy, create internal logic, add new PI/PO names if there are black boxes - Counter = -1; - Abc_NtkFlattenLogicHierarchy_rec( pNtkNew, pNtk, &Counter ); - printf( "Hierarchy reader flattened %d instances of logic boxes and left %d black boxes.\n", - Counter, Abc_NtkBlackboxNum(pNtkNew) ); - - if ( pNtk->pDesign ) - { - // pass on the design - assert( Vec_PtrEntry(pNtk->pDesign->vTops, 0) == pNtk ); - pNtkNew->pDesign = Abc_LibDupBlackboxes( pNtk->pDesign, pNtkNew ); - // update the pointers - Abc_NtkForEachBlackbox( pNtkNew, pTerm, i ) - pTerm->pData = ((Abc_Ntk_t *)pTerm->pData)->pCopy; - } - - // copy the timing information -// Abc_ManTimeDup( pNtk, pNtkNew ); - // duplicate EXDC - if ( pNtk->pExdc ) - printf( "EXDC is not transformed.\n" ); - if ( !Abc_NtkCheck( pNtkNew ) ) - { - fprintf( stdout, "Abc_NtkFlattenLogicHierarchy(): Network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Extracts blackboxes by making them into additional PIs/POs.] - - Description [The input netlist has not logic hierarchy. The resulting - netlist has additional PIs/POs for each blackbox input/output.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkConvertBlackboxes( Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pNet, * pFanin, * pTerm; - int i, k; - - assert( Abc_NtkIsNetlist(pNtk) ); - assert( Abc_NtkWhiteboxNum(pNtk) == 0 ); - - // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); - // duplicate the name and the spec - pNtkNew->pName = Extra_UtilStrsav( pNtk->pName ); - pNtkNew->pSpec = Extra_UtilStrsav( pNtk->pSpec ); - - // clean the node copy fields - Abc_NtkCleanCopy( pNtk ); - - // mark the nodes that should not be connected - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachBlackbox( pNtk, pObj, i ) - Abc_NodeSetTravIdCurrent( pObj ); - Abc_NtkForEachCi( pNtk, pTerm, i ) - Abc_NodeSetTravIdCurrent( pTerm ); - Abc_NtkForEachCo( pNtk, pTerm, i ) - Abc_NodeSetTravIdCurrent( pTerm ); - // unmark PIs and LIs/LOs - Abc_NtkForEachPi( pNtk, pTerm, i ) - Abc_NodeSetTravIdPrevious( pTerm ); - Abc_NtkForEachLatchInput( pNtk, pTerm, i ) - Abc_NodeSetTravIdPrevious( pTerm ); - Abc_NtkForEachLatchOutput( pNtk, pTerm, i ) - Abc_NodeSetTravIdPrevious( pTerm ); - // copy the box outputs - Abc_NtkForEachBlackbox( pNtk, pObj, i ) - Abc_ObjForEachFanout( pObj, pTerm, k ) - pTerm->pCopy = Abc_NtkCreatePi( pNtkNew ); - - // duplicate other objects - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( !Abc_NodeIsTravIdCurrent(pObj) ) - Abc_NtkDupObj( pNtkNew, pObj, Abc_ObjIsNet(pObj) ); - - // connect all objects - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( !Abc_NodeIsTravIdCurrent(pObj) ) - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - - // create unique PO for each net feeding into blackboxes or POs - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachCo( pNtk, pTerm, i ) - { - // skip latch inputs - assert( Abc_ObjFanoutNum(pTerm) <= 1 ); - if ( Abc_ObjFanoutNum(pTerm) > 0 && Abc_ObjIsLatch(Abc_ObjFanout0(pTerm)) ) - continue; - // check if the net is visited - pNet = Abc_ObjFanin0(pTerm); - if ( Abc_NodeIsTravIdCurrent(pNet) ) - continue; - // create PO - Abc_NodeSetTravIdCurrent( pNet ); - Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNet->pCopy ); - } - - // check integrity - if ( !Abc_NtkCheck( pNtkNew ) ) - { - fprintf( stdout, "Abc_NtkConvertBlackboxes(): Network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Inserts blackboxes into the netlist.] - - Description [The first arg is the netlist with blackboxes without logic hierarchy. - The second arg is a non-hierarchical netlist derived from the above netlist after processing. - This procedure create a new netlist, which is comparable to the original netlist with - blackboxes, except that it contains logic nodes from the netlist after processing.] - - SideEffects [This procedure silently assumes that blackboxes appear - only in the top-level model. If they appear in other models as well, - the name of the model and its number were appended to the names of - blackbox inputs/outputs.] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkInsertNewLogic( Abc_Ntk_t * pNtkH, Abc_Ntk_t * pNtkL ) -{ - Abc_Lib_t * pDesign; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObjH, * pObjL, * pNetH, * pNetL, * pTermH; - int i, k; - - assert( Abc_NtkIsNetlist(pNtkH) ); - assert( Abc_NtkWhiteboxNum(pNtkH) == 0 ); - assert( Abc_NtkBlackboxNum(pNtkH) > 0 ); - - assert( Abc_NtkIsNetlist(pNtkL) ); - assert( Abc_NtkWhiteboxNum(pNtkL) == 0 ); - assert( Abc_NtkBlackboxNum(pNtkL) == 0 ); - - // prepare the logic network for copying - Abc_NtkCleanCopy( pNtkL ); - - // start the network - pNtkNew = Abc_NtkAlloc( pNtkL->ntkType, pNtkL->ntkFunc, 1 ); - // duplicate the name and the spec - pNtkNew->pName = Extra_UtilStrsav( pNtkH->pName ); - pNtkNew->pSpec = Extra_UtilStrsav( pNtkH->pSpec ); - - // make sure every PI/PO has a PI/PO in the processed network - Abc_NtkForEachPi( pNtkH, pObjH, i ) - { - pNetH = Abc_ObjFanout0(pObjH); - pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) ); - if ( pNetL == NULL || !Abc_ObjIsPi( Abc_ObjFanin0(pNetL) ) ) - { - printf( "Error in Abc_NtkInsertNewLogic(): There is no PI corresponding to the PI %s.\n", Abc_ObjName(pNetH) ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - if ( pNetL->pCopy ) - { - printf( "Error in Abc_NtkInsertNewLogic(): Primary input %s is repeated twice.\n", Abc_ObjName(pNetH) ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - // create the new net - pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) ); - Abc_NtkDupObj( pNtkNew, Abc_ObjFanin0(pNetL), 0 ); - } - - // make sure every BB has a PI/PO in the processed network - Abc_NtkForEachBlackbox( pNtkH, pObjH, i ) - { - // duplicate the box - Abc_NtkDupBox( pNtkNew, pObjH, 0 ); - pObjH->pCopy->pData = pObjH->pData; - // create PIs - Abc_ObjForEachFanout( pObjH, pTermH, k ) - { - pNetH = Abc_ObjFanout0( pTermH ); - pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) ); - if ( pNetL == NULL || !Abc_ObjIsPi( Abc_ObjFanin0(pNetL) ) ) - { - printf( "Error in Abc_NtkInsertNewLogic(): There is no PI corresponding to the inpout %s of blackbox %s.\n", Abc_ObjName(pNetH), Abc_ObjName(pObjH) ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - if ( pNetL->pCopy ) - { - printf( "Error in Abc_NtkInsertNewLogic(): Box output %s is repeated twice.\n", Abc_ObjName(pNetH) ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - // create net and map the PI - pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) ); - Abc_ObjFanin0(pNetL)->pCopy = pTermH->pCopy; - } - } - - Abc_NtkForEachPo( pNtkH, pObjH, i ) - { - pNetH = Abc_ObjFanin0(pObjH); - pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) ); - if ( pNetL == NULL || !Abc_ObjIsPo( Abc_ObjFanout0(pNetL) ) ) - { - printf( "Error in Abc_NtkInsertNewLogic(): There is no PO corresponding to the PO %s.\n", Abc_ObjName(pNetH) ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - if ( pNetL->pCopy ) - continue; - // create the new net - pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) ); - Abc_NtkDupObj( pNtkNew, Abc_ObjFanout0(pNetL), 0 ); - } - Abc_NtkForEachBlackbox( pNtkH, pObjH, i ) - { - Abc_ObjForEachFanin( pObjH, pTermH, k ) - { - char * pName; - pNetH = Abc_ObjFanin0( pTermH ); - pName = Abc_ObjName(pNetH); - pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) ); - if ( pNetL == NULL || !Abc_ObjIsPo( Abc_ObjFanout0(pNetL) ) ) - { - printf( "There is no PO corresponding to the input %s of blackbox %s.\n", Abc_ObjName(pNetH), Abc_ObjName(pObjH) ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - // create net and map the PO - if ( pNetL->pCopy ) - { - if ( Abc_ObjFanout0(pNetL)->pCopy == NULL ) - Abc_ObjFanout0(pNetL)->pCopy = pTermH->pCopy; - else - Abc_ObjAddFanin( pTermH->pCopy, pNetL->pCopy ); - continue; - } - pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) ); - Abc_ObjFanout0(pNetL)->pCopy = pTermH->pCopy; - } - } - - // duplicate other objects of the logic network - Abc_NtkForEachObj( pNtkL, pObjL, i ) - if ( pObjL->pCopy == NULL && !Abc_ObjIsPo(pObjL) ) // skip POs feeding into PIs - Abc_NtkDupObj( pNtkNew, pObjL, Abc_ObjIsNet(pObjL) ); - - // connect objects - Abc_NtkForEachObj( pNtkL, pObjL, i ) - Abc_ObjForEachFanin( pObjL, pNetL, k ) - if ( pObjL->pCopy ) - Abc_ObjAddFanin( pObjL->pCopy, pNetL->pCopy ); - - // transfer the design - pDesign = pNtkH->pDesign; pNtkH->pDesign = NULL; - assert( Vec_PtrEntry( pDesign->vModules, 0 ) == pNtkH ); - Vec_PtrWriteEntry( pDesign->vModules, 0, pNtkNew ); - pNtkNew->pDesign = pDesign; - -//Abc_NtkPrintStats( stdout, pNtkH, 0 ); -//Abc_NtkPrintStats( stdout, pNtkNew, 0 ); - - // check integrity - if ( !Abc_NtkCheck( pNtkNew ) ) - { - fprintf( stdout, "Abc_NtkInsertNewLogic(): Network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcInt.h b/src/base/abc/abcInt.h index 0e35e774..1a1ab75f 100644 --- a/src/base/abc/abcInt.h +++ b/src/base/abc/abcInt.h @@ -29,24 +29,18 @@ /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#define ABC_NUM_STEPS 10 - //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// +/// END OF FILE /// //////////////////////////////////////////////////////////////////////// #endif -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c index d96bbfac..d804601e 100644 --- a/src/base/abc/abcLatch.c +++ b/src/base/abc/abcLatch.c @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -45,10 +45,10 @@ bool Abc_NtkLatchIsSelfFeed_rec( Abc_Obj_t * pLatch, Abc_Obj_t * pLatchRoot ) assert( Abc_ObjIsLatch(pLatch) ); if ( pLatch == pLatchRoot ) return 1; - pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch)); - if ( !Abc_ObjIsBo(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) ) + pFanin = Abc_ObjFanin0(pLatch); + if ( !Abc_ObjIsLatch(pFanin) ) return 0; - return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatch ); + return Abc_NtkLatchIsSelfFeed_rec( pFanin, pLatch ); } /**Function************************************************************* @@ -66,10 +66,10 @@ bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch ) { Abc_Obj_t * pFanin; assert( Abc_ObjIsLatch(pLatch) ); - pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch)); - if ( !Abc_ObjIsBo(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) ) + pFanin = Abc_ObjFanin0(pLatch); + if ( !Abc_ObjIsLatch(pFanin) ) return 0; - return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatch ); + return Abc_NtkLatchIsSelfFeed_rec( pFanin, pLatch ); } /**Function************************************************************* @@ -89,234 +89,10 @@ int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk ) int i, Counter; Counter = 0; Abc_NtkForEachLatch( pNtk, pLatch, i ) - { -// if ( Abc_NtkLatchIsSelfFeed(pLatch) && Abc_ObjFanoutNum(pLatch) > 1 ) -// printf( "Fanouts = %d.\n", Abc_ObjFanoutNum(pLatch) ); Counter += Abc_NtkLatchIsSelfFeed( pLatch ); - } return Counter; } -/**Function************************************************************* - - Synopsis [Replaces self-feeding latches by latches with constant inputs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pLatch, * pConst1; - int i, Counter; - Counter = 0; - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - if ( Abc_NtkLatchIsSelfFeed( pLatch ) ) - { - if ( Abc_NtkIsStrash(pNtk) ) - pConst1 = Abc_AigConst1(pNtk); - else - pConst1 = Abc_NtkCreateNodeConst1(pNtk); - Abc_ObjPatchFanin( Abc_ObjFanin0(pLatch), Abc_ObjFanin0(Abc_ObjFanin0(pLatch)), pConst1 ); - Counter++; - } - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Pipelines the network with latches.] - - Description [] - - SideEffects [Does not check the names of the added latches!!!] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj, * pLatch, * pFanin, * pFanout; - int i, k, nTotal, nDigits; - if ( nLatches < 1 ) - return; - nTotal = nLatches * Abc_NtkPiNum(pNtk); - nDigits = Extra_Base10Log( nTotal ); - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachPi( pNtk, pObj, i ) - { - // remember current fanins of the PI - Abc_NodeCollectFanouts( pObj, vNodes ); - // create the latches - for ( pFanin = pObj, k = 0; k < nLatches; k++, pFanin = pLatch ) - { - pLatch = Abc_NtkCreateLatch( pNtk ); - Abc_ObjAddFanin( pLatch, pFanin ); - Abc_LatchSetInitDc( pLatch ); - // create the name of the new latch - Abc_ObjAssignName( pLatch, Abc_ObjNameDummy("LL", i*nLatches + k, nDigits), NULL ); - } - // patch the PI fanouts - Vec_PtrForEachEntry( vNodes, pFanout, k ) - Abc_ObjPatchFanin( pFanout, pObj, pFanin ); - } - Vec_PtrFree( vNodes ); - Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk ) -{ - Vec_Int_t * vValues; - Abc_Obj_t * pLatch; - int i; - vValues = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) ); - Abc_NtkForEachLatch( pNtk, pLatch, i ) - Vec_IntPush( vValues, Abc_LatchIsInit1(pLatch) ); - return vValues; -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues ) -{ - Abc_Obj_t * pLatch; - int i; - Abc_NtkForEachLatch( pNtk, pLatch, i ) - pLatch->pData = (void *)(vValues? (Vec_IntEntry(vValues,i)? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC); -} - -/**Function************************************************************* - - Synopsis [Creates latch with the given initial value.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkAddLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pDriver, Abc_InitType_t Init ) -{ - Abc_Obj_t * pLatchOut, * pLatch, * pLatchIn; - pLatchOut = Abc_NtkCreateBo(pNtk); - pLatch = Abc_NtkCreateLatch(pNtk); - pLatchIn = Abc_NtkCreateBi(pNtk); - Abc_ObjAssignName( pLatchOut, Abc_ObjName(pLatch), "_lo" ); - Abc_ObjAssignName( pLatchIn, Abc_ObjName(pLatch), "_li" ); - Abc_ObjAddFanin( pLatchOut, pLatch ); - Abc_ObjAddFanin( pLatch, pLatchIn ); - Abc_ObjAddFanin( pLatchIn, pDriver ); - pLatch->pData = (void *)Init; - return pLatchOut; -} - -/**Function************************************************************* - - Synopsis [Creates MUX.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkNodeConvertToMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0, Abc_Obj_t * pMux ) -{ - assert( Abc_NtkIsLogic(pNtk) ); - Abc_ObjAddFanin( pMux, pNodeC ); - Abc_ObjAddFanin( pMux, pNode1 ); - Abc_ObjAddFanin( pMux, pNode0 ); - if ( Abc_NtkHasSop(pNtk) ) - pMux->pData = Abc_SopRegister( pNtk->pManFunc, "11- 1\n0-1 1\n" ); - else if ( Abc_NtkHasBdd(pNtk) ) - pMux->pData = Cudd_bddIte(pNtk->pManFunc,Cudd_bddIthVar(pNtk->pManFunc,0),Cudd_bddIthVar(pNtk->pManFunc,1),Cudd_bddIthVar(pNtk->pManFunc,2)), Cudd_Ref( pMux->pData ); - else if ( Abc_NtkHasAig(pNtk) ) - pMux->pData = Hop_Mux(pNtk->pManFunc,Hop_IthVar(pNtk->pManFunc,0),Hop_IthVar(pNtk->pManFunc,1),Hop_IthVar(pNtk->pManFunc,2)); - else - assert( 0 ); -} - -/**Function************************************************************* - - Synopsis [Converts registers with DC values into additional PIs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkConvertDcLatches( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pCtrl, * pLatch, * pMux, * pPi; - Abc_InitType_t Init = ABC_INIT_ZERO; - int i, fFound = 0, Counter; - // check if there are latches with DC values - Abc_NtkForEachLatch( pNtk, pLatch, i ) - if ( Abc_LatchIsInitDc(pLatch) ) - { - fFound = 1; - break; - } - if ( !fFound ) - return; - // add control latch - pCtrl = Abc_NtkAddLatch( pNtk, Abc_NtkCreateNodeConst1(pNtk), Init ); - // add fanouts for each latch with DC values - Counter = 0; - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - if ( !Abc_LatchIsInitDc(pLatch) ) - continue; - // change latch value - pLatch->pData = (void *)Init; - // if the latch output has the same name as a PO, rename it - if ( Abc_NodeFindCoFanout( Abc_ObjFanout0(pLatch) ) ) - { - Nm_ManDeleteIdName( pLatch->pNtk->pManName, Abc_ObjFanout0(pLatch)->Id ); - Abc_ObjAssignName( Abc_ObjFanout0(pLatch), Abc_ObjName(pLatch), "_lo" ); - } - // create new PIs - pPi = Abc_NtkCreatePi( pNtk ); - Abc_ObjAssignName( pPi, Abc_ObjName(pLatch), "_pi" ); - // create a new node and transfer fanout from latch output to the new node - pMux = Abc_NtkCreateNode( pNtk ); - Abc_ObjTransferFanout( Abc_ObjFanout0(pLatch), pMux ); - // convert the node into a mux - Abc_NtkNodeConvertToMux( pNtk, pCtrl, Abc_ObjFanout0(pLatch), pPi, pMux ); - Counter++; - } - printf( "The number of converted latches with DC values = %d.\n", Counter ); -} //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcLib.c b/src/base/abc/abcLib.c deleted file mode 100644 index feff1478..00000000 --- a/src/base/abc/abcLib.c +++ /dev/null @@ -1,454 +0,0 @@ -/**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->vTops = Vec_PtrAlloc( 100 ); - p->vModules = Vec_PtrAlloc( 100 ); - p->pManFunc = Hop_ManStart(); - p->pLibrary = NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [Frees the library.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_LibFree( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave ) -{ - Abc_Ntk_t * pNtk; - int i; - if ( pLib->pName ) - free( pLib->pName ); - if ( pLib->pManFunc ) - Hop_ManStop( pLib->pManFunc ); - if ( pLib->tModules ) - st_free_table( pLib->tModules ); - if ( pLib->vModules ) - { - Vec_PtrForEachEntry( pLib->vModules, pNtk, i ) - { - if ( pNtk == pNtkSave ) - continue; -// pNtk->pManFunc = NULL; - pNtk->pDesign = NULL; - Abc_NtkDelete( pNtk ); - } - Vec_PtrFree( pLib->vModules ); - } - if ( pLib->vTops ) - Vec_PtrFree( pLib->vTops ); - free( pLib ); -} - -/**Function************************************************************* - - Synopsis [Frees the library.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Lib_t * Abc_LibDupBlackboxes( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave ) -{ - Abc_Lib_t * pLibNew; - Abc_Ntk_t * pNtkTemp; - int i; - assert( Vec_PtrSize(pLib->vTops) > 0 ); - assert( Vec_PtrSize(pLib->vModules) > 1 ); - pLibNew = Abc_LibCreate( pLib->pName ); -// pLibNew->pManFunc = pNtkSave->pManFunc; - Vec_PtrPush( pLibNew->vTops, pNtkSave ); - Vec_PtrPush( pLibNew->vModules, pNtkSave ); - Vec_PtrForEachEntry( pLib->vModules, pNtkTemp, i ) - if ( Abc_NtkHasBlackbox( pNtkTemp ) ) - Vec_PtrPush( pLibNew->vModules, Abc_NtkDup(pNtkTemp) ); - return pLibNew; -} - - -/**Function************************************************************* - - Synopsis [Prints the library.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_LibPrint( Abc_Lib_t * pLib ) -{ - Abc_Ntk_t * pNtk; - Abc_Obj_t * pObj; - int i, k; - printf( "Models of design %s:\n", pLib->pName ); - Vec_PtrForEachEntry( pLib->vModules, pNtk, i ) - { - printf( "%2d : %20s ", i+1, pNtk->pName ); - printf( "nd = %6d lat = %6d whitebox = %3d blackbox = %3d\n", - Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk), - Abc_NtkWhiteboxNum(pNtk), Abc_NtkBlackboxNum(pNtk) ); - if ( Abc_NtkBlackboxNum(pNtk) == 0 ) - continue; - Abc_NtkForEachWhitebox( pNtk, pObj, k ) - printf( " %20s (whitebox)\n", Abc_NtkName(pObj->pData) ); - Abc_NtkForEachBlackbox( pNtk, pObj, k ) - printf( " %20s (blackbox)\n", Abc_NtkName(pObj->pData) ); - } -} - -/**Function************************************************************* - - Synopsis [Create the library.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_LibAddModel( Abc_Lib_t * pLib, Abc_Ntk_t * pNtk ) -{ - if ( st_is_member( pLib->tModules, (char *)pNtk->pName ) ) - return 0; - st_insert( pLib->tModules, (char *)pNtk->pName, (char *)pNtk ); - Vec_PtrPush( pLib->vModules, pNtk ); - pNtk->pDesign = pLib; - return 1; -} - -/**Function************************************************************* - - Synopsis [Create the library.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_LibFindModelByName( Abc_Lib_t * pLib, char * pName ) -{ - Abc_Ntk_t * pNtk; - if ( !st_is_member( pLib->tModules, (char *)pName ) ) - return NULL; - st_lookup( pLib->tModules, (char *)pName, (char **)&pNtk ); - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Frees the library.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib ) -{ - Abc_Ntk_t * pNtk; - if ( Vec_PtrSize(pLib->vModules) > 1 ) - { - printf( "The design includes more than one module and is currently not used.\n" ); - return NULL; - } - pNtk = Vec_PtrEntry( pLib->vModules, 0 ); Vec_PtrClear( pLib->vModules ); - pNtk->pManFunc = pLib->pManFunc; pLib->pManFunc = NULL; - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Detects the top-level models.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_LibFindTopLevelModels( Abc_Lib_t * pLib ) -{ - Abc_Ntk_t * pNtk, * pNtkBox; - Abc_Obj_t * pObj; - int i, k; - assert( Vec_PtrSize( pLib->vModules ) > 0 ); - // clear the models - Vec_PtrForEachEntry( pLib->vModules, pNtk, i ) - pNtk->fHieVisited = 0; - // mark all the models reachable from other models - Vec_PtrForEachEntry( pLib->vModules, pNtk, i ) - { - Abc_NtkForEachBox( pNtk, pObj, k ) - { - if ( Abc_ObjIsLatch(pObj) ) - continue; - if ( pObj->pData == NULL ) - continue; - pNtkBox = pObj->pData; - pNtkBox->fHieVisited = 1; - } - } - // collect the models that are not marked - Vec_PtrClear( pLib->vTops ); - Vec_PtrForEachEntry( pLib->vModules, pNtk, i ) - { - if ( pNtk->fHieVisited == 0 ) - Vec_PtrPush( pLib->vTops, pNtk ); - else - pNtk->fHieVisited = 0; - } - return Vec_PtrSize( pLib->vTops ); -} - - -/**Function************************************************************* - - Synopsis [Surround boxes without content (black boxes) with BIs/BOs.] - - Description [Returns the number of black boxes converted.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_LibDeriveBlackBoxes( Abc_Ntk_t * pNtk, Abc_Lib_t * pLib ) -{ -/* - Abc_Obj_t * pObj, * pFanin, * pFanout; - int i, k; - assert( Abc_NtkIsNetlist(pNtk) ); - // collect blackbox nodes - assert( Vec_PtrSize(pNtk->vBoxes) == 0 ); - Vec_PtrClear( pNtk->vBoxes ); - Abc_NtkForEachBox( pNtk, pObj, i ) - if ( Abc_NtkNodeNum(pObj->pData) == 0 ) - Vec_PtrPush( pNtk->vBoxes, pObj ); - // return if there is no black boxes without content - if ( Vec_PtrSize(pNtk->vBoxes) == 0 ) - return 0; - // print the boxes - printf( "Black boxes are: " ); - Abc_NtkForEachBox( pNtk, pObj, i ) - printf( " %s", ((Abc_Ntk_t *)pObj->pData)->pName ); - printf( "\n" ); - // iterate through the boxes and add BIs/BOs - Abc_NtkForEachBox( pNtk, pObj, i ) - { - // go through the fanin nets - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjInsertBetween( pFanin, pObj, ABC_OBJ_BI ); - // go through the fanout nets - Abc_ObjForEachFanout( pObj, pFanout, k ) - { - Abc_ObjInsertBetween( pObj, pFanout, ABC_OBJ_BO ); - // if the name is not given assign name - if ( pFanout->pData == NULL ) - { - pFanout->pData = Abc_ObjName( pFanout ); - Nm_ManStoreIdName( pNtk->pManName, pFanout->Id, pFanout->pData, NULL ); - } - } - } - return Vec_PtrSize(pNtk->vBoxes); -*/ - return 0; -} - -/**Function************************************************************* - - Synopsis [Derive the AIG of the logic in the netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeStrashUsingNetwork_rec( Abc_Ntk_t * pNtkAig, Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanin; - int i; - assert( !Abc_ObjIsNet(pObj) ); - if ( pObj->pCopy ) - return; - // call for the fanins - Abc_ObjForEachFanin( pObj, pFanin, i ) - Abc_NodeStrashUsingNetwork_rec( pNtkAig, Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)) ); - // compute for the node - pObj->pCopy = Abc_NodeStrash( pNtkAig, pObj, 0 ); - // set for the fanout net - Abc_ObjFanout0(pObj)->pCopy = pObj->pCopy; -} - -/**Function************************************************************* - - Synopsis [Derive the AIG of the logic in the netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeStrashUsingNetwork( Abc_Ntk_t * pNtkAig, Abc_Obj_t * pBox ) -{ - Abc_Ntk_t * pNtkGate; - Abc_Obj_t * pObj; - unsigned * pPolarity; - int i, fCompl; - assert( Abc_ObjIsBox(pBox) ); - pNtkGate = pBox->pData; - pPolarity = (unsigned *)pBox->pNext; - assert( Abc_NtkIsNetlist(pNtkGate) ); - assert( Abc_NtkLatchNum(pNtkGate) == 0 ); - Abc_NtkCleanCopy( pNtkGate ); - // set the PI values - Abc_NtkForEachPi( pNtkGate, pObj, i ) - { - fCompl = (pPolarity && Abc_InfoHasBit(pPolarity, i)); - pObj->pCopy = Abc_ObjNotCond( Abc_ObjFanin(pBox,i)->pCopy, fCompl ); - Abc_ObjFanout0(pObj)->pCopy = pObj->pCopy; - } - // build recursively and set the PO values - Abc_NtkForEachPo( pNtkGate, pObj, i ) - { - Abc_NodeStrashUsingNetwork_rec( pNtkAig, Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)) ); - Abc_ObjFanout(pBox,i)->pCopy = Abc_ObjFanin0(pObj)->pCopy; - } -//printf( "processing %d\n", pBox->Id ); -} - -/**Function************************************************************* - - Synopsis [Derive the AIG of the logic in the netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_LibDeriveAig( Abc_Ntk_t * pNtk, Abc_Lib_t * pLib ) -{ - ProgressBar * pProgress; - Vec_Ptr_t * vNodes; - Abc_Ntk_t * pNtkAig; - Abc_Obj_t * pObj; - int i, nBoxes; - // explicitly derive black boxes - assert( Abc_NtkIsNetlist(pNtk) ); - nBoxes = Abc_LibDeriveBlackBoxes( pNtk, pLib ); - if ( nBoxes ) - printf( "Detected and transformed %d black boxes.\n", nBoxes ); - // create the new network with black boxes in place - pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); - // transer to the nets - Abc_NtkForEachCi( pNtk, pObj, i ) - Abc_ObjFanout0(pObj)->pCopy = pObj->pCopy; - // build the AIG for the remaining logic in the netlist - vNodes = Abc_NtkDfs( pNtk, 0 ); - pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - if ( Abc_ObjIsNode(pObj) ) - { - pObj->pCopy = Abc_NodeStrash( pNtkAig, pObj, 0 ); - Abc_ObjFanout0(pObj)->pCopy = pObj->pCopy; - continue; - } - Abc_NodeStrashUsingNetwork( pNtkAig, pObj ); - } - Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); - // deallocate memory manager, which remembers the phase - if ( pNtk->pData ) - { - Extra_MmFlexStop( pNtk->pData ); - pNtk->pData = NULL; - } - // set the COs -// Abc_NtkFinalize( pNtk, pNtkAig ); - Abc_NtkForEachCo( pNtk, pObj, i ) - Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy ); - Abc_AigCleanup( pNtkAig->pManFunc ); - // make sure that everything is okay - if ( !Abc_NtkCheck( pNtkAig ) ) - { - printf( "Abc_LibDeriveAig: The network check has failed.\n" ); - return 0; - } - return pNtkAig; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c index e1c0f4fd..e143ba7b 100644 --- a/src/base/abc/abcMinBase.c +++ b/src/base/abc/abcMinBase.c @@ -27,7 +27,7 @@ static int Abc_NodeSupport( DdNode * bFunc, Vec_Str_t * vSupport, int nVars ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -65,8 +65,8 @@ int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk ) ***********************************************************************/ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) { - Vec_Str_t * vSupport; - Vec_Ptr_t * vFanins; + Vec_Str_t * vSupport = pNode->pNtk->vStrTemp; + Vec_Ptr_t * vFanins = pNode->pNtk->vPtrTemp; DdNode * bTemp; int i, nVars; @@ -74,16 +74,11 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) assert( Abc_ObjIsNode(pNode) ); // compute support - vSupport = Vec_StrAlloc( 10 ); nVars = Abc_NodeSupport( Cudd_Regular(pNode->pData), vSupport, Abc_ObjFaninNum(pNode) ); if ( nVars == Abc_ObjFaninNum(pNode) ) - { - Vec_StrFree( vSupport ); return 0; - } // remove unused fanins - vFanins = Vec_PtrAlloc( Abc_ObjFaninNum(pNode) ); Abc_NodeCollectFanins( pNode, vFanins ); for ( i = 0; i < vFanins->nSize; i++ ) if ( vSupport->pArray[i] == 0 ) @@ -93,8 +88,6 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) // update the function of the node pNode->pData = Extra_bddRemapUp( pNode->pNtk->pManFunc, bTemp = pNode->pData ); Cudd_Ref( pNode->pData ); Cudd_RecursiveDeref( pNode->pNtk->pManFunc, bTemp ); - Vec_PtrFree( vFanins ); - Vec_StrFree( vSupport ); return 1; } @@ -112,11 +105,12 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; - int i, Counter; + int i, Counter, fChanged; assert( Abc_NtkIsBddLogic(pNtk) ); Counter = 0; Abc_NtkForEachNode( pNtk, pNode, i ) - Counter += Abc_NodeRemoveDupFanins( pNode ); + while ( fChanged = Abc_NodeRemoveDupFanins(pNode) ) + Counter += fChanged; return Counter; } @@ -131,7 +125,7 @@ int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -int Abc_NodeRemoveDupFanins_int( Abc_Obj_t * pNode ) +int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode ) { Abc_Obj_t * pFanin1, * pFanin2; int i, k; @@ -164,24 +158,6 @@ int Abc_NodeRemoveDupFanins_int( Abc_Obj_t * pNode ) /**Function************************************************************* - Synopsis [Removes duplicated fanins if present.] - - Description [Returns the number of fanins removed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode ) -{ - int Counter = 0; - while ( Abc_NodeRemoveDupFanins_int(pNode) ) - Counter++; - return Counter; -} -/**Function************************************************************* - Synopsis [Computes support of the node.] Description [] @@ -249,256 +225,6 @@ int Abc_NodeSupport( DdNode * bFunc, Vec_Str_t * vSupport, int nVars ) return Counter; } - - -/**Function************************************************************* - - Synopsis [Find the number of unique variables after collapsing.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeCheckDupFanin( Abc_Obj_t * pFanin, Abc_Obj_t * pFanout, int * piFanin ) -{ - Abc_Obj_t * pObj; - int i, Counter = 0; - Abc_ObjForEachFanin( pFanout, pObj, i ) - if ( pObj == pFanin ) - { - if ( piFanin ) - *piFanin = i; - Counter++; - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Find the number of unique variables after collapsing.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeCollapseSuppSize( Abc_Obj_t * pFanin, Abc_Obj_t * pFanout, Vec_Ptr_t * vFanins ) -{ - Abc_Obj_t * pObj; - int i; - Vec_PtrClear( vFanins ); - Abc_ObjForEachFanin( pFanout, pObj, i ) - if ( pObj != pFanin ) - Vec_PtrPushUnique( vFanins, pObj ); - Abc_ObjForEachFanin( pFanin, pObj, i ) - Vec_PtrPushUnique( vFanins, pObj ); - return Vec_PtrSize( vFanins ); -} - -/**Function************************************************************* - - Synopsis [Returns the index of the new fanin.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ObjFaninNumberNew( Vec_Ptr_t * vFanins, Abc_Obj_t * pFanin ) -{ - Abc_Obj_t * pObj; - int i; - Vec_PtrForEachEntry( vFanins, pObj, i ) - if ( pObj == pFanin ) - return i; - return -1; -} - -/**Function************************************************************* - - Synopsis [Find the permutation map for the given node into the new order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeCollapsePermMap( Abc_Obj_t * pNode, Abc_Obj_t * pSkip, Vec_Ptr_t * vFanins, int * pPerm ) -{ - Abc_Obj_t * pFanin; - int i; - for ( i = 0; i < Vec_PtrSize(vFanins); i++ ) - pPerm[i] = i; - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - if ( pFanin == pSkip ) - continue; - pPerm[i] = Abc_ObjFaninNumberNew( vFanins, pFanin ); - if ( pPerm[i] == -1 ) - return 0; - } - return 1; -} - - -/**Function************************************************************* - - Synopsis [Computes support of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NodeCollapseFunc( Abc_Obj_t * pFanin, Abc_Obj_t * pFanout, Vec_Ptr_t * vFanins, int * pPermFanin, int * pPermFanout ) -{ - DdManager * dd = pFanin->pNtk->pManFunc; - DdNode * bVar, * bFunc0, * bFunc1, * bTemp, * bFanin, * bFanout; - int RetValue, nSize, iFanin; - // can only eliminate if fanin occurs in the fanin list of the fanout exactly once - if ( Abc_NodeCheckDupFanin( pFanin, pFanout, &iFanin ) != 1 ) - return NULL; - // find the new number of fanins after collapsing - nSize = Abc_NodeCollapseSuppSize( pFanin, pFanout, vFanins ); - bVar = Cudd_bddIthVar( dd, nSize - 1 ); - assert( nSize <= dd->size ); - // find the permutation after collapsing - RetValue = Abc_NodeCollapsePermMap( pFanin, NULL, vFanins, pPermFanin ); - assert( RetValue ); - RetValue = Abc_NodeCollapsePermMap( pFanout, pFanin, vFanins, pPermFanout ); - assert( RetValue ); - // cofactor the local function of the node - bVar = Cudd_bddIthVar( dd, iFanin ); - bFunc0 = Cudd_Cofactor( dd, pFanout->pData, Cudd_Not(bVar) ); Cudd_Ref( bFunc0 ); - bFunc1 = Cudd_Cofactor( dd, pFanout->pData, bVar ); Cudd_Ref( bFunc1 ); - // find the permutation after collapsing - bFunc0 = Cudd_bddPermute( dd, bTemp = bFunc0, pPermFanout ); Cudd_Ref( bFunc0 ); - Cudd_RecursiveDeref( dd, bTemp ); - bFunc1 = Cudd_bddPermute( dd, bTemp = bFunc1, pPermFanout ); Cudd_Ref( bFunc1 ); - Cudd_RecursiveDeref( dd, bTemp ); - bFanin = Cudd_bddPermute( dd, pFanin->pData, pPermFanin ); Cudd_Ref( bFanin ); - // create the new function - bFanout = Cudd_bddIte( dd, bFanin, bFunc1, bFunc0 ); Cudd_Ref( bFanout ); - Cudd_RecursiveDeref( dd, bFanin ); - Cudd_RecursiveDeref( dd, bFunc1 ); - Cudd_RecursiveDeref( dd, bFunc0 ); - Cudd_Deref( bFanout ); - return bFanout; -} - -/**Function************************************************************* - - Synopsis [Collapses one node into its fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeCollapse( Abc_Obj_t * pFanin, Abc_Obj_t * pFanout, Vec_Ptr_t * vFanins, int * pPermFanin, int * pPermFanout ) -{ - Abc_Obj_t * pFanoutNew, * pObj; - DdNode * bFanoutNew; - int i; - assert( Abc_NtkIsBddLogic(pFanin->pNtk) ); - assert( Abc_ObjIsNode(pFanin) ); - assert( Abc_ObjIsNode(pFanout) ); - bFanoutNew = Abc_NodeCollapseFunc( pFanin, pFanout, vFanins, pPermFanin, pPermFanout ); - if ( bFanoutNew == NULL ) - return 0; - Cudd_Ref( bFanoutNew ); - // create the new node - pFanoutNew = Abc_NtkCreateNode( pFanin->pNtk ); - Vec_PtrForEachEntry( vFanins, pObj, i ) - Abc_ObjAddFanin( pFanoutNew, pObj ); - pFanoutNew->pData = bFanoutNew; - // minimize the node - Abc_NodeMinimumBase( pFanoutNew ); - // transfer the fanout - Abc_ObjTransferFanout( pFanout, pFanoutNew ); - assert( Abc_ObjFanoutNum( pFanout ) == 0 ); - Abc_NtkDeleteObj_rec( pFanout, 1 ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Eliminates the nodes into their fanouts if the node size does not exceed this number.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkEliminate( Abc_Ntk_t * pNtk, int nMaxSize, int fReverse, int fVerbose ) -{ - extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose ); - Vec_Ptr_t * vFanouts, * vFanins, * vNodes; - Abc_Obj_t * pNode, * pFanout; - int * pPermFanin, * pPermFanout; - int RetValue, i, k; - assert( nMaxSize > 0 ); - assert( Abc_NtkIsLogic(pNtk) ); - // convert network to BDD representation - if ( !Abc_NtkToBdd(pNtk) ) - { - fprintf( stdout, "Converting to BDD has failed.\n" ); - return 0; - } - // prepare nodes for sweeping - Abc_NtkRemoveDupFanins( pNtk ); - Abc_NtkMinimumBase( pNtk ); - Abc_NtkCleanup( pNtk, 0 ); - // get the nodes in the given order - vNodes = fReverse? Abc_NtkDfsReverse( pNtk ) : Abc_NtkDfs( pNtk, 0 ); - // go through the nodes and decide is they can be eliminated - pPermFanin = ALLOC( int, nMaxSize + 100 ); - pPermFanout = ALLOC( int, nMaxSize + 100 ); - vFanins = Vec_PtrAlloc( 100 ); - vFanouts = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( Abc_NodeFindCoFanout(pNode) != NULL ) - continue; - if ( Abc_ObjFaninNum(pNode) > nMaxSize ) - continue; - Abc_ObjForEachFanout( pNode, pFanout, k ) - if ( Abc_NodeCollapseSuppSize(pNode, pFanout, vFanins) > nMaxSize ) - break; - if ( k < Abc_ObjFanoutNum(pNode) ) - continue; - // perform elimination - Abc_NodeCollectFanouts( pNode, vFanouts ); - Vec_PtrForEachEntry( vFanouts, pFanout, k ) - { - RetValue = Abc_NodeCollapse( pNode, pFanout, vFanins, pPermFanin, pPermFanout ); - assert( RetValue ); - } - } - Abc_NtkBddReorder( pNtk, 0 ); - Vec_PtrFree( vFanins ); - Vec_PtrFree( vFanouts ); - Vec_PtrFree( vNodes ); - free( pPermFanin ); - free( pPermFanout ); - return 1; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcNames.c b/src/base/abc/abcNames.c index 91964dfa..2bf6461b 100644 --- a/src/base/abc/abcNames.c +++ b/src/base/abc/abcNames.c @@ -25,47 +25,95 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Returns the unique name for the object.] + Synopsis [Registers the name with the string memory manager.] - Description [If the name previously did not exist, creates a new unique - name but does not assign this name to the object. The temporary unique - name is stored in a static buffer inside this procedure. It is important - that the name is used before the function is called again!] + Description [This function should be used to register all names + permanentsly stored with the network. The pointer returned by + this procedure contains the copy of the name, which should be used + in all network manipulation procedures.] SideEffects [] SeeAlso [] ***********************************************************************/ -char * Abc_ObjName( Abc_Obj_t * pObj ) +char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName ) { - return Nm_ManCreateUniqueName( pObj->pNtk->pManName, pObj->Id ); + char * pRegName; + if ( pName == NULL ) return NULL; + pRegName = Extra_MmFlexEntryFetch( pNtk->pMmNames, strlen(pName) + 1 ); + strcpy( pRegName, pName ); + return pRegName; } /**Function************************************************************* - Synopsis [Assigns the given name to the object.] + Synopsis [Registers the name with the string memory manager.] - Description [The object should not have a name assigned. The same - name may be used for several objects, which they share the same net - in the original netlist. (For example, latch output and primary output - may have the same name.) This procedure returns the pointer to the - internally stored representation of the given name.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -char * Abc_ObjAssignName( Abc_Obj_t * pObj, char * pName, char * pSuffix ) +char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix ) { - assert( pName != NULL ); - return Nm_ManStoreIdName( pObj->pNtk->pManName, pObj->Id, pObj->Type, pName, pSuffix ); + char * pRegName; + assert( pName && pSuffix ); + pRegName = Extra_MmFlexEntryFetch( pNtk->pMmNames, strlen(pName) + strlen(pSuffix) + 1 ); + sprintf( pRegName, "%s%s", pName, pSuffix ); + return pRegName; +} + +/**Function************************************************************* + + Synopsis [Gets the long name of the object.] + + Description [The temporary name is stored in a static buffer inside this + procedure. It is important that the name is used before the function is + called again!] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Abc_ObjName( Abc_Obj_t * pObj ) +{ + static char Buffer[500]; + char * pName; + + // check if the object is in the lookup table + if ( stmm_lookup( pObj->pNtk->tObj2Name, (char *)pObj, &pName ) ) + return pName; + + // consider network types + if ( Abc_NtkIsNetlist(pObj->pNtk) ) + { + // in a netlist, nets have names, nodes have no names + if ( Abc_ObjIsNode(pObj) ) + pObj = Abc_ObjFanout0(pObj); + assert( Abc_ObjIsNet(pObj) ); + // if the name is not given, invent it + if ( pObj->pData ) + sprintf( Buffer, "%s", pObj->pData ); + else + sprintf( Buffer, "[%d]", pObj->Id ); // make sure this name is unique!!! + } + else + { + // in a logic network, PI/PO/latch names are stored in the hash table + // internal nodes have made up names + assert( Abc_ObjIsNode(pObj) || Abc_ObjIsLatch(pObj) ); + sprintf( Buffer, "[%d]", pObj->Id ); + } + return Buffer; } /**Function************************************************************* @@ -88,7 +136,62 @@ char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix ) /**Function************************************************************* - Synopsis [Returns the dummy PI name.] + Synopsis [Finds a unique name for the node.] + + Description [If the name exists, tries appending numbers to it until + it becomes unique.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Abc_ObjNameUnique( Abc_Ntk_t * pNtk, char * pName ) +{ + static char Buffer[1000]; + int Counter; + assert( 0 ); + if ( !stmm_is_member( pNtk->tName2Net, pName ) ) + return pName; + for ( Counter = 1; ; Counter++ ) + { + sprintf( Buffer, "%s_%d", pName, Counter ); + if ( !stmm_is_member( pNtk->tName2Net, Buffer ) ) + return Buffer; + } + return NULL; +} + + +/**Function************************************************************* + + Synopsis [Adds new name to the network.] + + Description [The new object (pObjNew) is a PI, PO or latch. The name + is registered and added to the hash table.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Abc_NtkLogicStoreName( Abc_Obj_t * pObjNew, char * pNameOld ) +{ + char * pNewName; + assert( Abc_ObjIsCio(pObjNew) ); + // get the new name + pNewName = Abc_NtkRegisterName( pObjNew->pNtk, pNameOld ); + // add the name to the table + if ( stmm_insert( pObjNew->pNtk->tObj2Name, (char *)pObjNew, pNewName ) ) + { + assert( 0 ); // the object is added for the second time + } + return pNewName; +} + +/**Function************************************************************* + + Synopsis [Adds new name to the network.] Description [] @@ -97,73 +200,73 @@ char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix ) SeeAlso [] ***********************************************************************/ -char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits ) +char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pObjNew, char * pNameOld, char * pSuffix ) { - static char Buffer[100]; - sprintf( Buffer, "%s%0*d", pPrefix, nDigits, Num ); - return Buffer; + char * pNewName; + assert( pSuffix ); + assert( Abc_ObjIsCio(pObjNew) ); + // get the new name + pNewName = Abc_NtkRegisterNamePlus( pObjNew->pNtk, pNameOld, pSuffix ); + // add the name to the table + if ( stmm_insert( pObjNew->pNtk->tObj2Name, (char *)pObjNew, pNewName ) ) + { + assert( 0 ); // the object is added for the second time + } + return pNewName; } /**Function************************************************************* - Synopsis [Tranfers names to the old network.] + Synopsis [Creates the name arrays from the old network.] - Description [Assumes that the new nodes are attached using pObj->pCopy.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -void Abc_NtkTrasferNames( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +void Abc_NtkCreateCioNamesTable( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; int i; - assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) ); - assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) ); - assert( Abc_NtkBoxNum(pNtk) == Abc_NtkBoxNum(pNtkNew) ); - assert( Abc_NtkAssertNum(pNtk) == Abc_NtkAssertNum(pNtkNew) ); - assert( Nm_ManNumEntries(pNtk->pManName) > 0 ); - assert( Nm_ManNumEntries(pNtkNew->pManName) == 0 ); - // copy the CI/CO/box names - Abc_NtkForEachCi( pNtk, pObj, i ) - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(Abc_ObjFanout0Ntk(pObj)), NULL ); - Abc_NtkForEachCo( pNtk, pObj, i ) - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(Abc_ObjFanin0Ntk(pObj)), NULL ); - Abc_NtkForEachBox( pNtk, pObj, i ) - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL ); + assert( Abc_NtkIsNetlist(pNtk) ); + assert( st_count(pNtk->tObj2Name) == 0 ); + Abc_NtkForEachPi( pNtk, pObj, i ) + Abc_NtkLogicStoreName( pObj, Abc_ObjFanout0(pObj)->pData ); + Abc_NtkForEachPo( pNtk, pObj, i ) + Abc_NtkLogicStoreName( pObj, Abc_ObjFanin0(pObj)->pData ); + Abc_NtkForEachLatch( pNtk, pObj, i ) + Abc_NtkLogicStoreName( pObj, Abc_ObjFanout0(pObj)->pData ); } /**Function************************************************************* - Synopsis [Tranfers names to the old network.] + Synopsis [Duplicates the name arrays.] - Description [Assumes that the new nodes are attached using pObj->pCopy.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -void Abc_NtkTrasferNamesNoLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) { Abc_Obj_t * pObj; int i; assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) ); assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) ); - assert( Abc_NtkAssertNum(pNtk) == Abc_NtkAssertNum(pNtkNew) ); - assert( Nm_ManNumEntries(pNtk->pManName) > 0 ); - assert( Nm_ManNumEntries(pNtkNew->pManName) == 0 ); - // copy the CI/CO/box name and skip latches and theirs inputs/outputs - Abc_NtkForEachCi( pNtk, pObj, i ) - if ( Abc_ObjFaninNum(pObj) == 0 || !Abc_ObjIsLatch(Abc_ObjFanin0(pObj)) ) - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(Abc_ObjFanout0Ntk(pObj)), NULL ); - Abc_NtkForEachCo( pNtk, pObj, i ) - if ( Abc_ObjFanoutNum(pObj) == 0 || !Abc_ObjIsLatch(Abc_ObjFanout0(pObj)) ) - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(Abc_ObjFanin0Ntk(pObj)), NULL ); - Abc_NtkForEachBox( pNtk, pObj, i ) - if ( !Abc_ObjIsLatch(pObj) ) - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL ); + assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) ); + assert( st_count(pNtk->tObj2Name) > 0 ); + assert( st_count(pNtkNew->tObj2Name) == 0 ); + // copy the CI/CO names if given + Abc_NtkForEachPi( pNtk, pObj, i ) + Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pObj) ); + Abc_NtkForEachPo( pNtk, pObj, i ) + Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pObj) ); + Abc_NtkForEachLatch( pNtk, pObj, i ) + Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(pObj) ); } /**Function************************************************************* @@ -184,7 +287,7 @@ Vec_Ptr_t * Abc_NodeGetFaninNames( Abc_Obj_t * pNode ) int i; vNodes = Vec_PtrAlloc( 100 ); Abc_ObjForEachFanin( pNode, pFanin, i ) - Vec_PtrPush( vNodes, Extra_UtilStrsav(Abc_ObjName(pFanin)) ); + Vec_PtrPush( vNodes, util_strsav(Abc_ObjName(pFanin)) ); return vNodes; } @@ -219,7 +322,7 @@ Vec_Ptr_t * Abc_NodeGetFakeNames( int nNames ) Buffer[1] = '0' + i/26; Buffer[2] = 0; } - Vec_PtrPush( vNames, Extra_UtilStrsav(Buffer) ); + Vec_PtrPush( vNames, util_strsav(Buffer) ); } return vNames; } @@ -312,38 +415,42 @@ void Abc_NtkOrderObjsByName( Abc_Ntk_t * pNtk, int fComb ) { Abc_Obj_t * pObj; int i; - assert( Abc_NtkAssertNum(pNtk) == 0 ); - assert( Abc_NtkHasOnlyLatchBoxes(pNtk) ); // temporarily store the names in the copy field Abc_NtkForEachPi( pNtk, pObj, i ) pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj); Abc_NtkForEachPo( pNtk, pObj, i ) pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj); - Abc_NtkForEachBox( pNtk, pObj, i ) - pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(Abc_ObjFanout0(pObj)); + Abc_NtkForEachLatch( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj); // order objects alphabetically - qsort( (void *)Vec_PtrArray(pNtk->vPis), Vec_PtrSize(pNtk->vPis), sizeof(Abc_Obj_t *), + qsort( pNtk->vCis->pArray, pNtk->nPis, sizeof(Abc_Obj_t *), (int (*)(const void *, const void *)) Abc_NodeCompareNames ); - qsort( (void *)Vec_PtrArray(pNtk->vPos), Vec_PtrSize(pNtk->vPos), sizeof(Abc_Obj_t *), + qsort( pNtk->vCos->pArray, pNtk->nPos, sizeof(Abc_Obj_t *), (int (*)(const void *, const void *)) Abc_NodeCompareNames ); // if the comparison if combinational (latches as PIs/POs), order them too if ( fComb ) - qsort( (void *)Vec_PtrArray(pNtk->vBoxes), Vec_PtrSize(pNtk->vBoxes), sizeof(Abc_Obj_t *), + { + qsort( pNtk->vLats->pArray, pNtk->nLatches, sizeof(Abc_Obj_t *), (int (*)(const void *, const void *)) Abc_NodeCompareNames ); - // order CIs/COs first PIs/POs(Asserts) then latches - Abc_NtkOrderCisCos( pNtk ); + // add latches to make COs + Abc_NtkForEachLatch( pNtk, pObj, i ) + { + Vec_PtrWriteEntry( pNtk->vCis, pNtk->nPis + i, pObj ); + Vec_PtrWriteEntry( pNtk->vCos, pNtk->nPos + i, pObj ); + } + } // clean the copy fields Abc_NtkForEachPi( pNtk, pObj, i ) pObj->pCopy = NULL; Abc_NtkForEachPo( pNtk, pObj, i ) pObj->pCopy = NULL; - Abc_NtkForEachBox( pNtk, pObj, i ) + Abc_NtkForEachLatch( pNtk, pObj, i ) pObj->pCopy = NULL; } /**Function************************************************************* - Synopsis [Adds dummy names.] + Synopsis [] Description [] @@ -352,112 +459,41 @@ void Abc_NtkOrderObjsByName( Abc_Ntk_t * pNtk, int fComb ) SeeAlso [] ***********************************************************************/ -void Abc_NtkAddDummyPiNames( Abc_Ntk_t * pNtk ) +void Abc_NtkShortNames( Abc_Ntk_t * pNtk ) { + stmm_table * tObj2NameNew; Abc_Obj_t * pObj; - int nDigits, i; - nDigits = Extra_Base10Log( Abc_NtkPiNum(pNtk) ); - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_ObjAssignName( pObj, Abc_ObjNameDummy("pi", i, nDigits), NULL ); -} - -/**Function************************************************************* - - Synopsis [Adds dummy names.] - - Description [] - - SideEffects [] - - SeeAlso [] + char Buffer[100]; + char * pNameNew; + int Length, i; -***********************************************************************/ -void Abc_NtkAddDummyPoNames( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int nDigits, i; - nDigits = Extra_Base10Log( Abc_NtkPoNum(pNtk) ); + tObj2NameNew = stmm_init_table(stmm_ptrcmp, stmm_ptrhash); + // create new names and add them to the table + Length = Extra_Base10Log( Abc_NtkPiNum(pNtk) ); + Abc_NtkForEachPi( pNtk, pObj, i ) + { + sprintf( Buffer, "pi%0*d", Length, i ); + pNameNew = Abc_NtkRegisterName( pNtk, Buffer ); + stmm_insert( tObj2NameNew, (char *)pObj, pNameNew ); + } + // create new names and add them to the table + Length = Extra_Base10Log( Abc_NtkPoNum(pNtk) ); Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_ObjAssignName( pObj, Abc_ObjNameDummy("po", i, nDigits), NULL ); -} - -/**Function************************************************************* - - Synopsis [Adds dummy names.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkAddDummyAssertNames( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int nDigits, i; - nDigits = Extra_Base10Log( Abc_NtkAssertNum(pNtk) ); - Abc_NtkForEachAssert( pNtk, pObj, i ) - Abc_ObjAssignName( pObj, Abc_ObjNameDummy("a", i, nDigits), NULL ); -} - -/**Function************************************************************* - - Synopsis [Adds dummy names.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkAddDummyBoxNames( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int nDigits, i; - assert( !Abc_NtkIsNetlist(pNtk) ); - nDigits = Extra_Base10Log( Abc_NtkLatchNum(pNtk) ); - Abc_NtkForEachLatch( pNtk, pObj, i ) { - Abc_ObjAssignName( pObj, Abc_ObjNameDummy("l", i, nDigits), NULL ); - Abc_ObjAssignName( Abc_ObjFanin0(pObj), Abc_ObjNameDummy("li", i, nDigits), NULL ); - Abc_ObjAssignName( Abc_ObjFanout0(pObj), Abc_ObjNameDummy("lo", i, nDigits), NULL ); + sprintf( Buffer, "po%0*d", Length, i ); + pNameNew = Abc_NtkRegisterName( pNtk, Buffer ); + stmm_insert( tObj2NameNew, (char *)pObj, pNameNew ); } -/* - nDigits = Extra_Base10Log( Abc_NtkBlackboxNum(pNtk) ); - Abc_NtkForEachBlackbox( pNtk, pObj, i ) + // create new names and add them to the table + Length = Extra_Base10Log( Abc_NtkLatchNum(pNtk) ); + Abc_NtkForEachLatch( pNtk, pObj, i ) { - pName = Abc_ObjAssignName( pObj, Abc_ObjNameDummy("B", i, nDigits), NULL ); - nDigitsF = Extra_Base10Log( Abc_ObjFaninNum(pObj) ); - Abc_ObjForEachFanin( pObj, pTerm, k ) - Abc_ObjAssignName( Abc_ObjFanin0(pObj), pName, Abc_ObjNameDummy("i", k, nDigitsF) ); - nDigitsF = Extra_Base10Log( Abc_ObjFanoutNum(pObj) ); - Abc_ObjForEachFanout( pObj, pTerm, k ) - Abc_ObjAssignName( Abc_ObjFanin0(pObj), pName, Abc_ObjNameDummy("o", k, nDigitsF) ); + sprintf( Buffer, "lat%0*d", Length, i ); + pNameNew = Abc_NtkRegisterName( pNtk, Buffer ); + stmm_insert( tObj2NameNew, (char *)pObj, pNameNew ); } -*/ -} - -/**Function************************************************************* - - Synopsis [Replaces names by short names.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkShortNames( Abc_Ntk_t * pNtk ) -{ - Nm_ManFree( pNtk->pManName ); - pNtk->pManName = Nm_ManCreate( Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk) + Abc_NtkBoxNum(pNtk) ); - Abc_NtkAddDummyPiNames( pNtk ); - Abc_NtkAddDummyPoNames( pNtk ); - Abc_NtkAddDummyAssertNames( pNtk ); - Abc_NtkAddDummyBoxNames( pNtk ); + stmm_free_table( pNtk->tObj2Name ); + pNtk->tObj2Name = tObj2NameNew; } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c index 26b88c68..08ee93bb 100644 --- a/src/base/abc/abcNetlist.c +++ b/src/base/abc/abcNetlist.c @@ -19,19 +19,13 @@ ***********************************************************************/ #include "abc.h" -//#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// - -static void Abc_NtkAddPoBuffers( Abc_Ntk_t * pNtk ); -static Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ); -static Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk ); -static Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk ); - + //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -45,37 +39,33 @@ static Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk ); SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk ) +Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; Abc_Obj_t * pObj, * pFanin; int i, k; - // consider the case of the AIG - if ( Abc_NtkIsStrash(pNtk) ) - return Abc_NtkAigToLogicSop( pNtk ); assert( Abc_NtkIsNetlist(pNtk) ); - // consider simple case when there is hierarchy -// assert( pNtk->pDesign == NULL ); - assert( Abc_NtkWhiteboxNum(pNtk) == 0 ); - assert( Abc_NtkBlackboxNum(pNtk) == 0 ); // start the network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, pNtk->ntkFunc ); + if ( !Abc_NtkHasMapping(pNtk) ) + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP ); + else + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_MAP ); // duplicate the nodes Abc_NtkForEachNode( pNtk, pObj, i ) - Abc_NtkDupObj(pNtkNew, pObj, 0); + Abc_NtkDupObj(pNtkNew, pObj); // reconnect the internal nodes in the new network Abc_NtkForEachNode( pNtk, pObj, i ) Abc_ObjForEachFanin( pObj, pFanin, k ) Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pFanin)->pCopy ); // collect the CO nodes Abc_NtkFinalize( pNtk, pNtkNew ); - // fix the problem with CO pointing directly to CIs + // fix the problem with CO pointing directing to CIs Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); // duplicate EXDC if ( pNtk->pExdc ) - pNtkNew->pExdc = Abc_NtkToLogic( pNtk->pExdc ); + pNtkNew->pExdc = Abc_NtkNetlistToLogic( pNtk->pExdc ); if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkToLogic(): Network check has failed.\n" ); + fprintf( stdout, "Abc_NtkNetlistToLogic(): Network check has failed.\n" ); return pNtkNew; } @@ -90,18 +80,31 @@ Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk ) +Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew, * pNtkTemp; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) ); + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) ); if ( Abc_NtkIsStrash(pNtk) ) { pNtkTemp = Abc_NtkAigToLogicSop(pNtk); - pNtkNew = Abc_NtkLogicToNetlist( pNtkTemp ); + pNtkNew = Abc_NtkLogicSopToNetlist( pNtkTemp ); + Abc_NtkDelete( pNtkTemp ); + } + else if ( Abc_NtkIsSeq(pNtk) ) + { + pNtkTemp = Abc_NtkSeqToLogicSop(pNtk); + pNtkNew = Abc_NtkLogicSopToNetlist( pNtkTemp ); Abc_NtkDelete( pNtkTemp ); - return pNtkNew; } - return Abc_NtkLogicToNetlist( pNtk ); + else if ( Abc_NtkIsBddLogic(pNtk) ) + { + Abc_NtkBddToSop(pNtk); + pNtkNew = Abc_NtkLogicSopToNetlist( pNtk ); + Abc_NtkSopToBdd(pNtk); + } + else + pNtkNew = Abc_NtkLogicSopToNetlist( pNtk ); + return pNtkNew; } /**Function************************************************************* @@ -115,12 +118,12 @@ Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk ) +Abc_Ntk_t * Abc_NtkLogicToNetlistBench( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew, * pNtkTemp; assert( Abc_NtkIsStrash(pNtk) ); pNtkTemp = Abc_NtkAigToLogicSopBench( pNtk ); - pNtkNew = Abc_NtkLogicToNetlist( pNtkTemp ); + pNtkNew = Abc_NtkLogicSopToNetlist( pNtkTemp ); Abc_NtkDelete( pNtkTemp ); return pNtkNew; } @@ -140,31 +143,24 @@ Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) +Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; Abc_Obj_t * pObj, * pNet, * pDriver, * pFanin; + char * pNameCo; int i, k; assert( Abc_NtkIsLogic(pNtk) ); + assert( Abc_NtkLogicHasSimpleCos(pNtk) ); - // remove dangling nodes - Abc_NtkCleanup( pNtk, 0 ); - - // make sure the CO names are unique - Abc_NtkCheckUniqueCiNames( pNtk ); - Abc_NtkCheckUniqueCoNames( pNtk ); - Abc_NtkCheckUniqueCioNames( pNtk ); - -// assert( Abc_NtkLogicHasSimpleCos(pNtk) ); - if ( !Abc_NtkLogicHasSimpleCos(pNtk) ) - { - printf( "Abc_NtkLogicToNetlist() warning: The network is converted to have simple COs.\n" ); - Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); - } + if ( Abc_NtkIsBddLogic(pNtk) ) + Abc_NtkBddToSop(pNtk); // start the netlist by creating PI/PO/Latch objects - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, pNtk->ntkFunc ); + if ( Abc_NtkIsSopLogic(pNtk) ) + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_NETLIST, ABC_FUNC_SOP ); + else + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_NETLIST, ABC_FUNC_BDD ); // create the CI nets and remember them in the new CI nodes Abc_NtkForEachCi( pNtk, pObj, i ) { @@ -174,7 +170,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) } // duplicate all nodes Abc_NtkForEachNode( pNtk, pObj, i ) - Abc_NtkDupObj(pNtkNew, pObj, 0); + Abc_NtkDupObj(pNtkNew, pObj); // first add the nets to the CO drivers Abc_NtkForEachCo( pNtk, pObj, i ) { @@ -186,21 +182,18 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) continue; } assert( Abc_ObjIsNode(pDriver) ); - // if the CO driver has no net, create it - if ( pDriver->pCopy->pCopy == NULL ) - { - // create the CO net and connect it to CO - pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) ); - Abc_ObjAddFanin( pObj->pCopy, pNet ); - // connect the CO net to the new driver and remember it in the new driver - Abc_ObjAddFanin( pNet, pDriver->pCopy ); - pDriver->pCopy->pCopy = pNet; - } - else - { - assert( !strcmp( Abc_ObjName(pDriver->pCopy->pCopy), Abc_ObjName(pObj) ) ); - Abc_ObjAddFanin( pObj->pCopy, pDriver->pCopy->pCopy ); - } + // the driver is a node + + // get the CO name + pNameCo = Abc_ObjIsPo(pObj)? Abc_ObjName(pObj) : Abc_ObjNameSuffix( pObj, "_in" ); + // make sure CO has a unique name + assert( Abc_NtkFindNet( pNtkNew, pNameCo ) == NULL ); + // create the CO net and connect it to CO + pNet = Abc_NtkFindOrCreateNet( pNtkNew, pNameCo ); + Abc_ObjAddFanin( pObj->pCopy, pNet ); + // connect the CO net to the new driver and remember it in the new driver + Abc_ObjAddFanin( pNet, pDriver->pCopy ); + pDriver->pCopy->pCopy = pNet; } // create the missing nets Abc_NtkForEachNode( pNtk, pObj, i ) @@ -208,7 +201,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) if ( pObj->pCopy->pCopy ) // the net of the new object is already created continue; // create the new net - pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) ); // here we create ridiculous names net line "n48", where 48 is the ID of the node + pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) ); Abc_ObjAddFanin( pNet, pObj->pCopy ); pObj->pCopy->pCopy = pNet; } @@ -218,9 +211,9 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy ); // duplicate EXDC if ( pNtk->pExdc ) - pNtkNew->pExdc = Abc_NtkToNetlist( pNtk->pExdc ); + pNtkNew->pExdc = Abc_NtkLogicToNetlist( pNtk->pExdc ); if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkLogicToNetlist(): Network check has failed.\n" ); + fprintf( stdout, "Abc_NtkLogicSopToNetlist(): Network check has failed.\n" ); return pNtkNew; } @@ -239,40 +232,40 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; Abc_Obj_t * pObj, * pFanin, * pNodeNew; - Vec_Int_t * vInts; int i, k; 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_NtkCreateNodeConst1(pNtkNew); + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP ); + // create the constant node + Abc_NtkDupConst1( pNtk, pNtkNew ); // duplicate the nodes and create node functions Abc_NtkForEachNode( pNtk, pObj, i ) { - Abc_NtkDupObj(pNtkNew, pObj, 0); + 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_AigNodeIsChoice(pObj) ) + if ( Abc_NodeIsConst(pObj) ) + continue; + if ( !Abc_NodeIsAigChoice(pObj) ) continue; // create an OR gate pNodeNew = Abc_NtkCreateNode(pNtkNew); // add fanins - vInts = Vec_IntAlloc( 10 ); + Vec_IntClear( pNtk->vIntTemp ); for ( pFanin = pObj; pFanin; pFanin = pFanin->pData ) { - Vec_IntPush( vInts, (int)(pObj->fPhase != pFanin->fPhase) ); + Vec_IntPush( pNtk->vIntTemp, (int)(pObj->fPhase != pFanin->fPhase) ); Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); } // create the logic function - pNodeNew->pData = Abc_SopCreateOrMultiCube( pNtkNew->pManFunc, Vec_IntSize(vInts), Vec_IntArray(vInts) ); + pNodeNew->pData = Abc_SopCreateOrMultiCube( pNtkNew->pManFunc, pNtk->vIntTemp->nSize, pNtk->vIntTemp->pArray ); // set the new node pObj->pCopy->pCopy = pNodeNew; - Vec_IntFree( vInts ); } // connect the internal nodes Abc_NtkForEachNode( pNtk, pObj, i ) @@ -282,17 +275,7 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk ) else Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); // connect the COs -// Abc_NtkFinalize( pNtk, pNtkNew ); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pFanin = Abc_ObjFanin0(pObj); - if ( pFanin->pCopy->pCopy ) - pNodeNew = Abc_ObjNotCond(pFanin->pCopy->pCopy, Abc_ObjFaninC0(pObj)); - else - pNodeNew = Abc_ObjNotCond(pFanin->pCopy, Abc_ObjFaninC0(pObj)); - Abc_ObjAddFanin( pObj->pCopy, pNodeNew ); - } - + Abc_NtkFinalize( pNtk, pNtkNew ); // fix the problem with complemented and duplicated CO edges Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); // duplicate the EXDC Ntk @@ -329,26 +312,25 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk ) if ( Abc_NtkGetChoiceNum(pNtk) ) printf( "Warning: Choice nodes are skipped.\n" ); // start the network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP ); + // create the constant node + Abc_NtkDupConst1( pNtk, pNtkNew ); // 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_NtkCreateNodeConst1(pNtkNew); - pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy ); - } Abc_NtkForEachCi( pNtk, pObj, i ) if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) ) - pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy ); + pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy ); // duplicate the nodes, create node functions, and inverters Vec_PtrForEachEntry( vNodes, pObj, i ) { - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2, NULL ); + if ( !Abc_NodeIsConst(pObj) ) + { + Abc_NtkDupObj( pNtkNew, pObj ); + pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2 ); + } if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) ) - pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy ); + pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy ); } // connect the objects Vec_PtrForEachEntry( vNodes, pObj, i ) @@ -379,31 +361,6 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk ) return pNtkNew; } -/**Function************************************************************* - - Synopsis [Adds buffers for each PO.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkAddPoBuffers( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj, * pFanin, * pFaninNew; - int i; - assert( Abc_NtkIsStrash(pNtk) ); - Abc_NtkForEachPo( pNtk, pObj, i ) - { - pFanin = Abc_ObjChild0(pObj); - pFaninNew = Abc_NtkCreateNode(pNtk); - Abc_ObjAddFanin( pFaninNew, pFanin ); - Abc_ObjPatchFanin( pObj, pFanin, pFaninNew ); - } -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index d78a3a6a..5c199141 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -19,7 +19,6 @@ ***********************************************************************/ #include "abc.h" -#include "abcInt.h" #include "main.h" #include "mio.h" @@ -27,8 +26,10 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#define ABC_NUM_STEPS 10 + //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -42,7 +43,7 @@ SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan ) +Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ) { Abc_Ntk_t * pNtk; pNtk = ALLOC( Abc_Ntk_t, 1 ); @@ -51,35 +52,32 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan pNtk->ntkFunc = Func; // start the object storage pNtk->vObjs = Vec_PtrAlloc( 100 ); - pNtk->vAsserts = Vec_PtrAlloc( 100 ); - pNtk->vPios = Vec_PtrAlloc( 100 ); - pNtk->vPis = Vec_PtrAlloc( 100 ); - pNtk->vPos = Vec_PtrAlloc( 100 ); + pNtk->vLats = Vec_PtrAlloc( 100 ); pNtk->vCis = Vec_PtrAlloc( 100 ); pNtk->vCos = Vec_PtrAlloc( 100 ); - pNtk->vBoxes = Vec_PtrAlloc( 100 ); + pNtk->vPtrTemp = Vec_PtrAlloc( 100 ); + pNtk->vIntTemp = Vec_IntAlloc( 100 ); + pNtk->vStrTemp = Vec_StrAlloc( 100 ); + // start the hash table + pNtk->tName2Net = stmm_init_table(strcmp, stmm_strhash); + pNtk->tObj2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash); // start the memory managers - pNtk->pMmObj = fUseMemMan? Extra_MmFixedStart( sizeof(Abc_Obj_t) ) : NULL; - pNtk->pMmStep = fUseMemMan? Extra_MmStepStart( ABC_NUM_STEPS ) : NULL; + pNtk->pMmNames = Extra_MmFlexStart(); + 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_NtkIsStrash(pNtk) ) - pNtk->pManFunc = Abc_AigAlloc( pNtk ); - else if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) ) + 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) ) - pNtk->pManFunc = Hop_ManStart(); + pNtk->pManFunc = Abc_AigAlloc( pNtk ); else if ( Abc_NtkHasMapping(pNtk) ) - pNtk->pManFunc = Abc_FrameReadLibGen(); - else if ( !Abc_NtkHasBlackbox(pNtk) ) + pNtk->pManFunc = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()); + else assert( 0 ); - // name manager - pNtk->pManName = Nm_ManCreate( 200 ); - // attribute manager - pNtk->vAttrs = Vec_PtrStart( VEC_ATTR_TOTAL_NUM ); return pNtk; } @@ -97,44 +95,38 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ) { Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj; - int fCopyNames, i; + Abc_Obj_t * pObj, * pObjNew; + int i; if ( pNtk == NULL ) return NULL; - // decide whether to copy the names - fCopyNames = ( Type != ABC_NTK_NETLIST ); // start the network - pNtkNew = Abc_NtkAlloc( Type, Func, 1 ); + pNtkNew = Abc_NtkAlloc( Type, Func ); // duplicate the name and the spec - pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); - pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); - // clean the node copy fields - Abc_NtkCleanCopy( pNtk ); - // map the constant nodes - if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) - Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); - // clone CIs/CIs/boxes + pNtkNew->pName = util_strsav(pNtk->pName); + pNtkNew->pSpec = util_strsav(pNtk->pSpec); + // clone the PIs/POs/latches Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); + Abc_NtkDupObj(pNtkNew, pObj); Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); - Abc_NtkForEachAssert( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); - Abc_NtkForEachBox( pNtk, pObj, i ) - Abc_NtkDupBox( pNtkNew, pObj, fCopyNames ); + Abc_NtkDupObj(pNtkNew, pObj); + Abc_NtkForEachLatch( pNtk, pObj, i ) + { + pObjNew = Abc_NtkDupObj(pNtkNew, pObj); + Vec_PtrPush( pNtkNew->vCis, pObjNew ); + Vec_PtrPush( pNtkNew->vCos, pObjNew ); + } + // clean the node copy fields + Abc_NtkForEachNode( pNtk, pObj, i ) + pObj->pCopy = NULL; // transfer the names -// Abc_NtkTrasferNames( pNtk, pNtkNew ); + Abc_NtkDupCioNamesTable( pNtk, pNtkNew ); Abc_ManTimeDup( pNtk, pNtkNew ); - // check that the CI/CO/latches are copied correctly - assert( Abc_NtkCiNum(pNtk) == Abc_NtkCiNum(pNtkNew) ); - assert( Abc_NtkCoNum(pNtk) == Abc_NtkCoNum(pNtkNew) ); - assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) ); return pNtkNew; } /**Function************************************************************* - Synopsis [Starts a new network using existing network as a model.] + Synopsis [Finalizes the network using the existing network as a model.] Description [] @@ -143,44 +135,17 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_ SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ) +void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) { - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj; + Abc_Obj_t * pObj, * pDriver, * pDriverNew; int i; - if ( pNtk == NULL ) - return NULL; - assert( Type != ABC_NTK_NETLIST ); - // start the network - pNtkNew = Abc_NtkAlloc( Type, Func, 1 ); - // duplicate the name and the spec - pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); - pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); - // clean the node copy fields - Abc_NtkCleanCopy( pNtk ); - // map the constant nodes - if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) - Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); - // clone CIs/CIs/boxes - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 1 ); - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 1 ); - Abc_NtkForEachAssert( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 1 ); - Abc_NtkForEachBox( pNtk, pObj, i ) + // set the COs of the strashed network + Abc_NtkForEachCo( pNtk, pObj, i ) { - if ( Abc_ObjIsLatch(pObj) ) - continue; - Abc_NtkDupBox(pNtkNew, pObj, 1); + pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) ); + pDriverNew = Abc_ObjNotCond(pDriver->pCopy, Abc_ObjFaninC0(pObj)); + Abc_ObjAddFanin( pObj->pCopy, pDriverNew ); } - // transfer the names -// Abc_NtkTrasferNamesNoLatches( pNtk, pNtkNew ); - Abc_ManTimeDup( pNtk, pNtkNew ); - // check that the CI/CO/latches are copied correctly - assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) ); - assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) ); - return pNtkNew; } /**Function************************************************************* @@ -194,7 +159,7 @@ Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc SeeAlso [] ***********************************************************************/ -void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) { Abc_Obj_t * pObj, * pDriver, * pDriverNew; int i; @@ -202,13 +167,37 @@ void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) Abc_NtkForEachCo( pNtk, pObj, i ) { pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) ); - pDriverNew = Abc_ObjNotCond(pDriver->pCopy, Abc_ObjFaninC0(pObj)); + pDriverNew = pDriver->pCopy; Abc_ObjAddFanin( pObj->pCopy, pDriverNew ); } } /**Function************************************************************* + Synopsis [Finalizes the network adding latches to CI/CO lists and creates their names.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pLatch; + int i; + // set the COs of the strashed network + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + Vec_PtrPush( pNtk->vCis, pLatch ); + Vec_PtrPush( pNtk->vCos, pLatch ); + Abc_NtkLogicStoreName( pLatch, Abc_ObjNameSuffix(pLatch, "L") ); + } +} + +/**Function************************************************************* + Synopsis [Starts a new network using existing network as a model.] Description [] @@ -222,15 +211,10 @@ Abc_Ntk_t * Abc_NtkStartRead( char * pName ) { Abc_Ntk_t * pNtkNew; // allocate the empty network - pNtkNew = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 ); + pNtkNew = Abc_NtkAlloc( ABC_TYPE_NETLIST, ABC_FUNC_SOP ); // set the specs - pNtkNew->pName = Extra_FileNameGeneric(pName); - pNtkNew->pSpec = Extra_UtilStrsav(pName); - if ( pNtkNew->pName == NULL || strlen(pNtkNew->pName) == 0 ) - { - FREE( pNtkNew->pName ); - pNtkNew->pName = Extra_UtilStrsav("unknown"); - } + pNtkNew->pName = util_strsav( pName ); + pNtkNew->pSpec = util_strsav( pName ); return pNtkNew; } @@ -247,50 +231,19 @@ Abc_Ntk_t * Abc_NtkStartRead( char * pName ) ***********************************************************************/ void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pBox, * pObj, * pTerm, * pNet; + Abc_Obj_t * pLatch; int i; - if ( Abc_NtkHasBlackbox(pNtk) && Abc_NtkBoxNum(pNtk) == 0 ) - { - pBox = Abc_NtkCreateBlackbox(pNtk); - Abc_NtkForEachPi( pNtk, pObj, i ) - { - pTerm = Abc_NtkCreateBi(pNtk); - Abc_ObjAddFanin( pTerm, Abc_ObjFanout0(pObj) ); - Abc_ObjAddFanin( pBox, pTerm ); - } - Abc_NtkForEachPo( pNtk, pObj, i ) - { - pTerm = Abc_NtkCreateBo(pNtk); - Abc_ObjAddFanin( pTerm, pBox ); - Abc_ObjAddFanin( Abc_ObjFanin0(pObj), pTerm ); - } - return; - } assert( Abc_NtkIsNetlist(pNtk) ); - - // check if constant 0 net is used - pNet = Abc_NtkFindNet( pNtk, "1\'b0" ); - if ( pNet ) - { - if ( Abc_ObjFanoutNum(pNet) == 0 ) - Abc_NtkDeleteObj(pNet); - else if ( Abc_ObjFaninNum(pNet) == 0 ) - Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst0(pNtk) ); - } - // check if constant 1 net is used - pNet = Abc_NtkFindNet( pNtk, "1\'b1" ); - if ( pNet ) - { - if ( Abc_ObjFanoutNum(pNet) == 0 ) - Abc_NtkDeleteObj(pNet); - else if ( Abc_ObjFaninNum(pNet) == 0 ) - Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst1(pNtk) ); - } // fix the net drivers Abc_NtkFixNonDrivenNets( pNtk ); - - // reorder the CI/COs to PI/POs first - Abc_NtkOrderCisCos( pNtk ); + // create the names table + Abc_NtkCreateCioNamesTable( pNtk ); + // add latches to the CI/CO arrays + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + Vec_PtrPush( pNtk->vCis, pLatch ); + Vec_PtrPush( pNtk->vCos, pLatch ); + } } /**Function************************************************************* @@ -314,47 +267,30 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) // start the network pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc ); // copy the internal nodes - if ( Abc_NtkIsStrash(pNtk) ) - { - // copy the AND gates - Abc_AigForEachAnd( pNtk, pObj, i ) - pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - // relink the choice nodes - Abc_AigForEachAnd( pNtk, pObj, i ) - if ( pObj->pData ) - pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy; - // relink the CO nodes - Abc_NtkForEachCo( pNtk, pObj, i ) - Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); - // get the number of nodes before and after - if ( Abc_NtkNodeNum(pNtk) != Abc_NtkNodeNum(pNtkNew) ) - printf( "Warning: Structural hashing during duplication reduced %d nodes (this is a minor bug).\n", - Abc_NtkNodeNum(pNtk) - Abc_NtkNodeNum(pNtkNew) ); - } + if ( Abc_NtkHasAig(pNtk) ) + Abc_AigDup( pNtk->pManFunc, pNtkNew->pManFunc ); else { // duplicate the nets and nodes (CIs/COs/latches already dupped) Abc_NtkForEachObj( pNtk, pObj, i ) if ( pObj->pCopy == NULL ) - Abc_NtkDupObj(pNtkNew, pObj, 0); + Abc_NtkDupObj(pNtkNew, pObj); // reconnect all objects (no need to transfer attributes on edges) Abc_NtkForEachObj( pNtk, pObj, i ) - if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) ) - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); } // duplicate the EXDC Ntk if ( pNtk->pExdc ) pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); - pNtk->pCopy = pNtkNew; return pNtkNew; } /**Function************************************************************* - Synopsis [Duplicate the network.] + Synopsis [Creates the network composed of one output.] Description [] @@ -363,173 +299,24 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkDouble( Abc_Ntk_t * pNtk ) -{ - char Buffer[500]; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pFanin; - int i, k; - assert( Abc_NtkIsLogic(pNtk) ); - - // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); - sprintf( Buffer, "%s%s", pNtk->pName, "_2x" ); - pNtkNew->pName = Extra_UtilStrsav(Buffer); - - // clean the node copy fields - Abc_NtkCleanCopy( pNtk ); - // clone CIs/CIs/boxes - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_NtkForEachAssert( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_NtkForEachBox( pNtk, pObj, i ) - Abc_NtkDupBox( pNtkNew, pObj, 0 ); - // copy the internal nodes - // duplicate the nets and nodes (CIs/COs/latches already dupped) - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( pObj->pCopy == NULL ) - Abc_NtkDupObj(pNtkNew, pObj, 0); - // reconnect all objects (no need to transfer attributes on edges) - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) ) - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - - // clean the node copy fields - Abc_NtkCleanCopy( pNtk ); - // clone CIs/CIs/boxes - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_NtkForEachAssert( pNtk, pObj, i ) - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_NtkForEachBox( pNtk, pObj, i ) - Abc_NtkDupBox( pNtkNew, pObj, 0 ); - // copy the internal nodes - // duplicate the nets and nodes (CIs/COs/latches already dupped) - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( pObj->pCopy == NULL ) - Abc_NtkDupObj(pNtkNew, pObj, 0); - // reconnect all objects (no need to transfer attributes on edges) - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) ) - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - - // assign names - Abc_NtkForEachCi( pNtk, pObj, i ) - { - Abc_ObjAssignName( Abc_NtkCi(pNtkNew, i), "1_", Abc_ObjName(pObj) ); - Abc_ObjAssignName( Abc_NtkCi(pNtkNew, Abc_NtkCiNum(pNtk) + i), "2_", Abc_ObjName(pObj) ); - } - Abc_NtkForEachCo( pNtk, pObj, i ) - { - Abc_ObjAssignName( Abc_NtkCo(pNtkNew, i), "1_", Abc_ObjName(pObj) ); - Abc_ObjAssignName( Abc_NtkCo(pNtkNew, Abc_NtkCoNum(pNtk) + i), "2_", Abc_ObjName(pObj) ); - } - - // perform the final check - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Attaches the second network at the bottom of the first.] - - Description [Returns the first network. Deletes the second network.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkAttachBottom( Abc_Ntk_t * pNtkTop, Abc_Ntk_t * pNtkBottom ) +Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis ) { - Abc_Obj_t * pObj, * pFanin, * pBuffer; Vec_Ptr_t * vNodes; - int i, k; - assert( pNtkBottom != NULL ); - if ( pNtkTop == NULL ) - return pNtkBottom; - // make sure the networks are combinational - assert( Abc_NtkPiNum(pNtkTop) == Abc_NtkCiNum(pNtkTop) ); - assert( Abc_NtkPiNum(pNtkBottom) == Abc_NtkCiNum(pNtkBottom) ); - // make sure the POs of the bottom correspond to the PIs of the top - assert( Abc_NtkPoNum(pNtkBottom) == Abc_NtkPiNum(pNtkTop) ); - assert( Abc_NtkPiNum(pNtkBottom) < Abc_NtkPiNum(pNtkTop) ); - // add buffers for the PIs of the top - save results in the POs of the bottom - Abc_NtkForEachPi( pNtkTop, pObj, i ) - { - pBuffer = Abc_NtkCreateNodeBuf( pNtkTop, NULL ); - Abc_ObjTransferFanout( pObj, pBuffer ); - Abc_NtkPo(pNtkBottom, i)->pCopy = pBuffer; - } - // remove useless PIs of the top - for ( i = Abc_NtkPiNum(pNtkTop) - 1; i >= Abc_NtkPiNum(pNtkBottom); i-- ) - Abc_NtkDeleteObj( Abc_NtkPi(pNtkTop, i) ); - assert( Abc_NtkPiNum(pNtkBottom) == Abc_NtkPiNum(pNtkTop) ); - // copy the bottom network - Abc_NtkForEachPi( pNtkBottom, pObj, i ) - Abc_NtkPi(pNtkBottom, i)->pCopy = Abc_NtkPi(pNtkTop, i); - // construct all nodes - vNodes = Abc_NtkDfs( pNtkBottom, 0 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - Abc_NtkDupObj(pNtkTop, pObj, 0); - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - } - Vec_PtrFree( vNodes ); - // connect the POs - Abc_NtkForEachPo( pNtkBottom, pObj, i ) - Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy ); - // delete old network - Abc_NtkDelete( pNtkBottom ); - // return the network - if ( !Abc_NtkCheck( pNtkTop ) ) - fprintf( stdout, "Abc_NtkAttachBottom(): Network check has failed.\n" ); - return pNtkTop; -} - -/**Function************************************************************* - - Synopsis [Creates the network composed of one logic cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNodeName, int fUseAllCis ) -{ Abc_Ntk_t * pNtkNew; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj, * pFanin, * pNodeCoNew; + Abc_Obj_t * pObj, * pFanin; char Buffer[1000]; int i, k; assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) ); - assert( Abc_ObjIsNode(pNode) ); + assert( Abc_ObjIsCo(pNode) ); // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); + pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc ); // set the name - sprintf( Buffer, "%s_%s", pNtk->pName, pNodeName ); - pNtkNew->pName = Extra_UtilStrsav(Buffer); + sprintf( Buffer, "%s_%s", pNtk->pName, Abc_ObjName(pNode) ); + pNtkNew->pName = util_strsav(Buffer); - // establish connection between the constant nodes - if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); - - // collect the nodes in the TFI of the output (mark the TFI) + // collect the nodes in the TFI of the output vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 ); // create the PIs Abc_NtkForEachCi( pNtk, pObj, i ) @@ -537,79 +324,12 @@ Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNode if ( fUseAllCis || Abc_NodeIsTravIdCurrent(pObj) ) // TravId is set by DFS { pObj->pCopy = Abc_NtkCreatePi(pNtkNew); - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL ); - } - } - // add the PO corresponding to this output - pNodeCoNew = Abc_NtkCreatePo( pNtkNew ); - Abc_ObjAssignName( pNodeCoNew, pNodeName, NULL ); - // copy the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // if it is an AIG, add to the hash table - if ( Abc_NtkIsStrash(pNtk) ) - { - pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - } - else - { - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); } } - // connect the internal nodes to the new CO - Abc_ObjAddFanin( pNodeCoNew, pNode->pCopy ); - Vec_PtrFree( vNodes ); - - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Creates the network composed of several logic cones.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkCreateConeArray( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, int fUseAllCis ) -{ - Abc_Ntk_t * pNtkNew; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj, * pFanin, * pNodeCoNew; - char Buffer[1000]; - int i, k; - - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) ); - - // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); - // set the name - sprintf( Buffer, "%s_part", pNtk->pName ); - pNtkNew->pName = Extra_UtilStrsav(Buffer); - // establish connection between the constant nodes 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, (Abc_Obj_t **)Vec_PtrArray(vRoots), Vec_PtrSize(vRoots) ); - - // create the PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - { - if ( fUseAllCis || Abc_NodeIsTravIdCurrent(pObj) ) // TravId is set by DFS - { - pObj->pCopy = Abc_NtkCreatePi(pNtkNew); - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL ); - } - } + Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc); // copy the nodes Vec_PtrForEachEntry( vNodes, pObj, i ) @@ -621,160 +341,26 @@ Abc_Ntk_t * Abc_NtkCreateConeArray( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, int fU } else { - Abc_NtkDupObj( pNtkNew, pObj, 0 ); + Abc_NtkDupObj( pNtkNew, pObj ); Abc_ObjForEachFanin( pObj, pFanin, k ) Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); } } Vec_PtrFree( vNodes ); - // add the POs corresponding to the root nodes - Vec_PtrForEachEntry( vRoots, pObj, i ) - { - // create the PO node - pNodeCoNew = Abc_NtkCreatePo( pNtkNew ); - // connect the internal nodes to the new CO - if ( Abc_ObjIsCo(pObj) ) - Abc_ObjAddFanin( pNodeCoNew, Abc_ObjChild0Copy(pObj) ); - else - Abc_ObjAddFanin( pNodeCoNew, pObj->pCopy ); - // assign the name - Abc_ObjAssignName( pNodeCoNew, Abc_ObjName(pObj), NULL ); - } - - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkCreateConeArray(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Adds new nodes to the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkAppendToCone( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; - int i, iNodeId; - - assert( Abc_NtkIsStrash(pNtkNew) ); - assert( Abc_NtkIsStrash(pNtk) ); - - // collect the nodes in the TFI of the output (mark the TFI) - vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)Vec_PtrArray(vRoots), Vec_PtrSize(vRoots) ); - - // establish connection between the constant nodes - Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); - - // create the PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - { - // skip CIs that are not used - if ( !Abc_NodeIsTravIdCurrent(pObj) ) - continue; - // find the corresponding CI in the new network - iNodeId = Nm_ManFindIdByNameTwoTypes( pNtkNew->pManName, Abc_ObjName(pObj), ABC_OBJ_PI, ABC_OBJ_BO ); - if ( iNodeId == -1 ) - { - pObj->pCopy = Abc_NtkCreatePi(pNtkNew); - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL ); - } - else - pObj->pCopy = Abc_NtkObj( pNtkNew, iNodeId ); - } - - // copy the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - Vec_PtrFree( vNodes ); - - // do not add the COs - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkAppendToCone(): Network check has failed.\n" ); -} - -/**Function************************************************************* - - Synopsis [Creates the network composed of MFFC of one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNodeName ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pFanin, * pNodeCoNew; - Vec_Ptr_t * vCone, * vSupp; - char Buffer[1000]; - int i, k; - - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) ); - assert( Abc_ObjIsNode(pNode) ); - - // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); - // set the name - sprintf( Buffer, "%s_%s", pNtk->pName, pNodeName ); - pNtkNew->pName = Extra_UtilStrsav(Buffer); - - // establish connection between the constant nodes - if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); - - // collect the nodes in MFFC - vCone = Vec_PtrAlloc( 100 ); - vSupp = Vec_PtrAlloc( 100 ); - Abc_NodeDeref_rec( pNode ); - Abc_NodeMffsConeSupp( pNode, vCone, vSupp ); - Abc_NodeRef_rec( pNode ); - // create the PIs - Vec_PtrForEachEntry( vSupp, pObj, i ) - { - pObj->pCopy = Abc_NtkCreatePi(pNtkNew); - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL ); - } - // create the PO - pNodeCoNew = Abc_NtkCreatePo( pNtkNew ); - Abc_ObjAssignName( pNodeCoNew, pNodeName, NULL ); - // copy the nodes - Vec_PtrForEachEntry( vCone, pObj, i ) - { - // if it is an AIG, add to the hash table - if ( Abc_NtkIsStrash(pNtk) ) - { - pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - } - else - { - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - } - } - // connect the topmost node - Abc_ObjAddFanin( pNodeCoNew, pNode->pCopy ); - Vec_PtrFree( vCone ); - Vec_PtrFree( vSupp ); + // add the PO corresponding to this output + pNode->pCopy = Abc_NtkCreatePo( pNtkNew ); + Abc_ObjAddFanin( pNode->pCopy, Abc_ObjFanin0(pNode)->pCopy ); + Abc_NtkLogicStoreName( pNode->pCopy, Abc_ObjName(pNode) ); if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkCreateMffc(): Network check has failed.\n" ); + fprintf( stdout, "Abc_NtkSplitOutput(): Network check has failed.\n" ); return pNtkNew; } /**Function************************************************************* - Synopsis [Creates the miter composed of one multi-output cone.] + Synopsis [Creates the network composed of one output.] Description [] @@ -783,7 +369,7 @@ Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNode SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ) +Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ) { Vec_Ptr_t * vNodes; Abc_Ntk_t * pNtkNew; @@ -794,8 +380,8 @@ Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t // start the network Abc_NtkCleanCopy( pNtk ); - pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); - pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); + pNtkNew = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); + pNtkNew->pName = util_strsav(pNtk->pName); // collect the nodes in the TFI of the output vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)vRoots->pArray, vRoots->nSize ); @@ -803,21 +389,18 @@ Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t Abc_NtkForEachCi( pNtk, pObj, i ) { pObj->pCopy = Abc_NtkCreatePi(pNtkNew); - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL ); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); } // copy the nodes Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = Abc_NodeStrash( pNtkNew, pObj, 0 ); + pObj->pCopy = Abc_NodeStrash( pNtkNew->pManFunc, pObj ); Vec_PtrFree( vNodes ); // add the PO - pFinal = Abc_AigConst1( pNtkNew ); + pFinal = Abc_AigConst1( pNtkNew->pManFunc ); Vec_PtrForEachEntry( vRoots, pObj, i ) { - if ( Abc_ObjIsCo(pObj) ) - pOther = Abc_ObjFanin0(pObj)->pCopy; - else - pOther = pObj->pCopy; + pOther = pObj->pCopy; if ( Vec_IntEntry(vValues, i) == 0 ) pOther = Abc_ObjNot(pOther); pFinal = Abc_AigAnd( pNtkNew->pManFunc, pFinal, pOther ); @@ -826,15 +409,15 @@ Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t // add the PO corresponding to this output pNodePo = Abc_NtkCreatePo( pNtkNew ); Abc_ObjAddFanin( pNodePo, pFinal ); - Abc_ObjAssignName( pNodePo, "miter", NULL ); + Abc_NtkLogicStoreName( pNodePo, "miter" ); if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkCreateTarget(): Network check has failed.\n" ); + fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); return pNtkNew; } /**Function************************************************************* - Synopsis [Creates the network composed of one node.] + Synopsis [Deletes the Ntk.] Description [] @@ -843,71 +426,30 @@ Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkCreateFromNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ) +Abc_Ntk_t * Abc_NtkSplitNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtkNew; Abc_Obj_t * pFanin, * pNodePo; int i; // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); - pNtkNew->pName = Extra_UtilStrsav(Abc_ObjName(pNode)); + pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc ); + pNtkNew->pName = util_strsav(Abc_ObjName(pNode)); // add the PIs corresponding to the fanins of the node Abc_ObjForEachFanin( pNode, pFanin, i ) { pFanin->pCopy = Abc_NtkCreatePi( pNtkNew ); - Abc_ObjAssignName( pFanin->pCopy, Abc_ObjName(pFanin), NULL ); + Abc_NtkLogicStoreName( pFanin->pCopy, Abc_ObjName(pFanin) ); } // duplicate and connect the node - pNode->pCopy = Abc_NtkDupObj( pNtkNew, pNode, 0 ); + pNode->pCopy = Abc_NtkDupObj( pNtkNew, pNode ); Abc_ObjForEachFanin( pNode, pFanin, i ) Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy ); // create the only PO pNodePo = Abc_NtkCreatePo( pNtkNew ); Abc_ObjAddFanin( pNodePo, pNode->pCopy ); - Abc_ObjAssignName( pNodePo, Abc_ObjName(pNode), NULL ); - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkCreateFromNode(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Creates the network composed of one node with the given SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pFanin, * pNode, * pNodePo; - Vec_Ptr_t * vNames; - int i, nVars; - // start the network - pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); - pNtkNew->pName = Extra_UtilStrsav("ex"); - // create PIs - Vec_PtrPush( pNtkNew->vObjs, NULL ); - nVars = Abc_SopGetVarNum( pSop ); - vNames = Abc_NodeGetFakeNames( nVars ); - for ( i = 0; i < nVars; i++ ) - Abc_ObjAssignName( Abc_NtkCreatePi(pNtkNew), Vec_PtrEntry(vNames, i), NULL ); - Abc_NodeFreeNames( vNames ); - // create the node, add PIs as fanins, set the function - pNode = Abc_NtkCreateNode( pNtkNew ); - Abc_NtkForEachPi( pNtkNew, pFanin, i ) - Abc_ObjAddFanin( pNode, pFanin ); - pNode->pData = Abc_SopRegister( pNtkNew->pManFunc, pSop ); - // create the only PO - pNodePo = Abc_NtkCreatePo(pNtkNew); - Abc_ObjAddFanin( pNodePo, pNode ); - Abc_ObjAssignName( pNodePo, "F", NULL ); + Abc_NtkLogicStoreName( pNodePo, Abc_ObjName(pNode) ); if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkCreateWithNode(): Network check has failed.\n" ); + fprintf( stdout, "Abc_NtkSplitNode(): Network check has failed.\n" ); return pNtkNew; } @@ -925,107 +467,64 @@ Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop ) void Abc_NtkDelete( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; - void * pAttrMan; int TotalMemory, i; int LargePiece = (4 << ABC_NUM_STEPS); if ( pNtk == NULL ) return; - // free the HAIG - if ( pNtk->pHaig ) - Abc_NtkHaigStop( pNtk ); - // free EXDC Ntk - if ( pNtk->pExdc ) - Abc_NtkDelete( pNtk->pExdc ); - // dereference the BDDs - if ( Abc_NtkHasBdd(pNtk) ) - { - Abc_NtkForEachNode( pNtk, pObj, i ) - Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); - } // make sure all the marks are clean Abc_NtkForEachObj( pNtk, pObj, i ) { // free large fanout arrays - if ( pNtk->pMmObj && pObj->vFanouts.nCap * 4 > LargePiece ) + if ( pObj->vFanouts.nCap * 4 > LargePiece ) FREE( pObj->vFanouts.pArray ); - // these flags should be always zero - // if this is not true, something is wrong somewhere + // check that the other things are okay assert( pObj->fMarkA == 0 ); assert( pObj->fMarkB == 0 ); assert( pObj->fMarkC == 0 ); } - // free the nodes - if ( pNtk->pMmStep == NULL ) - { - Abc_NtkForEachObj( pNtk, pObj, i ) - { - FREE( pObj->vFanouts.pArray ); - FREE( pObj->vFanins.pArray ); - } - } - if ( pNtk->pMmObj == NULL ) - { - Abc_NtkForEachObj( pNtk, pObj, i ) - free( pObj ); - } + + // dereference the BDDs + if ( Abc_NtkHasBdd(pNtk) ) + Abc_NtkForEachNode( pNtk, pObj, i ) + Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); + FREE( pNtk->pName ); + FREE( pNtk->pSpec ); + // copy the EXDC Ntk + 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->vObjs ); + Vec_PtrFree( pNtk->vLats ); Vec_PtrFree( pNtk->vCis ); Vec_PtrFree( pNtk->vCos ); - Vec_PtrFree( pNtk->vAsserts ); - Vec_PtrFree( pNtk->vObjs ); - Vec_PtrFree( pNtk->vBoxes ); - if ( pNtk->vLevelsR ) Vec_IntFree( pNtk->vLevelsR ); - FREE( pNtk->pModel ); - FREE( pNtk->pSeqModel ); + Vec_PtrFree( pNtk->vPtrTemp ); + Vec_IntFree( pNtk->vIntTemp ); + Vec_StrFree( pNtk->vStrTemp ); + // free the hash table of Obj name into Obj ID + stmm_free_table( pNtk->tName2Net ); + stmm_free_table( pNtk->tObj2Name ); TotalMemory = 0; - TotalMemory += pNtk->pMmObj? Extra_MmFixedReadMemUsage(pNtk->pMmObj) : 0; - TotalMemory += pNtk->pMmStep? Extra_MmStepReadMemUsage(pNtk->pMmStep) : 0; + TotalMemory += Extra_MmFlexReadMemUsage(pNtk->pMmNames); + TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj); + TotalMemory += Extra_MmStepReadMemUsage(pNtk->pMmStep); // fprintf( stdout, "The total memory allocated internally by the network = %0.2f Mb.\n", ((double)TotalMemory)/(1<<20) ); // free the storage - if ( pNtk->pMmObj ) - Extra_MmFixedStop( pNtk->pMmObj ); - if ( pNtk->pMmStep ) - Extra_MmStepStop ( pNtk->pMmStep ); - // name manager - Nm_ManFree( pNtk->pManName ); + Extra_MmFlexStop ( pNtk->pMmNames, 0 ); + Extra_MmFixedStop( pNtk->pMmObj, 0 ); + Extra_MmStepStop ( pNtk->pMmStep, 0 ); // free the timing manager if ( pNtk->pManTime ) Abc_ManTimeStop( pNtk->pManTime ); // start the functionality manager - if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigFree( pNtk->pManFunc ); - else if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) ) - Extra_MmFlexStop( pNtk->pManFunc ); + if ( Abc_NtkHasSop(pNtk) ) + Extra_MmFlexStop( pNtk->pManFunc, 0 ); else if ( Abc_NtkHasBdd(pNtk) ) Extra_StopManager( pNtk->pManFunc ); else if ( Abc_NtkHasAig(pNtk) ) - { if ( pNtk->pManFunc ) Hop_ManStop( pNtk->pManFunc ); } - else if ( Abc_NtkHasMapping(pNtk) ) - pNtk->pManFunc = NULL; - else if ( !Abc_NtkHasBlackbox(pNtk) ) + Abc_AigFree( pNtk->pManFunc ); + else if ( !Abc_NtkHasMapping(pNtk) ) assert( 0 ); - // free the hierarchy - if ( pNtk->pDesign ) - { - Abc_LibFree( pNtk->pDesign, pNtk ); - pNtk->pDesign = NULL; - } -// if ( pNtk->pBlackBoxes ) -// Vec_IntFree( pNtk->pBlackBoxes ); - // free node attributes - Vec_PtrForEachEntry( pNtk->vAttrs, pAttrMan, i ) - if ( pAttrMan ) - { -//printf( "deleting attr\n" ); - Vec_AttFree( pAttrMan, 1 ); - } - Vec_PtrFree( pNtk->vAttrs ); - FREE( pNtk->pName ); - FREE( pNtk->pSpec ); free( pNtk ); } @@ -1046,9 +545,6 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ) Abc_Obj_t * pNet, * pNode; int i; - if ( Abc_NtkNodeNum(pNtk) == 0 && Abc_NtkBoxNum(pNtk) == 0 ) - return; - // check for non-driven nets vNets = Vec_PtrAlloc( 100 ); Abc_NtkForEachNet( pNtk, pNet, i ) @@ -1056,24 +552,28 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ) if ( Abc_ObjFaninNum(pNet) > 0 ) continue; // add the constant 0 driver - pNode = Abc_NtkCreateNodeConst0( pNtk ); + pNode = Abc_NtkCreateNode( pNtk ); + // set the constant function + Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") ); // add the fanout net Abc_ObjAddFanin( pNet, pNode ); // add the net to those for which the warning will be printed - Vec_PtrPush( vNets, pNet ); + Vec_PtrPush( vNets, pNet->pData ); } // print the warning if ( vNets->nSize > 0 ) { - printf( "Warning: Constant-0 drivers added to %d non-driven nets in network \"%s\":\n", Vec_PtrSize(vNets), pNtk->pName ); - Vec_PtrForEachEntry( vNets, pNet, i ) + printf( "Constant-zero drivers were added to %d non-driven nets:\n", vNets->nSize ); + for ( i = 0; i < vNets->nSize; i++ ) { - printf( "%s%s", (i? ", ": ""), Abc_ObjName(pNet) ); - if ( i == 3 ) + if ( i == 0 ) + printf( "%s", vNets->pArray[i] ); + else if ( i == 1 ) + printf( ", %s", vNets->pArray[i] ); + else if ( i == 2 ) { - if ( Vec_PtrSize(vNets) > 3 ) - printf( " ..." ); + printf( ", %s, etc.", vNets->pArray[i] ); break; } } @@ -1083,150 +583,6 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ) } -/**Function************************************************************* - - Synopsis [Converts the network to combinational.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMakeComb( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - - if ( Abc_NtkIsComb(pNtk) ) - return; - - assert( !Abc_NtkIsNetlist(pNtk) ); - assert( Abc_NtkHasOnlyLatchBoxes(pNtk) ); - - // detach the latches -// Abc_NtkForEachLatch( pNtk, pObj, i ) - Vec_PtrForEachEntryReverse( pNtk->vBoxes, pObj, i ) - Abc_NtkDeleteObj( pObj ); - assert( Abc_NtkLatchNum(pNtk) == 0 ); - assert( Abc_NtkBoxNum(pNtk) == 0 ); - - // move CIs to become PIs - Vec_PtrClear( pNtk->vPis ); - Abc_NtkForEachCi( pNtk, pObj, i ) - { - if ( Abc_ObjIsBo(pObj) ) - { - pObj->Type = ABC_OBJ_PI; - pNtk->nObjCounts[ABC_OBJ_PI]++; - pNtk->nObjCounts[ABC_OBJ_BO]--; - } - Vec_PtrPush( pNtk->vPis, pObj ); - } - assert( Abc_NtkBoNum(pNtk) == 0 ); - - // move COs to become POs - Vec_PtrClear( pNtk->vPos ); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - if ( Abc_ObjIsBi(pObj) ) - { - pObj->Type = ABC_OBJ_PO; - pNtk->nObjCounts[ABC_OBJ_PO]++; - pNtk->nObjCounts[ABC_OBJ_BI]--; - } - Vec_PtrPush( pNtk->vPos, pObj ); - } - assert( Abc_NtkBiNum(pNtk) == 0 ); - - if ( !Abc_NtkCheck( pNtk ) ) - fprintf( stdout, "Abc_NtkMakeComb(): Network check has failed.\n" ); -} - - -/**Function************************************************************* - - Synopsis [Removes POs with suppsize less than 2 and PIs without fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkTrim( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i, k, m; - - // filter POs - k = m = 0; - Abc_NtkForEachCo( pNtk, pObj, i ) - { - if ( Abc_ObjIsPo(pObj) ) - { - // remove constant nodes and PI pointers - if ( Abc_ObjFaninNum(Abc_ObjFanin0(pObj)) == 0 ) - { - Abc_ObjDeleteFanin( pObj, Abc_ObjFanin0(pObj) ); - if ( Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 0 && !Abc_ObjIsPi(Abc_ObjFanin0(pObj)) ) - Abc_NtkDeleteObj_rec( Abc_ObjFanin0(pObj), 1 ); - pNtk->vObjs->pArray[pObj->Id] = NULL; - pObj->Id = (1<<26)-1; - pNtk->nObjCounts[pObj->Type]--; - pNtk->nObjs--; - Abc_ObjRecycle( pObj ); - continue; - } - // remove buffers/inverters of PIs - if ( Abc_ObjFaninNum(Abc_ObjFanin0(pObj)) == 1 ) - { - if ( Abc_ObjIsPi(Abc_ObjFanin0(Abc_ObjFanin0(pObj))) ) - { - Abc_ObjDeleteFanin( pObj, Abc_ObjFanin0(pObj) ); - if ( Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 0 ) - Abc_NtkDeleteObj_rec( Abc_ObjFanin0(pObj), 1 ); - pNtk->vObjs->pArray[pObj->Id] = NULL; - pObj->Id = (1<<26)-1; - pNtk->nObjCounts[pObj->Type]--; - pNtk->nObjs--; - Abc_ObjRecycle( pObj ); - continue; - } - } - Vec_PtrWriteEntry( pNtk->vPos, m++, pObj ); - } - Vec_PtrWriteEntry( pNtk->vCos, k++, pObj ); - } - Vec_PtrShrink( pNtk->vPos, m ); - Vec_PtrShrink( pNtk->vCos, k ); - - // filter PIs - k = m = 0; - Abc_NtkForEachCi( pNtk, pObj, i ) - { - if ( Abc_ObjIsPi(pObj) ) - { - if ( Abc_ObjFanoutNum(pObj) == 0 ) - { - pNtk->vObjs->pArray[pObj->Id] = NULL; - pObj->Id = (1<<26)-1; - pNtk->nObjCounts[pObj->Type]--; - pNtk->nObjs--; - Abc_ObjRecycle( pObj ); - continue; - } - Vec_PtrWriteEntry( pNtk->vPis, m++, pObj ); - } - Vec_PtrWriteEntry( pNtk->vCis, k++, pObj ); - } - Vec_PtrShrink( pNtk->vPis, m ); - Vec_PtrShrink( pNtk->vCis, k ); - - return Abc_NtkDup( pNtk ); -} //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c index 7a995c71..40c6e7a5 100644 --- a/src/base/abc/abcObj.c +++ b/src/base/abc/abcObj.c @@ -19,7 +19,6 @@ ***********************************************************************/ #include "abc.h" -#include "abcInt.h" #include "main.h" #include "mio.h" @@ -28,12 +27,12 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Creates a new object.] + Synopsis [Creates a new Obj.] Description [] @@ -45,20 +44,17 @@ Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) { Abc_Obj_t * pObj; - if ( pNtk->pMmObj ) - pObj = (Abc_Obj_t *)Extra_MmFixedEntryFetch( pNtk->pMmObj ); - else - pObj = (Abc_Obj_t *)ALLOC( Abc_Obj_t, 1 ); + pObj = (Abc_Obj_t *)Extra_MmFixedEntryFetch( pNtk->pMmObj ); memset( pObj, 0, sizeof(Abc_Obj_t) ); + pObj->Id = -1; pObj->pNtk = pNtk; pObj->Type = Type; - pObj->Id = -1; return pObj; } /**Function************************************************************* - Synopsis [Recycles the object.] + Synopsis [Recycles the Obj.] Description [] @@ -70,22 +66,8 @@ Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) void Abc_ObjRecycle( Abc_Obj_t * pObj ) { Abc_Ntk_t * pNtk = pObj->pNtk; - int LargePiece = (4 << ABC_NUM_STEPS); - // free large fanout arrays - if ( pNtk->pMmStep && pObj->vFanouts.nCap * 4 > LargePiece ) - FREE( pObj->vFanouts.pArray ); - if ( pNtk->pMmStep == NULL ) - { - FREE( pObj->vFanouts.pArray ); - FREE( pObj->vFanins.pArray ); - } - // clean the memory to make deleted object distinct from the live one memset( pObj, 0, sizeof(Abc_Obj_t) ); - // recycle the object - if ( pNtk->pMmObj ) - Extra_MmFixedEntryRecycle( pNtk->pMmObj, (char *)pObj ); - else - free( pObj ); + Extra_MmFixedEntryRecycle( pNtk->pMmObj, (char *)pObj ); } /**Function************************************************************* @@ -99,207 +81,49 @@ void Abc_ObjRecycle( Abc_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) +void Abc_ObjAdd( Abc_Obj_t * pObj ) { - Abc_Obj_t * pObj; - // create new object, assign ID, and add to the array - pObj = Abc_ObjAlloc( pNtk, Type ); + Abc_Ntk_t * pNtk = pObj->pNtk; + assert( !Abc_ObjIsComplement(pObj) ); + // add to the array of objects pObj->Id = pNtk->vObjs->nSize; Vec_PtrPush( pNtk->vObjs, pObj ); - pNtk->nObjCounts[Type]++; pNtk->nObjs++; // perform specialized operations depending on the object type - switch (Type) + if ( Abc_ObjIsNet(pObj) ) { - case ABC_OBJ_NONE: - assert(0); - break; - case ABC_OBJ_CONST1: - assert(0); - break; - case ABC_OBJ_PIO: - assert(0); - break; - case ABC_OBJ_PI: - Vec_PtrPush( pNtk->vPis, pObj ); - Vec_PtrPush( pNtk->vCis, pObj ); - break; - case ABC_OBJ_PO: - Vec_PtrPush( pNtk->vPos, pObj ); - Vec_PtrPush( pNtk->vCos, pObj ); - break; - case ABC_OBJ_BI: - if ( pNtk->vCos ) Vec_PtrPush( pNtk->vCos, pObj ); - break; - case ABC_OBJ_BO: - if ( pNtk->vCis ) Vec_PtrPush( pNtk->vCis, pObj ); - break; - case ABC_OBJ_ASSERT: - Vec_PtrPush( pNtk->vAsserts, pObj ); - Vec_PtrPush( pNtk->vCos, pObj ); - break; - case ABC_OBJ_NET: - case ABC_OBJ_NODE: - break; - case ABC_OBJ_LATCH: - pObj->pData = (void *)ABC_INIT_NONE; - case ABC_OBJ_WHITEBOX: - case ABC_OBJ_BLACKBOX: - if ( pNtk->vBoxes ) Vec_PtrPush( pNtk->vBoxes, pObj ); - break; - default: - assert(0); - break; + // add the name to the table + if ( pObj->pData && stmm_insert( pNtk->tName2Net, pObj->pData, (char *)pObj ) ) + { + printf( "Error: The net is already in the table...\n" ); + assert( 0 ); + } + pNtk->nNets++; } - return pObj; -} - -/**Function************************************************************* - - Synopsis [Deletes the object from the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) -{ - Abc_Ntk_t * pNtk = pObj->pNtk; - Vec_Ptr_t * vNodes; - int i; - assert( !Abc_ObjIsComplement(pObj) ); - // remove from the table of names - if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) ) - Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id); - // delete fanins and fanouts - vNodes = Vec_PtrAlloc( 100 ); - Abc_NodeCollectFanouts( pObj, vNodes ); - for ( i = 0; i < vNodes->nSize; i++ ) - Abc_ObjDeleteFanin( vNodes->pArray[i], pObj ); - Abc_NodeCollectFanins( pObj, vNodes ); - for ( i = 0; i < vNodes->nSize; i++ ) - Abc_ObjDeleteFanin( pObj, vNodes->pArray[i] ); - Vec_PtrFree( vNodes ); - // remove from the list of objects - Vec_PtrWriteEntry( pNtk->vObjs, pObj->Id, NULL ); - pObj->Id = (1<<26)-1; - pNtk->nObjCounts[pObj->Type]--; - pNtk->nObjs--; - // perform specialized operations depending on the object type - switch (pObj->Type) + else if ( Abc_ObjIsNode(pObj) ) { - case ABC_OBJ_NONE: - assert(0); - break; - case ABC_OBJ_CONST1: - assert(0); - break; - case ABC_OBJ_PIO: - assert(0); - break; - case ABC_OBJ_PI: - Vec_PtrRemove( pNtk->vPis, pObj ); - Vec_PtrRemove( pNtk->vCis, pObj ); - break; - case ABC_OBJ_PO: - Vec_PtrRemove( pNtk->vPos, pObj ); - Vec_PtrRemove( pNtk->vCos, pObj ); - break; - case ABC_OBJ_BI: - if ( pNtk->vCos ) Vec_PtrRemove( pNtk->vCos, pObj ); - break; - case ABC_OBJ_BO: - if ( pNtk->vCis ) Vec_PtrRemove( pNtk->vCis, pObj ); - break; - case ABC_OBJ_ASSERT: - Vec_PtrRemove( pNtk->vAsserts, pObj ); - Vec_PtrRemove( pNtk->vCos, pObj ); - break; - case ABC_OBJ_NET: - break; - case ABC_OBJ_NODE: - if ( Abc_NtkHasBdd(pNtk) ) - Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); - pObj->pData = NULL; - break; - case ABC_OBJ_LATCH: - case ABC_OBJ_WHITEBOX: - case ABC_OBJ_BLACKBOX: - if ( pNtk->vBoxes ) Vec_PtrRemove( pNtk->vBoxes, pObj ); - break; - default: - assert(0); - break; + pNtk->nNodes++; } - // recycle the object memory - Abc_ObjRecycle( pObj ); -} - -/**Function************************************************************* - - Synopsis [Deletes the node and MFFC of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes ) -{ - Vec_Ptr_t * vNodes; - int i; - assert( !Abc_ObjIsComplement(pObj) ); - assert( !Abc_ObjIsPi(pObj) ); - assert( Abc_ObjFanoutNum(pObj) == 0 ); - // delete fanins and fanouts - vNodes = Vec_PtrAlloc( 100 ); - Abc_NodeCollectFanins( pObj, vNodes ); - Abc_NtkDeleteObj( pObj ); - if ( fOnlyNodes ) + else if ( Abc_ObjIsLatch(pObj) ) { - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 ) - Abc_NtkDeleteObj_rec( pObj, fOnlyNodes ); + Vec_PtrPush( pNtk->vLats, pObj ); + pNtk->nLatches++; + } + else if ( Abc_ObjIsPi(pObj) ) + { + Vec_PtrPush( pNtk->vCis, pObj ); + pNtk->nPis++; + } + else if ( Abc_ObjIsPo(pObj) ) + { + Vec_PtrPush( pNtk->vCos, pObj ); + pNtk->nPos++; } else { - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( !Abc_ObjIsPi(pObj) && Abc_ObjFanoutNum(pObj) == 0 ) - Abc_NtkDeleteObj_rec( pObj, fOnlyNodes ); + assert( 0 ); } - Vec_PtrFree( vNodes ); -} - -/**Function************************************************************* - - Synopsis [Deletes the node and MFFC of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDeleteAll_rec( Abc_Obj_t * pObj ) -{ - Vec_Ptr_t * vNodes; - int i; - assert( !Abc_ObjIsComplement(pObj) ); - assert( Abc_ObjFanoutNum(pObj) == 0 ); - // delete fanins and fanouts - vNodes = Vec_PtrAlloc( 100 ); - Abc_NodeCollectFanins( pObj, vNodes ); - Abc_NtkDeleteObj( pObj ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( !Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 ) - Abc_NtkDeleteAll_rec( pObj ); - Vec_PtrFree( vNodes ); + assert( pObj->Id >= 0 ); } /**Function************************************************************* @@ -313,68 +137,37 @@ void Abc_NtkDeleteAll_rec( Abc_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName ) +Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) { Abc_Obj_t * pObjNew; - // create the new object - pObjNew = Abc_NtkCreateObj( pNtkNew, pObj->Type ); - // transfer names of the terminal objects - if ( fCopyName ) - { - if ( Abc_ObjIsCi(pObj) ) - { - if ( !Abc_NtkIsNetlist(pNtkNew) ) - Abc_ObjAssignName( pObjNew, Abc_ObjName(Abc_ObjFanout0Ntk(pObj)), NULL ); - } - else if ( Abc_ObjIsCo(pObj) ) - { - if ( !Abc_NtkIsNetlist(pNtkNew) ) - { - if ( Abc_ObjIsPo(pObj) ) - Abc_ObjAssignName( pObjNew, Abc_ObjName(Abc_ObjFanin0Ntk(pObj)), NULL ); - else - { - assert( Abc_ObjIsLatch(Abc_ObjFanout0(pObj)) ); - Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL ); - } - } - } - else if ( Abc_ObjIsBox(pObj) || Abc_ObjIsNet(pObj) ) - Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL ); - } - // copy functionality/names + pObjNew = Abc_ObjAlloc( pNtkNew, pObj->Type ); if ( Abc_ObjIsNode(pObj) ) // copy the function if functionality is compatible { if ( pNtkNew->ntkFunc == pObj->pNtk->ntkFunc ) { - if ( Abc_NtkIsStrash(pNtkNew) ) - {} - else if ( Abc_NtkHasSop(pNtkNew) || Abc_NtkHasBlifMv(pNtkNew) ) + 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 = Hop_Transfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData, Abc_ObjFaninNum(pObj)); else if ( Abc_NtkHasMapping(pNtkNew) ) pObjNew->pData = pObj->pData; - else assert( 0 ); + else if ( Abc_NtkHasAig(pNtkNew) ) + assert( 0 ); } } else if ( Abc_ObjIsNet(pObj) ) // copy the name - { - } + pObjNew->pData = Abc_NtkRegisterName( pNtkNew, pObj->pData ); else if ( Abc_ObjIsLatch(pObj) ) // copy the reset value pObjNew->pData = pObj->pData; - // transfer HAIG -// pObjNew->pEquiv = pObj->pEquiv; - // remember the new node in the old node pObj->pCopy = pObjNew; + // add the object to the network + Abc_ObjAdd( pObjNew ); return pObjNew; } /**Function************************************************************* - Synopsis [Duplicates the latch with its input/output terminals.] + Synopsis [Creates a new constant node.] Description [] @@ -383,25 +176,48 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkDupBox( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pBox, int fCopyName ) -{ - Abc_Obj_t * pTerm, * pBoxNew; - int i; - assert( Abc_ObjIsBox(pBox) ); - // duplicate the box - pBoxNew = Abc_NtkDupObj( pNtkNew, pBox, fCopyName ); - // duplicate the fanins and connect them - Abc_ObjForEachFanin( pBox, pTerm, i ) - Abc_ObjAddFanin( pBoxNew, Abc_NtkDupObj(pNtkNew, pTerm, fCopyName) ); - // duplicate the fanouts and connect them - Abc_ObjForEachFanout( pBox, pTerm, i ) - Abc_ObjAddFanin( Abc_NtkDupObj(pNtkNew, pTerm, fCopyName), pBoxNew ); - return pBoxNew; -} +Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ) +{ + Abc_Obj_t * pConst1; + assert( Abc_NtkIsStrash(pNtkAig) ); + assert( Abc_NtkIsSopLogic(pNtkNew) ); + pConst1 = Abc_AigConst1(pNtkAig->pManFunc); + if ( Abc_ObjFanoutNum(pConst1) > 0 ) + pConst1->pCopy = Abc_NodeCreateConst1( pNtkNew ); + return pConst1->pCopy; +} + +/**Function************************************************************* + + Synopsis [Creates a new constant node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ) +{ + Abc_Obj_t * pReset, * pConst1; + assert( Abc_NtkIsStrash(pNtkAig) ); + assert( Abc_NtkIsSopLogic(pNtkNew) ); + pReset = Abc_AigReset(pNtkAig->pManFunc); + if ( Abc_ObjFanoutNum(pReset) > 0 ) + { + // create new latch with reset value 0 + pReset->pCopy = Abc_NtkCreateLatch( pNtkNew ); + // add constant node fanin to the latch + pConst1 = Abc_NodeCreateConst1( pNtkNew ); + Abc_ObjAddFanin( pReset->pCopy, pConst1 ); + } + return pReset->pCopy; +} /**Function************************************************************* - Synopsis [Clones the objects in the same network but does not assign its function.] + Synopsis [Deletes the object from the network.] Description [] @@ -410,17 +226,59 @@ Abc_Obj_t * Abc_NtkDupBox( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pBox, int fCopyName SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pObj ) +void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) { - Abc_Obj_t * pClone, * pFanin; + Vec_Ptr_t * vNodes = pObj->pNtk->vPtrTemp; + Abc_Ntk_t * pNtk = pObj->pNtk; int i; - pClone = Abc_NtkCreateObj( pObj->pNtk, pObj->Type ); - Abc_ObjForEachFanin( pObj, pFanin, i ) - Abc_ObjAddFanin( pClone, pFanin ); - return pClone; + + assert( !Abc_ObjIsComplement(pObj) ); + + // delete fanins and fanouts + Abc_NodeCollectFanouts( pObj, vNodes ); + for ( i = 0; i < vNodes->nSize; i++ ) + Abc_ObjDeleteFanin( vNodes->pArray[i], pObj ); + Abc_NodeCollectFanins( pObj, vNodes ); + for ( i = 0; i < vNodes->nSize; i++ ) + Abc_ObjDeleteFanin( pObj, vNodes->pArray[i] ); + + // remove from the list of objects + Vec_PtrWriteEntry( pNtk->vObjs, pObj->Id, NULL ); + pObj->Id = (1<<26)-1; + pNtk->nObjs--; + + // perform specialized operations depending on the object type + if ( Abc_ObjIsNet(pObj) ) + { + // remove the net from the hash table of nets + if ( pObj->pData && !stmm_delete( pNtk->tName2Net, (char **)&pObj->pData, (char **)&pObj ) ) + { + printf( "Error: The net is not in the table...\n" ); + assert( 0 ); + } + pObj->pData = NULL; + pNtk->nNets--; + } + else if ( Abc_ObjIsNode(pObj) ) + { + if ( Abc_NtkHasBdd(pNtk) ) + Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); + pNtk->nNodes--; + } + else if ( Abc_ObjIsLatch(pObj) ) + { + pNtk->nLatches--; + } + else + assert( 0 ); + // recycle the net itself + Abc_ObjRecycle( pObj ); } + + + /**Function************************************************************* Synopsis [Returns the net with the given name.] @@ -434,22 +292,38 @@ Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pObj ) ***********************************************************************/ Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ) { - Abc_Obj_t * pObj; - int Num; - // try to find the terminal - Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PO ); - if ( Num >= 0 ) - return Abc_ObjFanin0( Abc_NtkObj( pNtk, Num ) ); - Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BI ); - if ( Num >= 0 ) - return Abc_ObjFanin0( Abc_NtkObj( pNtk, Num ) ); - Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_NODE ); - if ( Num >= 0 ) - return Abc_NtkObj( pNtk, Num ); + Abc_Obj_t * pObj, * pDriver; + int i, Num; + // check if the node is among CIs + Abc_NtkForEachCi( pNtk, pObj, i ) + { + if ( strcmp( Abc_ObjName(pObj), pName ) == 0 ) + { + if ( i < Abc_NtkPiNum(pNtk) ) + printf( "Node \"%s\" is a primary input.\n", pName ); + else + printf( "Node \"%s\" is a latch output.\n", pName ); + return NULL; + } + } + // search the node among COs + Abc_NtkForEachCo( pNtk, pObj, i ) + { + if ( strcmp( Abc_ObjName(pObj), pName ) == 0 ) + { + pDriver = Abc_ObjFanin0(pObj); + if ( !Abc_ObjIsNode(pDriver) ) + { + printf( "Node \"%s\" does not have logic associated with it.\n", pName ); + return NULL; + } + return pDriver; + } + } // find the internal node - if ( pName[0] != 'n' ) + if ( pName[0] != '[' || pName[strlen(pName)-1] != ']' ) { - printf( "Name \"%s\" is not found among CO or node names (internal names often look as \"n<num>\").\n", pName ); + printf( "Name \"%s\" is not found among CIs/COs (internal name looks like this: \"[integer]\").\n", pName ); return NULL; } Num = atoi( pName + 1 ); @@ -483,70 +357,104 @@ Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ) 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.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ) { Abc_Obj_t * pNet; - int ObjId; assert( Abc_NtkIsNetlist(pNtk) ); - ObjId = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_NET ); - if ( ObjId == -1 ) - return NULL; - pNet = Abc_NtkObj( pNtk, ObjId ); - return pNet; + if ( stmm_lookup( pNtk->tName2Net, pName, (char**)&pNet ) ) + return pNet; + return NULL; } /**Function************************************************************* - Synopsis [Returns CI with the given name.] + Synopsis [Finds or creates the net.] - Description [] - - SideEffects [] + Description [] + + SideEffects [] - SeeAlso [] + SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkFindCi( Abc_Ntk_t * pNtk, char * pName ) +Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ) { - int Num; - assert( !Abc_NtkIsNetlist(pNtk) ); - Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PI ); - if ( Num >= 0 ) - return Abc_NtkObj( pNtk, Num ); - Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BO ); - if ( Num >= 0 ) - return Abc_NtkObj( pNtk, Num ); - return NULL; + Abc_Obj_t * pNet; + assert( Abc_NtkIsNetlist(pNtk) ); + if ( pNet = Abc_NtkFindNet( pNtk, pName ) ) + return pNet; + // create a new net + pNet = Abc_ObjAlloc( pNtk, ABC_OBJ_NET ); + pNet->pData = Abc_NtkRegisterName( pNtk, pName ); + Abc_ObjAdd( pNet ); + return pNet; } - + /**Function************************************************************* - Synopsis [Returns CO with the given name.] + Synopsis [Create the new node.] - Description [] - - SideEffects [] + Description [] + + SideEffects [] - SeeAlso [] + SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ) +Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ) { - int Num; - assert( !Abc_NtkIsNetlist(pNtk) ); - Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PO ); - if ( Num >= 0 ) - return Abc_NtkObj( pNtk, Num ); - Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BI ); - if ( Num >= 0 ) - return Abc_NtkObj( pNtk, Num ); - return NULL; + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_NODE ); + Abc_ObjAdd( pObj ); + return pObj; } + +/**Function************************************************************* + + Synopsis [Create the new node.] + + Description [] + + SideEffects [] + SeeAlso [] +***********************************************************************/ +Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_PI ); + Abc_ObjAdd( pObj ); + return pObj; +} + /**Function************************************************************* - Synopsis [Finds or creates the net.] + Synopsis [Create the new node.] Description [] @@ -555,23 +463,17 @@ Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ) +Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pNet; - assert( Abc_NtkIsNetlist(pNtk) ); - if ( pName && (pNet = Abc_NtkFindNet( pNtk, pName )) ) - return pNet; -//printf( "Creating net %s.\n", pName ); - // create a new net - pNet = Abc_NtkCreateNet( pNtk ); - if ( pName ) - Nm_ManStoreIdName( pNtk->pManName, pNet->Id, pNet->Type, pName, NULL ); - return pNet; + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_PO ); + Abc_ObjAdd( pObj ); + return pObj; } /**Function************************************************************* - Synopsis [Creates constant 0 node.] + Synopsis [Create the new node.] Description [] @@ -580,27 +482,17 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk ) +Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pNode; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); - pNode = Abc_NtkCreateNode( pNtk ); - if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(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 = Hop_ManConst0(pNtk->pManFunc); - else if ( Abc_NtkHasMapping(pNtk) ) - pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen()); - else if ( !Abc_NtkHasBlackbox(pNtk) ) - assert( 0 ); - return pNode; + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_LATCH ); + Abc_ObjAdd( pObj ); + return pObj; } /**Function************************************************************* - Synopsis [Creates constant 1 node.] + Synopsis [Creates inverter.] Description [] @@ -609,20 +501,18 @@ Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk ) +Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + assert( !Abc_NtkHasAig(pNtk) ); pNode = Abc_NtkCreateNode( pNtk ); - if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) ) - pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 1\n" ); + if ( Abc_NtkHasSop(pNtk) ) + pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 0\n" ); else if ( Abc_NtkHasBdd(pNtk) ) - pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData ); - else if ( Abc_NtkHasAig(pNtk) ) - pNode->pData = Hop_ManConst1(pNtk->pManFunc); + pNode->pData = Cudd_ReadLogicZero(pNtk->pManFunc), Cudd_Ref( pNode->pData ); else if ( Abc_NtkHasMapping(pNtk) ) - pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen()); - else if ( !Abc_NtkHasBlackbox(pNtk) ) + pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); + else assert( 0 ); return pNode; } @@ -638,20 +528,18 @@ Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) +Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + if ( Abc_NtkHasAig(pNtk) ) + return Abc_AigConst1(pNtk->pManFunc); pNode = Abc_NtkCreateNode( pNtk ); - if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 1\n" ); + pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 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 = Hop_Not(Hop_IthVar(pNtk->pManFunc,0)); + pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData ); else if ( Abc_NtkHasMapping(pNtk) ) - pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen()); + pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); else assert( 0 ); return pNode; @@ -659,7 +547,7 @@ Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) /**Function************************************************************* - Synopsis [Creates buffer.] + Synopsis [Creates inverter.] Description [] @@ -668,20 +556,18 @@ Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) +Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) { Abc_Obj_t * pNode; assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); - pNode = Abc_NtkCreateNode( pNtk ); - if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin ); + pNode = Abc_NtkCreateNode( pNtk ); + Abc_ObjAddFanin( pNode, pFanin ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" ); + pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 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 = Hop_IthVar(pNtk->pManFunc,0); + pNode->pData = Cudd_Not(Cudd_bddIthVar(pNtk->pManFunc,0)), Cudd_Ref( pNode->pData ); else if ( Abc_NtkHasMapping(pNtk) ) - pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen()); + pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); else assert( 0 ); return pNode; @@ -689,7 +575,7 @@ Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) /**Function************************************************************* - Synopsis [Creates AND.] + Synopsis [Creates buffer.] Description [] @@ -698,20 +584,18 @@ Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) +Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) { 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] ); + Abc_ObjAddFanin( pNode, pFanin ); if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopCreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins), NULL ); + pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) - pNode->pData = Extra_bddCreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref(pNode->pData); - else if ( Abc_NtkHasAig(pNtk) ) - pNode->pData = Hop_CreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins) ); + pNode->pData = Cudd_bddIthVar(pNtk->pManFunc,0), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasMapping(pNtk) ) + pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); else assert( 0 ); return pNode; @@ -719,7 +603,7 @@ Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) /**Function************************************************************* - Synopsis [Creates OR.] + Synopsis [Creates inverter.] Description [] @@ -728,20 +612,39 @@ Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) +Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) { Abc_Obj_t * pNode; int i; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + assert( Abc_NtkIsLogic(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_SopCreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins), NULL ); + { + 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; + } else if ( Abc_NtkHasBdd(pNtk) ) - pNode->pData = Extra_bddCreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref(pNode->pData); - else if ( Abc_NtkHasAig(pNtk) ) - pNode->pData = Hop_CreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins) ); + { + 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; + } else assert( 0 ); return pNode; @@ -749,7 +652,7 @@ Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) /**Function************************************************************* - Synopsis [Creates EXOR.] + Synopsis [Creates inverter.] Description [] @@ -758,20 +661,39 @@ Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) +Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) { Abc_Obj_t * pNode; int i; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + assert( Abc_NtkIsLogic(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) ); + { + 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; + } 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 = Hop_CreateExor( pNtk->pManFunc, Vec_PtrSize(vFanins) ); + { + 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; + } else assert( 0 ); return pNode; @@ -779,7 +701,7 @@ Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) /**Function************************************************************* - Synopsis [Creates MUX.] + Synopsis [Creates inverter.] Description [] @@ -788,7 +710,7 @@ Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 ) +Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 ) { Abc_Obj_t * pNode; assert( Abc_NtkIsLogic(pNtk) ); @@ -800,17 +722,14 @@ Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_ 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 = Hop_Mux(pNtk->pManFunc,Hop_IthVar(pNtk->pManFunc,0),Hop_IthVar(pNtk->pManFunc,1),Hop_IthVar(pNtk->pManFunc,2)); else assert( 0 ); return pNode; } - /**Function************************************************************* - Synopsis [Returns 1 if the node is a constant 0 node.] + Synopsis [Clones the given node but does not assign the function.] Description [] @@ -819,15 +738,22 @@ Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_ SeeAlso [] ***********************************************************************/ -bool Abc_NodeIsConst( Abc_Obj_t * pNode ) -{ - assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) ); - return Abc_ObjIsNode(pNode) && Abc_ObjFaninNum(pNode) == 0; +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; } + + /**Function************************************************************* - Synopsis [Returns 1 if the node is a constant 0 node.] + Synopsis [] Description [] @@ -839,25 +765,23 @@ bool Abc_NodeIsConst( Abc_Obj_t * pNode ) bool Abc_NodeIsConst0( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); - assert( Abc_ObjIsNode(pNode) ); - if ( !Abc_NodeIsConst(pNode) ) - return 0; + assert(Abc_ObjIsNode(pNode)); + assert(Abc_NodeIsConst(pNode)); if ( Abc_NtkHasSop(pNtk) ) return Abc_SopIsConst0(pNode->pData); if ( Abc_NtkHasBdd(pNtk) ) return Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return Hop_IsComplement(pNode->pData); + return Abc_ObjNot(pNode) == Abc_AigConst1(pNode->pNtk->pManFunc); if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibGen()); + return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); assert( 0 ); return 0; } /**Function************************************************************* - Synopsis [Returns 1 if the node is a constant 1 node.] + Synopsis [] Description [] @@ -869,25 +793,23 @@ bool Abc_NodeIsConst0( Abc_Obj_t * pNode ) bool Abc_NodeIsConst1( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); - assert( Abc_ObjIsNode(pNode) ); - if ( !Abc_NodeIsConst(pNode) ) - return 0; + assert(Abc_ObjIsNode(pNode)); + assert(Abc_NodeIsConst(pNode)); if ( Abc_NtkHasSop(pNtk) ) return Abc_SopIsConst1(pNode->pData); if ( Abc_NtkHasBdd(pNtk) ) return !Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return !Hop_IsComplement(pNode->pData); + return pNode == Abc_AigConst1(pNode->pNtk->pManFunc); if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibGen()); + return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); assert( 0 ); return 0; } /**Function************************************************************* - Synopsis [Returns 1 if the node is a buffer.] + Synopsis [] Description [] @@ -899,8 +821,7 @@ bool Abc_NodeIsConst1( Abc_Obj_t * pNode ) bool Abc_NodeIsBuf( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); - assert( Abc_ObjIsNode(pNode) ); + assert(Abc_ObjIsNode(pNode)); if ( Abc_ObjFaninNum(pNode) != 1 ) return 0; if ( Abc_NtkHasSop(pNtk) ) @@ -908,16 +829,16 @@ bool Abc_NodeIsBuf( Abc_Obj_t * pNode ) if ( Abc_NtkHasBdd(pNtk) ) return !Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return !Hop_IsComplement(pNode->pData); + return 0; if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibGen()); + return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); assert( 0 ); return 0; } /**Function************************************************************* - Synopsis [Returns 1 if the node is an inverter.] + Synopsis [] Description [] @@ -929,8 +850,7 @@ bool Abc_NodeIsBuf( Abc_Obj_t * pNode ) bool Abc_NodeIsInv( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); - assert( Abc_ObjIsNode(pNode) ); + assert(Abc_ObjIsNode(pNode)); if ( Abc_ObjFaninNum(pNode) != 1 ) return 0; if ( Abc_NtkHasSop(pNtk) ) @@ -938,38 +858,13 @@ bool Abc_NodeIsInv( Abc_Obj_t * pNode ) if ( Abc_NtkHasBdd(pNtk) ) return Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return Hop_IsComplement(pNode->pData); + return 0; if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibGen()); + return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); 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 = Hop_Not( pNode->pData ); - else - assert( 0 ); -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcRefs.c b/src/base/abc/abcRefs.c index 604c5ffa..47618bf4 100644 --- a/src/base/abc/abcRefs.c +++ b/src/base/abc/abcRefs.c @@ -24,11 +24,11 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel ); +static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel, Vec_Ptr_t * vNodes ); static int Abc_NodeRefDerefStop( Abc_Obj_t * pNode, bool fReference ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -45,13 +45,12 @@ static int Abc_NodeRefDerefStop( Abc_Obj_t * pNode, bool fReference ); int Abc_NodeMffcSize( Abc_Obj_t * pNode ) { int nConeSize1, nConeSize2; -// assert( Abc_NtkIsStrash(pNode->pNtk) ); -// assert( !Abc_ObjIsComplement( pNode ) ); + assert( !Abc_ObjIsComplement( pNode ) ); assert( Abc_ObjIsNode( pNode ) ); if ( Abc_ObjFaninNum(pNode) == 0 ) return 0; - nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0 ); // dereference - nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0 ); // reference + nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0, NULL ); // dereference + nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0, NULL ); // reference assert( nConeSize1 == nConeSize2 ); assert( nConeSize1 > 0 ); return nConeSize1; @@ -71,7 +70,6 @@ int Abc_NodeMffcSize( Abc_Obj_t * pNode ) int Abc_NodeMffcSizeStop( Abc_Obj_t * pNode ) { int nConeSize1, nConeSize2; - assert( Abc_NtkIsStrash(pNode->pNtk) ); assert( !Abc_ObjIsComplement( pNode ) ); assert( Abc_ObjIsNode( pNode ) ); if ( Abc_ObjFaninNum(pNode) == 0 ) @@ -94,16 +92,15 @@ int Abc_NodeMffcSizeStop( Abc_Obj_t * pNode ) SeeAlso [] ***********************************************************************/ -int Abc_NodeMffcLabelAig( Abc_Obj_t * pNode ) +int Abc_NodeMffcLabel( Abc_Obj_t * pNode ) { int nConeSize1, nConeSize2; - assert( Abc_NtkIsStrash(pNode->pNtk) ); assert( !Abc_ObjIsComplement( pNode ) ); assert( Abc_ObjIsNode( pNode ) ); if ( Abc_ObjFaninNum(pNode) == 0 ) return 0; - nConeSize1 = Abc_NodeRefDeref( pNode, 0, 1 ); // dereference - nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0 ); // reference + nConeSize1 = Abc_NodeRefDeref( pNode, 0, 1, NULL ); // dereference + nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0, NULL ); // reference assert( nConeSize1 == nConeSize2 ); assert( nConeSize1 > 0 ); return nConeSize1; @@ -111,6 +108,33 @@ int Abc_NodeMffcLabelAig( Abc_Obj_t * pNode ) /**Function************************************************************* + Synopsis [Collects the nodes in MFFC in the topological order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NodeMffcCollect( Abc_Obj_t * pNode ) +{ + Vec_Ptr_t * vNodes; + int nConeSize1, nConeSize2; + assert( !Abc_ObjIsComplement( pNode ) ); + assert( Abc_ObjIsNode( pNode ) ); + vNodes = Vec_PtrAlloc( 8 ); + if ( Abc_ObjFaninNum(pNode) == 0 ) + return vNodes; + nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0, vNodes ); // dereference + nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0, NULL ); // reference + assert( nConeSize1 == nConeSize2 ); + assert( nConeSize1 > 0 ); + return vNodes; +} + +/**Function************************************************************* + Synopsis [References/references the node and returns MFFC size.] Description [] @@ -120,13 +144,16 @@ int Abc_NodeMffcLabelAig( Abc_Obj_t * pNode ) SeeAlso [] ***********************************************************************/ -int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel ) +int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel, Vec_Ptr_t * vNodes ) { Abc_Obj_t * pNode0, * pNode1; int Counter; // label visited nodes if ( fLabel ) Abc_NodeSetTravIdCurrent( pNode ); + // collect visited nodes + if ( vNodes ) + Vec_PtrPush( vNodes, pNode ); // skip the CI if ( Abc_ObjIsCi(pNode) ) return 0; @@ -137,23 +164,22 @@ int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel ) if ( fReference ) { if ( pNode0->vFanouts.nSize++ == 0 ) - Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel ); + Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel, vNodes ); if ( pNode1->vFanouts.nSize++ == 0 ) - Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel ); + Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel, vNodes ); } else { assert( pNode0->vFanouts.nSize > 0 ); assert( pNode1->vFanouts.nSize > 0 ); if ( --pNode0->vFanouts.nSize == 0 ) - Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel ); + Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel, vNodes ); if ( --pNode1->vFanouts.nSize == 0 ) - Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel ); + Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel, vNodes ); } return Counter; } - /**Function************************************************************* Synopsis [References/references the node and returns MFFC size.] @@ -195,256 +221,6 @@ int Abc_NodeRefDerefStop( Abc_Obj_t * pNode, bool fReference ) return Counter; } - - - -/**Function************************************************************* - - Synopsis [Dereferences the node's MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeDeref_rec( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pFanin; - int i, Counter = 1; - if ( Abc_ObjIsCi(pNode) ) - return 0; - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - assert( pFanin->vFanouts.nSize > 0 ); - if ( --pFanin->vFanouts.nSize == 0 ) - Counter += Abc_NodeDeref_rec( pFanin ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [References the node's MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeRef_rec( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pFanin; - int i, Counter = 1; - if ( Abc_ObjIsCi(pNode) ) - return 0; - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - if ( pFanin->vFanouts.nSize++ == 0 ) - Counter += Abc_NodeRef_rec( pFanin ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Collects the internal and boundary nodes in the derefed MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeMffsConeSupp_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int fTopmost ) -{ - Abc_Obj_t * pFanin; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pNode) ) - return; - Abc_NodeSetTravIdCurrent(pNode); - // add to the new support nodes - if ( !fTopmost && (Abc_ObjIsCi(pNode) || pNode->vFanouts.nSize > 0) ) - { - if ( vSupp ) Vec_PtrPush( vSupp, pNode ); - return; - } - // recur on the children - Abc_ObjForEachFanin( pNode, pFanin, i ) - Abc_NodeMffsConeSupp_rec( pFanin, vCone, vSupp, 0 ); - // collect the internal node - if ( vCone ) Vec_PtrPush( vCone, pNode ); -// printf( "%d ", pNode->Id ); -} - -/**Function************************************************************* - - Synopsis [Collects the support of the derefed MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeMffsConeSupp( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp ) -{ - assert( Abc_ObjIsNode(pNode) ); - assert( !Abc_ObjIsComplement(pNode) ); - if ( vCone ) Vec_PtrClear( vCone ); - if ( vSupp ) Vec_PtrClear( vSupp ); - Abc_NtkIncrementTravId( pNode->pNtk ); - Abc_NodeMffsConeSupp_rec( pNode, vCone, vSupp, 1 ); -// printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Collects the support of the derefed MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeMffsConeSuppPrint( Abc_Obj_t * pNode ) -{ - Vec_Ptr_t * vCone, * vSupp; - Abc_Obj_t * pObj; - int i; - vCone = Vec_PtrAlloc( 100 ); - vSupp = Vec_PtrAlloc( 100 ); - Abc_NodeDeref_rec( pNode ); - Abc_NodeMffsConeSupp( pNode, vCone, vSupp ); - Abc_NodeRef_rec( pNode ); - printf( "Node = %6s : Supp = %3d Cone = %3d (", - Abc_ObjName(pNode), Vec_PtrSize(vSupp), Vec_PtrSize(vCone) ); - Vec_PtrForEachEntry( vCone, pObj, i ) - printf( " %s", Abc_ObjName(pObj) ); - printf( " )\n" ); - Vec_PtrFree( vCone ); - Vec_PtrFree( vSupp ); -} - -/**Function************************************************************* - - Synopsis [Collects the internal nodes of the MFFC limited by cut.] - - Description [] - - SideEffects [Increments the trav ID and marks visited nodes.] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeMffsInside( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vInside ) -{ - Abc_Obj_t * pObj; - int i, Count1, Count2; - // increment the fanout counters for the leaves - Vec_PtrForEachEntry( vLeaves, pObj, i ) - pObj->vFanouts.nSize++; - // dereference the node - Count1 = Abc_NodeDeref_rec( pNode ); - // collect the nodes inside the MFFC - Abc_NodeMffsConeSupp( pNode, vInside, NULL ); - // reference it back - Count2 = Abc_NodeRef_rec( pNode ); - assert( Count1 == Count2 ); - // remove the extra counters - Vec_PtrForEachEntry( vLeaves, pObj, i ) - pObj->vFanouts.nSize--; - return Count1; -} - -/**Function************************************************************* - - Synopsis [Collects the internal nodes of the MFFC limited by cut.] - - Description [] - - SideEffects [Increments the trav ID and marks visited nodes.] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NodeMffsInsideCollect( Abc_Obj_t * pNode ) -{ - Vec_Ptr_t * vInside; - int Count1, Count2; - // dereference the node - Count1 = Abc_NodeDeref_rec( pNode ); - // collect the nodes inside the MFFC - vInside = Vec_PtrAlloc( 10 ); - Abc_NodeMffsConeSupp( pNode, vInside, NULL ); - // reference it back - Count2 = Abc_NodeRef_rec( pNode ); - assert( Count1 == Count2 ); - return vInside; -} - -/**Function************************************************************* - - Synopsis [Collects the internal and boundary nodes in the derefed MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeMffcLabel_rec( Abc_Obj_t * pNode, int fTopmost ) -{ - Abc_Obj_t * pFanin; - int i; - // add to the new support nodes - if ( !fTopmost && (Abc_ObjIsCi(pNode) || pNode->vFanouts.nSize > 0) ) - return; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pNode) ) - return; - Abc_NodeSetTravIdCurrent(pNode); - // recur on the children - Abc_ObjForEachFanin( pNode, pFanin, i ) - Abc_NodeMffcLabel_rec( pFanin, 0 ); - // collect the internal node -// printf( "%d ", pNode->Id ); -} - -/**Function************************************************************* - - Synopsis [Collects the internal nodes of the MFFC limited by cut.] - - Description [] - - SideEffects [Increments the trav ID and marks visited nodes.] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeMffcLabel( Abc_Obj_t * pNode ) -{ - int Count1, Count2; - // dereference the node - Count1 = Abc_NodeDeref_rec( pNode ); - // collect the nodes inside the MFFC - Abc_NtkIncrementTravId( pNode->pNtk ); - Abc_NodeMffcLabel_rec( pNode, 1 ); - // reference it back - Count2 = Abc_NodeRef_rec( pNode ); - assert( Count1 == Count2 ); - return Count1; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcShow.c b/src/base/abc/abcShow.c index 40d1dcad..20a64246 100644 --- a/src/base/abc/abcShow.c +++ b/src/base/abc/abcShow.c @@ -30,11 +30,11 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern void Abc_ShowFile( char * FileNameDot ); +static void Abc_ShowFile( char * FileNameDot ); static void Abc_ShowGetFileName( char * pName, char * pBuffer ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -79,6 +79,47 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode ) /**Function************************************************************* + Synopsis [Visualizes AIG with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkShowAig( Abc_Ntk_t * pNtk ) +{ + FILE * pFile; + Abc_Obj_t * pNode; + Vec_Ptr_t * vNodes; + char FileNameDot[200]; + int i; + + assert( Abc_NtkIsStrash(pNtk) ); + // create the file name + Abc_ShowGetFileName( pNtk->pName, FileNameDot ); + // check that the file can be opened + if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot ); + return; + } + + // collect all nodes in the network + vNodes = Vec_PtrAlloc( 100 ); + Abc_NtkForEachObj( pNtk, pNode, i ) + Vec_PtrPush( vNodes, pNode ); + // write the DOT file + Io_WriteDot( pNtk, vNodes, NULL, FileNameDot ); + Vec_PtrFree( vNodes ); + + // visualize the file + Abc_ShowFile( FileNameDot ); +} + +/**Function************************************************************* + Synopsis [Visualizes a reconvergence driven cut at the node.] Description [] @@ -129,7 +170,7 @@ void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax ) // add the root node to the cone (for visualization) Vec_PtrPush( vCutSmall, pNode ); // write the DOT file - Io_WriteDotNtk( pNode->pNtk, vInside, vCutSmall, FileNameDot, 0, 0 ); + Io_WriteDot( pNode->pNtk, vInside, vCutSmall, FileNameDot ); // stop the cut computation manager Abc_NtkManCutStop( p ); @@ -137,59 +178,6 @@ void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax ) Abc_ShowFile( FileNameDot ); } -/**Function************************************************************* - - Synopsis [Visualizes AIG with choices.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkShow( Abc_Ntk_t * pNtk, int fGateNames, int fSeq, int fUseReverse ) -{ - FILE * pFile; - Abc_Obj_t * pNode; - Vec_Ptr_t * vNodes; - char FileNameDot[200]; - int i; - - assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) ); - if ( Abc_NtkIsStrash(pNtk) && Abc_NtkGetChoiceNum(pNtk) ) - { - printf( "Temporarily visualization of AIGs with choice nodes is disabled.\n" ); - return; - } - // convert to logic SOP - if ( Abc_NtkIsLogic(pNtk) ) - Abc_NtkToSop( pNtk, 0 ); - // create the file name - Abc_ShowGetFileName( pNtk->pName, FileNameDot ); - // check that the file can be opened - if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) - { - fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot ); - return; - } - fclose( pFile ); - - // collect all nodes in the network - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachObj( pNtk, pNode, i ) - Vec_PtrPush( vNodes, pNode ); - // write the DOT file - if ( fSeq ) - Io_WriteDotSeq( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse ); - else - Io_WriteDotNtk( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse ); - Vec_PtrFree( vNodes ); - - // visualize the file - Abc_ShowFile( FileNameDot ); -} - /**Function************************************************************* diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index 106901ab..28e92889 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -28,7 +28,7 @@ 01- 1 1-1 1 - is the string: "01- 1\n1-1 1\n" where '\n' is a single char. + is the string: "01- 1/n1-1 1/n" where '/n' is a single char. */ //////////////////////////////////////////////////////////////////////// @@ -36,7 +36,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -61,7 +61,7 @@ char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName ) /**Function************************************************************* - Synopsis [Creates the constant 1 cover with the given number of variables and cubes.] + Synopsis [Starts the constant 1 cover with the given number of variables and cubes.] Description [] @@ -92,7 +92,7 @@ char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars ) /**Function************************************************************* - Synopsis [Creates the constant 1 cover with 0 variables.] + Synopsis [Starts the constant 1 cover with 0 variables.] Description [] @@ -108,7 +108,7 @@ char * Abc_SopCreateConst1( Extra_MmFlex_t * pMan ) /**Function************************************************************* - Synopsis [Creates the constant 1 cover with 0 variables.] + Synopsis [Starts the constant 1 cover with 0 variables.] Description [] @@ -124,7 +124,7 @@ char * Abc_SopCreateConst0( Extra_MmFlex_t * pMan ) /**Function************************************************************* - Synopsis [Creates the AND2 cover.] + Synopsis [Starts the AND2 cover.] Description [] @@ -147,7 +147,7 @@ char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 ) /**Function************************************************************* - Synopsis [Creates the multi-input AND cover.] + Synopsis [Starts the multi-input AND cover.] Description [] @@ -156,20 +156,19 @@ char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 ) SeeAlso [] ***********************************************************************/ -char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ) +char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars ) { char * pSop; int i; pSop = Abc_SopStart( pMan, 1, nVars ); for ( i = 0; i < nVars; i++ ) - pSop[i] = '1' - (pfCompl? pfCompl[i] : 0); - pSop[nVars + 1] = '1'; + pSop[i] = '1'; return pSop; } /**Function************************************************************* - Synopsis [Creates the multi-input NAND cover.] + Synopsis [Starts the multi-input NAND cover.] Description [] @@ -191,7 +190,7 @@ char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars ) /**Function************************************************************* - Synopsis [Creates the multi-input OR cover.] + Synopsis [Starts the multi-input OR cover.] Description [] @@ -213,7 +212,7 @@ char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl ) /**Function************************************************************* - Synopsis [Creates the multi-input OR cover.] + Synopsis [Starts the multi-input OR cover.] Description [] @@ -238,7 +237,7 @@ char * Abc_SopCreateOrMultiCube( Extra_MmFlex_t * pMan, int nVars, int * pfCompl /**Function************************************************************* - Synopsis [Creates the multi-input NOR cover.] + Synopsis [Starts the multi-input NOR cover.] Description [] @@ -259,7 +258,7 @@ char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars ) /**Function************************************************************* - Synopsis [Creates the multi-input XOR cover.] + Synopsis [Starts the multi-input XOR cover.] Description [] @@ -276,27 +275,7 @@ char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars ) /**Function************************************************************* - Synopsis [Creates the multi-input XOR cover (special case).] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars ) -{ - char * pSop; - pSop = Abc_SopCreateAnd( pMan, nVars, NULL ); - pSop[nVars+1] = 'x'; - assert( pSop[nVars+2] == '\n' ); - return pSop; -} - -/**Function************************************************************* - - Synopsis [Creates the multi-input XNOR cover.] + Synopsis [Starts the multi-input XNOR cover.] Description [] @@ -308,29 +287,12 @@ char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars ) char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars ) { assert( nVars == 2 ); - return Abc_SopRegister(pMan, "11 1\n00 1\n"); + return Abc_SopRegister(pMan, "11 1\n11 1\n"); } /**Function************************************************************* - Synopsis [Creates the MUX cover.] - - Description [The first input of MUX is the control. The second input - is DATA1. The third input is DATA0.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_SopCreateMux( Extra_MmFlex_t * pMan ) -{ - return Abc_SopRegister(pMan, "11- 1\n0-1 1\n"); -} - -/**Function************************************************************* - - Synopsis [Creates the inv cover.] + Synopsis [Starts the inv cover.] Description [] @@ -346,7 +308,7 @@ char * Abc_SopCreateInv( Extra_MmFlex_t * pMan ) /**Function************************************************************* - Synopsis [Creates the buf cover.] + Synopsis [Starts the buf cover.] Description [] @@ -360,82 +322,6 @@ char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan ) return Abc_SopRegister(pMan, "1 1\n"); } -/**Function************************************************************* - - Synopsis [Creates the arbitrary cover from the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth ) -{ - char * pSop, * pCube; - int nMints, Counter, i, k; - // count the number of true minterms - Counter = 0; - nMints = (1 << nVars); - for ( i = 0; i < nMints; i++ ) - Counter += ((pTruth[i>>5] & (1 << (i&31))) > 0); - // SOP is not well-defined if the truth table is constant 0 - assert( Counter > 0 ); - if ( Counter == 0 ) - return NULL; - // start the cover - pSop = Abc_SopStart( pMan, Counter, nVars ); - // create true minterms - Counter = 0; - for ( i = 0; i < nMints; i++ ) - if ( (pTruth[i>>5] & (1 << (i&31))) > 0 ) - { - pCube = pSop + Counter * (nVars + 3); - for ( k = 0; k < nVars; k++ ) - pCube[k] = '0' + ((i & (1 << k)) > 0); - Counter++; - } - return pSop; -} - -/**Function************************************************************* - - Synopsis [Creates the cover from the ISOP computed from TT.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover ) -{ - char * pSop, * pCube; - int i, k, Entry, Literal; - assert( Vec_IntSize(vCover) > 0 ); - if ( Vec_IntSize(vCover) == 0 ) - return NULL; - // start the cover - pSop = Abc_SopStart( pMan, Vec_IntSize(vCover), nVars ); - // create cubes - Vec_IntForEachEntry( vCover, Entry, i ) - { - pCube = pSop + i * (nVars + 3); - for ( k = 0; k < nVars; k++ ) - { - Literal = 3 & (Entry >> (k << 1)); - if ( Literal == 1 ) - pCube[k] = '0'; - else if ( Literal == 2 ) - pCube[k] = '1'; - else if ( Literal != 0 ) - assert( 0 ); - } - } - return pSop; -} /**Function************************************************************* @@ -516,9 +402,9 @@ int Abc_SopGetVarNum( char * pSop ) int Abc_SopGetPhase( char * pSop ) { int nVars = Abc_SopGetVarNum( pSop ); - if ( pSop[nVars+1] == '0' || pSop[nVars+1] == 'n' ) + if ( pSop[nVars+1] == '0' ) return 0; - if ( pSop[nVars+1] == '1' || pSop[nVars+1] == 'x' ) + if ( pSop[nVars+1] == '1' ) return 1; assert( 0 ); return -1; @@ -567,10 +453,6 @@ void Abc_SopComplement( char * pSop ) *(pCur - 1) = '1'; else if ( *(pCur - 1) == '1' ) *(pCur - 1) = '0'; - else if ( *(pCur - 1) == 'x' ) - *(pCur - 1) = 'n'; - else if ( *(pCur - 1) == 'n' ) - *(pCur - 1) = 'x'; else assert( 0 ); } @@ -592,7 +474,7 @@ bool Abc_SopIsComplement( char * pSop ) char * pCur; for ( pCur = pSop; *pCur; pCur++ ) if ( *pCur == '\n' ) - return (int)(*(pCur - 1) == '0' || *(pCur - 1) == 'n'); + return (int)(*(pCur - 1) == '0'); assert( 0 ); return 0; } @@ -734,27 +616,6 @@ bool Abc_SopIsOrType( char * pSop ) SeeAlso [] ***********************************************************************/ -int Abc_SopIsExorType( char * pSop ) -{ - char * pCur; - for ( pCur = pSop; *pCur; pCur++ ) - if ( *pCur == '\n' ) - return (int)(*(pCur - 1) == 'x' || *(pCur - 1) == 'n'); - assert( 0 ); - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ bool Abc_SopCheck( char * pSop, int nFanins ) { char * pCubes, * pCubesOld; @@ -768,8 +629,7 @@ bool Abc_SopCheck( char * pSop, int nFanins ) // compare the distance if ( pCubes - pCubesOld != nFanins ) { - fprintf( stdout, "Abc_SopCheck: SOP has a mismatch between its cover size (%d) and its fanin number (%d).\n", - pCubes - pCubesOld, nFanins ); + fprintf( stdout, "Abc_SopCheck: SOP has a mismatch between its cover and its fanins.\n" ); return 0; } // check the output values for this cube @@ -778,9 +638,9 @@ bool Abc_SopCheck( char * pSop, int nFanins ) fFound0 = 1; else if ( *pCubes == '1' ) fFound1 = 1; - else if ( *pCubes != 'x' && *pCubes != 'n' ) + else { - fprintf( stdout, "Abc_SopCheck: SOP has a strange character (%c) in the output part of its cube.\n", *pCubes ); + fprintf( stdout, "Abc_SopCheck: SOP has a strange character in the output part of its cube.\n" ); return 0; } // check the last symbol (new line) @@ -799,274 +659,78 @@ bool Abc_SopCheck( char * pSop, int nFanins ) return 1; } - /**Function************************************************************* - Synopsis [Derives SOP from the truth table representation.] - - Description [Truth table is expected to be in the hexadecimal notation.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_SopFromTruthBin( char * pTruth ) -{ - char * pSopCover, * pCube; - int nTruthSize, nVars, Digit, Length, Mint, i, b; - Vec_Int_t * vMints; + Synopsis [Writes the CNF of the SOP into file.] - // get the number of variables - nTruthSize = strlen(pTruth); - nVars = Extra_Base2Log( nTruthSize ); - if ( nTruthSize != (1 << (nVars)) ) - { - printf( "String %s does not look like a truth table of a %d-variable function.\n", pTruth, nVars ); - return NULL; - } - - // collect the on-set minterms - vMints = Vec_IntAlloc( 100 ); - for ( i = 0; i < nTruthSize; i++ ) - { - if ( pTruth[i] >= '0' && pTruth[i] <= '1' ) - Digit = pTruth[i] - '0'; - else - { - printf( "String %s does not look like a binary representation of the truth table.\n", pTruth ); - return NULL; - } - if ( Digit == 1 ) - Vec_IntPush( vMints, nTruthSize - 1 - i ); - } - if ( Vec_IntSize( vMints ) == 0 || Vec_IntSize( vMints ) == nTruthSize ) - { - Vec_IntFree( vMints ); - printf( "Cannot create constant function.\n" ); - return NULL; - } - - // create the SOP representation of the minterms - Length = Vec_IntSize(vMints) * (nVars + 3); - pSopCover = ALLOC( char, Length + 1 ); - pSopCover[Length] = 0; - Vec_IntForEachEntry( vMints, Mint, i ) - { - pCube = pSopCover + i * (nVars + 3); - for ( b = 0; b < nVars; b++ ) - if ( Mint & (1 << (nVars-1-b)) ) -// if ( Mint & (1 << b) ) - pCube[b] = '1'; - else - pCube[b] = '0'; - pCube[nVars + 0] = ' '; - pCube[nVars + 1] = '1'; - pCube[nVars + 2] = '\n'; - } - Vec_IntFree( vMints ); - return pSopCover; -} - -/**Function************************************************************* - - Synopsis [Derives SOP from the truth table representation.] - - Description [Truth table is expected to be in the hexadecimal notation.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -char * Abc_SopFromTruthHex( char * pTruth ) +void Abc_SopWriteCnf( FILE * pFile, char * pClauses, Vec_Int_t * vVars ) { - char * pSopCover, * pCube; - int nTruthSize, nVars, Digit, Length, Mint, i, b; - Vec_Int_t * vMints; - - // get the number of variables - nTruthSize = strlen(pTruth); - nVars = Extra_Base2Log( nTruthSize ) + 2; - if ( nTruthSize != (1 << (nVars-2)) ) - { - printf( "String %s does not look like a truth table of a %d-variable function.\n", pTruth, nVars ); - return NULL; - } - - // collect the on-set minterms - vMints = Vec_IntAlloc( 100 ); - for ( i = 0; i < nTruthSize; i++ ) - { - if ( pTruth[i] >= '0' && pTruth[i] <= '9' ) - Digit = pTruth[i] - '0'; - else if ( pTruth[i] >= 'a' && pTruth[i] <= 'f' ) - Digit = 10 + pTruth[i] - 'a'; - else if ( pTruth[i] >= 'A' && pTruth[i] <= 'F' ) - Digit = 10 + pTruth[i] - 'A'; - else - { - printf( "String %s does not look like a hexadecimal representation of the truth table.\n", pTruth ); - return NULL; - } - for ( b = 0; b < 4; b++ ) - if ( Digit & (1 << b) ) - Vec_IntPush( vMints, 4*(nTruthSize-1-i)+b ); - } - - // create the SOP representation of the minterms - Length = Vec_IntSize(vMints) * (nVars + 3); - pSopCover = ALLOC( char, Length + 1 ); - pSopCover[Length] = 0; - Vec_IntForEachEntry( vMints, Mint, i ) + char * pChar; + int i; + // check the logic function of the node + for ( pChar = pClauses; *pChar; pChar++ ) { - pCube = pSopCover + i * (nVars + 3); - for ( b = 0; b < nVars; b++ ) -// if ( Mint & (1 << (nVars-1-b)) ) - if ( Mint & (1 << b) ) - pCube[b] = '1'; - else - pCube[b] = '0'; - pCube[nVars + 0] = ' '; - pCube[nVars + 1] = '1'; - pCube[nVars + 2] = '\n'; + // write the clause + for ( i = 0; i < vVars->nSize; i++, pChar++ ) + if ( *pChar == '0' ) + fprintf( pFile, "%d ", vVars->pArray[i] ); + else if ( *pChar == '1' ) + fprintf( pFile, "%d ", -vVars->pArray[i] ); + fprintf( pFile, "0\n" ); + // check that the remainig part is fine + assert( *pChar == ' ' ); + pChar++; + assert( *pChar == '1' ); + pChar++; + assert( *pChar == '\n' ); } - Vec_IntFree( vMints ); - return pSopCover; } /**Function************************************************************* - Synopsis [Creates one encoder node.] + Synopsis [Adds the clauses of for the CNF to the solver.] - Description [Produces MV-SOP for BLIF-MV representation.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_SopEncoderPos( Extra_MmFlex_t * pMan, int iValue, int nValues ) -{ - char Buffer[32]; - assert( iValue < nValues ); - sprintf( Buffer, "d0\n%d 1\n", iValue ); - return Abc_SopRegister( pMan, Buffer ); -} - -/**Function************************************************************* - - Synopsis [Creates one encoder node.] - - Description [Produces MV-SOP for BLIF-MV representation.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_SopEncoderLog( Extra_MmFlex_t * pMan, int iBit, int nValues ) -{ - char * pResult; - Vec_Str_t * vSop; - int v, Counter, fFirst = 1, nBits = Extra_Base2Log(nValues); - assert( iBit < nBits ); - // count the number of literals - Counter = 0; - for ( v = 0; v < nValues; v++ ) - Counter += ( (v & (1 << iBit)) > 0 ); - // create the cover - vSop = Vec_StrAlloc( 100 ); - Vec_StrPrintStr( vSop, "d0\n" ); - if ( Counter > 1 ) - Vec_StrPrintStr( vSop, "(" ); - for ( v = 0; v < nValues; v++ ) - if ( v & (1 << iBit) ) - { - if ( fFirst ) - fFirst = 0; - else - Vec_StrPush( vSop, ',' ); - Vec_StrPrintNum( vSop, v ); - } - if ( Counter > 1 ) - Vec_StrPrintStr( vSop, ")" ); - Vec_StrPrintStr( vSop, " 1\n" ); - Vec_StrPush( vSop, 0 ); - pResult = Abc_SopRegister( pMan, Vec_StrArray(vSop) ); - Vec_StrFree( vSop ); - return pResult; -} - -/**Function************************************************************* - - Synopsis [Creates the decoder node.] - - Description [Produces MV-SOP for BLIF-MV representation.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -char * Abc_SopDecoderPos( Extra_MmFlex_t * pMan, int nValues ) +void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses, Vec_Int_t * vVars, Vec_Int_t * vTemp ) { - char * pResult; - Vec_Str_t * vSop; - int i, k; - assert( nValues > 1 ); - vSop = Vec_StrAlloc( 100 ); - for ( i = 0; i < nValues; i++ ) + char * pChar; + int i, RetValue; + // check the logic function of the node + for ( pChar = pClauses; *pChar; pChar++ ) { - for ( k = 0; k < nValues; k++ ) - { - if ( k == i ) - Vec_StrPrintStr( vSop, "1 " ); - else - Vec_StrPrintStr( vSop, "- " ); - } - Vec_StrPrintNum( vSop, i ); - Vec_StrPush( vSop, '\n' ); + // add the clause + vTemp->nSize = 0; + for ( i = 0; i < vVars->nSize; i++, pChar++ ) + if ( *pChar == '0' ) + Vec_IntPush( vTemp, toLit(vVars->pArray[i]) ); + else if ( *pChar == '1' ) + Vec_IntPush( vTemp, neg(toLit(vVars->pArray[i])) ); + // add the clause to the solver + RetValue = solver_addclause( pSat, vTemp->pArray, vTemp->pArray + vTemp->nSize ); + assert( RetValue != 1 ); + // check that the remainig part is fine + assert( *pChar == ' ' ); + pChar++; + assert( *pChar == '1' ); + pChar++; + assert( *pChar == '\n' ); } - Vec_StrPush( vSop, 0 ); - pResult = Abc_SopRegister( pMan, Vec_StrArray(vSop) ); - Vec_StrFree( vSop ); - return pResult; } -/**Function************************************************************* - - Synopsis [Creates the decover node.] - Description [Produces MV-SOP for BLIF-MV representation.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_SopDecoderLog( Extra_MmFlex_t * pMan, int nValues ) -{ - char * pResult; - Vec_Str_t * vSop; - int i, b, nBits = Extra_Base2Log(nValues); - assert( nValues > 1 && nValues <= (1<<nBits) ); - vSop = Vec_StrAlloc( 100 ); - for ( i = 0; i < nValues; i++ ) - { - for ( b = 0; b < nBits; b++ ) - { - Vec_StrPrintNum( vSop, (int)((i & (1 << b)) > 0) ); - Vec_StrPush( vSop, ' ' ); - } - Vec_StrPrintNum( vSop, i ); - Vec_StrPush( vSop, '\n' ); - } - Vec_StrPush( vSop, 0 ); - pResult = Abc_SopRegister( pMan, Vec_StrArray(vSop) ); - Vec_StrFree( vSop ); - return pResult; -} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index d3d32b98..7a6a705d 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -22,39 +22,19 @@ #include "main.h" #include "mio.h" #include "dec.h" -//#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fFanouts, bool fReference ); + //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Frees one attribute manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFreeMan ) -{ - void * pUserMan; - Vec_Att_t * pAttrMan; - pAttrMan = Vec_PtrEntry( pNtk->vAttrs, Attr ); - Vec_PtrWriteEntry( pNtk->vAttrs, Attr, NULL ); - pUserMan = Vec_AttFree( pAttrMan, fFreeMan ); - return pUserMan; -} - -/**Function************************************************************* - Synopsis [Increments the current traversal ID of the network.] Description [] @@ -68,7 +48,7 @@ void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; int i; - if ( pNtk->nTravIds >= (1<<30)-1 ) + if ( pNtk->nTravIds == (1<<12)-1 ) { pNtk->nTravIds = 0; Abc_NtkForEachObj( pNtk, pObj, i ) @@ -79,49 +59,6 @@ void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Order CI/COs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj, * pTerm; - int i, k; - Vec_PtrClear( pNtk->vCis ); - Vec_PtrClear( pNtk->vCos ); - Abc_NtkForEachPi( pNtk, pObj, i ) - Vec_PtrPush( pNtk->vCis, pObj ); - Abc_NtkForEachPo( pNtk, pObj, i ) - Vec_PtrPush( pNtk->vCos, pObj ); - Abc_NtkForEachAssert( pNtk, pObj, i ) - Vec_PtrPush( pNtk->vCos, pObj ); - Abc_NtkForEachBox( pNtk, pObj, i ) - { - if ( Abc_ObjIsLatch(pObj) ) - continue; - Abc_ObjForEachFanin( pObj, pTerm, k ) - Vec_PtrPush( pNtk->vCos, pTerm ); - Abc_ObjForEachFanout( pObj, pTerm, k ) - Vec_PtrPush( pNtk->vCis, pTerm ); - } - Abc_NtkForEachBox( pNtk, pObj, i ) - { - if ( !Abc_ObjIsLatch(pObj) ) - continue; - Abc_ObjForEachFanin( pObj, pTerm, k ) - Vec_PtrPush( pNtk->vCos, pTerm ); - Abc_ObjForEachFanout( pObj, pTerm, k ) - Vec_PtrPush( pNtk->vCis, pTerm ); - } -} - -/**Function************************************************************* - Synopsis [Reads the number of cubes of the node.] Description [] @@ -138,8 +75,6 @@ int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk ) assert( Abc_NtkHasSop(pNtk) ); Abc_NtkForEachNode( pNtk, pNode, i ) { - if ( Abc_NodeIsConst(pNode) ) - continue; assert( pNode->pData ); nCubes += Abc_SopGetCubeNum( pNode->pData ); } @@ -157,33 +92,6 @@ int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -int Abc_NtkGetCubePairNum( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int i, nCubes, nCubePairs = 0; - assert( Abc_NtkHasSop(pNtk) ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - if ( Abc_NodeIsConst(pNode) ) - continue; - assert( pNode->pData ); - nCubes = Abc_SopGetCubeNum( pNode->pData ); - nCubePairs += nCubes * (nCubes - 1) / 2; - } - return nCubePairs; -} - -/**Function************************************************************* - - Synopsis [Reads the number of literals in the SOPs of the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; @@ -245,36 +153,7 @@ int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk ) Abc_NtkForEachNode( pNtk, pNode, i ) { assert( pNode->pData ); - if ( Abc_ObjFaninNum(pNode) < 2 ) - continue; - nNodes += pNode->pData? -1 + 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_ObjFaninNum(pNode) < 2 ) - continue; -//printf( "%d ", Hop_DagSize( pNode->pData ) ); - nNodes += pNode->pData? Hop_DagSize( pNode->pData ) : 0; + nNodes += pNode->pData? Cudd_DagSize( pNode->pData ) : 0; } return nNodes; } @@ -339,12 +218,7 @@ double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk ) TotalArea = 0.0; Abc_NtkForEachNode( pNtk, pNode, i ) { -// assert( pNode->pData ); - if ( pNode->pData == NULL ) - { - printf( "Node without mapping is encountered.\n" ); - continue; - } + assert( pNode->pData ); TotalArea += Mio_GateReadArea( pNode->pData ); } return TotalArea; @@ -372,26 +246,6 @@ int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Counts the number of exors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int i, Counter = 0; - Abc_NtkForEachNode( pNtk, pNode, i ) - Counter += Abc_NodeIsMuxType(pNode); - return Counter; -} - -/**Function************************************************************* - Synopsis [Returns 1 if it is an AIG with choice nodes.] Description [] @@ -409,7 +263,7 @@ int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk ) return 0; Counter = 0; Abc_NtkForEachNode( pNtk, pNode, i ) - Counter += Abc_AigNodeIsChoice( pNode ); + Counter += Abc_NodeIsAigChoice( pNode ); return Counter; } @@ -438,26 +292,6 @@ int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Reads the total number of all fanins.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int i, nFanins = 0; - Abc_NtkForEachNode( pNtk, pNode, i ) - nFanins += Abc_ObjFaninNum(pNode); - return nFanins; -} - -/**Function************************************************************* - Synopsis [Cleans the copy field of all objects.] Description [] @@ -471,199 +305,19 @@ void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; int i; + i = 0; + // set the data filed to NULL Abc_NtkForEachObj( pNtk, pObj, i ) pObj->pCopy = NULL; } /**Function************************************************************* - Synopsis [Cleans the copy field of all objects.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCleanData( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->pData = NULL; -} - -/**Function************************************************************* - - Synopsis [Cleans the copy field of all objects.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCleanEquiv( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->pEquiv = NULL; -} - -/**Function************************************************************* - - Synopsis [Counts the number of nodes having non-trivial copies.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkCountCopy( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i, Counter = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( Abc_ObjIsNode(pObj) ) - Counter += (pObj->pCopy != NULL); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Saves copy field of the objects.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkSaveCopy( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vCopies; - Abc_Obj_t * pObj; - int i; - vCopies = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); - Abc_NtkForEachObj( pNtk, pObj, i ) - Vec_PtrWriteEntry( vCopies, i, pObj->pCopy ); - return vCopies; -} - -/**Function************************************************************* - - Synopsis [Loads copy field of the objects.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkLoadCopy( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCopies ) -{ - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->pCopy = Vec_PtrEntry( vCopies, i ); -} - -/**Function************************************************************* - - Synopsis [Cleans the copy field of all objects.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCleanNext( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->pNext = NULL; -} - -/**Function************************************************************* - - Synopsis [Cleans the copy field of all objects.] + Synopsis [Checks if the internal node has a unique CO.] - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->fMarkA = 0; -} - -/**Function************************************************************* - - Synopsis [Checks if the internal node has CO fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pFanout; - int i; - Abc_ObjForEachFanout( pNode, pFanout, i ) - if ( Abc_ObjIsCo(pFanout) ) - return pFanout; - return NULL; -} - -/**Function************************************************************* - - Synopsis [Checks if the internal node has CO fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pFanout; - int i; - Abc_ObjForEachFanout( pNode, pFanout, i ) - if ( !Abc_ObjIsCo(pFanout) ) - return pFanout; - return NULL; -} - -/**Function************************************************************* - - Synopsis [Checks if the internal node has CO drivers with the same name.] - - Description [Checks if the internal node can borrow its name from CO fanouts. - This is possible if all COs with non-complemented fanin edge pointing to this - node have the same name.] + Description [Checks if the internal node can borrow a name from a CO + fanout. This is possible if there is only one CO with non-complemented + fanin edge pointing to this node.] SideEffects [] @@ -673,73 +327,23 @@ Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode ) Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode ) { Abc_Obj_t * pFanout, * pFanoutCo; - int i; - pFanoutCo = NULL; + int i, Counter; + if ( !Abc_ObjIsNode(pNode) ) + return NULL; + Counter = 0; Abc_ObjForEachFanout( pNode, pFanout, i ) { - if ( !Abc_ObjIsCo(pFanout) ) - continue; - if ( Abc_ObjFaninC0(pFanout) ) - continue; - if ( pFanoutCo == NULL ) + if ( Abc_ObjIsCo(pFanout) && !Abc_ObjFaninC0(pFanout) ) { assert( Abc_ObjFaninNum(pFanout) == 1 ); assert( Abc_ObjFanin0(pFanout) == pNode ); pFanoutCo = pFanout; - continue; + Counter++; } - if ( strcmp( Abc_ObjName(pFanoutCo), Abc_ObjName(pFanout) ) ) // they have diff names - return NULL; } - return pFanoutCo; -} - -/**Function************************************************************* - - Synopsis [Fixes the CO driver problem.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fDuplicate ) -{ - Abc_Ntk_t * pNtk = pDriver->pNtk; - Abc_Obj_t * pDriverNew, * pFanin; - int k; - if ( fDuplicate && !Abc_ObjIsCi(pDriver) ) - { - pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 ); - Abc_ObjForEachFanin( pDriver, pFanin, k ) - Abc_ObjAddFanin( pDriverNew, pFanin ); - if ( Abc_ObjFaninC0(pNodeCo) ) - { - // change polarity of the duplicated driver - Abc_NodeComplement( pDriverNew ); - Abc_ObjXorFaninC( pNodeCo, 0 ); - } - } - else - { - // add inverters and buffers when necessary - if ( Abc_ObjFaninC0(pNodeCo) ) - { - pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver ); - Abc_ObjXorFaninC( pNodeCo, 0 ); - } - else - pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver ); - } - // update the fanin of the PO node - Abc_ObjPatchFanin( pNodeCo, pDriver, pDriverNew ); - assert( Abc_ObjFanoutNum(pDriverNew) == 1 ); - // remove the old driver if it dangles - // (this happens when the duplicated driver had only one complemented fanout) - if ( Abc_ObjFanoutNum(pDriver) == 0 ) - Abc_NtkDeleteObj( pDriver ); + if ( Counter == 1 ) + return pFanoutCo; + return NULL; } /**Function************************************************************* @@ -748,8 +352,9 @@ void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fD Description [The COs of a logic network are simple under three conditions: (1) The edge from CO to its driver is not complemented. - (2) If CI is a driver of a CO, they have the same name.] - (3) If two COs share the same driver, they have the same name.] + (2) No two COs share the same driver. + (3) The driver is not a CI unless the CI and the CO have the same name + (and so the inv/buf should not be written into a file).] SideEffects [] @@ -760,27 +365,19 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode, * pDriver; int i; - assert( Abc_NtkIsLogic(pNtk) ); + assert( !Abc_NtkIsNetlist(pNtk) ); + // check if there are complemented or idential POs Abc_NtkIncrementTravId( pNtk ); Abc_NtkForEachCo( pNtk, pNode, i ) { - // if the driver is complemented, this is an error pDriver = Abc_ObjFanin0(pNode); if ( Abc_ObjFaninC0(pNode) ) return 0; - // if the driver is a CI and has different name, this is an error - if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) ) + if ( Abc_NodeIsTravIdCurrent(pDriver) ) return 0; - // if the driver is visited for the first time, remember the CO name - if ( !Abc_NodeIsTravIdCurrent(pDriver) ) - { - pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode); - Abc_NodeSetTravIdCurrent(pDriver); - continue; - } - // the driver has second CO - if they have different name, this is an error - if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names + if ( Abc_ObjIsCi(pDriver) && strcmp( Abc_ObjName(pDriver), Abc_ObjName(pNode) ) != 0 ) return 0; + Abc_NodeSetTravIdCurrent(pDriver); } return 1; } @@ -790,9 +387,10 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ) Synopsis [Transforms the network to have simple COs.] Description [The COs of a logic network are simple under three conditions: - (1) The edge from CO to its driver is not complemented. - (2) If CI is a driver of a CO, they have the same name.] - (3) If two COs share the same driver, they have the same name. + (1) The edge from the CO to its driver is not complemented. + (2) No two COs share the same driver. + (3) The driver is not a CI unless the CI and the CO have the same name + (and so the inv/buf should not be written into a file). In some cases, such as FPGA mapping, we prevent the increase in delay by duplicating the driver nodes, rather than adding invs/bufs.] @@ -803,41 +401,63 @@ bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ) ***********************************************************************/ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate ) { - Abc_Obj_t * pNode, * pDriver; - int i, nDupGates = 0; + Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin; + int i, k, nDupGates = 0; assert( Abc_NtkIsLogic(pNtk) ); - Abc_NtkIncrementTravId( pNtk ); + // process the COs by adding inverters and buffers when necessary Abc_NtkForEachCo( pNtk, pNode, i ) { - // if the driver is complemented, this is an error pDriver = Abc_ObjFanin0(pNode); - if ( Abc_ObjFaninC0(pNode) ) + if ( Abc_ObjIsCi(pDriver) ) { - Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate ); - nDupGates++; - continue; + // skip the case when the driver is a different node with the same name + if ( pDriver != pNode && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) == 0 ) + { + assert( !Abc_ObjFaninC0(pNode) ); + continue; + } } - // if the driver is a CI and has different name, this is an error - if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) ) + else { - Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate ); - nDupGates++; - continue; + // skip the case when the driver's unique CO fanout is this CO + if ( Abc_NodeHasUniqueCoFanout(pDriver) == pNode ) + continue; } - // if the driver is visited for the first time, remember the CO name - if ( !Abc_NodeIsTravIdCurrent(pDriver) ) + if ( fDuplicate && !Abc_ObjIsCi(pDriver) ) { - pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode); - Abc_NodeSetTravIdCurrent(pDriver); - continue; + pDriverNew = Abc_NtkDupObj( pNtk, pDriver ); + Abc_ObjForEachFanin( pDriver, pFanin, k ) + Abc_ObjAddFanin( pDriverNew, pFanin ); + 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); + } } - // the driver has second CO - if they have different name, this is an error - if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names + else { - Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate ); - nDupGates++; - continue; + // add inverters and buffers when necessary + if ( Abc_ObjFaninC0(pNode) ) + { + pDriverNew = Abc_NodeCreateInv( pNtk, pDriver ); + Abc_ObjXorFaninC( pNode, 0 ); + } + else + pDriverNew = Abc_NodeCreateBuf( pNtk, pDriver ); } + // update the fanin of the PO node + Abc_ObjPatchFanin( pNode, pDriver, pDriverNew ); + assert( Abc_ObjFanoutNum(pDriverNew) == 1 ); + nDupGates++; + // remove the old driver if it dangles + if ( Abc_ObjFanoutNum(pDriver) == 0 ) + Abc_NtkDeleteObj( pDriver ); } assert( Abc_NtkLogicHasSimpleCos(pNtk) ); return nDupGates; @@ -891,7 +511,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_AigNodeIsAnd(pNode) ) + if ( !Abc_NodeIsAigAnd(pNode) ) return 0; // if the children are not complemented, this is not EXOR if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) ) @@ -924,7 +544,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_AigNodeIsAnd(pNode) ) + if ( !Abc_NodeIsAigAnd(pNode) ) return 0; // if the children are not complemented, this is not MUX if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) ) @@ -944,35 +564,6 @@ bool Abc_NodeIsMuxType( Abc_Obj_t * pNode ) /**Function************************************************************* - Synopsis [Returns 1 if the node is the control type of the MUX.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NodeIsMuxControlType( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pNode0, * pNode1; - // check that the node is regular - assert( !Abc_ObjIsComplement(pNode) ); - // skip the node that do not have two fanouts - if ( Abc_ObjFanoutNum(pNode) != 2 ) - return 0; - // get the fanouts - pNode0 = Abc_ObjFanout( pNode, 0 ); - pNode1 = Abc_ObjFanout( pNode, 1 ); - // if they have more than one fanout, we are not interested - if ( Abc_ObjFanoutNum(pNode0) != 1 || Abc_ObjFanoutNum(pNode1) != 1 ) - return 0; - // if the fanouts have the same fanout, this is MUX or EXOR (or a redundant gate (CA)(CB)) - return Abc_ObjFanout0(pNode0) == Abc_ObjFanout0(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. @@ -1082,7 +673,7 @@ int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc { int fCheck = 1; FILE * pFile; - Abc_Ntk_t * pNtk1, * pNtk2, * pNtkTemp; + Abc_Ntk_t * pNtk1, * pNtk2; int util_optind = 0; *pfDelete1 = 0; @@ -1107,8 +698,15 @@ int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc } else fclose( pFile ); - pNtk1 = pNtk; - pNtk2 = Io_Read( pNtk->pSpec, Io_ReadFileType(pNtk->pSpec), fCheck ); + + if ( Abc_NtkIsSeq(pNtk) ) + { + pNtk1 = Abc_NtkSeqToLogicSop(pNtk); + *pfDelete1 = 1; + } + else + pNtk1 = pNtk; + pNtk2 = Io_Read( pNtk->pSpec, fCheck ); if ( pNtk2 == NULL ) return 0; *pfDelete2 = 1; @@ -1120,18 +718,24 @@ int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc fprintf( pErr, "Empty current network.\n" ); return 0; } - pNtk1 = pNtk; - pNtk2 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck ); + if ( Abc_NtkIsSeq(pNtk) ) + { + pNtk1 = Abc_NtkSeqToLogicSop(pNtk); + *pfDelete1 = 1; + } + else + pNtk1 = pNtk; + pNtk2 = Io_Read( argv[util_optind], fCheck ); if ( pNtk2 == NULL ) return 0; *pfDelete2 = 1; } else if ( argc == util_optind + 2 ) { - pNtk1 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck ); + pNtk1 = Io_Read( argv[util_optind], fCheck ); if ( pNtk1 == NULL ) return 0; - pNtk2 = Io_Read( argv[util_optind+1], Io_ReadFileType(argv[util_optind+1]), fCheck ); + pNtk2 = Io_Read( argv[util_optind+1], fCheck ); if ( pNtk2 == NULL ) { Abc_NtkDelete( pNtk1 ); @@ -1145,25 +749,6 @@ int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc fprintf( pErr, "Wrong number of arguments.\n" ); return 0; } - - // make sure the networks are strashed - if ( !Abc_NtkIsStrash(pNtk1) ) - { - pNtkTemp = Abc_NtkStrash( pNtk1, 0, 1, 0 ); - if ( *pfDelete1 ) - Abc_NtkDelete( pNtk1 ); - pNtk1 = pNtkTemp; - *pfDelete1 = 1; - } - if ( !Abc_NtkIsStrash(pNtk2) ) - { - pNtkTemp = Abc_NtkStrash( pNtk2, 0, 1, 0 ); - if ( *pfDelete2 ) - Abc_NtkDelete( pNtk2 ); - pNtk2 = pNtkTemp; - *pfDelete2 = 1; - } - *ppNtk1 = pNtk1; *ppNtk2 = pNtk2; return 1; @@ -1185,7 +770,7 @@ void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) { Abc_Obj_t * pFanin; int i; - Vec_PtrClear(vNodes); + vNodes->nSize = 0; Abc_ObjForEachFanin( pNode, pFanin, i ) Vec_PtrPush( vNodes, pFanin ); } @@ -1205,36 +790,14 @@ void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) { Abc_Obj_t * pFanout; int i; - Vec_PtrClear(vNodes); + vNodes->nSize = 0; Abc_ObjForEachFanout( pNode, pFanout, i ) Vec_PtrPush( vNodes, pFanout ); } /**Function************************************************************* - Synopsis [Collects all latches in the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkCollectLatches( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vLatches; - Abc_Obj_t * pObj; - int i; - vLatches = Vec_PtrAlloc( 10 ); - Abc_NtkForEachObj( pNtk, pObj, i ) - Vec_PtrPush( vLatches, pObj ); - return vLatches; -} - -/**Function************************************************************* - - Synopsis [Procedure used for sorting the nodes in increasing order of levels.] + Synopsis [Procedure used for sorting the nodes in decreasing order of levels.] Description [] @@ -1320,461 +883,6 @@ Vec_Ptr_t * Abc_NtkCollectObjects( Abc_Ntk_t * pNtk ) return vNodes; } -/**Function************************************************************* - - Synopsis [Returns the array of CI IDs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NtkGetCiIds( Abc_Ntk_t * pNtk ) -{ - Vec_Int_t * vCiIds; - Abc_Obj_t * pObj; - int i; - vCiIds = Vec_IntAlloc( Abc_NtkCiNum(pNtk) ); - Abc_NtkForEachCi( pNtk, pObj, i ) - Vec_IntPush( vCiIds, pObj->Id ); - return vCiIds; -} - -/**Function************************************************************* - - Synopsis [Puts the nodes into the DFS order and reassign their IDs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkReassignIds( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Vec_Ptr_t * vObjsNew; - Abc_Obj_t * pNode, * pTemp, * pConst1; - int i, k; - assert( Abc_NtkIsStrash(pNtk) ); -//printf( "Total = %d. Current = %d.\n", Abc_NtkObjNumMax(pNtk), Abc_NtkObjNum(pNtk) ); - // start the array of objects with new IDs - vObjsNew = Vec_PtrAlloc( pNtk->nObjs ); - // put constant node first - pConst1 = Abc_AigConst1(pNtk); - assert( pConst1->Id == 0 ); - Vec_PtrPush( vObjsNew, pConst1 ); - // put PI nodes next - Abc_NtkForEachPi( pNtk, pNode, i ) - { - pNode->Id = Vec_PtrSize( vObjsNew ); - Vec_PtrPush( vObjsNew, pNode ); - } - // put PO nodes next - Abc_NtkForEachPo( pNtk, pNode, i ) - { - pNode->Id = Vec_PtrSize( vObjsNew ); - Vec_PtrPush( vObjsNew, pNode ); - } - // put assert nodes next - Abc_NtkForEachAssert( pNtk, pNode, i ) - { - pNode->Id = Vec_PtrSize( vObjsNew ); - Vec_PtrPush( vObjsNew, pNode ); - } - // put latches and their inputs/outputs next - Abc_NtkForEachBox( pNtk, pNode, i ) - { - pNode->Id = Vec_PtrSize( vObjsNew ); - Vec_PtrPush( vObjsNew, pNode ); - Abc_ObjForEachFanin( pNode, pTemp, k ) - { - pTemp->Id = Vec_PtrSize( vObjsNew ); - Vec_PtrPush( vObjsNew, pTemp ); - } - Abc_ObjForEachFanout( pNode, pTemp, k ) - { - pTemp->Id = Vec_PtrSize( vObjsNew ); - Vec_PtrPush( vObjsNew, pTemp ); - } - } - // finally, internal nodes in the DFS order - vNodes = Abc_AigDfs( pNtk, 1, 0 ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( pNode == pConst1 ) - continue; - pNode->Id = Vec_PtrSize( vObjsNew ); - Vec_PtrPush( vObjsNew, pNode ); - } - Vec_PtrFree( vNodes ); - assert( Vec_PtrSize(vObjsNew) == pNtk->nObjs ); - - // update the fanin/fanout arrays - Abc_NtkForEachObj( pNtk, pNode, i ) - { - Abc_ObjForEachFanin( pNode, pTemp, k ) - pNode->vFanins.pArray[k] = pTemp->Id; - Abc_ObjForEachFanout( pNode, pTemp, k ) - pNode->vFanouts.pArray[k] = pTemp->Id; - } - - // replace the array of objs - Vec_PtrFree( pNtk->vObjs ); - pNtk->vObjs = vObjsNew; - - // rehash the AIG - Abc_AigRehash( pNtk->pManFunc ); - - // update the name manager!!! -} - -/**Function************************************************************* - - Synopsis [Detect cases when non-trivial FF matching is possible.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDetectMatching( Abc_Ntk_t * pNtk ) -{ -/* - Abc_Obj_t * pLatch, * pFanin; - int i, nTFFs, nJKFFs; - nTFFs = nJKFFs = 0; - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - pFanin = Abc_ObjFanin0(pLatch); - if ( Abc_ObjFaninNum(pFanin) != 2 ) - continue; - if ( Abc_NodeIsExorType(pLatch) ) - { - if ( Abc_ObjFanin0(Abc_ObjFanin0(pFanin)) == pLatch || - Abc_ObjFanin1(Abc_ObjFanin0(pFanin)) == pLatch ) - nTFFs++; - } - if ( Abc_ObjFaninNum( Abc_ObjFanin0(pFanin) ) != 2 || - Abc_ObjFaninNum( Abc_ObjFanin1(pFanin) ) != 2 ) - continue; - - if ( (Abc_ObjFanin0(Abc_ObjFanin0(pFanin)) == pLatch || - Abc_ObjFanin1(Abc_ObjFanin0(pFanin)) == pLatch) && - (Abc_ObjFanin0(Abc_ObjFanin1(pFanin)) == pLatch || - Abc_ObjFanin1(Abc_ObjFanin1(pFanin)) == pLatch) ) - { - nJKFFs++; - } - } - printf( "D = %6d. T = %6d. JK = %6d. (%6.2f %%)\n", - Abc_NtkLatchNum(pNtk), nTFFs, nJKFFs, 100.0 * nJKFFs / Abc_NtkLatchNum(pNtk) ); -*/ -} - - -/**Function************************************************************* - - Synopsis [Compares the pointers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ObjPointerCompare( void ** pp1, void ** pp2 ) -{ - if ( *pp1 < *pp2 ) - return -1; - if ( *pp1 > *pp2 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Adjusts the copy pointers.] - - Description [This procedure assumes that the network was transformed - into another network, which was in turn transformed into yet another - network. It makes the pCopy pointers of the original network point to - the objects of the yet another network.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTransferCopy( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( !Abc_ObjIsNet(pObj) ) - pObj->pCopy = pObj->pCopy? Abc_ObjCopyCond(pObj->pCopy) : NULL; -} - - -/**Function************************************************************* - - Synopsis [Increaments the cut counter.] - - Description [Returns 1 if it becomes equal to the ref counter.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Abc_ObjCrossCutInc( Abc_Obj_t * pObj ) -{ -// pObj->pCopy = (void *)(((int)pObj->pCopy)++); - int Value = (int)pObj->pCopy; - pObj->pCopy = (void *)(Value + 1); - return (int)pObj->pCopy == Abc_ObjFanoutNum(pObj); -} - -/**Function************************************************************* - - Synopsis [Computes cross-cut of the circuit.] - - Description [Returns 1 if it is the last visit to the node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkCrossCut_rec( Abc_Obj_t * pObj, int * pnCutSize, int * pnCutSizeMax ) -{ - Abc_Obj_t * pFanin; - int i, nDecrem = 0; - int fReverse = 0; - if ( Abc_ObjIsCi(pObj) ) - return 0; - // if visited, increment visit counter - if ( Abc_NodeIsTravIdCurrent( pObj ) ) - return Abc_ObjCrossCutInc( pObj ); - Abc_NodeSetTravIdCurrent( pObj ); - // visit the fanins - if ( !Abc_ObjIsCi(pObj) ) - { - if ( fReverse ) - { - Abc_ObjForEachFanin( pObj, pFanin, i ) - { - pFanin = Abc_ObjFanin( pObj, Abc_ObjFaninNum(pObj) - 1 - i ); - nDecrem += Abc_NtkCrossCut_rec( pFanin, pnCutSize, pnCutSizeMax ); - } - } - else - { - Abc_ObjForEachFanin( pObj, pFanin, i ) - nDecrem += Abc_NtkCrossCut_rec( pFanin, pnCutSize, pnCutSizeMax ); - } - } - // count the node - (*pnCutSize)++; - if ( *pnCutSizeMax < *pnCutSize ) - *pnCutSizeMax = *pnCutSize; - (*pnCutSize) -= nDecrem; - return Abc_ObjCrossCutInc( pObj ); -} - -/**Function************************************************************* - - Synopsis [Computes cross-cut of the circuit.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkCrossCut( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int nCutSize = 0, nCutSizeMax = 0; - int i; - Abc_NtkCleanCopy( pNtk ); - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - Abc_NtkCrossCut_rec( pObj, &nCutSize, &nCutSizeMax ); - nCutSize--; - } - assert( nCutSize == 0 ); - printf( "Max cross cut size = %6d. Ratio = %6.2f %%\n", nCutSizeMax, 100.0 * nCutSizeMax/Abc_NtkObjNum(pNtk) ); - return nCutSizeMax; -} - - -/**Function************************************************************* - - Synopsis [Prints all 3-var functions.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrint256() -{ - FILE * pFile; - unsigned i; - pFile = fopen( "4varfs.txt", "w" ); - for ( i = 1; i < (1<<16)-1; i++ ) - { - fprintf( pFile, "read_truth " ); - Extra_PrintBinary( pFile, &i, 16 ); - fprintf( pFile, "; clp; st; w 1.blif; map; cec 1.blif\n" ); - } - fclose( pFile ); -} - - -static int * pSupps; - -/**Function************************************************************* - - Synopsis [Compares the supergates by their level.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkCompareConesCompare( int * pNum1, int * pNum2 ) -{ - if ( pSupps[*pNum1] > pSupps[*pNum2] ) - return -1; - if ( pSupps[*pNum1] < pSupps[*pNum2] ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Analyze choice node support.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCompareCones( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vSupp, * vNodes, * vReverse; - Abc_Obj_t * pObj, * pTemp; - int Iter, i, k, Counter, CounterCos, CounterCosNew; - int * pPerms; - - // sort COs by support size - pPerms = ALLOC( int, Abc_NtkCoNum(pNtk) ); - pSupps = ALLOC( int, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pPerms[i] = i; - vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); - pSupps[i] = Vec_PtrSize(vSupp); - Vec_PtrFree( vSupp ); - } - qsort( (void *)pPerms, Abc_NtkCoNum(pNtk), sizeof(int), (int (*)(const void *, const void *)) Abc_NtkCompareConesCompare ); - - // consider COs in this order - Iter = 0; - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pObj = Abc_NtkCo( pNtk, pPerms[i] ); - if ( pObj->fMarkA ) - continue; - Iter++; - - vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); - vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); - vReverse = Abc_NtkDfsReverseNodesContained( pNtk, (Abc_Obj_t **)Vec_PtrArray(vSupp), Vec_PtrSize(vSupp) ); - // count the number of nodes in the reverse cone - Counter = 0; - for ( k = 1; k < Vec_PtrSize(vReverse) - 1; k++ ) - for ( pTemp = Vec_PtrEntry(vReverse, k); pTemp; pTemp = pTemp->pCopy ) - Counter++; - CounterCos = CounterCosNew = 0; - for ( pTemp = Vec_PtrEntryLast(vReverse); pTemp; pTemp = pTemp->pCopy ) - { - assert( Abc_ObjIsCo(pTemp) ); - CounterCos++; - if ( pTemp->fMarkA == 0 ) - CounterCosNew++; - pTemp->fMarkA = 1; - } - // print statistics - printf( "%4d CO %5d : Supp = %5d. Lev = %3d. Cone = %5d. Rev = %5d. COs = %3d (%3d).\n", - Iter, pPerms[i], Vec_PtrSize(vSupp), Abc_ObjLevel(Abc_ObjFanin0(pObj)), Vec_PtrSize(vNodes), Counter, CounterCos, CounterCosNew ); - - // free arrays - Vec_PtrFree( vSupp ); - Vec_PtrFree( vNodes ); - Vec_PtrFree( vReverse ); - - if ( Vec_PtrSize(vSupp) < 10 ) - break; - } - Abc_NtkForEachCo( pNtk, pObj, i ) - pObj->fMarkA = 0; - - free( pPerms ); - free( pSupps ); -} - -/**Function************************************************************* - - Synopsis [Analyze choice node support.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCompareSupports( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vSupp; - Abc_Obj_t * pObj, * pTemp; - int i, nNodesOld; - assert( Abc_NtkIsStrash(pNtk) ); - Abc_AigForEachAnd( pNtk, pObj, i ) - { - if ( !Abc_AigNodeIsChoice(pObj) ) - continue; - - vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); - nNodesOld = Vec_PtrSize(vSupp); - Vec_PtrFree( vSupp ); - - for ( pTemp = pObj->pData; pTemp; pTemp = pTemp->pData ) - { - vSupp = Abc_NtkNodeSupport( pNtk, &pTemp, 1 ); - if ( nNodesOld != Vec_PtrSize(vSupp) ) - printf( "Choice orig = %3d Choice new = %3d\n", nNodesOld, Vec_PtrSize(vSupp) ); - Vec_PtrFree( vSupp ); - } - } -} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/abc/abc_.c b/src/base/abc/abc_.c index 50558bdb..bef3836f 100644 --- a/src/base/abc/abc_.c +++ b/src/base/abc/abc_.c @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/base/abc/module.make b/src/base/abc/module.make index 7b34d8f6..649e71a2 100644 --- a/src/base/abc/module.make +++ b/src/base/abc/module.make @@ -1,12 +1,9 @@ SRC += src/base/abc/abcAig.c \ - src/base/abc/abcBlifMv.c \ src/base/abc/abcCheck.c \ src/base/abc/abcDfs.c \ src/base/abc/abcFanio.c \ src/base/abc/abcFunc.c \ - src/base/abc/abcHie.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 \ |