Merged alanmi/abc into default

This commit is contained in:
Bruno Schmitt 2017-01-25 13:40:31 +09:00
commit 876eb5a52e
80 changed files with 7457 additions and 735 deletions

View File

@ -139,6 +139,8 @@ OBJ := \
$(patsubst %.c, %.o, $(filter %.c, $(SRC))) \
$(patsubst %.y, %.o, $(filter %.y, $(SRC)))
LIBOBJ := $(filter-out src/base/main/main.o,$(OBJ))
DEP := $(OBJ:.o=.d)
# implicit rules
@ -186,11 +188,15 @@ $(PROG): $(OBJ)
@echo "$(MSG_PREFIX)\`\` Building binary:" $(notdir $@)
$(VERBOSE)$(LD) -o $@ $^ $(LIBS)
lib$(PROG).a: $(OBJ)
lib$(PROG).a: $(LIBOBJ)
@echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@)
$(VERBOSE)ar rv $@ $?
$(VERBOSE)ranlib $@
lib$(PROG).so: $(LIBOBJ)
@echo "$(MSG_PREFIX)\`\` Linking:" $(notdir $@)
$(VERBOSE)$(CXX) -shared -o $@ $^ $(LIBS)
docs:
@echo "$(MSG_PREFIX)\`\` Building documentation." $(notdir $@)
$(VERBOSE)doxygen doxygen.conf

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

@ -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 );

View File

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

View File

@ -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);

View File

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

View File

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

View File

@ -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 );
}

View File

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

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -21,6 +21,7 @@
#include "gia.h"
#include "opt/dau/dau.h"
#include "base/main/main.h"
#include "misc/util/utilTruth.h"
#include "aig/miniaig/miniaig.h"
#include "aig/miniaig/minilut.h"
@ -245,6 +246,34 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p )
return pGia;
}
/**Function*************************************************************
Synopsis [Marks LUTs that should be complemented.]
Description [These are LUTs whose all PO fanouts require them
in negative polarity. Other fanouts may require them in
positive polarity.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Bit_t * Gia_ManFindComplLuts( Gia_Man_t * pGia )
{
Gia_Obj_t * pObj; int i;
// mark objects pointed by COs in negative polarity
Vec_Bit_t * vMarks = Vec_BitStart( Gia_ManObjNum(pGia) );
Gia_ManForEachCo( pGia, pObj, i )
if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Gia_ObjFaninC0(pObj) )
Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 1 );
// unmark objects pointed by COs in positive polarity
Gia_ManForEachCo( pGia, pObj, i )
if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && !Gia_ObjFaninC0(pObj) )
Vec_BitWriteEntry( vMarks, Gia_ObjFaninId0p(pGia, pObj), 0 );
return vMarks;
}
/**Function*************************************************************
Synopsis [Converts GIA into MiniLUT.]
@ -260,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 );

View File

@ -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 );
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1077,6 +1077,7 @@ void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate )
***********************************************************************/
int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
{
int fAddBuffers = 1;
Vec_Ptr_t * vDrivers, * vCoTerms;
Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
int i, k, LevelMax, nTotal = 0;
@ -1191,6 +1192,12 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
// collect COs that needs fixing by adding buffers or duplicating
vCoTerms = Vec_PtrAlloc( 100 );
Abc_NtkIncrementTravId( pNtk );
// The following cases should be addressed only if the network is written
// into a BLIF file. Otherwise, it is possible to skip them:
// (1) if a CO points to a CI with a different name
// (2) if an internal node drives more than one CO
if ( fAddBuffers )
Abc_NtkForEachCo( pNtk, pNode, i )
{
// if the driver is a CI and has different name, this is an error

View File

@ -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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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*************************************************************

View File

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

View File

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

View File

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

View File

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

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View File

@ -643,6 +643,41 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level )
Vec_IntInsert( vProd, i + 1, Node );
Vec_IntInsert( vLevel, i + 1, Level );
}
void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds )
{
int fVerbose = 0;
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
Vec_Int_t * vLevel; word Truth;
int i, k, iLit;
Vec_WecForEachLevel( vProds, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) );
printf( "Booth partial products: %d pps, %d unique, %d nodes.\n",
Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) );
Vec_IntPrint( vSupp );
if ( fVerbose )
Vec_WecForEachLevel( vProds, vLevel, i )
Vec_IntForEachEntry( vLevel, iLit, k )
{
printf( "Obj = %4d : ", Abc_Lit2Var(iLit) );
printf( "Compl = %d ", Abc_LitIsCompl(iLit) );
printf( "Rank = %2d ", i );
Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp );
Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
printf( " " );
Vec_IntPrint( vSupp );
if ( k == Vec_IntSize(vLevel)-1 )
printf( "\n" );
}
Vec_IntFree( vSupp );
Vec_WrdFree( vTemp );
}
void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes )
{
Vec_Int_t * vLevel, * vProd;
@ -812,6 +847,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
Vec_WecPush( vLevels, k, 0 );
}
//Vec_WecPrint( vProds, 0 );
//Wlc_BlastPrintMatrix( pNew, vProds );
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes );
@ -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 )
{

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View File

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

View File

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

View File

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

View File

@ -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 );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

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

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

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

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

View File

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

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

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

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

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View File

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

View File

@ -19,6 +19,9 @@
***********************************************************************/
#include "acecInt.h"
#include "proof/cec/cec.h"
#include "misc/util/utilTruth.h"
#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@ -27,10 +30,37 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define TRUTH_UNUSED 0x1234567812345678
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [This procedure sets default parameters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p )
{
memset( p, 0, sizeof(Acec_ParCec_t) );
p->nBTLimit = 1000; // conflict limit at a node
p->TimeLimit = 0; // the runtime limit in seconds
p->fMiter = 0; // input circuit is a miter
p->fDualOutput = 0; // dual-output miter
p->fTwoOutput = 0; // two-output miter
p->fSilent = 0; // print no messages
p->fVeryVerbose = 0; // verbose stats
p->fVerbose = 0; // verbose stats
p->iOutFail = -1; // the number of failed output
}
/**Function*************************************************************
Synopsis []
@ -42,15 +72,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;
}
////////////////////////////////////////////////////////////////////////

View File

@ -27,7 +27,6 @@
////////////////////////////////////////////////////////////////////////
#include "aig/gia/gia.h"
#include "proof/cec/cec.h"
#include "acec.h"
////////////////////////////////////////////////////////////////////////
@ -38,6 +37,17 @@
ABC_NAMESPACE_HEADER_START
typedef struct Acec_Box_t_ Acec_Box_t;
struct Acec_Box_t_
{
Gia_Man_t * pGia; // AIG manager
Vec_Wec_t * vAdds; // adders by rank
Vec_Wec_t * vLeafLits; // leaf literals by rank
Vec_Wec_t * vRootLits; // root literals by rank
Vec_Wec_t * vShared; // shared leaves
Vec_Wec_t * vUnique; // unique leaves
};
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
@ -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

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

@ -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

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

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

View File

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

View File

@ -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 );

View File

@ -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;
}

View File

@ -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

754
src/proof/acec/acecTree.c Normal file
View File

@ -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

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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

View File

@ -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 );

View File

@ -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 );

View File

@ -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 )

View File

@ -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 );

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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 );
}

View File

@ -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;