mirror of https://github.com/YosysHQ/abc.git
Experiments with don't-cares.
This commit is contained in:
parent
d0ea4853ec
commit
036be3a541
|
|
@ -1079,6 +1079,10 @@ SOURCE=.\src\base\acb\acbMfs.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\acb\acbPar.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\acb\acbUtil.c
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
|
|||
|
|
@ -378,6 +378,8 @@ char * Abc_SopCreateFromTruth( Mem_Flex_t * pMan, int nVars, unsigned * pTruth )
|
|||
{
|
||||
char * pSop, * pCube;
|
||||
int nMints, Counter, i, k;
|
||||
if ( nVars == 0 )
|
||||
return pTruth[0] ? Abc_SopCreateConst1(pMan) : Abc_SopCreateConst0(pMan);
|
||||
// count the number of true minterms
|
||||
Counter = 0;
|
||||
nMints = (1 << nVars);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@
|
|||
#include "map/mpm/mpm.h"
|
||||
#include "opt/fret/fretime.h"
|
||||
#include "opt/nwk/nwkMerge.h"
|
||||
#include "base/acb/acbPar.h"
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
|
|
@ -121,6 +123,7 @@ static int Abc_CommandLutmin ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandMfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandMfs2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandMfs3 ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandMfse ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandTrace ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandGlitch ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandSpeedup ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -777,6 +780,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Synthesis", "mfs", Abc_CommandMfs, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "mfs2", Abc_CommandMfs2, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "mfs3", Abc_CommandMfs3, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "mfse", Abc_CommandMfse, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "trace", Abc_CommandTrace, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "glitch", Abc_CommandGlitch, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "speedup", Abc_CommandSpeedup, 1 );
|
||||
|
|
@ -5654,6 +5658,137 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandMfse( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Abc_Ntk_t * Abc_NtkOptMfse( Abc_Ntk_t * pNtk, Acb_Par_t * pPars );
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
Acb_Par_t Pars, * pPars = &Pars; int c;
|
||||
Acb_ParSetDefault( pPars );
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "MDOFLCavwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'M':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nTabooMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nTabooMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'D':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nDivMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nDivMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'O':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nTfoLevMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nTfoLevMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'F':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nFanoutMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nFanoutMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'L':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nGrowthLevel = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nGrowthLevel < -ABC_INFINITY || pPars->nGrowthLevel > ABC_INFINITY )
|
||||
goto usage;
|
||||
break;
|
||||
case 'C':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nBTLimit = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nBTLimit < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'a':
|
||||
pPars->fArea ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
pPars->fVerbose ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
pPars->fVeryVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkIsLogic(pNtk) )
|
||||
{
|
||||
Abc_Print( -1, "This command can only be applied to a logic network.\n" );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: mfse [-MDOFLC <num>] [-avwh]\n" );
|
||||
Abc_Print( -2, "\t performs don't-care-based optimization of logic networks\n" );
|
||||
Abc_Print( -2, "\t-M <num> : the max number of fanin nodes to skip (num >= 1) [default = %d]\n", pPars->nTabooMax );
|
||||
Abc_Print( -2, "\t-D <num> : the max number of divisors [default = %d]\n", pPars->nDivMax );
|
||||
Abc_Print( -2, "\t-O <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevMax );
|
||||
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nFanoutMax );
|
||||
Abc_Print( -2, "\t-L <num> : the max increase in node level after resynthesis (0 <= num) [default = %d]\n", pPars->nGrowthLevel );
|
||||
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 [default = %s]\n", pPars->fArea? "area": "delay" );
|
||||
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");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ static inline int * Acb_ObjFanins( Acb_Ntk_t * p, int i ) { r
|
|||
static inline int Acb_ObjFanin( Acb_Ntk_t * p, int i, int k ) { return Acb_ObjFanins(p, i)[k+1]; }
|
||||
static inline int Acb_ObjFaninNum( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[0]; }
|
||||
static inline int Acb_ObjFanoutNum( Acb_Ntk_t * p, int i ) { return Vec_IntSize( Vec_WecEntry(&p->vFanouts, i) ); }
|
||||
static inline Vec_Int_t * Acb_ObjFanoutVec( Acb_Ntk_t * p, int i ) { return Vec_WecEntry( &p->vFanouts, i ); }
|
||||
static inline int Acb_ObjFanin0( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[1]; }
|
||||
static inline int Acb_ObjCioId( Acb_Ntk_t * p, int i ) { return Acb_ObjFanins(p, i)[2]; }
|
||||
|
||||
|
|
@ -251,6 +252,7 @@ static inline int Acb_ObjCopy( Acb_Ntk_t * p, int i ) { a
|
|||
static inline int Acb_ObjFunc( Acb_Ntk_t * p, int i ) { assert(i>0); assert( Acb_NtkHasObjFuncs(p) ); return Vec_IntGetEntry(&p->vObjFunc, i); }
|
||||
static inline int Acb_ObjWeight( Acb_Ntk_t * p, int i ) { assert(i>0); assert( Acb_NtkHasObjWeights(p) );return Vec_IntGetEntry(&p->vObjWeight, i); }
|
||||
static inline word Acb_ObjTruth( Acb_Ntk_t * p, int i ) { assert(i>0); assert( Acb_NtkHasObjTruths(p) ); return Vec_WrdGetEntry(&p->vObjTruth, i); }
|
||||
static inline word * Acb_ObjTruthP( Acb_Ntk_t * p, int i ) { assert(i>0); assert( Acb_NtkHasObjTruths(p) ); return Vec_WrdEntryP(&p->vObjTruth, i); }
|
||||
static inline int Acb_ObjName( Acb_Ntk_t * p, int i ) { assert(i>0); assert( Acb_NtkHasObjNames(p) ); return Vec_IntGetEntry(&p->vObjName, i); }
|
||||
static inline char * Acb_ObjNameStr( Acb_Ntk_t * p, int i ) { assert(i>0); return Acb_NtkStr(p, Acb_ObjName(p, i)); }
|
||||
static inline int Acb_ObjAttr( Acb_Ntk_t * p, int i ) { assert(i>=0); return Acb_NtkHasObjAttrs(p) ? Vec_IntGetEntry(&p->vObjAttr, i) : 0; }
|
||||
|
|
@ -397,6 +399,16 @@ static inline void Acb_ObjSetNtkId( Acb_Ntk_t * p, int iObj, int iNtk ) // shoul
|
|||
assert( pFanins[ 1 + pFanins[0] ] == -1 );
|
||||
pFanins[ 1 + pFanins[0] ] = iNtk;
|
||||
}
|
||||
static inline void Acb_ObjRemoveFanins( Acb_Ntk_t * p, int iObj )
|
||||
{
|
||||
int i, * pFanins = Acb_ObjFanins( p, iObj );
|
||||
for ( i = 1; i <= pFanins[0]; i++ )
|
||||
{
|
||||
assert( pFanins[i] > 0 );
|
||||
pFanins[i] = -1;
|
||||
}
|
||||
pFanins[0] = 0;
|
||||
}
|
||||
static inline int Acb_ObjAlloc( Acb_Ntk_t * p, Acb_ObjType_t Type, int nFans, int nFons )
|
||||
{
|
||||
int i, nFansReal, CioId = -1, iObj = Vec_StrSize(&p->vObjType);
|
||||
|
|
@ -925,110 +937,10 @@ static inline void Acb_ManPrintStats( Acb_Man_t * p, int nModules, int fVerbose
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Name handling.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
/*
|
||||
static inline void Acb_NtkAddMissingFonNames( Acb_Ntk_t * p, char * pPref )
|
||||
{
|
||||
int iFon, NameId, Index;
|
||||
// populate map
|
||||
Acb_ManCleanMap( p->pDesign );
|
||||
Vec_IntForEachEntryStart( &p->vFonName, NameId, iFon, 1 )
|
||||
if ( NameId )
|
||||
Acb_ManSetMap( p->pDesign, NameId, iFon );
|
||||
// check remaining ones
|
||||
Vec_IntForEachEntryStart( &p->vFonName, NameId, iFon, 1 )
|
||||
{
|
||||
if ( NameId )
|
||||
continue;
|
||||
NameId = Acb_NtkNewStrId(p, "%s%d", pPref, iFon);
|
||||
for ( Index = 1; Acb_ManGetMap(p->pDesign, NameId); Index++ )
|
||||
NameId = Acb_NtkNewStrId(p, "%s%d_%d", pPref, iFon, Index);
|
||||
Acb_FonSetName( p, iFon, NameId );
|
||||
Acb_ManSetMap( p->pDesign, NameId, iFon );
|
||||
}
|
||||
}
|
||||
static inline void Acb_NtkCreateFonNames( Acb_Ntk_t * p, char * pPref )
|
||||
{
|
||||
int i, iObj, iFon;//, NameId;
|
||||
Acb_NtkCleanFonNames( p );
|
||||
Acb_NtkForEachPiFon( p, iObj, iFon, i )
|
||||
if ( !Acb_FonName(p, iFon) )
|
||||
Acb_FonSetName( p, iFon, Acb_ObjName(p, iObj) );
|
||||
Acb_NtkForEachPoDriverFon( p, iObj, iFon, i )
|
||||
if ( Acb_FonIsReal(iFon) && !Acb_FonName(p, iFon) )
|
||||
Acb_FonSetName( p, iFon, Acb_ObjName(p, iObj) );
|
||||
// Vec_IntForEachEntryStart( &p->vFonName, NameId, iFon, 1 )
|
||||
// if ( NameId == 0 )
|
||||
// Vec_IntWriteEntry( &p->vFonName, iFon, Acb_NtkNewStrId(p, "%s%d", pPref, iFon) );
|
||||
Acb_NtkAddMissingFonNames( p, pPref );
|
||||
}
|
||||
static inline void Acb_NtkMissingFonNames( Acb_Ntk_t * p, char * pPref )
|
||||
{
|
||||
int i, iObj, iFon;//, NameId;
|
||||
Acb_NtkForEachPiFon( p, iObj, iFon, i )
|
||||
if ( !Acb_FonName(p, iFon) )
|
||||
Acb_FonSetName( p, iFon, Acb_ObjName(p, iObj) );
|
||||
Acb_NtkForEachPoDriverFon( p, iObj, iFon, i )
|
||||
if ( Acb_FonIsReal(iFon) && !Acb_FonName(p, iFon) )
|
||||
Acb_FonSetName( p, iFon, Acb_ObjName(p, iObj) );
|
||||
// Vec_IntForEachEntryStart( &p->vFonName, NameId, iFon, 1 )
|
||||
// if ( NameId == 0 )
|
||||
// Acb_FonSetName( p, iFon, Acb_NtkNewStrId(p, "%s%d", pPref, iFon) );
|
||||
Acb_NtkAddMissingFonNames( p, pPref );
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*=== acbBlast.c =============================================================*/
|
||||
extern Gia_Man_t * Acb_ManBlast( Acb_Man_t * p, int fBarBufs, int fSeq, int fVerbose );
|
||||
extern Acb_Man_t * Acb_ManInsertGia( Acb_Man_t * p, Gia_Man_t * pGia );
|
||||
extern Acb_Man_t * Acb_ManInsertAbc( Acb_Man_t * p, void * pAbc );
|
||||
/*=== acbCba.c ===============================================================*/
|
||||
extern Acb_Man_t * Acb_ManReadCba( char * pFileName );
|
||||
extern void Acb_ManWriteCba( char * pFileName, Acb_Man_t * p );
|
||||
/*=== acbCom.c ===============================================================*/
|
||||
/*=== acbNtk.c ===============================================================*/
|
||||
extern void Acb_NtkPrintStatsFull( Acb_Ntk_t * p, int fDistrib, int fVerbose );
|
||||
extern void Acb_NtkPrintNodes( Acb_Ntk_t * p, int Type );
|
||||
extern void Acb_NtkPrintDistribOld( Acb_Ntk_t * p );
|
||||
extern void Acb_ManPrintDistrib( Acb_Man_t * p );
|
||||
//extern void Acb_ManPrepareTypeNames( Acb_Man_t * p );
|
||||
extern void Acb_NtkObjOrder( Acb_Ntk_t * p, Vec_Int_t * vObjs, Vec_Int_t * vNameIds );
|
||||
extern int Acb_NtkCiFonNum( Acb_Ntk_t * p );
|
||||
extern int Acb_NtkCoFinNum( Acb_Ntk_t * p );
|
||||
extern int Acb_NtkCheckComboLoop( Acb_Ntk_t * p );
|
||||
extern int Acb_ManIsTopoOrder( Acb_Man_t * p );
|
||||
extern Vec_Int_t * Acb_NtkCollectDfs( Acb_Ntk_t * p );
|
||||
extern Acb_Man_t * Acb_ManCollapse( Acb_Man_t * p );
|
||||
extern Acb_Man_t * Acb_ManExtractGroup( Acb_Man_t * p, Vec_Int_t * vObjs );
|
||||
extern Acb_Man_t * Acb_ManDeriveFromGia( Acb_Man_t * p, Gia_Man_t * pGia, int fUseXor );
|
||||
extern Acb_Man_t * Acb_ManInsertGroup( Acb_Man_t * p, Vec_Int_t * vObjs, Acb_Ntk_t * pSyn );
|
||||
/*=== acbReadBlif.c ==========================================================*/
|
||||
extern Acb_Man_t * Prs_ManBuildCbaBlif( char * pFileName, Vec_Ptr_t * vDes );
|
||||
extern void Prs_ManReadBlifTest( char * pFileName );
|
||||
extern Acb_Man_t * Acb_ManReadBlif( char * pFileName );
|
||||
/*=== acbReadVer.c ===========================================================*/
|
||||
extern Acb_Man_t * Prs_ManBuildCbaVerilog( char * pFileName, Vec_Ptr_t * vDes );
|
||||
extern void Prs_ManReadVerilogTest( char * pFileName );
|
||||
extern Acb_Man_t * Acb_ManReadVerilog( char * pFileName );
|
||||
/*=== acbWriteBlif.c =========================================================*/
|
||||
extern void Prs_ManWriteBlif( char * pFileName, Vec_Ptr_t * p );
|
||||
extern void Acb_ManWriteBlif( char * pFileName, Acb_Man_t * p );
|
||||
/*=== acbWriteVer.c ==========================================================*/
|
||||
extern void Acb_ManCreatePrimMap( char ** pMap );
|
||||
extern char * Acb_ManGetSliceName( Acb_Ntk_t * p, int iFon, int RangeId );
|
||||
extern void Prs_ManWriteVerilog( char * pFileName, Vec_Ptr_t * p );
|
||||
extern void Acb_ManWriteVerilog( char * pFileName, Acb_Man_t * p, int fInlineConcat );
|
||||
/*=== acbUtil.c =============================================================*/
|
||||
extern void Acb_NtkUpdateTiming( Acb_Ntk_t * p, int iObj );
|
||||
extern void Acb_NtkUpdateNode( Acb_Ntk_t * p, int Pivot, word uTruth, Vec_Int_t * vSupp );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "acb.h"
|
||||
#include "base/abc/abc.h"
|
||||
#include "aig/miniaig/ndr.h"
|
||||
#include "acbPar.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -69,6 +70,43 @@ Acb_Ntk_t * Acb_NtkFromAbc( Abc_Ntk_t * p )
|
|||
return pNtk;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Acb_NtkToAbc( Abc_Ntk_t * pNtk, Acb_Ntk_t * p )
|
||||
{
|
||||
int i, k, iObj, iFanin;
|
||||
Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
Mem_Flex_t * pMan = (Mem_Flex_t *)pNtkNew->pManFunc;
|
||||
Acb_NtkCleanObjCopies( p );
|
||||
Acb_NtkForEachCi( p, iObj, i )
|
||||
Acb_ObjSetCopy( p, iObj, Abc_ObjId(Abc_NtkCi(pNtkNew, i)) );
|
||||
Acb_NtkForEachNode( p, iObj )
|
||||
{
|
||||
Abc_Obj_t * pObjNew = Abc_NtkCreateNode( pNtkNew );
|
||||
Acb_ObjForEachFanin( p, iObj, iFanin, k )
|
||||
Abc_ObjAddFanin( pObjNew, Abc_NtkObj(pNtkNew, Acb_ObjCopy(p, iFanin)) );
|
||||
pObjNew->pData = Abc_SopCreateFromTruth( pMan, Acb_ObjFaninNum(p, iObj), (unsigned *)Acb_ObjTruthP(p, iObj) );
|
||||
}
|
||||
Acb_NtkForEachCoDriver( p, iFanin, i )
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), Abc_NtkObj(pNtkNew, Acb_ObjCopy(p, iFanin)) );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Acb_NtkToAbc: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -138,6 +176,58 @@ Acb_Ntk_t * Acb_NtkFromNdr( char * pFileName, void * pModule, Abc_Nam_t * pNames
|
|||
return pNtk;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Setup parameter structure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_ParSetDefault( Acb_Par_t * pPars )
|
||||
{
|
||||
memset( pPars, 0, sizeof(Acb_Par_t) );
|
||||
pPars->nLutSize = 4; // LUT size
|
||||
pPars->nTfoLevMax = 3; // the maximum fanout levels
|
||||
pPars->nTfiLevMax = 3; // the maximum fanin levels
|
||||
pPars->nFanoutMax = 10; // the maximum number of fanouts
|
||||
pPars->nDivMax = 16; // the maximum divisor count
|
||||
pPars->nTabooMax = 4; // the minimum MFFC size
|
||||
pPars->nGrowthLevel = 0; // the maximum allowed growth in level
|
||||
pPars->nBTLimit = 0; // the maximum number of conflicts in one SAT run
|
||||
pPars->nNodesMax = 0; // the maximum number of nodes to try
|
||||
pPars->iNodeOne = 0; // one particular node to try
|
||||
pPars->fArea = 0; // performs optimization for area
|
||||
pPars->fMoreEffort = 0; // enables using more effort
|
||||
pPars->fVerbose = 0; // enable basic stats
|
||||
pPars->fVeryVerbose = 0; // enable detailed stats
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkOptMfse( Abc_Ntk_t * pNtk, Acb_Par_t * pPars )
|
||||
{
|
||||
extern void Acb_NtkOpt( Acb_Ntk_t * p, Acb_Par_t * pPars );
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Acb_Ntk_t * p = Acb_NtkFromAbc( pNtk );
|
||||
Acb_NtkOpt( p, pPars );
|
||||
pNtkNew = Acb_NtkToAbc( pNtk, p );
|
||||
Acb_ManFree( p->pDesign );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@
|
|||
#include "acb.h"
|
||||
#include "bool/kit/kit.h"
|
||||
#include "sat/bsat/satSolver.h"
|
||||
#include "sat/cnf/cnf.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "acbPar.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -34,7 +37,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Derive CNF for nodes in the window.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -43,7 +46,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Acb_Truth2Cnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf )
|
||||
int Acb_DeriveCnfFromTruth( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf )
|
||||
{
|
||||
Vec_StrClear( vCnf );
|
||||
if ( Truth == 0 || ~Truth == 0 )
|
||||
|
|
@ -82,58 +85,32 @@ int Acb_Truth2Cnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf )
|
|||
return nCubes;
|
||||
}
|
||||
}
|
||||
Vec_Wec_t * Acb_NtkDeriveCnf( Acb_Ntk_t * p )
|
||||
Vec_Wec_t * Acb_DeriveCnfForWindow( Acb_Ntk_t * p, Vec_Int_t * vWin, int PivotVar )
|
||||
{
|
||||
Vec_Wec_t * vCnfs = Vec_WecStart( Acb_NtkObjNumMax(p) );
|
||||
Vec_Str_t * vCnf = Vec_StrAlloc( 100 ); int iObj;
|
||||
Acb_NtkForEachNode( p, iObj )
|
||||
Vec_Wec_t * vCnfs = &p->vCnfs;
|
||||
Vec_Str_t * vCnfBase, * vCnf = NULL; int i, iObj;
|
||||
assert( Vec_WecSize(vCnfs) == Acb_NtkObjNumMax(p) );
|
||||
Vec_IntForEachEntry( vWin, iObj, i )
|
||||
{
|
||||
int nCubes = Acb_Truth2Cnf( Acb_ObjTruth(p, iObj), Acb_ObjFaninNum(p, iObj), &p->vCover, vCnf );
|
||||
Vec_Str_t * vCnfBase = (Vec_Str_t *)Vec_WecEntry( vCnfs, iObj );
|
||||
if ( Abc_LitIsCompl(iObj) && i < PivotVar )
|
||||
continue;
|
||||
vCnfBase = (Vec_Str_t *)Vec_WecEntry( vCnfs, iObj );
|
||||
if ( vCnfBase != NULL )
|
||||
continue;
|
||||
if ( vCnf == NULL )
|
||||
vCnf = Vec_StrAlloc( 1000 );
|
||||
Acb_DeriveCnfFromTruth( Acb_ObjTruth(p, iObj), Acb_ObjFaninNum(p, iObj), &p->vCover, vCnf );
|
||||
Vec_StrGrow( vCnfBase, Vec_StrSize(vCnf) );
|
||||
memcpy( Vec_StrArray(vCnfBase), Vec_StrArray(vCnf), Vec_StrSize(vCnf) );
|
||||
vCnfBase->nSize = Vec_StrSize(vCnf);
|
||||
}
|
||||
Vec_StrFree( vCnf );
|
||||
Vec_StrFreeP( &vCnf );
|
||||
return vCnfs;
|
||||
}
|
||||
void Acb_CnfTranslate( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vSatVars, int iPivotVar )
|
||||
{
|
||||
Vec_Int_t * vClause;
|
||||
signed char Entry;
|
||||
int i, Lit;
|
||||
Vec_WecClear( vRes );
|
||||
vClause = Vec_WecPushLevel( vRes );
|
||||
Vec_StrForEachEntry( vCnf, Entry, i )
|
||||
{
|
||||
if ( (int)Entry == -1 )
|
||||
{
|
||||
vClause = Vec_WecPushLevel( vRes );
|
||||
continue;
|
||||
}
|
||||
Lit = Abc_Lit2LitV( Vec_IntArray(vSatVars), (int)Entry );
|
||||
Lit = Abc_LitNotCond( Lit, Abc_Lit2Var(Lit) == iPivotVar );
|
||||
Vec_IntPush( vClause, Lit );
|
||||
}
|
||||
}
|
||||
int Acb_ObjCreateCnf( sat_solver * pSat, Acb_Ntk_t * p, int iObj, Vec_Int_t * vSatVars, int iPivotVar )
|
||||
{
|
||||
Vec_Int_t * vClause; int k, RetValue;
|
||||
Acb_CnfTranslate( &p->vClauses, (Vec_Str_t *)Vec_WecEntry(&p->vCnfs, iObj), vSatVars, iPivotVar );
|
||||
Vec_WecForEachLevel( &p->vClauses, vClause, k )
|
||||
{
|
||||
if ( Vec_IntSize(vClause) == 0 )
|
||||
break;
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vClause), Vec_IntLimit(vClause) );
|
||||
if ( RetValue == 0 )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs SAT solver for the window.]
|
||||
Synopsis [Constructs CNF for the window.]
|
||||
|
||||
Description [The window for the pivot node is represented as a DFS ordered array
|
||||
of objects (vWinObjs) whose indexes are used as SAT variable IDs (stored in p->vCopies).
|
||||
|
|
@ -148,6 +125,22 @@ int Acb_ObjCreateCnf( sat_solver * pSat, Acb_Ntk_t * p, int iObj, Vec_Int_t * vS
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_TranslateCnf( Vec_Int_t * vClas, Vec_Int_t * vLits, Vec_Str_t * vCnf, Vec_Int_t * vSatVars, int iPivotVar )
|
||||
{
|
||||
signed char Entry;
|
||||
int i, Lit;
|
||||
Vec_StrForEachEntry( vCnf, Entry, i )
|
||||
{
|
||||
if ( (int)Entry == -1 )
|
||||
{
|
||||
Vec_IntPush( vClas, Vec_IntSize(vLits) );
|
||||
continue;
|
||||
}
|
||||
Lit = Abc_Lit2LitV( Vec_IntArray(vSatVars), (int)Entry );
|
||||
Lit = Abc_LitNotCond( Lit, Abc_Lit2Var(Lit) == iPivotVar );
|
||||
Vec_IntPush( vLits, Lit );
|
||||
}
|
||||
}
|
||||
int Acb_NtkCountRoots( Vec_Int_t * vWinObjs, int PivotVar )
|
||||
{
|
||||
int i, iObjLit, nRoots = 0;
|
||||
|
|
@ -155,31 +148,27 @@ int Acb_NtkCountRoots( Vec_Int_t * vWinObjs, int PivotVar )
|
|||
nRoots += Abc_LitIsCompl(iObjLit);
|
||||
return nRoots;
|
||||
}
|
||||
sat_solver * Acb_NtkWindow2Solver( sat_solver * pSat, Acb_Ntk_t * p, int Pivot, Vec_Int_t * vWinObjs, int fQbf )
|
||||
Cnf_Dat_t * Acb_NtkWindow2Cnf( Acb_Ntk_t * p, Vec_Int_t * vWinObjs, int Pivot )
|
||||
{
|
||||
Cnf_Dat_t * pCnf;
|
||||
Vec_Int_t * vFaninVars = Vec_IntAlloc( 8 );
|
||||
int PivotVar = Vec_IntFind(vWinObjs, Abc_Var2Lit(Pivot, 0));
|
||||
int nRoots = Acb_NtkCountRoots(vWinObjs, PivotVar);
|
||||
int TfoStart = PivotVar + 1;
|
||||
int nTfoSize = Vec_IntSize(vWinObjs) - TfoStart;
|
||||
int LastVar = Vec_IntSize(vWinObjs) + TfoStart + nRoots;
|
||||
int i, k, iLit = 1, RetValue, iObj, iObjLit, iFanin, * pFanins;
|
||||
//Vec_IntPrint( vWinObjs );
|
||||
int nVarsAll = Vec_IntSize(vWinObjs) + nTfoSize + nRoots;
|
||||
int i, k, iObj, iObjLit, iFanin, * pFanins, Entry;
|
||||
Vec_Wec_t * vCnfs = Acb_DeriveCnfForWindow( p, vWinObjs, PivotVar );
|
||||
Vec_Int_t * vClas = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 1000 );
|
||||
// mark new SAT variables
|
||||
Vec_IntForEachEntry( vWinObjs, iObj, i )
|
||||
Acb_ObjSetCopy( p, i, iObj );
|
||||
// create SAT solver
|
||||
if ( pSat == NULL )
|
||||
pSat = sat_solver_new();
|
||||
else
|
||||
sat_solver_restart( pSat );
|
||||
sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + nTfoSize + nRoots + 1 );
|
||||
// create constant 0 clause
|
||||
sat_solver_addclause( pSat, &iLit, &iLit + 1 );
|
||||
// add clauses for all nodes
|
||||
Vec_IntForEachEntryStop( vWinObjs, iObjLit, i, TfoStart )
|
||||
Vec_IntPush( vClas, Vec_IntSize(vLits) );
|
||||
Vec_IntForEachEntry( vWinObjs, iObjLit, i )
|
||||
{
|
||||
if ( Abc_LitIsCompl(iObjLit) )
|
||||
if ( Abc_LitIsCompl(iObjLit) && i < PivotVar )
|
||||
continue;
|
||||
iObj = Abc_Lit2Var(iObjLit);
|
||||
assert( !Acb_ObjIsCio(p, iObj) );
|
||||
|
|
@ -189,8 +178,7 @@ sat_solver * Acb_NtkWindow2Solver( sat_solver * pSat, Acb_Ntk_t * p, int Pivot,
|
|||
Vec_IntPush( vFaninVars, Acb_ObjCopy(p, iFanin) );
|
||||
Vec_IntPush( vFaninVars, Acb_ObjCopy(p, iObj) );
|
||||
// derive CNF for the node
|
||||
RetValue = Acb_ObjCreateCnf( pSat, p, iObj, vFaninVars, -1 );
|
||||
assert( RetValue );
|
||||
Acb_TranslateCnf( vClas, vLits, (Vec_Str_t *)Vec_WecEntry(vCnfs, iObj), vFaninVars, -1 );
|
||||
}
|
||||
// add second clauses for the TFO
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObjLit, i, TfoStart )
|
||||
|
|
@ -200,11 +188,10 @@ sat_solver * Acb_NtkWindow2Solver( sat_solver * pSat, Acb_Ntk_t * p, int Pivot,
|
|||
// collect SAT variables
|
||||
Vec_IntClear( vFaninVars );
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Vec_IntPush( vFaninVars, (fQbf && iFanin == Pivot) ? LastVar : Acb_ObjCopy(p, iFanin) );
|
||||
Vec_IntPush( vFaninVars, Acb_ObjCopy(p, iObj) );
|
||||
Vec_IntPush( vFaninVars, Acb_ObjCopy(p, iFanin) + (iFanin > PivotVar) * nTfoSize );
|
||||
Vec_IntPush( vFaninVars, Acb_ObjCopy(p, iObj) + nTfoSize );
|
||||
// derive CNF for the node
|
||||
RetValue = Acb_ObjCreateCnf( pSat, p, iObj, vFaninVars, fQbf ? -1 : PivotVar );
|
||||
assert( RetValue );
|
||||
Acb_TranslateCnf( vClas, vLits, (Vec_Str_t *)Vec_WecEntry(vCnfs, iObj), vFaninVars, PivotVar );
|
||||
}
|
||||
if ( nRoots > 0 )
|
||||
{
|
||||
|
|
@ -215,31 +202,91 @@ sat_solver * Acb_NtkWindow2Solver( sat_solver * pSat, Acb_Ntk_t * p, int Pivot,
|
|||
{
|
||||
if ( !Abc_LitIsCompl(iObjLit) )
|
||||
continue;
|
||||
Vec_IntPush( vFaninVars, Abc_Var2Lit(nVars, 0) );
|
||||
sat_solver_add_xor( pSat, Acb_ObjCopy(p, iObj), Acb_ObjCopy(p, iObj) + nTfoSize, nVars++, 0 );
|
||||
}
|
||||
// make OR clause for the last nRoots variables
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vFaninVars), Vec_IntLimit(vFaninVars) );
|
||||
if ( RetValue == 0 )
|
||||
{
|
||||
Vec_IntFree( vFaninVars );
|
||||
sat_solver_delete( pSat );
|
||||
return NULL;
|
||||
}
|
||||
assert( sat_solver_nvars(pSat) == nVars + 1 );
|
||||
}
|
||||
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 );
|
||||
iObj = Abc_Lit2Var(iObjLit);
|
||||
// add clauses
|
||||
Vec_IntPushThree( vLits, Abc_Var2Lit(Acb_ObjCopy(p, iObj), 0), Abc_Var2Lit(Acb_ObjCopy(p, iObj) + nTfoSize, 0), Abc_Var2Lit(nVars, 0) );
|
||||
Vec_IntPush( vClas, Vec_IntSize(vLits) );
|
||||
Vec_IntPushThree( vLits, Abc_Var2Lit(Acb_ObjCopy(p, iObj), 1), Abc_Var2Lit(Acb_ObjCopy(p, iObj) + nTfoSize, 1), Abc_Var2Lit(nVars, 0) );
|
||||
Vec_IntPush( vClas, Vec_IntSize(vLits) );
|
||||
Vec_IntPushThree( vLits, Abc_Var2Lit(Acb_ObjCopy(p, iObj), 0), Abc_Var2Lit(Acb_ObjCopy(p, iObj) + nTfoSize, 1), Abc_Var2Lit(nVars, 1) );
|
||||
Vec_IntPush( vClas, Vec_IntSize(vLits) );
|
||||
Vec_IntPushThree( vLits, Abc_Var2Lit(Acb_ObjCopy(p, iObj), 1), Abc_Var2Lit(Acb_ObjCopy(p, iObj) + nTfoSize, 0), Abc_Var2Lit(nVars, 1) );
|
||||
Vec_IntPush( vClas, Vec_IntSize(vLits) );
|
||||
Vec_IntPush( vFaninVars, Abc_Var2Lit(nVars++, 0) );
|
||||
}
|
||||
Vec_IntAppend( vLits, vFaninVars );
|
||||
Vec_IntPush( vClas, Vec_IntSize(vLits) );
|
||||
assert( nRoots == Vec_IntSize(vFaninVars) );
|
||||
assert( nVars == nVarsAll );
|
||||
}
|
||||
Vec_IntFree( vFaninVars );
|
||||
// undo SAT variables
|
||||
Vec_IntForEachEntry( vWinObjs, iObj, i )
|
||||
Vec_IntWriteEntry( &p->vObjCopy, iObj, -1 );
|
||||
// create CNF structure
|
||||
pCnf = ABC_CALLOC( Cnf_Dat_t, 1 );
|
||||
pCnf->nVars = nVarsAll;
|
||||
pCnf->nClauses = Vec_IntSize(vClas)-1;
|
||||
pCnf->nLiterals = Vec_IntSize(vLits);
|
||||
pCnf->pClauses = ABC_ALLOC( int *, Vec_IntSize(vClas) );
|
||||
pCnf->pClauses[0] = Vec_IntReleaseArray(vLits);
|
||||
Vec_IntForEachEntry( vClas, Entry, i )
|
||||
pCnf->pClauses[i] = pCnf->pClauses[0] + Entry;
|
||||
// cleanup
|
||||
Vec_IntFree( vClas );
|
||||
Vec_IntFree( vLits );
|
||||
return pCnf;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates SAT solver containing several copies of the window.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
sat_solver * Acb_NtkWindow2Solver( Cnf_Dat_t * pCnf, int PivotVar, int nDivs, int nTimes )
|
||||
{
|
||||
int n, i, RetValue, nRounds = nTimes <= 2 ? nTimes-1 : nTimes;
|
||||
Vec_Int_t * vFlips = Cnf_DataCollectFlipLits( pCnf, PivotVar );
|
||||
sat_solver * pSat = sat_solver_new();
|
||||
sat_solver_setnvars( pSat, nTimes * pCnf->nVars + nRounds * nDivs + 1 );
|
||||
assert( nTimes == 1 || nTimes == 2 || nTimes == 6 );
|
||||
for ( n = 0; n < nTimes; n++ )
|
||||
{
|
||||
if ( n & 1 )
|
||||
Cnf_DataLiftAndFlipLits( pCnf, -pCnf->nVars, vFlips );
|
||||
for ( i = 0; i < pCnf->nClauses; i++ )
|
||||
{
|
||||
if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
|
||||
{
|
||||
Vec_IntFree( vFlips );
|
||||
sat_solver_delete( pSat );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ( n & 1 )
|
||||
Cnf_DataLiftAndFlipLits( pCnf, pCnf->nVars, vFlips );
|
||||
if ( n < nTimes - 1 )
|
||||
Cnf_DataLift( pCnf, pCnf->nVars );
|
||||
else if ( n ) // if ( n == nTimes - 1 )
|
||||
Cnf_DataLift( pCnf, -(nTimes - 1) * pCnf->nVars );
|
||||
}
|
||||
Vec_IntFree( vFlips );
|
||||
// add conditional buffers
|
||||
for ( n = 0; n < nRounds; n++ )
|
||||
{
|
||||
int BaseA = n * pCnf->nVars;
|
||||
int BaseB = ((n + 1) % nTimes) * pCnf->nVars;
|
||||
int BaseC = nTimes * pCnf->nVars + n * nDivs;
|
||||
for ( i = 0; i < nDivs; i++ )
|
||||
sat_solver_add_buffer_enable( pSat, BaseA + i, BaseB + i, BaseC + i, 0 );
|
||||
}
|
||||
// finalize
|
||||
RetValue = sat_solver_simplify( pSat );
|
||||
if ( RetValue == 0 )
|
||||
|
|
@ -250,64 +297,6 @@ sat_solver * Acb_NtkWindow2Solver( sat_solver * pSat, Acb_Ntk_t * p, int Pivot,
|
|||
return pSat;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_NtkUnmarkWindow( Acb_Ntk_t * p, Vec_Int_t * vWin )
|
||||
{
|
||||
int i, iObj;
|
||||
Vec_IntForEachEntry( vWin, iObj, i )
|
||||
Vec_IntWriteEntry( &p->vObjCopy, iObj, -1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects divisors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Acb_ObjIsCritFanin( Acb_Ntk_t * p, int i, int f ) { return Acb_ObjLevelR(p, i) + Acb_ObjLevelD(p, f) == p->LevelMax; }
|
||||
Vec_Int_t * Acb_NtkDivisors( Acb_Ntk_t * p, int Pivot, int nTfiLevMin )
|
||||
{
|
||||
int i, k, iObj, iFanin, iFanin2, * pFanins, * pFanins2, Lev, Level = Acb_ObjLevelD(p, Pivot);
|
||||
// include non-critical pivot fanins AND fanins of critical pivot fanins
|
||||
Vec_Int_t * vDivs = Vec_IntAlloc( 100 );
|
||||
Acb_ObjForEachFaninFast( p, Pivot, pFanins, iFanin, i )
|
||||
{
|
||||
if ( !Acb_ObjIsCritFanin(p, Pivot, iFanin) ) // non-critical fanin
|
||||
Vec_IntPush( vDivs, iFanin );
|
||||
else // critical fanin
|
||||
Acb_ObjForEachFaninFast( p, iFanin, pFanins2, iFanin2, k )
|
||||
Vec_IntPushUnique( vDivs, iFanin2 );
|
||||
}
|
||||
// continue for a few more levels
|
||||
for ( Lev = Level-2; Lev >= nTfiLevMin; Lev-- )
|
||||
{
|
||||
Vec_IntForEachEntry( vDivs, iObj, i )
|
||||
if ( Acb_ObjLevelD(p, iObj) == Lev )
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Vec_IntPushUnique( vDivs, iFanin );
|
||||
}
|
||||
// sort them by level
|
||||
Vec_IntSelectSortCost( Vec_IntArray(vDivs), Vec_IntSize(vDivs), &p->vLevelD );
|
||||
return vDivs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -406,18 +395,18 @@ void Acb_ObjDeriveTfo_rec( Acb_Ntk_t * p, int iObj, Vec_Int_t * vTfo, Vec_Int_t
|
|||
Acb_ObjDeriveTfo_rec( p, iFanout, vTfo, vRoots );
|
||||
Vec_IntPush( vTfo, Diff );
|
||||
}
|
||||
void Acb_ObjDeriveTfo( Acb_Ntk_t * p, int Root, int nTfoLevMax, int nFanMax, Vec_Int_t ** pvTfo, Vec_Int_t ** pvRoots )
|
||||
void Acb_ObjDeriveTfo( Acb_Ntk_t * p, int Pivot, int nTfoLevMax, int nFanMax, Vec_Int_t ** pvTfo, Vec_Int_t ** pvRoots )
|
||||
{
|
||||
int Res = Acb_ObjLabelTfo( p, Root, nTfoLevMax, nFanMax );
|
||||
int Res = Acb_ObjLabelTfo( p, Pivot, nTfoLevMax, nFanMax );
|
||||
Vec_Int_t * vTfo = *pvTfo = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vRoots = *pvRoots = Vec_IntAlloc( 100 );
|
||||
if ( Res ) // none or root
|
||||
return;
|
||||
Acb_NtkIncTravId( p ); // root (2) inner (1) visited (0)
|
||||
Acb_ObjDeriveTfo_rec( p, Root, vTfo, vRoots );
|
||||
assert( Vec_IntEntryLast(vTfo) == Root );
|
||||
Acb_ObjDeriveTfo_rec( p, Pivot, vTfo, vRoots );
|
||||
assert( Vec_IntEntryLast(vTfo) == Pivot );
|
||||
Vec_IntPop( vTfo );
|
||||
assert( Vec_IntEntryLast(vRoots) != Root );
|
||||
assert( Vec_IntEntryLast(vRoots) != Pivot );
|
||||
Vec_IntReverseOrder( vTfo );
|
||||
Vec_IntReverseOrder( vRoots );
|
||||
}
|
||||
|
|
@ -439,12 +428,14 @@ Vec_Int_t * Acb_NtkCollectTfoSideInputs( Acb_Ntk_t * p, int Pivot, Vec_Int_t * v
|
|||
Vec_Int_t * vSide = Vec_IntAlloc( 100 );
|
||||
int i, k, Node, iFanin, * pFanins;
|
||||
Acb_NtkIncTravId( p );
|
||||
Vec_IntPush( vTfo, Pivot );
|
||||
Vec_IntForEachEntry( vTfo, Node, i )
|
||||
Acb_ObjSetTravIdCur( p, Node ), assert( Node != Pivot );
|
||||
Acb_ObjSetTravIdCur( p, Node );
|
||||
Vec_IntForEachEntry( vTfo, Node, i )
|
||||
Acb_ObjForEachFaninFast( p, Node, pFanins, iFanin, k )
|
||||
if ( !Acb_ObjSetTravIdCur(p, iFanin) && iFanin != Pivot )
|
||||
Vec_IntPush( vSide, iFanin );
|
||||
Vec_IntPop( vTfo );
|
||||
return vSide;
|
||||
}
|
||||
|
||||
|
|
@ -481,11 +472,14 @@ void Acb_NtkCollectNewTfi2_rec( Acb_Ntk_t * p, int iObj, Vec_Int_t * vTfiNew )
|
|||
Acb_NtkCollectNewTfi2_rec( p, iFanin, vTfiNew );
|
||||
Vec_IntPush( vTfiNew, iObj );
|
||||
}
|
||||
Vec_Int_t * Acb_NtkCollectNewTfi( Acb_Ntk_t * p, int Pivot, Vec_Int_t * vSide )
|
||||
Vec_Int_t * Acb_NtkCollectNewTfi( Acb_Ntk_t * p, int Pivot, Vec_Int_t * vDivs, Vec_Int_t * vSide )
|
||||
{
|
||||
Vec_Int_t * vTfiNew = Vec_IntAlloc( 100 );
|
||||
int i, Node;
|
||||
Acb_NtkIncTravId( p );
|
||||
Vec_IntForEachEntry( vDivs, Node, i )
|
||||
Acb_NtkCollectNewTfi1_rec( p, Node, vTfiNew );
|
||||
assert( Vec_IntSize(vTfiNew) == Vec_IntSize(vDivs) );
|
||||
Acb_NtkCollectNewTfi1_rec( p, Pivot, vTfiNew );
|
||||
assert( Vec_IntEntryLast(vTfiNew) == Pivot );
|
||||
Vec_IntPop( vTfiNew );
|
||||
|
|
@ -510,6 +504,7 @@ Vec_Int_t * Acb_NtkCollectWindow( Acb_Ntk_t * p, int Pivot, Vec_Int_t * vTfi, Ve
|
|||
{
|
||||
Vec_Int_t * vWin = Vec_IntAlloc( 100 );
|
||||
int i, k, iObj, iFanin, * pFanins;
|
||||
assert( Vec_IntEntryLast(vTfi) == Pivot );
|
||||
// mark leaves
|
||||
Acb_NtkIncTravId( p );
|
||||
Vec_IntForEachEntry( vTfi, iObj, i )
|
||||
|
|
@ -532,6 +527,73 @@ Vec_Int_t * Acb_NtkCollectWindow( Acb_Ntk_t * p, int Pivot, Vec_Int_t * vTfi, Ve
|
|||
return vWin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects divisors in a non-topo order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Acb_NtkDivisors( Acb_Ntk_t * p, int Pivot, int * pTaboo, int nTaboo, int nDivsMax )
|
||||
{
|
||||
Vec_Int_t * vDivs = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vFront = Vec_IntAlloc( 100 );
|
||||
int i, k, iFanin, * pFanins;
|
||||
// mark taboo nodes
|
||||
Acb_NtkIncTravId( p );
|
||||
assert( !Acb_ObjIsCio(p, Pivot) );
|
||||
Acb_ObjSetTravIdCur( p, Pivot );
|
||||
for ( i = 0; i < nTaboo; i++ )
|
||||
{
|
||||
assert( !Acb_ObjIsCio(p, pTaboo[i]) );
|
||||
if ( Acb_ObjSetTravIdCur( p, pTaboo[i] ) )
|
||||
assert( 0 );
|
||||
}
|
||||
// collect non-taboo fanins of pivot but do not use them as frontier
|
||||
Acb_ObjForEachFaninFast( p, Pivot, pFanins, iFanin, k )
|
||||
if ( !Acb_ObjSetTravIdCur( p, iFanin ) )
|
||||
Vec_IntPush( vDivs, iFanin );
|
||||
// collect non-tabook fanins of taboo nodes and use them as frontier
|
||||
for ( i = 0; i < nTaboo; i++ )
|
||||
Acb_ObjForEachFaninFast( p, pTaboo[i], pFanins, iFanin, k )
|
||||
if ( !Acb_ObjSetTravIdCur( p, iFanin ) )
|
||||
{
|
||||
Vec_IntPush( vDivs, iFanin );
|
||||
if ( !Acb_ObjIsCio(p, iFanin) )
|
||||
Vec_IntPush( vFront, iFanin );
|
||||
}
|
||||
// select divisors incrementally
|
||||
while ( Vec_IntSize(vFront) > 0 && Vec_IntSize(vDivs) < nDivsMax )
|
||||
{
|
||||
// select the topmost
|
||||
int iObj, iObjMax = -1, LevelMax = -1;
|
||||
Vec_IntForEachEntry( vFront, iObj, k )
|
||||
if ( LevelMax < Acb_ObjLevelD(p, iObj) )
|
||||
LevelMax = Acb_ObjLevelD(p, (iObjMax = iObj));
|
||||
assert( iObjMax > 0 );
|
||||
Vec_IntRemove( vFront, iObjMax );
|
||||
// expand the topmost
|
||||
Acb_ObjForEachFaninFast( p, iObjMax, pFanins, iFanin, k )
|
||||
if ( !Acb_ObjSetTravIdCur( p, iFanin ) )
|
||||
{
|
||||
Vec_IntPush( vDivs, iFanin );
|
||||
if ( !Acb_ObjIsCio(p, iFanin) )
|
||||
Vec_IntPush( vFront, iFanin );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vFront );
|
||||
// sort them by level
|
||||
Vec_IntSelectSortCost( Vec_IntArray(vDivs), Vec_IntSize(vDivs), &p->vLevelD );
|
||||
return vDivs;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -543,29 +605,30 @@ Vec_Int_t * Acb_NtkCollectWindow( Acb_Ntk_t * p, int Pivot, Vec_Int_t * vTfi, Ve
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Acb_NtkWindow( Acb_Ntk_t * p, int Pivot, int nTfiLevs, int nTfoLevs, int nFanMax, Vec_Int_t ** pvDivs )
|
||||
Vec_Int_t * Acb_NtkWindow( Acb_Ntk_t * p, int Pivot, int * pTaboo, int nTaboo, int nDivsMax, int nTfoLevs, int nFanMax, int * pnDivs )
|
||||
{
|
||||
int nTfiLevMin = Acb_ObjLevelD(p, Pivot) - nTfiLevs;
|
||||
int nTfoLevMax = Acb_ObjLevelD(p, Pivot) + nTfoLevs;
|
||||
Vec_Int_t * vWin, * vDivs, * vTfo, * vRoots, * vSide, * vTfi;
|
||||
// collect divisors by traversing limited TFI
|
||||
vDivs = Acb_NtkDivisors( p, Pivot, nTfiLevMin );
|
||||
vDivs = Acb_NtkDivisors( p, Pivot, pTaboo, nTaboo, nDivsMax );
|
||||
// mark limited TFO of the divisors
|
||||
Acb_ObjMarkTfo( p, vDivs, Pivot, nTfoLevMax, nFanMax );
|
||||
// collect TFO and roots
|
||||
Acb_ObjDeriveTfo( p, Pivot, nTfoLevMax, nFanMax, &vTfo, &vRoots );
|
||||
// collect side inputs of the TFO
|
||||
vSide = Acb_NtkCollectTfoSideInputs( p, Pivot, vTfo );
|
||||
// mark limited TFO of the divisors
|
||||
Acb_ObjMarkTfo( p, vDivs, Pivot, nTfoLevMax, nFanMax );
|
||||
// collect new TFI
|
||||
vTfi = Acb_NtkCollectNewTfi( p, Pivot, vSide );
|
||||
vTfi = Acb_NtkCollectNewTfi( p, Pivot, vDivs, vSide );
|
||||
Vec_IntFree( vSide );
|
||||
Vec_IntFree( vDivs );
|
||||
// collect all nodes
|
||||
vWin = Acb_NtkCollectWindow( p, Pivot, vTfi, vTfo, vRoots );
|
||||
// cleanup
|
||||
Vec_IntFree( vTfi );
|
||||
Vec_IntFree( vTfo );
|
||||
Vec_IntFree( vRoots );
|
||||
Vec_IntFree( vSide );
|
||||
*pvDivs = vDivs;
|
||||
return vWin;
|
||||
}
|
||||
|
||||
|
|
@ -597,6 +660,155 @@ int Acb_NtkFindSupp( sat_solver * pSat, Acb_Ntk_t * p, Vec_Int_t * vWin, Vec_Int
|
|||
return Vec_IntSize(vDivs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes function of the node]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
word Acb_ComputeFunction( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars )
|
||||
{
|
||||
int fExpand = 1;
|
||||
word uCube, uTruth = 0;
|
||||
Vec_Int_t * vTempLits = Vec_IntAlloc( 100 );
|
||||
int status, i, iVar, iLit, nFinal, * pFinal, pLits[2];
|
||||
assert( FreeVar < sat_solver_nvars(pSat) );
|
||||
pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1
|
||||
pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit
|
||||
while ( 1 )
|
||||
{
|
||||
// find onset minterm
|
||||
status = sat_solver_solve( pSat, pLits, pLits + 2, 0, 0, 0, 0 );
|
||||
if ( status == l_False )
|
||||
{
|
||||
Vec_IntFree( vTempLits );
|
||||
return uTruth;
|
||||
}
|
||||
assert( status == l_True );
|
||||
if ( fExpand )
|
||||
{
|
||||
// collect divisor literals
|
||||
Vec_IntFill( vTempLits, 1, Abc_LitNot(pLits[0]) ); // F = 0
|
||||
Vec_IntForEachEntry( vDivVars, iVar, i )
|
||||
Vec_IntPush( vTempLits, sat_solver_var_literal(pSat, iVar) );
|
||||
// check against offset
|
||||
status = sat_solver_solve( pSat, Vec_IntArray(vTempLits), Vec_IntLimit(vTempLits), 0, 0, 0, 0 );
|
||||
assert( status == l_False );
|
||||
// compute cube and add clause
|
||||
nFinal = sat_solver_final( pSat, &pFinal );
|
||||
Vec_IntFill( vTempLits, 1, Abc_LitNot(pLits[1]) ); // NOT(iNewLit)
|
||||
uCube = ~(word)0;
|
||||
for ( i = 0; i < nFinal; i++ )
|
||||
if ( pFinal[i] != pLits[0] )
|
||||
Vec_IntPush( vTempLits, pFinal[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
// collect divisor literals
|
||||
Vec_IntFill( vTempLits, 1, Abc_LitNot(pLits[1]) );// NOT(iNewLit)
|
||||
Vec_IntForEachEntry( vDivVars, iVar, i )
|
||||
Vec_IntPush( vTempLits, Abc_LitNot(sat_solver_var_literal(pSat, iVar)) );
|
||||
}
|
||||
Vec_IntForEachEntry( vTempLits, iLit, i )
|
||||
{
|
||||
iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(iLit) ); assert( iVar >= 0 );
|
||||
uCube &= Abc_LitIsCompl(iLit) ? s_Truths6[iVar] : ~s_Truths6[iVar];
|
||||
}
|
||||
uTruth |= uCube;
|
||||
status = sat_solver_addclause( pSat, Vec_IntArray(vTempLits), Vec_IntLimit(vTempLits) );
|
||||
if ( status == 0 )
|
||||
{
|
||||
Vec_IntFree( vTempLits );
|
||||
return uTruth;
|
||||
}
|
||||
}
|
||||
assert( 0 );
|
||||
return ~(word)0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the taboo nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Acb_ObjIsCritFanin( Acb_Ntk_t * p, int i, int f ) { return Acb_ObjLevelR(p, i) + Acb_ObjLevelD(p, f) == p->LevelMax; }
|
||||
|
||||
static inline void Acb_ObjUpdateFanoutCount( Acb_Ntk_t * p, int iObj, int AddOn )
|
||||
{
|
||||
int k, iFanin, * pFanins;
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Acb_ObjFanoutVec(p, iFanin)->nSize += AddOn;
|
||||
}
|
||||
|
||||
int Acb_NtkCollectTaboo( Acb_Ntk_t * p, int Pivot, int nTabooMax, int * pTaboo )
|
||||
{
|
||||
int i, k, iFanin, * pFanins, nTaboo = 0;
|
||||
if ( nTabooMax == 0 ) // delay optimization
|
||||
{
|
||||
// collect delay critical fanins of the pivot node
|
||||
Acb_ObjForEachFaninFast( p, Pivot, pFanins, iFanin, k )
|
||||
if ( !Acb_ObjIsCi(p, iFanin) && Acb_ObjIsCritFanin( p, Pivot, iFanin ) )
|
||||
pTaboo[ nTaboo++ ] = iFanin;
|
||||
}
|
||||
else // area optimization
|
||||
{
|
||||
// check if the node has any area critical fanins
|
||||
Acb_ObjForEachFaninFast( p, Pivot, pFanins, iFanin, k )
|
||||
if ( !Acb_ObjIsCi(p, iFanin) && Acb_ObjFanoutNum(p, iFanin) == 1 )
|
||||
break;
|
||||
if ( k < Acb_ObjFaninNum(p, Pivot) ) // there is fanin
|
||||
{
|
||||
// mark pivot
|
||||
Acb_NtkIncTravId( p );
|
||||
Acb_ObjSetTravIdCur( p, Pivot );
|
||||
Acb_ObjUpdateFanoutCount( p, Pivot, -1 );
|
||||
// add the first taboo node
|
||||
assert( Acb_ObjFanoutNum(p, iFanin) == 0 );
|
||||
pTaboo[ nTaboo++ ] = iFanin;
|
||||
Acb_ObjSetTravIdCur( p, iFanin );
|
||||
Acb_ObjUpdateFanoutCount( p, iFanin, -1 );
|
||||
while ( nTaboo < nTabooMax )
|
||||
{
|
||||
// select the first unrefed fanin
|
||||
for ( i = 0; i < nTaboo; i++ )
|
||||
{
|
||||
Acb_ObjForEachFaninFast( p, pTaboo[i], pFanins, iFanin, k )
|
||||
if ( !Acb_ObjIsCi(p, iFanin) && !Acb_ObjIsTravIdCur(p, iFanin) && Acb_ObjFanoutNum(p, iFanin) == 0 )
|
||||
{
|
||||
pTaboo[ nTaboo++ ] = iFanin;
|
||||
Acb_ObjSetTravIdCur( p, iFanin );
|
||||
Acb_ObjUpdateFanoutCount( p, iFanin, -1 );
|
||||
break;
|
||||
}
|
||||
if ( k < Acb_ObjFaninNum(p, pTaboo[i]) )
|
||||
break;
|
||||
}
|
||||
if ( i == nTaboo ) // no change
|
||||
break;
|
||||
}
|
||||
// reference nodes back
|
||||
Acb_ObjUpdateFanoutCount( p, Pivot, 1 );
|
||||
for ( i = 0; i < nTaboo; i++ )
|
||||
Acb_ObjUpdateFanoutCount( p, pTaboo[i], 1 );
|
||||
}
|
||||
}
|
||||
return nTaboo;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -608,25 +820,113 @@ int Acb_NtkFindSupp( sat_solver * pSat, Acb_Ntk_t * p, Vec_Int_t * vWin, Vec_Int
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_NtkOptNode( Acb_Ntk_t * p, int Pivot, int nTfiLevs, int nTfoLevs, int nFanMax )
|
||||
static inline void Vec_IntVars2Lits( Vec_Int_t * p, int Shift, int fCompl )
|
||||
{
|
||||
Vec_Int_t * vSupp = &p->vArray0;
|
||||
Vec_Int_t * vDivs, * vWin = Acb_NtkWindow( p, Pivot, nTfiLevs, nTfoLevs, nFanMax, &vDivs );
|
||||
sat_solver * pSat = Acb_NtkWindow2Solver( pSat, p, Pivot, vWin, 0 );
|
||||
int nSuppNew, Level = Acb_ObjLevelD( p, Pivot );
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
p->pArray[i] = Abc_Var2Lit( p->pArray[i] + Shift, fCompl );
|
||||
}
|
||||
static inline void Vec_IntLits2Vars( Vec_Int_t * p, int Shift )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
p->pArray[i] = Abc_Lit2Var( p->pArray[i] ) - Shift;
|
||||
}
|
||||
static inline void Vec_IntRemap( Vec_Int_t * p, Vec_Int_t * vMap )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
p->pArray[i] = Vec_IntEntry(vMap, p->pArray[i]);
|
||||
}
|
||||
|
||||
void Acb_NtkOptNode( Acb_Ntk_t * p, int Pivot, int nTabooMax, int nDivMax, int nTfoLevs, int nFanMax, int nLutSize )
|
||||
{
|
||||
Cnf_Dat_t * pCnf;
|
||||
Vec_Int_t * vWin, * vSupp;
|
||||
sat_solver * pSat1 = NULL, * pSat2 = NULL, * pSat3 = NULL;
|
||||
int c, nSuppNew, PivotVar, nDivs = 0;
|
||||
int pTaboo[16], nTaboo = Acb_NtkCollectTaboo( p, Pivot, nTabooMax, pTaboo );
|
||||
if ( nTaboo == 0 )
|
||||
return;
|
||||
assert( nTabooMax == 0 || nTaboo <= nTabooMax );
|
||||
assert( nTaboo <= 16 );
|
||||
|
||||
// compute divisor and window for these nodes
|
||||
vWin = Acb_NtkWindow( p, Pivot, pTaboo, nTaboo, nDivMax, nTfoLevs, nFanMax, &nDivs );
|
||||
PivotVar = Vec_IntFind(vWin, Abc_Var2Lit(Pivot, 0));
|
||||
|
||||
// derive CNF and SAT solvers
|
||||
pCnf = Acb_NtkWindow2Cnf( p, vWin, Pivot );
|
||||
pSat1 = Acb_NtkWindow2Solver( pCnf, PivotVar, nDivs, 1 );
|
||||
// check constants
|
||||
for ( c = 0; c < 2; c++ )
|
||||
{
|
||||
int Lit = Abc_Var2Lit( PivotVar, c );
|
||||
int status = sat_solver_solve( pSat1, &Lit, &Lit + 1, 0, 0, 0, 0 );
|
||||
if ( status == l_False )
|
||||
{
|
||||
Acb_NtkUpdateNode( p, Pivot, c ? ~(word)0 : 0, NULL );
|
||||
goto cleanup;
|
||||
}
|
||||
assert( status == l_True );
|
||||
}
|
||||
|
||||
pSat2 = Acb_NtkWindow2Solver( pCnf, PivotVar, nDivs, 2 );
|
||||
//pSat6 = Acb_NtkWindow2Solver( pCnf, PivotVar, nDivs, 6 );
|
||||
|
||||
// try solving the original support
|
||||
Vec_IntClear( vSupp );
|
||||
Vec_IntAppend( vSupp, vDivs );
|
||||
nSuppNew = sat_solver_minimize_assumptions( pSat, Vec_IntArray(vSupp), Vec_IntSize(vSupp), 0 );
|
||||
vSupp = Vec_IntStartNatural( nDivs );
|
||||
Vec_IntVars2Lits( vSupp, 2*pCnf->nVars, 0 );
|
||||
nSuppNew = sat_solver_minimize_assumptions( pSat2, Vec_IntArray(vSupp), Vec_IntSize(vSupp), 0 );
|
||||
Vec_IntShrink( vSupp, nSuppNew );
|
||||
Vec_IntLits2Vars( vSupp, -2*pCnf->nVars );
|
||||
|
||||
// try solving by level
|
||||
if ( nSuppNew <= nLutSize )
|
||||
{
|
||||
int FreeVar = sat_solver_nvars( pSat1 ) - 1;
|
||||
word uTruth;
|
||||
|
||||
Acb_NtkUnmarkWindow( p, vWin );
|
||||
Vec_IntVars2Lits( vSupp, pCnf->nVars, 0 );
|
||||
uTruth = Acb_ComputeFunction( pSat1, PivotVar, FreeVar, vSupp );
|
||||
Vec_IntLits2Vars( vSupp, -pCnf->nVars );
|
||||
// create support in terms of nodes
|
||||
Vec_IntRemap( vSupp, vWin );
|
||||
Vec_IntLits2Vars( vSupp, 0 );
|
||||
|
||||
Acb_NtkUpdateNode( p, Pivot, uTruth, vSupp );
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// cleanup
|
||||
cleanup:
|
||||
if ( pSat1 ) sat_solver_delete( pSat1 );
|
||||
if ( pSat2 ) sat_solver_delete( pSat2 );
|
||||
if ( pSat3 ) sat_solver_delete( pSat3 );
|
||||
Cnf_DataFree( pCnf );
|
||||
Vec_IntFree( vWin );
|
||||
Vec_IntFree( vDivs );
|
||||
Vec_IntFree( vSupp );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Acb_NtkOpt( Acb_Ntk_t * p, Acb_Par_t * pPars )
|
||||
{
|
||||
int iObj;
|
||||
if ( pPars->fArea )
|
||||
{
|
||||
Acb_NtkForEachNode( p, iObj )
|
||||
Acb_NtkOptNode( p, iObj, pPars->nTabooMax, pPars->nDivMax, pPars->nTfoLevMax, pPars->nFanoutMax, pPars->nLutSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
Acb_NtkUpdateTiming( p, -1 );
|
||||
while ( 1 )
|
||||
{
|
||||
int iObj = 0;
|
||||
Acb_NtkOptNode( p, iObj, 0, pPars->nDivMax, pPars->nTfoLevMax, pPars->nFanoutMax, pPars->nLutSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [acbPar.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Hierarchical word-level netlist.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - July 21, 2015.]
|
||||
|
||||
Revision [$Id: acbPar.h,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__base__acb__acbPar_h
|
||||
#define ABC__base__acb__acbPar_h
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Acb_Par_t_ Acb_Par_t;
|
||||
struct Acb_Par_t_
|
||||
{
|
||||
int nLutSize; // LUT size
|
||||
int nTfoLevMax; // the maximum fanout levels
|
||||
int nTfiLevMax; // the maximum fanin levels
|
||||
int nFanoutMax; // the maximum number of fanouts
|
||||
int nDivMax; // the maximum divisor count
|
||||
int nTabooMax; // the minimum MFFC size
|
||||
int nGrowthLevel; // the maximum allowed growth in level
|
||||
int nBTLimit; // the maximum number of conflicts in one SAT run
|
||||
int nNodesMax; // the maximum number of nodes to try
|
||||
int iNodeOne; // one particular node to try
|
||||
int fArea; // performs optimization for area
|
||||
int fMoreEffort; // performs high-affort minimization
|
||||
int fVerbose; // enable basic stats
|
||||
int fVeryVerbose; // enable detailed stats
|
||||
};
|
||||
|
||||
|
||||
/*=== acbAbc.c =============================================================*/
|
||||
extern void Acb_ParSetDefault( Acb_Par_t * pPars );
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -42,13 +42,24 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_ObjAddFanout( Acb_Ntk_t * p, int iObj )
|
||||
{
|
||||
int k, iFanin, * pFanins;
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Vec_IntPush( Vec_WecEntry(&p->vFanouts, iFanin), iObj );
|
||||
}
|
||||
void Acb_ObjRemoveFanout( Acb_Ntk_t * p, int iObj )
|
||||
{
|
||||
int k, iFanin, * pFanins;
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Vec_IntRemove( Vec_WecEntry(&p->vFanouts, iFanin), iObj );
|
||||
}
|
||||
void Acb_NtkCreateFanout( Acb_Ntk_t * p )
|
||||
{
|
||||
int k, iObj, iFanin, * pFanins;
|
||||
int iObj;
|
||||
Vec_WecInit( &p->vFanouts, Acb_NtkObjNumMax(p) );
|
||||
Acb_NtkForEachObj( p, iObj )
|
||||
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
||||
Vec_IntPush( Vec_WecEntry(&p->vFanouts, iFanin), iObj );
|
||||
Acb_ObjAddFanout( p, iObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -263,12 +274,11 @@ int Acb_NtkComputePathsR( Acb_Ntk_t * p, Vec_Int_t * vTfi )
|
|||
|
||||
int Acb_NtkComputePaths( Acb_Ntk_t * p )
|
||||
{
|
||||
int LevelD = Acb_NtkComputeLevelD( p, NULL );
|
||||
int LevelR = Acb_NtkComputeLevelR( p, NULL );
|
||||
int PathD = Acb_NtkComputePathsD( p, NULL );
|
||||
int PathR = Acb_NtkComputePathsR( p, NULL );
|
||||
assert( PathD == PathR );
|
||||
return PathR;
|
||||
Acb_NtkComputeLevelD( p, NULL );
|
||||
Acb_NtkComputeLevelR( p, NULL );
|
||||
Acb_NtkComputePathsD( p, NULL );
|
||||
Acb_NtkComputePathsR( p, NULL );
|
||||
return p->nPaths;
|
||||
}
|
||||
|
||||
void Abc_NtkComputePaths( Abc_Ntk_t * p )
|
||||
|
|
@ -310,10 +320,10 @@ void Acb_NtkUpdateTiming( Acb_Ntk_t * p, int iObj )
|
|||
// assuming that level of the new nodes is up to date
|
||||
Vec_Int_t * vTfi = Acb_ObjCollectTfi( p, iObj, 1 );
|
||||
Vec_Int_t * vTfo = Acb_ObjCollectTfo( p, iObj, 1 );
|
||||
int nLevelD = Acb_NtkComputeLevelD( p, vTfo );
|
||||
int nLevelR = Acb_NtkComputeLevelR( p, vTfi );
|
||||
int nPathD = Acb_NtkComputePathsD( p, vTfo );
|
||||
int nPathR = Acb_NtkComputePathsR( p, vTfi );
|
||||
Acb_NtkComputeLevelD( p, vTfo );
|
||||
Acb_NtkComputeLevelR( p, vTfi );
|
||||
Acb_NtkComputePathsD( p, vTfo );
|
||||
Acb_NtkComputePathsR( p, vTfi );
|
||||
Vec_IntForEachEntry( vTfi, Entry, i )
|
||||
Acb_ObjUpdateTiming( p, Entry );
|
||||
Vec_IntForEachEntry( vTfo, Entry, i )
|
||||
|
|
@ -321,16 +331,40 @@ void Acb_NtkUpdateTiming( Acb_Ntk_t * p, int iObj )
|
|||
}
|
||||
else
|
||||
{
|
||||
int LevelD = Acb_NtkComputeLevelD( p, NULL );
|
||||
int LevelR = Acb_NtkComputeLevelR( p, NULL );
|
||||
int PathD = Acb_NtkComputePathsD( p, NULL );
|
||||
int PathR = Acb_NtkComputePathsR( p, NULL );
|
||||
Acb_NtkComputeLevelD( p, NULL );
|
||||
Acb_NtkComputeLevelR( p, NULL );
|
||||
Acb_NtkComputePathsD( p, NULL );
|
||||
Acb_NtkComputePathsR( p, NULL );
|
||||
Acb_NtkForEachNode( p, Entry )
|
||||
Acb_ObjUpdateTiming( p, Entry );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_NtkUpdateNode( Acb_Ntk_t * p, int Pivot, word uTruth, Vec_Int_t * vSupp )
|
||||
{
|
||||
int i, iFanin;
|
||||
Vec_WrdSetEntry( &p->vObjTruth, Pivot, uTruth );
|
||||
Acb_ObjRemoveFanout( p, Pivot );
|
||||
Acb_ObjRemoveFanins( p, Pivot );
|
||||
Vec_IntForEachEntry( vSupp, iFanin, i )
|
||||
Acb_ObjAddFanin( p, Pivot, iFanin );
|
||||
Acb_ObjAddFanout( p, Pivot );
|
||||
Acb_NtkUpdateTiming( p, Pivot );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -855,7 +855,7 @@ int Sdb_StoDiffExactlyOne3( Vec_Wec_t * vCuts, int Limit, int * pCut, int * pCou
|
|||
}
|
||||
Vec_Int_t * Sdb_StoFindAll( Vec_Wec_t * vCuts )
|
||||
{
|
||||
int i, k, Entry, iNew = -1;
|
||||
int i, k, Entry;
|
||||
Vec_Int_t * vCut, * vAll = Vec_IntAlloc( 100 );
|
||||
Vec_WecForEachLevel( vCuts, vCut, i )
|
||||
Vec_IntForEachEntry( vCut, Entry, k )
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ extern Cnf_Dat_t * Cnf_DataAlloc( Aig_Man_t * pAig, int nVars, int nClauses,
|
|||
extern Cnf_Dat_t * Cnf_DataDup( Cnf_Dat_t * p );
|
||||
extern void Cnf_DataFree( Cnf_Dat_t * p );
|
||||
extern void Cnf_DataLift( Cnf_Dat_t * p, int nVarsPlus );
|
||||
extern void Cnf_DataFlipLastLiteral( Cnf_Dat_t * p );
|
||||
extern Vec_Int_t * Cnf_DataCollectFlipLits( Cnf_Dat_t * p, int iFlipVar );
|
||||
extern void Cnf_DataLiftAndFlipLits( Cnf_Dat_t * p, int nVarsPlus, Vec_Int_t * vLits );
|
||||
extern void Cnf_DataPrint( Cnf_Dat_t * p, int fReadable );
|
||||
extern void Cnf_DataWriteIntoFile( Cnf_Dat_t * p, char * pFileName, int fReadable, Vec_Int_t * vForAlls, Vec_Int_t * vExists );
|
||||
extern void * Cnf_DataWriteIntoSolver( Cnf_Dat_t * p, int nFrames, int fInit );
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ void Cnf_DataFree( Cnf_Dat_t * p )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes CNF into a file.]
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -215,26 +215,26 @@ void Cnf_DataLift( Cnf_Dat_t * p, int nVarsPlus )
|
|||
for ( v = 0; v < p->nLiterals; v++ )
|
||||
p->pClauses[0][v] += 2*nVarsPlus;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes CNF into a file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cnf_DataFlipLastLiteral( Cnf_Dat_t * p )
|
||||
Vec_Int_t * Cnf_DataCollectFlipLits( Cnf_Dat_t * p, int iFlipVar )
|
||||
{
|
||||
p->pClauses[0][p->nLiterals-1] = lit_neg( p->pClauses[0][p->nLiterals-1] );
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 100 ); int v;
|
||||
assert( p->pMan == NULL );
|
||||
for ( v = 0; v < p->nLiterals; v++ )
|
||||
if ( Abc_Lit2Var(p->pClauses[0][v]) == iFlipVar )
|
||||
Vec_IntPush( vLits, v );
|
||||
return vLits;
|
||||
}
|
||||
void Cnf_DataLiftAndFlipLits( Cnf_Dat_t * p, int nVarsPlus, Vec_Int_t * vLits )
|
||||
{
|
||||
int i, iLit;
|
||||
assert( p->pMan == NULL );
|
||||
Vec_IntForEachEntry( vLits, iLit, i )
|
||||
p->pClauses[0][iLit] = Abc_LitNot(p->pClauses[0][iLit]) + 2*nVarsPlus;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes CNF into a file.]
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue