diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2006-06-11 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2006-06-11 08:01:00 -0700 |
commit | 3db1557f45b03875a0a0b8adddcc15c4565895d2 (patch) | |
tree | 2896d20ddcb85ae4aa7245ca28bc585f567fea54 /src | |
parent | 7d0921330b1f4e789901b4c2450920e7c412f95f (diff) | |
download | abc-3db1557f45b03875a0a0b8adddcc15c4565895d2.tar.gz abc-3db1557f45b03875a0a0b8adddcc15c4565895d2.tar.bz2 abc-3db1557f45b03875a0a0b8adddcc15c4565895d2.zip |
Version abc60611
Diffstat (limited to 'src')
129 files changed, 10550 insertions, 3904 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 1fb57f67..29a95e46 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -53,7 +53,6 @@ typedef enum { 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_SEQ, // 4: sequential AIG (two input AND gates with c- and latch-attributes on edges) - ABC_NTK_BLACKBOX, // 5: black box about which nothing is known ABC_NTK_OTHER // 6: unused } Abc_NtkType_t; @@ -89,8 +88,9 @@ typedef enum { ABC_OBJ_LATCH, // 3: latch ABC_OBJ_PI, // 4: primary input terminal ABC_OBJ_PO, // 5: primary output terminal - ABC_OBJ_BOX, // 6: abstract box - ABC_OBJ_OTHER // 7: unused + ABC_OBJ_ASSERT, // 6: assertion output + ABC_OBJ_BOX, // 7: box + ABC_OBJ_OTHER // 8: unused } Abc_ObjType_t; // latch initial values @@ -107,9 +107,11 @@ typedef enum { //////////////////////////////////////////////////////////////////////// //typedef int bool; +#ifndef __cplusplus #ifndef bool #define bool int #endif +#endif typedef struct Abc_Obj_t_ Abc_Obj_t; typedef struct Abc_Ntk_t_ Abc_Ntk_t; @@ -120,101 +122,82 @@ 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 + Abc_Ntk_t * pNtk; // the host network + int Id; // the object ID // internal information - unsigned Type : 3; // 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 fCompl0 : 1; // complemented attribute of the first fanin in the AIG - unsigned fCompl1 : 1; // complemented attribute of the second fanin in the AIG - unsigned TravId : 10; // the traversal ID (if changed, update Abc_NtkIncrementTravId) - unsigned Level : 12; // the level of the node + unsigned Type : 3; // 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 TravId : 9; // the traversal ID (if changed, update Abc_NtkIncrementTravId) + unsigned Level : 12; // the level of the node // connectivity - Vec_Int_t vFanins; // the array of fanins - Vec_Int_t vFanouts; // the array of fanouts + Vec_Int_t vFanins; // the array of fanins + Vec_Int_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 + 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 - int Id; // network ID - // 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 + 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 + int Id; // network ID + Nm_Man_t * pManName; // name manager (stores names of objects) // components of the network - 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 * vAsserts; // the array of assertions - Vec_Ptr_t * vLats; // the array of latches (or the cutset in the sequential network) - Vec_Ptr_t * vCutSet; // the array of cutset nodes (used in the sequential AIG) - // the stats about the number of living objects - int nObjs; // the number of live objs - int nNets; // the number of live nets - int nNodes; // the number of live nodes - int nBoxes; // the number of live nodes - int nLatches; // the number of live latches - int nPis; // the number of primary inputs - int nPos; // the number of primary outputs - int nAsserts; // the number of assertion 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 satisfiable assignment of the miter - int * pModel; - // the external don't-care if given - Abc_Ntk_t * pExdc; // the EXDC network - // miscellaneous data members - 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 - // name manager - Nm_Man_t * pManName; + Vec_Ptr_t * vObjs; // the array of all objects (net, nodes, latches, etc) + 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 * vPis; // the array of PIs + Vec_Ptr_t * vPos; // the array of POs + Vec_Ptr_t * vLatches; // the array of latches (or the cutset in the sequential network) + Vec_Ptr_t * vAsserts; // the array of assertions + Vec_Ptr_t * vCutSet; // the array of cutset nodes (used in the sequential AIG) + // the number of living objects + int nObjs; // the number of live objs + int nNets; // the number of live nets + int nNodes; // the number of live nodes + int nBoxes; // the number of live nodes // 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 - // hierarchical design - stmm_table * tName2Model; // the table hashing names into network pointers (or NULL if no hierarchy) - Vec_Int_t * pBlackBoxes; // stores pairs (PI num, PO num) for each model, including the base model (or NULL if no hierarchy) - short fHieVisited; // flag to mark the visited network - short fHiePath; // flag to mark the network on the path - // 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 + Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network + int iStep; // the generation number for the given network + // hierarchy + stmm_table * tName2Model; // the table hashing names into network pointers (or NULL if no hierarchy) + Vec_Int_t * pBlackBoxes; // stores pairs (PI num, PO num) for each model, including the base model (or NULL if no hierarchy) + short fHieVisited; // flag to mark the visited network + short fHiePath; // flag to mark the network on the path + // miscellaneous data members + unsigned 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) + void * pManGlob; // the global BDD manager + Vec_Ptr_t * vFuncsGlob; // the global BDDs of CO functions + 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) + Abc_Ntk_t * pExdc; // the EXDC network (if given) }; //////////////////////////////////////////////////////////////////////// @@ -236,7 +219,6 @@ static inline bool Abc_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pN 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_NtkIsSeq( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_SEQ; } -static inline bool Abc_NtkIsBlackbox( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_BLACKBOX;} 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; } @@ -249,7 +231,7 @@ static inline bool Abc_NtkIsMappedNetlist( Abc_Ntk_t * pNtk ) { return pN 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_NtkIsMappedLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_LOGIC ; } -static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return pNtk->nLatches == 0; } +static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vLatches) == 0; } // reading data members of the network static inline char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; } @@ -258,7 +240,7 @@ static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pN static inline Abc_Ntk_t * Abc_NtkExdc( Abc_Ntk_t * pNtk ) { return pNtk->pExdc; } static inline Abc_Ntk_t * Abc_NtkBackup( Abc_Ntk_t * pNtk ) { return pNtk->pNetBackup; } static inline int Abc_NtkStep ( Abc_Ntk_t * pNtk ) { return pNtk->iStep; } -static inline Abc_Obj_t * Abc_NtkConst1( Abc_Ntk_t * pNtk ) { return pNtk->vObjs->pArray[0]; } +static inline Abc_Obj_t * Abc_NtkConst1( Abc_Ntk_t * pNtk ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vObjs, 0 ); } // setting data members of the network static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; } @@ -267,25 +249,27 @@ 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_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_NtkCutSetNodeNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCutSet); } -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; } +static inline int Abc_NtkObjNumMax( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vObjs); } +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 Vec_PtrSize(pNtk->vLatches); } +static inline int Abc_NtkAssertNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vAsserts); } +static inline int Abc_NtkCutSetNodeNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCutSet); } +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); } // reading objects -static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vObjs, i ); } -static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vLats, i ); } -static inline Abc_Obj_t * Abc_NtkCutSetNode( Abc_Ntk_t * pNtk, int i){ return Vec_PtrEntry( pNtk->vCutSet, i ); } -static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vCis, i ); } -static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vCos, i ); } -static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPiNum(pNtk) ); return Abc_NtkCi( pNtk, i ); } -static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPoNum(pNtk) ); return Abc_NtkCo( pNtk, i ); } +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_NtkLatch( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vLatches, 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_NtkCutSetNode( Abc_Ntk_t * pNtk, int i){ return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCutSet, 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_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 ); } // reading data members of the object static inline unsigned Abc_ObjType( Abc_Obj_t * pObj ) { return pObj->Type; } @@ -298,26 +282,27 @@ static inline Abc_Ntk_t * Abc_ObjNtk( Abc_Obj_t * pObj ) { return pO static inline void * Abc_ObjData( Abc_Obj_t * pObj ) { return pObj->pData; } // setting data members of the network -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)); } +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)); } // checking the object type static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; } static inline bool Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BOX; } static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; } static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH; } +static inline bool Abc_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; } static inline bool Abc_ObjIsPi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI; } static inline bool Abc_ObjIsPo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO; } static inline bool Abc_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; } +static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; } +static inline bool Abc_ObjIsCio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; } // working with fanin/fanout edges static inline int Abc_ObjFaninNum( Abc_Obj_t * pObj ) { return pObj->vFanins.nSize; } @@ -331,8 +316,8 @@ static inline Abc_Obj_t * Abc_ObjFanout0( Abc_Obj_t * pObj ) { return (A 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_Obj_t *)(Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanin0(pObj) : pObj); } -static inline Abc_Obj_t * Abc_ObjFanout0Ntk( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)(Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanout0(pObj) : pObj); } +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; } @@ -354,6 +339,11 @@ extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode ); extern bool Abc_NodeIsBuf( Abc_Obj_t * pNode ); extern bool Abc_NodeIsInv( Abc_Obj_t * pNode ); +// handling persistent nodes +static inline int Abc_NodeIsPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); return pNode->fPersist; } +static inline void Abc_NodeSetPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); pNode->fPersist = 1; } +static inline void Abc_NodeClearPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); pNode->fPersist = 0; } + // working with the traversal ID static inline void Abc_NodeSetTravId( Abc_Obj_t * pNode, int TravId ) { pNode->TravId = TravId; } static inline void Abc_NodeSetTravIdCurrent( Abc_Obj_t * pNode ) { pNode->TravId = pNode->pNtk->nTravIds; } @@ -386,28 +376,29 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab #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_NtkForEachLatch( pNtk, pLatch, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vLats)) && (((pLatch) = Abc_NtkLatch(pNtk, i)), 1); i++ )\ - if ( (pLatch) == NULL ) {} 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_NtkForEachBox( pNtk, pNode, i ) \ - for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ - if ( (pNode) == NULL || !Abc_ObjIsBox(pNode) ) {} else #define Abc_AigForEachAnd( pNtk, pNode, i ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ if ( (pNode) == NULL || !Abc_NodeIsAigAnd(pNode) ) {} else +#define Abc_NtkForEachBox( pNtk, pNode, i ) \ + for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ + if ( (pNode) == NULL || !Abc_ObjIsBox(pNode) ) {} else #define Abc_SeqForEachCutsetNode( pNtk, pNode, i ) \ for ( i = 0; (i < Abc_NtkCutSetNodeNum(pNtk)) && (((pNode) = Abc_NtkCutSetNode(pNtk, i)), 1); i++ )\ if ( (pNode) == NULL ) {} else // inputs and outputs #define Abc_NtkForEachPi( pNtk, pPi, i ) \ for ( i = 0; (i < Abc_NtkPiNum(pNtk)) && (((pPi) = Abc_NtkPi(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachPo( pNtk, pPo, i ) \ - for ( i = 0; (i < Abc_NtkPoNum(pNtk)) && (((pPo) = Abc_NtkPo(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 ) \ + for ( i = 0; (i < Abc_NtkPoNum(pNtk)) && (((pPo) = Abc_NtkPo(pNtk, i)), 1); i++ ) +#define Abc_NtkForEachAssert( pNtk, pAssert, i ) \ + for ( i = 0; (i < Vec_PtrSize((pNtk)->vAsserts)) && (((pAssert) = Abc_NtkAssert(pNtk, i)), 1); i++ ) +#define Abc_NtkForEachLatch( pNtk, pLatch, i ) \ + for ( i = 0; (i < Vec_PtrSize((pNtk)->vLatches)) && (((pLatch) = Abc_NtkLatch(pNtk, i)), 1); i++ ) #define Abc_NtkForEachCo( pNtk, pCo, i ) \ for ( i = 0; (i < Abc_NtkCoNum(pNtk)) && (((pCo) = Abc_NtkCo(pNtk, i)), 1); i++ ) // fanin and fanouts @@ -533,6 +524,7 @@ extern Abc_Obj_t * Abc_NtkCreateBox( 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_NtkCreateAssert( 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 ); @@ -545,8 +537,6 @@ 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 ); /*=== 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_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix ); extern char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits ); @@ -562,6 +552,7 @@ extern int Abc_NodeCompareNames( Abc_Obj_t ** pp1, Abc_Obj_t ** p 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_NtkAddDummyLatchNames( Abc_Ntk_t * pNtk ); extern void Abc_NtkShortNames( Abc_Ntk_t * pNtk ); /*=== abcNetlist.c ==========================================================*/ @@ -581,8 +572,6 @@ 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_NtkStartFromDual( 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 ); @@ -627,7 +616,7 @@ extern int Abc_NodeRef_rec( Abc_Obj_t * pNode ); extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor ); extern DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld ); /*=== abcSat.c ==========================================================*/ -extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFront, int fVerbose ); +extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fJFront, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects ); extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront ); /*=== abcSop.c ==========================================================*/ extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName ); @@ -646,6 +635,7 @@ 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 int Abc_SopGetCubeNum( char * pSop ); extern int Abc_SopGetLitNum( char * pSop ); extern int Abc_SopGetVarNum( char * pSop ); @@ -709,6 +699,7 @@ extern int Abc_HManPopulate( Abc_Ntk_t * pNtk ); extern int Abc_HManVerify( int NtkIdOld, int NtkIdNew ); /*=== abcUtil.c ==========================================================*/ extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk ); +extern void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk ); diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c index 49e0e825..af6f4ef7 100644 --- a/src/base/abc/abcCheck.c +++ b/src/base/abc/abcCheck.c @@ -92,7 +92,8 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) Abc_Obj_t * pObj, * pNet, * pNode; int i; - if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) && !Abc_NtkIsBlackbox(pNtk) ) + // check network types + if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) ) { fprintf( stdout, "NetworkCheck: Unknown network type.\n" ); return 0; @@ -111,6 +112,22 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * 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_ObjAdd() 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_ObjAdd() and in the user's code.\n" ); + return 0; + } + // check the names if ( !Abc_NtkCheckNames( pNtk ) ) return 0; @@ -181,14 +198,7 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) // check the EXDC network if present if ( pNtk->pExdc ) - { -// if ( pNtk->Type != pNtk->pExdc->Type ) -// { -// fprintf( stdout, "NetworkCheck: Network and its EXDC have different types.\n" ); -// return 0; -// } - return Abc_NtkCheck( pNtk->pExdc ); - } + Abc_NtkCheck( pNtk->pExdc ); // check the hierarchy if ( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model ) @@ -226,76 +236,60 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) ***********************************************************************/ bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk ) { - stmm_generator * gen; - Abc_Obj_t * pNet, * pNet2, * pObj; + Abc_Obj_t * pObj; + Vec_Int_t * vNameIds; char * pName; - int i; + int i, NameId; - if ( Abc_NtkIsNetlist(pNtk) ) + // check that each CI/CO has a name + Abc_NtkForEachCi( pNtk, pObj, i ) { -/* - // check that the nets in the table are also in the network - stmm_foreach_item( pNtk->tName2Net, gen, &pName, (char**)&pNet ) + pObj = Abc_ObjFanout0Ntk(pObj); + if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) == NULL ) { - 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; - } + fprintf( stdout, "NetworkCheck: CI with ID %d is in the network but not in the name table.\n", pObj->Id ); + return 0; } -*/ } -/* - // check PI/PO/latch names - Abc_NtkForEachPi( pNtk, pObj, i ) + Abc_NtkForEachCo( pNtk, pObj, i ) { - 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 ) ) + if ( Abc_ObjIsLatch(pObj) ) + continue; + pObj = Abc_ObjFanin0Ntk(pObj); + if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) == NULL ) { - fprintf( stdout, "NetworkCheck: PI \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) ); + fprintf( stdout, "NetworkCheck: CO with ID %d is in the network but not in the name table.\n", pObj->Id ); return 0; } } - Abc_NtkForEachPo( pNtk, pObj, i ) + + if ( Abc_NtkIsNetlist(pNtk) ) { - 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 ) ) + Abc_NtkForEachNet( pNtk, pObj, i ) { - fprintf( stdout, "NetworkCheck: PO \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) ); - return 0; + pName = Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id); + if ( pObj->pData && strcmp( pName, pObj->pData ) != 0 ) + { + fprintf( stdout, "NetworkCheck: Net \"%s\" has different name in the name table and at the data pointer.\n", pObj->pData ); + return 0; + } } } - Abc_NtkForEachLatch( pNtk, pObj, i ) + + // 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 ) { - if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &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 ) ) + if ( Vec_PtrEntry( pNtk->vObjs, NameId ) == NULL ) { - fprintf( stdout, "NetworkCheck: Latch \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) ); + 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 ); return 0; } } -*/ + Vec_IntFree( vNameIds ); return 1; } @@ -316,12 +310,6 @@ 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 ) { @@ -370,12 +358,6 @@ 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 ) { @@ -582,7 +564,7 @@ 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) ) + if ( pNtk->vLatches->nSize != Abc_NtkLatchNum(pNtk) ) { fprintf( stdout, "NetworkCheck: Incorrect size of the latch array.\n" ); return 0; @@ -759,7 +741,7 @@ int Abc_NtkIsAcyclicHierarchy_rec( Abc_Ntk_t * pNtk ) return 1; pNtk->fHieVisited = 1; // return if black box - if ( Abc_NtkIsBlackbox(pNtk) ) + if ( Abc_NtkHasBlackbox(pNtk) ) return 1; assert( Abc_NtkIsNetlist(pNtk) ); // go through all the children networks diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c index bd707c25..79669657 100644 --- a/src/base/abc/abcDfs.c +++ b/src/base/abc/abcDfs.c @@ -579,7 +579,7 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode ) Abc_Obj_t * pFanin; int fAcyclic, i; assert( !Abc_ObjIsNet(pNode) ); - if ( Abc_ObjIsCi(pNode) ) + if ( Abc_ObjIsCi(pNode) || Abc_ObjIsBox(pNode) ) return 1; assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) ); // make sure the node is not visited @@ -607,7 +607,7 @@ 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(pNode) ); + fprintf( stdout, " <-- %s", Abc_ObjName(Abc_ObjFanout0(pFanin)) ); return 0; } // mark this node as a visited node diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c index 60e847d0..2a84212e 100644 --- a/src/base/abc/abcFanio.c +++ b/src/base/abc/abcFanio.c @@ -50,7 +50,7 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id ); if ( Abc_ObjIsComplement(pFanin) ) Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 ); - Abc_HManAddFanin( pObj, pFanin ); +// Abc_HManAddFanin( pObj, pFanin ); } @@ -179,7 +179,7 @@ void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFa ***********************************************************************/ void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo ) { - Vec_Ptr_t * vFanouts = pNodeFrom->pNtk->vPtrTemp; + Vec_Ptr_t * vFanouts; int nFanoutsOld, i; assert( !Abc_ObjIsComplement(pNodeFrom) ); assert( !Abc_ObjIsComplement(pNodeTo) ); @@ -190,12 +190,14 @@ void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * 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************************************************************* diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c index 85dd9d8e..610e311a 100644 --- a/src/base/abc/abcLatch.c +++ b/src/base/abc/abcLatch.c @@ -155,9 +155,6 @@ void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches ) pLatch = Abc_NtkCreateLatch( pNtk ); Abc_ObjAddFanin( pLatch, pFanin ); Abc_LatchSetInitDc( pLatch ); - // add the latch to the CI/CO lists - Vec_PtrPush( pNtk->vCis, pLatch ); - Vec_PtrPush( pNtk->vCos, pLatch ); // create the name of the new latch Abc_NtkLogicStoreName( pLatch, Abc_ObjNameDummy("LL", i*nLatches + k, nDigits) ); } diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c index cf5ad320..604dd96e 100644 --- a/src/base/abc/abcMinBase.c +++ b/src/base/abc/abcMinBase.c @@ -65,8 +65,8 @@ int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk ) ***********************************************************************/ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) { - Vec_Str_t * vSupport = pNode->pNtk->vStrTemp; - Vec_Ptr_t * vFanins = pNode->pNtk->vPtrTemp; + Vec_Str_t * vSupport; + Vec_Ptr_t * vFanins; DdNode * bTemp; int i, nVars; @@ -74,11 +74,16 @@ 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 ) @@ -88,6 +93,8 @@ 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; } diff --git a/src/base/abc/abcNames.c b/src/base/abc/abcNames.c index f9fbe9db..4ddd2061 100644 --- a/src/base/abc/abcNames.c +++ b/src/base/abc/abcNames.c @@ -30,55 +30,6 @@ /**Function************************************************************* - Synopsis [Registers the name with the string memory manager.] - - 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_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName ) -{ -/* - char * pRegName; - if ( pName == NULL ) return NULL; - pRegName = Extra_MmFlexEntryFetch( pNtk->pMmNames, strlen(pName) + 1 ); - strcpy( pRegName, pName ); - return pRegName; -*/ - return NULL; -} - -/**Function************************************************************* - - Synopsis [Registers the name with the string memory manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix ) -{ -/* - char * pRegName; - assert( pName && pSuffix ); - pRegName = Extra_MmFlexEntryFetch( pNtk->pMmNames, strlen(pName) + strlen(pSuffix) + 1 ); - sprintf( pRegName, "%s%s", pName, pSuffix ); - return pRegName; -*/ - return NULL; -} - -/**Function************************************************************* - Synopsis [Gets the long name of the object.] Description [The temporary name is stored in a static buffer inside this @@ -176,20 +127,7 @@ char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits ) ***********************************************************************/ 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; -*/ - Nm_ManStoreIdName( pObjNew->pNtk->pManName, pObjNew->Id, pNameOld, NULL ); - return NULL; + return Nm_ManStoreIdName( pObjNew->pNtk->pManName, pObjNew->Id, pNameOld, NULL ); } /**Function************************************************************* @@ -205,21 +143,7 @@ char * Abc_NtkLogicStoreName( Abc_Obj_t * pObjNew, char * pNameOld ) ***********************************************************************/ char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pObjNew, char * pNameOld, char * pSuffix ) { -/* - 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; -*/ - Nm_ManStoreIdName( pObjNew->pNtk->pManName, pObjNew->Id, pNameOld, pSuffix ); - return NULL; + return Nm_ManStoreIdName( pObjNew->pNtk->pManName, pObjNew->Id, pNameOld, pSuffix ); } /**Function************************************************************* @@ -239,17 +163,20 @@ void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) int i; assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) ); assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) ); + assert( Abc_NtkAssertNum(pNtk) == Abc_NtkAssertNum(pNtkNew) ); assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) ); -// assert( st_count(pNtk->tObj2Name) > 0 ); -// assert( st_count(pNtkNew->tObj2Name) == 0 ); + assert( Nm_ManNumEntries(pNtk->pManName) > 0 ); + assert( Nm_ManNumEntries(pNtkNew->pManName) == 0 ); // copy the CI/CO names if given Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) ); + Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) ); Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(Abc_ObjFanin0Ntk(pObj)) ); + Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(Abc_ObjFanin0Ntk(pObj)) ); + Abc_NtkForEachAssert( pNtk, pObj, i ) + Abc_NtkLogicStoreName( Abc_NtkAssert(pNtkNew,i), Abc_ObjName(Abc_ObjFanin0Ntk(pObj)) ); if ( !Abc_NtkIsSeq(pNtk) ) Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) ); + Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) ); } /**Function************************************************************* @@ -270,8 +197,8 @@ void Abc_NtkDupCioNamesTableDual( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) ); assert( Abc_NtkPoNum(pNtk) * 2 == Abc_NtkPoNum(pNtkNew) ); assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) ); -// assert( st_count(pNtk->tObj2Name) > 0 ); -// assert( st_count(pNtkNew->tObj2Name) == 0 ); + assert( Nm_ManNumEntries(pNtk->pManName) > 0 ); + assert( Nm_ManNumEntries(pNtkNew->pManName) == 0 ); // copy the CI/CO names if given Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pObj) ); @@ -280,6 +207,8 @@ void Abc_NtkDupCioNamesTableDual( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) Abc_NtkLogicStoreNamePlus( Abc_NtkPo(pNtkNew,2*i+0), Abc_ObjName(pObj), "_pos" ); Abc_NtkLogicStoreNamePlus( Abc_NtkPo(pNtkNew,2*i+1), Abc_ObjName(pObj), "_neg" ); } + Abc_NtkForEachAssert( pNtk, pObj, i ) + Abc_NtkLogicStoreName( Abc_NtkAssert(pNtkNew,i), Abc_ObjName(pObj) ); if ( !Abc_NtkIsSeq(pNtk) ) Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(pObj) ); @@ -439,22 +368,16 @@ void Abc_NtkOrderObjsByName( Abc_Ntk_t * pNtk, int fComb ) Abc_NtkForEachLatch( pNtk, pObj, i ) pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj); // order objects alphabetically - qsort( pNtk->vCis->pArray, pNtk->nPis, sizeof(Abc_Obj_t *), + qsort( (void *)Vec_PtrArray(pNtk->vPis), Vec_PtrSize(pNtk->vPis), sizeof(Abc_Obj_t *), (int (*)(const void *, const void *)) Abc_NodeCompareNames ); - qsort( pNtk->vCos->pArray, pNtk->nPos, sizeof(Abc_Obj_t *), + qsort( (void *)Vec_PtrArray(pNtk->vPos), Vec_PtrSize(pNtk->vPos), 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( pNtk->vLats->pArray, pNtk->nLatches, sizeof(Abc_Obj_t *), + qsort( (void *)Vec_PtrArray(pNtk->vLatches), Vec_PtrSize(pNtk->vLatches), sizeof(Abc_Obj_t *), (int (*)(const void *, const void *)) Abc_NodeCompareNames ); - // 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 ); - } - } + // order CIs/COs first PIs/POs(Asserts) then latches + Abc_NtkOrderCisCos( pNtk ); // clean the copy fields Abc_NtkForEachPi( pNtk, pObj, i ) pObj->pCopy = NULL; @@ -515,6 +438,26 @@ void Abc_NtkAddDummyPoNames( Abc_Ntk_t * pNtk ) 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_NtkLogicStoreName( pObj, Abc_ObjNameDummy("a", i, nDigits) ); +} + +/**Function************************************************************* + + Synopsis [Adds dummy names.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ void Abc_NtkAddDummyLatchNames( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; @@ -537,13 +480,11 @@ void Abc_NtkAddDummyLatchNames( Abc_Ntk_t * pNtk ) ***********************************************************************/ void Abc_NtkShortNames( Abc_Ntk_t * pNtk ) { -// stmm_free_table( pNtk->tObj2Name ); -// pNtk->tObj2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash); Nm_ManFree( pNtk->pManName ); - pNtk->pManName = Nm_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) + 10 ); - + pNtk->pManName = Nm_ManCreate( Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk) - Abc_NtkLatchNum(pNtk) + 10 ); Abc_NtkAddDummyPiNames( pNtk ); Abc_NtkAddDummyPoNames( pNtk ); + Abc_NtkAddDummyAssertNames( pNtk ); Abc_NtkAddDummyLatchNames( pNtk ); } diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c index 75f3ed33..7d4460bf 100644 --- a/src/base/abc/abcNetlist.c +++ b/src/base/abc/abcNetlist.c @@ -106,33 +106,22 @@ Abc_Ntk_t * Abc_NtkNetlistToLogicHie( Abc_Ntk_t * pNtk ) // clean the node copy fields Abc_NtkForEachNode( pNtk, pObj, i ) pObj->pCopy = NULL; - // map the constant nodes - if ( Abc_NtkConst1(pNtk) ) - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); - // clone PIs/POs and make old nets point to new terminals; create PI/PO names - Abc_NtkForEachPi( pNtk, pObj, i ) + // clone PIs/POs/latches and make old nets point to new terminals; create names + Abc_NtkForEachCi( pNtk, pObj, i ) { Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj(pNtkNew, pObj); - Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(Abc_ObjFanout0(pObj)) ); } Abc_NtkForEachPo( pNtk, pObj, i ) { Abc_NtkDupObj(pNtkNew, pObj); - Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(Abc_ObjFanin0(pObj)) ); } // recursively flatten hierarchy, create internal logic, add new PI/PO names if there are black boxes Abc_NtkNetlistToLogicHie_rec( pNtkNew, pNtk, &Counter ); if ( Counter ) printf( "Warning: The total of %d block boxes are transformed into PI/PO pairs.\n", Counter ); - // add latches - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj(pNtkNew, pObj); - Vec_PtrPush( pNtkNew->vCis, pObj->pCopy ); - Vec_PtrPush( pNtkNew->vCos, pObj->pCopy ); - Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(pObj) ); - } - // collect the CO nodes + // connect the CO nodes Abc_NtkForEachCo( pNtk, pObj, i ) Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy ); // copy the timing information @@ -167,62 +156,75 @@ void Abc_NtkNetlistToLogicHie_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtkOld, int int i, k; // collect nodes and boxes in topological order vNodes = Abc_NtkDfs( pNtkOld, 0 ); - // create logic for nodes and boxes + // duplicate nodes, create PIs/POs corresponding to blackboxes + // have to do it first if blackboxes break combinational loops + // (current we do not allow whiteboxes to break combinational loops) Vec_PtrForEachEntry( vNodes, pNode, i ) { - if ( Abc_ObjFaninNum(pNode) == 0 ) - continue; if ( Abc_ObjIsNode(pNode) ) { // duplicate the node and save it in the fanout net Abc_NtkDupObj( pNtkNew, pNode ); + Abc_ObjFanout0(pNode)->pCopy = pNode->pCopy; + continue; + } + assert( Abc_ObjIsBox(pNode) ); + pNtkModel = pNode->pData; + if ( !Abc_NtkHasBlackbox(pNtkModel) ) + continue; + // consider this blockbox + if ( pNtkNew->pBlackBoxes == NULL ) + { + pNtkNew->pBlackBoxes = Vec_IntAlloc( 10 ); + Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) ); + } + sprintf( Prefix, "%s_%d_", Abc_NtkName(pNtkModel), *pCounter ); + // create new PIs from the POs of the box + Abc_NtkForEachPo( pNtkModel, pObj, k ) + { + pObj->pCopy = Abc_NtkCreatePi( pNtkNew ); + Abc_ObjFanout(pNode, k)->pCopy = pObj->pCopy; + Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(Abc_ObjFanin0(pObj)) ); + } + // create new POs from the PIs of the box + Abc_NtkForEachPi( pNtkModel, pObj, k ) + { + pObj->pCopy = Abc_NtkCreatePo( pNtkNew ); +// Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin(pNode, k)->pCopy ); + Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(Abc_ObjFanout0(pObj)) ); + } + (*pCounter)++; + Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) ); + } + // connect nodes and boxes + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + if ( Abc_ObjIsNode(pNode) ) + { +// printf( "adding node %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) ); Abc_ObjForEachFanin( pNode, pFanin, k ) Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy ); - Abc_ObjFanout0(pNode)->pCopy = pNode->pCopy; continue; } assert( Abc_ObjIsBox(pNode) ); pNtkModel = pNode->pData; +// printf( "adding model %s\n", Abc_NtkName(pNtkModel) ); // consider the case of the black box - if ( Abc_NtkIsBlackbox(pNtkModel) ) + if ( Abc_NtkHasBlackbox(pNtkModel) ) { - if ( pNtkNew->pBlackBoxes == NULL ) - { - pNtkNew->pBlackBoxes = Vec_IntAlloc( 10 ); - Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) ); - } - sprintf( Prefix, "%s_%d_", Abc_NtkName(pNtkModel), *pCounter ); - // create new PIs from the POs of the box - Abc_NtkForEachPo( pNtkModel, pObj, k ) - { - pObj->pCopy = Abc_NtkCreatePi( pNtkNew ); - Abc_ObjFanout(pNode, k)->pCopy = pObj->pCopy; - Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(pObj) ); - } // create new POs from the PIs of the box Abc_NtkForEachPi( pNtkModel, pObj, k ) - { - pObj->pCopy = Abc_NtkCreatePo( pNtkNew ); Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin(pNode, k)->pCopy ); - Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(pObj) ); - } - (*pCounter)++; - Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) ); - } - else - { - // map the constant nodes - if ( Abc_NtkConst1(pNtkModel) ) - Abc_NtkConst1(pNtkModel)->pCopy = Abc_NtkConst1(pNtkNew); - // transfer the nodes to the box inputs - Abc_NtkForEachPi( pNtkModel, pObj, k ) - Abc_ObjFanout0(pObj)->pCopy = Abc_ObjFanin(pNode, k)->pCopy; - // construct recursively - Abc_NtkNetlistToLogicHie_rec( pNtkNew, pNtkModel, pCounter ); - // transfer the results back - Abc_NtkForEachPo( pNtkModel, pObj, k ) - Abc_ObjFanout(pNode, k)->pCopy = Abc_ObjFanin0(pObj)->pCopy; + continue; } + // transfer the nodes to the box inputs + Abc_NtkForEachPi( pNtkModel, pObj, k ) + Abc_ObjFanout0(pObj)->pCopy = Abc_ObjFanin(pNode, k)->pCopy; + // construct recursively + Abc_NtkNetlistToLogicHie_rec( pNtkNew, pNtkModel, pCounter ); + // transfer the results back + Abc_NtkForEachPo( pNtkModel, pObj, k ) + Abc_ObjFanout(pNode, k)->pCopy = Abc_ObjFanin0(pObj)->pCopy; } Vec_PtrFree( vNodes ); } @@ -352,7 +354,7 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk ) // the driver is a node // get the CO name - pNameCo = Abc_ObjIsPo(pObj)? Abc_ObjName(pObj) : Abc_ObjNameSuffix( pObj, "_in" ); + pNameCo = Abc_ObjIsLatch(pObj)? Abc_ObjNameSuffix( pObj, "_in" ) : Abc_ObjName(pObj); // make sure CO has a unique name assert( Abc_NtkFindNet( pNtkNew, pNameCo ) == NULL ); // create the CO net and connect it to CO @@ -401,6 +403,7 @@ 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 @@ -423,16 +426,17 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk ) // create an OR gate pNodeNew = Abc_NtkCreateNode(pNtkNew); // add fanins - Vec_IntClear( pNtk->vIntTemp ); + vInts = Vec_IntAlloc( 10 ); for ( pFanin = pObj; pFanin; pFanin = pFanin->pData ) { - Vec_IntPush( pNtk->vIntTemp, (int)(pObj->fPhase != pFanin->fPhase) ); + Vec_IntPush( vInts, (int)(pObj->fPhase != pFanin->fPhase) ); Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); } // create the logic function - pNodeNew->pData = Abc_SopCreateOrMultiCube( pNtkNew->pManFunc, pNtk->vIntTemp->nSize, pNtk->vIntTemp->pArray ); + pNodeNew->pData = Abc_SopCreateOrMultiCube( pNtkNew->pManFunc, Vec_IntSize(vInts), Vec_IntArray(vInts) ); // set the new node pObj->pCopy->pCopy = pNodeNew; + Vec_IntFree( vInts ); } // connect the internal nodes Abc_NtkForEachNode( pNtk, pObj, i ) diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index c8bdf987..56d399f0 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -53,19 +53,14 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ) pNtk->Id = !Abc_HManIsRunning()? 0 : Abc_HManGetNewNtkId(); // start the object storage pNtk->vObjs = Vec_PtrAlloc( 100 ); - pNtk->vLats = Vec_PtrAlloc( 100 ); - pNtk->vCutSet = Vec_PtrAlloc( 100 ); + pNtk->vLatches = Vec_PtrAlloc( 100 ); + pNtk->vAsserts = Vec_PtrAlloc( 100 ); + pNtk->vPis = Vec_PtrAlloc( 100 ); + pNtk->vPos = Vec_PtrAlloc( 100 ); pNtk->vCis = Vec_PtrAlloc( 100 ); pNtk->vCos = Vec_PtrAlloc( 100 ); - pNtk->vAsserts = 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); + pNtk->vCutSet = Vec_PtrAlloc( 100 ); // start the memory managers -// 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 @@ -115,7 +110,7 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ) 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, * pObjNew; + Abc_Obj_t * pObj; int i; if ( pNtk == NULL ) return NULL; @@ -135,12 +130,10 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_ Abc_NtkDupObj(pNtkNew, pObj); Abc_NtkForEachPo( pNtk, pObj, i ) Abc_NtkDupObj(pNtkNew, pObj); + Abc_NtkForEachAssert( pNtk, pObj, i ) + Abc_NtkDupObj(pNtkNew, pObj); Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObjNew = Abc_NtkDupObj(pNtkNew, pObj); - Vec_PtrPush( pNtkNew->vCis, pObjNew ); - Vec_PtrPush( pNtkNew->vCos, pObjNew ); - } + Abc_NtkDupObj(pNtkNew, pObj); if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() ) { Abc_HManAddProto( Abc_NtkConst1(pNtk)->pCopy, Abc_NtkConst1(pNtk) ); @@ -202,15 +195,12 @@ Abc_Ntk_t * Abc_NtkStartFromDual( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkF // collect first to old pObj->pCopy = pObjNew; } + Abc_NtkForEachAssert( pNtk, pObj, i ) + Abc_NtkDupObj(pNtkNew, pObj); Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObjNew = Abc_NtkDupObj(pNtkNew, pObj); - Vec_PtrPush( pNtkNew->vCis, pObjNew ); - Vec_PtrPush( pNtkNew->vCos, pObjNew ); - } + Abc_NtkDupObj(pNtkNew, pObj); // transfer the names Abc_NtkDupCioNamesTableDual( 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)* 2 == Abc_NtkCoNum(pNtkNew) ); @@ -244,54 +234,6 @@ void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) /**Function************************************************************* - Synopsis [Finalizes the network using the existing network as a model.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) -{ - Abc_Obj_t * pObj, * pDriver, * pDriverNew; - int i; - // set the COs of the strashed network - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(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 [] @@ -325,9 +267,9 @@ Abc_Ntk_t * Abc_NtkStartRead( char * pName ) ***********************************************************************/ void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pLatch, * pBox, * pObj; + Abc_Obj_t * pBox, * pObj; int i; - if ( pNtk->ntkType == ABC_NTK_BLACKBOX ) + if ( Abc_NtkHasBlackbox(pNtk) ) { pBox = Abc_NtkCreateBox(pNtk); Abc_NtkForEachPi( pNtk, pObj, i ) @@ -339,14 +281,8 @@ void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ) assert( Abc_NtkIsNetlist(pNtk) ); // fix the net drivers Abc_NtkFixNonDrivenNets( 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 ); - } + // reorder the CI/COs to PI/POs first + Abc_NtkOrderCisCos( pNtk ); } /**Function************************************************************* @@ -740,7 +676,6 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) int LargePiece = (4 << ABC_NUM_STEPS); if ( pNtk == NULL ) return; -//printf( "Deleted newtork %p\n", pNtk ); // make sure all the marks are clean Abc_NtkForEachObj( pNtk, pObj, i ) { @@ -765,26 +700,20 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) if ( pNtk->pExdc ) Abc_NtkDelete( pNtk->pExdc ); // free the arrays + Vec_PtrFree( pNtk->vPis ); + Vec_PtrFree( pNtk->vPos ); Vec_PtrFree( pNtk->vCis ); Vec_PtrFree( pNtk->vCos ); Vec_PtrFree( pNtk->vAsserts ); + Vec_PtrFree( pNtk->vLatches ); Vec_PtrFree( pNtk->vObjs ); - Vec_PtrFree( pNtk->vLats ); Vec_PtrFree( pNtk->vCutSet ); - Vec_PtrFree( pNtk->vPtrTemp ); - Vec_IntFree( pNtk->vIntTemp ); - Vec_StrFree( pNtk->vStrTemp ); if ( pNtk->pModel ) free( pNtk->pModel ); - // free the hash table of Obj name into Obj ID -// stmm_free_table( pNtk->tName2Net ); -// stmm_free_table( pNtk->tObj2Name ); TotalMemory = 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 -// Extra_MmFlexStop ( pNtk->pMmNames, 0 ); Extra_MmFixedStop( pNtk->pMmObj, 0 ); Extra_MmStepStop ( pNtk->pMmStep, 0 ); // free the timing manager @@ -802,7 +731,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) else Seq_Delete( pNtk->pManFunc ); } - else if ( !Abc_NtkHasMapping(pNtk) ) + else if ( !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlackbox(pNtk) ) assert( 0 ); // name manager Nm_ManFree( pNtk->pManName ); @@ -815,9 +744,9 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) stmm_foreach_item( pNtk->tName2Model, gen, &pName, (char **)&pNtkTemp ) Abc_NtkDelete( pNtkTemp ); stmm_free_table( pNtk->tName2Model ); - if ( pNtk->pBlackBoxes ) - Vec_IntFree( pNtk->pBlackBoxes ); } + if ( pNtk->pBlackBoxes ) + Vec_IntFree( pNtk->pBlackBoxes ); free( pNtk ); } diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c index 56fcef95..53886161 100644 --- a/src/base/abc/abcObj.c +++ b/src/base/abc/abcObj.c @@ -101,34 +101,32 @@ void Abc_ObjAdd( Abc_Obj_t * pObj ) // perform specialized operations depending on the object type if ( Abc_ObjIsNet(pObj) ) { -/* - // 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++; } else if ( Abc_ObjIsNode(pObj) ) { pNtk->nNodes++; } - else if ( Abc_ObjIsLatch(pObj) ) - { - Vec_PtrPush( pNtk->vLats, pObj ); - pNtk->nLatches++; - } else if ( Abc_ObjIsPi(pObj) ) { + Vec_PtrPush( pNtk->vPis, pObj ); Vec_PtrPush( pNtk->vCis, pObj ); - pNtk->nPis++; } else if ( Abc_ObjIsPo(pObj) ) { + Vec_PtrPush( pNtk->vPos, pObj ); + Vec_PtrPush( pNtk->vCos, pObj ); + } + else if ( Abc_ObjIsLatch(pObj) ) + { + Vec_PtrPush( pNtk->vLatches, pObj ); + Vec_PtrPush( pNtk->vCis, pObj ); + Vec_PtrPush( pNtk->vCos, pObj ); + } + else if ( Abc_ObjIsAssert(pObj) ) + { + Vec_PtrPush( pNtk->vAsserts, pObj ); Vec_PtrPush( pNtk->vCos, pObj ); - pNtk->nPos++; } else if ( Abc_ObjIsBox(pObj) ) { @@ -138,7 +136,6 @@ void Abc_ObjAdd( Abc_Obj_t * pObj ) { assert( 0 ); } - assert( pObj->Id >= 0 ); } /**Function************************************************************* @@ -155,7 +152,11 @@ void Abc_ObjAdd( Abc_Obj_t * pObj ) Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) { Abc_Obj_t * pObjNew; + // create the new object pObjNew = Abc_ObjAlloc( pNtkNew, pObj->Type ); + // add the object to the network + Abc_ObjAdd( pObjNew ); + // copy functionality/names if ( Abc_ObjIsNode(pObj) ) // copy the function if functionality is compatible { if ( pNtkNew->ntkFunc == pObj->pNtk->ntkFunc ) @@ -172,18 +173,11 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) } else if ( Abc_ObjIsNet(pObj) ) // copy the name { -// pObjNew->pData = Abc_NtkRegisterName( pNtkNew, pObj->pData ); + pObjNew->pData = Nm_ManStoreIdName( pNtkNew->pManName, pObjNew->Id, pObj->pData, NULL ); } else if ( Abc_ObjIsLatch(pObj) ) // copy the reset value pObjNew->pData = pObj->pData; pObj->pCopy = pObjNew; - // add the object to the network - Abc_ObjAdd( pObjNew ); - - - if ( Abc_ObjIsNet(pObj) ) - pObjNew->pData = Nm_ManStoreIdName( pNtkNew->pManName, pObjNew->Id, pObj->pData, NULL ); - return pObjNew; } @@ -201,37 +195,34 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) ***********************************************************************/ void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) { - Vec_Ptr_t * vNodes = pObj->pNtk->vPtrTemp; Abc_Ntk_t * pNtk = pObj->pNtk; + Vec_Ptr_t * vNodes; int i; assert( !Abc_ObjIsComplement(pObj) ); // 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->nObjs--; + // remove from the table of names + if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) ) + Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id); + // perform specialized operations depending on the object type if ( Abc_ObjIsNet(pObj) ) { - assert( 0 ); -/* - // 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--; } @@ -239,26 +230,33 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) { if ( Abc_NtkHasBdd(pNtk) ) Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); + pObj->pData = NULL; pNtk->nNodes--; } else if ( Abc_ObjIsLatch(pObj) ) { - pNtk->nLatches--; + Vec_PtrRemove( pNtk->vLatches, pObj ); + Vec_PtrRemove( pNtk->vCis, pObj ); + Vec_PtrRemove( pNtk->vCos, pObj ); + } + else if ( Abc_ObjIsPi(pObj) ) + { + Vec_PtrRemove( pObj->pNtk->vPis, pObj ); + Vec_PtrRemove( pObj->pNtk->vCis, pObj ); } else if ( Abc_ObjIsPo(pObj) ) { - assert( Abc_NtkPoNum(pObj->pNtk) > 0 ); + Vec_PtrRemove( pObj->pNtk->vPos, pObj ); Vec_PtrRemove( pObj->pNtk->vCos, pObj ); - pObj->pNtk->nPos--; - - assert( 0 ); -/* - // add the name to the table - if ( !stmm_delete( pObj->pNtk->tObj2Name, (char **)&pObj, NULL ) ) - { - assert( 0 ); // the PO is not in the table - } -*/ + } + else if ( Abc_ObjIsAssert(pObj) ) + { + Vec_PtrRemove( pObj->pNtk->vAsserts, pObj ); + Vec_PtrRemove( pObj->pNtk->vCos, pObj ); + } + else if ( Abc_ObjIsBox(pObj) ) + { + pNtk->nBoxes--; } else assert( 0 ); @@ -377,9 +375,6 @@ Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ) Abc_Obj_t * pNet; int ObjId; assert( Abc_NtkIsNetlist(pNtk) ); -// if ( stmm_lookup( pNtk->tName2Net, pName, (char**)&pNet ) ) -// return pNet; -// return NULL; ObjId = Nm_ManFindIdByName( pNtk->pManName, pName, NULL ); if ( ObjId == -1 ) return NULL; @@ -406,7 +401,6 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ) return pNet; // create a new net pNet = Abc_ObjAlloc( pNtk, ABC_OBJ_NET ); -// pNet->pData = Abc_NtkRegisterName( pNtk, pName ); Abc_ObjAdd( pNet ); pNet->pData = Nm_ManStoreIdName( pNtk->pManName, pNet->Id, pName, NULL ); return pNet; @@ -510,6 +504,25 @@ Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ) /**Function************************************************************* + Synopsis [Create the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_ASSERT ); + Abc_ObjAdd( pObj ); + return pObj; +} + +/**Function************************************************************* + Synopsis [Creates inverter.] Description [] diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index d5cc65f1..a893f3e2 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -360,6 +360,44 @@ 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************************************************************* diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 034aa38f..175b17f7 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -47,7 +47,7 @@ void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; int i; - if ( pNtk->nTravIds == (1<<10)-1 ) + if ( pNtk->nTravIds == (1<<9)-1 ) { pNtk->nTravIds = 0; Abc_NtkForEachObj( pNtk, pObj, i ) @@ -58,6 +58,36 @@ 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; + int i; + 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_NtkForEachLatch( pNtk, pObj, i ) + { + Vec_PtrPush( pNtk->vCis, pObj ); + Vec_PtrPush( pNtk->vCos, pObj ); + } +} + +/**Function************************************************************* + Synopsis [Reads the number of cubes of the node.] Description [] @@ -84,7 +114,7 @@ int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Reads the number of cubes of the node.] + Synopsis [Reads the number of literals in the SOPs of the nodes.] Description [] @@ -1029,6 +1059,12 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk ) 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 next Abc_NtkForEachLatch( pNtk, pNode, i ) { diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 201a1208..075c64ee 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -83,9 +83,9 @@ static int Abc_CommandExdcFree ( Abc_Frame_t * pAbc, int argc, char ** argv static int Abc_CommandExdcGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandExdcSet ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandEspresso ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandGen ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -193,9 +193,9 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "exdc_get", Abc_CommandExdcGet, 1 ); Cmd_CommandAdd( pAbc, "Various", "exdc_set", Abc_CommandExdcSet, 1 ); Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 ); - Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 ); Cmd_CommandAdd( pAbc, "Various", "espresso", Abc_CommandEspresso, 1 ); Cmd_CommandAdd( pAbc, "Various", "gen", Abc_CommandGen, 0 ); + Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 ); Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 ); Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 ); @@ -4297,98 +4297,6 @@ usage: SeeAlso [] ***********************************************************************/ -int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - int fVerbose; - int fUseInvs; - int nFaninMax; - extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); - - pNtk = Abc_FrameReadNtk(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fVerbose = 0; - fUseInvs = 1; - nFaninMax = 128; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Nivh" ) ) != EOF ) - { - switch ( c ) - { - case 'N': - if ( globalUtilOptind >= argc ) - { - fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); - goto usage; - } - nFaninMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( nFaninMax < 0 ) - goto usage; - break; - case 'i': - fUseInvs ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Only works for strashed networks.\n" ); - return 1; - } - - // run the command -// pNtkRes = Abc_NtkXyz( pNtk, nFaninMax, 1, 0, fUseInvs, fVerbose ); - pNtkRes = NULL; - - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Command has failed.\n" ); - return 0; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: xyz [-N num] [-ivh]\n" ); - fprintf( pErr, "\t specilized AND/OR/EXOR decomposition\n" ); - fprintf( pErr, "\t-N num : maximum number of inputs [default = %d]\n", nFaninMax ); - fprintf( pErr, "\t-i : toggle the use of interters [default = %s]\n", fUseInvs? "yes": "no" ); - fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int Abc_CommandEspresso( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; @@ -4543,20 +4451,127 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + int nLutMax; + int nPlaMax; + int fVerbose; +// extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nPlaMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); + extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose ); + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + nLutMax = 8; + nPlaMax = 128; + fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "LPvh" ) ) != EOF ) + { + switch ( c ) + { + case 'L': + if ( globalUtilOptind >= argc ) + { + fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nLutMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLutMax < 0 ) + goto usage; + break; + case 'P': + if ( globalUtilOptind >= argc ) + { + fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nPlaMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nPlaMax < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Only works for strashed networks.\n" ); + return 1; + } + + if ( nLutMax < 2 || nLutMax > 8 || nPlaMax < 8 || nPlaMax > 128 ) + { + fprintf( pErr, "Incorrect LUT/PLA parameters.\n" ); + return 1; + } + + // run the command +// pNtkRes = Abc_NtkXyz( pNtk, nPlaMax, 1, 0, fUseInvs, fVerbose ); + pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, fVerbose ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Command has failed.\n" ); + return 0; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: xyz [-L num] [-P num] [-vh]\n" ); + fprintf( pErr, "\t specilized LUT/PLA decomposition\n" ); + fprintf( pErr, "\t-L num : maximum number of LUT inputs (2<=num<=8) [default = %d]\n", nLutMax ); + fprintf( pErr, "\t-P num : maximum number of PLA inputs/cubes (8<=num<=128) [default = %d]\n", nPlaMax ); + fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; - Abc_Ntk_t * pNtk;//, * pNtkRes; + Abc_Ntk_t * pNtk, * pNtkRes; int c; int nLevels; // extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk ); + extern Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); // set defaults - nLevels = 15; + nLevels = 128; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF ) { @@ -4614,7 +4629,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) // Cut_CellDumpToFile(); // else // Cut_CellPrecompute(); - Cut_CellLoad(); +// Cut_CellLoad(); /* { Abc_Ntk_t * pNtkRes; @@ -4623,6 +4638,24 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); } */ +// Abc_NtkSimulteBuggyMiter( pNtk ); + +// Rwr_Temp(); +// Abc_MvExperiment(); +// Ivy_TruthTest(); + + + pNtkRes = Abc_NtkIvy( pNtk ); +// pNtkRes = Abc_NtkPlayer( pNtk, nLevels, 0 ); +// pNtkRes = NULL; + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Command has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; usage: @@ -6614,9 +6647,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) int fVerbose; int nSeconds; int nConfLimit; - int nImpLimit; + int nInsLimit; - extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nImpLimit ); + extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit ); extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ); @@ -6629,7 +6662,7 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) fVerbose = 0; nSeconds = 20; nConfLimit = 10000; - nImpLimit = 0; + nInsLimit = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "TCIsvh" ) ) != EOF ) { @@ -6663,9 +6696,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" ); goto usage; } - nImpLimit = atoi(argv[globalUtilOptind]); + nInsLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nImpLimit < 0 ) + if ( nInsLimit < 0 ) goto usage; break; case 's': @@ -6686,7 +6719,7 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) // perform equivalence checking if ( fSat ) - Abc_NtkCecSat( pNtk1, pNtk2, nConfLimit, nImpLimit ); + Abc_NtkCecSat( pNtk1, pNtk2, nConfLimit, nInsLimit ); else Abc_NtkCecFraig( pNtk1, pNtk2, nSeconds, fVerbose ); @@ -6699,7 +6732,7 @@ usage: fprintf( pErr, "\t performs combinational equivalence checking\n" ); fprintf( pErr, "\t-T num : approximate runtime limit in seconds [default = %d]\n", nSeconds ); fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit ); - fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit ); + fprintf( pErr, "\t-I num : limit on the number of clause inspections [default = %d]\n", nInsLimit ); fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" ); fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); @@ -6734,9 +6767,9 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv ) int nFrames; int nSeconds; int nConfLimit; - int nImpLimit; + int nInsLimit; - extern void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nImpLimit, int nFrames ); + extern void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit, int nFrames ); extern void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nFrames, int fVerbose ); @@ -6750,7 +6783,7 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv ) nFrames = 3; nSeconds = 20; nConfLimit = 10000; - nImpLimit = 0; + nInsLimit = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "FTCIsvh" ) ) != EOF ) { @@ -6795,9 +6828,9 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" ); goto usage; } - nImpLimit = atoi(argv[globalUtilOptind]); + nInsLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nImpLimit < 0 ) + if ( nInsLimit < 0 ) goto usage; break; case 'v': @@ -6818,7 +6851,7 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv ) // perform equivalence checking if ( fSat ) - Abc_NtkSecSat( pNtk1, pNtk2, nConfLimit, nImpLimit, nFrames ); + Abc_NtkSecSat( pNtk1, pNtk2, nConfLimit, nInsLimit, nFrames ); else Abc_NtkSecFraig( pNtk1, pNtk2, nSeconds, nFrames, fVerbose ); @@ -6835,7 +6868,7 @@ usage: fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames ); fprintf( pErr, "\t-T num : approximate runtime limit in seconds [default = %d]\n", nSeconds ); fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit ); - fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit ); + fprintf( pErr, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit ); fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); @@ -6863,7 +6896,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) int fJFront; int fVerbose; int nConfLimit; - int nImpLimit; + int nInsLimit; int clk; pNtk = Abc_FrameReadNtk(pAbc); @@ -6871,10 +6904,10 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) pErr = Abc_FrameReadErr(pAbc); // set defaults - fJFront = 0; + fJFront = 0; fVerbose = 0; nConfLimit = 100000; - nImpLimit = 0; + nInsLimit = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "CIvjh" ) ) != EOF ) { @@ -6897,9 +6930,9 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" ); goto usage; } - nImpLimit = atoi(argv[globalUtilOptind]); + nInsLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nImpLimit < 0 ) + if ( nInsLimit < 0 ) goto usage; break; case 'j': @@ -6934,13 +6967,13 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) clk = clock(); if ( Abc_NtkIsStrash(pNtk) ) { - RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, fJFront, fVerbose ); + RetValue = Abc_NtkMiterSat( pNtk, (sint64)nConfLimit, (sint64)nInsLimit, fJFront, fVerbose, NULL, NULL ); } else { Abc_Ntk_t * pTemp; pTemp = Abc_NtkStrash( pNtk, 0, 0 ); - RetValue = Abc_NtkMiterSat( pTemp, nConfLimit, nImpLimit, fJFront, fVerbose ); + RetValue = Abc_NtkMiterSat( pTemp, (sint64)nConfLimit, (sint64)nInsLimit, fJFront, fVerbose, NULL, NULL ); pNtk->pModel = pTemp->pModel; pTemp->pModel = NULL; Abc_NtkDelete( pTemp ); } @@ -6948,10 +6981,22 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) // verify that the pattern is correct if ( RetValue == 0 && Abc_NtkPoNum(pNtk) == 1 ) { + //int i; + //Abc_Obj_t * pObj; int * pSimInfo = Abc_NtkVerifySimulatePattern( pNtk, pNtk->pModel ); if ( pSimInfo[0] != 1 ) printf( "ERROR in Abc_NtkMiterSat(): Generated counter example is invalid.\n" ); free( pSimInfo ); + /* + // print model + Abc_NtkForEachPi( pNtk, pObj, i ) + { + printf( "%d", (int)(pNtk->pModel[i] > 0) ); + if ( i == 70 ) + break; + } + printf( "\n" ); + */ } if ( RetValue == -1 ) @@ -6969,7 +7014,7 @@ usage: fprintf( pErr, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" ); fprintf( pErr, "\t derives CNF from the current network and leave it unchanged\n" ); fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit ); - fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit ); + fprintf( pErr, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit ); fprintf( pErr, "\t-j : toggle the use of J-frontier [default = %s]\n", fJFront? "yes": "no" ); fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); @@ -7001,7 +7046,7 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults Prove_ParamsSetDefault( pParams ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "NCFLrfvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NCFLIrfbvh" ) ) != EOF ) { switch ( c ) { @@ -7049,12 +7094,26 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pParams->nMiteringLimitLast < 0 ) goto usage; break; + case 'I': + if ( globalUtilOptind >= argc ) + { + fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nTotalInspectLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pParams->nTotalInspectLimit < 0 ) + goto usage; + break; case 'r': pParams->fUseRewriting ^= 1; break; case 'f': pParams->fUseFraiging ^= 1; break; + case 'b': + pParams->fUseBdds ^= 1; + break; case 'v': pParams->fVerbose ^= 1; break; @@ -7118,15 +7177,17 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: prove [-N num] [-C num] [-F num] [-L num] [-rfvh]\n" ); + fprintf( pErr, "usage: prove [-N num] [-C num] [-F num] [-L num] [-I num] [-rfbvh]\n" ); fprintf( pErr, "\t solves combinational miter by rewriting, FRAIGing, and SAT\n" ); fprintf( pErr, "\t replaces the current network by the cone modified by rewriting\n" ); fprintf( pErr, "\t-N num : max number of iterations [default = %d]\n", pParams->nItersMax ); fprintf( pErr, "\t-C num : max starting number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitStart ); fprintf( pErr, "\t-F num : max starting number of conflicts in fraiging [default = %d]\n", pParams->nFraigingLimitStart ); fprintf( pErr, "\t-L num : max last-gasp number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitLast ); + fprintf( pErr, "\t-I num : max number of clause inspections in all SAT calls [default = %d]\n", (int)pParams->nTotalInspectLimit ); fprintf( pErr, "\t-r : toggle the use of rewriting [default = %s]\n", pParams->fUseRewriting? "yes": "no" ); fprintf( pErr, "\t-f : toggle the use of FRAIGing [default = %s]\n", pParams->fUseFraiging? "yes": "no" ); + fprintf( pErr, "\t-b : toggle the use of BDDs [default = %s]\n", pParams->fUseBdds? "yes": "no" ); fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/abci/abcAttach.c b/src/base/abci/abcAttach.c index 78573718..bf40e45b 100644 --- a/src/base/abci/abcAttach.c +++ b/src/base/abci/abcAttach.c @@ -387,13 +387,13 @@ void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned nMints = (1 << nVars); for ( iMint = 0; iMint < nMints; iMint++ ) { - if ( (uTruthNode[iMint/32] & (1 << (iMint%32))) == 0 ) + if ( (uTruthNode[iMint>>5] & (1 << (iMint&31))) == 0 ) continue; iMintPerm = 0; for ( v = 0; v < nVars; v++ ) if ( iMint & (1 << v) ) iMintPerm |= (1 << pPerm[v]); - uTruthPerm[iMintPerm/32] |= (1 << (iMintPerm%32)); + uTruthPerm[iMintPerm>>5] |= (1 << (iMintPerm&31)); } } diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c new file mode 100644 index 00000000..0108b520 --- /dev/null +++ b/src/base/abci/abcIvy.c @@ -0,0 +1,407 @@ +/**CFile**************************************************************** + + FileName [abcIvy.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Strashing of the current network.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcIvy.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "dec.h" +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan ); +static Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld ); + +static void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan ); +static Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode ); +static Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ); +static Ivy_Obj_t * Abc_NodeStrashAigExorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ); +static Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ); +extern char * Mio_GateReadSop( void * pGate ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Gives the current ABC network to AIG manager for processing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ) +{ + Ivy_Man_t * pMan; + Abc_Ntk_t * pNtkAig; + int fCleanup = 1; + int nNodes; + + assert( !Abc_NtkIsNetlist(pNtk) ); + assert( !Abc_NtkIsSeq(pNtk) ); + if ( Abc_NtkIsBddLogic(pNtk) ) + { + if ( !Abc_NtkBddToSop(pNtk, 0) ) + { + printf( "Converting to SOPs has failed.\n" ); + return NULL; + } + } + // print warning about choice nodes + if ( Abc_NtkGetChoiceNum( pNtk ) ) + printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" ); + + // convert to the AIG manager + pMan = Abc_NtkToAig( pNtk ); + + if ( !Ivy_ManCheck( pMan ) ) + { + printf( "AIG check has failed.\n" ); + Ivy_ManStop( pMan ); + return NULL; + } + + +// Ivy_MffcTest( pMan ); + Ivy_ManPrintStats( pMan ); + Ivy_ManSeqRewrite( pMan, 0, 0 ); + Ivy_ManPrintStats( pMan ); + + // convert from the AIG manager + pNtkAig = Abc_NtkFromAig( pNtk, pMan ); + Ivy_ManStop( pMan ); + + // report the cleanup results + if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) + printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes ); + // duplicate EXDC + if ( pNtk->pExdc ) + pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc ); + // make sure everything is okay + if ( !Abc_NtkCheck( pNtkAig ) ) + { + printf( "Abc_NtkStrash: The network check has failed.\n" ); + Abc_NtkDelete( pNtkAig ); + return NULL; + } + return pNtkAig; +} + +/**Function************************************************************* + + Synopsis [Converts the network from the AIG manager into ABC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan ) +{ + Vec_Int_t * vNodes; + Abc_Ntk_t * pNtk; + Abc_Obj_t * pObj, * pObjNew, * pFaninNew, * pFaninNew0, * pFaninNew1; + Ivy_Obj_t * pNode; + int i, Fanin; + // perform strashing + pNtk = Abc_NtkStartFrom( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG ); + // transfer the pointers to the basic nodes + Ivy_ManConst1(pMan)->TravId = (Abc_NtkConst1(pNtk)->Id << 1); + Abc_NtkForEachCi( pNtkOld, pObj, i ) + Ivy_ManPi(pMan, i)->TravId = (pObj->pCopy->Id << 1); + // rebuild the AIG + vNodes = Ivy_ManDfs( pMan ); + Ivy_ManForEachNodeVec( pMan, vNodes, pNode, i ) + { + // add the first fanins + Fanin = Ivy_ObjFanin0(pNode)->TravId; + pFaninNew0 = Abc_NtkObj( pNtk, Fanin >> 1 ); + pFaninNew0 = Abc_ObjNotCond( pFaninNew0, Ivy_ObjFaninC0(pNode) ^ (Fanin&1) ); + if ( Ivy_ObjIsBuf(pNode) ) + { + pNode->TravId = (Abc_ObjRegular(pFaninNew0)->Id << 1) | Abc_ObjIsComplement(pFaninNew0); + continue; + } + // add the first second + Fanin = Ivy_ObjFanin1(pNode)->TravId; + pFaninNew1 = Abc_NtkObj( pNtk, Fanin >> 1 ); + pFaninNew1 = Abc_ObjNotCond( pFaninNew1, Ivy_ObjFaninC1(pNode) ^ (Fanin&1) ); + // create the new node + if ( Ivy_ObjIsExor(pNode) ) + pObjNew = Abc_AigXor( pNtk->pManFunc, pFaninNew0, pFaninNew1 ); + else + pObjNew = Abc_AigAnd( pNtk->pManFunc, pFaninNew0, pFaninNew1 ); + pNode->TravId = (Abc_ObjRegular(pObjNew)->Id << 1) | Abc_ObjIsComplement(pObjNew); + } + Vec_IntFree( vNodes ); + // connect the PO nodes + Abc_NtkForEachCo( pNtkOld, pObj, i ) + { + pNode = Ivy_ManPo(pMan, i); + Fanin = Ivy_ObjFanin0(pNode)->TravId; + pFaninNew = Abc_NtkObj( pNtk, Fanin >> 1 ); + pFaninNew = Abc_ObjNotCond( pFaninNew, Ivy_ObjFaninC0(pNode) ^ (Fanin&1) ); + Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); + } + return pNtk; +} + +/**Function************************************************************* + + Synopsis [Converts the network from the AIG manager into ABC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld ) +{ + Ivy_Man_t * pMan; + Abc_Obj_t * pObj; + Ivy_Obj_t * pFanin; + int i; + // create the manager + assert( Abc_NtkHasSop(pNtkOld) || Abc_NtkHasAig(pNtkOld) ); + if ( Abc_NtkHasSop(pNtkOld) ) + pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), 3 * Abc_NtkGetLitNum(pNtkOld) + 10 ); + else + pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), 3 * Abc_NtkNodeNum(pNtkOld) + 10 ); + // create the PIs + Abc_NtkConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); + Abc_NtkForEachCi( pNtkOld, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i); + // perform the conversion of the internal nodes + Abc_NtkStrashPerformAig( pNtkOld, pMan ); + // create the POs + Abc_NtkForEachCo( pNtkOld, pObj, i ) + { + pFanin = (Ivy_Obj_t *)Abc_ObjFanin0(pObj)->pCopy; + pFanin = Ivy_NotCond( pFanin, Abc_ObjFaninC0(pObj) ); + Ivy_ObjConnect( Ivy_ManPo(pMan, i), pFanin ); + } + Ivy_ManCleanup( pMan ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Prepares the network for strashing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan ) +{ +// ProgressBar * pProgress; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode; + int i; + vNodes = Abc_NtkDfs( pNtk, 0 ); +// pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { +// Extra_ProgressBarUpdate( pProgress, i, NULL ); + pNode->pCopy = (Abc_Obj_t *)Abc_NodeStrashAig( pMan, pNode ); + } +// Extra_ProgressBarStop( pProgress ); + Vec_PtrFree( vNodes ); +} + +/**Function************************************************************* + + Synopsis [Strashes one logic node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode ) +{ + int fUseFactor = 1; + char * pSop; + Ivy_Obj_t * pFanin0, * pFanin1; + extern int Abc_SopIsExorType( char * pSop ); + + assert( Abc_ObjIsNode(pNode) ); + + // consider the case when the graph is an AIG + if ( Abc_NtkIsStrash(pNode->pNtk) ) + { + if ( Abc_NodeIsConst(pNode) ) + return Ivy_ManConst1(pMan); + pFanin0 = (Ivy_Obj_t *)Abc_ObjFanin0(pNode)->pCopy; + pFanin0 = Ivy_NotCond( pFanin0, Abc_ObjFaninC0(pNode) ); + pFanin1 = (Ivy_Obj_t *)Abc_ObjFanin1(pNode)->pCopy; + pFanin1 = Ivy_NotCond( pFanin1, Abc_ObjFaninC1(pNode) ); + return Ivy_And( pFanin0, pFanin1 ); + } + + // get the SOP of the node + if ( Abc_NtkHasMapping(pNode->pNtk) ) + pSop = Mio_GateReadSop(pNode->pData); + else + pSop = pNode->pData; + + // consider the constant node + if ( Abc_NodeIsConst(pNode) ) + return Ivy_NotCond( Ivy_ManConst1(pMan), Abc_SopIsConst0(pSop) ); + + // consider the special case of EXOR function + if ( Abc_SopIsExorType(pSop) ) + return Abc_NodeStrashAigExorAig( pMan, pNode, pSop ); + + // decide when to use factoring + if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) + return Abc_NodeStrashAigFactorAig( pMan, pNode, pSop ); + return Abc_NodeStrashAigSopAig( pMan, pNode, pSop ); +} + +/**Function************************************************************* + + Synopsis [Strashes one logic node using its SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ) +{ + Abc_Obj_t * pFanin; + Ivy_Obj_t * pAnd, * pSum; + char * pCube; + int i, nFanins; + + // get the number of node's fanins + nFanins = Abc_ObjFaninNum( pNode ); + assert( nFanins == Abc_SopGetVarNum(pSop) ); + // go through the cubes of the node's SOP + pSum = Ivy_Not( Ivy_ManConst1(pMan) ); + Abc_SopForEachCube( pSop, nFanins, pCube ) + { + // create the AND of literals + pAnd = Ivy_ManConst1(pMan); + Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net + { + if ( pCube[i] == '1' ) + pAnd = Ivy_And( pAnd, (Ivy_Obj_t *)pFanin->pCopy ); + else if ( pCube[i] == '0' ) + pAnd = Ivy_And( pAnd, Ivy_Not((Ivy_Obj_t *)pFanin->pCopy) ); + } + // add to the sum of cubes + pSum = Ivy_Or( pSum, pAnd ); + } + // decide whether to complement the result + if ( Abc_SopIsComplement(pSop) ) + pSum = Ivy_Not(pSum); + return pSum; +} + +/**Function************************************************************* + + Synopsis [Strashed n-input XOR function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Abc_NodeStrashAigExorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ) +{ + Abc_Obj_t * pFanin; + Ivy_Obj_t * pSum; + int i, nFanins; + // get the number of node's fanins + nFanins = Abc_ObjFaninNum( pNode ); + assert( nFanins == Abc_SopGetVarNum(pSop) ); + // go through the cubes of the node's SOP + pSum = Ivy_Not( Ivy_ManConst1(pMan) ); + for ( i = 0; i < nFanins; i++ ) + { + pFanin = Abc_ObjFanin( pNode, i ); + pSum = Ivy_Exor( pSum, (Ivy_Obj_t *)pFanin->pCopy ); + } + if ( Abc_SopIsComplement(pSop) ) + pSum = Ivy_Not(pSum); + return pSum; +} + +/**Function************************************************************* + + Synopsis [Strashes one logic node using its SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pRoot, char * pSop ) +{ + Dec_Graph_t * pFForm; + Dec_Node_t * pNode; + Ivy_Obj_t * pAnd; + int i; + +// extern Ivy_Obj_t * Dec_GraphToNetworkAig( Ivy_Man_t * pMan, Dec_Graph_t * pGraph ); + extern Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph ); + +// assert( 0 ); + + // perform factoring + pFForm = Dec_Factor( pSop ); + // collect the fanins + Dec_GraphForEachLeaf( pFForm, pNode, i ) + pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy; + // perform strashing +// pAnd = Dec_GraphToNetworkAig( pMan, pFForm ); + pAnd = Dec_GraphToNetworkIvy( pMan, pFForm ); +// pAnd = NULL; + + Dec_GraphFree( pFForm ); + return pAnd; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c index 490cf0c6..ecd44017 100644 --- a/src/base/abci/abcMiter.c +++ b/src/base/abci/abcMiter.c @@ -81,7 +81,7 @@ Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) ***********************************************************************/ Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) { - char Buffer[100]; + char Buffer[1000]; Abc_Ntk_t * pNtkMiter; assert( Abc_NtkIsStrash(pNtk1) ); @@ -168,16 +168,12 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk Abc_NtkForEachLatch( pNtk1, pObj, i ) { pObjNew = Abc_NtkDupObj( pNtkMiter, pObj ); - Vec_PtrPush( pNtkMiter->vCis, pObjNew ); - Vec_PtrPush( pNtkMiter->vCos, pObjNew ); // add name Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_1" ); } Abc_NtkForEachLatch( pNtk2, pObj, i ) { pObjNew = Abc_NtkDupObj( pNtkMiter, pObj ); - Vec_PtrPush( pNtkMiter->vCis, pObjNew ); - Vec_PtrPush( pNtkMiter->vCos, pObjNew ); // add name Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_2" ); } @@ -295,7 +291,7 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt ***********************************************************************/ Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) { - char Buffer[100]; + char Buffer[1000]; Abc_Ntk_t * pNtkMiter; Abc_Obj_t * pOutput1, * pOutput2; Abc_Obj_t * pRoot1, * pRoot2, * pMiter; @@ -352,7 +348,7 @@ Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) ***********************************************************************/ Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues ) { - char Buffer[100]; + char Buffer[1000]; Abc_Ntk_t * pNtkMiter; Abc_Obj_t * pRoot, * pOutput1; int Value, i; @@ -418,7 +414,7 @@ Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues ) ***********************************************************************/ Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 ) { - char Buffer[100]; + char Buffer[1000]; Abc_Ntk_t * pNtkMiter; Abc_Obj_t * pRoot, * pOutput1, * pOutput2, * pMiter; @@ -665,7 +661,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ) ***********************************************************************/ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) { - char Buffer[100]; + char Buffer[1000]; ProgressBar * pProgress; Abc_Ntk_t * pNtkFrames; Abc_Obj_t * pLatch, * pLatchNew; @@ -717,8 +713,6 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) { pLatchNew = Abc_NtkLatch(pNtkFrames, i); Abc_ObjAddFanin( pLatchNew, pLatch->pCopy ); - Vec_PtrPush( pNtkFrames->vCis, pLatchNew ); - Vec_PtrPush( pNtkFrames->vCos, pLatchNew ); Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) ); } } @@ -728,6 +722,9 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) // remove dangling nodes Abc_AigCleanup( pNtkFrames->pManFunc ); + // reorder the latches + Abc_NtkOrderCisCos( pNtkFrames ); + // make sure that everything is okay if ( !Abc_NtkCheck( pNtkFrames ) ) { @@ -773,6 +770,12 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame ) Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer ); Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) ); } + // add the new asserts + Abc_NtkForEachAssert( pNtk, pNode, i ) + { + Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer ); + Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) ); + } // transfer the implementation of the latch drivers to the latches Abc_NtkForEachLatch( pNtk, pLatch, i ) pLatch->pNext = Abc_ObjChild0Copy(pLatch); @@ -795,7 +798,7 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame ) ***********************************************************************/ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFrameMapping addFrameMapping, void* arg ) { - char Buffer[100]; + char Buffer[1000]; ProgressBar * pProgress; Abc_Ntk_t * pNtkFrames; Vec_Ptr_t * vNodes; @@ -854,9 +857,6 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram { pLatchNew = Abc_NtkLatch(pNtkFrames, i); Abc_ObjAddFanin( pLatchNew, pLatch->pCopy ); - - Vec_PtrPush( pNtkFrames->vCis, pLatchNew ); - Vec_PtrPush( pNtkFrames->vCos, pLatchNew ); Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) ); } } @@ -865,6 +865,9 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram // remove dangling nodes Abc_AigCleanup( pNtkFrames->pManFunc ); + + // reorder the latches + Abc_NtkOrderCisCos( pNtkFrames ); // make sure that everything is okay if ( !Abc_NtkCheck( pNtkFrames ) ) diff --git a/src/base/abci/abcMv.c b/src/base/abci/abcMv.c new file mode 100644 index 00000000..2858b8a7 --- /dev/null +++ b/src/base/abci/abcMv.c @@ -0,0 +1,369 @@ +/**CFile**************************************************************** + + FileName [abcMv.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Multi-valued decomposition.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcMv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Mv_Man_t_ Mv_Man_t; +struct Mv_Man_t_ +{ + int nInputs; // the number of 4-valued input variables + int nFuncs; // the number of 4-valued functions + DdManager * dd; // representation of functions + DdNode * bValues[15][4]; // representation of i-sets + DdNode * bValueDcs[15][4]; // representation of i-sets don't-cares + DdNode * bFuncs[15]; // representation of functions +}; + +static void Abc_MvDecompose( Mv_Man_t * p ); +static void Abc_MvPrintStats( Mv_Man_t * p ); +static void Abc_MvRead( Mv_Man_t * p ); +static void Abc_MvDeref( Mv_Man_t * p ); +static DdNode * Abc_MvReadCube( DdManager * dd, char * pLine, int nVars ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MvExperiment() +{ + Mv_Man_t * p; + // get the functions + p = ALLOC( Mv_Man_t, 1 ); + memset( p, 0, sizeof(Mv_Man_t) ); + p->dd = Cudd_Init( 32, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + p->nFuncs = 15; + p->nInputs = 9; + Abc_MvRead( p ); + // process the functions + Abc_MvPrintStats( p ); +// Cudd_ReduceHeap( p->dd, CUDD_REORDER_SYMM_SIFT, 1 ); +// Abc_MvPrintStats( p ); + // try detecting support reducing bound set + Abc_MvDecompose( p ); + + // remove the manager + Abc_MvDeref( p ); + Extra_StopManager( p->dd ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MvPrintStats( Mv_Man_t * p ) +{ + int i, v; + for ( i = 0; i < 15; i++ ) + { + printf( "%2d : ", i ); + printf( "%3d (%2d) ", Cudd_DagSize(p->bFuncs[i])-1, Cudd_SupportSize(p->dd, p->bFuncs[i]) ); + for ( v = 0; v < 4; v++ ) + printf( "%d = %3d (%2d) ", v, Cudd_DagSize(p->bValues[i][v])-1, Cudd_SupportSize(p->dd, p->bValues[i][v]) ); + printf( "\n" ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_MvReadCube( DdManager * dd, char * pLine, int nVars ) +{ + DdNode * bCube, * bVar, * bTemp; + int i; + bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube ); + for ( i = 0; i < nVars; i++ ) + { + if ( pLine[i] == '-' ) + continue; + else if ( pLine[i] == '0' ) // 0 + bVar = Cudd_Not( Cudd_bddIthVar(dd, 29-i) ); + else if ( pLine[i] == '1' ) // 1 + bVar = Cudd_bddIthVar(dd, 29-i); + else assert(0); + bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube ); + Cudd_RecursiveDeref( dd, bTemp ); + } + Cudd_Deref( bCube ); + return bCube; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MvRead( Mv_Man_t * p ) +{ + FILE * pFile; + char Buffer[1000], * pLine; + DdNode * bCube, * bTemp, * bProd, * bVar0, * bVar1, * bCubeSum; + int i, v; + + // start the cube + bCubeSum = Cudd_ReadLogicZero(p->dd); Cudd_Ref( bCubeSum ); + + // start the values + for ( i = 0; i < 15; i++ ) + for ( v = 0; v < 4; v++ ) + { + p->bValues[i][v] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bValues[i][v] ); + p->bValueDcs[i][v] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bValueDcs[i][v] ); + } + + // read the file + pFile = fopen( "input.pla", "r" ); + while ( fgets( Buffer, 1000, pFile ) ) + { + if ( Buffer[0] == '#' ) + continue; + if ( Buffer[0] == '.' ) + { + if ( Buffer[1] == 'e' ) + break; + continue; + } + + // get the cube + bCube = Abc_MvReadCube( p->dd, Buffer, 18 ); Cudd_Ref( bCube ); + + // add it to the values of the output functions + pLine = Buffer + 19; + for ( i = 0; i < 15; i++ ) + { + if ( pLine[2*i] == '-' && pLine[2*i+1] == '-' ) + { + for ( v = 0; v < 4; v++ ) + { + p->bValueDcs[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValueDcs[i][v], bCube ); Cudd_Ref( p->bValueDcs[i][v] ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + continue; + } + else if ( pLine[2*i] == '0' && pLine[2*i+1] == '0' ) // 0 + v = 0; + else if ( pLine[2*i] == '1' && pLine[2*i+1] == '0' ) // 1 + v = 1; + else if ( pLine[2*i] == '0' && pLine[2*i+1] == '1' ) // 2 + v = 2; + else if ( pLine[2*i] == '1' && pLine[2*i+1] == '1' ) // 3 + v = 3; + else assert( 0 ); + // add the value + p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], bCube ); Cudd_Ref( p->bValues[i][v] ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + + // add the cube + bCubeSum = Cudd_bddOr( p->dd, bTemp = bCubeSum, bCube ); Cudd_Ref( bCubeSum ); + Cudd_RecursiveDeref( p->dd, bTemp ); + Cudd_RecursiveDeref( p->dd, bCube ); + } + + // add the complement of the domain to all values + for ( i = 0; i < 15; i++ ) + for ( v = 0; v < 4; v++ ) + { + if ( p->bValues[i][v] == Cudd_Not(Cudd_ReadOne(p->dd)) ) + continue; + p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], p->bValueDcs[i][v] ); Cudd_Ref( p->bValues[i][v] ); + Cudd_RecursiveDeref( p->dd, bTemp ); + p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], Cudd_Not(bCubeSum) ); Cudd_Ref( p->bValues[i][v] ); + Cudd_RecursiveDeref( p->dd, bTemp ); + } + printf( "Domain = %5.2f %%.\n", 100.0*Cudd_CountMinterm(p->dd, bCubeSum, 32)/Cudd_CountMinterm(p->dd, Cudd_ReadOne(p->dd), 32) ); + Cudd_RecursiveDeref( p->dd, bCubeSum ); + + // create each output function + for ( i = 0; i < 15; i++ ) + { + p->bFuncs[i] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bFuncs[i] ); + for ( v = 0; v < 4; v++ ) + { + bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 30), ((v & 1) == 0) ); + bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 31), ((v & 2) == 0) ); + bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bCube ); + bProd = Cudd_bddAnd( p->dd, p->bValues[i][v], bCube ); Cudd_Ref( bProd ); + Cudd_RecursiveDeref( p->dd, bCube ); + // add the value + p->bFuncs[i] = Cudd_bddOr( p->dd, bTemp = p->bFuncs[i], bProd ); Cudd_Ref( p->bFuncs[i] ); + Cudd_RecursiveDeref( p->dd, bTemp ); + Cudd_RecursiveDeref( p->dd, bProd ); + } + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MvDeref( Mv_Man_t * p ) +{ + int i, v; + for ( i = 0; i < 15; i++ ) + for ( v = 0; v < 4; v++ ) + { + Cudd_RecursiveDeref( p->dd, p->bValues[i][v] ); + Cudd_RecursiveDeref( p->dd, p->bValueDcs[i][v] ); + } + for ( i = 0; i < 15; i++ ) + Cudd_RecursiveDeref( p->dd, p->bFuncs[i] ); +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_MvDecompose( Mv_Man_t * p ) +{ + DdNode * bCofs[16], * bVarCube1, * bVarCube2, * bVarCube, * bCube, * bVar0, * bVar1;//, * bRes; + int k, i1, i2, v1, v2;//, c1, c2, Counter; + + bVar0 = Cudd_bddIthVar(p->dd, 30); + bVar1 = Cudd_bddIthVar(p->dd, 31); + bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bCube ); + + for ( k = 0; k < p->nFuncs; k++ ) + { + printf( "FUNCTION %d\n", k ); + for ( i1 = 0; i1 < p->nFuncs; i1++ ) + for ( i2 = i1+1; i2 < p->nFuncs; i2++ ) + { + Vec_Ptr_t * vCofs; + + for ( v1 = 0; v1 < 4; v1++ ) + { + bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i1 ), ((v1 & 1) == 0) ); + bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i1-1), ((v1 & 2) == 0) ); + bVarCube1 = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bVarCube1 ); + for ( v2 = 0; v2 < 4; v2++ ) + { + bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i2 ), ((v2 & 1) == 0) ); + bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i2-1), ((v2 & 2) == 0) ); + bVarCube2 = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bVarCube2 ); + bVarCube = Cudd_bddAnd( p->dd, bVarCube1, bVarCube2 ); Cudd_Ref( bVarCube ); + bCofs[v1 * 4 + v2] = Cudd_Cofactor( p->dd, p->bFuncs[k], bVarCube ); Cudd_Ref( bCofs[v1 * 4 + v2] ); + Cudd_RecursiveDeref( p->dd, bVarCube ); + Cudd_RecursiveDeref( p->dd, bVarCube2 ); + } + Cudd_RecursiveDeref( p->dd, bVarCube1 ); + } +/* + // check the compatibility of cofactors + Counter = 0; + for ( c1 = 0; c1 < 16; c1++ ) + { + for ( c2 = 0; c2 <= c1; c2++ ) + printf( " " ); + for ( c2 = c1+1; c2 < 16; c2++ ) + { + bRes = Cudd_bddAndAbstract( p->dd, bCofs[c1], bCofs[c2], bCube ); Cudd_Ref( bRes ); + if ( bRes == Cudd_ReadOne(p->dd) ) + { + printf( "+" ); + Counter++; + } + else + { + printf( " " ); + } + Cudd_RecursiveDeref( p->dd, bRes ); + } + printf( "\n" ); + } +*/ + + vCofs = Vec_PtrAlloc( 16 ); + for ( v1 = 0; v1 < 4; v1++ ) + for ( v2 = 0; v2 < 4; v2++ ) + Vec_PtrPushUnique( vCofs, bCofs[v1 * 4 + v2] ); + printf( "%d ", Vec_PtrSize(vCofs) ); + Vec_PtrFree( vCofs ); + + // free the cofactors + for ( v1 = 0; v1 < 4; v1++ ) + for ( v2 = 0; v2 < 4; v2++ ) + Cudd_RecursiveDeref( p->dd, bCofs[v1 * 4 + v2] ); + + printf( "\n" ); +// printf( "%2d, %2d : %3d\n", i1, i2, Counter ); + } + } + + Cudd_RecursiveDeref( p->dd, bCube ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index 2aad721b..f95591ab 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -48,12 +48,15 @@ ***********************************************************************/ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) { - int Num, Num2; + int Num;//, Num2; // Abc_NtkDetectMatching( pNtk ); // return; fprintf( pFile, "%-13s:", pNtk->pName ); - fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) ); + if ( Abc_NtkAssertNum(pNtk) ) + fprintf( pFile, " i/o/a = %4d/%4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk), Abc_NtkAssertNum(pNtk) ); + else + fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) ); if ( !Abc_NtkIsSeq(pNtk) ) fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) ); diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c index 23315223..85a58c32 100644 --- a/src/base/abci/abcProve.c +++ b/src/base/abci/abcProve.c @@ -30,7 +30,7 @@ extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, i extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUpdateLevel, bool fUseZeros, bool fUseDcs, bool fVerbose ); extern Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk ); -static Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue, int * pNumFails ); +static Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, sint64 nInspLimit, int * pRetValue, int * pNumFails, sint64 * pNumConfs, sint64 * pNumInspects ); static void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fVerbose ); @@ -56,13 +56,14 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) { Prove_Params_t * pParams = pPars; Abc_Ntk_t * pNtk, * pNtkTemp; - int RetValue, nIter, Counter, clk, timeStart = clock(); + int RetValue, nIter, nSatFails, Counter, clk, timeStart = clock(); + sint64 nSatConfs, nSatInspects, nInspectLimit; // get the starting network pNtk = *ppNtk; assert( Abc_NtkIsStrash(pNtk) ); assert( Abc_NtkPoNum(pNtk) == 1 ); - + if ( pParams->fVerbose ) { printf( "RESOURCE LIMITS: Iterations = %d. Rewriting = %s. Fraiging = %s.\n", @@ -79,7 +80,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) if ( !pParams->fUseRewriting && !pParams->fUseFraiging ) { clk = clock(); - RetValue = Abc_NtkMiterSat( pNtk, pParams->nMiteringLimitLast, 0, 0, 0 ); + RetValue = Abc_NtkMiterSat( pNtk, (sint64)pParams->nMiteringLimitLast, (sint64)0, 0, 0, NULL, NULL ); Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose ); *ppNtk = pNtk; return RetValue; @@ -98,11 +99,24 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) // try brute-force SAT clk = clock(); - RetValue = Abc_NtkMiterSat( pNtk, (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), 0, 0, 0 ); + nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0; + RetValue = Abc_NtkMiterSat( pNtk, (sint64)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), (sint64)nInspectLimit, 0, 0, &nSatConfs, &nSatInspects ); Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose ); if ( RetValue >= 0 ) break; + // add to the number of backtracks and inspects + pParams->nTotalBacktracksMade += nSatConfs; + pParams->nTotalInspectsMade += nSatInspects; + // check if global resource limit is reached + if ( (pParams->nTotalBacktrackLimit && pParams->nTotalBacktracksMade >= pParams->nTotalBacktrackLimit) || + (pParams->nTotalInspectLimit && pParams->nTotalInspectsMade >= pParams->nTotalInspectLimit) ) + { + printf( "Reached global limit on conflicts/inspects. Quitting.\n" ); + *ppNtk = pNtk; + return -1; + } + // try rewriting if ( pParams->fUseRewriting ) { @@ -131,18 +145,30 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) if ( pParams->fUseFraiging ) { - int nSatFails; // try FRAIGing clk = clock(); - pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)), &RetValue, &nSatFails ); Abc_NtkDelete( pNtkTemp ); + nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0; + pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)), nInspectLimit, &RetValue, &nSatFails, &nSatConfs, &nSatInspects ); Abc_NtkDelete( pNtkTemp ); Abc_NtkMiterPrint( pNtk, "FRAIGing ", clk, pParams->fVerbose ); // printf( "NumFails = %d\n", nSatFails ); if ( RetValue >= 0 ) break; + + // add to the number of backtracks and inspects + pParams->nTotalBacktracksMade += nSatConfs; + pParams->nTotalInspectsMade += nSatInspects; + // check if global resource limit is reached + if ( (pParams->nTotalBacktrackLimit && pParams->nTotalBacktracksMade >= pParams->nTotalBacktrackLimit) || + (pParams->nTotalInspectLimit && pParams->nTotalInspectsMade >= pParams->nTotalInspectLimit) ) + { + printf( "Reached global limit on conflicts/inspects. Quitting.\n" ); + *ppNtk = pNtk; + return -1; + } } } -/* + // try to prove it using brute force SAT if ( RetValue < 0 && pParams->fUseBdds ) { @@ -162,7 +188,6 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) pNtk = pNtkTemp; Abc_NtkMiterPrint( pNtk, "BDD building", clk, pParams->fVerbose ); } -*/ if ( RetValue < 0 ) { @@ -172,7 +197,8 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) fflush( stdout ); } clk = clock(); - RetValue = Abc_NtkMiterSat( pNtk, pParams->nMiteringLimitLast, 0, 0, 0 ); + nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0; + RetValue = Abc_NtkMiterSat( pNtk, (sint64)pParams->nMiteringLimitLast, (sint64)nInspectLimit, 0, 0, NULL, NULL ); Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose ); } @@ -197,7 +223,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue, int * pNumFails ) +Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, sint64 nInspLimit, int * pRetValue, int * pNumFails, sint64 * pNumConfs, sint64 * pNumInspects ) { Abc_Ntk_t * pNtkNew; Fraig_Params_t Params, * pParams = &Params; @@ -222,6 +248,7 @@ Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue, pParams->fTryProve = 0; // do not try to prove the final miter pParams->fDoSparse = 1; // try proving sparse functions pParams->fVerbose = 0; + pParams->nInspLimit = nInspLimit; // transform the target into a fraig pMan = Abc_NtkToFraig( pNtk, pParams, 0, 0 ); @@ -243,6 +270,8 @@ Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue, // save the return values *pRetValue = RetValue; *pNumFails = Fraig_ManReadSatFails( pMan ); + *pNumConfs = Fraig_ManReadConflicts( pMan ); + *pNumInspects = Fraig_ManReadInspects( pMan ); // delete the fraig manager Fraig_ManFree( pMan ); diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c index 9ea3ad71..3dd6c519 100644 --- a/src/base/abci/abcRefactor.c +++ b/src/base/abci/abcRefactor.c @@ -111,6 +111,9 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool // skip the constant node if ( Abc_NodeIsConst(pNode) ) continue; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + continue; // skip the nodes with many fanouts if ( Abc_ObjFanoutNum(pNode) > 1000 ) continue; diff --git a/src/base/abci/abcRenode.c b/src/base/abci/abcRenode.c index ea728858..f7d351d2 100644 --- a/src/base/abci/abcRenode.c +++ b/src/base/abci/abcRenode.c @@ -377,7 +377,7 @@ int Abc_NtkRenodeLimit( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax ) ***********************************************************************/ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ) { - Vec_Ptr_t * vCone = pNtk->vPtrTemp; + Vec_Ptr_t * vCone = Vec_PtrAlloc(10); Abc_Obj_t * pNode; int i, nFanouts, nConeSize; @@ -414,6 +414,7 @@ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ) while ( Abc_NtkRenodeLimit(pNode, vCone, nFaninMax) ); assert( vCone->nSize <= nFaninMax ); } + Vec_PtrFree(vCone); /* // make sure the fanin limit is met Abc_NtkForEachNode( pNtk, pNode, i ) diff --git a/src/base/abci/abcRestruct.c b/src/base/abci/abcRestruct.c index 49208772..d738123a 100644 --- a/src/base/abci/abcRestruct.c +++ b/src/base/abci/abcRestruct.c @@ -134,6 +134,9 @@ pManRst->timeCut += clock() - clk; // skip the constant node if ( Abc_NodeIsConst(pNode) ) continue; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + continue; // skip the node if it is inside the tree // if ( Abc_ObjFanoutNum(pNode) < 2 ) // continue; diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c index e9de4858..b0061b61 100644 --- a/src/base/abci/abcResub.c +++ b/src/base/abci/abcResub.c @@ -160,6 +160,9 @@ int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, bool fUpd // skip the constant node if ( Abc_NodeIsConst(pNode) ) continue; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + continue; // skip the nodes with many fanouts if ( Abc_ObjFanoutNum(pNode) > 1000 ) continue; @@ -278,7 +281,7 @@ Abc_ManRes_t * Abc_ManResubStart( int nLeavesMax, int nDivsMax ) pData = p->vSims->pArray[k]; for ( i = 0; i < p->nBits; i++ ) if ( i & (1 << k) ) - pData[i/32] |= (1 << (i%32)); + pData[i>>5] |= (1 << (i&31)); } // create the remaining divisors p->vDivs1UP = Vec_PtrAlloc( p->nDivsMax ); diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c index f11e5e9d..703f05d9 100644 --- a/src/base/abci/abcRewrite.c +++ b/src/base/abci/abcRewrite.c @@ -34,6 +34,7 @@ static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk ); static void Abc_NodePrintCuts( Abc_Obj_t * pNode ); +static void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -87,15 +88,39 @@ Rwr_ManAddTimeCuts( pManRwr, clock() - clk ); // skip the constant node if ( Abc_NodeIsConst(pNode) ) continue; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + continue; // skip the nodes with many fanouts if ( Abc_ObjFanoutNum(pNode) > 1000 ) continue; +//printf( "*******Node %d: \n", pNode->Id ); + // for each cut, try to resynthesize it nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros ); if ( nGain > 0 || nGain == 0 && fUseZeros ) { +// extern void Abc_RwrExpWithCut( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); + Dec_Graph_t * pGraph = Rwr_ManReadDecs(pManRwr); int fCompl = Rwr_ManReadCompl(pManRwr); + +// Abc_RwrExpWithCut( pNode, Rwr_ManReadLeaves(pManRwr) ); + +/* + { + Abc_Obj_t * pObj; + int i; + printf( "USING: (" ); + Vec_PtrForEachEntry( Rwr_ManReadLeaves(pManRwr), pObj, i ) + printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pObj)) ); + printf( ") Gain = %d.\n", nGain ); + } +*/ + +// if ( nGain > 0 ) +// Abc_ManShowCutCone( pNode, Rwr_ManReadLeaves(pManRwr) ); + /* if ( nGain > 0 ) { // print stats on the MFFC @@ -209,6 +234,163 @@ void Abc_NodePrintCuts( Abc_Obj_t * pNode ) } } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManRewritePrintDivs( Vec_Ptr_t * vDivs, int nLeaves ) +{ + Abc_Obj_t * pFanin, * pNode, * pRoot; + int i, k; + pRoot = Vec_PtrEntryLast(vDivs); + // print the nodes + Vec_PtrForEachEntry( vDivs, pNode, i ) + { + if ( i < nLeaves ) + { + printf( "%6d : %c\n", pNode->Id, 'a'+i ); + continue; + } + printf( "%6d : %2d = ", pNode->Id, i ); + // find the first fanin + Vec_PtrForEachEntry( vDivs, pFanin, k ) + if ( Abc_ObjFanin0(pNode) == pFanin ) + break; + if ( k < nLeaves ) + printf( "%c", 'a' + k ); + else + printf( "%d", k ); + printf( "%s ", Abc_ObjFaninC0(pNode)? "\'" : "" ); + // find the second fanin + Vec_PtrForEachEntry( vDivs, pFanin, k ) + if ( Abc_ObjFanin1(pNode) == pFanin ) + break; + if ( k < nLeaves ) + printf( "%c", 'a' + k ); + else + printf( "%d", k ); + printf( "%s ", Abc_ObjFaninC1(pNode)? "\'" : "" ); + if ( pNode == pRoot ) + printf( " root" ); + printf( "\n" ); + } + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManShowCutCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vDivs ) +{ + if ( Abc_NodeIsTravIdCurrent(pNode) ) + return; + Abc_NodeSetTravIdCurrent(pNode); + Abc_ManShowCutCone_rec( Abc_ObjFanin0(pNode), vDivs ); + Abc_ManShowCutCone_rec( Abc_ObjFanin1(pNode), vDivs ); + Vec_PtrPush( vDivs, pNode ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ) +{ + Abc_Ntk_t * pNtk = pNode->pNtk; + Abc_Obj_t * pObj; + Vec_Ptr_t * vDivs; + int i; + vDivs = Vec_PtrAlloc( 100 ); + Abc_NtkIncrementTravId( pNtk ); + Vec_PtrForEachEntry( vLeaves, pObj, i ) + { + Abc_NodeSetTravIdCurrent( Abc_ObjRegular(pObj) ); + Vec_PtrPush( vDivs, Abc_ObjRegular(pObj) ); + } + Abc_ManShowCutCone_rec( pNode, vDivs ); + Abc_ManRewritePrintDivs( vDivs, Vec_PtrSize(vLeaves) ); + Vec_PtrFree( vDivs ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_RwrExpWithCut_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, int fUseA ) +{ + if ( Vec_PtrFind(vLeaves, pNode) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pNode)) >= 0 ) + { + if ( fUseA ) + Abc_ObjRegular(pNode)->fMarkA = 1; + else + Abc_ObjRegular(pNode)->fMarkB = 1; + return; + } + assert( Abc_ObjIsNode(pNode) ); + Abc_RwrExpWithCut_rec( Abc_ObjFanin0(pNode), vLeaves, fUseA ); + Abc_RwrExpWithCut_rec( Abc_ObjFanin1(pNode), vLeaves, fUseA ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_RwrExpWithCut( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ) +{ + Abc_Obj_t * pObj; + int i, CountA, CountB; + Abc_RwrExpWithCut_rec( Abc_ObjFanin0(pNode), vLeaves, 1 ); + Abc_RwrExpWithCut_rec( Abc_ObjFanin1(pNode), vLeaves, 0 ); + CountA = CountB = 0; + Vec_PtrForEachEntry( vLeaves, pObj, i ) + { + CountA += Abc_ObjRegular(pObj)->fMarkA; + CountB += Abc_ObjRegular(pObj)->fMarkB; + Abc_ObjRegular(pObj)->fMarkA = 0; + Abc_ObjRegular(pObj)->fMarkB = 0; + } + printf( "(%d,%d:%d) ", CountA, CountB, CountA+CountB-Vec_PtrSize(vLeaves) ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcRr.c b/src/base/abci/abcRr.c index a9c61e1a..b3788d31 100644 --- a/src/base/abci/abcRr.c +++ b/src/base/abci/abcRr.c @@ -105,6 +105,9 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa p->nFanoutLevels = nFanoutLevels; p->nNodesOld = Abc_NtkNodeNum(pNtk); p->nLevelsOld = Abc_AigGetLevelNum(pNtk); + // remember latch values + Abc_NtkForEachLatch( pNtk, pNode, i ) + pNode->pNext = pNode->pData; // go through the nodes Abc_NtkCleanCopy(pNtk); nNodes = Abc_NtkObjNumMax(pNtk); @@ -119,6 +122,9 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa // skip the constant node if ( Abc_NodeIsConst(pNode) ) continue; + // skip persistant nodes + if ( Abc_NodeIsPersistant(pNode) ) + continue; // skip the nodes with many fanouts if ( Abc_ObjFanoutNum(pNode) > 1000 ) continue; @@ -209,6 +215,9 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa if ( fVerbose ) Abc_RRManPrintStats( p ); Abc_RRManStop( p ); + // restore latch values + Abc_NtkForEachLatch( pNtk, pNode, i ) + pNode->pData = pNode->pNext, pNode->pNext = NULL; // put the nodes into the DFS order and reassign their IDs Abc_NtkReassignIds( pNtk ); Abc_NtkGetLevelNum( pNtk ); @@ -692,6 +701,7 @@ Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vC // add the PI/PO names Abc_NtkAddDummyPiNames( pNtkNew ); Abc_NtkAddDummyPoNames( pNtkNew ); + Abc_NtkAddDummyAssertNames( pNtkNew ); // check if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) { diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c index 06376eed..b21278f7 100644 --- a/src/base/abci/abcSat.c +++ b/src/base/abci/abcSat.c @@ -42,12 +42,17 @@ static nMuxes; SeeAlso [] ***********************************************************************/ -int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFront, int fVerbose ) +int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fJFront, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects ) { solver * pSat; lbool status; int RetValue, clk; + if ( pNumConfs ) + *pNumConfs = 0; + if ( pNumInspects ) + *pNumInspects = 0; + assert( Abc_NtkIsStrash(pNtk) ); assert( Abc_NtkLatchNum(pNtk) == 0 ); @@ -78,7 +83,7 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFron clk = clock(); if ( fVerbose ) pSat->verbosity = 1; - status = solver_solve( pSat, NULL, NULL, nConfLimit, nImpLimit ); + status = solver_solve( pSat, NULL, NULL, (sint64)nConfLimit, (sint64)nInsLimit ); if ( status == l_Undef ) { // printf( "The problem timed out.\n" ); @@ -97,6 +102,7 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFron else assert( 0 ); // PRT( "SAT solver time", clock() - clk ); +// printf( "The number of conflicts = %d.\n", (int)pSat->solver_stats.conflicts ); // if the problem is SAT, get the counterexample if ( status == l_True ) @@ -109,6 +115,12 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFron // free the solver if ( fVerbose ) Asat_SatPrintStats( stdout, pSat ); + + if ( pNumConfs ) + *pNumConfs = (int)pSat->solver_stats.conflicts; + if ( pNumInspects ) + *pNumInspects = (int)pSat->solver_stats.inspects; + solver_delete( pSat ); return RetValue; } @@ -401,6 +413,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront ) Vec_Vec_t * vCircuit; int i, k, fUseMuxes = 1; int clk1 = clock(), clk; + int fOrderCiVarsFirst = 0; assert( Abc_NtkIsStrash(pNtk) ); @@ -431,6 +444,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront ) Vec_PtrPush( vNodes, pNode ); } */ + // collect the nodes that need clauses and top-level assignments Abc_NtkForEachCo( pNtk, pNode, i ) { @@ -526,6 +540,21 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront ) } } + // set preferred variables + if ( fOrderCiVarsFirst ) + { + int * pPrefVars = ALLOC( int, Abc_NtkCiNum(pNtk) ); + int nVars = 0; + Abc_NtkForEachCi( pNtk, pNode, i ) + { + if ( pNode->fMarkA == 0 ) + continue; + pPrefVars[nVars++] = (int)pNode->pCopy; + } + nVars = ABC_MIN( nVars, 10 ); + Asat_SolverSetPrefVars( pSat, pPrefVars, nVars ); + } + // create the variable order if ( fJFront ) { diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c index 08236edc..3665584e 100644 --- a/src/base/abci/abcSweep.c +++ b/src/base/abci/abcSweep.c @@ -571,12 +571,13 @@ int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose ) ***********************************************************************/ void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose ) { - Vec_Ptr_t * vFanout = pNode->pNtk->vPtrTemp; Abc_Obj_t * pFanout, * pDriver; + Vec_Ptr_t * vFanout; int i; assert( Abc_ObjFaninNum(pNode) < 2 ); assert( Abc_ObjFanoutNum(pNode) > 0 ); // iterate through the fanouts + vFanout = Vec_PtrAlloc( Abc_ObjFanoutNum(pNode) ); Abc_NodeCollectFanouts( pNode, vFanout ); Vec_PtrForEachEntry( vFanout, pFanout, i ) { @@ -607,6 +608,7 @@ void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose ) Abc_ObjPatchFanin( pFanout, pNode, pDriver ); } } + Vec_PtrFree( vFanout ); } /**Function************************************************************* diff --git a/src/base/abci/abcTrace.c b/src/base/abci/abcTrace.c index 0275c0a1..4abe235e 100644 --- a/src/base/abci/abcTrace.c +++ b/src/base/abci/abcTrace.c @@ -148,7 +148,7 @@ void Abc_HManStart() pData = p->vSims->pArray[k]; for ( i = 0; i < p->nBits; i++ ) if ( i & (1 << k) ) - pData[i/32] |= (1 << (i%32)); + pData[i>>5] |= (1 << (i&31)); } // allocate storage for the nodes p->pMmObj = Extra_MmFixedStart( sizeof(Abc_HObj_t) ); diff --git a/src/base/abci/abcVanEijk.c b/src/base/abci/abcVanEijk.c index 8d8784e0..81423c30 100644 --- a/src/base/abci/abcVanEijk.c +++ b/src/base/abci/abcVanEijk.c @@ -544,8 +544,6 @@ Abc_Ntk_t * Abc_NtkVanEijkFrames( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCorresp, int nF { pLatchNew = Abc_NtkLatch(pNtkFrames, i); Abc_ObjAddFanin( pLatchNew, pLatch->pCopy ); - Vec_PtrPush( pNtkFrames->vCis, pLatchNew ); - Vec_PtrPush( pNtkFrames->vCos, pLatchNew ); Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) ); pLatch->pNext = NULL; } diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c index e0c65058..d9478b04 100644 --- a/src/base/abci/abcVerify.c +++ b/src/base/abci/abcVerify.c @@ -44,7 +44,7 @@ static void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, SeeAlso [] ***********************************************************************/ -void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nImpLimit ) +void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit ) { Abc_Ntk_t * pMiter; Abc_Ntk_t * pCnf; @@ -85,7 +85,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI } // solve the CNF using the SAT solver - RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0, 0 ); + RetValue = Abc_NtkMiterSat( pCnf, (sint64)nConfLimit, (sint64)nInsLimit, 0, 0, NULL, NULL ); if ( RetValue == -1 ) printf( "Networks are undecided (SAT solver timed out).\n" ); else if ( RetValue == 0 ) @@ -178,7 +178,14 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV if ( RetValue == -1 ) printf( "Networks are undecided (resource limits is reached).\n" ); else if ( RetValue == 0 ) - printf( "Networks are NOT EQUIVALENT.\n" ); + { + int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel ); + if ( pSimInfo[0] != 1 ) + printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" ); + else + printf( "Networks are NOT EQUIVALENT.\n" ); + free( pSimInfo ); + } else printf( "Networks are equivalent.\n" ); if ( pMiter->pModel ) @@ -197,7 +204,7 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV SeeAlso [] ***********************************************************************/ -void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nImpLimit, int nFrames ) +void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit, int nFrames ) { Abc_Ntk_t * pMiter; Abc_Ntk_t * pFrames; @@ -257,7 +264,7 @@ void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI } // solve the CNF using the SAT solver - RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0, 0 ); + RetValue = Abc_NtkMiterSat( pCnf, (sint64)nConfLimit, (sint64)nInsLimit, 0, 0, NULL, NULL ); if ( RetValue == -1 ) printf( "Networks are undecided (SAT solver timed out).\n" ); else if ( RetValue == 0 ) @@ -709,6 +716,52 @@ void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pM if ( fRemove2 ) Abc_NtkDelete( pNtk2 ); } +/**Function************************************************************* + + Synopsis [Simulates buggy miter emailed by Mike.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSimulteBuggyMiter( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + int * pModel1, * pModel2, * pResult1, * pResult2; + char * vPiValues1 = "01001011100000000011010110101000000"; + char * vPiValues2 = "11001101011101011111110100100010001"; + + assert( strlen(vPiValues1) == (unsigned)Abc_NtkPiNum(pNtk) ); + assert( 1 == Abc_NtkPoNum(pNtk) ); + + pModel1 = ALLOC( int, Abc_NtkCiNum(pNtk) ); + Abc_NtkForEachPi( pNtk, pObj, i ) + pModel1[i] = vPiValues1[i] - '0'; + Abc_NtkForEachLatch( pNtk, pObj, i ) + pModel1[Abc_NtkPiNum(pNtk)+i] = ((int)pObj->pData) - 1; + + pResult1 = Abc_NtkVerifySimulatePattern( pNtk, pModel1 ); + printf( "Value = %d\n", pResult1[0] ); + + pModel2 = ALLOC( int, Abc_NtkCiNum(pNtk) ); + Abc_NtkForEachPi( pNtk, pObj, i ) + pModel2[i] = vPiValues2[i] - '0'; + Abc_NtkForEachLatch( pNtk, pObj, i ) + pModel2[Abc_NtkPiNum(pNtk)+i] = pResult1[Abc_NtkPoNum(pNtk)+i]; + + pResult2 = Abc_NtkVerifySimulatePattern( pNtk, pModel2 ); + printf( "Value = %d\n", pResult2[0] ); + + free( pModel1 ); + free( pModel2 ); + free( pResult1 ); + free( pResult2 ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/abci/module.make b/src/base/abci/module.make index 41223c0b..c297180d 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -11,6 +11,7 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcFraig.c \ src/base/abci/abcFxu.c \ src/base/abci/abcGen.c \ + src/base/abci/abcIvy.c \ src/base/abci/abcMap.c \ src/base/abci/abcMiter.c \ src/base/abci/abcNtbdd.c \ diff --git a/src/base/io/io.h b/src/base/io/io.h index b408293e..8c8d6bed 100644 --- a/src/base/io/io.h +++ b/src/base/io/io.h @@ -68,6 +68,7 @@ extern Abc_Ntk_t * Io_ReadPla( char * pFileName, int fCheck ); /*=== abcUtil.c ==========================================================*/ extern Abc_Obj_t * Io_ReadCreatePi( Abc_Ntk_t * pNtk, char * pName ); extern Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName ); +extern Abc_Obj_t * Io_ReadCreateAssert( Abc_Ntk_t * pNtk, char * pName ); extern Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO ); extern Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesIn[], int nInputs ); extern Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 ); diff --git a/src/base/io/ioReadBaf.c b/src/base/io/ioReadBaf.c index e2aa2109..8f4a8ec4 100644 --- a/src/base/io/ioReadBaf.c +++ b/src/base/io/ioReadBaf.c @@ -100,8 +100,6 @@ Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck ) pObj = Abc_NtkCreateLatch(pNtkNew); Abc_NtkLogicStoreName( pObj, pCur ); while ( *pCur++ ); Vec_PtrPush( vNodes, pObj ); - Vec_PtrPush( pNtkNew->vCis, pObj ); - Vec_PtrPush( pNtkNew->vCos, pObj ); } // get the pointer to the beginning of the node array diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c index 3d33e6a3..11dd2db1 100644 --- a/src/base/io/ioReadBlif.c +++ b/src/base/io/ioReadBlif.c @@ -33,6 +33,7 @@ struct Io_ReadBlif_t_ char * pFileName; // the name of the file Extra_FileReader_t * pReader; // the input file reader // current processing info + Abc_Ntk_t * pNtkMaster; // the primary network Abc_Ntk_t * pNtkCur; // the primary network int LineCur; // the line currently parsed // temporary storage for tokens @@ -54,6 +55,7 @@ static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p ); static Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ); static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); +static int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ); static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ); @@ -151,7 +153,7 @@ Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p ) // add this network as part of the hierarchy if ( pNtkMaster == NULL ) // no master network so far { - pNtkMaster = pNtk; + p->pNtkMaster = pNtkMaster = pNtk; continue; } // make sure hierarchy does not have the network with this name @@ -222,11 +224,12 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) } // read the inputs/outputs + if ( p->pNtkMaster == NULL ) pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) ); fTokensReady = fStatus = 0; for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ ) { - if ( iLine % 1000 == 0 ) + if ( p->pNtkMaster == NULL && iLine % 1000 == 0 ) Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL ); // consider different line types @@ -242,6 +245,8 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens ); else if ( !strcmp( pDirective, ".outputs" ) ) fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens ); + else if ( !strcmp( pDirective, ".asserts" ) ) + fStatus = Io_ReadBlifNetworkAsserts( p, p->vTokens ); else if ( !strcmp( pDirective, ".input_arrival" ) ) fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens ); else if ( !strcmp( pDirective, ".default_input_arrival" ) ) @@ -257,8 +262,10 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) } else if ( !strcmp( pDirective, ".blackbox" ) ) { - pNtk->ntkType = ABC_NTK_BLACKBOX; + pNtk->ntkType = ABC_NTK_NETLIST; pNtk->ntkFunc = ABC_FUNC_BLACKBOX; + Extra_MmFlexStop( pNtk->pManFunc, 0 ); + pNtk->pManFunc = NULL; } else printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName, @@ -268,6 +275,7 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) if ( fStatus == 1 ) return NULL; } + if ( p->pNtkMaster == NULL ) Extra_ProgressBarStop( pProgress ); return pNtk; } @@ -321,6 +329,25 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) SeeAlso [] ***********************************************************************/ +int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) +{ + int i; + for ( i = 1; i < vTokens->nSize; i++ ) + Io_ReadCreateAssert( p->pNtkCur, vTokens->pArray[i] ); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) { Abc_Ntk_t * pNtk = p->pNtkCur; @@ -340,7 +367,7 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) Abc_LatchSetInitDc( pLatch ); else { - ResetValue = atoi(vTokens->pArray[3]); + ResetValue = atoi(vTokens->pArray[vTokens->nSize-1]); if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); @@ -870,50 +897,55 @@ int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, s // create the fanins of the box Abc_NtkForEachPi( pNtkModel, pObj, i ) pObj->pCopy = NULL; - Vec_PtrForEachEntryStart( pNames, pName, i, 1 ) + if ( Abc_NtkPiNum(pNtkModel) == 0 ) + Start = 1; + else { - pActual = Io_ReadBlifCleanName(pName); - if ( pActual == NULL ) - { - p->LineCur = (int)pBox->pCopy; - sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName ); - Io_ReadBlifPrintErrorMessage( p ); - return 1; - } - Length = pActual - pName - 1; - pName[Length] = 0; - // find the PI net with this name - pObj = Abc_NtkFindNet( pNtkModel, pName ); - if ( pObj == NULL ) - { - p->LineCur = (int)pBox->pCopy; - sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) ); - Io_ReadBlifPrintErrorMessage( p ); - return 1; - } - // get the PI - pObj = Abc_ObjFanin0(pObj); - // quit if this is not a PI net - if ( !Abc_ObjIsPi(pObj) ) - { - pName[Length] = '='; - Start = i; - break; - } - // remember the actual name in the net - if ( pObj->pCopy != NULL ) - { - p->LineCur = (int)pBox->pCopy; - sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName ); - Io_ReadBlifPrintErrorMessage( p ); - return 1; - } - pObj->pCopy = (void *)pActual; - // quit if we processed all PIs - if ( i == Abc_NtkPiNum(pNtkModel) ) + Vec_PtrForEachEntryStart( pNames, pName, i, 1 ) { - Start = i+1; - break; + pActual = Io_ReadBlifCleanName(pName); + if ( pActual == NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + Length = pActual - pName - 1; + pName[Length] = 0; + // find the PI net with this name + pObj = Abc_NtkFindNet( pNtkModel, pName ); + if ( pObj == NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + // get the PI + pObj = Abc_ObjFanin0(pObj); + // quit if this is not a PI net + if ( !Abc_ObjIsPi(pObj) ) + { + pName[Length] = '='; + Start = i; + break; + } + // remember the actual name in the net + if ( pObj->pCopy != NULL ) + { + p->LineCur = (int)pBox->pCopy; + sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName ); + Io_ReadBlifPrintErrorMessage( p ); + return 1; + } + pObj->pCopy = (void *)pActual; + // quit if we processed all PIs + if ( i == Abc_NtkPiNum(pNtkModel) ) + { + Start = i+1; + break; + } } } // create the fanins of the box @@ -986,6 +1018,8 @@ int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, s pObj->pCopy = NULL; // remove the array of names, assign the pointer to the model + Vec_PtrForEachEntry( pBox->pData, pName, i ) + free( pName ); Vec_PtrFree( pBox->pData ); pBox->pData = pNtkModel; return 0; diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c index fc37bc3f..5482eed4 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -80,6 +80,31 @@ Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName ) /**Function************************************************************* + Synopsis [Creates PO terminal and net.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Io_ReadCreateAssert( Abc_Ntk_t * pNtk, char * pName ) +{ + Abc_Obj_t * pNet, * pTerm; + // get the PO net + pNet = Abc_NtkFindNet( pNtk, pName ); + if ( pNet && Abc_ObjFaninNum(pNet) == 0 ) + printf( "Warning: Assert \"%s\" appears twice in the list.\n", pName ); + pNet = Abc_NtkFindOrCreateNet( pNtk, pName ); + // add the PO node + pTerm = Abc_NtkCreateAssert( pNtk ); + Abc_ObjAddFanin( pTerm, pNet ); + return pTerm; +} + +/**Function************************************************************* + Synopsis [Create a latch with the given input/output.] Description [By default, the latch value is unknown (ABC_INIT_NONE).] diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c index 1e27498d..8cbd0cd0 100644 --- a/src/base/io/ioWriteBlif.c +++ b/src/base/io/ioWriteBlif.c @@ -30,6 +30,7 @@ static void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ); static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ); static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ); static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ); +static void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode ); @@ -115,7 +116,7 @@ void Io_WriteBlifNetlist( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches ) void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ) { Abc_Ntk_t * pExdc; - assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsBlackbox(pNtk) ); + assert( Abc_NtkIsNetlist(pNtk) ); // write the model name fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) ); // write the network @@ -159,8 +160,16 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ) Io_NtkWritePos( pFile, pNtk, fWriteLatches ); fprintf( pFile, "\n" ); + // write the assertions + if ( Abc_NtkAssertNum(pNtk) ) + { + fprintf( pFile, ".asserts" ); + Io_NtkWriteAsserts( pFile, pNtk ); + fprintf( pFile, "\n" ); + } + // write the blackbox - if ( Abc_NtkIsBlackbox( pNtk ) ) + if ( Abc_NtkHasBlackbox( pNtk ) ) { fprintf( pFile, ".blackbox\n" ); return; @@ -296,6 +305,8 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ) { Abc_NtkForEachCo( pNtk, pTerm, i ) { + if ( Abc_ObjIsAssert(pTerm) ) + continue; pNet = Abc_ObjFanin0(pTerm); // get the line length after this name is written AddedLength = strlen(Abc_ObjName(pNet)) + 1; @@ -313,6 +324,45 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ) } } +/**Function************************************************************* + + Synopsis [Writes the assertion list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pTerm, * pNet; + int LineLength; + int AddedLength; + int NameCounter; + int i; + + LineLength = 8; + NameCounter = 0; + + Abc_NtkForEachAssert( pNtk, pTerm, i ) + { + pNet = Abc_ObjFanin0(pTerm); + // get the line length after this name is written + AddedLength = strlen(Abc_ObjName(pNet)) + 1; + if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) + { // write the line extender + fprintf( pFile, " \\\n" ); + // reset the line length + LineLength = 0; + NameCounter = 0; + } + fprintf( pFile, " %s", Abc_ObjName(pNet) ); + LineLength += AddedLength; + NameCounter++; + } +} /**Function************************************************************* diff --git a/src/base/io/ioWriteVer.c b/src/base/io/ioWriteVer.c index 75467d4d..e18f9b12 100644 --- a/src/base/io/ioWriteVer.c +++ b/src/base/io/ioWriteVer.c @@ -33,7 +33,6 @@ static void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start ); static void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start ); static void Io_WriteVerilogGates( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk ); -static void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros ); static void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk ); static int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk ); static char * Io_WriteVerilogGetName( Abc_Obj_t * pObj ); @@ -225,7 +224,7 @@ void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) int i, Counter, nNodes; // count the number of wires - nNodes = 0; + nNodes = Abc_NtkLatchNum(pNtk); Abc_NtkForEachNode( pNtk, pTerm, i ) { if ( i == 0 ) @@ -261,6 +260,24 @@ void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) LineLength += AddedLength; NameCounter++; } + Abc_NtkForEachLatch( pNtk, pTerm, i ) + { + pNet = Abc_ObjFanin0(pTerm); + Counter++; + // get the line length after this name is written + AddedLength = strlen(Abc_ObjName(pNet)) + 2; + if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) + { // write the line extender + fprintf( pFile, "\n " ); + // reset the line length + LineLength = 3; + NameCounter = 0; + } + fprintf( pFile, " %s%s", Io_WriteVerilogGetName(pNet), (Counter==nNodes)? "" : "," ); + LineLength += AddedLength; + NameCounter++; + } + assert( Counter == nNodes ); } /**Function************************************************************* @@ -325,12 +342,15 @@ void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk ) int i; Abc_NtkForEachLatch( pNtk, pLatch, i ) { +// fprintf( pFile, " always@(posedge gclk) begin %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); + fprintf( pFile, " always begin %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); + fprintf( pFile, " = %s; end\n", Abc_ObjName(Abc_ObjFanin0(pLatch)) ); if ( Abc_LatchInit(pLatch) == ABC_INIT_ZERO ) - fprintf( pFile, " initial begin %s = 1\'b0; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); +// fprintf( pFile, " initial begin %s = 1\'b0; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); + fprintf( pFile, " initial begin %s = 0; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); else if ( Abc_LatchInit(pLatch) == ABC_INIT_ONE ) - fprintf( pFile, " initial begin %s = 1\'b1; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); - fprintf( pFile, " always@(posedge gclk) begin %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); - fprintf( pFile, " = %s; end\n", Abc_ObjName(Abc_ObjFanin0(pLatch)) ); +// fprintf( pFile, " initial begin %s = 1\'b1; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); + fprintf( pFile, " initial begin %s = 1; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) ); } } @@ -378,7 +398,7 @@ void Io_WriteVerilogGates( FILE * pFile, Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk ) +void Io_WriteVerilogNodes2( FILE * pFile, Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj, * pFanin; int i, k, nFanins; @@ -390,7 +410,8 @@ void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk ) nFanins = Abc_ObjFaninNum(pObj); if ( nFanins == 0 ) { - fprintf( pFile, " assign %s = 1'b%d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) ); +// fprintf( pFile, " assign %s = 1'b%d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) ); + fprintf( pFile, " assign %s = %d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) ); continue; } if ( nFanins == 1 ) @@ -410,7 +431,7 @@ void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Writes the inputs.] + Synopsis [Writes the nodes.] Description [] @@ -419,24 +440,32 @@ void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros ) +void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pFanin; - int i, Counter = 2; - fprintf( pFile, "(.z (%s)", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) ); - Abc_ObjForEachFanin( pObj, pFanin, i ) - { - if ( Counter++ % 4 == 0 ) - fprintf( pFile, "\n " ); - fprintf( pFile, " .i%d (%s)", i+1, Io_WriteVerilogGetName(Abc_ObjFanin(pObj,i)) ); - } - for ( ; i < nInMax; i++ ) + Abc_Obj_t * pObj, * pFanin; + int i, k, nFanins; + char pOper[] = " ? ", Symb; + Abc_NtkForEachNode( pNtk, pObj, i ) { - if ( Counter++ % 4 == 0 ) - fprintf( pFile, "\n " ); - fprintf( pFile, " .i%d (%s)", i+1, fPadZeros? "1\'b0" : "1\'b1" ); + assert( Abc_SopGetCubeNum(pObj->pData) == 1 ); + nFanins = Abc_ObjFaninNum(pObj); + if ( nFanins == 0 ) + { + fprintf( pFile, " assign %s = 1'b%d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) ); + continue; + } + fprintf( pFile, " assign %s = ", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) ); + pOper[1] = Abc_SopIsComplement(pObj->pData) ? '|' : '&'; + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + Symb = ((char*)pObj->pData)[k]; + assert( Symb == '0' || Symb == '1' ); + if ( Symb == '0' ) + fprintf( pFile, "~" ); + fprintf( pFile, "%s%s", Io_WriteVerilogGetName(pFanin), (k==nFanins-1? "" : pOper) ); + } + fprintf( pFile, ";\n" ); } - fprintf( pFile, ");\n" ); } /**Function************************************************************* diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index 5747443c..23e304b3 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -446,7 +446,7 @@ void Abc_FrameDeleteAllNetworks( Abc_Frame_t * p ) Abc_NtkDelete( pNtk ); // set the current network empty p->pNtkCur = NULL; - fprintf( p->Out, "All networks have been deleted.\n" ); +// fprintf( p->Out, "All networks have been deleted.\n" ); } /**Function************************************************************* diff --git a/src/base/main/module.make b/src/base/main/module.make index 7a04e533..367f89f6 100644 --- a/src/base/main/module.make +++ b/src/base/main/module.make @@ -1,5 +1,5 @@ SRC += src/base/main/main.c \ src/base/main/mainFrame.c \ src/base/main/mainInit.c \ - src/base/main/mainUtils.c \ - src/base/main/libSupport.c + src/base/main/libSupport.c \ + src/base/main/mainUtils.c diff --git a/src/base/seq/seqAigCore.c b/src/base/seq/seqAigCore.c index 813b1ed8..358d306c 100644 --- a/src/base/seq/seqAigCore.c +++ b/src/base/seq/seqAigCore.c @@ -319,6 +319,7 @@ int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int // add the PI/PO names Abc_NtkAddDummyPiNames( pNtkProb ); Abc_NtkAddDummyPoNames( pNtkProb ); + Abc_NtkAddDummyAssertNames( pNtkProb ); // make sure everything is okay with the network structure if ( !Abc_NtkDoCheck( pNtkProb ) ) @@ -358,7 +359,7 @@ int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int // solve the miter clk = clock(); // RetValue = Abc_NtkMiterSat_OldAndRusty( pNtkCnf, 30, 0 ); - RetValue = Abc_NtkMiterSat( pNtkCnf, 500000, 50000000, 0, 0 ); + RetValue = Abc_NtkMiterSat( pNtkCnf, (sint64)500000, (sint64)50000000, 0, 0, NULL, NULL ); if ( fVerbose ) if ( clock() - clk > 100 ) { diff --git a/src/base/seq/seqCreate.c b/src/base/seq/seqCreate.c index b0c2e084..a553e06f 100644 --- a/src/base/seq/seqCreate.c +++ b/src/base/seq/seqCreate.c @@ -110,17 +110,23 @@ Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ) pNtkNew->nObjs++; } pNtkNew->nNodes = pNtk->nNodes; - pNtkNew->nPis = pNtk->nPis; - pNtkNew->nPos = pNtk->nPos; // create PI/PO and their names Abc_NtkForEachPi( pNtk, pObj, i ) { + Vec_PtrPush( pNtkNew->vPis, pObj->pCopy ); Vec_PtrPush( pNtkNew->vCis, pObj->pCopy ); Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); } Abc_NtkForEachPo( pNtk, pObj, i ) { + Vec_PtrPush( pNtkNew->vPos, pObj->pCopy ); + Vec_PtrPush( pNtkNew->vCos, pObj->pCopy ); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); + } + Abc_NtkForEachAssert( pNtk, pObj, i ) + { + Vec_PtrPush( pNtkNew->vAsserts, pObj->pCopy ); Vec_PtrPush( pNtkNew->vCos, pObj->pCopy ); Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); } @@ -252,7 +258,7 @@ void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk ) Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pObjNew, * pFaninNew; + Abc_Obj_t * pObj, * pFaninNew; Seq_Lat_t * pRing; int i; @@ -297,11 +303,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) // add the latches and their names Abc_NtkAddDummyLatchNames( pNtkNew ); - Abc_NtkForEachLatch( pNtkNew, pObjNew, i ) - { - Vec_PtrPush( pNtkNew->vCis, pObjNew ); - Vec_PtrPush( pNtkNew->vCos, pObjNew ); - } + Abc_NtkOrderCisCos( pNtkNew ); // fix the problem with complemented and duplicated CO edges Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); if ( !Abc_NtkCheck( pNtkNew ) ) @@ -324,7 +326,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) Abc_Ntk_t * Abc_NtkSeqToLogicSop_old( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pObjNew, * pFaninNew; + Abc_Obj_t * pObj, * pFaninNew; int i; assert( Abc_NtkIsSeq(pNtk) ); @@ -371,11 +373,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop_old( Abc_Ntk_t * pNtk ) } // add the latches and their names Abc_NtkAddDummyLatchNames( pNtkNew ); - Abc_NtkForEachLatch( pNtkNew, pObjNew, i ) - { - Vec_PtrPush( pNtkNew->vCis, pObjNew ); - Vec_PtrPush( pNtkNew->vCos, pObjNew ); - } + Abc_NtkOrderCisCos( pNtkNew ); // fix the problem with complemented and duplicated CO edges Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); if ( !Abc_NtkCheck( pNtkNew ) ) diff --git a/src/base/seq/seqFpgaCore.c b/src/base/seq/seqFpgaCore.c index 6d0c8c97..79e44caf 100644 --- a/src/base/seq/seqFpgaCore.c +++ b/src/base/seq/seqFpgaCore.c @@ -280,7 +280,7 @@ Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtk ) Abc_Seq_t * p = pNtk->pManFunc; Abc_Ntk_t * pNtkMap; Vec_Ptr_t * vLeaves; - Abc_Obj_t * pObj, * pLatch, * pFaninNew; + Abc_Obj_t * pObj, * pFaninNew; Seq_Lat_t * pRing; int i; @@ -322,11 +322,7 @@ Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtk ) // add the latches and their names Abc_NtkAddDummyLatchNames( pNtkMap ); - Abc_NtkForEachLatch( pNtkMap, pLatch, i ) - { - Vec_PtrPush( pNtkMap->vCis, pLatch ); - Vec_PtrPush( pNtkMap->vCos, pLatch ); - } + Abc_NtkOrderCisCos( pNtkMap ); // fix the problem with complemented and duplicated CO edges Abc_NtkLogicMakeSimpleCos( pNtkMap, 1 ); // make the network minimum base diff --git a/src/base/seq/seqMapCore.c b/src/base/seq/seqMapCore.c index b1d4871e..a444ec58 100644 --- a/src/base/seq/seqMapCore.c +++ b/src/base/seq/seqMapCore.c @@ -370,7 +370,7 @@ Abc_Ntk_t * Seq_NtkSeqMapMapped( Abc_Ntk_t * pNtk ) Seq_Match_t * pMatch; Abc_Ntk_t * pNtkMap; Vec_Ptr_t * vLeaves; - Abc_Obj_t * pObj, * pLatch, * pFaninNew; + Abc_Obj_t * pObj, * pFaninNew; Seq_Lat_t * pRing; int i; @@ -413,11 +413,7 @@ Abc_Ntk_t * Seq_NtkSeqMapMapped( Abc_Ntk_t * pNtk ) // add the latches and their names Abc_NtkAddDummyLatchNames( pNtkMap ); - Abc_NtkForEachLatch( pNtkMap, pLatch, i ) - { - Vec_PtrPush( pNtkMap->vCis, pLatch ); - Vec_PtrPush( pNtkMap->vCos, pLatch ); - } + Abc_NtkOrderCisCos( pNtkMap ); // fix the problem with complemented and duplicated CO edges Abc_NtkLogicMakeSimpleCos( pNtkMap, 1 ); // make the network minimum base diff --git a/src/base/seq/seqRetCore.c b/src/base/seq/seqRetCore.c index 38915bf4..ba66a881 100644 --- a/src/base/seq/seqRetCore.c +++ b/src/base/seq/seqRetCore.c @@ -327,7 +327,7 @@ Abc_Ntk_t * Seq_NtkRetimeReconstruct( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkSeq ) Abc_Seq_t * p = pNtkSeq->pManFunc; Seq_Lat_t * pRing0, * pRing1; Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pObjNew, * pFanin, * pFaninNew, * pMirror; + Abc_Obj_t * pObj, * pFanin, * pFaninNew, * pMirror; Vec_Ptr_t * vMirrors; int i, k; @@ -408,11 +408,7 @@ Abc_Ntk_t * Seq_NtkRetimeReconstruct( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkSeq ) // add the latches and their names Abc_NtkAddDummyLatchNames( pNtkNew ); - Abc_NtkForEachLatch( pNtkNew, pObjNew, i ) - { - Vec_PtrPush( pNtkNew->vCis, pObjNew ); - Vec_PtrPush( pNtkNew->vCos, pObjNew ); - } + Abc_NtkOrderCisCos( pNtkNew ); // fix the problem with complemented and duplicated CO edges Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); if ( !Abc_NtkCheck( pNtkNew ) ) diff --git a/src/map/fpga/fpgaCut.c b/src/map/fpga/fpgaCut.c index 2f686711..01562708 100644 --- a/src/map/fpga/fpgaCut.c +++ b/src/map/fpga/fpgaCut.c @@ -1082,7 +1082,7 @@ Fpga_Cut_t * Fpga_CutSortCuts( Fpga_Man_t * pMan, Fpga_CutTable_t * p, Fpga_Cut_ nCuts = Fpga_CutList2Array( p->pCuts1, pList ); assert( nCuts <= FPGA_CUTS_MAX_COMPUTE ); // sort the cuts - qsort( (void *)p->pCuts1, nCuts, sizeof(Fpga_Cut_t *), + qsort( (void *)p->pCuts1, nCuts, sizeof(void *), (int (*)(const void *, const void *)) Fpga_CutSortCutsCompare ); // move them back into the list if ( nCuts > FPGA_CUTS_MAX_USE - 1 ) diff --git a/src/map/mapper/mapperTable.c b/src/map/mapper/mapperTable.c index e097ef57..d0cb7a01 100644 --- a/src/map/mapper/mapperTable.c +++ b/src/map/mapper/mapperTable.c @@ -325,7 +325,7 @@ void Map_SuperTableSortSupergates( Map_HashTable_t * p, int nSupersMax ) ppSupers[nSupers++] = pSuper; // sort by usage - qsort( (void *)ppSupers, nSupers, sizeof(int), + qsort( (void *)ppSupers, nSupers, sizeof(Map_Super_t *), (int (*)(const void *, const void *)) Map_SuperTableCompareSupergates ); assert( Map_SuperTableCompareSupergates( ppSupers, ppSupers + nSupers - 1 ) <= 0 ); @@ -380,7 +380,7 @@ void Map_SuperTableSortSupergatesByDelay( Map_HashTable_t * p, int nSupersMax ) if ( nSupers == 0 ) continue; // sort the gates by delay - qsort( (void *)ppSupers, nSupers, sizeof(int), + qsort( (void *)ppSupers, nSupers, sizeof(Map_Super_t *), (int (*)(const void *, const void *)) Map_SuperTableCompareGatesInList ); assert( Map_SuperTableCompareGatesInList( ppSupers, ppSupers + nSupers - 1 ) <= 0 ); // link them in the reverse order diff --git a/src/map/mapper/mapperTruth.c b/src/map/mapper/mapperTruth.c index bebb9b74..388b6dd3 100644 --- a/src/map/mapper/mapperTruth.c +++ b/src/map/mapper/mapperTruth.c @@ -89,14 +89,15 @@ void Map_MappingTruths( Map_Man_t * pMan ) ***********************************************************************/ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut ) -{ +{ // unsigned uCanon1, uCanon2; unsigned uTruth[2], uCanon[2]; unsigned char uPhases[16]; unsigned * uCanon2; char * pPhases2; - int fUseFast = 0; - int fUseRec = 1; + int fUseFast = 1; + int fUseSlow = 0; + int fUseRec = 0; // this does not work for Solaris extern int Map_CanonCompute( int nVarsMax, int nVarsReal, unsigned * pt, unsigned ** pptRes, char ** ppfRes ); @@ -117,6 +118,8 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut ) // compute the canonical form for the positive phase if ( fUseFast ) Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); + else if ( fUseSlow ) + Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); else if ( fUseRec ) { // Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); @@ -145,6 +148,8 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut ) uTruth[1] = ~uTruth[1]; if ( fUseFast ) Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); + else if ( fUseSlow ) + Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); else if ( fUseRec ) { // Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h index 6336f5ea..d404dbc6 100644 --- a/src/misc/extra/extra.h +++ b/src/misc/extra/extra.h @@ -464,9 +464,8 @@ extern unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, i #define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) #define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) #define REALLOC(type, obj, num) \ - (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \ - ((type *) malloc(sizeof(type) * (num))) - + ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num)))) extern long Extra_CpuTime(); extern int Extra_GetSoftDataLimit(); diff --git a/src/misc/extra/extraUtilBitMatrix.c b/src/misc/extra/extraUtilBitMatrix.c index 93cbbeac..b860a538 100644 --- a/src/misc/extra/extraUtilBitMatrix.c +++ b/src/misc/extra/extraUtilBitMatrix.c @@ -348,7 +348,7 @@ int Extra_BitMatrixCountOnesUpper( Extra_BitMat_t * p ) int i, k, nTotal = 0; for ( i = 0; i < p->nSize; i++ ) for ( k = i + 1; k < p->nSize; k++ ) - nTotal += ( (p->ppData[i][k/32] & (1 << (k%32))) > 0 ); + nTotal += ( (p->ppData[i][k>>5] & (1 << (k&31))) > 0 ); return nTotal; } diff --git a/src/misc/extra/extraUtilMisc.c b/src/misc/extra/extraUtilMisc.c index bd7f19ec..f62de314 100644 --- a/src/misc/extra/extraUtilMisc.c +++ b/src/misc/extra/extraUtilMisc.c @@ -1323,9 +1323,9 @@ void Extra_TruthExpand( int nVars, int nWords, unsigned * puTruth, unsigned uPha { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 }, { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 }, { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, - { 0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000 }, - { 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 }, - { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000 } + { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, + { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, + { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } }; static char Cases[256] = { 0, // 00000000 @@ -1922,12 +1922,12 @@ void Extra_TruthExpand( int nVars, int nWords, unsigned * puTruth, unsigned uPha puTruthR[i] = 0; nMints = (1 << nVars); for ( i = 0; i < nMints; i++ ) - if ( puTruth[i/32] & (1 << (i%32)) ) + if ( puTruth[i>>5] & (1 << (i&31)) ) { for ( iRes = 0, k = 0; k < 5; k++ ) if ( i & (1 << pPerm[k]) ) iRes |= (1 << k); - puTruthR[iRes/32] |= (1 << (iRes%32)); + puTruthR[iRes>>5] |= (1 << (iRes&31)); } } } @@ -2058,9 +2058,9 @@ unsigned ** Extra_Truths8() { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 }, { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 }, { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, - { 0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000 }, - { 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 }, - { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000 } + { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, + { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, + { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } }; static unsigned * puResult[8] = { uTruths[0], uTruths[1], uTruths[2], uTruths[3], uTruths[4], uTruths[5], uTruths[6], uTruths[7] diff --git a/src/misc/extra/extraUtilTruth.c b/src/misc/extra/extraUtilTruth.c index 74308ab2..a0c58025 100644 --- a/src/misc/extra/extraUtilTruth.c +++ b/src/misc/extra/extraUtilTruth.c @@ -264,15 +264,15 @@ DdNode * Extra_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int DdNode * bF0, * bF1, * bF; if ( nVars == 0 ) { - if ( pTruth[iBit/32] & (1 << iBit%32) ) + if ( pTruth[iBit>>5] & (1 << iBit&31) ) return b1; return b0; } if ( nVars == 5 ) { - if ( pTruth[iBit/32] == 0xFFFFFFFF ) + if ( pTruth[iBit>>5] == 0xFFFFFFFF ) return b1; - if ( pTruth[iBit/32] == 0 ) + if ( pTruth[iBit>>5] == 0 ) return b0; } // other special cases can be added diff --git a/src/misc/mvc/mvc.h b/src/misc/mvc/mvc.h index 650f698d..70834e0a 100644 --- a/src/misc/mvc/mvc.h +++ b/src/misc/mvc/mvc.h @@ -49,7 +49,7 @@ //////////////////////////////////////////////////////////////////////// // cube/list/cover/data -typedef unsigned long Mvc_CubeWord_t; +typedef unsigned int Mvc_CubeWord_t; typedef struct MvcCubeStruct Mvc_Cube_t; typedef struct MvcListStruct Mvc_List_t; typedef struct MvcCoverStruct Mvc_Cover_t; diff --git a/src/misc/nm/module.make b/src/misc/nm/module.make new file mode 100644 index 00000000..2a3820c7 --- /dev/null +++ b/src/misc/nm/module.make @@ -0,0 +1,2 @@ +SRC += src/misc/nm/nmApi.c \ + src/misc/nm/nmTable.c diff --git a/src/misc/nm/nm.h b/src/misc/nm/nm.h index 5b17aaed..9c96c8ba 100644 --- a/src/misc/nm/nm.h +++ b/src/misc/nm/nm.h @@ -52,10 +52,12 @@ extern Nm_Man_t * Nm_ManCreate( int nSize ); extern void Nm_ManFree( Nm_Man_t * p ); extern int Nm_ManNumEntries( Nm_Man_t * p ); extern char * Nm_ManStoreIdName( Nm_Man_t * p, int ObjId, char * pName, char * pSuffix ); +extern void Nm_ManDeleteIdName( Nm_Man_t * p, int ObjId ); extern char * Nm_ManCreateUniqueName( Nm_Man_t * p, int ObjId ); extern char * Nm_ManFindNameById( Nm_Man_t * p, int ObjId ); extern int Nm_ManFindIdByName( Nm_Man_t * p, char * pName, int * pSecond ); extern void Nm_ManPrintTables( Nm_Man_t * p ); +extern Vec_Int_t * Nm_ManReturnNameIds( Nm_Man_t * p ); #ifdef __cplusplus } diff --git a/src/misc/nm/nmApi.c b/src/misc/nm/nmApi.c index 72ec24e6..3a9ac074 100644 --- a/src/misc/nm/nmApi.c +++ b/src/misc/nm/nmApi.c @@ -135,6 +135,31 @@ char * Nm_ManStoreIdName( Nm_Man_t * p, int ObjId, char * pName, char * pSuffix return pEntry->Name; } +/**Function************************************************************* + + Synopsis [Creates a new entry in the name manager.] + + Description [Returns 1 if the entry with the given object ID + already exists in the name manager.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Nm_ManDeleteIdName( Nm_Man_t * p, int ObjId ) +{ + Nm_Entry_t * pEntry; + pEntry = Nm_ManTableLookupId(p, ObjId); + if ( pEntry == NULL ) + { + printf( "Nm_ManDeleteIdName(): This entry is not in the table.\n" ); + return; + } + // remove entry from the table + Nm_ManTableDelete( p, pEntry ); +} + /**Function************************************************************* @@ -255,6 +280,28 @@ void Nm_ManPrintTables( Nm_Man_t * p ) printf( "\n" ); } +/**Function************************************************************* + + Synopsis [Return the IDs of objects with names.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Nm_ManReturnNameIds( Nm_Man_t * p ) +{ + Vec_Int_t * vNameIds; + int i; + vNameIds = Vec_IntAlloc( p->nEntries ); + for ( i = 0; i < p->nBins; i++ ) + if ( p->pBinsI2N[i] ) + Vec_IntPush( vNameIds, p->pBinsI2N[i]->ObjId ); + return vNameIds; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/misc/nm/nmInt.h b/src/misc/nm/nmInt.h index d0475c23..43901993 100644 --- a/src/misc/nm/nmInt.h +++ b/src/misc/nm/nmInt.h @@ -30,6 +30,7 @@ extern "C" { //////////////////////////////////////////////////////////////////////// #include "extra.h" +#include "vec.h" #include "nm.h" //////////////////////////////////////////////////////////////////////// diff --git a/src/misc/util/util_hack.h b/src/misc/util/util_hack.h index a9b90e61..71c77321 100644 --- a/src/misc/util/util_hack.h +++ b/src/misc/util/util_hack.h @@ -73,8 +73,8 @@ extern "C" { #define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) #define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) #define REALLOC(type, obj, num) \ - (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \ - ((type *) malloc(sizeof(type) * (num))) + ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num)))) extern long Extra_CpuTime(); extern int Extra_GetSoftDataLimit(); diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index 5a627623..fd8dbc86 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -540,6 +540,27 @@ static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry ) /**Function************************************************************* + Synopsis [Inserts the entry while preserving the increasing order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry ) +{ + int i; + for ( i = 0; i < p->nSize; i++ ) + if ( p->pArray[i] == Entry ) + return 1; + Vec_IntPushOrder( p, Entry ); + return 0; +} + +/**Function************************************************************* + Synopsis [] Description [] diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h index 65314af6..63dcc9b8 100644 --- a/src/misc/vec/vecPtr.h +++ b/src/misc/vec/vecPtr.h @@ -472,6 +472,26 @@ static inline void * Vec_PtrPop( Vec_Ptr_t * p ) /**Function************************************************************* + Synopsis [Find entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry ) +{ + int i; + for ( i = 0; i < p->nSize; i++ ) + if ( p->pArray[i] == Entry ) + return i; + return -1; +} + +/**Function************************************************************* + Synopsis [] Description [] diff --git a/src/misc/vec/vecStr.h b/src/misc/vec/vecStr.h index 5549d374..4cda06f0 100644 --- a/src/misc/vec/vecStr.h +++ b/src/misc/vec/vecStr.h @@ -494,10 +494,10 @@ static inline int Vec_StrSortCompare2( char * pp1, char * pp2 ) static inline void Vec_StrSort( Vec_Str_t * p, int fReverse ) { if ( fReverse ) - qsort( (void *)p->pArray, p->nSize, sizeof(int), + qsort( (void *)p->pArray, p->nSize, sizeof(char), (int (*)(const void *, const void *)) Vec_StrSortCompare2 ); else - qsort( (void *)p->pArray, p->nSize, sizeof(int), + qsort( (void *)p->pArray, p->nSize, sizeof(char), (int (*)(const void *, const void *)) Vec_StrSortCompare1 ); } diff --git a/src/opt/cut/Abc_NtkFindCi.c b/src/opt/cut/Abc_NtkFindCi.c new file mode 100644 index 00000000..203f9e6f --- /dev/null +++ b/src/opt/cut/Abc_NtkFindCi.c @@ -0,0 +1,988 @@ +/**CFile**************************************************************** + + FileName [cutPre22.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Precomputes truth tables for the 2x2 macro cell.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cutPre22.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cutInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define CUT_CELL_MVAR 9 + +typedef struct Cut_Cell_t_ Cut_Cell_t; +typedef struct Cut_CMan_t_ Cut_CMan_t; + +struct Cut_Cell_t_ +{ + Cut_Cell_t * pNext; // pointer to the next cell in the table + Cut_Cell_t * pNextVar; // pointer to the next cell of this support size + Cut_Cell_t * pParent; // pointer to the cell used to derive this one + int nUsed; // the number of times the cell is used + char Box[4]; // functions in the boxes + unsigned nVars : 4; // the number of variables + unsigned CrossBar0 : 4; // the variable set equal + unsigned CrossBar1 : 4; // the variable set equal + unsigned CrossBarPhase : 2; // the phase of the cross bar (0, 1, or 2) + unsigned CanonPhase : 18; // the canonical phase + char CanonPerm[CUT_CELL_MVAR+3]; // semicanonical permutation + short Store[2*CUT_CELL_MVAR]; // minterm counts in the cofactors + unsigned uTruth[1<<(CUT_CELL_MVAR-5)]; // the current truth table +}; + +struct Cut_CMan_t_ +{ + // storage for canonical cells + Extra_MmFixed_t * pMem; + st_table * tTable; + Cut_Cell_t * pSameVar[CUT_CELL_MVAR+1]; + // elementary truth tables + unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)]; + // temporary truth tables + unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)]; + unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)]; + unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)]; + unsigned uFinal[1<<(CUT_CELL_MVAR-5)]; + unsigned puAux[1<<(CUT_CELL_MVAR-5)]; + // statistical variables + int nTotal; + int nGood; + int nVarCounts[CUT_CELL_MVAR+1]; + int nSymGroups[CUT_CELL_MVAR+1]; + int nSymGroupsE[CUT_CELL_MVAR+1]; + int timeCanon; + int timeSupp; + int timeTable; + int nCellFound; + int nCellNotFound; +}; + +// NP-classes of functions of 3 variables (22) +static char * s_NP3[22] = { + " 0\n", // 00 const 0 // 0 vars + " 1\n", // 01 const 1 // 0 vars + "1 1\n", // 02 a // 1 vars + "11 1\n", // 03 ab // 2 vars + "11 0\n", // 04 (ab)' // 2 vars + "10 1\n01 1\n", // 05 a<+>b // 2 vars + "111 1\n", // 06 0s abc // 3 vars + "111 0\n", // 07 (abc)' // + "11- 1\n1-1 1\n", // 08 1p a(b+c) // + "11- 0\n1-1 0\n", // 09 (a(b+c))' // + "111 1\n100 1\n010 1\n001 1\n", // 10 2s a<+>b<+>c // + "10- 0\n1-0 0\n011 0\n", // 11 3p a<+>bc // + "101 1\n110 1\n", // 12 4p a(b<+>c) // + "101 0\n110 0\n", // 13 (a(b<+>c))' // + "11- 1\n1-1 1\n-11 1\n", // 14 5s ab+bc+ac // + "111 1\n000 1\n", // 15 6s abc+a'b'c' // + "111 0\n000 0\n", // 16 (abc+a'b'c')' // + "11- 1\n-11 1\n0-1 1\n", // 17 7 ab+bc+a'c // + "011 1\n101 1\n110 1\n", // 18 8s a'bc+ab'c+abc' // + "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' // + "100 1\n-11 1\n", // 20 9p ab'c'+bc // + "100 0\n-11 0\n" // 21 (ab'c'+bc)' // +}; + +// NP-classes of functions of 3 variables (22) +static char * s_NP3Names[22] = { + " const 0 ", + " const 1 ", + " a ", + " ab ", + " (ab)' ", + " a<+>b ", + "0s abc ", + " (abc)' ", + "1p a(b+c) ", + " (a(b+c))' ", + "2s a<+>b<+>c ", + "3p a<+>bc ", + "4p a(b<+>c) ", + " (a(b<+>c))' ", + "5s ab+bc+ac ", + "6s abc+a'b'c' ", + " (abc+a'b'c')' ", + "7 ab+bc+a'c ", + "8s a'bc+ab'c+abc' ", + " (a'bc+ab'c+abc')' ", + "9p ab'c'+bc ", + " (ab'c'+bc)' " +}; + +// the number of variables in each function +static int s_NP3VarNums[22] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; + +// NPN classes of functions of exactly 3 inputs (10) +static int s_NPNe3[10] = { 6, 8, 10, 11, 12, 14, 15, 17, 18, 20 }; + +// NPN classes of functions of exactly 3 inputs that are symmetric (5) +static int s_NPNe3s[10] = { 6, 10, 14, 15, 18 }; + +// NPN classes of functions of exactly 3 inputs (4) +static int s_NPNe3p[10] = { 8, 11, 12, 20 }; + +static Cut_CMan_t * Cut_CManStart(); +static void Cut_CManStop( Cut_CMan_t * p ); +static void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type ); +static void Cut_CellCanonicize( Cut_CMan_t * p, Cut_Cell_t * pCell ); +static int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell ); +static void Cut_CellSuppMin( Cut_Cell_t * pCell ); +static void Cut_CellCrossBar( Cut_Cell_t * pCell ); + + +static Cut_CMan_t * s_pCMan = NULL; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Start the precomputation manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CellLoad() +{ + FILE * pFile; + char * pFileName = "cells22_daomap_iwls.txt"; + char pString[1000]; + Cut_CMan_t * p; + Cut_Cell_t * pCell; + int Length; //, i; + pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\".\n", pFileName ); + return; + } + // start the manager + p = Cut_CManStart(); + // load truth tables + while ( fgets(pString, 1000, pFile) ) + { + Length = strlen(pString); + pString[Length--] = 0; + if ( Length == 0 ) + continue; + // derive the cell + pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); + memset( pCell, 0, sizeof(Cut_Cell_t) ); + pCell->nVars = Extra_Base2Log(Length*4); + pCell->nUsed = 1; +// Extra_TruthCopy( pCell->uTruth, pTruth, nVars ); + Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars ); + Cut_CellSuppMin( pCell ); +/* + // set the elementary permutation + for ( i = 0; i < (int)pCell->nVars; i++ ) + pCell->CanonPerm[i] = i; + // canonicize + pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); +*/ + // add to the table + p->nTotal++; + +// Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); printf( "\n" ); +// if ( p->nTotal == 500 ) +// break; + + if ( !Cut_CellTableLookup( p, pCell ) ) // new cell + p->nGood++; + } + printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood ); + fclose( pFile ); +// return p; +} + +/**Function************************************************************* + + Synopsis [Precomputes truth tables for the 2x2 macro cell.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CellPrecompute() +{ + Cut_CMan_t * p; + Cut_Cell_t * pCell, * pTemp; + int i1, i2, i3, i, j, k, c, clk = clock(), clk2 = clock(); + + p = Cut_CManStart(); + + // precompute truth tables + for ( i = 0; i < 22; i++ ) + Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i ); + for ( i = 0; i < 22; i++ ) + Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i ); + for ( i = 0; i < 22; i++ ) + Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i ); +/* + if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) ) + { + Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " ); + for ( i = 0; i < pCell->nVars; i++ ) + printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); + Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); + printf( "\n" ); + } +*/ +/* + // go through symmetric roots + for ( k = 0; k < 5; k++ ) + for ( i1 = 0; i1 < 22; i1++ ) + for ( i2 = i1; i2 < 22; i2++ ) + for ( i3 = i2; i3 < 22; i3++ ) + { + // derive the cell + pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); + memset( pCell, 0, sizeof(Cut_Cell_t) ); + pCell->nVars = 9; + pCell->Box[0] = s_NPNe3s[k]; + pCell->Box[1] = i1; + pCell->Box[2] = i2; + pCell->Box[3] = i3; + // fill in the truth table + Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] ); + // canonicize + Cut_CellCanonicize( pCell ); + + // add to the table + p->nTotal++; + if ( Cut_CellTableLookup( p, pCell ) ) // already exists + Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); + else + p->nGood++; + } + + // go through partially symmetric roots + for ( k = 0; k < 4; k++ ) + for ( i1 = 0; i1 < 22; i1++ ) + for ( i2 = 0; i2 < 22; i2++ ) + for ( i3 = i2; i3 < 22; i3++ ) + { + // derive the cell + pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); + memset( pCell, 0, sizeof(Cut_Cell_t) ); + pCell->nVars = 9; + pCell->Box[0] = s_NPNe3p[k]; + pCell->Box[1] = i1; + pCell->Box[2] = i2; + pCell->Box[3] = i3; + // fill in the truth table + Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] ); + // canonicize + Cut_CellCanonicize( pCell ); + + // add to the table + p->nTotal++; + if ( Cut_CellTableLookup( p, pCell ) ) // already exists + Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); + else + p->nGood++; + } + + // go through non-symmetric functions + for ( i1 = 0; i1 < 22; i1++ ) + for ( i2 = 0; i2 < 22; i2++ ) + for ( i3 = 0; i3 < 22; i3++ ) + { + // derive the cell + pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); + memset( pCell, 0, sizeof(Cut_Cell_t) ); + pCell->nVars = 9; + pCell->Box[0] = 17; + pCell->Box[1] = i1; + pCell->Box[2] = i2; + pCell->Box[3] = i3; + // fill in the truth table + Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 ); + // canonicize + Cut_CellCanonicize( pCell ); + + // add to the table + p->nTotal++; + if ( Cut_CellTableLookup( p, pCell ) ) // already exists + Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); + else + p->nGood++; + } +*/ + + // go through non-symmetric functions + for ( k = 0; k < 10; k++ ) + for ( i1 = 0; i1 < 22; i1++ ) + for ( i2 = 0; i2 < 22; i2++ ) + for ( i3 = 0; i3 < 22; i3++ ) + { + // derive the cell + pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); + memset( pCell, 0, sizeof(Cut_Cell_t) ); + pCell->nVars = 9; + pCell->Box[0] = s_NPNe3[k]; + pCell->Box[1] = i1; + pCell->Box[2] = i2; + pCell->Box[3] = i3; + // set the elementary permutation + for ( i = 0; i < (int)pCell->nVars; i++ ) + pCell->CanonPerm[i] = i; + // fill in the truth table + Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] ); + // minimize the support + Cut_CellSuppMin( pCell ); + + // canonicize + pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); + + // add to the table + p->nTotal++; + if ( Cut_CellTableLookup( p, pCell ) ) // already exists + Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); + else + { + p->nGood++; + p->nVarCounts[pCell->nVars]++; + + if ( pCell->nVars ) + for ( i = 0; i < (int)pCell->nVars-1; i++ ) + { + if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric + continue; + // i and i+1 can be symmetric + // find the end of this group + for ( j = i+1; j < (int)pCell->nVars; j++ ) + if ( pCell->Store[2*i] != pCell->Store[2*j] ) + break; + + if ( pCell->Store[2*i] == pCell->Store[2*i+1] ) + p->nSymGroupsE[j-i]++; + else + p->nSymGroups[j-i]++; + i = j - 1; + } +/* + if ( pCell->nVars == 3 ) + { + Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" ); + for ( i = 0; i < (int)pCell->nVars; i++ ) + printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); + printf( "\n" ); + } +*/ + } + } + + printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", p->nTotal, p->nGood, sizeof(Cut_Cell_t) ); + PRT( "Time", clock() - clk ); + printf( "Cells: " ); + for ( i = 0; i <= 9; i++ ) + printf( "%d=%d ", i, p->nVarCounts[i] ); + printf( "\nDiffs: " ); + for ( i = 0; i <= 9; i++ ) + printf( "%d=%d ", i, p->nSymGroups[i] ); + printf( "\nEquals: " ); + for ( i = 0; i <= 9; i++ ) + printf( "%d=%d ", i, p->nSymGroupsE[i] ); + printf( "\n" ); + + // continue adding new cells using support + for ( k = CUT_CELL_MVAR; k > 3; k-- ) + { + for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) + for ( i1 = 0; i1 < k; i1++ ) + for ( i2 = i1+1; i2 < k; i2++ ) + for ( c = 0; c < 3; c++ ) + { + // derive the cell + pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); + memset( pCell, 0, sizeof(Cut_Cell_t) ); + pCell->nVars = pTemp->nVars; + pCell->pParent = pTemp; + // set the elementary permutation + for ( i = 0; i < (int)pCell->nVars; i++ ) + pCell->CanonPerm[i] = i; + // fill in the truth table + Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars ); + // create the cross-bar + pCell->CrossBar0 = i1; + pCell->CrossBar1 = i2; + pCell->CrossBarPhase = c; + Cut_CellCrossBar( pCell ); + // minimize the support +//clk2 = clock(); + Cut_CellSuppMin( pCell ); +//p->timeSupp += clock() - clk2; + // canonicize +//clk2 = clock(); + pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); +//p->timeCanon += clock() - clk2; + + // add to the table +//clk2 = clock(); + p->nTotal++; + if ( Cut_CellTableLookup( p, pCell ) ) // already exists + Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); + else + { + p->nGood++; + p->nVarCounts[pCell->nVars]++; + + for ( i = 0; i < (int)pCell->nVars-1; i++ ) + { + if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric + continue; + // i and i+1 can be symmetric + // find the end of this group + for ( j = i+1; j < (int)pCell->nVars; j++ ) + if ( pCell->Store[2*i] != pCell->Store[2*j] ) + break; + + if ( pCell->Store[2*i] == pCell->Store[2*i+1] ) + p->nSymGroupsE[j-i]++; + else + p->nSymGroups[j-i]++; + i = j - 1; + } +/* + if ( pCell->nVars == 3 ) + { + Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" ); + for ( i = 0; i < (int)pCell->nVars; i++ ) + printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); + printf( "\n" ); + } +*/ + } +//p->timeTable += clock() - clk2; + } + + printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, sizeof(Cut_Cell_t) ); + PRT( "Time", clock() - clk ); + printf( "Cells: " ); + for ( i = 0; i <= 9; i++ ) + printf( "%d=%d ", i, p->nVarCounts[i] ); + printf( "\nDiffs: " ); + for ( i = 0; i <= 9; i++ ) + printf( "%d=%d ", i, p->nSymGroups[i] ); + printf( "\nEquals: " ); + for ( i = 0; i <= 9; i++ ) + printf( "%d=%d ", i, p->nSymGroupsE[i] ); + printf( "\n" ); + } +// printf( "\n" ); + PRT( "Supp ", p->timeSupp ); + PRT( "Canon", p->timeCanon ); + PRT( "Table", p->timeTable ); +// Cut_CManStop( p ); +} + +/**Function************************************************************* + + Synopsis [Check the table.] + + Description [Returns 1 if such a truth table already exists.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell ) +{ + Cut_Cell_t ** pSlot, * pTemp; + unsigned Hash; + Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum( pCell->nVars ) ); + if ( !st_find_or_add( p->tTable, (char *)Hash, (char ***)&pSlot ) ) + *pSlot = NULL; + for ( pTemp = *pSlot; pTemp; pTemp = pTemp->pNext ) + { + if ( pTemp->nVars != pCell->nVars ) + continue; + if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) ) + return 1; + } + // the entry is new + pCell->pNext = *pSlot; + *pSlot = pCell; + // add it to the variable support list + pCell->pNextVar = p->pSameVar[pCell->nVars]; + p->pSameVar[pCell->nVars] = pCell; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CellSuppMin( Cut_Cell_t * pCell ) +{ + static unsigned uTemp[1<<(CUT_CELL_MVAR-5)]; + unsigned * pIn, * pOut, * pTemp; + int i, k, Counter, Temp; + + // go backward through the support variables and remove redundant + for ( k = pCell->nVars - 1; k >= 0; k-- ) + if ( !Extra_TruthVarInSupport(pCell->uTruth, pCell->nVars, k) ) + { + // shift all the variables above this one + Counter = 0; + pIn = pCell->uTruth; pOut = uTemp; + for ( i = k; i < (int)pCell->nVars - 1; i++ ) + { + Extra_TruthSwapAdjacentVars( pOut, pIn, pCell->nVars, i ); + pTemp = pIn; pIn = pOut; pOut = pTemp; + // swap the support vars + Temp = pCell->CanonPerm[i]; + pCell->CanonPerm[i] = pCell->CanonPerm[i+1]; + pCell->CanonPerm[i+1] = Temp; + Counter++; + } + // return the function back into its place + if ( Counter & 1 ) + Extra_TruthCopy( pOut, pIn, pCell->nVars ); + // remove one variable + pCell->nVars--; +// Extra_PrintBinary( stdout, pCell->uTruth, (1<<pCell->nVars) ); printf( "\n" ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CellCrossBar( Cut_Cell_t * pCell ) +{ + static unsigned uTemp0[1<<(CUT_CELL_MVAR-5)]; + static unsigned uTemp1[1<<(CUT_CELL_MVAR-5)]; + Extra_TruthCopy( uTemp0, pCell->uTruth, pCell->nVars ); + Extra_TruthCopy( uTemp1, pCell->uTruth, pCell->nVars ); + if ( pCell->CanonPhase == 0 ) + { + Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 ); + Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 ); + Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 ); + Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 ); + } + else if ( pCell->CanonPhase == 1 ) + { + Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar0 ); + Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 ); + Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar0 ); + Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 ); + } + else if ( pCell->CanonPhase == 2 ) + { + Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 ); + Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar1 ); + Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 ); + Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 ); + } + else assert( 0 ); + Extra_TruthCombine( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type ) +{ + int nWords = Extra_TruthWordNum( nVars ); + int i; + + assert( Type < 22 ); + switch ( Type ) + { + // " 0\n", // 00 const 0 + case 0: + for ( i = 0; i < nWords; i++ ) + pOut[i] = 0; + return; + // " 1\n", // 01 const 1 + case 1: + for ( i = 0; i < nWords; i++ ) + pOut[i] = 0xFFFFFFFF; + return; + // "1 1\n", // 02 a + case 2: + for ( i = 0; i < nWords; i++ ) + pOut[i] = InA[i]; + return; + // "11 1\n", // 03 ab + case 3: + for ( i = 0; i < nWords; i++ ) + pOut[i] = InA[i] & InB[i]; + return; + // "11 0\n", // 04 (ab)' + case 4: + for ( i = 0; i < nWords; i++ ) + pOut[i] = ~(InA[i] & InB[i]); + return; + // "10 1\n01 1\n", // 05 a<+>b + case 5: + for ( i = 0; i < nWords; i++ ) + pOut[i] = InA[i] ^ InB[i]; + return; + // "111 1\n", // 06 + abc + case 6: + for ( i = 0; i < nWords; i++ ) + pOut[i] = InA[i] & InB[i] & InC[i]; + return; + // "111 0\n", // 07 (abc)' + case 7: + for ( i = 0; i < nWords; i++ ) + pOut[i] = ~(InA[i] & InB[i] & InC[i]); + return; + // "11- 1\n1-1 1\n", // 08 + a(b+c) + case 8: + for ( i = 0; i < nWords; i++ ) + pOut[i] = InA[i] & (InB[i] | InC[i]); + return; + // "11- 0\n1-1 0\n", // 09 (a(b+c))' + case 9: + for ( i = 0; i < nWords; i++ ) + pOut[i] = ~(InA[i] & (InB[i] | InC[i])); + return; + // "111 1\n100 1\n010 1\n001 1\n", // 10 + a<+>b<+>c + case 10: + for ( i = 0; i < nWords; i++ ) + pOut[i] = InA[i] ^ InB[i] ^ InC[i]; + return; + // "10- 0\n1-0 0\n011 0\n", // 11 + a<+>bc + case 11: + for ( i = 0; i < nWords; i++ ) + pOut[i] = InA[i] ^ (InB[i] & InC[i]); + return; + // "101 1\n110 1\n", // 12 + a(b<+>c) + case 12: + for ( i = 0; i < nWords; i++ ) + pOut[i] = InA[i] & (InB[i] ^ InC[i]); + return; + // "101 0\n110 0\n", // 13 (a(b<+>c))' + case 13: + for ( i = 0; i < nWords; i++ ) + pOut[i] = ~(InA[i] & (InB[i] ^ InC[i])); + return; + // "11- 1\n1-1 1\n-11 1\n", // 14 + ab+bc+ac + case 14: + for ( i = 0; i < nWords; i++ ) + pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (InA[i] & InC[i]); + return; + // "111 1\n000 1\n", // 15 + abc+a'b'c' + case 15: + for ( i = 0; i < nWords; i++ ) + pOut[i] = (InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]); + return; + // "111 0\n000 0\n", // 16 (abc+a'b'c')' + case 16: + for ( i = 0; i < nWords; i++ ) + pOut[i] = ~((InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i])); + return; + // "11- 1\n-11 1\n0-1 1\n", // 17 + ab+bc+a'c + case 17: + for ( i = 0; i < nWords; i++ ) + pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (~InA[i] & InC[i]); + return; + // "011 1\n101 1\n110 1\n", // 18 + a'bc+ab'c+abc' + case 18: + for ( i = 0; i < nWords; i++ ) + pOut[i] = (~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]); + return; + // "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' + case 19: + for ( i = 0; i < nWords; i++ ) + pOut[i] = ~((~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i])); + return; + // "100 1\n-11 1\n", // 20 + ab'c'+bc + case 20: + for ( i = 0; i < nWords; i++ ) + pOut[i] = (InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]); + return; + // "100 0\n-11 0\n" // 21 (ab'c'+bc)' + case 21: + for ( i = 0; i < nWords; i++ ) + pOut[i] = ~((InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i])); + return; + } +} + + +/**Function************************************************************* + + Synopsis [Start the precomputation manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cut_CMan_t * Cut_CManStart() +{ + Cut_CMan_t * p; + int i, k; + // start the manager + assert( sizeof(unsigned) == 4 ); + p = ALLOC( Cut_CMan_t, 1 ); + memset( p, 0, sizeof(Cut_CMan_t) ); + // start the table and the memory manager + p->tTable = st_init_table(st_ptrcmp,st_ptrhash); + p->pMem = Extra_MmFixedStart( sizeof(Cut_Cell_t) ); + // set elementary truth tables + for ( k = 0; k < CUT_CELL_MVAR; k++ ) + for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ ) + if ( i & (1 << k) ) + p->uInputs[k][i>>5] |= (1 << (i&31)); + s_pCMan = p; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CManStop( Cut_CMan_t * p ) +{ + st_free_table( p->tTable ); + Extra_MmFixedStop( p->pMem, 0 ); + free( p ); +} +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_CellIsRunning() +{ + return s_pCMan != NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CellDumpToFile() +{ + FILE * pFile; + Cut_CMan_t * p = s_pCMan; + Cut_Cell_t * pTemp; + char * pFileName = "celllib22.txt"; + int NumUsed[10][5] = {{0}}; + int BoxUsed[22][5] = {{0}}; + int i, k, Counter; + int clk = clock(); + + if ( p == NULL ) + { + printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" ); + return; + } + + // count the number of cells used + for ( k = CUT_CELL_MVAR; k >= 0; k-- ) + { + for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) + { + if ( pTemp->nUsed == 0 ) + NumUsed[k][0]++; + else if ( pTemp->nUsed < 10 ) + NumUsed[k][1]++; + else if ( pTemp->nUsed < 100 ) + NumUsed[k][2]++; + else if ( pTemp->nUsed < 1000 ) + NumUsed[k][3]++; + else + NumUsed[k][4]++; + + for ( i = 0; i < 4; i++ ) + if ( pTemp->nUsed == 0 ) + BoxUsed[ pTemp->Box[i] ][0]++; + else if ( pTemp->nUsed < 10 ) + BoxUsed[ pTemp->Box[i] ][1]++; + else if ( pTemp->nUsed < 100 ) + BoxUsed[ pTemp->Box[i] ][2]++; + else if ( pTemp->nUsed < 1000 ) + BoxUsed[ pTemp->Box[i] ][3]++; + else + BoxUsed[ pTemp->Box[i] ][4]++; + } + } + + printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound ); + for ( k = 0; k <= CUT_CELL_MVAR; k++ ) + { + printf( "%3d : ", k ); + for ( i = 0; i < 5; i++ ) + printf( "%8d ", NumUsed[k][i] ); + printf( "\n" ); + } + printf( "Box usage:\n" ); + for ( k = 0; k < 22; k++ ) + { + printf( "%3d : ", k ); + for ( i = 0; i < 5; i++ ) + printf( "%8d ", BoxUsed[k][i] ); + printf( " %s", s_NP3Names[k] ); + printf( "\n" ); + } + + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + printf( "Cut_CellDumpToFile: Cannout open output file.\n" ); + return; + } + + Counter = 0; + for ( k = 0; k <= CUT_CELL_MVAR; k++ ) + { + for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) + if ( pTemp->nUsed > 0 ) + { + Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) ); + fprintf( pFile, "\n" ); + Counter++; + } + fprintf( pFile, "\n" ); + } + fclose( pFile ); + + printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName ); + + PRT( "Time", clock() - clk ); +} + + +/**Function************************************************************* + + Synopsis [Looks up if the given function exists in the hash table.] + + Description [If the function exists, returns 1, meaning that it can be + implemented using two levels of 3-input LUTs. If the function does not + exist, return 0.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_CellTruthLookup( unsigned * pTruth, int nVars ) +{ + Cut_CMan_t * p = s_pCMan; + Cut_Cell_t * pTemp; + Cut_Cell_t Cell, * pCell = &Cell; + unsigned Hash; + int i; + + // cell manager is not defined + if ( p == NULL ) + { + printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" ); + return 0; + } + + // canonicize + memset( pCell, 0, sizeof(Cut_Cell_t) ); + pCell->nVars = nVars; + Extra_TruthCopy( pCell->uTruth, pTruth, nVars ); + Cut_CellSuppMin( pCell ); + // set the elementary permutation + for ( i = 0; i < (int)pCell->nVars; i++ ) + pCell->CanonPerm[i] = i; + // canonicize + pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); + + + // check if the cell exists + Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) ); + if ( st_lookup( p->tTable, (char *)Hash, (char **)&pTemp ) ) + { + for ( ; pTemp; pTemp = pTemp->pNext ) + { + if ( pTemp->nVars != pCell->nVars ) + continue; + if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) ) + { + pTemp->nUsed++; + p->nCellFound++; + return 1; + } + } + } + p->nCellNotFound++; + return 0; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/cut/cutMan.c b/src/opt/cut/cutMan.c index 0cd01bc9..22ea1cb6 100644 --- a/src/opt/cut/cutMan.c +++ b/src/opt/cut/cutMan.c @@ -45,6 +45,8 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams ) { Cut_Man_t * p; int clk = clock(); +// extern int nTruthDsd; +// nTruthDsd = 0; assert( pParams->nVarsMax >= 3 && pParams->nVarsMax <= CUT_SIZE_MAX ); p = ALLOC( Cut_Man_t, 1 ); memset( p, 0, sizeof(Cut_Man_t) ); @@ -114,6 +116,9 @@ void Cut_ManStop( Cut_Man_t * p ) { Cut_Cut_t * pCut; int i; +// extern int nTruthDsd; +// printf( "Decomposable cuts = %d.\n", nTruthDsd ); + Vec_PtrForEachEntry( p->vCutsNew, pCut, i ) if ( pCut != NULL ) { diff --git a/src/opt/cut/cutPre22.c b/src/opt/cut/cutPre22.c index 693978d6..203f9e6f 100644 --- a/src/opt/cut/cutPre22.c +++ b/src/opt/cut/cutPre22.c @@ -779,7 +779,7 @@ Cut_CMan_t * Cut_CManStart() for ( k = 0; k < CUT_CELL_MVAR; k++ ) for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ ) if ( i & (1 << k) ) - p->uInputs[k][i/32] |= (1 << (i%32)); + p->uInputs[k][i>>5] |= (1 << (i&31)); s_pCMan = p; return p; } diff --git a/src/opt/cut/cutTruth.c b/src/opt/cut/cutTruth.c index 2e36c9e1..c3514ad7 100644 --- a/src/opt/cut/cutTruth.c +++ b/src/opt/cut/cutTruth.c @@ -189,6 +189,9 @@ void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_C Extra_TruthNand( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax ); else Extra_TruthAnd( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax ); + +// Ivy_TruthTestOne( *Cut_CutReadTruth(pCut) ); + // quit if no fancy computation is needed if ( !p->pParams->fFancy ) return; diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c index af76cd84..1b23bb53 100644 --- a/src/opt/dec/decAbc.c +++ b/src/opt/dec/decAbc.c @@ -19,6 +19,7 @@ #include "abc.h" #include "dec.h" //#include "aig.h" +#include "ivy.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -238,6 +239,41 @@ Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) } */ +/**Function************************************************************* + + Synopsis [Transforms the decomposition graph into the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph ) +{ + Dec_Node_t * pNode; + Ivy_Obj_t * pAnd0, * pAnd1; + int i; + // check for constant function + if ( Dec_GraphIsConst(pGraph) ) + return Ivy_NotCond( Ivy_ManConst1(pMan), Dec_GraphIsComplement(pGraph) ); + // check for a literal + if ( Dec_GraphIsVar(pGraph) ) + return Ivy_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); + // build the AIG nodes corresponding to the AND gates of the graph + Dec_GraphForEachNode( pGraph, pNode, i ) + { + pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); + pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); + pNode->pFunc = Ivy_And( pAnd0, pAnd1 ); + } + // complement the result if necessary + return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/dec/decFactor.c b/src/opt/dec/decFactor.c index 210b69e5..dca422ea 100644 --- a/src/opt/dec/decFactor.c +++ b/src/opt/dec/decFactor.c @@ -258,16 +258,15 @@ Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover ) ***********************************************************************/ Dec_Edge_t Dec_FactorTrivialCube( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube, Vec_Int_t * vEdgeLits ) { -// Dec_Edge_t eNode; + Dec_Edge_t eNode; int iBit, Value; // create the factored form for each literal Vec_IntClear( vEdgeLits ); Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) if ( Value ) { -// eNode = Dec_EdgeCreate( iBit/2, iBit%2 ); // CST -// Vec_IntPush( vEdgeLits, Dec_EdgeToInt_(eNode) ); - Vec_IntPush( vEdgeLits, iBit ); + eNode = Dec_EdgeCreate( iBit/2, iBit%2 ); // CST + Vec_IntPush( vEdgeLits, Dec_EdgeToInt_(eNode) ); } // balance the factored forms return Dec_FactorTrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeLits->pArray, vEdgeLits->nSize, 0 ); diff --git a/src/opt/fxu/fxu.h b/src/opt/fxu/fxu.h index 6a1bb5e3..7025d019 100644 --- a/src/opt/fxu/fxu.h +++ b/src/opt/fxu/fxu.h @@ -37,9 +37,11 @@ extern "C" { /// STRUCTURE DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +#ifndef __cplusplus #ifndef bool #define bool int #endif +#endif typedef struct FxuDataStruct Fxu_Data_t; diff --git a/src/opt/rwr/rwr.h b/src/opt/rwr/rwr.h index 8de225e8..f8c40a7c 100644 --- a/src/opt/rwr/rwr.h +++ b/src/opt/rwr/rwr.h @@ -135,6 +135,7 @@ extern void Rwr_ManStop( Rwr_Man_t * p ); extern void Rwr_ManPrintStats( Rwr_Man_t * p ); extern void Rwr_ManPrintStatsFile( Rwr_Man_t * p ); extern void * Rwr_ManReadDecs( Rwr_Man_t * p ); +extern Vec_Ptr_t * Rwr_ManReadLeaves( Rwr_Man_t * p ); extern int Rwr_ManReadCompl( Rwr_Man_t * p ); extern void Rwr_ManAddTimeCuts( Rwr_Man_t * p, int Time ); extern void Rwr_ManAddTimeUpdate( Rwr_Man_t * p, int Time ); diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c index 55132a75..9ae9c18c 100644 --- a/src/opt/rwr/rwrEva.c +++ b/src/opt/rwr/rwrEva.c @@ -100,9 +100,16 @@ clk = clock(); p->nCutsGood++; clk2 = clock(); +/* + printf( "Considering: (" ); + Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) ); + printf( ")\n" ); +*/ // mark the fanin boundary Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) Abc_ObjRegular(pFanin)->vFanouts.nSize++; + // label MFFC with current ID Abc_NtkIncrementTravId( pNode->pNtk ); nNodesSaved = Abc_NodeMffcLabel( pNode ); @@ -136,6 +143,8 @@ p->timeRes += clock() - clk; if ( GainBest == -1 ) return -1; +// printf( "%d", nNodesSaveCur - GainBest ); + // copy the leaves Vec_PtrForEachEntry( p->vFanins, pFanin, i ) Dec_GraphNode(p->pGraph, i)->pFunc = pFanin; diff --git a/src/opt/rwr/rwrMan.c b/src/opt/rwr/rwrMan.c index 115065f5..b6d58d99 100644 --- a/src/opt/rwr/rwrMan.c +++ b/src/opt/rwr/rwrMan.c @@ -163,7 +163,11 @@ void Rwr_ManPrintStats( Rwr_Man_t * p ) printf( "The scores are:\n" ); for ( i = 0; i < 222; i++ ) if ( p->nScores[i] > 0 ) - printf( "%3d = %8d canon = %5d\n", i, p->nScores[i], p->pMapInv[i] ); + { + extern void Ivy_TruthDsdComputePrint( unsigned uTruth ); + printf( "%3d = %8d canon = %5d ", i, p->nScores[i], p->pMapInv[i] ); + Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[i] | ((unsigned)p->pMapInv[i] << 16) ); + } printf( "\n" ); } @@ -218,6 +222,22 @@ void * Rwr_ManReadDecs( Rwr_Man_t * p ) SeeAlso [] ***********************************************************************/ +Vec_Ptr_t * Rwr_ManReadLeaves( Rwr_Man_t * p ) +{ + return p->vFanins; +} + +/**Function************************************************************* + + Synopsis [Stops the resynthesis manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Rwr_ManReadCompl( Rwr_Man_t * p ) { return p->fCompl; diff --git a/src/opt/rwr/rwrTemp.c b/src/opt/rwr/rwrTemp.c new file mode 100644 index 00000000..3ffbd408 --- /dev/null +++ b/src/opt/rwr/rwrTemp.c @@ -0,0 +1,121 @@ +/**CFile**************************************************************** + + FileName [rwrCut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [DAG-aware AIG rewriting package.] + + Synopsis [Cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: rwrCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "rwr.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int pTruths[13719]; +static int pFreqs[13719]; +static int pPerm[13719]; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rwr_TempCompare( int * pNum1, int * pNum2 ) +{ + int Freq1 = pFreqs[*pNum1]; + int Freq2 = pFreqs[*pNum2]; + if ( Freq1 < Freq2 ) + return 1; + if ( Freq1 > Freq2 ) + return -1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rwr_Temp() +{ + char Buffer[32]; + int nFuncs = 13719; + int nEntries = 100; + unsigned uTruth; + int i, k; + FILE * pFile; + + pFile = fopen( "nnclass_stats5.txt", "r" ); + for ( i = 0; i < 13719; i++ ) + { + fscanf( pFile, "%s%d", Buffer, &pFreqs[i] ); + Extra_ReadHexadecimal( &uTruth, Buffer+2, 5 ); + pTruths[i] = uTruth; + } + fclose( pFile ); + + for ( i = 0; i < 13719; i++ ) + pPerm[i] = i; + + qsort( (void *)pPerm, 13719, sizeof(int), + (int (*)(const void *, const void *)) Rwr_TempCompare ); + + + pFile = fopen( "5npn_100.blif", "w" ); + fprintf( pFile, "# Most frequent NPN classes of 5 vars.\n" ); + fprintf( pFile, ".model 5npn\n" ); + fprintf( pFile, ".inputs a b c d e\n" ); + fprintf( pFile, ".outputs" ); + for ( i = 0; i < nEntries; i++ ) + fprintf( pFile, " %02d", i ); + fprintf( pFile, "\n" ); + + for ( i = 0; i < nEntries; i++ ) + { + fprintf( pFile, ".names a b c d e %02d\n", i ); + uTruth = pTruths[pPerm[i]]; + for ( k = 0; k < 32; k++ ) + if ( uTruth & (1 << k) ) + { + Extra_PrintBinary( pFile, &k, 5 ); + fprintf( pFile, " 1\n" ); + } + } + fprintf( pFile, ".end\n" ); + fclose( pFile ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/sim.h b/src/opt/sim/sim.h index 7f32fc34..7fcf5ae6 100644 --- a/src/opt/sim/sim.h +++ b/src/opt/sim/sim.h @@ -143,8 +143,8 @@ struct Sim_Pat_t_ /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -#define SIM_NUM_WORDS(n) ((n)/32 + (((n)%32) > 0)) -#define SIM_LAST_BITS(n) ((((n)%32) > 0)? (n)%32 : 32) +#define SIM_NUM_WORDS(n) (((n)>>5) + (((n)&31) > 0)) +#define SIM_LAST_BITS(n) ((((n)&31) > 0)? (n)&31 : 32) #define SIM_MASK_FULL (0xFFFFFFFF) #define SIM_MASK_BEG(n) (SIM_MASK_FULL >> (32-n)) diff --git a/src/opt/xyz/module.make b/src/opt/xyz/module.make deleted file mode 100644 index ae7dab0f..00000000 --- a/src/opt/xyz/module.make +++ /dev/null @@ -1,8 +0,0 @@ -SRC += src/opt/xyz/xyzBuild.c \ - src/opt/xyz/xyzCore.c \ - src/opt/xyz/xyzMan.c \ - src/opt/xyz/xyzMinEsop.c \ - src/opt/xyz/xyzMinMan.c \ - src/opt/xyz/xyzMinSop.c \ - src/opt/xyz/xyzMinUtil.c \ - src/opt/xyz/xyzTest.c diff --git a/src/opt/xyz/xyz.h b/src/opt/xyz/xyz.h deleted file mode 100644 index 4fec2150..00000000 --- a/src/opt/xyz/xyz.h +++ /dev/null @@ -1,110 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyz.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyz.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __XYZ_H__ -#define __XYZ_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "abc.h" -#include "xyzInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Xyz_Man_t_ Xyz_Man_t; -typedef struct Xyz_Obj_t_ Xyz_Obj_t; - -// storage for node information -struct Xyz_Obj_t_ -{ - Min_Cube_t * pCover[3]; // pos/neg/esop - Vec_Int_t * vSupp; // computed support (all nodes except CIs) -}; - -// storage for additional information -struct Xyz_Man_t_ -{ - // general characteristics - int nFaninMax; // the number of vars - int nCubesMax; // the limit on the number of cubes in the intermediate covers - int nWords; // the number of words - Vec_Int_t * vFanCounts; // fanout counts - Vec_Ptr_t * vObjStrs; // object structures - void * pMemory; // memory for the internal data strctures - Min_Man_t * pManMin; // the cub manager - int fUseEsop; // enables ESOPs - int fUseSop; // enables SOPs - // arrays to map local variables - Vec_Int_t * vComTo0; // mapping of common variables into first fanin - Vec_Int_t * vComTo1; // mapping of common variables into second fanin - Vec_Int_t * vPairs0; // the first var in each pair of common vars - Vec_Int_t * vPairs1; // the second var in each pair of common vars - Vec_Int_t * vTriv0; // trival support of the first node - Vec_Int_t * vTriv1; // trival support of the second node - // statistics - int nSupps; // supports created - int nSuppsMax; // the maximum number of supports - int nBoundary; // the boundary size - int nNodes; // the number of nodes processed -}; - -static inline Xyz_Obj_t * Abc_ObjGetStr( Abc_Obj_t * pObj ) { return Vec_PtrEntry(((Xyz_Man_t *)pObj->pNtk->pManCut)->vObjStrs, pObj->Id); } - -static inline void Abc_ObjSetSupp( Abc_Obj_t * pObj, Vec_Int_t * vVec ) { Abc_ObjGetStr(pObj)->vSupp = vVec; } -static inline Vec_Int_t * Abc_ObjGetSupp( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->vSupp; } - -static inline void Abc_ObjSetCover2( Abc_Obj_t * pObj, Min_Cube_t * pCov ) { Abc_ObjGetStr(pObj)->pCover[2] = pCov; } -static inline Min_Cube_t * Abc_ObjGetCover2( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->pCover[2]; } - -static inline void Abc_ObjSetCover( Abc_Obj_t * pObj, Min_Cube_t * pCov, int Pol ) { Abc_ObjGetStr(pObj)->pCover[Pol] = pCov; } -static inline Min_Cube_t * Abc_ObjGetCover( Abc_Obj_t * pObj, int Pol ) { return Abc_ObjGetStr(pObj)->pCover[Pol]; } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== xyzBuild.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk ); -/*=== xyzCore.c ===========================================================*/ -extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); -/*=== xyzMan.c ============================================================*/ -extern Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax ); -extern void Xyz_ManFree( Xyz_Man_t * p ); -extern void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj ); -/*=== xyzTest.c ===========================================================*/ -extern Abc_Ntk_t * Abc_NtkXyzTestSop( Abc_Ntk_t * pNtk ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - - diff --git a/src/opt/xyz/xyzBuild.c b/src/opt/xyz/xyzBuild.c deleted file mode 100644 index e32721e7..00000000 --- a/src/opt/xyz/xyzBuild.c +++ /dev/null @@ -1,379 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzBuild.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Network construction procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzBuild.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyz.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveCube( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp ) -{ - Vec_Int_t * vLits; - Abc_Obj_t * pNodeNew, * pFanin; - int i, iFanin, Lit; - // create empty cube - if ( pCube->nLits == 0 ) - return Abc_NodeCreateConst1(pNtkNew); - // get the literals of this cube - vLits = Vec_IntAlloc( 10 ); - Min_CubeGetLits( pCube, vLits ); - assert( pCube->nLits == (unsigned)vLits->nSize ); - // create special case when there is only one literal - if ( pCube->nLits == 1 ) - { - iFanin = Vec_IntEntry(vLits,0); - pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); - Lit = Min_CubeGetVar(pCube, iFanin); - assert( Lit == 1 || Lit == 2 ); - Vec_IntFree( vLits ); - if ( Lit == 1 )// negative - return Abc_NodeCreateInv( pNtkNew, pFanin->pCopy ); - return pFanin->pCopy; - } - assert( pCube->nLits > 1 ); - // create the AND cube - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - for ( i = 0; i < vLits->nSize; i++ ) - { - iFanin = Vec_IntEntry(vLits,i); - pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); - Lit = Min_CubeGetVar(pCube, iFanin); - assert( Lit == 1 || Lit == 2 ); - Vec_IntWriteEntry( vLits, i, Lit==1 ); - Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); - } - pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); - Vec_IntFree( vLits ); - return pNodeNew; -} - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveNode_rec( Xyz_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int Level ) -{ - Min_Cube_t * pCover, * pCube; - Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin; - Vec_Int_t * vSupp; - int Entry, nCubes, i; - - if ( Abc_ObjIsCi(pObj) ) - return pObj->pCopy; - assert( Abc_ObjIsNode(pObj) ); - // skip if already computed - if ( pObj->pCopy ) - return pObj->pCopy; - - // get the support and the cover - vSupp = Abc_ObjGetSupp( pObj ); - pCover = Abc_ObjGetCover2( pObj ); - assert( vSupp ); -/* - if ( pCover && pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) > 0 ) - { - printf( "%d\n ", pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) ); - Min_CoverWrite( stdout, pCover ); - } -*/ -/* - // print the support of this node - printf( "{ " ); - Vec_IntForEachEntry( vSupp, Entry, i ) - printf( "%d ", Entry ); - printf( "} cubes = %d\n", Min_CoverCountCubes( pCover ) ); -*/ - // process the fanins - Vec_IntForEachEntry( vSupp, Entry, i ) - { - pFanin = Abc_NtkObj(pObj->pNtk, Entry); - Abc_NtkXyzDeriveNode_rec( p, pNtkNew, pFanin, Level+1 ); - } - - // for each cube, construct the node - nCubes = Min_CoverCountCubes( pCover ); - if ( nCubes == 0 ) - pNodeNew = Abc_NodeCreateConst0(pNtkNew); - else if ( nCubes == 1 ) - pNodeNew = Abc_NtkXyzDeriveCube( pNtkNew, pObj, pCover, vSupp ); - else - { - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - Min_CoverForEachCube( pCover, pCube ) - { - pFaninNew = Abc_NtkXyzDeriveCube( pNtkNew, pObj, pCube, vSupp ); - Abc_ObjAddFanin( pNodeNew, pFaninNew ); - } - pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes ); - } -/* - printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level ); - Vec_IntForEachEntry( vSupp, Entry, i ) - { - pFanin = Abc_NtkObj(pObj->pNtk, Entry); - printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id ); - } - printf( "\n" ); - Min_CoverWrite( stdout, pCover ); -*/ - pObj->pCopy = pNodeNew; - return pNodeNew; -} - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj; - int i; - assert( Abc_NtkIsStrash(pNtk) ); - // perform strashing - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); - // reconstruct the network - Abc_NtkForEachCo( pNtk, pObj, i ) - { - Abc_NtkXyzDeriveNode_rec( p, pNtkNew, Abc_ObjFanin0(pObj), 0 ); -// printf( "*** CO %s : %d -> %d \n", Abc_ObjName(pObj), pObj->pCopy->Id, Abc_ObjFanin0(pObj)->pCopy->Id ); - } - // add the COs - Abc_NtkFinalize( pNtk, pNtkNew ); - Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); - // make sure everything is okay - if ( !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkXyzDerive: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - - - - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl ) -{ - assert( pObj->pCopy ); - if ( !fCompl ) - return pObj->pCopy; - if ( pObj->pCopy->pCopy == NULL ) - pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy ); - return pObj->pCopy->pCopy; - } - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveCubeInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp ) -{ - Vec_Int_t * vLits; - Abc_Obj_t * pNodeNew, * pFanin; - int i, iFanin, Lit; - // create empty cube - if ( pCube->nLits == 0 ) - return Abc_NodeCreateConst1(pNtkNew); - // get the literals of this cube - vLits = Vec_IntAlloc( 10 ); - Min_CubeGetLits( pCube, vLits ); - assert( pCube->nLits == (unsigned)vLits->nSize ); - // create special case when there is only one literal - if ( pCube->nLits == 1 ) - { - iFanin = Vec_IntEntry(vLits,0); - pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); - Lit = Min_CubeGetVar(pCube, iFanin); - assert( Lit == 1 || Lit == 2 ); - Vec_IntFree( vLits ); -// if ( Lit == 1 )// negative -// return Abc_NodeCreateInv( pNtkNew, pFanin->pCopy ); -// return pFanin->pCopy; - return Abc_NtkXyzDeriveInv( pNtkNew, pFanin, Lit==1 ); - } - assert( pCube->nLits > 1 ); - // create the AND cube - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - for ( i = 0; i < vLits->nSize; i++ ) - { - iFanin = Vec_IntEntry(vLits,i); - pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); - Lit = Min_CubeGetVar(pCube, iFanin); - assert( Lit == 1 || Lit == 2 ); - Vec_IntWriteEntry( vLits, i, Lit==1 ); -// Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); - Abc_ObjAddFanin( pNodeNew, Abc_NtkXyzDeriveInv( pNtkNew, pFanin, Lit==1 ) ); - } -// pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); - pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, NULL ); - Vec_IntFree( vLits ); - return pNodeNew; -} - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveNodeInv_rec( Xyz_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl ) -{ - Min_Cube_t * pCover, * pCube; - Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin; - Vec_Int_t * vSupp; - int Entry, nCubes, i; - - // skip if already computed - if ( pObj->pCopy ) - return Abc_NtkXyzDeriveInv( pNtkNew, pObj, fCompl ); - assert( Abc_ObjIsNode(pObj) ); - - // get the support and the cover - vSupp = Abc_ObjGetSupp( pObj ); - pCover = Abc_ObjGetCover2( pObj ); - assert( vSupp ); - - // process the fanins - Vec_IntForEachEntry( vSupp, Entry, i ) - { - pFanin = Abc_NtkObj(pObj->pNtk, Entry); - Abc_NtkXyzDeriveNodeInv_rec( p, pNtkNew, pFanin, 0 ); - } - - // for each cube, construct the node - nCubes = Min_CoverCountCubes( pCover ); - if ( nCubes == 0 ) - pNodeNew = Abc_NodeCreateConst0(pNtkNew); - else if ( nCubes == 1 ) - pNodeNew = Abc_NtkXyzDeriveCubeInv( pNtkNew, pObj, pCover, vSupp ); - else - { - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - Min_CoverForEachCube( pCover, pCube ) - { - pFaninNew = Abc_NtkXyzDeriveCubeInv( pNtkNew, pObj, pCube, vSupp ); - Abc_ObjAddFanin( pNodeNew, pFaninNew ); - } - pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes ); - } - - pObj->pCopy = pNodeNew; - return Abc_NtkXyzDeriveInv( pNtkNew, pObj, fCompl ); -} - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [The resulting network contains only pure AND/OR/EXOR gates - and inverters. This procedure is usedful to generate Verilog.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pNodeNew; - int i; - assert( Abc_NtkIsStrash(pNtk) ); - // perform strashing - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); - // reconstruct the network - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pNodeNew = Abc_NtkXyzDeriveNodeInv_rec( p, pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) ); - Abc_ObjAddFanin( pObj->pCopy, pNodeNew ); - } - // add the COs - Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); - // make sure everything is okay - if ( !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkXyzDeriveInv: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/xyz/xyzCore.c b/src/opt/xyz/xyzCore.c deleted file mode 100644 index e5089788..00000000 --- a/src/opt/xyz/xyzCore.c +++ /dev/null @@ -1,1025 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzCore.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Core procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyz.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NtkXyzCovers( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ); -static int Abc_NtkXyzCoversOne( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ); -static void Abc_NtkXyzCovers_rec( Xyz_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary ); -/* -static int Abc_NodeXyzPropagateEsop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ); -static int Abc_NodeXyzPropagateSop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ); -static int Abc_NodeXyzUnionEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); -static int Abc_NodeXyzUnionSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); -static int Abc_NodeXyzProductEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); -static int Abc_NodeXyzProductSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); -*/ - -static int Abc_NodeXyzPropagate( Xyz_Man_t * p, Abc_Obj_t * pObj ); -static Min_Cube_t * Abc_NodeXyzProduct( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ); -static Min_Cube_t * Abc_NodeXyzSum( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ); - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs decomposition.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ) -{ - Abc_Ntk_t * pNtkNew; - Xyz_Man_t * p; - - assert( Abc_NtkIsStrash(pNtk) ); - - // create the manager - p = Xyz_ManAlloc( pNtk, nFaninMax ); - p->fUseEsop = fUseEsop; - p->fUseSop = 1;//fUseSop; - pNtk->pManCut = p; - - // perform mapping - Abc_NtkXyzCovers( p, pNtk, fVerbose ); - - // derive the final network - if ( fUseInvs ) - pNtkNew = Abc_NtkXyzDeriveClean( p, pNtk ); - else - pNtkNew = Abc_NtkXyzDerive( p, pNtk ); -// pNtkNew = NULL; - - - Xyz_ManFree( p ); - pNtk->pManCut = NULL; - - // make sure that everything is okay - if ( pNtkNew && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkXyz: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Compute the supports.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkXyzCovers( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ) -{ - Abc_Obj_t * pObj; - int i, clk = clock(); - - // start the manager - p->vFanCounts = Abc_NtkFanoutCounts(pNtk); - - // set trivial cuts for the constant and the CIs - pObj = Abc_NtkConst1(pNtk); - pObj->fMarkA = 1; - Abc_NtkForEachCi( pNtk, pObj, i ) - pObj->fMarkA = 1; - - // perform iterative decomposition - for ( i = 0; ; i++ ) - { - if ( fVerbose ) - printf( "Iter %d : ", i+1 ); - if ( Abc_NtkXyzCoversOne(p, pNtk, fVerbose) ) - break; - } - - // clean the cut-point markers - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->fMarkA = 0; - -if ( fVerbose ) -{ -PRT( "Total", clock() - clk ); -} -} - -/**Function************************************************************* - - Synopsis [Compute the supports.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkXyzCoversOne( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ) -{ - ProgressBar * pProgress; - Abc_Obj_t * pObj; - Vec_Ptr_t * vBoundary; - int i, clk = clock(); - int Counter = 0; - int fStop = 1; - - // array to collect the nodes in the new boundary - vBoundary = Vec_PtrAlloc( 100 ); - - // start from the COs and mark visited nodes using pObj->fMarkB - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // skip the solved nodes (including the CIs) - pObj = Abc_ObjFanin0(pObj); - if ( pObj->fMarkA ) - { - Counter++; - continue; - } - - // traverse the cone starting from this node - if ( Abc_ObjGetSupp(pObj) == NULL ) - Abc_NtkXyzCovers_rec( p, pObj, vBoundary ); - - // count the number of solved cones - if ( Abc_ObjGetSupp(pObj) == NULL ) - fStop = 0; - else - Counter++; - -/* - printf( "%-15s : ", Abc_ObjName(pObj) ); - printf( "lev = %5d ", pObj->Level ); - if ( Abc_ObjGetSupp(pObj) == NULL ) - { - printf( "\n" ); - continue; - } - printf( "supp = %3d ", Abc_ObjGetSupp(pObj)->nSize ); - printf( "esop = %3d ", Min_CoverCountCubes( Abc_ObjGetCover2(pObj) ) ); - printf( "\n" ); -*/ - } - Extra_ProgressBarStop( pProgress ); - - // clean visited nodes - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->fMarkB = 0; - - // create the new boundary - p->nBoundary = 0; - Vec_PtrForEachEntry( vBoundary, pObj, i ) - { - if ( !pObj->fMarkA ) - { - pObj->fMarkA = 1; - p->nBoundary++; - } - } - Vec_PtrFree( vBoundary ); - -if ( fVerbose ) -{ - printf( "Outs = %4d (%4d) Node = %6d (%6d) Max = %6d Bound = %4d ", - Counter, Abc_NtkCoNum(pNtk), p->nSupps, Abc_NtkNodeNum(pNtk), p->nSuppsMax, p->nBoundary ); -PRT( "T", clock() - clk ); -} - return fStop; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkXyzCovers_rec( Xyz_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary ) -{ - Abc_Obj_t * pObj0, * pObj1; - // return if the support is already computed - if ( pObj->fMarkB || pObj->fMarkA )//|| Abc_ObjGetSupp(pObj) ) // why do we need Supp check here??? - return; - // mark as visited - pObj->fMarkB = 1; - // get the fanins - pObj0 = Abc_ObjFanin0(pObj); - pObj1 = Abc_ObjFanin1(pObj); - // solve for the fanins - Abc_NtkXyzCovers_rec( p, pObj0, vBoundary ); - Abc_NtkXyzCovers_rec( p, pObj1, vBoundary ); - // skip the node that spaced out - if ( !pObj0->fMarkA && !Abc_ObjGetSupp(pObj0) || // fanin is not ready - !pObj1->fMarkA && !Abc_ObjGetSupp(pObj1) || // fanin is not ready - !Abc_NodeXyzPropagate( p, pObj ) ) // node's support or covers cannot be computed - { - // save the nodes of the future boundary - if ( !pObj0->fMarkA && Abc_ObjGetSupp(pObj0) ) - Vec_PtrPush( vBoundary, pObj0 ); - if ( !pObj1->fMarkA && Abc_ObjGetSupp(pObj1) ) - Vec_PtrPush( vBoundary, pObj1 ); - return; - } - // consider dropping the fanin supports -// Abc_NodeXyzDropData( p, pObj0 ); -// Abc_NodeXyzDropData( p, pObj1 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NodeXyzSupport( Xyz_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1 ) -{ - Vec_Int_t * vSupp; - int k0, k1; - - assert( vSupp0 && vSupp1 ); - Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 ); - Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 ); - Vec_IntClear( p->vPairs0 ); - Vec_IntClear( p->vPairs1 ); - - vSupp = Vec_IntAlloc( vSupp0->nSize + vSupp1->nSize ); - for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; ) - { - if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] ) - { - Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); - Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); - Vec_IntPush( p->vPairs0, k0 ); - Vec_IntPush( p->vPairs1, k1 ); - Vec_IntPush( vSupp, vSupp0->pArray[k0] ); - k0++; k1++; - } - else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] ) - { - Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); - Vec_IntPush( vSupp, vSupp0->pArray[k0] ); - k0++; - } - else - { - Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); - Vec_IntPush( vSupp, vSupp1->pArray[k1] ); - k1++; - } - } - for ( ; k0 < vSupp0->nSize; k0++ ) - { - Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); - Vec_IntPush( vSupp, vSupp0->pArray[k0] ); - } - for ( ; k1 < vSupp1->nSize; k1++ ) - { - Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); - Vec_IntPush( vSupp, vSupp1->pArray[k1] ); - } -/* - printf( "Zero : " ); - for ( k0 = 0; k0 < vSupp0->nSize; k0++ ) - printf( "%d ", vSupp0->pArray[k0] ); - printf( "\n" ); - - printf( "One : " ); - for ( k1 = 0; k1 < vSupp1->nSize; k1++ ) - printf( "%d ", vSupp1->pArray[k1] ); - printf( "\n" ); - - printf( "Sum : " ); - for ( k0 = 0; k0 < vSupp->nSize; k0++ ) - printf( "%d ", vSupp->pArray[k0] ); - printf( "\n" ); - printf( "\n" ); -*/ - return vSupp; -} - -/**Function************************************************************* - - Synopsis [Propagates all types of covers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzPropagate( Xyz_Man_t * p, Abc_Obj_t * pObj ) -{ - Min_Cube_t * pCoverP = NULL, * pCoverN = NULL, * pCoverX = NULL; - Min_Cube_t * pCov0, * pCov1, * pCover0, * pCover1; - Vec_Int_t * vSupp, * vSupp0, * vSupp1; - Abc_Obj_t * pObj0, * pObj1; - int fCompl0, fCompl1; - - pObj0 = Abc_ObjFanin0( pObj ); - pObj1 = Abc_ObjFanin1( pObj ); - - if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); - if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); - - // get the resulting support - vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); - vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); - vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 ); - - // quit if support if too large - if ( vSupp->nSize > p->nFaninMax ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // get the complemented attributes - fCompl0 = Abc_ObjFaninC0( pObj ); - fCompl1 = Abc_ObjFaninC1( pObj ); - - // propagate ESOP - if ( p->fUseEsop ) - { - // get the covers - pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0); - pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1); - if ( pCov0 && pCov1 ) - { - // complement the first if needed - if ( !fCompl0 ) - pCover0 = pCov0; - else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube - pCover0 = pCov0->pNext; - else - pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0; - - // complement the second if needed - if ( !fCompl1 ) - pCover1 = pCov1; - else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube - pCover1 = pCov1->pNext; - else - pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1; - - // derive the new cover - pCoverX = Abc_NodeXyzProduct( p, pCover0, pCover1, 1, vSupp->nSize ); - } - } - // propagate SOPs - if ( p->fUseSop ) - { - // get the covers for the direct polarity - pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0); - pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1); - // derive the new cover - if ( pCover0 && pCover1 ) - pCoverP = Abc_NodeXyzProduct( p, pCover0, pCover1, 0, vSupp->nSize ); - - // get the covers for the inverse polarity - pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0); - pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1); - // derive the new cover - if ( pCover0 && pCover1 ) - pCoverN = Abc_NodeXyzSum( p, pCover0, pCover1, 0, vSupp->nSize ); - } - - // if none of the covers can be computed quit - if ( !pCoverX && !pCoverP && !pCoverN ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // set the covers - assert( Abc_ObjGetSupp(pObj) == NULL ); - Abc_ObjSetSupp( pObj, vSupp ); - Abc_ObjSetCover( pObj, pCoverP, 0 ); - Abc_ObjSetCover( pObj, pCoverN, 1 ); - Abc_ObjSetCover2( pObj, pCoverX ); -//printf( "%3d : %4d %4d %4d\n", pObj->Id, Min_CoverCountCubes(pCoverP), Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverX) ); - - // count statistics - p->nSupps++; - p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); - return 1; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeXyzProduct( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ) -{ - Min_Cube_t * pCube, * pCube0, * pCube1; - Min_Cube_t * pCover; - int i, Val0, Val1; - assert( pCover0 && pCover1 ); - - // clean storage - Min_ManClean( p->pManMin, nSupp ); - // go through the cube pairs - Min_CoverForEachCube( pCover0, pCube0 ) - Min_CoverForEachCube( pCover1, pCube1 ) - { - // go through the support variables of the cubes - for ( i = 0; i < p->vPairs0->nSize; i++ ) - { - Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); - Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); - if ( (Val0 & Val1) == 0 ) - break; - } - // check disjointness - if ( i < p->vPairs0->nSize ) - continue; - - if ( p->pManMin->nCubes > p->nCubesMax ) - { - pCover = Min_CoverCollect( p->pManMin, nSupp ); -//Min_CoverWriteFile( pCover, "large", 1 ); - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - - // create the product cube - pCube = Min_CubeAlloc( p->pManMin ); - - // add the literals - pCube->nLits = 0; - for ( i = 0; i < nSupp; i++ ) - { - if ( p->vComTo0->pArray[i] == -1 ) - Val0 = 3; - else - Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); - - if ( p->vComTo1->pArray[i] == -1 ) - Val1 = 3; - else - Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); - - if ( (Val0 & Val1) == 3 ) - continue; - - Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); - pCube->nLits++; - } - // add the cube to storage - if ( fEsop ) - Min_EsopAddCube( p->pManMin, pCube ); - else - Min_SopAddCube( p->pManMin, pCube ); - } - - // minimize the cover - if ( fEsop ) - Min_EsopMinimize( p->pManMin ); - else - Min_SopMinimize( p->pManMin ); - pCover = Min_CoverCollect( p->pManMin, nSupp ); - - // quit if the cover is too large - if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) - { -/* -Min_CoverWriteFile( pCover, "large", 1 ); - Min_CoverExpand( p->pManMin, pCover ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - pCover = Min_CoverCollect( p->pManMin, nSupp ); -*/ - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeXyzSum( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ) -{ - Min_Cube_t * pCube, * pCube0, * pCube1; - Min_Cube_t * pCover; - int i, Val0, Val1; - assert( pCover0 && pCover1 ); - - // clean storage - Min_ManClean( p->pManMin, nSupp ); - Min_CoverForEachCube( pCover0, pCube0 ) - { - // create the cube - pCube = Min_CubeAlloc( p->pManMin ); - pCube->nLits = 0; - for ( i = 0; i < p->vComTo0->nSize; i++ ) - { - if ( p->vComTo0->pArray[i] == -1 ) - continue; - Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); - if ( Val0 == 3 ) - continue; - Min_CubeXorVar( pCube, i, Val0 ^ 3 ); - pCube->nLits++; - } - if ( p->pManMin->nCubes > p->nCubesMax ) - { - pCover = Min_CoverCollect( p->pManMin, nSupp ); - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - // add the cube to storage - if ( fEsop ) - Min_EsopAddCube( p->pManMin, pCube ); - else - Min_SopAddCube( p->pManMin, pCube ); - } - Min_CoverForEachCube( pCover1, pCube1 ) - { - // create the cube - pCube = Min_CubeAlloc( p->pManMin ); - pCube->nLits = 0; - for ( i = 0; i < p->vComTo1->nSize; i++ ) - { - if ( p->vComTo1->pArray[i] == -1 ) - continue; - Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); - if ( Val1 == 3 ) - continue; - Min_CubeXorVar( pCube, i, Val1 ^ 3 ); - pCube->nLits++; - } - if ( p->pManMin->nCubes > p->nCubesMax ) - { - pCover = Min_CoverCollect( p->pManMin, nSupp ); - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - // add the cube to storage - if ( fEsop ) - Min_EsopAddCube( p->pManMin, pCube ); - else - Min_SopAddCube( p->pManMin, pCube ); - } - - // minimize the cover - if ( fEsop ) - Min_EsopMinimize( p->pManMin ); - else - Min_SopMinimize( p->pManMin ); - pCover = Min_CoverCollect( p->pManMin, nSupp ); - - // quit if the cover is too large - if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) - { - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - return pCover; -} - - - - - - - -#if 0 - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzPropagateEsop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ) -{ - Min_Cube_t * pCover, * pCover0, * pCover1, * pCov0, * pCov1; - Vec_Int_t * vSupp, * vSupp0, * vSupp1; - - if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); - if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); - - // get the resulting support - vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); - vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); - vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 ); - - // quit if support if too large - if ( vSupp->nSize > p->nFaninMax ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // get the covers - pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0); - pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1); - - // complement the first if needed - if ( !Abc_ObjFaninC0(pObj) ) - pCover0 = pCov0; - else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube - pCover0 = pCov0->pNext; - else - pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0; - - // complement the second if needed - if ( !Abc_ObjFaninC1(pObj) ) - pCover1 = pCov1; - else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube - pCover1 = pCov1->pNext; - else - pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1; - - // derive and minimize the cover (quit if too large) - if ( !Abc_NodeXyzProductEsop( p, pCover0, pCover1, vSupp->nSize ) ) - { - pCover = Min_CoverCollect( p->pManMin, vSupp->nSize ); - Min_CoverRecycle( p->pManMin, pCover ); - Vec_IntFree( vSupp ); - return 0; - } - - // minimize the cover - Min_EsopMinimize( p->pManMin ); - pCover = Min_CoverCollect( p->pManMin, vSupp->nSize ); - - // quit if the cover is too large - if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) - { - Min_CoverRecycle( p->pManMin, pCover ); - Vec_IntFree( vSupp ); - return 0; - } - - // count statistics - p->nSupps++; - p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); - - // set the covers - assert( Abc_ObjGetSupp(pObj) == NULL ); - Abc_ObjSetSupp( pObj, vSupp ); - Abc_ObjSetCover2( pObj, pCover ); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzPropagateSop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ) -{ - Min_Cube_t * pCoverP, * pCoverN, * pCover0, * pCover1; - Vec_Int_t * vSupp, * vSupp0, * vSupp1; - int fCompl0, fCompl1; - - if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); - if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); - - // get the resulting support - vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); - vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); - vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 ); - - // quit if support if too large - if ( vSupp->nSize > p->nFaninMax ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // get the complemented attributes - fCompl0 = Abc_ObjFaninC0(pObj); - fCompl1 = Abc_ObjFaninC1(pObj); - - // prepare the positive cover - pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0); - pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1); - - // derive and minimize the cover (quit if too large) - if ( !pCover0 || !pCover1 ) - pCoverP = NULL; - else if ( !Abc_NodeXyzProductSop( p, pCover0, pCover1, vSupp->nSize ) ) - { - pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize ); - Min_CoverRecycle( p->pManMin, pCoverP ); - pCoverP = NULL; - } - else - { - Min_SopMinimize( p->pManMin ); - pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize ); - // quit if the cover is too large - if ( Min_CoverCountCubes(pCoverP) > p->nFaninMax ) - { - Min_CoverRecycle( p->pManMin, pCoverP ); - pCoverP = NULL; - } - } - - // prepare the negative cover - pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0); - pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1); - - // derive and minimize the cover (quit if too large) - if ( !pCover0 || !pCover1 ) - pCoverN = NULL; - else if ( !Abc_NodeXyzUnionSop( p, pCover0, pCover1, vSupp->nSize ) ) - { - pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize ); - Min_CoverRecycle( p->pManMin, pCoverN ); - pCoverN = NULL; - } - else - { - Min_SopMinimize( p->pManMin ); - pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize ); - // quit if the cover is too large - if ( Min_CoverCountCubes(pCoverN) > p->nFaninMax ) - { - Min_CoverRecycle( p->pManMin, pCoverN ); - pCoverN = NULL; - } - } - - if ( pCoverP == NULL && pCoverN == NULL ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // count statistics - p->nSupps++; - p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); - - // set the covers - assert( Abc_ObjGetSupp(pObj) == NULL ); - Abc_ObjSetSupp( pObj, vSupp ); - Abc_ObjSetCover( pObj, pCoverP, 0 ); - Abc_ObjSetCover( pObj, pCoverN, 1 ); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzProductEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) -{ - Min_Cube_t * pCube, * pCube0, * pCube1; - int i, Val0, Val1; - - // clean storage - Min_ManClean( p->pManMin, nSupp ); - if ( pCover0 == NULL || pCover1 == NULL ) - return 1; - - // go through the cube pairs - Min_CoverForEachCube( pCover0, pCube0 ) - Min_CoverForEachCube( pCover1, pCube1 ) - { - // go through the support variables of the cubes - for ( i = 0; i < p->vPairs0->nSize; i++ ) - { - Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); - Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); - if ( (Val0 & Val1) == 0 ) - break; - } - // check disjointness - if ( i < p->vPairs0->nSize ) - continue; - - if ( p->pManMin->nCubes >= p->nCubesMax ) - return 0; - - // create the product cube - pCube = Min_CubeAlloc( p->pManMin ); - - // add the literals - pCube->nLits = 0; - for ( i = 0; i < nSupp; i++ ) - { - if ( p->vComTo0->pArray[i] == -1 ) - Val0 = 3; - else - Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); - - if ( p->vComTo1->pArray[i] == -1 ) - Val1 = 3; - else - Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); - - if ( (Val0 & Val1) == 3 ) - continue; - - Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); - pCube->nLits++; - } - // add the cube to storage - Min_EsopAddCube( p->pManMin, pCube ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzProductSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) -{ - return 1; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzUnionEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) -{ - Min_Cube_t * pCube, * pCube0, * pCube1; - int i, Val0, Val1; - - // clean storage - Min_ManClean( p->pManMin, nSupp ); - if ( pCover0 ) - { - Min_CoverForEachCube( pCover0, pCube0 ) - { - // create the cube - pCube = Min_CubeAlloc( p->pManMin ); - pCube->nLits = 0; - for ( i = 0; i < p->vComTo0->nSize; i++ ) - { - if ( p->vComTo0->pArray[i] == -1 ) - continue; - Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); - if ( Val0 == 3 ) - continue; - Min_CubeXorVar( pCube, i, Val0 ^ 3 ); - pCube->nLits++; - } - if ( p->pManMin->nCubes >= p->nCubesMax ) - return 0; - // add the cube to storage - Min_EsopAddCube( p->pManMin, pCube ); - } - } - if ( pCover1 ) - { - Min_CoverForEachCube( pCover1, pCube1 ) - { - // create the cube - pCube = Min_CubeAlloc( p->pManMin ); - pCube->nLits = 0; - for ( i = 0; i < p->vComTo1->nSize; i++ ) - { - if ( p->vComTo1->pArray[i] == -1 ) - continue; - Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); - if ( Val1 == 3 ) - continue; - Min_CubeXorVar( pCube, i, Val1 ^ 3 ); - pCube->nLits++; - } - if ( p->pManMin->nCubes >= p->nCubesMax ) - return 0; - // add the cube to storage - Min_EsopAddCube( p->pManMin, pCube ); - } - } - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzUnionSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) -{ - return 1; -} - - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/xyz/xyzMan.c b/src/opt/xyz/xyzMan.c deleted file mode 100644 index 844e8c13..00000000 --- a/src/opt/xyz/xyzMan.c +++ /dev/null @@ -1,144 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Decomposition manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyz.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax ) -{ - Xyz_Man_t * pMan; - Xyz_Obj_t * pMem; - Abc_Obj_t * pObj; - int i; - assert( pNtk->pManCut == NULL ); - - // start the manager - pMan = ALLOC( Xyz_Man_t, 1 ); - memset( pMan, 0, sizeof(Xyz_Man_t) ); - pMan->nFaninMax = nFaninMax; - pMan->nCubesMax = 2 * pMan->nFaninMax; - pMan->nWords = Abc_BitWordNum( nFaninMax * 2 ); - - // get the cubes - pMan->vComTo0 = Vec_IntAlloc( 2*nFaninMax ); - pMan->vComTo1 = Vec_IntAlloc( 2*nFaninMax ); - pMan->vPairs0 = Vec_IntAlloc( nFaninMax ); - pMan->vPairs1 = Vec_IntAlloc( nFaninMax ); - pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 ); - pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 ); - - // allocate memory for object structures - pMan->pMemory = pMem = ALLOC( Xyz_Obj_t, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) ); - memset( pMem, 0, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) ); - // allocate storage for the pointers to the memory - pMan->vObjStrs = Vec_PtrAlloc( Abc_NtkObjNumMax(pNtk) ); - Vec_PtrFill( pMan->vObjStrs, Abc_NtkObjNumMax(pNtk), NULL ); - Abc_NtkForEachObj( pNtk, pObj, i ) - Vec_PtrWriteEntry( pMan->vObjStrs, i, pMem + i ); - // create the cube manager - pMan->pManMin = Min_ManAlloc( nFaninMax ); - return pMan; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Xyz_ManFree( Xyz_Man_t * p ) -{ - Vec_Int_t * vSupp; - int i; - for ( i = 0; i < p->vObjStrs->nSize; i++ ) - { - vSupp = ((Xyz_Obj_t *)p->vObjStrs->pArray[i])->vSupp; - if ( vSupp ) Vec_IntFree( vSupp ); - } - - Min_ManFree( p->pManMin ); - Vec_PtrFree( p->vObjStrs ); - Vec_IntFree( p->vFanCounts ); - Vec_IntFree( p->vTriv0 ); - Vec_IntFree( p->vTriv1 ); - Vec_IntFree( p->vComTo0 ); - Vec_IntFree( p->vComTo1 ); - Vec_IntFree( p->vPairs0 ); - Vec_IntFree( p->vPairs1 ); - free( p->pMemory ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Drop the covers at the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj ) -{ - int nFanouts; - assert( p->vFanCounts ); - nFanouts = Vec_IntEntry( p->vFanCounts, pObj->Id ); - assert( nFanouts > 0 ); - if ( --nFanouts == 0 ) - { - Vec_IntFree( Abc_ObjGetSupp(pObj) ); - Abc_ObjSetSupp( pObj, NULL ); - Min_CoverRecycle( p->pManMin, Abc_ObjGetCover2(pObj) ); - Abc_ObjSetCover2( pObj, NULL ); - p->nSupps--; - } - Vec_IntWriteEntry( p->vFanCounts, pObj->Id, nFanouts ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/xyz/xyzMinSop.c b/src/opt/xyz/xyzMinSop.c deleted file mode 100644 index a5d57c66..00000000 --- a/src/opt/xyz/xyzMinSop.c +++ /dev/null @@ -1,615 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzMinSop.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [SOP manipulation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzMinSop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyzInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Min_SopRewrite( Min_Man_t * p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopMinimize( Min_Man_t * p ) -{ - int nCubesInit, nCubesOld, nIter; - if ( p->nCubes < 3 ) - return; - nIter = 0; - nCubesInit = p->nCubes; - do { - nCubesOld = p->nCubes; - Min_SopRewrite( p ); - nIter++; -// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes ); - } - while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); -// printf( "\n" ); - -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopRewrite( Min_Man_t * p ) -{ - Min_Cube_t * pCube, ** ppPrev; - Min_Cube_t * pThis, ** ppPrevT; - Min_Cube_t * pTemp; - int v00, v01, v10, v11, Var0, Var1, Index, fCont0, fCont1, nCubesOld; - int nPairs = 0; -/* - { - Min_Cube_t * pCover; - pCover = Min_CoverCollect( p, p->nVars ); -printf( "\n\n" ); -Min_CoverWrite( stdout, pCover ); - Min_CoverExpand( p, pCover ); - } -*/ - - // insert the bubble before the first cube - p->pBubble->pNext = p->ppStore[0]; - p->ppStore[0] = p->pBubble; - p->pBubble->nLits = 0; - - // go through the cubes - while ( 1 ) - { - // get the index of the bubble - Index = p->pBubble->nLits; - - // find the bubble - Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) - if ( pCube == p->pBubble ) - break; - assert( pCube == p->pBubble ); - - // remove the bubble, get the next cube after the bubble - *ppPrev = p->pBubble->pNext; - pCube = p->pBubble->pNext; - if ( pCube == NULL ) - for ( Index++; Index <= p->nVars; Index++ ) - if ( p->ppStore[Index] ) - { - ppPrev = &(p->ppStore[Index]); - pCube = p->ppStore[Index]; - break; - } - // stop if there is no more cubes - if ( pCube == NULL ) - break; - - // find the first dist2 cube - Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) - break; - if ( pThis == NULL && Index < p->nVars ) - Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) - break; - // continue if there is no dist2 cube - if ( pThis == NULL ) - { - // insert the bubble after the cube - p->pBubble->pNext = pCube->pNext; - pCube->pNext = p->pBubble; - p->pBubble->nLits = pCube->nLits; - continue; - } - nPairs++; -/* -printf( "\n" ); -Min_CubeWrite( stdout, pCube ); -Min_CubeWrite( stdout, pThis ); -*/ - // remove the cubes, insert the bubble instead of pCube - *ppPrevT = pThis->pNext; - *ppPrev = p->pBubble; - p->pBubble->pNext = pCube->pNext; - p->pBubble->nLits = pCube->nLits; - p->nCubes -= 2; - - assert( pCube != p->pBubble && pThis != p->pBubble ); - - - // save the dist2 parameters - v00 = Min_CubeGetVar( pCube, Var0 ); - v01 = Min_CubeGetVar( pCube, Var1 ); - v10 = Min_CubeGetVar( pThis, Var0 ); - v11 = Min_CubeGetVar( pThis, Var1 ); - assert( v00 != v10 && v01 != v11 ); - assert( v00 != 3 || v01 != 3 ); - assert( v10 != 3 || v11 != 3 ); - -//printf( "\n" ); -//Min_CubeWrite( stdout, pCube ); -//Min_CubeWrite( stdout, pThis ); - -//printf( "\n" ); -//Min_CubeWrite( stdout, pCube ); -//Min_CubeWrite( stdout, pThis ); - - // consider the case when both cubes have non-empty literals - if ( v00 != 3 && v01 != 3 && v10 != 3 && v11 != 3 ) - { - assert( v00 == (v10 ^ 3) ); - assert( v01 == (v11 ^ 3) ); - // create the temporary cube equal to the first corner - Min_CubeXorVar( pCube, Var0, 3 ); - // check if this cube is contained - fCont0 = Min_CoverContainsCube( p, pCube ); - // create the temporary cube equal to the first corner - Min_CubeXorVar( pCube, Var0, 3 ); - Min_CubeXorVar( pCube, Var1, 3 ); -//printf( "\n" ); -//Min_CubeWrite( stdout, pCube ); -//Min_CubeWrite( stdout, pThis ); - // check if this cube is contained - fCont1 = Min_CoverContainsCube( p, pCube ); - // undo the change - Min_CubeXorVar( pCube, Var1, 3 ); - - // check if the cubes can be overwritten - if ( fCont0 && fCont1 ) - { - // one of the cubes can be recycled, the other expanded and added - Min_CubeRecycle( p, pThis ); - // remove the literals - Min_CubeXorVar( pCube, Var0, v00 ^ 3 ); - Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); - pCube->nLits -= 2; - Min_SopAddCube( p, pCube ); - } - else if ( fCont0 ) - { - // expand both cubes and add them - Min_CubeXorVar( pCube, Var0, v00 ^ 3 ); - pCube->nLits--; - Min_SopAddCube( p, pCube ); - Min_CubeXorVar( pThis, Var1, v11 ^ 3 ); - pThis->nLits--; - Min_SopAddCube( p, pThis ); - } - else if ( fCont1 ) - { - // expand both cubes and add them - Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); - pCube->nLits--; - Min_SopAddCube( p, pCube ); - Min_CubeXorVar( pThis, Var0, v10 ^ 3 ); - pThis->nLits--; - Min_SopAddCube( p, pThis ); - } - else - { - Min_SopAddCube( p, pCube ); - Min_SopAddCube( p, pThis ); - } - // otherwise, no change is possible - continue; - } - - // if one of them does not have DC lit, move it - if ( v00 != 3 && v01 != 3 ) - { - assert( v10 == 3 || v11 == 3 ); - pTemp = pCube; pCube = pThis; pThis = pTemp; - Index = v00; v00 = v10; v10 = Index; - Index = v01; v01 = v11; v11 = Index; - } - - // make sure the first cube has first var DC - if ( v00 != 3 ) - { - assert( v01 == 3 ); - Index = Var0; Var0 = Var1; Var1 = Index; - Index = v00; v00 = v01; v01 = Index; - Index = v10; v10 = v11; v11 = Index; - } - - // consider both cases: both have DC lit - if ( v00 == 3 && v11 == 3 ) - { - assert( v01 != 3 && v10 != 3 ); - // try the remaining minterm - // create the temporary cube equal to the first corner - Min_CubeXorVar( pCube, Var0, v10 ); - Min_CubeXorVar( pCube, Var1, 3 ); - pCube->nLits++; - // check if this cube is contained - fCont0 = Min_CoverContainsCube( p, pCube ); - // undo the cube transformations - Min_CubeXorVar( pCube, Var0, v10 ); - Min_CubeXorVar( pCube, Var1, 3 ); - pCube->nLits--; - // check the case when both are covered - if ( fCont0 ) - { - // one of the cubes can be recycled, the other expanded and added - Min_CubeRecycle( p, pThis ); - // remove the literals - Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); - pCube->nLits--; - Min_SopAddCube( p, pCube ); - } - else - { - // try two reduced cubes - Min_CubeXorVar( pCube, Var0, v10 ); - pCube->nLits++; - // remember the cubes - nCubesOld = p->nCubes; - Min_SopAddCube( p, pCube ); - // check if the cube is absorbed - if ( p->nCubes < nCubesOld + 1 ) - { // absorbed - add the second cube - Min_SopAddCube( p, pThis ); - } - else - { // remove this cube, and try another one - assert( pCube == p->ppStore[pCube->nLits] ); - p->ppStore[pCube->nLits] = pCube->pNext; - p->nCubes--; - - // return the cube to the previous state - Min_CubeXorVar( pCube, Var0, v10 ); - pCube->nLits--; - - // generate another reduced cube - Min_CubeXorVar( pThis, Var1, v01 ); - pThis->nLits++; - - // add both cubes - Min_SopAddCube( p, pCube ); - Min_SopAddCube( p, pThis ); - } - } - } - else // the first cube has DC lit - { - assert( v01 != 3 && v10 != 3 && v11 != 3 ); - // try the remaining minterm - // create the temporary cube equal to the minterm - Min_CubeXorVar( pThis, Var0, 3 ); - // check if this cube is contained - fCont0 = Min_CoverContainsCube( p, pThis ); - // undo the cube transformations - Min_CubeXorVar( pThis, Var0, 3 ); - // check the case when both are covered - if ( fCont0 ) - { - // one of the cubes can be recycled, the other expanded and added - Min_CubeRecycle( p, pThis ); - // remove the literals - Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); - pCube->nLits--; - Min_SopAddCube( p, pCube ); - } - else - { - // try reshaping the cubes - // reduce the first cube - Min_CubeXorVar( pCube, Var0, v10 ); - pCube->nLits++; - // expand the second cube - Min_CubeXorVar( pThis, Var1, v11 ^ 3 ); - pThis->nLits--; - // add both cubes - Min_SopAddCube( p, pCube ); - Min_SopAddCube( p, pThis ); - } - } - } -// printf( "Pairs = %d ", nPairs ); -} - -/**Function************************************************************* - - Synopsis [Adds cube to the SOP cover stored in the manager.] - - Description [Returns 0 if the cube is added or removed. Returns 1 - if the cube is glued with some other cube and has to be added again.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Min_SopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) -{ - Min_Cube_t * pThis, * pThis2, ** ppPrev; - int i; - // try to find the identical cube - Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) - { - if ( Min_CubesAreEqual( pCube, pThis ) ) - { - Min_CubeRecycle( p, pCube ); - return 0; - } - } - // try to find a containing cube - for ( i = 0; i < (int)pCube->nLits; i++ ) - Min_CoverForEachCube( p->ppStore[i], pThis ) - { - if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) - { - Min_CubeRecycle( p, pCube ); - return 0; - } - } - // try to find distance one in the same bin - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) - { - if ( Min_CubesDistOne( pCube, pThis, NULL ) ) - { - *ppPrev = pThis->pNext; - Min_CubesTransformOr( pCube, pThis ); - pCube->nLits--; - Min_CubeRecycle( p, pThis ); - p->nCubes--; - return 1; - } - } - - // clean the other cubes using this one - for ( i = pCube->nLits + 1; i <= (int)pCube->nVars; i++ ) - { - ppPrev = &p->ppStore[i]; - Min_CoverForEachCubeSafe( p->ppStore[i], pThis, pThis2 ) - { - if ( pThis != p->pBubble && Min_CubeIsContained( pCube, pThis ) ) - { - *ppPrev = pThis->pNext; - Min_CubeRecycle( p, pThis ); - p->nCubes--; - } - else - ppPrev = &pThis->pNext; - } - } - - // add the cube - pCube->pNext = p->ppStore[pCube->nLits]; - p->ppStore[pCube->nLits] = pCube; - p->nCubes++; - return 0; -} - -/**Function************************************************************* - - Synopsis [Adds the cube to storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) -{ - assert( Min_CubeCheck( pCube ) ); - assert( pCube != p->pBubble ); - assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); - while ( Min_SopAddCubeInt( p, pCube ) ); -} - - - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopContain( Min_Man_t * p ) -{ - Min_Cube_t * pCube, * pCube2, ** ppPrev; - int i, k; - for ( i = 0; i <= p->nVars; i++ ) - { - Min_CoverForEachCube( p->ppStore[i], pCube ) - Min_CoverForEachCubePrev( pCube->pNext, pCube2, ppPrev ) - { - if ( !Min_CubesAreEqual( pCube, pCube2 ) ) - continue; - *ppPrev = pCube2->pNext; - Min_CubeRecycle( p, pCube2 ); - p->nCubes--; - } - for ( k = i + 1; k <= p->nVars; k++ ) - Min_CoverForEachCubePrev( p->ppStore[k], pCube2, ppPrev ) - { - if ( !Min_CubeIsContained( pCube, pCube2 ) ) - continue; - *ppPrev = pCube2->pNext; - Min_CubeRecycle( p, pCube2 ); - p->nCubes--; - } - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopDist1Merge( Min_Man_t * p ) -{ - Min_Cube_t * pCube, * pCube2, * pCubeNew; - int i; - for ( i = p->nVars; i >= 0; i-- ) - { - Min_CoverForEachCube( p->ppStore[i], pCube ) - Min_CoverForEachCube( pCube->pNext, pCube2 ) - { - assert( pCube->nLits == pCube2->nLits ); - if ( !Min_CubesDistOne( pCube, pCube2, NULL ) ) - continue; - pCubeNew = Min_CubesXor( p, pCube, pCube2 ); - assert( pCubeNew->nLits == pCube->nLits - 1 ); - pCubeNew->pNext = p->ppStore[pCubeNew->nLits]; - p->ppStore[pCubeNew->nLits] = pCubeNew; - p->nCubes++; - } - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Min_SopComplement( Min_Man_t * p, Min_Cube_t * pSharp ) -{ - Vec_Int_t * vVars; - Min_Cube_t * pCover, * pCube, * pNext, * pReady, * pThis, ** ppPrev; - int Num, Value, i; - - // get the variables - vVars = Vec_IntAlloc( 100 ); - // create the tautology cube - pCover = Min_CubeAlloc( p ); - // sharp it with all cubes - Min_CoverForEachCube( pSharp, pCube ) - Min_CoverForEachCubePrev( pCover, pThis, ppPrev ) - { - if ( Min_CubesDisjoint( pThis, pCube ) ) - continue; - // remember the next pointer - pNext = pThis->pNext; - // get the variables, in which pThis is '-' while pCube is fixed - Min_CoverGetDisjVars( pThis, pCube, vVars ); - // generate the disjoint cubes - pReady = pThis; - Vec_IntForEachEntryReverse( vVars, Num, i ) - { - // correct the literal - Min_CubeXorVar( pReady, vVars->pArray[i], 3 ); - if ( i == 0 ) - break; - // create the new cube and clean this value - Value = Min_CubeGetVar( pReady, vVars->pArray[i] ); - pReady = Min_CubeDup( p, pReady ); - Min_CubeXorVar( pReady, vVars->pArray[i], 3 ^ Value ); - // add to the cover - *ppPrev = pReady; - ppPrev = &pReady->pNext; - } - pThis = pReady; - pThis->pNext = pNext; - } - Vec_IntFree( vVars ); - - // perform dist-1 merge and contain - Min_CoverExpandRemoveEqual( p, pCover ); - Min_SopDist1Merge( p ); - Min_SopContain( p ); - return Min_CoverCollect( p, p->nVars ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Min_SopCheck( Min_Man_t * p ) -{ - Min_Cube_t * pCube, * pThis; - int i; - - pCube = Min_CubeAlloc( p ); - Min_CubeXorBit( pCube, 2*0+1 ); - Min_CubeXorBit( pCube, 2*1+1 ); - Min_CubeXorBit( pCube, 2*2+0 ); - Min_CubeXorBit( pCube, 2*3+0 ); - Min_CubeXorBit( pCube, 2*4+0 ); - Min_CubeXorBit( pCube, 2*5+1 ); - Min_CubeXorBit( pCube, 2*6+1 ); - pCube->nLits = 7; - -// Min_CubeWrite( stdout, pCube ); - - // check that the cubes contain it - for ( i = 0; i <= p->nVars; i++ ) - Min_CoverForEachCube( p->ppStore[i], pThis ) - if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) - { - Min_CubeRecycle( p, pCube ); - return 1; - } - Min_CubeRecycle( p, pCube ); - return 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/xyz/xyzTest.c b/src/opt/xyz/xyzTest.c deleted file mode 100644 index 38580790..00000000 --- a/src/opt/xyz/xyzTest.c +++ /dev/null @@ -1,417 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzTest.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Testing procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzTest.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyz.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeDeriveCoverPro( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 ) -{ - Min_Cube_t * pCover; - Min_Cube_t * pCube0, * pCube1, * pCube; - if ( pCover0 == NULL || pCover1 == NULL ) - return NULL; - // clean storage - Min_ManClean( p, p->nVars ); - // go through the cube pairs - Min_CoverForEachCube( pCover0, pCube0 ) - Min_CoverForEachCube( pCover1, pCube1 ) - { - if ( Min_CubesDisjoint( pCube0, pCube1 ) ) - continue; - pCube = Min_CubesProduct( p, pCube0, pCube1 ); - // add the cube to storage - Min_SopAddCube( p, pCube ); - } - Min_SopMinimize( p ); - pCover = Min_CoverCollect( p, p->nVars ); - assert( p->nCubes == Min_CoverCountCubes(pCover) ); - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeDeriveCoverSum( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 ) -{ - Min_Cube_t * pCover; - Min_Cube_t * pThis, * pCube; - if ( pCover0 == NULL || pCover1 == NULL ) - return NULL; - // clean storage - Min_ManClean( p, p->nVars ); - // add the cubes to storage - Min_CoverForEachCube( pCover0, pThis ) - { - pCube = Min_CubeDup( p, pThis ); - Min_SopAddCube( p, pCube ); - } - Min_CoverForEachCube( pCover1, pThis ) - { - pCube = Min_CubeDup( p, pThis ); - Min_SopAddCube( p, pCube ); - } - Min_SopMinimize( p ); - pCover = Min_CoverCollect( p, p->nVars ); - assert( p->nCubes == Min_CoverCountCubes(pCover) ); - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeDeriveSops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes ) -{ - Min_Cube_t * pCov0[2], * pCov1[2]; - Min_Cube_t * pCoverP, * pCoverN; - Abc_Obj_t * pObj; - int i, nCubes, fCompl0, fCompl1; - - // set elementary vars - Vec_PtrForEachEntry( vSupp, pObj, i ) - { - pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 ); - pObj->pNext = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 1 ); - } - - // get the cover for each node in the array - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // get the complements - fCompl0 = Abc_ObjFaninC0(pObj); - fCompl1 = Abc_ObjFaninC1(pObj); - // get the covers - pCov0[0] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy; - pCov0[1] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pNext; - pCov1[0] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy; - pCov1[1] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pNext; - // compute the covers - pCoverP = Abc_NodeDeriveCoverPro( p, pCov0[ fCompl0], pCov1[ fCompl1] ); - pCoverN = Abc_NodeDeriveCoverSum( p, pCov0[!fCompl0], pCov1[!fCompl1] ); - // set the covers - pObj->pCopy = (Abc_Obj_t *)pCoverP; - pObj->pNext = (Abc_Obj_t *)pCoverN; - } - - nCubes = ABC_MIN( Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverP) ); - -/* -printf( "\n\n" ); -Min_CoverWrite( stdout, pCoverP ); -printf( "\n\n" ); -Min_CoverWrite( stdout, pCoverN ); -*/ - -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverP ); - -// Min_CoverExpand( p, pCoverP ); -// Min_SopMinimize( p ); -// pCoverP = Min_CoverCollect( p, p->nVars ); - -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverP ); - -// nCubes = Min_CoverCountCubes(pCoverP); - - // clean the copy fields - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = pObj->pNext = NULL; - Vec_PtrForEachEntry( vSupp, pObj, i ) - pObj->pCopy = pObj->pNext = NULL; - -// Min_CoverWriteFile( pCoverP, Abc_ObjName(pRoot), 0 ); -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverP ); - -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverP ); -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverN ); - return nCubes; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTestSop( Abc_Ntk_t * pNtk ) -{ - Min_Man_t * p; - Vec_Ptr_t * vSupp, * vNodes; - Abc_Obj_t * pObj; - int i, nCubes; - assert( Abc_NtkIsStrash(pNtk) ); - - Abc_NtkCleanCopy(pNtk); - Abc_NtkCleanNext(pNtk); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - if ( !Abc_NodeIsAigAnd(Abc_ObjFanin0(pObj)) ) - { - printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) ); - continue; - } - - vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); - vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); - - printf( "%20s : Cone = %5d. Supp = %5d. ", - Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize ); -// if ( vSupp->nSize <= 128 ) - { - p = Min_ManAlloc( vSupp->nSize ); - nCubes = Abc_NodeDeriveSops( p, pObj, vSupp, vNodes ); - printf( "Cubes = %5d. ", nCubes ); - Min_ManFree( p ); - } - printf( "\n" ); - - - Vec_PtrFree( vNodes ); - Vec_PtrFree( vSupp ); - } -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeDeriveCover( Min_Man_t * p, Min_Cube_t * pCov0, Min_Cube_t * pCov1, int fComp0, int fComp1 ) -{ - Min_Cube_t * pCover0, * pCover1, * pCover; - Min_Cube_t * pCube0, * pCube1, * pCube; - - // complement the first if needed - if ( !fComp0 ) - pCover0 = pCov0; - else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube - pCover0 = pCov0->pNext; - else - pCover0 = p->pOne0, p->pOne0->pNext = pCov0; - - // complement the second if needed - if ( !fComp1 ) - pCover1 = pCov1; - else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube - pCover1 = pCov1->pNext; - else - pCover1 = p->pOne1, p->pOne1->pNext = pCov1; - - if ( pCover0 == NULL || pCover1 == NULL ) - return NULL; - - // clean storage - Min_ManClean( p, p->nVars ); - // go through the cube pairs - Min_CoverForEachCube( pCover0, pCube0 ) - Min_CoverForEachCube( pCover1, pCube1 ) - { - if ( Min_CubesDisjoint( pCube0, pCube1 ) ) - continue; - pCube = Min_CubesProduct( p, pCube0, pCube1 ); - // add the cube to storage - Min_EsopAddCube( p, pCube ); - } - - if ( p->nCubes > 10 ) - { -// printf( "(%d,", p->nCubes ); - Min_EsopMinimize( p ); -// printf( "%d) ", p->nCubes ); - } - - pCover = Min_CoverCollect( p, p->nVars ); - assert( p->nCubes == Min_CoverCountCubes(pCover) ); - -// if ( p->nCubes > 1000 ) -// printf( "%d ", p->nCubes ); - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeDeriveEsops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes ) -{ - Min_Cube_t * pCover, * pCube; - Abc_Obj_t * pObj; - int i; - - // set elementary vars - Vec_PtrForEachEntry( vSupp, pObj, i ) - pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 ); - - // get the cover for each node in the array - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - pCover = Abc_NodeDeriveCover( p, - (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy, - (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy, - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); - pObj->pCopy = (Abc_Obj_t *)pCover; - if ( p->nCubes > 3000 ) - return -1; - } - - // add complement if needed - if ( Abc_ObjFaninC0(pRoot) ) - { - if ( pCover && pCover->nLits == 0 ) // topmost one is the tautology cube - { - pCube = pCover; - pCover = pCover->pNext; - Min_CubeRecycle( p, pCube ); - p->nCubes--; - } - else - { - pCube = Min_CubeAlloc( p ); - pCube->pNext = pCover; - p->nCubes++; - } - } -/* - Min_CoverExpand( p, pCover ); - Min_EsopMinimize( p ); - pCover = Min_CoverCollect( p, p->nVars ); -*/ - // clean the copy fields - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = NULL; - Vec_PtrForEachEntry( vSupp, pObj, i ) - pObj->pCopy = NULL; - -// Min_CoverWriteFile( pCover, Abc_ObjName(pRoot), 1 ); -// Min_CoverWrite( stdout, pCover ); - return p->nCubes; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTestEsop( Abc_Ntk_t * pNtk ) -{ - Min_Man_t * p; - Vec_Ptr_t * vSupp, * vNodes; - Abc_Obj_t * pObj; - int i, nCubes; - assert( Abc_NtkIsStrash(pNtk) ); - - Abc_NtkCleanCopy(pNtk); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - if ( !Abc_NodeIsAigAnd(Abc_ObjFanin0(pObj)) ) - { - printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) ); - continue; - } - - vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); - vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); - - printf( "%20s : Cone = %5d. Supp = %5d. ", - Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize ); -// if ( vSupp->nSize <= 128 ) - { - p = Min_ManAlloc( vSupp->nSize ); - nCubes = Abc_NodeDeriveEsops( p, pObj, vSupp, vNodes ); - printf( "Cubes = %5d. ", nCubes ); - Min_ManFree( p ); - } - printf( "\n" ); - - - Vec_PtrFree( vNodes ); - Vec_PtrFree( vSupp ); - } -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aig.h b/src/sat/aig/aig.h index 5d2547ea..a0d63ce9 100644 --- a/src/sat/aig/aig.h +++ b/src/sat/aig/aig.h @@ -64,9 +64,11 @@ extern "C" { //////////////////////////////////////////////////////////////////////// //typedef int bool; +#ifndef __cplusplus #ifndef bool #define bool int #endif +#endif typedef struct Aig_Param_t_ Aig_Param_t; typedef struct Aig_Man_t_ Aig_Man_t; @@ -215,7 +217,7 @@ struct Aig_SimInfo_t_ /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -static inline int Aig_BitWordNum( int nBits ) { return nBits/32 + ((nBits%32) > 0); } +static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } static inline int Aig_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } static inline void Aig_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } static inline void Aig_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } diff --git a/src/sat/aig/fraigCore.c b/src/sat/aig/fraigCore.c index 525d4a14..03781180 100644 --- a/src/sat/aig/fraigCore.c +++ b/src/sat/aig/fraigCore.c @@ -92,7 +92,7 @@ Aig_ProofType_t Aig_FraigProveOutput( Aig_Man_t * pMan ) // solve the miter clk = clock(); pMan->pSat->verbosity = pMan->pParam->fSatVerbose; - status = solver_solve( pMan->pSat, NULL, NULL, 0, 0 );//pMan->pParam->nConfLimit, pMan->pParam->nImpLimit ); + status = solver_solve( pMan->pSat, NULL, NULL, 0, 0 );//pMan->pParam->nConfLimit, pMan->pParam->nInsLimit ); if ( status == l_Undef ) { // printf( "The problem timed out.\n" ); diff --git a/src/sat/aig/rwrTruth.c b/src/sat/aig/rwrTruth.c index 92a39f0a..cb8d03e0 100644 --- a/src/sat/aig/rwrTruth.c +++ b/src/sat/aig/rwrTruth.c @@ -167,7 +167,7 @@ void Aig_TruthCount( Aig_Truth_t * p ) ***********************************************************************/ static inline unsigned Aig_WordGetPart( unsigned * p, int Start, int Size ) { - return (p[Start/5] >> (Start%32)) & (~0u >> (32-Size)); + return (p[Start/5] >> (Start&31)) & (~0u >> (32-Size)); } /**Function************************************************************* @@ -183,7 +183,7 @@ static inline unsigned Aig_WordGetPart( unsigned * p, int Start, int Size ) ***********************************************************************/ static inline void Aig_WordSetPart( unsigned * p, int Start, unsigned Part ) { - p[Start/5] |= (Part << (Start%32)); + p[Start/5] |= (Part << (Start&31)); } /**Function************************************************************* @@ -254,7 +254,7 @@ DdNode * Aig_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int Shift, int n } if ( nVars == 5 ) { - unsigned * pWord = pTruth + Shift/32; + unsigned * pWord = pTruth + (Shift>>5); assert( Shift % 32 == 0 ); if ( *pWord == 0 ) return Cudd_ReadLogicZero(dd); diff --git a/src/sat/asat/added.c b/src/sat/asat/added.c index e1b1bb2a..832bc0cf 100644 --- a/src/sat/asat/added.c +++ b/src/sat/asat/added.c @@ -158,7 +158,7 @@ int * solver_get_model( solver * p, int * pVars, int nVars ) for ( i = 0; i < nVars; i++ ) { assert( pVars[i] >= 0 && pVars[i] < p->size ); - pModel[i] = (int)(p->model.ptr[pVars[i]] == (void *)l_True); + pModel[i] = (int)(p->model.ptr[pVars[i]] == l_True); } return pModel; } @@ -188,6 +188,28 @@ void Asat_SatPrintStats( FILE * pFile, solver * p ) (float)(p->timeUpdate)/(float)(CLOCKS_PER_SEC) ); } +/**Function************************************************************* + + Synopsis [Sets the preferred variables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Asat_SolverSetPrefVars(solver * s, int * pPrefVars, int nPrefVars) +{ + int i; + assert( s->pPrefVars == NULL ); + for ( i = 0; i < nPrefVars; i++ ) + assert( pPrefVars[i] < s->size ); + s->pPrefVars = pPrefVars; + s->nPrefVars = nPrefVars; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/asat/asat60525.zip b/src/sat/asat/asat60525.zip Binary files differnew file mode 100644 index 00000000..b8361af1 --- /dev/null +++ b/src/sat/asat/asat60525.zip diff --git a/src/sat/asat/jfront.c b/src/sat/asat/jfront.c index 1def6a37..8e673cc9 100644 --- a/src/sat/asat/jfront.c +++ b/src/sat/asat/jfront.c @@ -95,7 +95,7 @@ static void Asat_JRingRemove( Asat_JMan_t * p, Asat_JVar_t * pVar ); // iterator through the adjacent variables #define Asat_JVarForEachFanio( p, pVar, pFan, i ) \ - for ( i = 0; (i < pVar->nFans) && (((pFan) = Asat_JManVar(p, pVar->Fans[i])), 1); i++ ) + for ( i = 0; (i < (int)pVar->nFans) && (((pFan) = Asat_JManVar(p, pVar->Fans[i])), 1); i++ ) extern void Asat_JManAssign( Asat_JMan_t * p, int Var ); @@ -223,7 +223,7 @@ int Asat_JManCheck( Asat_JMan_t * p ) // assert( i != pVar->nFans ); // if ( i == pVar->nFans ) // return 0; - if ( i == pVar->nFans ) + if ( i == (int)pVar->nFans ) Counter++; } if ( Counter > 0 ) diff --git a/src/sat/asat/solver.c b/src/sat/asat/solver.c index 6d76d890..548abd1d 100644 --- a/src/sat/asat/solver.c +++ b/src/sat/asat/solver.c @@ -26,7 +26,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "solver.h" -//#define ASAT_USE_SYSTEM_MEMORY_MANAGEMENT +#define ASAT_USE_SYSTEM_MEMORY_MANAGEMENT //================================================================================================= // Simple (var/literal) helpers: @@ -96,14 +96,14 @@ static inline void clause_setactivity(clause* c, float a) { *((float*)&c->lits[ //================================================================================================= // Encode literals in clause pointers: -clause* clause_from_lit (lit l) { return (clause*)(l + l + 1); } -bool clause_is_lit (clause* c) { return ((unsigned int)c & 1); } -lit clause_read_lit (clause* c) { return (lit)((unsigned int)c >> 1); } +clause* clause_from_lit (lit l) { return (clause*)(((unsigned long)l) + ((unsigned long)l) + 1); } +bool clause_is_lit (clause* c) { return ((unsigned long)c & 1); } +lit clause_read_lit (clause* c) { return (lit)((unsigned long)c >> 1); } //================================================================================================= // Simple helpers: -static inline int solver_dlevel(solver* s) { return vec_size(&s->trail_lim); } +static inline int solver_dlevel(solver* s) { return veci_size(&s->trail_lim); } static inline vec* solver_read_wlist (solver* s, lit l){ return &s->wlists[l]; } static inline void vec_remove(vec* v, void* e) { @@ -124,7 +124,7 @@ static inline void order_update(solver* s, int v) // updateorder // int clk = clock(); int* orderpos = s->orderpos; double* activity = s->activity; - int* heap = (int*)vec_begin(&s->order); + int* heap = veci_begin(&s->order); int i = orderpos[v]; int x = heap[i]; int parent = (i - 1) / 2; @@ -151,8 +151,8 @@ static inline void order_unassigned(solver* s, int v) // undoorder // int clk = clock(); int* orderpos = s->orderpos; if (orderpos[v] == -1){ - orderpos[v] = vec_size(&s->order); - vec_push(&s->order,(void*)v); + orderpos[v] = veci_size(&s->order); + veci_push(&s->order,v); order_update(s,v); } // s->timeUpdate += clock() - clk; @@ -161,12 +161,23 @@ static inline void order_unassigned(solver* s, int v) // undoorder static int order_select(solver* s, float random_var_freq) // selectvar { // int clk = clock(); + static int Counter = 0; int* heap; double* activity; int* orderpos; lbool* values = s->assigns; + // The first decisions + if ( s->pPrefVars && s->nPrefDecNum < s->nPrefVars ) + { + int i; + s->nPrefDecNum++; + for ( i = 0; i < s->nPrefVars; i++ ) + if ( values[s->pPrefVars[i]] == l_Undef ) + return s->pPrefVars[i]; + } + // Random decision: if (drand(&s->random_seed) < random_var_freq){ int next = irand(&s->random_seed,s->size); @@ -177,17 +188,17 @@ static int order_select(solver* s, float random_var_freq) // selectvar // Activity based decision: - heap = (int*)vec_begin(&s->order); + heap = veci_begin(&s->order); activity = s->activity; orderpos = s->orderpos; - while (vec_size(&s->order) > 0){ + while (veci_size(&s->order) > 0){ int next = heap[0]; - int size = vec_size(&s->order)-1; + int size = veci_size(&s->order)-1; int x = heap[size]; - vec_resize(&s->order,size); + veci_resize(&s->order,size); orderpos[next] = -1; @@ -300,7 +311,10 @@ static clause* clause_new(solver* s, lit* begin, lit* end, int learnt) assert(((unsigned int)c & 1) == 0); for (i = 0; i < size; i++) + { + assert(begin[i] >= 0); c->lits[i] = begin[i]; + } if (learnt) *((float*)&c->lits[size]) = 0.0; @@ -328,11 +342,11 @@ static void clause_remove(solver* s, clause* c) lit* lits = clause_begin(c); assert(neg(lits[0]) < s->size*2); assert(neg(lits[1]) < s->size*2); + assert(lits[0] < s->size*2); //vec_remove(solver_read_wlist(s,neg(lits[0])),(void*)c); //vec_remove(solver_read_wlist(s,neg(lits[1])),(void*)c); - assert(lits[0] < s->size*2); vec_remove(solver_read_wlist(s,neg(lits[0])),(void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[1]))); vec_remove(solver_read_wlist(s,neg(lits[1])),(void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[0]))); @@ -399,8 +413,8 @@ static void solver_setnvars(solver* s,int n) s->levels [var] = 0; s->tags [var] = l_Undef; - assert(vec_size(&s->order) == var); - vec_push(&s->order,(void*)var); + assert(veci_size(&s->order) == var); + veci_push(&s->order,var); order_update(s,var); } @@ -413,20 +427,19 @@ static inline bool enqueue(solver* s, lit l, clause* from) lbool* values = s->assigns; int v = lit_var(l); lbool val = values[v]; + lbool sig = !lit_sign(l); sig += sig - 1; #ifdef VERBOSEDEBUG printf(L_IND"enqueue("L_LIT")\n", L_ind, L_lit(l)); #endif - - lbool sig = !lit_sign(l); sig += sig - 1; if (val != l_Undef){ return val == sig; }else{ // New fact -- store it. + int* levels = s->levels; + clause** reasons = s->reasons; #ifdef VERBOSEDEBUG printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(l)); #endif - int* levels = s->levels; - clause** reasons = s->reasons; values [v] = sig; levels [v] = solver_dlevel(s); @@ -448,7 +461,7 @@ static inline void assume(solver* s, lit l){ #ifdef VERBOSEDEBUG printf(L_IND"assume("L_LIT")\n", L_ind, L_lit(l)); #endif - vec_push(&s->trail_lim,(void*)s->qtail); + veci_push(&s->trail_lim,s->qtail); enqueue(s,l,(clause*)0); } @@ -466,7 +479,7 @@ static inline void solver_canceluntil(solver* s, int level) { trail = s->trail; values = s->assigns; reasons = s->reasons; - bound = ((int*)vec_begin(&s->trail_lim))[level]; + bound = veci_begin(&s->trail_lim)[level]; for (c = s->qtail-1; c >= bound; c--) { int x = lit_var(trail[c]); @@ -482,23 +495,23 @@ static inline void solver_canceluntil(solver* s, int level) { order_unassigned( s, lit_var(trail[c]) ); s->qhead = s->qtail = bound; - vec_resize(&s->trail_lim,level); + veci_resize(&s->trail_lim,level); } -static void solver_record(solver* s, vec* cls) +static void solver_record(solver* s, veci* cls) { - lit* begin = (lit*)vec_begin(cls); - lit* end = begin + vec_size(cls); - clause* c = (vec_size(cls) > 1) ? clause_new(s,begin,end,1) : (clause*)0; + lit* begin = veci_begin(cls); + lit* end = begin + veci_size(cls); + clause* c = (veci_size(cls) > 1) ? clause_new(s,begin,end,1) : (clause*)0; enqueue(s,*begin,c); - assert(vec_size(cls) > 0); + assert(veci_size(cls) > 0); if (c != 0) { vec_push(&s->learnts,(void*)c); act_clause_bump(s,c); s->solver_stats.learnts++; - s->solver_stats.learnts_literals += vec_size(cls); + s->solver_stats.learnts_literals += veci_size(cls); } } @@ -525,18 +538,18 @@ static bool solver_lit_removable(solver* s, lit l, int minl) lbool* tags = s->tags; clause** reasons = s->reasons; int* levels = s->levels; - int top = vec_size(&s->tagged); + int top = veci_size(&s->tagged); assert(lit_var(l) >= 0 && lit_var(l) < s->size); assert(reasons[lit_var(l)] != 0); - vec_resize(&s->stack,0); - vec_push(&s->stack,(void*)lit_var(l)); + veci_resize(&s->stack,0); + veci_push(&s->stack,lit_var(l)); - while (vec_size(&s->stack) > 0){ + while (veci_size(&s->stack) > 0){ clause* c; - int v = (int)vec_begin(&s->stack)[vec_size(&s->stack)-1]; + int v = veci_begin(&s->stack)[veci_size(&s->stack)-1]; assert(v >= 0 && v < s->size); - vec_resize(&s->stack,vec_size(&s->stack)-1); + veci_resize(&s->stack,veci_size(&s->stack)-1); assert(reasons[v] != 0); c = reasons[v]; @@ -544,15 +557,15 @@ static bool solver_lit_removable(solver* s, lit l, int minl) int v = lit_var(clause_read_lit(c)); if (tags[v] == l_Undef && levels[v] != 0){ if (reasons[v] != 0 && ((1 << (levels[v] & 31)) & minl)){ - vec_push(&s->stack,(void*)v); + veci_push(&s->stack,v); tags[v] = l_True; - vec_push(&s->tagged,(void*)v); + veci_push(&s->tagged,v); }else{ - int* tagged = (int*)vec_begin(&s->tagged); + int* tagged = veci_begin(&s->tagged); int j; - for (j = top; j < vec_size(&s->tagged); j++) + for (j = top; j < veci_size(&s->tagged); j++) tags[tagged[j]] = l_Undef; - vec_resize(&s->tagged,top); + veci_resize(&s->tagged,top); return 0; } } @@ -565,14 +578,14 @@ static bool solver_lit_removable(solver* s, lit l, int minl) if (tags[v] == l_Undef && levels[v] != 0){ if (reasons[v] != 0 && ((1 << (levels[v] & 31)) & minl)){ - vec_push(&s->stack,(void*)lit_var(lits[i])); + veci_push(&s->stack,lit_var(lits[i])); tags[v] = l_True; - vec_push(&s->tagged,(void*)v); + veci_push(&s->tagged,v); }else{ - int* tagged = (int*)vec_begin(&s->tagged); - for (j = top; j < vec_size(&s->tagged); j++) + int* tagged = veci_begin(&s->tagged); + for (j = top; j < veci_size(&s->tagged); j++) tags[tagged[j]] = l_Undef; - vec_resize(&s->tagged,top); + veci_resize(&s->tagged,top); return 0; } } @@ -583,7 +596,7 @@ static bool solver_lit_removable(solver* s, lit l, int minl) return 1; } -static void solver_analyze(solver* s, clause* c, vec* learnt) +static void solver_analyze(solver* s, clause* c, veci* learnt) { lit* trail = s->trail; lbool* tags = s->tags; @@ -596,7 +609,7 @@ static void solver_analyze(solver* s, clause* c, vec* learnt) int i, j, minl; int* tagged; - vec_push(learnt,(void*)lit_Undef); + veci_push(learnt,lit_Undef); do{ assert(c != 0); @@ -606,12 +619,12 @@ static void solver_analyze(solver* s, clause* c, vec* learnt) assert(lit_var(q) >= 0 && lit_var(q) < s->size); if (tags[lit_var(q)] == l_Undef && levels[lit_var(q)] > 0){ tags[lit_var(q)] = l_True; - vec_push(&s->tagged,(void*)lit_var(q)); + veci_push(&s->tagged,lit_var(q)); act_var_bump(s,lit_var(q)); if (levels[lit_var(q)] == solver_dlevel(s)) cnt++; else - vec_push(learnt,(void*)q); + veci_push(learnt,q); } }else{ @@ -625,12 +638,12 @@ static void solver_analyze(solver* s, clause* c, vec* learnt) assert(lit_var(q) >= 0 && lit_var(q) < s->size); if (tags[lit_var(q)] == l_Undef && levels[lit_var(q)] > 0){ tags[lit_var(q)] = l_True; - vec_push(&s->tagged,(void*)lit_var(q)); + veci_push(&s->tagged,lit_var(q)); act_var_bump(s,lit_var(q)); if (levels[lit_var(q)] == solver_dlevel(s)) cnt++; else - vec_push(learnt,(void*)q); + veci_push(learnt,q); } } } @@ -643,31 +656,34 @@ static void solver_analyze(solver* s, clause* c, vec* learnt) }while (cnt > 0); - *(lit*)vec_begin(learnt) = neg(p); +// *veci_begin(learnt) = neg(p); + + lits = veci_begin(learnt); + lits[0] = neg(p); - lits = (lit*)vec_begin(learnt); minl = 0; - for (i = 1; i < vec_size(learnt); i++){ + for (i = 1; i < veci_size(learnt); i++){ int lev = levels[lit_var(lits[i])]; minl |= 1 << (lev & 31); } // simplify (full) - for (i = j = 1; i < vec_size(learnt); i++){ + for (i = j = 1; i < veci_size(learnt); i++){ if (reasons[lit_var(lits[i])] == 0 || !solver_lit_removable(s,lits[i],minl)) lits[j++] = lits[i]; } +// j = veci_size(learnt); // update size of learnt + statistics - s->solver_stats.max_literals += vec_size(learnt); - vec_resize(learnt,j); + s->solver_stats.max_literals += veci_size(learnt); + veci_resize(learnt,j); s->solver_stats.tot_literals += j; // clear tags - tagged = (int*)vec_begin(&s->tagged); - for (i = 0; i < vec_size(&s->tagged); i++) + tagged = veci_begin(&s->tagged); + for (i = 0; i < veci_size(&s->tagged); i++) tags[tagged[i]] = l_Undef; - vec_resize(&s->tagged,0); + veci_resize(&s->tagged,0); #ifdef DEBUG for (i = 0; i < s->size; i++) @@ -676,14 +692,14 @@ static void solver_analyze(solver* s, clause* c, vec* learnt) #ifdef VERBOSEDEBUG printf(L_IND"Learnt {", L_ind); - for (i = 0; i < vec_size(learnt); i++) printf(" "L_LIT, L_lit(lits[i])); + for (i = 0; i < veci_size(learnt); i++) printf(" "L_LIT, L_lit(lits[i])); #endif - if (vec_size(learnt) > 1){ + if (veci_size(learnt) > 1){ int max_i = 1; int max = levels[lit_var(lits[1])]; lit tmp; - for (i = 2; i < vec_size(learnt); i++) + for (i = 2; i < veci_size(learnt); i++) if (levels[lit_var(lits[i])] > max){ max = levels[lit_var(lits[i])]; max_i = i; @@ -695,7 +711,7 @@ static void solver_analyze(solver* s, clause* c, vec* learnt) } #ifdef VERBOSEDEBUG { - int lev = vec_size(learnt) > 1 ? levels[lit_var(lits[1])] : 0; + int lev = veci_size(learnt) > 1 ? levels[lit_var(lits[1])] : 0; printf(" } at level %d\n", lev); } #endif @@ -824,15 +840,15 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts) double random_var_freq = 0.0;//0.02; int conflictC = 0; - vec learnt_clause; + veci learnt_clause; assert(s->root_level == solver_dlevel(s)); s->solver_stats.starts++; s->var_decay = (float)(1 / var_decay ); s->cla_decay = (float)(1 / clause_decay); - vec_resize(&s->model,0); - vec_new(&learnt_clause); + veci_resize(&s->model,0); + veci_new(&learnt_clause); for (;;){ clause* confl = solver_propagate(s); @@ -845,13 +861,13 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts) #endif s->solver_stats.conflicts++; conflictC++; if (solver_dlevel(s) == s->root_level){ - vec_delete(&learnt_clause); + veci_delete(&learnt_clause); return l_False; } - vec_resize(&learnt_clause,0); + veci_resize(&learnt_clause,0); solver_analyze(s, confl, &learnt_clause); - blevel = vec_size(&learnt_clause) > 1 ? levels[lit_var(((lit*)vec_begin(&learnt_clause))[1])] : s->root_level; + blevel = veci_size(&learnt_clause) > 1 ? levels[lit_var(veci_begin(&learnt_clause)[1])] : s->root_level; solver_canceluntil(s,blevel); solver_record(s,&learnt_clause); act_var_decay(s); @@ -866,17 +882,17 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts) // Reached bound on number of conflicts: s->progress_estimate = solver_progress(s); solver_canceluntil(s,s->root_level); - vec_delete(&learnt_clause); + veci_delete(&learnt_clause); return l_Undef; } - if ( s->nConfLimit && s->solver_stats.conflicts > s->nConfLimit || - s->nImpLimit && s->solver_stats.propagations > s->nImpLimit ) + if ( s->nConfLimit && s->solver_stats.conflicts > s->nConfLimit || + s->nInsLimit && s->solver_stats.inspects > s->nInsLimit ) { // Reached bound on number of conflicts: s->progress_estimate = solver_progress(s); solver_canceluntil(s,s->root_level); - vec_delete(&learnt_clause); + veci_delete(&learnt_clause); return l_Undef; } @@ -899,9 +915,9 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts) // Model found: lbool* values = s->assigns; int i; - for (i = 0; i < s->size; i++) vec_push(&s->model,(void*)((int)values[i])); + for (i = 0; i < s->size; i++) veci_push(&s->model,(int)values[i]); solver_canceluntil(s,s->root_level); - vec_delete(&learnt_clause); + veci_delete(&learnt_clause); return l_True; } @@ -922,11 +938,11 @@ solver* solver_new(void) // initialize vectors vec_new(&s->clauses); vec_new(&s->learnts); - vec_new(&s->order); - vec_new(&s->trail_lim); - vec_new(&s->tagged); - vec_new(&s->stack); - vec_new(&s->model); + veci_new(&s->order); + veci_new(&s->trail_lim); + veci_new(&s->tagged); + veci_new(&s->stack); + veci_new(&s->model); // initialize arrays s->wlists = 0; @@ -975,6 +991,8 @@ solver* solver_new(void) s->pMem = Asat_MmStepStart( 10 ); #endif s->pJMan = NULL; + s->pPrefVars = NULL; + s->nPrefVars = 0; s->timeTotal = clock(); s->timeSelect = 0; s->timeUpdate = 0; @@ -998,11 +1016,11 @@ void solver_delete(solver* s) // delete vectors vec_delete(&s->clauses); vec_delete(&s->learnts); - vec_delete(&s->order); - vec_delete(&s->trail_lim); - vec_delete(&s->tagged); - vec_delete(&s->stack); - vec_delete(&s->model); + veci_delete(&s->order); + veci_delete(&s->trail_lim); + veci_delete(&s->tagged); + veci_delete(&s->stack); + veci_delete(&s->model); free(s->binary); // delete arrays @@ -1022,7 +1040,8 @@ void solver_delete(solver* s) free(s->tags ); } - if ( s->pJMan ) Asat_JManStop( s ); + if ( s->pJMan ) Asat_JManStop( s ); + if ( s->pPrefVars ) free( s->pPrefVars ); free(s); } @@ -1117,9 +1136,10 @@ bool solver_simplify(solver* s) } -bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit ) +bool solver_solve(solver* s, lit* begin, lit* end, sint64 nConfLimit, sint64 nInsLimit ) { double nof_conflicts = 100; +// double nof_conflicts = 1000000; double nof_learnts = solver_nclauses(s) / 3; lbool status = l_Undef; lbool* values = s->assigns; @@ -1127,7 +1147,7 @@ bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit // set the external limits s->nConfLimit = nConfLimit; // external limit on the number of conflicts - s->nImpLimit = nImpLimit; // external limit on the number of implications + s->nInsLimit = nInsLimit; // external limit on the number of implications for (i = begin; i < end; i++) @@ -1160,6 +1180,7 @@ bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit s->progress_estimate*100); fflush(stdout); } + s->nPrefDecNum = 0; status = solver_search(s,(int)nof_conflicts, (int)nof_learnts); nof_conflicts *= 1.5; nof_learnts *= 1.1; @@ -1170,9 +1191,9 @@ bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit // printf( "Reached the limit on the number of conflicts (%d).\n", s->nConfLimit ); break; } - if ( s->nImpLimit && s->solver_stats.propagations > s->nImpLimit ) + if ( s->nInsLimit && s->solver_stats.inspects > s->nInsLimit ) { -// printf( "Reached the limit on the number of implications (%d).\n", s->nImpLimit ); +// printf( "Reached the limit on the number of implications (%d).\n", s->nInsLimit ); break; } } diff --git a/src/sat/asat/solver.h b/src/sat/asat/solver.h index 3684d259..05e9dafa 100644 --- a/src/sat/asat/solver.h +++ b/src/sat/asat/solver.h @@ -37,9 +37,11 @@ extern "C" { // Simple types: //typedef int bool; +#ifndef __cplusplus #ifndef bool #define bool int #endif +#endif typedef int lit; typedef char lbool; @@ -74,17 +76,19 @@ extern void solver_delete(solver* s); extern bool solver_addclause(solver* s, lit* begin, lit* end); extern bool solver_simplify(solver* s); -extern int solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit ); +extern int solver_solve(solver* s, lit* begin, lit* end, sint64 nConfLimit, sint64 nInsLimit ); extern int * solver_get_model( solver * p, int * pVars, int nVars ); extern int solver_nvars(solver* s); extern int solver_nclauses(solver* s); + // additional procedures extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName, lit* assumptionsBegin, lit* assumptionsEnd, int incrementVars); extern void Asat_SatPrintStats( FILE * pFile, solver * p ); +extern void Asat_SolverSetPrefVars( solver * s, int * pPrefVars, int nPrefVars ); // J-frontier support extern Asat_JMan_t * Asat_JManStart( solver * pSat, void * vCircuit ); @@ -131,12 +135,12 @@ struct solver_t clause* binary; // A temporary binary clause lbool* tags; // - vec tagged; // (contains: var) - vec stack; // (contains: var) + veci tagged; // (contains: var) + veci stack; // (contains: var) - vec order; // Variable order. (heap) (contains: var) - vec trail_lim; // Separator indices for different decision levels in 'trail'. (contains: int) - vec model; // If problem is solved, this vector contains the model (contains: lbool). + veci order; // Variable order. (heap) (contains: var) + veci trail_lim; // Separator indices for different decision levels in 'trail'. (contains: int) + veci model; // If problem is solved, this vector contains the model (contains: lbool). int root_level; // Level of first proper decision. int simpdb_assigns;// Number of top-level assignments at last 'simplifyDB()'. @@ -145,8 +149,8 @@ struct solver_t double progress_estimate; int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything - int nConfLimit; // external limit on the number of conflicts - int nImpLimit; // external limit on the number of implications + sint64 nConfLimit; // external limit on the number of conflicts + sint64 nInsLimit; // external limit on the number of implications // the memory manager Asat_MmStep_t * pMem; @@ -154,6 +158,12 @@ struct solver_t // J-frontier Asat_JMan_t * pJMan; + // for making decisions on some variables first + int nPrefDecNum; + int * pPrefVars; + int nPrefVars; + + // solver statistics stats solver_stats; int timeTotal; int timeSelect; diff --git a/src/sat/asat/solver_vec.h b/src/sat/asat/solver_vec.h index fae313d0..1ae30b0a 100644 --- a/src/sat/asat/solver_vec.h +++ b/src/sat/asat/solver_vec.h @@ -24,6 +24,35 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include <stdlib.h> +// vector of 32-bit intergers (added for 64-bit portability) +struct veci_t { + int size; + int cap; + int* ptr; +}; +typedef struct veci_t veci; + +static inline void veci_new (veci* v) { + v->size = 0; + v->cap = 4; + v->ptr = (int*)malloc(sizeof(int)*v->cap); +} + +static inline void veci_delete (veci* v) { free(v->ptr); } +static inline int* veci_begin (veci* v) { return v->ptr; } +static inline int veci_size (veci* v) { return v->size; } +static inline void veci_resize (veci* v, int k) { v->size = k; } // only safe to shrink !! +static inline void veci_push (veci* v, int e) +{ + if (v->size == v->cap) { + int newsize = v->cap * 2+1; + v->ptr = (int*)realloc(v->ptr,sizeof(int)*newsize); + v->cap = newsize; } + v->ptr[v->size++] = e; +} + + +// vector of 32- or 64-bit pointers struct vec_t { int size; int cap; @@ -50,4 +79,5 @@ static inline void vec_push (vec* v, void* e) v->ptr[v->size++] = e; } + #endif diff --git a/src/sat/csat/csat_apis.c b/src/sat/csat/csat_apis.c index 9184cab9..353f6c4c 100644 --- a/src/sat/csat/csat_apis.c +++ b/src/sat/csat/csat_apis.c @@ -39,8 +39,7 @@ struct ABC_ManagerStruct_t Extra_MmFlex_t * pMmNames; // memory manager for signal names // solving parameters int mode; // 0 = resource-aware integration; 1 = brute-force SAT - int nConfLimit; // time limit for pure SAT solving - int nImpLimit; // time limit for pure SAT solving + Prove_Params_t Params; // integrated CEC parameters // information about the target int nog; // the numbers of gates in the target Vec_Ptr_t * vNodes; // the gates in the target @@ -87,9 +86,11 @@ ABC_Manager ABC_InitManager() mng->pMmNames = Extra_MmFlexStart(); mng->vNodes = Vec_PtrAlloc( 100 ); mng->vValues = Vec_IntAlloc( 100 ); - mng->nConfLimit = ABC_DEFAULT_CONF_LIMIT; - mng->nImpLimit = ABC_DEFAULT_IMP_LIMIT; mng->mode = 0; // set "resource-aware integration" as the default mode + // set default parameters for CEC + Prove_ParamsSetDefault( &mng->Params ); + // set infinite resource limit for the final mitering + mng->Params.nMiteringLimitLast = ABC_INFINITY; return mng; } @@ -334,7 +335,7 @@ int ABC_Check_Integrity( ABC_Manager mng ) continue; if ( Abc_ObjFanoutNum(pObj) == 0 ) { - printf( "ABC_Check_Integrity: The network has dangling nodes.\n" ); +// printf( "ABC_Check_Integrity: The network has dangling nodes.\n" ); return 0; } } @@ -361,7 +362,7 @@ int ABC_Check_Integrity( ABC_Manager mng ) ***********************************************************************/ void ABC_SetTimeLimit( ABC_Manager mng, int runtime ) { - printf( "ABC_SetTimeLimit: The resource limit is not implemented (warning).\n" ); +// printf( "ABC_SetTimeLimit: The resource limit is not implemented (warning).\n" ); } /**Function************************************************************* @@ -377,7 +378,7 @@ void ABC_SetTimeLimit( ABC_Manager mng, int runtime ) ***********************************************************************/ void ABC_SetLearnLimit( ABC_Manager mng, int num ) { - printf( "ABC_SetLearnLimit: The resource limit is not implemented (warning).\n" ); +// printf( "ABC_SetLearnLimit: The resource limit is not implemented (warning).\n" ); } /**Function************************************************************* @@ -393,7 +394,7 @@ void ABC_SetLearnLimit( ABC_Manager mng, int num ) ***********************************************************************/ void ABC_SetLearnBacktrackLimit( ABC_Manager mng, int num ) { - printf( "ABC_SetLearnBacktrackLimit: The resource limit is not implemented (warning).\n" ); +// printf( "ABC_SetLearnBacktrackLimit: The resource limit is not implemented (warning).\n" ); } /**Function************************************************************* @@ -409,7 +410,7 @@ void ABC_SetLearnBacktrackLimit( ABC_Manager mng, int num ) ***********************************************************************/ void ABC_SetSolveBacktrackLimit( ABC_Manager mng, int num ) { - mng->nConfLimit = num; + mng->Params.nMiteringLimitLast = num; } /**Function************************************************************* @@ -425,7 +426,70 @@ void ABC_SetSolveBacktrackLimit( ABC_Manager mng, int num ) ***********************************************************************/ void ABC_SetSolveImplicationLimit( ABC_Manager mng, int num ) { - mng->nImpLimit = num; +// printf( "ABC_SetSolveImplicationLimit: The resource limit is not implemented (warning).\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void ABC_SetTotalBacktrackLimit( ABC_Manager mng, uint64 num ) +{ + mng->Params.nTotalBacktrackLimit = num; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void ABC_SetTotalInspectLimit( ABC_Manager mng, uint64 num ) +{ + mng->Params.nTotalInspectLimit = num; +} +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +uint64 ABC_GetTotalBacktracksMade( ABC_Manager mng ) +{ + return mng->Params.nTotalBacktracksMade; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +uint64 ABC_GetTotalInspectsMade( ABC_Manager mng ) +{ + return mng->Params.nTotalInspectsMade; } /**Function************************************************************* @@ -539,7 +603,7 @@ void ABC_AnalyzeTargets( ABC_Manager mng ) ***********************************************************************/ enum CSAT_StatusT ABC_Solve( ABC_Manager mng ) { - Prove_Params_t Params, * pParams = &Params; + Prove_Params_t * pParams = &mng->Params; int RetValue, i; // check if the target network is available @@ -548,16 +612,9 @@ enum CSAT_StatusT ABC_Solve( ABC_Manager mng ) // try to prove the miter using a number of techniques if ( mng->mode ) - RetValue = Abc_NtkMiterSat( mng->pTarget, mng->nConfLimit, mng->nImpLimit, 0, 0 ); + RetValue = Abc_NtkMiterSat( mng->pTarget, (sint64)pParams->nMiteringLimitLast, (sint64)0, 0, 0, NULL, NULL ); else - { - // set default parameters for CEC - Prove_ParamsSetDefault( pParams ); - // set infinite resource limit for the final mitering - pParams->nMiteringLimitLast = ABC_INFINITY; - // call the checker RetValue = Abc_NtkMiterProve( &mng->pTarget, pParams ); - } // analyze the result mng->pResult = ABC_TargetResAlloc( Abc_NtkCiNum(mng->pTarget) ); diff --git a/src/sat/csat/csat_apis.h b/src/sat/csat/csat_apis.h index d2fa770e..b80eddbf 100644 --- a/src/sat/csat/csat_apis.h +++ b/src/sat/csat/csat_apis.h @@ -182,6 +182,11 @@ extern void ABC_SetSolveBacktrackLimit(ABC_Manager mng, int num extern void ABC_SetLearnBacktrackLimit(ABC_Manager mng, int num); extern void ABC_EnableDump(ABC_Manager mng, char* dump_file); +extern void ABC_SetTotalBacktrackLimit( ABC_Manager mng, uint64 num ); +extern void ABC_SetTotalInspectLimit( ABC_Manager mng, uint64 num ); +extern uint64 ABC_GetTotalBacktracksMade( ABC_Manager mng ); +extern uint64 ABC_GetTotalInspectsMade( ABC_Manager mng ); + // the meaning of the parameters are: // nog: number of gates that are in the targets // names: name array of gates diff --git a/src/sat/fraig/fraig.h b/src/sat/fraig/fraig.h index d6215465..84363efe 100644 --- a/src/sat/fraig/fraig.h +++ b/src/sat/fraig/fraig.h @@ -27,6 +27,8 @@ extern "C" { /// INCLUDES /// //////////////////////////////////////////////////////////////////////// +#include "solver.h" + //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// @@ -49,8 +51,6 @@ struct Fraig_ParamsStruct_t_ int nPatsDyna; // the number of words of dynamic simulation info int nBTLimit; // the max number of backtracks to perform int nSeconds; // the timeout for the final proof - int nConfLimit; - int nImpLimit; int fFuncRed; // performs only one level hashing int fFeedBack; // enables solver feedback int fDist1Pats; // enables distance-1 patterns @@ -60,31 +60,39 @@ struct Fraig_ParamsStruct_t_ int fVerbose; // the verbosiness flag int fVerboseP; // the verbosiness flag (for proof reporting) int fInternal; // is set to 1 for internal fraig calls + int nConfLimit; // the limit on the number of conflicts + sint64 nInspLimit; // the limit on the number of inspections }; struct Prove_ParamsStruct_t_ { // general parameters - int fUseFraiging; // enables fraiging - int fUseRewriting; // enables rewriting - int fUseBdds; // enables BDD construction when other methods fail - int fVerbose; // prints verbose stats + int fUseFraiging; // enables fraiging + int fUseRewriting; // enables rewriting + int fUseBdds; // enables BDD construction when other methods fail + int fVerbose; // prints verbose stats // iterations - int nItersMax; // the number of iterations + int nItersMax; // the number of iterations // mitering - int nMiteringLimitStart; // starting mitering limit - float nMiteringLimitMulti; // multiplicative coefficient to increase the limit in each iteration + int nMiteringLimitStart; // starting mitering limit + float nMiteringLimitMulti; // multiplicative coefficient to increase the limit in each iteration // rewriting - int nRewritingLimitStart; // the number of rewriting iterations - float nRewritingLimitMulti; // multiplicative coefficient to increase the limit in each iteration + int nRewritingLimitStart; // the number of rewriting iterations + float nRewritingLimitMulti; // multiplicative coefficient to increase the limit in each iteration // fraiging - int nFraigingLimitStart; // starting backtrack(conflict) limit - float nFraigingLimitMulti; // multiplicative coefficient to increase the limit in each iteration + int nFraigingLimitStart; // starting backtrack(conflict) limit + float nFraigingLimitMulti; // multiplicative coefficient to increase the limit in each iteration // last-gasp BDD construction - int nBddSizeLimit; // the number of BDD nodes when construction is aborted - int fBddReorder; // enables dynamic BDD variable reordering + int nBddSizeLimit; // the number of BDD nodes when construction is aborted + int fBddReorder; // enables dynamic BDD variable reordering // last-gasp mitering - int nMiteringLimitLast; // final mitering limit + int nMiteringLimitLast; // final mitering limit + // global SAT solver limits + sint64 nTotalBacktrackLimit; // global limit on the number of backtracks + sint64 nTotalInspectLimit; // global limit on the number of clause inspects + // global resources applied + sint64 nTotalBacktracksMade; // the total number of backtracks made + sint64 nTotalInspectsMade; // the total number of inspects made }; //////////////////////////////////////////////////////////////////////// @@ -137,6 +145,8 @@ extern int Fraig_ManReadPatternNumRandom( Fraig_Man_t * p ); extern int Fraig_ManReadPatternNumDynamic( Fraig_Man_t * p ); extern int Fraig_ManReadPatternNumDynamicFiltered( Fraig_Man_t * p ); extern int Fraig_ManReadSatFails( Fraig_Man_t * p ); +extern int Fraig_ManReadConflicts( Fraig_Man_t * p ); +extern int Fraig_ManReadInspects( Fraig_Man_t * p ); extern void Fraig_ManSetFuncRed( Fraig_Man_t * p, int fFuncRed ); extern void Fraig_ManSetFeedBack( Fraig_Man_t * p, int fFeedBack ); diff --git a/src/sat/fraig/fraigApi.c b/src/sat/fraig/fraigApi.c index b4bdbcab..79a7c224 100644 --- a/src/sat/fraig/fraigApi.c +++ b/src/sat/fraig/fraigApi.c @@ -66,6 +66,10 @@ int Fraig_ManReadPatternNumDynamic( Fraig_Man_t * p ) { int Fraig_ManReadPatternNumDynamicFiltered( Fraig_Man_t * p ) { return p->iPatsPerm; } // returns the number of times FRAIG package timed out int Fraig_ManReadSatFails( Fraig_Man_t * p ) { return p->nSatFailsReal; } +// returns the number of conflicts in the SAT solver +int Fraig_ManReadConflicts( Fraig_Man_t * p ) { return p->pSat? Msat_SolverReadBackTracks(p->pSat) : 0; } +// returns the number of inspections in the SAT solver +int Fraig_ManReadInspects( Fraig_Man_t * p ) { return p->pSat? Msat_SolverReadInspects(p->pSat) : 0; } /**Function************************************************************* diff --git a/src/sat/fraig/fraigCanon.c b/src/sat/fraig/fraigCanon.c index 4ebb9a9f..89bc924f 100644 --- a/src/sat/fraig/fraigCanon.c +++ b/src/sat/fraig/fraigCanon.c @@ -49,6 +49,7 @@ Fraig_Node_t * Fraig_NodeAndCanon( Fraig_Man_t * pMan, Fraig_Node_t * p1, Fraig_Node_t * p2 ) { Fraig_Node_t * pNodeNew, * pNodeOld, * pNodeRepr; + int fUseSatCheck; // int RetValue; // check for trivial cases @@ -167,7 +168,8 @@ Fraig_Node_t * Fraig_NodeAndCanon( Fraig_Man_t * pMan, Fraig_Node_t * p1, Fraig_ // there is another node which looks the same according to simulation // use SAT to resolve the ambiguity - if ( Fraig_NodeIsEquivalent( pMan, pNodeOld, pNodeNew, pMan->nBTLimit, 1000000 ) ) + fUseSatCheck = (pMan->nInspLimit == 0 || Fraig_ManReadInspects(pMan) < pMan->nInspLimit); + if ( fUseSatCheck && Fraig_NodeIsEquivalent( pMan, pNodeOld, pNodeNew, pMan->nBTLimit, 1000000 ) ) { // set the node to be equivalent with this node // to prevent loops, only set if the old node is not in the TFI of the new node diff --git a/src/sat/fraig/fraigInt.h b/src/sat/fraig/fraigInt.h index 8e016331..9c6e0d47 100644 --- a/src/sat/fraig/fraigInt.h +++ b/src/sat/fraig/fraigInt.h @@ -66,7 +66,7 @@ // the bit masks #define FRAIG_MASK(n) ((~((unsigned)0)) >> (32-(n))) #define FRAIG_FULL (~((unsigned)0)) -#define FRAIG_NUM_WORDS(n) ((n)/32 + (((n)%32) > 0)) +#define FRAIG_NUM_WORDS(n) (((n)>>5) + (((n)&31) > 0)) // maximum/minimum operators #define FRAIG_MIN(a,b) (((a) < (b))? (a) : (b)) @@ -152,6 +152,7 @@ struct Fraig_ManStruct_t_ int fTryProve; // tries to solve the final miter int fVerbose; // the verbosiness flag int fVerboseP; // the verbosiness flag + sint64 nInspLimit; // the inspection limit int nTravIds; // the traversal counter int nTravIds2; // the traversal counter diff --git a/src/sat/fraig/fraigMan.c b/src/sat/fraig/fraigMan.c index 3268ac3a..ffb51a07 100644 --- a/src/sat/fraig/fraigMan.c +++ b/src/sat/fraig/fraigMan.c @@ -42,10 +42,12 @@ int timeAssign; ***********************************************************************/ void Prove_ParamsSetDefault( Prove_Params_t * pParams ) { + // clean the parameter structure + memset( pParams, 0, sizeof(Prove_Params_t) ); // general parameters pParams->fUseFraiging = 1; // enables fraiging pParams->fUseRewriting = 1; // enables rewriting - pParams->fUseBdds = 1; // enables BDD construction when other methods fail + pParams->fUseBdds = 0; // enables BDD construction when other methods fail pParams->fVerbose = 0; // prints verbose stats // iterations pParams->nItersMax = 6; // the number of iterations @@ -63,6 +65,9 @@ void Prove_ParamsSetDefault( Prove_Params_t * pParams ) pParams->fBddReorder = 1; // enables dynamic BDD variable reordering // last-gasp mitering pParams->nMiteringLimitLast = 1000000; // final mitering limit + // global SAT solver limits + pParams->nTotalBacktrackLimit = 0; // global limit on the number of backtracks + pParams->nTotalInspectLimit = 0; // global limit on the number of clause inspects } /**Function************************************************************* @@ -92,6 +97,8 @@ void Fraig_ParamsSetDefault( Fraig_Params_t * pParams ) pParams->fVerbose = 0; // the verbosiness flag pParams->fVerboseP = 0; // the verbose flag for reporting the proof pParams->fInternal = 0; // the flag indicates the internal run + pParams->nConfLimit = 0; // the limit on the number of conflicts + pParams->nInspLimit = 0; // the limit on the number of inspections } /**Function************************************************************* @@ -121,6 +128,8 @@ void Fraig_ParamsSetDefaultFull( Fraig_Params_t * pParams ) pParams->fVerbose = 0; // the verbosiness flag pParams->fVerboseP = 0; // the verbose flag for reporting the proof pParams->fInternal = 0; // the flag indicates the internal run + pParams->nConfLimit = 0; // the limit on the number of conflicts + pParams->nInspLimit = 0; // the limit on the number of inspections } /**Function************************************************************* @@ -176,6 +185,7 @@ Fraig_Man_t * Fraig_ManCreate( Fraig_Params_t * pParams ) p->fTryProve = pParams->fTryProve; // disable accumulation of structural choices (keeps only the first choice) p->fVerbose = pParams->fVerbose; // disable verbose output p->fVerboseP = pParams->fVerboseP; // disable verbose output + p->nInspLimit = pParams->nInspLimit; // the limit on the number of inspections // start memory managers p->mmNodes = Fraig_MemFixedStart( sizeof(Fraig_Node_t) ); diff --git a/src/sat/msat/msat.h b/src/sat/msat/msat.h index 94416a5d..5f8603a7 100644 --- a/src/sat/msat/msat.h +++ b/src/sat/msat/msat.h @@ -97,6 +97,7 @@ extern int * Msat_SolverReadAssignsArray( Msat_Solver_t * p ); extern int * Msat_SolverReadModelArray( Msat_Solver_t * p ); extern unsigned Msat_SolverReadTruth( Msat_Solver_t * p ); extern int Msat_SolverReadBackTracks( Msat_Solver_t * p ); +extern int Msat_SolverReadInspects( Msat_Solver_t * p ); extern void Msat_SolverSetVerbosity( Msat_Solver_t * p, int fVerbose ); extern void Msat_SolverSetProofWriting( Msat_Solver_t * p, int fProof ); extern void Msat_SolverSetVarTypeA( Msat_Solver_t * p, int Var ); diff --git a/src/sat/msat/msatInt.h b/src/sat/msat/msatInt.h index 3dfe2109..03e7b873 100644 --- a/src/sat/msat/msatInt.h +++ b/src/sat/msat/msatInt.h @@ -56,10 +56,10 @@ typedef long long int64; #define ALLOC(type, num) \ ((type *) malloc(sizeof(type) * (num))) #define REALLOC(type, obj, num) \ - (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \ - ((type *) malloc(sizeof(type) * (num))) + ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num)))) #define FREE(obj) \ - ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) + ((obj) ? (free((char *)(obj)), (obj) = 0) : 0) // By default, custom memory management is used // which guarantees constant time allocation/deallocation diff --git a/src/sat/msat/msatSolverApi.c b/src/sat/msat/msatSolverApi.c index 4a721487..e3d85774 100644 --- a/src/sat/msat/msatSolverApi.c +++ b/src/sat/msat/msatSolverApi.c @@ -41,26 +41,27 @@ static void Msat_SolverSetupTruthTables( unsigned uTruths[][2] ); SeeAlso [] ***********************************************************************/ -int Msat_SolverReadVarNum( Msat_Solver_t * p ) { return p->nVars; } -int Msat_SolverReadClauseNum( Msat_Solver_t * p ) { return p->nClauses; } -int Msat_SolverReadVarAllocNum( Msat_Solver_t * p ) { return p->nVarsAlloc;} +int Msat_SolverReadVarNum( Msat_Solver_t * p ) { return p->nVars; } +int Msat_SolverReadClauseNum( Msat_Solver_t * p ) { return p->nClauses; } +int Msat_SolverReadVarAllocNum( Msat_Solver_t * p ) { return p->nVarsAlloc; } int Msat_SolverReadDecisionLevel( Msat_Solver_t * p ) { return Msat_IntVecReadSize(p->vTrailLim); } -int * Msat_SolverReadDecisionLevelArray( Msat_Solver_t * p ) { return p->pLevel; } -Msat_Clause_t ** Msat_SolverReadReasonArray( Msat_Solver_t * p ) { return p->pReasons; } +int * Msat_SolverReadDecisionLevelArray( Msat_Solver_t * p ) { return p->pLevel; } +Msat_Clause_t ** Msat_SolverReadReasonArray( Msat_Solver_t * p ) { return p->pReasons; } Msat_Lit_t Msat_SolverReadVarValue( Msat_Solver_t * p, Msat_Var_t Var ) { return p->pAssigns[Var]; } -Msat_ClauseVec_t * Msat_SolverReadLearned( Msat_Solver_t * p ) { return p->vLearned; } -Msat_ClauseVec_t ** Msat_SolverReadWatchedArray( Msat_Solver_t * p ) { return p->pvWatched; } -int * Msat_SolverReadAssignsArray( Msat_Solver_t * p ) { return p->pAssigns; } -int * Msat_SolverReadModelArray( Msat_Solver_t * p ) { return p->pModel; } -int Msat_SolverReadBackTracks( Msat_Solver_t * p ) { return p->nBackTracks; } -Msat_MmStep_t * Msat_SolverReadMem( Msat_Solver_t * p ) { return p->pMem; } -int * Msat_SolverReadSeenArray( Msat_Solver_t * p ) { return p->pSeen; } -int Msat_SolverIncrementSeenId( Msat_Solver_t * p ) { return ++p->nSeenId; } +Msat_ClauseVec_t * Msat_SolverReadLearned( Msat_Solver_t * p ) { return p->vLearned; } +Msat_ClauseVec_t ** Msat_SolverReadWatchedArray( Msat_Solver_t * p ) { return p->pvWatched; } +int * Msat_SolverReadAssignsArray( Msat_Solver_t * p ) { return p->pAssigns; } +int * Msat_SolverReadModelArray( Msat_Solver_t * p ) { return p->pModel; } +int Msat_SolverReadBackTracks( Msat_Solver_t * p ) { return (int)p->Stats.nConflicts; } +int Msat_SolverReadInspects( Msat_Solver_t * p ) { return (int)p->Stats.nInspects; } +Msat_MmStep_t * Msat_SolverReadMem( Msat_Solver_t * p ) { return p->pMem; } +int * Msat_SolverReadSeenArray( Msat_Solver_t * p ) { return p->pSeen; } +int Msat_SolverIncrementSeenId( Msat_Solver_t * p ) { return ++p->nSeenId; } void Msat_SolverSetVerbosity( Msat_Solver_t * p, int fVerbose ) { p->fVerbose = fVerbose; } -void Msat_SolverClausesIncrement( Msat_Solver_t * p ) { p->nClausesAlloc++; } -void Msat_SolverClausesDecrement( Msat_Solver_t * p ) { p->nClausesAlloc--; } -void Msat_SolverClausesIncrementL( Msat_Solver_t * p ) { p->nClausesAllocL++; } -void Msat_SolverClausesDecrementL( Msat_Solver_t * p ) { p->nClausesAllocL--; } +void Msat_SolverClausesIncrement( Msat_Solver_t * p ) { p->nClausesAlloc++; } +void Msat_SolverClausesDecrement( Msat_Solver_t * p ) { p->nClausesAlloc--; } +void Msat_SolverClausesIncrementL( Msat_Solver_t * p ) { p->nClausesAllocL++; } +void Msat_SolverClausesDecrementL( Msat_Solver_t * p ) { p->nClausesAllocL--; } void Msat_SolverMarkLastClauseTypeA( Msat_Solver_t * p ) { Msat_ClauseSetTypeA( Msat_ClauseVecReadEntry( p->vClauses, Msat_ClauseVecReadSize(p->vClauses)-1 ), 1 ); } void Msat_SolverMarkClausesStart( Msat_Solver_t * p ) { p->nClausesStart = Msat_ClauseVecReadSize(p->vClauses); } diff --git a/src/opt/xyz/xyzInt.h b/src/temp/esop/esop.h index 656612aa..d6cdff71 100644 --- a/src/opt/xyz/xyzInt.h +++ b/src/temp/esop/esop.h @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [xyzInt.h] + FileName [esop.h] SystemName [ABC: Logic synthesis and verification system.] @@ -14,96 +14,119 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: xyzInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: esop.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "abc.h" +#ifndef __ESOP_H__ +#define __ESOP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdio.h" +#include "vec.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct Min_Man_t_ Min_Man_t; -typedef struct Min_Cube_t_ Min_Cube_t; +typedef struct Esop_Man_t_ Esop_Man_t; +typedef struct Esop_Cube_t_ Esop_Cube_t; +typedef struct Esop_MmFixed_t_ Esop_MmFixed_t; -struct Min_Man_t_ +struct Esop_Man_t_ { int nVars; // the number of vars int nWords; // the number of words - Extra_MmFixed_t * pMemMan; // memory manager for cubes + Esop_MmFixed_t * pMemMan1; // memory manager for cubes + Esop_MmFixed_t * pMemMan2; // memory manager for cubes + Esop_MmFixed_t * pMemMan4; // memory manager for cubes + Esop_MmFixed_t * pMemMan8; // memory manager for cubes // temporary cubes - Min_Cube_t * pOne0; // tautology cube - Min_Cube_t * pOne1; // tautology cube - Min_Cube_t * pTriv0[2]; // trivial cube - Min_Cube_t * pTriv1[2]; // trivial cube - Min_Cube_t * pTemp; // cube for computing the distance - Min_Cube_t * pBubble; // cube used as a separator + Esop_Cube_t * pOne0; // tautology cube + Esop_Cube_t * pOne1; // tautology cube + Esop_Cube_t * pTriv0; // trivial cube + Esop_Cube_t * pTriv1; // trivial cube + Esop_Cube_t * pTemp; // cube for computing the distance + Esop_Cube_t * pBubble; // cube used as a separator // temporary storage for the new cover int nCubes; // the number of cubes - Min_Cube_t ** ppStore; // storage for cubes by number of literals + Esop_Cube_t ** ppStore; // storage for cubes by number of literals }; -struct Min_Cube_t_ +struct Esop_Cube_t_ { - Min_Cube_t * pNext; // the pointer to the next cube in the cover + Esop_Cube_t * pNext; // the pointer to the next cube in the cover unsigned nVars : 10; // the number of variables unsigned nWords : 12; // the number of machine words unsigned nLits : 10; // the number of literals in the cube unsigned uData[1]; // the bit-data for the cube }; +#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) +#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#define REALLOC(type, obj, num) \ + ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \ + ((type *) malloc(sizeof(type) * (num)))) // iterators through the entries in the linked lists of cubes -#define Min_CoverForEachCube( pCover, pCube ) \ +#define Esop_CoverForEachCube( pCover, pCube ) \ for ( pCube = pCover; \ pCube; \ pCube = pCube->pNext ) -#define Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \ +#define Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \ for ( pCube = pCover, \ pCube2 = pCube? pCube->pNext: NULL; \ pCube; \ pCube = pCube2, \ pCube2 = pCube? pCube->pNext: NULL ) -#define Min_CoverForEachCubePrev( pCover, pCube, ppPrev ) \ +#define Esop_CoverForEachCubePrev( pCover, pCube, ppPrev ) \ for ( pCube = pCover, \ ppPrev = &(pCover); \ pCube; \ ppPrev = &pCube->pNext, \ pCube = pCube->pNext ) + // macros to get hold of bits and values in the cubes -static inline int Min_CubeHasBit( Min_Cube_t * p, int i ) { return (p->uData[(i)>>5] & (1<<((i) & 31))) > 0; } -static inline void Min_CubeSetBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] |= (1<<((i) & 31)); } -static inline void Min_CubeXorBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] ^= (1<<((i) & 31)); } -static inline int Min_CubeGetVar( Min_Cube_t * p, int Var ) { return 3 & (p->uData[(2*Var)>>5] >> ((2*Var) & 31)); } -static inline void Min_CubeXorVar( Min_Cube_t * p, int Var, int Value ) { p->uData[(2*Var)>>5] ^= (Value<<((2*Var) & 31)); } - -/*=== xyzMinEsop.c ==========================================================*/ -extern void Min_EsopMinimize( Min_Man_t * p ); -extern void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); -/*=== xyzMinSop.c ==========================================================*/ -extern void Min_SopMinimize( Min_Man_t * p ); -extern void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); -/*=== xyzMinMan.c ==========================================================*/ -extern Min_Man_t * Min_ManAlloc( int nVars ); -extern void Min_ManClean( Min_Man_t * p, int nSupp ); -extern void Min_ManFree( Min_Man_t * p ); -/*=== xyzMinUtil.c ==========================================================*/ -extern void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ); -extern void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ); -extern void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ); -extern void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ); -extern void Min_CoverCheck( Min_Man_t * p ); -extern int Min_CubeCheck( Min_Cube_t * pCube ); -extern Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ); -extern void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ); -extern int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ); +static inline int Esop_CubeHasBit( Esop_Cube_t * p, int i ) { return (p->uData[i >> 5] & (1<<(i & 31))) > 0; } +static inline void Esop_CubeSetBit( Esop_Cube_t * p, int i ) { p->uData[i >> 5] |= (1<<(i & 31)); } +static inline void Esop_CubeXorBit( Esop_Cube_t * p, int i ) { p->uData[i >> 5] ^= (1<<(i & 31)); } +static inline int Esop_CubeGetVar( Esop_Cube_t * p, int Var ) { return 3 & (p->uData[(Var<<1)>>5] >> ((Var<<1) & 31)); } +static inline void Esop_CubeXorVar( Esop_Cube_t * p, int Var, int Value ) { p->uData[(Var<<1)>>5] ^= (Value<<((Var<<1) & 31)); } +static inline int Esop_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } + +/*=== esopMem.c ===========================================================*/ +extern Esop_MmFixed_t * Esop_MmFixedStart( int nEntrySize ); +extern void Esop_MmFixedStop( Esop_MmFixed_t * p, int fVerbose ); +extern char * Esop_MmFixedEntryFetch( Esop_MmFixed_t * p ); +extern void Esop_MmFixedEntryRecycle( Esop_MmFixed_t * p, char * pEntry ); +extern void Esop_MmFixedRestart( Esop_MmFixed_t * p ); +extern int Esop_MmFixedReadMemUsage( Esop_MmFixed_t * p ); +/*=== esopMin.c ===========================================================*/ +extern void Esop_EsopMinimize( Esop_Man_t * p ); +extern void Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube ); +/*=== esopMan.c ===========================================================*/ +extern Esop_Man_t * Esop_ManAlloc( int nVars ); +extern void Esop_ManClean( Esop_Man_t * p, int nSupp ); +extern void Esop_ManFree( Esop_Man_t * p ); +/*=== esopUtil.c ===========================================================*/ +extern void Esop_CubeWrite( FILE * pFile, Esop_Cube_t * pCube ); +extern void Esop_CoverWrite( FILE * pFile, Esop_Cube_t * pCover ); +extern void Esop_CoverWriteStore( FILE * pFile, Esop_Man_t * p ); +extern void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop ); +extern void Esop_CoverCheck( Esop_Man_t * p ); +extern int Esop_CubeCheck( Esop_Cube_t * pCube ); +extern Esop_Cube_t * Esop_CoverCollect( Esop_Man_t * p, int nSuppSize ); +extern void Esop_CoverExpand( Esop_Man_t * p, Esop_Cube_t * pCover ); +extern int Esop_CoverSuppVarNum( Esop_Man_t * p, Esop_Cube_t * pCover ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// - + /**Function************************************************************* Synopsis [Creates the cube.] @@ -115,10 +138,17 @@ extern int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ); SeeAlso [] ***********************************************************************/ -static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p ) +static inline Esop_Cube_t * Esop_CubeAlloc( Esop_Man_t * p ) { - Min_Cube_t * pCube; - pCube = (Min_Cube_t *)Extra_MmFixedEntryFetch( p->pMemMan ); + Esop_Cube_t * pCube; + if ( p->nWords <= 1 ) + pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan1 ); + else if ( p->nWords <= 2 ) + pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan2 ); + else if ( p->nWords <= 4 ) + pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan4 ); + else if ( p->nWords <= 8 ) + pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan8 ); pCube->pNext = NULL; pCube->nVars = p->nVars; pCube->nWords = p->nWords; @@ -138,11 +168,11 @@ static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p ) SeeAlso [] ***********************************************************************/ -static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl ) +static inline Esop_Cube_t * Esop_CubeAllocVar( Esop_Man_t * p, int iVar, int fCompl ) { - Min_Cube_t * pCube; - pCube = Min_CubeAlloc( p ); - Min_CubeXorBit( pCube, iVar*2+fCompl ); + Esop_Cube_t * pCube; + pCube = Esop_CubeAlloc( p ); + Esop_CubeXorBit( pCube, iVar*2+fCompl ); pCube->nLits = 1; return pCube; } @@ -158,10 +188,10 @@ static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl SeeAlso [] ***********************************************************************/ -static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy ) +static inline Esop_Cube_t * Esop_CubeDup( Esop_Man_t * p, Esop_Cube_t * pCopy ) { - Min_Cube_t * pCube; - pCube = Min_CubeAlloc( p ); + Esop_Cube_t * pCube; + pCube = Esop_CubeAlloc( p ); memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords ); pCube->nLits = pCopy->nLits; return pCube; @@ -178,9 +208,16 @@ static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy ) SeeAlso [] ***********************************************************************/ -static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube ) +static inline void Esop_CubeRecycle( Esop_Man_t * p, Esop_Cube_t * pCube ) { - Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); + if ( pCube->nWords <= 1 ) + Esop_MmFixedEntryRecycle( p->pMemMan1, (char *)pCube ); + else if ( pCube->nWords <= 2 ) + Esop_MmFixedEntryRecycle( p->pMemMan2, (char *)pCube ); + else if ( pCube->nWords <= 4 ) + Esop_MmFixedEntryRecycle( p->pMemMan4, (char *)pCube ); + else if ( pCube->nWords <= 8 ) + Esop_MmFixedEntryRecycle( p->pMemMan8, (char *)pCube ); } /**Function************************************************************* @@ -194,11 +231,48 @@ static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube ) SeeAlso [] ***********************************************************************/ -static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover ) +static inline void Esop_CoverRecycle( Esop_Man_t * p, Esop_Cube_t * pCover ) { - Min_Cube_t * pCube, * pCube2; - Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) - Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); + Esop_Cube_t * pCube, * pCube2; + if ( pCover == NULL ) + return; + if ( pCover->nWords <= 1 ) + Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + Esop_MmFixedEntryRecycle( p->pMemMan1, (char *)pCube ); + else if ( pCover->nWords <= 2 ) + Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + Esop_MmFixedEntryRecycle( p->pMemMan2, (char *)pCube ); + else if ( pCover->nWords <= 4 ) + Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + Esop_MmFixedEntryRecycle( p->pMemMan4, (char *)pCube ); + else if ( pCover->nWords <= 8 ) + Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + Esop_MmFixedEntryRecycle( p->pMemMan8, (char *)pCube ); +} + +/**Function************************************************************* + + Synopsis [Recycles the cube cover.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Esop_Cube_t * Esop_CoverDup( Esop_Man_t * p, Esop_Cube_t * pCover ) +{ + Esop_Cube_t * pCube, * pCubeNew; + Esop_Cube_t * pCoverNew = NULL, ** ppTail = &pCoverNew; + Esop_CoverForEachCube( pCover, pCube ) + { + pCubeNew = Esop_CubeDup( p, pCube ); + *ppTail = pCubeNew; + ppTail = &pCubeNew->pNext; + } + *ppTail = NULL; + return pCoverNew; } @@ -213,7 +287,7 @@ static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover ) SeeAlso [] ***********************************************************************/ -static inline int Min_CubeCountLits( Min_Cube_t * pCube ) +static inline int Esop_CubeCountLits( Esop_Cube_t * pCube ) { unsigned uData; int Count = 0, i, w; @@ -238,7 +312,7 @@ static inline int Min_CubeCountLits( Min_Cube_t * pCube ) SeeAlso [] ***********************************************************************/ -static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits ) +static inline void Esop_CubeGetLits( Esop_Cube_t * pCube, Vec_Int_t * vLits ) { unsigned uData; int i, w; @@ -263,11 +337,11 @@ static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits ) SeeAlso [] ***********************************************************************/ -static inline int Min_CoverCountCubes( Min_Cube_t * pCover ) +static inline int Esop_CoverCountCubes( Esop_Cube_t * pCover ) { - Min_Cube_t * pCube; + Esop_Cube_t * pCube; int Count = 0; - Min_CoverForEachCube( pCover, pCube ) + Esop_CoverForEachCube( pCover, pCube ) Count++; return Count; } @@ -284,7 +358,7 @@ static inline int Min_CoverCountCubes( Min_Cube_t * pCover ) SeeAlso [] ***********************************************************************/ -static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +static inline int Esop_CubesDisjoint( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 ) { unsigned uData; int i; @@ -310,7 +384,7 @@ static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) SeeAlso [] ***********************************************************************/ -static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube, Vec_Int_t * vVars ) +static inline void Esop_CoverGetDisjVars( Esop_Cube_t * pThis, Esop_Cube_t * pCube, Vec_Int_t * vVars ) { unsigned uData; int i, w; @@ -338,7 +412,7 @@ static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube, SeeAlso [] ***********************************************************************/ -static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Min_Cube_t * pTemp ) +static inline int Esop_CubesDistOne( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1, Esop_Cube_t * pTemp ) { unsigned uData; int i, fFound = 0; @@ -361,9 +435,9 @@ static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Mi if ( fFound == 0 ) { printf( "\n" ); - Min_CubeWrite( stdout, pCube0 ); - Min_CubeWrite( stdout, pCube1 ); - printf( "Error: Min_CubesDistOne() looks at two equal cubes!\n" ); + Esop_CubeWrite( stdout, pCube0 ); + Esop_CubeWrite( stdout, pCube1 ); + printf( "Error: Esop_CubesDistOne() looks at two equal cubes!\n" ); } return 1; } @@ -379,7 +453,7 @@ static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Mi SeeAlso [] ***********************************************************************/ -static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, int * pVar0, int * pVar1 ) +static inline int Esop_CubesDistTwo( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1, int * pVar0, int * pVar1 ) { unsigned uData;//, uData2; int i, k, Var0 = -1, Var1 = -1; @@ -427,9 +501,9 @@ static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, in if ( Var0 == -1 || Var1 == -1 ) { printf( "\n" ); - Min_CubeWrite( stdout, pCube0 ); - Min_CubeWrite( stdout, pCube1 ); - printf( "Error: Min_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" ); + Esop_CubeWrite( stdout, pCube0 ); + Esop_CubeWrite( stdout, pCube1 ); + printf( "Error: Esop_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" ); } return 0; } @@ -445,15 +519,15 @@ static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, in SeeAlso [] ***********************************************************************/ -static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +static inline Esop_Cube_t * Esop_CubesProduct( Esop_Man_t * p, Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 ) { - Min_Cube_t * pCube; + Esop_Cube_t * pCube; int i; assert( pCube0->nVars == pCube1->nVars ); - pCube = Min_CubeAlloc( p ); + pCube = Esop_CubeAlloc( p ); for ( i = 0; i < p->nWords; i++ ) pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i]; - pCube->nLits = Min_CubeCountLits( pCube ); + pCube->nLits = Esop_CubeCountLits( pCube ); return pCube; } @@ -468,15 +542,15 @@ static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0, SeeAlso [] ***********************************************************************/ -static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +static inline Esop_Cube_t * Esop_CubesXor( Esop_Man_t * p, Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 ) { - Min_Cube_t * pCube; + Esop_Cube_t * pCube; int i; assert( pCube0->nVars == pCube1->nVars ); - pCube = Min_CubeAlloc( p ); + pCube = Esop_CubeAlloc( p ); for ( i = 0; i < p->nWords; i++ ) pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i]; - pCube->nLits = Min_CubeCountLits( pCube ); + pCube->nLits = Esop_CubeCountLits( pCube ); return pCube; } @@ -491,7 +565,7 @@ static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min SeeAlso [] ***********************************************************************/ -static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +static inline int Esop_CubesAreEqual( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 ) { int i; for ( i = 0; i < (int)pCube0->nWords; i++ ) @@ -511,7 +585,7 @@ static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) SeeAlso [] ***********************************************************************/ -static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +static inline int Esop_CubeIsContained( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 ) { int i; for ( i = 0; i < (int)pCube0->nWords; i++ ) @@ -531,7 +605,7 @@ static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1 SeeAlso [] ***********************************************************************/ -static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, Min_Cube_t * pMask ) +static inline void Esop_CubesTransform( Esop_Cube_t * pCube, Esop_Cube_t * pDist, Esop_Cube_t * pMask ) { int w; for ( w = 0; w < (int)pCube->nWords; w++ ) @@ -552,7 +626,7 @@ static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, M SeeAlso [] ***********************************************************************/ -static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist ) +static inline void Esop_CubesTransformOr( Esop_Cube_t * pCube, Esop_Cube_t * pDist ) { int w; for ( w = 0; w < (int)pCube->nWords; w++ ) @@ -572,22 +646,22 @@ static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist SeeAlso [] ***********************************************************************/ -static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCover ) +static inline void Esop_CoverExpandRemoveEqual( Esop_Man_t * p, Esop_Cube_t * pCover ) { - Min_Cube_t * pCube, * pCube2, * pThis; + Esop_Cube_t * pCube, * pCube2, * pThis; if ( pCover == NULL ) { - Min_ManClean( p, p->nVars ); + Esop_ManClean( p, p->nVars ); return; } - Min_ManClean( p, pCover->nVars ); - Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + Esop_ManClean( p, pCover->nVars ); + Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) { // go through the linked list - Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) - if ( Min_CubesAreEqual( pCube, pThis ) ) + Esop_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) + if ( Esop_CubesAreEqual( pCube, pThis ) ) { - Min_CubeRecycle( p, pCube ); + Esop_CubeRecycle( p, pCube ); break; } if ( pThis != NULL ) @@ -609,32 +683,38 @@ static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCove SeeAlso [] ***********************************************************************/ -static inline int Min_CoverContainsCube( Min_Man_t * p, Min_Cube_t * pCube ) +static inline int Esop_CoverContainsCube( Esop_Man_t * p, Esop_Cube_t * pCube ) { - Min_Cube_t * pThis; + Esop_Cube_t * pThis; int i; /* // this cube cannot be equal to any cube - Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) + Esop_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) { - if ( Min_CubesAreEqual( pCube, pThis ) ) + if ( Esop_CubesAreEqual( pCube, pThis ) ) { - Min_CubeWrite( stdout, pCube ); + Esop_CubeWrite( stdout, pCube ); assert( 0 ); } } */ // try to find a containing cube for ( i = 0; i <= (int)pCube->nLits; i++ ) - Min_CoverForEachCube( p->ppStore[i], pThis ) + Esop_CoverForEachCube( p->ppStore[i], pThis ) { // skip the bubble - if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) + if ( pThis != p->pBubble && Esop_CubeIsContained( pThis, pCube ) ) return 1; } return 0; } +#ifdef __cplusplus +} +#endif + +#endif + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/xyz/xyzMinMan.c b/src/temp/esop/esopMan.c index 20314698..e81411f8 100644 --- a/src/opt/xyz/xyzMinMan.c +++ b/src/temp/esop/esopMan.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [xyzMinMan.c] + FileName [esopMan.c] SystemName [ABC: Logic synthesis and verification system.] @@ -14,11 +14,11 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: xyzMinMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: esopMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "xyzInt.h" +#include "esop.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -39,30 +39,31 @@ SeeAlso [] ***********************************************************************/ -Min_Man_t * Min_ManAlloc( int nVars ) +Esop_Man_t * Esop_ManAlloc( int nVars ) { - Min_Man_t * pMan; + Esop_Man_t * pMan; // start the manager - pMan = ALLOC( Min_Man_t, 1 ); - memset( pMan, 0, sizeof(Min_Man_t) ); - pMan->nVars = nVars; - pMan->nWords = Abc_BitWordNum( nVars * 2 ); - pMan->pMemMan = Extra_MmFixedStart( sizeof(Min_Cube_t) + sizeof(unsigned) * (pMan->nWords - 1) ); + pMan = ALLOC( Esop_Man_t, 1 ); + memset( pMan, 0, sizeof(Esop_Man_t) ); + pMan->nVars = nVars; + pMan->nWords = Esop_BitWordNum( nVars * 2 ); + pMan->pMemMan1 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (1 - 1) ); + pMan->pMemMan2 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (2 - 1) ); + pMan->pMemMan4 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (4 - 1) ); + pMan->pMemMan8 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (8 - 1) ); // allocate storage for the temporary cover - pMan->ppStore = ALLOC( Min_Cube_t *, pMan->nVars + 1 ); + pMan->ppStore = ALLOC( Esop_Cube_t *, pMan->nVars + 1 ); // create tautology cubes - Min_ManClean( pMan, nVars ); - pMan->pOne0 = Min_CubeAlloc( pMan ); - pMan->pOne1 = Min_CubeAlloc( pMan ); - pMan->pTemp = Min_CubeAlloc( pMan ); - pMan->pBubble = Min_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0; + Esop_ManClean( pMan, nVars ); + pMan->pOne0 = Esop_CubeAlloc( pMan ); + pMan->pOne1 = Esop_CubeAlloc( pMan ); + pMan->pTemp = Esop_CubeAlloc( pMan ); + pMan->pBubble = Esop_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0; // create trivial cubes - Min_ManClean( pMan, 1 ); - pMan->pTriv0[0] = Min_CubeAllocVar( pMan, 0, 0 ); - pMan->pTriv0[1] = Min_CubeAllocVar( pMan, 0, 1 ); - pMan->pTriv1[0] = Min_CubeAllocVar( pMan, 0, 0 ); - pMan->pTriv1[1] = Min_CubeAllocVar( pMan, 0, 1 ); - Min_ManClean( pMan, nVars ); + Esop_ManClean( pMan, 1 ); + pMan->pTriv0 = Esop_CubeAllocVar( pMan, 0, 0 ); + pMan->pTriv1 = Esop_CubeAllocVar( pMan, 0, 0 ); + Esop_ManClean( pMan, nVars ); return pMan; } @@ -77,13 +78,13 @@ Min_Man_t * Min_ManAlloc( int nVars ) SeeAlso [] ***********************************************************************/ -void Min_ManClean( Min_Man_t * p, int nSupp ) +void Esop_ManClean( Esop_Man_t * p, int nSupp ) { // set the size of the cube manager p->nVars = nSupp; - p->nWords = Abc_BitWordNum(2*nSupp); + p->nWords = Esop_BitWordNum(2*nSupp); // clean the storage - memset( p->ppStore, 0, sizeof(Min_Cube_t *) * (nSupp + 1) ); + memset( p->ppStore, 0, sizeof(Esop_Cube_t *) * (nSupp + 1) ); p->nCubes = 0; } @@ -98,9 +99,12 @@ void Min_ManClean( Min_Man_t * p, int nSupp ) SeeAlso [] ***********************************************************************/ -void Min_ManFree( Min_Man_t * p ) +void Esop_ManFree( Esop_Man_t * p ) { - Extra_MmFixedStop ( p->pMemMan, 0 ); + Esop_MmFixedStop ( p->pMemMan1, 0 ); + Esop_MmFixedStop ( p->pMemMan2, 0 ); + Esop_MmFixedStop ( p->pMemMan4, 0 ); + Esop_MmFixedStop ( p->pMemMan8, 0 ); free( p->ppStore ); free( p ); } diff --git a/src/temp/esop/esopMem.c b/src/temp/esop/esopMem.c new file mode 100644 index 00000000..9d8e7405 --- /dev/null +++ b/src/temp/esop/esopMem.c @@ -0,0 +1,274 @@ +/**CFile**************************************************************** + + FileName [esopMem.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Cover manipulation package.] + + Synopsis [Memory managers.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: esopMem.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "esop.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Esop_MmFixed_t_ +{ + // information about individual entries + int nEntrySize; // the size of one entry + int nEntriesAlloc; // the total number of entries allocated + int nEntriesUsed; // the number of entries in use + int nEntriesMax; // the max number of entries in use + char * pEntriesFree; // the linked list of free entries + + // this is where the memory is stored + int nChunkSize; // the size of one chunk + int nChunksAlloc; // the maximum number of memory chunks + int nChunks; // the current number of memory chunks + char ** pChunks; // the allocated memory + + // statistics + int nMemoryUsed; // memory used in the allocated entries + int nMemoryAlloc; // memory allocated +}; + +struct Esop_MmFlex_t_ +{ + // information about individual entries + int nEntriesUsed; // the number of entries allocated + char * pCurrent; // the current pointer to free memory + char * pEnd; // the first entry outside the free memory + + // this is where the memory is stored + int nChunkSize; // the size of one chunk + int nChunksAlloc; // the maximum number of memory chunks + int nChunks; // the current number of memory chunks + char ** pChunks; // the allocated memory + + // statistics + int nMemoryUsed; // memory used in the allocated entries + int nMemoryAlloc; // memory allocated +}; + +struct Esop_MmStep_t_ +{ + int nMems; // the number of fixed memory managers employed + Esop_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc + int nMapSize; // the size of the memory array + Esop_MmFixed_t ** pMap; // maps the number of bytes into its memory manager +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates memory pieces of fixed size.] + + Description [The size of the chunk is computed as the minimum of + 1024 entries and 64K. Can only work with entry size at least 4 byte long.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Esop_MmFixed_t * Esop_MmFixedStart( int nEntrySize ) +{ + Esop_MmFixed_t * p; + + p = ALLOC( Esop_MmFixed_t, 1 ); + memset( p, 0, sizeof(Esop_MmFixed_t) ); + + p->nEntrySize = nEntrySize; + p->nEntriesAlloc = 0; + p->nEntriesUsed = 0; + p->pEntriesFree = NULL; + + if ( nEntrySize * (1 << 10) < (1<<16) ) + p->nChunkSize = (1 << 10); + else + p->nChunkSize = (1<<16) / nEntrySize; + if ( p->nChunkSize < 8 ) + p->nChunkSize = 8; + + p->nChunksAlloc = 64; + p->nChunks = 0; + p->pChunks = ALLOC( char *, p->nChunksAlloc ); + + p->nMemoryUsed = 0; + p->nMemoryAlloc = 0; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Esop_MmFixedStop( Esop_MmFixed_t * p, int fVerbose ) +{ + int i; + if ( p == NULL ) + return; + if ( fVerbose ) + { + printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n", + p->nEntrySize, p->nChunkSize, p->nChunks ); + printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n", + p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc ); + } + for ( i = 0; i < p->nChunks; i++ ) + free( p->pChunks[i] ); + free( p->pChunks ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Esop_MmFixedEntryFetch( Esop_MmFixed_t * p ) +{ + char * pTemp; + int i; + + // check if there are still free entries + if ( p->nEntriesUsed == p->nEntriesAlloc ) + { // need to allocate more entries + assert( p->pEntriesFree == NULL ); + if ( p->nChunks == p->nChunksAlloc ) + { + p->nChunksAlloc *= 2; + p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc ); + } + p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize ); + p->nMemoryAlloc += p->nEntrySize * p->nChunkSize; + // transform these entries into a linked list + pTemp = p->pEntriesFree; + for ( i = 1; i < p->nChunkSize; i++ ) + { + *((char **)pTemp) = pTemp + p->nEntrySize; + pTemp += p->nEntrySize; + } + // set the last link + *((char **)pTemp) = NULL; + // add the chunk to the chunk storage + p->pChunks[ p->nChunks++ ] = p->pEntriesFree; + // add to the number of entries allocated + p->nEntriesAlloc += p->nChunkSize; + } + // incrememt the counter of used entries + p->nEntriesUsed++; + if ( p->nEntriesMax < p->nEntriesUsed ) + p->nEntriesMax = p->nEntriesUsed; + // return the first entry in the free entry list + pTemp = p->pEntriesFree; + p->pEntriesFree = *((char **)pTemp); + return pTemp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Esop_MmFixedEntryRecycle( Esop_MmFixed_t * p, char * pEntry ) +{ + // decrement the counter of used entries + p->nEntriesUsed--; + // add the entry to the linked list of free entries + *((char **)pEntry) = p->pEntriesFree; + p->pEntriesFree = pEntry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [Relocates all the memory except the first chunk.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Esop_MmFixedRestart( Esop_MmFixed_t * p ) +{ + int i; + char * pTemp; + + // deallocate all chunks except the first one + for ( i = 1; i < p->nChunks; i++ ) + free( p->pChunks[i] ); + p->nChunks = 1; + // transform these entries into a linked list + pTemp = p->pChunks[0]; + for ( i = 1; i < p->nChunkSize; i++ ) + { + *((char **)pTemp) = pTemp + p->nEntrySize; + pTemp += p->nEntrySize; + } + // set the last link + *((char **)pTemp) = NULL; + // set the free entry list + p->pEntriesFree = p->pChunks[0]; + // set the correct statistics + p->nMemoryAlloc = p->nEntrySize * p->nChunkSize; + p->nMemoryUsed = 0; + p->nEntriesAlloc = p->nChunkSize; + p->nEntriesUsed = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Esop_MmFixedReadMemUsage( Esop_MmFixed_t * p ) +{ + return p->nMemoryAlloc; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/opt/xyz/xyzMinEsop.c b/src/temp/esop/esopMin.c index 839e2410..7a460f8e 100644 --- a/src/opt/xyz/xyzMinEsop.c +++ b/src/temp/esop/esopMin.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [xyzMinEsop.c] + FileName [esopMin.c] SystemName [ABC: Logic synthesis and verification system.] @@ -14,17 +14,17 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: xyzMinEsop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: esopMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "xyzInt.h" +#include "esop.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static void Min_EsopRewrite( Min_Man_t * p ); +static void Esop_EsopRewrite( Esop_Man_t * p ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -32,7 +32,7 @@ static void Min_EsopRewrite( Min_Man_t * p ); /**Function************************************************************* - Synopsis [] + Synopsis [ESOP minimization procedure.] Description [] @@ -41,7 +41,7 @@ static void Min_EsopRewrite( Min_Man_t * p ); SeeAlso [] ***********************************************************************/ -void Min_EsopMinimize( Min_Man_t * p ) +void Esop_EsopMinimize( Esop_Man_t * p ) { int nCubesInit, nCubesOld, nIter; if ( p->nCubes < 3 ) @@ -50,7 +50,7 @@ void Min_EsopMinimize( Min_Man_t * p ) nCubesInit = p->nCubes; do { nCubesOld = p->nCubes; - Min_EsopRewrite( p ); + Esop_EsopRewrite( p ); nIter++; } while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); @@ -73,10 +73,10 @@ void Min_EsopMinimize( Min_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Min_EsopRewrite( Min_Man_t * p ) +void Esop_EsopRewrite( Esop_Man_t * p ) { - Min_Cube_t * pCube, ** ppPrev; - Min_Cube_t * pThis, ** ppPrevT; + Esop_Cube_t * pCube, ** ppPrev; + Esop_Cube_t * pThis, ** ppPrevT; int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld; int nPairs = 0; @@ -92,7 +92,7 @@ void Min_EsopRewrite( Min_Man_t * p ) Index = p->pBubble->nLits; // find the bubble - Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) + Esop_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) if ( pCube == p->pBubble ) break; assert( pCube == p->pBubble ); @@ -113,16 +113,16 @@ void Min_EsopRewrite( Min_Man_t * p ) break; // find the first dist2 cube - Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) + Esop_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) + if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) break; if ( pThis == NULL && Index < p->nVars ) - Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) + Esop_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) + if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) break; if ( pThis == NULL && Index < p->nVars - 1 ) - Min_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) + Esop_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT ) + if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) break; // continue if there is no dist2 cube if ( pThis == NULL ) @@ -148,26 +148,26 @@ void Min_EsopRewrite( Min_Man_t * p ) // A{v00} B{v01+v11} + A{v00+v10} B{v11} // save the dist2 parameters - v00 = Min_CubeGetVar( pCube, Var0 ); - v01 = Min_CubeGetVar( pCube, Var1 ); - v10 = Min_CubeGetVar( pThis, Var0 ); - v11 = Min_CubeGetVar( pThis, Var1 ); + v00 = Esop_CubeGetVar( pCube, Var0 ); + v01 = Esop_CubeGetVar( pCube, Var1 ); + v10 = Esop_CubeGetVar( pThis, Var0 ); + v11 = Esop_CubeGetVar( pThis, Var1 ); //printf( "\n" ); -//Min_CubeWrite( stdout, pCube ); -//Min_CubeWrite( stdout, pThis ); +//Esop_CubeWrite( stdout, pCube ); +//Esop_CubeWrite( stdout, pThis ); // derive the first pair of resulting cubes - Min_CubeXorVar( pCube, Var0, v10 ); + Esop_CubeXorVar( pCube, Var0, v10 ); pCube->nLits -= (v00 != 3); pCube->nLits += ((v00 ^ v10) != 3); - Min_CubeXorVar( pThis, Var1, v01 ); + Esop_CubeXorVar( pThis, Var1, v01 ); pThis->nLits -= (v11 != 3); pThis->nLits += ((v01 ^ v11) != 3); // add the cubes nCubesOld = p->nCubes; - Min_EsopAddCube( p, pCube ); - Min_EsopAddCube( p, pThis ); + Esop_EsopAddCube( p, pCube ); + Esop_EsopAddCube( p, pThis ); // check if the cubes were absorbed if ( p->nCubes < nCubesOld + 2 ) continue; @@ -180,23 +180,23 @@ void Min_EsopRewrite( Min_Man_t * p ) p->nCubes -= 2; // derive the second pair of resulting cubes - Min_CubeXorVar( pCube, Var0, v10 ); + Esop_CubeXorVar( pCube, Var0, v10 ); pCube->nLits -= ((v00 ^ v10) != 3); pCube->nLits += (v00 != 3); - Min_CubeXorVar( pCube, Var1, v11 ); + Esop_CubeXorVar( pCube, Var1, v11 ); pCube->nLits -= (v01 != 3); pCube->nLits += ((v01 ^ v11) != 3); - Min_CubeXorVar( pThis, Var0, v00 ); + Esop_CubeXorVar( pThis, Var0, v00 ); pThis->nLits -= (v10 != 3); pThis->nLits += ((v00 ^ v10) != 3); - Min_CubeXorVar( pThis, Var1, v01 ); + Esop_CubeXorVar( pThis, Var1, v01 ); pThis->nLits -= ((v01 ^ v11) != 3); pThis->nLits += (v11 != 3); // add them anyhow - Min_EsopAddCube( p, pCube ); - Min_EsopAddCube( p, pThis ); + Esop_EsopAddCube( p, pCube ); + Esop_EsopAddCube( p, pThis ); } // printf( "Pairs = %d ", nPairs ); } @@ -214,55 +214,55 @@ void Min_EsopRewrite( Min_Man_t * p ) SeeAlso [] ***********************************************************************/ -int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) +int Esop_EsopAddCubeInt( Esop_Man_t * p, Esop_Cube_t * pCube ) { - Min_Cube_t * pThis, ** ppPrev; + Esop_Cube_t * pThis, ** ppPrev; // try to find the identical cube - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) + Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) { - if ( Min_CubesAreEqual( pCube, pThis ) ) + if ( Esop_CubesAreEqual( pCube, pThis ) ) { *ppPrev = pThis->pNext; - Min_CubeRecycle( p, pCube ); - Min_CubeRecycle( p, pThis ); + Esop_CubeRecycle( p, pCube ); + Esop_CubeRecycle( p, pThis ); p->nCubes--; return 0; } } // find a distance-1 cube if it exists if ( pCube->nLits < pCube->nVars ) - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev ) + Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev ) { - if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) + if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) ) { *ppPrev = pThis->pNext; - Min_CubesTransform( pCube, pThis, p->pTemp ); + Esop_CubesTransform( pCube, pThis, p->pTemp ); pCube->nLits++; - Min_CubeRecycle( p, pThis ); + Esop_CubeRecycle( p, pThis ); p->nCubes--; return 1; } } - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) + Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) { - if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) + if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) ) { *ppPrev = pThis->pNext; - Min_CubesTransform( pCube, pThis, p->pTemp ); + Esop_CubesTransform( pCube, pThis, p->pTemp ); pCube->nLits--; - Min_CubeRecycle( p, pThis ); + Esop_CubeRecycle( p, pThis ); p->nCubes--; return 1; } } if ( pCube->nLits > 0 ) - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev ) + Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev ) { - if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) + if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) ) { *ppPrev = pThis->pNext; - Min_CubesTransform( pCube, pThis, p->pTemp ); - Min_CubeRecycle( p, pThis ); + Esop_CubesTransform( pCube, pThis, p->pTemp ); + Esop_CubeRecycle( p, pThis ); p->nCubes--; return 1; } @@ -285,11 +285,11 @@ int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) SeeAlso [] ***********************************************************************/ -void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) +void Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube ) { assert( pCube != p->pBubble ); - assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); - while ( Min_EsopAddCubeInt( p, pCube ) ); + assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) ); + while ( Esop_EsopAddCubeInt( p, pCube ) ); } //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/xyz/xyzMinUtil.c b/src/temp/esop/esopUtil.c index 9ec5f83f..dec6eae2 100644 --- a/src/opt/xyz/xyzMinUtil.c +++ b/src/temp/esop/esopUtil.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [xyzMinUtil.c] + FileName [esopUtil.c] SystemName [ABC: Logic synthesis and verification system.] @@ -14,11 +14,11 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: xyzMinUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: esopUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "xyzInt.h" +#include "esop.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -39,21 +39,21 @@ SeeAlso [] ***********************************************************************/ -void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ) +void Esop_CubeWrite( FILE * pFile, Esop_Cube_t * pCube ) { int i; - assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); + assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) ); for ( i = 0; i < (int)pCube->nVars; i++ ) - if ( Min_CubeHasBit(pCube, i*2) ) + if ( Esop_CubeHasBit(pCube, i*2) ) { - if ( Min_CubeHasBit(pCube, i*2+1) ) + if ( Esop_CubeHasBit(pCube, i*2+1) ) fprintf( pFile, "-" ); else fprintf( pFile, "0" ); } else { - if ( Min_CubeHasBit(pCube, i*2+1) ) + if ( Esop_CubeHasBit(pCube, i*2+1) ) fprintf( pFile, "1" ); else fprintf( pFile, "?" ); @@ -73,11 +73,11 @@ void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ) SeeAlso [] ***********************************************************************/ -void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ) +void Esop_CoverWrite( FILE * pFile, Esop_Cube_t * pCover ) { - Min_Cube_t * pCube; - Min_CoverForEachCube( pCover, pCube ) - Min_CubeWrite( pFile, pCube ); + Esop_Cube_t * pCube; + Esop_CoverForEachCube( pCover, pCube ) + Esop_CubeWrite( pFile, pCube ); printf( "\n" ); } @@ -92,13 +92,13 @@ void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ) SeeAlso [] ***********************************************************************/ -void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ) +void Esop_CoverWriteStore( FILE * pFile, Esop_Man_t * p ) { - Min_Cube_t * pCube; + Esop_Cube_t * pCube; int i; for ( i = 0; i <= p->nVars; i++ ) { - Min_CoverForEachCube( p->ppStore[i], pCube ) + Esop_CoverForEachCube( p->ppStore[i], pCube ) { printf( "%2d : ", i ); if ( pCube == p->pBubble ) @@ -106,7 +106,7 @@ void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ) printf( "Bubble\n" ); continue; } - Min_CubeWrite( pFile, pCube ); + Esop_CubeWrite( pFile, pCube ); } } printf( "\n" ); @@ -123,10 +123,10 @@ void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ) +void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop ) { char Buffer[1000]; - Min_Cube_t * pCube; + Esop_Cube_t * pCube; FILE * pFile; int i; sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" ); @@ -137,10 +137,10 @@ void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ) fprintf( pFile, "# %s cover for output %s generated by ABC on %s\n", fEsop? "ESOP":"SOP", pName, Extra_TimeStamp() ); fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 ); fprintf( pFile, ".o %d\n", 1 ); - fprintf( pFile, ".p %d\n", Min_CoverCountCubes(pCover) ); + fprintf( pFile, ".p %d\n", Esop_CoverCountCubes(pCover) ); if ( fEsop ) fprintf( pFile, ".type esop\n" ); - Min_CoverForEachCube( pCover, pCube ) - Min_CubeWrite( pFile, pCube ); + Esop_CoverForEachCube( pCover, pCube ) + Esop_CubeWrite( pFile, pCube ); fprintf( pFile, ".e\n" ); fclose( pFile ); } @@ -156,12 +156,12 @@ void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ) SeeAlso [] ***********************************************************************/ -void Min_CoverCheck( Min_Man_t * p ) +void Esop_CoverCheck( Esop_Man_t * p ) { - Min_Cube_t * pCube; + Esop_Cube_t * pCube; int i; for ( i = 0; i <= p->nVars; i++ ) - Min_CoverForEachCube( p->ppStore[i], pCube ) + Esop_CoverForEachCube( p->ppStore[i], pCube ) assert( i == (int)pCube->nLits ); } @@ -177,11 +177,11 @@ void Min_CoverCheck( Min_Man_t * p ) SeeAlso [] ***********************************************************************/ -int Min_CubeCheck( Min_Cube_t * pCube ) +int Esop_CubeCheck( Esop_Cube_t * pCube ) { int i; for ( i = 0; i < (int)pCube->nVars; i++ ) - if ( Min_CubeGetVar( pCube, i ) == 0 ) + if ( Esop_CubeGetVar( pCube, i ) == 0 ) return 0; return 1; } @@ -197,14 +197,14 @@ int Min_CubeCheck( Min_Cube_t * pCube ) SeeAlso [] ***********************************************************************/ -Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ) +Esop_Cube_t * Esop_CoverCollect( Esop_Man_t * p, int nSuppSize ) { - Min_Cube_t * pCov = NULL, ** ppTail = &pCov; - Min_Cube_t * pCube, * pCube2; + Esop_Cube_t * pCov = NULL, ** ppTail = &pCov; + Esop_Cube_t * pCube, * pCube2; int i; for ( i = 0; i <= nSuppSize; i++ ) { - Min_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 ) + Esop_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 ) { assert( i == (int)pCube->nLits ); *ppTail = pCube; @@ -227,11 +227,11 @@ Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ) SeeAlso [] ***********************************************************************/ -void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ) +void Esop_CoverExpand( Esop_Man_t * p, Esop_Cube_t * pCover ) { - Min_Cube_t * pCube, * pCube2; - Min_ManClean( p, p->nVars ); - Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + Esop_Cube_t * pCube, * pCube2; + Esop_ManClean( p, p->nVars ); + Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) { pCube->pNext = p->ppStore[pCube->nLits]; p->ppStore[pCube->nLits] = pCube; @@ -250,9 +250,9 @@ void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ) SeeAlso [] ***********************************************************************/ -int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ) +int Esop_CoverSuppVarNum( Esop_Man_t * p, Esop_Cube_t * pCover ) { - Min_Cube_t * pCube; + Esop_Cube_t * pCube; int i, Counter; if ( pCover == NULL ) return 0; @@ -260,13 +260,13 @@ int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ) for ( i = 0; i < (int)pCover->nWords; i++ ) p->pTemp->uData[i] = ~((unsigned)0); // add the bit data - Min_CoverForEachCube( pCover, pCube ) + Esop_CoverForEachCube( pCover, pCube ) for ( i = 0; i < (int)pCover->nWords; i++ ) p->pTemp->uData[i] &= pCube->uData[i]; // count the vars Counter = 0; for ( i = 0; i < (int)pCover->nVars; i++ ) - Counter += ( Min_CubeGetVar(p->pTemp, i) != 3 ); + Counter += ( Esop_CubeGetVar(p->pTemp, i) != 3 ); return Counter; } diff --git a/src/temp/esop/module.make b/src/temp/esop/module.make new file mode 100644 index 00000000..cab5e737 --- /dev/null +++ b/src/temp/esop/module.make @@ -0,0 +1,4 @@ +SRC += src/temp/esop/esopMan.c \ + src/temp/esop/esopMem.c \ + src/temp/esop/esopMin.c \ + src/temp/esop/esopUtil.c diff --git a/src/temp/ivy/ivy.h b/src/temp/ivy/ivy.h new file mode 100644 index 00000000..55ada384 --- /dev/null +++ b/src/temp/ivy/ivy.h @@ -0,0 +1,450 @@ +/**CFile**************************************************************** + + FileName [ivy.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivy.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __IVY_H__ +#define __IVY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "vec.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Ivy_Man_t_ Ivy_Man_t; +typedef struct Ivy_Obj_t_ Ivy_Obj_t; + +// object types +typedef enum { + IVY_NONE, // 0: unused node + IVY_PI, // 1: primary input (and constant 1 node) + IVY_PO, // 2: primary output + IVY_ASSERT, // 3: assertion + IVY_LATCH, // 4: sequential element + IVY_AND, // 5: internal AND node + IVY_EXOR, // 6: internal EXOR node + IVY_BUF, // 7: internal buffer (temporary) + IVY_ANDM, // 8: multi-input AND (logic network only) + IVY_EXORM, // 9: multi-input EXOR (logic network only) + IVY_LUT // 10: multi-input LUT (logic network only) +} Ivy_Type_t; + +// latch initial values +typedef enum { + IVY_INIT_NONE, // 0: not a latch + IVY_INIT_0, // 1: zero + IVY_INIT_1, // 2: one + IVY_INIT_DC // 3: don't-care +} Ivy_Init_t; + +// the AIG node +struct Ivy_Obj_t_ // 6 words +{ + int Id; // integer ID + int TravId; // traversal ID + int Fanin0; // fanin ID + int Fanin1; // fanin ID + int nRefs; // reference counter + unsigned Type : 4; // object type + unsigned fPhase : 1; // value under 000...0 pattern + unsigned fMarkA : 1; // multipurpose mask + unsigned fMarkB : 1; // multipurpose mask + unsigned fExFan : 1; // set to 1 if last fanout added is EXOR + unsigned fComp0 : 1; // complemented attribute + unsigned fComp1 : 1; // complemented attribute + unsigned Init : 2; // latch initial value + unsigned LevelR : 8; // reverse logic level + unsigned Level : 12; // logic level +}; + +// the AIG manager +struct Ivy_Man_t_ +{ + // AIG nodes + int nObjs[12]; // the number of objects by type + int nCreated; // the number of created objects + int nDeleted; // the number of deleted objects + int ObjIdNext; // the next free obj ID to assign + int nObjsAlloc; // the allocated number of nodes + Ivy_Obj_t * pObjs; // the array of all nodes + Vec_Int_t * vPis; // the array of PIs + Vec_Int_t * vPos; // the array of POs + // stuctural hash table + int * pTable; // structural hash table + int nTableSize; // structural hash table size + // various data members + int fExtended; // set to 1 in extended mode + int nTravIds; // the traversal ID + int nLevelMax; // the maximum level + void * pData; // the temporary data + // truth table of the 8-LUTs + unsigned * pMemory; // memory for truth tables + Vec_Int_t * vTruths; // offset for truth table of each node + // storage for the undo operation + Vec_Int_t * vFree; // storage for all deleted entries + Ivy_Obj_t * pUndos; // description of recently deleted nodes + int nUndos; // the number of recently deleted nodes + int nUndosAlloc; // the number of allocated cells + int fRecording; // shows that recording goes on +}; + + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define IVY_SANDBOX_SIZE 1 + +#define IVY_MIN(a,b) (((a) < (b))? (a) : (b)) +#define IVY_MAX(a,b) (((a) > (b))? (a) : (b)) + +static inline int Ivy_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } +static inline int Ivy_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } +static inline int Ivy_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } +static inline void Ivy_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } +static inline void Ivy_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } + +static inline int Ivy_FanCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; } +static inline int Ivy_FanId( int Fan ) { return Fan >> 1; } +static inline int Ivy_FanCompl( int Fan ) { return Fan & 1; } + +static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << 4) | Lat; } +static inline int Ivy_LeafId( int Leaf ) { return Leaf >> 4; } +static inline int Ivy_LeafLat( int Leaf ) { return Leaf & 15; } + +static inline Ivy_Obj_t * Ivy_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) & ~01); } +static inline Ivy_Obj_t * Ivy_Not( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) ^ 01); } +static inline Ivy_Obj_t * Ivy_NotCond( Ivy_Obj_t * p, int c ) { return (Ivy_Obj_t *)((unsigned)(p) ^ (c)); } +static inline int Ivy_IsComplement( Ivy_Obj_t * p ) { return (int )(((unsigned)p) & 01); } + +static inline Ivy_Obj_t * Ivy_ManConst0( Ivy_Man_t * p ) { return Ivy_Not(p->pObjs); } +static inline Ivy_Obj_t * Ivy_ManConst1( Ivy_Man_t * p ) { return p->pObjs; } +static inline Ivy_Obj_t * Ivy_ManGhost( Ivy_Man_t * p ) { return p->pObjs - IVY_SANDBOX_SIZE; } +static inline Ivy_Obj_t * Ivy_ManPi( Ivy_Man_t * p, int i ) { return p->pObjs + Vec_IntEntry(p->vPis,i); } +static inline Ivy_Obj_t * Ivy_ManPo( Ivy_Man_t * p, int i ) { return p->pObjs + Vec_IntEntry(p->vPos,i); } +static inline Ivy_Obj_t * Ivy_ManObj( Ivy_Man_t * p, int i ) { return p->pObjs + i; } + +static inline int Ivy_ManPiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PI]; } +static inline int Ivy_ManPoNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PO]; } +static inline int Ivy_ManAssertNum( Ivy_Man_t * p ) { return p->nObjs[IVY_ASSERT]; } +static inline int Ivy_ManLatchNum( Ivy_Man_t * p ) { return p->nObjs[IVY_LATCH]; } +static inline int Ivy_ManAndNum( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]; } +static inline int Ivy_ManExorNum( Ivy_Man_t * p ) { return p->nObjs[IVY_EXOR]; } +static inline int Ivy_ManBufNum( Ivy_Man_t * p ) { return p->nObjs[IVY_BUF]; } +static inline int Ivy_ManAndMultiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_ANDM]; } +static inline int Ivy_ManExorMultiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_EXORM]; } +static inline int Ivy_ManLutNum( Ivy_Man_t * p ) { return p->nObjs[IVY_LUT]; } +static inline int Ivy_ManObjNum( Ivy_Man_t * p ) { return p->nCreated - p->nDeleted; } +static inline int Ivy_ManObjIdNext( Ivy_Man_t * p ) { return p->ObjIdNext; } +static inline int Ivy_ManObjAllocNum( Ivy_Man_t * p ) { return p->nObjsAlloc; } +static inline int Ivy_ManNodeNum( Ivy_Man_t * p ) { return p->fExtended? p->nObjs[IVY_ANDM]+p->nObjs[IVY_EXORM]+p->nObjs[IVY_LUT] : p->nObjs[IVY_AND]+p->nObjs[IVY_EXOR]; } +static inline int Ivy_ManHashObjNum( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+p->nObjs[IVY_EXOR]+p->nObjs[IVY_LATCH]; } +static inline int Ivy_ManGetCost( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+3*p->nObjs[IVY_EXOR]+8*p->nObjs[IVY_LATCH]; } + +static inline Ivy_Type_t Ivy_ObjType( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type; } +static inline Ivy_Init_t Ivy_ObjInit( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Init; } +static inline int Ivy_ObjIsConst1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id == 0; } +static inline int Ivy_ObjIsGhost( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id < 0; } +static inline int Ivy_ObjIsNone( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_NONE; } +static inline int Ivy_ObjIsPi( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI; } +static inline int Ivy_ObjIsPo( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO; } +static inline int Ivy_ObjIsCi( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_LATCH; } +static inline int Ivy_ObjIsCo( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_LATCH; } +static inline int Ivy_ObjIsAssert( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_ASSERT; } +static inline int Ivy_ObjIsLatch( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_LATCH; } +static inline int Ivy_ObjIsAnd( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND; } +static inline int Ivy_ObjIsExor( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXOR; } +static inline int Ivy_ObjIsBuf( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_BUF; } +static inline int Ivy_ObjIsNode( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR; } +static inline int Ivy_ObjIsTerm( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; } +static inline int Ivy_ObjIsHash( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR || pObj->Type == IVY_LATCH; } +static inline int Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; } + +static inline int Ivy_ObjIsAndMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_ANDM; } +static inline int Ivy_ObjIsExorMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXORM; } +static inline int Ivy_ObjIsLut( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_LUT; } +static inline int Ivy_ObjIsNodeExt( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type >= IVY_ANDM; } + +static inline int Ivy_ObjIsMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fMarkA; } +static inline void Ivy_ObjSetMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->fMarkA = 1; } +static inline void Ivy_ObjClearMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->fMarkA = 0; } + +static inline Ivy_Man_t * Ivy_ObjMan( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return *((Ivy_Man_t **)(pObj - pObj->Id - IVY_SANDBOX_SIZE - 1)); } +static inline Ivy_Obj_t * Ivy_ObjConst0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_Not(pObj - pObj->Id); } +static inline Ivy_Obj_t * Ivy_ObjConst1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id; } +static inline Ivy_Obj_t * Ivy_ObjGhost( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id - IVY_SANDBOX_SIZE; } +static inline Ivy_Obj_t * Ivy_ObjObj( Ivy_Obj_t * pObj, int n ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id + n; } +static inline Ivy_Obj_t * Ivy_ObjNext( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id + pObj->TravId; } + +static inline void Ivy_ObjSetTravId( Ivy_Obj_t * pObj, int TravId ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = TravId; } +static inline void Ivy_ObjSetTravIdCurrent( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = Ivy_ObjMan(pObj)->nTravIds; } +static inline void Ivy_ObjSetTravIdPrevious( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = Ivy_ObjMan(pObj)->nTravIds - 1; } +static inline int Ivy_ObjIsTravIdCurrent( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return (int )((int)pObj->TravId == Ivy_ObjMan(pObj)->nTravIds); } +static inline int Ivy_ObjIsTravIdPrevious( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return (int )((int)pObj->TravId == Ivy_ObjMan(pObj)->nTravIds - 1); } + +static inline int Ivy_ObjId( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id; } +static inline int Ivy_ObjPhase( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fPhase; } +static inline int Ivy_ObjExorFanout( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fExFan; } +static inline int Ivy_ObjRefs( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->nRefs; } +static inline void Ivy_ObjRefsInc( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->nRefs++; } +static inline void Ivy_ObjRefsDec( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); assert( pObj->nRefs > 0 ); pObj->nRefs--; } +static inline int Ivy_ObjFaninId0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Fanin0; } +static inline int Ivy_ObjFaninId1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Fanin1; } +static inline int Ivy_ObjFaninC0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fComp0; } +static inline int Ivy_ObjFaninC1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fComp1; } +static inline Ivy_Obj_t * Ivy_ObjFanin0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjObj(pObj, pObj->Fanin0); } +static inline Ivy_Obj_t * Ivy_ObjFanin1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjObj(pObj, pObj->Fanin1); } +static inline Ivy_Obj_t * Ivy_ObjChild0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_NotCond( Ivy_ObjFanin0(pObj), Ivy_ObjFaninC0(pObj) ); } +static inline Ivy_Obj_t * Ivy_ObjChild1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_NotCond( Ivy_ObjFanin1(pObj), Ivy_ObjFaninC1(pObj) ); } +static inline int Ivy_ObjLevelR( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->LevelR; } +static inline int Ivy_ObjLevel( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Level; } +static inline int Ivy_ObjLevelNew( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return 1 + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level); } +static inline void Ivy_ObjClean( Ivy_Obj_t * pObj ) { + int IdSaved = pObj->Id; + if ( IdSaved == 54 ) + { + int x = 0; + } + memset( pObj, 0, sizeof(Ivy_Obj_t) ); + pObj->Id = IdSaved; +} +static inline void Ivy_ObjOverwrite( Ivy_Obj_t * pBase, Ivy_Obj_t * pData ) { int IdSaved = pBase->Id; memcpy( pBase, pData, sizeof(Ivy_Obj_t) ); pBase->Id = IdSaved; } +static inline int Ivy_ObjWhatFanin( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin ) +{ + if ( Ivy_ObjFaninId0(pObj) == Ivy_ObjId(pFanin) ) return 0; + if ( Ivy_ObjFaninId1(pObj) == Ivy_ObjId(pFanin) ) return 1; + assert(0); return -1; +} +static inline int Ivy_ObjFanoutC( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) +{ + if ( Ivy_ObjFaninId0(pFanout) == Ivy_ObjId(pObj) ) return Ivy_ObjFaninC0(pObj); + if ( Ivy_ObjFaninId1(pFanout) == Ivy_ObjId(pObj) ) return Ivy_ObjFaninC1(pObj); + assert(0); return -1; +} + +// create the ghost of the new node +static inline Ivy_Obj_t * Ivy_ObjCreateGhost( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type, Ivy_Init_t Init ) +{ + Ivy_Obj_t * pGhost; + int Temp; + pGhost = Ivy_ObjGhost(Ivy_Regular(p0)); + pGhost->Type = Type; + pGhost->Init = Init; + pGhost->fComp0 = Ivy_IsComplement(p0); + pGhost->fComp1 = Ivy_IsComplement(p1); + pGhost->Fanin0 = Ivy_ObjId(Ivy_Regular(p0)); + pGhost->Fanin1 = Ivy_ObjId(Ivy_Regular(p1)); + if ( pGhost->Fanin0 < pGhost->Fanin1 ) + { + Temp = pGhost->Fanin0, pGhost->Fanin0 = pGhost->Fanin1, pGhost->Fanin1 = Temp; + Temp = pGhost->fComp0, pGhost->fComp0 = pGhost->fComp1, pGhost->fComp1 = Temp; + } + assert( Ivy_ObjIsOneFanin(pGhost) || pGhost->Fanin0 > pGhost->Fanin1 ); + return pGhost; +} + +// create the ghost of the new node +static inline Ivy_Obj_t * Ivy_ObjCreateGhost2( Ivy_Man_t * p, Ivy_Obj_t * pObjDead ) +{ + Ivy_Obj_t * pGhost; + pGhost = Ivy_ManGhost(p); + pGhost->Type = pObjDead->Type; + pGhost->Init = pObjDead->Init; + pGhost->fComp0 = pObjDead->fComp0; + pGhost->fComp1 = pObjDead->fComp1; + pGhost->Fanin0 = pObjDead->Fanin0; + pGhost->Fanin1 = pObjDead->Fanin1; + assert( Ivy_ObjIsOneFanin(pGhost) || pGhost->Fanin0 > pGhost->Fanin1 ); + return pGhost; +} + +// get the complemented initial state +static Ivy_Init_t Ivy_InitNotCond( Ivy_Init_t Init, int fCompl ) +{ + assert( Init != IVY_INIT_NONE ); + if ( fCompl == 0 ) + return Init; + if ( Init == IVY_INIT_0 ) + return IVY_INIT_1; + if ( Init == IVY_INIT_1 ) + return IVY_INIT_0; + return IVY_INIT_DC; +} + +// get the initial state after forward retiming over AND gate +static Ivy_Init_t Ivy_InitAnd( Ivy_Init_t InitA, Ivy_Init_t InitB ) +{ + assert( InitA != IVY_INIT_NONE && InitB != IVY_INIT_NONE ); + if ( InitA == IVY_INIT_0 || InitB == IVY_INIT_0 ) + return IVY_INIT_0; + if ( InitA == IVY_INIT_DC || InitB == IVY_INIT_DC ) + return IVY_INIT_DC; + return IVY_INIT_1; +} + +// get the initial state after forward retiming over EXOR gate +static Ivy_Init_t Ivy_InitExor( Ivy_Init_t InitA, Ivy_Init_t InitB ) +{ + assert( InitA != IVY_INIT_NONE && InitB != IVY_INIT_NONE ); + if ( InitA == IVY_INIT_DC || InitB == IVY_INIT_DC ) + return IVY_INIT_DC; + if ( InitA == IVY_INIT_0 && InitB == IVY_INIT_1 ) + return IVY_INIT_1; + if ( InitA == IVY_INIT_1 && InitB == IVY_INIT_0 ) + return IVY_INIT_1; + return IVY_INIT_0; +} + +// extended fanins +static inline Vec_Int_t * Ivy_ObjGetFanins( Ivy_Obj_t * pObj ) { assert(Ivy_ObjMan(pObj)->fExtended); return (Vec_Int_t *)*(((int*)pObj)+2); } +static inline void Ivy_ObjSetFanins( Ivy_Obj_t * pObj, Vec_Int_t * vFanins ) { assert(Ivy_ObjMan(pObj)->fExtended); assert(Ivy_ObjGetFanins(pObj)==NULL); *(Vec_Int_t **)(((int*)pObj)+2) = vFanins; } +static inline void Ivy_ObjStartFanins( Ivy_Obj_t * pObj, int nFanins ) { assert(Ivy_ObjMan(pObj)->fExtended); Ivy_ObjSetFanins( pObj, Vec_IntAlloc(nFanins) ); } +static inline void Ivy_ObjAddFanin( Ivy_Obj_t * pObj, int Fanin ) { assert(Ivy_ObjMan(pObj)->fExtended); Vec_IntPush( Ivy_ObjGetFanins(pObj), Fanin ); } +static inline int Ivy_ObjReadFanin( Ivy_Obj_t * pObj, int i ) { assert(Ivy_ObjMan(pObj)->fExtended); return Vec_IntEntry( Ivy_ObjGetFanins(pObj), i ); } +static inline int Ivy_ObjFaninNum( Ivy_Obj_t * pObj ) { assert(Ivy_ObjMan(pObj)->fExtended); return Vec_IntSize( Ivy_ObjGetFanins(pObj) ); } + +//////////////////////////////////////////////////////////////////////// +/// ITERATORS /// +//////////////////////////////////////////////////////////////////////// + +// iterator over all objects, including those currently not used +#define Ivy_ManForEachObj( p, pObj, i ) \ + for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ ) +// iterator over the primary inputs +#define Ivy_ManForEachPi( p, pObj, i ) \ + for ( i = 0; i < Vec_IntSize(p->vPis) && ((pObj) = Ivy_ManPi(p, i)); i++ ) +// iterator over the primary outputs +#define Ivy_ManForEachPo( p, pObj, i ) \ + for ( i = 0; i < Vec_IntSize(p->vPos) && ((pObj) = Ivy_ManPo(p, i)); i++ ) +// iterator over the combinational inputs +#define Ivy_ManForEachCi( p, pObj, i ) \ + for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ ) \ + if ( !Ivy_ObjIsCi(pObj) ) {} else +// iterator over the combinational outputs +#define Ivy_ManForEachCo( p, pObj, i ) \ + for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ ) \ + if ( !Ivy_ObjIsCo(pObj) ) {} else +// iterator over logic nodes (AND and EXOR gates) +#define Ivy_ManForEachNode( p, pObj, i ) \ + for ( i = 1, pObj = p->pObjs+i; i < p->ObjIdNext; i++, pObj++ ) \ + if ( !Ivy_ObjIsNode(pObj) ) {} else +// iterator over logic latches +#define Ivy_ManForEachLatch( p, pObj, i ) \ + for ( i = 1, pObj = p->pObjs+i; i < p->ObjIdNext; i++, pObj++ ) \ + if ( !Ivy_ObjIsLatch(pObj) ) {} else +// iterator over the nodes whose IDs are stored in the array +#define Ivy_ManForEachNodeVec( p, vIds, pObj, i ) \ + for ( i = 0; i < Vec_IntSize(vIds) && ((pObj) = Ivy_ManObj(p, Vec_IntEntry(vIds,i))); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== ivyCanon.c ========================================================*/ +extern Ivy_Obj_t * Ivy_CanonAnd( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); +extern Ivy_Obj_t * Ivy_CanonExor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); +extern Ivy_Obj_t * Ivy_CanonLatch( Ivy_Obj_t * pObj, Ivy_Init_t Init ); +/*=== ivyCheck.c ========================================================*/ +extern int Ivy_ManCheck( Ivy_Man_t * p ); +/*=== ivyCut.c ==========================================================*/ +extern void Ivy_ManSeqFindCut( Ivy_Obj_t * pNode, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize ); +/*=== ivyBalance.c ======================================================*/ +extern int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel ); +/*=== ivyDfs.c ==========================================================*/ +extern Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p ); +extern Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p ); +/*=== ivyDsd.c ==========================================================*/ +extern int Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree ); +extern void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree ); +extern unsigned Ivy_TruthDsdCompute( Vec_Int_t * vTree ); +extern void Ivy_TruthDsdComputePrint( unsigned uTruth ); +extern Ivy_Obj_t * Ivy_ManDsdConstruct( Ivy_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vTree ); +/*=== ivyMan.c ==========================================================*/ +extern Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax ); +extern void Ivy_ManStop( Ivy_Man_t * p ); +extern void Ivy_ManGrow( Ivy_Man_t * p ); +extern int Ivy_ManCleanup( Ivy_Man_t * p ); +extern void Ivy_ManPrintStats( Ivy_Man_t * p ); +/*=== ivyMulti.c ==========================================================*/ +extern Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); +extern Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); +extern Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type ); +extern Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); +/*=== ivyObj.c ==========================================================*/ +extern Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost ); +extern Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type ); +extern void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin ); +extern void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop ); +extern void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop ); +extern void Ivy_ObjReplace( Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop ); +extern void Ivy_NodeFixBufferFanins( Ivy_Obj_t * pNode ); +/*=== ivyOper.c =========================================================*/ +extern Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type ); +extern Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); +extern Ivy_Obj_t * Ivy_Or( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); +extern Ivy_Obj_t * Ivy_Exor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); +extern Ivy_Obj_t * Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 ); +extern Ivy_Obj_t * Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC ); +extern Ivy_Obj_t * Ivy_Miter( Vec_Ptr_t * vPairs ); +/*=== ivyRewrite.c =========================================================*/ +extern int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ); +/*=== ivyTable.c ========================================================*/ +extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Obj_t * pObj ); +extern void Ivy_TableInsert( Ivy_Obj_t * pObj ); +extern void Ivy_TableDelete( Ivy_Obj_t * pObj ); +extern void Ivy_TableUpdate( Ivy_Obj_t * pObj, int ObjIdNew ); +extern int Ivy_TableCountEntries( Ivy_Man_t * p ); +extern void Ivy_TableResize( Ivy_Man_t * p ); +/*=== ivyUndo.c =========================================================*/ +extern void Ivy_ManUndoStart( Ivy_Man_t * p ); +extern void Ivy_ManUndoStop( Ivy_Man_t * p ); +extern void Ivy_ManUndoRecord( Ivy_Man_t * p, Ivy_Obj_t * pObj ); +extern void Ivy_ManUndoPerform( Ivy_Man_t * p, Ivy_Obj_t * pRoot ); +/*=== ivyUtil.c =========================================================*/ +extern void Ivy_ManIncrementTravId( Ivy_Man_t * p ); +extern void Ivy_ManCleanTravId( Ivy_Man_t * p ); +extern int Ivy_ObjIsMuxType( Ivy_Obj_t * pObj ); +extern Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pObj, Ivy_Obj_t ** ppObjT, Ivy_Obj_t ** ppObjE ); +extern unsigned * Ivy_ManCutTruth( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth ); +extern Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin ); +extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/ivy/ivyBalance.c b/src/temp/ivy/ivyBalance.c new file mode 100644 index 00000000..bbe69dd9 --- /dev/null +++ b/src/temp/ivy/ivyBalance.c @@ -0,0 +1,421 @@ +/**CFile**************************************************************** + + FileName [ivyBalance.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Algebraic AIG balancing.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Ivy_NodeBalance( Ivy_Obj_t * pNode, int fUpdateLevel, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots ); + +// this procedure returns 1 if the node cannot be expanded +static inline int Ivy_NodeStopFanin( Ivy_Obj_t * pNode, int iFanin ) +{ + if ( iFanin == 0 ) + return Ivy_ObjFanin0(pNode)->Type != pNode->Type || Ivy_ObjRefs(Ivy_ObjFanin0(pNode)) > 1 || Ivy_ObjFaninC0(pNode); + else + return Ivy_ObjFanin1(pNode)->Type != pNode->Type || Ivy_ObjRefs(Ivy_ObjFanin1(pNode)) > 1 || Ivy_ObjFaninC1(pNode); +} + +// this procedure returns 1 if the node cannot be recursively dereferenced +static inline int Ivy_NodeBalanceDerefFanin( Ivy_Obj_t * pNode, int iFanin ) +{ + if ( iFanin == 0 ) + return Ivy_ObjFanin0(pNode)->Type == pNode->Type && Ivy_ObjRefs(Ivy_ObjFanin0(pNode)) == 0 && !Ivy_ObjFaninC0(pNode); + else + return Ivy_ObjFanin1(pNode)->Type == pNode->Type && Ivy_ObjRefs(Ivy_ObjFanin1(pNode)) == 0 && !Ivy_ObjFaninC1(pNode); +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs algebraic balancing of the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel ) +{ + Vec_Int_t * vNodes; + Vec_Ptr_t * vFront, * vSpots; + Ivy_Obj_t * pNode; + int i; + vSpots = Vec_PtrAlloc( 50 ); + vFront = Vec_PtrAlloc( 50 ); + vNodes = Ivy_ManDfs( p ); + Ivy_ManForEachNodeVec( p, vNodes, pNode, i ) + { + if ( Ivy_ObjIsBuf(pNode) ) + continue; + // fix the fanin buffer problem + Ivy_NodeFixBufferFanins( pNode ); + // skip node if it became a buffer + if ( Ivy_ObjIsBuf(pNode) ) + continue; + // skip nodes with one fanout if type of the node is the same as type of the fanout + // such nodes will be processed when the fanouts are processed + if ( Ivy_ObjRefs(pNode) == 1 && Ivy_ObjIsExor(pNode) == Ivy_ObjExorFanout(pNode) ) + continue; + assert( Ivy_ObjRefs(pNode) > 0 ); + // do not balance the node if both if its fanins have more than one fanout + if ( Ivy_NodeStopFanin(pNode, 0) && Ivy_NodeStopFanin(pNode, 1) ) + continue; + // try balancing this node + Ivy_NodeBalance( pNode, fUpdateLevel, vFront, vSpots ); + } + Vec_IntFree( vNodes ); + Vec_PtrFree( vSpots ); + Vec_PtrFree( vFront ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Dereferences MFFC of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_NodeBalanceDeref_rec( Ivy_Obj_t * pNode ) +{ + Ivy_Obj_t * pFan; + // deref the first fanin + pFan = Ivy_ObjFanin0(pNode); + Ivy_ObjRefsDec( pFan ); + if ( Ivy_NodeBalanceDerefFanin(pNode, 0) ) + Ivy_NodeBalanceDeref_rec( pFan ); + // deref the second fanin + pFan = Ivy_ObjFanin1(pNode); + Ivy_ObjRefsDec( pFan ); + if ( Ivy_NodeBalanceDerefFanin(pNode, 1) ) + Ivy_NodeBalanceDeref_rec( pFan ); +} + +/**Function************************************************************* + + Synopsis [Removes nodes inside supergate and determines frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_NodeBalanceCollect_rec( Ivy_Obj_t * pNode, Vec_Ptr_t * vSpots, Vec_Ptr_t * vFront ) +{ + Ivy_Obj_t * pFanin; + // skip visited nodes + if ( Vec_PtrFind(vSpots, pNode) >= 0 ) + return; + // collect node + Vec_PtrPush( vSpots, pNode ); + // first fanin + pFanin = Ivy_ObjFanin0(pNode); + if ( Ivy_ObjRefs(pFanin) == 0 ) + Ivy_NodeBalanceCollect_rec( pFanin, vSpots, vFront ); + else if ( Ivy_ObjIsExor(pNode) && Vec_PtrFind(vFront, Ivy_ObjChild0(pNode)) >= 0 ) + Vec_PtrRemove( vFront, Ivy_ObjChild0(pNode) ); + else + Vec_PtrPushUnique( vFront, Ivy_ObjChild0(pNode) ); + // second fanin + pFanin = Ivy_ObjFanin1(pNode); + if ( Ivy_ObjRefs(pFanin) == 0 ) + Ivy_NodeBalanceCollect_rec( pFanin, vSpots, vFront ); + else if ( Ivy_ObjIsExor(pNode) && Vec_PtrFind(vFront, Ivy_ObjChild1(pNode)) >= 0 ) + Vec_PtrRemove( vFront, Ivy_ObjChild1(pNode) ); + else + Vec_PtrPushUnique( vFront, Ivy_ObjChild1(pNode) ); +} + +/**Function************************************************************* + + Synopsis [Comparison procedure for two nodes by level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_BalanceCompareByLevel( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 ) +{ + int Level1 = Ivy_ObjLevel( *pp1 ); + int Level2 = Ivy_ObjLevel( *pp2 ); + if ( Level1 > Level2 ) + return -1; + if ( Level1 < Level2 ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Removes nodes inside supergate and determines frontier.] + + Description [Return 1 if the output needs to be complemented.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_NodeBalancePrepare( Ivy_Obj_t * pNode, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots ) +{ + Ivy_Man_t * pMan = Ivy_ObjMan( pNode ); + Ivy_Obj_t * pObj, * pNext; + int i, k, Counter = 0; + // dereference the cone + Ivy_NodeBalanceDeref_rec( pNode ); + // collect the frontier and the internal nodes + Vec_PtrClear( vFront ); + Vec_PtrClear( vSpots ); + Ivy_NodeBalanceCollect_rec( pNode, vSpots, vFront ); + // remove all the nodes + Vec_PtrForEachEntry( vSpots, pObj, i ) + { + // skip the first entry (the node itself) + if ( i == 0 ) continue; + // collect the free entries + Vec_IntPush( pMan->vFree, pObj->Id ); + Ivy_ObjDelete( pObj, 1 ); + } + // sort nodes by level in decreasing order + qsort( (void *)Vec_PtrArray(vFront), Vec_PtrSize(vFront), sizeof(Ivy_Obj_t *), + (int (*)(const void *, const void *))Ivy_BalanceCompareByLevel ); + // check if there are nodes and their complements + Counter = 0; + Vec_PtrForEachEntry( vFront, pObj, i ) + { + if ( i == Vec_PtrSize(vFront) - 1 ) + break; + pNext = Vec_PtrEntry( vFront, i+1 ); + if ( Ivy_Regular(pObj) == Ivy_Regular(pNext) ) + { + assert( pObj == Ivy_Not(pNext) ); + Vec_PtrWriteEntry( vFront, i, NULL ); + Vec_PtrWriteEntry( vFront, i+1, NULL ); + i++; + Counter++; + } + } + // if there are no complemented pairs, go ahead and balance + if ( Counter == 0 ) + return 0; + // if there are complemented pairs and this is AND, create const 0 + if ( Counter > 0 && Ivy_ObjIsAnd(pNode) ) + { + Vec_PtrClear( vFront ); + Vec_PtrPush( vFront, Ivy_ManConst0(pMan) ); + return 0; + } + assert( Counter > 0 && Ivy_ObjIsExor(pNode) ); + // remove the pairs + k = 0; + Vec_PtrForEachEntry( vFront, pObj, i ) + if ( pObj ) + Vec_PtrWriteEntry( vFront, k++, pObj ); + Vec_PtrShrink( vFront, k ); + // add constant zero node if nothing is left + if ( Vec_PtrSize(vFront) == 0 ) + Vec_PtrPush( vFront, Ivy_ManConst0(pMan) ); + // return 1 if the number of pairs is odd (need to complement the output) + return Counter & 1; +} + +/**Function************************************************************* + + Synopsis [Finds the left bound on the next candidate to be paired.] + + Description [The nodes in the array are in the decreasing order of levels. + The last node in the array has the smallest level. By default it would be paired + with the next node on the left. However, it may be possible to pair it with some + other node on the left, in such a way that the new node is shared. This procedure + finds the index of the left-most node, which can be paired with the last node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper ) +{ + Ivy_Obj_t * pNodeRight, * pNodeLeft; + int Current; + // if two or less nodes, pair with the first + if ( Vec_PtrSize(vSuper) < 3 ) + return 0; + // set the pointer to the one before the last + Current = Vec_PtrSize(vSuper) - 2; + pNodeRight = Vec_PtrEntry( vSuper, Current ); + // go through the nodes to the left of this one + for ( Current--; Current >= 0; Current-- ) + { + // get the next node on the left + pNodeLeft = Vec_PtrEntry( vSuper, Current ); + // if the level of this node is different, quit the loop + if ( Ivy_Regular(pNodeLeft)->Level != Ivy_Regular(pNodeRight)->Level ) + break; + } + Current++; + // get the node, for which the equality holds + pNodeLeft = Vec_PtrEntry( vSuper, Current ); + assert( Ivy_Regular(pNodeLeft)->Level == Ivy_Regular(pNodeRight)->Level ); + return Current; +} + +/**Function************************************************************* + + Synopsis [Moves closer to the end the node that is best for sharing.] + + Description [If there is no node with sharing, randomly chooses one of + the legal nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound, int fExor ) +{ + Ivy_Obj_t * pNode1, * pNode2, * pNode3, * pGhost; + int RightBound, i; + // get the right bound + RightBound = Vec_PtrSize(vSuper) - 2; + assert( LeftBound <= RightBound ); + if ( LeftBound == RightBound ) + return; + // get the two last nodes + pNode1 = Vec_PtrEntry( vSuper, RightBound + 1 ); + pNode2 = Vec_PtrEntry( vSuper, RightBound ); + // find the first node that can be shared + for ( i = RightBound; i >= LeftBound; i-- ) + { + pNode3 = Vec_PtrEntry( vSuper, i ); + pGhost = Ivy_ObjCreateGhost( pNode1, pNode3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE ); + if ( Ivy_TableLookup( pGhost ) ) + { + if ( pNode3 == pNode2 ) + return; + Vec_PtrWriteEntry( vSuper, i, pNode2 ); + Vec_PtrWriteEntry( vSuper, RightBound, pNode3 ); + return; + } + } +/* + // we did not find the node to share, randomize choice + { + int Choice = rand() % (RightBound - LeftBound + 1); + pNode3 = Vec_PtrEntry( vSuper, LeftBound + Choice ); + if ( pNode3 == pNode2 ) + return; + Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pNode2 ); + Vec_PtrWriteEntry( vSuper, RightBound, pNode3 ); + } +*/ +} + +/**Function************************************************************* + + Synopsis [Inserts a new node in the order by levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vFront, Ivy_Obj_t * pNode ) +{ + Ivy_Obj_t * pNode1, * pNode2; + int i; + if ( Vec_PtrPushUnique(vFront, pNode) ) + return; + // find the p of the node + for ( i = vFront->nSize-1; i > 0; i-- ) + { + pNode1 = vFront->pArray[i ]; + pNode2 = vFront->pArray[i-1]; + if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level ) + break; + vFront->pArray[i ] = pNode2; + vFront->pArray[i-1] = pNode1; + } +} + +/**Function************************************************************* + + Synopsis [Balances one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_NodeBalance( Ivy_Obj_t * pNode, int fUpdateLevel, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots ) +{ + Ivy_Man_t * pMan = Ivy_ObjMan( pNode ); + Ivy_Obj_t * pFan0, * pFan1, * pNodeNew; + int fCompl, LeftBound; + // remove internal nodes and derive the frontier + fCompl = Ivy_NodeBalancePrepare( pNode, vFront, vSpots ); + assert( Vec_PtrSize(vFront) > 0 ); + // balance the nodes + while ( Vec_PtrSize(vFront) > 1 ) + { + // find the left bound on the node to be paired + LeftBound = (!fUpdateLevel)? 0 : Ivy_NodeBalanceFindLeft( vFront ); + // find the node that can be shared (if no such node, randomize choice) + Ivy_NodeBalancePermute( pMan, vFront, LeftBound, Ivy_ObjIsExor(pNode) ); + // pull out the last two nodes + pFan0 = Vec_PtrPop(vFront); assert( !Ivy_ObjIsConst1(Ivy_Regular(pFan0)) ); + pFan1 = Vec_PtrPop(vFront); assert( !Ivy_ObjIsConst1(Ivy_Regular(pFan1)) ); + // create the new node + pNodeNew = Ivy_ObjCreate( Ivy_ObjCreateGhost(pFan0, pFan1, Ivy_ObjType(pNode), IVY_INIT_NONE) ); + // add the new node to the frontier + Ivy_NodeBalancePushUniqueOrderByLevel( vFront, pNodeNew ); + } + assert( Vec_PtrSize(vFront) == 1 ); + // perform the replacement + Ivy_ObjReplace( pNode, Ivy_NotCond(Vec_PtrPop(vFront), fCompl), 1, 1 ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyCanon.c b/src/temp/ivy/ivyCanon.c new file mode 100644 index 00000000..c6f43d15 --- /dev/null +++ b/src/temp/ivy/ivyCanon.c @@ -0,0 +1,147 @@ +/**CFile**************************************************************** + + FileName [ivyCanon.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Finding canonical form of objects.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyCanon.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Ivy_Obj_t * Ivy_TableLookupPair_rec( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1, int fCompl0, int fCompl1, Ivy_Type_t Type ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates the canonical form of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_CanonPair_rec( Ivy_Obj_t * pGhost ) +{ + Ivy_Obj_t * pResult, * pLat0, * pLat1; + Ivy_Init_t Init, Init0, Init1; + int fCompl0, fCompl1; + Ivy_Type_t Type; + assert( Ivy_ObjIsNode(pGhost) ); + assert( Ivy_ObjIsAnd(pGhost) || (!Ivy_ObjFaninC0(pGhost) && !Ivy_ObjFaninC1(pGhost)) ); + assert( Ivy_ObjFaninId0(pGhost) != 0 && Ivy_ObjFaninId1(pGhost) != 0 ); + // consider the case when the pair is canonical + if ( !Ivy_ObjIsLatch(Ivy_ObjFanin0(pGhost)) || !Ivy_ObjIsLatch(Ivy_ObjFanin1(pGhost)) ) + { + if ( pResult = Ivy_TableLookup( pGhost ) ) + return pResult; + return Ivy_ObjCreate( pGhost ); + } + /// remember the latches + pLat0 = Ivy_ObjFanin0(pGhost); + pLat1 = Ivy_ObjFanin1(pGhost); + // remember type and compls + Type = Ivy_ObjType(pGhost); + fCompl0 = Ivy_ObjFaninC0(pGhost); + fCompl1 = Ivy_ObjFaninC1(pGhost); + // modify the fanins to be latch fanins + pGhost->Fanin0 = Ivy_ObjFaninId0(pLat0); + pGhost->Fanin1 = Ivy_ObjFaninId0(pLat1); + // call recursively + pResult = Ivy_CanonPair_rec( pGhost ); + // build latch on top of this + Init0 = Ivy_InitNotCond( Ivy_ObjInit(pLat0), fCompl0 ); + Init1 = Ivy_InitNotCond( Ivy_ObjInit(pLat1), fCompl1 ); + Init = (Type == IVY_AND)? Ivy_InitAnd(Init0, Init1) : Ivy_InitExor(Init0, Init1); + return Ivy_CanonLatch( pResult, Init ); +} + +/**Function************************************************************* + + Synopsis [Creates the canonical form of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_CanonAnd( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 ) +{ + Ivy_Obj_t * pGhost, * pResult; + pGhost = Ivy_ObjCreateGhost( pObj0, pObj1, IVY_AND, IVY_INIT_NONE ); + pResult = Ivy_CanonPair_rec( pGhost ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Creates the canonical form of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_CanonExor( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 ) +{ + Ivy_Obj_t * pGhost, * pResult; + int fCompl = Ivy_IsComplement(pObj0) ^ Ivy_IsComplement(pObj1); + pObj0 = Ivy_Regular(pObj0); + pObj1 = Ivy_Regular(pObj1); + pGhost = Ivy_ObjCreateGhost( pObj0, pObj1, IVY_EXOR, IVY_INIT_NONE ); + pResult = Ivy_CanonPair_rec( pGhost ); + return Ivy_NotCond( pResult, fCompl ); +} + +/**Function************************************************************* + + Synopsis [Creates the canonical form of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_CanonLatch( Ivy_Obj_t * pObj, Ivy_Init_t Init ) +{ + Ivy_Obj_t * pGhost, * pResult; + int fCompl = Ivy_IsComplement(pObj); + pObj = Ivy_Regular(pObj); + pGhost = Ivy_ObjCreateGhost( pObj, Ivy_ObjConst1(pObj), IVY_LATCH, Ivy_InitNotCond(Init, fCompl) ); + pResult = Ivy_TableLookup( pGhost ); + if ( pResult == NULL ) + pResult = Ivy_ObjCreate( pGhost ); + return Ivy_NotCond( pResult, fCompl ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyCheck.c b/src/temp/ivy/ivyCheck.c new file mode 100644 index 00000000..c39eac12 --- /dev/null +++ b/src/temp/ivy/ivyCheck.c @@ -0,0 +1,121 @@ +/**CFile**************************************************************** + + FileName [ivyCheck.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [AIG checking procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyCheck.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Checks the consistency of the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManCheck( Ivy_Man_t * pMan ) +{ + Ivy_Obj_t * pObj, * pObj2; + int i; + Ivy_ManForEachObj( pMan, pObj, i ) + { + // skip deleted nodes + if ( Ivy_ObjIsNone(pObj) ) + continue; + // consider the constant node and PIs + if ( i == 0 || Ivy_ObjIsPi(pObj) ) + { + if ( Ivy_ObjFaninId0(pObj) || Ivy_ObjFaninId1(pObj) || Ivy_ObjLevel(pObj) ) + { + printf( "Ivy_ManCheck: The AIG has non-standard constant or PI node with ID \"%d\".\n", pObj->Id ); + return 0; + } + continue; + } + if ( Ivy_ObjIsPo(pObj) ) + { + if ( Ivy_ObjFaninId1(pObj) ) + { + printf( "Ivy_ManCheck: The AIG has non-standard PO node with ID \"%d\".\n", pObj->Id ); + return 0; + } + continue; + } + if ( Ivy_ObjIsBuf(pObj) ) + { + continue; + } + if ( Ivy_ObjIsLatch(pObj) ) + { + if ( Ivy_ObjFaninId1(pObj) != 0 ) + { + printf( "Ivy_ManCheck: The latch with ID \"%d\" contains second fanin.\n", pObj->Id ); + return 0; + } + if ( Ivy_ObjInit(pObj) == 0 ) + { + printf( "Ivy_ManCheck: The latch with ID \"%d\" does not have initial state.\n", pObj->Id ); + return 0; + } + pObj2 = Ivy_TableLookup( pObj ); + if ( pObj2 != pObj ) + printf( "Ivy_ManCheck: Latch with ID \"%d\" is not in the structural hashing table.\n", pObj->Id ); + continue; + } + // consider the AND node + if ( !Ivy_ObjFaninId0(pObj) || !Ivy_ObjFaninId1(pObj) ) + { + printf( "Ivy_ManCheck: The AIG has internal node \"%d\" with a constant fanin.\n", pObj->Id ); + return 0; + } + if ( Ivy_ObjFaninId0(pObj) <= Ivy_ObjFaninId1(pObj) ) + { + printf( "Ivy_ManCheck: The AIG has node \"%d\" with a wrong ordering of fanins.\n", pObj->Id ); + return 0; + } +// if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) ) +// printf( "Ivy_ManCheck: Node with ID \"%d\" has level that does not agree with the fanin levels.\n", pObj->Id ); + pObj2 = Ivy_TableLookup( pObj ); + if ( pObj2 != pObj ) + printf( "Ivy_ManCheck: Node with ID \"%d\" is not in the structural hashing table.\n", pObj->Id ); + } + // count the number of nodes in the table + if ( Ivy_TableCountEntries(pMan) != Ivy_ManAndNum(pMan) + Ivy_ManExorNum(pMan) + Ivy_ManLatchNum(pMan) ) + { + printf( "Ivy_ManCheck: The number of nodes in the structural hashing table is wrong.\n" ); + return 0; + } + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyCut.c b/src/temp/ivy/ivyCut.c new file mode 100644 index 00000000..a8fd148b --- /dev/null +++ b/src/temp/ivy/ivyCut.c @@ -0,0 +1,205 @@ +/**CFile**************************************************************** + + FileName [ivyCut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Computes reconvergence driven sequential cut.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyCut.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Evaluate the cost of removing the node from the set of leaves.] + + Description [Returns the number of new leaves that will be brought in. + Returns large number if the node cannot be removed from the set of leaves.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Ivy_NodeGetLeafCostOne( Ivy_Man_t * p, int Leaf, Vec_Int_t * vInside ) +{ + Ivy_Obj_t * pNode; + int nLatches, FaninLeaf, Cost; + // make sure leaf is not a contant node + assert( Leaf > 0 ); + // get the node + pNode = Ivy_ManObj( p, Ivy_LeafId(Leaf) ); + // cannot expand over the PI node + if ( Ivy_ObjIsPi(pNode) || Ivy_ObjIsConst1(pNode) ) + return 999; + // get the number of latches + nLatches = Ivy_LeafLat(Leaf) + Ivy_ObjIsLatch(pNode); + if ( nLatches > 15 ) + return 999; + // get the first fanin + FaninLeaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pNode), nLatches ); + Cost = FaninLeaf && (Vec_IntFind(vInside, FaninLeaf) == -1); + // quit if this is the one fanin node + if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ) + return Cost; + assert( Ivy_ObjIsNode(pNode) ); + // get the second fanin + FaninLeaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pNode), nLatches ); + Cost += FaninLeaf && (Vec_IntFind(vInside, FaninLeaf) == -1); + return Cost; +} + +/**Function************************************************************* + + Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.] + + Description [This procedure looks at the current leaves and tries to change + one leaf at a time in such a way that the cut grows as little as possible. + In evaluating the fanins, this procedure looks only at their immediate + predecessors (this is why it is called a one-level construction procedure).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManSeqFindCut_int( Ivy_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSizeLimit ) +{ + Ivy_Obj_t * pNode; + int CostBest, CostCur, Leaf, LeafBest, Next, nLatches, i; + int LeavesBest[10]; + int Counter; + + // add random selection of the best fanin!!! + + // find the best fanin + CostBest = 99; + LeafBest = -1; + Counter = -1; +//printf( "Evaluating fanins of the cut:\n" ); + Vec_IntForEachEntry( vFront, Leaf, i ) + { + CostCur = Ivy_NodeGetLeafCostOne( p, Leaf, vInside ); +//printf( " Fanin %s has cost %d.\n", Ivy_ObjName(pNode), CostCur ); + if ( CostBest > CostCur ) + { + CostBest = CostCur; + LeafBest = Leaf; + LeavesBest[0] = Leaf; + Counter = 1; + } + else if ( CostBest == CostCur ) + LeavesBest[Counter++] = Leaf; + + if ( CostBest <= 1 ) // can be if ( CostBest <= 1 ) + break; + } + if ( CostBest == 99 ) + return 0; +// return Ivy_NodeBuildCutLevelTwo_int( vInside, vFront, nFaninLimit ); + + assert( CostBest < 3 ); + if ( Vec_IntSize(vFront) - 1 + CostBest > nSizeLimit ) + return 0; +// return Ivy_NodeBuildCutLevelTwo_int( vInside, vFront, nFaninLimit ); + + assert( Counter > 0 ); +printf( "%d", Counter ); + + LeafBest = LeavesBest[rand() % Counter]; + + // remove the node from the array + assert( LeafBest >= 0 ); + Vec_IntRemove( vFront, LeafBest ); +//printf( "Removing fanin %s.\n", Ivy_ObjName(pNode) ); + + // get the node and its latches + pNode = Ivy_ManObj( p, Ivy_LeafId(LeafBest) ); + nLatches = Ivy_LeafLat(LeafBest) + Ivy_ObjIsLatch(pNode); + assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ); + + // add the left child to the fanins + Next = Ivy_LeafCreate( Ivy_ObjFaninId0(pNode), nLatches ); + if ( Next && Vec_IntFind(vInside, Next) == -1 ) + { +//printf( "Adding fanin %s.\n", Ivy_ObjName(pNext) ); + Vec_IntPush( vFront, Next ); + Vec_IntPush( vInside, Next ); + } + + // quit if this is the one fanin node + if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ) + return 1; + assert( Ivy_ObjIsNode(pNode) ); + + // add the right child to the fanins + Next = Ivy_LeafCreate( Ivy_ObjFaninId1(pNode), nLatches ); + if ( Next && Vec_IntFind(vInside, Next) == -1 ) + { +//printf( "Adding fanin %s.\n", Ivy_ObjName(pNext) ); + Vec_IntPush( vFront, Next ); + Vec_IntPush( vInside, Next ); + } + assert( Vec_IntSize(vFront) <= nSizeLimit ); + // keep doing this + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes one sequential cut of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManSeqFindCut( Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize ) +{ + assert( !Ivy_IsComplement(pRoot) ); + assert( Ivy_ObjIsNode(pRoot) ); + assert( Ivy_ObjFaninId0(pRoot) ); + assert( Ivy_ObjFaninId1(pRoot) ); + + // start the cut + Vec_IntClear( vFront ); + Vec_IntPush( vFront, Ivy_LeafCreate(Ivy_ObjFaninId0(pRoot), 0) ); + Vec_IntPush( vFront, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) ); + + // start the visited nodes + Vec_IntClear( vInside ); + Vec_IntPush( vInside, Ivy_LeafCreate(pRoot->Id, 0) ); + Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId0(pRoot), 0) ); + Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) ); + + // compute the cut + while ( Ivy_ManSeqFindCut_int( Ivy_ObjMan(pRoot), vFront, vInside, nSize ) ); + assert( Vec_IntSize(vFront) <= nSize ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyDfs.c b/src/temp/ivy/ivyDfs.c new file mode 100644 index 00000000..2db80b00 --- /dev/null +++ b/src/temp/ivy/ivyDfs.c @@ -0,0 +1,152 @@ +/**CFile**************************************************************** + + FileName [ivyDfs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [DFS collection procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyDfs.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collects nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManDfs_rec( Ivy_Obj_t * pObj, Vec_Int_t * vNodes ) +{ + if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) ) + return; + if ( Ivy_ObjIsMarkA(pObj) ) + return; + Ivy_ObjSetMarkA(pObj); + assert( Ivy_ObjIsBuf(pObj) || Ivy_ObjIsAnd(pObj) || Ivy_ObjIsExor(pObj) ); + Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes ); + if ( !Ivy_ObjIsBuf(pObj) ) + Ivy_ManDfs_rec( Ivy_ObjFanin1(pObj), vNodes ); + Vec_IntPush( vNodes, pObj->Id ); +} + +/**Function************************************************************* + + Synopsis [Collects AND/EXOR nodes in the DFS order from CIs to COs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p ) +{ + Vec_Int_t * vNodes; + Ivy_Obj_t * pObj; + int i; + // collect the nodes + vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) ); + if ( Ivy_ManLatchNum(p) > 0 ) + Ivy_ManForEachCo( p, pObj, i ) + Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes ); + else + Ivy_ManForEachPo( p, pObj, i ) + Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes ); + // unmark the collected nodes + Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) + Ivy_ObjClearMarkA(pObj); + // make sure network does not have dangling nodes + assert( Vec_IntSize(vNodes) == Ivy_ManNodeNum(p) + Ivy_ManBufNum(p) ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Collects nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManDfsExt_rec( Ivy_Obj_t * pObj, Vec_Int_t * vNodes ) +{ + Vec_Int_t * vFanins; + int i, Fanin; + if ( !Ivy_ObjIsNodeExt(pObj) || Ivy_ObjIsMarkA(pObj) ) + return; + // mark the node as visited + Ivy_ObjSetMarkA(pObj); + // traverse the fanins + vFanins = Ivy_ObjGetFanins( pObj ); + Vec_IntForEachEntry( vFanins, Fanin, i ) + Ivy_ManDfsExt_rec( Ivy_ObjObj(pObj, Ivy_FanId(Fanin)), vNodes ); + // add the node + Vec_IntPush( vNodes, pObj->Id ); +} + +/**Function************************************************************* + + Synopsis [Collects nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p ) +{ + Vec_Int_t * vNodes; + Ivy_Obj_t * pObj, * pFanin; + int i; + assert( p->fExtended ); + assert( Ivy_ManLatchNum(p) == 0 ); + // make sure network does not have buffers + vNodes = Vec_IntAlloc( 10 ); + Ivy_ManForEachPo( p, pObj, i ) + { + pFanin = Ivy_ManObj( p, Ivy_FanId( Ivy_ObjReadFanin(pObj,0) ) ); + Ivy_ManDfsExt_rec( pFanin, vNodes ); + } + Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) + Ivy_ObjClearMarkA(pObj); + // make sure network does not have dangling nodes + // the network may have dangling nodes if some fanins of ESOPs do not appear in cubes +// assert( p->nNodes == Vec_PtrSize(vNodes) ); + return vNodes; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyDsd.c b/src/temp/ivy/ivyDsd.c new file mode 100644 index 00000000..5dfdd30f --- /dev/null +++ b/src/temp/ivy/ivyDsd.c @@ -0,0 +1,819 @@ +/**CFile**************************************************************** + + FileName [ivyDsd.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Disjoint-support decomposition.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyDsd.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// decomposition types +typedef enum { + IVY_DEC_PI, // 0: var + IVY_DEC_CONST1, // 1: CONST1 + IVY_DEC_BUF, // 2: BUF + IVY_DEC_AND, // 3: AND + IVY_DEC_EXOR, // 4: EXOR + IVY_DEC_MUX, // 5: MUX + IVY_DEC_MAJ, // 6: MAJ + IVY_DEC_PRIME // 7: undecomposable +} Ivy_DecType_t; + +typedef struct Ivy_Dec_t_ Ivy_Dec_t; +struct Ivy_Dec_t_ +{ + unsigned Type : 4; // the node type (PI, CONST1, AND, EXOR, MUX, PRIME) + unsigned fCompl : 1; // shows if node is complemented (root node only) + unsigned nFans : 3; // the number of fanins + unsigned Fan0 : 4; // fanin 0 + unsigned Fan1 : 4; // fanin 1 + unsigned Fan2 : 4; // fanin 2 + unsigned Fan3 : 4; // fanin 3 + unsigned Fan4 : 4; // fanin 4 + unsigned Fan5 : 4; // fanin 5 +}; + +static inline int Ivy_DecToInt( Ivy_Dec_t Node ) { return *((int *)&Node); } +static inline Ivy_Dec_t Ivy_IntToDec( int Node ) { return *((Ivy_Dec_t *)&Node); } +static inline void Ivy_DecClear( Ivy_Dec_t * pNode ) { *((int *)pNode) = 0; } + + +static unsigned s_Masks[6][2] = { + { 0x55555555, 0xAAAAAAAA }, + { 0x33333333, 0xCCCCCCCC }, + { 0x0F0F0F0F, 0xF0F0F0F0 }, + { 0x00FF00FF, 0xFF00FF00 }, + { 0x0000FFFF, 0xFFFF0000 }, + { 0x00000000, 0xFFFFFFFF } +}; + +static inline int Ivy_TruthWordCountOnes( unsigned uWord ) +{ + uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555); + uWord = (uWord & 0x33333333) + ((uWord>>2) & 0x33333333); + uWord = (uWord & 0x0F0F0F0F) + ((uWord>>4) & 0x0F0F0F0F); + uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF); + return (uWord & 0x0000FFFF) + (uWord>>16); +} + +static inline int Ivy_TruthCofactorIsConst( unsigned uTruth, int Var, int Cof, int Const ) +{ + if ( Const == 0 ) + return (uTruth & s_Masks[Var][Cof]) == 0; + else + return (uTruth & s_Masks[Var][Cof]) == s_Masks[Var][Cof]; +} + +static inline int Ivy_TruthCofactorIsOne( unsigned uTruth, int Var ) +{ + return (uTruth & s_Masks[Var][0]) == 0; +} + +static inline unsigned Ivy_TruthCofactor( unsigned uTruth, int Var ) +{ + unsigned uCofactor = uTruth & s_Masks[Var >> 1][(Var & 1) == 0]; + int Shift = (1 << (Var >> 1)); + if ( Var & 1 ) + return uCofactor | (uCofactor << Shift); + return uCofactor | (uCofactor >> Shift); +} + +static inline unsigned Ivy_TruthCofactor2( unsigned uTruth, int Var0, int Var1 ) +{ + return Ivy_TruthCofactor( Ivy_TruthCofactor(uTruth, Var0), Var1 ); +} + +// returns 1 if the truth table depends on this var (var is regular interger var) +static inline int Ivy_TruthDepends( unsigned uTruth, int Var ) +{ + return Ivy_TruthCofactor(uTruth, Var << 1) != Ivy_TruthCofactor(uTruth, (Var << 1) | 1); +} + +static inline void Ivy_DecSetVar( Ivy_Dec_t * pNode, int iNum, unsigned Var ) +{ + assert( iNum >= 0 && iNum <= 5 ); + switch( iNum ) + { + case 0: pNode->Fan0 = Var; break; + case 1: pNode->Fan1 = Var; break; + case 2: pNode->Fan2 = Var; break; + case 3: pNode->Fan3 = Var; break; + case 4: pNode->Fan4 = Var; break; + case 5: pNode->Fan5 = Var; break; + } +} + +static inline unsigned Ivy_DecGetVar( Ivy_Dec_t * pNode, int iNum ) +{ + assert( iNum >= 0 && iNum <= 5 ); + switch( iNum ) + { + case 0: return pNode->Fan0; + case 1: return pNode->Fan1; + case 2: return pNode->Fan2; + case 3: return pNode->Fan3; + case 4: return pNode->Fan4; + case 5: return pNode->Fan5; + } + return ~0; +} + +static int Ivy_TruthDecompose_rec( unsigned uTruth, Vec_Int_t * vTree ); +static int Ivy_TruthRecognizeMuxMaj( unsigned uTruth, int * pSupp, int nSupp, Vec_Int_t * vTree ); + +//int nTruthDsd; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes DSD of truth table of 5 variables or less.] + + Description [Returns 1 if the function is a constant or is fully + DSD decomposable using AND/EXOR/MUX gates.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree ) +{ + Ivy_Dec_t Node; + int i, RetValue; + // set the PI variables + Vec_IntClear( vTree ); + for ( i = 0; i < 5; i++ ) + Vec_IntPush( vTree, 0 ); + // check if it is a constant + if ( uTruth == 0 || ~uTruth == 0 ) + { + Ivy_DecClear( &Node ); + Node.Type = IVY_DEC_CONST1; + Node.fCompl = (uTruth == 0); + Vec_IntPush( vTree, Ivy_DecToInt(Node) ); + return 1; + } + // perform the decomposition + RetValue = Ivy_TruthDecompose_rec( uTruth, vTree ); + if ( RetValue == -1 ) + return 0; + // get the topmost node + if ( (RetValue >> 1) < 5 ) + { // add buffer + Ivy_DecClear( &Node ); + Node.Type = IVY_DEC_BUF; + Node.fCompl = (RetValue & 1); + Node.Fan0 = ((RetValue >> 1) << 1); + Vec_IntPush( vTree, Ivy_DecToInt(Node) ); + } + else if ( RetValue & 1 ) + { // check if the topmost node has to be complemented + Node = Ivy_IntToDec( Vec_IntPop(vTree) ); + assert( Node.fCompl == 0 ); + Node.fCompl = (RetValue & 1); + Vec_IntPush( vTree, Ivy_DecToInt(Node) ); + } + if ( uTruth != Ivy_TruthDsdCompute(vTree) ) + printf( "Verification failed.\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes DSD of truth table.] + + Description [Returns the number of topmost decomposition node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_TruthDecompose_rec( unsigned uTruth, Vec_Int_t * vTree ) +{ + Ivy_Dec_t Node; + int Supp[5], Vars0[5], Vars1[5], Vars2[5], * pVars; + int nSupp, Count0, Count1, Count2, nVars, RetValue, fCompl, i; + unsigned uTruthCof, uCof0, uCof1; + + // get constant confactors + Count0 = Count1 = Count2 = nSupp = 0; + for ( i = 0; i < 5; i++ ) + { + if ( Ivy_TruthCofactorIsConst(uTruth, i, 0, 0) ) + Vars0[Count0++] = (i << 1) | 0; + else if ( Ivy_TruthCofactorIsConst(uTruth, i, 1, 0) ) + Vars0[Count0++] = (i << 1) | 1; + else if ( Ivy_TruthCofactorIsConst(uTruth, i, 0, 1) ) + Vars1[Count1++] = (i << 1) | 0; + else if ( Ivy_TruthCofactorIsConst(uTruth, i, 1, 1) ) + Vars1[Count1++] = (i << 1) | 1; + else + { + uCof0 = Ivy_TruthCofactor( uTruth, (i << 1) | 1 ); + uCof1 = Ivy_TruthCofactor( uTruth, (i << 1) | 0 ); + if ( uCof0 == ~uCof1 ) + Vars2[Count2++] = (i << 1) | 0; + else if ( uCof0 != uCof1 ) + Supp[nSupp++] = i; + } + } + assert( Count0 == 0 || Count1 == 0 ); + assert( Count0 == 0 || Count2 == 0 ); + assert( Count1 == 0 || Count2 == 0 ); + + // consider the case of a single variable + if ( Count0 == 1 && nSupp == 0 ) + return Vars0[0]; + + // consider more complex decompositions + if ( Count0 == 0 && Count1 == 0 && Count2 == 0 ) + return Ivy_TruthRecognizeMuxMaj( uTruth, Supp, nSupp, vTree ); + + // extract the nodes + Ivy_DecClear( &Node ); + if ( Count0 > 0 ) + nVars = Count0, pVars = Vars0, Node.Type = IVY_DEC_AND, fCompl = 0; + else if ( Count1 > 0 ) + nVars = Count1, pVars = Vars1, Node.Type = IVY_DEC_AND, fCompl = 1, uTruth = ~uTruth; + else if ( Count2 > 0 ) + nVars = Count2, pVars = Vars2, Node.Type = IVY_DEC_EXOR, fCompl = 0; + else + assert( 0 ); + Node.nFans = nVars+(nSupp>0); + + // compute cofactor + uTruthCof = uTruth; + for ( i = 0; i < nVars; i++ ) + { + uTruthCof = Ivy_TruthCofactor( uTruthCof, pVars[i] ); + Ivy_DecSetVar( &Node, i, pVars[i] ); + } + + if ( Node.Type == IVY_DEC_EXOR ) + fCompl ^= ((Node.nFans & 1) == 0); + + if ( nSupp > 0 ) + { + assert( uTruthCof != 0 && ~uTruthCof != 0 ); + // call recursively + RetValue = Ivy_TruthDecompose_rec( uTruthCof, vTree ); + // quit if non-decomposable + if ( RetValue == -1 ) + return -1; + // remove the complement from the child if the node is EXOR + if ( Node.Type == IVY_DEC_EXOR && (RetValue & 1) ) + { + fCompl ^= 1; + RetValue ^= 1; + } + // set the new decomposition + Ivy_DecSetVar( &Node, nVars, RetValue ); + } + else if ( Node.Type == IVY_DEC_EXOR ) + fCompl ^= (uTruthCof == 0); + + Vec_IntPush( vTree, Ivy_DecToInt(Node) ); + return ((Vec_IntSize(vTree)-1) << 1) | fCompl; +} + +/**Function************************************************************* + + Synopsis [Returns a non-negative number if the truth table is a MUX.] + + Description [If the truth table is a MUX, returns the variable as follows: + first, control variable; second, positive cofactor; third, negative cofactor.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_TruthRecognizeMuxMaj( unsigned uTruth, int * pSupp, int nSupp, Vec_Int_t * vTree ) +{ + Ivy_Dec_t Node; + int i, k, RetValue0, RetValue1; + unsigned uCof0, uCof1, Num; + char Count[3]; + assert( nSupp >= 3 ); + // start the node + Ivy_DecClear( &Node ); + Node.Type = IVY_DEC_MUX; + Node.nFans = 3; + // try each of the variables + for ( i = 0; i < nSupp; i++ ) + { + // get the cofactors with respect to these variables + uCof0 = Ivy_TruthCofactor( uTruth, (pSupp[i] << 1) | 1 ); + uCof1 = Ivy_TruthCofactor( uTruth, pSupp[i] << 1 ); + // go through all other variables and make sure + // each of them belongs to the support of one cofactor + for ( k = 0; k < nSupp; k++ ) + { + if ( k == i ) + continue; + if ( Ivy_TruthDepends(uCof0, pSupp[k]) && Ivy_TruthDepends(uCof1, pSupp[k]) ) + break; + } + if ( k < nSupp ) + continue; + // MUX decomposition exists + RetValue0 = Ivy_TruthDecompose_rec( uCof0, vTree ); + if ( RetValue0 == -1 ) + break; + RetValue1 = Ivy_TruthDecompose_rec( uCof1, vTree ); + if ( RetValue1 == -1 ) + break; + // both of them exist; create the node + Ivy_DecSetVar( &Node, 0, pSupp[i] << 1 ); + Ivy_DecSetVar( &Node, 1, RetValue1 ); + Ivy_DecSetVar( &Node, 2, RetValue0 ); + Vec_IntPush( vTree, Ivy_DecToInt(Node) ); + return ((Vec_IntSize(vTree)-1) << 1) | 0; + } + // check majority gate + if ( nSupp > 3 ) + return -1; + if ( Ivy_TruthWordCountOnes(uTruth) != 16 ) + return -1; + // this is a majority gate; determine polarity + Node.Type = IVY_DEC_MAJ; + Count[0] = Count[1] = Count[2] = 0; + for ( i = 0; i < 8; i++ ) + { + Num = 0; + for ( k = 0; k < 3; k++ ) + if ( i & (1 << k) ) + Num |= (1 << pSupp[k]); + assert( Num < 32 ); + if ( (uTruth & (1 << Num)) == 0 ) + continue; + for ( k = 0; k < 3; k++ ) + if ( i & (1 << k) ) + Count[k]++; + } + assert( Count[0] == 1 || Count[0] == 3 ); + assert( Count[1] == 1 || Count[1] == 3 ); + assert( Count[2] == 1 || Count[2] == 3 ); + Ivy_DecSetVar( &Node, 0, (pSupp[0] << 1)|(Count[0] == 1) ); + Ivy_DecSetVar( &Node, 1, (pSupp[1] << 1)|(Count[1] == 1) ); + Ivy_DecSetVar( &Node, 2, (pSupp[2] << 1)|(Count[2] == 1) ); + Vec_IntPush( vTree, Ivy_DecToInt(Node) ); + return ((Vec_IntSize(vTree)-1) << 1) | 0; +} + + +/**Function************************************************************* + + Synopsis [Computes truth table of decomposition tree for verification.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Ivy_TruthDsdCompute_rec( int iNode, Vec_Int_t * vTree ) +{ + unsigned uTruthChild, uTruthTotal; + int Var, i; + // get the node + Ivy_Dec_t Node = Ivy_IntToDec( Vec_IntEntry(vTree, iNode) ); + // compute the node function + if ( Node.Type == IVY_DEC_CONST1 ) + return s_Masks[5][ !Node.fCompl ]; + if ( Node.Type == IVY_DEC_PI ) + return s_Masks[iNode][ !Node.fCompl ]; + if ( Node.Type == IVY_DEC_BUF ) + { + uTruthTotal = Ivy_TruthDsdCompute_rec( Node.Fan0 >> 1, vTree ); + return Node.fCompl? ~uTruthTotal : uTruthTotal; + } + if ( Node.Type == IVY_DEC_AND ) + { + uTruthTotal = s_Masks[5][1]; + for ( i = 0; i < (int)Node.nFans; i++ ) + { + Var = Ivy_DecGetVar( &Node, i ); + uTruthChild = Ivy_TruthDsdCompute_rec( Var >> 1, vTree ); + uTruthTotal = (Var & 1)? uTruthTotal & ~uTruthChild : uTruthTotal & uTruthChild; + } + return Node.fCompl? ~uTruthTotal : uTruthTotal; + } + if ( Node.Type == IVY_DEC_EXOR ) + { + uTruthTotal = 0; + for ( i = 0; i < (int)Node.nFans; i++ ) + { + Var = Ivy_DecGetVar( &Node, i ); + uTruthTotal ^= Ivy_TruthDsdCompute_rec( Var >> 1, vTree ); + assert( (Var & 1) == 0 ); + } + return Node.fCompl? ~uTruthTotal : uTruthTotal; + } + assert( Node.fCompl == 0 ); + if ( Node.Type == IVY_DEC_MUX || Node.Type == IVY_DEC_MAJ ) + { + unsigned uTruthChildC, uTruthChild1, uTruthChild0; + int VarC, Var1, Var0; + VarC = Ivy_DecGetVar( &Node, 0 ); + Var1 = Ivy_DecGetVar( &Node, 1 ); + Var0 = Ivy_DecGetVar( &Node, 2 ); + uTruthChildC = Ivy_TruthDsdCompute_rec( VarC >> 1, vTree ); + uTruthChild1 = Ivy_TruthDsdCompute_rec( Var1 >> 1, vTree ); + uTruthChild0 = Ivy_TruthDsdCompute_rec( Var0 >> 1, vTree ); + assert( Node.Type == IVY_DEC_MAJ || (VarC & 1) == 0 ); + uTruthChildC = (VarC & 1)? ~uTruthChildC : uTruthChildC; + uTruthChild1 = (Var1 & 1)? ~uTruthChild1 : uTruthChild1; + uTruthChild0 = (Var0 & 1)? ~uTruthChild0 : uTruthChild0; + if ( Node.Type == IVY_DEC_MUX ) + return (uTruthChildC & uTruthChild1) | (~uTruthChildC & uTruthChild0); + else + return (uTruthChildC & uTruthChild1) | (uTruthChildC & uTruthChild0) | (uTruthChild1 & uTruthChild0); + } + assert( 0 ); + return 0; +} + + +/**Function************************************************************* + + Synopsis [Computes truth table of decomposition tree for verification.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Ivy_TruthDsdCompute( Vec_Int_t * vTree ) +{ + return Ivy_TruthDsdCompute_rec( Vec_IntSize(vTree)-1, vTree ); +} + +/**Function************************************************************* + + Synopsis [Prints the decomposition tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TruthDsdPrint_rec( FILE * pFile, int iNode, Vec_Int_t * vTree ) +{ + int Var, i; + // get the node + Ivy_Dec_t Node = Ivy_IntToDec( Vec_IntEntry(vTree, iNode) ); + // compute the node function + if ( Node.Type == IVY_DEC_CONST1 ) + fprintf( pFile, "Const1%s", (Node.fCompl? "\'" : "") ); + else if ( Node.Type == IVY_DEC_PI ) + fprintf( pFile, "%c%s", 'a' + iNode, (Node.fCompl? "\'" : "") ); + else if ( Node.Type == IVY_DEC_BUF ) + { + Ivy_TruthDsdPrint_rec( pFile, Node.Fan0 >> 1, vTree ); + fprintf( pFile, "%s", (Node.fCompl? "\'" : "") ); + } + else if ( Node.Type == IVY_DEC_AND ) + { + fprintf( pFile, "AND(" ); + for ( i = 0; i < (int)Node.nFans; i++ ) + { + Var = Ivy_DecGetVar( &Node, i ); + Ivy_TruthDsdPrint_rec( pFile, Var >> 1, vTree ); + fprintf( pFile, "%s", (Var & 1)? "\'" : "" ); + if ( i != (int)Node.nFans-1 ) + fprintf( pFile, "," ); + } + fprintf( pFile, ")%s", (Node.fCompl? "\'" : "") ); + } + else if ( Node.Type == IVY_DEC_EXOR ) + { + fprintf( pFile, "EXOR(" ); + for ( i = 0; i < (int)Node.nFans; i++ ) + { + Var = Ivy_DecGetVar( &Node, i ); + Ivy_TruthDsdPrint_rec( pFile, Var >> 1, vTree ); + if ( i != (int)Node.nFans-1 ) + fprintf( pFile, "," ); + assert( (Var & 1) == 0 ); + } + fprintf( pFile, ")%s", (Node.fCompl? "\'" : "") ); + } + else if ( Node.Type == IVY_DEC_MUX || Node.Type == IVY_DEC_MAJ ) + { + int VarC, Var1, Var0; + assert( Node.fCompl == 0 ); + VarC = Ivy_DecGetVar( &Node, 0 ); + Var1 = Ivy_DecGetVar( &Node, 1 ); + Var0 = Ivy_DecGetVar( &Node, 2 ); + fprintf( pFile, "%s", (Node.Type == IVY_DEC_MUX)? "MUX(" : "MAJ(" ); + Ivy_TruthDsdPrint_rec( pFile, VarC >> 1, vTree ); + fprintf( pFile, "%s", (VarC & 1)? "\'" : "" ); + fprintf( pFile, "," ); + Ivy_TruthDsdPrint_rec( pFile, Var1 >> 1, vTree ); + fprintf( pFile, "%s", (Var1 & 1)? "\'" : "" ); + fprintf( pFile, "," ); + Ivy_TruthDsdPrint_rec( pFile, Var0 >> 1, vTree ); + fprintf( pFile, "%s", (Var0 & 1)? "\'" : "" ); + fprintf( pFile, ")" ); + } + else assert( 0 ); +} + + +/**Function************************************************************* + + Synopsis [Prints the decomposition tree.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree ) +{ + fprintf( pFile, "F = " ); + Ivy_TruthDsdPrint_rec( pFile, Vec_IntSize(vTree)-1, vTree ); + fprintf( pFile, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Implement DSD in the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ManDsdConstruct_rec( Ivy_Man_t * p, Vec_Int_t * vFront, int iNode, Vec_Int_t * vTree ) +{ + Ivy_Obj_t * pResult, * pChild, * pNodes[16]; + int Var, i; + // get the node + Ivy_Dec_t Node = Ivy_IntToDec( Vec_IntEntry(vTree, iNode) ); + // compute the node function + if ( Node.Type == IVY_DEC_CONST1 ) + return Ivy_NotCond( Ivy_ManConst1(p), Node.fCompl ); + if ( Node.Type == IVY_DEC_PI ) + { + pResult = Ivy_ManObj( p, Vec_IntEntry(vFront, iNode) ); + return Ivy_NotCond( pResult, Node.fCompl ); + } + if ( Node.Type == IVY_DEC_BUF ) + { + pResult = Ivy_ManDsdConstruct_rec( p, vFront, Node.Fan0 >> 1, vTree ); + return Ivy_NotCond( pResult, Node.fCompl ); + } + if ( Node.Type == IVY_DEC_AND || Node.Type == IVY_DEC_EXOR ) + { + for ( i = 0; i < (int)Node.nFans; i++ ) + { + Var = Ivy_DecGetVar( &Node, i ); + assert( Node.Type == IVY_DEC_AND || (Var & 1) == 0 ); + pChild = Ivy_ManDsdConstruct_rec( p, vFront, Var >> 1, vTree ); + pChild = Ivy_NotCond( pChild, (Var & 1) ); + pNodes[i] = pChild; + } + +// Ivy_MultiEval( pNodes, Node.nFans, Node.Type == IVY_DEC_AND ? IVY_AND : IVY_EXOR ); + + pResult = Ivy_Multi( pNodes, Node.nFans, Node.Type == IVY_DEC_AND ? IVY_AND : IVY_EXOR ); + return Ivy_NotCond( pResult, Node.fCompl ); + } + assert( Node.fCompl == 0 ); + if ( Node.Type == IVY_DEC_MUX || Node.Type == IVY_DEC_MAJ ) + { + int VarC, Var1, Var0; + VarC = Ivy_DecGetVar( &Node, 0 ); + Var1 = Ivy_DecGetVar( &Node, 1 ); + Var0 = Ivy_DecGetVar( &Node, 2 ); + pNodes[0] = Ivy_ManDsdConstruct_rec( p, vFront, VarC >> 1, vTree ); + pNodes[1] = Ivy_ManDsdConstruct_rec( p, vFront, Var1 >> 1, vTree ); + pNodes[2] = Ivy_ManDsdConstruct_rec( p, vFront, Var0 >> 1, vTree ); + assert( Node.Type == IVY_DEC_MAJ || (VarC & 1) == 0 ); + pNodes[0] = Ivy_NotCond( pNodes[0], (VarC & 1) ); + pNodes[1] = Ivy_NotCond( pNodes[1], (Var1 & 1) ); + pNodes[2] = Ivy_NotCond( pNodes[2], (Var0 & 1) ); + if ( Node.Type == IVY_DEC_MUX ) + return Ivy_Mux( pNodes[0], pNodes[1], pNodes[2] ); + else + return Ivy_Maj( pNodes[0], pNodes[1], pNodes[2] ); + } + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Implement DSD in the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ManDsdConstruct( Ivy_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vTree ) +{ + int Entry, i; + // implement latches on the frontier (TEMPORARY!!!) + Vec_IntForEachEntry( vFront, Entry, i ) + Vec_IntWriteEntry( vFront, i, Ivy_LeafId(Entry) ); + // recursively construct the tree + return Ivy_ManDsdConstruct_rec( p, vFront, Vec_IntSize(vTree)-1, vTree ); +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TruthDsdComputePrint( unsigned uTruth ) +{ + static Vec_Int_t * vTree = NULL; + if ( vTree == NULL ) + vTree = Vec_IntAlloc( 12 ); + if ( Ivy_TruthDsd( uTruth, vTree ) ) + Ivy_TruthDsdPrint( stdout, vTree ); + else + printf( "Undecomposable\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TruthTestOne( unsigned uTruth ) +{ + static int Counter = 0; + static Vec_Int_t * vTree = NULL; + // decompose + if ( vTree == NULL ) + vTree = Vec_IntAlloc( 12 ); + + if ( !Ivy_TruthDsd( uTruth, vTree ) ) + { +// printf( "Undecomposable\n" ); + } + else + { +// nTruthDsd++; + printf( "%5d : ", Counter++ ); + Extra_PrintBinary( stdout, &uTruth, 32 ); + printf( " " ); + Ivy_TruthDsdPrint( stdout, vTree ); + if ( uTruth != Ivy_TruthDsdCompute(vTree) ) + printf( "Verification failed.\n" ); + } +// Vec_IntFree( vTree ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TruthTest() +{ + FILE * pFile; + char Buffer[100]; + unsigned uTruth; + int i; + + pFile = fopen( "npn4.txt", "r" ); + for ( i = 0; i < 222; i++ ) +// pFile = fopen( "npn5.txt", "r" ); +// for ( i = 0; i < 616126; i++ ) + { + fscanf( pFile, "%s", Buffer ); + Extra_ReadHexadecimal( &uTruth, Buffer+2, 4 ); +// Extra_ReadHexadecimal( &uTruth, Buffer+2, 5 ); + uTruth |= (uTruth << 16); +// uTruth = ~uTruth; + Ivy_TruthTestOne( uTruth ); + } + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TruthTest3() +{ + FILE * pFile; + char Buffer[100]; + unsigned uTruth; + int i; + + pFile = fopen( "npn3.txt", "r" ); + for ( i = 0; i < 14; i++ ) + { + fscanf( pFile, "%s", Buffer ); + Extra_ReadHexadecimal( &uTruth, Buffer+2, 3 ); + uTruth = uTruth | (uTruth << 8) | (uTruth << 16) | (uTruth << 24); + Ivy_TruthTestOne( uTruth ); + } + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TruthTest5() +{ + FILE * pFile; + char Buffer[100]; + unsigned uTruth; + int i; + +// pFile = fopen( "npn4.txt", "r" ); +// for ( i = 0; i < 222; i++ ) + pFile = fopen( "npn5.txt", "r" ); + for ( i = 0; i < 616126; i++ ) + { + fscanf( pFile, "%s", Buffer ); +// Extra_ReadHexadecimal( &uTruth, Buffer+2, 4 ); + Extra_ReadHexadecimal( &uTruth, Buffer+2, 5 ); +// uTruth |= (uTruth << 16); +// uTruth = ~uTruth; + Ivy_TruthTestOne( uTruth ); + } + fclose( pFile ); +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyMan.c b/src/temp/ivy/ivyMan.c new file mode 100644 index 00000000..04c31f3d --- /dev/null +++ b/src/temp/ivy/ivyMan.c @@ -0,0 +1,207 @@ +/**CFile**************************************************************** + + FileName [ivyMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [AIG manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivy_.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax ) +{ + Ivy_Man_t * p; + Ivy_Obj_t * pObj; + int i, nTotalSize; + // start the manager + p = ALLOC( Ivy_Man_t, 1 ); + memset( p, 0, sizeof(Ivy_Man_t) ); + p->nTravIds = 1; + // AIG nodes + p->nObjsAlloc = 1 + nPis + nPos + nNodesMax; +// p->nObjsAlloc += (p->nObjsAlloc & 1); // make it even + nTotalSize = p->nObjsAlloc + IVY_SANDBOX_SIZE + 1; + p->pObjs = ALLOC( Ivy_Obj_t, nTotalSize ); + memset( p->pObjs, 0, sizeof(Ivy_Obj_t) * nTotalSize ); + // temporary storage for deleted entries + p->vFree = Vec_IntAlloc( 100 ); + // set the node IDs + for ( i = 0, pObj = p->pObjs; i < nTotalSize; i++, pObj++ ) + pObj->Id = i - IVY_SANDBOX_SIZE - 1; + // remember the manager in the first entry + *((Ivy_Man_t **)p->pObjs) = p; + p->pObjs += IVY_SANDBOX_SIZE + 1; + // create the constant node + p->nCreated = 1; + p->ObjIdNext = 1; + Ivy_ManConst1(p)->fPhase = 1; + // create PIs + pObj = Ivy_ManGhost(p); + pObj->Type = IVY_PI; + p->vPis = Vec_IntAlloc( 100 ); + for ( i = 0; i < nPis; i++ ) + Ivy_ObjCreate( pObj ); + // create POs + pObj->Type = IVY_PO; + p->vPos = Vec_IntAlloc( 100 ); + for ( i = 0; i < nPos; i++ ) + Ivy_ObjCreate( pObj ); + // start the table + p->nTableSize = p->nObjsAlloc*5/2+13; + p->pTable = ALLOC( int, p->nTableSize ); + memset( p->pTable, 0, sizeof(int) * p->nTableSize ); + // allocate undo storage + p->nUndosAlloc = 100; + p->pUndos = ALLOC( Ivy_Obj_t, p->nUndosAlloc ); + memset( p->pUndos, 0, sizeof(Ivy_Obj_t) * p->nUndosAlloc ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManStop( Ivy_Man_t * p ) +{ + if ( p->fExtended ) + { + Ivy_Obj_t * pObj; + int i; + Ivy_ManForEachObj( p, pObj, i ) + if ( Ivy_ObjGetFanins(pObj) ) + Vec_IntFree( Ivy_ObjGetFanins(pObj) ); + } + if ( p->vFree ) Vec_IntFree( p->vFree ); + if ( p->vTruths ) Vec_IntFree( p->vTruths ); + if ( p->vPis ) Vec_IntFree( p->vPis ); + if ( p->vPos ) Vec_IntFree( p->vPos ); + FREE( p->pMemory ); + free( p->pObjs - IVY_SANDBOX_SIZE - 1 ); + free( p->pTable ); + free( p->pUndos ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Returns the number of dangling nodes removed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManGrow( Ivy_Man_t * p ) +{ + int i; + assert( p->ObjIdNext == p->nObjsAlloc ); + if ( p->ObjIdNext != p->nObjsAlloc ) + return; +// printf( "Ivy_ObjCreate(): Reallocing the node array.\n" ); + p->nObjsAlloc = 2 * p->nObjsAlloc; + p->pObjs = REALLOC( Ivy_Obj_t, p->pObjs - IVY_SANDBOX_SIZE - 1, p->nObjsAlloc + IVY_SANDBOX_SIZE + 1 ) + IVY_SANDBOX_SIZE + 1; + memset( p->pObjs + p->ObjIdNext, 0, sizeof(Ivy_Obj_t) * p->nObjsAlloc / 2 ); + for ( i = p->nObjsAlloc / 2; i < p->nObjsAlloc; i++ ) + Ivy_ManObj( p, i )->Id = i; +} + +/**Function************************************************************* + + Synopsis [Returns the number of dangling nodes removed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManCleanup( Ivy_Man_t * p ) +{ + Ivy_Obj_t * pNode; + int i, nNodesOld; + nNodesOld = Ivy_ManNodeNum(p); + Ivy_ManForEachNode( p, pNode, i ) + if ( Ivy_ObjRefs(pNode) == 0 ) + Ivy_ObjDelete_rec( pNode, 1 ); + return nNodesOld - Ivy_ManNodeNum(p); +} + +/**Function************************************************************* + + Synopsis [Stops the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManPrintStats( Ivy_Man_t * p ) +{ + printf( "PI/PO = %d/%d ", Ivy_ManPiNum(p), Ivy_ManPoNum(p) ); + if ( p->fExtended ) + { + printf( "Am = %d. ", Ivy_ManAndMultiNum(p) ); + printf( "Xm = %d. ", Ivy_ManExorMultiNum(p) ); + printf( "Lut = %d. ", Ivy_ManLutNum(p) ); + } + else + { + printf( "A = %d. ", Ivy_ManAndNum(p) ); + printf( "X = %d. ", Ivy_ManExorNum(p) ); + printf( "B = %d. ", Ivy_ManBufNum(p) ); + } + printf( "MaxID = %d. ", p->ObjIdNext-1 ); + printf( "All = %d. ", p->nObjsAlloc ); + printf( "Cre = %d. ", p->nCreated ); + printf( "Del = %d. ", p->nDeleted ); + printf( "\n" ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyMulti.c b/src/temp/ivy/ivyMulti.c new file mode 100644 index 00000000..059d1500 --- /dev/null +++ b/src/temp/ivy/ivyMulti.c @@ -0,0 +1,427 @@ +/**CFile**************************************************************** + + FileName [ivyMulti.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Constructing multi-input AND/EXOR gates.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyMulti.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Ivy_Eval_t_ Ivy_Eval_t; +struct Ivy_Eval_t_ +{ + unsigned Mask : 5; // the mask of covered nodes + unsigned Weight : 3; // the number of covered nodes + unsigned Cost : 4; // the number of overlapping nodes + unsigned Level : 12; // the level of this node + unsigned Fan0 : 4; // the first fanin + unsigned Fan1 : 4; // the second fanin +}; + +static Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); +static void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs ); +static int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode ); +static Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Constructs the well-balanced tree of gates.] + + Description [Disregards levels and possible logic sharing.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type ) +{ + Ivy_Obj_t * pObj1, * pObj2; + if ( nObjs == 1 ) + return ppObjs[0]; + pObj1 = Ivy_Multi_rec( ppObjs, nObjs/2, Type ); + pObj2 = Ivy_Multi_rec( ppObjs + nObjs/2, nObjs - nObjs/2, Type ); + return Ivy_Oper( pObj1, pObj2, Type ); +} + +/**Function************************************************************* + + Synopsis [Constructs a balanced tree while taking sharing into account.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgsInit, int nArgs, Ivy_Type_t Type ) +{ + static char NumBits[32] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5}; + static Ivy_Eval_t pEvals[15+15*14/2]; + static Ivy_Obj_t * pArgs[16]; + Ivy_Eval_t * pEva, * pEvaBest; + int nArgsNew, nEvals, i, k; + Ivy_Obj_t * pTemp; + + // consider the case of one argument + assert( nArgs > 0 ); + if ( nArgs == 1 ) + return pArgsInit[0]; + // consider the case of two arguments + if ( nArgs == 2 ) + return Ivy_Oper( pArgsInit[0], pArgsInit[1], Type ); + +//Ivy_MultiEval( pArgsInit, nArgs, Type ); printf( "\n" ); + + // set the initial ones + for ( i = 0; i < nArgs; i++ ) + { + pArgs[i] = pArgsInit[i]; + pEva = pEvals + i; + pEva->Mask = (1 << i); + pEva->Weight = 1; + pEva->Cost = 0; + pEva->Level = Ivy_Regular(pArgs[i])->Level; + pEva->Fan0 = 0; + pEva->Fan1 = 0; + } + + // find the available nodes + pEvaBest = pEvals; + nArgsNew = nArgs; + for ( i = 1; i < nArgsNew; i++ ) + for ( k = 0; k < i; k++ ) + if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)) ) + { + pEva = pEvals + nArgsNew; + pEva->Mask = pEvals[k].Mask | pEvals[i].Mask; + pEva->Weight = NumBits[pEva->Mask]; + pEva->Cost = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask]; + pEva->Level = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level); + pEva->Fan0 = k; + pEva->Fan1 = i; +// assert( pEva->Level == (unsigned)Ivy_ObjLevel(pTemp) ); + // compare + if ( pEvaBest->Weight < pEva->Weight || + pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost || + pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level ) + pEvaBest = pEva; + // save the argument + pArgs[nArgsNew++] = pTemp; + if ( nArgsNew == 15 ) + goto Outside; + } +Outside: + +// printf( "Best = %d.\n", pEvaBest - pEvals ); + + // the case of no common nodes + if ( nArgsNew == nArgs ) + { + Ivy_MultiSort( pArgs, nArgs ); + return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); + } + // the case of one common node + if ( nArgsNew == nArgs + 1 ) + { + assert( pEvaBest - pEvals == nArgs ); + k = 0; + for ( i = 0; i < nArgs; i++ ) + if ( i != (int)pEvaBest->Fan0 && i != (int)pEvaBest->Fan1 ) + pArgs[k++] = pArgs[i]; + pArgs[k++] = pArgs[nArgs]; + assert( k == nArgs - 1 ); + nArgs = k; + Ivy_MultiSort( pArgs, nArgs ); + return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); + } + // the case when there is a node that covers everything + if ( (int)pEvaBest->Mask == ((1 << nArgs) - 1) ) + return Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type ); + + // evaluate node pairs + nEvals = nArgsNew; + for ( i = 1; i < nArgsNew; i++ ) + for ( k = 0; k < i; k++ ) + { + pEva = pEvals + nEvals; + pEva->Mask = pEvals[k].Mask | pEvals[i].Mask; + pEva->Weight = NumBits[pEva->Mask]; + pEva->Cost = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask]; + pEva->Level = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level); + pEva->Fan0 = k; + pEva->Fan1 = i; + // compare + if ( pEvaBest->Weight < pEva->Weight || + pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost || + pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level ) + pEvaBest = pEva; + // save the argument + nEvals++; + } + assert( pEvaBest - pEvals >= nArgsNew ); + +// printf( "Used (%d, %d).\n", pEvaBest->Fan0, pEvaBest->Fan1 ); + + // get the best implementation + pTemp = Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type ); + + // collect those not covered by EvaBest + k = 0; + for ( i = 0; i < nArgs; i++ ) + if ( (pEvaBest->Mask & (1 << i)) == 0 ) + pArgs[k++] = pArgs[i]; + pArgs[k++] = pTemp; + assert( k == nArgs - (int)pEvaBest->Weight + 1 ); + nArgs = k; + Ivy_MultiSort( pArgs, nArgs ); + return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +} + +/**Function************************************************************* + + Synopsis [Implements multi-input AND/EXOR operation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ + Ivy_Obj_t * pNode0, * pNode1; + if ( iNum < nArgs ) + return pArgs[iNum]; + pNode0 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan0, pArgs, nArgs, Type ); + pNode1 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan1, pArgs, nArgs, Type ); + return Ivy_Oper( pNode0, pNode1, Type ); +} + +/**Function************************************************************* + + Synopsis [Selection-sorts the nodes in the decreasing over of level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs ) +{ + Ivy_Obj_t * pTemp; + int i, j, iBest; + + for ( i = 0; i < nArgs-1; i++ ) + { + iBest = i; + for ( j = i+1; j < nArgs; j++ ) + if ( Ivy_Regular(pArgs[j])->Level > Ivy_Regular(pArgs[iBest])->Level ) + iBest = j; + pTemp = pArgs[i]; + pArgs[i] = pArgs[iBest]; + pArgs[iBest] = pTemp; + } +} + +/**Function************************************************************* + + Synopsis [Inserts a new node in the order by levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode ) +{ + Ivy_Obj_t * pNode1, * pNode2; + int i; + // try to find the node in the array + for ( i = 0; i < nArgs; i++ ) + if ( pArray[i] == pNode ) + return nArgs; + // put the node last + pArray[nArgs++] = pNode; + // find the place to put the new node + for ( i = nArgs-1; i > 0; i-- ) + { + pNode1 = pArray[i ]; + pNode2 = pArray[i-1]; + if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level ) + break; + pArray[i ] = pNode2; + pArray[i-1] = pNode1; + } + return nArgs; +} + +/**Function************************************************************* + + Synopsis [Balances the array recursively.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ + Ivy_Obj_t * pNodeNew; + // consider the case of one argument + assert( nArgs > 0 ); + if ( nArgs == 1 ) + return pArgs[0]; + // consider the case of two arguments + if ( nArgs == 2 ) + return Ivy_Oper( pArgs[0], pArgs[1], Type ); + // get the last two nodes + pNodeNew = Ivy_Oper( pArgs[nArgs-1], pArgs[nArgs-2], Type ); + // add the new node + nArgs = Ivy_MultiPushUniqueOrderByLevel( pArgs, nArgs - 2, pNodeNew ); + return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +} + +/**Function************************************************************* + + Synopsis [Implements multi-input AND/EXOR operation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ + Ivy_Obj_t * pTemp; + int i, k; + int nArgsOld = nArgs; + for ( i = 0; i < nArgs; i++ ) + printf( "%d[%d] ", i, Ivy_Regular(pArgs[i])->Level ); + for ( i = 1; i < nArgs; i++ ) + for ( k = 0; k < i; k++ ) + { + pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)); + if ( pTemp != NULL ) + { + printf( "%d[%d]=(%d,%d) ", nArgs, Ivy_Regular(pTemp)->Level, k, i ); + pArgs[nArgs++] = pTemp; + } + } + printf( " ((%d/%d)) ", nArgsOld, nArgs-nArgsOld ); + return NULL; +} + + + +/**Function************************************************************* + + Synopsis [Old code.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ + Ivy_Obj_t * pArgsRef[5], * pTemp; + int i, k, m, nArgsNew, Counter = 0; + + +//Ivy_MultiEval( pArgs, nArgs, Type ); printf( "\n" ); + + + assert( Type == IVY_AND || Type == IVY_EXOR ); + assert( nArgs > 0 ); + if ( nArgs == 1 ) + return pArgs[0]; + + // find the nodes with more than one fanout + nArgsNew = 0; + for ( i = 0; i < nArgs; i++ ) + if ( Ivy_ObjRefs( Ivy_Regular(pArgs[i]) ) > 0 ) + pArgsRef[nArgsNew++] = pArgs[i]; + + // go through pairs + if ( nArgsNew >= 2 ) + for ( i = 0; i < nArgsNew; i++ ) + for ( k = i + 1; k < nArgsNew; k++ ) + if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) ) + Counter++; +// printf( "%d", Counter ); + + // go through pairs + if ( nArgsNew >= 2 ) + for ( i = 0; i < nArgsNew; i++ ) + for ( k = i + 1; k < nArgsNew; k++ ) + if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) ) + { + nArgsNew = 0; + for ( m = 0; m < nArgs; m++ ) + if ( pArgs[m] != pArgsRef[i] && pArgs[m] != pArgsRef[k] ) + pArgs[nArgsNew++] = pArgs[m]; + pArgs[nArgsNew++] = pTemp; + assert( nArgsNew == nArgs - 1 ); + return Ivy_Multi1( pArgs, nArgsNew, Type ); + } + return Ivy_Multi_rec( pArgs, nArgs, Type ); +} + +/**Function************************************************************* + + Synopsis [Old code.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Multi2( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ + assert( Type == IVY_AND || Type == IVY_EXOR ); + assert( nArgs > 0 ); + return Ivy_Multi_rec( pArgs, nArgs, Type ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyObj.c b/src/temp/ivy/ivyObj.c new file mode 100644 index 00000000..5d063525 --- /dev/null +++ b/src/temp/ivy/ivyObj.c @@ -0,0 +1,325 @@ +/**CFile**************************************************************** + + FileName [ivyObj.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Adding/removing objects.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyObj.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Create the new node assuming it does not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost ) +{ + Ivy_Man_t * p = Ivy_ObjMan(pGhost); + Ivy_Obj_t * pObj; + assert( !Ivy_IsComplement(pGhost) ); + assert( Ivy_ObjIsGhost(pGhost) ); + + assert( Ivy_TableLookup(pGhost) == NULL ); + + // realloc the node array + if ( p->ObjIdNext == p->nObjsAlloc ) + { + Ivy_ManGrow( p ); + pGhost = Ivy_ManGhost( p ); + } + // get memory for the new object + if ( Vec_IntSize(p->vFree) > 0 ) + pObj = p->pObjs + Vec_IntPop(p->vFree); + else + pObj = p->pObjs + p->ObjIdNext++; + assert( pObj->Id == pObj - p->pObjs ); + assert( Ivy_ObjIsNone(pObj) ); + // add basic info (fanins, compls, type, init) + Ivy_ObjOverwrite( pObj, pGhost ); + // increment references of the fanins + Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) ); + Ivy_ObjRefsInc( Ivy_ObjFanin1(pObj) ); + // add the node to the structural hash table + Ivy_TableInsert( pObj ); + // compute level + if ( Ivy_ObjIsNode(pObj) ) + pObj->Level = Ivy_ObjLevelNew(pObj); + else if ( Ivy_ObjIsLatch(pObj) ) + pObj->Level = 0; + else if ( Ivy_ObjIsOneFanin(pObj) ) + pObj->Level = Ivy_ObjFanin0(pObj)->Level; + else if ( !Ivy_ObjIsPi(pObj) ) + assert( 0 ); + // mark the fanins in a special way if the node is EXOR + if ( Ivy_ObjIsExor(pObj) ) + { + Ivy_ObjFanin0(pObj)->fExFan = 1; + Ivy_ObjFanin1(pObj)->fExFan = 1; + } + // add PIs/POs to the arrays + if ( Ivy_ObjIsPi(pObj) ) + Vec_IntPush( p->vPis, pObj->Id ); + else if ( Ivy_ObjIsPo(pObj) ) + Vec_IntPush( p->vPos, pObj->Id ); + // update node counters of the manager + p->nObjs[Ivy_ObjType(pObj)]++; + p->nCreated++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Create the new node assuming it does not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type ) +{ + Ivy_Obj_t * pObj; + assert( Type == IVY_ANDM || Type == IVY_EXORM || Type == IVY_LUT ); + // realloc the node array + if ( p->ObjIdNext == p->nObjsAlloc ) + Ivy_ManGrow( p ); + // create the new node + pObj = p->pObjs + p->ObjIdNext; + assert( pObj->Id == p->ObjIdNext ); + p->ObjIdNext++; + pObj->Type = Type; + // update node counters of the manager + p->nObjs[Type]++; + p->nCreated++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Connect the object to the fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin ) +{ + assert( !Ivy_IsComplement(pObj) ); + assert( Ivy_ObjIsOneFanin(pObj) ); + assert( Ivy_ObjFaninId0(pObj) == 0 ); + // add the first fanin + pObj->fComp0 = Ivy_IsComplement(pFanin); + pObj->Fanin0 = Ivy_Regular(pFanin)->Id; + // increment references of the fanins + Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) ); + // add the node to the structural hash table + Ivy_TableInsert( pObj ); +} + +/**Function************************************************************* + + Synopsis [Deletes the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop ) +{ + Ivy_Man_t * p; + assert( !Ivy_IsComplement(pObj) ); + assert( Ivy_ObjRefs(pObj) == 0 ); + // remove connections + Ivy_ObjRefsDec(Ivy_ObjFanin0(pObj)); + Ivy_ObjRefsDec(Ivy_ObjFanin1(pObj)); + // remove the node from the structural hash table + Ivy_TableDelete( pObj ); + // update node counters of the manager + p = Ivy_ObjMan(pObj); + p->nObjs[pObj->Type]--; + p->nDeleted++; + // remove PIs/POs from the arrays + if ( Ivy_ObjIsPi(pObj) ) + Vec_IntRemove( p->vPis, pObj->Id ); + else if ( Ivy_ObjIsPo(pObj) ) + Vec_IntRemove( p->vPos, pObj->Id ); + // recorde the deleted node + if ( p->fRecording ) + Ivy_ManUndoRecord( p, pObj ); + // clean the node's memory + Ivy_ObjClean( pObj ); + // remember the entry + if ( fFreeTop ) + Vec_IntPush( p->vFree, pObj->Id ); +} + +/**Function************************************************************* + + Synopsis [Deletes the MFFC of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop ) +{ + Ivy_Obj_t * pFanin0, * pFanin1; + assert( !Ivy_IsComplement(pObj) ); + assert( !Ivy_ObjIsPo(pObj) && !Ivy_ObjIsNone(pObj) ); + if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsPi(pObj) ) + return; + pFanin0 = Ivy_ObjFanin0(pObj); + pFanin1 = Ivy_ObjFanin1(pObj); + Ivy_ObjDelete( pObj, fFreeTop ); + if ( !Ivy_ObjIsNone(pFanin0) && Ivy_ObjRefs(pFanin0) == 0 ) + Ivy_ObjDelete_rec( pFanin0, 1 ); + if ( !Ivy_ObjIsNone(pFanin1) && Ivy_ObjRefs(pFanin1) == 0 ) + Ivy_ObjDelete_rec( pFanin1, 1 ); +} + +/**Function************************************************************* + + Synopsis [Replaces one object by another.] + + Description [Both objects are currently in the manager. The new object + (pObjNew) should be used instead of the old object (pObjOld). If the + new object is complemented or used, the buffer is added.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ObjReplace( Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop ) +{ + int nRefsOld; + // the object to be replaced cannot be complemented + assert( !Ivy_IsComplement(pObjOld) ); + // the object to be replaced cannot be a terminal + assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsTerm(pObjOld) ); + // the object to be used cannot be a PO or assert + assert( !Ivy_ObjIsPo(Ivy_Regular(pObjNew)) ); + // the object cannot be the same + assert( pObjOld != Ivy_Regular(pObjNew) ); + // if the new object is complemented or already used, add the buffer + if ( Ivy_IsComplement(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) ) + pObjNew = Ivy_ObjCreate( Ivy_ObjCreateGhost(pObjNew, Ivy_ObjConst1(pObjOld), IVY_BUF, IVY_INIT_NONE) ); + assert( !Ivy_IsComplement(pObjNew) ); + // remember the reference counter + nRefsOld = pObjOld->nRefs; + pObjOld->nRefs = 0; + // delete the old object + if ( fDeleteOld ) + Ivy_ObjDelete_rec( pObjOld, fFreeTop ); + // transfer the old object + assert( Ivy_ObjRefs(pObjNew) == 0 ); + Ivy_ObjOverwrite( pObjOld, pObjNew ); + pObjOld->nRefs = nRefsOld; + // update the hash table + Ivy_TableUpdate( pObjNew, pObjOld->Id ); + // create the object that was taken over by pObjOld + Ivy_ObjClean( pObjNew ); + // remember the entry + Vec_IntPush( Ivy_ObjMan(pObjOld)->vFree, pObjNew->Id ); +} + +/**Function************************************************************* + + Synopsis [Returns the first real fanins (not a buffer/inverter).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin ) +{ + if ( iFanin == 0 ) + { + if ( Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) ) + return Ivy_NotCond( Ivy_NodeRealFanin_rec(Ivy_ObjFanin0(pNode), 0), Ivy_ObjFaninC0(pNode) ); + else + return Ivy_ObjChild0(pNode); + } + else + { + if ( Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) ) + return Ivy_NotCond( Ivy_NodeRealFanin_rec(Ivy_ObjFanin1(pNode), 0), Ivy_ObjFaninC1(pNode) ); + else + return Ivy_ObjChild1(pNode); + } +} + +/**Function************************************************************* + + Synopsis [Fixes buffer fanins.] + + Description [This situation happens because NodeReplace is a lazy + procedure, which does not propagate the change to the fanouts but + instead records the change in the form of a buf/inv node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_NodeFixBufferFanins( Ivy_Obj_t * pNode ) +{ + Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult; + assert( Ivy_ObjIsNode(pNode) ); + if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) && !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) ) + return; + // get the real fanins + pFanReal0 = Ivy_NodeRealFanin_rec( pNode, 0 ); + pFanReal1 = Ivy_NodeRealFanin_rec( pNode, 1 ); + // get the new node + pResult = Ivy_Oper( pFanReal0, pFanReal1, Ivy_ObjType(pNode) ); + // perform the replacement + Ivy_ObjReplace( pNode, pResult, 1, 0 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyOper.c b/src/temp/ivy/ivyOper.c new file mode 100644 index 00000000..a10ba343 --- /dev/null +++ b/src/temp/ivy/ivyOper.c @@ -0,0 +1,254 @@ +/**CFile**************************************************************** + + FileName [ivyOper.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [AIG operations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyOper.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// procedure to detect an EXOR gate +static inline int Ivy_ObjIsExorType( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Obj_t ** ppFan0, Ivy_Obj_t ** ppFan1 ) +{ + if ( !Ivy_IsComplement(p0) || !Ivy_IsComplement(p1) ) + return 0; + p0 = Ivy_Regular(p0); + p1 = Ivy_Regular(p1); + if ( !Ivy_ObjIsAnd(p0) || !Ivy_ObjIsAnd(p1) ) + return 0; + if ( Ivy_ObjFanin0(p0) != Ivy_ObjFanin0(p1) || Ivy_ObjFanin1(p0) != Ivy_ObjFanin1(p1) ) + return 0; + if ( Ivy_ObjFaninC0(p0) == Ivy_ObjFaninC0(p1) || Ivy_ObjFaninC1(p0) == Ivy_ObjFaninC1(p1) ) + return 0; + *ppFan0 = Ivy_ObjChild0(p0); + *ppFan1 = Ivy_ObjChild1(p0); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Perform one operation.] + + Description [The argument nodes can be complemented.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type ) +{ + if ( Type == IVY_AND ) + return Ivy_And( p0, p1 ); + if ( Type == IVY_EXOR ) + return Ivy_Exor( p0, p1 ); + assert( 0 ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Performs canonicization step.] + + Description [The argument nodes can be complemented.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ) +{ + Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0)); + Ivy_Obj_t * pFan0, * pFan1; + // check trivial cases + if ( p0 == p1 ) + return p0; + if ( p0 == Ivy_Not(p1) ) + return Ivy_Not(pConst1); + if ( Ivy_Regular(p0) == pConst1 ) + return p0 == pConst1 ? p1 : Ivy_Not(pConst1); + if ( Ivy_Regular(p1) == pConst1 ) + return p1 == pConst1 ? p0 : Ivy_Not(pConst1); + // check if it can be an EXOR gate + if ( Ivy_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) ) + return Ivy_CanonExor( pFan0, pFan1 ); + return Ivy_CanonAnd( p0, p1 ); +} + +/**Function************************************************************* + + Synopsis [Performs canonicization step.] + + Description [The argument nodes can be complemented.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Exor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ) +{ + Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0)); + // check trivial cases + if ( p0 == p1 ) + return Ivy_Not(pConst1); + if ( p0 == Ivy_Not(p1) ) + return pConst1; + if ( Ivy_Regular(p0) == pConst1 ) + return Ivy_NotCond( p1, p0 == pConst1 ); + if ( Ivy_Regular(p1) == pConst1 ) + return Ivy_NotCond( p0, p1 == pConst1 ); + // check the table + return Ivy_CanonExor( p0, p1 ); +} + +/**Function************************************************************* + + Synopsis [Performs canonicization step.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Latch( Ivy_Obj_t * pObj, Ivy_Init_t Init ) +{ + return Ivy_CanonLatch( pObj, Init ); +} + +/**Function************************************************************* + + Synopsis [Implements Boolean OR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Or( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ) +{ + return Ivy_Not( Ivy_And( Ivy_Not(p0), Ivy_Not(p1) ) ); +} + +/**Function************************************************************* + + Synopsis [Implements ITE operation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 ) +{ + Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0)); + Ivy_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp; + int Count0, Count1; + // consider trivial cases + if ( p0 == Ivy_Not(p1) ) + return Ivy_Exor( pC, p0 ); + // other cases can be added + // implement the first MUX (F = C * x1 + C' * x0) + pTempA1 = Ivy_TableLookup( Ivy_ObjCreateGhost(pC, p1, IVY_AND, IVY_INIT_NONE) ); + pTempA2 = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pC), p0, IVY_AND, IVY_INIT_NONE) ); + if ( pTempA1 && pTempA2 ) + { + pTemp = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pTempA1), Ivy_Not(pTempA2), IVY_AND, IVY_INIT_NONE) ); + if ( pTemp ) return Ivy_Not(pTemp); + } + Count0 = (pTempA1 != NULL) + (pTempA2 != NULL); + // implement the second MUX (F' = C * x1' + C' * x0') + pTempB1 = Ivy_TableLookup( Ivy_ObjCreateGhost(pC, Ivy_Not(p1), IVY_AND, IVY_INIT_NONE) ); + pTempB2 = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pC), Ivy_Not(p0), IVY_AND, IVY_INIT_NONE) ); + if ( pTempB1 && pTempB2 ) + { + pTemp = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pTempB1), Ivy_Not(pTempB2), IVY_AND, IVY_INIT_NONE) ); + if ( pTemp ) return pTemp; + } + Count1 = (pTempB1 != NULL) + (pTempB2 != NULL); + // compare and decide which one to implement + if ( Count0 >= Count1 ) + { + pTempA1 = pTempA1? pTempA1 : Ivy_And(pC, p1); + pTempA2 = pTempA2? pTempA2 : Ivy_And(Ivy_Not(pC), p0); + return Ivy_Or( pTempA1, pTempA2 ); + } + pTempB1 = pTempB1? pTempB1 : Ivy_And(pC, Ivy_Not(p1)); + pTempB2 = pTempB2? pTempB2 : Ivy_And(Ivy_Not(pC), Ivy_Not(p0)); + return Ivy_Not( Ivy_Or( pTempB1, pTempB2 ) ); + +// return Ivy_Or( Ivy_And(pC, p1), Ivy_And(Ivy_Not(pC), p0) ); +} + +/**Function************************************************************* + + Synopsis [Implements ITE operation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC ) +{ + return Ivy_Or( Ivy_Or(Ivy_And(pA, pB), Ivy_And(pA, pC)), Ivy_And(pB, pC) ); +} + +/**Function************************************************************* + + Synopsis [Implements the miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Miter( Vec_Ptr_t * vPairs ) +{ + int i; + assert( vPairs->nSize > 0 ); + 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] = Ivy_Not( Ivy_Exor( vPairs->pArray[i], vPairs->pArray[i+1] ) ); + vPairs->nSize = vPairs->nSize/2; + return Ivy_Not( Ivy_Multi_rec( (Ivy_Obj_t **)vPairs->pArray, vPairs->nSize, IVY_AND ) ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyRewrite.c b/src/temp/ivy/ivyRewrite.c new file mode 100644 index 00000000..031db9bc --- /dev/null +++ b/src/temp/ivy/ivyRewrite.c @@ -0,0 +1,365 @@ +/**CFile**************************************************************** + + FileName [ivyRewrite.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [AIG rewriting.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyRewrite.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static unsigned Ivy_ManSeqFindTruth( Ivy_Obj_t * pNode, Vec_Int_t * vFront ); +static void Ivy_ManSeqCollectCone( Ivy_Obj_t * pNode, Vec_Int_t * vCone ); +static int Ivy_ManSeqGetCost( Ivy_Man_t * p, Vec_Int_t * vCone ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs Boolean rewriting of sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ) +{ + Vec_Int_t * vNodes, * vFront, * vInside, * vTree; + Ivy_Obj_t * pNode, * pNodeNew, * pTemp; + int i, k, nCostOld, nCostInt, nCostInt2, nCostNew, RetValue, Entry, nRefsSaved, nInputs; + int clk, clkCut = 0, clkTru = 0, clkDsd = 0, clkUpd = 0, clkStart = clock(); + unsigned uTruth; + + nInputs = 4; + vTree = Vec_IntAlloc( 8 ); + vFront = Vec_IntAlloc( 8 ); + vInside = Vec_IntAlloc( 50 ); + vNodes = Ivy_ManDfs( p ); + Ivy_ManForEachNodeVec( p, vNodes, pNode, i ) + { + if ( Ivy_ObjIsBuf(pNode) ) + continue; + // fix the fanin buffer problem + Ivy_NodeFixBufferFanins( pNode ); + if ( Ivy_ObjIsBuf(pNode) ) + continue; + + // find one sequential cut rooted at this node +clk = clock(); + Ivy_ManSeqFindCut( pNode, vFront, vInside, nInputs ); +clkCut += clock() - clk; + // compute the truth table of the cut +clk = clock(); + uTruth = Ivy_ManSeqFindTruth( pNode, vFront ); +clkTru += clock() - clk; + // decompose the truth table +clk = clock(); + RetValue = Ivy_TruthDsd( uTruth, vTree ); +clkDsd += clock() - clk; + if ( !RetValue ) + continue; // DSD does not exist +// Ivy_TruthDsdPrint( stdout, vTree ); + +clk = clock(); + // remember the cost of the current network + nCostOld = Ivy_ManGetCost(p); + // increment references of the cut variables + Vec_IntForEachEntry( vFront, Entry, k ) + { + pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry)); + Ivy_ObjRefsInc( pTemp ); + } + // dereference and record undo + nRefsSaved = pNode->nRefs; pNode->nRefs = 0; + Ivy_ManUndoStart( p ); + Ivy_ObjDelete_rec( pNode, 0 ); + Ivy_ManUndoStop( p ); + pNode->nRefs = nRefsSaved; + + // get the intermediate cost + nCostInt = Ivy_ManGetCost(p); + +// printf( "Removed by dereferencing = %d.\n", nCostOld - nCostInt ); + + // construct the new logic cone + pNodeNew = Ivy_ManDsdConstruct( p, vFront, vTree ); + // remember the cost + nCostNew = Ivy_ManGetCost(p); + +// printf( "Added by dereferencing = %d.\n", nCostInt - nCostNew ); +// nCostNew = nCostNew; + +/* + if ( Ivy_Regular(pNodeNew)->nRefs == 0 ) + Ivy_ObjDelete_rec( Ivy_Regular(pNodeNew), 1 ); + // get the intermediate cost + nCostInt2 = Ivy_ManGetCost(p); + assert( nCostInt == nCostInt2 ); + + Ivy_ManUndoPerform( p, pNode ); + pNode->nRefs = nRefsSaved; + + Vec_IntForEachEntry( vFront, Entry, k ) + { +// pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry)); + pTemp = Ivy_ManObj(p, Entry); + Ivy_ObjRefsDec( pTemp ); + } +clkUpd += clock() - clk; + continue; +*/ + + // detect the case when they are exactly the same +// if ( pNodeNew == pNode ) +// continue; + + // compare the costs + if ( nCostOld > nCostNew || nCostOld == nCostNew && fUseZeroCost ) + { // accept the change +// printf( "NODES GAINED = %d\n", nCostOld - nCostNew ); + + Ivy_ObjReplace( pNode, pNodeNew, 0, 1 ); + pNode->nRefs = nRefsSaved; + } + else + { // reject change +// printf( "Rejected\n" ); + + if ( Ivy_Regular(pNodeNew)->nRefs == 0 ) + Ivy_ObjDelete_rec( Ivy_Regular(pNodeNew), 1 ); + + // get the intermediate cost + nCostInt2 = Ivy_ManGetCost(p); + assert( nCostInt == nCostInt2 ); + + // reconstruct the old node + Ivy_ManUndoPerform( p, pNode ); + pNode->nRefs = nRefsSaved; + } + // decrement references of the cut variables + Vec_IntForEachEntry( vFront, Entry, k ) + { +// pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry)); + pTemp = Ivy_ManObj(p, Entry); + if ( Ivy_ObjIsNone(pTemp) ) + continue; + Ivy_ObjRefsDec( pTemp ); + if ( Ivy_ObjRefs(pTemp) == 0 ) + Ivy_ObjDelete_rec( pTemp, 1 ); + } + +clkUpd += clock() - clk; + } + +PRT( "Cut ", clkCut ); +PRT( "Truth ", clkTru ); +PRT( "DSD ", clkDsd ); +PRT( "Update ", clkUpd ); +PRT( "TOTAL ", clock() - clkStart ); + + Vec_IntFree( vTree ); + Vec_IntFree( vFront ); + Vec_IntFree( vInside ); + Vec_IntFree( vNodes ); + + if ( !Ivy_ManCheck(p) ) + { + printf( "Ivy_ManSeqRewrite(): The check has failed.\n" ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes the truth table of the sequential cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Ivy_ManSeqFindTruth_rec( Ivy_Man_t * p, unsigned Node, Vec_Int_t * vFront ) +{ + static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; + unsigned uTruth0, uTruth1; + Ivy_Obj_t * pNode; + int nLatches, Number; + // consider the case of a constant + if ( Node == 0 ) + return ~((unsigned)0); + // try to find this node in the frontier + Number = Vec_IntFind( vFront, Node ); + if ( Number >= 0 ) + return uMasks[Number]; + // get the node + pNode = Ivy_ManObj( p, Ivy_LeafId(Node) ); + assert( !Ivy_ObjIsPi(pNode) && !Ivy_ObjIsConst1(pNode) ); + // get the number of latches + nLatches = Ivy_LeafLat(Node) + Ivy_ObjIsLatch(pNode); + // expand the first fanin + uTruth0 = Ivy_ManSeqFindTruth_rec( p, Ivy_LeafCreate(Ivy_ObjFaninId0(pNode), nLatches), vFront ); + if ( Ivy_ObjFaninC0(pNode) ) + uTruth0 = ~uTruth0; + // quit if this is the one fanin node + if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ) + return uTruth0; + assert( Ivy_ObjIsNode(pNode) ); + // expand the second fanin + uTruth1 = Ivy_ManSeqFindTruth_rec( p, Ivy_LeafCreate(Ivy_ObjFaninId1(pNode), nLatches), vFront ); + if ( Ivy_ObjFaninC1(pNode) ) + uTruth1 = ~uTruth1; + // return the truth table + return Ivy_ObjIsAnd(pNode)? uTruth0 & uTruth1 : uTruth0 ^ uTruth1; +} + +/**Function************************************************************* + + Synopsis [Computes the truth table of the sequential cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Ivy_ManSeqFindTruth( Ivy_Obj_t * pNode, Vec_Int_t * vFront ) +{ + assert( Ivy_ObjIsNode(pNode) ); + return Ivy_ManSeqFindTruth_rec( Ivy_ObjMan(pNode), Ivy_LeafCreate(pNode->Id, 0), vFront ); +} + + +/**Function************************************************************* + + Synopsis [Recursively dereferences the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManSeqDeref_rec( Ivy_Obj_t * pNode, Vec_Int_t * vCone ) +{ + Ivy_Obj_t * pFan; + assert( !Ivy_IsComplement(pNode) ); + assert( !Ivy_ObjIsNone(pNode) ); + if ( Ivy_ObjIsPi(pNode) ) + return; + // deref the first fanin + pFan = Ivy_ObjFanin0(pNode); + Ivy_ObjRefsDec( pFan ); + if ( Ivy_ObjRefs( pFan ) == 0 ) + Ivy_ManSeqDeref_rec( pFan, vCone ); + // deref the second fanin + pFan = Ivy_ObjFanin1(pNode); + Ivy_ObjRefsDec( pFan ); + if ( Ivy_ObjRefs( pFan ) == 0 ) + Ivy_ManSeqDeref_rec( pFan, vCone ); + // save the node + Vec_IntPush( vCone, pNode->Id ); +} + +/**Function************************************************************* + + Synopsis [Recursively references the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManSeqRef_rec( Ivy_Obj_t * pNode ) +{ + Ivy_Obj_t * pFan; + assert( !Ivy_IsComplement(pNode) ); + assert( !Ivy_ObjIsNone(pNode) ); + if ( Ivy_ObjIsPi(pNode) ) + return; + // ref the first fanin + pFan = Ivy_ObjFanin0(pNode); + if ( Ivy_ObjRefs( pFan ) == 0 ) + Ivy_ManSeqRef_rec( pFan ); + Ivy_ObjRefsInc( pFan ); + // ref the second fanin + pFan = Ivy_ObjFanin1(pNode); + if ( Ivy_ObjRefs( pFan ) == 0 ) + Ivy_ManSeqRef_rec( pFan ); + Ivy_ObjRefsInc( pFan ); +} + +/**Function************************************************************* + + Synopsis [Collect MFFC of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManSeqCollectCone( Ivy_Obj_t * pNode, Vec_Int_t * vCone ) +{ + Vec_IntClear( vCone ); + Ivy_ManSeqDeref_rec( pNode, vCone ); + Ivy_ManSeqRef_rec( pNode ); +} + +/**Function************************************************************* + + Synopsis [Computes the cost of the logic cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManSeqGetCost( Ivy_Man_t * p, Vec_Int_t * vCone ) +{ + Ivy_Obj_t * pObj; + int i, Cost = 0; + Ivy_ManForEachNodeVec( p, vCone, pObj, i ) + { + if ( Ivy_ObjIsAnd(pObj) ) + Cost += 1; + else if ( Ivy_ObjIsExor(pObj) ) + Cost += 2; + } + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivySeq.c b/src/temp/ivy/ivySeq.c new file mode 100644 index 00000000..d8fbdd9b --- /dev/null +++ b/src/temp/ivy/ivySeq.c @@ -0,0 +1,101 @@ +/**CFile**************************************************************** + + FileName [ivySeq.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivySeq.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Converts a combinational AIG manager into a sequential one.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches ) +{ + Vec_Int_t * vNodes; + Ivy_Obj_t * pObj, * pObjNew, * pFan0, * pFan1; + int i, fChanges; + assert( nLatches < Ivy_ManPiNum(p) && nLatches < Ivy_ManPoNum(p) ); + // change POs into buffers + assert( Ivy_ManPoNum(p) == Vec_IntSize(p->vPos) ); + for ( i = Ivy_ManPoNum(p) - nLatches; i < Vec_IntSize(p->vPos); i++ ) + { + pObj = Ivy_ManPo(p, i); + pObj->Type = IVY_BUF; + } + // change PIs into latches and connect them to the corresponding POs + assert( Ivy_ManPiNum(p) == Vec_IntSize(p->vPis) ); + for ( i = Ivy_ManPiNum(p) - nLatches; i < Vec_IntSize(p->vPis); i++ ) + { + pObj = Ivy_ManPi(p, i); + pObj->Type = IVY_LATCH; + Ivy_ObjConnect( pObj, Ivy_ManPo(p, Ivy_ManPoNum(p) - Ivy_ManPiNum(p)) ); + } + // shrink the array + Vec_IntShrink( p->vPis, Ivy_ManPiNum(p) - nLatches ); + Vec_IntShrink( p->vPos, Ivy_ManPoNum(p) - nLatches ); + // update the counters of different objects + p->nObjs[IVY_PI] -= nLatches; + p->nObjs[IVY_PO] -= nLatches; + p->nObjs[IVY_BUF] += nLatches; + p->nObjs[IVY_LATCH] += nLatches; + // perform structural hashing while there are changes + fChanges = 1; + while ( fChanges ) + { + fChanges = 0; + vNodes = Ivy_ManDfs( p ); + Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) + { + if ( Ivy_ObjIsBuf(pObj) ) + continue; + pFan0 = Ivy_NodeRealFanin_rec( pObj, 0 ); + pFan1 = Ivy_NodeRealFanin_rec( pObj, 1 ); + if ( Ivy_ObjIsAnd(pObj) ) + pObjNew = Ivy_And(pFan0, pFan1); + else if ( Ivy_ObjIsExor(pObj) ) + pObjNew = Ivy_Exor(pFan0, pFan1); + else assert( 0 ); + if ( pObjNew == pObj ) + continue; + Ivy_ObjReplace( pObj, pObjNew, 1, 1 ); + fChanges = 1; + } + Vec_IntFree( vNodes ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyTable.c b/src/temp/ivy/ivyTable.c new file mode 100644 index 00000000..815caa29 --- /dev/null +++ b/src/temp/ivy/ivyTable.c @@ -0,0 +1,237 @@ +/**CFile**************************************************************** + + FileName [ivyTable.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Structural hashing table.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// hashing the node +static unsigned Ivy_Hash( Ivy_Obj_t * pObj, int TableSize ) +{ + unsigned Key = Ivy_ObjIsExor(pObj) * 1699; + Key ^= Ivy_ObjFaninId0(pObj) * 7937; + Key ^= Ivy_ObjFaninId1(pObj) * 2971; + Key ^= Ivy_ObjFaninC0(pObj) * 911; + Key ^= Ivy_ObjFaninC1(pObj) * 353; + Key ^= Ivy_ObjInit(pObj) * 911; + return Key % TableSize; +} + +// returns the place where this node is stored (or should be stored) +static int * Ivy_TableFind( Ivy_Obj_t * pObj ) +{ + Ivy_Man_t * p; + int i; + assert( Ivy_ObjIsHash(pObj) ); + p = Ivy_ObjMan(pObj); + for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize ) + if ( p->pTable[i] == pObj->Id ) + break; + return p->pTable + i; +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Checks if node with the given attributes is in the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_TableLookup( Ivy_Obj_t * pObj ) +{ + Ivy_Man_t * p; + Ivy_Obj_t * pEntry; + int i; + assert( !Ivy_IsComplement(pObj) ); + if ( !Ivy_ObjIsHash(pObj) ) + return NULL; + assert( Ivy_ObjIsLatch(pObj) || Ivy_ObjFaninId0(pObj) > 0 ); + assert( Ivy_ObjFaninId0(pObj) == 0 || Ivy_ObjFaninId0(pObj) > Ivy_ObjFaninId1(pObj) ); + p = Ivy_ObjMan(pObj); + for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize ) + { + pEntry = Ivy_ObjObj( pObj, p->pTable[i] ); + if ( Ivy_ObjFaninId0(pEntry) == Ivy_ObjFaninId0(pObj) && + Ivy_ObjFaninId1(pEntry) == Ivy_ObjFaninId1(pObj) && + Ivy_ObjFaninC0(pEntry) == Ivy_ObjFaninC0(pObj) && + Ivy_ObjFaninC1(pEntry) == Ivy_ObjFaninC1(pObj) && + Ivy_ObjInit(pEntry) == Ivy_ObjInit(pObj) && + Ivy_ObjType(pEntry) == Ivy_ObjType(pObj) ) + return Ivy_ObjObj( pObj, p->pTable[i] ); + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [Adds the node to the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TableInsert( Ivy_Obj_t * pObj ) +{ + int * pPlace; + assert( !Ivy_IsComplement(pObj) ); + if ( !Ivy_ObjIsHash(pObj) ) + return; + pPlace = Ivy_TableFind( pObj ); + assert( *pPlace == 0 ); + *pPlace = pObj->Id; +} + +/**Function************************************************************* + + Synopsis [Deletes the node from the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TableDelete( Ivy_Obj_t * pObj ) +{ + Ivy_Man_t * p; + Ivy_Obj_t * pEntry; + int i, * pPlace; + assert( !Ivy_IsComplement(pObj) ); + if ( !Ivy_ObjIsHash(pObj) ) + return; + pPlace = Ivy_TableFind( pObj ); + assert( *pPlace == pObj->Id ); // node should be in the table + *pPlace = 0; + // rehash the adjacent entries + p = Ivy_ObjMan(pObj); + i = pPlace - p->pTable; + for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize ) + { + pEntry = Ivy_ObjObj( pObj, p->pTable[i] ); + p->pTable[i] = 0; + Ivy_TableInsert( pEntry ); + } +} + +/**Function************************************************************* + + Synopsis [Updates the table to point to the new node.] + + Description [If the old node (pObj) is in the table, updates the table + to point to an object with different ID (ObjIdNew). The table should + not contain an object with ObjIdNew (this is currently not checked).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TableUpdate( Ivy_Obj_t * pObj, int ObjIdNew ) +{ + int * pPlace; + assert( !Ivy_IsComplement(pObj) ); + if ( !Ivy_ObjIsHash(pObj) ) + return; + pPlace = Ivy_TableFind( pObj ); + assert( *pPlace == pObj->Id ); // node should be in the table + *pPlace = ObjIdNew; +} + +/**Function************************************************************* + + Synopsis [Count the number of nodes in the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_TableCountEntries( Ivy_Man_t * p ) +{ + int i, Counter = 0; + for ( i = 0; i < p->nTableSize; i++ ) + Counter += (p->pTable[i] != 0); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Resizes the table.] + + Description [Typically this procedure should not be called.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_TableResize( Ivy_Man_t * p ) +{ + int * pTableOld, * pPlace; + int nTableSizeOld, Counter, e, clk; + assert( 0 ); +clk = clock(); + // save the old table + pTableOld = p->pTable; + nTableSizeOld = p->nTableSize; + // get the new table + p->nTableSize = p->nObjsAlloc*5/2+13; + p->pTable = ALLOC( int, p->nTableSize ); + memset( p->pTable, 0, sizeof(int) * p->nTableSize ); + // rehash the entries from the old table + Counter = 0; + for ( e = 0; e < nTableSizeOld; e++ ) + { + if ( pTableOld[e] == 0 ) + continue; + Counter++; + // get the place where this entry goes in the table table + pPlace = Ivy_TableFind( Ivy_ManObj(p, pTableOld[e]) ); + assert( *pPlace == 0 ); // should not be in the table + *pPlace = pTableOld[e]; + } + assert( Counter == Ivy_ManHashObjNum(p) ); +// printf( "Increasing the structural table size from %6d to %6d. ", p->nTableSize, nTableSizeNew ); +// PRT( "Time", clock() - clk ); + // replace the table and the parameters + free( p->pTable ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyUndo.c b/src/temp/ivy/ivyUndo.c new file mode 100644 index 00000000..6612bf42 --- /dev/null +++ b/src/temp/ivy/ivyUndo.c @@ -0,0 +1,165 @@ +/**CFile**************************************************************** + + FileName [ivyUndo.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Recording the results of recent deletion of logic cone.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyUndo.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManUndoStart( Ivy_Man_t * p ) +{ + p->fRecording = 1; + p->nUndos = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManUndoStop( Ivy_Man_t * p ) +{ + p->fRecording = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManUndoRecord( Ivy_Man_t * p, Ivy_Obj_t * pObj ) +{ + Ivy_Obj_t * pObjUndo; + if ( p->nUndos >= p->nUndosAlloc ) + { + printf( "Ivy_ManUndoRecord(): Not enough memory for undo.\n" ); + return; + } + pObjUndo = p->pUndos + p->nUndos++; + // required data for Ivy_ObjCreateGhost() + pObjUndo->Type = pObj->Type; + pObjUndo->Init = pObj->Init; + pObjUndo->Fanin0 = pObj->Fanin0; + pObjUndo->Fanin1 = pObj->Fanin1; + pObjUndo->fComp0 = pObj->fComp0; + pObjUndo->fComp1 = pObj->fComp1; + // additional data + pObjUndo->Id = pObj->Id; + pObjUndo->nRefs = pObj->nRefs; + pObjUndo->Level = pObj->Level; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Vec_IntPutLast( Vec_Int_t * vFree, int Last ) +{ + int Place, i; + // find the entry + Place = Vec_IntFind( vFree, Last ); + if ( Place == -1 ) + return 0; + // shift entries by one + assert( vFree->pArray[Place] == Last ); + for ( i = Place; i < Vec_IntSize(vFree) - 1; i++ ) + vFree->pArray[i] = vFree->pArray[i+1]; + // put the entry in the end + vFree->pArray[i] = Last; + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManUndoPerform( Ivy_Man_t * p, Ivy_Obj_t * pRoot ) +{ + Ivy_Obj_t * pObjUndo, * pObjNew; + int i; + assert( p->nUndos > 0 ); + assert( p->fRecording == 0 ); + for ( i = p->nUndos - 1; i >= 0; i-- ) + { + // get the undo object + pObjUndo = p->pUndos + i; + // if this is the last object + if ( i == 0 ) + Vec_IntPush( p->vFree, pRoot->Id ); + else + Vec_IntPutLast( p->vFree, pObjUndo->Id ); + // create the new object + pObjNew = Ivy_ObjCreate( Ivy_ObjCreateGhost2( p, pObjUndo) ); + pObjNew->nRefs = pObjUndo->nRefs; + pObjNew->Level = pObjUndo->Level; + // make sure the object is created in the same place as before + assert( pObjNew->Id == pObjUndo->Id ); + } + p->nUndos = 0; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyUtil.c b/src/temp/ivy/ivyUtil.c new file mode 100644 index 00000000..590affd7 --- /dev/null +++ b/src/temp/ivy/ivyUtil.c @@ -0,0 +1,369 @@ +/**CFile**************************************************************** + + FileName [ivyUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Various procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Increments the current traversal ID of the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManIncrementTravId( Ivy_Man_t * p ) +{ + if ( p->nTravIds >= (1<<30)-1 - 1000 ) + Ivy_ManCleanTravId( p ); + p->nTravIds++; +} + +/**Function************************************************************* + + Synopsis [Sets the DFS ordering of the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManCleanTravId( Ivy_Man_t * p ) +{ + Ivy_Obj_t * pObj; + int i; + p->nTravIds = 1; + Ivy_ManForEachObj( p, pObj, i ) + pObj->TravId = 0; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ObjIsMuxType( Ivy_Obj_t * pNode ) +{ + Ivy_Obj_t * pNode0, * pNode1; + // check that the node is regular + assert( !Ivy_IsComplement(pNode) ); + // if the node is not AND, this is not MUX + if ( !Ivy_ObjIsAnd(pNode) ) + return 0; + // if the children are not complemented, this is not MUX + if ( !Ivy_ObjFaninC0(pNode) || !Ivy_ObjFaninC1(pNode) ) + return 0; + // get children + pNode0 = Ivy_ObjFanin0(pNode); + pNode1 = Ivy_ObjFanin1(pNode); + // if the children are not ANDs, this is not MUX + if ( !Ivy_ObjIsAnd(pNode0) || !Ivy_ObjIsAnd(pNode1) ) + return 0; + // otherwise the node is MUX iff it has a pair of equal grandchildren + return (Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC0(pNode1))) || + (Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC1(pNode1))) || + (Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC0(pNode1))) || + (Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC1(pNode1))); +} + +/**Function************************************************************* + + Synopsis [Recognizes what nodes are control and data inputs of a MUX.] + + Description [If the node is a MUX, returns the control variable C. + Assigns nodes T and E to be the then and else variables of the MUX. + Node C is never complemented. Nodes T and E can be complemented. + This function also recognizes EXOR/NEXOR gates as MUXes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pNode, Ivy_Obj_t ** ppNodeT, Ivy_Obj_t ** ppNodeE ) +{ + Ivy_Obj_t * pNode0, * pNode1; + assert( !Ivy_IsComplement(pNode) ); + assert( Ivy_ObjIsMuxType(pNode) ); + // get children + pNode0 = Ivy_ObjFanin0(pNode); + pNode1 = Ivy_ObjFanin1(pNode); + // find the control variable +// if ( pNode1->p1 == Fraig_Not(pNode2->p1) ) + if ( Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC0(pNode1)) ) + { +// if ( Fraig_IsComplement(pNode1->p1) ) + if ( Ivy_ObjFaninC0(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2); + return Ivy_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2); + return Ivy_ObjChild0(pNode0);//pNode1->p1; + } + } +// else if ( pNode1->p1 == Fraig_Not(pNode2->p2) ) + else if ( Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC1(pNode1)) ) + { +// if ( Fraig_IsComplement(pNode1->p1) ) + if ( Ivy_ObjFaninC0(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2); + return Ivy_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1); + return Ivy_ObjChild0(pNode0);//pNode1->p1; + } + } +// else if ( pNode1->p2 == Fraig_Not(pNode2->p1) ) + else if ( Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC0(pNode1)) ) + { +// if ( Fraig_IsComplement(pNode1->p2) ) + if ( Ivy_ObjFaninC1(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1); + return Ivy_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2); + return Ivy_ObjChild1(pNode0);//pNode1->p2; + } + } +// else if ( pNode1->p2 == Fraig_Not(pNode2->p2) ) + else if ( Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC1(pNode1)) ) + { +// if ( Fraig_IsComplement(pNode1->p2) ) + if ( Ivy_ObjFaninC1(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1); + return Ivy_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1); + return Ivy_ObjChild1(pNode0);//pNode1->p2; + } + } + assert( 0 ); // this is not MUX + return NULL; +} + +/**Function************************************************************* + + Synopsis [Computes truth table of the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManCollectCut_rec( Ivy_Obj_t * pNode, Vec_Int_t * vNodes ) +{ + if ( pNode->fMarkA ) + return; + pNode->fMarkA = 1; + assert( Ivy_ObjIsAnd(pNode) || Ivy_ObjIsExor(pNode) ); + Ivy_ManCollectCut_rec( Ivy_ObjFanin0(pNode), vNodes ); + Ivy_ManCollectCut_rec( Ivy_ObjFanin1(pNode), vNodes ); + Vec_IntPush( vNodes, pNode->Id ); +} + +/**Function************************************************************* + + Synopsis [Computes truth table of the cut.] + + Description [Does not modify the array of leaves. Uses array vTruth to store + temporary truth tables. The returned pointer should be used immediately.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManCollectCut( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes ) +{ + int i, Leaf; + // collect and mark the leaves + Vec_IntClear( vNodes ); + Vec_IntForEachEntry( vLeaves, Leaf, i ) + { + Vec_IntPush( vNodes, Leaf ); + Ivy_ObjObj(pRoot, Leaf)->fMarkA = 1; + } + // collect and mark the nodes + Ivy_ManCollectCut_rec( pRoot, vNodes ); + // clean the nodes + Vec_IntForEachEntry( vNodes, Leaf, i ) + Ivy_ObjObj(pRoot, Leaf)->fMarkA = 0; +} + +/**Function************************************************************* + + Synopsis [Returns the pointer to the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Ivy_ObjGetTruthStore( int ObjNum, Vec_Int_t * vTruth ) +{ + return ((unsigned *)Vec_IntArray(vTruth)) + 8 * ObjNum; +} + +/**Function************************************************************* + + Synopsis [Computes truth table of the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ManCutTruthOne( Ivy_Obj_t * pNode, Vec_Int_t * vTruth, int nWords ) +{ + unsigned * pTruth, * pTruth0, * pTruth1; + int i; + pTruth = Ivy_ObjGetTruthStore( pNode->TravId, vTruth ); + pTruth0 = Ivy_ObjGetTruthStore( Ivy_ObjFanin0(pNode)->TravId, vTruth ); + pTruth1 = Ivy_ObjGetTruthStore( Ivy_ObjFanin1(pNode)->TravId, vTruth ); + if ( Ivy_ObjIsExor(pNode) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = pTruth0[i] ^ pTruth1[i]; + else if ( !Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = pTruth0[i] & pTruth1[i]; + else if ( !Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = pTruth0[i] & ~pTruth1[i]; + else if ( Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = ~pTruth0[i] & pTruth1[i]; + else // if ( Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) ) + for ( i = 0; i < nWords; i++ ) + pTruth[i] = ~pTruth0[i] & ~pTruth1[i]; +} + +/**Function************************************************************* + + Synopsis [Computes truth table of the cut.] + + Description [Does not modify the array of leaves. Uses array vTruth to store + temporary truth tables. The returned pointer should be used immediately.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Ivy_ManCutTruth( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth ) +{ + 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 } + }; + int i, Leaf; + // collect the cut + Ivy_ManCollectCut( pRoot, vLeaves, vNodes ); + // set the node numbers + Vec_IntForEachEntry( vNodes, Leaf, i ) + Ivy_ObjObj(pRoot, Leaf)->TravId = i; + // alloc enough memory + Vec_IntClear( vTruth ); + Vec_IntGrow( vTruth, 8 * Vec_IntSize(vNodes) ); + // set the elementary truth tables + Vec_IntForEachEntry( vLeaves, Leaf, i ) + memcpy( Ivy_ObjGetTruthStore(i, vTruth), uTruths[i], 8 * sizeof(unsigned) ); + // compute truths for other nodes + Vec_IntForEachEntryStart( vNodes, Leaf, i, Vec_IntSize(vLeaves) ) + Ivy_ManCutTruthOne( Ivy_ObjObj(pRoot, Leaf), vTruth, 8 ); + return Ivy_ObjGetTruthStore( pRoot->TravId, vTruth ); +} + +/**Function************************************************************* + + Synopsis [Collect the latches.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p ) +{ + Vec_Int_t * vLatches; + Ivy_Obj_t * pObj; + int i; + vLatches = Vec_IntAlloc( Ivy_ManLatchNum(p) ); + Ivy_ManForEachLatch( p, pObj, i ) + Vec_IntPush( vLatches, pObj->Id ); + return vLatches; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivy_.c b/src/temp/ivy/ivy_.c new file mode 100644 index 00000000..65689689 --- /dev/null +++ b/src/temp/ivy/ivy_.c @@ -0,0 +1,48 @@ +/**CFile**************************************************************** + + FileName [ivy_.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivy_.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/module.make b/src/temp/ivy/module.make new file mode 100644 index 00000000..d59a3fa3 --- /dev/null +++ b/src/temp/ivy/module.make @@ -0,0 +1,14 @@ +SRC += src/temp/ivy/ivyBalance.c \ + src/temp/ivy/ivyCanon.c \ + src/temp/ivy/ivyCheck.c \ + src/temp/ivy/ivyCut.c \ + src/temp/ivy/ivyDfs.c \ + src/temp/ivy/ivyDsd.c \ + src/temp/ivy/ivyMan.c \ + src/temp/ivy/ivyObj.c \ + src/temp/ivy/ivyOper.c \ + src/temp/ivy/ivyRewrite.c \ + src/temp/ivy/ivySeq.c \ + src/temp/ivy/ivyTable.c \ + src/temp/ivy/ivyUndo.c \ + src/temp/ivy/ivyUtil.c diff --git a/src/temp/player/module.make b/src/temp/player/module.make new file mode 100644 index 00000000..81a5d77e --- /dev/null +++ b/src/temp/player/module.make @@ -0,0 +1,5 @@ +SRC += src/temp/player/playerAbc.c \ + src/temp/player/playerBuild.c \ + src/temp/player/playerCore.c \ + src/temp/player/playerMan.c \ + src/temp/player/playerUtil.c diff --git a/src/temp/player/player.h b/src/temp/player/player.h new file mode 100644 index 00000000..9ecad35b --- /dev/null +++ b/src/temp/player/player.h @@ -0,0 +1,123 @@ +/**CFile**************************************************************** + + FileName [player.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: player.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __XYZ_H__ +#define __XYZ_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ivy.h" +#include "esop.h" +#include "vec.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Pla_Man_t_ Pla_Man_t; +typedef struct Pla_Obj_t_ Pla_Obj_t; + +// storage for node information +struct Pla_Obj_t_ +{ + unsigned fFixed : 1; // fixed node + unsigned Depth : 7; // the depth in terms of LUTs/PLAs + unsigned nRefs : 24; // the number of references + Vec_Int_t vSupp[2]; // supports in two frames + Esop_Cube_t * pCover[2]; // esops in two frames +}; + +// storage for additional information +struct Pla_Man_t_ +{ + // general characteristics + int nLutMax; // the number of vars + int nPlaMax; // the number of vars + int nCubesMax; // the limit on the number of cubes in the intermediate covers + Ivy_Man_t * pManAig; // the AIG manager + Pla_Obj_t * pPlaStrs; // memory for structures + Esop_Man_t * pManMin; // the cube manager + // arrays to map local variables + Vec_Int_t * vComTo0; // mapping of common variables into first fanin + Vec_Int_t * vComTo1; // mapping of common variables into second fanin + Vec_Int_t * vPairs0; // the first var in each pair of common vars + Vec_Int_t * vPairs1; // the second var in each pair of common vars + Vec_Int_t * vTriv0; // trival support of the first node + Vec_Int_t * vTriv1; // trival support of the second node + // statistics + int nNodes; // the number of nodes processed + int nNodesLut; // the number of nodes processed + int nNodesPla; // the number of nodes processed + int nNodesBoth; // the number of nodes processed + int nNodesDeref; // the number of nodes processed +}; + +#define PLAYER_FANIN_LIMIT 128 + +#define PLA_MIN(a,b) (((a) < (b))? (a) : (b)) +#define PLA_MAX(a,b) (((a) > (b))? (a) : (b)) + +#define PLA_EMPTY ((Esop_Cube_t *)1) + +static inline Pla_Man_t * Ivy_ObjPlaMan( Ivy_Obj_t * pObj ) { return (Pla_Man_t *)Ivy_ObjMan(pObj)->pData; } +static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Obj_t * pObj ) { return Ivy_ObjPlaMan(pObj)->pPlaStrs + pObj->Id; } + +static inline unsigned * Ivy_ObjGetTruth( Ivy_Obj_t * pObj ) +{ + Ivy_Man_t * p = Ivy_ObjMan(pObj); + int Offset = Vec_IntEntry( p->vTruths, pObj->Id ); + return Offset < 0 ? NULL : p->pMemory + Offset; + +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== playerAbc.c ==============================================================*/ +extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nFaninMax, int fVerbose ); +/*=== playerBuild.c ============================================================*/ +extern Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * p ); +/*=== playerCore.c =============================================================*/ +extern Ivy_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose ); +/*=== playerMan.c ==============================================================*/ +extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax ); +extern void Pla_ManFree( Pla_Man_t * p ); +extern void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr ); +/*=== playerUtil.c =============================================================*/ +extern int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp ); +extern Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit ); +extern Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit ); +extern void Pla_ManComputeStats( Ivy_Man_t * pAig, Vec_Int_t * vNodes ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + + diff --git a/src/temp/player/playerAbc.c b/src/temp/player/playerAbc.c new file mode 100644 index 00000000..9cc342d9 --- /dev/null +++ b/src/temp/player/playerAbc.c @@ -0,0 +1,215 @@ +/**CFile**************************************************************** + + FileName [playerAbc.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLAyer decomposition package.] + + Synopsis [Bridge between ABC and PLAyer.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 20, 2006.] + + Revision [$Id: playerAbc.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p ); +static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Gives the current ABC network to PLAyer for processing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose ) +{ + Ivy_Man_t * pMan, * pManExt; + Abc_Ntk_t * pNtkAig; + if ( !Abc_NtkIsStrash(pNtk) ) + return NULL; + // convert to the new AIG manager + pMan = Ivy_ManFromAbc( pNtk ); + // check the correctness of conversion + if ( !Ivy_ManCheck( pMan ) ) + { + printf( "Abc_NtkPlayer: Internal AIG check has failed.\n" ); + Ivy_ManStop( pMan ); + return NULL; + } + if ( fVerbose ) + Ivy_ManPrintStats( pMan ); + // perform decomposition/mapping into PLAs/LUTs + pManExt = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose ); + Ivy_ManStop( pMan ); + pMan = pManExt; + if ( fVerbose ) + Ivy_ManPrintStats( pMan ); + // convert from the extended AIG manager into an SOP network + pNtkAig = Ivy_ManToAbc( pNtk, pMan ); + Ivy_ManStop( pMan ); + // chech the resulting network + if ( !Abc_NtkCheck( pNtkAig ) ) + { + printf( "Abc_NtkPlayer: The network check has failed.\n" ); + Abc_NtkDelete( pNtkAig ); + return NULL; + } + return pNtkAig; +} + +/**Function************************************************************* + + Synopsis [Converts from strashed AIG in ABC into strash AIG in IVY.] + + Description [Assumes DFS ordering of nodes in the AIG of ABC.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk ) +{ + Ivy_Man_t * pMan; + Abc_Obj_t * pObj; + int i; + // create the manager + pMan = Ivy_ManStart( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), Abc_NtkNodeNum(pNtk) + 10 ); + // create the PIs + Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); + Abc_NtkForEachCi( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i); + // perform the conversion of the internal nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Ivy_And( (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) ); + // create the POs + Abc_NtkForEachCo( pNtk, pObj, i ) + Ivy_ObjConnect( Ivy_ManPo(pMan, i), (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) ); + Ivy_ManCleanup( pMan ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Converts AIG manager after PLA/LUT mapping into a logic ABC network.] + + Description [The AIG manager contains nodes with extended functionality. + Node types are in pObj->Type. Node fanins are in pObj->vFanins. Functions + of LUT nodes are in pMan->vTruths.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan ) +{ + Abc_Ntk_t * pNtkNew; + Vec_Int_t * vIvyNodes, * vIvyFanins, * vTruths = pMan->vTruths; + Abc_Obj_t * pObj, * pObjNew, * pFaninNew; + Ivy_Obj_t * pIvyNode, * pIvyFanin; + int pCompls[PLAYER_FANIN_LIMIT]; + int i, k, Fanin, nFanins; + // start the new ABC network + pNtkNew = Abc_NtkStartFrom( pNtkOld, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + // transfer the pointers to the basic nodes + Ivy_ManCleanTravId(pMan); + Ivy_ManConst1(pMan)->TravId = Abc_NtkConst1(pNtkNew)->Id; + Abc_NtkForEachCi( pNtkNew, pObjNew, i ) + Ivy_ManPi(pMan, i)->TravId = pObjNew->Id; + // construct the logic network isomorphic to logic network in the AIG manager + vIvyNodes = Ivy_ManDfsExt( pMan ); + Ivy_ManForEachNodeVec( pMan, vIvyNodes, pIvyNode, i ) + { + // get fanins of the old node + vIvyFanins = Ivy_ObjGetFanins( pIvyNode ); + nFanins = Vec_IntSize(vIvyFanins); + // create the new node + pObjNew = Abc_NtkCreateNode( pNtkNew ); + Vec_IntForEachEntry( vIvyFanins, Fanin, k ) + { + pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_FanId(Fanin) ); + pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId ); + Abc_ObjAddFanin( pObjNew, pFaninNew ); + pCompls[k] = Ivy_FanCompl(Fanin); + assert( Ivy_ObjIsAndMulti(pIvyNode) || nFanins == 1 || pCompls[k] == 0 ); // EXOR/LUT cannot have complemented fanins + } + assert( k <= PLAYER_FANIN_LIMIT ); + // create logic function of the node + if ( Ivy_ObjIsAndMulti(pIvyNode) ) + pObjNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, nFanins, pCompls ); + else if ( Ivy_ObjIsExorMulti(pIvyNode) ) + pObjNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nFanins ); + else if ( Ivy_ObjIsLut(pIvyNode) ) + pObjNew->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, nFanins, Ivy_ObjGetTruth(pIvyNode) ); + else assert( 0 ); + assert( Abc_SopGetVarNum(pObjNew->pData) == nFanins ); + pIvyNode->TravId = pObjNew->Id; + } +//Pla_ManComputeStats( pMan, vIvyNodes ); + Vec_IntFree( vIvyNodes ); + // connect the PO nodes + Abc_NtkForEachCo( pNtkOld, pObj, i ) + { + // get the old fanin of the PO node + vIvyFanins = Ivy_ObjGetFanins( Ivy_ManPo(pMan, i) ); + Fanin = Vec_IntEntry( vIvyFanins, 0 ); + pIvyFanin = Ivy_ManObj( pMan, Ivy_FanId(Fanin) ); + // get the new ABC node corresponding to the old fanin + pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId ); + if ( Ivy_FanCompl(Fanin) ) // complement + { +// pFaninNew = Abc_NodeCreateInv(pNtkNew, pFaninNew); + if ( Abc_ObjIsCi(pFaninNew) ) + pFaninNew = Abc_NodeCreateInv(pNtkNew, pFaninNew); + else + { + // clone the node + pObjNew = Abc_NodeClone( pFaninNew ); + // set complemented functions + pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pFaninNew->pData ); + Abc_SopComplement(pObjNew->pData); + // return the new node + pFaninNew = pObjNew; + } + assert( Abc_SopGetVarNum(pFaninNew->pData) == Abc_ObjFaninNum(pFaninNew) ); + } + Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); + } + // remove dangling nodes + Abc_NtkForEachNode(pNtkNew, pObj, i) + if ( Abc_ObjFanoutNum(pObj) == 0 ) + Abc_NtkDeleteObj(pObj); + // fix CIs feeding directly into COs + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + return pNtkNew; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerBuild.c b/src/temp/player/playerBuild.c new file mode 100644 index 00000000..a7b06f03 --- /dev/null +++ b/src/temp/player/playerBuild.c @@ -0,0 +1,279 @@ +/**CFile**************************************************************** + + FileName [playerBuild.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerBuild.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld ); +static Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Esop_Cube_t * pCube, Vec_Int_t * vSupp ); +static Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 ); +static int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Constructs the AIG manager (IVY) for the network after mapping.] + + Description [Uses extended node types (multi-input AND, multi-input EXOR, LUT).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * pOld ) +{ + Ivy_Man_t * pNew; + Ivy_Obj_t * pObjOld, * pObjNew; + int i; + // start the new manager + pNew = Ivy_ManStart( Ivy_ManPiNum(pOld), Ivy_ManPoNum(pOld), 2*Ivy_ManNodeNum(pOld) + 10 ); + pNew->fExtended = 1; + // transfer the const/PI numbers + Ivy_ManCleanTravId(pOld); + Ivy_ManConst1(pOld)->TravId = Ivy_ManConst1(pNew)->Id; + Ivy_ManForEachPi( pOld, pObjOld, i ) + pObjOld->TravId = Ivy_ManPi(pNew, i)->Id; + // recursively construct the network + Ivy_ManForEachPo( pOld, pObjOld, i ) + { + pObjNew = Pla_ManToAig_rec( pNew, Ivy_ObjFanin0(pObjOld) ); + Ivy_ObjStartFanins( Ivy_ManPo(pNew, i), 1 ); + Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_FanCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) ); + } + // compute the LUT functions + Pla_ManToAigLutFuncs( pNew, pOld ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Recursively construct the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld ) +{ + Pla_Man_t * p = Ivy_ObjMan(pObjOld)->pData; + Vec_Int_t * vSupp; + Esop_Cube_t * pCover, * pCube; + Ivy_Obj_t * pFaninOld, * pFaninNew, * pObjNew; + Pla_Obj_t * pStr; + int Entry, nCubes, ObjNewId, i; + // skip the node if it is a constant or already processed + if ( Ivy_ObjIsConst1(pObjOld) || pObjOld->TravId ) + return Ivy_ManObj( pNew, pObjOld->TravId ); + assert( Ivy_ObjIsAnd(pObjOld) || Ivy_ObjIsExor(pObjOld) ); + // get the support and the cover + pStr = Ivy_ObjPlaStr( pObjOld ); + if ( Vec_IntSize( &pStr->vSupp[0] ) <= p->nLutMax ) + { + vSupp = &pStr->vSupp[0]; + pCover = PLA_EMPTY; + } + else + { + vSupp = &pStr->vSupp[1]; + pCover = pStr->pCover[1]; + assert( pCover != PLA_EMPTY ); + } + // process the fanins + Vec_IntForEachEntry( vSupp, Entry, i ) + Pla_ManToAig_rec( pNew, Ivy_ObjObj(pObjOld, Entry) ); + // consider the case of a LUT + if ( pCover == PLA_EMPTY ) + { + pObjNew = Ivy_ObjCreateExt( pNew, IVY_LUT ); + Ivy_ObjStartFanins( pObjNew, p->nLutMax ); + // remember new object ID in case it changes + ObjNewId = pObjNew->Id; + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFaninOld = Ivy_ObjObj( pObjOld, Entry ); + Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_FanCreate(pFaninOld->TravId, 0) ); + } + // get the new object + pObjNew = Ivy_ManObj(pNew, ObjNewId); + } + else + { + // for each cube, construct the node + nCubes = Esop_CoverCountCubes( pCover ); + if ( nCubes == 0 ) + pObjNew = Ivy_ManToAigConst( pNew, 0 ); + else if ( nCubes == 1 ) + pObjNew = Ivy_ManToAigCube( pNew, pObjOld, pCover, vSupp ); + else + { + pObjNew = Ivy_ObjCreateExt( pNew, IVY_EXORM ); + Ivy_ObjStartFanins( pObjNew, p->nLutMax ); + // remember new object ID in case it changes + ObjNewId = pObjNew->Id; + Esop_CoverForEachCube( pCover, pCube ) + { + pFaninNew = Ivy_ManToAigCube( pNew, pObjOld, pCube, vSupp ); + Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_FanCreate(pFaninNew->Id, 0) ); + } + // get the new object + pObjNew = Ivy_ManObj(pNew, ObjNewId); + } + } + pObjOld->TravId = pObjNew->Id; + pObjNew->TravId = pObjOld->Id; + return pObjNew; +} + + +/**Function************************************************************* + + Synopsis [Returns constant 1 node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 ) +{ + Ivy_Obj_t * pObjNew; + pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM ); + Ivy_ObjStartFanins( pObjNew, 1 ); + Ivy_ObjAddFanin( pObjNew, Ivy_FanCreate(0, !fConst1) ); + return pObjNew; +} + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Esop_Cube_t * pCube, Vec_Int_t * vSupp ) +{ + Ivy_Obj_t * pObjNew, * pFaninOld; + int i, Value; + // if tautology cube, create constant 1 node + if ( pCube->nLits == 0 ) + return Ivy_ManToAigConst( pNew, 1 ); + // create AND node + pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM ); + Ivy_ObjStartFanins( pObjNew, pCube->nLits ); + // add fanins + for ( i = 0; i < (int)pCube->nVars; i++ ) + { + Value = Esop_CubeGetVar( pCube, i ); + assert( Value != 0 ); + if ( Value == 3 ) + continue; + pFaninOld = Ivy_ObjObj( pObjOld, Vec_IntEntry(vSupp, i) ); + Ivy_ObjAddFanin( pObjNew, Ivy_FanCreate( pFaninOld->TravId, Value==1 ) ); + } + assert( Ivy_ObjFaninNum(pObjNew) == (int)pCube->nLits ); + return pObjNew; +} + + +/**Function************************************************************* + + Synopsis [Recursively construct the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld ) +{ + Vec_Int_t * vSupp, * vFanins, * vNodes, * vTemp; + Ivy_Obj_t * pObjOld, * pObjNew; + unsigned * pComputed, * pTruth; + int i, k, Counter = 0; + // create mapping from the LUT nodes into truth table indices + assert( pNew->vTruths == NULL ); + vNodes = Vec_IntAlloc( 100 ); + vTemp = Vec_IntAlloc( 100 ); + pNew->vTruths = Vec_IntStart( Ivy_ManObjIdNext(pNew) ); + Ivy_ManForEachObj( pNew, pObjNew, i ) + { + if ( Ivy_ObjIsLut(pObjNew) ) + Vec_IntWriteEntry( pNew->vTruths, i, 8 * Counter++ ); + else + Vec_IntWriteEntry( pNew->vTruths, i, -1 ); + } + // allocate memory + pNew->pMemory = ALLOC( unsigned, 8 * Counter ); + memset( pNew->pMemory, 0, sizeof(unsigned) * 8 * Counter ); + // derive truth tables + Ivy_ManForEachObj( pNew, pObjNew, i ) + { + if ( !Ivy_ObjIsLut(pObjNew) ) + continue; + pObjOld = Ivy_ManObj( pOld, pObjNew->TravId ); + vSupp = Ivy_ObjPlaStr(pObjOld)->vSupp; + assert( Vec_IntSize(vSupp) <= 8 ); + pTruth = Ivy_ObjGetTruth( pObjNew ); + pComputed = Ivy_ManCutTruth( pObjOld, vSupp, vNodes, vTemp ); + // check if the truth table is constant 0 + for ( k = 0; k < 8; k++ ) + if ( pComputed[k] ) + break; + if ( k == 8 ) + { + // create inverter + for ( k = 0; k < 8; k++ ) + pComputed[k] = 0x55555555; + // point it to the constant 1 node + vFanins = Ivy_ObjGetFanins( pObjNew ); + Vec_IntClear( vFanins ); + Vec_IntPush( vFanins, Ivy_FanCreate(0, 1) ); + } + memcpy( pTruth, pComputed, sizeof(unsigned) * 8 ); +// Extra_PrintBinary( stdout, pTruth, 16 ); printf( "\n" ); + } + Vec_IntFree( vTemp ); + Vec_IntFree( vNodes ); + return Counter; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerCore.c b/src/temp/player/playerCore.c new file mode 100644 index 00000000..3cd3d8a8 --- /dev/null +++ b/src/temp/player/playerCore.c @@ -0,0 +1,381 @@ +/**CFile**************************************************************** + + FileName [playerCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerCore.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Pla_ManDecomposeInt( Pla_Man_t * p ); +static int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj ); +static void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level, + Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fVerbose ) +{ + Pla_Man_t * p; + Ivy_Man_t * pAigNew; + p = Pla_ManAlloc( pAig, nLutMax, nPlaMax ); + if ( !Pla_ManDecomposeInt( p ) ) + { + printf( "Decomposition/mapping failed.\n" ); + Pla_ManFree( p ); + return NULL; + } + pAigNew = Pla_ManToAig( pAig ); +// if ( fVerbose ) +// printf( "PLA stats: Both = %6d. Pla = %6d. Lut = %6d. Total = %6d. Deref = %6d.\n", +// p->nNodesBoth, p->nNodesPla, p->nNodesLut, p->nNodes, p->nNodesDeref ); + Pla_ManFree( p ); + return pAigNew; +} + +/**Function************************************************************* + + Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManDecomposeInt( Pla_Man_t * p ) +{ + Ivy_Man_t * pAig = p->pManAig; + Ivy_Obj_t * pObj; + Pla_Obj_t * pStr; + int i; + + // prepare the PI structures + Ivy_ManForEachPi( pAig, pObj, i ) + { + pStr = Ivy_ObjPlaStr( pObj ); + pStr->fFixed = 1; + pStr->Depth = 0; + pStr->nRefs = (unsigned)pObj->nRefs; + pStr->pCover[0] = PLA_EMPTY; + pStr->pCover[1] = PLA_EMPTY; + } + + // assuming DFS ordering of nodes in the manager + Ivy_ManForEachNode( pAig, pObj, i ) + if ( !Pla_ManDecomposeNode(p, pObj) ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Records decomposition statistics for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Pla_ManCountDecNodes( Pla_Man_t * p, Pla_Obj_t * pStr ) +{ + if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax && pStr->pCover[1] != PLA_EMPTY ) + p->nNodesBoth++; + else if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax ) + p->nNodesLut++; + else if ( pStr->pCover[1] != PLA_EMPTY ) + p->nNodesPla++; +} + +/**Function************************************************************* + + Synopsis [Performs decomposition/mapping for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj ) +{ + Pla_Obj_t * pStr, * pStr0, * pStr1; + Vec_Int_t * vSuppA, * vSuppB, * vSupp0, * vSupp1; + Esop_Cube_t * pCovA, * pCovB; + int nSuppSize1, nSuppSize2; + + assert( pObj->nRefs > 0 ); + p->nNodes++; + + // get the structures + pStr = Ivy_ObjPlaStr( pObj ); + pStr0 = Ivy_ObjPlaStr( Ivy_ObjFanin0( pObj ) ); + pStr1 = Ivy_ObjPlaStr( Ivy_ObjFanin1( pObj ) ); + vSupp0 = &pStr->vSupp[0]; + vSupp1 = &pStr->vSupp[1]; + pStr->pCover[0] = PLA_EMPTY; + pStr->pCover[1] = PLA_EMPTY; + + // process level 1 + Pla_NodeGetSuppsAndCovers( p, pObj, 1, &vSuppA, &vSuppB, &pCovA, &pCovB ); + nSuppSize1 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 ); + if ( nSuppSize1 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY ) + pStr->pCover[0] = PLA_EMPTY; + else if ( Ivy_ObjIsAnd(pObj) ) + pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 ); + else + pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 ); + + // process level 2 + if ( PLA_MAX(pStr0->Depth, pStr1->Depth) > 1 ) + { + Pla_NodeGetSuppsAndCovers( p, pObj, 2, &vSuppA, &vSuppB, &pCovA, &pCovB ); + nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp1 ); + if ( nSuppSize2 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY ) + pStr->pCover[1] = PLA_EMPTY; + else if ( Ivy_ObjIsAnd(pObj) ) + pStr->pCover[1] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 ); + else + pStr->pCover[1] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 ); + } + + // determine the level of this node + pStr->nRefs = (unsigned)pObj->nRefs; + pStr->Depth = PLA_MAX( pStr0->Depth, pStr1->Depth ); + pStr->Depth = pStr->Depth? pStr->Depth : 1; + if ( nSuppSize1 > p->nLutMax && pStr->pCover[1] == PLA_EMPTY ) + { + pStr->Depth++; + // free second level + if ( pStr->pCover[1] != PLA_EMPTY ) + Esop_CoverRecycle( p->pManMin, pStr->pCover[1] ); + vSupp1->nCap = 0; + vSupp1->nSize = 0; + FREE( vSupp1->pArray ); + pStr->pCover[1] = PLA_EMPTY; + // move first to second + pStr->vSupp[1] = pStr->vSupp[0]; + pStr->pCover[1] = pStr->pCover[0]; + vSupp0->nCap = 0; + vSupp0->nSize = 0; + vSupp0->pArray = NULL; + pStr->pCover[0] = PLA_EMPTY; + // get zero level + Pla_NodeGetSuppsAndCovers( p, pObj, 0, &vSuppA, &vSuppB, &pCovA, &pCovB ); + nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 ); + assert( nSuppSize2 == 2 ); + if ( pCovA == PLA_EMPTY || pCovB == PLA_EMPTY ) + pStr->pCover[0] = PLA_EMPTY; + else if ( Ivy_ObjIsAnd(pObj) ) + pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 ); + else + pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 ); + // count stats + if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 ); + if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 ); + // mark the nodes + pStr0->fFixed = 1; + pStr1->fFixed = 1; + } + else if ( pStr0->Depth < pStr1->Depth ) + { + if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 ); + pStr0->fFixed = 1; + } + else // if ( pStr0->Depth > pStr1->Depth ) + { + if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 ); + pStr1->fFixed = 1; + } + + // free some of the covers to save memory + assert( pStr0->nRefs > 0 ); + assert( pStr1->nRefs > 0 ); + pStr0->nRefs--; + pStr1->nRefs--; + + if ( pStr0->nRefs == 0 && !pStr0->fFixed ) + Pla_ManFreeStr( p, pStr0 ), p->nNodesDeref++; + if ( pStr1->nRefs == 0 && !pStr1->fFixed ) + Pla_ManFreeStr( p, pStr1 ), p->nNodesDeref++; + + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns pointers to the support arrays on the given level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level, + Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB ) +{ + Ivy_Obj_t * pFan0, * pFan1; + Pla_Obj_t * pStr, * pStr0, * pStr1; + Esop_Cube_t * pCovA, * pCovB; + int fCompl0, fCompl1; + assert( Level >= 0 && Level <= 2 ); + // get the complemented attributes + fCompl0 = Ivy_ObjFaninC0( pObj ); + fCompl1 = Ivy_ObjFaninC1( pObj ); + // get the fanins + pFan0 = Ivy_ObjFanin0( pObj ); + pFan1 = Ivy_ObjFanin1( pObj ); + // get the structures + pStr = Ivy_ObjPlaStr( pObj ); + pStr0 = Ivy_ObjPlaStr( pFan0 ); + pStr1 = Ivy_ObjPlaStr( pFan1 ); + // make sure the fanins are processed + assert( Ivy_ObjIsPi(pFan0) || pStr0->Depth > 0 ); + assert( Ivy_ObjIsPi(pFan1) || pStr1->Depth > 0 ); + // prepare the return values depending on the level + Vec_IntWriteEntry( p->vTriv0, 0, pFan0->Id ); + Vec_IntWriteEntry( p->vTriv1, 0, pFan1->Id ); + *pvSuppA = p->vTriv0; + *pvSuppB = p->vTriv1; + pCovA = p->pManMin->pTriv0; + pCovB = p->pManMin->pTriv1; + if ( Level == 1 ) + { + if ( pStr0->Depth == pStr1->Depth ) + { + if ( pStr0->Depth > 0 ) + { + *pvSuppA = &pStr0->vSupp[0]; + *pvSuppB = &pStr1->vSupp[0]; + pCovA = pStr0->pCover[0]; + pCovB = pStr1->pCover[0]; + } + } + else if ( pStr0->Depth < pStr1->Depth ) + { + *pvSuppB = &pStr1->vSupp[0]; + pCovB = pStr1->pCover[0]; + } + else // if ( pStr0->Depth > pStr1->Depth ) + { + *pvSuppA = &pStr0->vSupp[0]; + pCovA = pStr0->pCover[0]; + } + } + else if ( Level == 2 ) + { + if ( pStr0->Depth == pStr1->Depth ) + { + *pvSuppA = &pStr0->vSupp[1]; + *pvSuppB = &pStr1->vSupp[1]; + pCovA = pStr0->pCover[1]; + pCovB = pStr1->pCover[1]; + } + else if ( pStr0->Depth + 1 == pStr1->Depth ) + { + *pvSuppA = &pStr0->vSupp[0]; + *pvSuppB = &pStr1->vSupp[1]; + pCovA = pStr0->pCover[0]; + pCovB = pStr1->pCover[1]; + } + else if ( pStr0->Depth == pStr1->Depth + 1 ) + { + *pvSuppA = &pStr0->vSupp[1]; + *pvSuppB = &pStr1->vSupp[0]; + pCovA = pStr0->pCover[1]; + pCovB = pStr1->pCover[0]; + } + else if ( pStr0->Depth < pStr1->Depth ) + { + *pvSuppB = &pStr1->vSupp[1]; + pCovB = pStr1->pCover[1]; + } + else // if ( pStr0->Depth > pStr1->Depth ) + { + *pvSuppA = &pStr0->vSupp[1]; + pCovA = pStr0->pCover[1]; + } + } + // complement the first if needed + if ( pCovA == PLA_EMPTY || !fCompl0 ) + *pvCovA = pCovA; + else if ( pCovA && pCovA->nLits == 0 ) // topmost one is the tautology cube + *pvCovA = pCovA->pNext; + else + *pvCovA = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCovA; + // complement the second if needed + if ( pCovB == PLA_EMPTY || !fCompl1 ) + *pvCovB = pCovB; + else if ( pCovB && pCovB->nLits == 0 ) // topmost one is the tautology cube + *pvCovB = pCovB->pNext; + else + *pvCovB = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCovB; +} + + +/* + if ( pObj->Id == 1371 ) + { + int k; + printf( "Zero : " ); + for ( k = 0; k < vSuppA->nSize; k++ ) + printf( "%d ", vSuppA->pArray[k] ); + printf( "\n" ); + printf( "One : " ); + for ( k = 0; k < vSuppB->nSize; k++ ) + printf( "%d ", vSuppB->pArray[k] ); + printf( "\n" ); + printf( "Node : " ); + for ( k = 0; k < vSupp0->nSize; k++ ) + printf( "%d ", vSupp0->pArray[k] ); + printf( "\n" ); + printf( "\n" ); + printf( "\n" ); + Esop_CoverWrite( stdout, pCovA ); + printf( "\n" ); + Esop_CoverWrite( stdout, pCovB ); + printf( "\n" ); + } +*/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerMan.c b/src/temp/player/playerMan.c new file mode 100644 index 00000000..7f2c0919 --- /dev/null +++ b/src/temp/player/playerMan.c @@ -0,0 +1,125 @@ +/**CFile**************************************************************** + + FileName [playerMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerMan.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates the PLA/LUT mapping manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * pAig, int nLutMax, int nPlaMax ) +{ + Pla_Man_t * pMan; + assert( !(nLutMax < 2 || nLutMax > 8 || nPlaMax < 8 || nPlaMax > 128) ); + // start the manager + pMan = ALLOC( Pla_Man_t, 1 ); + memset( pMan, 0, sizeof(Pla_Man_t) ); + pMan->nLutMax = nLutMax; + pMan->nPlaMax = nPlaMax; + pMan->nCubesMax = 2 * nPlaMax; // higher limit, later reduced + pMan->pManAig = pAig; + // set up the temporaries + pMan->vComTo0 = Vec_IntAlloc( 2 * nPlaMax ); + pMan->vComTo1 = Vec_IntAlloc( 2 * nPlaMax ); + pMan->vPairs0 = Vec_IntAlloc( nPlaMax ); + pMan->vPairs1 = Vec_IntAlloc( nPlaMax ); + pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 ); + pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 ); + // allocate memory for object structures + pMan->pPlaStrs = ALLOC( Pla_Obj_t, sizeof(Pla_Obj_t) * Ivy_ManObjIdNext(pAig) ); + memset( pMan->pPlaStrs, 0, sizeof(Pla_Obj_t) * Ivy_ManObjIdNext(pAig) ); + // create the cube manager + pMan->pManMin = Esop_ManAlloc( nPlaMax ); + // save the resulting manager + assert( pAig->pData == NULL ); + pAig->pData = pMan; + return pMan; +} + +/**Function************************************************************* + + Synopsis [Frees the PLA/LUT mapping manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManFree( Pla_Man_t * p ) +{ + Pla_Obj_t * pStr; + int i; + Esop_ManFree( p->pManMin ); + Vec_IntFree( p->vTriv0 ); + Vec_IntFree( p->vTriv1 ); + Vec_IntFree( p->vComTo0 ); + Vec_IntFree( p->vComTo1 ); + Vec_IntFree( p->vPairs0 ); + Vec_IntFree( p->vPairs1 ); + for ( i = 0, pStr = p->pPlaStrs; i < Ivy_ManObjIdNext(p->pManAig); i++, pStr++ ) + FREE( pStr->vSupp[0].pArray ), FREE( pStr->vSupp[1].pArray ); + free( p->pPlaStrs ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Cleans the PLA/LUT structure of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr ) +{ + if ( pStr->pCover[0] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[0] ); + if ( pStr->pCover[1] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[1] ); + if ( pStr->vSupp[0].pArray ) free( pStr->vSupp[0].pArray ); + if ( pStr->vSupp[1].pArray ) free( pStr->vSupp[1].pArray ); + memset( pStr, 0, sizeof(Pla_Obj_t) ); + pStr->pCover[0] = PLA_EMPTY; + pStr->pCover[1] = PLA_EMPTY; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerUtil.c b/src/temp/player/playerUtil.c new file mode 100644 index 00000000..1b361839 --- /dev/null +++ b/src/temp/player/playerUtil.c @@ -0,0 +1,349 @@ +/**CFile**************************************************************** + + FileName [playerUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Merges two supports.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp ) +{ + int k0, k1; + + assert( vSupp0->nSize && vSupp1->nSize ); + + Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 ); + Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 ); + Vec_IntClear( p->vPairs0 ); + Vec_IntClear( p->vPairs1 ); + + vSupp->nSize = 0; + vSupp->nCap = vSupp0->nSize + vSupp1->nSize; + vSupp->pArray = ALLOC( int, vSupp->nCap ); + + for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; ) + { + if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( p->vPairs0, k0 ); + Vec_IntPush( p->vPairs1, k1 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + k0++; k1++; + } + else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + k0++; + } + else + { + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( vSupp, vSupp1->pArray[k1] ); + k1++; + } + } + for ( ; k0 < vSupp0->nSize; k0++ ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + } + for ( ; k1 < vSupp1->nSize; k1++ ) + { + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( vSupp, vSupp1->pArray[k1] ); + } +/* + printf( "Zero : " ); + for ( k = 0; k < vSupp0->nSize; k++ ) + printf( "%d ", vSupp0->pArray[k] ); + printf( "\n" ); + + printf( "One : " ); + for ( k = 0; k < vSupp1->nSize; k++ ) + printf( "%d ", vSupp1->pArray[k] ); + printf( "\n" ); + + printf( "Sum : " ); + for ( k = 0; k < vSupp->nSize; k++ ) + printf( "%d ", vSupp->pArray[k] ); + printf( "\n" ); + printf( "\n" ); +*/ + return Vec_IntSize(vSupp); +} + + +/**Function************************************************************* + + Synopsis [Computes the produce of two covers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit ) +{ + Esop_Cube_t * pCube, * pCube0, * pCube1; + Esop_Cube_t * pCover; + int i, Val0, Val1; + assert( pCover0 != PLA_EMPTY && pCover1 != PLA_EMPTY ); + + // clean storage + assert( nSupp <= p->nPlaMax ); + Esop_ManClean( p->pManMin, nSupp ); + // go through the cube pairs + Esop_CoverForEachCube( pCover0, pCube0 ) + Esop_CoverForEachCube( pCover1, pCube1 ) + { + // go through the support variables of the cubes + for ( i = 0; i < p->vPairs0->nSize; i++ ) + { + Val0 = Esop_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); + Val1 = Esop_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); + if ( (Val0 & Val1) == 0 ) + break; + } + // check disjointness + if ( i < p->vPairs0->nSize ) + continue; + + if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Esop_CoverCollect( p->pManMin, nSupp ); +//Esop_CoverWriteFile( pCover, "large", 1 ); + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } + + // create the product cube + pCube = Esop_CubeAlloc( p->pManMin ); + + // add the literals + pCube->nLits = 0; + for ( i = 0; i < nSupp; i++ ) + { + if ( p->vComTo0->pArray[i] == -1 ) + Val0 = 3; + else + Val0 = Esop_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + + if ( p->vComTo1->pArray[i] == -1 ) + Val1 = 3; + else + Val1 = Esop_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + + if ( (Val0 & Val1) == 3 ) + continue; + + Esop_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); + pCube->nLits++; + } + // add the cube to storage + Esop_EsopAddCube( p->pManMin, pCube ); + } + + // minimize the cover + Esop_EsopMinimize( p->pManMin ); + pCover = Esop_CoverCollect( p->pManMin, nSupp ); + + // quit if the cover is too large + if ( fStopAtLimit && Esop_CoverCountCubes(pCover) > p->nPlaMax ) + { + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } +// if ( pCover && pCover->nWords > 4 ) +// printf( "%d", pCover->nWords ); +// else +// printf( "." ); + return pCover; +} + +/**Function************************************************************* + + Synopsis [Computes the EXOR of two covers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit ) +{ + Esop_Cube_t * pCube, * pCube0, * pCube1; + Esop_Cube_t * pCover; + int i, Val0, Val1; + assert( pCover0 != PLA_EMPTY && pCover1 != PLA_EMPTY ); + + // clean storage + assert( nSupp <= p->nPlaMax ); + Esop_ManClean( p->pManMin, nSupp ); + Esop_CoverForEachCube( pCover0, pCube0 ) + { + // create the cube + pCube = Esop_CubeAlloc( p->pManMin ); + pCube->nLits = 0; + for ( i = 0; i < p->vComTo0->nSize; i++ ) + { + if ( p->vComTo0->pArray[i] == -1 ) + continue; + Val0 = Esop_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + if ( Val0 == 3 ) + continue; + Esop_CubeXorVar( pCube, i, Val0 ^ 3 ); + pCube->nLits++; + } + if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Esop_CoverCollect( p->pManMin, nSupp ); + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } + // add the cube to storage + Esop_EsopAddCube( p->pManMin, pCube ); + } + Esop_CoverForEachCube( pCover1, pCube1 ) + { + // create the cube + pCube = Esop_CubeAlloc( p->pManMin ); + pCube->nLits = 0; + for ( i = 0; i < p->vComTo1->nSize; i++ ) + { + if ( p->vComTo1->pArray[i] == -1 ) + continue; + Val1 = Esop_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + if ( Val1 == 3 ) + continue; + Esop_CubeXorVar( pCube, i, Val1 ^ 3 ); + pCube->nLits++; + } + if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Esop_CoverCollect( p->pManMin, nSupp ); + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } + // add the cube to storage + Esop_EsopAddCube( p->pManMin, pCube ); + } + + // minimize the cover + Esop_EsopMinimize( p->pManMin ); + pCover = Esop_CoverCollect( p->pManMin, nSupp ); + + // quit if the cover is too large + if ( fStopAtLimit && Esop_CoverCountCubes(pCover) > p->nPlaMax ) + { + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } + return pCover; +} + +/**Function************************************************************* + + Synopsis [Computes area/delay of the mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes ) +{ + Ivy_Obj_t * pObj, * pFanin; + Vec_Int_t * vFanins; + int Area, Delay, Fanin, nFanins, i, k; + + Delay = Area = 0; + // compute levels and area + Ivy_ManForEachPi( p, pObj, i ) + pObj->Level = 0; + Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) + { + // compute level of the node + pObj->Level = 0; + vFanins = Ivy_ObjGetFanins( pObj ); + Vec_IntForEachEntry( vFanins, Fanin, k ) + { + pFanin = Ivy_ManObj(p, Ivy_FanId(Fanin)); + pObj->Level = IVY_MAX( pObj->Level, pFanin->Level ); + } + pObj->Level += 1; + // compute area of the node + nFanins = Ivy_ObjFaninNum( pObj ); + if ( nFanins <= 4 ) + Area += 1; + else if ( nFanins <= 6 ) + Area += 2; + else if ( nFanins <= 8 ) + Area += 4; + else if ( nFanins <= 16 ) + Area += 8; + else if ( nFanins <= 32 ) + Area += 16; + else if ( nFanins <= 64 ) + Area += 32; + else if ( nFanins <= 128 ) + Area += 64; + else + assert( 0 ); + } + Ivy_ManForEachPo( p, pObj, i ) + { + Fanin = Ivy_ObjReadFanin(pObj, 0); + pFanin = Ivy_ManObj( p, Ivy_FanId(Fanin) ); + pObj->Level = pFanin->Level; + Delay = IVY_MAX( Delay, (int)pObj->Level ); + } + printf( "Area = %d. Delay = %d.\n", Area, Delay ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |