Commit 0c1e87bc by Alan Mishchenko

Version abc70705

parent a8db621d
......@@ -6,12 +6,21 @@ CP := cp
PROG := abc
MODULES := src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src/base/ver \
src/aig/ivy src/aig/hop src/aig/rwt src/aig/deco src/aig/mem src/aig/ec \
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse src/bdd/reo src/bdd/cas \
src/map/fpga src/map/mapper src/map/mio src/map/super src/map/if \
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/espresso src/misc/nm src/misc/vec src/misc/hash \
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim src/opt/ret src/opt/res src/opt/kit \
MODULES := src/base/abc src/base/abci src/base/cmd \
src/base/io src/base/main src/base/ver \
src/aig/ivy src/aig/hop src/aig/rwt src/aig/deco \
src/aig/mem src/aig/dar src/aig/fra src/aig/cnf \
src/aig/ec \
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr \
src/bdd/parse src/bdd/reo src/bdd/cas \
src/map/fpga src/map/mapper src/map/mio \
src/map/super src/map/if \
src/misc/extra src/misc/mvc src/misc/st src/misc/util \
src/misc/espresso src/misc/nm src/misc/vec \
src/misc/hash \
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr \
src/opt/sim src/opt/ret src/opt/res src/opt/kit \
src/opt/lpk \
src/sat/bsat src/sat/csat src/sat/msat src/sat/fraig \
src/phys/place
......
......@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\bsat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\opt\kit" /I "src\opt\res" /I "src\map\fpga" /I "src\map\if" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\aig\ivy" /I "src\aig\hop" /I "src\aig\rwt" /I "src\aig\deco" /I "src\aig\mem" /I "src\aig\dar" /I "src\aig\cnf" /I "src\aig\fra" /I "src\temp\esop" /I "src\phys\place" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\bsat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\opt\kit" /I "src\opt\res" /I "src\opt\lpk" /I "src\opt\bdc" /I "src\map\fpga" /I "src\map\if" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\aig\ivy" /I "src\aig\hop" /I "src\aig\rwt" /I "src\aig\deco" /I "src\aig\mem" /I "src\aig\dar" /I "src\aig\cnf" /I "src\aig\fra" /I "src\temp\esop" /I "src\phys\place" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
......@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\bsat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\opt\kit" /I "src\opt\res" /I "src\map\fpga" /I "src\map\if" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\aig\ivy" /I "src\aig\hop" /I "src\aig\rwt" /I "src\aig\deco" /I "src\aig\mem" /I "src\aig\dar" /I "src\aig\cnf" /I "src\aig\fra" /I "src\temp\esop" /I "src\phys\place" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\bsat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\opt\kit" /I "src\opt\res" /I "src\opt\lpk" /I "src\opt\bdc" /I "src\map\fpga" /I "src\map\if" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\aig\ivy" /I "src\aig\hop" /I "src\aig\rwt" /I "src\aig\deco" /I "src\aig\mem" /I "src\aig\dar" /I "src\aig\cnf" /I "src\aig\fra" /I "src\temp\esop" /I "src\phys\place" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
# SUBTRACT CPP /X
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
......@@ -230,10 +230,6 @@ SOURCE=.\src\base\abci\abcDsd.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcDsdRes.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcEspresso.c
# End Source File
# Begin Source File
......@@ -1937,6 +1933,46 @@ SOURCE=.\src\opt\bdc\bdcInt.h
SOURCE=.\src\opt\bdc\bdcTable.c
# End Source File
# End Group
# Begin Group "lpk"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\opt\lpk\lpk.h
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkCore.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkCut.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkInt.h
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkMan.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkMap.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkMulti.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkMux.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkSets.c
# End Source File
# End Group
# End Group
# Begin Group "map"
......
......@@ -31,6 +31,7 @@ alias fsto fraig_store
alias fres fraig_restore
alias ft fraig_trust
alias lp lutpack
alias pd print_dsd
alias pex print_exdc -d
alias pf print_factor
alias pfan print_fanio
......@@ -169,6 +170,8 @@ alias tst6 "r i10_if6.blif; st; ps; r x/rec6_16_.blif; st; rec_start; r i10_
alias bug "r pj1_if3.blif; lp"
alias table "r lutexp.baf; test"
alias t "r c.blif; st; wc c.cnf"
#alias t "r c.blif; st; wc c.cnf"
#alias t "r test/dsdmap6.blif; lutpack -vw; cec"
alias t "r i10_if4.blif; lp"
......@@ -227,23 +227,6 @@ struct Abc_Lib_t_
void * pGenlib; // the genlib library used to map this design
};
typedef struct Lut_Par_t_ Lut_Par_t;
struct Lut_Par_t_
{
// user-controlled parameters
int nLutsMax; // (N) the maximum number of LUTs in the structure
int nLutsOver; // (Q) the maximum number of LUTs not in the MFFC
int nVarsShared; // (S) the maximum number of shared variables (crossbars)
int nGrowthLevel; // (L) the maximum increase in the node level after resynthesis
int fSatur; // iterate till saturation
int fZeroCost; // accept zero-cost replacements
int fVerbose; // the verbosiness flag
int fVeryVerbose; // additional verbose info printout
// internal parameters
int nLutSize; // (K) the LUT size (determined by the input network)
int nVarsMax; // (V) the largest number of variables: V = N * (K-1) + 1
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......
......@@ -881,12 +881,20 @@ unsigned * Abc_ConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars, V
Hop_Obj_t * pObj;
unsigned * pTruth, * pTruth2;
int i, nWords, nNodes;
Vec_Ptr_t * vTtElems;
// if the number of variables is more than 8, allocate truth tables
if ( nVars > 8 )
vTtElems = Vec_PtrAllocTruthTables( nVars );
else
vTtElems = NULL;
// clear the data fields and set marks
nNodes = Abc_ConvertAigToTruth_rec1( pRoot );
// prepare memory
nWords = Hop_TruthWordNum( nVars );
Vec_IntClear( vTruth );
Vec_IntGrow( vTruth, nWords * nNodes );
Vec_IntGrow( vTruth, nWords * (nNodes+1) );
pTruth = Vec_IntFetch( vTruth, nWords );
// check the case of a constant
if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) )
......@@ -900,21 +908,33 @@ unsigned * Abc_ConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars, V
}
// set elementary truth tables at the leaves
assert( nVars <= Hop_ManPiNum(p) );
assert( Hop_ManPiNum(p) <= 8 );
// assert( Hop_ManPiNum(p) <= 8 );
if ( fMsbFirst )
{
Hop_ManForEachPi( p, pObj, i )
pObj->pData = (void *)uTruths[nVars-1-i];
{
if ( vTtElems )
pObj->pData = Vec_PtrEntry(vTtElems, nVars-1-i);
else
pObj->pData = (void *)uTruths[nVars-1-i];
}
}
else
{
Hop_ManForEachPi( p, pObj, i )
pObj->pData = (void *)uTruths[i];
{
if ( vTtElems )
pObj->pData = Vec_PtrEntry(vTtElems, i);
else
pObj->pData = (void *)uTruths[i];
}
}
// clear the marks and compute the truth table
pTruth2 = Abc_ConvertAigToTruth_rec2( pRoot, vTruth, nWords );
// copy the result
Extra_TruthCopy( pTruth, pTruth2, nVars );
if ( vTtElems )
Vec_PtrFree( vTtElems );
return pTruth;
}
......
......@@ -26,7 +26,7 @@
#include "fpga.h"
#include "if.h"
#include "res.h"
//#include "dar.h"
#include "lpk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -1509,23 +1509,37 @@ int Abc_CommandPrintDsd( Abc_Frame_t * pAbc, int argc, char ** argv )
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
int fUseLibrary;
int fCofactor;
int nCofLevel;
extern void Kit_DsdTest( unsigned * pTruth, int nVars );
extern void Kit_DsdPrintCofactors( unsigned * pTruth, int nVars, int nCofLevel, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fUseLibrary = 1;
nCofLevel = 1;
fCofactor = 1;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "lh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "Nch" ) ) != EOF )
{
switch ( c )
{
case 'l':
fUseLibrary ^= 1;
case 'N':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
goto usage;
}
nCofLevel = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nCofLevel < 0 )
goto usage;
break;
case 'c':
fCofactor ^= 1;
break;
case 'h':
goto usage;
......@@ -1549,16 +1563,16 @@ int Abc_CommandPrintDsd( Abc_Frame_t * pAbc, int argc, char ** argv )
// convert it to truth table
{
Abc_Obj_t * pObj = Abc_ObjFanin0( Abc_NtkPo(pNtk, 0) );
Vec_Int_t * vMemory = Vec_IntAlloc( 10000 );
Vec_Int_t * vMemory = Vec_IntAlloc(0);
unsigned * pTruth;
if ( !Abc_ObjIsNode(pObj) )
{
fprintf( pErr, "The fanin of the first PO node does not have a logic function.\n" );
return 1;
}
if ( Abc_ObjFaninNum(pObj) > 8 )
if ( Abc_ObjFaninNum(pObj) > 16 )
{
fprintf( pErr, "Currently works only for up to 8 inputs.\n" );
fprintf( pErr, "Currently works only for up to 16 inputs.\n" );
return 1;
}
pTruth = Abc_ConvertAigToTruth( pNtk->pManFunc, Hop_Regular(pObj->pData), Abc_ObjFaninNum(pObj), vMemory, 0 );
......@@ -1566,16 +1580,20 @@ int Abc_CommandPrintDsd( Abc_Frame_t * pAbc, int argc, char ** argv )
Extra_TruthNot( pTruth, pTruth, Abc_ObjFaninNum(pObj) );
Extra_PrintBinary( stdout, pTruth, 1 << Abc_ObjFaninNum(pObj) );
printf( "\n" );
Kit_DsdTest( pTruth, Abc_ObjFaninNum(pObj) );
if ( fCofactor )
Kit_DsdPrintCofactors( pTruth, Abc_ObjFaninNum(pObj), nCofLevel, 1 );
else
Kit_DsdTest( pTruth, Abc_ObjFaninNum(pObj) );
Vec_IntFree( vMemory );
}
return 0;
usage:
fprintf( pErr, "usage: print_dsd [-h]\n" );
fprintf( pErr, "\t print DSD formula for a single-output function with less than 16 variables\n" );
// fprintf( pErr, "\t-l : used library gate names (if mapped) [default = %s]\n", fUseLibrary? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
fprintf( pErr, "usage: print_dsd [-ch] [-N num]\n" );
fprintf( pErr, "\t print DSD formula for a single-output function with less than 16 variables\n" );
fprintf( pErr, "\t-c : toggle recursive cofactoring [default = %s]\n", fCofactor? "yes": "no" );
fprintf( pErr, "\t-N num : the number of levels to cofactor [default = %d]\n", nCofLevel );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
......@@ -2906,26 +2924,22 @@ int Abc_CommandLutpack( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
Lut_Par_t Pars, * pPars = &Pars;
Lpk_Par_t Pars, * pPars = &Pars;
int c;
extern int Abc_LutResynthesize( Abc_Ntk_t * pNtk, Lut_Par_t * pPars );
// printf( "Implementation of this command is not finished.\n" );
// return 1;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
memset( pPars, 0, sizeof(Lut_Par_t) );
memset( pPars, 0, sizeof(Lpk_Par_t) );
pPars->nLutsMax = 4; // (N) the maximum number of LUTs in the structure
pPars->nLutsOver = 3; // (Q) the maximum number of LUTs not in the MFFC
pPars->nVarsShared = 3; // (S) the maximum number of shared variables (crossbars)
pPars->nGrowthLevel = 1;
pPars->nVarsShared = 0; // (S) the maximum number of shared variables (crossbars)
pPars->nGrowthLevel = 9; // (L) the maximum number of increased levels
pPars->fSatur = 1;
pPars->fZeroCost = 0;
pPars->fVerbose = 0;
pPars->fVerbose = 1;
pPars->fVeryVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "NQSLszvwh" ) ) != EOF )
......@@ -3007,7 +3021,7 @@ int Abc_CommandLutpack( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// modify the current network
if ( !Abc_LutResynthesize( pNtk, pPars ) )
if ( !Lpk_Resynthesize( pNtk, pPars ) )
{
fprintf( pErr, "Resynthesis has failed.\n" );
return 1;
......
......@@ -145,8 +145,8 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
Extra_ProgressBarUpdate( pProgress, i, "Initial" );
// add the node to the mapper
pNode->pCopy = (Abc_Obj_t *)If_ManCreateAnd( pIfMan,
(If_Obj_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode),
(If_Obj_t *)Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) );
If_NotCond( (If_Obj_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
If_NotCond( (If_Obj_t *)Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
// set up the choice node
if ( Abc_AigNodeIsChoice( pNode ) )
{
......@@ -162,7 +162,7 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
// set the primary outputs without copying the phase
Abc_NtkForEachCo( pNtk, pNode, i )
If_ManCreateCo( pIfMan, (If_Obj_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ) );
return pIfMan;
}
......
......@@ -11,7 +11,6 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcDebug.c \
src/base/abci/abcDress.c \
src/base/abci/abcDsd.c \
src/base/abci/abcDsdRes.c \
src/base/abci/abcEspresso.c \
src/base/abci/abcExtract.c \
src/base/abci/abcFpga.c \
......
......@@ -715,7 +715,7 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
int fHex;
int c;
fHex = 0;
fHex = 1;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "xh" ) ) != EOF )
{
......
......@@ -212,6 +212,11 @@ struct If_Obj_t_
If_Cut_t CutBest; // the best cut selected
};
static inline If_Obj_t * If_Regular( If_Obj_t * p ) { return (If_Obj_t *)((unsigned long)(p) & ~01); }
static inline If_Obj_t * If_Not( If_Obj_t * p ) { return (If_Obj_t *)((unsigned long)(p) ^ 01); }
static inline If_Obj_t * If_NotCond( If_Obj_t * p, int c ) { return (If_Obj_t *)((unsigned long)(p) ^ (c)); }
static inline int If_IsComplement( If_Obj_t * p ) { return (int )(((unsigned long)p) & 01); }
static inline int If_ManCiNum( If_Man_t * p ) { return p->nObjs[IF_CI]; }
static inline int If_ManCoNum( If_Man_t * p ) { return p->nObjs[IF_CO]; }
static inline int If_ManAndNum( If_Man_t * p ) { return p->nObjs[IF_AND]; }
......@@ -334,10 +339,10 @@ extern If_Man_t * If_ManStart( If_Par_t * pPars );
extern void If_ManRestart( If_Man_t * p );
extern void If_ManStop( If_Man_t * p );
extern If_Obj_t * If_ManCreateCi( If_Man_t * p );
extern If_Obj_t * If_ManCreateCo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 );
extern If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_t * pFan1, int fCompl1 );
extern If_Obj_t * If_ManCreateXnor( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 );
extern If_Obj_t * If_ManCreateMnux( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1, If_Obj_t * pCtrl );
extern If_Obj_t * If_ManCreateCo( If_Man_t * p, If_Obj_t * pDriver );
extern If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 );
extern If_Obj_t * If_ManCreateXor( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 );
extern If_Obj_t * If_ManCreateMux( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1, If_Obj_t * pCtrl );
extern void If_ManCreateChoice( If_Man_t * p, If_Obj_t * pRepr );
extern void If_ManSetupCutTriv( If_Man_t * p, If_Cut_t * pCut, int ObjId );
extern void If_ManSetupCiCutSets( If_Man_t * p );
......
......@@ -175,13 +175,13 @@ If_Obj_t * If_ManCreateCi( If_Man_t * p )
SeeAlso []
***********************************************************************/
If_Obj_t * If_ManCreateCo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 )
If_Obj_t * If_ManCreateCo( If_Man_t * p, If_Obj_t * pDriver )
{
If_Obj_t * pObj;
pObj = If_ManSetupObj( p );
pObj->Type = IF_CO;
pObj->fCompl0 = fCompl0;
Vec_PtrPush( p->vCos, pObj );
pObj->Type = IF_CO;
pObj->fCompl0 = If_IsComplement(pDriver); pDriver = If_Regular(pDriver);
pObj->pFanin0 = pDriver; pDriver->nRefs++;
p->nObjs[IF_CO]++;
return pObj;
......@@ -198,17 +198,26 @@ If_Obj_t * If_ManCreateCo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 )
SeeAlso []
***********************************************************************/
If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_t * pFan1, int fCompl1 )
If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 )
{
If_Obj_t * pObj;
// perform constant propagation
if ( pFan0 == pFan1 )
return pFan0;
if ( pFan0 == If_Not(pFan1) )
return If_Not(p->pConst1);
if ( If_Regular(pFan0) == p->pConst1 )
return pFan0 == p->pConst1 ? pFan1 : If_Not(p->pConst1);
if ( If_Regular(pFan1) == p->pConst1 )
return pFan1 == p->pConst1 ? pFan0 : If_Not(p->pConst1);
// get memory for the new object
pObj = If_ManSetupObj( p );
pObj->Type = IF_AND;
pObj->fCompl0 = fCompl0;
pObj->fCompl1 = fCompl1;
pObj->fCompl0 = If_IsComplement(pFan0); pFan0 = If_Regular(pFan0);
pObj->fCompl1 = If_IsComplement(pFan1); pFan1 = If_Regular(pFan1);
pObj->pFanin0 = pFan0; pFan0->nRefs++; pFan0->nVisits++; pFan0->nVisitsCopy++;
pObj->pFanin1 = pFan1; pFan1->nRefs++; pFan1->nVisits++; pFan1->nVisitsCopy++;
pObj->fPhase = (fCompl0 ^ pFan0->fPhase) & (fCompl1 ^ pFan1->fPhase);
pObj->fPhase = (pObj->fCompl0 ^ pFan0->fPhase) & (pObj->fCompl1 ^ pFan1->fPhase);
pObj->Level = 1 + IF_MAX( pFan0->Level, pFan1->Level );
if ( p->nLevelMax < (int)pObj->Level )
p->nLevelMax = (int)pObj->Level;
......@@ -227,12 +236,12 @@ If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_
SeeAlso []
***********************************************************************/
If_Obj_t * If_ManCreateXnor( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 )
If_Obj_t * If_ManCreateXor( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 )
{
If_Obj_t * pRes1, * pRes2;
pRes1 = If_ManCreateAnd( p, pFan0, 0, pFan1, 1 );
pRes2 = If_ManCreateAnd( p, pFan0, 1, pFan1, 0 );
return If_ManCreateAnd( p, pRes1, 1, pRes2, 1 );
pRes1 = If_ManCreateAnd( p, If_Not(pFan0), pFan1 );
pRes2 = If_ManCreateAnd( p, pFan0, If_Not(pFan1) );
return If_Not( If_ManCreateAnd( p, If_Not(pRes1), If_Not(pRes2) ) );
}
/**Function*************************************************************
......@@ -246,12 +255,12 @@ If_Obj_t * If_ManCreateXnor( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 )
SeeAlso []
***********************************************************************/
If_Obj_t * If_ManCreateMnux( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1, If_Obj_t * pCtrl )
If_Obj_t * If_ManCreateMux( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1, If_Obj_t * pCtrl )
{
If_Obj_t * pRes1, * pRes2;
pRes1 = If_ManCreateAnd( p, pFan0, 0, pCtrl, 1 );
pRes2 = If_ManCreateAnd( p, pFan1, 0, pCtrl, 0 );
return If_ManCreateAnd( p, pRes1, 1, pRes2, 1 );
pRes1 = If_ManCreateAnd( p, pFan0, If_Not(pCtrl) );
pRes2 = If_ManCreateAnd( p, pFan1, pCtrl );
return If_Not( If_ManCreateAnd( p, If_Not(pRes1), If_Not(pRes2) ) );
}
/**Function*************************************************************
......
......@@ -159,6 +159,7 @@ static inline unsigned Kit_DsdLitSupport( Kit_DsdNtk_t * pNtk, int Lit )
#define KIT_MIN(a,b) (((a) < (b))? (a) : (b))
#define KIT_MAX(a,b) (((a) > (b))? (a) : (b))
#define KIT_INFINITY (100000000)
#ifndef ALLOC
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
......@@ -235,6 +236,10 @@ static inline int Kit_WordFindFirstBit( unsigned uWord )
return i;
return -1;
}
static inline int Kit_WordHasOneBit( unsigned uWord )
{
return (uWord & (uWord - 1)) == 0;
}
static inline int Kit_WordCountOnes( unsigned uWord )
{
uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
......@@ -250,6 +255,14 @@ static inline int Kit_TruthCountOnes( unsigned * pIn, int nVars )
Counter += Kit_WordCountOnes(pIn[w]);
return Counter;
}
static inline int Kit_TruthFindFirstBit( unsigned * pIn, int nVars )
{
int w;
for ( w = 0; w < Kit_TruthWordNum(nVars); w++ )
if ( pIn[w] )
return Kit_WordFindFirstBit(pIn[w]);
return -1;
}
static inline int Kit_TruthIsEqual( unsigned * pIn0, unsigned * pIn1, int nVars )
{
int w;
......@@ -433,7 +446,9 @@ extern DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nV
/*=== kitDsd.c ==========================================================*/
extern Kit_DsdNtk_t * Kit_DsdDeriveNtk( unsigned * pTruth, int nVars, int nLutSize );
extern unsigned * Kit_DsdTruthCompute( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk );
extern void Kit_DsdTruth( Kit_DsdNtk_t * pNtk, unsigned * pTruthRes );
extern void Kit_DsdPrint( FILE * pFile, Kit_DsdNtk_t * pNtk );
extern void Kit_DsdPrintExpanded( Kit_DsdNtk_t * pNtk );
extern Kit_DsdNtk_t * Kit_DsdDecompose( unsigned * pTruth, int nVars );
extern void Kit_DsdNtkFree( Kit_DsdNtk_t * pNtk );
extern int Kit_DsdNonDsdSizeMax( Kit_DsdNtk_t * pNtk );
......
/**CFile****************************************************************
FileName [lpk.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpk.h,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __LPK_H__
#define __LPK_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Lpk_Par_t_ Lpk_Par_t;
struct Lpk_Par_t_
{
// user-controlled parameters
int nLutsMax; // (N) the maximum number of LUTs in the structure
int nLutsOver; // (Q) the maximum number of LUTs not in the MFFC
int nVarsShared; // (S) the maximum number of shared variables (crossbars)
int nGrowthLevel; // (L) the maximum increase in the node level after resynthesis
int fSatur; // iterate till saturation
int fZeroCost; // accept zero-cost replacements
int fVerbose; // the verbosiness flag
int fVeryVerbose; // additional verbose info printout
// internal parameters
int nLutSize; // (K) the LUT size (determined by the input network)
int nVarsMax; // (V) the largest number of variables: V = N * (K-1) + 1
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== lpkCore.c ========================================================*/
extern int Lpk_Resynthesize( Abc_Ntk_t * pNtk, Lpk_Par_t * pPars );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [lpkCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkCore.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "lpkInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns 1 if at least one entry has changed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pTemp;
int i;
vNodes = Vec_VecEntry( p->vVisited, iNode );
if ( Vec_PtrSize(vNodes) == 0 )
return 1;
Vec_PtrForEachEntry( vNodes, pTemp, i )
{
// check if the node has changed
pTemp = Abc_NtkObj( p->pNtk, (int)pTemp );
if ( pTemp == NULL )
return 1;
// check if the number of fanouts has changed
// if ( Abc_ObjFanoutNum(pTemp) != (int)Vec_PtrEntry(vNodes, i+1) )
// return 1;
i++;
}
return 0;
}
/**Function*************************************************************
Synopsis [Performs resynthesis for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_ResynthesizeNode( Lpk_Man_t * p )
{
Kit_DsdNtk_t * pDsdNtk;
Lpk_Cut_t * pCut;
unsigned * pTruth;
void * pDsd = NULL;
int i, RetValue, clk;
Lpk_Cut_t * pCutMax;
// compute the cuts
clk = clock();
if ( !Lpk_NodeCuts( p ) )
{
p->timeCuts += clock() - clk;
return 0;
}
p->timeCuts += clock() - clk;
// find the max volume cut
pCutMax = NULL;
for ( i = 0; i < p->nEvals; i++ )
{
pCut = p->pCuts + p->pEvals[i];
if ( pCutMax == NULL || pCutMax->nNodes < pCut->nNodes )
pCutMax = pCut;
}
assert( pCutMax != NULL );
if ( p->pPars->fVeryVerbose )
printf( "Node %5d : Mffc size = %5d. Cuts = %5d.\n", p->pObj->Id, p->nMffc, p->nEvals );
// try the good cuts
p->nCutsTotal += p->nCuts;
p->nCutsUseful += p->nEvals;
for ( i = 0; i < p->nEvals; i++ )
{
// get the cut
pCut = p->pCuts + p->pEvals[i];
if ( pCut != pCutMax )
continue;
// compute the truth table
clk = clock();
pTruth = Lpk_CutTruth( p, pCut );
p->timeTruth += clock() - clk;
clk = clock();
pDsdNtk = Kit_DsdDeriveNtk( pTruth, pCut->nLeaves, p->pPars->nLutSize );
p->timeEval += clock() - clk;
if ( Kit_DsdNtkRoot(pDsdNtk)->nFans == 16 ) // skip 16-input non-DSD because ISOP will not work
{
Kit_DsdNtkFree( pDsdNtk );
continue;
}
if ( p->pPars->fVeryVerbose )
{
printf( " C%02d: L= %2d/%2d V= %2d/%d N= %d W= %4.2f ",
i, pCut->nLeaves, Extra_TruthSupportSize(pTruth, pCut->nLeaves), pCut->nNodes, pCut->nNodesDup, pCut->nLuts, pCut->Weight );
Kit_DsdPrint( stdout, pDsdNtk );
}
// update the network
clk = clock();
RetValue = Lpk_CutExplore( p, pCut, pDsdNtk );
Kit_DsdNtkFree( pDsdNtk );
p->timeMap += clock() - clk;
if ( RetValue )
break;
}
return 1;
}
/**Function*************************************************************
Synopsis [Performs resynthesis for one network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_Resynthesize( Abc_Ntk_t * pNtk, Lpk_Par_t * pPars )
{
ProgressBar * pProgress;
Lpk_Man_t * p;
Abc_Obj_t * pObj;
double Delta;
int i, Iter, nNodes, nNodesPrev, clk = clock();
assert( Abc_NtkIsLogic(pNtk) );
// get the number of inputs
pPars->nLutSize = Abc_NtkGetFaninMax( pNtk );
// adjust the number of crossbars based on LUT size
if ( pPars->nVarsShared > pPars->nLutSize - 2 )
pPars->nVarsShared = pPars->nLutSize - 2;
// get the max number of LUTs tried
pPars->nVarsMax = pPars->nLutsMax * (pPars->nLutSize - 1) + 1; // V = N * (K-1) + 1
while ( pPars->nVarsMax > 16 )
{
pPars->nLutsMax--;
pPars->nVarsMax = pPars->nLutsMax * (pPars->nLutSize - 1) + 1;
}
if ( pPars->fVerbose )
{
printf( "Resynthesis for %d %d-LUTs with %d non-MFFC LUTs, %d crossbars, and %d-input cuts.\n",
pPars->nLutsMax, pPars->nLutSize, pPars->nLutsOver, pPars->nVarsShared, pPars->nVarsMax );
}
// convert logic to AIGs
Abc_NtkToAig( pNtk );
// start the manager
p = Lpk_ManStart( pPars );
p->pNtk = pNtk;
p->nNodesTotal = Abc_NtkNodeNum(pNtk);
p->vLevels = Vec_VecStart( 3 * Abc_NtkLevel(pNtk) ); // computes levels of all nodes
if ( p->pPars->fSatur )
p->vVisited = Vec_VecStart( 0 );
// iterate over the network
nNodesPrev = p->nNodesTotal;
for ( Iter = 1; ; Iter++ )
{
// expand storage for changed nodes
if ( p->pPars->fSatur )
Vec_VecExpand( p->vVisited, Abc_NtkObjNumMax(pNtk) + 1 );
// consider all nodes
nNodes = Abc_NtkObjNumMax(pNtk);
if ( !pPars->fVeryVerbose )
pProgress = Extra_ProgressBarStart( stdout, nNodes );
Abc_NtkForEachNode( pNtk, pObj, i )
{
// skip all except the final node
// if ( !Abc_ObjIsCo(Abc_ObjFanout0(pObj)) )
// continue;
if ( i >= nNodes )
break;
if ( !pPars->fVeryVerbose )
Extra_ProgressBarUpdate( pProgress, i, NULL );
// skip the nodes that did not change
if ( p->pPars->fSatur && !Lpk_NodeHasChanged(p, pObj->Id) )
continue;
// resynthesize
p->pObj = pObj;
Lpk_ResynthesizeNode( p );
if ( p->nChanges == 3 )
break;
}
if ( !pPars->fVeryVerbose )
Extra_ProgressBarStop( pProgress );
// check the increase
Delta = 100.00 * (nNodesPrev - Abc_NtkNodeNum(pNtk)) / p->nNodesTotal;
if ( Delta < 0.05 )
break;
nNodesPrev = Abc_NtkNodeNum(pNtk);
if ( !p->pPars->fSatur )
break;
break;
}
if ( pPars->fVerbose )
{
printf( "N = %5d (%3d) Cut = %5d (%4d) Change = %5d Gain = %5d (%5.2f %%) Iter = %2d\n",
p->nNodesTotal, p->nNodesOver, p->nCutsTotal, p->nCutsUseful, p->nChanges, p->nGainTotal, 100.0 * p->nGainTotal / p->nNodesTotal, Iter );
printf( "Non_DSD blocks: " );
for ( i = 3; i <= pPars->nVarsMax; i++ )
if ( p->nBlocks[i] )
printf( "%d=%d ", i, p->nBlocks[i] );
printf( "\n" );
p->timeTotal = clock() - clk;
p->timeOther = p->timeTotal - p->timeCuts - p->timeTruth - p->timeEval - p->timeMap;
PRTP( "Cuts ", p->timeCuts, p->timeTotal );
PRTP( "Truth ", p->timeTruth, p->timeTotal );
PRTP( "Eval ", p->timeEval, p->timeTotal );
PRTP( "Map ", p->timeMap, p->timeTotal );
PRTP( "Other ", p->timeOther, p->timeTotal );
PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
}
Lpk_ManStop( p );
// check the resulting network
if ( !Abc_NtkCheck( pNtk ) )
{
printf( "Lpk_Resynthesize: The network check has failed.\n" );
return 0;
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [lpkInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis [Internal declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkInt.h,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __LPK_INT_H__
#define __LPK_INT_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "abc.h"
#include "kit.h"
#include "if.h"
#include "lpk.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
#define LPK_SIZE_MAX 24 // the largest size of the function
#define LPK_CUTS_MAX 512 // the largest number of cuts considered
typedef struct Lpk_Man_t_ Lpk_Man_t;
typedef struct Lpk_Cut_t_ Lpk_Cut_t;
struct Lpk_Cut_t_
{
unsigned nLeaves : 6; // (L) the number of leaves
unsigned nNodes : 6; // (M) the number of nodes
unsigned nNodesDup : 6; // (Q) nodes outside of MFFC
unsigned nLuts : 6; // (N) the number of LUTs to try
unsigned unused : 6; // unused
unsigned fHasDsd : 1; // set to 1 if the cut has structural DSD (and so cannot be used)
unsigned fMark : 1; // multipurpose mark
unsigned uSign[2]; // the signature
float Weight; // the weight of the cut: (M - Q)/N(V) (the larger the better)
int Gain; // the gain achieved using this cut
int pLeaves[LPK_SIZE_MAX]; // the leaves of the cut
int pNodes[LPK_SIZE_MAX]; // the nodes of the cut
};
struct Lpk_Man_t_
{
// parameters
Lpk_Par_t * pPars; // the set of parameters
// current representation
Abc_Ntk_t * pNtk; // the network
Abc_Obj_t * pObj; // the node to resynthesize
// cut representation
int nMffc; // the size of MFFC of the node
int nCuts; // the total number of cuts
int nCutsMax; // the largest possible number of cuts
int nEvals; // the number of good cuts
Lpk_Cut_t pCuts[LPK_CUTS_MAX]; // the storage for cuts
int pEvals[LPK_CUTS_MAX]; // the good cuts
// visited nodes
Vec_Vec_t * vVisited;
// mapping manager
If_Man_t * pIfMan;
Vec_Int_t * vCover;
Vec_Vec_t * vLevels;
// temporary variables
int fCofactoring; // working in the cofactoring mode
int fCalledOnce; // limits the depth of MUX cofactoring
int pRefs[LPK_SIZE_MAX]; // fanin reference counters
int pCands[LPK_SIZE_MAX]; // internal nodes pointing only to the leaves
// truth table representation
Vec_Ptr_t * vTtElems; // elementary truth tables
Vec_Ptr_t * vTtNodes; // storage for temporary truth tables of the nodes
// variable sets
Vec_Int_t * vSets[8];
// statistics
int nNodesTotal; // total number of nodes
int nNodesOver; // nodes with cuts over the limit
int nCutsTotal; // total number of cuts
int nCutsUseful; // useful cuts
int nGainTotal; // the gain in LUTs
int nChanges; // the number of changed nodes
// counter of non-DSD blocks
int nBlocks[17];
// rutime
int timeCuts;
int timeTruth;
int timeEval;
int timeMap;
int timeOther;
int timeTotal;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
#define Lpk_CutForEachLeaf( pNtk, pCut, pObj, i ) \
for ( i = 0; (i < (int)(pCut)->nLeaves) && (((pObj) = Abc_NtkObj(pNtk, (pCut)->pLeaves[i])), 1); i++ )
#define Lpk_CutForEachNode( pNtk, pCut, pObj, i ) \
for ( i = 0; (i < (int)(pCut)->nNodes) && (((pObj) = Abc_NtkObj(pNtk, (pCut)->pNodes[i])), 1); i++ )
#define Lpk_CutForEachNodeReverse( pNtk, pCut, pObj, i ) \
for ( i = (int)(pCut)->nNodes - 1; (i >= 0) && (((pObj) = Abc_NtkObj(pNtk, (pCut)->pNodes[i])), 1); i-- )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== lpkCut.c =========================================================*/
extern unsigned * Lpk_CutTruth( Lpk_Man_t * p, Lpk_Cut_t * pCut );
extern int Lpk_NodeCuts( Lpk_Man_t * p );
/*=== lpkMap.c =========================================================*/
extern Lpk_Man_t * Lpk_ManStart( Lpk_Par_t * pPars );
extern void Lpk_ManStop( Lpk_Man_t * p );
/*=== lpkMap.c =========================================================*/
extern int Lpk_CutExplore( Lpk_Man_t * p, Lpk_Cut_t * pCut, Kit_DsdNtk_t * pNtk );
extern If_Obj_t * Lpk_MapPrime( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves );
extern If_Obj_t * Lpk_MapTree_rec( Lpk_Man_t * p, Kit_DsdNtk_t * pNtk, If_Obj_t ** ppLeaves, int iLit, If_Obj_t * pResult );
/*=== lpkMulti.c =======================================================*/
extern If_Obj_t * Lpk_MapTreeMulti( Lpk_Man_t * p, unsigned * pTruth, int nLeaves, If_Obj_t ** ppLeaves );
/*=== lpkMux.c =========================================================*/
extern If_Obj_t * Lpk_MapTreeMux_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves );
extern If_Obj_t * Lpk_MapSuppRedDec_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves );
/*=== lpkSets.c =========================================================*/
extern unsigned Lpk_MapSuppRedDecSelect( Lpk_Man_t * p, unsigned * pTruth, int nVars, int * piVar, int * piVarReused );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [lpkMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkMan.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "lpkInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Lpk_Man_t * Lpk_ManStart( Lpk_Par_t * pPars )
{
Lpk_Man_t * p;
int i;
assert( pPars->nLutsMax <= 16 );
assert( pPars->nVarsMax > 0 );
p = ALLOC( Lpk_Man_t, 1 );
memset( p, 0, sizeof(Lpk_Man_t) );
p->pPars = pPars;
p->nCutsMax = LPK_CUTS_MAX;
p->vTtElems = Vec_PtrAllocTruthTables( pPars->nVarsMax );
p->vTtNodes = Vec_PtrAllocSimInfo( 256, Abc_TruthWordNum(pPars->nVarsMax) );
p->vCover = Vec_IntAlloc( 1 << 12 );
for ( i = 0; i < 8; i++ )
p->vSets[i] = Vec_IntAlloc(100);
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Lpk_ManStop( Lpk_Man_t * p )
{
int i;
for ( i = 0; i < 8; i++ )
Vec_IntFree(p->vSets[i]);
if ( p->pIfMan )
{
void * pPars = p->pIfMan->pPars;
If_ManStop( p->pIfMan );
free( pPars );
}
if ( p->vLevels )
Vec_VecFree( p->vLevels );
if ( p->vVisited )
Vec_VecFree( p->vVisited );
Vec_IntFree( p->vCover );
Vec_PtrFree( p->vTtElems );
Vec_PtrFree( p->vTtNodes );
free( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [lpkMux.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkMux.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "lpkInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Find the best cofactoring variable.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_MapTreeBestVar( Lpk_Man_t * p, unsigned * pTruth, int nVars )
{
// Kit_DsdNtk_t * ppNtks[2], * pTemp;
unsigned * pCof0 = Vec_PtrEntry( p->vTtNodes, 0 );
unsigned * pCof1 = Vec_PtrEntry( p->vTtNodes, 1 );
int i, iBestVar, nSuppSizeCur0, nSuppSizeCur1, nSuppSizeCur, nSuppSizeMin;
// int nPrimeSizeCur0, nPrimeSizeCur1, nPrimeSizeCur, nPrimeSizeMin;
// iterate through variables
iBestVar = -1;
nSuppSizeMin = ABC_INFINITY;
// nPrimeSizeMin = ABC_INFINITY;
for ( i = 0; i < nVars; i++ )
{
// cofactor the functiona and get support sizes
Kit_TruthCofactor0New( pCof0, pTruth, nVars, i );
Kit_TruthCofactor1New( pCof1, pTruth, nVars, i );
nSuppSizeCur0 = Kit_TruthSupportSize( pCof0, nVars );
nSuppSizeCur1 = Kit_TruthSupportSize( pCof1, nVars );
nSuppSizeCur = nSuppSizeCur0 + nSuppSizeCur1;
/*
// check the size of the largest prime components
ppNtks[0] = Kit_DsdDecompose( pCof0, nVars );
ppNtks[1] = Kit_DsdDecompose( pCof1, nVars );
// compute the largest non-decomp block
nPrimeSizeCur0 = Kit_DsdNonDsdSizeMax(ppNtks[0]);
nPrimeSizeCur1 = Kit_DsdNonDsdSizeMax(ppNtks[1]);
nPrimeSizeCur = KIT_MAX( nPrimeSizeCur0, nPrimeSizeCur1 );
printf( "Evaluating variable %c:\n", 'a'+i );
// Kit_DsdPrintExpanded( ppNtks[0] );
// Kit_DsdPrintExpanded( ppNtks[1] );
ppNtks[0] = Kit_DsdExpand( pTemp = ppNtks[0] );
Kit_DsdNtkFree( pTemp );
ppNtks[1] = Kit_DsdExpand( pTemp = ppNtks[1] );
Kit_DsdNtkFree( pTemp );
Kit_DsdPrint( stdout, ppNtks[0] );
Kit_DsdPrint( stdout, ppNtks[1] );
// Lpk_DsdEvalSets( p, ppNtks[0], ppNtks[1] );
// free the networks
Kit_DsdNtkFree( ppNtks[0] );
Kit_DsdNtkFree( ppNtks[1] );
*/
// compare this variable with other variables
if ( nSuppSizeMin > nSuppSizeCur ) //|| (nSuppSizeMin == nSuppSizeCur && nPrimeSizeMin > nPrimeSizeCur ) )
{
nSuppSizeMin = nSuppSizeCur;
// nPrimeSizeMin = nPrimeSizeCur;
iBestVar = i;
}
}
printf( "\n" );
assert( iBestVar != -1 );
return iBestVar;
}
/**Function*************************************************************
Synopsis [Maps the function by the best cofactoring.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
If_Obj_t * Lpk_MapTreeMux_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves )
{
If_Obj_t * pObj0, * pObj1;
Kit_DsdNtk_t * ppNtks[2];
unsigned * pCof0 = Vec_PtrEntry( p->vTtNodes, 0 );
unsigned * pCof1 = Vec_PtrEntry( p->vTtNodes, 1 );
int iBestVar;
assert( nVars > 3 );
p->fCalledOnce = 1;
// cofactor w.r.t. the best variable
iBestVar = Lpk_MapTreeBestVar( p, pTruth, nVars );
Kit_TruthCofactor0New( pCof0, pTruth, nVars, iBestVar );
Kit_TruthCofactor1New( pCof1, pTruth, nVars, iBestVar );
// decompose the functions
ppNtks[0] = Kit_DsdDecompose( pCof0, nVars );
ppNtks[1] = Kit_DsdDecompose( pCof1, nVars );
if ( p->pPars->fVeryVerbose )
{
printf( "Cofactoring w.r.t. var %c (%d -> %d+%d supp vars):\n",
'a'+iBestVar, nVars, Kit_TruthSupportSize(pCof0, nVars), Kit_TruthSupportSize(pCof1, nVars) );
Kit_DsdPrintExpanded( ppNtks[0] );
Kit_DsdPrintExpanded( ppNtks[1] );
}
// map the DSD structures
pObj0 = Lpk_MapTree_rec( p, ppNtks[0], ppLeaves, ppNtks[0]->Root, NULL );
pObj1 = Lpk_MapTree_rec( p, ppNtks[1], ppLeaves, ppNtks[1]->Root, NULL );
Kit_DsdNtkFree( ppNtks[0] );
Kit_DsdNtkFree( ppNtks[1] );
return If_ManCreateMux( p->pIfMan, pObj0, pObj1, ppLeaves[iBestVar] );
}
/**Function*************************************************************
Synopsis [Implements support-reducing decomposition.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
If_Obj_t * Lpk_MapSuppRedDec_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves )
{
Kit_DsdNtk_t * pNtkDec, * pNtkComp;
If_Obj_t * pObjNew;
unsigned * pCof0 = Vec_PtrEntry( p->vTtNodes, 0 );
unsigned * pCof1 = Vec_PtrEntry( p->vTtNodes, 1 );
unsigned * pDec0 = Vec_PtrEntry( p->vTtNodes, 2 );
unsigned * pDec1 = Vec_PtrEntry( p->vTtNodes, 3 );
unsigned * pDec = Vec_PtrEntry( p->vTtNodes, 4 );
unsigned * pCo00 = Vec_PtrEntry( p->vTtNodes, 5 );
unsigned * pCo01 = Vec_PtrEntry( p->vTtNodes, 6 );
unsigned * pCo10 = Vec_PtrEntry( p->vTtNodes, 7 );
unsigned * pCo11 = Vec_PtrEntry( p->vTtNodes, 8 );
unsigned * pCo0 = Vec_PtrEntry( p->vTtNodes, 9 );
unsigned * pCo1 = Vec_PtrEntry( p->vTtNodes, 10 );
unsigned * pCo = Vec_PtrEntry( p->vTtNodes, 11 );
int TrueMint0, TrueMint1;
int uSubsets, uSubset0, uSubset1, iVar, iVarReused, i;
// determine if supp-red decomposition exists
uSubsets = Lpk_MapSuppRedDecSelect( p, pTruth, nVars, &iVar, &iVarReused );
if ( uSubsets == 0 )
return NULL;
// get the bound sets
uSubset0 = uSubsets & 0xFFFF;
uSubset1 = uSubsets >> 16;
// get the cofactors
Kit_TruthCofactor0New( pCof0, pTruth, nVars, iVar );
Kit_TruthCofactor1New( pCof1, pTruth, nVars, iVar );
// find any true assignments of the cofactors
TrueMint0 = Kit_TruthFindFirstBit( pCof0, nVars );
TrueMint1 = Kit_TruthFindFirstBit( pCof1, nVars );
assert( TrueMint0 >= 0 && TrueMint1 >= 0 );
// cofactor the cofactors according to these minterms
Kit_TruthCopy( pDec0, pCof0, nVars );
Kit_TruthCopy( pDec1, pCof1, nVars );
for ( i = 0; i < nVars; i++ )
if ( !(uSubset0 & (1 << i)) )
{
if ( TrueMint0 & (1 << i) )
Kit_TruthCofactor1( pDec0, nVars, i );
else
Kit_TruthCofactor0( pDec0, nVars, i );
}
for ( i = 0; i < nVars; i++ )
if ( !(uSubset1 & (1 << i)) )
{
if ( TrueMint1 & (1 << i) )
Kit_TruthCofactor1( pDec1, nVars, i );
else
Kit_TruthCofactor0( pDec1, nVars, i );
}
// get the decomposed function
Kit_TruthMuxVar( pDec, pDec0, pDec1, nVars, iVar );
// derive the remainders
Kit_TruthAndPhase( pCo00, pCof0, pDec0, nVars, 0, 1 );
Kit_TruthAndPhase( pCo01, pCof0, pDec0, nVars, 0, 0 );
Kit_TruthAndPhase( pCo10, pCof1, pDec1, nVars, 0, 1 );
Kit_TruthAndPhase( pCo11, pCof1, pDec1, nVars, 0, 0 );
// quantify bound set variables
for ( i = 0; i < nVars; i++ )
if ( uSubset0 & (1 << i) )
{
Kit_TruthExist( pCo00, nVars, i );
Kit_TruthExist( pCo01, nVars, i );
}
for ( i = 0; i < nVars; i++ )
if ( uSubset1 & (1 << i) )
{
Kit_TruthExist( pCo10, nVars, i );
Kit_TruthExist( pCo11, nVars, i );
}
// derive the functions by composing them with the new variable (iVarReused)
Kit_TruthMuxVar( pCo0, pCo00, pCo01, nVars, iVarReused );
Kit_TruthMuxVar( pCo1, pCo10, pCo11, nVars, iVarReused );
// derive the composition function
Kit_TruthMuxVar( pCo , pCo0 , pCo1 , nVars, iVar );
// process the decomposed function
pNtkDec = Kit_DsdDecompose( pDec, nVars );
Kit_DsdPrint( stdout, pNtkDec );
ppLeaves[iVarReused] = Lpk_MapTree_rec( p, pNtkDec, ppLeaves, pNtkDec->Root, NULL );
Kit_DsdNtkFree( pNtkDec );
// process the composition function
pNtkComp = Kit_DsdDecompose( pCo, nVars );
Kit_DsdPrint( stdout, pNtkComp );
pObjNew = Lpk_MapTree_rec( p, pNtkComp, ppLeaves, pNtkComp->Root, NULL );
Kit_DsdNtkFree( pNtkComp );
return pObjNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [lpk_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpk_.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "lpkInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
SRC += src/aig/lpk/lpkCore.c \
src/aig/lpk/lpkCut.c \
src/aig/lpk/lpkMan.c \
src/aig/lpk/lpkMap.c \
src/aig/lpk/lpkMulti.c \
src/aig/lpk/lpkMux.c \
src/aig/lpk/lpkSets.c
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