From 4d30a1e4f1edecff86d5066ce4653a370e59e5e1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 30 Jan 2008 08:01:00 -0800 Subject: Version abc80130 --- src/aig/ivy/attr.h | 414 ------- src/aig/ivy/ivy.h | 557 ---------- src/aig/ivy/ivyBalance.c | 404 ------- src/aig/ivy/ivyCanon.c | 144 --- src/aig/ivy/ivyCheck.c | 273 ----- src/aig/ivy/ivyCut.c | 989 ----------------- src/aig/ivy/ivyCutTrav.c | 473 -------- src/aig/ivy/ivyDfs.c | 493 --------- src/aig/ivy/ivyDsd.c | 819 -------------- src/aig/ivy/ivyFanout.c | 309 ------ src/aig/ivy/ivyFastMap.c | 1593 -------------------------- src/aig/ivy/ivyFraig.c | 2760 ---------------------------------------------- src/aig/ivy/ivyHaig.c | 530 --------- src/aig/ivy/ivyMan.c | 546 --------- src/aig/ivy/ivyMem.c | 116 -- src/aig/ivy/ivyMulti.c | 301 ----- src/aig/ivy/ivyMulti8.c | 427 ------- src/aig/ivy/ivyObj.c | 476 -------- src/aig/ivy/ivyOper.c | 293 ----- src/aig/ivy/ivyResyn.c | 196 ---- src/aig/ivy/ivyRwr.c | 609 ---------- src/aig/ivy/ivyRwrAlg.c | 408 ------- src/aig/ivy/ivySeq.c | 1134 ------------------- src/aig/ivy/ivyShow.c | 338 ------ src/aig/ivy/ivyTable.c | 301 ----- src/aig/ivy/ivyUtil.c | 818 -------------- src/aig/ivy/ivy_.c | 48 - src/aig/ivy/module.make | 22 - 28 files changed, 15791 deletions(-) delete mode 100644 src/aig/ivy/attr.h delete mode 100644 src/aig/ivy/ivy.h delete mode 100644 src/aig/ivy/ivyBalance.c delete mode 100644 src/aig/ivy/ivyCanon.c delete mode 100644 src/aig/ivy/ivyCheck.c delete mode 100644 src/aig/ivy/ivyCut.c delete mode 100644 src/aig/ivy/ivyCutTrav.c delete mode 100644 src/aig/ivy/ivyDfs.c delete mode 100644 src/aig/ivy/ivyDsd.c delete mode 100644 src/aig/ivy/ivyFanout.c delete mode 100644 src/aig/ivy/ivyFastMap.c delete mode 100644 src/aig/ivy/ivyFraig.c delete mode 100644 src/aig/ivy/ivyHaig.c delete mode 100644 src/aig/ivy/ivyMan.c delete mode 100644 src/aig/ivy/ivyMem.c delete mode 100644 src/aig/ivy/ivyMulti.c delete mode 100644 src/aig/ivy/ivyMulti8.c delete mode 100644 src/aig/ivy/ivyObj.c delete mode 100644 src/aig/ivy/ivyOper.c delete mode 100644 src/aig/ivy/ivyResyn.c delete mode 100644 src/aig/ivy/ivyRwr.c delete mode 100644 src/aig/ivy/ivyRwrAlg.c delete mode 100644 src/aig/ivy/ivySeq.c delete mode 100644 src/aig/ivy/ivyShow.c delete mode 100644 src/aig/ivy/ivyTable.c delete mode 100644 src/aig/ivy/ivyUtil.c delete mode 100644 src/aig/ivy/ivy_.c delete mode 100644 src/aig/ivy/module.make (limited to 'src/aig/ivy') diff --git a/src/aig/ivy/attr.h b/src/aig/ivy/attr.h deleted file mode 100644 index 16cf0b84..00000000 --- a/src/aig/ivy/attr.h +++ /dev/null @@ -1,414 +0,0 @@ -/**CFile**************************************************************** - - FileName [attr.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network attributes.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: attr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __ATTR_H__ -#define __ATTR_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "extra.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Attr_ManStruct_t_ Attr_Man_t; -struct Attr_ManStruct_t_ -{ - // attribute info - int nAttrSize; // the size of each attribute in bytes - Extra_MmFixed_t * pManMem; // memory manager for attributes - int nAttrs; // the number of attributes allocated - void ** pAttrs; // the array of attributes - int fUseInt; // uses integer attributes - // attribute specific info - void * pManAttr; // the manager for this attribute - void (*pFuncFreeMan) (void *); // the procedure to call to free attribute-specific manager - void (*pFuncFreeObj) (void *, void *); // the procedure to call to free attribute-specific data -}; - -// at any time, an attribute of the given ID can be -// - not available (p->nAttrs < Id) -// - available but not allocated (p->nAttrs >= Id && p->pAttrs[Id] == NULL) -// - available and allocated (p->nAttrs >= Id && p->pAttrs[Id] != NULL) - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates the attribute manager.] - - Description [The manager is simple if it does not need memory manager.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Attr_Man_t * Attr_ManAlloc( int nAttrSize, int fManMem ) -{ - Attr_Man_t * p; - p = ALLOC( Attr_Man_t, 1 ); - memset( p, 0, sizeof(Attr_Man_t) ); - p->nAttrSize = nAttrSize; - if ( fManMem ) - p->pManMem = Extra_MmFixedStart( nAttrSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Start the attribute manager for integers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Attr_Man_t * Attr_ManStartInt( int nAttrs ) -{ - Attr_Man_t * p; - p = Attr_ManAlloc( sizeof(int), 0 ); - p->nAttrs = nAttrs; - p->pAttrs = (void **)ALLOC( int, nAttrs ); - memset( (int *)p->pAttrs, 0, sizeof(int) * nAttrs ); - p->fUseInt = 1; - return p; -} - -/**Function************************************************************* - - Synopsis [Start the attribute manager for pointers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Attr_Man_t * Attr_ManStartPtr( int nAttrs ) -{ - Attr_Man_t * p; - p = Attr_ManAlloc( sizeof(void *), 0 ); - p->nAttrs = nAttrs; - p->pAttrs = ALLOC( void *, nAttrs ); - memset( p->pAttrs, 0, sizeof(void *) * nAttrs ); - return p; -} - -/**Function************************************************************* - - Synopsis [Start the attribute manager for the fixed entry size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Attr_Man_t * Attr_ManStartPtrMem( int nAttrs, int nAttrSize ) -{ - Attr_Man_t * p; - int i; - p = Attr_ManAlloc( nAttrSize, 1 ); - p->nAttrs = nAttrs; - p->pAttrs = ALLOC( void *, nAttrs ); - for ( i = 0; i < p->nAttrs; i++ ) - { - p->pAttrs[i] = Extra_MmFixedEntryFetch( p->pManMem ); - memset( p->pAttrs[i], 0, nAttrSize ); - } - return p; -} - -/**Function************************************************************* - - Synopsis [Stop the attribute manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Attr_ManStop( Attr_Man_t * p ) -{ - // free the attributes of objects - if ( p->pFuncFreeObj ) - { - int i; - if ( p->fUseInt ) - { - for ( i = 0; i < p->nAttrs; i++ ) - if ( ((int *)p->pAttrs)[i] ) - p->pFuncFreeObj( p->pManAttr, (void *)((int *)p->pAttrs)[i] ); - } - else - { - for ( i = 0; i < p->nAttrs; i++ ) - if ( p->pAttrs[i] ) - p->pFuncFreeObj( p->pManAttr, p->pAttrs[i] ); - } - } - // free the attribute manager - if ( p->pManAttr && p->pFuncFreeMan ) - p->pFuncFreeMan( p->pManAttr ); - // free the memory manager - if ( p->pManMem ) - Extra_MmFixedStop( p->pManMem); - // free the attribute manager - FREE( p->pAttrs ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Reads the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Attr_ManReadAttrInt( Attr_Man_t * p, int Id ) -{ - assert( p->fUseInt ); - if ( Id >= p->nAttrs ) - return 0; - return ((int *)p->pAttrs)[Id]; -} - -/**Function************************************************************* - - Synopsis [Reads the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void * Attr_ManReadAttrPtr( Attr_Man_t * p, int Id ) -{ - assert( !p->fUseInt ); - if ( Id >= p->nAttrs ) - return NULL; - return p->pAttrs[Id]; -} - -/**Function************************************************************* - - Synopsis [Writes the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Attr_ManWriteAttrInt( Attr_Man_t * p, int Id, int Attr ) -{ - assert( p->fUseInt ); - ((int *)p->pAttrs)[Id] = Attr; -} - -/**Function************************************************************* - - Synopsis [Writes the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Attr_ManWriteAttrPtr( Attr_Man_t * p, int Id, void * pAttr ) -{ - assert( !p->fUseInt ); - assert( p->pManMem == NULL ); - p->pAttrs[Id] = pAttr; -} - -/**Function************************************************************* - - Synopsis [Returns or creates the pointer to the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int * Attr_ManFetchSpotInt( Attr_Man_t * p, int Id ) -{ - assert( p->fUseInt ); - if ( Id >= p->nAttrs ) - { - // save the old size - int i, nAttrsOld = p->nAttrs; - // get the new size - p->nAttrs = p->nAttrs? 2*p->nAttrs : 1024; - p->pAttrs = realloc( p->pAttrs, sizeof(int) * p->nAttrs ); - // fill in the empty spots - for ( i = nAttrsOld; i < p->nAttrs; i++ ) - ((int *)p->pAttrs)[Id] = 0; - } - return ((int *)p->pAttrs) + Id; -} - -/**Function************************************************************* - - Synopsis [Returns or creates the pointer to the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void ** Attr_ManFetchSpotPtr( Attr_Man_t * p, int Id ) -{ - assert( !p->fUseInt ); - if ( Id >= p->nAttrs ) - { - // save the old size - int i, nAttrsOld = p->nAttrs; - // get the new size - p->nAttrs = p->nAttrs? 2*p->nAttrs : 1024; - p->pAttrs = realloc( p->pAttrs, sizeof(void *) * p->nAttrs ); - // fill in the empty spots - for ( i = nAttrsOld; i < p->nAttrs; i++ ) - p->pAttrs[Id] = NULL; - } - // if memory manager is available but entry is not created, create it - if ( p->pManMem && p->pAttrs[Id] != NULL ) - { - p->pAttrs[Id] = Extra_MmFixedEntryFetch( p->pManMem ); - memset( p->pAttrs[Id], 0, p->nAttrSize ); - } - return p->pAttrs + Id; -} - - -/**Function************************************************************* - - Synopsis [Returns or creates the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Attr_ManFetchAttrInt( Attr_Man_t * p, int Id ) -{ - return *Attr_ManFetchSpotInt( p, Id ); -} - -/**Function************************************************************* - - Synopsis [Returns or creates the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void * Attr_ManFetchAttrPtr( Attr_Man_t * p, int Id ) -{ - return *Attr_ManFetchSpotPtr( p, Id ); -} - -/**Function************************************************************* - - Synopsis [Sets the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Attr_ManSetAttrInt( Attr_Man_t * p, int Id, int Attr ) -{ - *Attr_ManFetchSpotInt( p, Id ) = Attr; -} - -/**Function************************************************************* - - Synopsis [Sets the attribute of the given object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Attr_ManSetAttrPtr( Attr_Man_t * p, int Id, void * pAttr ) -{ - assert( p->pManMem == NULL ); - *Attr_ManFetchSpotPtr( p, Id ) = pAttr; -} - - - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/aig/ivy/ivy.h b/src/aig/ivy/ivy.h deleted file mode 100644 index c7435a63..00000000 --- a/src/aig/ivy/ivy.h +++ /dev/null @@ -1,557 +0,0 @@ -/**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 -#include "extra.h" -#include "vec.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Ivy_Man_t_ Ivy_Man_t; -typedef struct Ivy_Obj_t_ Ivy_Obj_t; -typedef int Ivy_Edge_t; -typedef struct Ivy_FraigParams_t_ Ivy_FraigParams_t; - -// object types -typedef enum { - IVY_NONE, // 0: non-existent object - 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: AND node - IVY_EXOR, // 6: EXOR node - IVY_BUF, // 7: buffer (temporary) - IVY_VOID // 8: unused object -} 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_ // 24 bytes (32-bit) or 32 bytes (64-bit) // 10 words - 16 words -{ - int Id; // integer ID - int TravId; // traversal ID - unsigned Type : 4; // object type - unsigned fMarkA : 1; // multipurpose mask - unsigned fMarkB : 1; // multipurpose mask - unsigned fExFan : 1; // set to 1 if last fanout added is EXOR - unsigned fPhase : 1; // value under 000...0 pattern - unsigned fFailTfo : 1; // the TFO of the failed node - unsigned Init : 2; // latch initial value - unsigned Level : 21; // logic level - int nRefs; // reference counter - Ivy_Obj_t * pFanin0; // fanin - Ivy_Obj_t * pFanin1; // fanin - Ivy_Obj_t * pFanout; // fanout - Ivy_Obj_t * pNextFan0; // next fanout of the first fanin - Ivy_Obj_t * pNextFan1; // next fanout of the second fanin - Ivy_Obj_t * pPrevFan0; // prev fanout of the first fanin - Ivy_Obj_t * pPrevFan1; // prev fanout of the second fanin - Ivy_Obj_t * pEquiv; // equivalent node -}; - -// the AIG manager -struct Ivy_Man_t_ -{ - // AIG nodes - Vec_Ptr_t * vPis; // the array of PIs - Vec_Ptr_t * vPos; // the array of POs - Vec_Ptr_t * vBufs; // the array of buffers - Vec_Ptr_t * vObjs; // the array of objects - Ivy_Obj_t * pConst1; // the constant 1 node - Ivy_Obj_t Ghost; // the ghost node - // AIG node counters - int nObjs[IVY_VOID];// the number of objects by type - int nCreated; // the number of created objects - int nDeleted; // the number of deleted objects - // stuctural hash table - int * pTable; // structural hash table - int nTableSize; // structural hash table size - // various data members - int fCatchExor; // set to 1 to detect EXORs - int nTravIds; // the traversal ID - int nLevelMax; // the maximum level - Vec_Int_t * vRequired; // required times - int fFanout; // fanout is allocated - void * pData; // the temporary data - void * pCopy; // the temporary data - Ivy_Man_t * pHaig; // history AIG if present - int nClassesSkip; // the number of skipped classes - // memory management - Vec_Ptr_t * vChunks; // allocated memory pieces - Vec_Ptr_t * vPages; // memory pages used by nodes - Ivy_Obj_t * pListFree; // the list of free nodes - // timing statistics - int time1; - int time2; -}; - -struct Ivy_FraigParams_t_ -{ - int nSimWords; // the number of words in the simulation info - double dSimSatur; // the ratio of refined classes when saturation is reached - int fPatScores; // enables simulation pattern scoring - int MaxScore; // max score after which resimulation is used - double dActConeRatio; // the ratio of cone to be bumped - double dActConeBumpMax; // the largest bump in activity - int fProve; // prove the miter outputs - int fVerbose; // verbose output - int fDoSparse; // skip sparse functions - int nBTLimitNode; // conflict limit at a node - int nBTLimitMiter; // conflict limit at an output -// int nBTLimitGlobal; // conflict limit global -// int nInsLimitNode; // inspection limit at a node -// int nInsLimitMiter; // inspection limit at an output -// int nInsLimitGlobal; // inspection limit global -}; - - -#define IVY_CUT_LIMIT 256 -#define IVY_CUT_INPUT 6 - -typedef struct Ivy_Cut_t_ Ivy_Cut_t; -struct Ivy_Cut_t_ -{ - int nLatches; - short nSize; - short nSizeMax; - int pArray[IVY_CUT_INPUT]; - unsigned uHash; -}; - -typedef struct Ivy_Store_t_ Ivy_Store_t; -struct Ivy_Store_t_ -{ - int nCuts; - int nCutsM; - int nCutsMax; - int fSatur; - Ivy_Cut_t pCuts[IVY_CUT_LIMIT]; // storage for cuts -}; - -#define IVY_LEAF_MASK 255 -#define IVY_LEAF_BITS 8 - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -#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 Ivy_Obj_t * Ivy_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned long)(p) & ~01); } -static inline Ivy_Obj_t * Ivy_Not( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned long)(p) ^ 01); } -static inline Ivy_Obj_t * Ivy_NotCond( Ivy_Obj_t * p, int c ) { return (Ivy_Obj_t *)((unsigned long)(p) ^ (c)); } -static inline int Ivy_IsComplement( Ivy_Obj_t * p ) { return (int)((unsigned long)(p) & 01); } - -static inline Ivy_Obj_t * Ivy_ManConst0( Ivy_Man_t * p ) { return Ivy_Not(p->pConst1); } -static inline Ivy_Obj_t * Ivy_ManConst1( Ivy_Man_t * p ) { return p->pConst1; } -static inline Ivy_Obj_t * Ivy_ManGhost( Ivy_Man_t * p ) { return &p->Ghost; } -static inline Ivy_Obj_t * Ivy_ManPi( Ivy_Man_t * p, int i ) { return (Ivy_Obj_t *)Vec_PtrEntry(p->vPis, i); } -static inline Ivy_Obj_t * Ivy_ManPo( Ivy_Man_t * p, int i ) { return (Ivy_Obj_t *)Vec_PtrEntry(p->vPos, i); } -static inline Ivy_Obj_t * Ivy_ManObj( Ivy_Man_t * p, int i ) { return (Ivy_Obj_t *)Vec_PtrEntry(p->vObjs, i); } - -static inline Ivy_Edge_t Ivy_EdgeCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; } -static inline int Ivy_EdgeId( Ivy_Edge_t Edge ) { return Edge >> 1; } -static inline int Ivy_EdgeIsComplement( Ivy_Edge_t Edge ) { return Edge & 1; } -static inline Ivy_Edge_t Ivy_EdgeRegular( Ivy_Edge_t Edge ) { return (Edge >> 1) << 1; } -static inline Ivy_Edge_t Ivy_EdgeNot( Ivy_Edge_t Edge ) { return Edge ^ 1; } -static inline Ivy_Edge_t Ivy_EdgeNotCond( Ivy_Edge_t Edge, int fCond ) { return Edge ^ fCond; } -static inline Ivy_Edge_t Ivy_EdgeFromNode( Ivy_Obj_t * pNode ) { return Ivy_EdgeCreate( Ivy_Regular(pNode)->Id, Ivy_IsComplement(pNode) ); } -static inline Ivy_Obj_t * Ivy_EdgeToNode( Ivy_Man_t * p, Ivy_Edge_t Edge ){ return Ivy_NotCond( Ivy_ManObj(p, Ivy_EdgeId(Edge)), Ivy_EdgeIsComplement(Edge) ); } - -static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << IVY_LEAF_BITS) | Lat; } -static inline int Ivy_LeafId( int Leaf ) { return Leaf >> IVY_LEAF_BITS; } -static inline int Ivy_LeafLat( int Leaf ) { return Leaf & IVY_LEAF_MASK; } - -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_ManObjNum( Ivy_Man_t * p ) { return p->nCreated - p->nDeleted; } -static inline int Ivy_ManObjIdMax( Ivy_Man_t * p ) { return Vec_PtrSize(p->vObjs)-1; } -static inline int Ivy_ManNodeNum( Ivy_Man_t * p ) { return 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 ) { return pObj->Type; } -static inline Ivy_Init_t Ivy_ObjInit( Ivy_Obj_t * pObj ) { return pObj->Init; } -static inline int Ivy_ObjIsConst1( Ivy_Obj_t * pObj ) { return pObj->Id == 0; } -static inline int Ivy_ObjIsGhost( Ivy_Obj_t * pObj ) { return pObj->Id < 0; } -static inline int Ivy_ObjIsNone( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_NONE; } -static inline int Ivy_ObjIsPi( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PI; } -static inline int Ivy_ObjIsPo( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PO; } -static inline int Ivy_ObjIsCi( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PI || pObj->Type == IVY_LATCH; } -static inline int Ivy_ObjIsCo( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PO || pObj->Type == IVY_LATCH; } -static inline int Ivy_ObjIsAssert( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_ASSERT; } -static inline int Ivy_ObjIsLatch( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_LATCH; } -static inline int Ivy_ObjIsAnd( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_AND; } -static inline int Ivy_ObjIsExor( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_EXOR; } -static inline int Ivy_ObjIsBuf( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_BUF; } -static inline int Ivy_ObjIsNode( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR; } -static inline int Ivy_ObjIsTerm( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PI || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; } -static inline int Ivy_ObjIsHash( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR || pObj->Type == IVY_LATCH; } -static inline int Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; } - -static inline int Ivy_ObjIsMarkA( Ivy_Obj_t * pObj ) { return pObj->fMarkA; } -static inline void Ivy_ObjSetMarkA( Ivy_Obj_t * pObj ) { pObj->fMarkA = 1; } -static inline void Ivy_ObjClearMarkA( Ivy_Obj_t * pObj ) { pObj->fMarkA = 0; } - -static inline void Ivy_ObjSetTravId( Ivy_Obj_t * pObj, int TravId ) { pObj->TravId = TravId; } -static inline void Ivy_ObjSetTravIdCurrent( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { pObj->TravId = p->nTravIds; } -static inline void Ivy_ObjSetTravIdPrevious( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { pObj->TravId = p->nTravIds - 1; } -static inline int Ivy_ObjIsTravIdCurrent( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return (int )((int)pObj->TravId == p->nTravIds); } -static inline int Ivy_ObjIsTravIdPrevious( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return (int )((int)pObj->TravId == p->nTravIds - 1); } - -static inline int Ivy_ObjId( Ivy_Obj_t * pObj ) { return pObj->Id; } -static inline int Ivy_ObjTravId( Ivy_Obj_t * pObj ) { return pObj->TravId; } -static inline int Ivy_ObjPhase( Ivy_Obj_t * pObj ) { return pObj->fPhase; } -static inline int Ivy_ObjExorFanout( Ivy_Obj_t * pObj ) { return pObj->fExFan; } -static inline int Ivy_ObjRefs( Ivy_Obj_t * pObj ) { return pObj->nRefs; } -static inline void Ivy_ObjRefsInc( Ivy_Obj_t * pObj ) { pObj->nRefs++; } -static inline void Ivy_ObjRefsDec( Ivy_Obj_t * pObj ) { assert( pObj->nRefs > 0 ); pObj->nRefs--; } -static inline int Ivy_ObjFaninId0( Ivy_Obj_t * pObj ) { return pObj->pFanin0? Ivy_ObjId(Ivy_Regular(pObj->pFanin0)) : 0; } -static inline int Ivy_ObjFaninId1( Ivy_Obj_t * pObj ) { return pObj->pFanin1? Ivy_ObjId(Ivy_Regular(pObj->pFanin1)) : 0; } -static inline int Ivy_ObjFaninC0( Ivy_Obj_t * pObj ) { return Ivy_IsComplement(pObj->pFanin0); } -static inline int Ivy_ObjFaninC1( Ivy_Obj_t * pObj ) { return Ivy_IsComplement(pObj->pFanin1); } -static inline Ivy_Obj_t * Ivy_ObjFanin0( Ivy_Obj_t * pObj ) { return Ivy_Regular(pObj->pFanin0); } -static inline Ivy_Obj_t * Ivy_ObjFanin1( Ivy_Obj_t * pObj ) { return Ivy_Regular(pObj->pFanin1); } -static inline Ivy_Obj_t * Ivy_ObjChild0( Ivy_Obj_t * pObj ) { return pObj->pFanin0; } -static inline Ivy_Obj_t * Ivy_ObjChild1( Ivy_Obj_t * pObj ) { return pObj->pFanin1; } -static inline Ivy_Obj_t * Ivy_ObjChild0Equiv( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjFanin0(pObj)? Ivy_NotCond(Ivy_ObjFanin0(pObj)->pEquiv, Ivy_ObjFaninC0(pObj)) : NULL; } -static inline Ivy_Obj_t * Ivy_ObjChild1Equiv( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjFanin1(pObj)? Ivy_NotCond(Ivy_ObjFanin1(pObj)->pEquiv, Ivy_ObjFaninC1(pObj)) : NULL; } -static inline Ivy_Obj_t * Ivy_ObjEquiv( Ivy_Obj_t * pObj ) { return Ivy_Regular(pObj)->pEquiv? Ivy_NotCond(Ivy_Regular(pObj)->pEquiv, Ivy_IsComplement(pObj)) : NULL; } -static inline int Ivy_ObjLevel( Ivy_Obj_t * pObj ) { return pObj->Level; } -static inline int Ivy_ObjLevelNew( Ivy_Obj_t * pObj ) { return 1 + Ivy_ObjIsExor(pObj) + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level); } -static inline int Ivy_ObjFaninPhase( Ivy_Obj_t * pObj ) { return Ivy_IsComplement(pObj)? !Ivy_Regular(pObj)->fPhase : pObj->fPhase; } - -static inline void Ivy_ObjClean( Ivy_Obj_t * pObj ) -{ - int IdSaved = pObj->Id; - 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_ObjFanin0(pObj) == pFanin ) return 0; - if ( Ivy_ObjFanin1(pObj) == pFanin ) return 1; - assert(0); return -1; -} -static inline int Ivy_ObjFanoutC( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) -{ - if ( Ivy_ObjFanin0(pFanout) == pObj ) return Ivy_ObjFaninC0(pObj); - if ( Ivy_ObjFanin1(pFanout) == pObj ) return Ivy_ObjFaninC1(pObj); - assert(0); return -1; -} - -// create the ghost of the new node -static inline Ivy_Obj_t * Ivy_ObjCreateGhost( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type, Ivy_Init_t Init ) -{ - Ivy_Obj_t * pGhost, * pTemp; - assert( Type != IVY_AND || !Ivy_ObjIsConst1(Ivy_Regular(p0)) ); - assert( p1 == NULL || !Ivy_ObjIsConst1(Ivy_Regular(p1)) ); - assert( Type == IVY_PI || Ivy_Regular(p0) != Ivy_Regular(p1) ); - assert( Type != IVY_LATCH || !Ivy_IsComplement(p0) ); -// assert( p1 == NULL || (!Ivy_ObjIsLatch(Ivy_Regular(p0)) || !Ivy_ObjIsLatch(Ivy_Regular(p1))) ); - pGhost = Ivy_ManGhost(p); - pGhost->Type = Type; - pGhost->Init = Init; - pGhost->pFanin0 = p0; - pGhost->pFanin1 = p1; - if ( p1 && Ivy_ObjFaninId0(pGhost) > Ivy_ObjFaninId1(pGhost) ) - pTemp = pGhost->pFanin0, pGhost->pFanin0 = pGhost->pFanin1, pGhost->pFanin1 = pTemp; - 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; -} - -// internal memory manager -static inline Ivy_Obj_t * Ivy_ManFetchMemory( Ivy_Man_t * p ) -{ - extern void Ivy_ManAddMemory( Ivy_Man_t * p ); - Ivy_Obj_t * pTemp; - if ( p->pListFree == NULL ) - Ivy_ManAddMemory( p ); - pTemp = p->pListFree; - p->pListFree = *((Ivy_Obj_t **)pTemp); - memset( pTemp, 0, sizeof(Ivy_Obj_t) ); - return pTemp; -} -static inline void Ivy_ManRecycleMemory( Ivy_Man_t * p, Ivy_Obj_t * pEntry ) -{ - pEntry->Type = IVY_NONE; // distinquishes dead node from live node - *((Ivy_Obj_t **)pEntry) = p->pListFree; - p->pListFree = pEntry; -} - - -//////////////////////////////////////////////////////////////////////// -/// ITERATORS /// -//////////////////////////////////////////////////////////////////////// - -// iterator over the primary inputs -#define Ivy_ManForEachPi( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPis, pObj, i ) -// iterator over the primary outputs -#define Ivy_ManForEachPo( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vPos, pObj, i ) -// iterator over all objects, including those currently not used -#define Ivy_ManForEachObj( p, pObj, i ) \ - Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else -// iterator over the combinational inputs -#define Ivy_ManForEachCi( p, pObj, i ) \ - Ivy_ManForEachObj( p, pObj, i ) if ( !Ivy_ObjIsCi(pObj) ) {} else -// iterator over the combinational outputs -#define Ivy_ManForEachCo( p, pObj, i ) \ - Ivy_ManForEachObj( p, pObj, i ) if ( !Ivy_ObjIsCo(pObj) ) {} else -// iterator over logic nodes (AND and EXOR gates) -#define Ivy_ManForEachNode( p, pObj, i ) \ - Ivy_ManForEachObj( p, pObj, i ) if ( !Ivy_ObjIsNode(pObj) ) {} else -// iterator over logic latches -#define Ivy_ManForEachLatch( p, pObj, i ) \ - Ivy_ManForEachObj( p, pObj, i ) 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++ ) -// iterator over the fanouts of an object -#define Ivy_ObjForEachFanout( p, pObj, vArray, pFanout, i ) \ - for ( i = 0, Ivy_ObjCollectFanouts(p, pObj, vArray); \ - i < Vec_PtrSize(vArray) && ((pFanout) = Vec_PtrEntry(vArray,i)); i++ ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== ivyBalance.c ========================================================*/ -extern Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel ); -extern Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel ); -/*=== ivyCanon.c ========================================================*/ -extern Ivy_Obj_t * Ivy_CanonAnd( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); -extern Ivy_Obj_t * Ivy_CanonExor( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); -extern Ivy_Obj_t * Ivy_CanonLatch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init ); -/*=== ivyCheck.c ========================================================*/ -extern int Ivy_ManCheck( Ivy_Man_t * p ); -extern int Ivy_ManCheckFanoutNums( Ivy_Man_t * p ); -extern int Ivy_ManCheckFanouts( Ivy_Man_t * p ); -extern int Ivy_ManCheckChoices( Ivy_Man_t * p ); -/*=== ivyCut.c ==========================================================*/ -extern void Ivy_ManSeqFindCut( Ivy_Man_t * p, Ivy_Obj_t * pNode, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize ); -extern Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves ); -/*=== ivyDfs.c ==========================================================*/ -extern Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p ); -extern Vec_Int_t * Ivy_ManDfsSeq( Ivy_Man_t * p, Vec_Int_t ** pvLatches ); -extern void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone ); -extern Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p ); -extern Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p ); -extern int Ivy_ManIsAcyclic( Ivy_Man_t * p ); -extern int Ivy_ManSetLevels( Ivy_Man_t * p, int fHaig ); -/*=== 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 ); -/*=== ivyFanout.c ==========================================================*/ -extern void Ivy_ManStartFanout( Ivy_Man_t * p ); -extern void Ivy_ManStopFanout( Ivy_Man_t * p ); -extern void Ivy_ObjAddFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ); -extern void Ivy_ObjDeleteFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ); -extern void Ivy_ObjPatchFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanoutOld, Ivy_Obj_t * pFanoutNew ); -extern void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vArray ); -extern Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -extern int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -/*=== ivyFastMap.c =============================================================*/ -extern void Ivy_FastMapPerform( Ivy_Man_t * pAig, int nLimit, int fRecovery, int fVerbose ); -extern void Ivy_FastMapStop( Ivy_Man_t * pAig ); -extern void Ivy_FastMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves ); -extern void Ivy_FastMapReverseLevel( Ivy_Man_t * pAig ); -/*=== ivyFraig.c ==========================================================*/ -extern int Ivy_FraigProve( Ivy_Man_t ** ppManAig, void * pPars ); -extern Ivy_Man_t * Ivy_FraigPerform( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams ); -extern Ivy_Man_t * Ivy_FraigMiter( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams ); -extern void Ivy_FraigParamsDefault( Ivy_FraigParams_t * pParams ); -/*=== ivyHaig.c ==========================================================*/ -extern void Ivy_ManHaigStart( Ivy_Man_t * p, int fVerbose ); -extern void Ivy_ManHaigTrasfer( Ivy_Man_t * p, Ivy_Man_t * pNew ); -extern void Ivy_ManHaigStop( Ivy_Man_t * p ); -extern void Ivy_ManHaigPostprocess( Ivy_Man_t * p, int fVerbose ); -extern void Ivy_ManHaigCreateObj( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -extern void Ivy_ManHaigCreateChoice( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew ); -extern void Ivy_ManHaigSimulate( Ivy_Man_t * p ); -/*=== ivyMan.c ==========================================================*/ -extern Ivy_Man_t * Ivy_ManStart(); -extern Ivy_Man_t * Ivy_ManStartFrom( Ivy_Man_t * p ); -extern Ivy_Man_t * Ivy_ManDup( Ivy_Man_t * p ); -extern Ivy_Man_t * Ivy_ManFrames( Ivy_Man_t * pMan, int nLatches, int nFrames, int fInit, Vec_Ptr_t ** pvMapping ); -extern void Ivy_ManStop( Ivy_Man_t * p ); -extern int Ivy_ManCleanup( Ivy_Man_t * p ); -extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel ); -extern void Ivy_ManPrintStats( Ivy_Man_t * p ); -extern void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits ); -/*=== ivyMem.c ==========================================================*/ -extern void Ivy_ManStartMemory( Ivy_Man_t * p ); -extern void Ivy_ManStopMemory( Ivy_Man_t * p ); -/*=== ivyMulti.c ==========================================================*/ -extern Ivy_Obj_t * Ivy_Multi( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); -extern Ivy_Obj_t * Ivy_Multi1( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); -extern Ivy_Obj_t * Ivy_Multi_rec( Ivy_Man_t * p, Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type ); -extern Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); -extern int Ivy_MultiPlus( Ivy_Man_t * p, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSol ); -/*=== ivyObj.c ==========================================================*/ -extern Ivy_Obj_t * Ivy_ObjCreatePi( Ivy_Man_t * p ); -extern Ivy_Obj_t * Ivy_ObjCreatePo( Ivy_Man_t * p, Ivy_Obj_t * pDriver ); -extern Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost ); -extern void Ivy_ObjConnect( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFan0, Ivy_Obj_t * pFan1 ); -extern void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -extern void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew ); -extern void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ); -extern void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ); -extern void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel ); -extern void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel ); -/*=== ivyOper.c =========================================================*/ -extern Ivy_Obj_t * Ivy_Oper( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type ); -extern Ivy_Obj_t * Ivy_And( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); -extern Ivy_Obj_t * Ivy_Or( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); -extern Ivy_Obj_t * Ivy_Exor( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); -extern Ivy_Obj_t * Ivy_Mux( Ivy_Man_t * p, Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 ); -extern Ivy_Obj_t * Ivy_Maj( Ivy_Man_t * p, Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC ); -extern Ivy_Obj_t * Ivy_Miter( Ivy_Man_t * p, Vec_Ptr_t * vPairs ); -extern Ivy_Obj_t * Ivy_Latch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init ); -/*=== ivyResyn.c =========================================================*/ -extern Ivy_Man_t * Ivy_ManResyn0( Ivy_Man_t * p, int fUpdateLevel, int fVerbose ); -extern Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * p, int fUpdateLevel, int fVerbose ); -extern Ivy_Man_t * Ivy_ManRwsat( Ivy_Man_t * pMan, int fVerbose ); -/*=== ivyRewrite.c =========================================================*/ -extern int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ); -extern int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ); -extern int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose ); -/*=== ivySeq.c =========================================================*/ -extern int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose ); -/*=== ivyShow.c =========================================================*/ -extern void Ivy_ManShow( Ivy_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold ); -/*=== ivyTable.c ========================================================*/ -extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -extern void Ivy_TableInsert( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -extern void Ivy_TableDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -extern void Ivy_TableUpdate( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ObjIdNew ); -extern int Ivy_TableCountEntries( Ivy_Man_t * p ); -extern void Ivy_TableProfile( Ivy_Man_t * p ); -/*=== ivyUtil.c =========================================================*/ -extern void Ivy_ManIncrementTravId( Ivy_Man_t * p ); -extern void Ivy_ManCleanTravId( Ivy_Man_t * p ); -extern unsigned * Ivy_ManCutTruth( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth ); -extern void Ivy_ManCollectCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes ); -extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p ); -extern int Ivy_ManLevels( Ivy_Man_t * p ); -extern void Ivy_ManResetLevels( Ivy_Man_t * p ); -extern int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -extern void Ivy_ObjUpdateLevel_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj ); -extern void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ReqNew ); -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 Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj ); -extern void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fHaig ); -extern void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig ); -extern int Ivy_CutTruthPrint( Ivy_Man_t * p, Ivy_Cut_t * pCut, unsigned uTruth ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/aig/ivy/ivyBalance.c b/src/aig/ivy/ivyBalance.c deleted file mode 100644 index 5627039a..00000000 --- a/src/aig/ivy/ivyBalance.c +++ /dev/null @@ -1,404 +0,0 @@ -/**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 int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel ); -static Vec_Ptr_t * Ivy_NodeBalanceCone( Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level ); -static int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper ); -static void Ivy_NodeBalancePermute( Ivy_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor ); -static void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs algebraic balancing of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel ) -{ - Ivy_Man_t * pNew; - Ivy_Obj_t * pObj, * pDriver; - Vec_Vec_t * vStore; - int i, NewNodeId; - // clean the old manager - Ivy_ManCleanTravId( p ); - // create the new manager - pNew = Ivy_ManStart(); - // map the nodes - Ivy_ManConst1(p)->TravId = Ivy_EdgeFromNode( Ivy_ManConst1(pNew) ); - Ivy_ManForEachPi( p, pObj, i ) - pObj->TravId = Ivy_EdgeFromNode( Ivy_ObjCreatePi(pNew) ); - // if HAIG is defined, trasfer the pointers to the PIs/latches -// if ( p->pHaig ) -// Ivy_ManHaigTrasfer( p, pNew ); - // balance the AIG - vStore = Vec_VecAlloc( 50 ); - Ivy_ManForEachPo( p, pObj, i ) - { - pDriver = Ivy_ObjReal( Ivy_ObjChild0(pObj) ); - NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular(pDriver), vStore, 0, fUpdateLevel ); - NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement(pDriver) ); - Ivy_ObjCreatePo( pNew, Ivy_EdgeToNode(pNew, NewNodeId) ); - } - Vec_VecFree( vStore ); - if ( i = Ivy_ManCleanup( pNew ) ) - { -// printf( "Cleanup after balancing removed %d dangling nodes.\n", i ); - } - // check the resulting AIG - if ( !Ivy_ManCheck(pNew) ) - printf( "Ivy_ManBalance(): The check has failed.\n" ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Procedure used for sorting the nodes in decreasing order of levels.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeCompareLevelsDecrease( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 ) -{ - int Diff = Ivy_Regular(*pp1)->Level - Ivy_Regular(*pp2)->Level; - if ( Diff > 0 ) - return -1; - if ( Diff < 0 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Returns the ID of new node constructed.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel ) -{ - Ivy_Obj_t * pObjNew; - Vec_Ptr_t * vSuper; - int i, NewNodeId; - assert( !Ivy_IsComplement(pObjOld) ); - assert( !Ivy_ObjIsBuf(pObjOld) ); - // return if the result is known - if ( Ivy_ObjIsConst1(pObjOld) ) - return pObjOld->TravId; - if ( pObjOld->TravId ) - return pObjOld->TravId; - assert( Ivy_ObjIsNode(pObjOld) ); - // get the implication supergate - vSuper = Ivy_NodeBalanceCone( pObjOld, vStore, Level ); - if ( vSuper->nSize == 0 ) - { // it means that the supergate contains two nodes in the opposite polarity - pObjOld->TravId = Ivy_EdgeFromNode( Ivy_ManConst0(pNew) ); - return pObjOld->TravId; - } - if ( vSuper->nSize < 2 ) - printf( "BUG!\n" ); - // for each old node, derive the new well-balanced node - for ( i = 0; i < vSuper->nSize; i++ ) - { - NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); - NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement(vSuper->pArray[i]) ); - vSuper->pArray[i] = Ivy_EdgeToNode( pNew, NewNodeId ); - } - // build the supergate - pObjNew = Ivy_NodeBalanceBuildSuper( pNew, vSuper, Ivy_ObjType(pObjOld), fUpdateLevel ); - vSuper->nSize = 0; - // make sure the balanced node is not assigned - assert( pObjOld->TravId == 0 ); - pObjOld->TravId = Ivy_EdgeFromNode( pObjNew ); -// assert( pObjOld->Level >= Ivy_Regular(pObjNew)->Level ); - return pObjOld->TravId; -} - -/**Function************************************************************* - - Synopsis [Builds implication supergate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel ) -{ - Ivy_Obj_t * pObj1, * pObj2; - int LeftBound; - assert( vSuper->nSize > 1 ); - // sort the new nodes by level in the decreasing order - Vec_PtrSort( vSuper, Ivy_NodeCompareLevelsDecrease ); - // balance the nodes - while ( vSuper->nSize > 1 ) - { - // find the left bound on the node to be paired - LeftBound = (!fUpdateLevel)? 0 : Ivy_NodeBalanceFindLeft( vSuper ); - // find the node that can be shared (if no such node, randomize choice) - Ivy_NodeBalancePermute( p, vSuper, LeftBound, Type == IVY_EXOR ); - // pull out the last two nodes - pObj1 = Vec_PtrPop(vSuper); - pObj2 = Vec_PtrPop(vSuper); - Ivy_NodeBalancePushUniqueOrderByLevel( vSuper, Ivy_Oper(p, pObj1, pObj2, Type) ); - } - return Vec_PtrEntry(vSuper, 0); -} - -/**Function************************************************************* - - Synopsis [Collects the nodes of the supergate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeBalanceCone_rec( Ivy_Obj_t * pRoot, Ivy_Obj_t * pObj, Vec_Ptr_t * vSuper ) -{ - int RetValue1, RetValue2, i; - // check if the node is visited - if ( Ivy_Regular(pObj)->fMarkB ) - { - // check if the node occurs in the same polarity - for ( i = 0; i < vSuper->nSize; i++ ) - if ( vSuper->pArray[i] == pObj ) - return 1; - // check if the node is present in the opposite polarity - for ( i = 0; i < vSuper->nSize; i++ ) - if ( vSuper->pArray[i] == Ivy_Not(pObj) ) - return -1; - assert( 0 ); - return 0; - } - // if the new node is complemented or a PI, another gate begins - if ( pObj != pRoot && (Ivy_IsComplement(pObj) || Ivy_ObjType(pObj) != Ivy_ObjType(pRoot) || Ivy_ObjRefs(pObj) > 1) ) - { - Vec_PtrPush( vSuper, pObj ); - Ivy_Regular(pObj)->fMarkB = 1; - return 0; - } - assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjIsNode(pObj) ); - // go through the branches - RetValue1 = Ivy_NodeBalanceCone_rec( pRoot, Ivy_ObjReal( Ivy_ObjChild0(pObj) ), vSuper ); - RetValue2 = Ivy_NodeBalanceCone_rec( pRoot, Ivy_ObjReal( Ivy_ObjChild1(pObj) ), vSuper ); - if ( RetValue1 == -1 || RetValue2 == -1 ) - return -1; - // return 1 if at least one branch has a duplicate - return RetValue1 || RetValue2; -} - -/**Function************************************************************* - - Synopsis [Collects the nodes of the supergate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Ivy_NodeBalanceCone( Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level ) -{ - Vec_Ptr_t * vNodes; - int RetValue, i; - assert( !Ivy_IsComplement(pObj) ); - // extend the storage - if ( Vec_VecSize( vStore ) <= Level ) - Vec_VecPush( vStore, Level, 0 ); - // get the temporary array of nodes - vNodes = Vec_VecEntry( vStore, Level ); - Vec_PtrClear( vNodes ); - // collect the nodes in the implication supergate - RetValue = Ivy_NodeBalanceCone_rec( pObj, pObj, vNodes ); - assert( vNodes->nSize > 1 ); - // unmark the visited nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - Ivy_Regular(pObj)->fMarkB = 0; - // if we found the node and its complement in the same implication supergate, - // return empty set of nodes (meaning that we should use constant-0 node) - if ( RetValue == -1 ) - vNodes->nSize = 0; - return vNodes; -} - -/**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 * pObjRight, * pObjLeft; - 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; - pObjRight = 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 - pObjLeft = Vec_PtrEntry( vSuper, Current ); - // if the level of this node is different, quit the loop - if ( Ivy_Regular(pObjLeft)->Level != Ivy_Regular(pObjRight)->Level ) - break; - } - Current++; - // get the node, for which the equality holds - pObjLeft = Vec_PtrEntry( vSuper, Current ); - assert( Ivy_Regular(pObjLeft)->Level == Ivy_Regular(pObjRight)->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 * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor ) -{ - Ivy_Obj_t * pObj1, * pObj2, * pObj3, * 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 - pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 ); - pObj2 = Vec_PtrEntry( vSuper, RightBound ); - if ( Ivy_Regular(pObj1) == p->pConst1 || Ivy_Regular(pObj2) == p->pConst1 ) - return; - // find the first node that can be shared - for ( i = RightBound; i >= LeftBound; i-- ) - { - pObj3 = Vec_PtrEntry( vSuper, i ); - if ( Ivy_Regular(pObj3) == p->pConst1 ) - { - Vec_PtrWriteEntry( vSuper, i, pObj2 ); - Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); - return; - } - pGhost = Ivy_ObjCreateGhost( p, pObj1, pObj3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE ); - if ( Ivy_TableLookup( p, pGhost ) ) - { - if ( pObj3 == pObj2 ) - return; - Vec_PtrWriteEntry( vSuper, i, pObj2 ); - Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); - return; - } - } -/* - // we did not find the node to share, randomize choice - { - int Choice = rand() % (RightBound - LeftBound + 1); - pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice ); - if ( pObj3 == pObj2 ) - return; - Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 ); - Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); - } -*/ -} - -/**Function************************************************************* - - Synopsis [Inserts a new node in the order by levels.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pObj1, * pObj2; - int i; - if ( Vec_PtrPushUnique(vStore, pObj) ) - return; - // find the p of the node - for ( i = vStore->nSize-1; i > 0; i-- ) - { - pObj1 = vStore->pArray[i ]; - pObj2 = vStore->pArray[i-1]; - if ( Ivy_Regular(pObj1)->Level <= Ivy_Regular(pObj2)->Level ) - break; - vStore->pArray[i ] = pObj2; - vStore->pArray[i-1] = pObj1; - } -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyCanon.c b/src/aig/ivy/ivyCanon.c deleted file mode 100644 index 5768b87e..00000000 --- a/src/aig/ivy/ivyCanon.c +++ /dev/null @@ -1,144 +0,0 @@ -/**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_Man_t * p, 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_Man_t * p, 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( p, pGhost ) ) - return pResult; - return Ivy_ObjCreate( p, 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); - // call recursively - pResult = Ivy_Oper( p, Ivy_NotCond(Ivy_ObjFanin0(pLat0), fCompl0), Ivy_NotCond(Ivy_ObjFanin0(pLat1), fCompl1), Type ); - // 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_Latch( p, pResult, Init ); -} - -/**Function************************************************************* - - Synopsis [Creates the canonical form of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_CanonAnd( Ivy_Man_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 ) -{ - Ivy_Obj_t * pGhost, * pResult; - pGhost = Ivy_ObjCreateGhost( p, pObj0, pObj1, IVY_AND, IVY_INIT_NONE ); - pResult = Ivy_CanonPair_rec( p, pGhost ); - return pResult; -} - -/**Function************************************************************* - - Synopsis [Creates the canonical form of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_CanonExor( Ivy_Man_t * p, 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( p, pObj0, pObj1, IVY_EXOR, IVY_INIT_NONE ); - pResult = Ivy_CanonPair_rec( p, pGhost ); - return Ivy_NotCond( pResult, fCompl ); -} - -/**Function************************************************************* - - Synopsis [Creates the canonical form of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_CanonLatch( Ivy_Man_t * p, 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( p, pObj, NULL, IVY_LATCH, Ivy_InitNotCond(Init, fCompl) ); - pResult = Ivy_TableLookup( p, pGhost ); - if ( pResult == NULL ) - pResult = Ivy_ObjCreate( p, pGhost ); - return Ivy_NotCond( pResult, fCompl ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyCheck.c b/src/aig/ivy/ivyCheck.c deleted file mode 100644 index 55448f19..00000000 --- a/src/aig/ivy/ivyCheck.c +++ /dev/null @@ -1,273 +0,0 @@ -/**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 * p ) -{ - Ivy_Obj_t * pObj, * pObj2; - int i; - Ivy_ManForEachObj( p, pObj, i ) - { - // skip deleted nodes - if ( Ivy_ObjId(pObj) != i ) - { - printf( "Ivy_ManCheck: Node with ID %d is listed as number %d in the array of objects.\n", pObj->Id, i ); - return 0; - } - // 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) ) - { - if ( Ivy_ObjFanin1(pObj) ) - { - printf( "Ivy_ManCheck: The buffer with ID \"%d\" contains second fanin.\n", pObj->Id ); - return 0; - } - continue; - } - if ( Ivy_ObjIsLatch(pObj) ) - { - if ( Ivy_ObjFanin1(pObj) ) - { - printf( "Ivy_ManCheck: The latch with ID \"%d\" contains second fanin.\n", pObj->Id ); - return 0; - } - if ( Ivy_ObjInit(pObj) == IVY_INIT_NONE ) - { - printf( "Ivy_ManCheck: The latch with ID \"%d\" does not have initial state.\n", pObj->Id ); - return 0; - } - pObj2 = Ivy_TableLookup( p, 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_ObjFanin0(pObj) || !Ivy_ObjFanin1(pObj) ) - { - printf( "Ivy_ManCheck: The AIG has internal node \"%d\" with a NULL 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 %d but should have level %d.\n", pObj->Id, Ivy_ObjLevel(pObj), Ivy_ObjLevelNew(pObj) ); - pObj2 = Ivy_TableLookup( p, pObj ); - if ( pObj2 != pObj ) - printf( "Ivy_ManCheck: Node with ID \"%d\" is not in the structural hashing table.\n", pObj->Id ); - if ( Ivy_ObjRefs(pObj) == 0 ) - printf( "Ivy_ManCheck: Node with ID \"%d\" has no fanouts.\n", pObj->Id ); - // check fanouts - if ( p->fFanout && Ivy_ObjRefs(pObj) != Ivy_ObjFanoutNum(p, pObj) ) - printf( "Ivy_ManCheck: Node with ID \"%d\" has mismatch between the number of fanouts and refs.\n", pObj->Id ); - } - // count the number of nodes in the table - if ( Ivy_TableCountEntries(p) != Ivy_ManAndNum(p) + Ivy_ManExorNum(p) + Ivy_ManLatchNum(p) ) - { - printf( "Ivy_ManCheck: The number of nodes in the structural hashing table is wrong.\n" ); - return 0; - } -// if ( !Ivy_ManCheckFanouts(p) ) -// return 0; - if ( !Ivy_ManIsAcyclic(p) ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Verifies the fanouts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManCheckFanoutNums( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - int i, Counter = 0; - Ivy_ManForEachObj( p, pObj, i ) - if ( Ivy_ObjIsNode(pObj) ) - Counter += (Ivy_ObjRefs(pObj) == 0); - if ( Counter ) - printf( "Sequential AIG has %d dangling nodes.\n", Counter ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Verifies the fanouts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManCheckFanouts( Ivy_Man_t * p ) -{ - Vec_Ptr_t * vFanouts; - Ivy_Obj_t * pObj, * pFanout, * pFanin; - int i, k, RetValue = 1; - if ( !p->fFanout ) - return 1; - vFanouts = Vec_PtrAlloc( 100 ); - // make sure every fanin is a fanout - Ivy_ManForEachObj( p, pObj, i ) - { - pFanin = Ivy_ObjFanin0(pObj); - if ( pFanin == NULL ) - continue; - Ivy_ObjForEachFanout( p, pFanin, vFanouts, pFanout, k ) - if ( pFanout == pObj ) - break; - if ( k == Vec_PtrSize(vFanouts) ) - { - printf( "Node %d is a fanin of node %d but the fanout is not there.\n", pFanin->Id, pObj->Id ); - RetValue = 0; - } - - pFanin = Ivy_ObjFanin1(pObj); - if ( pFanin == NULL ) - continue; - Ivy_ObjForEachFanout( p, pFanin, vFanouts, pFanout, k ) - if ( pFanout == pObj ) - break; - if ( k == Vec_PtrSize(vFanouts) ) - { - printf( "Node %d is a fanin of node %d but the fanout is not there.\n", pFanin->Id, pObj->Id ); - RetValue = 0; - } - // check that the previous fanout has the same fanin - if ( pObj->pPrevFan0 ) - { - if ( Ivy_ObjFanin0(pObj->pPrevFan0) != Ivy_ObjFanin0(pObj) && - Ivy_ObjFanin0(pObj->pPrevFan0) != Ivy_ObjFanin1(pObj) && - Ivy_ObjFanin1(pObj->pPrevFan0) != Ivy_ObjFanin0(pObj) && - Ivy_ObjFanin1(pObj->pPrevFan0) != Ivy_ObjFanin1(pObj) ) - { - printf( "Node %d has prev %d without common fanin.\n", pObj->Id, pObj->pPrevFan0->Id ); - RetValue = 0; - } - } - // check that the previous fanout has the same fanin - if ( pObj->pPrevFan1 ) - { - if ( Ivy_ObjFanin0(pObj->pPrevFan1) != Ivy_ObjFanin0(pObj) && - Ivy_ObjFanin0(pObj->pPrevFan1) != Ivy_ObjFanin1(pObj) && - Ivy_ObjFanin1(pObj->pPrevFan1) != Ivy_ObjFanin0(pObj) && - Ivy_ObjFanin1(pObj->pPrevFan1) != Ivy_ObjFanin1(pObj) ) - { - printf( "Node %d has prev %d without common fanin.\n", pObj->Id, pObj->pPrevFan1->Id ); - RetValue = 0; - } - } - } - // make sure every fanout is a fanin - Ivy_ManForEachObj( p, pObj, i ) - { - Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, k ) - if ( Ivy_ObjFanin0(pFanout) != pObj && Ivy_ObjFanin1(pFanout) != pObj ) - { - printf( "Node %d is a fanout of node %d but the fanin is not there.\n", pFanout->Id, pObj->Id ); - RetValue = 0; - } - } - Vec_PtrFree( vFanouts ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Checks that each choice node has exactly one node with fanouts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManCheckChoices( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj, * pTemp; - int i; - Ivy_ManForEachObj( p->pHaig, pObj, i ) - { - if ( Ivy_ObjRefs(pObj) == 0 ) - continue; - // count the number of nodes in the loop - assert( !Ivy_IsComplement(pObj->pEquiv) ); - for ( pTemp = pObj->pEquiv; pTemp && pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - if ( Ivy_ObjRefs(pTemp) > 1 ) - printf( "Node %d has member %d in its equiv class with %d fanouts.\n", pObj->Id, pTemp->Id, Ivy_ObjRefs(pTemp) ); - } - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyCut.c b/src/aig/ivy/ivyCut.c deleted file mode 100644 index e257d8a6..00000000 --- a/src/aig/ivy/ivyCut.c +++ /dev/null @@ -1,989 +0,0 @@ -/**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 /// -//////////////////////////////////////////////////////////////////////// - -static inline int Ivy_NodeCutHashValue( int NodeId ) { return 1 << (NodeId % 31); } - -//////////////////////////////////////////////////////////////////////// -/// 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_Man_t * p, 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( p, vFront, vInside, nSize ) ); - assert( Vec_IntSize(vFront) <= nSize ); -} - - - - - -/**Function************************************************************* - - Synopsis [Computing Boolean cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManFindBoolCut_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVolume, Ivy_Obj_t * pPivot ) -{ - int RetValue0, RetValue1; - if ( pObj == pPivot ) - { - Vec_PtrPushUnique( vLeaves, pObj ); - Vec_PtrPushUnique( vVolume, pObj ); - return 1; - } - if ( pObj->fMarkA ) - return 0; - -// assert( !Ivy_ObjIsCi(pObj) ); - if ( Ivy_ObjIsCi(pObj) ) - return 0; - - if ( Ivy_ObjIsBuf(pObj) ) - { - RetValue0 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot ); - if ( !RetValue0 ) - return 0; - Vec_PtrPushUnique( vVolume, pObj ); - return 1; - } - assert( Ivy_ObjIsNode(pObj) ); - RetValue0 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot ); - RetValue1 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin1(pObj), vLeaves, vVolume, pPivot ); - if ( !RetValue0 && !RetValue1 ) - return 0; - // add new leaves - if ( !RetValue0 ) - { - Vec_PtrPushUnique( vLeaves, Ivy_ObjFanin0(pObj) ); - Vec_PtrPushUnique( vVolume, Ivy_ObjFanin0(pObj) ); - } - if ( !RetValue1 ) - { - Vec_PtrPushUnique( vLeaves, Ivy_ObjFanin1(pObj) ); - Vec_PtrPushUnique( vVolume, Ivy_ObjFanin1(pObj) ); - } - Vec_PtrPushUnique( vVolume, pObj ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns the cost of one node (how many new nodes are added.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManFindBoolCutCost( Ivy_Obj_t * pObj ) -{ - int Cost; - // make sure the node is in the construction zone - assert( pObj->fMarkA == 1 ); - // cannot expand over the PI node - if ( Ivy_ObjIsCi(pObj) ) - return 999; - // always expand over the buffer - if ( Ivy_ObjIsBuf(pObj) ) - return !Ivy_ObjFanin0(pObj)->fMarkA; - // get the cost of the cone - Cost = (!Ivy_ObjFanin0(pObj)->fMarkA) + (!Ivy_ObjFanin1(pObj)->fMarkA); - // return the number of nodes to be added to the leaves if this node is removed - return Cost; -} - -/**Function************************************************************* - - Synopsis [Computing Boolean cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManFindBoolCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVolume, Vec_Ptr_t * vLeaves ) -{ - Ivy_Obj_t * pObj, * pFaninC, * pFanin0, * pFanin1, * pPivot; - int RetValue, LevelLimit, Lev, k; - assert( !Ivy_IsComplement(pRoot) ); - // clear the frontier and collect the nodes - Vec_PtrClear( vFront ); - Vec_PtrClear( vVolume ); - if ( Ivy_ObjIsMuxType(pRoot) ) - pFaninC = Ivy_ObjRecognizeMux( pRoot, &pFanin0, &pFanin1 ); - else - { - pFaninC = NULL; - pFanin0 = Ivy_ObjFanin0(pRoot); - pFanin1 = Ivy_ObjFanin1(pRoot); - } - // start cone A - pFanin0->fMarkA = 1; - Vec_PtrPush( vFront, pFanin0 ); - Vec_PtrPush( vVolume, pFanin0 ); - // start cone B - pFanin1->fMarkB = 1; - Vec_PtrPush( vFront, pFanin1 ); - Vec_PtrPush( vVolume, pFanin1 ); - // iteratively expand until the common node (pPivot) is found or limit is reached - assert( Ivy_ObjLevel(pRoot) == Ivy_ObjLevelNew(pRoot) ); - pPivot = NULL; - LevelLimit = IVY_MAX( Ivy_ObjLevel(pRoot) - 10, 1 ); - for ( Lev = Ivy_ObjLevel(pRoot) - 1; Lev >= LevelLimit; Lev-- ) - { - while ( 1 ) - { - // find the next node to expand on this level - Vec_PtrForEachEntry( vFront, pObj, k ) - if ( (int)pObj->Level == Lev ) - break; - if ( k == Vec_PtrSize(vFront) ) - break; - assert( (int)pObj->Level <= Lev ); - assert( pObj->fMarkA ^ pObj->fMarkB ); - // remove the old node - Vec_PtrRemove( vFront, pObj ); - - // expand this node - pFanin0 = Ivy_ObjFanin0(pObj); - if ( !pFanin0->fMarkA && !pFanin0->fMarkB ) - { - Vec_PtrPush( vFront, pFanin0 ); - Vec_PtrPush( vVolume, pFanin0 ); - } - // mark the new nodes - if ( pObj->fMarkA ) - pFanin0->fMarkA = 1; - if ( pObj->fMarkB ) - pFanin0->fMarkB = 1; - - if ( Ivy_ObjIsBuf(pObj) ) - { - if ( pFanin0->fMarkA && pFanin0->fMarkB ) - { - pPivot = pFanin0; - break; - } - continue; - } - - // expand this node - pFanin1 = Ivy_ObjFanin1(pObj); - if ( !pFanin1->fMarkA && !pFanin1->fMarkB ) - { - Vec_PtrPush( vFront, pFanin1 ); - Vec_PtrPush( vVolume, pFanin1 ); - } - // mark the new nodes - if ( pObj->fMarkA ) - pFanin1->fMarkA = 1; - if ( pObj->fMarkB ) - pFanin1->fMarkB = 1; - - // consider if it is time to quit - if ( pFanin0->fMarkA && pFanin0->fMarkB ) - { - pPivot = pFanin0; - break; - } - if ( pFanin1->fMarkA && pFanin1->fMarkB ) - { - pPivot = pFanin1; - break; - } - } - if ( pPivot != NULL ) - break; - } - if ( pPivot == NULL ) - return 0; - // if the MUX control is defined, it should not be - if ( pFaninC && !pFaninC->fMarkA && !pFaninC->fMarkB ) - Vec_PtrPush( vFront, pFaninC ); - // clean the markings - Vec_PtrForEachEntry( vVolume, pObj, k ) - pObj->fMarkA = pObj->fMarkB = 0; - - // mark the nodes on the frontier (including the pivot) - Vec_PtrForEachEntry( vFront, pObj, k ) - pObj->fMarkA = 1; - // cut exists, collect all the nodes on the shortest path to the pivot - Vec_PtrClear( vLeaves ); - Vec_PtrClear( vVolume ); - RetValue = Ivy_ManFindBoolCut_rec( p, pRoot, vLeaves, vVolume, pPivot ); - assert( RetValue == 1 ); - // unmark the nodes on the frontier (including the pivot) - Vec_PtrForEachEntry( vFront, pObj, k ) - pObj->fMarkA = 0; - - // mark the nodes in the volume - Vec_PtrForEachEntry( vVolume, pObj, k ) - pObj->fMarkA = 1; - // expand the cut without increasing its size - while ( 1 ) - { - Vec_PtrForEachEntry( vLeaves, pObj, k ) - if ( Ivy_ManFindBoolCutCost(pObj) < 2 ) - break; - if ( k == Vec_PtrSize(vLeaves) ) - break; - // the node can be expanded - // remove the old node - Vec_PtrRemove( vLeaves, pObj ); - // expand this node - pFanin0 = Ivy_ObjFanin0(pObj); - if ( !pFanin0->fMarkA ) - { - pFanin0->fMarkA = 1; - Vec_PtrPush( vVolume, pFanin0 ); - Vec_PtrPush( vLeaves, pFanin0 ); - } - if ( Ivy_ObjIsBuf(pObj) ) - continue; - // expand this node - pFanin1 = Ivy_ObjFanin1(pObj); - if ( !pFanin1->fMarkA ) - { - pFanin1->fMarkA = 1; - Vec_PtrPush( vVolume, pFanin1 ); - Vec_PtrPush( vLeaves, pFanin1 ); - } - } - // unmark the nodes in the volume - Vec_PtrForEachEntry( vVolume, pObj, k ) - pObj->fMarkA = 0; - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManTestCutsBool( Ivy_Man_t * p ) -{ - Vec_Ptr_t * vFront, * vVolume, * vLeaves; - Ivy_Obj_t * pObj;//, * pTemp; - int i, RetValue;//, k; - vFront = Vec_PtrAlloc( 100 ); - vVolume = Vec_PtrAlloc( 100 ); - vLeaves = Vec_PtrAlloc( 100 ); - Ivy_ManForEachObj( p, pObj, i ) - { - if ( !Ivy_ObjIsNode(pObj) ) - continue; - if ( Ivy_ObjIsMuxType(pObj) ) - { - printf( "m" ); - continue; - } - if ( Ivy_ObjIsExor(pObj) ) - printf( "x" ); - RetValue = Ivy_ManFindBoolCut( p, pObj, vFront, vVolume, vLeaves ); - if ( RetValue == 0 ) - printf( "- " ); - else - printf( "%d ", Vec_PtrSize(vLeaves) ); -/* - printf( "( " ); - Vec_PtrForEachEntry( vFront, pTemp, k ) - printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) ); - printf( ")\n" ); -*/ - } - printf( "\n" ); - Vec_PtrFree( vFront ); - Vec_PtrFree( vVolume ); - Vec_PtrFree( vLeaves ); -} - - - -/**Function************************************************************* - - Synopsis [Find the hash value of the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline unsigned Ivy_NodeCutHash( Ivy_Cut_t * pCut ) -{ - int i; -// for ( i = 1; i < pCut->nSize; i++ ) -// assert( pCut->pArray[i-1] < pCut->pArray[i] ); - pCut->uHash = 0; - for ( i = 0; i < pCut->nSize; i++ ) - pCut->uHash |= (1 << (pCut->pArray[i] % 31)); - return pCut->uHash; -} - -/**Function************************************************************* - - Synopsis [Removes one node to the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Ivy_NodeCutShrink( Ivy_Cut_t * pCut, int iOld ) -{ - int i, k; - for ( i = k = 0; i < pCut->nSize; i++ ) - if ( pCut->pArray[i] != iOld ) - pCut->pArray[k++] = pCut->pArray[i]; - assert( k == pCut->nSize - 1 ); - pCut->nSize--; -} - -/**Function************************************************************* - - Synopsis [Adds one node to the cut.] - - Description [Returns 1 if the cuts is still okay.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_NodeCutExtend( Ivy_Cut_t * pCut, int iNew ) -{ - int i; - for ( i = 0; i < pCut->nSize; i++ ) - if ( pCut->pArray[i] == iNew ) - return 1; - // check if there is room - if ( pCut->nSize == pCut->nSizeMax ) - return 0; - // add the new one - for ( i = pCut->nSize - 1; i >= 0; i-- ) - if ( pCut->pArray[i] > iNew ) - pCut->pArray[i+1] = pCut->pArray[i]; - else - { - assert( pCut->pArray[i] < iNew ); - break; - } - pCut->pArray[i+1] = iNew; - pCut->nSize++; - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_NodeCutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 ) -{ - int i; - if ( pCut->nSize < pCut->nSizeMax ) - return 1; - for ( i = 0; i < pCut->nSize; i++ ) - if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Derives new cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_NodeCutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) -{ - unsigned uHash = 0; - int i, k; - assert( pCut->nSize > 0 ); - assert( IdNew0 < IdNew1 ); - for ( i = k = 0; i < pCut->nSize; i++ ) - { - if ( pCut->pArray[i] == IdOld ) - continue; - if ( IdNew0 <= pCut->pArray[i] ) - { - if ( IdNew0 < pCut->pArray[i] ) - { - pCutNew->pArray[ k++ ] = IdNew0; - uHash |= Ivy_NodeCutHashValue( IdNew0 ); - } - IdNew0 = 0x7FFFFFFF; - } - if ( IdNew1 <= pCut->pArray[i] ) - { - if ( IdNew1 < pCut->pArray[i] ) - { - pCutNew->pArray[ k++ ] = IdNew1; - uHash |= Ivy_NodeCutHashValue( IdNew1 ); - } - IdNew1 = 0x7FFFFFFF; - } - pCutNew->pArray[ k++ ] = pCut->pArray[i]; - uHash |= Ivy_NodeCutHashValue( pCut->pArray[i] ); - } - if ( IdNew0 < 0x7FFFFFFF ) - { - pCutNew->pArray[ k++ ] = IdNew0; - uHash |= Ivy_NodeCutHashValue( IdNew0 ); - } - if ( IdNew1 < 0x7FFFFFFF ) - { - pCutNew->pArray[ k++ ] = IdNew1; - uHash |= Ivy_NodeCutHashValue( IdNew1 ); - } - pCutNew->nSize = k; - pCutNew->uHash = uHash; - assert( pCutNew->nSize <= pCut->nSizeMax ); -// for ( i = 1; i < pCutNew->nSize; i++ ) -// assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Check if the cut exists.] - - Description [Returns 1 if the cut exists.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeCutFindOrAdd( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew ) -{ - Ivy_Cut_t * pCut; - int i, k; - assert( pCutNew->uHash ); - // try to find the cut - for ( i = 0; i < pCutStore->nCuts; i++ ) - { - pCut = pCutStore->pCuts + i; - if ( pCut->uHash == pCutNew->uHash && pCut->nSize == pCutNew->nSize ) - { - for ( k = 0; k < pCutNew->nSize; k++ ) - if ( pCut->pArray[k] != pCutNew->pArray[k] ) - break; - if ( k == pCutNew->nSize ) - return 1; - } - } - assert( pCutStore->nCuts < pCutStore->nCutsMax ); - // add the cut - pCut = pCutStore->pCuts + pCutStore->nCuts++; - *pCut = *pCutNew; - return 0; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if pDom is contained in pCut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_CutCheckDominance( Ivy_Cut_t * pDom, Ivy_Cut_t * pCut ) -{ - int i, k; - for ( i = 0; i < pDom->nSize; i++ ) - { - for ( k = 0; k < pCut->nSize; k++ ) - if ( pDom->pArray[i] == pCut->pArray[k] ) - break; - if ( k == pCut->nSize ) // node i in pDom is not contained in pCut - return 0; - } - // every node in pDom is contained in pCut - return 1; -} - -/**Function************************************************************* - - Synopsis [Check if the cut exists.] - - Description [Returns 1 if the cut exists.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeCutFindOrAddFilter( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew ) -{ - Ivy_Cut_t * pCut; - int i, k; - assert( pCutNew->uHash ); - // try to find the cut - for ( i = 0; i < pCutStore->nCuts; i++ ) - { - pCut = pCutStore->pCuts + i; - if ( pCut->nSize == 0 ) - continue; - if ( pCut->nSize == pCutNew->nSize ) - { - if ( pCut->uHash == pCutNew->uHash ) - { - for ( k = 0; k < pCutNew->nSize; k++ ) - if ( pCut->pArray[k] != pCutNew->pArray[k] ) - break; - if ( k == pCutNew->nSize ) - return 1; - } - continue; - } - if ( pCut->nSize < pCutNew->nSize ) - { - // skip the non-contained cuts - if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash ) - continue; - // check containment seriously - if ( Ivy_CutCheckDominance( pCut, pCutNew ) ) - return 1; - continue; - } - // check potential containment of other cut - - // skip the non-contained cuts - if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash ) - continue; - // check containment seriously - if ( Ivy_CutCheckDominance( pCutNew, pCut ) ) - { - // remove the current cut -// --pCutStore->nCuts; -// for ( k = i; k < pCutStore->nCuts; k++ ) -// pCutStore->pCuts[k] = pCutStore->pCuts[k+1]; -// i--; - pCut->nSize = 0; - } - } - assert( pCutStore->nCuts < pCutStore->nCutsMax ); - // add the cut - pCut = pCutStore->pCuts + pCutStore->nCuts++; - *pCut = *pCutNew; - return 0; -} - -/**Function************************************************************* - - Synopsis [Print the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeCompactCuts( Ivy_Store_t * pCutStore ) -{ - Ivy_Cut_t * pCut; - int i, k; - for ( i = k = 0; i < pCutStore->nCuts; i++ ) - { - pCut = pCutStore->pCuts + i; - if ( pCut->nSize == 0 ) - continue; - pCutStore->pCuts[k++] = *pCut; - } - pCutStore->nCuts = k; -} - -/**Function************************************************************* - - Synopsis [Print the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodePrintCut( Ivy_Cut_t * pCut ) -{ - int i; - assert( pCut->nSize > 0 ); - printf( "%d : {", pCut->nSize ); - for ( i = 0; i < pCut->nSize; i++ ) - printf( " %d", pCut->pArray[i] ); - printf( " }\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodePrintCuts( Ivy_Store_t * pCutStore ) -{ - int i; - printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] ); - for ( i = 0; i < pCutStore->nCuts; i++ ) - Ivy_NodePrintCut( pCutStore->pCuts + i ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Ivy_Obj_t * Ivy_ObjRealFanin( Ivy_Obj_t * pObj ) -{ - if ( !Ivy_ObjIsBuf(pObj) ) - return pObj; - return Ivy_ObjRealFanin( Ivy_ObjFanin0(pObj) ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves ) -{ - static Ivy_Store_t CutStore, * pCutStore = &CutStore; - Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut; - Ivy_Obj_t * pLeaf; - int i, k, iLeaf0, iLeaf1; - - assert( nLeaves <= IVY_CUT_INPUT ); - - // start the structure - pCutStore->nCuts = 0; - pCutStore->nCutsMax = IVY_CUT_LIMIT; - // start the trivial cut - pCutNew->uHash = 0; - pCutNew->nSize = 1; - pCutNew->nSizeMax = nLeaves; - pCutNew->pArray[0] = pObj->Id; - Ivy_NodeCutHash( pCutNew ); - // add the trivial cut - Ivy_NodeCutFindOrAdd( pCutStore, pCutNew ); - assert( pCutStore->nCuts == 1 ); - - // explore the cuts - for ( i = 0; i < pCutStore->nCuts; i++ ) - { - // expand this cut - pCut = pCutStore->pCuts + i; - if ( pCut->nSize == 0 ) - continue; - for ( k = 0; k < pCut->nSize; k++ ) - { - pLeaf = Ivy_ManObj( p, pCut->pArray[k] ); - if ( Ivy_ObjIsCi(pLeaf) ) - continue; -/* - *pCutNew = *pCut; - Ivy_NodeCutShrink( pCutNew, pLeaf->Id ); - if ( !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId0(pLeaf) ) ) - continue; - if ( Ivy_ObjIsNode(pLeaf) && !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId1(pLeaf) ) ) - continue; - Ivy_NodeCutHash( pCutNew ); -*/ - iLeaf0 = Ivy_ObjId( Ivy_ObjRealFanin(Ivy_ObjFanin0(pLeaf)) ); - iLeaf1 = Ivy_ObjId( Ivy_ObjRealFanin(Ivy_ObjFanin1(pLeaf)) ); -// if ( iLeaf0 == iLeaf1 ) // strange situation observed on Jan 18, 2007 -// continue; - if ( !Ivy_NodeCutPrescreen( pCut, iLeaf0, iLeaf1 ) ) - continue; - if ( iLeaf0 > iLeaf1 ) - Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf1, iLeaf0 ); - else - Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ); - Ivy_NodeCutFindOrAddFilter( pCutStore, pCutNew ); - if ( pCutStore->nCuts == IVY_CUT_LIMIT ) - break; - } - if ( pCutStore->nCuts == IVY_CUT_LIMIT ) - break; - } - Ivy_NodeCompactCuts( pCutStore ); -// Ivy_NodePrintCuts( pCutStore ); - return pCutStore; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManTestCutsAll( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - int i, nCutsCut, nCutsTotal, nNodeTotal, nNodeOver; - int clk = clock(); - nNodeTotal = nNodeOver = 0; - nCutsTotal = -Ivy_ManNodeNum(p); - Ivy_ManForEachObj( p, pObj, i ) - { - if ( !Ivy_ObjIsNode(pObj) ) - continue; - nCutsCut = Ivy_NodeFindCutsAll( p, pObj, 5 )->nCuts; - nCutsTotal += nCutsCut; - nNodeOver += (nCutsCut == IVY_CUT_LIMIT); - nNodeTotal++; - } - printf( "Total cuts = %6d. Trivial = %6d. Nodes = %6d. Satur = %6d. ", - nCutsTotal, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver ); - PRT( "Time", clock() - clk ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyCutTrav.c b/src/aig/ivy/ivyCutTrav.c deleted file mode 100644 index ea57c9f5..00000000 --- a/src/aig/ivy/ivyCutTrav.c +++ /dev/null @@ -1,473 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyCutTrav.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: ivyCutTrav.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static unsigned * Ivy_NodeCutElementary( Vec_Int_t * vStore, int nWords, int NodeId ); -static void Ivy_NodeComputeVolume( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNodes, Vec_Ptr_t * vFront ); -static void Ivy_NodeFindCutsMerge( Vec_Ptr_t * vCuts0, Vec_Ptr_t * vCuts1, Vec_Ptr_t * vCuts, int nLeaves, int nWords, Vec_Int_t * vStore ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes cuts for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Store_t * Ivy_NodeFindCutsTravAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves, int nNodeLimit, - Vec_Ptr_t * vNodes, Vec_Ptr_t * vFront, Vec_Int_t * vStore, Vec_Vec_t * vBitCuts ) -{ - static Ivy_Store_t CutStore, * pCutStore = &CutStore; - Vec_Ptr_t * vCuts, * vCuts0, * vCuts1; - unsigned * pBitCut; - Ivy_Obj_t * pLeaf; - Ivy_Cut_t * pCut; - int i, k, nWords, nNodes; - - assert( nLeaves <= IVY_CUT_INPUT ); - - // find the given number of nodes in the TFI - Ivy_NodeComputeVolume( pObj, nNodeLimit - 1, vNodes, vFront ); - nNodes = Vec_PtrSize(vNodes); -// assert( nNodes <= nNodeLimit ); - - // make sure vBitCuts has enough room - Vec_VecExpand( vBitCuts, nNodes-1 ); - Vec_VecClear( vBitCuts ); - - // prepare the memory manager - Vec_IntClear( vStore ); - Vec_IntGrow( vStore, 64000 ); - - // set elementary cuts for the leaves - nWords = Extra_BitWordNum( nNodes ); - Vec_PtrForEachEntry( vFront, pLeaf, i ) - { - assert( Ivy_ObjTravId(pLeaf) < nNodes ); - // get the new bitcut - pBitCut = Ivy_NodeCutElementary( vStore, nWords, Ivy_ObjTravId(pLeaf) ); - // set it as the cut of this leaf - Vec_VecPush( vBitCuts, Ivy_ObjTravId(pLeaf), pBitCut ); - } - - // compute the cuts for each node - Vec_PtrForEachEntry( vNodes, pLeaf, i ) - { - // skip the leaves - vCuts = Vec_VecEntry( vBitCuts, Ivy_ObjTravId(pLeaf) ); - if ( Vec_PtrSize(vCuts) > 0 ) - continue; - // add elementary cut - pBitCut = Ivy_NodeCutElementary( vStore, nWords, Ivy_ObjTravId(pLeaf) ); - // set it as the cut of this leaf - Vec_VecPush( vBitCuts, Ivy_ObjTravId(pLeaf), pBitCut ); - // get the fanin cuts - vCuts0 = Vec_VecEntry( vBitCuts, Ivy_ObjTravId( Ivy_ObjFanin0(pLeaf) ) ); - vCuts1 = Vec_VecEntry( vBitCuts, Ivy_ObjTravId( Ivy_ObjFanin1(pLeaf) ) ); - assert( Vec_PtrSize(vCuts0) > 0 ); - assert( Vec_PtrSize(vCuts1) > 0 ); - // merge the cuts - Ivy_NodeFindCutsMerge( vCuts0, vCuts1, vCuts, nLeaves, nWords, vStore ); - } - - // start the structure - pCutStore->nCuts = 0; - pCutStore->nCutsMax = IVY_CUT_LIMIT; - // collect the cuts of the root node - vCuts = Vec_VecEntry( vBitCuts, Ivy_ObjTravId(pObj) ); - Vec_PtrForEachEntry( vCuts, pBitCut, i ) - { - pCut = pCutStore->pCuts + pCutStore->nCuts++; - pCut->nSize = 0; - pCut->nSizeMax = nLeaves; - pCut->uHash = 0; - for ( k = 0; k < nNodes; k++ ) - if ( Extra_TruthHasBit(pBitCut, k) ) - pCut->pArray[ pCut->nSize++ ] = Ivy_ObjId( Vec_PtrEntry(vNodes, k) ); - assert( pCut->nSize <= nLeaves ); - if ( pCutStore->nCuts == pCutStore->nCutsMax ) - break; - } - - // clean the travIds - Vec_PtrForEachEntry( vNodes, pLeaf, i ) - pLeaf->TravId = 0; - return pCutStore; -} - -/**Function************************************************************* - - Synopsis [Creates elementary bit-cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned * Ivy_NodeCutElementary( Vec_Int_t * vStore, int nWords, int NodeId ) -{ - unsigned * pBitCut; - pBitCut = Vec_IntFetch( vStore, nWords ); - memset( pBitCut, 0, 4 * nWords ); - Extra_TruthSetBit( pBitCut, NodeId ); - return pBitCut; -} - -/**Function************************************************************* - - Synopsis [Compares the node by level.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_CompareNodesByLevel( Ivy_Obj_t ** ppObj1, Ivy_Obj_t ** ppObj2 ) -{ - Ivy_Obj_t * pObj1 = *ppObj1; - Ivy_Obj_t * pObj2 = *ppObj2; - if ( pObj1->Level < pObj2->Level ) - return -1; - if ( pObj1->Level > pObj2->Level ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Mark all nodes up to the given depth.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeComputeVolumeTrav1_rec( Ivy_Obj_t * pObj, int Depth ) -{ - if ( Ivy_ObjIsCi(pObj) || Depth == 0 ) - return; - Ivy_NodeComputeVolumeTrav1_rec( Ivy_ObjFanin0(pObj), Depth - 1 ); - Ivy_NodeComputeVolumeTrav1_rec( Ivy_ObjFanin1(pObj), Depth - 1 ); - pObj->fMarkA = 1; -} - -/**Function************************************************************* - - Synopsis [Collect the marked nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeComputeVolumeTrav2_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vNodes ) -{ - if ( !pObj->fMarkA ) - return; - Ivy_NodeComputeVolumeTrav2_rec( Ivy_ObjFanin0(pObj), vNodes ); - Ivy_NodeComputeVolumeTrav2_rec( Ivy_ObjFanin1(pObj), vNodes ); - Vec_PtrPush( vNodes, pObj ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeComputeVolume( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNodes, Vec_Ptr_t * vFront ) -{ - Ivy_Obj_t * pTemp, * pFanin; - int i, nNodes; - // mark nodes up to the given depth - Ivy_NodeComputeVolumeTrav1_rec( pObj, 6 ); - // collect the marked nodes - Vec_PtrClear( vFront ); - Ivy_NodeComputeVolumeTrav2_rec( pObj, vFront ); - // find the fanins that are not marked - Vec_PtrClear( vNodes ); - Vec_PtrForEachEntry( vFront, pTemp, i ) - { - pFanin = Ivy_ObjFanin0(pTemp); - if ( !pFanin->fMarkA ) - { - pFanin->fMarkA = 1; - Vec_PtrPush( vNodes, pFanin ); - } - pFanin = Ivy_ObjFanin1(pTemp); - if ( !pFanin->fMarkA ) - { - pFanin->fMarkA = 1; - Vec_PtrPush( vNodes, pFanin ); - } - } - // remember the number of nodes in the frontier - nNodes = Vec_PtrSize( vNodes ); - // add the remaining nodes - Vec_PtrForEachEntry( vFront, pTemp, i ) - Vec_PtrPush( vNodes, pTemp ); - // unmark the nodes - Vec_PtrForEachEntry( vNodes, pTemp, i ) - { - pTemp->fMarkA = 0; - pTemp->TravId = i; - } - // collect the frontier nodes - Vec_PtrClear( vFront ); - Vec_PtrForEachEntryStop( vNodes, pTemp, i, nNodes ) - Vec_PtrPush( vFront, pTemp ); -// printf( "%d ", Vec_PtrSize(vNodes) ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeComputeVolume2( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNodes, Vec_Ptr_t * vFront ) -{ - Ivy_Obj_t * pLeaf, * pPivot, * pFanin; - int LevelMax, i; - assert( Ivy_ObjIsNode(pObj) ); - // clear arrays - Vec_PtrClear( vNodes ); - Vec_PtrClear( vFront ); - // add the root - pObj->fMarkA = 1; - Vec_PtrPush( vNodes, pObj ); - Vec_PtrPush( vFront, pObj ); - // expand node with maximum level - LevelMax = pObj->Level; - do { - // get the node to expand - pPivot = NULL; - Vec_PtrForEachEntryReverse( vFront, pLeaf, i ) - { - if ( (int)pLeaf->Level == LevelMax ) - { - pPivot = pLeaf; - break; - } - } - // decrease level if we did not find the node - if ( pPivot == NULL ) - { - if ( --LevelMax == 0 ) - break; - continue; - } - // the node to expand is found - // remove it from frontier - Vec_PtrRemove( vFront, pPivot ); - // add fanins - pFanin = Ivy_ObjFanin0(pPivot); - if ( !pFanin->fMarkA ) - { - pFanin->fMarkA = 1; - Vec_PtrPush( vNodes, pFanin ); - Vec_PtrPush( vFront, pFanin ); - } - pFanin = Ivy_ObjFanin1(pPivot); - if ( pFanin && !pFanin->fMarkA ) - { - pFanin->fMarkA = 1; - Vec_PtrPush( vNodes, pFanin ); - Vec_PtrPush( vFront, pFanin ); - } - // quit if we collected enough nodes - } while ( Vec_PtrSize(vNodes) < nNodeLimit ); - - // sort nodes by level - Vec_PtrSort( vNodes, Ivy_CompareNodesByLevel ); - // make sure the nodes are ordered in the increasing number of levels - pFanin = Vec_PtrEntry( vNodes, 0 ); - pPivot = Vec_PtrEntryLast( vNodes ); - assert( pFanin->Level <= pPivot->Level ); - - // clean the marks and remember node numbers in the TravId - Vec_PtrForEachEntry( vNodes, pFanin, i ) - { - pFanin->fMarkA = 0; - pFanin->TravId = i; - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Extra_TruthOrWords( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nWords ) -{ - int w; - for ( w = nWords-1; w >= 0; w-- ) - pOut[w] = pIn0[w] | pIn1[w]; -} -static inline int Extra_TruthIsImplyWords( unsigned * pIn1, unsigned * pIn2, int nWords ) -{ - int w; - for ( w = nWords-1; w >= 0; w-- ) - if ( pIn1[w] & ~pIn2[w] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Merges two sets of bit-cuts at a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeFindCutsMerge( Vec_Ptr_t * vCuts0, Vec_Ptr_t * vCuts1, Vec_Ptr_t * vCuts, - int nLeaves, int nWords, Vec_Int_t * vStore ) -{ - unsigned * pBitCut, * pBitCut0, * pBitCut1, * pBitCutTest; - int i, k, c, w, Counter; - // iterate through the cut pairs - Vec_PtrForEachEntry( vCuts0, pBitCut0, i ) - Vec_PtrForEachEntry( vCuts1, pBitCut1, k ) - { - // skip infeasible cuts - Counter = 0; - for ( w = 0; w < nWords; w++ ) - { - Counter += Extra_WordCountOnes( pBitCut0[w] | pBitCut1[w] ); - if ( Counter > nLeaves ) - break; - } - if ( Counter > nLeaves ) - continue; - // the new cut is feasible - create it - pBitCutTest = Vec_IntFetch( vStore, nWords ); - Extra_TruthOrWords( pBitCutTest, pBitCut0, pBitCut1, nWords ); - // filter contained cuts; try to find containing cut - w = 0; - Vec_PtrForEachEntry( vCuts, pBitCut, c ) - { - if ( Extra_TruthIsImplyWords( pBitCut, pBitCutTest, nWords ) ) - break; - if ( Extra_TruthIsImplyWords( pBitCutTest, pBitCut, nWords ) ) - continue; - Vec_PtrWriteEntry( vCuts, w++, pBitCut ); - } - if ( c != Vec_PtrSize(vCuts) ) - continue; - Vec_PtrShrink( vCuts, w ); - // add the cut - Vec_PtrPush( vCuts, pBitCutTest ); - } -} - -/**Function************************************************************* - - Synopsis [Compute the set of all cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManTestCutsTravAll( Ivy_Man_t * p ) -{ - Ivy_Store_t * pStore; - Ivy_Obj_t * pObj; - Vec_Ptr_t * vNodes, * vFront; - Vec_Int_t * vStore; - Vec_Vec_t * vBitCuts; - int i, nCutsCut, nCutsTotal, nNodeTotal, nNodeOver; - int clk = clock(); - - vNodes = Vec_PtrAlloc( 100 ); - vFront = Vec_PtrAlloc( 100 ); - vStore = Vec_IntAlloc( 100 ); - vBitCuts = Vec_VecAlloc( 100 ); - - nNodeTotal = nNodeOver = 0; - nCutsTotal = -Ivy_ManNodeNum(p); - Ivy_ManForEachObj( p, pObj, i ) - { - if ( !Ivy_ObjIsNode(pObj) ) - continue; - pStore = Ivy_NodeFindCutsTravAll( p, pObj, 4, 60, vNodes, vFront, vStore, vBitCuts ); - nCutsCut = pStore->nCuts; - nCutsTotal += nCutsCut; - nNodeOver += (nCutsCut == IVY_CUT_LIMIT); - nNodeTotal++; - } - printf( "Total cuts = %6d. Trivial = %6d. Nodes = %6d. Satur = %6d. ", - nCutsTotal, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver ); - PRT( "Time", clock() - clk ); - - Vec_PtrFree( vNodes ); - Vec_PtrFree( vFront ); - Vec_IntFree( vStore ); - Vec_VecFree( vBitCuts ); - -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyDfs.c b/src/aig/ivy/ivyDfs.c deleted file mode 100644 index c27cba31..00000000 --- a/src/aig/ivy/ivyDfs.c +++ /dev/null @@ -1,493 +0,0 @@ -/**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_Man_t * p, Ivy_Obj_t * pObj, Vec_Int_t * vNodes ) -{ - if ( Ivy_ObjIsMarkA(pObj) ) - return; - Ivy_ObjSetMarkA(pObj); - if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) ) - { - if ( p->pHaig == NULL && pObj->pEquiv ) - Ivy_ManDfs_rec( p, Ivy_Regular(pObj->pEquiv), vNodes ); - return; - } -//printf( "visiting node %d\n", pObj->Id ); -/* - if ( pObj->Id == 87 || pObj->Id == 90 ) - { - int y = 0; - } -*/ - assert( Ivy_ObjIsBuf(pObj) || Ivy_ObjIsAnd(pObj) || Ivy_ObjIsExor(pObj) ); - Ivy_ManDfs_rec( p, Ivy_ObjFanin0(pObj), vNodes ); - if ( !Ivy_ObjIsBuf(pObj) ) - Ivy_ManDfs_rec( p, Ivy_ObjFanin1(pObj), vNodes ); - if ( p->pHaig == NULL && pObj->pEquiv ) - Ivy_ManDfs_rec( p, Ivy_Regular(pObj->pEquiv), vNodes ); - Vec_IntPush( vNodes, pObj->Id ); - -//printf( "adding node %d with fanins %d and %d and equiv %d (refs = %d)\n", -// pObj->Id, Ivy_ObjFanin0(pObj)->Id, Ivy_ObjFanin1(pObj)->Id, -// pObj->pEquiv? Ivy_Regular(pObj->pEquiv)->Id: -1, Ivy_ObjRefs(pObj) ); -} - -/**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; - assert( Ivy_ManLatchNum(p) == 0 ); - // make sure the nodes are not marked - Ivy_ManForEachObj( p, pObj, i ) - assert( !pObj->fMarkA && !pObj->fMarkB ); - // collect the nodes - vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) ); - Ivy_ManForEachPo( p, pObj, i ) - Ivy_ManDfs_rec( p, Ivy_ObjFanin0(pObj), vNodes ); - // unmark the collected nodes -// Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) -// Ivy_ObjClearMarkA(pObj); - Ivy_ManForEachObj( p, 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 AND/EXOR nodes in the DFS order from CIs to COs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Ivy_ManDfsSeq( Ivy_Man_t * p, Vec_Int_t ** pvLatches ) -{ - Vec_Int_t * vNodes, * vLatches; - Ivy_Obj_t * pObj; - int i; -// assert( Ivy_ManLatchNum(p) > 0 ); - // make sure the nodes are not marked - Ivy_ManForEachObj( p, pObj, i ) - assert( !pObj->fMarkA && !pObj->fMarkB ); - // collect the latches - vLatches = Vec_IntAlloc( Ivy_ManLatchNum(p) ); - Ivy_ManForEachLatch( p, pObj, i ) - Vec_IntPush( vLatches, pObj->Id ); - // collect the nodes - vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) ); - Ivy_ManForEachPo( p, pObj, i ) - Ivy_ManDfs_rec( p, Ivy_ObjFanin0(pObj), vNodes ); - Ivy_ManForEachNodeVec( p, vLatches, pObj, i ) - Ivy_ManDfs_rec( p, Ivy_ObjFanin0(pObj), vNodes ); - // unmark the collected nodes -// Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) -// Ivy_ObjClearMarkA(pObj); - Ivy_ManForEachObj( p, pObj, i ) - Ivy_ObjClearMarkA(pObj); - // make sure network does not have dangling nodes -// assert( Vec_IntSize(vNodes) == Ivy_ManNodeNum(p) + Ivy_ManBufNum(p) ); - -// temporary!!! - - if ( pvLatches == NULL ) - Vec_IntFree( vLatches ); - else - *pvLatches = vLatches; - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Collects nodes in the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManCollectCone_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vCone ) -{ - if ( pObj->fMarkA ) - return; - if ( Ivy_ObjIsBuf(pObj) ) - { - Ivy_ManCollectCone_rec( Ivy_ObjFanin0(pObj), vCone ); - Vec_PtrPush( vCone, pObj ); - return; - } - assert( Ivy_ObjIsNode(pObj) ); - Ivy_ManCollectCone_rec( Ivy_ObjFanin0(pObj), vCone ); - Ivy_ManCollectCone_rec( Ivy_ObjFanin1(pObj), vCone ); - Vec_PtrPushUnique( vCone, pObj ); -} - -/**Function************************************************************* - - Synopsis [Collects nodes in the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone ) -{ - Ivy_Obj_t * pTemp; - int i; - assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjIsNode(pObj) ); - // mark the nodes - Vec_PtrForEachEntry( vFront, pTemp, i ) - Ivy_Regular(pTemp)->fMarkA = 1; - assert( pObj->fMarkA == 0 ); - // collect the cone - Vec_PtrClear( vCone ); - Ivy_ManCollectCone_rec( pObj, vCone ); - // unmark the nodes - Vec_PtrForEachEntry( vFront, pTemp, i ) - Ivy_Regular(pTemp)->fMarkA = 0; -} - -/**Function************************************************************* - - Synopsis [Returns the nodes by level.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p ) -{ - Vec_Vec_t * vNodes; - Ivy_Obj_t * pObj; - int i; - vNodes = Vec_VecAlloc( 100 ); - Ivy_ManForEachObj( p, pObj, i ) - { - assert( !Ivy_ObjIsBuf(pObj) ); - if ( Ivy_ObjIsNode(pObj) ) - Vec_VecPush( vNodes, pObj->Level, pObj ); - } - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Computes required levels for each node.] - - Description [Assumes topological ordering of the nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - Vec_Int_t * vLevelsR; - Vec_Vec_t * vNodes; - int i, k, Level, LevelMax; - assert( p->vRequired == NULL ); - // start the required times - vLevelsR = Vec_IntStart( Ivy_ManObjIdMax(p) + 1 ); - // iterate through the nodes in the reverse order - vNodes = Ivy_ManLevelize( p ); - Vec_VecForEachEntryReverseReverse( vNodes, pObj, i, k ) - { - Level = Vec_IntEntry( vLevelsR, pObj->Id ) + 1 + Ivy_ObjIsExor(pObj); - if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId0(pObj) ) < Level ) - Vec_IntWriteEntry( vLevelsR, Ivy_ObjFaninId0(pObj), Level ); - if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId1(pObj) ) < Level ) - Vec_IntWriteEntry( vLevelsR, Ivy_ObjFaninId1(pObj), Level ); - } - Vec_VecFree( vNodes ); - // convert it into the required times - LevelMax = Ivy_ManLevels( p ); -//printf( "max %5d\n",LevelMax ); - Ivy_ManForEachObj( p, pObj, i ) - { - Level = Vec_IntEntry( vLevelsR, pObj->Id ); - Vec_IntWriteEntry( vLevelsR, pObj->Id, LevelMax - Level ); -//printf( "%5d : %5d %5d\n", pObj->Id, Level, LevelMax - Level ); - } - p->vRequired = vLevelsR; - return vLevelsR; -} - -/**Function************************************************************* - - Synopsis [Recursively detects combinational loops.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManIsAcyclic_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - // skip the node if it is already visited - if ( Ivy_ObjIsTravIdPrevious(p, pObj) ) - return 1; - // check if the node is part of the combinational loop - if ( Ivy_ObjIsTravIdCurrent(p, pObj) ) - { - fprintf( stdout, "Manager contains combinational loop!\n" ); - fprintf( stdout, "Node \"%d\" is encountered twice on the following path:\n", Ivy_ObjId(pObj) ); - fprintf( stdout, " %d", Ivy_ObjId(pObj) ); - return 0; - } - // mark this node as a node on the current path - Ivy_ObjSetTravIdCurrent( p, pObj ); - // explore equivalent nodes if pObj is the main node - if ( p->pHaig == NULL && pObj->pEquiv && Ivy_ObjRefs(pObj) > 0 ) - { - Ivy_Obj_t * pTemp; - assert( !Ivy_IsComplement(pObj->pEquiv) ); - for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - { - // traverse the fanin's cone searching for the loop - if ( !Ivy_ManIsAcyclic_rec(p, pTemp) ) - { - // return as soon as the loop is detected - fprintf( stdout, " -> (%d", Ivy_ObjId(pObj) ); - for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - fprintf( stdout, " %d", Ivy_ObjId(pTemp) ); - fprintf( stdout, ")" ); - return 0; - } - } - } - // quite if it is a CI node - if ( Ivy_ObjIsCi(pObj) || Ivy_ObjIsConst1(pObj) ) - { - // mark this node as a visited node - Ivy_ObjSetTravIdPrevious( p, pObj ); - return 1; - } - assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) ); - // traverse the fanin's cone searching for the loop - if ( !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pObj)) ) - { - // return as soon as the loop is detected - fprintf( stdout, " -> %d", Ivy_ObjId(pObj) ); - return 0; - } - // traverse the fanin's cone searching for the loop - if ( Ivy_ObjIsNode(pObj) && !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin1(pObj)) ) - { - // return as soon as the loop is detected - fprintf( stdout, " -> %d", Ivy_ObjId(pObj) ); - return 0; - } - // mark this node as a visited node - Ivy_ObjSetTravIdPrevious( p, pObj ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Detects combinational loops.] - - Description [This procedure is based on the idea suggested by Donald Chai. - As we traverse the network and visit the nodes, we need to distinquish - three types of nodes: (1) those that are visited for the first time, - (2) those that have been visited in this traversal but are currently not - on the traversal path, (3) those that have been visited and are currently - on the travesal path. When the node of type (3) is encountered, it means - that there is a combinational loop. To mark the three types of nodes, - two new values of the traversal IDs are used.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManIsAcyclic( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - int fAcyclic, i; - // set the traversal ID for this DFS ordering - Ivy_ManIncrementTravId( p ); - Ivy_ManIncrementTravId( p ); - // pObj->TravId == pNet->nTravIds means "pObj is on the path" - // pObj->TravId == pNet->nTravIds - 1 means "pObj is visited but is not on the path" - // pObj->TravId < pNet->nTravIds - 1 means "pObj is not visited" - // traverse the network to detect cycles - fAcyclic = 1; - Ivy_ManForEachCo( p, pObj, i ) - { - // traverse the output logic cone - if ( fAcyclic = Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pObj)) ) - continue; - // stop as soon as the first loop is detected - fprintf( stdout, " (cone of %s \"%d\")\n", Ivy_ObjIsLatch(pObj)? "latch" : "PO", Ivy_ObjId(pObj) ); - break; - } - return fAcyclic; -} - -/**Function************************************************************* - - Synopsis [Sets the levels of the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManSetLevels_rec( Ivy_Obj_t * pObj, int fHaig ) -{ - // quit if the node is visited - if ( Ivy_ObjIsMarkA(pObj) ) - return pObj->Level; - Ivy_ObjSetMarkA(pObj); - // quit if this is a CI - if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) ) - return 0; - assert( Ivy_ObjIsBuf(pObj) || Ivy_ObjIsAnd(pObj) || Ivy_ObjIsExor(pObj) ); - // get levels of the fanins - Ivy_ManSetLevels_rec( Ivy_ObjFanin0(pObj), fHaig ); - if ( !Ivy_ObjIsBuf(pObj) ) - Ivy_ManSetLevels_rec( Ivy_ObjFanin1(pObj), fHaig ); - // get level of the node - if ( Ivy_ObjIsBuf(pObj) ) - pObj->Level = 1 + Ivy_ObjFanin0(pObj)->Level; - else if ( Ivy_ObjIsNode(pObj) ) - pObj->Level = Ivy_ObjLevelNew( pObj ); - else assert( 0 ); - // get level of other choices - if ( fHaig && pObj->pEquiv && Ivy_ObjRefs(pObj) > 0 ) - { - Ivy_Obj_t * pTemp; - unsigned LevelMax = pObj->Level; - for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - { - Ivy_ManSetLevels_rec( pTemp, fHaig ); - LevelMax = IVY_MAX( LevelMax, pTemp->Level ); - } - // get this level - pObj->Level = LevelMax; - for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - pTemp->Level = LevelMax; - } - return pObj->Level; -} - -/**Function************************************************************* - - Synopsis [Sets the levels of the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManSetLevels( Ivy_Man_t * p, int fHaig ) -{ - Ivy_Obj_t * pObj; - int i, LevelMax; - // check if CIs have choices - if ( fHaig ) - { - Ivy_ManForEachCi( p, pObj, i ) - if ( pObj->pEquiv ) - printf( "CI %d has a choice, which will not be visualized.\n", pObj->Id ); - } - // clean the levels - Ivy_ManForEachObj( p, pObj, i ) - pObj->Level = 0; - // compute the levels - LevelMax = 0; - Ivy_ManForEachCo( p, pObj, i ) - { - Ivy_ManSetLevels_rec( Ivy_ObjFanin0(pObj), fHaig ); - LevelMax = IVY_MAX( LevelMax, (int)Ivy_ObjFanin0(pObj)->Level ); - } - // compute levels of nodes without fanout - Ivy_ManForEachObj( p, pObj, i ) - if ( (Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj)) && Ivy_ObjRefs(pObj) == 0 ) - { - Ivy_ManSetLevels_rec( pObj, fHaig ); - LevelMax = IVY_MAX( LevelMax, (int)pObj->Level ); - } - // clean the marks - Ivy_ManForEachObj( p, pObj, i ) - Ivy_ObjClearMarkA(pObj); - return LevelMax; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyDsd.c b/src/aig/ivy/ivyDsd.c deleted file mode 100644 index 3b8a2e68..00000000 --- a/src/aig/ivy/ivyDsd.c +++ /dev/null @@ -1,819 +0,0 @@ -/**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( p, 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( p, pNodes[0], pNodes[1], pNodes[2] ); - else - return Ivy_Maj( p, 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/aig/ivy/ivyFanout.c b/src/aig/ivy/ivyFanout.c deleted file mode 100644 index 3930186a..00000000 --- a/src/aig/ivy/ivyFanout.c +++ /dev/null @@ -1,309 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyFanout.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [Representation of the fanouts.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyFanout.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// getting hold of the next fanout of the node -static inline Ivy_Obj_t * Ivy_ObjNextFanout( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) -{ - assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_IsComplement(pFanout) ); - if ( pFanout == NULL ) - return NULL; - if ( Ivy_ObjFanin0(pFanout) == pObj ) - return pFanout->pNextFan0; - assert( Ivy_ObjFanin1(pFanout) == pObj ); - return pFanout->pNextFan1; -} - -// getting hold of the previous fanout of the node -static inline Ivy_Obj_t * Ivy_ObjPrevFanout( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) -{ - assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_IsComplement(pFanout) ); - if ( pFanout == NULL ) - return NULL; - if ( Ivy_ObjFanin0(pFanout) == pObj ) - return pFanout->pPrevFan0; - assert( Ivy_ObjFanin1(pFanout) == pObj ); - return pFanout->pPrevFan1; -} - -// getting hold of the place where the next fanout will be attached -static inline Ivy_Obj_t ** Ivy_ObjNextFanoutPlace( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) -{ - assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_IsComplement(pFanout) ); - if ( Ivy_ObjFanin0(pFanout) == pObj ) - return &pFanout->pNextFan0; - assert( Ivy_ObjFanin1(pFanout) == pObj ); - return &pFanout->pNextFan1; -} - -// getting hold of the place where the next fanout will be attached -static inline Ivy_Obj_t ** Ivy_ObjPrevFanoutPlace( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) -{ - assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_IsComplement(pFanout) ); - if ( Ivy_ObjFanin0(pFanout) == pObj ) - return &pFanout->pPrevFan0; - assert( Ivy_ObjFanin1(pFanout) == pObj ); - return &pFanout->pPrevFan1; -} - -// getting hold of the place where the next fanout will be attached -static inline Ivy_Obj_t ** Ivy_ObjPrevNextFanoutPlace( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) -{ - Ivy_Obj_t * pTemp; - assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_IsComplement(pFanout) ); - pTemp = Ivy_ObjPrevFanout(pObj, pFanout); - if ( pTemp == NULL ) - return &pObj->pFanout; - if ( Ivy_ObjFanin0(pTemp) == pObj ) - return &pTemp->pNextFan0; - assert( Ivy_ObjFanin1(pTemp) == pObj ); - return &pTemp->pNextFan1; -} - -// getting hold of the place where the next fanout will be attached -static inline Ivy_Obj_t ** Ivy_ObjNextPrevFanoutPlace( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) -{ - Ivy_Obj_t * pTemp; - assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_IsComplement(pFanout) ); - pTemp = Ivy_ObjNextFanout(pObj, pFanout); - if ( pTemp == NULL ) - return NULL; - if ( Ivy_ObjFanin0(pTemp) == pObj ) - return &pTemp->pPrevFan0; - assert( Ivy_ObjFanin1(pTemp) == pObj ); - return &pTemp->pPrevFan1; -} - -// iterator through the fanouts of the node -#define Ivy_ObjForEachFanoutInt( pObj, pFanout ) \ - for ( pFanout = (pObj)->pFanout; pFanout; \ - pFanout = Ivy_ObjNextFanout(pObj, pFanout) ) - -// safe iterator through the fanouts of the node -#define Ivy_ObjForEachFanoutIntSafe( pObj, pFanout, pFanout2 ) \ - for ( pFanout = (pObj)->pFanout, \ - pFanout2 = Ivy_ObjNextFanout(pObj, pFanout); \ - pFanout; \ - pFanout = pFanout2, \ - pFanout2 = Ivy_ObjNextFanout(pObj, pFanout) ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the fanout representation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManStartFanout( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - assert( !p->fFanout ); - p->fFanout = 1; - Ivy_ManForEachObj( p, pObj, i ) - { - if ( Ivy_ObjFanin0(pObj) ) - Ivy_ObjAddFanout( p, Ivy_ObjFanin0(pObj), pObj ); - if ( Ivy_ObjFanin1(pObj) ) - Ivy_ObjAddFanout( p, Ivy_ObjFanin1(pObj), pObj ); - } -} - -/**Function************************************************************* - - Synopsis [Stops the fanout representation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManStopFanout( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - assert( p->fFanout ); - p->fFanout = 0; - Ivy_ManForEachObj( p, pObj, i ) - pObj->pFanout = pObj->pNextFan0 = pObj->pNextFan1 = pObj->pPrevFan0 = pObj->pPrevFan1 = NULL; -} - -/**Function************************************************************* - - Synopsis [Add the fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjAddFanout( Ivy_Man_t * p, Ivy_Obj_t * pFanin, Ivy_Obj_t * pFanout ) -{ - assert( p->fFanout ); - if ( pFanin->pFanout ) - { - *Ivy_ObjNextFanoutPlace(pFanin, pFanout) = pFanin->pFanout; - *Ivy_ObjPrevFanoutPlace(pFanin, pFanin->pFanout) = pFanout; - } - pFanin->pFanout = pFanout; -} - -/**Function************************************************************* - - Synopsis [Removes the fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjDeleteFanout( Ivy_Man_t * p, Ivy_Obj_t * pFanin, Ivy_Obj_t * pFanout ) -{ - Ivy_Obj_t ** ppPlace1, ** ppPlace2, ** ppPlaceN; - assert( pFanin->pFanout != NULL ); - - ppPlace1 = Ivy_ObjNextFanoutPlace(pFanin, pFanout); - ppPlaceN = Ivy_ObjPrevNextFanoutPlace(pFanin, pFanout); - assert( *ppPlaceN == pFanout ); - if ( ppPlaceN ) - *ppPlaceN = *ppPlace1; - - ppPlace2 = Ivy_ObjPrevFanoutPlace(pFanin, pFanout); - ppPlaceN = Ivy_ObjNextPrevFanoutPlace(pFanin, pFanout); - assert( ppPlaceN == NULL || *ppPlaceN == pFanout ); - if ( ppPlaceN ) - *ppPlaceN = *ppPlace2; - - *ppPlace1 = NULL; - *ppPlace2 = NULL; -} - -/**Function************************************************************* - - Synopsis [Replaces the fanout of pOld to be pFanoutNew.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjPatchFanout( Ivy_Man_t * p, Ivy_Obj_t * pFanin, Ivy_Obj_t * pFanoutOld, Ivy_Obj_t * pFanoutNew ) -{ - Ivy_Obj_t ** ppPlace; - ppPlace = Ivy_ObjPrevNextFanoutPlace(pFanin, pFanoutOld); - assert( *ppPlace == pFanoutOld ); - if ( ppPlace ) - *ppPlace = pFanoutNew; - ppPlace = Ivy_ObjNextPrevFanoutPlace(pFanin, pFanoutOld); - assert( ppPlace == NULL || *ppPlace == pFanoutOld ); - if ( ppPlace ) - *ppPlace = pFanoutNew; - // assuming that pFanoutNew already points to the next fanout -} - -/**Function************************************************************* - - Synopsis [Starts iteration through the fanouts.] - - Description [Copies the currently available fanouts into the array.] - - SideEffects [Can be used while the fanouts are being removed.] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vArray ) -{ - Ivy_Obj_t * pFanout; - assert( p->fFanout ); - assert( !Ivy_IsComplement(pObj) ); - Vec_PtrClear( vArray ); - Ivy_ObjForEachFanoutInt( pObj, pFanout ) - Vec_PtrPush( vArray, pFanout ); -} - -/**Function************************************************************* - - Synopsis [Reads one fanout.] - - Description [Returns fanout if there is only one fanout.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - return pObj->pFanout; -} - -/**Function************************************************************* - - Synopsis [Reads one fanout.] - - Description [Returns fanout if there is only one fanout.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pFanout; - int Counter = 0; - Ivy_ObjForEachFanoutInt( pObj, pFanout ) - Counter++; - return Counter; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyFastMap.c b/src/aig/ivy/ivyFastMap.c deleted file mode 100644 index c4a043f2..00000000 --- a/src/aig/ivy/ivyFastMap.c +++ /dev/null @@ -1,1593 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyFastMap.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [Fast FPGA mapping.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyFastMap.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define IVY_INFINITY 10000 - -typedef struct Ivy_SuppMan_t_ Ivy_SuppMan_t; -struct Ivy_SuppMan_t_ -{ - int nLimit; // the limit on the number of inputs - int nObjs; // the number of entries - int nSize; // size of each entry in bytes - char * pMem; // memory allocated - Vec_Vec_t * vLuts; // the array of nodes used in the mapping -}; - -typedef struct Ivy_Supp_t_ Ivy_Supp_t; -struct Ivy_Supp_t_ -{ - char nSize; // the number of support nodes - char fMark; // multipurpose mask - char fMark2; // multipurpose mask - char fMark3; // multipurpose mask - int nRefs; // the number of references - short Delay; // the delay of the node - short DelayR; // the reverse delay of the node - int pArray[0]; // the support nodes -}; - -static inline Ivy_Supp_t * Ivy_ObjSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - return (Ivy_Supp_t *)(((Ivy_SuppMan_t*)pAig->pData)->pMem + pObj->Id * ((Ivy_SuppMan_t*)pAig->pData)->nSize); -} -static inline Ivy_Supp_t * Ivy_ObjSuppStart( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSupp; - pSupp = Ivy_ObjSupp( pAig, pObj ); - pSupp->fMark = 0; - pSupp->Delay = 0; - pSupp->nSize = 1; - pSupp->pArray[0] = pObj->Id; - return pSupp; -} - -static void Ivy_FastMapPrint( Ivy_Man_t * pAig, int Delay, int Area, int Time, char * pStr ); -static int Ivy_FastMapDelay( Ivy_Man_t * pAig ); -static int Ivy_FastMapArea( Ivy_Man_t * pAig ); -static void Ivy_FastMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ); -static void Ivy_FastMapNodeArea( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ); -static int Ivy_FastMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit ); -static void Ivy_FastMapRequired( Ivy_Man_t * pAig, int Delay, int fSetInter ); -static void Ivy_FastMapRecover( Ivy_Man_t * pAig, int nLimit ); -static int Ivy_FastMapNodeDelay( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ); -static int Ivy_FastMapNodeAreaRefed( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ); -static int Ivy_FastMapNodeAreaDerefed( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ); -static void Ivy_FastMapNodeRecover( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ); -static int Ivy_FastMapNodeRef( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ); -static int Ivy_FastMapNodeDeref( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ); - - -extern int s_MappingTime; -extern int s_MappingMem; - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs fast K-LUT mapping of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapPerform( Ivy_Man_t * pAig, int nLimit, int fRecovery, int fVerbose ) -{ - Ivy_SuppMan_t * pMan; - Ivy_Obj_t * pObj; - int i, Delay, Area, clk, clkTotal = clock(); - // start the memory for supports - pMan = ALLOC( Ivy_SuppMan_t, 1 ); - memset( pMan, 0, sizeof(Ivy_SuppMan_t) ); - pMan->nLimit = nLimit; - pMan->nObjs = Ivy_ManObjIdMax(pAig) + 1; - pMan->nSize = sizeof(Ivy_Supp_t) + nLimit * sizeof(int); - pMan->pMem = (char *)malloc( pMan->nObjs * pMan->nSize ); - memset( pMan->pMem, 0, pMan->nObjs * pMan->nSize ); - pMan->vLuts = Vec_VecAlloc( 100 ); - pAig->pData = pMan; -clk = clock(); - // set the PI mapping - Ivy_ObjSuppStart( pAig, Ivy_ManConst1(pAig) ); - Ivy_ManForEachPi( pAig, pObj, i ) - Ivy_ObjSuppStart( pAig, pObj ); - // iterate through all nodes in the topological order - Ivy_ManForEachNode( pAig, pObj, i ) - Ivy_FastMapNode( pAig, pObj, nLimit ); - // find the best arrival time and area - Delay = Ivy_FastMapDelay( pAig ); - Area = Ivy_FastMapArea(pAig); - if ( fVerbose ) - Ivy_FastMapPrint( pAig, Delay, Area, clock() - clk, "Delay oriented mapping: " ); - -// 2-1-2 (doing 2-1-2-1-2 improves 0.5%) - - if ( fRecovery ) - { -clk = clock(); - Ivy_FastMapRequired( pAig, Delay, 0 ); - // remap the nodes - Ivy_FastMapRecover( pAig, nLimit ); - Delay = Ivy_FastMapDelay( pAig ); - Area = Ivy_FastMapArea(pAig); - if ( fVerbose ) - Ivy_FastMapPrint( pAig, Delay, Area, clock() - clk, "Area recovery 2 : " ); - -clk = clock(); - Ivy_FastMapRequired( pAig, Delay, 0 ); - // iterate through all nodes in the topological order - Ivy_ManForEachNode( pAig, pObj, i ) - Ivy_FastMapNodeArea( pAig, pObj, nLimit ); - Delay = Ivy_FastMapDelay( pAig ); - Area = Ivy_FastMapArea(pAig); - if ( fVerbose ) - Ivy_FastMapPrint( pAig, Delay, Area, clock() - clk, "Area recovery 1 : " ); - -clk = clock(); - Ivy_FastMapRequired( pAig, Delay, 0 ); - // remap the nodes - Ivy_FastMapRecover( pAig, nLimit ); - Delay = Ivy_FastMapDelay( pAig ); - Area = Ivy_FastMapArea(pAig); - if ( fVerbose ) - Ivy_FastMapPrint( pAig, Delay, Area, clock() - clk, "Area recovery 2 : " ); - } - - - s_MappingTime = clock() - clkTotal; - s_MappingMem = pMan->nObjs * pMan->nSize; -/* - { - Vec_Ptr_t * vNodes; - vNodes = Vec_PtrAlloc( 100 ); - Vec_VecForEachEntry( pMan->vLuts, pObj, i, k ) - Vec_PtrPush( vNodes, pObj ); - Ivy_ManShow( pAig, 0, vNodes ); - Vec_PtrFree( vNodes ); - } -*/ -} - -/**Function************************************************************* - - Synopsis [Cleans memory used for decomposition.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapStop( Ivy_Man_t * pAig ) -{ - Ivy_SuppMan_t * p = pAig->pData; - Vec_VecFree( p->vLuts ); - free( p->pMem ); - free( p ); - pAig->pData = NULL; -} - -/**Function************************************************************* - - Synopsis [Prints statistics.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapPrint( Ivy_Man_t * pAig, int Delay, int Area, int Time, char * pStr ) -{ - printf( "%s : Delay = %3d. Area = %6d. ", pStr, Delay, Area ); - PRT( "Time", Time ); -} - -/**Function************************************************************* - - Synopsis [Computes delay after LUT mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapDelay( Ivy_Man_t * pAig ) -{ - Ivy_Supp_t * pSupp; - Ivy_Obj_t * pObj; - int i, DelayMax = 0; - Ivy_ManForEachPo( pAig, pObj, i ) - { - pObj = Ivy_ObjFanin0(pObj); - if ( !Ivy_ObjIsNode(pObj) ) - continue; - pSupp = Ivy_ObjSupp( pAig, pObj ); - if ( DelayMax < pSupp->Delay ) - DelayMax = pSupp->Delay; - } - return DelayMax; -} - -/**Function************************************************************* - - Synopsis [Computes area after mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapArea_rec( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Vec_t * vLuts ) -{ - Ivy_Supp_t * pSupp; - int i, Counter; - pSupp = Ivy_ObjSupp( pAig, pObj ); - // skip visited nodes and PIs - if ( pSupp->fMark || pSupp->nSize == 1 ) - return 0; - pSupp->fMark = 1; - // compute the area of this node - Counter = 0; - for ( i = 0; i < pSupp->nSize; i++ ) - Counter += Ivy_FastMapArea_rec( pAig, Ivy_ManObj(pAig, pSupp->pArray[i]), vLuts ); - // add the node to the array of LUTs - Vec_VecPush( vLuts, pSupp->Delay, pObj ); - return 1 + Counter; -} - -/**Function************************************************************* - - Synopsis [Computes area after mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapArea( Ivy_Man_t * pAig ) -{ - Vec_Vec_t * vLuts; - Ivy_Obj_t * pObj; - int i, Counter = 0; - // get the array to store the nodes - vLuts = ((Ivy_SuppMan_t *)pAig->pData)->vLuts; - Vec_VecClear( vLuts ); - // explore starting from each node - Ivy_ManForEachPo( pAig, pObj, i ) - Counter += Ivy_FastMapArea_rec( pAig, Ivy_ObjFanin0(pObj), vLuts ); - // clean the marks - Ivy_ManForEachNode( pAig, pObj, i ) - Ivy_ObjSupp( pAig, pObj )->fMark = 0; - return Counter; -} - -/**Function************************************************************* - - Synopsis [Performs fast mapping for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Ivy_ObjIsNodeInt1( Ivy_Obj_t * pObj ) -{ - return Ivy_ObjIsNode(pObj) && Ivy_ObjRefs(pObj) == 1; -} - -/**Function************************************************************* - - Synopsis [Performs fast mapping for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Ivy_ObjIsNodeInt2( Ivy_Obj_t * pObj ) -{ - return Ivy_ObjIsNode(pObj) && Ivy_ObjRefs(pObj) <= 2; -} - -/**Function************************************************************* - - Synopsis [Performs fast mapping for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntSelectSort( int * pArray, int nSize ) -{ - int temp, i, j, best_i; - for ( i = 0; i < nSize-1; i++ ) - { - best_i = i; - for ( j = i+1; j < nSize; j++ ) - if ( pArray[j] < pArray[best_i] ) - best_i = j; - temp = pArray[i]; - pArray[i] = pArray[best_i]; - pArray[best_i] = temp; - } -} - -/**Function************************************************************* - - Synopsis [Performs fast mapping for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntRemoveDup( int * pArray, int nSize ) -{ - int i, k; - if ( nSize < 2 ) - return nSize; - for ( i = k = 1; i < nSize; i++ ) - if ( pArray[i] != pArray[i-1] ) - pArray[k++] = pArray[i]; - return k; -} - -/**Function************************************************************* - - Synopsis [Performs fast mapping for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodeArea2( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ) -{ - static int Store[32], StoreSize; - static char Supp0[16], Supp1[16]; - static Ivy_Supp_t * pTemp0 = (Ivy_Supp_t *)Supp0; - static Ivy_Supp_t * pTemp1 = (Ivy_Supp_t *)Supp1; - Ivy_Obj_t * pFanin0, * pFanin1; - Ivy_Supp_t * pSupp0, * pSupp1, * pSupp; - int RetValue, DelayOld; - assert( nLimit <= 32 ); - assert( Ivy_ObjIsNode(pObj) ); - // get the fanins - pFanin0 = Ivy_ObjFanin0(pObj); - pFanin1 = Ivy_ObjFanin1(pObj); - // get the supports - pSupp0 = Ivy_ObjSupp( pAig, pFanin0 ); - pSupp1 = Ivy_ObjSupp( pAig, pFanin1 ); - pSupp = Ivy_ObjSupp( pAig, pObj ); - assert( pSupp->fMark == 0 ); - // get the old delay of the node - DelayOld = Ivy_FastMapNodeDelay(pAig, pObj); - assert( DelayOld <= pSupp->DelayR ); - // copy the current cut - memcpy( Store, pSupp->pArray, sizeof(int) * pSupp->nSize ); - StoreSize = pSupp->nSize; - // get the fanin support - if ( Ivy_ObjRefs(pFanin0) > 1 && pSupp0->Delay < pSupp->DelayR ) - { - pSupp0 = pTemp0; - pSupp0->nSize = 1; - pSupp0->pArray[0] = Ivy_ObjFaninId0(pObj); - } - // get the fanin support - if ( Ivy_ObjRefs(pFanin1) > 1 && pSupp1->Delay < pSupp->DelayR ) - { - pSupp1 = pTemp1; - pSupp1->nSize = 1; - pSupp1->pArray[0] = Ivy_ObjFaninId1(pObj); - } - // merge the cuts - if ( pSupp0->nSize < pSupp1->nSize ) - RetValue = Ivy_FastMapMerge( pSupp1, pSupp0, pSupp, nLimit ); - else - RetValue = Ivy_FastMapMerge( pSupp0, pSupp1, pSupp, nLimit ); - if ( !RetValue ) - { - pSupp->nSize = 2; - pSupp->pArray[0] = Ivy_ObjFaninId0(pObj); - pSupp->pArray[1] = Ivy_ObjFaninId1(pObj); - } - // check the resulting delay - pSupp->Delay = Ivy_FastMapNodeDelay(pAig, pObj); - if ( pSupp->Delay > pSupp->DelayR ) - { - pSupp->nSize = StoreSize; - memcpy( pSupp->pArray, Store, sizeof(int) * pSupp->nSize ); - pSupp->Delay = DelayOld; - } -} - -/**Function************************************************************* - - Synopsis [Performs fast mapping for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodeArea( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ) -{ - static int Store[32], StoreSize; - static char Supp0[16], Supp1[16]; - static Ivy_Supp_t * pTemp0 = (Ivy_Supp_t *)Supp0; - static Ivy_Supp_t * pTemp1 = (Ivy_Supp_t *)Supp1; - Ivy_Obj_t * pFanin0, * pFanin1; - Ivy_Supp_t * pSupp0, * pSupp1, * pSupp; - int RetValue, DelayOld, RefsOld; - int AreaBef, AreaAft; - assert( nLimit <= 32 ); - assert( Ivy_ObjIsNode(pObj) ); - // get the fanins - pFanin0 = Ivy_ObjFanin0(pObj); - pFanin1 = Ivy_ObjFanin1(pObj); - // get the supports - pSupp0 = Ivy_ObjSupp( pAig, pFanin0 ); - pSupp1 = Ivy_ObjSupp( pAig, pFanin1 ); - pSupp = Ivy_ObjSupp( pAig, pObj ); - assert( pSupp->fMark == 0 ); - - // get the area - if ( pSupp->nRefs == 0 ) - AreaBef = Ivy_FastMapNodeAreaDerefed( pAig, pObj ); - else - AreaBef = Ivy_FastMapNodeAreaRefed( pAig, pObj ); -// if ( AreaBef == 1 ) -// return; - - // deref the cut if the node is refed - if ( pSupp->nRefs != 0 ) - Ivy_FastMapNodeDeref( pAig, pObj ); - - // get the old delay of the node - DelayOld = Ivy_FastMapNodeDelay(pAig, pObj); - assert( DelayOld <= pSupp->DelayR ); - // copy the current cut - memcpy( Store, pSupp->pArray, sizeof(int) * pSupp->nSize ); - StoreSize = pSupp->nSize; - // get the fanin support - if ( Ivy_ObjRefs(pFanin0) > 2 && pSupp0->Delay < pSupp->DelayR ) -// if ( pSupp0->nRefs > 0 && pSupp0->Delay < pSupp->DelayR ) // this leads to 2% worse results - { - pSupp0 = pTemp0; - pSupp0->nSize = 1; - pSupp0->pArray[0] = Ivy_ObjFaninId0(pObj); - } - // get the fanin support - if ( Ivy_ObjRefs(pFanin1) > 2 && pSupp1->Delay < pSupp->DelayR ) -// if ( pSupp1->nRefs > 0 && pSupp1->Delay < pSupp->DelayR ) - { - pSupp1 = pTemp1; - pSupp1->nSize = 1; - pSupp1->pArray[0] = Ivy_ObjFaninId1(pObj); - } - // merge the cuts - if ( pSupp0->nSize < pSupp1->nSize ) - RetValue = Ivy_FastMapMerge( pSupp1, pSupp0, pSupp, nLimit ); - else - RetValue = Ivy_FastMapMerge( pSupp0, pSupp1, pSupp, nLimit ); - if ( !RetValue ) - { - pSupp->nSize = 2; - pSupp->pArray[0] = Ivy_ObjFaninId0(pObj); - pSupp->pArray[1] = Ivy_ObjFaninId1(pObj); - } - - // check the resulting delay - pSupp->Delay = Ivy_FastMapNodeDelay(pAig, pObj); - - RefsOld = pSupp->nRefs; pSupp->nRefs = 0; - AreaAft = Ivy_FastMapNodeAreaDerefed( pAig, pObj ); - pSupp->nRefs = RefsOld; - - if ( AreaAft > AreaBef || pSupp->Delay > pSupp->DelayR ) -// if ( pSupp->Delay > pSupp->DelayR ) - { - pSupp->nSize = StoreSize; - memcpy( pSupp->pArray, Store, sizeof(int) * pSupp->nSize ); - pSupp->Delay = DelayOld; -// printf( "-" ); - } -// else -// printf( "+" ); - - if ( pSupp->nRefs != 0 ) - Ivy_FastMapNodeRef( pAig, pObj ); -} - -/**Function************************************************************* - - Synopsis [Performs fast mapping for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ) -{ - Ivy_Supp_t * pSupp0, * pSupp1, * pSupp; - int fFaninParam = 2; - int RetValue; - assert( Ivy_ObjIsNode(pObj) ); - // get the supports - pSupp0 = Ivy_ObjSupp( pAig, Ivy_ObjFanin0(pObj) ); - pSupp1 = Ivy_ObjSupp( pAig, Ivy_ObjFanin1(pObj) ); - pSupp = Ivy_ObjSupp( pAig, pObj ); - pSupp->fMark = 0; - // get the delays - if ( pSupp0->Delay == pSupp1->Delay ) - pSupp->Delay = (pSupp0->Delay == 0) ? pSupp0->Delay + 1: pSupp0->Delay; - else if ( pSupp0->Delay > pSupp1->Delay ) - { - pSupp->Delay = pSupp0->Delay; - pSupp1 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); - pSupp1->pArray[0] = Ivy_ObjFaninId1(pObj); - } - else // if ( pSupp0->Delay < pSupp1->Delay ) - { - pSupp->Delay = pSupp1->Delay; - pSupp0 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); - pSupp0->pArray[0] = Ivy_ObjFaninId0(pObj); - } - // merge the cuts - if ( pSupp0->nSize < pSupp1->nSize ) - RetValue = Ivy_FastMapMerge( pSupp1, pSupp0, pSupp, nLimit ); - else - RetValue = Ivy_FastMapMerge( pSupp0, pSupp1, pSupp, nLimit ); - if ( !RetValue ) - { - pSupp->Delay++; - if ( fFaninParam == 2 ) - { - pSupp->nSize = 2; - pSupp->pArray[0] = Ivy_ObjFaninId0(pObj); - pSupp->pArray[1] = Ivy_ObjFaninId1(pObj); - } - else if ( fFaninParam == 3 ) - { - Ivy_Obj_t * pFanin0, * pFanin1, * pFaninA, * pFaninB; - pFanin0 = Ivy_ObjFanin0(pObj); - pFanin1 = Ivy_ObjFanin1(pObj); - pSupp->nSize = 0; - // process the first fanin - if ( Ivy_ObjIsNodeInt1(pFanin0) ) - { - pFaninA = Ivy_ObjFanin0(pFanin0); - pFaninB = Ivy_ObjFanin1(pFanin0); - if ( Ivy_ObjIsNodeInt1(pFaninA) && Ivy_ObjIsNodeInt1(pFaninB) ) - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFanin0); - else - { - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFaninA); - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFaninB); - } - } - else - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFanin0); - // process the second fanin - if ( Ivy_ObjIsNodeInt1(pFanin1) ) - { - pFaninA = Ivy_ObjFanin0(pFanin1); - pFaninB = Ivy_ObjFanin1(pFanin1); - if ( Ivy_ObjIsNodeInt1(pFaninA) && Ivy_ObjIsNodeInt1(pFaninB) ) - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFanin1); - else - { - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFaninA); - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFaninB); - } - } - else - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFanin1); - // sort the fanins - Vec_IntSelectSort( pSupp->pArray, pSupp->nSize ); - pSupp->nSize = Vec_IntRemoveDup( pSupp->pArray, pSupp->nSize ); - assert( pSupp->pArray[0] < pSupp->pArray[1] ); - } - else if ( fFaninParam == 4 ) - { - Ivy_Obj_t * pFanin0, * pFanin1, * pFaninA, * pFaninB; - pFanin0 = Ivy_ObjFanin0(pObj); - pFanin1 = Ivy_ObjFanin1(pObj); - pSupp->nSize = 0; - // consider the case when exactly one of them is internal - if ( Ivy_ObjIsNodeInt1(pFanin0) ^ Ivy_ObjIsNodeInt1(pFanin1) ) - { - pSupp0 = Ivy_ObjSupp( pAig, Ivy_ObjFanin0(pObj) ); - pSupp1 = Ivy_ObjSupp( pAig, Ivy_ObjFanin1(pObj) ); - if ( Ivy_ObjIsNodeInt1(pFanin0) && pSupp0->nSize < nLimit ) - { - pSupp->Delay = IVY_MAX( pSupp0->Delay, pSupp1->Delay + 1 ); - pSupp1 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); - pSupp1->pArray[0] = Ivy_ObjId(pFanin1); - // merge the cuts - RetValue = Ivy_FastMapMerge( pSupp0, pSupp1, pSupp, nLimit ); - assert( RetValue ); - assert( pSupp->nSize > 1 ); - return; - } - if ( Ivy_ObjIsNodeInt1(pFanin1) && pSupp1->nSize < nLimit ) - { - pSupp->Delay = IVY_MAX( pSupp1->Delay, pSupp0->Delay + 1 ); - pSupp0 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); - pSupp0->pArray[0] = Ivy_ObjId(pFanin0); - // merge the cuts - RetValue = Ivy_FastMapMerge( pSupp1, pSupp0, pSupp, nLimit ); - assert( RetValue ); - assert( pSupp->nSize > 1 ); - return; - } - } - // process the first fanin - if ( Ivy_ObjIsNodeInt1(pFanin0) ) - { - pFaninA = Ivy_ObjFanin0(pFanin0); - pFaninB = Ivy_ObjFanin1(pFanin0); - if ( Ivy_ObjIsNodeInt1(pFaninA) && Ivy_ObjIsNodeInt1(pFaninB) ) - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFanin0); - else - { - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFaninA); - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFaninB); - } - } - else - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFanin0); - // process the second fanin - if ( Ivy_ObjIsNodeInt1(pFanin1) ) - { - pFaninA = Ivy_ObjFanin0(pFanin1); - pFaninB = Ivy_ObjFanin1(pFanin1); - if ( Ivy_ObjIsNodeInt1(pFaninA) && Ivy_ObjIsNodeInt1(pFaninB) ) - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFanin1); - else - { - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFaninA); - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFaninB); - } - } - else - pSupp->pArray[pSupp->nSize++] = Ivy_ObjId(pFanin1); - // sort the fanins - Vec_IntSelectSort( pSupp->pArray, pSupp->nSize ); - pSupp->nSize = Vec_IntRemoveDup( pSupp->pArray, pSupp->nSize ); - assert( pSupp->pArray[0] < pSupp->pArray[1] ); - assert( pSupp->nSize > 1 ); - } - } - assert( pSupp->Delay > 0 ); -} - -/**Function************************************************************* - - Synopsis [Merges two supports] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit ) -{ - int i, k, c; - assert( pSupp0->nSize >= pSupp1->nSize ); - // the case of the largest cut sizes - if ( pSupp0->nSize == nLimit && pSupp1->nSize == nLimit ) - { - for ( i = 0; i < pSupp0->nSize; i++ ) - if ( pSupp0->pArray[i] != pSupp1->pArray[i] ) - return 0; - for ( i = 0; i < pSupp0->nSize; i++ ) - pSupp->pArray[i] = pSupp0->pArray[i]; - pSupp->nSize = pSupp0->nSize; - return 1; - } - // the case when one of the cuts is the largest - if ( pSupp0->nSize == nLimit ) - { - for ( i = 0; i < pSupp1->nSize; i++ ) - { - for ( k = pSupp0->nSize - 1; k >= 0; k-- ) - if ( pSupp0->pArray[k] == pSupp1->pArray[i] ) - break; - if ( k == -1 ) // did not find - return 0; - } - for ( i = 0; i < pSupp0->nSize; i++ ) - pSupp->pArray[i] = pSupp0->pArray[i]; - pSupp->nSize = pSupp0->nSize; - return 1; - } - - // compare two cuts with different numbers - i = k = 0; - for ( c = 0; c < nLimit; c++ ) - { - if ( k == pSupp1->nSize ) - { - if ( i == pSupp0->nSize ) - { - pSupp->nSize = c; - return 1; - } - pSupp->pArray[c] = pSupp0->pArray[i++]; - continue; - } - if ( i == pSupp0->nSize ) - { - if ( k == pSupp1->nSize ) - { - pSupp->nSize = c; - return 1; - } - pSupp->pArray[c] = pSupp1->pArray[k++]; - continue; - } - if ( pSupp0->pArray[i] < pSupp1->pArray[k] ) - { - pSupp->pArray[c] = pSupp0->pArray[i++]; - continue; - } - if ( pSupp0->pArray[i] > pSupp1->pArray[k] ) - { - pSupp->pArray[c] = pSupp1->pArray[k++]; - continue; - } - pSupp->pArray[c] = pSupp0->pArray[i++]; - k++; - } - if ( i < pSupp0->nSize || k < pSupp1->nSize ) - return 0; - pSupp->nSize = c; - return 1; -} - -/**Function************************************************************* - - Synopsis [Creates integer vector with the support of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves ) -{ - Ivy_Supp_t * pSupp; - pSupp = Ivy_ObjSupp( pAig, pObj ); - vLeaves->nCap = 8; - vLeaves->nSize = pSupp->nSize; - vLeaves->pArray = pSupp->pArray; -} - -/**Function************************************************************* - - Synopsis [Sets the required times of the intermediate nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapRequired_rec( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Ivy_Obj_t * pRoot, int DelayR ) -{ - Ivy_Supp_t * pSupp; - pSupp = Ivy_ObjSupp( pAig, pObj ); - if ( pObj != pRoot && (pSupp->nRefs > 0 || Ivy_ObjIsCi(pObj)) ) - return; - Ivy_FastMapRequired_rec( pAig, Ivy_ObjFanin0(pObj), pRoot, DelayR ); - Ivy_FastMapRequired_rec( pAig, Ivy_ObjFanin1(pObj), pRoot, DelayR ); -// assert( pObj == pRoot || pSupp->DelayR == IVY_INFINITY ); - pSupp->DelayR = DelayR; -} - -/**Function************************************************************* - - Synopsis [Computes the required times for each node.] - - Description [Sets reference counters for each node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapRequired( Ivy_Man_t * pAig, int Delay, int fSetInter ) -{ - Vec_Vec_t * vLuts; - Vec_Ptr_t * vNodes; - Ivy_Obj_t * pObj; - Ivy_Supp_t * pSupp, * pSuppF; - int i, k, c; - // clean the required times - Ivy_ManForEachPi( pAig, pObj, i ) - { - pSupp = Ivy_ObjSupp( pAig, pObj ); - pSupp->DelayR = IVY_INFINITY; - pSupp->nRefs = 0; - } - Ivy_ManForEachNode( pAig, pObj, i ) - { - pSupp = Ivy_ObjSupp( pAig, pObj ); - pSupp->DelayR = IVY_INFINITY; - pSupp->nRefs = 0; - } - // set the required times of the POs - Ivy_ManForEachPo( pAig, pObj, i ) - { - pSupp = Ivy_ObjSupp( pAig, Ivy_ObjFanin0(pObj) ); - pSupp->DelayR = Delay; - pSupp->nRefs++; - } - // get the levelized nodes used in the mapping - vLuts = ((Ivy_SuppMan_t *)pAig->pData)->vLuts; - // propagate the required times - Vec_VecForEachLevelReverse( vLuts, vNodes, i ) - Vec_PtrForEachEntry( vNodes, pObj, k ) - { - pSupp = Ivy_ObjSupp( pAig, pObj ); - assert( pSupp->nRefs > 0 ); - for ( c = 0; c < pSupp->nSize; c++ ) - { - pSuppF = Ivy_ObjSupp( pAig, Ivy_ManObj(pAig, pSupp->pArray[c]) ); - pSuppF->DelayR = IVY_MIN( pSuppF->DelayR, pSupp->DelayR - 1 ); - pSuppF->nRefs++; - } - } -/* - // print out some of the required times - Ivy_ManForEachPi( pAig, pObj, i ) - { - pSupp = Ivy_ObjSupp( pAig, pObj ); - printf( "%d ", pSupp->DelayR ); - } - printf( "\n" ); -*/ - - if ( fSetInter ) - { - // set the required times of the intermediate nodes - Vec_VecForEachLevelReverse( vLuts, vNodes, i ) - Vec_PtrForEachEntry( vNodes, pObj, k ) - { - pSupp = Ivy_ObjSupp( pAig, pObj ); - Ivy_FastMapRequired_rec( pAig, pObj, pObj, pSupp->DelayR ); - } - // make sure that all required times are assigned - Ivy_ManForEachNode( pAig, pObj, i ) - { - pSupp = Ivy_ObjSupp( pAig, pObj ); - assert( pSupp->DelayR < IVY_INFINITY ); - } - } -} - -/**Function************************************************************* - - Synopsis [Performs area recovery for each node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapRecover( Ivy_Man_t * pAig, int nLimit ) -{ - Vec_Ptr_t * vFront, * vFrontOld; - Ivy_Obj_t * pObj; - int i; - vFront = Vec_PtrAlloc( nLimit ); - vFrontOld = Vec_PtrAlloc( nLimit ); - Ivy_ManCleanTravId( pAig ); - // iterate through all nodes in the topological order - Ivy_ManForEachNode( pAig, pObj, i ) - Ivy_FastMapNodeRecover( pAig, pObj, nLimit, vFront, vFrontOld ); - Vec_PtrFree( vFrontOld ); - Vec_PtrFree( vFront ); -} - -/**Function************************************************************* - - Synopsis [Computes the delay of the cut rooted at this node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapNodeDelay( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSupp, * pSuppF; - int c, Delay = 0; - pSupp = Ivy_ObjSupp( pAig, pObj ); - for ( c = 0; c < pSupp->nSize; c++ ) - { - pSuppF = Ivy_ObjSupp( pAig, Ivy_ManObj(pAig, pSupp->pArray[c]) ); - Delay = IVY_MAX( Delay, pSuppF->Delay ); - } - return 1 + Delay; -} - - -/**function************************************************************* - - synopsis [References the cut.] - - description [This procedure is similar to the procedure NodeReclaim.] - - sideeffects [] - - seealso [] - -***********************************************************************/ -int Ivy_FastMapNodeRef( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSupp, * pSuppF; - Ivy_Obj_t * pNodeChild; - int aArea, i; - // start the area of this cut - aArea = 1; - // go through the children - pSupp = Ivy_ObjSupp( pAig, pObj ); - assert( pSupp->nSize > 1 ); - for ( i = 0; i < pSupp->nSize; i++ ) - { - pNodeChild = Ivy_ManObj(pAig, pSupp->pArray[i]); - pSuppF = Ivy_ObjSupp( pAig, pNodeChild ); - assert( pSuppF->nRefs >= 0 ); - if ( pSuppF->nRefs++ > 0 ) - continue; - if ( pSuppF->nSize == 1 ) - continue; - aArea += Ivy_FastMapNodeRef( pAig, pNodeChild ); - } - return aArea; -} - -/**function************************************************************* - - synopsis [Dereferences the cut.] - - description [This procedure is similar to the procedure NodeRecusiveDeref.] - - sideeffects [] - - seealso [] - -***********************************************************************/ -int Ivy_FastMapNodeDeref( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSupp, * pSuppF; - Ivy_Obj_t * pNodeChild; - int aArea, i; - // start the area of this cut - aArea = 1; - // go through the children - pSupp = Ivy_ObjSupp( pAig, pObj ); - assert( pSupp->nSize > 1 ); - for ( i = 0; i < pSupp->nSize; i++ ) - { - pNodeChild = Ivy_ManObj(pAig, pSupp->pArray[i]); - pSuppF = Ivy_ObjSupp( pAig, pNodeChild ); - assert( pSuppF->nRefs > 0 ); - if ( --pSuppF->nRefs > 0 ) - continue; - if ( pSuppF->nSize == 1 ) - continue; - aArea += Ivy_FastMapNodeDeref( pAig, pNodeChild ); - } - return aArea; -} - -/**function************************************************************* - - synopsis [Computes the exact area associated with the cut.] - - description [] - - sideeffects [] - - seealso [] - -***********************************************************************/ -int Ivy_FastMapNodeAreaRefed( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSupp; - int aResult, aResult2; - if ( Ivy_ObjIsCi(pObj) ) - return 0; - assert( Ivy_ObjIsNode(pObj) ); - pSupp = Ivy_ObjSupp( pAig, pObj ); - assert( pSupp->nRefs > 0 ); - aResult = Ivy_FastMapNodeDeref( pAig, pObj ); - aResult2 = Ivy_FastMapNodeRef( pAig, pObj ); - assert( aResult == aResult2 ); - return aResult; -} - -/**function************************************************************* - - synopsis [Computes the exact area associated with the cut.] - - description [] - - sideeffects [] - - seealso [] - -***********************************************************************/ -int Ivy_FastMapNodeAreaDerefed( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSupp; - int aResult, aResult2; - if ( Ivy_ObjIsCi(pObj) ) - return 0; - assert( Ivy_ObjIsNode(pObj) ); - pSupp = Ivy_ObjSupp( pAig, pObj ); - assert( pSupp->nRefs == 0 ); - aResult2 = Ivy_FastMapNodeRef( pAig, pObj ); - aResult = Ivy_FastMapNodeDeref( pAig, pObj ); - assert( aResult == aResult2 ); - return aResult; -} - - - - -/**Function************************************************************* - - Synopsis [Counts the number of nodes with no external fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapCutCost( Ivy_Man_t * pAig, Vec_Ptr_t * vFront ) -{ - Ivy_Supp_t * pSuppF; - Ivy_Obj_t * pFanin; - int i, Counter = 0; - Vec_PtrForEachEntry( vFront, pFanin, i ) - { - pSuppF = Ivy_ObjSupp( pAig, pFanin ); - if ( pSuppF->nRefs == 0 ) - Counter++; - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Performs area recovery for each node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapMark_rec( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - if ( Ivy_ObjIsTravIdCurrent(pAig, pObj) ) - return; - assert( Ivy_ObjIsNode(pObj) ); - Ivy_FastMapMark_rec( pAig, Ivy_ObjFanin0(pObj) ); - Ivy_FastMapMark_rec( pAig, Ivy_ObjFanin1(pObj) ); - Ivy_ObjSetTravIdCurrent(pAig, pObj); -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the number of fanins will grow.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapNodeWillGrow( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pFanin0, * pFanin1; - assert( Ivy_ObjIsNode(pObj) ); - pFanin0 = Ivy_ObjFanin0(pObj); - pFanin1 = Ivy_ObjFanin1(pObj); - return !Ivy_ObjIsTravIdCurrent(pAig, pFanin0) && !Ivy_ObjIsTravIdCurrent(pAig, pFanin1); -} - -/**Function************************************************************* - - Synopsis [Returns the increase in the number of fanins with no external refs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapNodeFaninCost( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSuppF; - Ivy_Obj_t * pFanin; - int Counter = 0; - assert( Ivy_ObjIsNode(pObj) ); - // check if the node has external refs - pSuppF = Ivy_ObjSupp( pAig, pObj ); - if ( pSuppF->nRefs == 0 ) - Counter--; - // increment the number of fanins without external refs - pFanin = Ivy_ObjFanin0(pObj); - pSuppF = Ivy_ObjSupp( pAig, pFanin ); - if ( !Ivy_ObjIsTravIdCurrent(pAig, pFanin) && pSuppF->nRefs == 0 ) - Counter++; - // increment the number of fanins without external refs - pFanin = Ivy_ObjFanin1(pObj); - pSuppF = Ivy_ObjSupp( pAig, pFanin ); - if ( !Ivy_ObjIsTravIdCurrent(pAig, pFanin) && pSuppF->nRefs == 0 ) - Counter++; - return Counter; -} - -/**Function************************************************************* - - Synopsis [Updates the frontier.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodeFaninUpdate( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Ptr_t * vFront ) -{ - Ivy_Obj_t * pFanin; - assert( Ivy_ObjIsNode(pObj) ); - Vec_PtrRemove( vFront, pObj ); - pFanin = Ivy_ObjFanin0(pObj); - if ( !Ivy_ObjIsTravIdCurrent(pAig, pFanin) ) - { - Ivy_ObjSetTravIdCurrent(pAig, pFanin); - Vec_PtrPush( vFront, pFanin ); - } - pFanin = Ivy_ObjFanin1(pObj); - if ( !Ivy_ObjIsTravIdCurrent(pAig, pFanin) ) - { - Ivy_ObjSetTravIdCurrent(pAig, pFanin); - Vec_PtrPush( vFront, pFanin ); - } -} - -/**Function************************************************************* - - Synopsis [Compacts the number of external refs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapNodeFaninCompact0( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) -{ - Ivy_Obj_t * pFanin; - int i; - Vec_PtrForEachEntry( vFront, pFanin, i ) - { - if ( Ivy_ObjIsCi(pFanin) ) - continue; - if ( Ivy_FastMapNodeWillGrow(pAig, pFanin) ) - continue; - if ( Ivy_FastMapNodeFaninCost(pAig, pFanin) <= 0 ) - { - Ivy_FastMapNodeFaninUpdate( pAig, pFanin, vFront ); - return 1; - } - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Compacts the number of external refs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapNodeFaninCompact1( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) -{ - Ivy_Obj_t * pFanin; - int i; - Vec_PtrForEachEntry( vFront, pFanin, i ) - { - if ( Ivy_ObjIsCi(pFanin) ) - continue; - if ( Ivy_FastMapNodeFaninCost(pAig, pFanin) < 0 ) - { - Ivy_FastMapNodeFaninUpdate( pAig, pFanin, vFront ); - return 1; - } - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Compacts the number of external refs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapNodeFaninCompact2( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) -{ - Ivy_Obj_t * pFanin; - int i; - Vec_PtrForEachEntry( vFront, pFanin, i ) - { - if ( Ivy_ObjIsCi(pFanin) ) - continue; - if ( Ivy_FastMapNodeFaninCost(pAig, pFanin) <= 0 ) - { - Ivy_FastMapNodeFaninUpdate( pAig, pFanin, vFront ); - return 1; - } - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Compacts the number of external refs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FastMapNodeFaninCompact_int( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) -{ - if ( Ivy_FastMapNodeFaninCompact0(pAig, pObj, nLimit, vFront) ) - return 1; - if ( Vec_PtrSize(vFront) < nLimit && Ivy_FastMapNodeFaninCompact1(pAig, pObj, nLimit, vFront) ) - return 1; - if ( Vec_PtrSize(vFront) < nLimit && Ivy_FastMapNodeFaninCompact2(pAig, pObj, nLimit, vFront) ) - return 1; - assert( Vec_PtrSize(vFront) <= nLimit ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Compacts the number of external refs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodeFaninCompact( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) -{ - while ( Ivy_FastMapNodeFaninCompact_int( pAig, pObj, nLimit, vFront ) ); -} - -/**Function************************************************************* - - Synopsis [Prepares node mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodePrepare( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ) -{ - Ivy_Supp_t * pSupp; - Ivy_Obj_t * pFanin; - int i; - pSupp = Ivy_ObjSupp( pAig, pObj ); - // expand the cut downwards from the given place - Vec_PtrClear( vFront ); - Vec_PtrClear( vFrontOld ); - Ivy_ManIncrementTravId( pAig ); - for ( i = 0; i < pSupp->nSize; i++ ) - { - pFanin = Ivy_ManObj(pAig, pSupp->pArray[i]); - Vec_PtrPush( vFront, pFanin ); - Vec_PtrPush( vFrontOld, pFanin ); - Ivy_ObjSetTravIdCurrent( pAig, pFanin ); - } - // mark the nodes in the cone - Ivy_FastMapMark_rec( pAig, pObj ); -} - -/**Function************************************************************* - - Synopsis [Updates the frontier.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodeUpdate( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Ptr_t * vFront ) -{ - Ivy_Supp_t * pSupp; - Ivy_Obj_t * pFanin; - int i; - pSupp = Ivy_ObjSupp( pAig, pObj ); - // deref node's cut - Ivy_FastMapNodeDeref( pAig, pObj ); - // update the node's cut - pSupp->nSize = Vec_PtrSize(vFront); - Vec_PtrForEachEntry( vFront, pFanin, i ) - pSupp->pArray[i] = pFanin->Id; - // ref the new cut - Ivy_FastMapNodeRef( pAig, pObj ); -} - -/**Function************************************************************* - - Synopsis [Performs area recovery for each node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodeRecover2( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ) -{ - Ivy_Supp_t * pSupp; - int CostBef, CostAft; - int AreaBef, AreaAft; - pSupp = Ivy_ObjSupp( pAig, pObj ); -// if ( pSupp->nRefs == 0 ) -// return; - if ( pSupp->nRefs == 0 ) - AreaBef = Ivy_FastMapNodeAreaDerefed( pAig, pObj ); - else - AreaBef = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - // get the area - if ( AreaBef == 1 ) - return; - - if ( pSupp->nRefs == 0 ) - { - pSupp->nRefs = 1000000; - Ivy_FastMapNodeRef( pAig, pObj ); - } - // the cut is non-trivial - Ivy_FastMapNodePrepare( pAig, pObj, nLimit, vFront, vFrontOld ); - // iteratively modify the cut - CostBef = Ivy_FastMapCutCost( pAig, vFront ); - Ivy_FastMapNodeFaninCompact( pAig, pObj, nLimit, vFront ); - CostAft = Ivy_FastMapCutCost( pAig, vFront ); - assert( CostBef >= CostAft ); - // update the node - Ivy_FastMapNodeUpdate( pAig, pObj, vFront ); - // get the new area - AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - if ( AreaAft > AreaBef ) - { - Ivy_FastMapNodeUpdate( pAig, pObj, vFrontOld ); - AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - assert( AreaAft == AreaBef ); - } - if ( pSupp->nRefs == 1000000 ) - { - pSupp->nRefs = 0; - Ivy_FastMapNodeDeref( pAig, pObj ); - } -} - -/**Function************************************************************* - - Synopsis [Performs area recovery for each node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodeRecover( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ) -{ - Ivy_Supp_t * pSupp; - int CostBef, CostAft; - int AreaBef, AreaAft; - int DelayOld; - pSupp = Ivy_ObjSupp( pAig, pObj ); - DelayOld = pSupp->Delay = Ivy_FastMapNodeDelay( pAig, pObj ); - assert( pSupp->Delay <= pSupp->DelayR ); - if ( pSupp->nRefs == 0 ) - return; - // get the area - AreaBef = Ivy_FastMapNodeAreaRefed( pAig, pObj ); -// if ( AreaBef == 1 ) -// return; - if ( pObj->Id == 102 ) - { - int x = 0; - } - // the cut is non-trivial - Ivy_FastMapNodePrepare( pAig, pObj, nLimit, vFront, vFrontOld ); - // iteratively modify the cut - Ivy_FastMapNodeDeref( pAig, pObj ); - CostBef = Ivy_FastMapCutCost( pAig, vFront ); - Ivy_FastMapNodeFaninCompact( pAig, pObj, nLimit, vFront ); - CostAft = Ivy_FastMapCutCost( pAig, vFront ); - Ivy_FastMapNodeRef( pAig, pObj ); - assert( CostBef >= CostAft ); - // update the node - Ivy_FastMapNodeUpdate( pAig, pObj, vFront ); - pSupp->Delay = Ivy_FastMapNodeDelay( pAig, pObj ); - // get the new area - AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - if ( AreaAft > AreaBef || pSupp->Delay > pSupp->DelayR ) - { - Ivy_FastMapNodeUpdate( pAig, pObj, vFrontOld ); - AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - assert( AreaAft == AreaBef ); - pSupp->Delay = DelayOld; - } -} - -/**Function************************************************************* - - Synopsis [Performs area recovery for each node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FastMapNodeRecover4( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ) -{ - Ivy_Supp_t * pSupp; - int CostBef, CostAft; - int AreaBef, AreaAft; - int DelayOld; - pSupp = Ivy_ObjSupp( pAig, pObj ); - DelayOld = pSupp->Delay = Ivy_FastMapNodeDelay( pAig, pObj ); - assert( pSupp->Delay <= pSupp->DelayR ); -// if ( pSupp->nRefs == 0 ) -// return; -// AreaBef = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - // get the area - if ( pSupp->nRefs == 0 ) - AreaBef = Ivy_FastMapNodeAreaDerefed( pAig, pObj ); - else - AreaBef = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - if ( AreaBef == 1 ) - return; - - if ( pSupp->nRefs == 0 ) - { - pSupp->nRefs = 1000000; - Ivy_FastMapNodeRef( pAig, pObj ); - } - // the cut is non-trivial - Ivy_FastMapNodePrepare( pAig, pObj, nLimit, vFront, vFrontOld ); - // iteratively modify the cut - CostBef = Ivy_FastMapCutCost( pAig, vFront ); - Ivy_FastMapNodeFaninCompact( pAig, pObj, nLimit, vFront ); - CostAft = Ivy_FastMapCutCost( pAig, vFront ); - assert( CostBef >= CostAft ); - // update the node - Ivy_FastMapNodeUpdate( pAig, pObj, vFront ); - pSupp->Delay = Ivy_FastMapNodeDelay( pAig, pObj ); - // get the new area - AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - if ( AreaAft > AreaBef || pSupp->Delay > pSupp->DelayR ) - { - Ivy_FastMapNodeUpdate( pAig, pObj, vFrontOld ); - AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); - assert( AreaAft == AreaBef ); - pSupp->Delay = DelayOld; - } - if ( pSupp->nRefs == 1000000 ) - { - pSupp->nRefs = 0; - Ivy_FastMapNodeDeref( pAig, pObj ); - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyFraig.c b/src/aig/ivy/ivyFraig.c deleted file mode 100644 index 4079b6ed..00000000 --- a/src/aig/ivy/ivyFraig.c +++ /dev/null @@ -1,2760 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyFraig.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [Functional reduction of AIGs] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyFraig.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "satSolver.h" -#include "extra.h" -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Ivy_FraigMan_t_ Ivy_FraigMan_t; -typedef struct Ivy_FraigSim_t_ Ivy_FraigSim_t; -typedef struct Ivy_FraigList_t_ Ivy_FraigList_t; - -struct Ivy_FraigList_t_ -{ - Ivy_Obj_t * pHead; - Ivy_Obj_t * pTail; - int nItems; -}; - -struct Ivy_FraigSim_t_ -{ - int Type; - Ivy_FraigSim_t * pNext; - Ivy_FraigSim_t * pFanin0; - Ivy_FraigSim_t * pFanin1; - unsigned pData[0]; -}; - -struct Ivy_FraigMan_t_ -{ - // general info - Ivy_FraigParams_t * pParams; // various parameters - // temporary backtrack limits because "sint64" cannot be defined in Ivy_FraigParams_t ... - sint64 nBTLimitGlobal; // global limit on the number of backtracks - sint64 nInsLimitGlobal;// global limit on the number of clause inspects - // AIG manager - Ivy_Man_t * pManAig; // the starting AIG manager - Ivy_Man_t * pManFraig; // the final AIG manager - // simulation information - int nSimWords; // the number of words - char * pSimWords; // the simulation info - Ivy_FraigSim_t * pSimStart; // the list of simulation info for internal nodes - // counter example storage - int nPatWords; // the number of words in the counter example - unsigned * pPatWords; // the counter example - int * pPatScores; // the scores of each pattern - // equivalence classes - Ivy_FraigList_t lClasses; // equivalence classes - Ivy_FraigList_t lCand; // candidatates - int nPairs; // the number of pairs of nodes - // equivalence checking - sat_solver * pSat; // SAT solver - int nSatVars; // the number of variables currently used - Vec_Ptr_t * vPiVars; // the PIs of the cone used - // other - ProgressBar * pProgress; - // statistics - int nSimRounds; - int nNodesMiter; - int nClassesZero; - int nClassesBeg; - int nClassesEnd; - int nPairsBeg; - int nPairsEnd; - int nSatCalls; - int nSatCallsSat; - int nSatCallsUnsat; - int nSatProof; - int nSatFails; - int nSatFailsReal; - // runtime - int timeSim; - int timeTrav; - int timeSat; - int timeSatUnsat; - int timeSatSat; - int timeSatFail; - int timeRef; - int timeTotal; - int time1; - int time2; -}; - -typedef struct Prove_ParamsStruct_t_ Prove_Params_t; -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 - // iterations - int nItersMax; // the number of iterations - // mitering - 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 - // fraiging - 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 - // last-gasp mitering - 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 -}; - -static inline Ivy_FraigSim_t * Ivy_ObjSim( Ivy_Obj_t * pObj ) { return (Ivy_FraigSim_t *)pObj->pFanout; } -static inline Ivy_Obj_t * Ivy_ObjClassNodeLast( Ivy_Obj_t * pObj ) { return pObj->pNextFan0; } -static inline Ivy_Obj_t * Ivy_ObjClassNodeRepr( Ivy_Obj_t * pObj ) { return pObj->pNextFan0; } -static inline Ivy_Obj_t * Ivy_ObjClassNodeNext( Ivy_Obj_t * pObj ) { return pObj->pNextFan1; } -static inline Ivy_Obj_t * Ivy_ObjNodeHashNext( Ivy_Obj_t * pObj ) { return pObj->pPrevFan0; } -static inline Ivy_Obj_t * Ivy_ObjEquivListNext( Ivy_Obj_t * pObj ) { return pObj->pPrevFan0; } -static inline Ivy_Obj_t * Ivy_ObjEquivListPrev( Ivy_Obj_t * pObj ) { return pObj->pPrevFan1; } -static inline Ivy_Obj_t * Ivy_ObjFraig( Ivy_Obj_t * pObj ) { return pObj->pEquiv; } -static inline int Ivy_ObjSatNum( Ivy_Obj_t * pObj ) { return (int)pObj->pNextFan0; } -static inline Vec_Ptr_t * Ivy_ObjFaninVec( Ivy_Obj_t * pObj ) { return (Vec_Ptr_t *)pObj->pNextFan1; } - -static inline void Ivy_ObjSetSim( Ivy_Obj_t * pObj, Ivy_FraigSim_t * pSim ) { pObj->pFanout = (Ivy_Obj_t *)pSim; } -static inline void Ivy_ObjSetClassNodeLast( Ivy_Obj_t * pObj, Ivy_Obj_t * pLast ) { pObj->pNextFan0 = pLast; } -static inline void Ivy_ObjSetClassNodeRepr( Ivy_Obj_t * pObj, Ivy_Obj_t * pRepr ) { pObj->pNextFan0 = pRepr; } -static inline void Ivy_ObjSetClassNodeNext( Ivy_Obj_t * pObj, Ivy_Obj_t * pNext ) { pObj->pNextFan1 = pNext; } -static inline void Ivy_ObjSetNodeHashNext( Ivy_Obj_t * pObj, Ivy_Obj_t * pNext ) { pObj->pPrevFan0 = pNext; } -static inline void Ivy_ObjSetEquivListNext( Ivy_Obj_t * pObj, Ivy_Obj_t * pNext ) { pObj->pPrevFan0 = pNext; } -static inline void Ivy_ObjSetEquivListPrev( Ivy_Obj_t * pObj, Ivy_Obj_t * pPrev ) { pObj->pPrevFan1 = pPrev; } -static inline void Ivy_ObjSetFraig( Ivy_Obj_t * pObj, Ivy_Obj_t * pNode ) { pObj->pEquiv = pNode; } -static inline void Ivy_ObjSetSatNum( Ivy_Obj_t * pObj, int Num ) { pObj->pNextFan0 = (Ivy_Obj_t *)Num; } -static inline void Ivy_ObjSetFaninVec( Ivy_Obj_t * pObj, Vec_Ptr_t * vFanins ) { pObj->pNextFan1 = (Ivy_Obj_t *)vFanins; } - -static inline unsigned Ivy_ObjRandomSim() { return (rand() << 24) ^ (rand() << 12) ^ rand(); } - -// iterate through equivalence classes -#define Ivy_FraigForEachEquivClass( pList, pEnt ) \ - for ( pEnt = pList; \ - pEnt; \ - pEnt = Ivy_ObjEquivListNext(pEnt) ) -#define Ivy_FraigForEachEquivClassSafe( pList, pEnt, pEnt2 ) \ - for ( pEnt = pList, \ - pEnt2 = pEnt? Ivy_ObjEquivListNext(pEnt): NULL; \ - pEnt; \ - pEnt = pEnt2, \ - pEnt2 = pEnt? Ivy_ObjEquivListNext(pEnt): NULL ) -// iterate through nodes in one class -#define Ivy_FraigForEachClassNode( pClass, pEnt ) \ - for ( pEnt = pClass; \ - pEnt; \ - pEnt = Ivy_ObjClassNodeNext(pEnt) ) -// iterate through nodes in the hash table -#define Ivy_FraigForEachBinNode( pBin, pEnt ) \ - for ( pEnt = pBin; \ - pEnt; \ - pEnt = Ivy_ObjNodeHashNext(pEnt) ) - -static Ivy_FraigMan_t * Ivy_FraigStart( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams ); -static Ivy_FraigMan_t * Ivy_FraigStartSimple( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams ); -static Ivy_Man_t * Ivy_FraigPerform_int( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams, sint64 nBTLimitGlobal, sint64 nInsLimitGlobal, sint64 * pnSatConfs, sint64 * pnSatInspects ); -static void Ivy_FraigPrint( Ivy_FraigMan_t * p ); -static void Ivy_FraigStop( Ivy_FraigMan_t * p ); -static void Ivy_FraigSimulate( Ivy_FraigMan_t * p ); -static void Ivy_FraigSweep( Ivy_FraigMan_t * p ); -static Ivy_Obj_t * Ivy_FraigAnd( Ivy_FraigMan_t * p, Ivy_Obj_t * pObjOld ); -static int Ivy_FraigNodesAreEquiv( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 ); -static int Ivy_FraigNodeIsConst( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj ); -static void Ivy_FraigNodeAddToSolver( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 ); -static int Ivy_FraigSetActivityFactors( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * pNew ); -static void Ivy_FraigAddToPatScores( Ivy_FraigMan_t * p, Ivy_Obj_t * pClass, Ivy_Obj_t * pClassNew ); -static int Ivy_FraigMiterStatus( Ivy_Man_t * pMan ); -static void Ivy_FraigMiterProve( Ivy_FraigMan_t * p ); -static void Ivy_FraigMiterPrint( Ivy_Man_t * pNtk, char * pString, int clk, int fVerbose ); -static int * Ivy_FraigCreateModel( Ivy_FraigMan_t * p ); - -static int Ivy_FraigNodesAreEquivBdd( Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2 ); - -static sint64 s_nBTLimitGlobal = 0; -static sint64 s_nInsLimitGlobal = 0; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Sets the default solving parameters.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigParamsDefault( Ivy_FraigParams_t * pParams ) -{ - memset( pParams, 0, sizeof(Ivy_FraigParams_t) ); - pParams->nSimWords = 32; // the number of words in the simulation info - pParams->dSimSatur = 0.005; // the ratio of refined classes when saturation is reached - pParams->fPatScores = 0; // enables simulation pattern scoring - pParams->MaxScore = 25; // max score after which resimulation is used - pParams->fDoSparse = 1; // skips sparse functions -// pParams->dActConeRatio = 0.05; // the ratio of cone to be bumped -// pParams->dActConeBumpMax = 5.0; // the largest bump of activity - pParams->dActConeRatio = 0.3; // the ratio of cone to be bumped - pParams->dActConeBumpMax = 10.0; // the largest bump of activity - - pParams->nBTLimitNode = 100; // conflict limit at a node - pParams->nBTLimitMiter = 500000; // conflict limit at an output -// pParams->nBTLimitGlobal = 0; // conflict limit global -// pParams->nInsLimitGlobal = 0; // inspection limit global -} - -/**Function************************************************************* - - Synopsis [Performs combinational equivalence checking for the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigProve( Ivy_Man_t ** ppManAig, void * pPars ) -{ - Prove_Params_t * pParams = pPars; - Ivy_FraigParams_t Params, * pIvyParams = &Params; - Ivy_Man_t * pManAig, * pManTemp; - int RetValue, nIter, clk, timeStart = clock();//, Counter; - sint64 nSatConfs, nSatInspects; - - // start the network and parameters - pManAig = *ppManAig; - Ivy_FraigParamsDefault( pIvyParams ); - pIvyParams->fVerbose = pParams->fVerbose; - pIvyParams->fProve = 1; - - if ( pParams->fVerbose ) - { - printf( "RESOURCE LIMITS: Iterations = %d. Rewriting = %s. Fraiging = %s.\n", - pParams->nItersMax, pParams->fUseRewriting? "yes":"no", pParams->fUseFraiging? "yes":"no" ); - printf( "Miter = %d (%3.1f). Rwr = %d (%3.1f). Fraig = %d (%3.1f). Last = %d.\n", - pParams->nMiteringLimitStart, pParams->nMiteringLimitMulti, - pParams->nRewritingLimitStart, pParams->nRewritingLimitMulti, - pParams->nFraigingLimitStart, pParams->nFraigingLimitMulti, pParams->nMiteringLimitLast ); - } - - // if SAT only, solve without iteration - if ( !pParams->fUseRewriting && !pParams->fUseFraiging ) - { - clk = clock(); - pIvyParams->nBTLimitMiter = pParams->nMiteringLimitLast / Ivy_ManPoNum(pManAig); - pManAig = Ivy_FraigMiter( pManTemp = pManAig, pIvyParams ); Ivy_ManStop( pManTemp ); - RetValue = Ivy_FraigMiterStatus( pManAig ); - Ivy_FraigMiterPrint( pManAig, "SAT solving", clk, pParams->fVerbose ); - *ppManAig = pManAig; - return RetValue; - } - - if ( Ivy_ManNodeNum(pManAig) < 500 ) - { - // run the first mitering - clk = clock(); - pIvyParams->nBTLimitMiter = pParams->nMiteringLimitStart / Ivy_ManPoNum(pManAig); - pManAig = Ivy_FraigMiter( pManTemp = pManAig, pIvyParams ); Ivy_ManStop( pManTemp ); - RetValue = Ivy_FraigMiterStatus( pManAig ); - Ivy_FraigMiterPrint( pManAig, "SAT solving", clk, pParams->fVerbose ); - if ( RetValue >= 0 ) - { - *ppManAig = pManAig; - return RetValue; - } - } - - // check the current resource limits - RetValue = -1; - for ( nIter = 0; nIter < pParams->nItersMax; nIter++ ) - { - if ( pParams->fVerbose ) - { - printf( "ITERATION %2d : Confs = %6d. FraigBTL = %3d. \n", nIter+1, - (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), - (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)) ); - fflush( stdout ); - } - - // try rewriting - if ( pParams->fUseRewriting ) - { // bug in Ivy_NodeFindCutsAll() when leaves are identical! -/* - clk = clock(); - Counter = (int)(pParams->nRewritingLimitStart * pow(pParams->nRewritingLimitMulti,nIter)); - pManAig = Ivy_ManRwsat( pManAig, 0 ); - RetValue = Ivy_FraigMiterStatus( pManAig ); - Ivy_FraigMiterPrint( pManAig, "Rewriting ", clk, pParams->fVerbose ); -*/ - } - if ( RetValue >= 0 ) - break; - - // try fraiging followed by mitering - if ( pParams->fUseFraiging ) - { - clk = clock(); - pIvyParams->nBTLimitNode = (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)); - pIvyParams->nBTLimitMiter = (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)) / Ivy_ManPoNum(pManAig); - pManAig = Ivy_FraigPerform_int( pManTemp = pManAig, pIvyParams, pParams->nTotalBacktrackLimit, pParams->nTotalInspectLimit, &nSatConfs, &nSatInspects ); Ivy_ManStop( pManTemp ); - RetValue = Ivy_FraigMiterStatus( pManAig ); - Ivy_FraigMiterPrint( pManAig, "Fraiging ", 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" ); - *ppManAig = pManAig; - return -1; - } - } - - if ( RetValue < 0 ) - { - if ( pParams->fVerbose ) - { - printf( "Attempting SAT with conflict limit %d ...\n", pParams->nMiteringLimitLast ); - fflush( stdout ); - } - clk = clock(); - pIvyParams->nBTLimitMiter = pParams->nMiteringLimitLast / Ivy_ManPoNum(pManAig); - if ( pParams->nTotalBacktrackLimit ) - s_nBTLimitGlobal = pParams->nTotalBacktrackLimit - pParams->nTotalBacktracksMade; - if ( pParams->nTotalInspectLimit ) - s_nInsLimitGlobal = pParams->nTotalInspectLimit - pParams->nTotalInspectsMade; - pManAig = Ivy_FraigMiter( pManTemp = pManAig, pIvyParams ); Ivy_ManStop( pManTemp ); - s_nBTLimitGlobal = 0; - s_nInsLimitGlobal = 0; - RetValue = Ivy_FraigMiterStatus( pManAig ); - Ivy_FraigMiterPrint( pManAig, "SAT solving", clk, pParams->fVerbose ); - // make sure that the sover never returns "undecided" when infinite resource limits are set - if( RetValue == -1 && pParams->nTotalInspectLimit == 0 && - pParams->nTotalBacktrackLimit == 0 ) - { - extern void Prove_ParamsPrint( Prove_Params_t * pParams ); - Prove_ParamsPrint( pParams ); - printf("ERROR: ABC has returned \"undecided\" in spite of no limits...\n"); - exit(1); - } - } - - // assign the model if it was proved by rewriting (const 1 miter) - if ( RetValue == 0 && pManAig->pData == NULL ) - { - pManAig->pData = ALLOC( int, Ivy_ManPiNum(pManAig) ); - memset( pManAig->pData, 0, sizeof(int) * Ivy_ManPiNum(pManAig) ); - } - *ppManAig = pManAig; - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Performs fraiging of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_FraigPerform_int( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams, sint64 nBTLimitGlobal, sint64 nInsLimitGlobal, sint64 * pnSatConfs, sint64 * pnSatInspects ) -{ - Ivy_FraigMan_t * p; - Ivy_Man_t * pManAigNew; - int clk; - if ( Ivy_ManNodeNum(pManAig) == 0 ) - return Ivy_ManDup(pManAig); -clk = clock(); - assert( Ivy_ManLatchNum(pManAig) == 0 ); - p = Ivy_FraigStart( pManAig, pParams ); - // set global limits - p->nBTLimitGlobal = nBTLimitGlobal; - p->nInsLimitGlobal = nInsLimitGlobal; - - Ivy_FraigSimulate( p ); - Ivy_FraigSweep( p ); - pManAigNew = p->pManFraig; -p->timeTotal = clock() - clk; - if ( pnSatConfs ) - *pnSatConfs = p->pSat? p->pSat->stats.conflicts : 0; - if ( pnSatInspects ) - *pnSatInspects = p->pSat? p->pSat->stats.inspects : 0; - Ivy_FraigStop( p ); - return pManAigNew; -} - -/**Function************************************************************* - - Synopsis [Performs fraiging of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_FraigPerform( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams ) -{ - Ivy_FraigMan_t * p; - Ivy_Man_t * pManAigNew; - int clk; - if ( Ivy_ManNodeNum(pManAig) == 0 ) - return Ivy_ManDup(pManAig); -clk = clock(); - assert( Ivy_ManLatchNum(pManAig) == 0 ); - p = Ivy_FraigStart( pManAig, pParams ); - Ivy_FraigSimulate( p ); - Ivy_FraigSweep( p ); - pManAigNew = p->pManFraig; -p->timeTotal = clock() - clk; - Ivy_FraigStop( p ); - return pManAigNew; -} - -/**Function************************************************************* - - Synopsis [Applies brute-force SAT to the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_FraigMiter( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams ) -{ - Ivy_FraigMan_t * p; - Ivy_Man_t * pManAigNew; - Ivy_Obj_t * pObj; - int i, clk; -clk = clock(); - assert( Ivy_ManLatchNum(pManAig) == 0 ); - p = Ivy_FraigStartSimple( pManAig, pParams ); - // set global limits - p->nBTLimitGlobal = s_nBTLimitGlobal; - p->nInsLimitGlobal = s_nInsLimitGlobal; - // duplicate internal nodes - Ivy_ManForEachNode( p->pManAig, pObj, i ) - pObj->pEquiv = Ivy_And( p->pManFraig, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) ); - // try to prove each output of the miter - Ivy_FraigMiterProve( p ); - // add the POs - Ivy_ManForEachPo( p->pManAig, pObj, i ) - Ivy_ObjCreatePo( p->pManFraig, Ivy_ObjChild0Equiv(pObj) ); - // clean the new manager - Ivy_ManForEachObj( p->pManFraig, pObj, i ) - { - if ( Ivy_ObjFaninVec(pObj) ) - Vec_PtrFree( Ivy_ObjFaninVec(pObj) ); - pObj->pNextFan0 = pObj->pNextFan1 = NULL; - } - // remove dangling nodes - Ivy_ManCleanup( p->pManFraig ); - pManAigNew = p->pManFraig; -p->timeTotal = clock() - clk; - -//printf( "Final nodes = %6d. ", Ivy_ManNodeNum(pManAigNew) ); -//PRT( "Time", p->timeTotal ); - Ivy_FraigStop( p ); - return pManAigNew; -} - -/**Function************************************************************* - - Synopsis [Starts the fraiging manager without simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_FraigMan_t * Ivy_FraigStartSimple( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams ) -{ - Ivy_FraigMan_t * p; - // allocat the fraiging manager - p = ALLOC( Ivy_FraigMan_t, 1 ); - memset( p, 0, sizeof(Ivy_FraigMan_t) ); - p->pParams = pParams; - p->pManAig = pManAig; - p->pManFraig = Ivy_ManStartFrom( pManAig ); - p->vPiVars = Vec_PtrAlloc( 100 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Starts the fraiging manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_FraigMan_t * Ivy_FraigStart( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams ) -{ - Ivy_FraigMan_t * p; - Ivy_FraigSim_t * pSims; - Ivy_Obj_t * pObj; - int i, k, EntrySize; - // clean the fanout representation - Ivy_ManForEachObj( pManAig, pObj, i ) -// pObj->pEquiv = pObj->pFanout = pObj->pNextFan0 = pObj->pNextFan1 = pObj->pPrevFan0 = pObj->pPrevFan1 = NULL; - assert( !pObj->pEquiv && !pObj->pFanout ); - // allocat the fraiging manager - p = ALLOC( Ivy_FraigMan_t, 1 ); - memset( p, 0, sizeof(Ivy_FraigMan_t) ); - p->pParams = pParams; - p->pManAig = pManAig; - p->pManFraig = Ivy_ManStartFrom( pManAig ); - // allocate simulation info - p->nSimWords = pParams->nSimWords; -// p->pSimWords = ALLOC( unsigned, Ivy_ManObjNum(pManAig) * p->nSimWords ); - EntrySize = sizeof(Ivy_FraigSim_t) + sizeof(unsigned) * p->nSimWords; - p->pSimWords = (char *)malloc( Ivy_ManObjNum(pManAig) * EntrySize ); - memset( p->pSimWords, 0, EntrySize ); - k = 0; - Ivy_ManForEachObj( pManAig, pObj, i ) - { - pSims = (Ivy_FraigSim_t *)(p->pSimWords + EntrySize * k++); - pSims->pNext = NULL; - if ( Ivy_ObjIsNode(pObj) ) - { - if ( p->pSimStart == NULL ) - p->pSimStart = pSims; - else - ((Ivy_FraigSim_t *)(p->pSimWords + EntrySize * (k-2)))->pNext = pSims; - pSims->pFanin0 = Ivy_ObjSim( Ivy_ObjFanin0(pObj) ); - pSims->pFanin1 = Ivy_ObjSim( Ivy_ObjFanin1(pObj) ); - pSims->Type = (Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)) << 2) | (Ivy_ObjFaninPhase(Ivy_ObjChild1(pObj)) << 1) | pObj->fPhase; - } - else - { - pSims->pFanin0 = NULL; - pSims->pFanin1 = NULL; - pSims->Type = 0; - } - Ivy_ObjSetSim( pObj, pSims ); - } - assert( k == Ivy_ManObjNum(pManAig) ); - // allocate storage for sim pattern - p->nPatWords = Ivy_BitWordNum( Ivy_ManPiNum(pManAig) ); - p->pPatWords = ALLOC( unsigned, p->nPatWords ); - p->pPatScores = ALLOC( int, 32 * p->nSimWords ); - p->vPiVars = Vec_PtrAlloc( 100 ); - // set random number generator - srand( 0xABCABC ); - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the fraiging manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigStop( Ivy_FraigMan_t * p ) -{ - if ( p->pParams->fVerbose ) - Ivy_FraigPrint( p ); - if ( p->vPiVars ) Vec_PtrFree( p->vPiVars ); - if ( p->pSat ) sat_solver_delete( p->pSat ); - FREE( p->pPatScores ); - FREE( p->pPatWords ); - FREE( p->pSimWords ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Prints stats for the fraiging manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigPrint( Ivy_FraigMan_t * p ) -{ - double nMemory; - nMemory = (double)Ivy_ManObjNum(p->pManAig)*p->nSimWords*sizeof(unsigned)/(1<<20); - printf( "SimWords = %d. Rounds = %d. Mem = %0.2f Mb. ", p->nSimWords, p->nSimRounds, nMemory ); - printf( "Classes: Beg = %d. End = %d.\n", p->nClassesBeg, p->nClassesEnd ); -// printf( "Limits: BTNode = %d. BTMiter = %d.\n", p->pParams->nBTLimitNode, p->pParams->nBTLimitMiter ); - printf( "Proof = %d. Counter-example = %d. Fail = %d. FailReal = %d. Zero = %d.\n", - p->nSatProof, p->nSatCallsSat, p->nSatFails, p->nSatFailsReal, p->nClassesZero ); - printf( "Final = %d. Miter = %d. Total = %d. Mux = %d. (Exor = %d.) SatVars = %d.\n", - Ivy_ManNodeNum(p->pManFraig), p->nNodesMiter, Ivy_ManNodeNum(p->pManAig), 0, 0, p->nSatVars ); - if ( p->pSat ) Sat_SolverPrintStats( stdout, p->pSat ); - PRT( "AIG simulation ", p->timeSim ); - PRT( "AIG traversal ", p->timeTrav ); - PRT( "SAT solving ", p->timeSat ); - PRT( " Unsat ", p->timeSatUnsat ); - PRT( " Sat ", p->timeSatSat ); - PRT( " Fail ", p->timeSatFail ); - PRT( "Class refining ", p->timeRef ); - PRT( "TOTAL RUNTIME ", p->timeTotal ); - if ( p->time1 ) { PRT( "time1 ", p->time1 ); } -} - - - -/**Function************************************************************* - - Synopsis [Assigns random patterns to the PI node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeAssignRandom( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_FraigSim_t * pSims; - int i; - assert( Ivy_ObjIsPi(pObj) ); - pSims = Ivy_ObjSim(pObj); - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = Ivy_ObjRandomSim(); -} - -/**Function************************************************************* - - Synopsis [Assigns constant patterns to the PI node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeAssignConst( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj, int fConst1 ) -{ - Ivy_FraigSim_t * pSims; - int i; - assert( Ivy_ObjIsPi(pObj) ); - pSims = Ivy_ObjSim(pObj); - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = fConst1? ~(unsigned)0 : 0; -} - -/**Function************************************************************* - - Synopsis [Assings random simulation info for the PIs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigAssignRandom( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - Ivy_ManForEachPi( p->pManAig, pObj, i ) - Ivy_NodeAssignRandom( p, pObj ); -} - -/**Function************************************************************* - - Synopsis [Assings distance-1 simulation info for the PIs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigAssignDist1( Ivy_FraigMan_t * p, unsigned * pPat ) -{ - Ivy_Obj_t * pObj; - int i, Limit; - Ivy_ManForEachPi( p->pManAig, pObj, i ) - { - Ivy_NodeAssignConst( p, pObj, Ivy_InfoHasBit(pPat, i) ); -// printf( "%d", Ivy_InfoHasBit(pPat, i) ); - } -// printf( "\n" ); - - Limit = IVY_MIN( Ivy_ManPiNum(p->pManAig), p->nSimWords * 32 - 1 ); - for ( i = 0; i < Limit; i++ ) - Ivy_InfoXorBit( Ivy_ObjSim( Ivy_ManPi(p->pManAig,i) )->pData, i+1 ); -} - -/**Function************************************************************* - - Synopsis [Returns 1 if simulation info is composed of all zeros.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeHasZeroSim( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_FraigSim_t * pSims; - int i; - pSims = Ivy_ObjSim(pObj); - for ( i = 0; i < p->nSimWords; i++ ) - if ( pSims->pData[i] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if simulation info is composed of all zeros.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeComplementSim( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_FraigSim_t * pSims; - int i; - pSims = Ivy_ObjSim(pObj); - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = ~pSims->pData[i]; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if simulation infos are equal.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeCompareSims( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 ) -{ - Ivy_FraigSim_t * pSims0, * pSims1; - int i; - pSims0 = Ivy_ObjSim(pObj0); - pSims1 = Ivy_ObjSim(pObj1); - for ( i = 0; i < p->nSimWords; i++ ) - if ( pSims0->pData[i] != pSims1->pData[i] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Simulates one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeSimulateSim( Ivy_FraigMan_t * p, Ivy_FraigSim_t * pSims ) -{ - unsigned * pData, * pData0, * pData1; - int i; - pData = pSims->pData; - pData0 = pSims->pFanin0->pData; - pData1 = pSims->pFanin1->pData; - switch( pSims->Type ) - { - case 0: - for ( i = 0; i < p->nSimWords; i++ ) - pData[i] = (pData0[i] & pData1[i]); - break; - case 1: - for ( i = 0; i < p->nSimWords; i++ ) - pData[i] = ~(pData0[i] & pData1[i]); - break; - case 2: - for ( i = 0; i < p->nSimWords; i++ ) - pData[i] = (pData0[i] & ~pData1[i]); - break; - case 3: - for ( i = 0; i < p->nSimWords; i++ ) - pData[i] = (~pData0[i] | pData1[i]); - break; - case 4: - for ( i = 0; i < p->nSimWords; i++ ) - pData[i] = (~pData0[i] & pData1[i]); - break; - case 5: - for ( i = 0; i < p->nSimWords; i++ ) - pData[i] = (pData0[i] | ~pData1[i]); - break; - case 6: - for ( i = 0; i < p->nSimWords; i++ ) - pData[i] = ~(pData0[i] | pData1[i]); - break; - case 7: - for ( i = 0; i < p->nSimWords; i++ ) - pData[i] = (pData0[i] | pData1[i]); - break; - } -} - -/**Function************************************************************* - - Synopsis [Simulates one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeSimulate( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_FraigSim_t * pSims, * pSims0, * pSims1; - int fCompl, fCompl0, fCompl1, i; - assert( !Ivy_IsComplement(pObj) ); - // get hold of the simulation information - pSims = Ivy_ObjSim(pObj); - pSims0 = Ivy_ObjSim(Ivy_ObjFanin0(pObj)); - pSims1 = Ivy_ObjSim(Ivy_ObjFanin1(pObj)); - // get complemented attributes of the children using their random info - fCompl = pObj->fPhase; - fCompl0 = Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)); - fCompl1 = Ivy_ObjFaninPhase(Ivy_ObjChild1(pObj)); - // simulate - if ( fCompl0 && fCompl1 ) - { - if ( fCompl ) - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = (pSims0->pData[i] | pSims1->pData[i]); - else - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = ~(pSims0->pData[i] | pSims1->pData[i]); - } - else if ( fCompl0 && !fCompl1 ) - { - if ( fCompl ) - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = (pSims0->pData[i] | ~pSims1->pData[i]); - else - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = (~pSims0->pData[i] & pSims1->pData[i]); - } - else if ( !fCompl0 && fCompl1 ) - { - if ( fCompl ) - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = (~pSims0->pData[i] | pSims1->pData[i]); - else - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = (pSims0->pData[i] & ~pSims1->pData[i]); - } - else // if ( !fCompl0 && !fCompl1 ) - { - if ( fCompl ) - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = ~(pSims0->pData[i] & pSims1->pData[i]); - else - for ( i = 0; i < p->nSimWords; i++ ) - pSims->pData[i] = (pSims0->pData[i] & pSims1->pData[i]); - } -} - -/**Function************************************************************* - - Synopsis [Computes hash value using simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Ivy_NodeHash( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj ) -{ - static int s_FPrimes[128] = { - 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, - 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997, - 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543, - 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089, - 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671, - 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243, - 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871, - 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471, - 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073, - 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689, - 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309, - 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933, - 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147 - }; - Ivy_FraigSim_t * pSims; - unsigned uHash; - int i; - assert( p->nSimWords <= 128 ); - uHash = 0; - pSims = Ivy_ObjSim(pObj); - for ( i = 0; i < p->nSimWords; i++ ) - uHash ^= pSims->pData[i] * s_FPrimes[i]; - return uHash; -} - -/**Function************************************************************* - - Synopsis [Simulates AIG manager.] - - Description [Assumes that the PI simulation info is attached.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSimulateOne( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pObj; - int i, clk; -clk = clock(); - Ivy_ManForEachNode( p->pManAig, pObj, i ) - { - Ivy_NodeSimulate( p, pObj ); -/* - if ( Ivy_ObjFraig(pObj) == NULL ) - printf( "%3d --- -- %d : ", pObj->Id, pObj->fPhase ); - else - printf( "%3d %3d %2d %d : ", pObj->Id, Ivy_Regular(Ivy_ObjFraig(pObj))->Id, Ivy_ObjSatNum(Ivy_Regular(Ivy_ObjFraig(pObj))), pObj->fPhase ); - Extra_PrintBinary( stdout, Ivy_ObjSim(pObj), 30 ); - printf( "\n" ); -*/ - } -p->timeSim += clock() - clk; -p->nSimRounds++; -} - -/**Function************************************************************* - - Synopsis [Simulates AIG manager.] - - Description [Assumes that the PI simulation info is attached.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSimulateOneSim( Ivy_FraigMan_t * p ) -{ - Ivy_FraigSim_t * pSims; - int clk; -clk = clock(); - for ( pSims = p->pSimStart; pSims; pSims = pSims->pNext ) - Ivy_NodeSimulateSim( p, pSims ); -p->timeSim += clock() - clk; -p->nSimRounds++; -} - -/**Function************************************************************* - - Synopsis [Adds one node to the equivalence class.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_NodeAddToClass( Ivy_Obj_t * pClass, Ivy_Obj_t * pObj ) -{ - if ( Ivy_ObjClassNodeNext(pClass) == NULL ) - Ivy_ObjSetClassNodeNext( pClass, pObj ); - else - Ivy_ObjSetClassNodeNext( Ivy_ObjClassNodeLast(pClass), pObj ); - Ivy_ObjSetClassNodeLast( pClass, pObj ); - Ivy_ObjSetClassNodeRepr( pObj, pClass ); - Ivy_ObjSetClassNodeNext( pObj, NULL ); -} - -/**Function************************************************************* - - Synopsis [Adds equivalence class to the list of classes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigAddClass( Ivy_FraigList_t * pList, Ivy_Obj_t * pClass ) -{ - if ( pList->pHead == NULL ) - { - pList->pHead = pClass; - pList->pTail = pClass; - Ivy_ObjSetEquivListPrev( pClass, NULL ); - Ivy_ObjSetEquivListNext( pClass, NULL ); - } - else - { - Ivy_ObjSetEquivListNext( pList->pTail, pClass ); - Ivy_ObjSetEquivListPrev( pClass, pList->pTail ); - Ivy_ObjSetEquivListNext( pClass, NULL ); - pList->pTail = pClass; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [Updates the list of classes after base class has split.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigInsertClass( Ivy_FraigList_t * pList, Ivy_Obj_t * pBase, Ivy_Obj_t * pClass ) -{ - Ivy_ObjSetEquivListPrev( pClass, pBase ); - Ivy_ObjSetEquivListNext( pClass, Ivy_ObjEquivListNext(pBase) ); - if ( Ivy_ObjEquivListNext(pBase) ) - Ivy_ObjSetEquivListPrev( Ivy_ObjEquivListNext(pBase), pClass ); - Ivy_ObjSetEquivListNext( pBase, pClass ); - if ( pList->pTail == pBase ) - pList->pTail = pClass; - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [Removes equivalence class from the list of classes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigRemoveClass( Ivy_FraigList_t * pList, Ivy_Obj_t * pClass ) -{ - if ( pList->pHead == pClass ) - pList->pHead = Ivy_ObjEquivListNext(pClass); - if ( pList->pTail == pClass ) - pList->pTail = Ivy_ObjEquivListPrev(pClass); - if ( Ivy_ObjEquivListPrev(pClass) ) - Ivy_ObjSetEquivListNext( Ivy_ObjEquivListPrev(pClass), Ivy_ObjEquivListNext(pClass) ); - if ( Ivy_ObjEquivListNext(pClass) ) - Ivy_ObjSetEquivListPrev( Ivy_ObjEquivListNext(pClass), Ivy_ObjEquivListPrev(pClass) ); - Ivy_ObjSetEquivListNext( pClass, NULL ); - Ivy_ObjSetEquivListPrev( pClass, NULL ); - pClass->fMarkA = 0; - pList->nItems--; -} - -/**Function************************************************************* - - Synopsis [Count the number of pairs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigCountPairsClasses( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pClass, * pNode; - int nPairs = 0, nNodes; - return nPairs; - - Ivy_FraigForEachEquivClass( p->lClasses.pHead, pClass ) - { - nNodes = 0; - Ivy_FraigForEachClassNode( pClass, pNode ) - nNodes++; - nPairs += nNodes * (nNodes - 1) / 2; - } - return nPairs; -} - -/**Function************************************************************* - - Synopsis [Creates initial simulation classes.] - - Description [Assumes that simulation info is assigned.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigCreateClasses( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t ** pTable; - Ivy_Obj_t * pObj, * pConst1, * pBin, * pEntry; - int i, nTableSize; - unsigned Hash; - pConst1 = Ivy_ManConst1(p->pManAig); - // allocate the table - nTableSize = Ivy_ManObjNum(p->pManAig) / 2 + 13; - pTable = ALLOC( Ivy_Obj_t *, nTableSize ); - memset( pTable, 0, sizeof(Ivy_Obj_t *) * nTableSize ); - // collect nodes into the table - Ivy_ManForEachObj( p->pManAig, pObj, i ) - { - if ( !Ivy_ObjIsPi(pObj) && !Ivy_ObjIsNode(pObj) ) - continue; - Hash = Ivy_NodeHash( p, pObj ); - if ( Hash == 0 && Ivy_NodeHasZeroSim( p, pObj ) ) - { - Ivy_NodeAddToClass( pConst1, pObj ); - continue; - } - // add the node to the table - pBin = pTable[Hash % nTableSize]; - Ivy_FraigForEachBinNode( pBin, pEntry ) - if ( Ivy_NodeCompareSims( p, pEntry, pObj ) ) - { - Ivy_NodeAddToClass( pEntry, pObj ); - break; - } - // check if the entry was added - if ( pEntry ) - continue; - Ivy_ObjSetNodeHashNext( pObj, pBin ); - pTable[Hash % nTableSize] = pObj; - } - // collect non-trivial classes - assert( p->lClasses.pHead == NULL ); - Ivy_ManForEachObj( p->pManAig, pObj, i ) - { - if ( !Ivy_ObjIsConst1(pObj) && !Ivy_ObjIsPi(pObj) && !Ivy_ObjIsNode(pObj) ) - continue; - Ivy_ObjSetNodeHashNext( pObj, NULL ); - if ( Ivy_ObjClassNodeRepr(pObj) == NULL ) - { - assert( Ivy_ObjClassNodeNext(pObj) == NULL ); - continue; - } - // recognize the head of the class - if ( Ivy_ObjClassNodeNext( Ivy_ObjClassNodeRepr(pObj) ) != NULL ) - continue; - // clean the class representative and add it to the list - Ivy_ObjSetClassNodeRepr( pObj, NULL ); - Ivy_FraigAddClass( &p->lClasses, pObj ); - } - // free the table - free( pTable ); -} - -/**Function************************************************************* - - Synopsis [Recursively refines the class after simulation.] - - Description [Returns 1 if the class has changed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigRefineClass_rec( Ivy_FraigMan_t * p, Ivy_Obj_t * pClass ) -{ - Ivy_Obj_t * pClassNew, * pListOld, * pListNew, * pNode; - int RetValue = 0; - // check if there is refinement - pListOld = pClass; - Ivy_FraigForEachClassNode( Ivy_ObjClassNodeNext(pClass), pClassNew ) - { - if ( !Ivy_NodeCompareSims(p, pClass, pClassNew) ) - { - if ( p->pParams->fPatScores ) - Ivy_FraigAddToPatScores( p, pClass, pClassNew ); - break; - } - pListOld = pClassNew; - } - if ( pClassNew == NULL ) - return 0; - // set representative of the new class - Ivy_ObjSetClassNodeRepr( pClassNew, NULL ); - // start the new list - pListNew = pClassNew; - // go through the remaining nodes and sort them into two groups: - // (1) matches of the old node; (2) non-matches of the old node - Ivy_FraigForEachClassNode( Ivy_ObjClassNodeNext(pClassNew), pNode ) - if ( Ivy_NodeCompareSims( p, pClass, pNode ) ) - { - Ivy_ObjSetClassNodeNext( pListOld, pNode ); - pListOld = pNode; - } - else - { - Ivy_ObjSetClassNodeNext( pListNew, pNode ); - Ivy_ObjSetClassNodeRepr( pNode, pClassNew ); - pListNew = pNode; - } - // finish both lists - Ivy_ObjSetClassNodeNext( pListNew, NULL ); - Ivy_ObjSetClassNodeNext( pListOld, NULL ); - // update the list of classes - Ivy_FraigInsertClass( &p->lClasses, pClass, pClassNew ); - // if the old class is trivial, remove it - if ( Ivy_ObjClassNodeNext(pClass) == NULL ) - Ivy_FraigRemoveClass( &p->lClasses, pClass ); - // if the new class is trivial, remove it; otherwise, try to refine it - if ( Ivy_ObjClassNodeNext(pClassNew) == NULL ) - Ivy_FraigRemoveClass( &p->lClasses, pClassNew ); - else - RetValue = Ivy_FraigRefineClass_rec( p, pClassNew ); - return RetValue + 1; -} - -/**Function************************************************************* - - Synopsis [Creates the counter-example from the successful pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigCheckOutputSimsSavePattern( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_FraigSim_t * pSims; - int i, k, BestPat, * pModel; - // find the word of the pattern - pSims = Ivy_ObjSim(pObj); - for ( i = 0; i < p->nSimWords; i++ ) - if ( pSims->pData[i] ) - break; - assert( i < p->nSimWords ); - // find the bit of the pattern - for ( k = 0; k < 32; k++ ) - if ( pSims->pData[i] & (1 << k) ) - break; - assert( k < 32 ); - // determine the best pattern - BestPat = i * 32 + k; - // fill in the counter-example data - pModel = ALLOC( int, Ivy_ManPiNum(p->pManFraig) ); - Ivy_ManForEachPi( p->pManAig, pObj, i ) - { - pModel[i] = Ivy_InfoHasBit(Ivy_ObjSim(pObj)->pData, BestPat); -// printf( "%d", pModel[i] ); - } -// printf( "\n" ); - // set the model - assert( p->pManFraig->pData == NULL ); - p->pManFraig->pData = pModel; - return; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the one of the output is already non-constant 0.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigCheckOutputSims( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - // make sure the reference simulation pattern does not detect the bug - pObj = Ivy_ManPo( p->pManAig, 0 ); - assert( Ivy_ObjFanin0(pObj)->fPhase == (unsigned)Ivy_ObjFaninC0(pObj) ); // Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)) == 0 - Ivy_ManForEachPo( p->pManAig, pObj, i ) - { - // complement simulation info -// if ( Ivy_ObjFanin0(pObj)->fPhase ^ Ivy_ObjFaninC0(pObj) ) // Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)) -// Ivy_NodeComplementSim( p, Ivy_ObjFanin0(pObj) ); - // check - if ( !Ivy_NodeHasZeroSim( p, Ivy_ObjFanin0(pObj) ) ) - { - // create the counter-example from this pattern - Ivy_FraigCheckOutputSimsSavePattern( p, Ivy_ObjFanin0(pObj) ); - return 1; - } - // complement simulation info -// if ( Ivy_ObjFanin0(pObj)->fPhase ^ Ivy_ObjFaninC0(pObj) ) -// Ivy_NodeComplementSim( p, Ivy_ObjFanin0(pObj) ); - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Refines the classes after simulation.] - - Description [Assumes that simulation info is assigned. Returns the - number of classes refined.] - - SideEffects [Large equivalence class of constant 0 may cause problems.] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigRefineClasses( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pClass, * pClass2; - int clk, RetValue, Counter = 0; - // check if some outputs already became non-constant - // this is a special case when computation can be stopped!!! - if ( p->pParams->fProve ) - Ivy_FraigCheckOutputSims( p ); - if ( p->pManFraig->pData ) - return 0; - // refine the classed -clk = clock(); - Ivy_FraigForEachEquivClassSafe( p->lClasses.pHead, pClass, pClass2 ) - { - if ( pClass->fMarkA ) - continue; - RetValue = Ivy_FraigRefineClass_rec( p, pClass ); - Counter += ( RetValue > 0 ); -//if ( Ivy_ObjIsConst1(pClass) ) -//printf( "%d ", RetValue ); -//if ( Ivy_ObjIsConst1(pClass) ) -// p->time1 += clock() - clk; - } -p->timeRef += clock() - clk; - return Counter; -} - -/**Function************************************************************* - - Synopsis [Print the class.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigPrintClass( Ivy_Obj_t * pClass ) -{ - Ivy_Obj_t * pObj; - printf( "Class {" ); - Ivy_FraigForEachClassNode( pClass, pObj ) - printf( " %d(%d)%c", pObj->Id, pObj->Level, pObj->fPhase? '+' : '-' ); - printf( " }\n" ); -} - -/**Function************************************************************* - - Synopsis [Count the number of elements in the class.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigCountClassNodes( Ivy_Obj_t * pClass ) -{ - Ivy_Obj_t * pObj; - int Counter = 0; - Ivy_FraigForEachClassNode( pClass, pObj ) - Counter++; - return Counter; -} - -/**Function************************************************************* - - Synopsis [Prints simulation classes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigPrintSimClasses( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pClass; - Ivy_FraigForEachEquivClass( p->lClasses.pHead, pClass ) - { -// Ivy_FraigPrintClass( pClass ); - printf( "%d ", Ivy_FraigCountClassNodes( pClass ) ); - } -// printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Generated const 0 pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSavePattern0( Ivy_FraigMan_t * p ) -{ - memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); -} - -/**Function************************************************************* - - Synopsis [[Generated const 1 pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSavePattern1( Ivy_FraigMan_t * p ) -{ - memset( p->pPatWords, 0xff, sizeof(unsigned) * p->nPatWords ); -} - -/**Function************************************************************* - - Synopsis [Generates the counter-example satisfying the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int * Ivy_FraigCreateModel( Ivy_FraigMan_t * p ) -{ - int * pModel; - Ivy_Obj_t * pObj; - int i; - pModel = ALLOC( int, Ivy_ManPiNum(p->pManFraig) ); - Ivy_ManForEachPi( p->pManFraig, pObj, i ) - pModel[i] = ( p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True ); - return pModel; -} - -/**Function************************************************************* - - Synopsis [Copy pattern from the solver into the internal storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSavePattern( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); - Ivy_ManForEachPi( p->pManFraig, pObj, i ) -// Vec_PtrForEachEntry( p->vPiVars, pObj, i ) - if ( p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True ) - Ivy_InfoSetBit( p->pPatWords, i ); -// Ivy_InfoSetBit( p->pPatWords, pObj->Id - 1 ); -} - -/**Function************************************************************* - - Synopsis [Copy pattern from the solver into the internal storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSavePattern2( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); -// Ivy_ManForEachPi( p->pManFraig, pObj, i ) - Vec_PtrForEachEntry( p->vPiVars, pObj, i ) - if ( p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True ) -// Ivy_InfoSetBit( p->pPatWords, i ); - Ivy_InfoSetBit( p->pPatWords, pObj->Id - 1 ); -} - -/**Function************************************************************* - - Synopsis [Copy pattern from the solver into the internal storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSavePattern3( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - for ( i = 0; i < p->nPatWords; i++ ) - p->pPatWords[i] = Ivy_ObjRandomSim(); - Vec_PtrForEachEntry( p->vPiVars, pObj, i ) - if ( Ivy_InfoHasBit( p->pPatWords, pObj->Id - 1 ) ^ (p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True) ) - Ivy_InfoXorBit( p->pPatWords, pObj->Id - 1 ); -} - - -/**Function************************************************************* - - Synopsis [Performs simulation of the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSimulate( Ivy_FraigMan_t * p ) -{ - int nChanges, nClasses; - // start the classes - Ivy_FraigAssignRandom( p ); - Ivy_FraigSimulateOne( p ); - Ivy_FraigCreateClasses( p ); -//printf( "Starting classes = %5d. Pairs = %6d.\n", p->lClasses.nItems, Ivy_FraigCountPairsClasses(p) ); - // refine classes by walking 0/1 patterns - Ivy_FraigSavePattern0( p ); - Ivy_FraigAssignDist1( p, p->pPatWords ); - Ivy_FraigSimulateOne( p ); - nChanges = Ivy_FraigRefineClasses( p ); - if ( p->pManFraig->pData ) - return; -//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) ); - Ivy_FraigSavePattern1( p ); - Ivy_FraigAssignDist1( p, p->pPatWords ); - Ivy_FraigSimulateOne( p ); - nChanges = Ivy_FraigRefineClasses( p ); - if ( p->pManFraig->pData ) - return; -//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) ); - // refine classes by random simulation - do { - Ivy_FraigAssignRandom( p ); - Ivy_FraigSimulateOne( p ); - nClasses = p->lClasses.nItems; - nChanges = Ivy_FraigRefineClasses( p ); - if ( p->pManFraig->pData ) - return; -//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) ); - } while ( (double)nChanges / nClasses > p->pParams->dSimSatur ); -// Ivy_FraigPrintSimClasses( p ); -} - - - -/**Function************************************************************* - - Synopsis [Cleans pattern scores.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigCleanPatScores( Ivy_FraigMan_t * p ) -{ - int i, nLimit = p->nSimWords * 32; - for ( i = 0; i < nLimit; i++ ) - p->pPatScores[i] = 0; -} - -/**Function************************************************************* - - Synopsis [Adds to pattern scores.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigAddToPatScores( Ivy_FraigMan_t * p, Ivy_Obj_t * pClass, Ivy_Obj_t * pClassNew ) -{ - Ivy_FraigSim_t * pSims0, * pSims1; - unsigned uDiff; - int i, w; - // get hold of the simulation information - pSims0 = Ivy_ObjSim(pClass); - pSims1 = Ivy_ObjSim(pClassNew); - // iterate through the differences and record the score - for ( w = 0; w < p->nSimWords; w++ ) - { - uDiff = pSims0->pData[w] ^ pSims1->pData[w]; - if ( uDiff == 0 ) - continue; - for ( i = 0; i < 32; i++ ) - if ( uDiff & ( 1 << i ) ) - p->pPatScores[w*32+i]++; - } -} - -/**Function************************************************************* - - Synopsis [Selects the best pattern.] - - Description [Returns 1 if such pattern is found.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigSelectBestPat( Ivy_FraigMan_t * p ) -{ - Ivy_FraigSim_t * pSims; - Ivy_Obj_t * pObj; - int i, nLimit = p->nSimWords * 32, MaxScore = 0, BestPat = -1; - for ( i = 1; i < nLimit; i++ ) - { - if ( MaxScore < p->pPatScores[i] ) - { - MaxScore = p->pPatScores[i]; - BestPat = i; - } - } - if ( MaxScore == 0 ) - return 0; -// if ( MaxScore > p->pParams->MaxScore ) -// printf( "Max score is %3d. ", MaxScore ); - // copy the best pattern into the selected pattern - memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); - Ivy_ManForEachPi( p->pManAig, pObj, i ) - { - pSims = Ivy_ObjSim(pObj); - if ( Ivy_InfoHasBit(pSims->pData, BestPat) ) - Ivy_InfoSetBit(p->pPatWords, i); - } - return MaxScore; -} - -/**Function************************************************************* - - Synopsis [Resimulates fraiging manager after finding a counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigResimulate( Ivy_FraigMan_t * p ) -{ - int nChanges; - Ivy_FraigAssignDist1( p, p->pPatWords ); - Ivy_FraigSimulateOne( p ); - if ( p->pParams->fPatScores ) - Ivy_FraigCleanPatScores( p ); - nChanges = Ivy_FraigRefineClasses( p ); - if ( p->pManFraig->pData ) - return; - if ( nChanges < 1 ) - printf( "Error: A counter-example did not refine classes!\n" ); - assert( nChanges >= 1 ); -//printf( "Refined classes! = %5d. Changes = %4d.\n", p->lClasses.nItems, nChanges ); - if ( !p->pParams->fPatScores ) - return; - - // perform additional simulation using dist1 patterns derived from successful patterns - while ( Ivy_FraigSelectBestPat(p) > p->pParams->MaxScore ) - { - Ivy_FraigAssignDist1( p, p->pPatWords ); - Ivy_FraigSimulateOne( p ); - Ivy_FraigCleanPatScores( p ); - nChanges = Ivy_FraigRefineClasses( p ); - if ( p->pManFraig->pData ) - return; -//printf( "Refined class!!! = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) ); - if ( nChanges == 0 ) - break; - } -} - - -/**Function************************************************************* - - Synopsis [Prints the status of the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigMiterPrint( Ivy_Man_t * pNtk, char * pString, int clk, int fVerbose ) -{ - if ( !fVerbose ) - return; - printf( "Nodes = %7d. Levels = %4d. ", Ivy_ManNodeNum(pNtk), Ivy_ManLevels(pNtk) ); - PRT( pString, clock() - clk ); -} - -/**Function************************************************************* - - Synopsis [Reports the status of the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigMiterStatus( Ivy_Man_t * pMan ) -{ - Ivy_Obj_t * pObj, * pObjNew; - int i, CountConst0 = 0, CountNonConst0 = 0, CountUndecided = 0; - if ( pMan->pData ) - return 0; - Ivy_ManForEachPo( pMan, pObj, i ) - { - pObjNew = Ivy_ObjChild0(pObj); - // check if the output is constant 1 - if ( pObjNew == pMan->pConst1 ) - { - CountNonConst0++; - continue; - } - // check if the output is constant 0 - if ( pObjNew == Ivy_Not(pMan->pConst1) ) - { - CountConst0++; - continue; - } - // check if the output can be constant 0 - if ( Ivy_Regular(pObjNew)->fPhase != (unsigned)Ivy_IsComplement(pObjNew) ) - { - CountNonConst0++; - continue; - } - CountUndecided++; - } -/* - if ( p->pParams->fVerbose ) - { - printf( "Miter has %d outputs. ", Ivy_ManPoNum(p->pManAig) ); - printf( "Const0 = %d. ", CountConst0 ); - printf( "NonConst0 = %d. ", CountNonConst0 ); - printf( "Undecided = %d. ", CountUndecided ); - printf( "\n" ); - } -*/ - if ( CountNonConst0 ) - return 0; - if ( CountUndecided ) - return -1; - return 1; -} - -/**Function************************************************************* - - Synopsis [Tries to prove each output of the miter until encountering a sat output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigMiterProve( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pObj, * pObjNew; - int i, RetValue, clk = clock(); - int fVerbose = 0; - Ivy_ManForEachPo( p->pManAig, pObj, i ) - { - if ( i && fVerbose ) - { - PRT( "Time", clock() -clk ); - } - pObjNew = Ivy_ObjChild0Equiv(pObj); - // check if the output is constant 1 - if ( pObjNew == p->pManFraig->pConst1 ) - { - if ( fVerbose ) - printf( "Output %2d (out of %2d) is constant 1. ", i, Ivy_ManPoNum(p->pManAig) ); - // assing constant 0 model - p->pManFraig->pData = ALLOC( int, Ivy_ManPiNum(p->pManFraig) ); - memset( p->pManFraig->pData, 0, sizeof(int) * Ivy_ManPiNum(p->pManFraig) ); - break; - } - // check if the output is constant 0 - if ( pObjNew == Ivy_Not(p->pManFraig->pConst1) ) - { - if ( fVerbose ) - printf( "Output %2d (out of %2d) is already constant 0. ", i, Ivy_ManPoNum(p->pManAig) ); - continue; - } - // check if the output can be constant 0 - if ( Ivy_Regular(pObjNew)->fPhase != (unsigned)Ivy_IsComplement(pObjNew) ) - { - if ( fVerbose ) - printf( "Output %2d (out of %2d) cannot be constant 0. ", i, Ivy_ManPoNum(p->pManAig) ); - // assing constant 0 model - p->pManFraig->pData = ALLOC( int, Ivy_ManPiNum(p->pManFraig) ); - memset( p->pManFraig->pData, 0, sizeof(int) * Ivy_ManPiNum(p->pManFraig) ); - break; - } -/* - // check the representative of this node - pRepr = Ivy_ObjClassNodeRepr(Ivy_ObjFanin0(pObj)); - if ( Ivy_Regular(pRepr) != p->pManAig->pConst1 ) - printf( "Representative is not constant 1.\n" ); - else - printf( "Representative is constant 1.\n" ); -*/ - // try to prove the output constant 0 - RetValue = Ivy_FraigNodeIsConst( p, Ivy_Regular(pObjNew) ); - if ( RetValue == 1 ) // proved equivalent - { - if ( fVerbose ) - printf( "Output %2d (out of %2d) was proved constant 0. ", i, Ivy_ManPoNum(p->pManAig) ); - // set the constant miter - Ivy_ObjFanin0(pObj)->pEquiv = Ivy_NotCond( p->pManFraig->pConst1, !Ivy_ObjFaninC0(pObj) ); - continue; - } - if ( RetValue == -1 ) // failed - { - if ( fVerbose ) - printf( "Output %2d (out of %2d) has timed out at %d backtracks. ", i, Ivy_ManPoNum(p->pManAig), p->pParams->nBTLimitMiter ); - continue; - } - // proved satisfiable - if ( fVerbose ) - printf( "Output %2d (out of %2d) was proved NOT a constant 0. ", i, Ivy_ManPoNum(p->pManAig) ); - // create the model - p->pManFraig->pData = Ivy_FraigCreateModel(p); - break; - } - if ( fVerbose ) - { - PRT( "Time", clock() -clk ); - } -} - -/**Function************************************************************* - - Synopsis [Performs fraiging for the internal nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigSweep( Ivy_FraigMan_t * p ) -{ - Ivy_Obj_t * pObj;//, * pTemp; - int i, k = 0; -p->nClassesZero = p->lClasses.pHead? (Ivy_ObjIsConst1(p->lClasses.pHead) ? Ivy_FraigCountClassNodes(p->lClasses.pHead) : 0) : 0; -p->nClassesBeg = p->lClasses.nItems; - // duplicate internal nodes - p->pProgress = Extra_ProgressBarStart( stdout, Ivy_ManNodeNum(p->pManAig) ); - Ivy_ManForEachNode( p->pManAig, pObj, i ) - { - Extra_ProgressBarUpdate( p->pProgress, k++, NULL ); - // default to simple strashing if simulation detected a counter-example for a PO - if ( p->pManFraig->pData ) - pObj->pEquiv = Ivy_And( p->pManFraig, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) ); - else - pObj->pEquiv = Ivy_FraigAnd( p, pObj ); - assert( pObj->pEquiv != NULL ); -// pTemp = Ivy_Regular(pObj->pEquiv); -// assert( Ivy_Regular(pObj->pEquiv)->Type ); - } - Extra_ProgressBarStop( p->pProgress ); -p->nClassesEnd = p->lClasses.nItems; - // try to prove the outputs of the miter - p->nNodesMiter = Ivy_ManNodeNum(p->pManFraig); -// Ivy_FraigMiterStatus( p->pManFraig ); - if ( p->pParams->fProve && p->pManFraig->pData == NULL ) - Ivy_FraigMiterProve( p ); - // add the POs - Ivy_ManForEachPo( p->pManAig, pObj, i ) - Ivy_ObjCreatePo( p->pManFraig, Ivy_ObjChild0Equiv(pObj) ); - // clean the old manager - Ivy_ManForEachObj( p->pManAig, pObj, i ) - pObj->pFanout = pObj->pNextFan0 = pObj->pNextFan1 = pObj->pPrevFan0 = pObj->pPrevFan1 = NULL; - // clean the new manager - Ivy_ManForEachObj( p->pManFraig, pObj, i ) - { - if ( Ivy_ObjFaninVec(pObj) ) - Vec_PtrFree( Ivy_ObjFaninVec(pObj) ); - pObj->pNextFan0 = pObj->pNextFan1 = NULL; - } - // remove dangling nodes - Ivy_ManCleanup( p->pManFraig ); - // clean up the class marks - Ivy_FraigForEachEquivClass( p->lClasses.pHead, pObj ) - pObj->fMarkA = 0; -} - -/**Function************************************************************* - - Synopsis [Performs fraiging for one node.] - - Description [Returns the fraiged node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_FraigAnd( Ivy_FraigMan_t * p, Ivy_Obj_t * pObjOld ) -{ - Ivy_Obj_t * pObjNew, * pFanin0New, * pFanin1New, * pObjReprNew; - int RetValue; - // get the fraiged fanins - pFanin0New = Ivy_ObjChild0Equiv(pObjOld); - pFanin1New = Ivy_ObjChild1Equiv(pObjOld); - // get the candidate fraig node - pObjNew = Ivy_And( p->pManFraig, pFanin0New, pFanin1New ); - // get representative of this class - if ( Ivy_ObjClassNodeRepr(pObjOld) == NULL || // this is a unique node - (!p->pParams->fDoSparse && Ivy_ObjClassNodeRepr(pObjOld) == p->pManAig->pConst1) ) // this is a sparse node - { - assert( Ivy_Regular(pFanin0New) != Ivy_Regular(pFanin1New) ); - assert( pObjNew != Ivy_Regular(pFanin0New) ); - assert( pObjNew != Ivy_Regular(pFanin1New) ); - return pObjNew; - } - // get the fraiged representative - pObjReprNew = Ivy_ObjFraig(Ivy_ObjClassNodeRepr(pObjOld)); - // if the fraiged nodes are the same return - if ( Ivy_Regular(pObjNew) == Ivy_Regular(pObjReprNew) ) - return pObjNew; - assert( Ivy_Regular(pObjNew) != Ivy_ManConst1(p->pManFraig) ); -// printf( "Node = %d. Repr = %d.\n", pObjOld->Id, Ivy_ObjClassNodeRepr(pObjOld)->Id ); - - // they are different (the counter-example is in p->pPatWords) - RetValue = Ivy_FraigNodesAreEquiv( p, Ivy_Regular(pObjReprNew), Ivy_Regular(pObjNew) ); - if ( RetValue == 1 ) // proved equivalent - { - // mark the class as proved - if ( Ivy_ObjClassNodeNext(pObjOld) == NULL ) - Ivy_ObjClassNodeRepr(pObjOld)->fMarkA = 1; - return Ivy_NotCond( pObjReprNew, pObjOld->fPhase ^ Ivy_ObjClassNodeRepr(pObjOld)->fPhase ); - } - if ( RetValue == -1 ) // failed - return pObjNew; - // simulate the counter-example and return the new node - Ivy_FraigResimulate( p ); - return pObjNew; -} - -/**Function************************************************************* - - Synopsis [Prints variable activity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigPrintActivity( Ivy_FraigMan_t * p ) -{ - int i; - for ( i = 0; i < p->nSatVars; i++ ) - printf( "%d %.3f ", i, p->pSat->activity[i] ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Runs equivalence test for the two nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigNodesAreEquiv( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * pNew ) -{ - int pLits[4], RetValue, RetValue1, nBTLimit, clk, clk2 = clock(); - - // make sure the nodes are not complemented - assert( !Ivy_IsComplement(pNew) ); - assert( !Ivy_IsComplement(pOld) ); - assert( pNew != pOld ); - - // if at least one of the nodes is a failed node, perform adjustments: - // if the backtrack limit is small, simply skip this node - // if the backtrack limit is > 10, take the quare root of the limit - nBTLimit = p->pParams->nBTLimitNode; - if ( nBTLimit > 0 && (pOld->fFailTfo || pNew->fFailTfo) ) - { - p->nSatFails++; - // fail immediately -// return -1; - if ( nBTLimit <= 10 ) - return -1; - nBTLimit = (int)pow(nBTLimit, 0.7); - } - p->nSatCalls++; - - // make sure the solver is allocated and has enough variables - if ( p->pSat == NULL ) - { - p->pSat = sat_solver_new(); - p->nSatVars = 1; - sat_solver_setnvars( p->pSat, 1000 ); - // var 0 is reserved for const1 node - add the clause -// pLits[0] = toLit( 0 ); -// sat_solver_addclause( p->pSat, pLits, pLits + 1 ); - } - - // if the nodes do not have SAT variables, allocate them - Ivy_FraigNodeAddToSolver( p, pOld, pNew ); - - // prepare variable activity - Ivy_FraigSetActivityFactors( p, pOld, pNew ); - - // solve under assumptions - // A = 1; B = 0 OR A = 1; B = 1 -clk = clock(); - pLits[0] = toLitCond( Ivy_ObjSatNum(pOld), 0 ); - pLits[1] = toLitCond( Ivy_ObjSatNum(pNew), pOld->fPhase == pNew->fPhase ); -//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); - RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2, - (sint64)nBTLimit, (sint64)0, - p->nBTLimitGlobal, p->nInsLimitGlobal ); -p->timeSat += clock() - clk; - if ( RetValue1 == l_False ) - { -p->timeSatUnsat += clock() - clk; - pLits[0] = lit_neg( pLits[0] ); - pLits[1] = lit_neg( pLits[1] ); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); - assert( RetValue ); - // continue solving the other implication - p->nSatCallsUnsat++; - } - else if ( RetValue1 == l_True ) - { -p->timeSatSat += clock() - clk; - Ivy_FraigSavePattern( p ); - p->nSatCallsSat++; - return 0; - } - else // if ( RetValue1 == l_Undef ) - { -p->timeSatFail += clock() - clk; - // mark the node as the failed node - if ( pOld != p->pManFraig->pConst1 ) - pOld->fFailTfo = 1; - pNew->fFailTfo = 1; - p->nSatFailsReal++; - return -1; - } - - // if the old node was constant 0, we already know the answer - if ( pOld == p->pManFraig->pConst1 ) - { - p->nSatProof++; - return 1; - } - - // solve under assumptions - // A = 0; B = 1 OR A = 0; B = 0 -clk = clock(); - pLits[0] = toLitCond( Ivy_ObjSatNum(pOld), 1 ); - pLits[1] = toLitCond( Ivy_ObjSatNum(pNew), pOld->fPhase ^ pNew->fPhase ); - RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2, - (sint64)nBTLimit, (sint64)0, - p->nBTLimitGlobal, p->nInsLimitGlobal ); -p->timeSat += clock() - clk; - if ( RetValue1 == l_False ) - { -p->timeSatUnsat += clock() - clk; - pLits[0] = lit_neg( pLits[0] ); - pLits[1] = lit_neg( pLits[1] ); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); - assert( RetValue ); - p->nSatCallsUnsat++; - } - else if ( RetValue1 == l_True ) - { -p->timeSatSat += clock() - clk; - Ivy_FraigSavePattern( p ); - p->nSatCallsSat++; - return 0; - } - else // if ( RetValue1 == l_Undef ) - { -p->timeSatFail += clock() - clk; - // mark the node as the failed node - pOld->fFailTfo = 1; - pNew->fFailTfo = 1; - p->nSatFailsReal++; - return -1; - } -/* - // check BDD proof - { - int RetVal; - PRT( "Sat", clock() - clk2 ); - clk2 = clock(); - RetVal = Ivy_FraigNodesAreEquivBdd( pOld, pNew ); -// printf( "%d ", RetVal ); - assert( RetVal ); - PRT( "Bdd", clock() - clk2 ); - printf( "\n" ); - } -*/ - // return SAT proof - p->nSatProof++; - return 1; -} - -/**Function************************************************************* - - Synopsis [Runs equivalence test for one node.] - - Description [Returns the fraiged node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigNodeIsConst( Ivy_FraigMan_t * p, Ivy_Obj_t * pNew ) -{ - int pLits[2], RetValue1, RetValue, clk; - - // make sure the nodes are not complemented - assert( !Ivy_IsComplement(pNew) ); - assert( pNew != p->pManFraig->pConst1 ); - p->nSatCalls++; - - // make sure the solver is allocated and has enough variables - if ( p->pSat == NULL ) - { - p->pSat = sat_solver_new(); - p->nSatVars = 1; - sat_solver_setnvars( p->pSat, 1000 ); - // var 0 is reserved for const1 node - add the clause -// pLits[0] = toLit( 0 ); -// sat_solver_addclause( p->pSat, pLits, pLits + 1 ); - } - - // if the nodes do not have SAT variables, allocate them - Ivy_FraigNodeAddToSolver( p, NULL, pNew ); - - // prepare variable activity - Ivy_FraigSetActivityFactors( p, NULL, pNew ); - - // solve under assumptions -clk = clock(); - pLits[0] = toLitCond( Ivy_ObjSatNum(pNew), pNew->fPhase ); - RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 1, - (sint64)p->pParams->nBTLimitMiter, (sint64)0, - p->nBTLimitGlobal, p->nInsLimitGlobal ); -p->timeSat += clock() - clk; - if ( RetValue1 == l_False ) - { -p->timeSatUnsat += clock() - clk; - pLits[0] = lit_neg( pLits[0] ); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 ); - assert( RetValue ); - // continue solving the other implication - p->nSatCallsUnsat++; - } - else if ( RetValue1 == l_True ) - { -p->timeSatSat += clock() - clk; - if ( p->pPatWords ) - Ivy_FraigSavePattern( p ); - p->nSatCallsSat++; - return 0; - } - else // if ( RetValue1 == l_Undef ) - { -p->timeSatFail += clock() - clk; - // mark the node as the failed node - pNew->fFailTfo = 1; - p->nSatFailsReal++; - return -1; - } - - // return SAT proof - p->nSatProof++; - return 1; -} - -/**Function************************************************************* - - Synopsis [Addes clauses to the solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigAddClausesMux( Ivy_FraigMan_t * p, Ivy_Obj_t * pNode ) -{ - Ivy_Obj_t * pNodeI, * pNodeT, * pNodeE; - int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; - - assert( !Ivy_IsComplement( pNode ) ); - assert( Ivy_ObjIsMuxType( pNode ) ); - // get nodes (I = if, T = then, E = else) - pNodeI = Ivy_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); - // get the variable numbers - VarF = Ivy_ObjSatNum(pNode); - VarI = Ivy_ObjSatNum(pNodeI); - VarT = Ivy_ObjSatNum(Ivy_Regular(pNodeT)); - VarE = Ivy_ObjSatNum(Ivy_Regular(pNodeE)); - // get the complementation flags - fCompT = Ivy_IsComplement(pNodeT); - fCompE = Ivy_IsComplement(pNodeE); - - // f = ITE(i, t, e) - - // i' + t' + f - // i' + t + f' - // i + e' + f - // i + e + f' - - // create four clauses - pLits[0] = toLitCond(VarI, 1); - pLits[1] = toLitCond(VarT, 1^fCompT); - pLits[2] = toLitCond(VarF, 0); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); - assert( RetValue ); - pLits[0] = toLitCond(VarI, 1); - pLits[1] = toLitCond(VarT, 0^fCompT); - pLits[2] = toLitCond(VarF, 1); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); - assert( RetValue ); - pLits[0] = toLitCond(VarI, 0); - pLits[1] = toLitCond(VarE, 1^fCompE); - pLits[2] = toLitCond(VarF, 0); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); - assert( RetValue ); - pLits[0] = toLitCond(VarI, 0); - pLits[1] = toLitCond(VarE, 0^fCompE); - pLits[2] = toLitCond(VarF, 1); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); - assert( RetValue ); - - // two additional clauses - // t' & e' -> f' - // t & e -> f - - // t + e + f' - // t' + e' + f - - if ( VarT == VarE ) - { -// assert( fCompT == !fCompE ); - return; - } - - pLits[0] = toLitCond(VarT, 0^fCompT); - pLits[1] = toLitCond(VarE, 0^fCompE); - pLits[2] = toLitCond(VarF, 1); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); - assert( RetValue ); - pLits[0] = toLitCond(VarT, 1^fCompT); - pLits[1] = toLitCond(VarE, 1^fCompE); - pLits[2] = toLitCond(VarF, 0); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); - assert( RetValue ); -} - -/**Function************************************************************* - - Synopsis [Addes clauses to the solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigAddClausesSuper( Ivy_FraigMan_t * p, Ivy_Obj_t * pNode, Vec_Ptr_t * vSuper ) -{ - Ivy_Obj_t * pFanin; - int * pLits, nLits, RetValue, i; - assert( !Ivy_IsComplement(pNode) ); - assert( Ivy_ObjIsNode( pNode ) ); - // create storage for literals - nLits = Vec_PtrSize(vSuper) + 1; - pLits = ALLOC( int, nLits ); - // suppose AND-gate is A & B = C - // add !A => !C or A + !C - Vec_PtrForEachEntry( vSuper, pFanin, i ) - { - pLits[0] = toLitCond(Ivy_ObjSatNum(Ivy_Regular(pFanin)), Ivy_IsComplement(pFanin)); - pLits[1] = toLitCond(Ivy_ObjSatNum(pNode), 1); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); - assert( RetValue ); - } - // add A & B => C or !A + !B + C - Vec_PtrForEachEntry( vSuper, pFanin, i ) - pLits[i] = toLitCond(Ivy_ObjSatNum(Ivy_Regular(pFanin)), !Ivy_IsComplement(pFanin)); - pLits[nLits-1] = toLitCond(Ivy_ObjSatNum(pNode), 0); - RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits ); - assert( RetValue ); - free( pLits ); -} - -/**Function************************************************************* - - Synopsis [Collects the supergate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigCollectSuper_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes ) -{ - // if the new node is complemented or a PI, another gate begins - if ( Ivy_IsComplement(pObj) || Ivy_ObjIsPi(pObj) || (!fFirst && Ivy_ObjRefs(pObj) > 1) || - (fUseMuxes && Ivy_ObjIsMuxType(pObj)) ) - { - Vec_PtrPushUnique( vSuper, pObj ); - return; - } - // go through the branches - Ivy_FraigCollectSuper_rec( Ivy_ObjChild0(pObj), vSuper, 0, fUseMuxes ); - Ivy_FraigCollectSuper_rec( Ivy_ObjChild1(pObj), vSuper, 0, fUseMuxes ); -} - -/**Function************************************************************* - - Synopsis [Collects the supergate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Ivy_FraigCollectSuper( Ivy_Obj_t * pObj, int fUseMuxes ) -{ - Vec_Ptr_t * vSuper; - assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_ObjIsPi(pObj) ); - vSuper = Vec_PtrAlloc( 4 ); - Ivy_FraigCollectSuper_rec( pObj, vSuper, 1, fUseMuxes ); - return vSuper; -} - -/**Function************************************************************* - - Synopsis [Updates the solver clause database.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigObjAddToFrontier( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vFrontier ) -{ - assert( !Ivy_IsComplement(pObj) ); - if ( Ivy_ObjSatNum(pObj) ) - return; - assert( Ivy_ObjSatNum(pObj) == 0 ); - assert( Ivy_ObjFaninVec(pObj) == NULL ); - if ( Ivy_ObjIsConst1(pObj) ) - return; -//printf( "Assigning node %d number %d\n", pObj->Id, p->nSatVars ); - Ivy_ObjSetSatNum( pObj, p->nSatVars++ ); - if ( Ivy_ObjIsNode(pObj) ) - Vec_PtrPush( vFrontier, pObj ); -} - -/**Function************************************************************* - - Synopsis [Updates the solver clause database.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_FraigNodeAddToSolver( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * pNew ) -{ - Vec_Ptr_t * vFrontier, * vFanins; - Ivy_Obj_t * pNode, * pFanin; - int i, k, fUseMuxes = 1; - assert( pOld || pNew ); - // quit if CNF is ready - if ( (!pOld || Ivy_ObjFaninVec(pOld)) && (!pNew || Ivy_ObjFaninVec(pNew)) ) - return; - // start the frontier - vFrontier = Vec_PtrAlloc( 100 ); - if ( pOld ) Ivy_FraigObjAddToFrontier( p, pOld, vFrontier ); - if ( pNew ) Ivy_FraigObjAddToFrontier( p, pNew, vFrontier ); - // explore nodes in the frontier - Vec_PtrForEachEntry( vFrontier, pNode, i ) - { - // create the supergate - assert( Ivy_ObjSatNum(pNode) ); - assert( Ivy_ObjFaninVec(pNode) == NULL ); - if ( fUseMuxes && Ivy_ObjIsMuxType(pNode) ) - { - vFanins = Vec_PtrAlloc( 4 ); - Vec_PtrPushUnique( vFanins, Ivy_ObjFanin0( Ivy_ObjFanin0(pNode) ) ); - Vec_PtrPushUnique( vFanins, Ivy_ObjFanin0( Ivy_ObjFanin1(pNode) ) ); - Vec_PtrPushUnique( vFanins, Ivy_ObjFanin1( Ivy_ObjFanin0(pNode) ) ); - Vec_PtrPushUnique( vFanins, Ivy_ObjFanin1( Ivy_ObjFanin1(pNode) ) ); - Vec_PtrForEachEntry( vFanins, pFanin, k ) - Ivy_FraigObjAddToFrontier( p, Ivy_Regular(pFanin), vFrontier ); - Ivy_FraigAddClausesMux( p, pNode ); - } - else - { - vFanins = Ivy_FraigCollectSuper( pNode, fUseMuxes ); - Vec_PtrForEachEntry( vFanins, pFanin, k ) - Ivy_FraigObjAddToFrontier( p, Ivy_Regular(pFanin), vFrontier ); - Ivy_FraigAddClausesSuper( p, pNode, vFanins ); - } - assert( Vec_PtrSize(vFanins) > 1 ); - Ivy_ObjSetFaninVec( pNode, vFanins ); - } - Vec_PtrFree( vFrontier ); -} - -/**Function************************************************************* - - Synopsis [Sets variable activities in the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigSetActivityFactors_rec( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj, int LevelMin, int LevelMax ) -{ - Vec_Ptr_t * vFanins; - Ivy_Obj_t * pFanin; - int i, Counter = 0; - assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjSatNum(pObj) ); - // skip visited variables - if ( Ivy_ObjIsTravIdCurrent(p->pManFraig, pObj) ) - return 0; - Ivy_ObjSetTravIdCurrent(p->pManFraig, pObj); - // add the PI to the list - if ( pObj->Level <= (unsigned)LevelMin || Ivy_ObjIsPi(pObj) ) - return 0; - // set the factor of this variable - // (LevelMax-LevelMin) / (pObj->Level-LevelMin) = p->pParams->dActConeBumpMax / ThisBump - p->pSat->factors[Ivy_ObjSatNum(pObj)] = p->pParams->dActConeBumpMax * (pObj->Level - LevelMin)/(LevelMax - LevelMin); - veci_push(&p->pSat->act_vars, Ivy_ObjSatNum(pObj)); - // explore the fanins - vFanins = Ivy_ObjFaninVec( pObj ); - Vec_PtrForEachEntry( vFanins, pFanin, i ) - Counter += Ivy_FraigSetActivityFactors_rec( p, Ivy_Regular(pFanin), LevelMin, LevelMax ); - return 1 + Counter; -} - -/**Function************************************************************* - - Synopsis [Sets variable activities in the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigSetActivityFactors( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * pNew ) -{ - int clk, LevelMin, LevelMax; - assert( pOld || pNew ); -clk = clock(); - // reset the active variables - veci_resize(&p->pSat->act_vars, 0); - // prepare for traversal - Ivy_ManIncrementTravId( p->pManFraig ); - // determine the min and max level to visit - assert( p->pParams->dActConeRatio > 0 && p->pParams->dActConeRatio < 1 ); - LevelMax = IVY_MAX( (pNew ? pNew->Level : 0), (pOld ? pOld->Level : 0) ); - LevelMin = (int)(LevelMax * (1.0 - p->pParams->dActConeRatio)); - // traverse - if ( pOld && !Ivy_ObjIsConst1(pOld) ) - Ivy_FraigSetActivityFactors_rec( p, pOld, LevelMin, LevelMax ); - if ( pNew && !Ivy_ObjIsConst1(pNew) ) - Ivy_FraigSetActivityFactors_rec( p, pNew, LevelMin, LevelMax ); -//Ivy_FraigPrintActivity( p ); -p->timeTrav += clock() - clk; - return 1; -} - - - -#include "cuddInt.h" - -/**Function************************************************************* - - Synopsis [Checks equivalence using BDDs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Ivy_FraigNodesAreEquivBdd_int( DdManager * dd, DdNode * bFunc, Vec_Ptr_t * vFront, int Level ) -{ - DdNode ** pFuncs; - DdNode * bFuncNew; - Vec_Ptr_t * vTemp; - Ivy_Obj_t * pObj, * pFanin; - int i, NewSize; - // create new frontier - vTemp = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( vFront, pObj, i ) - { - if ( (int)pObj->Level != Level ) - { - pObj->fMarkB = 1; - pObj->TravId = Vec_PtrSize(vTemp); - Vec_PtrPush( vTemp, pObj ); - continue; - } - - pFanin = Ivy_ObjFanin0(pObj); - if ( pFanin->fMarkB == 0 ) - { - pFanin->fMarkB = 1; - pFanin->TravId = Vec_PtrSize(vTemp); - Vec_PtrPush( vTemp, pFanin ); - } - - pFanin = Ivy_ObjFanin1(pObj); - if ( pFanin->fMarkB == 0 ) - { - pFanin->fMarkB = 1; - pFanin->TravId = Vec_PtrSize(vTemp); - Vec_PtrPush( vTemp, pFanin ); - } - } - // collect the permutation - NewSize = IVY_MAX(dd->size, Vec_PtrSize(vTemp)); - pFuncs = ALLOC( DdNode *, NewSize ); - Vec_PtrForEachEntry( vFront, pObj, i ) - { - if ( (int)pObj->Level != Level ) - pFuncs[i] = Cudd_bddIthVar( dd, pObj->TravId ); - else - pFuncs[i] = Cudd_bddAnd( dd, - Cudd_NotCond( Cudd_bddIthVar(dd, Ivy_ObjFanin0(pObj)->TravId), Ivy_ObjFaninC0(pObj) ), - Cudd_NotCond( Cudd_bddIthVar(dd, Ivy_ObjFanin1(pObj)->TravId), Ivy_ObjFaninC1(pObj) ) ); - Cudd_Ref( pFuncs[i] ); - } - // add the remaining vars - assert( NewSize == dd->size ); - for ( i = Vec_PtrSize(vFront); i < dd->size; i++ ) - { - pFuncs[i] = Cudd_bddIthVar( dd, i ); - Cudd_Ref( pFuncs[i] ); - } - - // create new - bFuncNew = Cudd_bddVectorCompose( dd, bFunc, pFuncs ); Cudd_Ref( bFuncNew ); - // clean trav Id - Vec_PtrForEachEntry( vTemp, pObj, i ) - { - pObj->fMarkB = 0; - pObj->TravId = 0; - } - // deref - for ( i = 0; i < dd->size; i++ ) - Cudd_RecursiveDeref( dd, pFuncs[i] ); - free( pFuncs ); - - free( vFront->pArray ); - *vFront = *vTemp; - - vTemp->nCap = vTemp->nSize = 0; - vTemp->pArray = NULL; - Vec_PtrFree( vTemp ); - - Cudd_Deref( bFuncNew ); - return bFuncNew; -} - -/**Function************************************************************* - - Synopsis [Checks equivalence using BDDs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_FraigNodesAreEquivBdd( Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2 ) -{ - static DdManager * dd = NULL; - DdNode * bFunc, * bTemp; - Vec_Ptr_t * vFront; - Ivy_Obj_t * pObj; - int i, RetValue, Iter, Level; - // start the manager - if ( dd == NULL ) - dd = Cudd_Init( 50, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); - // create front - vFront = Vec_PtrAlloc( 100 ); - Vec_PtrPush( vFront, pObj1 ); - Vec_PtrPush( vFront, pObj2 ); - // get the function - bFunc = Cudd_bddXor( dd, Cudd_bddIthVar(dd,0), Cudd_bddIthVar(dd,1) ); Cudd_Ref( bFunc ); - bFunc = Cudd_NotCond( bFunc, pObj1->fPhase != pObj2->fPhase ); - // try running BDDs - for ( Iter = 0; ; Iter++ ) - { - // find max level - Level = 0; - Vec_PtrForEachEntry( vFront, pObj, i ) - if ( Level < (int)pObj->Level ) - Level = (int)pObj->Level; - if ( Level == 0 ) - break; - bFunc = Ivy_FraigNodesAreEquivBdd_int( dd, bTemp = bFunc, vFront, Level ); Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bTemp ); - if ( bFunc == Cudd_ReadLogicZero(dd) ) // proved - {printf( "%d", Iter ); break;} - if ( Cudd_DagSize(bFunc) > 1000 ) - {printf( "b" ); break;} - if ( dd->size > 120 ) - {printf( "s" ); break;} - if ( Iter > 50 ) - {printf( "i" ); break;} - } - if ( bFunc == Cudd_ReadLogicZero(dd) ) // unsat - RetValue = 1; - else if ( Level == 0 ) // sat - RetValue = 0; - else - RetValue = -1; // spaceout/timeout - Cudd_RecursiveDeref( dd, bFunc ); - Vec_PtrFree( vFront ); - return RetValue; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyHaig.c b/src/aig/ivy/ivyHaig.c deleted file mode 100644 index 87021600..00000000 --- a/src/aig/ivy/ivyHaig.c +++ /dev/null @@ -1,530 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyHaig.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [HAIG management procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyHaig.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/* - HAIGing rules in working AIG: - - Each node in the working AIG has a pointer to the corresponding node in HAIG - (this node is not necessarily the representative of the equivalence class of HAIG nodes) - - This pointer is complemented if the AIG node and its corresponding HAIG node have different phase - - Choice node rules in HAIG: - - Equivalent nodes are linked into a ring - - Exactly one node in the ring has fanouts (this node is called the representative) - - The pointer going from a node to the next node in the ring is complemented - if the first node is complemented, compared to the representative node of the equivalence class - - (consequence of the above) The representative node always has non-complemented pointer to the next node - - New nodes are inserted into the ring immediately after the representative node -*/ - -// returns the representative node of the given HAIG node -static inline Ivy_Obj_t * Ivy_HaigObjRepr( Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pTemp; - assert( !Ivy_IsComplement(pObj) ); - // if the node has no equivalent node or has fanout, it is representative - if ( pObj->pEquiv == NULL || Ivy_ObjRefs(pObj) > 0 ) - return pObj; - // the node belongs to a class and is not a representative - // complemented edge (pObj->pEquiv) tells if it is complemented w.r.t. the repr - for ( pTemp = Ivy_Regular(pObj->pEquiv); pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - if ( Ivy_ObjRefs(pTemp) > 0 ) - break; - // return the representative node - assert( Ivy_ObjRefs(pTemp) > 0 ); - return Ivy_NotCond( pTemp, Ivy_IsComplement(pObj->pEquiv) ); -} - -// counts the number of nodes in the equivalence class -static inline int Ivy_HaigObjCountClass( Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pTemp; - int Counter; - assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjRefs(pObj) > 0 ); - if ( pObj->pEquiv == NULL ) - return 1; - assert( !Ivy_IsComplement(pObj->pEquiv) ); - Counter = 1; - for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - Counter++; - return Counter; -} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts HAIG for the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManHaigStart( Ivy_Man_t * p, int fVerbose ) -{ - Vec_Int_t * vLatches; - Ivy_Obj_t * pObj; - int i; - assert( p->pHaig == NULL ); - p->pHaig = Ivy_ManDup( p ); - - if ( fVerbose ) - { - printf( "Starting : " ); - Ivy_ManPrintStats( p->pHaig ); - } - - // collect latches of design D and set their values to be DC - vLatches = Vec_IntAlloc( 100 ); - Ivy_ManForEachLatch( p->pHaig, pObj, i ) - { - pObj->Init = IVY_INIT_DC; - Vec_IntPush( vLatches, pObj->Id ); - } - p->pHaig->pData = vLatches; -/* - { - int x; - Ivy_ManShow( p, 0, NULL ); - Ivy_ManShow( p->pHaig, 1, NULL ); - x = 0; - } -*/ -} - -/**Function************************************************************* - - Synopsis [Transfers the HAIG to the newly created manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManHaigTrasfer( Ivy_Man_t * p, Ivy_Man_t * pNew ) -{ - Ivy_Obj_t * pObj; - int i; - assert( p->pHaig != NULL ); - Ivy_ManConst1(pNew)->pEquiv = Ivy_ManConst1(p)->pEquiv; - Ivy_ManForEachPi( pNew, pObj, i ) - pObj->pEquiv = Ivy_ManPi( p, i )->pEquiv; - pNew->pHaig = p->pHaig; -} - -/**Function************************************************************* - - Synopsis [Stops HAIG for the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManHaigStop( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - assert( p->pHaig != NULL ); - Vec_IntFree( p->pHaig->pData ); - Ivy_ManStop( p->pHaig ); - p->pHaig = NULL; - // remove dangling pointers to the HAIG objects - Ivy_ManForEachObj( p, pObj, i ) - pObj->pEquiv = NULL; -} - -/**Function************************************************************* - - Synopsis [Creates a new node in HAIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManHaigCreateObj( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pEquiv0, * pEquiv1; - assert( p->pHaig != NULL ); - assert( !Ivy_IsComplement(pObj) ); - if ( Ivy_ObjType(pObj) == IVY_BUF ) - pObj->pEquiv = Ivy_ObjChild0Equiv(pObj); - else if ( Ivy_ObjType(pObj) == IVY_LATCH ) - { -// pObj->pEquiv = Ivy_Latch( p->pHaig, Ivy_ObjChild0Equiv(pObj), pObj->Init ); - pEquiv0 = Ivy_ObjChild0Equiv(pObj); - pEquiv0 = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pEquiv0)), Ivy_IsComplement(pEquiv0) ); - pObj->pEquiv = Ivy_Latch( p->pHaig, pEquiv0, pObj->Init ); - } - else if ( Ivy_ObjType(pObj) == IVY_AND ) - { -// pObj->pEquiv = Ivy_And( p->pHaig, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) ); - pEquiv0 = Ivy_ObjChild0Equiv(pObj); - pEquiv0 = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pEquiv0)), Ivy_IsComplement(pEquiv0) ); - pEquiv1 = Ivy_ObjChild1Equiv(pObj); - pEquiv1 = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pEquiv1)), Ivy_IsComplement(pEquiv1) ); - pObj->pEquiv = Ivy_And( p->pHaig, pEquiv0, pEquiv1 ); - } - else assert( 0 ); - // make sure the node points to the representative -// pObj->pEquiv = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pObj->pEquiv)), Ivy_IsComplement(pObj->pEquiv) ); -} - -/**Function************************************************************* - - Synopsis [Checks if the old node is in the TFI of the new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ObjIsInTfi_rec( Ivy_Obj_t * pObjNew, Ivy_Obj_t * pObjOld, int Levels ) -{ - if ( pObjNew == pObjOld ) - return 1; - if ( Levels == 0 || Ivy_ObjIsCi(pObjNew) || Ivy_ObjIsConst1(pObjNew) ) - return 0; - if ( Ivy_ObjIsInTfi_rec( Ivy_ObjFanin0(pObjNew), pObjOld, Levels - 1 ) ) - return 1; - if ( Ivy_ObjIsNode(pObjNew) && Ivy_ObjIsInTfi_rec( Ivy_ObjFanin1(pObjNew), pObjOld, Levels - 1 ) ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Sets the pair of equivalent nodes in HAIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManHaigCreateChoice( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew ) -{ - Ivy_Obj_t * pObjOldHaig, * pObjNewHaig; - Ivy_Obj_t * pObjOldHaigR, * pObjNewHaigR; - int fCompl; -//printf( "\nCreating choice for %d and %d in AIG\n", pObjOld->Id, Ivy_Regular(pObjNew)->Id ); - - assert( p->pHaig != NULL ); - assert( !Ivy_IsComplement(pObjOld) ); - // get pointers to the representatives of pObjOld and pObjNew - pObjOldHaig = pObjOld->pEquiv; - pObjNewHaig = Ivy_NotCond( Ivy_Regular(pObjNew)->pEquiv, Ivy_IsComplement(pObjNew) ); - // get the classes - pObjOldHaig = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pObjOldHaig)), Ivy_IsComplement(pObjOldHaig) ); - pObjNewHaig = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pObjNewHaig)), Ivy_IsComplement(pObjNewHaig) ); - // get regular pointers - pObjOldHaigR = Ivy_Regular(pObjOldHaig); - pObjNewHaigR = Ivy_Regular(pObjNewHaig); - // check if there is phase difference between them - fCompl = (Ivy_IsComplement(pObjOldHaig) != Ivy_IsComplement(pObjNewHaig)); - // if the class is the same, nothing to do - if ( pObjOldHaigR == pObjNewHaigR ) - return; - // if the second node belongs to a class, do not merge classes (for the time being) - if ( Ivy_ObjRefs(pObjOldHaigR) == 0 || pObjNewHaigR->pEquiv != NULL || - Ivy_ObjRefs(pObjNewHaigR) > 0 ) //|| Ivy_ObjIsInTfi_rec(pObjNewHaigR, pObjOldHaigR, 10) ) - { -/* - if ( pObjNewHaigR->pEquiv != NULL ) - printf( "c" ); - if ( Ivy_ObjRefs(pObjNewHaigR) > 0 ) - printf( "f" ); - printf( " " ); -*/ - p->pHaig->nClassesSkip++; - return; - } - - // add this node to the class of pObjOldHaig - assert( Ivy_ObjRefs(pObjOldHaigR) > 0 ); - assert( !Ivy_IsComplement(pObjOldHaigR->pEquiv) ); - if ( pObjOldHaigR->pEquiv == NULL ) - pObjNewHaigR->pEquiv = Ivy_NotCond( pObjOldHaigR, fCompl ); - else - pObjNewHaigR->pEquiv = Ivy_NotCond( pObjOldHaigR->pEquiv, fCompl ); - pObjOldHaigR->pEquiv = pObjNewHaigR; -//printf( "Setting choice node %d -> %d.\n", pObjOldHaigR->Id, pObjNewHaigR->Id ); - // update the class of the new node -// Ivy_Regular(pObjNew)->pEquiv = Ivy_NotCond( pObjOldHaigR, fCompl ^ Ivy_IsComplement(pObjNew) ); -//printf( "Creating choice for %d and %d in HAIG\n", pObjOldHaigR->Id, pObjNewHaigR->Id ); - -// if ( pObjOldHaigR->Id == 13 ) -// { -// Ivy_ManShow( p, 0 ); -// Ivy_ManShow( p->pHaig, 1 ); -// } -// if ( !Ivy_ManIsAcyclic( p->pHaig ) ) -// printf( "HAIG contains a cycle\n" ); -} - -/**Function************************************************************* - - Synopsis [Count the number of choices and choice nodes in HAIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManHaigCountChoices( Ivy_Man_t * p, int * pnChoices ) -{ - Ivy_Obj_t * pObj; - int nChoices, nChoiceNodes, Counter, i; - assert( p->pHaig != NULL ); - nChoices = nChoiceNodes = 0; - Ivy_ManForEachObj( p->pHaig, pObj, i ) - { - if ( Ivy_ObjIsTerm(pObj) || i == 0 ) - continue; - if ( Ivy_ObjRefs(pObj) == 0 ) - continue; - Counter = Ivy_HaigObjCountClass( pObj ); - nChoiceNodes += (int)(Counter > 1); - nChoices += Counter - 1; -// if ( Counter > 1 ) -// printf( "Choice node %d %s\n", pObj->Id, Ivy_ObjIsLatch(pObj)? "(latch)": "" ); - } - *pnChoices = nChoices; - return nChoiceNodes; -} - -/**Function************************************************************* - - Synopsis [Prints statistics of the HAIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManHaigPostprocess( Ivy_Man_t * p, int fVerbose ) -{ - int nChoices, nChoiceNodes; - - assert( p->pHaig != NULL ); - - if ( fVerbose ) - { - printf( "Final : " ); - Ivy_ManPrintStats( p ); - printf( "HAIG : " ); - Ivy_ManPrintStats( p->pHaig ); - - // print choice node stats - nChoiceNodes = Ivy_ManHaigCountChoices( p, &nChoices ); - printf( "Total choice nodes = %d. Total choices = %d. Skipped classes = %d.\n", - nChoiceNodes, nChoices, p->pHaig->nClassesSkip ); - } - - if ( Ivy_ManIsAcyclic( p->pHaig ) ) - { - if ( fVerbose ) - printf( "HAIG is acyclic\n" ); - } - else - printf( "HAIG contains a cycle\n" ); - -// if ( fVerbose ) -// Ivy_ManHaigSimulate( p ); -} - - -/**Function************************************************************* - - Synopsis [Applies the simulation rules.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Ivy_Init_t Ivy_ManHaigSimulateAnd( Ivy_Init_t In0, Ivy_Init_t In1 ) -{ - assert( In0 != IVY_INIT_NONE && In1 != IVY_INIT_NONE ); - if ( In0 == IVY_INIT_DC || In1 == IVY_INIT_DC ) - return IVY_INIT_DC; - if ( In0 == IVY_INIT_1 && In1 == IVY_INIT_1 ) - return IVY_INIT_1; - return IVY_INIT_0; -} - -/**Function************************************************************* - - Synopsis [Applies the simulation rules.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Ivy_Init_t Ivy_ManHaigSimulateChoice( Ivy_Init_t In0, Ivy_Init_t In1 ) -{ - assert( In0 != IVY_INIT_NONE && In1 != IVY_INIT_NONE ); - if ( (In0 == IVY_INIT_0 && In1 == IVY_INIT_1) || (In0 == IVY_INIT_1 && In1 == IVY_INIT_0) ) - { - printf( "Compatibility fails.\n" ); - return IVY_INIT_0; - } - if ( In0 == IVY_INIT_DC && In1 == IVY_INIT_DC ) - return IVY_INIT_DC; - if ( In0 != IVY_INIT_DC ) - return In0; - return In1; -} - -/**Function************************************************************* - - Synopsis [Simulate HAIG using modified 3-valued simulation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManHaigSimulate( Ivy_Man_t * p ) -{ - Vec_Int_t * vNodes, * vLatches, * vLatchesD; - Ivy_Obj_t * pObj, * pTemp; - Ivy_Init_t In0, In1; - int i, k, Counter; - int fVerbose = 0; - - // check choices - Ivy_ManCheckChoices( p ); - - // switch to HAIG - assert( p->pHaig != NULL ); - p = p->pHaig; - -if ( fVerbose ) -Ivy_ManForEachPi( p, pObj, i ) -printf( "Setting PI %d\n", pObj->Id ); - - // collect latches and nodes in the DFS order - vNodes = Ivy_ManDfsSeq( p, &vLatches ); - -if ( fVerbose ) -Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) -printf( "Collected node %d with fanins %d and %d\n", pObj->Id, Ivy_ObjFanin0(pObj)->Id, Ivy_ObjFanin1(pObj)->Id ); - - // set the PI values - Ivy_ManConst1(p)->Init = IVY_INIT_1; - Ivy_ManForEachPi( p, pObj, i ) - pObj->Init = IVY_INIT_0; - - // set the latch values - Ivy_ManForEachNodeVec( p, vLatches, pObj, i ) - pObj->Init = IVY_INIT_DC; - // set the latches of D to be determinate - vLatchesD = p->pData; - Ivy_ManForEachNodeVec( p, vLatchesD, pObj, i ) - pObj->Init = IVY_INIT_0; - - // perform several rounds of simulation - for ( k = 0; k < 10; k++ ) - { - // count the number of non-determinate values - Counter = 0; - Ivy_ManForEachNodeVec( p, vLatches, pObj, i ) - Counter += ( pObj->Init == IVY_INIT_DC ); - printf( "Iter %d : Non-determinate = %d\n", k, Counter ); - - // simulate the internal nodes - Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) - { -if ( fVerbose ) -printf( "Processing node %d with fanins %d and %d\n", pObj->Id, Ivy_ObjFanin0(pObj)->Id, Ivy_ObjFanin1(pObj)->Id ); - In0 = Ivy_InitNotCond( Ivy_ObjFanin0(pObj)->Init, Ivy_ObjFaninC0(pObj) ); - In1 = Ivy_InitNotCond( Ivy_ObjFanin1(pObj)->Init, Ivy_ObjFaninC1(pObj) ); - pObj->Init = Ivy_ManHaigSimulateAnd( In0, In1 ); - // simulate the equivalence class if the node is a representative - if ( pObj->pEquiv && Ivy_ObjRefs(pObj) > 0 ) - { -if ( fVerbose ) -printf( "Processing choice node %d\n", pObj->Id ); - In0 = pObj->Init; - assert( !Ivy_IsComplement(pObj->pEquiv) ); - for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - { -if ( fVerbose ) -printf( "Processing secondary node %d\n", pTemp->Id ); - In1 = Ivy_InitNotCond( pTemp->Init, Ivy_IsComplement(pTemp->pEquiv) ); - In0 = Ivy_ManHaigSimulateChoice( In0, In1 ); - } - pObj->Init = In0; - } - } - - // simulate the latches - Ivy_ManForEachNodeVec( p, vLatches, pObj, i ) - { - pObj->Level = Ivy_ObjFanin0(pObj)->Init; -if ( fVerbose ) -printf( "Using latch %d with fanin %d\n", pObj->Id, Ivy_ObjFanin0(pObj)->Id ); - } - Ivy_ManForEachNodeVec( p, vLatches, pObj, i ) - pObj->Init = pObj->Level, pObj->Level = 0; - } - // free arrays - Vec_IntFree( vNodes ); - Vec_IntFree( vLatches ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyMan.c b/src/aig/ivy/ivyMan.c deleted file mode 100644 index 07faef85..00000000 --- a/src/aig/ivy/ivyMan.c +++ /dev/null @@ -1,546 +0,0 @@ -/**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() -{ - Ivy_Man_t * p; - // start the manager - p = ALLOC( Ivy_Man_t, 1 ); - memset( p, 0, sizeof(Ivy_Man_t) ); - // perform initializations - p->Ghost.Id = -1; - p->nTravIds = 1; - p->fCatchExor = 1; - // allocate arrays for nodes - p->vPis = Vec_PtrAlloc( 100 ); - p->vPos = Vec_PtrAlloc( 100 ); - p->vBufs = Vec_PtrAlloc( 100 ); - p->vObjs = Vec_PtrAlloc( 100 ); - // prepare the internal memory manager - Ivy_ManStartMemory( p ); - // create the constant node - p->pConst1 = Ivy_ManFetchMemory( p ); - p->pConst1->fPhase = 1; - Vec_PtrPush( p->vObjs, p->pConst1 ); - p->nCreated = 1; - // start the table - p->nTableSize = 10007; - p->pTable = ALLOC( int, p->nTableSize ); - memset( p->pTable, 0, sizeof(int) * p->nTableSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Duplicates the AIG manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_ManStartFrom( Ivy_Man_t * p ) -{ - Ivy_Man_t * pNew; - Ivy_Obj_t * pObj; - int i; - // create the new manager - pNew = Ivy_ManStart(); - // create the PIs - Ivy_ManConst1(p)->pEquiv = Ivy_ManConst1(pNew); - Ivy_ManForEachPi( p, pObj, i ) - pObj->pEquiv = Ivy_ObjCreatePi(pNew); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Duplicates the AIG manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_ManDup( Ivy_Man_t * p ) -{ - Vec_Int_t * vNodes, * vLatches; - Ivy_Man_t * pNew; - Ivy_Obj_t * pObj; - int i; - // collect latches and nodes in the DFS order - vNodes = Ivy_ManDfsSeq( p, &vLatches ); - // create the new manager - pNew = Ivy_ManStart(); - // create the PIs - Ivy_ManConst1(p)->pEquiv = Ivy_ManConst1(pNew); - Ivy_ManForEachPi( p, pObj, i ) - pObj->pEquiv = Ivy_ObjCreatePi(pNew); - // create the fake PIs for latches - Ivy_ManForEachNodeVec( p, vLatches, pObj, i ) - pObj->pEquiv = Ivy_ObjCreatePi(pNew); - // duplicate internal nodes - Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) - if ( Ivy_ObjIsBuf(pObj) ) - pObj->pEquiv = Ivy_ObjChild0Equiv(pObj); - else - pObj->pEquiv = Ivy_And( pNew, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) ); - // add the POs - Ivy_ManForEachPo( p, pObj, i ) - Ivy_ObjCreatePo( pNew, Ivy_ObjChild0Equiv(pObj) ); - // transform additional PI nodes into latches and connect them - Ivy_ManForEachNodeVec( p, vLatches, pObj, i ) - { - assert( !Ivy_ObjFaninC0(pObj) ); - pObj->pEquiv->Type = IVY_LATCH; - pObj->pEquiv->Init = pObj->Init; - Ivy_ObjConnect( pNew, pObj->pEquiv, Ivy_ObjChild0Equiv(pObj), NULL ); - } - // shrink the arrays - Vec_PtrShrink( pNew->vPis, Ivy_ManPiNum(p) ); - // update the counters of different objects - pNew->nObjs[IVY_PI] -= Ivy_ManLatchNum(p); - pNew->nObjs[IVY_LATCH] += Ivy_ManLatchNum(p); - // free arrays - Vec_IntFree( vNodes ); - Vec_IntFree( vLatches ); - // make sure structural hashing did not change anything - assert( Ivy_ManNodeNum(p) == Ivy_ManNodeNum(pNew) ); - assert( Ivy_ManLatchNum(p) == Ivy_ManLatchNum(pNew) ); - // check the resulting network - if ( !Ivy_ManCheck(pNew) ) - printf( "Ivy_ManMakeSeq(): The check has failed.\n" ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Stops the AIG manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_ManFrames( Ivy_Man_t * pMan, int nLatches, int nFrames, int fInit, Vec_Ptr_t ** pvMapping ) -{ - Vec_Ptr_t * vMapping; - Ivy_Man_t * pNew; - Ivy_Obj_t * pObj; - int i, f, nPis, nPos, nIdMax; - assert( Ivy_ManLatchNum(pMan) == 0 ); - assert( nFrames > 0 ); - // prepare the mapping - nPis = Ivy_ManPiNum(pMan) - nLatches; - nPos = Ivy_ManPoNum(pMan) - nLatches; - nIdMax = Ivy_ManObjIdMax(pMan); - // create the new manager - pNew = Ivy_ManStart(); - // set the starting values of latch inputs - for ( i = 0; i < nLatches; i++ ) - Ivy_ManPo(pMan, nPos+i)->pEquiv = fInit? Ivy_Not(Ivy_ManConst1(pNew)) : Ivy_ObjCreatePi(pNew); - // add timeframes - vMapping = Vec_PtrStart( nIdMax * nFrames + 1 ); - for ( f = 0; f < nFrames; f++ ) - { - // create PIs - Ivy_ManConst1(pMan)->pEquiv = Ivy_ManConst1(pNew); - for ( i = 0; i < nPis; i++ ) - Ivy_ManPi(pMan, i)->pEquiv = Ivy_ObjCreatePi(pNew); - // transfer values to latch outputs - for ( i = 0; i < nLatches; i++ ) - Ivy_ManPi(pMan, nPis+i)->pEquiv = Ivy_ManPo(pMan, nPos+i)->pEquiv; - // perform strashing - Ivy_ManForEachNode( pMan, pObj, i ) - pObj->pEquiv = Ivy_And( pNew, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) ); - // create POs - for ( i = 0; i < nPos; i++ ) - Ivy_ManPo(pMan, i)->pEquiv = Ivy_ObjCreatePo( pNew, Ivy_ObjChild0Equiv(Ivy_ManPo(pMan, i)) ); - // set the results of latch inputs - for ( i = 0; i < nLatches; i++ ) - Ivy_ManPo(pMan, nPos+i)->pEquiv = Ivy_ObjChild0Equiv(Ivy_ManPo(pMan, nPos+i)); - // save the pointers in this frame - Ivy_ManForEachObj( pMan, pObj, i ) - Vec_PtrWriteEntry( vMapping, f * nIdMax + i, pObj->pEquiv ); - } - // connect latches - if ( !fInit ) - for ( i = 0; i < nLatches; i++ ) - Ivy_ObjCreatePo( pNew, Ivy_ManPo(pMan, nPos+i)->pEquiv ); - // remove dangling nodes - Ivy_ManCleanup(pNew); - *pvMapping = vMapping; - // check the resulting network - if ( !Ivy_ManCheck(pNew) ) - printf( "Ivy_ManFrames(): The check has failed.\n" ); - return pNew; -} - - -/**Function************************************************************* - - Synopsis [Stops the AIG manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManStop( Ivy_Man_t * p ) -{ - if ( p->time1 ) { PRT( "Update lev ", p->time1 ); } - if ( p->time2 ) { PRT( "Update levR ", p->time2 ); } -// Ivy_TableProfile( p ); -// if ( p->vFanouts ) Ivy_ManStopFanout( p ); - if ( p->vChunks ) Ivy_ManStopMemory( p ); - if ( p->vRequired ) Vec_IntFree( p->vRequired ); - if ( p->vPis ) Vec_PtrFree( p->vPis ); - if ( p->vPos ) Vec_PtrFree( p->vPos ); - if ( p->vBufs ) Vec_PtrFree( p->vBufs ); - if ( p->vObjs ) Vec_PtrFree( p->vObjs ); - free( p->pTable ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Removes nodes without fanout.] - - Description [Returns the number of dangling nodes removed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManCleanup( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pNode; - int i, nNodesOld; - nNodesOld = Ivy_ManNodeNum(p); - Ivy_ManForEachObj( p, pNode, i ) - if ( Ivy_ObjIsNode(pNode) || Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ) - if ( Ivy_ObjRefs(pNode) == 0 ) - Ivy_ObjDelete_rec( p, pNode, 1 ); -//printf( "Cleanup removed %d nodes.\n", nNodesOld - Ivy_ManNodeNum(p) ); - return nNodesOld - Ivy_ManNodeNum(p); -} - -/**Function************************************************************* - - Synopsis [Marks nodes reachable from the given one.] - - Description [Returns the number of dangling nodes removed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManCleanupSeq_rec( Ivy_Obj_t * pObj ) -{ - if ( Ivy_ObjIsMarkA(pObj) ) - return; - Ivy_ObjSetMarkA(pObj); - if ( pObj->pFanin0 != NULL ) - Ivy_ManCleanupSeq_rec( Ivy_ObjFanin0(pObj) ); - if ( pObj->pFanin1 != NULL ) - Ivy_ManCleanupSeq_rec( Ivy_ObjFanin1(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Removes logic that does not feed into POs.] - - Description [Returns the number of dangling nodes removed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManCleanupSeq( Ivy_Man_t * p ) -{ - Vec_Ptr_t * vNodes; - Ivy_Obj_t * pObj; - int i, RetValue; - // mark the constant and PIs - Ivy_ObjSetMarkA( Ivy_ManConst1(p) ); - Ivy_ManForEachPi( p, pObj, i ) - Ivy_ObjSetMarkA( pObj ); - // mark nodes visited from POs - Ivy_ManForEachPo( p, pObj, i ) - Ivy_ManCleanupSeq_rec( pObj ); - // collect unmarked nodes - vNodes = Vec_PtrAlloc( 100 ); - Ivy_ManForEachObj( p, pObj, i ) - { - if ( Ivy_ObjIsMarkA(pObj) ) - Ivy_ObjClearMarkA(pObj); - else - Vec_PtrPush( vNodes, pObj ); - } - if ( Vec_PtrSize(vNodes) == 0 ) - { - Vec_PtrFree( vNodes ); -//printf( "Sequential sweep cleaned out %d nodes.\n", 0 ); - return 0; - } - // disconnect the marked objects - Vec_PtrForEachEntry( vNodes, pObj, i ) - Ivy_ObjDisconnect( p, pObj ); - // remove the dangling objects - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsLatch(pObj) || Ivy_ObjIsBuf(pObj) ); - assert( Ivy_ObjRefs(pObj) == 0 ); - // update node counters of the manager - p->nObjs[pObj->Type]--; - p->nDeleted++; - // delete buffer from the array of buffers - if ( p->fFanout && Ivy_ObjIsBuf(pObj) ) - Vec_PtrRemove( p->vBufs, pObj ); - // free the node - Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL ); - Ivy_ManRecycleMemory( p, pObj ); - } - // return the number of nodes freed - RetValue = Vec_PtrSize(vNodes); - Vec_PtrFree( vNodes ); -//printf( "Sequential sweep cleaned out %d nodes.\n", RetValue ); - return RetValue; -} - - -/**Function************************************************************* - - Synopsis [Checks if latches form self-loop.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManLatchIsSelfFeed_rec( Ivy_Obj_t * pLatch, Ivy_Obj_t * pLatchRoot ) -{ - if ( !Ivy_ObjIsLatch(pLatch) && !Ivy_ObjIsBuf(pLatch) ) - return 0; - if ( pLatch == pLatchRoot ) - return 1; - return Ivy_ManLatchIsSelfFeed_rec( Ivy_ObjFanin0(pLatch), pLatchRoot ); -} - -/**Function************************************************************* - - Synopsis [Checks if latches form self-loop.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManLatchIsSelfFeed( Ivy_Obj_t * pLatch ) -{ - if ( !Ivy_ObjIsLatch(pLatch) ) - return 0; - return Ivy_ManLatchIsSelfFeed_rec( Ivy_ObjFanin0(pLatch), pLatch ); -} - - -/**Function************************************************************* - - Synopsis [Returns the number of dangling nodes removed.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel ) -{ - Ivy_Obj_t * pNode; - int LimitFactor = 100; - int NodeBeg = Ivy_ManNodeNum(p); - int nSteps; - for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ ) - { - pNode = Vec_PtrEntryLast(p->vBufs); - while ( Ivy_ObjIsBuf(pNode) ) - pNode = Ivy_ObjReadFirstFanout( p, pNode ); - // check if this buffer should remain - if ( Ivy_ManLatchIsSelfFeed(pNode) ) - { - Vec_PtrPop(p->vBufs); - continue; - } -//printf( "Propagating buffer %d with input %d and output %d\n", Ivy_ObjFaninId0(pNode), Ivy_ObjFaninId0(Ivy_ObjFanin0(pNode)), pNode->Id ); -//printf( "Latch num %d\n", Ivy_ManLatchNum(p) ); - Ivy_NodeFixBufferFanins( p, pNode, fUpdateLevel ); - if ( nSteps > NodeBeg * LimitFactor ) - { - printf( "Structural hashing is not finished after %d forward latch moves.\n", NodeBeg * LimitFactor ); - printf( "This circuit cannot be forward-retimed completely. Quitting.\n" ); - break; - } - } -// printf( "Number of steps = %d. Nodes beg = %d. Nodes end = %d.\n", nSteps, NodeBeg, Ivy_ManNodeNum(p) ); - return nSteps; -} - -/**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) ); - printf( "A = %7d. ", Ivy_ManAndNum(p) ); - printf( "L = %5d. ", Ivy_ManLatchNum(p) ); -// printf( "X = %d. ", Ivy_ManExorNum(p) ); -// printf( "B = %3d. ", Ivy_ManBufNum(p) ); - printf( "MaxID = %7d. ", Ivy_ManObjIdMax(p) ); -// printf( "Cre = %d. ", p->nCreated ); -// printf( "Del = %d. ", p->nDeleted ); - printf( "Lev = %3d. ", Ivy_ManLatchNum(p)? -1 : Ivy_ManLevels(p) ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Converts a combinational AIG manager into a sequential one.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits ) -{ - Ivy_Obj_t * pObj, * pLatch; - Ivy_Init_t Init; - int i; - if ( nLatches == 0 ) - return; - assert( nLatches < Ivy_ManPiNum(p) && nLatches < Ivy_ManPoNum(p) ); - assert( Ivy_ManPiNum(p) == Vec_PtrSize(p->vPis) ); - assert( Ivy_ManPoNum(p) == Vec_PtrSize(p->vPos) ); - assert( Vec_PtrSize( p->vBufs ) == 0 ); - // create fanouts - if ( p->fFanout == 0 ) - Ivy_ManStartFanout( p ); - // collect the POs to be converted into latches - for ( i = 0; i < nLatches; i++ ) - { - // get the latch value - Init = pInits? pInits[i] : IVY_INIT_0; - // create latch - pObj = Ivy_ManPo( p, Ivy_ManPoNum(p) - nLatches + i ); - pLatch = Ivy_Latch( p, Ivy_ObjChild0(pObj), Init ); - Ivy_ObjDisconnect( p, pObj ); - // recycle the old PO object - Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL ); - Ivy_ManRecycleMemory( p, pObj ); - // convert the corresponding PI to a buffer and connect it to the latch - pObj = Ivy_ManPi( p, Ivy_ManPiNum(p) - nLatches + i ); - pObj->Type = IVY_BUF; - Ivy_ObjConnect( p, pObj, pLatch, NULL ); - // save the buffer - Vec_PtrPush( p->vBufs, pObj ); - } - // shrink the arrays - Vec_PtrShrink( p->vPis, Ivy_ManPiNum(p) - nLatches ); - Vec_PtrShrink( 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->nDeleted -= 2 * nLatches; - // remove dangling nodes - Ivy_ManCleanup(p); - Ivy_ManCleanupSeq(p); -/* - // check for dangling nodes - Ivy_ManForEachObj( p, pObj, i ) - if ( !Ivy_ObjIsPi(pObj) && !Ivy_ObjIsPo(pObj) && !Ivy_ObjIsConst1(pObj) ) - { - assert( Ivy_ObjRefs(pObj) > 0 ); - assert( Ivy_ObjRefs(pObj) == Ivy_ObjFanoutNum(p, pObj) ); - } -*/ - // perform hashing by propagating the buffers - Ivy_ManPropagateBuffers( p, 0 ); - if ( Ivy_ManBufNum(p) ) - printf( "The number of remaining buffers is %d.\n", Ivy_ManBufNum(p) ); - // fix the levels - Ivy_ManResetLevels( p ); - // check the resulting network - if ( !Ivy_ManCheck(p) ) - printf( "Ivy_ManMakeSeq(): The check has failed.\n" ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyMem.c b/src/aig/ivy/ivyMem.c deleted file mode 100644 index 2a96857c..00000000 --- a/src/aig/ivy/ivyMem.c +++ /dev/null @@ -1,116 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyMem.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [Memory management for the AIG nodes.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyMem.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// memory management -#define IVY_PAGE_SIZE 12 // page size containing 2^IVY_PAGE_SIZE nodes -#define IVY_PAGE_MASK 4095 // page bitmask (2^IVY_PAGE_SIZE)-1 - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the internal memory manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManStartMemory( Ivy_Man_t * p ) -{ - p->vChunks = Vec_PtrAlloc( 128 ); - p->vPages = Vec_PtrAlloc( 128 ); -} - -/**Function************************************************************* - - Synopsis [Stops the internal memory manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManStopMemory( Ivy_Man_t * p ) -{ - void * pMemory; - int i; - Vec_PtrForEachEntry( p->vChunks, pMemory, i ) - free( pMemory ); - Vec_PtrFree( p->vChunks ); - Vec_PtrFree( p->vPages ); - p->pListFree = NULL; -} - -/**Function************************************************************* - - Synopsis [Allocates additional memory for the nodes.] - - Description [Allocates IVY_PAGE_SIZE nodes. Aligns memory by 32 bytes. - Records the pointer to the AIG manager in the -1 entry.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManAddMemory( Ivy_Man_t * p ) -{ - char * pMemory; - int i, nBytes; - int EntrySizeMax = 128; - assert( sizeof(Ivy_Obj_t) <= EntrySizeMax ); - assert( p->pListFree == NULL ); -// assert( (Ivy_ManObjNum(p) & IVY_PAGE_MASK) == 0 ); - // allocate new memory page - nBytes = sizeof(Ivy_Obj_t) * (1<vChunks, pMemory ); - // align memory at the 32-byte boundary - pMemory = pMemory + EntrySizeMax - (((int)pMemory) & (EntrySizeMax-1)); - // remember the manager in the first entry - Vec_PtrPush( p->vPages, pMemory ); - // break the memory down into nodes - p->pListFree = (Ivy_Obj_t *)pMemory; - for ( i = 1; i <= IVY_PAGE_MASK; i++ ) - { - *((char **)pMemory) = pMemory + sizeof(Ivy_Obj_t); - pMemory += sizeof(Ivy_Obj_t); - } - *((char **)pMemory) = NULL; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyMulti.c b/src/aig/ivy/ivyMulti.c deleted file mode 100644 index a7970156..00000000 --- a/src/aig/ivy/ivyMulti.c +++ /dev/null @@ -1,301 +0,0 @@ -/**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 /// -//////////////////////////////////////////////////////////////////////// - -#define IVY_EVAL_LIMIT 128 - -typedef struct Ivy_Eva_t_ Ivy_Eva_t; -struct Ivy_Eva_t_ -{ - Ivy_Obj_t * pArg; // the argument node - unsigned Mask; // the mask of covered nodes - int Weight; // the number of covered nodes -}; - -static void Ivy_MultiPrint( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals ); -static int Ivy_MultiCover( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Constructs a balanced tree while taking sharing into account.] - - Description [Returns 1 if the implementation exists.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_MultiPlus( Ivy_Man_t * p, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSols ) -{ - static Ivy_Eva_t pEvals[IVY_EVAL_LIMIT]; - Ivy_Eva_t * pEval, * pFan0, * pFan1; - Ivy_Obj_t * pObj, * pTemp; - int nEvals, nEvalsOld, i, k, x, nLeaves; - unsigned uMaskAll; - - // consider special cases - nLeaves = Vec_PtrSize(vLeaves); - assert( nLeaves > 2 ); - if ( nLeaves > 32 || nLeaves + Vec_PtrSize(vCone) > IVY_EVAL_LIMIT ) - return 0; -// if ( nLeaves == 1 ) -// return Vec_PtrEntry( vLeaves, 0 ); -// if ( nLeaves == 2 ) -// return Ivy_Oper( Vec_PtrEntry(vLeaves, 0), Vec_PtrEntry(vLeaves, 1), Type ); - - // set the leaf entries - uMaskAll = ((1 << nLeaves) - 1); - nEvals = 0; - Vec_PtrForEachEntry( vLeaves, pObj, i ) - { - pEval = pEvals + nEvals; - pEval->pArg = pObj; - pEval->Mask = (1 << nEvals); - pEval->Weight = 1; - // mark the leaf - Ivy_Regular(pObj)->TravId = nEvals; - nEvals++; - } - - // propagate masks through the cone - Vec_PtrForEachEntry( vCone, pObj, i ) - { - pObj->TravId = nEvals + i; - if ( Ivy_ObjIsBuf(pObj) ) - pEvals[pObj->TravId].Mask = pEvals[Ivy_ObjFanin0(pObj)->TravId].Mask; - else - pEvals[pObj->TravId].Mask = pEvals[Ivy_ObjFanin0(pObj)->TravId].Mask | pEvals[Ivy_ObjFanin1(pObj)->TravId].Mask; - } - - // set the internal entries - Vec_PtrForEachEntry( vCone, pObj, i ) - { - if ( i == Vec_PtrSize(vCone) - 1 ) - break; - // skip buffers - if ( Ivy_ObjIsBuf(pObj) ) - continue; - // skip nodes without external fanout - if ( Ivy_ObjRefs(pObj) == 0 ) - continue; - assert( !Ivy_IsComplement(pObj) ); - pEval = pEvals + nEvals; - pEval->pArg = pObj; - pEval->Mask = pEvals[pObj->TravId].Mask; - pEval->Weight = Extra_WordCountOnes(pEval->Mask); - // mark the node - pObj->TravId = nEvals; - nEvals++; - } - - // find the available nodes - nEvalsOld = nEvals; - for ( i = 1; i < nEvals; i++ ) - for ( k = 0; k < i; k++ ) - { - pFan0 = pEvals + i; - pFan1 = pEvals + k; - pTemp = Ivy_TableLookup(p, Ivy_ObjCreateGhost(p, pFan0->pArg, pFan1->pArg, Type, IVY_INIT_NONE)); - // skip nodes in the cone - if ( pTemp == NULL || pTemp->fMarkB ) - continue; - // skip the leaves - for ( x = 0; x < nLeaves; x++ ) - if ( pTemp == Ivy_Regular(vLeaves->pArray[x]) ) - break; - if ( x < nLeaves ) - continue; - pEval = pEvals + nEvals; - pEval->pArg = pTemp; - pEval->Mask = pFan0->Mask | pFan1->Mask; - pEval->Weight = (pFan0->Mask & pFan1->Mask) ? Extra_WordCountOnes(pEval->Mask) : pFan0->Weight + pFan1->Weight; - // save the argument - pObj->TravId = nEvals; - nEvals++; - // quit if the number of entries exceeded the limit - if ( nEvals == IVY_EVAL_LIMIT ) - goto Outside; - // quit if we found an acceptable implementation - if ( pEval->Mask == uMaskAll ) - goto Outside; - } -Outside: - -// Ivy_MultiPrint( pEvals, nLeaves, nEvals ); - if ( !Ivy_MultiCover( p, pEvals, nLeaves, nEvals, nLimit, vSols ) ) - return 0; - assert( Vec_PtrSize( vSols ) > 0 ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Computes how many uncovered ones this one covers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_MultiPrint( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals ) -{ - Ivy_Eva_t * pEval; - int i, k; - for ( i = nLeaves; i < nEvals; i++ ) - { - pEval = pEvals + i; - printf( "%2d (id = %5d) : |", i-nLeaves, Ivy_ObjId(pEval->pArg) ); - for ( k = 0; k < nLeaves; k++ ) - { - if ( pEval->Mask & (1 << k) ) - printf( "+" ); - else - printf( " " ); - } - printf( "| Lev = %d.\n", Ivy_ObjLevel(pEval->pArg) ); - } -} - -/**Function************************************************************* - - Synopsis [Computes how many uncovered ones this one covers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_MultiWeight( unsigned uMask, int nMaskOnes, unsigned uFound ) -{ - assert( uMask & ~uFound ); - if ( (uMask & uFound) == 0 ) - return nMaskOnes; - return Extra_WordCountOnes( uMask & ~uFound ); -} - -/**Function************************************************************* - - Synopsis [Finds the cover.] - - Description [Returns 1 if the cover is found.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_MultiCover( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols ) -{ - int fVerbose = 0; - Ivy_Eva_t * pEval, * pEvalBest; - unsigned uMaskAll, uFound, uTemp; - int i, k, BestK, WeightBest, WeightCur, LevelBest, LevelCur; - uMaskAll = (nLeaves == 32)? (~(unsigned)0) : ((1 << nLeaves) - 1); - uFound = 0; - // solve the covering problem - if ( fVerbose ) - printf( "Solution: " ); - Vec_PtrClear( vSols ); - for ( i = 0; i < nLimit; i++ ) - { - BestK = -1; - for ( k = nEvals - 1; k >= 0; k-- ) - { - pEval = pEvals + k; - if ( (pEval->Mask & ~uFound) == 0 ) - continue; - if ( BestK == -1 ) - { - BestK = k; - pEvalBest = pEval; - WeightBest = Ivy_MultiWeight( pEvalBest->Mask, pEvalBest->Weight, uFound ); - LevelBest = Ivy_ObjLevel( Ivy_Regular(pEvalBest->pArg) ); - continue; - } - // compare BestK and the new one (k) - WeightCur = Ivy_MultiWeight( pEval->Mask, pEval->Weight, uFound ); - LevelCur = Ivy_ObjLevel( Ivy_Regular(pEval->pArg) ); - if ( WeightBest < WeightCur || - (WeightBest == WeightCur && LevelBest > LevelCur) ) - { - BestK = k; - pEvalBest = pEval; - WeightBest = WeightCur; - LevelBest = LevelCur; - } - } - assert( BestK != -1 ); - // if the cost is only 1, take the leaf - if ( WeightBest == 1 && BestK >= nLeaves ) - { - uTemp = (pEvalBest->Mask & ~uFound); - for ( k = 0; k < nLeaves; k++ ) - if ( uTemp & (1 << k) ) - break; - assert( k < nLeaves ); - BestK = k; - pEvalBest = pEvals + BestK; - } - if ( fVerbose ) - { - if ( BestK < nLeaves ) - printf( "L(%d) ", BestK ); - else - printf( "%d ", BestK - nLeaves ); - } - // update the found set - Vec_PtrPush( vSols, pEvalBest->pArg ); - uFound |= pEvalBest->Mask; - if ( uFound == uMaskAll ) - break; - } - if ( uFound == uMaskAll ) - { - if ( fVerbose ) - printf( " Found \n\n" ); - return 1; - } - else - { - if ( fVerbose ) - printf( " Not found \n\n" ); - return 0; - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyMulti8.c b/src/aig/ivy/ivyMulti8.c deleted file mode 100644 index 059d1500..00000000 --- a/src/aig/ivy/ivyMulti8.c +++ /dev/null @@ -1,427 +0,0 @@ -/**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/aig/ivy/ivyObj.c b/src/aig/ivy/ivyObj.c deleted file mode 100644 index 59dda19c..00000000 --- a/src/aig/ivy/ivyObj.c +++ /dev/null @@ -1,476 +0,0 @@ -/**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_ObjCreatePi( Ivy_Man_t * p ) -{ - return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, NULL, NULL, IVY_PI, IVY_INIT_NONE) ); -} - -/**Function************************************************************* - - Synopsis [Create the new node assuming it does not exist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_ObjCreatePo( Ivy_Man_t * p, Ivy_Obj_t * pDriver ) -{ - return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pDriver, NULL, IVY_PO, IVY_INIT_NONE) ); -} - -/**Function************************************************************* - - Synopsis [Create the new node assuming it does not exist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost ) -{ - Ivy_Obj_t * pObj; - assert( !Ivy_IsComplement(pGhost) ); - assert( Ivy_ObjIsGhost(pGhost) ); - assert( Ivy_TableLookup(p, pGhost) == NULL ); - // get memory for the new object - pObj = Ivy_ManFetchMemory( p ); - assert( Ivy_ObjIsNone(pObj) ); - pObj->Id = Vec_PtrSize(p->vObjs); - Vec_PtrPush( p->vObjs, pObj ); - // add basic info (fanins, compls, type, init) - pObj->Type = pGhost->Type; - pObj->Init = pGhost->Init; - // add connections - Ivy_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 ); - // 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 ); - // create phase - if ( Ivy_ObjIsNode(pObj) ) - pObj->fPhase = Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)) & Ivy_ObjFaninPhase(Ivy_ObjChild1(pObj)); - else if ( Ivy_ObjIsOneFanin(pObj) ) - pObj->fPhase = Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)); - // set the fail TFO flag - if ( Ivy_ObjIsNode(pObj) ) - pObj->fFailTfo = Ivy_ObjFanin0(pObj)->fFailTfo | Ivy_ObjFanin1(pObj)->fFailTfo; - // 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_PtrPush( p->vPis, pObj ); - else if ( Ivy_ObjIsPo(pObj) ) - Vec_PtrPush( p->vPos, pObj ); -// else if ( Ivy_ObjIsBuf(pObj) ) -// Vec_PtrPush( p->vBufs, pObj ); - if ( p->vRequired && Vec_IntSize(p->vRequired) <= pObj->Id ) - Vec_IntFillExtra( p->vRequired, 2 * Vec_IntSize(p->vRequired), 1000000 ); - // update node counters of the manager - p->nObjs[Ivy_ObjType(pObj)]++; - p->nCreated++; - -// printf( "Adding %sAIG node: ", p->pHaig==NULL? "H":" " ); -// Ivy_ObjPrintVerbose( p, pObj, p->pHaig==NULL ); -// printf( "\n" ); - - // if HAIG is defined, create a corresponding node - if ( p->pHaig ) - Ivy_ManHaigCreateObj( p, pObj ); - return pObj; -} - -/**Function************************************************************* - - Synopsis [Connect the object to the fanin.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjConnect( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFan0, Ivy_Obj_t * pFan1 ) -{ - assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjIsPi(pObj) || Ivy_ObjIsOneFanin(pObj) || pFan1 != NULL ); - // add the first fanin - pObj->pFanin0 = pFan0; - pObj->pFanin1 = pFan1; - // increment references of the fanins and add their fanouts - if ( Ivy_ObjFanin0(pObj) != NULL ) - { - Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) ); - if ( p->fFanout ) - Ivy_ObjAddFanout( p, Ivy_ObjFanin0(pObj), pObj ); - } - if ( Ivy_ObjFanin1(pObj) != NULL ) - { - Ivy_ObjRefsInc( Ivy_ObjFanin1(pObj) ); - if ( p->fFanout ) - Ivy_ObjAddFanout( p, Ivy_ObjFanin1(pObj), pObj ); - } - // add the node to the structural hash table - Ivy_TableInsert( p, pObj ); -} - -/**Function************************************************************* - - Synopsis [Connect the object to the fanin.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjIsPi(pObj) || Ivy_ObjIsOneFanin(pObj) || Ivy_ObjFanin1(pObj) != NULL ); - // remove connections - if ( pObj->pFanin0 != NULL ) - { - Ivy_ObjRefsDec(Ivy_ObjFanin0(pObj)); - if ( p->fFanout ) - Ivy_ObjDeleteFanout( p, Ivy_ObjFanin0(pObj), pObj ); - } - if ( pObj->pFanin1 != NULL ) - { - Ivy_ObjRefsDec(Ivy_ObjFanin1(pObj)); - if ( p->fFanout ) - Ivy_ObjDeleteFanout( p, Ivy_ObjFanin1(pObj), pObj ); - } - assert( pObj->pNextFan0 == NULL ); - assert( pObj->pNextFan1 == NULL ); - assert( pObj->pPrevFan0 == NULL ); - assert( pObj->pPrevFan1 == NULL ); - // remove the node from the structural hash table - Ivy_TableDelete( p, pObj ); - // add the first fanin - pObj->pFanin0 = NULL; - pObj->pFanin1 = NULL; -} - -/**Function************************************************************* - - Synopsis [Replaces the first fanin of the node by the new fanin.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew ) -{ - Ivy_Obj_t * pFaninOld; - assert( !Ivy_IsComplement(pObj) ); - pFaninOld = Ivy_ObjFanin0(pObj); - // decrement ref and remove fanout - Ivy_ObjRefsDec( pFaninOld ); - if ( p->fFanout ) - Ivy_ObjDeleteFanout( p, pFaninOld, pObj ); - // update the fanin - pObj->pFanin0 = pFaninNew; - // increment ref and add fanout - Ivy_ObjRefsInc( Ivy_Regular(pFaninNew) ); - if ( p->fFanout ) - Ivy_ObjAddFanout( p, Ivy_Regular(pFaninNew), pObj ); - // get rid of old fanin - if ( !Ivy_ObjIsPi(pFaninOld) && !Ivy_ObjIsConst1(pFaninOld) && Ivy_ObjRefs(pFaninOld) == 0 ) - Ivy_ObjDelete_rec( p, pFaninOld, 1 ); -} - -/**Function************************************************************* - - Synopsis [Deletes the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ) -{ - assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjRefs(pObj) == 0 || !fFreeTop ); - // update node counters of the manager - p->nObjs[pObj->Type]--; - p->nDeleted++; - // remove connections - Ivy_ObjDisconnect( p, pObj ); - // remove PIs/POs from the arrays - if ( Ivy_ObjIsPi(pObj) ) - Vec_PtrRemove( p->vPis, pObj ); - else if ( Ivy_ObjIsPo(pObj) ) - Vec_PtrRemove( p->vPos, pObj ); - else if ( p->fFanout && Ivy_ObjIsBuf(pObj) ) - Vec_PtrRemove( p->vBufs, pObj ); - // clean and recycle the entry - if ( fFreeTop ) - { - // free the node - Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL ); - Ivy_ManRecycleMemory( p, pObj ); - } - else - { - int nRefsOld = pObj->nRefs; - Ivy_Obj_t * pFanout = pObj->pFanout; - Ivy_ObjClean( pObj ); - pObj->pFanout = pFanout; - pObj->nRefs = nRefsOld; - } -} - -/**Function************************************************************* - - Synopsis [Deletes the MFFC of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ) -{ - Ivy_Obj_t * pFanin0, * pFanin1; - assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_ObjIsNone(pObj) ); - if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsPi(pObj) ) - return; - pFanin0 = Ivy_ObjFanin0(pObj); - pFanin1 = Ivy_ObjFanin1(pObj); - Ivy_ObjDelete( p, pObj, fFreeTop ); - if ( pFanin0 && !Ivy_ObjIsNone(pFanin0) && Ivy_ObjRefs(pFanin0) == 0 ) - Ivy_ObjDelete_rec( p, pFanin0, 1 ); - if ( pFanin1 && !Ivy_ObjIsNone(pFanin1) && Ivy_ObjRefs(pFanin1) == 0 ) - Ivy_ObjDelete_rec( p, 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_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel ) -{ - int nRefsOld;//, clk; - // 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_ObjIsPi(pObjOld) ); - // the object to be used cannot be a PO or assert - assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) ); - // the object cannot be the same - assert( pObjOld != Ivy_Regular(pObjNew) ); -//printf( "Replacing %d by %d.\n", Ivy_Regular(pObjOld)->Id, Ivy_Regular(pObjNew)->Id ); - - // if HAIG is defined, create the choice node - if ( p->pHaig ) - { -// if ( pObjOld->Id == 31 ) -// { -// Ivy_ManShow( p, 0 ); -// Ivy_ManShow( p->pHaig, 1 ); -// } - Ivy_ManHaigCreateChoice( p, pObjOld, pObjNew ); - } - // if the new object is complemented or already used, add the buffer - if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) ) - pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) ); - assert( !Ivy_IsComplement(pObjNew) ); - if ( fUpdateLevel ) - { -//clk = clock(); - // if the new node's arrival time is different, recursively update arrival time of the fanouts - if ( p->fFanout && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level ) - { - assert( Ivy_ObjIsNode(pObjOld) ); - pObjOld->Level = pObjNew->Level; - Ivy_ObjUpdateLevel_rec( p, pObjOld ); - } -//p->time1 += clock() - clk; - // if the new node's required time has changed, recursively update required time of the fanins -//clk = clock(); - if ( p->vRequired ) - { - int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id); - if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) ) - { - Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew ); - Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew ); - } - } -//p->time2 += clock() - clk; - } - // delete the old object - if ( fDeleteOld ) - Ivy_ObjDelete_rec( p, pObjOld, fFreeTop ); - // make sure object is not pointing to itself - assert( Ivy_ObjFanin0(pObjNew) == NULL || pObjOld != Ivy_ObjFanin0(pObjNew) ); - assert( Ivy_ObjFanin1(pObjNew) == NULL || pObjOld != Ivy_ObjFanin1(pObjNew) ); - // make sure the old node has no fanin fanout pointers - if ( p->fFanout ) - { - assert( pObjOld->pFanout != NULL ); - assert( pObjNew->pFanout == NULL ); - pObjNew->pFanout = pObjOld->pFanout; - } - // transfer the old object - assert( Ivy_ObjRefs(pObjNew) == 0 ); - nRefsOld = pObjOld->nRefs; - Ivy_ObjOverwrite( pObjOld, pObjNew ); - pObjOld->nRefs = nRefsOld; - // patch the fanout of the fanins - if ( p->fFanout ) - { - Ivy_ObjPatchFanout( p, Ivy_ObjFanin0(pObjOld), pObjNew, pObjOld ); - if ( Ivy_ObjFanin1(pObjOld) ) - Ivy_ObjPatchFanout( p, Ivy_ObjFanin1(pObjOld), pObjNew, pObjOld ); - } - // update the hash table - Ivy_TableUpdate( p, pObjNew, pObjOld->Id ); - // recycle the object that was taken over by pObjOld - Vec_PtrWriteEntry( p->vObjs, pObjNew->Id, NULL ); - Ivy_ManRecycleMemory( p, pObjNew ); - // if the new node is the buffer propagate it - if ( p->fFanout && Ivy_ObjIsBuf(pObjOld) ) - Vec_PtrPush( p->vBufs, pObjOld ); -// Ivy_ManCheckFanouts( p ); -// printf( "\n" ); -/* - if ( p->pHaig ) - { - int x; - Ivy_ManShow( p, 0, NULL ); - Ivy_ManShow( p->pHaig, 1, NULL ); - x = 0; - } -*/ -// if ( Ivy_ManCheckFanoutNums(p) ) -// { -// int x = 0; -// } -} - -/**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_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel ) -{ - Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult; - if ( Ivy_ObjIsPo(pNode) ) - { - if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) ) - return; - pFanReal0 = Ivy_ObjReal( Ivy_ObjChild0(pNode) ); - Ivy_ObjPatchFanin0( p, pNode, pFanReal0 ); -// Ivy_ManCheckFanouts( p ); - return; - } - if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) && !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) ) - return; - // get the real fanins - pFanReal0 = Ivy_ObjReal( Ivy_ObjChild0(pNode) ); - pFanReal1 = Ivy_ObjReal( Ivy_ObjChild1(pNode) ); - // get the new node - if ( Ivy_ObjIsNode(pNode) ) - pResult = Ivy_Oper( p, pFanReal0, pFanReal1, Ivy_ObjType(pNode) ); - else if ( Ivy_ObjIsLatch(pNode) ) - pResult = Ivy_Latch( p, pFanReal0, Ivy_ObjInit(pNode) ); - else - assert( 0 ); - -//printf( "===== Replacing %d by %d.\n", pNode->Id, pResult->Id ); -//Ivy_ObjPrintVerbose( p, pNode, 0 ); printf( "\n" ); -//Ivy_ObjPrintVerbose( p, pResult, 0 ); printf( "\n" ); - - // perform the replacement - Ivy_ObjReplace( p, pNode, pResult, 1, 0, fUpdateLevel ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyOper.c b/src/aig/ivy/ivyOper.c deleted file mode 100644 index 8115ce4f..00000000 --- a/src/aig/ivy/ivyOper.c +++ /dev/null @@ -1,293 +0,0 @@ -/**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_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type ) -{ - if ( Type == IVY_AND ) - return Ivy_And( p, p0, p1 ); - if ( Type == IVY_EXOR ) - return Ivy_Exor( p, 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_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ) -{ -// Ivy_Obj_t * pFan0, * pFan1; - // check trivial cases - if ( p0 == p1 ) - return p0; - if ( p0 == Ivy_Not(p1) ) - return Ivy_Not(p->pConst1); - if ( Ivy_Regular(p0) == p->pConst1 ) - return p0 == p->pConst1 ? p1 : Ivy_Not(p->pConst1); - if ( Ivy_Regular(p1) == p->pConst1 ) - return p1 == p->pConst1 ? p0 : Ivy_Not(p->pConst1); - // check if it can be an EXOR gate -// if ( Ivy_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) ) -// return Ivy_CanonExor( pFan0, pFan1 ); - return Ivy_CanonAnd( p, p0, p1 ); -} - -/**Function************************************************************* - - Synopsis [Performs canonicization step.] - - Description [The argument nodes can be complemented.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Exor( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ) -{ -/* - // check trivial cases - if ( p0 == p1 ) - return Ivy_Not(p->pConst1); - if ( p0 == Ivy_Not(p1) ) - return p->pConst1; - if ( Ivy_Regular(p0) == p->pConst1 ) - return Ivy_NotCond( p1, p0 == p->pConst1 ); - if ( Ivy_Regular(p1) == p->pConst1 ) - return Ivy_NotCond( p0, p1 == p->pConst1 ); - // check the table - return Ivy_CanonExor( p, p0, p1 ); -*/ - return Ivy_Or( p, Ivy_And(p, p0, Ivy_Not(p1)), Ivy_And(p, Ivy_Not(p0), p1) ); -} - -/**Function************************************************************* - - Synopsis [Implements Boolean OR.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Or( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ) -{ - return Ivy_Not( Ivy_And( p, Ivy_Not(p0), Ivy_Not(p1) ) ); -} - -/**Function************************************************************* - - Synopsis [Implements ITE operation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Mux( Ivy_Man_t * p, Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 ) -{ - Ivy_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp; - int Count0, Count1; - // consider trivial cases - if ( p0 == Ivy_Not(p1) ) - return Ivy_Exor( p, pC, p0 ); - // other cases can be added - // implement the first MUX (F = C * x1 + C' * x0) - pTempA1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pC, p1, IVY_AND, IVY_INIT_NONE) ); - pTempA2 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pC), p0, IVY_AND, IVY_INIT_NONE) ); - if ( pTempA1 && pTempA2 ) - { - pTemp = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, 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( p, Ivy_ObjCreateGhost(p, pC, Ivy_Not(p1), IVY_AND, IVY_INIT_NONE) ); - pTempB2 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pC), Ivy_Not(p0), IVY_AND, IVY_INIT_NONE) ); - if ( pTempB1 && pTempB2 ) - { - pTemp = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, 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(p, pC, p1); - pTempA2 = pTempA2? pTempA2 : Ivy_And(p, Ivy_Not(pC), p0); - return Ivy_Or( p, pTempA1, pTempA2 ); - } - pTempB1 = pTempB1? pTempB1 : Ivy_And(p, pC, Ivy_Not(p1)); - pTempB2 = pTempB2? pTempB2 : Ivy_And(p, Ivy_Not(pC), Ivy_Not(p0)); - return Ivy_Not( Ivy_Or( p, 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_Man_t * p, Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC ) -{ - return Ivy_Or( p, Ivy_Or(p, Ivy_And(p, pA, pB), Ivy_And(p, pA, pC)), Ivy_And(p, pB, pC) ); -} - -/**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_Man_t * p, 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( p, ppObjs, nObjs/2, Type ); - pObj2 = Ivy_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type ); - return Ivy_Oper( p, pObj1, pObj2, Type ); -} - -/**Function************************************************************* - - Synopsis [Old code.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Multi( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) -{ - assert( Type == IVY_AND || Type == IVY_EXOR ); - assert( nArgs > 0 ); - return Ivy_Multi_rec( p, pArgs, nArgs, Type ); -} - -/**Function************************************************************* - - Synopsis [Implements the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Miter( Ivy_Man_t * p, 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( p, vPairs->pArray[i], vPairs->pArray[i+1] ) ); - vPairs->nSize = vPairs->nSize/2; - return Ivy_Not( Ivy_Multi_rec( p, (Ivy_Obj_t **)vPairs->pArray, vPairs->nSize, IVY_AND ) ); -} - -/**Function************************************************************* - - Synopsis [Performs canonicization step.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Latch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init ) -{ - return Ivy_CanonLatch( p, pObj, Init ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyResyn.c b/src/aig/ivy/ivyResyn.c deleted file mode 100644 index f42d7464..00000000 --- a/src/aig/ivy/ivyResyn.c +++ /dev/null @@ -1,196 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyResyn.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [AIG rewriting script.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyResyn.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs several passes of rewriting on the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_ManResyn0( Ivy_Man_t * pMan, int fUpdateLevel, int fVerbose ) -{ - int clk; - Ivy_Man_t * pTemp; - -if ( fVerbose ) { printf( "Original:\n" ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - pMan = Ivy_ManBalance( pMan, fUpdateLevel ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Balance", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 0 ); -clk = clock(); - Ivy_ManRewritePre( pMan, fUpdateLevel, 0, 0 ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel ); - Ivy_ManStop( pTemp ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Balance", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - return pMan; -} - -/**Function************************************************************* - - Synopsis [Performs several passes of rewriting on the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * pMan, int fUpdateLevel, int fVerbose ) -{ - int clk; - Ivy_Man_t * pTemp; - -if ( fVerbose ) { printf( "Original:\n" ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - pMan = Ivy_ManBalance( pMan, fUpdateLevel ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Balance", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 0 ); -clk = clock(); - Ivy_ManRewritePre( pMan, fUpdateLevel, 0, 0 ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel ); - Ivy_ManStop( pTemp ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Balance", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 ); -clk = clock(); - Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel ); - Ivy_ManStop( pTemp ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Balance", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 ); -clk = clock(); - Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel ); - Ivy_ManStop( pTemp ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Balance", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - return pMan; -} - -/**Function************************************************************* - - Synopsis [Performs several passes of rewriting on the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Man_t * Ivy_ManRwsat( Ivy_Man_t * pMan, int fVerbose ) -{ - int clk; - Ivy_Man_t * pTemp; - -if ( fVerbose ) { printf( "Original:\n" ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - Ivy_ManRewritePre( pMan, 0, 0, 0 ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - pMan = Ivy_ManBalance( pTemp = pMan, 0 ); -// pMan = Ivy_ManDup( pTemp = pMan ); - Ivy_ManStop( pTemp ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Balance", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -/* -clk = clock(); - Ivy_ManRewritePre( pMan, 0, 0, 0 ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); - -clk = clock(); - pMan = Ivy_ManBalance( pTemp = pMan, 0 ); - Ivy_ManStop( pTemp ); -if ( fVerbose ) { printf( "\n" ); } -if ( fVerbose ) { PRT( "Balance", clock() - clk ); } -if ( fVerbose ) Ivy_ManPrintStats( pMan ); -*/ - return pMan; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyRwr.c b/src/aig/ivy/ivyRwr.c deleted file mode 100644 index 3f8720ba..00000000 --- a/src/aig/ivy/ivyRwr.c +++ /dev/null @@ -1,609 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyRwt.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [Rewriting based on precomputation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyRwt.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" -#include "deco.h" -#include "rwt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums ); -static int Ivy_NodeRewrite( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost ); -static Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, - Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth ); - -static int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ); -static void Ivy_GraphUpdateNetwork( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs incremental rewriting of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose ) -{ - Rwt_Man_t * pManRwt; - Ivy_Obj_t * pNode; - int i, nNodes, nGain; - int clk, clkStart = clock(); - // start the rewriting manager - pManRwt = Rwt_ManStart( 0 ); - p->pData = pManRwt; - if ( pManRwt == NULL ) - return 0; - // create fanouts - if ( fUpdateLevel && p->fFanout == 0 ) - Ivy_ManStartFanout( p ); - // compute the reverse levels if level update is requested - if ( fUpdateLevel ) - Ivy_ManRequiredLevels( p ); - // set the number of levels -// p->nLevelMax = Ivy_ManLevels( p ); - // resynthesize each node once - nNodes = Ivy_ManObjIdMax(p); - Ivy_ManForEachNode( p, pNode, i ) - { - // fix the fanin buffer problem - Ivy_NodeFixBufferFanins( p, pNode, 1 ); - if ( Ivy_ObjIsBuf(pNode) ) - continue; - // stop if all nodes have been tried once - if ( i > nNodes ) - break; - // for each cut, try to resynthesize it - nGain = Ivy_NodeRewrite( p, pManRwt, pNode, fUpdateLevel, fUseZeroCost ); - if ( nGain > 0 || nGain == 0 && fUseZeroCost ) - { - Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt); - int fCompl = Rwt_ManReadCompl(pManRwt); -/* - { - Ivy_Obj_t * pObj; - int i; - printf( "USING: (" ); - Vec_PtrForEachEntry( Rwt_ManReadLeaves(pManRwt), pObj, i ) - printf( "%d ", Ivy_ObjFanoutNum(Ivy_Regular(pObj)) ); - printf( ") Gain = %d.\n", nGain ); - } - if ( nGain > 0 ) - { // print stats on the MFFC - extern void Ivy_NodeMffsConeSuppPrint( Ivy_Obj_t * pNode ); - printf( "Node %6d : Gain = %4d ", pNode->Id, nGain ); - Ivy_NodeMffsConeSuppPrint( pNode ); - } -*/ - // complement the FF if needed -clk = clock(); - if ( fCompl ) Dec_GraphComplement( pGraph ); - Ivy_GraphUpdateNetwork( p, pNode, pGraph, fUpdateLevel, nGain ); - if ( fCompl ) Dec_GraphComplement( pGraph ); -Rwt_ManAddTimeUpdate( pManRwt, clock() - clk ); - } - } -Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart ); - // print stats - if ( fVerbose ) - Rwt_ManPrintStats( pManRwt ); - // delete the managers - Rwt_ManStop( pManRwt ); - p->pData = NULL; - // fix the levels - if ( fUpdateLevel ) - Vec_IntFree( p->vRequired ), p->vRequired = NULL; - else - Ivy_ManResetLevels( p ); - // check - if ( i = Ivy_ManCleanup(p) ) - printf( "Cleanup after rewriting removed %d dangling nodes.\n", i ); - if ( !Ivy_ManCheck(p) ) - printf( "Ivy_ManRewritePre(): The check has failed.\n" ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Performs rewriting for one node.] - - Description [This procedure considers all the cuts computed for the node - and tries to rewrite each of them using the "forest" of different AIG - structures precomputed and stored in the RWR manager. - Determines the best rewriting and computes the gain in the number of AIG - nodes in the final network. In the end, p->vFanins contains information - about the best cut that can be used for rewriting, while p->pGraph gives - the decomposition dag (represented using decomposition graph data structure). - Returns gain in the number of nodes or -1 if node cannot be rewritten.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeRewrite( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost ) -{ - int fVeryVerbose = 0; - Dec_Graph_t * pGraph; - Ivy_Store_t * pStore; - Ivy_Cut_t * pCut; - Ivy_Obj_t * pFanin; - unsigned uPhase, uTruthBest, uTruth; - char * pPerm; - int Required, nNodesSaved, nNodesSaveCur; - int i, c, GainCur, GainBest = -1; - int clk, clk2; - - p->nNodesConsidered++; - // get the required times - Required = fUpdateLevel? Vec_IntEntry( pMan->vRequired, pNode->Id ) : 1000000; - // get the node's cuts -clk = clock(); - pStore = Ivy_NodeFindCutsAll( pMan, pNode, 5 ); -p->timeCut += clock() - clk; - - // go through the cuts -clk = clock(); - for ( c = 1; c < pStore->nCuts; c++ ) - { - pCut = pStore->pCuts + c; - // consider only 4-input cuts - if ( pCut->nSize != 4 ) - continue; - // skip the cuts with buffers - for ( i = 0; i < (int)pCut->nSize; i++ ) - if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, pCut->pArray[i]) ) ) - break; - if ( i != pCut->nSize ) - { - p->nCutsBad++; - continue; - } - p->nCutsGood++; - // get the fanin permutation -clk2 = clock(); - uTruth = 0xFFFF & Ivy_NodeGetTruth( pNode, pCut->pArray, pCut->nSize ); // truth table -p->timeTruth += clock() - clk2; - pPerm = p->pPerms4[ p->pPerms[uTruth] ]; - uPhase = p->pPhases[uTruth]; - // collect fanins with the corresponding permutation/phase - Vec_PtrClear( p->vFaninsCur ); - Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 ); - for ( i = 0; i < (int)pCut->nSize; i++ ) - { - pFanin = Ivy_ManObj( pMan, pCut->pArray[pPerm[i]] ); - assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) ); - pFanin = Ivy_NotCond(pFanin, ((uPhase & (1< 0) ); - Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin ); - } -clk2 = clock(); -/* - printf( "Considering: (" ); - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - printf( "%d ", Ivy_ObjFanoutNum(Ivy_Regular(pFanin)) ); - printf( ")\n" ); -*/ - // mark the fanin boundary - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); - // label MFFC with current ID - Ivy_ManIncrementTravId( pMan ); - nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode ); - // unmark the fanin boundary - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); -p->timeMffc += clock() - clk2; - - // evaluate the cut -clk2 = clock(); - pGraph = Rwt_CutEvaluate( pMan, p, pNode, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth ); -p->timeEval += clock() - clk2; - - // check if the cut is better than the current best one - if ( pGraph != NULL && GainBest < GainCur ) - { - // save this form - nNodesSaveCur = nNodesSaved; - GainBest = GainCur; - p->pGraph = pGraph; - p->fCompl = ((uPhase & (1<<4)) > 0); - uTruthBest = uTruth; - // collect fanins in the - Vec_PtrClear( p->vFanins ); - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - Vec_PtrPush( p->vFanins, pFanin ); - } - } -p->timeRes += clock() - clk; - - if ( GainBest == -1 ) - return -1; - -// printf( "%d", nNodesSaveCur - GainBest ); -/* - if ( GainBest > 0 ) - { - if ( Rwt_CutIsintean( pNode, p->vFanins ) ) - printf( "b" ); - else - { - printf( "Node %d : ", pNode->Id ); - Vec_PtrForEachEntry( p->vFanins, pFanin, i ) - printf( "%d ", Ivy_Regular(pFanin)->Id ); - printf( "a" ); - } - } -*/ -/* - if ( GainBest > 0 ) - if ( p->fCompl ) - printf( "c" ); - else - printf( "." ); -*/ - - // copy the leaves - Vec_PtrForEachEntry( p->vFanins, pFanin, i ) - Dec_GraphNode(p->pGraph, i)->pFunc = pFanin; - - p->nScores[p->pMap[uTruthBest]]++; - p->nNodesGained += GainBest; - if ( fUseZeroCost || GainBest > 0 ) - p->nNodesRewritten++; - - // report the progress - if ( fVeryVerbose && GainBest > 0 ) - { - printf( "Node %6d : ", Ivy_ObjId(pNode) ); - printf( "Fanins = %d. ", p->vFanins->nSize ); - printf( "Save = %d. ", nNodesSaveCur ); - printf( "Add = %d. ", nNodesSaveCur-GainBest ); - printf( "GAIN = %d. ", GainBest ); - printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 ); - printf( "Class = %d. ", p->pMap[uTruthBest] ); - printf( "\n" ); - } - return GainBest; -} - -/**Function************************************************************* - - Synopsis [Computes the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Ivy_NodeGetTruth_rec( Ivy_Obj_t * pObj, int * pNums, int nNums ) -{ - static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; - unsigned uTruth0, uTruth1; - int i; - for ( i = 0; i < nNums; i++ ) - if ( pObj->Id == pNums[i] ) - return uMasks[i]; - assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) ); - uTruth0 = Ivy_NodeGetTruth_rec( Ivy_ObjFanin0(pObj), pNums, nNums ); - if ( Ivy_ObjFaninC0(pObj) ) - uTruth0 = ~uTruth0; - if ( Ivy_ObjIsBuf(pObj) ) - return uTruth0; - uTruth1 = Ivy_NodeGetTruth_rec( Ivy_ObjFanin1(pObj), pNums, nNums ); - if ( Ivy_ObjFaninC1(pObj) ) - uTruth1 = ~uTruth1; - return uTruth0 & uTruth1; -} - - -/**Function************************************************************* - - Synopsis [Computes the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums ) -{ - assert( nNums < 6 ); - return Ivy_NodeGetTruth_rec( pObj, pNums, nNums ); -} - -/**Function************************************************************* - - Synopsis [Evaluates the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth ) -{ - Vec_Ptr_t * vSubgraphs; - Dec_Graph_t * pGraphBest, * pGraphCur; - Rwt_Node_t * pNode, * pFanin; - int nNodesAdded, GainBest, i, k; - // find the matching class of subgraphs - vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); - p->nSubgraphs += vSubgraphs->nSize; - // determine the best subgraph - GainBest = -1; - Vec_PtrForEachEntry( vSubgraphs, pNode, i ) - { - // get the current graph - pGraphCur = (Dec_Graph_t *)pNode->pNext; - // copy the leaves - Vec_PtrForEachEntry( vFaninsCur, pFanin, k ) - Dec_GraphNode(pGraphCur, k)->pFunc = pFanin; - // detect how many unlabeled nodes will be reused - nNodesAdded = Ivy_GraphToNetworkCount( pMan, pRoot, pGraphCur, nNodesSaved, LevelMax ); - if ( nNodesAdded == -1 ) - continue; - assert( nNodesSaved >= nNodesAdded ); - // count the gain at this node - if ( GainBest < nNodesSaved - nNodesAdded ) - { - GainBest = nNodesSaved - nNodesAdded; - pGraphBest = pGraphCur; - } - } - if ( GainBest == -1 ) - return NULL; - *pGainBest = GainBest; - return pGraphBest; -} - - -/**Function************************************************************* - - Synopsis [Counts the number of new nodes added when using this graph.] - - Description [AIG nodes for the fanins should be assigned to pNode->pFunc - of the leaves of the graph before calling this procedure. - Returns -1 if the number of nodes and levels exceeded the given limit or - the number of levels exceeded the maximum allowed level.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ) -{ - Dec_Node_t * pNode, * pNode0, * pNode1; - Ivy_Obj_t * pAnd, * pAnd0, * pAnd1; - int i, Counter, LevelNew, LevelOld; - // check for constant function or a literal - if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) ) - return 0; - // set the levels of the leaves - Dec_GraphForEachLeaf( pGraph, pNode, i ) - pNode->Level = Ivy_Regular(pNode->pFunc)->Level; - // compute the AIG size after adding the internal nodes - Counter = 0; - Dec_GraphForEachNode( pGraph, pNode, i ) - { - // get the children of this node - pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); - pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); - // get the AIG nodes corresponding to the children - pAnd0 = pNode0->pFunc; - pAnd1 = pNode1->pFunc; - if ( pAnd0 && pAnd1 ) - { - // if they are both present, find the resulting node - pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl ); - pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl ); - pAnd = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) ); - // return -1 if the node is the same as the original root - if ( Ivy_Regular(pAnd) == pRoot ) - return -1; - } - else - pAnd = NULL; - // count the number of added nodes - if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(p, Ivy_Regular(pAnd)) ) - { - if ( ++Counter > NodeMax ) - return -1; - } - // count the number of new levels - LevelNew = 1 + RWT_MAX( pNode0->Level, pNode1->Level ); - if ( pAnd ) - { - if ( Ivy_Regular(pAnd) == p->pConst1 ) - LevelNew = 0; - else if ( Ivy_Regular(pAnd) == Ivy_Regular(pAnd0) ) - LevelNew = (int)Ivy_Regular(pAnd0)->Level; - else if ( Ivy_Regular(pAnd) == Ivy_Regular(pAnd1) ) - LevelNew = (int)Ivy_Regular(pAnd1)->Level; - LevelOld = (int)Ivy_Regular(pAnd)->Level; -// assert( LevelNew == LevelOld ); - } - if ( LevelNew > LevelMax ) - return -1; - pNode->pFunc = pAnd; - pNode->Level = LevelNew; - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Transforms the decomposition graph into the AIG.] - - Description [AIG nodes for the fanins should be assigned to pNode->pFunc - of the leaves of the graph before calling this procedure.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_GraphToNetwork( Ivy_Man_t * p, Dec_Graph_t * pGraph ) -{ - Ivy_Obj_t * pAnd0, * pAnd1; - Dec_Node_t * pNode; - int i; - // check for constant function - if ( Dec_GraphIsConst(pGraph) ) - return Ivy_NotCond( Ivy_ManConst1(p), 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( p, pAnd0, pAnd1 ); - } - // complement the result if necessary - return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); -} - -/**Function************************************************************* - - Synopsis [Replaces MFFC of the node by the new factored form.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_GraphUpdateNetwork( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ) -{ - Ivy_Obj_t * pRootNew; - int nNodesNew, nNodesOld, Required; - Required = fUpdateLevel? Vec_IntEntry( p->vRequired, pRoot->Id ) : 1000000; - nNodesOld = Ivy_ManNodeNum(p); - // create the new structure of nodes - pRootNew = Ivy_GraphToNetwork( p, pGraph ); - assert( (int)Ivy_Regular(pRootNew)->Level <= Required ); -// if ( Ivy_Regular(pRootNew)->Level == Required ) -// printf( "Difference %d.\n", Ivy_Regular(pRootNew)->Level - Required ); - // remove the old nodes -// Ivy_AigReplace( pMan->pManFunc, pRoot, pRootNew, fUpdateLevel ); -/* - if ( Ivy_IsComplement(pRootNew) ) - printf( "c" ); - else - printf( "d" ); - if ( Ivy_ObjRefs(Ivy_Regular(pRootNew)) > 0 ) - printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) ); - printf( " " ); -*/ - Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 1 ); - // compare the gains - nNodesNew = Ivy_ManNodeNum(p); - assert( nGain <= nNodesOld - nNodesNew ); - // propagate the buffer - Ivy_ManPropagateBuffers( p, 1 ); -} - -/**Function************************************************************* - - Synopsis [Replaces MFFC of the node by the new factored form.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ) -{ - Ivy_Obj_t * pRootNew, * pFanin; - int nNodesNew, nNodesOld, i, nRefsOld; - nNodesOld = Ivy_ManNodeNum(p); - -//printf( "Before = %d. ", Ivy_ManNodeNum(p) ); - // mark the cut - Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) - Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); - // deref the old cone - nRefsOld = pRoot->nRefs; - pRoot->nRefs = 0; - Ivy_ObjDelete_rec( p, pRoot, 0 ); - pRoot->nRefs = nRefsOld; - // unmark the cut - Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) - Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); -//printf( "Deref = %d. ", Ivy_ManNodeNum(p) ); - - // create the new structure of nodes - pRootNew = Ivy_GraphToNetwork( p, pGraph ); -//printf( "Create = %d. ", Ivy_ManNodeNum(p) ); - // remove the old nodes -// Ivy_AigReplace( pMan->pManFunc, pRoot, pRootNew, fUpdateLevel ); -/* - if ( Ivy_IsComplement(pRootNew) ) - printf( "c" ); - else - printf( "d" ); - if ( Ivy_ObjRefs(Ivy_Regular(pRootNew)) > 0 ) - printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) ); - printf( " " ); -*/ - Ivy_ObjReplace( p, pRoot, pRootNew, 0, 0, 1 ); -//printf( "Replace = %d. ", Ivy_ManNodeNum(p) ); - - // delete remaining dangling nodes - Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i ) - { - pFanin = Ivy_Regular(pFanin); - if ( !Ivy_ObjIsNone(pFanin) && Ivy_ObjRefs(pFanin) == 0 ) - Ivy_ObjDelete_rec( p, pFanin, 1 ); - } -//printf( "Deref = %d. ", Ivy_ManNodeNum(p) ); -//printf( "\n" ); - - // compare the gains - nNodesNew = Ivy_ManNodeNum(p); - assert( nGain <= nNodesOld - nNodesNew ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyRwrAlg.c b/src/aig/ivy/ivyRwrAlg.c deleted file mode 100644 index fc48deb0..00000000 --- a/src/aig/ivy/ivyRwrAlg.c +++ /dev/null @@ -1,408 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyRwrAlg.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [Algebraic AIG rewriting.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyRwrAlg.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone ); -static Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vSols, int LevelR, int fUseZeroCost ); -static int Ivy_NodeCountMffc( Ivy_Obj_t * pNode ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Algebraic AIG rewriting.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ) -{ - Vec_Int_t * vRequired; - Vec_Ptr_t * vFront, * vLeaves, * vCone, * vSol; - Ivy_Obj_t * pObj, * pResult; - int i, RetValue, LevelR, nNodesOld; - int CountUsed, CountUndo; - vRequired = fUpdateLevel? Ivy_ManRequiredLevels( p ) : NULL; - vFront = Vec_PtrAlloc( 100 ); - vLeaves = Vec_PtrAlloc( 100 ); - vCone = Vec_PtrAlloc( 100 ); - vSol = Vec_PtrAlloc( 100 ); - // go through the nodes in the topological order - CountUsed = CountUndo = 0; - nNodesOld = Ivy_ManObjIdNext(p); - Ivy_ManForEachObj( p, pObj, i ) - { - assert( !Ivy_ObjIsBuf(pObj) ); - if ( i >= nNodesOld ) - break; - // skip no-nodes and MUX roots - if ( !Ivy_ObjIsNode(pObj) || Ivy_ObjIsExor(pObj) || Ivy_ObjIsMuxType(pObj) ) - continue; -// if ( pObj->Id > 297 ) // 296 --- 297 -// break; - if ( pObj->Id == 297 ) - { - int x = 0; - } - // get the largest algebraic cut - RetValue = Ivy_ManFindAlgCut( pObj, vFront, vLeaves, vCone ); - // the case of a trivial tree cut - if ( RetValue == 1 ) - continue; - // the case of constant 0 cone - if ( RetValue == -1 ) - { - Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0, 1 ); - continue; - } - assert( Vec_PtrSize(vLeaves) > 2 ); - // get the required level for this node - LevelR = vRequired? Vec_IntEntry(vRequired, pObj->Id) : 1000000; - // create a new cone - pResult = Ivy_NodeRewriteAlg( pObj, vFront, vLeaves, vCone, vSol, LevelR, fUseZeroCost ); - if ( pResult == NULL || pResult == pObj ) - continue; - assert( Vec_PtrSize(vSol) == 1 || !Ivy_IsComplement(pResult) ); - if ( Ivy_ObjLevel(Ivy_Regular(pResult)) > LevelR && Ivy_ObjRefs(Ivy_Regular(pResult)) == 0 ) - Ivy_ObjDelete_rec(Ivy_Regular(pResult), 1), CountUndo++; - else - Ivy_ObjReplace( pObj, pResult, 1, 0, 1 ), CountUsed++; - } - printf( "Used = %d. Undo = %d.\n", CountUsed, CountUndo ); - Vec_PtrFree( vFront ); - Vec_PtrFree( vCone ); - Vec_PtrFree( vSol ); - if ( vRequired ) Vec_IntFree( vRequired ); - if ( i = Ivy_ManCleanup(p) ) - printf( "Cleanup after rewriting removed %d dangling nodes.\n", i ); - if ( !Ivy_ManCheck(p) ) - printf( "Ivy_ManRewriteAlg(): The check has failed.\n" ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Analizes one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vSols, int LevelR, int fUseZeroCost ) -{ - int fVerbose = 0; - Ivy_Obj_t * pTemp; - int k, Counter, nMffc, RetValue; - - if ( fVerbose ) - { - if ( Ivy_ObjIsExor(pObj) ) - printf( "x " ); - else - printf( " " ); - } - -/* - printf( "%d ", Vec_PtrSize(vFront) ); - printf( "( " ); - Vec_PtrForEachEntry( vFront, pTemp, k ) - printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) ); - printf( ")\n" ); -*/ - // collect nodes in the cone - if ( Ivy_ObjIsExor(pObj) ) - Ivy_ManCollectCone( pObj, vFront, vCone ); - else - Ivy_ManCollectCone( pObj, vLeaves, vCone ); - - // deref nodes in the cone - Vec_PtrForEachEntry( vCone, pTemp, k ) - { - Ivy_ObjRefsDec( Ivy_ObjFanin0(pTemp) ); - Ivy_ObjRefsDec( Ivy_ObjFanin1(pTemp) ); - pTemp->fMarkB = 1; - } - - // count the MFFC size - Vec_PtrForEachEntry( vFront, pTemp, k ) - Ivy_Regular(pTemp)->fMarkA = 1; - nMffc = Ivy_NodeCountMffc( pObj ); - Vec_PtrForEachEntry( vFront, pTemp, k ) - Ivy_Regular(pTemp)->fMarkA = 0; - - if ( fVerbose ) - { - Counter = 0; - Vec_PtrForEachEntry( vCone, pTemp, k ) - Counter += (Ivy_ObjRefs(pTemp) > 0); - printf( "%5d : Leaves = %2d. Cone = %2d. ConeRef = %2d. Mffc = %d. Lev = %d. LevR = %d.\n", - pObj->Id, Vec_PtrSize(vFront), Vec_PtrSize(vCone), Counter-1, nMffc, Ivy_ObjLevel(pObj), LevelR ); - } -/* - printf( "Leaves:" ); - Vec_PtrForEachEntry( vLeaves, pTemp, k ) - printf( " %d%s", Ivy_Regular(pTemp)->Id, Ivy_IsComplement(pTemp)? "\'" : "" ); - printf( "\n" ); - printf( "Cone:\n" ); - Vec_PtrForEachEntry( vCone, pTemp, k ) - printf( " %5d = %d%s %d%s\n", pTemp->Id, - Ivy_ObjFaninId0(pTemp), Ivy_ObjFaninC0(pTemp)? "\'" : "", - Ivy_ObjFaninId1(pTemp), Ivy_ObjFaninC1(pTemp)? "\'" : "" ); -*/ - - RetValue = Ivy_MultiPlus( vLeaves, vCone, Ivy_ObjType(pObj), nMffc + fUseZeroCost, vSols ); - - // ref nodes in the cone - Vec_PtrForEachEntry( vCone, pTemp, k ) - { - Ivy_ObjRefsInc( Ivy_ObjFanin0(pTemp) ); - Ivy_ObjRefsInc( Ivy_ObjFanin1(pTemp) ); - pTemp->fMarkA = 0; - pTemp->fMarkB = 0; - } - - if ( !RetValue ) - return NULL; - - if ( Vec_PtrSize( vSols ) == 1 ) - return Vec_PtrEntry( vSols, 0 ); - return Ivy_NodeBalanceBuildSuper( vSols, Ivy_ObjType(pObj), 1 ); -} - -/**Function************************************************************* - - Synopsis [Comparison for node pointers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeCountMffc_rec( Ivy_Obj_t * pNode ) -{ - if ( Ivy_ObjRefs(pNode) > 0 || Ivy_ObjIsCi(pNode) || pNode->fMarkA ) - return 0; - assert( pNode->fMarkB ); - pNode->fMarkA = 1; -// printf( "%d ", pNode->Id ); - if ( Ivy_ObjIsBuf(pNode) ) - return Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ); - return 1 + Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ) + Ivy_NodeCountMffc_rec( Ivy_ObjFanin1(pNode) ); -} - -/**Function************************************************************* - - Synopsis [Comparison for node pointers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeCountMffc( Ivy_Obj_t * pNode ) -{ - assert( pNode->fMarkB ); - return 1 + Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ) + Ivy_NodeCountMffc_rec( Ivy_ObjFanin1(pNode) ); -} - -/**Function************************************************************* - - Synopsis [Comparison for node pointers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManFindAlgCutCompare( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 ) -{ - if ( *pp1 < *pp2 ) - return -1; - if ( *pp1 > *pp2 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Computing one algebraic cut.] - - Description [Returns 1 if the tree-leaves of this node where traversed - and found to have no external references (and have not been collected). - Returns 0 if the tree-leaves have external references and are collected.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManFindAlgCut_rec( Ivy_Obj_t * pObj, Ivy_Type_t Type, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone ) -{ - int RetValue0, RetValue1; - Ivy_Obj_t * pObjR = Ivy_Regular(pObj); - assert( !Ivy_ObjIsBuf(pObjR) ); - assert( Type != IVY_EXOR || !Ivy_IsComplement(pObj) ); - - // make sure the node is not visited twice in different polarities - if ( Ivy_IsComplement(pObj) ) - { // if complemented, mark B - if ( pObjR->fMarkA ) - return -1; - pObjR->fMarkB = 1; - } - else - { // if non-complicated, mark A - if ( pObjR->fMarkB ) - return -1; - pObjR->fMarkA = 1; - } - Vec_PtrPush( vCone, pObjR ); - - // if the node is the end of the tree, return - if ( Ivy_IsComplement(pObj) || Ivy_ObjType(pObj) != Type ) - { - if ( Ivy_ObjRefs(pObjR) == 1 ) - return 1; - assert( Ivy_ObjRefs(pObjR) > 1 ); - Vec_PtrPush( vFront, pObj ); - return 0; - } - - // branch on the node - assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjIsNode(pObj) ); - // what if buffer has more than one fanout??? - RetValue0 = Ivy_ManFindAlgCut_rec( Ivy_ObjReal( Ivy_ObjChild0(pObj) ), Type, vFront, vCone ); - RetValue1 = Ivy_ManFindAlgCut_rec( Ivy_ObjReal( Ivy_ObjChild1(pObj) ), Type, vFront, vCone ); - if ( RetValue0 == -1 || RetValue1 == -1 ) - return -1; - - // the case when both have no external references - if ( RetValue0 && RetValue1 ) - { - if ( Ivy_ObjRefs(pObj) == 1 ) - return 1; - assert( Ivy_ObjRefs(pObj) > 1 ); - Vec_PtrPush( vFront, pObj ); - return 0; - } - // the case when one of them has external references - if ( RetValue0 ) - Vec_PtrPush( vFront, Ivy_ObjReal( Ivy_ObjChild0(pObj) ) ); - if ( RetValue1 ) - Vec_PtrPush( vFront, Ivy_ObjReal( Ivy_ObjChild1(pObj) ) ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Computing one algebraic cut.] - - Description [Algebraic cut stops when we hit (a) CI, (b) complemented edge, - (c) boundary of different gates. Returns 1 if this is a pure tree. - Returns -1 if the contant 0 is detected. Return 0 if the array can be used.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone ) -{ - Ivy_Obj_t * pObj, * pPrev; - int RetValue, i; - assert( !Ivy_IsComplement(pRoot) ); - assert( Ivy_ObjIsNode(pRoot) ); - // clear the frontier and collect the nodes - Vec_PtrClear( vCone ); - Vec_PtrClear( vFront ); - Vec_PtrClear( vLeaves ); - RetValue = Ivy_ManFindAlgCut_rec( pRoot, Ivy_ObjType(pRoot), vFront, vCone ); - // clean the marks - Vec_PtrForEachEntry( vCone, pObj, i ) - pObj->fMarkA = pObj->fMarkB = 0; - // quit if the same node is found in both polarities - if ( RetValue == -1 ) - return -1; - // return if the node is the root of a tree - if ( RetValue == 1 ) - return 1; - // return if the cut is composed of two nodes - if ( Vec_PtrSize(vFront) <= 2 ) - return 1; - // sort the entries in increasing order - Vec_PtrSort( vFront, Ivy_ManFindAlgCutCompare ); - // remove duplicates from vFront and save the nodes in vLeaves - pPrev = Vec_PtrEntry(vFront, 0); - Vec_PtrPush( vLeaves, pPrev ); - Vec_PtrForEachEntryStart( vFront, pObj, i, 1 ) - { - // compare current entry and the previous entry - if ( pObj == pPrev ) - { - if ( Ivy_ObjIsExor(pRoot) ) // A <+> A = 0 - { - // vLeaves are no longer structural support of pRoot!!! - Vec_PtrPop(vLeaves); - pPrev = Vec_PtrSize(vLeaves) == 0 ? NULL : Vec_PtrEntryLast(vLeaves); - } - continue; - } - if ( pObj == Ivy_Not(pPrev) ) - { - assert( Ivy_ObjIsAnd(pRoot) ); - return -1; - } - pPrev = pObj; - Vec_PtrPush( vLeaves, pObj ); - } - if ( Vec_PtrSize(vLeaves) == 0 ) - return -1; - if ( Vec_PtrSize(vLeaves) <= 2 ) - return 1; - return 0; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivySeq.c b/src/aig/ivy/ivySeq.c deleted file mode 100644 index 0ee29fee..00000000 --- a/src/aig/ivy/ivySeq.c +++ /dev/null @@ -1,1134 +0,0 @@ -/**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" -#include "deco.h" -#include "rwt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUseZeroCost ); -static void Ivy_GraphPrepare( Dec_Graph_t * pGraph, Ivy_Cut_t * pCut, Vec_Ptr_t * vFanins, char * pPerm ); -static unsigned Ivy_CutGetTruth( Ivy_Man_t * p, Ivy_Obj_t * pObj, int * pNums, int nNums ); -static Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, char * pPerm, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int * pGainBest, unsigned uTruth ); -static int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax ); -static Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph ); -static void Ivy_GraphUpdateNetworkSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain ); -static Ivy_Store_t * Ivy_CutComputeForNode( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves ); - -static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//int nMoves; -//int nMovesS; -//int nClauses; -//int timeInv; - -/**Function************************************************************* - - Synopsis [Performs incremental rewriting of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose ) -{ - Rwt_Man_t * pManRwt; - Ivy_Obj_t * pNode; - int i, nNodes, nGain; - int clk, clkStart = clock(); - - // set the DC latch values - Ivy_ManForEachLatch( p, pNode, i ) - pNode->Init = IVY_INIT_DC; - // start the rewriting manager - pManRwt = Rwt_ManStart( 0 ); - p->pData = pManRwt; - if ( pManRwt == NULL ) - return 0; - // create fanouts - if ( p->fFanout == 0 ) - Ivy_ManStartFanout( p ); - // resynthesize each node once - nNodes = Ivy_ManObjIdMax(p); - Ivy_ManForEachNode( p, pNode, i ) - { - assert( !Ivy_ObjIsBuf(pNode) ); - assert( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) ); - assert( !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) ); - // fix the fanin buffer problem -// Ivy_NodeFixBufferFanins( p, pNode ); -// if ( Ivy_ObjIsBuf(pNode) ) -// continue; - // stop if all nodes have been tried once - if ( i > nNodes ) - break; - // for each cut, try to resynthesize it - nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost ); - if ( nGain > 0 || nGain == 0 && fUseZeroCost ) - { - Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt); - int fCompl = Rwt_ManReadCompl(pManRwt); - // complement the FF if needed -clk = clock(); - if ( fCompl ) Dec_GraphComplement( pGraph ); - Ivy_GraphUpdateNetworkSeq( p, pNode, pGraph, nGain ); - if ( fCompl ) Dec_GraphComplement( pGraph ); -Rwt_ManAddTimeUpdate( pManRwt, clock() - clk ); - } - } -Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart ); - // print stats - if ( fVerbose ) - Rwt_ManPrintStats( pManRwt ); - // delete the managers - Rwt_ManStop( pManRwt ); - p->pData = NULL; - // fix the levels - Ivy_ManResetLevels( p ); -// if ( Ivy_ManCheckFanoutNums(p) ) -// printf( "Ivy_ManRewritePre(): The check has failed.\n" ); - // check - if ( !Ivy_ManCheck(p) ) - printf( "Ivy_ManRewritePre(): The check has failed.\n" ); - return 1; -} - - -/**Function************************************************************* - - Synopsis [Performs rewriting for one node.] - - Description [This procedure considers all the cuts computed for the node - and tries to rewrite each of them using the "forest" of different AIG - structures precomputed and stored in the RWR manager. - Determines the best rewriting and computes the gain in the number of AIG - nodes in the final network. In the end, p->vFanins contains information - about the best cut that can be used for rewriting, while p->pGraph gives - the decomposition dag (represented using decomposition graph data structure). - Returns gain in the number of nodes or -1 if node cannot be rewritten.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUseZeroCost ) -{ - int fVeryVerbose = 0; - Dec_Graph_t * pGraph; - Ivy_Store_t * pStore; - Ivy_Cut_t * pCut; - Ivy_Obj_t * pFanin;//, * pFanout; - Vec_Ptr_t * vFanout; - unsigned uPhase, uTruthBest, uTruth;//, nNewClauses; - char * pPerm; - int nNodesSaved, nNodesSaveCur; - int i, c, GainCur, GainBest = -1; - int clk, clk2;//, clk3; - - p->nNodesConsidered++; - // get the node's cuts -clk = clock(); - pStore = Ivy_CutComputeForNode( pMan, pNode, 5 ); -p->timeCut += clock() - clk; - - // go through the cuts -clk = clock(); - vFanout = Vec_PtrAlloc( 100 ); - for ( c = 1; c < pStore->nCuts; c++ ) - { - pCut = pStore->pCuts + c; - // consider only 4-input cuts - if ( pCut->nSize != 4 ) - continue; - // skip the cuts with buffers - for ( i = 0; i < (int)pCut->nSize; i++ ) - if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, Ivy_LeafId(pCut->pArray[i])) ) ) - break; - if ( i != pCut->nSize ) - { - p->nCutsBad++; - continue; - } - p->nCutsGood++; - // get the fanin permutation -clk2 = clock(); - uTruth = 0xFFFF & Ivy_CutGetTruth( pMan, pNode, pCut->pArray, pCut->nSize ); // truth table -p->timeTruth += clock() - clk2; - pPerm = p->pPerms4[ p->pPerms[uTruth] ]; - uPhase = p->pPhases[uTruth]; - // collect fanins with the corresponding permutation/phase - Vec_PtrClear( p->vFaninsCur ); - Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 ); - for ( i = 0; i < (int)pCut->nSize; i++ ) - { - pFanin = Ivy_ManObj( pMan, Ivy_LeafId( pCut->pArray[pPerm[i]] ) ); - assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) || Ivy_ObjIsConst1(pFanin) ); - pFanin = Ivy_NotCond(pFanin, ((uPhase & (1< 0) ); - Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin ); - } -clk2 = clock(); - // mark the fanin boundary - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); - // label MFFC with current ID - Ivy_ManIncrementTravId( pMan ); - nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode ); - // label fanouts with the current ID -// Ivy_ObjForEachFanout( pMan, pNode, vFanout, pFanout, i ) -// Ivy_ObjSetTravIdCurrent( pMan, pFanout ); - // unmark the fanin boundary - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); -p->timeMffc += clock() - clk2; - - // evaluate the cut -clk2 = clock(); - pGraph = Rwt_CutEvaluateSeq( pMan, p, pNode, pCut, pPerm, p->vFaninsCur, nNodesSaved, &GainCur, uTruth ); -p->timeEval += clock() - clk2; - - - // check if the cut is better than the current best one - if ( pGraph != NULL && GainBest < GainCur ) - { - // save this form - nNodesSaveCur = nNodesSaved; - GainBest = GainCur; - p->pGraph = pGraph; - p->pCut = pCut; - p->pPerm = pPerm; - p->fCompl = ((uPhase & (1<<4)) > 0); - uTruthBest = uTruth; - // collect fanins in the - Vec_PtrClear( p->vFanins ); - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - Vec_PtrPush( p->vFanins, pFanin ); - } - } - Vec_PtrFree( vFanout ); -p->timeRes += clock() - clk; - - if ( GainBest == -1 ) - return -1; -/* - { - Ivy_Cut_t * pCut = p->pCut; - printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) ); - for ( i = 0; i < pCut->nSize; i++ ) - printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) ); - printf( " }\n" ); - } -*/ - -//clk3 = clock(); -//nNewClauses = Ivy_CutTruthPrint( pMan, p->pCut, uTruth ); -//timeInv += clock() - clk; - -// nClauses += nNewClauses; -// nMoves++; -// if ( nNewClauses > 0 ) -// nMovesS++; - - // copy the leaves - Ivy_GraphPrepare( p->pGraph, p->pCut, p->vFanins, p->pPerm ); - - p->nScores[p->pMap[uTruthBest]]++; - p->nNodesGained += GainBest; - if ( fUseZeroCost || GainBest > 0 ) - p->nNodesRewritten++; - -/* - if ( GainBest > 0 ) - { - Ivy_Cut_t * pCut = p->pCut; - printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) ); - for ( i = 0; i < pCut->nSize; i++ ) - printf( " %5d(%2d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) ); - printf( " }\n" ); - } -*/ - - // report the progress - if ( fVeryVerbose && GainBest > 0 ) - { - printf( "Node %6d : ", Ivy_ObjId(pNode) ); - printf( "Fanins = %d. ", p->vFanins->nSize ); - printf( "Save = %d. ", nNodesSaveCur ); - printf( "Add = %d. ", nNodesSaveCur-GainBest ); - printf( "GAIN = %d. ", GainBest ); - printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 ); - printf( "Class = %d. ", p->pMap[uTruthBest] ); - printf( "\n" ); - } - return GainBest; -} - - -/**Function************************************************************* - - Synopsis [Evaluates the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, char * pPerm, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int * pGainBest, unsigned uTruth ) -{ - Vec_Ptr_t * vSubgraphs; - Dec_Graph_t * pGraphBest, * pGraphCur; - Rwt_Node_t * pNode; - int nNodesAdded, GainBest, i; - // find the matching class of subgraphs - vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); - p->nSubgraphs += vSubgraphs->nSize; - // determine the best subgraph - GainBest = -1; - Vec_PtrForEachEntry( vSubgraphs, pNode, i ) - { - // get the current graph - pGraphCur = (Dec_Graph_t *)pNode->pNext; - -// if ( pRoot->Id == 8648 ) -// Dec_GraphPrint( stdout, pGraphCur, NULL, NULL ); - // copy the leaves -// Vec_PtrForEachEntry( vFaninsCur, pFanin, k ) -// Dec_GraphNode(pGraphCur, k)->pFunc = pFanin; - Ivy_GraphPrepare( pGraphCur, pCut, vFaninsCur, pPerm ); - - // detect how many unlabeled nodes will be reused - nNodesAdded = Ivy_GraphToNetworkSeqCountSeq( pMan, pRoot, pGraphCur, nNodesSaved ); - if ( nNodesAdded == -1 ) - continue; - assert( nNodesSaved >= nNodesAdded ); - // count the gain at this node - if ( GainBest < nNodesSaved - nNodesAdded ) - { - GainBest = nNodesSaved - nNodesAdded; - pGraphBest = pGraphCur; - } - } - if ( GainBest == -1 ) - return NULL; - *pGainBest = GainBest; - return pGraphBest; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_GraphPrepare( Dec_Graph_t * pGraph, Ivy_Cut_t * pCut, Vec_Ptr_t * vFanins, char * pPerm ) -{ - Dec_Node_t * pNode, * pNode0, * pNode1; - int i; - assert( Dec_GraphLeaveNum(pGraph) == pCut->nSize ); - assert( Vec_PtrSize(vFanins) == pCut->nSize ); - // label the leaves with latch numbers - Dec_GraphForEachLeaf( pGraph, pNode, i ) - { - pNode->pFunc = Vec_PtrEntry( vFanins, i ); - pNode->nLat2 = Ivy_LeafLat( pCut->pArray[pPerm[i]] ); - } - // propagate latches through the nodes - Dec_GraphForEachNode( pGraph, pNode, i ) - { - // get the children of this node - pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); - pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); - // distribute the latches - pNode->nLat2 = IVY_MIN( pNode0->nLat2, pNode1->nLat2 ); - pNode->nLat0 = pNode0->nLat2 - pNode->nLat2; - pNode->nLat1 = pNode1->nLat2 - pNode->nLat2; - } -} - -/**Function************************************************************* - - Synopsis [Counts the number of new nodes added when using this graph.] - - Description [AIG nodes for the fanins should be assigned to pNode->pFunc - of the leaves of the graph before calling this procedure. - Returns -1 if the number of nodes and levels exceeded the given limit or - the number of levels exceeded the maximum allowed level.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax ) -{ - Dec_Node_t * pNode, * pNode0, * pNode1; - Ivy_Obj_t * pAnd, * pAnd0, * pAnd1; - int i, k, Counter, fCompl; - // check for constant function or a literal - if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) ) - return 0; - // compute the AIG size after adding the internal nodes - Counter = 0; - Dec_GraphForEachNode( pGraph, pNode, i ) - { - // get the children of this node - pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); - pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); - // get the AIG nodes corresponding to the children - pAnd0 = pNode0->pFunc; - pAnd1 = pNode1->pFunc; - // skip the latches - for ( k = 0; pAnd0 && k < (int)pNode->nLat0; k++ ) - { - fCompl = Ivy_IsComplement(pAnd0); - pAnd0 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd0), NULL, IVY_LATCH, IVY_INIT_DC) ); - if ( pAnd0 ) - pAnd0 = Ivy_NotCond( pAnd0, fCompl ); - } - for ( k = 0; pAnd1 && k < (int)pNode->nLat1; k++ ) - { - fCompl = Ivy_IsComplement(pAnd1); - pAnd1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd1), NULL, IVY_LATCH, IVY_INIT_DC) ); - if ( pAnd1 ) - pAnd1 = Ivy_NotCond( pAnd1, fCompl ); - } - // get the new node - if ( pAnd0 && pAnd1 ) - { - // if they are both present, find the resulting node - pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl ); - pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl ); - assert( !Ivy_ObjIsLatch(Ivy_Regular(pAnd0)) || !Ivy_ObjIsLatch(Ivy_Regular(pAnd1)) ); - if ( Ivy_Regular(pAnd0) == Ivy_Regular(pAnd1) || Ivy_ObjIsConst1(Ivy_Regular(pAnd0)) || Ivy_ObjIsConst1(Ivy_Regular(pAnd1)) ) - pAnd = Ivy_And( p, pAnd0, pAnd1 ); - else - pAnd = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) ); - // return -1 if the node is the same as the original root - if ( Ivy_Regular(pAnd) == pRoot ) - return -1; - } - else - pAnd = NULL; - // count the number of added nodes - if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(p, Ivy_Regular(pAnd)) ) - { - if ( ++Counter > NodeMax ) - return -1; - } - pNode->pFunc = pAnd; - } - return Counter; -} - - -/**Function************************************************************* - - Synopsis [Transforms the decomposition graph into the AIG.] - - Description [AIG nodes for the fanins should be assigned to pNode->pFunc - of the leaves of the graph before calling this procedure.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph ) -{ - Ivy_Obj_t * pAnd0, * pAnd1; - Dec_Node_t * pNode; - int i, k; - // check for constant function - if ( Dec_GraphIsConst(pGraph) ) - return Ivy_NotCond( Ivy_ManConst1(p), Dec_GraphIsComplement(pGraph) ); - // check for a literal - if ( Dec_GraphIsVar(pGraph) ) - { - // get the variable node - pNode = Dec_GraphVar(pGraph); - // add the remaining latches - for ( k = 0; k < (int)pNode->nLat2; k++ ) - pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC ); - return Ivy_NotCond( pNode->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 ); - // add the latches - for ( k = 0; k < (int)pNode->nLat0; k++ ) - pAnd0 = Ivy_Latch( p, pAnd0, IVY_INIT_DC ); - for ( k = 0; k < (int)pNode->nLat1; k++ ) - pAnd1 = Ivy_Latch( p, pAnd1, IVY_INIT_DC ); - // create the node - pNode->pFunc = Ivy_And( p, pAnd0, pAnd1 ); - } - // add the remaining latches - for ( k = 0; k < (int)pNode->nLat2; k++ ) - pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC ); - // complement the result if necessary - return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); -} - -/**Function************************************************************* - - Synopsis [Replaces MFFC of the node by the new factored form.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_GraphUpdateNetworkSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain ) -{ - Ivy_Obj_t * pRootNew; - int nNodesNew, nNodesOld; - nNodesOld = Ivy_ManNodeNum(p); - // create the new structure of nodes - pRootNew = Ivy_GraphToNetworkSeq( p, pGraph ); - Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 0 ); - // compare the gains - nNodesNew = Ivy_ManNodeNum(p); - assert( nGain <= nNodesOld - nNodesNew ); - // propagate the buffer - Ivy_ManPropagateBuffers( p, 0 ); -} - - - - - - - - - -/**Function************************************************************* - - Synopsis [Computes the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Ivy_CutGetTruth_rec( Ivy_Man_t * p, int Leaf, int * pNums, int nNums ) -{ - static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; - unsigned uTruth0, uTruth1; - Ivy_Obj_t * pObj; - int i; - for ( i = 0; i < nNums; i++ ) - if ( Leaf == pNums[i] ) - return uMasks[i]; - pObj = Ivy_ManObj( p, Ivy_LeafId(Leaf) ); - if ( Ivy_ObjIsLatch(pObj) ) - { - assert( !Ivy_ObjFaninC0(pObj) ); - Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) + 1 ); - return Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); - } - assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) ); - Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) ); - uTruth0 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); - if ( Ivy_ObjFaninC0(pObj) ) - uTruth0 = ~uTruth0; - if ( Ivy_ObjIsBuf(pObj) ) - return uTruth0; - Leaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pObj), Ivy_LeafLat(Leaf) ); - uTruth1 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); - if ( Ivy_ObjFaninC1(pObj) ) - uTruth1 = ~uTruth1; - return uTruth0 & uTruth1; -} - - -/**Function************************************************************* - - Synopsis [Computes the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Ivy_CutGetTruth( Ivy_Man_t * p, Ivy_Obj_t * pObj, int * pNums, int nNums ) -{ - assert( Ivy_ObjIsNode(pObj) ); - assert( nNums < 6 ); - return Ivy_CutGetTruth_rec( p, Ivy_LeafCreate(pObj->Id, 0), pNums, nNums ); -} - - - - - -/**Function************************************************************* - - Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_CutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 ) -{ - int i; - if ( pCut->nSize < pCut->nSizeMax ) - return 1; - for ( i = 0; i < pCut->nSize; i++ ) - if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Derives new cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_CutDeriveNew2( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) -{ - unsigned uHash = 0; - int i, k; - assert( pCut->nSize > 0 ); - assert( IdNew0 < IdNew1 ); - for ( i = k = 0; i < pCut->nSize; i++ ) - { - if ( pCut->pArray[i] == IdOld ) - continue; - if ( IdNew0 >= 0 ) - { - if ( IdNew0 <= pCut->pArray[i] ) - { - if ( IdNew0 < pCut->pArray[i] ) - { - if ( k == pCut->nSizeMax ) - return 0; - pCutNew->pArray[ k++ ] = IdNew0; - uHash |= Ivy_CutHashValue( IdNew0 ); - } - IdNew0 = -1; - } - } - if ( IdNew1 >= 0 ) - { - if ( IdNew1 <= pCut->pArray[i] ) - { - if ( IdNew1 < pCut->pArray[i] ) - { - if ( k == pCut->nSizeMax ) - return 0; - pCutNew->pArray[ k++ ] = IdNew1; - uHash |= Ivy_CutHashValue( IdNew1 ); - } - IdNew1 = -1; - } - } - if ( k == pCut->nSizeMax ) - return 0; - pCutNew->pArray[ k++ ] = pCut->pArray[i]; - uHash |= Ivy_CutHashValue( pCut->pArray[i] ); - } - if ( IdNew0 >= 0 ) - { - if ( k == pCut->nSizeMax ) - return 0; - pCutNew->pArray[ k++ ] = IdNew0; - uHash |= Ivy_CutHashValue( IdNew0 ); - } - if ( IdNew1 >= 0 ) - { - if ( k == pCut->nSizeMax ) - return 0; - pCutNew->pArray[ k++ ] = IdNew1; - uHash |= Ivy_CutHashValue( IdNew1 ); - } - pCutNew->nSize = k; - pCutNew->uHash = uHash; - assert( pCutNew->nSize <= pCut->nSizeMax ); - for ( i = 1; i < pCutNew->nSize; i++ ) - assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Derives new cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) -{ - unsigned uHash = 0; - int i, k; - assert( pCut->nSize > 0 ); - assert( IdNew0 < IdNew1 ); - for ( i = k = 0; i < pCut->nSize; i++ ) - { - if ( pCut->pArray[i] == IdOld ) - continue; - if ( IdNew0 <= pCut->pArray[i] ) - { - if ( IdNew0 < pCut->pArray[i] ) - { - pCutNew->pArray[ k++ ] = IdNew0; - uHash |= Ivy_CutHashValue( IdNew0 ); - } - IdNew0 = 0x7FFFFFFF; - } - if ( IdNew1 <= pCut->pArray[i] ) - { - if ( IdNew1 < pCut->pArray[i] ) - { - pCutNew->pArray[ k++ ] = IdNew1; - uHash |= Ivy_CutHashValue( IdNew1 ); - } - IdNew1 = 0x7FFFFFFF; - } - pCutNew->pArray[ k++ ] = pCut->pArray[i]; - uHash |= Ivy_CutHashValue( pCut->pArray[i] ); - } - if ( IdNew0 < 0x7FFFFFFF ) - { - pCutNew->pArray[ k++ ] = IdNew0; - uHash |= Ivy_CutHashValue( IdNew0 ); - } - if ( IdNew1 < 0x7FFFFFFF ) - { - pCutNew->pArray[ k++ ] = IdNew1; - uHash |= Ivy_CutHashValue( IdNew1 ); - } - pCutNew->nSize = k; - pCutNew->uHash = uHash; - assert( pCutNew->nSize <= pCut->nSizeMax ); -// for ( i = 1; i < pCutNew->nSize; i++ ) -// assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Find the hash value of the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline unsigned Ivy_NodeCutHash( Ivy_Cut_t * pCut ) -{ - int i; - pCut->uHash = 0; - for ( i = 0; i < pCut->nSize; i++ ) - pCut->uHash |= (1 << (pCut->pArray[i] % 31)); - return pCut->uHash; -} - -/**Function************************************************************* - - Synopsis [Derives new cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_CutDeriveNew3( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) -{ - int i, k; - assert( pCut->nSize > 0 ); - assert( IdNew0 < IdNew1 ); - for ( i = k = 0; i < pCut->nSize; i++ ) - { - if ( pCut->pArray[i] == IdOld ) - continue; - if ( IdNew0 <= pCut->pArray[i] ) - { - if ( IdNew0 < pCut->pArray[i] ) - pCutNew->pArray[ k++ ] = IdNew0; - IdNew0 = 0x7FFFFFFF; - } - if ( IdNew1 <= pCut->pArray[i] ) - { - if ( IdNew1 < pCut->pArray[i] ) - pCutNew->pArray[ k++ ] = IdNew1; - IdNew1 = 0x7FFFFFFF; - } - pCutNew->pArray[ k++ ] = pCut->pArray[i]; - } - if ( IdNew0 < 0x7FFFFFFF ) - pCutNew->pArray[ k++ ] = IdNew0; - if ( IdNew1 < 0x7FFFFFFF ) - pCutNew->pArray[ k++ ] = IdNew1; - pCutNew->nSize = k; - assert( pCutNew->nSize <= pCut->nSizeMax ); - Ivy_NodeCutHash( pCutNew ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if pDom is contained in pCut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_CutCheckDominance( Ivy_Cut_t * pDom, Ivy_Cut_t * pCut ) -{ - int i, k; - for ( i = 0; i < pDom->nSize; i++ ) - { - assert( i==0 || pDom->pArray[i-1] < pDom->pArray[i] ); - for ( k = 0; k < pCut->nSize; k++ ) - if ( pDom->pArray[i] == pCut->pArray[k] ) - break; - if ( k == pCut->nSize ) // node i in pDom is not contained in pCut - return 0; - } - // every node in pDom is contained in pCut - return 1; -} - -/**Function************************************************************* - - Synopsis [Check if the cut exists.] - - Description [Returns 1 if the cut exists.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_CutFindOrAddFilter( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew ) -{ - Ivy_Cut_t * pCut; - int i, k; - assert( pCutNew->uHash ); - // try to find the cut - for ( i = 0; i < pCutStore->nCuts; i++ ) - { - pCut = pCutStore->pCuts + i; - if ( pCut->nSize == 0 ) - continue; - if ( pCut->nSize == pCutNew->nSize ) - { - if ( pCut->uHash == pCutNew->uHash ) - { - for ( k = 0; k < pCutNew->nSize; k++ ) - if ( pCut->pArray[k] != pCutNew->pArray[k] ) - break; - if ( k == pCutNew->nSize ) - return 1; - } - continue; - } - if ( pCut->nSize < pCutNew->nSize ) - { - // skip the non-contained cuts - if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash ) - continue; - // check containment seriously - if ( Ivy_CutCheckDominance( pCut, pCutNew ) ) - return 1; - continue; - } - // check potential containment of other cut - - // skip the non-contained cuts - if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash ) - continue; - // check containment seriously - if ( Ivy_CutCheckDominance( pCutNew, pCut ) ) - { - // remove the current cut - pCut->nSize = 0; - } - } - assert( pCutStore->nCuts < pCutStore->nCutsMax ); - // add the cut - pCut = pCutStore->pCuts + pCutStore->nCuts++; - *pCut = *pCutNew; - return 0; -} - -/**Function************************************************************* - - Synopsis [Compresses the cut representation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_CutCompactAll( Ivy_Store_t * pCutStore ) -{ - Ivy_Cut_t * pCut; - int i, k; - pCutStore->nCutsM = 0; - for ( i = k = 0; i < pCutStore->nCuts; i++ ) - { - pCut = pCutStore->pCuts + i; - if ( pCut->nSize == 0 ) - continue; - if ( pCut->nSize < pCut->nSizeMax ) - pCutStore->nCutsM++; - pCutStore->pCuts[k++] = *pCut; - } - pCutStore->nCuts = k; -} - -/**Function************************************************************* - - Synopsis [Print the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_CutPrintForNode( Ivy_Cut_t * pCut ) -{ - int i; - assert( pCut->nSize > 0 ); - printf( "%d : {", pCut->nSize ); - for ( i = 0; i < pCut->nSize; i++ ) - printf( " %d", pCut->pArray[i] ); - printf( " }\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_CutPrintForNodes( Ivy_Store_t * pCutStore ) -{ - int i; - printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] ); - for ( i = 0; i < pCutStore->nCuts; i++ ) - Ivy_CutPrintForNode( pCutStore->pCuts + i ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Ivy_CutReadLeaf( Ivy_Obj_t * pFanin ) -{ - int nLats, iLeaf; - assert( !Ivy_IsComplement(pFanin) ); - if ( !Ivy_ObjIsLatch(pFanin) ) - return Ivy_LeafCreate( pFanin->Id, 0 ); - iLeaf = Ivy_CutReadLeaf(Ivy_ObjFanin0(pFanin)); - nLats = Ivy_LeafLat(iLeaf); - assert( nLats < IVY_LEAF_MASK ); - return 1 + iLeaf; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Store_t * Ivy_CutComputeForNode( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves ) -{ - static Ivy_Store_t CutStore, * pCutStore = &CutStore; - Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut; - Ivy_Man_t * pMan = p; - Ivy_Obj_t * pLeaf; - int i, k, Temp, nLats, iLeaf0, iLeaf1; - - assert( nLeaves <= IVY_CUT_INPUT ); - - // start the structure - pCutStore->nCuts = 0; - pCutStore->nCutsMax = IVY_CUT_LIMIT; - // start the trivial cut - pCutNew->uHash = 0; - pCutNew->nSize = 1; - pCutNew->nSizeMax = nLeaves; - pCutNew->pArray[0] = Ivy_LeafCreate( pObj->Id, 0 ); - pCutNew->uHash = Ivy_CutHashValue( pCutNew->pArray[0] ); - // add the trivial cut - pCutStore->pCuts[pCutStore->nCuts++] = *pCutNew; - assert( pCutStore->nCuts == 1 ); - - // explore the cuts - for ( i = 0; i < pCutStore->nCuts; i++ ) - { - // expand this cut - pCut = pCutStore->pCuts + i; - if ( pCut->nSize == 0 ) - continue; - for ( k = 0; k < pCut->nSize; k++ ) - { - pLeaf = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[k]) ); - if ( Ivy_ObjIsCi(pLeaf) || Ivy_ObjIsConst1(pLeaf) ) - continue; - assert( Ivy_ObjIsNode(pLeaf) ); - nLats = Ivy_LeafLat(pCut->pArray[k]); - - // get the fanins fanins - iLeaf0 = Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) ); - iLeaf1 = Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) ); - assert( nLats + Ivy_LeafLat(iLeaf0) < IVY_LEAF_MASK && nLats + Ivy_LeafLat(iLeaf1) < IVY_LEAF_MASK ); - iLeaf0 = nLats + iLeaf0; - iLeaf1 = nLats + iLeaf1; - if ( !Ivy_CutPrescreen( pCut, iLeaf0, iLeaf1 ) ) - continue; - // the given cut exist - if ( iLeaf0 > iLeaf1 ) - Temp = iLeaf0, iLeaf0 = iLeaf1, iLeaf1 = Temp; - // create the new cut - if ( !Ivy_CutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ) ) - continue; - // add the cut - Ivy_CutFindOrAddFilter( pCutStore, pCutNew ); - if ( pCutStore->nCuts == IVY_CUT_LIMIT ) - break; - } - if ( pCutStore->nCuts == IVY_CUT_LIMIT ) - break; - } - if ( pCutStore->nCuts == IVY_CUT_LIMIT ) - pCutStore->fSatur = 1; - else - pCutStore->fSatur = 0; -// printf( "%d ", pCutStore->nCuts ); - Ivy_CutCompactAll( pCutStore ); -// printf( "%d \n", pCutStore->nCuts ); -// Ivy_CutPrintForNodes( pCutStore ); - return pCutStore; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_CutComputeAll( Ivy_Man_t * p, int nInputs ) -{ - Ivy_Store_t * pStore; - Ivy_Obj_t * pObj; - int i, nCutsTotal, nCutsTotalM, nNodeTotal, nNodeOver; - int clk = clock(); - if ( nInputs > IVY_CUT_INPUT ) - { - printf( "Cannot compute cuts for more than %d inputs.\n", IVY_CUT_INPUT ); - return; - } - nNodeTotal = nNodeOver = 0; - nCutsTotal = nCutsTotalM = -Ivy_ManNodeNum(p); - Ivy_ManForEachObj( p, pObj, i ) - { - if ( !Ivy_ObjIsNode(pObj) ) - continue; - pStore = Ivy_CutComputeForNode( p, pObj, nInputs ); - nCutsTotal += pStore->nCuts; - nCutsTotalM += pStore->nCutsM; - nNodeOver += pStore->fSatur; - nNodeTotal++; - } - printf( "All = %6d. Minus = %6d. Triv = %6d. Node = %6d. Satur = %6d. ", - nCutsTotal, nCutsTotalM, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver ); - PRT( "Time", clock() - clk ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyShow.c b/src/aig/ivy/ivyShow.c deleted file mode 100644 index cd726e43..00000000 --- a/src/aig/ivy/ivyShow.c +++ /dev/null @@ -1,338 +0,0 @@ -/**CFile**************************************************************** - - FileName [ivyShow.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [Visualization of HAIG.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: ivyShow.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Ivy_WriteDotAig( Ivy_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * vBold ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManShow( Ivy_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold ) -{ - extern void Abc_ShowFile( char * FileNameDot ); - static Counter = 0; - char FileNameDot[200]; - FILE * pFile; - // create the file name -// Ivy_ShowGetFileName( pMan->pName, FileNameDot ); - sprintf( FileNameDot, "temp%02d.dot", Counter++ ); - // check that the file can be opened - if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) - { - fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot ); - return; - } - fclose( pFile ); - // generate the file - Ivy_WriteDotAig( pMan, FileNameDot, fHaig, vBold ); - // visualize the file - Abc_ShowFile( FileNameDot ); -} - -/**Function************************************************************* - - Synopsis [Writes the graph structure of AIG for DOT.] - - Description [Useful for graph visualization using tools such as GraphViz: - http://www.graphviz.org/] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_WriteDotAig( Ivy_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t * vBold ) -{ - FILE * pFile; - Ivy_Obj_t * pNode, * pTemp, * pPrev; - int LevelMax, Level, i; - - if ( Ivy_ManNodeNum(pMan) > 200 ) - { - fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" ); - return; - } - if ( (pFile = fopen( pFileName, "w" )) == NULL ) - { - fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); - return; - } - - // mark the nodes - if ( vBold ) - Vec_PtrForEachEntry( vBold, pNode, i ) - pNode->fMarkB = 1; - - // compute levels - LevelMax = 1 + Ivy_ManSetLevels( pMan, fHaig ); - - // write the DOT header - fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "digraph AIG {\n" ); - fprintf( pFile, "size = \"7.5,10\";\n" ); -// fprintf( pFile, "ranksep = 0.5;\n" ); -// fprintf( pFile, "nodesep = 0.5;\n" ); - fprintf( pFile, "center = true;\n" ); -// fprintf( pFile, "orientation = landscape;\n" ); -// fprintf( pFile, "edge [fontsize = 10];\n" ); -// fprintf( pFile, "edge [dir = none];\n" ); - fprintf( pFile, "edge [dir = back];\n" ); - fprintf( pFile, "\n" ); - - // labels on the left of the picture - fprintf( pFile, "{\n" ); - fprintf( pFile, " node [shape = plaintext];\n" ); - fprintf( pFile, " edge [style = invis];\n" ); - fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); - fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); - // generate node names with labels - for ( Level = LevelMax; Level >= 0; Level-- ) - { - // the visible node name - fprintf( pFile, " Level%d", Level ); - fprintf( pFile, " [label = " ); - // label name - fprintf( pFile, "\"" ); - fprintf( pFile, "\"" ); - fprintf( pFile, "];\n" ); - } - - // genetate the sequence of visible/invisible nodes to mark levels - fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); - for ( Level = LevelMax; Level >= 0; Level-- ) - { - // the visible node name - fprintf( pFile, " Level%d", Level ); - // the connector - if ( Level != 0 ) - fprintf( pFile, " ->" ); - else - fprintf( pFile, ";" ); - } - fprintf( pFile, "\n" ); - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - - // generate title box on top - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - fprintf( pFile, " LevelTitle1;\n" ); - fprintf( pFile, " title1 [shape=plaintext,\n" ); - fprintf( pFile, " fontsize=20,\n" ); - fprintf( pFile, " fontname = \"Times-Roman\",\n" ); - fprintf( pFile, " label=\"" ); - fprintf( pFile, "%s", "AIG structure visualized by ABC" ); - fprintf( pFile, "\\n" ); - fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" ); - fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); - fprintf( pFile, "\"\n" ); - fprintf( pFile, " ];\n" ); - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - - // generate statistics box - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - fprintf( pFile, " LevelTitle2;\n" ); - fprintf( pFile, " title2 [shape=plaintext,\n" ); - fprintf( pFile, " fontsize=18,\n" ); - fprintf( pFile, " fontname = \"Times-Roman\",\n" ); - fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Ivy_ManNodeNum(pMan), LevelMax ); - fprintf( pFile, "\\n" ); - fprintf( pFile, "\"\n" ); - fprintf( pFile, " ];\n" ); - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - - // generate the COs - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - // the labeling node of this level - fprintf( pFile, " Level%d;\n", LevelMax ); - // generate the CO nodes - Ivy_ManForEachCo( pMan, pNode, i ) - { - if ( fHaig || pNode->pEquiv == NULL ) - fprintf( pFile, " Node%d%s [label = \"%d%s\"", pNode->Id, - (Ivy_ObjIsLatch(pNode)? "_in":""), pNode->Id, (Ivy_ObjIsLatch(pNode)? "_in":"") ); - else - fprintf( pFile, " Node%d%s [label = \"%d%s(%d%s)\"", pNode->Id, - (Ivy_ObjIsLatch(pNode)? "_in":""), pNode->Id, (Ivy_ObjIsLatch(pNode)? "_in":""), - Ivy_Regular(pNode->pEquiv)->Id, Ivy_IsComplement(pNode->pEquiv)? "\'":"" ); - fprintf( pFile, ", shape = %s", (Ivy_ObjIsLatch(pNode)? "box":"invtriangle") ); - fprintf( pFile, ", color = coral, fillcolor = coral" ); - fprintf( pFile, "];\n" ); - } - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - - // generate nodes of each rank - for ( Level = LevelMax - 1; Level > 0; Level-- ) - { - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - // the labeling node of this level - fprintf( pFile, " Level%d;\n", Level ); - Ivy_ManForEachObj( pMan, pNode, i ) - { - if ( (int)pNode->Level != Level ) - continue; - if ( fHaig || pNode->pEquiv == NULL ) - fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id ); - else - fprintf( pFile, " Node%d [label = \"%d(%d%s)\"", pNode->Id, pNode->Id, - Ivy_Regular(pNode->pEquiv)->Id, Ivy_IsComplement(pNode->pEquiv)? "\'":"" ); - fprintf( pFile, ", shape = ellipse" ); - if ( vBold && pNode->fMarkB ) - fprintf( pFile, ", style = filled" ); - fprintf( pFile, "];\n" ); - } - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - } - - // generate the CI nodes - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - // the labeling node of this level - fprintf( pFile, " Level%d;\n", 0 ); - // generate constant node - if ( Ivy_ObjRefs(Ivy_ManConst1(pMan)) > 0 ) - { - pNode = Ivy_ManConst1(pMan); - // check if the costant node is present - fprintf( pFile, " Node%d [label = \"Const1\"", pNode->Id ); - fprintf( pFile, ", shape = ellipse" ); - fprintf( pFile, ", color = coral, fillcolor = coral" ); - fprintf( pFile, "];\n" ); - } - // generate the CI nodes - Ivy_ManForEachCi( pMan, pNode, i ) - { - if ( fHaig || pNode->pEquiv == NULL ) - fprintf( pFile, " Node%d%s [label = \"%d%s\"", pNode->Id, - (Ivy_ObjIsLatch(pNode)? "_out":""), pNode->Id, (Ivy_ObjIsLatch(pNode)? "_out":"") ); - else - fprintf( pFile, " Node%d%s [label = \"%d%s(%d%s)\"", pNode->Id, - (Ivy_ObjIsLatch(pNode)? "_out":""), pNode->Id, (Ivy_ObjIsLatch(pNode)? "_out":""), - Ivy_Regular(pNode->pEquiv)->Id, Ivy_IsComplement(pNode->pEquiv)? "\'":"" ); - fprintf( pFile, ", shape = %s", (Ivy_ObjIsLatch(pNode)? "box":"triangle") ); - fprintf( pFile, ", color = coral, fillcolor = coral" ); - fprintf( pFile, "];\n" ); - } - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - - // generate invisible edges from the square down - fprintf( pFile, "title1 -> title2 [style = invis];\n" ); - Ivy_ManForEachCo( pMan, pNode, i ) - fprintf( pFile, "title2 -> Node%d%s [style = invis];\n", pNode->Id, (Ivy_ObjIsLatch(pNode)? "_in":"") ); - - // generate edges - Ivy_ManForEachObj( pMan, pNode, i ) - { - if ( !Ivy_ObjIsNode(pNode) && !Ivy_ObjIsCo(pNode) && !Ivy_ObjIsBuf(pNode) ) - continue; - // generate the edge from this node to the next - fprintf( pFile, "Node%d%s", pNode->Id, (Ivy_ObjIsLatch(pNode)? "_in":"") ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d%s", Ivy_ObjFaninId0(pNode), (Ivy_ObjIsLatch(Ivy_ObjFanin0(pNode))? "_out":"") ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Ivy_ObjFaninC0(pNode)? "dotted" : "bold" ); -// if ( Ivy_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL0(pNode) > 0 ) -// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - if ( !Ivy_ObjIsNode(pNode) ) - continue; - // generate the edge from this node to the next - fprintf( pFile, "Node%d", pNode->Id ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d%s", Ivy_ObjFaninId1(pNode), (Ivy_ObjIsLatch(Ivy_ObjFanin1(pNode))? "_out":"") ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Ivy_ObjFaninC1(pNode)? "dotted" : "bold" ); -// if ( Ivy_NtkIsSeq(pNode->pMan) && Seq_ObjFaninL1(pNode) > 0 ) -// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - // generate the edges between the equivalent nodes - if ( fHaig && pNode->pEquiv && Ivy_ObjRefs(pNode) > 0 ) - { - pPrev = pNode; - for ( pTemp = pNode->pEquiv; pTemp != pNode; pTemp = Ivy_Regular(pTemp->pEquiv) ) - { - fprintf( pFile, "Node%d", pPrev->Id ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", pTemp->Id ); - fprintf( pFile, " [style = %s]", Ivy_IsComplement(pTemp->pEquiv)? "dotted" : "bold" ); - fprintf( pFile, ";\n" ); - pPrev = pTemp; - } - // connect the last node with the first - fprintf( pFile, "Node%d", pPrev->Id ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", pNode->Id ); - fprintf( pFile, " [style = %s]", Ivy_IsComplement(pPrev->pEquiv)? "dotted" : "bold" ); - fprintf( pFile, ";\n" ); - } - } - - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - fclose( pFile ); - - // unmark nodes - if ( vBold ) - Vec_PtrForEachEntry( vBold, pNode, i ) - pNode->fMarkB = 0; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyTable.c b/src/aig/ivy/ivyTable.c deleted file mode 100644 index 2ac0ae49..00000000 --- a/src/aig/ivy/ivyTable.c +++ /dev/null @@ -1,301 +0,0 @@ -/**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_Man_t * p, Ivy_Obj_t * pObj ) -{ - int i; - assert( Ivy_ObjIsHash(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; -} - -static void Ivy_TableResize( Ivy_Man_t * p ); -static unsigned int Cudd_PrimeAig( unsigned int p ); - -//////////////////////////////////////////////////////////////////////// -/// 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_Man_t * p, Ivy_Obj_t * pObj ) -{ - 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_ObjFaninId1(pObj) == 0 || Ivy_ObjFaninId0(pObj) < Ivy_ObjFaninId1(pObj) ); - if ( Ivy_ObjFanin0(pObj)->nRefs == 0 || (Ivy_ObjChild1(pObj) && Ivy_ObjFanin1(pObj)->nRefs == 0) ) - return NULL; - for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize ) - { - pEntry = Ivy_ManObj( p, p->pTable[i] ); - if ( Ivy_ObjChild0(pEntry) == Ivy_ObjChild0(pObj) && - Ivy_ObjChild1(pEntry) == Ivy_ObjChild1(pObj) && - Ivy_ObjInit(pEntry) == Ivy_ObjInit(pObj) && - Ivy_ObjType(pEntry) == Ivy_ObjType(pObj) ) - return pEntry; - } - return NULL; -} - -/**Function************************************************************* - - Synopsis [Adds the node to the hash table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_TableInsert( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - int * pPlace; - assert( !Ivy_IsComplement(pObj) ); - if ( !Ivy_ObjIsHash(pObj) ) - return; - if ( (pObj->Id & 63) == 0 ) - { - if ( p->nTableSize < 2 * Ivy_ManHashObjNum(p) ) - Ivy_TableResize( p ); - } - pPlace = Ivy_TableFind( p, pObj ); - assert( *pPlace == 0 ); - *pPlace = pObj->Id; -} - -/**Function************************************************************* - - Synopsis [Deletes the node from the hash table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_TableDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pEntry; - int i, * pPlace; - assert( !Ivy_IsComplement(pObj) ); - if ( !Ivy_ObjIsHash(pObj) ) - return; - pPlace = Ivy_TableFind( p, pObj ); - assert( *pPlace == pObj->Id ); // node should be in the table - *pPlace = 0; - // rehash the adjacent entries - i = pPlace - p->pTable; - for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize ) - { - pEntry = Ivy_ManObj( p, p->pTable[i] ); - p->pTable[i] = 0; - Ivy_TableInsert( p, 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_Man_t * p, Ivy_Obj_t * pObj, int ObjIdNew ) -{ - int * pPlace; - assert( !Ivy_IsComplement(pObj) ); - if ( !Ivy_ObjIsHash(pObj) ) - return; - pPlace = Ivy_TableFind( p, 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, nEntries, e, clk; -clk = clock(); - // save the old table - pTableOld = p->pTable; - nTableSizeOld = p->nTableSize; - // get the new table - p->nTableSize = Cudd_PrimeAig( 5 * Ivy_ManHashObjNum(p) ); - 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( p, Ivy_ManObj(p, pTableOld[e]) ); - assert( *pPlace == 0 ); // should not be in the table - *pPlace = pTableOld[e]; - } - nEntries = Ivy_ManHashObjNum(p); -// assert( Counter == nEntries ); -// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize ); -// PRT( "Time", clock() - clk ); - // replace the table and the parameters - free( pTableOld ); -} - -/**Function******************************************************************** - - Synopsis [Profiles the hash table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -void Ivy_TableProfile( Ivy_Man_t * p ) -{ - int i, Counter = 0; - for ( i = 0; i < p->nTableSize; i++ ) - { - if ( p->pTable[i] ) - Counter++; - else if ( Counter ) - { - printf( "%d ", Counter ); - Counter = 0; - } - } -} - -/**Function******************************************************************** - - Synopsis [Returns the next prime >= p.] - - Description [Copied from CUDD, for stand-aloneness.] - - SideEffects [None] - - SeeAlso [] - -******************************************************************************/ -unsigned int Cudd_PrimeAig( unsigned int p) -{ - int i,pn; - - p--; - do { - p++; - if (p&1) { - pn = 1; - i = 3; - while ((unsigned) (i * i) <= p) { - if (p % i == 0) { - pn = 0; - break; - } - i += 2; - } - } else { - pn = 0; - } - } while (!pn); - return(p); - -} /* end of Cudd_Prime */ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivyUtil.c b/src/aig/ivy/ivyUtil.c deleted file mode 100644 index ab62a276..00000000 --- a/src/aig/ivy/ivyUtil.c +++ /dev/null @@ -1,818 +0,0 @@ -/**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 [Computes truth table of the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManCollectCut_rec( Ivy_Man_t * p, 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( p, Ivy_ObjFanin0(pNode), vNodes ); - Ivy_ManCollectCut_rec( p, 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_Man_t * p, 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_ManObj(p, Leaf)->fMarkA = 1; - } - // collect and mark the nodes - Ivy_ManCollectCut_rec( p, pRoot, vNodes ); - // clean the nodes - Vec_IntForEachEntry( vNodes, Leaf, i ) - Ivy_ManObj(p, 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_Man_t * p, 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_Man_t * p, 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( p, pRoot, vLeaves, vNodes ); - // set the node numbers - Vec_IntForEachEntry( vNodes, Leaf, i ) - Ivy_ManObj(p, 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( p, Ivy_ManObj(p, 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; -} - -/**Function************************************************************* - - Synopsis [Collect the latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManLevels( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - int i, LevelMax = 0; - Ivy_ManForEachPo( p, pObj, i ) - LevelMax = IVY_MAX( LevelMax, (int)Ivy_ObjFanin0(pObj)->Level ); - return LevelMax; -} - -/**Function************************************************************* - - Synopsis [Collect the latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ManResetLevels_rec( Ivy_Obj_t * pObj ) -{ - if ( pObj->Level || Ivy_ObjIsCi(pObj) || Ivy_ObjIsConst1(pObj) ) - return pObj->Level; - if ( Ivy_ObjIsBuf(pObj) ) - return pObj->Level = Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) ); - assert( Ivy_ObjIsNode(pObj) ); - Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) ); - Ivy_ManResetLevels_rec( Ivy_ObjFanin1(pObj) ); - return pObj->Level = Ivy_ObjLevelNew( pObj ); -} - -/**Function************************************************************* - - Synopsis [Collect the latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManResetLevels( Ivy_Man_t * p ) -{ - Ivy_Obj_t * pObj; - int i; - Ivy_ManForEachObj( p, pObj, i ) - pObj->Level = 0; - Ivy_ManForEachCo( p, pObj, i ) - Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) ); -} - -/**Function************************************************************* - - Synopsis [References/references the node and returns MFFC size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ObjRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel ) -{ - Ivy_Obj_t * pNode0, * pNode1; - int Counter; - // label visited nodes - if ( fLabel ) - Ivy_ObjSetTravIdCurrent( p, pNode ); - // skip the CI - if ( Ivy_ObjIsPi(pNode) ) - return 0; - assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) || Ivy_ObjIsLatch(pNode) ); - // process the internal node - pNode0 = Ivy_ObjFanin0(pNode); - pNode1 = Ivy_ObjFanin1(pNode); - Counter = Ivy_ObjIsNode(pNode); - if ( fReference ) - { - if ( pNode0->nRefs++ == 0 ) - Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel ); - if ( pNode1 && pNode1->nRefs++ == 0 ) - Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel ); - } - else - { - assert( pNode0->nRefs > 0 ); - assert( pNode1 == NULL || pNode1->nRefs > 0 ); - if ( --pNode0->nRefs == 0 ) - Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel ); - if ( pNode1 && --pNode1->nRefs == 0 ) - Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel ); - } - return Counter; -} - - -/**Function************************************************************* - - Synopsis [Labels MFFC with the current label.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode ) -{ - int nConeSize1, nConeSize2; - assert( !Ivy_IsComplement( pNode ) ); - assert( Ivy_ObjIsNode( pNode ) ); - nConeSize1 = Ivy_ObjRefDeref( p, pNode, 0, 1 ); // dereference - nConeSize2 = Ivy_ObjRefDeref( p, pNode, 1, 0 ); // reference - assert( nConeSize1 == nConeSize2 ); - assert( nConeSize1 > 0 ); - return nConeSize1; -} - -/**Function************************************************************* - - Synopsis [Recursively updates fanout levels.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjUpdateLevel_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pFanout; - Vec_Ptr_t * vFanouts; - int i, LevelNew; - assert( p->fFanout ); - assert( Ivy_ObjIsNode(pObj) ); - vFanouts = Vec_PtrAlloc( 10 ); - Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i ) - { - if ( Ivy_ObjIsCo(pFanout) ) - { -// assert( (int)Ivy_ObjFanin0(pFanout)->Level <= p->nLevelMax ); - continue; - } - LevelNew = Ivy_ObjLevelNew( pFanout ); - if ( (int)pFanout->Level == LevelNew ) - continue; - pFanout->Level = LevelNew; - Ivy_ObjUpdateLevel_rec( p, pFanout ); - } - Vec_PtrFree( vFanouts ); -} - -/**Function************************************************************* - - Synopsis [Compute the new required level.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_ObjLevelRNew( Ivy_Man_t * p, Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pFanout; - Vec_Ptr_t * vFanouts; - int i, Required, LevelNew = 1000000; - assert( p->fFanout && p->vRequired ); - vFanouts = Vec_PtrAlloc( 10 ); - Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i ) - { - Required = Vec_IntEntry(p->vRequired, pFanout->Id); - LevelNew = IVY_MIN( LevelNew, Required ); - } - Vec_PtrFree( vFanouts ); - return LevelNew - 1; -} - -/**Function************************************************************* - - Synopsis [Recursively updates fanout levels.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ReqNew ) -{ - Ivy_Obj_t * pFanin; - if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) ) - return; - assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) ); - // process the first fanin - pFanin = Ivy_ObjFanin0(pObj); - if ( Vec_IntEntry(p->vRequired, pFanin->Id) > ReqNew - 1 ) - { - Vec_IntWriteEntry( p->vRequired, pFanin->Id, ReqNew - 1 ); - Ivy_ObjUpdateLevelR_rec( p, pFanin, ReqNew - 1 ); - } - if ( Ivy_ObjIsBuf(pObj) ) - return; - // process the second fanin - pFanin = Ivy_ObjFanin1(pObj); - if ( Vec_IntEntry(p->vRequired, pFanin->Id) > ReqNew - 1 ) - { - Vec_IntWriteEntry( p->vRequired, pFanin->Id, ReqNew - 1 ); - Ivy_ObjUpdateLevelR_rec( p, pFanin, ReqNew - 1 ); - } -} - -/**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 [Returns the real fanin.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj ) -{ - Ivy_Obj_t * pFanin; - if ( pObj == NULL || !Ivy_ObjIsBuf( Ivy_Regular(pObj) ) ) - return pObj; - pFanin = Ivy_ObjReal( Ivy_ObjChild0(Ivy_Regular(pObj)) ); - return Ivy_NotCond( pFanin, Ivy_IsComplement(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Prints node in HAIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fHaig ) -{ - Ivy_Obj_t * pTemp; - int fShowFanouts = 0; - assert( !Ivy_IsComplement(pObj) ); - printf( "Node %5d : ", Ivy_ObjId(pObj) ); - if ( Ivy_ObjIsConst1(pObj) ) - printf( "constant 1" ); - else if ( Ivy_ObjIsPi(pObj) ) - printf( "PI" ); - else if ( Ivy_ObjIsPo(pObj) ) - printf( "PO" ); - else if ( Ivy_ObjIsLatch(pObj) ) - printf( "latch (%d%s)", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") ); - else if ( Ivy_ObjIsBuf(pObj) ) - printf( "buffer (%d%s)", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") ); - else - printf( "AND( %5d%s, %5d%s )", - Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " "), - Ivy_ObjFanin1(pObj)->Id, (Ivy_ObjFaninC1(pObj)? "\'" : " ") ); - printf( " (refs = %3d)", Ivy_ObjRefs(pObj) ); - if ( fShowFanouts ) - { - Vec_Ptr_t * vFanouts; - Ivy_Obj_t * pFanout; - int i; - vFanouts = Vec_PtrAlloc( 10 ); - printf( "\nFanouts:\n" ); - Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i ) - { - printf( " " ); - printf( "Node %5d : ", Ivy_ObjId(pFanout) ); - if ( Ivy_ObjIsPo(pFanout) ) - printf( "PO" ); - else if ( Ivy_ObjIsLatch(pFanout) ) - printf( "latch (%d%s)", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " ") ); - else if ( Ivy_ObjIsBuf(pFanout) ) - printf( "buffer (%d%s)", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " ") ); - else - printf( "AND( %5d%s, %5d%s )", - Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " "), - Ivy_ObjFanin1(pFanout)->Id, (Ivy_ObjFaninC1(pFanout)? "\'" : " ") ); - printf( "\n" ); - } - Vec_PtrFree( vFanouts ); - return; - } - if ( !fHaig ) - { - if ( pObj->pEquiv == NULL ) - printf( " HAIG node not given" ); - else - printf( " HAIG node = %d%s", Ivy_Regular(pObj->pEquiv)->Id, (Ivy_IsComplement(pObj->pEquiv)? "\'" : " ") ); - return; - } - if ( pObj->pEquiv == NULL ) - return; - // there are choices - if ( Ivy_ObjRefs(pObj) > 0 ) - { - // print equivalence class - printf( " { %5d ", pObj->Id ); - assert( !Ivy_IsComplement(pObj->pEquiv) ); - for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) - printf( " %5d%s", pTemp->Id, (Ivy_IsComplement(pTemp->pEquiv)? "\'" : " ") ); - printf( " }" ); - return; - } - // this is a secondary node - for ( pTemp = Ivy_Regular(pObj->pEquiv); Ivy_ObjRefs(pTemp) == 0; pTemp = Ivy_Regular(pTemp->pEquiv) ); - assert( Ivy_ObjRefs(pTemp) > 0 ); - printf( " class of %d", pTemp->Id ); -} - -/**Function************************************************************* - - Synopsis [Prints node in HAIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig ) -{ - Vec_Int_t * vNodes; - Ivy_Obj_t * pObj; - int i; - printf( "PIs: " ); - Ivy_ManForEachPi( p, pObj, i ) - printf( " %d", pObj->Id ); - printf( "\n" ); - printf( "POs: " ); - Ivy_ManForEachPo( p, pObj, i ) - printf( " %d", pObj->Id ); - printf( "\n" ); - printf( "Latches: " ); - Ivy_ManForEachLatch( p, pObj, i ) - printf( " %d=%d%s", pObj->Id, Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") ); - printf( "\n" ); - vNodes = Ivy_ManDfsSeq( p, NULL ); - Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) - Ivy_ObjPrintVerbose( p, pObj, fHaig ), printf( "\n" ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Performs incremental rewriting of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_CutTruthPrint2( Ivy_Man_t * p, Ivy_Cut_t * pCut, unsigned uTruth ) -{ - int i; - printf( "Trying cut : {" ); - for ( i = 0; i < pCut->nSize; i++ ) - printf( " %6d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) ); - printf( " } " ); - Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Performs incremental rewriting of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_CutTruthPrint( Ivy_Man_t * p, Ivy_Cut_t * pCut, unsigned uTruth ) -{ - Vec_Ptr_t * vArray; - Ivy_Obj_t * pObj, * pFanout; - int nLatches = 0; - int nPresent = 0; - int i, k; - int fVerbose = 0; - - if ( fVerbose ) - printf( "Trying cut : {" ); - for ( i = 0; i < pCut->nSize; i++ ) - { - if ( fVerbose ) - printf( " %6d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) ); - nLatches += Ivy_LeafLat(pCut->pArray[i]); - } - if ( fVerbose ) - printf( " } " ); - if ( fVerbose ) - printf( "Latches = %d. ", nLatches ); - - // check if there are latches on the fanout edges - vArray = Vec_PtrAlloc( 100 ); - for ( i = 0; i < pCut->nSize; i++ ) - { - pObj = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[i]) ); - Ivy_ObjForEachFanout( p, pObj, vArray, pFanout, k ) - { - if ( Ivy_ObjIsLatch(pFanout) ) - { - nPresent++; - break; - } - } - } - Vec_PtrSize( vArray ); - if ( fVerbose ) - { - printf( "Present = %d. ", nPresent ); - if ( nLatches > nPresent ) - printf( "Clauses = %d. ", 2*(nLatches - nPresent) ); - printf( "\n" ); - } - return ( nLatches > nPresent ) ? 2*(nLatches - nPresent) : 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/ivy/ivy_.c b/src/aig/ivy/ivy_.c deleted file mode 100644 index 65689689..00000000 --- a/src/aig/ivy/ivy_.c +++ /dev/null @@ -1,48 +0,0 @@ -/**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/aig/ivy/module.make b/src/aig/ivy/module.make deleted file mode 100644 index daef43df..00000000 --- a/src/aig/ivy/module.make +++ /dev/null @@ -1,22 +0,0 @@ -SRC += src/aig/ivy/ivyBalance.c \ - src/aig/ivy/ivyCanon.c \ - src/aig/ivy/ivyCheck.c \ - src/aig/ivy/ivyCut.c \ - src/aig/ivy/ivyCutTrav.c \ - src/aig/ivy/ivyDfs.c \ - src/aig/ivy/ivyDsd.c \ - src/aig/ivy/ivyFanout.c \ - src/aig/ivy/ivyFastMap.c \ - src/aig/ivy/ivyFraig.c \ - src/aig/ivy/ivyHaig.c \ - src/aig/ivy/ivyMan.c \ - src/aig/ivy/ivyMem.c \ - src/aig/ivy/ivyMulti.c \ - src/aig/ivy/ivyObj.c \ - src/aig/ivy/ivyOper.c \ - src/aig/ivy/ivyResyn.c \ - src/aig/ivy/ivyRwr.c \ - src/aig/ivy/ivySeq.c \ - src/aig/ivy/ivyShow.c \ - src/aig/ivy/ivyTable.c \ - src/aig/ivy/ivyUtil.c -- cgit v1.2.3