Commit 33012d95 by Alan Mishchenko

Version abc50904

parent dce73ade
......@@ -6,14 +6,12 @@ CP := cp
PROG := abc
MODULES := src/base/abc src/base/cmd src/base/io src/base/main \
MODULES := src/base/abc src/base/abci src/base/abcs src/base/cmd src/base/io src/base/main \
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse src/bdd/reo \
src/map/fpga src/map/mapper src/map/mio src/map/super \
src/misc/extra src/misc/st src/misc/util src/misc/vec \
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr \
src/sat/asat src/sat/csat src/sat/msat src/sat/fraig src/sat/sim \
src/seq \
src/sop/mvc
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/vec \
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim \
src/sat/asat src/sat/csat src/sat/msat src/sat/fraig
default: $(PROG)
......
No preview for this file type
......@@ -30,6 +30,7 @@ alias sa set autoexec ps
alias so source -x
alias st strash
alias sw sweep
alias t "r dalu.blif; st; psu"
alias u undo
alias wb write_blif
alias wl write_blif
......
......@@ -165,6 +165,8 @@ struct Abc_Ntk_t_
// level information (for AIGs)
int LevelMax; // maximum number of levels
Vec_Int_t * vLevelsR; // level in the reverse topological order
// support information
Vec_Ptr_t * vSupps;
// the external don't-care if given
Abc_Ntk_t * pExdc; // the EXDC network
// miscellaneous data members
......@@ -415,39 +417,6 @@ extern bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj );
extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
/*=== abcCollapse.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose );
/*=== abcCreate.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func );
extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
extern void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkStartRead( char * pName );
extern void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis );
extern Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues );
extern Abc_Ntk_t * Abc_NtkSplitNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode );
extern void Abc_NtkDelete( Abc_Ntk_t * pNtk );
extern void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew );
extern Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew );
extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
extern Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode );
/*=== abcCut.c ==========================================================*/
extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj );
extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj );
......@@ -486,7 +455,6 @@ extern void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk );
extern bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch );
extern int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk );
/*=== abcMap.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose );
extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
/*=== abcMiter.c ==========================================================*/
extern int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk );
......@@ -495,11 +463,35 @@ extern int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk );
extern int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode );
/*=== abcMiter.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
extern Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 );
extern Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 );
extern int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter );
extern void Abc_NtkMiterReport( Abc_Ntk_t * pMiter );
extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
extern Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial );
/*=== abcObj.c ==========================================================*/
extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern void Abc_ObjRecycle( Abc_Obj_t * pObj );
extern void Abc_ObjAdd( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew );
extern Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew );
extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
extern Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode );
/*=== abcNames.c ====================================================*/
extern char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName );
extern char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix );
......@@ -529,6 +521,20 @@ extern Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc,
extern Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk );
extern DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fLatchOnly );
extern void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk );
/*=== abcNtk.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func );
extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
extern void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
extern void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkStartRead( char * pName );
extern void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis );
extern Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues );
extern Abc_Ntk_t * Abc_NtkSplitNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode );
extern void Abc_NtkDelete( Abc_Ntk_t * pNtk );
extern void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk );
/*=== abcPrint.c ==========================================================*/
extern void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored );
extern void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk );
......
SRC += src/base/abc/abc.c \
src/base/abc/abcAig.c \
src/base/abc/abcAttach.c \
src/base/abc/abcBalance.c \
SRC += src/base/abc/abcAig.c \
src/base/abc/abcCheck.c \
src/base/abc/abcCollapse.c \
src/base/abc/abcCreate.c \
src/base/abc/abcCut.c \
src/base/abc/abcDfs.c \
src/base/abc/abcDsd.c \
src/base/abc/abcFanio.c \
src/base/abc/abcFpga.c \
src/base/abc/abcFraig.c \
src/base/abc/abcFunc.c \
src/base/abc/abcFxu.c \
src/base/abc/abcLatch.c \
src/base/abc/abcMap.c \
src/base/abc/abcMinBase.c \
src/base/abc/abcMiter.c \
src/base/abc/abcNames.c \
src/base/abc/abcNetlist.c \
src/base/abc/abcNtbdd.c \
src/base/abc/abcPrint.c \
src/base/abc/abcReconv.c \
src/base/abc/abcRefactor.c \
src/base/abc/abcNtk.c \
src/base/abc/abcObj.c \
src/base/abc/abcRefs.c \
src/base/abc/abcRenode.c \
src/base/abc/abcRewrite.c \
src/base/abc/abcSat.c \
src/base/abc/abcSeq.c \
src/base/abc/abcSeqRetime.c \
src/base/abc/abcShow.c \
src/base/abc/abcSop.c \
src/base/abc/abcStrash.c \
src/base/abc/abcSweep.c \
src/base/abc/abcSymm.c \
src/base/abc/abcTiming.c \
src/base/abc/abcUnreach.c \
src/base/abc/abcUtil.c \
src/base/abc/abcVerify.c
src/base/abc/abcUtil.c
......@@ -65,6 +65,7 @@ static int Abc_CommandOneOutput ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandOneNode ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv );
......@@ -140,6 +141,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "one_node", Abc_CommandOneNode, 1 );
Cmd_CommandAdd( pAbc, "Various", "short_names", Abc_CommandShortNames, 0 );
Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 );
Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 );
......@@ -591,10 +593,11 @@ usage:
***********************************************************************/
int Abc_CommandPrintSupport( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Vec_Ptr_t * vSuppFun;
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
extern void * Sim_ComputeSupp( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNet(pAbc);
pOut = Abc_FrameReadOut(pAbc);
......@@ -619,12 +622,20 @@ int Abc_CommandPrintSupport( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( !Abc_NtkIsComb(pNtk) )
{
fprintf( pErr, "This command works only for combinational networks.\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
fprintf( pErr, "This command works only for AIGs.\n" );
return 1;
}
Sim_ComputeSupp( pNtk );
vSuppFun = Sim_ComputeFunSupp( pNtk );
free( vSuppFun->pArray[0] );
Vec_PtrFree( vSuppFun );
return 0;
usage:
......@@ -660,7 +671,7 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fUseBdds = 1;
fUseBdds = 0;
fNaive = 0;
fVerbose = 0;
util_getopt_reset();
......@@ -688,6 +699,11 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsComb(pNtk) )
{
fprintf( pErr, "This command works only for combinational networks.\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
fprintf( pErr, "This command works only for AIGs.\n" );
......@@ -2758,6 +2774,62 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
int c;
pNtk = Abc_FrameReadNet(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
// run the command
pNtkRes = Abc_NtkMiterForCofactors( pNtk, 0, 0, -1 );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Command has failed.\n" );
return 1;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
fprintf( pErr, "usage: test [-h]\n" );
fprintf( pErr, "\t testbench for new procedures\n" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
......@@ -3249,10 +3321,11 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
char Buffer[100];
double DelayTarget;
int fRecovery;
int fVerbose;
int fSweep;
int fSwitching;
int fVerbose;
int c;
extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose );
extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose );
pNtk = Abc_FrameReadNet(pAbc);
pOut = Abc_FrameReadOut(pAbc);
......@@ -3262,9 +3335,10 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
DelayTarget =-1;
fRecovery = 1;
fSweep = 1;
fSwitching = 0;
fVerbose = 0;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "Dasvh" ) ) != EOF )
while ( ( c = util_getopt( argc, argv, "Daspvh" ) ) != EOF )
{
switch ( c )
{
......@@ -3285,6 +3359,9 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
case 's':
fSweep ^= 1;
break;
case 'p':
fSwitching ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
......@@ -3318,7 +3395,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
}
fprintf( pOut, "The network was strashed and balanced before mapping.\n" );
// get the new network
pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fVerbose );
pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose );
if ( pNtkRes == NULL )
{
Abc_NtkDelete( pNtk );
......@@ -3330,7 +3407,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
else
{
// get the new network
pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fVerbose );
pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Mapping has failed.\n" );
......@@ -3350,11 +3427,12 @@ usage:
sprintf( Buffer, "not used" );
else
sprintf( Buffer, "%.3f", DelayTarget );
fprintf( pErr, "usage: map [-D num] [-asvh]\n" );
fprintf( pErr, "usage: map [-D num] [-aspvh]\n" );
fprintf( pErr, "\t performs standard cell mapping of the current network\n" );
fprintf( pErr, "\t-D num : sets the global required times [default = %s]\n", Buffer );
fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" );
fprintf( pErr, "\t-s : toggles sweep after mapping [default = %s]\n", fSweep? "yes": "no" );
fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", fSwitching? "yes": "no" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
......@@ -3569,8 +3647,9 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtk, * pNtkRes;
int c;
int fRecovery;
int fSwitching;
int fVerbose;
extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose );
extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fSwitching, int fVerbose );
pNtk = Abc_FrameReadNet(pAbc);
pOut = Abc_FrameReadOut(pAbc);
......@@ -3578,15 +3657,19 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
fRecovery = 1;
fSwitching = 0;
fVerbose = 0;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "avh" ) ) != EOF )
while ( ( c = util_getopt( argc, argv, "apvh" ) ) != EOF )
{
switch ( c )
{
case 'a':
fRecovery ^= 1;
break;
case 'p':
fSwitching ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
......@@ -3621,7 +3704,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
}
fprintf( pOut, "The network was strashed and balanced before FPGA mapping.\n" );
// get the new network
pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fVerbose );
pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fSwitching, fVerbose );
if ( pNtkRes == NULL )
{
Abc_NtkDelete( pNtk );
......@@ -3633,7 +3716,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
else
{
// get the new network
pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fVerbose );
pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fSwitching, fVerbose );
if ( pNtkRes == NULL )
{
fprintf( pErr, "FPGA mapping has failed.\n" );
......@@ -3645,9 +3728,10 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: fpga [-avh]\n" );
fprintf( pErr, "usage: fpga [-apvh]\n" );
fprintf( pErr, "\t performs FPGA mapping of the current network\n" );
fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" );
fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", fSwitching? "yes": "no" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : prints the command usage\n");
return 1;
......
......@@ -25,8 +25,8 @@
////////////////////////////////////////////////////////////////////////
static void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate );
static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, bool fDuplicate );
static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, int fDuplicate );
static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, Vec_Vec_t * vStorage, bool fDuplicate );
static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vSuper, int fDuplicate );
static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate );
////////////////////////////////////////////////////////////////////////
......@@ -78,6 +78,7 @@ void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplica
{
int fCheck = 1;
ProgressBar * pProgress;
Vec_Vec_t * vStorage;
Abc_Obj_t * pNode, * pDriver;
int i;
......@@ -85,6 +86,8 @@ void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplica
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkAig->pManFunc);
// set the level of PIs of AIG according to the arrival times of the old network
Abc_NtkSetNodeLevelsArrival( pNtk );
// allocate temporary storage for supergates
vStorage = Vec_VecStart( Abc_AigGetLevelNum(pNtk) + 1 );
// perform balancing of POs
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
......@@ -92,9 +95,10 @@ void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplica
Extra_ProgressBarUpdate( pProgress, i, NULL );
// strash the driver node
pDriver = Abc_ObjFanin0(pNode);
Abc_NodeBalance_rec( pNtkAig, pDriver, fDuplicate );
Abc_NodeBalance_rec( pNtkAig, pDriver, vStorage, fDuplicate );
}
Extra_ProgressBarStop( pProgress );
Vec_VecFree( vStorage );
}
/**Function*************************************************************
......@@ -108,7 +112,7 @@ void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplica
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, bool fDuplicate )
Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_Vec_t * vStorage, bool fDuplicate )
{
Abc_Aig_t * pMan = pNtkNew->pManFunc;
Abc_Obj_t * pNodeNew, * pNode1, * pNode2;
......@@ -120,17 +124,16 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, bool
return pNodeOld->pCopy;
assert( Abc_ObjIsNode(pNodeOld) );
// get the implication supergate
vSuper = Abc_NodeBalanceCone( pNodeOld, fDuplicate );
vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, fDuplicate );
if ( vSuper->nSize == 0 )
{ // it means that the supergate contains two nodes in the opposite polarity
Vec_PtrFree( vSuper );
pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pMan));
return pNodeOld->pCopy;
}
// for each old node, derive the new well-balanced node
for ( i = 0; i < vSuper->nSize; i++ )
{
pNodeNew = Abc_NodeBalance_rec( pNtkNew, Abc_ObjRegular(vSuper->pArray[i]), fDuplicate );
pNodeNew = Abc_NodeBalance_rec( pNtkNew, Abc_ObjRegular(vSuper->pArray[i]), vStorage, fDuplicate );
vSuper->pArray[i] = Abc_ObjNotCond( pNodeNew, Abc_ObjIsComplement(vSuper->pArray[i]) );
}
// sort the new nodes by level in the decreasing order
......@@ -147,7 +150,6 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, bool
assert( pNodeOld->pCopy == NULL );
// mark the old node with the new node
pNodeOld->pCopy = vSuper->pArray[0];
Vec_PtrFree( vSuper );
return pNodeOld->pCopy;
}
......@@ -164,12 +166,13 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, bool
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, int fDuplicate )
Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vStorage, int fDuplicate )
{
Vec_Ptr_t * vNodes;
int RetValue, i;
assert( !Abc_ObjIsComplement(pNode) );
vNodes = Vec_PtrAlloc( 4 );
vNodes = Vec_VecEntry( vStorage, pNode->Level );
Vec_PtrClear( vNodes );
RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, fDuplicate );
assert( vNodes->nSize > 0 );
for ( i = 0; i < vNodes->nSize; i++ )
......
......@@ -25,7 +25,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose );
static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose );
static Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk );
static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga );
......@@ -44,11 +44,14 @@ static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNo
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fSwitching, int fVerbose )
{
int fCheck = 1;
Abc_Ntk_t * pNtkNew;
Fpga_Man_t * pMan;
Vec_Int_t * vSwitching;
float * pSwitching = NULL;
int fShowSwitching = 0;
assert( Abc_NtkIsStrash(pNtk) );
......@@ -56,10 +59,21 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Performing FPGA mapping with choices.\n" );
// compute switching activity
fShowSwitching |= fSwitching;
if ( fShowSwitching )
{
extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns );
vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 );
pSwitching = (float *)vSwitching->pArray;
}
// perform FPGA mapping
pMan = Abc_NtkToFpga( pNtk, fRecovery, fVerbose );
pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fVerbose );
if ( pSwitching ) Vec_IntFree( vSwitching );
if ( pMan == NULL )
return NULL;
Fpga_ManSetSwitching( pMan, fSwitching );
if ( !Fpga_Mapping( pMan ) )
{
Fpga_ManFree( pMan );
......@@ -96,7 +110,7 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
SeeAlso []
***********************************************************************/
Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose )
{
Fpga_Man_t * pMan;
ProgressBar * pProgress;
......@@ -118,7 +132,12 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
// create PIs and remember them in the old nodes
Abc_NtkCleanCopy( pNtk );
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Fpga_ManReadInputs(pMan)[i];
{
pNodeFpga = Fpga_ManReadInputs(pMan)[i];
pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
if ( pSwitching )
Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
}
// load the AIG into the mapper
vNodes = Abc_AigDfs( pNtk, 0, 0 );
......@@ -139,6 +158,8 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
assert( pNode->pCopy == NULL );
// remember the node
pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
if ( pSwitching )
Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
// set up the choice node
if ( Abc_NodeIsAigChoice( pNode ) )
for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
......@@ -197,8 +218,8 @@ Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_NtkFinalize( pNtk, pNtkNew );
// decouple the PO driver nodes to reduce the number of levels
nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
if ( nDupGates && Fpga_ManReadVerbose(pMan) )
printf( "Duplicated %d gates to decouple the PO drivers.\n", nDupGates );
// if ( nDupGates && Fpga_ManReadVerbose(pMan) )
// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
return pNtkNew;
}
......
......@@ -52,12 +52,13 @@ static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode );
Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes )
{
int fCheck = 1;
Fraig_Params_t * pPars = pParams;
Abc_Ntk_t * pNtkNew;
Fraig_Man_t * pMan;
// perform fraiging
pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes );
// prove the miter if asked to
if ( ((Fraig_Params_t *)pParams)->fTryProve )
if ( pPars->fTryProve )
Fraig_ManProveMiter( pMan );
// reconstruct FRAIG in the new network
pNtkNew = Abc_NtkFromFraig( pMan, pNtk );
......@@ -106,9 +107,11 @@ Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fA
// perform strashing
vNodes = Abc_AigDfs( pNtk, fAllNodes, 0 );
if ( !pParams->fInternal )
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
if ( !pParams->fInternal )
Extra_ProgressBarUpdate( pProgress, i, NULL );
if ( pNode == pConst1 )
pNodeFraig = Fraig_ManReadConst1(pMan);
......@@ -121,12 +124,13 @@ Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fA
assert( pNode->pCopy == NULL );
pNode->pCopy = (Abc_Obj_t *)pNodeFraig;
}
if ( !pParams->fInternal )
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodes );
// set the primary outputs
Abc_NtkForEachCo( pNtk, pNode, i )
Fraig_ManSetPo( pMan, (Fraig_Node_t *)Abc_ObjFanin0(pNode)->pCopy );
Fraig_ManSetPo( pMan, (Fraig_Node_t *)Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ) );
return pMan;
}
......@@ -145,7 +149,7 @@ Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
{
ProgressBar * pProgress;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pNode;//, * pNodeNew;
Abc_Obj_t * pNode, * pNodeNew;
int i;
// create the new network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG );
......@@ -159,11 +163,10 @@ Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_NtkForEachCo( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
Abc_ObjFanin0(pNode)->pCopy = Abc_NodeFromFraig_rec( pNtkNew, Fraig_ManReadOutputs(pMan)[i] );
pNodeNew = Abc_NodeFromFraig_rec( pNtkNew, Fraig_ManReadOutputs(pMan)[i] );
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
}
Extra_ProgressBarStop( pProgress );
// finalize the new network
Abc_NtkFinalize( pNtk, pNtkNew );
return pNtkNew;
}
......
......@@ -27,7 +27,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose );
static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose );
static Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
......@@ -54,11 +54,14 @@ static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Sup
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose )
Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose )
{
int fCheck = 1;
Abc_Ntk_t * pNtkNew;
Map_Man_t * pMan;
Vec_Int_t * vSwitching;
float * pSwitching = NULL;
int fShowSwitching = 0;
int clk;
assert( Abc_NtkIsStrash(pNtk) );
......@@ -82,11 +85,22 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Performing mapping with choices.\n" );
// compute switching activity
fShowSwitching |= fSwitching;
if ( fShowSwitching )
{
extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns );
vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 );
pSwitching = (float *)vSwitching->pArray;
}
// perform the mapping
pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, fVerbose );
pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, pSwitching, fVerbose );
if ( pSwitching ) Vec_IntFree( vSwitching );
if ( pMan == NULL )
return NULL;
clk = clock();
Map_ManSetSwitching( pMan, fSwitching );
if ( !Map_Mapping( pMan ) )
{
Map_ManFree( pMan );
......@@ -121,7 +135,7 @@ clk = clock();
SeeAlso []
***********************************************************************/
Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose )
Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose )
{
Map_Man_t * pMan;
ProgressBar * pProgress;
......@@ -144,7 +158,12 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, i
// create PIs and remember them in the old nodes
Abc_NtkCleanCopy( pNtk );
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Map_ManReadInputs(pMan)[i];
{
pNodeMap = Map_ManReadInputs(pMan)[i];
pNode->pCopy = (Abc_Obj_t *)pNodeMap;
if ( pSwitching )
Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
}
// load the AIG into the mapper
vNodes = Abc_AigDfs( pNtk, 0, 0 );
......@@ -165,6 +184,8 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, i
assert( pNode->pCopy == NULL );
// remember the node
pNode->pCopy = (Abc_Obj_t *)pNodeMap;
if ( pSwitching )
Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
// set up the choice node
if ( Abc_NodeIsAigChoice( pNode ) )
for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
......@@ -224,8 +245,8 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
Extra_ProgressBarStop( pProgress );
// decouple the PO driver nodes to reduce the number of levels
nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
if ( nDupGates && Map_ManReadVerbose(pMan) )
printf( "Duplicated %d gates to decouple the PO drivers.\n", nDupGates );
// if ( nDupGates && Map_ManReadVerbose(pMan) )
// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
return pNtkNew;
}
......@@ -446,7 +467,7 @@ Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
printf( "Performing mapping with choices.\n" );
// perform the mapping
pMan = Abc_NtkToMap( pNtk, -1, 1, 0 );
pMan = Abc_NtkToMap( pNtk, -1, 1, NULL, 0 );
if ( pMan == NULL )
return NULL;
if ( !Map_Mapping( pMan ) )
......
......@@ -27,7 +27,7 @@
static Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb );
static void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter );
static void Abc_NtkMiterAddOneNode( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode );
static void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode );
static void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb );
static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame, Vec_Ptr_t * vNodes );
......@@ -121,8 +121,8 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk
Abc_Obj_t * pObj, * pObjNew;
int i;
// clean the copy field in all objects
Abc_NtkCleanCopy( pNtk1 );
Abc_NtkCleanCopy( pNtk2 );
// Abc_NtkCleanCopy( pNtk1 );
// Abc_NtkCleanCopy( pNtk2 );
if ( fComb )
{
// create new PIs and remember them in the old PIs
......@@ -224,7 +224,7 @@ void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter )
SeeAlso []
***********************************************************************/
void Abc_NtkMiterAddOneNode( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pRoot )
void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pRoot )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pNodeNew, * pConst1, * pConst1New;
......@@ -310,7 +310,7 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 )
Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 )
{
int fCheck = 1;
char Buffer[100];
......@@ -324,7 +324,7 @@ Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 )
// start the new network
pNtkMiter = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG );
sprintf( Buffer, "%s_%s_miter", pNtk->pName, Abc_ObjName(Abc_NtkCo(pNtk, Out)) );
sprintf( Buffer, "%s_miter", Abc_ObjName(Abc_NtkCo(pNtk, Out)) );
pNtkMiter->pName = util_strsav(Buffer);
// get the root output
......@@ -337,7 +337,7 @@ Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 )
if ( In2 >= 0 )
Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc );
// add the first cofactor
Abc_NtkMiterAddOneNode( pNtk, pNtkMiter, pRoot );
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
// save the output
pOutput1 = Abc_ObjFanin0(pRoot)->pCopy;
......@@ -347,7 +347,7 @@ Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 )
if ( In2 >= 0 )
Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) );
// add the second cofactor
Abc_NtkMiterAddOneNode( pNtk, pNtkMiter, pRoot );
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
// save the output
pOutput2 = Abc_ObjFanin0(pRoot)->pCopy;
......
......@@ -25,6 +25,7 @@
////////////////////////////////////////////////////////////////////////
static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose );
static void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose );
static void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose );
static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms );
......@@ -48,7 +49,25 @@ void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose
if ( fUseBdds || fNaive )
Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fVerbose );
else
printf( "This option is currently not implemented.\n" );
Abc_NtkSymmetriesUsingSandS( pNtk, fVerbose );
}
/**Function*************************************************************
Synopsis [Symmetry computation using simulation and SAT.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose )
{
extern int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk );
int nSymms = Sim_ComputeTwoVarSymms( pNtk );
printf( "The total number of symmetries is %d.\n", nSymms );
}
/**Function*************************************************************
......
/**CFile****************************************************************
FileName [simUnate.c]
FileName [abc_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Simulation to determine unateness of variables.]
Synopsis []
Author [Alan Mishchenko]
......@@ -14,12 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: simUnate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "sim.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
SRC += src/base/abci/abc.c \
src/base/abci/abcAttach.c \
src/base/abci/abcBalance.c \
src/base/abci/abcCollapse.c \
src/base/abci/abcCut.c \
src/base/abci/abcDsd.c \
src/base/abci/abcFpga.c \
src/base/abci/abcFraig.c \
src/base/abci/abcFxu.c \
src/base/abci/abcMap.c \
src/base/abci/abcMiter.c \
src/base/abci/abcNtbdd.c \
src/base/abci/abcPrint.c \
src/base/abci/abcReconv.c \
src/base/abci/abcRefactor.c \
src/base/abci/abcRenode.c \
src/base/abci/abcRewrite.c \
src/base/abci/abcSat.c \
src/base/abci/abcStrash.c \
src/base/abci/abcSweep.c \
src/base/abci/abcSymm.c \
src/base/abci/abcTiming.c \
src/base/abci/abcUnreach.c \
src/base/abci/abcVerify.c
/**CFile****************************************************************
FileName [simSym.c]
FileName [abc_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Simulation to determine two-variable symmetries.]
Synopsis []
Author [Alan Mishchenko]
......@@ -14,12 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: simSym.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "sim.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
SRC += src/base/abcs/abcRetime.c \
src/base/abcs/abcSeq.c
......@@ -91,6 +91,7 @@ extern void Fpga_ManSetFanoutViolations( Fpga_Man_t * p, int nVio );
extern void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes );
extern void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices );
extern void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose );
extern void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching );
extern void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches );
extern void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName );
......@@ -110,6 +111,7 @@ extern void Fpga_NodeSetData1( Fpga_Node_t * p, Fpga_Node_t * pNode )
extern void Fpga_NodeSetArrival( Fpga_Node_t * p, float Time );
extern void Fpga_NodeSetNextE( Fpga_Node_t * p, Fpga_Node_t * pNextE );
extern void Fpga_NodeSetRepr( Fpga_Node_t * p, Fpga_Node_t * pRepr );
extern void Fpga_NodeSetSwitching( Fpga_Node_t * p, float Switching );
extern int Fpga_NodeIsConst( Fpga_Node_t * p );
extern int Fpga_NodeIsVar( Fpga_Node_t * p );
......
......@@ -97,22 +97,26 @@ int Fpga_Mapping( Fpga_Man_t * p )
***********************************************************************/
int Fpga_MappingPostProcess( Fpga_Man_t * p )
{
float aAreaTotalPrev, aAreaTotalCur, aAreaTotalCur2;
int fShowSwitching = 0;
int fRecoverAreaFlow = 1;
int fRecoverArea = 1;
float aAreaTotalCur, aAreaTotalCur2;
int Iter, clk;
// compute area, set references, and collect nodes used in the mapping
Iter = 1;
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
if ( p->fVerbose )
{
printf( "Iteration %dD : Area = %11.1f ", 0, aAreaTotalCur );
printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur );
if ( fShowSwitching )
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
PRT( "Time", p->timeMatch );
}
Iter = 1;
do {
if ( fRecoverAreaFlow )
{
clk = clock();
// save the previous area flow
aAreaTotalPrev = aAreaTotalCur;
// compute the required times and the fanouts
Fpga_TimeComputeRequiredGlobal( p );
// remap topologically
......@@ -124,33 +128,38 @@ clk = clock();
// for some reason, this works better on benchmarks
if ( p->fVerbose )
{
printf( "Iteration %dF : Area = %11.1f ", Iter++, aAreaTotalCur );
printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur );
if ( fShowSwitching )
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
PRT( "Time", clock() - clk );
}
// quit if this iteration reduced area flow by less than 1%
} while ( aAreaTotalPrev > 1.02 * aAreaTotalCur );
}
// update reference counters
aAreaTotalCur2 = Fpga_MappingSetRefsAndArea( p );
assert( aAreaTotalCur == aAreaTotalCur2 );
do {
if ( fRecoverArea )
{
clk = clock();
// save the previous area flow
aAreaTotalPrev = aAreaTotalCur;
// compute the required times and the fanouts
Fpga_TimeComputeRequiredGlobal( p );
// remap topologically
if ( p->fSwitching )
Fpga_MappingMatchesSwitch( p );
else
Fpga_MappingMatchesArea( p );
// get the resulting area
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
if ( p->fVerbose )
{
printf( "Iteration %dA : Area = %11.1f ", Iter++, aAreaTotalCur );
printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->fSwitching?"S":"A"), aAreaTotalCur );
if ( fShowSwitching )
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
PRT( "Time", clock() - clk );
}
// quit if this iteration reduced area flow by less than 1%
} while ( aAreaTotalPrev > 1.02 * aAreaTotalCur );
}
p->fAreaGlo = aAreaTotalCur;
return 1;
}
......
......@@ -65,6 +65,7 @@ void Fpga_ManSetTimeLimit( Fpga_Man_t * p, float TimeLimit ) { p
void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes ) { p->nChoiceNodes = nChoiceNodes; }
void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices ) { p->nChoices = nChoices; }
void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; }
void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; }
void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ) { p->nLatches = nLatches; }
void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ) { p->pFileName = pFileName; }
......@@ -104,6 +105,7 @@ void Fpga_NodeSetData0( Fpga_Node_t * p, char * pData ) { p->
void Fpga_NodeSetData1( Fpga_Node_t * p, Fpga_Node_t * pNode ) { p->pLevel = pNode; }
void Fpga_NodeSetNextE( Fpga_Node_t * p, Fpga_Node_t * pNextE ) { p->pNextE = pNextE; }
void Fpga_NodeSetRepr( Fpga_Node_t * p, Fpga_Node_t * pRepr ) { p->pRepr = pRepr; }
void Fpga_NodeSetSwitching( Fpga_Node_t * p, float Switching ) { p->Switching = Switching; }
/**Function*************************************************************
......
......@@ -439,109 +439,6 @@ float Fpga_CutDeref( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut,
}
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut )
{
float aResult, aResult2;
if ( pCut->nLeaves == 1 )
return 0;
aResult2 = Fpga_CutRefSwitch( pMan, pNode, pCut, 0 );
aResult = Fpga_CutDerefSwitch( pMan, pNode, pCut, 0 );
// assert( aResult == aResult2 );
return aResult;
}
/**function*************************************************************
synopsis [References the cut.]
description [This procedure is similar to the procedure NodeReclaim.]
sideeffects []
seealso []
***********************************************************************/
float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts )
{
Fpga_Node_t * pNodeChild;
float aArea;
int i;
// deref the fanouts
// if ( fFanouts )
// Fpga_CutInsertFanouts( pMan, pNode, pCut );
// start the area of this cut
aArea = pNode->SwitchProb;
// go through the children
for ( i = 0; i < pCut->nLeaves; i++ )
{
pNodeChild = pCut->ppLeaves[i];
assert( pNodeChild->nRefs >= 0 );
if ( pNodeChild->nRefs++ > 0 )
continue;
if ( !Fpga_NodeIsAnd(pNodeChild) )
{
aArea += pNodeChild->SwitchProb;
continue;
}
aArea += Fpga_CutRefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts );
}
return aArea;
}
/**function*************************************************************
synopsis [Dereferences the cut.]
description [This procedure is similar to the procedure NodeRecusiveDeref.]
sideeffects []
seealso []
***********************************************************************/
float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts )
{
Fpga_Node_t * pNodeChild;
float aArea;
int i;
// deref the fanouts
// if ( fFanouts )
// Fpga_CutRemoveFanouts( pMan, pNode, pCut );
// start the area of this cut
aArea = pNode->SwitchProb;
// go through the children
for ( i = 0; i < pCut->nLeaves; i++ )
{
pNodeChild = pCut->ppLeaves[i];
assert( pNodeChild->nRefs > 0 );
if ( --pNodeChild->nRefs > 0 )
continue;
if ( !Fpga_NodeIsAnd(pNodeChild) )
{
aArea += pNodeChild->SwitchProb;
continue;
}
aArea += Fpga_CutDerefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts );
}
return aArea;
}
/**Function*************************************************************
Synopsis [Sets the used cuts to be the currently selected ones.]
......
......@@ -120,12 +120,9 @@ struct Fpga_ManStruct_t_
// mapping parameters
int nVarsMax; // the max number of variables
// int fTree; // the flag to enable tree mapping
// int fPower; // the flag to enable power optimization
int fAreaRecovery; // the flag to use area flow as the first parameter
int fVerbose; // the verbosiness flag
// int fRefCount; // enables reference counting
// int fSequential; // use sequential mapping
int fSwitching; // minimize the switching activity (instead of area)
int nTravIds;
// support of choice nodes
......@@ -137,7 +134,6 @@ struct Fpga_ManStruct_t_
// the supergate library
Fpga_LutLib_t * pLutLib; // the current LUT library
// unsigned uTruths[6][2]; // the elementary truth tables
// the memory managers
Extra_MmFixed_t * mmNodes; // the memory manager for nodes
......@@ -215,7 +211,7 @@ struct Fpga_NodeStruct_t_
// the delay information
float tRequired; // the best area flow
float aEstFanouts; // the fanout estimation
float SwitchProb; // the probability of switching
float Switching; // the probability of switching
int LValue; // the l-value of the node
short nLatches1; // the number of latches on the first edge
short nLatches2; // the number of latches on the second edge
......@@ -308,9 +304,6 @@ extern float Fpga_CutGetAreaRefed( Fpga_Man_t * pMan, Fpga_Cut_t * p
extern float Fpga_CutGetAreaDerefed( Fpga_Man_t * pMan, Fpga_Cut_t * pCut );
extern float Fpga_CutRef( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
extern float Fpga_CutDeref( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
extern float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut );
extern float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
extern float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
extern float Fpga_CutGetAreaFlow( Fpga_Man_t * pMan, Fpga_Cut_t * pCut );
extern void Fpga_CutGetParameters( Fpga_Man_t * pMan, Fpga_Cut_t * pCut );
/*=== fraigFanout.c =============================================================*/
......@@ -329,6 +322,11 @@ extern int Fpga_MappingMatchesSwitch( Fpga_Man_t * p );
/*=== fpgaShow.c =============================================================*/
extern void Fpga_MappingShow( Fpga_Man_t * pMan, char * pFileName );
extern void Fpga_MappingShowNodes( Fpga_Man_t * pMan, Fpga_Node_t ** ppRoots, int nRoots, char * pFileName );
/*=== fpgaSwitch.c =============================================================*/
extern float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut );
extern float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
extern float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
extern float Fpga_MappingGetSwitching( Fpga_Man_t * pMan, Fpga_NodeVec_t * vMapping );
/*=== fpgaTime.c ===============================================================*/
extern float Fpga_TimeCutComputeArrival( Fpga_Man_t * pMan, Fpga_Cut_t * pCut );
extern float Fpga_TimeCutComputeArrival_rec( Fpga_Man_t * pMan, Fpga_Cut_t * pCut );
......@@ -370,7 +368,6 @@ extern void Fpga_MappingSetupMask( unsigned uMask[], int nVarsMax )
extern void Fpga_MappingSortByLevel( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNodes, int fIncreasing );
extern Fpga_NodeVec_t * Fpga_DfsLim( Fpga_Man_t * pMan, Fpga_Node_t * pNode, int nLevels );
extern Fpga_NodeVec_t * Fpga_MappingLevelize( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNodes );
extern float Fpga_MappingPrintSwitching( Fpga_Man_t * pMan );
extern int Fpga_MappingMaxLevel( Fpga_Man_t * pMan );
extern void Fpga_ManReportChoices( Fpga_Man_t * pMan );
extern void Fpga_MappingSetChoiceLevels( Fpga_Man_t * pMan );
......
......@@ -432,7 +432,7 @@ clk = clock();
if ( pNode->nRefs )
{
pNode->pCutBest->aFlow = Fpga_CutRefSwitch( p, pNode, pNode->pCutBest, 0 );
assert( pNode->pCutBest->aFlow <= aAreaCutBest );
assert( pNode->pCutBest->aFlow <= aAreaCutBest + 0.001 );
// assert( pNode->tRequired < FPGA_FLOAT_LARGE );
}
return 1;
......
/**CFile****************************************************************
FileName [fpgaSwitch.c]
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
Synopsis [Generic technology mapping engine.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 8, 2003.]
Revision [$Id: fpgaSwitch.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $]
***********************************************************************/
#include "fpgaInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static float Fpga_CutGetSwitching( Fpga_Cut_t * pCut );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut )
{
float aResult, aResult2;
aResult2 = Fpga_CutRefSwitch( pMan, pNode, pCut, 0 );
aResult = Fpga_CutDerefSwitch( pMan, pNode, pCut, 0 );
// assert( aResult == aResult2 );
return aResult;
}
/**function*************************************************************
synopsis [References the cut.]
description [This procedure is similar to the procedure NodeReclaim.]
sideeffects []
seealso []
***********************************************************************/
float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts )
{
Fpga_Node_t * pNodeChild;
float aArea;
int i;
if ( pCut->nLeaves == 1 )
return 0;
// start the area of this cut
aArea = Fpga_CutGetSwitching( pCut );
// go through the children
for ( i = 0; i < pCut->nLeaves; i++ )
{
pNodeChild = pCut->ppLeaves[i];
assert( pNodeChild->nRefs >= 0 );
if ( pNodeChild->nRefs++ > 0 )
continue;
aArea += Fpga_CutRefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts );
}
return aArea;
}
/**function*************************************************************
synopsis [Dereferences the cut.]
description [This procedure is similar to the procedure NodeRecusiveDeref.]
sideeffects []
seealso []
***********************************************************************/
float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts )
{
Fpga_Node_t * pNodeChild;
float aArea;
int i;
if ( pCut->nLeaves == 1 )
return 0;
// start the area of this cut
aArea = Fpga_CutGetSwitching( pCut );
// go through the children
for ( i = 0; i < pCut->nLeaves; i++ )
{
pNodeChild = pCut->ppLeaves[i];
assert( pNodeChild->nRefs > 0 );
if ( --pNodeChild->nRefs > 0 )
continue;
aArea += Fpga_CutDerefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts );
}
return aArea;
}
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float Fpga_CutGetSwitching( Fpga_Cut_t * pCut )
{
float Result;
int i;
Result = 0.0;
for ( i = 0; i < pCut->nLeaves; i++ )
Result += pCut->ppLeaves[i]->Switching;
return Result;
}
/**Function*************************************************************
Synopsis [Computes the array of mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Fpga_MappingGetSwitching( Fpga_Man_t * pMan, Fpga_NodeVec_t * vMapping )
{
Fpga_Node_t * pNode;
float Switch;
int i;
Switch = 0.0;
for ( i = 0; i < vMapping->nSize; i++ )
{
pNode = vMapping->pArray[i];
if ( !Fpga_NodeIsAnd(pNode) )
continue;
// at least one phase has the best cut assigned
assert( pNode->pCutBest != NULL );
// at least one phase is used in the mapping
assert( pNode->nRefs > 0 );
// compute the array due to the supergate
Switch += pNode->Switching;
}
// add buffer for each CO driven by a CI
for ( i = 0; i < pMan->nOutputs; i++ )
if ( Fpga_NodeIsVar(pMan->pOutputs[i]) && !Fpga_IsComplement(pMan->pOutputs[i]) )
Switch += pMan->pOutputs[i]->Switching;
return Switch;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -779,43 +779,6 @@ Fpga_NodeVec_t * Fpga_MappingLevelize( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNode
}
return vLevels;
}
/**Function*************************************************************
Synopsis [Prints the switching activity changes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Fpga_MappingPrintSwitching( Fpga_Man_t * p )
{
Fpga_Node_t * pNode;
float SwitchTotal = 0.0;
int nNodes = 0;
int i;
for ( i = 0; i < p->vNodesAll->nSize; i++ )
{
// skip primary inputs
pNode = p->vNodesAll->pArray[i];
// if ( !Fpga_NodeIsAnd( pNode ) )
// continue;
// skip a secondary node
if ( pNode->pRepr )
continue;
// count the switching nodes
if ( pNode->nRefs > 0 )
{
SwitchTotal += pNode->SwitchProb;
nNodes++;
}
}
if ( p->fVerbose )
printf( "Total switching = %10.2f. Average switching = %6.4f.\n", SwitchTotal, SwitchTotal/nNodes );
return SwitchTotal;
}
/**Function*************************************************************
......
......@@ -6,6 +6,7 @@ SRC += src/map/fpga/fpga.c \
src/map/fpga/fpgaFanout.c \
src/map/fpga/fpgaLib.c \
src/map/fpga/fpgaMatch.c \
src/map/fpga/fpgaSwitch.c \
src/map/fpga/fpgaTime.c \
src/map/fpga/fpgaTruth.c \
src/map/fpga/fpgaUtils.c \
......
......@@ -101,6 +101,7 @@ extern void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio );
extern void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes );
extern void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices );
extern void Map_ManSetVerbose( Map_Man_t * p, int fVerbose );
extern void Map_ManSetSwitching( Map_Man_t * p, int fSwitching );
extern Map_Man_t * Map_NodeReadMan( Map_Node_t * p );
extern char * Map_NodeReadData( Map_Node_t * p, int fPhase );
......@@ -113,6 +114,7 @@ extern Map_Node_t * Map_NodeReadTwo( Map_Node_t * p );
extern void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData );
extern void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE );
extern void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr );
extern void Map_NodeSetSwitching( Map_Node_t * p, float Switching );
extern int Map_NodeIsConst( Map_Node_t * p );
extern int Map_NodeIsVar( Map_Node_t * p );
......
......@@ -46,9 +46,10 @@
***********************************************************************/
int Map_Mapping( Map_Man_t * p )
{
int fShowSwitching = 0;
int fUseAreaFlow = 1;
int fUseExactArea = 1;
int fUseExactAreaWithPhase = 1;
int fUseExactArea = !p->fSwitching;
int fUseExactAreaWithPhase = !p->fSwitching;
int clk;
//////////////////////////////////////////////////////////////////////
......@@ -83,8 +84,10 @@ int Map_Mapping( Map_Man_t * p )
p->AreaBase = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
printf( "Delay : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
printf( "Delay : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
fShowSwitching? "Switch" : "Delay",
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
PRT( "Time", p->timeMatch );
}
//////////////////////////////////////////////////////////////////////
......@@ -97,7 +100,7 @@ PRT( "Time", p->timeMatch );
clk = clock();
if ( fUseAreaFlow )
{
// compute the required times and the fanouts
// compute the required times
Map_TimeComputeRequiredGlobal( p );
// recover area flow
p->fMappingMode = 1;
......@@ -107,8 +110,10 @@ PRT( "Time", p->timeMatch );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
printf( "AreaFlow : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaFinal,
printf( "AreaFlow : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
fShowSwitching? "Switch" : "Delay",
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
Map_MappingGetAreaFlow(p), p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
......@@ -121,9 +126,9 @@ PRT( "Time", clock() - clk );
clk = clock();
if ( fUseExactArea )
{
// compute the required times and the fanouts
// compute the required times
Map_TimeComputeRequiredGlobal( p );
// recover area flow
// recover area
p->fMappingMode = 2;
Map_MappingMatches( p );
// compute the references and collect the nodes used in the mapping
......@@ -131,8 +136,10 @@ PRT( "Time", clock() - clk );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
p->fRequiredGlo, 0.0, p->AreaFinal,
printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
fShowSwitching? "Switch" : "Delay",
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
0.0, p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
......@@ -145,9 +152,9 @@ PRT( "Time", clock() - clk );
clk = clock();
if ( fUseExactAreaWithPhase )
{
// compute the required times and the fanouts
// compute the required times
Map_TimeComputeRequiredGlobal( p );
// recover area flow
// recover area
p->fMappingMode = 3;
Map_MappingMatches( p );
// compute the references and collect the nodes used in the mapping
......@@ -155,8 +162,54 @@ PRT( "Time", clock() - clk );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
p->fRequiredGlo, 0.0, p->AreaFinal,
printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
fShowSwitching? "Switch" : "Delay",
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
0.0, p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
}
p->timeArea += clock() - clk;
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// perform area recovery using exact area
clk = clock();
if ( p->fSwitching )
{
// compute the required times
Map_TimeComputeRequiredGlobal( p );
// recover switching activity
p->fMappingMode = 4;
Map_MappingMatches( p );
// compute the references and collect the nodes used in the mapping
Map_MappingSetRefs( p );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
fShowSwitching? "Switch" : "Delay",
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
0.0, p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
// compute the required times
Map_TimeComputeRequiredGlobal( p );
// recover switching activity
p->fMappingMode = 4;
Map_MappingMatches( p );
// compute the references and collect the nodes used in the mapping
Map_MappingSetRefs( p );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
fShowSwitching? "Switch" : "Delay",
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
0.0, p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
......
......@@ -69,6 +69,7 @@ void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio ) { p->nFa
void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes ) { p->nChoiceNodes = nChoiceNodes; }
void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices ) { p->nChoices = nChoices; }
void Map_ManSetVerbose( Map_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; }
void Map_ManSetSwitching( Map_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; }
/**Function*************************************************************
......@@ -92,6 +93,7 @@ Map_Node_t * Map_NodeReadTwo( Map_Node_t * p ) { return p
void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData ) { if (fPhase) p->pData1 = pData; else p->pData0 = pData; }
void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ) { p->pNextE = pNextE; }
void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ) { p->pRepr = pRepr; }
void Map_NodeSetSwitching( Map_Node_t * p, float Switching ) { p->Switching = Switching; }
/**Function*************************************************************
......
......@@ -117,6 +117,7 @@ struct Map_ManStruct_t_
bool fObeyFanoutLimits;// Should mapper try to obey fanout limits or not
float DelayTarget; // the required times set by the user
int nTravIds; // the traversal counter
bool fSwitching; // Should mapper try to obey fanout limits or not
// the supergate library
Map_SuperLib_t * pSuperLib; // the current supergate library
......@@ -184,6 +185,7 @@ struct Map_SuperLibStruct_t_
Mio_Gate_t * pGateInv; // the pointer to the intertor gate
Map_Time_t tDelayInv; // the delay of the inverter
float AreaInv; // the area of the inverter
float AreaBuf; // the area of the buffer
Map_Super_t * pSuperInv; // the supergate representing the inverter
// the memory manager for the internal table
......@@ -210,6 +212,7 @@ struct Map_NodeStruct_t_
unsigned NumTemp:10; // the level of the given node
int nRefAct[3]; // estimated fanout for current covering phase, neg and pos and sum
float nRefEst[3]; // actual fanout for previous covering phase, neg and pos and sum
float Switching; // the probability of switching
// connectivity
Map_Node_t * p1; // the first child
......@@ -378,6 +381,11 @@ extern int Map_MappingMatches( Map_Man_t * p );
extern float Map_MappingCombinePhases( Map_Man_t * p );
extern void Map_MatchClean( Map_Match_t * pMatch );
extern int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea );
/*=== mapperPower.c =============================================================*/
extern float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
extern float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
extern float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
extern float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping );
/*=== mapperRefs.c =============================================================*/
extern int Map_NodeReadRefPhaseAct( Map_Node_t * pNode, int fPhase );
extern float Map_NodeReadRefPhaseEst( Map_Node_t * pNode, int fPhase );
......
......@@ -102,6 +102,7 @@ if ( fVerbose ) {
p->tDelayInv.Fall = Mio_LibraryReadDelayInvFall( p->pGenlib );
p->tDelayInv.Worst = MAP_MAX( p->tDelayInv.Rise, p->tDelayInv.Fall );
p->AreaInv = Mio_LibraryReadAreaInv( p->pGenlib );
p->AreaBuf = Mio_LibraryReadAreaBuf( p->pGenlib );
// assign the interver supergate
p->pSuperInv = (Map_Super_t *)Extra_MmFixedEntryFetch( p->mmSupers );
......
......@@ -65,7 +65,7 @@ int Map_MappingMatches( Map_Man_t * p )
Map_Node_t * pNode;
int i;
assert( p->fMappingMode >= 0 && p->fMappingMode <= 3 );
assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 );
// use the externally given PI arrival times
if ( p->fMappingMode == 0 )
......@@ -158,7 +158,7 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
// recompute the exact area of the current best match
// because the exact area of the fanins may have changed
// as a result of remapping fanins in the topological order
if ( p->fMappingMode >= 2 )
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
{
pMatch = pCutBest->M + fPhase;
if ( pNode->nRefAct[fPhase] > 0 ||
......@@ -167,6 +167,15 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
else
pMatch->AreaFlow = Area1 = Map_CutGetAreaDerefed( pCutBest, fPhase );
}
else if ( p->fMappingMode == 4 )
{
pMatch = pCutBest->M + fPhase;
if ( pNode->nRefAct[fPhase] > 0 ||
(pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) )
pMatch->AreaFlow = Area1 = Map_SwitchCutDeref( pNode, pCutBest, fPhase );
else
pMatch->AreaFlow = Area1 = Map_SwitchCutGetDerefed( pNode, pCutBest, fPhase );
}
// save the old mapping
if ( pCutBest )
......@@ -210,7 +219,12 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
(pNode->nRefAct[fPhase] > 0 ||
(pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0)) )
{
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
Area2 = Map_CutRef( pNode->pCutBest[fPhase], fPhase );
else if ( p->fMappingMode == 4 )
Area2 = Map_SwitchCutRef( pNode, pNode->pCutBest[fPhase], fPhase );
else
assert( 0 );
assert( Area2 < Area1 + p->fEpsilon );
}
......@@ -273,8 +287,10 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f
else
{
// get the area (area flow)
if ( p->fMappingMode >= 2 )
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
else if ( p->fMappingMode == 4 )
pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase );
else
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
// skip if the cut is too large
......@@ -304,8 +320,10 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f
if ( pMatch->pSuperBest )
{
Map_TimeCutComputeArrival( pNode, pCut, fPhase, MAP_FLOAT_LARGE );
if ( p->fMappingMode >= 2 )
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
else if ( p->fMappingMode == 4 )
pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase );
else
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
}
......@@ -482,7 +500,7 @@ void Map_NodeTryDroppingOnePhase( Map_Man_t * p, Map_Node_t * pNode )
fUsePhase0 = (pNode->tRequired[1].Worst > tWorst1Using0 + 3*p->pSuperLib->tDelayInv.Worst + p->fEpsilon);
fUsePhase1 = (pNode->tRequired[0].Worst > tWorst0Using1 + 3*p->pSuperLib->tDelayInv.Worst + p->fEpsilon);
}
else if ( p->fMappingMode == 3 )
else if ( p->fMappingMode == 3 || p->fMappingMode == 4 )
{
fUsePhase0 = (pNode->tRequired[1].Worst > tWorst1Using0 + p->fEpsilon);
fUsePhase1 = (pNode->tRequired[0].Worst > tWorst0Using1 + p->fEpsilon);
......
......@@ -279,7 +279,7 @@ float Map_CutRef( Map_Cut_t * pCut, int fPhase )
/**function*************************************************************
synopsis [References the cut.]
synopsis [Dereferences the cut.]
description []
......@@ -298,8 +298,7 @@ float Map_CutDeref( Map_Cut_t * pCut, int fPhase )
synopsis [References or dereferences the cut.]
description [This reference part is similar to Cudd_NodeReclaim().
The dereference part is similar to Cudd_RecursiveDeref(). The
area of the inverter is not counted.]
The dereference part is similar to Cudd_RecursiveDeref().]
sideeffects []
......@@ -543,10 +542,10 @@ float Map_MappingGetArea( Map_Man_t * pMan, Map_NodeVec_t * vMapping )
(pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) )
Area += pMan->pSuperLib->AreaInv;
}
// add two inverters for each PO buffer
// add buffer for each CO driven by a CI
for ( i = 0; i < pMan->nOutputs; i++ )
if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) )
Area += 2 * pMan->pSuperLib->AreaInv;
Area += pMan->pSuperLib->AreaBuf;
return Area;
}
......
/**CFile****************************************************************
FileName [mapperSwitch.c]
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
Synopsis [Generic technology mapping engine.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 8, 2003.]
Revision [$Id: mapperSwitch.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $]
***********************************************************************/
#include "mapperInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference );
static float Map_CutGetSwitching( Map_Cut_t * pCut );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
{
float aResult, aResult2;
// assert( pNode->Switching > 0 );
aResult2 = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference
aResult = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference
// assert( aResult == aResult2 );
return aResult;
}
/**function*************************************************************
synopsis [References the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
{
return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference
}
/**function*************************************************************
synopsis [References the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
{
return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference
}
/**function*************************************************************
synopsis [References or dereferences the cut.]
description [This reference part is similar to Cudd_NodeReclaim().
The dereference part is similar to Cudd_RecursiveDeref().]
sideeffects []
seealso []
***********************************************************************/
float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference )
{
Map_Node_t * pNodeChild;
Map_Cut_t * pCutChild;
float aSwitchActivity;
int i, fPhaseChild;
// consider the elementary variable
if ( pCut->nLeaves == 1 )
return 0;
// start the area of this cut
aSwitchActivity = Map_CutGetSwitching( pCut );
// go through the children
assert( pCut->M[fPhase].pSuperBest );
for ( i = 0; i < pCut->nLeaves; i++ )
{
pNodeChild = pCut->ppLeaves[i];
fPhaseChild = Map_CutGetLeafPhase( pCut, fPhase, i );
// get the reference counter of the child
if ( fReference )
{
if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present
{
// if this phase of the node is referenced, there is no recursive call
pNodeChild->nRefAct[2]++;
if ( pNodeChild->nRefAct[fPhaseChild]++ > 0 )
continue;
}
else // only one phase is present
{
// inverter should be added if the phase
// (a) has no reference and (b) is implemented using other phase
if ( pNodeChild->nRefAct[fPhaseChild]++ == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL )
aSwitchActivity += pNodeChild->Switching;
// if the node is referenced, there is no recursive call
if ( pNodeChild->nRefAct[2]++ > 0 )
continue;
}
}
else
{
if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present
{
// if this phase of the node is referenced, there is no recursive call
--pNodeChild->nRefAct[2];
if ( --pNodeChild->nRefAct[fPhaseChild] > 0 )
continue;
}
else // only one phase is present
{
// inverter should be added if the phase
// (a) has no reference and (b) is implemented using other phase
if ( --pNodeChild->nRefAct[fPhaseChild] == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL )
aSwitchActivity += pNodeChild->Switching;
// if the node is referenced, there is no recursive call
if ( --pNodeChild->nRefAct[2] > 0 )
continue;
}
assert( pNodeChild->nRefAct[fPhaseChild] >= 0 );
}
// get the child cut
pCutChild = pNodeChild->pCutBest[fPhaseChild];
// if the child does not have this phase mapped, take the opposite phase
if ( pCutChild == NULL )
{
fPhaseChild = !fPhaseChild;
pCutChild = pNodeChild->pCutBest[fPhaseChild];
}
// reference and compute area recursively
aSwitchActivity += Map_SwitchCutRefDeref( pNodeChild, pCutChild, fPhaseChild, fReference );
}
return aSwitchActivity;
}
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float Map_CutGetSwitching( Map_Cut_t * pCut )
{
float Result;
int i;
Result = 0.0;
for ( i = 0; i < pCut->nLeaves; i++ )
Result += pCut->ppLeaves[i]->Switching;
return Result;
}
/**Function*************************************************************
Synopsis [Computes the array of mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping )
{
Map_Node_t * pNode;
float Switch;
int i;
Switch = 0.0;
for ( i = 0; i < vMapping->nSize; i++ )
{
pNode = vMapping->pArray[i];
// at least one phase has the best cut assigned
assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL );
// at least one phase is used in the mapping
assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 );
// compute the array due to the supergate
if ( Map_NodeIsAnd(pNode) )
{
// count switching of the negative phase
if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
Switch += pNode->Switching;
// count switching of the positive phase
if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
Switch += pNode->Switching;
}
// count switching of the interver if we need to implement one phase with another phase
if ( (pNode->pCutBest[0] == NULL && pNode->nRefAct[0] > 0) ||
(pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) )
Switch += pNode->Switching;
}
// add buffer for each CO driven by a CI
for ( i = 0; i < pMan->nOutputs; i++ )
if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) )
Switch += pMan->pOutputs[i]->Switching;
return Switch;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -9,6 +9,7 @@ SRC += src/map/mapper/mapper.c \
src/map/mapper/mapperMatch.c \
src/map/mapper/mapperRefs.c \
src/map/mapper/mapperSuper.c \
src/map/mapper/mapperSwitch.c \
src/map/mapper/mapperTable.c \
src/map/mapper/mapperTime.c \
src/map/mapper/mapperTree.c \
......
......@@ -90,6 +90,7 @@ extern float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib );
extern float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib );
extern float Mio_LibraryReadDelayNand2Max( Mio_Library_t * pLib );
extern float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib );
extern float Mio_LibraryReadAreaBuf ( Mio_Library_t * pLib );
extern float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib );
extern char * Mio_GateReadName ( Mio_Gate_t * pGate );
extern char * Mio_GateReadOutName ( Mio_Gate_t * pGate );
......
......@@ -46,14 +46,15 @@ Mio_Gate_t * Mio_LibraryReadInv ( Mio_Library_t * pLib ) { retur
Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib ) { return pLib->pGate0; }
Mio_Gate_t * Mio_LibraryReadConst1 ( Mio_Library_t * pLib ) { return pLib->pGate1; }
Mio_Gate_t * Mio_LibraryReadNand2 ( Mio_Library_t * pLib ) { return pLib->pGateNand2; }
float Mio_LibraryReadDelayInvRise ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockRise; }
float Mio_LibraryReadDelayInvFall ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockFall; }
float Mio_LibraryReadDelayInvMax ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockMax; }
float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockRise; }
float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockFall; }
float Mio_LibraryReadDelayNand2Max ( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockMax; }
float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->dArea; }
float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->dArea; }
float Mio_LibraryReadDelayInvRise ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockRise : 0.0); }
float Mio_LibraryReadDelayInvFall ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockFall : 0.0); }
float Mio_LibraryReadDelayInvMax ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockMax : 0.0); }
float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockRise : 0.0); }
float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockFall : 0.0); }
float Mio_LibraryReadDelayNand2Max ( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockMax : 0.0); }
float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->dArea : 0.0); }
float Mio_LibraryReadAreaBuf ( Mio_Library_t * pLib ) { return (float)(pLib->pGateBuf? pLib->pGateBuf->dArea : 0.0); }
float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->dArea : 0.0); }
/**Function*************************************************************
......
SRC += src/misc/mvc/mvc.c \
src/misc/mvc/mvcApi.c \
src/misc/mvc/mvcCompare.c \
src/misc/mvc/mvcContain.c \
src/misc/mvc/mvcCover.c \
src/misc/mvc/mvcCube.c \
src/misc/mvc/mvcDivide.c \
src/misc/mvc/mvcDivisor.c \
src/misc/mvc/mvcList.c \
src/misc/mvc/mvcLits.c \
src/misc/mvc/mvcMan.c \
src/misc/mvc/mvcOpAlg.c \
src/misc/mvc/mvcOpBool.c \
src/misc/mvc/mvcPrint.c \
src/misc/mvc/mvcSort.c \
src/misc/mvc/mvcUtils.c
......@@ -82,6 +82,26 @@ static inline Vec_Int_t * Vec_IntAlloc( int nCap )
/**Function*************************************************************
Synopsis [Allocates a vector with the given size and cleans it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Int_t * Vec_IntStart( int nSize )
{
Vec_Int_t * p;
p = Vec_IntAlloc( nSize );
p->nSize = nSize;
memset( p->pArray, 0, sizeof(int) * nSize );
return p;
}
/**Function*************************************************************
Synopsis [Creates the vector from an integer array of the given size.]
Description []
......@@ -437,6 +457,27 @@ static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry )
{
int i;
for ( i = 0; i < p->nSize; i++ )
if ( p->pArray[i] == Entry )
return 1;
Vec_IntPush( p, Entry );
return 0;
}
/**Function*************************************************************
Synopsis [Returns the last entry and removes it from the list.]
Description []
......
......@@ -53,6 +53,8 @@ struct Vec_Ptr_t_
for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \
for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
#define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \
for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -83,6 +85,26 @@ static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap )
/**Function*************************************************************
Synopsis [Allocates a vector with the given size and cleans it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Ptr_t * Vec_PtrStart( int nSize )
{
Vec_Ptr_t * p;
p = Vec_PtrAlloc( nSize );
p->nSize = nSize;
memset( p->pArray, 0, sizeof(void *) * nSize );
return p;
}
/**Function*************************************************************
Synopsis [Creates the vector from an integer array of the given size.]
Description []
......@@ -488,46 +510,6 @@ static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
/**Function*************************************************************
Synopsis [Frees the vector of vectors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_PtrFreeFree( Vec_Ptr_t * p )
{
Vec_Ptr_t * vVec;
int i;
Vec_PtrForEachEntry( p, vVec, i )
Vec_PtrFree( vVec );
Vec_PtrFree( p );
}
/**Function*************************************************************
Synopsis [Frees the vector of vectors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_PtrSizeSize( Vec_Ptr_t * p )
{
Vec_Ptr_t * vVec;
int i, Counter = 0;
Vec_PtrForEachEntry( p, vVec, i )
Counter += vVec->nSize;
return Counter;
}
/**Function*************************************************************
Synopsis [Sorting the entries by their integer value.]
Description []
......
......@@ -80,6 +80,26 @@ static inline Vec_Str_t * Vec_StrAlloc( int nCap )
/**Function*************************************************************
Synopsis [Allocates a vector with the given size and cleans it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Str_t * Vec_StrStart( int nSize )
{
Vec_Str_t * p;
p = Vec_StrAlloc( nSize );
p->nSize = nSize;
memset( p->pArray, 0, sizeof(char) * nSize );
return p;
}
/**Function*************************************************************
Synopsis [Creates the vector from an integer array of the given size.]
Description []
......
......@@ -68,6 +68,9 @@ struct Vec_Vec_t_
#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \
for ( i = LevelStart; i <= LevelStop; i++ ) \
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......
SRC += src/opt/sim/simMan.c \
src/opt/sim/simSat.c \
src/opt/sim/simSupp.c \
src/opt/sim/simSwitch.c \
src/opt/sim/simSym.c \
src/opt/sim/simSymSat.c \
src/opt/sim/simSymSim.c \
src/opt/sim/simSymStr.c \
src/opt/sim/simUtils.c
/**CFile****************************************************************
FileName [sim.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Simulation package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: sim.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __SIM_H__
#define __SIM_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Sym_Man_t_ Sym_Man_t;
struct Sym_Man_t_
{
// info about the network
Abc_Ntk_t * pNtk; // the network
Vec_Ptr_t * vNodes; // internal nodes in topological order
int nInputs;
int nOutputs;
// internal simulation information
int nSimWords; // the number of bits in simulation info
Vec_Ptr_t * vSim; // simulation info
// support information
Vec_Ptr_t * vSuppFun; // functional supports
// symmetry info for each output
Vec_Ptr_t * vMatrSymms; // symmetric pairs
Vec_Ptr_t * vMatrNonSymms; // non-symmetric pairs
Vec_Int_t * vPairsTotal; // total pairs
Vec_Int_t * vPairsSym; // symmetric pairs
Vec_Int_t * vPairsNonSym; // non-symmetric pairs
// temporary simulation info
unsigned * uPatRand;
unsigned * uPatCol;
unsigned * uPatRow;
// internal data structures
int nSatRuns;
int nSatRunsSat;
int nSatRunsUnsat;
// pairs
int nPairsSymm;
int nPairsSymmStr;
int nPairsNonSymm;
int nPairsTotal;
// runtime statistics
int timeSim;
int timeFraig;
int timeSat;
int timeTotal;
};
typedef struct Sim_Man_t_ Sim_Man_t;
struct Sim_Man_t_
{
// info about the network
Abc_Ntk_t * pNtk;
int nInputs;
int nOutputs;
// internal simulation information
int nSimBits; // the number of bits in simulation info
int nSimWords; // the number of words in simulation info
Vec_Ptr_t * vSim0; // simulation info 1
Vec_Ptr_t * vSim1; // simulation info 2
// support information
int nSuppBits; // the number of bits in support info
int nSuppWords; // the number of words in support info
Vec_Ptr_t * vSuppStr; // structural supports
Vec_Ptr_t * vSuppFun; // functional supports
// simulation targets
Vec_Vec_t * vSuppTargs; // support targets
// internal data structures
Extra_MmFixed_t * pMmPat;
Vec_Ptr_t * vFifo;
Vec_Int_t * vDiffs;
int nSatRuns;
int nSatRunsSat;
int nSatRunsUnsat;
// runtime statistics
int timeSim;
int timeTrav;
int timeFraig;
int timeSat;
int timeTotal;
};
typedef struct Sim_Pat_t_ Sim_Pat_t;
struct Sim_Pat_t_
{
int Input; // the input which it has detected
int Output; // the output for which it was collected
unsigned * pData; // the simulation data
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
#define SIM_NUM_WORDS(n) ((n)/32 + (((n)%32) > 0))
#define SIM_LAST_BITS(n) ((((n)%32) > 0)? (n)%32 : 32)
#define SIM_MASK_FULL (0xFFFFFFFF)
#define SIM_MASK_BEG(n) (SIM_MASK_FULL >> (32-n))
#define SIM_MASK_END(n) (SIM_MASK_FULL << (n))
#define SIM_SET_0_FROM(m,n) ((m) & ~SIM_MASK_BEG(n))
#define SIM_SET_1_FROM(m,n) ((m) | SIM_MASK_END(n))
// generating random unsigned (#define RAND_MAX 0x7fff)
#define SIM_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()))
// macros to get hold of bits in a bit string
#define Sim_SetBit(p,i) ((p)[(i)>>5] |= (1<<((i) & 31)))
#define Sim_XorBit(p,i) ((p)[(i)>>5] ^= (1<<((i) & 31)))
#define Sim_HasBit(p,i) (((p)[(i)>>5] & (1<<((i) & 31))) > 0)
// macros to get hold of the support info
#define Sim_SuppStrSetVar(vSupps,pNode,v) Sim_SetBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v))
#define Sim_SuppStrHasVar(vSupps,pNode,v) Sim_HasBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v))
#define Sim_SuppFunSetVar(vSupps,Output,v) Sim_SetBit((unsigned*)(vSupps)->pArray[Output],(v))
#define Sim_SuppFunHasVar(vSupps,Output,v) Sim_HasBit((unsigned*)(vSupps)->pArray[Output],(v))
#define Sim_SimInfoSetVar(vSupps,pNode,v) Sim_SetBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v))
#define Sim_SimInfoHasVar(vSupps,pNode,v) Sim_HasBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v))
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== simMan.c ==========================================================*/
extern Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk );
extern void Sym_ManStop( Sym_Man_t * p );
extern void Sym_ManPrintStats( Sym_Man_t * p );
extern Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk );
extern void Sim_ManStop( Sim_Man_t * p );
extern void Sim_ManPrintStats( Sim_Man_t * p );
extern Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p );
extern void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat );
/*=== simSupp.c ==========================================================*/
extern Vec_Ptr_t * Sim_ComputeStrSupp( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk );
/*=== simSym.c ==========================================================*/
extern int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk );
/*=== simSymStr.c ==========================================================*/
extern void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs );
/*=== simSymSim.c ==========================================================*/
extern void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPatRand, Vec_Ptr_t * vMatrsNonSym );
/*=== simUtil.c ==========================================================*/
extern Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean );
extern void Sim_UtilInfoFree( Vec_Ptr_t * p );
extern void Sim_UtilInfoAdd( unsigned * pInfo1, unsigned * pInfo2, int nWords );
extern void Sim_UtilInfoDetectDiffs( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs );
extern void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs );
extern void Sim_UtilInfoFlip( Sim_Man_t * p, Abc_Obj_t * pNode );
extern bool Sim_UtilInfoCompare( Sim_Man_t * p, Abc_Obj_t * pNode );
extern void Sim_UtilSimulate( Sim_Man_t * p, bool fFirst );
extern void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fType1, bool fType2 );
extern void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords );
extern int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct );
extern int Sim_UtilCountOnes( unsigned * pSimInfo, int nSimWords );
extern void Sim_UtilGetRandom( unsigned * pPatRand, int nSimWords );
extern int Sim_UtilCountAllPairs( Vec_Ptr_t * vSuppFun, int nSimWords, Vec_Int_t * vCounters );
extern int Sim_UtilCountPairs( Vec_Ptr_t * vMatrs, Vec_Int_t * vCounters );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif
......@@ -40,14 +40,126 @@
SeeAlso []
***********************************************************************/
Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk )
{
Sym_Man_t * p;
int i;
// start the manager
p = ALLOC( Sym_Man_t, 1 );
memset( p, 0, sizeof(Sym_Man_t) );
p->pNtk = pNtk;
p->vNodes = Abc_NtkDfs( pNtk, 0 );
p->nInputs = Abc_NtkCiNum(p->pNtk);
p->nOutputs = Abc_NtkCoNum(p->pNtk);
// internal simulation information
p->nSimWords = SIM_NUM_WORDS(p->nInputs);
p->vSim = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 );
// symmetry info for each output
p->vMatrSymms = Vec_PtrStart( p->nOutputs );
p->vMatrNonSymms = Vec_PtrStart( p->nOutputs );
p->vPairsTotal = Vec_IntStart( p->nOutputs );
p->vPairsSym = Vec_IntStart( p->nOutputs );
p->vPairsNonSym = Vec_IntStart( p->nOutputs );
for ( i = 0; i < p->nOutputs; i++ )
{
p->vMatrSymms->pArray[i] = Extra_BitMatrixStart( p->nInputs );
p->vMatrNonSymms->pArray[i] = Extra_BitMatrixStart( p->nInputs );
}
// temporary patterns
p->uPatRand = ALLOC( unsigned, p->nSimWords );
p->uPatCol = ALLOC( unsigned, p->nSimWords );
p->uPatRow = ALLOC( unsigned, p->nSimWords );
// compute supports
p->vSuppFun = Sim_ComputeFunSupp( pNtk );
return p;
}
/**Function*************************************************************
Synopsis [Stops the simulatin manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sym_ManStop( Sym_Man_t * p )
{
int i;
Sym_ManPrintStats( p );
if ( p->vSuppFun ) Sim_UtilInfoFree( p->vSuppFun );
if ( p->vSim ) Sim_UtilInfoFree( p->vSim );
if ( p->vNodes ) Vec_PtrFree( p->vNodes );
for ( i = 0; i < p->nOutputs; i++ )
{
Extra_BitMatrixStop( p->vMatrSymms->pArray[i] );
Extra_BitMatrixStop( p->vMatrNonSymms->pArray[i] );
}
Vec_PtrFree( p->vMatrSymms );
Vec_PtrFree( p->vMatrNonSymms );
Vec_IntFree( p->vPairsTotal );
Vec_IntFree( p->vPairsSym );
Vec_IntFree( p->vPairsNonSym );
FREE( p->uPatRand );
FREE( p->uPatCol );
FREE( p->uPatRow );
free( p );
}
/**Function*************************************************************
Synopsis [Prints the manager statisticis.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sym_ManPrintStats( Sym_Man_t * p )
{
printf( "Inputs = %d. Outputs = %d. Sim words = %d.\n",
Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords );
/*
printf( "Total struct supps = %6d.\n", Sim_UtilCountSuppSizes(p, 1) );
printf( "Total func supps = %6d.\n", Sim_UtilCountSuppSizes(p, 0) );
printf( "Total targets = %6d.\n", Vec_VecSizeSize(p->vSuppTargs) );
printf( "Total sim patterns = %6d.\n", Vec_PtrSize(p->vFifo) );
*/
printf( "Sat runs SAT = %6d.\n", p->nSatRunsSat );
printf( "Sat runs UNSAT = %6d.\n", p->nSatRunsUnsat );
PRT( "Simulation ", p->timeSim );
PRT( "Fraiging ", p->timeFraig );
PRT( "SAT ", p->timeSat );
PRT( "TOTAL ", p->timeTotal );
}
/**Function*************************************************************
Synopsis [Starts the simulatin manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk )
{
Sim_Man_t * p;
int i;
// start the manager
p = ALLOC( Sim_Man_t, 1 );
memset( p, 0, sizeof(Sim_Man_t) );
p->pNtk = pNtk;
p->nInputs = Abc_NtkCiNum(p->pNtk);
p->nOutputs = Abc_NtkCoNum(p->pNtk);
// internal simulation information
p->nSimBits = 2048;
p->nSimWords = SIM_NUM_WORDS(p->nSimBits);
......@@ -56,17 +168,14 @@ Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk )
// support information
p->nSuppBits = Abc_NtkCiNum(pNtk);
p->nSuppWords = SIM_NUM_WORDS(p->nSuppBits);
p->vSuppStr = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSuppWords, 1 );
p->vSuppStr = Sim_ComputeStrSupp( pNtk );
p->vSuppFun = Sim_UtilInfoAlloc( Abc_NtkCoNum(p->pNtk), p->nSuppWords, 1 );
// other data
p->pMmPat = Extra_MmFixedStart( sizeof(Sim_Pat_t) + p->nSuppWords * sizeof(unsigned) );
p->vFifo = Vec_PtrAlloc( 100 );
p->vDiffs = Vec_IntAlloc( 100 );
// allocate support targets
p->vSuppTargs = Vec_PtrAlloc( p->nSuppBits );
p->vSuppTargs->nSize = p->nSuppBits;
for ( i = 0; i < p->nSuppBits; i++ )
p->vSuppTargs->pArray[i] = Vec_IntAlloc( 8 );
// allocate support targets (array of unresolved outputs for each input)
p->vSuppTargs = Vec_VecStart( p->nInputs );
return p;
}
......@@ -87,14 +196,8 @@ void Sim_ManStop( Sim_Man_t * p )
if ( p->vSim0 ) Sim_UtilInfoFree( p->vSim0 );
if ( p->vSim1 ) Sim_UtilInfoFree( p->vSim1 );
if ( p->vSuppStr ) Sim_UtilInfoFree( p->vSuppStr );
if ( p->vSuppFun ) Sim_UtilInfoFree( p->vSuppFun );
if ( p->vUnateVarsP ) Sim_UtilInfoFree( p->vUnateVarsP );
if ( p->vUnateVarsN ) Sim_UtilInfoFree( p->vUnateVarsN );
if ( p->pMatSym ) Extra_BitMatrixStop( p->pMatSym );
if ( p->pMatNonSym ) Extra_BitMatrixStop( p->pMatNonSym );
if ( p->vSuppTargs ) Vec_PtrFreeFree( p->vSuppTargs );
if ( p->vUnateTargs ) Vec_PtrFree( p->vUnateTargs );
if ( p->vSymmTargs ) Vec_PtrFree( p->vSymmTargs );
// if ( p->vSuppFun ) Sim_UtilInfoFree( p->vSuppFun );
if ( p->vSuppTargs ) Vec_VecFree( p->vSuppTargs );
if ( p->pMmPat ) Extra_MmFixedStop( p->pMmPat, 0 );
if ( p->vFifo ) Vec_PtrFree( p->vFifo );
if ( p->vDiffs ) Vec_IntFree( p->vDiffs );
......@@ -103,7 +206,7 @@ void Sim_ManStop( Sim_Man_t * p )
/**Function*************************************************************
Synopsis [Returns one simulation pattern.]
Synopsis [Prints the manager statisticis.]
Description []
......@@ -112,16 +215,25 @@ void Sim_ManStop( Sim_Man_t * p )
SeeAlso []
***********************************************************************/
Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p )
void Sim_ManPrintStats( Sim_Man_t * p )
{
Sim_Pat_t * pPat;
pPat = (Sim_Pat_t *)Extra_MmFixedEntryFetch( p->pMmPat );
pPat->Output = -1;
pPat->pData = (unsigned *)((char *)pPat + sizeof(Sim_Pat_t));
memset( pPat->pData, 0, p->nSuppWords * sizeof(unsigned) );
return pPat;
printf( "Inputs = %d. Outputs = %d. Sim words = %d.\n",
Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords );
printf( "Total struct supps = %6d.\n", Sim_UtilCountSuppSizes(p, 1) );
printf( "Total func supps = %6d.\n", Sim_UtilCountSuppSizes(p, 0) );
printf( "Total targets = %6d.\n", Vec_VecSizeSize(p->vSuppTargs) );
printf( "Total sim patterns = %6d.\n", Vec_PtrSize(p->vFifo) );
printf( "Sat runs SAT = %6d.\n", p->nSatRunsSat );
printf( "Sat runs UNSAT = %6d.\n", p->nSatRunsUnsat );
PRT( "Simulation ", p->timeSim );
PRT( "Traversal ", p->timeTrav );
PRT( "Fraiging ", p->timeFraig );
PRT( "SAT ", p->timeSat );
PRT( "TOTAL ", p->timeTotal );
}
/**Function*************************************************************
Synopsis [Returns one simulation pattern.]
......@@ -133,14 +245,19 @@ Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p )
SeeAlso []
***********************************************************************/
void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat )
Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p )
{
Extra_MmFixedEntryRecycle( p->pMmPat, (char *)pPat );
Sim_Pat_t * pPat;
pPat = (Sim_Pat_t *)Extra_MmFixedEntryFetch( p->pMmPat );
pPat->Output = -1;
pPat->pData = (unsigned *)((char *)pPat + sizeof(Sim_Pat_t));
memset( pPat->pData, 0, p->nSuppWords * sizeof(unsigned) );
return pPat;
}
/**Function*************************************************************
Synopsis [Prints the manager statisticis.]
Synopsis [Returns one simulation pattern.]
Description []
......@@ -149,14 +266,9 @@ void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat )
SeeAlso []
***********************************************************************/
void Sim_ManPrintStats( Sim_Man_t * p )
void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat )
{
printf( "Inputs = %d. Outputs = %d. Sim words = %d.\n",
Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords );
printf( "Total struct supps = %6d.\n", Sim_UtilCountSuppSizes(p, 1) );
printf( "Total func supps = %6d.\n", Sim_UtilCountSuppSizes(p, 0) );
printf( "Total targets = %6d.\n", Vec_PtrSizeSize(p->vSuppTargs) );
printf( "Total sim patterns = %6d.\n", Vec_PtrSize(p->vFifo) );
Extra_MmFixedEntryRecycle( p->pMmPat, (char *)pPat );
}
////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [simSwitch.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Computes switching activity of nodes in the ABC network.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: simSwitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "sim.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Sim_NodeSimulate( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords );
static float Sim_ComputeSwitching( unsigned * pSimInfo, int nSimWords );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes switching activity using simulation.]
Description [Computes switching activity, which is understood as the
probability of switching under random simulation. Assigns the
random simulation information at the CI and propagates it through
the internal nodes of the AIG.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns )
{
Vec_Int_t * vSwitching;
float * pSwitching;
Vec_Ptr_t * vNodes;
Vec_Ptr_t * vSimInfo;
Abc_Obj_t * pNode;
unsigned * pSimInfo;
int nSimWords, i;
// allocate space for simulation info of all nodes
nSimWords = SIM_NUM_WORDS(nPatterns);
vSimInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nSimWords, 0 );
// assign the random simulation to the CIs
vSwitching = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
pSwitching = (float *)vSwitching->pArray;
Abc_NtkForEachCi( pNtk, pNode, i )
{
pSimInfo = Vec_PtrEntry(vSimInfo, pNode->Id);
Sim_UtilGetRandom( pSimInfo, nSimWords );
pSwitching[pNode->Id] = Sim_ComputeSwitching( pSimInfo, nSimWords );
}
// simulate the internal nodes
vNodes = Abc_AigDfs( pNtk, 1, 0 );
Vec_PtrForEachEntry( vNodes, pNode, i )
{
Sim_UtilSimulateNodeOne( pNode, vSimInfo, nSimWords );
pSimInfo = Vec_PtrEntry(vSimInfo, pNode->Id);
pSwitching[pNode->Id] = Sim_ComputeSwitching( pSimInfo, nSimWords );
}
Vec_PtrFree( vNodes );
Sim_UtilInfoFree( vSimInfo );
return vSwitching;
}
/**Function*************************************************************
Synopsis [Computes switching activity of one node.]
Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
SideEffects []
SeeAlso []
***********************************************************************/
float Sim_ComputeSwitching( unsigned * pSimInfo, int nSimWords )
{
int nOnes, nTotal;
nTotal = 32 * nSimWords;
nOnes = Sim_UtilCountOnes( pSimInfo, nSimWords );
return (float)2.0 * nOnes * (nTotal - nOnes) / nTotal / nTotal;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [simSym.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Simulation to determine two-variable symmetries.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: simSym.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "sim.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes two variable symmetries.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk )
{
Sym_Man_t * p;
Vec_Ptr_t * vResult;
int Result;
int i, clk = clock();
// srand( time(NULL) );
srand( 0xABC );
// start the simulation manager
p = Sym_ManStart( pNtk );
p->nPairsTotal = Sim_UtilCountAllPairs( p->vSuppFun, p->nSimWords, p->vPairsTotal );
// detect symmetries using circuit structure
Sim_SymmsStructCompute( pNtk, p->vMatrSymms );
p->nPairsSymm = p->nPairsSymmStr = Sim_UtilCountPairs( p->vMatrSymms, p->vPairsSym );
printf( "Total = %6d. Sym = %6d. NonSym = %6d. Remaining = %6d.\n",
p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsTotal-p->nPairsSymm-p->nPairsNonSymm );
// detect symmetries using simulation
for ( i = 1; i <= 1000; i++ )
{
// generate random pattern
Sim_UtilGetRandom( p->uPatRand, p->nSimWords );
// simulate this pattern
Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms );
if ( i % 100 != 0 )
continue;
// count the number of pairs
p->nPairsSymm = Sim_UtilCountPairs( p->vMatrSymms, p->vPairsSym );
p->nPairsNonSymm = Sim_UtilCountPairs( p->vMatrNonSymms, p->vPairsNonSym );
printf( "Total = %6d. Sym = %6d. NonSym = %6d. Remaining = %6d.\n",
p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsTotal-p->nPairsSymm-p->nPairsNonSymm );
}
Result = p->nPairsSymm;
vResult = p->vMatrSymms;
// p->vMatrSymms = NULL;
Sym_ManStop( p );
return Result;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [simSymSat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Satisfiability to determine two variable symmetries.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: simSymSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "sim.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Fraig_SymmsSatProveOne( Fraig_Man_t * p, int Var1, int Var2 );
static int Fraig_SymmsIsCliqueMatrix( Fraig_Man_t * p, Extra_BitMat_t * pMat );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs the SAT based check.]
Description [Given two bit matrices, with symm info and non-symm info,
checks the remaining pairs.]
SideEffects []
SeeAlso []
***********************************************************************/
void Fraig_SymmsSatComputeOne( Fraig_Man_t * p, Extra_BitMat_t * pMatSym, Extra_BitMat_t * pMatNonSym )
{
int VarsU[512], VarsV[512];
int nVarsU, nVarsV;
int v, u, i, k;
int Counter = 0;
int satCalled = 0;
int satProved = 0;
double Density;
int clk = clock();
extern int symsSat;
extern int Fraig_CountBits( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
// count undecided pairs
for ( v = 0; v < p->vInputs->nSize; v++ )
for ( u = v+1; u < p->vInputs->nSize; u++ )
{
if ( Extra_BitMatrixLookup1( pMatSym, v, u ) || Extra_BitMatrixLookup1( pMatNonSym, v, u ) )
continue;
Counter++;
}
// compute the density of 1's in the input space of the functions
Density = (double)Fraig_CountBits(p, Fraig_Regular(p->vOutputs->pArray[0])) * 100.0 / FRAIG_SIM_ROUNDS / 32;
printf( "Ins = %3d. Pairs to test = %4d. Dens = %5.2f %%. ",
p->vInputs->nSize, Counter, Density );
// go through the remaining variable pairs
for ( v = 0; v < p->vInputs->nSize; v++ )
for ( u = v+1; u < p->vInputs->nSize; u++ )
{
if ( Extra_BitMatrixLookup1( pMatSym, v, u ) || Extra_BitMatrixLookup1( pMatNonSym, v, u ) )
continue;
symsSat++;
satCalled++;
// collect the variables that are symmetric with each
nVarsU = nVarsV = 0;
for ( i = 0; i < p->vInputs->nSize; i++ )
{
if ( Extra_BitMatrixLookup1( pMatSym, u, i ) )
VarsU[nVarsU++] = i;
if ( Extra_BitMatrixLookup1( pMatSym, v, i ) )
VarsV[nVarsV++] = i;
}
if ( Fraig_SymmsSatProveOne( p, v, u ) )
{ // update the symmetric variable info
//printf( "%d sym %d\n", v, u );
for ( i = 0; i < nVarsU; i++ )
for ( k = 0; k < nVarsV; k++ )
{
Extra_BitMatrixInsert1( pMatSym, VarsU[i], VarsV[k] ); // Theorem 1
Extra_BitMatrixInsert2( pMatSym, VarsU[i], VarsV[k] ); // Theorem 1
Extra_BitMatrixOrTwo( pMatNonSym, VarsU[i], VarsV[k] ); // Theorem 2
}
satProved++;
}
else
{ // update the assymmetric variable info
//printf( "%d non-sym %d\n", v, u );
for ( i = 0; i < nVarsU; i++ )
for ( k = 0; k < nVarsV; k++ )
{
Extra_BitMatrixInsert1( pMatNonSym, VarsU[i], VarsV[k] ); // Theorem 3
Extra_BitMatrixInsert2( pMatNonSym, VarsU[i], VarsV[k] ); // Theorem 3
}
}
//Extra_BitMatrixPrint( pMatSym );
//Extra_BitMatrixPrint( pMatNonSym );
}
printf( "SAT calls = %3d. Proved = %3d. ", satCalled, satProved );
PRT( "Time", clock() - clk );
// make sure that the symmetry matrix contains only cliques
assert( Fraig_SymmsIsCliqueMatrix( p, pMatSym ) );
}
/**Function*************************************************************
Synopsis [Returns 1 if the variables are symmetric; 0 otherwise.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fraig_SymmsSatProveOne( Fraig_Man_t * p, int Var1, int Var2 )
{
Fraig_Node_t * pCof01, * pCof10, * pVar1, * pVar2;
int RetValue;
int nSatRuns = p->nSatCalls;
int nSatProof = p->nSatProof;
p->nBTLimit = 10; // set the backtrack limit
pVar1 = p->vInputs->pArray[Var1];
pVar2 = p->vInputs->pArray[Var2];
pCof01 = Fraig_CofactorTwo( p, p->vOutputs->pArray[0], pVar1, Fraig_Not(pVar2) );
pCof10 = Fraig_CofactorTwo( p, p->vOutputs->pArray[0], Fraig_Not(pVar1), pVar2 );
//printf( "(%d,%d)", p->nSatCalls - nSatRuns, p->nSatProof - nSatProof );
// RetValue = (pCof01 == pCof10);
// RetValue = Fraig_NodesAreaEqual( p, pCof01, pCof10 );
RetValue = Fraig_NodesAreEqual( p, pCof01, pCof10, -1 );
return RetValue;
}
/**Function*************************************************************
Synopsis [A sanity check procedure.]
Description [Makes sure that the symmetry information in the matrix
is closed w.r.t. the relationship of transitivity (that is the symmetry
graph is composed of cliques).]
SideEffects []
SeeAlso []
***********************************************************************/
int Fraig_SymmsIsCliqueMatrix( Fraig_Man_t * p, Extra_BitMat_t * pMat )
{
int v, u, i;
for ( v = 0; v < p->vInputs->nSize; v++ )
for ( u = v+1; u < p->vInputs->nSize; u++ )
{
if ( !Extra_BitMatrixLookup1( pMat, v, u ) )
continue;
// v and u are symmetric
for ( i = 0; i < p->vInputs->nSize; i++ )
{
if ( i == v || i == u )
continue;
// i is neither v nor u
// the symmetry status of i is the same w.r.t. to v and u
if ( Extra_BitMatrixLookup1( pMat, i, v ) != Extra_BitMatrixLookup1( pMat, i, u ) )
return 0;
}
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [simSymSim.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Simulation to determine two-variable symmetries.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: simSymSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "sim.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Sim_SymmsCreateSquare( Sym_Man_t * p, unsigned * pPat );
static void Sim_SymmsDeriveInfo( Sym_Man_t * p, unsigned * pPat, Abc_Obj_t * pNode, Extra_BitMat_t * pMatrix, int Output );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Detects non-symmetric pairs using one pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPat, Vec_Ptr_t * vMatrsNonSym )
{
Abc_Obj_t * pNode;
int i;
// create the simulation matrix
Sim_SymmsCreateSquare( p, pPat );
// simulate each node in the DFS order
Vec_PtrForEachEntry( p->vNodes, pNode, i )
{
if ( Abc_NodeIsConst(pNode) )
continue;
Sim_UtilSimulateNodeOne( pNode, p->vSim, p->nSimWords );
}
// collect info into the CO matrices
Abc_NtkForEachCo( p->pNtk, pNode, i )
{
pNode = Abc_ObjFanin0(pNode);
if ( Abc_ObjIsCi(pNode) || Abc_NodeIsConst(pNode) )
continue;
if ( Vec_IntEntry(p->vPairsTotal,i) == Vec_IntEntry(p->vPairsSym,i) + Vec_IntEntry(p->vPairsNonSym,i) )
continue;
Sim_SymmsDeriveInfo( p, pPat, pNode, Vec_PtrEntry(vMatrsNonSym, i), i );
}
}
/**Function*************************************************************
Synopsis [Creates the square matrix of simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sim_SymmsCreateSquare( Sym_Man_t * p, unsigned * pPat )
{
unsigned * pSimInfo;
Abc_Obj_t * pNode;
int i, w;
// for each PI var copy the pattern
Abc_NtkForEachCi( p->pNtk, pNode, i )
{
pSimInfo = Vec_PtrEntry( p->vSim, pNode->Id );
if ( Sim_HasBit(pPat, i) )
{
for ( w = 0; w < p->nSimWords; w++ )
pSimInfo[w] = SIM_MASK_FULL;
}
else
{
for ( w = 0; w < p->nSimWords; w++ )
pSimInfo[w] = 0;
}
// flip one bit
Sim_XorBit( pSimInfo, i );
}
}
/**Function*************************************************************
Synopsis [Transfers the info to the POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sim_SymmsDeriveInfo( Sym_Man_t * p, unsigned * pPat, Abc_Obj_t * pNode, Extra_BitMat_t * pMat, int Output )
{
unsigned * pSuppInfo;
unsigned * pSimInfo;
int i, w;
// get the simuation info for the node
pSimInfo = Vec_PtrEntry( p->vSim, pNode->Id );
pSuppInfo = Vec_PtrEntry( p->vSuppFun, Output );
// generate vectors A1 and A2
for ( w = 0; w < p->nSimWords; w++ )
{
p->uPatCol[w] = pSuppInfo[w] & pPat[w] & pSimInfo[w];
p->uPatRow[w] = pSuppInfo[w] & pPat[w] & ~pSimInfo[w];
}
// add two dimensions
for ( i = 0; i < p->nInputs; i++ )
if ( Sim_HasBit( p->uPatCol, i ) )
Extra_BitMatrixOr( pMat, i, p->uPatRow );
// add two dimensions
for ( i = 0; i < p->nInputs; i++ )
if ( Sim_HasBit( p->uPatRow, i ) )
Extra_BitMatrixOr( pMat, i, p->uPatCol );
// generate vectors B1 and B2
for ( w = 0; w < p->nSimWords; w++ )
{
p->uPatCol[w] = pSuppInfo[w] & ~pPat[w] & pSimInfo[w];
p->uPatRow[w] = pSuppInfo[w] & ~pPat[w] & ~pSimInfo[w];
}
// add two dimensions
for ( i = 0; i < p->nInputs; i++ )
if ( Sim_HasBit( p->uPatCol, i ) )
Extra_BitMatrixOr( pMat, i, p->uPatRow );
// add two dimensions
for ( i = 0; i < p->nInputs; i++ )
if ( Sim_HasBit( p->uPatRow, i ) )
Extra_BitMatrixOr( pMat, i, p->uPatCol );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -25,6 +25,17 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int bit_count[256] = {
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
};
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -44,6 +55,7 @@ Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean )
{
Vec_Ptr_t * vInfo;
int i;
assert( nSize > 0 && nWords > 0 );
vInfo = Vec_PtrAlloc( nSize );
vInfo->pArray[0] = ALLOC( unsigned, nSize * nWords );
if ( fClean )
......@@ -137,71 +149,6 @@ void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, V
/**Function*************************************************************
Synopsis [Computes structural supports.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sim_UtilComputeStrSupp( Sim_Man_t * p )
{
Abc_Obj_t * pNode;
unsigned * pSimmNode, * pSimmNode1, * pSimmNode2;
int i, k;
// assign the structural support to the PIs
Abc_NtkForEachCi( p->pNtk, pNode, i )
Sim_SuppStrSetVar( p, pNode, i );
// derive the structural supports of the internal nodes
Abc_NtkForEachNode( p->pNtk, pNode, i )
{
if ( Abc_NodeIsConst(pNode) )
continue;
pSimmNode = p->vSuppStr->pArray[ pNode->Id ];
pSimmNode1 = p->vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ];
pSimmNode2 = p->vSuppStr->pArray[ Abc_ObjFaninId1(pNode) ];
for ( k = 0; k < p->nSuppWords; k++ )
pSimmNode[k] = pSimmNode1[k] | pSimmNode2[k];
}
// set the structural supports of the PO nodes
Abc_NtkForEachCo( p->pNtk, pNode, i )
{
pSimmNode = p->vSuppStr->pArray[ pNode->Id ];
pSimmNode1 = p->vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ];
for ( k = 0; k < p->nSuppWords; k++ )
pSimmNode[k] = pSimmNode1[k];
}
}
/**Function*************************************************************
Synopsis [Assigns random simulation info to the PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sim_UtilAssignRandom( Sim_Man_t * p )
{
Abc_Obj_t * pNode;
unsigned * pSimInfo;
int i, k;
// assign the random/systematic simulation info to the PIs
Abc_NtkForEachCi( p->pNtk, pNode, i )
{
pSimInfo = p->vSim0->pArray[pNode->Id];
for ( k = 0; k < p->nSimWords; k++ )
pSimInfo[k] = SIM_RANDOM_UNSIGNED;
}
}
/**Function*************************************************************
Synopsis [Flips the simulation info of the node.]
Description []
......@@ -211,12 +158,12 @@ void Sim_UtilAssignRandom( Sim_Man_t * p )
SeeAlso []
***********************************************************************/
void Sim_UtilFlipSimInfo( Sim_Man_t * p, Abc_Obj_t * pNode )
void Sim_UtilInfoFlip( Sim_Man_t * p, Abc_Obj_t * pNode )
{
unsigned * pSimInfo1, * pSimInfo2;
int k;
pSimInfo1 = p->vSim1->pArray[pNode->Id];
pSimInfo2 = p->vSim0->pArray[pNode->Id];
pSimInfo1 = p->vSim0->pArray[pNode->Id];
pSimInfo2 = p->vSim1->pArray[pNode->Id];
for ( k = 0; k < p->nSimWords; k++ )
pSimInfo2[k] = ~pSimInfo1[k];
}
......@@ -232,12 +179,12 @@ void Sim_UtilFlipSimInfo( Sim_Man_t * p, Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
bool Sim_UtilCompareSimInfo( Sim_Man_t * p, Abc_Obj_t * pNode )
bool Sim_UtilInfoCompare( Sim_Man_t * p, Abc_Obj_t * pNode )
{
unsigned * pSimInfo1, * pSimInfo2;
int k;
pSimInfo1 = p->vSim1->pArray[pNode->Id];
pSimInfo2 = p->vSim0->pArray[pNode->Id];
pSimInfo1 = p->vSim0->pArray[pNode->Id];
pSimInfo2 = p->vSim1->pArray[pNode->Id];
for ( k = 0; k < p->nSimWords; k++ )
if ( pSimInfo2[k] != pSimInfo1[k] )
return 0;
......@@ -343,6 +290,44 @@ void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fT
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords )
{
unsigned * pSimmNode, * pSimmNode1, * pSimmNode2;
int k, fComp1, fComp2;
// simulate the internal nodes
assert( Abc_ObjIsNode(pNode) );
if ( Abc_NodeIsConst(pNode) )
return;
pSimmNode = Vec_PtrEntry(vSimInfo, pNode->Id);
pSimmNode1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode));
pSimmNode2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode));
fComp1 = Abc_ObjFaninC0(pNode);
fComp2 = Abc_ObjFaninC1(pNode);
if ( fComp1 && fComp2 )
for ( k = 0; k < nSimWords; k++ )
pSimmNode[k] = ~pSimmNode1[k] & ~pSimmNode2[k];
else if ( fComp1 && !fComp2 )
for ( k = 0; k < nSimWords; k++ )
pSimmNode[k] = ~pSimmNode1[k] & pSimmNode2[k];
else if ( !fComp1 && fComp2 )
for ( k = 0; k < nSimWords; k++ )
pSimmNode[k] = pSimmNode1[k] & ~pSimmNode2[k];
else // if ( fComp1 && fComp2 )
for ( k = 0; k < nSimWords; k++ )
pSimmNode[k] = pSimmNode1[k] & pSimmNode2[k];
}
/**Function*************************************************************
Synopsis [Returns 1 if the simulation infos are equal.]
Description []
......@@ -361,13 +346,106 @@ int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct )
{
Abc_NtkForEachCo( p->pNtk, pNode, i )
Abc_NtkForEachCi( p->pNtk, pNodeCi, v )
Counter += Sim_SuppStrHasVar( p, pNode, v );
Counter += Sim_SuppStrHasVar( p->vSuppStr, pNode, v );
}
else
{
Abc_NtkForEachCo( p->pNtk, pNode, i )
Abc_NtkForEachCi( p->pNtk, pNodeCi, v )
Counter += Sim_SuppFunHasVar( p, i, v );
Counter += Sim_SuppFunHasVar( p->vSuppFun, i, v );
}
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of 1's in the bitstring.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sim_UtilCountOnes( unsigned * pSimInfo, int nSimWords )
{
unsigned char * pBytes;
int nOnes, nBytes, i;
pBytes = (unsigned char *)pSimInfo;
nBytes = 4 * nSimWords;
nOnes = 0;
for ( i = 0; i < nBytes; i++ )
nOnes += bit_count[ pBytes[i] ];
return nOnes;
}
/**Function*************************************************************
Synopsis [Returns the random pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sim_UtilGetRandom( unsigned * pPatRand, int nSimWords )
{
int k;
for ( k = 0; k < nSimWords; k++ )
pPatRand[k] = SIM_RANDOM_UNSIGNED;
}
/**Function*************************************************************
Synopsis [Counts the total number of pairs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sim_UtilCountAllPairs( Vec_Ptr_t * vSuppFun, int nSimWords, Vec_Int_t * vCounters )
{
unsigned * pSupp;
int Counter, nOnes, nPairs, i;
Counter = 0;
Vec_PtrForEachEntry( vSuppFun, pSupp, i )
{
nOnes = Sim_UtilCountOnes( pSupp, nSimWords );
nPairs = nOnes * (nOnes - 1) / 2;
Vec_IntWriteEntry( vCounters, i, nPairs );
Counter += nPairs;
}
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of entries in the array of matrices.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sim_UtilCountPairs( Vec_Ptr_t * vMatrs, Vec_Int_t * vCounters )
{
Extra_BitMat_t * vMat;
int Counter, nPairs, i;
Counter = 0;
Vec_PtrForEachEntry( vMatrs, vMat, i )
{
nPairs = Extra_BitMatrixCountOnesUpper( vMat );
Vec_IntWriteEntry( vCounters, i, nPairs );
Counter += nPairs;
}
return Counter;
}
......
......@@ -50,6 +50,7 @@ struct Fraig_ParamsStruct_t_
int fTryProve; // tries to solve the final miter
int fVerbose; // the verbosiness flag
int fVerboseP; // the verbosiness flag (for proof reporting)
int fInternal; // is set to 1 for internal fraig calls
};
////////////////////////////////////////////////////////////////////////
......
......@@ -164,10 +164,9 @@ Fraig_Node_t * Fraig_ManReadIthVar( Fraig_Man_t * p, int i )
/**Function*************************************************************
Synopsis [Creates a new node.]
Synopsis [Creates a new PO node.]
Description [This procedure should be called to create the constant
node and the PI nodes first.]
Description [This procedure may take a complemented node.]
SideEffects []
......@@ -176,9 +175,8 @@ Fraig_Node_t * Fraig_ManReadIthVar( Fraig_Man_t * p, int i )
***********************************************************************/
void Fraig_ManSetPo( Fraig_Man_t * p, Fraig_Node_t * pNode )
{
// assert( pNode->fNodePo == 0 );
// internal node may be a PO two times
pNode->fNodePo = 1;
Fraig_Regular(pNode)->fNodePo = 1;
Fraig_NodeVecPush( p->vOutputs, pNode );
}
......
......@@ -768,7 +768,80 @@ void Fraig_ReallocateSimulationInfo( Fraig_Man_t * p )
/**Function*************************************************************
Synopsis [Doubles the size of simulation info.]
Synopsis [Generated trivial counter example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int * Fraig_ManAllocCounterExample( Fraig_Man_t * p )
{
int * pModel;
pModel = ALLOC( int, p->vInputs->nSize );
memset( pModel, 0, sizeof(int) * p->vInputs->nSize );
return pModel;
}
/**Function*************************************************************
Synopsis [Saves the counter example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fraig_ManSimulateBitNode_rec( Fraig_Man_t * p, Fraig_Node_t * pNode )
{
int Value0, Value1;
if ( Fraig_NodeIsTravIdCurrent( p, pNode ) )
return pNode->fMark3;
Fraig_NodeSetTravIdCurrent( p, pNode );
Value0 = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode->p1) );
Value1 = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode->p2) );
Value0 ^= Fraig_IsComplement(pNode->p1);
Value1 ^= Fraig_IsComplement(pNode->p2);
pNode->fMark3 = Value0 & Value1;
return pNode->fMark3;
}
/**Function*************************************************************
Synopsis [Simulates one bit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fraig_ManSimulateBitNode( Fraig_Man_t * p, Fraig_Node_t * pNode, int * pModel )
{
int fCompl, RetValue, i;
// set the PI values
Fraig_ManIncrementTravId( p );
for ( i = 0; i < p->vInputs->nSize; i++ )
{
Fraig_NodeSetTravIdCurrent( p, p->vInputs->pArray[i] );
p->vInputs->pArray[i]->fMark3 = pModel[i];
}
// perform the traversal
fCompl = Fraig_IsComplement(pNode);
RetValue = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode) );
return fCompl ^ RetValue;
}
/**Function*************************************************************
Synopsis [Saves the counter example.]
Description []
......@@ -779,33 +852,52 @@ void Fraig_ReallocateSimulationInfo( Fraig_Man_t * p )
***********************************************************************/
int * Fraig_ManSaveCounterExample( Fraig_Man_t * p, Fraig_Node_t * pNode )
{
int * pModel = NULL;
int * pModel;
int iPattern;
int i;
int i, fCompl;
// the node can be complemented
fCompl = Fraig_IsComplement(pNode);
// because we compare with constant 0, p->pConst1 should also be complemented
fCompl = !fCompl;
iPattern = Fraig_FindFirstDiff( p->pConst1, pNode, p->nWordsDyna, 0 );
// derive the model
pModel = Fraig_ManAllocCounterExample( p );
iPattern = Fraig_FindFirstDiff( p->pConst1, Fraig_Regular(pNode), fCompl, p->nWordsRand, 1 );
if ( iPattern >= 0 )
{
pModel = ALLOC( int, p->vInputs->nSize );
memset( pModel, 0, sizeof(int) * p->vInputs->nSize );
for ( i = 0; i < p->vInputs->nSize; i++ )
if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimD, iPattern ) )
if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimR, iPattern ) )
pModel[i] = 1;
/*
printf( "SAT solver's pattern:\n" );
for ( i = 0; i < p->vInputs->nSize; i++ )
printf( "%d", pModel[i] );
printf( "\n" );
*/
assert( Fraig_ManSimulateBitNode( p, pNode, pModel ) );
return pModel;
}
iPattern = Fraig_FindFirstDiff( p->pConst1, pNode, p->nWordsRand, 1 );
iPattern = Fraig_FindFirstDiff( p->pConst1, Fraig_Regular(pNode), fCompl, p->iWordStart, 0 );
if ( iPattern >= 0 )
{
pModel = ALLOC( int, p->vInputs->nSize );
memset( pModel, 0, sizeof(int) * p->vInputs->nSize );
for ( i = 0; i < p->vInputs->nSize; i++ )
if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimR, iPattern ) )
if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimD, iPattern ) )
pModel[i] = 1;
/*
printf( "SAT solver's pattern:\n" );
for ( i = 0; i < p->vInputs->nSize; i++ )
printf( "%d", pModel[i] );
printf( "\n" );
*/
assert( Fraig_ManSimulateBitNode( p, pNode, pModel ) );
return pModel;
}
return pModel;
FREE( pModel );
return NULL;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -239,10 +239,11 @@ struct Fraig_NodeStruct_t_
unsigned fMark0 : 1; // the mark used for traversals
unsigned fMark1 : 1; // the mark used for traversals
unsigned fMark2 : 1; // the mark used for traversals
unsigned fMark3 : 1; // the mark used for traversals
unsigned fFeedUse : 1; // the presence of the variable in the feedback
unsigned fFeedVal : 1; // the value of the variable in the feedback
unsigned nFanouts : 2; // the indicator of fanouts (none, one, or many)
unsigned nOnes : 22; // the number of 1's in the random sim info
unsigned nOnes : 21; // the number of 1's in the random sim info
// the children of the node
Fraig_Node_t * p1; // the first child
......@@ -379,6 +380,7 @@ extern void Fraig_FeedBackInit( Fraig_Man_t * p );
extern void Fraig_FeedBack( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars, Fraig_Node_t * pOld, Fraig_Node_t * pNew );
extern void Fraig_FeedBackTest( Fraig_Man_t * p );
extern int Fraig_FeedBackCompress( Fraig_Man_t * p );
extern int * Fraig_ManAllocCounterExample( Fraig_Man_t * p );
extern int * Fraig_ManSaveCounterExample( Fraig_Man_t * p, Fraig_Node_t * pNode );
/*=== fraigMem.c =============================================================*/
extern Fraig_MemFixed_t * Fraig_MemFixedStart( int nEntrySize );
......@@ -406,7 +408,7 @@ extern Fraig_Node_t * Fraig_HashTableLookupF0( Fraig_Man_t * pMan, Fraig_No
extern void Fraig_HashTableInsertF0( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
extern int Fraig_CompareSimInfo( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand );
extern int Fraig_CompareSimInfoUnderMask( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand, unsigned * puMask );
extern int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand );
extern int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int fCompl, int iWordLast, int fUseRand );
extern void Fraig_CollectXors( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand, unsigned * puMask );
extern void Fraig_TablePrintStatsS( Fraig_Man_t * pMan );
extern void Fraig_TablePrintStatsF( Fraig_Man_t * pMan );
......@@ -416,10 +418,6 @@ extern int Fraig_TableRehashF0( Fraig_Man_t * pMan, int fLinkEqu
extern int Fraig_NodeCountPis( Msat_IntVec_t * vVars, int nVarsPi );
extern int Fraig_NodeCountSuppVars( Fraig_Man_t * p, Fraig_Node_t * pNode, int fSuppStr );
extern int Fraig_NodesCompareSupps( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew );
extern void Fraig_ManIncrementTravId( Fraig_Man_t * pMan );
extern void Fraig_NodeSetTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
extern int Fraig_NodeIsTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
extern int Fraig_NodeIsTravIdPrevious( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
extern int Fraig_NodeAndSimpleCase_rec( Fraig_Node_t * pOld, Fraig_Node_t * pNew );
extern int Fraig_NodeIsExorType( Fraig_Node_t * pNode );
extern void Fraig_ManSelectBestChoice( Fraig_Man_t * p );
......@@ -435,6 +433,10 @@ extern int Fraig_NodeSimsContained( Fraig_Man_t * pMan, Fraig_No
extern int Fraig_NodeIsInSupergate( Fraig_Node_t * pOld, Fraig_Node_t * pNew );
extern Fraig_NodeVec_t * Fraig_CollectSupergate( Fraig_Node_t * pNode, int fStopAtMux );
extern int Fraig_CountPis( Fraig_Man_t * p, Msat_IntVec_t * vVarNums );
extern void Fraig_ManIncrementTravId( Fraig_Man_t * pMan );
extern void Fraig_NodeSetTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
extern int Fraig_NodeIsTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
extern int Fraig_NodeIsTravIdPrevious( Fraig_Man_t * pMan, Fraig_Node_t * pNode );
/*=== fraigVec.c ===============================================================*/
extern void Fraig_NodeVecSortByRefCount( Fraig_NodeVec_t * p );
......
......@@ -42,6 +42,7 @@ int timeAssign;
***********************************************************************/
void Fraig_ParamsSetDefault( Fraig_Params_t * pParams )
{
memset( pParams, 0, sizeof(Fraig_Params_t) );
pParams->nPatsRand = FRAIG_PATTERNS_RANDOM; // the number of words of random simulation info
pParams->nPatsDyna = FRAIG_PATTERNS_DYNAMIC; // the number of words of dynamic simulation info
pParams->nBTLimit = 99; // the max number of backtracks to perform
......
......@@ -122,11 +122,23 @@ void Fraig_ManProveMiter( Fraig_Man_t * p )
***********************************************************************/
int Fraig_ManCheckMiter( Fraig_Man_t * p )
{
if ( p->vOutputs->pArray[0] == Fraig_Not(p->pConst1) )
Fraig_Node_t * pNode;
FREE( p->pModel );
// get the output node (it can be complemented!)
pNode = p->vOutputs->pArray[0];
// if the miter is constant 0, the problem is UNSAT
if ( pNode == Fraig_Not(p->pConst1) )
return 1;
// consider the special case when the miter is constant 1
if ( pNode == p->pConst1 )
{
// in this case, any counter example will do to distinquish it from constant 0
// here we pick the counter example composed of all zeros
p->pModel = Fraig_ManAllocCounterExample( p );
return 0;
}
// save the counter example
FREE( p->pModel );
p->pModel = Fraig_ManSaveCounterExample( p, Fraig_Regular(p->vOutputs->pArray[0]) );
p->pModel = Fraig_ManSaveCounterExample( p, pNode );
// if the model is not found, return undecided
if ( p->pModel == NULL )
return -1;
......
......@@ -382,14 +382,38 @@ int Fraig_CompareSimInfo( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWor
SeeAlso []
***********************************************************************/
int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand )
int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int fCompl, int iWordLast, int fUseRand )
{
int i, v;
assert( !Fraig_IsComplement(pNode1) );
assert( !Fraig_IsComplement(pNode2) );
// take into account possible internal complementation
fCompl ^= pNode1->fInv;
fCompl ^= pNode2->fInv;
// find the pattern
if ( fCompl )
{
if ( fUseRand )
{
for ( i = 0; i < iWordLast; i++ )
if ( pNode1->puSimR[i] != ~pNode2->puSimR[i] )
for ( v = 0; v < 32; v++ )
if ( (pNode1->puSimR[i] ^ ~pNode2->puSimR[i]) & (1 << v) )
return i * 32 + v;
}
else
{
for ( i = 0; i < iWordLast; i++ )
if ( pNode1->puSimD[i] != ~pNode2->puSimD[i] )
for ( v = 0; v < 32; v++ )
if ( (pNode1->puSimD[i] ^ ~pNode2->puSimD[i]) & (1 << v) )
return i * 32 + v;
}
}
else
{
if ( fUseRand )
{
// check the simulation info
for ( i = 0; i < iWordLast; i++ )
if ( pNode1->puSimR[i] != pNode2->puSimR[i] )
for ( v = 0; v < 32; v++ )
......@@ -398,13 +422,13 @@ int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWord
}
else
{
// check the simulation info
for ( i = 0; i < iWordLast; i++ )
if ( pNode1->puSimD[i] != pNode2->puSimD[i] )
for ( v = 0; v < 32; v++ )
if ( (pNode1->puSimD[i] ^ pNode2->puSimD[i]) & (1 << v) )
return i * 32 + v;
}
}
return -1;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment