summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2006-06-11 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2006-06-11 08:01:00 -0700
commit3db1557f45b03875a0a0b8adddcc15c4565895d2 (patch)
tree2896d20ddcb85ae4aa7245ca28bc585f567fea54 /src
parent7d0921330b1f4e789901b4c2450920e7c412f95f (diff)
downloadabc-3db1557f45b03875a0a0b8adddcc15c4565895d2.tar.gz
abc-3db1557f45b03875a0a0b8adddcc15c4565895d2.tar.bz2
abc-3db1557f45b03875a0a0b8adddcc15c4565895d2.zip
Version abc60611
Diffstat (limited to 'src')
-rw-r--r--src/base/abc/abc.h243
-rw-r--r--src/base/abc/abcCheck.c128
-rw-r--r--src/base/abc/abcDfs.c4
-rw-r--r--src/base/abc/abcFanio.c6
-rw-r--r--src/base/abc/abcLatch.c3
-rw-r--r--src/base/abc/abcMinBase.c11
-rw-r--r--src/base/abc/abcNames.c141
-rw-r--r--src/base/abc/abcNetlist.c120
-rw-r--r--src/base/abc/abcNtk.c115
-rw-r--r--src/base/abc/abcObj.c113
-rw-r--r--src/base/abc/abcSop.c38
-rw-r--r--src/base/abc/abcUtil.c40
-rw-r--r--src/base/abci/abc.c303
-rw-r--r--src/base/abci/abcAttach.c4
-rw-r--r--src/base/abci/abcIvy.c407
-rw-r--r--src/base/abci/abcMiter.c33
-rw-r--r--src/base/abci/abcMv.c369
-rw-r--r--src/base/abci/abcPrint.c7
-rw-r--r--src/base/abci/abcProve.c51
-rw-r--r--src/base/abci/abcRefactor.c3
-rw-r--r--src/base/abci/abcRenode.c3
-rw-r--r--src/base/abci/abcRestruct.c3
-rw-r--r--src/base/abci/abcResub.c5
-rw-r--r--src/base/abci/abcRewrite.c182
-rw-r--r--src/base/abci/abcRr.c10
-rw-r--r--src/base/abci/abcSat.c33
-rw-r--r--src/base/abci/abcSweep.c4
-rw-r--r--src/base/abci/abcTrace.c2
-rw-r--r--src/base/abci/abcVanEijk.c2
-rw-r--r--src/base/abci/abcVerify.c63
-rw-r--r--src/base/abci/module.make1
-rw-r--r--src/base/io/io.h1
-rw-r--r--src/base/io/ioReadBaf.c2
-rw-r--r--src/base/io/ioReadBlif.c126
-rw-r--r--src/base/io/ioUtil.c25
-rw-r--r--src/base/io/ioWriteBlif.c54
-rw-r--r--src/base/io/ioWriteVer.c77
-rw-r--r--src/base/main/mainFrame.c2
-rw-r--r--src/base/main/module.make4
-rw-r--r--src/base/seq/seqAigCore.c3
-rw-r--r--src/base/seq/seqCreate.c26
-rw-r--r--src/base/seq/seqFpgaCore.c8
-rw-r--r--src/base/seq/seqMapCore.c8
-rw-r--r--src/base/seq/seqRetCore.c8
-rw-r--r--src/map/fpga/fpgaCut.c2
-rw-r--r--src/map/mapper/mapperTable.c4
-rw-r--r--src/map/mapper/mapperTruth.c11
-rw-r--r--src/misc/extra/extra.h5
-rw-r--r--src/misc/extra/extraUtilBitMatrix.c2
-rw-r--r--src/misc/extra/extraUtilMisc.c16
-rw-r--r--src/misc/extra/extraUtilTruth.c6
-rw-r--r--src/misc/mvc/mvc.h2
-rw-r--r--src/misc/nm/module.make2
-rw-r--r--src/misc/nm/nm.h2
-rw-r--r--src/misc/nm/nmApi.c47
-rw-r--r--src/misc/nm/nmInt.h1
-rw-r--r--src/misc/util/util_hack.h4
-rw-r--r--src/misc/vec/vecInt.h21
-rw-r--r--src/misc/vec/vecPtr.h20
-rw-r--r--src/misc/vec/vecStr.h4
-rw-r--r--src/opt/cut/Abc_NtkFindCi.c988
-rw-r--r--src/opt/cut/cutMan.c5
-rw-r--r--src/opt/cut/cutPre22.c2
-rw-r--r--src/opt/cut/cutTruth.c3
-rw-r--r--src/opt/dec/decAbc.c36
-rw-r--r--src/opt/dec/decFactor.c7
-rw-r--r--src/opt/fxu/fxu.h2
-rw-r--r--src/opt/rwr/rwr.h1
-rw-r--r--src/opt/rwr/rwrEva.c9
-rw-r--r--src/opt/rwr/rwrMan.c22
-rw-r--r--src/opt/rwr/rwrTemp.c121
-rw-r--r--src/opt/sim/sim.h4
-rw-r--r--src/opt/xyz/module.make8
-rw-r--r--src/opt/xyz/xyz.h110
-rw-r--r--src/opt/xyz/xyzBuild.c379
-rw-r--r--src/opt/xyz/xyzCore.c1025
-rw-r--r--src/opt/xyz/xyzMan.c144
-rw-r--r--src/opt/xyz/xyzMinSop.c615
-rw-r--r--src/opt/xyz/xyzTest.c417
-rw-r--r--src/sat/aig/aig.h4
-rw-r--r--src/sat/aig/fraigCore.c2
-rw-r--r--src/sat/aig/rwrTruth.c6
-rw-r--r--src/sat/asat/added.c24
-rw-r--r--src/sat/asat/asat60525.zipbin0 -> 25597 bytes
-rw-r--r--src/sat/asat/jfront.c4
-rw-r--r--src/sat/asat/solver.c201
-rw-r--r--src/sat/asat/solver.h26
-rw-r--r--src/sat/asat/solver_vec.h30
-rw-r--r--src/sat/csat/csat_apis.c95
-rw-r--r--src/sat/csat/csat_apis.h5
-rw-r--r--src/sat/fraig/fraig.h42
-rw-r--r--src/sat/fraig/fraigApi.c4
-rw-r--r--src/sat/fraig/fraigCanon.c4
-rw-r--r--src/sat/fraig/fraigInt.h3
-rw-r--r--src/sat/fraig/fraigMan.c12
-rw-r--r--src/sat/msat/msat.h1
-rw-r--r--src/sat/msat/msatInt.h6
-rw-r--r--src/sat/msat/msatSolverApi.c35
-rw-r--r--src/temp/esop/esop.h (renamed from src/opt/xyz/xyzInt.h)288
-rw-r--r--src/temp/esop/esopMan.c (renamed from src/opt/xyz/xyzMinMan.c)58
-rw-r--r--src/temp/esop/esopMem.c274
-rw-r--r--src/temp/esop/esopMin.c (renamed from src/opt/xyz/xyzMinEsop.c)108
-rw-r--r--src/temp/esop/esopUtil.c (renamed from src/opt/xyz/xyzMinUtil.c)76
-rw-r--r--src/temp/esop/module.make4
-rw-r--r--src/temp/ivy/ivy.h450
-rw-r--r--src/temp/ivy/ivyBalance.c421
-rw-r--r--src/temp/ivy/ivyCanon.c147
-rw-r--r--src/temp/ivy/ivyCheck.c121
-rw-r--r--src/temp/ivy/ivyCut.c205
-rw-r--r--src/temp/ivy/ivyDfs.c152
-rw-r--r--src/temp/ivy/ivyDsd.c819
-rw-r--r--src/temp/ivy/ivyMan.c207
-rw-r--r--src/temp/ivy/ivyMulti.c427
-rw-r--r--src/temp/ivy/ivyObj.c325
-rw-r--r--src/temp/ivy/ivyOper.c254
-rw-r--r--src/temp/ivy/ivyRewrite.c365
-rw-r--r--src/temp/ivy/ivySeq.c101
-rw-r--r--src/temp/ivy/ivyTable.c237
-rw-r--r--src/temp/ivy/ivyUndo.c165
-rw-r--r--src/temp/ivy/ivyUtil.c369
-rw-r--r--src/temp/ivy/ivy_.c48
-rw-r--r--src/temp/ivy/module.make14
-rw-r--r--src/temp/player/module.make5
-rw-r--r--src/temp/player/player.h123
-rw-r--r--src/temp/player/playerAbc.c215
-rw-r--r--src/temp/player/playerBuild.c279
-rw-r--r--src/temp/player/playerCore.c381
-rw-r--r--src/temp/player/playerMan.c125
-rw-r--r--src/temp/player/playerUtil.c349
129 files changed, 10550 insertions, 3904 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index 1fb57f67..29a95e46 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -53,7 +53,6 @@ typedef enum {
ABC_NTK_LOGIC, // 2: network with PIs/POs, latches, and nodes
ABC_NTK_STRASH, // 3: structurally hashed AIG (two input AND gates with c-attributes on edges)
ABC_NTK_SEQ, // 4: sequential AIG (two input AND gates with c- and latch-attributes on edges)
- ABC_NTK_BLACKBOX, // 5: black box about which nothing is known
ABC_NTK_OTHER // 6: unused
} Abc_NtkType_t;
@@ -89,8 +88,9 @@ typedef enum {
ABC_OBJ_LATCH, // 3: latch
ABC_OBJ_PI, // 4: primary input terminal
ABC_OBJ_PO, // 5: primary output terminal
- ABC_OBJ_BOX, // 6: abstract box
- ABC_OBJ_OTHER // 7: unused
+ ABC_OBJ_ASSERT, // 6: assertion output
+ ABC_OBJ_BOX, // 7: box
+ ABC_OBJ_OTHER // 8: unused
} Abc_ObjType_t;
// latch initial values
@@ -107,9 +107,11 @@ typedef enum {
////////////////////////////////////////////////////////////////////////
//typedef int bool;
+#ifndef __cplusplus
#ifndef bool
#define bool int
#endif
+#endif
typedef struct Abc_Obj_t_ Abc_Obj_t;
typedef struct Abc_Ntk_t_ Abc_Ntk_t;
@@ -120,101 +122,82 @@ typedef struct Abc_Time_t_ Abc_Time_t;
struct Abc_Time_t_
{
- float Rise;
- float Fall;
- float Worst;
+ float Rise;
+ float Fall;
+ float Worst;
};
struct Abc_Obj_t_ // 12 words
{
// high-level information
- Abc_Ntk_t * pNtk; // the host network
- int Id; // the object ID
+ Abc_Ntk_t * pNtk; // the host network
+ int Id; // the object ID
// internal information
- unsigned Type : 3; // the object type
- unsigned fMarkA : 1; // the multipurpose mark
- unsigned fMarkB : 1; // the multipurpose mark
- unsigned fMarkC : 1; // the multipurpose mark
- unsigned fPhase : 1; // the flag to mark the phase of equivalent node
- unsigned fExor : 1; // marks AIG node that is a root of EXOR
- unsigned fCompl0 : 1; // complemented attribute of the first fanin in the AIG
- unsigned fCompl1 : 1; // complemented attribute of the second fanin in the AIG
- unsigned TravId : 10; // the traversal ID (if changed, update Abc_NtkIncrementTravId)
- unsigned Level : 12; // the level of the node
+ unsigned Type : 3; // the object type
+ unsigned fMarkA : 1; // the multipurpose mark
+ unsigned fMarkB : 1; // the multipurpose mark
+ unsigned fMarkC : 1; // the multipurpose mark
+ unsigned fPhase : 1; // the flag to mark the phase of equivalent node
+ unsigned fExor : 1; // marks AIG node that is a root of EXOR
+ unsigned fPersist: 1; // marks the persistant AIG node
+ unsigned fCompl0 : 1; // complemented attribute of the first fanin in the AIG
+ unsigned fCompl1 : 1; // complemented attribute of the second fanin in the AIG
+ unsigned TravId : 9; // the traversal ID (if changed, update Abc_NtkIncrementTravId)
+ unsigned Level : 12; // the level of the node
// connectivity
- Vec_Int_t vFanins; // the array of fanins
- Vec_Int_t vFanouts; // the array of fanouts
+ Vec_Int_t vFanins; // the array of fanins
+ Vec_Int_t vFanouts; // the array of fanouts
// miscellaneous
- void * pData; // the network specific data (SOP, BDD, gate, equiv class, etc)
- Abc_Obj_t * pNext; // the next pointer in the hash table
- Abc_Obj_t * pCopy; // the copy of this object
+ void * pData; // the network specific data (SOP, BDD, gate, equiv class, etc)
+ Abc_Obj_t * pNext; // the next pointer in the hash table
+ Abc_Obj_t * pCopy; // the copy of this object
};
struct Abc_Ntk_t_
{
// general information
- Abc_NtkType_t ntkType; // type of the network
- Abc_NtkFunc_t ntkFunc; // functionality of the network
- char * pName; // the network name
- char * pSpec; // the name of the spec file if present
- int Id; // network ID
- // name representation
-// stmm_table * tName2Net; // the table hashing net names into net pointer
-// stmm_table * tObj2Name; // the table hashing PI/PO/latch pointers into names
+ Abc_NtkType_t ntkType; // type of the network
+ Abc_NtkFunc_t ntkFunc; // functionality of the network
+ char * pName; // the network name
+ char * pSpec; // the name of the spec file if present
+ int Id; // network ID
+ Nm_Man_t * pManName; // name manager (stores names of objects)
// components of the network
- Vec_Ptr_t * vObjs; // the array of all objects (net, nodes, latches)
- Vec_Ptr_t * vCis; // the array of combinational inputs (PIs followed by latches)
- Vec_Ptr_t * vCos; // the array of combinational outputs (POs followed by latches)
- Vec_Ptr_t * vAsserts; // the array of assertions
- Vec_Ptr_t * vLats; // the array of latches (or the cutset in the sequential network)
- Vec_Ptr_t * vCutSet; // the array of cutset nodes (used in the sequential AIG)
- // the stats about the number of living objects
- int nObjs; // the number of live objs
- int nNets; // the number of live nets
- int nNodes; // the number of live nodes
- int nBoxes; // the number of live nodes
- int nLatches; // the number of live latches
- int nPis; // the number of primary inputs
- int nPos; // the number of primary outputs
- int nAsserts; // the number of assertion primary outputs
- // the functionality manager
- void * pManFunc; // AIG manager, BDD manager, or memory manager for SOPs
- // the global functions (BDDs)
- void * pManGlob; // the BDD manager
- Vec_Ptr_t * vFuncsGlob; // the BDDs of CO functions
- // the timing manager (for mapped networks)
- Abc_ManTime_t * pManTime; // stores arrival/required times for all nodes
- // the cut manager (for AIGs)
- void * pManCut; // stores information about the cuts computed for the nodes
- // level information (for AIGs)
- int LevelMax; // maximum number of levels
- Vec_Int_t * vLevelsR; // level in the reverse topological order
- // support information
- Vec_Ptr_t * vSupps;
- // the satisfiable assignment of the miter
- int * pModel;
- // the external don't-care if given
- Abc_Ntk_t * pExdc; // the EXDC network
- // miscellaneous data members
- unsigned nTravIds; // the unique traversal IDs of nodes
- Vec_Ptr_t * vPtrTemp; // the temporary array
- Vec_Int_t * vIntTemp; // the temporary array
- Vec_Str_t * vStrTemp; // the temporary array
- void * pData; // the temporary pointer
- // name manager
- Nm_Man_t * pManName;
+ Vec_Ptr_t * vObjs; // the array of all objects (net, nodes, latches, etc)
+ Vec_Ptr_t * vCis; // the array of combinational inputs (PIs, latches)
+ Vec_Ptr_t * vCos; // the array of combinational outputs (POs, asserts, latches)
+ Vec_Ptr_t * vPis; // the array of PIs
+ Vec_Ptr_t * vPos; // the array of POs
+ Vec_Ptr_t * vLatches; // the array of latches (or the cutset in the sequential network)
+ Vec_Ptr_t * vAsserts; // the array of assertions
+ Vec_Ptr_t * vCutSet; // the array of cutset nodes (used in the sequential AIG)
+ // the number of living objects
+ int nObjs; // the number of live objs
+ int nNets; // the number of live nets
+ int nNodes; // the number of live nodes
+ int nBoxes; // the number of live nodes
// the backup network and the step number
- Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network
- int iStep; // the generation number for the given network
- // hierarchical design
- stmm_table * tName2Model; // the table hashing names into network pointers (or NULL if no hierarchy)
- Vec_Int_t * pBlackBoxes; // stores pairs (PI num, PO num) for each model, including the base model (or NULL if no hierarchy)
- short fHieVisited; // flag to mark the visited network
- short fHiePath; // flag to mark the network on the path
- // memory management
-// Extra_MmFlex_t * pMmNames; // memory manager for net names
- Extra_MmFixed_t* pMmObj; // memory manager for objects
- Extra_MmStep_t * pMmStep; // memory manager for arrays
+ Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network
+ int iStep; // the generation number for the given network
+ // hierarchy
+ stmm_table * tName2Model; // the table hashing names into network pointers (or NULL if no hierarchy)
+ Vec_Int_t * pBlackBoxes; // stores pairs (PI num, PO num) for each model, including the base model (or NULL if no hierarchy)
+ short fHieVisited; // flag to mark the visited network
+ short fHiePath; // flag to mark the network on the path
+ // miscellaneous data members
+ unsigned nTravIds; // the unique traversal IDs of nodes
+ Extra_MmFixed_t * pMmObj; // memory manager for objects
+ Extra_MmStep_t * pMmStep; // memory manager for arrays
+ void * pManFunc; // functionality manager (AIG manager, BDD manager, or memory manager for SOPs)
+ void * pManGlob; // the global BDD manager
+ Vec_Ptr_t * vFuncsGlob; // the global BDDs of CO functions
+ Abc_ManTime_t * pManTime; // the timing manager (for mapped networks) stores arrival/required times for all nodes
+ void * pManCut; // the cut manager (for AIGs) stores information about the cuts computed for the nodes
+ int LevelMax; // maximum number of levels
+ Vec_Int_t * vLevelsR; // level in the reverse topological order (for AIGs)
+ Vec_Ptr_t * vSupps; // CO support information
+ int * pModel; // counter-example (for miters)
+ Abc_Ntk_t * pExdc; // the EXDC network (if given)
};
////////////////////////////////////////////////////////////////////////
@@ -236,7 +219,6 @@ static inline bool Abc_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pN
static inline bool Abc_NtkIsLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_LOGIC; }
static inline bool Abc_NtkIsStrash( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_STRASH; }
static inline bool Abc_NtkIsSeq( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_SEQ; }
-static inline bool Abc_NtkIsBlackbox( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_BLACKBOX;}
static inline bool Abc_NtkHasSop( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP; }
static inline bool Abc_NtkHasBdd( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD; }
@@ -249,7 +231,7 @@ static inline bool Abc_NtkIsMappedNetlist( Abc_Ntk_t * pNtk ) { return pN
static inline bool Abc_NtkIsSopLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_NTK_LOGIC ; }
static inline bool Abc_NtkIsBddLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD && pNtk->ntkType == ABC_NTK_LOGIC ; }
static inline bool Abc_NtkIsMappedLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_LOGIC ; }
-static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return pNtk->nLatches == 0; }
+static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vLatches) == 0; }
// reading data members of the network
static inline char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; }
@@ -258,7 +240,7 @@ static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pN
static inline Abc_Ntk_t * Abc_NtkExdc( Abc_Ntk_t * pNtk ) { return pNtk->pExdc; }
static inline Abc_Ntk_t * Abc_NtkBackup( Abc_Ntk_t * pNtk ) { return pNtk->pNetBackup; }
static inline int Abc_NtkStep ( Abc_Ntk_t * pNtk ) { return pNtk->iStep; }
-static inline Abc_Obj_t * Abc_NtkConst1( Abc_Ntk_t * pNtk ) { return pNtk->vObjs->pArray[0]; }
+static inline Abc_Obj_t * Abc_NtkConst1( Abc_Ntk_t * pNtk ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vObjs, 0 ); }
// setting data members of the network
static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; }
@@ -267,25 +249,27 @@ static inline void Abc_NtkSetBackup( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNetBa
static inline void Abc_NtkSetStep ( Abc_Ntk_t * pNtk, int iStep ) { pNtk->iStep = iStep; }
// getting the number of objects
-static inline int Abc_NtkObjNumMax( Abc_Ntk_t * pNtk ) { return pNtk->vObjs->nSize; }
-static inline int Abc_NtkObjNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjs; }
-static inline int Abc_NtkNetNum( Abc_Ntk_t * pNtk ) { return pNtk->nNets; }
-static inline int Abc_NtkNodeNum( Abc_Ntk_t * pNtk ) { return pNtk->nNodes; }
-static inline int Abc_NtkLatchNum( Abc_Ntk_t * pNtk ) { return pNtk->nLatches; }
-static inline int Abc_NtkCutSetNodeNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCutSet); }
-static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return pNtk->nPis; }
-static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return pNtk->nPos; }
-static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return pNtk->vCis->nSize; }
-static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return pNtk->vCos->nSize; }
+static inline int Abc_NtkObjNumMax( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vObjs); }
+static inline int Abc_NtkObjNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjs; }
+static inline int Abc_NtkNetNum( Abc_Ntk_t * pNtk ) { return pNtk->nNets; }
+static inline int Abc_NtkNodeNum( Abc_Ntk_t * pNtk ) { return pNtk->nNodes; }
+static inline int Abc_NtkLatchNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vLatches); }
+static inline int Abc_NtkAssertNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vAsserts); }
+static inline int Abc_NtkCutSetNodeNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCutSet); }
+static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vPis); }
+static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vPos); }
+static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCis); }
+static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCos); }
// reading objects
-static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vObjs, i ); }
-static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vLats, i ); }
-static inline Abc_Obj_t * Abc_NtkCutSetNode( Abc_Ntk_t * pNtk, int i){ return Vec_PtrEntry( pNtk->vCutSet, i ); }
-static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vCis, i ); }
-static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vCos, i ); }
-static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPiNum(pNtk) ); return Abc_NtkCi( pNtk, i ); }
-static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPoNum(pNtk) ); return Abc_NtkCo( pNtk, i ); }
+static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vObjs, i ); }
+static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vLatches, i );}
+static inline Abc_Obj_t * Abc_NtkAssert( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vAsserts, i );}
+static inline Abc_Obj_t * Abc_NtkCutSetNode( Abc_Ntk_t * pNtk, int i){ return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCutSet, i ); }
+static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCis, i ); }
+static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCos, i ); }
+static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPis, i ); }
+static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPos, i ); }
// reading data members of the object
static inline unsigned Abc_ObjType( Abc_Obj_t * pObj ) { return pObj->Type; }
@@ -298,26 +282,27 @@ static inline Abc_Ntk_t * Abc_ObjNtk( Abc_Obj_t * pObj ) { return pO
static inline void * Abc_ObjData( Abc_Obj_t * pObj ) { return pObj->pData; }
// setting data members of the network
-static inline void Abc_ObjSetCopy( Abc_Obj_t * pObj, Abc_Obj_t * pCopy ) { pObj->pCopy = pCopy; }
-static inline void Abc_ObjSetData( Abc_Obj_t * pObj, void * pData ) { pObj->pData = pData; }
+static inline void Abc_ObjSetCopy( Abc_Obj_t * pObj, Abc_Obj_t * pCopy ) { pObj->pCopy = pCopy; }
+static inline void Abc_ObjSetData( Abc_Obj_t * pObj, void * pData ) { pObj->pData = pData; }
// working with complemented attributes of objects
-static inline bool Abc_ObjIsComplement( Abc_Obj_t * p ) { return (bool)(((unsigned)p) & 01); }
-static inline Abc_Obj_t * Abc_ObjRegular( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned)(p) & ~01); }
-static inline Abc_Obj_t * Abc_ObjNot( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned)(p) ^ 01); }
-static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (Abc_Obj_t *)((unsigned)(p) ^ (c)); }
+static inline bool Abc_ObjIsComplement( Abc_Obj_t * p ) { return (bool)((unsigned long)p & (unsigned long)01); }
+static inline Abc_Obj_t * Abc_ObjRegular( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned long)p & ~(unsigned long)01); }
+static inline Abc_Obj_t * Abc_ObjNot( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned long)p ^ (unsigned long)01); }
+static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (Abc_Obj_t *)((unsigned long)p ^ (unsigned long)(c!=0)); }
// checking the object type
static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; }
static inline bool Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BOX; }
static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; }
static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH; }
+static inline bool Abc_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; }
static inline bool Abc_ObjIsPi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI; }
static inline bool Abc_ObjIsPo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO; }
static inline bool Abc_ObjIsPio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO; }
static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_LATCH; }
-static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH; }
-static inline bool Abc_ObjIsCio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH; }
+static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; }
+static inline bool Abc_ObjIsCio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; }
// working with fanin/fanout edges
static inline int Abc_ObjFaninNum( Abc_Obj_t * pObj ) { return pObj->vFanins.nSize; }
@@ -331,8 +316,8 @@ static inline Abc_Obj_t * Abc_ObjFanout0( Abc_Obj_t * pObj ) { return (A
static inline Abc_Obj_t * Abc_ObjFanin( Abc_Obj_t * pObj, int i ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[i] ]; }
static inline Abc_Obj_t * Abc_ObjFanin0( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[0] ]; }
static inline Abc_Obj_t * Abc_ObjFanin1( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[1] ]; }
-static inline Abc_Obj_t * Abc_ObjFanin0Ntk( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)(Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanin0(pObj) : pObj); }
-static inline Abc_Obj_t * Abc_ObjFanout0Ntk( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)(Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanout0(pObj) : pObj); }
+static inline Abc_Obj_t * Abc_ObjFanin0Ntk( Abc_Obj_t * pObj ) { return (Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanin0(pObj) : pObj); }
+static inline Abc_Obj_t * Abc_ObjFanout0Ntk( Abc_Obj_t * pObj ) { return (Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanout0(pObj) : pObj); }
static inline bool Abc_ObjFaninC0( Abc_Obj_t * pObj ) { return pObj->fCompl0; }
static inline bool Abc_ObjFaninC1( Abc_Obj_t * pObj ) { return pObj->fCompl1; }
static inline bool Abc_ObjFaninC( Abc_Obj_t * pObj, int i ) { assert( i >=0 && i < 2 ); return i? pObj->fCompl1 : pObj->fCompl0; }
@@ -354,6 +339,11 @@ extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode );
extern bool Abc_NodeIsBuf( Abc_Obj_t * pNode );
extern bool Abc_NodeIsInv( Abc_Obj_t * pNode );
+// handling persistent nodes
+static inline int Abc_NodeIsPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); return pNode->fPersist; }
+static inline void Abc_NodeSetPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); pNode->fPersist = 1; }
+static inline void Abc_NodeClearPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); pNode->fPersist = 0; }
+
// working with the traversal ID
static inline void Abc_NodeSetTravId( Abc_Obj_t * pNode, int TravId ) { pNode->TravId = TravId; }
static inline void Abc_NodeSetTravIdCurrent( Abc_Obj_t * pNode ) { pNode->TravId = pNode->pNtk->nTravIds; }
@@ -386,28 +376,29 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab
#define Abc_NtkForEachNet( pNtk, pNet, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNet) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNet) == NULL || !Abc_ObjIsNet(pNet) ) {} else
-#define Abc_NtkForEachLatch( pNtk, pLatch, i ) \
- for ( i = 0; (i < Vec_PtrSize((pNtk)->vLats)) && (((pLatch) = Abc_NtkLatch(pNtk, i)), 1); i++ )\
- if ( (pLatch) == NULL ) {} else
#define Abc_NtkForEachNode( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else
-#define Abc_NtkForEachBox( pNtk, pNode, i ) \
- for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
- if ( (pNode) == NULL || !Abc_ObjIsBox(pNode) ) {} else
#define Abc_AigForEachAnd( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_NodeIsAigAnd(pNode) ) {} else
+#define Abc_NtkForEachBox( pNtk, pNode, i ) \
+ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
+ if ( (pNode) == NULL || !Abc_ObjIsBox(pNode) ) {} else
#define Abc_SeqForEachCutsetNode( pNtk, pNode, i ) \
for ( i = 0; (i < Abc_NtkCutSetNodeNum(pNtk)) && (((pNode) = Abc_NtkCutSetNode(pNtk, i)), 1); i++ )\
if ( (pNode) == NULL ) {} else
// inputs and outputs
#define Abc_NtkForEachPi( pNtk, pPi, i ) \
for ( i = 0; (i < Abc_NtkPiNum(pNtk)) && (((pPi) = Abc_NtkPi(pNtk, i)), 1); i++ )
-#define Abc_NtkForEachPo( pNtk, pPo, i ) \
- for ( i = 0; (i < Abc_NtkPoNum(pNtk)) && (((pPo) = Abc_NtkPo(pNtk, i)), 1); i++ )
#define Abc_NtkForEachCi( pNtk, pCi, i ) \
for ( i = 0; (i < Abc_NtkCiNum(pNtk)) && (((pCi) = Abc_NtkCi(pNtk, i)), 1); i++ )
+#define Abc_NtkForEachPo( pNtk, pPo, i ) \
+ for ( i = 0; (i < Abc_NtkPoNum(pNtk)) && (((pPo) = Abc_NtkPo(pNtk, i)), 1); i++ )
+#define Abc_NtkForEachAssert( pNtk, pAssert, i ) \
+ for ( i = 0; (i < Vec_PtrSize((pNtk)->vAsserts)) && (((pAssert) = Abc_NtkAssert(pNtk, i)), 1); i++ )
+#define Abc_NtkForEachLatch( pNtk, pLatch, i ) \
+ for ( i = 0; (i < Vec_PtrSize((pNtk)->vLatches)) && (((pLatch) = Abc_NtkLatch(pNtk, i)), 1); i++ )
#define Abc_NtkForEachCo( pNtk, pCo, i ) \
for ( i = 0; (i < Abc_NtkCoNum(pNtk)) && (((pCo) = Abc_NtkCo(pNtk, i)), 1); i++ )
// fanin and fanouts
@@ -533,6 +524,7 @@ extern Abc_Obj_t * Abc_NtkCreateBox( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk );
+extern Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
@@ -545,8 +537,6 @@ extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
extern void Abc_ObjAdd( Abc_Obj_t * pObj );
/*=== abcNames.c ====================================================*/
-//extern char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName );
-//extern char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix );
extern char * Abc_ObjName( Abc_Obj_t * pNode );
extern char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix );
extern char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits );
@@ -562,6 +552,7 @@ extern int Abc_NodeCompareNames( Abc_Obj_t ** pp1, Abc_Obj_t ** p
extern void Abc_NtkOrderObjsByName( Abc_Ntk_t * pNtk, int fComb );
extern void Abc_NtkAddDummyPiNames( Abc_Ntk_t * pNtk );
extern void Abc_NtkAddDummyPoNames( Abc_Ntk_t * pNtk );
+extern void Abc_NtkAddDummyAssertNames( Abc_Ntk_t * pNtk );
extern void Abc_NtkAddDummyLatchNames( Abc_Ntk_t * pNtk );
extern void Abc_NtkShortNames( Abc_Ntk_t * pNtk );
/*=== abcNetlist.c ==========================================================*/
@@ -581,8 +572,6 @@ extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
extern Abc_Ntk_t * Abc_NtkStartFromDual( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
-extern void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
-extern void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkStartRead( char * pName );
extern void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk );
@@ -627,7 +616,7 @@ extern int Abc_NodeRef_rec( Abc_Obj_t * pNode );
extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor );
extern DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld );
/*=== abcSat.c ==========================================================*/
-extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFront, int fVerbose );
+extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fJFront, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects );
extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront );
/*=== abcSop.c ==========================================================*/
extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
@@ -646,6 +635,7 @@ extern char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateMux( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateInv( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan );
+extern char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth );
extern int Abc_SopGetCubeNum( char * pSop );
extern int Abc_SopGetLitNum( char * pSop );
extern int Abc_SopGetVarNum( char * pSop );
@@ -709,6 +699,7 @@ extern int Abc_HManPopulate( Abc_Ntk_t * pNtk );
extern int Abc_HManVerify( int NtkIdOld, int NtkIdNew );
/*=== abcUtil.c ==========================================================*/
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
+extern void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk );
diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c
index 49e0e825..af6f4ef7 100644
--- a/src/base/abc/abcCheck.c
+++ b/src/base/abc/abcCheck.c
@@ -92,7 +92,8 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj, * pNet, * pNode;
int i;
- if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) && !Abc_NtkIsBlackbox(pNtk) )
+ // check network types
+ if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) )
{
fprintf( stdout, "NetworkCheck: Unknown network type.\n" );
return 0;
@@ -111,6 +112,22 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
}
}
+ // check CI/CO numbers
+ if ( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCiNum(pNtk) )
+ {
+ fprintf( stdout, "NetworkCheck: Number of CIs does not match number of PIs and latches.\n" );
+ fprintf( stdout, "One possible reason is that latches are added twice:\n" );
+ fprintf( stdout, "in procedure Abc_ObjAdd() and in the user's code.\n" );
+ return 0;
+ }
+ if ( Abc_NtkPoNum(pNtk) + Abc_NtkAssertNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCoNum(pNtk) )
+ {
+ fprintf( stdout, "NetworkCheck: Number of COs does not match number of POs, asserts, and latches.\n" );
+ fprintf( stdout, "One possible reason is that latches are added twice:\n" );
+ fprintf( stdout, "in procedure Abc_ObjAdd() and in the user's code.\n" );
+ return 0;
+ }
+
// check the names
if ( !Abc_NtkCheckNames( pNtk ) )
return 0;
@@ -181,14 +198,7 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
// check the EXDC network if present
if ( pNtk->pExdc )
- {
-// if ( pNtk->Type != pNtk->pExdc->Type )
-// {
-// fprintf( stdout, "NetworkCheck: Network and its EXDC have different types.\n" );
-// return 0;
-// }
- return Abc_NtkCheck( pNtk->pExdc );
- }
+ Abc_NtkCheck( pNtk->pExdc );
// check the hierarchy
if ( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model )
@@ -226,76 +236,60 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
***********************************************************************/
bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
{
- stmm_generator * gen;
- Abc_Obj_t * pNet, * pNet2, * pObj;
+ Abc_Obj_t * pObj;
+ Vec_Int_t * vNameIds;
char * pName;
- int i;
+ int i, NameId;
- if ( Abc_NtkIsNetlist(pNtk) )
+ // check that each CI/CO has a name
+ Abc_NtkForEachCi( pNtk, pObj, i )
{
-/*
- // check that the nets in the table are also in the network
- stmm_foreach_item( pNtk->tName2Net, gen, &pName, (char**)&pNet )
+ pObj = Abc_ObjFanout0Ntk(pObj);
+ if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) == NULL )
{
- if ( pNet->pData != pName )
- {
- fprintf( stdout, "NetworkCheck: Net \"%s\" has different name compared to the one in the name table.\n", pNet->pData );
- return 0;
- }
- }
- // check that the nets with names are also in the table
- Abc_NtkForEachNet( pNtk, pNet, i )
- {
- if ( pNet->pData && !stmm_lookup( pNtk->tName2Net, pNet->pData, (char**)&pNet2 ) )
- {
- fprintf( stdout, "NetworkCheck: Net \"%s\" is in the network but not in the name table.\n", pNet->pData );
- return 0;
- }
+ fprintf( stdout, "NetworkCheck: CI with ID %d is in the network but not in the name table.\n", pObj->Id );
+ return 0;
}
-*/
}
-/*
- // check PI/PO/latch names
- Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NtkForEachCo( pNtk, pObj, i )
{
- if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) )
- {
- fprintf( stdout, "NetworkCheck: PI \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) );
- return 0;
- }
- if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanout0(pObj)), pName ) )
+ if ( Abc_ObjIsLatch(pObj) )
+ continue;
+ pObj = Abc_ObjFanin0Ntk(pObj);
+ if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) == NULL )
{
- fprintf( stdout, "NetworkCheck: PI \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) );
+ fprintf( stdout, "NetworkCheck: CO with ID %d is in the network but not in the name table.\n", pObj->Id );
return 0;
}
}
- Abc_NtkForEachPo( pNtk, pObj, i )
+
+ if ( Abc_NtkIsNetlist(pNtk) )
{
- if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) )
- {
- fprintf( stdout, "NetworkCheck: PO \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) );
- return 0;
- }
- if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanin0(pObj)), pName ) )
+ Abc_NtkForEachNet( pNtk, pObj, i )
{
- fprintf( stdout, "NetworkCheck: PO \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) );
- return 0;
+ pName = Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id);
+ if ( pObj->pData && strcmp( pName, pObj->pData ) != 0 )
+ {
+ fprintf( stdout, "NetworkCheck: Net \"%s\" has different name in the name table and at the data pointer.\n", pObj->pData );
+ return 0;
+ }
}
}
- Abc_NtkForEachLatch( pNtk, pObj, i )
+
+ // return the array of all IDs, which have names
+ vNameIds = Nm_ManReturnNameIds( pNtk->pManName );
+ // make sure that these IDs correspond to live objects
+ Vec_IntForEachEntry( vNameIds, NameId, i )
{
- if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) )
- {
- fprintf( stdout, "NetworkCheck: Latch \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) );
- return 0;
- }
- if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanout0(pObj)), pName ) )
+ if ( Vec_PtrEntry( pNtk->vObjs, NameId ) == NULL )
{
- fprintf( stdout, "NetworkCheck: Latch \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) );
+ Vec_IntFree( vNameIds );
+ pName = Nm_ManFindNameById(pObj->pNtk->pManName, NameId);
+ fprintf( stdout, "NetworkCheck: Object with ID %d is deleted but its name \"%s\" remains in the name table.\n", NameId, pName );
return 0;
}
}
-*/
+ Vec_IntFree( vNameIds );
return 1;
}
@@ -316,12 +310,6 @@ bool Abc_NtkCheckPis( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
int i;
- if ( Abc_NtkCiNum(pNtk) != Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) )
- {
- fprintf( stdout, "NetworkCheck: Incorrect size of the PI array.\n" );
- return 0;
- }
-
// check that PIs are indeed PIs
Abc_NtkForEachPi( pNtk, pObj, i )
{
@@ -370,12 +358,6 @@ bool Abc_NtkCheckPos( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
int i;
- if ( Abc_NtkCoNum(pNtk) != Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) )
- {
- fprintf( stdout, "NetworkCheck: Incorrect size of the PO array.\n" );
- return 0;
- }
-
// check that POs are indeed POs
Abc_NtkForEachPo( pNtk, pObj, i )
{
@@ -582,7 +564,7 @@ bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode )
bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch )
{
int Value = 1;
- if ( pNtk->vLats->nSize != Abc_NtkLatchNum(pNtk) )
+ if ( pNtk->vLatches->nSize != Abc_NtkLatchNum(pNtk) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the latch array.\n" );
return 0;
@@ -759,7 +741,7 @@ int Abc_NtkIsAcyclicHierarchy_rec( Abc_Ntk_t * pNtk )
return 1;
pNtk->fHieVisited = 1;
// return if black box
- if ( Abc_NtkIsBlackbox(pNtk) )
+ if ( Abc_NtkHasBlackbox(pNtk) )
return 1;
assert( Abc_NtkIsNetlist(pNtk) );
// go through all the children networks
diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c
index bd707c25..79669657 100644
--- a/src/base/abc/abcDfs.c
+++ b/src/base/abc/abcDfs.c
@@ -579,7 +579,7 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
Abc_Obj_t * pFanin;
int fAcyclic, i;
assert( !Abc_ObjIsNet(pNode) );
- if ( Abc_ObjIsCi(pNode) )
+ if ( Abc_ObjIsCi(pNode) || Abc_ObjIsBox(pNode) )
return 1;
assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
// make sure the node is not visited
@@ -607,7 +607,7 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
if ( fAcyclic = Abc_NtkIsAcyclic_rec(pFanin) )
continue;
// return as soon as the loop is detected
- fprintf( stdout, " <-- %s", Abc_ObjName(pNode) );
+ fprintf( stdout, " <-- %s", Abc_ObjName(Abc_ObjFanout0(pFanin)) );
return 0;
}
// mark this node as a visited node
diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c
index 60e847d0..2a84212e 100644
--- a/src/base/abc/abcFanio.c
+++ b/src/base/abc/abcFanio.c
@@ -50,7 +50,7 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id );
if ( Abc_ObjIsComplement(pFanin) )
Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
- Abc_HManAddFanin( pObj, pFanin );
+// Abc_HManAddFanin( pObj, pFanin );
}
@@ -179,7 +179,7 @@ void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFa
***********************************************************************/
void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo )
{
- Vec_Ptr_t * vFanouts = pNodeFrom->pNtk->vPtrTemp;
+ Vec_Ptr_t * vFanouts;
int nFanoutsOld, i;
assert( !Abc_ObjIsComplement(pNodeFrom) );
assert( !Abc_ObjIsComplement(pNodeTo) );
@@ -190,12 +190,14 @@ void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo )
assert( Abc_ObjFanoutNum(pNodeFrom) > 0 );
// get the fanouts of the old node
nFanoutsOld = Abc_ObjFanoutNum(pNodeTo);
+ vFanouts = Vec_PtrAlloc( nFanoutsOld );
Abc_NodeCollectFanouts( pNodeFrom, vFanouts );
// patch the fanin of each of them
for ( i = 0; i < vFanouts->nSize; i++ )
Abc_ObjPatchFanin( vFanouts->pArray[i], pNodeFrom, pNodeTo );
assert( Abc_ObjFanoutNum(pNodeFrom) == 0 );
assert( Abc_ObjFanoutNum(pNodeTo) == nFanoutsOld + vFanouts->nSize );
+ Vec_PtrFree( vFanouts );
}
/**Function*************************************************************
diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c
index 85dd9d8e..610e311a 100644
--- a/src/base/abc/abcLatch.c
+++ b/src/base/abc/abcLatch.c
@@ -155,9 +155,6 @@ void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches )
pLatch = Abc_NtkCreateLatch( pNtk );
Abc_ObjAddFanin( pLatch, pFanin );
Abc_LatchSetInitDc( pLatch );
- // add the latch to the CI/CO lists
- Vec_PtrPush( pNtk->vCis, pLatch );
- Vec_PtrPush( pNtk->vCos, pLatch );
// create the name of the new latch
Abc_NtkLogicStoreName( pLatch, Abc_ObjNameDummy("LL", i*nLatches + k, nDigits) );
}
diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c
index cf5ad320..604dd96e 100644
--- a/src/base/abc/abcMinBase.c
+++ b/src/base/abc/abcMinBase.c
@@ -65,8 +65,8 @@ int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk )
***********************************************************************/
int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
{
- Vec_Str_t * vSupport = pNode->pNtk->vStrTemp;
- Vec_Ptr_t * vFanins = pNode->pNtk->vPtrTemp;
+ Vec_Str_t * vSupport;
+ Vec_Ptr_t * vFanins;
DdNode * bTemp;
int i, nVars;
@@ -74,11 +74,16 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
assert( Abc_ObjIsNode(pNode) );
// compute support
+ vSupport = Vec_StrAlloc( 10 );
nVars = Abc_NodeSupport( Cudd_Regular(pNode->pData), vSupport, Abc_ObjFaninNum(pNode) );
if ( nVars == Abc_ObjFaninNum(pNode) )
+ {
+ Vec_StrFree( vSupport );
return 0;
+ }
// remove unused fanins
+ vFanins = Vec_PtrAlloc( Abc_ObjFaninNum(pNode) );
Abc_NodeCollectFanins( pNode, vFanins );
for ( i = 0; i < vFanins->nSize; i++ )
if ( vSupport->pArray[i] == 0 )
@@ -88,6 +93,8 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
// update the function of the node
pNode->pData = Extra_bddRemapUp( pNode->pNtk->pManFunc, bTemp = pNode->pData ); Cudd_Ref( pNode->pData );
Cudd_RecursiveDeref( pNode->pNtk->pManFunc, bTemp );
+ Vec_PtrFree( vFanins );
+ Vec_StrFree( vSupport );
return 1;
}
diff --git a/src/base/abc/abcNames.c b/src/base/abc/abcNames.c
index f9fbe9db..4ddd2061 100644
--- a/src/base/abc/abcNames.c
+++ b/src/base/abc/abcNames.c
@@ -30,55 +30,6 @@
/**Function*************************************************************
- Synopsis [Registers the name with the string memory manager.]
-
- Description [This function should be used to register all names
- permanentsly stored with the network. The pointer returned by
- this procedure contains the copy of the name, which should be used
- in all network manipulation procedures.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName )
-{
-/*
- char * pRegName;
- if ( pName == NULL ) return NULL;
- pRegName = Extra_MmFlexEntryFetch( pNtk->pMmNames, strlen(pName) + 1 );
- strcpy( pRegName, pName );
- return pRegName;
-*/
- return NULL;
-}
-
-/**Function*************************************************************
-
- Synopsis [Registers the name with the string memory manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix )
-{
-/*
- char * pRegName;
- assert( pName && pSuffix );
- pRegName = Extra_MmFlexEntryFetch( pNtk->pMmNames, strlen(pName) + strlen(pSuffix) + 1 );
- sprintf( pRegName, "%s%s", pName, pSuffix );
- return pRegName;
-*/
- return NULL;
-}
-
-/**Function*************************************************************
-
Synopsis [Gets the long name of the object.]
Description [The temporary name is stored in a static buffer inside this
@@ -176,20 +127,7 @@ char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits )
***********************************************************************/
char * Abc_NtkLogicStoreName( Abc_Obj_t * pObjNew, char * pNameOld )
{
-/*
- char * pNewName;
- assert( Abc_ObjIsCio(pObjNew) );
- // get the new name
- pNewName = Abc_NtkRegisterName( pObjNew->pNtk, pNameOld );
- // add the name to the table
- if ( stmm_insert( pObjNew->pNtk->tObj2Name, (char *)pObjNew, pNewName ) )
- {
- assert( 0 ); // the object is added for the second time
- }
- return pNewName;
-*/
- Nm_ManStoreIdName( pObjNew->pNtk->pManName, pObjNew->Id, pNameOld, NULL );
- return NULL;
+ return Nm_ManStoreIdName( pObjNew->pNtk->pManName, pObjNew->Id, pNameOld, NULL );
}
/**Function*************************************************************
@@ -205,21 +143,7 @@ char * Abc_NtkLogicStoreName( Abc_Obj_t * pObjNew, char * pNameOld )
***********************************************************************/
char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pObjNew, char * pNameOld, char * pSuffix )
{
-/*
- char * pNewName;
- assert( pSuffix );
- assert( Abc_ObjIsCio(pObjNew) );
- // get the new name
- pNewName = Abc_NtkRegisterNamePlus( pObjNew->pNtk, pNameOld, pSuffix );
- // add the name to the table
- if ( stmm_insert( pObjNew->pNtk->tObj2Name, (char *)pObjNew, pNewName ) )
- {
- assert( 0 ); // the object is added for the second time
- }
- return pNewName;
-*/
- Nm_ManStoreIdName( pObjNew->pNtk->pManName, pObjNew->Id, pNameOld, pSuffix );
- return NULL;
+ return Nm_ManStoreIdName( pObjNew->pNtk->pManName, pObjNew->Id, pNameOld, pSuffix );
}
/**Function*************************************************************
@@ -239,17 +163,20 @@ void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
int i;
assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) );
assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) );
+ assert( Abc_NtkAssertNum(pNtk) == Abc_NtkAssertNum(pNtkNew) );
assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) );
-// assert( st_count(pNtk->tObj2Name) > 0 );
-// assert( st_count(pNtkNew->tObj2Name) == 0 );
+ assert( Nm_ManNumEntries(pNtk->pManName) > 0 );
+ assert( Nm_ManNumEntries(pNtkNew->pManName) == 0 );
// copy the CI/CO names if given
Abc_NtkForEachPi( pNtk, pObj, i )
- Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) );
+ Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) );
Abc_NtkForEachPo( pNtk, pObj, i )
- Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(Abc_ObjFanin0Ntk(pObj)) );
+ Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(Abc_ObjFanin0Ntk(pObj)) );
+ Abc_NtkForEachAssert( pNtk, pObj, i )
+ Abc_NtkLogicStoreName( Abc_NtkAssert(pNtkNew,i), Abc_ObjName(Abc_ObjFanin0Ntk(pObj)) );
if ( !Abc_NtkIsSeq(pNtk) )
Abc_NtkForEachLatch( pNtk, pObj, i )
- Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) );
+ Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) );
}
/**Function*************************************************************
@@ -270,8 +197,8 @@ void Abc_NtkDupCioNamesTableDual( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) );
assert( Abc_NtkPoNum(pNtk) * 2 == Abc_NtkPoNum(pNtkNew) );
assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) );
-// assert( st_count(pNtk->tObj2Name) > 0 );
-// assert( st_count(pNtkNew->tObj2Name) == 0 );
+ assert( Nm_ManNumEntries(pNtk->pManName) > 0 );
+ assert( Nm_ManNumEntries(pNtkNew->pManName) == 0 );
// copy the CI/CO names if given
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pObj) );
@@ -280,6 +207,8 @@ void Abc_NtkDupCioNamesTableDual( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
Abc_NtkLogicStoreNamePlus( Abc_NtkPo(pNtkNew,2*i+0), Abc_ObjName(pObj), "_pos" );
Abc_NtkLogicStoreNamePlus( Abc_NtkPo(pNtkNew,2*i+1), Abc_ObjName(pObj), "_neg" );
}
+ Abc_NtkForEachAssert( pNtk, pObj, i )
+ Abc_NtkLogicStoreName( Abc_NtkAssert(pNtkNew,i), Abc_ObjName(pObj) );
if ( !Abc_NtkIsSeq(pNtk) )
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(pObj) );
@@ -439,22 +368,16 @@ void Abc_NtkOrderObjsByName( Abc_Ntk_t * pNtk, int fComb )
Abc_NtkForEachLatch( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj);
// order objects alphabetically
- qsort( pNtk->vCis->pArray, pNtk->nPis, sizeof(Abc_Obj_t *),
+ qsort( (void *)Vec_PtrArray(pNtk->vPis), Vec_PtrSize(pNtk->vPis), sizeof(Abc_Obj_t *),
(int (*)(const void *, const void *)) Abc_NodeCompareNames );
- qsort( pNtk->vCos->pArray, pNtk->nPos, sizeof(Abc_Obj_t *),
+ qsort( (void *)Vec_PtrArray(pNtk->vPos), Vec_PtrSize(pNtk->vPos), sizeof(Abc_Obj_t *),
(int (*)(const void *, const void *)) Abc_NodeCompareNames );
// if the comparison if combinational (latches as PIs/POs), order them too
if ( fComb )
- {
- qsort( pNtk->vLats->pArray, pNtk->nLatches, sizeof(Abc_Obj_t *),
+ qsort( (void *)Vec_PtrArray(pNtk->vLatches), Vec_PtrSize(pNtk->vLatches), sizeof(Abc_Obj_t *),
(int (*)(const void *, const void *)) Abc_NodeCompareNames );
- // add latches to make COs
- Abc_NtkForEachLatch( pNtk, pObj, i )
- {
- Vec_PtrWriteEntry( pNtk->vCis, pNtk->nPis + i, pObj );
- Vec_PtrWriteEntry( pNtk->vCos, pNtk->nPos + i, pObj );
- }
- }
+ // order CIs/COs first PIs/POs(Asserts) then latches
+ Abc_NtkOrderCisCos( pNtk );
// clean the copy fields
Abc_NtkForEachPi( pNtk, pObj, i )
pObj->pCopy = NULL;
@@ -515,6 +438,26 @@ void Abc_NtkAddDummyPoNames( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
+void Abc_NtkAddDummyAssertNames( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int nDigits, i;
+ nDigits = Extra_Base10Log( Abc_NtkAssertNum(pNtk) );
+ Abc_NtkForEachAssert( pNtk, pObj, i )
+ Abc_NtkLogicStoreName( pObj, Abc_ObjNameDummy("a", i, nDigits) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds dummy names.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Abc_NtkAddDummyLatchNames( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
@@ -537,13 +480,11 @@ void Abc_NtkAddDummyLatchNames( Abc_Ntk_t * pNtk )
***********************************************************************/
void Abc_NtkShortNames( Abc_Ntk_t * pNtk )
{
-// stmm_free_table( pNtk->tObj2Name );
-// pNtk->tObj2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash);
Nm_ManFree( pNtk->pManName );
- pNtk->pManName = Nm_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) + 10 );
-
+ pNtk->pManName = Nm_ManCreate( Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk) - Abc_NtkLatchNum(pNtk) + 10 );
Abc_NtkAddDummyPiNames( pNtk );
Abc_NtkAddDummyPoNames( pNtk );
+ Abc_NtkAddDummyAssertNames( pNtk );
Abc_NtkAddDummyLatchNames( pNtk );
}
diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c
index 75f3ed33..7d4460bf 100644
--- a/src/base/abc/abcNetlist.c
+++ b/src/base/abc/abcNetlist.c
@@ -106,33 +106,22 @@ Abc_Ntk_t * Abc_NtkNetlistToLogicHie( Abc_Ntk_t * pNtk )
// clean the node copy fields
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = NULL;
- // map the constant nodes
- if ( Abc_NtkConst1(pNtk) )
- Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
- // clone PIs/POs and make old nets point to new terminals; create PI/PO names
- Abc_NtkForEachPi( pNtk, pObj, i )
+ // clone PIs/POs/latches and make old nets point to new terminals; create names
+ Abc_NtkForEachCi( pNtk, pObj, i )
{
Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj(pNtkNew, pObj);
- Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
+ Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(Abc_ObjFanout0(pObj)) );
}
Abc_NtkForEachPo( pNtk, pObj, i )
{
Abc_NtkDupObj(pNtkNew, pObj);
- Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
+ Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(Abc_ObjFanin0(pObj)) );
}
// recursively flatten hierarchy, create internal logic, add new PI/PO names if there are black boxes
Abc_NtkNetlistToLogicHie_rec( pNtkNew, pNtk, &Counter );
if ( Counter )
printf( "Warning: The total of %d block boxes are transformed into PI/PO pairs.\n", Counter );
- // add latches
- Abc_NtkForEachLatch( pNtk, pObj, i )
- {
- Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj(pNtkNew, pObj);
- Vec_PtrPush( pNtkNew->vCis, pObj->pCopy );
- Vec_PtrPush( pNtkNew->vCos, pObj->pCopy );
- Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(pObj) );
- }
- // collect the CO nodes
+ // connect the CO nodes
Abc_NtkForEachCo( pNtk, pObj, i )
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
// copy the timing information
@@ -167,62 +156,75 @@ void Abc_NtkNetlistToLogicHie_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtkOld, int
int i, k;
// collect nodes and boxes in topological order
vNodes = Abc_NtkDfs( pNtkOld, 0 );
- // create logic for nodes and boxes
+ // duplicate nodes, create PIs/POs corresponding to blackboxes
+ // have to do it first if blackboxes break combinational loops
+ // (current we do not allow whiteboxes to break combinational loops)
Vec_PtrForEachEntry( vNodes, pNode, i )
{
- if ( Abc_ObjFaninNum(pNode) == 0 )
- continue;
if ( Abc_ObjIsNode(pNode) )
{
// duplicate the node and save it in the fanout net
Abc_NtkDupObj( pNtkNew, pNode );
+ Abc_ObjFanout0(pNode)->pCopy = pNode->pCopy;
+ continue;
+ }
+ assert( Abc_ObjIsBox(pNode) );
+ pNtkModel = pNode->pData;
+ if ( !Abc_NtkHasBlackbox(pNtkModel) )
+ continue;
+ // consider this blockbox
+ if ( pNtkNew->pBlackBoxes == NULL )
+ {
+ pNtkNew->pBlackBoxes = Vec_IntAlloc( 10 );
+ Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) );
+ }
+ sprintf( Prefix, "%s_%d_", Abc_NtkName(pNtkModel), *pCounter );
+ // create new PIs from the POs of the box
+ Abc_NtkForEachPo( pNtkModel, pObj, k )
+ {
+ pObj->pCopy = Abc_NtkCreatePi( pNtkNew );
+ Abc_ObjFanout(pNode, k)->pCopy = pObj->pCopy;
+ Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(Abc_ObjFanin0(pObj)) );
+ }
+ // create new POs from the PIs of the box
+ Abc_NtkForEachPi( pNtkModel, pObj, k )
+ {
+ pObj->pCopy = Abc_NtkCreatePo( pNtkNew );
+// Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin(pNode, k)->pCopy );
+ Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(Abc_ObjFanout0(pObj)) );
+ }
+ (*pCounter)++;
+ Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) );
+ }
+ // connect nodes and boxes
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( Abc_ObjIsNode(pNode) )
+ {
+// printf( "adding node %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
Abc_ObjForEachFanin( pNode, pFanin, k )
Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy );
- Abc_ObjFanout0(pNode)->pCopy = pNode->pCopy;
continue;
}
assert( Abc_ObjIsBox(pNode) );
pNtkModel = pNode->pData;
+// printf( "adding model %s\n", Abc_NtkName(pNtkModel) );
// consider the case of the black box
- if ( Abc_NtkIsBlackbox(pNtkModel) )
+ if ( Abc_NtkHasBlackbox(pNtkModel) )
{
- if ( pNtkNew->pBlackBoxes == NULL )
- {
- pNtkNew->pBlackBoxes = Vec_IntAlloc( 10 );
- Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) );
- }
- sprintf( Prefix, "%s_%d_", Abc_NtkName(pNtkModel), *pCounter );
- // create new PIs from the POs of the box
- Abc_NtkForEachPo( pNtkModel, pObj, k )
- {
- pObj->pCopy = Abc_NtkCreatePi( pNtkNew );
- Abc_ObjFanout(pNode, k)->pCopy = pObj->pCopy;
- Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(pObj) );
- }
// create new POs from the PIs of the box
Abc_NtkForEachPi( pNtkModel, pObj, k )
- {
- pObj->pCopy = Abc_NtkCreatePo( pNtkNew );
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin(pNode, k)->pCopy );
- Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(pObj) );
- }
- (*pCounter)++;
- Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) );
- }
- else
- {
- // map the constant nodes
- if ( Abc_NtkConst1(pNtkModel) )
- Abc_NtkConst1(pNtkModel)->pCopy = Abc_NtkConst1(pNtkNew);
- // transfer the nodes to the box inputs
- Abc_NtkForEachPi( pNtkModel, pObj, k )
- Abc_ObjFanout0(pObj)->pCopy = Abc_ObjFanin(pNode, k)->pCopy;
- // construct recursively
- Abc_NtkNetlistToLogicHie_rec( pNtkNew, pNtkModel, pCounter );
- // transfer the results back
- Abc_NtkForEachPo( pNtkModel, pObj, k )
- Abc_ObjFanout(pNode, k)->pCopy = Abc_ObjFanin0(pObj)->pCopy;
+ continue;
}
+ // transfer the nodes to the box inputs
+ Abc_NtkForEachPi( pNtkModel, pObj, k )
+ Abc_ObjFanout0(pObj)->pCopy = Abc_ObjFanin(pNode, k)->pCopy;
+ // construct recursively
+ Abc_NtkNetlistToLogicHie_rec( pNtkNew, pNtkModel, pCounter );
+ // transfer the results back
+ Abc_NtkForEachPo( pNtkModel, pObj, k )
+ Abc_ObjFanout(pNode, k)->pCopy = Abc_ObjFanin0(pObj)->pCopy;
}
Vec_PtrFree( vNodes );
}
@@ -352,7 +354,7 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
// the driver is a node
// get the CO name
- pNameCo = Abc_ObjIsPo(pObj)? Abc_ObjName(pObj) : Abc_ObjNameSuffix( pObj, "_in" );
+ pNameCo = Abc_ObjIsLatch(pObj)? Abc_ObjNameSuffix( pObj, "_in" ) : Abc_ObjName(pObj);
// make sure CO has a unique name
assert( Abc_NtkFindNet( pNtkNew, pNameCo ) == NULL );
// create the CO net and connect it to CO
@@ -401,6 +403,7 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin, * pNodeNew;
+ Vec_Int_t * vInts;
int i, k;
assert( Abc_NtkIsStrash(pNtk) );
// start the network
@@ -423,16 +426,17 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk )
// create an OR gate
pNodeNew = Abc_NtkCreateNode(pNtkNew);
// add fanins
- Vec_IntClear( pNtk->vIntTemp );
+ vInts = Vec_IntAlloc( 10 );
for ( pFanin = pObj; pFanin; pFanin = pFanin->pData )
{
- Vec_IntPush( pNtk->vIntTemp, (int)(pObj->fPhase != pFanin->fPhase) );
+ Vec_IntPush( vInts, (int)(pObj->fPhase != pFanin->fPhase) );
Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
}
// create the logic function
- pNodeNew->pData = Abc_SopCreateOrMultiCube( pNtkNew->pManFunc, pNtk->vIntTemp->nSize, pNtk->vIntTemp->pArray );
+ pNodeNew->pData = Abc_SopCreateOrMultiCube( pNtkNew->pManFunc, Vec_IntSize(vInts), Vec_IntArray(vInts) );
// set the new node
pObj->pCopy->pCopy = pNodeNew;
+ Vec_IntFree( vInts );
}
// connect the internal nodes
Abc_NtkForEachNode( pNtk, pObj, i )
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index c8bdf987..56d399f0 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -53,19 +53,14 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
pNtk->Id = !Abc_HManIsRunning()? 0 : Abc_HManGetNewNtkId();
// start the object storage
pNtk->vObjs = Vec_PtrAlloc( 100 );
- pNtk->vLats = Vec_PtrAlloc( 100 );
- pNtk->vCutSet = Vec_PtrAlloc( 100 );
+ pNtk->vLatches = Vec_PtrAlloc( 100 );
+ pNtk->vAsserts = Vec_PtrAlloc( 100 );
+ pNtk->vPis = Vec_PtrAlloc( 100 );
+ pNtk->vPos = Vec_PtrAlloc( 100 );
pNtk->vCis = Vec_PtrAlloc( 100 );
pNtk->vCos = Vec_PtrAlloc( 100 );
- pNtk->vAsserts = Vec_PtrAlloc( 100 );
- pNtk->vPtrTemp = Vec_PtrAlloc( 100 );
- pNtk->vIntTemp = Vec_IntAlloc( 100 );
- pNtk->vStrTemp = Vec_StrAlloc( 100 );
- // start the hash table
-// pNtk->tName2Net = stmm_init_table(strcmp, stmm_strhash);
-// pNtk->tObj2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash);
+ pNtk->vCutSet = Vec_PtrAlloc( 100 );
// start the memory managers
-// pNtk->pMmNames = Extra_MmFlexStart();
pNtk->pMmObj = Extra_MmFixedStart( sizeof(Abc_Obj_t) );
pNtk->pMmStep = Extra_MmStepStart( ABC_NUM_STEPS );
// get ready to assign the first Obj ID
@@ -115,7 +110,7 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func )
{
Abc_Ntk_t * pNtkNew;
- Abc_Obj_t * pObj, * pObjNew;
+ Abc_Obj_t * pObj;
int i;
if ( pNtk == NULL )
return NULL;
@@ -135,12 +130,10 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
Abc_NtkDupObj(pNtkNew, pObj);
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
+ Abc_NtkForEachAssert( pNtk, pObj, i )
+ Abc_NtkDupObj(pNtkNew, pObj);
Abc_NtkForEachLatch( pNtk, pObj, i )
- {
- pObjNew = Abc_NtkDupObj(pNtkNew, pObj);
- Vec_PtrPush( pNtkNew->vCis, pObjNew );
- Vec_PtrPush( pNtkNew->vCos, pObjNew );
- }
+ Abc_NtkDupObj(pNtkNew, pObj);
if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() )
{
Abc_HManAddProto( Abc_NtkConst1(pNtk)->pCopy, Abc_NtkConst1(pNtk) );
@@ -202,15 +195,12 @@ Abc_Ntk_t * Abc_NtkStartFromDual( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkF
// collect first to old
pObj->pCopy = pObjNew;
}
+ Abc_NtkForEachAssert( pNtk, pObj, i )
+ Abc_NtkDupObj(pNtkNew, pObj);
Abc_NtkForEachLatch( pNtk, pObj, i )
- {
- pObjNew = Abc_NtkDupObj(pNtkNew, pObj);
- Vec_PtrPush( pNtkNew->vCis, pObjNew );
- Vec_PtrPush( pNtkNew->vCos, pObjNew );
- }
+ Abc_NtkDupObj(pNtkNew, pObj);
// transfer the names
Abc_NtkDupCioNamesTableDual( pNtk, pNtkNew );
-// Abc_ManTimeDup( pNtk, pNtkNew );
// check that the CI/CO/latches are copied correctly
assert( Abc_NtkCiNum(pNtk) == Abc_NtkCiNum(pNtkNew) );
assert( Abc_NtkCoNum(pNtk)* 2 == Abc_NtkCoNum(pNtkNew) );
@@ -244,54 +234,6 @@ void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
/**Function*************************************************************
- Synopsis [Finalizes the network using the existing network as a model.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
-{
- Abc_Obj_t * pObj, * pDriver, * pDriverNew;
- int i;
- // set the COs of the strashed network
- Abc_NtkForEachCo( pNtk, pObj, i )
- {
- pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) );
- pDriverNew = pDriver->pCopy;
- Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
- }
-}
-
-/**Function*************************************************************
-
- Synopsis [Finalizes the network adding latches to CI/CO lists and creates their names.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk )
-{
- Abc_Obj_t * pLatch;
- int i;
- // set the COs of the strashed network
- Abc_NtkForEachLatch( pNtk, pLatch, i )
- {
- Vec_PtrPush( pNtk->vCis, pLatch );
- Vec_PtrPush( pNtk->vCos, pLatch );
- Abc_NtkLogicStoreName( pLatch, Abc_ObjNameSuffix(pLatch, "L") );
- }
-}
-
-/**Function*************************************************************
-
Synopsis [Starts a new network using existing network as a model.]
Description []
@@ -325,9 +267,9 @@ Abc_Ntk_t * Abc_NtkStartRead( char * pName )
***********************************************************************/
void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk )
{
- Abc_Obj_t * pLatch, * pBox, * pObj;
+ Abc_Obj_t * pBox, * pObj;
int i;
- if ( pNtk->ntkType == ABC_NTK_BLACKBOX )
+ if ( Abc_NtkHasBlackbox(pNtk) )
{
pBox = Abc_NtkCreateBox(pNtk);
Abc_NtkForEachPi( pNtk, pObj, i )
@@ -339,14 +281,8 @@ void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsNetlist(pNtk) );
// fix the net drivers
Abc_NtkFixNonDrivenNets( pNtk );
- // create the names table
-// Abc_NtkCreateCioNamesTable( pNtk );
- // add latches to the CI/CO arrays
- Abc_NtkForEachLatch( pNtk, pLatch, i )
- {
- Vec_PtrPush( pNtk->vCis, pLatch );
- Vec_PtrPush( pNtk->vCos, pLatch );
- }
+ // reorder the CI/COs to PI/POs first
+ Abc_NtkOrderCisCos( pNtk );
}
/**Function*************************************************************
@@ -740,7 +676,6 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
int LargePiece = (4 << ABC_NUM_STEPS);
if ( pNtk == NULL )
return;
-//printf( "Deleted newtork %p\n", pNtk );
// make sure all the marks are clean
Abc_NtkForEachObj( pNtk, pObj, i )
{
@@ -765,26 +700,20 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
if ( pNtk->pExdc )
Abc_NtkDelete( pNtk->pExdc );
// free the arrays
+ Vec_PtrFree( pNtk->vPis );
+ Vec_PtrFree( pNtk->vPos );
Vec_PtrFree( pNtk->vCis );
Vec_PtrFree( pNtk->vCos );
Vec_PtrFree( pNtk->vAsserts );
+ Vec_PtrFree( pNtk->vLatches );
Vec_PtrFree( pNtk->vObjs );
- Vec_PtrFree( pNtk->vLats );
Vec_PtrFree( pNtk->vCutSet );
- Vec_PtrFree( pNtk->vPtrTemp );
- Vec_IntFree( pNtk->vIntTemp );
- Vec_StrFree( pNtk->vStrTemp );
if ( pNtk->pModel ) free( pNtk->pModel );
- // free the hash table of Obj name into Obj ID
-// stmm_free_table( pNtk->tName2Net );
-// stmm_free_table( pNtk->tObj2Name );
TotalMemory = 0;
-// TotalMemory += Extra_MmFlexReadMemUsage(pNtk->pMmNames);
TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj);
TotalMemory += Extra_MmStepReadMemUsage(pNtk->pMmStep);
// fprintf( stdout, "The total memory allocated internally by the network = %0.2f Mb.\n", ((double)TotalMemory)/(1<<20) );
// free the storage
-// Extra_MmFlexStop ( pNtk->pMmNames, 0 );
Extra_MmFixedStop( pNtk->pMmObj, 0 );
Extra_MmStepStop ( pNtk->pMmStep, 0 );
// free the timing manager
@@ -802,7 +731,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
else
Seq_Delete( pNtk->pManFunc );
}
- else if ( !Abc_NtkHasMapping(pNtk) )
+ else if ( !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlackbox(pNtk) )
assert( 0 );
// name manager
Nm_ManFree( pNtk->pManName );
@@ -815,9 +744,9 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
stmm_foreach_item( pNtk->tName2Model, gen, &pName, (char **)&pNtkTemp )
Abc_NtkDelete( pNtkTemp );
stmm_free_table( pNtk->tName2Model );
- if ( pNtk->pBlackBoxes )
- Vec_IntFree( pNtk->pBlackBoxes );
}
+ if ( pNtk->pBlackBoxes )
+ Vec_IntFree( pNtk->pBlackBoxes );
free( pNtk );
}
diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c
index 56fcef95..53886161 100644
--- a/src/base/abc/abcObj.c
+++ b/src/base/abc/abcObj.c
@@ -101,34 +101,32 @@ void Abc_ObjAdd( Abc_Obj_t * pObj )
// perform specialized operations depending on the object type
if ( Abc_ObjIsNet(pObj) )
{
-/*
- // add the name to the table
- if ( pObj->pData && stmm_insert( pNtk->tName2Net, pObj->pData, (char *)pObj ) )
- {
- printf( "Error: The net is already in the table...\n" );
- assert( 0 );
- }
-*/
pNtk->nNets++;
}
else if ( Abc_ObjIsNode(pObj) )
{
pNtk->nNodes++;
}
- else if ( Abc_ObjIsLatch(pObj) )
- {
- Vec_PtrPush( pNtk->vLats, pObj );
- pNtk->nLatches++;
- }
else if ( Abc_ObjIsPi(pObj) )
{
+ Vec_PtrPush( pNtk->vPis, pObj );
Vec_PtrPush( pNtk->vCis, pObj );
- pNtk->nPis++;
}
else if ( Abc_ObjIsPo(pObj) )
{
+ Vec_PtrPush( pNtk->vPos, pObj );
+ Vec_PtrPush( pNtk->vCos, pObj );
+ }
+ else if ( Abc_ObjIsLatch(pObj) )
+ {
+ Vec_PtrPush( pNtk->vLatches, pObj );
+ Vec_PtrPush( pNtk->vCis, pObj );
+ Vec_PtrPush( pNtk->vCos, pObj );
+ }
+ else if ( Abc_ObjIsAssert(pObj) )
+ {
+ Vec_PtrPush( pNtk->vAsserts, pObj );
Vec_PtrPush( pNtk->vCos, pObj );
- pNtk->nPos++;
}
else if ( Abc_ObjIsBox(pObj) )
{
@@ -138,7 +136,6 @@ void Abc_ObjAdd( Abc_Obj_t * pObj )
{
assert( 0 );
}
- assert( pObj->Id >= 0 );
}
/**Function*************************************************************
@@ -155,7 +152,11 @@ void Abc_ObjAdd( Abc_Obj_t * pObj )
Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
{
Abc_Obj_t * pObjNew;
+ // create the new object
pObjNew = Abc_ObjAlloc( pNtkNew, pObj->Type );
+ // add the object to the network
+ Abc_ObjAdd( pObjNew );
+ // copy functionality/names
if ( Abc_ObjIsNode(pObj) ) // copy the function if functionality is compatible
{
if ( pNtkNew->ntkFunc == pObj->pNtk->ntkFunc )
@@ -172,18 +173,11 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
}
else if ( Abc_ObjIsNet(pObj) ) // copy the name
{
-// pObjNew->pData = Abc_NtkRegisterName( pNtkNew, pObj->pData );
+ pObjNew->pData = Nm_ManStoreIdName( pNtkNew->pManName, pObjNew->Id, pObj->pData, NULL );
}
else if ( Abc_ObjIsLatch(pObj) ) // copy the reset value
pObjNew->pData = pObj->pData;
pObj->pCopy = pObjNew;
- // add the object to the network
- Abc_ObjAdd( pObjNew );
-
-
- if ( Abc_ObjIsNet(pObj) )
- pObjNew->pData = Nm_ManStoreIdName( pNtkNew->pManName, pObjNew->Id, pObj->pData, NULL );
-
return pObjNew;
}
@@ -201,37 +195,34 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
***********************************************************************/
void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
{
- Vec_Ptr_t * vNodes = pObj->pNtk->vPtrTemp;
Abc_Ntk_t * pNtk = pObj->pNtk;
+ Vec_Ptr_t * vNodes;
int i;
assert( !Abc_ObjIsComplement(pObj) );
// delete fanins and fanouts
+ vNodes = Vec_PtrAlloc( 100 );
Abc_NodeCollectFanouts( pObj, vNodes );
for ( i = 0; i < vNodes->nSize; i++ )
Abc_ObjDeleteFanin( vNodes->pArray[i], pObj );
Abc_NodeCollectFanins( pObj, vNodes );
for ( i = 0; i < vNodes->nSize; i++ )
Abc_ObjDeleteFanin( pObj, vNodes->pArray[i] );
+ Vec_PtrFree( vNodes );
// remove from the list of objects
Vec_PtrWriteEntry( pNtk->vObjs, pObj->Id, NULL );
pObj->Id = (1<<26)-1;
pNtk->nObjs--;
+ // remove from the table of names
+ if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) )
+ Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id);
+
// perform specialized operations depending on the object type
if ( Abc_ObjIsNet(pObj) )
{
- assert( 0 );
-/*
- // remove the net from the hash table of nets
- if ( pObj->pData && !stmm_delete( pNtk->tName2Net, (char **)&pObj->pData, (char **)&pObj ) )
- {
- printf( "Error: The net is not in the table...\n" );
- assert( 0 );
- }
-*/
pObj->pData = NULL;
pNtk->nNets--;
}
@@ -239,26 +230,33 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
{
if ( Abc_NtkHasBdd(pNtk) )
Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData );
+ pObj->pData = NULL;
pNtk->nNodes--;
}
else if ( Abc_ObjIsLatch(pObj) )
{
- pNtk->nLatches--;
+ Vec_PtrRemove( pNtk->vLatches, pObj );
+ Vec_PtrRemove( pNtk->vCis, pObj );
+ Vec_PtrRemove( pNtk->vCos, pObj );
+ }
+ else if ( Abc_ObjIsPi(pObj) )
+ {
+ Vec_PtrRemove( pObj->pNtk->vPis, pObj );
+ Vec_PtrRemove( pObj->pNtk->vCis, pObj );
}
else if ( Abc_ObjIsPo(pObj) )
{
- assert( Abc_NtkPoNum(pObj->pNtk) > 0 );
+ Vec_PtrRemove( pObj->pNtk->vPos, pObj );
Vec_PtrRemove( pObj->pNtk->vCos, pObj );
- pObj->pNtk->nPos--;
-
- assert( 0 );
-/*
- // add the name to the table
- if ( !stmm_delete( pObj->pNtk->tObj2Name, (char **)&pObj, NULL ) )
- {
- assert( 0 ); // the PO is not in the table
- }
-*/
+ }
+ else if ( Abc_ObjIsAssert(pObj) )
+ {
+ Vec_PtrRemove( pObj->pNtk->vAsserts, pObj );
+ Vec_PtrRemove( pObj->pNtk->vCos, pObj );
+ }
+ else if ( Abc_ObjIsBox(pObj) )
+ {
+ pNtk->nBoxes--;
}
else
assert( 0 );
@@ -377,9 +375,6 @@ Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName )
Abc_Obj_t * pNet;
int ObjId;
assert( Abc_NtkIsNetlist(pNtk) );
-// if ( stmm_lookup( pNtk->tName2Net, pName, (char**)&pNet ) )
-// return pNet;
-// return NULL;
ObjId = Nm_ManFindIdByName( pNtk->pManName, pName, NULL );
if ( ObjId == -1 )
return NULL;
@@ -406,7 +401,6 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
return pNet;
// create a new net
pNet = Abc_ObjAlloc( pNtk, ABC_OBJ_NET );
-// pNet->pData = Abc_NtkRegisterName( pNtk, pName );
Abc_ObjAdd( pNet );
pNet->pData = Nm_ManStoreIdName( pNtk->pManName, pNet->Id, pName, NULL );
return pNet;
@@ -510,6 +504,25 @@ Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk )
/**Function*************************************************************
+ Synopsis [Create the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_ASSERT );
+ Abc_ObjAdd( pObj );
+ return pObj;
+}
+
+/**Function*************************************************************
+
Synopsis [Creates inverter.]
Description []
diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c
index d5cc65f1..a893f3e2 100644
--- a/src/base/abc/abcSop.c
+++ b/src/base/abc/abcSop.c
@@ -360,6 +360,44 @@ char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan )
return Abc_SopRegister(pMan, "1 1\n");
}
+/**Function*************************************************************
+
+ Synopsis [Creates the arbitrary cover from the truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth )
+{
+ char * pSop, * pCube;
+ int nMints, Counter, i, k;
+ // count the number of true minterms
+ Counter = 0;
+ nMints = (1 << nVars);
+ for ( i = 0; i < nMints; i++ )
+ Counter += ((pTruth[i>>5] & (1 << (i&31))) > 0);
+ // SOP is not well-defined if the truth table is constant 0
+ assert( Counter > 0 );
+ if ( Counter == 0 )
+ return NULL;
+ // start the cover
+ pSop = Abc_SopStart( pMan, Counter, nVars );
+ // create true minterms
+ Counter = 0;
+ for ( i = 0; i < nMints; i++ )
+ if ( (pTruth[i>>5] & (1 << (i&31))) > 0 )
+ {
+ pCube = pSop + Counter * (nVars + 3);
+ for ( k = 0; k < nVars; k++ )
+ pCube[k] = '0' + ((i & (1 << k)) > 0);
+ Counter++;
+ }
+ return pSop;
+}
/**Function*************************************************************
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index 034aa38f..175b17f7 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -47,7 +47,7 @@ void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i;
- if ( pNtk->nTravIds == (1<<10)-1 )
+ if ( pNtk->nTravIds == (1<<9)-1 )
{
pNtk->nTravIds = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
@@ -58,6 +58,36 @@ void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk )
/**Function*************************************************************
+ Synopsis [Order CI/COs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ Vec_PtrClear( pNtk->vCis );
+ Vec_PtrClear( pNtk->vCos );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Vec_PtrPush( pNtk->vCis, pObj );
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Vec_PtrPush( pNtk->vCos, pObj );
+ Abc_NtkForEachAssert( pNtk, pObj, i )
+ Vec_PtrPush( pNtk->vCos, pObj );
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ Vec_PtrPush( pNtk->vCis, pObj );
+ Vec_PtrPush( pNtk->vCos, pObj );
+ }
+}
+
+/**Function*************************************************************
+
Synopsis [Reads the number of cubes of the node.]
Description []
@@ -84,7 +114,7 @@ int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk )
/**Function*************************************************************
- Synopsis [Reads the number of cubes of the node.]
+ Synopsis [Reads the number of literals in the SOPs of the nodes.]
Description []
@@ -1029,6 +1059,12 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk )
pNode->Id = Vec_PtrSize( vObjsNew );
Vec_PtrPush( vObjsNew, pNode );
}
+ // put assert nodes next
+ Abc_NtkForEachAssert( pNtk, pNode, i )
+ {
+ pNode->Id = Vec_PtrSize( vObjsNew );
+ Vec_PtrPush( vObjsNew, pNode );
+ }
// put latches next
Abc_NtkForEachLatch( pNtk, pNode, i )
{
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 201a1208..075c64ee 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -83,9 +83,9 @@ static int Abc_CommandExdcFree ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandExdcGet ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandExdcSet ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandEspresso ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -193,9 +193,9 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "exdc_get", Abc_CommandExdcGet, 1 );
Cmd_CommandAdd( pAbc, "Various", "exdc_set", Abc_CommandExdcSet, 1 );
Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 );
- Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 );
Cmd_CommandAdd( pAbc, "Various", "espresso", Abc_CommandEspresso, 1 );
Cmd_CommandAdd( pAbc, "Various", "gen", Abc_CommandGen, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 );
Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
@@ -4297,98 +4297,6 @@ usage:
SeeAlso []
***********************************************************************/
-int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )
-{
- FILE * pOut, * pErr;
- Abc_Ntk_t * pNtk, * pNtkRes;
- int c;
- int fVerbose;
- int fUseInvs;
- int nFaninMax;
- extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose );
-
- pNtk = Abc_FrameReadNtk(pAbc);
- pOut = Abc_FrameReadOut(pAbc);
- pErr = Abc_FrameReadErr(pAbc);
-
- // set defaults
- fVerbose = 0;
- fUseInvs = 1;
- nFaninMax = 128;
- Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Nivh" ) ) != EOF )
- {
- switch ( c )
- {
- case 'N':
- if ( globalUtilOptind >= argc )
- {
- fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
- goto usage;
- }
- nFaninMax = atoi(argv[globalUtilOptind]);
- globalUtilOptind++;
- if ( nFaninMax < 0 )
- goto usage;
- break;
- case 'i':
- fUseInvs ^= 1;
- break;
- case 'v':
- fVerbose ^= 1;
- break;
- case 'h':
- goto usage;
- default:
- goto usage;
- }
- }
- if ( pNtk == NULL )
- {
- fprintf( pErr, "Empty network.\n" );
- return 1;
- }
-
- if ( !Abc_NtkIsStrash(pNtk) )
- {
- fprintf( pErr, "Only works for strashed networks.\n" );
- return 1;
- }
-
- // run the command
-// pNtkRes = Abc_NtkXyz( pNtk, nFaninMax, 1, 0, fUseInvs, fVerbose );
- pNtkRes = NULL;
-
- if ( pNtkRes == NULL )
- {
- fprintf( pErr, "Command has failed.\n" );
- return 0;
- }
- // replace the current network
- Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
- return 0;
-
-usage:
- fprintf( pErr, "usage: xyz [-N num] [-ivh]\n" );
- fprintf( pErr, "\t specilized AND/OR/EXOR decomposition\n" );
- fprintf( pErr, "\t-N num : maximum number of inputs [default = %d]\n", nFaninMax );
- fprintf( pErr, "\t-i : toggle the use of interters [default = %s]\n", fUseInvs? "yes": "no" );
- fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
- fprintf( pErr, "\t-h : print the command usage\n");
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
int Abc_CommandEspresso( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
@@ -4543,20 +4451,127 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int nLutMax;
+ int nPlaMax;
+ int fVerbose;
+// extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nPlaMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose );
+ extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nLutMax = 8;
+ nPlaMax = 128;
+ fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "LPvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'L':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLutMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLutMax < 0 )
+ goto usage;
+ break;
+ case 'P':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nPlaMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nPlaMax < 0 )
+ goto usage;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "Only works for strashed networks.\n" );
+ return 1;
+ }
+
+ if ( nLutMax < 2 || nLutMax > 8 || nPlaMax < 8 || nPlaMax > 128 )
+ {
+ fprintf( pErr, "Incorrect LUT/PLA parameters.\n" );
+ return 1;
+ }
+
+ // run the command
+// pNtkRes = Abc_NtkXyz( pNtk, nPlaMax, 1, 0, fUseInvs, fVerbose );
+ pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Command has failed.\n" );
+ return 0;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: xyz [-L num] [-P num] [-vh]\n" );
+ fprintf( pErr, "\t specilized LUT/PLA decomposition\n" );
+ fprintf( pErr, "\t-L num : maximum number of LUT inputs (2<=num<=8) [default = %d]\n", nLutMax );
+ fprintf( pErr, "\t-P num : maximum number of PLA inputs/cubes (8<=num<=128) [default = %d]\n", nPlaMax );
+ fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
- Abc_Ntk_t * pNtk;//, * pNtkRes;
+ Abc_Ntk_t * pNtk, * pNtkRes;
int c;
int nLevels;
// extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk );
+ extern Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
- nLevels = 15;
+ nLevels = 128;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF )
{
@@ -4614,7 +4629,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
// Cut_CellDumpToFile();
// else
// Cut_CellPrecompute();
- Cut_CellLoad();
+// Cut_CellLoad();
/*
{
Abc_Ntk_t * pNtkRes;
@@ -4623,6 +4638,24 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
}
*/
+// Abc_NtkSimulteBuggyMiter( pNtk );
+
+// Rwr_Temp();
+// Abc_MvExperiment();
+// Ivy_TruthTest();
+
+
+ pNtkRes = Abc_NtkIvy( pNtk );
+// pNtkRes = Abc_NtkPlayer( pNtk, nLevels, 0 );
+// pNtkRes = NULL;
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Command has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+
return 0;
usage:
@@ -6614,9 +6647,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
int fVerbose;
int nSeconds;
int nConfLimit;
- int nImpLimit;
+ int nInsLimit;
- extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nImpLimit );
+ extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit );
extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose );
@@ -6629,7 +6662,7 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
fVerbose = 0;
nSeconds = 20;
nConfLimit = 10000;
- nImpLimit = 0;
+ nInsLimit = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "TCIsvh" ) ) != EOF )
{
@@ -6663,9 +6696,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" );
goto usage;
}
- nImpLimit = atoi(argv[globalUtilOptind]);
+ nInsLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nImpLimit < 0 )
+ if ( nInsLimit < 0 )
goto usage;
break;
case 's':
@@ -6686,7 +6719,7 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
// perform equivalence checking
if ( fSat )
- Abc_NtkCecSat( pNtk1, pNtk2, nConfLimit, nImpLimit );
+ Abc_NtkCecSat( pNtk1, pNtk2, nConfLimit, nInsLimit );
else
Abc_NtkCecFraig( pNtk1, pNtk2, nSeconds, fVerbose );
@@ -6699,7 +6732,7 @@ usage:
fprintf( pErr, "\t performs combinational equivalence checking\n" );
fprintf( pErr, "\t-T num : approximate runtime limit in seconds [default = %d]\n", nSeconds );
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
- fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit );
+ fprintf( pErr, "\t-I num : limit on the number of clause inspections [default = %d]\n", nInsLimit );
fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
@@ -6734,9 +6767,9 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv )
int nFrames;
int nSeconds;
int nConfLimit;
- int nImpLimit;
+ int nInsLimit;
- extern void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nImpLimit, int nFrames );
+ extern void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit, int nFrames );
extern void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nFrames, int fVerbose );
@@ -6750,7 +6783,7 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv )
nFrames = 3;
nSeconds = 20;
nConfLimit = 10000;
- nImpLimit = 0;
+ nInsLimit = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "FTCIsvh" ) ) != EOF )
{
@@ -6795,9 +6828,9 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" );
goto usage;
}
- nImpLimit = atoi(argv[globalUtilOptind]);
+ nInsLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nImpLimit < 0 )
+ if ( nInsLimit < 0 )
goto usage;
break;
case 'v':
@@ -6818,7 +6851,7 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv )
// perform equivalence checking
if ( fSat )
- Abc_NtkSecSat( pNtk1, pNtk2, nConfLimit, nImpLimit, nFrames );
+ Abc_NtkSecSat( pNtk1, pNtk2, nConfLimit, nInsLimit, nFrames );
else
Abc_NtkSecFraig( pNtk1, pNtk2, nSeconds, nFrames, fVerbose );
@@ -6835,7 +6868,7 @@ usage:
fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames );
fprintf( pErr, "\t-T num : approximate runtime limit in seconds [default = %d]\n", nSeconds );
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
- fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit );
+ fprintf( pErr, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit );
fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
fprintf( pErr, "\t if no files are given, uses the current network and its spec\n");
@@ -6863,7 +6896,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
int fJFront;
int fVerbose;
int nConfLimit;
- int nImpLimit;
+ int nInsLimit;
int clk;
pNtk = Abc_FrameReadNtk(pAbc);
@@ -6871,10 +6904,10 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
- fJFront = 0;
+ fJFront = 0;
fVerbose = 0;
nConfLimit = 100000;
- nImpLimit = 0;
+ nInsLimit = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "CIvjh" ) ) != EOF )
{
@@ -6897,9 +6930,9 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" );
goto usage;
}
- nImpLimit = atoi(argv[globalUtilOptind]);
+ nInsLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nImpLimit < 0 )
+ if ( nInsLimit < 0 )
goto usage;
break;
case 'j':
@@ -6934,13 +6967,13 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
clk = clock();
if ( Abc_NtkIsStrash(pNtk) )
{
- RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, fJFront, fVerbose );
+ RetValue = Abc_NtkMiterSat( pNtk, (sint64)nConfLimit, (sint64)nInsLimit, fJFront, fVerbose, NULL, NULL );
}
else
{
Abc_Ntk_t * pTemp;
pTemp = Abc_NtkStrash( pNtk, 0, 0 );
- RetValue = Abc_NtkMiterSat( pTemp, nConfLimit, nImpLimit, fJFront, fVerbose );
+ RetValue = Abc_NtkMiterSat( pTemp, (sint64)nConfLimit, (sint64)nInsLimit, fJFront, fVerbose, NULL, NULL );
pNtk->pModel = pTemp->pModel; pTemp->pModel = NULL;
Abc_NtkDelete( pTemp );
}
@@ -6948,10 +6981,22 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
// verify that the pattern is correct
if ( RetValue == 0 && Abc_NtkPoNum(pNtk) == 1 )
{
+ //int i;
+ //Abc_Obj_t * pObj;
int * pSimInfo = Abc_NtkVerifySimulatePattern( pNtk, pNtk->pModel );
if ( pSimInfo[0] != 1 )
printf( "ERROR in Abc_NtkMiterSat(): Generated counter example is invalid.\n" );
free( pSimInfo );
+ /*
+ // print model
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+ printf( "%d", (int)(pNtk->pModel[i] > 0) );
+ if ( i == 70 )
+ break;
+ }
+ printf( "\n" );
+ */
}
if ( RetValue == -1 )
@@ -6969,7 +7014,7 @@ usage:
fprintf( pErr, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" );
fprintf( pErr, "\t derives CNF from the current network and leave it unchanged\n" );
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
- fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit );
+ fprintf( pErr, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit );
fprintf( pErr, "\t-j : toggle the use of J-frontier [default = %s]\n", fJFront? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
@@ -7001,7 +7046,7 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
Prove_ParamsSetDefault( pParams );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "NCFLrfvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NCFLIrfbvh" ) ) != EOF )
{
switch ( c )
{
@@ -7049,12 +7094,26 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pParams->nMiteringLimitLast < 0 )
goto usage;
break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pParams->nTotalInspectLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pParams->nTotalInspectLimit < 0 )
+ goto usage;
+ break;
case 'r':
pParams->fUseRewriting ^= 1;
break;
case 'f':
pParams->fUseFraiging ^= 1;
break;
+ case 'b':
+ pParams->fUseBdds ^= 1;
+ break;
case 'v':
pParams->fVerbose ^= 1;
break;
@@ -7118,15 +7177,17 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( pErr, "usage: prove [-N num] [-C num] [-F num] [-L num] [-rfvh]\n" );
+ fprintf( pErr, "usage: prove [-N num] [-C num] [-F num] [-L num] [-I num] [-rfbvh]\n" );
fprintf( pErr, "\t solves combinational miter by rewriting, FRAIGing, and SAT\n" );
fprintf( pErr, "\t replaces the current network by the cone modified by rewriting\n" );
fprintf( pErr, "\t-N num : max number of iterations [default = %d]\n", pParams->nItersMax );
fprintf( pErr, "\t-C num : max starting number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitStart );
fprintf( pErr, "\t-F num : max starting number of conflicts in fraiging [default = %d]\n", pParams->nFraigingLimitStart );
fprintf( pErr, "\t-L num : max last-gasp number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitLast );
+ fprintf( pErr, "\t-I num : max number of clause inspections in all SAT calls [default = %d]\n", (int)pParams->nTotalInspectLimit );
fprintf( pErr, "\t-r : toggle the use of rewriting [default = %s]\n", pParams->fUseRewriting? "yes": "no" );
fprintf( pErr, "\t-f : toggle the use of FRAIGing [default = %s]\n", pParams->fUseFraiging? "yes": "no" );
+ fprintf( pErr, "\t-b : toggle the use of BDDs [default = %s]\n", pParams->fUseBdds? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
diff --git a/src/base/abci/abcAttach.c b/src/base/abci/abcAttach.c
index 78573718..bf40e45b 100644
--- a/src/base/abci/abcAttach.c
+++ b/src/base/abci/abcAttach.c
@@ -387,13 +387,13 @@ void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned
nMints = (1 << nVars);
for ( iMint = 0; iMint < nMints; iMint++ )
{
- if ( (uTruthNode[iMint/32] & (1 << (iMint%32))) == 0 )
+ if ( (uTruthNode[iMint>>5] & (1 << (iMint&31))) == 0 )
continue;
iMintPerm = 0;
for ( v = 0; v < nVars; v++ )
if ( iMint & (1 << v) )
iMintPerm |= (1 << pPerm[v]);
- uTruthPerm[iMintPerm/32] |= (1 << (iMintPerm%32));
+ uTruthPerm[iMintPerm>>5] |= (1 << (iMintPerm&31));
}
}
diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c
new file mode 100644
index 00000000..0108b520
--- /dev/null
+++ b/src/base/abci/abcIvy.c
@@ -0,0 +1,407 @@
+/**CFile****************************************************************
+
+ FileName [abcIvy.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Strashing of the current network.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcIvy.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "dec.h"
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan );
+static Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld );
+
+static void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan );
+static Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode );
+static Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop );
+static Ivy_Obj_t * Abc_NodeStrashAigExorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop );
+static Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop );
+extern char * Mio_GateReadSop( void * pGate );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Gives the current ABC network to AIG manager for processing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
+{
+ Ivy_Man_t * pMan;
+ Abc_Ntk_t * pNtkAig;
+ int fCleanup = 1;
+ int nNodes;
+
+ assert( !Abc_NtkIsNetlist(pNtk) );
+ assert( !Abc_NtkIsSeq(pNtk) );
+ if ( Abc_NtkIsBddLogic(pNtk) )
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Converting to SOPs has failed.\n" );
+ return NULL;
+ }
+ }
+ // print warning about choice nodes
+ if ( Abc_NtkGetChoiceNum( pNtk ) )
+ printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
+
+ // convert to the AIG manager
+ pMan = Abc_NtkToAig( pNtk );
+
+ if ( !Ivy_ManCheck( pMan ) )
+ {
+ printf( "AIG check has failed.\n" );
+ Ivy_ManStop( pMan );
+ return NULL;
+ }
+
+
+// Ivy_MffcTest( pMan );
+ Ivy_ManPrintStats( pMan );
+ Ivy_ManSeqRewrite( pMan, 0, 0 );
+ Ivy_ManPrintStats( pMan );
+
+ // convert from the AIG manager
+ pNtkAig = Abc_NtkFromAig( pNtk, pMan );
+ Ivy_ManStop( pMan );
+
+ // report the cleanup results
+ if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
+ printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
+ // duplicate EXDC
+ if ( pNtk->pExdc )
+ pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
+ // make sure everything is okay
+ if ( !Abc_NtkCheck( pNtkAig ) )
+ {
+ printf( "Abc_NtkStrash: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkAig );
+ return NULL;
+ }
+ return pNtkAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the network from the AIG manager into ABC.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
+{
+ Vec_Int_t * vNodes;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pObj, * pObjNew, * pFaninNew, * pFaninNew0, * pFaninNew1;
+ Ivy_Obj_t * pNode;
+ int i, Fanin;
+ // perform strashing
+ pNtk = Abc_NtkStartFrom( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG );
+ // transfer the pointers to the basic nodes
+ Ivy_ManConst1(pMan)->TravId = (Abc_NtkConst1(pNtk)->Id << 1);
+ Abc_NtkForEachCi( pNtkOld, pObj, i )
+ Ivy_ManPi(pMan, i)->TravId = (pObj->pCopy->Id << 1);
+ // rebuild the AIG
+ vNodes = Ivy_ManDfs( pMan );
+ Ivy_ManForEachNodeVec( pMan, vNodes, pNode, i )
+ {
+ // add the first fanins
+ Fanin = Ivy_ObjFanin0(pNode)->TravId;
+ pFaninNew0 = Abc_NtkObj( pNtk, Fanin >> 1 );
+ pFaninNew0 = Abc_ObjNotCond( pFaninNew0, Ivy_ObjFaninC0(pNode) ^ (Fanin&1) );
+ if ( Ivy_ObjIsBuf(pNode) )
+ {
+ pNode->TravId = (Abc_ObjRegular(pFaninNew0)->Id << 1) | Abc_ObjIsComplement(pFaninNew0);
+ continue;
+ }
+ // add the first second
+ Fanin = Ivy_ObjFanin1(pNode)->TravId;
+ pFaninNew1 = Abc_NtkObj( pNtk, Fanin >> 1 );
+ pFaninNew1 = Abc_ObjNotCond( pFaninNew1, Ivy_ObjFaninC1(pNode) ^ (Fanin&1) );
+ // create the new node
+ if ( Ivy_ObjIsExor(pNode) )
+ pObjNew = Abc_AigXor( pNtk->pManFunc, pFaninNew0, pFaninNew1 );
+ else
+ pObjNew = Abc_AigAnd( pNtk->pManFunc, pFaninNew0, pFaninNew1 );
+ pNode->TravId = (Abc_ObjRegular(pObjNew)->Id << 1) | Abc_ObjIsComplement(pObjNew);
+ }
+ Vec_IntFree( vNodes );
+ // connect the PO nodes
+ Abc_NtkForEachCo( pNtkOld, pObj, i )
+ {
+ pNode = Ivy_ManPo(pMan, i);
+ Fanin = Ivy_ObjFanin0(pNode)->TravId;
+ pFaninNew = Abc_NtkObj( pNtk, Fanin >> 1 );
+ pFaninNew = Abc_ObjNotCond( pFaninNew, Ivy_ObjFaninC0(pNode) ^ (Fanin&1) );
+ Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
+ }
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the network from the AIG manager into ABC.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld )
+{
+ Ivy_Man_t * pMan;
+ Abc_Obj_t * pObj;
+ Ivy_Obj_t * pFanin;
+ int i;
+ // create the manager
+ assert( Abc_NtkHasSop(pNtkOld) || Abc_NtkHasAig(pNtkOld) );
+ if ( Abc_NtkHasSop(pNtkOld) )
+ pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), 3 * Abc_NtkGetLitNum(pNtkOld) + 10 );
+ else
+ pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), 3 * Abc_NtkNodeNum(pNtkOld) + 10 );
+ // create the PIs
+ Abc_NtkConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
+ Abc_NtkForEachCi( pNtkOld, pObj, i )
+ pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i);
+ // perform the conversion of the internal nodes
+ Abc_NtkStrashPerformAig( pNtkOld, pMan );
+ // create the POs
+ Abc_NtkForEachCo( pNtkOld, pObj, i )
+ {
+ pFanin = (Ivy_Obj_t *)Abc_ObjFanin0(pObj)->pCopy;
+ pFanin = Ivy_NotCond( pFanin, Abc_ObjFaninC0(pObj) );
+ Ivy_ObjConnect( Ivy_ManPo(pMan, i), pFanin );
+ }
+ Ivy_ManCleanup( pMan );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the network for strashing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan )
+{
+// ProgressBar * pProgress;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode;
+ int i;
+ vNodes = Abc_NtkDfs( pNtk, 0 );
+// pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+// Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNode->pCopy = (Abc_Obj_t *)Abc_NodeStrashAig( pMan, pNode );
+ }
+// Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode )
+{
+ int fUseFactor = 1;
+ char * pSop;
+ Ivy_Obj_t * pFanin0, * pFanin1;
+ extern int Abc_SopIsExorType( char * pSop );
+
+ assert( Abc_ObjIsNode(pNode) );
+
+ // consider the case when the graph is an AIG
+ if ( Abc_NtkIsStrash(pNode->pNtk) )
+ {
+ if ( Abc_NodeIsConst(pNode) )
+ return Ivy_ManConst1(pMan);
+ pFanin0 = (Ivy_Obj_t *)Abc_ObjFanin0(pNode)->pCopy;
+ pFanin0 = Ivy_NotCond( pFanin0, Abc_ObjFaninC0(pNode) );
+ pFanin1 = (Ivy_Obj_t *)Abc_ObjFanin1(pNode)->pCopy;
+ pFanin1 = Ivy_NotCond( pFanin1, Abc_ObjFaninC1(pNode) );
+ return Ivy_And( pFanin0, pFanin1 );
+ }
+
+ // get the SOP of the node
+ if ( Abc_NtkHasMapping(pNode->pNtk) )
+ pSop = Mio_GateReadSop(pNode->pData);
+ else
+ pSop = pNode->pData;
+
+ // consider the constant node
+ if ( Abc_NodeIsConst(pNode) )
+ return Ivy_NotCond( Ivy_ManConst1(pMan), Abc_SopIsConst0(pSop) );
+
+ // consider the special case of EXOR function
+ if ( Abc_SopIsExorType(pSop) )
+ return Abc_NodeStrashAigExorAig( pMan, pNode, pSop );
+
+ // decide when to use factoring
+ if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
+ return Abc_NodeStrashAigFactorAig( pMan, pNode, pSop );
+ return Abc_NodeStrashAigSopAig( pMan, pNode, pSop );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node using its SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop )
+{
+ Abc_Obj_t * pFanin;
+ Ivy_Obj_t * pAnd, * pSum;
+ char * pCube;
+ int i, nFanins;
+
+ // get the number of node's fanins
+ nFanins = Abc_ObjFaninNum( pNode );
+ assert( nFanins == Abc_SopGetVarNum(pSop) );
+ // go through the cubes of the node's SOP
+ pSum = Ivy_Not( Ivy_ManConst1(pMan) );
+ Abc_SopForEachCube( pSop, nFanins, pCube )
+ {
+ // create the AND of literals
+ pAnd = Ivy_ManConst1(pMan);
+ Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net
+ {
+ if ( pCube[i] == '1' )
+ pAnd = Ivy_And( pAnd, (Ivy_Obj_t *)pFanin->pCopy );
+ else if ( pCube[i] == '0' )
+ pAnd = Ivy_And( pAnd, Ivy_Not((Ivy_Obj_t *)pFanin->pCopy) );
+ }
+ // add to the sum of cubes
+ pSum = Ivy_Or( pSum, pAnd );
+ }
+ // decide whether to complement the result
+ if ( Abc_SopIsComplement(pSop) )
+ pSum = Ivy_Not(pSum);
+ return pSum;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashed n-input XOR function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Abc_NodeStrashAigExorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop )
+{
+ Abc_Obj_t * pFanin;
+ Ivy_Obj_t * pSum;
+ int i, nFanins;
+ // get the number of node's fanins
+ nFanins = Abc_ObjFaninNum( pNode );
+ assert( nFanins == Abc_SopGetVarNum(pSop) );
+ // go through the cubes of the node's SOP
+ pSum = Ivy_Not( Ivy_ManConst1(pMan) );
+ for ( i = 0; i < nFanins; i++ )
+ {
+ pFanin = Abc_ObjFanin( pNode, i );
+ pSum = Ivy_Exor( pSum, (Ivy_Obj_t *)pFanin->pCopy );
+ }
+ if ( Abc_SopIsComplement(pSop) )
+ pSum = Ivy_Not(pSum);
+ return pSum;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node using its SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pRoot, char * pSop )
+{
+ Dec_Graph_t * pFForm;
+ Dec_Node_t * pNode;
+ Ivy_Obj_t * pAnd;
+ int i;
+
+// extern Ivy_Obj_t * Dec_GraphToNetworkAig( Ivy_Man_t * pMan, Dec_Graph_t * pGraph );
+ extern Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph );
+
+// assert( 0 );
+
+ // perform factoring
+ pFForm = Dec_Factor( pSop );
+ // collect the fanins
+ Dec_GraphForEachLeaf( pFForm, pNode, i )
+ pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy;
+ // perform strashing
+// pAnd = Dec_GraphToNetworkAig( pMan, pFForm );
+ pAnd = Dec_GraphToNetworkIvy( pMan, pFForm );
+// pAnd = NULL;
+
+ Dec_GraphFree( pFForm );
+ return pAnd;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c
index 490cf0c6..ecd44017 100644
--- a/src/base/abci/abcMiter.c
+++ b/src/base/abci/abcMiter.c
@@ -81,7 +81,7 @@ Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
{
- char Buffer[100];
+ char Buffer[1000];
Abc_Ntk_t * pNtkMiter;
assert( Abc_NtkIsStrash(pNtk1) );
@@ -168,16 +168,12 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk
Abc_NtkForEachLatch( pNtk1, pObj, i )
{
pObjNew = Abc_NtkDupObj( pNtkMiter, pObj );
- Vec_PtrPush( pNtkMiter->vCis, pObjNew );
- Vec_PtrPush( pNtkMiter->vCos, pObjNew );
// add name
Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_1" );
}
Abc_NtkForEachLatch( pNtk2, pObj, i )
{
pObjNew = Abc_NtkDupObj( pNtkMiter, pObj );
- Vec_PtrPush( pNtkMiter->vCis, pObjNew );
- Vec_PtrPush( pNtkMiter->vCos, pObjNew );
// add name
Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_2" );
}
@@ -295,7 +291,7 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
{
- char Buffer[100];
+ char Buffer[1000];
Abc_Ntk_t * pNtkMiter;
Abc_Obj_t * pOutput1, * pOutput2;
Abc_Obj_t * pRoot1, * pRoot2, * pMiter;
@@ -352,7 +348,7 @@ Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues )
{
- char Buffer[100];
+ char Buffer[1000];
Abc_Ntk_t * pNtkMiter;
Abc_Obj_t * pRoot, * pOutput1;
int Value, i;
@@ -418,7 +414,7 @@ Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues )
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 )
{
- char Buffer[100];
+ char Buffer[1000];
Abc_Ntk_t * pNtkMiter;
Abc_Obj_t * pRoot, * pOutput1, * pOutput2, * pMiter;
@@ -665,7 +661,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
***********************************************************************/
Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
{
- char Buffer[100];
+ char Buffer[1000];
ProgressBar * pProgress;
Abc_Ntk_t * pNtkFrames;
Abc_Obj_t * pLatch, * pLatchNew;
@@ -717,8 +713,6 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
{
pLatchNew = Abc_NtkLatch(pNtkFrames, i);
Abc_ObjAddFanin( pLatchNew, pLatch->pCopy );
- Vec_PtrPush( pNtkFrames->vCis, pLatchNew );
- Vec_PtrPush( pNtkFrames->vCos, pLatchNew );
Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) );
}
}
@@ -728,6 +722,9 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
// remove dangling nodes
Abc_AigCleanup( pNtkFrames->pManFunc );
+ // reorder the latches
+ Abc_NtkOrderCisCos( pNtkFrames );
+
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtkFrames ) )
{
@@ -773,6 +770,12 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame )
Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer );
Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) );
}
+ // add the new asserts
+ Abc_NtkForEachAssert( pNtk, pNode, i )
+ {
+ Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer );
+ Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) );
+ }
// transfer the implementation of the latch drivers to the latches
Abc_NtkForEachLatch( pNtk, pLatch, i )
pLatch->pNext = Abc_ObjChild0Copy(pLatch);
@@ -795,7 +798,7 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame )
***********************************************************************/
Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFrameMapping addFrameMapping, void* arg )
{
- char Buffer[100];
+ char Buffer[1000];
ProgressBar * pProgress;
Abc_Ntk_t * pNtkFrames;
Vec_Ptr_t * vNodes;
@@ -854,9 +857,6 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram
{
pLatchNew = Abc_NtkLatch(pNtkFrames, i);
Abc_ObjAddFanin( pLatchNew, pLatch->pCopy );
-
- Vec_PtrPush( pNtkFrames->vCis, pLatchNew );
- Vec_PtrPush( pNtkFrames->vCos, pLatchNew );
Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) );
}
}
@@ -865,6 +865,9 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram
// remove dangling nodes
Abc_AigCleanup( pNtkFrames->pManFunc );
+
+ // reorder the latches
+ Abc_NtkOrderCisCos( pNtkFrames );
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtkFrames ) )
diff --git a/src/base/abci/abcMv.c b/src/base/abci/abcMv.c
new file mode 100644
index 00000000..2858b8a7
--- /dev/null
+++ b/src/base/abci/abcMv.c
@@ -0,0 +1,369 @@
+/**CFile****************************************************************
+
+ FileName [abcMv.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Multi-valued decomposition.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcMv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Mv_Man_t_ Mv_Man_t;
+struct Mv_Man_t_
+{
+ int nInputs; // the number of 4-valued input variables
+ int nFuncs; // the number of 4-valued functions
+ DdManager * dd; // representation of functions
+ DdNode * bValues[15][4]; // representation of i-sets
+ DdNode * bValueDcs[15][4]; // representation of i-sets don't-cares
+ DdNode * bFuncs[15]; // representation of functions
+};
+
+static void Abc_MvDecompose( Mv_Man_t * p );
+static void Abc_MvPrintStats( Mv_Man_t * p );
+static void Abc_MvRead( Mv_Man_t * p );
+static void Abc_MvDeref( Mv_Man_t * p );
+static DdNode * Abc_MvReadCube( DdManager * dd, char * pLine, int nVars );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_MvExperiment()
+{
+ Mv_Man_t * p;
+ // get the functions
+ p = ALLOC( Mv_Man_t, 1 );
+ memset( p, 0, sizeof(Mv_Man_t) );
+ p->dd = Cudd_Init( 32, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+ p->nFuncs = 15;
+ p->nInputs = 9;
+ Abc_MvRead( p );
+ // process the functions
+ Abc_MvPrintStats( p );
+// Cudd_ReduceHeap( p->dd, CUDD_REORDER_SYMM_SIFT, 1 );
+// Abc_MvPrintStats( p );
+ // try detecting support reducing bound set
+ Abc_MvDecompose( p );
+
+ // remove the manager
+ Abc_MvDeref( p );
+ Extra_StopManager( p->dd );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_MvPrintStats( Mv_Man_t * p )
+{
+ int i, v;
+ for ( i = 0; i < 15; i++ )
+ {
+ printf( "%2d : ", i );
+ printf( "%3d (%2d) ", Cudd_DagSize(p->bFuncs[i])-1, Cudd_SupportSize(p->dd, p->bFuncs[i]) );
+ for ( v = 0; v < 4; v++ )
+ printf( "%d = %3d (%2d) ", v, Cudd_DagSize(p->bValues[i][v])-1, Cudd_SupportSize(p->dd, p->bValues[i][v]) );
+ printf( "\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_MvReadCube( DdManager * dd, char * pLine, int nVars )
+{
+ DdNode * bCube, * bVar, * bTemp;
+ int i;
+ bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube );
+ for ( i = 0; i < nVars; i++ )
+ {
+ if ( pLine[i] == '-' )
+ continue;
+ else if ( pLine[i] == '0' ) // 0
+ bVar = Cudd_Not( Cudd_bddIthVar(dd, 29-i) );
+ else if ( pLine[i] == '1' ) // 1
+ bVar = Cudd_bddIthVar(dd, 29-i);
+ else assert(0);
+ bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube );
+ Cudd_RecursiveDeref( dd, bTemp );
+ }
+ Cudd_Deref( bCube );
+ return bCube;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_MvRead( Mv_Man_t * p )
+{
+ FILE * pFile;
+ char Buffer[1000], * pLine;
+ DdNode * bCube, * bTemp, * bProd, * bVar0, * bVar1, * bCubeSum;
+ int i, v;
+
+ // start the cube
+ bCubeSum = Cudd_ReadLogicZero(p->dd); Cudd_Ref( bCubeSum );
+
+ // start the values
+ for ( i = 0; i < 15; i++ )
+ for ( v = 0; v < 4; v++ )
+ {
+ p->bValues[i][v] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bValues[i][v] );
+ p->bValueDcs[i][v] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bValueDcs[i][v] );
+ }
+
+ // read the file
+ pFile = fopen( "input.pla", "r" );
+ while ( fgets( Buffer, 1000, pFile ) )
+ {
+ if ( Buffer[0] == '#' )
+ continue;
+ if ( Buffer[0] == '.' )
+ {
+ if ( Buffer[1] == 'e' )
+ break;
+ continue;
+ }
+
+ // get the cube
+ bCube = Abc_MvReadCube( p->dd, Buffer, 18 ); Cudd_Ref( bCube );
+
+ // add it to the values of the output functions
+ pLine = Buffer + 19;
+ for ( i = 0; i < 15; i++ )
+ {
+ if ( pLine[2*i] == '-' && pLine[2*i+1] == '-' )
+ {
+ for ( v = 0; v < 4; v++ )
+ {
+ p->bValueDcs[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValueDcs[i][v], bCube ); Cudd_Ref( p->bValueDcs[i][v] );
+ Cudd_RecursiveDeref( p->dd, bTemp );
+ }
+ continue;
+ }
+ else if ( pLine[2*i] == '0' && pLine[2*i+1] == '0' ) // 0
+ v = 0;
+ else if ( pLine[2*i] == '1' && pLine[2*i+1] == '0' ) // 1
+ v = 1;
+ else if ( pLine[2*i] == '0' && pLine[2*i+1] == '1' ) // 2
+ v = 2;
+ else if ( pLine[2*i] == '1' && pLine[2*i+1] == '1' ) // 3
+ v = 3;
+ else assert( 0 );
+ // add the value
+ p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], bCube ); Cudd_Ref( p->bValues[i][v] );
+ Cudd_RecursiveDeref( p->dd, bTemp );
+ }
+
+ // add the cube
+ bCubeSum = Cudd_bddOr( p->dd, bTemp = bCubeSum, bCube ); Cudd_Ref( bCubeSum );
+ Cudd_RecursiveDeref( p->dd, bTemp );
+ Cudd_RecursiveDeref( p->dd, bCube );
+ }
+
+ // add the complement of the domain to all values
+ for ( i = 0; i < 15; i++ )
+ for ( v = 0; v < 4; v++ )
+ {
+ if ( p->bValues[i][v] == Cudd_Not(Cudd_ReadOne(p->dd)) )
+ continue;
+ p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], p->bValueDcs[i][v] ); Cudd_Ref( p->bValues[i][v] );
+ Cudd_RecursiveDeref( p->dd, bTemp );
+ p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], Cudd_Not(bCubeSum) ); Cudd_Ref( p->bValues[i][v] );
+ Cudd_RecursiveDeref( p->dd, bTemp );
+ }
+ printf( "Domain = %5.2f %%.\n", 100.0*Cudd_CountMinterm(p->dd, bCubeSum, 32)/Cudd_CountMinterm(p->dd, Cudd_ReadOne(p->dd), 32) );
+ Cudd_RecursiveDeref( p->dd, bCubeSum );
+
+ // create each output function
+ for ( i = 0; i < 15; i++ )
+ {
+ p->bFuncs[i] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bFuncs[i] );
+ for ( v = 0; v < 4; v++ )
+ {
+ bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 30), ((v & 1) == 0) );
+ bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 31), ((v & 2) == 0) );
+ bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bCube );
+ bProd = Cudd_bddAnd( p->dd, p->bValues[i][v], bCube ); Cudd_Ref( bProd );
+ Cudd_RecursiveDeref( p->dd, bCube );
+ // add the value
+ p->bFuncs[i] = Cudd_bddOr( p->dd, bTemp = p->bFuncs[i], bProd ); Cudd_Ref( p->bFuncs[i] );
+ Cudd_RecursiveDeref( p->dd, bTemp );
+ Cudd_RecursiveDeref( p->dd, bProd );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_MvDeref( Mv_Man_t * p )
+{
+ int i, v;
+ for ( i = 0; i < 15; i++ )
+ for ( v = 0; v < 4; v++ )
+ {
+ Cudd_RecursiveDeref( p->dd, p->bValues[i][v] );
+ Cudd_RecursiveDeref( p->dd, p->bValueDcs[i][v] );
+ }
+ for ( i = 0; i < 15; i++ )
+ Cudd_RecursiveDeref( p->dd, p->bFuncs[i] );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_MvDecompose( Mv_Man_t * p )
+{
+ DdNode * bCofs[16], * bVarCube1, * bVarCube2, * bVarCube, * bCube, * bVar0, * bVar1;//, * bRes;
+ int k, i1, i2, v1, v2;//, c1, c2, Counter;
+
+ bVar0 = Cudd_bddIthVar(p->dd, 30);
+ bVar1 = Cudd_bddIthVar(p->dd, 31);
+ bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bCube );
+
+ for ( k = 0; k < p->nFuncs; k++ )
+ {
+ printf( "FUNCTION %d\n", k );
+ for ( i1 = 0; i1 < p->nFuncs; i1++ )
+ for ( i2 = i1+1; i2 < p->nFuncs; i2++ )
+ {
+ Vec_Ptr_t * vCofs;
+
+ for ( v1 = 0; v1 < 4; v1++ )
+ {
+ bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i1 ), ((v1 & 1) == 0) );
+ bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i1-1), ((v1 & 2) == 0) );
+ bVarCube1 = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bVarCube1 );
+ for ( v2 = 0; v2 < 4; v2++ )
+ {
+ bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i2 ), ((v2 & 1) == 0) );
+ bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i2-1), ((v2 & 2) == 0) );
+ bVarCube2 = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bVarCube2 );
+ bVarCube = Cudd_bddAnd( p->dd, bVarCube1, bVarCube2 ); Cudd_Ref( bVarCube );
+ bCofs[v1 * 4 + v2] = Cudd_Cofactor( p->dd, p->bFuncs[k], bVarCube ); Cudd_Ref( bCofs[v1 * 4 + v2] );
+ Cudd_RecursiveDeref( p->dd, bVarCube );
+ Cudd_RecursiveDeref( p->dd, bVarCube2 );
+ }
+ Cudd_RecursiveDeref( p->dd, bVarCube1 );
+ }
+/*
+ // check the compatibility of cofactors
+ Counter = 0;
+ for ( c1 = 0; c1 < 16; c1++ )
+ {
+ for ( c2 = 0; c2 <= c1; c2++ )
+ printf( " " );
+ for ( c2 = c1+1; c2 < 16; c2++ )
+ {
+ bRes = Cudd_bddAndAbstract( p->dd, bCofs[c1], bCofs[c2], bCube ); Cudd_Ref( bRes );
+ if ( bRes == Cudd_ReadOne(p->dd) )
+ {
+ printf( "+" );
+ Counter++;
+ }
+ else
+ {
+ printf( " " );
+ }
+ Cudd_RecursiveDeref( p->dd, bRes );
+ }
+ printf( "\n" );
+ }
+*/
+
+ vCofs = Vec_PtrAlloc( 16 );
+ for ( v1 = 0; v1 < 4; v1++ )
+ for ( v2 = 0; v2 < 4; v2++ )
+ Vec_PtrPushUnique( vCofs, bCofs[v1 * 4 + v2] );
+ printf( "%d ", Vec_PtrSize(vCofs) );
+ Vec_PtrFree( vCofs );
+
+ // free the cofactors
+ for ( v1 = 0; v1 < 4; v1++ )
+ for ( v2 = 0; v2 < 4; v2++ )
+ Cudd_RecursiveDeref( p->dd, bCofs[v1 * 4 + v2] );
+
+ printf( "\n" );
+// printf( "%2d, %2d : %3d\n", i1, i2, Counter );
+ }
+ }
+
+ Cudd_RecursiveDeref( p->dd, bCube );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c
index 2aad721b..f95591ab 100644
--- a/src/base/abci/abcPrint.c
+++ b/src/base/abci/abcPrint.c
@@ -48,12 +48,15 @@
***********************************************************************/
void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
{
- int Num, Num2;
+ int Num;//, Num2;
// Abc_NtkDetectMatching( pNtk );
// return;
fprintf( pFile, "%-13s:", pNtk->pName );
- fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
+ if ( Abc_NtkAssertNum(pNtk) )
+ fprintf( pFile, " i/o/a = %4d/%4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk), Abc_NtkAssertNum(pNtk) );
+ else
+ fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
if ( !Abc_NtkIsSeq(pNtk) )
fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) );
diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c
index 23315223..85a58c32 100644
--- a/src/base/abci/abcProve.c
+++ b/src/base/abci/abcProve.c
@@ -30,7 +30,7 @@ extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, i
extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUpdateLevel, bool fUseZeros, bool fUseDcs, bool fVerbose );
extern Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
-static Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue, int * pNumFails );
+static Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, sint64 nInspLimit, int * pRetValue, int * pNumFails, sint64 * pNumConfs, sint64 * pNumInspects );
static void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fVerbose );
@@ -56,13 +56,14 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
{
Prove_Params_t * pParams = pPars;
Abc_Ntk_t * pNtk, * pNtkTemp;
- int RetValue, nIter, Counter, clk, timeStart = clock();
+ int RetValue, nIter, nSatFails, Counter, clk, timeStart = clock();
+ sint64 nSatConfs, nSatInspects, nInspectLimit;
// get the starting network
pNtk = *ppNtk;
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkPoNum(pNtk) == 1 );
-
+
if ( pParams->fVerbose )
{
printf( "RESOURCE LIMITS: Iterations = %d. Rewriting = %s. Fraiging = %s.\n",
@@ -79,7 +80,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
if ( !pParams->fUseRewriting && !pParams->fUseFraiging )
{
clk = clock();
- RetValue = Abc_NtkMiterSat( pNtk, pParams->nMiteringLimitLast, 0, 0, 0 );
+ RetValue = Abc_NtkMiterSat( pNtk, (sint64)pParams->nMiteringLimitLast, (sint64)0, 0, 0, NULL, NULL );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
*ppNtk = pNtk;
return RetValue;
@@ -98,11 +99,24 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
// try brute-force SAT
clk = clock();
- RetValue = Abc_NtkMiterSat( pNtk, (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), 0, 0, 0 );
+ nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0;
+ RetValue = Abc_NtkMiterSat( pNtk, (sint64)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), (sint64)nInspectLimit, 0, 0, &nSatConfs, &nSatInspects );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
if ( RetValue >= 0 )
break;
+ // add to the number of backtracks and inspects
+ pParams->nTotalBacktracksMade += nSatConfs;
+ pParams->nTotalInspectsMade += nSatInspects;
+ // check if global resource limit is reached
+ if ( (pParams->nTotalBacktrackLimit && pParams->nTotalBacktracksMade >= pParams->nTotalBacktrackLimit) ||
+ (pParams->nTotalInspectLimit && pParams->nTotalInspectsMade >= pParams->nTotalInspectLimit) )
+ {
+ printf( "Reached global limit on conflicts/inspects. Quitting.\n" );
+ *ppNtk = pNtk;
+ return -1;
+ }
+
// try rewriting
if ( pParams->fUseRewriting )
{
@@ -131,18 +145,30 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
if ( pParams->fUseFraiging )
{
- int nSatFails;
// try FRAIGing
clk = clock();
- pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)), &RetValue, &nSatFails ); Abc_NtkDelete( pNtkTemp );
+ nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0;
+ pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)), nInspectLimit, &RetValue, &nSatFails, &nSatConfs, &nSatInspects ); Abc_NtkDelete( pNtkTemp );
Abc_NtkMiterPrint( pNtk, "FRAIGing ", clk, pParams->fVerbose );
// printf( "NumFails = %d\n", nSatFails );
if ( RetValue >= 0 )
break;
+
+ // add to the number of backtracks and inspects
+ pParams->nTotalBacktracksMade += nSatConfs;
+ pParams->nTotalInspectsMade += nSatInspects;
+ // check if global resource limit is reached
+ if ( (pParams->nTotalBacktrackLimit && pParams->nTotalBacktracksMade >= pParams->nTotalBacktrackLimit) ||
+ (pParams->nTotalInspectLimit && pParams->nTotalInspectsMade >= pParams->nTotalInspectLimit) )
+ {
+ printf( "Reached global limit on conflicts/inspects. Quitting.\n" );
+ *ppNtk = pNtk;
+ return -1;
+ }
}
}
-/*
+
// try to prove it using brute force SAT
if ( RetValue < 0 && pParams->fUseBdds )
{
@@ -162,7 +188,6 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
pNtk = pNtkTemp;
Abc_NtkMiterPrint( pNtk, "BDD building", clk, pParams->fVerbose );
}
-*/
if ( RetValue < 0 )
{
@@ -172,7 +197,8 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
fflush( stdout );
}
clk = clock();
- RetValue = Abc_NtkMiterSat( pNtk, pParams->nMiteringLimitLast, 0, 0, 0 );
+ nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0;
+ RetValue = Abc_NtkMiterSat( pNtk, (sint64)pParams->nMiteringLimitLast, (sint64)nInspectLimit, 0, 0, NULL, NULL );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
}
@@ -197,7 +223,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue, int * pNumFails )
+Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, sint64 nInspLimit, int * pRetValue, int * pNumFails, sint64 * pNumConfs, sint64 * pNumInspects )
{
Abc_Ntk_t * pNtkNew;
Fraig_Params_t Params, * pParams = &Params;
@@ -222,6 +248,7 @@ Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue,
pParams->fTryProve = 0; // do not try to prove the final miter
pParams->fDoSparse = 1; // try proving sparse functions
pParams->fVerbose = 0;
+ pParams->nInspLimit = nInspLimit;
// transform the target into a fraig
pMan = Abc_NtkToFraig( pNtk, pParams, 0, 0 );
@@ -243,6 +270,8 @@ Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue,
// save the return values
*pRetValue = RetValue;
*pNumFails = Fraig_ManReadSatFails( pMan );
+ *pNumConfs = Fraig_ManReadConflicts( pMan );
+ *pNumInspects = Fraig_ManReadInspects( pMan );
// delete the fraig manager
Fraig_ManFree( pMan );
diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c
index 9ea3ad71..3dd6c519 100644
--- a/src/base/abci/abcRefactor.c
+++ b/src/base/abci/abcRefactor.c
@@ -111,6 +111,9 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
+ // skip persistant nodes
+ if ( Abc_NodeIsPersistant(pNode) )
+ continue;
// skip the nodes with many fanouts
if ( Abc_ObjFanoutNum(pNode) > 1000 )
continue;
diff --git a/src/base/abci/abcRenode.c b/src/base/abci/abcRenode.c
index ea728858..f7d351d2 100644
--- a/src/base/abci/abcRenode.c
+++ b/src/base/abci/abcRenode.c
@@ -377,7 +377,7 @@ int Abc_NtkRenodeLimit( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax )
***********************************************************************/
void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax )
{
- Vec_Ptr_t * vCone = pNtk->vPtrTemp;
+ Vec_Ptr_t * vCone = Vec_PtrAlloc(10);
Abc_Obj_t * pNode;
int i, nFanouts, nConeSize;
@@ -414,6 +414,7 @@ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax )
while ( Abc_NtkRenodeLimit(pNode, vCone, nFaninMax) );
assert( vCone->nSize <= nFaninMax );
}
+ Vec_PtrFree(vCone);
/*
// make sure the fanin limit is met
Abc_NtkForEachNode( pNtk, pNode, i )
diff --git a/src/base/abci/abcRestruct.c b/src/base/abci/abcRestruct.c
index 49208772..d738123a 100644
--- a/src/base/abci/abcRestruct.c
+++ b/src/base/abci/abcRestruct.c
@@ -134,6 +134,9 @@ pManRst->timeCut += clock() - clk;
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
+ // skip persistant nodes
+ if ( Abc_NodeIsPersistant(pNode) )
+ continue;
// skip the node if it is inside the tree
// if ( Abc_ObjFanoutNum(pNode) < 2 )
// continue;
diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c
index e9de4858..b0061b61 100644
--- a/src/base/abci/abcResub.c
+++ b/src/base/abci/abcResub.c
@@ -160,6 +160,9 @@ int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, bool fUpd
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
+ // skip persistant nodes
+ if ( Abc_NodeIsPersistant(pNode) )
+ continue;
// skip the nodes with many fanouts
if ( Abc_ObjFanoutNum(pNode) > 1000 )
continue;
@@ -278,7 +281,7 @@ Abc_ManRes_t * Abc_ManResubStart( int nLeavesMax, int nDivsMax )
pData = p->vSims->pArray[k];
for ( i = 0; i < p->nBits; i++ )
if ( i & (1 << k) )
- pData[i/32] |= (1 << (i%32));
+ pData[i>>5] |= (1 << (i&31));
}
// create the remaining divisors
p->vDivs1UP = Vec_PtrAlloc( p->nDivsMax );
diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c
index f11e5e9d..703f05d9 100644
--- a/src/base/abci/abcRewrite.c
+++ b/src/base/abci/abcRewrite.c
@@ -34,6 +34,7 @@
static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk );
static void Abc_NodePrintCuts( Abc_Obj_t * pNode );
+static void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -87,15 +88,39 @@ Rwr_ManAddTimeCuts( pManRwr, clock() - clk );
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
+ // skip persistant nodes
+ if ( Abc_NodeIsPersistant(pNode) )
+ continue;
// skip the nodes with many fanouts
if ( Abc_ObjFanoutNum(pNode) > 1000 )
continue;
+//printf( "*******Node %d: \n", pNode->Id );
+
// for each cut, try to resynthesize it
nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros );
if ( nGain > 0 || nGain == 0 && fUseZeros )
{
+// extern void Abc_RwrExpWithCut( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves );
+
Dec_Graph_t * pGraph = Rwr_ManReadDecs(pManRwr);
int fCompl = Rwr_ManReadCompl(pManRwr);
+
+// Abc_RwrExpWithCut( pNode, Rwr_ManReadLeaves(pManRwr) );
+
+/*
+ {
+ Abc_Obj_t * pObj;
+ int i;
+ printf( "USING: (" );
+ Vec_PtrForEachEntry( Rwr_ManReadLeaves(pManRwr), pObj, i )
+ printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pObj)) );
+ printf( ") Gain = %d.\n", nGain );
+ }
+*/
+
+// if ( nGain > 0 )
+// Abc_ManShowCutCone( pNode, Rwr_ManReadLeaves(pManRwr) );
+
/*
if ( nGain > 0 )
{ // print stats on the MFFC
@@ -209,6 +234,163 @@ void Abc_NodePrintCuts( Abc_Obj_t * pNode )
}
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManRewritePrintDivs( Vec_Ptr_t * vDivs, int nLeaves )
+{
+ Abc_Obj_t * pFanin, * pNode, * pRoot;
+ int i, k;
+ pRoot = Vec_PtrEntryLast(vDivs);
+ // print the nodes
+ Vec_PtrForEachEntry( vDivs, pNode, i )
+ {
+ if ( i < nLeaves )
+ {
+ printf( "%6d : %c\n", pNode->Id, 'a'+i );
+ continue;
+ }
+ printf( "%6d : %2d = ", pNode->Id, i );
+ // find the first fanin
+ Vec_PtrForEachEntry( vDivs, pFanin, k )
+ if ( Abc_ObjFanin0(pNode) == pFanin )
+ break;
+ if ( k < nLeaves )
+ printf( "%c", 'a' + k );
+ else
+ printf( "%d", k );
+ printf( "%s ", Abc_ObjFaninC0(pNode)? "\'" : "" );
+ // find the second fanin
+ Vec_PtrForEachEntry( vDivs, pFanin, k )
+ if ( Abc_ObjFanin1(pNode) == pFanin )
+ break;
+ if ( k < nLeaves )
+ printf( "%c", 'a' + k );
+ else
+ printf( "%d", k );
+ printf( "%s ", Abc_ObjFaninC1(pNode)? "\'" : "" );
+ if ( pNode == pRoot )
+ printf( " root" );
+ printf( "\n" );
+ }
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManShowCutCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vDivs )
+{
+ if ( Abc_NodeIsTravIdCurrent(pNode) )
+ return;
+ Abc_NodeSetTravIdCurrent(pNode);
+ Abc_ManShowCutCone_rec( Abc_ObjFanin0(pNode), vDivs );
+ Abc_ManShowCutCone_rec( Abc_ObjFanin1(pNode), vDivs );
+ Vec_PtrPush( vDivs, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves )
+{
+ Abc_Ntk_t * pNtk = pNode->pNtk;
+ Abc_Obj_t * pObj;
+ Vec_Ptr_t * vDivs;
+ int i;
+ vDivs = Vec_PtrAlloc( 100 );
+ Abc_NtkIncrementTravId( pNtk );
+ Vec_PtrForEachEntry( vLeaves, pObj, i )
+ {
+ Abc_NodeSetTravIdCurrent( Abc_ObjRegular(pObj) );
+ Vec_PtrPush( vDivs, Abc_ObjRegular(pObj) );
+ }
+ Abc_ManShowCutCone_rec( pNode, vDivs );
+ Abc_ManRewritePrintDivs( vDivs, Vec_PtrSize(vLeaves) );
+ Vec_PtrFree( vDivs );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_RwrExpWithCut_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, int fUseA )
+{
+ if ( Vec_PtrFind(vLeaves, pNode) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pNode)) >= 0 )
+ {
+ if ( fUseA )
+ Abc_ObjRegular(pNode)->fMarkA = 1;
+ else
+ Abc_ObjRegular(pNode)->fMarkB = 1;
+ return;
+ }
+ assert( Abc_ObjIsNode(pNode) );
+ Abc_RwrExpWithCut_rec( Abc_ObjFanin0(pNode), vLeaves, fUseA );
+ Abc_RwrExpWithCut_rec( Abc_ObjFanin1(pNode), vLeaves, fUseA );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_RwrExpWithCut( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves )
+{
+ Abc_Obj_t * pObj;
+ int i, CountA, CountB;
+ Abc_RwrExpWithCut_rec( Abc_ObjFanin0(pNode), vLeaves, 1 );
+ Abc_RwrExpWithCut_rec( Abc_ObjFanin1(pNode), vLeaves, 0 );
+ CountA = CountB = 0;
+ Vec_PtrForEachEntry( vLeaves, pObj, i )
+ {
+ CountA += Abc_ObjRegular(pObj)->fMarkA;
+ CountB += Abc_ObjRegular(pObj)->fMarkB;
+ Abc_ObjRegular(pObj)->fMarkA = 0;
+ Abc_ObjRegular(pObj)->fMarkB = 0;
+ }
+ printf( "(%d,%d:%d) ", CountA, CountB, CountA+CountB-Vec_PtrSize(vLeaves) );
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abcRr.c b/src/base/abci/abcRr.c
index a9c61e1a..b3788d31 100644
--- a/src/base/abci/abcRr.c
+++ b/src/base/abci/abcRr.c
@@ -105,6 +105,9 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa
p->nFanoutLevels = nFanoutLevels;
p->nNodesOld = Abc_NtkNodeNum(pNtk);
p->nLevelsOld = Abc_AigGetLevelNum(pNtk);
+ // remember latch values
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ pNode->pNext = pNode->pData;
// go through the nodes
Abc_NtkCleanCopy(pNtk);
nNodes = Abc_NtkObjNumMax(pNtk);
@@ -119,6 +122,9 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
+ // skip persistant nodes
+ if ( Abc_NodeIsPersistant(pNode) )
+ continue;
// skip the nodes with many fanouts
if ( Abc_ObjFanoutNum(pNode) > 1000 )
continue;
@@ -209,6 +215,9 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa
if ( fVerbose )
Abc_RRManPrintStats( p );
Abc_RRManStop( p );
+ // restore latch values
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ pNode->pData = pNode->pNext, pNode->pNext = NULL;
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
Abc_NtkGetLevelNum( pNtk );
@@ -692,6 +701,7 @@ Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vC
// add the PI/PO names
Abc_NtkAddDummyPiNames( pNtkNew );
Abc_NtkAddDummyPoNames( pNtkNew );
+ Abc_NtkAddDummyAssertNames( pNtkNew );
// check
if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
{
diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c
index 06376eed..b21278f7 100644
--- a/src/base/abci/abcSat.c
+++ b/src/base/abci/abcSat.c
@@ -42,12 +42,17 @@ static nMuxes;
SeeAlso []
***********************************************************************/
-int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFront, int fVerbose )
+int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fJFront, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects )
{
solver * pSat;
lbool status;
int RetValue, clk;
+ if ( pNumConfs )
+ *pNumConfs = 0;
+ if ( pNumInspects )
+ *pNumInspects = 0;
+
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkLatchNum(pNtk) == 0 );
@@ -78,7 +83,7 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFron
clk = clock();
if ( fVerbose )
pSat->verbosity = 1;
- status = solver_solve( pSat, NULL, NULL, nConfLimit, nImpLimit );
+ status = solver_solve( pSat, NULL, NULL, (sint64)nConfLimit, (sint64)nInsLimit );
if ( status == l_Undef )
{
// printf( "The problem timed out.\n" );
@@ -97,6 +102,7 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFron
else
assert( 0 );
// PRT( "SAT solver time", clock() - clk );
+// printf( "The number of conflicts = %d.\n", (int)pSat->solver_stats.conflicts );
// if the problem is SAT, get the counterexample
if ( status == l_True )
@@ -109,6 +115,12 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFron
// free the solver
if ( fVerbose )
Asat_SatPrintStats( stdout, pSat );
+
+ if ( pNumConfs )
+ *pNumConfs = (int)pSat->solver_stats.conflicts;
+ if ( pNumInspects )
+ *pNumInspects = (int)pSat->solver_stats.inspects;
+
solver_delete( pSat );
return RetValue;
}
@@ -401,6 +413,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
Vec_Vec_t * vCircuit;
int i, k, fUseMuxes = 1;
int clk1 = clock(), clk;
+ int fOrderCiVarsFirst = 0;
assert( Abc_NtkIsStrash(pNtk) );
@@ -431,6 +444,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
Vec_PtrPush( vNodes, pNode );
}
*/
+
// collect the nodes that need clauses and top-level assignments
Abc_NtkForEachCo( pNtk, pNode, i )
{
@@ -526,6 +540,21 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
}
}
+ // set preferred variables
+ if ( fOrderCiVarsFirst )
+ {
+ int * pPrefVars = ALLOC( int, Abc_NtkCiNum(pNtk) );
+ int nVars = 0;
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ {
+ if ( pNode->fMarkA == 0 )
+ continue;
+ pPrefVars[nVars++] = (int)pNode->pCopy;
+ }
+ nVars = ABC_MIN( nVars, 10 );
+ Asat_SolverSetPrefVars( pSat, pPrefVars, nVars );
+ }
+
// create the variable order
if ( fJFront )
{
diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c
index 08236edc..3665584e 100644
--- a/src/base/abci/abcSweep.c
+++ b/src/base/abci/abcSweep.c
@@ -571,12 +571,13 @@ int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
***********************************************************************/
void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose )
{
- Vec_Ptr_t * vFanout = pNode->pNtk->vPtrTemp;
Abc_Obj_t * pFanout, * pDriver;
+ Vec_Ptr_t * vFanout;
int i;
assert( Abc_ObjFaninNum(pNode) < 2 );
assert( Abc_ObjFanoutNum(pNode) > 0 );
// iterate through the fanouts
+ vFanout = Vec_PtrAlloc( Abc_ObjFanoutNum(pNode) );
Abc_NodeCollectFanouts( pNode, vFanout );
Vec_PtrForEachEntry( vFanout, pFanout, i )
{
@@ -607,6 +608,7 @@ void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose )
Abc_ObjPatchFanin( pFanout, pNode, pDriver );
}
}
+ Vec_PtrFree( vFanout );
}
/**Function*************************************************************
diff --git a/src/base/abci/abcTrace.c b/src/base/abci/abcTrace.c
index 0275c0a1..4abe235e 100644
--- a/src/base/abci/abcTrace.c
+++ b/src/base/abci/abcTrace.c
@@ -148,7 +148,7 @@ void Abc_HManStart()
pData = p->vSims->pArray[k];
for ( i = 0; i < p->nBits; i++ )
if ( i & (1 << k) )
- pData[i/32] |= (1 << (i%32));
+ pData[i>>5] |= (1 << (i&31));
}
// allocate storage for the nodes
p->pMmObj = Extra_MmFixedStart( sizeof(Abc_HObj_t) );
diff --git a/src/base/abci/abcVanEijk.c b/src/base/abci/abcVanEijk.c
index 8d8784e0..81423c30 100644
--- a/src/base/abci/abcVanEijk.c
+++ b/src/base/abci/abcVanEijk.c
@@ -544,8 +544,6 @@ Abc_Ntk_t * Abc_NtkVanEijkFrames( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCorresp, int nF
{
pLatchNew = Abc_NtkLatch(pNtkFrames, i);
Abc_ObjAddFanin( pLatchNew, pLatch->pCopy );
- Vec_PtrPush( pNtkFrames->vCis, pLatchNew );
- Vec_PtrPush( pNtkFrames->vCos, pLatchNew );
Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) );
pLatch->pNext = NULL;
}
diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c
index e0c65058..d9478b04 100644
--- a/src/base/abci/abcVerify.c
+++ b/src/base/abci/abcVerify.c
@@ -44,7 +44,7 @@ static void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2,
SeeAlso []
***********************************************************************/
-void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nImpLimit )
+void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit )
{
Abc_Ntk_t * pMiter;
Abc_Ntk_t * pCnf;
@@ -85,7 +85,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
}
// solve the CNF using the SAT solver
- RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0, 0 );
+ RetValue = Abc_NtkMiterSat( pCnf, (sint64)nConfLimit, (sint64)nInsLimit, 0, 0, NULL, NULL );
if ( RetValue == -1 )
printf( "Networks are undecided (SAT solver timed out).\n" );
else if ( RetValue == 0 )
@@ -178,7 +178,14 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
if ( RetValue == -1 )
printf( "Networks are undecided (resource limits is reached).\n" );
else if ( RetValue == 0 )
- printf( "Networks are NOT EQUIVALENT.\n" );
+ {
+ int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel );
+ if ( pSimInfo[0] != 1 )
+ printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" );
+ else
+ printf( "Networks are NOT EQUIVALENT.\n" );
+ free( pSimInfo );
+ }
else
printf( "Networks are equivalent.\n" );
if ( pMiter->pModel )
@@ -197,7 +204,7 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
SeeAlso []
***********************************************************************/
-void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nImpLimit, int nFrames )
+void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit, int nFrames )
{
Abc_Ntk_t * pMiter;
Abc_Ntk_t * pFrames;
@@ -257,7 +264,7 @@ void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
}
// solve the CNF using the SAT solver
- RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0, 0 );
+ RetValue = Abc_NtkMiterSat( pCnf, (sint64)nConfLimit, (sint64)nInsLimit, 0, 0, NULL, NULL );
if ( RetValue == -1 )
printf( "Networks are undecided (SAT solver timed out).\n" );
else if ( RetValue == 0 )
@@ -709,6 +716,52 @@ void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pM
if ( fRemove2 ) Abc_NtkDelete( pNtk2 );
}
+/**Function*************************************************************
+
+ Synopsis [Simulates buggy miter emailed by Mike.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSimulteBuggyMiter( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ int * pModel1, * pModel2, * pResult1, * pResult2;
+ char * vPiValues1 = "01001011100000000011010110101000000";
+ char * vPiValues2 = "11001101011101011111110100100010001";
+
+ assert( strlen(vPiValues1) == (unsigned)Abc_NtkPiNum(pNtk) );
+ assert( 1 == Abc_NtkPoNum(pNtk) );
+
+ pModel1 = ALLOC( int, Abc_NtkCiNum(pNtk) );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ pModel1[i] = vPiValues1[i] - '0';
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ pModel1[Abc_NtkPiNum(pNtk)+i] = ((int)pObj->pData) - 1;
+
+ pResult1 = Abc_NtkVerifySimulatePattern( pNtk, pModel1 );
+ printf( "Value = %d\n", pResult1[0] );
+
+ pModel2 = ALLOC( int, Abc_NtkCiNum(pNtk) );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ pModel2[i] = vPiValues2[i] - '0';
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ pModel2[Abc_NtkPiNum(pNtk)+i] = pResult1[Abc_NtkPoNum(pNtk)+i];
+
+ pResult2 = Abc_NtkVerifySimulatePattern( pNtk, pModel2 );
+ printf( "Value = %d\n", pResult2[0] );
+
+ free( pModel1 );
+ free( pModel2 );
+ free( pResult1 );
+ free( pResult2 );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/abci/module.make b/src/base/abci/module.make
index 41223c0b..c297180d 100644
--- a/src/base/abci/module.make
+++ b/src/base/abci/module.make
@@ -11,6 +11,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcFraig.c \
src/base/abci/abcFxu.c \
src/base/abci/abcGen.c \
+ src/base/abci/abcIvy.c \
src/base/abci/abcMap.c \
src/base/abci/abcMiter.c \
src/base/abci/abcNtbdd.c \
diff --git a/src/base/io/io.h b/src/base/io/io.h
index b408293e..8c8d6bed 100644
--- a/src/base/io/io.h
+++ b/src/base/io/io.h
@@ -68,6 +68,7 @@ extern Abc_Ntk_t * Io_ReadPla( char * pFileName, int fCheck );
/*=== abcUtil.c ==========================================================*/
extern Abc_Obj_t * Io_ReadCreatePi( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName );
+extern Abc_Obj_t * Io_ReadCreateAssert( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO );
extern Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesIn[], int nInputs );
extern Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 );
diff --git a/src/base/io/ioReadBaf.c b/src/base/io/ioReadBaf.c
index e2aa2109..8f4a8ec4 100644
--- a/src/base/io/ioReadBaf.c
+++ b/src/base/io/ioReadBaf.c
@@ -100,8 +100,6 @@ Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck )
pObj = Abc_NtkCreateLatch(pNtkNew);
Abc_NtkLogicStoreName( pObj, pCur ); while ( *pCur++ );
Vec_PtrPush( vNodes, pObj );
- Vec_PtrPush( pNtkNew->vCis, pObj );
- Vec_PtrPush( pNtkNew->vCos, pObj );
}
// get the pointer to the beginning of the node array
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c
index 3d33e6a3..11dd2db1 100644
--- a/src/base/io/ioReadBlif.c
+++ b/src/base/io/ioReadBlif.c
@@ -33,6 +33,7 @@ struct Io_ReadBlif_t_
char * pFileName; // the name of the file
Extra_FileReader_t * pReader; // the input file reader
// current processing info
+ Abc_Ntk_t * pNtkMaster; // the primary network
Abc_Ntk_t * pNtkCur; // the primary network
int LineCur; // the line currently parsed
// temporary storage for tokens
@@ -54,6 +55,7 @@ static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
static Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p );
static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+static int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens );
static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
@@ -151,7 +153,7 @@ Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
// add this network as part of the hierarchy
if ( pNtkMaster == NULL ) // no master network so far
{
- pNtkMaster = pNtk;
+ p->pNtkMaster = pNtkMaster = pNtk;
continue;
}
// make sure hierarchy does not have the network with this name
@@ -222,11 +224,12 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
}
// read the inputs/outputs
+ if ( p->pNtkMaster == NULL )
pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
fTokensReady = fStatus = 0;
for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
{
- if ( iLine % 1000 == 0 )
+ if ( p->pNtkMaster == NULL && iLine % 1000 == 0 )
Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL );
// consider different line types
@@ -242,6 +245,8 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens );
else if ( !strcmp( pDirective, ".outputs" ) )
fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens );
+ else if ( !strcmp( pDirective, ".asserts" ) )
+ fStatus = Io_ReadBlifNetworkAsserts( p, p->vTokens );
else if ( !strcmp( pDirective, ".input_arrival" ) )
fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens );
else if ( !strcmp( pDirective, ".default_input_arrival" ) )
@@ -257,8 +262,10 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
}
else if ( !strcmp( pDirective, ".blackbox" ) )
{
- pNtk->ntkType = ABC_NTK_BLACKBOX;
+ pNtk->ntkType = ABC_NTK_NETLIST;
pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
+ Extra_MmFlexStop( pNtk->pManFunc, 0 );
+ pNtk->pManFunc = NULL;
}
else
printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName,
@@ -268,6 +275,7 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
if ( fStatus == 1 )
return NULL;
}
+ if ( p->pNtkMaster == NULL )
Extra_ProgressBarStop( pProgress );
return pNtk;
}
@@ -321,6 +329,25 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
SeeAlso []
***********************************************************************/
+int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+{
+ int i;
+ for ( i = 1; i < vTokens->nSize; i++ )
+ Io_ReadCreateAssert( p->pNtkCur, vTokens->pArray[i] );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
Abc_Ntk_t * pNtk = p->pNtkCur;
@@ -340,7 +367,7 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
Abc_LatchSetInitDc( pLatch );
else
{
- ResetValue = atoi(vTokens->pArray[3]);
+ ResetValue = atoi(vTokens->pArray[vTokens->nSize-1]);
if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
@@ -870,50 +897,55 @@ int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, s
// create the fanins of the box
Abc_NtkForEachPi( pNtkModel, pObj, i )
pObj->pCopy = NULL;
- Vec_PtrForEachEntryStart( pNames, pName, i, 1 )
+ if ( Abc_NtkPiNum(pNtkModel) == 0 )
+ Start = 1;
+ else
{
- pActual = Io_ReadBlifCleanName(pName);
- if ( pActual == NULL )
- {
- p->LineCur = (int)pBox->pCopy;
- sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
- Io_ReadBlifPrintErrorMessage( p );
- return 1;
- }
- Length = pActual - pName - 1;
- pName[Length] = 0;
- // find the PI net with this name
- pObj = Abc_NtkFindNet( pNtkModel, pName );
- if ( pObj == NULL )
- {
- p->LineCur = (int)pBox->pCopy;
- sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
- Io_ReadBlifPrintErrorMessage( p );
- return 1;
- }
- // get the PI
- pObj = Abc_ObjFanin0(pObj);
- // quit if this is not a PI net
- if ( !Abc_ObjIsPi(pObj) )
- {
- pName[Length] = '=';
- Start = i;
- break;
- }
- // remember the actual name in the net
- if ( pObj->pCopy != NULL )
- {
- p->LineCur = (int)pBox->pCopy;
- sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName );
- Io_ReadBlifPrintErrorMessage( p );
- return 1;
- }
- pObj->pCopy = (void *)pActual;
- // quit if we processed all PIs
- if ( i == Abc_NtkPiNum(pNtkModel) )
+ Vec_PtrForEachEntryStart( pNames, pName, i, 1 )
{
- Start = i+1;
- break;
+ pActual = Io_ReadBlifCleanName(pName);
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ Length = pActual - pName - 1;
+ pName[Length] = 0;
+ // find the PI net with this name
+ pObj = Abc_NtkFindNet( pNtkModel, pName );
+ if ( pObj == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // get the PI
+ pObj = Abc_ObjFanin0(pObj);
+ // quit if this is not a PI net
+ if ( !Abc_ObjIsPi(pObj) )
+ {
+ pName[Length] = '=';
+ Start = i;
+ break;
+ }
+ // remember the actual name in the net
+ if ( pObj->pCopy != NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pObj->pCopy = (void *)pActual;
+ // quit if we processed all PIs
+ if ( i == Abc_NtkPiNum(pNtkModel) )
+ {
+ Start = i+1;
+ break;
+ }
}
}
// create the fanins of the box
@@ -986,6 +1018,8 @@ int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, s
pObj->pCopy = NULL;
// remove the array of names, assign the pointer to the model
+ Vec_PtrForEachEntry( pBox->pData, pName, i )
+ free( pName );
Vec_PtrFree( pBox->pData );
pBox->pData = pNtkModel;
return 0;
diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c
index fc37bc3f..5482eed4 100644
--- a/src/base/io/ioUtil.c
+++ b/src/base/io/ioUtil.c
@@ -80,6 +80,31 @@ Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName )
/**Function*************************************************************
+ Synopsis [Creates PO terminal and net.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Io_ReadCreateAssert( Abc_Ntk_t * pNtk, char * pName )
+{
+ Abc_Obj_t * pNet, * pTerm;
+ // get the PO net
+ pNet = Abc_NtkFindNet( pNtk, pName );
+ if ( pNet && Abc_ObjFaninNum(pNet) == 0 )
+ printf( "Warning: Assert \"%s\" appears twice in the list.\n", pName );
+ pNet = Abc_NtkFindOrCreateNet( pNtk, pName );
+ // add the PO node
+ pTerm = Abc_NtkCreateAssert( pNtk );
+ Abc_ObjAddFanin( pTerm, pNet );
+ return pTerm;
+}
+
+/**Function*************************************************************
+
Synopsis [Create a latch with the given input/output.]
Description [By default, the latch value is unknown (ABC_INIT_NONE).]
diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c
index 1e27498d..8cbd0cd0 100644
--- a/src/base/io/ioWriteBlif.c
+++ b/src/base/io/ioWriteBlif.c
@@ -30,6 +30,7 @@ static void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
+static void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode );
static void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode );
static void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode );
@@ -115,7 +116,7 @@ void Io_WriteBlifNetlist( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
Abc_Ntk_t * pExdc;
- assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsBlackbox(pNtk) );
+ assert( Abc_NtkIsNetlist(pNtk) );
// write the model name
fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
// write the network
@@ -159,8 +160,16 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
Io_NtkWritePos( pFile, pNtk, fWriteLatches );
fprintf( pFile, "\n" );
+ // write the assertions
+ if ( Abc_NtkAssertNum(pNtk) )
+ {
+ fprintf( pFile, ".asserts" );
+ Io_NtkWriteAsserts( pFile, pNtk );
+ fprintf( pFile, "\n" );
+ }
+
// write the blackbox
- if ( Abc_NtkIsBlackbox( pNtk ) )
+ if ( Abc_NtkHasBlackbox( pNtk ) )
{
fprintf( pFile, ".blackbox\n" );
return;
@@ -296,6 +305,8 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
Abc_NtkForEachCo( pNtk, pTerm, i )
{
+ if ( Abc_ObjIsAssert(pTerm) )
+ continue;
pNet = Abc_ObjFanin0(pTerm);
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
@@ -313,6 +324,45 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
}
}
+/**Function*************************************************************
+
+ Synopsis [Writes the assertion list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pTerm, * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+
+ LineLength = 8;
+ NameCounter = 0;
+
+ Abc_NtkForEachAssert( pNtk, pTerm, i )
+ {
+ pNet = Abc_ObjFanin0(pTerm);
+ // get the line length after this name is written
+ AddedLength = strlen(Abc_ObjName(pNet)) + 1;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, " \\\n" );
+ // reset the line length
+ LineLength = 0;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s", Abc_ObjName(pNet) );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+}
/**Function*************************************************************
diff --git a/src/base/io/ioWriteVer.c b/src/base/io/ioWriteVer.c
index 75467d4d..e18f9b12 100644
--- a/src/base/io/ioWriteVer.c
+++ b/src/base/io/ioWriteVer.c
@@ -33,7 +33,6 @@ static void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
static void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
static void Io_WriteVerilogGates( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk );
-static void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros );
static void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk );
static int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk );
static char * Io_WriteVerilogGetName( Abc_Obj_t * pObj );
@@ -225,7 +224,7 @@ void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
int i, Counter, nNodes;
// count the number of wires
- nNodes = 0;
+ nNodes = Abc_NtkLatchNum(pNtk);
Abc_NtkForEachNode( pNtk, pTerm, i )
{
if ( i == 0 )
@@ -261,6 +260,24 @@ void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
LineLength += AddedLength;
NameCounter++;
}
+ Abc_NtkForEachLatch( pNtk, pTerm, i )
+ {
+ pNet = Abc_ObjFanin0(pTerm);
+ Counter++;
+ // get the line length after this name is written
+ AddedLength = strlen(Abc_ObjName(pNet)) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = 3;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", Io_WriteVerilogGetName(pNet), (Counter==nNodes)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+ assert( Counter == nNodes );
}
/**Function*************************************************************
@@ -325,12 +342,15 @@ void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk )
int i;
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
+// fprintf( pFile, " always@(posedge gclk) begin %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
+ fprintf( pFile, " always begin %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
+ fprintf( pFile, " = %s; end\n", Abc_ObjName(Abc_ObjFanin0(pLatch)) );
if ( Abc_LatchInit(pLatch) == ABC_INIT_ZERO )
- fprintf( pFile, " initial begin %s = 1\'b0; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
+// fprintf( pFile, " initial begin %s = 1\'b0; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
+ fprintf( pFile, " initial begin %s = 0; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
else if ( Abc_LatchInit(pLatch) == ABC_INIT_ONE )
- fprintf( pFile, " initial begin %s = 1\'b1; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
- fprintf( pFile, " always@(posedge gclk) begin %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
- fprintf( pFile, " = %s; end\n", Abc_ObjName(Abc_ObjFanin0(pLatch)) );
+// fprintf( pFile, " initial begin %s = 1\'b1; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
+ fprintf( pFile, " initial begin %s = 1; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
}
}
@@ -378,7 +398,7 @@ void Io_WriteVerilogGates( FILE * pFile, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
+void Io_WriteVerilogNodes2( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj, * pFanin;
int i, k, nFanins;
@@ -390,7 +410,8 @@ void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
nFanins = Abc_ObjFaninNum(pObj);
if ( nFanins == 0 )
{
- fprintf( pFile, " assign %s = 1'b%d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) );
+// fprintf( pFile, " assign %s = 1'b%d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) );
+ fprintf( pFile, " assign %s = %d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) );
continue;
}
if ( nFanins == 1 )
@@ -410,7 +431,7 @@ void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
/**Function*************************************************************
- Synopsis [Writes the inputs.]
+ Synopsis [Writes the nodes.]
Description []
@@ -419,24 +440,32 @@ void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros )
+void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
{
- Abc_Obj_t * pFanin;
- int i, Counter = 2;
- fprintf( pFile, "(.z (%s)", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) );
- Abc_ObjForEachFanin( pObj, pFanin, i )
- {
- if ( Counter++ % 4 == 0 )
- fprintf( pFile, "\n " );
- fprintf( pFile, " .i%d (%s)", i+1, Io_WriteVerilogGetName(Abc_ObjFanin(pObj,i)) );
- }
- for ( ; i < nInMax; i++ )
+ Abc_Obj_t * pObj, * pFanin;
+ int i, k, nFanins;
+ char pOper[] = " ? ", Symb;
+ Abc_NtkForEachNode( pNtk, pObj, i )
{
- if ( Counter++ % 4 == 0 )
- fprintf( pFile, "\n " );
- fprintf( pFile, " .i%d (%s)", i+1, fPadZeros? "1\'b0" : "1\'b1" );
+ assert( Abc_SopGetCubeNum(pObj->pData) == 1 );
+ nFanins = Abc_ObjFaninNum(pObj);
+ if ( nFanins == 0 )
+ {
+ fprintf( pFile, " assign %s = 1'b%d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) );
+ continue;
+ }
+ fprintf( pFile, " assign %s = ", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) );
+ pOper[1] = Abc_SopIsComplement(pObj->pData) ? '|' : '&';
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ {
+ Symb = ((char*)pObj->pData)[k];
+ assert( Symb == '0' || Symb == '1' );
+ if ( Symb == '0' )
+ fprintf( pFile, "~" );
+ fprintf( pFile, "%s%s", Io_WriteVerilogGetName(pFanin), (k==nFanins-1? "" : pOper) );
+ }
+ fprintf( pFile, ";\n" );
}
- fprintf( pFile, ");\n" );
}
/**Function*************************************************************
diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c
index 5747443c..23e304b3 100644
--- a/src/base/main/mainFrame.c
+++ b/src/base/main/mainFrame.c
@@ -446,7 +446,7 @@ void Abc_FrameDeleteAllNetworks( Abc_Frame_t * p )
Abc_NtkDelete( pNtk );
// set the current network empty
p->pNtkCur = NULL;
- fprintf( p->Out, "All networks have been deleted.\n" );
+// fprintf( p->Out, "All networks have been deleted.\n" );
}
/**Function*************************************************************
diff --git a/src/base/main/module.make b/src/base/main/module.make
index 7a04e533..367f89f6 100644
--- a/src/base/main/module.make
+++ b/src/base/main/module.make
@@ -1,5 +1,5 @@
SRC += src/base/main/main.c \
src/base/main/mainFrame.c \
src/base/main/mainInit.c \
- src/base/main/mainUtils.c \
- src/base/main/libSupport.c
+ src/base/main/libSupport.c \
+ src/base/main/mainUtils.c
diff --git a/src/base/seq/seqAigCore.c b/src/base/seq/seqAigCore.c
index 813b1ed8..358d306c 100644
--- a/src/base/seq/seqAigCore.c
+++ b/src/base/seq/seqAigCore.c
@@ -319,6 +319,7 @@ int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int
// add the PI/PO names
Abc_NtkAddDummyPiNames( pNtkProb );
Abc_NtkAddDummyPoNames( pNtkProb );
+ Abc_NtkAddDummyAssertNames( pNtkProb );
// make sure everything is okay with the network structure
if ( !Abc_NtkDoCheck( pNtkProb ) )
@@ -358,7 +359,7 @@ int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int
// solve the miter
clk = clock();
// RetValue = Abc_NtkMiterSat_OldAndRusty( pNtkCnf, 30, 0 );
- RetValue = Abc_NtkMiterSat( pNtkCnf, 500000, 50000000, 0, 0 );
+ RetValue = Abc_NtkMiterSat( pNtkCnf, (sint64)500000, (sint64)50000000, 0, 0, NULL, NULL );
if ( fVerbose )
if ( clock() - clk > 100 )
{
diff --git a/src/base/seq/seqCreate.c b/src/base/seq/seqCreate.c
index b0c2e084..a553e06f 100644
--- a/src/base/seq/seqCreate.c
+++ b/src/base/seq/seqCreate.c
@@ -110,17 +110,23 @@ Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk )
pNtkNew->nObjs++;
}
pNtkNew->nNodes = pNtk->nNodes;
- pNtkNew->nPis = pNtk->nPis;
- pNtkNew->nPos = pNtk->nPos;
// create PI/PO and their names
Abc_NtkForEachPi( pNtk, pObj, i )
{
+ Vec_PtrPush( pNtkNew->vPis, pObj->pCopy );
Vec_PtrPush( pNtkNew->vCis, pObj->pCopy );
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
}
Abc_NtkForEachPo( pNtk, pObj, i )
{
+ Vec_PtrPush( pNtkNew->vPos, pObj->pCopy );
+ Vec_PtrPush( pNtkNew->vCos, pObj->pCopy );
+ Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
+ }
+ Abc_NtkForEachAssert( pNtk, pObj, i )
+ {
+ Vec_PtrPush( pNtkNew->vAsserts, pObj->pCopy );
Vec_PtrPush( pNtkNew->vCos, pObj->pCopy );
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
}
@@ -252,7 +258,7 @@ void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk )
Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew;
- Abc_Obj_t * pObj, * pObjNew, * pFaninNew;
+ Abc_Obj_t * pObj, * pFaninNew;
Seq_Lat_t * pRing;
int i;
@@ -297,11 +303,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
// add the latches and their names
Abc_NtkAddDummyLatchNames( pNtkNew );
- Abc_NtkForEachLatch( pNtkNew, pObjNew, i )
- {
- Vec_PtrPush( pNtkNew->vCis, pObjNew );
- Vec_PtrPush( pNtkNew->vCos, pObjNew );
- }
+ Abc_NtkOrderCisCos( pNtkNew );
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
if ( !Abc_NtkCheck( pNtkNew ) )
@@ -324,7 +326,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk )
Abc_Ntk_t * Abc_NtkSeqToLogicSop_old( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew;
- Abc_Obj_t * pObj, * pObjNew, * pFaninNew;
+ Abc_Obj_t * pObj, * pFaninNew;
int i;
assert( Abc_NtkIsSeq(pNtk) );
@@ -371,11 +373,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop_old( Abc_Ntk_t * pNtk )
}
// add the latches and their names
Abc_NtkAddDummyLatchNames( pNtkNew );
- Abc_NtkForEachLatch( pNtkNew, pObjNew, i )
- {
- Vec_PtrPush( pNtkNew->vCis, pObjNew );
- Vec_PtrPush( pNtkNew->vCos, pObjNew );
- }
+ Abc_NtkOrderCisCos( pNtkNew );
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
if ( !Abc_NtkCheck( pNtkNew ) )
diff --git a/src/base/seq/seqFpgaCore.c b/src/base/seq/seqFpgaCore.c
index 6d0c8c97..79e44caf 100644
--- a/src/base/seq/seqFpgaCore.c
+++ b/src/base/seq/seqFpgaCore.c
@@ -280,7 +280,7 @@ Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtk )
Abc_Seq_t * p = pNtk->pManFunc;
Abc_Ntk_t * pNtkMap;
Vec_Ptr_t * vLeaves;
- Abc_Obj_t * pObj, * pLatch, * pFaninNew;
+ Abc_Obj_t * pObj, * pFaninNew;
Seq_Lat_t * pRing;
int i;
@@ -322,11 +322,7 @@ Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtk )
// add the latches and their names
Abc_NtkAddDummyLatchNames( pNtkMap );
- Abc_NtkForEachLatch( pNtkMap, pLatch, i )
- {
- Vec_PtrPush( pNtkMap->vCis, pLatch );
- Vec_PtrPush( pNtkMap->vCos, pLatch );
- }
+ Abc_NtkOrderCisCos( pNtkMap );
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkMap, 1 );
// make the network minimum base
diff --git a/src/base/seq/seqMapCore.c b/src/base/seq/seqMapCore.c
index b1d4871e..a444ec58 100644
--- a/src/base/seq/seqMapCore.c
+++ b/src/base/seq/seqMapCore.c
@@ -370,7 +370,7 @@ Abc_Ntk_t * Seq_NtkSeqMapMapped( Abc_Ntk_t * pNtk )
Seq_Match_t * pMatch;
Abc_Ntk_t * pNtkMap;
Vec_Ptr_t * vLeaves;
- Abc_Obj_t * pObj, * pLatch, * pFaninNew;
+ Abc_Obj_t * pObj, * pFaninNew;
Seq_Lat_t * pRing;
int i;
@@ -413,11 +413,7 @@ Abc_Ntk_t * Seq_NtkSeqMapMapped( Abc_Ntk_t * pNtk )
// add the latches and their names
Abc_NtkAddDummyLatchNames( pNtkMap );
- Abc_NtkForEachLatch( pNtkMap, pLatch, i )
- {
- Vec_PtrPush( pNtkMap->vCis, pLatch );
- Vec_PtrPush( pNtkMap->vCos, pLatch );
- }
+ Abc_NtkOrderCisCos( pNtkMap );
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkMap, 1 );
// make the network minimum base
diff --git a/src/base/seq/seqRetCore.c b/src/base/seq/seqRetCore.c
index 38915bf4..ba66a881 100644
--- a/src/base/seq/seqRetCore.c
+++ b/src/base/seq/seqRetCore.c
@@ -327,7 +327,7 @@ Abc_Ntk_t * Seq_NtkRetimeReconstruct( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkSeq )
Abc_Seq_t * p = pNtkSeq->pManFunc;
Seq_Lat_t * pRing0, * pRing1;
Abc_Ntk_t * pNtkNew;
- Abc_Obj_t * pObj, * pObjNew, * pFanin, * pFaninNew, * pMirror;
+ Abc_Obj_t * pObj, * pFanin, * pFaninNew, * pMirror;
Vec_Ptr_t * vMirrors;
int i, k;
@@ -408,11 +408,7 @@ Abc_Ntk_t * Seq_NtkRetimeReconstruct( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkSeq )
// add the latches and their names
Abc_NtkAddDummyLatchNames( pNtkNew );
- Abc_NtkForEachLatch( pNtkNew, pObjNew, i )
- {
- Vec_PtrPush( pNtkNew->vCis, pObjNew );
- Vec_PtrPush( pNtkNew->vCos, pObjNew );
- }
+ Abc_NtkOrderCisCos( pNtkNew );
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
if ( !Abc_NtkCheck( pNtkNew ) )
diff --git a/src/map/fpga/fpgaCut.c b/src/map/fpga/fpgaCut.c
index 2f686711..01562708 100644
--- a/src/map/fpga/fpgaCut.c
+++ b/src/map/fpga/fpgaCut.c
@@ -1082,7 +1082,7 @@ Fpga_Cut_t * Fpga_CutSortCuts( Fpga_Man_t * pMan, Fpga_CutTable_t * p, Fpga_Cut_
nCuts = Fpga_CutList2Array( p->pCuts1, pList );
assert( nCuts <= FPGA_CUTS_MAX_COMPUTE );
// sort the cuts
- qsort( (void *)p->pCuts1, nCuts, sizeof(Fpga_Cut_t *),
+ qsort( (void *)p->pCuts1, nCuts, sizeof(void *),
(int (*)(const void *, const void *)) Fpga_CutSortCutsCompare );
// move them back into the list
if ( nCuts > FPGA_CUTS_MAX_USE - 1 )
diff --git a/src/map/mapper/mapperTable.c b/src/map/mapper/mapperTable.c
index e097ef57..d0cb7a01 100644
--- a/src/map/mapper/mapperTable.c
+++ b/src/map/mapper/mapperTable.c
@@ -325,7 +325,7 @@ void Map_SuperTableSortSupergates( Map_HashTable_t * p, int nSupersMax )
ppSupers[nSupers++] = pSuper;
// sort by usage
- qsort( (void *)ppSupers, nSupers, sizeof(int),
+ qsort( (void *)ppSupers, nSupers, sizeof(Map_Super_t *),
(int (*)(const void *, const void *)) Map_SuperTableCompareSupergates );
assert( Map_SuperTableCompareSupergates( ppSupers, ppSupers + nSupers - 1 ) <= 0 );
@@ -380,7 +380,7 @@ void Map_SuperTableSortSupergatesByDelay( Map_HashTable_t * p, int nSupersMax )
if ( nSupers == 0 )
continue;
// sort the gates by delay
- qsort( (void *)ppSupers, nSupers, sizeof(int),
+ qsort( (void *)ppSupers, nSupers, sizeof(Map_Super_t *),
(int (*)(const void *, const void *)) Map_SuperTableCompareGatesInList );
assert( Map_SuperTableCompareGatesInList( ppSupers, ppSupers + nSupers - 1 ) <= 0 );
// link them in the reverse order
diff --git a/src/map/mapper/mapperTruth.c b/src/map/mapper/mapperTruth.c
index bebb9b74..388b6dd3 100644
--- a/src/map/mapper/mapperTruth.c
+++ b/src/map/mapper/mapperTruth.c
@@ -89,14 +89,15 @@ void Map_MappingTruths( Map_Man_t * pMan )
***********************************************************************/
void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
-{
+{
// unsigned uCanon1, uCanon2;
unsigned uTruth[2], uCanon[2];
unsigned char uPhases[16];
unsigned * uCanon2;
char * pPhases2;
- int fUseFast = 0;
- int fUseRec = 1;
+ int fUseFast = 1;
+ int fUseSlow = 0;
+ int fUseRec = 0; // this does not work for Solaris
extern int Map_CanonCompute( int nVarsMax, int nVarsReal, unsigned * pt, unsigned ** pptRes, char ** ppfRes );
@@ -117,6 +118,8 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
// compute the canonical form for the positive phase
if ( fUseFast )
Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
+ else if ( fUseSlow )
+ Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
else if ( fUseRec )
{
// Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
@@ -145,6 +148,8 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
uTruth[1] = ~uTruth[1];
if ( fUseFast )
Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
+ else if ( fUseSlow )
+ Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
else if ( fUseRec )
{
// Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h
index 6336f5ea..d404dbc6 100644
--- a/src/misc/extra/extra.h
+++ b/src/misc/extra/extra.h
@@ -464,9 +464,8 @@ extern unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, i
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
#define REALLOC(type, obj, num) \
- (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \
- ((type *) malloc(sizeof(type) * (num)))
-
+ ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
+ ((type *) malloc(sizeof(type) * (num))))
extern long Extra_CpuTime();
extern int Extra_GetSoftDataLimit();
diff --git a/src/misc/extra/extraUtilBitMatrix.c b/src/misc/extra/extraUtilBitMatrix.c
index 93cbbeac..b860a538 100644
--- a/src/misc/extra/extraUtilBitMatrix.c
+++ b/src/misc/extra/extraUtilBitMatrix.c
@@ -348,7 +348,7 @@ int Extra_BitMatrixCountOnesUpper( Extra_BitMat_t * p )
int i, k, nTotal = 0;
for ( i = 0; i < p->nSize; i++ )
for ( k = i + 1; k < p->nSize; k++ )
- nTotal += ( (p->ppData[i][k/32] & (1 << (k%32))) > 0 );
+ nTotal += ( (p->ppData[i][k>>5] & (1 << (k&31))) > 0 );
return nTotal;
}
diff --git a/src/misc/extra/extraUtilMisc.c b/src/misc/extra/extraUtilMisc.c
index bd7f19ec..f62de314 100644
--- a/src/misc/extra/extraUtilMisc.c
+++ b/src/misc/extra/extraUtilMisc.c
@@ -1323,9 +1323,9 @@ void Extra_TruthExpand( int nVars, int nWords, unsigned * puTruth, unsigned uPha
{ 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
{ 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
{ 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 },
- { 0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000 },
- { 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 },
- { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000 }
+ { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
};
static char Cases[256] = {
0, // 00000000
@@ -1922,12 +1922,12 @@ void Extra_TruthExpand( int nVars, int nWords, unsigned * puTruth, unsigned uPha
puTruthR[i] = 0;
nMints = (1 << nVars);
for ( i = 0; i < nMints; i++ )
- if ( puTruth[i/32] & (1 << (i%32)) )
+ if ( puTruth[i>>5] & (1 << (i&31)) )
{
for ( iRes = 0, k = 0; k < 5; k++ )
if ( i & (1 << pPerm[k]) )
iRes |= (1 << k);
- puTruthR[iRes/32] |= (1 << (iRes%32));
+ puTruthR[iRes>>5] |= (1 << (iRes&31));
}
}
}
@@ -2058,9 +2058,9 @@ unsigned ** Extra_Truths8()
{ 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
{ 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
{ 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 },
- { 0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000 },
- { 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 },
- { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000000 }
+ { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
};
static unsigned * puResult[8] = {
uTruths[0], uTruths[1], uTruths[2], uTruths[3], uTruths[4], uTruths[5], uTruths[6], uTruths[7]
diff --git a/src/misc/extra/extraUtilTruth.c b/src/misc/extra/extraUtilTruth.c
index 74308ab2..a0c58025 100644
--- a/src/misc/extra/extraUtilTruth.c
+++ b/src/misc/extra/extraUtilTruth.c
@@ -264,15 +264,15 @@ DdNode * Extra_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int
DdNode * bF0, * bF1, * bF;
if ( nVars == 0 )
{
- if ( pTruth[iBit/32] & (1 << iBit%32) )
+ if ( pTruth[iBit>>5] & (1 << iBit&31) )
return b1;
return b0;
}
if ( nVars == 5 )
{
- if ( pTruth[iBit/32] == 0xFFFFFFFF )
+ if ( pTruth[iBit>>5] == 0xFFFFFFFF )
return b1;
- if ( pTruth[iBit/32] == 0 )
+ if ( pTruth[iBit>>5] == 0 )
return b0;
}
// other special cases can be added
diff --git a/src/misc/mvc/mvc.h b/src/misc/mvc/mvc.h
index 650f698d..70834e0a 100644
--- a/src/misc/mvc/mvc.h
+++ b/src/misc/mvc/mvc.h
@@ -49,7 +49,7 @@
////////////////////////////////////////////////////////////////////////
// cube/list/cover/data
-typedef unsigned long Mvc_CubeWord_t;
+typedef unsigned int Mvc_CubeWord_t;
typedef struct MvcCubeStruct Mvc_Cube_t;
typedef struct MvcListStruct Mvc_List_t;
typedef struct MvcCoverStruct Mvc_Cover_t;
diff --git a/src/misc/nm/module.make b/src/misc/nm/module.make
new file mode 100644
index 00000000..2a3820c7
--- /dev/null
+++ b/src/misc/nm/module.make
@@ -0,0 +1,2 @@
+SRC += src/misc/nm/nmApi.c \
+ src/misc/nm/nmTable.c
diff --git a/src/misc/nm/nm.h b/src/misc/nm/nm.h
index 5b17aaed..9c96c8ba 100644
--- a/src/misc/nm/nm.h
+++ b/src/misc/nm/nm.h
@@ -52,10 +52,12 @@ extern Nm_Man_t * Nm_ManCreate( int nSize );
extern void Nm_ManFree( Nm_Man_t * p );
extern int Nm_ManNumEntries( Nm_Man_t * p );
extern char * Nm_ManStoreIdName( Nm_Man_t * p, int ObjId, char * pName, char * pSuffix );
+extern void Nm_ManDeleteIdName( Nm_Man_t * p, int ObjId );
extern char * Nm_ManCreateUniqueName( Nm_Man_t * p, int ObjId );
extern char * Nm_ManFindNameById( Nm_Man_t * p, int ObjId );
extern int Nm_ManFindIdByName( Nm_Man_t * p, char * pName, int * pSecond );
extern void Nm_ManPrintTables( Nm_Man_t * p );
+extern Vec_Int_t * Nm_ManReturnNameIds( Nm_Man_t * p );
#ifdef __cplusplus
}
diff --git a/src/misc/nm/nmApi.c b/src/misc/nm/nmApi.c
index 72ec24e6..3a9ac074 100644
--- a/src/misc/nm/nmApi.c
+++ b/src/misc/nm/nmApi.c
@@ -135,6 +135,31 @@ char * Nm_ManStoreIdName( Nm_Man_t * p, int ObjId, char * pName, char * pSuffix
return pEntry->Name;
}
+/**Function*************************************************************
+
+ Synopsis [Creates a new entry in the name manager.]
+
+ Description [Returns 1 if the entry with the given object ID
+ already exists in the name manager.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Nm_ManDeleteIdName( Nm_Man_t * p, int ObjId )
+{
+ Nm_Entry_t * pEntry;
+ pEntry = Nm_ManTableLookupId(p, ObjId);
+ if ( pEntry == NULL )
+ {
+ printf( "Nm_ManDeleteIdName(): This entry is not in the table.\n" );
+ return;
+ }
+ // remove entry from the table
+ Nm_ManTableDelete( p, pEntry );
+}
+
/**Function*************************************************************
@@ -255,6 +280,28 @@ void Nm_ManPrintTables( Nm_Man_t * p )
printf( "\n" );
}
+/**Function*************************************************************
+
+ Synopsis [Return the IDs of objects with names.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Nm_ManReturnNameIds( Nm_Man_t * p )
+{
+ Vec_Int_t * vNameIds;
+ int i;
+ vNameIds = Vec_IntAlloc( p->nEntries );
+ for ( i = 0; i < p->nBins; i++ )
+ if ( p->pBinsI2N[i] )
+ Vec_IntPush( vNameIds, p->pBinsI2N[i]->ObjId );
+ return vNameIds;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/misc/nm/nmInt.h b/src/misc/nm/nmInt.h
index d0475c23..43901993 100644
--- a/src/misc/nm/nmInt.h
+++ b/src/misc/nm/nmInt.h
@@ -30,6 +30,7 @@ extern "C" {
////////////////////////////////////////////////////////////////////////
#include "extra.h"
+#include "vec.h"
#include "nm.h"
////////////////////////////////////////////////////////////////////////
diff --git a/src/misc/util/util_hack.h b/src/misc/util/util_hack.h
index a9b90e61..71c77321 100644
--- a/src/misc/util/util_hack.h
+++ b/src/misc/util/util_hack.h
@@ -73,8 +73,8 @@ extern "C" {
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
#define REALLOC(type, obj, num) \
- (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \
- ((type *) malloc(sizeof(type) * (num)))
+ ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
+ ((type *) malloc(sizeof(type) * (num))))
extern long Extra_CpuTime();
extern int Extra_GetSoftDataLimit();
diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h
index 5a627623..fd8dbc86 100644
--- a/src/misc/vec/vecInt.h
+++ b/src/misc/vec/vecInt.h
@@ -540,6 +540,27 @@ static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
/**Function*************************************************************
+ Synopsis [Inserts the entry while preserving the increasing order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return 1;
+ Vec_IntPushOrder( p, Entry );
+ return 0;
+}
+
+/**Function*************************************************************
+
Synopsis []
Description []
diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h
index 65314af6..63dcc9b8 100644
--- a/src/misc/vec/vecPtr.h
+++ b/src/misc/vec/vecPtr.h
@@ -472,6 +472,26 @@ static inline void * Vec_PtrPop( Vec_Ptr_t * p )
/**Function*************************************************************
+ Synopsis [Find entry.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
Synopsis []
Description []
diff --git a/src/misc/vec/vecStr.h b/src/misc/vec/vecStr.h
index 5549d374..4cda06f0 100644
--- a/src/misc/vec/vecStr.h
+++ b/src/misc/vec/vecStr.h
@@ -494,10 +494,10 @@ static inline int Vec_StrSortCompare2( char * pp1, char * pp2 )
static inline void Vec_StrSort( Vec_Str_t * p, int fReverse )
{
if ( fReverse )
- qsort( (void *)p->pArray, p->nSize, sizeof(int),
+ qsort( (void *)p->pArray, p->nSize, sizeof(char),
(int (*)(const void *, const void *)) Vec_StrSortCompare2 );
else
- qsort( (void *)p->pArray, p->nSize, sizeof(int),
+ qsort( (void *)p->pArray, p->nSize, sizeof(char),
(int (*)(const void *, const void *)) Vec_StrSortCompare1 );
}
diff --git a/src/opt/cut/Abc_NtkFindCi.c b/src/opt/cut/Abc_NtkFindCi.c
new file mode 100644
index 00000000..203f9e6f
--- /dev/null
+++ b/src/opt/cut/Abc_NtkFindCi.c
@@ -0,0 +1,988 @@
+/**CFile****************************************************************
+
+ FileName [cutPre22.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Precomputes truth tables for the 2x2 macro cell.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cutPre22.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cutInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define CUT_CELL_MVAR 9
+
+typedef struct Cut_Cell_t_ Cut_Cell_t;
+typedef struct Cut_CMan_t_ Cut_CMan_t;
+
+struct Cut_Cell_t_
+{
+ Cut_Cell_t * pNext; // pointer to the next cell in the table
+ Cut_Cell_t * pNextVar; // pointer to the next cell of this support size
+ Cut_Cell_t * pParent; // pointer to the cell used to derive this one
+ int nUsed; // the number of times the cell is used
+ char Box[4]; // functions in the boxes
+ unsigned nVars : 4; // the number of variables
+ unsigned CrossBar0 : 4; // the variable set equal
+ unsigned CrossBar1 : 4; // the variable set equal
+ unsigned CrossBarPhase : 2; // the phase of the cross bar (0, 1, or 2)
+ unsigned CanonPhase : 18; // the canonical phase
+ char CanonPerm[CUT_CELL_MVAR+3]; // semicanonical permutation
+ short Store[2*CUT_CELL_MVAR]; // minterm counts in the cofactors
+ unsigned uTruth[1<<(CUT_CELL_MVAR-5)]; // the current truth table
+};
+
+struct Cut_CMan_t_
+{
+ // storage for canonical cells
+ Extra_MmFixed_t * pMem;
+ st_table * tTable;
+ Cut_Cell_t * pSameVar[CUT_CELL_MVAR+1];
+ // elementary truth tables
+ unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)];
+ // temporary truth tables
+ unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)];
+ unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)];
+ unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)];
+ unsigned uFinal[1<<(CUT_CELL_MVAR-5)];
+ unsigned puAux[1<<(CUT_CELL_MVAR-5)];
+ // statistical variables
+ int nTotal;
+ int nGood;
+ int nVarCounts[CUT_CELL_MVAR+1];
+ int nSymGroups[CUT_CELL_MVAR+1];
+ int nSymGroupsE[CUT_CELL_MVAR+1];
+ int timeCanon;
+ int timeSupp;
+ int timeTable;
+ int nCellFound;
+ int nCellNotFound;
+};
+
+// NP-classes of functions of 3 variables (22)
+static char * s_NP3[22] = {
+ " 0\n", // 00 const 0 // 0 vars
+ " 1\n", // 01 const 1 // 0 vars
+ "1 1\n", // 02 a // 1 vars
+ "11 1\n", // 03 ab // 2 vars
+ "11 0\n", // 04 (ab)' // 2 vars
+ "10 1\n01 1\n", // 05 a<+>b // 2 vars
+ "111 1\n", // 06 0s abc // 3 vars
+ "111 0\n", // 07 (abc)' //
+ "11- 1\n1-1 1\n", // 08 1p a(b+c) //
+ "11- 0\n1-1 0\n", // 09 (a(b+c))' //
+ "111 1\n100 1\n010 1\n001 1\n", // 10 2s a<+>b<+>c //
+ "10- 0\n1-0 0\n011 0\n", // 11 3p a<+>bc //
+ "101 1\n110 1\n", // 12 4p a(b<+>c) //
+ "101 0\n110 0\n", // 13 (a(b<+>c))' //
+ "11- 1\n1-1 1\n-11 1\n", // 14 5s ab+bc+ac //
+ "111 1\n000 1\n", // 15 6s abc+a'b'c' //
+ "111 0\n000 0\n", // 16 (abc+a'b'c')' //
+ "11- 1\n-11 1\n0-1 1\n", // 17 7 ab+bc+a'c //
+ "011 1\n101 1\n110 1\n", // 18 8s a'bc+ab'c+abc' //
+ "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' //
+ "100 1\n-11 1\n", // 20 9p ab'c'+bc //
+ "100 0\n-11 0\n" // 21 (ab'c'+bc)' //
+};
+
+// NP-classes of functions of 3 variables (22)
+static char * s_NP3Names[22] = {
+ " const 0 ",
+ " const 1 ",
+ " a ",
+ " ab ",
+ " (ab)' ",
+ " a<+>b ",
+ "0s abc ",
+ " (abc)' ",
+ "1p a(b+c) ",
+ " (a(b+c))' ",
+ "2s a<+>b<+>c ",
+ "3p a<+>bc ",
+ "4p a(b<+>c) ",
+ " (a(b<+>c))' ",
+ "5s ab+bc+ac ",
+ "6s abc+a'b'c' ",
+ " (abc+a'b'c')' ",
+ "7 ab+bc+a'c ",
+ "8s a'bc+ab'c+abc' ",
+ " (a'bc+ab'c+abc')' ",
+ "9p ab'c'+bc ",
+ " (ab'c'+bc)' "
+};
+
+// the number of variables in each function
+static int s_NP3VarNums[22] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+// NPN classes of functions of exactly 3 inputs (10)
+static int s_NPNe3[10] = { 6, 8, 10, 11, 12, 14, 15, 17, 18, 20 };
+
+// NPN classes of functions of exactly 3 inputs that are symmetric (5)
+static int s_NPNe3s[10] = { 6, 10, 14, 15, 18 };
+
+// NPN classes of functions of exactly 3 inputs (4)
+static int s_NPNe3p[10] = { 8, 11, 12, 20 };
+
+static Cut_CMan_t * Cut_CManStart();
+static void Cut_CManStop( Cut_CMan_t * p );
+static void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type );
+static void Cut_CellCanonicize( Cut_CMan_t * p, Cut_Cell_t * pCell );
+static int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell );
+static void Cut_CellSuppMin( Cut_Cell_t * pCell );
+static void Cut_CellCrossBar( Cut_Cell_t * pCell );
+
+
+static Cut_CMan_t * s_pCMan = NULL;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Start the precomputation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellLoad()
+{
+ FILE * pFile;
+ char * pFileName = "cells22_daomap_iwls.txt";
+ char pString[1000];
+ Cut_CMan_t * p;
+ Cut_Cell_t * pCell;
+ int Length; //, i;
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\".\n", pFileName );
+ return;
+ }
+ // start the manager
+ p = Cut_CManStart();
+ // load truth tables
+ while ( fgets(pString, 1000, pFile) )
+ {
+ Length = strlen(pString);
+ pString[Length--] = 0;
+ if ( Length == 0 )
+ continue;
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = Extra_Base2Log(Length*4);
+ pCell->nUsed = 1;
+// Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
+ Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars );
+ Cut_CellSuppMin( pCell );
+/*
+ // set the elementary permutation
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ pCell->CanonPerm[i] = i;
+ // canonicize
+ pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
+*/
+ // add to the table
+ p->nTotal++;
+
+// Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); printf( "\n" );
+// if ( p->nTotal == 500 )
+// break;
+
+ if ( !Cut_CellTableLookup( p, pCell ) ) // new cell
+ p->nGood++;
+ }
+ printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood );
+ fclose( pFile );
+// return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Precomputes truth tables for the 2x2 macro cell.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellPrecompute()
+{
+ Cut_CMan_t * p;
+ Cut_Cell_t * pCell, * pTemp;
+ int i1, i2, i3, i, j, k, c, clk = clock(), clk2 = clock();
+
+ p = Cut_CManStart();
+
+ // precompute truth tables
+ for ( i = 0; i < 22; i++ )
+ Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i );
+ for ( i = 0; i < 22; i++ )
+ Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i );
+ for ( i = 0; i < 22; i++ )
+ Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i );
+/*
+ if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) )
+ {
+ Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " );
+ for ( i = 0; i < pCell->nVars; i++ )
+ printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
+ Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars );
+ printf( "\n" );
+ }
+*/
+/*
+ // go through symmetric roots
+ for ( k = 0; k < 5; k++ )
+ for ( i1 = 0; i1 < 22; i1++ )
+ for ( i2 = i1; i2 < 22; i2++ )
+ for ( i3 = i2; i3 < 22; i3++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = 9;
+ pCell->Box[0] = s_NPNe3s[k];
+ pCell->Box[1] = i1;
+ pCell->Box[2] = i2;
+ pCell->Box[3] = i3;
+ // fill in the truth table
+ Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] );
+ // canonicize
+ Cut_CellCanonicize( pCell );
+
+ // add to the table
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ p->nGood++;
+ }
+
+ // go through partially symmetric roots
+ for ( k = 0; k < 4; k++ )
+ for ( i1 = 0; i1 < 22; i1++ )
+ for ( i2 = 0; i2 < 22; i2++ )
+ for ( i3 = i2; i3 < 22; i3++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = 9;
+ pCell->Box[0] = s_NPNe3p[k];
+ pCell->Box[1] = i1;
+ pCell->Box[2] = i2;
+ pCell->Box[3] = i3;
+ // fill in the truth table
+ Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] );
+ // canonicize
+ Cut_CellCanonicize( pCell );
+
+ // add to the table
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ p->nGood++;
+ }
+
+ // go through non-symmetric functions
+ for ( i1 = 0; i1 < 22; i1++ )
+ for ( i2 = 0; i2 < 22; i2++ )
+ for ( i3 = 0; i3 < 22; i3++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = 9;
+ pCell->Box[0] = 17;
+ pCell->Box[1] = i1;
+ pCell->Box[2] = i2;
+ pCell->Box[3] = i3;
+ // fill in the truth table
+ Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 );
+ // canonicize
+ Cut_CellCanonicize( pCell );
+
+ // add to the table
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ p->nGood++;
+ }
+*/
+
+ // go through non-symmetric functions
+ for ( k = 0; k < 10; k++ )
+ for ( i1 = 0; i1 < 22; i1++ )
+ for ( i2 = 0; i2 < 22; i2++ )
+ for ( i3 = 0; i3 < 22; i3++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = 9;
+ pCell->Box[0] = s_NPNe3[k];
+ pCell->Box[1] = i1;
+ pCell->Box[2] = i2;
+ pCell->Box[3] = i3;
+ // set the elementary permutation
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ pCell->CanonPerm[i] = i;
+ // fill in the truth table
+ Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] );
+ // minimize the support
+ Cut_CellSuppMin( pCell );
+
+ // canonicize
+ pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
+
+ // add to the table
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ {
+ p->nGood++;
+ p->nVarCounts[pCell->nVars]++;
+
+ if ( pCell->nVars )
+ for ( i = 0; i < (int)pCell->nVars-1; i++ )
+ {
+ if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
+ continue;
+ // i and i+1 can be symmetric
+ // find the end of this group
+ for ( j = i+1; j < (int)pCell->nVars; j++ )
+ if ( pCell->Store[2*i] != pCell->Store[2*j] )
+ break;
+
+ if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
+ p->nSymGroupsE[j-i]++;
+ else
+ p->nSymGroups[j-i]++;
+ i = j - 1;
+ }
+/*
+ if ( pCell->nVars == 3 )
+ {
+ Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
+ printf( "\n" );
+ }
+*/
+ }
+ }
+
+ printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
+ PRT( "Time", clock() - clk );
+ printf( "Cells: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nVarCounts[i] );
+ printf( "\nDiffs: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nSymGroups[i] );
+ printf( "\nEquals: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nSymGroupsE[i] );
+ printf( "\n" );
+
+ // continue adding new cells using support
+ for ( k = CUT_CELL_MVAR; k > 3; k-- )
+ {
+ for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
+ for ( i1 = 0; i1 < k; i1++ )
+ for ( i2 = i1+1; i2 < k; i2++ )
+ for ( c = 0; c < 3; c++ )
+ {
+ // derive the cell
+ pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = pTemp->nVars;
+ pCell->pParent = pTemp;
+ // set the elementary permutation
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ pCell->CanonPerm[i] = i;
+ // fill in the truth table
+ Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars );
+ // create the cross-bar
+ pCell->CrossBar0 = i1;
+ pCell->CrossBar1 = i2;
+ pCell->CrossBarPhase = c;
+ Cut_CellCrossBar( pCell );
+ // minimize the support
+//clk2 = clock();
+ Cut_CellSuppMin( pCell );
+//p->timeSupp += clock() - clk2;
+ // canonicize
+//clk2 = clock();
+ pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
+//p->timeCanon += clock() - clk2;
+
+ // add to the table
+//clk2 = clock();
+ p->nTotal++;
+ if ( Cut_CellTableLookup( p, pCell ) ) // already exists
+ Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
+ else
+ {
+ p->nGood++;
+ p->nVarCounts[pCell->nVars]++;
+
+ for ( i = 0; i < (int)pCell->nVars-1; i++ )
+ {
+ if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
+ continue;
+ // i and i+1 can be symmetric
+ // find the end of this group
+ for ( j = i+1; j < (int)pCell->nVars; j++ )
+ if ( pCell->Store[2*i] != pCell->Store[2*j] )
+ break;
+
+ if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
+ p->nSymGroupsE[j-i]++;
+ else
+ p->nSymGroups[j-i]++;
+ i = j - 1;
+ }
+/*
+ if ( pCell->nVars == 3 )
+ {
+ Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
+ printf( "\n" );
+ }
+*/
+ }
+//p->timeTable += clock() - clk2;
+ }
+
+ printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
+ PRT( "Time", clock() - clk );
+ printf( "Cells: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nVarCounts[i] );
+ printf( "\nDiffs: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nSymGroups[i] );
+ printf( "\nEquals: " );
+ for ( i = 0; i <= 9; i++ )
+ printf( "%d=%d ", i, p->nSymGroupsE[i] );
+ printf( "\n" );
+ }
+// printf( "\n" );
+ PRT( "Supp ", p->timeSupp );
+ PRT( "Canon", p->timeCanon );
+ PRT( "Table", p->timeTable );
+// Cut_CManStop( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Check the table.]
+
+ Description [Returns 1 if such a truth table already exists.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell )
+{
+ Cut_Cell_t ** pSlot, * pTemp;
+ unsigned Hash;
+ Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum( pCell->nVars ) );
+ if ( !st_find_or_add( p->tTable, (char *)Hash, (char ***)&pSlot ) )
+ *pSlot = NULL;
+ for ( pTemp = *pSlot; pTemp; pTemp = pTemp->pNext )
+ {
+ if ( pTemp->nVars != pCell->nVars )
+ continue;
+ if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
+ return 1;
+ }
+ // the entry is new
+ pCell->pNext = *pSlot;
+ *pSlot = pCell;
+ // add it to the variable support list
+ pCell->pNextVar = p->pSameVar[pCell->nVars];
+ p->pSameVar[pCell->nVars] = pCell;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellSuppMin( Cut_Cell_t * pCell )
+{
+ static unsigned uTemp[1<<(CUT_CELL_MVAR-5)];
+ unsigned * pIn, * pOut, * pTemp;
+ int i, k, Counter, Temp;
+
+ // go backward through the support variables and remove redundant
+ for ( k = pCell->nVars - 1; k >= 0; k-- )
+ if ( !Extra_TruthVarInSupport(pCell->uTruth, pCell->nVars, k) )
+ {
+ // shift all the variables above this one
+ Counter = 0;
+ pIn = pCell->uTruth; pOut = uTemp;
+ for ( i = k; i < (int)pCell->nVars - 1; i++ )
+ {
+ Extra_TruthSwapAdjacentVars( pOut, pIn, pCell->nVars, i );
+ pTemp = pIn; pIn = pOut; pOut = pTemp;
+ // swap the support vars
+ Temp = pCell->CanonPerm[i];
+ pCell->CanonPerm[i] = pCell->CanonPerm[i+1];
+ pCell->CanonPerm[i+1] = Temp;
+ Counter++;
+ }
+ // return the function back into its place
+ if ( Counter & 1 )
+ Extra_TruthCopy( pOut, pIn, pCell->nVars );
+ // remove one variable
+ pCell->nVars--;
+// Extra_PrintBinary( stdout, pCell->uTruth, (1<<pCell->nVars) ); printf( "\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellCrossBar( Cut_Cell_t * pCell )
+{
+ static unsigned uTemp0[1<<(CUT_CELL_MVAR-5)];
+ static unsigned uTemp1[1<<(CUT_CELL_MVAR-5)];
+ Extra_TruthCopy( uTemp0, pCell->uTruth, pCell->nVars );
+ Extra_TruthCopy( uTemp1, pCell->uTruth, pCell->nVars );
+ if ( pCell->CanonPhase == 0 )
+ {
+ Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
+ Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
+ }
+ else if ( pCell->CanonPhase == 1 )
+ {
+ Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
+ Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
+ }
+ else if ( pCell->CanonPhase == 2 )
+ {
+ Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar1 );
+ Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 );
+ }
+ else assert( 0 );
+ Extra_TruthCombine( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type )
+{
+ int nWords = Extra_TruthWordNum( nVars );
+ int i;
+
+ assert( Type < 22 );
+ switch ( Type )
+ {
+ // " 0\n", // 00 const 0
+ case 0:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = 0;
+ return;
+ // " 1\n", // 01 const 1
+ case 1:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = 0xFFFFFFFF;
+ return;
+ // "1 1\n", // 02 a
+ case 2:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i];
+ return;
+ // "11 1\n", // 03 ab
+ case 3:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] & InB[i];
+ return;
+ // "11 0\n", // 04 (ab)'
+ case 4:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~(InA[i] & InB[i]);
+ return;
+ // "10 1\n01 1\n", // 05 a<+>b
+ case 5:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] ^ InB[i];
+ return;
+ // "111 1\n", // 06 + abc
+ case 6:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] & InB[i] & InC[i];
+ return;
+ // "111 0\n", // 07 (abc)'
+ case 7:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~(InA[i] & InB[i] & InC[i]);
+ return;
+ // "11- 1\n1-1 1\n", // 08 + a(b+c)
+ case 8:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] & (InB[i] | InC[i]);
+ return;
+ // "11- 0\n1-1 0\n", // 09 (a(b+c))'
+ case 9:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~(InA[i] & (InB[i] | InC[i]));
+ return;
+ // "111 1\n100 1\n010 1\n001 1\n", // 10 + a<+>b<+>c
+ case 10:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] ^ InB[i] ^ InC[i];
+ return;
+ // "10- 0\n1-0 0\n011 0\n", // 11 + a<+>bc
+ case 11:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] ^ (InB[i] & InC[i]);
+ return;
+ // "101 1\n110 1\n", // 12 + a(b<+>c)
+ case 12:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = InA[i] & (InB[i] ^ InC[i]);
+ return;
+ // "101 0\n110 0\n", // 13 (a(b<+>c))'
+ case 13:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~(InA[i] & (InB[i] ^ InC[i]));
+ return;
+ // "11- 1\n1-1 1\n-11 1\n", // 14 + ab+bc+ac
+ case 14:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (InA[i] & InC[i]);
+ return;
+ // "111 1\n000 1\n", // 15 + abc+a'b'c'
+ case 15:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]);
+ return;
+ // "111 0\n000 0\n", // 16 (abc+a'b'c')'
+ case 16:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~((InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]));
+ return;
+ // "11- 1\n-11 1\n0-1 1\n", // 17 + ab+bc+a'c
+ case 17:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (~InA[i] & InC[i]);
+ return;
+ // "011 1\n101 1\n110 1\n", // 18 + a'bc+ab'c+abc'
+ case 18:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]);
+ return;
+ // "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')'
+ case 19:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~((~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]));
+ return;
+ // "100 1\n-11 1\n", // 20 + ab'c'+bc
+ case 20:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = (InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]);
+ return;
+ // "100 0\n-11 0\n" // 21 (ab'c'+bc)'
+ case 21:
+ for ( i = 0; i < nWords; i++ )
+ pOut[i] = ~((InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]));
+ return;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Start the precomputation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cut_CMan_t * Cut_CManStart()
+{
+ Cut_CMan_t * p;
+ int i, k;
+ // start the manager
+ assert( sizeof(unsigned) == 4 );
+ p = ALLOC( Cut_CMan_t, 1 );
+ memset( p, 0, sizeof(Cut_CMan_t) );
+ // start the table and the memory manager
+ p->tTable = st_init_table(st_ptrcmp,st_ptrhash);
+ p->pMem = Extra_MmFixedStart( sizeof(Cut_Cell_t) );
+ // set elementary truth tables
+ for ( k = 0; k < CUT_CELL_MVAR; k++ )
+ for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ )
+ if ( i & (1 << k) )
+ p->uInputs[k][i>>5] |= (1 << (i&31));
+ s_pCMan = p;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CManStop( Cut_CMan_t * p )
+{
+ st_free_table( p->tTable );
+ Extra_MmFixedStop( p->pMem, 0 );
+ free( p );
+}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cut_CellIsRunning()
+{
+ return s_pCMan != NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cut_CellDumpToFile()
+{
+ FILE * pFile;
+ Cut_CMan_t * p = s_pCMan;
+ Cut_Cell_t * pTemp;
+ char * pFileName = "celllib22.txt";
+ int NumUsed[10][5] = {{0}};
+ int BoxUsed[22][5] = {{0}};
+ int i, k, Counter;
+ int clk = clock();
+
+ if ( p == NULL )
+ {
+ printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" );
+ return;
+ }
+
+ // count the number of cells used
+ for ( k = CUT_CELL_MVAR; k >= 0; k-- )
+ {
+ for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
+ {
+ if ( pTemp->nUsed == 0 )
+ NumUsed[k][0]++;
+ else if ( pTemp->nUsed < 10 )
+ NumUsed[k][1]++;
+ else if ( pTemp->nUsed < 100 )
+ NumUsed[k][2]++;
+ else if ( pTemp->nUsed < 1000 )
+ NumUsed[k][3]++;
+ else
+ NumUsed[k][4]++;
+
+ for ( i = 0; i < 4; i++ )
+ if ( pTemp->nUsed == 0 )
+ BoxUsed[ pTemp->Box[i] ][0]++;
+ else if ( pTemp->nUsed < 10 )
+ BoxUsed[ pTemp->Box[i] ][1]++;
+ else if ( pTemp->nUsed < 100 )
+ BoxUsed[ pTemp->Box[i] ][2]++;
+ else if ( pTemp->nUsed < 1000 )
+ BoxUsed[ pTemp->Box[i] ][3]++;
+ else
+ BoxUsed[ pTemp->Box[i] ][4]++;
+ }
+ }
+
+ printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound );
+ for ( k = 0; k <= CUT_CELL_MVAR; k++ )
+ {
+ printf( "%3d : ", k );
+ for ( i = 0; i < 5; i++ )
+ printf( "%8d ", NumUsed[k][i] );
+ printf( "\n" );
+ }
+ printf( "Box usage:\n" );
+ for ( k = 0; k < 22; k++ )
+ {
+ printf( "%3d : ", k );
+ for ( i = 0; i < 5; i++ )
+ printf( "%8d ", BoxUsed[k][i] );
+ printf( " %s", s_NP3Names[k] );
+ printf( "\n" );
+ }
+
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ printf( "Cut_CellDumpToFile: Cannout open output file.\n" );
+ return;
+ }
+
+ Counter = 0;
+ for ( k = 0; k <= CUT_CELL_MVAR; k++ )
+ {
+ for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
+ if ( pTemp->nUsed > 0 )
+ {
+ Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) );
+ fprintf( pFile, "\n" );
+ Counter++;
+ }
+ fprintf( pFile, "\n" );
+ }
+ fclose( pFile );
+
+ printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName );
+
+ PRT( "Time", clock() - clk );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Looks up if the given function exists in the hash table.]
+
+ Description [If the function exists, returns 1, meaning that it can be
+ implemented using two levels of 3-input LUTs. If the function does not
+ exist, return 0.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cut_CellTruthLookup( unsigned * pTruth, int nVars )
+{
+ Cut_CMan_t * p = s_pCMan;
+ Cut_Cell_t * pTemp;
+ Cut_Cell_t Cell, * pCell = &Cell;
+ unsigned Hash;
+ int i;
+
+ // cell manager is not defined
+ if ( p == NULL )
+ {
+ printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" );
+ return 0;
+ }
+
+ // canonicize
+ memset( pCell, 0, sizeof(Cut_Cell_t) );
+ pCell->nVars = nVars;
+ Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
+ Cut_CellSuppMin( pCell );
+ // set the elementary permutation
+ for ( i = 0; i < (int)pCell->nVars; i++ )
+ pCell->CanonPerm[i] = i;
+ // canonicize
+ pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
+
+
+ // check if the cell exists
+ Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) );
+ if ( st_lookup( p->tTable, (char *)Hash, (char **)&pTemp ) )
+ {
+ for ( ; pTemp; pTemp = pTemp->pNext )
+ {
+ if ( pTemp->nVars != pCell->nVars )
+ continue;
+ if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
+ {
+ pTemp->nUsed++;
+ p->nCellFound++;
+ return 1;
+ }
+ }
+ }
+ p->nCellNotFound++;
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/cut/cutMan.c b/src/opt/cut/cutMan.c
index 0cd01bc9..22ea1cb6 100644
--- a/src/opt/cut/cutMan.c
+++ b/src/opt/cut/cutMan.c
@@ -45,6 +45,8 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams )
{
Cut_Man_t * p;
int clk = clock();
+// extern int nTruthDsd;
+// nTruthDsd = 0;
assert( pParams->nVarsMax >= 3 && pParams->nVarsMax <= CUT_SIZE_MAX );
p = ALLOC( Cut_Man_t, 1 );
memset( p, 0, sizeof(Cut_Man_t) );
@@ -114,6 +116,9 @@ void Cut_ManStop( Cut_Man_t * p )
{
Cut_Cut_t * pCut;
int i;
+// extern int nTruthDsd;
+// printf( "Decomposable cuts = %d.\n", nTruthDsd );
+
Vec_PtrForEachEntry( p->vCutsNew, pCut, i )
if ( pCut != NULL )
{
diff --git a/src/opt/cut/cutPre22.c b/src/opt/cut/cutPre22.c
index 693978d6..203f9e6f 100644
--- a/src/opt/cut/cutPre22.c
+++ b/src/opt/cut/cutPre22.c
@@ -779,7 +779,7 @@ Cut_CMan_t * Cut_CManStart()
for ( k = 0; k < CUT_CELL_MVAR; k++ )
for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ )
if ( i & (1 << k) )
- p->uInputs[k][i/32] |= (1 << (i%32));
+ p->uInputs[k][i>>5] |= (1 << (i&31));
s_pCMan = p;
return p;
}
diff --git a/src/opt/cut/cutTruth.c b/src/opt/cut/cutTruth.c
index 2e36c9e1..c3514ad7 100644
--- a/src/opt/cut/cutTruth.c
+++ b/src/opt/cut/cutTruth.c
@@ -189,6 +189,9 @@ void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_C
Extra_TruthNand( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax );
else
Extra_TruthAnd( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax );
+
+// Ivy_TruthTestOne( *Cut_CutReadTruth(pCut) );
+
// quit if no fancy computation is needed
if ( !p->pParams->fFancy )
return;
diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c
index af76cd84..1b23bb53 100644
--- a/src/opt/dec/decAbc.c
+++ b/src/opt/dec/decAbc.c
@@ -19,6 +19,7 @@
#include "abc.h"
#include "dec.h"
//#include "aig.h"
+#include "ivy.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -238,6 +239,41 @@ Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph )
}
*/
+/**Function*************************************************************
+
+ Synopsis [Transforms the decomposition graph into the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
+{
+ Dec_Node_t * pNode;
+ Ivy_Obj_t * pAnd0, * pAnd1;
+ int i;
+ // check for constant function
+ if ( Dec_GraphIsConst(pGraph) )
+ return Ivy_NotCond( Ivy_ManConst1(pMan), Dec_GraphIsComplement(pGraph) );
+ // check for a literal
+ if ( Dec_GraphIsVar(pGraph) )
+ return Ivy_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
+ // build the AIG nodes corresponding to the AND gates of the graph
+ Dec_GraphForEachNode( pGraph, pNode, i )
+ {
+ pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
+ pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
+ pNode->pFunc = Ivy_And( pAnd0, pAnd1 );
+ }
+ // complement the result if necessary
+ return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/dec/decFactor.c b/src/opt/dec/decFactor.c
index 210b69e5..dca422ea 100644
--- a/src/opt/dec/decFactor.c
+++ b/src/opt/dec/decFactor.c
@@ -258,16 +258,15 @@ Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover )
***********************************************************************/
Dec_Edge_t Dec_FactorTrivialCube( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube, Vec_Int_t * vEdgeLits )
{
-// Dec_Edge_t eNode;
+ Dec_Edge_t eNode;
int iBit, Value;
// create the factored form for each literal
Vec_IntClear( vEdgeLits );
Mvc_CubeForEachBit( pCover, pCube, iBit, Value )
if ( Value )
{
-// eNode = Dec_EdgeCreate( iBit/2, iBit%2 ); // CST
-// Vec_IntPush( vEdgeLits, Dec_EdgeToInt_(eNode) );
- Vec_IntPush( vEdgeLits, iBit );
+ eNode = Dec_EdgeCreate( iBit/2, iBit%2 ); // CST
+ Vec_IntPush( vEdgeLits, Dec_EdgeToInt_(eNode) );
}
// balance the factored forms
return Dec_FactorTrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeLits->pArray, vEdgeLits->nSize, 0 );
diff --git a/src/opt/fxu/fxu.h b/src/opt/fxu/fxu.h
index 6a1bb5e3..7025d019 100644
--- a/src/opt/fxu/fxu.h
+++ b/src/opt/fxu/fxu.h
@@ -37,9 +37,11 @@ extern "C" {
/// STRUCTURE DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
+#ifndef __cplusplus
#ifndef bool
#define bool int
#endif
+#endif
typedef struct FxuDataStruct Fxu_Data_t;
diff --git a/src/opt/rwr/rwr.h b/src/opt/rwr/rwr.h
index 8de225e8..f8c40a7c 100644
--- a/src/opt/rwr/rwr.h
+++ b/src/opt/rwr/rwr.h
@@ -135,6 +135,7 @@ extern void Rwr_ManStop( Rwr_Man_t * p );
extern void Rwr_ManPrintStats( Rwr_Man_t * p );
extern void Rwr_ManPrintStatsFile( Rwr_Man_t * p );
extern void * Rwr_ManReadDecs( Rwr_Man_t * p );
+extern Vec_Ptr_t * Rwr_ManReadLeaves( Rwr_Man_t * p );
extern int Rwr_ManReadCompl( Rwr_Man_t * p );
extern void Rwr_ManAddTimeCuts( Rwr_Man_t * p, int Time );
extern void Rwr_ManAddTimeUpdate( Rwr_Man_t * p, int Time );
diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c
index 55132a75..9ae9c18c 100644
--- a/src/opt/rwr/rwrEva.c
+++ b/src/opt/rwr/rwrEva.c
@@ -100,9 +100,16 @@ clk = clock();
p->nCutsGood++;
clk2 = clock();
+/*
+ printf( "Considering: (" );
+ Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
+ printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) );
+ printf( ")\n" );
+*/
// mark the fanin boundary
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
Abc_ObjRegular(pFanin)->vFanouts.nSize++;
+
// label MFFC with current ID
Abc_NtkIncrementTravId( pNode->pNtk );
nNodesSaved = Abc_NodeMffcLabel( pNode );
@@ -136,6 +143,8 @@ p->timeRes += clock() - clk;
if ( GainBest == -1 )
return -1;
+// printf( "%d", nNodesSaveCur - GainBest );
+
// copy the leaves
Vec_PtrForEachEntry( p->vFanins, pFanin, i )
Dec_GraphNode(p->pGraph, i)->pFunc = pFanin;
diff --git a/src/opt/rwr/rwrMan.c b/src/opt/rwr/rwrMan.c
index 115065f5..b6d58d99 100644
--- a/src/opt/rwr/rwrMan.c
+++ b/src/opt/rwr/rwrMan.c
@@ -163,7 +163,11 @@ void Rwr_ManPrintStats( Rwr_Man_t * p )
printf( "The scores are:\n" );
for ( i = 0; i < 222; i++ )
if ( p->nScores[i] > 0 )
- printf( "%3d = %8d canon = %5d\n", i, p->nScores[i], p->pMapInv[i] );
+ {
+ extern void Ivy_TruthDsdComputePrint( unsigned uTruth );
+ printf( "%3d = %8d canon = %5d ", i, p->nScores[i], p->pMapInv[i] );
+ Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[i] | ((unsigned)p->pMapInv[i] << 16) );
+ }
printf( "\n" );
}
@@ -218,6 +222,22 @@ void * Rwr_ManReadDecs( Rwr_Man_t * p )
SeeAlso []
***********************************************************************/
+Vec_Ptr_t * Rwr_ManReadLeaves( Rwr_Man_t * p )
+{
+ return p->vFanins;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the resynthesis manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Rwr_ManReadCompl( Rwr_Man_t * p )
{
return p->fCompl;
diff --git a/src/opt/rwr/rwrTemp.c b/src/opt/rwr/rwrTemp.c
new file mode 100644
index 00000000..3ffbd408
--- /dev/null
+++ b/src/opt/rwr/rwrTemp.c
@@ -0,0 +1,121 @@
+/**CFile****************************************************************
+
+ FileName [rwrCut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [DAG-aware AIG rewriting package.]
+
+ Synopsis [Cut computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: rwrCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "rwr.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int pTruths[13719];
+static int pFreqs[13719];
+static int pPerm[13719];
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Rwr_TempCompare( int * pNum1, int * pNum2 )
+{
+ int Freq1 = pFreqs[*pNum1];
+ int Freq2 = pFreqs[*pNum2];
+ if ( Freq1 < Freq2 )
+ return 1;
+ if ( Freq1 > Freq2 )
+ return -1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Rwr_Temp()
+{
+ char Buffer[32];
+ int nFuncs = 13719;
+ int nEntries = 100;
+ unsigned uTruth;
+ int i, k;
+ FILE * pFile;
+
+ pFile = fopen( "nnclass_stats5.txt", "r" );
+ for ( i = 0; i < 13719; i++ )
+ {
+ fscanf( pFile, "%s%d", Buffer, &pFreqs[i] );
+ Extra_ReadHexadecimal( &uTruth, Buffer+2, 5 );
+ pTruths[i] = uTruth;
+ }
+ fclose( pFile );
+
+ for ( i = 0; i < 13719; i++ )
+ pPerm[i] = i;
+
+ qsort( (void *)pPerm, 13719, sizeof(int),
+ (int (*)(const void *, const void *)) Rwr_TempCompare );
+
+
+ pFile = fopen( "5npn_100.blif", "w" );
+ fprintf( pFile, "# Most frequent NPN classes of 5 vars.\n" );
+ fprintf( pFile, ".model 5npn\n" );
+ fprintf( pFile, ".inputs a b c d e\n" );
+ fprintf( pFile, ".outputs" );
+ for ( i = 0; i < nEntries; i++ )
+ fprintf( pFile, " %02d", i );
+ fprintf( pFile, "\n" );
+
+ for ( i = 0; i < nEntries; i++ )
+ {
+ fprintf( pFile, ".names a b c d e %02d\n", i );
+ uTruth = pTruths[pPerm[i]];
+ for ( k = 0; k < 32; k++ )
+ if ( uTruth & (1 << k) )
+ {
+ Extra_PrintBinary( pFile, &k, 5 );
+ fprintf( pFile, " 1\n" );
+ }
+ }
+ fprintf( pFile, ".end\n" );
+ fclose( pFile );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/sim/sim.h b/src/opt/sim/sim.h
index 7f32fc34..7fcf5ae6 100644
--- a/src/opt/sim/sim.h
+++ b/src/opt/sim/sim.h
@@ -143,8 +143,8 @@ struct Sim_Pat_t_
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-#define SIM_NUM_WORDS(n) ((n)/32 + (((n)%32) > 0))
-#define SIM_LAST_BITS(n) ((((n)%32) > 0)? (n)%32 : 32)
+#define SIM_NUM_WORDS(n) (((n)>>5) + (((n)&31) > 0))
+#define SIM_LAST_BITS(n) ((((n)&31) > 0)? (n)&31 : 32)
#define SIM_MASK_FULL (0xFFFFFFFF)
#define SIM_MASK_BEG(n) (SIM_MASK_FULL >> (32-n))
diff --git a/src/opt/xyz/module.make b/src/opt/xyz/module.make
deleted file mode 100644
index ae7dab0f..00000000
--- a/src/opt/xyz/module.make
+++ /dev/null
@@ -1,8 +0,0 @@
-SRC += src/opt/xyz/xyzBuild.c \
- src/opt/xyz/xyzCore.c \
- src/opt/xyz/xyzMan.c \
- src/opt/xyz/xyzMinEsop.c \
- src/opt/xyz/xyzMinMan.c \
- src/opt/xyz/xyzMinSop.c \
- src/opt/xyz/xyzMinUtil.c \
- src/opt/xyz/xyzTest.c
diff --git a/src/opt/xyz/xyz.h b/src/opt/xyz/xyz.h
deleted file mode 100644
index 4fec2150..00000000
--- a/src/opt/xyz/xyz.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/**CFile****************************************************************
-
- FileName [xyz.h]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Cover manipulation package.]
-
- Synopsis [External declarations.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: xyz.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#ifndef __XYZ_H__
-#define __XYZ_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "abc.h"
-#include "xyzInt.h"
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-typedef struct Xyz_Man_t_ Xyz_Man_t;
-typedef struct Xyz_Obj_t_ Xyz_Obj_t;
-
-// storage for node information
-struct Xyz_Obj_t_
-{
- Min_Cube_t * pCover[3]; // pos/neg/esop
- Vec_Int_t * vSupp; // computed support (all nodes except CIs)
-};
-
-// storage for additional information
-struct Xyz_Man_t_
-{
- // general characteristics
- int nFaninMax; // the number of vars
- int nCubesMax; // the limit on the number of cubes in the intermediate covers
- int nWords; // the number of words
- Vec_Int_t * vFanCounts; // fanout counts
- Vec_Ptr_t * vObjStrs; // object structures
- void * pMemory; // memory for the internal data strctures
- Min_Man_t * pManMin; // the cub manager
- int fUseEsop; // enables ESOPs
- int fUseSop; // enables SOPs
- // arrays to map local variables
- Vec_Int_t * vComTo0; // mapping of common variables into first fanin
- Vec_Int_t * vComTo1; // mapping of common variables into second fanin
- Vec_Int_t * vPairs0; // the first var in each pair of common vars
- Vec_Int_t * vPairs1; // the second var in each pair of common vars
- Vec_Int_t * vTriv0; // trival support of the first node
- Vec_Int_t * vTriv1; // trival support of the second node
- // statistics
- int nSupps; // supports created
- int nSuppsMax; // the maximum number of supports
- int nBoundary; // the boundary size
- int nNodes; // the number of nodes processed
-};
-
-static inline Xyz_Obj_t * Abc_ObjGetStr( Abc_Obj_t * pObj ) { return Vec_PtrEntry(((Xyz_Man_t *)pObj->pNtk->pManCut)->vObjStrs, pObj->Id); }
-
-static inline void Abc_ObjSetSupp( Abc_Obj_t * pObj, Vec_Int_t * vVec ) { Abc_ObjGetStr(pObj)->vSupp = vVec; }
-static inline Vec_Int_t * Abc_ObjGetSupp( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->vSupp; }
-
-static inline void Abc_ObjSetCover2( Abc_Obj_t * pObj, Min_Cube_t * pCov ) { Abc_ObjGetStr(pObj)->pCover[2] = pCov; }
-static inline Min_Cube_t * Abc_ObjGetCover2( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->pCover[2]; }
-
-static inline void Abc_ObjSetCover( Abc_Obj_t * pObj, Min_Cube_t * pCov, int Pol ) { Abc_ObjGetStr(pObj)->pCover[Pol] = pCov; }
-static inline Min_Cube_t * Abc_ObjGetCover( Abc_Obj_t * pObj, int Pol ) { return Abc_ObjGetStr(pObj)->pCover[Pol]; }
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/*=== xyzBuild.c ==========================================================*/
-extern Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk );
-extern Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk );
-/*=== xyzCore.c ===========================================================*/
-extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose );
-/*=== xyzMan.c ============================================================*/
-extern Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax );
-extern void Xyz_ManFree( Xyz_Man_t * p );
-extern void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj );
-/*=== xyzTest.c ===========================================================*/
-extern Abc_Ntk_t * Abc_NtkXyzTestSop( Abc_Ntk_t * pNtk );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
-
diff --git a/src/opt/xyz/xyzBuild.c b/src/opt/xyz/xyzBuild.c
deleted file mode 100644
index e32721e7..00000000
--- a/src/opt/xyz/xyzBuild.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/**CFile****************************************************************
-
- FileName [xyzBuild.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Cover manipulation package.]
-
- Synopsis [Network construction procedures.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: xyzBuild.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "xyz.h"
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis [Derives the decomposed network.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Abc_Obj_t * Abc_NtkXyzDeriveCube( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp )
-{
- Vec_Int_t * vLits;
- Abc_Obj_t * pNodeNew, * pFanin;
- int i, iFanin, Lit;
- // create empty cube
- if ( pCube->nLits == 0 )
- return Abc_NodeCreateConst1(pNtkNew);
- // get the literals of this cube
- vLits = Vec_IntAlloc( 10 );
- Min_CubeGetLits( pCube, vLits );
- assert( pCube->nLits == (unsigned)vLits->nSize );
- // create special case when there is only one literal
- if ( pCube->nLits == 1 )
- {
- iFanin = Vec_IntEntry(vLits,0);
- pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
- Lit = Min_CubeGetVar(pCube, iFanin);
- assert( Lit == 1 || Lit == 2 );
- Vec_IntFree( vLits );
- if ( Lit == 1 )// negative
- return Abc_NodeCreateInv( pNtkNew, pFanin->pCopy );
- return pFanin->pCopy;
- }
- assert( pCube->nLits > 1 );
- // create the AND cube
- pNodeNew = Abc_NtkCreateNode( pNtkNew );
- for ( i = 0; i < vLits->nSize; i++ )
- {
- iFanin = Vec_IntEntry(vLits,i);
- pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
- Lit = Min_CubeGetVar(pCube, iFanin);
- assert( Lit == 1 || Lit == 2 );
- Vec_IntWriteEntry( vLits, i, Lit==1 );
- Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
- }
- pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray );
- Vec_IntFree( vLits );
- return pNodeNew;
-}
-
-/**Function*************************************************************
-
- Synopsis [Derives the decomposed network.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Abc_Obj_t * Abc_NtkXyzDeriveNode_rec( Xyz_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int Level )
-{
- Min_Cube_t * pCover, * pCube;
- Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin;
- Vec_Int_t * vSupp;
- int Entry, nCubes, i;
-
- if ( Abc_ObjIsCi(pObj) )
- return pObj->pCopy;
- assert( Abc_ObjIsNode(pObj) );
- // skip if already computed
- if ( pObj->pCopy )
- return pObj->pCopy;
-
- // get the support and the cover
- vSupp = Abc_ObjGetSupp( pObj );
- pCover = Abc_ObjGetCover2( pObj );
- assert( vSupp );
-/*
- if ( pCover && pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) > 0 )
- {
- printf( "%d\n ", pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) );
- Min_CoverWrite( stdout, pCover );
- }
-*/
-/*
- // print the support of this node
- printf( "{ " );
- Vec_IntForEachEntry( vSupp, Entry, i )
- printf( "%d ", Entry );
- printf( "} cubes = %d\n", Min_CoverCountCubes( pCover ) );
-*/
- // process the fanins
- Vec_IntForEachEntry( vSupp, Entry, i )
- {
- pFanin = Abc_NtkObj(pObj->pNtk, Entry);
- Abc_NtkXyzDeriveNode_rec( p, pNtkNew, pFanin, Level+1 );
- }
-
- // for each cube, construct the node
- nCubes = Min_CoverCountCubes( pCover );
- if ( nCubes == 0 )
- pNodeNew = Abc_NodeCreateConst0(pNtkNew);
- else if ( nCubes == 1 )
- pNodeNew = Abc_NtkXyzDeriveCube( pNtkNew, pObj, pCover, vSupp );
- else
- {
- pNodeNew = Abc_NtkCreateNode( pNtkNew );
- Min_CoverForEachCube( pCover, pCube )
- {
- pFaninNew = Abc_NtkXyzDeriveCube( pNtkNew, pObj, pCube, vSupp );
- Abc_ObjAddFanin( pNodeNew, pFaninNew );
- }
- pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes );
- }
-/*
- printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level );
- Vec_IntForEachEntry( vSupp, Entry, i )
- {
- pFanin = Abc_NtkObj(pObj->pNtk, Entry);
- printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id );
- }
- printf( "\n" );
- Min_CoverWrite( stdout, pCover );
-*/
- pObj->pCopy = pNodeNew;
- return pNodeNew;
-}
-
-/**Function*************************************************************
-
- Synopsis [Derives the decomposed network.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk )
-{
- Abc_Ntk_t * pNtkNew;
- Abc_Obj_t * pObj;
- int i;
- assert( Abc_NtkIsStrash(pNtk) );
- // perform strashing
- pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
- // reconstruct the network
- Abc_NtkForEachCo( pNtk, pObj, i )
- {
- Abc_NtkXyzDeriveNode_rec( p, pNtkNew, Abc_ObjFanin0(pObj), 0 );
-// printf( "*** CO %s : %d -> %d \n", Abc_ObjName(pObj), pObj->pCopy->Id, Abc_ObjFanin0(pObj)->pCopy->Id );
- }
- // add the COs
- Abc_NtkFinalize( pNtk, pNtkNew );
- Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
- // make sure everything is okay
- if ( !Abc_NtkCheck( pNtkNew ) )
- {
- printf( "Abc_NtkXyzDerive: The network check has failed.\n" );
- Abc_NtkDelete( pNtkNew );
- return NULL;
- }
- return pNtkNew;
-}
-
-
-
-
-/**Function*************************************************************
-
- Synopsis [Derives the decomposed network.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Abc_Obj_t * Abc_NtkXyzDeriveInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl )
-{
- assert( pObj->pCopy );
- if ( !fCompl )
- return pObj->pCopy;
- if ( pObj->pCopy->pCopy == NULL )
- pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
- return pObj->pCopy->pCopy;
- }
-
-/**Function*************************************************************
-
- Synopsis [Derives the decomposed network.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Abc_Obj_t * Abc_NtkXyzDeriveCubeInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp )
-{
- Vec_Int_t * vLits;
- Abc_Obj_t * pNodeNew, * pFanin;
- int i, iFanin, Lit;
- // create empty cube
- if ( pCube->nLits == 0 )
- return Abc_NodeCreateConst1(pNtkNew);
- // get the literals of this cube
- vLits = Vec_IntAlloc( 10 );
- Min_CubeGetLits( pCube, vLits );
- assert( pCube->nLits == (unsigned)vLits->nSize );
- // create special case when there is only one literal
- if ( pCube->nLits == 1 )
- {
- iFanin = Vec_IntEntry(vLits,0);
- pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
- Lit = Min_CubeGetVar(pCube, iFanin);
- assert( Lit == 1 || Lit == 2 );
- Vec_IntFree( vLits );
-// if ( Lit == 1 )// negative
-// return Abc_NodeCreateInv( pNtkNew, pFanin->pCopy );
-// return pFanin->pCopy;
- return Abc_NtkXyzDeriveInv( pNtkNew, pFanin, Lit==1 );
- }
- assert( pCube->nLits > 1 );
- // create the AND cube
- pNodeNew = Abc_NtkCreateNode( pNtkNew );
- for ( i = 0; i < vLits->nSize; i++ )
- {
- iFanin = Vec_IntEntry(vLits,i);
- pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
- Lit = Min_CubeGetVar(pCube, iFanin);
- assert( Lit == 1 || Lit == 2 );
- Vec_IntWriteEntry( vLits, i, Lit==1 );
-// Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
- Abc_ObjAddFanin( pNodeNew, Abc_NtkXyzDeriveInv( pNtkNew, pFanin, Lit==1 ) );
- }
-// pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray );
- pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, NULL );
- Vec_IntFree( vLits );
- return pNodeNew;
-}
-
-/**Function*************************************************************
-
- Synopsis [Derives the decomposed network.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Abc_Obj_t * Abc_NtkXyzDeriveNodeInv_rec( Xyz_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl )
-{
- Min_Cube_t * pCover, * pCube;
- Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin;
- Vec_Int_t * vSupp;
- int Entry, nCubes, i;
-
- // skip if already computed
- if ( pObj->pCopy )
- return Abc_NtkXyzDeriveInv( pNtkNew, pObj, fCompl );
- assert( Abc_ObjIsNode(pObj) );
-
- // get the support and the cover
- vSupp = Abc_ObjGetSupp( pObj );
- pCover = Abc_ObjGetCover2( pObj );
- assert( vSupp );
-
- // process the fanins
- Vec_IntForEachEntry( vSupp, Entry, i )
- {
- pFanin = Abc_NtkObj(pObj->pNtk, Entry);
- Abc_NtkXyzDeriveNodeInv_rec( p, pNtkNew, pFanin, 0 );
- }
-
- // for each cube, construct the node
- nCubes = Min_CoverCountCubes( pCover );
- if ( nCubes == 0 )
- pNodeNew = Abc_NodeCreateConst0(pNtkNew);
- else if ( nCubes == 1 )
- pNodeNew = Abc_NtkXyzDeriveCubeInv( pNtkNew, pObj, pCover, vSupp );
- else
- {
- pNodeNew = Abc_NtkCreateNode( pNtkNew );
- Min_CoverForEachCube( pCover, pCube )
- {
- pFaninNew = Abc_NtkXyzDeriveCubeInv( pNtkNew, pObj, pCube, vSupp );
- Abc_ObjAddFanin( pNodeNew, pFaninNew );
- }
- pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes );
- }
-
- pObj->pCopy = pNodeNew;
- return Abc_NtkXyzDeriveInv( pNtkNew, pObj, fCompl );
-}
-
-/**Function*************************************************************
-
- Synopsis [Derives the decomposed network.]
-
- Description [The resulting network contains only pure AND/OR/EXOR gates
- and inverters. This procedure is usedful to generate Verilog.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk )
-{
- Abc_Ntk_t * pNtkNew;
- Abc_Obj_t * pObj, * pNodeNew;
- int i;
- assert( Abc_NtkIsStrash(pNtk) );
- // perform strashing
- pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
- // reconstruct the network
- Abc_NtkForEachCo( pNtk, pObj, i )
- {
- pNodeNew = Abc_NtkXyzDeriveNodeInv_rec( p, pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) );
- Abc_ObjAddFanin( pObj->pCopy, pNodeNew );
- }
- // add the COs
- Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
- // make sure everything is okay
- if ( !Abc_NtkCheck( pNtkNew ) )
- {
- printf( "Abc_NtkXyzDeriveInv: The network check has failed.\n" );
- Abc_NtkDelete( pNtkNew );
- return NULL;
- }
- return pNtkNew;
-}
-
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
diff --git a/src/opt/xyz/xyzCore.c b/src/opt/xyz/xyzCore.c
deleted file mode 100644
index e5089788..00000000
--- a/src/opt/xyz/xyzCore.c
+++ /dev/null
@@ -1,1025 +0,0 @@
-/**CFile****************************************************************
-
- FileName [xyzCore.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Cover manipulation package.]
-
- Synopsis [Core procedures.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: xyzCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "xyz.h"
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-static void Abc_NtkXyzCovers( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose );
-static int Abc_NtkXyzCoversOne( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose );
-static void Abc_NtkXyzCovers_rec( Xyz_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary );
-/*
-static int Abc_NodeXyzPropagateEsop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 );
-static int Abc_NodeXyzPropagateSop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 );
-static int Abc_NodeXyzUnionEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp );
-static int Abc_NodeXyzUnionSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp );
-static int Abc_NodeXyzProductEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp );
-static int Abc_NodeXyzProductSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp );
-*/
-
-static int Abc_NodeXyzPropagate( Xyz_Man_t * p, Abc_Obj_t * pObj );
-static Min_Cube_t * Abc_NodeXyzProduct( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp );
-static Min_Cube_t * Abc_NodeXyzSum( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp );
-
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis [Performs decomposition.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose )
-{
- Abc_Ntk_t * pNtkNew;
- Xyz_Man_t * p;
-
- assert( Abc_NtkIsStrash(pNtk) );
-
- // create the manager
- p = Xyz_ManAlloc( pNtk, nFaninMax );
- p->fUseEsop = fUseEsop;
- p->fUseSop = 1;//fUseSop;
- pNtk->pManCut = p;
-
- // perform mapping
- Abc_NtkXyzCovers( p, pNtk, fVerbose );
-
- // derive the final network
- if ( fUseInvs )
- pNtkNew = Abc_NtkXyzDeriveClean( p, pNtk );
- else
- pNtkNew = Abc_NtkXyzDerive( p, pNtk );
-// pNtkNew = NULL;
-
-
- Xyz_ManFree( p );
- pNtk->pManCut = NULL;
-
- // make sure that everything is okay
- if ( pNtkNew && !Abc_NtkCheck( pNtkNew ) )
- {
- printf( "Abc_NtkXyz: The network check has failed.\n" );
- Abc_NtkDelete( pNtkNew );
- return NULL;
- }
- return pNtkNew;
-}
-
-/**Function*************************************************************
-
- Synopsis [Compute the supports.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NtkXyzCovers( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose )
-{
- Abc_Obj_t * pObj;
- int i, clk = clock();
-
- // start the manager
- p->vFanCounts = Abc_NtkFanoutCounts(pNtk);
-
- // set trivial cuts for the constant and the CIs
- pObj = Abc_NtkConst1(pNtk);
- pObj->fMarkA = 1;
- Abc_NtkForEachCi( pNtk, pObj, i )
- pObj->fMarkA = 1;
-
- // perform iterative decomposition
- for ( i = 0; ; i++ )
- {
- if ( fVerbose )
- printf( "Iter %d : ", i+1 );
- if ( Abc_NtkXyzCoversOne(p, pNtk, fVerbose) )
- break;
- }
-
- // clean the cut-point markers
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->fMarkA = 0;
-
-if ( fVerbose )
-{
-PRT( "Total", clock() - clk );
-}
-}
-
-/**Function*************************************************************
-
- Synopsis [Compute the supports.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NtkXyzCoversOne( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose )
-{
- ProgressBar * pProgress;
- Abc_Obj_t * pObj;
- Vec_Ptr_t * vBoundary;
- int i, clk = clock();
- int Counter = 0;
- int fStop = 1;
-
- // array to collect the nodes in the new boundary
- vBoundary = Vec_PtrAlloc( 100 );
-
- // start from the COs and mark visited nodes using pObj->fMarkB
- pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
- Abc_NtkForEachCo( pNtk, pObj, i )
- {
- Extra_ProgressBarUpdate( pProgress, i, NULL );
- // skip the solved nodes (including the CIs)
- pObj = Abc_ObjFanin0(pObj);
- if ( pObj->fMarkA )
- {
- Counter++;
- continue;
- }
-
- // traverse the cone starting from this node
- if ( Abc_ObjGetSupp(pObj) == NULL )
- Abc_NtkXyzCovers_rec( p, pObj, vBoundary );
-
- // count the number of solved cones
- if ( Abc_ObjGetSupp(pObj) == NULL )
- fStop = 0;
- else
- Counter++;
-
-/*
- printf( "%-15s : ", Abc_ObjName(pObj) );
- printf( "lev = %5d ", pObj->Level );
- if ( Abc_ObjGetSupp(pObj) == NULL )
- {
- printf( "\n" );
- continue;
- }
- printf( "supp = %3d ", Abc_ObjGetSupp(pObj)->nSize );
- printf( "esop = %3d ", Min_CoverCountCubes( Abc_ObjGetCover2(pObj) ) );
- printf( "\n" );
-*/
- }
- Extra_ProgressBarStop( pProgress );
-
- // clean visited nodes
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->fMarkB = 0;
-
- // create the new boundary
- p->nBoundary = 0;
- Vec_PtrForEachEntry( vBoundary, pObj, i )
- {
- if ( !pObj->fMarkA )
- {
- pObj->fMarkA = 1;
- p->nBoundary++;
- }
- }
- Vec_PtrFree( vBoundary );
-
-if ( fVerbose )
-{
- printf( "Outs = %4d (%4d) Node = %6d (%6d) Max = %6d Bound = %4d ",
- Counter, Abc_NtkCoNum(pNtk), p->nSupps, Abc_NtkNodeNum(pNtk), p->nSuppsMax, p->nBoundary );
-PRT( "T", clock() - clk );
-}
- return fStop;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NtkXyzCovers_rec( Xyz_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary )
-{
- Abc_Obj_t * pObj0, * pObj1;
- // return if the support is already computed
- if ( pObj->fMarkB || pObj->fMarkA )//|| Abc_ObjGetSupp(pObj) ) // why do we need Supp check here???
- return;
- // mark as visited
- pObj->fMarkB = 1;
- // get the fanins
- pObj0 = Abc_ObjFanin0(pObj);
- pObj1 = Abc_ObjFanin1(pObj);
- // solve for the fanins
- Abc_NtkXyzCovers_rec( p, pObj0, vBoundary );
- Abc_NtkXyzCovers_rec( p, pObj1, vBoundary );
- // skip the node that spaced out
- if ( !pObj0->fMarkA && !Abc_ObjGetSupp(pObj0) || // fanin is not ready
- !pObj1->fMarkA && !Abc_ObjGetSupp(pObj1) || // fanin is not ready
- !Abc_NodeXyzPropagate( p, pObj ) ) // node's support or covers cannot be computed
- {
- // save the nodes of the future boundary
- if ( !pObj0->fMarkA && Abc_ObjGetSupp(pObj0) )
- Vec_PtrPush( vBoundary, pObj0 );
- if ( !pObj1->fMarkA && Abc_ObjGetSupp(pObj1) )
- Vec_PtrPush( vBoundary, pObj1 );
- return;
- }
- // consider dropping the fanin supports
-// Abc_NodeXyzDropData( p, pObj0 );
-// Abc_NodeXyzDropData( p, pObj1 );
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Int_t * Abc_NodeXyzSupport( Xyz_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1 )
-{
- Vec_Int_t * vSupp;
- int k0, k1;
-
- assert( vSupp0 && vSupp1 );
- Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 );
- Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 );
- Vec_IntClear( p->vPairs0 );
- Vec_IntClear( p->vPairs1 );
-
- vSupp = Vec_IntAlloc( vSupp0->nSize + vSupp1->nSize );
- for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; )
- {
- if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] )
- {
- Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
- Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
- Vec_IntPush( p->vPairs0, k0 );
- Vec_IntPush( p->vPairs1, k1 );
- Vec_IntPush( vSupp, vSupp0->pArray[k0] );
- k0++; k1++;
- }
- else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] )
- {
- Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
- Vec_IntPush( vSupp, vSupp0->pArray[k0] );
- k0++;
- }
- else
- {
- Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
- Vec_IntPush( vSupp, vSupp1->pArray[k1] );
- k1++;
- }
- }
- for ( ; k0 < vSupp0->nSize; k0++ )
- {
- Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
- Vec_IntPush( vSupp, vSupp0->pArray[k0] );
- }
- for ( ; k1 < vSupp1->nSize; k1++ )
- {
- Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
- Vec_IntPush( vSupp, vSupp1->pArray[k1] );
- }
-/*
- printf( "Zero : " );
- for ( k0 = 0; k0 < vSupp0->nSize; k0++ )
- printf( "%d ", vSupp0->pArray[k0] );
- printf( "\n" );
-
- printf( "One : " );
- for ( k1 = 0; k1 < vSupp1->nSize; k1++ )
- printf( "%d ", vSupp1->pArray[k1] );
- printf( "\n" );
-
- printf( "Sum : " );
- for ( k0 = 0; k0 < vSupp->nSize; k0++ )
- printf( "%d ", vSupp->pArray[k0] );
- printf( "\n" );
- printf( "\n" );
-*/
- return vSupp;
-}
-
-/**Function*************************************************************
-
- Synopsis [Propagates all types of covers.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeXyzPropagate( Xyz_Man_t * p, Abc_Obj_t * pObj )
-{
- Min_Cube_t * pCoverP = NULL, * pCoverN = NULL, * pCoverX = NULL;
- Min_Cube_t * pCov0, * pCov1, * pCover0, * pCover1;
- Vec_Int_t * vSupp, * vSupp0, * vSupp1;
- Abc_Obj_t * pObj0, * pObj1;
- int fCompl0, fCompl1;
-
- pObj0 = Abc_ObjFanin0( pObj );
- pObj1 = Abc_ObjFanin1( pObj );
-
- if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id );
- if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id );
-
- // get the resulting support
- vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0);
- vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1);
- vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 );
-
- // quit if support if too large
- if ( vSupp->nSize > p->nFaninMax )
- {
- Vec_IntFree( vSupp );
- return 0;
- }
-
- // get the complemented attributes
- fCompl0 = Abc_ObjFaninC0( pObj );
- fCompl1 = Abc_ObjFaninC1( pObj );
-
- // propagate ESOP
- if ( p->fUseEsop )
- {
- // get the covers
- pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0);
- pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1);
- if ( pCov0 && pCov1 )
- {
- // complement the first if needed
- if ( !fCompl0 )
- pCover0 = pCov0;
- else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube
- pCover0 = pCov0->pNext;
- else
- pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0;
-
- // complement the second if needed
- if ( !fCompl1 )
- pCover1 = pCov1;
- else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube
- pCover1 = pCov1->pNext;
- else
- pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1;
-
- // derive the new cover
- pCoverX = Abc_NodeXyzProduct( p, pCover0, pCover1, 1, vSupp->nSize );
- }
- }
- // propagate SOPs
- if ( p->fUseSop )
- {
- // get the covers for the direct polarity
- pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0);
- pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1);
- // derive the new cover
- if ( pCover0 && pCover1 )
- pCoverP = Abc_NodeXyzProduct( p, pCover0, pCover1, 0, vSupp->nSize );
-
- // get the covers for the inverse polarity
- pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0);
- pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1);
- // derive the new cover
- if ( pCover0 && pCover1 )
- pCoverN = Abc_NodeXyzSum( p, pCover0, pCover1, 0, vSupp->nSize );
- }
-
- // if none of the covers can be computed quit
- if ( !pCoverX && !pCoverP && !pCoverN )
- {
- Vec_IntFree( vSupp );
- return 0;
- }
-
- // set the covers
- assert( Abc_ObjGetSupp(pObj) == NULL );
- Abc_ObjSetSupp( pObj, vSupp );
- Abc_ObjSetCover( pObj, pCoverP, 0 );
- Abc_ObjSetCover( pObj, pCoverN, 1 );
- Abc_ObjSetCover2( pObj, pCoverX );
-//printf( "%3d : %4d %4d %4d\n", pObj->Id, Min_CoverCountCubes(pCoverP), Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverX) );
-
- // count statistics
- p->nSupps++;
- p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps );
- return 1;
-}
-
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Min_Cube_t * Abc_NodeXyzProduct( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp )
-{
- Min_Cube_t * pCube, * pCube0, * pCube1;
- Min_Cube_t * pCover;
- int i, Val0, Val1;
- assert( pCover0 && pCover1 );
-
- // clean storage
- Min_ManClean( p->pManMin, nSupp );
- // go through the cube pairs
- Min_CoverForEachCube( pCover0, pCube0 )
- Min_CoverForEachCube( pCover1, pCube1 )
- {
- // go through the support variables of the cubes
- for ( i = 0; i < p->vPairs0->nSize; i++ )
- {
- Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] );
- Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] );
- if ( (Val0 & Val1) == 0 )
- break;
- }
- // check disjointness
- if ( i < p->vPairs0->nSize )
- continue;
-
- if ( p->pManMin->nCubes > p->nCubesMax )
- {
- pCover = Min_CoverCollect( p->pManMin, nSupp );
-//Min_CoverWriteFile( pCover, "large", 1 );
- Min_CoverRecycle( p->pManMin, pCover );
- return NULL;
- }
-
- // create the product cube
- pCube = Min_CubeAlloc( p->pManMin );
-
- // add the literals
- pCube->nLits = 0;
- for ( i = 0; i < nSupp; i++ )
- {
- if ( p->vComTo0->pArray[i] == -1 )
- Val0 = 3;
- else
- Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] );
-
- if ( p->vComTo1->pArray[i] == -1 )
- Val1 = 3;
- else
- Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] );
-
- if ( (Val0 & Val1) == 3 )
- continue;
-
- Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 );
- pCube->nLits++;
- }
- // add the cube to storage
- if ( fEsop )
- Min_EsopAddCube( p->pManMin, pCube );
- else
- Min_SopAddCube( p->pManMin, pCube );
- }
-
- // minimize the cover
- if ( fEsop )
- Min_EsopMinimize( p->pManMin );
- else
- Min_SopMinimize( p->pManMin );
- pCover = Min_CoverCollect( p->pManMin, nSupp );
-
- // quit if the cover is too large
- if ( Min_CoverCountCubes(pCover) > p->nFaninMax )
- {
-/*
-Min_CoverWriteFile( pCover, "large", 1 );
- Min_CoverExpand( p->pManMin, pCover );
- Min_EsopMinimize( p->pManMin );
- Min_EsopMinimize( p->pManMin );
- Min_EsopMinimize( p->pManMin );
- Min_EsopMinimize( p->pManMin );
- Min_EsopMinimize( p->pManMin );
- Min_EsopMinimize( p->pManMin );
- Min_EsopMinimize( p->pManMin );
- Min_EsopMinimize( p->pManMin );
- Min_EsopMinimize( p->pManMin );
- pCover = Min_CoverCollect( p->pManMin, nSupp );
-*/
- Min_CoverRecycle( p->pManMin, pCover );
- return NULL;
- }
- return pCover;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Min_Cube_t * Abc_NodeXyzSum( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp )
-{
- Min_Cube_t * pCube, * pCube0, * pCube1;
- Min_Cube_t * pCover;
- int i, Val0, Val1;
- assert( pCover0 && pCover1 );
-
- // clean storage
- Min_ManClean( p->pManMin, nSupp );
- Min_CoverForEachCube( pCover0, pCube0 )
- {
- // create the cube
- pCube = Min_CubeAlloc( p->pManMin );
- pCube->nLits = 0;
- for ( i = 0; i < p->vComTo0->nSize; i++ )
- {
- if ( p->vComTo0->pArray[i] == -1 )
- continue;
- Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] );
- if ( Val0 == 3 )
- continue;
- Min_CubeXorVar( pCube, i, Val0 ^ 3 );
- pCube->nLits++;
- }
- if ( p->pManMin->nCubes > p->nCubesMax )
- {
- pCover = Min_CoverCollect( p->pManMin, nSupp );
- Min_CoverRecycle( p->pManMin, pCover );
- return NULL;
- }
- // add the cube to storage
- if ( fEsop )
- Min_EsopAddCube( p->pManMin, pCube );
- else
- Min_SopAddCube( p->pManMin, pCube );
- }
- Min_CoverForEachCube( pCover1, pCube1 )
- {
- // create the cube
- pCube = Min_CubeAlloc( p->pManMin );
- pCube->nLits = 0;
- for ( i = 0; i < p->vComTo1->nSize; i++ )
- {
- if ( p->vComTo1->pArray[i] == -1 )
- continue;
- Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] );
- if ( Val1 == 3 )
- continue;
- Min_CubeXorVar( pCube, i, Val1 ^ 3 );
- pCube->nLits++;
- }
- if ( p->pManMin->nCubes > p->nCubesMax )
- {
- pCover = Min_CoverCollect( p->pManMin, nSupp );
- Min_CoverRecycle( p->pManMin, pCover );
- return NULL;
- }
- // add the cube to storage
- if ( fEsop )
- Min_EsopAddCube( p->pManMin, pCube );
- else
- Min_SopAddCube( p->pManMin, pCube );
- }
-
- // minimize the cover
- if ( fEsop )
- Min_EsopMinimize( p->pManMin );
- else
- Min_SopMinimize( p->pManMin );
- pCover = Min_CoverCollect( p->pManMin, nSupp );
-
- // quit if the cover is too large
- if ( Min_CoverCountCubes(pCover) > p->nFaninMax )
- {
- Min_CoverRecycle( p->pManMin, pCover );
- return NULL;
- }
- return pCover;
-}
-
-
-
-
-
-
-
-#if 0
-
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeXyzPropagateEsop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 )
-{
- Min_Cube_t * pCover, * pCover0, * pCover1, * pCov0, * pCov1;
- Vec_Int_t * vSupp, * vSupp0, * vSupp1;
-
- if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id );
- if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id );
-
- // get the resulting support
- vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0);
- vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1);
- vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 );
-
- // quit if support if too large
- if ( vSupp->nSize > p->nFaninMax )
- {
- Vec_IntFree( vSupp );
- return 0;
- }
-
- // get the covers
- pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0);
- pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1);
-
- // complement the first if needed
- if ( !Abc_ObjFaninC0(pObj) )
- pCover0 = pCov0;
- else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube
- pCover0 = pCov0->pNext;
- else
- pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0;
-
- // complement the second if needed
- if ( !Abc_ObjFaninC1(pObj) )
- pCover1 = pCov1;
- else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube
- pCover1 = pCov1->pNext;
- else
- pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1;
-
- // derive and minimize the cover (quit if too large)
- if ( !Abc_NodeXyzProductEsop( p, pCover0, pCover1, vSupp->nSize ) )
- {
- pCover = Min_CoverCollect( p->pManMin, vSupp->nSize );
- Min_CoverRecycle( p->pManMin, pCover );
- Vec_IntFree( vSupp );
- return 0;
- }
-
- // minimize the cover
- Min_EsopMinimize( p->pManMin );
- pCover = Min_CoverCollect( p->pManMin, vSupp->nSize );
-
- // quit if the cover is too large
- if ( Min_CoverCountCubes(pCover) > p->nFaninMax )
- {
- Min_CoverRecycle( p->pManMin, pCover );
- Vec_IntFree( vSupp );
- return 0;
- }
-
- // count statistics
- p->nSupps++;
- p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps );
-
- // set the covers
- assert( Abc_ObjGetSupp(pObj) == NULL );
- Abc_ObjSetSupp( pObj, vSupp );
- Abc_ObjSetCover2( pObj, pCover );
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeXyzPropagateSop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 )
-{
- Min_Cube_t * pCoverP, * pCoverN, * pCover0, * pCover1;
- Vec_Int_t * vSupp, * vSupp0, * vSupp1;
- int fCompl0, fCompl1;
-
- if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id );
- if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id );
-
- // get the resulting support
- vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0);
- vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1);
- vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 );
-
- // quit if support if too large
- if ( vSupp->nSize > p->nFaninMax )
- {
- Vec_IntFree( vSupp );
- return 0;
- }
-
- // get the complemented attributes
- fCompl0 = Abc_ObjFaninC0(pObj);
- fCompl1 = Abc_ObjFaninC1(pObj);
-
- // prepare the positive cover
- pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0);
- pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1);
-
- // derive and minimize the cover (quit if too large)
- if ( !pCover0 || !pCover1 )
- pCoverP = NULL;
- else if ( !Abc_NodeXyzProductSop( p, pCover0, pCover1, vSupp->nSize ) )
- {
- pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize );
- Min_CoverRecycle( p->pManMin, pCoverP );
- pCoverP = NULL;
- }
- else
- {
- Min_SopMinimize( p->pManMin );
- pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize );
- // quit if the cover is too large
- if ( Min_CoverCountCubes(pCoverP) > p->nFaninMax )
- {
- Min_CoverRecycle( p->pManMin, pCoverP );
- pCoverP = NULL;
- }
- }
-
- // prepare the negative cover
- pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0);
- pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1);
-
- // derive and minimize the cover (quit if too large)
- if ( !pCover0 || !pCover1 )
- pCoverN = NULL;
- else if ( !Abc_NodeXyzUnionSop( p, pCover0, pCover1, vSupp->nSize ) )
- {
- pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize );
- Min_CoverRecycle( p->pManMin, pCoverN );
- pCoverN = NULL;
- }
- else
- {
- Min_SopMinimize( p->pManMin );
- pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize );
- // quit if the cover is too large
- if ( Min_CoverCountCubes(pCoverN) > p->nFaninMax )
- {
- Min_CoverRecycle( p->pManMin, pCoverN );
- pCoverN = NULL;
- }
- }
-
- if ( pCoverP == NULL && pCoverN == NULL )
- {
- Vec_IntFree( vSupp );
- return 0;
- }
-
- // count statistics
- p->nSupps++;
- p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps );
-
- // set the covers
- assert( Abc_ObjGetSupp(pObj) == NULL );
- Abc_ObjSetSupp( pObj, vSupp );
- Abc_ObjSetCover( pObj, pCoverP, 0 );
- Abc_ObjSetCover( pObj, pCoverN, 1 );
- return 1;
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeXyzProductEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp )
-{
- Min_Cube_t * pCube, * pCube0, * pCube1;
- int i, Val0, Val1;
-
- // clean storage
- Min_ManClean( p->pManMin, nSupp );
- if ( pCover0 == NULL || pCover1 == NULL )
- return 1;
-
- // go through the cube pairs
- Min_CoverForEachCube( pCover0, pCube0 )
- Min_CoverForEachCube( pCover1, pCube1 )
- {
- // go through the support variables of the cubes
- for ( i = 0; i < p->vPairs0->nSize; i++ )
- {
- Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] );
- Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] );
- if ( (Val0 & Val1) == 0 )
- break;
- }
- // check disjointness
- if ( i < p->vPairs0->nSize )
- continue;
-
- if ( p->pManMin->nCubes >= p->nCubesMax )
- return 0;
-
- // create the product cube
- pCube = Min_CubeAlloc( p->pManMin );
-
- // add the literals
- pCube->nLits = 0;
- for ( i = 0; i < nSupp; i++ )
- {
- if ( p->vComTo0->pArray[i] == -1 )
- Val0 = 3;
- else
- Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] );
-
- if ( p->vComTo1->pArray[i] == -1 )
- Val1 = 3;
- else
- Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] );
-
- if ( (Val0 & Val1) == 3 )
- continue;
-
- Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 );
- pCube->nLits++;
- }
- // add the cube to storage
- Min_EsopAddCube( p->pManMin, pCube );
- }
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeXyzProductSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp )
-{
- return 1;
-}
-
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeXyzUnionEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp )
-{
- Min_Cube_t * pCube, * pCube0, * pCube1;
- int i, Val0, Val1;
-
- // clean storage
- Min_ManClean( p->pManMin, nSupp );
- if ( pCover0 )
- {
- Min_CoverForEachCube( pCover0, pCube0 )
- {
- // create the cube
- pCube = Min_CubeAlloc( p->pManMin );
- pCube->nLits = 0;
- for ( i = 0; i < p->vComTo0->nSize; i++ )
- {
- if ( p->vComTo0->pArray[i] == -1 )
- continue;
- Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] );
- if ( Val0 == 3 )
- continue;
- Min_CubeXorVar( pCube, i, Val0 ^ 3 );
- pCube->nLits++;
- }
- if ( p->pManMin->nCubes >= p->nCubesMax )
- return 0;
- // add the cube to storage
- Min_EsopAddCube( p->pManMin, pCube );
- }
- }
- if ( pCover1 )
- {
- Min_CoverForEachCube( pCover1, pCube1 )
- {
- // create the cube
- pCube = Min_CubeAlloc( p->pManMin );
- pCube->nLits = 0;
- for ( i = 0; i < p->vComTo1->nSize; i++ )
- {
- if ( p->vComTo1->pArray[i] == -1 )
- continue;
- Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] );
- if ( Val1 == 3 )
- continue;
- Min_CubeXorVar( pCube, i, Val1 ^ 3 );
- pCube->nLits++;
- }
- if ( p->pManMin->nCubes >= p->nCubesMax )
- return 0;
- // add the cube to storage
- Min_EsopAddCube( p->pManMin, pCube );
- }
- }
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeXyzUnionSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp )
-{
- return 1;
-}
-
-
-#endif
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
diff --git a/src/opt/xyz/xyzMan.c b/src/opt/xyz/xyzMan.c
deleted file mode 100644
index 844e8c13..00000000
--- a/src/opt/xyz/xyzMan.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/**CFile****************************************************************
-
- FileName [xyzMan.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Cover manipulation package.]
-
- Synopsis [Decomposition manager.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: xyzMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "xyz.h"
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax )
-{
- Xyz_Man_t * pMan;
- Xyz_Obj_t * pMem;
- Abc_Obj_t * pObj;
- int i;
- assert( pNtk->pManCut == NULL );
-
- // start the manager
- pMan = ALLOC( Xyz_Man_t, 1 );
- memset( pMan, 0, sizeof(Xyz_Man_t) );
- pMan->nFaninMax = nFaninMax;
- pMan->nCubesMax = 2 * pMan->nFaninMax;
- pMan->nWords = Abc_BitWordNum( nFaninMax * 2 );
-
- // get the cubes
- pMan->vComTo0 = Vec_IntAlloc( 2*nFaninMax );
- pMan->vComTo1 = Vec_IntAlloc( 2*nFaninMax );
- pMan->vPairs0 = Vec_IntAlloc( nFaninMax );
- pMan->vPairs1 = Vec_IntAlloc( nFaninMax );
- pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 );
- pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 );
-
- // allocate memory for object structures
- pMan->pMemory = pMem = ALLOC( Xyz_Obj_t, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) );
- memset( pMem, 0, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) );
- // allocate storage for the pointers to the memory
- pMan->vObjStrs = Vec_PtrAlloc( Abc_NtkObjNumMax(pNtk) );
- Vec_PtrFill( pMan->vObjStrs, Abc_NtkObjNumMax(pNtk), NULL );
- Abc_NtkForEachObj( pNtk, pObj, i )
- Vec_PtrWriteEntry( pMan->vObjStrs, i, pMem + i );
- // create the cube manager
- pMan->pManMin = Min_ManAlloc( nFaninMax );
- return pMan;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Xyz_ManFree( Xyz_Man_t * p )
-{
- Vec_Int_t * vSupp;
- int i;
- for ( i = 0; i < p->vObjStrs->nSize; i++ )
- {
- vSupp = ((Xyz_Obj_t *)p->vObjStrs->pArray[i])->vSupp;
- if ( vSupp ) Vec_IntFree( vSupp );
- }
-
- Min_ManFree( p->pManMin );
- Vec_PtrFree( p->vObjStrs );
- Vec_IntFree( p->vFanCounts );
- Vec_IntFree( p->vTriv0 );
- Vec_IntFree( p->vTriv1 );
- Vec_IntFree( p->vComTo0 );
- Vec_IntFree( p->vComTo1 );
- Vec_IntFree( p->vPairs0 );
- Vec_IntFree( p->vPairs1 );
- free( p->pMemory );
- free( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Drop the covers at the node.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj )
-{
- int nFanouts;
- assert( p->vFanCounts );
- nFanouts = Vec_IntEntry( p->vFanCounts, pObj->Id );
- assert( nFanouts > 0 );
- if ( --nFanouts == 0 )
- {
- Vec_IntFree( Abc_ObjGetSupp(pObj) );
- Abc_ObjSetSupp( pObj, NULL );
- Min_CoverRecycle( p->pManMin, Abc_ObjGetCover2(pObj) );
- Abc_ObjSetCover2( pObj, NULL );
- p->nSupps--;
- }
- Vec_IntWriteEntry( p->vFanCounts, pObj->Id, nFanouts );
-}
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
diff --git a/src/opt/xyz/xyzMinSop.c b/src/opt/xyz/xyzMinSop.c
deleted file mode 100644
index a5d57c66..00000000
--- a/src/opt/xyz/xyzMinSop.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/**CFile****************************************************************
-
- FileName [xyzMinSop.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Cover manipulation package.]
-
- Synopsis [SOP manipulation.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: xyzMinSop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "xyzInt.h"
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-static void Min_SopRewrite( Min_Man_t * p );
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Min_SopMinimize( Min_Man_t * p )
-{
- int nCubesInit, nCubesOld, nIter;
- if ( p->nCubes < 3 )
- return;
- nIter = 0;
- nCubesInit = p->nCubes;
- do {
- nCubesOld = p->nCubes;
- Min_SopRewrite( p );
- nIter++;
-// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes );
- }
- while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 );
-// printf( "\n" );
-
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Min_SopRewrite( Min_Man_t * p )
-{
- Min_Cube_t * pCube, ** ppPrev;
- Min_Cube_t * pThis, ** ppPrevT;
- Min_Cube_t * pTemp;
- int v00, v01, v10, v11, Var0, Var1, Index, fCont0, fCont1, nCubesOld;
- int nPairs = 0;
-/*
- {
- Min_Cube_t * pCover;
- pCover = Min_CoverCollect( p, p->nVars );
-printf( "\n\n" );
-Min_CoverWrite( stdout, pCover );
- Min_CoverExpand( p, pCover );
- }
-*/
-
- // insert the bubble before the first cube
- p->pBubble->pNext = p->ppStore[0];
- p->ppStore[0] = p->pBubble;
- p->pBubble->nLits = 0;
-
- // go through the cubes
- while ( 1 )
- {
- // get the index of the bubble
- Index = p->pBubble->nLits;
-
- // find the bubble
- Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev )
- if ( pCube == p->pBubble )
- break;
- assert( pCube == p->pBubble );
-
- // remove the bubble, get the next cube after the bubble
- *ppPrev = p->pBubble->pNext;
- pCube = p->pBubble->pNext;
- if ( pCube == NULL )
- for ( Index++; Index <= p->nVars; Index++ )
- if ( p->ppStore[Index] )
- {
- ppPrev = &(p->ppStore[Index]);
- pCube = p->ppStore[Index];
- break;
- }
- // stop if there is no more cubes
- if ( pCube == NULL )
- break;
-
- // find the first dist2 cube
- Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
- if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
- break;
- if ( pThis == NULL && Index < p->nVars )
- Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
- if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
- break;
- // continue if there is no dist2 cube
- if ( pThis == NULL )
- {
- // insert the bubble after the cube
- p->pBubble->pNext = pCube->pNext;
- pCube->pNext = p->pBubble;
- p->pBubble->nLits = pCube->nLits;
- continue;
- }
- nPairs++;
-/*
-printf( "\n" );
-Min_CubeWrite( stdout, pCube );
-Min_CubeWrite( stdout, pThis );
-*/
- // remove the cubes, insert the bubble instead of pCube
- *ppPrevT = pThis->pNext;
- *ppPrev = p->pBubble;
- p->pBubble->pNext = pCube->pNext;
- p->pBubble->nLits = pCube->nLits;
- p->nCubes -= 2;
-
- assert( pCube != p->pBubble && pThis != p->pBubble );
-
-
- // save the dist2 parameters
- v00 = Min_CubeGetVar( pCube, Var0 );
- v01 = Min_CubeGetVar( pCube, Var1 );
- v10 = Min_CubeGetVar( pThis, Var0 );
- v11 = Min_CubeGetVar( pThis, Var1 );
- assert( v00 != v10 && v01 != v11 );
- assert( v00 != 3 || v01 != 3 );
- assert( v10 != 3 || v11 != 3 );
-
-//printf( "\n" );
-//Min_CubeWrite( stdout, pCube );
-//Min_CubeWrite( stdout, pThis );
-
-//printf( "\n" );
-//Min_CubeWrite( stdout, pCube );
-//Min_CubeWrite( stdout, pThis );
-
- // consider the case when both cubes have non-empty literals
- if ( v00 != 3 && v01 != 3 && v10 != 3 && v11 != 3 )
- {
- assert( v00 == (v10 ^ 3) );
- assert( v01 == (v11 ^ 3) );
- // create the temporary cube equal to the first corner
- Min_CubeXorVar( pCube, Var0, 3 );
- // check if this cube is contained
- fCont0 = Min_CoverContainsCube( p, pCube );
- // create the temporary cube equal to the first corner
- Min_CubeXorVar( pCube, Var0, 3 );
- Min_CubeXorVar( pCube, Var1, 3 );
-//printf( "\n" );
-//Min_CubeWrite( stdout, pCube );
-//Min_CubeWrite( stdout, pThis );
- // check if this cube is contained
- fCont1 = Min_CoverContainsCube( p, pCube );
- // undo the change
- Min_CubeXorVar( pCube, Var1, 3 );
-
- // check if the cubes can be overwritten
- if ( fCont0 && fCont1 )
- {
- // one of the cubes can be recycled, the other expanded and added
- Min_CubeRecycle( p, pThis );
- // remove the literals
- Min_CubeXorVar( pCube, Var0, v00 ^ 3 );
- Min_CubeXorVar( pCube, Var1, v01 ^ 3 );
- pCube->nLits -= 2;
- Min_SopAddCube( p, pCube );
- }
- else if ( fCont0 )
- {
- // expand both cubes and add them
- Min_CubeXorVar( pCube, Var0, v00 ^ 3 );
- pCube->nLits--;
- Min_SopAddCube( p, pCube );
- Min_CubeXorVar( pThis, Var1, v11 ^ 3 );
- pThis->nLits--;
- Min_SopAddCube( p, pThis );
- }
- else if ( fCont1 )
- {
- // expand both cubes and add them
- Min_CubeXorVar( pCube, Var1, v01 ^ 3 );
- pCube->nLits--;
- Min_SopAddCube( p, pCube );
- Min_CubeXorVar( pThis, Var0, v10 ^ 3 );
- pThis->nLits--;
- Min_SopAddCube( p, pThis );
- }
- else
- {
- Min_SopAddCube( p, pCube );
- Min_SopAddCube( p, pThis );
- }
- // otherwise, no change is possible
- continue;
- }
-
- // if one of them does not have DC lit, move it
- if ( v00 != 3 && v01 != 3 )
- {
- assert( v10 == 3 || v11 == 3 );
- pTemp = pCube; pCube = pThis; pThis = pTemp;
- Index = v00; v00 = v10; v10 = Index;
- Index = v01; v01 = v11; v11 = Index;
- }
-
- // make sure the first cube has first var DC
- if ( v00 != 3 )
- {
- assert( v01 == 3 );
- Index = Var0; Var0 = Var1; Var1 = Index;
- Index = v00; v00 = v01; v01 = Index;
- Index = v10; v10 = v11; v11 = Index;
- }
-
- // consider both cases: both have DC lit
- if ( v00 == 3 && v11 == 3 )
- {
- assert( v01 != 3 && v10 != 3 );
- // try the remaining minterm
- // create the temporary cube equal to the first corner
- Min_CubeXorVar( pCube, Var0, v10 );
- Min_CubeXorVar( pCube, Var1, 3 );
- pCube->nLits++;
- // check if this cube is contained
- fCont0 = Min_CoverContainsCube( p, pCube );
- // undo the cube transformations
- Min_CubeXorVar( pCube, Var0, v10 );
- Min_CubeXorVar( pCube, Var1, 3 );
- pCube->nLits--;
- // check the case when both are covered
- if ( fCont0 )
- {
- // one of the cubes can be recycled, the other expanded and added
- Min_CubeRecycle( p, pThis );
- // remove the literals
- Min_CubeXorVar( pCube, Var1, v01 ^ 3 );
- pCube->nLits--;
- Min_SopAddCube( p, pCube );
- }
- else
- {
- // try two reduced cubes
- Min_CubeXorVar( pCube, Var0, v10 );
- pCube->nLits++;
- // remember the cubes
- nCubesOld = p->nCubes;
- Min_SopAddCube( p, pCube );
- // check if the cube is absorbed
- if ( p->nCubes < nCubesOld + 1 )
- { // absorbed - add the second cube
- Min_SopAddCube( p, pThis );
- }
- else
- { // remove this cube, and try another one
- assert( pCube == p->ppStore[pCube->nLits] );
- p->ppStore[pCube->nLits] = pCube->pNext;
- p->nCubes--;
-
- // return the cube to the previous state
- Min_CubeXorVar( pCube, Var0, v10 );
- pCube->nLits--;
-
- // generate another reduced cube
- Min_CubeXorVar( pThis, Var1, v01 );
- pThis->nLits++;
-
- // add both cubes
- Min_SopAddCube( p, pCube );
- Min_SopAddCube( p, pThis );
- }
- }
- }
- else // the first cube has DC lit
- {
- assert( v01 != 3 && v10 != 3 && v11 != 3 );
- // try the remaining minterm
- // create the temporary cube equal to the minterm
- Min_CubeXorVar( pThis, Var0, 3 );
- // check if this cube is contained
- fCont0 = Min_CoverContainsCube( p, pThis );
- // undo the cube transformations
- Min_CubeXorVar( pThis, Var0, 3 );
- // check the case when both are covered
- if ( fCont0 )
- {
- // one of the cubes can be recycled, the other expanded and added
- Min_CubeRecycle( p, pThis );
- // remove the literals
- Min_CubeXorVar( pCube, Var1, v01 ^ 3 );
- pCube->nLits--;
- Min_SopAddCube( p, pCube );
- }
- else
- {
- // try reshaping the cubes
- // reduce the first cube
- Min_CubeXorVar( pCube, Var0, v10 );
- pCube->nLits++;
- // expand the second cube
- Min_CubeXorVar( pThis, Var1, v11 ^ 3 );
- pThis->nLits--;
- // add both cubes
- Min_SopAddCube( p, pCube );
- Min_SopAddCube( p, pThis );
- }
- }
- }
-// printf( "Pairs = %d ", nPairs );
-}
-
-/**Function*************************************************************
-
- Synopsis [Adds cube to the SOP cover stored in the manager.]
-
- Description [Returns 0 if the cube is added or removed. Returns 1
- if the cube is glued with some other cube and has to be added again.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Min_SopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube )
-{
- Min_Cube_t * pThis, * pThis2, ** ppPrev;
- int i;
- // try to find the identical cube
- Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
- {
- if ( Min_CubesAreEqual( pCube, pThis ) )
- {
- Min_CubeRecycle( p, pCube );
- return 0;
- }
- }
- // try to find a containing cube
- for ( i = 0; i < (int)pCube->nLits; i++ )
- Min_CoverForEachCube( p->ppStore[i], pThis )
- {
- if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) )
- {
- Min_CubeRecycle( p, pCube );
- return 0;
- }
- }
- // try to find distance one in the same bin
- Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
- {
- if ( Min_CubesDistOne( pCube, pThis, NULL ) )
- {
- *ppPrev = pThis->pNext;
- Min_CubesTransformOr( pCube, pThis );
- pCube->nLits--;
- Min_CubeRecycle( p, pThis );
- p->nCubes--;
- return 1;
- }
- }
-
- // clean the other cubes using this one
- for ( i = pCube->nLits + 1; i <= (int)pCube->nVars; i++ )
- {
- ppPrev = &p->ppStore[i];
- Min_CoverForEachCubeSafe( p->ppStore[i], pThis, pThis2 )
- {
- if ( pThis != p->pBubble && Min_CubeIsContained( pCube, pThis ) )
- {
- *ppPrev = pThis->pNext;
- Min_CubeRecycle( p, pThis );
- p->nCubes--;
- }
- else
- ppPrev = &pThis->pNext;
- }
- }
-
- // add the cube
- pCube->pNext = p->ppStore[pCube->nLits];
- p->ppStore[pCube->nLits] = pCube;
- p->nCubes++;
- return 0;
-}
-
-/**Function*************************************************************
-
- Synopsis [Adds the cube to storage.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube )
-{
- assert( Min_CubeCheck( pCube ) );
- assert( pCube != p->pBubble );
- assert( (int)pCube->nLits == Min_CubeCountLits(pCube) );
- while ( Min_SopAddCubeInt( p, pCube ) );
-}
-
-
-
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Min_SopContain( Min_Man_t * p )
-{
- Min_Cube_t * pCube, * pCube2, ** ppPrev;
- int i, k;
- for ( i = 0; i <= p->nVars; i++ )
- {
- Min_CoverForEachCube( p->ppStore[i], pCube )
- Min_CoverForEachCubePrev( pCube->pNext, pCube2, ppPrev )
- {
- if ( !Min_CubesAreEqual( pCube, pCube2 ) )
- continue;
- *ppPrev = pCube2->pNext;
- Min_CubeRecycle( p, pCube2 );
- p->nCubes--;
- }
- for ( k = i + 1; k <= p->nVars; k++ )
- Min_CoverForEachCubePrev( p->ppStore[k], pCube2, ppPrev )
- {
- if ( !Min_CubeIsContained( pCube, pCube2 ) )
- continue;
- *ppPrev = pCube2->pNext;
- Min_CubeRecycle( p, pCube2 );
- p->nCubes--;
- }
- }
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Min_SopDist1Merge( Min_Man_t * p )
-{
- Min_Cube_t * pCube, * pCube2, * pCubeNew;
- int i;
- for ( i = p->nVars; i >= 0; i-- )
- {
- Min_CoverForEachCube( p->ppStore[i], pCube )
- Min_CoverForEachCube( pCube->pNext, pCube2 )
- {
- assert( pCube->nLits == pCube2->nLits );
- if ( !Min_CubesDistOne( pCube, pCube2, NULL ) )
- continue;
- pCubeNew = Min_CubesXor( p, pCube, pCube2 );
- assert( pCubeNew->nLits == pCube->nLits - 1 );
- pCubeNew->pNext = p->ppStore[pCubeNew->nLits];
- p->ppStore[pCubeNew->nLits] = pCubeNew;
- p->nCubes++;
- }
- }
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Min_Cube_t * Min_SopComplement( Min_Man_t * p, Min_Cube_t * pSharp )
-{
- Vec_Int_t * vVars;
- Min_Cube_t * pCover, * pCube, * pNext, * pReady, * pThis, ** ppPrev;
- int Num, Value, i;
-
- // get the variables
- vVars = Vec_IntAlloc( 100 );
- // create the tautology cube
- pCover = Min_CubeAlloc( p );
- // sharp it with all cubes
- Min_CoverForEachCube( pSharp, pCube )
- Min_CoverForEachCubePrev( pCover, pThis, ppPrev )
- {
- if ( Min_CubesDisjoint( pThis, pCube ) )
- continue;
- // remember the next pointer
- pNext = pThis->pNext;
- // get the variables, in which pThis is '-' while pCube is fixed
- Min_CoverGetDisjVars( pThis, pCube, vVars );
- // generate the disjoint cubes
- pReady = pThis;
- Vec_IntForEachEntryReverse( vVars, Num, i )
- {
- // correct the literal
- Min_CubeXorVar( pReady, vVars->pArray[i], 3 );
- if ( i == 0 )
- break;
- // create the new cube and clean this value
- Value = Min_CubeGetVar( pReady, vVars->pArray[i] );
- pReady = Min_CubeDup( p, pReady );
- Min_CubeXorVar( pReady, vVars->pArray[i], 3 ^ Value );
- // add to the cover
- *ppPrev = pReady;
- ppPrev = &pReady->pNext;
- }
- pThis = pReady;
- pThis->pNext = pNext;
- }
- Vec_IntFree( vVars );
-
- // perform dist-1 merge and contain
- Min_CoverExpandRemoveEqual( p, pCover );
- Min_SopDist1Merge( p );
- Min_SopContain( p );
- return Min_CoverCollect( p, p->nVars );
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Min_SopCheck( Min_Man_t * p )
-{
- Min_Cube_t * pCube, * pThis;
- int i;
-
- pCube = Min_CubeAlloc( p );
- Min_CubeXorBit( pCube, 2*0+1 );
- Min_CubeXorBit( pCube, 2*1+1 );
- Min_CubeXorBit( pCube, 2*2+0 );
- Min_CubeXorBit( pCube, 2*3+0 );
- Min_CubeXorBit( pCube, 2*4+0 );
- Min_CubeXorBit( pCube, 2*5+1 );
- Min_CubeXorBit( pCube, 2*6+1 );
- pCube->nLits = 7;
-
-// Min_CubeWrite( stdout, pCube );
-
- // check that the cubes contain it
- for ( i = 0; i <= p->nVars; i++ )
- Min_CoverForEachCube( p->ppStore[i], pThis )
- if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) )
- {
- Min_CubeRecycle( p, pCube );
- return 1;
- }
- Min_CubeRecycle( p, pCube );
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
diff --git a/src/opt/xyz/xyzTest.c b/src/opt/xyz/xyzTest.c
deleted file mode 100644
index 38580790..00000000
--- a/src/opt/xyz/xyzTest.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/**CFile****************************************************************
-
- FileName [xyzTest.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Cover manipulation package.]
-
- Synopsis [Testing procedures.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: xyzTest.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "xyz.h"
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Min_Cube_t * Abc_NodeDeriveCoverPro( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 )
-{
- Min_Cube_t * pCover;
- Min_Cube_t * pCube0, * pCube1, * pCube;
- if ( pCover0 == NULL || pCover1 == NULL )
- return NULL;
- // clean storage
- Min_ManClean( p, p->nVars );
- // go through the cube pairs
- Min_CoverForEachCube( pCover0, pCube0 )
- Min_CoverForEachCube( pCover1, pCube1 )
- {
- if ( Min_CubesDisjoint( pCube0, pCube1 ) )
- continue;
- pCube = Min_CubesProduct( p, pCube0, pCube1 );
- // add the cube to storage
- Min_SopAddCube( p, pCube );
- }
- Min_SopMinimize( p );
- pCover = Min_CoverCollect( p, p->nVars );
- assert( p->nCubes == Min_CoverCountCubes(pCover) );
- return pCover;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Min_Cube_t * Abc_NodeDeriveCoverSum( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 )
-{
- Min_Cube_t * pCover;
- Min_Cube_t * pThis, * pCube;
- if ( pCover0 == NULL || pCover1 == NULL )
- return NULL;
- // clean storage
- Min_ManClean( p, p->nVars );
- // add the cubes to storage
- Min_CoverForEachCube( pCover0, pThis )
- {
- pCube = Min_CubeDup( p, pThis );
- Min_SopAddCube( p, pCube );
- }
- Min_CoverForEachCube( pCover1, pThis )
- {
- pCube = Min_CubeDup( p, pThis );
- Min_SopAddCube( p, pCube );
- }
- Min_SopMinimize( p );
- pCover = Min_CoverCollect( p, p->nVars );
- assert( p->nCubes == Min_CoverCountCubes(pCover) );
- return pCover;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeDeriveSops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes )
-{
- Min_Cube_t * pCov0[2], * pCov1[2];
- Min_Cube_t * pCoverP, * pCoverN;
- Abc_Obj_t * pObj;
- int i, nCubes, fCompl0, fCompl1;
-
- // set elementary vars
- Vec_PtrForEachEntry( vSupp, pObj, i )
- {
- pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 );
- pObj->pNext = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 1 );
- }
-
- // get the cover for each node in the array
- Vec_PtrForEachEntry( vNodes, pObj, i )
- {
- // get the complements
- fCompl0 = Abc_ObjFaninC0(pObj);
- fCompl1 = Abc_ObjFaninC1(pObj);
- // get the covers
- pCov0[0] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy;
- pCov0[1] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pNext;
- pCov1[0] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy;
- pCov1[1] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pNext;
- // compute the covers
- pCoverP = Abc_NodeDeriveCoverPro( p, pCov0[ fCompl0], pCov1[ fCompl1] );
- pCoverN = Abc_NodeDeriveCoverSum( p, pCov0[!fCompl0], pCov1[!fCompl1] );
- // set the covers
- pObj->pCopy = (Abc_Obj_t *)pCoverP;
- pObj->pNext = (Abc_Obj_t *)pCoverN;
- }
-
- nCubes = ABC_MIN( Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverP) );
-
-/*
-printf( "\n\n" );
-Min_CoverWrite( stdout, pCoverP );
-printf( "\n\n" );
-Min_CoverWrite( stdout, pCoverN );
-*/
-
-// printf( "\n" );
-// Min_CoverWrite( stdout, pCoverP );
-
-// Min_CoverExpand( p, pCoverP );
-// Min_SopMinimize( p );
-// pCoverP = Min_CoverCollect( p, p->nVars );
-
-// printf( "\n" );
-// Min_CoverWrite( stdout, pCoverP );
-
-// nCubes = Min_CoverCountCubes(pCoverP);
-
- // clean the copy fields
- Vec_PtrForEachEntry( vNodes, pObj, i )
- pObj->pCopy = pObj->pNext = NULL;
- Vec_PtrForEachEntry( vSupp, pObj, i )
- pObj->pCopy = pObj->pNext = NULL;
-
-// Min_CoverWriteFile( pCoverP, Abc_ObjName(pRoot), 0 );
-// printf( "\n" );
-// Min_CoverWrite( stdout, pCoverP );
-
-// printf( "\n" );
-// Min_CoverWrite( stdout, pCoverP );
-// printf( "\n" );
-// Min_CoverWrite( stdout, pCoverN );
- return nCubes;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NtkTestSop( Abc_Ntk_t * pNtk )
-{
- Min_Man_t * p;
- Vec_Ptr_t * vSupp, * vNodes;
- Abc_Obj_t * pObj;
- int i, nCubes;
- assert( Abc_NtkIsStrash(pNtk) );
-
- Abc_NtkCleanCopy(pNtk);
- Abc_NtkCleanNext(pNtk);
- Abc_NtkForEachCo( pNtk, pObj, i )
- {
- if ( !Abc_NodeIsAigAnd(Abc_ObjFanin0(pObj)) )
- {
- printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) );
- continue;
- }
-
- vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
- vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 );
-
- printf( "%20s : Cone = %5d. Supp = %5d. ",
- Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize );
-// if ( vSupp->nSize <= 128 )
- {
- p = Min_ManAlloc( vSupp->nSize );
- nCubes = Abc_NodeDeriveSops( p, pObj, vSupp, vNodes );
- printf( "Cubes = %5d. ", nCubes );
- Min_ManFree( p );
- }
- printf( "\n" );
-
-
- Vec_PtrFree( vNodes );
- Vec_PtrFree( vSupp );
- }
-}
-
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Min_Cube_t * Abc_NodeDeriveCover( Min_Man_t * p, Min_Cube_t * pCov0, Min_Cube_t * pCov1, int fComp0, int fComp1 )
-{
- Min_Cube_t * pCover0, * pCover1, * pCover;
- Min_Cube_t * pCube0, * pCube1, * pCube;
-
- // complement the first if needed
- if ( !fComp0 )
- pCover0 = pCov0;
- else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube
- pCover0 = pCov0->pNext;
- else
- pCover0 = p->pOne0, p->pOne0->pNext = pCov0;
-
- // complement the second if needed
- if ( !fComp1 )
- pCover1 = pCov1;
- else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube
- pCover1 = pCov1->pNext;
- else
- pCover1 = p->pOne1, p->pOne1->pNext = pCov1;
-
- if ( pCover0 == NULL || pCover1 == NULL )
- return NULL;
-
- // clean storage
- Min_ManClean( p, p->nVars );
- // go through the cube pairs
- Min_CoverForEachCube( pCover0, pCube0 )
- Min_CoverForEachCube( pCover1, pCube1 )
- {
- if ( Min_CubesDisjoint( pCube0, pCube1 ) )
- continue;
- pCube = Min_CubesProduct( p, pCube0, pCube1 );
- // add the cube to storage
- Min_EsopAddCube( p, pCube );
- }
-
- if ( p->nCubes > 10 )
- {
-// printf( "(%d,", p->nCubes );
- Min_EsopMinimize( p );
-// printf( "%d) ", p->nCubes );
- }
-
- pCover = Min_CoverCollect( p, p->nVars );
- assert( p->nCubes == Min_CoverCountCubes(pCover) );
-
-// if ( p->nCubes > 1000 )
-// printf( "%d ", p->nCubes );
- return pCover;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Abc_NodeDeriveEsops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes )
-{
- Min_Cube_t * pCover, * pCube;
- Abc_Obj_t * pObj;
- int i;
-
- // set elementary vars
- Vec_PtrForEachEntry( vSupp, pObj, i )
- pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 );
-
- // get the cover for each node in the array
- Vec_PtrForEachEntry( vNodes, pObj, i )
- {
- pCover = Abc_NodeDeriveCover( p,
- (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy,
- (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy,
- Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
- pObj->pCopy = (Abc_Obj_t *)pCover;
- if ( p->nCubes > 3000 )
- return -1;
- }
-
- // add complement if needed
- if ( Abc_ObjFaninC0(pRoot) )
- {
- if ( pCover && pCover->nLits == 0 ) // topmost one is the tautology cube
- {
- pCube = pCover;
- pCover = pCover->pNext;
- Min_CubeRecycle( p, pCube );
- p->nCubes--;
- }
- else
- {
- pCube = Min_CubeAlloc( p );
- pCube->pNext = pCover;
- p->nCubes++;
- }
- }
-/*
- Min_CoverExpand( p, pCover );
- Min_EsopMinimize( p );
- pCover = Min_CoverCollect( p, p->nVars );
-*/
- // clean the copy fields
- Vec_PtrForEachEntry( vNodes, pObj, i )
- pObj->pCopy = NULL;
- Vec_PtrForEachEntry( vSupp, pObj, i )
- pObj->pCopy = NULL;
-
-// Min_CoverWriteFile( pCover, Abc_ObjName(pRoot), 1 );
-// Min_CoverWrite( stdout, pCover );
- return p->nCubes;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Abc_NtkTestEsop( Abc_Ntk_t * pNtk )
-{
- Min_Man_t * p;
- Vec_Ptr_t * vSupp, * vNodes;
- Abc_Obj_t * pObj;
- int i, nCubes;
- assert( Abc_NtkIsStrash(pNtk) );
-
- Abc_NtkCleanCopy(pNtk);
- Abc_NtkForEachCo( pNtk, pObj, i )
- {
- if ( !Abc_NodeIsAigAnd(Abc_ObjFanin0(pObj)) )
- {
- printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) );
- continue;
- }
-
- vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
- vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 );
-
- printf( "%20s : Cone = %5d. Supp = %5d. ",
- Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize );
-// if ( vSupp->nSize <= 128 )
- {
- p = Min_ManAlloc( vSupp->nSize );
- nCubes = Abc_NodeDeriveEsops( p, pObj, vSupp, vNodes );
- printf( "Cubes = %5d. ", nCubes );
- Min_ManFree( p );
- }
- printf( "\n" );
-
-
- Vec_PtrFree( vNodes );
- Vec_PtrFree( vSupp );
- }
-}
-
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
diff --git a/src/sat/aig/aig.h b/src/sat/aig/aig.h
index 5d2547ea..a0d63ce9 100644
--- a/src/sat/aig/aig.h
+++ b/src/sat/aig/aig.h
@@ -64,9 +64,11 @@ extern "C" {
////////////////////////////////////////////////////////////////////////
//typedef int bool;
+#ifndef __cplusplus
#ifndef bool
#define bool int
#endif
+#endif
typedef struct Aig_Param_t_ Aig_Param_t;
typedef struct Aig_Man_t_ Aig_Man_t;
@@ -215,7 +217,7 @@ struct Aig_SimInfo_t_
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-static inline int Aig_BitWordNum( int nBits ) { return nBits/32 + ((nBits%32) > 0); }
+static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
static inline int Aig_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
static inline void Aig_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
static inline void Aig_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
diff --git a/src/sat/aig/fraigCore.c b/src/sat/aig/fraigCore.c
index 525d4a14..03781180 100644
--- a/src/sat/aig/fraigCore.c
+++ b/src/sat/aig/fraigCore.c
@@ -92,7 +92,7 @@ Aig_ProofType_t Aig_FraigProveOutput( Aig_Man_t * pMan )
// solve the miter
clk = clock();
pMan->pSat->verbosity = pMan->pParam->fSatVerbose;
- status = solver_solve( pMan->pSat, NULL, NULL, 0, 0 );//pMan->pParam->nConfLimit, pMan->pParam->nImpLimit );
+ status = solver_solve( pMan->pSat, NULL, NULL, 0, 0 );//pMan->pParam->nConfLimit, pMan->pParam->nInsLimit );
if ( status == l_Undef )
{
// printf( "The problem timed out.\n" );
diff --git a/src/sat/aig/rwrTruth.c b/src/sat/aig/rwrTruth.c
index 92a39f0a..cb8d03e0 100644
--- a/src/sat/aig/rwrTruth.c
+++ b/src/sat/aig/rwrTruth.c
@@ -167,7 +167,7 @@ void Aig_TruthCount( Aig_Truth_t * p )
***********************************************************************/
static inline unsigned Aig_WordGetPart( unsigned * p, int Start, int Size )
{
- return (p[Start/5] >> (Start%32)) & (~0u >> (32-Size));
+ return (p[Start/5] >> (Start&31)) & (~0u >> (32-Size));
}
/**Function*************************************************************
@@ -183,7 +183,7 @@ static inline unsigned Aig_WordGetPart( unsigned * p, int Start, int Size )
***********************************************************************/
static inline void Aig_WordSetPart( unsigned * p, int Start, unsigned Part )
{
- p[Start/5] |= (Part << (Start%32));
+ p[Start/5] |= (Part << (Start&31));
}
/**Function*************************************************************
@@ -254,7 +254,7 @@ DdNode * Aig_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int Shift, int n
}
if ( nVars == 5 )
{
- unsigned * pWord = pTruth + Shift/32;
+ unsigned * pWord = pTruth + (Shift>>5);
assert( Shift % 32 == 0 );
if ( *pWord == 0 )
return Cudd_ReadLogicZero(dd);
diff --git a/src/sat/asat/added.c b/src/sat/asat/added.c
index e1b1bb2a..832bc0cf 100644
--- a/src/sat/asat/added.c
+++ b/src/sat/asat/added.c
@@ -158,7 +158,7 @@ int * solver_get_model( solver * p, int * pVars, int nVars )
for ( i = 0; i < nVars; i++ )
{
assert( pVars[i] >= 0 && pVars[i] < p->size );
- pModel[i] = (int)(p->model.ptr[pVars[i]] == (void *)l_True);
+ pModel[i] = (int)(p->model.ptr[pVars[i]] == l_True);
}
return pModel;
}
@@ -188,6 +188,28 @@ void Asat_SatPrintStats( FILE * pFile, solver * p )
(float)(p->timeUpdate)/(float)(CLOCKS_PER_SEC) );
}
+/**Function*************************************************************
+
+ Synopsis [Sets the preferred variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Asat_SolverSetPrefVars(solver * s, int * pPrefVars, int nPrefVars)
+{
+ int i;
+ assert( s->pPrefVars == NULL );
+ for ( i = 0; i < nPrefVars; i++ )
+ assert( pPrefVars[i] < s->size );
+ s->pPrefVars = pPrefVars;
+ s->nPrefVars = nPrefVars;
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/asat/asat60525.zip b/src/sat/asat/asat60525.zip
new file mode 100644
index 00000000..b8361af1
--- /dev/null
+++ b/src/sat/asat/asat60525.zip
Binary files differ
diff --git a/src/sat/asat/jfront.c b/src/sat/asat/jfront.c
index 1def6a37..8e673cc9 100644
--- a/src/sat/asat/jfront.c
+++ b/src/sat/asat/jfront.c
@@ -95,7 +95,7 @@ static void Asat_JRingRemove( Asat_JMan_t * p, Asat_JVar_t * pVar );
// iterator through the adjacent variables
#define Asat_JVarForEachFanio( p, pVar, pFan, i ) \
- for ( i = 0; (i < pVar->nFans) && (((pFan) = Asat_JManVar(p, pVar->Fans[i])), 1); i++ )
+ for ( i = 0; (i < (int)pVar->nFans) && (((pFan) = Asat_JManVar(p, pVar->Fans[i])), 1); i++ )
extern void Asat_JManAssign( Asat_JMan_t * p, int Var );
@@ -223,7 +223,7 @@ int Asat_JManCheck( Asat_JMan_t * p )
// assert( i != pVar->nFans );
// if ( i == pVar->nFans )
// return 0;
- if ( i == pVar->nFans )
+ if ( i == (int)pVar->nFans )
Counter++;
}
if ( Counter > 0 )
diff --git a/src/sat/asat/solver.c b/src/sat/asat/solver.c
index 6d76d890..548abd1d 100644
--- a/src/sat/asat/solver.c
+++ b/src/sat/asat/solver.c
@@ -26,7 +26,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include "solver.h"
-//#define ASAT_USE_SYSTEM_MEMORY_MANAGEMENT
+#define ASAT_USE_SYSTEM_MEMORY_MANAGEMENT
//=================================================================================================
// Simple (var/literal) helpers:
@@ -96,14 +96,14 @@ static inline void clause_setactivity(clause* c, float a) { *((float*)&c->lits[
//=================================================================================================
// Encode literals in clause pointers:
-clause* clause_from_lit (lit l) { return (clause*)(l + l + 1); }
-bool clause_is_lit (clause* c) { return ((unsigned int)c & 1); }
-lit clause_read_lit (clause* c) { return (lit)((unsigned int)c >> 1); }
+clause* clause_from_lit (lit l) { return (clause*)(((unsigned long)l) + ((unsigned long)l) + 1); }
+bool clause_is_lit (clause* c) { return ((unsigned long)c & 1); }
+lit clause_read_lit (clause* c) { return (lit)((unsigned long)c >> 1); }
//=================================================================================================
// Simple helpers:
-static inline int solver_dlevel(solver* s) { return vec_size(&s->trail_lim); }
+static inline int solver_dlevel(solver* s) { return veci_size(&s->trail_lim); }
static inline vec* solver_read_wlist (solver* s, lit l){ return &s->wlists[l]; }
static inline void vec_remove(vec* v, void* e)
{
@@ -124,7 +124,7 @@ static inline void order_update(solver* s, int v) // updateorder
// int clk = clock();
int* orderpos = s->orderpos;
double* activity = s->activity;
- int* heap = (int*)vec_begin(&s->order);
+ int* heap = veci_begin(&s->order);
int i = orderpos[v];
int x = heap[i];
int parent = (i - 1) / 2;
@@ -151,8 +151,8 @@ static inline void order_unassigned(solver* s, int v) // undoorder
// int clk = clock();
int* orderpos = s->orderpos;
if (orderpos[v] == -1){
- orderpos[v] = vec_size(&s->order);
- vec_push(&s->order,(void*)v);
+ orderpos[v] = veci_size(&s->order);
+ veci_push(&s->order,v);
order_update(s,v);
}
// s->timeUpdate += clock() - clk;
@@ -161,12 +161,23 @@ static inline void order_unassigned(solver* s, int v) // undoorder
static int order_select(solver* s, float random_var_freq) // selectvar
{
// int clk = clock();
+ static int Counter = 0;
int* heap;
double* activity;
int* orderpos;
lbool* values = s->assigns;
+ // The first decisions
+ if ( s->pPrefVars && s->nPrefDecNum < s->nPrefVars )
+ {
+ int i;
+ s->nPrefDecNum++;
+ for ( i = 0; i < s->nPrefVars; i++ )
+ if ( values[s->pPrefVars[i]] == l_Undef )
+ return s->pPrefVars[i];
+ }
+
// Random decision:
if (drand(&s->random_seed) < random_var_freq){
int next = irand(&s->random_seed,s->size);
@@ -177,17 +188,17 @@ static int order_select(solver* s, float random_var_freq) // selectvar
// Activity based decision:
- heap = (int*)vec_begin(&s->order);
+ heap = veci_begin(&s->order);
activity = s->activity;
orderpos = s->orderpos;
- while (vec_size(&s->order) > 0){
+ while (veci_size(&s->order) > 0){
int next = heap[0];
- int size = vec_size(&s->order)-1;
+ int size = veci_size(&s->order)-1;
int x = heap[size];
- vec_resize(&s->order,size);
+ veci_resize(&s->order,size);
orderpos[next] = -1;
@@ -300,7 +311,10 @@ static clause* clause_new(solver* s, lit* begin, lit* end, int learnt)
assert(((unsigned int)c & 1) == 0);
for (i = 0; i < size; i++)
+ {
+ assert(begin[i] >= 0);
c->lits[i] = begin[i];
+ }
if (learnt)
*((float*)&c->lits[size]) = 0.0;
@@ -328,11 +342,11 @@ static void clause_remove(solver* s, clause* c)
lit* lits = clause_begin(c);
assert(neg(lits[0]) < s->size*2);
assert(neg(lits[1]) < s->size*2);
+ assert(lits[0] < s->size*2);
//vec_remove(solver_read_wlist(s,neg(lits[0])),(void*)c);
//vec_remove(solver_read_wlist(s,neg(lits[1])),(void*)c);
- assert(lits[0] < s->size*2);
vec_remove(solver_read_wlist(s,neg(lits[0])),(void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[1])));
vec_remove(solver_read_wlist(s,neg(lits[1])),(void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[0])));
@@ -399,8 +413,8 @@ static void solver_setnvars(solver* s,int n)
s->levels [var] = 0;
s->tags [var] = l_Undef;
- assert(vec_size(&s->order) == var);
- vec_push(&s->order,(void*)var);
+ assert(veci_size(&s->order) == var);
+ veci_push(&s->order,var);
order_update(s,var);
}
@@ -413,20 +427,19 @@ static inline bool enqueue(solver* s, lit l, clause* from)
lbool* values = s->assigns;
int v = lit_var(l);
lbool val = values[v];
+ lbool sig = !lit_sign(l); sig += sig - 1;
#ifdef VERBOSEDEBUG
printf(L_IND"enqueue("L_LIT")\n", L_ind, L_lit(l));
#endif
-
- lbool sig = !lit_sign(l); sig += sig - 1;
if (val != l_Undef){
return val == sig;
}else{
// New fact -- store it.
+ int* levels = s->levels;
+ clause** reasons = s->reasons;
#ifdef VERBOSEDEBUG
printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(l));
#endif
- int* levels = s->levels;
- clause** reasons = s->reasons;
values [v] = sig;
levels [v] = solver_dlevel(s);
@@ -448,7 +461,7 @@ static inline void assume(solver* s, lit l){
#ifdef VERBOSEDEBUG
printf(L_IND"assume("L_LIT")\n", L_ind, L_lit(l));
#endif
- vec_push(&s->trail_lim,(void*)s->qtail);
+ veci_push(&s->trail_lim,s->qtail);
enqueue(s,l,(clause*)0);
}
@@ -466,7 +479,7 @@ static inline void solver_canceluntil(solver* s, int level) {
trail = s->trail;
values = s->assigns;
reasons = s->reasons;
- bound = ((int*)vec_begin(&s->trail_lim))[level];
+ bound = veci_begin(&s->trail_lim)[level];
for (c = s->qtail-1; c >= bound; c--) {
int x = lit_var(trail[c]);
@@ -482,23 +495,23 @@ static inline void solver_canceluntil(solver* s, int level) {
order_unassigned( s, lit_var(trail[c]) );
s->qhead = s->qtail = bound;
- vec_resize(&s->trail_lim,level);
+ veci_resize(&s->trail_lim,level);
}
-static void solver_record(solver* s, vec* cls)
+static void solver_record(solver* s, veci* cls)
{
- lit* begin = (lit*)vec_begin(cls);
- lit* end = begin + vec_size(cls);
- clause* c = (vec_size(cls) > 1) ? clause_new(s,begin,end,1) : (clause*)0;
+ lit* begin = veci_begin(cls);
+ lit* end = begin + veci_size(cls);
+ clause* c = (veci_size(cls) > 1) ? clause_new(s,begin,end,1) : (clause*)0;
enqueue(s,*begin,c);
- assert(vec_size(cls) > 0);
+ assert(veci_size(cls) > 0);
if (c != 0) {
vec_push(&s->learnts,(void*)c);
act_clause_bump(s,c);
s->solver_stats.learnts++;
- s->solver_stats.learnts_literals += vec_size(cls);
+ s->solver_stats.learnts_literals += veci_size(cls);
}
}
@@ -525,18 +538,18 @@ static bool solver_lit_removable(solver* s, lit l, int minl)
lbool* tags = s->tags;
clause** reasons = s->reasons;
int* levels = s->levels;
- int top = vec_size(&s->tagged);
+ int top = veci_size(&s->tagged);
assert(lit_var(l) >= 0 && lit_var(l) < s->size);
assert(reasons[lit_var(l)] != 0);
- vec_resize(&s->stack,0);
- vec_push(&s->stack,(void*)lit_var(l));
+ veci_resize(&s->stack,0);
+ veci_push(&s->stack,lit_var(l));
- while (vec_size(&s->stack) > 0){
+ while (veci_size(&s->stack) > 0){
clause* c;
- int v = (int)vec_begin(&s->stack)[vec_size(&s->stack)-1];
+ int v = veci_begin(&s->stack)[veci_size(&s->stack)-1];
assert(v >= 0 && v < s->size);
- vec_resize(&s->stack,vec_size(&s->stack)-1);
+ veci_resize(&s->stack,veci_size(&s->stack)-1);
assert(reasons[v] != 0);
c = reasons[v];
@@ -544,15 +557,15 @@ static bool solver_lit_removable(solver* s, lit l, int minl)
int v = lit_var(clause_read_lit(c));
if (tags[v] == l_Undef && levels[v] != 0){
if (reasons[v] != 0 && ((1 << (levels[v] & 31)) & minl)){
- vec_push(&s->stack,(void*)v);
+ veci_push(&s->stack,v);
tags[v] = l_True;
- vec_push(&s->tagged,(void*)v);
+ veci_push(&s->tagged,v);
}else{
- int* tagged = (int*)vec_begin(&s->tagged);
+ int* tagged = veci_begin(&s->tagged);
int j;
- for (j = top; j < vec_size(&s->tagged); j++)
+ for (j = top; j < veci_size(&s->tagged); j++)
tags[tagged[j]] = l_Undef;
- vec_resize(&s->tagged,top);
+ veci_resize(&s->tagged,top);
return 0;
}
}
@@ -565,14 +578,14 @@ static bool solver_lit_removable(solver* s, lit l, int minl)
if (tags[v] == l_Undef && levels[v] != 0){
if (reasons[v] != 0 && ((1 << (levels[v] & 31)) & minl)){
- vec_push(&s->stack,(void*)lit_var(lits[i]));
+ veci_push(&s->stack,lit_var(lits[i]));
tags[v] = l_True;
- vec_push(&s->tagged,(void*)v);
+ veci_push(&s->tagged,v);
}else{
- int* tagged = (int*)vec_begin(&s->tagged);
- for (j = top; j < vec_size(&s->tagged); j++)
+ int* tagged = veci_begin(&s->tagged);
+ for (j = top; j < veci_size(&s->tagged); j++)
tags[tagged[j]] = l_Undef;
- vec_resize(&s->tagged,top);
+ veci_resize(&s->tagged,top);
return 0;
}
}
@@ -583,7 +596,7 @@ static bool solver_lit_removable(solver* s, lit l, int minl)
return 1;
}
-static void solver_analyze(solver* s, clause* c, vec* learnt)
+static void solver_analyze(solver* s, clause* c, veci* learnt)
{
lit* trail = s->trail;
lbool* tags = s->tags;
@@ -596,7 +609,7 @@ static void solver_analyze(solver* s, clause* c, vec* learnt)
int i, j, minl;
int* tagged;
- vec_push(learnt,(void*)lit_Undef);
+ veci_push(learnt,lit_Undef);
do{
assert(c != 0);
@@ -606,12 +619,12 @@ static void solver_analyze(solver* s, clause* c, vec* learnt)
assert(lit_var(q) >= 0 && lit_var(q) < s->size);
if (tags[lit_var(q)] == l_Undef && levels[lit_var(q)] > 0){
tags[lit_var(q)] = l_True;
- vec_push(&s->tagged,(void*)lit_var(q));
+ veci_push(&s->tagged,lit_var(q));
act_var_bump(s,lit_var(q));
if (levels[lit_var(q)] == solver_dlevel(s))
cnt++;
else
- vec_push(learnt,(void*)q);
+ veci_push(learnt,q);
}
}else{
@@ -625,12 +638,12 @@ static void solver_analyze(solver* s, clause* c, vec* learnt)
assert(lit_var(q) >= 0 && lit_var(q) < s->size);
if (tags[lit_var(q)] == l_Undef && levels[lit_var(q)] > 0){
tags[lit_var(q)] = l_True;
- vec_push(&s->tagged,(void*)lit_var(q));
+ veci_push(&s->tagged,lit_var(q));
act_var_bump(s,lit_var(q));
if (levels[lit_var(q)] == solver_dlevel(s))
cnt++;
else
- vec_push(learnt,(void*)q);
+ veci_push(learnt,q);
}
}
}
@@ -643,31 +656,34 @@ static void solver_analyze(solver* s, clause* c, vec* learnt)
}while (cnt > 0);
- *(lit*)vec_begin(learnt) = neg(p);
+// *veci_begin(learnt) = neg(p);
+
+ lits = veci_begin(learnt);
+ lits[0] = neg(p);
- lits = (lit*)vec_begin(learnt);
minl = 0;
- for (i = 1; i < vec_size(learnt); i++){
+ for (i = 1; i < veci_size(learnt); i++){
int lev = levels[lit_var(lits[i])];
minl |= 1 << (lev & 31);
}
// simplify (full)
- for (i = j = 1; i < vec_size(learnt); i++){
+ for (i = j = 1; i < veci_size(learnt); i++){
if (reasons[lit_var(lits[i])] == 0 || !solver_lit_removable(s,lits[i],minl))
lits[j++] = lits[i];
}
+// j = veci_size(learnt);
// update size of learnt + statistics
- s->solver_stats.max_literals += vec_size(learnt);
- vec_resize(learnt,j);
+ s->solver_stats.max_literals += veci_size(learnt);
+ veci_resize(learnt,j);
s->solver_stats.tot_literals += j;
// clear tags
- tagged = (int*)vec_begin(&s->tagged);
- for (i = 0; i < vec_size(&s->tagged); i++)
+ tagged = veci_begin(&s->tagged);
+ for (i = 0; i < veci_size(&s->tagged); i++)
tags[tagged[i]] = l_Undef;
- vec_resize(&s->tagged,0);
+ veci_resize(&s->tagged,0);
#ifdef DEBUG
for (i = 0; i < s->size; i++)
@@ -676,14 +692,14 @@ static void solver_analyze(solver* s, clause* c, vec* learnt)
#ifdef VERBOSEDEBUG
printf(L_IND"Learnt {", L_ind);
- for (i = 0; i < vec_size(learnt); i++) printf(" "L_LIT, L_lit(lits[i]));
+ for (i = 0; i < veci_size(learnt); i++) printf(" "L_LIT, L_lit(lits[i]));
#endif
- if (vec_size(learnt) > 1){
+ if (veci_size(learnt) > 1){
int max_i = 1;
int max = levels[lit_var(lits[1])];
lit tmp;
- for (i = 2; i < vec_size(learnt); i++)
+ for (i = 2; i < veci_size(learnt); i++)
if (levels[lit_var(lits[i])] > max){
max = levels[lit_var(lits[i])];
max_i = i;
@@ -695,7 +711,7 @@ static void solver_analyze(solver* s, clause* c, vec* learnt)
}
#ifdef VERBOSEDEBUG
{
- int lev = vec_size(learnt) > 1 ? levels[lit_var(lits[1])] : 0;
+ int lev = veci_size(learnt) > 1 ? levels[lit_var(lits[1])] : 0;
printf(" } at level %d\n", lev);
}
#endif
@@ -824,15 +840,15 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts)
double random_var_freq = 0.0;//0.02;
int conflictC = 0;
- vec learnt_clause;
+ veci learnt_clause;
assert(s->root_level == solver_dlevel(s));
s->solver_stats.starts++;
s->var_decay = (float)(1 / var_decay );
s->cla_decay = (float)(1 / clause_decay);
- vec_resize(&s->model,0);
- vec_new(&learnt_clause);
+ veci_resize(&s->model,0);
+ veci_new(&learnt_clause);
for (;;){
clause* confl = solver_propagate(s);
@@ -845,13 +861,13 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts)
#endif
s->solver_stats.conflicts++; conflictC++;
if (solver_dlevel(s) == s->root_level){
- vec_delete(&learnt_clause);
+ veci_delete(&learnt_clause);
return l_False;
}
- vec_resize(&learnt_clause,0);
+ veci_resize(&learnt_clause,0);
solver_analyze(s, confl, &learnt_clause);
- blevel = vec_size(&learnt_clause) > 1 ? levels[lit_var(((lit*)vec_begin(&learnt_clause))[1])] : s->root_level;
+ blevel = veci_size(&learnt_clause) > 1 ? levels[lit_var(veci_begin(&learnt_clause)[1])] : s->root_level;
solver_canceluntil(s,blevel);
solver_record(s,&learnt_clause);
act_var_decay(s);
@@ -866,17 +882,17 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts)
// Reached bound on number of conflicts:
s->progress_estimate = solver_progress(s);
solver_canceluntil(s,s->root_level);
- vec_delete(&learnt_clause);
+ veci_delete(&learnt_clause);
return l_Undef;
}
- if ( s->nConfLimit && s->solver_stats.conflicts > s->nConfLimit ||
- s->nImpLimit && s->solver_stats.propagations > s->nImpLimit )
+ if ( s->nConfLimit && s->solver_stats.conflicts > s->nConfLimit ||
+ s->nInsLimit && s->solver_stats.inspects > s->nInsLimit )
{
// Reached bound on number of conflicts:
s->progress_estimate = solver_progress(s);
solver_canceluntil(s,s->root_level);
- vec_delete(&learnt_clause);
+ veci_delete(&learnt_clause);
return l_Undef;
}
@@ -899,9 +915,9 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts)
// Model found:
lbool* values = s->assigns;
int i;
- for (i = 0; i < s->size; i++) vec_push(&s->model,(void*)((int)values[i]));
+ for (i = 0; i < s->size; i++) veci_push(&s->model,(int)values[i]);
solver_canceluntil(s,s->root_level);
- vec_delete(&learnt_clause);
+ veci_delete(&learnt_clause);
return l_True;
}
@@ -922,11 +938,11 @@ solver* solver_new(void)
// initialize vectors
vec_new(&s->clauses);
vec_new(&s->learnts);
- vec_new(&s->order);
- vec_new(&s->trail_lim);
- vec_new(&s->tagged);
- vec_new(&s->stack);
- vec_new(&s->model);
+ veci_new(&s->order);
+ veci_new(&s->trail_lim);
+ veci_new(&s->tagged);
+ veci_new(&s->stack);
+ veci_new(&s->model);
// initialize arrays
s->wlists = 0;
@@ -975,6 +991,8 @@ solver* solver_new(void)
s->pMem = Asat_MmStepStart( 10 );
#endif
s->pJMan = NULL;
+ s->pPrefVars = NULL;
+ s->nPrefVars = 0;
s->timeTotal = clock();
s->timeSelect = 0;
s->timeUpdate = 0;
@@ -998,11 +1016,11 @@ void solver_delete(solver* s)
// delete vectors
vec_delete(&s->clauses);
vec_delete(&s->learnts);
- vec_delete(&s->order);
- vec_delete(&s->trail_lim);
- vec_delete(&s->tagged);
- vec_delete(&s->stack);
- vec_delete(&s->model);
+ veci_delete(&s->order);
+ veci_delete(&s->trail_lim);
+ veci_delete(&s->tagged);
+ veci_delete(&s->stack);
+ veci_delete(&s->model);
free(s->binary);
// delete arrays
@@ -1022,7 +1040,8 @@ void solver_delete(solver* s)
free(s->tags );
}
- if ( s->pJMan ) Asat_JManStop( s );
+ if ( s->pJMan ) Asat_JManStop( s );
+ if ( s->pPrefVars ) free( s->pPrefVars );
free(s);
}
@@ -1117,9 +1136,10 @@ bool solver_simplify(solver* s)
}
-bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit )
+bool solver_solve(solver* s, lit* begin, lit* end, sint64 nConfLimit, sint64 nInsLimit )
{
double nof_conflicts = 100;
+// double nof_conflicts = 1000000;
double nof_learnts = solver_nclauses(s) / 3;
lbool status = l_Undef;
lbool* values = s->assigns;
@@ -1127,7 +1147,7 @@ bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit
// set the external limits
s->nConfLimit = nConfLimit; // external limit on the number of conflicts
- s->nImpLimit = nImpLimit; // external limit on the number of implications
+ s->nInsLimit = nInsLimit; // external limit on the number of implications
for (i = begin; i < end; i++)
@@ -1160,6 +1180,7 @@ bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit
s->progress_estimate*100);
fflush(stdout);
}
+ s->nPrefDecNum = 0;
status = solver_search(s,(int)nof_conflicts, (int)nof_learnts);
nof_conflicts *= 1.5;
nof_learnts *= 1.1;
@@ -1170,9 +1191,9 @@ bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit
// printf( "Reached the limit on the number of conflicts (%d).\n", s->nConfLimit );
break;
}
- if ( s->nImpLimit && s->solver_stats.propagations > s->nImpLimit )
+ if ( s->nInsLimit && s->solver_stats.inspects > s->nInsLimit )
{
-// printf( "Reached the limit on the number of implications (%d).\n", s->nImpLimit );
+// printf( "Reached the limit on the number of implications (%d).\n", s->nInsLimit );
break;
}
}
diff --git a/src/sat/asat/solver.h b/src/sat/asat/solver.h
index 3684d259..05e9dafa 100644
--- a/src/sat/asat/solver.h
+++ b/src/sat/asat/solver.h
@@ -37,9 +37,11 @@ extern "C" {
// Simple types:
//typedef int bool;
+#ifndef __cplusplus
#ifndef bool
#define bool int
#endif
+#endif
typedef int lit;
typedef char lbool;
@@ -74,17 +76,19 @@ extern void solver_delete(solver* s);
extern bool solver_addclause(solver* s, lit* begin, lit* end);
extern bool solver_simplify(solver* s);
-extern int solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit );
+extern int solver_solve(solver* s, lit* begin, lit* end, sint64 nConfLimit, sint64 nInsLimit );
extern int * solver_get_model( solver * p, int * pVars, int nVars );
extern int solver_nvars(solver* s);
extern int solver_nclauses(solver* s);
+
// additional procedures
extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName,
lit* assumptionsBegin, lit* assumptionsEnd,
int incrementVars);
extern void Asat_SatPrintStats( FILE * pFile, solver * p );
+extern void Asat_SolverSetPrefVars( solver * s, int * pPrefVars, int nPrefVars );
// J-frontier support
extern Asat_JMan_t * Asat_JManStart( solver * pSat, void * vCircuit );
@@ -131,12 +135,12 @@ struct solver_t
clause* binary; // A temporary binary clause
lbool* tags; //
- vec tagged; // (contains: var)
- vec stack; // (contains: var)
+ veci tagged; // (contains: var)
+ veci stack; // (contains: var)
- vec order; // Variable order. (heap) (contains: var)
- vec trail_lim; // Separator indices for different decision levels in 'trail'. (contains: int)
- vec model; // If problem is solved, this vector contains the model (contains: lbool).
+ veci order; // Variable order. (heap) (contains: var)
+ veci trail_lim; // Separator indices for different decision levels in 'trail'. (contains: int)
+ veci model; // If problem is solved, this vector contains the model (contains: lbool).
int root_level; // Level of first proper decision.
int simpdb_assigns;// Number of top-level assignments at last 'simplifyDB()'.
@@ -145,8 +149,8 @@ struct solver_t
double progress_estimate;
int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything
- int nConfLimit; // external limit on the number of conflicts
- int nImpLimit; // external limit on the number of implications
+ sint64 nConfLimit; // external limit on the number of conflicts
+ sint64 nInsLimit; // external limit on the number of implications
// the memory manager
Asat_MmStep_t * pMem;
@@ -154,6 +158,12 @@ struct solver_t
// J-frontier
Asat_JMan_t * pJMan;
+ // for making decisions on some variables first
+ int nPrefDecNum;
+ int * pPrefVars;
+ int nPrefVars;
+
+ // solver statistics
stats solver_stats;
int timeTotal;
int timeSelect;
diff --git a/src/sat/asat/solver_vec.h b/src/sat/asat/solver_vec.h
index fae313d0..1ae30b0a 100644
--- a/src/sat/asat/solver_vec.h
+++ b/src/sat/asat/solver_vec.h
@@ -24,6 +24,35 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include <stdlib.h>
+// vector of 32-bit intergers (added for 64-bit portability)
+struct veci_t {
+ int size;
+ int cap;
+ int* ptr;
+};
+typedef struct veci_t veci;
+
+static inline void veci_new (veci* v) {
+ v->size = 0;
+ v->cap = 4;
+ v->ptr = (int*)malloc(sizeof(int)*v->cap);
+}
+
+static inline void veci_delete (veci* v) { free(v->ptr); }
+static inline int* veci_begin (veci* v) { return v->ptr; }
+static inline int veci_size (veci* v) { return v->size; }
+static inline void veci_resize (veci* v, int k) { v->size = k; } // only safe to shrink !!
+static inline void veci_push (veci* v, int e)
+{
+ if (v->size == v->cap) {
+ int newsize = v->cap * 2+1;
+ v->ptr = (int*)realloc(v->ptr,sizeof(int)*newsize);
+ v->cap = newsize; }
+ v->ptr[v->size++] = e;
+}
+
+
+// vector of 32- or 64-bit pointers
struct vec_t {
int size;
int cap;
@@ -50,4 +79,5 @@ static inline void vec_push (vec* v, void* e)
v->ptr[v->size++] = e;
}
+
#endif
diff --git a/src/sat/csat/csat_apis.c b/src/sat/csat/csat_apis.c
index 9184cab9..353f6c4c 100644
--- a/src/sat/csat/csat_apis.c
+++ b/src/sat/csat/csat_apis.c
@@ -39,8 +39,7 @@ struct ABC_ManagerStruct_t
Extra_MmFlex_t * pMmNames; // memory manager for signal names
// solving parameters
int mode; // 0 = resource-aware integration; 1 = brute-force SAT
- int nConfLimit; // time limit for pure SAT solving
- int nImpLimit; // time limit for pure SAT solving
+ Prove_Params_t Params; // integrated CEC parameters
// information about the target
int nog; // the numbers of gates in the target
Vec_Ptr_t * vNodes; // the gates in the target
@@ -87,9 +86,11 @@ ABC_Manager ABC_InitManager()
mng->pMmNames = Extra_MmFlexStart();
mng->vNodes = Vec_PtrAlloc( 100 );
mng->vValues = Vec_IntAlloc( 100 );
- mng->nConfLimit = ABC_DEFAULT_CONF_LIMIT;
- mng->nImpLimit = ABC_DEFAULT_IMP_LIMIT;
mng->mode = 0; // set "resource-aware integration" as the default mode
+ // set default parameters for CEC
+ Prove_ParamsSetDefault( &mng->Params );
+ // set infinite resource limit for the final mitering
+ mng->Params.nMiteringLimitLast = ABC_INFINITY;
return mng;
}
@@ -334,7 +335,7 @@ int ABC_Check_Integrity( ABC_Manager mng )
continue;
if ( Abc_ObjFanoutNum(pObj) == 0 )
{
- printf( "ABC_Check_Integrity: The network has dangling nodes.\n" );
+// printf( "ABC_Check_Integrity: The network has dangling nodes.\n" );
return 0;
}
}
@@ -361,7 +362,7 @@ int ABC_Check_Integrity( ABC_Manager mng )
***********************************************************************/
void ABC_SetTimeLimit( ABC_Manager mng, int runtime )
{
- printf( "ABC_SetTimeLimit: The resource limit is not implemented (warning).\n" );
+// printf( "ABC_SetTimeLimit: The resource limit is not implemented (warning).\n" );
}
/**Function*************************************************************
@@ -377,7 +378,7 @@ void ABC_SetTimeLimit( ABC_Manager mng, int runtime )
***********************************************************************/
void ABC_SetLearnLimit( ABC_Manager mng, int num )
{
- printf( "ABC_SetLearnLimit: The resource limit is not implemented (warning).\n" );
+// printf( "ABC_SetLearnLimit: The resource limit is not implemented (warning).\n" );
}
/**Function*************************************************************
@@ -393,7 +394,7 @@ void ABC_SetLearnLimit( ABC_Manager mng, int num )
***********************************************************************/
void ABC_SetLearnBacktrackLimit( ABC_Manager mng, int num )
{
- printf( "ABC_SetLearnBacktrackLimit: The resource limit is not implemented (warning).\n" );
+// printf( "ABC_SetLearnBacktrackLimit: The resource limit is not implemented (warning).\n" );
}
/**Function*************************************************************
@@ -409,7 +410,7 @@ void ABC_SetLearnBacktrackLimit( ABC_Manager mng, int num )
***********************************************************************/
void ABC_SetSolveBacktrackLimit( ABC_Manager mng, int num )
{
- mng->nConfLimit = num;
+ mng->Params.nMiteringLimitLast = num;
}
/**Function*************************************************************
@@ -425,7 +426,70 @@ void ABC_SetSolveBacktrackLimit( ABC_Manager mng, int num )
***********************************************************************/
void ABC_SetSolveImplicationLimit( ABC_Manager mng, int num )
{
- mng->nImpLimit = num;
+// printf( "ABC_SetSolveImplicationLimit: The resource limit is not implemented (warning).\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void ABC_SetTotalBacktrackLimit( ABC_Manager mng, uint64 num )
+{
+ mng->Params.nTotalBacktrackLimit = num;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void ABC_SetTotalInspectLimit( ABC_Manager mng, uint64 num )
+{
+ mng->Params.nTotalInspectLimit = num;
+}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+uint64 ABC_GetTotalBacktracksMade( ABC_Manager mng )
+{
+ return mng->Params.nTotalBacktracksMade;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+uint64 ABC_GetTotalInspectsMade( ABC_Manager mng )
+{
+ return mng->Params.nTotalInspectsMade;
}
/**Function*************************************************************
@@ -539,7 +603,7 @@ void ABC_AnalyzeTargets( ABC_Manager mng )
***********************************************************************/
enum CSAT_StatusT ABC_Solve( ABC_Manager mng )
{
- Prove_Params_t Params, * pParams = &Params;
+ Prove_Params_t * pParams = &mng->Params;
int RetValue, i;
// check if the target network is available
@@ -548,16 +612,9 @@ enum CSAT_StatusT ABC_Solve( ABC_Manager mng )
// try to prove the miter using a number of techniques
if ( mng->mode )
- RetValue = Abc_NtkMiterSat( mng->pTarget, mng->nConfLimit, mng->nImpLimit, 0, 0 );
+ RetValue = Abc_NtkMiterSat( mng->pTarget, (sint64)pParams->nMiteringLimitLast, (sint64)0, 0, 0, NULL, NULL );
else
- {
- // set default parameters for CEC
- Prove_ParamsSetDefault( pParams );
- // set infinite resource limit for the final mitering
- pParams->nMiteringLimitLast = ABC_INFINITY;
- // call the checker
RetValue = Abc_NtkMiterProve( &mng->pTarget, pParams );
- }
// analyze the result
mng->pResult = ABC_TargetResAlloc( Abc_NtkCiNum(mng->pTarget) );
diff --git a/src/sat/csat/csat_apis.h b/src/sat/csat/csat_apis.h
index d2fa770e..b80eddbf 100644
--- a/src/sat/csat/csat_apis.h
+++ b/src/sat/csat/csat_apis.h
@@ -182,6 +182,11 @@ extern void ABC_SetSolveBacktrackLimit(ABC_Manager mng, int num
extern void ABC_SetLearnBacktrackLimit(ABC_Manager mng, int num);
extern void ABC_EnableDump(ABC_Manager mng, char* dump_file);
+extern void ABC_SetTotalBacktrackLimit( ABC_Manager mng, uint64 num );
+extern void ABC_SetTotalInspectLimit( ABC_Manager mng, uint64 num );
+extern uint64 ABC_GetTotalBacktracksMade( ABC_Manager mng );
+extern uint64 ABC_GetTotalInspectsMade( ABC_Manager mng );
+
// the meaning of the parameters are:
// nog: number of gates that are in the targets
// names: name array of gates
diff --git a/src/sat/fraig/fraig.h b/src/sat/fraig/fraig.h
index d6215465..84363efe 100644
--- a/src/sat/fraig/fraig.h
+++ b/src/sat/fraig/fraig.h
@@ -27,6 +27,8 @@ extern "C" {
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
+#include "solver.h"
+
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
@@ -49,8 +51,6 @@ struct Fraig_ParamsStruct_t_
int nPatsDyna; // the number of words of dynamic simulation info
int nBTLimit; // the max number of backtracks to perform
int nSeconds; // the timeout for the final proof
- int nConfLimit;
- int nImpLimit;
int fFuncRed; // performs only one level hashing
int fFeedBack; // enables solver feedback
int fDist1Pats; // enables distance-1 patterns
@@ -60,31 +60,39 @@ struct Fraig_ParamsStruct_t_
int fVerbose; // the verbosiness flag
int fVerboseP; // the verbosiness flag (for proof reporting)
int fInternal; // is set to 1 for internal fraig calls
+ int nConfLimit; // the limit on the number of conflicts
+ sint64 nInspLimit; // the limit on the number of inspections
};
struct Prove_ParamsStruct_t_
{
// general parameters
- int fUseFraiging; // enables fraiging
- int fUseRewriting; // enables rewriting
- int fUseBdds; // enables BDD construction when other methods fail
- int fVerbose; // prints verbose stats
+ int fUseFraiging; // enables fraiging
+ int fUseRewriting; // enables rewriting
+ int fUseBdds; // enables BDD construction when other methods fail
+ int fVerbose; // prints verbose stats
// iterations
- int nItersMax; // the number of iterations
+ int nItersMax; // the number of iterations
// mitering
- int nMiteringLimitStart; // starting mitering limit
- float nMiteringLimitMulti; // multiplicative coefficient to increase the limit in each iteration
+ int nMiteringLimitStart; // starting mitering limit
+ float nMiteringLimitMulti; // multiplicative coefficient to increase the limit in each iteration
// rewriting
- int nRewritingLimitStart; // the number of rewriting iterations
- float nRewritingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
+ int nRewritingLimitStart; // the number of rewriting iterations
+ float nRewritingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
// fraiging
- int nFraigingLimitStart; // starting backtrack(conflict) limit
- float nFraigingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
+ int nFraigingLimitStart; // starting backtrack(conflict) limit
+ float nFraigingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
// last-gasp BDD construction
- int nBddSizeLimit; // the number of BDD nodes when construction is aborted
- int fBddReorder; // enables dynamic BDD variable reordering
+ int nBddSizeLimit; // the number of BDD nodes when construction is aborted
+ int fBddReorder; // enables dynamic BDD variable reordering
// last-gasp mitering
- int nMiteringLimitLast; // final mitering limit
+ int nMiteringLimitLast; // final mitering limit
+ // global SAT solver limits
+ sint64 nTotalBacktrackLimit; // global limit on the number of backtracks
+ sint64 nTotalInspectLimit; // global limit on the number of clause inspects
+ // global resources applied
+ sint64 nTotalBacktracksMade; // the total number of backtracks made
+ sint64 nTotalInspectsMade; // the total number of inspects made
};
////////////////////////////////////////////////////////////////////////
@@ -137,6 +145,8 @@ extern int Fraig_ManReadPatternNumRandom( Fraig_Man_t * p );
extern int Fraig_ManReadPatternNumDynamic( Fraig_Man_t * p );
extern int Fraig_ManReadPatternNumDynamicFiltered( Fraig_Man_t * p );
extern int Fraig_ManReadSatFails( Fraig_Man_t * p );
+extern int Fraig_ManReadConflicts( Fraig_Man_t * p );
+extern int Fraig_ManReadInspects( Fraig_Man_t * p );
extern void Fraig_ManSetFuncRed( Fraig_Man_t * p, int fFuncRed );
extern void Fraig_ManSetFeedBack( Fraig_Man_t * p, int fFeedBack );
diff --git a/src/sat/fraig/fraigApi.c b/src/sat/fraig/fraigApi.c
index b4bdbcab..79a7c224 100644
--- a/src/sat/fraig/fraigApi.c
+++ b/src/sat/fraig/fraigApi.c
@@ -66,6 +66,10 @@ int Fraig_ManReadPatternNumDynamic( Fraig_Man_t * p ) {
int Fraig_ManReadPatternNumDynamicFiltered( Fraig_Man_t * p ) { return p->iPatsPerm; }
// returns the number of times FRAIG package timed out
int Fraig_ManReadSatFails( Fraig_Man_t * p ) { return p->nSatFailsReal; }
+// returns the number of conflicts in the SAT solver
+int Fraig_ManReadConflicts( Fraig_Man_t * p ) { return p->pSat? Msat_SolverReadBackTracks(p->pSat) : 0; }
+// returns the number of inspections in the SAT solver
+int Fraig_ManReadInspects( Fraig_Man_t * p ) { return p->pSat? Msat_SolverReadInspects(p->pSat) : 0; }
/**Function*************************************************************
diff --git a/src/sat/fraig/fraigCanon.c b/src/sat/fraig/fraigCanon.c
index 4ebb9a9f..89bc924f 100644
--- a/src/sat/fraig/fraigCanon.c
+++ b/src/sat/fraig/fraigCanon.c
@@ -49,6 +49,7 @@
Fraig_Node_t * Fraig_NodeAndCanon( Fraig_Man_t * pMan, Fraig_Node_t * p1, Fraig_Node_t * p2 )
{
Fraig_Node_t * pNodeNew, * pNodeOld, * pNodeRepr;
+ int fUseSatCheck;
// int RetValue;
// check for trivial cases
@@ -167,7 +168,8 @@ Fraig_Node_t * Fraig_NodeAndCanon( Fraig_Man_t * pMan, Fraig_Node_t * p1, Fraig_
// there is another node which looks the same according to simulation
// use SAT to resolve the ambiguity
- if ( Fraig_NodeIsEquivalent( pMan, pNodeOld, pNodeNew, pMan->nBTLimit, 1000000 ) )
+ fUseSatCheck = (pMan->nInspLimit == 0 || Fraig_ManReadInspects(pMan) < pMan->nInspLimit);
+ if ( fUseSatCheck && Fraig_NodeIsEquivalent( pMan, pNodeOld, pNodeNew, pMan->nBTLimit, 1000000 ) )
{
// set the node to be equivalent with this node
// to prevent loops, only set if the old node is not in the TFI of the new node
diff --git a/src/sat/fraig/fraigInt.h b/src/sat/fraig/fraigInt.h
index 8e016331..9c6e0d47 100644
--- a/src/sat/fraig/fraigInt.h
+++ b/src/sat/fraig/fraigInt.h
@@ -66,7 +66,7 @@
// the bit masks
#define FRAIG_MASK(n) ((~((unsigned)0)) >> (32-(n)))
#define FRAIG_FULL (~((unsigned)0))
-#define FRAIG_NUM_WORDS(n) ((n)/32 + (((n)%32) > 0))
+#define FRAIG_NUM_WORDS(n) (((n)>>5) + (((n)&31) > 0))
// maximum/minimum operators
#define FRAIG_MIN(a,b) (((a) < (b))? (a) : (b))
@@ -152,6 +152,7 @@ struct Fraig_ManStruct_t_
int fTryProve; // tries to solve the final miter
int fVerbose; // the verbosiness flag
int fVerboseP; // the verbosiness flag
+ sint64 nInspLimit; // the inspection limit
int nTravIds; // the traversal counter
int nTravIds2; // the traversal counter
diff --git a/src/sat/fraig/fraigMan.c b/src/sat/fraig/fraigMan.c
index 3268ac3a..ffb51a07 100644
--- a/src/sat/fraig/fraigMan.c
+++ b/src/sat/fraig/fraigMan.c
@@ -42,10 +42,12 @@ int timeAssign;
***********************************************************************/
void Prove_ParamsSetDefault( Prove_Params_t * pParams )
{
+ // clean the parameter structure
+ memset( pParams, 0, sizeof(Prove_Params_t) );
// general parameters
pParams->fUseFraiging = 1; // enables fraiging
pParams->fUseRewriting = 1; // enables rewriting
- pParams->fUseBdds = 1; // enables BDD construction when other methods fail
+ pParams->fUseBdds = 0; // enables BDD construction when other methods fail
pParams->fVerbose = 0; // prints verbose stats
// iterations
pParams->nItersMax = 6; // the number of iterations
@@ -63,6 +65,9 @@ void Prove_ParamsSetDefault( Prove_Params_t * pParams )
pParams->fBddReorder = 1; // enables dynamic BDD variable reordering
// last-gasp mitering
pParams->nMiteringLimitLast = 1000000; // final mitering limit
+ // global SAT solver limits
+ pParams->nTotalBacktrackLimit = 0; // global limit on the number of backtracks
+ pParams->nTotalInspectLimit = 0; // global limit on the number of clause inspects
}
/**Function*************************************************************
@@ -92,6 +97,8 @@ void Fraig_ParamsSetDefault( Fraig_Params_t * pParams )
pParams->fVerbose = 0; // the verbosiness flag
pParams->fVerboseP = 0; // the verbose flag for reporting the proof
pParams->fInternal = 0; // the flag indicates the internal run
+ pParams->nConfLimit = 0; // the limit on the number of conflicts
+ pParams->nInspLimit = 0; // the limit on the number of inspections
}
/**Function*************************************************************
@@ -121,6 +128,8 @@ void Fraig_ParamsSetDefaultFull( Fraig_Params_t * pParams )
pParams->fVerbose = 0; // the verbosiness flag
pParams->fVerboseP = 0; // the verbose flag for reporting the proof
pParams->fInternal = 0; // the flag indicates the internal run
+ pParams->nConfLimit = 0; // the limit on the number of conflicts
+ pParams->nInspLimit = 0; // the limit on the number of inspections
}
/**Function*************************************************************
@@ -176,6 +185,7 @@ Fraig_Man_t * Fraig_ManCreate( Fraig_Params_t * pParams )
p->fTryProve = pParams->fTryProve; // disable accumulation of structural choices (keeps only the first choice)
p->fVerbose = pParams->fVerbose; // disable verbose output
p->fVerboseP = pParams->fVerboseP; // disable verbose output
+ p->nInspLimit = pParams->nInspLimit; // the limit on the number of inspections
// start memory managers
p->mmNodes = Fraig_MemFixedStart( sizeof(Fraig_Node_t) );
diff --git a/src/sat/msat/msat.h b/src/sat/msat/msat.h
index 94416a5d..5f8603a7 100644
--- a/src/sat/msat/msat.h
+++ b/src/sat/msat/msat.h
@@ -97,6 +97,7 @@ extern int * Msat_SolverReadAssignsArray( Msat_Solver_t * p );
extern int * Msat_SolverReadModelArray( Msat_Solver_t * p );
extern unsigned Msat_SolverReadTruth( Msat_Solver_t * p );
extern int Msat_SolverReadBackTracks( Msat_Solver_t * p );
+extern int Msat_SolverReadInspects( Msat_Solver_t * p );
extern void Msat_SolverSetVerbosity( Msat_Solver_t * p, int fVerbose );
extern void Msat_SolverSetProofWriting( Msat_Solver_t * p, int fProof );
extern void Msat_SolverSetVarTypeA( Msat_Solver_t * p, int Var );
diff --git a/src/sat/msat/msatInt.h b/src/sat/msat/msatInt.h
index 3dfe2109..03e7b873 100644
--- a/src/sat/msat/msatInt.h
+++ b/src/sat/msat/msatInt.h
@@ -56,10 +56,10 @@ typedef long long int64;
#define ALLOC(type, num) \
((type *) malloc(sizeof(type) * (num)))
#define REALLOC(type, obj, num) \
- (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \
- ((type *) malloc(sizeof(type) * (num)))
+ ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
+ ((type *) malloc(sizeof(type) * (num))))
#define FREE(obj) \
- ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
+ ((obj) ? (free((char *)(obj)), (obj) = 0) : 0)
// By default, custom memory management is used
// which guarantees constant time allocation/deallocation
diff --git a/src/sat/msat/msatSolverApi.c b/src/sat/msat/msatSolverApi.c
index 4a721487..e3d85774 100644
--- a/src/sat/msat/msatSolverApi.c
+++ b/src/sat/msat/msatSolverApi.c
@@ -41,26 +41,27 @@ static void Msat_SolverSetupTruthTables( unsigned uTruths[][2] );
SeeAlso []
***********************************************************************/
-int Msat_SolverReadVarNum( Msat_Solver_t * p ) { return p->nVars; }
-int Msat_SolverReadClauseNum( Msat_Solver_t * p ) { return p->nClauses; }
-int Msat_SolverReadVarAllocNum( Msat_Solver_t * p ) { return p->nVarsAlloc;}
+int Msat_SolverReadVarNum( Msat_Solver_t * p ) { return p->nVars; }
+int Msat_SolverReadClauseNum( Msat_Solver_t * p ) { return p->nClauses; }
+int Msat_SolverReadVarAllocNum( Msat_Solver_t * p ) { return p->nVarsAlloc; }
int Msat_SolverReadDecisionLevel( Msat_Solver_t * p ) { return Msat_IntVecReadSize(p->vTrailLim); }
-int * Msat_SolverReadDecisionLevelArray( Msat_Solver_t * p ) { return p->pLevel; }
-Msat_Clause_t ** Msat_SolverReadReasonArray( Msat_Solver_t * p ) { return p->pReasons; }
+int * Msat_SolverReadDecisionLevelArray( Msat_Solver_t * p ) { return p->pLevel; }
+Msat_Clause_t ** Msat_SolverReadReasonArray( Msat_Solver_t * p ) { return p->pReasons; }
Msat_Lit_t Msat_SolverReadVarValue( Msat_Solver_t * p, Msat_Var_t Var ) { return p->pAssigns[Var]; }
-Msat_ClauseVec_t * Msat_SolverReadLearned( Msat_Solver_t * p ) { return p->vLearned; }
-Msat_ClauseVec_t ** Msat_SolverReadWatchedArray( Msat_Solver_t * p ) { return p->pvWatched; }
-int * Msat_SolverReadAssignsArray( Msat_Solver_t * p ) { return p->pAssigns; }
-int * Msat_SolverReadModelArray( Msat_Solver_t * p ) { return p->pModel; }
-int Msat_SolverReadBackTracks( Msat_Solver_t * p ) { return p->nBackTracks; }
-Msat_MmStep_t * Msat_SolverReadMem( Msat_Solver_t * p ) { return p->pMem; }
-int * Msat_SolverReadSeenArray( Msat_Solver_t * p ) { return p->pSeen; }
-int Msat_SolverIncrementSeenId( Msat_Solver_t * p ) { return ++p->nSeenId; }
+Msat_ClauseVec_t * Msat_SolverReadLearned( Msat_Solver_t * p ) { return p->vLearned; }
+Msat_ClauseVec_t ** Msat_SolverReadWatchedArray( Msat_Solver_t * p ) { return p->pvWatched; }
+int * Msat_SolverReadAssignsArray( Msat_Solver_t * p ) { return p->pAssigns; }
+int * Msat_SolverReadModelArray( Msat_Solver_t * p ) { return p->pModel; }
+int Msat_SolverReadBackTracks( Msat_Solver_t * p ) { return (int)p->Stats.nConflicts; }
+int Msat_SolverReadInspects( Msat_Solver_t * p ) { return (int)p->Stats.nInspects; }
+Msat_MmStep_t * Msat_SolverReadMem( Msat_Solver_t * p ) { return p->pMem; }
+int * Msat_SolverReadSeenArray( Msat_Solver_t * p ) { return p->pSeen; }
+int Msat_SolverIncrementSeenId( Msat_Solver_t * p ) { return ++p->nSeenId; }
void Msat_SolverSetVerbosity( Msat_Solver_t * p, int fVerbose ) { p->fVerbose = fVerbose; }
-void Msat_SolverClausesIncrement( Msat_Solver_t * p ) { p->nClausesAlloc++; }
-void Msat_SolverClausesDecrement( Msat_Solver_t * p ) { p->nClausesAlloc--; }
-void Msat_SolverClausesIncrementL( Msat_Solver_t * p ) { p->nClausesAllocL++; }
-void Msat_SolverClausesDecrementL( Msat_Solver_t * p ) { p->nClausesAllocL--; }
+void Msat_SolverClausesIncrement( Msat_Solver_t * p ) { p->nClausesAlloc++; }
+void Msat_SolverClausesDecrement( Msat_Solver_t * p ) { p->nClausesAlloc--; }
+void Msat_SolverClausesIncrementL( Msat_Solver_t * p ) { p->nClausesAllocL++; }
+void Msat_SolverClausesDecrementL( Msat_Solver_t * p ) { p->nClausesAllocL--; }
void Msat_SolverMarkLastClauseTypeA( Msat_Solver_t * p ) { Msat_ClauseSetTypeA( Msat_ClauseVecReadEntry( p->vClauses, Msat_ClauseVecReadSize(p->vClauses)-1 ), 1 ); }
void Msat_SolverMarkClausesStart( Msat_Solver_t * p ) { p->nClausesStart = Msat_ClauseVecReadSize(p->vClauses); }
diff --git a/src/opt/xyz/xyzInt.h b/src/temp/esop/esop.h
index 656612aa..d6cdff71 100644
--- a/src/opt/xyz/xyzInt.h
+++ b/src/temp/esop/esop.h
@@ -1,6 +1,6 @@
/**CFile****************************************************************
- FileName [xyzInt.h]
+ FileName [esop.h]
SystemName [ABC: Logic synthesis and verification system.]
@@ -14,96 +14,119 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: xyzInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: esop.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
-#include "abc.h"
+#ifndef __ESOP_H__
+#define __ESOP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stdio.h"
+#include "vec.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-typedef struct Min_Man_t_ Min_Man_t;
-typedef struct Min_Cube_t_ Min_Cube_t;
+typedef struct Esop_Man_t_ Esop_Man_t;
+typedef struct Esop_Cube_t_ Esop_Cube_t;
+typedef struct Esop_MmFixed_t_ Esop_MmFixed_t;
-struct Min_Man_t_
+struct Esop_Man_t_
{
int nVars; // the number of vars
int nWords; // the number of words
- Extra_MmFixed_t * pMemMan; // memory manager for cubes
+ Esop_MmFixed_t * pMemMan1; // memory manager for cubes
+ Esop_MmFixed_t * pMemMan2; // memory manager for cubes
+ Esop_MmFixed_t * pMemMan4; // memory manager for cubes
+ Esop_MmFixed_t * pMemMan8; // memory manager for cubes
// temporary cubes
- Min_Cube_t * pOne0; // tautology cube
- Min_Cube_t * pOne1; // tautology cube
- Min_Cube_t * pTriv0[2]; // trivial cube
- Min_Cube_t * pTriv1[2]; // trivial cube
- Min_Cube_t * pTemp; // cube for computing the distance
- Min_Cube_t * pBubble; // cube used as a separator
+ Esop_Cube_t * pOne0; // tautology cube
+ Esop_Cube_t * pOne1; // tautology cube
+ Esop_Cube_t * pTriv0; // trivial cube
+ Esop_Cube_t * pTriv1; // trivial cube
+ Esop_Cube_t * pTemp; // cube for computing the distance
+ Esop_Cube_t * pBubble; // cube used as a separator
// temporary storage for the new cover
int nCubes; // the number of cubes
- Min_Cube_t ** ppStore; // storage for cubes by number of literals
+ Esop_Cube_t ** ppStore; // storage for cubes by number of literals
};
-struct Min_Cube_t_
+struct Esop_Cube_t_
{
- Min_Cube_t * pNext; // the pointer to the next cube in the cover
+ Esop_Cube_t * pNext; // the pointer to the next cube in the cover
unsigned nVars : 10; // the number of variables
unsigned nWords : 12; // the number of machine words
unsigned nLits : 10; // the number of literals in the cube
unsigned uData[1]; // the bit-data for the cube
};
+#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
+#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
+#define REALLOC(type, obj, num) \
+ ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
+ ((type *) malloc(sizeof(type) * (num))))
// iterators through the entries in the linked lists of cubes
-#define Min_CoverForEachCube( pCover, pCube ) \
+#define Esop_CoverForEachCube( pCover, pCube ) \
for ( pCube = pCover; \
pCube; \
pCube = pCube->pNext )
-#define Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \
+#define Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \
for ( pCube = pCover, \
pCube2 = pCube? pCube->pNext: NULL; \
pCube; \
pCube = pCube2, \
pCube2 = pCube? pCube->pNext: NULL )
-#define Min_CoverForEachCubePrev( pCover, pCube, ppPrev ) \
+#define Esop_CoverForEachCubePrev( pCover, pCube, ppPrev ) \
for ( pCube = pCover, \
ppPrev = &(pCover); \
pCube; \
ppPrev = &pCube->pNext, \
pCube = pCube->pNext )
+
// macros to get hold of bits and values in the cubes
-static inline int Min_CubeHasBit( Min_Cube_t * p, int i ) { return (p->uData[(i)>>5] & (1<<((i) & 31))) > 0; }
-static inline void Min_CubeSetBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] |= (1<<((i) & 31)); }
-static inline void Min_CubeXorBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] ^= (1<<((i) & 31)); }
-static inline int Min_CubeGetVar( Min_Cube_t * p, int Var ) { return 3 & (p->uData[(2*Var)>>5] >> ((2*Var) & 31)); }
-static inline void Min_CubeXorVar( Min_Cube_t * p, int Var, int Value ) { p->uData[(2*Var)>>5] ^= (Value<<((2*Var) & 31)); }
-
-/*=== xyzMinEsop.c ==========================================================*/
-extern void Min_EsopMinimize( Min_Man_t * p );
-extern void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube );
-/*=== xyzMinSop.c ==========================================================*/
-extern void Min_SopMinimize( Min_Man_t * p );
-extern void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube );
-/*=== xyzMinMan.c ==========================================================*/
-extern Min_Man_t * Min_ManAlloc( int nVars );
-extern void Min_ManClean( Min_Man_t * p, int nSupp );
-extern void Min_ManFree( Min_Man_t * p );
-/*=== xyzMinUtil.c ==========================================================*/
-extern void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube );
-extern void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover );
-extern void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p );
-extern void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop );
-extern void Min_CoverCheck( Min_Man_t * p );
-extern int Min_CubeCheck( Min_Cube_t * pCube );
-extern Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize );
-extern void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover );
-extern int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover );
+static inline int Esop_CubeHasBit( Esop_Cube_t * p, int i ) { return (p->uData[i >> 5] & (1<<(i & 31))) > 0; }
+static inline void Esop_CubeSetBit( Esop_Cube_t * p, int i ) { p->uData[i >> 5] |= (1<<(i & 31)); }
+static inline void Esop_CubeXorBit( Esop_Cube_t * p, int i ) { p->uData[i >> 5] ^= (1<<(i & 31)); }
+static inline int Esop_CubeGetVar( Esop_Cube_t * p, int Var ) { return 3 & (p->uData[(Var<<1)>>5] >> ((Var<<1) & 31)); }
+static inline void Esop_CubeXorVar( Esop_Cube_t * p, int Var, int Value ) { p->uData[(Var<<1)>>5] ^= (Value<<((Var<<1) & 31)); }
+static inline int Esop_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
+
+/*=== esopMem.c ===========================================================*/
+extern Esop_MmFixed_t * Esop_MmFixedStart( int nEntrySize );
+extern void Esop_MmFixedStop( Esop_MmFixed_t * p, int fVerbose );
+extern char * Esop_MmFixedEntryFetch( Esop_MmFixed_t * p );
+extern void Esop_MmFixedEntryRecycle( Esop_MmFixed_t * p, char * pEntry );
+extern void Esop_MmFixedRestart( Esop_MmFixed_t * p );
+extern int Esop_MmFixedReadMemUsage( Esop_MmFixed_t * p );
+/*=== esopMin.c ===========================================================*/
+extern void Esop_EsopMinimize( Esop_Man_t * p );
+extern void Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube );
+/*=== esopMan.c ===========================================================*/
+extern Esop_Man_t * Esop_ManAlloc( int nVars );
+extern void Esop_ManClean( Esop_Man_t * p, int nSupp );
+extern void Esop_ManFree( Esop_Man_t * p );
+/*=== esopUtil.c ===========================================================*/
+extern void Esop_CubeWrite( FILE * pFile, Esop_Cube_t * pCube );
+extern void Esop_CoverWrite( FILE * pFile, Esop_Cube_t * pCover );
+extern void Esop_CoverWriteStore( FILE * pFile, Esop_Man_t * p );
+extern void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop );
+extern void Esop_CoverCheck( Esop_Man_t * p );
+extern int Esop_CubeCheck( Esop_Cube_t * pCube );
+extern Esop_Cube_t * Esop_CoverCollect( Esop_Man_t * p, int nSuppSize );
+extern void Esop_CoverExpand( Esop_Man_t * p, Esop_Cube_t * pCover );
+extern int Esop_CoverSuppVarNum( Esop_Man_t * p, Esop_Cube_t * pCover );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-
+
/**Function*************************************************************
Synopsis [Creates the cube.]
@@ -115,10 +138,17 @@ extern int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover );
SeeAlso []
***********************************************************************/
-static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p )
+static inline Esop_Cube_t * Esop_CubeAlloc( Esop_Man_t * p )
{
- Min_Cube_t * pCube;
- pCube = (Min_Cube_t *)Extra_MmFixedEntryFetch( p->pMemMan );
+ Esop_Cube_t * pCube;
+ if ( p->nWords <= 1 )
+ pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan1 );
+ else if ( p->nWords <= 2 )
+ pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan2 );
+ else if ( p->nWords <= 4 )
+ pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan4 );
+ else if ( p->nWords <= 8 )
+ pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan8 );
pCube->pNext = NULL;
pCube->nVars = p->nVars;
pCube->nWords = p->nWords;
@@ -138,11 +168,11 @@ static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p )
SeeAlso []
***********************************************************************/
-static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl )
+static inline Esop_Cube_t * Esop_CubeAllocVar( Esop_Man_t * p, int iVar, int fCompl )
{
- Min_Cube_t * pCube;
- pCube = Min_CubeAlloc( p );
- Min_CubeXorBit( pCube, iVar*2+fCompl );
+ Esop_Cube_t * pCube;
+ pCube = Esop_CubeAlloc( p );
+ Esop_CubeXorBit( pCube, iVar*2+fCompl );
pCube->nLits = 1;
return pCube;
}
@@ -158,10 +188,10 @@ static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl
SeeAlso []
***********************************************************************/
-static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy )
+static inline Esop_Cube_t * Esop_CubeDup( Esop_Man_t * p, Esop_Cube_t * pCopy )
{
- Min_Cube_t * pCube;
- pCube = Min_CubeAlloc( p );
+ Esop_Cube_t * pCube;
+ pCube = Esop_CubeAlloc( p );
memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords );
pCube->nLits = pCopy->nLits;
return pCube;
@@ -178,9 +208,16 @@ static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy )
SeeAlso []
***********************************************************************/
-static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube )
+static inline void Esop_CubeRecycle( Esop_Man_t * p, Esop_Cube_t * pCube )
{
- Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube );
+ if ( pCube->nWords <= 1 )
+ Esop_MmFixedEntryRecycle( p->pMemMan1, (char *)pCube );
+ else if ( pCube->nWords <= 2 )
+ Esop_MmFixedEntryRecycle( p->pMemMan2, (char *)pCube );
+ else if ( pCube->nWords <= 4 )
+ Esop_MmFixedEntryRecycle( p->pMemMan4, (char *)pCube );
+ else if ( pCube->nWords <= 8 )
+ Esop_MmFixedEntryRecycle( p->pMemMan8, (char *)pCube );
}
/**Function*************************************************************
@@ -194,11 +231,48 @@ static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube )
SeeAlso []
***********************************************************************/
-static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover )
+static inline void Esop_CoverRecycle( Esop_Man_t * p, Esop_Cube_t * pCover )
{
- Min_Cube_t * pCube, * pCube2;
- Min_CoverForEachCubeSafe( pCover, pCube, pCube2 )
- Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube );
+ Esop_Cube_t * pCube, * pCube2;
+ if ( pCover == NULL )
+ return;
+ if ( pCover->nWords <= 1 )
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Esop_MmFixedEntryRecycle( p->pMemMan1, (char *)pCube );
+ else if ( pCover->nWords <= 2 )
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Esop_MmFixedEntryRecycle( p->pMemMan2, (char *)pCube );
+ else if ( pCover->nWords <= 4 )
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Esop_MmFixedEntryRecycle( p->pMemMan4, (char *)pCube );
+ else if ( pCover->nWords <= 8 )
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Esop_MmFixedEntryRecycle( p->pMemMan8, (char *)pCube );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the cube cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Esop_Cube_t * Esop_CoverDup( Esop_Man_t * p, Esop_Cube_t * pCover )
+{
+ Esop_Cube_t * pCube, * pCubeNew;
+ Esop_Cube_t * pCoverNew = NULL, ** ppTail = &pCoverNew;
+ Esop_CoverForEachCube( pCover, pCube )
+ {
+ pCubeNew = Esop_CubeDup( p, pCube );
+ *ppTail = pCubeNew;
+ ppTail = &pCubeNew->pNext;
+ }
+ *ppTail = NULL;
+ return pCoverNew;
}
@@ -213,7 +287,7 @@ static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover )
SeeAlso []
***********************************************************************/
-static inline int Min_CubeCountLits( Min_Cube_t * pCube )
+static inline int Esop_CubeCountLits( Esop_Cube_t * pCube )
{
unsigned uData;
int Count = 0, i, w;
@@ -238,7 +312,7 @@ static inline int Min_CubeCountLits( Min_Cube_t * pCube )
SeeAlso []
***********************************************************************/
-static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits )
+static inline void Esop_CubeGetLits( Esop_Cube_t * pCube, Vec_Int_t * vLits )
{
unsigned uData;
int i, w;
@@ -263,11 +337,11 @@ static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits )
SeeAlso []
***********************************************************************/
-static inline int Min_CoverCountCubes( Min_Cube_t * pCover )
+static inline int Esop_CoverCountCubes( Esop_Cube_t * pCover )
{
- Min_Cube_t * pCube;
+ Esop_Cube_t * pCube;
int Count = 0;
- Min_CoverForEachCube( pCover, pCube )
+ Esop_CoverForEachCube( pCover, pCube )
Count++;
return Count;
}
@@ -284,7 +358,7 @@ static inline int Min_CoverCountCubes( Min_Cube_t * pCover )
SeeAlso []
***********************************************************************/
-static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
+static inline int Esop_CubesDisjoint( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
{
unsigned uData;
int i;
@@ -310,7 +384,7 @@ static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
SeeAlso []
***********************************************************************/
-static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube, Vec_Int_t * vVars )
+static inline void Esop_CoverGetDisjVars( Esop_Cube_t * pThis, Esop_Cube_t * pCube, Vec_Int_t * vVars )
{
unsigned uData;
int i, w;
@@ -338,7 +412,7 @@ static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube,
SeeAlso []
***********************************************************************/
-static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Min_Cube_t * pTemp )
+static inline int Esop_CubesDistOne( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1, Esop_Cube_t * pTemp )
{
unsigned uData;
int i, fFound = 0;
@@ -361,9 +435,9 @@ static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Mi
if ( fFound == 0 )
{
printf( "\n" );
- Min_CubeWrite( stdout, pCube0 );
- Min_CubeWrite( stdout, pCube1 );
- printf( "Error: Min_CubesDistOne() looks at two equal cubes!\n" );
+ Esop_CubeWrite( stdout, pCube0 );
+ Esop_CubeWrite( stdout, pCube1 );
+ printf( "Error: Esop_CubesDistOne() looks at two equal cubes!\n" );
}
return 1;
}
@@ -379,7 +453,7 @@ static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Mi
SeeAlso []
***********************************************************************/
-static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, int * pVar0, int * pVar1 )
+static inline int Esop_CubesDistTwo( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1, int * pVar0, int * pVar1 )
{
unsigned uData;//, uData2;
int i, k, Var0 = -1, Var1 = -1;
@@ -427,9 +501,9 @@ static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, in
if ( Var0 == -1 || Var1 == -1 )
{
printf( "\n" );
- Min_CubeWrite( stdout, pCube0 );
- Min_CubeWrite( stdout, pCube1 );
- printf( "Error: Min_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" );
+ Esop_CubeWrite( stdout, pCube0 );
+ Esop_CubeWrite( stdout, pCube1 );
+ printf( "Error: Esop_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" );
}
return 0;
}
@@ -445,15 +519,15 @@ static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, in
SeeAlso []
***********************************************************************/
-static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
+static inline Esop_Cube_t * Esop_CubesProduct( Esop_Man_t * p, Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
{
- Min_Cube_t * pCube;
+ Esop_Cube_t * pCube;
int i;
assert( pCube0->nVars == pCube1->nVars );
- pCube = Min_CubeAlloc( p );
+ pCube = Esop_CubeAlloc( p );
for ( i = 0; i < p->nWords; i++ )
pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i];
- pCube->nLits = Min_CubeCountLits( pCube );
+ pCube->nLits = Esop_CubeCountLits( pCube );
return pCube;
}
@@ -468,15 +542,15 @@ static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0,
SeeAlso []
***********************************************************************/
-static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
+static inline Esop_Cube_t * Esop_CubesXor( Esop_Man_t * p, Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
{
- Min_Cube_t * pCube;
+ Esop_Cube_t * pCube;
int i;
assert( pCube0->nVars == pCube1->nVars );
- pCube = Min_CubeAlloc( p );
+ pCube = Esop_CubeAlloc( p );
for ( i = 0; i < p->nWords; i++ )
pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i];
- pCube->nLits = Min_CubeCountLits( pCube );
+ pCube->nLits = Esop_CubeCountLits( pCube );
return pCube;
}
@@ -491,7 +565,7 @@ static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min
SeeAlso []
***********************************************************************/
-static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
+static inline int Esop_CubesAreEqual( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
{
int i;
for ( i = 0; i < (int)pCube0->nWords; i++ )
@@ -511,7 +585,7 @@ static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
SeeAlso []
***********************************************************************/
-static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
+static inline int Esop_CubeIsContained( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
{
int i;
for ( i = 0; i < (int)pCube0->nWords; i++ )
@@ -531,7 +605,7 @@ static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1
SeeAlso []
***********************************************************************/
-static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, Min_Cube_t * pMask )
+static inline void Esop_CubesTransform( Esop_Cube_t * pCube, Esop_Cube_t * pDist, Esop_Cube_t * pMask )
{
int w;
for ( w = 0; w < (int)pCube->nWords; w++ )
@@ -552,7 +626,7 @@ static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, M
SeeAlso []
***********************************************************************/
-static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist )
+static inline void Esop_CubesTransformOr( Esop_Cube_t * pCube, Esop_Cube_t * pDist )
{
int w;
for ( w = 0; w < (int)pCube->nWords; w++ )
@@ -572,22 +646,22 @@ static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist
SeeAlso []
***********************************************************************/
-static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCover )
+static inline void Esop_CoverExpandRemoveEqual( Esop_Man_t * p, Esop_Cube_t * pCover )
{
- Min_Cube_t * pCube, * pCube2, * pThis;
+ Esop_Cube_t * pCube, * pCube2, * pThis;
if ( pCover == NULL )
{
- Min_ManClean( p, p->nVars );
+ Esop_ManClean( p, p->nVars );
return;
}
- Min_ManClean( p, pCover->nVars );
- Min_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Esop_ManClean( p, pCover->nVars );
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
{
// go through the linked list
- Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
- if ( Min_CubesAreEqual( pCube, pThis ) )
+ Esop_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
+ if ( Esop_CubesAreEqual( pCube, pThis ) )
{
- Min_CubeRecycle( p, pCube );
+ Esop_CubeRecycle( p, pCube );
break;
}
if ( pThis != NULL )
@@ -609,32 +683,38 @@ static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCove
SeeAlso []
***********************************************************************/
-static inline int Min_CoverContainsCube( Min_Man_t * p, Min_Cube_t * pCube )
+static inline int Esop_CoverContainsCube( Esop_Man_t * p, Esop_Cube_t * pCube )
{
- Min_Cube_t * pThis;
+ Esop_Cube_t * pThis;
int i;
/*
// this cube cannot be equal to any cube
- Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
+ Esop_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
{
- if ( Min_CubesAreEqual( pCube, pThis ) )
+ if ( Esop_CubesAreEqual( pCube, pThis ) )
{
- Min_CubeWrite( stdout, pCube );
+ Esop_CubeWrite( stdout, pCube );
assert( 0 );
}
}
*/
// try to find a containing cube
for ( i = 0; i <= (int)pCube->nLits; i++ )
- Min_CoverForEachCube( p->ppStore[i], pThis )
+ Esop_CoverForEachCube( p->ppStore[i], pThis )
{
// skip the bubble
- if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) )
+ if ( pThis != p->pBubble && Esop_CubeIsContained( pThis, pCube ) )
return 1;
}
return 0;
}
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/xyz/xyzMinMan.c b/src/temp/esop/esopMan.c
index 20314698..e81411f8 100644
--- a/src/opt/xyz/xyzMinMan.c
+++ b/src/temp/esop/esopMan.c
@@ -1,6 +1,6 @@
/**CFile****************************************************************
- FileName [xyzMinMan.c]
+ FileName [esopMan.c]
SystemName [ABC: Logic synthesis and verification system.]
@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: xyzMinMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: esopMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
-#include "xyzInt.h"
+#include "esop.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -39,30 +39,31 @@
SeeAlso []
***********************************************************************/
-Min_Man_t * Min_ManAlloc( int nVars )
+Esop_Man_t * Esop_ManAlloc( int nVars )
{
- Min_Man_t * pMan;
+ Esop_Man_t * pMan;
// start the manager
- pMan = ALLOC( Min_Man_t, 1 );
- memset( pMan, 0, sizeof(Min_Man_t) );
- pMan->nVars = nVars;
- pMan->nWords = Abc_BitWordNum( nVars * 2 );
- pMan->pMemMan = Extra_MmFixedStart( sizeof(Min_Cube_t) + sizeof(unsigned) * (pMan->nWords - 1) );
+ pMan = ALLOC( Esop_Man_t, 1 );
+ memset( pMan, 0, sizeof(Esop_Man_t) );
+ pMan->nVars = nVars;
+ pMan->nWords = Esop_BitWordNum( nVars * 2 );
+ pMan->pMemMan1 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (1 - 1) );
+ pMan->pMemMan2 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (2 - 1) );
+ pMan->pMemMan4 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (4 - 1) );
+ pMan->pMemMan8 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (8 - 1) );
// allocate storage for the temporary cover
- pMan->ppStore = ALLOC( Min_Cube_t *, pMan->nVars + 1 );
+ pMan->ppStore = ALLOC( Esop_Cube_t *, pMan->nVars + 1 );
// create tautology cubes
- Min_ManClean( pMan, nVars );
- pMan->pOne0 = Min_CubeAlloc( pMan );
- pMan->pOne1 = Min_CubeAlloc( pMan );
- pMan->pTemp = Min_CubeAlloc( pMan );
- pMan->pBubble = Min_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0;
+ Esop_ManClean( pMan, nVars );
+ pMan->pOne0 = Esop_CubeAlloc( pMan );
+ pMan->pOne1 = Esop_CubeAlloc( pMan );
+ pMan->pTemp = Esop_CubeAlloc( pMan );
+ pMan->pBubble = Esop_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0;
// create trivial cubes
- Min_ManClean( pMan, 1 );
- pMan->pTriv0[0] = Min_CubeAllocVar( pMan, 0, 0 );
- pMan->pTriv0[1] = Min_CubeAllocVar( pMan, 0, 1 );
- pMan->pTriv1[0] = Min_CubeAllocVar( pMan, 0, 0 );
- pMan->pTriv1[1] = Min_CubeAllocVar( pMan, 0, 1 );
- Min_ManClean( pMan, nVars );
+ Esop_ManClean( pMan, 1 );
+ pMan->pTriv0 = Esop_CubeAllocVar( pMan, 0, 0 );
+ pMan->pTriv1 = Esop_CubeAllocVar( pMan, 0, 0 );
+ Esop_ManClean( pMan, nVars );
return pMan;
}
@@ -77,13 +78,13 @@ Min_Man_t * Min_ManAlloc( int nVars )
SeeAlso []
***********************************************************************/
-void Min_ManClean( Min_Man_t * p, int nSupp )
+void Esop_ManClean( Esop_Man_t * p, int nSupp )
{
// set the size of the cube manager
p->nVars = nSupp;
- p->nWords = Abc_BitWordNum(2*nSupp);
+ p->nWords = Esop_BitWordNum(2*nSupp);
// clean the storage
- memset( p->ppStore, 0, sizeof(Min_Cube_t *) * (nSupp + 1) );
+ memset( p->ppStore, 0, sizeof(Esop_Cube_t *) * (nSupp + 1) );
p->nCubes = 0;
}
@@ -98,9 +99,12 @@ void Min_ManClean( Min_Man_t * p, int nSupp )
SeeAlso []
***********************************************************************/
-void Min_ManFree( Min_Man_t * p )
+void Esop_ManFree( Esop_Man_t * p )
{
- Extra_MmFixedStop ( p->pMemMan, 0 );
+ Esop_MmFixedStop ( p->pMemMan1, 0 );
+ Esop_MmFixedStop ( p->pMemMan2, 0 );
+ Esop_MmFixedStop ( p->pMemMan4, 0 );
+ Esop_MmFixedStop ( p->pMemMan8, 0 );
free( p->ppStore );
free( p );
}
diff --git a/src/temp/esop/esopMem.c b/src/temp/esop/esopMem.c
new file mode 100644
index 00000000..9d8e7405
--- /dev/null
+++ b/src/temp/esop/esopMem.c
@@ -0,0 +1,274 @@
+/**CFile****************************************************************
+
+ FileName [esopMem.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Cover manipulation package.]
+
+ Synopsis [Memory managers.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: esopMem.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "esop.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Esop_MmFixed_t_
+{
+ // information about individual entries
+ int nEntrySize; // the size of one entry
+ int nEntriesAlloc; // the total number of entries allocated
+ int nEntriesUsed; // the number of entries in use
+ int nEntriesMax; // the max number of entries in use
+ char * pEntriesFree; // the linked list of free entries
+
+ // this is where the memory is stored
+ int nChunkSize; // the size of one chunk
+ int nChunksAlloc; // the maximum number of memory chunks
+ int nChunks; // the current number of memory chunks
+ char ** pChunks; // the allocated memory
+
+ // statistics
+ int nMemoryUsed; // memory used in the allocated entries
+ int nMemoryAlloc; // memory allocated
+};
+
+struct Esop_MmFlex_t_
+{
+ // information about individual entries
+ int nEntriesUsed; // the number of entries allocated
+ char * pCurrent; // the current pointer to free memory
+ char * pEnd; // the first entry outside the free memory
+
+ // this is where the memory is stored
+ int nChunkSize; // the size of one chunk
+ int nChunksAlloc; // the maximum number of memory chunks
+ int nChunks; // the current number of memory chunks
+ char ** pChunks; // the allocated memory
+
+ // statistics
+ int nMemoryUsed; // memory used in the allocated entries
+ int nMemoryAlloc; // memory allocated
+};
+
+struct Esop_MmStep_t_
+{
+ int nMems; // the number of fixed memory managers employed
+ Esop_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc
+ int nMapSize; // the size of the memory array
+ Esop_MmFixed_t ** pMap; // maps the number of bytes into its memory manager
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates memory pieces of fixed size.]
+
+ Description [The size of the chunk is computed as the minimum of
+ 1024 entries and 64K. Can only work with entry size at least 4 byte long.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Esop_MmFixed_t * Esop_MmFixedStart( int nEntrySize )
+{
+ Esop_MmFixed_t * p;
+
+ p = ALLOC( Esop_MmFixed_t, 1 );
+ memset( p, 0, sizeof(Esop_MmFixed_t) );
+
+ p->nEntrySize = nEntrySize;
+ p->nEntriesAlloc = 0;
+ p->nEntriesUsed = 0;
+ p->pEntriesFree = NULL;
+
+ if ( nEntrySize * (1 << 10) < (1<<16) )
+ p->nChunkSize = (1 << 10);
+ else
+ p->nChunkSize = (1<<16) / nEntrySize;
+ if ( p->nChunkSize < 8 )
+ p->nChunkSize = 8;
+
+ p->nChunksAlloc = 64;
+ p->nChunks = 0;
+ p->pChunks = ALLOC( char *, p->nChunksAlloc );
+
+ p->nMemoryUsed = 0;
+ p->nMemoryAlloc = 0;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_MmFixedStop( Esop_MmFixed_t * p, int fVerbose )
+{
+ int i;
+ if ( p == NULL )
+ return;
+ if ( fVerbose )
+ {
+ printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
+ p->nEntrySize, p->nChunkSize, p->nChunks );
+ printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
+ p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
+ }
+ for ( i = 0; i < p->nChunks; i++ )
+ free( p->pChunks[i] );
+ free( p->pChunks );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Esop_MmFixedEntryFetch( Esop_MmFixed_t * p )
+{
+ char * pTemp;
+ int i;
+
+ // check if there are still free entries
+ if ( p->nEntriesUsed == p->nEntriesAlloc )
+ { // need to allocate more entries
+ assert( p->pEntriesFree == NULL );
+ if ( p->nChunks == p->nChunksAlloc )
+ {
+ p->nChunksAlloc *= 2;
+ p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
+ }
+ p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
+ p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
+ // transform these entries into a linked list
+ pTemp = p->pEntriesFree;
+ for ( i = 1; i < p->nChunkSize; i++ )
+ {
+ *((char **)pTemp) = pTemp + p->nEntrySize;
+ pTemp += p->nEntrySize;
+ }
+ // set the last link
+ *((char **)pTemp) = NULL;
+ // add the chunk to the chunk storage
+ p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
+ // add to the number of entries allocated
+ p->nEntriesAlloc += p->nChunkSize;
+ }
+ // incrememt the counter of used entries
+ p->nEntriesUsed++;
+ if ( p->nEntriesMax < p->nEntriesUsed )
+ p->nEntriesMax = p->nEntriesUsed;
+ // return the first entry in the free entry list
+ pTemp = p->pEntriesFree;
+ p->pEntriesFree = *((char **)pTemp);
+ return pTemp;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_MmFixedEntryRecycle( Esop_MmFixed_t * p, char * pEntry )
+{
+ // decrement the counter of used entries
+ p->nEntriesUsed--;
+ // add the entry to the linked list of free entries
+ *((char **)pEntry) = p->pEntriesFree;
+ p->pEntriesFree = pEntry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description [Relocates all the memory except the first chunk.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_MmFixedRestart( Esop_MmFixed_t * p )
+{
+ int i;
+ char * pTemp;
+
+ // deallocate all chunks except the first one
+ for ( i = 1; i < p->nChunks; i++ )
+ free( p->pChunks[i] );
+ p->nChunks = 1;
+ // transform these entries into a linked list
+ pTemp = p->pChunks[0];
+ for ( i = 1; i < p->nChunkSize; i++ )
+ {
+ *((char **)pTemp) = pTemp + p->nEntrySize;
+ pTemp += p->nEntrySize;
+ }
+ // set the last link
+ *((char **)pTemp) = NULL;
+ // set the free entry list
+ p->pEntriesFree = p->pChunks[0];
+ // set the correct statistics
+ p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
+ p->nMemoryUsed = 0;
+ p->nEntriesAlloc = p->nChunkSize;
+ p->nEntriesUsed = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Esop_MmFixedReadMemUsage( Esop_MmFixed_t * p )
+{
+ return p->nMemoryAlloc;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/xyz/xyzMinEsop.c b/src/temp/esop/esopMin.c
index 839e2410..7a460f8e 100644
--- a/src/opt/xyz/xyzMinEsop.c
+++ b/src/temp/esop/esopMin.c
@@ -1,6 +1,6 @@
/**CFile****************************************************************
- FileName [xyzMinEsop.c]
+ FileName [esopMin.c]
SystemName [ABC: Logic synthesis and verification system.]
@@ -14,17 +14,17 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: xyzMinEsop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: esopMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
-#include "xyzInt.h"
+#include "esop.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static void Min_EsopRewrite( Min_Man_t * p );
+static void Esop_EsopRewrite( Esop_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -32,7 +32,7 @@ static void Min_EsopRewrite( Min_Man_t * p );
/**Function*************************************************************
- Synopsis []
+ Synopsis [ESOP minimization procedure.]
Description []
@@ -41,7 +41,7 @@ static void Min_EsopRewrite( Min_Man_t * p );
SeeAlso []
***********************************************************************/
-void Min_EsopMinimize( Min_Man_t * p )
+void Esop_EsopMinimize( Esop_Man_t * p )
{
int nCubesInit, nCubesOld, nIter;
if ( p->nCubes < 3 )
@@ -50,7 +50,7 @@ void Min_EsopMinimize( Min_Man_t * p )
nCubesInit = p->nCubes;
do {
nCubesOld = p->nCubes;
- Min_EsopRewrite( p );
+ Esop_EsopRewrite( p );
nIter++;
}
while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 );
@@ -73,10 +73,10 @@ void Min_EsopMinimize( Min_Man_t * p )
SeeAlso []
***********************************************************************/
-void Min_EsopRewrite( Min_Man_t * p )
+void Esop_EsopRewrite( Esop_Man_t * p )
{
- Min_Cube_t * pCube, ** ppPrev;
- Min_Cube_t * pThis, ** ppPrevT;
+ Esop_Cube_t * pCube, ** ppPrev;
+ Esop_Cube_t * pThis, ** ppPrevT;
int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld;
int nPairs = 0;
@@ -92,7 +92,7 @@ void Min_EsopRewrite( Min_Man_t * p )
Index = p->pBubble->nLits;
// find the bubble
- Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev )
+ Esop_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev )
if ( pCube == p->pBubble )
break;
assert( pCube == p->pBubble );
@@ -113,16 +113,16 @@ void Min_EsopRewrite( Min_Man_t * p )
break;
// find the first dist2 cube
- Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
- if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
+ Esop_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
+ if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
if ( pThis == NULL && Index < p->nVars )
- Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
- if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
+ Esop_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
+ if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
if ( pThis == NULL && Index < p->nVars - 1 )
- Min_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT )
- if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
+ Esop_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT )
+ if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
break;
// continue if there is no dist2 cube
if ( pThis == NULL )
@@ -148,26 +148,26 @@ void Min_EsopRewrite( Min_Man_t * p )
// A{v00} B{v01+v11} + A{v00+v10} B{v11}
// save the dist2 parameters
- v00 = Min_CubeGetVar( pCube, Var0 );
- v01 = Min_CubeGetVar( pCube, Var1 );
- v10 = Min_CubeGetVar( pThis, Var0 );
- v11 = Min_CubeGetVar( pThis, Var1 );
+ v00 = Esop_CubeGetVar( pCube, Var0 );
+ v01 = Esop_CubeGetVar( pCube, Var1 );
+ v10 = Esop_CubeGetVar( pThis, Var0 );
+ v11 = Esop_CubeGetVar( pThis, Var1 );
//printf( "\n" );
-//Min_CubeWrite( stdout, pCube );
-//Min_CubeWrite( stdout, pThis );
+//Esop_CubeWrite( stdout, pCube );
+//Esop_CubeWrite( stdout, pThis );
// derive the first pair of resulting cubes
- Min_CubeXorVar( pCube, Var0, v10 );
+ Esop_CubeXorVar( pCube, Var0, v10 );
pCube->nLits -= (v00 != 3);
pCube->nLits += ((v00 ^ v10) != 3);
- Min_CubeXorVar( pThis, Var1, v01 );
+ Esop_CubeXorVar( pThis, Var1, v01 );
pThis->nLits -= (v11 != 3);
pThis->nLits += ((v01 ^ v11) != 3);
// add the cubes
nCubesOld = p->nCubes;
- Min_EsopAddCube( p, pCube );
- Min_EsopAddCube( p, pThis );
+ Esop_EsopAddCube( p, pCube );
+ Esop_EsopAddCube( p, pThis );
// check if the cubes were absorbed
if ( p->nCubes < nCubesOld + 2 )
continue;
@@ -180,23 +180,23 @@ void Min_EsopRewrite( Min_Man_t * p )
p->nCubes -= 2;
// derive the second pair of resulting cubes
- Min_CubeXorVar( pCube, Var0, v10 );
+ Esop_CubeXorVar( pCube, Var0, v10 );
pCube->nLits -= ((v00 ^ v10) != 3);
pCube->nLits += (v00 != 3);
- Min_CubeXorVar( pCube, Var1, v11 );
+ Esop_CubeXorVar( pCube, Var1, v11 );
pCube->nLits -= (v01 != 3);
pCube->nLits += ((v01 ^ v11) != 3);
- Min_CubeXorVar( pThis, Var0, v00 );
+ Esop_CubeXorVar( pThis, Var0, v00 );
pThis->nLits -= (v10 != 3);
pThis->nLits += ((v00 ^ v10) != 3);
- Min_CubeXorVar( pThis, Var1, v01 );
+ Esop_CubeXorVar( pThis, Var1, v01 );
pThis->nLits -= ((v01 ^ v11) != 3);
pThis->nLits += (v11 != 3);
// add them anyhow
- Min_EsopAddCube( p, pCube );
- Min_EsopAddCube( p, pThis );
+ Esop_EsopAddCube( p, pCube );
+ Esop_EsopAddCube( p, pThis );
}
// printf( "Pairs = %d ", nPairs );
}
@@ -214,55 +214,55 @@ void Min_EsopRewrite( Min_Man_t * p )
SeeAlso []
***********************************************************************/
-int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube )
+int Esop_EsopAddCubeInt( Esop_Man_t * p, Esop_Cube_t * pCube )
{
- Min_Cube_t * pThis, ** ppPrev;
+ Esop_Cube_t * pThis, ** ppPrev;
// try to find the identical cube
- Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
+ Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
{
- if ( Min_CubesAreEqual( pCube, pThis ) )
+ if ( Esop_CubesAreEqual( pCube, pThis ) )
{
*ppPrev = pThis->pNext;
- Min_CubeRecycle( p, pCube );
- Min_CubeRecycle( p, pThis );
+ Esop_CubeRecycle( p, pCube );
+ Esop_CubeRecycle( p, pThis );
p->nCubes--;
return 0;
}
}
// find a distance-1 cube if it exists
if ( pCube->nLits < pCube->nVars )
- Min_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev )
+ Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev )
{
- if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
+ if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
- Min_CubesTransform( pCube, pThis, p->pTemp );
+ Esop_CubesTransform( pCube, pThis, p->pTemp );
pCube->nLits++;
- Min_CubeRecycle( p, pThis );
+ Esop_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
}
- Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
+ Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
{
- if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
+ if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
- Min_CubesTransform( pCube, pThis, p->pTemp );
+ Esop_CubesTransform( pCube, pThis, p->pTemp );
pCube->nLits--;
- Min_CubeRecycle( p, pThis );
+ Esop_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
}
if ( pCube->nLits > 0 )
- Min_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev )
+ Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev )
{
- if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
+ if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
{
*ppPrev = pThis->pNext;
- Min_CubesTransform( pCube, pThis, p->pTemp );
- Min_CubeRecycle( p, pThis );
+ Esop_CubesTransform( pCube, pThis, p->pTemp );
+ Esop_CubeRecycle( p, pThis );
p->nCubes--;
return 1;
}
@@ -285,11 +285,11 @@ int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube )
SeeAlso []
***********************************************************************/
-void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube )
+void Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube )
{
assert( pCube != p->pBubble );
- assert( (int)pCube->nLits == Min_CubeCountLits(pCube) );
- while ( Min_EsopAddCubeInt( p, pCube ) );
+ assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) );
+ while ( Esop_EsopAddCubeInt( p, pCube ) );
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/xyz/xyzMinUtil.c b/src/temp/esop/esopUtil.c
index 9ec5f83f..dec6eae2 100644
--- a/src/opt/xyz/xyzMinUtil.c
+++ b/src/temp/esop/esopUtil.c
@@ -1,6 +1,6 @@
/**CFile****************************************************************
- FileName [xyzMinUtil.c]
+ FileName [esopUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: xyzMinUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: esopUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
-#include "xyzInt.h"
+#include "esop.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -39,21 +39,21 @@
SeeAlso []
***********************************************************************/
-void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube )
+void Esop_CubeWrite( FILE * pFile, Esop_Cube_t * pCube )
{
int i;
- assert( (int)pCube->nLits == Min_CubeCountLits(pCube) );
+ assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) );
for ( i = 0; i < (int)pCube->nVars; i++ )
- if ( Min_CubeHasBit(pCube, i*2) )
+ if ( Esop_CubeHasBit(pCube, i*2) )
{
- if ( Min_CubeHasBit(pCube, i*2+1) )
+ if ( Esop_CubeHasBit(pCube, i*2+1) )
fprintf( pFile, "-" );
else
fprintf( pFile, "0" );
}
else
{
- if ( Min_CubeHasBit(pCube, i*2+1) )
+ if ( Esop_CubeHasBit(pCube, i*2+1) )
fprintf( pFile, "1" );
else
fprintf( pFile, "?" );
@@ -73,11 +73,11 @@ void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube )
SeeAlso []
***********************************************************************/
-void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover )
+void Esop_CoverWrite( FILE * pFile, Esop_Cube_t * pCover )
{
- Min_Cube_t * pCube;
- Min_CoverForEachCube( pCover, pCube )
- Min_CubeWrite( pFile, pCube );
+ Esop_Cube_t * pCube;
+ Esop_CoverForEachCube( pCover, pCube )
+ Esop_CubeWrite( pFile, pCube );
printf( "\n" );
}
@@ -92,13 +92,13 @@ void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover )
SeeAlso []
***********************************************************************/
-void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p )
+void Esop_CoverWriteStore( FILE * pFile, Esop_Man_t * p )
{
- Min_Cube_t * pCube;
+ Esop_Cube_t * pCube;
int i;
for ( i = 0; i <= p->nVars; i++ )
{
- Min_CoverForEachCube( p->ppStore[i], pCube )
+ Esop_CoverForEachCube( p->ppStore[i], pCube )
{
printf( "%2d : ", i );
if ( pCube == p->pBubble )
@@ -106,7 +106,7 @@ void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p )
printf( "Bubble\n" );
continue;
}
- Min_CubeWrite( pFile, pCube );
+ Esop_CubeWrite( pFile, pCube );
}
}
printf( "\n" );
@@ -123,10 +123,10 @@ void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p )
SeeAlso []
***********************************************************************/
-void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop )
+void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop )
{
char Buffer[1000];
- Min_Cube_t * pCube;
+ Esop_Cube_t * pCube;
FILE * pFile;
int i;
sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" );
@@ -137,10 +137,10 @@ void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop )
fprintf( pFile, "# %s cover for output %s generated by ABC on %s\n", fEsop? "ESOP":"SOP", pName, Extra_TimeStamp() );
fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 );
fprintf( pFile, ".o %d\n", 1 );
- fprintf( pFile, ".p %d\n", Min_CoverCountCubes(pCover) );
+ fprintf( pFile, ".p %d\n", Esop_CoverCountCubes(pCover) );
if ( fEsop ) fprintf( pFile, ".type esop\n" );
- Min_CoverForEachCube( pCover, pCube )
- Min_CubeWrite( pFile, pCube );
+ Esop_CoverForEachCube( pCover, pCube )
+ Esop_CubeWrite( pFile, pCube );
fprintf( pFile, ".e\n" );
fclose( pFile );
}
@@ -156,12 +156,12 @@ void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop )
SeeAlso []
***********************************************************************/
-void Min_CoverCheck( Min_Man_t * p )
+void Esop_CoverCheck( Esop_Man_t * p )
{
- Min_Cube_t * pCube;
+ Esop_Cube_t * pCube;
int i;
for ( i = 0; i <= p->nVars; i++ )
- Min_CoverForEachCube( p->ppStore[i], pCube )
+ Esop_CoverForEachCube( p->ppStore[i], pCube )
assert( i == (int)pCube->nLits );
}
@@ -177,11 +177,11 @@ void Min_CoverCheck( Min_Man_t * p )
SeeAlso []
***********************************************************************/
-int Min_CubeCheck( Min_Cube_t * pCube )
+int Esop_CubeCheck( Esop_Cube_t * pCube )
{
int i;
for ( i = 0; i < (int)pCube->nVars; i++ )
- if ( Min_CubeGetVar( pCube, i ) == 0 )
+ if ( Esop_CubeGetVar( pCube, i ) == 0 )
return 0;
return 1;
}
@@ -197,14 +197,14 @@ int Min_CubeCheck( Min_Cube_t * pCube )
SeeAlso []
***********************************************************************/
-Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize )
+Esop_Cube_t * Esop_CoverCollect( Esop_Man_t * p, int nSuppSize )
{
- Min_Cube_t * pCov = NULL, ** ppTail = &pCov;
- Min_Cube_t * pCube, * pCube2;
+ Esop_Cube_t * pCov = NULL, ** ppTail = &pCov;
+ Esop_Cube_t * pCube, * pCube2;
int i;
for ( i = 0; i <= nSuppSize; i++ )
{
- Min_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 )
+ Esop_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 )
{
assert( i == (int)pCube->nLits );
*ppTail = pCube;
@@ -227,11 +227,11 @@ Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize )
SeeAlso []
***********************************************************************/
-void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover )
+void Esop_CoverExpand( Esop_Man_t * p, Esop_Cube_t * pCover )
{
- Min_Cube_t * pCube, * pCube2;
- Min_ManClean( p, p->nVars );
- Min_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Esop_Cube_t * pCube, * pCube2;
+ Esop_ManClean( p, p->nVars );
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
{
pCube->pNext = p->ppStore[pCube->nLits];
p->ppStore[pCube->nLits] = pCube;
@@ -250,9 +250,9 @@ void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover )
SeeAlso []
***********************************************************************/
-int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover )
+int Esop_CoverSuppVarNum( Esop_Man_t * p, Esop_Cube_t * pCover )
{
- Min_Cube_t * pCube;
+ Esop_Cube_t * pCube;
int i, Counter;
if ( pCover == NULL )
return 0;
@@ -260,13 +260,13 @@ int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover )
for ( i = 0; i < (int)pCover->nWords; i++ )
p->pTemp->uData[i] = ~((unsigned)0);
// add the bit data
- Min_CoverForEachCube( pCover, pCube )
+ Esop_CoverForEachCube( pCover, pCube )
for ( i = 0; i < (int)pCover->nWords; i++ )
p->pTemp->uData[i] &= pCube->uData[i];
// count the vars
Counter = 0;
for ( i = 0; i < (int)pCover->nVars; i++ )
- Counter += ( Min_CubeGetVar(p->pTemp, i) != 3 );
+ Counter += ( Esop_CubeGetVar(p->pTemp, i) != 3 );
return Counter;
}
diff --git a/src/temp/esop/module.make b/src/temp/esop/module.make
new file mode 100644
index 00000000..cab5e737
--- /dev/null
+++ b/src/temp/esop/module.make
@@ -0,0 +1,4 @@
+SRC += src/temp/esop/esopMan.c \
+ src/temp/esop/esopMem.c \
+ src/temp/esop/esopMin.c \
+ src/temp/esop/esopUtil.c
diff --git a/src/temp/ivy/ivy.h b/src/temp/ivy/ivy.h
new file mode 100644
index 00000000..55ada384
--- /dev/null
+++ b/src/temp/ivy/ivy.h
@@ -0,0 +1,450 @@
+/**CFile****************************************************************
+
+ FileName [ivy.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivy.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __IVY_H__
+#define __IVY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "vec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ivy_Man_t_ Ivy_Man_t;
+typedef struct Ivy_Obj_t_ Ivy_Obj_t;
+
+// object types
+typedef enum {
+ IVY_NONE, // 0: unused node
+ IVY_PI, // 1: primary input (and constant 1 node)
+ IVY_PO, // 2: primary output
+ IVY_ASSERT, // 3: assertion
+ IVY_LATCH, // 4: sequential element
+ IVY_AND, // 5: internal AND node
+ IVY_EXOR, // 6: internal EXOR node
+ IVY_BUF, // 7: internal buffer (temporary)
+ IVY_ANDM, // 8: multi-input AND (logic network only)
+ IVY_EXORM, // 9: multi-input EXOR (logic network only)
+ IVY_LUT // 10: multi-input LUT (logic network only)
+} Ivy_Type_t;
+
+// latch initial values
+typedef enum {
+ IVY_INIT_NONE, // 0: not a latch
+ IVY_INIT_0, // 1: zero
+ IVY_INIT_1, // 2: one
+ IVY_INIT_DC // 3: don't-care
+} Ivy_Init_t;
+
+// the AIG node
+struct Ivy_Obj_t_ // 6 words
+{
+ int Id; // integer ID
+ int TravId; // traversal ID
+ int Fanin0; // fanin ID
+ int Fanin1; // fanin ID
+ int nRefs; // reference counter
+ unsigned Type : 4; // object type
+ unsigned fPhase : 1; // value under 000...0 pattern
+ unsigned fMarkA : 1; // multipurpose mask
+ unsigned fMarkB : 1; // multipurpose mask
+ unsigned fExFan : 1; // set to 1 if last fanout added is EXOR
+ unsigned fComp0 : 1; // complemented attribute
+ unsigned fComp1 : 1; // complemented attribute
+ unsigned Init : 2; // latch initial value
+ unsigned LevelR : 8; // reverse logic level
+ unsigned Level : 12; // logic level
+};
+
+// the AIG manager
+struct Ivy_Man_t_
+{
+ // AIG nodes
+ int nObjs[12]; // the number of objects by type
+ int nCreated; // the number of created objects
+ int nDeleted; // the number of deleted objects
+ int ObjIdNext; // the next free obj ID to assign
+ int nObjsAlloc; // the allocated number of nodes
+ Ivy_Obj_t * pObjs; // the array of all nodes
+ Vec_Int_t * vPis; // the array of PIs
+ Vec_Int_t * vPos; // the array of POs
+ // stuctural hash table
+ int * pTable; // structural hash table
+ int nTableSize; // structural hash table size
+ // various data members
+ int fExtended; // set to 1 in extended mode
+ int nTravIds; // the traversal ID
+ int nLevelMax; // the maximum level
+ void * pData; // the temporary data
+ // truth table of the 8-LUTs
+ unsigned * pMemory; // memory for truth tables
+ Vec_Int_t * vTruths; // offset for truth table of each node
+ // storage for the undo operation
+ Vec_Int_t * vFree; // storage for all deleted entries
+ Ivy_Obj_t * pUndos; // description of recently deleted nodes
+ int nUndos; // the number of recently deleted nodes
+ int nUndosAlloc; // the number of allocated cells
+ int fRecording; // shows that recording goes on
+};
+
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define IVY_SANDBOX_SIZE 1
+
+#define IVY_MIN(a,b) (((a) < (b))? (a) : (b))
+#define IVY_MAX(a,b) (((a) > (b))? (a) : (b))
+
+static inline int Ivy_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
+static inline int Ivy_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
+static inline int Ivy_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
+static inline void Ivy_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
+static inline void Ivy_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
+
+static inline int Ivy_FanCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; }
+static inline int Ivy_FanId( int Fan ) { return Fan >> 1; }
+static inline int Ivy_FanCompl( int Fan ) { return Fan & 1; }
+
+static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << 4) | Lat; }
+static inline int Ivy_LeafId( int Leaf ) { return Leaf >> 4; }
+static inline int Ivy_LeafLat( int Leaf ) { return Leaf & 15; }
+
+static inline Ivy_Obj_t * Ivy_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) & ~01); }
+static inline Ivy_Obj_t * Ivy_Not( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) ^ 01); }
+static inline Ivy_Obj_t * Ivy_NotCond( Ivy_Obj_t * p, int c ) { return (Ivy_Obj_t *)((unsigned)(p) ^ (c)); }
+static inline int Ivy_IsComplement( Ivy_Obj_t * p ) { return (int )(((unsigned)p) & 01); }
+
+static inline Ivy_Obj_t * Ivy_ManConst0( Ivy_Man_t * p ) { return Ivy_Not(p->pObjs); }
+static inline Ivy_Obj_t * Ivy_ManConst1( Ivy_Man_t * p ) { return p->pObjs; }
+static inline Ivy_Obj_t * Ivy_ManGhost( Ivy_Man_t * p ) { return p->pObjs - IVY_SANDBOX_SIZE; }
+static inline Ivy_Obj_t * Ivy_ManPi( Ivy_Man_t * p, int i ) { return p->pObjs + Vec_IntEntry(p->vPis,i); }
+static inline Ivy_Obj_t * Ivy_ManPo( Ivy_Man_t * p, int i ) { return p->pObjs + Vec_IntEntry(p->vPos,i); }
+static inline Ivy_Obj_t * Ivy_ManObj( Ivy_Man_t * p, int i ) { return p->pObjs + i; }
+
+static inline int Ivy_ManPiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PI]; }
+static inline int Ivy_ManPoNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PO]; }
+static inline int Ivy_ManAssertNum( Ivy_Man_t * p ) { return p->nObjs[IVY_ASSERT]; }
+static inline int Ivy_ManLatchNum( Ivy_Man_t * p ) { return p->nObjs[IVY_LATCH]; }
+static inline int Ivy_ManAndNum( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]; }
+static inline int Ivy_ManExorNum( Ivy_Man_t * p ) { return p->nObjs[IVY_EXOR]; }
+static inline int Ivy_ManBufNum( Ivy_Man_t * p ) { return p->nObjs[IVY_BUF]; }
+static inline int Ivy_ManAndMultiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_ANDM]; }
+static inline int Ivy_ManExorMultiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_EXORM]; }
+static inline int Ivy_ManLutNum( Ivy_Man_t * p ) { return p->nObjs[IVY_LUT]; }
+static inline int Ivy_ManObjNum( Ivy_Man_t * p ) { return p->nCreated - p->nDeleted; }
+static inline int Ivy_ManObjIdNext( Ivy_Man_t * p ) { return p->ObjIdNext; }
+static inline int Ivy_ManObjAllocNum( Ivy_Man_t * p ) { return p->nObjsAlloc; }
+static inline int Ivy_ManNodeNum( Ivy_Man_t * p ) { return p->fExtended? p->nObjs[IVY_ANDM]+p->nObjs[IVY_EXORM]+p->nObjs[IVY_LUT] : p->nObjs[IVY_AND]+p->nObjs[IVY_EXOR]; }
+static inline int Ivy_ManHashObjNum( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+p->nObjs[IVY_EXOR]+p->nObjs[IVY_LATCH]; }
+static inline int Ivy_ManGetCost( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+3*p->nObjs[IVY_EXOR]+8*p->nObjs[IVY_LATCH]; }
+
+static inline Ivy_Type_t Ivy_ObjType( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type; }
+static inline Ivy_Init_t Ivy_ObjInit( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Init; }
+static inline int Ivy_ObjIsConst1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id == 0; }
+static inline int Ivy_ObjIsGhost( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id < 0; }
+static inline int Ivy_ObjIsNone( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_NONE; }
+static inline int Ivy_ObjIsPi( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI; }
+static inline int Ivy_ObjIsPo( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO; }
+static inline int Ivy_ObjIsCi( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_LATCH; }
+static inline int Ivy_ObjIsCo( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_LATCH; }
+static inline int Ivy_ObjIsAssert( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_ASSERT; }
+static inline int Ivy_ObjIsLatch( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_LATCH; }
+static inline int Ivy_ObjIsAnd( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND; }
+static inline int Ivy_ObjIsExor( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXOR; }
+static inline int Ivy_ObjIsBuf( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_BUF; }
+static inline int Ivy_ObjIsNode( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR; }
+static inline int Ivy_ObjIsTerm( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; }
+static inline int Ivy_ObjIsHash( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR || pObj->Type == IVY_LATCH; }
+static inline int Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; }
+
+static inline int Ivy_ObjIsAndMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_ANDM; }
+static inline int Ivy_ObjIsExorMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXORM; }
+static inline int Ivy_ObjIsLut( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_LUT; }
+static inline int Ivy_ObjIsNodeExt( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type >= IVY_ANDM; }
+
+static inline int Ivy_ObjIsMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fMarkA; }
+static inline void Ivy_ObjSetMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->fMarkA = 1; }
+static inline void Ivy_ObjClearMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->fMarkA = 0; }
+
+static inline Ivy_Man_t * Ivy_ObjMan( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return *((Ivy_Man_t **)(pObj - pObj->Id - IVY_SANDBOX_SIZE - 1)); }
+static inline Ivy_Obj_t * Ivy_ObjConst0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_Not(pObj - pObj->Id); }
+static inline Ivy_Obj_t * Ivy_ObjConst1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id; }
+static inline Ivy_Obj_t * Ivy_ObjGhost( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id - IVY_SANDBOX_SIZE; }
+static inline Ivy_Obj_t * Ivy_ObjObj( Ivy_Obj_t * pObj, int n ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id + n; }
+static inline Ivy_Obj_t * Ivy_ObjNext( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id + pObj->TravId; }
+
+static inline void Ivy_ObjSetTravId( Ivy_Obj_t * pObj, int TravId ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = TravId; }
+static inline void Ivy_ObjSetTravIdCurrent( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = Ivy_ObjMan(pObj)->nTravIds; }
+static inline void Ivy_ObjSetTravIdPrevious( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = Ivy_ObjMan(pObj)->nTravIds - 1; }
+static inline int Ivy_ObjIsTravIdCurrent( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return (int )((int)pObj->TravId == Ivy_ObjMan(pObj)->nTravIds); }
+static inline int Ivy_ObjIsTravIdPrevious( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return (int )((int)pObj->TravId == Ivy_ObjMan(pObj)->nTravIds - 1); }
+
+static inline int Ivy_ObjId( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id; }
+static inline int Ivy_ObjPhase( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fPhase; }
+static inline int Ivy_ObjExorFanout( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fExFan; }
+static inline int Ivy_ObjRefs( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->nRefs; }
+static inline void Ivy_ObjRefsInc( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->nRefs++; }
+static inline void Ivy_ObjRefsDec( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); assert( pObj->nRefs > 0 ); pObj->nRefs--; }
+static inline int Ivy_ObjFaninId0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Fanin0; }
+static inline int Ivy_ObjFaninId1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Fanin1; }
+static inline int Ivy_ObjFaninC0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fComp0; }
+static inline int Ivy_ObjFaninC1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fComp1; }
+static inline Ivy_Obj_t * Ivy_ObjFanin0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjObj(pObj, pObj->Fanin0); }
+static inline Ivy_Obj_t * Ivy_ObjFanin1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjObj(pObj, pObj->Fanin1); }
+static inline Ivy_Obj_t * Ivy_ObjChild0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_NotCond( Ivy_ObjFanin0(pObj), Ivy_ObjFaninC0(pObj) ); }
+static inline Ivy_Obj_t * Ivy_ObjChild1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_NotCond( Ivy_ObjFanin1(pObj), Ivy_ObjFaninC1(pObj) ); }
+static inline int Ivy_ObjLevelR( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->LevelR; }
+static inline int Ivy_ObjLevel( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Level; }
+static inline int Ivy_ObjLevelNew( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return 1 + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level); }
+static inline void Ivy_ObjClean( Ivy_Obj_t * pObj ) {
+ int IdSaved = pObj->Id;
+ if ( IdSaved == 54 )
+ {
+ int x = 0;
+ }
+ memset( pObj, 0, sizeof(Ivy_Obj_t) );
+ pObj->Id = IdSaved;
+}
+static inline void Ivy_ObjOverwrite( Ivy_Obj_t * pBase, Ivy_Obj_t * pData ) { int IdSaved = pBase->Id; memcpy( pBase, pData, sizeof(Ivy_Obj_t) ); pBase->Id = IdSaved; }
+static inline int Ivy_ObjWhatFanin( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin )
+{
+ if ( Ivy_ObjFaninId0(pObj) == Ivy_ObjId(pFanin) ) return 0;
+ if ( Ivy_ObjFaninId1(pObj) == Ivy_ObjId(pFanin) ) return 1;
+ assert(0); return -1;
+}
+static inline int Ivy_ObjFanoutC( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout )
+{
+ if ( Ivy_ObjFaninId0(pFanout) == Ivy_ObjId(pObj) ) return Ivy_ObjFaninC0(pObj);
+ if ( Ivy_ObjFaninId1(pFanout) == Ivy_ObjId(pObj) ) return Ivy_ObjFaninC1(pObj);
+ assert(0); return -1;
+}
+
+// create the ghost of the new node
+static inline Ivy_Obj_t * Ivy_ObjCreateGhost( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type, Ivy_Init_t Init )
+{
+ Ivy_Obj_t * pGhost;
+ int Temp;
+ pGhost = Ivy_ObjGhost(Ivy_Regular(p0));
+ pGhost->Type = Type;
+ pGhost->Init = Init;
+ pGhost->fComp0 = Ivy_IsComplement(p0);
+ pGhost->fComp1 = Ivy_IsComplement(p1);
+ pGhost->Fanin0 = Ivy_ObjId(Ivy_Regular(p0));
+ pGhost->Fanin1 = Ivy_ObjId(Ivy_Regular(p1));
+ if ( pGhost->Fanin0 < pGhost->Fanin1 )
+ {
+ Temp = pGhost->Fanin0, pGhost->Fanin0 = pGhost->Fanin1, pGhost->Fanin1 = Temp;
+ Temp = pGhost->fComp0, pGhost->fComp0 = pGhost->fComp1, pGhost->fComp1 = Temp;
+ }
+ assert( Ivy_ObjIsOneFanin(pGhost) || pGhost->Fanin0 > pGhost->Fanin1 );
+ return pGhost;
+}
+
+// create the ghost of the new node
+static inline Ivy_Obj_t * Ivy_ObjCreateGhost2( Ivy_Man_t * p, Ivy_Obj_t * pObjDead )
+{
+ Ivy_Obj_t * pGhost;
+ pGhost = Ivy_ManGhost(p);
+ pGhost->Type = pObjDead->Type;
+ pGhost->Init = pObjDead->Init;
+ pGhost->fComp0 = pObjDead->fComp0;
+ pGhost->fComp1 = pObjDead->fComp1;
+ pGhost->Fanin0 = pObjDead->Fanin0;
+ pGhost->Fanin1 = pObjDead->Fanin1;
+ assert( Ivy_ObjIsOneFanin(pGhost) || pGhost->Fanin0 > pGhost->Fanin1 );
+ return pGhost;
+}
+
+// get the complemented initial state
+static Ivy_Init_t Ivy_InitNotCond( Ivy_Init_t Init, int fCompl )
+{
+ assert( Init != IVY_INIT_NONE );
+ if ( fCompl == 0 )
+ return Init;
+ if ( Init == IVY_INIT_0 )
+ return IVY_INIT_1;
+ if ( Init == IVY_INIT_1 )
+ return IVY_INIT_0;
+ return IVY_INIT_DC;
+}
+
+// get the initial state after forward retiming over AND gate
+static Ivy_Init_t Ivy_InitAnd( Ivy_Init_t InitA, Ivy_Init_t InitB )
+{
+ assert( InitA != IVY_INIT_NONE && InitB != IVY_INIT_NONE );
+ if ( InitA == IVY_INIT_0 || InitB == IVY_INIT_0 )
+ return IVY_INIT_0;
+ if ( InitA == IVY_INIT_DC || InitB == IVY_INIT_DC )
+ return IVY_INIT_DC;
+ return IVY_INIT_1;
+}
+
+// get the initial state after forward retiming over EXOR gate
+static Ivy_Init_t Ivy_InitExor( Ivy_Init_t InitA, Ivy_Init_t InitB )
+{
+ assert( InitA != IVY_INIT_NONE && InitB != IVY_INIT_NONE );
+ if ( InitA == IVY_INIT_DC || InitB == IVY_INIT_DC )
+ return IVY_INIT_DC;
+ if ( InitA == IVY_INIT_0 && InitB == IVY_INIT_1 )
+ return IVY_INIT_1;
+ if ( InitA == IVY_INIT_1 && InitB == IVY_INIT_0 )
+ return IVY_INIT_1;
+ return IVY_INIT_0;
+}
+
+// extended fanins
+static inline Vec_Int_t * Ivy_ObjGetFanins( Ivy_Obj_t * pObj ) { assert(Ivy_ObjMan(pObj)->fExtended); return (Vec_Int_t *)*(((int*)pObj)+2); }
+static inline void Ivy_ObjSetFanins( Ivy_Obj_t * pObj, Vec_Int_t * vFanins ) { assert(Ivy_ObjMan(pObj)->fExtended); assert(Ivy_ObjGetFanins(pObj)==NULL); *(Vec_Int_t **)(((int*)pObj)+2) = vFanins; }
+static inline void Ivy_ObjStartFanins( Ivy_Obj_t * pObj, int nFanins ) { assert(Ivy_ObjMan(pObj)->fExtended); Ivy_ObjSetFanins( pObj, Vec_IntAlloc(nFanins) ); }
+static inline void Ivy_ObjAddFanin( Ivy_Obj_t * pObj, int Fanin ) { assert(Ivy_ObjMan(pObj)->fExtended); Vec_IntPush( Ivy_ObjGetFanins(pObj), Fanin ); }
+static inline int Ivy_ObjReadFanin( Ivy_Obj_t * pObj, int i ) { assert(Ivy_ObjMan(pObj)->fExtended); return Vec_IntEntry( Ivy_ObjGetFanins(pObj), i ); }
+static inline int Ivy_ObjFaninNum( Ivy_Obj_t * pObj ) { assert(Ivy_ObjMan(pObj)->fExtended); return Vec_IntSize( Ivy_ObjGetFanins(pObj) ); }
+
+////////////////////////////////////////////////////////////////////////
+/// ITERATORS ///
+////////////////////////////////////////////////////////////////////////
+
+// iterator over all objects, including those currently not used
+#define Ivy_ManForEachObj( p, pObj, i ) \
+ for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ )
+// iterator over the primary inputs
+#define Ivy_ManForEachPi( p, pObj, i ) \
+ for ( i = 0; i < Vec_IntSize(p->vPis) && ((pObj) = Ivy_ManPi(p, i)); i++ )
+// iterator over the primary outputs
+#define Ivy_ManForEachPo( p, pObj, i ) \
+ for ( i = 0; i < Vec_IntSize(p->vPos) && ((pObj) = Ivy_ManPo(p, i)); i++ )
+// iterator over the combinational inputs
+#define Ivy_ManForEachCi( p, pObj, i ) \
+ for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ ) \
+ if ( !Ivy_ObjIsCi(pObj) ) {} else
+// iterator over the combinational outputs
+#define Ivy_ManForEachCo( p, pObj, i ) \
+ for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ ) \
+ if ( !Ivy_ObjIsCo(pObj) ) {} else
+// iterator over logic nodes (AND and EXOR gates)
+#define Ivy_ManForEachNode( p, pObj, i ) \
+ for ( i = 1, pObj = p->pObjs+i; i < p->ObjIdNext; i++, pObj++ ) \
+ if ( !Ivy_ObjIsNode(pObj) ) {} else
+// iterator over logic latches
+#define Ivy_ManForEachLatch( p, pObj, i ) \
+ for ( i = 1, pObj = p->pObjs+i; i < p->ObjIdNext; i++, pObj++ ) \
+ if ( !Ivy_ObjIsLatch(pObj) ) {} else
+// iterator over the nodes whose IDs are stored in the array
+#define Ivy_ManForEachNodeVec( p, vIds, pObj, i ) \
+ for ( i = 0; i < Vec_IntSize(vIds) && ((pObj) = Ivy_ManObj(p, Vec_IntEntry(vIds,i))); i++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== ivyCanon.c ========================================================*/
+extern Ivy_Obj_t * Ivy_CanonAnd( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
+extern Ivy_Obj_t * Ivy_CanonExor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
+extern Ivy_Obj_t * Ivy_CanonLatch( Ivy_Obj_t * pObj, Ivy_Init_t Init );
+/*=== ivyCheck.c ========================================================*/
+extern int Ivy_ManCheck( Ivy_Man_t * p );
+/*=== ivyCut.c ==========================================================*/
+extern void Ivy_ManSeqFindCut( Ivy_Obj_t * pNode, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize );
+/*=== ivyBalance.c ======================================================*/
+extern int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel );
+/*=== ivyDfs.c ==========================================================*/
+extern Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p );
+extern Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p );
+/*=== ivyDsd.c ==========================================================*/
+extern int Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree );
+extern void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree );
+extern unsigned Ivy_TruthDsdCompute( Vec_Int_t * vTree );
+extern void Ivy_TruthDsdComputePrint( unsigned uTruth );
+extern Ivy_Obj_t * Ivy_ManDsdConstruct( Ivy_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vTree );
+/*=== ivyMan.c ==========================================================*/
+extern Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax );
+extern void Ivy_ManStop( Ivy_Man_t * p );
+extern void Ivy_ManGrow( Ivy_Man_t * p );
+extern int Ivy_ManCleanup( Ivy_Man_t * p );
+extern void Ivy_ManPrintStats( Ivy_Man_t * p );
+/*=== ivyMulti.c ==========================================================*/
+extern Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
+extern Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
+extern Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type );
+extern Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
+/*=== ivyObj.c ==========================================================*/
+extern Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost );
+extern Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type );
+extern void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin );
+extern void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop );
+extern void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop );
+extern void Ivy_ObjReplace( Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop );
+extern void Ivy_NodeFixBufferFanins( Ivy_Obj_t * pNode );
+/*=== ivyOper.c =========================================================*/
+extern Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type );
+extern Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
+extern Ivy_Obj_t * Ivy_Or( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
+extern Ivy_Obj_t * Ivy_Exor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
+extern Ivy_Obj_t * Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 );
+extern Ivy_Obj_t * Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC );
+extern Ivy_Obj_t * Ivy_Miter( Vec_Ptr_t * vPairs );
+/*=== ivyRewrite.c =========================================================*/
+extern int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
+/*=== ivyTable.c ========================================================*/
+extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Obj_t * pObj );
+extern void Ivy_TableInsert( Ivy_Obj_t * pObj );
+extern void Ivy_TableDelete( Ivy_Obj_t * pObj );
+extern void Ivy_TableUpdate( Ivy_Obj_t * pObj, int ObjIdNew );
+extern int Ivy_TableCountEntries( Ivy_Man_t * p );
+extern void Ivy_TableResize( Ivy_Man_t * p );
+/*=== ivyUndo.c =========================================================*/
+extern void Ivy_ManUndoStart( Ivy_Man_t * p );
+extern void Ivy_ManUndoStop( Ivy_Man_t * p );
+extern void Ivy_ManUndoRecord( Ivy_Man_t * p, Ivy_Obj_t * pObj );
+extern void Ivy_ManUndoPerform( Ivy_Man_t * p, Ivy_Obj_t * pRoot );
+/*=== ivyUtil.c =========================================================*/
+extern void Ivy_ManIncrementTravId( Ivy_Man_t * p );
+extern void Ivy_ManCleanTravId( Ivy_Man_t * p );
+extern int Ivy_ObjIsMuxType( Ivy_Obj_t * pObj );
+extern Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pObj, Ivy_Obj_t ** ppObjT, Ivy_Obj_t ** ppObjE );
+extern unsigned * Ivy_ManCutTruth( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth );
+extern Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin );
+extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/temp/ivy/ivyBalance.c b/src/temp/ivy/ivyBalance.c
new file mode 100644
index 00000000..bbe69dd9
--- /dev/null
+++ b/src/temp/ivy/ivyBalance.c
@@ -0,0 +1,421 @@
+/**CFile****************************************************************
+
+ FileName [ivyBalance.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Algebraic AIG balancing.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Ivy_NodeBalance( Ivy_Obj_t * pNode, int fUpdateLevel, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots );
+
+// this procedure returns 1 if the node cannot be expanded
+static inline int Ivy_NodeStopFanin( Ivy_Obj_t * pNode, int iFanin )
+{
+ if ( iFanin == 0 )
+ return Ivy_ObjFanin0(pNode)->Type != pNode->Type || Ivy_ObjRefs(Ivy_ObjFanin0(pNode)) > 1 || Ivy_ObjFaninC0(pNode);
+ else
+ return Ivy_ObjFanin1(pNode)->Type != pNode->Type || Ivy_ObjRefs(Ivy_ObjFanin1(pNode)) > 1 || Ivy_ObjFaninC1(pNode);
+}
+
+// this procedure returns 1 if the node cannot be recursively dereferenced
+static inline int Ivy_NodeBalanceDerefFanin( Ivy_Obj_t * pNode, int iFanin )
+{
+ if ( iFanin == 0 )
+ return Ivy_ObjFanin0(pNode)->Type == pNode->Type && Ivy_ObjRefs(Ivy_ObjFanin0(pNode)) == 0 && !Ivy_ObjFaninC0(pNode);
+ else
+ return Ivy_ObjFanin1(pNode)->Type == pNode->Type && Ivy_ObjRefs(Ivy_ObjFanin1(pNode)) == 0 && !Ivy_ObjFaninC1(pNode);
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs algebraic balancing of the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )
+{
+ Vec_Int_t * vNodes;
+ Vec_Ptr_t * vFront, * vSpots;
+ Ivy_Obj_t * pNode;
+ int i;
+ vSpots = Vec_PtrAlloc( 50 );
+ vFront = Vec_PtrAlloc( 50 );
+ vNodes = Ivy_ManDfs( p );
+ Ivy_ManForEachNodeVec( p, vNodes, pNode, i )
+ {
+ if ( Ivy_ObjIsBuf(pNode) )
+ continue;
+ // fix the fanin buffer problem
+ Ivy_NodeFixBufferFanins( pNode );
+ // skip node if it became a buffer
+ if ( Ivy_ObjIsBuf(pNode) )
+ continue;
+ // skip nodes with one fanout if type of the node is the same as type of the fanout
+ // such nodes will be processed when the fanouts are processed
+ if ( Ivy_ObjRefs(pNode) == 1 && Ivy_ObjIsExor(pNode) == Ivy_ObjExorFanout(pNode) )
+ continue;
+ assert( Ivy_ObjRefs(pNode) > 0 );
+ // do not balance the node if both if its fanins have more than one fanout
+ if ( Ivy_NodeStopFanin(pNode, 0) && Ivy_NodeStopFanin(pNode, 1) )
+ continue;
+ // try balancing this node
+ Ivy_NodeBalance( pNode, fUpdateLevel, vFront, vSpots );
+ }
+ Vec_IntFree( vNodes );
+ Vec_PtrFree( vSpots );
+ Vec_PtrFree( vFront );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Dereferences MFFC of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_NodeBalanceDeref_rec( Ivy_Obj_t * pNode )
+{
+ Ivy_Obj_t * pFan;
+ // deref the first fanin
+ pFan = Ivy_ObjFanin0(pNode);
+ Ivy_ObjRefsDec( pFan );
+ if ( Ivy_NodeBalanceDerefFanin(pNode, 0) )
+ Ivy_NodeBalanceDeref_rec( pFan );
+ // deref the second fanin
+ pFan = Ivy_ObjFanin1(pNode);
+ Ivy_ObjRefsDec( pFan );
+ if ( Ivy_NodeBalanceDerefFanin(pNode, 1) )
+ Ivy_NodeBalanceDeref_rec( pFan );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes nodes inside supergate and determines frontier.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_NodeBalanceCollect_rec( Ivy_Obj_t * pNode, Vec_Ptr_t * vSpots, Vec_Ptr_t * vFront )
+{
+ Ivy_Obj_t * pFanin;
+ // skip visited nodes
+ if ( Vec_PtrFind(vSpots, pNode) >= 0 )
+ return;
+ // collect node
+ Vec_PtrPush( vSpots, pNode );
+ // first fanin
+ pFanin = Ivy_ObjFanin0(pNode);
+ if ( Ivy_ObjRefs(pFanin) == 0 )
+ Ivy_NodeBalanceCollect_rec( pFanin, vSpots, vFront );
+ else if ( Ivy_ObjIsExor(pNode) && Vec_PtrFind(vFront, Ivy_ObjChild0(pNode)) >= 0 )
+ Vec_PtrRemove( vFront, Ivy_ObjChild0(pNode) );
+ else
+ Vec_PtrPushUnique( vFront, Ivy_ObjChild0(pNode) );
+ // second fanin
+ pFanin = Ivy_ObjFanin1(pNode);
+ if ( Ivy_ObjRefs(pFanin) == 0 )
+ Ivy_NodeBalanceCollect_rec( pFanin, vSpots, vFront );
+ else if ( Ivy_ObjIsExor(pNode) && Vec_PtrFind(vFront, Ivy_ObjChild1(pNode)) >= 0 )
+ Vec_PtrRemove( vFront, Ivy_ObjChild1(pNode) );
+ else
+ Vec_PtrPushUnique( vFront, Ivy_ObjChild1(pNode) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two nodes by level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_BalanceCompareByLevel( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 )
+{
+ int Level1 = Ivy_ObjLevel( *pp1 );
+ int Level2 = Ivy_ObjLevel( *pp2 );
+ if ( Level1 > Level2 )
+ return -1;
+ if ( Level1 < Level2 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes nodes inside supergate and determines frontier.]
+
+ Description [Return 1 if the output needs to be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_NodeBalancePrepare( Ivy_Obj_t * pNode, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots )
+{
+ Ivy_Man_t * pMan = Ivy_ObjMan( pNode );
+ Ivy_Obj_t * pObj, * pNext;
+ int i, k, Counter = 0;
+ // dereference the cone
+ Ivy_NodeBalanceDeref_rec( pNode );
+ // collect the frontier and the internal nodes
+ Vec_PtrClear( vFront );
+ Vec_PtrClear( vSpots );
+ Ivy_NodeBalanceCollect_rec( pNode, vSpots, vFront );
+ // remove all the nodes
+ Vec_PtrForEachEntry( vSpots, pObj, i )
+ {
+ // skip the first entry (the node itself)
+ if ( i == 0 ) continue;
+ // collect the free entries
+ Vec_IntPush( pMan->vFree, pObj->Id );
+ Ivy_ObjDelete( pObj, 1 );
+ }
+ // sort nodes by level in decreasing order
+ qsort( (void *)Vec_PtrArray(vFront), Vec_PtrSize(vFront), sizeof(Ivy_Obj_t *),
+ (int (*)(const void *, const void *))Ivy_BalanceCompareByLevel );
+ // check if there are nodes and their complements
+ Counter = 0;
+ Vec_PtrForEachEntry( vFront, pObj, i )
+ {
+ if ( i == Vec_PtrSize(vFront) - 1 )
+ break;
+ pNext = Vec_PtrEntry( vFront, i+1 );
+ if ( Ivy_Regular(pObj) == Ivy_Regular(pNext) )
+ {
+ assert( pObj == Ivy_Not(pNext) );
+ Vec_PtrWriteEntry( vFront, i, NULL );
+ Vec_PtrWriteEntry( vFront, i+1, NULL );
+ i++;
+ Counter++;
+ }
+ }
+ // if there are no complemented pairs, go ahead and balance
+ if ( Counter == 0 )
+ return 0;
+ // if there are complemented pairs and this is AND, create const 0
+ if ( Counter > 0 && Ivy_ObjIsAnd(pNode) )
+ {
+ Vec_PtrClear( vFront );
+ Vec_PtrPush( vFront, Ivy_ManConst0(pMan) );
+ return 0;
+ }
+ assert( Counter > 0 && Ivy_ObjIsExor(pNode) );
+ // remove the pairs
+ k = 0;
+ Vec_PtrForEachEntry( vFront, pObj, i )
+ if ( pObj )
+ Vec_PtrWriteEntry( vFront, k++, pObj );
+ Vec_PtrShrink( vFront, k );
+ // add constant zero node if nothing is left
+ if ( Vec_PtrSize(vFront) == 0 )
+ Vec_PtrPush( vFront, Ivy_ManConst0(pMan) );
+ // return 1 if the number of pairs is odd (need to complement the output)
+ return Counter & 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds the left bound on the next candidate to be paired.]
+
+ Description [The nodes in the array are in the decreasing order of levels.
+ The last node in the array has the smallest level. By default it would be paired
+ with the next node on the left. However, it may be possible to pair it with some
+ other node on the left, in such a way that the new node is shared. This procedure
+ finds the index of the left-most node, which can be paired with the last node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
+{
+ Ivy_Obj_t * pNodeRight, * pNodeLeft;
+ int Current;
+ // if two or less nodes, pair with the first
+ if ( Vec_PtrSize(vSuper) < 3 )
+ return 0;
+ // set the pointer to the one before the last
+ Current = Vec_PtrSize(vSuper) - 2;
+ pNodeRight = Vec_PtrEntry( vSuper, Current );
+ // go through the nodes to the left of this one
+ for ( Current--; Current >= 0; Current-- )
+ {
+ // get the next node on the left
+ pNodeLeft = Vec_PtrEntry( vSuper, Current );
+ // if the level of this node is different, quit the loop
+ if ( Ivy_Regular(pNodeLeft)->Level != Ivy_Regular(pNodeRight)->Level )
+ break;
+ }
+ Current++;
+ // get the node, for which the equality holds
+ pNodeLeft = Vec_PtrEntry( vSuper, Current );
+ assert( Ivy_Regular(pNodeLeft)->Level == Ivy_Regular(pNodeRight)->Level );
+ return Current;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Moves closer to the end the node that is best for sharing.]
+
+ Description [If there is no node with sharing, randomly chooses one of
+ the legal nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
+{
+ Ivy_Obj_t * pNode1, * pNode2, * pNode3, * pGhost;
+ int RightBound, i;
+ // get the right bound
+ RightBound = Vec_PtrSize(vSuper) - 2;
+ assert( LeftBound <= RightBound );
+ if ( LeftBound == RightBound )
+ return;
+ // get the two last nodes
+ pNode1 = Vec_PtrEntry( vSuper, RightBound + 1 );
+ pNode2 = Vec_PtrEntry( vSuper, RightBound );
+ // find the first node that can be shared
+ for ( i = RightBound; i >= LeftBound; i-- )
+ {
+ pNode3 = Vec_PtrEntry( vSuper, i );
+ pGhost = Ivy_ObjCreateGhost( pNode1, pNode3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE );
+ if ( Ivy_TableLookup( pGhost ) )
+ {
+ if ( pNode3 == pNode2 )
+ return;
+ Vec_PtrWriteEntry( vSuper, i, pNode2 );
+ Vec_PtrWriteEntry( vSuper, RightBound, pNode3 );
+ return;
+ }
+ }
+/*
+ // we did not find the node to share, randomize choice
+ {
+ int Choice = rand() % (RightBound - LeftBound + 1);
+ pNode3 = Vec_PtrEntry( vSuper, LeftBound + Choice );
+ if ( pNode3 == pNode2 )
+ return;
+ Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pNode2 );
+ Vec_PtrWriteEntry( vSuper, RightBound, pNode3 );
+ }
+*/
+}
+
+/**Function*************************************************************
+
+ Synopsis [Inserts a new node in the order by levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vFront, Ivy_Obj_t * pNode )
+{
+ Ivy_Obj_t * pNode1, * pNode2;
+ int i;
+ if ( Vec_PtrPushUnique(vFront, pNode) )
+ return;
+ // find the p of the node
+ for ( i = vFront->nSize-1; i > 0; i-- )
+ {
+ pNode1 = vFront->pArray[i ];
+ pNode2 = vFront->pArray[i-1];
+ if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level )
+ break;
+ vFront->pArray[i ] = pNode2;
+ vFront->pArray[i-1] = pNode1;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Balances one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_NodeBalance( Ivy_Obj_t * pNode, int fUpdateLevel, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots )
+{
+ Ivy_Man_t * pMan = Ivy_ObjMan( pNode );
+ Ivy_Obj_t * pFan0, * pFan1, * pNodeNew;
+ int fCompl, LeftBound;
+ // remove internal nodes and derive the frontier
+ fCompl = Ivy_NodeBalancePrepare( pNode, vFront, vSpots );
+ assert( Vec_PtrSize(vFront) > 0 );
+ // balance the nodes
+ while ( Vec_PtrSize(vFront) > 1 )
+ {
+ // find the left bound on the node to be paired
+ LeftBound = (!fUpdateLevel)? 0 : Ivy_NodeBalanceFindLeft( vFront );
+ // find the node that can be shared (if no such node, randomize choice)
+ Ivy_NodeBalancePermute( pMan, vFront, LeftBound, Ivy_ObjIsExor(pNode) );
+ // pull out the last two nodes
+ pFan0 = Vec_PtrPop(vFront); assert( !Ivy_ObjIsConst1(Ivy_Regular(pFan0)) );
+ pFan1 = Vec_PtrPop(vFront); assert( !Ivy_ObjIsConst1(Ivy_Regular(pFan1)) );
+ // create the new node
+ pNodeNew = Ivy_ObjCreate( Ivy_ObjCreateGhost(pFan0, pFan1, Ivy_ObjType(pNode), IVY_INIT_NONE) );
+ // add the new node to the frontier
+ Ivy_NodeBalancePushUniqueOrderByLevel( vFront, pNodeNew );
+ }
+ assert( Vec_PtrSize(vFront) == 1 );
+ // perform the replacement
+ Ivy_ObjReplace( pNode, Ivy_NotCond(Vec_PtrPop(vFront), fCompl), 1, 1 );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyCanon.c b/src/temp/ivy/ivyCanon.c
new file mode 100644
index 00000000..c6f43d15
--- /dev/null
+++ b/src/temp/ivy/ivyCanon.c
@@ -0,0 +1,147 @@
+/**CFile****************************************************************
+
+ FileName [ivyCanon.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Finding canonical form of objects.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyCanon.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Ivy_Obj_t * Ivy_TableLookupPair_rec( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1, int fCompl0, int fCompl1, Ivy_Type_t Type );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates the canonical form of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_CanonPair_rec( Ivy_Obj_t * pGhost )
+{
+ Ivy_Obj_t * pResult, * pLat0, * pLat1;
+ Ivy_Init_t Init, Init0, Init1;
+ int fCompl0, fCompl1;
+ Ivy_Type_t Type;
+ assert( Ivy_ObjIsNode(pGhost) );
+ assert( Ivy_ObjIsAnd(pGhost) || (!Ivy_ObjFaninC0(pGhost) && !Ivy_ObjFaninC1(pGhost)) );
+ assert( Ivy_ObjFaninId0(pGhost) != 0 && Ivy_ObjFaninId1(pGhost) != 0 );
+ // consider the case when the pair is canonical
+ if ( !Ivy_ObjIsLatch(Ivy_ObjFanin0(pGhost)) || !Ivy_ObjIsLatch(Ivy_ObjFanin1(pGhost)) )
+ {
+ if ( pResult = Ivy_TableLookup( pGhost ) )
+ return pResult;
+ return Ivy_ObjCreate( pGhost );
+ }
+ /// remember the latches
+ pLat0 = Ivy_ObjFanin0(pGhost);
+ pLat1 = Ivy_ObjFanin1(pGhost);
+ // remember type and compls
+ Type = Ivy_ObjType(pGhost);
+ fCompl0 = Ivy_ObjFaninC0(pGhost);
+ fCompl1 = Ivy_ObjFaninC1(pGhost);
+ // modify the fanins to be latch fanins
+ pGhost->Fanin0 = Ivy_ObjFaninId0(pLat0);
+ pGhost->Fanin1 = Ivy_ObjFaninId0(pLat1);
+ // call recursively
+ pResult = Ivy_CanonPair_rec( pGhost );
+ // build latch on top of this
+ Init0 = Ivy_InitNotCond( Ivy_ObjInit(pLat0), fCompl0 );
+ Init1 = Ivy_InitNotCond( Ivy_ObjInit(pLat1), fCompl1 );
+ Init = (Type == IVY_AND)? Ivy_InitAnd(Init0, Init1) : Ivy_InitExor(Init0, Init1);
+ return Ivy_CanonLatch( pResult, Init );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the canonical form of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_CanonAnd( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
+{
+ Ivy_Obj_t * pGhost, * pResult;
+ pGhost = Ivy_ObjCreateGhost( pObj0, pObj1, IVY_AND, IVY_INIT_NONE );
+ pResult = Ivy_CanonPair_rec( pGhost );
+ return pResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the canonical form of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_CanonExor( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
+{
+ Ivy_Obj_t * pGhost, * pResult;
+ int fCompl = Ivy_IsComplement(pObj0) ^ Ivy_IsComplement(pObj1);
+ pObj0 = Ivy_Regular(pObj0);
+ pObj1 = Ivy_Regular(pObj1);
+ pGhost = Ivy_ObjCreateGhost( pObj0, pObj1, IVY_EXOR, IVY_INIT_NONE );
+ pResult = Ivy_CanonPair_rec( pGhost );
+ return Ivy_NotCond( pResult, fCompl );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the canonical form of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_CanonLatch( Ivy_Obj_t * pObj, Ivy_Init_t Init )
+{
+ Ivy_Obj_t * pGhost, * pResult;
+ int fCompl = Ivy_IsComplement(pObj);
+ pObj = Ivy_Regular(pObj);
+ pGhost = Ivy_ObjCreateGhost( pObj, Ivy_ObjConst1(pObj), IVY_LATCH, Ivy_InitNotCond(Init, fCompl) );
+ pResult = Ivy_TableLookup( pGhost );
+ if ( pResult == NULL )
+ pResult = Ivy_ObjCreate( pGhost );
+ return Ivy_NotCond( pResult, fCompl );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyCheck.c b/src/temp/ivy/ivyCheck.c
new file mode 100644
index 00000000..c39eac12
--- /dev/null
+++ b/src/temp/ivy/ivyCheck.c
@@ -0,0 +1,121 @@
+/**CFile****************************************************************
+
+ FileName [ivyCheck.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [AIG checking procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyCheck.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Checks the consistency of the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ManCheck( Ivy_Man_t * pMan )
+{
+ Ivy_Obj_t * pObj, * pObj2;
+ int i;
+ Ivy_ManForEachObj( pMan, pObj, i )
+ {
+ // skip deleted nodes
+ if ( Ivy_ObjIsNone(pObj) )
+ continue;
+ // consider the constant node and PIs
+ if ( i == 0 || Ivy_ObjIsPi(pObj) )
+ {
+ if ( Ivy_ObjFaninId0(pObj) || Ivy_ObjFaninId1(pObj) || Ivy_ObjLevel(pObj) )
+ {
+ printf( "Ivy_ManCheck: The AIG has non-standard constant or PI node with ID \"%d\".\n", pObj->Id );
+ return 0;
+ }
+ continue;
+ }
+ if ( Ivy_ObjIsPo(pObj) )
+ {
+ if ( Ivy_ObjFaninId1(pObj) )
+ {
+ printf( "Ivy_ManCheck: The AIG has non-standard PO node with ID \"%d\".\n", pObj->Id );
+ return 0;
+ }
+ continue;
+ }
+ if ( Ivy_ObjIsBuf(pObj) )
+ {
+ continue;
+ }
+ if ( Ivy_ObjIsLatch(pObj) )
+ {
+ if ( Ivy_ObjFaninId1(pObj) != 0 )
+ {
+ printf( "Ivy_ManCheck: The latch with ID \"%d\" contains second fanin.\n", pObj->Id );
+ return 0;
+ }
+ if ( Ivy_ObjInit(pObj) == 0 )
+ {
+ printf( "Ivy_ManCheck: The latch with ID \"%d\" does not have initial state.\n", pObj->Id );
+ return 0;
+ }
+ pObj2 = Ivy_TableLookup( pObj );
+ if ( pObj2 != pObj )
+ printf( "Ivy_ManCheck: Latch with ID \"%d\" is not in the structural hashing table.\n", pObj->Id );
+ continue;
+ }
+ // consider the AND node
+ if ( !Ivy_ObjFaninId0(pObj) || !Ivy_ObjFaninId1(pObj) )
+ {
+ printf( "Ivy_ManCheck: The AIG has internal node \"%d\" with a constant fanin.\n", pObj->Id );
+ return 0;
+ }
+ if ( Ivy_ObjFaninId0(pObj) <= Ivy_ObjFaninId1(pObj) )
+ {
+ printf( "Ivy_ManCheck: The AIG has node \"%d\" with a wrong ordering of fanins.\n", pObj->Id );
+ return 0;
+ }
+// if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) )
+// printf( "Ivy_ManCheck: Node with ID \"%d\" has level that does not agree with the fanin levels.\n", pObj->Id );
+ pObj2 = Ivy_TableLookup( pObj );
+ if ( pObj2 != pObj )
+ printf( "Ivy_ManCheck: Node with ID \"%d\" is not in the structural hashing table.\n", pObj->Id );
+ }
+ // count the number of nodes in the table
+ if ( Ivy_TableCountEntries(pMan) != Ivy_ManAndNum(pMan) + Ivy_ManExorNum(pMan) + Ivy_ManLatchNum(pMan) )
+ {
+ printf( "Ivy_ManCheck: The number of nodes in the structural hashing table is wrong.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyCut.c b/src/temp/ivy/ivyCut.c
new file mode 100644
index 00000000..a8fd148b
--- /dev/null
+++ b/src/temp/ivy/ivyCut.c
@@ -0,0 +1,205 @@
+/**CFile****************************************************************
+
+ FileName [ivyCut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Computes reconvergence driven sequential cut.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyCut.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Evaluate the cost of removing the node from the set of leaves.]
+
+ Description [Returns the number of new leaves that will be brought in.
+ Returns large number if the node cannot be removed from the set of leaves.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Ivy_NodeGetLeafCostOne( Ivy_Man_t * p, int Leaf, Vec_Int_t * vInside )
+{
+ Ivy_Obj_t * pNode;
+ int nLatches, FaninLeaf, Cost;
+ // make sure leaf is not a contant node
+ assert( Leaf > 0 );
+ // get the node
+ pNode = Ivy_ManObj( p, Ivy_LeafId(Leaf) );
+ // cannot expand over the PI node
+ if ( Ivy_ObjIsPi(pNode) || Ivy_ObjIsConst1(pNode) )
+ return 999;
+ // get the number of latches
+ nLatches = Ivy_LeafLat(Leaf) + Ivy_ObjIsLatch(pNode);
+ if ( nLatches > 15 )
+ return 999;
+ // get the first fanin
+ FaninLeaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pNode), nLatches );
+ Cost = FaninLeaf && (Vec_IntFind(vInside, FaninLeaf) == -1);
+ // quit if this is the one fanin node
+ if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) )
+ return Cost;
+ assert( Ivy_ObjIsNode(pNode) );
+ // get the second fanin
+ FaninLeaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pNode), nLatches );
+ Cost += FaninLeaf && (Vec_IntFind(vInside, FaninLeaf) == -1);
+ return Cost;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.]
+
+ Description [This procedure looks at the current leaves and tries to change
+ one leaf at a time in such a way that the cut grows as little as possible.
+ In evaluating the fanins, this procedure looks only at their immediate
+ predecessors (this is why it is called a one-level construction procedure).]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ManSeqFindCut_int( Ivy_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSizeLimit )
+{
+ Ivy_Obj_t * pNode;
+ int CostBest, CostCur, Leaf, LeafBest, Next, nLatches, i;
+ int LeavesBest[10];
+ int Counter;
+
+ // add random selection of the best fanin!!!
+
+ // find the best fanin
+ CostBest = 99;
+ LeafBest = -1;
+ Counter = -1;
+//printf( "Evaluating fanins of the cut:\n" );
+ Vec_IntForEachEntry( vFront, Leaf, i )
+ {
+ CostCur = Ivy_NodeGetLeafCostOne( p, Leaf, vInside );
+//printf( " Fanin %s has cost %d.\n", Ivy_ObjName(pNode), CostCur );
+ if ( CostBest > CostCur )
+ {
+ CostBest = CostCur;
+ LeafBest = Leaf;
+ LeavesBest[0] = Leaf;
+ Counter = 1;
+ }
+ else if ( CostBest == CostCur )
+ LeavesBest[Counter++] = Leaf;
+
+ if ( CostBest <= 1 ) // can be if ( CostBest <= 1 )
+ break;
+ }
+ if ( CostBest == 99 )
+ return 0;
+// return Ivy_NodeBuildCutLevelTwo_int( vInside, vFront, nFaninLimit );
+
+ assert( CostBest < 3 );
+ if ( Vec_IntSize(vFront) - 1 + CostBest > nSizeLimit )
+ return 0;
+// return Ivy_NodeBuildCutLevelTwo_int( vInside, vFront, nFaninLimit );
+
+ assert( Counter > 0 );
+printf( "%d", Counter );
+
+ LeafBest = LeavesBest[rand() % Counter];
+
+ // remove the node from the array
+ assert( LeafBest >= 0 );
+ Vec_IntRemove( vFront, LeafBest );
+//printf( "Removing fanin %s.\n", Ivy_ObjName(pNode) );
+
+ // get the node and its latches
+ pNode = Ivy_ManObj( p, Ivy_LeafId(LeafBest) );
+ nLatches = Ivy_LeafLat(LeafBest) + Ivy_ObjIsLatch(pNode);
+ assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) );
+
+ // add the left child to the fanins
+ Next = Ivy_LeafCreate( Ivy_ObjFaninId0(pNode), nLatches );
+ if ( Next && Vec_IntFind(vInside, Next) == -1 )
+ {
+//printf( "Adding fanin %s.\n", Ivy_ObjName(pNext) );
+ Vec_IntPush( vFront, Next );
+ Vec_IntPush( vInside, Next );
+ }
+
+ // quit if this is the one fanin node
+ if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) )
+ return 1;
+ assert( Ivy_ObjIsNode(pNode) );
+
+ // add the right child to the fanins
+ Next = Ivy_LeafCreate( Ivy_ObjFaninId1(pNode), nLatches );
+ if ( Next && Vec_IntFind(vInside, Next) == -1 )
+ {
+//printf( "Adding fanin %s.\n", Ivy_ObjName(pNext) );
+ Vec_IntPush( vFront, Next );
+ Vec_IntPush( vInside, Next );
+ }
+ assert( Vec_IntSize(vFront) <= nSizeLimit );
+ // keep doing this
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes one sequential cut of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManSeqFindCut( Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize )
+{
+ assert( !Ivy_IsComplement(pRoot) );
+ assert( Ivy_ObjIsNode(pRoot) );
+ assert( Ivy_ObjFaninId0(pRoot) );
+ assert( Ivy_ObjFaninId1(pRoot) );
+
+ // start the cut
+ Vec_IntClear( vFront );
+ Vec_IntPush( vFront, Ivy_LeafCreate(Ivy_ObjFaninId0(pRoot), 0) );
+ Vec_IntPush( vFront, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) );
+
+ // start the visited nodes
+ Vec_IntClear( vInside );
+ Vec_IntPush( vInside, Ivy_LeafCreate(pRoot->Id, 0) );
+ Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId0(pRoot), 0) );
+ Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) );
+
+ // compute the cut
+ while ( Ivy_ManSeqFindCut_int( Ivy_ObjMan(pRoot), vFront, vInside, nSize ) );
+ assert( Vec_IntSize(vFront) <= nSize );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyDfs.c b/src/temp/ivy/ivyDfs.c
new file mode 100644
index 00000000..2db80b00
--- /dev/null
+++ b/src/temp/ivy/ivyDfs.c
@@ -0,0 +1,152 @@
+/**CFile****************************************************************
+
+ FileName [ivyDfs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [DFS collection procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyDfs.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Collects nodes in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManDfs_rec( Ivy_Obj_t * pObj, Vec_Int_t * vNodes )
+{
+ if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) )
+ return;
+ if ( Ivy_ObjIsMarkA(pObj) )
+ return;
+ Ivy_ObjSetMarkA(pObj);
+ assert( Ivy_ObjIsBuf(pObj) || Ivy_ObjIsAnd(pObj) || Ivy_ObjIsExor(pObj) );
+ Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes );
+ if ( !Ivy_ObjIsBuf(pObj) )
+ Ivy_ManDfs_rec( Ivy_ObjFanin1(pObj), vNodes );
+ Vec_IntPush( vNodes, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects AND/EXOR nodes in the DFS order from CIs to COs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p )
+{
+ Vec_Int_t * vNodes;
+ Ivy_Obj_t * pObj;
+ int i;
+ // collect the nodes
+ vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) );
+ if ( Ivy_ManLatchNum(p) > 0 )
+ Ivy_ManForEachCo( p, pObj, i )
+ Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes );
+ else
+ Ivy_ManForEachPo( p, pObj, i )
+ Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes );
+ // unmark the collected nodes
+ Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
+ Ivy_ObjClearMarkA(pObj);
+ // make sure network does not have dangling nodes
+ assert( Vec_IntSize(vNodes) == Ivy_ManNodeNum(p) + Ivy_ManBufNum(p) );
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects nodes in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManDfsExt_rec( Ivy_Obj_t * pObj, Vec_Int_t * vNodes )
+{
+ Vec_Int_t * vFanins;
+ int i, Fanin;
+ if ( !Ivy_ObjIsNodeExt(pObj) || Ivy_ObjIsMarkA(pObj) )
+ return;
+ // mark the node as visited
+ Ivy_ObjSetMarkA(pObj);
+ // traverse the fanins
+ vFanins = Ivy_ObjGetFanins( pObj );
+ Vec_IntForEachEntry( vFanins, Fanin, i )
+ Ivy_ManDfsExt_rec( Ivy_ObjObj(pObj, Ivy_FanId(Fanin)), vNodes );
+ // add the node
+ Vec_IntPush( vNodes, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects nodes in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p )
+{
+ Vec_Int_t * vNodes;
+ Ivy_Obj_t * pObj, * pFanin;
+ int i;
+ assert( p->fExtended );
+ assert( Ivy_ManLatchNum(p) == 0 );
+ // make sure network does not have buffers
+ vNodes = Vec_IntAlloc( 10 );
+ Ivy_ManForEachPo( p, pObj, i )
+ {
+ pFanin = Ivy_ManObj( p, Ivy_FanId( Ivy_ObjReadFanin(pObj,0) ) );
+ Ivy_ManDfsExt_rec( pFanin, vNodes );
+ }
+ Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
+ Ivy_ObjClearMarkA(pObj);
+ // make sure network does not have dangling nodes
+ // the network may have dangling nodes if some fanins of ESOPs do not appear in cubes
+// assert( p->nNodes == Vec_PtrSize(vNodes) );
+ return vNodes;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyDsd.c b/src/temp/ivy/ivyDsd.c
new file mode 100644
index 00000000..5dfdd30f
--- /dev/null
+++ b/src/temp/ivy/ivyDsd.c
@@ -0,0 +1,819 @@
+/**CFile****************************************************************
+
+ FileName [ivyDsd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Disjoint-support decomposition.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyDsd.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// decomposition types
+typedef enum {
+ IVY_DEC_PI, // 0: var
+ IVY_DEC_CONST1, // 1: CONST1
+ IVY_DEC_BUF, // 2: BUF
+ IVY_DEC_AND, // 3: AND
+ IVY_DEC_EXOR, // 4: EXOR
+ IVY_DEC_MUX, // 5: MUX
+ IVY_DEC_MAJ, // 6: MAJ
+ IVY_DEC_PRIME // 7: undecomposable
+} Ivy_DecType_t;
+
+typedef struct Ivy_Dec_t_ Ivy_Dec_t;
+struct Ivy_Dec_t_
+{
+ unsigned Type : 4; // the node type (PI, CONST1, AND, EXOR, MUX, PRIME)
+ unsigned fCompl : 1; // shows if node is complemented (root node only)
+ unsigned nFans : 3; // the number of fanins
+ unsigned Fan0 : 4; // fanin 0
+ unsigned Fan1 : 4; // fanin 1
+ unsigned Fan2 : 4; // fanin 2
+ unsigned Fan3 : 4; // fanin 3
+ unsigned Fan4 : 4; // fanin 4
+ unsigned Fan5 : 4; // fanin 5
+};
+
+static inline int Ivy_DecToInt( Ivy_Dec_t Node ) { return *((int *)&Node); }
+static inline Ivy_Dec_t Ivy_IntToDec( int Node ) { return *((Ivy_Dec_t *)&Node); }
+static inline void Ivy_DecClear( Ivy_Dec_t * pNode ) { *((int *)pNode) = 0; }
+
+
+static unsigned s_Masks[6][2] = {
+ { 0x55555555, 0xAAAAAAAA },
+ { 0x33333333, 0xCCCCCCCC },
+ { 0x0F0F0F0F, 0xF0F0F0F0 },
+ { 0x00FF00FF, 0xFF00FF00 },
+ { 0x0000FFFF, 0xFFFF0000 },
+ { 0x00000000, 0xFFFFFFFF }
+};
+
+static inline int Ivy_TruthWordCountOnes( unsigned uWord )
+{
+ uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
+ uWord = (uWord & 0x33333333) + ((uWord>>2) & 0x33333333);
+ uWord = (uWord & 0x0F0F0F0F) + ((uWord>>4) & 0x0F0F0F0F);
+ uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF);
+ return (uWord & 0x0000FFFF) + (uWord>>16);
+}
+
+static inline int Ivy_TruthCofactorIsConst( unsigned uTruth, int Var, int Cof, int Const )
+{
+ if ( Const == 0 )
+ return (uTruth & s_Masks[Var][Cof]) == 0;
+ else
+ return (uTruth & s_Masks[Var][Cof]) == s_Masks[Var][Cof];
+}
+
+static inline int Ivy_TruthCofactorIsOne( unsigned uTruth, int Var )
+{
+ return (uTruth & s_Masks[Var][0]) == 0;
+}
+
+static inline unsigned Ivy_TruthCofactor( unsigned uTruth, int Var )
+{
+ unsigned uCofactor = uTruth & s_Masks[Var >> 1][(Var & 1) == 0];
+ int Shift = (1 << (Var >> 1));
+ if ( Var & 1 )
+ return uCofactor | (uCofactor << Shift);
+ return uCofactor | (uCofactor >> Shift);
+}
+
+static inline unsigned Ivy_TruthCofactor2( unsigned uTruth, int Var0, int Var1 )
+{
+ return Ivy_TruthCofactor( Ivy_TruthCofactor(uTruth, Var0), Var1 );
+}
+
+// returns 1 if the truth table depends on this var (var is regular interger var)
+static inline int Ivy_TruthDepends( unsigned uTruth, int Var )
+{
+ return Ivy_TruthCofactor(uTruth, Var << 1) != Ivy_TruthCofactor(uTruth, (Var << 1) | 1);
+}
+
+static inline void Ivy_DecSetVar( Ivy_Dec_t * pNode, int iNum, unsigned Var )
+{
+ assert( iNum >= 0 && iNum <= 5 );
+ switch( iNum )
+ {
+ case 0: pNode->Fan0 = Var; break;
+ case 1: pNode->Fan1 = Var; break;
+ case 2: pNode->Fan2 = Var; break;
+ case 3: pNode->Fan3 = Var; break;
+ case 4: pNode->Fan4 = Var; break;
+ case 5: pNode->Fan5 = Var; break;
+ }
+}
+
+static inline unsigned Ivy_DecGetVar( Ivy_Dec_t * pNode, int iNum )
+{
+ assert( iNum >= 0 && iNum <= 5 );
+ switch( iNum )
+ {
+ case 0: return pNode->Fan0;
+ case 1: return pNode->Fan1;
+ case 2: return pNode->Fan2;
+ case 3: return pNode->Fan3;
+ case 4: return pNode->Fan4;
+ case 5: return pNode->Fan5;
+ }
+ return ~0;
+}
+
+static int Ivy_TruthDecompose_rec( unsigned uTruth, Vec_Int_t * vTree );
+static int Ivy_TruthRecognizeMuxMaj( unsigned uTruth, int * pSupp, int nSupp, Vec_Int_t * vTree );
+
+//int nTruthDsd;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes DSD of truth table of 5 variables or less.]
+
+ Description [Returns 1 if the function is a constant or is fully
+ DSD decomposable using AND/EXOR/MUX gates.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree )
+{
+ Ivy_Dec_t Node;
+ int i, RetValue;
+ // set the PI variables
+ Vec_IntClear( vTree );
+ for ( i = 0; i < 5; i++ )
+ Vec_IntPush( vTree, 0 );
+ // check if it is a constant
+ if ( uTruth == 0 || ~uTruth == 0 )
+ {
+ Ivy_DecClear( &Node );
+ Node.Type = IVY_DEC_CONST1;
+ Node.fCompl = (uTruth == 0);
+ Vec_IntPush( vTree, Ivy_DecToInt(Node) );
+ return 1;
+ }
+ // perform the decomposition
+ RetValue = Ivy_TruthDecompose_rec( uTruth, vTree );
+ if ( RetValue == -1 )
+ return 0;
+ // get the topmost node
+ if ( (RetValue >> 1) < 5 )
+ { // add buffer
+ Ivy_DecClear( &Node );
+ Node.Type = IVY_DEC_BUF;
+ Node.fCompl = (RetValue & 1);
+ Node.Fan0 = ((RetValue >> 1) << 1);
+ Vec_IntPush( vTree, Ivy_DecToInt(Node) );
+ }
+ else if ( RetValue & 1 )
+ { // check if the topmost node has to be complemented
+ Node = Ivy_IntToDec( Vec_IntPop(vTree) );
+ assert( Node.fCompl == 0 );
+ Node.fCompl = (RetValue & 1);
+ Vec_IntPush( vTree, Ivy_DecToInt(Node) );
+ }
+ if ( uTruth != Ivy_TruthDsdCompute(vTree) )
+ printf( "Verification failed.\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes DSD of truth table.]
+
+ Description [Returns the number of topmost decomposition node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_TruthDecompose_rec( unsigned uTruth, Vec_Int_t * vTree )
+{
+ Ivy_Dec_t Node;
+ int Supp[5], Vars0[5], Vars1[5], Vars2[5], * pVars;
+ int nSupp, Count0, Count1, Count2, nVars, RetValue, fCompl, i;
+ unsigned uTruthCof, uCof0, uCof1;
+
+ // get constant confactors
+ Count0 = Count1 = Count2 = nSupp = 0;
+ for ( i = 0; i < 5; i++ )
+ {
+ if ( Ivy_TruthCofactorIsConst(uTruth, i, 0, 0) )
+ Vars0[Count0++] = (i << 1) | 0;
+ else if ( Ivy_TruthCofactorIsConst(uTruth, i, 1, 0) )
+ Vars0[Count0++] = (i << 1) | 1;
+ else if ( Ivy_TruthCofactorIsConst(uTruth, i, 0, 1) )
+ Vars1[Count1++] = (i << 1) | 0;
+ else if ( Ivy_TruthCofactorIsConst(uTruth, i, 1, 1) )
+ Vars1[Count1++] = (i << 1) | 1;
+ else
+ {
+ uCof0 = Ivy_TruthCofactor( uTruth, (i << 1) | 1 );
+ uCof1 = Ivy_TruthCofactor( uTruth, (i << 1) | 0 );
+ if ( uCof0 == ~uCof1 )
+ Vars2[Count2++] = (i << 1) | 0;
+ else if ( uCof0 != uCof1 )
+ Supp[nSupp++] = i;
+ }
+ }
+ assert( Count0 == 0 || Count1 == 0 );
+ assert( Count0 == 0 || Count2 == 0 );
+ assert( Count1 == 0 || Count2 == 0 );
+
+ // consider the case of a single variable
+ if ( Count0 == 1 && nSupp == 0 )
+ return Vars0[0];
+
+ // consider more complex decompositions
+ if ( Count0 == 0 && Count1 == 0 && Count2 == 0 )
+ return Ivy_TruthRecognizeMuxMaj( uTruth, Supp, nSupp, vTree );
+
+ // extract the nodes
+ Ivy_DecClear( &Node );
+ if ( Count0 > 0 )
+ nVars = Count0, pVars = Vars0, Node.Type = IVY_DEC_AND, fCompl = 0;
+ else if ( Count1 > 0 )
+ nVars = Count1, pVars = Vars1, Node.Type = IVY_DEC_AND, fCompl = 1, uTruth = ~uTruth;
+ else if ( Count2 > 0 )
+ nVars = Count2, pVars = Vars2, Node.Type = IVY_DEC_EXOR, fCompl = 0;
+ else
+ assert( 0 );
+ Node.nFans = nVars+(nSupp>0);
+
+ // compute cofactor
+ uTruthCof = uTruth;
+ for ( i = 0; i < nVars; i++ )
+ {
+ uTruthCof = Ivy_TruthCofactor( uTruthCof, pVars[i] );
+ Ivy_DecSetVar( &Node, i, pVars[i] );
+ }
+
+ if ( Node.Type == IVY_DEC_EXOR )
+ fCompl ^= ((Node.nFans & 1) == 0);
+
+ if ( nSupp > 0 )
+ {
+ assert( uTruthCof != 0 && ~uTruthCof != 0 );
+ // call recursively
+ RetValue = Ivy_TruthDecompose_rec( uTruthCof, vTree );
+ // quit if non-decomposable
+ if ( RetValue == -1 )
+ return -1;
+ // remove the complement from the child if the node is EXOR
+ if ( Node.Type == IVY_DEC_EXOR && (RetValue & 1) )
+ {
+ fCompl ^= 1;
+ RetValue ^= 1;
+ }
+ // set the new decomposition
+ Ivy_DecSetVar( &Node, nVars, RetValue );
+ }
+ else if ( Node.Type == IVY_DEC_EXOR )
+ fCompl ^= (uTruthCof == 0);
+
+ Vec_IntPush( vTree, Ivy_DecToInt(Node) );
+ return ((Vec_IntSize(vTree)-1) << 1) | fCompl;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns a non-negative number if the truth table is a MUX.]
+
+ Description [If the truth table is a MUX, returns the variable as follows:
+ first, control variable; second, positive cofactor; third, negative cofactor.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_TruthRecognizeMuxMaj( unsigned uTruth, int * pSupp, int nSupp, Vec_Int_t * vTree )
+{
+ Ivy_Dec_t Node;
+ int i, k, RetValue0, RetValue1;
+ unsigned uCof0, uCof1, Num;
+ char Count[3];
+ assert( nSupp >= 3 );
+ // start the node
+ Ivy_DecClear( &Node );
+ Node.Type = IVY_DEC_MUX;
+ Node.nFans = 3;
+ // try each of the variables
+ for ( i = 0; i < nSupp; i++ )
+ {
+ // get the cofactors with respect to these variables
+ uCof0 = Ivy_TruthCofactor( uTruth, (pSupp[i] << 1) | 1 );
+ uCof1 = Ivy_TruthCofactor( uTruth, pSupp[i] << 1 );
+ // go through all other variables and make sure
+ // each of them belongs to the support of one cofactor
+ for ( k = 0; k < nSupp; k++ )
+ {
+ if ( k == i )
+ continue;
+ if ( Ivy_TruthDepends(uCof0, pSupp[k]) && Ivy_TruthDepends(uCof1, pSupp[k]) )
+ break;
+ }
+ if ( k < nSupp )
+ continue;
+ // MUX decomposition exists
+ RetValue0 = Ivy_TruthDecompose_rec( uCof0, vTree );
+ if ( RetValue0 == -1 )
+ break;
+ RetValue1 = Ivy_TruthDecompose_rec( uCof1, vTree );
+ if ( RetValue1 == -1 )
+ break;
+ // both of them exist; create the node
+ Ivy_DecSetVar( &Node, 0, pSupp[i] << 1 );
+ Ivy_DecSetVar( &Node, 1, RetValue1 );
+ Ivy_DecSetVar( &Node, 2, RetValue0 );
+ Vec_IntPush( vTree, Ivy_DecToInt(Node) );
+ return ((Vec_IntSize(vTree)-1) << 1) | 0;
+ }
+ // check majority gate
+ if ( nSupp > 3 )
+ return -1;
+ if ( Ivy_TruthWordCountOnes(uTruth) != 16 )
+ return -1;
+ // this is a majority gate; determine polarity
+ Node.Type = IVY_DEC_MAJ;
+ Count[0] = Count[1] = Count[2] = 0;
+ for ( i = 0; i < 8; i++ )
+ {
+ Num = 0;
+ for ( k = 0; k < 3; k++ )
+ if ( i & (1 << k) )
+ Num |= (1 << pSupp[k]);
+ assert( Num < 32 );
+ if ( (uTruth & (1 << Num)) == 0 )
+ continue;
+ for ( k = 0; k < 3; k++ )
+ if ( i & (1 << k) )
+ Count[k]++;
+ }
+ assert( Count[0] == 1 || Count[0] == 3 );
+ assert( Count[1] == 1 || Count[1] == 3 );
+ assert( Count[2] == 1 || Count[2] == 3 );
+ Ivy_DecSetVar( &Node, 0, (pSupp[0] << 1)|(Count[0] == 1) );
+ Ivy_DecSetVar( &Node, 1, (pSupp[1] << 1)|(Count[1] == 1) );
+ Ivy_DecSetVar( &Node, 2, (pSupp[2] << 1)|(Count[2] == 1) );
+ Vec_IntPush( vTree, Ivy_DecToInt(Node) );
+ return ((Vec_IntSize(vTree)-1) << 1) | 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table of decomposition tree for verification.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ivy_TruthDsdCompute_rec( int iNode, Vec_Int_t * vTree )
+{
+ unsigned uTruthChild, uTruthTotal;
+ int Var, i;
+ // get the node
+ Ivy_Dec_t Node = Ivy_IntToDec( Vec_IntEntry(vTree, iNode) );
+ // compute the node function
+ if ( Node.Type == IVY_DEC_CONST1 )
+ return s_Masks[5][ !Node.fCompl ];
+ if ( Node.Type == IVY_DEC_PI )
+ return s_Masks[iNode][ !Node.fCompl ];
+ if ( Node.Type == IVY_DEC_BUF )
+ {
+ uTruthTotal = Ivy_TruthDsdCompute_rec( Node.Fan0 >> 1, vTree );
+ return Node.fCompl? ~uTruthTotal : uTruthTotal;
+ }
+ if ( Node.Type == IVY_DEC_AND )
+ {
+ uTruthTotal = s_Masks[5][1];
+ for ( i = 0; i < (int)Node.nFans; i++ )
+ {
+ Var = Ivy_DecGetVar( &Node, i );
+ uTruthChild = Ivy_TruthDsdCompute_rec( Var >> 1, vTree );
+ uTruthTotal = (Var & 1)? uTruthTotal & ~uTruthChild : uTruthTotal & uTruthChild;
+ }
+ return Node.fCompl? ~uTruthTotal : uTruthTotal;
+ }
+ if ( Node.Type == IVY_DEC_EXOR )
+ {
+ uTruthTotal = 0;
+ for ( i = 0; i < (int)Node.nFans; i++ )
+ {
+ Var = Ivy_DecGetVar( &Node, i );
+ uTruthTotal ^= Ivy_TruthDsdCompute_rec( Var >> 1, vTree );
+ assert( (Var & 1) == 0 );
+ }
+ return Node.fCompl? ~uTruthTotal : uTruthTotal;
+ }
+ assert( Node.fCompl == 0 );
+ if ( Node.Type == IVY_DEC_MUX || Node.Type == IVY_DEC_MAJ )
+ {
+ unsigned uTruthChildC, uTruthChild1, uTruthChild0;
+ int VarC, Var1, Var0;
+ VarC = Ivy_DecGetVar( &Node, 0 );
+ Var1 = Ivy_DecGetVar( &Node, 1 );
+ Var0 = Ivy_DecGetVar( &Node, 2 );
+ uTruthChildC = Ivy_TruthDsdCompute_rec( VarC >> 1, vTree );
+ uTruthChild1 = Ivy_TruthDsdCompute_rec( Var1 >> 1, vTree );
+ uTruthChild0 = Ivy_TruthDsdCompute_rec( Var0 >> 1, vTree );
+ assert( Node.Type == IVY_DEC_MAJ || (VarC & 1) == 0 );
+ uTruthChildC = (VarC & 1)? ~uTruthChildC : uTruthChildC;
+ uTruthChild1 = (Var1 & 1)? ~uTruthChild1 : uTruthChild1;
+ uTruthChild0 = (Var0 & 1)? ~uTruthChild0 : uTruthChild0;
+ if ( Node.Type == IVY_DEC_MUX )
+ return (uTruthChildC & uTruthChild1) | (~uTruthChildC & uTruthChild0);
+ else
+ return (uTruthChildC & uTruthChild1) | (uTruthChildC & uTruthChild0) | (uTruthChild1 & uTruthChild0);
+ }
+ assert( 0 );
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table of decomposition tree for verification.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ivy_TruthDsdCompute( Vec_Int_t * vTree )
+{
+ return Ivy_TruthDsdCompute_rec( Vec_IntSize(vTree)-1, vTree );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the decomposition tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TruthDsdPrint_rec( FILE * pFile, int iNode, Vec_Int_t * vTree )
+{
+ int Var, i;
+ // get the node
+ Ivy_Dec_t Node = Ivy_IntToDec( Vec_IntEntry(vTree, iNode) );
+ // compute the node function
+ if ( Node.Type == IVY_DEC_CONST1 )
+ fprintf( pFile, "Const1%s", (Node.fCompl? "\'" : "") );
+ else if ( Node.Type == IVY_DEC_PI )
+ fprintf( pFile, "%c%s", 'a' + iNode, (Node.fCompl? "\'" : "") );
+ else if ( Node.Type == IVY_DEC_BUF )
+ {
+ Ivy_TruthDsdPrint_rec( pFile, Node.Fan0 >> 1, vTree );
+ fprintf( pFile, "%s", (Node.fCompl? "\'" : "") );
+ }
+ else if ( Node.Type == IVY_DEC_AND )
+ {
+ fprintf( pFile, "AND(" );
+ for ( i = 0; i < (int)Node.nFans; i++ )
+ {
+ Var = Ivy_DecGetVar( &Node, i );
+ Ivy_TruthDsdPrint_rec( pFile, Var >> 1, vTree );
+ fprintf( pFile, "%s", (Var & 1)? "\'" : "" );
+ if ( i != (int)Node.nFans-1 )
+ fprintf( pFile, "," );
+ }
+ fprintf( pFile, ")%s", (Node.fCompl? "\'" : "") );
+ }
+ else if ( Node.Type == IVY_DEC_EXOR )
+ {
+ fprintf( pFile, "EXOR(" );
+ for ( i = 0; i < (int)Node.nFans; i++ )
+ {
+ Var = Ivy_DecGetVar( &Node, i );
+ Ivy_TruthDsdPrint_rec( pFile, Var >> 1, vTree );
+ if ( i != (int)Node.nFans-1 )
+ fprintf( pFile, "," );
+ assert( (Var & 1) == 0 );
+ }
+ fprintf( pFile, ")%s", (Node.fCompl? "\'" : "") );
+ }
+ else if ( Node.Type == IVY_DEC_MUX || Node.Type == IVY_DEC_MAJ )
+ {
+ int VarC, Var1, Var0;
+ assert( Node.fCompl == 0 );
+ VarC = Ivy_DecGetVar( &Node, 0 );
+ Var1 = Ivy_DecGetVar( &Node, 1 );
+ Var0 = Ivy_DecGetVar( &Node, 2 );
+ fprintf( pFile, "%s", (Node.Type == IVY_DEC_MUX)? "MUX(" : "MAJ(" );
+ Ivy_TruthDsdPrint_rec( pFile, VarC >> 1, vTree );
+ fprintf( pFile, "%s", (VarC & 1)? "\'" : "" );
+ fprintf( pFile, "," );
+ Ivy_TruthDsdPrint_rec( pFile, Var1 >> 1, vTree );
+ fprintf( pFile, "%s", (Var1 & 1)? "\'" : "" );
+ fprintf( pFile, "," );
+ Ivy_TruthDsdPrint_rec( pFile, Var0 >> 1, vTree );
+ fprintf( pFile, "%s", (Var0 & 1)? "\'" : "" );
+ fprintf( pFile, ")" );
+ }
+ else assert( 0 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints the decomposition tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree )
+{
+ fprintf( pFile, "F = " );
+ Ivy_TruthDsdPrint_rec( pFile, Vec_IntSize(vTree)-1, vTree );
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implement DSD in the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_ManDsdConstruct_rec( Ivy_Man_t * p, Vec_Int_t * vFront, int iNode, Vec_Int_t * vTree )
+{
+ Ivy_Obj_t * pResult, * pChild, * pNodes[16];
+ int Var, i;
+ // get the node
+ Ivy_Dec_t Node = Ivy_IntToDec( Vec_IntEntry(vTree, iNode) );
+ // compute the node function
+ if ( Node.Type == IVY_DEC_CONST1 )
+ return Ivy_NotCond( Ivy_ManConst1(p), Node.fCompl );
+ if ( Node.Type == IVY_DEC_PI )
+ {
+ pResult = Ivy_ManObj( p, Vec_IntEntry(vFront, iNode) );
+ return Ivy_NotCond( pResult, Node.fCompl );
+ }
+ if ( Node.Type == IVY_DEC_BUF )
+ {
+ pResult = Ivy_ManDsdConstruct_rec( p, vFront, Node.Fan0 >> 1, vTree );
+ return Ivy_NotCond( pResult, Node.fCompl );
+ }
+ if ( Node.Type == IVY_DEC_AND || Node.Type == IVY_DEC_EXOR )
+ {
+ for ( i = 0; i < (int)Node.nFans; i++ )
+ {
+ Var = Ivy_DecGetVar( &Node, i );
+ assert( Node.Type == IVY_DEC_AND || (Var & 1) == 0 );
+ pChild = Ivy_ManDsdConstruct_rec( p, vFront, Var >> 1, vTree );
+ pChild = Ivy_NotCond( pChild, (Var & 1) );
+ pNodes[i] = pChild;
+ }
+
+// Ivy_MultiEval( pNodes, Node.nFans, Node.Type == IVY_DEC_AND ? IVY_AND : IVY_EXOR );
+
+ pResult = Ivy_Multi( pNodes, Node.nFans, Node.Type == IVY_DEC_AND ? IVY_AND : IVY_EXOR );
+ return Ivy_NotCond( pResult, Node.fCompl );
+ }
+ assert( Node.fCompl == 0 );
+ if ( Node.Type == IVY_DEC_MUX || Node.Type == IVY_DEC_MAJ )
+ {
+ int VarC, Var1, Var0;
+ VarC = Ivy_DecGetVar( &Node, 0 );
+ Var1 = Ivy_DecGetVar( &Node, 1 );
+ Var0 = Ivy_DecGetVar( &Node, 2 );
+ pNodes[0] = Ivy_ManDsdConstruct_rec( p, vFront, VarC >> 1, vTree );
+ pNodes[1] = Ivy_ManDsdConstruct_rec( p, vFront, Var1 >> 1, vTree );
+ pNodes[2] = Ivy_ManDsdConstruct_rec( p, vFront, Var0 >> 1, vTree );
+ assert( Node.Type == IVY_DEC_MAJ || (VarC & 1) == 0 );
+ pNodes[0] = Ivy_NotCond( pNodes[0], (VarC & 1) );
+ pNodes[1] = Ivy_NotCond( pNodes[1], (Var1 & 1) );
+ pNodes[2] = Ivy_NotCond( pNodes[2], (Var0 & 1) );
+ if ( Node.Type == IVY_DEC_MUX )
+ return Ivy_Mux( pNodes[0], pNodes[1], pNodes[2] );
+ else
+ return Ivy_Maj( pNodes[0], pNodes[1], pNodes[2] );
+ }
+ assert( 0 );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implement DSD in the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_ManDsdConstruct( Ivy_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vTree )
+{
+ int Entry, i;
+ // implement latches on the frontier (TEMPORARY!!!)
+ Vec_IntForEachEntry( vFront, Entry, i )
+ Vec_IntWriteEntry( vFront, i, Ivy_LeafId(Entry) );
+ // recursively construct the tree
+ return Ivy_ManDsdConstruct_rec( p, vFront, Vec_IntSize(vTree)-1, vTree );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TruthDsdComputePrint( unsigned uTruth )
+{
+ static Vec_Int_t * vTree = NULL;
+ if ( vTree == NULL )
+ vTree = Vec_IntAlloc( 12 );
+ if ( Ivy_TruthDsd( uTruth, vTree ) )
+ Ivy_TruthDsdPrint( stdout, vTree );
+ else
+ printf( "Undecomposable\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TruthTestOne( unsigned uTruth )
+{
+ static int Counter = 0;
+ static Vec_Int_t * vTree = NULL;
+ // decompose
+ if ( vTree == NULL )
+ vTree = Vec_IntAlloc( 12 );
+
+ if ( !Ivy_TruthDsd( uTruth, vTree ) )
+ {
+// printf( "Undecomposable\n" );
+ }
+ else
+ {
+// nTruthDsd++;
+ printf( "%5d : ", Counter++ );
+ Extra_PrintBinary( stdout, &uTruth, 32 );
+ printf( " " );
+ Ivy_TruthDsdPrint( stdout, vTree );
+ if ( uTruth != Ivy_TruthDsdCompute(vTree) )
+ printf( "Verification failed.\n" );
+ }
+// Vec_IntFree( vTree );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TruthTest()
+{
+ FILE * pFile;
+ char Buffer[100];
+ unsigned uTruth;
+ int i;
+
+ pFile = fopen( "npn4.txt", "r" );
+ for ( i = 0; i < 222; i++ )
+// pFile = fopen( "npn5.txt", "r" );
+// for ( i = 0; i < 616126; i++ )
+ {
+ fscanf( pFile, "%s", Buffer );
+ Extra_ReadHexadecimal( &uTruth, Buffer+2, 4 );
+// Extra_ReadHexadecimal( &uTruth, Buffer+2, 5 );
+ uTruth |= (uTruth << 16);
+// uTruth = ~uTruth;
+ Ivy_TruthTestOne( uTruth );
+ }
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TruthTest3()
+{
+ FILE * pFile;
+ char Buffer[100];
+ unsigned uTruth;
+ int i;
+
+ pFile = fopen( "npn3.txt", "r" );
+ for ( i = 0; i < 14; i++ )
+ {
+ fscanf( pFile, "%s", Buffer );
+ Extra_ReadHexadecimal( &uTruth, Buffer+2, 3 );
+ uTruth = uTruth | (uTruth << 8) | (uTruth << 16) | (uTruth << 24);
+ Ivy_TruthTestOne( uTruth );
+ }
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TruthTest5()
+{
+ FILE * pFile;
+ char Buffer[100];
+ unsigned uTruth;
+ int i;
+
+// pFile = fopen( "npn4.txt", "r" );
+// for ( i = 0; i < 222; i++ )
+ pFile = fopen( "npn5.txt", "r" );
+ for ( i = 0; i < 616126; i++ )
+ {
+ fscanf( pFile, "%s", Buffer );
+// Extra_ReadHexadecimal( &uTruth, Buffer+2, 4 );
+ Extra_ReadHexadecimal( &uTruth, Buffer+2, 5 );
+// uTruth |= (uTruth << 16);
+// uTruth = ~uTruth;
+ Ivy_TruthTestOne( uTruth );
+ }
+ fclose( pFile );
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyMan.c b/src/temp/ivy/ivyMan.c
new file mode 100644
index 00000000..04c31f3d
--- /dev/null
+++ b/src/temp/ivy/ivyMan.c
@@ -0,0 +1,207 @@
+/**CFile****************************************************************
+
+ FileName [ivyMan.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [AIG manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivy_.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax )
+{
+ Ivy_Man_t * p;
+ Ivy_Obj_t * pObj;
+ int i, nTotalSize;
+ // start the manager
+ p = ALLOC( Ivy_Man_t, 1 );
+ memset( p, 0, sizeof(Ivy_Man_t) );
+ p->nTravIds = 1;
+ // AIG nodes
+ p->nObjsAlloc = 1 + nPis + nPos + nNodesMax;
+// p->nObjsAlloc += (p->nObjsAlloc & 1); // make it even
+ nTotalSize = p->nObjsAlloc + IVY_SANDBOX_SIZE + 1;
+ p->pObjs = ALLOC( Ivy_Obj_t, nTotalSize );
+ memset( p->pObjs, 0, sizeof(Ivy_Obj_t) * nTotalSize );
+ // temporary storage for deleted entries
+ p->vFree = Vec_IntAlloc( 100 );
+ // set the node IDs
+ for ( i = 0, pObj = p->pObjs; i < nTotalSize; i++, pObj++ )
+ pObj->Id = i - IVY_SANDBOX_SIZE - 1;
+ // remember the manager in the first entry
+ *((Ivy_Man_t **)p->pObjs) = p;
+ p->pObjs += IVY_SANDBOX_SIZE + 1;
+ // create the constant node
+ p->nCreated = 1;
+ p->ObjIdNext = 1;
+ Ivy_ManConst1(p)->fPhase = 1;
+ // create PIs
+ pObj = Ivy_ManGhost(p);
+ pObj->Type = IVY_PI;
+ p->vPis = Vec_IntAlloc( 100 );
+ for ( i = 0; i < nPis; i++ )
+ Ivy_ObjCreate( pObj );
+ // create POs
+ pObj->Type = IVY_PO;
+ p->vPos = Vec_IntAlloc( 100 );
+ for ( i = 0; i < nPos; i++ )
+ Ivy_ObjCreate( pObj );
+ // start the table
+ p->nTableSize = p->nObjsAlloc*5/2+13;
+ p->pTable = ALLOC( int, p->nTableSize );
+ memset( p->pTable, 0, sizeof(int) * p->nTableSize );
+ // allocate undo storage
+ p->nUndosAlloc = 100;
+ p->pUndos = ALLOC( Ivy_Obj_t, p->nUndosAlloc );
+ memset( p->pUndos, 0, sizeof(Ivy_Obj_t) * p->nUndosAlloc );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManStop( Ivy_Man_t * p )
+{
+ if ( p->fExtended )
+ {
+ Ivy_Obj_t * pObj;
+ int i;
+ Ivy_ManForEachObj( p, pObj, i )
+ if ( Ivy_ObjGetFanins(pObj) )
+ Vec_IntFree( Ivy_ObjGetFanins(pObj) );
+ }
+ if ( p->vFree ) Vec_IntFree( p->vFree );
+ if ( p->vTruths ) Vec_IntFree( p->vTruths );
+ if ( p->vPis ) Vec_IntFree( p->vPis );
+ if ( p->vPos ) Vec_IntFree( p->vPos );
+ FREE( p->pMemory );
+ free( p->pObjs - IVY_SANDBOX_SIZE - 1 );
+ free( p->pTable );
+ free( p->pUndos );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of dangling nodes removed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManGrow( Ivy_Man_t * p )
+{
+ int i;
+ assert( p->ObjIdNext == p->nObjsAlloc );
+ if ( p->ObjIdNext != p->nObjsAlloc )
+ return;
+// printf( "Ivy_ObjCreate(): Reallocing the node array.\n" );
+ p->nObjsAlloc = 2 * p->nObjsAlloc;
+ p->pObjs = REALLOC( Ivy_Obj_t, p->pObjs - IVY_SANDBOX_SIZE - 1, p->nObjsAlloc + IVY_SANDBOX_SIZE + 1 ) + IVY_SANDBOX_SIZE + 1;
+ memset( p->pObjs + p->ObjIdNext, 0, sizeof(Ivy_Obj_t) * p->nObjsAlloc / 2 );
+ for ( i = p->nObjsAlloc / 2; i < p->nObjsAlloc; i++ )
+ Ivy_ManObj( p, i )->Id = i;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of dangling nodes removed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ManCleanup( Ivy_Man_t * p )
+{
+ Ivy_Obj_t * pNode;
+ int i, nNodesOld;
+ nNodesOld = Ivy_ManNodeNum(p);
+ Ivy_ManForEachNode( p, pNode, i )
+ if ( Ivy_ObjRefs(pNode) == 0 )
+ Ivy_ObjDelete_rec( pNode, 1 );
+ return nNodesOld - Ivy_ManNodeNum(p);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManPrintStats( Ivy_Man_t * p )
+{
+ printf( "PI/PO = %d/%d ", Ivy_ManPiNum(p), Ivy_ManPoNum(p) );
+ if ( p->fExtended )
+ {
+ printf( "Am = %d. ", Ivy_ManAndMultiNum(p) );
+ printf( "Xm = %d. ", Ivy_ManExorMultiNum(p) );
+ printf( "Lut = %d. ", Ivy_ManLutNum(p) );
+ }
+ else
+ {
+ printf( "A = %d. ", Ivy_ManAndNum(p) );
+ printf( "X = %d. ", Ivy_ManExorNum(p) );
+ printf( "B = %d. ", Ivy_ManBufNum(p) );
+ }
+ printf( "MaxID = %d. ", p->ObjIdNext-1 );
+ printf( "All = %d. ", p->nObjsAlloc );
+ printf( "Cre = %d. ", p->nCreated );
+ printf( "Del = %d. ", p->nDeleted );
+ printf( "\n" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyMulti.c b/src/temp/ivy/ivyMulti.c
new file mode 100644
index 00000000..059d1500
--- /dev/null
+++ b/src/temp/ivy/ivyMulti.c
@@ -0,0 +1,427 @@
+/**CFile****************************************************************
+
+ FileName [ivyMulti.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Constructing multi-input AND/EXOR gates.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyMulti.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ivy_Eval_t_ Ivy_Eval_t;
+struct Ivy_Eval_t_
+{
+ unsigned Mask : 5; // the mask of covered nodes
+ unsigned Weight : 3; // the number of covered nodes
+ unsigned Cost : 4; // the number of overlapping nodes
+ unsigned Level : 12; // the level of this node
+ unsigned Fan0 : 4; // the first fanin
+ unsigned Fan1 : 4; // the second fanin
+};
+
+static Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
+static void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs );
+static int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode );
+static Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the well-balanced tree of gates.]
+
+ Description [Disregards levels and possible logic sharing.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type )
+{
+ Ivy_Obj_t * pObj1, * pObj2;
+ if ( nObjs == 1 )
+ return ppObjs[0];
+ pObj1 = Ivy_Multi_rec( ppObjs, nObjs/2, Type );
+ pObj2 = Ivy_Multi_rec( ppObjs + nObjs/2, nObjs - nObjs/2, Type );
+ return Ivy_Oper( pObj1, pObj2, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs a balanced tree while taking sharing into account.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgsInit, int nArgs, Ivy_Type_t Type )
+{
+ static char NumBits[32] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5};
+ static Ivy_Eval_t pEvals[15+15*14/2];
+ static Ivy_Obj_t * pArgs[16];
+ Ivy_Eval_t * pEva, * pEvaBest;
+ int nArgsNew, nEvals, i, k;
+ Ivy_Obj_t * pTemp;
+
+ // consider the case of one argument
+ assert( nArgs > 0 );
+ if ( nArgs == 1 )
+ return pArgsInit[0];
+ // consider the case of two arguments
+ if ( nArgs == 2 )
+ return Ivy_Oper( pArgsInit[0], pArgsInit[1], Type );
+
+//Ivy_MultiEval( pArgsInit, nArgs, Type ); printf( "\n" );
+
+ // set the initial ones
+ for ( i = 0; i < nArgs; i++ )
+ {
+ pArgs[i] = pArgsInit[i];
+ pEva = pEvals + i;
+ pEva->Mask = (1 << i);
+ pEva->Weight = 1;
+ pEva->Cost = 0;
+ pEva->Level = Ivy_Regular(pArgs[i])->Level;
+ pEva->Fan0 = 0;
+ pEva->Fan1 = 0;
+ }
+
+ // find the available nodes
+ pEvaBest = pEvals;
+ nArgsNew = nArgs;
+ for ( i = 1; i < nArgsNew; i++ )
+ for ( k = 0; k < i; k++ )
+ if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)) )
+ {
+ pEva = pEvals + nArgsNew;
+ pEva->Mask = pEvals[k].Mask | pEvals[i].Mask;
+ pEva->Weight = NumBits[pEva->Mask];
+ pEva->Cost = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];
+ pEva->Level = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);
+ pEva->Fan0 = k;
+ pEva->Fan1 = i;
+// assert( pEva->Level == (unsigned)Ivy_ObjLevel(pTemp) );
+ // compare
+ if ( pEvaBest->Weight < pEva->Weight ||
+ pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost ||
+ pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level )
+ pEvaBest = pEva;
+ // save the argument
+ pArgs[nArgsNew++] = pTemp;
+ if ( nArgsNew == 15 )
+ goto Outside;
+ }
+Outside:
+
+// printf( "Best = %d.\n", pEvaBest - pEvals );
+
+ // the case of no common nodes
+ if ( nArgsNew == nArgs )
+ {
+ Ivy_MultiSort( pArgs, nArgs );
+ return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
+ }
+ // the case of one common node
+ if ( nArgsNew == nArgs + 1 )
+ {
+ assert( pEvaBest - pEvals == nArgs );
+ k = 0;
+ for ( i = 0; i < nArgs; i++ )
+ if ( i != (int)pEvaBest->Fan0 && i != (int)pEvaBest->Fan1 )
+ pArgs[k++] = pArgs[i];
+ pArgs[k++] = pArgs[nArgs];
+ assert( k == nArgs - 1 );
+ nArgs = k;
+ Ivy_MultiSort( pArgs, nArgs );
+ return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
+ }
+ // the case when there is a node that covers everything
+ if ( (int)pEvaBest->Mask == ((1 << nArgs) - 1) )
+ return Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type );
+
+ // evaluate node pairs
+ nEvals = nArgsNew;
+ for ( i = 1; i < nArgsNew; i++ )
+ for ( k = 0; k < i; k++ )
+ {
+ pEva = pEvals + nEvals;
+ pEva->Mask = pEvals[k].Mask | pEvals[i].Mask;
+ pEva->Weight = NumBits[pEva->Mask];
+ pEva->Cost = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];
+ pEva->Level = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);
+ pEva->Fan0 = k;
+ pEva->Fan1 = i;
+ // compare
+ if ( pEvaBest->Weight < pEva->Weight ||
+ pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost ||
+ pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level )
+ pEvaBest = pEva;
+ // save the argument
+ nEvals++;
+ }
+ assert( pEvaBest - pEvals >= nArgsNew );
+
+// printf( "Used (%d, %d).\n", pEvaBest->Fan0, pEvaBest->Fan1 );
+
+ // get the best implementation
+ pTemp = Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type );
+
+ // collect those not covered by EvaBest
+ k = 0;
+ for ( i = 0; i < nArgs; i++ )
+ if ( (pEvaBest->Mask & (1 << i)) == 0 )
+ pArgs[k++] = pArgs[i];
+ pArgs[k++] = pTemp;
+ assert( k == nArgs - (int)pEvaBest->Weight + 1 );
+ nArgs = k;
+ Ivy_MultiSort( pArgs, nArgs );
+ return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements multi-input AND/EXOR operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
+{
+ Ivy_Obj_t * pNode0, * pNode1;
+ if ( iNum < nArgs )
+ return pArgs[iNum];
+ pNode0 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan0, pArgs, nArgs, Type );
+ pNode1 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan1, pArgs, nArgs, Type );
+ return Ivy_Oper( pNode0, pNode1, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Selection-sorts the nodes in the decreasing over of level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs )
+{
+ Ivy_Obj_t * pTemp;
+ int i, j, iBest;
+
+ for ( i = 0; i < nArgs-1; i++ )
+ {
+ iBest = i;
+ for ( j = i+1; j < nArgs; j++ )
+ if ( Ivy_Regular(pArgs[j])->Level > Ivy_Regular(pArgs[iBest])->Level )
+ iBest = j;
+ pTemp = pArgs[i];
+ pArgs[i] = pArgs[iBest];
+ pArgs[iBest] = pTemp;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Inserts a new node in the order by levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode )
+{
+ Ivy_Obj_t * pNode1, * pNode2;
+ int i;
+ // try to find the node in the array
+ for ( i = 0; i < nArgs; i++ )
+ if ( pArray[i] == pNode )
+ return nArgs;
+ // put the node last
+ pArray[nArgs++] = pNode;
+ // find the place to put the new node
+ for ( i = nArgs-1; i > 0; i-- )
+ {
+ pNode1 = pArray[i ];
+ pNode2 = pArray[i-1];
+ if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level )
+ break;
+ pArray[i ] = pNode2;
+ pArray[i-1] = pNode1;
+ }
+ return nArgs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Balances the array recursively.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
+{
+ Ivy_Obj_t * pNodeNew;
+ // consider the case of one argument
+ assert( nArgs > 0 );
+ if ( nArgs == 1 )
+ return pArgs[0];
+ // consider the case of two arguments
+ if ( nArgs == 2 )
+ return Ivy_Oper( pArgs[0], pArgs[1], Type );
+ // get the last two nodes
+ pNodeNew = Ivy_Oper( pArgs[nArgs-1], pArgs[nArgs-2], Type );
+ // add the new node
+ nArgs = Ivy_MultiPushUniqueOrderByLevel( pArgs, nArgs - 2, pNodeNew );
+ return Ivy_MultiBalance_rec( pArgs, nArgs, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements multi-input AND/EXOR operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
+{
+ Ivy_Obj_t * pTemp;
+ int i, k;
+ int nArgsOld = nArgs;
+ for ( i = 0; i < nArgs; i++ )
+ printf( "%d[%d] ", i, Ivy_Regular(pArgs[i])->Level );
+ for ( i = 1; i < nArgs; i++ )
+ for ( k = 0; k < i; k++ )
+ {
+ pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE));
+ if ( pTemp != NULL )
+ {
+ printf( "%d[%d]=(%d,%d) ", nArgs, Ivy_Regular(pTemp)->Level, k, i );
+ pArgs[nArgs++] = pTemp;
+ }
+ }
+ printf( " ((%d/%d)) ", nArgsOld, nArgs-nArgsOld );
+ return NULL;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Old code.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
+{
+ Ivy_Obj_t * pArgsRef[5], * pTemp;
+ int i, k, m, nArgsNew, Counter = 0;
+
+
+//Ivy_MultiEval( pArgs, nArgs, Type ); printf( "\n" );
+
+
+ assert( Type == IVY_AND || Type == IVY_EXOR );
+ assert( nArgs > 0 );
+ if ( nArgs == 1 )
+ return pArgs[0];
+
+ // find the nodes with more than one fanout
+ nArgsNew = 0;
+ for ( i = 0; i < nArgs; i++ )
+ if ( Ivy_ObjRefs( Ivy_Regular(pArgs[i]) ) > 0 )
+ pArgsRef[nArgsNew++] = pArgs[i];
+
+ // go through pairs
+ if ( nArgsNew >= 2 )
+ for ( i = 0; i < nArgsNew; i++ )
+ for ( k = i + 1; k < nArgsNew; k++ )
+ if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) )
+ Counter++;
+// printf( "%d", Counter );
+
+ // go through pairs
+ if ( nArgsNew >= 2 )
+ for ( i = 0; i < nArgsNew; i++ )
+ for ( k = i + 1; k < nArgsNew; k++ )
+ if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) )
+ {
+ nArgsNew = 0;
+ for ( m = 0; m < nArgs; m++ )
+ if ( pArgs[m] != pArgsRef[i] && pArgs[m] != pArgsRef[k] )
+ pArgs[nArgsNew++] = pArgs[m];
+ pArgs[nArgsNew++] = pTemp;
+ assert( nArgsNew == nArgs - 1 );
+ return Ivy_Multi1( pArgs, nArgsNew, Type );
+ }
+ return Ivy_Multi_rec( pArgs, nArgs, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Old code.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Multi2( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
+{
+ assert( Type == IVY_AND || Type == IVY_EXOR );
+ assert( nArgs > 0 );
+ return Ivy_Multi_rec( pArgs, nArgs, Type );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyObj.c b/src/temp/ivy/ivyObj.c
new file mode 100644
index 00000000..5d063525
--- /dev/null
+++ b/src/temp/ivy/ivyObj.c
@@ -0,0 +1,325 @@
+/**CFile****************************************************************
+
+ FileName [ivyObj.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Adding/removing objects.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyObj.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node assuming it does not exist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost )
+{
+ Ivy_Man_t * p = Ivy_ObjMan(pGhost);
+ Ivy_Obj_t * pObj;
+ assert( !Ivy_IsComplement(pGhost) );
+ assert( Ivy_ObjIsGhost(pGhost) );
+
+ assert( Ivy_TableLookup(pGhost) == NULL );
+
+ // realloc the node array
+ if ( p->ObjIdNext == p->nObjsAlloc )
+ {
+ Ivy_ManGrow( p );
+ pGhost = Ivy_ManGhost( p );
+ }
+ // get memory for the new object
+ if ( Vec_IntSize(p->vFree) > 0 )
+ pObj = p->pObjs + Vec_IntPop(p->vFree);
+ else
+ pObj = p->pObjs + p->ObjIdNext++;
+ assert( pObj->Id == pObj - p->pObjs );
+ assert( Ivy_ObjIsNone(pObj) );
+ // add basic info (fanins, compls, type, init)
+ Ivy_ObjOverwrite( pObj, pGhost );
+ // increment references of the fanins
+ Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) );
+ Ivy_ObjRefsInc( Ivy_ObjFanin1(pObj) );
+ // add the node to the structural hash table
+ Ivy_TableInsert( pObj );
+ // compute level
+ if ( Ivy_ObjIsNode(pObj) )
+ pObj->Level = Ivy_ObjLevelNew(pObj);
+ else if ( Ivy_ObjIsLatch(pObj) )
+ pObj->Level = 0;
+ else if ( Ivy_ObjIsOneFanin(pObj) )
+ pObj->Level = Ivy_ObjFanin0(pObj)->Level;
+ else if ( !Ivy_ObjIsPi(pObj) )
+ assert( 0 );
+ // mark the fanins in a special way if the node is EXOR
+ if ( Ivy_ObjIsExor(pObj) )
+ {
+ Ivy_ObjFanin0(pObj)->fExFan = 1;
+ Ivy_ObjFanin1(pObj)->fExFan = 1;
+ }
+ // add PIs/POs to the arrays
+ if ( Ivy_ObjIsPi(pObj) )
+ Vec_IntPush( p->vPis, pObj->Id );
+ else if ( Ivy_ObjIsPo(pObj) )
+ Vec_IntPush( p->vPos, pObj->Id );
+ // update node counters of the manager
+ p->nObjs[Ivy_ObjType(pObj)]++;
+ p->nCreated++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node assuming it does not exist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type )
+{
+ Ivy_Obj_t * pObj;
+ assert( Type == IVY_ANDM || Type == IVY_EXORM || Type == IVY_LUT );
+ // realloc the node array
+ if ( p->ObjIdNext == p->nObjsAlloc )
+ Ivy_ManGrow( p );
+ // create the new node
+ pObj = p->pObjs + p->ObjIdNext;
+ assert( pObj->Id == p->ObjIdNext );
+ p->ObjIdNext++;
+ pObj->Type = Type;
+ // update node counters of the manager
+ p->nObjs[Type]++;
+ p->nCreated++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Connect the object to the fanin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin )
+{
+ assert( !Ivy_IsComplement(pObj) );
+ assert( Ivy_ObjIsOneFanin(pObj) );
+ assert( Ivy_ObjFaninId0(pObj) == 0 );
+ // add the first fanin
+ pObj->fComp0 = Ivy_IsComplement(pFanin);
+ pObj->Fanin0 = Ivy_Regular(pFanin)->Id;
+ // increment references of the fanins
+ Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) );
+ // add the node to the structural hash table
+ Ivy_TableInsert( pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop )
+{
+ Ivy_Man_t * p;
+ assert( !Ivy_IsComplement(pObj) );
+ assert( Ivy_ObjRefs(pObj) == 0 );
+ // remove connections
+ Ivy_ObjRefsDec(Ivy_ObjFanin0(pObj));
+ Ivy_ObjRefsDec(Ivy_ObjFanin1(pObj));
+ // remove the node from the structural hash table
+ Ivy_TableDelete( pObj );
+ // update node counters of the manager
+ p = Ivy_ObjMan(pObj);
+ p->nObjs[pObj->Type]--;
+ p->nDeleted++;
+ // remove PIs/POs from the arrays
+ if ( Ivy_ObjIsPi(pObj) )
+ Vec_IntRemove( p->vPis, pObj->Id );
+ else if ( Ivy_ObjIsPo(pObj) )
+ Vec_IntRemove( p->vPos, pObj->Id );
+ // recorde the deleted node
+ if ( p->fRecording )
+ Ivy_ManUndoRecord( p, pObj );
+ // clean the node's memory
+ Ivy_ObjClean( pObj );
+ // remember the entry
+ if ( fFreeTop )
+ Vec_IntPush( p->vFree, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the MFFC of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop )
+{
+ Ivy_Obj_t * pFanin0, * pFanin1;
+ assert( !Ivy_IsComplement(pObj) );
+ assert( !Ivy_ObjIsPo(pObj) && !Ivy_ObjIsNone(pObj) );
+ if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsPi(pObj) )
+ return;
+ pFanin0 = Ivy_ObjFanin0(pObj);
+ pFanin1 = Ivy_ObjFanin1(pObj);
+ Ivy_ObjDelete( pObj, fFreeTop );
+ if ( !Ivy_ObjIsNone(pFanin0) && Ivy_ObjRefs(pFanin0) == 0 )
+ Ivy_ObjDelete_rec( pFanin0, 1 );
+ if ( !Ivy_ObjIsNone(pFanin1) && Ivy_ObjRefs(pFanin1) == 0 )
+ Ivy_ObjDelete_rec( pFanin1, 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces one object by another.]
+
+ Description [Both objects are currently in the manager. The new object
+ (pObjNew) should be used instead of the old object (pObjOld). If the
+ new object is complemented or used, the buffer is added.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ObjReplace( Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop )
+{
+ int nRefsOld;
+ // the object to be replaced cannot be complemented
+ assert( !Ivy_IsComplement(pObjOld) );
+ // the object to be replaced cannot be a terminal
+ assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsTerm(pObjOld) );
+ // the object to be used cannot be a PO or assert
+ assert( !Ivy_ObjIsPo(Ivy_Regular(pObjNew)) );
+ // the object cannot be the same
+ assert( pObjOld != Ivy_Regular(pObjNew) );
+ // if the new object is complemented or already used, add the buffer
+ if ( Ivy_IsComplement(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) )
+ pObjNew = Ivy_ObjCreate( Ivy_ObjCreateGhost(pObjNew, Ivy_ObjConst1(pObjOld), IVY_BUF, IVY_INIT_NONE) );
+ assert( !Ivy_IsComplement(pObjNew) );
+ // remember the reference counter
+ nRefsOld = pObjOld->nRefs;
+ pObjOld->nRefs = 0;
+ // delete the old object
+ if ( fDeleteOld )
+ Ivy_ObjDelete_rec( pObjOld, fFreeTop );
+ // transfer the old object
+ assert( Ivy_ObjRefs(pObjNew) == 0 );
+ Ivy_ObjOverwrite( pObjOld, pObjNew );
+ pObjOld->nRefs = nRefsOld;
+ // update the hash table
+ Ivy_TableUpdate( pObjNew, pObjOld->Id );
+ // create the object that was taken over by pObjOld
+ Ivy_ObjClean( pObjNew );
+ // remember the entry
+ Vec_IntPush( Ivy_ObjMan(pObjOld)->vFree, pObjNew->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the first real fanins (not a buffer/inverter).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin )
+{
+ if ( iFanin == 0 )
+ {
+ if ( Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) )
+ return Ivy_NotCond( Ivy_NodeRealFanin_rec(Ivy_ObjFanin0(pNode), 0), Ivy_ObjFaninC0(pNode) );
+ else
+ return Ivy_ObjChild0(pNode);
+ }
+ else
+ {
+ if ( Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) )
+ return Ivy_NotCond( Ivy_NodeRealFanin_rec(Ivy_ObjFanin1(pNode), 0), Ivy_ObjFaninC1(pNode) );
+ else
+ return Ivy_ObjChild1(pNode);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fixes buffer fanins.]
+
+ Description [This situation happens because NodeReplace is a lazy
+ procedure, which does not propagate the change to the fanouts but
+ instead records the change in the form of a buf/inv node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_NodeFixBufferFanins( Ivy_Obj_t * pNode )
+{
+ Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult;
+ assert( Ivy_ObjIsNode(pNode) );
+ if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) && !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) )
+ return;
+ // get the real fanins
+ pFanReal0 = Ivy_NodeRealFanin_rec( pNode, 0 );
+ pFanReal1 = Ivy_NodeRealFanin_rec( pNode, 1 );
+ // get the new node
+ pResult = Ivy_Oper( pFanReal0, pFanReal1, Ivy_ObjType(pNode) );
+ // perform the replacement
+ Ivy_ObjReplace( pNode, pResult, 1, 0 );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyOper.c b/src/temp/ivy/ivyOper.c
new file mode 100644
index 00000000..a10ba343
--- /dev/null
+++ b/src/temp/ivy/ivyOper.c
@@ -0,0 +1,254 @@
+/**CFile****************************************************************
+
+ FileName [ivyOper.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [AIG operations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyOper.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// procedure to detect an EXOR gate
+static inline int Ivy_ObjIsExorType( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Obj_t ** ppFan0, Ivy_Obj_t ** ppFan1 )
+{
+ if ( !Ivy_IsComplement(p0) || !Ivy_IsComplement(p1) )
+ return 0;
+ p0 = Ivy_Regular(p0);
+ p1 = Ivy_Regular(p1);
+ if ( !Ivy_ObjIsAnd(p0) || !Ivy_ObjIsAnd(p1) )
+ return 0;
+ if ( Ivy_ObjFanin0(p0) != Ivy_ObjFanin0(p1) || Ivy_ObjFanin1(p0) != Ivy_ObjFanin1(p1) )
+ return 0;
+ if ( Ivy_ObjFaninC0(p0) == Ivy_ObjFaninC0(p1) || Ivy_ObjFaninC1(p0) == Ivy_ObjFaninC1(p1) )
+ return 0;
+ *ppFan0 = Ivy_ObjChild0(p0);
+ *ppFan1 = Ivy_ObjChild1(p0);
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Perform one operation.]
+
+ Description [The argument nodes can be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type )
+{
+ if ( Type == IVY_AND )
+ return Ivy_And( p0, p1 );
+ if ( Type == IVY_EXOR )
+ return Ivy_Exor( p0, p1 );
+ assert( 0 );
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs canonicization step.]
+
+ Description [The argument nodes can be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
+{
+ Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0));
+ Ivy_Obj_t * pFan0, * pFan1;
+ // check trivial cases
+ if ( p0 == p1 )
+ return p0;
+ if ( p0 == Ivy_Not(p1) )
+ return Ivy_Not(pConst1);
+ if ( Ivy_Regular(p0) == pConst1 )
+ return p0 == pConst1 ? p1 : Ivy_Not(pConst1);
+ if ( Ivy_Regular(p1) == pConst1 )
+ return p1 == pConst1 ? p0 : Ivy_Not(pConst1);
+ // check if it can be an EXOR gate
+ if ( Ivy_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) )
+ return Ivy_CanonExor( pFan0, pFan1 );
+ return Ivy_CanonAnd( p0, p1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs canonicization step.]
+
+ Description [The argument nodes can be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Exor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
+{
+ Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0));
+ // check trivial cases
+ if ( p0 == p1 )
+ return Ivy_Not(pConst1);
+ if ( p0 == Ivy_Not(p1) )
+ return pConst1;
+ if ( Ivy_Regular(p0) == pConst1 )
+ return Ivy_NotCond( p1, p0 == pConst1 );
+ if ( Ivy_Regular(p1) == pConst1 )
+ return Ivy_NotCond( p0, p1 == pConst1 );
+ // check the table
+ return Ivy_CanonExor( p0, p1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs canonicization step.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Latch( Ivy_Obj_t * pObj, Ivy_Init_t Init )
+{
+ return Ivy_CanonLatch( pObj, Init );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements Boolean OR.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Or( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
+{
+ return Ivy_Not( Ivy_And( Ivy_Not(p0), Ivy_Not(p1) ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements ITE operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 )
+{
+ Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0));
+ Ivy_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp;
+ int Count0, Count1;
+ // consider trivial cases
+ if ( p0 == Ivy_Not(p1) )
+ return Ivy_Exor( pC, p0 );
+ // other cases can be added
+ // implement the first MUX (F = C * x1 + C' * x0)
+ pTempA1 = Ivy_TableLookup( Ivy_ObjCreateGhost(pC, p1, IVY_AND, IVY_INIT_NONE) );
+ pTempA2 = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pC), p0, IVY_AND, IVY_INIT_NONE) );
+ if ( pTempA1 && pTempA2 )
+ {
+ pTemp = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pTempA1), Ivy_Not(pTempA2), IVY_AND, IVY_INIT_NONE) );
+ if ( pTemp ) return Ivy_Not(pTemp);
+ }
+ Count0 = (pTempA1 != NULL) + (pTempA2 != NULL);
+ // implement the second MUX (F' = C * x1' + C' * x0')
+ pTempB1 = Ivy_TableLookup( Ivy_ObjCreateGhost(pC, Ivy_Not(p1), IVY_AND, IVY_INIT_NONE) );
+ pTempB2 = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pC), Ivy_Not(p0), IVY_AND, IVY_INIT_NONE) );
+ if ( pTempB1 && pTempB2 )
+ {
+ pTemp = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pTempB1), Ivy_Not(pTempB2), IVY_AND, IVY_INIT_NONE) );
+ if ( pTemp ) return pTemp;
+ }
+ Count1 = (pTempB1 != NULL) + (pTempB2 != NULL);
+ // compare and decide which one to implement
+ if ( Count0 >= Count1 )
+ {
+ pTempA1 = pTempA1? pTempA1 : Ivy_And(pC, p1);
+ pTempA2 = pTempA2? pTempA2 : Ivy_And(Ivy_Not(pC), p0);
+ return Ivy_Or( pTempA1, pTempA2 );
+ }
+ pTempB1 = pTempB1? pTempB1 : Ivy_And(pC, Ivy_Not(p1));
+ pTempB2 = pTempB2? pTempB2 : Ivy_And(Ivy_Not(pC), Ivy_Not(p0));
+ return Ivy_Not( Ivy_Or( pTempB1, pTempB2 ) );
+
+// return Ivy_Or( Ivy_And(pC, p1), Ivy_And(Ivy_Not(pC), p0) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements ITE operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC )
+{
+ return Ivy_Or( Ivy_Or(Ivy_And(pA, pB), Ivy_And(pA, pC)), Ivy_And(pB, pC) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_Miter( Vec_Ptr_t * vPairs )
+{
+ int i;
+ assert( vPairs->nSize > 0 );
+ assert( vPairs->nSize % 2 == 0 );
+ // go through the cubes of the node's SOP
+ for ( i = 0; i < vPairs->nSize; i += 2 )
+ vPairs->pArray[i/2] = Ivy_Not( Ivy_Exor( vPairs->pArray[i], vPairs->pArray[i+1] ) );
+ vPairs->nSize = vPairs->nSize/2;
+ return Ivy_Not( Ivy_Multi_rec( (Ivy_Obj_t **)vPairs->pArray, vPairs->nSize, IVY_AND ) );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyRewrite.c b/src/temp/ivy/ivyRewrite.c
new file mode 100644
index 00000000..031db9bc
--- /dev/null
+++ b/src/temp/ivy/ivyRewrite.c
@@ -0,0 +1,365 @@
+/**CFile****************************************************************
+
+ FileName [ivyRewrite.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [AIG rewriting.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyRewrite.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static unsigned Ivy_ManSeqFindTruth( Ivy_Obj_t * pNode, Vec_Int_t * vFront );
+static void Ivy_ManSeqCollectCone( Ivy_Obj_t * pNode, Vec_Int_t * vCone );
+static int Ivy_ManSeqGetCost( Ivy_Man_t * p, Vec_Int_t * vCone );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs Boolean rewriting of sequential AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost )
+{
+ Vec_Int_t * vNodes, * vFront, * vInside, * vTree;
+ Ivy_Obj_t * pNode, * pNodeNew, * pTemp;
+ int i, k, nCostOld, nCostInt, nCostInt2, nCostNew, RetValue, Entry, nRefsSaved, nInputs;
+ int clk, clkCut = 0, clkTru = 0, clkDsd = 0, clkUpd = 0, clkStart = clock();
+ unsigned uTruth;
+
+ nInputs = 4;
+ vTree = Vec_IntAlloc( 8 );
+ vFront = Vec_IntAlloc( 8 );
+ vInside = Vec_IntAlloc( 50 );
+ vNodes = Ivy_ManDfs( p );
+ Ivy_ManForEachNodeVec( p, vNodes, pNode, i )
+ {
+ if ( Ivy_ObjIsBuf(pNode) )
+ continue;
+ // fix the fanin buffer problem
+ Ivy_NodeFixBufferFanins( pNode );
+ if ( Ivy_ObjIsBuf(pNode) )
+ continue;
+
+ // find one sequential cut rooted at this node
+clk = clock();
+ Ivy_ManSeqFindCut( pNode, vFront, vInside, nInputs );
+clkCut += clock() - clk;
+ // compute the truth table of the cut
+clk = clock();
+ uTruth = Ivy_ManSeqFindTruth( pNode, vFront );
+clkTru += clock() - clk;
+ // decompose the truth table
+clk = clock();
+ RetValue = Ivy_TruthDsd( uTruth, vTree );
+clkDsd += clock() - clk;
+ if ( !RetValue )
+ continue; // DSD does not exist
+// Ivy_TruthDsdPrint( stdout, vTree );
+
+clk = clock();
+ // remember the cost of the current network
+ nCostOld = Ivy_ManGetCost(p);
+ // increment references of the cut variables
+ Vec_IntForEachEntry( vFront, Entry, k )
+ {
+ pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry));
+ Ivy_ObjRefsInc( pTemp );
+ }
+ // dereference and record undo
+ nRefsSaved = pNode->nRefs; pNode->nRefs = 0;
+ Ivy_ManUndoStart( p );
+ Ivy_ObjDelete_rec( pNode, 0 );
+ Ivy_ManUndoStop( p );
+ pNode->nRefs = nRefsSaved;
+
+ // get the intermediate cost
+ nCostInt = Ivy_ManGetCost(p);
+
+// printf( "Removed by dereferencing = %d.\n", nCostOld - nCostInt );
+
+ // construct the new logic cone
+ pNodeNew = Ivy_ManDsdConstruct( p, vFront, vTree );
+ // remember the cost
+ nCostNew = Ivy_ManGetCost(p);
+
+// printf( "Added by dereferencing = %d.\n", nCostInt - nCostNew );
+// nCostNew = nCostNew;
+
+/*
+ if ( Ivy_Regular(pNodeNew)->nRefs == 0 )
+ Ivy_ObjDelete_rec( Ivy_Regular(pNodeNew), 1 );
+ // get the intermediate cost
+ nCostInt2 = Ivy_ManGetCost(p);
+ assert( nCostInt == nCostInt2 );
+
+ Ivy_ManUndoPerform( p, pNode );
+ pNode->nRefs = nRefsSaved;
+
+ Vec_IntForEachEntry( vFront, Entry, k )
+ {
+// pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry));
+ pTemp = Ivy_ManObj(p, Entry);
+ Ivy_ObjRefsDec( pTemp );
+ }
+clkUpd += clock() - clk;
+ continue;
+*/
+
+ // detect the case when they are exactly the same
+// if ( pNodeNew == pNode )
+// continue;
+
+ // compare the costs
+ if ( nCostOld > nCostNew || nCostOld == nCostNew && fUseZeroCost )
+ { // accept the change
+// printf( "NODES GAINED = %d\n", nCostOld - nCostNew );
+
+ Ivy_ObjReplace( pNode, pNodeNew, 0, 1 );
+ pNode->nRefs = nRefsSaved;
+ }
+ else
+ { // reject change
+// printf( "Rejected\n" );
+
+ if ( Ivy_Regular(pNodeNew)->nRefs == 0 )
+ Ivy_ObjDelete_rec( Ivy_Regular(pNodeNew), 1 );
+
+ // get the intermediate cost
+ nCostInt2 = Ivy_ManGetCost(p);
+ assert( nCostInt == nCostInt2 );
+
+ // reconstruct the old node
+ Ivy_ManUndoPerform( p, pNode );
+ pNode->nRefs = nRefsSaved;
+ }
+ // decrement references of the cut variables
+ Vec_IntForEachEntry( vFront, Entry, k )
+ {
+// pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry));
+ pTemp = Ivy_ManObj(p, Entry);
+ if ( Ivy_ObjIsNone(pTemp) )
+ continue;
+ Ivy_ObjRefsDec( pTemp );
+ if ( Ivy_ObjRefs(pTemp) == 0 )
+ Ivy_ObjDelete_rec( pTemp, 1 );
+ }
+
+clkUpd += clock() - clk;
+ }
+
+PRT( "Cut ", clkCut );
+PRT( "Truth ", clkTru );
+PRT( "DSD ", clkDsd );
+PRT( "Update ", clkUpd );
+PRT( "TOTAL ", clock() - clkStart );
+
+ Vec_IntFree( vTree );
+ Vec_IntFree( vFront );
+ Vec_IntFree( vInside );
+ Vec_IntFree( vNodes );
+
+ if ( !Ivy_ManCheck(p) )
+ {
+ printf( "Ivy_ManSeqRewrite(): The check has failed.\n" );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the truth table of the sequential cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ivy_ManSeqFindTruth_rec( Ivy_Man_t * p, unsigned Node, Vec_Int_t * vFront )
+{
+ static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
+ unsigned uTruth0, uTruth1;
+ Ivy_Obj_t * pNode;
+ int nLatches, Number;
+ // consider the case of a constant
+ if ( Node == 0 )
+ return ~((unsigned)0);
+ // try to find this node in the frontier
+ Number = Vec_IntFind( vFront, Node );
+ if ( Number >= 0 )
+ return uMasks[Number];
+ // get the node
+ pNode = Ivy_ManObj( p, Ivy_LeafId(Node) );
+ assert( !Ivy_ObjIsPi(pNode) && !Ivy_ObjIsConst1(pNode) );
+ // get the number of latches
+ nLatches = Ivy_LeafLat(Node) + Ivy_ObjIsLatch(pNode);
+ // expand the first fanin
+ uTruth0 = Ivy_ManSeqFindTruth_rec( p, Ivy_LeafCreate(Ivy_ObjFaninId0(pNode), nLatches), vFront );
+ if ( Ivy_ObjFaninC0(pNode) )
+ uTruth0 = ~uTruth0;
+ // quit if this is the one fanin node
+ if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) )
+ return uTruth0;
+ assert( Ivy_ObjIsNode(pNode) );
+ // expand the second fanin
+ uTruth1 = Ivy_ManSeqFindTruth_rec( p, Ivy_LeafCreate(Ivy_ObjFaninId1(pNode), nLatches), vFront );
+ if ( Ivy_ObjFaninC1(pNode) )
+ uTruth1 = ~uTruth1;
+ // return the truth table
+ return Ivy_ObjIsAnd(pNode)? uTruth0 & uTruth1 : uTruth0 ^ uTruth1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the truth table of the sequential cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ivy_ManSeqFindTruth( Ivy_Obj_t * pNode, Vec_Int_t * vFront )
+{
+ assert( Ivy_ObjIsNode(pNode) );
+ return Ivy_ManSeqFindTruth_rec( Ivy_ObjMan(pNode), Ivy_LeafCreate(pNode->Id, 0), vFront );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Recursively dereferences the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManSeqDeref_rec( Ivy_Obj_t * pNode, Vec_Int_t * vCone )
+{
+ Ivy_Obj_t * pFan;
+ assert( !Ivy_IsComplement(pNode) );
+ assert( !Ivy_ObjIsNone(pNode) );
+ if ( Ivy_ObjIsPi(pNode) )
+ return;
+ // deref the first fanin
+ pFan = Ivy_ObjFanin0(pNode);
+ Ivy_ObjRefsDec( pFan );
+ if ( Ivy_ObjRefs( pFan ) == 0 )
+ Ivy_ManSeqDeref_rec( pFan, vCone );
+ // deref the second fanin
+ pFan = Ivy_ObjFanin1(pNode);
+ Ivy_ObjRefsDec( pFan );
+ if ( Ivy_ObjRefs( pFan ) == 0 )
+ Ivy_ManSeqDeref_rec( pFan, vCone );
+ // save the node
+ Vec_IntPush( vCone, pNode->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively references the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManSeqRef_rec( Ivy_Obj_t * pNode )
+{
+ Ivy_Obj_t * pFan;
+ assert( !Ivy_IsComplement(pNode) );
+ assert( !Ivy_ObjIsNone(pNode) );
+ if ( Ivy_ObjIsPi(pNode) )
+ return;
+ // ref the first fanin
+ pFan = Ivy_ObjFanin0(pNode);
+ if ( Ivy_ObjRefs( pFan ) == 0 )
+ Ivy_ManSeqRef_rec( pFan );
+ Ivy_ObjRefsInc( pFan );
+ // ref the second fanin
+ pFan = Ivy_ObjFanin1(pNode);
+ if ( Ivy_ObjRefs( pFan ) == 0 )
+ Ivy_ManSeqRef_rec( pFan );
+ Ivy_ObjRefsInc( pFan );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect MFFC of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManSeqCollectCone( Ivy_Obj_t * pNode, Vec_Int_t * vCone )
+{
+ Vec_IntClear( vCone );
+ Ivy_ManSeqDeref_rec( pNode, vCone );
+ Ivy_ManSeqRef_rec( pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cost of the logic cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ManSeqGetCost( Ivy_Man_t * p, Vec_Int_t * vCone )
+{
+ Ivy_Obj_t * pObj;
+ int i, Cost = 0;
+ Ivy_ManForEachNodeVec( p, vCone, pObj, i )
+ {
+ if ( Ivy_ObjIsAnd(pObj) )
+ Cost += 1;
+ else if ( Ivy_ObjIsExor(pObj) )
+ Cost += 2;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivySeq.c b/src/temp/ivy/ivySeq.c
new file mode 100644
index 00000000..d8fbdd9b
--- /dev/null
+++ b/src/temp/ivy/ivySeq.c
@@ -0,0 +1,101 @@
+/**CFile****************************************************************
+
+ FileName [ivySeq.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivySeq.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Converts a combinational AIG manager into a sequential one.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches )
+{
+ Vec_Int_t * vNodes;
+ Ivy_Obj_t * pObj, * pObjNew, * pFan0, * pFan1;
+ int i, fChanges;
+ assert( nLatches < Ivy_ManPiNum(p) && nLatches < Ivy_ManPoNum(p) );
+ // change POs into buffers
+ assert( Ivy_ManPoNum(p) == Vec_IntSize(p->vPos) );
+ for ( i = Ivy_ManPoNum(p) - nLatches; i < Vec_IntSize(p->vPos); i++ )
+ {
+ pObj = Ivy_ManPo(p, i);
+ pObj->Type = IVY_BUF;
+ }
+ // change PIs into latches and connect them to the corresponding POs
+ assert( Ivy_ManPiNum(p) == Vec_IntSize(p->vPis) );
+ for ( i = Ivy_ManPiNum(p) - nLatches; i < Vec_IntSize(p->vPis); i++ )
+ {
+ pObj = Ivy_ManPi(p, i);
+ pObj->Type = IVY_LATCH;
+ Ivy_ObjConnect( pObj, Ivy_ManPo(p, Ivy_ManPoNum(p) - Ivy_ManPiNum(p)) );
+ }
+ // shrink the array
+ Vec_IntShrink( p->vPis, Ivy_ManPiNum(p) - nLatches );
+ Vec_IntShrink( p->vPos, Ivy_ManPoNum(p) - nLatches );
+ // update the counters of different objects
+ p->nObjs[IVY_PI] -= nLatches;
+ p->nObjs[IVY_PO] -= nLatches;
+ p->nObjs[IVY_BUF] += nLatches;
+ p->nObjs[IVY_LATCH] += nLatches;
+ // perform structural hashing while there are changes
+ fChanges = 1;
+ while ( fChanges )
+ {
+ fChanges = 0;
+ vNodes = Ivy_ManDfs( p );
+ Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
+ {
+ if ( Ivy_ObjIsBuf(pObj) )
+ continue;
+ pFan0 = Ivy_NodeRealFanin_rec( pObj, 0 );
+ pFan1 = Ivy_NodeRealFanin_rec( pObj, 1 );
+ if ( Ivy_ObjIsAnd(pObj) )
+ pObjNew = Ivy_And(pFan0, pFan1);
+ else if ( Ivy_ObjIsExor(pObj) )
+ pObjNew = Ivy_Exor(pFan0, pFan1);
+ else assert( 0 );
+ if ( pObjNew == pObj )
+ continue;
+ Ivy_ObjReplace( pObj, pObjNew, 1, 1 );
+ fChanges = 1;
+ }
+ Vec_IntFree( vNodes );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyTable.c b/src/temp/ivy/ivyTable.c
new file mode 100644
index 00000000..815caa29
--- /dev/null
+++ b/src/temp/ivy/ivyTable.c
@@ -0,0 +1,237 @@
+/**CFile****************************************************************
+
+ FileName [ivyTable.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Structural hashing table.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// hashing the node
+static unsigned Ivy_Hash( Ivy_Obj_t * pObj, int TableSize )
+{
+ unsigned Key = Ivy_ObjIsExor(pObj) * 1699;
+ Key ^= Ivy_ObjFaninId0(pObj) * 7937;
+ Key ^= Ivy_ObjFaninId1(pObj) * 2971;
+ Key ^= Ivy_ObjFaninC0(pObj) * 911;
+ Key ^= Ivy_ObjFaninC1(pObj) * 353;
+ Key ^= Ivy_ObjInit(pObj) * 911;
+ return Key % TableSize;
+}
+
+// returns the place where this node is stored (or should be stored)
+static int * Ivy_TableFind( Ivy_Obj_t * pObj )
+{
+ Ivy_Man_t * p;
+ int i;
+ assert( Ivy_ObjIsHash(pObj) );
+ p = Ivy_ObjMan(pObj);
+ for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
+ if ( p->pTable[i] == pObj->Id )
+ break;
+ return p->pTable + i;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Checks if node with the given attributes is in the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_TableLookup( Ivy_Obj_t * pObj )
+{
+ Ivy_Man_t * p;
+ Ivy_Obj_t * pEntry;
+ int i;
+ assert( !Ivy_IsComplement(pObj) );
+ if ( !Ivy_ObjIsHash(pObj) )
+ return NULL;
+ assert( Ivy_ObjIsLatch(pObj) || Ivy_ObjFaninId0(pObj) > 0 );
+ assert( Ivy_ObjFaninId0(pObj) == 0 || Ivy_ObjFaninId0(pObj) > Ivy_ObjFaninId1(pObj) );
+ p = Ivy_ObjMan(pObj);
+ for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
+ {
+ pEntry = Ivy_ObjObj( pObj, p->pTable[i] );
+ if ( Ivy_ObjFaninId0(pEntry) == Ivy_ObjFaninId0(pObj) &&
+ Ivy_ObjFaninId1(pEntry) == Ivy_ObjFaninId1(pObj) &&
+ Ivy_ObjFaninC0(pEntry) == Ivy_ObjFaninC0(pObj) &&
+ Ivy_ObjFaninC1(pEntry) == Ivy_ObjFaninC1(pObj) &&
+ Ivy_ObjInit(pEntry) == Ivy_ObjInit(pObj) &&
+ Ivy_ObjType(pEntry) == Ivy_ObjType(pObj) )
+ return Ivy_ObjObj( pObj, p->pTable[i] );
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the node to the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TableInsert( Ivy_Obj_t * pObj )
+{
+ int * pPlace;
+ assert( !Ivy_IsComplement(pObj) );
+ if ( !Ivy_ObjIsHash(pObj) )
+ return;
+ pPlace = Ivy_TableFind( pObj );
+ assert( *pPlace == 0 );
+ *pPlace = pObj->Id;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the node from the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TableDelete( Ivy_Obj_t * pObj )
+{
+ Ivy_Man_t * p;
+ Ivy_Obj_t * pEntry;
+ int i, * pPlace;
+ assert( !Ivy_IsComplement(pObj) );
+ if ( !Ivy_ObjIsHash(pObj) )
+ return;
+ pPlace = Ivy_TableFind( pObj );
+ assert( *pPlace == pObj->Id ); // node should be in the table
+ *pPlace = 0;
+ // rehash the adjacent entries
+ p = Ivy_ObjMan(pObj);
+ i = pPlace - p->pTable;
+ for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize )
+ {
+ pEntry = Ivy_ObjObj( pObj, p->pTable[i] );
+ p->pTable[i] = 0;
+ Ivy_TableInsert( pEntry );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the table to point to the new node.]
+
+ Description [If the old node (pObj) is in the table, updates the table
+ to point to an object with different ID (ObjIdNew). The table should
+ not contain an object with ObjIdNew (this is currently not checked).]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TableUpdate( Ivy_Obj_t * pObj, int ObjIdNew )
+{
+ int * pPlace;
+ assert( !Ivy_IsComplement(pObj) );
+ if ( !Ivy_ObjIsHash(pObj) )
+ return;
+ pPlace = Ivy_TableFind( pObj );
+ assert( *pPlace == pObj->Id ); // node should be in the table
+ *pPlace = ObjIdNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count the number of nodes in the table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_TableCountEntries( Ivy_Man_t * p )
+{
+ int i, Counter = 0;
+ for ( i = 0; i < p->nTableSize; i++ )
+ Counter += (p->pTable[i] != 0);
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the table.]
+
+ Description [Typically this procedure should not be called.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_TableResize( Ivy_Man_t * p )
+{
+ int * pTableOld, * pPlace;
+ int nTableSizeOld, Counter, e, clk;
+ assert( 0 );
+clk = clock();
+ // save the old table
+ pTableOld = p->pTable;
+ nTableSizeOld = p->nTableSize;
+ // get the new table
+ p->nTableSize = p->nObjsAlloc*5/2+13;
+ p->pTable = ALLOC( int, p->nTableSize );
+ memset( p->pTable, 0, sizeof(int) * p->nTableSize );
+ // rehash the entries from the old table
+ Counter = 0;
+ for ( e = 0; e < nTableSizeOld; e++ )
+ {
+ if ( pTableOld[e] == 0 )
+ continue;
+ Counter++;
+ // get the place where this entry goes in the table table
+ pPlace = Ivy_TableFind( Ivy_ManObj(p, pTableOld[e]) );
+ assert( *pPlace == 0 ); // should not be in the table
+ *pPlace = pTableOld[e];
+ }
+ assert( Counter == Ivy_ManHashObjNum(p) );
+// printf( "Increasing the structural table size from %6d to %6d. ", p->nTableSize, nTableSizeNew );
+// PRT( "Time", clock() - clk );
+ // replace the table and the parameters
+ free( p->pTable );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyUndo.c b/src/temp/ivy/ivyUndo.c
new file mode 100644
index 00000000..6612bf42
--- /dev/null
+++ b/src/temp/ivy/ivyUndo.c
@@ -0,0 +1,165 @@
+/**CFile****************************************************************
+
+ FileName [ivyUndo.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Recording the results of recent deletion of logic cone.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyUndo.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManUndoStart( Ivy_Man_t * p )
+{
+ p->fRecording = 1;
+ p->nUndos = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManUndoStop( Ivy_Man_t * p )
+{
+ p->fRecording = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManUndoRecord( Ivy_Man_t * p, Ivy_Obj_t * pObj )
+{
+ Ivy_Obj_t * pObjUndo;
+ if ( p->nUndos >= p->nUndosAlloc )
+ {
+ printf( "Ivy_ManUndoRecord(): Not enough memory for undo.\n" );
+ return;
+ }
+ pObjUndo = p->pUndos + p->nUndos++;
+ // required data for Ivy_ObjCreateGhost()
+ pObjUndo->Type = pObj->Type;
+ pObjUndo->Init = pObj->Init;
+ pObjUndo->Fanin0 = pObj->Fanin0;
+ pObjUndo->Fanin1 = pObj->Fanin1;
+ pObjUndo->fComp0 = pObj->fComp0;
+ pObjUndo->fComp1 = pObj->fComp1;
+ // additional data
+ pObjUndo->Id = pObj->Id;
+ pObjUndo->nRefs = pObj->nRefs;
+ pObjUndo->Level = pObj->Level;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Vec_IntPutLast( Vec_Int_t * vFree, int Last )
+{
+ int Place, i;
+ // find the entry
+ Place = Vec_IntFind( vFree, Last );
+ if ( Place == -1 )
+ return 0;
+ // shift entries by one
+ assert( vFree->pArray[Place] == Last );
+ for ( i = Place; i < Vec_IntSize(vFree) - 1; i++ )
+ vFree->pArray[i] = vFree->pArray[i+1];
+ // put the entry in the end
+ vFree->pArray[i] = Last;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManUndoPerform( Ivy_Man_t * p, Ivy_Obj_t * pRoot )
+{
+ Ivy_Obj_t * pObjUndo, * pObjNew;
+ int i;
+ assert( p->nUndos > 0 );
+ assert( p->fRecording == 0 );
+ for ( i = p->nUndos - 1; i >= 0; i-- )
+ {
+ // get the undo object
+ pObjUndo = p->pUndos + i;
+ // if this is the last object
+ if ( i == 0 )
+ Vec_IntPush( p->vFree, pRoot->Id );
+ else
+ Vec_IntPutLast( p->vFree, pObjUndo->Id );
+ // create the new object
+ pObjNew = Ivy_ObjCreate( Ivy_ObjCreateGhost2( p, pObjUndo) );
+ pObjNew->nRefs = pObjUndo->nRefs;
+ pObjNew->Level = pObjUndo->Level;
+ // make sure the object is created in the same place as before
+ assert( pObjNew->Id == pObjUndo->Id );
+ }
+ p->nUndos = 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivyUtil.c b/src/temp/ivy/ivyUtil.c
new file mode 100644
index 00000000..590affd7
--- /dev/null
+++ b/src/temp/ivy/ivyUtil.c
@@ -0,0 +1,369 @@
+/**CFile****************************************************************
+
+ FileName [ivyUtil.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis [Various procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivyUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Increments the current traversal ID of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManIncrementTravId( Ivy_Man_t * p )
+{
+ if ( p->nTravIds >= (1<<30)-1 - 1000 )
+ Ivy_ManCleanTravId( p );
+ p->nTravIds++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the DFS ordering of the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManCleanTravId( Ivy_Man_t * p )
+{
+ Ivy_Obj_t * pObj;
+ int i;
+ p->nTravIds = 1;
+ Ivy_ManForEachObj( p, pObj, i )
+ pObj->TravId = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ObjIsMuxType( Ivy_Obj_t * pNode )
+{
+ Ivy_Obj_t * pNode0, * pNode1;
+ // check that the node is regular
+ assert( !Ivy_IsComplement(pNode) );
+ // if the node is not AND, this is not MUX
+ if ( !Ivy_ObjIsAnd(pNode) )
+ return 0;
+ // if the children are not complemented, this is not MUX
+ if ( !Ivy_ObjFaninC0(pNode) || !Ivy_ObjFaninC1(pNode) )
+ return 0;
+ // get children
+ pNode0 = Ivy_ObjFanin0(pNode);
+ pNode1 = Ivy_ObjFanin1(pNode);
+ // if the children are not ANDs, this is not MUX
+ if ( !Ivy_ObjIsAnd(pNode0) || !Ivy_ObjIsAnd(pNode1) )
+ return 0;
+ // otherwise the node is MUX iff it has a pair of equal grandchildren
+ return (Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC0(pNode1))) ||
+ (Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC1(pNode1))) ||
+ (Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC0(pNode1))) ||
+ (Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC1(pNode1)));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recognizes what nodes are control and data inputs of a MUX.]
+
+ Description [If the node is a MUX, returns the control variable C.
+ Assigns nodes T and E to be the then and else variables of the MUX.
+ Node C is never complemented. Nodes T and E can be complemented.
+ This function also recognizes EXOR/NEXOR gates as MUXes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pNode, Ivy_Obj_t ** ppNodeT, Ivy_Obj_t ** ppNodeE )
+{
+ Ivy_Obj_t * pNode0, * pNode1;
+ assert( !Ivy_IsComplement(pNode) );
+ assert( Ivy_ObjIsMuxType(pNode) );
+ // get children
+ pNode0 = Ivy_ObjFanin0(pNode);
+ pNode1 = Ivy_ObjFanin1(pNode);
+ // find the control variable
+// if ( pNode1->p1 == Fraig_Not(pNode2->p1) )
+ if ( Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC0(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p1) )
+ if ( Ivy_ObjFaninC0(pNode0) )
+ { // pNode2->p1 is positive phase of C
+ *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2);
+ *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2);
+ return Ivy_ObjChild0(pNode1);//pNode2->p1;
+ }
+ else
+ { // pNode1->p1 is positive phase of C
+ *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2);
+ *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2);
+ return Ivy_ObjChild0(pNode0);//pNode1->p1;
+ }
+ }
+// else if ( pNode1->p1 == Fraig_Not(pNode2->p2) )
+ else if ( Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC1(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p1) )
+ if ( Ivy_ObjFaninC0(pNode0) )
+ { // pNode2->p2 is positive phase of C
+ *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1);
+ *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2);
+ return Ivy_ObjChild1(pNode1);//pNode2->p2;
+ }
+ else
+ { // pNode1->p1 is positive phase of C
+ *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2);
+ *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1);
+ return Ivy_ObjChild0(pNode0);//pNode1->p1;
+ }
+ }
+// else if ( pNode1->p2 == Fraig_Not(pNode2->p1) )
+ else if ( Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC0(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p2) )
+ if ( Ivy_ObjFaninC1(pNode0) )
+ { // pNode2->p1 is positive phase of C
+ *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2);
+ *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1);
+ return Ivy_ObjChild0(pNode1);//pNode2->p1;
+ }
+ else
+ { // pNode1->p2 is positive phase of C
+ *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1);
+ *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2);
+ return Ivy_ObjChild1(pNode0);//pNode1->p2;
+ }
+ }
+// else if ( pNode1->p2 == Fraig_Not(pNode2->p2) )
+ else if ( Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC1(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p2) )
+ if ( Ivy_ObjFaninC1(pNode0) )
+ { // pNode2->p2 is positive phase of C
+ *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1);
+ *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1);
+ return Ivy_ObjChild1(pNode1);//pNode2->p2;
+ }
+ else
+ { // pNode1->p2 is positive phase of C
+ *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1);
+ *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1);
+ return Ivy_ObjChild1(pNode0);//pNode1->p2;
+ }
+ }
+ assert( 0 ); // this is not MUX
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table of the cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManCollectCut_rec( Ivy_Obj_t * pNode, Vec_Int_t * vNodes )
+{
+ if ( pNode->fMarkA )
+ return;
+ pNode->fMarkA = 1;
+ assert( Ivy_ObjIsAnd(pNode) || Ivy_ObjIsExor(pNode) );
+ Ivy_ManCollectCut_rec( Ivy_ObjFanin0(pNode), vNodes );
+ Ivy_ManCollectCut_rec( Ivy_ObjFanin1(pNode), vNodes );
+ Vec_IntPush( vNodes, pNode->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table of the cut.]
+
+ Description [Does not modify the array of leaves. Uses array vTruth to store
+ temporary truth tables. The returned pointer should be used immediately.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManCollectCut( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
+{
+ int i, Leaf;
+ // collect and mark the leaves
+ Vec_IntClear( vNodes );
+ Vec_IntForEachEntry( vLeaves, Leaf, i )
+ {
+ Vec_IntPush( vNodes, Leaf );
+ Ivy_ObjObj(pRoot, Leaf)->fMarkA = 1;
+ }
+ // collect and mark the nodes
+ Ivy_ManCollectCut_rec( pRoot, vNodes );
+ // clean the nodes
+ Vec_IntForEachEntry( vNodes, Leaf, i )
+ Ivy_ObjObj(pRoot, Leaf)->fMarkA = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the pointer to the truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Ivy_ObjGetTruthStore( int ObjNum, Vec_Int_t * vTruth )
+{
+ return ((unsigned *)Vec_IntArray(vTruth)) + 8 * ObjNum;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table of the cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ivy_ManCutTruthOne( Ivy_Obj_t * pNode, Vec_Int_t * vTruth, int nWords )
+{
+ unsigned * pTruth, * pTruth0, * pTruth1;
+ int i;
+ pTruth = Ivy_ObjGetTruthStore( pNode->TravId, vTruth );
+ pTruth0 = Ivy_ObjGetTruthStore( Ivy_ObjFanin0(pNode)->TravId, vTruth );
+ pTruth1 = Ivy_ObjGetTruthStore( Ivy_ObjFanin1(pNode)->TravId, vTruth );
+ if ( Ivy_ObjIsExor(pNode) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = pTruth0[i] ^ pTruth1[i];
+ else if ( !Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = pTruth0[i] & pTruth1[i];
+ else if ( !Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = pTruth0[i] & ~pTruth1[i];
+ else if ( Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ~pTruth0[i] & pTruth1[i];
+ else // if ( Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) )
+ for ( i = 0; i < nWords; i++ )
+ pTruth[i] = ~pTruth0[i] & ~pTruth1[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes truth table of the cut.]
+
+ Description [Does not modify the array of leaves. Uses array vTruth to store
+ temporary truth tables. The returned pointer should be used immediately.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned * Ivy_ManCutTruth( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth )
+{
+ static unsigned uTruths[8][8] = { // elementary truth tables
+ { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA },
+ { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC },
+ { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
+ { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
+ { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 },
+ { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
+ };
+ int i, Leaf;
+ // collect the cut
+ Ivy_ManCollectCut( pRoot, vLeaves, vNodes );
+ // set the node numbers
+ Vec_IntForEachEntry( vNodes, Leaf, i )
+ Ivy_ObjObj(pRoot, Leaf)->TravId = i;
+ // alloc enough memory
+ Vec_IntClear( vTruth );
+ Vec_IntGrow( vTruth, 8 * Vec_IntSize(vNodes) );
+ // set the elementary truth tables
+ Vec_IntForEachEntry( vLeaves, Leaf, i )
+ memcpy( Ivy_ObjGetTruthStore(i, vTruth), uTruths[i], 8 * sizeof(unsigned) );
+ // compute truths for other nodes
+ Vec_IntForEachEntryStart( vNodes, Leaf, i, Vec_IntSize(vLeaves) )
+ Ivy_ManCutTruthOne( Ivy_ObjObj(pRoot, Leaf), vTruth, 8 );
+ return Ivy_ObjGetTruthStore( pRoot->TravId, vTruth );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect the latches.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p )
+{
+ Vec_Int_t * vLatches;
+ Ivy_Obj_t * pObj;
+ int i;
+ vLatches = Vec_IntAlloc( Ivy_ManLatchNum(p) );
+ Ivy_ManForEachLatch( p, pObj, i )
+ Vec_IntPush( vLatches, pObj->Id );
+ return vLatches;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/ivy_.c b/src/temp/ivy/ivy_.c
new file mode 100644
index 00000000..65689689
--- /dev/null
+++ b/src/temp/ivy/ivy_.c
@@ -0,0 +1,48 @@
+/**CFile****************************************************************
+
+ FileName [ivy_.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [And-Inverter Graph package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: ivy_.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/ivy/module.make b/src/temp/ivy/module.make
new file mode 100644
index 00000000..d59a3fa3
--- /dev/null
+++ b/src/temp/ivy/module.make
@@ -0,0 +1,14 @@
+SRC += src/temp/ivy/ivyBalance.c \
+ src/temp/ivy/ivyCanon.c \
+ src/temp/ivy/ivyCheck.c \
+ src/temp/ivy/ivyCut.c \
+ src/temp/ivy/ivyDfs.c \
+ src/temp/ivy/ivyDsd.c \
+ src/temp/ivy/ivyMan.c \
+ src/temp/ivy/ivyObj.c \
+ src/temp/ivy/ivyOper.c \
+ src/temp/ivy/ivyRewrite.c \
+ src/temp/ivy/ivySeq.c \
+ src/temp/ivy/ivyTable.c \
+ src/temp/ivy/ivyUndo.c \
+ src/temp/ivy/ivyUtil.c
diff --git a/src/temp/player/module.make b/src/temp/player/module.make
new file mode 100644
index 00000000..81a5d77e
--- /dev/null
+++ b/src/temp/player/module.make
@@ -0,0 +1,5 @@
+SRC += src/temp/player/playerAbc.c \
+ src/temp/player/playerBuild.c \
+ src/temp/player/playerCore.c \
+ src/temp/player/playerMan.c \
+ src/temp/player/playerUtil.c
diff --git a/src/temp/player/player.h b/src/temp/player/player.h
new file mode 100644
index 00000000..9ecad35b
--- /dev/null
+++ b/src/temp/player/player.h
@@ -0,0 +1,123 @@
+/**CFile****************************************************************
+
+ FileName [player.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [PLA decomposition package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: player.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __XYZ_H__
+#define __XYZ_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ivy.h"
+#include "esop.h"
+#include "vec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Pla_Man_t_ Pla_Man_t;
+typedef struct Pla_Obj_t_ Pla_Obj_t;
+
+// storage for node information
+struct Pla_Obj_t_
+{
+ unsigned fFixed : 1; // fixed node
+ unsigned Depth : 7; // the depth in terms of LUTs/PLAs
+ unsigned nRefs : 24; // the number of references
+ Vec_Int_t vSupp[2]; // supports in two frames
+ Esop_Cube_t * pCover[2]; // esops in two frames
+};
+
+// storage for additional information
+struct Pla_Man_t_
+{
+ // general characteristics
+ int nLutMax; // the number of vars
+ int nPlaMax; // the number of vars
+ int nCubesMax; // the limit on the number of cubes in the intermediate covers
+ Ivy_Man_t * pManAig; // the AIG manager
+ Pla_Obj_t * pPlaStrs; // memory for structures
+ Esop_Man_t * pManMin; // the cube manager
+ // arrays to map local variables
+ Vec_Int_t * vComTo0; // mapping of common variables into first fanin
+ Vec_Int_t * vComTo1; // mapping of common variables into second fanin
+ Vec_Int_t * vPairs0; // the first var in each pair of common vars
+ Vec_Int_t * vPairs1; // the second var in each pair of common vars
+ Vec_Int_t * vTriv0; // trival support of the first node
+ Vec_Int_t * vTriv1; // trival support of the second node
+ // statistics
+ int nNodes; // the number of nodes processed
+ int nNodesLut; // the number of nodes processed
+ int nNodesPla; // the number of nodes processed
+ int nNodesBoth; // the number of nodes processed
+ int nNodesDeref; // the number of nodes processed
+};
+
+#define PLAYER_FANIN_LIMIT 128
+
+#define PLA_MIN(a,b) (((a) < (b))? (a) : (b))
+#define PLA_MAX(a,b) (((a) > (b))? (a) : (b))
+
+#define PLA_EMPTY ((Esop_Cube_t *)1)
+
+static inline Pla_Man_t * Ivy_ObjPlaMan( Ivy_Obj_t * pObj ) { return (Pla_Man_t *)Ivy_ObjMan(pObj)->pData; }
+static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Obj_t * pObj ) { return Ivy_ObjPlaMan(pObj)->pPlaStrs + pObj->Id; }
+
+static inline unsigned * Ivy_ObjGetTruth( Ivy_Obj_t * pObj )
+{
+ Ivy_Man_t * p = Ivy_ObjMan(pObj);
+ int Offset = Vec_IntEntry( p->vTruths, pObj->Id );
+ return Offset < 0 ? NULL : p->pMemory + Offset;
+
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== playerAbc.c ==============================================================*/
+extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nFaninMax, int fVerbose );
+/*=== playerBuild.c ============================================================*/
+extern Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * p );
+/*=== playerCore.c =============================================================*/
+extern Ivy_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose );
+/*=== playerMan.c ==============================================================*/
+extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax );
+extern void Pla_ManFree( Pla_Man_t * p );
+extern void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr );
+/*=== playerUtil.c =============================================================*/
+extern int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp );
+extern Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit );
+extern Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit );
+extern void Pla_ManComputeStats( Ivy_Man_t * pAig, Vec_Int_t * vNodes );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+
diff --git a/src/temp/player/playerAbc.c b/src/temp/player/playerAbc.c
new file mode 100644
index 00000000..9cc342d9
--- /dev/null
+++ b/src/temp/player/playerAbc.c
@@ -0,0 +1,215 @@
+/**CFile****************************************************************
+
+ FileName [playerAbc.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [PLAyer decomposition package.]
+
+ Synopsis [Bridge between ABC and PLAyer.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 20, 2006.]
+
+ Revision [$Id: playerAbc.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "player.h"
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p );
+static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Gives the current ABC network to PLAyer for processing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )
+{
+ Ivy_Man_t * pMan, * pManExt;
+ Abc_Ntk_t * pNtkAig;
+ if ( !Abc_NtkIsStrash(pNtk) )
+ return NULL;
+ // convert to the new AIG manager
+ pMan = Ivy_ManFromAbc( pNtk );
+ // check the correctness of conversion
+ if ( !Ivy_ManCheck( pMan ) )
+ {
+ printf( "Abc_NtkPlayer: Internal AIG check has failed.\n" );
+ Ivy_ManStop( pMan );
+ return NULL;
+ }
+ if ( fVerbose )
+ Ivy_ManPrintStats( pMan );
+ // perform decomposition/mapping into PLAs/LUTs
+ pManExt = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
+ Ivy_ManStop( pMan );
+ pMan = pManExt;
+ if ( fVerbose )
+ Ivy_ManPrintStats( pMan );
+ // convert from the extended AIG manager into an SOP network
+ pNtkAig = Ivy_ManToAbc( pNtk, pMan );
+ Ivy_ManStop( pMan );
+ // chech the resulting network
+ if ( !Abc_NtkCheck( pNtkAig ) )
+ {
+ printf( "Abc_NtkPlayer: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkAig );
+ return NULL;
+ }
+ return pNtkAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts from strashed AIG in ABC into strash AIG in IVY.]
+
+ Description [Assumes DFS ordering of nodes in the AIG of ABC.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk )
+{
+ Ivy_Man_t * pMan;
+ Abc_Obj_t * pObj;
+ int i;
+ // create the manager
+ pMan = Ivy_ManStart( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), Abc_NtkNodeNum(pNtk) + 10 );
+ // create the PIs
+ Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i);
+ // perform the conversion of the internal nodes
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ pObj->pCopy = (Abc_Obj_t *)Ivy_And( (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) );
+ // create the POs
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Ivy_ObjConnect( Ivy_ManPo(pMan, i), (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) );
+ Ivy_ManCleanup( pMan );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts AIG manager after PLA/LUT mapping into a logic ABC network.]
+
+ Description [The AIG manager contains nodes with extended functionality.
+ Node types are in pObj->Type. Node fanins are in pObj->vFanins. Functions
+ of LUT nodes are in pMan->vTruths.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
+{
+ Abc_Ntk_t * pNtkNew;
+ Vec_Int_t * vIvyNodes, * vIvyFanins, * vTruths = pMan->vTruths;
+ Abc_Obj_t * pObj, * pObjNew, * pFaninNew;
+ Ivy_Obj_t * pIvyNode, * pIvyFanin;
+ int pCompls[PLAYER_FANIN_LIMIT];
+ int i, k, Fanin, nFanins;
+ // start the new ABC network
+ pNtkNew = Abc_NtkStartFrom( pNtkOld, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ // transfer the pointers to the basic nodes
+ Ivy_ManCleanTravId(pMan);
+ Ivy_ManConst1(pMan)->TravId = Abc_NtkConst1(pNtkNew)->Id;
+ Abc_NtkForEachCi( pNtkNew, pObjNew, i )
+ Ivy_ManPi(pMan, i)->TravId = pObjNew->Id;
+ // construct the logic network isomorphic to logic network in the AIG manager
+ vIvyNodes = Ivy_ManDfsExt( pMan );
+ Ivy_ManForEachNodeVec( pMan, vIvyNodes, pIvyNode, i )
+ {
+ // get fanins of the old node
+ vIvyFanins = Ivy_ObjGetFanins( pIvyNode );
+ nFanins = Vec_IntSize(vIvyFanins);
+ // create the new node
+ pObjNew = Abc_NtkCreateNode( pNtkNew );
+ Vec_IntForEachEntry( vIvyFanins, Fanin, k )
+ {
+ pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_FanId(Fanin) );
+ pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
+ Abc_ObjAddFanin( pObjNew, pFaninNew );
+ pCompls[k] = Ivy_FanCompl(Fanin);
+ assert( Ivy_ObjIsAndMulti(pIvyNode) || nFanins == 1 || pCompls[k] == 0 ); // EXOR/LUT cannot have complemented fanins
+ }
+ assert( k <= PLAYER_FANIN_LIMIT );
+ // create logic function of the node
+ if ( Ivy_ObjIsAndMulti(pIvyNode) )
+ pObjNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, nFanins, pCompls );
+ else if ( Ivy_ObjIsExorMulti(pIvyNode) )
+ pObjNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nFanins );
+ else if ( Ivy_ObjIsLut(pIvyNode) )
+ pObjNew->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, nFanins, Ivy_ObjGetTruth(pIvyNode) );
+ else assert( 0 );
+ assert( Abc_SopGetVarNum(pObjNew->pData) == nFanins );
+ pIvyNode->TravId = pObjNew->Id;
+ }
+//Pla_ManComputeStats( pMan, vIvyNodes );
+ Vec_IntFree( vIvyNodes );
+ // connect the PO nodes
+ Abc_NtkForEachCo( pNtkOld, pObj, i )
+ {
+ // get the old fanin of the PO node
+ vIvyFanins = Ivy_ObjGetFanins( Ivy_ManPo(pMan, i) );
+ Fanin = Vec_IntEntry( vIvyFanins, 0 );
+ pIvyFanin = Ivy_ManObj( pMan, Ivy_FanId(Fanin) );
+ // get the new ABC node corresponding to the old fanin
+ pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
+ if ( Ivy_FanCompl(Fanin) ) // complement
+ {
+// pFaninNew = Abc_NodeCreateInv(pNtkNew, pFaninNew);
+ if ( Abc_ObjIsCi(pFaninNew) )
+ pFaninNew = Abc_NodeCreateInv(pNtkNew, pFaninNew);
+ else
+ {
+ // clone the node
+ pObjNew = Abc_NodeClone( pFaninNew );
+ // set complemented functions
+ pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pFaninNew->pData );
+ Abc_SopComplement(pObjNew->pData);
+ // return the new node
+ pFaninNew = pObjNew;
+ }
+ assert( Abc_SopGetVarNum(pFaninNew->pData) == Abc_ObjFaninNum(pFaninNew) );
+ }
+ Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
+ }
+ // remove dangling nodes
+ Abc_NtkForEachNode(pNtkNew, pObj, i)
+ if ( Abc_ObjFanoutNum(pObj) == 0 )
+ Abc_NtkDeleteObj(pObj);
+ // fix CIs feeding directly into COs
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
+ return pNtkNew;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/player/playerBuild.c b/src/temp/player/playerBuild.c
new file mode 100644
index 00000000..a7b06f03
--- /dev/null
+++ b/src/temp/player/playerBuild.c
@@ -0,0 +1,279 @@
+/**CFile****************************************************************
+
+ FileName [playerBuild.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [PLA decomposition package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: playerBuild.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "player.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld );
+static Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Esop_Cube_t * pCube, Vec_Int_t * vSupp );
+static Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 );
+static int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the AIG manager (IVY) for the network after mapping.]
+
+ Description [Uses extended node types (multi-input AND, multi-input EXOR, LUT).]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * pOld )
+{
+ Ivy_Man_t * pNew;
+ Ivy_Obj_t * pObjOld, * pObjNew;
+ int i;
+ // start the new manager
+ pNew = Ivy_ManStart( Ivy_ManPiNum(pOld), Ivy_ManPoNum(pOld), 2*Ivy_ManNodeNum(pOld) + 10 );
+ pNew->fExtended = 1;
+ // transfer the const/PI numbers
+ Ivy_ManCleanTravId(pOld);
+ Ivy_ManConst1(pOld)->TravId = Ivy_ManConst1(pNew)->Id;
+ Ivy_ManForEachPi( pOld, pObjOld, i )
+ pObjOld->TravId = Ivy_ManPi(pNew, i)->Id;
+ // recursively construct the network
+ Ivy_ManForEachPo( pOld, pObjOld, i )
+ {
+ pObjNew = Pla_ManToAig_rec( pNew, Ivy_ObjFanin0(pObjOld) );
+ Ivy_ObjStartFanins( Ivy_ManPo(pNew, i), 1 );
+ Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_FanCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) );
+ }
+ // compute the LUT functions
+ Pla_ManToAigLutFuncs( pNew, pOld );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively construct the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld )
+{
+ Pla_Man_t * p = Ivy_ObjMan(pObjOld)->pData;
+ Vec_Int_t * vSupp;
+ Esop_Cube_t * pCover, * pCube;
+ Ivy_Obj_t * pFaninOld, * pFaninNew, * pObjNew;
+ Pla_Obj_t * pStr;
+ int Entry, nCubes, ObjNewId, i;
+ // skip the node if it is a constant or already processed
+ if ( Ivy_ObjIsConst1(pObjOld) || pObjOld->TravId )
+ return Ivy_ManObj( pNew, pObjOld->TravId );
+ assert( Ivy_ObjIsAnd(pObjOld) || Ivy_ObjIsExor(pObjOld) );
+ // get the support and the cover
+ pStr = Ivy_ObjPlaStr( pObjOld );
+ if ( Vec_IntSize( &pStr->vSupp[0] ) <= p->nLutMax )
+ {
+ vSupp = &pStr->vSupp[0];
+ pCover = PLA_EMPTY;
+ }
+ else
+ {
+ vSupp = &pStr->vSupp[1];
+ pCover = pStr->pCover[1];
+ assert( pCover != PLA_EMPTY );
+ }
+ // process the fanins
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ Pla_ManToAig_rec( pNew, Ivy_ObjObj(pObjOld, Entry) );
+ // consider the case of a LUT
+ if ( pCover == PLA_EMPTY )
+ {
+ pObjNew = Ivy_ObjCreateExt( pNew, IVY_LUT );
+ Ivy_ObjStartFanins( pObjNew, p->nLutMax );
+ // remember new object ID in case it changes
+ ObjNewId = pObjNew->Id;
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ {
+ pFaninOld = Ivy_ObjObj( pObjOld, Entry );
+ Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_FanCreate(pFaninOld->TravId, 0) );
+ }
+ // get the new object
+ pObjNew = Ivy_ManObj(pNew, ObjNewId);
+ }
+ else
+ {
+ // for each cube, construct the node
+ nCubes = Esop_CoverCountCubes( pCover );
+ if ( nCubes == 0 )
+ pObjNew = Ivy_ManToAigConst( pNew, 0 );
+ else if ( nCubes == 1 )
+ pObjNew = Ivy_ManToAigCube( pNew, pObjOld, pCover, vSupp );
+ else
+ {
+ pObjNew = Ivy_ObjCreateExt( pNew, IVY_EXORM );
+ Ivy_ObjStartFanins( pObjNew, p->nLutMax );
+ // remember new object ID in case it changes
+ ObjNewId = pObjNew->Id;
+ Esop_CoverForEachCube( pCover, pCube )
+ {
+ pFaninNew = Ivy_ManToAigCube( pNew, pObjOld, pCube, vSupp );
+ Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_FanCreate(pFaninNew->Id, 0) );
+ }
+ // get the new object
+ pObjNew = Ivy_ManObj(pNew, ObjNewId);
+ }
+ }
+ pObjOld->TravId = pObjNew->Id;
+ pObjNew->TravId = pObjOld->Id;
+ return pObjNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns constant 1 node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 )
+{
+ Ivy_Obj_t * pObjNew;
+ pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM );
+ Ivy_ObjStartFanins( pObjNew, 1 );
+ Ivy_ObjAddFanin( pObjNew, Ivy_FanCreate(0, !fConst1) );
+ return pObjNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Esop_Cube_t * pCube, Vec_Int_t * vSupp )
+{
+ Ivy_Obj_t * pObjNew, * pFaninOld;
+ int i, Value;
+ // if tautology cube, create constant 1 node
+ if ( pCube->nLits == 0 )
+ return Ivy_ManToAigConst( pNew, 1 );
+ // create AND node
+ pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM );
+ Ivy_ObjStartFanins( pObjNew, pCube->nLits );
+ // add fanins
+ for ( i = 0; i < (int)pCube->nVars; i++ )
+ {
+ Value = Esop_CubeGetVar( pCube, i );
+ assert( Value != 0 );
+ if ( Value == 3 )
+ continue;
+ pFaninOld = Ivy_ObjObj( pObjOld, Vec_IntEntry(vSupp, i) );
+ Ivy_ObjAddFanin( pObjNew, Ivy_FanCreate( pFaninOld->TravId, Value==1 ) );
+ }
+ assert( Ivy_ObjFaninNum(pObjNew) == (int)pCube->nLits );
+ return pObjNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Recursively construct the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld )
+{
+ Vec_Int_t * vSupp, * vFanins, * vNodes, * vTemp;
+ Ivy_Obj_t * pObjOld, * pObjNew;
+ unsigned * pComputed, * pTruth;
+ int i, k, Counter = 0;
+ // create mapping from the LUT nodes into truth table indices
+ assert( pNew->vTruths == NULL );
+ vNodes = Vec_IntAlloc( 100 );
+ vTemp = Vec_IntAlloc( 100 );
+ pNew->vTruths = Vec_IntStart( Ivy_ManObjIdNext(pNew) );
+ Ivy_ManForEachObj( pNew, pObjNew, i )
+ {
+ if ( Ivy_ObjIsLut(pObjNew) )
+ Vec_IntWriteEntry( pNew->vTruths, i, 8 * Counter++ );
+ else
+ Vec_IntWriteEntry( pNew->vTruths, i, -1 );
+ }
+ // allocate memory
+ pNew->pMemory = ALLOC( unsigned, 8 * Counter );
+ memset( pNew->pMemory, 0, sizeof(unsigned) * 8 * Counter );
+ // derive truth tables
+ Ivy_ManForEachObj( pNew, pObjNew, i )
+ {
+ if ( !Ivy_ObjIsLut(pObjNew) )
+ continue;
+ pObjOld = Ivy_ManObj( pOld, pObjNew->TravId );
+ vSupp = Ivy_ObjPlaStr(pObjOld)->vSupp;
+ assert( Vec_IntSize(vSupp) <= 8 );
+ pTruth = Ivy_ObjGetTruth( pObjNew );
+ pComputed = Ivy_ManCutTruth( pObjOld, vSupp, vNodes, vTemp );
+ // check if the truth table is constant 0
+ for ( k = 0; k < 8; k++ )
+ if ( pComputed[k] )
+ break;
+ if ( k == 8 )
+ {
+ // create inverter
+ for ( k = 0; k < 8; k++ )
+ pComputed[k] = 0x55555555;
+ // point it to the constant 1 node
+ vFanins = Ivy_ObjGetFanins( pObjNew );
+ Vec_IntClear( vFanins );
+ Vec_IntPush( vFanins, Ivy_FanCreate(0, 1) );
+ }
+ memcpy( pTruth, pComputed, sizeof(unsigned) * 8 );
+// Extra_PrintBinary( stdout, pTruth, 16 ); printf( "\n" );
+ }
+ Vec_IntFree( vTemp );
+ Vec_IntFree( vNodes );
+ return Counter;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/player/playerCore.c b/src/temp/player/playerCore.c
new file mode 100644
index 00000000..3cd3d8a8
--- /dev/null
+++ b/src/temp/player/playerCore.c
@@ -0,0 +1,381 @@
+/**CFile****************************************************************
+
+ FileName [playerCore.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [PLA decomposition package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: playerCore.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "player.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Pla_ManDecomposeInt( Pla_Man_t * p );
+static int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj );
+static void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level,
+ Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ivy_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fVerbose )
+{
+ Pla_Man_t * p;
+ Ivy_Man_t * pAigNew;
+ p = Pla_ManAlloc( pAig, nLutMax, nPlaMax );
+ if ( !Pla_ManDecomposeInt( p ) )
+ {
+ printf( "Decomposition/mapping failed.\n" );
+ Pla_ManFree( p );
+ return NULL;
+ }
+ pAigNew = Pla_ManToAig( pAig );
+// if ( fVerbose )
+// printf( "PLA stats: Both = %6d. Pla = %6d. Lut = %6d. Total = %6d. Deref = %6d.\n",
+// p->nNodesBoth, p->nNodesPla, p->nNodesLut, p->nNodes, p->nNodesDeref );
+ Pla_ManFree( p );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Pla_ManDecomposeInt( Pla_Man_t * p )
+{
+ Ivy_Man_t * pAig = p->pManAig;
+ Ivy_Obj_t * pObj;
+ Pla_Obj_t * pStr;
+ int i;
+
+ // prepare the PI structures
+ Ivy_ManForEachPi( pAig, pObj, i )
+ {
+ pStr = Ivy_ObjPlaStr( pObj );
+ pStr->fFixed = 1;
+ pStr->Depth = 0;
+ pStr->nRefs = (unsigned)pObj->nRefs;
+ pStr->pCover[0] = PLA_EMPTY;
+ pStr->pCover[1] = PLA_EMPTY;
+ }
+
+ // assuming DFS ordering of nodes in the manager
+ Ivy_ManForEachNode( pAig, pObj, i )
+ if ( !Pla_ManDecomposeNode(p, pObj) )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records decomposition statistics for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Pla_ManCountDecNodes( Pla_Man_t * p, Pla_Obj_t * pStr )
+{
+ if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax && pStr->pCover[1] != PLA_EMPTY )
+ p->nNodesBoth++;
+ else if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax )
+ p->nNodesLut++;
+ else if ( pStr->pCover[1] != PLA_EMPTY )
+ p->nNodesPla++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs decomposition/mapping for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj )
+{
+ Pla_Obj_t * pStr, * pStr0, * pStr1;
+ Vec_Int_t * vSuppA, * vSuppB, * vSupp0, * vSupp1;
+ Esop_Cube_t * pCovA, * pCovB;
+ int nSuppSize1, nSuppSize2;
+
+ assert( pObj->nRefs > 0 );
+ p->nNodes++;
+
+ // get the structures
+ pStr = Ivy_ObjPlaStr( pObj );
+ pStr0 = Ivy_ObjPlaStr( Ivy_ObjFanin0( pObj ) );
+ pStr1 = Ivy_ObjPlaStr( Ivy_ObjFanin1( pObj ) );
+ vSupp0 = &pStr->vSupp[0];
+ vSupp1 = &pStr->vSupp[1];
+ pStr->pCover[0] = PLA_EMPTY;
+ pStr->pCover[1] = PLA_EMPTY;
+
+ // process level 1
+ Pla_NodeGetSuppsAndCovers( p, pObj, 1, &vSuppA, &vSuppB, &pCovA, &pCovB );
+ nSuppSize1 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 );
+ if ( nSuppSize1 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
+ pStr->pCover[0] = PLA_EMPTY;
+ else if ( Ivy_ObjIsAnd(pObj) )
+ pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 );
+ else
+ pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 );
+
+ // process level 2
+ if ( PLA_MAX(pStr0->Depth, pStr1->Depth) > 1 )
+ {
+ Pla_NodeGetSuppsAndCovers( p, pObj, 2, &vSuppA, &vSuppB, &pCovA, &pCovB );
+ nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp1 );
+ if ( nSuppSize2 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
+ pStr->pCover[1] = PLA_EMPTY;
+ else if ( Ivy_ObjIsAnd(pObj) )
+ pStr->pCover[1] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 );
+ else
+ pStr->pCover[1] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 );
+ }
+
+ // determine the level of this node
+ pStr->nRefs = (unsigned)pObj->nRefs;
+ pStr->Depth = PLA_MAX( pStr0->Depth, pStr1->Depth );
+ pStr->Depth = pStr->Depth? pStr->Depth : 1;
+ if ( nSuppSize1 > p->nLutMax && pStr->pCover[1] == PLA_EMPTY )
+ {
+ pStr->Depth++;
+ // free second level
+ if ( pStr->pCover[1] != PLA_EMPTY )
+ Esop_CoverRecycle( p->pManMin, pStr->pCover[1] );
+ vSupp1->nCap = 0;
+ vSupp1->nSize = 0;
+ FREE( vSupp1->pArray );
+ pStr->pCover[1] = PLA_EMPTY;
+ // move first to second
+ pStr->vSupp[1] = pStr->vSupp[0];
+ pStr->pCover[1] = pStr->pCover[0];
+ vSupp0->nCap = 0;
+ vSupp0->nSize = 0;
+ vSupp0->pArray = NULL;
+ pStr->pCover[0] = PLA_EMPTY;
+ // get zero level
+ Pla_NodeGetSuppsAndCovers( p, pObj, 0, &vSuppA, &vSuppB, &pCovA, &pCovB );
+ nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 );
+ assert( nSuppSize2 == 2 );
+ if ( pCovA == PLA_EMPTY || pCovB == PLA_EMPTY )
+ pStr->pCover[0] = PLA_EMPTY;
+ else if ( Ivy_ObjIsAnd(pObj) )
+ pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 );
+ else
+ pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 );
+ // count stats
+ if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 );
+ if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 );
+ // mark the nodes
+ pStr0->fFixed = 1;
+ pStr1->fFixed = 1;
+ }
+ else if ( pStr0->Depth < pStr1->Depth )
+ {
+ if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 );
+ pStr0->fFixed = 1;
+ }
+ else // if ( pStr0->Depth > pStr1->Depth )
+ {
+ if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 );
+ pStr1->fFixed = 1;
+ }
+
+ // free some of the covers to save memory
+ assert( pStr0->nRefs > 0 );
+ assert( pStr1->nRefs > 0 );
+ pStr0->nRefs--;
+ pStr1->nRefs--;
+
+ if ( pStr0->nRefs == 0 && !pStr0->fFixed )
+ Pla_ManFreeStr( p, pStr0 ), p->nNodesDeref++;
+ if ( pStr1->nRefs == 0 && !pStr1->fFixed )
+ Pla_ManFreeStr( p, pStr1 ), p->nNodesDeref++;
+
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns pointers to the support arrays on the given level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level,
+ Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB )
+{
+ Ivy_Obj_t * pFan0, * pFan1;
+ Pla_Obj_t * pStr, * pStr0, * pStr1;
+ Esop_Cube_t * pCovA, * pCovB;
+ int fCompl0, fCompl1;
+ assert( Level >= 0 && Level <= 2 );
+ // get the complemented attributes
+ fCompl0 = Ivy_ObjFaninC0( pObj );
+ fCompl1 = Ivy_ObjFaninC1( pObj );
+ // get the fanins
+ pFan0 = Ivy_ObjFanin0( pObj );
+ pFan1 = Ivy_ObjFanin1( pObj );
+ // get the structures
+ pStr = Ivy_ObjPlaStr( pObj );
+ pStr0 = Ivy_ObjPlaStr( pFan0 );
+ pStr1 = Ivy_ObjPlaStr( pFan1 );
+ // make sure the fanins are processed
+ assert( Ivy_ObjIsPi(pFan0) || pStr0->Depth > 0 );
+ assert( Ivy_ObjIsPi(pFan1) || pStr1->Depth > 0 );
+ // prepare the return values depending on the level
+ Vec_IntWriteEntry( p->vTriv0, 0, pFan0->Id );
+ Vec_IntWriteEntry( p->vTriv1, 0, pFan1->Id );
+ *pvSuppA = p->vTriv0;
+ *pvSuppB = p->vTriv1;
+ pCovA = p->pManMin->pTriv0;
+ pCovB = p->pManMin->pTriv1;
+ if ( Level == 1 )
+ {
+ if ( pStr0->Depth == pStr1->Depth )
+ {
+ if ( pStr0->Depth > 0 )
+ {
+ *pvSuppA = &pStr0->vSupp[0];
+ *pvSuppB = &pStr1->vSupp[0];
+ pCovA = pStr0->pCover[0];
+ pCovB = pStr1->pCover[0];
+ }
+ }
+ else if ( pStr0->Depth < pStr1->Depth )
+ {
+ *pvSuppB = &pStr1->vSupp[0];
+ pCovB = pStr1->pCover[0];
+ }
+ else // if ( pStr0->Depth > pStr1->Depth )
+ {
+ *pvSuppA = &pStr0->vSupp[0];
+ pCovA = pStr0->pCover[0];
+ }
+ }
+ else if ( Level == 2 )
+ {
+ if ( pStr0->Depth == pStr1->Depth )
+ {
+ *pvSuppA = &pStr0->vSupp[1];
+ *pvSuppB = &pStr1->vSupp[1];
+ pCovA = pStr0->pCover[1];
+ pCovB = pStr1->pCover[1];
+ }
+ else if ( pStr0->Depth + 1 == pStr1->Depth )
+ {
+ *pvSuppA = &pStr0->vSupp[0];
+ *pvSuppB = &pStr1->vSupp[1];
+ pCovA = pStr0->pCover[0];
+ pCovB = pStr1->pCover[1];
+ }
+ else if ( pStr0->Depth == pStr1->Depth + 1 )
+ {
+ *pvSuppA = &pStr0->vSupp[1];
+ *pvSuppB = &pStr1->vSupp[0];
+ pCovA = pStr0->pCover[1];
+ pCovB = pStr1->pCover[0];
+ }
+ else if ( pStr0->Depth < pStr1->Depth )
+ {
+ *pvSuppB = &pStr1->vSupp[1];
+ pCovB = pStr1->pCover[1];
+ }
+ else // if ( pStr0->Depth > pStr1->Depth )
+ {
+ *pvSuppA = &pStr0->vSupp[1];
+ pCovA = pStr0->pCover[1];
+ }
+ }
+ // complement the first if needed
+ if ( pCovA == PLA_EMPTY || !fCompl0 )
+ *pvCovA = pCovA;
+ else if ( pCovA && pCovA->nLits == 0 ) // topmost one is the tautology cube
+ *pvCovA = pCovA->pNext;
+ else
+ *pvCovA = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCovA;
+ // complement the second if needed
+ if ( pCovB == PLA_EMPTY || !fCompl1 )
+ *pvCovB = pCovB;
+ else if ( pCovB && pCovB->nLits == 0 ) // topmost one is the tautology cube
+ *pvCovB = pCovB->pNext;
+ else
+ *pvCovB = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCovB;
+}
+
+
+/*
+ if ( pObj->Id == 1371 )
+ {
+ int k;
+ printf( "Zero : " );
+ for ( k = 0; k < vSuppA->nSize; k++ )
+ printf( "%d ", vSuppA->pArray[k] );
+ printf( "\n" );
+ printf( "One : " );
+ for ( k = 0; k < vSuppB->nSize; k++ )
+ printf( "%d ", vSuppB->pArray[k] );
+ printf( "\n" );
+ printf( "Node : " );
+ for ( k = 0; k < vSupp0->nSize; k++ )
+ printf( "%d ", vSupp0->pArray[k] );
+ printf( "\n" );
+ printf( "\n" );
+ printf( "\n" );
+ Esop_CoverWrite( stdout, pCovA );
+ printf( "\n" );
+ Esop_CoverWrite( stdout, pCovB );
+ printf( "\n" );
+ }
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/player/playerMan.c b/src/temp/player/playerMan.c
new file mode 100644
index 00000000..7f2c0919
--- /dev/null
+++ b/src/temp/player/playerMan.c
@@ -0,0 +1,125 @@
+/**CFile****************************************************************
+
+ FileName [playerMan.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [PLA decomposition package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: playerMan.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "player.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates the PLA/LUT mapping manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * pAig, int nLutMax, int nPlaMax )
+{
+ Pla_Man_t * pMan;
+ assert( !(nLutMax < 2 || nLutMax > 8 || nPlaMax < 8 || nPlaMax > 128) );
+ // start the manager
+ pMan = ALLOC( Pla_Man_t, 1 );
+ memset( pMan, 0, sizeof(Pla_Man_t) );
+ pMan->nLutMax = nLutMax;
+ pMan->nPlaMax = nPlaMax;
+ pMan->nCubesMax = 2 * nPlaMax; // higher limit, later reduced
+ pMan->pManAig = pAig;
+ // set up the temporaries
+ pMan->vComTo0 = Vec_IntAlloc( 2 * nPlaMax );
+ pMan->vComTo1 = Vec_IntAlloc( 2 * nPlaMax );
+ pMan->vPairs0 = Vec_IntAlloc( nPlaMax );
+ pMan->vPairs1 = Vec_IntAlloc( nPlaMax );
+ pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 );
+ pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 );
+ // allocate memory for object structures
+ pMan->pPlaStrs = ALLOC( Pla_Obj_t, sizeof(Pla_Obj_t) * Ivy_ManObjIdNext(pAig) );
+ memset( pMan->pPlaStrs, 0, sizeof(Pla_Obj_t) * Ivy_ManObjIdNext(pAig) );
+ // create the cube manager
+ pMan->pManMin = Esop_ManAlloc( nPlaMax );
+ // save the resulting manager
+ assert( pAig->pData == NULL );
+ pAig->pData = pMan;
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the PLA/LUT mapping manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pla_ManFree( Pla_Man_t * p )
+{
+ Pla_Obj_t * pStr;
+ int i;
+ Esop_ManFree( p->pManMin );
+ Vec_IntFree( p->vTriv0 );
+ Vec_IntFree( p->vTriv1 );
+ Vec_IntFree( p->vComTo0 );
+ Vec_IntFree( p->vComTo1 );
+ Vec_IntFree( p->vPairs0 );
+ Vec_IntFree( p->vPairs1 );
+ for ( i = 0, pStr = p->pPlaStrs; i < Ivy_ManObjIdNext(p->pManAig); i++, pStr++ )
+ FREE( pStr->vSupp[0].pArray ), FREE( pStr->vSupp[1].pArray );
+ free( p->pPlaStrs );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cleans the PLA/LUT structure of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr )
+{
+ if ( pStr->pCover[0] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[0] );
+ if ( pStr->pCover[1] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[1] );
+ if ( pStr->vSupp[0].pArray ) free( pStr->vSupp[0].pArray );
+ if ( pStr->vSupp[1].pArray ) free( pStr->vSupp[1].pArray );
+ memset( pStr, 0, sizeof(Pla_Obj_t) );
+ pStr->pCover[0] = PLA_EMPTY;
+ pStr->pCover[1] = PLA_EMPTY;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/player/playerUtil.c b/src/temp/player/playerUtil.c
new file mode 100644
index 00000000..1b361839
--- /dev/null
+++ b/src/temp/player/playerUtil.c
@@ -0,0 +1,349 @@
+/**CFile****************************************************************
+
+ FileName [playerUtil.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [PLA decomposition package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: playerUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "player.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Merges two supports.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp )
+{
+ int k0, k1;
+
+ assert( vSupp0->nSize && vSupp1->nSize );
+
+ Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 );
+ Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 );
+ Vec_IntClear( p->vPairs0 );
+ Vec_IntClear( p->vPairs1 );
+
+ vSupp->nSize = 0;
+ vSupp->nCap = vSupp0->nSize + vSupp1->nSize;
+ vSupp->pArray = ALLOC( int, vSupp->nCap );
+
+ for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; )
+ {
+ if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] )
+ {
+ Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
+ Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
+ Vec_IntPush( p->vPairs0, k0 );
+ Vec_IntPush( p->vPairs1, k1 );
+ Vec_IntPush( vSupp, vSupp0->pArray[k0] );
+ k0++; k1++;
+ }
+ else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] )
+ {
+ Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
+ Vec_IntPush( vSupp, vSupp0->pArray[k0] );
+ k0++;
+ }
+ else
+ {
+ Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
+ Vec_IntPush( vSupp, vSupp1->pArray[k1] );
+ k1++;
+ }
+ }
+ for ( ; k0 < vSupp0->nSize; k0++ )
+ {
+ Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 );
+ Vec_IntPush( vSupp, vSupp0->pArray[k0] );
+ }
+ for ( ; k1 < vSupp1->nSize; k1++ )
+ {
+ Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 );
+ Vec_IntPush( vSupp, vSupp1->pArray[k1] );
+ }
+/*
+ printf( "Zero : " );
+ for ( k = 0; k < vSupp0->nSize; k++ )
+ printf( "%d ", vSupp0->pArray[k] );
+ printf( "\n" );
+
+ printf( "One : " );
+ for ( k = 0; k < vSupp1->nSize; k++ )
+ printf( "%d ", vSupp1->pArray[k] );
+ printf( "\n" );
+
+ printf( "Sum : " );
+ for ( k = 0; k < vSupp->nSize; k++ )
+ printf( "%d ", vSupp->pArray[k] );
+ printf( "\n" );
+ printf( "\n" );
+*/
+ return Vec_IntSize(vSupp);
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the produce of two covers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit )
+{
+ Esop_Cube_t * pCube, * pCube0, * pCube1;
+ Esop_Cube_t * pCover;
+ int i, Val0, Val1;
+ assert( pCover0 != PLA_EMPTY && pCover1 != PLA_EMPTY );
+
+ // clean storage
+ assert( nSupp <= p->nPlaMax );
+ Esop_ManClean( p->pManMin, nSupp );
+ // go through the cube pairs
+ Esop_CoverForEachCube( pCover0, pCube0 )
+ Esop_CoverForEachCube( pCover1, pCube1 )
+ {
+ // go through the support variables of the cubes
+ for ( i = 0; i < p->vPairs0->nSize; i++ )
+ {
+ Val0 = Esop_CubeGetVar( pCube0, p->vPairs0->pArray[i] );
+ Val1 = Esop_CubeGetVar( pCube1, p->vPairs1->pArray[i] );
+ if ( (Val0 & Val1) == 0 )
+ break;
+ }
+ // check disjointness
+ if ( i < p->vPairs0->nSize )
+ continue;
+
+ if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax )
+ {
+ pCover = Esop_CoverCollect( p->pManMin, nSupp );
+//Esop_CoverWriteFile( pCover, "large", 1 );
+ Esop_CoverRecycle( p->pManMin, pCover );
+ return PLA_EMPTY;
+ }
+
+ // create the product cube
+ pCube = Esop_CubeAlloc( p->pManMin );
+
+ // add the literals
+ pCube->nLits = 0;
+ for ( i = 0; i < nSupp; i++ )
+ {
+ if ( p->vComTo0->pArray[i] == -1 )
+ Val0 = 3;
+ else
+ Val0 = Esop_CubeGetVar( pCube0, p->vComTo0->pArray[i] );
+
+ if ( p->vComTo1->pArray[i] == -1 )
+ Val1 = 3;
+ else
+ Val1 = Esop_CubeGetVar( pCube1, p->vComTo1->pArray[i] );
+
+ if ( (Val0 & Val1) == 3 )
+ continue;
+
+ Esop_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 );
+ pCube->nLits++;
+ }
+ // add the cube to storage
+ Esop_EsopAddCube( p->pManMin, pCube );
+ }
+
+ // minimize the cover
+ Esop_EsopMinimize( p->pManMin );
+ pCover = Esop_CoverCollect( p->pManMin, nSupp );
+
+ // quit if the cover is too large
+ if ( fStopAtLimit && Esop_CoverCountCubes(pCover) > p->nPlaMax )
+ {
+ Esop_CoverRecycle( p->pManMin, pCover );
+ return PLA_EMPTY;
+ }
+// if ( pCover && pCover->nWords > 4 )
+// printf( "%d", pCover->nWords );
+// else
+// printf( "." );
+ return pCover;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the EXOR of two covers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit )
+{
+ Esop_Cube_t * pCube, * pCube0, * pCube1;
+ Esop_Cube_t * pCover;
+ int i, Val0, Val1;
+ assert( pCover0 != PLA_EMPTY && pCover1 != PLA_EMPTY );
+
+ // clean storage
+ assert( nSupp <= p->nPlaMax );
+ Esop_ManClean( p->pManMin, nSupp );
+ Esop_CoverForEachCube( pCover0, pCube0 )
+ {
+ // create the cube
+ pCube = Esop_CubeAlloc( p->pManMin );
+ pCube->nLits = 0;
+ for ( i = 0; i < p->vComTo0->nSize; i++ )
+ {
+ if ( p->vComTo0->pArray[i] == -1 )
+ continue;
+ Val0 = Esop_CubeGetVar( pCube0, p->vComTo0->pArray[i] );
+ if ( Val0 == 3 )
+ continue;
+ Esop_CubeXorVar( pCube, i, Val0 ^ 3 );
+ pCube->nLits++;
+ }
+ if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax )
+ {
+ pCover = Esop_CoverCollect( p->pManMin, nSupp );
+ Esop_CoverRecycle( p->pManMin, pCover );
+ return PLA_EMPTY;
+ }
+ // add the cube to storage
+ Esop_EsopAddCube( p->pManMin, pCube );
+ }
+ Esop_CoverForEachCube( pCover1, pCube1 )
+ {
+ // create the cube
+ pCube = Esop_CubeAlloc( p->pManMin );
+ pCube->nLits = 0;
+ for ( i = 0; i < p->vComTo1->nSize; i++ )
+ {
+ if ( p->vComTo1->pArray[i] == -1 )
+ continue;
+ Val1 = Esop_CubeGetVar( pCube1, p->vComTo1->pArray[i] );
+ if ( Val1 == 3 )
+ continue;
+ Esop_CubeXorVar( pCube, i, Val1 ^ 3 );
+ pCube->nLits++;
+ }
+ if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax )
+ {
+ pCover = Esop_CoverCollect( p->pManMin, nSupp );
+ Esop_CoverRecycle( p->pManMin, pCover );
+ return PLA_EMPTY;
+ }
+ // add the cube to storage
+ Esop_EsopAddCube( p->pManMin, pCube );
+ }
+
+ // minimize the cover
+ Esop_EsopMinimize( p->pManMin );
+ pCover = Esop_CoverCollect( p->pManMin, nSupp );
+
+ // quit if the cover is too large
+ if ( fStopAtLimit && Esop_CoverCountCubes(pCover) > p->nPlaMax )
+ {
+ Esop_CoverRecycle( p->pManMin, pCover );
+ return PLA_EMPTY;
+ }
+ return pCover;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes area/delay of the mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes )
+{
+ Ivy_Obj_t * pObj, * pFanin;
+ Vec_Int_t * vFanins;
+ int Area, Delay, Fanin, nFanins, i, k;
+
+ Delay = Area = 0;
+ // compute levels and area
+ Ivy_ManForEachPi( p, pObj, i )
+ pObj->Level = 0;
+ Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
+ {
+ // compute level of the node
+ pObj->Level = 0;
+ vFanins = Ivy_ObjGetFanins( pObj );
+ Vec_IntForEachEntry( vFanins, Fanin, k )
+ {
+ pFanin = Ivy_ManObj(p, Ivy_FanId(Fanin));
+ pObj->Level = IVY_MAX( pObj->Level, pFanin->Level );
+ }
+ pObj->Level += 1;
+ // compute area of the node
+ nFanins = Ivy_ObjFaninNum( pObj );
+ if ( nFanins <= 4 )
+ Area += 1;
+ else if ( nFanins <= 6 )
+ Area += 2;
+ else if ( nFanins <= 8 )
+ Area += 4;
+ else if ( nFanins <= 16 )
+ Area += 8;
+ else if ( nFanins <= 32 )
+ Area += 16;
+ else if ( nFanins <= 64 )
+ Area += 32;
+ else if ( nFanins <= 128 )
+ Area += 64;
+ else
+ assert( 0 );
+ }
+ Ivy_ManForEachPo( p, pObj, i )
+ {
+ Fanin = Ivy_ObjReadFanin(pObj, 0);
+ pFanin = Ivy_ManObj( p, Ivy_FanId(Fanin) );
+ pObj->Level = pFanin->Level;
+ Delay = IVY_MAX( Delay, (int)pObj->Level );
+ }
+ printf( "Area = %d. Delay = %d.\n", Area, Delay );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+