mirror of https://github.com/YosysHQ/abc.git
Merged alanmi/abc into default
This commit is contained in:
commit
28e8e7f3e7
|
|
@ -52,9 +52,14 @@ build/
|
|||
*.rej
|
||||
*.orig
|
||||
|
||||
tags
|
||||
|
||||
syntax: regexp
|
||||
|
||||
^libabc.a$
|
||||
^abc$
|
||||
|
||||
^arch_flags$
|
||||
|
||||
^cmake
|
||||
^cscope
|
||||
|
|
|
|||
10
Makefile
10
Makefile
|
|
@ -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
|
||||
|
|
|
|||
216
abclib.dsp
216
abclib.dsp
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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.]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
1063
src/base/abci/abc.c
1063
src/base/abci/abc.c
File diff suppressed because it is too large
Load Diff
|
|
@ -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) );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ) )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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.]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ========================================================*/
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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 ///
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ); }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -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 :
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 ///
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
Loading…
Reference in New Issue