summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--abc.dsp114
-rw-r--r--abc.rc7
-rw-r--r--src/base/abc/abc.h30
-rw-r--r--src/base/abc/abcCheck.c13
-rw-r--r--src/base/abc/abcDfs.c116
-rw-r--r--src/base/abc/abcFanio.c7
-rw-r--r--src/base/abc/abcLatch.c26
-rw-r--r--src/base/abc/abcNetlist.c13
-rw-r--r--src/base/abc/abcNtk.c71
-rw-r--r--src/base/abc/abcObj.c61
-rw-r--r--src/base/abc/abcRefs.c8
-rw-r--r--src/base/abc/abcShow.c6
-rw-r--r--src/base/abc/abcUtil.c40
-rw-r--r--src/base/abci/abc.c400
-rw-r--r--src/base/abci/abcBmc.c115
-rw-r--r--src/base/abci/abcDsd.c2
-rw-r--r--src/base/abci/abcFpga.c2
-rw-r--r--src/base/abci/abcFpgaFast.c4
-rw-r--r--src/base/abci/abcIvy.c35
-rw-r--r--src/base/abci/abcLut.c4
-rw-r--r--src/base/abci/abcMap.c10
-rw-r--r--src/base/abci/abcNtbdd.c8
-rw-r--r--src/base/abci/abcPrint.c107
-rw-r--r--src/base/abci/abcSweep.c262
-rw-r--r--src/base/abci/abcVerify.c4
-rw-r--r--src/base/abci/abcXsim.c164
-rw-r--r--src/base/abci/module.make4
-rw-r--r--src/base/io/ioUtil.c6
-rw-r--r--src/base/io/ioWriteDot.c13
-rw-r--r--src/base/seq/seqUtil.c3
-rw-r--r--src/bdd/dsd/dsd.h8
-rw-r--r--src/bdd/reo/reo.h4
-rw-r--r--src/map/fpga/fpga.h8
-rw-r--r--src/map/fpga/fpgaInt.h16
-rw-r--r--src/map/mapper/mapper.h8
-rw-r--r--src/map/mapper/mapperInt.h8
-rw-r--r--src/map/super/superAnd.c8
-rw-r--r--src/misc/nm/nmApi.c2
-rw-r--r--src/misc/vec/vecPtr.h26
-rw-r--r--src/opt/ret/module.make8
-rw-r--r--src/opt/ret/retArea.c593
-rw-r--r--src/opt/ret/retBwd.c65
-rw-r--r--src/opt/ret/retCore.c76
-rw-r--r--src/opt/ret/retDelay.c65
-rw-r--r--src/opt/ret/retFlow.c462
-rw-r--r--src/opt/ret/retFwd.c65
-rw-r--r--src/opt/ret/retInit.c71
-rw-r--r--src/opt/ret/retInt.h68
-rw-r--r--src/opt/ret/ret_.c48
-rw-r--r--src/opt/rwr/rwr.h8
-rw-r--r--src/sat/fraig/fraig.h8
-rw-r--r--src/temp/aig-alan.tar.gzbin0 -> 27265 bytes
-rw-r--r--src/temp/aig/aig.h17
-rw-r--r--src/temp/aig/aigBalance.c2
-rw-r--r--src/temp/aig/cudd2.c20
-rw-r--r--src/temp/aig/cudd2.h6
-rw-r--r--src/temp/aig_free/aig.h321
-rw-r--r--src/temp/aig_free/aigBalance.c391
-rw-r--r--src/temp/aig_free/aigCheck.c110
-rw-r--r--src/temp/aig_free/aigDfs.c399
-rw-r--r--src/temp/aig_free/aigMan.c162
-rw-r--r--src/temp/aig_free/aigMem.c115
-rw-r--r--src/temp/aig_free/aigObj.c228
-rw-r--r--src/temp/aig_free/aigOper.c373
-rw-r--r--src/temp/aig_free/aigTable.c266
-rw-r--r--src/temp/aig_free/aigUtil.c513
-rw-r--r--src/temp/aig_free/cudd2.c375
-rw-r--r--src/temp/aig_free/cudd2.h83
-rw-r--r--src/temp/aig_free/st.c626
-rw-r--r--src/temp/aig_free/st.h96
-rw-r--r--src/temp/aig_free/subdir.mk87
-rw-r--r--src/temp/aig_free/vec.h82
-rw-r--r--src/temp/aig_free/vecFlt.h667
-rw-r--r--src/temp/aig_free/vecInt.h781
-rw-r--r--src/temp/aig_free/vecPtr.h587
-rw-r--r--src/temp/aig_free/vecStr.h510
-rw-r--r--src/temp/aig_free/vecVec.h289
-rw-r--r--src/temp/esop/esop.h723
-rw-r--r--src/temp/esop/esopMan.c117
-rw-r--r--src/temp/esop/esopMin.c299
-rw-r--r--src/temp/esop/esopUtil.c277
-rw-r--r--src/temp/esop/module.make3
-rw-r--r--src/temp/ivy/ivy.h11
-rw-r--r--src/temp/ivy/ivyFraig.c5
-rw-r--r--src/temp/ivy/ivyHaig.c16
-rw-r--r--src/temp/ivy/ivyMan.c129
-rw-r--r--src/temp/ivy/ivyObj.c15
-rw-r--r--src/temp/ivy/ivySeq.c4
-rw-r--r--src/temp/ivy/ivyUtil.c35
-rw-r--r--src/temp/player/module.make4
-rw-r--r--src/temp/player/player.h113
-rw-r--r--src/temp/player/playerAbc.c228
-rw-r--r--src/temp/player/playerBuild.c283
-rw-r--r--src/temp/player/playerCore.c376
-rw-r--r--src/temp/player/playerMan.c125
-rw-r--r--src/temp/player/playerToAbc.c523
-rw-r--r--src/temp/player/playerUtil.c353
-rw-r--r--src/temp/rwt/rwt.h8
-rw-r--r--src/temp/ver/verCore.c4
100 files changed, 13679 insertions, 366 deletions
diff --git a/Makefile b/Makefile
index ef5d745d..cf5e864f 100644
--- a/Makefile
+++ b/Makefile
@@ -6,18 +6,18 @@ CP := cp
PROG := abc
-MODULES := src/base/abc src/base/abci src/base/seq src/base/cmd src/base/io src/base/main \
+MODULES := src/base/abc src/base/abci src/base/cmd src/base/io src/base/main \
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse src/bdd/reo \
src/map/fpga src/map/pga src/map/mapper src/map/mio src/map/super \
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/espresso src/misc/nm src/misc/vec src/misc/hash \
- src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim \
+ src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim src/opt/ret \
src/sat/asat src/sat/bsat src/sat/csat src/sat/msat src/sat/fraig \
src/temp/ivy src/temp/aig src/temp/rwt src/temp/deco src/temp/mem src/temp/ver
default: $(PROG)
-OPTFLAGS := -DNDEBUG -O3
-#OPTFLAGS := -g -O
+#OPTFLAGS := -DNDEBUG -O3
+OPTFLAGS := -g -O
CFLAGS += -Wall -Wno-unused-function $(OPTFLAGS) $(patsubst %, -I%, $(MODULES))
CXXFLAGS += $(CFLAGS)
diff --git a/abc.dsp b/abc.dsp
index aad90c3c..6690e23b 100644
--- a/abc.dsp
+++ b/abc.dsp
@@ -186,6 +186,10 @@ SOURCE=.\src\base\abci\abcBalance.c
# End Source File
# Begin Source File
+SOURCE=.\src\base\abci\abcBmc.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\base\abci\abcClpBdd.c
# End Source File
# Begin Source File
@@ -332,73 +336,9 @@ SOURCE=.\src\base\abci\abcUnreach.c
SOURCE=.\src\base\abci\abcVerify.c
# End Source File
-# End Group
-# Begin Group "seq"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\src\base\seq\seq.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqAigCore.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqAigIter.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqCreate.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqFpgaCore.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqFpgaIter.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqInt.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqLatch.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqMan.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqMapCore.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqMapIter.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqMaxMeanCycle.c
-# End Source File
# Begin Source File
-SOURCE=.\src\base\seq\seqRetCore.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqRetIter.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqShare.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\base\seq\seqUtil.c
+SOURCE=.\src\base\abci\abcXsim.c
# End Source File
# End Group
# Begin Group "cmd"
@@ -1389,6 +1329,42 @@ SOURCE=.\src\opt\sim\simSymStr.c
SOURCE=.\src\opt\sim\simUtils.c
# End Source File
# End Group
+# Begin Group "ret"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\src\opt\ret\retArea.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\ret\retBwd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\ret\retCore.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\ret\retDelay.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\ret\retFlow.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\ret\retFwd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\ret\retInit.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\opt\ret\retInt.h
+# End Source File
+# End Group
# End Group
# Begin Group "map"
@@ -2300,14 +2276,6 @@ SOURCE=.\src\temp\aig\aigTable.c
SOURCE=.\src\temp\aig\aigUtil.c
# End Source File
-# Begin Source File
-
-SOURCE=.\src\temp\aig\cudd2.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\src\temp\aig\cudd2.h
-# End Source File
# End Group
# End Group
# End Group
diff --git a/abc.rc b/abc.rc
index f31053ed..56c8bf31 100644
--- a/abc.rc
+++ b/abc.rc
@@ -1,7 +1,7 @@
# global parameters
-#set check # checks intermediate networks
+set check # checks intermediate networks
#set checkfio # prints warnings when fanins/fanouts are duplicated
-#set checkread # checks new networks after reading from file
+set checkread # checks new networks after reading from file
set backup # saves backup networks retrived by "undo" and "recall"
set savesteps 1 # sets the maximum number of backup networks to save
set progressbar # display the progress bar
@@ -61,6 +61,7 @@ alias rez restructure -z
alias rs resub
alias rsz resub -z
alias sa set autoexec ps
+alias scl scleanup
alias so source -x
alias st strash
alias sw sweep
@@ -100,7 +101,7 @@ alias compress2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l;
# temporaries
#alias test "rvl th/lib.v; rvv th/t2.v"
#alias test "so c/pure_sat/test.c"
-alias test "r c/14/csat_998.bench; st; ps"
+#alias test "r c/14/csat_998.bench; st; ps"
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index 149748fc..33345577 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -529,6 +529,8 @@ extern void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj );
extern Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
extern Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
extern Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk );
+extern Vec_Ptr_t * Abc_NtkDfsSeq( Abc_Ntk_t * pNtk );
+extern Vec_Ptr_t * Abc_NtkDfsSeqReverse( Abc_Ntk_t * pNtk );
extern bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_NtkSupport( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
@@ -570,7 +572,8 @@ extern int Abc_NtkLogicToAig( Abc_Ntk_t * pNtk );
extern bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch );
extern int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk );
extern int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk );
-/*=== abcLib.c ==========================================================*/
+extern Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk );
+ /*=== abcLib.c ==========================================================*/
extern Abc_Lib_t * Abc_LibCreate( char * pName );
extern void Abc_LibFree( Abc_Lib_t * pLib );
extern Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib );
@@ -595,7 +598,7 @@ extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj );
-extern void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj );
+extern void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes );
extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName );
extern Abc_Obj_t * Abc_NtkDupBox( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pBox, int fCopyName );
extern Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pNode );
@@ -604,14 +607,14 @@ extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindCi( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName );
-extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk );
-extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk );
-extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
-extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
-extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
-extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
-extern Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
-extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
+extern Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk );
+extern Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk );
+extern Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
+extern Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
+extern Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
+extern Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
+extern Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
+extern Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
extern bool Abc_NodeIsConst( Abc_Obj_t * pNode );
extern bool Abc_NodeIsConst0( Abc_Obj_t * pNode );
extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode );
@@ -673,9 +676,11 @@ extern void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, in
extern void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames );
extern void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes );
extern void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode );
-extern void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll);
+extern void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll );
+extern void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj );
/*=== abcProve.c ==========================================================*/
extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pParams );
+extern int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars );
/*=== abcReconv.c ==========================================================*/
extern Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop );
extern void Abc_NtkManCutStop( Abc_ManCut_t * p );
@@ -751,7 +756,7 @@ extern Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels );
/*=== abcSweep.c ==========================================================*/
extern int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose );
extern int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose );
-extern int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes );
+extern int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fVerbose );
/*=== abcTiming.c ==========================================================*/
extern Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode );
extern Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode );
@@ -809,6 +814,7 @@ extern Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_NtkCollectObjects( Abc_Ntk_t * pNtk );
extern Vec_Int_t * Abc_NtkGetCiIds( Abc_Ntk_t * pNtk );
extern void Abc_NtkReassignIds( Abc_Ntk_t * pNtk );
+extern int Abc_ObjPointerCompare( void ** pp1, void ** pp2 );
/*=== abcVerify.c ==========================================================*/
extern int * Abc_NtkVerifyGetCleanModel( Abc_Ntk_t * pNtk, int nFrames );
extern int * Abc_NtkVerifySimulatePattern( Abc_Ntk_t * pNtk, int * pModel );
diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c
index 118ea291..d0c1deef 100644
--- a/src/base/abc/abcCheck.c
+++ b/src/base/abc/abcCheck.c
@@ -167,13 +167,8 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
}
// check the nodes
- if ( Abc_NtkHasAig(pNtk) )
- {
- if ( Abc_NtkIsStrash(pNtk) )
- Abc_AigCheck( pNtk->pManFunc );
- else
- Abc_NtkSeqCheck( pNtk );
- }
+ if ( Abc_NtkIsStrash(pNtk) )
+ Abc_AigCheck( pNtk->pManFunc );
else
{
Abc_NtkForEachNode( pNtk, pNode, i )
@@ -240,9 +235,10 @@ bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
Vec_Int_t * vNameIds;
char * pName;
int i, NameId;
-
+/*
if ( Abc_NtkIsNetlist(pNtk) )
{
+
// check that each net has a name
Abc_NtkForEachNet( pNtk, pObj, i )
{
@@ -254,6 +250,7 @@ bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
}
}
else
+*/
{
// check that each CI/CO has a name
Abc_NtkForEachCi( pNtk, pObj, i )
diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c
index 54676e9d..d9985737 100644
--- a/src/base/abc/abcDfs.c
+++ b/src/base/abc/abcDfs.c
@@ -209,6 +209,118 @@ void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
/**Function*************************************************************
+ Synopsis [Performs DFS for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkDfsSeq_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ // if this node is already visited, skip
+ if ( Abc_NodeIsTravIdCurrent( pNode ) )
+ return;
+ // mark the node as visited
+ Abc_NodeSetTravIdCurrent( pNode );
+ // visit the transitive fanin of the node
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ Abc_NtkDfsSeq_rec( pFanin, vNodes );
+ // add the node after the fanins have been added
+ Vec_PtrPush( vNodes, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the array of nodes and latches reachable from POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkDfsSeq( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pObj;
+ int i;
+ assert( !Abc_NtkIsNetlist(pNtk) );
+ // set the traversal ID
+ Abc_NtkIncrementTravId( pNtk );
+ // start the array of nodes
+ vNodes = Vec_PtrAlloc( 100 );
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Abc_NtkDfsSeq_rec( pObj, vNodes );
+ // mark the PIs
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NtkDfsSeq_rec( pObj, vNodes );
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs DFS for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkDfsSeqReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
+{
+ Abc_Obj_t * pFanout;
+ int i;
+ // if this node is already visited, skip
+ if ( Abc_NodeIsTravIdCurrent( pNode ) )
+ return;
+ // mark the node as visited
+ Abc_NodeSetTravIdCurrent( pNode );
+ // visit the transitive fanin of the node
+ Abc_ObjForEachFanout( pNode, pFanout, i )
+ Abc_NtkDfsSeqReverse_rec( pFanout, vNodes );
+ // add the node after the fanins have been added
+ Vec_PtrPush( vNodes, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the array of nodes and latches reachable from POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkDfsSeqReverse( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pObj;
+ int i;
+ assert( !Abc_NtkIsNetlist(pNtk) );
+ // set the traversal ID
+ Abc_NtkIncrementTravId( pNtk );
+ // start the array of nodes
+ vNodes = Vec_PtrAlloc( 100 );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NtkDfsSeqReverse_rec( pObj, vNodes );
+ // mark the logic feeding into POs
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Abc_NtkDfsSeq_rec( pObj, vNodes );
+ return vNodes;
+}
+
+/**Function*************************************************************
+
Synopsis [Returns 1 if the ordering of nodes is DFS.]
Description []
@@ -611,9 +723,9 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
Abc_Obj_t * pFanin;
int fAcyclic, i;
assert( !Abc_ObjIsNet(pNode) );
- if ( Abc_ObjIsCi(pNode) || Abc_ObjIsBox(pNode) )
+ if ( Abc_ObjIsCi(pNode) || Abc_ObjIsBox(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
return 1;
- assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
+ assert( Abc_ObjIsNode(pNode) );
// make sure the node is not visited
assert( !Abc_NodeIsTravIdPrevious(pNode) );
// check if the node is part of the combinational loop
diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c
index 8e78ae61..0581b35d 100644
--- a/src/base/abc/abcFanio.c
+++ b/src/base/abc/abcFanio.c
@@ -223,8 +223,8 @@ void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo )
int nFanoutsOld, i;
assert( !Abc_ObjIsComplement(pNodeFrom) );
assert( !Abc_ObjIsComplement(pNodeTo) );
- assert( Abc_ObjIsNode(pNodeFrom) );
- assert( Abc_ObjIsNode(pNodeTo) );
+ assert( Abc_ObjIsNode(pNodeFrom) || Abc_ObjIsCi(pNodeFrom) );
+ assert( !Abc_ObjIsPo(pNodeTo) );
assert( pNodeFrom->pNtk == pNodeTo->pNtk );
assert( pNodeFrom != pNodeTo );
assert( Abc_ObjFanoutNum(pNodeFrom) > 0 );
@@ -255,12 +255,9 @@ void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew )
{
assert( !Abc_ObjIsComplement(pNodeOld) );
assert( !Abc_ObjIsComplement(pNodeNew) );
- assert( Abc_ObjIsNode(pNodeOld) );
- assert( Abc_ObjIsNode(pNodeNew) );
assert( pNodeOld->pNtk == pNodeNew->pNtk );
assert( pNodeOld != pNodeNew );
assert( Abc_ObjFanoutNum(pNodeOld) > 0 );
- assert( Abc_ObjFanoutNum(pNodeNew) == 0 );
// transfer the fanouts to the old node
Abc_ObjTransferFanout( pNodeOld, pNodeNew );
// remove the old node
diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c
index 8b0a1608..7bc5e264 100644
--- a/src/base/abc/abcLatch.c
+++ b/src/base/abc/abcLatch.c
@@ -48,7 +48,7 @@ bool Abc_NtkLatchIsSelfFeed_rec( Abc_Obj_t * pLatch, Abc_Obj_t * pLatchRoot )
pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
if ( !Abc_ObjIsBi(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
return 0;
- return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatch );
+ return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatchRoot );
}
/**Function*************************************************************
@@ -120,7 +120,7 @@ int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk )
if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) )
pConst1 = Abc_AigConst1(pNtk);
else
- pConst1 = Abc_NodeCreateConst1(pNtk);
+ pConst1 = Abc_NtkCreateNodeConst1(pNtk);
Abc_ObjPatchFanin( pLatch, Abc_ObjFanin0(Abc_ObjFanin0(pLatch)), pConst1 );
Counter++;
}
@@ -170,6 +170,28 @@ void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches )
Abc_NtkLogicMakeSimpleCos( pNtk, 0 );
}
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node using its SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk )
+{
+ Vec_Int_t * vArray;
+ Abc_Obj_t * pLatch;
+ int i;
+ vArray = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) );
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ Vec_IntPush( vArray, Abc_LatchIsInit1(pLatch) );
+ return vArray;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c
index f71093ef..30fab9a3 100644
--- a/src/base/abc/abcNetlist.c
+++ b/src/base/abc/abcNetlist.c
@@ -253,9 +253,12 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk, int fDirect )
}
else if ( Abc_NtkIsSeq(pNtk) )
{
+ assert( 0 );
+/*
pNtkTemp = Abc_NtkSeqToLogicSop(pNtk);
pNtkNew = Abc_NtkLogicSopToNetlist( pNtkTemp );
Abc_NtkDelete( pNtkTemp );
+*/
}
else if ( Abc_NtkIsBddLogic(pNtk) )
{
@@ -416,7 +419,7 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk )
// if the constant node is used, duplicate it
pObj = Abc_AigConst1(pNtk);
if ( Abc_ObjFanoutNum(pObj) > 0 )
- pObj->pCopy = Abc_NodeCreateConst1(pNtkNew);
+ pObj->pCopy = Abc_NtkCreateNodeConst1(pNtkNew);
// duplicate the nodes and create node functions
Abc_NtkForEachNode( pNtk, pObj, i )
{
@@ -505,19 +508,19 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk )
pObj = Abc_AigConst1(pNtk);
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
{
- pObj->pCopy = Abc_NodeCreateConst1(pNtkNew);
- pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
+ pObj->pCopy = Abc_NtkCreateNodeConst1(pNtkNew);
+ pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
}
Abc_NtkForEachCi( pNtk, pObj, i )
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
- pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
+ pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
// duplicate the nodes, create node functions, and inverters
Vec_PtrForEachEntry( vNodes, pObj, i )
{
Abc_NtkDupObj( pNtkNew, pObj, 0 );
pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2, NULL );
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
- pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
+ pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
}
// connect the objects
Vec_PtrForEachEntry( vNodes, pObj, i )
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index c99be016..96f489bd 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -69,8 +69,8 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan
// start the functionality manager
if ( Abc_NtkIsStrash(pNtk) )
pNtk->pManFunc = Abc_AigAlloc( pNtk );
- else if ( Abc_NtkIsSeq(pNtk) )
- pNtk->pManFunc = Seq_Create( pNtk );
+// else if ( Abc_NtkIsSeq(pNtk) )
+// pNtk->pManFunc = Seq_Create( pNtk );
else if ( Abc_NtkHasSop(pNtk) )
pNtk->pManFunc = Extra_MmFlexStart();
else if ( Abc_NtkHasBdd(pNtk) )
@@ -301,6 +301,7 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
printf( "Warning: Structural hashing during duplication reduced %d nodes (this is a minor bug).\n",
Abc_NtkNodeNum(pNtk) - Abc_NtkNodeNum(pNtkNew) );
}
+/*
else if ( Abc_NtkIsSeq(pNtk) )
{
// start the storage for initial states
@@ -333,6 +334,7 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
Vec_PtrPush( pNtkNew->vCutSet, pObj->pCopy );
}
+*/
else
{
// duplicate the nets and nodes (CIs/COs/latches already dupped)
@@ -355,6 +357,65 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
/**Function*************************************************************
+ Synopsis [Attaches the second network at the bottom of the first.]
+
+ Description [Returns the first network. Deletes the second network.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkAttachBottom( Abc_Ntk_t * pNtkTop, Abc_Ntk_t * pNtkBottom )
+{
+ Abc_Obj_t * pObj, * pFanin, * pBuffer;
+ Vec_Ptr_t * vNodes;
+ int i, k;
+ assert( pNtkBottom != NULL );
+ if ( pNtkTop == NULL )
+ return pNtkBottom;
+ // make sure the networks are combinational
+ assert( Abc_NtkPiNum(pNtkTop) == Abc_NtkCiNum(pNtkTop) );
+ assert( Abc_NtkPiNum(pNtkBottom) == Abc_NtkCiNum(pNtkBottom) );
+ // make sure the POs of the bottom correspond to the PIs of the top
+ assert( Abc_NtkPoNum(pNtkBottom) == Abc_NtkPiNum(pNtkTop) );
+ assert( Abc_NtkPiNum(pNtkBottom) < Abc_NtkPiNum(pNtkTop) );
+ // add buffers for the PIs of the top - save results in the POs of the bottom
+ Abc_NtkForEachPi( pNtkTop, pObj, i )
+ {
+ pBuffer = Abc_NtkCreateNodeBuf( pNtkTop, NULL );
+ Abc_ObjTransferFanout( pObj, pBuffer );
+ Abc_NtkPo(pNtkBottom, i)->pCopy = pBuffer;
+ }
+ // remove useless PIs of the top
+ for ( i = Abc_NtkPiNum(pNtkTop) - 1; i >= Abc_NtkPiNum(pNtkBottom); i-- )
+ Abc_NtkDeleteObj( Abc_NtkPi(pNtkTop, i) );
+ assert( Abc_NtkPiNum(pNtkBottom) == Abc_NtkPiNum(pNtkTop) );
+ // copy the bottom network
+ Abc_NtkForEachPi( pNtkBottom, pObj, i )
+ Abc_NtkPi(pNtkBottom, i)->pCopy = Abc_NtkPi(pNtkTop, i);
+ // construct all nodes
+ vNodes = Abc_NtkDfs( pNtkBottom, 0 );
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ Abc_NtkDupObj(pNtkTop, pObj, 0);
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
+ }
+ Vec_PtrFree( vNodes );
+ // connect the POs
+ Abc_NtkForEachPo( pNtkBottom, pObj, i )
+ Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
+ // delete old network
+ Abc_NtkDelete( pNtkBottom );
+ // return the network
+ if ( !Abc_NtkCheck( pNtkTop ) )
+ fprintf( stdout, "Abc_NtkAttachBottom(): Network check has failed.\n" );
+ return pNtkTop;
+}
+
+/**Function*************************************************************
+
Synopsis [Creates the network composed of one logic cone.]
Description []
@@ -720,8 +781,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
// start the functionality manager
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigFree( pNtk->pManFunc );
- else if ( Abc_NtkIsSeq(pNtk) )
- Seq_Delete( pNtk->pManFunc );
+// else if ( Abc_NtkIsSeq(pNtk) )
+// Seq_Delete( pNtk->pManFunc );
else if ( Abc_NtkHasSop(pNtk) )
Extra_MmFlexStop( pNtk->pManFunc, 0 );
else if ( Abc_NtkHasBdd(pNtk) )
@@ -777,7 +838,7 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
if ( Abc_ObjFaninNum(pNet) > 0 )
continue;
// add the constant 0 driver
- pNode = Abc_NodeCreateConst0( pNtk );
+ pNode = Abc_NtkCreateNodeConst0( pNtk );
// add the fanout net
Abc_ObjAddFanin( pNet, pNode );
// add the net to those for which the warning will be printed
diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c
index 68bbdb40..ca86565a 100644
--- a/src/base/abc/abcObj.c
+++ b/src/base/abc/abcObj.c
@@ -129,10 +129,10 @@ Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
Vec_PtrPush( pNtk->vCos, pObj );
break;
case ABC_OBJ_BI:
- Vec_PtrPush( pNtk->vCis, pObj );
+ if ( pNtk->vCis ) Vec_PtrPush( pNtk->vCis, pObj );
break;
case ABC_OBJ_BO:
- Vec_PtrPush( pNtk->vCos, pObj );
+ if ( pNtk->vCos ) Vec_PtrPush( pNtk->vCos, pObj );
break;
case ABC_OBJ_ASSERT:
Vec_PtrPush( pNtk->vAsserts, pObj );
@@ -146,7 +146,7 @@ Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
pObj->pData = (void *)ABC_INIT_NONE;
case ABC_OBJ_TRI:
case ABC_OBJ_BLACKBOX:
- Vec_PtrPush( pNtk->vBoxes, pObj );
+ if ( pNtk->vBoxes ) Vec_PtrPush( pNtk->vBoxes, pObj );
break;
default:
assert(0);
@@ -171,6 +171,9 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
Abc_Ntk_t * pNtk = pObj->pNtk;
Vec_Ptr_t * vNodes;
int i;
+ // remove from the table of names
+ if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) )
+ Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id);
// delete fanins and fanouts
assert( !Abc_ObjIsComplement(pObj) );
vNodes = Vec_PtrAlloc( 100 );
@@ -186,9 +189,6 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
pObj->Id = (1<<26)-1;
pNtk->nObjCounts[pObj->Type]--;
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
switch (pObj->Type)
{
@@ -210,10 +210,10 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
Vec_PtrRemove( pNtk->vCos, pObj );
break;
case ABC_OBJ_BI:
- Vec_PtrRemove( pNtk->vCis, pObj );
+ if ( pNtk->vCis ) Vec_PtrRemove( pNtk->vCis, pObj );
break;
case ABC_OBJ_BO:
- Vec_PtrRemove( pNtk->vCos, pObj );
+ if ( pNtk->vCos ) Vec_PtrRemove( pNtk->vCos, pObj );
break;
case ABC_OBJ_ASSERT:
Vec_PtrRemove( pNtk->vAsserts, pObj );
@@ -230,7 +230,7 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
case ABC_OBJ_LATCH:
case ABC_OBJ_TRI:
case ABC_OBJ_BLACKBOX:
- Vec_PtrRemove( pNtk->vBoxes, pObj );
+ if ( pNtk->vBoxes ) Vec_PtrRemove( pNtk->vBoxes, pObj );
break;
default:
assert(0);
@@ -251,20 +251,30 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
SeeAlso []
***********************************************************************/
-void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj )
+void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes )
{
Abc_Ntk_t * pNtk = pObj->pNtk;
Vec_Ptr_t * vNodes;
int i;
assert( !Abc_ObjIsComplement(pObj) );
+ assert( !Abc_ObjIsPi(pObj) );
assert( Abc_ObjFanoutNum(pObj) == 0 );
// delete fanins and fanouts
vNodes = Vec_PtrAlloc( 100 );
Abc_NodeCollectFanins( pObj, vNodes );
Abc_NtkDeleteObj( pObj );
- Vec_PtrForEachEntry( vNodes, pObj, i )
- if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
- Abc_NtkDeleteObj_rec( pObj );
+ if ( fOnlyNodes )
+ {
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
+ Abc_NtkDeleteObj_rec( pObj, fOnlyNodes );
+ }
+ else
+ {
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ if ( !Abc_ObjIsPi(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
+ Abc_NtkDeleteObj_rec( pObj, fOnlyNodes );
+ }
Vec_PtrFree( vNodes );
}
@@ -530,7 +540,7 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
+Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
@@ -559,7 +569,7 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
+Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
@@ -588,12 +598,12 @@ Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
+Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
- Abc_ObjAddFanin( pNode, pFanin );
+ if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin );
if ( Abc_NtkHasSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 1\n" );
else if ( Abc_NtkHasBdd(pNtk) )
@@ -618,12 +628,12 @@ Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
+Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
- pNode = Abc_NtkCreateNode( pNtk );
- Abc_ObjAddFanin( pNode, pFanin );
+ pNode = Abc_NtkCreateNode( pNtk );
+ if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin );
if ( Abc_NtkHasSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" );
else if ( Abc_NtkHasBdd(pNtk) )
@@ -648,7 +658,7 @@ Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
+Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
{
Abc_Obj_t * pNode;
int i;
@@ -678,7 +688,7 @@ Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
+Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
{
Abc_Obj_t * pNode;
int i;
@@ -708,7 +718,7 @@ Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
+Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
{
Abc_Obj_t * pNode;
int i;
@@ -738,7 +748,7 @@ Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 )
+Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) );
@@ -772,8 +782,7 @@ Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t *
bool Abc_NodeIsConst( Abc_Obj_t * pNode )
{
assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) );
- assert( Abc_ObjIsNode(pNode) );
- return Abc_ObjFaninNum(pNode) == 0;
+ return Abc_ObjIsNode(pNode) && Abc_ObjFaninNum(pNode) == 0;
}
/**Function*************************************************************
diff --git a/src/base/abc/abcRefs.c b/src/base/abc/abcRefs.c
index ea076e47..bc9c316f 100644
--- a/src/base/abc/abcRefs.c
+++ b/src/base/abc/abcRefs.c
@@ -316,12 +316,18 @@ void Abc_NodeMffsConeSupp( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSu
void Abc_NodeMffsConeSuppPrint( Abc_Obj_t * pNode )
{
Vec_Ptr_t * vCone, * vSupp;
+ Abc_Obj_t * pObj;
+ int i;
vCone = Vec_PtrAlloc( 100 );
vSupp = Vec_PtrAlloc( 100 );
Abc_NodeDeref_rec( pNode );
Abc_NodeMffsConeSupp( pNode, vCone, vSupp );
Abc_NodeRef_rec( pNode );
- printf( "Cone = %6d. Supp = %6d. \n", Vec_PtrSize(vCone), Vec_PtrSize(vSupp) );
+ printf( "Node = %6s : Supp = %3d Cone = %3d (",
+ Abc_ObjName(pNode), Vec_PtrSize(vSupp), Vec_PtrSize(vCone) );
+ Vec_PtrForEachEntry( vCone, pObj, i )
+ printf( " %s", Abc_ObjName(pObj) );
+ printf( " )\n" );
Vec_PtrFree( vCone );
Vec_PtrFree( vSupp );
}
diff --git a/src/base/abc/abcShow.c b/src/base/abc/abcShow.c
index bb0606f7..8ed653a9 100644
--- a/src/base/abc/abcShow.c
+++ b/src/base/abc/abcShow.c
@@ -88,7 +88,7 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
-void Abc_NtkShowAig( Abc_Ntk_t * pNtk )
+void Abc_NtkShowAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesShow )
{
FILE * pFile;
Abc_Obj_t * pNode;
@@ -96,7 +96,7 @@ void Abc_NtkShowAig( Abc_Ntk_t * pNtk )
char FileNameDot[200];
int i;
- assert( Abc_NtkHasAig(pNtk) );
+ assert( Abc_NtkIsStrash(pNtk) );
// create the file name
Abc_ShowGetFileName( pNtk->pName, FileNameDot );
// check that the file can be opened
@@ -112,7 +112,7 @@ void Abc_NtkShowAig( Abc_Ntk_t * pNtk )
Abc_NtkForEachObj( pNtk, pNode, i )
Vec_PtrPush( vNodes, pNode );
// write the DOT file
- Io_WriteDotAig( pNtk, vNodes, NULL, FileNameDot, 0 );
+ Io_WriteDotAig( pNtk, vNodes, vNodesShow, FileNameDot, 0 );
Vec_PtrFree( vNodes );
// visualize the file
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index 6e506b0e..d5a4b5cb 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -81,6 +81,17 @@ void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk )
Vec_PtrPush( pNtk->vCos, pObj );
Abc_NtkForEachBox( pNtk, pObj, i )
{
+ if ( Abc_ObjIsLatch(pObj) )
+ continue;
+ Abc_ObjForEachFanin( pObj, pTerm, k )
+ Vec_PtrPush( pNtk->vCos, pTerm );
+ Abc_ObjForEachFanout( pObj, pTerm, k )
+ Vec_PtrPush( pNtk->vCis, pTerm );
+ }
+ Abc_NtkForEachBox( pNtk, pObj, i )
+ {
+ if ( !Abc_ObjIsLatch(pObj) )
+ continue;
Abc_ObjForEachFanin( pObj, pTerm, k )
Vec_PtrPush( pNtk->vCos, pTerm );
Abc_ObjForEachFanout( pObj, pTerm, k )
@@ -545,11 +556,11 @@ void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fD
// add inverters and buffers when necessary
if ( Abc_ObjFaninC0(pNodeCo) )
{
- pDriverNew = Abc_NodeCreateInv( pNtk, pDriver );
+ pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
Abc_ObjXorFaninC( pNodeCo, 0 );
}
else
- pDriverNew = Abc_NodeCreateBuf( pNtk, pDriver );
+ pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
}
// update the fanin of the PO node
Abc_ObjPatchFanin( pNodeCo, pDriver, pDriverNew );
@@ -925,13 +936,14 @@ int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc
}
else
fclose( pFile );
-
+/*
if ( Abc_NtkIsSeq(pNtk) )
{
pNtk1 = Abc_NtkSeqToLogicSop(pNtk);
*pfDelete1 = 1;
}
else
+*/
pNtk1 = pNtk;
pNtk2 = Io_Read( pNtk->pSpec, fCheck );
if ( pNtk2 == NULL )
@@ -945,12 +957,14 @@ int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc
fprintf( pErr, "Empty current network.\n" );
return 0;
}
+/*
if ( Abc_NtkIsSeq(pNtk) )
{
pNtk1 = Abc_NtkSeqToLogicSop(pNtk);
*pfDelete1 = 1;
}
else
+*/
pNtk1 = pNtk;
pNtk2 = Io_Read( argv[util_optind], fCheck );
if ( pNtk2 == NULL )
@@ -1265,6 +1279,26 @@ void Abc_NtkDetectMatching( Abc_Ntk_t * pNtk )
}
+/**Function*************************************************************
+
+ Synopsis [Compares the pointers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_ObjPointerCompare( void ** pp1, void ** pp2 )
+{
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 )
+ return 1;
+ return 0;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index b25ca2f7..5d6af56d 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -36,6 +36,7 @@ static int Abc_CommandPrintExdc ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandPrintIo ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintLatch ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintFanio ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintMffc ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -90,6 +91,7 @@ static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** arg
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_CommandXsim ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIStrash ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -102,6 +104,7 @@ static int Abc_CommandIFraig ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandBmc ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -166,6 +169,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Printing", "print_io", Abc_CommandPrintIo, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_latch", Abc_CommandPrintLatch, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_fanio", Abc_CommandPrintFanio, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_mffc", Abc_CommandPrintMffc, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 );
@@ -220,6 +224,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
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", "xsim", Abc_CommandXsim, 0 );
Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 );
Cmd_CommandAdd( pAbc, "New AIG", "istrash", Abc_CommandIStrash, 1 );
@@ -232,6 +237,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "New AIG", "iprove", Abc_CommandIProve, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "haig", Abc_CommandHaig, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "mini", Abc_CommandMini, 1 );
+ Cmd_CommandAdd( pAbc, "New AIG", "bmc", Abc_CommandBmc, 0 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 );
@@ -250,15 +256,15 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "FPGA mapping", "ffpga", Abc_CommandFpgaFast, 1 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "pga", Abc_CommandPga, 1 );
- Cmd_CommandAdd( pAbc, "Sequential", "scut", Abc_CommandScut, 0 );
- Cmd_CommandAdd( pAbc, "Sequential", "init", Abc_CommandInit, 1 );
- Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 );
- Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
- Cmd_CommandAdd( pAbc, "Sequential", "unseq", Abc_CommandUnseq, 1 );
+// Cmd_CommandAdd( pAbc, "Sequential", "scut", Abc_CommandScut, 0 );
+// Cmd_CommandAdd( pAbc, "Sequential", "init", Abc_CommandInit, 1 );
+// Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 );
+// Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
+// Cmd_CommandAdd( pAbc, "Sequential", "unseq", Abc_CommandUnseq, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 );
- Cmd_CommandAdd( pAbc, "Sequential", "sfpga", Abc_CommandSeqFpga, 1 );
- Cmd_CommandAdd( pAbc, "Sequential", "smap", Abc_CommandSeqMap, 1 );
- Cmd_CommandAdd( pAbc, "Sequential", "ssweep", Abc_CommandSeqSweep, 1 );
+// Cmd_CommandAdd( pAbc, "Sequential", "sfpga", Abc_CommandSeqFpga, 1 );
+// Cmd_CommandAdd( pAbc, "Sequential", "smap", Abc_CommandSeqMap, 1 );
+// Cmd_CommandAdd( pAbc, "Sequential", "ssweep", Abc_CommandSeqSweep, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "scleanup", Abc_CommandSeqCleanup, 1 );
Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
@@ -269,8 +275,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
// Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 );
// Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 );
- Cmd_CommandAdd( pAbc, "Sequential", "howard", Abc_CommandHoward, 0 );
- Cmd_CommandAdd( pAbc, "Sequential", "skew_fwd", Abc_CommandSkewForward, 0 );
+// Cmd_CommandAdd( pAbc, "Sequential", "howard", Abc_CommandHoward, 0 );
+// Cmd_CommandAdd( pAbc, "Sequential", "skew_fwd", Abc_CommandSkewForward, 0 );
// Rwt_Man4ExploreStart();
// Map_Var3Print();
@@ -629,6 +635,58 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandPrintMffc( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ extern void Abc_NtkPrintMffc( FILE * pFile, Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // print the nodes
+ Abc_NtkPrintMffc( pOut, pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_mffc [-h]\n" );
+ fprintf( pErr, "\t prints the MFFC of each node in the network\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandPrintFactor( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
@@ -1581,7 +1639,7 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtk;
int c;
int fMulti;
- extern void Abc_NtkShowAig( Abc_Ntk_t * pNtk );
+ extern void Abc_NtkShowAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesShow );
extern void Abc_NtkShowMulti( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
@@ -1609,7 +1667,7 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
- if ( !Abc_NtkHasAig(pNtk) )
+ if ( !Abc_NtkIsStrash(pNtk) )
{
fprintf( pErr, "Visualizing networks other than AIGs can be done using command \"show_ntk\".\n" );
return 1;
@@ -1622,7 +1680,7 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( !fMulti )
- Abc_NtkShowAig( pNtk );
+ Abc_NtkShowAig( pNtk, NULL );
else
Abc_NtkShowMulti( pNtk );
return 0;
@@ -1683,7 +1741,7 @@ int Abc_CommandShowNtk( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
- if ( Abc_NtkHasAig(pNtk) )
+ if ( Abc_NtkIsStrash(pNtk) )
{
fprintf( pErr, "Visualizing AIG can only be done using command \"show_aig\".\n" );
return 1;
@@ -4975,14 +5033,97 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int nFrames;
+ int fInputs;
+ int fVerbose;
+ extern void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nFrames = 10;
+ fInputs = 0;
+ fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Fivh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'F':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nFrames = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nFrames < 0 )
+ goto usage;
+ break;
+ case 'i':
+ fInputs ^= 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;
+ }
+
+ Abc_NtkXValueSimulate( pNtk, nFrames, fInputs, fVerbose );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: xsim [-F num] [-ivh]\n" );
+ fprintf( pErr, "\t performs X-valued simulation of the AIG\n" );
+ fprintf( pErr, "\t-F num : the number of frames to simulate [default = %d]\n", nFrames );
+ fprintf( pErr, "\t-i : toggle X-valued state or X-valued inputs [default = %s]\n", fInputs? "inputs": "state" );
+ 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 );
+// extern Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk );
+ extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
@@ -5064,7 +5205,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
// Ivy_TruthEstimateNodesTest();
-
+/*
pNtkRes = Abc_NtkIvy( pNtk );
// pNtkRes = Abc_NtkPlayer( pNtk, nLevels, 0 );
// pNtkRes = NULL;
@@ -5075,7 +5216,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
-
+*/
+ Abc_NtkMaxFlowTest( pNtk );
return 0;
usage:
@@ -5100,7 +5242,7 @@ usage:
int Abc_CommandIStrash( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
- Abc_Ntk_t * pNtk, * pNtkRes;
+ Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp;
int c;
extern Abc_Ntk_t * Abc_NtkIvyStrash( Abc_Ntk_t * pNtk );
@@ -5132,11 +5274,12 @@ int Abc_CommandIStrash( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( !Abc_NtkIsStrash(pNtk) )
{
- fprintf( pErr, "Only works for combinatinally strashed AIG networks.\n" );
- return 1;
+ pNtkTemp = Abc_NtkStrash( pNtk, 0, 1 );
+ pNtkRes = Abc_NtkIvyStrash( pNtkTemp );
+ Abc_NtkDelete( pNtkTemp );
}
-
- pNtkRes = Abc_NtkIvyStrash( pNtk );
+ else
+ pNtkRes = Abc_NtkIvyStrash( pNtk );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Command has failed.\n" );
@@ -5741,9 +5884,9 @@ int Abc_CommandHaig( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
- nIters = 3;
- fUseZeroCost = 1;
- fVerbose = 0;
+ nIters = 2;
+ fUseZeroCost = 0;
+ fVerbose = 1;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Izvh" ) ) != EOF )
{
@@ -5869,6 +6012,94 @@ usage:
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandBmc( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int nFrames;
+ int fInit;
+ int fVerbose;
+
+ extern void Abc_NtkBmc( Abc_Ntk_t * pNtk, int nFrames, int fInit, int fVerbose );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nFrames = 5;
+ fInit = 0;
+ fVerbose = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Kivh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nFrames = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nFrames < 0 )
+ goto usage;
+ break;
+ case 'i':
+ fInit ^= 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_NtkIsSeq(pNtk) )
+ {
+ fprintf( pErr, "Only works for non-sequential networks.\n" );
+ return 1;
+ }
+ if ( Abc_NtkIsStrash(pNtk) )
+ Abc_NtkBmc( pNtk, nFrames, fInit, fVerbose );
+ else
+ {
+ pNtk = Abc_NtkStrash( pNtk, 0, 1 );
+ Abc_NtkBmc( pNtk, nFrames, fInit, fVerbose );
+ Abc_NtkDelete( pNtk );
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: bmc [-K num] [-ivh]\n" );
+ fprintf( pErr, "\t perform bounded model checking\n" );
+ fprintf( pErr, "\t-K num : number of time frames [default = %d]\n", nFrames );
+ fprintf( pErr, "\t-i : toggle initialization of the first frame [default = %s]\n", fInit? "yes": "no" );
+ fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
/**Function*************************************************************
@@ -7573,48 +7804,38 @@ usage:
int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
- Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp;
+ Abc_Ntk_t * pNtk, * pNtkTemp;
int c, nMaxIters;
- int fForward;
- int fBackward;
int fInitial;
int fVerbose;
+ int Mode;
+ extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
- fForward = 0;
- fBackward = 0;
+ Mode = 3;
fInitial = 1;
- fVerbose = 0;
+ fVerbose = 1;
nMaxIters = 15;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Ifbivh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Mvh" ) ) != EOF )
{
switch ( c )
{
- case 'I':
+ case 'M':
if ( globalUtilOptind >= argc )
{
- fprintf( pErr, "Command line switch \"-I\" should be followed by a positive integer.\n" );
+ fprintf( pErr, "Command line switch \"-M\" should be followed by a positive integer.\n" );
goto usage;
}
- nMaxIters = atoi(argv[globalUtilOptind]);
+ Mode = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
- if ( nMaxIters < 0 )
+ if ( Mode < 0 )
goto usage;
break;
- case 'f':
- fForward ^= 1;
- break;
- case 'b':
- fBackward ^= 1;
- break;
- case 'i':
- fInitial ^= 1;
- break;
case 'v':
fVerbose ^= 1;
break;
@@ -7631,61 +7852,56 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
- if ( !Abc_NtkIsSeq(pNtk) && Abc_NtkLatchNum(pNtk) == 0 )
+ if ( !Abc_NtkLatchNum(pNtk) )
{
fprintf( pErr, "The network has no latches. Retiming is not performed.\n" );
return 0;
}
- if ( Abc_NtkHasAig(pNtk) )
+ if ( Abc_NtkIsStrash(pNtk) )
{
- // quit if there are choice nodes
if ( Abc_NtkGetChoiceNum(pNtk) )
{
- fprintf( pErr, "Currently cannot retime networks with choice nodes.\n" );
+ fprintf( pErr, "Retiming with choice nodes is not implemented.\n" );
return 0;
}
- if ( Abc_NtkIsStrash(pNtk) )
- pNtkRes = Abc_NtkAigToSeq(pNtk);
- else
- pNtkRes = Abc_NtkDup(pNtk);
- // retime the network
- if ( fForward )
- Seq_NtkSeqRetimeForward( pNtkRes, fInitial, fVerbose );
- else if ( fBackward )
- Seq_NtkSeqRetimeBackward( pNtkRes, fInitial, fVerbose );
- else
- Seq_NtkSeqRetimeDelay( pNtkRes, nMaxIters, fInitial, fVerbose );
- // if the network is an AIG, convert the result into an AIG
- if ( Abc_NtkIsStrash(pNtk) )
- {
- pNtkRes = Abc_NtkSeqToLogicSop( pNtkTemp = pNtkRes );
- Abc_NtkDelete( pNtkTemp );
- pNtkRes = Abc_NtkStrash( pNtkTemp = pNtkRes, 0, 0 );
- Abc_NtkDelete( pNtkTemp );
- }
+ pNtk = Abc_NtkAigToLogicSop( pNtkTemp = pNtk );
+ Abc_NtkDelete( pNtkTemp );
}
- else
- pNtkRes = Seq_NtkRetime( pNtk, nMaxIters, fInitial, fVerbose );
- // replace the network
- if ( pNtkRes == NULL )
+
+ // get the network in the SOP form
+ if ( !Abc_NtkLogicToSop(pNtk, 0) )
{
- fprintf( pErr, "Retiming has failed.\n" );
+ printf( "Converting to SOPs has failed.\n" );
return 0;
}
- // replace the current network
- Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+
+ if ( !Abc_NtkIsLogic(pNtk) )
+ {
+ fprintf( pErr, "The network is not a logic network. Retiming is not performed.\n" );
+ return 0;
+ }
+
+ // perform the retiming
+ Abc_NtkRetime( pNtk, Mode, fVerbose );
return 0;
usage:
- fprintf( pErr, "usage: retime [-I num] [-fbih]\n" );
- fprintf( pErr, "\t retimes the current network using Pan's delay-optimal retiming\n" );
- fprintf( pErr, "\t-I num : max number of iterations of l-value computation [default = %d]\n", nMaxIters );
- fprintf( pErr, "\t-f : toggle forward retiming (for AIGs) [default = %s]\n", fForward? "yes": "no" );
- fprintf( pErr, "\t-b : toggle backward retiming (for AIGs) [default = %s]\n", fBackward? "yes": "no" );
- fprintf( pErr, "\t-i : toggle computation of initial state [default = %s]\n", fInitial? "yes": "no" );
+ fprintf( pErr, "usage: retime [-M num] [-vh]\n" );
+ fprintf( pErr, "\t retimes the current network using one of the algorithms:\n" );
+ fprintf( pErr, "\t 1: most forward retiming\n" );
+ fprintf( pErr, "\t 2: most backward retiming\n" );
+ fprintf( pErr, "\t 3: min-area retiming\n" );
+ fprintf( pErr, "\t 4: min-delay retiming\n" );
+ fprintf( pErr, "\t 5: min-area under min-delay constraint retiming\n" );
+ fprintf( pErr, "\t-M num : the retiming algorithm to use [default = %d]\n", Mode );
+ fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
+// fprintf( pErr, "\t-I num : max number of iterations of l-value computation [default = %d]\n", nMaxIters );
+// fprintf( pErr, "\t-f : toggle forward retiming (for AIGs) [default = %s]\n", fForward? "yes": "no" );
+// fprintf( pErr, "\t-b : toggle backward retiming (for AIGs) [default = %s]\n", fBackward? "yes": "no" );
+// fprintf( pErr, "\t-i : toggle computation of initial state [default = %s]\n", fInitial? "yes": "no" );
}
/**Function*************************************************************
@@ -8069,17 +8285,22 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
+ int fVerbose;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
+ fVerbose = 1;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{
switch ( c )
{
+ case 'v':
+ fVerbose ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -8091,18 +8312,23 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Empty network.\n" );
return 1;
}
- if ( !Abc_NtkIsSeq(pNtk) )
+ if ( !Abc_NtkIsLogic(pNtk) )
{
- fprintf( pErr, "Only works for sequential AIGs.\n" );
+ fprintf( pErr, "Only works for logic networks.\n" );
return 1;
}
// modify the current network
- Seq_NtkCleanup( pNtk, 1 );
+ Abc_NtkCleanupSeq( pNtk, fVerbose );
return 0;
usage:
- fprintf( pErr, "usage: scleanup [-h]\n" );
+ fprintf( pErr, "usage: scleanup [-vh]\n" );
fprintf( pErr, "\t performs sequential cleanup\n" );
+ fprintf( pErr, "\t - removes nodes/latches that do not feed into POs\n" );
+ fprintf( pErr, "\t - removes and shared latches driven by constants\n" );
+ fprintf( pErr, "\t - replaces autonomous logic by free PI variables\n" );
+ fprintf( pErr, "\t (the latter may change sequential behaviour)\n" );
+ fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
diff --git a/src/base/abci/abcBmc.c b/src/base/abci/abcBmc.c
new file mode 100644
index 00000000..af6d237b
--- /dev/null
+++ b/src/base/abci/abcBmc.c
@@ -0,0 +1,115 @@
+/**CFile****************************************************************
+
+ FileName [abcBmc.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Performs bounded model check.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcBmc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "ivy.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc );
+
+static void Abc_NtkBmcReport( Ivy_Man_t * pMan, Ivy_Man_t * pFrames, Ivy_Man_t * pFraig, Vec_Ptr_t * vMapping, int nFrames );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkBmc( Abc_Ntk_t * pNtk, int nFrames, int fInit, int fVerbose )
+{
+ Ivy_FraigParams_t Params, * pParams = &Params;
+ Ivy_Man_t * pMan, * pFrames, * pFraig;
+ Vec_Ptr_t * vMapping;
+ // convert to IVY manager
+ pMan = Abc_NtkIvyBefore( pNtk, 0, 0 );
+ // generate timeframes
+ pFrames = Ivy_ManFrames( pMan, Abc_NtkLatchNum(pNtk), nFrames, fInit, &vMapping );
+ // fraig the timeframes
+ Ivy_FraigParamsDefault( pParams );
+ pParams->nBTLimitNode = ABC_INFINITY;
+ pParams->fVerbose = 0;
+ pParams->fProve = 0;
+ pFraig = Ivy_FraigPerform( pFrames, pParams );
+printf( "Frames have %6d nodes. ", Ivy_ManNodeNum(pFrames) );
+printf( "Fraig has %6d nodes.\n", Ivy_ManNodeNum(pFraig) );
+ // report the classes
+// if ( fVerbose )
+// Abc_NtkBmcReport( pMan, pFrames, pFraig, vMapping, nFrames );
+ // free stuff
+ Vec_PtrFree( vMapping );
+ Ivy_ManStop( pFraig );
+ Ivy_ManStop( pFrames );
+ Ivy_ManStop( pMan );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkBmcReport( Ivy_Man_t * pMan, Ivy_Man_t * pFrames, Ivy_Man_t * pFraig, Vec_Ptr_t * vMapping, int nFrames )
+{
+ Ivy_Obj_t * pFirst1, * pFirst2, * pFirst3;
+ int i, f, nIdMax, Prev2, Prev3;
+ nIdMax = Ivy_ManObjIdMax(pMan);
+ // check what is the number of nodes in each frame
+ Prev2 = Prev3 = 0;
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Ivy_ManForEachNode( pMan, pFirst1, i )
+ {
+ pFirst2 = Ivy_Regular( Vec_PtrEntry(vMapping, f * nIdMax + pFirst1->Id) );
+ if ( Ivy_ObjIsConst1(pFirst2) || pFirst2->Type == 0 )
+ continue;
+ pFirst3 = Ivy_Regular( pFirst2->pEquiv );
+ if ( Ivy_ObjIsConst1(pFirst3) || pFirst3->Type == 0 )
+ continue;
+ break;
+ }
+ if ( f )
+ printf( "Frame %3d : Strash = %5d Fraig = %5d\n", f, pFirst2->Id - Prev2, pFirst3->Id - Prev3 );
+ Prev2 = pFirst2->Id;
+ Prev3 = pFirst3->Id;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c
index 6708217c..b38012cd 100644
--- a/src/base/abci/abcDsd.c
+++ b/src/base/abci/abcDsd.c
@@ -172,7 +172,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t *
int i, nNodesDsd;
// save the CI nodes in the DSD nodes
- Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_NodeCreateConst1(pNtkNew) );
+ Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_NtkCreateNodeConst1(pNtkNew) );
Abc_NtkForEachCi( pNtk, pNode, i )
{
pNodeDsd = Dsd_ManagerReadInput( pManDsd, i );
diff --git a/src/base/abci/abcFpga.c b/src/base/abci/abcFpga.c
index 80238b48..3bc9fbed 100644
--- a/src/base/abci/abcFpga.c
+++ b/src/base/abci/abcFpga.c
@@ -210,7 +210,7 @@ Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy );
// set the constant node
// if ( Fpga_NodeReadRefs(Fpga_ManReadConst1(pMan)) > 0 )
- Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) );
+ Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NtkCreateNodeConst1(pNtkNew) );
// process the nodes in topological order
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
diff --git a/src/base/abci/abcFpgaFast.c b/src/base/abci/abcFpgaFast.c
index b307273f..3ad29291 100644
--- a/src/base/abci/abcFpgaFast.c
+++ b/src/base/abci/abcFpgaFast.c
@@ -99,7 +99,7 @@ Abc_Ntk_t * Ivy_ManFpgaToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan )
// start the new ABC network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_AIG );
// transfer the pointers to the basic nodes
- Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NodeCreateConst1(pNtkNew) );
+ Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NtkCreateNodeConst1(pNtkNew) );
Abc_NtkForEachCi( pNtkNew, pObjAbc, i )
Abc_ObjSetIvy2Abc( pMan, Ivy_ManPi(pMan, i)->Id, pObjAbc );
// recursively construct the network
@@ -112,7 +112,7 @@ Abc_Ntk_t * Ivy_ManFpgaToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan )
if ( Ivy_ObjFaninC0(pObjIvy) ) // complement
{
if ( Abc_ObjIsCi(pObjAbc) )
- pObjAbc = Abc_NodeCreateInv( pNtkNew, pObjAbc );
+ pObjAbc = Abc_NtkCreateNodeInv( pNtkNew, pObjAbc );
else
{
// clone the node
diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c
index 82e03119..446eb0cc 100644
--- a/src/base/abci/abcIvy.c
+++ b/src/base/abci/abcIvy.c
@@ -51,7 +51,7 @@ static inline Abc_Obj_t * Abc_EdgeToNode( Abc_Ntk_t * p, Abc_Edge_t Edge ) {
static inline Abc_Obj_t * Abc_ObjFanin0Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin0(pObj)->TravId), Ivy_ObjFaninC0(pObj) ); }
static inline Abc_Obj_t * Abc_ObjFanin1Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin1(pObj)->TravId), Ivy_ObjFaninC1(pObj) ); }
-static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs );
+static Vec_Int_t * Abc_NtkCollectLatchValuesIvy( Abc_Ntk_t * pNtk, int fUseDcs );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -85,7 +85,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
if ( fSeq && Abc_NtkCountSelfFeedLatches(pNtk) )
{
printf( "Warning: The network has %d self-feeding latches. Quitting.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
- return NULL;
+// return NULL;
}
// print warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
@@ -102,9 +102,9 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
if ( fSeq )
{
int nLatches = Abc_NtkLatchNum(pNtk);
- int * pInit = Abc_NtkCollectLatchValues( pNtk, fUseDc );
- Ivy_ManMakeSeq( pMan, nLatches, pInit );
- FREE( pInit );
+ Vec_Int_t * vInit = Abc_NtkCollectLatchValuesIvy( pNtk, fUseDc );
+ Ivy_ManMakeSeq( pMan, nLatches, vInit->pArray );
+ Vec_IntFree( vInit );
// Ivy_ManPrintStats( pMan );
}
return pMan;
@@ -191,8 +191,8 @@ Abc_Ntk_t * Abc_NtkIvyHaig( Abc_Ntk_t * pNtk, int nIters, int fUseZeroCost, int
return NULL;
Ivy_ManHaigStart( pMan, fVerbose );
- Ivy_ManRewriteSeq( pMan, 0, 0 );
- for ( i = 1; i < nIters; i++ )
+// Ivy_ManRewriteSeq( pMan, 0, 0 );
+ for ( i = 0; i < nIters; i++ )
Ivy_ManRewriteSeq( pMan, fUseZeroCost, 0 );
Ivy_ManHaigPostprocess( pMan, fVerbose );
@@ -486,7 +486,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
int fCleanup = 1;
// int nNodes;
int nLatches = Abc_NtkLatchNum(pNtk);
- int * pInit = Abc_NtkCollectLatchValues( pNtk, 0 );
+ Vec_Int_t * vInit = Abc_NtkCollectLatchValuesIvy( pNtk, 0 );
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
@@ -494,7 +494,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
- FREE( pInit );
+ Vec_IntFree( vInit );
printf( "Abc_NtkIvy(): Converting to SOPs has failed.\n" );
return NULL;
}
@@ -513,7 +513,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
pMan = Abc_NtkToAig( pNtk );
if ( !Ivy_ManCheck( pMan ) )
{
- FREE( pInit );
+ Vec_IntFree( vInit );
printf( "AIG check has failed.\n" );
Ivy_ManStop( pMan );
return NULL;
@@ -975,22 +975,23 @@ Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pRoot, cha
SeeAlso []
***********************************************************************/
-int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs )
+Vec_Int_t * Abc_NtkCollectLatchValuesIvy( Abc_Ntk_t * pNtk, int fUseDcs )
{
Abc_Obj_t * pLatch;
- int * pArray, i;
- pArray = ALLOC( int, Abc_NtkLatchNum(pNtk) );
+ Vec_Int_t * vArray;
+ int i;
+ vArray = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
if ( fUseDcs || Abc_LatchIsInitDc(pLatch) )
- pArray[i] = IVY_INIT_DC;
+ Vec_IntPush( vArray, IVY_INIT_DC );
else if ( Abc_LatchIsInit1(pLatch) )
- pArray[i] = IVY_INIT_1;
+ Vec_IntPush( vArray, IVY_INIT_1 );
else if ( Abc_LatchIsInit0(pLatch) )
- pArray[i] = IVY_INIT_0;
+ Vec_IntPush( vArray, IVY_INIT_0 );
else assert( 0 );
}
- return pArray;
+ return vArray;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abcLut.c b/src/base/abci/abcLut.c
index 165d84c5..61b1ce78 100644
--- a/src/base/abci/abcLut.c
+++ b/src/base/abci/abcLut.c
@@ -148,7 +148,7 @@ int Abc_NtkSuperChoiceLut( Abc_Ntk_t * pNtk, int nLutSize, int nCutSizeMax, int
// if there is no delay improvement, skip; otherwise, update level
if ( pObjTop->Level >= pObj->Level )
{
- Abc_NtkDeleteObj_rec( pObjTop );
+ Abc_NtkDeleteObj_rec( pObjTop, 1 );
continue;
}
pObj->Level = pObjTop->Level;
@@ -570,7 +570,7 @@ Abc_Obj_t * Abc_NodeSuperChoiceLut( Abc_ManScl_t * p, Abc_Obj_t * pObj )
{
Vec_PtrForEachEntry( p->vLeaves, pFanin, i )
if ( Abc_ObjIsNode(pFanin) && Abc_ObjFanoutNum(pFanin) == 0 )
- Abc_NtkDeleteObj_rec( pFanin );
+ Abc_NtkDeleteObj_rec( pFanin, 1 );
return NULL;
}
// create the topmost node
diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c
index 276e41d0..c4f9850a 100644
--- a/src/base/abci/abcMap.c
+++ b/src/base/abci/abcMap.c
@@ -259,7 +259,7 @@ Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int
// check the case of constant node
if ( Map_NodeIsConst(pNodeMap) )
- return fPhase? Abc_NodeCreateConst1(pNtkNew) : Abc_NodeCreateConst0(pNtkNew);
+ return fPhase? Abc_NtkCreateNodeConst1(pNtkNew) : Abc_NtkCreateNodeConst0(pNtkNew);
// check if the phase is already implemented
pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
@@ -369,7 +369,7 @@ Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
* (since the cut only has 4 variables). An interesting question is what
* if the first variable (and not the fifth one is the redundant one;
* can that happen?) */
- return Abc_NodeCreateConst0(pNtkNew);
+ return Abc_NtkCreateNodeConst0(pNtkNew);
}
}
@@ -503,14 +503,14 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
// set the pointers from the mapper to the new nodes
Abc_NtkForEachCi( pNtk, pNode, i )
{
- Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
+ Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NtkCreateNodeInv(pNtkNew,pNode->pCopy) );
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
}
Abc_NtkForEachNode( pNtk, pNode, i )
{
// if ( Abc_NodeIsConst(pNode) )
// continue;
- Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
+ Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NtkCreateNodeInv(pNtkNew,pNode->pCopy) );
Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy );
}
@@ -630,7 +630,7 @@ Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * p
* (since the cut only has 4 variables). An interesting question is what
* if the first variable (and not the fifth one is the redundant one;
* can that happen?) */
- return Abc_NodeCreateConst0(pNtkNew);
+ return Abc_NtkCreateNodeConst0(pNtkNew);
}
}
diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c
index 9b67ab13..a1f6b9f9 100644
--- a/src/base/abci/abcNtbdd.c
+++ b/src/base/abci/abcNtbdd.c
@@ -195,7 +195,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew )
pNodeNew = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node );
st_free_table( tBdd2Node );
if ( Cudd_IsComplement(bFunc) )
- pNodeNew = Abc_NodeCreateInv( pNtkNew, pNodeNew );
+ pNodeNew = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew );
return pNodeNew;
}
@@ -215,18 +215,18 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC;
assert( !Cudd_IsComplement(bFunc) );
if ( bFunc == b1 )
- return Abc_NodeCreateConst1(pNtkNew);
+ return Abc_NtkCreateNodeConst1(pNtkNew);
if ( st_lookup( tBdd2Node, (char *)bFunc, (char **)&pNodeNew ) )
return pNodeNew;
// solve for the children nodes
pNodeNew0 = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(cuddE(bFunc)), pNtkNew, tBdd2Node );
if ( Cudd_IsComplement(cuddE(bFunc)) )
- pNodeNew0 = Abc_NodeCreateInv( pNtkNew, pNodeNew0 );
+ pNodeNew0 = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew0 );
pNodeNew1 = Abc_NodeBddToMuxes_rec( dd, cuddT(bFunc), pNtkNew, tBdd2Node );
if ( !st_lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeNewC ) )
assert( 0 );
// create the MUX node
- pNodeNew = Abc_NodeCreateMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 );
+ pNodeNew = Abc_NtkCreateNodeMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 );
st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew );
return pNodeNew;
}
diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c
index afc635e9..6af12afd 100644
--- a/src/base/abci/abcPrint.c
+++ b/src/base/abci/abcPrint.c
@@ -61,10 +61,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
else
fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
- if ( !Abc_NtkIsSeq(pNtk) )
+// if ( !Abc_NtkIsSeq(pNtk) )
fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) );
- else
- fprintf( pFile, " lat = %4d(%d,%d)", Seq_NtkLatchNum(pNtk), Seq_NtkLatchNumShared(pNtk), Seq_NtkLatchNumMax(pNtk) );
+// else
+// fprintf( pFile, " lat = %4d(%d,%d)", Seq_NtkLatchNum(pNtk), Seq_NtkLatchNumShared(pNtk), Seq_NtkLatchNumMax(pNtk) );
if ( Abc_NtkIsNetlist(pNtk) )
{
@@ -228,6 +228,7 @@ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
int InitNums[4], Init;
assert( !Abc_NtkIsNetlist(pNtk) );
+/*
if ( Abc_NtkIsSeq(pNtk) )
{
Seq_NtkLatchGetInitNums( pNtk, InitNums );
@@ -236,7 +237,7 @@ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
Abc_NtkLatchNum(pNtk), InitNums[0], InitNums[1], InitNums[2], InitNums[3] );
return;
}
-
+*/
if ( Abc_NtkLatchNum(pNtk) == 0 )
{
fprintf( pFile, "The network is combinational.\n" );
@@ -383,6 +384,26 @@ void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode )
/**Function*************************************************************
+ Synopsis [Prints the MFFCs of the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintMffc( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ extern void Abc_NodeMffsConeSuppPrint( Abc_Obj_t * pNode );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Abc_NodeMffsConeSuppPrint( pNode );
+}
+
+/**Function*************************************************************
+
Synopsis [Prints the factored form of one node.]
Description []
@@ -833,6 +854,84 @@ void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll ) {
fprintf( pFile, "Endpoint Skews : Total |Skew| = %.2f\t Avg |Skew| = %.2f\t Non-Zero Skews = %d\n",
sum, avg, nNonZero );
}
+
+/**Function*************************************************************
+
+ Synopsis [Prints information about the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ fprintf( pFile, "Object %5d : ", pObj->Id );
+ switch ( pObj->Type )
+ {
+ case ABC_OBJ_NONE:
+ fprintf( pFile, "NONE " );
+ break;
+ case ABC_OBJ_CONST1:
+ fprintf( pFile, "Const1 " );
+ break;
+ case ABC_OBJ_PIO:
+ fprintf( pFile, "PIO " );
+ break;
+ case ABC_OBJ_PI:
+ fprintf( pFile, "PI " );
+ break;
+ case ABC_OBJ_PO:
+ fprintf( pFile, "PO " );
+ break;
+ case ABC_OBJ_BI:
+ fprintf( pFile, "BI " );
+ break;
+ case ABC_OBJ_BO:
+ fprintf( pFile, "BO " );
+ break;
+ case ABC_OBJ_ASSERT:
+ fprintf( pFile, "Assert " );
+ break;
+ case ABC_OBJ_NET:
+ fprintf( pFile, "Net " );
+ break;
+ case ABC_OBJ_NODE:
+ fprintf( pFile, "Node " );
+ break;
+ case ABC_OBJ_GATE:
+ fprintf( pFile, "Gate " );
+ break;
+ case ABC_OBJ_LATCH:
+ fprintf( pFile, "Latch " );
+ break;
+ case ABC_OBJ_TRI:
+ fprintf( pFile, "Tristate" );
+ break;
+ case ABC_OBJ_BLACKBOX:
+ fprintf( pFile, "Blackbox" );
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ // print the fanins
+ fprintf( pFile, " Fanins ( " );
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ fprintf( pFile, "%d ", pFanin->Id );
+ fprintf( pFile, ") " );
+ // print the logic function
+ if ( Abc_ObjIsNode(pObj) && Abc_NtkIsSopLogic(pObj->pNtk) )
+ fprintf( pFile, " %s", pObj->pData );
+ else
+ fprintf( pFile, "\n" );
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c
index cac634da..076bee46 100644
--- a/src/base/abci/abcSweep.c
+++ b/src/base/abci/abcSweep.c
@@ -32,6 +32,7 @@ static void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t
static void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose );
static int Abc_NodeDroppingCost( Abc_Obj_t * pNode );
+static int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes );
static void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose );
static void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 );
static void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin );
@@ -425,7 +426,7 @@ void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv,
return;
// add the invertor
- pNodeMinInv = Abc_NodeCreateInv( pNtk, pNodeMin );
+ pNodeMinInv = Abc_NtkCreateNodeInv( pNtk, pNodeMin );
// move the fanouts of the inverted nodes
for ( pNode = pListInv; pNode; pNode = pNode->pNext )
@@ -583,7 +584,7 @@ int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
if ( Abc_ObjFanoutNum(pNode) > 0 )
Vec_PtrPush( vNodes, pNode );
else
- Abc_NtkDeleteObj_rec( pNode );
+ Abc_NtkDeleteObj_rec( pNode, 1 );
}
Vec_PtrFree( vNodes );
// sweep a node into its CO fanout if all of this is true:
@@ -672,6 +673,263 @@ void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
Cudd_RecursiveDeref( dd, bCof1 );
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Removes all objects whose trav ID is not current.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeRemoveNonCurrentObjects( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int Counter, i;
+ int fVerbose = 0;
+
+ // report on the nodes to be deleted
+ if ( fVerbose )
+ {
+ printf( "These nodes will be deleted: \n" );
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ if ( !Abc_NodeIsTravIdCurrent( pObj ) )
+ {
+ printf( " " );
+ Abc_ObjPrint( stdout, pObj );
+ }
+ }
+
+ // delete the nodes
+ Counter = 0;
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ if ( !Abc_NodeIsTravIdCurrent( pObj ) )
+ {
+ Abc_NtkDeleteObj( pObj );
+ Counter++;
+ }
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Check if the fanin of this latch is a constant.]
+
+ Description [Returns 0/1 if constant; -1 if not a constant.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSetTravId_rec( Abc_Obj_t * pObj )
+{
+ Abc_NodeSetTravIdCurrent(pObj);
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ return;
+ assert( Abc_ObjFaninNum(pObj) == 1 );
+ Abc_NtkSetTravId_rec( Abc_ObjFanin0(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Check if the fanin of this latch is a constant.]
+
+ Description [Returns 0/1 if constant; -1 if not a constant.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkCheckConstant_rec( Abc_Obj_t * pObj )
+{
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ {
+ if ( !Abc_ObjIsNode(pObj) )
+ return -1;
+ if ( Abc_NodeIsConst0(pObj) )
+ return 0;
+ if ( Abc_NodeIsConst1(pObj) )
+ return 1;
+ assert( 0 );
+ return -1;
+ }
+ if ( Abc_ObjIsLatch(pObj) || Abc_ObjFaninNum(pObj) > 1 )
+ return -1;
+ if ( !Abc_ObjIsNode(pObj) || Abc_NodeIsBuf(pObj) )
+ return Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pObj) );
+ if ( Abc_NodeIsInv(pObj) )
+ {
+ int RetValue = Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pObj) );
+ if ( RetValue == 0 )
+ return 1;
+ if ( RetValue == 1 )
+ return 0;
+ return RetValue;
+ }
+ assert( 0 );
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes redundant latches.]
+
+ Description [The redundant latches are of two types:
+ - Latches fed by a constant which matches the init value of the latch.
+ - Latches fed by a constant which does not match the init value of the latch
+ can be all replaced by one latch.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkLatchSweep( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pFanin, * pLatch, * pLatchPivot = NULL;
+ int Counter, RetValue, i;
+ Counter = 0;
+ // go through the latches
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ // check if the latch has constant input
+ RetValue = Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pLatch) );
+ if ( RetValue == -1 )
+ continue;
+ // found a latch with constant fanin
+ if ( (RetValue == 1 && Abc_LatchIsInit0(pLatch)) ||
+ (RetValue == 0 && Abc_LatchIsInit1(pLatch)) )
+ {
+ // fanin constant differs from the latch init value
+ if ( pLatchPivot == NULL )
+ {
+ pLatchPivot = pLatch;
+ continue;
+ }
+ if ( Abc_LatchInit(pLatch) != Abc_LatchInit(pLatchPivot) ) // add inverter
+ pFanin = Abc_NtkCreateNodeInv( pNtk, Abc_ObjFanout0(pLatchPivot) );
+ else
+ pFanin = Abc_ObjFanout0(pLatchPivot);
+ }
+ else
+ pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
+ // replace latch
+ Abc_ObjTransferFanout( Abc_ObjFanout0(pLatch), pFanin );
+ // delete the extra nodes
+ Abc_NtkDeleteObj_rec( Abc_ObjFanout0(pLatch), 0 );
+ Counter++;
+ }
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces autonumnous logic by free inputs.]
+
+ Description [Assumes that non-autonomous logic is marked with
+ the current ID.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkReplaceAutonomousLogic( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode, * pFanin;
+ Vec_Ptr_t * vNodes;
+ int i, k, Counter;
+ // collect the nodes that feed into the reachable logic
+ vNodes = Vec_PtrAlloc( 100 );
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ {
+ // skip non-visited fanins
+ if ( !Abc_NodeIsTravIdCurrent(pNode) )
+ continue;
+ // look for non-visited fanins
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ {
+ // skip visited fanins
+ if ( Abc_NodeIsTravIdCurrent(pFanin) )
+ continue;
+ // skip constants and latches fed by constants
+ if ( Abc_NtkCheckConstant_rec(pFanin) != -1 ||
+ (Abc_ObjIsBi(pFanin) && Abc_NtkCheckConstant_rec(Abc_ObjFanin0(Abc_ObjFanin0(pFanin))) != -1) )
+ {
+ Abc_NtkSetTravId_rec( pFanin );
+ continue;
+ }
+ assert( !Abc_ObjIsLatch(pFanin) );
+ Vec_PtrPush( vNodes, pFanin );
+ }
+ }
+ Vec_PtrUniqify( vNodes, Abc_ObjPointerCompare );
+ // replace these nodes by the PIs
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ pFanin = Abc_NtkCreatePi(pNtk);
+ Abc_NodeSetTravIdCurrent( pFanin );
+ Abc_ObjTransferFanout( pNode, pFanin );
+ }
+ Counter = Vec_PtrSize(vNodes);
+ Vec_PtrFree( vNodes );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sequential cleanup.]
+
+ Description [Performs three tasks:
+ - Removes logic that does not feed into POs.
+ - Removes latches driven by constant values equal to the initial state.
+ - Replaces the autonomous components by additional PI variables.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ Vec_Ptr_t * vNodes;
+ int Counter;
+ assert( Abc_NtkIsLogic(pNtk) );
+ // mark the nodes reachable from the POs
+ vNodes = Abc_NtkDfsSeq( pNtk );
+ Vec_PtrFree( vNodes );
+ // remove the non-marked nodes
+ Counter = Abc_NodeRemoveNonCurrentObjects( pNtk );
+ if ( fVerbose )
+ printf( "Cleanup removed %4d dangling objects.\n", Counter );
+ // check if some of the latches can be removed
+ Counter = Abc_NtkLatchSweep( pNtk );
+ if ( fVerbose )
+ printf( "Cleanup removed %4d redundant latches.\n", Counter );
+ // detect the autonomous components
+ vNodes = Abc_NtkDfsSeqReverse( pNtk );
+ Vec_PtrFree( vNodes );
+ // replace them by PIs
+ Counter = Abc_NtkReplaceAutonomousLogic( pNtk );
+ if ( fVerbose )
+ printf( "Cleanup added %4d additional PIs.\n", Counter );
+ // remove the non-marked nodes
+ Counter = Abc_NodeRemoveNonCurrentObjects( pNtk );
+ if ( fVerbose )
+ printf( "Cleanup removed %4d autonomous objects.\n", Counter );
+ // check
+ if ( !Abc_NtkCheck( pNtk ) )
+ printf( "Abc_NtkCleanupSeq: The network check has failed.\n" );
+ return 1;
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c
index 622b4103..594cc2d6 100644
--- a/src/base/abci/abcVerify.c
+++ b/src/base/abci/abcVerify.c
@@ -333,7 +333,7 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
printf( "Networks are NOT EQUIVALENT after framing.\n" );
// report the error
pFrames->pModel = Abc_NtkVerifyGetCleanModel( pFrames, 1 );
- Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, pFrames->pModel, nFrames );
+// Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, pFrames->pModel, nFrames );
FREE( pFrames->pModel );
Abc_NtkDelete( pFrames );
return;
@@ -365,7 +365,7 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF
else if ( RetValue == 0 )
{
printf( "Networks are NOT EQUIVALENT after fraiging.\n" );
- Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, Fraig_ManReadModel(pMan), nFrames );
+// Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, Fraig_ManReadModel(pMan), nFrames );
}
else assert( 0 );
// delete the fraig manager
diff --git a/src/base/abci/abcXsim.c b/src/base/abci/abcXsim.c
new file mode 100644
index 00000000..1d56ba36
--- /dev/null
+++ b/src/base/abci/abcXsim.c
@@ -0,0 +1,164 @@
+/**CFile****************************************************************
+
+ FileName [abcXsim.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Using X-valued simulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcXsim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define XVS0 1
+#define XVS1 2
+#define XVSX 3
+
+static inline void Abc_ObjSetXsim( Abc_Obj_t * pObj, int Value ) { pObj->pCopy = (void *)Value; }
+static inline int Abc_ObjGetXsim( Abc_Obj_t * pObj ) { return (int)pObj->pCopy; }
+static inline int Abc_XsimInv( int Value )
+{
+ if ( Value == XVS0 )
+ return XVS1;
+ if ( Value == XVS1 )
+ return XVS0;
+ assert( Value == XVSX );
+ return XVSX;
+}
+static inline int Abc_XsimAnd( int Value0, int Value1 )
+{
+ if ( Value0 == XVS0 || Value1 == XVS0 )
+ return XVS0;
+ if ( Value0 == XVSX || Value1 == XVSX )
+ return XVSX;
+ assert( Value0 == XVS1 && Value1 == XVS1 );
+ return XVS1;
+}
+static inline int Abc_XsimRand2()
+{
+ return (rand() & 1) ? XVS1 : XVS0;
+}
+static inline int Abc_XsimRand3()
+{
+ int RetValue;
+ do {
+ RetValue = rand() & 3;
+ } while ( RetValue == 0 );
+ return RetValue;
+}
+static inline int Abc_ObjGetXsimFanin0( Abc_Obj_t * pObj )
+{
+ int RetValue;
+ RetValue = Abc_ObjGetXsim(Abc_ObjFanin0(pObj));
+ return Abc_ObjFaninC0(pObj)? Abc_XsimInv(RetValue) : RetValue;
+}
+static inline int Abc_ObjGetXsimFanin1( Abc_Obj_t * pObj )
+{
+ int RetValue;
+ RetValue = Abc_ObjGetXsim(Abc_ObjFanin1(pObj));
+ return Abc_ObjFaninC1(pObj)? Abc_XsimInv(RetValue) : RetValue;
+}
+static inline void Abc_XsimPrint( FILE * pFile, int Value )
+{
+ if ( Value == XVS0 )
+ {
+ fprintf( pFile, "0" );
+ return;
+ }
+ if ( Value == XVS1 )
+ {
+ fprintf( pFile, "1" );
+ return;
+ }
+ assert( Value == XVSX );
+ fprintf( pFile, "x" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs X-valued simulation of the sequential network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose )
+{
+ Abc_Obj_t * pObj;
+ int i, f;
+ assert( Abc_NtkIsStrash(pNtk) );
+ srand( 0x12341234 );
+ // start simulation
+ Abc_ObjSetXsim( Abc_AigConst1(pNtk), XVS1 );
+ if ( fInputs )
+ {
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_ObjSetXsim( pObj, XVSX );
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchInit(pObj) );
+ }
+ else
+ {
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ Abc_ObjSetXsim( Abc_ObjFanout0(pObj), XVSX );
+ }
+ // simulate and print the result
+ fprintf( stdout, "Frame : Inputs : Latches : Outputs\n" );
+ for ( f = 0; f < nFrames; f++ )
+ {
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ Abc_ObjSetXsim( pObj, Abc_XsimAnd(Abc_ObjGetXsimFanin0(pObj), Abc_ObjGetXsimFanin1(pObj)) );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Abc_ObjSetXsim( pObj, Abc_ObjGetXsimFanin0(pObj) );
+ // print out
+ fprintf( stdout, "%2d : ", f );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
+ fprintf( stdout, " : " );
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ Abc_XsimPrint( stdout, Abc_ObjGetXsim(Abc_ObjFanout0(pObj)) );
+ fprintf( stdout, " : " );
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
+ fprintf( stdout, "\n" );
+ // assign input values
+ if ( fInputs )
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_ObjSetXsim( pObj, XVSX );
+ else
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
+ // transfer the latch values
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_ObjGetXsim(Abc_ObjFanin0(pObj)) );
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/module.make b/src/base/abci/module.make
index bb2ae1a0..50a40393 100644
--- a/src/base/abci/module.make
+++ b/src/base/abci/module.make
@@ -2,6 +2,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcAttach.c \
src/base/abci/abcAuto.c \
src/base/abci/abcBalance.c \
+ src/base/abci/abcBmc.c \
src/base/abci/abcClpBdd.c \
src/base/abci/abcClpSop.c \
src/base/abci/abcCut.c \
@@ -37,4 +38,5 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcTiming.c \
src/base/abci/abcUnate.c \
src/base/abci/abcUnreach.c \
- src/base/abci/abcVerify.c
+ src/base/abci/abcVerify.c \
+ src/base/abci/abcXsim.c
diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c
index cc51cc1c..f2f07b14 100644
--- a/src/base/io/ioUtil.c
+++ b/src/base/io/ioUtil.c
@@ -179,7 +179,7 @@ Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesI
Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 )
{
Abc_Obj_t * pNet, * pTerm;
- pTerm = fConst1? Abc_NodeCreateConst1(pNtk) : Abc_NodeCreateConst0(pNtk);
+ pTerm = fConst1? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk);
pNet = Abc_NtkFindNet(pNtk, pName); assert( pNet );
Abc_ObjAddFanin( pNet, pTerm );
return pTerm;
@@ -200,7 +200,7 @@ Abc_Obj_t * Io_ReadCreateInv( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut
{
Abc_Obj_t * pNet, * pNode;
pNet = Abc_NtkFindNet(pNtk, pNameIn); assert( pNet );
- pNode = Abc_NodeCreateInv(pNtk, pNet);
+ pNode = Abc_NtkCreateNodeInv(pNtk, pNet);
pNet = Abc_NtkFindNet(pNtk, pNameOut); assert( pNet );
Abc_ObjAddFanin( pNet, pNode );
return pNode;
@@ -221,7 +221,7 @@ Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut
{
Abc_Obj_t * pNet, * pNode;
pNet = Abc_NtkFindNet(pNtk, pNameIn); assert( pNet );
- pNode = Abc_NodeCreateBuf(pNtk, pNet);
+ pNode = Abc_NtkCreateNodeBuf(pNtk, pNet);
pNet = Abc_NtkFindNet(pNtk, pNameOut); assert( pNet );
Abc_ObjAddFanin( pNet, pNode );
return pNet;
diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c
index 8ce837e2..05539c40 100644
--- a/src/base/io/ioWriteDot.c
+++ b/src/base/io/ioWriteDot.c
@@ -112,10 +112,13 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "\n" );
fprintf( pFile, "digraph AIG {\n" );
fprintf( pFile, "size = \"7.5,10\";\n" );
+// fprintf( pFile, "size = \"10,8.5\";\n" );
+// fprintf( pFile, "size = \"14,11\";\n" );
+// fprintf( pFile, "page = \"8,11\";\n" );
// fprintf( pFile, "ranksep = 0.5;\n" );
// fprintf( pFile, "nodesep = 0.5;\n" );
fprintf( pFile, "center = true;\n" );
-// fprintf( pFile, "orientation = landscape;\n" );
+// fprintf( pFile, "orientation = landscape;\n" );
// fprintf( pFile, "edge [fontsize = 10];\n" );
// fprintf( pFile, "edge [dir = none];\n" );
fprintf( pFile, "edge [dir = back];\n" );
@@ -320,8 +323,8 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "Node%d%s", Abc_ObjFaninId0(pNode), (Abc_ObjIsLatch(Abc_ObjFanin0(pNode))? "_out":"") );
fprintf( pFile, " [" );
fprintf( pFile, "style = %s", Abc_ObjFaninC0(pNode)? "dotted" : "bold" );
- if ( Abc_NtkIsSeq(pNode->pNtk) && Seq_ObjFaninL0(pNode) > 0 )
- fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) );
+// if ( Abc_NtkIsSeq(pNode->pNtk) && Seq_ObjFaninL0(pNode) > 0 )
+// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}
@@ -335,8 +338,8 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "Node%d%s", Abc_ObjFaninId1(pNode), (Abc_ObjIsLatch(Abc_ObjFanin1(pNode))? "_out":"") );
fprintf( pFile, " [" );
fprintf( pFile, "style = %s", Abc_ObjFaninC1(pNode)? "dotted" : "bold" );
- if ( Abc_NtkIsSeq(pNode->pNtk) && Seq_ObjFaninL1(pNode) > 0 )
- fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) );
+// if ( Abc_NtkIsSeq(pNode->pNtk) && Seq_ObjFaninL1(pNode) > 0 )
+// fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}
diff --git a/src/base/seq/seqUtil.c b/src/base/seq/seqUtil.c
index af2a0a7a..55b9df8e 100644
--- a/src/base/seq/seqUtil.c
+++ b/src/base/seq/seqUtil.c
@@ -580,7 +580,8 @@ int Seq_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose )
Abc_NtkNodeNum(pNtk), Vec_PtrSize(vNodesPo), Vec_PtrSize(vNodesPi) );
if ( Abc_NtkNodeNum(pNtk) > Vec_PtrSize(vNodesPo) )
{
- Counter = Abc_NtkReduceNodes( pNtk, vNodesPo );
+// Counter = Abc_NtkReduceNodes( pNtk, vNodesPo );
+ Counter = 0;
if ( fVerbose )
printf( "Cleanup removed %d nodes that are not reachable from the POs.\n", Counter );
}
diff --git a/src/bdd/dsd/dsd.h b/src/bdd/dsd/dsd.h
index a3fc4948..b73b81ab 100644
--- a/src/bdd/dsd/dsd.h
+++ b/src/bdd/dsd/dsd.h
@@ -63,10 +63,10 @@ enum Dsd_Type_t_ {
////////////////////////////////////////////////////////////////////////
// complementation and testing for pointers for decomposition entries
-#define Dsd_IsComplement(p) (((int)((long) (p) & 01)))
-#define Dsd_Regular(p) ((Dsd_Node_t *)((unsigned)(p) & ~01))
-#define Dsd_Not(p) ((Dsd_Node_t *)((long)(p) ^ 01))
-#define Dsd_NotCond(p,c) ((Dsd_Node_t *)((long)(p) ^ (c)))
+#define Dsd_IsComplement(p) (((int)((unsigned long) (p) & 01)))
+#define Dsd_Regular(p) ((Dsd_Node_t *)((unsigned long)(p) & ~01))
+#define Dsd_Not(p) ((Dsd_Node_t *)((unsigned long)(p) ^ 01))
+#define Dsd_NotCond(p,c) ((Dsd_Node_t *)((unsigned long)(p) ^ (c)))
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
diff --git a/src/bdd/reo/reo.h b/src/bdd/reo/reo.h
index 9be29f87..1a31242a 100644
--- a/src/bdd/reo/reo.h
+++ b/src/bdd/reo/reo.h
@@ -172,8 +172,8 @@ struct _reo_man
// used to manipulate units
#define Unit_Regular(u) ((reo_unit *)((unsigned long)(u) & ~01))
-#define Unit_Not(u) ((reo_unit *)((long)(u) ^ 01))
-#define Unit_NotCond(u,c) ((reo_unit *)((long)(u) ^ (c)))
+#define Unit_Not(u) ((reo_unit *)((unsigned long)(u) ^ 01))
+#define Unit_NotCond(u,c) ((reo_unit *)((unsigned long)(u) ^ (c)))
#define Unit_IsConstant(u) ((int)((u)->lev == REO_CONST_LEVEL))
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/fpga/fpga.h b/src/map/fpga/fpga.h
index 3ecdb44f..d89f6dc9 100644
--- a/src/map/fpga/fpga.h
+++ b/src/map/fpga/fpga.h
@@ -52,10 +52,10 @@ typedef struct Fpga_LutLibStruct_t_ Fpga_LutLib_t;
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-#define Fpga_IsComplement(p) (((int)((long) (p) & 01)))
-#define Fpga_Regular(p) ((Fpga_Node_t *)((unsigned)(p) & ~01))
-#define Fpga_Not(p) ((Fpga_Node_t *)((long)(p) ^ 01))
-#define Fpga_NotCond(p,c) ((Fpga_Node_t *)((long)(p) ^ (c)))
+#define Fpga_IsComplement(p) (((int)((unsigned long) (p) & 01)))
+#define Fpga_Regular(p) ((Fpga_Node_t *)((unsigned long)(p) & ~01))
+#define Fpga_Not(p) ((Fpga_Node_t *)((unsigned long)(p) ^ 01))
+#define Fpga_NotCond(p,c) ((Fpga_Node_t *)((unsigned long)(p) ^ (c)))
#define Fpga_Ref(p)
#define Fpga_Deref(p)
diff --git a/src/map/fpga/fpgaInt.h b/src/map/fpga/fpgaInt.h
index 60f18080..9085baa2 100644
--- a/src/map/fpga/fpgaInt.h
+++ b/src/map/fpga/fpgaInt.h
@@ -67,16 +67,16 @@
#define FPGA_SEQ_SIGN(p) (1 << (((unsigned)p)%31));
// internal macros to work with cuts
-#define Fpga_CutIsComplement(p) (((int)((long) (p) & 01)))
-#define Fpga_CutRegular(p) ((Fpga_Cut_t *)((unsigned)(p) & ~01))
-#define Fpga_CutNot(p) ((Fpga_Cut_t *)((long)(p) ^ 01))
-#define Fpga_CutNotCond(p,c) ((Fpga_Cut_t *)((long)(p) ^ (c)))
+#define Fpga_CutIsComplement(p) (((int)((unsigned long) (p) & 01)))
+#define Fpga_CutRegular(p) ((Fpga_Cut_t *)((unsigned long)(p) & ~01))
+#define Fpga_CutNot(p) ((Fpga_Cut_t *)((unsigned long)(p) ^ 01))
+#define Fpga_CutNotCond(p,c) ((Fpga_Cut_t *)((unsigned long)(p) ^ (c)))
// the cut nodes
-#define Fpga_SeqIsComplement( p ) (((int)((long) (p) & 01)))
-#define Fpga_SeqRegular( p ) ((Fpga_Node_t *)((unsigned)(p) & ~015))
-#define Fpga_SeqIndex( p ) ((((unsigned)(p)) >> 1) & 07)
-#define Fpga_SeqIndexCreate( p, Ind ) (((unsigned)(p)) | (1 << (((unsigned)(Ind)) & 07)))
+#define Fpga_SeqIsComplement( p ) (((int)((unsigned long) (p) & 01)))
+#define Fpga_SeqRegular( p ) ((Fpga_Node_t *)((unsigned long)(p) & ~015))
+#define Fpga_SeqIndex( p ) ((((unsigned long)(p)) >> 1) & 07)
+#define Fpga_SeqIndexCreate( p, Ind ) (((unsigned long)(p)) | (1 << (((unsigned)(Ind)) & 07)))
// internal macros for referencing of nodes
#define Fpga_NodeReadRef(p) ((Fpga_Regular(p))->nRefs)
diff --git a/src/map/mapper/mapper.h b/src/map/mapper/mapper.h
index 10839382..8eade761 100644
--- a/src/map/mapper/mapper.h
+++ b/src/map/mapper/mapper.h
@@ -63,10 +63,10 @@ struct Map_TimeStruct_t_
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-#define Map_IsComplement(p) (((int)((long) (p) & 01)))
-#define Map_Regular(p) ((Map_Node_t *)((unsigned)(p) & ~01))
-#define Map_Not(p) ((Map_Node_t *)((long)(p) ^ 01))
-#define Map_NotCond(p,c) ((Map_Node_t *)((long)(p) ^ (c)))
+#define Map_IsComplement(p) (((int)((unsigned long) (p) & 01)))
+#define Map_Regular(p) ((Map_Node_t *)((unsigned long)(p) & ~01))
+#define Map_Not(p) ((Map_Node_t *)((unsigned long)(p) ^ 01))
+#define Map_NotCond(p,c) ((Map_Node_t *)((unsigned long)(p) ^ (c)))
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
diff --git a/src/map/mapper/mapperInt.h b/src/map/mapper/mapperInt.h
index a3a2cf40..37cca3d3 100644
--- a/src/map/mapper/mapperInt.h
+++ b/src/map/mapper/mapperInt.h
@@ -61,10 +61,10 @@
#define MAP_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()))
// internal macros to work with cuts
-#define Map_CutIsComplement(p) (((int)((long) (p) & 01)))
-#define Map_CutRegular(p) ((Map_Cut_t *)((unsigned)(p) & ~01))
-#define Map_CutNot(p) ((Map_Cut_t *)((long)(p) ^ 01))
-#define Map_CutNotCond(p,c) ((Map_Cut_t *)((long)(p) ^ (c)))
+#define Map_CutIsComplement(p) (((int)((unsigned long) (p) & 01)))
+#define Map_CutRegular(p) ((Map_Cut_t *)((unsigned long)(p) & ~01))
+#define Map_CutNot(p) ((Map_Cut_t *)((unsigned long)(p) ^ 01))
+#define Map_CutNotCond(p,c) ((Map_Cut_t *)((unsigned long)(p) ^ (c)))
// internal macros for referencing of nodes
#define Map_NodeReadRef(p) ((Map_Regular(p))->nRefs)
diff --git a/src/map/super/superAnd.c b/src/map/super/superAnd.c
index 02b25778..29d556f0 100644
--- a/src/map/super/superAnd.c
+++ b/src/map/super/superAnd.c
@@ -61,10 +61,10 @@ struct Super2_GateStruct_t_
// manipulation of complemented attributes
-#define Super2_IsComplement(p) (((int)((long) (p) & 01)))
-#define Super2_Regular(p) ((Super2_Gate_t *)((unsigned)(p) & ~01))
-#define Super2_Not(p) ((Super2_Gate_t *)((long)(p) ^ 01))
-#define Super2_NotCond(p,c) ((Super2_Gate_t *)((long)(p) ^ (c)))
+#define Super2_IsComplement(p) (((int)((unsigned long) (p) & 01)))
+#define Super2_Regular(p) ((Super2_Gate_t *)((unsigned long)(p) & ~01))
+#define Super2_Not(p) ((Super2_Gate_t *)((unsigned long)(p) ^ 01))
+#define Super2_NotCond(p,c) ((Super2_Gate_t *)((unsigned long)(p) ^ (c)))
// iterating through the gates in the library
#define Super2_LibForEachGate( Lib, Gate ) \
diff --git a/src/misc/nm/nmApi.c b/src/misc/nm/nmApi.c
index 05fe80a1..1306b497 100644
--- a/src/misc/nm/nmApi.c
+++ b/src/misc/nm/nmApi.c
@@ -120,7 +120,7 @@ char * Nm_ManStoreIdName( Nm_Man_t * p, int ObjId, int Type, char * pName, char
nEntrySize = sizeof(Nm_Entry_t) + strlen(pName) + (pSuffix?strlen(pSuffix):0) + 1;
nEntrySize = (nEntrySize / 4 + ((nEntrySize % 4) > 0)) * 4;
pEntry = (Nm_Entry_t *)Extra_MmFlexEntryFetch( p->pMem, nEntrySize );
- pEntry->pNextI2N = pEntry->pNextN2I = NULL;
+ pEntry->pNextI2N = pEntry->pNextN2I = pEntry->pNameSake = NULL;
pEntry->ObjId = ObjId;
pEntry->Type = Type;
sprintf( pEntry->Name, "%s%s", pName, pSuffix? pSuffix : "" );
diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h
index 07ac0f17..38513a93 100644
--- a/src/misc/vec/vecPtr.h
+++ b/src/misc/vec/vecPtr.h
@@ -574,8 +574,34 @@ static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
***********************************************************************/
static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
{
+ if ( p->nSize < 2 )
+ return;
+ qsort( (void *)p->pArray, p->nSize, sizeof(void *),
+ (int (*)(const void *, const void *)) Vec_PtrSortCompare );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrUniqify( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
+{
+ int i, k;
+ if ( p->nSize < 2 )
+ return;
qsort( (void *)p->pArray, p->nSize, sizeof(void *),
(int (*)(const void *, const void *)) Vec_PtrSortCompare );
+ for ( i = k = 1; i < p->nSize; i++ )
+ if ( p->pArray[i] != p->pArray[i-1] )
+ p->pArray[k++] = p->pArray[i];
+ p->nSize = k;
}
#endif
diff --git a/src/opt/ret/module.make b/src/opt/ret/module.make
new file mode 100644
index 00000000..9ac0bf1f
--- /dev/null
+++ b/src/opt/ret/module.make
@@ -0,0 +1,8 @@
+SRC += src/opt/dec/retArea.c \
+ src/opt/dec/retBwd.c \
+ src/opt/dec/retCore.c \
+ src/opt/dec/retDelay.c \
+ src/opt/dec/retFlow.c \
+ src/opt/dec/retFwd.c \
+ src/opt/dec/retInit.c
+
diff --git a/src/opt/ret/retArea.c b/src/opt/ret/retArea.c
new file mode 100644
index 00000000..7f93b87b
--- /dev/null
+++ b/src/opt/ret/retArea.c
@@ -0,0 +1,593 @@
+/**CFile****************************************************************
+
+ FileName [retArea.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Retiming package.]
+
+ Synopsis [Min-area retiming.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: retArea.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "retInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Abc_NtkRetimeMinAreaFwd( Abc_Ntk_t * pNtk, int fVerbose );
+static Abc_Ntk_t * Abc_NtkRetimeMinAreaBwd( Abc_Ntk_t * pNtk, int fVerbose );
+static void Abc_NtkRetimeMinAreaPrepare( Abc_Ntk_t * pNtk, int fForward );
+static Vec_Ptr_t * Abc_NtkRetimeMinAreaAddBuffers( Abc_Ntk_t * pNtk );
+static void Abc_NtkRetimeMinAreaRemoveBuffers( Abc_Ntk_t * pNtk, Vec_Ptr_t * vBuffers );
+static void Abc_NtkRetimeMinAreaInitValue( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut );
+static Abc_Ntk_t * Abc_NtkRetimeMinAreaConstructNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut );
+static void Abc_NtkRetimeMinAreaUpdateLatches( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward );
+
+extern Abc_Ntk_t * Abc_NtkAttachBottom( Abc_Ntk_t * pNtkTop, Abc_Ntk_t * pNtkBottom );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs min-area retiming.]
+
+ Description [Returns the number of latches reduced.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ Abc_Ntk_t * pNtkTotal = NULL, * pNtkBottom, * pNtkMiter;
+ Vec_Int_t * vValues;
+ int nLatches = Abc_NtkLatchNum(pNtk);
+ // there should not be black boxes
+ assert( Abc_NtkIsSopLogic(pNtk) );
+ assert( Abc_NtkLatchNum(pNtk) == Vec_PtrSize(pNtk->vBoxes) );
+ // reorder CI/CO/latch inputs
+ Abc_NtkOrderCisCos( pNtk );
+ // perform forward retiming
+ vValues = Abc_NtkCollectLatchValues( pNtk );
+// Abc_NtkRetimeMinAreaFwd( pNtk, fVerbose );
+ pNtkTotal = Abc_NtkRetimeMinAreaBwd( pNtk, fVerbose );
+
+// while ( Abc_NtkRetimeMinAreaFwd( pNtk, fVerbose ) );
+ // perform backward retiming
+// while ( pNtkBottom = Abc_NtkRetimeMinAreaBwd( pNtk, fVerbose ) )
+// pNtkTotal = Abc_NtkAttachBottom( pNtkTotal, pNtkBottom );
+ // compute initial values
+ if ( pNtkTotal )
+ {
+ // convert the target network to AIG
+ Abc_NtkLogicToAig( pNtkTotal );
+ // get the miter
+ pNtkMiter = Abc_NtkCreateTarget( pNtkTotal, pNtkTotal->vCos, vValues );
+ Abc_NtkDelete( pNtkTotal );
+ // get the initial values
+ Abc_NtkRetimeInitialValues( pNtk, pNtkMiter, fVerbose );
+ Abc_NtkDelete( pNtkMiter );
+ }
+ Vec_IntFree( vValues );
+ // fix the COs
+ Abc_NtkLogicMakeSimpleCos( pNtk, 0 );
+ // check for correctness
+ if ( !Abc_NtkCheck( pNtk ) )
+ fprintf( stdout, "Abc_NtkRetimeMinArea(): Network check has failed.\n" );
+ // return the number of latches saved
+ return nLatches - Abc_NtkLatchNum(pNtk);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs min-area retiming forward.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRetimeMinAreaFwd( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ Vec_Ptr_t * vBuffers, * vMinCut;
+ int nLatches = Abc_NtkLatchNum(pNtk);
+ // mark current latches and TFO(PIs)
+ Abc_NtkRetimeMinAreaPrepare( pNtk, 1 );
+ // add buffers on edges feeding into the marked nodes
+ vBuffers = Abc_NtkRetimeMinAreaAddBuffers( pNtk );
+ // run the maximum forward flow
+ vMinCut = Abc_NtkMaxFlow( pNtk, 1, fVerbose );
+ assert( Vec_PtrSize(vMinCut) <= Abc_NtkLatchNum(pNtk) );
+ // create new latch boundary if there is improvement
+ if ( Vec_PtrSize(vMinCut) < Abc_NtkLatchNum(pNtk) )
+ {
+ Abc_NtkRetimeMinAreaInitValue( pNtk, vMinCut );
+ Abc_NtkRetimeMinAreaUpdateLatches( pNtk, vMinCut, 1 );
+ }
+ // clean up
+ Abc_NtkRetimeMinAreaRemoveBuffers( pNtk, vBuffers );
+ Vec_PtrFree( vMinCut );
+ Abc_NtkCleanMarkA( pNtk );
+ return nLatches - Abc_NtkLatchNum(pNtk);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs min-area retiming backward.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkRetimeMinAreaBwd( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ Abc_Ntk_t * pNtkNew = NULL;
+ Vec_Ptr_t * vMinCut;
+ int nLatches = Abc_NtkLatchNum(pNtk);
+ // mark current latches and TFI(POs)
+ Abc_NtkRetimeMinAreaPrepare( pNtk, 0 );
+ // run the maximum forward flow
+ vMinCut = Abc_NtkMaxFlow( pNtk, 0, fVerbose );
+ assert( Vec_PtrSize(vMinCut) <= Abc_NtkLatchNum(pNtk) );
+ // create new latch boundary if there is improvement
+ if ( Vec_PtrSize(vMinCut) < Abc_NtkLatchNum(pNtk) )
+ {
+ pNtkNew = Abc_NtkRetimeMinAreaConstructNtk( pNtk, vMinCut );
+ Abc_NtkRetimeMinAreaUpdateLatches( pNtk, vMinCut, 0 );
+ }
+ // clean up
+ Vec_PtrFree( vMinCut );
+ Abc_NtkCleanMarkA( pNtk );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks the cone with MarkA.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMarkCone_rec( Abc_Obj_t * pObj, int fForward )
+{
+ Abc_Obj_t * pNext;
+ int i;
+ if ( pObj->fMarkA )
+ return;
+ pObj->fMarkA = 1;
+ if ( fForward )
+ {
+ Abc_ObjForEachFanout( pObj, pNext, i )
+ Abc_NtkMarkCone_rec( pNext, fForward );
+ }
+ else
+ {
+ Abc_ObjForEachFanin( pObj, pNext, i )
+ Abc_NtkMarkCone_rec( pNext, fForward );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the network for running MaxFlow.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRetimeMinAreaPrepare( Abc_Ntk_t * pNtk, int fForward )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ if ( fForward )
+ {
+ // mark the frontier
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ pObj->fMarkA = 1;
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pObj->fMarkA = 1;
+ Abc_ObjFanin0(pObj)->fMarkA = 1;
+ }
+ // mark the nodes reachable from the POs
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NtkMarkCone_rec( pObj, fForward );
+ }
+ else
+ {
+ // mark the frontier
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ pObj->fMarkA = 1;
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pObj->fMarkA = 1;
+ Abc_ObjFanout0(pObj)->fMarkA = 1;
+ }
+ // mark the nodes reachable from the POs
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Abc_NtkMarkCone_rec( pObj, fForward );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Add extra buffers.]
+
+ Description [This is needed to make sure that forward retiming
+ works correctly. This has to do with the nodes in the TFO cone
+ of the PIs having multiple incoming edges.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkRetimeMinAreaAddBuffers( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vFeeds, * vFanouts;
+ Abc_Obj_t * pObj, * pFanin, * pFanout, * pBuffer;
+ int i, k;
+ // collect all nodes that are feeding into the marked nodes
+ Abc_NtkIncrementTravId(pNtk);
+ vFeeds = Vec_PtrAlloc( 100 );
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ if ( !pObj->fMarkA )
+ continue;
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ if ( !pFanin->fMarkA && !Abc_NodeIsTravIdCurrent(pFanin) )
+ {
+ Abc_NodeSetTravIdCurrent( pFanin );
+ Vec_PtrPush( vFeeds, pFanin );
+ }
+ }
+ // add buffers for each such node
+ vFanouts = Vec_PtrAlloc( 100 );
+ Vec_PtrForEachEntry( vFeeds, pObj, i )
+ {
+ // create and remember the buffers
+ pBuffer = Abc_NtkCreateNodeBuf( pNtk, pObj );
+ Vec_PtrWriteEntry( vFeeds, i, pBuffer );
+ // patch the fanin of each marked fanout to point to the buffer
+ Abc_NodeCollectFanouts( pObj, vFanouts );
+ Vec_PtrForEachEntry( vFanouts, pFanout, k )
+ if ( pFanout->fMarkA )
+ Abc_ObjPatchFanin( pFanout, pObj, pBuffer );
+ }
+ Vec_PtrFree( vFanouts );
+ // mark the new buffers
+ Vec_PtrForEachEntry( vFeeds, pObj, i )
+ pObj->fMarkA = 1;
+ return vFeeds;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes extra buffers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRetimeMinAreaRemoveBuffers( Abc_Ntk_t * pNtk, Vec_Ptr_t * vBuffers )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ Vec_PtrForEachEntry( vBuffers, pObj, i )
+ {
+ Abc_ObjTransferFanout( pObj, Abc_ObjFanin0(pObj) );
+ Abc_NtkDeleteObj( pObj );
+ }
+ Vec_PtrFree( vBuffers );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the results of simulating one node.]
+
+ Description [Assumes that fanins have pCopy set to the input values.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_ObjSopSimulate( Abc_Obj_t * pObj )
+{
+ char * pCube, * pSop = pObj->pData;
+ int nVars, Value, v, ResOr, ResAnd, ResVar;
+ assert( pSop && !Abc_SopIsExorType(pSop) );
+ // simulate the SOP of the node
+ ResOr = 0;
+ nVars = Abc_SopGetVarNum(pSop);
+ Abc_SopForEachCube( pSop, nVars, pCube )
+ {
+ ResAnd = 1;
+ Abc_CubeForEachVar( pCube, Value, v )
+ {
+ if ( Value == '0' )
+ ResVar = 1 ^ ((int)Abc_ObjFanin(pObj, v)->pCopy);
+ else if ( Value == '1' )
+ ResVar = (int)Abc_ObjFanin(pObj, v)->pCopy;
+ else
+ continue;
+ ResAnd &= ResVar;
+ }
+ ResOr |= ResAnd;
+ }
+ // complement the result if necessary
+ if ( !Abc_SopGetPhase(pSop) )
+ ResOr ^= 1;
+ return ResOr;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute initial values.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRetimeMinAreaInitValue_rec( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ // skip visited nodes
+ if ( Abc_NodeIsTravIdCurrent(pObj) )
+ return (int)pObj->pCopy;
+ Abc_NodeSetTravIdCurrent(pObj);
+ // consider the case of a latch output
+ if ( Abc_ObjIsBi(pObj) )
+ {
+ assert( Abc_ObjIsLatch(Abc_ObjFanin0(pObj)) );
+ pObj->pCopy = (void *)Abc_NtkRetimeMinAreaInitValue_rec( Abc_ObjFanin0(pObj) );
+ return (int)pObj->pCopy;
+ }
+ assert( Abc_ObjIsNode(pObj) );
+ // visit the fanins
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ Abc_NtkRetimeMinAreaInitValue_rec( pFanin );
+ // compute the value of the node
+ pObj->pCopy = (void *)Abc_ObjSopSimulate(pObj);
+ return (int)pObj->pCopy;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute initial values.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRetimeMinAreaInitValue( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ // transfer initial values to pCopy and mark the latches
+ Abc_NtkIncrementTravId(pNtk);
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pObj->pCopy = (void *)Abc_LatchIsInit1(pObj);
+ Abc_NodeSetTravIdCurrent( pObj );
+ }
+ // propagate initial values
+ Vec_PtrForEachEntry( vMinCut, pObj, i )
+ Abc_NtkRetimeMinAreaInitValue_rec( pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs min-area retiming backward.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkRetimeMinAreaConstructNtk_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ // skip visited nodes
+ if ( Abc_NodeIsTravIdCurrent(pObj) )
+ return pObj->pCopy;
+ Abc_NodeSetTravIdCurrent(pObj);
+ // consider the case of a latch output
+ if ( Abc_ObjIsBo(pObj) )
+ return Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, Abc_ObjFanin0(pObj) );
+ assert( Abc_ObjIsNode(pObj) );
+ // visit the fanins
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, pFanin );
+ // compute the value of the node
+ Abc_NtkDupObj( pNtkNew, pObj, 0 );
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
+ return pObj->pCopy;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the network from computing initial state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkRetimeMinAreaConstructNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pObjNew;
+ int i;
+ // create new network
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
+ // set mapping of new latches into the PIs of the network
+ Abc_NtkIncrementTravId(pNtk);
+ Vec_PtrForEachEntry( vMinCut, pObj, i )
+ {
+ pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
+ Abc_NodeSetTravIdCurrent( pObj );
+ }
+ // construct the network recursively
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pObjNew = Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, Abc_ObjFanin0(pObj) );
+ Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pObjNew );
+ }
+ // assign dummy node names
+ Abc_NtkAddDummyPiNames( pNtkNew );
+ Abc_NtkAddDummyPoNames( pNtkNew );
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ fprintf( stdout, "Abc_NtkRetimeMinAreaConstructNtk(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the network after backward retiming.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRetimeMinAreaUpdateLatches( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward )
+{
+ Vec_Ptr_t * vCis, * vCos, * vBoxes, * vBoxesNew, * vFanouts;
+ Abc_Obj_t * pObj, * pLatch, * pLatchIn, * pLatchOut, * pFanout;
+ int i, k;
+ // create new latches
+ Vec_PtrShrink( pNtk->vCis, Abc_NtkCiNum(pNtk) - Abc_NtkLatchNum(pNtk) );
+ Vec_PtrShrink( pNtk->vCos, Abc_NtkCoNum(pNtk) - Abc_NtkLatchNum(pNtk) );
+ vCis = pNtk->vCis; pNtk->vCis = NULL;
+ vCos = pNtk->vCos; pNtk->vCos = NULL;
+ vBoxes = pNtk->vBoxes; pNtk->vBoxes = NULL;
+ // transfer boxes
+ vBoxesNew = Vec_PtrAlloc(100);
+ Vec_PtrForEachEntry( vBoxes, pObj, i )
+ if ( !Abc_ObjIsLatch(pObj) )
+ Vec_PtrPush( vBoxesNew, pObj );
+ // create or reuse latches
+ Abc_NtkIncrementTravId(pNtk);
+ vFanouts = Vec_PtrAlloc( 100 );
+ Vec_PtrForEachEntry( vMinCut, pObj, i )
+ {
+ if ( Abc_ObjIsCi(pObj) && fForward )
+ {
+ pLatchOut = pObj;
+ pLatch = Abc_ObjFanin0(pLatchOut);
+ pLatchIn = Abc_ObjFanin0(pLatch);
+ assert( Abc_ObjIsBi(pLatchOut) && Abc_ObjIsLatch(pLatch) && Abc_ObjIsBo(pLatchIn) );
+ // mark the latch as reused
+ Abc_NodeSetTravIdCurrent( pLatch );
+ }
+ else if ( Abc_ObjIsCo(pObj) && !fForward )
+ {
+ pLatchIn = pObj;
+ pLatch = Abc_ObjFanout0(pLatchIn);
+ pLatchOut = Abc_ObjFanout0(pLatch);
+ assert( Abc_ObjIsBi(pLatchOut) && Abc_ObjIsLatch(pLatch) && Abc_ObjIsBo(pLatchIn) );
+ // mark the latch as reused
+ Abc_NodeSetTravIdCurrent( pLatch );
+ }
+ else
+ {
+ pLatchOut = Abc_NtkCreateBi(pNtk);
+ pLatch = Abc_NtkCreateLatch(pNtk);
+ pLatchIn = Abc_NtkCreateBo(pNtk);
+ Abc_ObjAssignName( pLatchOut, Abc_ObjName(pLatchOut), NULL );
+ Abc_ObjAssignName( pLatchIn, Abc_ObjName(pLatchIn), NULL );
+ // connect
+ Abc_ObjAddFanin( pLatchOut, pLatch );
+ Abc_ObjAddFanin( pLatch, pLatchIn );
+ if ( fForward )
+ {
+ Abc_ObjTransferFanout( pObj, pLatchOut );
+ pLatch->pData = (void *)(pObj->pCopy? ABC_INIT_ONE : ABC_INIT_ZERO);
+ }
+ else
+ {
+ // redirect unmarked edges
+ Abc_NodeCollectFanouts( pObj, vFanouts );
+ Vec_PtrForEachEntry( vFanouts, pFanout, k )
+ if ( !pFanout->fMarkA )
+ Abc_ObjPatchFanin( pFanout, pObj, pLatchOut );
+ }
+ // connect latch to the node
+ Abc_ObjAddFanin( pLatchIn, pObj );
+ }
+ Vec_PtrPush( vCis, pLatchOut );
+ Vec_PtrPush( vBoxesNew, pLatch );
+ Vec_PtrPush( vCos, pLatchIn );
+ }
+ Vec_PtrFree( vFanouts );
+ // remove useless latches
+ Vec_PtrForEachEntry( vBoxes, pObj, i )
+ {
+ if ( !Abc_ObjIsLatch(pObj) )
+ continue;
+ if ( Abc_NodeIsTravIdCurrent(pObj) )
+ continue;
+ pLatchOut = Abc_ObjFanout0(pObj);
+ pLatch = pObj;
+ pLatchIn = Abc_ObjFanin0(pObj);
+ Abc_ObjTransferFanout( pLatchOut, Abc_ObjFanin0(pLatchIn) );
+ Abc_NtkDeleteObj( pLatchOut );
+ Abc_NtkDeleteObj( pObj );
+ Abc_NtkDeleteObj( pLatchIn );
+ }
+ // set the arrays
+ pNtk->vCis = vCis;
+ pNtk->vCos = vCos;
+ pNtk->vBoxes = vBoxesNew;
+ Vec_PtrFree( vBoxes );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/ret/retBwd.c b/src/opt/ret/retBwd.c
new file mode 100644
index 00000000..7eefc4e0
--- /dev/null
+++ b/src/opt/ret/retBwd.c
@@ -0,0 +1,65 @@
+/**CFile****************************************************************
+
+ FileName [retBwd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Retiming package.]
+
+ Synopsis [Most backward retiming.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: retBwd.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "retInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ printf( "Not implemented.\n" );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/ret/retCore.c b/src/opt/ret/retCore.c
new file mode 100644
index 00000000..541f5962
--- /dev/null
+++ b/src/opt/ret/retCore.c
@@ -0,0 +1,76 @@
+/**CFile****************************************************************
+
+ FileName [retCore.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Retiming package.]
+
+ Synopsis [The core retiming procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: retCore.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "retInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Implementation of retiming.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fVerbose )
+{
+ int RetValue;
+ assert( Mode > 0 && Mode < 6 );
+ // perform forward retiming
+ switch ( Mode )
+ {
+ case 1: // forward
+ RetValue = Abc_NtkRetimeForward( pNtk, fVerbose );
+ break;
+ case 2: // backward
+ RetValue = Abc_NtkRetimeBackward( pNtk, fVerbose );
+ break;
+ case 3: // min-area
+ RetValue = Abc_NtkRetimeMinArea( pNtk, fVerbose );
+ break;
+ case 4: // min-delay
+ RetValue = Abc_NtkRetimeMinDelay( pNtk, fVerbose );
+ break;
+ case 5: // min-area + min-delay
+ RetValue = Abc_NtkRetimeMinArea( pNtk, fVerbose );
+ RetValue += Abc_NtkRetimeMinDelay( pNtk, fVerbose );
+ break;
+ default:
+ printf( "Unknown retiming option.\n" );
+ break;
+ }
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/ret/retDelay.c b/src/opt/ret/retDelay.c
new file mode 100644
index 00000000..b7ccc570
--- /dev/null
+++ b/src/opt/ret/retDelay.c
@@ -0,0 +1,65 @@
+/**CFile****************************************************************
+
+ FileName [retDelay.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Retiming package.]
+
+ Synopsis [Incremental retiming for optimum delay.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: retDelay.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "retInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ printf( "Not implemented.\n" );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/ret/retFlow.c b/src/opt/ret/retFlow.c
new file mode 100644
index 00000000..9b8393f3
--- /dev/null
+++ b/src/opt/ret/retFlow.c
@@ -0,0 +1,462 @@
+/**CFile****************************************************************
+
+ FileName [retFlow.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Implementation of maximum flow (min-area retiming).]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: retFlow.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "retInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int Abc_ObjSetPath( Abc_Obj_t * pObj, Abc_Obj_t * pNext ) { pObj->pCopy = pNext; return 1; }
+static inline Abc_Obj_t * Abc_ObjGetPath( Abc_Obj_t * pObj ) { return pObj->pCopy; }
+static inline Abc_Obj_t * Abc_ObjGetFanoutPath( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanout;
+ int i;
+ assert( Abc_ObjGetPath(pObj) );
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ if ( Abc_ObjGetPath(pFanout) == pObj )
+ return pFanout;
+ return NULL;
+}
+static inline Abc_Obj_t * Abc_ObjGetFaninPath( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ assert( Abc_ObjGetPath(pObj) );
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ if ( Abc_ObjGetPath(pFanin) == pObj )
+ return pFanin;
+ return NULL;
+}
+
+static int Abc_NtkMaxFlowPath( Abc_Ntk_t * pNtk, int * pStart, int fForward );
+static int Abc_NtkMaxFlowBwdPath_rec( Abc_Obj_t * pObj );
+static int Abc_NtkMaxFlowFwdPath_rec( Abc_Obj_t * pObj );
+static Vec_Ptr_t * Abc_NtkMaxFlowMinCut( Abc_Ntk_t * pNtk );
+static int Abc_NtkMaxFlowVerifyCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward );
+static void Abc_NtkMaxFlowPrintFlow( Abc_Ntk_t * pNtk, int fForward );
+static void Abc_NtkMaxFlowPrintCut( Vec_Ptr_t * vMinCut );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Test-bench for the max-flow computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vMinCut;
+ Abc_Obj_t * pObj;
+ int i;
+
+ // forward flow
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ pObj->fMarkA = 1;
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ pObj->fMarkA = Abc_ObjFanin0(pObj)->fMarkA = 1;
+ vMinCut = Abc_NtkMaxFlow( pNtk, 1, 1 );
+ Vec_PtrFree( vMinCut );
+ Abc_NtkCleanMarkA( pNtk );
+
+ // backward flow
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ pObj->fMarkA = 1;
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ pObj->fMarkA = Abc_ObjFanout0(pObj)->fMarkA = 1;
+ vMinCut = Abc_NtkMaxFlow( pNtk, 0, 1 );
+ Vec_PtrFree( vMinCut );
+ Abc_NtkCleanMarkA( pNtk );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implementation of max-flow/min-cut computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkMaxFlow( Abc_Ntk_t * pNtk, int fForward, int fVerbose )
+{
+ Vec_Ptr_t * vMinCut;
+ int Flow, RetValue;
+ int clk = clock();
+ int Start = 0;
+
+ // find the max-flow
+ Abc_NtkCleanCopy( pNtk );
+ for ( Flow = 0; Abc_NtkMaxFlowPath( pNtk, &Start, fForward ); Flow++ );
+// Abc_NtkMaxFlowPrintFlow( pNtk, fForward );
+
+ // find the min-cut with the smallest volume
+ RetValue = Abc_NtkMaxFlowPath( pNtk, NULL, fForward );
+ assert( RetValue == 0 );
+ vMinCut = Abc_NtkMaxFlowMinCut( pNtk );
+ if ( !Abc_NtkMaxFlowVerifyCut(pNtk, vMinCut, fForward) )
+ printf( "Abc_NtkMaxFlow() error! The computed min-cut is not a cut!\n" );
+
+ // report the results
+ printf( "Latches = %6d. %s max-flow = %6d. Min-cut = %6d. ",
+ Abc_NtkLatchNum(pNtk), fForward? "Forward " : "Backward", Flow, Vec_PtrSize(vMinCut) );
+PRT( "Time", clock() - clk );
+
+// Abc_NtkMaxFlowPrintCut( vMinCut );
+ return vMinCut;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds and augments one path.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkMaxFlowPath( Abc_Ntk_t * pNtk, int * pStart, int fForward )
+{
+ Abc_Obj_t * pLatch;
+ int i, LatchStart = pStart? *pStart : 0;
+ Abc_NtkIncrementTravId(pNtk);
+ Vec_PtrForEachEntryStart( pNtk->vBoxes, pLatch, i, LatchStart )
+ {
+ if ( !Abc_ObjIsLatch(pLatch) )
+ continue;
+ if ( fForward )
+ {
+ assert( !Abc_ObjFanout0(pLatch)->fMarkA );
+ if ( Abc_NtkMaxFlowFwdPath_rec( Abc_ObjFanout0(pLatch) ) )
+ {
+ if ( pStart ) *pStart = i + 1;
+ return 1;
+ }
+ }
+ else
+ {
+ assert( !Abc_ObjFanin0(pLatch)->fMarkA );
+ if ( Abc_NtkMaxFlowBwdPath_rec( Abc_ObjFanin0(pLatch) ) )
+ {
+ if ( pStart ) *pStart = i + 1;
+ return 1;
+ }
+ }
+ }
+ if ( pStart ) *pStart = 0;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Tries to find an augmenting path originating in this node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkMaxFlowBwdPath_rec( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanout, * pFanin;
+ int i;
+ // skip visited nodes
+ if ( Abc_NodeIsTravIdCurrent(pObj) )
+ return 0;
+ Abc_NodeSetTravIdCurrent(pObj);
+ // process node without flow
+ if ( !Abc_ObjGetPath(pObj) )
+ {
+ // start the path if we reached a terminal node
+ if ( pObj->fMarkA )
+ return Abc_ObjSetPath( pObj, (void *)1 );
+ // explore the fanins
+ Abc_ObjForEachFanin( pObj, pFanin, i )
+ if ( Abc_NtkMaxFlowBwdPath_rec(pFanin) )
+ return Abc_ObjSetPath( pObj, pFanin );
+ return 0;
+ }
+ // pObj has flow - find the fanout with flow
+ pFanout = Abc_ObjGetFanoutPath( pObj );
+ if ( pFanout == NULL )
+ return 0;
+ // go through the fanins of the fanout with flow
+ Abc_ObjForEachFanin( pFanout, pFanin, i )
+ if ( pFanin != pObj && Abc_NtkMaxFlowBwdPath_rec( pFanin ) )
+ return Abc_ObjSetPath( pFanout, pFanin );
+ // try the fanout
+ if ( Abc_NtkMaxFlowBwdPath_rec( pFanout ) )
+ return Abc_ObjSetPath( pFanout, NULL );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Tries to find an augmenting path originating in this node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkMaxFlowFwdPath_rec( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanout, * pFanin;
+ int i;
+ // skip visited nodes
+ if ( Abc_NodeIsTravIdCurrent(pObj) )
+ return 0;
+ Abc_NodeSetTravIdCurrent(pObj);
+ // process node without flow
+ if ( !Abc_ObjGetPath(pObj) )
+ {
+ // start the path if we reached a terminal node
+ if ( pObj->fMarkA )
+ return Abc_ObjSetPath( pObj, (void *)1 );
+ // explore the fanins
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ if ( Abc_NtkMaxFlowFwdPath_rec(pFanout) )
+ return Abc_ObjSetPath( pObj, pFanout );
+ return 0;
+ }
+ // pObj has flow - find the fanout with flow
+ pFanin = Abc_ObjGetFaninPath( pObj );
+ if ( pFanin == NULL )
+ return 0;
+ // go through the fanins of the fanout with flow
+ Abc_ObjForEachFanout( pFanin, pFanout, i )
+ if ( pFanout != pObj && Abc_NtkMaxFlowFwdPath_rec( pFanout ) )
+ return Abc_ObjSetPath( pFanin, pFanout );
+ // try the fanout
+ if ( Abc_NtkMaxFlowFwdPath_rec( pFanin ) )
+ return Abc_ObjSetPath( pFanin, NULL );
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Find one minumum cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkMaxFlowMinCut( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vMinCut;
+ Abc_Obj_t * pObj;
+ int i;
+ // collect the cut nodes
+ vMinCut = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) );
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ // node without flow is not a cut node
+ if ( !Abc_ObjGetPath(pObj) )
+ continue;
+ // unvisited node is below the cut
+ if ( !Abc_NodeIsTravIdCurrent(pObj) )
+ continue;
+ // add terminal with flow or node whose path is not visited
+ if ( pObj->fMarkA || !Abc_NodeIsTravIdCurrent( Abc_ObjGetPath(pObj) ) )
+ Vec_PtrPush( vMinCut, pObj );
+ }
+ return vMinCut;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies the min-cut is indeed a cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkMaxFlowVerifyCut_rec( Abc_Obj_t * pObj, int fForward )
+{
+ Abc_Obj_t * pNext;
+ int i;
+ // skip visited nodes
+ if ( Abc_NodeIsTravIdCurrent(pObj) )
+ return 1;
+ Abc_NodeSetTravIdCurrent(pObj);
+ // visit the node
+ if ( fForward )
+ {
+ if ( Abc_ObjIsCo(pObj) )
+ return 0;
+ // explore the fanouts
+ Abc_ObjForEachFanout( pObj, pNext, i )
+ if ( !Abc_NtkMaxFlowVerifyCut_rec(pNext, fForward) )
+ return 0;
+ }
+ else
+ {
+ if ( Abc_ObjIsCi(pObj) )
+ return 0;
+ // explore the fanins
+ Abc_ObjForEachFanin( pObj, pNext, i )
+ if ( !Abc_NtkMaxFlowVerifyCut_rec(pNext, fForward) )
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies the min-cut is indeed a cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkMaxFlowVerifyCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ // mark the cut with the current traversal ID
+ Abc_NtkIncrementTravId(pNtk);
+ Vec_PtrForEachEntry( vMinCut, pObj, i )
+ Abc_NodeSetTravIdCurrent( pObj );
+ // search from the latches for a path to the COs/CIs
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ if ( fForward )
+ {
+ assert( !Abc_ObjFanout0(pObj)->fMarkA );
+ if ( !Abc_NtkMaxFlowVerifyCut_rec( Abc_ObjFanout0(pObj), fForward ) )
+ return 0;
+ }
+ else
+ {
+ assert( !Abc_ObjFanin0(pObj)->fMarkA );
+ if ( !Abc_NtkMaxFlowVerifyCut_rec( Abc_ObjFanin0(pObj), fForward ) )
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the flows.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMaxFlowPrintFlow( Abc_Ntk_t * pNtk, int fForward )
+{
+ Abc_Obj_t * pLatch, * pNext, * pPrev;
+ int i;
+ if ( fForward )
+ {
+ Vec_PtrForEachEntry( pNtk->vBoxes, pLatch, i )
+ {
+ assert( !Abc_ObjFanout0(pLatch)->fMarkA );
+ if ( Abc_ObjGetPath(Abc_ObjFanout0(pLatch)) == NULL ) // no flow through this latch
+ continue;
+ printf( "Path = " );
+ for ( pNext = Abc_ObjFanout0(pLatch); pNext != (void *)1; pNext = Abc_ObjGetPath(pNext) )
+ {
+ printf( "%s(%d) ", Abc_ObjName(pNext), pNext->Id );
+ pPrev = pNext;
+ }
+ if ( !Abc_ObjIsPo(pPrev) )
+ printf( "%s(%d) ", Abc_ObjName(Abc_ObjFanout0(pPrev)), Abc_ObjFanout0(pPrev)->Id );
+ printf( "\n" );
+ }
+ }
+ else
+ {
+ Vec_PtrForEachEntry( pNtk->vBoxes, pLatch, i )
+ {
+ assert( !Abc_ObjFanin0(pLatch)->fMarkA );
+ if ( Abc_ObjGetPath(Abc_ObjFanin0(pLatch)) == NULL ) // no flow through this latch
+ continue;
+ printf( "Path = " );
+ for ( pNext = Abc_ObjFanin0(pLatch); pNext != (void *)1; pNext = Abc_ObjGetPath(pNext) )
+ {
+ printf( "%s(%d) ", Abc_ObjName(pNext), pNext->Id );
+ pPrev = pNext;
+ }
+ if ( !Abc_ObjIsPi(pPrev) )
+ printf( "%s(%d) ", Abc_ObjName(Abc_ObjFanin0(pPrev)), Abc_ObjFanin0(pPrev)->Id );
+ printf( "\n" );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the min-cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMaxFlowPrintCut( Vec_Ptr_t * vMinCut )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ printf( "Min-cut: " );
+ Vec_PtrForEachEntry( vMinCut, pObj, i )
+ printf( "%d ", pObj->Id );
+ printf( "\n" );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/ret/retFwd.c b/src/opt/ret/retFwd.c
new file mode 100644
index 00000000..c33abc30
--- /dev/null
+++ b/src/opt/ret/retFwd.c
@@ -0,0 +1,65 @@
+/**CFile****************************************************************
+
+ FileName [retFwd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Retiming package.]
+
+ Synopsis [Most forward retiming.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: retFwd.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "retInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRetimeForward( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ printf( "Not implemented.\n" );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/ret/retInit.c b/src/opt/ret/retInit.c
new file mode 100644
index 00000000..169d5a63
--- /dev/null
+++ b/src/opt/ret/retInit.c
@@ -0,0 +1,71 @@
+/**CFile****************************************************************
+
+ FileName [ret_.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Retiming package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: ret_.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "retInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes initial values of the new latches.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, int fVerbose )
+{
+ Abc_Obj_t * pLatch;
+ int * pModel, RetValue, clk, i;
+ if ( fVerbose )
+ printf( "The number of ANDs in the AIG = %5d.\n", Abc_NtkNodeNum(pNtkMiter) );
+ // solve the miter
+clk = clock();
+ RetValue = Abc_NtkMiterSat( pNtkMiter, (sint64)500000, (sint64)50000000, 0, 0, NULL, NULL );
+if ( fVerbose && clock() - clk > 100 )
+{
+PRT( "SAT solving time", clock() - clk );
+}
+ // analyze the result
+ if ( RetValue == 1 )
+ printf( "Abc_NtkRetimeInitialValues(): The problem is unsatisfiable. DC latch values are used.\n" );
+ else if ( RetValue == -1 )
+ printf( "Abc_NtkRetimeInitialValues(): The SAT problem timed out. DC latch values are used.\n" );
+ // set the values of the latches
+ pModel = pNtkMiter->pModel; pNtkMiter->pModel = NULL;
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ pLatch->pData = (void *)(pModel? (pModel[i]? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC);
+ FREE( pModel );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/ret/retInt.h b/src/opt/ret/retInt.h
new file mode 100644
index 00000000..2cb465fa
--- /dev/null
+++ b/src/opt/ret/retInt.h
@@ -0,0 +1,68 @@
+/**CFile****************************************************************
+
+ FileName [retInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Retiming package.]
+
+ Synopsis [Internal declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: retInt.h,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __RET_INT_H__
+#define __RET_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== retArea.c ========================================================*/
+extern int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fVerbose );
+/*=== retBwd.c ========================================================*/
+extern int Abc_NtkRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose );
+/*=== retCore.c ========================================================*/
+extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fVerbose );
+/*=== retDelay.c ========================================================*/
+extern int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, int fVerbose );
+/*=== retFlow.c ========================================================*/
+extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk );
+extern Vec_Ptr_t * Abc_NtkMaxFlow( Abc_Ntk_t * pNtk, int fForward, int fVerbose );
+/*=== retFwd.c ========================================================*/
+extern int Abc_NtkRetimeForward( Abc_Ntk_t * pNtk, int fVerbose );
+/*=== retInit.c ========================================================*/
+extern void Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, int fVerbose );
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/ret/ret_.c b/src/opt/ret/ret_.c
new file mode 100644
index 00000000..89625e17
--- /dev/null
+++ b/src/opt/ret/ret_.c
@@ -0,0 +1,48 @@
+/**CFile****************************************************************
+
+ FileName [ret_.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Retiming package.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Oct 31, 2006.]
+
+ Revision [$Id: ret_.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "retInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/rwr/rwr.h b/src/opt/rwr/rwr.h
index f8c40a7c..eda2b85f 100644
--- a/src/opt/rwr/rwr.h
+++ b/src/opt/rwr/rwr.h
@@ -106,10 +106,10 @@ struct Rwr_Node_t_ // 24 bytes
};
// manipulation of complemented attributes
-static inline bool Rwr_IsComplement( Rwr_Node_t * p ) { return (bool)(((unsigned)p) & 01); }
-static inline Rwr_Node_t * Rwr_Regular( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) & ~01); }
-static inline Rwr_Node_t * Rwr_Not( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) ^ 01); }
-static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_Node_t *)((unsigned)(p) ^ (c)); }
+static inline bool Rwr_IsComplement( Rwr_Node_t * p ) { return (bool)(((unsigned long)p) & 01); }
+static inline Rwr_Node_t * Rwr_Regular( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned long)(p) & ~01); }
+static inline Rwr_Node_t * Rwr_Not( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned long)(p) ^ 01); }
+static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_Node_t *)((unsigned long)(p) ^ (c)); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
diff --git a/src/sat/fraig/fraig.h b/src/sat/fraig/fraig.h
index 84363efe..7f15c58f 100644
--- a/src/sat/fraig/fraig.h
+++ b/src/sat/fraig/fraig.h
@@ -104,10 +104,10 @@ struct Prove_ParamsStruct_t_
////////////////////////////////////////////////////////////////////////
// macros working with complemented attributes of the nodes
-#define Fraig_IsComplement(p) (((int)((long) (p) & 01)))
-#define Fraig_Regular(p) ((Fraig_Node_t *)((unsigned)(p) & ~01))
-#define Fraig_Not(p) ((Fraig_Node_t *)((long)(p) ^ 01))
-#define Fraig_NotCond(p,c) ((Fraig_Node_t *)((long)(p) ^ (c)))
+#define Fraig_IsComplement(p) (((int)((unsigned long) (p) & 01)))
+#define Fraig_Regular(p) ((Fraig_Node_t *)((unsigned long)(p) & ~01))
+#define Fraig_Not(p) ((Fraig_Node_t *)((unsigned long)(p) ^ 01))
+#define Fraig_NotCond(p,c) ((Fraig_Node_t *)((unsigned long)(p) ^ (c)))
// these are currently not used
#define Fraig_Ref(p)
diff --git a/src/temp/aig-alan.tar.gz b/src/temp/aig-alan.tar.gz
new file mode 100644
index 00000000..b61827ad
--- /dev/null
+++ b/src/temp/aig-alan.tar.gz
Binary files differ
diff --git a/src/temp/aig/aig.h b/src/temp/aig/aig.h
index fbf234ac..0dfc3f11 100644
--- a/src/temp/aig/aig.h
+++ b/src/temp/aig/aig.h
@@ -30,6 +30,11 @@ extern "C" {
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+
#include "vec.h"
////////////////////////////////////////////////////////////////////////
@@ -104,16 +109,20 @@ struct Aig_Man_t_
#define AIG_MIN(a,b) (((a) < (b))? (a) : (b))
#define AIG_MAX(a,b) (((a) > (b))? (a) : (b))
+#ifndef PRT
+#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
+#endif
+
static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
static inline int Aig_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
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)); }
-static inline Aig_Obj_t * Aig_Regular( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned)(p) & ~01); }
-static inline Aig_Obj_t * Aig_Not( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned)(p) ^ 01); }
-static inline Aig_Obj_t * Aig_NotCond( Aig_Obj_t * p, int c ) { return (Aig_Obj_t *)((unsigned)(p) ^ (c)); }
-static inline int Aig_IsComplement( Aig_Obj_t * p ) { return (int )(((unsigned)p) & 01); }
+static inline Aig_Obj_t * Aig_Regular( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) & ~01); }
+static inline Aig_Obj_t * Aig_Not( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) ^ 01); }
+static inline Aig_Obj_t * Aig_NotCond( Aig_Obj_t * p, int c ) { return (Aig_Obj_t *)((unsigned long)(p) ^ (c)); }
+static inline int Aig_IsComplement( Aig_Obj_t * p ) { return (int )(((unsigned long)p) & 01); }
static inline Aig_Obj_t * Aig_ManConst0( Aig_Man_t * p ) { return Aig_Not(p->pConst1); }
static inline Aig_Obj_t * Aig_ManConst1( Aig_Man_t * p ) { return p->pConst1; }
diff --git a/src/temp/aig/aigBalance.c b/src/temp/aig/aigBalance.c
index 1abc672d..8806b654 100644
--- a/src/temp/aig/aigBalance.c
+++ b/src/temp/aig/aigBalance.c
@@ -17,7 +17,7 @@
Revision [$Id: aigBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
-
+
#include "aig.h"
////////////////////////////////////////////////////////////////////////
diff --git a/src/temp/aig/cudd2.c b/src/temp/aig/cudd2.c
index 95663420..3cc38260 100644
--- a/src/temp/aig/cudd2.c
+++ b/src/temp/aig/cudd2.c
@@ -53,7 +53,9 @@ static Aig_CuddMan_t * s_pCuddMan = NULL;
void Cudd2_Init( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd )
{
int v;
- assert( s_pCuddMan == NULL );
+ // start the BDD-to-AIG manager when the first BDD manager is allocated
+ if ( s_pCuddMan != NULL )
+ return;
s_pCuddMan = ALLOC( Aig_CuddMan_t, 1 );
s_pCuddMan->pAig = Aig_ManStart();
s_pCuddMan->pTable = st_init_table( st_ptrcmp, st_ptrhash );
@@ -127,6 +129,22 @@ static void Cudd2_SetArg( Aig_Obj_t * pNode, void * pResult )
/**Function*************************************************************
+ Synopsis [Registers constant 1 node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddOne( void * pCudd, void * pResult )
+{
+ Cudd2_SetArg( Aig_ManConst1(s_pCuddMan->pAig), pResult );
+}
+
+/**Function*************************************************************
+
Synopsis [Adds elementary variable.]
Description []
diff --git a/src/temp/aig/cudd2.h b/src/temp/aig/cudd2.h
index 800ee33f..69711c11 100644
--- a/src/temp/aig/cudd2.h
+++ b/src/temp/aig/cudd2.h
@@ -25,6 +25,11 @@
extern "C" {
#endif
+// HA: Added for printing messages
+#ifndef MSG
+#define MSG(msg) (printf("%s = \n",(msg)));
+#endif
+
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
@@ -52,6 +57,7 @@ extern "C" {
extern void Cudd2_Init ( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd );
extern void Cudd2_Quit ( void * pCudd );
+extern void Cudd2_bddOne ( void * pCudd, void * pResult );
extern void Cudd2_bddIthVar ( void * pCudd, int iVar, void * pResult );
extern void Cudd2_bddAnd ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
extern void Cudd2_bddOr ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
diff --git a/src/temp/aig_free/aig.h b/src/temp/aig_free/aig.h
new file mode 100644
index 00000000..0dfc3f11
--- /dev/null
+++ b/src/temp/aig_free/aig.h
@@ -0,0 +1,321 @@
+/**CFile****************************************************************
+
+ FileName [aig.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: aig.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __AIG_H__
+#define __AIG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+
+#include "vec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Aig_Man_t_ Aig_Man_t;
+typedef struct Aig_Obj_t_ Aig_Obj_t;
+typedef int Aig_Edge_t;
+
+// object types
+typedef enum {
+ AIG_NONE, // 0: non-existent object
+ AIG_CONST1, // 1: constant 1
+ AIG_PI, // 2: primary input
+ AIG_PO, // 3: primary output
+ AIG_AND, // 4: AND node
+ AIG_EXOR, // 5: EXOR node
+ AIG_VOID // 6: unused object
+} Aig_Type_t;
+
+// the AIG node
+struct Aig_Obj_t_ // 4 words
+{
+ void * pData; // misc
+ Aig_Obj_t * pFanin0; // fanin
+ Aig_Obj_t * pFanin1; // fanin
+ unsigned long Type : 3; // object type
+ unsigned long fPhase : 1; // value under 000...0 pattern
+ unsigned long fMarkA : 1; // multipurpose mask
+ unsigned long fMarkB : 1; // multipurpose mask
+ unsigned long nRefs : 26; // reference count (level)
+};
+
+// the AIG manager
+struct Aig_Man_t_
+{
+ // AIG nodes
+ Vec_Ptr_t * vPis; // the array of PIs
+ Vec_Ptr_t * vPos; // the array of POs
+ Aig_Obj_t * pConst1; // the constant 1 node
+ Aig_Obj_t Ghost; // the ghost node
+ // AIG node counters
+ int nObjs[AIG_VOID];// the number of objects by type
+ int nCreated; // the number of created objects
+ int nDeleted; // the number of deleted objects
+ // stuctural hash table
+ Aig_Obj_t ** pTable; // structural hash table
+ int nTableSize; // structural hash table size
+ // various data members
+ void * pData; // the temporary data
+ int nTravIds; // the current traversal ID
+ int fRefCount; // enables reference counting
+ int fCatchExor; // enables EXOR nodes
+ // memory management
+ Vec_Ptr_t * vChunks; // allocated memory pieces
+ Vec_Ptr_t * vPages; // memory pages used by nodes
+ Aig_Obj_t * pListFree; // the list of free nodes
+ // timing statistics
+ int time1;
+ int time2;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define AIG_MIN(a,b) (((a) < (b))? (a) : (b))
+#define AIG_MAX(a,b) (((a) > (b))? (a) : (b))
+
+#ifndef PRT
+#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
+#endif
+
+static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
+static inline int Aig_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
+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)); }
+
+static inline Aig_Obj_t * Aig_Regular( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) & ~01); }
+static inline Aig_Obj_t * Aig_Not( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned long)(p) ^ 01); }
+static inline Aig_Obj_t * Aig_NotCond( Aig_Obj_t * p, int c ) { return (Aig_Obj_t *)((unsigned long)(p) ^ (c)); }
+static inline int Aig_IsComplement( Aig_Obj_t * p ) { return (int )(((unsigned long)p) & 01); }
+
+static inline Aig_Obj_t * Aig_ManConst0( Aig_Man_t * p ) { return Aig_Not(p->pConst1); }
+static inline Aig_Obj_t * Aig_ManConst1( Aig_Man_t * p ) { return p->pConst1; }
+static inline Aig_Obj_t * Aig_ManGhost( Aig_Man_t * p ) { return &p->Ghost; }
+static inline Aig_Obj_t * Aig_ManPi( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPis, i); }
+
+static inline Aig_Edge_t Aig_EdgeCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; }
+static inline int Aig_EdgeId( Aig_Edge_t Edge ) { return Edge >> 1; }
+static inline int Aig_EdgeIsComplement( Aig_Edge_t Edge ) { return Edge & 1; }
+static inline Aig_Edge_t Aig_EdgeRegular( Aig_Edge_t Edge ) { return (Edge >> 1) << 1; }
+static inline Aig_Edge_t Aig_EdgeNot( Aig_Edge_t Edge ) { return Edge ^ 1; }
+static inline Aig_Edge_t Aig_EdgeNotCond( Aig_Edge_t Edge, int fCond ) { return Edge ^ fCond; }
+
+static inline int Aig_ManPiNum( Aig_Man_t * p ) { return p->nObjs[AIG_PI]; }
+static inline int Aig_ManPoNum( Aig_Man_t * p ) { return p->nObjs[AIG_PO]; }
+static inline int Aig_ManAndNum( Aig_Man_t * p ) { return p->nObjs[AIG_AND]; }
+static inline int Aig_ManExorNum( Aig_Man_t * p ) { return p->nObjs[AIG_EXOR]; }
+static inline int Aig_ManNodeNum( Aig_Man_t * p ) { return p->nObjs[AIG_AND]+p->nObjs[AIG_EXOR];}
+static inline int Aig_ManGetCost( Aig_Man_t * p ) { return p->nObjs[AIG_AND]+3*p->nObjs[AIG_EXOR]; }
+static inline int Aig_ManObjNum( Aig_Man_t * p ) { return p->nCreated - p->nDeleted; }
+
+static inline Aig_Type_t Aig_ObjType( Aig_Obj_t * pObj ) { return pObj->Type; }
+static inline int Aig_ObjIsNone( Aig_Obj_t * pObj ) { return pObj->Type == AIG_NONE; }
+static inline int Aig_ObjIsConst1( Aig_Obj_t * pObj ) { assert(!Aig_IsComplement(pObj)); return pObj->Type == AIG_CONST1; }
+static inline int Aig_ObjIsPi( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PI; }
+static inline int Aig_ObjIsPo( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PO; }
+static inline int Aig_ObjIsAnd( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND; }
+static inline int Aig_ObjIsExor( Aig_Obj_t * pObj ) { return pObj->Type == AIG_EXOR; }
+static inline int Aig_ObjIsNode( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND || pObj->Type == AIG_EXOR; }
+static inline int Aig_ObjIsTerm( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PI || pObj->Type == AIG_PO || pObj->Type == AIG_CONST1; }
+static inline int Aig_ObjIsHash( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND || pObj->Type == AIG_EXOR; }
+
+static inline int Aig_ObjIsMarkA( Aig_Obj_t * pObj ) { return pObj->fMarkA; }
+static inline void Aig_ObjSetMarkA( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; }
+static inline void Aig_ObjClearMarkA( Aig_Obj_t * pObj ) { pObj->fMarkA = 0; }
+
+static inline void Aig_ObjSetTravId( Aig_Obj_t * pObj, int TravId ) { pObj->pData = (void *)TravId; }
+static inline void Aig_ObjSetTravIdCurrent( Aig_Man_t * p, Aig_Obj_t * pObj ) { pObj->pData = (void *)p->nTravIds; }
+static inline void Aig_ObjSetTravIdPrevious( Aig_Man_t * p, Aig_Obj_t * pObj ) { pObj->pData = (void *)(p->nTravIds - 1); }
+static inline int Aig_ObjIsTravIdCurrent( Aig_Man_t * p, Aig_Obj_t * pObj ) { return (int )((int)pObj->pData == p->nTravIds); }
+static inline int Aig_ObjIsTravIdPrevious( Aig_Man_t * p, Aig_Obj_t * pObj ) { return (int )((int)pObj->pData == p->nTravIds - 1); }
+
+static inline int Aig_ObjTravId( Aig_Obj_t * pObj ) { return (int)pObj->pData; }
+static inline int Aig_ObjPhase( Aig_Obj_t * pObj ) { return pObj->fPhase; }
+static inline int Aig_ObjRefs( Aig_Obj_t * pObj ) { return pObj->nRefs; }
+static inline void Aig_ObjRef( Aig_Obj_t * pObj ) { pObj->nRefs++; }
+static inline void Aig_ObjDeref( Aig_Obj_t * pObj ) { assert( pObj->nRefs > 0 ); pObj->nRefs--; }
+static inline void Aig_ObjClearRef( Aig_Obj_t * pObj ) { pObj->nRefs = 0; }
+static inline int Aig_ObjFaninC0( Aig_Obj_t * pObj ) { return Aig_IsComplement(pObj->pFanin0); }
+static inline int Aig_ObjFaninC1( Aig_Obj_t * pObj ) { return Aig_IsComplement(pObj->pFanin1); }
+static inline Aig_Obj_t * Aig_ObjFanin0( Aig_Obj_t * pObj ) { return Aig_Regular(pObj->pFanin0); }
+static inline Aig_Obj_t * Aig_ObjFanin1( Aig_Obj_t * pObj ) { return Aig_Regular(pObj->pFanin1); }
+static inline Aig_Obj_t * Aig_ObjChild0( Aig_Obj_t * pObj ) { return pObj->pFanin0; }
+static inline Aig_Obj_t * Aig_ObjChild1( Aig_Obj_t * pObj ) { return pObj->pFanin1; }
+static inline Aig_Obj_t * Aig_ObjChild0Copy( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj)) : NULL; }
+static inline Aig_Obj_t * Aig_ObjChild1Copy( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj)) : NULL; }
+static inline int Aig_ObjLevel( Aig_Obj_t * pObj ) { return pObj->nRefs; }
+static inline int Aig_ObjLevelNew( Aig_Obj_t * pObj ) { return 1 + Aig_ObjIsExor(pObj) + AIG_MAX(Aig_ObjFanin0(pObj)->nRefs, Aig_ObjFanin1(pObj)->nRefs); }
+static inline void Aig_ObjClean( Aig_Obj_t * pObj ) { memset( pObj, 0, sizeof(Aig_Obj_t) ); }
+static inline int Aig_ObjWhatFanin( Aig_Obj_t * pObj, Aig_Obj_t * pFanin )
+{
+ if ( Aig_ObjFanin0(pObj) == pFanin ) return 0;
+ if ( Aig_ObjFanin1(pObj) == pFanin ) return 1;
+ assert(0); return -1;
+}
+static inline int Aig_ObjFanoutC( Aig_Obj_t * pObj, Aig_Obj_t * pFanout )
+{
+ if ( Aig_ObjFanin0(pFanout) == pObj ) return Aig_ObjFaninC0(pObj);
+ if ( Aig_ObjFanin1(pFanout) == pObj ) return Aig_ObjFaninC1(pObj);
+ assert(0); return -1;
+}
+
+// create the ghost of the new node
+static inline Aig_Obj_t * Aig_ObjCreateGhost( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type )
+{
+ Aig_Obj_t * pGhost;
+ assert( Type != AIG_AND || !Aig_ObjIsConst1(Aig_Regular(p0)) );
+ assert( p1 == NULL || !Aig_ObjIsConst1(Aig_Regular(p1)) );
+ assert( Type == AIG_PI || Aig_Regular(p0) != Aig_Regular(p1) );
+ pGhost = Aig_ManGhost(p);
+ pGhost->Type = Type;
+ pGhost->pFanin0 = p0 < p1? p0 : p1;
+ pGhost->pFanin1 = p0 < p1? p1 : p0;
+ return pGhost;
+}
+
+// internal memory manager
+static inline Aig_Obj_t * Aig_ManFetchMemory( Aig_Man_t * p )
+{
+ extern void Aig_ManAddMemory( Aig_Man_t * p );
+ Aig_Obj_t * pTemp;
+ if ( p->pListFree == NULL )
+ Aig_ManAddMemory( p );
+ pTemp = p->pListFree;
+ p->pListFree = *((Aig_Obj_t **)pTemp);
+ memset( pTemp, 0, sizeof(Aig_Obj_t) );
+ return pTemp;
+}
+static inline void Aig_ManRecycleMemory( Aig_Man_t * p, Aig_Obj_t * pEntry )
+{
+ pEntry->Type = AIG_NONE; // distinquishes dead node from live node
+ *((Aig_Obj_t **)pEntry) = p->pListFree;
+ p->pListFree = pEntry;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// ITERATORS ///
+////////////////////////////////////////////////////////////////////////
+
+// iterator over the primary inputs
+#define Aig_ManForEachPi( p, pObj, i ) \
+ Vec_PtrForEachEntry( p->vPis, pObj, i )
+// iterator over the primary outputs
+#define Aig_ManForEachPo( p, pObj, i ) \
+ Vec_PtrForEachEntry( p->vPos, pObj, i )
+// iterator over all objects, including those currently not used
+#define Aig_ManForEachNode( p, pObj, i ) \
+ for ( i = 0; i < p->nTableSize; i++ ) \
+ if ( ((pObj) = p->pTable[i]) == NULL ) {} else
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== aigBalance.c ========================================================*/
+extern Aig_Man_t * Aig_ManBalance( Aig_Man_t * p, int fUpdateLevel );
+extern Aig_Obj_t * Aig_NodeBalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel );
+/*=== aigCheck.c ========================================================*/
+extern int Aig_ManCheck( Aig_Man_t * p );
+/*=== aigDfs.c ==========================================================*/
+extern Vec_Ptr_t * Aig_ManDfs( Aig_Man_t * p );
+extern Vec_Ptr_t * Aig_ManDfsNode( Aig_Man_t * p, Aig_Obj_t * pNode );
+extern int Aig_ManCountLevels( Aig_Man_t * p );
+extern void Aig_ManCreateRefs( Aig_Man_t * p );
+extern int Aig_DagSize( Aig_Obj_t * pObj );
+extern void Aig_ConeUnmark_rec( Aig_Obj_t * pObj );
+extern Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pObj, int nVars );
+extern Aig_Obj_t * Aig_Compose( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Obj_t * pFunc, int iVar );
+/*=== aigMan.c ==========================================================*/
+extern Aig_Man_t * Aig_ManStart();
+extern Aig_Man_t * Aig_ManDup( Aig_Man_t * p );
+extern void Aig_ManStop( Aig_Man_t * p );
+extern int Aig_ManCleanup( Aig_Man_t * p );
+extern void Aig_ManPrintStats( Aig_Man_t * p );
+/*=== aigMem.c ==========================================================*/
+extern void Aig_ManStartMemory( Aig_Man_t * p );
+extern void Aig_ManStopMemory( Aig_Man_t * p );
+/*=== aigObj.c ==========================================================*/
+extern Aig_Obj_t * Aig_ObjCreatePi( Aig_Man_t * p );
+extern Aig_Obj_t * Aig_ObjCreatePo( Aig_Man_t * p, Aig_Obj_t * pDriver );
+extern Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost );
+extern void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFan0, Aig_Obj_t * pFan1 );
+extern void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj );
+extern void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj );
+extern void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj );
+/*=== aigOper.c =========================================================*/
+extern Aig_Obj_t * Aig_IthVar( Aig_Man_t * p, int i );
+extern Aig_Obj_t * Aig_Oper( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type );
+extern Aig_Obj_t * Aig_And( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 );
+extern Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 );
+extern Aig_Obj_t * Aig_Exor( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 );
+extern Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 );
+extern Aig_Obj_t * Aig_Maj( Aig_Man_t * p, Aig_Obj_t * pA, Aig_Obj_t * pB, Aig_Obj_t * pC );
+extern Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs );
+extern Aig_Obj_t * Aig_CreateAnd( Aig_Man_t * p, int nVars );
+extern Aig_Obj_t * Aig_CreateOr( Aig_Man_t * p, int nVars );
+extern Aig_Obj_t * Aig_CreateExor( Aig_Man_t * p, int nVars );
+/*=== aigTable.c ========================================================*/
+extern Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost );
+extern void Aig_TableInsert( Aig_Man_t * p, Aig_Obj_t * pObj );
+extern void Aig_TableDelete( Aig_Man_t * p, Aig_Obj_t * pObj );
+extern int Aig_TableCountEntries( Aig_Man_t * p );
+extern void Aig_TableProfile( Aig_Man_t * p );
+/*=== aigUtil.c =========================================================*/
+extern void Aig_ManIncrementTravId( Aig_Man_t * p );
+extern void Aig_ManCleanData( Aig_Man_t * p );
+extern void Aig_ObjCollectMulti( Aig_Obj_t * pFunc, Vec_Ptr_t * vSuper );
+extern int Aig_ObjIsMuxType( Aig_Obj_t * pObj );
+extern int Aig_ObjRecognizeExor( Aig_Obj_t * pObj, Aig_Obj_t ** ppFan0, Aig_Obj_t ** ppFan1 );
+extern Aig_Obj_t * Aig_ObjRecognizeMux( Aig_Obj_t * pObj, Aig_Obj_t ** ppObjT, Aig_Obj_t ** ppObjE );
+extern void Aig_ObjPrintVerilog( FILE * pFile, Aig_Obj_t * pObj, Vec_Vec_t * vLevels, int Level );
+extern void Aig_ObjPrintVerbose( Aig_Obj_t * pObj, int fHaig );
+extern void Aig_ManPrintVerbose( Aig_Man_t * p, int fHaig );
+extern void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/temp/aig_free/aigBalance.c b/src/temp/aig_free/aigBalance.c
new file mode 100644
index 00000000..1abc672d
--- /dev/null
+++ b/src/temp/aig_free/aigBalance.c
@@ -0,0 +1,391 @@
+/**CFile****************************************************************
+
+ FileName [aigBalance.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [Algebraic AIG balancing.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: aigBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Aig_Obj_t * Aig_NodeBalance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel );
+static Vec_Ptr_t * Aig_NodeBalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level );
+static int Aig_NodeBalanceFindLeft( Vec_Ptr_t * vSuper );
+static void Aig_NodeBalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor );
+static void Aig_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs algebraic balancing of the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Aig_ManBalance( Aig_Man_t * p, int fUpdateLevel )
+{
+ Aig_Man_t * pNew;
+ Aig_Obj_t * pObj, * pObjNew;
+ Vec_Vec_t * vStore;
+ int i;
+ // create the new manager
+ pNew = Aig_ManStart();
+ pNew->fRefCount = 0;
+ // map the PI nodes
+ Aig_ManCleanData( p );
+ Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
+ Aig_ManForEachPi( p, pObj, i )
+ pObj->pData = Aig_ObjCreatePi(pNew);
+ // balance the AIG
+ vStore = Vec_VecAlloc( 50 );
+ Aig_ManForEachPo( p, pObj, i )
+ {
+ pObjNew = Aig_NodeBalance_rec( pNew, Aig_ObjFanin0(pObj), vStore, 0, fUpdateLevel );
+ Aig_ObjCreatePo( pNew, Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) ) );
+ }
+ Vec_VecFree( vStore );
+ // remove dangling nodes
+// Aig_ManCreateRefs( pNew );
+// if ( i = Aig_ManCleanup( pNew ) )
+// printf( "Cleanup after balancing removed %d dangling nodes.\n", i );
+ // check the resulting AIG
+ if ( !Aig_ManCheck(pNew) )
+ printf( "Aig_ManBalance(): The check has failed.\n" );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the new node constructed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_NodeBalance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )
+{
+ Aig_Obj_t * pObjNew;
+ Vec_Ptr_t * vSuper;
+ int i;
+ assert( !Aig_IsComplement(pObjOld) );
+ // return if the result is known
+ if ( pObjOld->pData )
+ return pObjOld->pData;
+ assert( Aig_ObjIsNode(pObjOld) );
+ // get the implication supergate
+ vSuper = Aig_NodeBalanceCone( pObjOld, vStore, Level );
+ // check if supergate contains two nodes in the opposite polarity
+ if ( vSuper->nSize == 0 )
+ return pObjOld->pData = Aig_ManConst0(pNew);
+ if ( Vec_PtrSize(vSuper) < 2 )
+ printf( "BUG!\n" );
+ // for each old node, derive the new well-balanced node
+ for ( i = 0; i < Vec_PtrSize(vSuper); i++ )
+ {
+ pObjNew = Aig_NodeBalance_rec( pNew, Aig_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel );
+ vSuper->pArray[i] = Aig_NotCond( pObjNew, Aig_IsComplement(vSuper->pArray[i]) );
+ }
+ // build the supergate
+ pObjNew = Aig_NodeBalanceBuildSuper( pNew, vSuper, Aig_ObjType(pObjOld), fUpdateLevel );
+ // make sure the balanced node is not assigned
+// assert( pObjOld->Level >= Aig_Regular(pObjNew)->Level );
+ assert( pObjOld->pData == NULL );
+ return pObjOld->pData = pObjNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the nodes of the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_NodeBalanceCone_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper )
+{
+ int RetValue1, RetValue2, i;
+ // check if the node is visited
+ if ( Aig_Regular(pObj)->fMarkB )
+ {
+ // check if the node occurs in the same polarity
+ for ( i = 0; i < vSuper->nSize; i++ )
+ if ( vSuper->pArray[i] == pObj )
+ return 1;
+ // check if the node is present in the opposite polarity
+ for ( i = 0; i < vSuper->nSize; i++ )
+ if ( vSuper->pArray[i] == Aig_Not(pObj) )
+ return -1;
+ assert( 0 );
+ return 0;
+ }
+ // if the new node is complemented or a PI, another gate begins
+ if ( pObj != pRoot && (Aig_IsComplement(pObj) || Aig_ObjType(pObj) != Aig_ObjType(pRoot) || Aig_ObjRefs(pObj) > 1) )
+ {
+ Vec_PtrPush( vSuper, pObj );
+ Aig_Regular(pObj)->fMarkB = 1;
+ return 0;
+ }
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_ObjIsNode(pObj) );
+ // go through the branches
+ RetValue1 = Aig_NodeBalanceCone_rec( pRoot, Aig_ObjChild0(pObj), vSuper );
+ RetValue2 = Aig_NodeBalanceCone_rec( pRoot, Aig_ObjChild1(pObj), vSuper );
+ if ( RetValue1 == -1 || RetValue2 == -1 )
+ return -1;
+ // return 1 if at least one branch has a duplicate
+ return RetValue1 || RetValue2;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the nodes of the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Aig_NodeBalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
+{
+ Vec_Ptr_t * vNodes;
+ int RetValue, i;
+ assert( !Aig_IsComplement(pObj) );
+ // extend the storage
+ if ( Vec_VecSize( vStore ) <= Level )
+ Vec_VecPush( vStore, Level, 0 );
+ // get the temporary array of nodes
+ vNodes = Vec_VecEntry( vStore, Level );
+ Vec_PtrClear( vNodes );
+ // collect the nodes in the implication supergate
+ RetValue = Aig_NodeBalanceCone_rec( pObj, pObj, vNodes );
+ assert( vNodes->nSize > 1 );
+ // unmark the visited nodes
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ Aig_Regular(pObj)->fMarkB = 0;
+ // if we found the node and its complement in the same implication supergate,
+ // return empty set of nodes (meaning that we should use constant-0 node)
+ if ( RetValue == -1 )
+ vNodes->nSize = 0;
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_NodeCompareLevelsDecrease( Aig_Obj_t ** pp1, Aig_Obj_t ** pp2 )
+{
+ int Diff = Aig_ObjLevel(Aig_Regular(*pp1)) - Aig_ObjLevel(Aig_Regular(*pp2));
+ if ( Diff > 0 )
+ return -1;
+ if ( Diff < 0 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Builds implication supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_NodeBalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel )
+{
+ Aig_Obj_t * pObj1, * pObj2;
+ int LeftBound;
+ assert( vSuper->nSize > 1 );
+ // sort the new nodes by level in the decreasing order
+ Vec_PtrSort( vSuper, Aig_NodeCompareLevelsDecrease );
+ // balance the nodes
+ while ( vSuper->nSize > 1 )
+ {
+ // find the left bound on the node to be paired
+ LeftBound = (!fUpdateLevel)? 0 : Aig_NodeBalanceFindLeft( vSuper );
+ // find the node that can be shared (if no such node, randomize choice)
+ Aig_NodeBalancePermute( p, vSuper, LeftBound, Type == AIG_EXOR );
+ // pull out the last two nodes
+ pObj1 = Vec_PtrPop(vSuper);
+ pObj2 = Vec_PtrPop(vSuper);
+ Aig_NodeBalancePushUniqueOrderByLevel( vSuper, Aig_Oper(p, pObj1, pObj2, Type) );
+ }
+ return Vec_PtrEntry(vSuper, 0);
+}
+
+/**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 Aig_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
+{
+ Aig_Obj_t * pObjRight, * pObjLeft;
+ int Current;
+ // if two or less nodes, pair with the first
+ if ( Vec_PtrSize(vSuper) < 3 )
+ return 0;
+ // set the pointer to the one before the last
+ Current = Vec_PtrSize(vSuper) - 2;
+ pObjRight = Vec_PtrEntry( vSuper, Current );
+ // go through the nodes to the left of this one
+ for ( Current--; Current >= 0; Current-- )
+ {
+ // get the next node on the left
+ pObjLeft = Vec_PtrEntry( vSuper, Current );
+ // if the level of this node is different, quit the loop
+ if ( Aig_ObjLevel(Aig_Regular(pObjLeft)) != Aig_ObjLevel(Aig_Regular(pObjRight)) )
+ break;
+ }
+ Current++;
+ // get the node, for which the equality holds
+ pObjLeft = Vec_PtrEntry( vSuper, Current );
+ assert( Aig_ObjLevel(Aig_Regular(pObjLeft)) == Aig_ObjLevel(Aig_Regular(pObjRight)) );
+ 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 Aig_NodeBalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
+{
+ Aig_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
+ int RightBound, i;
+ // get the right bound
+ RightBound = Vec_PtrSize(vSuper) - 2;
+ assert( LeftBound <= RightBound );
+ if ( LeftBound == RightBound )
+ return;
+ // get the two last nodes
+ pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 );
+ pObj2 = Vec_PtrEntry( vSuper, RightBound );
+ if ( Aig_Regular(pObj1) == p->pConst1 || Aig_Regular(pObj2) == p->pConst1 )
+ return;
+ // find the first node that can be shared
+ for ( i = RightBound; i >= LeftBound; i-- )
+ {
+ pObj3 = Vec_PtrEntry( vSuper, i );
+ if ( Aig_Regular(pObj3) == p->pConst1 )
+ {
+ Vec_PtrWriteEntry( vSuper, i, pObj2 );
+ Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
+ return;
+ }
+ pGhost = Aig_ObjCreateGhost( p, pObj1, pObj3, fExor? AIG_EXOR : AIG_AND );
+ if ( Aig_TableLookup( p, pGhost ) )
+ {
+ if ( pObj3 == pObj2 )
+ return;
+ Vec_PtrWriteEntry( vSuper, i, pObj2 );
+ Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
+ return;
+ }
+ }
+/*
+ // we did not find the node to share, randomize choice
+ {
+ int Choice = rand() % (RightBound - LeftBound + 1);
+ pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice );
+ if ( pObj3 == pObj2 )
+ return;
+ Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 );
+ Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
+ }
+*/
+}
+
+/**Function*************************************************************
+
+ Synopsis [Inserts a new node in the order by levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pObj1, * pObj2;
+ int i;
+ if ( Vec_PtrPushUnique(vStore, pObj) )
+ return;
+ // find the p of the node
+ for ( i = vStore->nSize-1; i > 0; i-- )
+ {
+ pObj1 = vStore->pArray[i ];
+ pObj2 = vStore->pArray[i-1];
+ if ( Aig_ObjLevel(Aig_Regular(pObj1)) <= Aig_ObjLevel(Aig_Regular(pObj2)) )
+ break;
+ vStore->pArray[i ] = pObj2;
+ vStore->pArray[i-1] = pObj1;
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/aigCheck.c b/src/temp/aig_free/aigCheck.c
new file mode 100644
index 00000000..61e4cf78
--- /dev/null
+++ b/src/temp/aig_free/aigCheck.c
@@ -0,0 +1,110 @@
+/**CFile****************************************************************
+
+ FileName [aigCheck.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [AIG checking procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: aigCheck.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Checks the consistency of the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_ManCheck( Aig_Man_t * p )
+{
+ Aig_Obj_t * pObj, * pObj2;
+ int i;
+ // check primary inputs
+ Aig_ManForEachPi( p, pObj, i )
+ {
+ if ( Aig_ObjFanin0(pObj) || Aig_ObjFanin1(pObj) )
+ {
+ printf( "Aig_ManCheck: The PI node \"%p\" has fanins.\n", pObj );
+ return 0;
+ }
+ }
+ // check primary outputs
+ Aig_ManForEachPo( p, pObj, i )
+ {
+ if ( !Aig_ObjFanin0(pObj) )
+ {
+ printf( "Aig_ManCheck: The PO node \"%p\" has NULL fanin.\n", pObj );
+ return 0;
+ }
+ if ( Aig_ObjFanin1(pObj) )
+ {
+ printf( "Aig_ManCheck: The PO node \"%p\" has second fanin.\n", pObj );
+ return 0;
+ }
+ }
+ // check internal nodes
+ Aig_ManForEachNode( p, pObj, i )
+ {
+ if ( !Aig_ObjFanin0(pObj) || !Aig_ObjFanin1(pObj) )
+ {
+ printf( "Aig_ManCheck: The AIG has internal node \"%p\" with a NULL fanin.\n", pObj );
+ return 0;
+ }
+ if ( Aig_ObjFanin0(pObj) >= Aig_ObjFanin1(pObj) )
+ {
+ printf( "Aig_ManCheck: The AIG has node \"%p\" with a wrong ordering of fanins.\n", pObj );
+ return 0;
+ }
+ pObj2 = Aig_TableLookup( p, pObj );
+ if ( pObj2 != pObj )
+ {
+ printf( "Aig_ManCheck: Node \"%p\" is not in the structural hashing table.\n", pObj );
+ return 0;
+ }
+ }
+ // count the total number of nodes
+ if ( Aig_ManObjNum(p) != 1 + Aig_ManPiNum(p) + Aig_ManPoNum(p) + Aig_ManAndNum(p) + Aig_ManExorNum(p) )
+ {
+ printf( "Aig_ManCheck: The number of created nodes is wrong.\n" );
+ return 0;
+ }
+ // count the number of nodes in the table
+ if ( Aig_TableCountEntries(p) != Aig_ManAndNum(p) + Aig_ManExorNum(p) )
+ {
+ printf( "Aig_ManCheck: The number of nodes in the structural hashing table is wrong.\n" );
+ return 0;
+ }
+// if ( !Aig_ManIsAcyclic(p) )
+// return 0;
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/aigDfs.c b/src/temp/aig_free/aigDfs.c
new file mode 100644
index 00000000..c004cab0
--- /dev/null
+++ b/src/temp/aig_free/aigDfs.c
@@ -0,0 +1,399 @@
+/**CFile****************************************************************
+
+ FileName [aigDfs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [DFS traversal procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: aigDfs.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Collects internal nodes in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManDfs_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
+ return;
+ Aig_ManDfs_rec( Aig_ObjFanin0(pObj), vNodes );
+ Aig_ManDfs_rec( Aig_ObjFanin1(pObj), vNodes );
+ assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
+ Aig_ObjSetMarkA(pObj);
+ Vec_PtrPush( vNodes, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects internal nodes in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Aig_ManDfs( Aig_Man_t * p )
+{
+ Vec_Ptr_t * vNodes;
+ Aig_Obj_t * pObj;
+ int i;
+ vNodes = Vec_PtrAlloc( Aig_ManNodeNum(p) );
+ Aig_ManForEachNode( p, pObj, i )
+ Aig_ManDfs_rec( pObj, vNodes );
+ Aig_ManForEachNode( p, pObj, i )
+ Aig_ObjClearMarkA(pObj);
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects internal nodes in the DFS order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Aig_ManDfsNode( Aig_Man_t * p, Aig_Obj_t * pNode )
+{
+ Vec_Ptr_t * vNodes;
+ Aig_Obj_t * pObj;
+ int i;
+ assert( !Aig_IsComplement(pNode) );
+ vNodes = Vec_PtrAlloc( 16 );
+ Aig_ManDfs_rec( pNode, vNodes );
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ Aig_ObjClearMarkA(pObj);
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the max number of levels in the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_ManCountLevels( Aig_Man_t * p )
+{
+ Vec_Ptr_t * vNodes;
+ Aig_Obj_t * pObj;
+ int i, LevelsMax, Level0, Level1;
+ // initialize the levels
+ Aig_ManConst1(p)->pData = NULL;
+ Aig_ManForEachPi( p, pObj, i )
+ pObj->pData = NULL;
+ // compute levels in a DFS order
+ vNodes = Aig_ManDfs( p );
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ Level0 = (int)Aig_ObjFanin0(pObj)->pData;
+ Level1 = (int)Aig_ObjFanin1(pObj)->pData;
+ pObj->pData = (void *)(1 + Aig_ObjIsExor(pObj) + AIG_MAX(Level0, Level1));
+ }
+ Vec_PtrFree( vNodes );
+ // get levels of the POs
+ LevelsMax = 0;
+ Aig_ManForEachPo( p, pObj, i )
+ LevelsMax = AIG_MAX( LevelsMax, (int)Aig_ObjFanin0(pObj)->pData );
+ return LevelsMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates correct reference counters at each node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManCreateRefs( Aig_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ if ( p->fRefCount )
+ return;
+ p->fRefCount = 1;
+ // clear refs
+ Aig_ObjClearRef( Aig_ManConst1(p) );
+ Aig_ManForEachPi( p, pObj, i )
+ Aig_ObjClearRef( pObj );
+ Aig_ManForEachNode( p, pObj, i )
+ Aig_ObjClearRef( pObj );
+ Aig_ManForEachPo( p, pObj, i )
+ Aig_ObjClearRef( pObj );
+ // set refs
+ Aig_ManForEachNode( p, pObj, i )
+ {
+ Aig_ObjRef( Aig_ObjFanin0(pObj) );
+ Aig_ObjRef( Aig_ObjFanin1(pObj) );
+ }
+ Aig_ManForEachPo( p, pObj, i )
+ Aig_ObjRef( Aig_ObjFanin0(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of AIG nodes rooted at this cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ConeMark_rec( Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
+ return;
+ Aig_ConeMark_rec( Aig_ObjFanin0(pObj) );
+ Aig_ConeMark_rec( Aig_ObjFanin1(pObj) );
+ assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
+ Aig_ObjSetMarkA( pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of AIG nodes rooted at this cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ConeCleanAndMark_rec( Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
+ return;
+ Aig_ConeCleanAndMark_rec( Aig_ObjFanin0(pObj) );
+ Aig_ConeCleanAndMark_rec( Aig_ObjFanin1(pObj) );
+ assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
+ Aig_ObjSetMarkA( pObj );
+ pObj->pData = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of AIG nodes rooted at this cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_ConeCountAndMark_rec( Aig_Obj_t * pObj )
+{
+ int Counter;
+ assert( !Aig_IsComplement(pObj) );
+ if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
+ return 0;
+ Counter = 1 + Aig_ConeCountAndMark_rec( Aig_ObjFanin0(pObj) ) +
+ Aig_ConeCountAndMark_rec( Aig_ObjFanin1(pObj) );
+ assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
+ Aig_ObjSetMarkA( pObj );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of AIG nodes rooted at this cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ConeUnmark_rec( Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( !Aig_ObjIsNode(pObj) || !Aig_ObjIsMarkA(pObj) )
+ return;
+ Aig_ConeUnmark_rec( Aig_ObjFanin0(pObj) );
+ Aig_ConeUnmark_rec( Aig_ObjFanin1(pObj) );
+ assert( Aig_ObjIsMarkA(pObj) ); // loop detection
+ Aig_ObjClearMarkA( pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of AIG nodes rooted at this cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_DagSize( Aig_Obj_t * pObj )
+{
+ int Counter;
+ Counter = Aig_ConeCountAndMark_rec( Aig_Regular(pObj) );
+ Aig_ConeUnmark_rec( Aig_Regular(pObj) );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the AIG from one manager into another.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_Transfer_rec( Aig_Man_t * pDest, Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) )
+ return;
+ Aig_Transfer_rec( pDest, Aig_ObjFanin0(pObj) );
+ Aig_Transfer_rec( pDest, Aig_ObjFanin1(pObj) );
+ pObj->pData = Aig_And( pDest, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
+ Aig_ObjSetMarkA( pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the AIG from one manager into another.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pRoot, int nVars )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ // solve simple cases
+ if ( pSour == pDest )
+ return pRoot;
+ if ( Aig_ObjIsConst1( Aig_Regular(pRoot) ) )
+ return Aig_NotCond( Aig_ManConst1(pDest), Aig_IsComplement(pRoot) );
+ // set the PI mapping
+ Aig_ManForEachPi( pSour, pObj, i )
+ {
+ if ( i == nVars )
+ break;
+ pObj->pData = Aig_IthVar(pDest, i);
+ }
+ // transfer and set markings
+ Aig_Transfer_rec( pDest, Aig_Regular(pRoot) );
+ // clear the markings
+ Aig_ConeUnmark_rec( Aig_Regular(pRoot) );
+ return Aig_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_Compose_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFunc, Aig_Obj_t * pVar )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( Aig_ObjIsMarkA(pObj) )
+ return;
+ if ( Aig_ObjIsConst1(pObj) || Aig_ObjIsPi(pObj) )
+ {
+ pObj->pData = pObj == pVar ? pFunc : pObj;
+ return;
+ }
+ Aig_Compose_rec( p, Aig_ObjFanin0(pObj), pFunc, pVar );
+ Aig_Compose_rec( p, Aig_ObjFanin1(pObj), pFunc, pVar );
+ pObj->pData = Aig_And( p, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ assert( !Aig_ObjIsMarkA(pObj) ); // loop detection
+ Aig_ObjSetMarkA( pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Compose( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Obj_t * pFunc, int iVar )
+{
+ // quit if the PI variable is not defined
+ if ( iVar >= Aig_ManPiNum(p) )
+ {
+ printf( "Aig_Compose(): The PI variable %d is not defined.\n", iVar );
+ return NULL;
+ }
+ // recursively perform composition
+ Aig_Compose_rec( p, Aig_Regular(pRoot), pFunc, Aig_ManPi(p, iVar) );
+ // clear the markings
+ Aig_ConeUnmark_rec( Aig_Regular(pRoot) );
+ return Aig_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/aigMan.c b/src/temp/aig_free/aigMan.c
new file mode 100644
index 00000000..bb39712f
--- /dev/null
+++ b/src/temp/aig_free/aigMan.c
@@ -0,0 +1,162 @@
+/**CFile****************************************************************
+
+ FileName [aigMan.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [AIG manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: aig_.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Aig_ManStart()
+{
+ Aig_Man_t * p;
+ // start the manager
+ p = ALLOC( Aig_Man_t, 1 );
+ memset( p, 0, sizeof(Aig_Man_t) );
+ // perform initializations
+ p->nTravIds = 1;
+ p->fRefCount = 1;
+ p->fCatchExor = 0;
+ // allocate arrays for nodes
+ p->vPis = Vec_PtrAlloc( 100 );
+ p->vPos = Vec_PtrAlloc( 100 );
+ // prepare the internal memory manager
+ Aig_ManStartMemory( p );
+ // create the constant node
+ p->pConst1 = Aig_ManFetchMemory( p );
+ p->pConst1->Type = AIG_CONST1;
+ p->pConst1->fPhase = 1;
+ p->nCreated = 1;
+ // start the table
+ p->nTableSize = 10007;
+ p->pTable = ALLOC( Aig_Obj_t *, p->nTableSize );
+ memset( p->pTable, 0, sizeof(Aig_Obj_t *) * p->nTableSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManStop( Aig_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ // make sure the nodes have clean marks
+ pObj = Aig_ManConst1(p);
+ assert( !pObj->fMarkA && !pObj->fMarkB );
+ Aig_ManForEachPi( p, pObj, i )
+ assert( !pObj->fMarkA && !pObj->fMarkB );
+ Aig_ManForEachPo( p, pObj, i )
+ assert( !pObj->fMarkA && !pObj->fMarkB );
+ Aig_ManForEachNode( p, pObj, i )
+ assert( !pObj->fMarkA && !pObj->fMarkB );
+ // print time
+ if ( p->time1 ) { PRT( "time1", p->time1 ); }
+ if ( p->time2 ) { PRT( "time2", p->time2 ); }
+// Aig_TableProfile( p );
+ if ( p->vChunks ) Aig_ManStopMemory( p );
+ if ( p->vPis ) Vec_PtrFree( p->vPis );
+ if ( p->vPos ) Vec_PtrFree( p->vPos );
+ free( p->pTable );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of dangling nodes removed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_ManCleanup( Aig_Man_t * p )
+{
+ Vec_Ptr_t * vNodes;
+ Aig_Obj_t * pNode;
+ int i, nNodesOld;
+ assert( p->fRefCount );
+ nNodesOld = Aig_ManNodeNum(p);
+ // collect roots of dangling nodes
+ vNodes = Vec_PtrAlloc( 100 );
+ Aig_ManForEachNode( p, pNode, i )
+ if ( Aig_ObjRefs(pNode) == 0 )
+ Vec_PtrPush( vNodes, pNode );
+ // recursively remove dangling nodes
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ Aig_ObjDelete_rec( p, pNode );
+ Vec_PtrFree( vNodes );
+ return nNodesOld - Aig_ManNodeNum(p);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManPrintStats( Aig_Man_t * p )
+{
+ printf( "PI/PO = %d/%d. ", Aig_ManPiNum(p), Aig_ManPoNum(p) );
+ printf( "A = %7d. ", Aig_ManAndNum(p) );
+ printf( "X = %5d. ", Aig_ManExorNum(p) );
+ printf( "Cre = %7d. ", p->nCreated );
+ printf( "Del = %7d. ", p->nDeleted );
+ printf( "Lev = %3d. ", Aig_ManCountLevels(p) );
+ printf( "\n" );
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/aigMem.c b/src/temp/aig_free/aigMem.c
new file mode 100644
index 00000000..1be78a88
--- /dev/null
+++ b/src/temp/aig_free/aigMem.c
@@ -0,0 +1,115 @@
+/**CFile****************************************************************
+
+ FileName [aigMem.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [Memory management for the AIG nodes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: aigMem.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// memory management
+#define IVY_PAGE_SIZE 12 // page size containing 2^IVY_PAGE_SIZE nodes
+#define IVY_PAGE_MASK 4095 // page bitmask (2^IVY_PAGE_SIZE)-1
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts the internal memory manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManStartMemory( Aig_Man_t * p )
+{
+ p->vChunks = Vec_PtrAlloc( 128 );
+ p->vPages = Vec_PtrAlloc( 128 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the internal memory manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManStopMemory( Aig_Man_t * p )
+{
+ void * pMemory;
+ int i;
+ Vec_PtrForEachEntry( p->vChunks, pMemory, i )
+ free( pMemory );
+ Vec_PtrFree( p->vChunks );
+ Vec_PtrFree( p->vPages );
+ p->pListFree = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates additional memory for the nodes.]
+
+ Description [Allocates IVY_PAGE_SIZE nodes. Aligns memory by 32 bytes.
+ Records the pointer to the AIG manager in the -1 entry.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManAddMemory( Aig_Man_t * p )
+{
+ char * pMemory;
+ int i, nBytes;
+ assert( sizeof(Aig_Obj_t) <= 64 );
+ assert( p->pListFree == NULL );
+// assert( (Aig_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
+ // allocate new memory page
+ nBytes = sizeof(Aig_Obj_t) * (1<<IVY_PAGE_SIZE) + 64;
+ pMemory = ALLOC( char, nBytes );
+ Vec_PtrPush( p->vChunks, pMemory );
+ // align memory at the 32-byte boundary
+ pMemory = pMemory + 64 - (((int)pMemory) & 63);
+ // remember the manager in the first entry
+ Vec_PtrPush( p->vPages, pMemory );
+ // break the memory down into nodes
+ p->pListFree = (Aig_Obj_t *)pMemory;
+ for ( i = 1; i <= IVY_PAGE_MASK; i++ )
+ {
+ *((char **)pMemory) = pMemory + sizeof(Aig_Obj_t);
+ pMemory += sizeof(Aig_Obj_t);
+ }
+ *((char **)pMemory) = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/aigObj.c b/src/temp/aig_free/aigObj.c
new file mode 100644
index 00000000..51ce6008
--- /dev/null
+++ b/src/temp/aig_free/aigObj.c
@@ -0,0 +1,228 @@
+/**CFile****************************************************************
+
+ FileName [aigObj.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [Adding/removing objects.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: aigObj.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates primary input.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_ObjCreatePi( Aig_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ pObj = Aig_ManFetchMemory( p );
+ pObj->Type = AIG_PI;
+ Vec_PtrPush( p->vPis, pObj );
+ p->nObjs[AIG_PI]++;
+ p->nCreated++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates primary output with the given driver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_ObjCreatePo( Aig_Man_t * p, Aig_Obj_t * pDriver )
+{
+ Aig_Obj_t * pObj;
+ pObj = Aig_ManFetchMemory( p );
+ pObj->Type = AIG_PO;
+ Vec_PtrPush( p->vPos, pObj );
+ // add connections
+ pObj->pFanin0 = pDriver;
+ if ( p->fRefCount )
+ Aig_ObjRef( Aig_Regular(pDriver) );
+ else
+ pObj->nRefs = Aig_ObjLevel( Aig_Regular(pDriver) );
+ // update node counters of the manager
+ p->nObjs[AIG_PO]++;
+ p->nCreated++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node assuming it does not exist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost )
+{
+ Aig_Obj_t * pObj;
+ assert( !Aig_IsComplement(pGhost) );
+ assert( Aig_ObjIsNode(pGhost) );
+ assert( pGhost == &p->Ghost );
+ // get memory for the new object
+ pObj = Aig_ManFetchMemory( p );
+ pObj->Type = pGhost->Type;
+ // add connections
+ Aig_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 );
+ // update node counters of the manager
+ p->nObjs[Aig_ObjType(pObj)]++;
+ p->nCreated++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Connect the object to the fanin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFan0, Aig_Obj_t * pFan1 )
+{
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_ObjIsNode(pObj) );
+ // add the first fanin
+ pObj->pFanin0 = pFan0;
+ pObj->pFanin1 = pFan1;
+ // increment references of the fanins and add their fanouts
+ if ( p->fRefCount )
+ {
+ if ( pFan0 != NULL )
+ Aig_ObjRef( Aig_ObjFanin0(pObj) );
+ if ( pFan1 != NULL )
+ Aig_ObjRef( Aig_ObjFanin1(pObj) );
+ }
+ else
+ pObj->nRefs = Aig_ObjLevelNew( pObj );
+ // add the node to the structural hash table
+ Aig_TableInsert( p, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Connect the object to the fanin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_ObjIsNode(pObj) );
+ // remove connections
+ if ( pObj->pFanin0 != NULL )
+ Aig_ObjDeref(Aig_ObjFanin0(pObj));
+ if ( pObj->pFanin1 != NULL )
+ Aig_ObjDeref(Aig_ObjFanin1(pObj));
+ // remove the node from the structural hash table
+ Aig_TableDelete( p, pObj );
+ // add the first fanin
+ pObj->pFanin0 = NULL;
+ pObj->pFanin1 = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ assert( !Aig_IsComplement(pObj) );
+ assert( !Aig_ObjIsTerm(pObj) );
+ assert( Aig_ObjRefs(pObj) == 0 );
+ // update node counters of the manager
+ p->nObjs[pObj->Type]--;
+ p->nDeleted++;
+ // remove connections
+ Aig_ObjDisconnect( p, pObj );
+ // remove PIs/POs from the arrays
+ if ( Aig_ObjIsPi(pObj) )
+ Vec_PtrRemove( p->vPis, pObj );
+ // free the node
+ Aig_ManRecycleMemory( p, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the MFFC of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pFanin0, * pFanin1;
+ assert( !Aig_IsComplement(pObj) );
+ if ( Aig_ObjIsConst1(pObj) || Aig_ObjIsPi(pObj) )
+ return;
+ assert( Aig_ObjIsNode(pObj) );
+ pFanin0 = Aig_ObjFanin0(pObj);
+ pFanin1 = Aig_ObjFanin1(pObj);
+ Aig_ObjDelete( p, pObj );
+ if ( pFanin0 && !Aig_ObjIsNone(pFanin0) && Aig_ObjRefs(pFanin0) == 0 )
+ Aig_ObjDelete_rec( p, pFanin0 );
+ if ( pFanin1 && !Aig_ObjIsNone(pFanin1) && Aig_ObjRefs(pFanin1) == 0 )
+ Aig_ObjDelete_rec( p, pFanin1 );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/aigOper.c b/src/temp/aig_free/aigOper.c
new file mode 100644
index 00000000..9985093e
--- /dev/null
+++ b/src/temp/aig_free/aigOper.c
@@ -0,0 +1,373 @@
+/**CFile****************************************************************
+
+ FileName [aigOper.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [AIG operations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006.]
+
+ Revision [$Id: aigOper.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// procedure to detect an EXOR gate
+static inline int Aig_ObjIsExorType( Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Obj_t ** ppFan0, Aig_Obj_t ** ppFan1 )
+{
+ if ( !Aig_IsComplement(p0) || !Aig_IsComplement(p1) )
+ return 0;
+ p0 = Aig_Regular(p0);
+ p1 = Aig_Regular(p1);
+ if ( !Aig_ObjIsAnd(p0) || !Aig_ObjIsAnd(p1) )
+ return 0;
+ if ( Aig_ObjFanin0(p0) != Aig_ObjFanin0(p1) || Aig_ObjFanin1(p0) != Aig_ObjFanin1(p1) )
+ return 0;
+ if ( Aig_ObjFaninC0(p0) == Aig_ObjFaninC0(p1) || Aig_ObjFaninC1(p0) == Aig_ObjFaninC1(p1) )
+ return 0;
+ *ppFan0 = Aig_ObjChild0(p0);
+ *ppFan1 = Aig_ObjChild1(p0);
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns i-th elementary variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_IthVar( Aig_Man_t * p, int i )
+{
+ int v;
+ for ( v = Aig_ManPiNum(p); v <= i; v++ )
+ Aig_ObjCreatePi( p );
+ assert( i < Vec_PtrSize(p->vPis) );
+ return Aig_ManPi( p, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Perform one operation.]
+
+ Description [The argument nodes can be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Oper( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type )
+{
+ if ( Type == AIG_AND )
+ return Aig_And( p, p0, p1 );
+ if ( Type == AIG_EXOR )
+ return Aig_Exor( p, p0, p1 );
+ assert( 0 );
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs canonicization step.]
+
+ Description [The argument nodes can be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_And( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 )
+{
+ Aig_Obj_t * pGhost, * pResult;
+// Aig_Obj_t * pFan0, * pFan1;
+ // check trivial cases
+ if ( p0 == p1 )
+ return p0;
+ if ( p0 == Aig_Not(p1) )
+ return Aig_Not(p->pConst1);
+ if ( Aig_Regular(p0) == p->pConst1 )
+ return p0 == p->pConst1 ? p1 : Aig_Not(p->pConst1);
+ if ( Aig_Regular(p1) == p->pConst1 )
+ return p1 == p->pConst1 ? p0 : Aig_Not(p->pConst1);
+ // check if it can be an EXOR gate
+// if ( Aig_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) )
+// return Aig_Exor( p, pFan0, pFan1 );
+ // check the table
+ pGhost = Aig_ObjCreateGhost( p, p0, p1, AIG_AND );
+ if ( pResult = Aig_TableLookup( p, pGhost ) )
+ return pResult;
+ return Aig_ObjCreate( p, pGhost );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs canonicization step.]
+
+ Description [The argument nodes can be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Exor( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 )
+{
+/*
+ Aig_Obj_t * pGhost, * pResult;
+ // check trivial cases
+ if ( p0 == p1 )
+ return Aig_Not(p->pConst1);
+ if ( p0 == Aig_Not(p1) )
+ return p->pConst1;
+ if ( Aig_Regular(p0) == p->pConst1 )
+ return Aig_NotCond( p1, p0 == p->pConst1 );
+ if ( Aig_Regular(p1) == p->pConst1 )
+ return Aig_NotCond( p0, p1 == p->pConst1 );
+ // check the table
+ pGhost = Aig_ObjCreateGhost( p, p0, p1, AIG_EXOR );
+ if ( pResult = Aig_TableLookup( p, pGhost ) )
+ return pResult;
+ return Aig_ObjCreate( p, pGhost );
+*/
+ return Aig_Or( p, Aig_And(p, p0, Aig_Not(p1)), Aig_And(p, Aig_Not(p0), p1) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements Boolean OR.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 )
+{
+ return Aig_Not( Aig_And( p, Aig_Not(p0), Aig_Not(p1) ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements ITE operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 )
+{
+/*
+ Aig_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp;
+ int Count0, Count1;
+ // consider trivial cases
+ if ( p0 == Aig_Not(p1) )
+ return Aig_Exor( p, pC, p0 );
+ // other cases can be added
+ // implement the first MUX (F = C * x1 + C' * x0)
+
+ // check for constants here!!!
+
+ pTempA1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, p1, AIG_AND) );
+ pTempA2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), p0, AIG_AND) );
+ if ( pTempA1 && pTempA2 )
+ {
+ pTemp = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pTempA1), Aig_Not(pTempA2), AIG_AND) );
+ if ( pTemp ) return Aig_Not(pTemp);
+ }
+ Count0 = (pTempA1 != NULL) + (pTempA2 != NULL);
+ // implement the second MUX (F' = C * x1' + C' * x0')
+ pTempB1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, Aig_Not(p1), AIG_AND) );
+ pTempB2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), Aig_Not(p0), AIG_AND) );
+ if ( pTempB1 && pTempB2 )
+ {
+ pTemp = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pTempB1), Aig_Not(pTempB2), AIG_AND) );
+ if ( pTemp ) return pTemp;
+ }
+ Count1 = (pTempB1 != NULL) + (pTempB2 != NULL);
+ // compare and decide which one to implement
+ if ( Count0 >= Count1 )
+ {
+ pTempA1 = pTempA1? pTempA1 : Aig_And(p, pC, p1);
+ pTempA2 = pTempA2? pTempA2 : Aig_And(p, Aig_Not(pC), p0);
+ return Aig_Or( p, pTempA1, pTempA2 );
+ }
+ pTempB1 = pTempB1? pTempB1 : Aig_And(p, pC, Aig_Not(p1));
+ pTempB2 = pTempB2? pTempB2 : Aig_And(p, Aig_Not(pC), Aig_Not(p0));
+ return Aig_Not( Aig_Or( p, pTempB1, pTempB2 ) );
+*/
+ return Aig_Or( p, Aig_And(p, pC, p1), Aig_And(p, Aig_Not(pC), p0) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements ITE operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Maj( Aig_Man_t * p, Aig_Obj_t * pA, Aig_Obj_t * pB, Aig_Obj_t * pC )
+{
+ return Aig_Or( p, Aig_Or(p, Aig_And(p, pA, pB), Aig_And(p, pA, pC)), Aig_And(p, pB, pC) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the well-balanced tree of gates.]
+
+ Description [Disregards levels and possible logic sharing.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Multi_rec( Aig_Man_t * p, Aig_Obj_t ** ppObjs, int nObjs, Aig_Type_t Type )
+{
+ Aig_Obj_t * pObj1, * pObj2;
+ if ( nObjs == 1 )
+ return ppObjs[0];
+ pObj1 = Aig_Multi_rec( p, ppObjs, nObjs/2, Type );
+ pObj2 = Aig_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type );
+ return Aig_Oper( p, pObj1, pObj2, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Old code.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Multi( Aig_Man_t * p, Aig_Obj_t ** pArgs, int nArgs, Aig_Type_t Type )
+{
+ assert( Type == AIG_AND || Type == AIG_EXOR );
+ assert( nArgs > 0 );
+ return Aig_Multi_rec( p, pArgs, nArgs, Type );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs )
+{
+ int i;
+ assert( vPairs->nSize > 0 );
+ assert( vPairs->nSize % 2 == 0 );
+ // go through the cubes of the node's SOP
+ for ( i = 0; i < vPairs->nSize; i += 2 )
+ vPairs->pArray[i/2] = Aig_Not( Aig_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) );
+ vPairs->nSize = vPairs->nSize/2;
+ return Aig_Not( Aig_Multi_rec( p, (Aig_Obj_t **)vPairs->pArray, vPairs->nSize, AIG_AND ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates AND function with nVars inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_CreateAnd( Aig_Man_t * p, int nVars )
+{
+ Aig_Obj_t * pFunc;
+ int i;
+ pFunc = Aig_ManConst1( p );
+ for ( i = 0; i < nVars; i++ )
+ pFunc = Aig_And( p, pFunc, Aig_IthVar(p, i) );
+ return pFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates AND function with nVars inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_CreateOr( Aig_Man_t * p, int nVars )
+{
+ Aig_Obj_t * pFunc;
+ int i;
+ pFunc = Aig_ManConst0( p );
+ for ( i = 0; i < nVars; i++ )
+ pFunc = Aig_Or( p, pFunc, Aig_IthVar(p, i) );
+ return pFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates AND function with nVars inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_CreateExor( Aig_Man_t * p, int nVars )
+{
+ Aig_Obj_t * pFunc;
+ int i;
+ pFunc = Aig_ManConst0( p );
+ for ( i = 0; i < nVars; i++ )
+ pFunc = Aig_Exor( p, pFunc, Aig_IthVar(p, i) );
+ return pFunc;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/aigTable.c b/src/temp/aig_free/aigTable.c
new file mode 100644
index 00000000..338faa45
--- /dev/null
+++ b/src/temp/aig_free/aigTable.c
@@ -0,0 +1,266 @@
+/**CFile****************************************************************
+
+ FileName [aigTable.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [Structural hashing table.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - May 11, 2006. ]
+
+ Revision [$Id: aigTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// hashing the node
+static unsigned long Aig_Hash( Aig_Obj_t * pObj, int TableSize )
+{
+ unsigned long Key = Aig_ObjIsExor(pObj) * 1699;
+ Key ^= (long)Aig_ObjFanin0(pObj) * 7937;
+ Key ^= (long)Aig_ObjFanin1(pObj) * 2971;
+ Key ^= Aig_ObjFaninC0(pObj) * 911;
+ Key ^= Aig_ObjFaninC1(pObj) * 353;
+ return Key % TableSize;
+}
+
+// returns the place where this node is stored (or should be stored)
+static Aig_Obj_t ** Aig_TableFind( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ int i;
+ assert( Aig_ObjChild0(pObj) && Aig_ObjChild1(pObj) );
+ assert( Aig_ObjChild0(pObj) < Aig_ObjChild1(pObj) );
+ for ( i = Aig_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
+ if ( p->pTable[i] == pObj )
+ break;
+ return p->pTable + i;
+}
+
+static void Aig_TableResize( Aig_Man_t * p );
+static unsigned int Cudd_PrimeAig( unsigned int p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Checks if node with the given attributes is in the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost )
+{
+ int i;
+ assert( !Aig_IsComplement(pGhost) );
+ assert( Aig_ObjChild0(pGhost) && Aig_ObjChild1(pGhost) );
+ assert( Aig_ObjChild0(pGhost) < Aig_ObjChild1(pGhost) );
+ if ( p->fRefCount && (!Aig_ObjRefs(Aig_ObjFanin0(pGhost)) || !Aig_ObjRefs(Aig_ObjFanin1(pGhost))) )
+ return NULL;
+ for ( i = Aig_Hash(pGhost, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
+ {
+ if ( Aig_ObjChild0(p->pTable[i]) == Aig_ObjChild0(pGhost) &&
+ Aig_ObjChild1(p->pTable[i]) == Aig_ObjChild1(pGhost) &&
+ Aig_ObjType(p->pTable[i]) == Aig_ObjType(pGhost) )
+ return p->pTable[i];
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the new node to the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_TableInsert( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t ** ppPlace;
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_TableLookup(p, pObj) == NULL );
+ if ( p->nTableSize < 2 * Aig_ManNodeNum(p) )
+ Aig_TableResize( p );
+ ppPlace = Aig_TableFind( p, pObj );
+ assert( *ppPlace == NULL );
+ *ppPlace = pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the node from the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_TableDelete( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pEntry, ** ppPlace;
+ int i;
+ assert( !Aig_IsComplement(pObj) );
+ ppPlace = Aig_TableFind( p, pObj );
+ assert( *ppPlace == pObj ); // node should be in the table
+ *ppPlace = NULL;
+ // rehash the adjacent entries
+ i = ppPlace - p->pTable;
+ for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize )
+ {
+ pEntry = p->pTable[i];
+ p->pTable[i] = 0;
+ Aig_TableInsert( p, pEntry );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count the number of nodes in the table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_TableCountEntries( Aig_Man_t * p )
+{
+ int i, Counter = 0;
+ for ( i = 0; i < p->nTableSize; i++ )
+ Counter += (p->pTable[i] != NULL);
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the table.]
+
+ Description [Typically this procedure should not be called.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_TableResize( Aig_Man_t * p )
+{
+ Aig_Obj_t ** pTableOld, ** ppPlace;
+ int nTableSizeOld, Counter, nEntries, e, clk;
+clk = clock();
+ // save the old table
+ pTableOld = p->pTable;
+ nTableSizeOld = p->nTableSize;
+ // get the new table
+ p->nTableSize = Cudd_PrimeAig( 5 * Aig_ManNodeNum(p) );
+ p->pTable = ALLOC( Aig_Obj_t *, p->nTableSize );
+ memset( p->pTable, 0, sizeof(Aig_Obj_t *) * 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
+ ppPlace = Aig_TableFind( p, pTableOld[e] );
+ assert( *ppPlace == NULL ); // should not be in the table
+ *ppPlace = pTableOld[e];
+ }
+ nEntries = Aig_ManNodeNum(p);
+// assert( Counter == nEntries );
+// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
+// PRT( "Time", clock() - clk );
+ // replace the table and the parameters
+ free( pTableOld );
+}
+
+/**Function********************************************************************
+
+ Synopsis [Profiles the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+void Aig_TableProfile( Aig_Man_t * p )
+{
+ int i, Counter = 0;
+ for ( i = 0; i < p->nTableSize; i++ )
+ {
+ if ( p->pTable[i] )
+ Counter++;
+ else if ( Counter )
+ {
+ printf( "%d ", Counter );
+ Counter = 0;
+ }
+ }
+}
+
+/**Function********************************************************************
+
+ Synopsis [Returns the next prime &gt;= p.]
+
+ Description [Copied from CUDD, for stand-aloneness.]
+
+ SideEffects [None]
+
+ SeeAlso []
+
+******************************************************************************/
+unsigned int Cudd_PrimeAig( unsigned int p)
+{
+ int i,pn;
+
+ p--;
+ do {
+ p++;
+ if (p&1) {
+ pn = 1;
+ i = 3;
+ while ((unsigned) (i * i) <= p) {
+ if (p % i == 0) {
+ pn = 0;
+ break;
+ }
+ i += 2;
+ }
+ } else {
+ pn = 0;
+ }
+ } while (!pn);
+ return(p);
+
+} /* end of Cudd_Prime */
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/aigUtil.c b/src/temp/aig_free/aigUtil.c
new file mode 100644
index 00000000..623de32b
--- /dev/null
+++ b/src/temp/aig_free/aigUtil.c
@@ -0,0 +1,513 @@
+/**CFile****************************************************************
+
+ FileName [aigUtil.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: aigUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+
+int Extra_Base10Log( unsigned Num )
+{
+ int Res;
+ assert( Num >= 0 );
+ if ( Num == 0 ) return 0;
+ if ( Num == 1 ) return 1;
+ for ( Res = 0, Num--; Num; Num /= 10, Res++ );
+ return Res;
+} /* end of Extra_Base2Log */
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Increments the current traversal ID of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManIncrementTravId( Aig_Man_t * p )
+{
+ if ( p->nTravIds >= (1<<30)-1 )
+ Aig_ManCleanData( p );
+ p->nTravIds++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the DFS ordering of the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManCleanData( Aig_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ p->nTravIds = 1;
+ Aig_ManConst1(p)->pData = NULL;
+ Aig_ManForEachPi( p, pObj, i )
+ pObj->pData = NULL;
+ Aig_ManForEachPo( p, pObj, i )
+ pObj->pData = NULL;
+ Aig_ManForEachNode( p, pObj, i )
+ pObj->pData = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Detects multi-input gate rooted at this node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjCollectMulti_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper )
+{
+ if ( pRoot != pObj && (Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) || Aig_ObjType(pRoot) != Aig_ObjType(pObj)) )
+ {
+ Vec_PtrPushUnique(vSuper, pObj);
+ return;
+ }
+ Aig_ObjCollectMulti_rec( pRoot, Aig_ObjChild0(pObj), vSuper );
+ Aig_ObjCollectMulti_rec( pRoot, Aig_ObjChild1(pObj), vSuper );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Detects multi-input gate rooted at this node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjCollectMulti( Aig_Obj_t * pRoot, Vec_Ptr_t * vSuper )
+{
+ assert( !Aig_IsComplement(pRoot) );
+ Vec_PtrClear( vSuper );
+ Aig_ObjCollectMulti_rec( pRoot, pRoot, vSuper );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_ObjIsMuxType( Aig_Obj_t * pNode )
+{
+ Aig_Obj_t * pNode0, * pNode1;
+ // check that the node is regular
+ assert( !Aig_IsComplement(pNode) );
+ // if the node is not AND, this is not MUX
+ if ( !Aig_ObjIsAnd(pNode) )
+ return 0;
+ // if the children are not complemented, this is not MUX
+ if ( !Aig_ObjFaninC0(pNode) || !Aig_ObjFaninC1(pNode) )
+ return 0;
+ // get children
+ pNode0 = Aig_ObjFanin0(pNode);
+ pNode1 = Aig_ObjFanin1(pNode);
+ // if the children are not ANDs, this is not MUX
+ if ( !Aig_ObjIsAnd(pNode0) || !Aig_ObjIsAnd(pNode1) )
+ return 0;
+ // otherwise the node is MUX iff it has a pair of equal grandchildren
+ return (Aig_ObjFanin0(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC0(pNode1))) ||
+ (Aig_ObjFanin0(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC1(pNode1))) ||
+ (Aig_ObjFanin1(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC0(pNode1))) ||
+ (Aig_ObjFanin1(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC1(pNode1)));
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Recognizes what nodes are inputs of the EXOR.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Aig_ObjRecognizeExor( Aig_Obj_t * pObj, Aig_Obj_t ** ppFan0, Aig_Obj_t ** ppFan1 )
+{
+ Aig_Obj_t * p0, * p1;
+ assert( !Aig_IsComplement(pObj) );
+ if ( !Aig_ObjIsNode(pObj) )
+ return 0;
+ if ( Aig_ObjIsExor(pObj) )
+ {
+ *ppFan0 = Aig_ObjChild0(pObj);
+ *ppFan1 = Aig_ObjChild1(pObj);
+ return 1;
+ }
+ assert( Aig_ObjIsAnd(pObj) );
+ p0 = Aig_ObjChild0(pObj);
+ p1 = Aig_ObjChild1(pObj);
+ if ( !Aig_IsComplement(p0) || !Aig_IsComplement(p1) )
+ return 0;
+ p0 = Aig_Regular(p0);
+ p1 = Aig_Regular(p1);
+ if ( !Aig_ObjIsAnd(p0) || !Aig_ObjIsAnd(p1) )
+ return 0;
+ if ( Aig_ObjFanin0(p0) != Aig_ObjFanin0(p1) || Aig_ObjFanin1(p0) != Aig_ObjFanin1(p1) )
+ return 0;
+ if ( Aig_ObjFaninC0(p0) == Aig_ObjFaninC0(p1) || Aig_ObjFaninC1(p0) == Aig_ObjFaninC1(p1) )
+ return 0;
+ *ppFan0 = Aig_ObjChild0(p0);
+ *ppFan1 = Aig_ObjChild1(p0);
+ return 1;
+}
+
+/**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 []
+
+***********************************************************************/
+Aig_Obj_t * Aig_ObjRecognizeMux( Aig_Obj_t * pNode, Aig_Obj_t ** ppNodeT, Aig_Obj_t ** ppNodeE )
+{
+ Aig_Obj_t * pNode0, * pNode1;
+ assert( !Aig_IsComplement(pNode) );
+ assert( Aig_ObjIsMuxType(pNode) );
+ // get children
+ pNode0 = Aig_ObjFanin0(pNode);
+ pNode1 = Aig_ObjFanin1(pNode);
+
+ // find the control variable
+ if ( Aig_ObjFanin1(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC1(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p2) )
+ if ( Aig_ObjFaninC1(pNode0) )
+ { // pNode2->p2 is positive phase of C
+ *ppNodeT = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1);
+ *ppNodeE = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1);
+ return Aig_ObjChild1(pNode1);//pNode2->p2;
+ }
+ else
+ { // pNode1->p2 is positive phase of C
+ *ppNodeT = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1);
+ *ppNodeE = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1);
+ return Aig_ObjChild1(pNode0);//pNode1->p2;
+ }
+ }
+ else if ( Aig_ObjFanin0(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC0(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p1) )
+ if ( Aig_ObjFaninC0(pNode0) )
+ { // pNode2->p1 is positive phase of C
+ *ppNodeT = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2);
+ *ppNodeE = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2);
+ return Aig_ObjChild0(pNode1);//pNode2->p1;
+ }
+ else
+ { // pNode1->p1 is positive phase of C
+ *ppNodeT = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2);
+ *ppNodeE = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2);
+ return Aig_ObjChild0(pNode0);//pNode1->p1;
+ }
+ }
+ else if ( Aig_ObjFanin0(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC1(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p1) )
+ if ( Aig_ObjFaninC0(pNode0) )
+ { // pNode2->p2 is positive phase of C
+ *ppNodeT = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1);
+ *ppNodeE = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2);
+ return Aig_ObjChild1(pNode1);//pNode2->p2;
+ }
+ else
+ { // pNode1->p1 is positive phase of C
+ *ppNodeT = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2);
+ *ppNodeE = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1);
+ return Aig_ObjChild0(pNode0);//pNode1->p1;
+ }
+ }
+ else if ( Aig_ObjFanin1(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC0(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p2) )
+ if ( Aig_ObjFaninC1(pNode0) )
+ { // pNode2->p1 is positive phase of C
+ *ppNodeT = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2);
+ *ppNodeE = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1);
+ return Aig_ObjChild0(pNode1);//pNode2->p1;
+ }
+ else
+ { // pNode1->p2 is positive phase of C
+ *ppNodeT = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1);
+ *ppNodeE = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2);
+ return Aig_ObjChild1(pNode0);//pNode1->p2;
+ }
+ }
+ assert( 0 ); // this is not MUX
+ return NULL;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints Verilog formula for the AIG rooted at this node.]
+
+ Description [The formula is in terms of PIs, which should have
+ their names assigned in pObj->pData fields.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjPrintVerilog( FILE * pFile, Aig_Obj_t * pObj, Vec_Vec_t * vLevels, int Level )
+{
+ Vec_Ptr_t * vSuper;
+ Aig_Obj_t * pFanin, * pFanin0, * pFanin1, * pFaninC;
+ int fCompl, i;
+ // store the complemented attribute
+ fCompl = Aig_IsComplement(pObj);
+ pObj = Aig_Regular(pObj);
+ // constant case
+ if ( Aig_ObjIsConst1(pObj) )
+ {
+ fprintf( pFile, "%d", !fCompl );
+ return;
+ }
+ // PI case
+ if ( Aig_ObjIsPi(pObj) )
+ {
+ fprintf( pFile, "%s%s", fCompl? "~" : "", pObj->pData );
+ return;
+ }
+ // EXOR case
+ if ( Aig_ObjIsExor(pObj) )
+ {
+ Vec_VecExpand( vLevels, Level );
+ vSuper = Vec_VecEntry( vLevels, Level );
+ Aig_ObjCollectMulti( pObj, vSuper );
+ fprintf( pFile, "%s", (Level==0? "" : "(") );
+ Vec_PtrForEachEntry( vSuper, pFanin, i )
+ {
+ Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin, (fCompl && i==0)), vLevels, Level+1 );
+ if ( i < Vec_PtrSize(vSuper) - 1 )
+ fprintf( pFile, " ^ " );
+ }
+ fprintf( pFile, "%s", (Level==0? "" : ")") );
+ return;
+ }
+ // MUX case
+ if ( Aig_ObjIsMuxType(pObj) )
+ {
+ if ( Aig_ObjRecognizeExor( pObj, &pFanin0, &pFanin1 ) )
+ {
+ fprintf( pFile, "%s", (Level==0? "" : "(") );
+ Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin0, fCompl), vLevels, Level+1 );
+ fprintf( pFile, " ^ " );
+ Aig_ObjPrintVerilog( pFile, pFanin1, vLevels, Level+1 );
+ fprintf( pFile, "%s", (Level==0? "" : ")") );
+ }
+ else
+ {
+ pFaninC = Aig_ObjRecognizeMux( pObj, &pFanin1, &pFanin0 );
+ fprintf( pFile, "%s", (Level==0? "" : "(") );
+ Aig_ObjPrintVerilog( pFile, pFaninC, vLevels, Level+1 );
+ fprintf( pFile, " ? " );
+ Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin1, fCompl), vLevels, Level+1 );
+ fprintf( pFile, " : " );
+ Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin0, fCompl), vLevels, Level+1 );
+ fprintf( pFile, "%s", (Level==0? "" : ")") );
+ }
+ return;
+ }
+ // AND case
+ Vec_VecExpand( vLevels, Level );
+ vSuper = Vec_VecEntry(vLevels, Level);
+ Aig_ObjCollectMulti( pObj, vSuper );
+ fprintf( pFile, "%s", (Level==0? "" : "(") );
+ Vec_PtrForEachEntry( vSuper, pFanin, i )
+ {
+ Aig_ObjPrintVerilog( pFile, Aig_NotCond(pFanin, fCompl), vLevels, Level+1 );
+ if ( i < Vec_PtrSize(vSuper) - 1 )
+ fprintf( pFile, " %s ", fCompl? "|" : "&" );
+ }
+ fprintf( pFile, "%s", (Level==0? "" : ")") );
+ return;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints node in HAIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ObjPrintVerbose( Aig_Obj_t * pObj, int fHaig )
+{
+ assert( !Aig_IsComplement(pObj) );
+ printf( "Node %p : ", pObj );
+ if ( Aig_ObjIsConst1(pObj) )
+ printf( "constant 1" );
+ else if ( Aig_ObjIsPi(pObj) )
+ printf( "PI" );
+ else
+ printf( "AND( %p%s, %p%s )",
+ Aig_ObjFanin0(pObj), (Aig_ObjFaninC0(pObj)? "\'" : " "),
+ Aig_ObjFanin1(pObj), (Aig_ObjFaninC1(pObj)? "\'" : " ") );
+ printf( " (refs = %3d)", Aig_ObjRefs(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints node in HAIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManPrintVerbose( Aig_Man_t * p, int fHaig )
+{
+ Vec_Ptr_t * vNodes;
+ Aig_Obj_t * pObj;
+ int i;
+ printf( "PIs: " );
+ Aig_ManForEachPi( p, pObj, i )
+ printf( " %p", pObj );
+ printf( "\n" );
+ vNodes = Aig_ManDfs( p );
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ Aig_ObjPrintVerbose( pObj, fHaig ), printf( "\n" );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the AIG into the BLIF file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName )
+{
+ FILE * pFile;
+ Vec_Ptr_t * vNodes;
+ Aig_Obj_t * pObj, * pConst1 = NULL;
+ int i, nDigits, Counter = 0;
+ if ( Aig_ManPoNum(p) == 0 )
+ {
+ printf( "Aig_ManDumpBlif(): AIG manager does not have POs.\n" );
+ return;
+ }
+ // collect nodes in the DFS order
+ vNodes = Aig_ManDfs( p );
+ // assign IDs to objects
+ Aig_ManConst1(p)->pData = (void *)Counter++;
+ Aig_ManForEachPi( p, pObj, i )
+ pObj->pData = (void *)Counter++;
+ Aig_ManForEachPo( p, pObj, i )
+ pObj->pData = (void *)Counter++;
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ pObj->pData = (void *)Counter++;
+ nDigits = Extra_Base10Log( Counter );
+ // write the file
+ pFile = fopen( pFileName, "w" );
+ fprintf( pFile, "# BLIF file written by procedure Aig_ManDumpBlif() in ABC\n" );
+ fprintf( pFile, "# http://www.eecs.berkeley.edu/~alanmi/abc/\n" );
+ fprintf( pFile, ".model test\n" );
+ // write PIs
+ fprintf( pFile, ".inputs" );
+ Aig_ManForEachPi( p, pObj, i )
+ fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
+ fprintf( pFile, "\n" );
+ // write POs
+ fprintf( pFile, ".outputs" );
+ Aig_ManForEachPo( p, pObj, i )
+ fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
+ fprintf( pFile, "\n" );
+ // write nodes
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ fprintf( pFile, ".names n%0*d n%0*d n%0*d\n",
+ nDigits, (int)Aig_ObjFanin0(pObj)->pData,
+ nDigits, (int)Aig_ObjFanin1(pObj)->pData,
+ nDigits, (int)pObj->pData );
+ fprintf( pFile, "%d%d 1\n", !Aig_ObjFaninC0(pObj), !Aig_ObjFaninC1(pObj) );
+ }
+ // write POs
+ Aig_ManForEachPo( p, pObj, i )
+ {
+ fprintf( pFile, ".names n%0*d n%0*d\n",
+ nDigits, (int)Aig_ObjFanin0(pObj)->pData,
+ nDigits, (int)pObj->pData );
+ fprintf( pFile, "%d 1\n", !Aig_ObjFaninC0(pObj) );
+ if ( Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) )
+ pConst1 = Aig_ManConst1(p);
+ }
+ if ( pConst1 )
+ fprintf( pFile, ".names n%0*d\n 1\n", nDigits, (int)pConst1->pData );
+ fprintf( pFile, ".end\n\n" );
+ fclose( pFile );
+ Vec_PtrFree( vNodes );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/cudd2.c b/src/temp/aig_free/cudd2.c
new file mode 100644
index 00000000..f95d3fd0
--- /dev/null
+++ b/src/temp/aig_free/cudd2.c
@@ -0,0 +1,375 @@
+/**CFile****************************************************************
+
+ FileName [cudd2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [Recording AIGs for the BDD operations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - October 3, 2006.]
+
+ Revision [$Id: cudd2.c,v 1.00 2006/10/03 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+#include "st.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Aig_CuddMan_t_ Aig_CuddMan_t;
+struct Aig_CuddMan_t_
+{
+ Aig_Man_t * pAig; // internal AIG package
+ st_table * pTable; // hash table mapping BDD nodes into AIG nodes
+};
+
+// static Cudd AIG manager used in this experiment
+static Aig_CuddMan_t * s_pCuddMan = NULL;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Start AIG recording.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_Init( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd )
+{
+ int v;
+ assert( s_pCuddMan == NULL );
+ s_pCuddMan = ALLOC( Aig_CuddMan_t, 1 );
+ s_pCuddMan->pAig = Aig_ManStart();
+ s_pCuddMan->pTable = st_init_table( st_ptrcmp, st_ptrhash );
+ for ( v = 0; v < (int)numVars; v++ )
+ Aig_ObjCreatePi( s_pCuddMan->pAig );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops AIG recording.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_Quit( void * pCudd )
+{
+ assert( s_pCuddMan != NULL );
+ Aig_ManDumpBlif( s_pCuddMan->pAig, "aig_temp.blif" );
+ Aig_ManStop( s_pCuddMan->pAig );
+ st_free_table( s_pCuddMan->pTable );
+ free( s_pCuddMan );
+ s_pCuddMan = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fetches AIG node corresponding to the BDD node from the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Aig_Obj_t * Cudd2_GetArg( void * pArg )
+{
+ Aig_Obj_t * pNode;
+ assert( s_pCuddMan != NULL );
+ if ( !st_lookup( s_pCuddMan->pTable, (char *)Aig_Regular(pArg), (char **)&pNode ) )
+ {
+ printf( "Cudd2_GetArg(): An argument BDD is not in the hash table.\n" );
+ return NULL;
+ }
+ return Aig_NotCond( pNode, Aig_IsComplement(pArg) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Inserts the AIG node corresponding to the BDD node into the hash table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Cudd2_SetArg( Aig_Obj_t * pNode, void * pResult )
+{
+ assert( s_pCuddMan != NULL );
+ if ( st_is_member( s_pCuddMan->pTable, (char *)Aig_Regular(pResult) ) )
+ return;
+ pNode = Aig_NotCond( pNode, Aig_IsComplement(pResult) );
+ st_insert( s_pCuddMan->pTable, (char *)Aig_Regular(pResult), (char *)pNode );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates equivalent of BDD.ONE and BDD.ReadZero.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+void Cudd2_bddOne( void * pCudd, void * pResult )
+{
+ Cudd2_SetArg( Aig_ManConst1(s_pCuddMan->pAig), pResult );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds elementary variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddIthVar( void * pCudd, int iVar, void * pResult )
+{
+ int v;
+ assert( s_pCuddMan != NULL );
+ for ( v = Aig_ManPiNum(s_pCuddMan->pAig); v <= iVar; v++ )
+ Aig_ObjCreatePi( s_pCuddMan->pAig );
+ Cudd2_SetArg( Aig_ManPi(s_pCuddMan->pAig, iVar), pResult );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs BDD operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddAnd( void * pCudd, void * pArg0, void * pArg1, void * pResult )
+{
+ Aig_Obj_t * pNode0, * pNode1, * pNode;
+ pNode0 = Cudd2_GetArg( pArg0 );
+ pNode1 = Cudd2_GetArg( pArg1 );
+ pNode = Aig_And( s_pCuddMan->pAig, pNode0, pNode1 );
+ Cudd2_SetArg( pNode, pResult );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs BDD operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddOr( void * pCudd, void * pArg0, void * pArg1, void * pResult )
+{
+ Cudd2_bddAnd( pCudd, Aig_Not(pArg0), Aig_Not(pArg1), Aig_Not(pResult) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs BDD operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddNand( void * pCudd, void * pArg0, void * pArg1, void * pResult )
+{
+ Cudd2_bddAnd( pCudd, pArg0, pArg1, Aig_Not(pResult) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs BDD operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddNor( void * pCudd, void * pArg0, void * pArg1, void * pResult )
+{
+ Cudd2_bddAnd( pCudd, Aig_Not(pArg0), Aig_Not(pArg1), pResult );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs BDD operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddXor( void * pCudd, void * pArg0, void * pArg1, void * pResult )
+{
+ Aig_Obj_t * pNode0, * pNode1, * pNode;
+ pNode0 = Cudd2_GetArg( pArg0 );
+ pNode1 = Cudd2_GetArg( pArg1 );
+ pNode = Aig_Exor( s_pCuddMan->pAig, pNode0, pNode1 );
+ Cudd2_SetArg( pNode, pResult );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs BDD operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddXnor( void * pCudd, void * pArg0, void * pArg1, void * pResult )
+{
+ Cudd2_bddXor( pCudd, pArg0, pArg1, Aig_Not(pResult) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs BDD operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddIte( void * pCudd, void * pArg0, void * pArg1, void * pArg2, void * pResult )
+{
+ Aig_Obj_t * pNode0, * pNode1, * pNode2, * pNode;
+ pNode0 = Cudd2_GetArg( pArg0 );
+ pNode1 = Cudd2_GetArg( pArg1 );
+ pNode2 = Cudd2_GetArg( pArg2 );
+ pNode = Aig_Mux( s_pCuddMan->pAig, pNode0, pNode1, pNode2 );
+ Cudd2_SetArg( pNode, pResult );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs BDD operation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddCompose( void * pCudd, void * pArg0, void * pArg1, int v, void * pResult )
+{
+ Aig_Obj_t * pNode0, * pNode1, * pNode;
+ pNode0 = Cudd2_GetArg( pArg0 );
+ pNode1 = Cudd2_GetArg( pArg1 );
+ pNode = Aig_Compose( s_pCuddMan->pAig, pNode0, pNode1, v );
+ Cudd2_SetArg( pNode, pResult );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Should be called after each containment check.]
+
+ Description [Result should be 1 if Cudd2_bddLeq returned 1.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddLeq( void * pCudd, void * pArg0, void * pArg1, int Result )
+{
+ Aig_Obj_t * pNode0, * pNode1, * pNode;
+ pNode0 = Cudd2_GetArg( pArg0 );
+ pNode1 = Cudd2_GetArg( pArg1 );
+ pNode = Aig_And( s_pCuddMan->pAig, pNode0, Aig_Not(pNode1) );
+ Aig_ObjCreatePo( s_pCuddMan->pAig, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Should be called after each equality check.]
+
+ Description [Result should be 1 if they are equal.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_bddEqual( void * pCudd, void * pArg0, void * pArg1, int Result )
+{
+ Aig_Obj_t * pNode0, * pNode1, * pNode;
+ pNode0 = Cudd2_GetArg( pArg0 );
+ pNode1 = Cudd2_GetArg( pArg1 );
+ pNode = Aig_Exor( s_pCuddMan->pAig, pNode0, pNode1 );
+ Aig_ObjCreatePo( s_pCuddMan->pAig, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Should be called each time a BDD node is dereferenced.]
+
+ Description [Removes mapping of a BDD node into an AIG node when the BDD
+ node is dereferenced.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cudd2_RecursiveDeref( void * pCudd, void * pArg )
+{
+ assert( s_pCuddMan != NULL );
+ assert( st_is_member(s_pCuddMan->pTable, (char *)Aig_Regular(pArg)) );
+ st_delete( s_pCuddMan->pTable, (char *)Aig_Regular(pArg), NULL );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/aig_free/cudd2.h b/src/temp/aig_free/cudd2.h
new file mode 100644
index 00000000..c80ec5ed
--- /dev/null
+++ b/src/temp/aig_free/cudd2.h
@@ -0,0 +1,83 @@
+/**CFile****************************************************************
+
+ FileName [cudd2.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Minimalistic And-Inverter Graph package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - October 3, 2006.]
+
+ Revision [$Id: cudd2.h,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __CUDD2_H__
+#define __CUDD2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// HA: Added for printing messages
+#ifndef MSG
+#define MSG(msg) (printf("%s = \n",(msg)));
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// ITERATORS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+ extern void Cudd2_Init ( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd );
+ extern void Cudd2_Quit ( void * pCudd );
+ extern void Cudd2_bddOne ( void * pCudd, void * pResult );
+
+ extern void Cudd2_bddIthVar ( void * pCudd, int iVar, void * pResult );
+ extern void Cudd2_bddAnd ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
+ extern void Cudd2_bddOr ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
+ extern void Cudd2_bddNand ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
+ extern void Cudd2_bddNor ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
+ extern void Cudd2_bddXor ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
+ extern void Cudd2_bddXnor ( void * pCudd, void * pArg0, void * pArg1, void * pResult );
+ extern void Cudd2_bddIte ( void * pCudd, void * pArg0, void * pArg1, void * pArg2, void * pResult );
+ extern void Cudd2_bddCompose( void * pCudd, void * pArg0, void * pArg1, int v, void * pResult );
+ extern void Cudd2_bddLeq ( void * pCudd, void * pArg0, void * pArg1, int Result );
+ extern void Cudd2_bddEqual ( void * pCudd, void * pArg0, void * pArg1, int Result );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/temp/aig_free/st.c b/src/temp/aig_free/st.c
new file mode 100644
index 00000000..5024e08d
--- /dev/null
+++ b/src/temp/aig_free/st.c
@@ -0,0 +1,626 @@
+/*
+ * Revision Control Information
+ *
+ * /projects/hsis/CVS/utilities/st/st.c,v
+ * serdar
+ * 1.1
+ * 1993/07/29 01:00:13
+ *
+ */
+#include <stdio.h>
+
+#include <stdlib.h>
+//#include "extra.h"
+#include "st.h"
+
+#ifndef ABS
+# define ABS(a) ((a) < 0 ? -(a) : (a))
+#endif
+
+#ifndef ALLOC
+#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
+#endif
+
+#ifndef FREE
+#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
+#endif
+
+#ifndef REALLOC
+#define REALLOC(type, obj, num) \
+ ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
+ ((type *) malloc(sizeof(type) * (num))))
+#endif
+
+#define ST_NUMCMP(x,y) ((x) != (y))
+#define ST_NUMHASH(x,size) (ABS((long)x)%(size))
+#define ST_PTRHASH(x,size) ((int)((unsigned long)(x)>>2)%size)
+#define EQUAL(func, x, y) \
+ ((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\
+ (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0))
+
+
+#define do_hash(key, table)\
+ ((table->hash == st_ptrhash) ? ST_PTRHASH((key),(table)->num_bins) :\
+ (table->hash == st_numhash) ? ST_NUMHASH((key), (table)->num_bins) :\
+ (*table->hash)((key), (table)->num_bins))
+
+static int rehash();
+int st_numhash(), st_ptrhash(), st_numcmp(), st_ptrcmp();
+
+st_table *
+st_init_table_with_params(compare, hash, size, density, grow_factor,
+ reorder_flag)
+int (*compare)();
+int (*hash)();
+int size;
+int density;
+double grow_factor;
+int reorder_flag;
+{
+ int i;
+ st_table *new;
+
+ new = ALLOC(st_table, 1);
+ if (new == NULL) {
+ return NULL;
+ }
+ new->compare = compare;
+ new->hash = hash;
+ new->num_entries = 0;
+ new->max_density = density;
+ new->grow_factor = grow_factor;
+ new->reorder_flag = reorder_flag;
+ if (size <= 0) {
+ size = 1;
+ }
+ new->num_bins = size;
+ new->bins = ALLOC(st_table_entry *, size);
+ if (new->bins == NULL) {
+ FREE(new);
+ return NULL;
+ }
+ for(i = 0; i < size; i++) {
+ new->bins[i] = 0;
+ }
+ return new;
+}
+
+st_table *
+st_init_table(compare, hash)
+int (*compare)();
+int (*hash)();
+{
+ return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE,
+ ST_DEFAULT_MAX_DENSITY,
+ ST_DEFAULT_GROW_FACTOR,
+ ST_DEFAULT_REORDER_FLAG);
+}
+
+void
+st_free_table(table)
+st_table *table;
+{
+ register st_table_entry *ptr, *next;
+ int i;
+
+ for(i = 0; i < table->num_bins ; i++) {
+ ptr = table->bins[i];
+ while (ptr != NULL) {
+ next = ptr->next;
+ FREE(ptr);
+ ptr = next;
+ }
+ }
+ FREE(table->bins);
+ FREE(table);
+}
+
+#define PTR_NOT_EQUAL(table, ptr, user_key)\
+(ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key))
+
+#define FIND_ENTRY(table, hash_val, key, ptr, last) \
+ (last) = &(table)->bins[hash_val];\
+ (ptr) = *(last);\
+ while (PTR_NOT_EQUAL((table), (ptr), (key))) {\
+ (last) = &(ptr)->next; (ptr) = *(last);\
+ }\
+ if ((ptr) != NULL && (table)->reorder_flag) {\
+ *(last) = (ptr)->next;\
+ (ptr)->next = (table)->bins[hash_val];\
+ (table)->bins[hash_val] = (ptr);\
+ }
+
+int
+st_lookup(table, key, value)
+st_table *table;
+register char *key;
+char **value;
+{
+ int hash_val;
+ register st_table_entry *ptr, **last;
+
+ hash_val = do_hash(key, table);
+
+ FIND_ENTRY(table, hash_val, key, ptr, last);
+
+ if (ptr == NULL) {
+ return 0;
+ } else {
+ if (value != NULL) {
+ *value = ptr->record;
+ }
+ return 1;
+ }
+}
+
+int
+st_lookup_int(table, key, value)
+st_table *table;
+register char *key;
+int *value;
+{
+ int hash_val;
+ register st_table_entry *ptr, **last;
+
+ hash_val = do_hash(key, table);
+
+ FIND_ENTRY(table, hash_val, key, ptr, last);
+
+ if (ptr == NULL) {
+ return 0;
+ } else {
+ if (value != 0) {
+ *value = (long) ptr->record;
+ }
+ return 1;
+ }
+}
+
+/* This macro does not check if memory allocation fails. Use at you own risk */
+#define ADD_DIRECT(table, key, value, hash_val, new)\
+{\
+ if (table->num_entries/table->num_bins >= table->max_density) {\
+ rehash(table);\
+ hash_val = do_hash(key,table);\
+ }\
+ \
+ new = ALLOC(st_table_entry, 1);\
+ \
+ new->key = key;\
+ new->record = value;\
+ new->next = table->bins[hash_val];\
+ table->bins[hash_val] = new;\
+ table->num_entries++;\
+}
+
+int
+st_insert(table, key, value)
+register st_table *table;
+register char *key;
+char *value;
+{
+ int hash_val;
+ st_table_entry *new;
+ register st_table_entry *ptr, **last;
+
+ hash_val = do_hash(key, table);
+
+ FIND_ENTRY(table, hash_val, key, ptr, last);
+
+ if (ptr == NULL) {
+ if (table->num_entries/table->num_bins >= table->max_density) {
+ if (rehash(table) == ST_OUT_OF_MEM) {
+ return ST_OUT_OF_MEM;
+ }
+ hash_val = do_hash(key, table);
+ }
+ new = ALLOC(st_table_entry, 1);
+ if (new == NULL) {
+ return ST_OUT_OF_MEM;
+ }
+ new->key = key;
+ new->record = value;
+ new->next = table->bins[hash_val];
+ table->bins[hash_val] = new;
+ table->num_entries++;
+ return 0;
+ } else {
+ ptr->record = value;
+ return 1;
+ }
+}
+
+int
+st_add_direct(table, key, value)
+st_table *table;
+char *key;
+char *value;
+{
+ int hash_val;
+ st_table_entry *new;
+
+ hash_val = do_hash(key, table);
+ if (table->num_entries / table->num_bins >= table->max_density) {
+ if (rehash(table) == ST_OUT_OF_MEM) {
+ return ST_OUT_OF_MEM;
+ }
+ }
+ hash_val = do_hash(key, table);
+ new = ALLOC(st_table_entry, 1);
+ if (new == NULL) {
+ return ST_OUT_OF_MEM;
+ }
+ new->key = key;
+ new->record = value;
+ new->next = table->bins[hash_val];
+ table->bins[hash_val] = new;
+ table->num_entries++;
+ return 1;
+}
+
+int
+st_find_or_add(table, key, slot)
+st_table *table;
+char *key;
+char ***slot;
+{
+ int hash_val;
+ st_table_entry *new, *ptr, **last;
+
+ hash_val = do_hash(key, table);
+
+ FIND_ENTRY(table, hash_val, key, ptr, last);
+
+ if (ptr == NULL) {
+ if (table->num_entries / table->num_bins >= table->max_density) {
+ if (rehash(table) == ST_OUT_OF_MEM) {
+ return ST_OUT_OF_MEM;
+ }
+ hash_val = do_hash(key, table);
+ }
+ new = ALLOC(st_table_entry, 1);
+ if (new == NULL) {
+ return ST_OUT_OF_MEM;
+ }
+ new->key = key;
+ new->record = (char *) 0;
+ new->next = table->bins[hash_val];
+ table->bins[hash_val] = new;
+ table->num_entries++;
+ if (slot != NULL) *slot = &new->record;
+ return 0;
+ } else {
+ if (slot != NULL) *slot = &ptr->record;
+ return 1;
+ }
+}
+
+int
+st_find(table, key, slot)
+st_table *table;
+char *key;
+char ***slot;
+{
+ int hash_val;
+ st_table_entry *ptr, **last;
+
+ hash_val = do_hash(key, table);
+
+ FIND_ENTRY(table, hash_val, key, ptr, last);
+
+ if (ptr == NULL) {
+ return 0;
+ } else {
+ if (slot != NULL) {
+ *slot = &ptr->record;
+ }
+ return 1;
+ }
+}
+
+static int
+rehash(table)
+register st_table *table;
+{
+ register st_table_entry *ptr, *next, **old_bins;
+ int i, old_num_bins, hash_val, old_num_entries;
+
+ /* save old values */
+ old_bins = table->bins;
+ old_num_bins = table->num_bins;
+ old_num_entries = table->num_entries;
+
+ /* rehash */
+ table->num_bins = (int)(table->grow_factor * old_num_bins);
+ if (table->num_bins % 2 == 0) {
+ table->num_bins += 1;
+ }
+ table->num_entries = 0;
+ table->bins = ALLOC(st_table_entry *, table->num_bins);
+ if (table->bins == NULL) {
+ table->bins = old_bins;
+ table->num_bins = old_num_bins;
+ table->num_entries = old_num_entries;
+ return ST_OUT_OF_MEM;
+ }
+ /* initialize */
+ for (i = 0; i < table->num_bins; i++) {
+ table->bins[i] = 0;
+ }
+
+ /* copy data over */
+ for (i = 0; i < old_num_bins; i++) {
+ ptr = old_bins[i];
+ while (ptr != NULL) {
+ next = ptr->next;
+ hash_val = do_hash(ptr->key, table);
+ ptr->next = table->bins[hash_val];
+ table->bins[hash_val] = ptr;
+ table->num_entries++;
+ ptr = next;
+ }
+ }
+ FREE(old_bins);
+
+ return 1;
+}
+
+st_table *
+st_copy(old_table)
+st_table *old_table;
+{
+ st_table *new_table;
+ st_table_entry *ptr, *newptr, *next, *new;
+ int i, j, num_bins = old_table->num_bins;
+
+ new_table = ALLOC(st_table, 1);
+ if (new_table == NULL) {
+ return NULL;
+ }
+
+ *new_table = *old_table;
+ new_table->bins = ALLOC(st_table_entry *, num_bins);
+ if (new_table->bins == NULL) {
+ FREE(new_table);
+ return NULL;
+ }
+ for(i = 0; i < num_bins ; i++) {
+ new_table->bins[i] = NULL;
+ ptr = old_table->bins[i];
+ while (ptr != NULL) {
+ new = ALLOC(st_table_entry, 1);
+ if (new == NULL) {
+ for (j = 0; j <= i; j++) {
+ newptr = new_table->bins[j];
+ while (newptr != NULL) {
+ next = newptr->next;
+ FREE(newptr);
+ newptr = next;
+ }
+ }
+ FREE(new_table->bins);
+ FREE(new_table);
+ return NULL;
+ }
+ *new = *ptr;
+ new->next = new_table->bins[i];
+ new_table->bins[i] = new;
+ ptr = ptr->next;
+ }
+ }
+ return new_table;
+}
+
+int
+st_delete(table, keyp, value)
+register st_table *table;
+register char **keyp;
+char **value;
+{
+ int hash_val;
+ char *key = *keyp;
+ register st_table_entry *ptr, **last;
+
+ hash_val = do_hash(key, table);
+
+ FIND_ENTRY(table, hash_val, key, ptr ,last);
+
+ if (ptr == NULL) {
+ return 0;
+ }
+
+ *last = ptr->next;
+ if (value != NULL) *value = ptr->record;
+ *keyp = ptr->key;
+ FREE(ptr);
+ table->num_entries--;
+ return 1;
+}
+
+int
+st_delete_int(table, keyp, value)
+register st_table *table;
+register long *keyp;
+char **value;
+{
+ int hash_val;
+ char *key = (char *) *keyp;
+ register st_table_entry *ptr, **last;
+
+ hash_val = do_hash(key, table);
+
+ FIND_ENTRY(table, hash_val, key, ptr ,last);
+
+ if (ptr == NULL) {
+ return 0;
+ }
+
+ *last = ptr->next;
+ if (value != NULL) *value = ptr->record;
+ *keyp = (long) ptr->key;
+ FREE(ptr);
+ table->num_entries--;
+ return 1;
+}
+
+int
+st_foreach(table, func, arg)
+st_table *table;
+enum st_retval (*func)();
+char *arg;
+{
+ st_table_entry *ptr, **last;
+ enum st_retval retval;
+ int i;
+
+ for(i = 0; i < table->num_bins; i++) {
+ last = &table->bins[i]; ptr = *last;
+ while (ptr != NULL) {
+ retval = (*func)(ptr->key, ptr->record, arg);
+ switch (retval) {
+ case ST_CONTINUE:
+ last = &ptr->next; ptr = *last;
+ break;
+ case ST_STOP:
+ return 0;
+ case ST_DELETE:
+ *last = ptr->next;
+ table->num_entries--; /* cstevens@ic */
+ FREE(ptr);
+ ptr = *last;
+ }
+ }
+ }
+ return 1;
+}
+
+int
+st_strhash(string, modulus)
+register char *string;
+int modulus;
+{
+ register int val = 0;
+ register int c;
+
+ while ((c = *string++) != '\0') {
+ val = val*997 + c;
+ }
+
+ return ((val < 0) ? -val : val)%modulus;
+}
+
+int
+st_numhash(x, size)
+char *x;
+int size;
+{
+ return ST_NUMHASH(x, size);
+}
+
+int
+st_ptrhash(x, size)
+char *x;
+int size;
+{
+ return ST_PTRHASH(x, size);
+}
+
+int
+st_numcmp(x, y)
+char *x;
+char *y;
+{
+ return ST_NUMCMP(x, y);
+}
+
+int
+st_ptrcmp(x, y)
+char *x;
+char *y;
+{
+ return ST_NUMCMP(x, y);
+}
+
+st_generator *
+st_init_gen(table)
+st_table *table;
+{
+ st_generator *gen;
+
+ gen = ALLOC(st_generator, 1);
+ if (gen == NULL) {
+ return NULL;
+ }
+ gen->table = table;
+ gen->entry = NULL;
+ gen->index = 0;
+ return gen;
+}
+
+
+int
+st_gen(gen, key_p, value_p)
+st_generator *gen;
+char **key_p;
+char **value_p;
+{
+ register int i;
+
+ if (gen->entry == NULL) {
+ /* try to find next entry */
+ for(i = gen->index; i < gen->table->num_bins; i++) {
+ if (gen->table->bins[i] != NULL) {
+ gen->index = i+1;
+ gen->entry = gen->table->bins[i];
+ break;
+ }
+ }
+ if (gen->entry == NULL) {
+ return 0; /* that's all folks ! */
+ }
+ }
+ *key_p = gen->entry->key;
+ if (value_p != 0) {
+ *value_p = gen->entry->record;
+ }
+ gen->entry = gen->entry->next;
+ return 1;
+}
+
+
+int
+st_gen_int(gen, key_p, value_p)
+st_generator *gen;
+char **key_p;
+long *value_p;
+{
+ register int i;
+
+ if (gen->entry == NULL) {
+ /* try to find next entry */
+ for(i = gen->index; i < gen->table->num_bins; i++) {
+ if (gen->table->bins[i] != NULL) {
+ gen->index = i+1;
+ gen->entry = gen->table->bins[i];
+ break;
+ }
+ }
+ if (gen->entry == NULL) {
+ return 0; /* that's all folks ! */
+ }
+ }
+ *key_p = gen->entry->key;
+ if (value_p != 0) {
+ *value_p = (long) gen->entry->record;
+ }
+ gen->entry = gen->entry->next;
+ return 1;
+}
+
+
+void
+st_free_gen(gen)
+st_generator *gen;
+{
+ FREE(gen);
+}
diff --git a/src/temp/aig_free/st.h b/src/temp/aig_free/st.h
new file mode 100644
index 00000000..b15f3c83
--- /dev/null
+++ b/src/temp/aig_free/st.h
@@ -0,0 +1,96 @@
+/*
+ * Revision Control Information
+ *
+ * /projects/hsis/CVS/utilities/st/st.h,v
+ * serdar
+ * 1.1
+ * 1993/07/29 01:00:21
+ *
+ */
+/* LINTLIBRARY */
+
+/* /projects/hsis/CVS/utilities/st/st.h,v 1.1 1993/07/29 01:00:21 serdar Exp */
+
+#ifndef ST_INCLUDED
+#define ST_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct st_table_entry st_table_entry;
+struct st_table_entry {
+ char *key;
+ char *record;
+ st_table_entry *next;
+};
+
+typedef struct st_table st_table;
+struct st_table {
+ int (*compare)();
+ int (*hash)();
+ int num_bins;
+ int num_entries;
+ int max_density;
+ int reorder_flag;
+ double grow_factor;
+ st_table_entry **bins;
+};
+
+typedef struct st_generator st_generator;
+struct st_generator {
+ st_table *table;
+ st_table_entry *entry;
+ int index;
+};
+
+#define st_is_member(table,key) st_lookup(table,key,(char **) 0)
+#define st_count(table) ((table)->num_entries)
+
+enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};
+
+typedef enum st_retval (*ST_PFSR)();
+typedef int (*ST_PFI)();
+
+extern st_table *st_init_table_with_params (ST_PFI, ST_PFI, int, int, double, int);
+extern st_table *st_init_table (ST_PFI, ST_PFI);
+extern void st_free_table (st_table *);
+extern int st_lookup (st_table *, char *, char **);
+extern int st_lookup_int (st_table *, char *, int *);
+extern int st_insert (st_table *, char *, char *);
+extern int st_add_direct (st_table *, char *, char *);
+extern int st_find_or_add (st_table *, char *, char ***);
+extern int st_find (st_table *, char *, char ***);
+extern st_table *st_copy (st_table *);
+extern int st_delete (st_table *, char **, char **);
+extern int st_delete_int (st_table *, long *, char **);
+extern int st_foreach (st_table *, ST_PFSR, char *);
+extern int st_strhash (char *, int);
+extern int st_numhash (char *, int);
+extern int st_ptrhash (char *, int);
+extern int st_numcmp (char *, char *);
+extern int st_ptrcmp (char *, char *);
+extern st_generator *st_init_gen (st_table *);
+extern int st_gen (st_generator *, char **, char **);
+extern int st_gen_int (st_generator *, char **, long *);
+extern void st_free_gen (st_generator *);
+
+
+#define ST_DEFAULT_MAX_DENSITY 5
+#define ST_DEFAULT_INIT_TABLE_SIZE 11
+#define ST_DEFAULT_GROW_FACTOR 2.0
+#define ST_DEFAULT_REORDER_FLAG 0
+
+#define st_foreach_item(table, gen, key, value) \
+ for(gen=st_init_gen(table); st_gen(gen,key,value) || (st_free_gen(gen),0);)
+
+#define st_foreach_item_int(table, gen, key, value) \
+ for(gen=st_init_gen(table); st_gen_int(gen,key,value) || (st_free_gen(gen),0);)
+
+#define ST_OUT_OF_MEM -10000
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ST_INCLUDED */
diff --git a/src/temp/aig_free/subdir.mk b/src/temp/aig_free/subdir.mk
new file mode 100644
index 00000000..1867f777
--- /dev/null
+++ b/src/temp/aig_free/subdir.mk
@@ -0,0 +1,87 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+INCPATHS = -I$(ROOT)/aig-alan
+
+# Add inputs and outputs from these tool invocations to the build variables
+PURE_C_SRCS += \
+${addprefix $(ROOT)/aig-alan/, \
+aigBalance.c \
+aigCheck.c \
+aigDfs.c \
+aigMan.c \
+aigMem.c \
+aigObj.c \
+aigOper.c \
+aigTable.c \
+aigUtil.c \
+cudd2.c \
+st.c \
+}
+
+C_SRCS += $(PURE_C_SRCS)
+
+
+PURE_C_OBJS += \
+${addprefix $(ROOT)/obj/aig-alan/, \
+aigBalance.o \
+aigCheck.o \
+aigDfs.o \
+aigMan.o \
+aigMem.o \
+aigObj.o \
+aigOper.o \
+aigTable.o \
+aigUtil.o \
+cudd2.o \
+st.o \
+}
+
+OBJS += $(PURE_C_OBJS)
+
+PURE_C_DEPS += \
+${addprefix $(ROOT)/obj/aig-alan, \
+aigBalance.d \
+aigCheck.d \
+aigDfs.d \
+aigMan.d \
+aigMem.d \
+aigObj.d \
+aigOper.d \
+aigTable.d \
+aigUtil.d \
+cudd2.d \
+st.d \
+}
+
+DEPS += $(PURE_C_DEPS)
+
+
+OCAML_OBJS +=
+
+
+DEPEND_SRCS +=
+
+# Each subdirectory must supply rules for building sources it contributes
+$(ROOT)/obj/aig-alan/%.o: $(ROOT)/aig-alan/%.c
+ @echo 'Building file: $<'
+ @echo 'Invoking: GCC C Compiler: $(CC)'
+ @echo $(CC) $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 -o$@ $<
+ @$(CC) $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 -o$@ $< && \
+ echo -n $(@:%.o=%.d) $(dir $@) > $(@:%.o=%.d) && \
+ $(CC) -MM -MG -P -w $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 $< >> $(@:%.o=%.d)
+ @echo 'Finished building: $<'
+ @echo ' '
+
+$(ROOT)/obj/aig-alan/%.o: $(ROOT)/aig-alan/%.cpp
+ @echo 'Building file: $<'
+ @echo 'Invoking: G++ C Compiler: $(GPCC)'
+ @echo $(GPPCC) $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 -o$@ $<
+ @$(GPPCC) $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 -o$@ $< && \
+ echo -n $(@:%.o=%.d) $(dir $@) > $(@:%.o=%.d) && \
+ $(GPPCC) -MM -MG -P -w $(GPCC_OPTS) $(INCPATHS) -O3 -g3 -Wall -c -fmessage-length=0 $< >> $(@:%.o=%.d)
+ @echo 'Finished building: $<'
+ @echo ' '
+
+
diff --git a/src/temp/aig_free/vec.h b/src/temp/aig_free/vec.h
new file mode 100644
index 00000000..61737d3a
--- /dev/null
+++ b/src/temp/aig_free/vec.h
@@ -0,0 +1,82 @@
+/**CFile****************************************************************
+
+ FileName [vec.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_H__
+#define __VEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WIN32
+#define inline __inline // compatible with MS VS 6.0
+#endif
+
+#ifndef ALLOC
+#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
+#endif
+
+#ifndef FREE
+#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
+#endif
+
+#ifndef REALLOC
+#define REALLOC(type, obj, num) \
+ ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
+ ((type *) malloc(sizeof(type) * (num))))
+#endif
+
+
+#include "vecInt.h"
+#include "vecFlt.h"
+#include "vecStr.h"
+#include "vecPtr.h"
+#include "vecVec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/temp/aig_free/vecFlt.h b/src/temp/aig_free/vecFlt.h
new file mode 100644
index 00000000..6d92d824
--- /dev/null
+++ b/src/temp/aig_free/vecFlt.h
@@ -0,0 +1,667 @@
+/**CFile****************************************************************
+
+ FileName [vecFlt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable arrays of floats.]
+
+ Author [Aaron P. Hurst]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_FLT_H__
+#define __VEC_FLT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+//#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Flt_t_ Vec_Flt_t;
+struct Vec_Flt_t_
+{
+ int nCap;
+ int nSize;
+ float * pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define Vec_FltForEachEntry( vVec, Entry, i ) \
+ for ( i = 0; (i < Vec_FltSize(vVec)) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
+#define Vec_FltForEachEntryStart( vVec, Entry, i, Start ) \
+ for ( i = Start; (i < Vec_FltSize(vVec)) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
+#define Vec_FltForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \
+ for ( i = Start; (i < Stop) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ )
+#define Vec_FltForEachEntryReverse( vVec, pEntry, i ) \
+ for ( i = Vec_FltSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_FltEntry(vVec, i)), 1); i-- )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Flt_t * Vec_FltAlloc( int nCap )
+{
+ Vec_Flt_t * p;
+ p = ALLOC( Vec_Flt_t, 1 );
+ if ( nCap > 0 && nCap < 16 )
+ nCap = 16;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( float, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Flt_t * Vec_FltStart( int nSize )
+{
+ Vec_Flt_t * p;
+ p = Vec_FltAlloc( nSize );
+ p->nSize = nSize;
+ memset( p->pArray, 0, sizeof(float) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from a float array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Flt_t * Vec_FltAllocArray( float * pArray, int nSize )
+{
+ Vec_Flt_t * p;
+ p = ALLOC( Vec_Flt_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from a float array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Flt_t * Vec_FltAllocArrayCopy( float * pArray, int nSize )
+{
+ Vec_Flt_t * p;
+ p = ALLOC( Vec_Flt_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = ALLOC( float, nSize );
+ memcpy( p->pArray, pArray, sizeof(float) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the float array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Flt_t * Vec_FltDup( Vec_Flt_t * pVec )
+{
+ Vec_Flt_t * p;
+ p = ALLOC( Vec_Flt_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = p->nCap? ALLOC( float, p->nCap ) : NULL;
+ memcpy( p->pArray, pVec->pArray, sizeof(float) * pVec->nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the array into another vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Flt_t * Vec_FltDupArray( Vec_Flt_t * pVec )
+{
+ Vec_Flt_t * p;
+ p = ALLOC( Vec_Flt_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = pVec->pArray;
+ pVec->nSize = 0;
+ pVec->nCap = 0;
+ pVec->pArray = NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltFree( Vec_Flt_t * p )
+{
+ FREE( p->pArray );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline float * Vec_FltReleaseArray( Vec_Flt_t * p )
+{
+ float * pArray = p->pArray;
+ p->nCap = 0;
+ p->nSize = 0;
+ p->pArray = NULL;
+ return pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline float * Vec_FltArray( Vec_Flt_t * p )
+{
+ return p->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_FltSize( Vec_Flt_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline float Vec_FltEntry( Vec_Flt_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltWriteEntry( Vec_Flt_t * p, int i, float Entry )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltAddToEntry( Vec_Flt_t * p, int i, float Addition )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] += Addition;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline float Vec_FltEntryLast( Vec_Flt_t * p )
+{
+ return p->pArray[p->nSize-1];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the vector to the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltGrow( Vec_Flt_t * p, int nCapMin )
+{
+ if ( p->nCap >= nCapMin )
+ return;
+ p->pArray = REALLOC( float, p->pArray, nCapMin );
+ p->nCap = nCapMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltFill( Vec_Flt_t * p, int nSize, float Entry )
+{
+ int i;
+ Vec_FltGrow( p, nSize );
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltFillExtra( Vec_Flt_t * p, int nSize, float Entry )
+{
+ int i;
+ if ( p->nSize >= nSize )
+ return;
+ Vec_FltGrow( p, nSize );
+ for ( i = p->nSize; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltShrink( Vec_Flt_t * p, int nSizeNew )
+{
+ assert( p->nSize >= nSizeNew );
+ p->nSize = nSizeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltClear( Vec_Flt_t * p )
+{
+ p->nSize = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltPush( Vec_Flt_t * p, float Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_FltGrow( p, 16 );
+ else
+ Vec_FltGrow( p, 2 * p->nCap );
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// HA: Commented as proposed by Alan M.
+// static inline void Vec_FltPushMem( Extra_MmStep_t * pMemMan, Vec_Flt_t * p, float Entry )
+// {
+// if ( p->nSize == p->nCap )
+// {
+// float * pArray;
+// int i;
+
+// if ( p->nSize == 0 )
+// p->nCap = 1;
+// pArray = (float *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
+// // pArray = ALLOC( float, p->nCap * 2 );
+// if ( p->pArray )
+// {
+// for ( i = 0; i < p->nSize; i++ )
+// pArray[i] = p->pArray[i];
+// Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
+// // free( p->pArray );
+// }
+// p->nCap *= 2;
+// p->pArray = pArray;
+// }
+// p->pArray[p->nSize++] = Entry;
+// }
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltPushOrder( Vec_Flt_t * p, float Entry )
+{
+ int i;
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_FltGrow( p, 16 );
+ else
+ Vec_FltGrow( p, 2 * p->nCap );
+ }
+ p->nSize++;
+ for ( i = p->nSize-2; i >= 0; i-- )
+ if ( p->pArray[i] > Entry )
+ p->pArray[i+1] = p->pArray[i];
+ else
+ break;
+ p->pArray[i+1] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_FltPushUnique( Vec_Flt_t * p, float Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return 1;
+ Vec_FltPush( p, Entry );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the last entry and removes it from the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline float Vec_FltPop( Vec_Flt_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[--p->nSize];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find entry.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_FltFind( Vec_Flt_t * p, float Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_FltRemove( Vec_Flt_t * p, float Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ break;
+ if ( i == p->nSize )
+ return 0;
+ assert( i < p->nSize );
+ for ( i++; i < p->nSize; i++ )
+ p->pArray[i-1] = p->pArray[i];
+ p->nSize--;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two floats.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_FltSortCompare1( float * pp1, float * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two floats.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_FltSortCompare2( float * pp1, float * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 > *pp2 )
+ return -1;
+ if ( *pp1 < *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_FltSort( Vec_Flt_t * p, int fReverse )
+{
+ if ( fReverse )
+ qsort( (void *)p->pArray, p->nSize, sizeof(float),
+ (int (*)(const void *, const void *)) Vec_FltSortCompare2 );
+ else
+ qsort( (void *)p->pArray, p->nSize, sizeof(float),
+ (int (*)(const void *, const void *)) Vec_FltSortCompare1 );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/temp/aig_free/vecInt.h b/src/temp/aig_free/vecInt.h
new file mode 100644
index 00000000..77bf5849
--- /dev/null
+++ b/src/temp/aig_free/vecInt.h
@@ -0,0 +1,781 @@
+/**CFile****************************************************************
+
+ FileName [vecInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable arrays of integers.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_INT_H__
+#define __VEC_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+//HA: Commented as advised by Alan
+//#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Int_t_ Vec_Int_t;
+struct Vec_Int_t_
+{
+ int nCap;
+ int nSize;
+ int * pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define Vec_IntForEachEntry( vVec, Entry, i ) \
+ for ( i = 0; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
+#define Vec_IntForEachEntryStart( vVec, Entry, i, Start ) \
+ for ( i = Start; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
+#define Vec_IntForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \
+ for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
+#define Vec_IntForEachEntryReverse( vVec, pEntry, i ) \
+ for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntAlloc( int nCap )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ if ( nCap > 0 && nCap < 16 )
+ nCap = 16;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntStart( int nSize )
+{
+ Vec_Int_t * p;
+ p = Vec_IntAlloc( nSize );
+ p->nSize = nSize;
+ memset( p->pArray, 0, sizeof(int) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntAllocArrayCopy( int * pArray, int nSize )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = ALLOC( int, nSize );
+ memcpy( p->pArray, pArray, sizeof(int) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the integer array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntDup( Vec_Int_t * pVec )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
+ memcpy( p->pArray, pVec->pArray, sizeof(int) * pVec->nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the array into another vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntDupArray( Vec_Int_t * pVec )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = pVec->pArray;
+ pVec->nSize = 0;
+ pVec->nCap = 0;
+ pVec->pArray = NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFree( Vec_Int_t * p )
+{
+ FREE( p->pArray );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int * Vec_IntReleaseArray( Vec_Int_t * p )
+{
+ int * pArray = p->pArray;
+ p->nCap = 0;
+ p->nSize = 0;
+ p->pArray = NULL;
+ return pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int * Vec_IntArray( Vec_Int_t * p )
+{
+ return p->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSize( Vec_Int_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntEntry( Vec_Int_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] += Addition;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntEntryLast( Vec_Int_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[p->nSize-1];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the vector to the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
+{
+ if ( p->nCap >= nCapMin )
+ return;
+ p->pArray = REALLOC( int, p->pArray, nCapMin );
+ assert( p->pArray );
+ p->nCap = nCapMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry )
+{
+ int i;
+ Vec_IntGrow( p, nSize );
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry )
+{
+ int i;
+ if ( p->nSize >= nSize )
+ return;
+ Vec_IntGrow( p, nSize );
+ for ( i = p->nSize; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew )
+{
+ assert( p->nSize >= nSizeNew );
+ p->nSize = nSizeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntClear( Vec_Int_t * p )
+{
+ p->nSize = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry )
+{
+ int i;
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->nSize++;
+ for ( i = p->nSize - 1; i >= 1; i-- )
+ p->pArray[i] = p->pArray[i-1];
+ p->pArray[0] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// HA: Commented as advised by Alan M.
+// static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry )
+// {
+// if ( p->nSize == p->nCap )
+// {
+// int * pArray;
+// int i;
+
+// if ( p->nSize == 0 )
+// p->nCap = 1;
+// if ( pMemMan )
+// pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
+// else
+// pArray = ALLOC( int, p->nCap * 2 );
+// if ( p->pArray )
+// {
+// for ( i = 0; i < p->nSize; i++ )
+// pArray[i] = p->pArray[i];
+// if ( pMemMan )
+// Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
+// else
+// free( p->pArray );
+// }
+// p->nCap *= 2;
+// p->pArray = pArray;
+// }
+// p->pArray[p->nSize++] = Entry;
+//}
+
+/**Function*************************************************************
+
+ Synopsis [Inserts the entry while preserving the increasing order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
+{
+ int i;
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->nSize++;
+ for ( i = p->nSize-2; i >= 0; i-- )
+ if ( p->pArray[i] > Entry )
+ p->pArray[i+1] = p->pArray[i];
+ else
+ break;
+ p->pArray[i+1] = 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 []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return 1;
+ Vec_IntPush( p, Entry );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the pointer to the next nWords entries in the vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned * Vec_IntFetch( Vec_Int_t * p, int nWords )
+{
+ p->nSize += nWords;
+ if ( p->nSize > p->nCap )
+ {
+// Vec_IntGrow( p, 2 * p->nSize );
+ return NULL;
+ }
+ return ((unsigned *)p->pArray) + p->nSize - nWords;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the last entry and removes it from the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntPop( Vec_Int_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[--p->nSize];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find entry.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntFind( Vec_Int_t * p, int Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntRemove( Vec_Int_t * p, int Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ break;
+ if ( i == p->nSize )
+ return 0;
+ assert( i < p->nSize );
+ for ( i++; i < p->nSize; i++ )
+ p->pArray[i-1] = p->pArray[i];
+ p->nSize--;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two integers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSortCompare1( int * pp1, int * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two integers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSortCompare2( int * pp1, int * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 > *pp2 )
+ return -1;
+ if ( *pp1 < *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntSort( Vec_Int_t * p, int fReverse )
+{
+ if ( fReverse )
+ qsort( (void *)p->pArray, p->nSize, sizeof(int),
+ (int (*)(const void *, const void *)) Vec_IntSortCompare2 );
+ else
+ qsort( (void *)p->pArray, p->nSize, sizeof(int),
+ (int (*)(const void *, const void *)) Vec_IntSortCompare1 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two integers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSortCompareUnsigned( unsigned * pp1, unsigned * pp2 )
+{
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntSortUnsigned( Vec_Int_t * p )
+{
+ qsort( (void *)p->pArray, p->nSize, sizeof(int),
+ (int (*)(const void *, const void *)) Vec_IntSortCompareUnsigned );
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/temp/aig_free/vecPtr.h b/src/temp/aig_free/vecPtr.h
new file mode 100644
index 00000000..72678ed6
--- /dev/null
+++ b/src/temp/aig_free/vecPtr.h
@@ -0,0 +1,587 @@
+/**CFile****************************************************************
+
+ FileName [vecPtr.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable arrays of generic pointers.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecPtr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_PTR_H__
+#define __VEC_PTR_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+//#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Ptr_t_ Vec_Ptr_t;
+struct Vec_Ptr_t_
+{
+ int nCap;
+ int nSize;
+ void ** pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// iterators through entries
+#define Vec_PtrForEachEntry( vVec, pEntry, i ) \
+ for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
+#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \
+ for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
+#define Vec_PtrForEachEntryStop( vVec, pEntry, i, Stop ) \
+ for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
+#define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop ) \
+ for ( i = Start; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
+#define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \
+ for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ if ( nCap > 0 && nCap < 8 )
+ nCap = 8;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrStart( int nSize )
+{
+ Vec_Ptr_t * p;
+ p = Vec_PtrAlloc( nSize );
+ p->nSize = nSize;
+ memset( p->pArray, 0, sizeof(void *) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrAllocArray( void ** pArray, int nSize )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrAllocArrayCopy( void ** pArray, int nSize )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = ALLOC( void *, nSize );
+ memcpy( p->pArray, pArray, sizeof(void *) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the integer array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrDup( Vec_Ptr_t * pVec )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
+ memcpy( p->pArray, pVec->pArray, sizeof(void *) * pVec->nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the array into another vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrDupArray( Vec_Ptr_t * pVec )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = pVec->pArray;
+ pVec->nSize = 0;
+ pVec->nCap = 0;
+ pVec->pArray = NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrFree( Vec_Ptr_t * p )
+{
+ FREE( p->pArray );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void ** Vec_PtrReleaseArray( Vec_Ptr_t * p )
+{
+ void ** pArray = p->pArray;
+ p->nCap = 0;
+ p->nSize = 0;
+ p->pArray = NULL;
+ return pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void ** Vec_PtrArray( Vec_Ptr_t * p )
+{
+ return p->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_PtrSize( Vec_Ptr_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void ** Vec_PtrEntryP( Vec_Ptr_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray + i;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[p->nSize-1];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the vector to the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin )
+{
+ if ( p->nCap >= nCapMin )
+ return;
+ p->pArray = REALLOC( void *, p->pArray, nCapMin );
+ p->nCap = nCapMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry )
+{
+ int i;
+ Vec_PtrGrow( p, nSize );
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
+{
+ int i;
+ if ( p->nSize >= nSize )
+ return;
+ if ( p->nSize < 2 * nSize )
+ Vec_PtrGrow( p, 2 * nSize );
+ else
+ Vec_PtrGrow( p, p->nSize );
+ for ( i = p->nSize; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrShrink( Vec_Ptr_t * p, int nSizeNew )
+{
+ assert( p->nSize >= nSizeNew );
+ p->nSize = nSizeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrClear( Vec_Ptr_t * p )
+{
+ p->nSize = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_PtrGrow( p, 16 );
+ else
+ Vec_PtrGrow( p, 2 * p->nCap );
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_PtrPushUnique( Vec_Ptr_t * p, void * Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return 1;
+ Vec_PtrPush( p, Entry );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the last entry and removes it from the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void * Vec_PtrPop( Vec_Ptr_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[--p->nSize];
+}
+
+/**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 []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry )
+{
+ int i;
+ // delete assuming that it is closer to the end
+ for ( i = p->nSize - 1; i >= 0; i-- )
+ if ( p->pArray[i] == Entry )
+ break;
+ assert( i >= 0 );
+/*
+ // delete assuming that it is closer to the beginning
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ break;
+ assert( i < p->nSize );
+*/
+ for ( i++; i < p->nSize; i++ )
+ p->pArray[i-1] = p->pArray[i];
+ p->nSize--;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Moves the first nItems to the end.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
+{
+ assert( nItems < p->nSize );
+ Vec_PtrGrow( p, nItems + p->nSize );
+ memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) );
+ memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
+{
+ qsort( (void *)p->pArray, p->nSize, sizeof(void *),
+ (int (*)(const void *, const void *)) Vec_PtrSortCompare );
+}
+
+#endif
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/temp/aig_free/vecStr.h b/src/temp/aig_free/vecStr.h
new file mode 100644
index 00000000..a36734f6
--- /dev/null
+++ b/src/temp/aig_free/vecStr.h
@@ -0,0 +1,510 @@
+/**CFile****************************************************************
+
+ FileName [vecStr.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable arrays of characters.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecStr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_STR_H__
+#define __VEC_STR_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+//#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Str_t_ Vec_Str_t;
+struct Vec_Str_t_
+{
+ int nCap;
+ int nSize;
+ char * pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define Vec_StrForEachEntry( vVec, Entry, i ) \
+ for ( i = 0; (i < Vec_StrSize(vVec)) && (((Entry) = Vec_StrEntry(vVec, i)), 1); i++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrAlloc( int nCap )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ if ( nCap > 0 && nCap < 16 )
+ nCap = 16;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrStart( int nSize )
+{
+ Vec_Str_t * p;
+ p = Vec_StrAlloc( nSize );
+ p->nSize = nSize;
+ memset( p->pArray, 0, sizeof(char) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrAllocArrayCopy( char * pArray, int nSize )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = ALLOC( char, nSize );
+ memcpy( p->pArray, pArray, sizeof(char) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the integer array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrDup( Vec_Str_t * pVec )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
+ memcpy( p->pArray, pVec->pArray, sizeof(char) * pVec->nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the array into another vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = pVec->pArray;
+ pVec->nSize = 0;
+ pVec->nCap = 0;
+ pVec->pArray = NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrFree( Vec_Str_t * p )
+{
+ FREE( p->pArray );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char * Vec_StrReleaseArray( Vec_Str_t * p )
+{
+ char * pArray = p->pArray;
+ p->nCap = 0;
+ p->nSize = 0;
+ p->pArray = NULL;
+ return pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char * Vec_StrArray( Vec_Str_t * p )
+{
+ return p->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_StrSize( Vec_Str_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Vec_StrEntry( Vec_Str_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Vec_StrEntryLast( Vec_Str_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[p->nSize-1];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the vector to the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin )
+{
+ if ( p->nCap >= nCapMin )
+ return;
+ p->pArray = REALLOC( char, p->pArray, 2 * nCapMin );
+ p->nCap = 2 * nCapMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrFill( Vec_Str_t * p, int nSize, char Entry )
+{
+ int i;
+ Vec_StrGrow( p, nSize );
+ p->nSize = nSize;
+ for ( i = 0; i < p->nSize; i++ )
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrShrink( Vec_Str_t * p, int nSizeNew )
+{
+ assert( p->nSize >= nSizeNew );
+ p->nSize = nSizeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrClear( Vec_Str_t * p )
+{
+ p->nSize = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_StrGrow( p, 16 );
+ else
+ Vec_StrGrow( p, 2 * p->nCap );
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Appends the string to the char vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrAppend( Vec_Str_t * p, char * pString )
+{
+ int i, nLength = strlen(pString);
+ Vec_StrGrow( p, p->nSize + nLength );
+ for ( i = 0; i < nLength; i++ )
+ p->pArray[p->nSize + i] = pString[i];
+ p->nSize += nLength;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the last entry and removes it from the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Vec_StrPop( Vec_Str_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[--p->nSize];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_StrSortCompare1( char * pp1, char * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_StrSortCompare2( char * pp1, char * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 > *pp2 )
+ return -1;
+ if ( *pp1 < *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrSort( Vec_Str_t * p, int fReverse )
+{
+ if ( fReverse )
+ qsort( (void *)p->pArray, p->nSize, sizeof(char),
+ (int (*)(const void *, const void *)) Vec_StrSortCompare2 );
+ else
+ qsort( (void *)p->pArray, p->nSize, sizeof(char),
+ (int (*)(const void *, const void *)) Vec_StrSortCompare1 );
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/temp/aig_free/vecVec.h b/src/temp/aig_free/vecVec.h
new file mode 100644
index 00000000..2de38619
--- /dev/null
+++ b/src/temp/aig_free/vecVec.h
@@ -0,0 +1,289 @@
+/**CFile****************************************************************
+
+ FileName [vecVec.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable vector of resizable vectors.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_VEC_H__
+#define __VEC_VEC_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+//#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Vec_t_ Vec_Vec_t;
+struct Vec_Vec_t_
+{
+ int nCap;
+ int nSize;
+ void ** pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// iterators through levels
+#define Vec_VecForEachLevel( vGlob, vVec, i ) \
+ for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
+#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
+ for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
+#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
+ for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
+#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \
+ for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
+
+// iteratores through entries
+#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
+ for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
+ Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
+#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \
+ for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \
+ Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
+#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \
+ for ( i = LevelStart; i <= LevelStop; i++ ) \
+ Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
+#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \
+ for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
+ Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
+#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k ) \
+ for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- ) \
+ Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
+{
+ Vec_Vec_t * p;
+ p = ALLOC( Vec_Vec_t, 1 );
+ if ( nCap > 0 && nCap < 8 )
+ nCap = 8;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Vec_t * Vec_VecStart( int nSize )
+{
+ Vec_Vec_t * p;
+ int i;
+ p = Vec_VecAlloc( nSize );
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = Vec_PtrAlloc( 0 );
+ p->nSize = nSize;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
+{
+ int i;
+ if ( p->nSize >= Level + 1 )
+ return;
+ Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
+ for ( i = p->nSize; i <= Level; i++ )
+ p->pArray[i] = Vec_PtrAlloc( 0 );
+ p->nSize = Level + 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_VecSize( Vec_Vec_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void * Vec_VecEntry( Vec_Vec_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecFree( Vec_Vec_t * p )
+{
+ Vec_Ptr_t * vVec;
+ int i;
+ Vec_VecForEachLevel( p, vVec, i )
+ Vec_PtrFree( vVec );
+ Vec_PtrFree( (Vec_Ptr_t *)p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the vector of vectors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_VecSizeSize( Vec_Vec_t * p )
+{
+ Vec_Ptr_t * vVec;
+ int i, Counter = 0;
+ Vec_VecForEachLevel( p, vVec, i )
+ Counter += vVec->nSize;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecClear( Vec_Vec_t * p )
+{
+ Vec_Ptr_t * vVec;
+ int i;
+ Vec_VecForEachLevel( p, vVec, i )
+ Vec_PtrClear( vVec );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry )
+{
+ if ( p->nSize < Level + 1 )
+ {
+ int i;
+ Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
+ for ( i = p->nSize; i < Level + 1; i++ )
+ p->pArray[i] = Vec_PtrAlloc( 0 );
+ p->nSize = Level + 1;
+ }
+ Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry )
+{
+ if ( p->nSize < Level + 1 )
+ Vec_VecPush( p, Level, Entry );
+ else
+ Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry );
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/temp/esop/esop.h b/src/temp/esop/esop.h
new file mode 100644
index 00000000..5f95f371
--- /dev/null
+++ b/src/temp/esop/esop.h
@@ -0,0 +1,723 @@
+/**CFile****************************************************************
+
+ FileName [esop.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Cover manipulation package.]
+
+ Synopsis [Internal declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: esop.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __ESOP_H__
+#define __ESOP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include "vec.h"
+#include "mem.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Esop_Man_t_ Esop_Man_t;
+typedef struct Esop_Cube_t_ Esop_Cube_t;
+typedef struct Mem_Fixed_t_ Mem_Fixed_t;
+
+struct Esop_Man_t_
+{
+ int nVars; // the number of vars
+ int nWords; // the number of words
+ Mem_Fixed_t * pMemMan1; // memory manager for cubes
+ Mem_Fixed_t * pMemMan2; // memory manager for cubes
+ Mem_Fixed_t * pMemMan4; // memory manager for cubes
+ Mem_Fixed_t * pMemMan8; // memory manager for cubes
+ // temporary cubes
+ 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
+ Esop_Cube_t ** ppStore; // storage for cubes by number of literals
+};
+
+struct Esop_Cube_t_
+{
+ 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 Esop_CoverForEachCube( pCover, pCube ) \
+ for ( pCube = pCover; \
+ pCube; \
+ pCube = pCube->pNext )
+#define Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \
+ for ( pCube = pCover, \
+ pCube2 = pCube? pCube->pNext: NULL; \
+ pCube; \
+ pCube = pCube2, \
+ pCube2 = pCube? pCube->pNext: NULL )
+#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 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 Mem_Fixed_t * Mem_FixedStart( int nEntrySize );
+extern void Mem_FixedStop( Mem_Fixed_t * p, int fVerbose );
+extern char * Mem_FixedEntryFetch( Mem_Fixed_t * p );
+extern void Mem_FixedEntryRecycle( Mem_Fixed_t * p, char * pEntry );
+extern void Mem_FixedRestart( Mem_Fixed_t * p );
+extern int Mem_FixedReadMemUsage( Mem_Fixed_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.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Esop_Cube_t * Esop_CubeAlloc( Esop_Man_t * p )
+{
+ Esop_Cube_t * pCube;
+ if ( p->nWords <= 1 )
+ pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan1 );
+ else if ( p->nWords <= 2 )
+ pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan2 );
+ else if ( p->nWords <= 4 )
+ pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan4 );
+ else if ( p->nWords <= 8 )
+ pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan8 );
+ pCube->pNext = NULL;
+ pCube->nVars = p->nVars;
+ pCube->nWords = p->nWords;
+ pCube->nLits = 0;
+ memset( pCube->uData, 0xff, sizeof(unsigned) * p->nWords );
+ return pCube;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the cube representing elementary var.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Esop_Cube_t * Esop_CubeAllocVar( Esop_Man_t * p, int iVar, int fCompl )
+{
+ Esop_Cube_t * pCube;
+ pCube = Esop_CubeAlloc( p );
+ Esop_CubeXorBit( pCube, iVar*2+fCompl );
+ pCube->nLits = 1;
+ return pCube;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the cube.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Esop_Cube_t * Esop_CubeDup( Esop_Man_t * p, Esop_Cube_t * pCopy )
+{
+ Esop_Cube_t * pCube;
+ pCube = Esop_CubeAlloc( p );
+ memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords );
+ pCube->nLits = pCopy->nLits;
+ return pCube;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the cube.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Esop_CubeRecycle( Esop_Man_t * p, Esop_Cube_t * pCube )
+{
+ if ( pCube->nWords <= 1 )
+ Mem_FixedEntryRecycle( p->pMemMan1, (char *)pCube );
+ else if ( pCube->nWords <= 2 )
+ Mem_FixedEntryRecycle( p->pMemMan2, (char *)pCube );
+ else if ( pCube->nWords <= 4 )
+ Mem_FixedEntryRecycle( p->pMemMan4, (char *)pCube );
+ else if ( pCube->nWords <= 8 )
+ Mem_FixedEntryRecycle( p->pMemMan8, (char *)pCube );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the cube cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Esop_CoverRecycle( Esop_Man_t * p, Esop_Cube_t * pCover )
+{
+ Esop_Cube_t * pCube, * pCube2;
+ if ( pCover == NULL )
+ return;
+ if ( pCover->nWords <= 1 )
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Mem_FixedEntryRecycle( p->pMemMan1, (char *)pCube );
+ else if ( pCover->nWords <= 2 )
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Mem_FixedEntryRecycle( p->pMemMan2, (char *)pCube );
+ else if ( pCover->nWords <= 4 )
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Mem_FixedEntryRecycle( p->pMemMan4, (char *)pCube );
+ else if ( pCover->nWords <= 8 )
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ Mem_FixedEntryRecycle( 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;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of cubes in the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Esop_CubeCountLits( Esop_Cube_t * pCube )
+{
+ unsigned uData;
+ int Count = 0, i, w;
+ for ( w = 0; w < (int)pCube->nWords; w++ )
+ {
+ uData = pCube->uData[w] ^ (pCube->uData[w] >> 1);
+ for ( i = 0; i < 32; i += 2 )
+ if ( uData & (1 << i) )
+ Count++;
+ }
+ return Count;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of cubes in the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Esop_CubeGetLits( Esop_Cube_t * pCube, Vec_Int_t * vLits )
+{
+ unsigned uData;
+ int i, w;
+ Vec_IntClear( vLits );
+ for ( w = 0; w < (int)pCube->nWords; w++ )
+ {
+ uData = pCube->uData[w] ^ (pCube->uData[w] >> 1);
+ for ( i = 0; i < 32; i += 2 )
+ if ( uData & (1 << i) )
+ Vec_IntPush( vLits, w*16 + i/2 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of cubes in the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Esop_CoverCountCubes( Esop_Cube_t * pCover )
+{
+ Esop_Cube_t * pCube;
+ int Count = 0;
+ Esop_CoverForEachCube( pCover, pCube )
+ Count++;
+ return Count;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Checks if two cubes are disjoint.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Esop_CubesDisjoint( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
+{
+ unsigned uData;
+ int i;
+ assert( pCube0->nVars == pCube1->nVars );
+ for ( i = 0; i < (int)pCube0->nWords; i++ )
+ {
+ uData = pCube0->uData[i] & pCube1->uData[i];
+ uData = (uData | (uData >> 1)) & 0x55555555;
+ if ( uData != 0x55555555 )
+ return 1;
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the disjoint variables of the two cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Esop_CoverGetDisjVars( Esop_Cube_t * pThis, Esop_Cube_t * pCube, Vec_Int_t * vVars )
+{
+ unsigned uData;
+ int i, w;
+ Vec_IntClear( vVars );
+ for ( w = 0; w < (int)pCube->nWords; w++ )
+ {
+ uData = pThis->uData[w] & (pThis->uData[w] >> 1) & 0x55555555;
+ uData &= (pCube->uData[w] ^ (pCube->uData[w] >> 1));
+ if ( uData == 0 )
+ continue;
+ for ( i = 0; i < 32; i += 2 )
+ if ( uData & (1 << i) )
+ Vec_IntPush( vVars, w*16 + i/2 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if two cubes are disjoint.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Esop_CubesDistOne( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1, Esop_Cube_t * pTemp )
+{
+ unsigned uData;
+ int i, fFound = 0;
+ for ( i = 0; i < (int)pCube0->nWords; i++ )
+ {
+ uData = pCube0->uData[i] ^ pCube1->uData[i];
+ if ( uData == 0 )
+ {
+ if ( pTemp ) pTemp->uData[i] = 0;
+ continue;
+ }
+ if ( fFound )
+ return 0;
+ uData = (uData | (uData >> 1)) & 0x55555555;
+ if ( (uData & (uData-1)) > 0 ) // more than one 1
+ return 0;
+ if ( pTemp ) pTemp->uData[i] = uData | (uData << 1);
+ fFound = 1;
+ }
+ if ( fFound == 0 )
+ {
+ printf( "\n" );
+ Esop_CubeWrite( stdout, pCube0 );
+ Esop_CubeWrite( stdout, pCube1 );
+ printf( "Error: Esop_CubesDistOne() looks at two equal cubes!\n" );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if two cubes are disjoint.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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;
+ for ( i = 0; i < (int)pCube0->nWords; i++ )
+ {
+ uData = pCube0->uData[i] ^ pCube1->uData[i];
+ if ( uData == 0 )
+ continue;
+ if ( Var0 >= 0 && Var1 >= 0 ) // more than two 1s
+ return 0;
+ uData = (uData | (uData >> 1)) & 0x55555555;
+ if ( (Var0 >= 0 || Var1 >= 0) && (uData & (uData-1)) > 0 )
+ return 0;
+ for ( k = 0; k < 32; k += 2 )
+ if ( uData & (1 << k) )
+ {
+ if ( Var0 == -1 )
+ Var0 = 16 * i + k/2;
+ else if ( Var1 == -1 )
+ Var1 = 16 * i + k/2;
+ else
+ return 0;
+ }
+ /*
+ if ( Var0 >= 0 )
+ {
+ uData &= 0xFFFF;
+ uData2 = (uData >> 16);
+ if ( uData && uData2 )
+ return 0;
+ if ( uData )
+ {
+ }
+ uData }= uData2;
+ uData &= 0x
+ }
+ */
+ }
+ if ( Var0 >= 0 && Var1 >= 0 )
+ {
+ *pVar0 = Var0;
+ *pVar1 = Var1;
+ return 1;
+ }
+ if ( Var0 == -1 || Var1 == -1 )
+ {
+ printf( "\n" );
+ Esop_CubeWrite( stdout, pCube0 );
+ Esop_CubeWrite( stdout, pCube1 );
+ printf( "Error: Esop_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" );
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Makes the produce of two cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Esop_Cube_t * Esop_CubesProduct( Esop_Man_t * p, Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
+{
+ Esop_Cube_t * pCube;
+ int i;
+ assert( pCube0->nVars == pCube1->nVars );
+ pCube = Esop_CubeAlloc( p );
+ for ( i = 0; i < p->nWords; i++ )
+ pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i];
+ pCube->nLits = Esop_CubeCountLits( pCube );
+ return pCube;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Makes the produce of two cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Esop_Cube_t * Esop_CubesXor( Esop_Man_t * p, Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
+{
+ Esop_Cube_t * pCube;
+ int i;
+ assert( pCube0->nVars == pCube1->nVars );
+ pCube = Esop_CubeAlloc( p );
+ for ( i = 0; i < p->nWords; i++ )
+ pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i];
+ pCube->nLits = Esop_CubeCountLits( pCube );
+ return pCube;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Makes the produce of two cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Esop_CubesAreEqual( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
+{
+ int i;
+ for ( i = 0; i < (int)pCube0->nWords; i++ )
+ if ( pCube0->uData[i] != pCube1->uData[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if pCube1 is contained in pCube0, bitwise.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Esop_CubeIsContained( Esop_Cube_t * pCube0, Esop_Cube_t * pCube1 )
+{
+ int i;
+ for ( i = 0; i < (int)pCube0->nWords; i++ )
+ if ( (pCube0->uData[i] & pCube1->uData[i]) != pCube1->uData[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the cube into the result of merging.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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++ )
+ {
+ pCube->uData[w] = pCube->uData[w] ^ pDist->uData[w];
+ pCube->uData[w] |= (pDist->uData[w] & ~pMask->uData[w]);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the cube into the result of distance-1 merging.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Esop_CubesTransformOr( Esop_Cube_t * pCube, Esop_Cube_t * pDist )
+{
+ int w;
+ for ( w = 0; w < (int)pCube->nWords; w++ )
+ pCube->uData[w] |= pDist->uData[w];
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Sorts the cover in the increasing number of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Esop_CoverExpandRemoveEqual( Esop_Man_t * p, Esop_Cube_t * pCover )
+{
+ Esop_Cube_t * pCube, * pCube2, * pThis;
+ if ( pCover == NULL )
+ {
+ Esop_ManClean( p, p->nVars );
+ return;
+ }
+ Esop_ManClean( p, pCover->nVars );
+ Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 )
+ {
+ // go through the linked list
+ Esop_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
+ if ( Esop_CubesAreEqual( pCube, pThis ) )
+ {
+ Esop_CubeRecycle( p, pCube );
+ break;
+ }
+ if ( pThis != NULL )
+ continue;
+ pCube->pNext = p->ppStore[pCube->nLits];
+ p->ppStore[pCube->nLits] = pCube;
+ p->nCubes++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the given cube is contained in one of the cubes of the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Esop_CoverContainsCube( Esop_Man_t * p, Esop_Cube_t * pCube )
+{
+ Esop_Cube_t * pThis;
+ int i;
+/*
+ // this cube cannot be equal to any cube
+ Esop_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
+ {
+ if ( Esop_CubesAreEqual( pCube, pThis ) )
+ {
+ Esop_CubeWrite( stdout, pCube );
+ assert( 0 );
+ }
+ }
+*/
+ // try to find a containing cube
+ for ( i = 0; i <= (int)pCube->nLits; i++ )
+ Esop_CoverForEachCube( p->ppStore[i], pThis )
+ {
+ // skip the bubble
+ if ( pThis != p->pBubble && Esop_CubeIsContained( pThis, pCube ) )
+ return 1;
+ }
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/esop/esopMan.c b/src/temp/esop/esopMan.c
new file mode 100644
index 00000000..5c411349
--- /dev/null
+++ b/src/temp/esop/esopMan.c
@@ -0,0 +1,117 @@
+/**CFile****************************************************************
+
+ FileName [esopMan.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: esopMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "esop.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts the minimization manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Esop_Man_t * Esop_ManAlloc( int nVars )
+{
+ Esop_Man_t * pMan;
+ // start the manager
+ pMan = ALLOC( Esop_Man_t, 1 );
+ memset( pMan, 0, sizeof(Esop_Man_t) );
+ pMan->nVars = nVars;
+ pMan->nWords = Esop_BitWordNum( nVars * 2 );
+ pMan->pMemMan1 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (1 - 1) );
+ pMan->pMemMan2 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (2 - 1) );
+ pMan->pMemMan4 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (4 - 1) );
+ pMan->pMemMan8 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (8 - 1) );
+ // allocate storage for the temporary cover
+ pMan->ppStore = ALLOC( Esop_Cube_t *, pMan->nVars + 1 );
+ // create tautology cubes
+ 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
+ Esop_ManClean( pMan, 1 );
+ pMan->pTriv0 = Esop_CubeAllocVar( pMan, 0, 0 );
+ pMan->pTriv1 = Esop_CubeAllocVar( pMan, 0, 0 );
+ Esop_ManClean( pMan, nVars );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cleans the minimization manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_ManClean( Esop_Man_t * p, int nSupp )
+{
+ // set the size of the cube manager
+ p->nVars = nSupp;
+ p->nWords = Esop_BitWordNum(2*nSupp);
+ // clean the storage
+ memset( p->ppStore, 0, sizeof(Esop_Cube_t *) * (nSupp + 1) );
+ p->nCubes = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the minimization manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_ManFree( Esop_Man_t * p )
+{
+ Mem_FixedStop ( p->pMemMan1, 0 );
+ Mem_FixedStop ( p->pMemMan2, 0 );
+ Mem_FixedStop ( p->pMemMan4, 0 );
+ Mem_FixedStop ( p->pMemMan8, 0 );
+ free( p->ppStore );
+ free( p );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/esop/esopMin.c b/src/temp/esop/esopMin.c
new file mode 100644
index 00000000..7a460f8e
--- /dev/null
+++ b/src/temp/esop/esopMin.c
@@ -0,0 +1,299 @@
+/**CFile****************************************************************
+
+ FileName [esopMin.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Cover manipulation package.]
+
+ Synopsis [ESOP manipulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: esopMin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "esop.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Esop_EsopRewrite( Esop_Man_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [ESOP minimization procedure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_EsopMinimize( Esop_Man_t * p )
+{
+ int nCubesInit, nCubesOld, nIter;
+ if ( p->nCubes < 3 )
+ return;
+ nIter = 0;
+ nCubesInit = p->nCubes;
+ do {
+ nCubesOld = p->nCubes;
+ Esop_EsopRewrite( p );
+ nIter++;
+ }
+ while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 );
+
+// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of rewriting using distance 2 cubes.]
+
+ Description [The weakness of this procedure is that it tries each cube
+ with only one distance-2 cube. If this pair does not lead to improvement
+ the cube is inserted into the cover anyhow, and we try another pair.
+ A possible improvement would be to try this cube with all distance-2
+ cubes, until an improvement is found, or until all such cubes are tried.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_EsopRewrite( Esop_Man_t * p )
+{
+ Esop_Cube_t * pCube, ** ppPrev;
+ Esop_Cube_t * pThis, ** ppPrevT;
+ int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld;
+ int nPairs = 0;
+
+ // 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
+ Esop_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
+ Esop_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
+ if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
+ break;
+ if ( pThis == NULL && Index < p->nVars )
+ Esop_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
+ if ( Esop_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
+ break;
+ if ( pThis == NULL && Index < p->nVars - 1 )
+ 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 )
+ {
+ // insert the bubble after the cube
+ p->pBubble->pNext = pCube->pNext;
+ pCube->pNext = p->pBubble;
+ p->pBubble->nLits = pCube->nLits;
+ continue;
+ }
+ nPairs++;
+
+ // 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;
+
+ // Exorlink-2:
+ // A{v00} B{v01} + A{v10} B{v11} =
+ // A{v00+v10} B{v01} + A{v10} B{v01+v11} =
+ // A{v00} B{v01+v11} + A{v00+v10} B{v11}
+
+ // save the dist2 parameters
+ v00 = Esop_CubeGetVar( pCube, Var0 );
+ v01 = Esop_CubeGetVar( pCube, Var1 );
+ v10 = Esop_CubeGetVar( pThis, Var0 );
+ v11 = Esop_CubeGetVar( pThis, Var1 );
+//printf( "\n" );
+//Esop_CubeWrite( stdout, pCube );
+//Esop_CubeWrite( stdout, pThis );
+
+ // derive the first pair of resulting cubes
+ Esop_CubeXorVar( pCube, Var0, v10 );
+ pCube->nLits -= (v00 != 3);
+ pCube->nLits += ((v00 ^ v10) != 3);
+ Esop_CubeXorVar( pThis, Var1, v01 );
+ pThis->nLits -= (v11 != 3);
+ pThis->nLits += ((v01 ^ v11) != 3);
+
+ // add the cubes
+ nCubesOld = p->nCubes;
+ Esop_EsopAddCube( p, pCube );
+ Esop_EsopAddCube( p, pThis );
+ // check if the cubes were absorbed
+ if ( p->nCubes < nCubesOld + 2 )
+ continue;
+
+ // pull out both cubes
+ assert( pThis == p->ppStore[pThis->nLits] );
+ p->ppStore[pThis->nLits] = pThis->pNext;
+ assert( pCube == p->ppStore[pCube->nLits] );
+ p->ppStore[pCube->nLits] = pCube->pNext;
+ p->nCubes -= 2;
+
+ // derive the second pair of resulting cubes
+ Esop_CubeXorVar( pCube, Var0, v10 );
+ pCube->nLits -= ((v00 ^ v10) != 3);
+ pCube->nLits += (v00 != 3);
+ Esop_CubeXorVar( pCube, Var1, v11 );
+ pCube->nLits -= (v01 != 3);
+ pCube->nLits += ((v01 ^ v11) != 3);
+
+ Esop_CubeXorVar( pThis, Var0, v00 );
+ pThis->nLits -= (v10 != 3);
+ pThis->nLits += ((v00 ^ v10) != 3);
+ Esop_CubeXorVar( pThis, Var1, v01 );
+ pThis->nLits -= ((v01 ^ v11) != 3);
+ pThis->nLits += (v11 != 3);
+
+ // add them anyhow
+ Esop_EsopAddCube( p, pCube );
+ Esop_EsopAddCube( p, pThis );
+ }
+// printf( "Pairs = %d ", nPairs );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the cube to storage.]
+
+ 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.
+ Do not forget to clean the storage!]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Esop_EsopAddCubeInt( Esop_Man_t * p, Esop_Cube_t * pCube )
+{
+ Esop_Cube_t * pThis, ** ppPrev;
+ // try to find the identical cube
+ Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
+ {
+ if ( Esop_CubesAreEqual( pCube, pThis ) )
+ {
+ *ppPrev = pThis->pNext;
+ 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 )
+ Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev )
+ {
+ if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
+ {
+ *ppPrev = pThis->pNext;
+ Esop_CubesTransform( pCube, pThis, p->pTemp );
+ pCube->nLits++;
+ Esop_CubeRecycle( p, pThis );
+ p->nCubes--;
+ return 1;
+ }
+ }
+ Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
+ {
+ if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
+ {
+ *ppPrev = pThis->pNext;
+ Esop_CubesTransform( pCube, pThis, p->pTemp );
+ pCube->nLits--;
+ Esop_CubeRecycle( p, pThis );
+ p->nCubes--;
+ return 1;
+ }
+ }
+ if ( pCube->nLits > 0 )
+ Esop_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev )
+ {
+ if ( Esop_CubesDistOne( pCube, pThis, p->pTemp ) )
+ {
+ *ppPrev = pThis->pNext;
+ Esop_CubesTransform( pCube, pThis, p->pTemp );
+ Esop_CubeRecycle( p, pThis );
+ p->nCubes--;
+ return 1;
+ }
+ }
+ // 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 Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube )
+{
+ assert( pCube != p->pBubble );
+ assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) );
+ while ( Esop_EsopAddCubeInt( p, pCube ) );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/esop/esopUtil.c b/src/temp/esop/esopUtil.c
new file mode 100644
index 00000000..7230cc87
--- /dev/null
+++ b/src/temp/esop/esopUtil.c
@@ -0,0 +1,277 @@
+/**CFile****************************************************************
+
+ FileName [esopUtil.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Cover manipulation package.]
+
+ Synopsis [Utilities.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: esopUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "esop.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_CubeWrite( FILE * pFile, Esop_Cube_t * pCube )
+{
+ int i;
+ assert( (int)pCube->nLits == Esop_CubeCountLits(pCube) );
+ for ( i = 0; i < (int)pCube->nVars; i++ )
+ if ( Esop_CubeHasBit(pCube, i*2) )
+ {
+ if ( Esop_CubeHasBit(pCube, i*2+1) )
+ fprintf( pFile, "-" );
+ else
+ fprintf( pFile, "0" );
+ }
+ else
+ {
+ if ( Esop_CubeHasBit(pCube, i*2+1) )
+ fprintf( pFile, "1" );
+ else
+ fprintf( pFile, "?" );
+ }
+ fprintf( pFile, " 1\n" );
+// fprintf( pFile, " %d\n", pCube->nLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_CoverWrite( FILE * pFile, Esop_Cube_t * pCover )
+{
+ Esop_Cube_t * pCube;
+ Esop_CoverForEachCube( pCover, pCube )
+ Esop_CubeWrite( pFile, pCube );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_CoverWriteStore( FILE * pFile, Esop_Man_t * p )
+{
+ Esop_Cube_t * pCube;
+ int i;
+ for ( i = 0; i <= p->nVars; i++ )
+ {
+ Esop_CoverForEachCube( p->ppStore[i], pCube )
+ {
+ printf( "%2d : ", i );
+ if ( pCube == p->pBubble )
+ {
+ printf( "Bubble\n" );
+ continue;
+ }
+ Esop_CubeWrite( pFile, pCube );
+ }
+ }
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop )
+{
+ char Buffer[1000];
+ Esop_Cube_t * pCube;
+ FILE * pFile;
+ int i;
+ sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" );
+ for ( i = strlen(Buffer) - 1; i >= 0; i-- )
+ if ( Buffer[i] == '<' || Buffer[i] == '>' )
+ Buffer[i] = '_';
+ pFile = fopen( Buffer, "w" );
+ fprintf( pFile, "# %s cover for output %s generated by ABC\n", fEsop? "ESOP":"SOP", pName );
+ fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 );
+ fprintf( pFile, ".o %d\n", 1 );
+ fprintf( pFile, ".p %d\n", Esop_CoverCountCubes(pCover) );
+ if ( fEsop ) fprintf( pFile, ".type esop\n" );
+ Esop_CoverForEachCube( pCover, pCube )
+ Esop_CubeWrite( pFile, pCube );
+ fprintf( pFile, ".e\n" );
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_CoverCheck( Esop_Man_t * p )
+{
+ Esop_Cube_t * pCube;
+ int i;
+ for ( i = 0; i <= p->nVars; i++ )
+ Esop_CoverForEachCube( p->ppStore[i], pCube )
+ assert( i == (int)pCube->nLits );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Esop_CubeCheck( Esop_Cube_t * pCube )
+{
+ int i;
+ for ( i = 0; i < (int)pCube->nVars; i++ )
+ if ( Esop_CubeGetVar( pCube, i ) == 0 )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the cover from the sorted structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Esop_Cube_t * Esop_CoverCollect( Esop_Man_t * p, int nSuppSize )
+{
+ Esop_Cube_t * pCov = NULL, ** ppTail = &pCov;
+ Esop_Cube_t * pCube, * pCube2;
+ int i;
+ for ( i = 0; i <= nSuppSize; i++ )
+ {
+ Esop_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 )
+ {
+ assert( i == (int)pCube->nLits );
+ *ppTail = pCube;
+ ppTail = &pCube->pNext;
+ assert( pCube->uData[0] ); // not a bubble
+ }
+ }
+ *ppTail = NULL;
+ return pCov;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorts the cover in the increasing number of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Esop_CoverExpand( Esop_Man_t * p, Esop_Cube_t * pCover )
+{
+ 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;
+ p->nCubes++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorts the cover in the increasing number of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Esop_CoverSuppVarNum( Esop_Man_t * p, Esop_Cube_t * pCover )
+{
+ Esop_Cube_t * pCube;
+ int i, Counter;
+ if ( pCover == NULL )
+ return 0;
+ // clean the cube
+ for ( i = 0; i < (int)pCover->nWords; i++ )
+ p->pTemp->uData[i] = ~((unsigned)0);
+ // add the bit data
+ 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 += ( Esop_CubeGetVar(p->pTemp, i) != 3 );
+ return Counter;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/esop/module.make b/src/temp/esop/module.make
new file mode 100644
index 00000000..1003ccc1
--- /dev/null
+++ b/src/temp/esop/module.make
@@ -0,0 +1,3 @@
+SRC += src/temp/esop/esopMan.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
index e7c9bc2e..eb5f50e4 100644
--- a/src/temp/ivy/ivy.h
+++ b/src/temp/ivy/ivy.h
@@ -183,10 +183,10 @@ static inline int Ivy_InfoHasBit( unsigned * p, int i ) { return (p[(i
static inline void Ivy_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
static inline void Ivy_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
-static inline Ivy_Obj_t * Ivy_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(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_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned long)(p) & ~01); }
+static inline Ivy_Obj_t * Ivy_Not( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned long)(p) ^ 01); }
+static inline Ivy_Obj_t * Ivy_NotCond( Ivy_Obj_t * p, int c ) { return (Ivy_Obj_t *)((unsigned long)(p) ^ (c)); }
+static inline int Ivy_IsComplement( Ivy_Obj_t * p ) { return (int )(((unsigned long)p) & 01); }
static inline Ivy_Obj_t * Ivy_ManConst0( Ivy_Man_t * p ) { return Ivy_Not(p->pConst1); }
static inline Ivy_Obj_t * Ivy_ManConst1( Ivy_Man_t * p ) { return p->pConst1; }
@@ -471,6 +471,7 @@ extern int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t *
extern Ivy_Man_t * Ivy_ManStart();
extern Ivy_Man_t * Ivy_ManStartFrom( Ivy_Man_t * p );
extern Ivy_Man_t * Ivy_ManDup( Ivy_Man_t * p );
+extern Ivy_Man_t * Ivy_ManFrames( Ivy_Man_t * pMan, int nLatches, int nFrames, int fInit, Vec_Ptr_t ** pvMapping );
extern void Ivy_ManStop( Ivy_Man_t * p );
extern int Ivy_ManCleanup( Ivy_Man_t * p );
extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel );
@@ -538,7 +539,7 @@ extern void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj,
extern int Ivy_ObjIsMuxType( Ivy_Obj_t * pObj );
extern Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pObj, Ivy_Obj_t ** ppObjT, Ivy_Obj_t ** ppObjE );
extern Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj );
-extern void Ivy_ObjPrintVerbose( Ivy_Obj_t * pObj, int fHaig );
+extern void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fHaig );
extern void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig );
#ifdef __cplusplus
diff --git a/src/temp/ivy/ivyFraig.c b/src/temp/ivy/ivyFraig.c
index 9c729b23..694d5a30 100644
--- a/src/temp/ivy/ivyFraig.c
+++ b/src/temp/ivy/ivyFraig.c
@@ -1807,7 +1807,7 @@ void Ivy_FraigMiterProve( Ivy_FraigMan_t * p )
***********************************************************************/
void Ivy_FraigSweep( Ivy_FraigMan_t * p )
{
- Ivy_Obj_t * pObj;
+ Ivy_Obj_t * pObj;//, * pTemp;
int i, k = 0;
p->nClassesZero = p->lClasses.pHead? (Ivy_ObjIsConst1(p->lClasses.pHead) ? Ivy_FraigCountClassNodes(p->lClasses.pHead) : 0) : 0;
p->nClassesBeg = p->lClasses.nItems;
@@ -1817,6 +1817,9 @@ p->nClassesBeg = p->lClasses.nItems;
{
Extra_ProgressBarUpdate( p->pProgress, k++, NULL );
pObj->pEquiv = Ivy_FraigAnd( p, pObj );
+ assert( pObj->pEquiv != NULL );
+// pTemp = Ivy_Regular(pObj->pEquiv);
+// assert( Ivy_Regular(pObj->pEquiv)->Type );
}
Extra_ProgressBarStop( p->pProgress );
p->nClassesEnd = p->lClasses.nItems;
diff --git a/src/temp/ivy/ivyHaig.c b/src/temp/ivy/ivyHaig.c
index ca68c3c6..87021600 100644
--- a/src/temp/ivy/ivyHaig.c
+++ b/src/temp/ivy/ivyHaig.c
@@ -44,7 +44,7 @@ static inline Ivy_Obj_t * Ivy_HaigObjRepr( Ivy_Obj_t * pObj )
{
Ivy_Obj_t * pTemp;
assert( !Ivy_IsComplement(pObj) );
- // if the node has no equivalent or has fanout, it is representative
+ // if the node has no equivalent node or has fanout, it is representative
if ( pObj->pEquiv == NULL || Ivy_ObjRefs(pObj) > 0 )
return pObj;
// the node belongs to a class and is not a representative
@@ -110,6 +110,14 @@ void Ivy_ManHaigStart( Ivy_Man_t * p, int fVerbose )
Vec_IntPush( vLatches, pObj->Id );
}
p->pHaig->pData = vLatches;
+/*
+ {
+ int x;
+ Ivy_ManShow( p, 0, NULL );
+ Ivy_ManShow( p->pHaig, 1, NULL );
+ x = 0;
+ }
+*/
}
/**Function*************************************************************
@@ -257,7 +265,7 @@ void Ivy_ManHaigCreateChoice( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pO
return;
// if the second node belongs to a class, do not merge classes (for the time being)
if ( Ivy_ObjRefs(pObjOldHaigR) == 0 || pObjNewHaigR->pEquiv != NULL ||
- Ivy_ObjRefs(pObjNewHaigR) > 0 || Ivy_ObjIsInTfi_rec(pObjNewHaigR, pObjOldHaigR, 10) )
+ Ivy_ObjRefs(pObjNewHaigR) > 0 ) //|| Ivy_ObjIsInTfi_rec(pObjNewHaigR, pObjOldHaigR, 10) )
{
/*
if ( pObjNewHaigR->pEquiv != NULL )
@@ -363,8 +371,8 @@ void Ivy_ManHaigPostprocess( Ivy_Man_t * p, int fVerbose )
else
printf( "HAIG contains a cycle\n" );
- if ( fVerbose )
- Ivy_ManHaigSimulate( p );
+// if ( fVerbose )
+// Ivy_ManHaigSimulate( p );
}
diff --git a/src/temp/ivy/ivyMan.c b/src/temp/ivy/ivyMan.c
index e2689580..8099b834 100644
--- a/src/temp/ivy/ivyMan.c
+++ b/src/temp/ivy/ivyMan.c
@@ -46,9 +46,9 @@ Ivy_Man_t * Ivy_ManStart()
p = ALLOC( Ivy_Man_t, 1 );
memset( p, 0, sizeof(Ivy_Man_t) );
// perform initializations
- p->Ghost.Id = -1;
- p->nTravIds = 1;
- p->fCatchExor = 1;
+ p->Ghost.Id = -1;
+ p->nTravIds = 1;
+ p->fCatchExor = 1;
// allocate arrays for nodes
p->vPis = Vec_PtrAlloc( 100 );
p->vPos = Vec_PtrAlloc( 100 );
@@ -166,6 +166,72 @@ Ivy_Man_t * Ivy_ManDup( Ivy_Man_t * p )
SeeAlso []
***********************************************************************/
+Ivy_Man_t * Ivy_ManFrames( Ivy_Man_t * pMan, int nLatches, int nFrames, int fInit, Vec_Ptr_t ** pvMapping )
+{
+ Vec_Ptr_t * vMapping;
+ Ivy_Man_t * pNew;
+ Ivy_Obj_t * pObj;
+ int i, f, nPis, nPos, nIdMax;
+ assert( Ivy_ManLatchNum(pMan) == 0 );
+ assert( nFrames > 0 );
+ // prepare the mapping
+ nPis = Ivy_ManPiNum(pMan) - nLatches;
+ nPos = Ivy_ManPoNum(pMan) - nLatches;
+ nIdMax = Ivy_ManObjIdMax(pMan);
+ // create the new manager
+ pNew = Ivy_ManStart();
+ // set the starting values of latch inputs
+ for ( i = 0; i < nLatches; i++ )
+ Ivy_ManPo(pMan, nPos+i)->pEquiv = fInit? Ivy_Not(Ivy_ManConst1(pNew)) : Ivy_ObjCreatePi(pNew);
+ // add timeframes
+ vMapping = Vec_PtrStart( nIdMax * nFrames + 1 );
+ for ( f = 0; f < nFrames; f++ )
+ {
+ // create PIs
+ Ivy_ManConst1(pMan)->pEquiv = Ivy_ManConst1(pNew);
+ for ( i = 0; i < nPis; i++ )
+ Ivy_ManPi(pMan, i)->pEquiv = Ivy_ObjCreatePi(pNew);
+ // transfer values to latch outputs
+ for ( i = 0; i < nLatches; i++ )
+ Ivy_ManPi(pMan, nPis+i)->pEquiv = Ivy_ManPo(pMan, nPos+i)->pEquiv;
+ // perform strashing
+ Ivy_ManForEachNode( pMan, pObj, i )
+ pObj->pEquiv = Ivy_And( pNew, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) );
+ // create POs
+ for ( i = 0; i < nPos; i++ )
+ Ivy_ManPo(pMan, i)->pEquiv = Ivy_ObjCreatePo( pNew, Ivy_ObjChild0Equiv(Ivy_ManPo(pMan, i)) );
+ // set the results of latch inputs
+ for ( i = 0; i < nLatches; i++ )
+ Ivy_ManPo(pMan, nPos+i)->pEquiv = Ivy_ObjChild0Equiv(Ivy_ManPo(pMan, nPos+i));
+ // save the pointers in this frame
+ Ivy_ManForEachObj( pMan, pObj, i )
+ Vec_PtrWriteEntry( vMapping, f * nIdMax + i, pObj->pEquiv );
+ }
+ // connect latches
+ if ( !fInit )
+ for ( i = 0; i < nLatches; i++ )
+ Ivy_ObjCreatePo( pNew, Ivy_ManPo(pMan, nPos+i)->pEquiv );
+ // remove dangling nodes
+ Ivy_ManCleanup(pNew);
+ *pvMapping = vMapping;
+ // check the resulting network
+ if ( !Ivy_ManCheck(pNew) )
+ printf( "Ivy_ManFrames(): The check has failed.\n" );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Stops the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Ivy_ManStop( Ivy_Man_t * p )
{
if ( p->time1 ) { PRT( "Update lev ", p->time1 ); }
@@ -291,6 +357,46 @@ int Ivy_ManCleanupSeq( Ivy_Man_t * p )
return RetValue;
}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if latches form self-loop.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ManLatchIsSelfFeed_rec( Ivy_Obj_t * pLatch, Ivy_Obj_t * pLatchRoot )
+{
+ if ( !Ivy_ObjIsLatch(pLatch) && !Ivy_ObjIsBuf(pLatch) )
+ return 0;
+ if ( pLatch == pLatchRoot )
+ return 1;
+ return Ivy_ManLatchIsSelfFeed_rec( Ivy_ObjFanin0(pLatch), pLatchRoot );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if latches form self-loop.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ivy_ManLatchIsSelfFeed( Ivy_Obj_t * pLatch )
+{
+ if ( !Ivy_ObjIsLatch(pLatch) )
+ return 0;
+ return Ivy_ManLatchIsSelfFeed_rec( Ivy_ObjFanin0(pLatch), pLatch );
+}
+
+
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
@@ -305,23 +411,30 @@ int Ivy_ManCleanupSeq( Ivy_Man_t * p )
int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel )
{
Ivy_Obj_t * pNode;
- int LimitFactor = 20;
+ int LimitFactor = 100;
+ int NodeBeg = Ivy_ManNodeNum(p);
int nSteps;
for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ )
{
pNode = Vec_PtrEntryLast(p->vBufs);
while ( Ivy_ObjIsBuf(pNode) )
pNode = Ivy_ObjReadFirstFanout( p, pNode );
+ // check if this buffer should remain
+ if ( Ivy_ManLatchIsSelfFeed(pNode) )
+ {
+ Vec_PtrPop(p->vBufs);
+ continue;
+ }
//printf( "Propagating buffer %d with input %d and output %d\n", Ivy_ObjFaninId0(pNode), Ivy_ObjFaninId0(Ivy_ObjFanin0(pNode)), pNode->Id );
//printf( "Latch num %d\n", Ivy_ManLatchNum(p) );
Ivy_NodeFixBufferFanins( p, pNode, fUpdateLevel );
- if ( nSteps > Ivy_ManNodeNum(p) * LimitFactor )
+ if ( nSteps > NodeBeg * LimitFactor )
{
- printf( "This circuit cannot be forward retimed completely. Structural hashing is not finished after %d forward latch moves.\n", Ivy_ManNodeNum(p) * LimitFactor );
+ printf( "This circuit cannot be forward retimed completely. Structural hashing is not finished after %d forward latch moves.\n", NodeBeg * LimitFactor );
break;
}
}
-// printf( "Number of steps = %d\n", nSteps );
+ printf( "Number of steps = %d. Nodes beg = %d. Nodes end = %d.\n", nSteps, NodeBeg, Ivy_ManNodeNum(p) );
return nSteps;
}
@@ -416,6 +529,8 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits )
*/
// perform hashing by propagating the buffers
Ivy_ManPropagateBuffers( p, 0 );
+ if ( Ivy_ManBufNum(p) )
+ printf( "The number of remaining buffers is %d.\n", Ivy_ManBufNum(p) );
// fix the levels
Ivy_ManResetLevels( p );
// check the resulting network
diff --git a/src/temp/ivy/ivyObj.c b/src/temp/ivy/ivyObj.c
index d9887c5b..59dda19c 100644
--- a/src/temp/ivy/ivyObj.c
+++ b/src/temp/ivy/ivyObj.c
@@ -124,7 +124,7 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost )
p->nCreated++;
// printf( "Adding %sAIG node: ", p->pHaig==NULL? "H":" " );
-// Ivy_ObjPrintVerbose( pObj, p->pHaig==NULL );
+// Ivy_ObjPrintVerbose( p, pObj, p->pHaig==NULL );
// printf( "\n" );
// if HAIG is defined, create a corresponding node
@@ -234,7 +234,7 @@ void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew
if ( p->fFanout )
Ivy_ObjAddFanout( p, Ivy_Regular(pFaninNew), pObj );
// get rid of old fanin
- if ( !Ivy_ObjIsPi(pFaninOld) && Ivy_ObjRefs(pFaninOld) == 0 )
+ if ( !Ivy_ObjIsPi(pFaninOld) && !Ivy_ObjIsConst1(pFaninOld) && Ivy_ObjRefs(pFaninOld) == 0 )
Ivy_ObjDelete_rec( p, pFaninOld, 1 );
}
@@ -333,6 +333,8 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) );
// the object cannot be the same
assert( pObjOld != Ivy_Regular(pObjNew) );
+//printf( "Replacing %d by %d.\n", Ivy_Regular(pObjOld)->Id, Ivy_Regular(pObjNew)->Id );
+
// if HAIG is defined, create the choice node
if ( p->pHaig )
{
@@ -410,8 +412,8 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
if ( p->pHaig )
{
int x;
- Ivy_ManShow( p, 0 );
- Ivy_ManShow( p->pHaig, 1 );
+ Ivy_ManShow( p, 0, NULL );
+ Ivy_ManShow( p->pHaig, 1, NULL );
x = 0;
}
*/
@@ -458,6 +460,11 @@ void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel
pResult = Ivy_Latch( p, pFanReal0, Ivy_ObjInit(pNode) );
else
assert( 0 );
+
+//printf( "===== Replacing %d by %d.\n", pNode->Id, pResult->Id );
+//Ivy_ObjPrintVerbose( p, pNode, 0 ); printf( "\n" );
+//Ivy_ObjPrintVerbose( p, pResult, 0 ); printf( "\n" );
+
// perform the replacement
Ivy_ObjReplace( p, pNode, pResult, 1, 0, fUpdateLevel );
}
diff --git a/src/temp/ivy/ivySeq.c b/src/temp/ivy/ivySeq.c
index 44a35d33..c1f3da2b 100644
--- a/src/temp/ivy/ivySeq.c
+++ b/src/temp/ivy/ivySeq.c
@@ -242,12 +242,14 @@ p->timeRes += clock() - clk;
if ( GainBest == -1 )
return -1;
-
/*
+ {
+ Ivy_Cut_t * pCut = p->pCut;
printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) );
for ( i = 0; i < pCut->nSize; i++ )
printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
printf( " }\n" );
+ }
*/
// copy the leaves
diff --git a/src/temp/ivy/ivyUtil.c b/src/temp/ivy/ivyUtil.c
index 3c53bd21..0e44c216 100644
--- a/src/temp/ivy/ivyUtil.c
+++ b/src/temp/ivy/ivyUtil.c
@@ -623,9 +623,10 @@ Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj )
SeeAlso []
***********************************************************************/
-void Ivy_ObjPrintVerbose( Ivy_Obj_t * pObj, int fHaig )
+void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fHaig )
{
Ivy_Obj_t * pTemp;
+ int fShowFanouts = 0;
assert( !Ivy_IsComplement(pObj) );
printf( "Node %5d : ", Ivy_ObjId(pObj) );
if ( Ivy_ObjIsConst1(pObj) )
@@ -635,14 +636,40 @@ void Ivy_ObjPrintVerbose( Ivy_Obj_t * pObj, int fHaig )
else if ( Ivy_ObjIsPo(pObj) )
printf( "PO" );
else if ( Ivy_ObjIsLatch(pObj) )
- printf( "latch %d%s", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") );
+ printf( "latch (%d%s)", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") );
else if ( Ivy_ObjIsBuf(pObj) )
- printf( "buffer %d%s", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") );
+ printf( "buffer (%d%s)", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") );
else
printf( "AND( %5d%s, %5d%s )",
Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " "),
Ivy_ObjFanin1(pObj)->Id, (Ivy_ObjFaninC1(pObj)? "\'" : " ") );
printf( " (refs = %3d)", Ivy_ObjRefs(pObj) );
+ if ( fShowFanouts )
+ {
+ Vec_Ptr_t * vFanouts;
+ Ivy_Obj_t * pFanout;
+ int i;
+ vFanouts = Vec_PtrAlloc( 10 );
+ printf( "\nFanouts:\n" );
+ Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i )
+ {
+ printf( " " );
+ printf( "Node %5d : ", Ivy_ObjId(pFanout) );
+ if ( Ivy_ObjIsPo(pFanout) )
+ printf( "PO" );
+ else if ( Ivy_ObjIsLatch(pFanout) )
+ printf( "latch (%d%s)", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " ") );
+ else if ( Ivy_ObjIsBuf(pFanout) )
+ printf( "buffer (%d%s)", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " ") );
+ else
+ printf( "AND( %5d%s, %5d%s )",
+ Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " "),
+ Ivy_ObjFanin1(pFanout)->Id, (Ivy_ObjFaninC1(pFanout)? "\'" : " ") );
+ printf( "\n" );
+ }
+ Vec_PtrFree( vFanouts );
+ return;
+ }
if ( !fHaig )
{
if ( pObj->pEquiv == NULL )
@@ -700,7 +727,7 @@ void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig )
printf( "\n" );
vNodes = Ivy_ManDfsSeq( p, NULL );
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
- Ivy_ObjPrintVerbose( pObj, fHaig ), printf( "\n" );
+ Ivy_ObjPrintVerbose( p, pObj, fHaig ), printf( "\n" );
printf( "\n" );
}
diff --git a/src/temp/player/module.make b/src/temp/player/module.make
new file mode 100644
index 00000000..5185f56e
--- /dev/null
+++ b/src/temp/player/module.make
@@ -0,0 +1,4 @@
+SRC += src/temp/player/playerToAbc.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..a4ee5650
--- /dev/null
+++ b/src/temp/player/player.h
@@ -0,0 +1,113 @@
+/**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 : 31; // the depth in terms of LUTs/PLAs
+ int nRefs; // 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_Man_t * p, Ivy_Obj_t * pObj ) { return (Pla_Man_t *)p->pData; }
+static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return ((Pla_Man_t *)p->pData)->pPlaStrs + pObj->Id; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== playerToAbc.c ==============================================================*/
+extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose );
+/*=== playerCore.c =============================================================*/
+extern Pla_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..dcbca462
--- /dev/null
+++ b/src/temp/player/playerAbc.c
@@ -0,0 +1,228 @@
+/**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 ///
+////////////////////////////////////////////////////////////////////////
+
+#if 0
+
+/**Function*************************************************************
+
+ Synopsis [Gives the current ABC network to PLAyer for processing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose )
+{
+ int fUseRewriting = 1;
+ 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 );
+ if ( fUseRewriting )
+ {
+ // simplify
+ pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 );
+ Ivy_ManStop( pManExt );
+ 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_AigConst1(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_AigConst1(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_EdgeId(Fanin) );
+ pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
+ Abc_ObjAddFanin( pObjNew, pFaninNew );
+ pCompls[k] = Ivy_EdgeIsComplement(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_EdgeId(Fanin) );
+ // get the new ABC node corresponding to the old fanin
+ pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );
+ if ( Ivy_EdgeIsComplement(Fanin) ) // complement
+ {
+// pFaninNew = Abc_NtkCreateNodeInv(pNtkNew, pFaninNew);
+ if ( Abc_ObjIsCi(pFaninNew) )
+ pFaninNew = Abc_NtkCreateNodeInv(pNtkNew, pFaninNew);
+ else
+ {
+ // clone the node
+ pObjNew = Abc_NtkCloneObj( 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;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/player/playerBuild.c b/src/temp/player/playerBuild.c
new file mode 100644
index 00000000..e878f19c
--- /dev/null
+++ b/src/temp/player/playerBuild.c
@@ -0,0 +1,283 @@
+/**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 ///
+////////////////////////////////////////////////////////////////////////
+
+#if 0
+
+/**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_EdgeCreate(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( pNew, 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_EdgeCreate(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_EdgeCreate(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_EdgeCreate(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_EdgeCreate( 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(pNew, pObjOld)->vSupp;
+ assert( Vec_IntSize(vSupp) <= 8 );
+ pTruth = Ivy_ObjGetTruth( pObjNew );
+ pComputed = Ivy_ManCutTruth( pNew, 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_EdgeCreate(0, 1) );
+ }
+ memcpy( pTruth, pComputed, sizeof(unsigned) * 8 );
+// Extra_PrintBinary( stdout, pTruth, 16 ); printf( "\n" );
+ }
+ Vec_IntFree( vTemp );
+ Vec_IntFree( vNodes );
+ return Counter;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/player/playerCore.c b/src/temp/player/playerCore.c
new file mode 100644
index 00000000..b87f39d4
--- /dev/null
+++ b/src/temp/player/playerCore.c
@@ -0,0 +1,376 @@
+/**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 []
+
+***********************************************************************/
+Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fVerbose )
+{
+ Pla_Man_t * p;
+ p = Pla_ManAlloc( pAig, nLutMax, nPlaMax );
+ if ( !Pla_ManDecomposeInt( p ) )
+ {
+ printf( "Decomposition/mapping failed.\n" );
+ Pla_ManFree( p );
+ return NULL;
+ }
+ return p;
+}
+
+/**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( pAig, 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( p->pManAig, pObj );
+ pStr0 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin0( pObj ) );
+ pStr1 = Ivy_ObjPlaStr( p->pManAig, 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;
+ }
+ assert( pStr->Depth );
+
+ // 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( p->pManAig, pObj );
+ pStr0 = Ivy_ObjPlaStr( p->pManAig, pFan0 );
+ pStr1 = Ivy_ObjPlaStr( p->pManAig, 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..32eacc9b
--- /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, Ivy_ManObjIdMax(pAig)+1 );
+ memset( pMan->pPlaStrs, 0, sizeof(Pla_Obj_t) * (Ivy_ManObjIdMax(pAig)+1) );
+ // 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_ManObjIdMax(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/playerToAbc.c b/src/temp/player/playerToAbc.c
new file mode 100644
index 00000000..81032826
--- /dev/null
+++ b/src/temp/player/playerToAbc.c
@@ -0,0 +1,523 @@
+/**CFile****************************************************************
+
+ FileName [playerToAbc.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: playerToAbc.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 * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode );
+static Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp );
+static Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp );
+static Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp );
+static int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose );
+
+static inline void Abc_ObjSetIvy2Abc( Ivy_Man_t * p, int IvyId, Abc_Obj_t * pObjAbc ) { assert(Vec_PtrEntry(p->pCopy, IvyId) == NULL); assert(!Abc_ObjIsComplement(pObjAbc)); Vec_PtrWriteEntry( p->pCopy, IvyId, pObjAbc ); }
+static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId ) { return Vec_PtrEntry( p->pCopy, IvyId ); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Applies PLA/LUT mapping to the ABC network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose )
+{
+ Pla_Man_t * p;
+ Ivy_Man_t * pMan, * pManExt;
+ Abc_Ntk_t * pNtkNew;
+ 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 );
+ if ( fRewriting )
+ {
+ // simplify
+ pMan = Ivy_ManResyn0( pManExt = pMan, 1, 0 );
+ Ivy_ManStop( pManExt );
+ if ( fVerbose )
+ Ivy_ManPrintStats( pMan );
+ }
+ if ( fSynthesis )
+ {
+ // simplify
+ pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 );
+ Ivy_ManStop( pManExt );
+ if ( fVerbose )
+ Ivy_ManPrintStats( pMan );
+ }
+ // perform decomposition
+ if ( fFastMode )
+ {
+ // perform mapping into LUTs
+ Ivy_FastMapPerform( pMan, nLutMax, 1, fVerbose );
+ // convert from the extended AIG manager into an SOP network
+ pNtkNew = Ivy_ManToAbc( pNtk, pMan, NULL, fFastMode );
+// pNtkNew = NULL;
+ Ivy_FastMapStop( pMan );
+ }
+ else
+ {
+ assert( nLutMax >= 2 && nLutMax <= 8 );
+ // perform decomposition/mapping into PLAs/LUTs
+ p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
+ // convert from the extended AIG manager into an SOP network
+ pNtkNew = Ivy_ManToAbc( pNtk, pMan, p, fFastMode );
+ Pla_ManFree( p );
+ }
+ Ivy_ManStop( pMan );
+ // chech the resulting network
+ if ( pNtkNew && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkPlayer: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+// Abc_NtkPlayerCost( pNtkNew, RankCost, fVerbose );
+ return pNtkNew;
+}
+
+/**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();
+ // create the PIs
+ Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ pObj->pCopy = (Abc_Obj_t *)Ivy_ObjCreatePi(pMan);
+ // perform the conversion of the internal nodes
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ pObj->pCopy = (Abc_Obj_t *)Ivy_And( pMan, (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) );
+ // create the POs
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Ivy_ObjCreatePo( pMan, (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) );
+ Ivy_ManCleanup( pMan );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the ABC network after mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObjAbc, * pObj;
+ Ivy_Obj_t * pObjIvy;
+ Vec_Int_t * vNodes, * vTemp;
+ int i;
+ // start mapping from Ivy into Abc
+ pMan->pCopy = Vec_PtrStart( Ivy_ManObjIdMax(pMan) + 1 );
+ // start the new ABC network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ // transfer the pointers to the basic nodes
+ Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NtkCreateNodeConst1(pNtkNew) );
+ Abc_NtkForEachCi( pNtkNew, pObjAbc, i )
+ Abc_ObjSetIvy2Abc( pMan, Ivy_ManPi(pMan, i)->Id, pObjAbc );
+ // recursively construct the network
+ vNodes = Vec_IntAlloc( 100 );
+ vTemp = Vec_IntAlloc( 100 );
+ Ivy_ManForEachPo( pMan, pObjIvy, i )
+ {
+ // get the new ABC node corresponding to the old fanin of the PO in IVY
+ if ( fFastMode )
+ pObjAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp );
+ else
+ pObjAbc = Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp );
+ // consider the case of complemented fanin of the PO
+ if ( Ivy_ObjFaninC0(pObjIvy) ) // complement
+ {
+ if ( Abc_ObjIsCi(pObjAbc) )
+ pObjAbc = Abc_NtkCreateNodeInv( pNtkNew, pObjAbc );
+ else
+ {
+ // clone the node
+ pObj = Abc_NtkCloneObj( pObjAbc );
+ // set complemented functions
+ pObj->pData = Abc_SopRegister( pNtkNew->pManFunc, pObjAbc->pData );
+ Abc_SopComplement(pObj->pData);
+ // return the new node
+ pObjAbc = pObj;
+ }
+ assert( Abc_SopGetVarNum(pObjAbc->pData) == Abc_ObjFaninNum(pObjAbc) );
+ }
+ Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), pObjAbc );
+ }
+ Vec_IntFree( vTemp );
+ Vec_IntFree( vNodes );
+ Vec_PtrFree( pMan->pCopy );
+ pMan->pCopy = NULL;
+ // remove dangling nodes
+// Abc_NtkForEachNode( pNtkNew, pObjAbc, i )
+// if ( Abc_ObjFanoutNum(pObjAbc) == 0 )
+// Abc_NtkDeleteObj(pObjAbc);
+ Abc_NtkCleanup( pNtkNew, 0 );
+ // fix CIs feeding directly into COs
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively construct the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp )
+{
+ Vec_Int_t * vSupp;
+ Esop_Cube_t * pCover, * pCube;
+ Abc_Obj_t * pObjAbc, * pFaninAbc;
+ Pla_Obj_t * pStr;
+ int Entry, nCubes, i;
+ unsigned * puTruth;
+ // skip the node if it is a constant or already processed
+ pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id );
+ if ( pObjAbc )
+ return pObjAbc;
+ assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) );
+ // get the support and the cover
+ pStr = Ivy_ObjPlaStr( pMan, pObjIvy );
+ 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 );
+ }
+ // create new node and its fanins
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ManObj(pMan, Entry), vNodes, vTemp );
+ // consider the case of a LUT
+ if ( pCover == PLA_EMPTY )
+ {
+ pObjAbc = Abc_NtkCreateNode( pNtkNew );
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ Abc_ObjAddFanin( pObjAbc, Abc_ObjGetIvy2Abc(pMan, Entry) );
+ // check if the truth table is constant 0
+ puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp );
+ // if the function is constant 0, create constant 0 node
+ if ( Extra_TruthIsConst0(puTruth, 8) )
+ {
+ pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
+ pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew );
+ }
+ else if ( Extra_TruthIsConst1(puTruth, 8) )
+ {
+ pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
+ pObjAbc = Abc_NtkCreateNodeConst1( pNtkNew );
+ }
+ else
+ {
+ int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes, 1 );
+ if ( vNodes->nSize == -1 )
+ printf( "Ivy_ManToAbc_rec(): Internal error.\n" );
+ pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes );
+ if ( fCompl ) Abc_SopComplement(pObjAbc->pData);
+// printf( "Cover contains %d cubes.\n", Vec_IntSize(vNodes) );
+// pObjAbc->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, Vec_IntSize(vSupp), puTruth );
+ }
+ }
+ else
+ {
+ // for each cube, construct the node
+ nCubes = Esop_CoverCountCubes( pCover );
+ if ( nCubes == 0 )
+ pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew );
+ else if ( nCubes == 1 )
+ pObjAbc = Ivy_ManToAigCube( pNtkNew, pMan, pObjIvy, pCover, vSupp );
+ else
+ {
+ pObjAbc = Abc_NtkCreateNode( pNtkNew );
+ Esop_CoverForEachCube( pCover, pCube )
+ {
+ pFaninAbc = Ivy_ManToAigCube( pNtkNew, pMan, pObjIvy, pCube, vSupp );
+ Abc_ObjAddFanin( pObjAbc, pFaninAbc );
+ }
+ pObjAbc->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, Abc_ObjFaninNum(pObjAbc) );
+ }
+ }
+ Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc );
+ return pObjAbc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp )
+{
+ int pCompls[PLAYER_FANIN_LIMIT];
+ Abc_Obj_t * pObjAbc, * pFaninAbc;
+ int i, k, Value;
+ // if tautology cube, create constant 1 node
+ if ( pCube->nLits == 0 )
+ return Abc_NtkCreateNodeConst1(pNtkNew);
+ // create AND node
+ pObjAbc = Abc_NtkCreateNode( pNtkNew );
+ for ( i = k = 0; i < (int)pCube->nVars; i++ )
+ {
+ Value = Esop_CubeGetVar( pCube, i );
+ assert( Value != 0 );
+ if ( Value == 3 )
+ continue;
+ pFaninAbc = Abc_ObjGetIvy2Abc( pMan, Vec_IntEntry(vSupp, i) );
+ pFaninAbc = Abc_ObjNotCond( pFaninAbc, Value==1 );
+ Abc_ObjAddFanin( pObjAbc, Abc_ObjRegular(pFaninAbc) );
+ pCompls[k++] = Abc_ObjIsComplement(pFaninAbc);
+ }
+ pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Abc_ObjFaninNum(pObjAbc), pCompls );
+ assert( Abc_ObjFaninNum(pObjAbc) == (int)pCube->nLits );
+ return pObjAbc;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Recursively construct the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp )
+{
+ Vec_Int_t Supp, * vSupp = &Supp;
+ Abc_Obj_t * pObjAbc, * pFaninAbc;
+ int i, Entry;
+ unsigned * puTruth;
+ // skip the node if it is a constant or already processed
+ pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id );
+ if ( pObjAbc )
+ return pObjAbc;
+ assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) );
+ // get the support of K-LUT
+ Ivy_FastMapReadSupp( pMan, pObjIvy, vSupp );
+ // create new ABC node and its fanins
+ pObjAbc = Abc_NtkCreateNode( pNtkNew );
+ Vec_IntForEachEntry( vSupp, Entry, i )
+ {
+ pFaninAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ManObj(pMan, Entry), vNodes, vTemp );
+ Abc_ObjAddFanin( pObjAbc, pFaninAbc );
+ }
+ // check if the truth table is constant 0
+ puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp );
+ // if the function is constant 0, create constant 0 node
+ if ( Extra_TruthIsConst0(puTruth, 8) )
+ {
+ pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
+ pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew );
+ }
+ else if ( Extra_TruthIsConst1(puTruth, 8) )
+ {
+ pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
+ pObjAbc = Abc_NtkCreateNodeConst1( pNtkNew );
+ }
+ else
+ {
+ int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes, 1 );
+ if ( vNodes->nSize == -1 )
+ printf( "Ivy_ManToAbcFast_rec(): Internal error.\n" );
+ pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes );
+ if ( fCompl ) Abc_SopComplement(pObjAbc->pData);
+ }
+ Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc );
+ return pObjAbc;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes cost of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Abc_NodePlayerCost( int nFanins )
+{
+ if ( nFanins <= 4 )
+ return 1;
+ if ( nFanins <= 6 )
+ return 2;
+ if ( nFanins <= 8 )
+ return 4;
+ if ( nFanins <= 16 )
+ return 8;
+ if ( nFanins <= 32 )
+ return 16;
+ if ( nFanins <= 64 )
+ return 32;
+ if ( nFanins <= 128 )
+ return 64;
+ assert( 0 );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the number of ranks needed for one level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Abc_NtkPlayerCostOneLevel( int nCost, int RankCost )
+{
+ return (nCost / RankCost) + ((nCost % RankCost) > 0);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cost function for the network (number of ranks).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose )
+{
+ Abc_Obj_t * pObj;
+ int * pLevelCosts, * pLevelCostsR;
+ int Cost, CostTotal, CostTotalR, nRanksTotal, nRanksTotalR;
+ int nFanins, nLevels, LevelR, i;
+ // compute the reverse levels
+ Abc_NtkStartReverseLevels( pNtk );
+ // compute the costs for each level
+ nLevels = Abc_NtkGetLevelNum( pNtk );
+ pLevelCosts = ALLOC( int, nLevels + 1 );
+ pLevelCostsR = ALLOC( int, nLevels + 1 );
+ memset( pLevelCosts, 0, sizeof(int) * (nLevels + 1) );
+ memset( pLevelCostsR, 0, sizeof(int) * (nLevels + 1) );
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ nFanins = Abc_ObjFaninNum(pObj);
+ if ( nFanins == 0 )
+ continue;
+ Cost = Abc_NodePlayerCost( nFanins );
+ LevelR = Vec_IntEntry( pNtk->vLevelsR, pObj->Id );
+ pLevelCosts[ pObj->Level ] += Cost;
+ pLevelCostsR[ LevelR ] += Cost;
+ }
+ // compute the total cost
+ CostTotal = CostTotalR = nRanksTotal = nRanksTotalR = 0;
+ for ( i = 0; i <= nLevels; i++ )
+ {
+ CostTotal += pLevelCosts[i];
+ CostTotalR += pLevelCostsR[i];
+ nRanksTotal += Abc_NtkPlayerCostOneLevel( pLevelCosts[i], RankCost );
+ nRanksTotalR += Abc_NtkPlayerCostOneLevel( pLevelCostsR[i], RankCost );
+ }
+ assert( CostTotal == CostTotalR );
+ // print out statistics
+ if ( fVerbose )
+ {
+ for ( i = 1; i <= nLevels; i++ )
+ {
+ printf( "Level %2d : Cost = %7d. Ranks = %6.3f. Cost = %7d. Ranks = %6.3f.\n", i,
+ pLevelCosts[i], ((double)pLevelCosts[i])/RankCost,
+ pLevelCostsR[nLevels+1-i], ((double)pLevelCostsR[nLevels+1-i])/RankCost );
+ }
+ printf( "TOTAL : Cost = %7d. Ranks = %6d. RanksR = %5d. RanksBest = %5d.\n",
+ CostTotal, nRanksTotal, nRanksTotalR, nLevels );
+ }
+ free( pLevelCosts );
+ free( pLevelCostsR );
+ return nRanksTotal;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/player/playerUtil.c b/src/temp/player/playerUtil.c
new file mode 100644
index 00000000..1c8aeec2
--- /dev/null
+++ b/src/temp/player/playerUtil.c
@@ -0,0 +1,353 @@
+/**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;
+}
+
+#if 0
+
+/**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_EdgeId(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_EdgeId(Fanin) );
+ pObj->Level = pFanin->Level;
+ Delay = IVY_MAX( Delay, (int)pObj->Level );
+ }
+ printf( "Area = %d. Delay = %d.\n", Area, Delay );
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/temp/rwt/rwt.h b/src/temp/rwt/rwt.h
index 8f24842b..42a57ad6 100644
--- a/src/temp/rwt/rwt.h
+++ b/src/temp/rwt/rwt.h
@@ -111,10 +111,10 @@ struct Rwt_Node_t_ // 24 bytes
};
// manipulation of complemented attributes
-static inline int Rwt_IsComplement( Rwt_Node_t * p ) { return (int)(((unsigned)p) & 01); }
-static inline Rwt_Node_t * Rwt_Regular( Rwt_Node_t * p ) { return (Rwt_Node_t *)((unsigned)(p) & ~01); }
-static inline Rwt_Node_t * Rwt_Not( Rwt_Node_t * p ) { return (Rwt_Node_t *)((unsigned)(p) ^ 01); }
-static inline Rwt_Node_t * Rwt_NotCond( Rwt_Node_t * p, int c ) { return (Rwt_Node_t *)((unsigned)(p) ^ (c)); }
+static inline int Rwt_IsComplement( Rwt_Node_t * p ) { return (int)(((unsigned long)p) & 01); }
+static inline Rwt_Node_t * Rwt_Regular( Rwt_Node_t * p ) { return (Rwt_Node_t *)((unsigned long)(p) & ~01); }
+static inline Rwt_Node_t * Rwt_Not( Rwt_Node_t * p ) { return (Rwt_Node_t *)((unsigned long)(p) ^ 01); }
+static inline Rwt_Node_t * Rwt_NotCond( Rwt_Node_t * p, int c ) { return (Rwt_Node_t *)((unsigned long)(p) ^ (c)); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
diff --git a/src/temp/ver/verCore.c b/src/temp/ver/verCore.c
index d18d1820..352a4361 100644
--- a/src/temp/ver/verCore.c
+++ b/src/temp/ver/verCore.c
@@ -387,13 +387,13 @@ int Ver_ParseModule( Ver_Man_t * pMan )
if ( Abc_ObjFanoutNum(pNet) == 0 )
Abc_NtkDeleteObj(pNet);
else
- Abc_ObjAddFanin( pNet, Abc_NodeCreateConst0(pNtk) );
+ Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst0(pNtk) );
// check if constant 1 net is used
pNet = Abc_NtkFindOrCreateNet( pNtk, "1'b1" );
if ( Abc_ObjFanoutNum(pNet) == 0 )
Abc_NtkDeleteObj(pNet);
else
- Abc_ObjAddFanin( pNet, Abc_NodeCreateConst1(pNtk) );
+ Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst1(pNtk) );
// fix the dangling nets
Abc_NtkFinalizeRead( pNtk );