mirror of https://github.com/YosysHQ/abc.git
Merged alanmi/abc into default
This commit is contained in:
commit
876eb5a52e
8
Makefile
8
Makefile
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -88,6 +88,10 @@ LINK32=link.exe
|
|||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\acec\acecTree.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\main\main.c
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
|
|||
32
abclib.dsp
32
abclib.dsp
|
|
@ -2759,10 +2759,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
|
||||
|
|
@ -5463,6 +5479,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
|
||||
|
|
@ -5487,6 +5507,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
|
||||
|
|
@ -5515,6 +5543,10 @@ SOURCE=.\src\proof\acec\acecSt.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
|
||||
# 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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -665,21 +665,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 +765,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 );
|
||||
|
|
@ -1219,6 +1242,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 +1272,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 );
|
||||
|
|
@ -1403,7 +1429,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 +1517,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 );
|
||||
|
|
|
|||
|
|
@ -3045,6 +3045,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 +3442,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 +3764,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 +3941,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.]
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1256,10 +1256,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) );
|
||||
|
|
@ -1702,11 +1702,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) );
|
||||
|
|
|
|||
|
|
@ -2012,14 +2012,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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1415,11 +1415,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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,8 +289,9 @@ 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 );
|
||||
|
|
@ -274,12 +304,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 +323,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 +333,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 );
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "gia.h"
|
||||
#include "proof/cec/cec.h"
|
||||
#include "proof/acec/acec.h"
|
||||
#include "misc/extra/extra.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -29,6 +30,8 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NODE_MAX 2000
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -45,40 +48,64 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold )
|
||||
void Gia_ShowPath( Gia_Man_t * p, char * pFileName )
|
||||
{
|
||||
FILE * pFile;
|
||||
Gia_Obj_t * pNode;//, * pTemp, * pPrev;
|
||||
int LevelMax, Prev, Level, i;
|
||||
int fConstIsUsed = 0;
|
||||
Gia_Obj_t * pNode;
|
||||
Vec_Bit_t * vPath = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
int i, k, iFan, LevelMax, nLevels, * pLevels, Level, Prev;
|
||||
int nLuts = 0, nNodes = 0, nEdges = 0;
|
||||
assert( Gia_ManHasMapping(p) );
|
||||
|
||||
if ( Gia_ManAndNum(p) > 500 )
|
||||
// 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 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( nNodes > NODE_MAX )
|
||||
{
|
||||
fprintf( stdout, "Cannot visualize AIG with more than 500 nodes.\n" );
|
||||
ABC_FREE( pLevels );
|
||||
Vec_BitFree( vPath );
|
||||
fprintf( stdout, "Cannot visualize AIG with more than %d critical nodes.\n", NODE_MAX );
|
||||
return;
|
||||
}
|
||||
if ( (pFile = fopen( pFileName, "w" )) == NULL )
|
||||
{
|
||||
ABC_FREE( pLevels );
|
||||
Vec_BitFree( vPath );
|
||||
fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the nodes
|
||||
if ( vBold )
|
||||
Gia_ManForEachObjVec( vBold, p, pNode, i )
|
||||
pNode->fMark0 = 1;
|
||||
else if ( p->nXors || p->nMuxes )
|
||||
Gia_ManForEachObj( p, pNode, i )
|
||||
if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) )
|
||||
pNode->fMark0 = 1;
|
||||
Vec_IntFreeP( &p->vLevels );
|
||||
p->vLevels = Vec_IntAllocArray( pLevels, Gia_ManObjNum(p) );
|
||||
|
||||
// compute levels
|
||||
LevelMax = 1 + Gia_ManLevelNum( p );
|
||||
// compute CO levels
|
||||
LevelMax = 1 + nLevels;
|
||||
Gia_ManForEachCo( p, pNode, i )
|
||||
Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax );
|
||||
|
||||
// write the DOT header
|
||||
fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" );
|
||||
fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, "digraph AIG {\n" );
|
||||
fprintf( pFile, "size = \"7.5,10\";\n" );
|
||||
|
|
@ -152,7 +179,271 @@ void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold )
|
|||
fprintf( pFile, " fontsize=18,\n" );
|
||||
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
|
||||
fprintf( pFile, " label=\"" );
|
||||
fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax );
|
||||
fprintf( pFile, "The critical path contains %d LUTs with %d critical edges and spans %d levels.", nNodes, nEdges, nLevels );
|
||||
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
|
||||
Gia_ManForEachCo( p, pNode, i )
|
||||
{
|
||||
if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels )
|
||||
continue;
|
||||
assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels );
|
||||
fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
|
||||
fprintf( pFile, ", shape = %s", "invtriangle" );
|
||||
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 );
|
||||
Gia_ManForEachObj( p, pNode, i )
|
||||
{
|
||||
if ( (int)Gia_ObjLevel(p, pNode) != Level || !Vec_BitEntry(vPath, i) )
|
||||
continue;
|
||||
fprintf( pFile, " Node%d [label = \"%d:%d\"", i, i, Gia_ObjIsAnd(pNode)? Gia_ObjLutSize(p, i) : 0 );
|
||||
fprintf( pFile, ", shape = ellipse" );
|
||||
if ( pNode->fMark0 )
|
||||
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
|
||||
Gia_ManForEachCi( p, pNode, i )
|
||||
{
|
||||
if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) )
|
||||
continue;
|
||||
fprintf( pFile, " Node%d [label = \"%d\"", Gia_ObjId(p, pNode), Gia_ObjId(p, pNode) );
|
||||
fprintf( pFile, ", shape = %s", "triangle" );
|
||||
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" );
|
||||
Gia_ManForEachCo( p, pNode, i )
|
||||
{
|
||||
if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels )
|
||||
continue;
|
||||
fprintf( pFile, "title2 -> Node%d [style = invis];\n", Gia_ObjId(p, pNode) );
|
||||
}
|
||||
// generate invisible edges among the COs
|
||||
Prev = -1;
|
||||
Gia_ManForEachCo( p, pNode, i )
|
||||
{
|
||||
if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) < nLevels )
|
||||
continue;
|
||||
assert( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels );
|
||||
if ( Prev >= 0 )
|
||||
fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) );
|
||||
Prev = Gia_ObjId(p, pNode);
|
||||
}
|
||||
// generate invisible edges among the CIs
|
||||
Prev = -1;
|
||||
Gia_ManForEachCi( p, pNode, i )
|
||||
{
|
||||
if ( !Vec_BitEntry(vPath, Gia_ObjId(p, pNode)) )
|
||||
continue;
|
||||
if ( Prev >= 0 )
|
||||
fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Gia_ObjId(p, pNode) );
|
||||
Prev = Gia_ObjId(p, pNode);
|
||||
}
|
||||
|
||||
// generate edges
|
||||
Gia_ManForEachObj( p, pNode, i )
|
||||
{
|
||||
if ( Gia_ObjIsCo(pNode) )
|
||||
{
|
||||
if ( Gia_ObjLevel(p, Gia_ObjFanin0(pNode)) == nLevels )
|
||||
{
|
||||
// generate the edge from this node to the next
|
||||
fprintf( pFile, "Node%d", i );
|
||||
fprintf( pFile, " -> " );
|
||||
fprintf( pFile, "Node%d", Gia_ObjFaninId0p(p, pNode) );
|
||||
fprintf( pFile, " [" );
|
||||
fprintf( pFile, "style = %s", "bold" );
|
||||
fprintf( pFile, "]" );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( !Gia_ObjIsAnd(pNode) || !Vec_BitEntry(vPath, i) )
|
||||
continue;
|
||||
Gia_LutForEachFanin( p, i, iFan, k )
|
||||
{
|
||||
if ( pLevels[iFan] + 1 < pLevels[i] )
|
||||
continue;
|
||||
assert( pLevels[iFan] + 1 == pLevels[i] );
|
||||
// generate the edge from this node to the next
|
||||
fprintf( pFile, "Node%d", i );
|
||||
fprintf( pFile, " -> " );
|
||||
fprintf( pFile, "Node%d", iFan );
|
||||
fprintf( pFile, " [" );
|
||||
fprintf( pFile, "style = %s", "bold" );
|
||||
fprintf( pFile, "]" );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( pFile, "}" );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
|
||||
Vec_IntFreeP( &p->vLevels );
|
||||
Vec_BitFree( vPath );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the graph structure of AIG for DOT.]
|
||||
|
||||
Description [Useful for graph visualization using tools such as GraphViz:
|
||||
http://www.graphviz.org/]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_WriteDotAigSimple( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold )
|
||||
{
|
||||
FILE * pFile;
|
||||
Gia_Obj_t * pNode;//, * pTemp, * pPrev;
|
||||
int LevelMax, Prev, Level, i;
|
||||
int fConstIsUsed = 0;
|
||||
|
||||
if ( Gia_ManAndNum(p) > NODE_MAX )
|
||||
{
|
||||
fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX );
|
||||
return;
|
||||
}
|
||||
if ( (pFile = fopen( pFileName, "w" )) == NULL )
|
||||
{
|
||||
fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the nodes
|
||||
if ( vBold )
|
||||
Gia_ManForEachObjVec( vBold, p, pNode, i )
|
||||
pNode->fMark0 = 1;
|
||||
else if ( p->nXors || p->nMuxes )
|
||||
Gia_ManForEachObj( p, pNode, i )
|
||||
if ( Gia_ObjIsXor(pNode) || Gia_ObjIsMux(p, pNode) )
|
||||
pNode->fMark0 = 1;
|
||||
|
||||
// compute levels
|
||||
LevelMax = 1 + Gia_ManLevelNum( p );
|
||||
Gia_ManForEachCo( p, pNode, i )
|
||||
Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax );
|
||||
|
||||
// write the DOT header
|
||||
fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, "digraph AIG {\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", "AIG structure visualized by ABC" );
|
||||
fprintf( pFile, "\\n" );
|
||||
fprintf( pFile, "Benchmark \\\"%s\\\". ", "aig" );
|
||||
// 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 AIG contains %d nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax-1 );
|
||||
fprintf( pFile, "\\n" );
|
||||
fprintf( pFile, "\"\n" );
|
||||
fprintf( pFile, " ];\n" );
|
||||
|
|
@ -381,16 +672,17 @@ int Gia_ShowAddOut( Vec_Int_t * vAdds, Vec_Int_t * vMapAdds, int Node )
|
|||
return Vec_IntEntry( vAdds, 6*iBox+4 );
|
||||
return Node;
|
||||
}
|
||||
void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder )
|
||||
void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, Vec_Int_t * vMapAdds, Vec_Int_t * vMapXors, Vec_Int_t * vOrder )
|
||||
{
|
||||
FILE * pFile;
|
||||
Gia_Obj_t * pNode;//, * pTemp, * pPrev;
|
||||
int LevelMax, Prev, Level, i;
|
||||
int fConstIsUsed = 0;
|
||||
int nFadds = Ree_ManCountFadds( vAdds );
|
||||
|
||||
if ( Gia_ManAndNum(p) > 1000 )
|
||||
if ( Gia_ManAndNum(p) > NODE_MAX )
|
||||
{
|
||||
fprintf( stdout, "Cannot visualize AIG with more than 1000 nodes.\n" );
|
||||
fprintf( stdout, "Cannot visualize AIG with more than %d nodes.\n", NODE_MAX );
|
||||
return;
|
||||
}
|
||||
if ( (pFile = fopen( pFileName, "w" )) == NULL )
|
||||
|
|
@ -399,13 +691,18 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In
|
|||
return;
|
||||
}
|
||||
|
||||
// mark the nodes
|
||||
if ( vBold )
|
||||
Gia_ManForEachObjVec( vBold, p, pNode, i )
|
||||
pNode->fMark0 = 1;
|
||||
|
||||
// compute levels
|
||||
LevelMax = 1 + p->nLevels;
|
||||
Gia_ManForEachCo( p, pNode, i )
|
||||
Vec_IntWriteEntry( p->vLevels, Gia_ObjId(p, pNode), LevelMax );
|
||||
|
||||
// write the DOT header
|
||||
fprintf( pFile, "# %s\n", "AIG structure generated by IVY package" );
|
||||
fprintf( pFile, "# %s\n", "AIG structure generated by GIA package" );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, "digraph AIG {\n" );
|
||||
fprintf( pFile, "size = \"7.5,10\";\n" );
|
||||
|
|
@ -479,7 +776,8 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In
|
|||
fprintf( pFile, " fontsize=18,\n" );
|
||||
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
|
||||
fprintf( pFile, " label=\"" );
|
||||
fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Gia_ManAndNum(p), LevelMax );
|
||||
fprintf( pFile, "The AIG contains %d nodes, %d full-adders, and %d half-adders, and spans %d levels.",
|
||||
Gia_ManAndNum(p), nFadds, Vec_IntSize(vAdds)/6-nFadds, LevelMax-1 );
|
||||
fprintf( pFile, "\\n" );
|
||||
fprintf( pFile, "\"\n" );
|
||||
fprintf( pFile, " ];\n" );
|
||||
|
|
@ -528,7 +826,7 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In
|
|||
else
|
||||
fprintf( pFile, ", shape = ellipse" );
|
||||
*/
|
||||
if ( Vec_IntEntry(vMapAdds, iNode) >= 0 )
|
||||
if ( !pNode->fMark0 && Vec_IntEntry(vMapAdds, iNode) >= 0 )
|
||||
{
|
||||
int iBox = Vec_IntEntry(vMapAdds, iNode);
|
||||
fprintf( pFile, " Node%d [label = \"%d_%d\"", Gia_ShowAddOut(vAdds, vMapAdds, iNode), Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) );
|
||||
|
|
@ -557,8 +855,8 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In
|
|||
fprintf( pFile, " Node%d [label = \"%d\"", iNode, iNode );
|
||||
fprintf( pFile, ", shape = ellipse" );
|
||||
}
|
||||
// if ( pNode->fMark0 )
|
||||
// fprintf( pFile, ", style = filled" );
|
||||
if ( pNode->fMark0 )
|
||||
fprintf( pFile, ", style = filled" );
|
||||
fprintf( pFile, "];\n" );
|
||||
}
|
||||
fprintf( pFile, "}" );
|
||||
|
|
@ -629,8 +927,6 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In
|
|||
Gia_ManForEachObjVec( vOrder, p, pNode, i )
|
||||
{
|
||||
int iNode = Gia_ObjId( p, pNode );
|
||||
// if ( !Gia_ObjIsAnd(pNode) && !Gia_ObjIsCo(pNode) && !Gia_ObjIsBuf(pNode) )
|
||||
// continue;
|
||||
if ( Vec_IntEntry(vMapAdds, Gia_ObjId(p, pNode)) >= 0 )
|
||||
{
|
||||
int k, iBox = Vec_IntEntry(vMapAdds, iNode);
|
||||
|
|
@ -699,6 +995,11 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In
|
|||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
|
||||
// unmark nodes
|
||||
if ( vBold )
|
||||
Gia_ManForEachObjVec( vBold, p, pNode, i )
|
||||
pNode->fMark0 = 0;
|
||||
|
||||
Vec_IntFreeP( &p->vLevels );
|
||||
}
|
||||
|
||||
|
|
@ -713,14 +1014,23 @@ void Gia_WriteDotAig( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_In
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds )
|
||||
Vec_Int_t * Gia_ShowMapAdds( Gia_Man_t * p, Vec_Int_t * vAdds, int fFadds, Vec_Int_t * vBold )
|
||||
{
|
||||
Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i;
|
||||
Vec_Bit_t * vIsBold = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vMapAdds = Vec_IntStartFull( Gia_ManObjNum(p) ); int i, Entry;
|
||||
if ( vBold )
|
||||
Vec_IntForEachEntry( vBold, Entry, i )
|
||||
Vec_BitWriteEntry( vIsBold, Entry, 1 );
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
if ( fFadds && Vec_IntEntry(vAdds, 6*i+2) == 0 )
|
||||
continue;
|
||||
if ( Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIsBold, Vec_IntEntry(vAdds, 6*i+4)) )
|
||||
continue;
|
||||
Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+3), i );
|
||||
Vec_IntWriteEntry( vMapAdds, Vec_IntEntry(vAdds, 6*i+4), i );
|
||||
}
|
||||
Vec_BitFree( vIsBold );
|
||||
return vMapAdds;
|
||||
}
|
||||
Vec_Int_t * Gia_ShowMapXors( Gia_Man_t * p, Vec_Int_t * vXors )
|
||||
|
|
@ -800,34 +1110,23 @@ Vec_Int_t * Gia_ShowCollectObjs( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * v
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vAdds, Vec_Int_t * vXors )
|
||||
void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_Int_t * vAdds, Vec_Int_t * vXors, int fFadds )
|
||||
{
|
||||
Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds );
|
||||
Vec_Int_t * vMapAdds = Gia_ShowMapAdds( p, vAdds, fFadds, vBold );
|
||||
Vec_Int_t * vMapXors = Gia_ShowMapXors( p, vXors );
|
||||
Vec_Int_t * vOrder = Gia_ShowCollectObjs( p, vAdds, vXors, vMapAdds, vMapXors );
|
||||
Gia_WriteDotAig( p, pFileName, vAdds, vXors, vMapAdds, vMapXors, vOrder );
|
||||
Gia_WriteDotAig( p, pFileName, vBold, vAdds, vXors, vMapAdds, vMapXors, vOrder );
|
||||
Vec_IntFree( vMapAdds );
|
||||
Vec_IntFree( vMapXors );
|
||||
Vec_IntFree( vOrder );
|
||||
}
|
||||
void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders )
|
||||
void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath )
|
||||
{
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
|
||||
extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
|
||||
extern void Abc_ShowFile( char * FileNameDot );
|
||||
static int Counter = 0;
|
||||
char FileNameDot[200];
|
||||
FILE * pFile;
|
||||
|
||||
Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( pMan, &vXors, 0 );
|
||||
Ree_ManRemoveTrivial( pMan, vAdds );
|
||||
Ree_ManRemoveContained( pMan, vAdds );
|
||||
|
||||
// create the file name
|
||||
// Gia_ShowGetFileName( pMan->pName, FileNameDot );
|
||||
sprintf( FileNameDot, "temp%02d.dot", Counter++ );
|
||||
Vec_Int_t * vXors = NULL, * vAdds = fAdders ? Ree_ManComputeCuts( pMan, &vXors, 0 ) : NULL;
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
|
||||
// check that the file can be opened
|
||||
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
|
||||
{
|
||||
|
|
@ -836,15 +1135,17 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders )
|
|||
}
|
||||
fclose( pFile );
|
||||
// generate the file
|
||||
if ( fAdders )
|
||||
Gia_ShowProcess( pMan, FileNameDot, vAdds, vXors );
|
||||
if ( fPath )
|
||||
Gia_ShowPath( pMan, FileNameDot );
|
||||
else if ( fAdders )
|
||||
Gia_ShowProcess( pMan, FileNameDot, vBold, vAdds, vXors, fFadds );
|
||||
else
|
||||
Gia_WriteDotAigSimple( pMan, FileNameDot, vBold );
|
||||
// visualize the file
|
||||
Abc_ShowFile( FileNameDot );
|
||||
|
||||
Vec_IntFree( vAdds );
|
||||
Vec_IntFree( vXors );
|
||||
Vec_IntFreeP( &vAdds );
|
||||
Vec_IntFreeP( &vXors );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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.]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ static int Abc_CommandAbc9Fadds ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Decla ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -1124,6 +1126,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "ABC9", "&atree", Abc_CommandAbc9ATree, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&decla", Abc_CommandAbc9Decla, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 );
|
||||
|
|
@ -19532,7 +19536,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
if ( Abc_NtkIsComb(pNtk) )
|
||||
{
|
||||
Abc_Print( -1, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" );
|
||||
Abc_Print( 0, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -28592,15 +28596,21 @@ usage:
|
|||
int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Vec_Int_t * vBold = NULL;
|
||||
int c, fAdders = 0;
|
||||
int c, fAdders = 0, fFadds = 0, fPath = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "afph" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'a':
|
||||
fAdders ^= 1;
|
||||
break;
|
||||
case 'f':
|
||||
fFadds ^= 1;
|
||||
break;
|
||||
case 'p':
|
||||
fPath ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
|
|
@ -28623,14 +28633,16 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Gia_ManForEachLut( pAbc->pGia, c )
|
||||
Vec_IntPush( vBold, c );
|
||||
}
|
||||
Gia_ManShow( pAbc->pGia, vBold, fAdders );
|
||||
Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds, fPath );
|
||||
Vec_IntFreeP( &vBold );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &show [-ah]\n" );
|
||||
Abc_Print( -2, "usage: &show [-afph]\n" );
|
||||
Abc_Print( -2, "\t shows the current GIA using GSView\n" );
|
||||
Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" );
|
||||
Abc_Print( -2, "\t-f : toggle showing only full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" );
|
||||
Abc_Print( -2, "\t-p : toggle showing the critical path of a LUT mapping [default = %s]\n", fPath? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -31954,7 +31966,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
if ( Gia_ManRegNum(pAbc->pGia) == 0 )
|
||||
{
|
||||
Abc_Print( -1, "The network is combinational.\n" );
|
||||
Abc_Print( 0, "The network is combinational.\n" );
|
||||
return 0;
|
||||
}
|
||||
pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars );
|
||||
|
|
@ -32915,8 +32927,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
{
|
||||
Cec_ParCec_t ParsCec, * pPars = &ParsCec;
|
||||
FILE * pFile;
|
||||
Gia_Man_t * pSecond, * pMiter;
|
||||
char * FileName, * pTemp;
|
||||
Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter;
|
||||
char ** pArgvNew;
|
||||
int c, nArgcNew, fMiter = 0, fDualOutput = 0, fDumpMiter = 0;
|
||||
Cec_ManCecSetDefaultParams( pPars );
|
||||
|
|
@ -32971,13 +32982,15 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no AIG.\n" );
|
||||
return 1;
|
||||
}
|
||||
pArgvNew = argv + globalUtilOptind;
|
||||
nArgcNew = argc - globalUtilOptind;
|
||||
if ( fMiter )
|
||||
{
|
||||
if ( pAbc->pGia == NULL || nArgcNew != 0 )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Cec(): A miter cannot be given as an argument of command &cec and should be entered using &r.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( fDualOutput )
|
||||
{
|
||||
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
|
||||
|
|
@ -32986,14 +32999,14 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
if ( !pPars->fSilent )
|
||||
Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
|
||||
Abc_Print( 1, "Assuming the current network is a double-output miter.\n" );
|
||||
pAbc->Status = Cec_ManVerify( pAbc->pGia, pPars );
|
||||
}
|
||||
else
|
||||
{
|
||||
Gia_Man_t * pTemp;
|
||||
if ( !pPars->fSilent )
|
||||
Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
|
||||
Abc_Print( 1, "Assuming the current network is a single-output miter.\n" );
|
||||
pTemp = Gia_ManDemiterToDual( pAbc->pGia );
|
||||
pAbc->Status = Cec_ManVerify( pTemp, pPars );
|
||||
ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb );
|
||||
|
|
@ -33002,41 +33015,81 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
|
||||
return 0;
|
||||
}
|
||||
|
||||
pArgvNew = argv + globalUtilOptind;
|
||||
nArgcNew = argc - globalUtilOptind;
|
||||
if ( nArgcNew != 1 )
|
||||
if ( nArgcNew > 2 )
|
||||
{
|
||||
if ( pAbc->pGia->pSpec == NULL )
|
||||
{
|
||||
Abc_Print( -1, "File name is not given on the command line.\n" );
|
||||
return 1;
|
||||
}
|
||||
FileName = pAbc->pGia->pSpec;
|
||||
}
|
||||
else
|
||||
FileName = pArgvNew[0];
|
||||
// fix the wrong symbol
|
||||
for ( pTemp = FileName; *pTemp; pTemp++ )
|
||||
if ( *pTemp == '>' )
|
||||
*pTemp = '\\';
|
||||
if ( (pFile = fopen( FileName, "r" )) == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
|
||||
if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
|
||||
Abc_Print( 1, "Did you mean \"%s\"?", FileName );
|
||||
Abc_Print( 1, "\n" );
|
||||
Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" );
|
||||
return 1;
|
||||
}
|
||||
fclose( pFile );
|
||||
pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
|
||||
if ( pSecond == NULL )
|
||||
if ( nArgcNew == 2 )
|
||||
{
|
||||
Abc_Print( -1, "Reading AIGER has failed.\n" );
|
||||
return 0;
|
||||
char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp;
|
||||
int n;
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
// fix the wrong symbol
|
||||
for ( pTemp = pFileNames[n]; *pTemp; pTemp++ )
|
||||
if ( *pTemp == '>' )
|
||||
*pTemp = '\\';
|
||||
if ( (pFile = fopen( pFileNames[n], "r" )) == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] );
|
||||
if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) )
|
||||
Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] );
|
||||
Abc_Print( 1, "\n" );
|
||||
return 1;
|
||||
}
|
||||
fclose( pFile );
|
||||
pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 );
|
||||
if ( pGias[n] == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char * FileName, * pTemp;
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" );
|
||||
return 1;
|
||||
}
|
||||
pGias[0] = pAbc->pGia;
|
||||
if ( nArgcNew == 1 )
|
||||
FileName = pArgvNew[0];
|
||||
else
|
||||
{
|
||||
assert( nArgcNew == 0 );
|
||||
if ( pAbc->pGia->pSpec == NULL )
|
||||
{
|
||||
Abc_Print( -1, "File name is not given on the command line.\n" );
|
||||
return 1;
|
||||
}
|
||||
FileName = pAbc->pGia->pSpec;
|
||||
}
|
||||
// fix the wrong symbol
|
||||
for ( pTemp = FileName; *pTemp; pTemp++ )
|
||||
if ( *pTemp == '>' )
|
||||
*pTemp = '\\';
|
||||
if ( (pFile = fopen( FileName, "r" )) == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
|
||||
if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
|
||||
Abc_Print( 1, "Did you mean \"%s\"?", FileName );
|
||||
Abc_Print( 1, "\n" );
|
||||
return 1;
|
||||
}
|
||||
fclose( pFile );
|
||||
pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 );
|
||||
if ( pGias[1] == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Reading AIGER has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// compute the miter
|
||||
pMiter = Gia_ManMiter( pAbc->pGia, pSecond, 0, 1, 0, 0, pPars->fVerbose );
|
||||
pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, 1, 0, 0, pPars->fVerbose );
|
||||
if ( pMiter )
|
||||
{
|
||||
if ( fDumpMiter )
|
||||
|
|
@ -33045,10 +33098,12 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0 );
|
||||
}
|
||||
pAbc->Status = Cec_ManVerify( pMiter, pPars );
|
||||
Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
|
||||
Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
|
||||
Gia_ManStop( pMiter );
|
||||
}
|
||||
Gia_ManStop( pSecond );
|
||||
if ( pGias[0] != pAbc->pGia )
|
||||
Gia_ManStop( pGias[0] );
|
||||
Gia_ManStop( pGias[1] );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
@ -36166,7 +36221,7 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &satlut [-NICDQ num] [-drwvh]\n" );
|
||||
Abc_Print( -2, "\t performs SAT-based remapping of the 4-LUT network\n" );
|
||||
Abc_Print( -2, "\t performs SAT-based remapping of the LUT-mapped network\n" );
|
||||
Abc_Print( -2, "\t-N num : the limit on AIG nodes in the window (num <= 128) [default = %d]\n", nNumber );
|
||||
Abc_Print( -2, "\t-I num : the limit on the number of improved windows [default = %d]\n", nImproves );
|
||||
Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nBTLimit );
|
||||
|
|
@ -40528,14 +40583,12 @@ usage:
|
|||
int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pFile;
|
||||
Cec_ParCec_t ParsCec, * pPars = &ParsCec;
|
||||
Gia_Man_t * pSecond;
|
||||
char * FileName, * pTemp;
|
||||
Acec_ParCec_t ParsCec, * pPars = &ParsCec;
|
||||
char ** pArgvNew;
|
||||
int c, nArgcNew, fMiter = 0, fDualOutput = 0, fTwoOutput = 0;
|
||||
Cec_ManCecSetDefaultParams( pPars );
|
||||
int c, nArgcNew;
|
||||
Acec_ManCecSetDefaultParams( pPars );
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdtvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtbvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -40561,17 +40614,17 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pPars->TimeLimit < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'n':
|
||||
pPars->fNaive ^= 1;
|
||||
break;
|
||||
case 'm':
|
||||
fMiter ^= 1;
|
||||
pPars->fMiter ^= 1;
|
||||
break;
|
||||
case 'd':
|
||||
fDualOutput ^= 1;
|
||||
pPars->fDualOutput ^= 1;
|
||||
break;
|
||||
case 't':
|
||||
fTwoOutput ^= 1;
|
||||
pPars->fTwoOutput ^= 1;
|
||||
break;
|
||||
case 'b':
|
||||
pPars->fBooth ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
pPars->fVerbose ^= 1;
|
||||
|
|
@ -40582,15 +40635,20 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( fMiter )
|
||||
if ( pPars->fMiter )
|
||||
{
|
||||
Gia_Man_t * pGia0, * pGia1, * pDual;
|
||||
if ( argc != globalUtilOptind )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Acec(): If the input is a miter, it cannot be given on the command line.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Acec(): There is no AIG.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( fDualOutput )
|
||||
if ( pPars->fDualOutput )
|
||||
{
|
||||
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
|
||||
{
|
||||
|
|
@ -40600,28 +40658,28 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( !pPars->fSilent )
|
||||
Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
|
||||
Gia_ManDemiterDual( pAbc->pGia, &pGia0, &pGia1 );
|
||||
pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
|
||||
pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
|
||||
}
|
||||
else if ( fTwoOutput )
|
||||
else if ( pPars->fTwoOutput )
|
||||
{
|
||||
if ( Gia_ManPoNum(pAbc->pGia) & 1 )
|
||||
{
|
||||
Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" );
|
||||
Abc_Print( -1, "The two-output miter should have an even number of outputs.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !pPars->fSilent )
|
||||
Abc_Print( 1, "Assuming the current network is a two-word miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
|
||||
Gia_ManDemiterTwoWords( pAbc->pGia, &pGia0, &pGia1 );
|
||||
pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
|
||||
pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
|
||||
}
|
||||
else
|
||||
else // regular single- or multi-output miter
|
||||
{
|
||||
if ( !pPars->fSilent )
|
||||
Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
|
||||
Abc_Print( 1, "Assuming the current network is a regular single- or multi-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
|
||||
pDual = Gia_ManDemiterToDual( pAbc->pGia );
|
||||
Gia_ManDemiterDual( pDual, &pGia0, &pGia1 );
|
||||
Gia_ManStop( pDual );
|
||||
pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
|
||||
pAbc->Status = Acec_Solve( pGia0, pGia1, pPars );
|
||||
}
|
||||
Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb );
|
||||
Gia_ManStop( pGia0 );
|
||||
|
|
@ -40631,55 +40689,201 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
pArgvNew = argv + globalUtilOptind;
|
||||
nArgcNew = argc - globalUtilOptind;
|
||||
if ( nArgcNew != 1 )
|
||||
if ( nArgcNew == 0 || nArgcNew == 1 )
|
||||
{
|
||||
if ( pAbc->pGia->pSpec == NULL )
|
||||
Gia_Man_t * pSecond;
|
||||
char * pTemp, * FileName = NULL;
|
||||
if ( nArgcNew == 0 )
|
||||
{
|
||||
Abc_Print( -1, "File name is not given on the command line.\n" );
|
||||
return 1;
|
||||
FileName = pAbc->pGia->pSpec;
|
||||
if ( FileName == NULL )
|
||||
{
|
||||
Abc_Print( -1, "File name is not given on the command line.\n" );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
FileName = pAbc->pGia->pSpec;
|
||||
else // if ( nArgcNew == 1 )
|
||||
{
|
||||
FileName = pArgvNew[0];
|
||||
// fix the wrong symbol
|
||||
for ( pTemp = FileName; *pTemp; pTemp++ )
|
||||
if ( *pTemp == '>' )
|
||||
*pTemp = '\\';
|
||||
if ( (pFile = fopen( FileName, "r" )) == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
|
||||
if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
|
||||
Abc_Print( 1, "Did you mean \"%s\"?", FileName );
|
||||
Abc_Print( 1, "\n" );
|
||||
return 1;
|
||||
}
|
||||
fclose( pFile );
|
||||
}
|
||||
pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
|
||||
if ( pSecond == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Reading AIGER has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
pAbc->Status = Acec_Solve( pAbc->pGia, pSecond, pPars );
|
||||
Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
|
||||
Gia_ManStop( pSecond );
|
||||
}
|
||||
else if ( nArgcNew == 2 )
|
||||
{
|
||||
Gia_Man_t * pGias[2] = {NULL}; int i;
|
||||
char * pTemp, * FileName[2] = { pArgvNew[0], pArgvNew[1] };
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
// fix the wrong symbol
|
||||
for ( pTemp = FileName[i]; *pTemp; pTemp++ )
|
||||
if ( *pTemp == '>' )
|
||||
*pTemp = '\\';
|
||||
if ( (pFile = fopen( FileName[i], "r" )) == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Cannot open input file \"%s\". ", FileName[i] );
|
||||
if ( (FileName[i] = Extra_FileGetSimilarName( FileName[i], ".aig", NULL, NULL, NULL, NULL )) )
|
||||
Abc_Print( 1, "Did you mean \"%s\"?", FileName[i] );
|
||||
Abc_Print( 1, "\n" );
|
||||
return 1;
|
||||
}
|
||||
fclose( pFile );
|
||||
pGias[i] = Gia_AigerRead( FileName[i], 0, 0, 0 );
|
||||
if ( pGias[i] == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Reading AIGER has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pAbc->Status = Acec_Solve( pGias[0], pGias[1], pPars );
|
||||
Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb );
|
||||
Gia_ManStop( pGias[0] );
|
||||
Gia_ManStop( pGias[1] );
|
||||
}
|
||||
else
|
||||
FileName = pArgvNew[0];
|
||||
// fix the wrong symbol
|
||||
for ( pTemp = FileName; *pTemp; pTemp++ )
|
||||
if ( *pTemp == '>' )
|
||||
*pTemp = '\\';
|
||||
if ( (pFile = fopen( FileName, "r" )) == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
|
||||
if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
|
||||
Abc_Print( 1, "Did you mean \"%s\"?", FileName );
|
||||
Abc_Print( 1, "\n" );
|
||||
Abc_Print( -1, "Too many command-line arguments.\n" );
|
||||
return 1;
|
||||
}
|
||||
fclose( pFile );
|
||||
pSecond = Gia_AigerRead( FileName, 0, 0, 0 );
|
||||
if ( pSecond == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Reading AIGER has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
pAbc->Status = Gia_PolynCec( pAbc->pGia, pSecond, pPars );
|
||||
Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
|
||||
Gia_ManStop( pSecond );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &acec [-CT num] [-nmdtvh]\n" );
|
||||
Abc_Print( -2, "usage: &acec [-CT num] [-mdtbvh] <file1> <file2>\n" );
|
||||
Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" );
|
||||
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
|
||||
Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit );
|
||||
Abc_Print( -2, "\t-n : toggle using naive SAT-based checking [default = %s]\n", pPars->fNaive? "yes":"no");
|
||||
Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits");
|
||||
Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no");
|
||||
Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", fTwoOutput? "yes":"no");
|
||||
Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits");
|
||||
Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no");
|
||||
Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no");
|
||||
Abc_Print( -2, "\t-b : toggle working with Booth multipliers [default = %s]\n", pPars->fBooth? "yes":"no");
|
||||
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n");
|
||||
Abc_Print( -2, "\tfile2 : (optional) the file with the second network\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Gia_Man_t * pTemp;
|
||||
int c, fBooth = 0, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'b':
|
||||
fBooth ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" );
|
||||
return 0;
|
||||
}
|
||||
pTemp = Acec_Normalize( pAbc->pGia, fBooth, fVerbose );
|
||||
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &anorm [-bvh]\n" );
|
||||
Abc_Print( -2, "\t normalize adder trees in the current AIG\n" );
|
||||
Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandAbc9Decla( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Gia_Man_t * pTemp;
|
||||
int c, fBooth = 0, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'b':
|
||||
fBooth ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Decla(): There is no AIG.\n" );
|
||||
return 0;
|
||||
}
|
||||
pTemp = Acec_ManDecla( pAbc->pGia, fBooth, fVerbose );
|
||||
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &decla [-bvh]\n" );
|
||||
Abc_Print( -2, "\t removes carry look ahead adders\n" );
|
||||
Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -41006,7 +41210,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Sbd_Par_t Pars, * pPars = &Pars;
|
||||
Sbd_ParSetDefault( pPars );
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KWFMCacvwh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCmcdpvwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -41021,6 +41225,39 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pPars->nLutSize < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'S':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nLutNum = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nLutNum < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nCutSize = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nCutSize < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'P':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nCutNum = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nCutNum < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'W':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
|
|
@ -41065,11 +41302,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pPars->nBTLimit < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'a':
|
||||
pPars->fArea ^= 1;
|
||||
case 'm':
|
||||
pPars->fMapping ^= 1;
|
||||
break;
|
||||
case 'c':
|
||||
pPars->fCover ^= 1;
|
||||
pPars->fMoreCuts ^= 1;
|
||||
break;
|
||||
case 'd':
|
||||
pPars->fFindDivs ^= 1;
|
||||
break;
|
||||
case 'p':
|
||||
pPars->fUsePath ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
pPars->fVerbose ^= 1;
|
||||
|
|
@ -41085,33 +41328,35 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Mfs(): There is no AIG.\n" );
|
||||
Abc_Print( -1, "Abc_CommandAbc9Mfsd(): There is no AIG.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Gia_ManBufNum(pAbc->pGia) )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Mfs(): This command does not work with barrier buffers.\n" );
|
||||
Abc_Print( -1, "Abc_CommandAbc9Mfsd(): This command does not work with barrier buffers.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Gia_ManHasMapping(pAbc->pGia) )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has mapping (run &st to unmap).\n" );
|
||||
return 0;
|
||||
}
|
||||
Abc_Print( 1, "The current AIG has mapping, which can be used to determine critical path if \"-p\" is selected.\n" );
|
||||
pTemp = Sbd_NtkPerform( pAbc->pGia, pPars );
|
||||
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &mfsd [-KWFMC <num>] [-acvwh]\n" );
|
||||
Abc_Print( -2, "usage: &mfsd [-KSNPWFMC <num>] [-mcdpvwh]\n" );
|
||||
Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" );
|
||||
Abc_Print( -2, "\t-K <num> : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize );
|
||||
Abc_Print( -2, "\t-S <num> : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum );
|
||||
Abc_Print( -2, "\t-N <num> : the cut size considered for optimization (2 <= num <= 10) [default = %d]\n", pPars->nCutSize );
|
||||
Abc_Print( -2, "\t-P <num> : the number of cuts computed at a node (1 <= num <= 500) [default = %d]\n", pPars->nCutNum );
|
||||
Abc_Print( -2, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels );
|
||||
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax );
|
||||
Abc_Print( -2, "\t-M <num> : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax );
|
||||
Abc_Print( -2, "\t-C <num> : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit );
|
||||
Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" );
|
||||
Abc_Print( -2, "\t-c : toggle using complete slow covering procedure [default = %s]\n", pPars->fCover? "yes": "no" );
|
||||
Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "yes": "no" );
|
||||
Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" );
|
||||
Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" );
|
||||
Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
|
|
@ -42541,8 +42786,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
// Jf_ManTestCnf( pAbc->pGia );
|
||||
// Gia_ManCheckFalseTest( pAbc->pGia, nFrames );
|
||||
// Gia_ParTest( pAbc->pGia, nWords, nProcs );
|
||||
// Gia_PolynExplore( pAbc->pGia );
|
||||
// Gia_ManTestSatEnum( pAbc->pGia );
|
||||
|
||||
// printf( "\nThis command is currently disabled.\n\n" );
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -1147,26 +1147,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*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,66 @@ 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 interpolant.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs )
|
||||
{
|
||||
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_Obj_t * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) );
|
||||
char * pName, * pCube, * pSop = (char *)pNode->pData;
|
||||
Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) );
|
||||
Abc_Obj_t * pFanin; int i, k, Value, nLits;
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
{
|
||||
assert( Abc_ObjIsCi(pFanin) );
|
||||
pName = Abc_ObjName(pFanin);
|
||||
for ( k = (int)strlen(pName)-1; k >= 0; k-- )
|
||||
if ( pName[k] < '0' || pName[k] > '9' )
|
||||
break;
|
||||
if ( k == (int)strlen(pName)-1 )
|
||||
{
|
||||
printf( "Cannot read input name of fanin %d.\n", i );
|
||||
Value = i;
|
||||
}
|
||||
else
|
||||
Value = atoi(pName + k + 1);
|
||||
Vec_IntPush( vFanins, Value );
|
||||
}
|
||||
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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
@ -1509,7 +1545,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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,18 +32,21 @@ static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
|||
static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; }
|
||||
static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); }
|
||||
static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; }
|
||||
|
||||
static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; }
|
||||
static inline Vec_Int_t * Wlc_AbcGetCnf( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcCnf; }
|
||||
static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcStr; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -66,10 +69,15 @@ void Wlc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 );
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
|
@ -429,122 +437,6 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose );
|
||||
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandPsInv(): There is no current design.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Wlc_AbcGetNtk(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandPsInv(): There is no saved invariant.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Wlc_AbcGetInv(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandPsInv(): Invariant is not available.\n" );
|
||||
return 0;
|
||||
}
|
||||
Wlc_NtkPrintInvStats( pNtk, Wlc_AbcGetInv(pAbc), fVerbose );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: %%psinv [-vh]\n" );
|
||||
Abc_Print( -2, "\t prints statistics for inductive invariant\n" );
|
||||
Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\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 []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose );
|
||||
Abc_Ntk_t * pMainNtk;
|
||||
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandGetInv(): There is no current design.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Wlc_AbcGetNtk(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandGetInv(): There is no saved invariant.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Wlc_AbcGetInv(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandGetInv(): Invariant is not available.\n" );
|
||||
return 0;
|
||||
}
|
||||
// derive the network
|
||||
pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), Wlc_AbcGetStr(pAbc), fVerbose );
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: %%getinv [-vh]\n" );
|
||||
Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" );
|
||||
Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\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 []
|
||||
|
|
@ -641,6 +533,326 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandInvPs( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
|
||||
extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose );
|
||||
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
|
||||
Vec_Int_t * vCounts;
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvPs(): There is no current design.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Wlc_AbcGetInv(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" );
|
||||
return 0;
|
||||
}
|
||||
vCounts = Pdr_InvCounts( Wlc_AbcGetInv(pAbc) );
|
||||
Wlc_NtkPrintInvStats( pNtk, vCounts, fVerbose );
|
||||
Vec_IntFree( vCounts );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: inv_ps [-vh]\n" );
|
||||
Abc_Print( -2, "\t prints statistics for inductive invariant\n" );
|
||||
Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\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 []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Pdr_InvPrint( Vec_Int_t * vInv );
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( Wlc_AbcGetInv(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" );
|
||||
return 0;
|
||||
}
|
||||
Pdr_InvPrint( Wlc_AbcGetInv(pAbc) );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: inv_print [-vh]\n" );
|
||||
Abc_Print( -2, "\t prints the current inductive invariant\n" );
|
||||
Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\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 []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Vec_Int_t * Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv );
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Wlc_AbcGetInv(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvMin(): There is no saved invariant.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(Wlc_AbcGetInv(pAbc)) )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" );
|
||||
return 0;
|
||||
}
|
||||
Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: inv_check [-vh]\n" );
|
||||
Abc_Print( -2, "\t checks that the invariant is indeed an inductive invariant\n" );
|
||||
Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\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 []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv );
|
||||
Abc_Ntk_t * pMainNtk;
|
||||
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( Wlc_AbcGetInv(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" );
|
||||
return 0;
|
||||
}
|
||||
// derive the network
|
||||
pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) );
|
||||
// replace the current network
|
||||
if ( pMainNtk )
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: inv_get [-vh]\n" );
|
||||
Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" );
|
||||
Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\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 []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs );
|
||||
Vec_Int_t * vInv = NULL;
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvPut(): There is no current design.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvPut(): There is no current AIG.\n" );
|
||||
return 0;
|
||||
}
|
||||
// derive the network
|
||||
vInv = Wlc_NtkGetPut( pNtk, Gia_ManRegNum(pAbc->pGia) );
|
||||
if ( vInv )
|
||||
Abc_FrameSetInv( vInv );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: inv_put [-vh]\n" );
|
||||
Abc_Print( -2, "\t inputs the current network in the main-space as an invariant\n" );
|
||||
Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\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 []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv );
|
||||
Vec_Int_t * vInv, * vInv2;
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Wlc_AbcGetInv(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvMin(): Invariant is not available.\n" );
|
||||
return 0;
|
||||
}
|
||||
vInv = Wlc_AbcGetInv(pAbc);
|
||||
if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(vInv) )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" );
|
||||
return 0;
|
||||
}
|
||||
vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv );
|
||||
if ( vInv2 )
|
||||
Abc_FrameSetInv( vInv2 );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: inv_min [-vh]\n" );
|
||||
Abc_Print( -2, "\t minimizes the number of clauses in the current invariant\n" );
|
||||
Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ); }
|
||||
|
|
|
|||
|
|
@ -2612,7 +2612,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 +2634,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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p )
|
|||
break;
|
||||
}
|
||||
Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) );
|
||||
Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan1)) : Gia_ObjId(p, Gia_Regular(pFan0)) );
|
||||
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)) );
|
||||
}
|
||||
|
|
@ -173,10 +173,101 @@ int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf )
|
|||
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;
|
||||
|
|
@ -215,18 +306,10 @@ Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet )
|
|||
***********************************************************************/
|
||||
Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
|
||||
extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
|
||||
extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, 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_ManRemoveTrivial( p, vAdds );
|
||||
// Ree_ManRemoveContained( p, vAdds );
|
||||
|
||||
//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 );
|
||||
|
|
@ -236,6 +319,8 @@ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose )
|
|||
vRootXorSet = Acec_CollectXorTops( p );
|
||||
if ( vRootXorSet )
|
||||
{
|
||||
Acec_DetectComputeSupports( p, vRootXorSet );
|
||||
|
||||
pNew = Acec_DetectXorBuildNew( p, vRootXorSet );
|
||||
Vec_IntFree( vRootXorSet );
|
||||
}
|
||||
|
|
@ -250,6 +335,107 @@ Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose )
|
|||
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,472 @@ 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;
|
||||
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)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -54,10 +64,25 @@ 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 );
|
||||
/*=== 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 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 );
|
||||
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,550 @@
|
|||
/**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 []
|
||||
|
||||
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] )
|
||||
{
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -303,17 +303,9 @@ void Acec_ManPrintRanks( Vec_Int_t * vPairs )
|
|||
***********************************************************************/
|
||||
void Acec_ManProfile( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
|
||||
extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
|
||||
extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
|
||||
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Wec_t * vBoxes; int i;
|
||||
Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, fVerbose );
|
||||
Ree_ManRemoveTrivial( p, vAdds );
|
||||
Ree_ManRemoveContained( p, vAdds );
|
||||
|
||||
//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 );
|
||||
|
|
@ -396,13 +388,6 @@ Vec_Int_t * Acec_ManPoolTopMost( Gia_Man_t * p, Vec_Int_t * vAdds )
|
|||
}
|
||||
void Acec_ManPool( Gia_Man_t * p )
|
||||
{
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
|
||||
extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes );
|
||||
|
||||
extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
|
||||
extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
|
||||
extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
Vec_Int_t * vTops, * vTree;
|
||||
Vec_Wec_t * vTrees;
|
||||
|
||||
|
|
@ -413,8 +398,6 @@ void Acec_ManPool( Gia_Man_t * p )
|
|||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
||||
clk = Abc_Clock();
|
||||
Ree_ManRemoveTrivial( p, vAdds );
|
||||
Ree_ManRemoveContained( p, vAdds );
|
||||
nFadds = Ree_ManCountFadds( vAdds );
|
||||
printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ static inline int Ree_ManCutFind( int iObj, int * pCut )
|
|||
}
|
||||
static inline int Ree_ManCutNotFind( int iObj1, int iObj2, int * pCut )
|
||||
{
|
||||
assert( pCut[0] == 3 );
|
||||
if ( pCut[3] != iObj1 && pCut[3] != iObj2 ) return 0;
|
||||
if ( pCut[2] != iObj1 && pCut[2] != iObj2 ) return 1;
|
||||
if ( pCut[1] != iObj1 && pCut[1] != iObj2 ) return 2;
|
||||
|
|
@ -162,13 +163,19 @@ static inline int Ree_ManCutTruthOne( int * pCut0, int * pCut )
|
|||
Truth0 = fComp0 ? ~Truth0 : Truth0;
|
||||
if ( pCut0[0] == 2 )
|
||||
{
|
||||
int Truths[3][8] = {
|
||||
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-}
|
||||
{ 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1}
|
||||
{ 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1}
|
||||
};
|
||||
int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7];
|
||||
return 0xFF & (fComp0 ? ~Truth : Truth);
|
||||
if ( pCut[0] == 3 )
|
||||
{
|
||||
int Truths[3][8] = {
|
||||
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-}
|
||||
{ 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1}
|
||||
{ 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1}
|
||||
};
|
||||
int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7];
|
||||
return 0xFF & (fComp0 ? ~Truth : Truth);
|
||||
}
|
||||
assert( pCut[0] == 2 );
|
||||
assert( pCut[1] == pCut0[1] && pCut[2] == pCut0[2] );
|
||||
return pCut0[pCut0[0]+1];
|
||||
}
|
||||
if ( pCut0[0] == 1 )
|
||||
{
|
||||
|
|
@ -236,10 +243,10 @@ int Ree_ObjComputeTruth( Gia_Man_t * p, int iObj, int * pCut )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ree_ManCutPrint( int * pCut, int Count, word Truth )
|
||||
void Ree_ManCutPrint( int * pCut, int Count, word Truth, int iObj )
|
||||
{
|
||||
int c;
|
||||
printf( "%d : ", Count );
|
||||
printf( "%d : %d : ", Count, iObj );
|
||||
for ( c = 1; c <= pCut[0]; c++ )
|
||||
printf( "%3d ", pCut[c] );
|
||||
for ( ; c <= 4; c++ )
|
||||
|
|
@ -290,7 +297,7 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I
|
|||
Vec_IntPushThree( vData, iObj, Value, TruthC );
|
||||
}
|
||||
if ( fVerbose )
|
||||
Ree_ManCutPrint( pCut, ++Count, TruthC );
|
||||
Ree_ManCutPrint( pCut, ++Count, TruthC, iObj );
|
||||
}
|
||||
if ( !vXors )
|
||||
return;
|
||||
|
|
@ -370,7 +377,7 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos
|
|||
Vec_IntForEachEntryDouble( vXorOne, iObj, Truth, j )
|
||||
Vec_IntForEachEntryDouble( vMajOne, iObj2, Truth2, k )
|
||||
{
|
||||
int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0xEE, 0xDD, 0xBB, 0x77};
|
||||
int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0x77, 0xBB, 0xDD, 0xEE};
|
||||
int SignMaj[8] = {0xE8, 0xD4, 0xB2, 0x71, 0x8E, 0x4D, 0x2B, 0x17};
|
||||
int n, SignXor = (Truth == 0x99 || Truth == 0x69) << 3;
|
||||
for ( n = 0; n < 8; n++ )
|
||||
|
|
@ -390,8 +397,18 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos
|
|||
Vec_WecFree( vMajMap );
|
||||
return vAdds;
|
||||
}
|
||||
int Ree_ManCompare( int * pCut0, int * pCut1 )
|
||||
{
|
||||
if ( pCut0[3] < pCut1[3] ) return -1;
|
||||
if ( pCut0[3] > pCut1[3] ) return 1;
|
||||
if ( pCut0[4] < pCut1[4] ) return -1;
|
||||
if ( pCut0[4] > pCut1[4] ) return 1;
|
||||
return 0;
|
||||
}
|
||||
Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose )
|
||||
{
|
||||
extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
Gia_Obj_t * pObj;
|
||||
int * pList0, * pList1, i, nCuts = 0;
|
||||
Hash_IntMan_t * pHash = Hash_IntManStart( 1000 );
|
||||
|
|
@ -425,11 +442,15 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose
|
|||
Vec_IntFree( vTemp );
|
||||
Vec_IntFree( vCuts );
|
||||
vAdds = Ree_ManDeriveAdds( pHash, vData, fVerbose );
|
||||
qsort( Vec_IntArray(vAdds), Vec_IntSize(vAdds)/6, 24, (int (*)(const void *, const void *))Ree_ManCompare );
|
||||
if ( fVerbose )
|
||||
printf( "Adders = %d. Total cuts = %d. Hashed cuts = %d. Hashed/Adders = %.2f.\n",
|
||||
Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) );
|
||||
Vec_IntFree( vData );
|
||||
Hash_IntManStop( pHash );
|
||||
Ree_ManRemoveTrivial( p, vAdds );
|
||||
Ree_ManRemoveContained( p, vAdds );
|
||||
//Ree_ManPrintAdders( vAdds, 1 );
|
||||
return vAdds;
|
||||
}
|
||||
|
||||
|
|
@ -503,6 +524,10 @@ void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds )
|
|||
{
|
||||
pObjX = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+3) );
|
||||
pObjM = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+4) );
|
||||
// rule out if MAJ is a fanout of XOR
|
||||
//if ( pObjX == Gia_ObjFanin0(pObjM) || pObjX == Gia_ObjFanin1(pObjM) )
|
||||
// continue;
|
||||
// rule out if MAJ is a fanin of XOR and has no other fanouts
|
||||
if ( (pObjM == Gia_ObjFanin0(pObjX) || pObjM == Gia_ObjFanin1(pObjX)) && Gia_ObjRefNum(p, pObjM) == 1 )
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#include "acecInt.h"
|
||||
#include "misc/vec/vecWec.h"
|
||||
#include "misc/extra/extra.h"
|
||||
#include "aig/aig/aig.h"
|
||||
#include "opt/dar/dar.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,754 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [acecTree.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [CEC for arithmetic circuits.]
|
||||
|
||||
Synopsis [Adder tree construction.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: acecTree.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "acecInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acec_BoxFree( Acec_Box_t * pBox )
|
||||
{
|
||||
Vec_WecFreeP( &pBox->vAdds );
|
||||
Vec_WecFreeP( &pBox->vLeafLits );
|
||||
Vec_WecFreeP( &pBox->vRootLits );
|
||||
Vec_WecFreeP( &pBox->vUnique );
|
||||
Vec_WecFreeP( &pBox->vShared );
|
||||
ABC_FREE( pBox );
|
||||
}
|
||||
void Acec_BoxFreeP( Acec_Box_t ** ppBox )
|
||||
{
|
||||
if ( *ppBox )
|
||||
Acec_BoxFree( *ppBox );
|
||||
*ppBox = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acec_VerifyBoxLeaves( Acec_Box_t * pBox, Vec_Bit_t * vIgnore )
|
||||
{
|
||||
Vec_Int_t * vLevel;
|
||||
int i, k, iLit, Count = 0;
|
||||
if ( vIgnore == NULL )
|
||||
return;
|
||||
Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
|
||||
Vec_IntForEachEntry( vLevel, iLit, k )
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(pBox->pGia, Abc_Lit2Var(iLit))) && !Vec_BitEntry(vIgnore, Abc_Lit2Var(iLit)) )
|
||||
printf( "Internal node %d of rank %d is not part of PPG.\n", Abc_Lit2Var(iLit), i ), Count++;
|
||||
printf( "Detected %d suspicious leaves.\n", Count );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Filters trees by removing TFO of roots.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
|
||||
{
|
||||
Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, k = 0, Box, Rank;
|
||||
// mark roots
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
||||
{
|
||||
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
|
||||
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
|
||||
}
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
||||
{
|
||||
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+0), 0 );
|
||||
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+1), 0 );
|
||||
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+2), 0 );
|
||||
}
|
||||
// iterate through nodes to detect TFO of roots
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
if ( Vec_BitEntry(vIsRoot, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vIsRoot, Gia_ObjFaninId1(pObj,i)) ||
|
||||
Vec_BitEntry(vMarked, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vMarked, Gia_ObjFaninId1(pObj,i)) )
|
||||
Vec_BitWriteEntry( vMarked, i, 1 );
|
||||
}
|
||||
// remove those that overlap with roots
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
||||
{
|
||||
// special case of the first bit
|
||||
// if ( i == 0 )
|
||||
// continue;
|
||||
|
||||
/*
|
||||
if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 )
|
||||
{
|
||||
printf( "**** removing special one \n" );
|
||||
continue;
|
||||
}
|
||||
if ( Vec_IntEntry(vAdds, 6*Box+3) == 48 && Vec_IntEntry(vAdds, 6*Box+4) == 49 )
|
||||
{
|
||||
printf( "**** removing special one \n" );
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) )
|
||||
{
|
||||
printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank );
|
||||
continue;
|
||||
}
|
||||
Vec_IntWriteEntry( vTree, k++, Box );
|
||||
Vec_IntWriteEntry( vTree, k++, Rank );
|
||||
}
|
||||
Vec_IntShrink( vTree, k );
|
||||
Vec_BitFree( vIsRoot );
|
||||
Vec_BitFree( vMarked );
|
||||
}
|
||||
void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees )
|
||||
{
|
||||
Vec_Int_t * vLevel;
|
||||
int i;
|
||||
Vec_WecForEachLevel( vTrees, vLevel, i )
|
||||
Acec_TreeFilterOne( p, vAdds, vLevel );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Filters trees by removing TFO of roots.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acec_TreeMarkTFI_rec( Gia_Man_t * p, int Id, Vec_Bit_t * vMarked )
|
||||
{
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, Id);
|
||||
if ( Vec_BitEntry(vMarked, Id) )
|
||||
return;
|
||||
Vec_BitWriteEntry( vMarked, Id, 1 );
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
return;
|
||||
Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId0(pObj, Id), vMarked );
|
||||
Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId1(pObj, Id), vMarked );
|
||||
}
|
||||
void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
|
||||
{
|
||||
Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, k = 0, Box, Rank;
|
||||
// mark leaves
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
||||
{
|
||||
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
|
||||
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
|
||||
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
|
||||
}
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
||||
{
|
||||
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+3), 0 );
|
||||
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4), 0 );
|
||||
}
|
||||
// mark TFI of leaves
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Vec_BitEntry(vIsLeaf, i) )
|
||||
Acec_TreeMarkTFI_rec( p, i, vMarked );
|
||||
// additional one
|
||||
//if ( 10942 < Gia_ManObjNum(p) )
|
||||
// Acec_TreeMarkTFI_rec( p, 10942, vMarked );
|
||||
// remove those that overlap with the marked TFI
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
||||
{
|
||||
if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) )
|
||||
{
|
||||
printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank );
|
||||
continue;
|
||||
}
|
||||
Vec_IntWriteEntry( vTree, k++, Box );
|
||||
Vec_IntWriteEntry( vTree, k++, Rank );
|
||||
}
|
||||
Vec_IntShrink( vTree, k );
|
||||
Vec_BitFree( vIsLeaf );
|
||||
Vec_BitFree( vMarked );
|
||||
}
|
||||
void Acec_TreeFilterTrees2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees )
|
||||
{
|
||||
Vec_Int_t * vLevel;
|
||||
int i;
|
||||
Vec_WecForEachLevel( vTrees, vLevel, i )
|
||||
Acec_TreeFilterOne2( p, vAdds, vLevel );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
int Truth0, Truth1;
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
return pObj->Value;
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
assert( !Gia_ObjIsXor(pObj) );
|
||||
Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) );
|
||||
Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) );
|
||||
Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0;
|
||||
Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1;
|
||||
return (pObj->Value = Truth0 & Truth1);
|
||||
}
|
||||
void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 };
|
||||
int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0;
|
||||
int fFlip = !fFadd && Acec_SignBit2(vAdds, iBox, 2);
|
||||
|
||||
Gia_ManIncrementTravId( p );
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
iObj = Vec_IntEntry( vAdds, 6*iBox+k );
|
||||
if ( iObj == 0 )
|
||||
continue;
|
||||
pObj = Gia_ManObj( p, iObj );
|
||||
pObj->Value = (Acec_SignBit2(vAdds, iBox, k) ^ fFlip) ? 0xFF & ~Truths[k] : Truths[k];
|
||||
Gia_ObjSetTravIdCurrent( p, pObj );
|
||||
}
|
||||
|
||||
iObj = Vec_IntEntry( vAdds, 6*iBox+3 );
|
||||
TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
|
||||
TruthXor = (Acec_SignBit2(vAdds, iBox, 3) ^ fFlip) ? 0xFF & ~TruthXor : TruthXor;
|
||||
|
||||
iObj = Vec_IntEntry( vAdds, 6*iBox+4 );
|
||||
TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
|
||||
TruthMaj = (Acec_SignBit2(vAdds, iBox, 4) ^ fFlip) ? 0xFF & ~TruthMaj : TruthMaj;
|
||||
|
||||
if ( fFadd ) // FADD
|
||||
{
|
||||
if ( TruthXor != 0x96 )
|
||||
printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) );
|
||||
if ( TruthMaj != 0xE8 )
|
||||
printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf( "Sign1 = %d%d%d %d\n", Acec_SignBit(vAdds, iBox, 0), Acec_SignBit(vAdds, iBox, 1), Acec_SignBit(vAdds, iBox, 2), Acec_SignBit(vAdds, iBox, 3) );
|
||||
//printf( "Sign2 = %d%d%d %d%d\n", Acec_SignBit2(vAdds, iBox, 0), Acec_SignBit2(vAdds, iBox, 1), Acec_SignBit2(vAdds, iBox, 2), Acec_SignBit2(vAdds, iBox, 3), Acec_SignBit2(vAdds, iBox, 4) );
|
||||
if ( TruthXor != 0x66 )
|
||||
printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) );
|
||||
if ( TruthMaj != 0x88 )
|
||||
printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) );
|
||||
}
|
||||
}
|
||||
void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
|
||||
{
|
||||
Vec_Int_t * vLevel;
|
||||
int i, k, Box;
|
||||
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
||||
Vec_IntForEachEntry( vLevel, Box, k )
|
||||
Acec_TreeVerifyPhaseOne( p, vAdds, Box );
|
||||
}
|
||||
void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
|
||||
{
|
||||
Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Bit_t * vRoots = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vLevel;
|
||||
int i, k, n, Box;
|
||||
// mark all output points and their values
|
||||
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
||||
Vec_IntForEachEntry( vLevel, Box, k )
|
||||
{
|
||||
Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+3 ), 1 );
|
||||
Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+4 ), 1 );
|
||||
Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+3 ), Acec_SignBit2(vAdds, Box, 3) );
|
||||
Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+4 ), Acec_SignBit2(vAdds, Box, 4) );
|
||||
}
|
||||
// compare with input points
|
||||
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
||||
Vec_IntForEachEntry( vLevel, Box, k )
|
||||
for ( n = 0; n < 3; n++ )
|
||||
{
|
||||
if ( !Vec_BitEntry(vRoots, Vec_IntEntry(vAdds, 6*Box+n)) )
|
||||
continue;
|
||||
if ( Vec_BitEntry(vPhase, Vec_IntEntry(vAdds, 6*Box+n)) == Acec_SignBit2(vAdds, Box, n) )
|
||||
continue;
|
||||
printf( "Phase of input %d=%d is mismatched in box %d=(%d,%d).\n",
|
||||
n, Vec_IntEntry(vAdds, 6*Box+n), Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4) );
|
||||
}
|
||||
Vec_BitFree( vPhase );
|
||||
Vec_BitFree( vRoots );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates polarity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
|
||||
{
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vLevel;
|
||||
int i, k, Box;
|
||||
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
||||
Vec_IntForEachEntry( vLevel, Box, k )
|
||||
Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box );
|
||||
return vMap;
|
||||
}
|
||||
void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit )
|
||||
{
|
||||
int k, iBox, iXor, fXorPhase, fPhaseThis;
|
||||
assert( Node != 0 );
|
||||
iBox = Vec_IntEntry( vMap, Node );
|
||||
if ( iBox == -1 )
|
||||
return;
|
||||
assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) );
|
||||
if ( Vec_BitEntry(vVisit, iBox) )
|
||||
return;
|
||||
Vec_BitWriteEntry( vVisit, iBox, 1 );
|
||||
iXor = Vec_IntEntry( vAdds, 6*iBox+3 );
|
||||
fXorPhase = Acec_SignBit(vAdds, iBox, 3);
|
||||
if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 )
|
||||
{
|
||||
//fPhaseThis = Acec_SignBit( vAdds, iBox, 2 ) ^ fPhase;
|
||||
//fXorPhase ^= fPhaseThis;
|
||||
//Acec_SignSetBit2( vAdds, iBox, 2, fPhaseThis ); // complemented HADD -- create const1 input
|
||||
fPhase ^= Acec_SignBit( vAdds, iBox, 2 );
|
||||
fXorPhase ^= fPhase;
|
||||
Acec_SignSetBit2( vAdds, iBox, 2, fPhase ); // complemented HADD -- create const1 input
|
||||
}
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
int iObj = Vec_IntEntry( vAdds, 6*iBox+k );
|
||||
if ( iObj == 0 )
|
||||
continue;
|
||||
fPhaseThis = Acec_SignBit(vAdds, iBox, k) ^ fPhase;
|
||||
fXorPhase ^= fPhaseThis;
|
||||
Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vVisit );
|
||||
Acec_SignSetBit2( vAdds, iBox, k, fPhaseThis );
|
||||
}
|
||||
Acec_SignSetBit2( vAdds, iBox, 3, fXorPhase );
|
||||
Acec_SignSetBit2( vAdds, iBox, 4, fPhase );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find internal cut points with exactly one adder fanin/fanout.]
|
||||
|
||||
Description [Returns a map of point into its input/output adder.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut )
|
||||
{
|
||||
int * pPlace = Vec_IntEntryP( vMap, Abc_Var2Lit(iObj, fOut) );
|
||||
if ( *pPlace == -1 )
|
||||
*pPlace = iAdd;
|
||||
else if ( *pPlace >= 0 )
|
||||
*pPlace = -2;
|
||||
}
|
||||
Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore )
|
||||
{
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) );
|
||||
int i;
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) )
|
||||
continue;
|
||||
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 );
|
||||
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 );
|
||||
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 );
|
||||
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+3), i, 1 );
|
||||
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+4), i, 1 );
|
||||
}
|
||||
return vMap;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find adder trees as groups of adders connected vis cut-points.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Acec_TreeWhichPoint( Vec_Int_t * vAdds, int iAdd, int iObj )
|
||||
{
|
||||
int k;
|
||||
for ( k = 0; k < 5; k++ )
|
||||
if ( Vec_IntEntry(vAdds, 6*iAdd+k) == iObj )
|
||||
return k;
|
||||
assert( 0 );
|
||||
return -1;
|
||||
}
|
||||
void Acec_TreeFindTrees2_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iAdd, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound )
|
||||
{
|
||||
extern void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound );
|
||||
int k;
|
||||
if ( Vec_BitEntry(vFound, iAdd) )
|
||||
return;
|
||||
Vec_BitWriteEntry( vFound, iAdd, 1 );
|
||||
Vec_IntPush( vTree, iAdd );
|
||||
Vec_IntPush( vTree, Rank );
|
||||
//printf( "Assigning rank %d to (%d:%d).\n", Rank, Vec_IntEntry(vAdds, 6*iAdd+3), Vec_IntEntry(vAdds, 6*iAdd+4) );
|
||||
for ( k = 0; k < 5; k++ )
|
||||
Acec_TreeFindTrees_rec( vAdds, vMap, Vec_IntEntry(vAdds, 6*iAdd+k), k == 4 ? Rank + 1 : Rank, vTree, vFound );
|
||||
}
|
||||
void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound )
|
||||
{
|
||||
int In = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 1) );
|
||||
int Out = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 0) );
|
||||
if ( In < 0 || Out < 0 )
|
||||
return;
|
||||
Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound );
|
||||
Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound );
|
||||
}
|
||||
Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut )
|
||||
{
|
||||
Vec_Wec_t * vTrees = Vec_WecAlloc( 10 );
|
||||
Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore );
|
||||
Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 );
|
||||
Vec_Int_t * vTree;
|
||||
int i, k, In, Out, Box, Rank, MinRank;
|
||||
// go through the cut-points
|
||||
Vec_IntForEachEntryDouble( vMap, In, Out, i )
|
||||
{
|
||||
if ( In < 0 || Out < 0 )
|
||||
continue;
|
||||
assert( Vec_BitEntry(vFound, In) == Vec_BitEntry(vFound, Out) );
|
||||
if ( Vec_BitEntry(vFound, In) )
|
||||
continue;
|
||||
vTree = Vec_WecPushLevel( vTrees );
|
||||
Acec_TreeFindTrees_rec( vAdds, vMap, i/2, 0, vTree, vFound );
|
||||
// normalize rank
|
||||
MinRank = ABC_INFINITY;
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
|
||||
MinRank = Abc_MinInt( MinRank, Rank );
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
|
||||
Vec_IntWriteEntry( vTree, k+1, Rank - MinRank );
|
||||
}
|
||||
Vec_BitFree( vFound );
|
||||
Vec_IntFree( vMap );
|
||||
// filter trees
|
||||
if ( fFilterIn )
|
||||
Acec_TreeFilterTrees2( p, vAdds, vTrees );
|
||||
else if ( fFilterOut )
|
||||
Acec_TreeFilterTrees( p, vAdds, vTrees );
|
||||
// sort by size
|
||||
Vec_WecSort( vTrees, 1 );
|
||||
return vTrees;
|
||||
}
|
||||
void Acec_TreeFindTreesTest( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Wec_t * vTrees;
|
||||
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
|
||||
int nFadds = Ree_ManCountFadds( vAdds );
|
||||
printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
||||
clk = Abc_Clock();
|
||||
vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 );
|
||||
printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
Vec_WecPrint( vTrees, 0 );
|
||||
|
||||
Vec_WecFree( vTrees );
|
||||
Vec_IntFree( vAdds );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives one adder tree.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds )
|
||||
{
|
||||
Vec_Int_t * vLevel;
|
||||
int i, k, iBox;
|
||||
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
||||
{
|
||||
printf( " %4d : %2d {", i, Vec_IntSize(vLevel) );
|
||||
Vec_IntForEachEntry( vLevel, iBox, k )
|
||||
{
|
||||
printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox,
|
||||
Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) );
|
||||
//printf( "(%d,%d,%d)", Vec_IntEntry(vAdds, 6*iBox+0), Vec_IntEntry(vAdds, 6*iBox+1), Vec_IntEntry(vAdds, 6*iBox+2) );
|
||||
}
|
||||
printf( " }\n" );
|
||||
}
|
||||
}
|
||||
void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds )
|
||||
{
|
||||
printf( "Adders:\n" );
|
||||
Acec_PrintAdders( pBox->vAdds, vAdds );
|
||||
printf( "Inputs:\n" );
|
||||
Vec_WecPrintLits( pBox->vLeafLits );
|
||||
printf( "Outputs:\n" );
|
||||
Vec_WecPrintLits( pBox->vRootLits );
|
||||
}
|
||||
|
||||
int Acec_CreateBoxMaxRank( Vec_Int_t * vTree )
|
||||
{
|
||||
int k, Box, Rank, MaxRank = 0;
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
|
||||
MaxRank = Abc_MaxInt( MaxRank, Rank );
|
||||
return MaxRank;
|
||||
}
|
||||
Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
|
||||
{
|
||||
int MaxRank = Acec_CreateBoxMaxRank(vTree);
|
||||
Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 );
|
||||
Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vLevel, * vMap;
|
||||
int i, j, k, Box, Rank;//, Count = 0;
|
||||
|
||||
Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 );
|
||||
pBox->pGia = p;
|
||||
pBox->vAdds = Vec_WecStart( MaxRank + 1 );
|
||||
pBox->vLeafLits = Vec_WecStart( MaxRank + 1 );
|
||||
pBox->vRootLits = Vec_WecStart( MaxRank + 2 );
|
||||
|
||||
// collect boxes; mark inputs/outputs
|
||||
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
||||
{
|
||||
// if ( 37 == Box && 6 == Rank )
|
||||
// {
|
||||
// printf( "Skipping one adder...\n" );
|
||||
// continue;
|
||||
// }
|
||||
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
|
||||
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
|
||||
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
|
||||
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
|
||||
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
|
||||
Vec_WecPush( pBox->vAdds, Rank, Box );
|
||||
}
|
||||
// sort each level
|
||||
Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
|
||||
Vec_IntSort( vLevel, 0 );
|
||||
|
||||
// set phases starting from roots
|
||||
vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds );
|
||||
Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i )
|
||||
Vec_IntForEachEntry( vLevel, Box, k )
|
||||
if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) )
|
||||
{
|
||||
//printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box );
|
||||
Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit );
|
||||
}
|
||||
Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds );
|
||||
Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds );
|
||||
Vec_BitFree( vVisit );
|
||||
Vec_IntFree( vMap );
|
||||
|
||||
// collect inputs/outputs
|
||||
Vec_BitWriteEntry( vIsRoot, 0, 1 );
|
||||
Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
|
||||
Vec_IntForEachEntry( vLevel, Box, j )
|
||||
{
|
||||
for ( k = 0; k < 3; k++ )
|
||||
if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) )
|
||||
Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
|
||||
for ( k = 3; k < 5; k++ )
|
||||
if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) )
|
||||
{
|
||||
//if ( Vec_IntEntry(vAdds, 6*Box+k) == 10942 )
|
||||
//{
|
||||
// printf( "++++++++++++ Skipping special\n" );
|
||||
// continue;
|
||||
//}
|
||||
Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
|
||||
}
|
||||
if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) )
|
||||
Vec_WecPush( pBox->vLeafLits, i, 1 );
|
||||
}
|
||||
Vec_BitFree( vIsLeaf );
|
||||
Vec_BitFree( vIsRoot );
|
||||
// sort each level
|
||||
Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
|
||||
Vec_IntSort( vLevel, 0 );
|
||||
Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
|
||||
Vec_IntSort( vLevel, 1 );
|
||||
//return pBox;
|
||||
/*
|
||||
// push literals forward
|
||||
//Vec_WecPrint( pBox->vLeafLits, 0 );
|
||||
Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
|
||||
{
|
||||
int This, Prev = Vec_IntEntry(vLevel, 0);
|
||||
Vec_IntForEachEntryStart( vLevel, This, j, 1 )
|
||||
{
|
||||
if ( Prev != This )
|
||||
{
|
||||
Prev = This;
|
||||
continue;
|
||||
}
|
||||
if ( i+1 >= Vec_WecSize(pBox->vLeafLits) )
|
||||
continue;
|
||||
Vec_IntPushOrder( Vec_WecEntry(pBox->vLeafLits, i+1), This );
|
||||
Vec_IntDrop( vLevel, j-- );
|
||||
Vec_IntDrop( vLevel, j-- );
|
||||
Prev = -1;
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
printf( "Pushed forward %d input literals.\n", Count );
|
||||
*/
|
||||
//Vec_WecPrint( pBox->vLeafLits, 0 );
|
||||
return pBox;
|
||||
}
|
||||
void Acec_CreateBoxTest( Gia_Man_t * p )
|
||||
{
|
||||
Acec_Box_t * pBox;
|
||||
Vec_Wec_t * vTrees;
|
||||
Vec_Int_t * vTree;
|
||||
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
|
||||
int i, nFadds = Ree_ManCountFadds( vAdds );
|
||||
printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
||||
clk = Abc_Clock();
|
||||
vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 );
|
||||
printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
//Vec_WecPrint( vTrees, 0 );
|
||||
|
||||
Vec_WecForEachLevel( vTrees, vTree, i )
|
||||
{
|
||||
pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, i) );
|
||||
printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n",
|
||||
i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds),
|
||||
Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) );
|
||||
Acec_PrintBox( pBox, vAdds );
|
||||
Acec_BoxFreeP( &pBox );
|
||||
}
|
||||
|
||||
Vec_WecFree( vTrees );
|
||||
Vec_IntFree( vAdds );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose )
|
||||
{
|
||||
Acec_Box_t * pBox = NULL;
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose );
|
||||
Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore, fFilterIn, fFilterOut );
|
||||
if ( vTrees && Vec_WecSize(vTrees) > 0 )
|
||||
{
|
||||
pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) );
|
||||
Acec_VerifyBoxLeaves( pBox, vIgnore );
|
||||
}
|
||||
if ( pBox )//&& fVerbose )
|
||||
printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n",
|
||||
0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds),
|
||||
Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) );
|
||||
if ( pBox && fVerbose )
|
||||
Acec_PrintBox( pBox, vAdds );
|
||||
//Acec_PrintAdders( pBox0->vAdds, vAdds );
|
||||
//Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits );
|
||||
Vec_WecFreeP( &vTrees );
|
||||
Vec_IntFree( vAdds );
|
||||
return pBox;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -90,6 +90,29 @@ void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose )
|
|||
Vec_IntFree( vXors );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManDupTopMostRange( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Vec_Int_t * vTops = Vec_IntAlloc( 10 );
|
||||
int i;
|
||||
for ( i = 45; i < 52; i++ )
|
||||
Vec_IntPush( vTops, Gia_ObjId( p, Gia_ObjFanin0(Gia_ManCo(p, i)) ) );
|
||||
pNew = Gia_ManDupAndConesLimit( p, Vec_IntArray(vTops), Vec_IntSize(vTops), 100 );
|
||||
Vec_IntFree( vTops );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
SRC += src/proof/acec/acecCl.c \
|
||||
src/proof/acec/acecCore.c \
|
||||
src/proof/acec/acecCo.c \
|
||||
src/proof/acec/acecBo.c \
|
||||
src/proof/acec/acecRe.c \
|
||||
src/proof/acec/acecPa.c \
|
||||
src/proof/acec/acecPo.c \
|
||||
src/proof/acec/acecPool.c \
|
||||
src/proof/acec/acecCover.c \
|
||||
src/proof/acec/acecFadds.c \
|
||||
src/proof/acec/acecMult.c \
|
||||
src/proof/acec/acecNorm.c \
|
||||
src/proof/acec/acecOrder.c \
|
||||
src/proof/acec/acecPolyn.c \
|
||||
src/proof/acec/acecSt.c \
|
||||
src/proof/acec/acecTree.c \
|
||||
src/proof/acec/acecUtil.c
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
|
|||
{
|
||||
if ( !fSilent )
|
||||
{
|
||||
Abc_Print( 1, "Networks are equivalent. " );
|
||||
Abc_Print( 1, "Networks are equivalent. " );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
}
|
||||
|
|
@ -93,7 +93,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
|
|||
{
|
||||
if ( !fSilent )
|
||||
{
|
||||
Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
|
||||
Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
if ( pMiterCec->pData == NULL )
|
||||
|
|
@ -120,7 +120,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
|
|||
}
|
||||
else if ( !fSilent )
|
||||
{
|
||||
Abc_Print( 1, "Networks are UNDECIDED. " );
|
||||
Abc_Print( 1, "Networks are UNDECIDED. " );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
fflush( stdout );
|
||||
|
|
|
|||
|
|
@ -547,17 +547,17 @@ int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int n
|
|||
// 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 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Networks are UNDECIDED. " );
|
||||
printf( "Networks are UNDECIDED. " );
|
||||
ABC_PRT( "Time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
fflush( stdout );
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ finish:
|
|||
{
|
||||
if ( !pParSec->fSilent )
|
||||
{
|
||||
printf( "Networks are equivalent. " );
|
||||
printf( "Networks are equivalent. " );
|
||||
ABC_PRT( "Time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
if ( pParSec->fReportSolution && !pParSec->fRecursive )
|
||||
|
|
@ -630,7 +630,7 @@ ABC_PRT( "Time", Abc_Clock() - clkTotal );
|
|||
}
|
||||
if ( !pParSec->fSilent )
|
||||
{
|
||||
printf( "Networks are NOT EQUIVALENT. " );
|
||||
printf( "Networks are NOT EQUIVALENT. " );
|
||||
ABC_PRT( "Time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
if ( pParSec->fReportSolution && !pParSec->fRecursive )
|
||||
|
|
|
|||
|
|
@ -922,10 +922,9 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars )
|
|||
}
|
||||
if ( p->pPars->fDumpInv )
|
||||
{
|
||||
Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
|
||||
Abc_FrameSetStr( Pdr_ManDumpString(p) );
|
||||
Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) );
|
||||
Pdr_ManDumpClauses( p, (char *)"inv.pla", RetValue==1 );
|
||||
char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla");
|
||||
Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
|
||||
Pdr_ManDumpClauses( p, pFileName, RetValue==1 );
|
||||
}
|
||||
p->tTotal += Abc_Clock() - clk;
|
||||
Pdr_ManStop( p );
|
||||
|
|
|
|||
|
|
@ -605,9 +605,237 @@ Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce )
|
|||
//Vec_PtrFree( vCubes );
|
||||
Vec_PtrFreeP( &p->vInfCubes );
|
||||
p->vInfCubes = vCubes;
|
||||
Vec_IntPush( vResult, Aig_ManRegNum(p->pAig) );
|
||||
return vResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Remove clauses while maintaining the invariant.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
#define Pdr_ForEachCube( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 1 )
|
||||
|
||||
extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
|
||||
|
||||
Vec_Int_t * Pdr_InvMap( Vec_Int_t * vCounts )
|
||||
{
|
||||
int i, k = 0, Count;
|
||||
Vec_Int_t * vMap = Vec_IntStart( Vec_IntSize(vCounts) );
|
||||
Vec_IntForEachEntry( vCounts, Count, i )
|
||||
if ( Count )
|
||||
Vec_IntWriteEntry( vMap, i, k++ );
|
||||
return vMap;
|
||||
}
|
||||
Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv )
|
||||
{
|
||||
int i, k, * pCube, * pList = Vec_IntArray(vInv);
|
||||
Vec_Int_t * vCounts = Vec_IntStart( Vec_IntEntryLast(vInv) );
|
||||
Pdr_ForEachCube( pList, pCube, i )
|
||||
for ( k = 0; k < pCube[0]; k++ )
|
||||
Vec_IntAddToEntry( vCounts, Abc_Lit2Var(pCube[k+1]), 1 );
|
||||
return vCounts;
|
||||
}
|
||||
int Pdr_InvUsedFlopNum( Vec_Int_t * vInv )
|
||||
{
|
||||
Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
|
||||
int nZeros = Vec_IntCountZero( vCounts );
|
||||
Vec_IntFree( vCounts );
|
||||
return Vec_IntEntryLast(vInv) - nZeros;
|
||||
}
|
||||
|
||||
Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts )
|
||||
{
|
||||
Vec_Str_t * vStr = Vec_StrAlloc( 1000 );
|
||||
Vec_Int_t * vMap = Pdr_InvMap( vCounts );
|
||||
int nVars = Vec_IntSize(vCounts) - Vec_IntCountZero(vCounts);
|
||||
int i, k, * pCube, * pList = Vec_IntArray(vInv);
|
||||
char * pBuffer = ABC_ALLOC( char, nVars );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
pBuffer[i] = '-';
|
||||
Pdr_ForEachCube( pList, pCube, i )
|
||||
{
|
||||
for ( k = 0; k < pCube[0]; k++ )
|
||||
pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '0' + !Abc_LitIsCompl(pCube[k+1]);
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
Vec_StrPush( vStr, pBuffer[k] );
|
||||
Vec_StrPush( vStr, ' ' );
|
||||
Vec_StrPush( vStr, '1' );
|
||||
Vec_StrPush( vStr, '\n' );
|
||||
for ( k = 0; k < pCube[0]; k++ )
|
||||
pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '-';
|
||||
}
|
||||
Vec_StrPush( vStr, '\0' );
|
||||
ABC_FREE( pBuffer );
|
||||
Vec_IntFree( vMap );
|
||||
return vStr;
|
||||
}
|
||||
void Pdr_InvPrint( Vec_Int_t * vInv )
|
||||
{
|
||||
Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
|
||||
Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts );
|
||||
printf( "Invariant contains %d clauses with %d literals and %d flops (out of %d).\n", Vec_IntEntry(vInv, 0), Vec_IntSize(vInv)-Vec_IntEntry(vInv, 0)-2, Pdr_InvUsedFlopNum(vInv), Vec_IntEntryLast(vInv) );
|
||||
printf( "%s", Vec_StrArray( vStr ) );
|
||||
Vec_IntFree( vCounts );
|
||||
Vec_StrFree( vStr );
|
||||
}
|
||||
|
||||
void Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv )
|
||||
{
|
||||
int nBTLimit = 0;
|
||||
int i, k, status, nFailed = 0;
|
||||
// create SAT solver
|
||||
Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
|
||||
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
|
||||
// collect cubes
|
||||
int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0];
|
||||
// create variables
|
||||
Vec_Int_t * vLits = Vec_IntAlloc(100);
|
||||
int nVars = Gia_ManRegNum(p);
|
||||
int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p);
|
||||
int iFiVarBeg = 1 + Gia_ManPoNum(p);
|
||||
assert( Gia_ManPoNum(p) == 1 );
|
||||
// add cubes
|
||||
Pdr_ForEachCube( pList, pCube, i )
|
||||
{
|
||||
// collect literals
|
||||
Vec_IntClear( vLits );
|
||||
for ( k = 0; k < pCube[0]; k++ )
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) );
|
||||
// add it to the solver
|
||||
status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) );
|
||||
assert( status == 1 );
|
||||
}
|
||||
// iterate through cubes in the direct order
|
||||
Pdr_ForEachCube( pList, pCube, i )
|
||||
{
|
||||
// collect cube
|
||||
Vec_IntClear( vLits );
|
||||
for ( k = 0; k < pCube[0]; k++ )
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) );
|
||||
// check if this cube intersects with the complement of other cubes in the solver
|
||||
// if it does not intersect, then it is redundant and can be skipped
|
||||
status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
|
||||
if ( status == l_Undef ) // timeout
|
||||
break;
|
||||
if ( status == l_False ) // unsat -- correct
|
||||
continue;
|
||||
assert( status == l_True );
|
||||
nFailed++;
|
||||
}
|
||||
if ( nFailed )
|
||||
printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, nCubes );
|
||||
else
|
||||
printf( "Invariant verification passes.\n" );
|
||||
Cnf_DataFree( pCnf );
|
||||
sat_solver_delete( pSat );
|
||||
Vec_IntFree( vLits );
|
||||
}
|
||||
|
||||
Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv )
|
||||
{
|
||||
int nBTLimit = 0;
|
||||
int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0;
|
||||
Vec_Int_t * vRes = NULL;
|
||||
// create SAT solver
|
||||
Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
|
||||
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
|
||||
int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0];
|
||||
// create variables
|
||||
Vec_Int_t * vLits = Vec_IntAlloc(100);
|
||||
Vec_Bit_t * vRemoved = Vec_BitStart( nCubes );
|
||||
int nVars = Gia_ManRegNum(p);
|
||||
int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p);
|
||||
int iFiVarBeg = 1 + Gia_ManPoNum(p);
|
||||
int iAuxVarBeg = sat_solver_nvars(pSat);
|
||||
assert( Gia_ManPoNum(p) == 1 );
|
||||
// allocate auxiliary variables
|
||||
sat_solver_setnvars( pSat, sat_solver_nvars(pSat) + nCubes );
|
||||
// add clauses
|
||||
Pdr_ForEachCube( pList, pCube, i )
|
||||
{
|
||||
// collect literals
|
||||
Vec_IntFill( vLits, 1, Abc_Var2Lit(iAuxVarBeg + i, 1) ); // neg aux literal
|
||||
for ( k = 0; k < pCube[0]; k++ )
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) );
|
||||
// add it to the solver
|
||||
status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) );
|
||||
assert( status == 1 );
|
||||
}
|
||||
// iterate through clauses
|
||||
Pdr_ForEachCube( pList, pCube, i )
|
||||
{
|
||||
if ( Vec_BitEntry(vRemoved, i) )
|
||||
continue;
|
||||
// collect aux literals for remaining clauses
|
||||
Vec_IntClear( vLits );
|
||||
for ( k = 0; k < nCubes; k++ )
|
||||
if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal
|
||||
nLits = Vec_IntSize( vLits );
|
||||
// try removing other clauses
|
||||
fCannot = 0;
|
||||
Pdr_ForEachCube( pList, pCube, n )
|
||||
{
|
||||
if ( Vec_BitEntry(vRemoved, n) || n == i )
|
||||
continue;
|
||||
// collect cube
|
||||
Vec_IntShrink( vLits, nLits );
|
||||
for ( k = 0; k < pCube[0]; k++ )
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) );
|
||||
// check if this cube intersects with the complement of other cubes in the solver
|
||||
// if it does not intersect, then it is redundant and can be skipped
|
||||
status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
|
||||
if ( status == l_Undef ) // timeout
|
||||
{
|
||||
fFailed = 1;
|
||||
break;
|
||||
}
|
||||
if ( status == l_False ) // unsat -- correct
|
||||
continue;
|
||||
assert( status == l_True );
|
||||
// cannot remove
|
||||
fCannot = 1;
|
||||
break;
|
||||
}
|
||||
if ( fFailed )
|
||||
break;
|
||||
if ( fCannot )
|
||||
continue;
|
||||
printf( "Removing clause %d.\n", i );
|
||||
Vec_BitWriteEntry( vRemoved, i, 1 );
|
||||
nRemoved++;
|
||||
}
|
||||
if ( nRemoved )
|
||||
printf( "Invariant minimization reduced %d clauses (out of %d).\n", nRemoved, nCubes );
|
||||
else
|
||||
printf( "Invariant minimization did not change the invariant.\n" );
|
||||
// cleanup cover
|
||||
if ( !fFailed && nRemoved > 0 ) // finished without timeout and removed some cubes
|
||||
{
|
||||
vRes = Vec_IntAlloc( 1000 );
|
||||
Vec_IntPush( vRes, nCubes-nRemoved );
|
||||
Pdr_ForEachCube( pList, pCube, i )
|
||||
if ( !Vec_BitEntry(vRemoved, i) )
|
||||
for ( k = 0; k <= pCube[0]; k++ )
|
||||
Vec_IntPush( vRes, pCube[k] );
|
||||
Vec_IntPush( vRes, Vec_IntEntryLast(vInv) );
|
||||
}
|
||||
Cnf_DataFree( pCnf );
|
||||
sat_solver_delete( pSat );
|
||||
Vec_BitFree( vRemoved );
|
||||
Vec_IntFree( vLits );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vF
|
|||
}
|
||||
Vec_StrPushBuffer( vStr, pBuff, k );
|
||||
Vec_StrPush( vStr, ' ' );
|
||||
Vec_StrPush( vStr, '0' );
|
||||
Vec_StrPush( vStr, '1' );
|
||||
Vec_StrPush( vStr, '\n' );
|
||||
ABC_FREE( pBuff );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,7 +229,12 @@ static void sat_solver_compress(sat_solver* s)
|
|||
(void) RetValue;
|
||||
}
|
||||
}
|
||||
|
||||
static void sat_solver_delete_p( sat_solver ** ps )
|
||||
{
|
||||
if ( *ps )
|
||||
sat_solver_delete( *ps );
|
||||
*ps = NULL;
|
||||
}
|
||||
static void sat_solver_clean_polarity(sat_solver* s, int * pVars, int nVars )
|
||||
{
|
||||
int i;
|
||||
|
|
|
|||
Loading…
Reference in New Issue