summaryrefslogtreecommitdiffstats
path: root/src/aig/ivy
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2008-01-30 08:01:00 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2008-01-30 08:01:00 -0800
commit4d30a1e4f1edecff86d5066ce4653a370e59e5e1 (patch)
tree366355938a4af0a92f848841ac65374f338d691b /src/aig/ivy
parent6537f941887b06e588d3acfc97b5fdf48875cc4e (diff)
downloadabc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.tar.gz
abc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.tar.bz2
abc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.zip
Version abc80130
Diffstat (limited to 'src/aig/ivy')
-rw-r--r--src/aig/ivy/attr.h414
-rw-r--r--src/aig/ivy/ivy.h557
-rw-r--r--src/aig/ivy/ivyBalance.c404
-rw-r--r--src/aig/ivy/ivyCanon.c144
-rw-r--r--src/aig/ivy/ivyCheck.c273
-rw-r--r--src/aig/ivy/ivyCut.c989
-rw-r--r--src/aig/ivy/ivyCutTrav.c473
-rw-r--r--src/aig/ivy/ivyDfs.c493
-rw-r--r--src/aig/ivy/ivyDsd.c819
-rw-r--r--src/aig/ivy/ivyFanout.c309
-rw-r--r--src/aig/ivy/ivyFastMap.c1593
-rw-r--r--src/aig/ivy/ivyFraig.c2760
-rw-r--r--src/aig/ivy/ivyHaig.c530
-rw-r--r--src/aig/ivy/ivyMan.c546
-rw-r--r--src/aig/ivy/ivyMem.c116
-rw-r--r--src/aig/ivy/ivyMulti.c301
-rw-r--r--src/aig/ivy/ivyMulti8.c427
-rw-r--r--src/aig/ivy/ivyObj.c476
-rw-r--r--src/aig/ivy/ivyOper.c293
-rw-r--r--src/aig/ivy/ivyResyn.c196
-rw-r--r--src/aig/ivy/ivyRwr.c609
-rw-r--r--src/aig/ivy/ivyRwrAlg.c408
-rw-r--r--src/aig/ivy/ivySeq.c1134
-rw-r--r--src/aig/ivy/ivyShow.c338
-rw-r--r--src/aig/ivy/ivyTable.c301
-rw-r--r--src/aig/ivy/ivyUtil.c818
-rw-r--r--src/aig/ivy/ivy_.c48
-rw-r--r--src/aig/ivy/module.make22
28 files changed, 0 insertions, 15791 deletions
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 <stdio.h>
-#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<<IVY_PAGE_SIZE) + EntrySizeMax;
- pMemory = ALLOC( char, nBytes );
- Vec_PtrPush( p->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<<i)) > 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<<i)) > 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 &gt;= 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