summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Een <niklas@een.se>2012-10-30 12:38:57 -0700
committerNiklas Een <niklas@een.se>2012-10-30 12:38:57 -0700
commite353c4b75cb594d21b9060cbaf26114504513cd8 (patch)
treea0d3119ba2c35f909fc25405fed700c93300922d
parentc3168ba661a06022654aae11693f08368ec15acc (diff)
parent9b8d3628541cb30ad99b104f6449d48f3546193a (diff)
downloadabc-e353c4b75cb594d21b9060cbaf26114504513cd8.tar.gz
abc-e353c4b75cb594d21b9060cbaf26114504513cd8.tar.bz2
abc-e353c4b75cb594d21b9060cbaf26114504513cd8.zip
Merge
-rw-r--r--abclib.dsp12
-rw-r--r--src/aig/gia/gia.h31
-rw-r--r--src/aig/gia/giaAig.c77
-rw-r--r--src/aig/gia/giaAig.h1
-rw-r--r--src/aig/gia/giaChoice.c103
-rw-r--r--src/aig/gia/giaFront.c43
-rw-r--r--src/aig/gia/giaIf.c768
-rw-r--r--src/aig/gia/giaMan.c126
-rw-r--r--src/aig/gia/giaScl.c26
-rw-r--r--src/aig/gia/giaUtil.c83
-rw-r--r--src/base/abc/abc.h11
-rw-r--r--src/base/abc/abcCheck.c4
-rw-r--r--src/base/abc/abcFanio.c13
-rw-r--r--src/base/abci/abc.c947
-rw-r--r--src/base/abci/abcDar.c144
-rw-r--r--src/base/abci/abcDec.c34
-rw-r--r--src/base/abci/abcIf.c10
-rw-r--r--src/base/abci/abcNpn.c15
-rw-r--r--src/base/abci/abcRec2.c105
-rw-r--r--src/base/abci/abcRec3.c1097
-rw-r--r--src/base/abci/module.make1
-rw-r--r--src/base/io/io.c35
-rw-r--r--src/base/io/ioAbc.h2
-rw-r--r--src/base/io/ioReadBlifMv.c5
-rw-r--r--src/base/io/ioWriteBlif.c298
-rw-r--r--src/base/main/mainInt.h2
-rw-r--r--src/bool/kit/kit.h4
-rw-r--r--src/bool/kit/kitHop.c89
-rw-r--r--src/bool/kit/kitTruth.c2
-rw-r--r--src/map/if/if.h15
-rw-r--r--src/map/if/ifMan.c4
-rw-r--r--src/map/if/ifMap.c30
-rw-r--r--src/map/if/ifTruth.c199
-rw-r--r--src/map/if/ifUtil.c84
-rw-r--r--src/map/scl/sclTime.c1
-rw-r--r--src/misc/util/abc_global.h8
-rw-r--r--src/misc/util/utilTruth.h422
-rw-r--r--src/misc/vec/vecMem.h82
-rw-r--r--src/opt/dau/dauDsd.c341
-rw-r--r--src/opt/dau/dauEnum.c253
-rw-r--r--src/opt/dau/module.make3
-rw-r--r--src/opt/nwk/nwkMap.c1
-rw-r--r--src/proof/cec/cec.h1
-rw-r--r--src/proof/cec/cecCorr.c13
-rw-r--r--src/proof/dch/dchChoice.c2
-rw-r--r--src/proof/dch/dchCore.c4
-rw-r--r--src/proof/llb/llb4Map.c2
-rw-r--r--src/proof/ssw/ssw.h1
-rw-r--r--src/proof/ssw/sswCore.c18
49 files changed, 5006 insertions, 566 deletions
diff --git a/abclib.dsp b/abclib.dsp
index c729baa9..c0ad64cc 100644
--- a/abclib.dsp
+++ b/abclib.dsp
@@ -391,6 +391,10 @@ SOURCE=.\src\base\abci\abcRec2.c
# End Source File
# Begin Source File
+SOURCE=.\src\base\abci\abcRec3.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\base\abci\abcReconv.c
# End Source File
# Begin Source File
@@ -1979,6 +1983,10 @@ SOURCE=.\src\opt\dau\dauDsd.c
# End Source File
# Begin Source File
+SOURCE=.\src\opt\dau\dauEnum.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\opt\dau\dauInt.h
# End Source File
# End Group
@@ -2705,6 +2713,10 @@ SOURCE=.\src\misc\util\utilSignal.h
SOURCE=.\src\misc\util\utilSort.c
# End Source File
+# Begin Source File
+
+SOURCE=.\src\misc\util\utilTruth.h
+# End Source File
# End Group
# Begin Group "nm"
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index b3efa455..35d80047 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -117,6 +117,7 @@ struct Gia_Man_t_
int * pReprsOld; // representatives (for CIs and ANDs)
Gia_Rpr_t * pReprs; // representatives (for CIs and ANDs)
int * pNexts; // next nodes in the equivalence classes
+ int * pSibls; // next nodes in the choice nodes
int * pIso; // pairs of structurally isomorphic nodes
int nTerLoop; // the state where loop begins
int nTerStates; // the total number of ternary states
@@ -481,6 +482,13 @@ static inline int Gia_ManAppendXor( Gia_Man_t * p, int iLit0, int iLit1 )
{
return Gia_ManAppendMux( p, iLit0, Abc_LitNot(iLit1), iLit1 );
}
+static inline void Gia_ManPatchCoDriver( Gia_Man_t * p, int iCoIndex, int iLit0 )
+{
+ Gia_Obj_t * pObjCo = Gia_ManCo( p, iCoIndex );
+ assert( Gia_ObjId(p, pObjCo) > Abc_Lit2Var(iLit0) );
+ pObjCo->iDiff0 = Gia_ObjId(p, pObjCo) - Abc_Lit2Var(iLit0);
+ pObjCo->fCompl0 = Abc_LitIsCompl(iLit0);
+}
#define GIA_ZER 1
#define GIA_ONE 2
@@ -570,6 +578,8 @@ static inline void Gia_ObjSetReprRev( Gia_Man_t * p, int Id, int Num ){ a
static inline void Gia_ObjUnsetRepr( Gia_Man_t * p, int Id ) { p->pReprs[Id].iRepr = GIA_VOID; }
static inline int Gia_ObjHasRepr( Gia_Man_t * p, int Id ) { return p->pReprs[Id].iRepr != GIA_VOID; }
static inline int Gia_ObjReprSelf( Gia_Man_t * p, int Id ) { return Gia_ObjHasRepr(p, Id) ? Gia_ObjRepr(p, Id) : Id; }
+static inline int Gia_ObjSibl( Gia_Man_t * p, int Id ) { return p->pSibls ? p->pSibls[Id] : 0; }
+static inline Gia_Obj_t * Gia_ObjSiblObj( Gia_Man_t * p, int Id ) { return (p->pSibls && p->pSibls[Id]) ? Gia_ManObj(p, p->pSibls[Id]) : NULL; }
static inline int Gia_ObjProved( Gia_Man_t * p, int Id ) { return p->pReprs[Id].fProved; }
static inline void Gia_ObjSetProved( Gia_Man_t * p, int Id ) { p->pReprs[Id].fProved = 1; }
@@ -697,6 +707,7 @@ extern int Gia_ManCounterExampleValueLookup( Gia_Man_t * pGia, i
extern void Gia_ManVerifyChoices( Gia_Man_t * p );
extern void Gia_ManReverseClasses( Gia_Man_t * p, int fNowIncreasing );
extern int Gia_ManHasChoices( Gia_Man_t * p );
+extern int Gia_ManChoiceLevel( Gia_Man_t * p );
/*=== giaCsatOld.c ============================================================*/
extern Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose );
/*=== giaCsat.c ============================================================*/
@@ -807,7 +818,14 @@ extern Gia_Man_t * Gia_ManRehash( Gia_Man_t * p, int fAddStrash );
extern void Gia_ManHashProfile( Gia_Man_t * p );
extern int Gia_ManHashLookup( Gia_Man_t * p, Gia_Obj_t * p0, Gia_Obj_t * p1 );
/*=== giaIf.c ===========================================================*/
-extern void Gia_ManPrintNpnClasses( Gia_Man_t * p );
+extern void Gia_ManPrintMappingStats( Gia_Man_t * p );
+extern int Gia_ManLutFaninCount( Gia_Man_t * p );
+extern int Gia_ManLutSizeMax( Gia_Man_t * p );
+extern int Gia_ManLutNum( Gia_Man_t * p );
+extern int Gia_ManLutLevel( Gia_Man_t * p );
+extern void Gia_ManSetRefsMapped( Gia_Man_t * p );
+extern void Gia_ManSetIfParsDefault( void * pIfPars );
+extern Gia_Man_t * Gia_ManPerformMapping( Gia_Man_t * p, void * pIfPars );
/*=== giaIso.c ===========================================================*/
extern Gia_Man_t * Gia_ManIsoCanonicize( Gia_Man_t * p, int fVerbose );
extern Gia_Man_t * Gia_ManIsoReduce( Gia_Man_t * p, Vec_Ptr_t ** pvPosEquivs, int fDualOut, int fVerbose );
@@ -823,12 +841,7 @@ extern void Gia_ManPrintStatsShort( Gia_Man_t * p );
extern void Gia_ManPrintMiterStatus( Gia_Man_t * p );
extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );
extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew );
-/*=== giaMap.c ===========================================================*/
-extern void Gia_ManPrintMappingStats( Gia_Man_t * p );
-extern int Gia_ManLutFaninCount( Gia_Man_t * p );
-extern int Gia_ManLutSizeMax( Gia_Man_t * p );
-extern int Gia_ManLutNum( Gia_Man_t * p );
-extern int Gia_ManLutLevel( Gia_Man_t * p );
+extern void Gia_ManPrintNpnClasses( Gia_Man_t * p );
/*=== giaMem.c ===========================================================*/
extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax );
extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose );
@@ -857,6 +870,7 @@ extern int Sat_ManTest( Gia_Man_t * pGia, Gia_Obj_t * pObj, int
extern int Gia_ManSeqMarkUsed( Gia_Man_t * p );
extern int Gia_ManCombMarkUsed( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p );
+extern Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs );
extern Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose );
/*=== giaShrink.c ===========================================================*/
@@ -906,7 +920,7 @@ extern int Gia_ManLevelNum( Gia_Man_t * p );
extern void Gia_ManCreateValueRefs( Gia_Man_t * p );
extern void Gia_ManCreateRefs( Gia_Man_t * p );
extern int * Gia_ManCreateMuxRefs( Gia_Man_t * p );
-extern int Gia_ManCrossCut( Gia_Man_t * p );
+extern int Gia_ManCrossCut( Gia_Man_t * p, int fReverse );
extern int Gia_ManIsNormalized( Gia_Man_t * p );
extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p );
extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode );
@@ -920,6 +934,7 @@ extern void Gia_ObjPrint( Gia_Man_t * p, Gia_Obj_t * pObj );
extern void Gia_ManPrint( Gia_Man_t * p );
extern void Gia_ManInvertConstraints( Gia_Man_t * pAig );
extern int Gia_ManCompare( Gia_Man_t * p1, Gia_Man_t * p2 );
+extern void Gia_ManMarkFanoutDrivers( Gia_Man_t * p );
/*=== giaCTas.c ===========================================================*/
typedef struct Tas_Man_t_ Tas_Man_t;
diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c
index 224d3bda..5dcc6038 100644
--- a/src/aig/gia/giaAig.c
+++ b/src/aig/gia/giaAig.c
@@ -42,7 +42,7 @@ static inline Aig_Obj_t * Gia_ObjChild1Copy2( Aig_Obj_t ** ppNodes, Gia_Obj_t *
/**Function*************************************************************
- Synopsis [Derives combinational miter of the two AIGs.]
+ Synopsis [Duplicates AIG in the DFS order.]
Description []
@@ -70,6 +70,34 @@ void Gia_ManFromAig_rec( Gia_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
pNew->pNexts[iObjNew] = iNextNew;
}
}
+Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Aig_Obj_t * pObj;
+ int i;
+ // create the new manager
+ pNew = Gia_ManStart( Aig_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ pNew->nConstrs = p->nConstrs;
+ // create room to store equivalences
+ if ( p->pEquivs )
+ pNew->pNexts = ABC_CALLOC( int, Aig_ManObjNum(p) );
+ // create the PIs
+ Aig_ManCleanData( p );
+ Aig_ManConst1(p)->iData = 1;
+ Aig_ManForEachCi( p, pObj, i )
+ pObj->iData = Gia_ManAppendCi( pNew );
+ // add logic for the POs
+ Aig_ManForEachCo( p, pObj, i )
+ Gia_ManFromAig_rec( pNew, p, Aig_ObjFanin0(pObj) );
+ Aig_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
+ Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
+ if ( pNew->pNexts )
+ Gia_ManDeriveReprs( pNew );
+ return pNew;
+}
/**Function*************************************************************
@@ -82,19 +110,38 @@ void Gia_ManFromAig_rec( Gia_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p )
+void Gia_ManFromAigChoices_rec( Gia_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ if ( pObj == NULL || pObj->iData )
+ return;
+ assert( Aig_ObjIsNode(pObj) );
+ Gia_ManFromAigChoices_rec( pNew, p, Aig_ObjFanin0(pObj) );
+ Gia_ManFromAigChoices_rec( pNew, p, Aig_ObjFanin1(pObj) );
+ Gia_ManFromAigChoices_rec( pNew, p, Aig_ObjEquiv(p, pObj) );
+ pObj->iData = Gia_ManAppendAnd( pNew, Gia_ObjChild0Copy(pObj), Gia_ObjChild1Copy(pObj) );
+ if ( Aig_ObjEquiv(p, pObj) )
+ {
+ int iObjNew, iNextNew;
+ iObjNew = Abc_Lit2Var(pObj->iData);
+ iNextNew = Abc_Lit2Var(Aig_ObjEquiv(p, pObj)->iData);
+ assert( iObjNew > iNextNew );
+ assert( Gia_ObjIsAnd(Gia_ManObj(pNew, iNextNew)) );
+ pNew->pSibls[iObjNew] = iNextNew;
+ }
+}
+Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p )
{
Gia_Man_t * pNew;
Aig_Obj_t * pObj;
int i;
+ assert( p->pEquivs != NULL );
// create the new manager
pNew = Gia_ManStart( Aig_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
pNew->nConstrs = p->nConstrs;
// create room to store equivalences
- if ( p->pEquivs )
- pNew->pNexts = ABC_CALLOC( int, Aig_ManObjNum(p) );
+ pNew->pSibls = ABC_CALLOC( int, Aig_ManObjNum(p) );
// create the PIs
Aig_ManCleanData( p );
Aig_ManConst1(p)->iData = 1;
@@ -102,12 +149,11 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p )
pObj->iData = Gia_ManAppendCi( pNew );
// add logic for the POs
Aig_ManForEachCo( p, pObj, i )
- Gia_ManFromAig_rec( pNew, p, Aig_ObjFanin0(pObj) );
+ Gia_ManFromAigChoices_rec( pNew, p, Aig_ObjFanin0(pObj) );
Aig_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
- if ( pNew->pNexts )
- Gia_ManDeriveReprs( pNew );
+ assert( Gia_ManObjNum(pNew) == Aig_ManObjNum(p) );
return pNew;
}
@@ -195,7 +241,7 @@ Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p )
/**Function*************************************************************
- Synopsis [Derives combinational miter of the two AIGs.]
+ Synopsis [Duplicates AIG in the DFS order.]
Description []
@@ -228,18 +274,6 @@ void Gia_ManToAig_rec( Aig_Man_t * pNew, Aig_Obj_t ** ppNodes, Gia_Man_t * p, Gi
pNew->pEquivs[Aig_Regular(pObjNew)->Id] = Aig_Regular(pNextNew);
}
}
-
-/**Function*************************************************************
-
- Synopsis [Duplicates AIG in the DFS order.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices )
{
Aig_Man_t * pNew;
@@ -541,7 +575,8 @@ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars )
Aig_Man_t * pNew;
pNew = Gia_ManToAig( p, 0 );
pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars );
- pGia = Gia_ManFromAig( pNew );
+// pGia = Gia_ManFromAig( pNew );
+ pGia = Gia_ManFromAigChoices( pNew );
Aig_ManStop( pNew );
return pGia;
}
diff --git a/src/aig/gia/giaAig.h b/src/aig/gia/giaAig.h
index b72f6415..6498ec52 100644
--- a/src/aig/gia/giaAig.h
+++ b/src/aig/gia/giaAig.h
@@ -51,6 +51,7 @@ ABC_NAMESPACE_HEADER_START
/*=== giaAig.c =============================================================*/
extern Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p );
+extern Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p );
extern Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p );
extern Gia_Man_t * Gia_ManFromAigSwitch( Aig_Man_t * p );
extern Aig_Man_t * Gia_ManToAig( Gia_Man_t * p, int fChoices );
diff --git a/src/aig/gia/giaChoice.c b/src/aig/gia/giaChoice.c
index 85f0a372..ca2acb28 100644
--- a/src/aig/gia/giaChoice.c
+++ b/src/aig/gia/giaChoice.c
@@ -20,6 +20,7 @@
#include "gia.h"
#include "giaAig.h"
+#include "misc/tim/tim.h"
ABC_NAMESPACE_IMPL_START
@@ -261,6 +262,108 @@ int Gia_ManHasChoices( Gia_Man_t * p )
return 1;
}
+
+/**Function*************************************************************
+
+ Synopsis [Computes levels for AIG with choices and white boxes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManChoiceLevel_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
+ Gia_Obj_t * pNext;
+ int i, iBox, iTerm1, nTerms, LevelMax = 0;
+ if ( Gia_ObjIsTravIdCurrent( p, pObj ) )
+ return;
+ Gia_ObjSetTravIdCurrent( p, pObj );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ if ( pManTime )
+ {
+ iBox = Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) );
+ if ( iBox >= 0 ) // this is not a true PI
+ {
+ iTerm1 = Tim_ManBoxInputFirst( pManTime, iBox );
+ nTerms = Tim_ManBoxInputNum( pManTime, iBox );
+ for ( i = 0; i < nTerms; i++ )
+ {
+ pNext = Gia_ManCo( p, iTerm1 + i );
+ Gia_ManChoiceLevel_rec( p, pNext );
+ if ( LevelMax < Gia_ObjLevel(p, pNext) )
+ LevelMax = Gia_ObjLevel(p, pNext);
+ }
+ LevelMax++;
+ }
+ }
+// Abc_Print( 1, "%d ", pObj->Level );
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ {
+ pNext = Gia_ObjFanin0(pObj);
+ Gia_ManChoiceLevel_rec( p, pNext );
+ if ( LevelMax < Gia_ObjLevel(p, pNext) )
+ LevelMax = Gia_ObjLevel(p, pNext);
+ }
+ else if ( Gia_ObjIsAnd(pObj) )
+ {
+ // get the maximum level of the two fanins
+ pNext = Gia_ObjFanin0(pObj);
+ Gia_ManChoiceLevel_rec( p, pNext );
+ if ( LevelMax < Gia_ObjLevel(p, pNext) )
+ LevelMax = Gia_ObjLevel(p, pNext);
+ pNext = Gia_ObjFanin1(pObj);
+ Gia_ManChoiceLevel_rec( p, pNext );
+ if ( LevelMax < Gia_ObjLevel(p, pNext) )
+ LevelMax = Gia_ObjLevel(p, pNext);
+ LevelMax++;
+
+ // get the level of the nodes in the choice node
+ if ( p->pSibls && (pNext = Gia_ObjSiblObj(p, Gia_ObjId(p, pObj))) )
+ {
+ Gia_ManChoiceLevel_rec( p, pNext );
+ if ( LevelMax < Gia_ObjLevel(p, pNext) )
+ LevelMax = Gia_ObjLevel(p, pNext);
+ }
+ }
+ else if ( !Gia_ObjIsConst0(pObj) )
+ assert( 0 );
+ Gia_ObjSetLevel( p, pObj, LevelMax );
+}
+int Gia_ManChoiceLevel( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, LevelMax = 0;
+// assert( Gia_ManRegNum(p) == 0 );
+ Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
+ Gia_ManIncrementTravId( p );
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ Gia_ManChoiceLevel_rec( p, pObj );
+ if ( LevelMax < Gia_ObjLevel(p, pObj) )
+ LevelMax = Gia_ObjLevel(p, pObj);
+ }
+ // account for dangling boxes
+ Gia_ManForEachCi( p, pObj, i )
+ {
+ Gia_ManChoiceLevel_rec( p, pObj );
+ if ( LevelMax < Gia_ObjLevel(p, pObj) )
+ LevelMax = Gia_ObjLevel(p, pObj);
+// Abc_Print( 1, "%d ", Gia_ObjLevel(p, pObj) );
+ }
+// Abc_Print( 1, "\n" );
+ Gia_ManForEachAnd( p, pObj, i )
+ assert( Gia_ObjLevel(p, pObj) > 0 );
+// printf( "Max level %d\n", LevelMax );
+ return LevelMax;
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaFront.c b/src/aig/gia/giaFront.c
index 322da785..fc99cfe9 100644
--- a/src/aig/gia/giaFront.c
+++ b/src/aig/gia/giaFront.c
@@ -103,13 +103,54 @@ void Gia_ManFrontTransform( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
+int Gia_ManCrossCutSimple( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, nCutCur = 0, nCutMax = 0;
+ Gia_ManCreateValueRefs( p );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ if ( pObj->Value )
+ nCutCur++;
+ if ( nCutMax < nCutCur )
+ nCutMax = nCutCur;
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ if ( --Gia_ObjFanin0(pObj)->Value == 0 )
+ nCutCur--;
+ if ( --Gia_ObjFanin1(pObj)->Value == 0 )
+ nCutCur--;
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ {
+ if ( --Gia_ObjFanin0(pObj)->Value == 0 )
+ nCutCur--;
+ }
+ }
+// Gia_ManForEachObj( p, pObj, i )
+// assert( pObj->Value == 0 );
+ return nCutMax;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Determine the frontier.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
Gia_Man_t * Gia_ManFront( Gia_Man_t * p )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj, * pFanin0New, * pFanin1New, * pObjNew;
char * pFront; // places used for the frontier
int i, iLit, nCrossCut = 0, nCrossCutMax = 0;
- int nCrossCutMaxInit = Gia_ManCrossCut( p );
+ int nCrossCutMaxInit = Gia_ManCrossCutSimple( p );
int iFront = 0;//, clk = clock();
// set references for all objects
Gia_ManCreateValueRefs( p );
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c
index 13e4f429..deab1a60 100644
--- a/src/aig/gia/giaIf.c
+++ b/src/aig/gia/giaIf.c
@@ -21,7 +21,7 @@
#include "gia.h"
#include "aig/aig/aig.h"
#include "map/if/if.h"
-#include "opt/dar/dar.h"
+#include "bool/kit/kit.h"
ABC_NAMESPACE_IMPL_START
@@ -30,6 +30,9 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
+extern int Abc_RecToGia2( Gia_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj, Vec_Int_t * vLeaves, int fHash );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -45,44 +48,48 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-void Gia_ManSetIfParsDefault( If_Par_t * pPars )
+void Gia_ManSetIfParsDefault( void * pp )
{
+ If_Par_t * pPars = (If_Par_t *)pp;
// extern void * Abc_FrameReadLibLut();
+ If_Par_t * p = (If_Par_t *)pPars;
// set defaults
- memset( pPars, 0, sizeof(If_Par_t) );
+ memset( p, 0, sizeof(If_Par_t) );
// user-controlable paramters
-// pPars->nLutSize = -1;
- pPars->nLutSize = 6;
- pPars->nCutsMax = 8;
- pPars->nFlowIters = 1;
- pPars->nAreaIters = 2;
- pPars->DelayTarget = -1;
- pPars->Epsilon = (float)0.005;
- pPars->fPreprocess = 1;
- pPars->fArea = 0;
- pPars->fFancy = 0;
- pPars->fExpRed = 1; ////
- pPars->fLatchPaths = 0;
- pPars->fEdge = 1;
- pPars->fPower = 0;
- pPars->fCutMin = 0;
- pPars->fSeqMap = 0;
- pPars->fVerbose = 0;
+ p->nLutSize = -1;
+// p->nLutSize = 6;
+ p->nCutsMax = 8;
+ p->nFlowIters = 1;
+ p->nAreaIters = 2;
+ p->DelayTarget = -1;
+ p->Epsilon = (float)0.005;
+ p->fPreprocess = 1;
+ p->fArea = 0;
+ p->fFancy = 0;
+ p->fExpRed = 0; ////
+ p->fLatchPaths = 0;
+ p->fEdge = 1;
+ p->fPower = 0;
+ p->fCutMin = 0;
+ p->fSeqMap = 0;
+ p->fVerbose = 0;
+ p->pLutStruct = NULL;
// internal parameters
- pPars->fTruth = 0;
- pPars->nLatchesCi = 0;
- pPars->nLatchesCo = 0;
- pPars->fLiftLeaves = 0;
-// pPars->pLutLib = Abc_FrameReadLibLut();
- pPars->pLutLib = NULL;
- pPars->pTimesArr = NULL;
- pPars->pTimesArr = NULL;
- pPars->pFuncCost = NULL;
+ p->fTruth = 0;
+ p->nLatchesCi = 0;
+ p->nLatchesCo = 0;
+ p->fLiftLeaves = 0;
+ p->fUseCoAttrs = 1; // use CO attributes
+ p->pLutLib = NULL;
+ p->pTimesArr = NULL;
+ p->pTimesArr = NULL;
+ p->pFuncCost = NULL;
}
+
/**Function*************************************************************
- Synopsis [Load the network into FPGA manager.]
+ Synopsis [Prints mapping statistics.]
Description []
@@ -91,97 +98,17 @@ void Gia_ManSetIfParsDefault( If_Par_t * pPars )
SeeAlso []
***********************************************************************/
-If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
+int Gia_ManLutFaninCount( Gia_Man_t * p )
{
-// extern Vec_Int_t * SGia_ManComputeSwitchProbs( Gia_Man_t * p, int nFrames, int nPref, int fProbOne );
-// Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL;
-// float * pSwitching, * pSwitching2;
- If_Man_t * pIfMan;
- If_Obj_t * pIfObj;
- Gia_Obj_t * pNode;
- int i;//, clk = clock();
- Gia_ManLevelNum( p );
-// assert( p->pReprs == NULL );
-/*
- // set the number of registers (switch activity will be combinational)
- Gia_ManSetRegNum( p, 0 );
- if ( pPars->fPower )
- {
- vSwitching = SGia_ManComputeSwitchProbs( p, 48, 16, 0 );
- if ( pPars->fVerbose )
- {
- ABC_PRT( "Computing switching activity", clock() - clk );
- }
- pSwitching = (float *)vSwitching->pArray;
- vSwitching2 = Vec_IntStart( Gia_ManObjNumMax(p) );
- pSwitching2 = (float *)vSwitching2->pArray;
- }
-*/
- // start the mapping manager and set its parameters
- pIfMan = If_ManStart( pPars );
-// pIfMan->vSwitching = vSwitching2;
- // load the AIG into the mapper
- Gia_ManCreateRefs( p );
- Gia_ManForEachObj( p, pNode, i )
- {
- if ( Gia_ObjIsAnd(pNode) )
- pIfObj = If_ManCreateAnd( pIfMan,
- If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ),
- If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) );
- else if ( Gia_ObjIsCi(pNode) )
- {
- pIfObj = If_ManCreateCi( pIfMan );
- If_ObjSetLevel( pIfObj, Gia_ObjLevel(p,pNode) );
-// Abc_Print( 1, "pi=%d ", pIfObj->Level );
- if ( pIfMan->nLevelMax < (int)pIfObj->Level )
- pIfMan->nLevelMax = (int)pIfObj->Level;
- }
- else if ( Gia_ObjIsCo(pNode) )
- {
- pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) );
-// Abc_Print( 1, "po=%d ", pIfObj->Level );
- }
- else if ( Gia_ObjIsConst0(pNode) )
- pIfObj = If_Not(If_ManConst1( pIfMan ));
- else // add the node to the mapper
- assert( 0 );
- // save the result
- assert( Vec_PtrEntry(vAigToIf, i) == NULL );
- Vec_PtrWriteEntry( vAigToIf, i, pIfObj );
-// if ( vSwitching2 )
-// pSwitching2[pIfObj->Id] = pSwitching[pNode->Id];
- // set up the choice node
-/*
-// if ( p->pReprs && p->pNexts && Gia_ObjIsHead( p, i ) )
- if ( p->pNexts && Gia_ObjNext(p, i) && Gia_ObjRefNumId(p, i) )
- {
- int iPrev, iFanin;
- pIfMan->nChoices++;
- for ( iPrev = i, iFanin = Gia_ObjNext(p, i); iFanin; iPrev = iFanin, iFanin = Gia_ObjNext(p, iFanin) )
- If_ObjSetChoice( Vec_PtrEntry(vAigToIf,iPrev), Vec_PtrEntry(vAigToIf,iFanin) );
- If_ManCreateChoice( pIfMan, Vec_PtrEntry(vAigToIf,i) );
- }
-*/
-/* // set up the choice node
- if ( Gia_ObjIsChoice( p, pNode ) )
- {
- pIfMan->nChoices++;
- for ( pPrev = pNode, pFanin = Gia_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Gia_ObjEquiv(p, pFanin) )
- If_ObjSetChoice( pPrev->pData, pFanin->pData );
- If_ManCreateChoice( pIfMan, pNode->pData );
- }
-// assert( If_ObjLevel(pIfObj) == Gia_ObjLevel(pNode) );
-*/
- }
-// if ( vSwitching )
-// Vec_IntFree( vSwitching );
- return pIfMan;
+ int i, Counter = 0;
+ Gia_ManForEachLut( p, i )
+ Counter += Gia_ObjLutSize(p, i);
+ return Counter;
}
-
/**Function*************************************************************
- Synopsis []
+ Synopsis [Prints mapping statistics.]
Description []
@@ -190,60 +117,17 @@ If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
SeeAlso []
***********************************************************************/
-int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf )
+int Gia_ManLutSizeMax( Gia_Man_t * p )
{
- int * pMapping, iOffset;
- Vec_Ptr_t * vIfToAig;
- Gia_Obj_t * pObj, * pObjRepr;
- If_Obj_t * pIfObj;
- If_Cut_t * pCutBest;
- int i, k, j, nLeaves, * ppLeaves;
- int nItems = 0;
- assert( Gia_ManCiNum(p) == If_ManCiNum(pIfMan) );
- assert( Gia_ManCoNum(p) == If_ManCoNum(pIfMan) );
- assert( Gia_ManAndNum(p) == If_ManAndNum(pIfMan) );
- // create mapping of IF to AIG
- vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) );
- Gia_ManForEachObj( p, pObj, i )
- {
- pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i );
- Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj );
- if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 )
- continue;
- nItems += 2 + If_CutLeaveNum( If_ObjCutBest(pIfObj) );
- }
- // construct the network
- pMapping = ABC_CALLOC( int, Gia_ManObjNum(p) + nItems );
- iOffset = Gia_ManObjNum(p);
- Gia_ManForEachObj( p, pObj, i )
- {
- pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i );
- if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 )
- continue;
- pCutBest = If_ObjCutBest( pIfObj );
- nLeaves = If_CutLeaveNum( pCutBest );
- ppLeaves = If_CutLeaves( pCutBest );
- // create node
- k = iOffset;
- pMapping[k++] = nLeaves;
- for ( j = 0; j < nLeaves; j++ )
- {
- pObjRepr = (Gia_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[j] );
- pMapping[k++] = Gia_ObjId( p, pObjRepr );
- }
- pMapping[k++] = i;
- pMapping[i] = iOffset;
- iOffset = k;
- }
- assert( iOffset <= Gia_ManObjNum(p) + nItems );
- Vec_PtrFree( vIfToAig );
-// pNtk->pManTime = Tim_ManDup( pIfMan->pManTim, 0 );
- return pMapping;
+ int i, nSizeMax = -1;
+ Gia_ManForEachLut( p, i )
+ nSizeMax = Abc_MaxInt( nSizeMax, Gia_ObjLutSize(p, i) );
+ return nSizeMax;
}
/**Function*************************************************************
- Synopsis [Interface with the FPGA mapping package.]
+ Synopsis [Prints mapping statistics.]
Description []
@@ -252,39 +136,14 @@ int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf )
SeeAlso []
***********************************************************************/
-int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars )
+int Gia_ManLutNum( Gia_Man_t * p )
{
- If_Man_t * pIfMan;
- Vec_Ptr_t * vAigToIf;
- // set the arrival times
- pPars->pTimesArr = ABC_ALLOC( float, Gia_ManCiNum(p) );
- memset( pPars->pTimesArr, 0, sizeof(float) * Gia_ManCiNum(p) );
- // translate into the mapper
- vAigToIf = Vec_PtrStart( Gia_ManObjNum(p) );
- pIfMan = Gia_ManToIf( p, pPars, vAigToIf );
- if ( pIfMan == NULL )
- {
- Vec_PtrFree( vAigToIf );
- return 0;
- }
-// pIfMan->pManTim = Tim_ManDup( pManTime, 0 );
- if ( !If_ManPerformMapping( pIfMan ) )
- {
- Vec_PtrFree( vAigToIf );
- If_ManStop( pIfMan );
- return 0;
- }
- // transform the result of mapping into the new network
- ABC_FREE( p->pMapping );
- p->pMapping = Gia_ManFromIf( pIfMan, p, vAigToIf );
-// if ( pPars->fBidec && pPars->nLutSize <= 8 )
-// Gia_ManBidecResyn( pNtk, 0 );
- If_ManStop( pIfMan );
- Vec_PtrFree( vAigToIf );
- return 1;
+ int i, Counter = 0;
+ Gia_ManForEachLut( p, i )
+ Counter ++;
+ return Counter;
}
-
/**Function*************************************************************
Synopsis [Prints mapping statistics.]
@@ -296,35 +155,30 @@ int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars )
SeeAlso []
***********************************************************************/
-void Gia_ManPrintMappingStats( Gia_Man_t * p )
+int Gia_ManLutLevel( Gia_Man_t * p )
{
- int * pLevels;
- int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0;
- if ( !p->pMapping )
- return;
- pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_Obj_t * pObj;
+ int i, k, iFan, Level;
+ int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
Gia_ManForEachLut( p, i )
{
- nLuts++;
- nFanins += Gia_ObjLutSize(p, i);
- nLutSize = Abc_MaxInt( nLutSize, Gia_ObjLutSize(p, i) );
+ Level = 0;
Gia_LutForEachFanin( p, i, iFan, k )
- pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[iFan] );
- pLevels[i]++;
- LevelMax = Abc_MaxInt( LevelMax, pLevels[i] );
+ if ( Level < pLevels[iFan] )
+ Level = pLevels[iFan];
+ pLevels[i] = Level + 1;
}
+ Level = 0;
+ Gia_ManForEachCo( p, pObj, k )
+ if ( Level < pLevels[Gia_ObjFaninId0p(p, pObj)] )
+ Level = pLevels[Gia_ObjFaninId0p(p, pObj)];
ABC_FREE( pLevels );
- Abc_Print( 1, "mapping (K=%d) : ", nLutSize );
- Abc_Print( 1, "lut =%7d ", nLuts );
- Abc_Print( 1, "edge =%8d ", nFanins );
- Abc_Print( 1, "lev =%5d ", LevelMax );
- Abc_Print( 1, "mem =%5.2f MB", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) );
- Abc_Print( 1, "\n" );
+ return Level;
}
/**Function*************************************************************
- Synopsis [Prints mapping statistics.]
+ Synopsis [Assigns levels.]
Description []
@@ -333,12 +187,17 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-int Gia_ManLutFaninCount( Gia_Man_t * p )
+void Gia_ManSetRefsMapped( Gia_Man_t * p )
{
- int i, Counter = 0;
+ Gia_Obj_t * pObj;
+ int i, k, iFan;
+ ABC_FREE( p->pRefs );
+ p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ObjRefInc( p, Gia_ObjFanin0(pObj) );
Gia_ManForEachLut( p, i )
- Counter += Gia_ObjLutSize(p, i);
- return Counter;
+ Gia_LutForEachFanin( p, i, iFan, k )
+ Gia_ObjRefInc( p, Gia_ManObj(p, iFan) );
}
/**Function*************************************************************
@@ -352,17 +211,37 @@ int Gia_ManLutFaninCount( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-int Gia_ManLutSizeMax( Gia_Man_t * p )
+void Gia_ManPrintMappingStats( Gia_Man_t * p )
{
- int i, nSizeMax = -1;
+ int * pLevels;
+ int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0;
+ if ( !p->pMapping )
+ return;
+ pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
Gia_ManForEachLut( p, i )
- nSizeMax = Abc_MaxInt( nSizeMax, Gia_ObjLutSize(p, i) );
- return nSizeMax;
+ {
+ nLuts++;
+ nFanins += Gia_ObjLutSize(p, i);
+ nLutSize = Abc_MaxInt( nLutSize, Gia_ObjLutSize(p, i) );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[iFan] );
+ pLevels[i]++;
+ LevelMax = Abc_MaxInt( LevelMax, pLevels[i] );
+ }
+ ABC_FREE( pLevels );
+ Abc_Print( 1, "mapping (K=%d) : ", nLutSize );
+ Abc_Print( 1, "lut =%7d ", nLuts );
+ Abc_Print( 1, "edge =%8d ", nFanins );
+ Abc_Print( 1, "lev =%5d ", LevelMax );
+ Abc_Print( 1, "mem =%5.2f MB", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) );
+ Abc_Print( 1, "\n" );
}
+
+
/**Function*************************************************************
- Synopsis [Prints mapping statistics.]
+ Synopsis [Converts GIA into IF manager.]
Description []
@@ -371,17 +250,66 @@ int Gia_ManLutSizeMax( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-int Gia_ManLutNum( Gia_Man_t * p )
+static inline If_Obj_t * If_ManFanin0Copy( If_Man_t * pIfMan, Gia_Obj_t * pObj ) { return If_NotCond( If_ManObj(pIfMan, Gia_ObjValue(Gia_ObjFanin0(pObj))), Gia_ObjFaninC0(pObj) ); }
+static inline If_Obj_t * If_ManFanin1Copy( If_Man_t * pIfMan, Gia_Obj_t * pObj ) { return If_NotCond( If_ManObj(pIfMan, Gia_ObjValue(Gia_ObjFanin1(pObj))), Gia_ObjFaninC1(pObj) ); }
+If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars )
{
- int i, Counter = 0;
- Gia_ManForEachLut( p, i )
- Counter ++;
- return Counter;
+ If_Man_t * pIfMan;
+ If_Obj_t * pIfObj;
+ Gia_Obj_t * pObj;
+ int i;
+ // create levels with choices
+ Gia_ManChoiceLevel( p );
+ // mark representative nodes
+ Gia_ManMarkFanoutDrivers( p );
+ // start the mapping manager and set its parameters
+ pIfMan = If_ManStart( pPars );
+ pIfMan->pName = Abc_UtilStrsav( Gia_ManName(p) );
+ // print warning about excessive memory usage
+ if ( 1.0 * Gia_ManObjNum(p) * pIfMan->nObjBytes / (1<<30) > 1.0 )
+ printf( "Warning: The mapper will allocate %.1f GB for to represent the subject graph with %d AIG nodes.\n",
+ 1.0 * Gia_ManObjNum(p) * pIfMan->nObjBytes / (1<<30), Gia_ManObjNum(p) );
+ // load the AIG into the mapper
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = If_ObjId( If_ManConst1(pIfMan) );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ pIfObj = If_ManCreateAnd( pIfMan, If_ManFanin0Copy(pIfMan, pObj), If_ManFanin1Copy(pIfMan, pObj) );
+ else if ( Gia_ObjIsCi(pObj) )
+ {
+ pIfObj = If_ManCreateCi( pIfMan );
+ If_ObjSetLevel( pIfObj, Gia_ObjLevel(p, pObj) );
+// Abc_Print( 1, "pi%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) );
+ if ( pIfMan->nLevelMax < (int)pIfObj->Level )
+ pIfMan->nLevelMax = (int)pIfObj->Level;
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ {
+ pIfObj = If_ManCreateCo( pIfMan, If_NotCond( If_ManFanin0Copy(pIfMan, pObj), Gia_ObjIsConst0(Gia_ObjFanin0(pObj))) );
+// Abc_Print( 1, "po%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) );
+ }
+ else assert( 0 );
+ assert( i == If_ObjId(pIfObj) );
+ Gia_ObjSetValue( pObj, If_ObjId(pIfObj) );
+ // set up the choice node
+ if ( Gia_ObjSibl(p, i) && pObj->fMark0 )
+ {
+ Gia_Obj_t * pSibl, * pPrev;
+ for ( pPrev = pObj, pSibl = Gia_ObjSiblObj(p, i); pSibl; pPrev = pSibl, pSibl = Gia_ObjSiblObj(p, Gia_ObjId(p, pSibl)) )
+ If_ObjSetChoice( If_ManObj(pIfMan, Gia_ObjValue(pObj)), If_ManObj(pIfMan, Gia_ObjValue(pSibl)) );
+ If_ManCreateChoice( pIfMan, If_ManObj(pIfMan, Gia_ObjValue(pObj)) );
+ }
+// assert( If_ObjLevel(pIfObj) == Gia_ObjLevel(pNode) );
+ }
+ Gia_ManCleanMark0( p );
+ return pIfMan;
}
+
/**Function*************************************************************
- Synopsis [Prints mapping statistics.]
+ Synopsis [Derives node's AIG after SOP balancing]
Description []
@@ -390,30 +318,47 @@ int Gia_ManLutNum( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-int Gia_ManLutLevel( Gia_Man_t * p )
+int Gia_ManNodeIfSopToGiaInt( Gia_Man_t * pNew, Vec_Wrd_t * vAnds, int nVars, Vec_Int_t * vLeaves, int fHash )
{
- Gia_Obj_t * pObj;
- int i, k, iFan, Level;
- int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) );
- Gia_ManForEachLut( p, i )
+ Vec_Int_t * vResults;
+ int iRes0, iRes1, iRes = -1;
+ If_And_t This;
+ word Entry;
+ int i;
+ if ( Vec_WrdSize(vAnds) == 0 )
+ return 0;
+ if ( Vec_WrdSize(vAnds) == 1 && Vec_WrdEntry(vAnds,0) == 0 )
+ return 1;
+ vResults = Vec_IntAlloc( Vec_WrdSize(vAnds) );
+ for ( i = 0; i < nVars; i++ )
+ Vec_IntPush( vResults, Vec_IntEntry(vLeaves, i) );
+ Vec_WrdForEachEntryStart( vAnds, Entry, i, nVars )
{
- Level = 0;
- Gia_LutForEachFanin( p, i, iFan, k )
- if ( Level < pLevels[iFan] )
- Level = pLevels[iFan];
- pLevels[i] = Level + 1;
+ This = If_WrdToAnd( Entry );
+ iRes0 = Abc_LitNotCond( Vec_IntEntry(vResults, This.iFan0), This.fCompl0 );
+ iRes1 = Abc_LitNotCond( Vec_IntEntry(vResults, This.iFan1), This.fCompl1 );
+ if ( fHash )
+ iRes = Gia_ManHashAnd( pNew, iRes0, iRes1 );
+ else
+ iRes = Gia_ManAppendAnd( pNew, iRes0, iRes1 );
+ Vec_IntPush( vResults, iRes );
}
- Level = 0;
- Gia_ManForEachCo( p, pObj, k )
- if ( Level < pLevels[Gia_ObjFaninId0p(p, pObj)] )
- Level = pLevels[Gia_ObjFaninId0p(p, pObj)];
- ABC_FREE( pLevels );
- return Level;
+ Vec_IntFree( vResults );
+ return Abc_LitNotCond( iRes, This.fCompl );
+}
+int Gia_ManNodeIfSopToGia( Gia_Man_t * pNew, If_Man_t * p, If_Cut_t * pCut, Vec_Int_t * vLeaves, int fHash )
+{
+ int iResult;
+ Vec_Wrd_t * vArray;
+ vArray = If_CutDelaySopArray( p, pCut );
+ iResult = Gia_ManNodeIfSopToGiaInt( pNew, vArray, If_CutLeaveNum(pCut), vLeaves, fHash );
+// Vec_WrdFree( vArray );
+ return iResult;
}
/**Function*************************************************************
- Synopsis [Assigns levels.]
+ Synopsis [Recursively derives the local AIG for the cut.]
Description []
@@ -422,22 +367,74 @@ int Gia_ManLutLevel( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-void Gia_ManSetRefsMapped( Gia_Man_t * p )
+int Gia_ManNodeIfToGia_rec( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited, int fHash )
{
- Gia_Obj_t * pObj;
- int i, k, iFan;
- ABC_FREE( p->pRefs );
- p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) );
- Gia_ManForEachCo( p, pObj, i )
- Gia_ObjRefInc( p, Gia_ObjFanin0(pObj) );
- Gia_ManForEachLut( p, i )
- Gia_LutForEachFanin( p, i, iFan, k )
- Gia_ObjRefInc( p, Gia_ManObj(p, iFan) );
+ If_Cut_t * pCut;
+ If_Obj_t * pTemp;
+ int iFunc, iFunc0, iFunc1;
+ // get the best cut
+ pCut = If_ObjCutBest(pIfObj);
+ // if the cut is visited, return the result
+ if ( If_CutDataInt(pCut) )
+ return If_CutDataInt(pCut);
+ // mark the node as visited
+ Vec_PtrPush( vVisited, pCut );
+ // insert the worst case
+ If_CutSetDataInt( pCut, ~0 );
+ // skip in case of primary input
+ if ( If_ObjIsCi(pIfObj) )
+ return If_CutDataInt(pCut);
+ // compute the functions of the children
+ for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv )
+ {
+ iFunc0 = Gia_ManNodeIfToGia_rec( pNew, pIfMan, pTemp->pFanin0, vVisited, fHash );
+ if ( iFunc0 == ~0 )
+ continue;
+ iFunc1 = Gia_ManNodeIfToGia_rec( pNew, pIfMan, pTemp->pFanin1, vVisited, fHash );
+ if ( iFunc1 == ~0 )
+ continue;
+ // both branches are solved
+ if ( fHash )
+ iFunc = Gia_ManHashAnd( pNew, Abc_LitNotCond(iFunc0, pTemp->fCompl0), Abc_LitNotCond(iFunc1, pTemp->fCompl1) );
+ else
+ iFunc = Gia_ManAppendAnd( pNew, Abc_LitNotCond(iFunc0, pTemp->fCompl0), Abc_LitNotCond(iFunc1, pTemp->fCompl1) );
+ if ( pTemp->fPhase != pIfObj->fPhase )
+ iFunc = Abc_LitNot(iFunc);
+ If_CutSetDataInt( pCut, iFunc );
+ break;
+ }
+ return If_CutDataInt(pCut);
+}
+int Gia_ManNodeIfToGia( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Int_t * vLeaves, int fHash )
+{
+ If_Cut_t * pCut;
+ If_Obj_t * pLeaf;
+ int i, iRes;
+ // get the best cut
+ pCut = If_ObjCutBest(pIfObj);
+ assert( pCut->nLeaves > 1 );
+ // set the leaf variables
+ If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
+ If_CutSetDataInt( If_ObjCutBest(pLeaf), Vec_IntEntry(vLeaves, i) );
+ // recursively compute the function while collecting visited cuts
+ Vec_PtrClear( pIfMan->vTemp );
+ iRes = Gia_ManNodeIfToGia_rec( pNew, pIfMan, pIfObj, pIfMan->vTemp, fHash );
+ if ( iRes == ~0 )
+ {
+ Abc_Print( -1, "Gia_ManNodeIfToGia(): Computing local AIG has failed.\n" );
+ return ~0;
+ }
+ // clean the cuts
+ If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
+ If_CutSetDataInt( If_ObjCutBest(pLeaf), 0 );
+ Vec_PtrForEachEntry( If_Cut_t *, pIfMan->vTemp, pCut, i )
+ If_CutSetDataInt( pCut, 0 );
+ return iRes;
}
/**Function*************************************************************
- Synopsis [Prints NPN class statistics.]
+ Synopsis [Converts IF into GIA manager.]
Description []
@@ -446,83 +443,212 @@ void Gia_ManSetRefsMapped( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-void Gia_ManPrintNpnClasses( Gia_Man_t * p )
+Gia_Man_t * Gia_ManFromIf( If_Man_t * pIfMan )
{
- extern char ** Kit_DsdNpn4ClassNames();
- char ** pNames = Kit_DsdNpn4ClassNames();
- Vec_Int_t * vLeaves, * vTruth, * vVisited;
- int * pLutClass, ClassCounts[222] = {0};
- int i, k, iFan, Class, OtherClasses, OtherClasses2, nTotal, Counter, Counter2;
+ int fHash = 0;
+ Gia_Man_t * pNew;
+ If_Obj_t * pIfObj, * pIfLeaf;
+ If_Cut_t * pCutBest;
+ Vec_Int_t * vLeaves;
+ Vec_Int_t * vCover;
unsigned * pTruth;
- assert( p->pMapping != NULL );
- assert( Gia_ManLutSizeMax( p ) <= 4 );
- vLeaves = Vec_IntAlloc( 100 );
- vVisited = Vec_IntAlloc( 100 );
- vTruth = Vec_IntAlloc( (1<<16) );
- pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) );
- Gia_ManCleanTruth( p );
- Gia_ManForEachLut( p, i )
+ int Counter, iOffset, nItems = 0;
+ int i, k, w, GiaId;
+ // create new manager
+ pNew = Gia_ManStart( If_ManObjNum(pIfMan) );
+ Gia_ManHashAlloc( pNew );
+ // iterate through nodes used in the mapping
+ vCover = Vec_IntAlloc( 1 << 16 );
+ vLeaves = Vec_IntAlloc( 16 );
+ If_ManCleanCutData( pIfMan );
+ If_ManForEachObj( pIfMan, pIfObj, i )
{
- if ( Gia_ObjLutSize(p,i) > 4 )
+ if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) )
continue;
- Vec_IntClear( vLeaves );
- Gia_LutForEachFanin( p, i, iFan, k )
- Vec_IntPush( vLeaves, iFan );
- for ( ; k < 4; k++ )
- Vec_IntPush( vLeaves, 0 );
- pTruth = Gia_ManConvertAigToTruth( p, Gia_ManObj(p, i), vLeaves, vTruth, vVisited );
- Class = Dar_LibReturnClass( *pTruth );
- ClassCounts[ Class ]++;
- pLutClass[i] = Class;
+ if ( If_ObjIsAnd(pIfObj) )
+ {
+ pCutBest = If_ObjCutBest( pIfObj );
+ // collect leaves of the best cut
+ Vec_IntClear( vLeaves );
+ If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
+ Vec_IntPush( vLeaves, pIfLeaf->iCopy );
+ // get the functionality
+ if ( pIfMan->pPars->pLutStruct )
+ pIfObj->iCopy = Kit_TruthToGia( pNew, If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), vCover, vLeaves, fHash );
+ else if ( pIfMan->pPars->fDelayOpt )
+ pIfObj->iCopy = Gia_ManNodeIfSopToGia( pNew, pIfMan, pCutBest, vLeaves, fHash );
+ else if ( pIfMan->pPars->fUserRecLib )
+ pIfObj->iCopy = Abc_RecToGia2( pNew, pIfMan, pCutBest, pIfObj, vLeaves, fHash );
+ else
+ pIfObj->iCopy = Gia_ManNodeIfToGia( pNew, pIfMan, pIfObj, vLeaves, fHash );
+ // complement the node if the TT was used and the cut was complemented
+ if ( pIfMan->pPars->pLutStruct )
+ pIfObj->iCopy = Abc_LitNotCond( pIfObj->iCopy, pCutBest->fCompl );
+ // count entries in the mapping array
+ nItems += 2 + If_CutLeaveNum( pCutBest );
+ }
+ else if ( If_ObjIsCi(pIfObj) )
+ pIfObj->iCopy = Gia_ManAppendCi(pNew);
+ else if ( If_ObjIsCo(pIfObj) )
+ pIfObj->iCopy = Gia_ManAppendCo( pNew, Abc_LitNotCond(If_ObjFanin0(pIfObj)->iCopy, If_ObjFaninC0(pIfObj)) );
+ else if ( If_ObjIsConst1(pIfObj) )
+ {
+ pIfObj->iCopy = 1;
+ nItems += 2;
+ }
+ else assert( 0 );
}
+ Vec_IntFree( vCover );
Vec_IntFree( vLeaves );
- Vec_IntFree( vTruth );
- Vec_IntFree( vVisited );
- Vec_IntFreeP( &p->vTruths );
- nTotal = 0;
- for ( i = 0; i < 222; i++ )
- nTotal += ClassCounts[i];
- Abc_Print( 1, "NPN CLASS STATISTICS (for %d LUT4 present in the current mapping):\n", nTotal );
- OtherClasses = 0;
- for ( i = 0; i < 222; i++ )
+ Gia_ManHashStop( pNew );
+
+ // GIA after mapping with choices may end up with dangling nodes
+ // which participate as leaves of some cuts used in the mapping
+ // such nodes are marked here and skipped when mapping is derived
+ Counter = Gia_ManMarkDangling(pNew);
+// if ( pIfMan->pPars->fVerbose && Counter )
+ if ( Counter )
+ printf( "GIA after mapping has %d dangling nodes.\n", Counter );
+
+ // create mapping
+ iOffset = Gia_ManObjNum(pNew);
+ pNew->pMapping = ABC_CALLOC( int, iOffset + nItems );
+ assert( pNew->vTruths == NULL );
+ if ( pIfMan->pPars->pLutStruct )
+ pNew->vTruths = Vec_IntAlloc( 1000 );
+ If_ManForEachObj( pIfMan, pIfObj, i )
{
- if ( ClassCounts[i] == 0 )
+ if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) )
continue;
- if ( 100.0 * ClassCounts[i] / (nTotal+1) < 0.1 ) // do not show anything below 0.1 percent
- continue;
- OtherClasses += ClassCounts[i];
- Abc_Print( 1, "Class %3d : Count = %6d (%7.2f %%) %s\n",
- i, ClassCounts[i], 100.0 * ClassCounts[i] / (nTotal+1), pNames[i] );
+ if ( If_ObjIsAnd(pIfObj) )
+ {
+ GiaId = Abc_Lit2Var( pIfObj->iCopy );
+ if ( !Gia_ObjIsAnd(Gia_ManObj(pNew, GiaId)) ) // skip trivial node
+ continue;
+ assert( Gia_ObjIsAnd(Gia_ManObj(pNew, GiaId)) );
+ if ( !Gia_ManObj(pNew, GiaId)->fMark0 ) // skip dangling node
+ continue;
+ // get the best cut
+ pCutBest = If_ObjCutBest( pIfObj );
+ // copy the truth tables
+ pTruth = NULL;
+ if ( pNew->vTruths )
+ {
+ // copy truth table
+ for ( w = 0; w < pIfMan->nTruthWords; w++ )
+ Vec_IntPush( pNew->vTruths, If_CutTruth(pCutBest)[w] );
+ pTruth = (unsigned *)(Vec_IntArray(pNew->vTruths) + Vec_IntSize(pNew->vTruths) - pIfMan->nTruthWords);
+ // complement
+ if ( pCutBest->fCompl ^ Abc_LitIsCompl(pIfObj->iCopy) )
+ for ( w = 0; w < pIfMan->nTruthWords; w++ )
+ pTruth[w] = ~pTruth[w];
+ }
+ // create node
+ pNew->pMapping[GiaId] = iOffset;
+ pNew->pMapping[iOffset++] = If_CutLeaveNum(pCutBest);
+ If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
+ {
+ int FaninId = Abc_Lit2Var(pIfLeaf->iCopy);
+ if ( pTruth && Abc_LitIsCompl(pIfLeaf->iCopy) )
+ Kit_TruthChangePhase( pTruth, If_CutLeaveNum(pCutBest), k );
+ if ( !Gia_ManObj(pNew, FaninId)->fMark0 ) // skip dangling node
+ {
+ // update truth table
+ if ( pTruth )
+ {
+ extern void If_CluSwapVars( word * pTruth, int nVars, int * V2P, int * P2V, int iVar, int jVar );
+ if ( If_CutLeaveNum(pCutBest) >= 6 )
+ If_CluSwapVars( (word*)pTruth, If_CutLeaveNum(pCutBest), NULL, NULL, k, If_CutLeaveNum(pCutBest)-1 );
+ else
+ {
+ word Truth = ((word)pTruth[0] << 32) | (word)pTruth[0];
+ If_CluSwapVars( &Truth, 6, NULL, NULL, k, If_CutLeaveNum(pCutBest)-1 );
+ pTruth[0] = (Truth & 0xFFFFFFFF);
+ }
+ }
+ pNew->pMapping[iOffset-k-1]--;
+ continue;
+ }
+ assert( FaninId < GiaId );
+ pNew->pMapping[iOffset++] = FaninId;
+ }
+ pNew->pMapping[iOffset++] = GiaId;
+ }
+ else if ( If_ObjIsConst1(pIfObj) )
+ {
+ // create node
+ pNew->pMapping[0] = iOffset;
+ pNew->pMapping[iOffset++] = 0;
+ pNew->pMapping[iOffset++] = 0;
+/*
+ if ( pNew->vTruths )
+ {
+ printf( "%d ", nLeaves );
+ for ( w = 0; w < pIfMan->nTruthWords; w++ )
+ Vec_IntPush( pNew->vTruths, 0 );
+ }
+*/
+ }
}
- OtherClasses = nTotal - OtherClasses;
- Abc_Print( 1, "Other : Count = %6d (%7.2f %%)\n",
- OtherClasses, 100.0 * OtherClasses / (nTotal+1) );
- // count the number of LUTs that have MUX function and two fanins with MUX functions
- OtherClasses = OtherClasses2 = 0;
- ABC_FREE( p->pRefs );
- Gia_ManSetRefsMapped( p );
- Gia_ManForEachLut( p, i )
+ Gia_ManCleanMark0( pNew );
+// assert( iOffset == Gia_ManObjNum(pNew) + nItems );
+ if ( pIfMan->pManTim )
+ pNew->pManTime = Tim_ManDup( pIfMan->pManTim, 0 );
+ // verify that COs have mapping
{
- if ( pLutClass[i] != 109 )
- continue;
- Counter = Counter2 = 0;
- Gia_LutForEachFanin( p, i, iFan, k )
+ Gia_Obj_t * pObj;
+ Gia_ManForEachCo( pNew, pObj, i )
{
- Counter += (pLutClass[iFan] == 109);
- Counter2 += (pLutClass[iFan] == 109) && (Gia_ObjRefNumId(p, iFan) == 1);
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) )
+ assert( pNew->pMapping[Gia_ObjFaninId0p(pNew, pObj)] != 0 );
}
- OtherClasses += (Counter > 1);
- OtherClasses2 += (Counter2 > 1);
-// Abc_Print( 1, "%d -- ", pLutClass[i] );
-// Gia_LutForEachFanin( p, i, iFan, k )
-// Abc_Print( 1, "%d ", pLutClass[iFan] );
-// Abc_Print( 1, "\n" );
}
- ABC_FREE( p->pRefs );
- Abc_Print( 1, "Approximate number of 4:1 MUX structures: All = %6d (%7.2f %%) MFFC = %6d (%7.2f %%)\n",
- OtherClasses, 100.0 * OtherClasses / (nTotal+1),
- OtherClasses2, 100.0 * OtherClasses2 / (nTotal+1) );
- ABC_FREE( pLutClass );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interface of LUT mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManPerformMapping( Gia_Man_t * p, void * pp )
+{
+ Gia_Man_t * pNew;
+ If_Man_t * pIfMan;
+ If_Par_t * pPars = (If_Par_t *)pp;
+ // set the arrival times
+ assert( pPars->pTimesArr == NULL );
+ pPars->pTimesArr = ABC_ALLOC( float, Gia_ManCiNum(p) );
+ memset( pPars->pTimesArr, 0, sizeof(float) * Gia_ManCiNum(p) );
+ // translate into the mapper
+ pIfMan = Gia_ManToIf( p, pPars );
+ if ( pIfMan == NULL )
+ return NULL;
+ if ( p->pManTime )
+ pIfMan->pManTim = Tim_ManDup( p->pManTime, 0 );
+ if ( !If_ManPerformMapping( pIfMan ) )
+ {
+ If_ManStop( pIfMan );
+ return NULL;
+ }
+ // transform the result of mapping into the new network
+ pNew = Gia_ManFromIf( pIfMan );
+ If_ManStop( pIfMan );
+ // transfer name
+ assert( pNew->pName == NULL );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ // unmap in case of SOP balancing
+// if ( pIfMan->pPars->fDelayOpt )
+// Vec_IntFreeP( &pNew->vMapping );
+ return pNew;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c
index f78ea847..0ae484fc 100644
--- a/src/aig/gia/giaMan.c
+++ b/src/aig/gia/giaMan.c
@@ -21,6 +21,7 @@
#include "gia.h"
#include "misc/tim/tim.h"
#include "proof/abs/abs.h"
+#include "opt/dar/dar.h"
ABC_NAMESPACE_IMPL_START
@@ -107,6 +108,7 @@ void Gia_ManStop( Gia_Man_t * p )
ABC_FREE( p->pReprsOld );
ABC_FREE( p->pReprs );
ABC_FREE( p->pNexts );
+ ABC_FREE( p->pSibls );
ABC_FREE( p->pRefs );
// ABC_FREE( p->pNodeRefs );
ABC_FREE( p->pHTable );
@@ -260,6 +262,36 @@ void Gia_ManPrintTents( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
+void Gia_ManPrintChoiceStats( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, nEquivs = 0, nChoices = 0;
+ Gia_ManMarkFanoutDrivers( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjSibl(p, i) )
+ continue;
+ nEquivs++;
+ if ( pObj->fMark0 )
+ nChoices++;
+ assert( !Gia_ObjSiblObj(p, i)->fMark0 );
+ assert( Gia_ObjIsAnd(Gia_ObjSiblObj(p, i)) );
+ }
+ Abc_Print( 1, "Choice stats: Equivs =%7d. Choices =%7d.\n", nEquivs, nChoices );
+ Gia_ManCleanMark0( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats for the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Gia_ManPrintStats( Gia_Man_t * p, int fTents, int fSwitch )
{
if ( p->pName )
@@ -271,7 +303,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, int fTents, int fSwitch )
printf( " ff =%7d", Gia_ManRegNum(p) );
printf( " and =%8d", Gia_ManAndNum(p) );
printf( " lev =%5d", Gia_ManLevelNum(p) ); Vec_IntFreeP( &p->vLevels );
- printf( " cut =%5d", Gia_ManCrossCut(p) );
+ printf( " cut = %d(%d)", Gia_ManCrossCut(p, 0), Gia_ManCrossCut(p, 1) );
// printf( " mem =%5.2f MB", 1.0*(sizeof(Gia_Obj_t)*p->nObjs + sizeof(int)*(Vec_IntSize(p->vCis) + Vec_IntSize(p->vCos)))/(1<<20) );
printf( " mem =%5.2f MB", 1.0*(sizeof(Gia_Obj_t)*p->nObjsAlloc + sizeof(int)*(Vec_IntCap(p->vCis) + Vec_IntCap(p->vCos)))/(1<<20) );
if ( Gia_ManHasDangling(p) )
@@ -289,6 +321,8 @@ void Gia_ManPrintStats( Gia_Man_t * p, int fTents, int fSwitch )
// Gia_ManSatExperiment( p );
if ( p->pReprs && p->pNexts )
Gia_ManEquivPrintClasses( p, 0, 0.0 );
+ if ( p->pSibls )
+ Gia_ManPrintChoiceStats( p );
if ( p->pMapping )
Gia_ManPrintMappingStats( p );
if ( p->pPlacement )
@@ -427,6 +461,96 @@ void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew )
printf( "\n" );
}
+/**Function*************************************************************
+
+ Synopsis [Prints NPN class statistics.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManPrintNpnClasses( Gia_Man_t * p )
+{
+ extern char ** Kit_DsdNpn4ClassNames();
+ char ** pNames = Kit_DsdNpn4ClassNames();
+ Vec_Int_t * vLeaves, * vTruth, * vVisited;
+ int * pLutClass, ClassCounts[222] = {0};
+ int i, k, iFan, Class, OtherClasses, OtherClasses2, nTotal, Counter, Counter2;
+ unsigned * pTruth;
+ assert( p->pMapping != NULL );
+ assert( Gia_ManLutSizeMax( p ) <= 4 );
+ vLeaves = Vec_IntAlloc( 100 );
+ vVisited = Vec_IntAlloc( 100 );
+ vTruth = Vec_IntAlloc( (1<<16) );
+ pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) );
+ Gia_ManCleanTruth( p );
+ Gia_ManForEachLut( p, i )
+ {
+ if ( Gia_ObjLutSize(p,i) > 4 )
+ continue;
+ Vec_IntClear( vLeaves );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ Vec_IntPush( vLeaves, iFan );
+ for ( ; k < 4; k++ )
+ Vec_IntPush( vLeaves, 0 );
+ pTruth = Gia_ManConvertAigToTruth( p, Gia_ManObj(p, i), vLeaves, vTruth, vVisited );
+ Class = Dar_LibReturnClass( *pTruth );
+ ClassCounts[ Class ]++;
+ pLutClass[i] = Class;
+ }
+ Vec_IntFree( vLeaves );
+ Vec_IntFree( vTruth );
+ Vec_IntFree( vVisited );
+ Vec_IntFreeP( &p->vTruths );
+ nTotal = 0;
+ for ( i = 0; i < 222; i++ )
+ nTotal += ClassCounts[i];
+ Abc_Print( 1, "NPN CLASS STATISTICS (for %d LUT4 present in the current mapping):\n", nTotal );
+ OtherClasses = 0;
+ for ( i = 0; i < 222; i++ )
+ {
+ if ( ClassCounts[i] == 0 )
+ continue;
+ if ( 100.0 * ClassCounts[i] / (nTotal+1) < 0.1 ) // do not show anything below 0.1 percent
+ continue;
+ OtherClasses += ClassCounts[i];
+ Abc_Print( 1, "Class %3d : Count = %6d (%7.2f %%) %s\n",
+ i, ClassCounts[i], 100.0 * ClassCounts[i] / (nTotal+1), pNames[i] );
+ }
+ OtherClasses = nTotal - OtherClasses;
+ Abc_Print( 1, "Other : Count = %6d (%7.2f %%)\n",
+ OtherClasses, 100.0 * OtherClasses / (nTotal+1) );
+ // count the number of LUTs that have MUX function and two fanins with MUX functions
+ OtherClasses = OtherClasses2 = 0;
+ ABC_FREE( p->pRefs );
+ Gia_ManSetRefsMapped( p );
+ Gia_ManForEachLut( p, i )
+ {
+ if ( pLutClass[i] != 109 )
+ continue;
+ Counter = Counter2 = 0;
+ Gia_LutForEachFanin( p, i, iFan, k )
+ {
+ Counter += (pLutClass[iFan] == 109);
+ Counter2 += (pLutClass[iFan] == 109) && (Gia_ObjRefNumId(p, iFan) == 1);
+ }
+ OtherClasses += (Counter > 1);
+ OtherClasses2 += (Counter2 > 1);
+// Abc_Print( 1, "%d -- ", pLutClass[i] );
+// Gia_LutForEachFanin( p, i, iFan, k )
+// Abc_Print( 1, "%d ", pLutClass[iFan] );
+// Abc_Print( 1, "\n" );
+ }
+ ABC_FREE( p->pRefs );
+ Abc_Print( 1, "Approximate number of 4:1 MUX structures: All = %6d (%7.2f %%) MFFC = %6d (%7.2f %%)\n",
+ OtherClasses, 100.0 * OtherClasses / (nTotal+1),
+ OtherClasses2, 100.0 * OtherClasses2 / (nTotal+1) );
+ ABC_FREE( pLutClass );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaScl.c b/src/aig/gia/giaScl.c
index 0aa255db..9b4c1c3e 100644
--- a/src/aig/gia/giaScl.c
+++ b/src/aig/gia/giaScl.c
@@ -94,6 +94,32 @@ Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p )
return Gia_ManDupMarked( p );
}
+/**Function*************************************************************
+
+ Synopsis [Skip the first outputs during cleanup.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ assert( Gia_ManRegNum(p) == 0 );
+ assert( nOutputs < Gia_ManCoNum(p) );
+ Gia_ManCombMarkUsed( p );
+ Gia_ManForEachCo( p, pObj, i )
+ if ( i < nOutputs )
+ pObj->fMark0 = 1;
+ else
+ break;
+ return Gia_ManDupMarked( p );
+}
+
/**Function*************************************************************
diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c
index da713aa0..8389a9b0 100644
--- a/src/aig/gia/giaUtil.c
+++ b/src/aig/gia/giaUtil.c
@@ -550,12 +550,59 @@ int * Gia_ManCreateMuxRefs( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
-int Gia_ManCrossCut( Gia_Man_t * p )
+void Gia_ManDfsForCrossCut_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes )
{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+ return;
+ }
+ if ( Gia_ObjIsCo(pObj) )
+ {
+ Gia_ObjFanin0(pObj)->Value++;
+ Gia_ManDfsForCrossCut_rec( p, Gia_ObjFanin0(pObj), vNodes );
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ObjFanin0(pObj)->Value++;
+ Gia_ObjFanin1(pObj)->Value++;
+ Gia_ManDfsForCrossCut_rec( p, Gia_ObjFanin0(pObj), vNodes );
+ Gia_ManDfsForCrossCut_rec( p, Gia_ObjFanin1(pObj), vNodes );
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+}
+Vec_Int_t * Gia_ManDfsForCrossCut( Gia_Man_t * p, int fReverse )
+{
+ Vec_Int_t * vNodes;
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManCleanValue( p );
+ vNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Gia_ManIncrementTravId( p );
+ if ( fReverse )
+ {
+ Gia_ManForEachCoReverse( p, pObj, i )
+ if ( !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
+ Gia_ManDfsForCrossCut_rec( p, pObj, vNodes );
+ }
+ else
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ if ( !Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
+ Gia_ManDfsForCrossCut_rec( p, pObj, vNodes );
+ }
+ return vNodes;
+}
+int Gia_ManCrossCut( Gia_Man_t * p, int fReverse )
+{
+ Vec_Int_t * vNodes;
Gia_Obj_t * pObj;
int i, nCutCur = 0, nCutMax = 0;
- Gia_ManCreateValueRefs( p );
- Gia_ManForEachObj( p, pObj, i )
+ vNodes = Gia_ManDfsForCrossCut( p, fReverse );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
{
if ( pObj->Value )
nCutCur++;
@@ -574,8 +621,9 @@ int Gia_ManCrossCut( Gia_Man_t * p )
nCutCur--;
}
}
-// Gia_ManForEachObj( p, pObj, i )
-// assert( pObj->Value == 0 );
+ Vec_IntFree( vNodes );
+ Gia_ManForEachObj( p, pObj, i )
+ assert( pObj->Value == 0 );
return nCutMax;
}
@@ -1195,6 +1243,31 @@ int Gia_ManCompare( Gia_Man_t * p1, Gia_Man_t * p2 )
return 1;
}
+/**Function*************************************************************
+
+ Synopsis [Marks nodes that appear as faninis of other nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManMarkFanoutDrivers( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManCleanMark0( p );
+ Gia_ManForEachObj( p, pObj, i )
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ Gia_ObjFanin1(pObj)->fMark0 = 1;
+ }
+ else if ( Gia_ObjIsCo(pObj) )
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index f8e16cd6..e08e11d9 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -789,7 +789,7 @@ extern ABC_DLL int Abc_NtkRecVarNum();
extern ABC_DLL Vec_Int_t * Abc_NtkRecMemory();
extern ABC_DLL int Abc_NtkRecStrashNode( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, unsigned * pTruth, int nVars );
/*=== abcRec2.c ==========================================================*/
-extern ABC_DLL void Abc_NtkRecStart2( Gia_Man_t *p, int nVars, int nCuts, int fTrim );
+extern ABC_DLL void Abc_NtkRecStart2( Gia_Man_t * p, int nVars, int nCuts, int fTrim );
extern ABC_DLL void Abc_NtkRecStop2();
extern ABC_DLL void Abc_NtkRecAdd2( Abc_Ntk_t * pNtk, int fUseSOPB );
extern ABC_DLL void Abc_NtkRecPs2(int fPrintLib);
@@ -798,6 +798,15 @@ extern ABC_DLL void Abc_NtkRecLibMerge2(Gia_Man_t * pGia);
extern ABC_DLL int Abc_NtkRecIsRunning2();
extern ABC_DLL int Abc_NtkRecIsInTrimMode2();
extern ABC_DLL void Abc_NtkRecFilter2(int nLimit);
+/*=== abcRec3.c ==========================================================*/
+extern ABC_DLL void Abc_NtkRecStart3( Gia_Man_t * p, int nVars, int nCuts, int fFuncOnly, int fVerbose );
+extern ABC_DLL void Abc_NtkRecStop3();
+extern ABC_DLL void Abc_NtkRecAdd3( Abc_Ntk_t * pNtk, int fUseSOPB );
+extern ABC_DLL void Abc_NtkRecPs3(int fPrintLib);
+extern ABC_DLL Gia_Man_t * Abc_NtkRecGetGia3();
+extern ABC_DLL int Abc_NtkRecIsRunning3();
+extern ABC_DLL void Abc_NtkRecLibMerge3(Gia_Man_t * pGia);
+//extern ABC_DLL void Abc_NtkRecFilter3(int nLimit);
/*=== abcReconv.c ==========================================================*/
extern ABC_DLL Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop );
extern ABC_DLL void Abc_NtkManCutStop( Abc_ManCut_t * p );
diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c
index bc3399e0..6dc06f19 100644
--- a/src/base/abc/abcCheck.c
+++ b/src/base/abc/abcCheck.c
@@ -377,12 +377,12 @@ int Abc_NtkCheckPos( Abc_Ntk_t * pNtk )
}
if ( Abc_ObjFaninNum(pObj) != 1 )
{
- fprintf( stdout, "NetworkCheck: A PO \"%s\" does not have one fanin.\n", Abc_ObjName(pObj) );
+ fprintf( stdout, "NetworkCheck: A PO \"%s\" does not have one fanin (but %d).\n", Abc_ObjName(pObj), Abc_ObjFaninNum(pObj) );
return 0;
}
if ( Abc_ObjFanoutNum(pObj) > 0 )
{
- fprintf( stdout, "NetworkCheck: A PO \"%s\" has fanouts.\n", Abc_ObjName(pObj) );
+ fprintf( stdout, "NetworkCheck: A PO \"%s\" has %d fanout(s).\n", Abc_ObjName(pObj), Abc_ObjFanoutNum(pObj) );
return 0;
}
pObj->pCopy = (Abc_Obj_t *)1;
diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c
index 5fb22d79..2669ae0c 100644
--- a/src/base/abc/abcFanio.c
+++ b/src/base/abc/abcFanio.c
@@ -87,20 +87,13 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
assert( !Abc_ObjIsComplement(pObj) );
assert( pObj->pNtk == pFaninR->pNtk );
assert( pObj->Id >= 0 && pFaninR->Id >= 0 );
+ assert( !Abc_ObjIsPi(pObj) && !Abc_ObjIsPo(pFanin) ); // fanin of PI or fanout of PO
+ assert( !Abc_ObjIsCo(pObj) || !Abc_ObjFaninNum(pObj) ); // CO with two fanins
+ assert( !Abc_ObjIsNet(pObj) || !Abc_ObjFaninNum(pObj) ); // net with two fanins
Vec_IntPushMem( pObj->pNtk->pMmStep, &pObj->vFanins, pFaninR->Id );
Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id );
if ( Abc_ObjIsComplement(pFanin) )
Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
- if ( Abc_ObjIsNet(pObj) && Abc_ObjFaninNum(pObj) > 1 )
- {
- printf( "Abc_ObjAddFanin(): Error! Creating net \"%s\" with two fanins.\n", Abc_ObjName(pObj) );
- }
-/*
- if ( Abc_ObjIsCo(pFanin) )
- {
- printf( "Abc_ObjAddFanin(): Error! Creating fanout of a CO.\n", Abc_ObjName(pFanin) );
- }
-*/
}
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index d1acef62..c6ec9d5b 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -169,6 +169,10 @@ static int Abc_CommandSenseInput ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandNpnLoad ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandNpnSave ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSendAig ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSendStatus ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSendCex ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
static int Abc_CommandIStrash ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandICut ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -201,20 +205,27 @@ static int Abc_CommandFraigDress ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandRecStart ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecStop ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandRecAdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRecAdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecUse ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecFilter ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecMerge ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecStart2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRecStop2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecPs2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecAdd2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandRecStop2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecDump2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecMerge2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRecFilter2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRecStart3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRecStop3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRecPs3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRecAdd3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRecDump3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRecMerge3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
static int Abc_CommandMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandUnmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -622,6 +633,10 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "npnload", Abc_CommandNpnLoad, 0 );
Cmd_CommandAdd( pAbc, "Various", "npnsave", Abc_CommandNpnSave, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "send_aig", Abc_CommandSendAig, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "send_status", Abc_CommandSendStatus, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "send_cex", Abc_CommandSendCex, 0 );
+
Cmd_CommandAdd( pAbc, "New AIG", "istrash", Abc_CommandIStrash, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "icut", Abc_CommandICut, 0 );
Cmd_CommandAdd( pAbc, "New AIG", "irw", Abc_CommandIRewrite, 1 );
@@ -653,16 +668,23 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Choicing", "rec_add", Abc_CommandRecAdd, 0 );
Cmd_CommandAdd( pAbc, "Choicing", "rec_ps", Abc_CommandRecPs, 0 );
Cmd_CommandAdd( pAbc, "Choicing", "rec_use", Abc_CommandRecUse, 1 );
- Cmd_CommandAdd( pAbc, "Choicing", "rec_filter", Abc_CommandRecFilter, 1 );
- Cmd_CommandAdd( pAbc, "Choicing", "rec_merge", Abc_CommandRecMerge, 1 );
-
- Cmd_CommandAdd( pAbc, "Choicing", "rec_start2", Abc_CommandRecStart2, 0 );
- Cmd_CommandAdd( pAbc, "Choicing", "rec_stop2", Abc_CommandRecStop2, 0 );
- Cmd_CommandAdd( pAbc, "Choicing", "rec_add2", Abc_CommandRecAdd2, 0 );
- Cmd_CommandAdd( pAbc, "Choicing", "rec_ps2", Abc_CommandRecPs2, 0 );
- Cmd_CommandAdd( pAbc, "Choicing", "rec_dump2", Abc_CommandRecDump2, 1 );
- Cmd_CommandAdd( pAbc, "Choicing", "rec_filter2", Abc_CommandRecFilter2, 1 );
- Cmd_CommandAdd( pAbc, "Choicing", "rec_merge2", Abc_CommandRecMerge2, 1 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_filter", Abc_CommandRecFilter, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_merge", Abc_CommandRecMerge, 0 );
+
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_start2", Abc_CommandRecStart2, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_stop2", Abc_CommandRecStop2, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_ps2", Abc_CommandRecPs2, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_add2", Abc_CommandRecAdd2, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_dump2", Abc_CommandRecDump2, 1 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_filter2", Abc_CommandRecFilter2, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_merge2", Abc_CommandRecMerge2, 0 );
+
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_start3", Abc_CommandRecStart3, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_stop3", Abc_CommandRecStop3, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_ps3", Abc_CommandRecPs3, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_add3", Abc_CommandRecAdd3, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_dump3", Abc_CommandRecDump3, 0 );
+ Cmd_CommandAdd( pAbc, "Choicing", "rec_merge3", Abc_CommandRecMerge3, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "map", Abc_CommandMap, 1 );
Cmd_CommandAdd( pAbc, "SC mapping", "amap", Abc_CommandAmap, 1 );
@@ -2628,10 +2650,10 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
pNtk = Abc_FrameReadNtk(pAbc);
// set defaults
- fVerbose = 1;
+ fVerbose = 0;
fReorder = 1;
fDualRail = 0;
- fBddSizeMax = 50000000;
+ fBddSizeMax = ABC_INFINITY;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Brdvh" ) ) != EOF )
{
@@ -4824,6 +4846,7 @@ usage:
Abc_Print( -2, "\t 1: algebraic factoring applied to ISOP\n" );
Abc_Print( -2, "\t 2: bi-decomposition with cofactoring\n" );
Abc_Print( -2, "\t 3: disjoint-support decomposition with cofactoring\n" );
+ Abc_Print( -2, "\t 4: updated disjoint-support decomposition with cofactoring\n" );
Abc_Print( -2, "\t-N <num> : the number of support variables (binary files only) [default = unused]\n" );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -4846,15 +4869,16 @@ usage:
***********************************************************************/
int Abc_CommandTestNpn( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int fVerbose );
+ extern int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int fBinary, int fVerbose );
char * pFileName;
int c;
int fVerbose = 0;
int NpnType = 0;
int nVarNum = -1;
int fDumpRes = 0;
+ int fBinary = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ANdvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ANdbvh" ) ) != EOF )
{
switch ( c )
{
@@ -4883,6 +4907,9 @@ int Abc_CommandTestNpn( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'd':
fDumpRes ^= 1;
break;
+ case 'b':
+ fBinary ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -4905,11 +4932,11 @@ int Abc_CommandTestNpn( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the output file name
pFileName = argv[globalUtilOptind];
// call the testbench
- Abc_NpnTest( pFileName, NpnType, nVarNum, fDumpRes, fVerbose );
+ Abc_NpnTest( pFileName, NpnType, nVarNum, fDumpRes, fBinary, fVerbose );
return 0;
usage:
- Abc_Print( -2, "usage: testnpn [-AN <num>] [-dvh] <file>\n" );
+ Abc_Print( -2, "usage: testnpn [-AN <num>] [-dbvh] <file>\n" );
Abc_Print( -2, "\t testbench for computing (semi-)canonical forms\n" );
Abc_Print( -2, "\t of completely-specified Boolean functions up to 16 varibles\n" );
Abc_Print( -2, "\t-A <num> : semi-caninical form computation algorithm [default = %d]\n", NpnType );
@@ -4920,6 +4947,7 @@ usage:
Abc_Print( -2, "\t 4: Jake's hybrid semi-canonical form (high-effort)\n" );
Abc_Print( -2, "\t-N <num> : the number of support variables (binary files only) [default = unused]\n" );
Abc_Print( -2, "\t-d : toggle dumping resulting functions into a file [default = %s]\n", fDumpRes? "yes": "no" );
+ Abc_Print( -2, "\t-b : toggle dumping in binary format [default = %s]\n", fBinary? "yes": "no" );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t<file> : a text file with truth tables in hexadecimal, listed one per line,\n");
@@ -11602,6 +11630,171 @@ usage:
return 1;
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSendAig( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern int Gia_ManToBridgeAbsNetlist( FILE * pFile, Gia_Man_t * p );
+ int c, fAndSpace = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "a" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'a':
+ fAndSpace ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if ( !Abc_FrameIsBridgeMode() )
+ {
+ Abc_Print( -1, "The bridge mode is not available.\n" );
+ return 1;
+ }
+ if ( fAndSpace )
+ {
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "There is no AIG in the &-space.\n" );
+ return 1;
+ }
+ Gia_ManToBridgeAbsNetlist( stdout, pAbc->pGia );
+ }
+ else
+ {
+ extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
+ Aig_Man_t * pAig;
+ Gia_Man_t * pGia;
+ if ( pAbc->pNtkCur == NULL )
+ {
+ Abc_Print( -1, "There is no network in the main-space.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsStrash(pAbc->pNtkCur) )
+ {
+ Abc_Print( -1, "The main-space network is not an AIG.\n" );
+ return 1;
+ }
+ pAig = Abc_NtkToDar( pAbc->pNtkCur, 0, 1 );
+ pGia = Gia_ManFromAig( pAig );
+ Aig_ManStop( pAig );
+ Gia_ManToBridgeAbsNetlist( stdout, pGia );
+ Gia_ManStop( pGia );
+ }
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: send_aig -a\n" );
+ Abc_Print( -2, "\t sends current AIG to the bridge\n" );
+ Abc_Print( -2, "\t-a : toggle sending AIG from &-space [default = %s]\n", fAndSpace? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSendStatus( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex );
+ int c;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( !Abc_FrameIsBridgeMode() )
+ {
+ Abc_Print( -1, "The bridge mode is not available.\n" );
+ return 1;
+ }
+ if ( pAbc->Status == 0 && pAbc->pCex == NULL )
+ {
+ Abc_Print( -1, "Status is \"sat\", but current CEX is not available.\n" );
+ return 1;
+ }
+ Gia_ManToBridgeResult( stdout, pAbc->Status, pAbc->pCex );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: send_status\n" );
+ Abc_Print( -2, "\t sends current status to the bridge\n" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSendCex( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_ManFromBridgeCex( FILE * pFile, Abc_Cex_t * pCex );
+ int c;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( !Abc_FrameIsBridgeMode() )
+ {
+ Abc_Print( -1, "The bridge mode is not available.\n" );
+ return 1;
+ }
+ if ( pAbc->pCex == NULL )
+ {
+ Abc_Print( -1, "Current CEX is not available.\n" );
+ return 1;
+ }
+ Gia_ManFromBridgeCex( stdout, pAbc->pCex );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: send_cex\n" );
+ Abc_Print( -2, "\t sends current CEX to the bridge\n" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
/**Function*************************************************************
@@ -12312,19 +12505,18 @@ usage:
SeeAlso []
***********************************************************************/
-int Abc_CommandRecAdd( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandRecPs( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c;
- int fUseSOPB = 0;
+// Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
+ int c, fPrintLib = 0;
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "gh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ph" ) ) != EOF )
{
switch ( c )
{
- case 'g':
- fUseSOPB = 1;
+ case 'p':
+ fPrintLib ^= 1;
break;
case 'h':
goto usage;
@@ -12332,22 +12524,17 @@ int Abc_CommandRecAdd( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
- if ( !Abc_NtkIsStrash(pNtk) )
- {
- Abc_Print( -1, "This command works for AIGs.\n" );
- return 0;
- }
if ( !Abc_NtkRecIsRunning() )
{
- Abc_Print( -1, "This command works for AIGs after calling \"rec_start\".\n" );
+ Abc_Print( -1, "This command works for AIGs only after calling \"rec_start\".\n" );
return 0;
}
- Abc_NtkRecAdd( pNtk, fUseSOPB);
+ Abc_NtkRecPs(fPrintLib);
return 0;
usage:
- Abc_Print( -2, "usage: rec_add [-h]\n" );
- Abc_Print( -2, "\t adds subgraphs from the current network to the set\n" );
+ Abc_Print( -2, "usage: rec_ps [-h]\n" );
+ Abc_Print( -2, "\t prints statistics about the recorded AIG subgraphs\n" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -12363,18 +12550,19 @@ usage:
SeeAlso []
***********************************************************************/
-int Abc_CommandRecPs( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandRecAdd( Abc_Frame_t * pAbc, int argc, char ** argv )
{
-// Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c, fPrintLib = 0;
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
+ int c;
+ int fUseSOPB = 0;
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ph" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "gh" ) ) != EOF )
{
switch ( c )
{
- case 'p':
- fPrintLib ^= 1;
+ case 'g':
+ fUseSOPB = 1;
break;
case 'h':
goto usage;
@@ -12382,17 +12570,22 @@ int Abc_CommandRecPs( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ Abc_Print( -1, "This command works for AIGs.\n" );
+ return 0;
+ }
if ( !Abc_NtkRecIsRunning() )
{
- Abc_Print( -1, "This command works for AIGs only after calling \"rec_start\".\n" );
+ Abc_Print( -1, "This command works for AIGs after calling \"rec_start\".\n" );
return 0;
}
- Abc_NtkRecPs(fPrintLib);
+ Abc_NtkRecAdd( pNtk, fUseSOPB);
return 0;
usage:
- Abc_Print( -2, "usage: rec_ps [-h]\n" );
- Abc_Print( -2, "\t prints statistics about the recorded AIG subgraphs\n" );
+ Abc_Print( -2, "usage: rec_add [-h]\n" );
+ Abc_Print( -2, "\t adds subgraphs from the current network to the set\n" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -12728,19 +12921,18 @@ usage:
SeeAlso []
***********************************************************************/
-int Abc_CommandRecAdd2( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandRecPs2( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c;
- int fUseSOPB = 0;
+// Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
+ int c, fPrintLib = 0;
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "gh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ph" ) ) != EOF )
{
switch ( c )
{
- case 'g':
- fUseSOPB = 1;
+ case 'p':
+ fPrintLib ^= 1;
break;
case 'h':
goto usage;
@@ -12748,22 +12940,17 @@ int Abc_CommandRecAdd2( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
- if ( !Abc_NtkIsStrash(pNtk) )
- {
- Abc_Print( -1, "This command works for AIGs.\n" );
- return 0;
- }
if ( !Abc_NtkRecIsRunning2() )
{
- Abc_Print( -1, "This command works for AIGs after calling \"rec_start2\".\n" );
+ Abc_Print( -1, "This command works for AIGs only after calling \"rec_start2\".\n" );
return 0;
}
- Abc_NtkRecAdd2( pNtk, fUseSOPB);
+ Abc_NtkRecPs2(fPrintLib);
return 0;
usage:
- Abc_Print( -2, "usage: rec_add2 [-h]\n" );
- Abc_Print( -2, "\t adds subgraphs from the current network to the set\n" );
+ Abc_Print( -2, "usage: rec_ps2 [-h]\n" );
+ Abc_Print( -2, "\t prints statistics about the recorded AIG subgraphs\n" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -12780,18 +12967,19 @@ usage:
SeeAlso []
***********************************************************************/
-int Abc_CommandRecPs2( Abc_Frame_t * pAbc, int argc, char ** argv )
+int Abc_CommandRecAdd2( Abc_Frame_t * pAbc, int argc, char ** argv )
{
-// Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
- int c, fPrintLib = 0;
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
+ int c;
+ int fUseSOPB = 0;
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ph" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "gh" ) ) != EOF )
{
switch ( c )
{
- case 'p':
- fPrintLib ^= 1;
+ case 'g':
+ fUseSOPB = 1;
break;
case 'h':
goto usage;
@@ -12799,17 +12987,22 @@ int Abc_CommandRecPs2( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ Abc_Print( -1, "This command works for AIGs.\n" );
+ return 0;
+ }
if ( !Abc_NtkRecIsRunning2() )
{
- Abc_Print( -1, "This command works for AIGs only after calling \"rec_start2\".\n" );
+ Abc_Print( -1, "This command works for AIGs after calling \"rec_start2\".\n" );
return 0;
}
- Abc_NtkRecPs2(fPrintLib);
+ Abc_NtkRecAdd2( pNtk, fUseSOPB);
return 0;
usage:
- Abc_Print( -2, "usage: rec_ps2 [-h]\n" );
- Abc_Print( -2, "\t prints statistics about the recorded AIG subgraphs\n" );
+ Abc_Print( -2, "usage: rec_add2 [-h]\n" );
+ Abc_Print( -2, "\t adds subgraphs from the current network to the set\n" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -13018,6 +13211,405 @@ usage:
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRecStart3( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ char * FileName, * pTemp;
+ char ** pArgvNew;
+ int c, nArgcNew;
+ FILE * pFile;
+ Gia_Man_t * pGia = NULL;
+ int nVars = 6;
+ int nCuts = 32;
+ int fFuncOnly = 0;
+ int fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KCfvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nVars = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nVars < 1 )
+ goto usage;
+ break;
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nCuts = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nCuts < 1 )
+ goto usage;
+ break;
+ case 'f':
+ fFuncOnly ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( !(nVars >= 3 && nVars <= 16) )
+ {
+ Abc_Print( -1, "The range of allowed values is 3 <= K <= 16.\n" );
+ return 0;
+ }
+ if ( Abc_NtkRecIsRunning3() )
+ {
+ Abc_Print( -1, "The AIG subgraph recording is already started.\n" );
+ return 0;
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 1 )
+ Abc_Print( 1, "File name is not given on the command line. Starting a new record.\n" );
+ else
+ {
+ // get the input file name
+ FileName = pArgvNew[0];
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGia = Gia_ReadAiger( FileName, 1, 0 );
+ if ( pGia == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ }
+ Abc_NtkRecStart3( pGia, nVars, nCuts, fFuncOnly, fVerbose );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: rec_start3 [-K num] [-C num] [-fvh] <file>\n" );
+ Abc_Print( -2, "\t starts recording AIG subgraphs (should be called for\n" );
+ Abc_Print( -2, "\t an empty network or after reading in a previous record)\n" );
+ Abc_Print( -2, "\t-K num : the largest number of inputs [default = %d]\n", nVars );
+ Abc_Print( -2, "\t-C num : the max number of cuts used at a node (0 < num < 2^12) [default = %d]\n", nCuts );
+ Abc_Print( -2, "\t-f : toggles recording functions without AIG subgraphs [default = %s]\n", fFuncOnly? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggles additional verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<file> : AIGER file with the library\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRecStop3( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ int c;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( !Abc_NtkRecIsRunning3() )
+ {
+ Abc_Print( -1, "This command works only after calling \"rec_start3\".\n" );
+ return 0;
+ }
+ Abc_NtkRecStop3();
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: rec_stop3 [-h]\n" );
+ Abc_Print( -2, "\t cleans the internal storage for AIG subgraphs\n" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRecPs3( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ int c, fPrintLib = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ph" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'p':
+ fPrintLib ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( !Abc_NtkRecIsRunning3() )
+ {
+ Abc_Print( -1, "This command works for AIGs only after calling \"rec_start2\".\n" );
+ return 0;
+ }
+ Abc_NtkRecPs3(fPrintLib);
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: rec_ps3 [-h]\n" );
+ Abc_Print( -2, "\t prints statistics about the recorded AIG subgraphs\n" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRecAdd3( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
+ int c;
+ int fUseSOPB = 0;
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "gh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'g':
+ fUseSOPB = 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ Abc_Print( -1, "This command works for AIGs.\n" );
+ return 0;
+ }
+ if ( !Abc_NtkRecIsRunning3() )
+ {
+ Abc_Print( -1, "This command works for AIGs after calling \"rec_start2\".\n" );
+ return 0;
+ }
+ Abc_NtkRecAdd3( pNtk, fUseSOPB );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: rec_add3 [-h]\n" );
+ Abc_Print( -2, "\t adds subgraphs from the current network to the set\n" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRecDump3( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ char * FileName;
+ char ** pArgvNew;
+ int nArgcNew;
+ Gia_Man_t * pGia;
+ int c;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( !Abc_NtkRecIsRunning3() )
+ {
+ Abc_Print( -1, "The AIG subgraph recording is not started.\n" );
+ return 1;
+ }
+
+ pGia = Abc_NtkRecGetGia3();
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 1 )
+ {
+ Abc_Print( -1, "File name is not given on the command line.\n" );
+ return 1;
+ }
+ else if( Gia_ManPoNum(pGia) == 0 )
+ {
+ Abc_Print( 0, "No structure in the library.\n" );
+ return 1;
+ }
+ else
+ {
+ // get the input file name
+ FileName = pArgvNew[0];
+ Gia_WriteAiger( pGia, FileName, 0, 0 );
+ }
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: rec_dump3 [-h] <file>\n" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<file> : AIGER file to write the library\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRecMerge3( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ int c;
+ char * FileName, * pTemp;
+ char ** pArgvNew;
+ int nArgcNew;
+ FILE * pFile;
+ Gia_Man_t * pGia = NULL;
+
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( !Abc_NtkRecIsRunning3() )
+ {
+ Abc_Print( -1, "This command works for AIGs only after calling \"rec_start3\".\n" );
+ return 0;
+ }
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 1 )
+ {
+ Abc_Print( -1, "File name is not given on the command line.\n" );
+ return 1;
+ }
+ else
+ {
+ // get the input file name
+ FileName = pArgvNew[0];
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pGia = Gia_ReadAiger( FileName, 1, 0 );
+ if ( pGia == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ }
+ Abc_NtkRecLibMerge3(pGia);
+ Gia_ManStop( pGia );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: rec_merge3 [-h] <file>\n" );
+ Abc_Print( -2, "\t merge libraries\n" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<file> : AIGER file with the library\n");
+ return 1;
+}
+
+
/**Function*************************************************************
Synopsis []
@@ -13052,7 +13644,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
DelayMulti = 0;
fAreaOnly = 0;
fRecovery = 1;
- fSweep = 1;
+ fSweep = 0;
fSwitching = 0;
fVerbose = 0;
Extra_UtilGetoptReset();
@@ -14392,7 +14984,7 @@ usage:
Abc_Print( -2, "\t-d : toggles deriving local AIGs using bi-decomposition [default = %s]\n", pPars->fBidec? "yes": "no" );
Abc_Print( -2, "\t-b : toggles the use of one special feature [default = %s]\n", pPars->fUseBat? "yes": "no" );
Abc_Print( -2, "\t-u : toggles the use of MUXes along with LUTs [default = %s]\n", fLutMux? "yes": "no" );
- Abc_Print( -2, "\t-g : toggles global delay optimization [default = %s]\n", pPars->fDelayOpt? "yes": "no" );
+ Abc_Print( -2, "\t-g : toggles delay optimization by SOP balancing [default = %s]\n", pPars->fDelayOpt? "yes": "no" );
Abc_Print( -2, "\t-y : toggles delay optimization with recorded library [default = %s]\n", pPars->fUserRecLib? "yes": "no" );
Abc_Print( -2, "\t-o : toggles using buffers to decouple combinational outputs [default = %s]\n", pPars->fUseBuffs? "yes": "no" );
Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" );
@@ -16004,7 +16596,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
Ssw_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLSIVMNcmplkofdsevwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLSIVMNcmplkofdseqvwh" ) ) != EOF )
{
switch ( c )
{
@@ -16148,6 +16740,9 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'e':
pPars->fEquivDump ^= 1;
break;
+ case 'q':
+ pPars->fStopWhenGone ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -16214,7 +16809,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: scorr [-PQFCLSIVMN <num>] [-cmplkodsevwh]\n" );
+ Abc_Print( -2, "usage: scorr [-PQFCLSIVMN <num>] [-cmplkodseqvwh]\n" );
Abc_Print( -2, "\t performs sequential sweep using K-step induction\n" );
Abc_Print( -2, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize );
Abc_Print( -2, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize );
@@ -16237,6 +16832,7 @@ usage:
Abc_Print( -2, "\t-d : toggle dynamic addition of constraints [default = %s]\n", pPars->fDynamic? "yes": "no" );
Abc_Print( -2, "\t-s : toggle local simulation in the cone of influence [default = %s]\n", pPars->fLocalSim? "yes": "no" );
Abc_Print( -2, "\t-e : toggle dumping disproved internal equivalences [default = %s]\n", pPars->fEquivDump? "yes": "no" );
+ Abc_Print( -2, "\t-q : toggle quitting when PO is not a constant candidate [default = %s]\n", pPars->fStopWhenGone? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printout of flop equivalences [default = %s]\n", pPars->fFlopVerbose? "yes": "no" );
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -22697,7 +23293,12 @@ int Abc_CommandAbc9Put( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Empty network.\n" );
return 1;
}
- if ( Gia_ManHasDangling(pAbc->pGia) == 0 )
+ if ( pAbc->pGia->pMapping )
+ {
+ extern Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p );
+ pNtk = Abc_NtkFromMappedGia( pAbc->pGia );
+ }
+ else if ( Gia_ManHasDangling(pAbc->pGia) == 0 )
{
pMan = Gia_ManToAig( pAbc->pGia, 0 );
pNtk = Abc_NtkFromAigPhase( pMan );
@@ -25098,7 +25699,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
Cec_ManCorSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "FCPkrecwvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "FCPkrecqwvh" ) ) != EOF )
{
switch ( c )
{
@@ -25147,6 +25748,9 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'c':
pPars->fUseCSat ^= 1;
break;
+ case 'q':
+ pPars->fStopWhenGone ^= 1;
+ break;
case 'w':
pPars->fVerboseFlops ^= 1;
break;
@@ -25172,7 +25776,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &scorr [-FCP num] [-krecwvh]\n" );
+ Abc_Print( -2, "usage: &scorr [-FCP num] [-krecqwvh]\n" );
Abc_Print( -2, "\t performs signal correpondence computation\n" );
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames );
@@ -25181,6 +25785,7 @@ usage:
Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" );
Abc_Print( -2, "\t-e : toggle using equivalences as choices [default = %s]\n", pPars->fMakeChoices? "yes": "no" );
Abc_Print( -2, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" );
+ Abc_Print( -2, "\t-q : toggle quitting when PO is not a constant candidate [default = %s]\n", pPars->fStopWhenGone? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing verbose info about equivalent flops [default = %s]\n", pPars->fVerboseFlops? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -26210,20 +26815,18 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
{
char Buffer[200];
char LutSize[200];
+ Gia_Man_t * pNew;
If_Par_t Pars, * pPars = &Pars;
int c;
- extern void Gia_ManSetIfParsDefault( If_Par_t * pPars );
- extern int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars );
// set defaults
Gia_ManSetIfParsDefault( pPars );
-// if ( pAbc->pAbc8Lib == NULL )
-// {
-// Abc_Print( -1, "LUT library is not given. Using default LUT library.\n" );
-// pAbc->pAbc8Lib = If_SetSimpleLutLib( 6 );
-// }
-// pPars->pLutLib = pAbc->pAbc8Lib;
+ if ( pAbc->pLibLut == NULL )
+ {
+ Abc_Print( -1, "LUT library is not given. Using default LUT library.\n" );
+ pAbc->pLibLut = If_SetSimpleLutLib( 6 );
+ }
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "KCFADEqaflepmrsdbvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGDEWSqaflepmrsdbgyojikcvh" ) ) != EOF )
{
switch ( c )
{
@@ -26273,6 +26876,17 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nAreaIters < 0 )
goto usage;
break;
+ case 'G':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer no less than 3.\n" );
+ goto usage;
+ }
+ pPars->nGateSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nGateSize < 2 )
+ goto usage;
+ break;
case 'D':
if ( globalUtilOptind >= argc )
{
@@ -26295,6 +26909,31 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->Epsilon < 0.0 || pPars->Epsilon > 1.0 )
goto usage;
break;
+ case 'W':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-W\" should be followed by a floating point number.\n" );
+ goto usage;
+ }
+ pPars->WireDelay = (float)atof(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->WireDelay < 0.0 )
+ goto usage;
+ break;
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by string.\n" );
+ goto usage;
+ }
+ pPars->pLutStruct = argv[globalUtilOptind];
+ globalUtilOptind++;
+ if ( strlen(pPars->pLutStruct) != 2 && strlen(pPars->pLutStruct) != 3 )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by a 2- or 3-char string (e.g. \"44\" or \"555\").\n" );
+ goto usage;
+ }
+ break;
case 'q':
pPars->fPreprocess ^= 1;
break;
@@ -26328,6 +26967,27 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'b':
pPars->fUseBat ^= 1;
break;
+ case 'g':
+ pPars->fDelayOpt ^= 1;
+ break;
+ case 'y':
+ pPars->fUserRecLib ^= 1;
+ break;
+ case 'o':
+ pPars->fUseBuffs ^= 1;
+ break;
+ case 'j':
+ pPars->fEnableCheck07 ^= 1;
+ break;
+ case 'i':
+ pPars->fEnableCheck08 ^= 1;
+ break;
+ case 'k':
+ pPars->fEnableCheck10 ^= 1;
+ break;
+ case 'c':
+ pPars->fEnableRealPos ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -26336,12 +26996,27 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+
if ( pAbc->pGia == NULL )
{
- Abc_Print( -1, "Abc_CommandAbc9If(): There is no AIG to map.\n" );
+ Abc_Print( -1, "Empty GIA network.\n" );
return 1;
}
+ if ( pPars->nLutSize == -1 )
+ {
+ if ( pPars->pLutLib == NULL )
+ {
+ Abc_Print( -1, "The LUT library is not given.\n" );
+ return 1;
+ }
+ // get LUT size from the library
+ pPars->nLutSize = pPars->pLutLib->LutMax;
+ // if variable pin delay, force truth table computation
+// if ( pPars->pLutLib->fVarPinDelays )
+// pPars->fTruth = 1;
+ }
+
if ( pPars->nLutSize < 3 || pPars->nLutSize > IF_MAX_LUTSIZE )
{
Abc_Print( -1, "Incorrect LUT size (%d).\n", pPars->nLutSize );
@@ -26355,9 +27030,10 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// enable truth table computation if choices are selected
- if ( (c = Gia_ManCountChoiceNodes( pAbc->pGia )) )
+ if ( Gia_ManHasChoices(pAbc->pGia) )
{
- Abc_Print( 0, "Performing LUT mapping with %d choices.\n", c );
+ if ( !Abc_FrameReadFlag("silentmode") )
+ Abc_Print( 0, "Performing LUT mapping with choices.\n" );
pPars->fExpRed = 0;
}
@@ -26371,12 +27047,86 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->fCutMin = 1;
}
+ if ( pPars->fEnableCheck07 + pPars->fEnableCheck08 + pPars->fEnableCheck10 + (pPars->pLutStruct != NULL) > 1 )
+ {
+ Abc_Print( -1, "Only one additional check can be performed at the same time.\n" );
+ return 1;
+ }
+ if ( pPars->fEnableCheck07 )
+ {
+ if ( pPars->nLutSize < 6 || pPars->nLutSize > 7 )
+ {
+ Abc_Print( -1, "This feature only works for {6,7}-LUTs.\n" );
+ return 1;
+ }
+ pPars->pFuncCell = If_CutPerformCheck07;
+ pPars->fCutMin = 1;
+ }
+ if ( pPars->fEnableCheck08 )
+ {
+ if ( pPars->nLutSize < 6 || pPars->nLutSize > 8 )
+ {
+ Abc_Print( -1, "This feature only works for {6,7,8}-LUTs.\n" );
+ return 1;
+ }
+ pPars->pFuncCell = If_CutPerformCheck08;
+ pPars->fCutMin = 1;
+ }
+ if ( pPars->fEnableCheck10 )
+ {
+ if ( pPars->nLutSize < 6 || pPars->nLutSize > 10 )
+ {
+ Abc_Print( -1, "This feature only works for {6,7,8,9,10}-LUTs.\n" );
+ return 1;
+ }
+ pPars->pFuncCell = If_CutPerformCheck10;
+ pPars->fCutMin = 1;
+ }
+ if ( pPars->pLutStruct )
+ {
+ if ( pPars->nLutSize < 6 || pPars->nLutSize > 16 )
+ {
+ Abc_Print( -1, "This feature only works for [6;16]-LUTs.\n" );
+ return 1;
+ }
+ pPars->pFuncCell = If_CutPerformCheck16;
+ pPars->fCutMin = 1;
+ }
+
// enable truth table computation if cut minimization is selected
if ( pPars->fCutMin )
{
pPars->fTruth = 1;
pPars->fExpRed = 0;
}
+ // modify the subgraph recording
+ if ( pPars->fUserRecLib )
+ {
+ pPars->fTruth = 1;
+ pPars->fCutMin = 1;
+ pPars->fExpRed = 0;
+ pPars->fUsePerm = 1;
+ pPars->pLutLib = NULL;
+ }
+ // modify for global delay optimization
+ if ( pPars->fDelayOpt )
+ {
+ pPars->fTruth = 1;
+ pPars->fCutMin = 1;
+ pPars->fExpRed = 0;
+ pPars->fUsePerm = 1;
+ pPars->pLutLib = NULL;
+ }
+ // modify for global delay optimization
+ if ( pPars->nGateSize > 0 )
+ {
+ pPars->fTruth = 1;
+ pPars->fCutMin = 1;
+ pPars->fExpRed = 0;
+ pPars->fUsePerm = 1;
+ pPars->pLutLib = NULL;
+ pPars->nLutSize = pPars->nGateSize;
+ }
// complain if truth tables are requested but the cut size is too large
if ( pPars->fTruth && pPars->nLutSize > IF_MAX_FUNC_LUTSIZE )
@@ -26385,11 +27135,14 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
- if ( !Gia_MappingIf( pAbc->pGia, pPars ) )
+ // perform mapping
+ pNew = Gia_ManPerformMapping( pAbc->pGia, pPars );
+ if ( pNew == NULL )
{
Abc_Print( -1, "Abc_CommandAbc9If(): Mapping of the AIG has failed.\n" );
return 1;
}
+ Abc_CommandUpdate9( pAbc, pNew );
return 0;
usage:
@@ -26401,14 +27154,17 @@ usage:
sprintf( LutSize, "library" );
else
sprintf( LutSize, "%d", pPars->nLutSize );
- Abc_Print( -2, "usage: &if [-KCFA num] [-DE float] [-qarlepmdbvh]\n" );
+ Abc_Print( -2, "usage: &if [-KCFAG num] [-DEW float] [-S str] [-qarlepmsdbgyojikcvh]\n" );
Abc_Print( -2, "\t performs FPGA technology mapping of the network\n" );
Abc_Print( -2, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize );
Abc_Print( -2, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax );
Abc_Print( -2, "\t-F num : the number of area flow recovery iterations (num >= 0) [default = %d]\n", pPars->nFlowIters );
Abc_Print( -2, "\t-A num : the number of exact area recovery iterations (num >= 0) [default = %d]\n", pPars->nAreaIters );
+ Abc_Print( -2, "\t-G num : the max AND/OR gate size for mapping (0 = unused) [default = %d]\n", pPars->nGateSize );
Abc_Print( -2, "\t-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer );
Abc_Print( -2, "\t-E float : sets epsilon used for tie-breaking [default = %f]\n", pPars->Epsilon );
+ Abc_Print( -2, "\t-W float : sets wire delay between adjects LUTs [default = %f]\n", pPars->WireDelay );
+ Abc_Print( -2, "\t-S str : string representing the LUT structure [default = %s]\n", pPars->pLutStruct ? pPars->pLutStruct : "not used" );
Abc_Print( -2, "\t-q : toggles preprocessing using several starting points [default = %s]\n", pPars->fPreprocess? "yes": "no" );
Abc_Print( -2, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" );
// Abc_Print( -2, "\t-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" );
@@ -26417,9 +27173,16 @@ usage:
Abc_Print( -2, "\t-e : uses edge-based cut selection heuristics [default = %s]\n", pPars->fEdge? "yes": "no" );
Abc_Print( -2, "\t-p : uses power-aware cut selection heuristics [default = %s]\n", pPars->fPower? "yes": "no" );
Abc_Print( -2, "\t-m : enables cut minimization by removing vacuous variables [default = %s]\n", pPars->fCutMin? "yes": "no" );
-// Abc_Print( -2, "\t-s : toggles sequential mapping [default = %s]\n", pPars->fSeqMap? "yes": "no" );
+ Abc_Print( -2, "\t-s : toggles sequential mapping [default = %s]\n", pPars->fSeqMap? "yes": "no" );
Abc_Print( -2, "\t-d : toggles deriving local AIGs using bi-decomposition [default = %s]\n", pPars->fBidec? "yes": "no" );
Abc_Print( -2, "\t-b : toggles the use of one special feature [default = %s]\n", pPars->fUseBat? "yes": "no" );
+ Abc_Print( -2, "\t-g : toggles delay optimization by SOP balancing [default = %s]\n", pPars->fDelayOpt? "yes": "no" );
+ Abc_Print( -2, "\t-y : toggles delay optimization with recorded library [default = %s]\n", pPars->fUserRecLib? "yes": "no" );
+ Abc_Print( -2, "\t-o : toggles using buffers to decouple combinational outputs [default = %s]\n", pPars->fUseBuffs? "yes": "no" );
+ Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" );
+ Abc_Print( -2, "\t-i : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck08? "yes": "no" );
+ Abc_Print( -2, "\t-k : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck10? "yes": "no" );
+ Abc_Print( -2, "\t-c : toggles enabling additional feature [default = %s]\n", pPars->fEnableRealPos? "yes": "no" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : prints the command usage\n");
return 1;
diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c
index 6072a9db..dbb75f59 100644
--- a/src/base/abci/abcDar.c
+++ b/src/base/abci/abcDar.c
@@ -620,6 +620,150 @@ Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan )
return pNtkNew;
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates local function of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Hop_Obj_t * Abc_ObjHopFromGia_rec( Hop_Man_t * pHopMan, Gia_Man_t * p, int Id, Vec_Ptr_t * vCopies )
+{
+ Gia_Obj_t * pObj;
+ Hop_Obj_t * gFunc, * gFunc0, * gFunc1;
+ if ( Gia_ObjIsTravIdCurrentId(p, Id) )
+ return (Hop_Obj_t *)Vec_PtrEntry( vCopies, Id );
+ Gia_ObjSetTravIdCurrentId(p, Id);
+ pObj = Gia_ManObj(p, Id);
+ assert( Gia_ObjIsAnd(pObj) );
+ // compute the functions of the children
+ gFunc0 = Abc_ObjHopFromGia_rec( pHopMan, p, Gia_ObjFaninId0(pObj, Id), vCopies );
+ gFunc1 = Abc_ObjHopFromGia_rec( pHopMan, p, Gia_ObjFaninId1(pObj, Id), vCopies );
+ // get the function of the cut
+ gFunc = Hop_And( pHopMan, Hop_NotCond(gFunc0, Gia_ObjFaninC0(pObj)), Hop_NotCond(gFunc1, Gia_ObjFaninC1(pObj)) );
+ Vec_PtrWriteEntry( vCopies, Id, gFunc );
+ return gFunc;
+}
+Hop_Obj_t * Abc_ObjHopFromGia( Hop_Man_t * pHopMan, Gia_Man_t * p, int GiaId, Vec_Ptr_t * vCopies )
+{
+ int k, iFan;
+ assert( Gia_ObjIsLut(p, GiaId) );
+ assert( Gia_ObjLutSize(p, GiaId) > 0 );
+ Gia_ManIncrementTravId( p );
+ Gia_LutForEachFanin( p, GiaId, iFan, k )
+ {
+ Gia_ObjSetTravIdCurrentId(p, iFan);
+ Vec_PtrWriteEntry( vCopies, iFan, Hop_IthVar(pHopMan, k) );
+ }
+ return Abc_ObjHopFromGia_rec( pHopMan, p, GiaId, vCopies );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the network from the mapped GIA manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p )
+{
+ int fVerbose = 0;
+ int fDuplicate = 0;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObjNew, * pObjNewLi, * pObjNewLo, * pConst0 = NULL;
+ Gia_Obj_t * pObj, * pObjLi, * pObjLo;
+ Vec_Ptr_t * vReflect;
+ int i, k, iFan, nDupGates;
+ assert( p->pMapping != NULL );
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_AIG, 1 );
+ // duplicate the name and the spec
+ pNtkNew->pName = Extra_UtilStrsav(p->pName);
+ pNtkNew->pSpec = Extra_UtilStrsav(p->pSpec);
+ Gia_ManFillValue( p );
+ // create constant
+ pConst0 = Abc_NtkCreateNodeConst0( pNtkNew );
+ Gia_ManConst0(p)->Value = Abc_ObjId(pConst0);
+ // create PIs
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = Abc_ObjId( Abc_NtkCreatePi( pNtkNew ) );
+ // create POs
+ Gia_ManForEachPo( p, pObj, i )
+ pObj->Value = Abc_ObjId( Abc_NtkCreatePo( pNtkNew ) );
+ // create as many latches as there are registers in the manager
+ Gia_ManForEachRiRo( p, pObjLi, pObjLo, i )
+ {
+ pObjNew = Abc_NtkCreateLatch( pNtkNew );
+ pObjNewLi = Abc_NtkCreateBi( pNtkNew );
+ pObjNewLo = Abc_NtkCreateBo( pNtkNew );
+ Abc_ObjAddFanin( pObjNew, pObjNewLi );
+ Abc_ObjAddFanin( pObjNewLo, pObjNew );
+ pObjLi->Value = Abc_ObjId( pObjNewLi );
+ pObjLo->Value = Abc_ObjId( pObjNewLo );
+ Abc_LatchSetInit0( pObjNew );
+ }
+ // rebuild the AIG
+ vReflect = Vec_PtrStart( Gia_ManObjNum(p) );
+ Gia_ManForEachLut( p, i )
+ {
+ pObj = Gia_ManObj(p, i);
+ assert( pObj->Value == ~0 );
+ if ( Gia_ObjLutSize(p, i) == 0 )
+ {
+ pObj->Value = Abc_ObjId(pConst0);
+ continue;
+ }
+ pObjNew = Abc_NtkCreateNode( pNtkNew );
+ Gia_LutForEachFanin( p, i, iFan, k )
+ Abc_ObjAddFanin( pObjNew, Abc_NtkObj(pNtkNew, Gia_ObjValue(Gia_ManObj(p, iFan))) );
+ pObjNew->pData = Abc_ObjHopFromGia( pNtkNew->pManFunc, p, i, vReflect );
+ pObj->Value = Abc_ObjId( pObjNew );
+ }
+ Vec_PtrFree( vReflect );
+ // connect the PO nodes
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ pObjNew = Abc_NtkObj( pNtkNew, Gia_ObjValue(Gia_ObjFanin0(pObj)) );
+ Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), Abc_ObjNotCond( pObjNew, Gia_ObjFaninC0(pObj) ) );
+ }
+ // create names
+ Abc_NtkAddDummyPiNames( pNtkNew );
+ Abc_NtkAddDummyPoNames( pNtkNew );
+ Abc_NtkAddDummyBoxNames( pNtkNew );
+
+ // decouple the PO driver nodes to reduce the number of levels
+ nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, fDuplicate );
+ if ( fVerbose && nDupGates && !Abc_FrameReadFlag("silentmode") )
+ {
+ if ( !fDuplicate )
+ printf( "Added %d buffers/inverters to decouple the CO drivers.\n", nDupGates );
+ else
+ printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
+ }
+ // remove const node if it is not used
+ if ( Abc_ObjFanoutNum(pConst0) == 0 )
+ Abc_NtkDeleteObj( pConst0 );
+
+ assert( Gia_ManPiNum(p) == Abc_NtkPiNum(pNtkNew) );
+ assert( Gia_ManPoNum(p) == Abc_NtkPoNum(pNtkNew) );
+ assert( Gia_ManRegNum(p) == Abc_NtkLatchNum(pNtkNew) );
+
+ // check the resulting AIG
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ Abc_Print( 1, "Abc_NtkFromMappedGia(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+
/**Function*************************************************************
Synopsis [Converts the network from the AIG manager into ABC.]
diff --git a/src/base/abci/abcDec.c b/src/base/abci/abcDec.c
index 309c6a50..f5dce96e 100644
--- a/src/base/abci/abcDec.c
+++ b/src/base/abci/abcDec.c
@@ -353,10 +353,10 @@ void Abc_TruthStoreRead( char * pFileName, Abc_TtStore_t * p )
SeeAlso []
***********************************************************************/
-void Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p )
+void Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p, int fBinary )
{
FILE * pFile;
- int i;
+ int i, nBytes = 8 * Abc_Truth6WordNum( p->nVars );
pFile = fopen( pFileName, "wb" );
if ( pFile == NULL )
{
@@ -365,8 +365,10 @@ void Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p )
}
for ( i = 0; i < p->nFuncs; i++ )
{
- Abc_TruthWriteHex( pFile, p->pFuncs[i], p->nVars );
- fprintf( pFile, "\n" );
+ if ( fBinary )
+ fwrite( p->pFuncs[i], nBytes, 1, pFile );
+ else
+ Abc_TruthWriteHex( pFile, p->pFuncs[i], p->nVars ), fprintf( pFile, "\n" );
}
fclose( pFile );
}
@@ -441,7 +443,7 @@ void Abc_TtStoreTest( char * pFileName )
return;
// write into another file
- Abc_TtStoreWrite( pFileOutput, p );
+ Abc_TtStoreWrite( pFileOutput, p, 0 );
// delete data-structure
Abc_TtStoreFree( p, -1 );
@@ -471,6 +473,8 @@ void Abc_TruthDecPerform( Abc_TtStore_t * p, int DecType, int fVerbose )
pAlgoName = "bi-decomp";
else if ( DecType == 3 )
pAlgoName = "DSD";
+ else if ( DecType == 4 )
+ pAlgoName = "fast DSD";
if ( pAlgoName )
printf( "Applying %-10s to %8d func%s of %2d vars... ",
@@ -535,6 +539,24 @@ void Abc_TruthDecPerform( Abc_TtStore_t * p, int DecType, int fVerbose )
Kit_DsdNtkFree( pNtk );
}
}
+ else if ( DecType == 4 )
+ {
+ extern void Dau_DsdTestOne( word t, int i );
+ if ( p->nVars != 6 )
+ {
+ printf( "Currently only works for 6 variables.\n" );
+ return;
+ }
+ // perform disjoint-support decomposition and count AIG nodes
+ // (non-DSD blocks are decomposed into 2:1 MUXes, each counting as 3 AIG nodes)
+ assert( p->nVars == 6 );
+ for ( i = 0; i < p->nFuncs; i++ )
+ {
+ if ( fVerbose )
+ printf( "%7d : ", i );
+ Dau_DsdTestOne( *p->pFuncs[i], i );
+ }
+ }
else assert( 0 );
printf( "AIG nodes =%9d ", nNodes );
@@ -585,7 +607,7 @@ int Abc_DecTest( char * pFileName, int DecType, int nVarNum, int fVerbose )
printf( "Using truth tables from file \"%s\"...\n", pFileName );
if ( DecType == 0 )
{ if ( nVarNum < 0 ) Abc_TtStoreTest( pFileName ); }
- else if ( DecType >= 1 && DecType <= 3 )
+ else if ( DecType >= 1 && DecType <= 4 )
Abc_TruthDecTest( pFileName, DecType, nVarNum, fVerbose );
else
printf( "Unknown decomposition type value (%d).\n", DecType );
diff --git a/src/base/abci/abcIf.c b/src/base/abci/abcIf.c
index 362f0e46..76171eee 100644
--- a/src/base/abci/abcIf.c
+++ b/src/base/abci/abcIf.c
@@ -228,7 +228,6 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
// set up the choice node
if ( Abc_AigNodeIsChoice( pNode ) )
{
- pIfMan->nChoices++;
for ( pPrev = pNode, pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pPrev = pFanin, pFanin = (Abc_Obj_t *)pFanin->pData )
If_ObjSetChoice( (If_Obj_t *)pPrev->pCopy, (If_Obj_t *)pFanin->pCopy );
If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pCopy );
@@ -495,10 +494,13 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
{
extern Hop_Obj_t * Abc_RecToHop( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj );
extern Hop_Obj_t * Abc_RecToHop2( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj );
- if(Abc_NtkRecIsRunning())
- pNodeNew->pData = Abc_RecToHop( (Hop_Man_t *)pNtkNew->pManFunc, pIfMan, pCutBest, pIfObj);
- else
+ extern Hop_Obj_t * Abc_RecToHop3( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj );
+ if(Abc_NtkRecIsRunning3())
+ pNodeNew->pData = Abc_RecToHop3( (Hop_Man_t *)pNtkNew->pManFunc, pIfMan, pCutBest, pIfObj);
+ else if(Abc_NtkRecIsRunning2())
pNodeNew->pData = Abc_RecToHop2( (Hop_Man_t *)pNtkNew->pManFunc, pIfMan, pCutBest, pIfObj);
+ else
+ pNodeNew->pData = Abc_RecToHop( (Hop_Man_t *)pNtkNew->pManFunc, pIfMan, pCutBest, pIfObj);
}
else
diff --git a/src/base/abci/abcNpn.c b/src/base/abci/abcNpn.c
index 9494cba2..0e3f41f9 100644
--- a/src/base/abci/abcNpn.c
+++ b/src/base/abci/abcNpn.c
@@ -49,7 +49,7 @@ struct Abc_TtStore_t_
extern Abc_TtStore_t * Abc_TtStoreLoad( char * pFileName, int nVarNum );
extern void Abc_TtStoreFree( Abc_TtStore_t * p, int nVarNum );
-extern void Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p );
+extern void Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p, int fBinary );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -276,7 +276,7 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
SeeAlso []
***********************************************************************/
-void Abc_TruthNpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int fVerbose )
+void Abc_TruthNpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int fBinary, int fVerbose )
{
Abc_TtStore_t * p;
char * pFileNameOut;
@@ -292,8 +292,11 @@ void Abc_TruthNpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes,
// write the result
if ( fDumpRes )
{
- pFileNameOut = Extra_FileNameGenericAppend( pFileName, "_out.txt" );
- Abc_TtStoreWrite( pFileNameOut, p );
+ if ( fBinary )
+ pFileNameOut = Extra_FileNameGenericAppend( pFileName, "_out.tt" );
+ else
+ pFileNameOut = Extra_FileNameGenericAppend( pFileName, "_out.txt" );
+ Abc_TtStoreWrite( pFileNameOut, p, fBinary );
if ( fVerbose )
printf( "The resulting functions are written into file \"%s\".\n", pFileNameOut );
}
@@ -315,12 +318,12 @@ void Abc_TruthNpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes,
SeeAlso []
***********************************************************************/
-int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int fVerbose )
+int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int fBinary, int fVerbose )
{
if ( fVerbose )
printf( "Using truth tables from file \"%s\"...\n", pFileName );
if ( NpnType >= 0 && NpnType <= 4 )
- Abc_TruthNpnTest( pFileName, NpnType, nVarNum, fDumpRes, fVerbose );
+ Abc_TruthNpnTest( pFileName, NpnType, nVarNum, fDumpRes, fBinary, fVerbose );
else
printf( "Unknown canonical form value (%d).\n", NpnType );
fflush( stdout );
diff --git a/src/base/abci/abcRec2.c b/src/base/abci/abcRec2.c
index 12e444e8..0eb843bf 100644
--- a/src/base/abci/abcRec2.c
+++ b/src/base/abci/abcRec2.c
@@ -86,6 +86,7 @@ struct Abc_ManRec_t_2
Vec_Ptr_t * vNodes; // the temporary nodes
Vec_Ptr_t * vTtTemps; // the truth tables for the internal nodes of the cut
Vec_Ptr_t * vLabels; // temporary storage for AIG node labels
+ Vec_Int_t * vLabelsInt; // temporary storage for AIG node labels
Vec_Int_t * vUselessPos;
// statistics
int nTried; // the number of cuts tried
@@ -1144,6 +1145,7 @@ p->timeInsert += clock() - timeInsert;
p->vNodes = Vec_PtrAlloc( 100 );
p->vTtTemps = Vec_PtrAllocSimInfo( 1024, p->nWords );
p->vLabels = Vec_PtrStart( 1000 );
+ p->vLabelsInt = Vec_IntStart( 1000 );
p->timeTotal += clock() - clkTotal;
@@ -2065,6 +2067,105 @@ Hop_Obj_t * Abc_RecToHop2( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut,
/**Function*************************************************************
+ Synopsis [Derive the final network from the library.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_RecToGia2( Gia_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj, Vec_Int_t * vLeaves, int fHash )
+{
+ Rec_Obj_t2 * pCandMin;
+ int pHopObj, pFan0, pFan1;
+ Gia_Obj_t* pGiaObj, *pGiaTemp;
+ Gia_Man_t * pAig = s_pMan->pGia;
+ int nLeaves, i;// DelayMin = ABC_INFINITY , Delay = -ABC_INFINITY
+ unsigned uCanonPhase;
+ int nVars = s_pMan->nVars;
+ char pCanonPerm[16];
+ unsigned *pInOut = s_pMan->pTemp1;
+ unsigned *pTemp = s_pMan->pTemp2;
+ int time = clock();
+ int fCompl;
+ int * pCompl = &fCompl;
+ nLeaves = If_CutLeaveNum(pCut);
+// if (nLeaves < 3)
+// return Abc_NodeTruthToHop(pMan, pIfMan, pCut);
+ Kit_TruthCopy(pInOut, If_CutTruth(pCut), pCut->nLimit);
+ //special cases when cut-minimization return 2, that means there is only one leaf in the cut.
+ if ((Kit_TruthIsConst0(pInOut, nLeaves) && pCut->fCompl == 0) || (Kit_TruthIsConst1(pInOut, nLeaves) && pCut->fCompl == 1))
+ return 0;
+ if ((Kit_TruthIsConst0(pInOut, nLeaves) && pCut->fCompl == 1) || (Kit_TruthIsConst1(pInOut, nLeaves) && pCut->fCompl == 0))
+ return 1;
+ if (Kit_TruthSupport(pInOut, nLeaves) != Kit_BitMask(nLeaves))
+ {
+ for (i = 0; i < nLeaves; i++)
+ if(Kit_TruthVarInSupport( pInOut, nLeaves, i ))
+ return Abc_LitNotCond( Vec_IntEntry(vLeaves, i), (pCut->fCompl ^ ((*pInOut & 0x01) > 0)) );
+ }
+
+ for (i = 0; i < nLeaves; i++)
+ pCanonPerm[i] = i;
+ uCanonPhase = Kit_TruthSemiCanonicize_new(pInOut, pTemp, nLeaves, pCanonPerm);
+ If_CutTruthStretch(pInOut, nLeaves, nVars);
+ pCandMin = Abc_NtkRecLookUpBest(pIfMan, pCut, pInOut, pCanonPerm, pCompl,NULL);
+
+ // get the top-most GIA node
+ pGiaObj = Abc_NtkRecGetObj( Rec_ObjID(s_pMan, pCandMin) );
+ assert( Gia_ObjIsAnd(pGiaObj) || Gia_ObjIsPi(pAig, pGiaObj) );
+ // collect internal nodes into pAig->vTtNodes
+ if ( pAig->vTtNodes == NULL )
+ pAig->vTtNodes = Vec_IntAlloc( 256 );
+ Gia_ObjCollectInternal( pAig, pGiaObj );
+ // collect HOP nodes for leaves
+ Vec_IntClear( s_pMan->vLabelsInt );
+ for (i = 0; i < nLeaves; i++)
+ {
+ pHopObj = Vec_IntEntry(vLeaves, pCanonPerm[i]);
+ pHopObj = Abc_LitNotCond(pHopObj, ((uCanonPhase & (1 << i)) > 0));
+ Vec_IntPush(s_pMan->vLabelsInt, pHopObj);
+ }
+ // compute HOP nodes for internal nodes
+ Gia_ManForEachObjVec( pAig->vTtNodes, pAig, pGiaTemp, i )
+ {
+ pGiaTemp->fMark0 = 0; // unmark node marked by Gia_ObjCollectInternal()
+
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(pGiaTemp)) )
+ pFan0 = Vec_IntEntry(s_pMan->vLabelsInt, Gia_ObjNum(pAig, Gia_ObjFanin0(pGiaTemp)) + nLeaves);
+ else
+ pFan0 = Vec_IntEntry(s_pMan->vLabelsInt, Gia_ObjCioId(Gia_ObjFanin0(pGiaTemp)));
+ pFan0 = Abc_LitNotCond(pFan0, Gia_ObjFaninC0(pGiaTemp));
+
+ if ( Gia_ObjIsAnd(Gia_ObjFanin1(pGiaTemp)) )
+ pFan1 = Vec_IntEntry(s_pMan->vLabelsInt, Gia_ObjNum(pAig, Gia_ObjFanin1(pGiaTemp)) + nLeaves);
+ else
+ pFan1 = Vec_IntEntry(s_pMan->vLabelsInt, Gia_ObjCioId(Gia_ObjFanin1(pGiaTemp)));
+ pFan1 = Abc_LitNotCond(pFan1, Gia_ObjFaninC1(pGiaTemp));
+
+ if ( fHash )
+ pHopObj = Gia_ManHashAnd(pMan, pFan0, pFan1);
+ else
+ pHopObj = Gia_ManAppendAnd(pMan, pFan0, pFan1);
+ Vec_IntPush(s_pMan->vLabelsInt, pHopObj);
+ }
+ // get the final result
+ if ( Gia_ObjIsAnd(pGiaObj) )
+ pHopObj = Vec_IntEntry(s_pMan->vLabelsInt, Gia_ObjNum(pAig, pGiaObj) + nLeaves);
+ else if ( Gia_ObjIsPi(pAig, pGiaObj) )
+ pHopObj = Vec_IntEntry(s_pMan->vLabelsInt, Gia_ObjCioId(pGiaObj));
+ else assert( 0 );
+
+ s_pMan->timeIfDerive += clock() - time;
+ s_pMan->timeIfTotal += clock() - time;
+ // complement the result if needed
+ return Abc_LitNotCond(pHopObj, (pCut->fCompl)^(((uCanonPhase & (1 << nLeaves)) > 0)) ^ fCompl);
+}
+
+/**Function*************************************************************
+
Synopsis [Returns the given record.]
Description []
@@ -2097,8 +2198,8 @@ void Abc_NtkRecStop2()
ABC_FREE( s_pMan->pTemp2 );
Vec_PtrFree( s_pMan->vNodes );
Vec_PtrFree( s_pMan->vTtTemps );
- if ( s_pMan->vLabels )
- Vec_PtrFree( s_pMan->vLabels );
+ Vec_PtrFree( s_pMan->vLabels );
+ Vec_IntFree( s_pMan->vLabelsInt );
//if(s_pMan->pMemObj)
// Mem_FixedStop(s_pMan->pMemObj, 0);
Vec_IntFree( s_pMan->vUselessPos);
diff --git a/src/base/abci/abcRec3.c b/src/base/abci/abcRec3.c
new file mode 100644
index 00000000..ed6148ab
--- /dev/null
+++ b/src/base/abci/abcRec3.c
@@ -0,0 +1,1097 @@
+/**CFile****************************************************************
+
+ FileName [abcRec2.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Record of semi-canonical AIG subgraphs.]
+
+ Author [Allan Yang, Alan Mishchenko]
+
+ Affiliation [Fudan University in Shanghai, UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcRec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "base/abc/abc.h"
+#include "map/if/if.h"
+#include "bool/kit/kit.h"
+#include "aig/gia/giaAig.h"
+#include "misc/vec/vecMem.h"
+#include "bool/lucky/lucky.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*
+ This LMS manager can be used in two modes:
+ - library constuction
+ - AIG level minimization
+
+ It is not OK to switch from library construction to AIG level minimization
+ without restarting LSM manager. To restart the LSM manager, GIA has to be written out
+ (rec_dump3 <file>.aig) and LMS manager started again (rec_start3 <file>.aig).
+*/
+
+typedef struct Lms_Man_t_ Lms_Man_t;
+struct Lms_Man_t_
+{
+ // parameters
+ int nVars; // the number of variables
+ int nWords; // the number of TT words
+ int nCuts; // the max number of cuts to use
+ int fFuncOnly; // record only functions
+ int fLibConstr; // this manager is used for library construction
+ // internal data for library construction
+ Gia_Man_t * pGia; // the record
+ Vec_Mem_t * vTtMem; // truth table memory and hash table
+ Vec_Int_t * vTruthIds; // truth table IDs of each PO
+ // internal data for AIG level minimization (allocated the first time it is called)
+ Vec_Int_t * vTruthPo; // first PO where this canonicized truth table was seen
+ Vec_Wrd_t * vDelays; // pin-to-pin delays of each PO
+ Vec_Str_t * vAreas; // number of AND gates in each PO
+ Vec_Int_t * vFreqs; // subgraph usage frequencies
+ // temporaries
+ Vec_Ptr_t * vNodes; // the temporary nodes
+ Vec_Ptr_t * vLabelsP; // temporary storage for HOP node labels
+ Vec_Int_t * vLabels; // temporary storage for AIG node labels
+ word pTemp1[1024]; // copy of the truth table
+ word pTemp2[1024]; // copy of the truth table
+ // statistics
+ int nTried;
+ int nFilterSize;
+ int nFilterRedund;
+ int nFilterVolume;
+ int nFilterTruth;
+ int nFilterError;
+ int nFilterSame;
+ int nAdded;
+ int nAddedFuncs;
+ int nHoleInTheWall;
+ // runtime
+ clock_t timeCollect;
+ clock_t timeCanon;
+ clock_t timeBuild;
+ clock_t timeCheck;
+ clock_t timeInsert;
+ clock_t timeOther;
+ clock_t timeTotal;
+};
+
+static Lms_Man_t * s_pMan3 = NULL;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Lms_Man_t * Lms_ManStart( Gia_Man_t * pGia, int nVars, int nCuts, int fFuncOnly, int fVerbose )
+{
+ Lms_Man_t * p;
+ // if GIA is given, use the number of variables from GIA
+ nVars = pGia ? Gia_ManCiNum(pGia) : nVars;
+ assert( nVars >= 6 && nVars <= 16 );
+ // allocate manager
+ p = ABC_CALLOC( Lms_Man_t, 1 );
+ // parameters
+ p->nVars = nVars;
+ p->nCuts = nCuts;
+ p->nWords = Abc_Truth6WordNum( nVars );
+ p->fFuncOnly = fFuncOnly;
+ // internal data for library construction
+ p->vTtMem = Vec_MemAlloc( p->nWords, 12 ); // 32 KB/page for 6-var functions
+ Vec_MemHashAlloc( p->vTtMem, 10000 );
+ p->vTruthIds = Vec_IntAlloc( 10000 );
+ if ( pGia == NULL )
+ {
+ int i;
+ p->pGia = Gia_ManStart( 10000 );
+ p->pGia->pName = Abc_UtilStrsav( "record" );
+ for ( i = 0; i < nVars; i++ )
+ Gia_ManAppendCi( p->pGia );
+ }
+ else
+ {
+ Gia_Obj_t * pObj;
+ unsigned * pTruth;
+ int i, Index, Prev = -1;
+ p->pGia = pGia;
+ // populate the manager with subgraphs present in GIA
+ p->nAdded = Gia_ManCoNum( p->pGia );
+ Gia_ManForEachCo( p->pGia, pObj, i )
+ {
+ pTruth = Gia_ObjComputeTruthTable( p->pGia, pObj );
+ Index = Vec_MemHashInsert( p->vTtMem, (word *)pTruth );
+ assert( Index == Prev || Index == Prev + 1 ); // GIA subgraphs should be ordered
+ Vec_IntPush( p->vTruthIds, Index );
+ Prev = Index;
+ }
+ }
+ // temporaries
+ p->vNodes = Vec_PtrAlloc( 1000 );
+ p->vLabelsP = Vec_PtrAlloc( 1000 );
+ p->vLabels = Vec_IntAlloc( 1000 );
+ return p;
+}
+void Lms_ManStop( Lms_Man_t * p )
+{
+ // temporaries
+ Vec_IntFreeP( &p->vLabels );
+ Vec_PtrFreeP( &p->vLabelsP );
+ Vec_PtrFreeP( &p->vNodes );
+ // internal data for AIG level minimization
+ Vec_IntFreeP( &p->vTruthPo );
+ Vec_WrdFreeP( &p->vDelays );
+ Vec_StrFreeP( &p->vAreas );
+ Vec_IntFreeP( &p->vFreqs );
+ // internal data for library construction
+ Vec_IntFreeP( &p->vTruthIds );
+ Vec_MemHashFree( p->vTtMem );
+ Vec_MemFree( p->vTtMem );
+ Gia_ManStop( p->pGia );
+ ABC_FREE( p );
+}
+void Lms_ManPrint( Lms_Man_t * p )
+{
+// Gia_ManPrintStats( p->pGia, 0, 0 );
+ printf( "Library with %d vars has %d classes and %d AIG subgraphs with %d AND nodes.\n",
+ Gia_ManCiNum(p->pGia), Vec_MemEntryNum(p->vTtMem), p->nAdded, Gia_ManAndNum(p->pGia) );
+
+ p->nAddedFuncs = Vec_MemEntryNum(p->vTtMem);
+ printf( "Subgraphs tried = %10d. (%6.2f %%)\n", p->nTried, !p->nTried? 0 : 100.0*p->nTried/p->nTried );
+ printf( "Subgraphs filtered by support size = %10d. (%6.2f %%)\n", p->nFilterSize, !p->nTried? 0 : 100.0*p->nFilterSize/p->nTried );
+ printf( "Subgraphs filtered by structural redundancy = %10d. (%6.2f %%)\n", p->nFilterRedund, !p->nTried? 0 : 100.0*p->nFilterRedund/p->nTried );
+ printf( "Subgraphs filtered by volume = %10d. (%6.2f %%)\n", p->nFilterVolume, !p->nTried? 0 : 100.0*p->nFilterVolume/p->nTried );
+ printf( "Subgraphs filtered by TT redundancy = %10d. (%6.2f %%)\n", p->nFilterTruth, !p->nTried? 0 : 100.0*p->nFilterTruth/p->nTried );
+ printf( "Subgraphs filtered by error = %10d. (%6.2f %%)\n", p->nFilterError, !p->nTried? 0 : 100.0*p->nFilterError/p->nTried );
+ printf( "Subgraphs filtered by isomorphism = %10d. (%6.2f %%)\n", p->nFilterSame, !p->nTried? 0 : 100.0*p->nFilterSame/p->nTried );
+ printf( "Subgraphs added = %10d. (%6.2f %%)\n", p->nAdded, !p->nTried? 0 : 100.0*p->nAdded/p->nTried );
+ printf( "Functions added = %10d. (%6.2f %%)\n", p->nAddedFuncs, !p->nTried? 0 : 100.0*p->nAddedFuncs/p->nTried );
+ if ( p->nHoleInTheWall )
+ printf( "Cuts whose logic structure has a hole = %10d. (%6.2f %%)\n", p->nHoleInTheWall, !p->nTried? 0 : 100.0*p->nHoleInTheWall/p->nTried );
+
+ p->timeOther = p->timeTotal - p->timeCollect - p->timeCanon - p->timeBuild - p->timeCheck - p->timeInsert;
+ ABC_PRTP( "Runtime: Collect", p->timeCollect, p->timeTotal );
+ ABC_PRTP( "Runtime: Canon ", p->timeCanon, p->timeTotal );
+ ABC_PRTP( "Runtime: Build ", p->timeBuild, p->timeTotal );
+ ABC_PRTP( "Runtime: Check ", p->timeCheck, p->timeTotal );
+ ABC_PRTP( "Runtime: Insert ", p->timeInsert, p->timeTotal );
+ ABC_PRTP( "Runtime: Other ", p->timeOther, p->timeTotal );
+ ABC_PRTP( "Runtime: TOTAL ", p->timeTotal, p->timeTotal );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRecStart3( Gia_Man_t * p, int nVars, int nCuts, int fFuncOnly, int fVerbose )
+{
+ assert( s_pMan3 == NULL );
+ s_pMan3 = Lms_ManStart( p, nVars, nCuts, fFuncOnly, fVerbose );
+}
+
+void Abc_NtkRecStop3()
+{
+ assert( s_pMan3 != NULL );
+ Lms_ManStop( s_pMan3 );
+ s_pMan3 = NULL;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Compute delay/area profiles of POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Lms_DelayGet( word D, int v ) { assert(v >= 0 && v < 16); return (int)((D >> (v << 2)) & 0xF); }
+static inline void Lms_DelaySet( word * pD, int v, int d ) { assert(v >= 0 && v < 16); assert(d >= 0 && d < 16); *pD |= ((word)d << (v << 2)); }
+static inline word Lms_DelayInit( int v ) { assert(v >= 0 && v < 16); return (word)1 << (v << 2); }
+static inline word Lms_DelayMax( word D1, word D2, int nVars )
+{
+ int v, Max;
+ word D = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( (Max = Abc_MaxInt(Lms_DelayGet(D1, v), Lms_DelayGet(D2, v))) )
+ Lms_DelaySet( &D, v, Abc_MinInt(Max + 1, 15) );
+ return D;
+}
+static inline word Lms_DelayDecrement( word D1, int nVars )
+{
+ int v;
+ word D = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( Lms_DelayGet(D1, v) )
+ Lms_DelaySet( &D, v, Lms_DelayGet(D1, v) - 1 );
+ return D;
+}
+static inline int Lms_DelayEqual( word D1, word D2, int nVars ) // returns 1 if D1 has the same delays than D2
+{
+ int v;
+ for ( v = 0; v < nVars; v++ )
+ if ( Lms_DelayGet(D1, v) != Lms_DelayGet(D2, v) )
+ return 0;
+ return 1;
+}
+static inline int Lms_DelayDom( word D1, word D2, int nVars ) // returns 1 if D1 has the same or smaller delays than D2
+{
+ int v;
+ for ( v = 0; v < nVars; v++ )
+ if ( Lms_DelayGet(D1, v) > Lms_DelayGet(D2, v) )
+ return 0;
+ return 1;
+}
+static inline void Lms_DelayPrint( word D, int nVars )
+{
+ int v;
+ printf( "Delay profile = {" );
+ for ( v = 0; v < nVars; v++ )
+ printf( " %d", Lms_DelayGet(D, v) );
+ printf( " }\n" );
+}
+Vec_Wrd_t * Lms_GiaDelays( Gia_Man_t * p )
+{
+ Vec_Wrd_t * vDelays, * vResult;
+ Gia_Obj_t * pObj;
+ int i;
+ // compute delay profiles of all objects
+ vDelays = Vec_WrdAlloc( Gia_ManObjNum(p) );
+ Vec_WrdPush( vDelays, 0 ); // const 0
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_WrdPush( vDelays, Lms_DelayMax( Vec_WrdEntry(vDelays, Gia_ObjFaninId0(pObj, i)), Vec_WrdEntry(vDelays, Gia_ObjFaninId1(pObj, i)), Gia_ManCiNum(p) ) );
+ else if ( Gia_ObjIsCo(pObj) )
+ Vec_WrdPush( vDelays, Lms_DelayDecrement( Vec_WrdEntry(vDelays, Gia_ObjFaninId0(pObj, i)), Gia_ManCiNum(p) ) );
+ else if ( Gia_ObjIsCi(pObj) )
+ Vec_WrdPush( vDelays, Lms_DelayInit( Gia_ObjCioId(pObj) ) );
+ else assert( 0 );
+ }
+ // collect delay profiles of COs only
+ vResult = Vec_WrdAlloc( Gia_ManCoNum(p) );
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_WrdPush( vResult, Vec_WrdEntry(vDelays, Gia_ObjId(p, pObj)) );
+ Vec_WrdFree( vDelays );
+ return vResult;
+}
+void Lms_ObjAreaMark_rec( Gia_Obj_t * pObj )
+{
+ if ( pObj->fMark0 || Gia_ObjIsCi(pObj) )
+ return;
+ pObj->fMark0 = 1;
+ Lms_ObjAreaMark_rec( Gia_ObjFanin0(pObj) );
+ Lms_ObjAreaMark_rec( Gia_ObjFanin1(pObj) );
+}
+int Lms_ObjAreaUnmark_rec( Gia_Obj_t * pObj )
+{
+ if ( !pObj->fMark0 || Gia_ObjIsCi(pObj) )
+ return 0;
+ pObj->fMark0 = 0;
+ return 1 + Lms_ObjAreaUnmark_rec( Gia_ObjFanin0(pObj) )
+ + Lms_ObjAreaUnmark_rec( Gia_ObjFanin1(pObj) );
+}
+int Lms_ObjArea( Gia_Obj_t * pObj )
+{
+ assert( Gia_ObjIsAnd(pObj) );
+ Lms_ObjAreaMark_rec( pObj );
+ return Lms_ObjAreaUnmark_rec( pObj );
+}
+Vec_Str_t * Lms_GiaAreas( Gia_Man_t * p )
+{
+ Vec_Str_t * vAreas;
+ Gia_Obj_t * pObj;
+ int i;
+ vAreas = Vec_StrAlloc( Gia_ManCoNum(p) );
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_StrPush( vAreas, (char)(Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) ? Lms_ObjArea(Gia_ObjFanin0(pObj)) : 0) );
+ return vAreas;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints one GIA subgraph.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Lms_GiaPrintSubgraph_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( !pObj->fMark0 || Gia_ObjIsCi(pObj) )
+ return;
+ pObj->fMark0 = 0;
+ assert( Gia_ObjIsAnd(pObj) );
+ Lms_GiaPrintSubgraph_rec( p, Gia_ObjFanin0(pObj) );
+ Lms_GiaPrintSubgraph_rec( p, Gia_ObjFanin1(pObj) );
+ Gia_ObjPrint( p, pObj );
+}
+void Lms_GiaPrintSubgraph( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ assert( Gia_ObjIsCo(pObj) );
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) )
+ {
+ Lms_ObjAreaMark_rec( Gia_ObjFanin0(pObj) );
+ Lms_GiaPrintSubgraph_rec( p, Gia_ObjFanin0(pObj) );
+ }
+ else
+ Gia_ObjPrint( p, Gia_ObjFanin0(pObj) );
+ Gia_ObjPrint( p, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints delay/area profiles of the GIA subgraphs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Lms_GiaProfilesPrint( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Vec_Wrd_t * vDelays;
+ Vec_Str_t * vAreas;
+ vDelays = Lms_GiaDelays( p );
+ vAreas = Lms_GiaAreas( p );
+
+ Gia_ManForEachPo( p, pObj, i )
+ {
+ printf( "%6d : ", i );
+ printf( "A = %2d ", Vec_StrEntry(vAreas, i) );
+ Lms_DelayPrint( Vec_WrdEntry(vDelays, i), Gia_ManPiNum(p) );
+// Lms_GiaPrintSubgraph( p, pObj );
+// printf( "\n" );
+ }
+
+ Vec_WrdFree( vDelays );
+ Vec_StrFree( vAreas );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute support sizes for each CO.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Str_t * Gia_ManSuppSizes( Gia_Man_t * p )
+{
+ Vec_Str_t * vResult;
+ Vec_Str_t * vSupps;
+ Gia_Obj_t * pObj;
+ int i;
+ vSupps = Vec_StrAlloc( Gia_ManObjNum(p) );
+ Vec_StrPush( vSupps, 0 );
+ Gia_ManForEachObj1( p, pObj, i )
+ {
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_StrPush( vSupps, (char)Abc_MaxInt( Vec_StrEntry(vSupps, Gia_ObjFaninId0(pObj, i)), Vec_StrEntry(vSupps, Gia_ObjFaninId1(pObj, i)) ) );
+ else if ( Gia_ObjIsCo(pObj) )
+ Vec_StrPush( vSupps, Vec_StrEntry(vSupps, Gia_ObjFaninId0(pObj, i)) );
+ else if ( Gia_ObjIsCi(pObj) )
+ Vec_StrPush( vSupps, (char)(Gia_ObjCioId(pObj)+1) );
+ else assert( 0 );
+ }
+ assert( Vec_StrSize(vSupps) == Gia_ManObjNum(p) );
+ vResult = Vec_StrAlloc( Gia_ManCoNum(p) );
+ Gia_ManForEachCo( p, pObj, i )
+ Vec_StrPush( vResult, Vec_StrEntry(vSupps, Gia_ObjId(p, pObj)) );
+ Vec_StrFree( vSupps );
+ return vResult;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Recanonicizes the library and add it to the current library.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRecLibMerge3( Gia_Man_t * pLib )
+{
+ int fCheck = 0;
+ Lms_Man_t * p = s_pMan3;
+ Gia_Man_t * pGia = p->pGia;
+ Vec_Str_t * vSupps;
+ char pCanonPerm[16];
+ unsigned uCanonPhase;
+ unsigned * pTruth;
+ int i, k, Index, iFanin0, iFanin1, nLeaves;
+ Gia_Obj_t * pObjPo, * pDriver, * pTemp = NULL;
+ clock_t clk, clk2 = clock();
+
+ assert( Gia_ManCiNum(pLib) == Gia_ManCiNum(pGia) );
+
+ // create hash table if not available
+ if ( pGia->pHTable == NULL )
+ Gia_ManHashStart( pGia );
+
+ // add AIG subgraphs
+ vSupps = Gia_ManSuppSizes( pLib );
+ Gia_ManForEachCo( pLib, pObjPo, k )
+ {
+ // get support size
+ nLeaves = Vec_StrEntry(vSupps, k);
+ assert( nLeaves > 1 );
+ // compute the truth table
+clk = clock();
+ pTruth = Gia_ObjComputeTruthTable( pLib, Gia_ObjFanin0(pObjPo) );
+p->timeCollect += clock() - clk;
+ // semi-canonicize
+clk = clock();
+ memcpy( p->pTemp1, pTruth, p->nWords * sizeof(word) );
+ // uCanonPhase = luckyCanonicizer_final_fast( p->pTemp1, nLeaves, pCanonPerm );
+ uCanonPhase = Kit_TruthSemiCanonicize( (unsigned *)p->pTemp1, (unsigned *)p->pTemp2, nLeaves, pCanonPerm );
+ Abc_TtStretch5( (unsigned *)p->pTemp1, nLeaves, p->nVars );
+p->timeCanon += clock() - clk;
+ // pCanonPerm and uCanonPhase show what was the variable corresponding to each var in the current truth
+
+clk = clock();
+ // map cut leaves into elementary variables of GIA
+ for ( i = 0; i < nLeaves; i++ )
+ Gia_ManCi( pLib, pCanonPerm[i] )->Value = Abc_Var2Lit( Gia_ObjId(pGia, Gia_ManPi(pGia, i)), (uCanonPhase >> i) & 1 );
+ // build internal nodes
+ assert( Vec_IntSize(pLib->vTtNodes) > 0 );
+ Gia_ManForEachObjVec( pLib->vTtNodes, pLib, pTemp, i )
+ {
+ iFanin0 = Abc_LitNotCond( Gia_ObjFanin0(pTemp)->Value, Gia_ObjFaninC0(pTemp) );
+ iFanin1 = Abc_LitNotCond( Gia_ObjFanin1(pTemp)->Value, Gia_ObjFaninC1(pTemp) );
+ pTemp->Value = Gia_ManHashAnd( pGia, iFanin0, iFanin1 );
+ }
+p->timeBuild += clock() - clk;
+
+ // check if this node is already driving a PO
+ assert( Gia_ObjIsAnd(pTemp) );
+ pDriver = Gia_ManObj(pGia, Abc_Lit2Var(pTemp->Value));
+ if ( pDriver->fMark1 )
+ {
+ p->nFilterSame++;
+ continue;
+ }
+ pDriver->fMark1 = 1;
+ // create output
+ Gia_ManAppendCo( pGia, Abc_LitNotCond( pTemp->Value, (uCanonPhase >> nLeaves) & 1 ) );
+
+ // verify truth table
+ if ( fCheck )
+ {
+clk = clock();
+ pTemp = Gia_ManCo(pGia, Gia_ManCoNum(pGia)-1);
+ pTruth = Gia_ObjComputeTruthTable( pGia, Gia_ManCo(pGia, Gia_ManCoNum(pGia)-1) );
+p->timeCheck += clock() - clk;
+ if ( memcmp( p->pTemp1, pTruth, p->nWords * sizeof(word) ) != 0 )
+ {
+
+ Kit_DsdPrintFromTruth( pTruth, nLeaves ); printf( "\n" );
+ Kit_DsdPrintFromTruth( (unsigned *)p->pTemp1, nLeaves ); printf( "\n" );
+ printf( "Truth table verification has failed.\n" );
+
+ // drive PO with constant
+ Gia_ManPatchCoDriver( pGia, Gia_ManCoNum(pGia)-1, 0 );
+ // save truth table ID
+ Vec_IntPush( p->vTruthIds, -1 );
+ p->nFilterTruth++;
+ continue;
+ }
+ }
+
+clk = clock();
+ // add the resulting truth table to the hash table
+ Index = Vec_MemHashInsert( p->vTtMem, p->pTemp1 );
+ // save truth table ID
+ Vec_IntPush( p->vTruthIds, Index );
+ assert( Gia_ManCoNum(pGia) == Vec_IntSize(p->vTruthIds) );
+ p->nAdded++;
+p->timeInsert += clock() - clk;
+ }
+ Vec_StrFree( vSupps );
+p->timeTotal += clock() - clk2;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Evaluates one cut during library construction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRecAddCut3( If_Man_t * pIfMan, If_Obj_t * pRoot, If_Cut_t * pCut )
+{
+ Lms_Man_t * p = s_pMan3;
+ char pCanonPerm[16];
+ unsigned uCanonPhase;
+ int i, Index, iFanin0, iFanin1, fHole;
+ int nLeaves = If_CutLeaveNum(pCut);
+ Vec_Ptr_t * vNodes = p->vNodes;
+ Gia_Man_t * pGia = p->pGia;
+ Gia_Obj_t * pDriver;
+ If_Obj_t * pIfObj = NULL;
+ unsigned * pTruth;
+ clock_t clk;
+ p->nTried++;
+
+ // skip small cuts
+ assert( p->nVars == (int)pCut->nLimit );
+ if ( nLeaves < 2 )
+ {
+ p->nFilterSize++;
+ return 1;
+ }
+
+ // collect internal nodes and skip redundant cuts
+clk = clock();
+ If_CutTraverse( pIfMan, pRoot, pCut, vNodes );
+p->timeCollect += clock() - clk;
+
+ // semi-canonicize truth table
+clk = clock();
+ memcpy( p->pTemp1, If_CutTruthW(pCut), p->nWords * sizeof(word) );
+// uCanonPhase = luckyCanonicizer_final_fast( p->pTemp1, nLeaves, pCanonPerm );
+ uCanonPhase = Kit_TruthSemiCanonicize( (unsigned *)p->pTemp1, (unsigned *)p->pTemp2, nLeaves, pCanonPerm );
+ Abc_TtStretch5( (unsigned *)p->pTemp1, nLeaves, p->nVars );
+p->timeCanon += clock() - clk;
+ // pCanonPerm and uCanonPhase show what was the variable corresponding to each var in the current truth
+
+clk = clock();
+ // map cut leaves into elementary variables of GIA
+ for ( i = 0; i < nLeaves; i++ )
+ If_ManObj( pIfMan, pCut->pLeaves[(int)pCanonPerm[i]] )->iCopy = Abc_Var2Lit( Gia_ObjId(pGia, Gia_ManPi(pGia, i)), (uCanonPhase >> i) & 1 );
+ // build internal nodes
+ fHole = 0;
+ assert( Vec_PtrSize(vNodes) > 0 );
+ Vec_PtrForEachEntryStart( If_Obj_t *, vNodes, pIfObj, i, nLeaves )
+ {
+ if ( If_ObjIsCi(pIfObj) )
+ {
+ pIfObj->iCopy = 0;
+ fHole = 1;
+ continue;
+ }
+ iFanin0 = Abc_LitNotCond( If_ObjFanin0(pIfObj)->iCopy, If_ObjFaninC0(pIfObj) );
+ iFanin1 = Abc_LitNotCond( If_ObjFanin1(pIfObj)->iCopy, If_ObjFaninC1(pIfObj) );
+ pIfObj->iCopy = Gia_ManHashAnd( pGia, iFanin0, iFanin1 );
+ }
+ p->nHoleInTheWall += fHole;
+p->timeBuild += clock() - clk;
+
+ // check if this node is already driving a PO
+ assert( If_ObjIsAnd(pIfObj) );
+ pDriver = Gia_ManObj(pGia, Abc_Lit2Var(pIfObj->iCopy));
+ if ( pDriver->fMark1 )
+ {
+ p->nFilterSame++;
+ return 1;
+ }
+ pDriver->fMark1 = 1;
+ // create output
+ Gia_ManAppendCo( pGia, Abc_LitNotCond( pIfObj->iCopy, (uCanonPhase >> nLeaves) & 1 ) );
+
+ // verify truth table
+clk = clock();
+ pTruth = Gia_ObjComputeTruthTable( pGia, Gia_ManCo(pGia, Gia_ManCoNum(pGia)-1) );
+p->timeCheck += clock() - clk;
+ if ( memcmp( p->pTemp1, pTruth, p->nWords * sizeof(word) ) != 0 )
+ {
+/*
+ Kit_DsdPrintFromTruth( pTruth, nLeaves ); printf( "\n" );
+ Kit_DsdPrintFromTruth( (unsigned *)p->pTemp1, nLeaves ); printf( "\n" );
+ printf( "Truth table verification has failed.\n" );
+*/
+ // drive PO with constant
+ Gia_ManPatchCoDriver( pGia, Gia_ManCoNum(pGia)-1, 0 );
+ // save truth table ID
+ Vec_IntPush( p->vTruthIds, -1 );
+ p->nFilterTruth++;
+ return 1;
+ }
+
+clk = clock();
+ // add the resulting truth table to the hash table
+ Index = Vec_MemHashInsert( p->vTtMem, p->pTemp1 );
+ // save truth table ID
+ Vec_IntPush( p->vTruthIds, Index );
+ assert( Gia_ManCoNum(pGia) == Vec_IntSize(p->vTruthIds) );
+ p->nAdded++;
+p->timeInsert += clock() - clk;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Top level procedure for library construction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRecAdd3( Abc_Ntk_t * pNtk, int fUseSOPB )
+{
+ extern Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
+ If_Par_t Pars, * pPars = &Pars;
+ Abc_Ntk_t * pNtkNew;
+ int clk = clock();
+ if ( Abc_NtkGetChoiceNum( pNtk ) )
+ printf( "Performing recoding structures with choices.\n" );
+ // remember that the manager was used for library construction
+ s_pMan3->fLibConstr = 1;
+ // create hash table if not available
+ if ( s_pMan3->pGia->pHTable == NULL )
+ Gia_ManHashStart( s_pMan3->pGia );
+
+ // set defaults
+ memset( pPars, 0, sizeof(If_Par_t) );
+ // user-controlable paramters
+ pPars->nLutSize = s_pMan3->nVars;
+ pPars->nCutsMax = s_pMan3->nCuts;
+ pPars->DelayTarget = -1;
+ pPars->Epsilon = (float)0.005;
+ pPars->fArea = 1;
+ // internal parameters
+ if ( fUseSOPB )
+ {
+ pPars->fTruth = 1;
+ pPars->fCutMin = 0;
+ pPars->fUsePerm = 1;
+ pPars->fDelayOpt = 1;
+ }
+ else
+ {
+ pPars->fTruth = 1;
+ pPars->fCutMin = 1;
+ pPars->fUsePerm = 0;
+ pPars->fDelayOpt = 0;
+ }
+ pPars->fSkipCutFilter = 0;
+ pPars->pFuncCost = NULL;
+ pPars->pFuncUser = Abc_NtkRecAddCut3;
+ // perform recording
+ pNtkNew = Abc_NtkIf( pNtk, pPars );
+ Abc_NtkDelete( pNtkNew );
+s_pMan3->timeTotal += clock() - clk;
+}
+
+ /**Function*************************************************************
+
+ Synopsis [Returns min AIG level at the output fo the cut using the library.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int If_CutComputeDelay( If_Man_t * p, If_Cut_t * pCut, char * pCanonPerm, word Delay )
+{
+ If_Obj_t* pLeaf;
+ int nLeaves = If_CutLeaveNum(pCut);
+ int i, delayTemp, delayMax = -ABC_INFINITY;
+ for ( i = 0; i < nLeaves; i++ )
+ {
+ pLeaf = If_ManObj(p, (pCut)->pLeaves[(int)pCanonPerm[i]]);
+ delayTemp = If_ObjCutBest(pLeaf)->Delay + Lms_DelayGet(Delay, i);
+ if(delayTemp > delayMax)
+ delayMax = delayTemp;
+ }
+ return delayMax;
+}
+static inline int If_CutFindBestStruct( If_Man_t * pIfMan, If_Cut_t * pCut, char * pCanonPerm, unsigned * puCanonPhase, int * pBestPo )
+{
+ Lms_Man_t * p = s_pMan3;
+ int i, * pTruthId, iFirstPo, iFirstPoNext, iBestPo;
+ int BestDelay = ABC_INFINITY, BestArea = ABC_INFINITY, Delay, Area;
+ int nLeaves = If_CutLeaveNum( pCut );
+ clock_t clk;
+
+ // semicanonicize the function
+clk = clock();
+ memcpy( p->pTemp1, If_CutTruthW(pCut), p->nWords * sizeof(word) );
+// uCanonPhase = luckyCanonicizer_final_fast( p->pTemp1, nLeaves, pCanonPerm );
+ *puCanonPhase = Kit_TruthSemiCanonicize( (unsigned *)p->pTemp1, (unsigned *)p->pTemp2, nLeaves, pCanonPerm );
+ Abc_TtStretch5( (unsigned *)p->pTemp1, nLeaves, p->nVars );
+p->timeCanon += clock() - clk;
+
+ // get TT ID for the given class
+ pTruthId = Vec_MemHashLookup( p->vTtMem, p->pTemp1 );
+ if ( *pTruthId == -1 )
+ return ABC_INFINITY;
+
+ // note that array p->vTruthPo contains the first PO for the given truth table
+ // other POs belonging to the same equivalence class follow immediately after this one
+ // to iterate through the POs, we need to perform the following steps
+
+ // find the first PO of this class
+ iFirstPo = Vec_IntEntry( p->vTruthPo, *pTruthId );
+ // find the first PO of the next class
+ iFirstPoNext = Vec_IntEntry( p->vTruthPo, *pTruthId+1 );
+ // iterate through the subgraphs of this class
+ iBestPo = -1;
+ for ( i = iFirstPo; i < iFirstPoNext; i++ )
+ {
+ Delay = If_CutComputeDelay( pIfMan, pCut, pCanonPerm, Vec_WrdEntry(p->vDelays, i) );
+ Area = Vec_StrEntry(p->vAreas, i);
+ if ( iBestPo == -1 || BestDelay > Delay || (BestDelay == Delay && BestArea > Area) )
+ {
+ iBestPo = i;
+ BestDelay = Delay;
+ BestArea = Area;
+ }
+ }
+ if ( pBestPo )
+ *pBestPo = iBestPo;
+ return BestDelay;
+}
+int If_CutDelayRecCost3( If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pObj )
+{
+ Lms_Man_t * p = s_pMan3;
+ char pCanonPerm[16];
+ unsigned uCanonPhase;
+ // make sure the cut functions match the library
+ assert( p->nVars == (int)pCut->nLimit );
+ // if this assertion fires, it means that LMS manager was used for library construction
+ // in this case, GIA has to be written out and the manager restarted as described above
+ assert( !p->fLibConstr );
+ if ( p->vTruthPo == NULL ) // the first time AIG level minimization is called
+ {
+ // compute the first PO for each semi-canonical form
+ int i, Entry;
+ p->vTruthPo = Vec_IntStartFull( Vec_MemEntryNum(p->vTtMem)+1 );
+ assert( Vec_IntFindMin(p->vTruthIds) >= 0 );
+ assert( Vec_IntFindMax(p->vTruthIds) < Vec_MemEntryNum(p->vTtMem) );
+ Vec_IntForEachEntry( p->vTruthIds, Entry, i )
+ if ( Vec_IntEntry(p->vTruthPo, Entry) == -1 )
+ Vec_IntWriteEntry( p->vTruthPo, Entry, i );
+ Vec_IntWriteEntry( p->vTruthPo, Vec_MemEntryNum(p->vTtMem), Gia_ManCoNum(p->pGia) );
+ // compute delay/area and init frequency
+ assert( p->vDelays == NULL );
+ assert( p->vAreas == NULL );
+ assert( p->vFreqs == NULL );
+ p->vDelays = Lms_GiaDelays( p->pGia );
+ p->vAreas = Lms_GiaAreas( p->pGia );
+ p->vFreqs = Vec_IntStart( Gia_ManCoNum(p->pGia) );
+ }
+ // return the delay of the best structure
+ return If_CutFindBestStruct( pIfMan, pCut, pCanonPerm, &uCanonPhase, NULL );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reexpresses the best structure of the cut in the HOP manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Hop_Obj_t * Abc_RecToHop3( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj )
+{
+ Lms_Man_t * p = s_pMan3;
+ char pCanonPerm[16];
+ unsigned uCanonPhase;
+ Hop_Obj_t * pFan0, * pFan1, * pHopObj;
+ Gia_Man_t * pGia = p->pGia;
+ Gia_Obj_t * pGiaPo, * pGiaTemp = NULL;
+ int i, BestPo = -1, nLeaves = If_CutLeaveNum(pCut);
+ assert( pIfMan->pPars->fCutMin == 1 );
+ assert( nLeaves > 1 );
+
+ // get the best output for this node
+ If_CutFindBestStruct( pIfMan, pCut, pCanonPerm, &uCanonPhase, &BestPo );
+ assert( BestPo >= 0 );
+ pGiaPo = Gia_ManCo( pGia, BestPo );
+
+ // collect internal nodes into pGia->vTtNodes
+ if ( pGia->vTtNodes == NULL )
+ pGia->vTtNodes = Vec_IntAlloc( 256 );
+ Gia_ObjCollectInternal( pGia, pGiaPo );
+ // collect HOP nodes for leaves
+ Vec_PtrClear( p->vLabelsP );
+ for ( i = 0; i < nLeaves; i++ )
+ {
+ pHopObj = Hop_IthVar( pMan, pCanonPerm[i] );
+ pHopObj = Hop_NotCond( pHopObj, (uCanonPhase >> i) & 1 );
+ Vec_PtrPush(p->vLabelsP, pHopObj);
+ }
+ // compute HOP nodes for internal nodes
+ Gia_ManForEachObjVec( pGia->vTtNodes, pGia, pGiaTemp, i )
+ {
+ pGiaTemp->fMark0 = 0; // unmark node marked by Gia_ObjCollectInternal()
+
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(pGiaTemp)) )
+ pFan0 = (Hop_Obj_t *)Vec_PtrEntry(p->vLabelsP, Gia_ObjNum(pGia, Gia_ObjFanin0(pGiaTemp)) + nLeaves);
+ else
+ pFan0 = (Hop_Obj_t *)Vec_PtrEntry(p->vLabelsP, Gia_ObjCioId(Gia_ObjFanin0(pGiaTemp)));
+ pFan0 = Hop_NotCond(pFan0, Gia_ObjFaninC0(pGiaTemp));
+
+ if ( Gia_ObjIsAnd(Gia_ObjFanin1(pGiaTemp)) )
+ pFan1 = (Hop_Obj_t *)Vec_PtrEntry(p->vLabelsP, Gia_ObjNum(pGia, Gia_ObjFanin1(pGiaTemp)) + nLeaves);
+ else
+ pFan1 = (Hop_Obj_t *)Vec_PtrEntry(p->vLabelsP, Gia_ObjCioId(Gia_ObjFanin1(pGiaTemp)));
+ pFan1 = Hop_NotCond(pFan1, Gia_ObjFaninC1(pGiaTemp));
+
+ pHopObj = Hop_And(pMan, pFan0, pFan1);
+ Vec_PtrPush(p->vLabelsP, pHopObj);
+ }
+ // get the final result
+ assert( Gia_ObjIsAnd(pGiaTemp) );
+ pHopObj = (Hop_Obj_t *)Vec_PtrEntry(p->vLabelsP, Gia_ObjNum(pGia, pGiaTemp) + nLeaves);
+ // complement the result if needed
+ return Hop_NotCond( pHopObj, pCut->fCompl ^ Gia_ObjFaninC0(pGiaPo) ^ ((uCanonPhase >> nLeaves) & 1) );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Reduces GIA to contain only useful COs and internal nodes.]
+
+ Description [During library construction, redundant nodes are added.
+ Some COs are found to be useless because their TT does not match the
+ (semi-canonicized TT) of the cut, etc. This procedure reduces GIA
+ to contains only useful (non-redundant, non-dominated) COs and the
+ corresponding internal nodes. This procedure replaces GIA by a new GIA
+ and creates new vTruthIds. The COs with the same truth table have
+ adjacent IDs. This procedure does not change the truth tables.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// count how many times TT occurs
+Vec_Int_t * Lms_GiaCountTruths( Lms_Man_t * p )
+{
+ Vec_Int_t * vCounts = Vec_IntStart( Vec_MemEntryNum(p->vTtMem) );
+ int i, Entry;
+ Vec_IntForEachEntry( p->vTruthIds, Entry, i )
+ if ( Entry >= 0 )
+ Vec_IntAddToEntry( vCounts, Entry, 1 );
+ return vCounts;
+}
+// collect PO indexes worth visiting
+Vec_Int_t * Lms_GiaCollectUsefulCos( Lms_Man_t * p )
+{
+ Vec_Int_t * vBegins = Vec_IntAlloc( Vec_MemEntryNum(p->vTtMem) );
+ Vec_Int_t * vUseful = Vec_IntStartFull( Gia_ManCoNum(p->pGia) + Vec_MemEntryNum(p->vTtMem) );
+ Vec_Int_t * vCounts = Lms_GiaCountTruths( p );
+ int i, Entry, * pPlace, SumTotal = 0;
+ // mark up the place for POs
+ Vec_IntForEachEntry( vCounts, Entry, i )
+ {
+ assert( Entry > 0 );
+ Vec_IntPush( vBegins, SumTotal );
+ SumTotal += Entry + 1;
+// printf( "%d ", Entry );
+ }
+ Vec_IntPush( vBegins, SumTotal );
+ // fill out POs in their places
+ Vec_IntFill( vCounts, Vec_IntSize(vCounts), 0 );
+ Vec_IntForEachEntry( p->vTruthIds, Entry, i )
+ {
+ if ( Entry < 0 )
+ continue;
+ pPlace = Vec_IntEntryP( vUseful, Vec_IntEntry(vBegins, Entry) + Vec_IntEntry(vCounts, Entry) );
+ assert( *pPlace == -1 );
+ *pPlace = i;
+ Vec_IntAddToEntry( vCounts, Entry, 1 );
+ }
+ Vec_IntFree( vBegins );
+ Vec_IntFree( vCounts );
+ return vUseful;
+}
+// collect non-dominated COs
+Vec_Int_t * Lms_GiaFindNonRedundantCos( Lms_Man_t * p )
+{
+ Vec_Int_t * vRemain;
+ Vec_Int_t * vUseful;
+ Vec_Wrd_t * vDelays;
+ int i, k, EntryI, EntryK;
+ word D1, D2;
+ vDelays = Lms_GiaDelays( p->pGia );
+ vUseful = Lms_GiaCollectUsefulCos( p );
+ Vec_IntForEachEntry( vUseful, EntryI, i )
+ {
+ if ( EntryI < 0 )
+ continue;
+ D1 = Vec_WrdEntry(vDelays, EntryI);
+ assert( D1 > 0 );
+ Vec_IntForEachEntryStart( vUseful, EntryK, k, i+1 )
+ {
+ if ( EntryK == -1 )
+ break;
+ if ( EntryK == -2 )
+ continue;
+ D2 = Vec_WrdEntry(vDelays, EntryK);
+ assert( D2 > 0 );
+ if ( Lms_DelayDom(D1, D2, Gia_ManCiNum(p->pGia)) ) // D1 dominate D2
+ {
+ Vec_IntWriteEntry( vUseful, k, -2 );
+ continue;
+ }
+ if ( Lms_DelayDom(D2, D1, Gia_ManCiNum(p->pGia)) ) // D2 dominate D1
+ {
+ Vec_IntWriteEntry( vUseful, i, -2 );
+ break;
+ }
+ }
+ }
+
+ vRemain = Vec_IntAlloc( 1000 );
+ Vec_IntForEachEntry( vUseful, EntryI, i )
+ if ( EntryI >= 0 )
+ Vec_IntPush( vRemain, EntryI );
+ Vec_IntFree( vUseful );
+ Vec_WrdFree( vDelays );
+ return vRemain;
+}
+// replace GIA and vTruthIds by filtered ones
+void Lms_GiaNormalize( Lms_Man_t * p )
+{
+ Gia_Man_t * pGiaNew;
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vRemain;
+ Vec_Int_t * vTruthIdsNew;
+ int i, Entry, Prev = -1, Next;
+ clock_t clk = clock();
+ // collect non-redundant COs
+ vRemain = Lms_GiaFindNonRedundantCos( p );
+ // change these to be useful literals
+ vTruthIdsNew = Vec_IntAlloc( Vec_IntSize(vRemain) );
+ Vec_IntForEachEntry( vRemain, Entry, i )
+ {
+ pObj = Gia_ManCo(p->pGia, Entry);
+ assert( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) );
+ Vec_IntWriteEntry( vRemain, i, Gia_ObjFaninLit0p(p->pGia, pObj) );
+ // create new truth IDs
+ Next = Vec_IntEntry(p->vTruthIds, Gia_ObjCioId(pObj));
+ assert( Prev <= Next );
+ Vec_IntPush( vTruthIdsNew, Next );
+ Prev = Next;
+ }
+ // create a new GIA
+ Gia_ManForEachObj( p->pGia, pObj, i )
+ assert( pObj->fMark0 == 0 );
+ for ( i = 0; i < Gia_ManCoNum(p->pGia); i++ )
+ Gia_ManPatchCoDriver( p->pGia, i, 0 );
+ Vec_IntForEachEntry( vRemain, Entry, i )
+ Gia_ManAppendCo( p->pGia, Entry );
+// pGiaNew = Gia_ManCleanup( p->pGia );
+ pGiaNew = Gia_ManCleanupOutputs( p->pGia, Gia_ManCoNum(p->pGia) - Vec_IntSize(vRemain) );
+ Gia_ManStop( p->pGia );
+ p->pGia = pGiaNew;
+ Vec_IntFree( vRemain );
+ // update truth IDs
+ Vec_IntFree( p->vTruthIds );
+ p->vTruthIds = vTruthIdsNew;
+// Vec_IntPrint( vTruthIdsNew );
+ Abc_PrintTime( 1, "Normalization runtime", clock() - clk );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRecPs3(int fPrintLib)
+{
+ Lms_ManPrint( s_pMan3 );
+
+ printf( "Before normalizing\n" );
+ Gia_ManPrintStats( s_pMan3->pGia, 0, 0 );
+
+ Lms_GiaNormalize( s_pMan3 );
+
+ printf( "After normalizing\n" );
+ Gia_ManPrintStats( s_pMan3->pGia, 0, 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRecIsRunning3()
+{
+ return s_pMan3 != NULL;
+}
+Gia_Man_t * Abc_NtkRecGetGia3()
+{
+ Lms_GiaNormalize( s_pMan3 );
+ return s_pMan3->pGia;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END \ No newline at end of file
diff --git a/src/base/abci/module.make b/src/base/abci/module.make
index d96afbd1..90bdb419 100644
--- a/src/base/abci/module.make
+++ b/src/base/abci/module.make
@@ -46,6 +46,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcQuant.c \
src/base/abci/abcRec.c \
src/base/abci/abcRec2.c \
+ src/base/abci/abcRec3.c \
src/base/abci/abcReconv.c \
src/base/abci/abcReach.c \
src/base/abci/abcRefactor.c \
diff --git a/src/base/io/io.c b/src/base/io/io.c
index b7c3234c..466a563a 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -1654,9 +1654,10 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
char * pFileName;
char * pLutStruct = NULL;
int c, fSpecial = 0;
+ int fUseHie = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Sjh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Sjah" ) ) != EOF )
{
switch ( c )
{
@@ -1677,6 +1678,9 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
case 'j':
fSpecial ^= 1;
break;
+ case 'a':
+ fUseHie ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -1694,16 +1698,17 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
pFileName = argv[globalUtilOptind];
// call the corresponding file writer
if ( fSpecial || pLutStruct )
- Io_WriteBlifSpecial( pAbc->pNtkCur, pFileName, pLutStruct );
+ Io_WriteBlifSpecial( pAbc->pNtkCur, pFileName, pLutStruct, fUseHie );
else
Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BLIF );
return 0;
usage:
- fprintf( pAbc->Err, "usage: write_blif [-S str] [-jh] <file>\n" );
+ fprintf( pAbc->Err, "usage: write_blif [-S str] [-jah] <file>\n" );
fprintf( pAbc->Err, "\t writes the network into a BLIF file\n" );
fprintf( pAbc->Err, "\t-S str : string representing the LUT structure [default = %s]\n", pLutStruct ? pLutStruct : "not used" );
fprintf( pAbc->Err, "\t-j : enables special BLIF writing [default = %s]\n", fSpecial? "yes" : "no" );;
+ fprintf( pAbc->Err, "\t-a : enables hierarchical BLIF writing for LUT structures [default = %s]\n", fUseHie? "yes" : "no" );;
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .blif)\n" );
return 1;
@@ -2734,17 +2739,22 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv )
char * pFileName;
FILE * pFile;
unsigned * pTruth;
+ int nBytes;
int fReverse = 0;
+ int fBinary = 0;
int c, i;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "rh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "rbh" ) ) != EOF )
{
switch ( c )
{
case 'r':
fReverse ^= 1;
break;
+ case 'b':
+ fBinary ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -2761,30 +2771,39 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv )
Abc_Print( -1, "IoCommandWriteTruths(): Can write truth tables up to 16 inputs.\n" );
return 0;
}
+ if ( Gia_ManPiNum(pAbc->pGia) < 3 )
+ {
+ Abc_Print( -1, "IoCommandWriteTruths(): Can write truth tables for 3 inputs or more.\n" );
+ return 0;
+ }
if ( argc != globalUtilOptind + 1 )
goto usage;
// get the input file name
pFileName = argv[globalUtilOptind];
// convert to logic
- pFile = fopen( pFileName, "w" );
+ pFile = fopen( pFileName, "wb" );
if ( pFile == NULL )
{
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
return 0;
}
+ nBytes = 8 * Abc_Truth6WordNum( Gia_ManPiNum(pAbc->pGia) );
Gia_ManForEachCo( pAbc->pGia, pObj, i )
{
pTruth = Gia_ObjComputeTruthTable( pAbc->pGia, pObj );
- Extra_PrintHex( pFile, pTruth, Gia_ManPiNum(pAbc->pGia) );
- fprintf( pFile, "\n" );
+ if ( fBinary )
+ fwrite( pTruth, nBytes, 1, pFile );
+ else
+ Extra_PrintHex( pFile, pTruth, Gia_ManPiNum(pAbc->pGia) ), fprintf( pFile, "\n" );
}
fclose( pFile );
return 0;
usage:
- fprintf( pAbc->Err, "usage: &write_truths [-rh] <file>\n" );
+ fprintf( pAbc->Err, "usage: &write_truths [-rbh] <file>\n" );
fprintf( pAbc->Err, "\t writes truth tables of each PO of GIA manager into a file\n" );
fprintf( pAbc->Err, "\t-r : toggle reversing bits in the truth table [default = %s]\n", fReverse? "yes":"no" );
+ fprintf( pAbc->Err, "\t-b : toggle using binary format [default = %s]\n", fBinary? "yes":"no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
return 1;
diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h
index 039f53c0..efac1212 100644
--- a/src/base/io/ioAbc.h
+++ b/src/base/io/ioAbc.h
@@ -106,7 +106,7 @@ extern void Io_WriteBblif( Abc_Ntk_t * pNtk, char * pFileName );
extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches, int fBb2Wb, int fSeq );
extern void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk );
-extern void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct );
+extern void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie );
/*=== abcWriteBlifMv.c ==========================================================*/
extern void Io_WriteBlifMv( Abc_Ntk_t * pNtk, char * FileName );
/*=== abcWriteBench.c =========================================================*/
diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c
index bbaad423..ab40065e 100644
--- a/src/base/io/ioReadBlifMv.c
+++ b/src/base/io/ioReadBlifMv.c
@@ -1272,7 +1272,7 @@ static int Io_MvParseLineSubckt( Io_MvMod_t * p, char * pLine )
return 0;
}
*/
- if ( k == nEquals )
+ if ( pName2 == NULL )
{
Abc_Obj_t * pNode = Abc_NtkCreateNode( p->pNtk );
pNode->pData = Abc_SopRegister( (Mem_Flex_t *)p->pNtk->pManFunc, " 0\n" );
@@ -1313,11 +1313,10 @@ static int Io_MvParseLineSubckt( Io_MvMod_t * p, char * pLine )
return 0;
}
*/
- assert( pName2 != NULL );
// create the BI with the actual name
pTerm = Abc_NtkCreateBo( p->pNtk );
- pNet = Abc_NtkFindOrCreateNet( p->pNtk, k == nEquals ? Abc_ObjNameSuffix(pTerm, "abc") : pName2 );
+ pNet = Abc_NtkFindOrCreateNet( p->pNtk, pName2 == NULL ? Abc_ObjNameSuffix(pTerm, "abc") : pName2 );
Abc_ObjAddFanin( pNet, pTerm );
Abc_ObjAddFanin( pTerm, pBox );
}
diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c
index e13037db..bd7d9819 100644
--- a/src/base/io/ioWriteBlif.c
+++ b/src/base/io/ioWriteBlif.c
@@ -514,6 +514,68 @@ void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode )
fprintf( pFile, " %s", pName );
}
+/**Function*************************************************************
+
+ Synopsis [Writes the primary input list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteSubcktFanins( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ char * pName;
+ int i;
+
+ LineLength = 6;
+ NameCounter = 0;
+
+ // get the output name
+ pName = Abc_ObjName(Abc_ObjFanout0(pNode));
+ // get the line length after the output name is written
+ AddedLength = strlen(pName) + 1;
+ fprintf( pFile, " m%d", Abc_ObjId(pNode) );
+
+ // get the input names
+ Abc_ObjForEachFanin( pNode, pNet, i )
+ {
+ // get the fanin name
+ pName = Abc_ObjName(pNet);
+ // get the line length after the fanin name is written
+ AddedLength = strlen(pName) + 3;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, " \\\n" );
+ // reset the line length
+ LineLength = 0;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %c=%s", 'a'+i, pName );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+
+ // get the output name
+ pName = Abc_ObjName(Abc_ObjFanout0(pNode));
+ // get the line length after the output name is written
+ AddedLength = strlen(pName) + 3;
+ if ( NameCounter && LineLength + AddedLength > 75 )
+ { // write the line extender
+ fprintf( pFile, " \\\n" );
+ // reset the line length
+ LineLength = 0;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %c=%s", 'o', pName );
+}
+
/**Function*************************************************************
@@ -586,6 +648,26 @@ int Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length )
/**Function*************************************************************
+ Synopsis [Write the node into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_NtkWriteNodeSubckt( FILE * pFile, Abc_Obj_t * pNode, int Length )
+{
+ int RetValue = 0;
+ fprintf( pFile, ".subckt" );
+ Io_NtkWriteSubcktFanins( pFile, pNode );
+ fprintf( pFile, "\n" );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
Synopsis [Writes the timing info.]
Description []
@@ -1022,6 +1104,182 @@ void Io_NtkWriteNodeIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCov
/**Function*************************************************************
+ Synopsis [Write the node into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteModelIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCover, char * pStr )
+{
+ Abc_Obj_t * pNet;
+ int nLeaves = Abc_ObjFaninNum(pNode);
+ int i, nLutLeaf, nLutLeaf2, nLutRoot, Length;
+
+ // write the header
+ fprintf( pFile, "\n" );
+ fprintf( pFile, ".model m%d\n", Abc_ObjId(pNode) );
+ fprintf( pFile, ".inputs" );
+ for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
+ fprintf( pFile, " %c", 'a' + i );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, ".outputs o\n" );
+
+ // quit if parameters are wrong
+ Length = strlen(pStr);
+ if ( Length != 2 && Length != 3 )
+ {
+ printf( "Wrong LUT struct (%s)\n", pStr );
+ return;
+ }
+ for ( i = 0; i < Length; i++ )
+ if ( pStr[i] - '0' < 3 || pStr[i] - '0' > 6 )
+ {
+ printf( "The LUT size (%d) should belong to {3,4,5,6}.\n", pStr[i] - '0' );
+ return;
+ }
+
+ nLutLeaf = pStr[0] - '0';
+ nLutLeaf2 = ( Length == 3 ) ? pStr[1] - '0' : 0;
+ nLutRoot = pStr[Length-1] - '0';
+ if ( nLeaves > nLutLeaf - 1 + (nLutLeaf2 ? nLutLeaf2 - 1 : 0) + nLutRoot )
+ {
+ printf( "The node size (%d) is too large for the LUT structure %s.\n", nLeaves, pStr );
+ return;
+ }
+
+ // consider easy case
+ if ( nLeaves <= Abc_MaxInt( nLutLeaf2, Abc_MaxInt(nLutLeaf, nLutRoot) ) )
+ {
+ // write the .names line
+ fprintf( pFile, ".names" );
+ Abc_ObjForEachFanin( pNode, pNet, i )
+ fprintf( pFile, " %c", 'a' + i );
+ // get the output name
+ fprintf( pFile, " %s\n", "o" );
+ // write the cubes
+ fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
+ fprintf( pFile, ".end\n" );
+ return;
+ }
+ else
+ {
+ extern int If_CluMinimumBase( word * t, int * pSupp, int nVarsAll, int * pnVars );
+
+ static word TruthStore[16][1<<10] = {{0}}, * pTruths[16];
+ word pCube[1<<10], pRes[1<<10], Func0, Func1, Func2;
+ char pLut0[32], pLut1[32], pLut2[32] = {0}, * pSop;
+// int nVarsMin[3], pVars[3][20];
+
+ if ( TruthStore[0][0] == 0 )
+ {
+ static word Truth6[6] = {
+ 0xAAAAAAAAAAAAAAAA,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFF00FF00FF00FF00,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFF00000000
+ };
+ int nVarsMax = 16;
+ int nWordsMax = (1 << 10);
+ int i, k;
+ assert( nVarsMax <= 16 );
+ for ( i = 0; i < nVarsMax; i++ )
+ pTruths[i] = TruthStore[i];
+ for ( i = 0; i < 6; i++ )
+ for ( k = 0; k < nWordsMax; k++ )
+ pTruths[i][k] = Truth6[i];
+ for ( i = 6; i < nVarsMax; i++ )
+ for ( k = 0; k < nWordsMax; k++ )
+ pTruths[i][k] = ((k >> (i-6)) & 1) ? ~(word)0 : 0;
+ }
+
+ // collect variables
+// Abc_ObjForEachFanin( pNode, pNet, i )
+// pVars[0][i] = pVars[1][i] = pVars[2][i] = i;
+
+ // derive truth table
+ Abc_SopToTruthBig( (char*)Abc_ObjData(pNode), nLeaves, pTruths, pCube, pRes );
+ if ( Kit_TruthIsConst0((unsigned *)pRes, nLeaves) || Kit_TruthIsConst1((unsigned *)pRes, nLeaves) )
+ {
+ fprintf( pFile, ".names %s\n %d\n", "o", Kit_TruthIsConst1((unsigned *)pRes, nLeaves) );
+ fprintf( pFile, ".end\n" );
+ return;
+ }
+
+// Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
+// Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
+
+ // perform decomposition
+ if ( Length == 2 )
+ {
+ if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
+ {
+ Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
+ Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
+ printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
+ return;
+ }
+ }
+ else
+ {
+ if ( !If_CluCheckExt3( NULL, pRes, nLeaves, nLutLeaf, nLutLeaf2, nLutRoot, pLut0, pLut1, pLut2, &Func0, &Func1, &Func2 ) )
+ {
+ Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
+ Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
+ printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
+ return;
+ }
+ }
+
+ // write leaf node
+ fprintf( pFile, ".names" );
+ for ( i = 0; i < pLut1[0]; i++ )
+ fprintf( pFile, " %c", 'a' + pLut1[2+i] );
+ fprintf( pFile, " lut1\n" );
+ // write SOP
+ pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func1, pLut1[0], vCover );
+ fprintf( pFile, "%s", pSop );
+
+ if ( Length == 3 && pLut2[0] > 0 )
+ {
+ // write leaf node
+ fprintf( pFile, ".names" );
+ for ( i = 0; i < pLut2[0]; i++ )
+ if ( pLut2[2+i] == nLeaves )
+ fprintf( pFile, " lut1" );
+ else
+ fprintf( pFile, " %c", 'a' + pLut2[2+i] );
+ fprintf( pFile, " lut2\n" );
+ // write SOP
+ pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func2, pLut2[0], vCover );
+ fprintf( pFile, "%s", pSop );
+ }
+
+ // write root node
+ fprintf( pFile, ".names" );
+ for ( i = 0; i < pLut0[0]; i++ )
+ if ( pLut0[2+i] == nLeaves )
+ fprintf( pFile, " lut1" );
+ else if ( pLut0[2+i] == nLeaves+1 )
+ fprintf( pFile, " lut2" );
+ else
+ fprintf( pFile, " %c", 'a' + pLut0[2+i] );
+ fprintf( pFile, " %s\n", "o" );
+ // write SOP
+ pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func0, pLut0[0], vCover );
+ fprintf( pFile, "%s", pSop );
+ fprintf( pFile, ".end\n" );
+ }
+}
+
+
+/**Function*************************************************************
+
Synopsis [Write the network into a BLIF file with the given name.]
Description []
@@ -1031,7 +1289,7 @@ void Io_NtkWriteNodeIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCov
SeeAlso []
***********************************************************************/
-void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct )
+void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie )
{
FILE * pFile;
Vec_Int_t * vCover;
@@ -1063,18 +1321,33 @@ void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct )
Io_NtkWriteLatch( pFile, pLatch );
if ( Abc_NtkLatchNum(pNtk) )
fprintf( pFile, "\n" );
- // write each internal node
+ // write the hierarchy
vCover = Vec_IntAlloc( (1<<16) );
- Abc_NtkForEachNode( pNtk, pNode, i )
+ if ( fUseHie )
{
- if ( pLutStruct )
- Io_NtkWriteNodeIntStruct( pFile, pNode, vCover, pLutStruct );
- else
- Io_NtkWriteNodeInt( pFile, pNode, vCover );
+ // write each internal node
+ fprintf( pFile, "\n" );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Io_NtkWriteNodeSubckt( pFile, pNode, 0 );
+ fprintf( pFile, ".end\n\n" );
+ // write models
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Io_NtkWriteModelIntStruct( pFile, pNode, vCover, pLutStruct );
+ fprintf( pFile, "\n" );
+ }
+ else
+ {
+ // write each internal node
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( pLutStruct )
+ Io_NtkWriteNodeIntStruct( pFile, pNode, vCover, pLutStruct );
+ else
+ Io_NtkWriteNodeInt( pFile, pNode, vCover );
+ }
+ fprintf( pFile, ".end\n\n" );
}
Vec_IntFree( vCover );
- // write the end
- fprintf( pFile, ".end\n\n" );
fclose( pFile );
}
@@ -1089,7 +1362,7 @@ void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct )
SeeAlso []
***********************************************************************/
-void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct )
+void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie )
{
Abc_Ntk_t * pNtkTemp;
assert( Abc_NtkIsLogic(pNtk) );
@@ -1101,7 +1374,10 @@ void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct )
fprintf( stdout, "Writing BLIF has failed.\n" );
return;
}
- Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct );
+ if ( pLutStruct && fUseHie )
+ Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct, 1 );
+ else
+ Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct, 0 );
Abc_NtkDelete( pNtkTemp );
}
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
index 4db982f0..f30a13e5 100644
--- a/src/base/main/mainInt.h
+++ b/src/base/main/mainInt.h
@@ -111,7 +111,7 @@ struct Abc_Frame_t_
void * pAbc85Ntl2;
void * pAbc85Best;
void * pAbc85Delay;
- If_Lib_t * pAbc85Lib;
+// If_Lib_t * pAbc85Lib;
EXT_ABC_FRAME // plugin for external functionality
};
diff --git a/src/bool/kit/kit.h b/src/bool/kit/kit.h
index 5ecb5581..cb1c1eb0 100644
--- a/src/bool/kit/kit.h
+++ b/src/bool/kit/kit.h
@@ -68,7 +68,8 @@ struct Kit_Node_t_
Kit_Edge_t eEdge0; // the left child of the node
Kit_Edge_t eEdge1; // the right child of the node
// other info
- void * pFunc; // the function of the node (BDD or AIG)
+ union { int iFunc; // the function of the node (BDD or AIG)
+ void * pFunc; }; // the function of the node (BDD or AIG)
unsigned Level : 14; // the level of this node in the global AIG
// printing info
unsigned fNodeOr : 1; // marks the original OR node
@@ -561,6 +562,7 @@ extern unsigned Kit_GraphToTruth( Kit_Graph_t * pGraph );
extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
extern int Kit_GraphLeafDepth_rec( Kit_Graph_t * pGraph, Kit_Node_t * pNode, Kit_Node_t * pLeaf );
/*=== kitHop.c ==========================================================*/
+//extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
//extern Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph );
//extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
//extern Hop_Obj_t * Kit_CoverToHop( Hop_Man_t * pMan, Vec_Int_t * vCover, int nVars, Vec_Int_t * vMemory );
diff --git a/src/bool/kit/kitHop.c b/src/bool/kit/kitHop.c
index c7c855af..a4ce79f3 100644
--- a/src/bool/kit/kitHop.c
+++ b/src/bool/kit/kitHop.c
@@ -20,6 +20,7 @@
#include "kit.h"
#include "aig/hop/hop.h"
+#include "aig/gia/gia.h"
ABC_NAMESPACE_IMPL_START
@@ -43,31 +44,66 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-Hop_Obj_t * Kit_GraphToHopInternal( Hop_Man_t * pMan, Kit_Graph_t * pGraph )
+int Kit_GraphToGiaInternal( Gia_Man_t * pMan, Kit_Graph_t * pGraph, int fHash )
{
Kit_Node_t * pNode = NULL;
- Hop_Obj_t * pAnd0, * pAnd1;
- int i;
+ int i, pAnd0, pAnd1;
// check for constant function
if ( Kit_GraphIsConst(pGraph) )
- return Hop_NotCond( Hop_ManConst1(pMan), Kit_GraphIsComplement(pGraph) );
+ return Abc_LitNotCond( 1, Kit_GraphIsComplement(pGraph) );
// check for a literal
if ( Kit_GraphIsVar(pGraph) )
- return Hop_NotCond( (Hop_Obj_t *)Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) );
+ return Abc_LitNotCond( Kit_GraphVar(pGraph)->iFunc, Kit_GraphIsComplement(pGraph) );
// build the AIG nodes corresponding to the AND gates of the graph
Kit_GraphForEachNode( pGraph, pNode, i )
{
- pAnd0 = Hop_NotCond( (Hop_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
- pAnd1 = Hop_NotCond( (Hop_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
- pNode->pFunc = Hop_And( pMan, pAnd0, pAnd1 );
+ pAnd0 = Abc_LitNotCond( Kit_GraphNode(pGraph, pNode->eEdge0.Node)->iFunc, pNode->eEdge0.fCompl );
+ pAnd1 = Abc_LitNotCond( Kit_GraphNode(pGraph, pNode->eEdge1.Node)->iFunc, pNode->eEdge1.fCompl );
+ if ( fHash )
+ pNode->iFunc = Gia_ManHashAnd( pMan, pAnd0, pAnd1 );
+ else
+ pNode->iFunc = Gia_ManAppendAnd( pMan, pAnd0, pAnd1 );
}
// complement the result if necessary
- return Hop_NotCond( (Hop_Obj_t *)pNode->pFunc, Kit_GraphIsComplement(pGraph) );
+ return Abc_LitNotCond( pNode->iFunc, Kit_GraphIsComplement(pGraph) );
+}
+int Kit_GraphToGia( Gia_Man_t * pMan, Kit_Graph_t * pGraph, Vec_Int_t * vLeaves, int fHash )
+{
+ Kit_Node_t * pNode = NULL;
+ int i;
+ // collect the fanins
+ Kit_GraphForEachLeaf( pGraph, pNode, i )
+ pNode->iFunc = Vec_IntEntry( vLeaves, i );
+ // perform strashing
+ return Kit_GraphToGiaInternal( pMan, pGraph, fHash );
+}
+int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash )
+{
+ int iLit;
+ Kit_Graph_t * pGraph;
+ // transform truth table into the decomposition tree
+ if ( vMemory == NULL )
+ {
+ vMemory = Vec_IntAlloc( 0 );
+ pGraph = Kit_TruthToGraph( pTruth, nVars, vMemory );
+ Vec_IntFree( vMemory );
+ }
+ else
+ pGraph = Kit_TruthToGraph( pTruth, nVars, vMemory );
+ if ( pGraph == NULL )
+ {
+ printf( "Kit_TruthToGia(): Converting truth table to AIG has failed for function:\n" );
+ Kit_DsdPrintFromTruth( pTruth, nVars ); printf( "\n" );
+ }
+ // derive the AIG for the decomposition tree
+ iLit = Kit_GraphToGia( pMan, pGraph, vLeaves, fHash );
+ Kit_GraphFree( pGraph );
+ return iLit;
}
/**Function*************************************************************
- Synopsis [Strashes one logic node using its SOP.]
+ Synopsis [Transforms the decomposition graph into the AIG.]
Description []
@@ -76,6 +112,27 @@ Hop_Obj_t * Kit_GraphToHopInternal( Hop_Man_t * pMan, Kit_Graph_t * pGraph )
SeeAlso []
***********************************************************************/
+Hop_Obj_t * Kit_GraphToHopInternal( Hop_Man_t * pMan, Kit_Graph_t * pGraph )
+{
+ Kit_Node_t * pNode = NULL;
+ Hop_Obj_t * pAnd0, * pAnd1;
+ int i;
+ // check for constant function
+ if ( Kit_GraphIsConst(pGraph) )
+ return Hop_NotCond( Hop_ManConst1(pMan), Kit_GraphIsComplement(pGraph) );
+ // check for a literal
+ if ( Kit_GraphIsVar(pGraph) )
+ return Hop_NotCond( (Hop_Obj_t *)Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) );
+ // build the AIG nodes corresponding to the AND gates of the graph
+ Kit_GraphForEachNode( pGraph, pNode, i )
+ {
+ pAnd0 = Hop_NotCond( (Hop_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
+ pAnd1 = Hop_NotCond( (Hop_Obj_t *)Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
+ pNode->pFunc = Hop_And( pMan, pAnd0, pAnd1 );
+ }
+ // complement the result if necessary
+ return Hop_NotCond( (Hop_Obj_t *)pNode->pFunc, Kit_GraphIsComplement(pGraph) );
+}
Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph )
{
Kit_Node_t * pNode = NULL;
@@ -86,18 +143,6 @@ Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph )
// perform strashing
return Kit_GraphToHopInternal( pMan, pGraph );
}
-
-/**Function*************************************************************
-
- Synopsis [Strashed onen logic nodes using its truth table.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory )
{
Hop_Obj_t * pObj;
diff --git a/src/bool/kit/kitTruth.c b/src/bool/kit/kitTruth.c
index a6951163..87b28135 100644
--- a/src/bool/kit/kitTruth.c
+++ b/src/bool/kit/kitTruth.c
@@ -1664,6 +1664,8 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars,
// canonicize output
uCanonPhase = 0;
+ for ( i = 0; i < nVars; i++ )
+ pCanonPerm[i] = i;
nOnes = Kit_TruthCountOnes(pIn, nVars);
//if(pIn[0] & 1)
diff --git a/src/map/if/if.h b/src/map/if/if.h
index f74a59da..9e649e0c 100644
--- a/src/map/if/if.h
+++ b/src/map/if/if.h
@@ -333,7 +333,7 @@ static inline void * If_ObjCopy( If_Obj_t * pObj ) { r
static inline int If_ObjLevel( If_Obj_t * pObj ) { return pObj->Level; }
static inline void If_ObjSetLevel( If_Obj_t * pObj, int Level ) { pObj->Level = Level; }
static inline void If_ObjSetCopy( If_Obj_t * pObj, void * pCopy ) { pObj->pCopy = pCopy; }
-static inline void If_ObjSetChoice( If_Obj_t * pObj, If_Obj_t * pEqu ) { pObj->pEquiv = pEqu; }
+static inline void If_ObjSetChoice( If_Obj_t * pObj, If_Obj_t * pEqu ) { assert( pObj->Id > pEqu->Id ); pObj->pEquiv = pEqu; }
static inline If_Cut_t * If_ObjCutBest( If_Obj_t * pObj ) { return &pObj->CutBest; }
static inline unsigned If_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId % 31)); }
@@ -353,8 +353,9 @@ static inline void If_CutSetDataInt( If_Cut_t * pCut, int Data ) { *
static inline int If_CutLeaveNum( If_Cut_t * pCut ) { return pCut->nLeaves; }
static inline int * If_CutLeaves( If_Cut_t * pCut ) { return pCut->pLeaves; }
static inline unsigned * If_CutTruth( If_Cut_t * pCut ) { return pCut->pTruth; }
+static inline word * If_CutTruthW( If_Cut_t * pCut ) { return (word *)pCut->pTruth; }
static inline unsigned If_CutSuppMask( If_Cut_t * pCut ) { return (~(unsigned)0) >> (32-pCut->nLeaves); }
-static inline int If_CutTruthWords( int nVarsMax ) { return nVarsMax <= 5 ? 1 : (1 << (nVarsMax - 5)); }
+static inline int If_CutTruthWords( int nVarsMax ) { return nVarsMax <= 5 ? 2 : (1 << (nVarsMax - 5)); }
static inline int If_CutPermWords( int nVarsMax ) { return nVarsMax / sizeof(int) + ((nVarsMax % sizeof(int)) > 0); }
static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { return pCut->fUser? (float)pCut->Cost : (p->pPars->pLutLib? p->pPars->pLutLib->pLutAreas[pCut->nLeaves] : (float)1.0); }
@@ -505,8 +506,9 @@ extern void If_CutPropagateRequired( If_Man_t * p, If_Obj_t * pObj, I
extern void If_CutRotatePins( If_Man_t * p, If_Cut_t * pCut );
/*=== ifTruth.c ===========================================================*/
extern int If_CutTruthMinimize( If_Man_t * p, If_Cut_t * pCut );
-extern int If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 );
extern void If_CutTruthPermute( unsigned * pOut, unsigned * pIn, int nVars, float * pDelays, int * pVars );
+extern int If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 );
+extern int If_CutComputeTruth2( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 );
/*=== ifUtil.c ============================================================*/
extern void If_ManCleanNodeCopy( If_Man_t * p );
extern void If_ManCleanCutData( If_Man_t * p );
@@ -525,13 +527,18 @@ extern Vec_Ptr_t * If_ManCollectMappingDirect( If_Man_t * p );
extern Vec_Int_t * If_ManCollectMappingInt( If_Man_t * p );
extern int If_ManCountSpecialPos( If_Man_t * p );
+extern void If_CutTraverse( If_Man_t * p, If_Obj_t * pRoot, If_Cut_t * pCut, Vec_Ptr_t * vNodes );
+extern void If_ObjPrint( If_Obj_t * pObj );
/*=== abcRec.c ============================================================*/
+/*=== abcRec2.c ============================================================*/
+/*=== abcRec3.c ============================================================*/
extern int If_CutDelayRecCost(If_Man_t* p, If_Cut_t* pCut, If_Obj_t * pObj);
extern int If_CutDelayRecCost2(If_Man_t* p, If_Cut_t* pCut, If_Obj_t * pObj);
-/*=== abcRec2.c ============================================================*/
+extern int If_CutDelayRecCost3(If_Man_t* p, If_Cut_t* pCut, If_Obj_t * pObj);
extern ABC_DLL int Abc_NtkRecIsRunning();
extern ABC_DLL int Abc_NtkRecIsRunning2();
+extern ABC_DLL int Abc_NtkRecIsRunning3();
// othe packages
extern int Bat_ManCellFuncLookup( unsigned * pTruth, int nVars, int nLeaves );
diff --git a/src/map/if/ifMan.c b/src/map/if/ifMan.c
index 3028e370..0ebdec1b 100644
--- a/src/map/if/ifMan.c
+++ b/src/map/if/ifMan.c
@@ -337,6 +337,7 @@ void If_ManCreateChoice( If_Man_t * p, If_Obj_t * pObj )
// mark the largest level
if ( p->nLevelMax < (int)pObj->Level )
p->nLevelMax = (int)pObj->Level;
+ p->nChoices++;
}
/**Function*************************************************************
@@ -410,8 +411,7 @@ void If_ManSetupCutTriv( If_Man_t * p, If_Cut_t * pCut, int ObjId )
// set up elementary truth table of the unit cut
if ( p->pPars->fTruth )
{
- int i, nTruthWords;
- nTruthWords = pCut->nLimit <= 5 ? 1 : (1 << (pCut->nLimit - 5));
+ int i, nTruthWords = If_CutTruthWords(pCut->nLimit);
for ( i = 0; i < nTruthWords; i++ )
If_CutTruth(pCut)[i] = 0xAAAAAAAA;
}
diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c
index 6fcb8799..1f7ba898 100644
--- a/src/map/if/ifMap.c
+++ b/src/map/if/ifMap.c
@@ -75,7 +75,8 @@ float If_CutDelaySpecial( If_Man_t * p, If_Cut_t * pCut, int fCarry )
Delay = IF_MAX( Delay, Pin2Pin[fCarry][i] + DelayCur );
}
return Delay;
- }
+}
+
/**Function*************************************************************
@@ -157,12 +158,13 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
/// pCut->Delay = If_CutDelayLutStruct( p, pCut, p->pPars->pLutStruct, p->pPars->WireDelay );
if ( p->pPars->fUserRecLib )
{
- if((Abc_NtkRecIsRunning2()&& Abc_NtkRecIsRunning()) || (!Abc_NtkRecIsRunning2()&& !Abc_NtkRecIsRunning()))
- assert(0);
- else if(Abc_NtkRecIsRunning())
- pCut->Delay = If_CutDelayRecCost(p, pCut, pObj);
+ assert( Abc_NtkRecIsRunning() + Abc_NtkRecIsRunning2() + Abc_NtkRecIsRunning3() == 1 );
+ if ( Abc_NtkRecIsRunning3() )
+ pCut->Delay = If_CutDelayRecCost3(p, pCut, pObj);
+ else if( Abc_NtkRecIsRunning2() )
+ pCut->Delay = If_CutDelayRecCost2(p, pCut, pObj);
else
- pCut->Delay = If_CutDelayRecCost2(p, pCut, pObj);
+ pCut->Delay = If_CutDelayRecCost(p, pCut, pObj);
}
else if(p->pPars->fDelayOpt)
pCut->Delay = If_CutDelaySopCost(p,pCut);
@@ -211,8 +213,10 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
if ( p->pPars->fTruth )
{
// clock_t clk = clock();
- int RetValue = If_CutComputeTruth( p, pCut, pCut0, pCut1, pObj->fCompl0, pObj->fCompl1 );
+// int RetValue = If_CutComputeTruth( p, pCut, pCut0, pCut1, pObj->fCompl0, pObj->fCompl1 );
+ int RetValue = If_CutComputeTruth2( p, pCut, pCut0, pCut1, pObj->fCompl0, pObj->fCompl1 );
// p->timeTruth += clock() - clk;
+
pCut->fUseless = 0;
if ( p->pPars->pFuncCell && RetValue < 2 )
{
@@ -236,12 +240,13 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
/// pCut->Delay = If_CutDelayLutStruct( p, pCut, p->pPars->pLutStruct, p->pPars->WireDelay );
if ( p->pPars->fUserRecLib )
{
- if((Abc_NtkRecIsRunning2()&& Abc_NtkRecIsRunning()) || (!Abc_NtkRecIsRunning2()&& !Abc_NtkRecIsRunning()))
- assert(0);
- else if(Abc_NtkRecIsRunning())
- pCut->Delay = If_CutDelayRecCost(p, pCut, pObj);
- else
+ assert( Abc_NtkRecIsRunning() + Abc_NtkRecIsRunning2() + Abc_NtkRecIsRunning3() == 1 );
+ if ( Abc_NtkRecIsRunning3() )
+ pCut->Delay = If_CutDelayRecCost3(p, pCut, pObj);
+ else if( Abc_NtkRecIsRunning2() )
pCut->Delay = If_CutDelayRecCost2(p, pCut, pObj);
+ else
+ pCut->Delay = If_CutDelayRecCost(p, pCut, pObj);
}
else if (p->pPars->fDelayOpt)
pCut->Delay = If_CutDelaySopCost(p, pCut);
@@ -263,6 +268,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
pCut->AveRefs = (Mode == 0)? (float)0.0 : If_CutAverageRefs( p, pCut );
// insert the cut into storage
If_CutSort( p, pCutSet, pCut );
+// If_CutTraverse( p, pObj, pCut );
}
assert( pCutSet->nCuts > 0 );
diff --git a/src/map/if/ifTruth.c b/src/map/if/ifTruth.c
index f0289695..4b0db8b4 100644
--- a/src/map/if/ifTruth.c
+++ b/src/map/if/ifTruth.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "if.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -43,29 +44,28 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-static inline int If_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
static inline void If_TruthNot( unsigned * pOut, unsigned * pIn, int nVars )
{
int w;
- for ( w = If_TruthWordNum(nVars)-1; w >= 0; w-- )
+ for ( w = If_CutTruthWords(nVars)-1; w >= 0; w-- )
pOut[w] = ~pIn[w];
}
static inline void If_TruthCopy( unsigned * pOut, unsigned * pIn, int nVars )
{
int w;
- for ( w = If_TruthWordNum(nVars)-1; w >= 0; w-- )
+ for ( w = If_CutTruthWords(nVars)-1; w >= 0; w-- )
pOut[w] = pIn[w];
}
static inline void If_TruthNand( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
{
int w;
- for ( w = If_TruthWordNum(nVars)-1; w >= 0; w-- )
+ for ( w = If_CutTruthWords(nVars)-1; w >= 0; w-- )
pOut[w] = ~(pIn0[w] & pIn1[w]);
}
static inline void If_TruthAnd( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
{
int w;
- for ( w = If_TruthWordNum(nVars)-1; w >= 0; w-- )
+ for ( w = If_CutTruthWords(nVars)-1; w >= 0; w-- )
pOut[w] = pIn0[w] & pIn1[w];
}
@@ -89,7 +89,7 @@ void If_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int i
{ 0xF00FF00F, 0x00F000F0, 0x0F000F00 },
{ 0xFF0000FF, 0x0000FF00, 0x00FF0000 }
};
- int nWords = If_TruthWordNum( nVars );
+ int nWords = If_CutTruthWords( nVars );
int i, k, Step, Shift;
assert( iVar < nVars - 1 );
@@ -245,7 +245,7 @@ void If_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, u
***********************************************************************/
int If_CutTruthVarInSupport( unsigned * pTruth, int nVars, int iVar )
{
- int nWords = If_TruthWordNum( nVars );
+ int nWords = If_CutTruthWords( nVars );
int i, k, Step;
assert( iVar < nVars );
@@ -449,6 +449,191 @@ int If_CutTruthMinimize( If_Man_t * p, If_Cut_t * pCut )
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs truth table computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int If_CutTruthMinimize6( If_Man_t * p, If_Cut_t * pCut )
+{
+ unsigned uSupport;
+ int i, k, nSuppSize;
+ int nVars = If_CutLeaveNum(pCut);
+ // compute the support of the cut's function
+ uSupport = Abc_Tt6SupportAndSize( *If_CutTruthW(pCut), nVars, &nSuppSize );
+ if ( nSuppSize == If_CutLeaveNum(pCut) )
+ return 0;
+// TEMPORARY
+ if ( nSuppSize < 2 )
+ {
+ p->nSmallSupp++;
+ return 2;
+ }
+ // update leaves and signature
+ pCut->uSign = 0;
+ for ( i = k = 0; i < nVars; i++ )
+ {
+ if ( !(uSupport & (1 << i)) )
+ continue;
+ pCut->uSign |= If_ObjCutSign( pCut->pLeaves[i] );
+ if ( k < i )
+ {
+ pCut->pLeaves[k] = pCut->pLeaves[i];
+ Abc_TtSwapVars( If_CutTruthW(pCut), pCut->nLimit, k, i );
+ }
+ k++;
+ }
+ assert( k == nSuppSize );
+ pCut->nLeaves = nSuppSize;
+ // verify the result
+// assert( nSuppSize == Abc_TtSupportSize(If_CutTruthW(pCut), nVars) );
+ return 1;
+}
+static inline word If_TruthStretch6( word Truth, If_Cut_t * pCut, If_Cut_t * pCut0 )
+{
+ int i, k;
+ for ( i = (int)pCut->nLeaves - 1, k = (int)pCut0->nLeaves - 1; i >= 0 && k >= 0; i-- )
+ {
+ if ( pCut0->pLeaves[k] < pCut->pLeaves[i] )
+ continue;
+ assert( pCut0->pLeaves[k] == pCut->pLeaves[i] );
+ if ( k < i )
+ Abc_TtSwapVars( &Truth, pCut->nLimit, k, i );
+ k--;
+ }
+ return Truth;
+}
+static inline int If_CutComputeTruth6( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 )
+{
+ word t0 = (fCompl0 ^ pCut0->fCompl) ? ~*If_CutTruthW(pCut0) : *If_CutTruthW(pCut0);
+ word t1 = (fCompl1 ^ pCut1->fCompl) ? ~*If_CutTruthW(pCut1) : *If_CutTruthW(pCut1);
+ assert( pCut->nLimit <= 6 );
+ t0 = If_TruthStretch6( t0, pCut, pCut0 );
+ t1 = If_TruthStretch6( t1, pCut, pCut1 );
+ *If_CutTruthW(pCut) = t0 & t1;
+ if ( p->pPars->fCutMin )
+ return If_CutTruthMinimize6( p, pCut );
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs truth table computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// this procedure handles special case reductions
+static inline int If_CutTruthMinimize21( If_Man_t * p, If_Cut_t * pCut )
+{
+ word * pTruth = If_CutTruthW(pCut);
+ int i, k, nVars = If_CutLeaveNum(pCut);
+ unsigned uSign = 0;
+ for ( i = k = 0; i < nVars; i++ )
+ {
+ if ( !Abc_TtHasVar( pTruth, nVars, i ) )
+ continue;
+ uSign |= If_ObjCutSign( pCut->pLeaves[i] );
+ if ( k < i )
+ {
+ pCut->pLeaves[k] = pCut->pLeaves[i];
+ Abc_TtSwapVars( pTruth, nVars, k, i );
+ }
+ k++;
+ }
+ if ( k == nVars )
+ return 0;
+ assert( k < nVars );
+ pCut->nLeaves = k;
+ pCut->uSign = uSign;
+// TEMPORARY
+ if ( pCut->nLeaves < 2 )
+ {
+ p->nSmallSupp++;
+ return 2;
+ }
+ // verify the result
+ assert( If_CutLeaveNum(pCut) == Abc_TtSupportSize(pTruth, nVars) );
+ return 1;
+}
+static inline int If_CutTruthMinimize2( If_Man_t * p, If_Cut_t * pCut )
+{
+ unsigned uSupport;
+ int i, k, nSuppSize;
+ int nVars = If_CutLeaveNum(pCut);
+ // compute the support of the cut's function
+ uSupport = Abc_TtSupportAndSize( If_CutTruthW(pCut), nVars, &nSuppSize );
+ if ( nSuppSize == If_CutLeaveNum(pCut) )
+ return 0;
+// TEMPORARY
+ if ( nSuppSize < 2 )
+ {
+ p->nSmallSupp++;
+ return 2;
+ }
+ // update leaves and signature
+ pCut->uSign = 0;
+ for ( i = k = 0; i < nVars; i++ )
+ {
+ if ( !(uSupport & (1 << i)) )
+ continue;
+ pCut->uSign |= If_ObjCutSign( pCut->pLeaves[i] );
+ if ( k < i )
+ {
+ pCut->pLeaves[k] = pCut->pLeaves[i];
+ Abc_TtSwapVars( If_CutTruthW(pCut), pCut->nLimit, k, i );
+ }
+ k++;
+ }
+ assert( k == nSuppSize );
+ pCut->nLeaves = nSuppSize;
+ // verify the result
+// assert( nSuppSize == Abc_TtSupportSize(If_CutTruthW(pCut), nVars) );
+ return 1;
+}
+static inline void If_TruthStretch2( word * pTruth, If_Cut_t * pCut, If_Cut_t * pCut0 )
+{
+ int i, k;
+ for ( i = (int)pCut->nLeaves - 1, k = (int)pCut0->nLeaves - 1; i >= 0 && k >= 0; i-- )
+ {
+ if ( pCut0->pLeaves[k] < pCut->pLeaves[i] )
+ continue;
+ assert( pCut0->pLeaves[k] == pCut->pLeaves[i] );
+ if ( k < i )
+ Abc_TtSwapVars( pTruth, pCut->nLimit, k, i );
+ k--;
+ }
+}
+inline int If_CutComputeTruth2( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 )
+{
+ int nWords;
+ if ( pCut->nLimit < 7 )
+ return If_CutComputeTruth6( p, pCut, pCut0, pCut1, fCompl0, fCompl1 );
+ nWords = Abc_TtWordNum( pCut->nLimit );
+ Abc_TtCopy( (word *)p->puTemp[0], If_CutTruthW(pCut0), nWords, fCompl0 ^ pCut0->fCompl );
+ Abc_TtCopy( (word *)p->puTemp[1], If_CutTruthW(pCut1), nWords, fCompl1 ^ pCut1->fCompl );
+ If_TruthStretch2( (word *)p->puTemp[0], pCut, pCut0 );
+ If_TruthStretch2( (word *)p->puTemp[1], pCut, pCut1 );
+ Abc_TtAnd( If_CutTruthW(pCut), (word *)p->puTemp[0], (word *)p->puTemp[1], nWords, 0 );
+ if ( p->pPars->fCutMin )
+ return If_CutTruthMinimize2( p, pCut );
+ return 0;
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/if/ifUtil.c b/src/map/if/ifUtil.c
index 4d904613..b8b03d70 100644
--- a/src/map/if/ifUtil.c
+++ b/src/map/if/ifUtil.c
@@ -769,6 +769,90 @@ int If_ManCountSpecialPos( If_Man_t * p )
}
+/**Function*************************************************************
+
+ Synopsis [Traverse the cut and counts its volume.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void If_CutTraverse_rec( If_Obj_t * pNode, Vec_Ptr_t * vNodes )
+{
+ if ( pNode->fMark )
+ return;
+ pNode->fMark = 1;
+// assert( !If_ObjIsCi(pNode) ); // does not hold with cut minimization
+ if ( If_ObjIsAnd(pNode) )
+ If_CutTraverse_rec( If_ObjFanin0(pNode), vNodes );
+ if ( If_ObjIsAnd(pNode) )
+ If_CutTraverse_rec( If_ObjFanin1(pNode), vNodes );
+ Vec_PtrPush( vNodes, pNode );
+}
+void If_CutTraverse( If_Man_t * p, If_Obj_t * pRoot, If_Cut_t * pCut, Vec_Ptr_t * vNodes )
+{
+ If_Obj_t * pLeaf;
+ int i;
+ // collect the internal nodes of the cut
+ Vec_PtrClear( vNodes );
+ If_CutForEachLeaf( p, pCut, pLeaf, i )
+ {
+ Vec_PtrPush( vNodes, pLeaf );
+ assert( pLeaf->fMark == 0 );
+ pLeaf->fMark = 1;
+ }
+ // collect other nodes
+ If_CutTraverse_rec( pRoot, vNodes );
+ // clean the mark
+ Vec_PtrForEachEntry( If_Obj_t *, vNodes, pLeaf, i )
+ pLeaf->fMark = 0;
+}
+void If_CutTraverseTest( If_Man_t * p, If_Obj_t * pRoot, If_Cut_t * pCut )
+{
+ Vec_Ptr_t * vNodes;
+ vNodes = Vec_PtrAlloc( 1000 );
+ If_CutTraverse( p, pRoot, pCut, vNodes );
+//if ( Vec_PtrSize(vNodes) > 30 )
+//printf( "%d ", Vec_PtrSize(vNodes) );
+ Vec_PtrFree( vNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_ObjPrint( If_Obj_t * pObj )
+{
+ if ( pObj == NULL )
+ {
+ printf( "Object is NULL." );
+ return;
+ }
+ printf( "Obj %4d : ", If_ObjId(pObj) );
+ if ( If_ObjIsConst1(pObj) )
+ printf( "constant 1" );
+ else if ( If_ObjIsCi(pObj) )
+ printf( "PI" );
+ else if ( If_ObjIsCo(pObj) )
+ printf( "PO( %4d%s )", If_ObjId(If_ObjFanin0(pObj)), (If_ObjFaninC0(pObj)? "\'" : " ") );
+ else
+ printf( "AND( %4d%s, %4d%s )",
+ If_ObjId(If_ObjFanin0(pObj)), (If_ObjFaninC0(pObj)? "\'" : " "),
+ If_ObjId(If_ObjFanin1(pObj)), (If_ObjFaninC1(pObj)? "\'" : " ") );
+ printf( " (refs = %3d)", pObj->nVisitsCopy );
+ printf( "\n" );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/scl/sclTime.c b/src/map/scl/sclTime.c
index 66a28b51..4e3b3de8 100644
--- a/src/map/scl/sclTime.c
+++ b/src/map/scl/sclTime.c
@@ -109,6 +109,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise
{
printf( "%7d : ", Abc_ObjId(pObj) );
printf( "%d ", Abc_ObjFaninNum(pObj) );
+ printf( "%d ", Abc_ObjFanoutNum(pObj) );
printf( "%-*s ", Length, Abc_SclObjCell(p, pObj)->pName );
if ( fRise >= 0 )
printf( "(%s) ", fRise ? "rise" : "fall" );
diff --git a/src/misc/util/abc_global.h b/src/misc/util/abc_global.h
index 03474a04..3259fa0d 100644
--- a/src/misc/util/abc_global.h
+++ b/src/misc/util/abc_global.h
@@ -52,9 +52,11 @@
#endif
// catch memory leaks in Visual Studio
-#ifdef _DEBUG
-#define _CRTDBG_MAP_ALLOC
-#include <crtdbg.h>
+#ifdef WIN32
+ #ifdef _DEBUG
+ #define _CRTDBG_MAP_ALLOC
+ #include <crtdbg.h>
+ #endif
#endif
#if !defined(___unused)
diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h
new file mode 100644
index 00000000..6bfb5699
--- /dev/null
+++ b/src/misc/util/utilTruth.h
@@ -0,0 +1,422 @@
+/**CFile****************************************************************
+
+ FileName [utilTruth.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Truth table manipulation.]
+
+ Synopsis [Truth table manipulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - October 28, 2012.]
+
+ Revision [$Id: utilTruth.h,v 1.00 2012/10/28 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__misc__util__utilTruth_h
+#define ABC__misc__util__utilTruth_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+static word s_Truths6[6] = {
+ 0xAAAAAAAAAAAAAAAA,
+ 0xCCCCCCCCCCCCCCCC,
+ 0xF0F0F0F0F0F0F0F0,
+ 0xFF00FF00FF00FF00,
+ 0xFFFF0000FFFF0000,
+ 0xFFFFFFFF00000000
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Abc_TtWordNum( int nVars ) { return nVars <= 6 ? 1 : 1 << (nVars-6); }
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Abc_TtCopy( word * pOut, word * pIn, int nWords, int fCompl )
+{
+ int w;
+ if ( fCompl )
+ for ( w = 0; w < nWords; w++ )
+ pOut[w] = ~pIn[w];
+ else
+ for ( w = 0; w < nWords; w++ )
+ pOut[w] = pIn[w];
+}
+static inline void Abc_TtAnd( word * pOut, word * pIn1, word * pIn2, int nWords, int fCompl )
+{
+ int w;
+ if ( fCompl )
+ for ( w = 0; w < nWords; w++ )
+ pOut[w] = ~(pIn1[w] & pIn2[w]);
+ else
+ for ( w = 0; w < nWords; w++ )
+ pOut[w] = pIn1[w] & pIn2[w];
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Abc_TtSuppIsMinBase( int Supp )
+{
+ return (Supp & (Supp+1)) == 0;
+}
+static inline int Abc_Tt6HasVar( word t, int iVar )
+{
+ return ((t << (1<<iVar)) & s_Truths6[iVar]) != (t & s_Truths6[iVar]);
+}
+static inline int Abc_TtHasVar( word * t, int nVars, int iVar )
+{
+ int nWords = Abc_TtWordNum( nVars );
+ assert( iVar < nVars );
+ if ( iVar < 6 )
+ {
+ int i, Shift = (1 << iVar);
+ for ( i = 0; i < nWords; i++ )
+ if ( ((t[i] << Shift) & s_Truths6[iVar]) != (t[i] & s_Truths6[iVar]) )
+ return 1;
+ return 0;
+ }
+ else
+ {
+ int i, Step = (1 << (iVar - 6));
+ word * tLimit = t + nWords;
+ for ( ; t < tLimit; t += 2*Step )
+ for ( i = 0; i < Step; i++ )
+ if ( t[i] != t[Step+i] )
+ return 1;
+ return 0;
+ }
+}
+static inline int Abc_TtSupport( word * t, int nVars )
+{
+ int v, Supp = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtHasVar( t, nVars, v ) )
+ Supp |= (1 << v);
+ return Supp;
+}
+static inline int Abc_TtSupportSize( word * t, int nVars )
+{
+ int v, SuppSize = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtHasVar( t, nVars, v ) )
+ SuppSize++;
+ return SuppSize;
+}
+static inline int Abc_TtSupportAndSize( word * t, int nVars, int * pSuppSize )
+{
+ int v, Supp = 0;
+ *pSuppSize = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtHasVar( t, nVars, v ) )
+ Supp |= (1 << v), (*pSuppSize)++;
+ return Supp;
+}
+static inline int Abc_Tt6SupportAndSize( word t, int nVars, int * pSuppSize )
+{
+ int v, Supp = 0;
+ *pSuppSize = 0;
+ assert( nVars <= 6 );
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_Tt6HasVar( t, v ) )
+ Supp |= (1 << v), (*pSuppSize)++;
+ return Supp;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Abc_TtSwapVars( word * pTruth, int nVars, int iVar, int jVar )
+{
+ static word PPMasks[5][6][3] = {
+ {
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 0 0
+ { 0x9999999999999999, 0x2222222222222222, 0x4444444444444444 }, // 0 1
+ { 0xA5A5A5A5A5A5A5A5, 0x0A0A0A0A0A0A0A0A, 0x5050505050505050 }, // 0 2
+ { 0xAA55AA55AA55AA55, 0x00AA00AA00AA00AA, 0x5500550055005500 }, // 0 3
+ { 0xAAAA5555AAAA5555, 0x0000AAAA0000AAAA, 0x5555000055550000 }, // 0 4
+ { 0xAAAAAAAA55555555, 0x00000000AAAAAAAA, 0x5555555500000000 } // 0 5
+ },
+ {
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 1 0
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 1 1
+ { 0xC3C3C3C3C3C3C3C3, 0x0C0C0C0C0C0C0C0C, 0x3030303030303030 }, // 1 2
+ { 0xCC33CC33CC33CC33, 0x00CC00CC00CC00CC, 0x3300330033003300 }, // 1 3
+ { 0xCCCC3333CCCC3333, 0x0000CCCC0000CCCC, 0x3333000033330000 }, // 1 4
+ { 0xCCCCCCCC33333333, 0x00000000CCCCCCCC, 0x3333333300000000 } // 1 5
+ },
+ {
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 2 0
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 2 1
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 2 2
+ { 0xF00FF00FF00FF00F, 0x00F000F000F000F0, 0x0F000F000F000F00 }, // 2 3
+ { 0xF0F00F0FF0F00F0F, 0x0000F0F00000F0F0, 0x0F0F00000F0F0000 }, // 2 4
+ { 0xF0F0F0F00F0F0F0F, 0x00000000F0F0F0F0, 0x0F0F0F0F00000000 } // 2 5
+ },
+ {
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 3 0
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 3 1
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 3 2
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 3 3
+ { 0xFF0000FFFF0000FF, 0x0000FF000000FF00, 0x00FF000000FF0000 }, // 3 4
+ { 0xFF00FF0000FF00FF, 0x00000000FF00FF00, 0x00FF00FF00000000 } // 3 5
+ },
+ {
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 4 0
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 4 1
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 4 2
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 4 3
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, // 4 4
+ { 0xFFFF00000000FFFF, 0x00000000FFFF0000, 0x0000FFFF00000000 } // 4 5
+ }
+ };
+ if ( iVar == jVar )
+ return;
+ if ( jVar < iVar )
+ ABC_SWAP( int, iVar, jVar );
+ assert( iVar < jVar && jVar < nVars );
+ if ( nVars <= 6 )
+ {
+ word * pMasks = PPMasks[iVar][jVar];
+ int shift = (1 << jVar) - (1 << iVar);
+ pTruth[0] = (pTruth[0] & pMasks[0]) | ((pTruth[0] & pMasks[1]) << shift) | ((pTruth[0] & pMasks[2]) >> shift);
+ }
+ else
+ {
+ if ( jVar <= 5 )
+ {
+ word * pMasks = PPMasks[iVar][jVar];
+ int nWords = Abc_TtWordNum(nVars);
+ int w, shift = (1 << jVar) - (1 << iVar);
+ for ( w = 0; w < nWords; w++ )
+ pTruth[w] = (pTruth[w] & pMasks[0]) | ((pTruth[w] & pMasks[1]) << shift) | ((pTruth[w] & pMasks[2]) >> shift);
+ }
+ else if ( iVar <= 5 && jVar > 5 )
+ {
+ word low2High, high2Low;
+ word * pLimit = pTruth + Abc_TtWordNum(nVars);
+ int j, jStep = Abc_TtWordNum(jVar);
+ int shift = 1 << iVar;
+ for ( ; pTruth < pLimit; pTruth += 2*jStep )
+ for ( j = 0; j < jStep; j++ )
+ {
+ low2High = (pTruth[j] & s_Truths6[iVar]) >> shift;
+ high2Low = (pTruth[j+jStep] << shift) & s_Truths6[iVar];
+ pTruth[j] = (pTruth[j] & ~s_Truths6[iVar]) | high2Low;
+ pTruth[j+jStep] = (pTruth[j+jStep] & s_Truths6[iVar]) | low2High;
+ }
+ }
+ else
+ {
+ word temp, * pLimit = pTruth + Abc_TtWordNum(nVars);
+ int i, iStep = Abc_TtWordNum(iVar);
+ int j, jStep = Abc_TtWordNum(jVar);
+ for ( ; pTruth < pLimit; pTruth += 2*jStep )
+ for ( i = 0; i < jStep; i += 2*iStep )
+ for ( j = 0; j < iStep; j++ )
+ {
+ temp = pTruth[iStep + i + j];
+ pTruth[iStep + i + j] = pTruth[jStep + i + j];
+ pTruth[jStep + i + j] = temp;
+ }
+ }
+ }
+}
+
+static inline void Abc_TtSwapVars_( word * pTruth, int nVars, int iVar, int jVar )
+{
+ static word PPMasks[6][6] = {
+ { 0x2222222222222222, 0x0A0A0A0A0A0A0A0A, 0x00AA00AA00AA00AA, 0x0000AAAA0000AAAA, 0x00000000AAAAAAAA, 0xAAAAAAAAAAAAAAAA },
+ { 0x0000000000000000, 0x0C0C0C0C0C0C0C0C, 0x00CC00CC00CC00CC, 0x0000CCCC0000CCCC, 0x00000000CCCCCCCC, 0xCCCCCCCCCCCCCCCC },
+ { 0x0000000000000000, 0x0000000000000000, 0x00F000F000F000F0, 0x0000F0F00000F0F0, 0x00000000F0F0F0F0, 0xF0F0F0F0F0F0F0F0 },
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000FF000000FF00, 0x00000000FF00FF00, 0xFF00FF00FF00FF00 },
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x00000000FFFF0000, 0xFFFF0000FFFF0000 },
+ { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000 }
+ };
+ if ( nVars <= 6 )
+ {
+ int shift;
+ word low2High, high2Low;
+ assert( iVar <= 5 && jVar <= 5 && iVar < jVar );
+ shift = (1 << jVar) - (1 << iVar);
+ low2High = (pTruth[0] & PPMasks[iVar][jVar - 1] ) << shift;
+ pTruth[0] &= ~PPMasks[iVar][jVar - 1];
+ high2Low = (pTruth[0] & (PPMasks[iVar][jVar - 1] << shift )) >> shift;
+ pTruth[0] &= ~(PPMasks[iVar][jVar - 1] << shift);
+ pTruth[0] |= low2High | high2Low;
+ }
+ else
+ {
+ word low2High, high2Low, temp;
+ int nWords = Abc_TtWordNum(nVars);
+ int shift, step, iStep, jStep;
+ int w = 0, i = 0, j = 0;
+ if ( iVar == jVar )
+ return;
+ if ( jVar < iVar )
+ ABC_SWAP( int, iVar, jVar );
+ if ( iVar <= 5 && jVar <= 5 )
+ {
+ shift = (1 << jVar) - (1 << iVar);
+ for ( w = 0; w < nWords; w++ )
+ {
+ low2High = (pTruth[w] & PPMasks[iVar][jVar - 1] ) << shift;
+ pTruth[w] &= ~PPMasks[iVar][jVar - 1];
+ high2Low = (pTruth[w] & (PPMasks[iVar][jVar - 1] << shift )) >> shift;
+ pTruth[w] &= ~(PPMasks[iVar][jVar - 1] << shift);
+ pTruth[w] |= low2High | high2Low;
+ }
+ }
+ else if ( iVar <= 5 && jVar > 5 )
+ {
+ step = Abc_TtWordNum(jVar + 1)/2;
+ shift = 1 << iVar;
+ for ( w = 0; w < nWords; w += 2*step )
+ {
+ for (j = 0; j < step; j++)
+ {
+ low2High = (pTruth[w + j] & PPMasks[iVar][5]) >> shift;
+ pTruth[w + j] &= ~PPMasks[iVar][5];
+ high2Low = (pTruth[w + step + j] & (PPMasks[iVar][5] >> shift)) << shift;
+ pTruth[w + step + j] &= ~(PPMasks[iVar][5] >> shift);
+ pTruth[w + j] |= high2Low;
+ pTruth[w + step + j] |= low2High;
+ }
+ }
+ }
+ else
+ {
+ iStep = Abc_TtWordNum(iVar + 1)/2;
+ jStep = Abc_TtWordNum(jVar + 1)/2;
+ for (w = 0; w < nWords; w += 2*jStep)
+ {
+ for (i = 0; i < jStep; i += 2*iStep)
+ {
+ for (j = 0; j < iStep; j++)
+ {
+ temp = pTruth[w + iStep + i + j];
+ pTruth[w + iStep + i + j] = pTruth[w + jStep + i + j];
+ pTruth[w + jStep + i + j] = temp;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Stretch truthtable to have more input variables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Abc_TtStretch5( unsigned * pInOut, int nVarS, int nVarB )
+{
+ int w, i, step, nWords;
+ if ( nVarS == nVarB )
+ return;
+ assert( nVarS < nVarB );
+ step = Abc_TruthWordNum(nVarS);
+ nWords = Abc_TruthWordNum(nVarB);
+ if ( step == nWords )
+ return;
+ assert( step < nWords );
+ for ( w = 0; w < nWords; w += step )
+ for ( i = 0; i < step; i++ )
+ pInOut[w + i] = pInOut[i];
+}
+static void Abc_TtStretch6( word * pInOut, int nVarS, int nVarB )
+{
+ int w, i, step, nWords;
+ if ( nVarS == nVarB )
+ return;
+ assert( nVarS < nVarB );
+ step = Abc_Truth6WordNum(nVarS);
+ nWords = Abc_Truth6WordNum(nVarB);
+ if ( step == nWords )
+ return;
+ assert( step < nWords );
+ for ( w = 0; w < nWords; w += step )
+ for ( i = 0; i < step; i++ )
+ pInOut[w + i] = pInOut[i];
+}
+
+/*=== utilTruth.c ===========================================================*/
+
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/misc/vec/vecMem.h b/src/misc/vec/vecMem.h
index 229c53a2..eaa9481f 100644
--- a/src/misc/vec/vecMem.h
+++ b/src/misc/vec/vecMem.h
@@ -57,14 +57,16 @@ struct Vec_Mem_t_
int nPageAlloc; // number of pages currently allocated
int iPage; // the number of a page currently used
word ** ppPages; // memory pages
+ Vec_Int_t * vTable; // hash table
+ Vec_Int_t * vNexts; // next pointers
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
-#define Vec_MemForEachEntry( vVec, pEntry, i ) \
- for ( i = 0; (i < Vec_MemEntryNum(vVec)) && ((pEntry) = Vec_MemReadEntry(vVec, i)); i++ )
+#define Vec_MemForEachEntry( p, pEntry, i ) \
+ for ( i = 0; (i < Vec_MemEntryNum(p)) && ((pEntry) = Vec_MemReadEntry(p, i)); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -266,12 +268,12 @@ static inline void Vec_MemShrink( Vec_Mem_t * p, int nEntriesNew )
SeeAlso []
***********************************************************************/
-static inline void Vec_MemPrint( Vec_Mem_t * vVec )
+static inline void Vec_MemPrint( Vec_Mem_t * p )
{
word * pEntry;
int i;
- printf( "Memory vector has %d entries: ", Vec_MemEntryNum(vVec) );
- Vec_MemForEachEntry( vVec, pEntry, i )
+ printf( "Memory vector has %d entries: ", Vec_MemEntryNum(p) );
+ Vec_MemForEachEntry( p, pEntry, i )
{
printf( "%3d : ", i );
// add printout here
@@ -279,6 +281,76 @@ static inline void Vec_MemPrint( Vec_Mem_t * vVec )
}
}
+/**Function*************************************************************
+
+ Synopsis [Hashing entries in the memory vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_MemHashAlloc( Vec_Mem_t * p, int nTableSize )
+{
+ assert( p->vTable == NULL && p->vNexts == NULL );
+ p->vTable = Vec_IntStartFull( Abc_PrimeCudd(nTableSize) );
+ p->vNexts = Vec_IntAlloc( nTableSize );
+}
+static inline void Vec_MemHashFree( Vec_Mem_t * p )
+{
+ Vec_IntFreeP( &p->vTable );
+ Vec_IntFreeP( &p->vNexts );
+}
+static inline unsigned Vec_MemHashKey( Vec_Mem_t * p, word * pEntry )
+{
+ static int s_Primes[8] = { 1699, 4177, 5147, 5647, 6343, 7103, 7873, 8147 };
+ int i, nData = 2 * p->nEntrySize;
+ unsigned * pData = (unsigned *)pEntry;
+ unsigned uHash = 0;
+ for ( i = 0; i < nData; i++ )
+ uHash += pData[i] * s_Primes[i & 0x7];
+ return uHash % Vec_IntSize(p->vTable);
+}
+static int * Vec_MemHashLookup( Vec_Mem_t * p, word * pEntry )
+{
+ int * pSpot = Vec_IntEntryP( p->vTable, Vec_MemHashKey(p, pEntry) );
+ for ( ; *pSpot != -1; pSpot = Vec_IntEntryP(p->vNexts, *pSpot) )
+ if ( !memcmp( Vec_MemReadEntry(p, *pSpot), pEntry, sizeof(word) * p->nEntrySize ) ) // equal
+ return pSpot;
+ return pSpot;
+}
+static void Vec_MemHashResize( Vec_Mem_t * p )
+{
+ word * pEntry;
+ int i, * pSpot;
+ Vec_IntFill( p->vTable, Abc_PrimeCudd(2 * Vec_IntSize(p->vTable)), -1 );
+ Vec_IntClear( p->vNexts );
+ Vec_MemForEachEntry( p, pEntry, i )
+ {
+ pSpot = Vec_MemHashLookup( p, pEntry );
+ assert( *pSpot == -1 );
+ *pSpot = Vec_IntSize(p->vNexts);
+ Vec_IntPush( p->vNexts, -1 );
+ }
+ assert( p->nEntries == Vec_IntSize(p->vNexts) );
+}
+static int Vec_MemHashInsert( Vec_Mem_t * p, word * pEntry )
+{
+ int * pSpot;
+ if ( p->nEntries > Vec_IntSize(p->vTable) )
+ Vec_MemHashResize( p );
+ pSpot = Vec_MemHashLookup( p, pEntry );
+ if ( *pSpot != -1 )
+ return *pSpot;
+ *pSpot = Vec_IntSize(p->vNexts);
+ Vec_IntPush( p->vNexts, -1 );
+ Vec_MemPush( p, pEntry );
+ assert( p->nEntries == Vec_IntSize(p->vNexts) );
+ return Vec_IntSize(p->vNexts) - 1;
+}
+
ABC_NAMESPACE_HEADER_END
diff --git a/src/opt/dau/dauDsd.c b/src/opt/dau/dauDsd.c
index 6f970b62..f6367304 100644
--- a/src/opt/dau/dauDsd.c
+++ b/src/opt/dau/dauDsd.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "dauInt.h"
+#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@@ -443,7 +444,7 @@ void Dau_DsdTestOne( word t, int i )
{
word t2;
char * p = Dau_DsdPerform( t );
-// return;
+ return;
t2 = Dau_DsdToTruth( p );
if ( t != t2 )
{
@@ -463,6 +464,344 @@ void Dau_DsdTestOne( word t, int i )
Dau_DsdTestOne( *p->pFuncs[i], i );
*/
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Abc_TtTruthIsConst0( word * p, int nWords ) { int w; for ( w = 0; w < nWords; w++ ) if ( p[w] != 0 ) return 0; return 1; }
+static inline int Abc_TtTruthIsConst1( word * p, int nWords ) { int w; for ( w = 0; w < nWords; w++ ) if ( p[w] != ~(word)0 ) return 0; return 1; }
+
+static inline int Abc_TtCof0IsConst0( word * t, int nWords, int iVar )
+{
+ if ( iVar < 6 )
+ {
+ int i;
+ for ( i = 0; i < nWords; i++ )
+ if ( t[i] & ~s_Truths6[iVar] )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ int i, Step = (1 << (iVar - 6));
+ word * tLimit = t + nWords;
+ for ( ; t < tLimit; t += 2*Step )
+ for ( i = 0; i < Step; i++ )
+ if ( t[i] )
+ return 0;
+ return 1;
+ }
+}
+static inline int Abc_TtCof0IsConst1( word * t, int nWords, int iVar )
+{
+ if ( iVar < 6 )
+ {
+ int i;
+ for ( i = 0; i < nWords; i++ )
+ if ( (t[i] & ~s_Truths6[iVar]) != ~s_Truths6[iVar] )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ int i, Step = (1 << (iVar - 6));
+ word * tLimit = t + nWords;
+ for ( ; t < tLimit; t += 2*Step )
+ for ( i = 0; i < Step; i++ )
+ if ( t[i] != ~(word)0 )
+ return 0;
+ return 1;
+ }
+}
+static inline int Abc_TtCof1IsConst0( word * t, int nWords, int iVar )
+{
+ if ( iVar < 6 )
+ {
+ int i;
+ for ( i = 0; i < nWords; i++ )
+ if ( t[i] & s_Truths6[iVar] )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ int i, Step = (1 << (iVar - 6));
+ word * tLimit = t + nWords;
+ for ( ; t < tLimit; t += 2*Step )
+ for ( i = 0; i < Step; i++ )
+ if ( t[i+Step] )
+ return 0;
+ return 1;
+ }
+}
+static inline int Abc_TtCof1IsConst1( word * t, int nWords, int iVar )
+{
+ if ( iVar < 6 )
+ {
+ int i;
+ for ( i = 0; i < nWords; i++ )
+ if ( (t[i] & s_Truths6[iVar]) != s_Truths6[iVar] )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ int i, Step = (1 << (iVar - 6));
+ word * tLimit = t + nWords;
+ for ( ; t < tLimit; t += 2*Step )
+ for ( i = 0; i < Step; i++ )
+ if ( t[i+Step] != ~(word)0 )
+ return 0;
+ return 1;
+ }
+}
+static inline int Abc_TtCofsOpposite( word * t, int nWords, int iVar )
+{
+ if ( iVar < 6 )
+ {
+ int i, Shift = (1 << iVar);
+ for ( i = 0; i < nWords; i++ )
+ if ( ((t[i] << Shift) & s_Truths6[iVar]) != (~t[i] & s_Truths6[iVar]) )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ int i, Step = (1 << (iVar - 6));
+ word * tLimit = t + nWords;
+ for ( ; t < tLimit; t += 2*Step )
+ for ( i = 0; i < Step; i++ )
+ if ( t[i] != ~t[i+Step] )
+ return 0;
+ return 1;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Abc_TtCof0HasVar( word * t, int nWords, int iVarI, int iVarJ )
+{
+ assert( iVarI > iVarJ );
+ if ( iVarI < 6 )
+ {
+ int i, Shift = (1 << iVarJ);
+ for ( i = 0; i < nWords; i++ )
+ if ( (((t[i] & ~s_Truths6[iVarI]) << Shift) & s_Truths6[iVarJ]) != ((t[i] & ~s_Truths6[iVarI]) & s_Truths6[iVarJ]) )
+ return 0;
+ return 1;
+ }
+ else if ( iVarI == 6 )
+ {
+ }
+ else
+ {
+ int i, Step = (1 << (iVarJ - 6));
+ word * tLimit = t + nWords;
+ for ( ; t < tLimit; t += 2*Step )
+ for ( i = 0; i < Step; i++ )
+ if ( t[i] != t[i+Step] )
+ return 0;
+ return 1;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Dau_DsdMinimize( word * p, int * pVars, int nVars )
+{
+ int i, k;
+ assert( nVars > 6 );
+ for ( i = k = nVars - 1; i >= 0; i-- )
+ {
+ if ( Abc_TtHasVar( p, nVars, i ) )
+ continue;
+ if ( i < k )
+ {
+ pVars[i] = pVars[k];
+ Abc_TtSwapVars( p, nVars, i, k );
+ }
+ k--;
+ nVars--;
+ }
+ return nVars;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Dau_DsdRun6_rec( word * p, int * pVars, int nVars, char * pBuffer, int Pos, char pStore[16][16], int Func )
+{
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Dau_DsdRun_rec( word * p, int * pVars, int nVars, char * pBuffer, int Pos, char pStore[16][16], int Func )
+{
+ int v, nWords = Abc_TtWordNum( nVars );
+ nVars = Dau_DsdMinimize( p, pVars, nVars );
+ if ( nVars <= 6 )
+ return Dau_DsdRun6_rec( p, pVars, nVars, pBuffer, Pos, pStore, Func );
+ if ( p[0] & 1 )
+ {
+ // check for !(ax)
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtCof0IsConst0( p, nWords, v ) )
+ {
+ pBuffer[Pos++] = '(';
+ pBuffer[Pos++] = 'a' + pVars[v];
+ Abc_TtSwapVars( p, nVars, v, nVars - 1 );
+ pVars[v] = pVars[nVars-1];
+ Pos = Dau_DsdRun_rec( p + nWords/2, pVars, nVars-1, pBuffer, Pos, pStore, Func );
+ pBuffer[Pos++] = ')';
+ return Pos;
+ }
+ }
+ else
+ {
+ // check for ax
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtCof0IsConst1( p, nWords, v ) )
+ {
+ pBuffer[Pos++] = '!';
+ pBuffer[Pos++] = '(';
+ pBuffer[Pos++] = 'a' + pVars[v];
+ Abc_TtSwapVars( p, nVars, v, nVars - 1 );
+ pVars[v] = pVars[nVars-1];
+ Pos = Dau_DsdRun_rec( p + nWords/2, pVars, nVars-1, pBuffer, Pos, pStore, Func );
+ pBuffer[Pos++] = ')';
+ return Pos;
+ }
+ }
+ if ( (p[nWords-1] >> 63) & 1 )
+ {
+ // check for !(!ax)
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtCof0IsConst1( p, nWords, v ) )
+ {
+ pBuffer[Pos++] = '!';
+ pBuffer[Pos++] = '(';
+ pBuffer[Pos++] = '!';
+ pBuffer[Pos++] = 'a' + pVars[v];
+ Abc_TtSwapVars( p, nVars, v, nVars - 1 );
+ pVars[v] = pVars[nVars-1];
+ Pos = Dau_DsdRun_rec( p, pVars, nVars-1, pBuffer, Pos, pStore, Func );
+ pBuffer[Pos++] = ')';
+ return Pos;
+ }
+ }
+ else
+ {
+ // check for !ax
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtCof1IsConst0( p, nWords, v ) )
+ {
+ pBuffer[Pos++] = '(';
+ pBuffer[Pos++] = '!';
+ pBuffer[Pos++] = 'a' + pVars[v];
+ Abc_TtSwapVars( p, nVars, v, nVars - 1 );
+ pVars[v] = pVars[nVars-1];
+ Pos = Dau_DsdRun_rec( p, pVars, nVars-1, pBuffer, Pos, pStore, Func );
+ pBuffer[Pos++] = ')';
+ return Pos;
+ }
+ }
+ // check for a^x
+ for ( v = 0; v < nVars; v++ )
+ if ( Abc_TtCofsOpposite( p, nWords, v ) )
+ {
+ pBuffer[Pos++] = '[';
+ pBuffer[Pos++] = 'a' + pVars[v];
+ Abc_TtSwapVars( p, nVars, v, nVars - 1 );
+ pVars[v] = pVars[nVars-1];
+ Pos = Dau_DsdRun_rec( p, pVars, nVars-1, pBuffer, Pos, pStore, Func );
+ pBuffer[Pos++] = ']';
+ return Pos;
+ }
+
+ return 0;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Dau_DsdRun( word * p, int nVars )
+{
+ static char pBuffer[DAU_MAX_STR+20];
+ static char pStore[16][16];
+ int nWords = Abc_TtWordNum( nVars );
+ int i, Pos = 0, Func = 0, pVars[16];
+ assert( nVars <= 16 );
+ for ( i = 0; i < nVars; i++ )
+ pVars[i] = i;
+ if ( Abc_TtTruthIsConst0( p, nWords ) )
+ pBuffer[Pos++] = '0';
+ else if ( Abc_TtTruthIsConst1( p, nWords ) )
+ pBuffer[Pos++] = '1';
+ else if ( nVars <= 6 )
+ Pos = Dau_DsdRun6_rec( p, pVars, nVars, pBuffer, Pos, pStore, Func );
+ else
+ Pos = Dau_DsdRun_rec( p, pVars, nVars, pBuffer, Pos, pStore, Func );
+ pBuffer[Pos++] = 0;
+ Dau_DsdCleanBraces( pBuffer );
+ return pBuffer;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/opt/dau/dauEnum.c b/src/opt/dau/dauEnum.c
new file mode 100644
index 00000000..58e44c02
--- /dev/null
+++ b/src/opt/dau/dauEnum.c
@@ -0,0 +1,253 @@
+/**CFile****************************************************************
+
+ FileName [dauEnum.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [DAG-aware unmapping.]
+
+ Synopsis [Enumeration of decompositions.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: dauEnum.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "dauInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Dau_EnumLift( char * pName, int Shift )
+{
+ static char pBuffer[64];
+ char * pTemp;
+ for ( pTemp = pBuffer; *pName; pTemp++, pName++ )
+ *pTemp = (*pName >= 'a' && *pName <= 'z') ? *pName + Shift : *pName;
+ *pTemp = 0;
+ return pBuffer;
+}
+char * Dau_EnumLift2( char * pName, int Shift )
+{
+ static char pBuffer[64];
+ char * pTemp;
+ for ( pTemp = pBuffer; *pName; pTemp++, pName++ )
+ *pTemp = (*pName >= 'a' && *pName <= 'z') ? *pName + Shift : *pName;
+ *pTemp = 0;
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Dau_EnumCombineTwo( Vec_Ptr_t * vOne, int fStar, int fXor, char * pName1, char * pName2, int Shift2, int fCompl1, int fCompl2 )
+{
+ static char pBuffer[256];
+ pName2 = Dau_EnumLift( pName2, Shift2 );
+ sprintf( pBuffer, "%s%c%s%s%s%s%c",
+ fStar?"*":"",
+ fXor?'[':'(',
+ fCompl1?"!":"", pName1[0] == '*' ? pName1 + 1 : pName1,
+ fCompl2?"!":"", pName2[0] == '*' ? pName2 + 1 : pName2,
+ fXor?']':')' );
+// printf( "%s ", pBuffer );
+ Vec_PtrPush( vOne, Abc_UtilStrsav(pBuffer) );
+}
+void Dau_EnumCombineThree( Vec_Ptr_t * vOne, int fStar, char * pNameC, char * pName1, char * pName2, int Shift1, int Shift2, int fComplC, int fCompl1, int fCompl2 )
+{
+ static char pBuffer[256];
+ pName1 = Dau_EnumLift( pName1, Shift1 );
+ pName2 = Dau_EnumLift2( pName2, Shift2 );
+ sprintf( pBuffer, "%s%c%s%s%s%s%s%s%c",
+ fStar?"*":"",
+ '<',
+ fComplC?"!":"", pNameC[0] == '*' ? pNameC + 1 : pNameC,
+ fCompl1?"!":"", pName1[0] == '*' ? pName1 + 1 : pName1,
+ fCompl2?"!":"", pName2[0] == '*' ? pName2 + 1 : pName2,
+ '>' );
+// printf( "%s ", pBuffer );
+ Vec_PtrPush( vOne, Abc_UtilStrsav(pBuffer) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Dau_EnumTestDump( Vec_Ptr_t * vSets, char * pFileName )
+{
+ FILE * pFile;
+ Vec_Ptr_t * vOne;
+ char * pName;
+ int v, k;
+ pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ return;
+ Vec_PtrForEachEntry( Vec_Ptr_t *, vSets, vOne, v )
+ {
+ fprintf( pFile, "VARIABLE NUMBER %d:\n", v );
+ Vec_PtrForEachEntry( char *, vOne, pName, k )
+ fprintf( pFile, "%s\n", pName );
+ }
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Dau_EnumTest()
+{
+ int v, k, nVarMax = 10;
+ Vec_Ptr_t * vSets;
+ Vec_Ptr_t * vOne;
+ char * pName;
+ // 0 vars
+ vSets = Vec_PtrAlloc( 16 );
+ Vec_PtrPush( vSets, Vec_PtrAlloc(0) );
+ // 1 vars
+ vOne = Vec_PtrAlloc( 1 );
+ Vec_PtrPush( vOne, Abc_UtilStrsav("*a") );
+ Vec_PtrPush( vSets, vOne );
+ // 2+ vars
+ for ( v = 2; v <= nVarMax; v++ )
+ {
+ Vec_Ptr_t * vSetI, * vSetJ, * vSetK;
+ char * pNameI, * pNameJ, * pNameK;
+ int i, j, k, i1, j1, k1;
+ vOne = Vec_PtrAlloc( 100 );
+ for ( i = 1; i < v; i++ )
+ for ( j = i; j < v; j++ )
+ {
+ if ( i + j != v )
+ continue;
+ vSetI = (Vec_Ptr_t *)Vec_PtrEntry( vSets, i );
+ vSetJ = (Vec_Ptr_t *)Vec_PtrEntry( vSets, j );
+ Vec_PtrForEachEntry( char *, vSetI, pNameI, i1 )
+ Vec_PtrForEachEntry( char *, vSetJ, pNameJ, j1 )
+ {
+ // AND(a,b)
+ Dau_EnumCombineTwo( vOne, 0, 0, pNameI, pNameJ, i, 0, 0 );
+ // AND(!a,b)
+ if ( pNameI[0] != '*' )
+ Dau_EnumCombineTwo( vOne, 0, 0, pNameI, pNameJ, i, 1, 0 );
+ // AND(a,!b)
+ if ( pNameJ[0] != '*' && !(i == j && i1 == j1) )
+ Dau_EnumCombineTwo( vOne, 0, 0, pNameI, pNameJ, i, 0, 1 );
+ // AND(!a,!b)
+ if ( pNameI[0] != '*' && pNameJ[0] != '*' )
+ Dau_EnumCombineTwo( vOne, 0, 0, pNameI, pNameJ, i, 1, 1 );
+ // XOR(a,b)
+ Dau_EnumCombineTwo( vOne, pNameI[0] == '*' || pNameJ[0] == '*', 1, pNameI, pNameJ, i, 0, 0 );
+ }
+ }
+ for ( k = 1; k < v; k++ )
+ for ( i = 1; i < v; i++ )
+ for ( j = i; j < v; j++ )
+ {
+ if ( k + i + j != v )
+ continue;
+ vSetK = (Vec_Ptr_t *)Vec_PtrEntry( vSets, k );
+ vSetI = (Vec_Ptr_t *)Vec_PtrEntry( vSets, i );
+ vSetJ = (Vec_Ptr_t *)Vec_PtrEntry( vSets, j );
+ Vec_PtrForEachEntry( char *, vSetK, pNameK, k1 )
+ Vec_PtrForEachEntry( char *, vSetI, pNameI, i1 )
+ Vec_PtrForEachEntry( char *, vSetJ, pNameJ, j1 )
+ {
+ int fStar = pNameI[0] == '*' && pNameJ[0] == '*';
+
+ // MUX(c,a,b)
+ Dau_EnumCombineThree( vOne, fStar, pNameK, pNameI, pNameJ, k, k+i, 0, 0, 0 );
+ // MUX(c,!a,b)
+ if ( pNameI[0] != '*' )
+ Dau_EnumCombineThree( vOne, fStar, pNameK, pNameI, pNameJ, k, k+i, 0, 1, 0 );
+ // MUX(c,a,!b)
+ if ( pNameJ[0] != '*' && !(i == j && i1 == j1) )
+ Dau_EnumCombineThree( vOne, fStar, pNameK, pNameI, pNameJ, k, k+i, 0, 0, 1 );
+
+ if ( pNameK[0] != '*' && !(i == j && i1 == j1) )
+ {
+ // MUX(!c,a,b)
+ Dau_EnumCombineThree( vOne, fStar, pNameK, pNameI, pNameJ, k, k+i, 1, 0, 0 );
+ // MUX(!c,!a,b)
+ if ( pNameI[0] != '*' )
+ Dau_EnumCombineThree( vOne, fStar, pNameK, pNameI, pNameJ, k, k+i, 1, 1, 0 );
+ // MUX(!c,a,!b)
+ if ( pNameJ[0] != '*' )
+ Dau_EnumCombineThree( vOne, fStar, pNameK, pNameI, pNameJ, k, k+i, 1, 0, 1 );
+ }
+ }
+ }
+ Vec_PtrPush( vSets, vOne );
+ }
+ Dau_EnumTestDump( vSets, "_npn/npn/dsd10.txt" );
+
+ Vec_PtrForEachEntry( Vec_Ptr_t *, vSets, vOne, v )
+ {
+ printf( "VARIABLE NUMBER %d:\n", v );
+ Vec_PtrForEachEntry( char *, vOne, pName, k )
+ printf( "%s\n", pName );
+ if ( v == 4 )
+ break;
+ }
+ Vec_PtrForEachEntry( Vec_Ptr_t *, vSets, vOne, v )
+ {
+ printf( "%d=%d ", v, Vec_PtrSize(vOne) );
+ Vec_PtrFreeFree( vOne );
+ }
+ Vec_PtrFree( vSets );
+ printf( "\n" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/opt/dau/module.make b/src/opt/dau/module.make
index c58d8807..87a800e9 100644
--- a/src/opt/dau/module.make
+++ b/src/opt/dau/module.make
@@ -1,3 +1,4 @@
SRC += src/opt/dau/dau.c \
src/opt/dau/dauCore.c \
- src/opt/dau/dauDsd.c
+ src/opt/dau/dauDsd.c \
+ src/opt/dau/dauEnum.c
diff --git a/src/opt/nwk/nwkMap.c b/src/opt/nwk/nwkMap.c
index e80c4c93..e8be5a2d 100644
--- a/src/opt/nwk/nwkMap.c
+++ b/src/opt/nwk/nwkMap.c
@@ -163,7 +163,6 @@ If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
// set up the choice node
if ( Aig_ObjIsChoice( p, pNode ) )
{
- pIfMan->nChoices++;
for ( pPrev = pNode, pFanin = Aig_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Aig_ObjEquiv(p, pFanin) )
If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData );
If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData );
diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h
index 10b06c28..65d2e24e 100644
--- a/src/proof/cec/cec.h
+++ b/src/proof/cec/cec.h
@@ -144,6 +144,7 @@ struct Cec_ParCor_t_
int fUseCSat; // use circuit-based solver
// int fFirstStop; // stop on the first sat output
int fUseSmartCnf; // use smart CNF computation
+ int fStopWhenGone; // quit when PO is not a candidate constant
int fVerboseFlops; // verbose stats
int fVeryVerbose; // verbose stats
int fVerbose; // verbose stats
diff --git a/src/proof/cec/cecCorr.c b/src/proof/cec/cecCorr.c
index f35cd952..f3a84d3a 100644
--- a/src/proof/cec/cecCorr.c
+++ b/src/proof/cec/cecCorr.c
@@ -753,6 +753,7 @@ void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIte
nFail++;
}
Abc_Print( 1, "p =%6d d =%6d f =%6d ", nProve, nDispr, nFail );
+ Abc_Print( 1, "%c ", Gia_ObjIsConst( p, Gia_ObjFaninId0p(p, Gia_ManPo(p, 0)) ) ? '+' : '-' );
Abc_PrintTime( 1, "T", Time );
}
@@ -950,6 +951,14 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
//Gia_ManEquivPrintClasses( pAig, 1, 0 );
if ( pPars->pFunc )
((int (*)(void *))pPars->pFunc)( pPars->pData );
+ // quit if const is no longer there
+ if ( pPars->fStopWhenGone && Gia_ManPoNum(pAig) == 1 && !Gia_ObjIsConst( pAig, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)) ) )
+ {
+ printf( "Iterative refinement is stopped after iteration %d\n", r );
+ printf( "because the property output is no longer a candidate constant.\n" );
+ Cec_ManSimStop( pSim );
+ return 0;
+ }
}
if ( pPars->fVerbose )
Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, clock() - clk );
@@ -1071,7 +1080,11 @@ Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
ABC_FREE( pAig->pReprs );
ABC_FREE( pAig->pNexts );
if ( pPars->nPrefix == 0 )
+ {
RetValue = Cec_ManLSCorrespondenceClasses( pAig, pPars );
+ if ( RetValue == 0 )
+ return Gia_ManDup( pAig );
+ }
else
{
// compute the cycles AIG
diff --git a/src/proof/dch/dchChoice.c b/src/proof/dch/dchChoice.c
index 783202e2..3f097ecc 100644
--- a/src/proof/dch/dchChoice.c
+++ b/src/proof/dch/dchChoice.c
@@ -95,7 +95,7 @@ int Dch_DeriveChoiceCountEquivs( Aig_Man_t * pAig )
pEquiv = Aig_ObjEquiv( pAig, pObj );
if ( pEquiv == NULL )
continue;
- assert( pEquiv->Id > pObj->Id );
+ assert( pEquiv->Id < pObj->Id );
nEquivs++;
}
return nEquivs;
diff --git a/src/proof/dch/dchCore.c b/src/proof/dch/dchCore.c
index 0d2e8c0d..b92de8a6 100644
--- a/src/proof/dch/dchCore.c
+++ b/src/proof/dch/dchCore.c
@@ -111,7 +111,9 @@ p->timeTotal = clock() - clkTotal;
pResult = Dch_DeriveChoiceAig( pAig, pPars->fSkipRedSupp );
// count the number of representatives
if ( pPars->fVerbose )
- Abc_Print( 1, "STATS: Reprs = %6d. Equivs = %6d. Choices = %6d.\n",
+ Abc_Print( 1, "STATS: Ands:%8d ->%8d. Reprs:%7d ->%7d. Choices =%7d.\n",
+ Aig_ManNodeNum(pAig),
+ Aig_ManNodeNum(pResult),
Dch_DeriveChoiceCountReprs( pAig ),
Dch_DeriveChoiceCountEquivs( pResult ),
Aig_ManChoiceNum( pResult ) );
diff --git a/src/proof/llb/llb4Map.c b/src/proof/llb/llb4Map.c
index 51f1fec6..4b46f308 100644
--- a/src/proof/llb/llb4Map.c
+++ b/src/proof/llb/llb4Map.c
@@ -48,7 +48,7 @@ Vec_Int_t * Llb_AigMap( Aig_Man_t * pAig, int nLutSize, int nLutMin )
{
extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
extern If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
- extern void Gia_ManSetIfParsDefault( If_Par_t * pPars );
+ extern void Gia_ManSetIfParsDefault( void * pPars );
If_Par_t Pars, * pPars = &Pars;
If_Man_t * pIfMan;
If_Obj_t * pAnd;
diff --git a/src/proof/ssw/ssw.h b/src/proof/ssw/ssw.h
index 35d41a35..df73c357 100644
--- a/src/proof/ssw/ssw.h
+++ b/src/proof/ssw/ssw.h
@@ -70,6 +70,7 @@ struct Ssw_Pars_t_
int fVerbose; // verbose stats
int fFlopVerbose; // verbose printout of redundant flops
int fEquivDump; // enables dumping equivalences
+ int fStopWhenGone; // stop when PO output is not a candidate constant
// optimized latch correspondence
int fLatchCorrOpt; // perform register correspondence (optimized)
int nSatVarMax; // max number of SAT vars before recycling SAT solver (optimized latch corr only)
diff --git a/src/proof/ssw/sswCore.c b/src/proof/ssw/sswCore.c
index 7e2e66da..7a9d4b9f 100644
--- a/src/proof/ssw/sswCore.c
+++ b/src/proof/ssw/sswCore.c
@@ -346,6 +346,24 @@ clk = clock();
}
// if ( p->pPars->fDynamic && p->nSatCallsSat-nSatCallsSat < 100 )
// p->pPars->nBTLimit = 10000;
+
+ if ( p->pPars->fStopWhenGone && Saig_ManPoNum(p->pAig) == 1 && !Ssw_ObjIsConst1Cand(p->pAig,Aig_ObjFanin0(Aig_ManCo(p->pAig,0))) )
+ {
+ printf( "Iterative refinement is stopped after iteration %d\n", nIter );
+ printf( "because the property output is no longer a candidate constant.\n" );
+ // prepare to quite
+ p->nLitsEnd = p->nLitsBeg;
+ p->nNodesEnd = p->nNodesBeg;
+ p->nRegsEnd = p->nRegsBeg;
+ // cleanup
+ Ssw_SatStop( p->pMSat );
+ p->pMSat = NULL;
+ Ssw_ManCleanup( p );
+ // cleanup
+ Aig_ManSetPhase( p->pAig );
+ Aig_ManCleanMarkB( p->pAig );
+ return Aig_ManDupSimple( p->pAig );
+ }
}
nSatProof = p->nSatProof;
nSatCallsSat = p->nSatCallsSat;