Merged alanmi/abc into default

This commit is contained in:
Mathias Soeken 2017-02-22 19:00:28 -08:00
commit 28e8e7f3e7
177 changed files with 26430 additions and 2073 deletions

View File

@ -52,9 +52,14 @@ build/
*.rej
*.orig
tags
syntax: regexp
^libabc.a$
^abc$
^arch_flags$
^cmake
^cscope

View File

@ -23,7 +23,7 @@ MODULES := \
src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \
src/sat/bsat src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \
src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \
src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \
src/bool/rsb src/bool/rpo \
src/proof/pdr src/proof/abs src/proof/live src/proof/ssc src/proof/int \
@ -139,6 +139,8 @@ OBJ := \
$(patsubst %.c, %.o, $(filter %.c, $(SRC))) \
$(patsubst %.y, %.o, $(filter %.y, $(SRC)))
LIBOBJ := $(filter-out src/base/main/main.o,$(OBJ))
DEP := $(OBJ:.o=.d)
# implicit rules
@ -186,11 +188,15 @@ $(PROG): $(OBJ)
@echo "$(MSG_PREFIX)\`\` Building binary:" $(notdir $@)
$(VERBOSE)$(LD) -o $@ $^ $(LIBS)
lib$(PROG).a: $(OBJ)
lib$(PROG).a: $(LIBOBJ)
@echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@)
$(VERBOSE)ar rv $@ $?
$(VERBOSE)ranlib $@
lib$(PROG).so: $(LIBOBJ)
@echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@)
$(VERBOSE)$(CXX) -shared -o $@ $^ $(LIBS)
docs:
@echo "$(MSG_PREFIX)\`\` Building documentation." $(notdir $@)
$(VERBOSE)doxygen doxygen.conf

View File

@ -523,6 +523,10 @@ SOURCE=.\src\base\cmd\cmdApi.c
# End Source File
# Begin Source File
SOURCE=.\src\base\cmd\cmdAuto.c
# End Source File
# Begin Source File
SOURCE=.\src\base\cmd\cmdFlag.c
# End Source File
# Begin Source File
@ -775,6 +779,10 @@ SOURCE=.\src\base\wlc\wlcAbs.c
# End Source File
# Begin Source File
SOURCE=.\src\base\wlc\wlcAbs2.c
# End Source File
# Begin Source File
SOURCE=.\src\base\wlc\wlcBlast.c
# End Source File
# Begin Source File
@ -799,6 +807,10 @@ SOURCE=.\src\base\wlc\wlcReadVer.c
# End Source File
# Begin Source File
SOURCE=.\src\base\wlc\wlcShow.c
# End Source File
# Begin Source File
SOURCE=.\src\base\wlc\wlcSim.c
# End Source File
# Begin Source File
@ -807,6 +819,10 @@ SOURCE=.\src\base\wlc\wlcStdin.c
# End Source File
# Begin Source File
SOURCE=.\src\base\wlc\wlcUif.c
# End Source File
# Begin Source File
SOURCE=.\src\base\wlc\wlcWin.c
# End Source File
# Begin Source File
@ -1938,6 +1954,142 @@ SOURCE=.\src\sat\bmc\bmcUnroll.c
# PROP Default_Filter ""
# End Group
# Begin Group "xsat"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\sat\xsat\xsat.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatBQueue.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatClause.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatCnfReader.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatHeap.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatMemory.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatSolver.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatSolver.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatSolverAPI.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatUtils.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\xsat\xsatWatchList.h
# End Source File
# End Group
# Begin Group "satoko"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\sat\satoko\act_clause.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\act_var.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\b_queue.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\cdb.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\clause.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\cnf_reader.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\heap.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\mem.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\misc.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\satoko.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\sdbl.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\solver.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\solver.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\solver_api.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\sort.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\types.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\vec\vec_char.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\vec\vec_flt.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\vec\vec_int.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\utils\vec\vec_uint.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\satoko\watch_list.h
# End Source File
# End Group
# End Group
# Begin Group "opt"
@ -2711,10 +2863,26 @@ SOURCE=.\src\opt\sbd\sbdCore.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\sbd\sbdCut.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\sbd\sbdCut2.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\sbd\sbdInt.h
# End Source File
# Begin Source File
SOURCE=.\src\opt\sbd\sbdLut.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\sbd\sbdPath.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\sbd\sbdSat.c
# End Source File
# Begin Source File
@ -3487,10 +3655,18 @@ SOURCE=.\src\misc\util\utilColor.c
# End Source File
# Begin Source File
SOURCE=.\src\misc\util\utilDouble.h
# End Source File
# Begin Source File
SOURCE=.\src\misc\util\utilFile.c
# End Source File
# Begin Source File
SOURCE=.\src\misc\util\utilFloat.h
# End Source File
# Begin Source File
SOURCE=.\src\misc\util\utilIsop.c
# End Source File
# Begin Source File
@ -4483,6 +4659,10 @@ SOURCE=.\src\aig\gia\giaSatMap.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaSatoko.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaScl.c
# End Source File
# Begin Source File
@ -4847,6 +5027,10 @@ SOURCE=.\src\proof\cec\cecPat.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\cec\cecSat.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\cec\cecSeq.c
# End Source File
# Begin Source File
@ -5171,6 +5355,10 @@ SOURCE=.\src\proof\pdr\pdrCore.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\pdr\pdrIncr.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\pdr\pdrInt.h
# End Source File
# Begin Source File
@ -5191,6 +5379,10 @@ SOURCE=.\src\proof\pdr\pdrTsim.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\pdr\pdrTsim2.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\pdr\pdrUtil.c
# End Source File
# End Group
@ -5415,6 +5607,10 @@ SOURCE=.\src\proof\acec\acec.h
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecBo.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecCl.c
# End Source File
# Begin Source File
@ -5439,6 +5635,14 @@ SOURCE=.\src\proof\acec\acecInt.h
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecMult.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecNorm.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecOrder.c
# End Source File
# Begin Source File
@ -5467,8 +5671,20 @@ SOURCE=.\src\proof\acec\acecSt.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecStruct.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecTree.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecUtil.c
# End Source File
# Begin Source File
SOURCE=.\src\proof\acec\acecXor.c
# End Source File
# End Group
# End Group
# End Group

View File

@ -53,6 +53,13 @@ The current version of ABC can be compiled with C compiler or C++ compiler.
* To compile as C++ code with namespaces: make sure that `CC=g++` and `ABC_NAMESPACE` is set to
the name of the requested namespace. For example, add `-DABC_NAMESPACE=xxx` to OPTFLAGS.
## Building a shared library
* Compile the code as position-independent by adding `ABC_USE_PIC=1`.
* Build the `libabc.so` target:
make ABC_USE_PIC=1 libabc.so
## Bug reporting:
Please try to reproduce all the reported bugs and unexpected features using the latest

View File

@ -19,6 +19,7 @@
***********************************************************************/
#include "aig.h"
#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@ -340,12 +341,10 @@ void Aig_WriteDotAig( Aig_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t *
void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold )
{
extern void Abc_ShowFile( char * FileNameDot );
static int Counter = 0;
char FileNameDot[200];
FILE * pFile;
// create the file name
// Aig_ShowGetFileName( pMan->pName, FileNameDot );
sprintf( FileNameDot, "temp%02d.dot", Counter++ );
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
{

View File

@ -194,6 +194,7 @@ struct Gia_Man_t_
int MappedDelay; // delay after mapping
// bit-parallel simulation
int iPatsPi;
int nSimWords;
Vec_Wrd_t * vSims;
Vec_Wrd_t * vSimsPi;
Vec_Int_t * vClassOld;
@ -311,6 +312,7 @@ struct Jf_Par_t_
int fGenCnf;
int fCnfObjIds;
int fAddOrCla;
int fCnfMapping;
int fPureAig;
int fDoAverage;
int fCutHashing;
@ -665,21 +667,6 @@ static inline int Gia_ManAppendAnd( Gia_Man_t * p, int iLit0, int iLit1 )
}
return Gia_ObjId( p, pObj ) << 1;
}
static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 )
{
if ( !p->fGiaSimple )
{
if ( iLit0 < 2 )
return iLit0 ? iLit1 : 0;
if ( iLit1 < 2 )
return iLit1 ? iLit0 : 0;
if ( iLit0 == iLit1 )
return iLit1;
if ( iLit0 == Abc_LitNot(iLit1) )
return 0;
}
return Gia_ManAppendAnd( p, iLit0, iLit1 );
}
static inline int Gia_ManAppendXorReal( Gia_Man_t * p, int iLit0, int iLit1 )
{
Gia_Obj_t * pObj = Gia_ManAppendObj( p );
@ -780,6 +767,44 @@ static inline int Gia_ManAppendXor( Gia_Man_t * p, int iLit0, int iLit1 )
{
return Gia_ManAppendMux( p, iLit0, Abc_LitNot(iLit1), iLit1 );
}
static inline int Gia_ManAppendAnd2( Gia_Man_t * p, int iLit0, int iLit1 )
{
if ( !p->fGiaSimple )
{
if ( iLit0 < 2 )
return iLit0 ? iLit1 : 0;
if ( iLit1 < 2 )
return iLit1 ? iLit0 : 0;
if ( iLit0 == iLit1 )
return iLit1;
if ( iLit0 == Abc_LitNot(iLit1) )
return 0;
}
return Gia_ManAppendAnd( p, iLit0, iLit1 );
}
static inline int Gia_ManAppendOr2( Gia_Man_t * p, int iLit0, int iLit1 )
{
return Abc_LitNot(Gia_ManAppendAnd2( p, Abc_LitNot(iLit0), Abc_LitNot(iLit1) ));
}
static inline int Gia_ManAppendMux2( Gia_Man_t * p, int iCtrl, int iData1, int iData0 )
{
int iTemp0 = Gia_ManAppendAnd2( p, Abc_LitNot(iCtrl), iData0 );
int iTemp1 = Gia_ManAppendAnd2( p, iCtrl, iData1 );
return Abc_LitNotCond( Gia_ManAppendAnd2( p, Abc_LitNot(iTemp0), Abc_LitNot(iTemp1) ), 1 );
}
static inline int Gia_ManAppendMaj2( Gia_Man_t * p, int iData0, int iData1, int iData2 )
{
int iTemp0 = Gia_ManAppendOr2( p, iData1, iData2 );
int iTemp1 = Gia_ManAppendAnd2( p, iData0, iTemp0 );
int iTemp2 = Gia_ManAppendAnd2( p, iData1, iData2 );
return Gia_ManAppendOr2( p, iTemp1, iTemp2 );
}
static inline int Gia_ManAppendXor2( Gia_Man_t * p, int iLit0, int iLit1 )
{
return Gia_ManAppendMux2( 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 );
@ -958,24 +983,26 @@ static inline void Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num ) { p
static inline int Gia_ObjIsConst( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == 0; }
static inline int Gia_ObjIsHead( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0; }
static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; }
static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0; }
static inline int Gia_ObjIsNone( Gia_Man_t * p, int Id ) { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) <= 0; }
static inline int Gia_ObjIsTail( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) <= 0; }
static inline int Gia_ObjIsClass( Gia_Man_t * p, int Id ) { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0; }
static inline int Gia_ObjHasSameRepr( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjRepr(p, i) == Gia_ObjRepr(p, k) && Gia_ObjRepr(p, i) != GIA_VOID) : Gia_ObjRepr(p, k) == 0; }
static inline int Gia_ObjIsFailedPair( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjFailed(p, i) || Gia_ObjFailed(p, k)) : Gia_ObjFailed(p, k); }
static inline int Gia_ClassIsPair( Gia_Man_t * p, int i ) { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) == 0; }
static inline int Gia_ClassIsPair( Gia_Man_t * p, int i ) { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) <= 0; }
static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { assert( Gia_ClassIsPair(p,i) ); Gia_ObjSetRepr(p, Gia_ObjNext(p, i), GIA_VOID); Gia_ObjSetNext(p, i, 0); }
#define Gia_ManForEachConst( p, i ) \
for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else
#define Gia_ManForEachClass( p, i ) \
for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ManForEachClass0( p, i ) \
for ( i = 0; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ManForEachClassReverse( p, i ) \
for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else
#define Gia_ClassForEachObj( p, i, iObj ) \
for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) )
for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) )
#define Gia_ClassForEachObj1( p, i, iObj ) \
for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) )
for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
static inline int Gia_ObjFoffsetId( Gia_Man_t * p, int Id ) { return Vec_IntEntry( p->vFanout, Id ); }
@ -1205,6 +1232,7 @@ extern Gia_Man_t * Gia_ManDupTrimmed( Gia_Man_t * p, int fTrimCis, int f
extern Gia_Man_t * Gia_ManDupOntop( Gia_Man_t * p, Gia_Man_t * p2 );
extern Gia_Man_t * Gia_ManDupWithNewPo( Gia_Man_t * p1, Gia_Man_t * p2 );
extern Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits );
extern Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int nExtra );
extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose );
extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int nInsDup, int fDualOut, int fSeq, int fImplic, int fVerbose );
@ -1219,6 +1247,8 @@ extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias );
extern Gia_Man_t * Gia_ManDupWithConstraints( Gia_Man_t * p, Vec_Int_t * vPoTypes );
extern Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis );
extern Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrimPis );
extern Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level );
extern Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level );
extern Gia_Man_t * Gia_ManDupOneHot( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupLevelized( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupFromVecs( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs );
@ -1247,6 +1277,7 @@ extern void Gia_ManOrigIdsInit( Gia_Man_t * p );
extern void Gia_ManOrigIdsStart( Gia_Man_t * p );
extern void Gia_ManOrigIdsRemap( Gia_Man_t * p, Gia_Man_t * pNew );
extern Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs );
extern Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose );
extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p );
extern int Gia_ManCheckTopoOrder( Gia_Man_t * p );
extern int * Gia_ManDeriveNexts( Gia_Man_t * p );
@ -1379,6 +1410,7 @@ extern int Gia_MmStepReadMemUsage( Gia_MmStep_t * p );
/*=== giaMf.c ===========================================================*/
extern void Mf_ManSetDefaultPars( Jf_Par_t * pPars );
extern Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars );
extern void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose );
/*=== giaMini.c ===========================================================*/
extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName );
extern void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName );
@ -1403,7 +1435,7 @@ 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 );
/*=== giaShow.c ===========================================================*/
extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders );
extern void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath );
/*=== giaShrink.c ===========================================================*/
extern Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose );
extern Gia_Man_t * Gia_ManMapShrink6( Gia_Man_t * p, int nFanoutMax, int fKeepLevel, int fVerbose );
@ -1491,6 +1523,7 @@ extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimi
extern word Gia_LutComputeTruth6( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTruths );
extern word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp );
extern word Gia_ObjComputeTruthTable6( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTruths );
extern word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp );
extern void Gia_ObjCollectInternal( Gia_Man_t * p, Gia_Obj_t * pObj );
extern word * Gia_ObjComputeTruthTable( Gia_Man_t * p, Gia_Obj_t * pObj );
extern void Gia_ObjComputeTruthTableStart( Gia_Man_t * p, int nVarsMax );

View File

@ -22,6 +22,7 @@
#include "proof/fra/fra.h"
#include "proof/dch/dch.h"
#include "opt/dar/dar.h"
#include "opt/dau/dau.h"
ABC_NAMESPACE_IMPL_START
@ -576,11 +577,17 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose )
***********************************************************************/
Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars )
{
Gia_Man_t * pGia;
int fUseMapping = 0;
Gia_Man_t * pGia, * pGia1;
Aig_Man_t * pNew;
if ( p->pManTime && p->vLevels == NULL )
Gia_ManLevelWithBoxes( p );
pNew = Gia_ManToAig( p, 0 );
if ( fUseMapping && Gia_ManHasMapping(p) )
pGia1 = (Gia_Man_t *)Dsm_ManDeriveGia( p, 0 );
else
pGia1 = Gia_ManDup( p );
pNew = Gia_ManToAig( pGia1, 0 );
Gia_ManStop( pGia1 );
pNew = Dar_ManChoiceNew( pNew, (Dch_Pars_t *)pPars );
// pGia = Gia_ManFromAig( pNew );
pGia = Gia_ManFromAigChoices( pNew );

View File

@ -220,6 +220,80 @@ Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p )
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates AIG while putting objects in the DFS order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
int k, Flop, Used;
assert( Vec_IntSize(vMapFf2Ppi) == Vec_IntSize(vMapPpi2Ff) + Vec_IntCountEntry(vMapFf2Ppi, -1) );
Gia_ManFillValue( p );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManConst0(p)->Value = 0;
// create inputs
Gia_ManForEachPi( p, pObj, k )
pObj->Value = Gia_ManAppendCi(pNew);
Vec_IntForEachEntry( vMapPpi2Ff, Flop, k )
{
pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop );
pObj->Value = Gia_ManAppendCi(pNew);
}
Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop )
{
pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop );
if ( Used >= 0 )
{
assert( pObj->Value != ~0 );
continue;
}
assert( pObj->Value == ~0 );
pObj->Value = Gia_ManAppendCi(pNew);
}
Gia_ManForEachCi( p, pObj, k )
assert( pObj->Value != ~0 );
// create nodes
Gia_ManForEachPo( p, pObj, k )
Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop )
{
if ( Used >= 0 )
continue;
pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop );
pObj = Gia_ObjRoToRi( p, pObj );
Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) );
}
// create outputs
Gia_ManForEachPo( p, pObj, k )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Vec_IntForEachEntry( vMapFf2Ppi, Used, Flop )
{
if ( Used >= 0 )
continue;
pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Flop );
pObj = Gia_ObjRoToRi( p, pObj );
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
}
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) - Vec_IntSize(vMapPpi2Ff) );
assert( Gia_ManPiNum(pNew) == Gia_ManPiNum(p) + Vec_IntSize(vMapPpi2Ff) );
assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) );
assert( Gia_ManPoNum(pNew) == Gia_ManPoNum(p) );
assert( Gia_ManCoNum(pNew) == Gia_ManCoNum(p) - Vec_IntSize(vMapPpi2Ff) );
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates AIG while putting objects in the DFS order.]
@ -2095,6 +2169,43 @@ Gia_Man_t * Gia_ManDupDfsCiMap( Gia_Man_t * p, int * pCi2Lit, Vec_Int_t * vLits
return pNew;
}
/**Function*************************************************************
Synopsis [Permute inputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int nExtra )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
int i;
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManConst0(p)->Value = 0;
for ( i = 0; i < Gia_ManPiNum(p) - nPpis - nExtra; i++ ) // regular PIs
Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew );
for ( i = Gia_ManPiNum(p) - nExtra; i < Gia_ManPiNum(p); i++ ) // extra PIs due to DC values
Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew );
for ( i = Gia_ManPiNum(p) - nPpis - nExtra; i < Gia_ManPiNum(p) - nExtra; i++ ) // pseudo-PIs
Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew );
for ( i = Gia_ManPiNum(p); i < Gia_ManCiNum(p); i++ ) // flop outputs
Gia_ManCi(p, i)->Value = Gia_ManAppendCi( pNew );
assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) );
Gia_ManForEachAnd( p, pObj, i )
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
Gia_ManForEachCo( p, pObj, i )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates AIG in the DFS order.]
@ -3045,6 +3156,71 @@ Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrim
Vec_PtrFree( vRoots );
return pNew;
}
void Gia_ManDupAndConesLimit_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level )
{
Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
if ( ~pObj->Value )
return;
if ( !Gia_ObjIsAnd(pObj) || Gia_ObjLevel(p, pObj) < Level )
{
pObj->Value = Gia_ManAppendCi( pNew );
//printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj );
return;
}
Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level );
Gia_ManDupAndConesLimit_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level );
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
//printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj );
}
Gia_Man_t * Gia_ManDupAndConesLimit( Gia_Man_t * p, int * pAnds, int nAnds, int Level )
{
Gia_Man_t * pNew;
int i;
pNew = Gia_ManStart( 1000 );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManLevelNum( p );
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
for ( i = 0; i < nAnds; i++ )
Gia_ManDupAndConesLimit_rec( pNew, p, pAnds[i], Level );
for ( i = 0; i < nAnds; i++ )
Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value );
return pNew;
}
void Gia_ManDupAndConesLimit2_rec( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, int Level )
{
Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
if ( ~pObj->Value )
return;
if ( !Gia_ObjIsAnd(pObj) || Level <= 0 )
{
pObj->Value = Gia_ManAppendCi( pNew );
//printf( "PI %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj );
return;
}
Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj), Level-1 );
Gia_ManDupAndConesLimit2_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj), Level-1 );
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
//printf( "Obj %d for %d.\n", Abc_Lit2Var(pObj->Value), iObj );
}
Gia_Man_t * Gia_ManDupAndConesLimit2( Gia_Man_t * p, int * pAnds, int nAnds, int Level )
{
Gia_Man_t * pNew;
int i;
pNew = Gia_ManStart( 1000 );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
for ( i = 0; i < nAnds; i++ )
Gia_ManDupAndConesLimit2_rec( pNew, p, pAnds[i], Level );
for ( i = 0; i < nAnds; i++ )
Gia_ManAppendCo( pNew, Gia_ManObj(p, pAnds[i])->Value );
return pNew;
}
/**Function*************************************************************
@ -3377,6 +3553,26 @@ Gia_Man_t * Gia_ManDupOuts( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose )
{
abctime clk = Abc_Clock();
Gia_Obj_t * pObj; int i, Id;
Vec_Wec_t * vSuppsNo = Vec_WecStart( Vec_IntSize(vNodes) );
Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) );
Gia_ManForEachCiId( p, Id, i )
Vec_IntPush( Vec_WecEntry(vSupps, Id), i );
Gia_ManForEachAnd( p, pObj, Id )
Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, Id)),
Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, Id)),
Vec_WecEntry(vSupps, Id) );
Gia_ManForEachObjVec( vNodes, p, pObj, i )
Vec_IntAppend( Vec_WecEntry(vSuppsNo, i), Vec_WecEntry(vSupps, Gia_ObjId(p, pObj)) );
Vec_WecFree( vSupps );
if ( fVerbose )
Abc_PrintTime( 1, "Support computation", Abc_Clock() - clk );
return vSuppsNo;
}
Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose )
{
abctime clk = Abc_Clock();
@ -3679,6 +3875,81 @@ Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose )
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManDupDemiterOrderXors2( Gia_Man_t * p, Vec_Int_t * vXors )
{
int i, iObj, * pPerm;
Vec_Int_t * vSizes = Vec_IntAlloc( 100 );
Vec_IntForEachEntry( vXors, iObj, i )
Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) );
pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) );
Vec_IntClear( vSizes );
for ( i = 0; i < Vec_IntSize(vXors); i++ )
Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) );
ABC_FREE( pPerm );
Vec_IntClear( vXors );
Vec_IntAppend( vXors, vSizes );
Vec_IntFree( vSizes );
}
int Gia_ManDupDemiterFindMin( Vec_Wec_t * vSupps, Vec_Int_t * vTakenIns, Vec_Int_t * vTakenOuts )
{
Vec_Int_t * vLevel;
int i, k, iObj, iObjBest = -1;
int Count, CountBest = ABC_INFINITY;
Vec_WecForEachLevel( vSupps, vLevel, i )
{
if ( Vec_IntEntry(vTakenOuts, i) )
continue;
Count = 0;
Vec_IntForEachEntry( vLevel, iObj, k )
Count += !Vec_IntEntry(vTakenIns, iObj);
if ( CountBest > Count )
{
CountBest = Count;
iObjBest = i;
}
}
return iObjBest;
}
void Gia_ManDupDemiterOrderXors( Gia_Man_t * p, Vec_Int_t * vXors )
{
extern Vec_Wec_t * Gia_ManCreateNodeSupps( Gia_Man_t * p, Vec_Int_t * vNodes, int fVerbose );
Vec_Wec_t * vSupps = Gia_ManCreateNodeSupps( p, vXors, 0 );
Vec_Int_t * vTakenIns = Vec_IntStart( Gia_ManCiNum(p) );
Vec_Int_t * vTakenOuts = Vec_IntStart( Vec_IntSize(vXors) );
Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXors) );
int i, k, iObj;
// add outputs in the order of increasing supports
for ( i = 0; i < Vec_IntSize(vXors); i++ )
{
int Index = Gia_ManDupDemiterFindMin( vSupps, vTakenIns, vTakenOuts );
assert( Index >= 0 && Index < Vec_IntSize(vXors) );
Vec_IntPush( vOrder, Vec_IntEntry(vXors, Index) );
assert( !Vec_IntEntry( vTakenOuts, Index ) );
Vec_IntWriteEntry( vTakenOuts, Index, 1 );
Vec_IntForEachEntry( Vec_WecEntry(vSupps, Index), iObj, k )
Vec_IntWriteEntry( vTakenIns, iObj, 1 );
}
Vec_WecFree( vSupps );
Vec_IntFree( vTakenIns );
Vec_IntFree( vTakenOuts );
// reload
Vec_IntClear( vXors );
Vec_IntAppend( vXors, vOrder );
Vec_IntFree( vOrder );
}
/**Function*************************************************************
Synopsis []
@ -3781,27 +4052,26 @@ void Gia_ManCollectTopXors_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXo
}
Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p )
{
int i, iObj, iObj2, fFlip, * pPerm, Count1 = 0;
Vec_Int_t * vXors, * vSizes, * vPart[2], * vOrder;
int i, iObj, iObj2, fFlip, Count1 = 0;
Vec_Int_t * vXors, * vPart[2], * vOrder;
Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0);
assert( Gia_ManCoNum(p) == 1 );
vXors = Vec_IntAlloc( 100 );
if ( Gia_ObjFaninC0(pObj) )
Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors );
if ( Gia_ManCoNum(p) == 1 )
{
if ( Gia_ObjFaninC0(pObj) )
Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors );
else
Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) );
}
else
Vec_IntPush( vXors, Gia_ObjId(p, Gia_ObjFanin0(pObj)) );
{
Gia_ManForEachCo( p, pObj, i )
if ( Gia_ObjFaninId0p(p, pObj) > 0 )
Vec_IntPush( vXors, Gia_ObjFaninId0p(p, pObj) );
}
// order by support size
vSizes = Vec_IntAlloc( 100 );
Vec_IntForEachEntry( vXors, iObj, i )
Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) );
pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) );
Vec_IntClear( vSizes );
for ( i = 0; i < Vec_IntSize(vXors); i++ )
Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) );
ABC_FREE( pPerm );
Vec_IntClear( vXors );
Vec_IntAppend( vXors, vSizes );
Vec_IntFree( vSizes );
Gia_ManDupDemiterOrderXors( p, vXors );
//Vec_IntPrint( vXors );
Vec_IntReverseOrder( vXors ); // from MSB to LSB
// divide into groups
Gia_ManCleanMark01(p);

View File

@ -129,7 +129,7 @@ Gia_Man_t * Gia_ManOrigIdsReduce( Gia_Man_t * p, Vec_Int_t * vPairs )
}
Gia_ManHashStop( pNew );
Gia_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Vec_IntFree( vMap );
// compute equivalences
assert( !p->pReprs && !p->pNexts );
@ -169,6 +169,31 @@ Gia_Man_t * Gia_ManOrigIdsReduceTest( Gia_Man_t * p, Vec_Int_t * vPairs )
return pNew;
}
/**Function*************************************************************
Synopsis [Compute equivalence classes of nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose )
{
Gia_Man_t * pTemp;
Cec_ParFra_t ParsFra, * pPars = &ParsFra;
Cec_ManFraSetDefaultParams( pPars );
pPars->fUseOrigIds = 1;
pPars->fSatSweeping = 1;
pPars->nBTLimit = nConfs;
pPars->fVerbose = fVerbose;
pTemp = Cec_ManSatSweeping( pGia, pPars, 0 );
Gia_ManStop( pTemp );
return Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv );
}
/**Function*************************************************************
Synopsis [Returns 1 if AIG is not in the required topo order.]
@ -460,7 +485,7 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )
if ( fVerbose )
{
// int Ent;
Abc_Print( 1, "Const0 = " );
Abc_Print( 1, "Const0 (%d) = ", Counter0 );
Gia_ManForEachConst( p, i )
Abc_Print( 1, "%d ", i );
Abc_Print( 1, "\n" );

View File

@ -539,33 +539,25 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
{
sprintf( FileNameOld, "%s", p->pName );
fprintf( pTable, "\n" );
fprintf( pTable, "%s ", p->pName );
// fprintf( pTable, "%d ", Gia_ManCiNum(p) );
// fprintf( pTable, "%d ", Gia_ManCoNum(p) );
// fprintf( pTable, "%d ", Gia_ManAndNum(p) );
// fprintf( pTable, "%d ", Gia_ManPiNum(p) - Gia_ManBoxCiNum(p) - Gia_ManRegBoxNum(p) );
// fprintf( pTable, "%d ", Gia_ManPoNum(p) - Gia_ManBoxCoNum(p) - Gia_ManRegBoxNum(p) );
// fprintf( pTable, "%d ", Gia_ManClockDomainNum(p) );
fprintf( pTable, "%s ", p->pName );
fprintf( pTable, " " );
fprintf( pTable, "%d ", p->MappedDelay );
fprintf( pTable, "%d ", p->MappedArea );
fprintf( pTable, "%d ", nFanins );
fprintf( pTable, "%d ", LevelMax );
fprintf( pTable, "%d ", Gia_ManAndNum(p) );
fprintf( pTable, "%d ", nLuts );
// fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
// fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) );
//fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
//fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
//fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC );
clk = Abc_Clock();
}
else
{
printf( "This part of the code is currently not used.\n" );
assert( 0 );
//printf( "This part of the code is currently not used.\n" );
//assert( 0 );
fprintf( pTable, " " );
fprintf( pTable, "%d ", nLuts );
fprintf( pTable, "%d ", LevelMax );
fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) );
//fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
//fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC );
clk = Abc_Clock();
}
@ -2014,7 +2006,7 @@ void Gia_ManMappingVerify( Gia_Man_t * p )
void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia )
{
Gia_Obj_t * pObj;
int i, k, iFan;
int i, k, iFan, iPlace;
if ( !Gia_ManHasMapping(pGia) )
return;
Gia_ManMappingVerify( pGia );
@ -2023,12 +2015,20 @@ void Gia_ManTransferMapping( Gia_Man_t * p, Gia_Man_t * pGia )
Vec_IntFill( p->vMapping, Gia_ManObjNum(p), 0 );
Gia_ManForEachLut( pGia, i )
{
if ( Gia_ObjValue(Gia_ManObj(pGia, i)) == ~0 ) // handle dangling LUT
continue;
assert( !Abc_LitIsCompl(Gia_ObjValue(Gia_ManObj(pGia, i))) );
pObj = Gia_ManObj( p, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, i))) );
Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) );
iPlace = Vec_IntSize( p->vMapping );
Vec_IntPush( p->vMapping, Gia_ObjLutSize(pGia, i) );
Gia_LutForEachFanin( pGia, i, iFan, k )
Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) );
{
if ( Gia_ObjValue(Gia_ManObj(pGia, iFan)) == ~0 ) // handle dangling LUT fanin
Vec_IntAddToEntry( p->vMapping, iPlace, -1 );
else
Vec_IntPush( p->vMapping, Abc_Lit2Var(Gia_ObjValue(Gia_ManObj(pGia, iFan))) );
}
iFan = Abc_Lit2Var( Gia_ObjValue(Gia_ManObj(pGia, Abc_AbsInt(Gia_ObjLutMuxId(pGia, i)))) );
Vec_IntPush( p->vMapping, Gia_ObjLutIsMux(pGia, i) ? -iFan : iFan );
}

View File

@ -36,6 +36,7 @@ ABC_NAMESPACE_IMPL_START
#define JF_LEAF_MAX 8
#define JF_WORD_MAX ((JF_LEAF_MAX > 6) ? 1 << (JF_LEAF_MAX-6) : 1)
#define JF_CUT_MAX 16
#define JF_EPSILON 0.005
typedef struct Jf_Cut_t_ Jf_Cut_t;
struct Jf_Cut_t_
@ -940,15 +941,16 @@ float Jf_CutCompareDelay( Jf_Cut_t * pOld, Jf_Cut_t * pNew )
{
if ( pOld->Time != pNew->Time ) return pOld->Time - pNew->Time;
if ( pOld->pCut[0] != pNew->pCut[0] ) return pOld->pCut[0] - pNew->pCut[0];
if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow;
// if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow;
if ( pOld->Flow < pNew->Flow - JF_EPSILON ) return -1;
if ( pOld->Flow > pNew->Flow + JF_EPSILON ) return 1;
return 0;
}
float Jf_CutCompareArea( Jf_Cut_t * pOld, Jf_Cut_t * pNew )
{
// float Epsilon = (float)0.001;
// if ( pOld->Flow > pNew->Flow + Epsilon ) return 1;
// if ( pOld->Flow < pNew->Flow - Epsilon ) return -1;
if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow;
// if ( pOld->Flow != pNew->Flow ) return pOld->Flow - pNew->Flow;
if ( pOld->Flow < pNew->Flow - JF_EPSILON ) return -1;
if ( pOld->Flow > pNew->Flow + JF_EPSILON ) return 1;
if ( pOld->pCut[0] != pNew->pCut[0] ) return pOld->pCut[0] - pNew->pCut[0];
if ( pOld->Time != pNew->Time ) return pOld->Time - pNew->Time;
return 0;
@ -1256,10 +1258,10 @@ void Jf_ManComputeCuts( Jf_Man_t * p, int fEdge )
}
if ( p->pPars->fVerbose )
{
printf( "CutPair = %lu ", p->CutCount[0] );
printf( "Merge = %lu ", p->CutCount[1] );
printf( "Eval = %lu ", p->CutCount[2] );
printf( "Cut = %lu ", p->CutCount[3] );
printf( "CutPair = %lu ", (long)p->CutCount[0] );
printf( "Merge = %lu ", (long)p->CutCount[1] );
printf( "Eval = %lu ", (long)p->CutCount[2] );
printf( "Cut = %lu ", (long)p->CutCount[3] );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
printf( "Memory: " );
printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) );
@ -1367,7 +1369,7 @@ void Jf_ObjComputeBestCut( Jf_Man_t * p, Gia_Obj_t * pObj, int fEdge, int fEla )
if ( fEdge && !fEla )
Jf_CutSetCost(pCut, Jf_CutSize(pCut));
Area = fEla ? Jf_CutArea(p, pCut, fEdge) : Jf_CutFlow(p, pCut) + Jf_CutCost(pCut);
if ( pCutBest == NULL || AreaBest > Area || (AreaBest == Area && TimeBest > (Time = Jf_CutArr(p, pCut))) )
if ( pCutBest == NULL || AreaBest > Area + JF_EPSILON || (AreaBest > Area - JF_EPSILON && TimeBest > (Time = Jf_CutArr(p, pCut))) )
pCutBest = pCut, AreaBest = Area, TimeBest = Time;
}
Vec_IntWriteEntry( &p->vArr, iObj, Jf_CutArr(p, pCutBest) );
@ -1702,11 +1704,11 @@ void Jf_ManPrintStats( Jf_Man_t * p, char * pTitle )
if ( !p->pPars->fVerbose )
return;
printf( "%s : ", pTitle );
printf( "Level =%6lu ", p->pPars->Delay );
printf( "Area =%9lu ", p->pPars->Area );
printf( "Edge =%9lu ", p->pPars->Edge );
printf( "Level =%6lu ", (long)p->pPars->Delay );
printf( "Area =%9lu ", (long)p->pPars->Area );
printf( "Edge =%9lu ", (long)p->pPars->Edge );
if ( p->pPars->fGenCnf )
printf( "Cnf =%9lu ", p->pPars->Clause );
printf( "Cnf =%9lu ", (long)p->pPars->Clause );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}

View File

@ -1125,9 +1125,9 @@ void Kf_ManPrintStats( Kf_Man_t * p, char * pTitle )
if ( !p->pPars->fVerbose )
return;
printf( "%s : ", pTitle );
printf( "Level =%6lu ", p->pPars->Delay );
printf( "Area =%9lu ", p->pPars->Area );
printf( "Edge =%9lu ", p->pPars->Edge );
printf( "Level =%6lu ", (long)p->pPars->Delay );
printf( "Area =%9lu ", (long)p->pPars->Area );
printf( "Edge =%9lu ", (long)p->pPars->Edge );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}
@ -1173,10 +1173,10 @@ void Kf_ManComputeMapping( Kf_Man_t * p )
Kf_ManComputeRefs( p );
if ( p->pPars->fVerbose )
{
printf( "CutPair = %lu ", p->pSett->CutCount[0] );
printf( "Merge = %lu ", p->pSett->CutCount[1] );
printf( "Eval = %lu ", p->pSett->CutCount[2] );
printf( "Cut = %lu ", p->pSett->CutCount[3] );
printf( "CutPair = %lu ", (long)p->pSett->CutCount[0] );
printf( "Merge = %lu ", (long)p->pSett->CutCount[1] );
printf( "Eval = %lu ", (long)p->pSett->CutCount[2] );
printf( "Cut = %lu ", (long)p->pSett->CutCount[3] );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
printf( "Memory: " );
printf( "Gia = %.2f MB ", Gia_ManMemory(p->pGia) / (1<<20) );

View File

@ -36,6 +36,7 @@ ABC_NAMESPACE_IMPL_START
#define LF_NO_LEAF 255
#define LF_CUT_WORDS (4+LF_LEAF_MAX/2)
#define LF_TT_WORDS ((LF_LEAF_MAX > 6) ? 1 << (LF_LEAF_MAX-6) : 1)
#define LF_EPSILON 0.005
typedef struct Lf_Cut_t_ Lf_Cut_t;
struct Lf_Cut_t_
@ -847,16 +848,16 @@ static inline int Lf_CutCompareDelay( Lf_Cut_t * pCut0, Lf_Cut_t * pCut1 )
if ( pCut0->Delay > pCut1->Delay ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
if ( pCut0->Flow < pCut1->Flow ) return -1;
if ( pCut0->Flow > pCut1->Flow ) return 1;
if ( pCut0->Flow < pCut1->Flow - LF_EPSILON ) return -1;
if ( pCut0->Flow > pCut1->Flow + LF_EPSILON ) return 1;
return 0;
}
static inline int Lf_CutCompareArea( Lf_Cut_t * pCut0, Lf_Cut_t * pCut1 )
{
if ( pCut0->fLate < pCut1->fLate ) return -1;
if ( pCut0->fLate > pCut1->fLate ) return 1;
if ( pCut0->Flow < pCut1->Flow ) return -1;
if ( pCut0->Flow > pCut1->Flow ) return 1;
if ( pCut0->Flow < pCut1->Flow - LF_EPSILON ) return -1;
if ( pCut0->Flow > pCut1->Flow + LF_EPSILON ) return 1;
if ( pCut0->Delay < pCut1->Delay ) return -1;
if ( pCut0->Delay > pCut1->Delay ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
@ -1304,7 +1305,7 @@ void Lf_ObjMergeOrder( Lf_Man_t * p, int iObj )
p->nCutEqual++;
// area cut
iCutUsed = 0;
if ( nCutsR > 1 && pCutsR[0]->Flow > pCutsR[1]->Flow )//&& !pCutsR[1]->fLate ) // can remove !fLate
if ( nCutsR > 1 && pCutsR[0]->Flow > pCutsR[1]->Flow + LF_EPSILON )//&& !pCutsR[1]->fLate ) // can remove !fLate
{
pBest->Cut[1].Handle = Lf_MemSaveCut(&p->vStoreNew, pCutsR[1], iObj);
pBest->Delay[1] = pCutsR[1]->Delay;
@ -2012,14 +2013,14 @@ void Lf_ManPrintStats( Lf_Man_t * p, char * pTitle )
if ( !p->pPars->fVerbose )
return;
printf( "%s : ", pTitle );
printf( "Level =%6lu ", p->pPars->Delay );
printf( "Area =%9lu ", p->pPars->Area );
printf( "Edge =%9lu ", p->pPars->Edge );
printf( "LUT =%9lu ", p->pPars->Area+p->nInverters );
printf( "Level =%6lu ", (long)p->pPars->Delay );
printf( "Area =%9lu ", (long)p->pPars->Area );
printf( "Edge =%9lu ", (long)p->pPars->Edge );
printf( "LUT =%9lu ", (long)p->pPars->Area+p->nInverters );
if ( Vec_FltSize(&p->vSwitches) )
printf( "Swt =%8.1f ", p->Switches );
if ( p->pPars->fUseMux7 )
printf( "Mux7 =%7lu ", p->pPars->Mux7 );
printf( "Mux7 =%7lu ", (long)p->pPars->Mux7 );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}

View File

@ -37,6 +37,7 @@ ABC_NAMESPACE_IMPL_START
#define MF_NO_LEAF 31
#define MF_TT_WORDS ((MF_LEAF_MAX > 6) ? 1 << (MF_LEAF_MAX-6) : 1)
#define MF_NO_FUNC 134217727 // (1<<27)-1
#define MF_EPSILON 0.005
typedef struct Mf_Cut_t_ Mf_Cut_t;
struct Mf_Cut_t_
@ -387,6 +388,8 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla )
Gia_ManForEachCoId( p->pGia, Id, i )
pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[Id], 0);
}
if ( p->pPars->fCnfMapping )
pCnf->vMapping = Vec_IntStart( nVars );
// add clauses for the COs
Gia_ManForEachCo( p->pGia, pObj, i )
{
@ -400,6 +403,14 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla )
pCnf->pClauses[iCla++] = pCnf->pClauses[0] + iLit;
pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[Id], 1);
pCnf->pClauses[0][iLit++] = Abc_Var2Lit(pCnfIds[DriId], Gia_ObjFaninC0(pObj));
// generate mapping
if ( pCnf->vMapping )
{
Vec_IntWriteEntry( pCnf->vMapping, pCnfIds[Id], Vec_IntSize(pCnf->vMapping) );
Vec_IntPush( pCnf->vMapping, 1 );
Vec_IntPush( pCnf->vMapping, pCnfIds[DriId] );
Vec_IntPush( pCnf->vMapping, Gia_ObjFaninC0(pObj) ? 0x55555555 : 0xAAAAAAAA );
}
}
// add clauses for the mapping
Gia_ManForEachAndReverseId( p->pGia, Id )
@ -426,6 +437,35 @@ Cnf_Dat_t * Mf_ManDeriveCnf( Mf_Man_t * p, int fCnfObjIds, int fAddOrCla )
if ( Mf_CubeLit(pCubes[c], k) )
pCnf->pClauses[0][iLit++] = Abc_Var2Lit( pFanins[k], Mf_CubeLit(pCubes[c], k) == 2 );
}
// generate mapping
if ( pCnf->vMapping )
{
word pTruth[4], * pTruthP = Vec_MemReadEntry(p->vTtMem, iFunc);
assert( p->pPars->nLutSize <= 8 );
Abc_TtCopy( pTruth, pTruthP, Abc_Truth6WordNum(p->pPars->nLutSize), Abc_LitIsCompl(iFunc) );
assert( pCnfIds[Id] >= 0 && pCnfIds[Id] < nVars );
Vec_IntWriteEntry( pCnf->vMapping, pCnfIds[Id], Vec_IntSize(pCnf->vMapping) );
Vec_IntPush( pCnf->vMapping, Mf_CutSize(pCut) );
for ( k = 0; k < Mf_CutSize(pCut); k++ )
Vec_IntPush( pCnf->vMapping, pCnfIds[pCut[k+1]] );
Vec_IntPush( pCnf->vMapping, (unsigned)pTruth[0] );
if ( Mf_CutSize(pCut) >= 6 )
{
Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[0] >> 32) );
if ( Mf_CutSize(pCut) >= 7 )
{
Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[1]) );
Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[1] >> 32) );
}
if ( Mf_CutSize(pCut) >= 8 )
{
Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[2]) );
Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[2] >> 32) );
Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[3]) );
Vec_IntPush( pCnf->vMapping, (unsigned)(pTruth[3] >> 32) );
}
}
}
}
// constant clause
pCnf->pClauses[iCla++] = pCnf->pClauses[0] + iLit;
@ -920,8 +960,8 @@ static inline int Mf_SetLastCutContainsArea( Mf_Cut_t ** pCuts, int nCuts )
}
static inline int Mf_CutCompareArea( Mf_Cut_t * pCut0, Mf_Cut_t * pCut1 )
{
if ( pCut0->Flow < pCut1->Flow ) return -1;
if ( pCut0->Flow > pCut1->Flow ) return 1;
if ( pCut0->Flow < pCut1->Flow - MF_EPSILON ) return -1;
if ( pCut0->Flow > pCut1->Flow + MF_EPSILON ) return 1;
if ( pCut0->Delay < pCut1->Delay ) return -1;
if ( pCut0->Delay > pCut1->Delay ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
@ -1415,11 +1455,11 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle )
if ( !p->pPars->fVerbose )
return;
printf( "%s : ", pTitle );
printf( "Level =%6lu ", p->pPars->Delay );
printf( "Area =%9lu ", p->pPars->Area );
printf( "Edge =%9lu ", p->pPars->Edge );
printf( "Level =%6lu ", (long)p->pPars->Delay );
printf( "Area =%9lu ", (long)p->pPars->Area );
printf( "Edge =%9lu ", (long)p->pPars->Edge );
if ( p->pPars->fGenCnf )
printf( "CNF =%9lu ", p->pPars->Clause );
printf( "CNF =%9lu ", (long)p->pPars->Clause );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
fflush( stdout );
}
@ -1544,7 +1584,7 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj )
assert( !Mf_CutIsTriv(pCut, iObj) );
assert( Mf_CutSize(pCut) <= p->pPars->nLutSize );
Flow = p->fUseEla ? Mf_CutAreaDerefed(p, pCut) : Mf_CutFlow(p, pCut, &Time);
if ( pCutBest == NULL || FlowBest > Flow || (FlowBest == Flow && TimeBest > Time) )
if ( pCutBest == NULL || FlowBest > Flow + MF_EPSILON || (FlowBest > Flow - MF_EPSILON && TimeBest > Time) )
pCutBest = pCut, FlowBest = Flow, TimeBest = Time;
}
assert( pCutBest != NULL );
@ -1635,28 +1675,29 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
SeeAlso []
***********************************************************************/
Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose )
void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose )
{
Gia_Man_t * pNew;
Jf_Par_t Pars, * pPars = &Pars;
assert( nLutSize >= 3 && nLutSize <= 8 );
Mf_ManSetDefaultPars( pPars );
pPars->fGenCnf = 1;
pPars->fCoarsen = !fCnfObjIds;
pPars->nLutSize = nLutSize;
pPars->fCnfObjIds = fCnfObjIds;
pPars->fAddOrCla = fAddOrCla;
pPars->fVerbose = fVerbose;
pPars->fGenCnf = 1;
pPars->fCoarsen = !fCnfObjIds;
pPars->nLutSize = nLutSize;
pPars->fCnfObjIds = fCnfObjIds;
pPars->fAddOrCla = fAddOrCla;
pPars->fCnfMapping = fMapping;
pPars->fVerbose = fVerbose;
pNew = Mf_ManPerformMapping( pGia, pPars );
Gia_ManStopP( &pNew );
// Cnf_DataPrint( (Cnf_Dat_t *)pGia->pData, 1 );
return (Cnf_Dat_t*)pGia->pData;
return pGia->pData;
}
void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose )
{
abctime clk = Abc_Clock();
Cnf_Dat_t * pCnf;
pCnf = Mf_ManGenerateCnf( p, nLutSize, fCnfObjIds, fAddOrCla, fVerbose );
pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, nLutSize, fCnfObjIds, fAddOrCla, 0, fVerbose );
Cnf_DataWriteIntoFile( pCnf, pFileName, 0, NULL, NULL );
// if ( fVerbose )
{

View File

@ -451,6 +451,7 @@ Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars )
nNodes = Sfm_NtkPerform( pNtk, pPars );
if ( nNodes == 0 )
{
if ( p->pManTime )
Abc_Print( 1, "The network is not changed by \"&mfs\".\n" );
pNew = Gia_ManDup( p );
pNew->vMapping = Vec_IntDup( p->vMapping );

View File

@ -21,6 +21,7 @@
#include "gia.h"
#include "opt/dau/dau.h"
#include "base/main/main.h"
#include "misc/util/utilTruth.h"
#include "aig/miniaig/miniaig.h"
#include "aig/miniaig/minilut.h"
@ -245,6 +246,34 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p )
return pGia;
}
/**Function*************************************************************
Synopsis [Marks LUTs that should be complemented.]
Description [These are LUTs whose all PO fanouts require them
in negative polarity. Other fanouts may require them in
positive polarity.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Bit_t * Gia_ManFindComplLuts( Gia_Man_t * pGia )
{
Gia_Obj_t * pObj; int i;
// mark objects pointed by COs in negative polarity
Vec_Bit_t * vMarks = Vec_BitStart( Gia_ManObjNum(pGia) );
Gia_ManForEachCo( pGia, pObj, i )
if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Gia_ObjFaninC0(pObj) )
Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 1 );
// unmark objects pointed by COs in positive polarity
Gia_ManForEachCo( pGia, pObj, i )
if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) )
Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 0 );
return vMarks;
}
/**Function*************************************************************
Synopsis [Converts GIA into MiniLUT.]
@ -260,11 +289,13 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
{
Mini_Lut_t * p;
Vec_Wrd_t * vTruths;
Vec_Bit_t * vMarks;
Gia_Obj_t * pObj, * pFanin;
int i, k, LutSize, pVars[16];
int i, k, iFanin, LutSize, pVars[16];
word Truth;
assert( Gia_ManHasMapping(pGia) );
LutSize = Gia_ManLutSizeMax( pGia );
LutSize = Abc_MaxInt( LutSize, 2 );
assert( LutSize >= 2 );
// create the manager
p = Mini_LutStart( LutSize );
@ -274,12 +305,17 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
pObj->Value = Mini_LutCreatePi(p);
// create internal nodes
vTruths = Vec_WrdStart( Gia_ManObjNum(pGia) );
vMarks = Gia_ManFindComplLuts( pGia );
Gia_ManForEachLut( pGia, i )
{
pObj = Gia_ManObj( pGia, i );
Gia_LutForEachFaninObj( pGia, i, pFanin, k )
pVars[k] = pFanin->Value;
Truth = Gia_LutComputeTruth6( pGia, i, vTruths );
Truth = Vec_BitEntry(vMarks, i) ? ~Truth : Truth;
Gia_LutForEachFanin( pGia, i, iFanin, k )
if ( Vec_BitEntry(vMarks, iFanin) )
Truth = Abc_Tt6Flip( Truth, k );
pObj->Value = Mini_LutCreateNode( p, Gia_ObjLutSize(pGia, i), pVars, (unsigned *)&Truth );
}
Vec_WrdFree( vTruths );
@ -288,7 +324,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
{
if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(pGia) )
pObj->Value = Mini_LutCreatePo( p, Gia_ObjFaninC0(pObj) );
else if ( !Gia_ObjFaninC0(pObj) )
else if ( Gia_ObjFaninC0(pObj) == Vec_BitEntry(vMarks, Gia_ObjFaninId0p(pGia, pObj)) )
pObj->Value = Mini_LutCreatePo( p, Gia_ObjFanin0(pObj)->Value );
else // add inverter LUT
{
@ -298,6 +334,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
pObj->Value = Mini_LutCreatePo( p, LutInv );
}
}
Vec_BitFree( vMarks );
// set registers
Mini_LutSetRegNum( p, Gia_ManRegNum(pGia) );
//Mini_LutPrintStats( p );

View File

@ -41,6 +41,7 @@ ABC_NAMESPACE_IMPL_START
#define NF_CUT_MAX 32
#define NF_NO_LEAF 31
#define NF_NO_FUNC 0x3FFFFFF
#define NF_EPSILON 0.001
typedef struct Nf_Cut_t_ Nf_Cut_t;
struct Nf_Cut_t_
@ -171,7 +172,7 @@ static inline int Nf_CfgCompl( Nf_Cfg_t Cfg, int i )
int Nf_StoCellIsDominated( Mio_Cell2_t * pCell, int * pFans, int * pProf )
{
int k;
if ( pCell->AreaF < Abc_Int2Float(pProf[0]) )
if ( pCell->AreaF + NF_EPSILON < Abc_Int2Float(pProf[0]) )
return 0;
for ( k = 0; k < (int)pCell->nFanins; k++ )
if ( pCell->iDelays[Abc_Lit2Var(pFans[k])] < pProf[k+1] )
@ -802,8 +803,8 @@ static inline int Nf_CutCompareArea( Nf_Cut_t * pCut0, Nf_Cut_t * pCut1 )
{
if ( pCut0->Useless < pCut1->Useless ) return -1;
if ( pCut0->Useless > pCut1->Useless ) return 1;
if ( pCut0->Flow < pCut1->Flow ) return -1;
if ( pCut0->Flow > pCut1->Flow ) return 1;
if ( pCut0->Flow < pCut1->Flow - NF_EPSILON ) return -1;
if ( pCut0->Flow > pCut1->Flow + NF_EPSILON ) return 1;
if ( pCut0->Delay < pCut1->Delay ) return -1;
if ( pCut0->Delay > pCut1->Delay ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
@ -1162,7 +1163,7 @@ void Nf_ManCutMatchOne( Nf_Man_t * p, int iObj, int * pCut, int * pCutSet )
pD->Cfg.fCompl = 0;
}
if ( pA->F > AreaF )
if ( pA->F > AreaF + NF_EPSILON )
{
pA->D = Delay;
pA->F = AreaF;
@ -1310,7 +1311,7 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj )
}
//assert( pAp->F < FLT_MAX || pAn->F < FLT_MAX );
// try replacing pos with neg
if ( pAp->D == SCL_INFINITY || (pAp->F > pAn->F + p->InvAreaF && pAn->D + p->InvDelayI <= Required[0]) )
if ( pAp->D == SCL_INFINITY || (pAp->F > pAn->F + p->InvAreaF + NF_EPSILON && pAn->D + p->InvDelayI <= Required[0]) )
{
assert( p->Iter > 0 );
*pAp = *pAn;
@ -1322,7 +1323,7 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj )
//printf( "Using inverter to improve area at node %d in phase %d.\n", iObj, 1 );
}
// try replacing neg with pos
else if ( pAn->D == SCL_INFINITY || (pAn->F > pAp->F + p->InvAreaF && pAp->D + p->InvDelayI <= Required[1]) )
else if ( pAn->D == SCL_INFINITY || (pAn->F > pAp->F + p->InvAreaF + NF_EPSILON && pAp->D + p->InvDelayI <= Required[1]) )
{
assert( p->Iter > 0 );
*pAn = *pAp;
@ -1778,7 +1779,7 @@ void Nf_ManElaBestMatchOne( Nf_Man_t * p, int iObj, int c, int * pCut, int * pCu
pMb->Cfg = Nf_Int2Cfg(0);
pMb->fBest = 1;
// compare
if ( pRes->F > pMb->F || (pRes->F == pMb->F && pRes->D > pMb->D) )
if ( pRes->F > pMb->F + NF_EPSILON || (pRes->F > pMb->F - NF_EPSILON && pRes->D > pMb->D) )
*pRes = *pMb;
return;
}
@ -1814,7 +1815,7 @@ void Nf_ManElaBestMatchOne( Nf_Man_t * p, int iObj, int c, int * pCut, int * pCu
// compute area
pMb->F = Scl_Int2Flt((int)Nf_MatchRefArea(p, iObj, c, pMb, Required));
// compare
if ( pRes->F > pMb->F || (pRes->F == pMb->F && pRes->D > pMb->D) )
if ( pRes->F > pMb->F + NF_EPSILON || (pRes->F > pMb->F - NF_EPSILON && pRes->D > pMb->D) )
*pRes = *pMb;
}
}

View File

@ -48,8 +48,6 @@ struct Qbf_Man_t_
abctime clkSat; // SAT solver time
};
extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@ -192,7 +190,7 @@ int Gia_ManSatEnum( Gia_Man_t * pGia, int nConfLimit, int nTimeOut, int fVerbose
int i, iLit, iParVarBeg, Iter;
int nSolutions = 0, RetValue = 0;
abctime clkStart = Abc_Clock();
pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
iParVarBeg = pCnf->nVars - Gia_ManPiNum(pGia);// - 1;
Cnf_DataFree( pCnf );
@ -247,7 +245,7 @@ void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars )
{
// original problem: \exists p \forall x \exists y. M(p,x,y)
// negated problem: \forall p \exists x \exists y. !M(p,x,y)
Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
Vec_Int_t * vVarMap, * vForAlls, * vExists;
Gia_Obj_t * pObj;
char * pFileName;
@ -291,7 +289,7 @@ Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fVerbose )
Qbf_Man_t * p;
Cnf_Dat_t * pCnf;
Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) );
pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) );
p = ABC_CALLOC( Qbf_Man_t, 1 );
p->clkStart = Abc_Clock();
@ -426,7 +424,7 @@ Gia_Man_t * Gia_QbfCofactor( Gia_Man_t * p, int nPars, Vec_Int_t * vValues, Vec_
/*
int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof )
{
Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 );
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 );
int i, iFirstVar = sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof);// - 1;
pCnf->pMan = NULL;
Cnf_DataLift( pCnf, sat_solver_nvars(p->pSatSyn) );
@ -459,7 +457,7 @@ void Cnf_SpecialDataLift( Cnf_Dat_t * p, int nVarsPlus, int firstPiVar, int last
int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof )
{
Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 );
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 );
int i, useold = 0;
int iFirstVar = useold ? sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof) : pCnf->nVars - Gia_ManPiNum(pCof); //-1
pCnf->pMan = NULL;

205
src/aig/gia/giaSatoko.c Normal file
View File

@ -0,0 +1,205 @@
/**CFile****************************************************************
FileName [giaSatoko.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
Synopsis [Interface to Satoko solver.]
Author [Alan Mishchenko, Bruno Schmitt]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaSatoko.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
#include "sat/cnf/cnf.h"
#include "sat/satoko/satoko.h"
#include "sat/satoko/solver.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManCollectVars_rec( int Var, Vec_Int_t * vMapping, Vec_Int_t * vRes, Vec_Bit_t * vVisit )
{
int * pCut, i;
if ( Vec_BitEntry(vVisit, Var) )
return;
Vec_BitWriteEntry(vVisit, Var, 1);
if ( Vec_IntEntry(vMapping, Var) ) // primary input or constant 0
{
pCut = Vec_IntEntryP( vMapping, Vec_IntEntry(vMapping, Var) );
for ( i = 1; i <= pCut[0]; i++ )
Gia_ManCollectVars_rec( pCut[i], vMapping, vRes, vVisit );
}
Vec_IntPush( vRes, Var );
}
Vec_Int_t * Gia_ManCollectVars( int Root, Vec_Int_t * vMapping, int nVars )
{
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
Vec_Bit_t * vVisit = Vec_BitStart( nVars );
assert( Vec_IntEntry(vMapping, Root) );
Gia_ManCollectVars_rec( Root, vMapping, vRes, vVisit );
Vec_BitFree( vVisit );
return vRes;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
satoko_t * Gia_ManSatokoInit( Cnf_Dat_t * pCnf, satoko_opts_t * opts )
{
satoko_t * pSat = satoko_create();
int i;
//sat_solver_setnvars( pSat, p->nVars );
for ( i = 0; i < pCnf->nClauses; i++ )
{
if ( !satoko_add_clause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) )
{
satoko_destroy( pSat );
return NULL;
}
}
satoko_configure(pSat, opts);
return pSat;
}
void Gia_ManSatokoReport( int iOutput, int status, abctime clk )
{
if ( iOutput >= 0 )
Abc_Print( 1, "Output %6d : ", iOutput );
else
Abc_Print( 1, "Total: " );
if ( status == SATOKO_UNDEC )
Abc_Print( 1, "UNDECIDED " );
else if ( status == SATOKO_SAT )
Abc_Print( 1, "SATISFIABLE " );
else
Abc_Print( 1, "UNSATISFIABLE " );
Abc_PrintTime( 1, "Time", clk );
}
satoko_t * Gia_ManSatokoCreate( Gia_Man_t * p, satoko_opts_t * opts )
{
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 1, 0, 0 );
satoko_t * pSat = Gia_ManSatokoInit( pCnf, opts );
int status = pSat ? satoko_simplify(pSat) : SATOKO_OK;
Cnf_DataFree( pCnf );
if ( status == SATOKO_OK )
return pSat;
satoko_destroy( pSat );
return NULL;
}
int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput )
{
abctime clk = Abc_Clock();
satoko_t * pSat;
int status, Cost = 0;
pSat = Gia_ManSatokoCreate( p, opts );
if ( pSat )
{
status = satoko_solve( pSat );
Cost = (unsigned)pSat->stats.n_conflicts;
satoko_destroy( pSat );
}
else
status = SATOKO_UNSAT;
Gia_ManSatokoReport( iOutput, status, Abc_Clock() - clk );
return Cost;
}
void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem )
{
int fUseCone = 1;
Gia_Man_t * pOne;
Gia_Obj_t * pRoot;
Vec_Int_t * vCone;
int i, iLit, status;
if ( fIncrem )
{
abctime clk = Abc_Clock();
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, fUseCone, 0 );
satoko_t * pSat = Gia_ManSatokoInit( pCnf, opts );
Gia_ManForEachCo( p, pRoot, i )
{
abctime clk = Abc_Clock();
iLit = Abc_Var2Lit( i+1, 0 );
satoko_assump_push( pSat, iLit );
if ( fUseCone )
{
vCone = Gia_ManCollectVars( i+1, pCnf->vMapping, pCnf->nVars );
satoko_mark_cone( pSat, Vec_IntArray(vCone), Vec_IntSize(vCone) );
printf( "Cone has %6d vars (out of %6d). ", Vec_IntSize(vCone), pCnf->nVars );
status = satoko_solve( pSat );
satoko_unmark_cone( pSat, Vec_IntArray(vCone), Vec_IntSize(vCone) );
Vec_IntFree( vCone );
}
else
{
status = satoko_solve( pSat );
}
satoko_assump_pop( pSat );
Gia_ManSatokoReport( i, status, Abc_Clock() - clk );
}
Cnf_DataFree( pCnf );
satoko_destroy( pSat );
Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
return;
}
if ( fSplit )
{
abctime clk = Abc_Clock();
Gia_ManForEachCo( p, pRoot, i )
{
pOne = Gia_ManDupDfsCone( p, pRoot );
Gia_ManSatokoCallOne( pOne, opts, i );
Gia_ManStop( pOne );
}
Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
return;
}
Gia_ManSatokoCallOne( p, opts, -1 );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

File diff suppressed because it is too large Load Diff

View File

@ -584,6 +584,8 @@ int Gia_ManLutLevelWithBoxes( Gia_Man_t * p )
Gia_Obj_t * pObj, * pObjIn;
int i, k, j, curCi, curCo, LevelMax;
assert( Gia_ManRegNum(p) == 0 );
if ( pManTime == NULL )
return Gia_ManLutLevel(p, NULL);
// copy const and real PIs
Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
Gia_ObjSetLevel( p, Gia_ManConst0(p), 0 );

View File

@ -137,6 +137,59 @@ word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp )
return Vec_WrdEntry( vTemp, iObj );
}
/**Function*************************************************************
Synopsis [Computes truth table up to 6 inputs in terms of CIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
word Gia_ObjComputeTruth6( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp )
{
int i, Fanin;
assert( Vec_WrdSize(vTemp) == Gia_ManObjNum(p) );
assert( Vec_IntSize(vSupp) <= 6 );
Gia_ManIncrementTravId( p );
Vec_IntForEachEntry( vSupp, Fanin, i )
{
Gia_ObjSetTravIdCurrentId( p, Fanin );
Vec_WrdWriteEntry( vTemp, Fanin, s_Truth6[i] );
}
Gia_ObjComputeTruthTable6Lut_rec( p, iObj, vTemp );
return Vec_WrdEntry( vTemp, iObj );
}
void Gia_ObjComputeTruth6CisSupport_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp )
{
Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
return;
Gia_ObjSetTravIdCurrentId(p, iObj);
if ( Gia_ObjIsCi(pObj) )
{
Vec_IntPushOrder( vSupp, iObj );
return;
}
assert( Gia_ObjIsAnd(pObj) );
Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId0p(p, pObj), vSupp );
Gia_ObjComputeTruth6CisSupport_rec( p, Gia_ObjFaninId1p(p, pObj), vSupp );
}
word Gia_ObjComputeTruth6Cis( Gia_Man_t * p, int iLit, Vec_Int_t * vSupp, Vec_Wrd_t * vTemp )
{
int iObj = Abc_Lit2Var(iLit);
Vec_IntClear( vSupp );
if ( !iObj ) return Abc_LitIsCompl(iLit) ? ~(word)0 : (word)0;
Gia_ManIncrementTravId( p );
Gia_ObjComputeTruth6CisSupport_rec( p, iObj, vSupp );
if ( Vec_IntSize(vSupp) > 6 )
return 0;
Gia_ObjComputeTruth6( p, iObj, vSupp, vTemp );
return Abc_LitIsCompl(iLit) ? ~Vec_WrdEntry(vTemp, iObj) : Vec_WrdEntry(vTemp, iObj);
}
/**Function*************************************************************
Synopsis [Computes truth table up to 6 inputs.]

View File

@ -937,8 +937,8 @@ int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** pp
return 0;
if ( Gia_ObjFaninC0(p0) == Gia_ObjFaninC0(p1) || Gia_ObjFaninC1(p0) == Gia_ObjFaninC1(p1) )
return 0;
*ppFan0 = Gia_ObjChild0(p0);
*ppFan1 = Gia_ObjChild1(p0);
if ( ppFan0 ) *ppFan0 = Gia_ObjChild0(p0);
if ( ppFan1 ) *ppFan1 = Gia_ObjChild1(p0);
return 1;
}

View File

@ -59,6 +59,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaSatLE.c \
src/aig/gia/giaSatLut.c \
src/aig/gia/giaSatMap.c \
src/aig/gia/giaSatoko.c \
src/aig/gia/giaScl.c \
src/aig/gia/giaScript.c \
src/aig/gia/giaShow.c \

View File

@ -2081,7 +2081,7 @@ void Ivy_FraigPrintActivity( Ivy_FraigMan_t * p )
{
int i;
for ( i = 0; i < p->nSatVars; i++ )
printf( "%d %d ", i, p->pSat->activity[i] );
printf( "%d %d ", i, (int)p->pSat->activity[i] );
printf( "\n" );
}

View File

@ -52,11 +52,13 @@ extern int Cmd_CommandExecute( void * pAbc, char * pCommandLine );
// procedures to input/output 'mini AIG'
extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig );
extern void * Abc_NtkOutputMiniAig( void * pAbc );
extern void Abc_FrameGiaInputMiniAig( void * pAbc, void * p );
extern void * Abc_FrameGiaOutputMiniAig( void * pAbc );
extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops );
// procedures to input/output 'mini AIG'
extern void Abc_NtkInputMiniLut( void * pAbc, void * pMiniLut );
extern void * Abc_NtkOutputMiniLut( void * pAbc );
// procedures to input/output 'mini LUT'
extern void Abc_FrameGiaInputMiniLut( void * pAbc, void * pMiniLut );
extern void * Abc_FrameGiaOutputMiniLut( void * pAbc );
// procedures to set CI/CO arrival/required times
extern void Abc_NtkSetCiArrivalTime( void * pAbc, int iCi, float Rise, float Fall );

View File

@ -1111,12 +1111,12 @@ int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int nFrames, int fVe
// report the miter
if ( RetValue == 1 )
{
printf( "Networks are equivalent. " );
printf( "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
printf( "Networks are NOT EQUIVALENT. " );
printf( "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
if ( pMiterCec->pData == NULL )
printf( "Counter-example is not available.\n" );

View File

@ -1077,6 +1077,7 @@ void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate )
***********************************************************************/
int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
{
int fAddBuffers = 1;
Vec_Ptr_t * vDrivers, * vCoTerms;
Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
int i, k, LevelMax, nTotal = 0;
@ -1191,6 +1192,12 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
// collect COs that needs fixing by adding buffers or duplicating
vCoTerms = Vec_PtrAlloc( 100 );
Abc_NtkIncrementTravId( pNtk );
// The following cases should be addressed only if the network is written
// into a BLIF file. Otherwise, it is possible to skip them:
// (1) if a CO points to a CI with a different name
// (2) if an internal node drives more than one CO
if ( fAddBuffers )
Abc_NtkForEachCo( pNtk, pNode, i )
{
// if the driver is a CI and has different name, this is an error
@ -2926,6 +2933,160 @@ void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
Vec_IntWriteEntry( pNtkNew->vPhases, Abc_ObjId( (Abc_Obj_t *)pObj->pCopy ), Vec_IntEntry(pNtk->vPhases, i) );
}
/**Function*************************************************************
Synopsis [Starts a new network using existing network as a model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDeriveWithOnePo( Abc_Ntk_t * pNtk, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues )
{
int fCopyNames = 1;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin, * pObjNew, * pOutputNew;
Vec_Ptr_t * vFanins = Vec_PtrAlloc( 100 );
int i, k, Id, Value;
// start the network
pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
// duplicate the name and the spec
pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
// clean the node copy fields
Abc_NtkCleanCopy( pNtk );
// map the constant nodes
if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
// clone CIs/CIs/boxes
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, fCopyNames );
//Abc_NtkForEachPo( pNtk, pObj, i )
// Abc_NtkDupObj( pNtkNew, pObj, fCopyNames );
// create one PO
pObjNew = Abc_NtkCreateObj( pNtkNew, ABC_OBJ_PO );
Abc_ObjAssignName( pObjNew, "monitor", NULL );
// create boxes
Abc_NtkForEachBox( pNtk, pObj, i )
Abc_NtkDupBox( pNtkNew, pObj, fCopyNames );
// duplicate nodes (CIs/COs/latches are already duplicated)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->pCopy == NULL && !Abc_ObjIsPo(pObj) )
Abc_NtkDupObj(pNtkNew, pObj, 0);
// reconnect all objects except boxes (they are already connected) and POs (they will be connected later)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( !Abc_ObjIsPo(pObj) && !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// AND nodes (with interters if needed)
pOutputNew = NULL;
Vec_IntForEachEntryTwo( vNodeIds, vNodeValues, Id, Value, i )
{
pObjNew = Abc_NtkObj( pNtk, Id )->pCopy;
if ( Value == 0 ) // negative polarity - add inverter
pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew );
if ( pOutputNew == NULL )
pOutputNew = pObjNew;
else
{
Vec_PtrFillTwo( vFanins, 2, pOutputNew, pObjNew );
pOutputNew = Abc_NtkCreateNodeAnd( pNtkNew, vFanins );
}
}
Vec_PtrFree( vFanins );
// create the only POs, which is the AND of the corresponding nodes
Abc_ObjAddFanin( Abc_NtkPo(pNtkNew, 0), pOutputNew );
// check that the CI/CO/latches are copied correctly
assert( Abc_NtkPoNum(pNtkNew) == 1 );
assert( Abc_NtkCiNum(pNtkNew) == Abc_NtkCiNum(pNtk) );
assert( Abc_NtkLatchNum(pNtkNew) == Abc_NtkLatchNum(pNtk) );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Derives the AIG representing a property.]
Description [Given is a sequential logic network (Abc_Ntk_t) and
an array of nodes (vector of object IDs) and their values (vector of 0s or 1s).
This procedure creates a sequential AIG (Abc_Ntk_t), which can be given to a
sequential model checker (in particular "pdr") to prove that the given
combination of values never appears at the intenal nodes of the network,
or produce a counter-example showing that it can appear.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkCreatePropertyMonitor( Abc_Ntk_t * p, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues )
{
Abc_Ntk_t * pMonitor, * pStrashed, * pResult;
// sequential cleanup parameters
int fLatchConst = 1;
int fLatchEqual = 1;
int fSaveNames = 1;
int fUseMvSweep = 0;
int nFramesSymb = 1;
int nFramesSatur = 512;
int fVerbose = 0;
int fVeryVerbose = 0;
// expecting sequential logic network
assert( Abc_NtkIsLogic(p) );
assert( Abc_NtkLatchNum(p) > 0 );
assert( Vec_IntSize(vNodeIds) > 0 );
assert( Vec_IntSize(vNodeIds) == Vec_IntSize(vNodeValues) );
// derive ABC network whose only output is 1 iff the given nodes have the given values
pMonitor = Abc_NtkDeriveWithOnePo( p, vNodeIds, vNodeValues );
// perform structural hashing
pStrashed = Abc_NtkStrash( pMonitor, 0, 1, 0 );
Abc_NtkDelete( pMonitor );
// it is a good idea to run sequential cleanup before giving the network to PDR
pResult = Abc_NtkDarLatchSweep( pStrashed, fLatchConst, fLatchEqual, fSaveNames, fUseMvSweep, nFramesSymb, nFramesSatur, fVerbose, fVeryVerbose );
Abc_NtkDelete( pStrashed );
return pResult;
}
/**Function*************************************************************
Synopsis [Testbench.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkCreatePropertyMonitorTest( Abc_Ntk_t * p )
{
Abc_Ntk_t * pNtk;
Vec_Int_t * vNodeIds = Vec_IntAlloc( 100 );
Vec_Int_t * vNodeValues = Vec_IntAlloc( 100 );
// this test will only work for the network, which has nodes with internal IDs such as these
Vec_IntPush( vNodeIds, 90 );
Vec_IntPush( vNodeIds, 80 );
Vec_IntPush( vNodeIds, 100 );
Vec_IntPush( vNodeValues, 1 );
Vec_IntPush( vNodeValues, 0 );
Vec_IntPush( vNodeValues, 1 );
pNtk = Abc_NtkCreatePropertyMonitor( p, vNodeIds, vNodeValues );
Vec_IntFree( vNodeIds );
Vec_IntFree( vNodeValues );
return pNtk;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -537,8 +537,6 @@ extern Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose );
extern int Gia_ManCoLargestSupp( Gia_Man_t * p, Vec_Wec_t * vSupps );
extern Vec_Wec_t * Gia_ManIsoStrashReduceInt( Gia_Man_t * p, Vec_Wec_t * vSupps, int fVerbose );
extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
/**Function*************************************************************
Synopsis [Derives GIA for the network.]
@ -802,7 +800,7 @@ Vec_Ptr_t * Abc_GiaDeriveSops( Abc_Ntk_t * pNtkNew, Gia_Man_t * p, Vec_Wec_t * v
if ( fCnfShared )
{
vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
pCnf = Mf_ManGenerateCnf( p, 8, 1, 0, 0 );
pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 1, 0, 0, 0 );
}
vSopsRepr = Vec_PtrStart( Vec_IntSize(vReprs) );
pProgress = Extra_ProgressBarStart( stdout, Vec_IntSize(vReprs) );

View File

@ -1946,17 +1946,17 @@ finish:
// report the miter
if ( RetValue == 1 )
{
Abc_Print( 1, "Networks are equivalent. " );
Abc_Print( 1, "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else
{
Abc_Print( 1, "Networks are UNDECIDED. " );
Abc_Print( 1, "Networks are UNDECIDED. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
fflush( stdout );
@ -3695,17 +3695,17 @@ int Abc_NtkDarInduction( Abc_Ntk_t * pNtk, int nTimeOut, int nFramesMax, int nCo
RetValue = Saig_ManInduction( pMan, nTimeOut, nFramesMax, nConfMax, fUnique, fUniqueAll, fGetCex, fVerbose, fVeryVerbose );
if ( RetValue == 1 )
{
Abc_Print( 1, "Networks are equivalent. " );
Abc_Print( 1, "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else
{
Abc_Print( 1, "Networks are UNDECIDED. " );
Abc_Print( 1, "Networks are UNDECIDED. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( fGetCex )

View File

@ -901,8 +901,7 @@ Vec_Int_t * Abc_NtkFinCheckPair( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t
}
else
{
extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
if ( pSat == NULL )
{

View File

@ -33,32 +33,6 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Compute equivalence classes of nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose )
{
Gia_Man_t * pTemp;
Cec_ParFra_t ParsFra, * pPars = &ParsFra;
Cec_ManFraSetDefaultParams( pPars );
pPars->fUseOrigIds = 1;
pPars->fSatSweeping = 1;
pPars->nBTLimit = nConfs;
pPars->fVerbose = fVerbose;
pTemp = Cec_ManSatSweeping( pGia, pPars, 0 );
Gia_ManStop( pTemp );
pTemp = Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv );
Gia_ManStop( pTemp );
}
/**Function*************************************************************
Synopsis [Converts AIG from HOP to GIA.]
@ -315,13 +289,15 @@ void Abc_NtkDumpEquivFile( char * pFileName, Vec_Int_t * vClasses, Abc_Ntk_t * p
void Abc_NtkDumpEquiv( Abc_Ntk_t * pNtks[2], char * pFileName, int nConfs, int fByName, int fVerbose )
{
//abctime clk = Abc_Clock();
Gia_Man_t * pTemp;
Vec_Int_t * vClasses;
// derive shared AIG for the two networks
Gia_Man_t * pGia = Abc_NtkAigToGiaTwo( pNtks[0], pNtks[1], fByName );
if ( fVerbose )
printf( "Computing equivalences for networks \"%s\" and \"%s\" with conflict limit %d.\n", Abc_NtkName(pNtks[0]), Abc_NtkName(pNtks[1]), nConfs );
// compute equivalences in this AIG
Abc_NtkComputeGiaEquivs( pGia, nConfs, fVerbose );
pTemp = Gia_ManComputeGiaEquivs( pGia, nConfs, fVerbose );
Gia_ManStop( pTemp );
//if ( fVerbose )
// Abc_PrintTime( 1, "Equivalence computation time", Abc_Clock() - clk );
if ( fVerbose )

View File

@ -873,7 +873,7 @@ static void Ses_StoreRead( Ses_Store_t * pStore, const char * pFilename, int fSy
fclose( pFile );
printf( "read %lu entries from file\n", nEntries );
printf( "read %lu entries from file\n", (long)nEntries );
}
// computes top decomposition of variables wrt. to AND and OR

View File

@ -259,7 +259,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
if ( nFaninMax > 6 )
{
Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" );
return 0;
return 1;
}
if ( !Abc_NtkHasSop(pNtk) )
if ( !Abc_NtkToSop( pNtk, -1, ABC_INFINITY ) )

View File

@ -122,6 +122,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
***********************************************************************/
void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose )
{
abctime clk = Abc_Clock();
Prove_Params_t Params, * pParams = &Params;
// Fraig_Params_t Params;
// Fraig_Man_t * pMan;
@ -170,18 +171,20 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
RetValue = Abc_NtkMiterIsConstant( pMiter );
if ( RetValue == 0 )
{
printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
printf( "Networks are NOT EQUIVALENT after structural hashing. " );
// report the error
pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 );
Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel );
ABC_FREE( pMiter->pModel );
Abc_NtkDelete( pMiter );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return;
}
if ( RetValue == 1 )
{
printf( "Networks are equivalent after structural hashing.\n" );
printf( "Networks are equivalent after structural hashing. " );
Abc_NtkDelete( pMiter );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return;
}
/*
@ -220,18 +223,19 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
// pParams->fVerbose = 1;
RetValue = Abc_NtkIvyProve( &pMiter, pParams );
if ( RetValue == -1 )
printf( "Networks are undecided (resource limits is reached).\n" );
printf( "Networks are undecided (resource limits is reached). " );
else if ( RetValue == 0 )
{
int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel );
if ( pSimInfo[0] != 1 )
printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" );
else
printf( "Networks are NOT EQUIVALENT.\n" );
printf( "Networks are NOT EQUIVALENT. " );
ABC_FREE( pSimInfo );
}
else
printf( "Networks are equivalent.\n" );
printf( "Networks are equivalent. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
if ( pMiter->pModel )
Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel );
Abc_NtkDelete( pMiter );

View File

@ -60,6 +60,7 @@ static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv
static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandStarter ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandAutoTuner ( Abc_Frame_t * pAbc, int argc, char ** argv );
extern int Cmd_CommandAbcLoadPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -110,6 +111,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1 );
Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0 );
Cmd_CommandAdd( pAbc, "Various", "starter", CmdCommandStarter, 0 );
Cmd_CommandAdd( pAbc, "Various", "autotuner", CmdCommandAutoTuner, 0 );
Cmd_CommandAdd( pAbc, "Various", "load_plugin", Cmd_CommandAbcLoadPlugIn, 0 );
}
@ -1147,26 +1149,7 @@ usage:
#if defined(WIN32) && !defined(__cplusplus)
#include <direct.h>
// these structures are defined in <io.h> but are for some reason invisible
typedef unsigned long _fsize_t; // Could be 64 bits for Win32
struct _finddata_t {
unsigned attrib;
time_t time_create; // -1 for FAT file systems
time_t time_access; // -1 for FAT file systems
time_t time_write;
_fsize_t size;
char name[260];
};
extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
extern int _findnext( long handle, struct _finddata_t *fileinfo );
extern int _findclose( long handle );
//extern char * _getcwd( char * buffer, int maxlen );
//extern int _chdir( const char *dirname );
#include <io.h>
/**Function*************************************************************
@ -2476,6 +2459,118 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores );
FILE * pFile;
char * pFileConf = NULL;
char * pFileList = NULL;
char * pFileName;
int c, nCores = 3;
int fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "NCFvh" ) ) != EOF )
{
switch ( c )
{
case 'N':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
goto usage;
}
nCores = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nCores < 0 )
goto usage;
break;
case 'C':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-C\" should be followed by a string (possibly in quotes).\n" );
goto usage;
}
pFileConf = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-F\" should be followed by a string (possibly in quotes).\n" );
goto usage;
}
pFileList = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pFileConf == NULL )
{
Abc_Print( -2, "File containing configuration for autotuning is not given.\n" );
return 1;
}
if ( pFileList == NULL )
{
Abc_Print( -2, "File contining list of files for autotuning is not given.\n" );
return 1;
}
// get the input file name
pFileName = pFileConf;
if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL )
// if ( (pFile = fopen( pFileName, "rb" )) == NULL )
{
Abc_Print( -2, "Cannot open configuration file \"%s\". ", pFileName );
if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) ))
Abc_Print( -2, "Did you mean \"%s\"?", pFileName );
Abc_Print( -2, "\n" );
return 1;
}
fclose( pFile );
// get the input file name
pFileName = pFileList;
if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL )
// if ( (pFile = fopen( pFileName, "rb" )) == NULL )
{
Abc_Print( -2, "Cannot open the file list \"%s\". ", pFileName );
if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) ))
Abc_Print( -2, "Did you mean \"%s\"?", pFileName );
Abc_Print( -2, "\n" );
return 1;
}
fclose( pFile );
// run commands
Cmd_RunAutoTuner( pFileConf, pFileList, nCores );
return 0;
usage:
Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" );
Abc_Print( -2, "\t performs autotuning\n" );
Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores );
Abc_Print( -2, "\t-C cmd : configuration file with settings for autotuning\n" );
Abc_Print( -2, "\t-F cmd : list of AIGER files to be used for autotuning\n" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
/**Function********************************************************************
Synopsis [Print the version string.]

684
src/base/cmd/cmdAuto.c Normal file
View File

@ -0,0 +1,684 @@
/**CFile****************************************************************
FileName [cmdAuto.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Command processing package.]
Synopsis [Autotuner.]
Author [Alan Mishchenko, Bruno Schmitt]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cmdAuto.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "misc/util/abc_global.h"
#include "misc/extra/extra.h"
#include "aig/gia/gia.h"
#include "sat/satoko/satoko.h"
#ifdef ABC_USE_PTHREADS
#ifdef _WIN32
#include "../lib/pthread.h"
#else
#include <pthread.h>
#include <unistd.h>
#endif
#endif
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string
#define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call
extern int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Printing option structure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts )
{
printf( "-C %d ", (int)pOpts->conf_limit );
printf( "-V %.3f ", (float)pOpts->var_decay );
printf( "-W %.3f ", (float)pOpts->clause_decay );
if ( pOpts->verbose )
printf( "-v" );
printf( "\n" );
}
/**Function*************************************************************
Synopsis [The main evaluation procedure for an array of AIGs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts )
{
Gia_Man_t * pGia;
int i, TotalCost = 0;
//printf( "Tuning with options: " );
//Cmd_RunAutoTunerPrintOptions( pOpts );
Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
TotalCost += Gia_ManSatokoCallOne( pGia, pOpts, -1 );
return TotalCost;
}
/**Function*************************************************************
Synopsis [The main evaluation procedure for the set of AIGs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
#ifndef ABC_USE_PTHREADS
int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nCores )
{
return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts );
}
#else // pthreads are used
#define CMD_THR_MAX 100
typedef struct Cmd_AutoData_t_
{
Gia_Man_t * pGia;
satoko_opts_t * pOpts;
int iThread;
int nTimeOut;
int fWorking;
int Result;
} Cmd_AutoData_t;
void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg )
{
Cmd_AutoData_t * pThData = (Cmd_AutoData_t *)pArg;
volatile int * pPlace = &pThData->fWorking;
while ( 1 )
{
while ( *pPlace == 0 );
assert( pThData->fWorking );
if ( pThData->pGia == NULL ) // kills itself when there is nothing to do
{
pthread_exit( NULL );
assert( 0 );
return NULL;
}
pThData->Result = Gia_ManSatokoCallOne( pThData->pGia, pThData->pOpts, -1 );
pThData->fWorking = 0;
}
assert( 0 );
return NULL;
}
int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs )
{
Cmd_AutoData_t ThData[CMD_THR_MAX];
pthread_t WorkerThread[CMD_THR_MAX];
int i, status, fWorkToDo = 1, TotalCost = 0;
Vec_Ptr_t * vStack;
if ( nProcs == 1 )
return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts );
// subtract manager thread
nProcs--;
assert( nProcs >= 1 && nProcs <= CMD_THR_MAX );
// start threads
for ( i = 0; i < nProcs; i++ )
{
ThData[i].pGia = NULL;
ThData[i].pOpts = pOpts;
ThData[i].iThread = i;
ThData[i].nTimeOut = -1;
ThData[i].fWorking = 0;
ThData[i].Result = -1;
status = pthread_create( WorkerThread + i, NULL,Cmd_RunAutoTunerEvalWorkerThread, (void *)(ThData + i) ); assert( status == 0 );
}
// look at the threads
vStack = Vec_PtrDup(vAigs);
while ( fWorkToDo )
{
fWorkToDo = (int)(Vec_PtrSize(vStack) > 0);
for ( i = 0; i < nProcs; i++ )
{
// check if this thread is working
if ( ThData[i].fWorking )
{
fWorkToDo = 1;
continue;
}
// check if this thread has recently finished
if ( ThData[i].pGia != NULL )
{
assert( ThData[i].Result >= 0 );
TotalCost += ThData[i].Result;
ThData[i].pGia = NULL;
}
if ( Vec_PtrSize(vStack) == 0 )
continue;
// give this thread a new job
assert( ThData[i].pGia == NULL );
ThData[i].pGia = (Gia_Man_t *)Vec_PtrPop( vStack );
ThData[i].fWorking = 1;
}
}
Vec_PtrFree( vStack );
// stop threads
for ( i = 0; i < nProcs; i++ )
{
assert( !ThData[i].fWorking );
// stop
ThData[i].pGia = NULL;
ThData[i].fWorking = 1;
}
return TotalCost;
}
#endif // pthreads are used
/**Function*************************************************************
Synopsis [Derives all possible param stucts according to the config file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Cmd_DeriveConvertIntoString( int argc, char ** argv )
{
char pBuffer[CMD_AUTO_LINE_MAX] = {0};
int i;
for ( i = 0; i < argc; i++ )
{
strcat( pBuffer, argv[i] );
strcat( pBuffer, " " );
}
return Abc_UtilStrsav(pBuffer);
}
satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv )
{
int c;
satoko_opts_t opts, * pOpts;
satoko_default_opts(&opts);
Extra_UtilGetoptReset();
#ifdef SATOKO_ACT_VAR_FIXED
while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF )
#else
while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF )
#endif
{
switch ( c )
{
case 'C':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
return NULL;
}
opts.conf_limit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( opts.conf_limit < 0 )
return NULL;
break;
case 'P':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" );
return NULL;
}
opts.prop_limit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( opts.prop_limit < 0 )
return NULL;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" );
return NULL;
}
opts.f_rst = atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( opts.f_rst < 0 )
return NULL;
break;
case 'E':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" );
return NULL;
}
opts.b_rst = atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( opts.b_rst < 0 )
return NULL;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
return NULL;
}
opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'G':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" );
return NULL;
}
opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'H':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" );
return NULL;
}
opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'I':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
return NULL;
}
opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'J':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" );
return NULL;
}
opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'K':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
return NULL;
}
opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'L':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" );
return NULL;
}
opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'M':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
return NULL;
}
opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100;
globalUtilOptind++;
if ( opts.learnt_ratio < 0 )
return NULL;
break;
case 'N':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
return NULL;
}
opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100;
globalUtilOptind++;
if ( opts.garbage_max_ratio < 0 )
return NULL;
break;
case 'O':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
return NULL;
}
opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'Q':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
return NULL;
}
opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'R':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" );
return NULL;
}
opts.clause_decay = atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( opts.clause_decay < 0 )
return NULL;
break;
case 'S':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" );
return NULL;
}
opts.var_decay = atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( opts.var_decay < 0 )
return NULL;
break;
#ifdef SATOKO_ACT_VAR_FIXED
case 'T':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" );
return NULL;
}
opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16);
globalUtilOptind++;
break;
case 'U':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" );
return NULL;
}
opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16);
globalUtilOptind++;
break;
#endif
case 'h':
return NULL;
case 'v':
opts.verbose ^= 1;
break;
default:
return NULL;
}
}
// return a copy of this parameter structure
pOpts = ABC_ALLOC( satoko_opts_t, 1 );
memcpy( pOpts, &opts, sizeof(satoko_opts_t) );
return pOpts;
}
void Cmf_CreateOptions_rec( Vec_Wec_t * vPars, int iPar, char Argv[CMD_AUTO_ARG_MAX][20], int Argc, Vec_Ptr_t * vOpts )
{
Vec_Int_t * vLine;
int Symb, Num, i;
assert( Argc <= CMD_AUTO_ARG_MAX );
if ( Vec_WecSize(vPars) == iPar )
{
satoko_opts_t * pOpts;
char * pArgv[CMD_AUTO_ARG_MAX];
for ( i = 0; i < Argc; i++ )
pArgv[i] = Argv[i];
pOpts = Cmd_DeriveOptionFromSettings( Argc, pArgv );
if ( pOpts == NULL )
printf( "Cannot parse command line options...\n" );
else
{
Vec_PtrPush( vOpts, pOpts );
Vec_PtrPush( vOpts, Cmd_DeriveConvertIntoString(Argc, pArgv) );
printf( "Adding settings %s\n", (char *)Vec_PtrEntryLast(vOpts) );
}
return;
}
vLine = Vec_WecEntry( vPars, iPar );
// consider binary option
if ( Vec_IntSize(vLine) == 2 )
{
Symb = Vec_IntEntry( vLine, 0 );
Num = Vec_IntEntry( vLine, 1 );
assert( Abc_Int2Float(Num) == -1.0 );
// create one setting without this option
Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc, vOpts );
// create another setting with this option
sprintf( Argv[Argc], "-%c", Symb );
Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+1, vOpts );
return;
}
// consider numeric option
Vec_IntForEachEntryDouble( vLine, Symb, Num, i )
{
float NumF = Abc_Int2Float(Num);
// create setting with this option
assert( NumF >= 0 );
sprintf( Argv[Argc], "-%c", Symb );
if ( NumF == (float)(int)NumF )
sprintf( Argv[Argc+1], "%d", (int)NumF );
else
sprintf( Argv[Argc+1], "%.3f", NumF );
Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+2, vOpts );
}
}
Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars )
{
char Argv[CMD_AUTO_ARG_MAX][20];
int Symb, Num, i, Argc = 0;
Vec_Ptr_t * vOpts = Vec_PtrAlloc( 100 );
Vec_Int_t * vLine = Vec_WecEntry( vPars, 0 );
printf( "Creating all possible settings to be used by the autotuner:\n" );
sprintf( Argv[Argc++], "autotuner" );
Vec_IntForEachEntryDouble( vLine, Symb, Num, i )
{
float NumF = Abc_Int2Float(Num);
sprintf( Argv[Argc++], "-%c", Symb );
if ( NumF < 0.0 )
continue;
if ( NumF == (float)(int)NumF )
sprintf( Argv[Argc++], "%d", (int)NumF );
else
sprintf( Argv[Argc++], "%.3f", NumF );
}
Cmf_CreateOptions_rec( vPars, 1, Argv, Argc, vOpts );
printf( "Finished creating %d settings.\n\n", Vec_PtrSize(vOpts)/2 );
return vOpts;
}
/**Function*************************************************************
Synopsis [Parses config file and derives AIGs listed in file list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; }
static inline int Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; }
static inline int Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; }
static inline int Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; }
Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig )
{
Vec_Wec_t * vPars;
Vec_Int_t * vLine;
char * pThis, pBuffer[CMD_AUTO_LINE_MAX];
FILE * pFile = fopen( pConfig, "rb" );
if ( pFile == NULL )
{ printf( "File containing list of files \"%s\" cannot be opened.\n", pConfig ); return NULL; }
vPars = Vec_WecAlloc( 100 );
while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL )
{
// get the command from the file
if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#')
continue;
// skip trailing spaces
while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) )
pBuffer[strlen(pBuffer)-1] = 0;
// read the line
vLine = Vec_WecPushLevel( vPars );
for ( pThis = pBuffer; *pThis; )
{
if ( Cmf_IsLowerCaseChar(*pThis) )
{
Vec_IntPushTwo( vLine, (int)*pThis, Abc_Float2Int((float)-1.0) );
pThis++;
while ( Cmf_IsSpace(*pThis) )
pThis++;
continue;
}
if ( Cmf_IsUpperCaseChar(*pThis) )
{
char Param = *pThis++;
if ( !Cmf_IsDigit(*pThis) )
{ printf( "Upper-case character (%c) should be followed by a number without space in line \"%s\".\n", Param, pBuffer ); return NULL; }
Vec_IntPushTwo( vLine, (int)Param, Abc_Float2Int(atof(pThis)) );
while ( Cmf_IsDigit(*pThis) )
pThis++;
while ( Cmf_IsSpace(*pThis) )
pThis++;
continue;
}
printf( "Expecting a leading lower-case or upper-case digit in line \"%s\".\n", pBuffer );
return NULL;
}
}
fclose( pFile );
return vPars;
}
Vec_Ptr_t * Cmd_ReadFiles( char * pFileList )
{
Gia_Man_t * pGia;
Vec_Ptr_t * vAigs;
char pBuffer[CMD_AUTO_LINE_MAX];
FILE * pFile = fopen( pFileList, "rb" );
if ( pFile == NULL )
{ printf( "File containing list of files \"%s\" cannot be opened.\n", pFileList ); return NULL; }
vAigs = Vec_PtrAlloc( 100 );
while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL )
{
// get the command from the file
if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#')
continue;
// skip trailing spaces
while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) )
pBuffer[strlen(pBuffer)-1] = 0;
// read the file
pGia = Gia_AigerRead( pBuffer, 0, 0, 0 );
if ( pGia == NULL )
{
printf( "Cannot read AIG from file \"%s\".\n", pBuffer );
continue;
}
Vec_PtrPush( vAigs, pGia );
}
fclose( pFile );
return vAigs;
}
/**Function*************************************************************
Synopsis [Autotuner for SAT solver "satoko".]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores )
{
abctime clk = Abc_Clock();
Vec_Wec_t * vPars = Cmd_ReadParamChoices( pConfig );
Vec_Ptr_t * vAigs = Cmd_ReadFiles( pFileList );
Vec_Ptr_t * vOpts = vPars ? Cmf_CreateOptions( vPars ) : NULL;
int i; char * pString, * pStringBest = NULL;
satoko_opts_t * pOpts, * pOptsBest = NULL;
int Result, ResultBest = 0x7FFFFFFF;
Gia_Man_t * pGia;
// iterate through all possible option settings
if ( vAigs && vOpts )
{
Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i )
{
abctime clk = Abc_Clock();
printf( "Evaluating settings: %20s... \n", pString );
Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores );
printf( "Cost = %6d. ", Result );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
if ( ResultBest > Result )
{
ResultBest = Result;
pStringBest = pString;
pOptsBest = pOpts;
}
}
printf( "The best settings are: %20s \n", pStringBest );
printf( "Best cost = %6d. ", ResultBest );
Abc_PrintTime( 1, "Total time", Abc_Clock() - clk );
}
// cleanup
if ( vPars ) Vec_WecFree( vPars );
if ( vOpts ) Vec_PtrFreeFree( vOpts );
if ( vAigs )
{
Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i )
Gia_ManStop( pGia );
Vec_PtrFree( vAigs );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -97,26 +97,7 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv )
#if defined(WIN32) && !defined(__cplusplus)
#include <direct.h>
// these structures are defined in <io.h> but are for some reason invisible
typedef unsigned long _fsize_t; // Could be 64 bits for Win32
struct _finddata_t {
unsigned attrib;
time_t time_create; // -1 for FAT file systems
time_t time_access; // -1 for FAT file systems
time_t time_write;
_fsize_t size;
char name[260];
};
extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
extern int _findnext( long handle, struct _finddata_t *fileinfo );
extern int _findclose( long handle );
//extern char * _getcwd( char * buffer, int maxlen );
//extern int _chdir( const char *dirname );
#include <io.h>
/**Function*************************************************************

View File

@ -1,6 +1,7 @@
SRC += src/base/cmd/cmd.c \
src/base/cmd/cmdAlias.c \
src/base/cmd/cmdApi.c \
src/base/cmd/cmdAuto.c \
src/base/cmd/cmdFlag.c \
src/base/cmd/cmdHist.c \
src/base/cmd/cmdLoad.c \

View File

@ -2150,7 +2150,7 @@ int IoCommandWriteCnf2( Abc_Frame_t * pAbc, int argc, char **argv )
extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
FILE * pFile;
char * pFileName;
int nLutSize = 6;
int nLutSize = 8;
int fNewAlgo = 1;
int fCnfObjIds = 0;
int fAddOrCla = 1;
@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv )
Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose );
}
else
pCare = Bmc_CexCareMinimize( pAig, pCex, fCheckCex, fVerbose );
pCare = Bmc_CexCareMinimize( pAig, Saig_ManPiNum(pAig), pCex, 4, fCheckCex, fVerbose );
Aig_ManStop( pAig );
}
// output flop values (unaffected by the minimization)

View File

@ -394,7 +394,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pFanin->Id );
fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" );
// fprintf( pFile, ", label = \"%c\"", 'a' + k );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
@ -764,7 +764,7 @@ void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", pFanin->Id );
fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" );
// fprintf( pFile, ", label = \"%c\"", 'a' + k );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );

View File

@ -95,8 +95,6 @@ void Abc_FrameSetStatus( int Status ) { ABC_FREE( s_Globa
void Abc_FrameSetManDsd( void * pMan ) { if (s_GlobalFrame->pManDsd && s_GlobalFrame->pManDsd != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd, 0); s_GlobalFrame->pManDsd = pMan; }
void Abc_FrameSetManDsd2( void * pMan ) { if (s_GlobalFrame->pManDsd2 && s_GlobalFrame->pManDsd2 != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd2, 0); s_GlobalFrame->pManDsd2 = pMan; }
void Abc_FrameSetInv( Vec_Int_t * vInv ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcInv); s_GlobalFrame->pAbcWlcInv = vInv; }
void Abc_FrameSetCnf( Vec_Int_t * vCnf ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcCnf); s_GlobalFrame->pAbcWlcCnf = vCnf; }
void Abc_FrameSetStr( Vec_Str_t * vStr ) { Vec_StrFreeP(&s_GlobalFrame->pAbcWlcStr); s_GlobalFrame->pAbcWlcStr = vStr; }
void Abc_FrameSetJsonStrs( Abc_Nam_t * pStrs ) { Abc_NamDeref( s_GlobalFrame->pJsonStrs ); s_GlobalFrame->pJsonStrs = pStrs; }
void Abc_FrameSetJsonObjs( Vec_Wec_t * vObjs ) { Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); s_GlobalFrame->vJsonObjs = vObjs; }
@ -227,8 +225,6 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
ABC_FREE( p->pCex2 );
ABC_FREE( p->pCex );
Vec_IntFreeP( &p->pAbcWlcInv );
Vec_IntFreeP( &p->pAbcWlcCnf );
Vec_StrFreeP( &p->pAbcWlcStr );
Abc_NamDeref( s_GlobalFrame->pJsonStrs );
Vec_WecFreeP(&s_GlobalFrame->vJsonObjs );
ABC_FREE( p );

View File

@ -129,8 +129,6 @@ struct Abc_Frame_t_
void * pAbc85Delay;
void * pAbcWlc;
Vec_Int_t * pAbcWlcInv;
Vec_Int_t * pAbcWlcCnf;
Vec_Str_t * pAbcWlcStr;
void * pAbcBac;
void * pAbcCba;
void * pAbcPla;

View File

@ -196,7 +196,7 @@ int Abc_RealMain( int argc, char * argv[] )
case 't':
if ( TypeCheck( pAbc, globalUtilOptarg ) )
{
if ( !strcmp(globalUtilOptarg, "none") == 0 )
if ( (!strcmp(globalUtilOptarg, "none")) == 0 )
{
fInitRead = 1;
sprintf( sReadCmd, "read_%s", globalUtilOptarg );
@ -211,7 +211,7 @@ int Abc_RealMain( int argc, char * argv[] )
case 'T':
if ( TypeCheck( pAbc, globalUtilOptarg ) )
{
if (!strcmp(globalUtilOptarg, "none") == 0)
if ( (!strcmp(globalUtilOptarg, "none")) == 0)
{
fFinalWrite = 1;
sprintf( sWriteCmd, "write_%s", globalUtilOptarg);

View File

@ -1,4 +1,5 @@
SRC += src/base/wlc/wlcAbs.c \
src/base/wlc/wlcAbs2.c \
src/base/wlc/wlcAbc.c \
src/base/wlc/wlcBlast.c \
src/base/wlc/wlcCom.c \
@ -7,6 +8,8 @@ SRC += src/base/wlc/wlcAbs.c \
src/base/wlc/wlcReadSmt.c \
src/base/wlc/wlcReadVer.c \
src/base/wlc/wlcSim.c \
src/base/wlc/wlcShow.c \
src/base/wlc/wlcStdin.c \
src/base/wlc/wlcUif.c \
src/base/wlc/wlcWin.c \
src/base/wlc/wlcWriteVer.c

View File

@ -140,6 +140,7 @@ struct Wlc_Ntk_t_
int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type
int nAnds[WLC_OBJ_NUMBER]; // counter of AND gates after blasting
int fSmtLib; // the network comes from an SMT-LIB file
int nAssert; // the number of asserts
// memory for objects
Wlc_Obj_t * pObjs;
int iObj;
@ -156,6 +157,23 @@ struct Wlc_Ntk_t_
Vec_Int_t vTravIds; // trav IDs of the objects
Vec_Int_t vCopies; // object first bits
Vec_Int_t vBits; // object mapping into AIG nodes
Vec_Int_t vLevels; // object levels
Vec_Int_t vRefs; // object reference counters
};
typedef struct Wlc_Par_t_ Wlc_Par_t;
struct Wlc_Par_t_
{
int nBitsAdd; // adder bit-width
int nBitsMul; // multiplier bit-widht
int nBitsMux; // MUX bit-width
int nBitsFlop; // flop bit-width
int nIterMax; // the max number of iterations
int fXorOutput; // XOR outputs of word-level miter
int fCheckClauses; // Check clauses in the reloaded trace
int fPushClauses; // Push clauses in the reloaded trace
int fVerbose; // verbose output
int fPdrVerbose; // verbose output
};
static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; }
@ -205,6 +223,8 @@ static inline int Wlc_ObjSign( Wlc_Obj_t * p )
static inline int * Wlc_ObjConstValue( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_CONST); return Wlc_ObjFanins(p); }
static inline int Wlc_ObjTableId( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_TABLE); return p->Fanins[1]; }
static inline word * Wlc_ObjTable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return (word *)Vec_PtrEntry( p->vTables, Wlc_ObjTableId(pObj) ); }
static inline int Wlc_ObjLevelId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vLevels, iObj ); }
static inline int Wlc_ObjLevel( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_ObjLevelId( p, Wlc_ObjId(p, pObj) ); }
static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vCopies, p->nObjsAlloc, 0 ); }
static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; }
@ -217,7 +237,8 @@ static inline int Wlc_NtkHasNameId( Wlc_Ntk_t * p )
static inline void Wlc_ObjSetNameId( Wlc_Ntk_t * p, int iObj, int i ) { Vec_IntWriteEntry( &p->vNameIds, iObj, i ); }
static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vNameIds, iObj ); }
static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkCoNum(p) - Wlc_NtkCiNum(p) + Wlc_ObjCiId(pObj)); }
static inline Wlc_Obj_t * Wlc_ObjFo2Fi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkPoNum(p) + Wlc_ObjCiId(pObj) - Wlc_NtkPiNum(p)); }
static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) { return iCoId < Wlc_NtkPoNum(p) ? Wlc_NtkPo(p, iCoId) : Wlc_NtkCi(p, Wlc_NtkPiNum(p) + iCoId - Wlc_NtkPoNum(p)); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
@ -229,6 +250,8 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
#define Wlc_NtkForEachObj( p, pObj, i ) \
for ( i = 1; (i < Wlc_NtkObjNumMax(p)) && (((pObj) = Wlc_NtkObj(p, i)), 1); i++ )
#define Wlc_NtkForEachObjReverse( p, pObj, i ) \
for ( i = Wlc_NtkObjNumMax(p) - 1; (i > 0) && (((pObj) = Wlc_NtkObj(p, i)), 1); i-- )
#define Wlc_NtkForEachObjVec( vVec, p, pObj, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && (((pObj) = Wlc_NtkObj(p, Vec_IntEntry(vVec, i))), 1); i++ )
#define Wlc_NtkForEachPi( p, pPi, i ) \
@ -255,16 +278,17 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
////////////////////////////////////////////////////////////////////////
/*=== wlcAbs.c ========================================================*/
extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 );
extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p );
extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p );
extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes );
extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs );
extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
/*=== wlcAbs2.c ========================================================*/
extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars );
/*=== wlcBlast.c ========================================================*/
extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth );
/*=== wlcCom.c ========================================================*/
extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk );
/*=== wlcNtk.c ========================================================*/
extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars );
extern char * Wlc_ObjTypeName( Wlc_Obj_t * p );
extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc );
extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg );
extern int Wlc_ObjCreate( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg, Vec_Int_t * vFanins );
@ -274,13 +298,25 @@ extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj );
extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type );
extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins );
extern void Wlc_NtkFree( Wlc_Ntk_t * p );
extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p );
extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p );
extern int Wlc_NtkCountRealPis( Wlc_Ntk_t * p );
extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj );
extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray );
extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type );
extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose );
extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p );
extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose );
extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p );
extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq );
extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq );
extern Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops );
extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p );
extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis );
extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p );
extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p );
extern void Wlc_NtkShortNames( Wlc_Ntk_t * p );
extern int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p );
extern void Wlc_NtkSetRefs( Wlc_Ntk_t * p );
extern int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew );
/*=== wlcReadSmt.c ========================================================*/
extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree );
extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree );
@ -291,6 +327,12 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p );
extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd );
/*=== wlcReadVer.c ========================================================*/
extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr );
/*=== wlcUif.c ========================================================*/
extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 );
extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p );
extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p );
extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes );
extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs );
/*=== wlcWin.c =============================================================*/
extern void Wlc_WinProfileArith( Wlc_Ntk_t * p );
/*=== wlcWriteVer.c ========================================================*/

View File

@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose )
{
Wlc_Obj_t * pObj;
int i, k, nNum, nRange, nBits = 0;
@ -53,7 +53,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
nRange = Wlc_ObjRange(pObj);
for ( k = 0; k < nRange; k++ )
{
nNum = Vec_IntEntry(vInv, nBits + k);
nNum = Vec_IntEntry(vCounts, nBits + k);
if ( nNum )
break;
}
@ -65,7 +65,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
for ( k = 0; k < nRange; k++ )
{
nNum = Vec_IntEntry( vInv, nBits + k );
nNum = Vec_IntEntry( vCounts, nBits + k );
if ( nNum == 0 )
continue;
printf( " [%d] -> %d", k, nNum );
@ -73,8 +73,8 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
printf( "\n");
nBits += nRange;
}
//printf( "%d %d\n", Vec_IntSize(vInv), nBits );
assert( Vec_IntSize(vInv) == nBits );
//printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
assert( Vec_IntSize(vCounts) == nBits );
}
/**Function*************************************************************
@ -88,8 +88,14 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose )
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose )
Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv )
{
extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts );
Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts );
Wlc_Obj_t * pObj;
int i, k, nNum, nRange, nBits = 0;
Abc_Ntk_t * pMainNtk = NULL;
@ -98,46 +104,69 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop,
// start the network
pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
// duplicate the name and the spec
pMainNtk->pName = Extra_UtilStrsav(pNtk->pName);
pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv");
// create primary inputs
Wlc_NtkForEachCi( pNtk, pObj, i )
if ( pNtk == NULL )
{
if ( pObj->Type != WLC_OBJ_FO )
continue;
nRange = Wlc_ObjRange(pObj);
for ( k = 0; k < nRange; k++ )
int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) );
Vec_IntForEachEntry( vCounts, Entry, i )
{
nNum = Vec_IntEntry(vInv, nBits + k);
if ( nNum )
break;
}
if ( k == nRange )
{
nBits += nRange;
continue;
}
//printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
for ( k = 0; k < nRange; k++ )
{
nNum = Vec_IntEntry( vInv, nBits + k );
if ( nNum == 0 )
if ( Entry == 0 )
continue;
//printf( " [%d] -> %d", k, nNum );
pMainObj = Abc_NtkCreatePi( pMainNtk );
sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
sprintf( Buffer, "pi%d", i );
Abc_ObjAssignName( pMainObj, Buffer, NULL );
}
//printf( "\n");
nBits += nRange;
if ( Abc_NtkPiNum(pMainNtk) != nInputs )
{
printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" );
Abc_NtkDelete( pMainNtk );
return NULL;
}
}
//printf( "%d %d\n", Vec_IntSize(vInv), nBits );
assert( Vec_IntSize(vInv) == nBits );
else
{
Wlc_NtkForEachCi( pNtk, pObj, i )
{
if ( pObj->Type != WLC_OBJ_FO )
continue;
nRange = Wlc_ObjRange(pObj);
for ( k = 0; k < nRange; k++ )
{
nNum = Vec_IntEntry(vCounts, nBits + k);
if ( nNum )
break;
}
if ( k == nRange )
{
nBits += nRange;
continue;
}
//printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
for ( k = 0; k < nRange; k++ )
{
nNum = Vec_IntEntry( vCounts, nBits + k );
if ( nNum == 0 )
continue;
//printf( " [%d] -> %d", k, nNum );
pMainObj = Abc_NtkCreatePi( pMainNtk );
sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
Abc_ObjAssignName( pMainObj, Buffer, NULL );
}
//printf( "\n");
nBits += nRange;
}
}
//printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits );
// create node
pMainObj = Abc_NtkCreateNode( pMainNtk );
Abc_NtkForEachPi( pMainNtk, pMainTemp, i )
Abc_ObjAddFanin( pMainObj, pMainTemp );
pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) );
Vec_IntFree( vCounts );
Vec_StrFree( vSop );
// create PO
pMainTemp = Abc_NtkCreatePo( pMainNtk );
Abc_ObjAddFanin( pMainTemp, pMainObj );
@ -145,6 +174,98 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop,
return pMainNtk;
}
/**Function*************************************************************
Synopsis [Translate current network into an invariant.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia )
{
int nRegs = Gia_ManRegNum(pGia);
Vec_Int_t * vRes = NULL;
if ( Abc_NtkPoNum(pNtk) != 1 )
printf( "The number of outputs is other than 1.\n" );
else if ( Abc_NtkNodeNum(pNtk) != 1 )
printf( "The number of internal nodes is other than 1.\n" );
else
{
Abc_Nam_t * pNames = NULL;
Abc_Obj_t * pFanin, * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) );
char * pName, * pCube, * pSop = (char *)pNode->pData;
Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) );
int i, k, Value, nLits, Counter = 0;
if ( pGia->vNamesIn )
{
// hash the names
pNames = Abc_NamStart( 100, 16 );
Vec_PtrForEachEntry( char *, pGia->vNamesIn, pName, i )
{
Value = Abc_NamStrFindOrAdd( pNames, pName, NULL );
assert( Value == i+1 );
//printf( "%s(%d) ", pName, i );
}
//printf( "\n" );
}
Abc_ObjForEachFanin( pNode, pFanin, i )
{
assert( Abc_ObjIsCi(pFanin) );
pName = Abc_ObjName(pFanin);
if ( pNames )
{
Value = Abc_NamStrFind(pNames, pName) - 1 - Gia_ManPiNum(pGia);
if ( Value < 0 )
{
if ( Counter++ == 0 )
printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
Value = i;
}
}
else
{
for ( k = (int)strlen(pName)-1; k >= 0; k-- )
if ( pName[k] < '0' || pName[k] > '9' )
break;
if ( k == (int)strlen(pName)-1 )
{
if ( Counter++ == 0 )
printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
Value = i;
}
else
Value = atoi(pName + k + 1);
}
Vec_IntPush( vFanins, Value );
}
if ( Counter )
printf( "Cannot read names for %d inputs of the invariant.\n", Counter );
if ( pNames )
Abc_NamStop( pNames );
assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) );
vRes = Vec_IntAlloc( 1000 );
Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) );
Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube )
{
nLits = 0;
Abc_CubeForEachVar( pCube, Value, k )
if ( Value != '-' )
nLits++;
Vec_IntPush( vRes, nLits );
Abc_CubeForEachVar( pCube, Value, k )
if ( Value != '-' )
Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') );
}
Vec_IntPush( vRes, nRegs );
Vec_IntFree( vFanins );
}
return vRes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -8,7 +8,7 @@
Synopsis [Abstraction for word-level networks.]
Author [Alan Mishchenko]
Author [Yen-Sheng Ho, Alan Mishchenko]
Affiliation [UC Berkeley]
@ -19,6 +19,10 @@
***********************************************************************/
#include "wlc.h"
#include "proof/pdr/pdr.h"
#include "proof/pdr/pdrInt.h"
#include "aig/gia/giaAig.h"
#include "sat/bmc/bmc.h"
ABC_NAMESPACE_IMPL_START
@ -26,161 +30,330 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast );
extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap );
extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Check if two objects have the same input/output signatures.]
Synopsis [Mark operators that meet the abstraction criteria.]
Description []
Description [This procedure returns the array of objects (vLeaves) that
should be abstracted because of their high bit-width. It uses input array (vUnmark)
to not abstract those objects that have been refined in the previous rounds.]
SideEffects []
SeeAlso []
***********************************************************************/
int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 )
static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
{
Wlc_Obj_t * pFanin, * pFanin2; int k;
if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) )
return 0;
if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) )
return 0;
if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) )
return 0;
for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
{
pFanin = Wlc_ObjFanin(p, pObj, k);
pFanin2 = Wlc_ObjFanin(p, pObj2, k);
if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) )
return 0;
if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) )
return 0;
}
return 1;
}
/**Function*************************************************************
Synopsis [Collect IDs of the multipliers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj; int i;
Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 );
Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
Wlc_Obj_t * pObj; int i, Count[4] = {0};
Wlc_NtkForEachObj( p, pObj, i )
if ( pObj->Type == WLC_OBJ_ARI_MULTI )
Vec_IntPush( vBoxIds, i );
if ( Vec_IntSize( vBoxIds ) > 0 )
return vBoxIds;
Vec_IntFree( vBoxIds );
return NULL;
}
/**Function*************************************************************
Synopsis [Returns all pairs of uifable multipliers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p )
{
Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p );
Vec_Int_t * vPairs = Vec_IntAlloc( 2 );
Wlc_Obj_t * pObj, * pObj2; int i, k;
// iterate through unique pairs
Wlc_NtkForEachObjVec( vMultis, p, pObj, i )
Wlc_NtkForEachObjVec( vMultis, p, pObj2, k )
{
if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
continue;
if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
{
if ( k == i )
break;
if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) )
{
Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) );
Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) );
}
if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
continue;
}
Vec_IntFree( vMultis );
if ( Vec_IntSize( vPairs ) > 0 )
return vPairs;
Vec_IntFree( vPairs );
return NULL;
if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
{
if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
continue;
}
if ( pObj->Type == WLC_OBJ_MUX )
{
if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
continue;
}
if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
{
if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
continue;
}
}
if ( fVerbose )
printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] );
return vLeaves;
}
/**Function*************************************************************
Synopsis [Abstracts nodes by replacing their outputs with new PIs.]
Synopsis [Marks nodes to be included in the abstracted network.]
Description [If array is NULL, abstract all multipliers.]
Description [Marks all objects that will be included in the abstracted model.
Stops at the objects (vLeaves) that are abstracted away. Returns three arrays:
a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the
set of flops present as flops in the abstracted network.]
SideEffects []
SeeAlso []
***********************************************************************/
Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
int i, iFanin;
if ( pObj->Mark )
return;
pObj->Mark = 1;
if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
{
assert( !Wlc_ObjIsPi(pObj) );
Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
return;
}
if ( Wlc_ObjIsCi(pObj) )
{
if ( Wlc_ObjIsPi(pObj) )
Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
else
Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
return;
}
Wlc_ObjForEachFanin( pObj, iFanin, i )
Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
}
static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
Vec_Int_t * vNodes = vNodesInit;
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj;
int i, k, iObj, iFanin;
// get multipliers if not given
if ( vNodes == NULL )
vNodes = Wlc_NtkCollectMultipliers( p );
if ( vNodes == NULL )
return NULL;
// mark nodes
Wlc_NtkForEachObjVec( vNodes, p, pObj, i )
pObj->Mark = 1;
// iterate through the nodes in the DFS order
Wlc_NtkCleanCopy( p );
Wlc_NtkForEachObj( p, pObj, i )
{
if ( i == Vec_IntSize(&p->vCopies) )
break;
if ( pObj->Mark ) {
// clean
pObj->Mark = 0;
// add fresh PI with the same number of bits
iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 );
int i, Count = 0;
Wlc_NtkCleanMarks( p );
Wlc_NtkForEachCo( p, pObj, i )
Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
/*
Vec_IntClear(vFlops);
Wlc_NtkForEachCi( p, pObj, i ) {
if ( !Wlc_ObjIsPi(pObj) ) {
Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
pObj->Mark = 1;
}
else {
// update fanins
Wlc_ObjForEachFanin( pObj, iFanin, k )
Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin);
// node to remain
iObj = i;
}
Wlc_ObjSetCopy( p, i, iObj );
}
// POs do not change in this procedure
if ( vNodes != vNodesInit )
Vec_IntFree( vNodes );
// reconstruct topological order
pNew = Wlc_NtkDupDfs( p );
Wlc_NtkTransferNames( pNew, p );
return pNew;
*/
Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
Wlc_NtkForEachObj( p, pObj, i )
Count += pObj->Mark;
// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n",
// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops),
// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
Vec_IntSort( vPisOld, 0 );
Vec_IntSort( vPisNew, 0 );
Vec_IntSort( vFlops, 0 );
Wlc_NtkCleanMarks( p );
}
/**Function*************************************************************
Synopsis [Adds UIF constraints to node pairs and updates POs.]
Synopsis [Derive word-level abstracted model based on the parameter values.]
Description [Retuns the word-level abstracted network and the set of pseudo-PIs
(vPisNew), which were created during abstraction. If the abstraction is
satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs
and their MFFC cones will be listed in the array (vUnmark), which will
force the abstraction to not stop at these pseudo-PIs in the future.]
SideEffects []
SeeAlso []
***********************************************************************/
static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, Vec_Int_t ** pvFlops, int fVerbose )
{
Wlc_Ntk_t * pNtkNew = NULL;
Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
Vec_Int_t * vFlops = Vec_IntAlloc( 100 );
Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
Vec_BitFree( vLeaves );
pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
Vec_IntFree( vPisOld );
if ( pvFlops )
*pvFlops = vFlops;
else
Vec_IntFree( vFlops );
if ( pvPisNew )
*pvPisNew = vPisNew;
else
Vec_IntFree( vPisNew );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Find what objects need to be un-abstracted.]
Description [Returns a subset of pseudo-PIs (vPisNew), which will be
prevented from being abstracted in the future rounds of abstraction.
The AIG manager (pGia) is a bit-level view of the abstracted model.
The counter-example (pCex) is used to find waht PPIs to refine.]
SideEffects []
SeeAlso []
***********************************************************************/
static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
{
Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
Abc_Cex_t * pCexCare;
Wlc_Obj_t * pObj;
// count the number of bit-level PPIs and map them into word-level objects they were derived from
int f, i, b, nRealPis, nPpiBits = 0;
Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
// since PPIs are ordered last, the previous bits are real PIs
nRealPis = pCex->nPis - nPpiBits;
// find the care-set
pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
assert( pCexCare->nPis == pCex->nPis );
// detect care PPIs
for ( f = 0; f <= pCexCare->iFrame; f++ )
for ( i = nRealPis; i < pCexCare->nPis; i++ )
if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
Abc_CexFree( pCexCare );
Vec_IntFree( vMap );
if ( Vec_IntSize(vRefine) == 0 )// real CEX
Vec_IntFreeP( &vRefine );
return vRefine;
}
/**Function*************************************************************
Synopsis [Mark MFFC cones of the un-abstracted objects.]
Description [The MFFC cones of the objects in vRefine are traversed
and all their nodes are marked in vUnmark.]
SideEffects []
SeeAlso []
***********************************************************************/
static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
{
int i, Fanin, Counter = 1;
if ( Wlc_ObjIsCi(pNode) )
return 0;
Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
Wlc_ObjForEachFanin( pNode, Fanin, i )
{
Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
}
return Counter;
}
static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
{
int i, Fanin, Counter = 1;
if ( Wlc_ObjIsCi(pNode) )
return 0;
Wlc_ObjForEachFanin( pNode, Fanin, i )
{
if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
}
return Counter;
}
static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
{
int Count1, Count2;
// if this is a flop output, compute MFFC of the corresponding flop input
while ( Wlc_ObjIsCi(pNode) )
{
Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
pNode = Wlc_ObjFo2Fi(p, pNode);
}
assert( !Wlc_ObjIsCi(pNode) );
// dereference the node (and set the bits in vUnmark)
Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
// reference it back
Count2 = Wlc_NtkNodeRef_rec( p, pNode );
assert( Count1 == Count2 );
return Count1;
}
static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
{
Wlc_Obj_t * pObj; int i, nNodes = 0;
if ( Vec_IntSize(&p->vRefs) == 0 )
Wlc_NtkSetRefs( p );
Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
return nNodes;
}
/**Function*************************************************************
Synopsis [Computes the map for remapping flop IDs used in the clauses.]
Description [Takes the original network (Wlc_Ntk_t) and the array of word-level
flops used in the old abstraction (vFfOld) and those used in the new abstraction
(vFfNew). Returns the integer map, which remaps every binary flop found
in the old abstraction into a binary flop found in the new abstraction.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Wlc_NtkFlopsRemap( Wlc_Ntk_t * p, Vec_Int_t * vFfOld, Vec_Int_t * vFfNew )
{
Vec_Int_t * vMap = Vec_IntAlloc( 1000 ); // the resulting map
Vec_Int_t * vMapFfNew2Bit1 = Vec_IntAlloc( 1000 ); // first binary bit of each new word-level flop
int i, b, iFfOld, iFfNew, iBit1New, nBits = 0;
// map object IDs of old flops into their flop indexes
Vec_Int_t * vMapFfObj2FfId = Vec_IntStartFull( Wlc_NtkObjNumMax(p) );
Vec_IntForEachEntry( vFfNew, iFfNew, i )
Vec_IntWriteEntry( vMapFfObj2FfId, iFfNew, i );
// map each new flop index into its first bit
Vec_IntForEachEntry( vFfNew, iFfNew, i )
{
Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfNew );
int nRange = Wlc_ObjRange( pObj );
Vec_IntPush( vMapFfNew2Bit1, nBits );
nBits += nRange;
}
assert( Vec_IntSize(vMapFfNew2Bit1) == Vec_IntSize(vFfNew) );
// remap old binary flops into new binary flops
Vec_IntForEachEntry( vFfOld, iFfOld, i )
{
Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfOld );
int nRange = Wlc_ObjRange( pObj );
iFfNew = Vec_IntEntry( vMapFfObj2FfId, iFfOld );
assert( iFfNew >= 0 ); // every old flop should be present in the new abstraction
// find the first bit of this new flop
iBit1New = Vec_IntEntry( vMapFfNew2Bit1, iFfNew );
for ( b = 0; b < nRange; b++ )
Vec_IntPush( vMap, iBit1New + b );
}
Vec_IntFree( vMapFfNew2Bit1 );
Vec_IntFree( vMapFfObj2FfId );
return vMap;
}
/**Function*************************************************************
Synopsis [Performs PDR with word-level abstraction.]
Description []
@ -189,98 +362,266 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
SeeAlso []
***********************************************************************/
Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit )
int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
Vec_Int_t * vPairs = vPairsInit;
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj, * pObj2;
Vec_Int_t * vUifConstrs, * vCompares, * vFanins;
int i, k, iObj, iObj2, iObjNew, iObjNew2;
int iFanin, iFanin2, iFaninNew;
// get multiplier pairs if not given
if ( vPairs == NULL )
vPairs = Wlc_NtkFindUifableMultiplierPairs( p );
if ( vPairs == NULL )
return NULL;
// sanity checks
assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 );
// iterate through node pairs
vFanins = Vec_IntAlloc( 100 );
vCompares = Vec_IntAlloc( 100 );
vUifConstrs = Vec_IntAlloc( 100 );
Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i )
abctime clk = Abc_Clock();
abctime pdrClk;
Pdr_Man_t * pPdr;
Vec_Vec_t * vClauses = NULL;
Vec_Int_t * vFfOld = NULL, * vFfNew = NULL, * vMap = NULL;
int nIters, nNodes, nDcFlops, RetValue = -1, nGiaFfNumOld = -1;
// start the bitmap to mark objects that cannot be abstracted because of refinement
// currently, this bitmap is empty because abstraction begins without refinement
Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
// set up parameters to run PDR
Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
Pdr_ManSetDefaultParams( pPdrPars );
pPdrPars->fVerbose = pPars->fPdrVerbose;
pPdrPars->fVeryVerbose = 0;
// perform refinement iterations
for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
{
// get two nodes
pObj = Wlc_NtkObj( p, iObj );
pObj2 = Wlc_NtkObj( p, iObj2 );
assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) );
// create fanin comparator nodes
Vec_IntClear( vCompares );
Wlc_ObjForEachFanin( pObj, iFanin, k )
Aig_Man_t * pAig;
Abc_Cex_t * pCex;
Vec_Int_t * vPisNew, * vRefine;
Gia_Man_t * pGia, * pTemp;
Wlc_Ntk_t * pAbs;
if ( pPars->fVerbose )
printf( "\nIteration %d:\n", nIters );
// get abstracted GIA and the set of pseudo-PIs (vPisNew)
pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, &vFfNew, pPars->fVerbose );
pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
// map old flops into new flops
if ( vFfOld )
{
iFanin2 = Wlc_ObjFaninId( pObj2, k );
Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 );
iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins );
Vec_IntPush( vCompares, iFaninNew );
// note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
// Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
pObj = Wlc_NtkObj( p, iObj );
assert( nGiaFfNumOld >= 0 );
vMap = Wlc_NtkFlopsRemap( p, vFfOld, vFfNew );
//Vec_IntPrint( vMap );
// if reset flop was added in the previous iteration, it will be added again in this iteration
// remap the last flop (reset flop) into the last flop (reset flop) of the current AIG
if ( Vec_IntSize(vMap) + 1 == nGiaFfNumOld )
Vec_IntPush( vMap, Gia_ManRegNum(pGia)-1 );
assert( Vec_IntSize(vMap) == nGiaFfNumOld );
Vec_IntFreeP( &vFfOld );
}
// concatenate fanin comparators
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares );
// create reduction-OR node
Vec_IntFill( vFanins, 1, iObjNew );
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins );
// craete output comparator node
Vec_IntFillTwo( vFanins, 2, iObj, iObj2 );
iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins );
// create implication node (iObjNew is already complemented above)
Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 );
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins );
// save the constraint
Vec_IntPush( vUifConstrs, iObjNew );
ABC_SWAP( Vec_Int_t *, vFfOld, vFfNew );
nGiaFfNumOld = Gia_ManRegNum(pGia);
// if the abstraction has flops with DC-init state,
// new PIs were introduced by bit-blasting at the end of the PI list
// here we move these variables to be *before* PPIs, because
// PPIs are supposed to be at the end of the PI list for refinement
nDcFlops = Wlc_NtkDcFlopNum(pAbs);
if ( nDcFlops > 0 ) // DC-init flops are present
{
pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
Gia_ManStop( pTemp );
}
// if the word-level outputs have to be XORs, this is a place to do it
if ( pPars->fXorOutput )
{
pGia = Gia_ManTransformMiter2( pTemp = pGia );
Gia_ManStop( pTemp );
}
if ( pPars->fVerbose )
{
printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
Gia_ManPrintStats( pGia, NULL );
}
Wlc_NtkFree( pAbs );
// try to prove abstracted GIA by converting it to AIG and calling PDR
pAig = Gia_ManToAigSimple( pGia );
pPdr = Pdr_ManStart( pAig, pPdrPars, NULL );
pdrClk = Abc_Clock();
if ( vClauses ) {
assert( Vec_VecSize( vClauses) >= 2 );
IPdr_ManRestore( pPdr, vClauses, vMap );
}
Vec_IntFreeP( &vMap );
RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses );
pPdr->tTotal += Abc_Clock() - pdrClk;
pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
// consider outcomes
if ( pCex == NULL )
{
assert( RetValue ); // proved or undecided
Gia_ManStop( pGia );
Vec_IntFree( vPisNew );
Pdr_ManStop( pPdr );
Aig_ManStop( pAig );
break;
}
// perform refinement
vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
Gia_ManStop( pGia );
Vec_IntFree( vPisNew );
if ( vRefine == NULL ) // real CEX
{
Abc_CexFree( pCex ); // return CEX in the future
Pdr_ManStop( pPdr );
Aig_ManStop( pAig );
break;
}
// spurious CEX, continue solving
vClauses = IPdr_ManSaveClauses( pPdr, 0 );
Pdr_ManStop( pPdr );
// update the set of objects to be un-abstracted
nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
if ( pPars->fVerbose )
printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
Vec_IntFree( vRefine );
Abc_CexFree( pCex );
Aig_ManStop( pAig );
}
// derive the AND of the UIF contraints
assert( Vec_IntSize(vUifConstrs) > 0 );
if ( Vec_IntSize(vUifConstrs) == 1 )
iObjNew = Vec_IntEntry( vUifConstrs, 0 );
else
Vec_IntFreeP( &vFfOld );
Vec_BitFree( vUnmark );
// report the result
if ( pPars->fVerbose )
printf( "\n" );
printf( "Abstraction " );
if ( RetValue == 0 )
printf( "resulted in a real CEX" );
else if ( RetValue == 1 )
printf( "is successfully proved" );
else
printf( "timed out" );
printf( " after %d iterations. ", nIters );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return RetValue;
}
/**Function*************************************************************
Synopsis [Performs abstraction.]
Description [Derives initial abstraction based on user-specified
parameter values, which tell what is the smallest bit-width of a
primitive that is being abstracted away. Currently only add/sub,
mul/div, mux, and flop are supported with individual parameters.
The second step is to refine the initial abstraction until the
point when the property is proved.]
SideEffects []
SeeAlso []
***********************************************************************/
int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
abctime clk = Abc_Clock();
int nIters, nNodes, nDcFlops, RetValue = -1;
// start the bitmap to mark objects that cannot be abstracted because of refinement
// currently, this bitmap is empty because abstraction begins without refinement
Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
// set up parameters to run PDR
Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
Pdr_ManSetDefaultParams( pPdrPars );
//pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction)
//pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization)
//pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization)
//pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
pPdrPars->fVerbose = pPars->fPdrVerbose;
pPdrPars->fVeryVerbose = 0;
// perform refinement iterations
for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
{
// concatenate
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs );
// create reduction-AND node
Vec_IntFill( vFanins, 1, iObjNew );
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins );
Aig_Man_t * pAig;
Abc_Cex_t * pCex;
Vec_Int_t * vPisNew, * vRefine;
Gia_Man_t * pGia, * pTemp;
Wlc_Ntk_t * pAbs;
if ( pPars->fVerbose )
printf( "\nIteration %d:\n", nIters );
// get abstracted GIA and the set of pseudo-PIs (vPisNew)
pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, NULL, pPars->fVerbose );
pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
// if the abstraction has flops with DC-init state,
// new PIs were introduced by bit-blasting at the end of the PI list
// here we move these variables to be *before* PPIs, because
// PPIs are supposed to be at the end of the PI list for refinement
nDcFlops = Wlc_NtkDcFlopNum(pAbs);
if ( nDcFlops > 0 ) // DC-init flops are present
{
pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
Gia_ManStop( pTemp );
}
// if the word-level outputs have to be XORs, this is a place to do it
if ( pPars->fXorOutput )
{
pGia = Gia_ManTransformMiter2( pTemp = pGia );
Gia_ManStop( pTemp );
}
if ( pPars->fVerbose )
{
printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
Gia_ManPrintStats( pGia, NULL );
}
Wlc_NtkFree( pAbs );
// try to prove abstracted GIA by converting it to AIG and calling PDR
pAig = Gia_ManToAigSimple( pGia );
RetValue = Pdr_ManSolve( pAig, pPdrPars );
pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
Aig_ManStop( pAig );
// consider outcomes
if ( pCex == NULL )
{
assert( RetValue ); // proved or undecided
Gia_ManStop( pGia );
Vec_IntFree( vPisNew );
break;
}
// perform refinement
vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
Gia_ManStop( pGia );
Vec_IntFree( vPisNew );
if ( vRefine == NULL ) // real CEX
{
Abc_CexFree( pCex ); // return CEX in the future
break;
}
// update the set of objects to be un-abstracted
nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
if ( pPars->fVerbose )
printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
Vec_IntFree( vRefine );
Abc_CexFree( pCex );
}
// update each PO to point to the new node
Wlc_NtkForEachPo( p, pObj, i )
{
iObj = Wlc_ObjId(p, pObj);
Vec_IntFillTwo( vFanins, 2, iObj, iObjNew );
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins );
// note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
// Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
pObj = Wlc_NtkObj( p, iObj );
// update PO/CO arrays
assert( Vec_IntEntry(&p->vPos, i) == iObj );
assert( Vec_IntEntry(&p->vCos, i) == iObj );
Vec_IntWriteEntry( &p->vPos, i, iObjNew );
Vec_IntWriteEntry( &p->vCos, i, iObjNew );
// transfer the PO attribute
Wlc_NtkObj(p, iObjNew)->fIsPo = 1;
assert( pObj->fIsPo );
pObj->fIsPo = 0;
}
// cleanup
Vec_IntFree( vUifConstrs );
Vec_IntFree( vCompares );
Vec_IntFree( vFanins );
if ( vPairs != vPairsInit )
Vec_IntFree( vPairs );
// reconstruct topological order
pNew = Wlc_NtkDupDfs( p );
Wlc_NtkTransferNames( pNew, p );
return pNew;
Vec_BitFree( vUnmark );
// report the result
if ( pPars->fVerbose )
printf( "\n" );
printf( "Abstraction " );
if ( RetValue == 0 )
printf( "resulted in a real CEX" );
else if ( RetValue == 1 )
printf( "is successfully proved" );
else
printf( "timed out" );
printf( " after %d iterations. ", nIters );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return RetValue;
}
////////////////////////////////////////////////////////////////////////

410
src/base/wlc/wlcAbs2.c Normal file
View File

@ -0,0 +1,410 @@
/**CFile****************************************************************
FileName [wlcAbs2.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Verilog parser.]
Synopsis [Abstraction for word-level networks.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - August 22, 2014.]
Revision [$Id: wlcAbs2.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
***********************************************************************/
#include "wlc.h"
#include "proof/pdr/pdr.h"
#include "aig/gia/giaAig.h"
#include "sat/bmc/bmc.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Mark operators that meet the abstraction criteria.]
Description [This procedure returns the array of objects (vLeaves) that
should be abstracted because of their high bit-width. It uses input array (vUnmark)
to not abstract those objects that have been refined in the previous rounds.]
SideEffects []
SeeAlso []
***********************************************************************/
static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
{
Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
Wlc_Obj_t * pObj; int i, Count[4] = {0};
Wlc_NtkForEachObj( p, pObj, i )
{
if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
continue;
if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
{
if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
continue;
}
if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
{
if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
continue;
}
if ( pObj->Type == WLC_OBJ_MUX )
{
if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
continue;
}
if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
{
if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
continue;
}
}
if ( fVerbose )
printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] );
return vLeaves;
}
/**Function*************************************************************
Synopsis [Marks nodes to be included in the abstracted network.]
Description [Marks all objects that will be included in the abstracted model.
Stops at the objects (vLeaves) that are abstracted away. Returns three arrays:
a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the
set of flops present as flops in the abstracted network.]
SideEffects []
SeeAlso []
***********************************************************************/
static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
int i, iFanin;
if ( pObj->Mark )
return;
pObj->Mark = 1;
if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
{
assert( !Wlc_ObjIsPi(pObj) );
Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
return;
}
if ( Wlc_ObjIsCi(pObj) )
{
if ( Wlc_ObjIsPi(pObj) )
Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
else
Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
return;
}
Wlc_ObjForEachFanin( pObj, iFanin, i )
Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
}
static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
Wlc_Obj_t * pObj;
int i, Count = 0;
Wlc_NtkCleanMarks( p );
Wlc_NtkForEachCo( p, pObj, i )
Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
Wlc_NtkForEachObj( p, pObj, i )
Count += pObj->Mark;
// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n",
// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops),
// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
Vec_IntSort( vPisOld, 0 );
Vec_IntSort( vPisNew, 0 );
Vec_IntSort( vFlops, 0 );
Wlc_NtkCleanMarks( p );
}
/**Function*************************************************************
Synopsis [Derive word-level abstracted model based on the parameter values.]
Description [Retuns the word-level abstracted network and the set of pseudo-PIs
(vPisNew), which were created during abstraction. If the abstraction is
satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs
and their MFFC cones will be listed in the array (vUnmark), which will
force the abstraction to not stop at these pseudo-PIs in the future.]
SideEffects []
SeeAlso []
***********************************************************************/
static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose )
{
Wlc_Ntk_t * pNtkNew = NULL;
Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
Vec_Int_t * vFlops = Vec_IntAlloc( 100 );
Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
Vec_BitFree( vLeaves );
pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
Vec_IntFree( vPisOld );
Vec_IntFree( vFlops );
if ( pvPisNew )
*pvPisNew = vPisNew;
else
Vec_IntFree( vPisNew );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Find what objects need to be un-abstracted.]
Description [Returns a subset of pseudo-PIs (vPisNew), which will be
prevented from being abstracted in the future rounds of abstraction.
The AIG manager (pGia) is a bit-level view of the abstracted model.
The counter-example (pCex) is used to find waht PPIs to refine.]
SideEffects []
SeeAlso []
***********************************************************************/
static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
{
Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
Abc_Cex_t * pCexCare;
Wlc_Obj_t * pObj;
// count the number of bit-level PPIs and map them into word-level objects they were derived from
int f, i, b, nRealPis, nPpiBits = 0;
Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
// since PPIs are ordered last, the previous bits are real PIs
nRealPis = pCex->nPis - nPpiBits;
// find the care-set
pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
assert( pCexCare->nPis == pCex->nPis );
// detect care PPIs
for ( f = 0; f <= pCexCare->iFrame; f++ )
for ( i = nRealPis; i < pCexCare->nPis; i++ )
if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
Abc_CexFree( pCexCare );
Vec_IntFree( vMap );
if ( Vec_IntSize(vRefine) == 0 )// real CEX
Vec_IntFreeP( &vRefine );
return vRefine;
}
/**Function*************************************************************
Synopsis [Mark MFFC cones of the un-abstracted objects.]
Description [The MFFC cones of the objects in vRefine are traversed
and all their nodes are marked in vUnmark.]
SideEffects []
SeeAlso []
***********************************************************************/
static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
{
int i, Fanin, Counter = 1;
if ( Wlc_ObjIsCi(pNode) )
return 0;
Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
Wlc_ObjForEachFanin( pNode, Fanin, i )
{
Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
}
return Counter;
}
static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
{
int i, Fanin, Counter = 1;
if ( Wlc_ObjIsCi(pNode) )
return 0;
Wlc_ObjForEachFanin( pNode, Fanin, i )
{
if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
}
return Counter;
}
static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
{
int Count1, Count2;
// if this is a flop output, compute MFFC of the corresponding flop input
while ( Wlc_ObjIsCi(pNode) )
{
Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
pNode = Wlc_ObjFo2Fi(p, pNode);
}
assert( !Wlc_ObjIsCi(pNode) );
// dereference the node (and set the bits in vUnmark)
Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
// reference it back
Count2 = Wlc_NtkNodeRef_rec( p, pNode );
assert( Count1 == Count2 );
return Count1;
}
static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
{
Wlc_Obj_t * pObj; int i, nNodes = 0;
if ( Vec_IntSize(&p->vRefs) == 0 )
Wlc_NtkSetRefs( p );
Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
return nNodes;
}
/**Function*************************************************************
Synopsis [Performs abstraction.]
Description [Derives initial abstraction based on user-specified
parameter values, which tell what is the smallest bit-width of a
primitive that is being abstracted away. Currently only add/sub,
mul/div, mux, and flop are supported with individual parameters.
The second step is to refine the initial abstraction until the
point when the property is proved.]
SideEffects []
SeeAlso []
***********************************************************************/
int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
{
abctime clk = Abc_Clock();
int nIters, nNodes, nDcFlops, RetValue = -1;
// start the bitmap to mark objects that cannot be abstracted because of refinement
// currently, this bitmap is empty because abstraction begins without refinement
Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
// set up parameters to run PDR
Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
Pdr_ManSetDefaultParams( pPdrPars );
pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction)
pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization)
pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization)
//pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
pPdrPars->fVerbose = pPars->fPdrVerbose;
// perform refinement iterations
for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
{
Aig_Man_t * pAig;
Abc_Cex_t * pCex;
Vec_Int_t * vPisNew, * vRefine;
Gia_Man_t * pGia, * pTemp;
Wlc_Ntk_t * pAbs;
if ( pPars->fVerbose )
printf( "\nIteration %d:\n", nIters );
// get abstracted GIA and the set of pseudo-PIs (vPisNew)
pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose );
pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
// if the abstraction has flops with DC-init state,
// new PIs were introduced by bit-blasting at the end of the PI list
// here we move these variables to be *before* PPIs, because
// PPIs are supposed to be at the end of the PI list for refinement
nDcFlops = Wlc_NtkDcFlopNum(pAbs);
if ( nDcFlops > 0 ) // DC-init flops are present
{
pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
Gia_ManStop( pTemp );
}
// if the word-level outputs have to be XORs, this is a place to do it
if ( pPars->fXorOutput )
{
pGia = Gia_ManTransformMiter2( pTemp = pGia );
Gia_ManStop( pTemp );
}
if ( pPars->fVerbose )
{
printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
Gia_ManPrintStats( pGia, NULL );
}
Wlc_NtkFree( pAbs );
// try to prove abstracted GIA by converting it to AIG and calling PDR
pAig = Gia_ManToAigSimple( pGia );
RetValue = Pdr_ManSolve( pAig, pPdrPars );
pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
Aig_ManStop( pAig );
// consider outcomes
if ( pCex == NULL )
{
assert( RetValue ); // proved or undecided
Gia_ManStop( pGia );
Vec_IntFree( vPisNew );
break;
}
// perform refinement
vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
Gia_ManStop( pGia );
Vec_IntFree( vPisNew );
if ( vRefine == NULL ) // real CEX
{
Abc_CexFree( pCex ); // return CEX in the future
break;
}
// update the set of objects to be un-abstracted
nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
if ( pPars->fVerbose )
printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
Vec_IntFree( vRefine );
Abc_CexFree( pCex );
}
Vec_BitFree( vUnmark );
// report the result
if ( pPars->fVerbose )
printf( "\n" );
printf( "Abstraction " );
if ( RetValue == 0 )
printf( "resulted in a real CEX" );
else if ( RetValue == 1 )
printf( "is successfully proved" );
else
printf( "timed out" );
printf( " after %d iterations. ", nIters );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -643,6 +643,41 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level )
Vec_IntInsert( vProd, i + 1, Node );
Vec_IntInsert( vLevel, i + 1, Level );
}
void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds )
{
int fVerbose = 0;
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
Vec_Int_t * vLevel; word Truth;
int i, k, iLit;
Vec_WecForEachLevel( vProds, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) );
printf( "Booth partial products: %d pps, %d unique, %d nodes.\n",
Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) );
Vec_IntPrint( vSupp );
if ( fVerbose )
Vec_WecForEachLevel( vProds, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
printf( "Obj = %4d : ", Abc_Lit2Var(iLit) );
printf( "Compl = %d ", Abc_LitIsCompl(iLit) );
printf( "Rank = %2d ", i );
Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp );
Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
printf( " " );
Vec_IntPrint( vSupp );
if ( k == Vec_IntSize(vLevel)-1 )
printf( "\n" );
}
Vec_IntFree( vSupp );
Vec_WrdFree( vTemp );
}
void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes )
{
Vec_Int_t * vLevel, * vProd;
@ -812,6 +847,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
Vec_WecPush( vLevels, k, 0 );
}
//Vec_WecPrint( vProds, 0 );
//Wlc_BlastPrintMatrix( pNew, vProds );
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes );
@ -836,6 +872,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
int fVerbose = 0;
int fUseOldMultiplierBlasting = 0;
int fSkipBitRange = 0;
Tim_Man_t * pManTime = NULL;
Gia_Man_t * pTemp, * pNew, * pExtra = NULL;
Wlc_Obj_t * pObj;
@ -1381,7 +1418,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
}
else
{
pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 1 );
pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 0 );
Gia_ManDupRemapLiterals( vBits, pTemp );
Gia_ManStop( pTemp );
}
@ -1412,7 +1449,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
if ( nRange == 1 )
if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@ -1439,7 +1476,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
if ( nRange == 1 )
if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@ -1462,7 +1499,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
if ( nRange == 1 )
if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@ -1477,7 +1514,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
if ( nRange == 1 )
if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@ -1496,7 +1533,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
nRange = Wlc_ObjRange( pObj );
if ( nRange == 1 )
if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
@ -1509,7 +1546,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) );
}
pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName );
//pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName );
// dump the miter parts
if ( 0 )
{

File diff suppressed because it is too large Load Diff

View File

@ -88,10 +88,38 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
NULL // 54: unused
};
char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars )
{
memset( pPars, 0, sizeof(Wlc_Par_t) );
pPars->nBitsAdd = ABC_INFINITY; // adder bit-width
pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht
pPars->nBitsMux = ABC_INFINITY; // MUX bit-width
pPars->nBitsFlop = ABC_INFINITY; // flop bit-width
pPars->nIterMax = 1000; // the max number of iterations
pPars->fXorOutput = 1; // XOR outputs of word-level miter
pPars->fCheckClauses = 1; // Check clauses in the reloaded trace
pPars->fPushClauses = 0; // Push clauses in the reloaded trace
pPars->fVerbose = 0; // verbose output`
pPars->fPdrVerbose = 0; // show verbose PDR output
}
/**Function*************************************************************
Synopsis [Working with models.]
@ -195,14 +223,14 @@ void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins )
{
assert( pObj->nFanins == 0 );
pObj->nFanins = Vec_IntSize(vFanins);
if ( Wlc_ObjHasArray(pObj) )
pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) );
memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) );
// special treatment of CONST, SELECT and TABLE
if ( pObj->Type == WLC_OBJ_CONST )
pObj->nFanins = 0;
else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE )
pObj->nFanins = 1;
if ( Wlc_ObjHasArray(pObj) )
pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) );
memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) );
}
void Wlc_NtkFree( Wlc_Ntk_t * p )
{
@ -224,6 +252,8 @@ void Wlc_NtkFree( Wlc_Ntk_t * p )
ABC_FREE( p->vValues.pArray );
ABC_FREE( p->vCopies.pArray );
ABC_FREE( p->vBits.pArray );
ABC_FREE( p->vLevels.pArray );
ABC_FREE( p->vRefs.pArray );
ABC_FREE( p->pInits );
ABC_FREE( p->pObjs );
ABC_FREE( p->pName );
@ -244,6 +274,91 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p )
return Mem;
}
/**Function*************************************************************
Synopsis [Assigns object levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Wlc_NtkCreateLevels( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj;
int i, k, iFanin, Level, LevelMax = 0;
Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
Wlc_NtkForEachObj( p, pObj, i )
{
Level = 0;
Wlc_ObjForEachFanin( pObj, iFanin, k )
Level = Abc_MaxInt( Level, Wlc_ObjLevelId(p, iFanin) + 1 );
Vec_IntWriteEntry( &p->vLevels, i, Level );
LevelMax = Abc_MaxInt( LevelMax, Level );
}
return LevelMax;
}
int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj;
int i, k, iFanin, Level, LevelMax = 0;
Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
Wlc_NtkForEachObjReverse( p, pObj, i )
{
if ( Wlc_ObjIsCi(pObj) )
continue;
Level = Wlc_ObjLevel(p, pObj) + 1;
Wlc_ObjForEachFanin( pObj, iFanin, k )
Vec_IntUpdateEntry( &p->vLevels, iFanin, Level );
LevelMax = Abc_MaxInt( LevelMax, Level );
}
// reverse the values
Wlc_NtkForEachObj( p, pObj, i )
Vec_IntWriteEntry( &p->vLevels, i, LevelMax - Wlc_ObjLevelId(p, i) );
Wlc_NtkForEachCi( p, pObj, i )
Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), 0 );
return LevelMax;
}
/**Function*************************************************************
Synopsis [Collects statistics for each side of the miter.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] )
{
Wlc_Obj_t * pObj;
int n, i;
if ( Wlc_NtkPoNum(p) != 2 )
return;
for ( n = 0; n < 2; n++ )
{
Wlc_NtkMarkCone( p, n, 1, 1, 0 );
Wlc_NtkForEachObj( p, pObj, i )
if ( pObj->Mark )
nObjs[n][pObj->Type]++;
}
Wlc_NtkCleanMarks( p );
}
int Wlc_NtkCountRealPis( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj;
int i, Count = 0;
Wlc_NtkMarkCone( p, -1, -1, 1, 0 );
Wlc_NtkForEachPi( p, pObj, i )
Count += pObj->Mark;
Wlc_NtkCleanMarks( p );
return Count;
}
/**Function*************************************************************
Synopsis [Prints distribution of operator types.]
@ -298,13 +413,18 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty
Vec_WrdReverseOrder( vType );
Vec_WrdReverseOrder( vOccur );
}
void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fTwoSides, int fVerbose )
{
int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type
Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0;
Vec_Ptr_t * vTypes, * vOccurs;
Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER );
word Sign;
int i, k, s, s0, s1;
if ( Wlc_NtkPoNum(p) != 2 )
fTwoSides = 0;
if ( fTwoSides )
Wlc_NtkCollectStats( p, nObjs );
// allocate statistics arrays
vTypes = Vec_PtrStart( WLC_OBJ_NUMBER );
vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER );
@ -409,11 +529,11 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
else if ( pObj->Type == WLC_OBJ_REDUCT_XOR )
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_XOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NAND )
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NOR )
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
else if ( pObj->Type == WLC_OBJ_REDUCT_NXOR )
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
else if ( pObj->Type == WLC_OBJ_ARI_ADD )
Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_ADD, 9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
else if ( pObj->Type == WLC_OBJ_ARI_SUB )
@ -435,28 +555,41 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
else if ( pObj->Type == WLC_OBJ_ARI_SQUARE )
Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQUARE, 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) );
}
if ( nCountRange )
if ( nCountRange && Vec_IntSize(&p->vNameIds) > 0 )
{
printf( "Warning: %d objects of the design have non-zero-based ranges.\n", nCountRange );
printf( "In particular, object %6d with name \"%s\" has range %d=[%d:%d]\n", Wlc_ObjId(p, pObjRange),
Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg );
}
// print by occurrence
printf( "ID : name occurrence and2 (occurrence)<output_range>=<input_range>.<input_range> ...\n" );
printf( "ID : name occurrence%s and2 (occurrence)<output_range>=<input_range>.<input_range> ...\n", fTwoSides ? " Left Share Right":"" );
for ( i = 0; i < WLC_OBJ_NUMBER; i++ )
{
Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i );
Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, i );
if ( p->nObjs[i] == 0 )
continue;
printf( "%2d : %-8s %6d%8d ", i, Wlc_Names[i], p->nObjs[i], Vec_IntEntry(vAnds, i) );
printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] );
if ( fTwoSides )
{
int nTotal = i == WLC_OBJ_PI ? Wlc_NtkCountRealPis(p) : p->nObjs[i];
printf( " " );
printf( "%6d", nObjs[0][i] );
printf( "%6d", nObjs[0][i]+nObjs[1][i]-nTotal );
printf( "%6d", nObjs[1][i] );
}
printf( "%8d ", Vec_IntEntry(vAnds, i) );
// sort by occurence
Wlc_NtkPrintDistribSortOne( vTypes, vOccurs, i );
Vec_WrdForEachEntry( vType, Sign, k )
{
Wlc_NtkPrintDistribFromSign( Sign, &s, &s0, &s1 );
if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) )
{
printf( "\n " );
if ( fTwoSides )
printf( " " );
}
printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) );
printf( "%s%d", Abc_LitIsCompl(s)?"-":"", Abc_Lit2Var(s) );
if ( s0 )
@ -535,19 +668,19 @@ void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type )
Wlc_NtkPrintNode( p, pObj );
}
}
void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose )
void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose )
{
int i;
printf( "%-20s : ", p->pName );
printf( "PI = %4d ", Wlc_NtkPiNum(p) );
printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) );
printf( "PO = %4d ", Wlc_NtkPoNum(p) );
printf( "FF = %4d ", Wlc_NtkFfNum(p) );
printf( "Obj = %6d ", Wlc_NtkObjNum(p) );
printf( "Obj = %6d ", Wlc_NtkObjNum(p) - Wlc_NtkPiNum(p) - Wlc_NtkPoNum(p) - Wlc_NtkFfNum(p) );
printf( "Mem = %.3f MB", 1.0*Wlc_NtkMemUsage(p)/(1<<20) );
printf( "\n" );
if ( fDistrib )
{
Wlc_NtkPrintDistrib( p, fVerbose );
Wlc_NtkPrintDistrib( p, fTwoSides, fVerbose );
return;
}
if ( !fVerbose )
@ -564,6 +697,80 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose )
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p )
{
int i;
assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) );
assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) );
assert( pNew->pManName == NULL && p->pManName != NULL );
Wlc_NtkCleanNameId( pNew );
for ( i = 0; i < p->nObjsAlloc; i++ )
if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) )
Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) );
pNew->pManName = p->pManName;
p->pManName = NULL;
Vec_IntErase( &p->vNameIds );
// transfer table
pNew->pMemTable = p->pMemTable; p->pMemTable = NULL;
pNew->vTables = p->vTables; p->vTables = NULL;
}
char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq )
{
static char pBuffer[1000];
sprintf( pBuffer, "%s_o%d_%s", p->pName, iCoId, fSeq ? "seq": "comb" );
return pBuffer;
}
/**Function*************************************************************
Synopsis [Reduce init vector.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit )
{
Vec_Int_t * vInitNew = Vec_IntDup( vInit );
Wlc_Obj_t * pObj; int i, k = 0;
assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) );
Wlc_NtkForEachCi( p, pObj, i )
if ( !Wlc_ObjIsPi(pObj) && pObj->Mark )
Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i - Wlc_NtkPiNum(p)) );
Vec_IntShrink( vInitNew, k );
return vInitNew;
}
char * Wlc_ReduceMarkedInitStr( Wlc_Ntk_t * p, char * pInit )
{
char * pInitNew = Abc_UtilStrsav( pInit );
Wlc_Obj_t * pObj; int i, b, nBits = 0, k = 0;
Wlc_NtkForEachCi( p, pObj, i )
{
if ( !Wlc_ObjIsPi(pObj) && pObj->Mark )
for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
pInitNew[k++] = pInitNew[nBits+b];
if ( !Wlc_ObjIsPi(pObj) )
nBits += Wlc_ObjRange(pObj);
}
pInitNew[k] = '\0';
assert( nBits == (int)strlen(pInit) );
return pInitNew;
}
/**Function*************************************************************
Synopsis [Duplicates the network in a topological order.]
@ -623,47 +830,214 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v
Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
Wlc_ObjDup( pNew, p, iObj, vFanins );
}
Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p )
Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq )
{
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj;
Vec_Int_t * vFanins;
int i;
vFanins = Vec_IntAlloc( 100 );
Wlc_NtkCleanCopy( p );
pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
pNew->fSmtLib = p->fSmtLib;
Wlc_NtkForEachCi( p, pObj, i )
if ( !fMarked || pObj->Mark )
{
unsigned Type = pObj->Type;
if ( !fSeq ) pObj->Type = WLC_OBJ_PI;
Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
pObj->Type = Type;
}
Wlc_NtkForEachCo( p, pObj, i )
if ( !fMarked || pObj->Mark )
Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
if ( !fMarked || pObj->Mark )
Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 );
Vec_IntFree( vFanins );
if ( fSeq )
{
if ( fMarked )
{
if ( p->vInits )
pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits );
if ( p->pInits )
pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits );
}
else
{
if ( p->vInits )
pNew->vInits = Vec_IntDup( p->vInits );
if ( p->pInits )
pNew->pInits = Abc_UtilStrsav( p->pInits );
}
}
if ( p->pSpec )
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Wlc_NtkTransferNames( pNew, p );
return pNew;
}
Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
{
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj;
Vec_Int_t * vFanins;
int i;
Wlc_NtkCleanCopy( p );
vFanins = Vec_IntAlloc( 100 );
pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
pNew->fSmtLib = p->fSmtLib;
Wlc_NtkForEachCi( p, pObj, i )
// duplicate marked PIs
vFanins = Vec_IntAlloc( 100 );
Wlc_NtkForEachObjVec( vPisOld, p, pObj, i )
{
assert( Wlc_ObjIsPi(pObj) );
Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
}
// duplicate additional PIs
Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
{
unsigned Type = pObj->Type;
int nFanins = Wlc_ObjFaninNum(pObj);
assert( !Wlc_ObjIsPi(pObj) );
pObj->Type = WLC_OBJ_PI;
pObj->nFanins = 0;
Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
pObj->Type = Type;
pObj->nFanins = (unsigned)nFanins;
}
// duplicate flop outputs
Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
{
assert( !Wlc_ObjIsPi(pObj) && Wlc_ObjIsCi(pObj) );
Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
}
// duplicate logic cones of primary outputs
Wlc_NtkForEachPo( p, pObj, i )
Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi );
if ( p->vInits )
pNew->vInits = Vec_IntDup( p->vInits );
if ( p->pInits )
pNew->pInits = Abc_UtilStrsav( p->pInits );
// duplidate logic cone of flop inputs
Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj)), vFanins );
// duplicate POs
Wlc_NtkForEachPo( p, pObj, i )
Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), 0 );
// duplicate flop inputs
Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, Wlc_ObjFo2Fi(p, pObj)), 1 );
Vec_IntFree( vFanins );
// mark flop outputs
Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
pObj->Mark = 1;
if ( p->vInits )
pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits );
if ( p->pInits )
pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits );
Wlc_NtkCleanMarks( p );
if ( p->pSpec )
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
//Wlc_NtkTransferNames( pNew, p );
return pNew;
}
void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p )
/**Function*************************************************************
Synopsis [Select the cone of the given output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_NtkCleanMarks( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj;
int i;
assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) );
assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) );
assert( pNew->pManName == NULL && p->pManName != NULL );
Wlc_NtkCleanNameId( pNew );
for ( i = 0; i < p->nObjsAlloc; i++ )
if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) )
Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) );
pNew->pManName = p->pManName;
p->pManName = NULL;
Vec_IntErase( &p->vNameIds );
// transfer table
pNew->pMemTable = p->pMemTable; p->pMemTable = NULL;
pNew->vTables = p->vTables; p->vTables = NULL;
Wlc_NtkForEachObj( p, pObj, i )
pObj->Mark = 0;
}
int Wlc_NtkCountMarked( Wlc_Ntk_t * p, int * pnPis, int * pnFos, int * pnAdders, int * pnMults )
{
Wlc_Obj_t * pObj;
int i, nNodes = 0;
*pnPis = *pnFos = *pnAdders = *pnMults = 0;
Wlc_NtkForEachObj( p, pObj, i )
{
if ( !pObj->Mark )
continue;
if ( Wlc_ObjIsPi(pObj) )
(*pnPis)++;
else if ( Wlc_ObjIsCi(pObj) )
(*pnFos)++;
else if ( pObj->Mark )
{
nNodes++;
if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB )
(*pnAdders)++;
else if ( pObj->Type == WLC_OBJ_ARI_MULTI )
(*pnMults)++;
}
}
return nNodes;
}
void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops )
{
int i, iFanin;
if ( pObj->Mark )
return;
pObj->Mark = 1;
if ( Wlc_ObjIsCi(pObj) )
{
if ( !Wlc_ObjIsPi(pObj) )
Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) );
return;
}
Wlc_ObjForEachFanin( pObj, iFanin, i )
Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops );
}
void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis )
{
Vec_Int_t * vFlops;
Wlc_Obj_t * pObj;
int i, CiId, CoId;
Wlc_NtkCleanMarks( p );
if ( fAllPis )
Wlc_NtkForEachPi( p, pObj, i )
pObj->Mark = 1;
vFlops = Vec_IntAlloc( 100 );
Wlc_NtkForEachCo( p, pObj, i )
if ( iCoId == -1 || (i >= iCoId && i < iCoId + Range) )
Wlc_NtkMarkCone_rec( p, pObj, vFlops );
if ( fSeq )
Vec_IntForEachEntry( vFlops, CiId, i )
{
CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p);
Wlc_NtkMarkCone_rec( p, Wlc_NtkCo(p, CoId), vFlops );
}
Vec_IntFree( vFlops );
}
void Wlc_NtkProfileCones( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj;
int i, nPis, nFos, nNodes, nAdders, nMults;
Wlc_NtkForEachCo( p, pObj, i )
{
Wlc_NtkMarkCone( p, i, 1, 0, 0 );
nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults );
printf( "Cone %5d : ", i );
printf( "PI = %4d ", nPis );
printf( "FO = %4d ", nFos );
printf( "Node = %6d ", nNodes );
printf( "Add/Sub = %4d ", nAdders );
printf( "Mult = %4d ", nMults );
printf( "\n" );
}
Wlc_NtkCleanMarks( p );
}
/**Function*************************************************************
@ -723,6 +1097,128 @@ Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p )
return pNew;
}
/**Function*************************************************************
Synopsis [Creates short names for all objects.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_NtkShortNames( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj;
char pBuffer[100];
int nDigits, NameId, fFound, i;
int nFlops = Wlc_NtkCoNum(p) - Wlc_NtkPoNum(p);
nDigits = Abc_Base10Log( nFlops );
Wlc_NtkForEachCo( p, pObj, i )
{
if ( Wlc_ObjIsPo(pObj) )
continue;
sprintf( pBuffer, "%s%0*d", "fi", nDigits, i - Wlc_NtkPoNum(p) );
NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
}
Wlc_NtkForEachCi( p, pObj, i )
{
if ( Wlc_ObjIsPi(pObj) )
continue;
sprintf( pBuffer, "%s%0*d", "fo", nDigits, i - Wlc_NtkPiNum(p) );
NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
}
nDigits = Abc_Base10Log( Wlc_NtkPoNum(p) );
Wlc_NtkForEachPo( p, pObj, i )
{
sprintf( pBuffer, "%s%0*d", "po", nDigits, i );
NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
}
nDigits = Abc_Base10Log( Wlc_NtkPiNum(p) );
Wlc_NtkForEachPi( p, pObj, i )
{
sprintf( pBuffer, "%s%0*d", "pi", nDigits, i );
NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
}
nDigits = Abc_Base10Log( Wlc_NtkObjNum(p) );
Wlc_NtkForEachObj( p, pObj, i )
{
if ( Wlc_ObjIsCi(pObj) || Wlc_ObjIsCo(pObj) )
continue;
sprintf( pBuffer, "%s%0*d", "n", nDigits, i );
NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
}
}
/**Function*************************************************************
Synopsis [Count the number of flops initialized to DC value.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p )
{
int i, nFlops, Count = 0;
if ( p->pInits == NULL )
return 0;
nFlops = strlen(p->pInits);
for ( i = 0; i < nFlops; i++ )
Count += (p->pInits[i] == 'x' || p->pInits[i] == 'X');
return Count;
}
/**Function*************************************************************
Synopsis [Create references.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_NtkSetRefs( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj; int i, k, Fanin;
Vec_IntFill( &p->vRefs, Wlc_NtkObjNumMax(p), 0 );
Wlc_NtkForEachObj( p, pObj, i )
Wlc_ObjForEachFanin( pObj, Fanin, k )
Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
Wlc_NtkForEachCo( p, pObj, i )
Vec_IntAddToEntry( &p->vRefs, Wlc_ObjId(p, pObj), 1 );
}
/**Function*************************************************************
Synopsis [This procedure simply count the number of PPI bits.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew )
{
Wlc_Obj_t * pObj;
int i, Count = 0;
Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
Count += Wlc_ObjRange(pObj);
return Count;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///

View File

@ -48,6 +48,9 @@ struct Smt_Prs_t_
char ErrorStr[1000];
};
//#define SMT_GLO_SUFFIX "_glb"
#define SMT_GLO_SUFFIX ""
// parser name types
typedef enum {
SMT_PRS_NONE = 0,
@ -219,6 +222,8 @@ static inline int Smt_StrToType( char * pName, int * pfSigned )
Type = WLC_OBJ_ARI_REM, *pfSigned = 1; // 40: arithmetic remainder
else if ( !strcmp(pName, "bvsmod") )
Type = WLC_OBJ_ARI_MODULUS, *pfSigned = 1; // 40: arithmetic modulus
else if ( !strcmp(pName, "=") )
Type = WLC_OBJ_COMP_EQU; // 40: arithmetic modulus
// else if ( !strcmp(pName, "") )
// Type = WLC_OBJ_ARI_POWER; // 41: arithmetic power
else if ( !strcmp(pName, "bvneg") )
@ -255,6 +260,8 @@ static inline int Smt_PrsReadType( Smt_Prs_t * p, int iSig, int * pfSigned, int
}
}
static inline int Smt_StrType( char * str ) { return Smt_StrToType(str, NULL); }
/**Function*************************************************************
Synopsis []
@ -274,20 +281,27 @@ static inline int Smt_PrsCreateNodeOld( Wlc_Ntk_t * pNtk, int Type, int fSigned,
assert( Type > 0 );
assert( Range >= 0 );
assert( fSigned >= 0 );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins );
if ( fSigned )
Wlc_NtkObj(pNtk, iObj)->Signed = fSigned;
if ( Type == WLC_OBJ_SHIFT_RA )
Wlc_NtkObj(pNtk, iObj)->Signed = 1;
// add node's name
if ( pName == NULL )
{
sprintf( Buffer, "_n%d_", iObj );
pName = Buffer;
}
// add node's name
NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound );
assert( !fFound );
assert( iObj == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins );
if ( fSigned )
{
Wlc_NtkObj(pNtk, iObj)->Signed = fSigned;
// if ( Vec_IntSize(vFanins) > 0 )
// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 0))->Signed = fSigned;
// if ( Vec_IntSize(vFanins) > 1 )
// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 1))->Signed = fSigned;
}
return iObj;
}
static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, int Range, Vec_Int_t * vFanins, char * pName )
@ -302,8 +316,7 @@ static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, in
assert( Range >= 0 );
assert( fSigned >= 0 );
// allow more than 2 fanins for specific operators
// if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX )
//if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX )
// explicitely secify allowed multi operators
if (Vec_IntSize(vFanins)<=2 ||
!( Type == WLC_OBJ_BIT_AND || // 16:`` bitwise AND
@ -362,17 +375,17 @@ FINISHED_WITH_FANINS:
Vec_IntFree(v2Fanins);
// to deal with long shifts create extra bit select (ROTATE as well ??)
//added to deal with long shifts create extra bit select (ROTATE as well ??)
// this is a temporary hack
// basically we keep only 32 bits.
// bits 0 - 30 are kept same as original
// bit 31 will be the reduction or of all bits from 31 to Range-1
// basically we keep only 32 bits.
// bit[31] will be the copy of original MSB (sign bit, just in case) UPDATE: assume it is unsigned first????
// bit[31] will be the reduction or of any bits from [31] to Range
if (Type == WLC_OBJ_SHIFT_R || Type == WLC_OBJ_SHIFT_RA || Type == WLC_OBJ_SHIFT_L)
{
int iFanin1 = Vec_IntEntry(vFanins,1);
int range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) );
int iObj1, iObj2, iObj3;
int range1, iObj1, iObj2, iObj3;
assert(Vec_IntSize(vFanins)>=2);
iFanin1 = Vec_IntEntry(vFanins,1);
range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) );
if (range1>32)
{
Vec_Int_t * newFanins = Vec_IntAlloc(10);
@ -389,6 +402,8 @@ FINISHED_WITH_FANINS:
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj1), newFanins );
//printf("obj1: %d\n",iObj1);
// bit select of larger bits
Vec_IntPop(newFanins);
Vec_IntPop(newFanins);
@ -402,6 +417,7 @@ FINISHED_WITH_FANINS:
assert( iObj2 == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj2), newFanins );
//printf("obj2: %d\n",iObj2);
// reduction or
Vec_IntPop( newFanins );
@ -416,6 +432,7 @@ FINISHED_WITH_FANINS:
assert( iObj3 == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj3), newFanins );
//printf("obj3: %d\n",iObj3);
// concat all together
Vec_IntWriteEntry( newFanins, 0, iObj3 );
@ -429,6 +446,7 @@ FINISHED_WITH_FANINS:
assert( iObj == NameId );
Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), newFanins );
//printf("obj: %d\n",iObj);
// pushing the new node
Vec_IntWriteEntry(vFanins, 1, iObj);
@ -461,34 +479,22 @@ FINISHED_WITH_FANINS:
return iObj;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline char * Smt_GetHexFromDecimalString(char * pStr)
{
int i,k=0, nDigits = strlen(pStr);
int digit, carry = 0;
int metNonZeroBit;
int nBits;
char * hex;
int metNonZeroBit = 0;
Vec_Int_t * decimal = Vec_IntAlloc(nDigits);
Vec_Int_t * rev;
int nBits;
char * hex;
for (i=0;i<nDigits;i++)
Vec_IntPush(decimal,pStr[i]-'0');
// firstly fill-in the reversed vector
// firstly fillin the reversed vector
rev = Vec_IntAlloc(10);
metNonZeroBit = 0;
while(k<nDigits)
{
digit = Vec_IntEntry(decimal,k);
@ -501,7 +507,7 @@ static inline char * Smt_GetHexFromDecimalString(char * pStr)
break;
else
{
Vec_IntPush(rev,carry);
Vec_IntPush(rev,carry);
carry = 0;
k = 0;
metNonZeroBit = 0;
@ -564,12 +570,17 @@ static inline char * Smt_GetHexFromDecimalString(char * pStr)
default: assert(0);
}
hex[nBits/4-1-k] = letter;
//if (k<Vec_IntSize(rev))
// Vec_IntPush(vFanins,Vec_IntEntry(rev,k));
//else
// Vec_IntPush(vFanins,0);
}
hex[nBits/4] = '\0';
Vec_IntFree(rev);
return hex;
}
}
static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits, char * pName )
{
int i, nDigits, iObj;
@ -578,6 +589,25 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
{
if ( pStr[0] >= '0' && pStr[0] <= '9' )
{
// added: sanity check for large constants
/*
Vec_Int_t * temp = Vec_IntAlloc(10);
int fullBits = -1;
Smt_GetBinaryFromDecimalString(pStr,temp,&fullBits);
Vec_IntFree(temp);
assert(fullBits < 32);*/
char * pHex = Smt_GetHexFromDecimalString(pStr);
if ( nBits == -1 )
nBits = strlen(pHex)*4;
//printf("nbits: %d\n",nBits);
Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex );
ABC_FREE( pHex );
/*
int w, nWords, Number = atoi( pStr );
if ( nBits == -1 )
@ -589,15 +619,6 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
for ( w = 0; w < nWords; w++ )
Vec_IntPush( vFanins, w ? 0 : Number );
*/
// convert decimal to hex to parse large constants
char * pHex = Smt_GetHexFromDecimalString(pStr);
if ( nBits == -1 )
nBits = strlen(pHex)*4;
Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex );
}
else
{
@ -616,7 +637,10 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
if ( pStr[2+i] == '1' )
Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i );
else if ( pStr[2+i] != '0' )
{
Vec_IntFree( vFanins );
return 0;
}
}
else if ( pStr[1] == 'x' ) // hexadecimal
{
@ -625,9 +649,16 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits
Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 );
if ( nDigits != (nBits + 3)/4 )
{
Vec_IntFree( vFanins );
return 0;
}
}
else
{
Vec_IntFree( vFanins );
return 0;
}
else return 0;
// create constant node
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_CONST, 0, nBits, vFanins, pName );
Vec_IntFree( vFanins );
@ -648,12 +679,6 @@ int Smt_PrsBuildNode( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int RangeOut,
// s3087
int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
assert( fFound );
// create buffer if the name of the fanin has different name
if ( pName && strcmp(pStr, pName) )
{
Vec_IntFill( &p->vTempFans, 1, iObj );
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, RangeOut, &p->vTempFans, pName );
}
return iObj;
}
}
@ -804,13 +829,6 @@ Wlc_Ntk_t * Smt_PrsBuild( Smt_Prs_t * p )
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
vFans2 = Smt_VecEntryNode(p, vFans, 2);
if ( Vec_IntSize(vFans2) > 0 )
{
printf( "File parsing error: Uninterpreted functions are not supported.\n" );
Wlc_NtkFree( pNtk ); pNtk = NULL;
goto finish;
}
// check type (Bool or BitVec)
Fan = Vec_IntEntry(vFans, 3);
if ( Smt_EntryIsName(Fan) )
@ -1006,6 +1024,14 @@ char * Smt_PrsGenName( Smt_Prs_t * p )
}
int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pName )
{
char suffix[100];
sprintf(suffix,"_as%d",pNtk->nAssert);
//char * prepStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode));
//printf("prestr: %s\n",prepStr);
//printf("inode: %d %d\n",iNode,Smt_EntryIsName(iNode));
if ( Smt_EntryIsName(iNode) )
{
char * pStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode));
@ -1018,7 +1044,27 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
return Smt_PrsBuildConstant( pNtk, pStr, -1, pName ? pName : Smt_PrsGenName(p) );
else
{
int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
int fFound, iObj;
// look either for global DECLARE-FUN variable or local LET
char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb
char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1);
strcpy(pStr_glb,pStr);
strcat(pStr_glb,SMT_GLO_SUFFIX);
strcpy(pStr_loc,pStr);
strcat(pStr_loc,suffix);
fFound = Abc_NamStrFind( pNtk->pManName, pStr_glb );
if (fFound)
pStr = pStr_glb;
else
{
assert( Abc_NamStrFind( pNtk->pManName, pStr_loc ));
pStr = pStr_loc;
}
// FIXME: delete memory of pStr
iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound );
assert( fFound );
// create buffer if the name of the fanin has different name
if ( pName && strcmp(Wlc_ObjName(pNtk, iObj), pName) )
@ -1026,9 +1072,11 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
Vec_IntFill( &p->vTempFans, 1, iObj );
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, Wlc_ObjRange(Wlc_NtkObj(pNtk, iObj)), &p->vTempFans, pName );
}
ABC_FREE( pStr_glb );
ABC_FREE( pStr_loc );
return iObj;
}
}
}
else
{
Vec_Int_t * vRoots, * vRoots1, * vFans3;
@ -1039,7 +1087,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
if ( Smt_EntryIsName(iRoot0) )
{
char * pName2, * pStr0 = Abc_NamStr(p->pStrs, Abc_Lit2Var(iRoot0));
if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET )
if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET || Abc_Lit2Var(iRoot0) == SMT_PRS_DEFINE_FUN) //added define-fun is similar to let
{
// let ((s35550 (bvor s48 s35549)))
assert( Vec_IntSize(vRoots) == 3 );
@ -1051,6 +1099,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
// iterate through the parts
Vec_IntForEachEntry( vRoots1, Fan, k )
{
char * temp;
// s35550 (bvor s48 s35549)
assert( !Smt_EntryIsName(Fan) );
vFans3 = Smt_EntryNode(p, Fan);
@ -1059,11 +1108,26 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
Fan3 = Vec_IntEntry(vFans3, 0);
assert( Smt_EntryIsName(Fan3) );
pName2 = Smt_EntryName(p, Fan3);
// create a local name with suffix
if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET )
{
temp = (char *)malloc(strlen(pName2) + strlen(suffix) + 1);
strcpy(temp, pName2);
strcat(temp,suffix);
}
else
{ temp = (char *)malloc(strlen(pName2) + 4 + 1);
strcpy(temp, pName2);
strcat(temp,SMT_GLO_SUFFIX);
}
// FIXME: need to delete memory of pName2
pName2 = temp;
// get function
Fan3 = Vec_IntEntry(vFans3, 1);
//assert( !Smt_EntryIsName(Fan3) );
// solve the problem
iObj = Smt_PrsBuild2_rec( pNtk, p, Fan3, -1, pName2 ); // NULL ); //pName2 );
ABC_FREE( temp );
if ( iObj == 0 )
return 0;
// create buffer
@ -1133,7 +1197,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
int iObj = Abc_NamStrFind( pNtk->pManName, pStr0 );
if ( iObj )
return iObj;
Type0 = Smt_StrToType( pStr0, &fSigned );
if ( Type0 == 0 )
return 0;
@ -1151,7 +1214,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev,
}
Vec_IntPush( vFanins, iObj );
}
// find range
Range = 0;
if ( Type0 >= WLC_OBJ_LOGIC_NOT && Type0 <= WLC_OBJ_REDUCT_XOR )
@ -1197,7 +1259,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Wlc_Ntk_t * pNtk;
Vec_Int_t * vFansRoot, * vFans, * vFans2;
Vec_Int_t * vAsserts = Vec_IntAlloc(100);
int i, Root, Fan, iObj, NameId, Range, Status, nBits = 0;
int i, Root, Fan, iObj, NameId, Range, nBits = 0;
char * pName, * pRange;
// start network and create primary inputs
pNtk = Wlc_NtkAlloc( p->pName, 1000 );
@ -1214,22 +1276,22 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// create variables
if ( Abc_Lit2Var(Fan) == SMT_PRS_DECLARE_FUN )
{
char * pName_glb;
assert( Vec_IntSize(vFans) == 4 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DECLARE_FUN) );
// get name
Fan = Vec_IntEntry(vFans, 1);
assert( Smt_EntryIsName(Fan) );
pName = Smt_EntryName(p, Fan);
// added: giving a global suffix
pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
strcpy(pName_glb,pName);
strcat(pName_glb,SMT_GLO_SUFFIX);
// FIXME: delete memory of pName
pName = pName_glb;
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
vFans2 = Smt_VecEntryNode(p, vFans, 2);
if ( Vec_IntSize(vFans2) > 0 )
{
printf( "File parsing error: Uninterpreted functions are not supported.\n" );
Wlc_NtkFree( pNtk ); pNtk = NULL;
goto finish;
}
// check type (Bool or BitVec)
Fan = Vec_IntEntry(vFans, 3);
if ( Smt_EntryIsName(Fan) )
@ -1259,9 +1321,11 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Vec_IntPush( &pNtk->vValues, nBits );
Vec_IntPush( &pNtk->vValues, Range );
nBits += Range;
ABC_FREE( pName_glb );
}
// create constants
else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN )
/*
else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) // added: we parse DEFINE_FUN in LET
{
assert( Vec_IntSize(vFans) == 5 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) );
@ -1269,6 +1333,14 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
Fan = Vec_IntEntry(vFans, 1);
assert( Smt_EntryIsName(Fan) );
pName = Smt_EntryName(p, Fan);
// added: giving a global suffix
char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
strcpy(pName_glb,pName);
strcat(pName_glb,SMT_GLO_SUFFIX);
// FIXME: delete memory of pName
pName = pName_glb;
// skip ()
Fan = Vec_IntEntry(vFans, 2);
assert( !Smt_EntryIsName(Fan) );
@ -1278,13 +1350,17 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
{
// (define-fun s_2 () Bool false)
assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) );
iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), -1, pName );
if ( iObj == 0 )
{
Wlc_NtkFree( pNtk ); pNtk = NULL;
goto finish;
}
continue;
Range = 1;
pValue = Smt_VecEntryName(p, vFans, 4);
//printf("value: %s\n",pValue);
if ( !strcmp("false", pValue) )
pValue = "#b0";
else if ( !strcmp("true", pValue) )
pValue = "#b1";
else assert( 0 );
Status = Smt_PrsBuildConstant( pNtk, pValue, Range, pName );
}
else
{
@ -1292,6 +1368,74 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// (define-fun s1 () (_ BitVec 8) (bvneg #x7f))
// get range
Fan = Vec_IntEntry(vFans, 3);
assert( !Smt_EntryIsName(Fan) );
vFans2 = Smt_VecEntryNode(p, vFans, 3);
assert( Vec_IntSize(vFans2) == 3 );
assert( !strcmp("_", Smt_VecEntryName(p, vFans2, 0)) );
assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) );
// get range
Fan = Vec_IntEntry(vFans2, 2);
assert( Smt_EntryIsName(Fan) );
pRange = Smt_EntryName(p, Fan);
Range = atoi(pRange);
// added: can parse functions too
Vec_Int_t * vFans3 = Smt_VecEntryNode(p, vFans, 4);
Fan = Vec_IntEntry(vFans3, 0);
// get constant
//Fan = Vec_IntEntry(vFans, 4);
//printf("fan3: %s\n",Fan);
//printf("fan0: %s\n",Smt_VecEntryName(p, vFans3, 0));
//printf("fan1: %s\n",Smt_VecEntryName(p, vFans3, 1));
//printf("fan2: %s\n",Smt_VecEntryName(p, vFans3, 2));
//printf("fan3: %s\n",Smt_VecEntryName(p, vFans3, 3));
Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName );
}
if ( !Status )
{
Wlc_NtkFree( pNtk ); pNtk = NULL;
goto finish;
}
}
*/
// added: new way to parse define-fun
// create constants
else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN )
{
char * pName_glb;
// (define-fun def_16001 () Bool (or def_15999 def_16000))
// (define-fun def_15990 () (_ BitVec 24) (concat def_15988 def_15989))
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) );
assert( Vec_IntSize(vFans) == 5 ); // const or definition
// get name
Fan = Vec_IntEntry(vFans, 1);
assert( Smt_EntryIsName(Fan) );
pName = Smt_EntryName(p, Fan);
// added: giving a global suffix
pName_glb = (char *) malloc(strlen(pName) + 4 + 1);
strcpy(pName_glb,pName);
strcat(pName_glb,SMT_GLO_SUFFIX);
// FIXME: delete memory of pName
pName = pName_glb;
//get range
Fan = Vec_IntEntry(vFans, 3);
if ( Smt_EntryIsName(Fan) )
{
// (define-fun s_2 () Bool false)
assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) );
Range = 1;
}
else
{
// (define-fun s702 () (_ BitVec 4) #xe)
// (define-fun s1 () (_ BitVec 8) (bvneg #x7f))
assert( !Smt_EntryIsName(Fan) );
vFans2 = Smt_VecEntryNode(p, vFans, 3);
assert( Vec_IntSize(vFans2) == 3 );
@ -1302,16 +1446,13 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
assert( Smt_EntryIsName(Fan) );
pRange = Smt_EntryName(p, Fan);
Range = atoi(pRange);
// get constant
Fan = Vec_IntEntry(vFans, 4);
Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName );
}
if ( !Status )
{
Wlc_NtkFree( pNtk ); pNtk = NULL;
goto finish;
}
iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), Range, pName );
assert( iObj );
ABC_FREE( pName_glb );
}
// collect assertion outputs
else if ( Abc_Lit2Var(Fan) == SMT_PRS_ASSERT )
{
@ -1321,6 +1462,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
//(assert (not (= s0 #x00)))
assert( Vec_IntSize(vFans) == 2 );
assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_ASSERT) );
pNtk->nAssert++; // added
iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 1), -1, NULL );
if ( iObj == 0 )
{
@ -1336,6 +1478,9 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p )
// build AND of asserts
if ( Vec_IntSize(vAsserts) == 1 )
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, 1, vAsserts, "miter" );
// added: 0 asserts
else if ( Vec_IntSize(vAsserts) == 0 )
iObj = Smt_PrsBuildConstant( pNtk, "#b1", 1, "miter" );
else
{
iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vAsserts), vAsserts, NULL );
@ -1413,18 +1558,35 @@ static inline char * Smt_PrsLoadFile( char * pFileName, char ** ppLimit )
static inline int Smt_PrsRemoveComments( char * pBuffer, char * pLimit )
{
char * pTemp; int nCount1 = 0, nCount2 = 0, fHaveBar = 0;
int backslash = 0;
for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ )
{
if ( *pTemp == '(' )
nCount1++;
{ if ( !fHaveBar ) nCount1++; }
else if ( *pTemp == ')' )
nCount2++;
{ if ( !fHaveBar ) nCount2++; }
else if ( *pTemp == '|' )
fHaveBar ^= 1;
else if ( *pTemp == ';' && !fHaveBar )
while ( *pTemp && *pTemp != '\n' )
*pTemp++ = ' ';
// added: hack to remove quotes
else if ( *pTemp == '\"' && *(pTemp-1) != '\\' && !fHaveBar )
{
*pTemp++ = ' ';
while ( *pTemp && (*pTemp != '\"' || backslash))
{
if (*pTemp == '\\')
backslash = 1;
else
backslash = 0;
*pTemp++ = ' ';
}
// remove the last quote symbol
*pTemp = ' ';
}
}
if ( nCount1 != nCount2 )
printf( "The input SMTLIB file has different number of opening and closing parentheses (%d and %d).\n", nCount1, nCount2 );
else if ( nCount1 == 0 )
@ -1486,6 +1648,7 @@ static inline void Smt_PrsSkipNonSpaces( Smt_Prs_t * p )
}
void Smt_PrsReadLines( Smt_Prs_t * p )
{
int fFirstTime = 1;
assert( Vec_IntSize(&p->vStack) == 0 );
//assert( Vec_WecSize(&p->vDepth) == 0 );
assert( Vec_WecSize(&p->vObjs) == 0 );
@ -1499,6 +1662,16 @@ void Smt_PrsReadLines( Smt_Prs_t * p )
for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ )
{
Smt_PrsSkipSpaces( p );
if ( fFirstTime && *p->pCur == '|' )
{
fFirstTime = 0;
*p->pCur = ' ';
while ( *p->pCur && *p->pCur != '|' )
*p->pCur++ = ' ';
if ( *p->pCur == '|' )
*p->pCur = ' ';
continue;
}
if ( *p->pCur == '(' )
{
// add new node at this depth
@ -1524,12 +1697,13 @@ void Smt_PrsReadLines( Smt_Prs_t * p )
{
// remove strange characters (this can lead to name clashes)
int iToken;
/* commented out for SMT comp
char * pTemp;
if ( *pStart == '?' )
*pStart = '_';
for ( pTemp = pStart; pTemp < p->pCur; pTemp++ )
if ( *pTemp == '.' )
*pTemp = '_';
*pTemp = '_';*/
// create and save token for this string
iToken = Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur--, NULL );
Vec_IntPush( Vec_WecEntry(&p->vObjs, Vec_IntEntryLast(&p->vStack)), Abc_Var2Lit(iToken, 1) );

View File

@ -28,7 +28,7 @@ ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
// Word-level Verilog file parser
#define WLV_PRS_MAX_LINE 1000
#define WLV_PRS_MAX_LINE 10000
typedef struct Wlc_Prs_t_ Wlc_Prs_t;
struct Wlc_Prs_t_
@ -1265,8 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
if ( !Wlc_PrsDerive( p ) )
goto finish;
// derive topological order
pNtk = Wlc_NtkDupDfs( p->pNtk );
Wlc_NtkTransferNames( pNtk, p->pNtk );
pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 );
pNtk->pSpec = Abc_UtilStrsav( pFileName );
finish:
Wlc_PrsPrintErrorMessage( p );

337
src/base/wlc/wlcShow.c Normal file
View File

@ -0,0 +1,337 @@
/**CFile****************************************************************
FileName [wlcShow.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Verilog parser.]
Synopsis [Parses several flavors of word-level Verilog.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - August 22, 2014.]
Revision [$Id: wlcShow.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
***********************************************************************/
#include "wlc.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Writes the graph structure of WLC for DOT.]
Description [Useful for graph visualization using tools such as GraphViz:
http://www.graphviz.org/]
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold )
{
FILE * pFile;
Wlc_Obj_t * pNode;
int LevelMax, Prev, Level, i;
if ( Wlc_NtkObjNum(p) > 2000 )
{
fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 2000 );
return;
}
if ( (pFile = fopen( pFileName, "w" )) == NULL )
{
fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
return;
}
// mark the nodes
if ( vBold )
Wlc_NtkForEachObjVec( vBold, p, pNode, i )
pNode->Mark = 1;
// compute levels
LevelMax = 1 + Wlc_NtkCreateLevelsRev( p );
// write the DOT header
fprintf( pFile, "# %s\n", "WLC structure generated by ABC" );
fprintf( pFile, "\n" );
fprintf( pFile, "digraph WLC {\n" );
fprintf( pFile, "size = \"7.5,10\";\n" );
// fprintf( pFile, "ranksep = 0.5;\n" );
// fprintf( pFile, "nodesep = 0.5;\n" );
fprintf( pFile, "center = true;\n" );
// fprintf( pFile, "orientation = landscape;\n" );
// fprintf( pFile, "edge [fontsize = 10];\n" );
// fprintf( pFile, "edge [dir = none];\n" );
fprintf( pFile, "edge [dir = back];\n" );
fprintf( pFile, "\n" );
// labels on the left of the picture
fprintf( pFile, "{\n" );
fprintf( pFile, " node [shape = plaintext];\n" );
fprintf( pFile, " edge [style = invis];\n" );
fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
// generate node names with labels
for ( Level = LevelMax; Level >= 0; Level-- )
{
// the visible node name
fprintf( pFile, " Level%d", Level );
fprintf( pFile, " [label = " );
// label name
fprintf( pFile, "\"" );
fprintf( pFile, "\"" );
fprintf( pFile, "];\n" );
}
// genetate the sequence of visible/invisible nodes to mark levels
fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
for ( Level = LevelMax; Level >= 0; Level-- )
{
// the visible node name
fprintf( pFile, " Level%d", Level );
// the connector
if ( Level != 0 )
fprintf( pFile, " ->" );
else
fprintf( pFile, ";" );
}
fprintf( pFile, "\n" );
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
// generate title box on top
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
fprintf( pFile, " LevelTitle1;\n" );
fprintf( pFile, " title1 [shape=plaintext,\n" );
fprintf( pFile, " fontsize=20,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
fprintf( pFile, "%s", "WLC structure generated by ABC" );
fprintf( pFile, "\\n" );
fprintf( pFile, "Benchmark \\\"%s\\\". ", p->pName );
// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
fprintf( pFile, "\"\n" );
fprintf( pFile, " ];\n" );
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
// generate statistics box
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
fprintf( pFile, " LevelTitle2;\n" );
fprintf( pFile, " title2 [shape=plaintext,\n" );
fprintf( pFile, " fontsize=18,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkCiNum(p), LevelMax-1 );
fprintf( pFile, "\\n" );
fprintf( pFile, "\"\n" );
fprintf( pFile, " ];\n" );
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
// generate the COs
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
// the labeling node of this level
fprintf( pFile, " Level%d;\n", LevelMax );
// generate the CO nodes
Wlc_NtkForEachCo( p, pNode, i )
{
pNode = Wlc_ObjCo2PoFo(p, i);
fprintf( pFile, " NodePo%d [label = \"%s_in %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
fprintf( pFile, ", shape = %s", i < Wlc_NtkPoNum(p) ? "invtriangle" : "box" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
fprintf( pFile, "];\n" );
}
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
// generate nodes of each rank
for ( Level = LevelMax - 1; Level > 0; Level-- )
{
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
// the labeling node of this level
fprintf( pFile, " Level%d;\n", Level );
Wlc_NtkForEachObj( p, pNode, i )
{
if ( (int)Wlc_ObjLevel(p, pNode) != Level )
continue;
if ( pNode->Type == WLC_OBJ_CONST )
{
fprintf( pFile, " Node%d [label = \"0x", i );
Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 );
fprintf( pFile, "\"" );
}
else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_MUX )
fprintf( pFile, " Node%d [label = \"%d\"", i, Wlc_ObjRange(pNode) );
else if ( pNode->Type >= WLC_OBJ_LOGIC_NOT && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
fprintf( pFile, " Node%d [label = \"%s\"", i, Wlc_ObjTypeName(pNode) );
else
fprintf( pFile, " Node%d [label = \"%s %d\"", i, Wlc_ObjTypeName(pNode), Wlc_ObjRange(pNode) );
if ( pNode->Type == WLC_OBJ_ARI_MULTI )
fprintf( pFile, ", shape = doublecircle" );
else if ( pNode->Type >= WLC_OBJ_COMP_EQU && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
fprintf( pFile, ", shape = diamond" );
else if ( pNode->Type == WLC_OBJ_BIT_SELECT || pNode->Type == WLC_OBJ_BIT_CONCAT )
fprintf( pFile, ", shape = box" );
else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_BIT_ZEROPAD || pNode->Type == WLC_OBJ_BIT_SIGNEXT )
fprintf( pFile, ", shape = triangle" );
else if ( pNode->Type == WLC_OBJ_MUX )
fprintf( pFile, ", shape = trapezium" );
else
fprintf( pFile, ", shape = ellipse" );
if ( vBold ? pNode->Mark : ((pNode->Type >= WLC_OBJ_ARI_ADD && pNode->Type <= WLC_OBJ_ARI_SQUARE) || pNode->Type == WLC_OBJ_BIT_NOT) )
fprintf( pFile, ", style = filled" );
fprintf( pFile, "];\n" );
}
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
}
// generate the CI nodes
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
// the labeling node of this level
fprintf( pFile, " Level%d;\n", 0 );
// generate the CI nodes
Wlc_NtkForEachCi( p, pNode, i )
{
fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
fprintf( pFile, ", shape = %s", i < Wlc_NtkPiNum(p) ? "triangle" : "box" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
fprintf( pFile, "];\n" );
}
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
// generate invisible edges from the square down
fprintf( pFile, "title1 -> title2 [style = invis];\n" );
Wlc_NtkForEachCo( p, pNode, i )
{
pNode = Wlc_ObjCo2PoFo( p, i );
fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) );
}
// generate invisible edges among the COs
Prev = -1;
Wlc_NtkForEachCo( p, pNode, i )
{
pNode = Wlc_ObjCo2PoFo( p, i );
if ( i > 0 )
fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
Prev = Wlc_ObjId(p, pNode);
}
// generate invisible edges among the CIs
Prev = -1;
Wlc_NtkForEachCi( p, pNode, i )
{
if ( i > 0 )
fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
Prev = Wlc_ObjId(p, pNode);
}
// generate edges
Wlc_NtkForEachCo( p, pNode, i )
{
fprintf( pFile, "NodePo%d", Wlc_ObjId(p, Wlc_ObjCo2PoFo(p, i)) );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", Wlc_ObjId(p, pNode) );
fprintf( pFile, " [" );
fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "solid" );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}
Wlc_NtkForEachObj( p, pNode, i )
{
int k, iFanin;
if ( Wlc_ObjIsCi(pNode) )
continue;
// generate the edge from this node to the next
Wlc_ObjForEachFanin( pNode, iFanin, k )
{
fprintf( pFile, "Node%d", i );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", iFanin );
fprintf( pFile, " [" );
fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "solid" );
if ( pNode->Type == WLC_OBJ_MUX && k == 0 )
fprintf( pFile, ", style = %s", "bold" );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}
}
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
fclose( pFile );
// unmark nodes
if ( vBold )
Wlc_NtkCleanMarks( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold )
{
extern void Abc_ShowFile( char * FileNameDot );
FILE * pFile;
char FileNameDot[200];
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(p->pName, ".dot") );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
{
fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
return;
}
fclose( pFile );
// generate the file
Wlc_NtkDumpDot( p, FileNameDot, vBold );
// visualize the file
Abc_ShowFile( FileNameDot );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -43,13 +43,13 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj )
{
return Vec_WrdEntryP( p->vSims, p->iPatsPi * iObj );
return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );
}
static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj )
{
int w;
word * pSim = Wlc_ObjSim( p, iObj );
for ( w = 0; w < p->iPatsPi; w++ )
for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = Gia_ManRandomW( 0 );
}
static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )
@ -57,7 +57,7 @@ static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )
int w;
word * pSimRo = Wlc_ObjSim( p, iObj );
word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) );
for ( w = 0; w < p->iPatsPi; w++ )
for ( w = 0; w < p->nSimWords; w++ )
pSimRo[w] = pSimRi[w];
}
static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )
@ -67,10 +67,10 @@ static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )
word * pSimCo = Wlc_ObjSim( p, iObj );
word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
if ( Gia_ObjFaninC0(pObj) )
for ( w = 0; w < p->iPatsPi; w++ )
for ( w = 0; w < p->nSimWords; w++ )
pSimCo[w] = ~pSimDri[w];
else
for ( w = 0; w < p->iPatsPi; w++ )
for ( w = 0; w < p->nSimWords; w++ )
pSimCo[w] = pSimDri[w];
}
static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )
@ -81,16 +81,16 @@ static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )
word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );
if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
for ( w = 0; w < p->iPatsPi; w++ )
for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = ~pSim0[w] & ~pSim1[w];
else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
for ( w = 0; w < p->iPatsPi; w++ )
for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = ~pSim0[w] & pSim1[w];
else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
for ( w = 0; w < p->iPatsPi; w++ )
for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = pSim0[w] & ~pSim1[w];
else
for ( w = 0; w < p->iPatsPi; w++ )
for ( w = 0; w < p->nSimWords; w++ )
pSim[w] = pSim0[w] & pSim1[w];
}
@ -135,7 +135,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int
// allocate simulation info for one timeframe
Vec_WrdFreeP( &pGia->vSims );
pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords );
pGia->iPatsPi = nWords;
pGia->nSimWords = nWords;
// allocate resulting simulation info
vRes = Vec_PtrAlloc( Vec_IntSize(vNodes) );
Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i )
@ -188,7 +188,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int
printf( "Replaced %d dangling internal bits with constant 0.\n", Counter );
}
Vec_WrdFreeP( &pGia->vSims );
pGia->iPatsPi = 0;
pGia->nSimWords = 0;
Gia_ManStop( pGia );
return vRes;
}

290
src/base/wlc/wlcUif.c Normal file
View File

@ -0,0 +1,290 @@
/**CFile****************************************************************
FileName [wlcUif.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Verilog parser.]
Synopsis [Abstraction for word-level networks.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - August 22, 2014.]
Revision [$Id: wlcUif.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
***********************************************************************/
#include "wlc.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Check if two objects have the same input/output signatures.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 )
{
Wlc_Obj_t * pFanin, * pFanin2; int k;
if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) )
return 0;
if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) )
return 0;
if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) )
return 0;
for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
{
pFanin = Wlc_ObjFanin(p, pObj, k);
pFanin2 = Wlc_ObjFanin(p, pObj2, k);
if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) )
return 0;
if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) )
return 0;
}
return 1;
}
/**Function*************************************************************
Synopsis [Collect IDs of the multipliers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj; int i;
Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 );
Wlc_NtkForEachObj( p, pObj, i )
if ( pObj->Type == WLC_OBJ_ARI_MULTI )
Vec_IntPush( vBoxIds, i );
if ( Vec_IntSize( vBoxIds ) > 0 )
return vBoxIds;
Vec_IntFree( vBoxIds );
return NULL;
}
/**Function*************************************************************
Synopsis [Returns all pairs of uifable multipliers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p )
{
Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p );
Vec_Int_t * vPairs = Vec_IntAlloc( 2 );
Wlc_Obj_t * pObj, * pObj2; int i, k;
// iterate through unique pairs
Wlc_NtkForEachObjVec( vMultis, p, pObj, i )
Wlc_NtkForEachObjVec( vMultis, p, pObj2, k )
{
if ( k == i )
break;
if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) )
{
Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) );
Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) );
}
}
Vec_IntFree( vMultis );
if ( Vec_IntSize( vPairs ) > 0 )
return vPairs;
Vec_IntFree( vPairs );
return NULL;
}
/**Function*************************************************************
Synopsis [Abstracts nodes by replacing their outputs with new PIs.]
Description [If array is NULL, abstract all multipliers.]
SideEffects []
SeeAlso []
***********************************************************************/
Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit )
{
Vec_Int_t * vNodes = vNodesInit;
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj;
int i, k, iObj, iFanin;
// get multipliers if not given
if ( vNodes == NULL )
vNodes = Wlc_NtkCollectMultipliers( p );
if ( vNodes == NULL )
return NULL;
// mark nodes
Wlc_NtkForEachObjVec( vNodes, p, pObj, i )
pObj->Mark = 1;
// iterate through the nodes in the DFS order
Wlc_NtkCleanCopy( p );
Wlc_NtkForEachObj( p, pObj, i )
{
if ( i == Vec_IntSize(&p->vCopies) )
break;
if ( pObj->Mark ) {
// clean
pObj->Mark = 0;
// add fresh PI with the same number of bits
iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 );
}
else {
// update fanins
Wlc_ObjForEachFanin( pObj, iFanin, k )
Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin);
// node to remain
iObj = i;
}
Wlc_ObjSetCopy( p, i, iObj );
}
// POs do not change in this procedure
if ( vNodes != vNodesInit )
Vec_IntFree( vNodes );
// reconstruct topological order
pNew = Wlc_NtkDupDfs( p, 0, 1 );
return pNew;
}
/**Function*************************************************************
Synopsis [Adds UIF constraints to node pairs and updates POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit )
{
Vec_Int_t * vPairs = vPairsInit;
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj, * pObj2;
Vec_Int_t * vUifConstrs, * vCompares, * vFanins;
int i, k, iObj, iObj2, iObjNew, iObjNew2;
int iFanin, iFanin2, iFaninNew;
// get multiplier pairs if not given
if ( vPairs == NULL )
vPairs = Wlc_NtkFindUifableMultiplierPairs( p );
if ( vPairs == NULL )
return NULL;
// sanity checks
assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 );
// iterate through node pairs
vFanins = Vec_IntAlloc( 100 );
vCompares = Vec_IntAlloc( 100 );
vUifConstrs = Vec_IntAlloc( 100 );
Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i )
{
// get two nodes
pObj = Wlc_NtkObj( p, iObj );
pObj2 = Wlc_NtkObj( p, iObj2 );
assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) );
// create fanin comparator nodes
Vec_IntClear( vCompares );
Wlc_ObjForEachFanin( pObj, iFanin, k )
{
iFanin2 = Wlc_ObjFaninId( pObj2, k );
Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 );
iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins );
Vec_IntPush( vCompares, iFaninNew );
// note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
// Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
pObj = Wlc_NtkObj( p, iObj );
}
// concatenate fanin comparators
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares );
// create reduction-OR node
Vec_IntFill( vFanins, 1, iObjNew );
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins );
// craete output comparator node
Vec_IntFillTwo( vFanins, 2, iObj, iObj2 );
iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins );
// create implication node (iObjNew is already complemented above)
Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 );
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins );
// save the constraint
Vec_IntPush( vUifConstrs, iObjNew );
}
// derive the AND of the UIF contraints
assert( Vec_IntSize(vUifConstrs) > 0 );
if ( Vec_IntSize(vUifConstrs) == 1 )
iObjNew = Vec_IntEntry( vUifConstrs, 0 );
else
{
// concatenate
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs );
// create reduction-AND node
Vec_IntFill( vFanins, 1, iObjNew );
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins );
}
// update each PO to point to the new node
Wlc_NtkForEachPo( p, pObj, i )
{
iObj = Wlc_ObjId(p, pObj);
Vec_IntFillTwo( vFanins, 2, iObj, iObjNew );
iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins );
// note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to
// Wlc_ObjCreate() due to a possible realloc of the internal array of objects...
pObj = Wlc_NtkObj( p, iObj );
// update PO/CO arrays
assert( Vec_IntEntry(&p->vPos, i) == iObj );
assert( Vec_IntEntry(&p->vCos, i) == iObj );
Vec_IntWriteEntry( &p->vPos, i, iObjNew );
Vec_IntWriteEntry( &p->vCos, i, iObjNew );
// transfer the PO attribute
Wlc_NtkObj(p, iObjNew)->fIsPo = 1;
assert( pObj->fIsPo );
pObj->fIsPo = 0;
}
// cleanup
Vec_IntFree( vUifConstrs );
Vec_IntFree( vCompares );
Vec_IntFree( vFanins );
if ( vPairs != vPairsInit )
Vec_IntFree( vPairs );
// reconstruct topological order
pNew = Wlc_NtkDupDfs( p, 0, 1 );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -409,7 +409,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
fprintf( pFile, " reg%d (", i );
fprintf( pFile, " .q( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
fprintf( pFile, " .qbar()," );
fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFoToFi(p, pObj))) );
fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj))) );
fprintf( pFile, " .clk( %s ),", "1\'b0" );
fprintf( pFile, " .arst( %s ),", "1\'b0" );
if ( p->vInits )

View File

@ -2333,6 +2333,255 @@ void Extra_zddDumpPla( DdManager * dd, DdNode * F, int nVars, char * pFileName )
ABC_FREE( pCube );
}
/**Function*************************************************************
Synopsis [Constructing ZDD of a graph.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Extra_GraphExperiment()
{
int Edges[5][5] = {
{1, 3, 4},
{1, 5},
{2, 3, 5},
{2, 4}
};
int e, n;
DdManager * dd = Cudd_Init( 0, 6, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
// create the edges
DdNode * zGraph, * zEdge, * zVar, * zTemp;
zGraph = DD_ZERO(dd); Cudd_Ref( zGraph );
for ( e = 0; Edges[e][0]; e++ )
{
zEdge = DD_ONE(dd); Cudd_Ref( zEdge );
for ( n = 0; Edges[e][n]; n++ )
{
zVar = cuddZddGetNode( dd, Edges[e][n], DD_ONE(dd), DD_ZERO(dd) ); Cudd_Ref( zVar );
zEdge = Cudd_zddUnateProduct( dd, zTemp = zEdge, zVar ); Cudd_Ref( zEdge );
Cudd_RecursiveDerefZdd( dd, zTemp );
Cudd_RecursiveDerefZdd( dd, zVar );
}
zGraph = Cudd_zddUnion( dd, zTemp = zGraph, zEdge ); Cudd_Ref( zGraph );
Cudd_RecursiveDerefZdd( dd, zTemp );
Cudd_RecursiveDerefZdd( dd, zEdge );
}
Cudd_zddPrintMinterm( dd, zGraph );
Cudd_RecursiveDerefZdd( dd, zGraph );
Cudd_Quit(dd);
}
/**Function********************************************************************
Synopsis [Performs the reordering-sensitive step of Extra_zddCombination().]
Description [Generates in a bottom-up fashion ZDD for one combination
whose var values are given in the array VarValues. If necessary,
creates new variables on the fly.]
SideEffects []
SeeAlso []
******************************************************************************/
DdNode * extraZddCombination(
DdManager* dd,
int* VarValues,
int nVars )
{
int lev, index;
DdNode *zRes, *zTemp;
/* transform the combination from the array VarValues into a ZDD cube. */
zRes = dd->one;
cuddRef(zRes);
/* go through levels starting bottom-up and create nodes
* if these variables are present in the comb
*/
for (lev = nVars - 1; lev >= 0; lev--)
{
index = (lev >= dd->sizeZ) ? lev : dd->invpermZ[lev];
if (VarValues[index] == 1)
{
/* compose zRes with ZERO for the given ZDD variable */
zRes = cuddZddGetNode( dd, index, zTemp = zRes, dd->zero );
if ( zRes == NULL )
{
Cudd_RecursiveDerefZdd( dd, zTemp );
return NULL;
}
cuddRef( zRes );
cuddDeref( zTemp );
}
}
cuddDeref( zRes );
return zRes;
} /* end of extraZddCombination */
/**Function********************************************************************
Synopsis [Creates ZDD of the combination containing given variables.]
Description [Creates ZDD of the combination containing given variables.
VarValues contains 1 for a variable that belongs to the
combination and 0 for a varible that does not belong.
nVars is number of ZDD variables in the array.]
SideEffects [New ZDD variables are created if indices of the variables
present in the combination are larger than the currently
allocated number of ZDD variables.]
SeeAlso []
******************************************************************************/
DdNode * Extra_zddCombination(
DdManager *dd,
int* VarValues,
int nVars )
{
DdNode *res;
do {
dd->reordered = 0;
res = extraZddCombination(dd, VarValues, nVars);
} while (dd->reordered == 1);
return(res);
} /* end of Extra_zddCombination */
/**Function********************************************************************
Synopsis [Generates a random set of combinations.]
Description [Given a set of n elements, each of which is encoded using one
ZDD variable, this function generates a random set of k subsets
(combinations of elements) with density d. Assumes that k and n
are positive integers. Returns NULL if density is less than 0.0
or more than 1.0.]
SideEffects [Allocates new ZDD variables if their current number is less than n.]
SeeAlso []
******************************************************************************/
DdNode* Extra_zddRandomSet(
DdManager * dd, /* the DD manager */
int n, /* the number of elements */
int k, /* the number of combinations (subsets) */
double d) /* average density of elements in combinations */
{
DdNode *Result, *TempComb, *Aux;
int c, v, Limit, *VarValues;
/* sanity check the parameters */
if ( n <= 0 || k <= 0 || d < 0.0 || d > 1.0 )
return NULL;
/* allocate temporary storage for variable values */
VarValues = ABC_ALLOC( int, n );
if (VarValues == NULL)
{
dd->errorCode = CUDD_MEMORY_OUT;
return NULL;
}
/* start the new set */
Result = dd->zero;
Cudd_Ref( Result );
/* seed random number generator */
Cudd_Srandom( time(NULL) );
// Cudd_Srandom( 4 );
/* determine the limit below which var belongs to the combination */
Limit = (int)(d * 2147483561.0);
/* add combinations one by one */
for ( c = 0; c < k; c++ )
{
for ( v = 0; v < n; v++ )
if ( Cudd_Random() <= Limit )
VarValues[v] = 1;
else
VarValues[v] = 0;
TempComb = Extra_zddCombination( dd, VarValues, n );
Cudd_Ref( TempComb );
/* make sure that this combination is not already in the set */
if ( c )
{ /* at least one combination is already included */
Aux = Cudd_zddDiff( dd, Result, TempComb );
Cudd_Ref( Aux );
if ( Aux != Result )
{
Cudd_RecursiveDerefZdd( dd, Aux );
Cudd_RecursiveDerefZdd( dd, TempComb );
c--;
continue;
}
else
{ /* Aux is the same node as Result */
Cudd_Deref( Aux );
}
}
Result = Cudd_zddUnion( dd, Aux = Result, TempComb );
Cudd_Ref( Result );
Cudd_RecursiveDerefZdd( dd, Aux );
Cudd_RecursiveDerefZdd( dd, TempComb );
}
ABC_FREE( VarValues );
Cudd_Deref( Result );
return Result;
} /* end of Extra_zddRandomSet */
/**Function********************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
******************************************************************************/
void Extra_ZddTest()
{
int N = 64;
int K0 = 1000;
int i, Size;
DdManager * dd = Cudd_Init( 0, 32, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
for ( i = 1; i <= 10; i++ )
{
int K = K0 * i;
DdNode * zRandSet = Extra_zddRandomSet( dd, N, K, 0.5 ); Cudd_Ref(zRandSet);
Size = Cudd_zddDagSize(zRandSet);
//Cudd_zddPrintMinterm( dd, zRandSet );
printf( "N = %5d K = %5d BddSize = %6d MemBdd = %8.3f MB MemBit = %8.3f MB Ratio = %8.3f %%\n",
N, K, Size, 20.0*Size/(1<<20), 0.125 * N * K /(1<<20), 100.0*(0.125 * N * K)/(20.0*Size) );
Cudd_RecursiveDerefZdd( dd, zRandSet );
}
Cudd_Quit(dd);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -902,7 +902,7 @@ void If_CluReverseOrder_old( word * pF, int nVars, int * V2P, int * P2V, int iVa
// return the number of cofactors w.r.t. the topmost vars (nBSsize)
int If_CluCountCofs( word * pF, int nVars, int nBSsize, int iShift, word pCofs[3][CLU_WRD_MAX/4] )
{
word iCofs[128], iCof, Result = 0;
word iCofs[128] = {0}, iCof, Result = 0;
word * pCofA, * pCofB;
int nMints = (1 << nBSsize);
int i, c, w, nCofs;

View File

@ -75,6 +75,7 @@ If_LibLut_t * If_LibLutRead( char * FileName )
Abc_Print( 1, "Error in the LUT library file \"%s\".\n", FileName );
ABC_FREE( p->pName );
ABC_FREE( p );
fclose( pFile );
return NULL;
}
@ -93,6 +94,7 @@ If_LibLut_t * If_LibLutRead( char * FileName )
ABC_FREE( p->pName );
ABC_FREE( p );
Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
fclose( pFile );
return NULL;
}
@ -105,6 +107,7 @@ If_LibLut_t * If_LibLutRead( char * FileName )
ABC_FREE( p->pName );
ABC_FREE( p );
Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i );
fclose( pFile );
return NULL;
}
i++;
@ -136,6 +139,7 @@ If_LibLut_t * If_LibLutRead( char * FileName )
}
}
fclose( pFile );
return p;
}

View File

@ -569,7 +569,7 @@ Mio_Cell_t * Mio_CollectRootsNew( Mio_Library_t * pLib, int nInputs, int * pnGat
if ( ppCells[3].pName == NULL )
{ printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; }
// sort by delay
if ( iCell > 1 )
if ( iCell > 5 )
{
qsort( (void *)(ppCells + 4), iCell - 4, sizeof(Mio_Cell_t),
(int (*)(const void *, const void *)) Mio_AreaCompare );
@ -726,7 +726,7 @@ Mio_Cell2_t * Mio_CollectRootsNew2( Mio_Library_t * pLib, int nInputs, int * pnG
if ( ppCells[3].pName == NULL )
{ printf( "Error: Cannot find inverter gate in the library.\n" ); return NULL; }
// sort by delay
if ( iCell > 1 )
if ( iCell > 5 )
{
qsort( (void *)(ppCells + 4), iCell - 4, sizeof(Mio_Cell2_t),
(int (*)(const void *, const void *)) Mio_AreaCompare2 );

View File

@ -259,7 +259,7 @@ usage:
fprintf( pAbc->Err, "\t-d : toggle dumping the parsed library into file \"*_temp.lib\" [default = %s]\n", fDump? "yes": "no" );
fprintf( pAbc->Err, "\t-n : toggle replacing gate/pin names by short strings [default = %s]\n", fShortNames? "yes": "no" );
fprintf( pAbc->Err, "\t-v : toggle writing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-v : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-w : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
fprintf( pAbc->Err, "\t<file> : the name of a file to read\n" );
return 1;

View File

@ -509,7 +509,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents )
{
FILE * pFile = fopen( pFileName, "rb" );
char * pContents = ABC_ALLOC( char, nContents+1 );
int RetValue;
int RetValue = 0;
RetValue = fread( pContents, nContents, 1, pFile );
fclose( pFile );
pContents[nContents] = 0;
@ -518,7 +518,7 @@ char * Scl_LibertyFileContents( char * pFileName, int nContents )
void Scl_LibertyStringDump( char * pFileName, Vec_Str_t * vStr )
{
FILE * pFile = fopen( pFileName, "wb" );
int RetValue;
int RetValue = 0;
if ( pFile == NULL )
{
printf( "Scl_LibertyStringDump(): The output file is unavailable.\n" );
@ -583,7 +583,7 @@ Scl_Tree_t * Scl_LibertyParse( char * pFileName, int fVerbose )
return NULL;
pPos = p->pContents;
Scl_LibertyWipeOutComments( p->pContents, p->pContents+p->nContents );
if ( !Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents ) == 0 )
if ( (!Scl_LibertyBuildItem( p, &pPos, p->pContents + p->nContents )) == 0 )
{
if ( p->pError ) printf( "%s", p->pError );
printf( "Parsing failed. " );
@ -765,10 +765,10 @@ Vec_Str_t * Scl_LibertyParseGenlibStr( char * pFileName, int fVerbose )
***********************************************************************/
//#define SCL_DEBUG
#ifdef SCL_DEBUG
static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); }
static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", Val ); Vec_StrPutW( vOut, Val ); }
static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); }
static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); }
static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { printf( "%d ", Val ); Vec_StrPutI( vOut, Val ); }
static inline void Vec_StrPutW_( Vec_Str_t * vOut, word Val ) { printf( "%lu ", (long)Val ); Vec_StrPutW( vOut, Val ); }
static inline void Vec_StrPutF_( Vec_Str_t * vOut, float Val ) { printf( "%f ", Val ); Vec_StrPutF( vOut, Val ); }
static inline void Vec_StrPutS_( Vec_Str_t * vOut, char * Val ) { printf( "%s ", Val ); Vec_StrPutS( vOut, Val ); }
static inline void Vec_StrPut_( Vec_Str_t * vOut ) { printf( "\n" ); }
#else
static inline void Vec_StrPutI_( Vec_Str_t * vOut, int Val ) { Vec_StrPutI( vOut, Val ); }

View File

@ -102,35 +102,45 @@ int Extra_UtilGetopt( int argc, char *argv[], const char *optstring )
globalUtilOptarg = NULL;
if (pScanStr == NULL || *pScanStr == '\0') {
if (globalUtilOptind == 0) globalUtilOptind++;
if (globalUtilOptind >= argc) return EOF;
place = argv[globalUtilOptind];
if (place[0] != '-' || place[1] == '\0') return EOF;
globalUtilOptind++;
if (place[1] == '-' && place[2] == '\0') return EOF;
pScanStr = place+1;
if (pScanStr == NULL || *pScanStr == '\0')
{
if (globalUtilOptind == 0)
globalUtilOptind++;
if (globalUtilOptind >= argc)
return EOF;
place = argv[globalUtilOptind];
if (place[0] != '-' || place[1] == '\0')
return EOF;
globalUtilOptind++;
if (place[1] == '-' && place[2] == '\0')
return EOF;
pScanStr = place+1;
}
c = *pScanStr++;
place = strchr(optstring, c);
if (place == NULL || c == ':') {
(void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
return '?';
}
if (*++place == ':') {
if (*pScanStr != '\0') {
globalUtilOptarg = pScanStr;
pScanStr = NULL;
} else {
if (globalUtilOptind >= argc) {
(void) fprintf(stderr, "%s: %c requires an argument\n",
argv[0], c);
(void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
return '?';
}
globalUtilOptarg = argv[globalUtilOptind];
globalUtilOptind++;
}
if (*++place == ':')
{
if (*pScanStr != '\0')
{
globalUtilOptarg = pScanStr;
pScanStr = NULL;
}
else
{
if (globalUtilOptind >= argc)
{
(void) fprintf(stderr, "%s: %c requires an argument\n",
argv[0], c);
return '?';
}
globalUtilOptarg = argv[globalUtilOptind];
globalUtilOptind++;
}
}
return c;
}

View File

@ -225,6 +225,8 @@ static inline double Abc_MinDouble( double a, double b ) { return a < b ?
static inline int Abc_Float2Int( float Val ) { union { int x; float y; } v; v.y = Val; return v.x; }
static inline float Abc_Int2Float( int Num ) { union { int x; float y; } v; v.x = Num; return v.y; }
static inline word Abc_Dbl2Word( double Dbl ) { union { word x; double y; } v; v.y = Dbl; return v.x; }
static inline double Abc_Word2Dbl( word Num ) { union { word x; double y; } v; v.x = Num; return v.y; }
static inline int Abc_Base2Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n >>= 1, r++ ) {}; return r; }
static inline int Abc_Base10Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 10, r++ ) {}; return r; }
static inline int Abc_Base16Log( unsigned n ) { int r; if ( n < 2 ) return n; for ( r = 0, n--; n; n /= 16, r++ ) {}; return r; }

View File

@ -272,9 +272,9 @@ void Abc_CexPrintStats( Abc_Cex_t * p )
p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits,
Counter, 100.0 * Counter / (p->nBits - p->nRegs) );
}
void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nInputs )
void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nRealPis )
{
int k, Counter = 0, Counter2 = 0;
int k, Counter = 0, CounterPi = 0, CounterPpi = 0;
if ( p == NULL )
{
printf( "The counter example is NULL.\n" );
@ -285,16 +285,27 @@ void Abc_CexPrintStatsInputs( Abc_Cex_t * p, int nInputs )
printf( "The counter example is present but not available (pointer has value \"1\").\n" );
return;
}
assert( nRealPis <= p->nPis );
for ( k = 0; k < p->nBits; k++ )
{
Counter += Abc_InfoHasBit(p->pData, k);
if ( (k - p->nRegs) % p->nPis < nInputs )
Counter2 += Abc_InfoHasBit(p->pData, k);
if ( nRealPis == p->nPis )
continue;
if ( (k - p->nRegs) % p->nPis < nRealPis )
CounterPi += Abc_InfoHasBit(p->pData, k);
else
CounterPpi += Abc_InfoHasBit(p->pData, k);
}
printf( "CEX: Po =%4d Frame =%4d FF = %d PI = %d Bit =%8d 1s =%8d (%5.2f %%) 1sIn =%8d (%5.2f %%)\n",
printf( "CEX: Po =%4d Fr =%4d FF = %d PI = %d Bit =%7d 1 =%8d (%5.2f %%)",
p->iPo, p->iFrame, p->nRegs, p->nPis, p->nBits,
Counter, 100.0 * Counter / (p->nBits - p->nRegs),
Counter2, 100.0 * Counter2 / (p->nBits - p->nRegs - (p->iFrame + 1) * (p->nPis - nInputs)) );
Counter, 100.0 * Counter / ((p->iFrame + 1) * p->nPis ) );
if ( nRealPis < p->nPis )
{
printf( " 1pi =%8d (%5.2f %%) 1ppi =%8d (%5.2f %%)",
CounterPi, 100.0 * CounterPi / ((p->iFrame + 1) * nRealPis ),
CounterPpi, 100.0 * CounterPpi / ((p->iFrame + 1) * (p->nPis - nRealPis)) );
}
printf( "\n" );
}
/**Function*************************************************************

222
src/misc/util/utilDouble.h Normal file
View File

@ -0,0 +1,222 @@
/**CFile****************************************************************
FileName [utilDouble.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName []
Synopsis [Double floating point number implementation.]
Author [Alan Mishchenko, Bruno Schmitt]
Affiliation [UC Berkeley / UFRGS]
Date [Ver. 1.0. Started - February 11, 2017.]
Revision []
***********************************************************************/
#ifndef ABC__sat__Xdbl__Xdbl_h
#define ABC__sat__Xdbl__Xdbl_h
#include "misc/util/abc_global.h"
ABC_NAMESPACE_HEADER_START
////////////////////////////////////////////////////////////////////////
/// STRUCTURE DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/*
The xdbl floating-point number is represented as a 64-bit unsigned int.
The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a
48-bit mantissa. The decimal point is located between the MSB of Mnt,
which is always 1, and the remaining 15 digits of Mnt.
Currently, only positive numbers are represented.
The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111]
that is, the smallest possible number is 1.0 and the largest possible
number is 2^(---16 ones---).(1.---47 ones---)
Comparison of numbers can be done by comparing the underlying unsigned ints.
Only addition, multiplication, and division by 2^n are currently implemented.
*/
typedef word xdbl;
static inline word Xdbl_Exp( xdbl a ) { return a >> 48; }
static inline word Xdbl_Mnt( xdbl a ) { return (a << 16) >> 16; }
static inline xdbl Xdbl_Create( word Exp, word Mnt ) { assert(!(Exp>>16) && (Mnt>>47)==(word)1); return (Exp<<48) | Mnt; }
static inline xdbl Xdbl_Const1() { return Xdbl_Create( (word)0, (word)1 << 47 ); }
static inline xdbl Xdbl_Const2() { return Xdbl_Create( (word)1, (word)1 << 47 ); }
static inline xdbl Xdbl_Const3() { return Xdbl_Create( (word)1, (word)3 << 46 ); }
static inline xdbl Xdbl_Const12() { return Xdbl_Create( (word)3, (word)3 << 46 ); }
static inline xdbl Xdbl_Const1point5() { return Xdbl_Create( (word)0, (word)3 << 46 ); }
static inline xdbl Xdbl_Const2point5() { return Xdbl_Create( (word)1, (word)5 << 45 ); }
static inline xdbl Xdbl_Maximum() { return ~(word)0; }
static inline double Xdbl_ToDouble( xdbl a ) { assert(Xdbl_Exp(a) < 1023); return Abc_Word2Dbl(((Xdbl_Exp(a) + 1023) << 52) | (((a<<17)>>17) << 5)); }
static inline xdbl Xdbl_FromDouble( double a ) { word A = Abc_Dbl2Word(a); assert(a >= 1.0); return Xdbl_Create((A >> 52)-1023, (((word)1) << 47) | ((A << 12) >> 17)); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Adding two floating-point numbers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline xdbl Xdbl_Add( xdbl a, xdbl b )
{
word Exp, Mnt;
if ( a < b ) a ^= b, b ^= a, a ^= b;
assert( a >= b );
Mnt = Xdbl_Mnt(a) + (Xdbl_Mnt(b) >> (Xdbl_Exp(a) - Xdbl_Exp(b)));
Exp = Xdbl_Exp(a);
if ( Mnt >> 48 ) // new MSB is created
Exp++, Mnt >>= 1;
if ( Exp >> 16 ) // overflow
return Xdbl_Maximum();
return Xdbl_Create( Exp, Mnt );
}
/**Function*************************************************************
Synopsis [Multiplying two floating-point numbers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline xdbl Xdbl_Mul( xdbl a, xdbl b )
{
word Exp, Mnt, MntA, MntB, MntAh, MntBh, MntAl, MntBl;
if ( a < b ) a ^= b, b ^= a, a ^= b;
assert( a >= b );
MntA = Xdbl_Mnt(a);
MntB = Xdbl_Mnt(b);
MntAh = MntA>>32;
MntBh = MntB>>32;
MntAl = (MntA<<32)>>32;
MntBl = (MntB<<32)>>32;
Mnt = ((MntAh * MntBh) << 17) + ((MntAl * MntBl) >> 47) + ((MntAl * MntBh) >> 15) + ((MntAh * MntBl) >> 15);
Exp = Xdbl_Exp(a) + Xdbl_Exp(b);
if ( Mnt >> 48 ) // new MSB is created
Exp++, Mnt >>= 1;
if ( Exp >> 16 ) // overflow
return Xdbl_Maximum();
return Xdbl_Create( Exp, Mnt );
}
/**Function*************************************************************
Synopsis [Dividing floating point number by a degree of 2.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline xdbl Xdbl_Div( xdbl a, unsigned Deg2 )
{
if ( Xdbl_Exp(a) >= (word)Deg2 )
return Xdbl_Create( Xdbl_Exp(a) - Deg2, Xdbl_Mnt(a) );
return Xdbl_Const1(); // underflow
}
/**Function*************************************************************
Synopsis [Testing procedure.]
Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Xdbl_Test()
{
xdbl c1 = Xdbl_Const1();
xdbl c2 = Xdbl_Const2();
xdbl c3 = Xdbl_Const3();
xdbl c12 = Xdbl_Const12();
xdbl c1p5 = Xdbl_Const1point5();
xdbl c2p5 = Xdbl_Const2point5();
xdbl c1_ = Xdbl_FromDouble(1.0);
xdbl c2_ = Xdbl_FromDouble(2.0);
xdbl c3_ = Xdbl_FromDouble(3.0);
xdbl c12_ = Xdbl_FromDouble(12.0);
xdbl c1p5_ = Xdbl_FromDouble(1.5);
xdbl c2p5_ = Xdbl_FromDouble(2.5);
xdbl sum1 = Xdbl_Add(c1, c1p5);
xdbl mul1 = Xdbl_Mul(c2, c1p5);
xdbl sum2 = Xdbl_Add(c1p5, c2p5);
xdbl mul2 = Xdbl_Mul(c1p5, c2p5);
xdbl a = Xdbl_FromDouble(1.2929725);
xdbl b = Xdbl_FromDouble(10.28828287);
xdbl ab = Xdbl_Mul(a, b);
xdbl ten100 = Xdbl_FromDouble( 1e100 );
xdbl ten100_ = ABC_CONST(0x014c924d692ca61b);
assert( ten100 == ten100_ );
// float f1 = Xdbl_ToDouble(c1);
// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" );
// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" );
printf( "1 = %lf\n", Xdbl_ToDouble(c1) );
printf( "2 = %lf\n", Xdbl_ToDouble(c2) );
printf( "3 = %lf\n", Xdbl_ToDouble(c3) );
printf( "12 = %lf\n", Xdbl_ToDouble(c12) );
printf( "1.5 = %lf\n", Xdbl_ToDouble(c1p5) );
printf( "2.5 = %lf\n", Xdbl_ToDouble(c2p5) );
printf( "Converted 1 = %lf\n", Xdbl_ToDouble(c1_) );
printf( "Converted 2 = %lf\n", Xdbl_ToDouble(c2_) );
printf( "Converted 3 = %lf\n", Xdbl_ToDouble(c3_) );
printf( "Converted 12 = %lf\n", Xdbl_ToDouble(c12_) );
printf( "Converted 1.5 = %lf\n", Xdbl_ToDouble(c1p5_) );
printf( "Converted 2.5 = %lf\n", Xdbl_ToDouble(c2p5_) );
printf( "1.0 + 1.5 = %lf\n", Xdbl_ToDouble(sum1) );
printf( "2.0 * 1.5 = %lf\n", Xdbl_ToDouble(mul1) );
printf( "1.5 + 2.5 = %lf\n", Xdbl_ToDouble(sum2) );
printf( "1.5 * 2.5 = %lf\n", Xdbl_ToDouble(mul2) );
printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) );
printf( "12 / 2^2 = %lf\n", Xdbl_ToDouble(Xdbl_Div(c12, 2)) );
printf( "%.16lf * %.16lf = %.16lf (%.16lf)\n", Xdbl_ToDouble(a), Xdbl_ToDouble(b), Xdbl_ToDouble(ab), 1.2929725 * 10.28828287 );
assert( sum1 == c2p5 );
assert( mul1 == c3 );
}
ABC_NAMESPACE_HEADER_END
#endif

226
src/misc/util/utilFloat.h Normal file
View File

@ -0,0 +1,226 @@
/**CFile****************************************************************
FileName [utilFloat.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName []
Synopsis [Floating point number implementation.]
Author [Alan Mishchenko, Bruno Schmitt]
Affiliation [UC Berkeley / UFRGS]
Date [Ver. 1.0. Started - January 28, 2017.]
Revision []
***********************************************************************/
#ifndef ABC__sat__xSAT__xsatFloat_h
#define ABC__sat__xSAT__xsatFloat_h
#include "misc/util/abc_global.h"
ABC_NAMESPACE_HEADER_START
////////////////////////////////////////////////////////////////////////
/// STRUCTURE DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/*
The xFloat_t floating-point number is represented as a 32-bit unsigned int.
The number is (2^Exp)*Mnt, where Exp is a 16-bit exponent and Mnt is a
16-bit mantissa. The decimal point is located between the MSB of Mnt,
which is always 1, and the remaining 15 digits of Mnt.
Currently, only positive numbers are represented.
The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111]
that is, the smallest possible number is 1.0 and the largest possible
number is 2^(---16 ones---).(1.---15 ones---)
Comparison of numbers can be done by comparing the underlying unsigned ints.
Only addition, multiplication, and division by 2^n are currently implemented.
*/
typedef struct xFloat_t_ xFloat_t;
struct xFloat_t_
{
unsigned Mnt : 16;
unsigned Exp : 16;
};
static inline unsigned xSat_Float2Uint( xFloat_t f ) { union { xFloat_t f; unsigned u; } temp; temp.f = f; return temp.u; }
static inline xFloat_t xSat_Uint2Float( unsigned u ) { union { xFloat_t f; unsigned u; } temp; temp.u = u; return temp.f; }
static inline int xSat_LessThan( xFloat_t a, xFloat_t b ) { return a.Exp < b.Exp || (a.Exp == b.Exp && a.Mnt < b.Mnt); }
static inline int xSat_Equal( xFloat_t a, xFloat_t b ) { return a.Exp == b.Exp && a.Mnt == b.Mnt; }
static inline xFloat_t xSat_FloatCreate( unsigned Exp, unsigned Mnt ) { xFloat_t res; res.Exp = Exp; res.Mnt = Mnt; return res; }
static inline xFloat_t xSat_FloatCreateConst1() { return xSat_FloatCreate( 0, 1 << 15 ); }
static inline xFloat_t xSat_FloatCreateConst2() { return xSat_FloatCreate( 1, 1 << 15 ); }
static inline xFloat_t xSat_FloatCreateConst3() { return xSat_FloatCreate( 1, 3 << 14 ); }
static inline xFloat_t xSat_FloatCreateConst12() { return xSat_FloatCreate( 3, 3 << 14 ); }
static inline xFloat_t xSat_FloatCreateConst1point5() { return xSat_FloatCreate( 0, 3 << 14 ); }
static inline xFloat_t xSat_FloatCreateConst2point5() { return xSat_FloatCreate( 1, 5 << 13 ); }
static inline xFloat_t xSat_FloatCreateMaximum() { return xSat_Uint2Float( 0xFFFFFFFF ); }
static inline float xSat_Float2Float( xFloat_t a ) { assert(a.Exp < 127); return Abc_Int2Float(((a.Exp + 127) << 23) | ((a.Mnt & 0x7FFF) << 8)); }
static inline xFloat_t xSat_FloatFromFloat( float a ) { int A = Abc_Float2Int(a); assert(a >= 1.0); return xSat_FloatCreate((A >> 23)-127, 0x8000 | ((A >> 8) & 0x7FFF)); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Adding two floating-point numbers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline xFloat_t xSat_FloatAdd( xFloat_t a, xFloat_t b )
{
unsigned Exp, Mnt;
if ( a.Exp < b.Exp )
return xSat_FloatAdd(b, a);
assert( a.Exp >= b.Exp );
// compute new mantissa
Mnt = a.Mnt + (b.Mnt >> (a.Exp - b.Exp));
// compute new exponent
Exp = a.Exp;
// update exponent and mantissa if new MSB is created
if ( Mnt & 0xFFFF0000 ) // new MSB bit is created
Exp++, Mnt >>= 1;
// check overflow
if ( Exp & 0xFFFF0000 ) // overflow
return xSat_Uint2Float( 0xFFFFFFFF );
assert( (Exp & 0xFFFF0000) == 0 );
assert( (Mnt & 0xFFFF0000) == 0 );
assert( Mnt & 0x00008000 );
return xSat_FloatCreate( Exp, Mnt );
}
/**Function*************************************************************
Synopsis [Multiplying two floating-point numbers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline xFloat_t xSat_FloatMul( xFloat_t a, xFloat_t b )
{
unsigned Exp, Mnt;
if ( a.Exp < b.Exp )
return xSat_FloatMul(b, a);
assert( a.Exp >= b.Exp );
// compute new mantissa
Mnt = (a.Mnt * b.Mnt) >> 15;
// compute new exponent
Exp = a.Exp + b.Exp;
// update exponent and mantissa if new MSB is created
if ( Mnt & 0xFFFF0000 ) // new MSB bit is created
Exp++, Mnt >>= 1;
// check overflow
if ( Exp & 0xFFFF0000 ) // overflow
return xSat_Uint2Float( 0xFFFFFFFF );
assert( (Exp & 0xFFFF0000) == 0 );
assert( (Mnt & 0xFFFF0000) == 0 );
assert( Mnt & 0x00008000 );
return xSat_FloatCreate( Exp, Mnt );
}
/**Function*************************************************************
Synopsis [Dividing floating point number by a degree of 2.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline xFloat_t xSat_FloatDiv( xFloat_t a, unsigned Deg2 )
{
assert( Deg2 < 0xFFFF );
if ( a.Exp >= Deg2 )
return xSat_FloatCreate( a.Exp - Deg2, a.Mnt );
return xSat_FloatCreateConst1(); // underflow
}
/**Function*************************************************************
Synopsis [Testing procedure.]
Description [Helpful link https://www.h-schmidt.net/FloatConverter/IEEE754.html]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void xSat_FloatTest()
{
xFloat_t c1 = xSat_FloatCreateConst1();
xFloat_t c2 = xSat_FloatCreateConst2();
xFloat_t c3 = xSat_FloatCreateConst3();
xFloat_t c12 = xSat_FloatCreateConst12();
xFloat_t c1p5 = xSat_FloatCreateConst1point5();
xFloat_t c2p5 = xSat_FloatCreateConst2point5();
xFloat_t c1_ = xSat_FloatFromFloat(1.0);
xFloat_t c2_ = xSat_FloatFromFloat(2.0);
xFloat_t c3_ = xSat_FloatFromFloat(3.0);
xFloat_t c12_ = xSat_FloatFromFloat(12.0);
xFloat_t c1p5_ = xSat_FloatFromFloat(1.5);
xFloat_t c2p5_ = xSat_FloatFromFloat(2.5);
xFloat_t sum1 = xSat_FloatAdd(c1, c1p5);
xFloat_t mul1 = xSat_FloatMul(c2, c1p5);
xFloat_t sum2 = xSat_FloatAdd(c1p5, c2p5);
xFloat_t mul2 = xSat_FloatMul(c1p5, c2p5);
// float f1 = xSat_Float2Float(c1);
// Extra_PrintBinary( stdout, (int *)&c1, 32 ); printf( "\n" );
// Extra_PrintBinary( stdout, (int *)&f1, 32 ); printf( "\n" );
printf( "1 = %f\n", xSat_Float2Float(c1) );
printf( "2 = %f\n", xSat_Float2Float(c2) );
printf( "3 = %f\n", xSat_Float2Float(c3) );
printf( "12 = %f\n", xSat_Float2Float(c12) );
printf( "1.5 = %f\n", xSat_Float2Float(c1p5) );
printf( "2.5 = %f\n", xSat_Float2Float(c2p5) );
printf( "Converted 1 = %f\n", xSat_Float2Float(c1_) );
printf( "Converted 2 = %f\n", xSat_Float2Float(c2_) );
printf( "Converted 3 = %f\n", xSat_Float2Float(c3_) );
printf( "Converted 12 = %f\n", xSat_Float2Float(c12_) );
printf( "Converted 1.5 = %f\n", xSat_Float2Float(c1p5_) );
printf( "Converted 2.5 = %f\n", xSat_Float2Float(c2p5_) );
printf( "1.0 + 1.5 = %f\n", xSat_Float2Float(sum1) );
printf( "2.0 * 1.5 = %f\n", xSat_Float2Float(mul1) );
printf( "1.5 + 2.5 = %f\n", xSat_Float2Float(sum2) );
printf( "1.5 * 2.5 = %f\n", xSat_Float2Float(mul2) );
printf( "12 / 2^2 = %f\n", xSat_Float2Float(xSat_FloatDiv(c12, 2)) );
assert( xSat_Equal(sum1, c2p5) );
assert( xSat_Equal(mul1, c3) );
}
ABC_NAMESPACE_HEADER_END
#endif

View File

@ -1631,6 +1631,14 @@ static inline int Abc_TtFindFirstBit( word * pIn, int nVars )
return 64*w + Abc_Tt6FirstBit(pIn[w]);
return -1;
}
static inline int Abc_TtFindFirstBit2( word * pIn, int nWords )
{
int w;
for ( w = 0; w < nWords; w++ )
if ( pIn[w] )
return 64*w + Abc_Tt6FirstBit(pIn[w]);
return -1;
}
static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars )
{
int w, nWords = Abc_TtWordNum(nVars);
@ -1639,6 +1647,14 @@ static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars )
return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]);
return -1;
}
static inline int Abc_TtFindFirstDiffBit2( word * pIn1, word * pIn2, int nWords )
{
int w;
for ( w = 0; w < nWords; w++ )
if ( pIn1[w] ^ pIn2[w] )
return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]);
return -1;
}
static inline int Abc_TtFindFirstZero( word * pIn, int nVars )
{
int w, nWords = Abc_TtWordNum(nVars);
@ -2612,7 +2628,7 @@ static inline int Abc_TtProcessBiDec( word * pTruth, int nVars, int nSuppLim )
static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLim )
{
word This, That, pTemp[64];
int Res, resThis, resThat, nThis, nThat;
int Res, resThis, resThat;//, nThis, nThat;
int nWords = Abc_TtWordNum(nVars);
Abc_TtCopy( pTemp, pTruth, nWords, 0 );
Res = Abc_TtProcessBiDec( pTemp, nVars, nSuppLim );
@ -2634,8 +2650,8 @@ static inline void Abc_TtProcessBiDecTest( word * pTruth, int nVars, int nSuppLi
// Dau_DsdPrintFromTruth( pTemp, nVars );
nThis = Abc_TtBitCount16(resThis);
nThat = Abc_TtBitCount16(resThat);
//nThis = Abc_TtBitCount16(resThis);
//nThat = Abc_TtBitCount16(resThat);
printf( "Variable sets: " );
Abc_TtPrintVarSet( resThis, nVars );

View File

@ -1692,6 +1692,24 @@ static inline int Vec_IntTwoFindCommon( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Ve
}
return Vec_IntSize(vArr);
}
static inline int Vec_IntTwoFindCommonReverse( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vArr )
{
int * pBeg1 = vArr1->pArray;
int * pBeg2 = vArr2->pArray;
int * pEnd1 = vArr1->pArray + vArr1->nSize;
int * pEnd2 = vArr2->pArray + vArr2->nSize;
Vec_IntClear( vArr );
while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
{
if ( *pBeg1 == *pBeg2 )
Vec_IntPush( vArr, *pBeg1 ), pBeg1++, pBeg2++;
else if ( *pBeg1 > *pBeg2 )
pBeg1++;
else
pBeg2++;
}
return Vec_IntSize(vArr);
}
/**Function*************************************************************

View File

@ -65,7 +65,7 @@ struct Vec_Ptr_t_
#define Vec_PtrForEachEntryTwo( Type1, vVec1, Type2, vVec2, pEntry1, pEntry2, i ) \
for ( i = 0; (i < Vec_PtrSize(vVec1)) && (((pEntry1) = (Type1)Vec_PtrEntry(vVec1, i)), 1) && (((pEntry2) = (Type2)Vec_PtrEntry(vVec2, i)), 1); i++ )
#define Vec_PtrForEachEntryDouble( Type1, Type2, vVec, Entry1, Entry2, i ) \
for ( i = 0; (i+1 < Vec_IntSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 )
for ( i = 0; (i+1 < Vec_PtrSize(vVec)) && (((Entry1) = (Type1)Vec_PtrEntry(vVec, i)), 1) && (((Entry2) = (Type2)Vec_PtrEntry(vVec, i+1)), 1); i += 2 )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///

View File

@ -303,6 +303,23 @@ static inline Vec_Int_t * Vec_WecPushLevel( Vec_Wec_t * p )
++p->nSize;
return Vec_WecEntryLast( p );
}
static inline Vec_Int_t * Vec_WecInsertLevel( Vec_Wec_t * p, int i )
{
Vec_Int_t * pTemp;
if ( p->nSize == p->nCap )
{
if ( p->nCap < 16 )
Vec_WecGrow( p, 16 );
else
Vec_WecGrow( p, 2 * p->nCap );
}
++p->nSize;
assert( i >= 0 && i < p->nSize );
for ( pTemp = p->pArray + p->nSize - 2; pTemp >= p->pArray + i; pTemp-- )
pTemp[1] = pTemp[0];
Vec_IntZero( p->pArray + i );
return p->pArray + i;
}
/**Function*************************************************************
@ -544,6 +561,18 @@ static inline void Vec_WecPrint( Vec_Wec_t * p, int fSkipSingles )
printf( " }\n" );
}
}
static inline void Vec_WecPrintLits( Vec_Wec_t * p )
{
Vec_Int_t * vVec;
int i, k, iLit;
Vec_WecForEachLevel( p, vVec, i )
{
printf( " %4d : %2d {", i, Vec_IntSize(vVec) );
Vec_IntForEachEntry( vVec, iLit, k )
printf( " %c%d", Abc_LitIsCompl(iLit) ? '-' : '+', Abc_Lit2Var(iLit) );
printf( " }\n" );
}
}
/**Function*************************************************************

View File

@ -1445,7 +1445,7 @@ long ZEXPORT inflateMark(z_streamp strm)
{
struct inflate_state FAR *state;
if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
if (strm == Z_NULL || strm->state == Z_NULL) return -(1L << 16);
state = (struct inflate_state FAR *)strm->state;
return ((long)(state->back) << 16) +
(state->mode == COPY ? state->length :

View File

@ -241,7 +241,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd )
if ( pGia->pHTable == NULL )
{
if ( fAnd )
iFan = Gia_ManAppendAnd( pGia, iFan0, iFan1 );
iFan = Gia_ManAppendAnd2( pGia, iFan0, iFan1 );
else if ( pGia->pMuxes )
{
int fCompl = Abc_LitIsCompl(iFan0) ^ Abc_LitIsCompl(iFan1);
@ -249,7 +249,7 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd )
iFan = Abc_LitNotCond( iFan, fCompl );
}
else
iFan = Gia_ManAppendXor( pGia, iFan0, iFan1 );
iFan = Gia_ManAppendXor2( pGia, iFan0, iFan1 );
}
else
{
@ -361,7 +361,7 @@ int Dau_DsdToGia_rec( Gia_Man_t * pGia, char * pStr, char ** p, int * pMatches,
if ( pGia->pMuxes )
Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] );
else
Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] );
Res = Gia_ManAppendMux2( pGia, Temp[0], Temp[1], Temp[2] );
}
else
{

View File

@ -51,14 +51,14 @@ struct Dsc_node_t_
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
inline void xorInPlace( word * pOut, word * pIn2, int nWords)
static inline void xorInPlace( word * pOut, word * pIn2, int nWords)
{
int w;
for ( w = 0; w < nWords; w++ )
pOut[w] ^= pIn2[w];
}
void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) {
static inline void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) {
int i;
printf("Node:\t%s\n",pNode->exp);
printf("\tneg cof:\t");Abc_TtPrintHexRev(stdout, pNode->pNegCof, nVars);
@ -75,7 +75,7 @@ void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) {
printf("\n");
}
inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) {
static inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) {
if (Abc_TtEqual(ni->pNegCof, nj->pNegCof, TRUTH_WORDS)) {*ci=1; *cj=1; return 1;}
else if (Abc_TtEqual(ni->pNegCof, nj->pPosCof, TRUTH_WORDS)) {*ci=1; *cj=0; return 1;}
else if (Abc_TtEqual(ni->pPosCof, nj->pNegCof, TRUTH_WORDS)) {*ci=0; *cj=1; return 1;}
@ -83,11 +83,11 @@ inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, i
return 0;
}
inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) {
static inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) {
return Abc_TtEqual(ni->pBoolDiff, nj->pBoolDiff, TRUTH_WORDS);
}
void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) {
static inline void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) {
*target++ = begin;
//s1
if (!s1Polarity)
@ -104,7 +104,7 @@ void concat(char* target, char begin, char end, char* s1, int s1Polarity, char*
*target = '\0';
}
void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) {
static inline void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) {
int size = cubeCof[0];
int i;
for (i = 1; i <= size; i++) {
@ -117,7 +117,7 @@ void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const
}
}
void merge(unsigned int * const pOut, const unsigned int * const pIn) {
static inline void merge(unsigned int * const pOut, const unsigned int * const pIn) {
const int elementsToCopy = pIn[0];
int i, j;
for (i = pOut[0]+1, j = 1; j <= elementsToCopy; i++, j++) {

View File

@ -96,12 +96,12 @@ void Lpk_IfManStart( Lpk_Man_t * p )
int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pTemp;
Abc_Obj_t * pTemp, * pTemp2;
int i;
vNodes = Vec_VecEntry( p->vVisited, iNode );
if ( Vec_PtrSize(vNodes) == 0 )
return 1;
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pTemp, i )
Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pTemp, pTemp2, i )
{
// check if the node has changed
pTemp = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pTemp );
@ -110,7 +110,7 @@ int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode )
// check if the number of fanouts has changed
// if ( Abc_ObjFanoutNum(pTemp) != (int)Vec_PtrEntry(vNodes, i+1) )
// return 1;
i++;
// i++;
}
return 0;
}

View File

@ -234,7 +234,7 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p )
{
Lpk_Cut_t * pCut;
Vec_Ptr_t * vNodes = Vec_VecEntry( p->vVisited, p->pObj->Id );
Abc_Obj_t * pNode;
Abc_Obj_t * pNode, * pNode2;
int i, k;
// collect the nodes that impact the given node
Vec_PtrClear( vNodes );
@ -252,11 +252,11 @@ void Lpk_NodeRecordImpact( Lpk_Man_t * p )
}
}
// clear the marks
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
Vec_PtrForEachEntryDouble( Abc_Obj_t *, Abc_Obj_t *, vNodes, pNode, pNode2, i )
{
pNode = Abc_NtkObj( p->pNtk, (int)(ABC_PTRUINT_T)pNode );
pNode->fMarkC = 0;
i++;
// i++;
}
//printf( "%d ", Vec_PtrSize(vNodes) );
}

View File

@ -1,5 +1,9 @@
SRC += src/opt/sbd/sbd.c \
src/opt/sbd/sbdCnf.c \
src/opt/sbd/sbdCore.c \
src/opt/sbd/sbdCut.c \
src/opt/sbd/sbdCut2.c \
src/opt/sbd/sbdLut.c \
src/opt/sbd/sbdPath.c \
src/opt/sbd/sbdSat.c \
src/opt/sbd/sbdWin.c

View File

@ -39,11 +39,18 @@ typedef struct Sbd_Par_t_ Sbd_Par_t;
struct Sbd_Par_t_
{
int nLutSize; // target LUT size
int nLutNum; // target LUT count
int nCutSize; // target cut size
int nCutNum; // target cut count
int nTfoLevels; // the number of TFO levels (windowing)
int nTfoFanMax; // the max number of fanouts (windowing)
int nWinSizeMax; // maximum window size (windowing)
int nBTLimit; // maximum number of SAT conflicts
int nWords; // simulation word count
int fMapping; // generate mapping
int fMoreCuts; // use several cuts
int fFindDivs; // perform divisor search
int fUsePath; // optimize only critical path
int fArea; // area-oriented optimization
int fCover; // use complete cover procedure
int fVerbose; // verbose flag

View File

@ -44,7 +44,7 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
void Sbd_PrintCnf( Vec_Str_t * vCnf )
{
char Entry;
signed char Entry;
int i, Lit;
Vec_StrForEachEntry( vCnf, Entry, i )
{
@ -121,7 +121,7 @@ int Sbd_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf
void Sbd_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar )
{
Vec_Int_t * vClause;
char Entry;
signed char Entry;
int i, Lit;
Vec_WecClear( vRes );
vClause = Vec_WecPushLevel( vRes );

File diff suppressed because it is too large Load Diff

872
src/opt/sbd/sbdCut.c Normal file
View File

@ -0,0 +1,872 @@
/**CFile****************************************************************
FileName [sbdCut.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT-based optimization using internal don't-cares.]
Synopsis [Cut computation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: sbdCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sbdInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define SBD_MAX_CUTSIZE 10
#define SBD_MAX_CUTNUM 501
#define SBD_MAX_TT_WORDS ((SBD_MAX_CUTSIZE > 6) ? 1 << (SBD_MAX_CUTSIZE-6) : 1)
#define SBD_CUT_NO_LEAF 0xF
typedef struct Sbd_Cut_t_ Sbd_Cut_t;
struct Sbd_Cut_t_
{
word Sign; // signature
int iFunc; // functionality
int Cost; // cut cost
int CostLev; // cut cost
unsigned nTreeLeaves : 9; // tree leaves
unsigned nSlowLeaves : 9; // slow leaves
unsigned nTopLeaves : 10; // top leaves
unsigned nLeaves : 4; // leaf count
int pLeaves[SBD_MAX_CUTSIZE]; // leaves
};
struct Sbd_Sto_t_
{
int nLutSize;
int nCutSize;
int nCutNum;
int fCutMin;
int fVerbose;
Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes)
Vec_Int_t * vMirrors; // mirrors for each node
Vec_Int_t * vDelays; // delays for each node
Vec_Int_t * vLevels; // levels for each node
Vec_Int_t * vRefs; // refs for each node
Vec_Wec_t * vCuts; // cuts for each node
Vec_Mem_t * vTtMem; // truth tables
Sbd_Cut_t pCuts[3][SBD_MAX_CUTNUM]; // temporary cuts
Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers
int nCutsR; // the number of cuts
int Pivot; // current object
int iCutBest; // best-delay cut
int nCutsSpec; // special cuts
int nCutsOver; // overflow cuts
int DelayMin; // minimum delay
double CutCount[4]; // cut counters
abctime clkStart; // starting time
};
static inline word * Sbd_CutTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut ) { return Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)); }
#define Sbd_ForEachCut( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 2 )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Check correctness of cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline word Sbd_CutGetSign( Sbd_Cut_t * pCut )
{
word Sign = 0; int i;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
Sign |= ((word)1) << (pCut->pLeaves[i] & 0x3F);
return Sign;
}
static inline int Sbd_CutCheck( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase
{
int nSizeB = pBase->nLeaves;
int nSizeC = pCut->nLeaves;
int i, * pB = pBase->pLeaves;
int k, * pC = pCut->pLeaves;
for ( i = 0; i < nSizeC; i++ )
{
for ( k = 0; k < nSizeB; k++ )
if ( pC[i] == pB[k] )
break;
if ( k == nSizeB )
return 0;
}
return 1;
}
static inline int Sbd_CutSetCheckArray( Sbd_Cut_t ** ppCuts, int nCuts )
{
Sbd_Cut_t * pCut0, * pCut1;
int i, k, m, n, Value;
assert( nCuts > 0 );
for ( i = 0; i < nCuts; i++ )
{
pCut0 = ppCuts[i];
assert( pCut0->nLeaves <= SBD_MAX_CUTSIZE );
assert( pCut0->Sign == Sbd_CutGetSign(pCut0) );
// check duplicates
for ( m = 0; m < (int)pCut0->nLeaves; m++ )
for ( n = m + 1; n < (int)pCut0->nLeaves; n++ )
assert( pCut0->pLeaves[m] < pCut0->pLeaves[n] );
// check pairs
for ( k = 0; k < nCuts; k++ )
{
pCut1 = ppCuts[k];
if ( pCut0 == pCut1 )
continue;
// check containments
Value = Sbd_CutCheck( pCut0, pCut1 );
assert( Value == 0 );
}
}
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Sbd_CutMergeOrder( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize )
{
int nSize0 = pCut0->nLeaves;
int nSize1 = pCut1->nLeaves;
int i, * pC0 = pCut0->pLeaves;
int k, * pC1 = pCut1->pLeaves;
int c, * pC = pCut->pLeaves;
// the case of the largest cut sizes
if ( nSize0 == nCutSize && nSize1 == nCutSize )
{
for ( i = 0; i < nSize0; i++ )
{
if ( pC0[i] != pC1[i] ) return 0;
pC[i] = pC0[i];
}
pCut->nLeaves = nCutSize;
pCut->iFunc = -1;
pCut->Sign = pCut0->Sign | pCut1->Sign;
return 1;
}
// compare two cuts with different numbers
i = k = c = 0;
if ( nSize0 == 0 ) goto FlushCut1;
if ( nSize1 == 0 ) goto FlushCut0;
while ( 1 )
{
if ( c == nCutSize ) return 0;
if ( pC0[i] < pC1[k] )
{
pC[c++] = pC0[i++];
if ( i >= nSize0 ) goto FlushCut1;
}
else if ( pC0[i] > pC1[k] )
{
pC[c++] = pC1[k++];
if ( k >= nSize1 ) goto FlushCut0;
}
else
{
pC[c++] = pC0[i++]; k++;
if ( i >= nSize0 ) goto FlushCut1;
if ( k >= nSize1 ) goto FlushCut0;
}
}
FlushCut0:
if ( c + nSize0 > nCutSize + i ) return 0;
while ( i < nSize0 )
pC[c++] = pC0[i++];
pCut->nLeaves = c;
pCut->iFunc = -1;
pCut->Sign = pCut0->Sign | pCut1->Sign;
return 1;
FlushCut1:
if ( c + nSize1 > nCutSize + k ) return 0;
while ( k < nSize1 )
pC[c++] = pC1[k++];
pCut->nLeaves = c;
pCut->iFunc = -1;
pCut->Sign = pCut0->Sign | pCut1->Sign;
return 1;
}
static inline int Sbd_CutMergeOrder2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, Sbd_Cut_t * pCut, int nCutSize )
{
int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves;
int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves;
int xMin, c = 0, * pC = pCut->pLeaves;
while ( 1 )
{
x0 = (i0 == nSize0) ? ABC_INFINITY : pC0[i0];
x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1];
xMin = Abc_MinInt(x0, x1);
if ( xMin == ABC_INFINITY ) break;
if ( c == nCutSize ) return 0;
pC[c++] = xMin;
if (x0 == xMin) i0++;
if (x1 == xMin) i1++;
}
pCut->nLeaves = c;
pCut->iFunc = -1;
pCut->Sign = pCut0->Sign | pCut1->Sign;
return 1;
}
static inline int Sbd_CutSetCutIsContainedOrder( Sbd_Cut_t * pBase, Sbd_Cut_t * pCut ) // check if pCut is contained in pBase
{
int i, nSizeB = pBase->nLeaves;
int k, nSizeC = pCut->nLeaves;
if ( nSizeB == nSizeC )
{
for ( i = 0; i < nSizeB; i++ )
if ( pBase->pLeaves[i] != pCut->pLeaves[i] )
return 0;
return 1;
}
assert( nSizeB > nSizeC );
if ( nSizeC == 0 )
return 1;
for ( i = k = 0; i < nSizeB; i++ )
{
if ( pBase->pLeaves[i] > pCut->pLeaves[k] )
return 0;
if ( pBase->pLeaves[i] == pCut->pLeaves[k] )
{
if ( ++k == nSizeC )
return 1;
}
}
return 0;
}
static inline int Sbd_CutSetLastCutIsContained( Sbd_Cut_t ** pCuts, int nCuts )
{
int i;
for ( i = 0; i < nCuts; i++ )
if ( pCuts[i]->nLeaves <= pCuts[nCuts]->nLeaves && (pCuts[i]->Sign & pCuts[nCuts]->Sign) == pCuts[i]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[nCuts], pCuts[i]) )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Sbd_CutCompare( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 )
{
if ( pCut0->nLeaves <= 4 && pCut1->nLeaves <= 4 )
{
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
if ( pCut0->Cost < pCut1->Cost ) return -1;
if ( pCut0->Cost > pCut1->Cost ) return 1;
if ( pCut0->CostLev < pCut1->CostLev ) return -1;
if ( pCut0->CostLev > pCut1->CostLev ) return 1;
}
else if ( pCut0->nLeaves <= 4 )
return -1;
else if ( pCut1->nLeaves <= 4 )
return 1;
else
{
if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1;
if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1;
if ( pCut0->Cost < pCut1->Cost ) return -1;
if ( pCut0->Cost > pCut1->Cost ) return 1;
if ( pCut0->CostLev < pCut1->CostLev ) return -1;
if ( pCut0->CostLev > pCut1->CostLev ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
}
return 0;
}
static inline int Sbd_CutCompare2( Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1 )
{
assert( pCut0->nLeaves > 4 && pCut1->nLeaves > 4 );
if ( pCut0->nSlowLeaves < pCut1->nSlowLeaves ) return -1;
if ( pCut0->nSlowLeaves > pCut1->nSlowLeaves ) return 1;
if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1;
if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1;
if ( pCut0->Cost < pCut1->Cost ) return -1;
if ( pCut0->Cost > pCut1->Cost ) return 1;
if ( pCut0->CostLev < pCut1->CostLev ) return -1;
if ( pCut0->CostLev > pCut1->CostLev ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
return 0;
}
static inline int Sbd_CutSetLastCutContains( Sbd_Cut_t ** pCuts, int nCuts )
{
int i, k, fChanges = 0;
for ( i = 0; i < nCuts; i++ )
if ( pCuts[nCuts]->nLeaves < pCuts[i]->nLeaves && (pCuts[nCuts]->Sign & pCuts[i]->Sign) == pCuts[nCuts]->Sign && Sbd_CutSetCutIsContainedOrder(pCuts[i], pCuts[nCuts]) )
pCuts[i]->nLeaves = SBD_CUT_NO_LEAF, fChanges = 1;
if ( !fChanges )
return nCuts;
for ( i = k = 0; i <= nCuts; i++ )
{
if ( pCuts[i]->nLeaves == SBD_CUT_NO_LEAF )
continue;
if ( k < i )
ABC_SWAP( Sbd_Cut_t *, pCuts[k], pCuts[i] );
k++;
}
return k - 1;
}
static inline void Sbd_CutSetSortByCost( Sbd_Cut_t ** pCuts, int nCuts )
{
int i;
for ( i = nCuts; i > 0; i-- )
{
if ( Sbd_CutCompare(pCuts[i - 1], pCuts[i]) < 0 )//!= 1 )
return;
ABC_SWAP( Sbd_Cut_t *, pCuts[i - 1], pCuts[i] );
}
}
static inline int Sbd_CutSetAddCut( Sbd_Cut_t ** pCuts, int nCuts, int nCutNum )
{
if ( nCuts == 0 )
return 1;
nCuts = Sbd_CutSetLastCutContains(pCuts, nCuts);
assert( nCuts >= 0 );
Sbd_CutSetSortByCost( pCuts, nCuts );
// add new cut if there is room
return Abc_MinInt( nCuts + 1, nCutNum - 1 );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Sbd_CutComputeTruth6( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor )
{
int nOldSupp = pCutR->nLeaves, truthId, fCompl; word t;
word t0 = *Sbd_CutTruth(p, pCut0);
word t1 = *Sbd_CutTruth(p, pCut1);
if ( Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ) t0 = ~t0;
if ( Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ) t1 = ~t1;
t0 = Abc_Tt6Expand( t0, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
t1 = Abc_Tt6Expand( t1, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
t = fIsXor ? t0 ^ t1 : t0 & t1;
if ( (fCompl = (int)(t & 1)) ) t = ~t;
pCutR->nLeaves = Abc_Tt6MinBase( &t, pCutR->pLeaves, pCutR->nLeaves );
assert( (int)(t & 1) == 0 );
truthId = Vec_MemHashInsert(p->vTtMem, &t);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
assert( (int)pCutR->nLeaves <= nOldSupp );
return (int)pCutR->nLeaves < nOldSupp;
}
static inline int Sbd_CutComputeTruth( Sbd_Sto_t * p, Sbd_Cut_t * pCut0, Sbd_Cut_t * pCut1, int fCompl0, int fCompl1, Sbd_Cut_t * pCutR, int fIsXor )
{
if ( p->nCutSize <= 6 )
return Sbd_CutComputeTruth6( p, pCut0, pCut1, fCompl0, fCompl1, pCutR, fIsXor );
{
word uTruth[SBD_MAX_TT_WORDS], uTruth0[SBD_MAX_TT_WORDS], uTruth1[SBD_MAX_TT_WORDS];
int nOldSupp = pCutR->nLeaves, truthId;
int nCutSize = p->nCutSize, fCompl;
int nWords = Abc_Truth6WordNum(nCutSize);
word * pTruth0 = Sbd_CutTruth(p, pCut0);
word * pTruth1 = Sbd_CutTruth(p, pCut1);
Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 );
Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 );
Abc_TtExpand( uTruth0, nCutSize, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
Abc_TtExpand( uTruth1, nCutSize, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
if ( fIsXor )
Abc_TtXor( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] ^ uTruth1[0]) & 1)) );
else
Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, (fCompl = (int)((uTruth0[0] & uTruth1[0]) & 1)) );
pCutR->nLeaves = Abc_TtMinBase( uTruth, pCutR->pLeaves, pCutR->nLeaves, nCutSize );
assert( (uTruth[0] & 1) == 0 );
//Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" );
truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
assert( (int)pCutR->nLeaves <= nOldSupp );
return (int)pCutR->nLeaves < nOldSupp;
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Sbd_CutCountBits( word i )
{
i = i - ((i >> 1) & 0x5555555555555555);
i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F);
return (i*(0x0101010101010101))>>56;
}
static inline int Sbd_CutCost( Sbd_Sto_t * p, Sbd_Cut_t * pCut )
{
int i, Cost = 0;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
Cost += Vec_IntEntry( p->vDelays, pCut->pLeaves[i] );
return Cost;
}
static inline int Sbd_CutCostLev( Sbd_Sto_t * p, Sbd_Cut_t * pCut )
{
int i, Cost = 0;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
Cost += Vec_IntEntry( p->vLevels, pCut->pLeaves[i] );
return Cost;
}
static inline int Sbd_CutTreeLeaves( Sbd_Sto_t * p, Sbd_Cut_t * pCut )
{
int i, Cost = 0;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1;
return Cost;
}
static inline int Sbd_CutSlowLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut )
{
int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj);
for ( i = 0; i < (int)pCut->nLeaves; i++ )
Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay >= -1);
return Count;
}
static inline int Sbd_CutTopLeaves( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut )
{
int i, Count = 0, Delay = Vec_IntEntry(p->vDelays, iObj);
for ( i = 0; i < (int)pCut->nLeaves; i++ )
Count += (Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay == -2);
return Count;
}
static inline void Sbd_CutAddUnit( Sbd_Sto_t * p, int iObj )
{
Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj );
if ( Vec_IntSize(vThis) == 0 )
Vec_IntPush( vThis, 1 );
else
Vec_IntAddToEntry( vThis, 0, 1 );
Vec_IntPush( vThis, 1 );
Vec_IntPush( vThis, iObj );
Vec_IntPush( vThis, 2 );
}
static inline void Sbd_CutAddZero( Sbd_Sto_t * p, int iObj )
{
Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj );
assert( Vec_IntSize(vThis) == 0 );
Vec_IntPush( vThis, 1 );
Vec_IntPush( vThis, 0 );
Vec_IntPush( vThis, 0 );
}
static inline int Sbd_StoPrepareSet( Sbd_Sto_t * p, int iObj, int Index )
{
Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj );
int i, v, * pCut, * pList = Vec_IntArray( vThis );
Sbd_ForEachCut( pList, pCut, i )
{
Sbd_Cut_t * pCutTemp = &p->pCuts[Index][i];
pCutTemp->nLeaves = pCut[0];
for ( v = 1; v <= pCut[0]; v++ )
pCutTemp->pLeaves[v-1] = pCut[v];
pCutTemp->iFunc = pCut[pCut[0]+1];
pCutTemp->Sign = Sbd_CutGetSign( pCutTemp );
pCutTemp->Cost = Sbd_CutCost( p, pCutTemp );
pCutTemp->CostLev = Sbd_CutCostLev( p, pCutTemp );
pCutTemp->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutTemp );
pCutTemp->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCutTemp );
pCutTemp->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCutTemp );
}
return pList[0];
}
static inline void Sbd_StoInitResult( Sbd_Sto_t * p )
{
int i;
for ( i = 0; i < SBD_MAX_CUTNUM; i++ )
p->ppCuts[i] = &p->pCuts[2][i];
}
static inline void Sbd_StoStoreResult( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts )
{
int i, v;
Vec_Int_t * vList = Vec_WecEntry( p->vCuts, iObj );
Vec_IntPush( vList, nCuts );
for ( i = 0; i < nCuts; i++ )
{
Vec_IntPush( vList, pCuts[i]->nLeaves );
for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ )
Vec_IntPush( vList, pCuts[i]->pLeaves[v] );
Vec_IntPush( vList, pCuts[i]->iFunc );
}
}
static inline void Sbd_StoComputeDelay( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts )
{
int i, v, Delay, DelayMin = ABC_INFINITY;
assert( nCuts > 0 );
p->iCutBest = -1;
for ( i = 0; i < nCuts; i++ )
{
if ( (int)pCuts[i]->nLeaves > p->nLutSize )
continue;
Delay = 0;
for ( v = 0; v < (int)pCuts[i]->nLeaves; v++ )
Delay = Abc_MaxInt( Delay, Vec_IntEntry(p->vDelays, pCuts[i]->pLeaves[v]) );
//DelayMin = Abc_MinInt( DelayMin, Delay );
if ( DelayMin > Delay )
{
DelayMin = Delay;
p->iCutBest = i;
}
else if ( DelayMin == Delay && p->iCutBest >= 0 && pCuts[p->iCutBest]->nLeaves > pCuts[i]->nLeaves )
p->iCutBest = i;
}
assert( p->iCutBest >= 0 );
assert( DelayMin < ABC_INFINITY );
DelayMin = (nCuts > 1 || pCuts[0]->nLeaves > 1) ? DelayMin + 1 : DelayMin;
Vec_IntWriteEntry( p->vDelays, iObj, DelayMin );
p->DelayMin = Abc_MaxInt( p->DelayMin, DelayMin );
}
static inline void Sbd_StoComputeSpec( Sbd_Sto_t * p, int iObj, Sbd_Cut_t ** pCuts, int nCuts )
{
int i;
for ( i = 0; i < nCuts; i++ )
{
pCuts[i]->nTopLeaves = Sbd_CutTopLeaves( p, iObj, pCuts[i] );
pCuts[i]->nSlowLeaves = Sbd_CutSlowLeaves( p, iObj, pCuts[i] );
p->nCutsSpec += (pCuts[i]->nSlowLeaves == 0);
}
}
static inline void Sbd_CutPrint( Sbd_Sto_t * p, int iObj, Sbd_Cut_t * pCut )
{
int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia));
int Delay = Vec_IntEntry(p->vDelays, iObj);
if ( pCut == NULL ) { printf( "No cut.\n" ); return; }
printf( "%d {", pCut->nLeaves );
for ( i = 0; i < (int)pCut->nLeaves; i++ )
printf( " %*d", nDigits, pCut->pLeaves[i] );
for ( ; i < (int)p->nCutSize; i++ )
printf( " %*s", nDigits, " " );
printf( " } Cost = %3d CostL = %3d Tree = %d Slow = %d Top = %d ",
pCut->Cost, pCut->CostLev, pCut->nTreeLeaves, pCut->nSlowLeaves, pCut->nTopLeaves );
printf( "%c ", pCut->nSlowLeaves == 0 ? '*' : ' ' );
for ( i = 0; i < (int)pCut->nLeaves; i++ )
printf( "%3d ", Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) - Delay );
printf( "\n" );
}
void Sbd_StoMergeCuts( Sbd_Sto_t * p, int iObj )
{
Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj);
int fIsXor = Gia_ObjIsXor(pObj);
int nCutSize = p->nCutSize;
int nCutNum = p->nCutNum;
int Lit0m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) ) : -1;
int Lit1m = p->vMirrors ? Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) ) : -1;
int fComp0 = Gia_ObjFaninC0(pObj) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
int fComp1 = Gia_ObjFaninC1(pObj) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
int nCuts0 = Sbd_StoPrepareSet( p, Fan0, 0 );
int nCuts1 = Sbd_StoPrepareSet( p, Fan1, 1 );
int i, k, nCutsR = 0;
Sbd_Cut_t * pCut0, * pCut1, ** pCutsR = p->ppCuts;
assert( !Gia_ObjIsBuf(pObj) );
assert( !Gia_ObjIsMux(p->pGia, pObj) );
Sbd_StoInitResult( p );
p->CutCount[0] += nCuts0 * nCuts1;
for ( i = 0, pCut0 = p->pCuts[0]; i < nCuts0; i++, pCut0++ )
for ( k = 0, pCut1 = p->pCuts[1]; k < nCuts1; k++, pCut1++ )
{
if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nCutSize && Sbd_CutCountBits(pCut0->Sign | pCut1->Sign) > nCutSize )
continue;
p->CutCount[1]++;
if ( !Sbd_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nCutSize) )
continue;
if ( Sbd_CutSetLastCutIsContained(pCutsR, nCutsR) )
continue;
p->CutCount[2]++;
if ( p->fCutMin && Sbd_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) )
pCutsR[nCutsR]->Sign = Sbd_CutGetSign(pCutsR[nCutsR]);
pCutsR[nCutsR]->Cost = Sbd_CutCost( p, pCutsR[nCutsR] );
pCutsR[nCutsR]->CostLev = Sbd_CutCostLev( p, pCutsR[nCutsR] );
pCutsR[nCutsR]->nTreeLeaves = Sbd_CutTreeLeaves( p, pCutsR[nCutsR] );
nCutsR = Sbd_CutSetAddCut( pCutsR, nCutsR, nCutNum );
}
Sbd_StoComputeDelay( p, iObj, pCutsR, nCutsR );
Sbd_StoComputeSpec( p, iObj, pCutsR, nCutsR );
p->CutCount[3] += nCutsR;
p->nCutsOver += nCutsR == nCutNum-1;
p->nCutsR = nCutsR;
p->Pivot = iObj;
// debug printout
if ( 0 )
{
printf( "*** Obj = %4d Delay = %4d NumCuts = %4d\n", iObj, Vec_IntEntry(p->vDelays, iObj), nCutsR );
for ( i = 0; i < nCutsR; i++ )
if ( (int)pCutsR[i]->nLeaves <= p->nLutSize || pCutsR[i]->nSlowLeaves < 2 )
Sbd_CutPrint( p, iObj, pCutsR[i] );
printf( "\n" );
}
// verify
assert( nCutsR > 0 && nCutsR < nCutNum );
assert( Sbd_CutSetCheckArray(pCutsR, nCutsR) );
// store the cutset
Sbd_StoStoreResult( p, iObj, pCutsR, nCutsR );
if ( nCutsR > 1 || pCutsR[0]->nLeaves > 1 )
Sbd_CutAddUnit( p, iObj );
}
/**Function*************************************************************
Synopsis [Incremental cut computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose )
{
Sbd_Sto_t * p;
assert( nLutSize <= nCutSize );
assert( nCutSize < SBD_CUT_NO_LEAF );
assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE );
assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM );
p = ABC_CALLOC( Sbd_Sto_t, 1 );
p->clkStart = Abc_Clock();
p->nLutSize = nLutSize;
p->nCutSize = nCutSize;
p->nCutNum = nCutNum;
p->fCutMin = fCutMin;
p->fVerbose = fVerbose;
p->pGia = pGia;
p->vMirrors = vMirrors;
p->vDelays = Vec_IntStart( Gia_ManObjNum(pGia) );
p->vLevels = Vec_IntStart( Gia_ManObjNum(pGia) );
p->vRefs = Vec_IntAlloc( Gia_ManObjNum(pGia) );
p->vCuts = Vec_WecStart( Gia_ManObjNum(pGia) );
p->vTtMem = fCutMin ? Vec_MemAllocForTT( nCutSize, 0 ) : NULL;
return p;
}
void Sbd_StoFree( Sbd_Sto_t * p )
{
Vec_IntFree( p->vDelays );
Vec_IntFree( p->vLevels );
Vec_IntFree( p->vRefs );
Vec_WecFree( p->vCuts );
if ( p->fCutMin )
Vec_MemHashFree( p->vTtMem );
if ( p->fCutMin )
Vec_MemFree( p->vTtMem );
ABC_FREE( p );
}
void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level )
{
if ( iObj < Vec_IntSize(p->vDelays) )
{
Vec_IntWriteEntry( p->vDelays, iObj, Delay );
Vec_IntWriteEntry( p->vLevels, iObj, Level );
}
else
{
assert( iObj == Vec_IntSize(p->vDelays) );
assert( iObj == Vec_IntSize(p->vLevels) );
assert( iObj == Vec_WecSize(p->vCuts) );
Vec_IntPush( p->vDelays, Delay );
Vec_IntPush( p->vLevels, Level );
Vec_WecPushLevel( p->vCuts );
}
}
void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj )
{
Sbd_StoComputeCutsObj( p, iObj, 0, 0 );
Sbd_CutAddZero( p, iObj );
}
void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level )
{
Sbd_StoComputeCutsObj( p, iObj, Delay, Level );
Sbd_CutAddUnit( p, iObj );
}
int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj )
{
Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj);
int Lev0 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId0(pObj, iObj) );
int Lev1 = Vec_IntEntry( p->vLevels, Gia_ObjFaninId1(pObj, iObj) );
Sbd_StoComputeCutsObj( p, iObj, -1, 1 + Abc_MaxInt(Lev0, Lev1) );
Sbd_StoMergeCuts( p, iObj );
return Vec_IntEntry( p->vDelays, iObj );
}
void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut )
{
Sbd_Cut_t * pCutBest = p->ppCuts[p->iCutBest]; int i;
assert( iObj == p->Pivot );
pCut[0] = pCutBest->nLeaves;
for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
pCut[i+1] = pCutBest->pLeaves[i];
}
int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj )
{
return Vec_IntEntry(p->vRefs, iObj);
}
void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror )
{
Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj);
assert( iObj == Vec_IntSize(p->vRefs) );
assert( iMirror < iObj );
Vec_IntPush( p->vRefs, 0 );
//printf( "Ref %d\n", iObj );
if ( iMirror > 0 )
{
Vec_IntWriteEntry( p->vRefs, iObj, Vec_IntEntry(p->vRefs, iMirror) );
Vec_IntWriteEntry( p->vRefs, iMirror, 1 );
}
if ( Gia_ObjIsAnd(pObj) )
{
int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) );
int Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) );
int Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
int Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
Vec_IntAddToEntry( p->vRefs, Fan0, 1 );
Vec_IntAddToEntry( p->vRefs, Fan1, 1 );
}
else if ( Gia_ObjIsCo(pObj) )
{
int Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) );
assert( Lit0m == -1 );
Vec_IntAddToEntry( p->vRefs, Gia_ObjFaninId0(pObj, iObj), 1 );
}
}
void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj )
{
Gia_Obj_t * pObj;
int Lit0m, Lit1m, Fan0, Fan1;
return;
pObj = Gia_ManObj(p->pGia, iObj);
if ( Vec_IntEntry(p->vRefs, iObj) == 0 )
printf( "Ref count mismatch at node %d\n", iObj );
assert( Vec_IntEntry(p->vRefs, iObj) > 0 );
Vec_IntAddToEntry( p->vRefs, iObj, -1 );
if ( Vec_IntEntry( p->vRefs, iObj ) > 0 )
return;
if ( Gia_ObjIsCi(pObj) )
return;
//printf( "Deref %d\n", iObj );
assert( Gia_ObjIsAnd(pObj) );
Lit0m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId0(pObj, iObj) );
Lit1m = Vec_IntEntry( p->vMirrors, Gia_ObjFaninId1(pObj, iObj) );
Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
if ( Fan0 ) Sbd_StoDerefObj( p, Fan0 );
if ( Fan1 ) Sbd_StoDerefObj( p, Fan1 );
}
int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves )
{
int fVerbose = 0;
Sbd_Cut_t * pCutBest = NULL; int i;
assert( p->Pivot == iObj );
if ( fVerbose && iObj % 1000 == 0 )
printf( "Node %6d : \n", iObj );
for ( i = 0; i < p->nCutsR; i++ )
{
if ( fVerbose && iObj % 1000 == 0 )
Sbd_CutPrint( p, iObj, p->ppCuts[i] );
if ( nSize && (int)p->ppCuts[i]->nLeaves != nSize )
continue;
if ( (int)p->ppCuts[i]->nLeaves > p->nLutSize &&
(int)p->ppCuts[i]->nSlowLeaves <= 1 &&
(int)p->ppCuts[i]->nTopLeaves <= p->nLutSize-1 &&
(pCutBest == NULL || Sbd_CutCompare2(pCutBest, p->ppCuts[i]) == 1) )
pCutBest = p->ppCuts[i];
}
if ( fVerbose && iObj % 1000 == 0 )
{
printf( "Best cut of size %d:\n", nSize );
Sbd_CutPrint( p, iObj, pCutBest );
}
if ( pCutBest == NULL )
return -1;
assert( pCutBest->nLeaves <= SBD_DIV_MAX );
for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
pLeaves[i] = pCutBest->pLeaves[i];
return pCutBest->nLeaves;
}
void Sbd_StoComputeCutsTest( Gia_Man_t * pGia )
{
Sbd_Sto_t * p = Sbd_StoAlloc( pGia, NULL, 4, 8, 100, 1, 1 );
Gia_Obj_t * pObj;
int i, iObj;
// prepare references
Gia_ManForEachObj( p->pGia, pObj, iObj )
Sbd_StoRefObj( p, iObj, -1 );
// compute cuts
Sbd_StoComputeCutsConst0( p, 0 );
Gia_ManForEachCiId( p->pGia, iObj, i )
Sbd_StoComputeCutsCi( p, iObj, 0, 0 );
Gia_ManForEachAnd( p->pGia, pObj, iObj )
Sbd_StoComputeCutsNode( p, iObj );
if ( p->fVerbose )
{
printf( "Running cut computation with LutSize = %d CutSize = %d CutNum = %d:\n", p->nLutSize, p->nCutSize, p->nCutNum );
printf( "CutPair = %.0f ", p->CutCount[0] );
printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] );
printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] );
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
printf( "\n" );
printf( "Spec = %4d ", p->nCutsSpec );
printf( "Over = %4d ", p->nCutsOver );
printf( "Lev = %4d ", p->DelayMin );
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
}
Sbd_StoFree( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

431
src/opt/sbd/sbdCut2.c Normal file
View File

@ -0,0 +1,431 @@
/**CFile****************************************************************
FileName [sbdCut2.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT-based optimization using internal don't-cares.]
Synopsis [Cut computation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: sbdCut2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sbdInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define SBD_MAX_CUTSIZE 10
#define SBD_MAX_CUTNUM 501
#define SBD_CUT_NO_LEAF 0xF
typedef struct Sbd_Cut_t_ Sbd_Cut_t;
struct Sbd_Cut_t_
{
word Sign; // signature
int iFunc; // functionality
int Cost; // cut cost
int CostLev; // cut cost
unsigned nTreeLeaves : 9; // tree leaves
unsigned nSlowLeaves : 9; // slow leaves
unsigned nTopLeaves : 10; // top leaves
unsigned nLeaves : 4; // leaf count
int pLeaves[SBD_MAX_CUTSIZE]; // leaves
};
struct Sbd_Srv_t_
{
int nLutSize;
int nCutSize;
int nCutNum;
int fVerbose;
Gia_Man_t * pGia; // user's AIG manager (will be modified by adding nodes)
Vec_Int_t * vMirrors; // mirrors for each node
Vec_Int_t * vLutLevs; // delays for each node
Vec_Int_t * vLevs; // levels for each node
Vec_Int_t * vRefs; // refs for each node
Sbd_Cut_t pCuts[SBD_MAX_CUTNUM]; // temporary cuts
Sbd_Cut_t * ppCuts[SBD_MAX_CUTNUM]; // temporary cut pointers
abctime clkStart; // starting time
Vec_Int_t * vCut0; // current cut
Vec_Int_t * vCut; // current cut
Vec_Int_t * vCutTop; // current cut
Vec_Int_t * vCutBot; // current cut
};
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors,
Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs,
int nLutSize, int nCutSize, int nCutNum, int fVerbose )
{
Sbd_Srv_t * p;
assert( nLutSize <= nCutSize );
assert( nCutSize < SBD_CUT_NO_LEAF );
assert( nCutSize > 1 && nCutSize <= SBD_MAX_CUTSIZE );
assert( nCutNum > 1 && nCutNum < SBD_MAX_CUTNUM );
p = ABC_CALLOC( Sbd_Srv_t, 1 );
p->clkStart = Abc_Clock();
p->nLutSize = nLutSize;
p->nCutSize = nCutSize;
p->nCutNum = nCutNum;
p->fVerbose = fVerbose;
p->pGia = pGia;
p->vMirrors = vMirrors;
p->vLutLevs = vLutLevs;
p->vLevs = vLevs;
p->vRefs = vRefs;
p->vCut0 = Vec_IntAlloc( 100 );
p->vCut = Vec_IntAlloc( 100 );
p->vCutTop = Vec_IntAlloc( 100 );
p->vCutBot = Vec_IntAlloc( 100 );
return p;
}
void Sbd_ManCutServerStop( Sbd_Srv_t * p )
{
Vec_IntFree( p->vCut0 );
Vec_IntFree( p->vCut );
Vec_IntFree( p->vCutTop );
Vec_IntFree( p->vCutBot );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sbd_ManCutIsTopo_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj )
{
Gia_Obj_t * pObj;
int Ret0, Ret1;
if ( Vec_IntEntry(vMirrors, iObj) >= 0 )
iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj));
if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
return 1;
Gia_ObjSetTravIdCurrentId(p, iObj);
pObj = Gia_ManObj( p, iObj );
if ( Gia_ObjIsCi(pObj) )
return 0;
assert( Gia_ObjIsAnd(pObj) );
Ret0 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj) );
Ret1 = Sbd_ManCutIsTopo_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj) );
return Ret0 && Ret1;
}
int Sbd_ManCutIsTopo( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vCut, int iObj )
{
int i, Entry, RetValue;
Gia_ManIncrementTravId( p );
Vec_IntForEachEntry( vCut, Entry, i )
Gia_ObjSetTravIdCurrentId( p, Entry );
RetValue = Sbd_ManCutIsTopo_rec( p, vMirrors, iObj );
if ( RetValue == 0 )
printf( "Cut of node %d is not tological\n", iObj );
assert( RetValue );
return RetValue;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Sbd_ManCutExpandOne( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, int iThis, int iObj )
{
int Lit0m, Lit1m, Fan0, Fan1, iPlace0, iPlace1;
int LutLev = Vec_IntEntry( vLutLevs, iObj );
Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
if ( Gia_ObjIsCi(pObj) )
return 0;
assert( Gia_ObjIsAnd(pObj) );
Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) );
Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) );
Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
iPlace0 = Vec_IntFind( vCut, Fan0 );
iPlace1 = Vec_IntFind( vCut, Fan1 );
if ( iPlace0 == -1 && iPlace1 == -1 )
return 0;
if ( Vec_IntEntry(vLutLevs, Fan0) > LutLev || Vec_IntEntry(vLutLevs, Fan1) > LutLev )
return 0;
Vec_IntDrop( vCut, iThis );
if ( iPlace0 == -1 && Fan0 )
Vec_IntPushOrder( vCut, Fan0 );
if ( iPlace1 == -1 && Fan1 )
Vec_IntPushOrder( vCut, Fan1 );
return 1;
}
void Vec_IntIsOrdered( Vec_Int_t * vCut )
{
int i, Prev, Entry;
Prev = Vec_IntEntry( vCut, 0 );
Vec_IntForEachEntryStart( vCut, Entry, i, 1 )
{
assert( Prev < Entry );
Prev = Entry;
}
}
void Sbd_ManCutExpand( Gia_Man_t * p, Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, Vec_Int_t * vCut )
{
int i, Entry;
do
{
Vec_IntForEachEntry( vCut, Entry, i )
if ( Sbd_ManCutExpandOne( p, vMirrors, vLutLevs, vCut, i, Entry ) )
break;
}
while ( i < Vec_IntSize(vCut) );
}
void Sbd_ManCutReload( Vec_Int_t * vMirrors, Vec_Int_t * vLutLevs, int LevStop, Vec_Int_t * vCut, Vec_Int_t * vCutTop, Vec_Int_t * vCutBot )
{
int i, Entry;
Vec_IntClear( vCutTop );
Vec_IntClear( vCutBot );
Vec_IntForEachEntry( vCut, Entry, i )
{
assert( Entry );
assert( Vec_IntEntry(vMirrors, Entry) == -1 );
assert( Vec_IntEntry(vLutLevs, Entry) <= LevStop );
if ( Vec_IntEntry(vLutLevs, Entry) == LevStop )
Vec_IntPush( vCutTop, Entry );
else
Vec_IntPush( vCutBot, Entry );
}
Vec_IntIsOrdered( vCut );
}
int Sbd_ManCutCollect_rec( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, int LevStop, Vec_Int_t * vLutLevs, Vec_Int_t * vCut )
{
Gia_Obj_t * pObj;
int Ret0, Ret1;
if ( Vec_IntEntry(vMirrors, iObj) >= 0 )
iObj = Abc_Lit2Var(Vec_IntEntry(vMirrors, iObj));
if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
return 1;
Gia_ObjSetTravIdCurrentId(p, iObj);
pObj = Gia_ManObj( p, iObj );
if ( Gia_ObjIsCi(pObj) || Vec_IntEntry(vLutLevs, iObj) <= LevStop )
{
Vec_IntPush( vCut, iObj );
return Vec_IntEntry(vLutLevs, iObj) <= LevStop;
}
assert( Gia_ObjIsAnd(pObj) );
Ret0 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId0(pObj, iObj), LevStop, vLutLevs, vCut );
Ret1 = Sbd_ManCutCollect_rec( p, vMirrors, Gia_ObjFaninId1(pObj, iObj), LevStop, vLutLevs, vCut );
return Ret0 && Ret1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sbd_ManCutReduceTop( Gia_Man_t * p, Vec_Int_t * vMirrors, int iObj, Vec_Int_t * vLutLevs, Vec_Int_t * vCut, Vec_Int_t * vCutTop, int nCutSize )
{
int i, Entry, Lit0m, Lit1m, Fan0, Fan1;
int LevStop = Vec_IntEntry(vLutLevs, iObj) - 2;
Vec_IntIsOrdered( vCut );
Vec_IntForEachEntryReverse( vCutTop, Entry, i )
{
Gia_Obj_t * pObj = Gia_ManObj( p, Entry );
if ( Gia_ObjIsCi(pObj) )
continue;
assert( Gia_ObjIsAnd(pObj) );
assert( Vec_IntEntry(vLutLevs, Entry) == LevStop );
Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, Entry) );
Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, Entry) );
Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, Entry);
Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, Entry);
if ( Vec_IntEntry(vLutLevs, Fan0) > LevStop || Vec_IntEntry(vLutLevs, Fan1) > LevStop )
continue;
assert( Vec_IntEntry(vLutLevs, Fan0) <= LevStop );
assert( Vec_IntEntry(vLutLevs, Fan1) <= LevStop );
if ( Vec_IntEntry(vLutLevs, Fan0) == LevStop && Vec_IntEntry(vLutLevs, Fan1) == LevStop )
continue;
Vec_IntRemove( vCut, Entry );
if ( Fan0 ) Vec_IntPushUniqueOrder( vCut, Fan0 );
if ( Fan1 ) Vec_IntPushUniqueOrder( vCut, Fan1 );
//Sbd_ManCutIsTopo( p, vMirrors, vCut, iObj );
return 1;
}
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves )
{
int RetValue, LevStop = Vec_IntEntry(p->vLutLevs, iObj) - 2;
Vec_IntClear( p->vCut );
Gia_ManIncrementTravId( p->pGia );
RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop, p->vLutLevs, p->vCut );
if ( RetValue == 0 ) // cannot build delay-improving cut
return -1;
// check if the current cut is good
Vec_IntSort( p->vCut, 0 );
/*
Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
{
//printf( "%d ", Vec_IntSize(p->vCut) );
memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
return Vec_IntSize(p->vCut);
}
*/
// try to expand the cut
Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
{
//printf( "1=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
//printf( "%d ", Vec_IntSize(p->vCut) );
memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
return Vec_IntSize(p->vCut);
}
// try to reduce the topmost
Vec_IntClear( p->vCut0 );
Vec_IntAppend( p->vCut0, p->vCut );
if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) )
{
Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
assert( Vec_IntSize(p->vCut) <= p->nCutSize );
if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
{
//printf( "%d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
return Vec_IntSize(p->vCut);
}
// try again
if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) )
{
Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
assert( Vec_IntSize(p->vCut) <= p->nCutSize );
if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
{
//printf( "* %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
return Vec_IntSize(p->vCut);
}
// try again
if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) )
{
Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
assert( Vec_IntSize(p->vCut) <= p->nCutSize );
if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
{
//printf( "** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
return Vec_IntSize(p->vCut);
}
// try again
if ( Vec_IntSize(p->vCut) < p->nCutSize && Sbd_ManCutReduceTop( p->pGia, p->vMirrors, iObj, p->vLutLevs, p->vCut, p->vCutTop, p->nCutSize ) )
{
Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
assert( Vec_IntSize(p->vCut) <= p->nCutSize );
if ( Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
{
//printf( "*** %d -> %d (%d + %d)\n", Vec_IntSize(p->vCut0), Vec_IntSize(p->vCut), Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
return Vec_IntSize(p->vCut);
}
}
}
}
}
// recompute the cut
Vec_IntClear( p->vCut );
Gia_ManIncrementTravId( p->pGia );
RetValue = Sbd_ManCutCollect_rec( p->pGia, p->vMirrors, iObj, LevStop-1, p->vLutLevs, p->vCut );
if ( RetValue == 0 ) // cannot build delay-improving cut
return -1;
// check if the current cut is good
Vec_IntSort( p->vCut, 0 );
/*
Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
{
//printf( "%d ", Vec_IntSize(p->vCut) );
memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
return Vec_IntSize(p->vCut);
}
*/
// try to expand the cut
Sbd_ManCutExpand( p->pGia, p->vMirrors, p->vLutLevs, p->vCut );
Sbd_ManCutReload( p->vMirrors, p->vLutLevs, LevStop, p->vCut, p->vCutTop, p->vCutBot );
if ( Vec_IntSize(p->vCut) <= p->nCutSize && Vec_IntSize(p->vCutTop) <= p->nLutSize-1 )
{
//printf( "2=(%d,%d) ", Vec_IntSize(p->vCutTop), Vec_IntSize(p->vCutBot) );
//printf( "%d ", Vec_IntSize(p->vCut) );
memcpy( pLeaves, Vec_IntArray(p->vCut), sizeof(int) * Vec_IntSize(p->vCut) );
return Vec_IntSize(p->vCut);
}
return -1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -52,10 +52,26 @@ ABC_NAMESPACE_HEADER_START
#define SBD_SAT_UNDEC 0x1234567812345678
#define SBD_SAT_SAT 0x8765432187654321
#define SBD_LUTS_MAX 2
#define SBD_SIZE_MAX 4
#define SBD_DIV_MAX 10
#define SBD_FVAR_MAX 100
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Sbd_Sto_t_ Sbd_Sto_t;
typedef struct Sbd_Srv_t_ Sbd_Srv_t;
typedef struct Sbd_Str_t_ Sbd_Str_t;
struct Sbd_Str_t_
{
int fLut; // LUT or SEL
int nVarIns; // input count
int VarIns[SBD_DIV_MAX]; // input vars
word Res; // result of solving
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
@ -66,7 +82,38 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== sbdCnf.c ==========================================================*/
/*=== sbdCut.c ==========================================================*/
extern Sbd_Sto_t * Sbd_StoAlloc( Gia_Man_t * pGia, Vec_Int_t * vMirrors, int nLutSize, int nCutSize, int nCutNum, int fCutMin, int fVerbose );
extern void Sbd_StoFree( Sbd_Sto_t * p );
extern int Sbd_StoObjRefs( Sbd_Sto_t * p, int iObj );
extern void Sbd_StoRefObj( Sbd_Sto_t * p, int iObj, int iMirror );
extern void Sbd_StoDerefObj( Sbd_Sto_t * p, int iObj );
extern void Sbd_StoComputeCutsConst0( Sbd_Sto_t * p, int iObj );
extern void Sbd_StoComputeCutsObj( Sbd_Sto_t * p, int iObj, int Delay, int Level );
extern void Sbd_StoComputeCutsCi( Sbd_Sto_t * p, int iObj, int Delay, int Level );
extern int Sbd_StoComputeCutsNode( Sbd_Sto_t * p, int iObj );
extern void Sbd_StoSaveBestDelayCut( Sbd_Sto_t * p, int iObj, int * pCut );
extern int Sbd_StoObjBestCut( Sbd_Sto_t * p, int iObj, int nSize, int * pLeaves );
/*=== sbdCut2.c ==========================================================*/
extern Sbd_Srv_t * Sbd_ManCutServerStart( Gia_Man_t * pGia, Vec_Int_t * vMirrors,
Vec_Int_t * vLutLevs, Vec_Int_t * vLevs, Vec_Int_t * vRefs,
int nLutSize, int nCutSize, int nCutNum, int fVerbose );
extern void Sbd_ManCutServerStop( Sbd_Srv_t * p );
extern int Sbd_ManCutServerFirst( Sbd_Srv_t * p, int iObj, int * pLeaves );
/*=== sbdWin.c ==========================================================*/
extern word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp );
extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf );
extern int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds );
extern int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset );
/*=== sbdPath.c ==========================================================*/
extern Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p );
/*=== sbdQbf.c ==========================================================*/
extern int Sbd_ProblemSolve(
Gia_Man_t * p, Vec_Int_t * vMirrors,
int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var,
Vec_Int_t * vTfo, Vec_Int_t * vRoots,
Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0
);
ABC_NAMESPACE_HEADER_END

311
src/opt/sbd/sbdLut.c Normal file
View File

@ -0,0 +1,311 @@
/**CFile****************************************************************
FileName [sbdLut.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT-based optimization using internal don't-cares.]
Synopsis [CNF computation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: sbdLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sbdInt.h"
#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
// count the number of parameter variables in the structure
int Sbd_ProblemCountParams( int nStrs, Sbd_Str_t * pStr0 )
{
Sbd_Str_t * pStr; int nPars = 0;
for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ )
nPars += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns;
return nPars;
}
// add clauses for the structure
int Sbd_ProblemAddClauses( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 )
{
// variable order: inputs, structure outputs, parameters
Sbd_Str_t * pStr;
int VarOut = nVars;
int VarPar = nVars + nStrs;
int m, k, n, status, pLits[SBD_SIZE_MAX+2];
//printf( "Start par = %d. ", VarPar );
for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++, VarOut++ )
{
if ( pStr->fLut )
{
int nMints = 1 << pStr->nVarIns;
assert( pStr->nVarIns <= 6 );
for ( m = 0; m < nMints; m++, VarPar++ )
{
for ( k = 0; k < pStr->nVarIns; k++ )
pLits[k] = Abc_Var2Lit( pVars[pStr->VarIns[k]], (m >> k) & 1 );
for ( n = 0; n < 2; n++ )
{
pLits[pStr->nVarIns] = Abc_Var2Lit( pVars[VarPar], n );
pLits[pStr->nVarIns+1] = Abc_Var2Lit( pVars[VarOut], !n );
status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns + 2 );
if ( !status )
return 0;
}
}
}
else
{
assert( pStr->nVarIns <= SBD_DIV_MAX );
for ( k = 0; k < pStr->nVarIns; k++, VarPar++ )
{
for ( n = 0; n < 2; n++ )
{
pLits[0] = Abc_Var2Lit( pVars[VarPar], 1 );
pLits[1] = Abc_Var2Lit( pVars[VarOut], n );
pLits[2] = Abc_Var2Lit( pVars[pStr->VarIns[k]], !n );
status = sat_solver_addclause( pSat, pLits, pLits + 3 );
if ( !status )
return 0;
}
}
}
}
return 1;
}
void Sbd_ProblemAddClausesInit( sat_solver * pSat, int nVars, int nStrs, int * pVars, Sbd_Str_t * pStr0 )
{
Sbd_Str_t * pStr;
int VarPar = nVars + nStrs;
int m, m2, status, pLits[SBD_DIV_MAX];
// make sure selector parameters are mutually exclusive
for ( pStr = pStr0; pStr < pStr0 + nStrs; VarPar += pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns, pStr++ )
{
if ( pStr->fLut )
continue;
// one variable should be selected
assert( pStr->nVarIns <= SBD_DIV_MAX );
for ( m = 0; m < pStr->nVarIns; m++ )
pLits[m] = Abc_Var2Lit( pVars[VarPar + m], 0 );
status = sat_solver_addclause( pSat, pLits, pLits + pStr->nVarIns );
assert( status );
// two variables cannot be selected
for ( m = 0; m < pStr->nVarIns; m++ )
for ( m2 = m+1; m2 < pStr->nVarIns; m2++ )
{
pLits[0] = Abc_Var2Lit( pVars[VarPar + m], 1 );
pLits[1] = Abc_Var2Lit( pVars[VarPar + m2], 1 );
status = sat_solver_addclause( pSat, pLits, pLits + 2 );
assert( status );
}
}
}
void Sbd_ProblemPrintSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits )
{
Sbd_Str_t * pStr;
int m, nIters, iLit = 0;
printf( "Solution found:\n" );
for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ )
{
nIters = pStr->fLut ? 1 << pStr->nVarIns : pStr->nVarIns;
printf( "%s%d : ", pStr->fLut ? "LUT":"SEL", (int)(pStr-pStr0) );
for ( m = 0; m < nIters; m++, iLit++ )
printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) );
printf( " {" );
for ( m = 0; m < pStr->nVarIns; m++ )
printf( " %d", pStr->VarIns[m] );
printf( " }\n" );
}
assert( iLit == Vec_IntSize(vLits) );
}
void Sbd_ProblemCollectSolution( int nStrs, Sbd_Str_t * pStr0, Vec_Int_t * vLits )
{
Sbd_Str_t * pStr;
int m, nIters, iLit = 0;
for ( pStr = pStr0; pStr < pStr0 + nStrs; pStr++ )
{
pStr->Res = 0;
if ( pStr->fLut )
{
nIters = 1 << pStr->nVarIns;
for ( m = 0; m < nIters; m++, iLit++ )
if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) )
Abc_TtSetBit( &pStr->Res, m );
pStr->Res = Abc_Tt6Stretch( pStr->Res, pStr->nVarIns );
}
else
{
nIters = 0;
for ( m = 0; m < pStr->nVarIns; m++, iLit++ )
if ( !Abc_LitIsCompl(Vec_IntEntry(vLits, iLit)) )
{
pStr->Res = pStr->VarIns[m];
nIters++;
}
assert( nIters == 1 );
}
}
assert( iLit == Vec_IntSize(vLits) );
}
/**Function*************************************************************
Synopsis [Solves QBF problem for the given window.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sbd_ProblemSolve( Gia_Man_t * p, Vec_Int_t * vMirrors,
int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var,
Vec_Int_t * vTfo, Vec_Int_t * vRoots,
Vec_Int_t * vDivSet, int nStrs, Sbd_Str_t * pStr0 ) // divisors, structures
{
extern sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf );
int fVerbose = 0;
abctime clk = Abc_Clock();
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
sat_solver * pSatCec = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 1 );
sat_solver * pSatQbf = sat_solver_new();
int nVars = Vec_IntSize( vDivSet );
int nPars = Sbd_ProblemCountParams( nStrs, pStr0 );
int VarCecOut = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots);
int VarCecPar = VarCecOut + nStrs;
int VarQbfPar = 0;
int VarQbfFree = nPars;
int pVarsCec[256];
int pVarsQbf[256];
int i, iVar, iLit, nIters;
int RetValue = 0;
assert( Vec_IntSize(vDivSet) <= SBD_DIV_MAX );
assert( nVars + nStrs + nPars <= 256 );
// collect CEC variables
Vec_IntForEachEntry( vDivSet, iVar, i )
pVarsCec[i] = iVar;
for ( i = 0; i < nStrs; i++ )
pVarsCec[nVars + i] = VarCecOut + i;
for ( i = 0; i < nPars; i++ )
pVarsCec[nVars + nStrs + i] = VarCecPar + i;
// collect QBF variables
for ( i = 0; i < nVars + nStrs; i++ )
pVarsQbf[i] = -1;
for ( i = 0; i < nPars; i++ )
pVarsQbf[nVars + nStrs + i] = VarQbfPar + i;
// add clauses to the CEC problem
Sbd_ProblemAddClauses( pSatCec, nVars, nStrs, pVarsCec, pStr0 );
// create QBF solver
sat_solver_setnvars( pSatQbf, 1000 );
Sbd_ProblemAddClausesInit( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 );
// assume all parameter variables are 0
Vec_IntClear( vLits );
for ( i = 0; i < nPars; i++ )
Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, 1) );
for ( nIters = 0; nIters < (1 << nVars); nIters++ )
{
// check if these parameters solve the problem
int status = sat_solver_solve( pSatCec, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 );
if ( status == l_False ) // solution found
break;
assert( status == l_True );
if ( fVerbose )
{
printf( "Iter %3d : ", nIters );
for ( i = 0; i < nPars; i++ )
printf( "%d", !Abc_LitIsCompl(Vec_IntEntry(vLits, i)) );
printf( " " );
}
Vec_IntClear( vLits );
// create new QBF variables
for ( i = 0; i < nVars + nStrs; i++ )
pVarsQbf[i] = VarQbfFree++;
// set their values
Vec_IntForEachEntry( vDivSet, iVar, i )
{
iLit = Abc_Var2Lit( pVarsQbf[i], !sat_solver_var_value(pSatCec, iVar) );
status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 );
assert( status );
if ( fVerbose )
printf( "%d", sat_solver_var_value(pSatCec, iVar) );
}
iLit = Abc_Var2Lit( pVarsQbf[nVars], sat_solver_var_value(pSatCec, VarCecOut) );
status = sat_solver_addclause( pSatQbf, &iLit, &iLit + 1 );
assert( status );
if ( fVerbose )
printf( " %d\n", !sat_solver_var_value(pSatCec, VarCecOut) );
// add clauses to the QBF problem
if ( !Sbd_ProblemAddClauses( pSatQbf, nVars, nStrs, pVarsQbf, pStr0 ) )
break; // solution does not exist
// check if solution still exists
status = sat_solver_solve( pSatQbf, NULL, NULL, 0, 0, 0, 0 );
if ( status == l_False ) // solution does not exist
break;
assert( status == l_True );
// find the new values of parameters
assert( Vec_IntSize(vLits) == 0 );
for ( i = 0; i < nPars; i++ )
Vec_IntPush( vLits, Abc_Var2Lit(VarCecPar + i, !sat_solver_var_value(pSatQbf, VarQbfPar + i)) );
}
if ( Vec_IntSize(vLits) > 0 )
{
//Sbd_ProblemPrintSolution( nStrs, pStr0, vLits );
Sbd_ProblemCollectSolution( nStrs, pStr0, vLits );
RetValue = 1;
}
sat_solver_delete( pSatCec );
sat_solver_delete( pSatQbf );
Vec_IntFree( vLits );
if ( fVerbose )
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

197
src/opt/sbd/sbdPath.c Normal file
View File

@ -0,0 +1,197 @@
/**CFile****************************************************************
FileName [sbdPath.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT-based optimization using internal don't-cares.]
Synopsis [Critical path.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: sbdPath.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sbdInt.h"
#include "misc/tim/tim.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sbc_ManAddInternalToPath_rec( Gia_Man_t * p, int iObj, Vec_Bit_t * vPath )
{
Gia_Obj_t * pObj;
int k, iFan, Value = 0;
if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
return Vec_BitEntry(vPath, iObj);
Gia_ObjSetTravIdCurrentId(p, iObj);
pObj = Gia_ManObj( p, iObj );
if ( Gia_ObjIsCi(pObj) )
return Vec_BitEntry(vPath, iObj);
assert( Gia_ObjIsAnd(pObj) );
Gia_LutForEachFanin( p, iObj, iFan, k )
Value |= Sbc_ManAddInternalToPath_rec( p, iFan, vPath );
if ( Value )
Vec_BitWriteEntry( vPath, iObj, 1 );
return Value;
}
void Sbc_ManAddInternalToPath( Gia_Man_t * p, Vec_Bit_t * vPath )
{
int k, iFan, iObj;
Gia_ManForEachLut( p, iObj )
{
if ( !Vec_BitEntry(vPath, iObj) )
continue;
Gia_ManIncrementTravId( p );
Gia_LutForEachFanin( p, iObj, iFan, k )
Gia_ObjSetTravIdCurrentId(p, iFan);
Sbc_ManAddInternalToPath_rec( p, iObj, vPath );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sbc_ManCriticalPath_rec( Gia_Man_t * p, int * pLevels, int iObj, int LevelFan, Vec_Bit_t * vPath, int Slack )
{
Gia_Obj_t * pObj; int k, iFan;
if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
return;
Gia_ObjSetTravIdCurrentId(p, iObj);
pObj = Gia_ManObj( p, iObj );
Vec_BitWriteEntry( vPath, iObj, 1 );
if ( Gia_ObjIsCi(pObj) )
{
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
int iBox = pManTime ? Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) ) : -1;
if ( iBox >= 0 )
{
int curCo = Tim_ManBoxInputFirst( pManTime, iBox );
int nBoxInputs = Tim_ManBoxInputNum( pManTime, iBox );
for ( k = 0; k < nBoxInputs; k++ )
{
Gia_Obj_t * pCo = Gia_ManCo( p, curCo + k );
int iDriver = Gia_ObjFaninId0p( p, pCo );
if ( (pLevels[iDriver]+Slack >= LevelFan-1) && iDriver )
Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Abc_MaxInt(0, pLevels[iDriver]+Slack-(LevelFan-1)) );
}
}
return;
}
assert( Gia_ObjIsAnd(pObj) );
Gia_LutForEachFanin( p, iObj, iFan, k )
if ( pLevels[iFan]+Slack >= LevelFan-1 )
Sbc_ManCriticalPath_rec( p, pLevels, iFan, pLevels[iFan], vPath, Abc_MaxInt(0, pLevels[iFan]+Slack-(LevelFan-1)) );
}
Vec_Bit_t * Sbc_ManCriticalPath( Gia_Man_t * p )
{
int * pLevels = NULL, k, iDriver, Slack = 1;
int nLevels = p->pManTime ? Gia_ManLutLevelWithBoxes(p) : Gia_ManLutLevel(p, &pLevels);
Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) );
if ( p->pManTime )
pLevels = Vec_IntArray( p->vLevels );
Gia_ManIncrementTravId( p );
Gia_ManForEachCoDriverId( p, iDriver, k )
if ( (pLevels[iDriver] == nLevels) && iDriver )
Sbc_ManCriticalPath_rec( p, pLevels, iDriver, pLevels[iDriver], vPath, Slack );
if ( !p->pManTime )
ABC_FREE( pLevels );
Sbc_ManAddInternalToPath( p, vPath );
return vPath;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sbc_ManDelayTrace( Gia_Man_t * p )
{
Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) );
int i, k, iFan, nLevels, * pLevels;
int nLuts = 0, nNodes = 0, nEdges = 0, nEdgesAll = 0;
if ( !Gia_ManHasMapping(p) )
{
printf( "No mapping is available.\n" );
return;
}
assert( Gia_ManHasMapping(p) );
// set critical CO drivers
nLevels = Gia_ManLutLevel( p, &pLevels );
Gia_ManForEachCoDriverId( p, iFan, i )
if ( pLevels[iFan] == nLevels )
Vec_BitWriteEntry( vPath, iFan, 1 );
// set critical internal nodes
Gia_ManForEachLutReverse( p, i )
{
nLuts++;
if ( !Vec_BitEntry(vPath, i) )
continue;
nNodes++;
Gia_LutForEachFanin( p, i, iFan, k )
{
if ( pLevels[iFan] +1 < pLevels[i] )
continue;
assert( pLevels[iFan] + 1 == pLevels[i] );
Vec_BitWriteEntry( vPath, iFan, 1 );
nEdges++;
//printf( "%d -> %d\n", i, iFan );
}
}
Gia_ManForEachLut( p, i )
Gia_LutForEachFanin( p, i, iFan, k )
nEdgesAll += (Vec_BitEntry(vPath, i) && Vec_BitEntry(vPath, iFan));
ABC_FREE( pLevels );
Vec_BitFree( vPath );
printf( "AIG = %d. LUT = %d. Lev = %d. Path nodes = %d. Path edges = %d. (%d.)\n",
Gia_ManAndNum(p), nLuts, nLevels, nNodes, nEdges, nEdgesAll );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -37,10 +37,6 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define SBD_LUTS_MAX 2
#define SBD_SIZE_MAX 4
#define SBD_DIV_MAX 16
// new AIG manager
typedef struct Sbd_Pro_t_ Sbd_Pro_t;
struct Sbd_Pro_t_

View File

@ -39,19 +39,25 @@ ABC_NAMESPACE_IMPL_START
a DFS ordered array of objects (vWinObjs) whose indexed in the array
(which will be used as SAT variables) are given in array vObj2Var.
The TFO nodes are listed as the last ones in vWinObjs. The root nodes
are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.]
are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.
If fQbf is 1, returns the instance meant for QBF solving. It is using
the last variable (LastVar) as the placeholder for the second copy
of the pivot node.]
SideEffects []
SeeAlso []
***********************************************************************/
sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors,
int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var,
Vec_Int_t * vTfo, Vec_Int_t * vRoots, int fQbf )
{
Gia_Obj_t * pObj;
int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue;
int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo);
int PivotVar = Vec_IntEntry(vObj2Var, Pivot);
int LastVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots);
//Vec_IntPrint( vWinObjs );
//Vec_IntPrint( vTfo );
//Vec_IntPrint( vRoots );
@ -60,7 +66,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
pSat = sat_solver_new();
else
sat_solver_restart( pSat );
sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + 32 );
sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + SBD_FVAR_MAX );
// create constant 0 clause
sat_solver_addclause( pSat, &iLit, &iLit + 1 );
// add clauses for all nodes
@ -100,8 +106,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
Fan1 = Vec_IntEntry( vObj2Var, Fan1 );
Fan0 = Fan0 < TfoStart ? Fan0 : Fan0 + Vec_IntSize(vTfo);
Fan1 = Fan1 < TfoStart ? Fan1 : Fan1 + Vec_IntSize(vTfo);
fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
if ( fQbf )
{
Fan0 = Fan0 == PivotVar ? LastVar : Fan0;
Fan1 = Fan1 == PivotVar ? LastVar : Fan1;
}
fCompl0 = Gia_ObjFaninC0(pObj) ^ (!fQbf && Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
fCompl1 = Gia_ObjFaninC1(pObj) ^ (!fQbf && Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
if ( Gia_ObjIsXor(pObj) )
sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 );
else
@ -127,7 +138,18 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
sat_solver_delete( pSat );
return NULL;
}
assert( sat_solver_nvars(pSat) == nVars + 32 );
assert( sat_solver_nvars(pSat) == nVars + SBD_FVAR_MAX );
}
else if ( fQbf )
{
int n, pLits[2];
for ( n = 0; n < 2; n++ )
{
pLits[0] = Abc_Var2Lit( PivotVar, n );
pLits[1] = Abc_Var2Lit( LastVar, n );
RetValue = sat_solver_addclause( pSat, pLits, pLits + 2 );
assert( RetValue );
}
}
// finalize
RetValue = sat_solver_simplify( pSat );
@ -143,7 +165,7 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
Synopsis [Solves one SAT problem.]
Description [Computes node function for PivotVar with fanins in vDivVars
Description [Computes node function for PivotVar with fanins in vDivSet
using don't-care represented in the SAT solver. Uses array vValues to
return the values of the first Vec_IntSize(vValues) SAT variables in case
the implementation of the node with the given fanins does not exist.]
@ -153,12 +175,13 @@ sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMi
SeeAlso []
***********************************************************************/
word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp )
word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivSet, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp )
{
int nBTLimit = 0;
word uCube, uTruth = 0;
int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0;
assert( FreeVar < sat_solver_nvars(pSat) );
assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) );
pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1
pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit
while ( 1 )
@ -171,12 +194,12 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
return uTruth;
assert( status == l_True );
// remember variable values
for ( i = 0; i < Vec_IntSize(vValues); i++ )
Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) );
Vec_IntForEachEntry( vDivVars, iVar, i )
Vec_IntWriteEntry( vDivValues, i, 2*sat_solver_var_value(pSat, iVar) );
// collect divisor literals
Vec_IntClear( vTemp );
Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0
Vec_IntForEachEntry( vDivVars, iVar, i )
Vec_IntForEachEntry( vDivSet, iVar, i )
Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) );
// check against offset
status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 );
@ -195,7 +218,7 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
if ( pFinal[i] == pLits[0] )
continue;
Vec_IntPush( vTemp, pFinal[i] );
iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
iVar = Vec_IntFind( vDivSet, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar];
}
uTruth |= uCube;
@ -205,11 +228,11 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
}
assert( status == l_True );
// store the counter-example
for ( i = 0; i < Vec_IntSize(vValues); i++ )
Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) );
Vec_IntForEachEntry( vDivVars, iVar, i )
Vec_IntAddToEntry( vDivValues, i, sat_solver_var_value(pSat, iVar) );
for ( i = 0; i < Vec_IntSize(vValues); i++ )
Vec_IntAddToEntry( vValues, i, 0xC );
for ( i = 0; i < Vec_IntSize(vDivValues); i++ )
Vec_IntAddToEntry( vDivValues, i, 0xC );
/*
// reduce the counter example
for ( n = 0; n < 2; n++ )
@ -230,6 +253,140 @@ word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDi
return SBD_SAT_SAT;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sbd_ManSolve2( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vTemp, Vec_Int_t * vSop )
{
int nBTLimit = 0;
int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0;
assert( FreeVar < sat_solver_nvars(pSat) );
assert( Vec_IntSize(vDivVars) == Vec_IntSize(vDivValues) );
pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1
pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit
Vec_IntClear( vSop );
while ( 1 )
{
// find onset minterm
status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 );
if ( status == l_Undef )
return 0;
if ( status == l_False )
return 1;
assert( status == l_True );
// remember variable values
//for ( i = 0; i < Vec_IntSize(vValues); i++ )
// Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) );
// collect divisor literals
Vec_IntClear( vTemp );
Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0
//Vec_IntForEachEntry( vDivSet, iVar, i )
Vec_IntForEachEntry( vDivVars, iVar, i )
Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) );
// check against offset
status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 );
if ( status == l_Undef )
return 0;
if ( status == l_True )
break;
assert( status == l_False );
// compute cube and add clause
nFinal = sat_solver_final( pSat, &pFinal );
Vec_IntClear( vTemp );
Vec_IntPush( vTemp, Abc_LitNot(pLits[1]) ); // NOT(iNewLit)
for ( i = 0; i < nFinal; i++ )
{
if ( pFinal[i] == pLits[0] )
continue;
Vec_IntPush( vTemp, pFinal[i] );
iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
//uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar];
Vec_IntPush( vSop, Abc_Var2Lit( iVar, !Abc_LitIsCompl(pFinal[i]) ) );
}
//uTruth |= uCube;
Vec_IntPush( vSop, -1 );
status = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp) );
assert( status );
nIter++;
}
assert( status == l_True );
// store the counter-example
//for ( i = 0; i < Vec_IntSize(vValues); i++ )
// Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) );
return 0;
}
word Sbd_ManSolverSupp( Vec_Int_t * vSop, int * pInds, int * pnVars )
{
word Supp = 0;
int i, Entry, nVars = 0;
Vec_IntForEachEntry( vSop, Entry, i )
{
if ( Entry == -1 )
continue;
assert( Abc_Lit2Var(Entry) < 64 );
if ( (Supp >> Abc_Lit2Var(Entry)) & 1 )
continue;
pInds[Abc_Lit2Var(Entry)] = nVars++;
Supp |= (word)1 << Abc_Lit2Var(Entry);
}
*pnVars = nVars;
return Supp;
}
void Sbd_ManSolverPrint( Vec_Int_t * vSop )
{
int v, i, Entry, nVars, pInds[64];
word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars );
char Cube[65] = {'\0'};
assert( Cube[nVars] == '\0' );
for ( v = 0; v < nVars; v++ )
Cube[v] = '-';
Vec_IntForEachEntry( vSop, Entry, i )
{
if ( Entry == -1 )
{
printf( "%s\n", Cube );
for ( v = 0; v < nVars; v++ )
Cube[v] = '-';
continue;
}
Cube[pInds[Abc_Lit2Var(Entry)]] = '1' - (char)Abc_LitIsCompl(Entry);
}
Supp = 0;
}
void Sbd_ManSolveSelect( Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vDivVars, Vec_Int_t * vDivValues, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
{
Vec_Int_t * vSop = Vec_IntAlloc( 100 );
Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
sat_solver * pSat = Sbd_ManSatSolver( NULL, p, vMirrors, Pivot, vWinObjs, vObj2Var, vTfo, vRoots, 0 );
int PivotVar = Vec_IntEntry(vObj2Var, Pivot);
int FreeVar = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots);
int Status = Sbd_ManSolve2( pSat, PivotVar, FreeVar, vDivVars, vDivValues, vTemp, vSop );
printf( "Pivot = %4d. Divs = %4d. ", Pivot, Vec_IntSize(vDivVars) );
if ( Status == 0 )
printf( "UNSAT.\n" );
else
{
int nVars, pInds[64];
word Supp = Sbd_ManSolverSupp( vSop, pInds, &nVars );
//Sbd_ManSolverPrint( vSop );
printf( "SAT with %d vars and %d cubes.\n", nVars, Vec_IntCountEntry(vSop, -1) );
Supp = 0;
}
Vec_IntFree( vTemp );
Vec_IntFree( vSop );
sat_solver_delete( pSat );
}
/**Function*************************************************************
Synopsis [Returns a bunch of positive/negative random care minterms.]
@ -273,6 +430,30 @@ int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar,
return -1;
}
int Sbd_ManCollectConstantsNew( sat_solver * pSat, Vec_Int_t * vDivVars, int nConsts, int PivotVar, word * pOnset, word * pOffset )
{
int nBTLimit = 0;
int n, i, k, status, iLit, iVar;
word * pPats[2] = {pOnset, pOffset};
assert( Vec_IntSize(vDivVars) < 64 );
for ( n = 0; n < 2; n++ )
for ( i = 0; i < nConsts; i++ )
{
sat_solver_random_polarity( pSat );
iLit = Abc_Var2Lit( PivotVar, n );
status = sat_solver_solve( pSat, &iLit, &iLit + 1, nBTLimit, 0, 0, 0 );
if ( status == l_Undef )
return -2;
if ( status == l_False )
return n;
pPats[n][i] = ((word)!n) << Vec_IntSize(vDivVars);
Vec_IntForEachEntry( vDivVars, iVar, k )
if ( sat_solver_var_value(pSat, iVar) )
Abc_TtXorBit(&pPats[n][i], k);
}
return -1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///

View File

@ -45,7 +45,7 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
void Sfm_PrintCnf( Vec_Str_t * vCnf )
{
char Entry;
signed char Entry;
int i, Lit;
Vec_StrForEachEntry( vCnf, Entry, i )
{
@ -153,7 +153,7 @@ Vec_Wec_t * Sfm_CreateCnf( Sfm_Ntk_t * p )
void Sfm_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar )
{
Vec_Int_t * vClause;
char Entry;
signed char Entry;
int i, Lit;
Vec_WecClear( vRes );
vClause = Vec_WecPushLevel( vRes );

View File

@ -38,6 +38,22 @@ ABC_NAMESPACE_HEADER_START
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
// combinational equivalence checking parameters
typedef struct Acec_ParCec_t_ Acec_ParCec_t;
struct Acec_ParCec_t_
{
int nBTLimit; // conflict limit at a node
int TimeLimit; // the runtime limit in seconds
int fMiter; // input circuit is a miter
int fDualOutput; // dual-output miter
int fTwoOutput; // two-output miter
int fBooth; // expecting Booth multiplier
int fSilent; // print no messages
int fVeryVerbose; // verbose stats
int fVerbose; // verbose stats
int iOutFail; // the number of failed output
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@ -50,8 +66,11 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== acecCl.c ========================================================*/
extern Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose );
/*=== acecCore.c ========================================================*/
extern int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars );
extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p );
extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars );
/*=== acecFadds.c ========================================================*/
extern Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose, Vec_Int_t ** vCutsXor2 );
extern Vec_Int_t * Gia_ManDetectHalfAdders( Gia_Man_t * p, int fVerbose );
@ -60,6 +79,12 @@ extern Vec_Int_t * Gia_PolynReorder( Gia_Man_t * pGia, int fVerbose, int fVery
extern Vec_Int_t * Gia_PolynFindOrder( Gia_Man_t * pGia, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int fVerbose, int fVeryVerbose );
/*=== acecPolyn.c ========================================================*/
extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fSigned, int fVerbose, int fVeryVerbose );
/*=== acecRe.c ========================================================*/
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
/*=== acecTree.c ========================================================*/
extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose );
ABC_NAMESPACE_HEADER_END

216
src/proof/acec/acecBo.c Normal file
View File

@ -0,0 +1,216 @@
/**CFile****************************************************************
FileName [acecBo.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [CEC for arithmetic circuits.]
Synopsis [Core procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: acecBo.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "acecInt.h"
#include "misc/vec/vecWec.h"
#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Acec_DetectBoothXorMux( Gia_Man_t * p, Gia_Obj_t * pMux, Gia_Obj_t * pXor, int pIns[3] )
{
Gia_Obj_t * pFan0, * pFan1;
Gia_Obj_t * pDat0, * pDat1, * pCtrl;
if ( !Gia_ObjIsMuxType(pMux) || !Gia_ObjIsMuxType(pXor) )
return 0;
if ( !Gia_ObjRecognizeExor( pXor, &pFan0, &pFan1 ) )
return 0;
pFan0 = Gia_Regular(pFan0);
pFan1 = Gia_Regular(pFan1);
if ( Gia_ObjId(p, pFan0) > Gia_ObjId(p, pFan1) )
ABC_SWAP( Gia_Obj_t *, pFan0, pFan1 );
if ( !(pCtrl = Gia_ObjRecognizeMux( pMux, &pDat0, &pDat1 )) )
return 0;
pDat0 = Gia_Regular(pDat0);
pDat1 = Gia_Regular(pDat1);
pCtrl = Gia_Regular(pCtrl);
if ( !Gia_ObjIsAnd(pDat0) || !Gia_ObjIsAnd(pDat1) )
return 0;
if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjFaninId0p(p, pDat1) ||
Gia_ObjFaninId1p(p, pDat0) != Gia_ObjFaninId1p(p, pDat1) )
return 0;
if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjId(p, pFan0) ||
Gia_ObjFaninId1p(p, pDat0) != Gia_ObjId(p, pFan1) )
return 0;
pIns[0] = Gia_ObjId(p, pFan0);
pIns[1] = Gia_ObjId(p, pFan1);
pIns[2] = Gia_ObjId(p, pCtrl);
return 1;
}
int Acec_DetectBoothXorFanin( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
{
Gia_Obj_t * pFan0, * pFan1;
//int Id = Gia_ObjId(p, pObj);
if ( !Gia_ObjIsAnd(pObj) )
return 0;
if ( !Gia_ObjFaninC0(pObj) || !Gia_ObjFaninC1(pObj) )
return 0;
pFan0 = Gia_ObjFanin0(pObj);
pFan1 = Gia_ObjFanin1(pObj);
if ( !Gia_ObjIsAnd(pFan0) || !Gia_ObjIsAnd(pFan1) )
return 0;
if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin0(pFan1), pIns) )
{
pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0));
pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1));
return 1;
}
if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin1(pFan1), pIns) )
{
pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0));
pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1));
return 1;
}
if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin0(pFan1), pIns) )
{
pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0));
pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1));
return 1;
}
if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin1(pFan1), pIns) )
{
pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0));
pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1));
return 1;
}
return 0;
}
int Acec_DetectBoothOne( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
{
Gia_Obj_t * pFan0, * pFan1;
if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) )
return 0;
pFan0 = Gia_Regular(pFan0);
pFan1 = Gia_Regular(pFan1);
if ( Acec_DetectBoothXorFanin( p, pFan0, pIns ) && pIns[2] == Gia_ObjId(p, pFan1) )
return 1;
if ( Acec_DetectBoothXorFanin( p, pFan1, pIns ) && pIns[2] == Gia_ObjId(p, pFan0) )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Acec_DetectBoothTwoXor( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
{
Gia_Obj_t * pFan0, * pFan1;
if ( !Gia_ObjIsAnd(pObj) )
return 0;
if ( Gia_ObjRecognizeExor( Gia_ObjFanin0(pObj), &pFan0, &pFan1 ) )
{
pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0));
pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1));
pIns[2] = -1;
pIns[3] = 0;
pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pObj));
return 1;
}
if ( Gia_ObjRecognizeExor( Gia_ObjFanin1(pObj), &pFan0, &pFan1 ) )
{
pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0));
pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1));
pIns[2] = -1;
pIns[3] = 0;
pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pObj));
return 1;
}
return 0;
}
int Acec_DetectBoothTwo( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
{
Gia_Obj_t * pFan0, * pFan1;
if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) )
return 0;
pFan0 = Gia_Regular(pFan0);
pFan1 = Gia_Regular(pFan1);
if ( Acec_DetectBoothTwoXor( p, pFan0, pIns ) )
{
pIns[2] = Gia_ObjId(p, pFan1);
return 1;
}
if ( Acec_DetectBoothTwoXor( p, pFan1, pIns ) )
{
pIns[2] = Gia_ObjId(p, pFan0);
return 1;
}
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Acec_DetectBoothTest( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
int i, pIns[5];
Gia_ManForEachAnd( p, pObj, i )
{
if ( !Acec_DetectBoothOne(p, pObj, pIns) && !Acec_DetectBoothTwo(p, pObj, pIns) )
continue;
printf( "obj = %4d : b0 = %4d b1 = %4d b2 = %4d a0 = %4d a1 = %4d\n",
i, pIns[0], pIns[1], pIns[2], pIns[3], pIns[4] );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -45,6 +45,396 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
void Acec_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors )
{
Gia_Obj_t * pObj;
int Obj = Node;
if ( Vec_IntEntry(vMirrors, Node) >= 0 )
Obj = Abc_Lit2Var( Vec_IntEntry(vMirrors, Node) );
pObj = Gia_ManObj( p, Obj );
if ( !~pObj->Value )
{
assert( Gia_ObjIsAnd(pObj) );
Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0(pObj, Obj), vMirrors );
Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId1(pObj, Obj), vMirrors );
if ( Gia_ObjIsXor(pObj) )
pObj->Value = Gia_ManAppendXorReal( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
else
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
}
// set the original node as well
if ( Obj != Node )
Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) );
}
Gia_Man_t * Acec_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
int i;
assert( p->pMuxes == NULL );
Gia_ManFillValue( p );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManConst0(p)->Value = 0;
Gia_ManHashAlloc( pNew );
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi(pNew);
Gia_ManForEachCo( p, pObj, i )
Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0p(p, pObj), vMirrors );
Gia_ManForEachCo( p, pObj, i )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManHashStop( pNew );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p )
{
Vec_Int_t * vRootXorSet = Vec_IntAlloc( Gia_ManCoNum(p) );
Gia_Obj_t * pObj, * pFan0, * pFan1, * pFan00, * pFan01, * pFan10, * pFan11;
int i, fXor0, fXor1, fFirstXor = 0;
Gia_ManForEachCoDriver( p, pObj, i )
{
if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
{
if ( fFirstXor )
{
printf( "XORs do not form a continuous sequence\n" );
Vec_IntFreeP( &vRootXorSet );
break;
}
continue;
}
fFirstXor = 1;
fXor0 = Gia_ObjRecognizeExor(Gia_Regular(pFan0), &pFan00, &pFan01);
fXor1 = Gia_ObjRecognizeExor(Gia_Regular(pFan1), &pFan10, &pFan11);
if ( fXor0 == fXor1 )
{
printf( "Both inputs of top level XOR have XOR/non-XOR\n" );
Vec_IntFreeP( &vRootXorSet );
break;
}
Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) );
Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan0)) : Gia_ObjId(p, Gia_Regular(pFan1)) );
Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan10)) : Gia_ObjId(p, Gia_Regular(pFan00)) );
Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan11)) : Gia_ObjId(p, Gia_Regular(pFan01)) );
}
for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
{
printf( "%2d : ", i );
printf( "%4d <- ", Vec_IntEntry(vRootXorSet, 4*i) );
printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+1) );
printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+2) );
printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+3) );
printf( "\n" );
}
return vRootXorSet;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf )
{
Gia_Obj_t * pNode;
int Lit0, Lit1;
if ( Node < Leaf )
return -1;
if ( Node == Leaf )
return Abc_Var2Lit(Node, 0);
pNode = Gia_ManObj( p, Node );
Lit0 = Acec_DetectLitPolarity( p, Gia_ObjFaninId0(pNode, Node), Leaf );
Lit1 = Acec_DetectLitPolarity( p, Gia_ObjFaninId1(pNode, Node), Leaf );
Lit0 = Lit0 == -1 ? Lit0 : Abc_LitNotCond( Lit0, Gia_ObjFaninC0(pNode) );
Lit1 = Lit1 == -1 ? Lit1 : Abc_LitNotCond( Lit1, Gia_ObjFaninC1(pNode) );
if ( Lit0 == -1 && Lit1 == -1 )
return -1;
assert( Lit0 != -1 || Lit1 != -1 );
if ( Lit0 != -1 && Lit1 != -1 )
{
assert( Lit0 == Lit1 );
printf( "Problem for leaf %d\n", Leaf );
return Lit0;
}
return Lit0 != -1 ? Lit0 : Lit1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Acec_DetectComputeSuppOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Int_t * vNods )
{
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( pObj->fMark0 )
{
Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
return;
}
assert( Gia_ObjIsAnd(pObj) );
Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin0(pObj), vSupp, vNods );
Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin1(pObj), vSupp, vNods );
Vec_IntPush( vNods, Gia_ObjId(p, pObj) );
}
void Acec_DetectComputeSupports( Gia_Man_t * p, Vec_Int_t * vRootXorSet )
{
Vec_Int_t * vNods = Vec_IntAlloc( 100 );
Vec_Int_t * vPols = Vec_IntAlloc( 100 );
Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); int i, k, Node, Pol;
for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
{
Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1;
Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 1;
Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 1;
}
for ( i = 1; 4*i < Vec_IntSize(vRootXorSet); i++ )
{
Vec_IntClear( vSupp );
Gia_ManIncrementTravId( p );
Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0;
Acec_DetectComputeSuppOne_rec( p, Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) ), vSupp, vNods );
Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1;
Vec_IntSort( vSupp, 0 );
printf( "Out %4d : %4d \n", i, Vec_IntEntry(vRootXorSet, 4*i+1) );
Vec_IntPrint( vSupp );
printf( "Cone:\n" );
Vec_IntForEachEntry( vNods, Node, k )
Gia_ObjPrint( p, Gia_ManObj(p, Node) );
Vec_IntClear( vPols );
Vec_IntForEachEntry( vSupp, Node, k )
Vec_IntPush( vPols, Acec_DetectLitPolarity(p, Vec_IntEntry(vRootXorSet, 4*i+1), Node) );
Vec_IntForEachEntryTwo( vSupp, vPols, Node, Pol, k )
printf( "%d(%d) ", Node, Abc_LitIsCompl(Pol) );
printf( "\n" );
Vec_IntPrint( vSupp );
}
for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
{
Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0;
Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 0;
Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 0;
}
Vec_IntFree( vSupp );
Vec_IntFree( vPols );
Vec_IntFree( vNods );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet )
{
Gia_Man_t * pNew;
int i, k, iOr1, iAnd1, iAnd2, pLits[3]; // carry, in1, in2
Vec_Int_t * vMirrors = Vec_IntStart( Gia_ManObjNum(p) );
for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
{
pLits[0] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+1) );
// get polarity of two new ones
for ( k = 1; k < 3; k++ )
pLits[k] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+k+1) );
// create the gate
iOr1 = Gia_ManAppendOr( p, pLits[1], pLits[2] );
iAnd1 = Gia_ManAppendAnd( p, pLits[0], iOr1 );
iAnd2 = Gia_ManAppendAnd( p, pLits[1], pLits[2] );
pLits[0] = Gia_ManAppendOr( p, iAnd1, iAnd2 );
Vec_IntWriteEntry( vMirrors, Vec_IntEntry(vRootXorSet, 4*i+1), pLits[0] );
}
// remap the AIG using map
pNew = Acec_ManDerive( p, vMirrors );
Vec_IntFree( vMirrors );
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose )
{
abctime clk = Abc_Clock();
Gia_Man_t * pNew;
Vec_Int_t * vRootXorSet;
// Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 );
//Ree_ManPrintAdders( vAdds, 1 );
// printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 );
// Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
clk = Abc_Clock();
vRootXorSet = Acec_CollectXorTops( p );
if ( vRootXorSet )
{
Acec_DetectComputeSupports( p, vRootXorSet );
pNew = Acec_DetectXorBuildNew( p, vRootXorSet );
Vec_IntFree( vRootXorSet );
}
else
pNew = Gia_ManDup( p );
printf( "Detected %d top XORs. ", Vec_IntSize(vRootXorSet)/4 );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
// Vec_IntFree( vXors );
// Vec_IntFree( vAdds );
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox )
{
Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 );
Vec_Int_t * vLevel;
int i, k, iStart, iLit, Driver, Count = 0;
// determine how much to shift
Driver = Gia_ObjFaninId0p( p, Gia_ManCo(p, 0) );
Vec_WecForEachLevel( pBox->vRootLits, vLevel, iStart )
if ( Abc_Lit2Var(Vec_IntEntry(vLevel,0)) == Driver )
break;
assert( iStart < Gia_ManCoNum(p) );
//Vec_WecPrintLits( pBox->vRootLits );
Vec_WecForEachLevelStart( pBox->vRootLits, vLevel, i, iStart )
{
int In[3] = {0}, Out[2];
assert( Vec_IntSize(vLevel) > 0 );
assert( Vec_IntSize(vLevel) <= 3 );
if ( Vec_IntSize(vLevel) == 1 )
{
Vec_IntPush( vRes, Vec_IntEntry(vLevel, 0) );
continue;
}
Vec_IntForEachEntry( vLevel, iLit, k )
In[k] = iLit;
Acec_InsertFadd( p, In, Out );
Vec_IntPush( vRes, Out[0] );
if ( i+1 < Vec_WecSize(pBox->vRootLits) )
Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] );
else
Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] );
Count++;
}
assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) );
Vec_IntShrink( vRes, Gia_ManCoNum(p) );
printf( "Added %d adders for replace CLAs. ", Count );
return vRes;
}
Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes )
{
Gia_Man_t * pNew, * pTemp;
Gia_Obj_t * pObj; int i;
assert( Gia_ManCoNum(p) == Vec_IntSize(vRes) );
// create new manager
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi(pNew);
Gia_ManForEachAnd( p, pObj, i )
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
Gia_ManForEachCo( p, pObj, i )
{
int iLit = Vec_IntEntry( vRes, i );
Gia_Obj_t * pRepr = Gia_ManObj( p, Abc_Lit2Var(iLit) );
pObj->Value = Gia_ManAppendCo( pNew, pRepr->Value );
}
// set correct phase
Gia_ManSetPhase( p );
Gia_ManSetPhase( pNew );
Gia_ManForEachCo( pNew, pObj, i )
if ( Gia_ObjPhase(pObj) != Gia_ObjPhase(Gia_ManCo(p, i)) )
Gia_ObjFlipFaninC0( pObj );
// remove dangling nodes
pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp );
return pNew;
}
Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose )
{
abctime clk = Abc_Clock();
Gia_Man_t * pNew = NULL;
Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL;
Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose );
Vec_Int_t * vResult;
Vec_BitFreeP( &vIgnore );
if ( pBox == NULL ) // cannot match
{
printf( "Cannot find arithmetic boxes.\n" );
return Gia_ManDup( pGia );
}
vResult = Acec_RewriteTop( pGia, pBox );
Acec_BoxFreeP( &pBox );
pNew = Acec_RewriteReplace( pGia, vResult );
Vec_IntFree( vResult );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///

View File

@ -109,7 +109,7 @@ Vec_Int_t * Gia_PolynCoreOrder_int( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Wec
{
Vec_Int_t * vOrder = Vec_IntAlloc( 1000 );
Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(pGia) );
int i, k, Index, Driver, Entry1, Entry2 = -1;
int i, k, Index = -1, Driver, Entry1, Entry2 = -1;
// mark roots
Vec_IntForEachEntry( vRoots, Driver, i )
Vec_BitWriteEntry( vIsRoot, Driver, 1 );

View File

@ -19,6 +19,9 @@
***********************************************************************/
#include "acecInt.h"
#include "proof/cec/cec.h"
#include "misc/util/utilTruth.h"
#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@ -27,10 +30,37 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define TRUTH_UNUSED 0x1234567812345678
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [This procedure sets default parameters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p )
{
memset( p, 0, sizeof(Acec_ParCec_t) );
p->nBTLimit = 1000; // conflict limit at a node
p->TimeLimit = 0; // the runtime limit in seconds
p->fMiter = 0; // input circuit is a miter
p->fDualOutput = 0; // dual-output miter
p->fTwoOutput = 0; // two-output miter
p->fSilent = 0; // print no messages
p->fVeryVerbose = 0; // verbose stats
p->fVerbose = 0; // verbose stats
p->iOutFail = -1; // the number of failed output
}
/**Function*************************************************************
Synopsis []
@ -42,15 +72,476 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars )
void Acec_VerifyClasses( Gia_Man_t * p, Vec_Wec_t * vLits, Vec_Wec_t * vReprs )
{
Vec_Int_t * vOrder0 = Gia_PolynReorder( pGia0, pPars->fVerbose, pPars->fVeryVerbose );
Vec_Int_t * vOrder1 = Gia_PolynReorder( pGia1, pPars->fVerbose, pPars->fVeryVerbose );
Gia_PolynBuild( pGia0, vOrder0, 0, pPars->fVerbose, pPars->fVeryVerbose );
Gia_PolynBuild( pGia1, vOrder1, 0, pPars->fVerbose, pPars->fVeryVerbose );
Vec_IntFree( vOrder0 );
Vec_IntFree( vOrder1 );
return 1;
Vec_Ptr_t * vFunc = Vec_PtrAlloc( Vec_WecSize(vLits) );
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
Vec_Int_t * vLevel;
int i, j, k, Entry, Entry2, nOvers = 0, nErrors = 0;
Vec_WecForEachLevel( vLits, vLevel, i )
{
Vec_Wrd_t * vTruths = Vec_WrdAlloc( Vec_IntSize(vLevel) );
Vec_IntForEachEntry( vLevel, Entry, k )
{
word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp );
if ( Vec_IntSize(vSupp) > 6 )
{
nOvers++;
Vec_WrdPush( vTruths, TRUTH_UNUSED );
continue;
}
vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
if ( Vec_IntSize(vSupp) > 5 )
{
nOvers++;
Vec_WrdPush( vTruths, TRUTH_UNUSED );
continue;
}
Vec_WrdPush( vTruths, Truth );
}
Vec_PtrPush( vFunc, vTruths );
}
if ( nOvers )
printf( "Detected %d oversize support nodes.\n", nOvers );
Vec_IntFree( vSupp );
Vec_WrdFree( vTemp );
// verify the classes
Vec_WecForEachLevel( vReprs, vLevel, i )
{
Vec_Wrd_t * vTruths = (Vec_Wrd_t *)Vec_PtrEntry( vFunc, i );
Vec_IntForEachEntry( vLevel, Entry, k )
Vec_IntForEachEntryStart( vLevel, Entry2, j, k+1 )
{
word Truth = Vec_WrdEntry( vTruths, k );
word Truth2 = Vec_WrdEntry( vTruths, j );
if ( Entry == Entry2 )
{
nErrors++;
if ( Truth != Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED )
printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j );
}
if ( Entry == Abc_LitNot(Entry2) )
{
nErrors++;
if ( Truth != ~Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED )
printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j );
}
}
}
if ( nErrors )
printf( "Total errors in equivalence classes = %d.\n", nErrors );
Vec_VecFree( (Vec_Vec_t *)vFunc );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Acec_CommonStart( Gia_Man_t * pBase, Gia_Man_t * pAdd )
{
Gia_Obj_t * pObj;
int i;
Gia_ManFillValue( pAdd );
Gia_ManConst0(pAdd)->Value = 0;
if ( pBase == NULL )
{
pBase = Gia_ManStart( Gia_ManObjNum(pAdd) );
pBase->pName = Abc_UtilStrsav( pAdd->pName );
pBase->pSpec = Abc_UtilStrsav( pAdd->pSpec );
Gia_ManForEachCi( pAdd, pObj, i )
pObj->Value = Gia_ManAppendCi(pBase);
Gia_ManHashAlloc( pBase );
}
else
{
assert( Gia_ManCiNum(pBase) == Gia_ManCiNum(pAdd) );
Gia_ManForEachCi( pAdd, pObj, i )
pObj->Value = Gia_Obj2Lit( pBase, Gia_ManCi(pBase, i) );
}
Gia_ManForEachAnd( pAdd, pObj, i )
pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
return pBase;
}
void Acec_CommonFinish( Gia_Man_t * pBase )
{
int Id;
Gia_ManCreateRefs( pBase );
Gia_ManForEachAndId( pBase, Id )
if ( Gia_ObjRefNumId(pBase, Id) == 0 )
Gia_ManAppendCo( pBase, Abc_Var2Lit(Id,0) );
}
Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase )
{
Gia_Obj_t * pObj; int i;
Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) );
Gia_ManSetPhase( pAdd );
Vec_IntWriteEntry( vMapNew, 0, 0 );
Gia_ManForEachCand( pAdd, pObj, i )
{
int iObjBase = Abc_Lit2Var(pObj->Value);
Gia_Obj_t * pObjBase = Gia_ManObj( pBase, iObjBase );
int iObjRepr = Abc_Lit2Var(pObjBase->Value);
Vec_IntWriteEntry( vMapNew, i, Abc_Var2Lit(iObjRepr, Gia_ObjPhase(pObj)) );
}
return vMapNew;
}
void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 )
{
abctime clk = Abc_Clock();
Gia_Man_t * pBase, * pRepr;
pBase = Acec_CommonStart( NULL, pOne );
pBase = Acec_CommonStart( pBase, pTwo );
Acec_CommonFinish( pBase );
//Gia_ManShow( pBase, NULL, 0, 0, 0 );
pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 );
*pvMap1 = Acec_CountRemap( pOne, pBase );
*pvMap2 = Acec_CountRemap( pTwo, pBase );
Gia_ManStop( pBase );
Gia_ManStop( pRepr );
printf( "Finished computing equivalent nodes. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
}
void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits )
{
int i, j, best_i;
for ( i = 0; i < nSize-1; i++ )
{
best_i = i;
for ( j = i+1; j < nSize; j++ )
if ( Abc_Lit2LitL(pCostLits, pArray[j]) > Abc_Lit2LitL(pCostLits, pArray[best_i]) )
best_i = j;
ABC_SWAP( int, pArray[i], pArray[best_i] );
}
}
void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose )
{
Vec_Int_t * vSupp;
Vec_Wrd_t * vTemp;
Vec_Int_t * vLevel;
int i, k, Entry;
printf( "Leaf literals and their classes:\n" );
Vec_WecForEachLevel( vLits, vLevel, i )
{
if ( Vec_IntSize(vLevel) == 0 )
continue;
printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) );
Vec_IntForEachEntry( vLevel, Entry, k )
printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) );
printf( "\n" );
}
if ( !fVerbose )
return;
vSupp = Vec_IntAlloc( 100 );
vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
Vec_WecForEachLevel( vLits, vLevel, i )
{
//if ( i != 20 )
// continue;
if ( Vec_IntSize(vLevel) == 0 )
continue;
Vec_IntForEachEntry( vLevel, Entry, k )
{
word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp );
/*
{
int iObj = Abc_Lit2Var(Entry);
Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 );
Gia_ManShow( pGia0, NULL, 0, 0, 0 );
Gia_ManStop( pGia0 );
}
*/
printf( "Rank = %4d : ", i );
printf( "Obj = %4d ", Abc_Lit2Var(Entry) );
if ( Vec_IntSize(vSupp) > 6 )
{
printf( "Supp = %d.\n", Vec_IntSize(vSupp) );
continue;
}
vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
if ( Vec_IntSize(vSupp) > 5 )
{
printf( "Supp = %d.\n", Vec_IntSize(vSupp) );
continue;
}
Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
printf( " " );
Vec_IntPrint( vSupp );
}
printf( "\n" );
}
Vec_IntFree( vSupp );
Vec_WrdFree( vTemp );
}
Vec_Wec_t * Acec_MatchCopy( Vec_Wec_t * vLits, Vec_Int_t * vMap )
{
Vec_Wec_t * vRes = Vec_WecStart( Vec_WecSize(vLits) );
Vec_Int_t * vLevel; int i, k, iLit;
Vec_WecForEachLevel( vLits, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
Vec_WecPush( vRes, i, Abc_Lit2LitL(Vec_IntArray(vMap), iLit) );
return vRes;
}
int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift )
{
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
Vec_Int_t * vLevel1, * vLevel2;
int i, nCommon = 0;
Vec_WecForEachLevel( vLits1, vLevel1, i )
{
if ( i+Shift < 0 || i+Shift >= Vec_WecSize(vLits2) )
continue;
vLevel2 = Vec_WecEntry( vLits2, i+Shift );
nCommon += Vec_IntTwoFindCommonReverse( vLevel1, vLevel2, vRes );
}
Vec_IntFree( vRes );
return nCommon;
}
void Vec_IntInsertOrder( Vec_Int_t * vLits, Vec_Int_t * vClasses, int Lit, int Class )
{
int i;
for ( i = Vec_IntSize(vClasses)-1; i >= 0; i-- )
if ( Vec_IntEntry(vClasses,i) >= Class )
break;
Vec_IntInsert( vLits, i+1, Lit );
Vec_IntInsert( vClasses, i+1, Class );
}
void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses )
{
Vec_Int_t * vLevel1, * vLevel2;
int i, k, Prev, This, Entry, Counter = 0;
Vec_WecForEachLevel( vLits, vLevel1, i )
{
if ( i == Vec_WecSize(vLits) - 1 )
break;
vLevel2 = Vec_WecEntry(vClasses, i);
assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) );
Prev = -1;
Vec_IntForEachEntry( vLevel2, This, k )
{
if ( Prev != This )
{
Prev = This;
continue;
}
Prev = -1;
Entry = Vec_IntEntry( vLevel1, k );
Vec_IntDrop( vLevel1, k );
Vec_IntDrop( vLevel2, k-- );
Vec_IntDrop( vLevel1, k );
Vec_IntDrop( vLevel2, k-- );
Vec_IntInsertOrder( Vec_WecEntry(vLits, i+1), Vec_WecEntry(vClasses, i+1), Entry, This );
assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) );
assert( Vec_IntSize(Vec_WecEntry(vLits, i+1)) == Vec_IntSize(Vec_WecEntry(vClasses, i+1)) );
Counter++;
}
}
printf( "Moved %d pairs of PPs to normalize the matrix.\n", Counter );
}
void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 )
{
Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 );
Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 );
int nCommon = Acec_MatchCountCommon( vRes0, vRes1, 0 );
int nCommonPlus = Acec_MatchCountCommon( vRes0, vRes1, 1 );
int nCommonMinus = Acec_MatchCountCommon( vRes0, vRes1, -1 );
if ( nCommonPlus >= nCommonMinus && nCommonPlus > nCommon )
{
Vec_WecInsertLevel( vLits0, 0 );
Vec_WecInsertLevel( vRoots0, 0 );
Vec_WecInsertLevel( vRes0, 0 );
printf( "Shifted one level up.\n" );
}
else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon )
{
Vec_WecInsertLevel( vLits1, 0 );
Vec_WecInsertLevel( vRoots1, 0 );
Vec_WecInsertLevel( vRes1, 0 );
printf( "Shifted one level down.\n" );
}
Acec_MoveDuplicates( vLits0, vRes0 );
Acec_MoveDuplicates( vLits1, vRes1 );
//Vec_WecPrintLits( vLits1 );
//printf( "Input literals:\n" );
//Vec_WecPrintLits( vLits0 );
//printf( "Equiv classes:\n" );
//Vec_WecPrintLits( vRes0 );
//printf( "Input literals:\n" );
//Vec_WecPrintLits( vLits1 );
//printf( "Equiv classes:\n" );
//Vec_WecPrintLits( vRes1 );
//Acec_VerifyClasses( pGia0, vLits0, vRes0 );
//Acec_VerifyClasses( pGia1, vLits1, vRes1 );
Vec_WecFree( vRes0 );
Vec_WecFree( vRes1 );
}
int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 )
{
Vec_Int_t * vMap0, * vMap1, * vLevel;
int i, nSize, nTotal;
Acec_ComputeEquivClasses( pBox0->pGia, pBox1->pGia, &vMap0, &vMap1 );
// sort nodes in the classes by their equivalences
Vec_WecForEachLevel( pBox0->vLeafLits, vLevel, i )
Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) );
Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i )
Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) );
Acec_MatchCheckShift( pBox0->pGia, pBox1->pGia, pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits );
//Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 );
//Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 );
//printf( "Outputs:\n" );
//Vec_WecPrintLits( pBox0->vRootLits );
//printf( "Outputs:\n" );
//Vec_WecPrintLits( pBox1->vRootLits );
// reorder nodes to have the same order
assert( pBox0->vShared == NULL );
assert( pBox1->vShared == NULL );
pBox0->vShared = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) );
pBox1->vShared = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) );
pBox0->vUnique = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) );
pBox1->vUnique = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) );
nSize = Abc_MinInt( Vec_WecSize(pBox0->vLeafLits), Vec_WecSize(pBox1->vLeafLits) );
Vec_WecForEachLevelStart( pBox0->vLeafLits, vLevel, i, nSize )
Vec_IntAppend( Vec_WecEntry(pBox0->vUnique, i), vLevel );
Vec_WecForEachLevelStart( pBox1->vLeafLits, vLevel, i, nSize )
Vec_IntAppend( Vec_WecEntry(pBox1->vUnique, i), vLevel );
for ( i = 0; i < nSize; i++ )
{
Vec_Int_t * vShared0 = Vec_WecEntry( pBox0->vShared, i );
Vec_Int_t * vShared1 = Vec_WecEntry( pBox1->vShared, i );
Vec_Int_t * vUnique0 = Vec_WecEntry( pBox0->vUnique, i );
Vec_Int_t * vUnique1 = Vec_WecEntry( pBox1->vUnique, i );
Vec_Int_t * vLevel0 = Vec_WecEntry( pBox0->vLeafLits, i );
Vec_Int_t * vLevel1 = Vec_WecEntry( pBox1->vLeafLits, i );
int * pBeg0 = Vec_IntArray(vLevel0);
int * pBeg1 = Vec_IntArray(vLevel1);
int * pEnd0 = Vec_IntLimit(vLevel0);
int * pEnd1 = Vec_IntLimit(vLevel1);
while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 )
{
int Entry0 = Abc_Lit2LitL( Vec_IntArray(vMap0), *pBeg0 );
int Entry1 = Abc_Lit2LitL( Vec_IntArray(vMap1), *pBeg1 );
assert( *pBeg0 && *pBeg1 );
if ( Entry0 == Entry1 )
{
Vec_IntPush( vShared0, *pBeg0++ );
Vec_IntPush( vShared1, *pBeg1++ );
}
else if ( Entry0 > Entry1 )
Vec_IntPush( vUnique0, *pBeg0++ );
else
Vec_IntPush( vUnique1, *pBeg1++ );
}
while ( pBeg0 < pEnd0 )
Vec_IntPush( vUnique0, *pBeg0++ );
while ( pBeg1 < pEnd1 )
Vec_IntPush( vUnique1, *pBeg1++ );
assert( Vec_IntSize(vShared0) == Vec_IntSize(vShared1) );
assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) );
assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) );
}
nTotal = Vec_WecSizeSize(pBox0->vShared);
printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) );
printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) );
//Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vShared, Vec_IntArray(vMap0), 0 );
//Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vShared, Vec_IntArray(vMap1), 0 );
//printf( "\n" );
//Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 );
//Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 );
Vec_IntFree( vMap0 );
Vec_IntFree( vMap1 );
return nTotal;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars )
{
int status = -1;
abctime clk = Abc_Clock();
Gia_Man_t * pMiter;
Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1;
Cec_ParCec_t ParsCec, * pCecPars = &ParsCec;
// Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL;
// Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL;
// Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose );
// Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose );
// Vec_BitFreeP( &vIgnore0 );
// Vec_BitFreeP( &vIgnore1 );
Acec_Box_t * pBox0 = Acec_ProduceBox( pGia0, pPars->fVerbose );
Acec_Box_t * pBox1 = Acec_ProduceBox( pGia1, pPars->fVerbose );
if ( pBox0 == NULL || pBox1 == NULL ) // cannot match
printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" );
else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching
printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" );
else
{
pGia0n = Acec_InsertBox( pBox0, 0 );
pGia1n = Acec_InsertBox( pBox1, 0 );
printf( "Matching of adder trees in LHS and RHS succeeded. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
// remove the last output
Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 );
Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 );
Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-2, 0 );
Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-2, 0 );
}
// solve regular CEC problem
Cec_ManCecSetDefaultParams( pCecPars );
pCecPars->nBTLimit = pPars->nBTLimit;
pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose );
if ( pMiter )
{
int fDumpMiter = 0;
if ( fDumpMiter )
{
Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" );
Gia_AigerWrite( pMiter, "acec_miter.aig", 0, 0 );
}
status = Cec_ManVerify( pMiter, pCecPars );
ABC_SWAP( Abc_Cex_t *, pGia0->pCexComb, pMiter->pCexComb );
Gia_ManStop( pMiter );
}
else
printf( "Miter computation has failed.\n" );
if ( pGia0n != pGia0 )
Gia_ManStop( pGia0n );
if ( pGia1n != pGia1 )
Gia_ManStop( pGia1n );
Acec_BoxFreeP( &pBox0 );
Acec_BoxFreeP( &pBox1 );
return status;
}
////////////////////////////////////////////////////////////////////////

View File

@ -27,7 +27,6 @@
////////////////////////////////////////////////////////////////////////
#include "aig/gia/gia.h"
#include "proof/cec/cec.h"
#include "acec.h"
////////////////////////////////////////////////////////////////////////
@ -38,6 +37,17 @@
ABC_NAMESPACE_HEADER_START
typedef struct Acec_Box_t_ Acec_Box_t;
struct Acec_Box_t_
{
Gia_Man_t * pGia; // AIG manager
Vec_Wec_t * vAdds; // adders by rank
Vec_Wec_t * vLeafLits; // leaf literals by rank
Vec_Wec_t * vRootLits; // root literals by rank
Vec_Wec_t * vShared; // shared leaves
Vec_Wec_t * vUnique; // unique leaves
};
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
@ -46,6 +56,12 @@ ABC_NAMESPACE_HEADER_START
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; }
static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; }
static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); }
static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); }
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
@ -54,9 +70,28 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== acecCo.c ========================================================*/
extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts );
extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes );
/*=== acecMult.c ========================================================*/
extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits );
extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p );
extern Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p );
/*=== acecNorm.c ========================================================*/
extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] );
extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll );
/*=== acecTree.c ========================================================*/
extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds );
extern void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds );
extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose );
extern void Acec_BoxFreeP( Acec_Box_t ** ppBox );
/*=== acecUtil.c ========================================================*/
extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose );
extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose );
/*=== acecUtil.c ========================================================*/
extern Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose );
ABC_NAMESPACE_HEADER_END

617
src/proof/acec/acecMult.c Normal file
View File

@ -0,0 +1,617 @@
/**CFile****************************************************************
FileName [acecMult.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [CEC for arithmetic circuits.]
Synopsis [Multiplier.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: acecMult.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "acecInt.h"
#include "misc/extra/extra.h"
#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
unsigned s_Classes4a[96] = {
0xD728, 0xB748, 0x9F60, 0xD278, 0xB478, 0x96F0, 0xC66C, 0x96CC, 0x9C6C, 0x96AA, 0xA66A, 0x9A6A,
0x28D7, 0x48B7, 0x609F, 0x2D87, 0x4B87, 0x690F, 0x3993, 0x6933, 0x6393, 0x6955, 0x5995, 0x6595,
0xEB14, 0xED12, 0xF906, 0xE1B4, 0xE1D2, 0xF096, 0xC99C, 0xCC96, 0xC9C6, 0xAA96, 0xA99A, 0xA9A6,
0x14EB, 0x12ED, 0x06F9, 0x1E4B, 0x1E2D, 0x0F69, 0x3663, 0x3369, 0x3639, 0x5569, 0x5665, 0x5659,
0x7D82, 0x7B84, 0x6F90, 0x78D2, 0x78B4, 0x69F0, 0x6CC6, 0x69CC, 0x6C9C, 0x69AA, 0x6AA6, 0x6A9A,
0x827D, 0x847B, 0x906F, 0x872D, 0x874B, 0x960F, 0x9339, 0x9633, 0x9363, 0x9655, 0x9559, 0x9565,
0xBE41, 0xDE21, 0xF609, 0xB4E1, 0xD2E1, 0xF069, 0x9CC9, 0xCC69, 0xC6C9, 0xAA69, 0x9AA9, 0xA6A9,
0x41BE, 0x21DE, 0x09F6, 0x4B1E, 0x2D1E, 0x0F96, 0x6336, 0x3396, 0x3936, 0x5596, 0x6556, 0x5956
};
unsigned s_Classes4b[384] = {
0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0,
0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22,
0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0,
0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88,
0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A,
0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522,
0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A,
0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588,
0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570,
0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A,
0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0,
0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A,
0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025,
0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5,
0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085,
0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5,
0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B,
0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511,
0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E,
0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544,
0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1,
0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11,
0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4,
0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44,
0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207,
0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5,
0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D,
0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5,
0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752,
0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A,
0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58,
0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A
};
unsigned s_Classes4c[768] = {
0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0,
0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22,
0xCA3F, 0xAC5F, 0xE23F, 0xB877, 0xD877, 0xE45F, 0xC3AF, 0xA5CF, 0xE32F, 0xB787, 0xD787, 0xE54F,
0xCB3B, 0x9F93, 0xC3BB, 0x99F3, 0xD973, 0xD793, 0x9F95, 0xAD5D, 0xB795, 0xB975, 0x99F5, 0xA5DD,
0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0,
0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88,
0xC53F, 0xA35F, 0xD13F, 0x8B77, 0x8D77, 0xB15F, 0xC35F, 0xA53F, 0xD31F, 0x87B7, 0x87D7, 0xB51F,
0xC737, 0x939F, 0xC377, 0x993F, 0x9D37, 0x93D7, 0x959F, 0xA757, 0x95B7, 0x9B57, 0x995F, 0xA577,
0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A,
0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522,
0x3ACF, 0x5CAF, 0x2EF3, 0x74BB, 0x72DD, 0x4EF5, 0x3CAF, 0x5ACF, 0x2FE3, 0x7B4B, 0x7D2D, 0x4FE5,
0x3BCB, 0x6F63, 0x3CBB, 0x66F3, 0x73D9, 0x7D39, 0x6F65, 0x5DAD, 0x7B59, 0x75B9, 0x66F5, 0x5ADD,
0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A,
0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588,
0x35CF, 0x53AF, 0x1DF3, 0x47BB, 0x27DD, 0x1BF5, 0x3C5F, 0x5A3F, 0x1FD3, 0x4B7B, 0x2D7D, 0x1FB5,
0x37C7, 0x636F, 0x3C77, 0x663F, 0x379D, 0x397D, 0x656F, 0x57A7, 0x597B, 0x579B, 0x665F, 0x5A77,
0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570,
0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A,
0xACF3, 0xCAF5, 0xB8CF, 0xE2DD, 0xE4BB, 0xD8AF, 0xAFC3, 0xCFA5, 0xBC8F, 0xED2D, 0xEB4B, 0xDA8F,
0xBCB3, 0xF939, 0xBBC3, 0xF399, 0xE6B3, 0xEB63, 0xF959, 0xDAD5, 0xED65, 0xE6D5, 0xF599, 0xDDA5,
0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0,
0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A,
0x5CF3, 0x3AF5, 0x74CF, 0x2EDD, 0x4EBB, 0x72AF, 0x5FC3, 0x3FA5, 0x7C4F, 0x2DED, 0x4BEB, 0x7A2F,
0x7C73, 0x39F9, 0x77C3, 0x3F99, 0x6E3B, 0x63EB, 0x59F9, 0x7A75, 0x65ED, 0x6E5D, 0x5F99, 0x77A5,
0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025,
0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5,
0xA3FC, 0xC5FA, 0x8BFC, 0xD1EE, 0xB1EE, 0x8DFA, 0xAF3C, 0xCF5A, 0x8FBC, 0xDE1E, 0xBE1E, 0x8FDA,
0xB3BC, 0xF636, 0xBB3C, 0xF366, 0xB3E6, 0xBE36, 0xF656, 0xD5DA, 0xDE56, 0xD5E6, 0xF566, 0xDD5A,
0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085,
0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5,
0x53FC, 0x35FA, 0x47FC, 0x1DEE, 0x1BEE, 0x27FA, 0x5F3C, 0x3F5A, 0x4F7C, 0x1EDE, 0x1EBE, 0x2F7A,
0x737C, 0x36F6, 0x773C, 0x3F66, 0x3B6E, 0x36BE, 0x56F6, 0x757A, 0x56DE, 0x5D6E, 0x5F66, 0x775A,
0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B,
0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511,
0x3FCA, 0x5FAC, 0x3FE2, 0x77B8, 0x77D8, 0x5FE4, 0x3CFA, 0x5AFC, 0x3EF2, 0x7B78, 0x7D78, 0x5EF4,
0x3ECE, 0x6F6C, 0x3CEE, 0x66FC, 0x76DC, 0x7D6C, 0x6F6A, 0x5EAE, 0x7B6A, 0x76BA, 0x66FA, 0x5AEE,
0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E,
0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544,
0x3FC5, 0x5FA3, 0x3FD1, 0x778B, 0x778D, 0x5FB1, 0x3CF5, 0x5AF3, 0x3DF1, 0x787B, 0x787D, 0x5BF1,
0x3DCD, 0x6C6F, 0x3CDD, 0x66CF, 0x67CD, 0x6C7D, 0x6A6F, 0x5BAB, 0x6A7B, 0x67AB, 0x66AF, 0x5ABB,
0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1,
0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11,
0xCF3A, 0xAF5C, 0xF32E, 0xBB74, 0xDD72, 0xF54E, 0xC3FA, 0xA5FC, 0xF23E, 0xB7B4, 0xD7D2, 0xF45E,
0xCE3E, 0x9F9C, 0xC3EE, 0x99FC, 0xDC76, 0xD7C6, 0x9F9A, 0xAE5E, 0xB7A6, 0xBA76, 0x99FA, 0xA5EE,
0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4,
0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44,
0xCF35, 0xAF53, 0xF31D, 0xBB47, 0xDD27, 0xF51B, 0xC3F5, 0xA5F3, 0xF13D, 0xB4B7, 0xD2D7, 0xF15B,
0xCD3D, 0x9C9F, 0xC3DD, 0x99CF, 0xCD67, 0xC6D7, 0x9A9F, 0xAB5B, 0xA6B7, 0xAB67, 0x99AF, 0xA5BB,
0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207,
0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5,
0xF3AC, 0xF5CA, 0xCFB8, 0xDDE2, 0xBBE4, 0xAFD8, 0xFA3C, 0xFC5A, 0xCBF8, 0xDED2, 0xBEB4, 0xADF8,
0xE3EC, 0xF6C6, 0xEE3C, 0xFC66, 0xB9EC, 0xBE9C, 0xF6A6, 0xE5EA, 0xDE9A, 0xD9EA, 0xFA66, 0xEE5A,
0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D,
0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5,
0xF35C, 0xF53A, 0xCF74, 0xDD2E, 0xBB4E, 0xAF72, 0xF53C, 0xF35A, 0xC7F4, 0xD2DE, 0xB4BE, 0xA7F2,
0xD3DC, 0xC6F6, 0xDD3C, 0xCF66, 0x9BCE, 0x9CBE, 0xA6F6, 0xB5BA, 0x9ADE, 0x9DAE, 0xAF66, 0xBB5A,
0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752,
0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A,
0xFCA3, 0xFAC5, 0xFC8B, 0xEED1, 0xEEB1, 0xFA8D, 0xFAC3, 0xFCA5, 0xF8CB, 0xEDE1, 0xEBE1, 0xF8AD,
0xECE3, 0xF9C9, 0xEEC3, 0xFC99, 0xECB9, 0xEBC9, 0xF9A9, 0xEAE5, 0xEDA9, 0xEAD9, 0xFA99, 0xEEA5,
0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58,
0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A,
0xFC53, 0xFA35, 0xFC47, 0xEE1D, 0xEE1B, 0xFA27, 0xF5C3, 0xF3A5, 0xF4C7, 0xE1ED, 0xE1EB, 0xF2A7,
0xDCD3, 0xC9F9, 0xDDC3, 0xCF99, 0xCE9B, 0xC9EB, 0xA9F9, 0xBAB5, 0xA9ED, 0xAE9D, 0xAF99, 0xBBA5
};
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes NPN-canonical form using brute-force methods.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Extra_TruthCanonNPN2( unsigned uTruth, int nVars, Vec_Int_t * vRes )
{
static int nVarsOld, nPerms;
static char ** pPerms = NULL;
unsigned uTruthMin, uTruthC, uPhase, uPerm;
int nMints, k, i;
if ( pPerms == NULL )
{
nPerms = Extra_Factorial( nVars );
pPerms = Extra_Permutations( nVars );
nVarsOld = nVars;
}
else if ( nVarsOld != nVars )
{
ABC_FREE( pPerms );
nPerms = Extra_Factorial( nVars );
pPerms = Extra_Permutations( nVars );
nVarsOld = nVars;
}
nMints = (1 << nVars);
uTruthC = (unsigned)( (~uTruth) & ((~((unsigned)0)) >> (32-nMints)) );
uTruthMin = 0xFFFFFFFF;
for ( i = 0; i < nMints; i++ )
{
uPhase = Extra_TruthPolarize( uTruth, i, nVars );
for ( k = 0; k < nPerms; k++ )
{
uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
Vec_IntPushUnique( vRes, uPerm );
if ( uTruthMin > uPerm )
uTruthMin = uPerm;
}
uPhase = Extra_TruthPolarize( uTruthC, i, nVars );
for ( k = 0; k < nPerms; k++ )
{
uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
Vec_IntPushUnique( vRes, uPerm );
if ( uTruthMin > uPerm )
uTruthMin = uPerm;
}
}
return uTruthMin;
}
void Acec_MultFuncTest5()
{
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
int i, Entry;
unsigned Truth = 0xF335ACC0;
unsigned Canon = Extra_TruthCanonNPN2( Truth, 5, vRes );
Extra_PrintHex( stdout, (unsigned*)&Truth, 5 ); printf( "\n" );
Extra_PrintHex( stdout, (unsigned*)&Canon, 5 ); printf( "\n" );
printf( "Members = %d.\n", Vec_IntSize(vRes) );
Vec_IntForEachEntry( vRes, Entry, i )
{
Extra_PrintHex( stdout, (unsigned*)&Entry, 5 );
printf( ", " );
if ( i % 8 == 7 )
printf( "\n" );
}
Vec_IntFree( vRes );
}
void Acec_MultFuncTest4()
{
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
int i, Entry;
unsigned Truth = 0x35C0;
//unsigned Truth = 0xD728;
unsigned Canon = Extra_TruthCanonNPN2( Truth, 4, vRes );
Extra_PrintHex( stdout, (unsigned*)&Truth, 4 ); printf( "\n" );
Extra_PrintHex( stdout, (unsigned*)&Canon, 4 ); printf( "\n" );
printf( "Members = %d.\n", Vec_IntSize(vRes) );
Vec_IntForEachEntry( vRes, Entry, i )
{
Extra_PrintHex( stdout, (unsigned*)&Entry, 4 );
printf( ", " );
if ( i % 12 == 11 )
printf( "\n" );
}
Vec_IntFree( vRes );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Acec_MultCollectInputs( Vec_Int_t * vPairs, Vec_Int_t * vRanks, int iObj )
{
Vec_Int_t * vItems = Vec_IntAlloc( 100 );
int k, iObj1, iObj2;
// collect all those appearing with this one
Vec_IntForEachEntryDouble( vPairs, iObj1, iObj2, k )
if ( iObj == iObj1 )
Vec_IntPushUnique( vItems, iObj2 );
else if ( iObj == iObj2 )
Vec_IntPushUnique( vItems, iObj1 );
// sort items by rank cost
Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks );
return vItems;
}
Vec_Int_t * Acec_MultDetectInputs1( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits )
{
Vec_Int_t * vInputs = Vec_IntAlloc( 100 );
Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) );
Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) );
Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
Vec_Int_t * vItems = Vec_IntAlloc( 100 );
Vec_Int_t * vItems0;
Vec_Int_t * vItems1;
Vec_Int_t * vLevel;
int i, k, iLit, iObj, Count;
// count how many times each input appears
Vec_WecForEachLevel( vLeafLits, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
iObj = Abc_Lit2Var(iLit);
Vec_IntAddToEntry( vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), 1 );
Vec_IntAddToEntry( vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), 1 );
/*
printf( "Rank %2d : Leaf = %4d : (%2d, %2d)\n", i, iObj,
Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) );
if ( k == Vec_IntSize(vLevel) - 1 )
printf( "\n" );
*/
}
// count ranks for each one
Vec_WecForEachLevel( vLeafLits, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
iObj = Abc_Lit2Var(iLit);
if ( Vec_IntEntry(vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj)) < 2 )
{
printf( "Skipping %d.\n", iObj );
continue;
}
if ( Vec_IntEntry(vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj)) < 2 )
{
printf( "Skipping %d.\n", iObj );
continue;
}
Vec_IntAddToEntry( vRanks, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), i );
Vec_IntAddToEntry( vRanks, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), i );
Vec_IntPushTwo( vPairs, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) );
}
// print statistics
Vec_IntForEachEntry( vCounts, Count, i )
{
if ( !Count )
continue;
if ( !Vec_IntEntry(vRanks, i) )
continue;
Vec_IntPush( vItems, i );
printf( "Obj = %3d Occurs = %3d Ranks = %3d\n", i, Count, Vec_IntEntry(vRanks, i) );
}
// sort items by rank cost
Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks );
// collect all those appearing with the last one
vItems0 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems) );
Vec_IntAppend( vInputs, vItems0 );
// collect all those appearing with the last one
vItems1 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems0) );
Vec_IntAppend( vInputs, vItems1 );
Vec_IntPrint( vItems0 );
Vec_IntPrint( vItems1 );
Vec_IntFree( vCounts );
Vec_IntFree( vRanks );
Vec_IntFree( vPairs );
Vec_IntFree( vItems );
Vec_IntFree( vItems0 );
Vec_IntFree( vItems1 );
return vInputs;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits )
{
Vec_Int_t * vInputs = Vec_IntAlloc( 100 );
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) );
Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) );
Vec_Int_t * vLevel;
int i, k, iLit, iObj, j, Entry;
ABC_FREE( p->pRefs );
Gia_ManCreateRefs( p );
Gia_ManForEachCiId( p, iObj, i )
printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) );
printf( "\n" );
Gia_ManForEachAndId( p, iObj )
if ( Gia_ObjRefNumId(p, iObj) >= 4 )
printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) );
printf( "\n" );
Vec_WecForEachLevel( vLeafLits, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp );
if ( Vec_IntSize(vSupp) >= 0 )
{
printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) );
printf( "Rank = %2d ", i );
printf( "Supp = %2d ", Vec_IntSize(vSupp) );
Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
printf( " " );
Vec_IntPrint( vSupp );
/*
if ( Truth == 0xF335ACC0F335ACC0 )
{
int iObj = Abc_Lit2Var(iLit);
Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 );
Gia_ManShow( pGia0, NULL, 0, 0, 0 );
Gia_ManStop( pGia0 );
}
*/
}
// support rank counts
Vec_IntForEachEntry( vSupp, Entry, j )
{
Vec_IntAddToEntry( vRanks, Entry, i );
Vec_IntAddToEntry( vCounts, Entry, 1 );
}
if ( k == Vec_IntSize(vLevel)-1 )
printf( "\n" );
}
Vec_IntForEachEntry( vCounts, Entry, j )
if ( Entry )
printf( "%d=%d(%.2f) ", j, Entry, 1.0*Vec_IntEntry(vRanks, j)/Entry );
printf( "\n" );
Vec_IntFree( vSupp );
Vec_WrdFree( vTemp );
Vec_IntFree( vRanks );
Vec_IntFree( vCounts );
return vInputs;
}
/**Function*************************************************************
Synopsis [Mark nodes whose function is exactly that of a Booth PP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p )
{
word Saved[32] = {
ABC_CONST(0xF335ACC0F335ACC0),
ABC_CONST(0x35C035C035C035C0),
ABC_CONST(0xD728D728D728D728),
ABC_CONST(0xFD80FD80FD80FD80),
ABC_CONST(0xACC0ACC0ACC0ACC0),
ABC_CONST(0x7878787878787878),
ABC_CONST(0x2828282828282828),
ABC_CONST(0xD0D0D0D0D0D0D0D0),
ABC_CONST(0x8080808080808080),
ABC_CONST(0x8888888888888888),
ABC_CONST(0xAAAAAAAAAAAAAAAA),
ABC_CONST(0x5555555555555555),
ABC_CONST(0xD5A8D5A8D5A8D5A8),
ABC_CONST(0x2A572A572A572A57),
ABC_CONST(0xF3C0F3C0F3C0F3C0),
ABC_CONST(0x5858585858585858),
ABC_CONST(0xA7A7A7A7A7A7A7A7),
ABC_CONST(0x2727272727272727),
ABC_CONST(0xD8D8D8D8D8D8D8D8)
};
Vec_Bit_t * vRes = Vec_BitStart( Gia_ManObjNum(p) );
Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
int i, iObj, nProds = 0;
Gia_ManCleanMark0(p);
Gia_ManForEachAndId( p, iObj )
{
word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp );
if ( Vec_IntSize(vSupp) > 6 )
continue;
vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
if ( Vec_IntSize(vSupp) > 5 )
continue;
for ( i = 0; i < 32 && Saved[i]; i++ )
{
if ( Truth == Saved[i] || Truth == ~Saved[i] )
{
Vec_BitWriteEntry( vRes, iObj, 1 );
nProds++;
break;
}
}
}
Gia_ManCleanMark0(p);
printf( "Collected %d pps.\n", nProds );
Vec_IntFree( vSupp );
Vec_WrdFree( vTemp );
return vRes;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Acec_MultFindPPs_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vBold )
{
Gia_Obj_t * pObj;
pObj = Gia_ManObj( p, iObj );
if ( pObj->fMark0 )
return;
pObj->fMark0 = 1;
if ( !Gia_ObjIsAnd(pObj) )
return;
Acec_MultFindPPs_rec( p, Gia_ObjFaninId0(pObj, iObj), vBold );
Acec_MultFindPPs_rec( p, Gia_ObjFaninId1(pObj, iObj), vBold );
Vec_IntPush( vBold, iObj );
}
Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p )
{
word Saved[32] = {
ABC_CONST(0xF335ACC0F335ACC0),
ABC_CONST(0x35C035C035C035C0),
ABC_CONST(0xD728D728D728D728),
ABC_CONST(0xFD80FD80FD80FD80),
ABC_CONST(0xACC0ACC0ACC0ACC0),
ABC_CONST(0x7878787878787878),
ABC_CONST(0x2828282828282828),
ABC_CONST(0xD0D0D0D0D0D0D0D0),
ABC_CONST(0x8080808080808080),
ABC_CONST(0x8888888888888888),
ABC_CONST(0xAAAAAAAAAAAAAAAA),
ABC_CONST(0x5555555555555555),
ABC_CONST(0xD5A8D5A8D5A8D5A8),
ABC_CONST(0x2A572A572A572A57),
ABC_CONST(0xF3C0F3C0F3C0F3C0),
ABC_CONST(0x5858585858585858),
ABC_CONST(0xA7A7A7A7A7A7A7A7),
ABC_CONST(0x2727272727272727),
ABC_CONST(0xD8D8D8D8D8D8D8D8)
};
Vec_Int_t * vBold = Vec_IntAlloc( 100 );
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
int i, iObj, nProds = 0;
Gia_ManCleanMark0(p);
Gia_ManForEachAndId( p, iObj )
{
word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp );
if ( Vec_IntSize(vSupp) > 6 )
continue;
vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
if ( Vec_IntSize(vSupp) > 5 )
continue;
for ( i = 0; i < 32 && Saved[i]; i++ )
{
if ( Truth == Saved[i] || Truth == ~Saved[i] )
{
//printf( "*** Node %d is PP with support %d.\n", iObj, Vec_IntSize(vSupp) );
Acec_MultFindPPs_rec( p, iObj, vBold );
nProds++;
break;
}
}
/*
if ( Saved[i] )
{
printf( "Obj = %4d ", iObj );
Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
printf( " " );
Vec_IntPrint( vSupp );
}
*/
}
Gia_ManCleanMark0(p);
printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) );
Vec_IntFree( vSupp );
Vec_WrdFree( vTemp );
return vBold;
}
Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p )
{
Vec_Bit_t * vIgnore = Vec_BitStart( Gia_ManObjNum(p) );
Vec_Int_t * vMap = Acec_MultFindPPs( p );
int i, Entry;
Vec_IntForEachEntry( vMap, Entry, i )
Vec_BitWriteEntry( vIgnore, Entry, 1 );
Vec_IntFree( vMap );
return vIgnore;
}
void Acec_MultFindPPsTest( Gia_Man_t * p )
{
Vec_Int_t * vBold = Acec_MultFindPPs( p );
Gia_ManShow( p, vBold, 1, 0, 0 );
Vec_IntFree( vBold );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

226
src/proof/acec/acecNorm.c Normal file
View File

@ -0,0 +1,226 @@
/**CFile****************************************************************
FileName [acecNorm.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [CEC for arithmetic circuits.]
Synopsis [Adder tree normalization.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: acecNorm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "acecInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] )
{
int And, Or;
Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] );
And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) );
Or = Gia_ManAppendOr2( pNew, Out[1], And );
Out[0] = Abc_LitNot( Or );
}
void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] )
{
int In2[2], Out1[2], Out2[2];
Acec_InsertHadd( pNew, In, Out1 );
In2[0] = Out1[0];
In2[1] = In[2];
Acec_InsertHadd( pNew, In2, Out2 );
Out[0] = Out2[0];
Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] );
}
Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap )
{
Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 );
Vec_Int_t * vLevel;
int i, In[3], Out[2];
Vec_WecForEachLevel( vLeafMap, vLevel, i )
{
if ( Vec_IntSize(vLevel) == 0 )
{
Vec_IntPush( vRootRanks, 0 );
continue;
}
while ( Vec_IntSize(vLevel) > 1 )
{
if ( Vec_IntSize(vLevel) == 2 )
Vec_IntPush( vLevel, 0 );
//In[2] = Vec_IntPop( vLevel );
//In[1] = Vec_IntPop( vLevel );
//In[0] = Vec_IntPop( vLevel );
In[0] = Vec_IntEntry( vLevel, 0 );
Vec_IntDrop( vLevel, 0 );
In[1] = Vec_IntEntry( vLevel, 0 );
Vec_IntDrop( vLevel, 0 );
In[2] = Vec_IntEntry( vLevel, 0 );
Vec_IntDrop( vLevel, 0 );
Acec_InsertFadd( pNew, In, Out );
Vec_IntPush( vLevel, Out[0] );
if ( i+1 < Vec_WecSize(vLeafMap) )
vLevel = Vec_WecEntry(vLeafMap, i+1);
else
vLevel = Vec_WecPushLevel(vLeafMap);
Vec_IntPush( vLevel, Out[1] );
vLevel = Vec_WecEntry(vLeafMap, i);
}
assert( Vec_IntSize(vLevel) == 1 );
Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) );
}
return vRootRanks;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
{
if ( ~pObj->Value )
return pObj->Value;
assert( Gia_ObjIsAnd(pObj) );
Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) );
Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) );
return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ));
}
Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Int_t * vRootLits )
{
Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) );
Vec_Int_t * vLevel, * vRootRanks;
int i, k, iLit, iLitNew;
// add roo literals
if ( vRootLits )
Vec_IntForEachEntry( vRootLits, iLit, i )
{
if ( i < Vec_WecSize(vLeafMap) )
vLevel = Vec_WecEntry(vLeafMap, i);
else
vLevel = Vec_WecPushLevel(vLeafMap);
Vec_IntPush( vLevel, iLit );
}
// add other literals
Vec_WecForEachLevel( vLeafLits, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
iLitNew = Acec_InsertBox_rec( pNew, p, pObj );
iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) );
Vec_WecPush( vLeafMap, i, iLitNew );
}
// construct map of root literals
vRootRanks = Acec_InsertTree( pNew, vLeafMap );
Vec_WecFree( vLeafMap );
return vRootRanks;
}
Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll )
{
Gia_Man_t * p = pBox->pGia;
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
Vec_Int_t * vRootRanks, * vLevel, * vTemp;
int i, k, iLit, iLitNew;
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManFillValue(p);
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
// implement tree
if ( fAll )
vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits, NULL );
else
{
assert( pBox->vShared != NULL );
assert( pBox->vUnique != NULL );
vRootRanks = Acec_BuildTree( pNew, p, pBox->vShared, NULL );
vRootRanks = Acec_BuildTree( pNew, p, pBox->vUnique, vTemp = vRootRanks );
Vec_IntFree( vTemp );
}
// update polarity of literals
Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, i );
pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) );
}
Vec_IntFree( vRootRanks );
// construct the outputs
Gia_ManForEachCo( p, pObj, i )
Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) );
Gia_ManForEachCo( p, pObj, i )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose )
{
Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL;
Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose );
Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 );
Acec_BoxFreeP( &pBox );
Vec_BitFreeP( &vIgnore );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -248,11 +248,6 @@ int Pas_ManComputeCuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vOrder, Ve
***********************************************************************/
void Pas_ManComputeCutsTest( Gia_Man_t * p )
{
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts );
extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
abctime clk = Abc_Clock();
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
Vec_Int_t * vIns, * vOuts;

Some files were not shown because too many files have changed in this diff Show More