mirror of https://github.com/YosysHQ/abc.git
Version abc60803
This commit is contained in:
parent
7e8e03206c
commit
103fa22e9c
8
abc.dsp
8
abc.dsp
|
|
@ -2114,6 +2114,10 @@ SOURCE=.\src\temp\ivy\ivyFanout.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyIsop.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2166,6 +2170,10 @@ SOURCE=.\src\temp\player\playerCore.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\player\playerFast.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\player\playerMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
6
abc.rc
6
abc.rc
|
|
@ -1,9 +1,9 @@
|
|||
# global parameters
|
||||
#set check # checks intermediate networks
|
||||
#set checkfio # prints warnings when fanins/fanouts are duplicated
|
||||
set checkread # checks new networks after reading from file
|
||||
set backup # saves backup networks retrived by "undo" and "recall"
|
||||
set savesteps 1 # sets the maximum number of backup networks to save
|
||||
#set checkread # checks new networks after reading from file
|
||||
#set backup # saves backup networks retrived by "undo" and "recall"
|
||||
#set savesteps 1 # sets the maximum number of backup networks to save
|
||||
|
||||
# program names for internal calls
|
||||
set dotwin dot.exe
|
||||
|
|
|
|||
|
|
@ -640,6 +640,7 @@ extern char * Abc_SopCreateMux( Extra_MmFlex_t * pMan );
|
|||
extern char * Abc_SopCreateInv( Extra_MmFlex_t * pMan );
|
||||
extern char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan );
|
||||
extern char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth );
|
||||
extern char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover );
|
||||
extern int Abc_SopGetCubeNum( char * pSop );
|
||||
extern int Abc_SopGetLitNum( char * pSop );
|
||||
extern int Abc_SopGetVarNum( char * pSop );
|
||||
|
|
|
|||
|
|
@ -357,6 +357,32 @@ int Abc_NodeMffsInside( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vIns
|
|||
return Count1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the internal nodes of the MFFC limited by cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects [Increments the trav ID and marks visited nodes.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_NodeMffsInsideCollect( Abc_Obj_t * pNode )
|
||||
{
|
||||
Vec_Ptr_t * vInside;
|
||||
int Count1, Count2;
|
||||
// dereference the node
|
||||
Count1 = Abc_NodeDeref_rec( pNode );
|
||||
// collect the nodes inside the MFFC
|
||||
vInside = Vec_PtrAlloc( 10 );
|
||||
Abc_NodeMffsConeSupp( pNode, vInside, NULL );
|
||||
// reference it back
|
||||
Count2 = Abc_NodeRef_rec( pNode );
|
||||
assert( Count1 == Count2 );
|
||||
return vInside;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -399,6 +399,44 @@ char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTru
|
|||
return pSop;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the cover from the ISOP computed from TT.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover )
|
||||
{
|
||||
char * pSop, * pCube;
|
||||
int i, k, Entry, Literal;
|
||||
assert( Vec_IntSize(vCover) > 0 );
|
||||
if ( Vec_IntSize(vCover) == 0 )
|
||||
return NULL;
|
||||
// start the cover
|
||||
pSop = Abc_SopStart( pMan, Vec_IntSize(vCover), nVars );
|
||||
// create cubes
|
||||
Vec_IntForEachEntry( vCover, Entry, i )
|
||||
{
|
||||
pCube = pSop + i * (nVars + 3);
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
{
|
||||
Literal = 3 & (Entry >> (k << 1));
|
||||
if ( Literal == 1 )
|
||||
pCube[k] = '1';
|
||||
else if ( Literal == 2 )
|
||||
pCube[k] = '0';
|
||||
else if ( Literal != 0 )
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
return pSop;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the number of cubes in the cover.]
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** arg
|
|||
static int Abc_CommandIStrash ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandICut ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandIRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandIRewriteSeq ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandIResyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -207,6 +208,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "New AIG", "istrash", Abc_CommandIStrash, 1 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "icut", Abc_CommandICut, 0 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "irw", Abc_CommandIRewrite, 1 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "irws", Abc_CommandIRewriteSeq, 1 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "iresyn", Abc_CommandIResyn, 1 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
|
||||
|
|
@ -4086,9 +4088,10 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pParams->fGlobal = 0; // compute global cuts
|
||||
pParams->fLocal = 0; // compute local cuts
|
||||
pParams->fFancy = 0; // compute something fancy
|
||||
pParams->fMap = 0; // compute mapping delay
|
||||
pParams->fVerbose = 0; // the verbosiness flag
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdxyglzvoh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdxyglzmvoh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -4138,6 +4141,9 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'z':
|
||||
pParams->fFancy ^= 1;
|
||||
break;
|
||||
case 'm':
|
||||
pParams->fMap ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
pParams->fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -4175,7 +4181,6 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( fOracle )
|
||||
pParams->fRecord = 1;
|
||||
pCutMan = Abc_NtkCuts( pNtk, pParams );
|
||||
Cut_ManPrintStats( pCutMan );
|
||||
if ( fOracle )
|
||||
pCutOracle = Cut_OracleStart( pCutMan );
|
||||
Cut_ManStop( pCutMan );
|
||||
|
|
@ -4187,7 +4192,7 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdxyzvh]\n" );
|
||||
fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdxyzmvh]\n" );
|
||||
fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" );
|
||||
fprintf( pErr, "\t-K num : max number of leaves (%d <= num <= %d) [default = %d]\n", CUT_SIZE_MIN, CUT_SIZE_MAX, pParams->nVarsMax );
|
||||
fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax );
|
||||
|
|
@ -4199,6 +4204,7 @@ usage:
|
|||
fprintf( pErr, "\t-g : toggle computing only global cuts [default = %s]\n", pParams->fGlobal? "yes": "no" );
|
||||
fprintf( pErr, "\t-l : toggle computing only local cuts [default = %s]\n", pParams->fLocal? "yes": "no" );
|
||||
fprintf( pErr, "\t-z : toggle fancy computations [default = %s]\n", pParams->fFancy? "yes": "no" );
|
||||
fprintf( pErr, "\t-m : toggle delay-oriented FPGA mapping [default = %s]\n", pParams->fMap? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -4293,7 +4299,6 @@ int Abc_CommandScut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
|
||||
pCutMan = Abc_NtkSeqCuts( pNtk, pParams );
|
||||
Cut_ManPrintStats( pCutMan );
|
||||
Cut_ManStop( pCutMan );
|
||||
return 0;
|
||||
|
||||
|
|
@ -4480,27 +4485,31 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int c;
|
||||
int nLutMax;
|
||||
int nPlaMax;
|
||||
int RankCost;
|
||||
int fFastMode;
|
||||
int fVerbose;
|
||||
// extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nPlaMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose );
|
||||
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose );
|
||||
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nLutMax = 8;
|
||||
nPlaMax = 128;
|
||||
fVerbose = 0;
|
||||
nLutMax = 8;
|
||||
nPlaMax = 128;
|
||||
RankCost = 96000;
|
||||
fFastMode = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "LPvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "LPRfvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'L':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||
fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nLutMax = atoi(argv[globalUtilOptind]);
|
||||
|
|
@ -4511,7 +4520,7 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'P':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||
fprintf( pErr, "Command line switch \"-P\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nPlaMax = atoi(argv[globalUtilOptind]);
|
||||
|
|
@ -4519,6 +4528,20 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nPlaMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'R':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
RankCost = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( RankCost < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'f':
|
||||
fFastMode ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -4548,7 +4571,7 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
// run the command
|
||||
// pNtkRes = Abc_NtkXyz( pNtk, nPlaMax, 1, 0, fUseInvs, fVerbose );
|
||||
pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, fVerbose );
|
||||
pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, RankCost, fFastMode, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
|
|
@ -4559,10 +4582,12 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: xyz [-L num] [-P num] [-vh]\n" );
|
||||
fprintf( pErr, "usage: xyz [-L num] [-P num] [-R num] [-fvh]\n" );
|
||||
fprintf( pErr, "\t specilized LUT/PLA decomposition\n" );
|
||||
fprintf( pErr, "\t-L num : maximum number of LUT inputs (2<=num<=8) [default = %d]\n", nLutMax );
|
||||
fprintf( pErr, "\t-P num : maximum number of PLA inputs/cubes (8<=num<=128) [default = %d]\n", nPlaMax );
|
||||
fprintf( pErr, "\t-R num : maximum are of one decomposition rank [default = %d]\n", RankCost );
|
||||
fprintf( pErr, "\t-f : toggle using fast LUT mapping mode [default = %s]\n", fFastMode? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -4744,7 +4769,7 @@ int Abc_CommandIStrash( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
|
|
@ -4886,7 +4911,7 @@ int Abc_CommandIRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
|
|
@ -4902,6 +4927,83 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandIRewriteSeq( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int c, fUpdateLevel, fUseZeroCost, fVerbose;
|
||||
extern Abc_Ntk_t * Abc_NtkIvyRewriteSeq( Abc_Ntk_t * pNtk, int fUseZeroCost, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
fUpdateLevel = 1;
|
||||
fUseZeroCost = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "lzvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'l':
|
||||
fUpdateLevel ^= 1;
|
||||
break;
|
||||
case 'z':
|
||||
fUseZeroCost ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Abc_NtkIsSeq(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Only works for non-sequential networks.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
pNtkRes = Abc_NtkIvyRewriteSeq( pNtk, fUseZeroCost, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: irws [-zvh]\n" );
|
||||
fprintf( pErr, "\t perform sequential AIG rewriting\n" );
|
||||
// fprintf( pErr, "\t-l : toggle preserving the number of levels [default = %s]\n", fUpdateLevel? "yes": "no" );
|
||||
fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeroCost? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -4959,7 +5061,7 @@ int Abc_CommandIResyn( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
|
|
@ -5915,11 +6017,12 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int c;
|
||||
int fRecovery;
|
||||
int fSwitching;
|
||||
int fLatchPaths;
|
||||
int fVerbose;
|
||||
int nLutSize;
|
||||
float DelayTarget;
|
||||
|
||||
extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
|
|
@ -5928,11 +6031,12 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
// set defaults
|
||||
fRecovery = 1;
|
||||
fSwitching = 0;
|
||||
fLatchPaths = 0;
|
||||
fVerbose = 0;
|
||||
DelayTarget =-1;
|
||||
nLutSize =-1;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "apvhDK" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "aplvhDK" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -5942,6 +6046,9 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'p':
|
||||
fSwitching ^= 1;
|
||||
break;
|
||||
case 'l':
|
||||
fLatchPaths ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -5989,7 +6096,13 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
// create the new LUT library
|
||||
if ( nLutSize >= 3 && nLutSize <= 6 )
|
||||
Fpga_SetSimpleLutLib( nLutSize );
|
||||
|
||||
/*
|
||||
else
|
||||
{
|
||||
fprintf( pErr, "Cannot perform FPGA mapping with LUT size %d.\n", nLutSize );
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
// strash and balance the network
|
||||
|
|
@ -6008,7 +6121,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, DelayTarget, fRecovery, fSwitching, fVerbose );
|
||||
pNtkRes = Abc_NtkFpga( pNtk, DelayTarget, fRecovery, fSwitching, fLatchPaths, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
Abc_NtkDelete( pNtk );
|
||||
|
|
@ -6020,7 +6133,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
else
|
||||
{
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkFpga( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose );
|
||||
pNtkRes = Abc_NtkFpga( pNtk, DelayTarget, fRecovery, fSwitching, fLatchPaths, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "FPGA mapping has failed.\n" );
|
||||
|
|
@ -6040,10 +6153,11 @@ usage:
|
|||
sprintf( LutSize, "library" );
|
||||
else
|
||||
sprintf( LutSize, "%d", nLutSize );
|
||||
fprintf( pErr, "usage: fpga [-D float] [-K num] [-apvh]\n" );
|
||||
fprintf( pErr, "usage: fpga [-D float] [-K num] [-aplvh]\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-l : optimizes latch paths for delay, other paths for area [default = %s]\n", fLatchPaths? "yes": "no" );
|
||||
fprintf( pErr, "\t-D float : sets the required time for the mapping [default = %s]\n", Buffer );
|
||||
fprintf( pErr, "\t-K num : the number of LUT inputs [default = %s]%s\n", LutSize, (nLutSize == -1 ? " (type \"print_lut\")" : "") );
|
||||
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
|
|||
extern int nTotal, nGood, nEqual;
|
||||
|
||||
static Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
|
||||
static int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -117,7 +118,9 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
|||
Extra_ProgressBarStop( pProgress );
|
||||
Vec_PtrFree( vNodes );
|
||||
Vec_IntFree( vChoices );
|
||||
PRT( "Total", clock() - clk );
|
||||
Cut_ManPrintStats( p );
|
||||
PRT( "TOTAL ", clock() - clk );
|
||||
printf( "Area = %d.\n", Abc_NtkComputeArea( pNtk, p ) );
|
||||
//Abc_NtkPrintCuts( p, pNtk, 0 );
|
||||
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
|
||||
|
||||
|
|
@ -279,13 +282,35 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
|||
pObj->fMarkC = 0;
|
||||
if ( pParams->fVerbose )
|
||||
{
|
||||
PRT( "Total", clock() - clk );
|
||||
Cut_ManPrintStats( p );
|
||||
PRT( "TOTAL ", clock() - clk );
|
||||
printf( "Converged after %d iterations.\n", nIters );
|
||||
}
|
||||
//Abc_NtkPrintCuts( p, pNtk, 1 );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int Counter, i;
|
||||
Counter = 0;
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
Counter += Cut_ManMappingArea_rec( p, Abc_ObjFaninId0(pObj) );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
|
@ -479,21 +504,51 @@ void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk )
|
||||
Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vAttrs;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
// Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj;//, * pTemp;
|
||||
int i;//, k;
|
||||
int nNodesTotal = 0, nMffcsTotal = 0;
|
||||
extern Vec_Ptr_t * Abc_NodeMffsInsideCollect( Abc_Obj_t * pNode );
|
||||
|
||||
vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
|
||||
// Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjIsNode(pObj) )
|
||||
nNodesTotal++;
|
||||
if ( Abc_ObjIsCo(pObj) && Abc_ObjIsNode(Abc_ObjFanin0(pObj)) )
|
||||
nMffcsTotal += Abc_NodeMffcSize( Abc_ObjFanin0(pObj) );
|
||||
// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) )
|
||||
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
|
||||
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
// if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
|
||||
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) )
|
||||
{
|
||||
int nMffc = Abc_NodeMffcSize(pObj);
|
||||
nMffcsTotal += Abc_NodeMffcSize(pObj);
|
||||
// printf( "%d ", nMffc );
|
||||
|
||||
if ( nMffc > 2 || Abc_ObjFanoutNum(pObj) > 8 )
|
||||
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
}
|
||||
}
|
||||
/*
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
if ( Vec_IntEntry( vAttrs, pObj->Id ) )
|
||||
{
|
||||
vNodes = Abc_NodeMffsInsideCollect( pObj );
|
||||
Vec_PtrForEachEntry( vNodes, pTemp, k )
|
||||
if ( pTemp != pObj )
|
||||
Vec_IntWriteEntry( vAttrs, pTemp->Id, 0 );
|
||||
Vec_PtrFree( vNodes );
|
||||
}
|
||||
}
|
||||
*/
|
||||
printf( "Total nodes = %d. Total MFFC nodes = %d.\n", nNodesTotal, nMffcsTotal );
|
||||
return vAttrs;
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +588,7 @@ int Abc_NtkSubDagSize_rec( Abc_Obj_t * pObj, Vec_Int_t * vAttrs )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
|
||||
Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vAttrs;
|
||||
Abc_Obj_t * pObj;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose );
|
||||
static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, 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,7 +44,7 @@ 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, float DelayTarget, int fRecovery, int fSwitching, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose )
|
||||
{
|
||||
int fShowSwitching = 1;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
|
|
@ -68,11 +68,13 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int
|
|||
}
|
||||
|
||||
// perform FPGA mapping
|
||||
pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fVerbose );
|
||||
pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fLatchPaths, fVerbose );
|
||||
if ( pSwitching ) Vec_IntFree( vSwitching );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
Fpga_ManSetSwitching( pMan, fSwitching );
|
||||
Fpga_ManSetLatchPaths( pMan, fLatchPaths );
|
||||
Fpga_ManSetLatchNum( pMan, Abc_NtkLatchNum(pNtk) );
|
||||
Fpga_ManSetDelayTarget( pMan, DelayTarget );
|
||||
if ( !Fpga_Mapping( pMan ) )
|
||||
{
|
||||
|
|
@ -113,13 +115,14 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose )
|
||||
Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose )
|
||||
{
|
||||
Fpga_Man_t * pMan;
|
||||
ProgressBar * pProgress;
|
||||
Fpga_Node_t * pNodeFpga;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pNode, * pFanin, * pPrev;
|
||||
float * pfArrivals;
|
||||
int i;
|
||||
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
|
@ -130,7 +133,13 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching,
|
|||
return NULL;
|
||||
Fpga_ManSetAreaRecovery( pMan, fRecovery );
|
||||
Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
|
||||
Fpga_ManSetInputArrivals( pMan, Abc_NtkGetCiArrivalFloats(pNtk) );
|
||||
pfArrivals = Abc_NtkGetCiArrivalFloats(pNtk);
|
||||
if ( fLatchPaths )
|
||||
{
|
||||
for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ )
|
||||
pfArrivals[i] = -FPGA_FLOAT_LARGE;
|
||||
}
|
||||
Fpga_ManSetInputArrivals( pMan, pfArrivals );
|
||||
|
||||
// create PIs and remember them in the old nodes
|
||||
Abc_NtkCleanCopy( pNtk );
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int f
|
|||
// perform fraiging
|
||||
pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes, fExdc );
|
||||
// add algebraic choices
|
||||
if ( pPars->fChoicing )
|
||||
Fraig_ManAddChoices( pMan, 0, 6 );
|
||||
// if ( pPars->fChoicing )
|
||||
// Fraig_ManAddChoices( pMan, 0, 6 );
|
||||
// prove the miter if asked to
|
||||
if ( pPars->fTryProve )
|
||||
Fraig_ManProveMiter( pMan );
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static inline Abc_Obj_t * Abc_EdgeToNode( Abc_Ntk_t * p, Abc_Edge_t Edge ) {
|
|||
static inline Abc_Obj_t * Abc_ObjFanin0Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin0(pObj)->TravId), Ivy_ObjFaninC0(pObj) ); }
|
||||
static inline Abc_Obj_t * Abc_ObjFanin1Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin1(pObj)->TravId), Ivy_ObjFaninC1(pObj) ); }
|
||||
|
||||
static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk );
|
||||
static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -67,7 +67,7 @@ static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq )
|
||||
Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc )
|
||||
{
|
||||
Ivy_Man_t * pMan;
|
||||
int fCleanup = 1;
|
||||
|
|
@ -101,7 +101,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq )
|
|||
if ( fSeq )
|
||||
{
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
int * pInit = Abc_NtkCollectLatchValues( pNtk );
|
||||
int * pInit = Abc_NtkCollectLatchValues( pNtk, fUseDc );
|
||||
Ivy_ManMakeSeq( pMan, nLatches, pInit );
|
||||
FREE( pInit );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
|
@ -160,7 +160,7 @@ Abc_Ntk_t * Abc_NtkIvyStrash( Abc_Ntk_t * pNtk )
|
|||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 1 );
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 1, 0 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 1 );
|
||||
|
|
@ -183,7 +183,7 @@ void Abc_NtkIvyCuts( Abc_Ntk_t * pNtk, int nInputs )
|
|||
{
|
||||
extern void Ivy_CutComputeAll( Ivy_Man_t * p, int nInputs );
|
||||
Ivy_Man_t * pMan;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 1 );
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 1, 0 );
|
||||
if ( pMan == NULL )
|
||||
return;
|
||||
Ivy_CutComputeAll( pMan, nInputs );
|
||||
|
|
@ -205,7 +205,7 @@ Abc_Ntk_t * Abc_NtkIvyRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeroC
|
|||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 0 );
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 0, 0 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
Ivy_ManRewritePre( pMan, fUpdateLevel, fUseZeroCost, fVerbose );
|
||||
|
|
@ -214,6 +214,30 @@ Abc_Ntk_t * Abc_NtkIvyRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeroC
|
|||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkIvyRewriteSeq( Abc_Ntk_t * pNtk, int fUseZeroCost, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 1, 1 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
Ivy_ManRewriteSeq( pMan, fUseZeroCost, fVerbose );
|
||||
pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 1 );
|
||||
Ivy_ManStop( pMan );
|
||||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
|
@ -229,7 +253,7 @@ Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose )
|
|||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan, * pTemp;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 0 );
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 0, 0 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
pMan = Ivy_ManResyn( pTemp = pMan, fUpdateLevel, fVerbose );
|
||||
|
|
@ -253,11 +277,11 @@ Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose )
|
|||
Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan, * pTemp;
|
||||
Ivy_Man_t * pMan;//, * pTemp;
|
||||
int fCleanup = 1;
|
||||
int nNodes;
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
int * pInit = Abc_NtkCollectLatchValues( pNtk );
|
||||
int * pInit = Abc_NtkCollectLatchValues( pNtk, 0 );
|
||||
|
||||
assert( !Abc_NtkIsNetlist(pNtk) );
|
||||
assert( !Abc_NtkIsSeq(pNtk) );
|
||||
|
|
@ -304,7 +328,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
// pMan = Ivy_ManResyn( pTemp = pMan, 1, 0 );
|
||||
// Ivy_ManStop( pTemp );
|
||||
|
||||
Ivy_ManTestCutsAll( pMan );
|
||||
// Ivy_ManTestCutsAll( pMan );
|
||||
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
|
|
@ -319,6 +343,10 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
|
||||
// Ivy_ManRequiredLevels( pMan );
|
||||
|
||||
Pla_ManFastLutMap( pMan, 8 );
|
||||
Ivy_ManStop( pMan );
|
||||
return NULL;
|
||||
/*
|
||||
// convert from the AIG manager
|
||||
pNtkAig = Abc_NtkFromAig( pNtk, pMan );
|
||||
// pNtkAig = Abc_NtkFromAigSeq( pNtk, pMan );
|
||||
|
|
@ -341,6 +369,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
|
||||
FREE( pInit );
|
||||
return pNtkAig;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -717,14 +746,14 @@ Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pRoot, cha
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk )
|
||||
int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs )
|
||||
{
|
||||
Abc_Obj_t * pLatch;
|
||||
int * pArray, i;
|
||||
pArray = ALLOC( int, Abc_NtkLatchNum(pNtk) );
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
{
|
||||
if ( Abc_LatchIsInitDc(pLatch) )
|
||||
if ( fUseDcs || Abc_LatchIsInitDc(pLatch) )
|
||||
pArray[i] = IVY_INIT_DC;
|
||||
else if ( Abc_LatchIsInit1(pLatch) )
|
||||
pArray[i] = IVY_INIT_1;
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) );
|
||||
else
|
||||
nFanouts = Abc_ObjFanoutNum(pNode);
|
||||
// nFanouts = Abc_NodeMffcSize(pNode);
|
||||
if ( nFanins > vFanins->nSize || nFanouts > vFanouts->nSize )
|
||||
{
|
||||
nOldSize = vFanins->nSize;
|
||||
|
|
|
|||
|
|
@ -394,6 +394,26 @@ void Abc_NtkCollectSupergate( Abc_Obj_t * pNode, int fStopAtMux, Vec_Ptr_t * vNo
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the factor of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkNodeFactor( Abc_Obj_t * pObj, int nLevelMax )
|
||||
{
|
||||
// nLevelMax = ((nLevelMax)/2)*3;
|
||||
assert( pObj->Level <= nLevelMax );
|
||||
// return (int)(100000000.0 * pow(0.999, nLevelMax - pObj->Level));
|
||||
return (int)(100000000.0 * (1 + 0.01 * pObj->Level));
|
||||
// return (int)(100000000.0 / ((nLevelMax)/2)*3 - pObj->Level);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets up the SAT solver.]
|
||||
|
|
@ -409,11 +429,13 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
|
|||
{
|
||||
Abc_Obj_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE;
|
||||
Vec_Ptr_t * vNodes, * vSuper;
|
||||
// Vec_Int_t * vLevels;
|
||||
Vec_Int_t * vVars, * vFanio;
|
||||
Vec_Vec_t * vCircuit;
|
||||
int i, k, fUseMuxes = 1;
|
||||
int clk1 = clock(), clk;
|
||||
int fOrderCiVarsFirst = 0;
|
||||
int nLevelsMax = Abc_AigGetLevelNum(pNtk);
|
||||
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
||||
|
|
@ -422,9 +444,9 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
|
|||
pNode->pCopy = NULL;
|
||||
|
||||
// start the data structures
|
||||
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver
|
||||
vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
|
||||
vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
|
||||
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver
|
||||
vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
|
||||
vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
|
||||
if ( fJFront )
|
||||
vCircuit = Vec_VecAlloc( 1000 );
|
||||
// vCircuit = Vec_VecStart( 184 );
|
||||
|
|
@ -565,7 +587,16 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
|
|||
// Asat_JManStop( pSat );
|
||||
// PRT( "Total", clock() - clk1 );
|
||||
}
|
||||
|
||||
/*
|
||||
// create factors
|
||||
vLevels = Vec_IntStart( Vec_PtrSize(vNodes) ); // the reverse levels of the nodes
|
||||
Abc_NtkForEachObj( pNtk, pNode, i )
|
||||
if ( pNode->fMarkA )
|
||||
Vec_IntWriteEntry( vLevels, (int)pNode->pCopy, Abc_NtkNodeFactor(pNode, nLevelsMax) );
|
||||
assert( Vec_PtrSize(vNodes) == Vec_IntSize(vLevels) );
|
||||
Asat_SolverSetFactors( pSat, Vec_IntReleaseArray(vLevels) );
|
||||
Vec_IntFree( vLevels );
|
||||
*/
|
||||
// delete
|
||||
Vec_IntFree( vVars );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
|
|
|||
|
|
@ -136,9 +136,11 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
|
|||
{
|
||||
extern void Rwt_ManGlobalStop();
|
||||
extern void undefine_cube_size();
|
||||
extern void Ivy_TruthManStop();
|
||||
// Abc_HManStop();
|
||||
undefine_cube_size();
|
||||
Rwt_ManGlobalStop();
|
||||
Ivy_TruthManStop();
|
||||
if ( p->pManDec ) Dec_ManStop( p->pManDec );
|
||||
if ( p->dd ) Extra_StopManager( p->dd );
|
||||
Abc_FrameDeleteAllNetworks( p );
|
||||
|
|
|
|||
|
|
@ -96,8 +96,9 @@ extern void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNode
|
|||
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_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget );
|
||||
extern void Fpga_ManSetLatchPaths( Fpga_Man_t * p, int fLatchPaths );
|
||||
extern void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches );
|
||||
extern void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget );
|
||||
extern void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName );
|
||||
|
||||
extern int Fpga_LibReadLutMax( Fpga_LutLib_t * pLib );
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ int Fpga_MappingPostProcess( Fpga_Man_t * p )
|
|||
float aAreaTotalCur, aAreaTotalCur2;
|
||||
int Iter, clk;
|
||||
|
||||
if ( p->fVerbose )
|
||||
printf( "Best clock period = %5.2f\n", Fpga_TimeComputeArrivalMax(p) );
|
||||
|
||||
// compute area, set references, and collect nodes used in the mapping
|
||||
Iter = 1;
|
||||
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
|
||||
|
|
|
|||
|
|
@ -66,8 +66,9 @@ void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes ) { p
|
|||
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_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget; }
|
||||
void Fpga_ManSetLatchPaths( Fpga_Man_t * p, int fLatchPaths ) { p->fLatchPaths = fLatchPaths; }
|
||||
void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ) { p->nLatches = nLatches; }
|
||||
void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget; }
|
||||
void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ) { p->pFileName = pFileName; }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ struct Fpga_CutTableStrutct_t
|
|||
};
|
||||
|
||||
// the largest number of cuts considered
|
||||
#define FPGA_CUTS_MAX_COMPUTE 5000
|
||||
#define FPGA_CUTS_MAX_COMPUTE 500
|
||||
// the largest number of cuts used
|
||||
#define FPGA_CUTS_MAX_USE 2000
|
||||
#define FPGA_CUTS_MAX_USE 200
|
||||
|
||||
// primes used to compute the hash key
|
||||
static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 };
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ struct Fpga_ManStruct_t_
|
|||
int fAreaRecovery; // the flag to use area flow as the first parameter
|
||||
int fVerbose; // the verbosiness flag
|
||||
int fSwitching; // minimize the switching activity (instead of area)
|
||||
int fLatchPaths; // optimize latch paths for delay, other paths for area
|
||||
int nTravIds; // the counter of traversal IDs
|
||||
float DelayTarget; // the target required times
|
||||
|
||||
|
|
|
|||
|
|
@ -87,13 +87,34 @@ float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p )
|
|||
{
|
||||
float fRequired;
|
||||
int i;
|
||||
if ( p->fLatchPaths && p->nLatches == 0 )
|
||||
{
|
||||
printf( "Delay optimization of latch path is not performed because there is no latches.\n" );
|
||||
p->fLatchPaths = 0;
|
||||
}
|
||||
// get the critical PO arrival time
|
||||
fRequired = -FPGA_FLOAT_LARGE;
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
if ( p->fLatchPaths )
|
||||
{
|
||||
if ( Fpga_NodeIsConst(p->pOutputs[i]) )
|
||||
continue;
|
||||
fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
||||
for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ )
|
||||
{
|
||||
if ( Fpga_NodeIsConst(p->pOutputs[i]) )
|
||||
continue;
|
||||
fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
||||
// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
||||
}
|
||||
// printf( "Required latches = %5.1f\n", fRequired );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
{
|
||||
if ( Fpga_NodeIsConst(p->pOutputs[i]) )
|
||||
continue;
|
||||
fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
||||
// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
||||
}
|
||||
// printf( "Required outputs = %5.1f\n", fRequired );
|
||||
}
|
||||
return fRequired;
|
||||
}
|
||||
|
|
@ -148,10 +169,23 @@ void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired )
|
|||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
p->vAnds->pArray[i]->tRequired = FPGA_FLOAT_LARGE;
|
||||
// set the required times for the POs
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
Fpga_Regular(p->pOutputs[i])->tRequired = fRequired;
|
||||
if ( p->fLatchPaths )
|
||||
for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ )
|
||||
Fpga_Regular(p->pOutputs[i])->tRequired = fRequired;
|
||||
else
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
Fpga_Regular(p->pOutputs[i])->tRequired = fRequired;
|
||||
// collect nodes reachable from POs in the DFS order through the best cuts
|
||||
Fpga_TimePropagateRequired( p, p->vMapping );
|
||||
/*
|
||||
{
|
||||
int Counter = 0;
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
if ( p->vAnds->pArray[i]->tRequired > FPGA_FLOAT_LARGE - 100 )
|
||||
Counter++;
|
||||
printf( "The number of nodes with large required times = %d.\n", Counter );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -662,7 +662,7 @@ void Extra_TruthMux( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nV
|
|||
for ( i = 0; i < Step; i++ )
|
||||
{
|
||||
pOut[i] = pCof0[i];
|
||||
pOut[Step+i] = pCof1[i];
|
||||
pOut[Step+i] = pCof1[Step+i];
|
||||
}
|
||||
pOut += 2*Step;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ Nm_Man_t * Nm_ManCreate( int nSize )
|
|||
p = ALLOC( Nm_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Nm_Man_t) );
|
||||
// set the parameters
|
||||
p->nSizeFactor = 3; // determined how much larger the table should be compared to data in it
|
||||
p->nGrowthFactor = 3; // determined how much the table grows after resizing
|
||||
p->nSizeFactor = 4; // determined how much larger the table should be compared to data in it
|
||||
p->nGrowthFactor = 4; // determined how much the table grows after resizing
|
||||
// allocate and clean the bins
|
||||
p->nBins = Cudd_PrimeNm(p->nSizeFactor*nSize);
|
||||
p->pBinsI2N = ALLOC( Nm_Entry_t *, p->nBins );
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static unsigned Nm_HashString( char * pName, int TableSize )
|
|||
};
|
||||
unsigned i, Key = 0;
|
||||
for ( i = 0; pName[i] != '\0'; i++ )
|
||||
Key ^= s_Primes[i%10]*pName[i]*pName[i];
|
||||
Key ^= s_Primes[i%10]*pName[i]*pName[i]*pName[i];
|
||||
return Key % TableSize;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -525,10 +525,18 @@ static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry )
|
|||
static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
// delete assuming that it is closer to the end
|
||||
for ( i = p->nSize - 1; i >= 0; i-- )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
assert( i >= 0 );
|
||||
/*
|
||||
// delete assuming that it is closer to the beginning
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
assert( i < p->nSize );
|
||||
*/
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
|
|
|
|||
|
|
@ -1,491 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abcCut.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Interface to cut computation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abcCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
#include "cut.h"
|
||||
#include "seqInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq );
|
||||
static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
|
||||
|
||||
|
||||
extern int nTotal, nGood, nEqual;
|
||||
|
||||
// temporary
|
||||
//Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) { return NULL; }
|
||||
Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
|
||||
int i;
|
||||
Abc_Obj_t * pObj;
|
||||
|
||||
// Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) )
|
||||
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
|
||||
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
}
|
||||
return vAttrs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Cut_Man_t * p;
|
||||
Abc_Obj_t * pObj, * pNode;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Vec_Int_t * vChoices;
|
||||
int i;
|
||||
int clk = clock();
|
||||
|
||||
extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
|
||||
|
||||
nTotal = nGood = nEqual = 0;
|
||||
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
// start the manager
|
||||
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||
p = Cut_ManStart( pParams );
|
||||
// compute node attributes if local or global cuts are requested
|
||||
if ( pParams->fGlobal || pParams->fLocal )
|
||||
{
|
||||
extern Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
|
||||
Cut_ManSetNodeAttrs( p, Abc_NtkGetNodeAttributes(pNtk) );
|
||||
}
|
||||
// prepare for cut dropping
|
||||
if ( pParams->fDrop )
|
||||
Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
|
||||
// set cuts for PIs
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||
Cut_NodeSetTriv( p, pObj->Id );
|
||||
// compute cuts for internal nodes
|
||||
vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
|
||||
vChoices = Vec_IntAlloc( 100 );
|
||||
pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
// when we reached a CO, it is time to deallocate the cuts
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
{
|
||||
if ( pParams->fDrop )
|
||||
Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
|
||||
continue;
|
||||
}
|
||||
// skip constant node, it has no cuts
|
||||
if ( Abc_NodeIsConst(pObj) )
|
||||
continue;
|
||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||
// compute the cuts to the internal node
|
||||
Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
|
||||
// consider dropping the fanins cuts
|
||||
if ( pParams->fDrop )
|
||||
{
|
||||
Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
|
||||
Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
|
||||
}
|
||||
// add cuts due to choices
|
||||
if ( Abc_NodeIsAigChoice(pObj) )
|
||||
{
|
||||
Vec_IntClear( vChoices );
|
||||
for ( pNode = pObj; pNode; pNode = pNode->pData )
|
||||
Vec_IntPush( vChoices, pNode->Id );
|
||||
Cut_NodeUnionCuts( p, vChoices );
|
||||
}
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
Vec_PtrFree( vNodes );
|
||||
Vec_IntFree( vChoices );
|
||||
PRT( "Total", clock() - clk );
|
||||
//Abc_NtkPrintCuts( p, pNtk, 0 );
|
||||
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
|
||||
|
||||
// temporary printout of stats
|
||||
if ( nTotal )
|
||||
printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cut computation using the oracle.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
Vec_Ptr_t * vNodes;
|
||||
int i, clk = clock();
|
||||
int fDrop = Cut_OracleReadDrop(p);
|
||||
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
||||
// prepare cut droppping
|
||||
if ( fDrop )
|
||||
Cut_OracleSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
|
||||
|
||||
// set cuts for PIs
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||
Cut_OracleNodeSetTriv( p, pObj->Id );
|
||||
|
||||
// compute cuts for internal nodes
|
||||
vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
// when we reached a CO, it is time to deallocate the cuts
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
{
|
||||
if ( fDrop )
|
||||
Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
|
||||
continue;
|
||||
}
|
||||
// skip constant node, it has no cuts
|
||||
if ( Abc_NodeIsConst(pObj) )
|
||||
continue;
|
||||
// compute the cuts to the internal node
|
||||
Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
||||
// consider dropping the fanins cuts
|
||||
if ( fDrop )
|
||||
{
|
||||
Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
|
||||
Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
|
||||
}
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
//PRT( "Total", clock() - clk );
|
||||
//Abc_NtkPrintCuts_( p, pNtk, 0 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
||||
{
|
||||
Cut_Man_t * p;
|
||||
Abc_Obj_t * pObj, * pNode;
|
||||
int i, nIters, fStatus;
|
||||
Vec_Int_t * vChoices;
|
||||
int clk = clock();
|
||||
|
||||
assert( Abc_NtkIsSeq(pNtk) );
|
||||
assert( pParams->fSeq );
|
||||
// assert( Abc_NtkIsDfsOrdered(pNtk) );
|
||||
|
||||
// start the manager
|
||||
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||
pParams->nCutSet = Abc_NtkCutSetNodeNum( pNtk );
|
||||
p = Cut_ManStart( pParams );
|
||||
|
||||
// set cuts for the constant node and the PIs
|
||||
pObj = Abc_NtkConst1(pNtk);
|
||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||
Cut_NodeSetTriv( p, pObj->Id );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
{
|
||||
//printf( "Setting trivial cut %d.\n", pObj->Id );
|
||||
Cut_NodeSetTriv( p, pObj->Id );
|
||||
}
|
||||
// label the cutset nodes and set their number in the array
|
||||
// assign the elementary cuts to the cutset nodes
|
||||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
{
|
||||
assert( pObj->fMarkC == 0 );
|
||||
pObj->fMarkC = 1;
|
||||
pObj->pCopy = (Abc_Obj_t *)i;
|
||||
Cut_NodeSetTriv( p, pObj->Id );
|
||||
//printf( "Setting trivial cut %d.\n", pObj->Id );
|
||||
}
|
||||
|
||||
// process the nodes
|
||||
vChoices = Vec_IntAlloc( 100 );
|
||||
for ( nIters = 0; nIters < 10; nIters++ )
|
||||
{
|
||||
//printf( "ITERATION %d:\n", nIters );
|
||||
// compute the cuts for the internal nodes
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
{
|
||||
Abc_NodeGetCutsSeq( p, pObj, nIters==0 );
|
||||
// add cuts due to choices
|
||||
if ( Abc_NodeIsAigChoice(pObj) )
|
||||
{
|
||||
Vec_IntClear( vChoices );
|
||||
for ( pNode = pObj; pNode; pNode = pNode->pData )
|
||||
Vec_IntPush( vChoices, pNode->Id );
|
||||
Cut_NodeUnionCutsSeq( p, vChoices, (pObj->fMarkC ? (int)pObj->pCopy : -1), nIters==0 );
|
||||
}
|
||||
}
|
||||
// merge the new cuts with the old cuts
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Cut_NodeNewMergeWithOld( p, pObj->Id );
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
Cut_NodeNewMergeWithOld( p, pObj->Id );
|
||||
// for the cutset, transfer temp cuts to new cuts
|
||||
fStatus = 0;
|
||||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
fStatus |= Cut_NodeTempTransferToNew( p, pObj->Id, i );
|
||||
if ( fStatus == 0 )
|
||||
break;
|
||||
}
|
||||
Vec_IntFree( vChoices );
|
||||
|
||||
// if the status is not finished, transfer new to old for the cutset
|
||||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
Cut_NodeNewMergeWithOld( p, pObj->Id );
|
||||
|
||||
// transfer the old cuts to the new positions
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
Cut_NodeOldTransferToNew( p, pObj->Id );
|
||||
|
||||
// unlabel the cutset nodes
|
||||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
pObj->fMarkC = 0;
|
||||
if ( pParams->fVerbose )
|
||||
{
|
||||
PRT( "Total", clock() - clk );
|
||||
printf( "Converged after %d iterations.\n", nIters );
|
||||
}
|
||||
//Abc_NtkPrintCuts( p, pNtk, 1 );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
|
||||
{
|
||||
void * pList;
|
||||
if ( pList = Abc_NodeReadCuts( p, pObj ) )
|
||||
return pList;
|
||||
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree );
|
||||
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree );
|
||||
return Abc_NodeGetCuts( p, pObj, fDag, fTree );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int fDagNode, fTriv, TreeCode = 0;
|
||||
// assert( Abc_NtkIsStrash(pObj->pNtk) );
|
||||
assert( Abc_ObjFaninNum(pObj) == 2 );
|
||||
|
||||
|
||||
// check if the node is a DAG node
|
||||
fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj));
|
||||
// increment the counter of DAG nodes
|
||||
if ( fDagNode ) Cut_ManIncrementDagNodes( p );
|
||||
// add the trivial cut if the node is a DAG node, or if we compute all cuts
|
||||
fTriv = fDagNode || !fDag;
|
||||
// check if fanins are DAG nodes
|
||||
if ( fTree )
|
||||
{
|
||||
pFanin = Abc_ObjFanin0(pObj);
|
||||
TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin));
|
||||
pFanin = Abc_ObjFanin1(pObj);
|
||||
TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1);
|
||||
}
|
||||
|
||||
|
||||
// changes due to the global/local cut computation
|
||||
{
|
||||
Cut_Params_t * pParams = Cut_ManReadParams(p);
|
||||
if ( pParams->fLocal )
|
||||
{
|
||||
Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs(p);
|
||||
fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id );
|
||||
if ( fDagNode ) Cut_ManIncrementDagNodes( p );
|
||||
// fTriv = fDagNode || !pParams->fGlobal;
|
||||
fTriv = !Vec_IntEntry( vNodeAttrs, pObj->Id );
|
||||
TreeCode = 0;
|
||||
pFanin = Abc_ObjFanin0(pObj);
|
||||
TreeCode |= Vec_IntEntry( vNodeAttrs, pFanin->Id );
|
||||
pFanin = Abc_ObjFanin1(pObj);
|
||||
TreeCode |= (Vec_IntEntry( vNodeAttrs, pFanin->Id ) << 1);
|
||||
}
|
||||
}
|
||||
return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv )
|
||||
{
|
||||
int CutSetNum;
|
||||
assert( Abc_NtkIsSeq(pObj->pNtk) );
|
||||
assert( Abc_ObjFaninNum(pObj) == 2 );
|
||||
fTriv = pObj->fMarkC ? 0 : fTriv;
|
||||
CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1;
|
||||
Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Seq_ObjFaninL0(pObj), Seq_ObjFaninL1(pObj), fTriv, CutSetNum );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
return Cut_NodeReadCutsNew( p, pObj->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Cut_NodeFreeCuts( p, pObj->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq )
|
||||
{
|
||||
Cut_Man_t * pMan = p;
|
||||
Cut_Cut_t * pList;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
printf( "Cuts of the network:\n" );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
pList = Abc_NodeReadCuts( p, pObj );
|
||||
printf( "Node %s:\n", Abc_ObjName(pObj) );
|
||||
Cut_CutPrintList( pList, fSeq );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq )
|
||||
{
|
||||
Cut_Man_t * pMan = p;
|
||||
Cut_Cut_t * pList;
|
||||
Abc_Obj_t * pObj;
|
||||
pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 );
|
||||
pList = Abc_NodeReadCuts( p, pObj );
|
||||
printf( "Node %s:\n", Abc_ObjName(pObj) );
|
||||
Cut_CutPrintList( pList, fSeq );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -65,6 +65,7 @@ struct Cut_ParamsStruct_t_
|
|||
int fLocal; // compute only local cuts
|
||||
int fRecord; // record the cut computation flow
|
||||
int fFancy; // perform fancy computations
|
||||
int fMap; // computes delay of FPGA mapping with cuts
|
||||
int fVerbose; // the verbosiness flag
|
||||
};
|
||||
|
||||
|
|
@ -129,6 +130,7 @@ extern void Cut_ManIncrementDagNodes( Cut_Man_t * p );
|
|||
extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode );
|
||||
extern Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes );
|
||||
extern Cut_Cut_t * Cut_NodeUnionCutsSeq( Cut_Man_t * p, Vec_Int_t * vNodes, int CutSetNum, int fFirst );
|
||||
extern int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node );
|
||||
/*=== cutSeq.c ==========================================================*/
|
||||
extern void Cut_NodeComputeCutsSeq( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int nLat0, int nLat1, int fTriv, int CutSetNum );
|
||||
extern void Cut_NodeNewMergeWithOld( Cut_Man_t * p, int Node );
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@ struct Cut_ManStruct_t_
|
|||
Vec_Int_t * vNodeCuts; // the number of cuts for each node
|
||||
Vec_Int_t * vNodeStarts; // the number of the starting cut of each node
|
||||
Vec_Int_t * vCutPairs; // the pairs of parent cuts for each cut
|
||||
// minimum delay mapping with the given cuts
|
||||
Vec_Ptr_t * vCutsMax;
|
||||
Vec_Int_t * vDelays;
|
||||
Vec_Int_t * vDelays2;
|
||||
int nDelayMin;
|
||||
// statistics
|
||||
int nCutsCur;
|
||||
int nCutsAlloc;
|
||||
|
|
@ -88,6 +93,7 @@ struct Cut_ManStruct_t_
|
|||
int timeTruth;
|
||||
int timeFilter;
|
||||
int timeHash;
|
||||
int timeMap;
|
||||
};
|
||||
|
||||
// iterator through all the cuts of the list
|
||||
|
|
|
|||
|
|
@ -95,6 +95,13 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams )
|
|||
p->vNodeStarts = Vec_IntStart( pParams->nIdsMax );
|
||||
p->vCutPairs = Vec_IntAlloc( 0 );
|
||||
}
|
||||
// allocate storage for delays
|
||||
if ( pParams->fMap && !p->pParams->fSeq )
|
||||
{
|
||||
p->vDelays = Vec_IntStart( pParams->nIdsMax );
|
||||
p->vDelays2 = Vec_IntStart( pParams->nIdsMax );
|
||||
p->vCutsMax = Vec_PtrStart( pParams->nIdsMax );
|
||||
}
|
||||
// memory for cuts
|
||||
p->pMmCuts = Extra_MmFixedStart( p->EntrySize );
|
||||
p->vTemp = Vec_PtrAlloc( 100 );
|
||||
|
|
@ -130,6 +137,9 @@ void Cut_ManStop( Cut_Man_t * p )
|
|||
if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts );
|
||||
if ( p->vTemp ) Vec_PtrFree( p->vTemp );
|
||||
|
||||
if ( p->vCutsMax ) Vec_PtrFree( p->vCutsMax );
|
||||
if ( p->vDelays ) Vec_IntFree( p->vDelays );
|
||||
if ( p->vDelays2 ) Vec_IntFree( p->vDelays2 );
|
||||
if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts );
|
||||
if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts );
|
||||
if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs );
|
||||
|
|
@ -168,13 +178,20 @@ void Cut_ManPrintStats( Cut_Man_t * p )
|
|||
printf( "The cut size = %8d bytes.\n", p->EntrySize );
|
||||
printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) );
|
||||
printf( "Total nodes = %8d.\n", p->nNodes );
|
||||
if ( p->pParams->fDag || p->pParams->fTree )
|
||||
{
|
||||
printf( "DAG nodes = %8d.\n", p->nNodesDag );
|
||||
printf( "Tree nodes = %8d.\n", p->nNodes - p->nNodesDag );
|
||||
}
|
||||
printf( "Nodes w/o cuts = %8d.\n", p->nNodesNoCuts );
|
||||
if ( p->pParams->fMap && !p->pParams->fSeq )
|
||||
printf( "Mapping delay = %8d.\n", p->nDelayMin );
|
||||
|
||||
PRT( "Merge ", p->timeMerge );
|
||||
PRT( "Union ", p->timeUnion );
|
||||
PRT( "Filter", p->timeFilter );
|
||||
PRT( "Truth ", p->timeTruth );
|
||||
PRT( "Map ", p->timeMap );
|
||||
// printf( "Nodes = %d. Multi = %d. Cuts = %d. Multi = %d.\n",
|
||||
// p->nNodes, p->nNodesMulti, p->nCutsCur-p->nCutsTriv, p->nCutsMulti );
|
||||
// printf( "Count0 = %d. Count1 = %d. Count2 = %d.\n\n", p->Count0, p->Count1, p->Count2 );
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 );
|
||||
static int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -396,15 +399,157 @@ p->timeMerge += clock() - clk;
|
|||
// set the list at the node
|
||||
Vec_PtrFillExtra( p->vCutsNew, Node + 1, NULL );
|
||||
assert( Cut_NodeReadCutsNew(p, Node) == NULL );
|
||||
|
||||
/////
|
||||
pList->pNext = NULL;
|
||||
/////
|
||||
|
||||
Cut_NodeWriteCutsNew( p, Node, pList );
|
||||
// filter the cuts
|
||||
//clk = clock();
|
||||
// if ( p->pParams->fFilter )
|
||||
// Cut_CutFilter( p, pList0 );
|
||||
//p->timeFilter += clock() - clk;
|
||||
// perform mapping of this node with these cuts
|
||||
clk = clock();
|
||||
if ( p->pParams->fMap && !p->pParams->fSeq )
|
||||
{
|
||||
// int Delay1, Delay2;
|
||||
// Delay1 = Cut_NodeMapping( p, pList, Node, Node0, Node1 );
|
||||
// Delay2 = Cut_NodeMapping2( p, pList, Node, Node0, Node1 );
|
||||
// assert( Delay1 >= Delay2 );
|
||||
Cut_NodeMapping( p, pList, Node, Node0, Node1 );
|
||||
}
|
||||
p->timeMap += clock() - clk;
|
||||
return pList;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns optimum delay mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 )
|
||||
{
|
||||
Cut_Cut_t * pCut;
|
||||
int DelayMin, DelayCur, i;
|
||||
if ( pCuts == NULL )
|
||||
p->nDelayMin = -1;
|
||||
if ( p->nDelayMin == -1 )
|
||||
return -1;
|
||||
DelayMin = 1000000;
|
||||
Cut_ListForEachCut( pCuts, pCut )
|
||||
{
|
||||
if ( pCut->nLeaves == 1 )
|
||||
continue;
|
||||
DelayCur = 0;
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
if ( DelayCur < Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) )
|
||||
DelayCur = Vec_IntEntry(p->vDelays, pCut->pLeaves[i]);
|
||||
if ( DelayMin > DelayCur )
|
||||
DelayMin = DelayCur;
|
||||
}
|
||||
if ( DelayMin == 1000000 )
|
||||
{
|
||||
p->nDelayMin = -1;
|
||||
return -1;
|
||||
}
|
||||
DelayMin++;
|
||||
Vec_IntWriteEntry( p->vDelays, Node, DelayMin );
|
||||
if ( p->nDelayMin < DelayMin )
|
||||
p->nDelayMin = DelayMin;
|
||||
return DelayMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns optimum delay mapping using the largest cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 )
|
||||
{
|
||||
Cut_Cut_t * pCut0, * pCut1, * pCut;
|
||||
int Delay0, Delay1, Delay;
|
||||
// get the fanin cuts
|
||||
Delay0 = Vec_IntEntry( p->vDelays2, Node0 );
|
||||
Delay1 = Vec_IntEntry( p->vDelays2, Node1 );
|
||||
pCut0 = (Delay0 == 0) ? Vec_PtrEntry( p->vCutsNew, Node0 ) : Vec_PtrEntry( p->vCutsMax, Node0 );
|
||||
pCut1 = (Delay1 == 0) ? Vec_PtrEntry( p->vCutsNew, Node1 ) : Vec_PtrEntry( p->vCutsMax, Node1 );
|
||||
if ( Delay0 == Delay1 )
|
||||
Delay = (Delay0 == 0) ? Delay0 + 1: Delay0;
|
||||
else if ( Delay0 > Delay1 )
|
||||
{
|
||||
Delay = Delay0;
|
||||
pCut1 = Vec_PtrEntry( p->vCutsNew, Node1 );
|
||||
assert( pCut1->nLeaves == 1 );
|
||||
}
|
||||
else // if ( Delay0 < Delay1 )
|
||||
{
|
||||
Delay = Delay1;
|
||||
pCut0 = Vec_PtrEntry( p->vCutsNew, Node0 );
|
||||
assert( pCut0->nLeaves == 1 );
|
||||
}
|
||||
// merge the cuts
|
||||
if ( pCut0->nLeaves < pCut1->nLeaves )
|
||||
pCut = Cut_CutMergeTwo( p, pCut1, pCut0 );
|
||||
else
|
||||
pCut = Cut_CutMergeTwo( p, pCut0, pCut1 );
|
||||
if ( pCut == NULL )
|
||||
{
|
||||
Delay++;
|
||||
pCut = Cut_CutAlloc( p );
|
||||
pCut->nLeaves = 2;
|
||||
pCut->pLeaves[0] = Node0 < Node1 ? Node0 : Node1;
|
||||
pCut->pLeaves[1] = Node0 < Node1 ? Node1 : Node0;
|
||||
}
|
||||
assert( Delay > 0 );
|
||||
Vec_IntWriteEntry( p->vDelays2, Node, Delay );
|
||||
Vec_PtrWriteEntry( p->vCutsMax, Node, pCut );
|
||||
if ( p->nDelayMin < Delay )
|
||||
p->nDelayMin = Delay;
|
||||
return Delay;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area after mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node )
|
||||
{
|
||||
Cut_Cut_t * pCut;
|
||||
int i, Counter;
|
||||
if ( p->vCutsMax == NULL )
|
||||
return 0;
|
||||
pCut = Vec_PtrEntry( p->vCutsMax, Node );
|
||||
if ( pCut == NULL || pCut->nLeaves == 1 )
|
||||
return 0;
|
||||
Counter = 0;
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
Counter += Cut_ManMappingArea_rec( p, pCut->pLeaves[i] );
|
||||
Vec_PtrWriteEntry( p->vCutsMax, Node, NULL );
|
||||
return 1 + Counter;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts by merging cuts at two nodes.]
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_H__
|
||||
#define __VEC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _WIN32
|
||||
#define inline __inline // compatible with MS VS 6.0
|
||||
#endif
|
||||
|
||||
#include "vecInt.h"
|
||||
#include "vecStr.h"
|
||||
#include "vecPtr.h"
|
||||
#include "vecVec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -1,753 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecInt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of integers.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_INT_H__
|
||||
#define __VEC_INT_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Int_t_ Vec_Int_t;
|
||||
struct Vec_Int_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
int * pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Vec_IntForEachEntry( vVec, Entry, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryStart( vVec, Entry, i, Start ) \
|
||||
for ( i = Start; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \
|
||||
for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryReverse( vVec, pEntry, i ) \
|
||||
for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAlloc( int nCap )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**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 []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAllocArrayCopy( int * pArray, int nSize )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( int, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(int) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntDup( Vec_Int_t * pVec )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(int) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntDupArray( Vec_Int_t * pVec )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFree( Vec_Int_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Vec_IntReleaseArray( Vec_Int_t * p )
|
||||
{
|
||||
int * pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Vec_IntArray( Vec_Int_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSize( Vec_Int_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntEntry( Vec_Int_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] += Addition;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntEntryLast( Vec_Int_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( int, p->pArray, nCapMin );
|
||||
assert( p->pArray );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_IntGrow( p, nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
Vec_IntGrow( p, nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntClear( Vec_Int_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize - 1; i >= 1; i-- )
|
||||
p->pArray[i] = p->pArray[i-1];
|
||||
p->pArray[0] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
int * pArray;
|
||||
int i;
|
||||
|
||||
if ( p->nSize == 0 )
|
||||
p->nCap = 1;
|
||||
pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
|
||||
// pArray = ALLOC( int, p->nCap * 2 );
|
||||
if ( p->pArray )
|
||||
{
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
pArray[i] = p->pArray[i];
|
||||
Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
|
||||
// free( p->pArray );
|
||||
}
|
||||
p->nCap *= 2;
|
||||
p->pArray = pArray;
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the entry while preserving the increasing order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
if ( p->pArray[i] > Entry )
|
||||
p->pArray[i+1] = p->pArray[i];
|
||||
else
|
||||
break;
|
||||
p->pArray[i+1] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the entry while preserving the increasing order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_IntPushOrder( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**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 []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPop( Vec_Int_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntFind( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntRemove( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
if ( i == p->nSize )
|
||||
return 0;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompare1( int * pp1, int * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompare2( int * pp1, int * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntSort( Vec_Int_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompare1 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompareUnsigned( unsigned * pp1, unsigned * pp2 )
|
||||
{
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntSortUnsigned( Vec_Int_t * p )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompareUnsigned );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -1,579 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecPtr.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of generic pointers.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecPtr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_PTR_H__
|
||||
#define __VEC_PTR_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Ptr_t_ Vec_Ptr_t;
|
||||
struct Vec_Ptr_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterators through entries
|
||||
#define Vec_PtrForEachEntry( vVec, pEntry, i ) \
|
||||
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_PtrForEachEntryStop( vVec, pEntry, i, Stop ) \
|
||||
for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop ) \
|
||||
for ( i = Start; (i < Stop) && (((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 DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
if ( nCap > 0 && nCap < 8 )
|
||||
nCap = 8;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**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 []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAllocArray( void ** pArray, int nSize )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAllocArrayCopy( void ** pArray, int nSize )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( void *, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(void *) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrDup( Vec_Ptr_t * pVec )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(void *) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrDupArray( Vec_Ptr_t * pVec )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFree( Vec_Ptr_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrReleaseArray( Vec_Ptr_t * p )
|
||||
{
|
||||
void ** pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrArray( Vec_Ptr_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrSize( Vec_Ptr_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrEntryP( Vec_Ptr_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray + i;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( void *, p->pArray, nCapMin );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_PtrGrow( p, nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
if ( p->nSize < 2 * nSize )
|
||||
Vec_PtrGrow( p, 2 * nSize );
|
||||
else
|
||||
Vec_PtrGrow( p, p->nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrShrink( Vec_Ptr_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrClear( Vec_Ptr_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_PtrGrow( p, 16 );
|
||||
else
|
||||
Vec_PtrGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrPushUnique( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_PtrPush( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrPop( Vec_Ptr_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Moves the first nItems to the end.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
|
||||
{
|
||||
assert( nItems < p->nSize );
|
||||
Vec_PtrGrow( p, nItems + p->nSize );
|
||||
memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) );
|
||||
memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(void *),
|
||||
(int (*)(const void *, const void *)) Vec_PtrSortCompare );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -1,510 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecStr.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of characters.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecStr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_STR_H__
|
||||
#define __VEC_STR_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Str_t_ Vec_Str_t;
|
||||
struct Vec_Str_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
char * pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Vec_StrForEachEntry( vVec, Entry, i ) \
|
||||
for ( i = 0; (i < Vec_StrSize(vVec)) && (((Entry) = Vec_StrEntry(vVec, i)), 1); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAlloc( int nCap )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**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 []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAllocArrayCopy( char * pArray, int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( char, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(char) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrDup( Vec_Str_t * pVec )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(char) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrFree( Vec_Str_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char * Vec_StrReleaseArray( Vec_Str_t * p )
|
||||
{
|
||||
char * pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char * Vec_StrArray( Vec_Str_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSize( Vec_Str_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrEntry( Vec_Str_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrEntryLast( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( char, p->pArray, 2 * nCapMin );
|
||||
p->nCap = 2 * nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrFill( Vec_Str_t * p, int nSize, char Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_StrGrow( p, nSize );
|
||||
p->nSize = nSize;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrShrink( Vec_Str_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrClear( Vec_Str_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_StrGrow( p, 16 );
|
||||
else
|
||||
Vec_StrGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Appends the string to the char vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrAppend( Vec_Str_t * p, char * pString )
|
||||
{
|
||||
int i, nLength = strlen(pString);
|
||||
Vec_StrGrow( p, p->nSize + nLength );
|
||||
for ( i = 0; i < nLength; i++ )
|
||||
p->pArray[p->nSize + i] = pString[i];
|
||||
p->nSize += nLength;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrPop( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSortCompare1( char * pp1, char * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSortCompare2( char * pp1, char * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrSort( Vec_Str_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(char),
|
||||
(int (*)(const void *, const void *)) Vec_StrSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(char),
|
||||
(int (*)(const void *, const void *)) Vec_StrSortCompare1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -1,289 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecVec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable vector of resizable vectors.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_VEC_H__
|
||||
#define __VEC_VEC_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Vec_t_ Vec_Vec_t;
|
||||
struct Vec_Vec_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterators through levels
|
||||
#define Vec_VecForEachLevel( vGlob, vVec, i ) \
|
||||
for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
|
||||
for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
|
||||
// iteratores through entries
|
||||
#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
|
||||
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \
|
||||
for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#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 )
|
||||
#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- ) \
|
||||
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
p = ALLOC( Vec_Vec_t, 1 );
|
||||
if ( nCap > 0 && nCap < 8 )
|
||||
nCap = 8;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecStart( int nSize )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
int i;
|
||||
p = Vec_VecAlloc( nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = nSize;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= Level + 1 )
|
||||
return;
|
||||
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
|
||||
for ( i = p->nSize; i <= Level; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = Level + 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_VecSize( Vec_Vec_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_VecEntry( Vec_Vec_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecFree( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Vec_PtrFree( vVec );
|
||||
Vec_PtrFree( (Vec_Ptr_t *)p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector of vectors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_VecSizeSize( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i, Counter = 0;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Counter += vVec->nSize;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecClear( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Vec_PtrClear( vVec );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry )
|
||||
{
|
||||
if ( p->nSize < Level + 1 )
|
||||
{
|
||||
int i;
|
||||
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
|
||||
for ( i = p->nSize; i < Level + 1; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = Level + 1;
|
||||
}
|
||||
Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry )
|
||||
{
|
||||
if ( p->nSize < Level + 1 )
|
||||
Vec_VecPush( p, Level, Entry );
|
||||
else
|
||||
Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -51,11 +51,15 @@ struct Dec_Node_t_
|
|||
Dec_Edge_t eEdge1; // the right child of the node
|
||||
// other info
|
||||
void * pFunc; // the function of the node (BDD or AIG)
|
||||
unsigned Level : 16; // the level of this node in the global AIG
|
||||
unsigned Level : 14; // the level of this node in the global AIG
|
||||
// printing info
|
||||
unsigned fNodeOr : 1; // marks the original OR node
|
||||
unsigned fCompl0 : 1; // marks the original complemented edge
|
||||
unsigned fCompl1 : 1; // marks the original complemented edge
|
||||
// latch info
|
||||
unsigned nLat0 : 5; // the number of latches on the first edge
|
||||
unsigned nLat1 : 5; // the number of latches on the second edge
|
||||
unsigned nLat2 : 5; // the number of latches on the output edge
|
||||
};
|
||||
|
||||
typedef struct Dec_Graph_t_ Dec_Graph_t;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
static Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest );
|
||||
static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
|
||||
static int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -72,6 +73,8 @@ clk = clock();
|
|||
assert( pCut != NULL );
|
||||
p->timeCut += clock() - clk;
|
||||
|
||||
//printf( " %d", Rwr_CutCountNumNodes(pNode, pCut) );
|
||||
|
||||
// go through the cuts
|
||||
clk = clock();
|
||||
for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
|
||||
|
|
@ -104,6 +107,15 @@ clk = clock();
|
|||
}
|
||||
p->nCutsGood++;
|
||||
|
||||
{
|
||||
int Counter = 0;
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
if ( Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) == 1 )
|
||||
Counter++;
|
||||
if ( Counter > 2 )
|
||||
continue;
|
||||
}
|
||||
|
||||
clk2 = clock();
|
||||
/*
|
||||
printf( "Considering: (" );
|
||||
|
|
@ -306,6 +318,72 @@ int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
|
|||
return RetValue;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Count the nodes in the cut space of a node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Rwr_CutCountNumNodes_rec( Abc_Obj_t * pObj, Cut_Cut_t * pCut, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
if ( pCut->pLeaves[i] == pObj->Id )
|
||||
{
|
||||
// check if the node is collected
|
||||
if ( pObj->fMarkC == 0 )
|
||||
{
|
||||
pObj->fMarkC = 1;
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
}
|
||||
return;
|
||||
}
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
// check if the node is collected
|
||||
if ( pObj->fMarkC == 0 )
|
||||
{
|
||||
pObj->fMarkC = 1;
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
}
|
||||
// traverse the fanins
|
||||
Rwr_CutCountNumNodes_rec( Abc_ObjFanin0(pObj), pCut, vNodes );
|
||||
Rwr_CutCountNumNodes_rec( Abc_ObjFanin1(pObj), pCut, vNodes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Count the nodes in the cut space of a node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
int i, Counter;
|
||||
// collect all nodes
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
|
||||
Rwr_CutCountNumNodes_rec( pObj, pCut, vNodes );
|
||||
// clean all nodes
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
pObj->fMarkC = 0;
|
||||
// delete and return
|
||||
Counter = Vec_PtrSize(vNodes);
|
||||
Vec_PtrFree( vNodes );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -209,6 +209,23 @@ void Asat_SolverSetPrefVars(solver * s, int * pPrefVars, int nPrefVars)
|
|||
s->nPrefVars = nPrefVars;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the preferred variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_SolverSetFactors(solver * s, int * pFactors)
|
||||
{
|
||||
assert( s->factors == NULL );
|
||||
s->factors = pFactors;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ static inline void act_var_rescale(solver* s) {
|
|||
static inline void act_var_bump(solver* s, int v) {
|
||||
double* activity = s->activity;
|
||||
if ((activity[v] += s->var_inc) > 1e100)
|
||||
// if ((activity[v] += s->var_inc*s->factors[v]/100000000) > 1e100)
|
||||
act_var_rescale(s);
|
||||
|
||||
//printf("bump %d %f\n", v-1, activity[v]);
|
||||
|
|
@ -947,6 +948,7 @@ solver* solver_new(void)
|
|||
// initialize arrays
|
||||
s->wlists = 0;
|
||||
s->activity = 0;
|
||||
s->factors = 0;
|
||||
s->assigns = 0;
|
||||
s->orderpos = 0;
|
||||
s->reasons = 0;
|
||||
|
|
@ -1039,9 +1041,9 @@ void solver_delete(solver* s)
|
|||
free(s->trail );
|
||||
free(s->tags );
|
||||
}
|
||||
|
||||
if ( s->pJMan ) Asat_JManStop( s );
|
||||
if ( s->pPrefVars ) free( s->pPrefVars );
|
||||
if ( s->factors ) free( s->factors );
|
||||
free(s);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName,
|
|||
int incrementVars);
|
||||
extern void Asat_SatPrintStats( FILE * pFile, solver * p );
|
||||
extern void Asat_SolverSetPrefVars( solver * s, int * pPrefVars, int nPrefVars );
|
||||
extern void Asat_SolverSetFactors( solver * s, int * pFactors );
|
||||
|
||||
// J-frontier support
|
||||
extern Asat_JMan_t * Asat_JManStart( solver * pSat, void * vCircuit );
|
||||
|
|
@ -127,6 +128,7 @@ struct solver_t
|
|||
|
||||
vec* wlists; //
|
||||
double* activity; // A heuristic measurement of the activity of a variable.
|
||||
int * factors; // the factor of variable activity
|
||||
lbool* assigns; // Current values of variables.
|
||||
int* orderpos; // Index in variable order.
|
||||
clause** reasons; //
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ int Fraig_NodeIsEquivalent( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t *
|
|||
Fraig_ManCreateSolver( p );
|
||||
// make sure the SAT solver has enough variables
|
||||
for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
|
||||
Msat_SolverAddVar( p->pSat );
|
||||
Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
|
||||
|
||||
|
||||
|
||||
|
|
@ -543,7 +543,7 @@ int Fraig_NodeIsImplication( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t
|
|||
Fraig_ManCreateSolver( p );
|
||||
// make sure the SAT solver has enough variables
|
||||
for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
|
||||
Msat_SolverAddVar( p->pSat );
|
||||
Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
|
||||
|
||||
// get the logic cone
|
||||
clk = clock();
|
||||
|
|
@ -642,7 +642,7 @@ int Fraig_ManCheckClauseUsingSat( Fraig_Man_t * p, Fraig_Node_t * pNode1, Fraig_
|
|||
Fraig_ManCreateSolver( p );
|
||||
// make sure the SAT solver has enough variables
|
||||
for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ )
|
||||
Msat_SolverAddVar( p->pSat );
|
||||
Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level );
|
||||
|
||||
// get the logic cone
|
||||
clk = clock();
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ typedef enum { MSAT_FALSE = -1, MSAT_UNKNOWN = 0, MSAT_TRUE = 1 } Msat_Type_t;
|
|||
extern bool Msat_SolverParseDimacs( FILE * pFile, Msat_Solver_t ** p, int fVerbose );
|
||||
/*=== satSolver.c ===========================================================*/
|
||||
// adding vars, clauses, simplifying the database, and solving
|
||||
extern bool Msat_SolverAddVar( Msat_Solver_t * p );
|
||||
extern bool Msat_SolverAddVar( Msat_Solver_t * p, int Level );
|
||||
extern bool Msat_SolverAddClause( Msat_Solver_t * p, Msat_IntVec_t * pLits );
|
||||
extern bool Msat_SolverSimplifyDB( Msat_Solver_t * p );
|
||||
extern bool Msat_SolverSolve( Msat_Solver_t * p, Msat_IntVec_t * pVecAssumps, int nBackTrackLimit, int nTimeLimit );
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ void Msat_SolverVarBumpActivity( Msat_Solver_t * p, Msat_Lit_t Lit )
|
|||
return;
|
||||
Var = MSAT_LIT2VAR(Lit);
|
||||
if ( (p->pdActivity[Var] += p->dVarInc) > 1e100 )
|
||||
// if ( (p->pdActivity[Var] += p->dVarInc * (1.0 + 0.005*p->pLevel[Var])) > 1e100 )
|
||||
Msat_SolverVarRescaleActivity( p );
|
||||
Msat_OrderUpdate( p->pOrder, Var );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ struct Msat_Solver_t_
|
|||
double dClaDecay; // INVERSE decay factor for clause activity: stores 1/decay.
|
||||
|
||||
double * pdActivity; // A heuristic measurement of the activity of a variable.
|
||||
int * pLevels; // the levels of the variables
|
||||
double dVarInc; // Amount to bump next variable with.
|
||||
double dVarDecay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order.
|
||||
Msat_Order_t * pOrder; // Keeps track of the decision variable order.
|
||||
|
|
|
|||
|
|
@ -174,8 +174,12 @@ Msat_Solver_t * Msat_SolverAlloc( int nVarsAlloc,
|
|||
p->dVarDecay = dVarDecay;
|
||||
|
||||
p->pdActivity = ALLOC( double, p->nVarsAlloc );
|
||||
p->pLevels = ALLOC( int, p->nVarsAlloc );
|
||||
for ( i = 0; i < p->nVarsAlloc; i++ )
|
||||
{
|
||||
p->pdActivity[i] = 0;
|
||||
p->pLevels = 0;
|
||||
}
|
||||
|
||||
p->pAssigns = ALLOC( int, p->nVarsAlloc );
|
||||
p->pModel = ALLOC( int, p->nVarsAlloc );
|
||||
|
|
@ -239,6 +243,7 @@ void Msat_SolverResize( Msat_Solver_t * p, int nVarsAlloc )
|
|||
p->nVarsAlloc = nVarsAlloc;
|
||||
|
||||
p->pdActivity = REALLOC( double, p->pdActivity, p->nVarsAlloc );
|
||||
p->pLevels = REALLOC( int, p->pLevels, p->nVarsAlloc );
|
||||
for ( i = nVarsAllocOld; i < p->nVarsAlloc; i++ )
|
||||
p->pdActivity[i] = 0;
|
||||
|
||||
|
|
@ -394,6 +399,7 @@ void Msat_SolverFree( Msat_Solver_t * p )
|
|||
Msat_ClauseVecFree( p->vLearned );
|
||||
|
||||
FREE( p->pdActivity );
|
||||
FREE( p->pLevels );
|
||||
Msat_OrderFree( p->pOrder );
|
||||
|
||||
for ( i = 0; i < 2 * p->nVarsAlloc; i++ )
|
||||
|
|
|
|||
|
|
@ -39,10 +39,11 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
bool Msat_SolverAddVar( Msat_Solver_t * p )
|
||||
bool Msat_SolverAddVar( Msat_Solver_t * p, int Level )
|
||||
{
|
||||
if ( p->nVars == p->nVarsAlloc )
|
||||
Msat_SolverResize( p, 2 * p->nVarsAlloc );
|
||||
p->pLevel[p->nVars] = Level;
|
||||
p->nVars++;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,11 +51,15 @@ struct Dec_Node_t_
|
|||
Dec_Edge_t eEdge1; // the right child of the node
|
||||
// other info
|
||||
void * pFunc; // the function of the node (BDD or AIG)
|
||||
unsigned Level : 16; // the level of this node in the global AIG
|
||||
unsigned Level : 14; // the level of this node in the global AIG
|
||||
// printing info
|
||||
unsigned fNodeOr : 1; // marks the original OR node
|
||||
unsigned fCompl0 : 1; // marks the original complemented edge
|
||||
unsigned fCompl1 : 1; // marks the original complemented edge
|
||||
// latch info
|
||||
unsigned nLat0 : 5; // the number of latches on the first edge
|
||||
unsigned nLat1 : 5; // the number of latches on the second edge
|
||||
unsigned nLat2 : 5; // the number of latches on the output edge
|
||||
};
|
||||
|
||||
typedef struct Dec_Graph_t_ Dec_Graph_t;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ struct Ivy_Obj_t_ // 24 bytes (32-bit) or 32 bytes (64-bit)
|
|||
int nRefs; // reference counter
|
||||
Ivy_Obj_t * pFanin0; // fanin
|
||||
Ivy_Obj_t * pFanin1; // fanin
|
||||
Ivy_Obj_t * pFanout; // fanout
|
||||
Ivy_Obj_t * pEquiv; // equivalent node
|
||||
};
|
||||
|
||||
// the AIG manager
|
||||
|
|
@ -136,6 +138,9 @@ struct Ivy_Store_t_
|
|||
Ivy_Cut_t pCuts[IVY_CUT_LIMIT]; // storage for cuts
|
||||
};
|
||||
|
||||
#define IVY_LEAF_MASK 255
|
||||
#define IVY_LEAF_BITS 8
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -170,9 +175,9 @@ static inline Ivy_Edge_t Ivy_EdgeNotCond( Ivy_Edge_t Edge, int fCond ) { ret
|
|||
static inline Ivy_Edge_t Ivy_EdgeFromNode( Ivy_Obj_t * pNode ) { return Ivy_EdgeCreate( Ivy_Regular(pNode)->Id, Ivy_IsComplement(pNode) ); }
|
||||
static inline Ivy_Obj_t * Ivy_EdgeToNode( Ivy_Man_t * p, Ivy_Edge_t Edge ){ return Ivy_NotCond( Ivy_ManObj(p, Ivy_EdgeId(Edge)), Ivy_EdgeIsComplement(Edge) ); }
|
||||
|
||||
static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << 4) | Lat; }
|
||||
static inline int Ivy_LeafId( int Leaf ) { return Leaf >> 4; }
|
||||
static inline int Ivy_LeafLat( int Leaf ) { return Leaf & 15; }
|
||||
static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << IVY_LEAF_BITS) | Lat; }
|
||||
static inline int Ivy_LeafId( int Leaf ) { return Leaf >> IVY_LEAF_BITS; }
|
||||
static inline int Ivy_LeafLat( int Leaf ) { return Leaf & IVY_LEAF_MASK; }
|
||||
|
||||
static inline int Ivy_ManPiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PI]; }
|
||||
static inline int Ivy_ManPoNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PO]; }
|
||||
|
|
@ -261,12 +266,16 @@ static inline int Ivy_ObjFanoutC( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout
|
|||
static inline Ivy_Obj_t * Ivy_ObjCreateGhost( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type, Ivy_Init_t Init )
|
||||
{
|
||||
Ivy_Obj_t * pGhost, * pTemp;
|
||||
assert( Type != IVY_AND || !Ivy_ObjIsConst1(Ivy_Regular(p0)) );
|
||||
assert( p1 == NULL || !Ivy_ObjIsConst1(Ivy_Regular(p1)) );
|
||||
assert( Type == IVY_PI || Ivy_Regular(p0) != Ivy_Regular(p1) );
|
||||
assert( Type != IVY_LATCH || !Ivy_IsComplement(p0) );
|
||||
// assert( p1 == NULL || (!Ivy_ObjIsLatch(Ivy_Regular(p0)) || !Ivy_ObjIsLatch(Ivy_Regular(p1))) );
|
||||
pGhost = Ivy_ManGhost(p);
|
||||
pGhost->Type = Type;
|
||||
pGhost->Init = Init;
|
||||
pGhost->pFanin0 = p0;
|
||||
pGhost->pFanin1 = p1;
|
||||
assert( Type == IVY_PI || Ivy_ObjFanin0(pGhost) != Ivy_ObjFanin1(pGhost) );
|
||||
if ( p1 && Ivy_ObjFaninId0(pGhost) > Ivy_ObjFaninId1(pGhost) )
|
||||
pTemp = pGhost->pFanin0, pGhost->pFanin0 = pGhost->pFanin1, pGhost->pFanin1 = pTemp;
|
||||
return pGhost;
|
||||
|
|
@ -384,6 +393,7 @@ extern Vec_Int_t * Ivy_ManDfsSeq( Ivy_Man_t * p, Vec_Int_t ** pvLatches );
|
|||
extern void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone );
|
||||
extern Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p );
|
||||
extern Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p );
|
||||
extern int Ivy_ManIsAcyclic( Ivy_Man_t * p );
|
||||
/*=== ivyDsd.c ==========================================================*/
|
||||
extern int Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree );
|
||||
extern void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree );
|
||||
|
|
@ -400,11 +410,14 @@ extern void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, V
|
|||
extern Ivy_Obj_t * Ivy_ObjReadOneFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
/*=== ivyIsop.c ==========================================================*/
|
||||
extern int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover );
|
||||
extern void Ivy_TruthManStop();
|
||||
/*=== ivyMan.c ==========================================================*/
|
||||
extern Ivy_Man_t * Ivy_ManStart();
|
||||
extern void Ivy_ManStop( Ivy_Man_t * p );
|
||||
extern int Ivy_ManCleanup( Ivy_Man_t * p );
|
||||
extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p );
|
||||
extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel );
|
||||
extern void Ivy_ManPrintStats( Ivy_Man_t * p );
|
||||
extern void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits );
|
||||
/*=== ivyMem.c ==========================================================*/
|
||||
|
|
@ -425,8 +438,8 @@ extern void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
|||
extern void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew );
|
||||
extern void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop );
|
||||
extern void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop );
|
||||
extern void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop );
|
||||
extern void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode );
|
||||
extern void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel );
|
||||
extern void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel );
|
||||
/*=== ivyOper.c =========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_Oper( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_And( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
|
|
@ -442,6 +455,8 @@ extern Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * p, int fUpdateLevel, int fVerbo
|
|||
extern int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
|
||||
extern int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
|
||||
extern int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose );
|
||||
/*=== ivySeq.c =========================================================*/
|
||||
extern int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose );
|
||||
/*=== ivyTable.c ========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_TableInsert( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
|
|
@ -456,6 +471,7 @@ extern unsigned * Ivy_ManCutTruth( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_In
|
|||
extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p );
|
||||
extern int Ivy_ManLevels( Ivy_Man_t * p );
|
||||
extern void Ivy_ManResetLevels( Ivy_Man_t * p );
|
||||
extern int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_ObjUpdateLevel_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ReqNew );
|
||||
extern int Ivy_ObjIsMuxType( Ivy_Obj_t * pObj );
|
||||
|
|
|
|||
|
|
@ -107,8 +107,8 @@ int Ivy_ManCheck( Ivy_Man_t * p )
|
|||
printf( "Ivy_ManCheck: The AIG has node \"%d\" with a wrong ordering of fanins.\n", pObj->Id );
|
||||
return 0;
|
||||
}
|
||||
// if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) )
|
||||
// printf( "Ivy_ManCheck: Node with ID \"%d\" has level %d but should have level %d.\n", pObj->Id, Ivy_ObjLevel(pObj), Ivy_ObjLevelNew(pObj) );
|
||||
if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) )
|
||||
printf( "Ivy_ManCheck: Node with ID \"%d\" has level %d but should have level %d.\n", pObj->Id, Ivy_ObjLevel(pObj), Ivy_ObjLevelNew(pObj) );
|
||||
pObj2 = Ivy_TableLookup( p, pObj );
|
||||
if ( pObj2 != pObj )
|
||||
printf( "Ivy_ManCheck: Node with ID \"%d\" is not in the structural hashing table.\n", pObj->Id );
|
||||
|
|
@ -124,6 +124,8 @@ int Ivy_ManCheck( Ivy_Man_t * p )
|
|||
printf( "Ivy_ManCheck: The number of nodes in the structural hashing table is wrong.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( !Ivy_ManIsAcyclic(p) )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Ivy_NodeCutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -578,6 +580,88 @@ static inline int Ivy_NodeCutExtend( Ivy_Cut_t * pCut, int iNew )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_NodeCutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 )
|
||||
{
|
||||
int i;
|
||||
if ( pCut->nSize < pCut->nSizeMax )
|
||||
return 1;
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives new cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_NodeCutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
|
||||
{
|
||||
unsigned uHash = 0;
|
||||
int i, k;
|
||||
assert( pCut->nSize > 0 );
|
||||
assert( IdNew0 < IdNew1 );
|
||||
for ( i = k = 0; i < pCut->nSize; i++ )
|
||||
{
|
||||
if ( pCut->pArray[i] == IdOld )
|
||||
continue;
|
||||
if ( IdNew0 <= pCut->pArray[i] )
|
||||
{
|
||||
if ( IdNew0 < pCut->pArray[i] )
|
||||
{
|
||||
pCutNew->pArray[ k++ ] = IdNew0;
|
||||
uHash |= Ivy_NodeCutHashValue( IdNew0 );
|
||||
}
|
||||
IdNew0 = 0x7FFFFFFF;
|
||||
}
|
||||
if ( IdNew1 <= pCut->pArray[i] )
|
||||
{
|
||||
if ( IdNew1 < pCut->pArray[i] )
|
||||
{
|
||||
pCutNew->pArray[ k++ ] = IdNew1;
|
||||
uHash |= Ivy_NodeCutHashValue( IdNew1 );
|
||||
}
|
||||
IdNew1 = 0x7FFFFFFF;
|
||||
}
|
||||
pCutNew->pArray[ k++ ] = pCut->pArray[i];
|
||||
uHash |= Ivy_NodeCutHashValue( pCut->pArray[i] );
|
||||
}
|
||||
if ( IdNew0 < 0x7FFFFFFF )
|
||||
{
|
||||
pCutNew->pArray[ k++ ] = IdNew0;
|
||||
uHash |= Ivy_NodeCutHashValue( IdNew0 );
|
||||
}
|
||||
if ( IdNew1 < 0x7FFFFFFF )
|
||||
{
|
||||
pCutNew->pArray[ k++ ] = IdNew1;
|
||||
uHash |= Ivy_NodeCutHashValue( IdNew1 );
|
||||
}
|
||||
pCutNew->nSize = k;
|
||||
pCutNew->uHash = uHash;
|
||||
assert( pCutNew->nSize <= pCut->nSizeMax );
|
||||
// for ( i = 1; i < pCutNew->nSize; i++ )
|
||||
// assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check if the cut exists.]
|
||||
|
|
@ -789,7 +873,7 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves
|
|||
Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut;
|
||||
Ivy_Man_t * pMan = p;
|
||||
Ivy_Obj_t * pLeaf;
|
||||
int i, k;
|
||||
int i, k, iLeaf0, iLeaf1;
|
||||
|
||||
assert( nLeaves <= IVY_CUT_INPUT );
|
||||
|
||||
|
|
@ -818,6 +902,7 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves
|
|||
pLeaf = Ivy_ManObj( p, pCut->pArray[k] );
|
||||
if ( Ivy_ObjIsCi(pLeaf) )
|
||||
continue;
|
||||
/*
|
||||
*pCutNew = *pCut;
|
||||
Ivy_NodeCutShrink( pCutNew, pLeaf->Id );
|
||||
if ( !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId0(pLeaf) ) )
|
||||
|
|
@ -825,6 +910,12 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves
|
|||
if ( Ivy_ObjIsNode(pLeaf) && !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId1(pLeaf) ) )
|
||||
continue;
|
||||
Ivy_NodeCutHash( pCutNew );
|
||||
*/
|
||||
iLeaf0 = Ivy_ObjFaninId0(pLeaf);
|
||||
iLeaf1 = Ivy_ObjFaninId1(pLeaf);
|
||||
if ( !Ivy_NodeCutPrescreen( pCut, iLeaf0, iLeaf1 ) )
|
||||
continue;
|
||||
Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 );
|
||||
Ivy_NodeCutFindOrAddFilter( pCutStore, pCutNew );
|
||||
if ( pCutStore->nCuts == IVY_CUT_LIMIT )
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -250,6 +250,105 @@ Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p )
|
|||
return vLevelsR;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively detects combinational loops.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManIsAcyclic_rec( Ivy_Man_t * p, Ivy_Obj_t * pNode )
|
||||
{
|
||||
if ( Ivy_ObjIsCi(pNode) || Ivy_ObjIsConst1(pNode) )
|
||||
return 1;
|
||||
assert( Ivy_ObjIsNode( pNode ) );
|
||||
// make sure the node is not visited
|
||||
assert( !Ivy_ObjIsTravIdPrevious(p, pNode) );
|
||||
// check if the node is part of the combinational loop
|
||||
if ( Ivy_ObjIsTravIdCurrent(p, pNode) )
|
||||
{
|
||||
fprintf( stdout, "Manager contains combinational loop!\n" );
|
||||
fprintf( stdout, "Node \"%d\" is encountered twice on the following path:\n", Ivy_ObjId(pNode) );
|
||||
fprintf( stdout, " %d", Ivy_ObjId(pNode) );
|
||||
return 0;
|
||||
}
|
||||
// mark this node as a node on the current path
|
||||
Ivy_ObjSetTravIdCurrent( p, pNode );
|
||||
// check if the fanin is visited
|
||||
if ( !Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin0(pNode)) )
|
||||
{
|
||||
// traverse the fanin's cone searching for the loop
|
||||
if ( !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pNode)) )
|
||||
{
|
||||
// return as soon as the loop is detected
|
||||
fprintf( stdout, " <-- %d", Ivy_ObjId(Ivy_ObjFanin0(pNode)) );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// check if the fanin is visited
|
||||
if ( !Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin1(pNode)) )
|
||||
{
|
||||
// traverse the fanin's cone searching for the loop
|
||||
if ( !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin1(pNode)) )
|
||||
{
|
||||
// return as soon as the loop is detected
|
||||
fprintf( stdout, " <-- %d", Ivy_ObjId(Ivy_ObjFanin1(pNode)) );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// mark this node as a visited node
|
||||
Ivy_ObjSetTravIdPrevious( p, pNode );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Detects combinational loops.]
|
||||
|
||||
Description [This procedure is based on the idea suggested by Donald Chai.
|
||||
As we traverse the network and visit the nodes, we need to distinquish
|
||||
three types of nodes: (1) those that are visited for the first time,
|
||||
(2) those that have been visited in this traversal but are currently not
|
||||
on the traversal path, (3) those that have been visited and are currently
|
||||
on the travesal path. When the node of type (3) is encountered, it means
|
||||
that there is a combinational loop. To mark the three types of nodes,
|
||||
two new values of the traversal IDs are used.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManIsAcyclic( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pNode;
|
||||
int fAcyclic, i;
|
||||
// set the traversal ID for this DFS ordering
|
||||
Ivy_ManIncrementTravId( p );
|
||||
Ivy_ManIncrementTravId( p );
|
||||
// pNode->TravId == pNet->nTravIds means "pNode is on the path"
|
||||
// pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path"
|
||||
// pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited"
|
||||
// traverse the network to detect cycles
|
||||
fAcyclic = 1;
|
||||
Ivy_ManForEachCo( p, pNode, i )
|
||||
{
|
||||
if ( Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin0(pNode)) )
|
||||
continue;
|
||||
// traverse the output logic cone
|
||||
if ( fAcyclic = Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pNode)) )
|
||||
continue;
|
||||
// stop as soon as the first loop is detected
|
||||
fprintf( stdout, " (cone of CO \"%d\")\n", Ivy_ObjFaninId0(pNode) );
|
||||
break;
|
||||
}
|
||||
return fAcyclic;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ void Ivy_ObjDeleteFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout )
|
|||
assert( *ppSpot == pFanout );
|
||||
*ppSpot = NULL;
|
||||
}
|
||||
// printf( " %d", Ivy_ObjFanoutNum(p, pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
#include "mem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -33,7 +34,8 @@ struct Ivy_Sop_t_
|
|||
|
||||
static Mem_Flex_t * s_Man = NULL;
|
||||
|
||||
static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t * pcRes );
|
||||
static unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy_Sop_t * pcRes );
|
||||
static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t * pcRes );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -41,23 +43,7 @@ static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_TruthManStart()
|
||||
{
|
||||
s_Man = Mem_FlexStart();
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Deallocates memory used for computing ISOPs from TTs.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -74,7 +60,7 @@ void Ivy_TruthManStop()
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Computes ISOP from TT.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -83,13 +69,90 @@ void Ivy_TruthManStop()
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Ivy_TruthIsop( unsigned * uTruth, int nVars )
|
||||
int Ivy_TruthIsopOne( unsigned * puTruth, int nVars, Vec_Int_t * vCover )
|
||||
{
|
||||
Ivy_Sop_t cRes, * pcRes = &cRes;
|
||||
unsigned * pResult;
|
||||
int i;
|
||||
assert( nVars >= 0 && nVars < 16 );
|
||||
// if nVars < 5, make sure it does not depend on those vars
|
||||
for ( i = nVars; i < 5; i++ )
|
||||
assert( !Extra_TruthVarInSupport(puTruth, 5, i) );
|
||||
// prepare memory manager
|
||||
if ( s_Man == NULL )
|
||||
s_Man = Mem_FlexStart();
|
||||
else
|
||||
Mem_FlexRestart( s_Man );
|
||||
// compute ISOP
|
||||
pResult = Ivy_TruthIsop_rec( puTruth, puTruth, nVars, pcRes );
|
||||
// Extra_PrintBinary( stdout, puTruth, 1 << nVars ); printf( "\n" );
|
||||
// Extra_PrintBinary( stdout, pResult, 1 << nVars ); printf( "\n" );
|
||||
assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) );
|
||||
//printf( "%d ", Mem_FlexReadMemUsage(s_Man) );
|
||||
//printf( "%d ", pcRes->nCubes );
|
||||
// copy the truth table
|
||||
Vec_IntClear( vCover );
|
||||
for ( i = 0; i < pcRes->nCubes; i++ )
|
||||
Vec_IntPush( vCover, pcRes->pCubes[i] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes ISOP for 5 variables or less.]
|
||||
Synopsis [Computes ISOP from TT.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover )
|
||||
{
|
||||
Ivy_Sop_t cRes, * pcRes = &cRes;
|
||||
unsigned * pResult;
|
||||
int i;
|
||||
assert( nVars >= 0 && nVars < 16 );
|
||||
// if nVars < 5, make sure it does not depend on those vars
|
||||
for ( i = nVars; i < 5; i++ )
|
||||
assert( !Extra_TruthVarInSupport(puTruth, 5, i) );
|
||||
// prepare memory manager
|
||||
if ( s_Man == NULL )
|
||||
s_Man = Mem_FlexStart();
|
||||
else
|
||||
Mem_FlexRestart( s_Man );
|
||||
// compute ISOP
|
||||
pResult = Ivy_TruthIsop_rec( puTruth, puTruth, nVars, pcRes );
|
||||
// Extra_PrintBinary( stdout, puTruth, 1 << nVars ); printf( "\n" );
|
||||
// Extra_PrintBinary( stdout, pResult, 1 << nVars ); printf( "\n" );
|
||||
assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) );
|
||||
//printf( "%d ", Mem_FlexReadMemUsage(s_Man) );
|
||||
//printf( "%d ", pcRes->nCubes );
|
||||
// copy the truth table
|
||||
Vec_IntClear( vCover );
|
||||
for ( i = 0; i < pcRes->nCubes; i++ )
|
||||
Vec_IntPush( vCover, pcRes->pCubes[i] );
|
||||
|
||||
// try other polarity
|
||||
Mem_FlexRestart( s_Man );
|
||||
Extra_TruthNot( puTruth, puTruth, nVars );
|
||||
pResult = Ivy_TruthIsop_rec( puTruth, puTruth, nVars, pcRes );
|
||||
assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) );
|
||||
Extra_TruthNot( puTruth, puTruth, nVars );
|
||||
if ( Vec_IntSize(vCover) < pcRes->nCubes )
|
||||
return 0;
|
||||
|
||||
// copy the truth table
|
||||
Vec_IntClear( vCover );
|
||||
for ( i = 0; i < pcRes->nCubes; i++ )
|
||||
Vec_IntPush( vCover, pcRes->pCubes[i] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes ISOP 6 variables or more.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -103,54 +166,59 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy
|
|||
Ivy_Sop_t cRes0, cRes1, cRes2;
|
||||
Ivy_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
|
||||
unsigned * puRes0, * puRes1, * puRes2;
|
||||
unsigned * puOn0, * puOn1, * puOnDc0, * puOnDc1, * pTemp0, * pTemp1;
|
||||
int i, k, Var, nWords;
|
||||
assert( nVars > 5 );
|
||||
unsigned * puOn0, * puOn1, * puOnDc0, * puOnDc1, * pTemp, * pTemp0, * pTemp1;
|
||||
int i, k, Var, nWords, nWordsAll;
|
||||
assert( Extra_TruthIsImply( puOn, puOnDc, nVars ) );
|
||||
// allocate room for the resulting truth table
|
||||
nWordsAll = Extra_TruthWordNum( nVars );
|
||||
pTemp = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * nWordsAll );
|
||||
// check for constants
|
||||
if ( Extra_TruthIsConst0( puOn, nVars ) )
|
||||
{
|
||||
pcRes->nCubes = 0;
|
||||
pcRes->pCubes = NULL;
|
||||
return puOn;
|
||||
Extra_TruthClear( pTemp, nVars );
|
||||
return pTemp;
|
||||
}
|
||||
if ( Extra_TruthIsConst1( puOnDc, nVars ) )
|
||||
{
|
||||
pcRes->nCubes = 1;
|
||||
pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 );
|
||||
pcRes->pCubes[0] = 0;
|
||||
return puOnDc;
|
||||
Extra_TruthFill( pTemp, nVars );
|
||||
return pTemp;
|
||||
}
|
||||
assert( nVars > 0 );
|
||||
// find the topmost var
|
||||
for ( Var = nVars-1; Var >= 0; Var-- )
|
||||
if ( Extra_TruthVarInSupport( puOn, nVars, Var ) ||
|
||||
Extra_TruthVarInSupport( puOnDc, nVars, Var ) )
|
||||
break;
|
||||
assert( Var >= 0 );
|
||||
// consider a simple case when one-word computation can be used
|
||||
if ( Var < 5 )
|
||||
{
|
||||
unsigned * puRes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 );
|
||||
*puRes = Ivy_TruthIsop5_rec( puOn[0], puOnDc[0], Var + 1, pcRes );
|
||||
return puRes;
|
||||
unsigned uRes = Ivy_TruthIsop5_rec( puOn[0], puOnDc[0], Var+1, pcRes );
|
||||
for ( i = 0; i < nWordsAll; i++ )
|
||||
pTemp[i] = uRes;
|
||||
return pTemp;
|
||||
}
|
||||
nWords = Extra_TruthWordNum( Var+1 );
|
||||
assert( Var >= 5 );
|
||||
nWords = Extra_TruthWordNum( Var );
|
||||
// cofactor
|
||||
puOn0 = puOn;
|
||||
puOn1 = puOn + nWords;
|
||||
puOnDc0 = puOnDc;
|
||||
puOnDc1 = puOnDc + nWords;
|
||||
// intermediate copies
|
||||
pTemp0 = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * nWords );
|
||||
pTemp1 = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * nWords );
|
||||
puOn0 = puOn; puOn1 = puOn + nWords;
|
||||
puOnDc0 = puOnDc; puOnDc1 = puOnDc + nWords;
|
||||
pTemp0 = pTemp; pTemp1 = pTemp + nWords;
|
||||
// solve for cofactors
|
||||
Extra_TruthSharp( pTemp0, puOn0, puOnDc1, Var + 1 );
|
||||
puRes0 = Ivy_TruthIsop5_rec( pTemp0, uOnDc0, Var-1, pcRes0 );
|
||||
Extra_TruthSharp( pTemp0, puOn1, puOnDc0, Var + 1 );
|
||||
puRes1 = Ivy_TruthIsop5_rec( pTemp1, uOnDc1, Var-1, pcRes1 );
|
||||
Extra_TruthSharp( pTemp0, puOn0, puRes0, Var + 1 );
|
||||
Extra_TruthSharp( pTemp1, puOn1, puRes1, Var + 1 );
|
||||
Extra_TruthOr( pTemp0, pTemp0, pTemp1, Var + 1 );
|
||||
Extra_TruthAnd( pTemp1, puOnDc0, puOnDc1, Var + 1 );
|
||||
puRes2 = Ivy_TruthIsop5_rec( pTemp0, pTemp1, Var-1, pcRes2 );
|
||||
Extra_TruthSharp( pTemp0, puOn0, puOnDc1, Var );
|
||||
puRes0 = Ivy_TruthIsop_rec( pTemp0, puOnDc0, Var, pcRes0 );
|
||||
Extra_TruthSharp( pTemp1, puOn1, puOnDc0, Var );
|
||||
puRes1 = Ivy_TruthIsop_rec( pTemp1, puOnDc1, Var, pcRes1 );
|
||||
Extra_TruthSharp( pTemp0, puOn0, puRes0, Var );
|
||||
Extra_TruthSharp( pTemp1, puOn1, puRes1, Var );
|
||||
Extra_TruthOr( pTemp0, pTemp0, pTemp1, Var );
|
||||
Extra_TruthAnd( pTemp1, puOnDc0, puOnDc1, Var );
|
||||
puRes2 = Ivy_TruthIsop_rec( pTemp0, pTemp1, Var, pcRes2 );
|
||||
// create the resulting cover
|
||||
pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes;
|
||||
pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * pcRes->nCubes );
|
||||
|
|
@ -159,13 +227,21 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy
|
|||
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+1));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+0));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
for ( i = 0; i < pcRes2->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes2->pCubes[i];
|
||||
assert( k == pcRes->nCubes );
|
||||
// create the resulting truth table
|
||||
Extra_TruthSharp( pTemp0, Var, uRes0, uRes1, Var + 1 );
|
||||
Extra_TruthOr( pTemp0, pTemp0, uRes2, Var + 1 );
|
||||
return pTemp0;
|
||||
Extra_TruthOr( pTemp0, puRes0, puRes2, Var );
|
||||
Extra_TruthOr( pTemp1, puRes1, puRes2, Var );
|
||||
// copy the table if needed
|
||||
nWords <<= 1;
|
||||
for ( i = 1; i < nWordsAll/nWords; i++ )
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
pTemp[i*nWords + k] = pTemp[k];
|
||||
// verify in the end
|
||||
// assert( Extra_TruthIsImply( puOn, pTemp, nVars ) );
|
||||
// assert( Extra_TruthIsImply( pTemp, puOnDc, nVars ) );
|
||||
return pTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -184,12 +260,11 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t
|
|||
unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
|
||||
Ivy_Sop_t cRes0, cRes1, cRes2;
|
||||
Ivy_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
|
||||
unsigned uRes0, uRes1, uRes2;
|
||||
unsigned uOn0, uOn1, uOnDc0, uOnDc1;
|
||||
unsigned uOn0, uOn1, uOnDc0, uOnDc1, uRes0, uRes1, uRes2;
|
||||
int i, k, Var;
|
||||
assert( nVars <= 5 );
|
||||
assert( uOn & ~uOnDc == 0 );
|
||||
if ( Extra_TruthIsConst0( uOn == 0 )
|
||||
assert( (uOn & ~uOnDc) == 0 );
|
||||
if ( uOn == 0 )
|
||||
{
|
||||
pcRes->nCubes = 0;
|
||||
pcRes->pCubes = NULL;
|
||||
|
|
@ -202,6 +277,7 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t
|
|||
pcRes->pCubes[0] = 0;
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
assert( nVars > 0 );
|
||||
// find the topmost var
|
||||
for ( Var = nVars-1; Var >= 0; Var-- )
|
||||
if ( Extra_TruthVarInSupport( &uOn, 5, Var ) ||
|
||||
|
|
@ -209,16 +285,16 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t
|
|||
break;
|
||||
assert( Var >= 0 );
|
||||
// cofactor
|
||||
uOn0 = uOn1 = uOn;
|
||||
uOn0 = uOn1 = uOn;
|
||||
uOnDc0 = uOnDc1 = uOnDc;
|
||||
Extra_TruthCofactor0( &uOn0, 5, Var );
|
||||
Extra_TruthCofactor1( &uOn1, 5, Var );
|
||||
Extra_TruthCofactor0( &uOnDc0, 5, Var );
|
||||
Extra_TruthCofactor1( &uOnDc1, 5, Var );
|
||||
Extra_TruthCofactor0( &uOn0, Var + 1, Var );
|
||||
Extra_TruthCofactor1( &uOn1, Var + 1, Var );
|
||||
Extra_TruthCofactor0( &uOnDc0, Var + 1, Var );
|
||||
Extra_TruthCofactor1( &uOnDc1, Var + 1, Var );
|
||||
// solve for cofactors
|
||||
uRes0 = Ivy_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var-1, pcRes0 );
|
||||
uRes1 = Ivy_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var-1, pcRes1 );
|
||||
uRes2 = Ivy_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var-1, pcRes2 );
|
||||
uRes0 = Ivy_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var, pcRes0 );
|
||||
uRes1 = Ivy_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var, pcRes1 );
|
||||
uRes2 = Ivy_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var, pcRes2 );
|
||||
// create the resulting cover
|
||||
pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes;
|
||||
pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * pcRes->nCubes );
|
||||
|
|
@ -227,10 +303,14 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t
|
|||
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+1));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+0));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
for ( i = 0; i < pcRes2->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes2->pCubes[i];
|
||||
assert( k == pcRes->nCubes );
|
||||
return (uRes0 & ~uMasks[Var]) | (uRes1 & uMasks[Var]) | uRes2;
|
||||
// derive the final truth table
|
||||
uRes2 |= (uRes0 & ~uMasks[Var]) | (uRes1 & uMasks[Var]);
|
||||
// assert( (uOn & ~uRes2) == 0 );
|
||||
// assert( (uRes2 & ~uOnDc) == 0 );
|
||||
return uRes2;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -109,9 +109,10 @@ int Ivy_ManCleanup( Ivy_Man_t * p )
|
|||
Ivy_Obj_t * pNode;
|
||||
int i, nNodesOld;
|
||||
nNodesOld = Ivy_ManNodeNum(p);
|
||||
Ivy_ManForEachNode( p, pNode, i )
|
||||
if ( Ivy_ObjRefs(pNode) == 0 )
|
||||
Ivy_ObjDelete_rec( p, pNode, 1 );
|
||||
Ivy_ManForEachObj( p, pNode, i )
|
||||
if ( Ivy_ObjIsNode(pNode) || Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) )
|
||||
if ( Ivy_ObjRefs(pNode) == 0 )
|
||||
Ivy_ObjDelete_rec( p, pNode, 1 );
|
||||
return nNodesOld - Ivy_ManNodeNum(p);
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ int Ivy_ManCleanup( Ivy_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManPropagateBuffers( Ivy_Man_t * p )
|
||||
int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel )
|
||||
{
|
||||
Ivy_Obj_t * pNode;
|
||||
int nSteps;
|
||||
|
|
@ -135,7 +136,7 @@ int Ivy_ManPropagateBuffers( Ivy_Man_t * p )
|
|||
pNode = Vec_PtrEntryLast(p->vBufs);
|
||||
while ( Ivy_ObjIsBuf(pNode) )
|
||||
pNode = Ivy_ObjReadFirstFanout( p, pNode );
|
||||
Ivy_NodeFixBufferFanins( p, pNode );
|
||||
Ivy_NodeFixBufferFanins( p, pNode, fUpdateLevel );
|
||||
}
|
||||
// printf( "Number of steps = %d\n", nSteps );
|
||||
return nSteps;
|
||||
|
|
@ -200,6 +201,9 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits )
|
|||
pObj = Ivy_ManPo( p, Ivy_ManPoNum(p) - nLatches + i );
|
||||
pLatch = Ivy_Latch( p, Ivy_ObjChild0(pObj), Init );
|
||||
Ivy_ObjDisconnect( p, pObj );
|
||||
// recycle the old PO object
|
||||
Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
|
||||
Ivy_ManRecycleMemory( p, pObj );
|
||||
// convert the corresponding PI to a buffer and connect it to the latch
|
||||
pObj = Ivy_ManPi( p, Ivy_ManPiNum(p) - nLatches + i );
|
||||
pObj->Type = IVY_BUF;
|
||||
|
|
@ -215,8 +219,21 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits )
|
|||
p->nObjs[IVY_PO] -= nLatches;
|
||||
p->nObjs[IVY_BUF] += nLatches;
|
||||
p->nDeleted -= 2 * nLatches;
|
||||
// remove dangling nodes
|
||||
Ivy_ManCleanup(p);
|
||||
/*
|
||||
// check for dangling nodes
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
if ( !Ivy_ObjIsPi(pObj) && !Ivy_ObjIsPo(pObj) && !Ivy_ObjIsConst1(pObj) )
|
||||
{
|
||||
assert( Ivy_ObjRefs(pObj) > 0 );
|
||||
assert( Ivy_ObjRefs(pObj) == Ivy_ObjFanoutNum(p, pObj) );
|
||||
}
|
||||
*/
|
||||
// perform hashing by propagating the buffers
|
||||
Ivy_ManPropagateBuffers( p );
|
||||
Ivy_ManPropagateBuffers( p, 0 );
|
||||
// fix the levels
|
||||
Ivy_ManResetLevels( p );
|
||||
// check the resulting network
|
||||
if ( !Ivy_ManCheck(p) )
|
||||
printf( "Ivy_ManMakeSeq(): The check has failed.\n" );
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop )
|
||||
void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel )
|
||||
{
|
||||
int nRefsOld;
|
||||
// the object to be replaced cannot be complemented
|
||||
|
|
@ -315,26 +315,32 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
|
|||
if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) )
|
||||
pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) );
|
||||
assert( !Ivy_IsComplement(pObjNew) );
|
||||
// if the new node's arrival time is different, recursively update arrival time of the fanouts
|
||||
if ( p->vFanouts && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level )
|
||||
if ( fUpdateLevel )
|
||||
{
|
||||
assert( Ivy_ObjIsNode(pObjOld) );
|
||||
pObjOld->Level = pObjNew->Level;
|
||||
Ivy_ObjUpdateLevel_rec( p, pObjOld );
|
||||
}
|
||||
// if the new node's required time has changed, recursively update required time of the fanins
|
||||
if ( p->vRequired )
|
||||
{
|
||||
int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id);
|
||||
if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) )
|
||||
// if the new node's arrival time is different, recursively update arrival time of the fanouts
|
||||
if ( p->vFanouts && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew );
|
||||
Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew );
|
||||
assert( Ivy_ObjIsNode(pObjOld) );
|
||||
pObjOld->Level = pObjNew->Level;
|
||||
Ivy_ObjUpdateLevel_rec( p, pObjOld );
|
||||
}
|
||||
// if the new node's required time has changed, recursively update required time of the fanins
|
||||
if ( p->vRequired )
|
||||
{
|
||||
int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id);
|
||||
if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew );
|
||||
Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew );
|
||||
}
|
||||
}
|
||||
}
|
||||
// delete the old object
|
||||
if ( fDeleteOld )
|
||||
Ivy_ObjDelete_rec( p, pObjOld, fFreeTop );
|
||||
// make sure object is pointing to itself
|
||||
assert( Ivy_ObjFanin0(pObjNew) == NULL || pObjOld != Ivy_ObjFanin0(pObjNew) );
|
||||
assert( Ivy_ObjFanin1(pObjNew) == NULL || pObjOld != Ivy_ObjFanin1(pObjNew) );
|
||||
// transfer the old object
|
||||
assert( Ivy_ObjRefs(pObjNew) == 0 );
|
||||
nRefsOld = pObjOld->nRefs;
|
||||
|
|
@ -370,7 +376,7 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode )
|
||||
void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel )
|
||||
{
|
||||
Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult;
|
||||
if ( Ivy_ObjIsPo(pNode) )
|
||||
|
|
@ -394,7 +400,7 @@ void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode )
|
|||
else
|
||||
assert( 0 );
|
||||
// perform the replacement
|
||||
Ivy_ObjReplace( p, pNode, pResult, 1, 0 );
|
||||
Ivy_ObjReplace( p, pNode, pResult, 1, 0, fUpdateLevel );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost )
|
|||
// the case of constant 0 cone
|
||||
if ( RetValue == -1 )
|
||||
{
|
||||
Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0 );
|
||||
Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0, 1 );
|
||||
continue;
|
||||
}
|
||||
assert( Vec_PtrSize(vLeaves) > 2 );
|
||||
|
|
@ -94,7 +94,7 @@ int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost )
|
|||
if ( Ivy_ObjLevel(Ivy_Regular(pResult)) > LevelR && Ivy_ObjRefs(Ivy_Regular(pResult)) == 0 )
|
||||
Ivy_ObjDelete_rec(Ivy_Regular(pResult), 1), CountUndo++;
|
||||
else
|
||||
Ivy_ObjReplace( pObj, pResult, 1, 0 ), CountUsed++;
|
||||
Ivy_ObjReplace( pObj, pResult, 1, 0, 1 ), CountUsed++;
|
||||
}
|
||||
printf( "Used = %d. Undo = %d.\n", CountUsed, CountUndo );
|
||||
Vec_PtrFree( vFront );
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums );
|
||||
static int Ivy_NodeMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
static int Ivy_NodeRewrite( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost );
|
||||
static Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut,
|
||||
static Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot,
|
||||
Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth );
|
||||
|
||||
static int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax );
|
||||
|
|
@ -74,7 +73,7 @@ int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fV
|
|||
Ivy_ManForEachNode( p, pNode, i )
|
||||
{
|
||||
// fix the fanin buffer problem
|
||||
Ivy_NodeFixBufferFanins( p, pNode );
|
||||
Ivy_NodeFixBufferFanins( p, pNode, 1 );
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
continue;
|
||||
// stop if all nodes have been tried once
|
||||
|
|
@ -120,8 +119,8 @@ Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart );
|
|||
// fix the levels
|
||||
if ( fUpdateLevel )
|
||||
Vec_IntFree( p->vRequired ), p->vRequired = NULL;
|
||||
// else
|
||||
// Ivy_ManResetLevels( p );
|
||||
else
|
||||
Ivy_ManResetLevels( p );
|
||||
// check
|
||||
if ( i = Ivy_ManCleanup(p) )
|
||||
printf( "Cleanup after rewriting removed %d dangling nodes.\n", i );
|
||||
|
|
@ -182,7 +181,11 @@ clk = clock();
|
|||
if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, pCut->pArray[i]) ) )
|
||||
break;
|
||||
if ( i != pCut->nSize )
|
||||
{
|
||||
p->nCutsBad++;
|
||||
continue;
|
||||
}
|
||||
p->nCutsGood++;
|
||||
// get the fanin permutation
|
||||
clk2 = clock();
|
||||
uTruth = 0xFFFF & Ivy_NodeGetTruth( pNode, pCut->pArray, pCut->nSize ); // truth table
|
||||
|
|
@ -211,7 +214,7 @@ clk2 = clock();
|
|||
Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
|
||||
// label MFFC with current ID
|
||||
Ivy_ManIncrementTravId( pMan );
|
||||
nNodesSaved = Ivy_NodeMffcLabel( pMan, pNode );
|
||||
nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode );
|
||||
// unmark the fanin boundary
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
|
||||
|
|
@ -219,7 +222,7 @@ p->timeMffc += clock() - clk2;
|
|||
|
||||
// evaluate the cut
|
||||
clk2 = clock();
|
||||
pGraph = Rwt_CutEvaluate( pMan, p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth );
|
||||
pGraph = Rwt_CutEvaluate( pMan, p, pNode, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth );
|
||||
p->timeEval += clock() - clk2;
|
||||
|
||||
// check if the cut is better than the current best one
|
||||
|
|
@ -289,75 +292,6 @@ p->timeRes += clock() - clk;
|
|||
return GainBest;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [References/references the node and returns MFFC size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel )
|
||||
{
|
||||
Ivy_Obj_t * pNode0, * pNode1;
|
||||
int Counter;
|
||||
// label visited nodes
|
||||
if ( fLabel )
|
||||
Ivy_ObjSetTravIdCurrent( p, pNode );
|
||||
// skip the CI
|
||||
if ( Ivy_ObjIsCi(pNode) )
|
||||
return 0;
|
||||
assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) );
|
||||
// process the internal node
|
||||
pNode0 = Ivy_ObjFanin0(pNode);
|
||||
pNode1 = Ivy_ObjFanin1(pNode);
|
||||
Counter = Ivy_ObjIsNode(pNode);
|
||||
if ( fReference )
|
||||
{
|
||||
if ( pNode0->nRefs++ == 0 )
|
||||
Counter += Ivy_NodeRefDeref( p, pNode0, fReference, fLabel );
|
||||
if ( pNode1 && pNode1->nRefs++ == 0 )
|
||||
Counter += Ivy_NodeRefDeref( p, pNode1, fReference, fLabel );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( pNode0->nRefs > 0 );
|
||||
assert( pNode1 == NULL || pNode1->nRefs > 0 );
|
||||
if ( --pNode0->nRefs == 0 )
|
||||
Counter += Ivy_NodeRefDeref( p, pNode0, fReference, fLabel );
|
||||
if ( pNode1 && --pNode1->nRefs == 0 )
|
||||
Counter += Ivy_NodeRefDeref( p, pNode1, fReference, fLabel );
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the size of MFFC and labels nodes with the current TravId.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode )
|
||||
{
|
||||
int nConeSize1, nConeSize2;
|
||||
assert( !Ivy_IsComplement( pNode ) );
|
||||
assert( Ivy_ObjIsNode( pNode ) );
|
||||
nConeSize1 = Ivy_NodeRefDeref( p, pNode, 0, 1 ); // dereference
|
||||
nConeSize2 = Ivy_NodeRefDeref( p, pNode, 1, 0 ); // reference
|
||||
assert( nConeSize1 == nConeSize2 );
|
||||
assert( nConeSize1 > 0 );
|
||||
return nConeSize1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table.]
|
||||
|
|
@ -418,7 +352,7 @@ unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth )
|
||||
Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth )
|
||||
{
|
||||
Vec_Ptr_t * vSubgraphs;
|
||||
Dec_Graph_t * pGraphBest, * pGraphCur;
|
||||
|
|
@ -596,12 +530,12 @@ void Ivy_GraphUpdateNetwork( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGr
|
|||
printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) );
|
||||
printf( " " );
|
||||
*/
|
||||
Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0 );
|
||||
Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 1 );
|
||||
// compare the gains
|
||||
nNodesNew = Ivy_ManNodeNum(p);
|
||||
assert( nGain <= nNodesOld - nNodesNew );
|
||||
// propagate the buffer
|
||||
Ivy_ManPropagateBuffers( p );
|
||||
Ivy_ManPropagateBuffers( p, 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -649,7 +583,7 @@ void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pG
|
|||
printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) );
|
||||
printf( " " );
|
||||
*/
|
||||
Ivy_ObjReplace( p, pRoot, pRootNew, 0, 0 );
|
||||
Ivy_ObjReplace( p, pRoot, pRootNew, 0, 0, 1 );
|
||||
//printf( "Replace = %d. ", Ivy_ManNodeNum(p) );
|
||||
|
||||
// delete remaining dangling nodes
|
||||
|
|
|
|||
|
|
@ -13,23 +13,323 @@
|
|||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
|
||||
Revision [$Id: ivySeq.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
#include "deco.h"
|
||||
#include "rwt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUseZeroCost );
|
||||
static void Ivy_GraphPrepare( Dec_Graph_t * pGraph, Ivy_Cut_t * pCut, Vec_Ptr_t * vFanins, char * pPerm );
|
||||
static unsigned Ivy_CutGetTruth( Ivy_Man_t * p, Ivy_Obj_t * pObj, int * pNums, int nNums );
|
||||
static Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, char * pPerm, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int * pGainBest, unsigned uTruth );
|
||||
static int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax );
|
||||
static Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph );
|
||||
static void Ivy_GraphUpdateNetworkSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain );
|
||||
static Ivy_Store_t * Ivy_CutComputeForNode( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves );
|
||||
|
||||
static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs incremental rewriting of the AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose )
|
||||
{
|
||||
Rwt_Man_t * pManRwt;
|
||||
Ivy_Obj_t * pNode;
|
||||
int i, nNodes, nGain;
|
||||
int clk, clkStart = clock();
|
||||
// start the rewriting manager
|
||||
pManRwt = Rwt_ManStart( 0 );
|
||||
p->pData = pManRwt;
|
||||
if ( pManRwt == NULL )
|
||||
return 0;
|
||||
// create fanouts
|
||||
if ( p->vFanouts == NULL )
|
||||
Ivy_ManStartFanout( p );
|
||||
// resynthesize each node once
|
||||
nNodes = Ivy_ManObjIdMax(p);
|
||||
Ivy_ManForEachNode( p, pNode, i )
|
||||
{
|
||||
assert( !Ivy_ObjIsBuf(pNode) );
|
||||
assert( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) );
|
||||
assert( !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) );
|
||||
// fix the fanin buffer problem
|
||||
// Ivy_NodeFixBufferFanins( p, pNode );
|
||||
// if ( Ivy_ObjIsBuf(pNode) )
|
||||
// continue;
|
||||
// stop if all nodes have been tried once
|
||||
if ( i > nNodes )
|
||||
break;
|
||||
if ( i == 8648 )
|
||||
{
|
||||
int x = 0;
|
||||
}
|
||||
// for each cut, try to resynthesize it
|
||||
nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost );
|
||||
if ( nGain > 0 || nGain == 0 && fUseZeroCost )
|
||||
{
|
||||
Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt);
|
||||
int fCompl = Rwt_ManReadCompl(pManRwt);
|
||||
// complement the FF if needed
|
||||
clk = clock();
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
Ivy_GraphUpdateNetworkSeq( p, pNode, pGraph, nGain );
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
Rwt_ManAddTimeUpdate( pManRwt, clock() - clk );
|
||||
/*
|
||||
if ( !Ivy_ManIsAcyclic(p) )
|
||||
{
|
||||
int x = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart );
|
||||
// print stats
|
||||
if ( fVerbose )
|
||||
Rwt_ManPrintStats( pManRwt );
|
||||
// delete the managers
|
||||
Rwt_ManStop( pManRwt );
|
||||
p->pData = NULL;
|
||||
// fix the levels
|
||||
Ivy_ManResetLevels( p );
|
||||
// check
|
||||
if ( !Ivy_ManCheck(p) )
|
||||
printf( "Ivy_ManRewritePre(): The check has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs rewriting for one node.]
|
||||
|
||||
Description [This procedure considers all the cuts computed for the node
|
||||
and tries to rewrite each of them using the "forest" of different AIG
|
||||
structures precomputed and stored in the RWR manager.
|
||||
Determines the best rewriting and computes the gain in the number of AIG
|
||||
nodes in the final network. In the end, p->vFanins contains information
|
||||
about the best cut that can be used for rewriting, while p->pGraph gives
|
||||
the decomposition dag (represented using decomposition graph data structure).
|
||||
Returns gain in the number of nodes or -1 if node cannot be rewritten.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUseZeroCost )
|
||||
{
|
||||
int fVeryVerbose = 0;
|
||||
Dec_Graph_t * pGraph;
|
||||
Ivy_Store_t * pStore;
|
||||
Ivy_Cut_t * pCut;
|
||||
Ivy_Obj_t * pFanin;
|
||||
unsigned uPhase, uTruthBest, uTruth;
|
||||
char * pPerm;
|
||||
int nNodesSaved, nNodesSaveCur;
|
||||
int i, c, GainCur, GainBest = -1;
|
||||
int clk, clk2;
|
||||
|
||||
p->nNodesConsidered++;
|
||||
// get the node's cuts
|
||||
clk = clock();
|
||||
pStore = Ivy_CutComputeForNode( pMan, pNode, 5 );
|
||||
p->timeCut += clock() - clk;
|
||||
|
||||
// go through the cuts
|
||||
clk = clock();
|
||||
for ( c = 1; c < pStore->nCuts; c++ )
|
||||
{
|
||||
pCut = pStore->pCuts + c;
|
||||
// consider only 4-input cuts
|
||||
if ( pCut->nSize != 4 )
|
||||
continue;
|
||||
// skip the cuts with buffers
|
||||
for ( i = 0; i < (int)pCut->nSize; i++ )
|
||||
if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, Ivy_LeafId(pCut->pArray[i])) ) )
|
||||
break;
|
||||
if ( i != pCut->nSize )
|
||||
{
|
||||
p->nCutsBad++;
|
||||
continue;
|
||||
}
|
||||
p->nCutsGood++;
|
||||
// get the fanin permutation
|
||||
clk2 = clock();
|
||||
uTruth = 0xFFFF & Ivy_CutGetTruth( pMan, pNode, pCut->pArray, pCut->nSize ); // truth table
|
||||
p->timeTruth += clock() - clk2;
|
||||
pPerm = p->pPerms4[ p->pPerms[uTruth] ];
|
||||
uPhase = p->pPhases[uTruth];
|
||||
// collect fanins with the corresponding permutation/phase
|
||||
Vec_PtrClear( p->vFaninsCur );
|
||||
Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 );
|
||||
for ( i = 0; i < (int)pCut->nSize; i++ )
|
||||
{
|
||||
pFanin = Ivy_ManObj( pMan, Ivy_LeafId( pCut->pArray[pPerm[i]] ) );
|
||||
assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) || Ivy_ObjIsConst1(pFanin) );
|
||||
pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) );
|
||||
Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
|
||||
}
|
||||
clk2 = clock();
|
||||
// mark the fanin boundary
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
|
||||
// label MFFC with current ID
|
||||
Ivy_ManIncrementTravId( pMan );
|
||||
nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode );
|
||||
// unmark the fanin boundary
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
|
||||
p->timeMffc += clock() - clk2;
|
||||
/*
|
||||
if ( pNode->Id == 8648 )
|
||||
{
|
||||
int i;
|
||||
printf( "Trying cut : {" );
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
|
||||
// printf( " }\n" );
|
||||
printf( " } " );
|
||||
Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" );
|
||||
}
|
||||
*/
|
||||
|
||||
// evaluate the cut
|
||||
clk2 = clock();
|
||||
pGraph = Rwt_CutEvaluateSeq( pMan, p, pNode, pCut, pPerm, p->vFaninsCur, nNodesSaved, &GainCur, uTruth );
|
||||
p->timeEval += clock() - clk2;
|
||||
|
||||
|
||||
// check if the cut is better than the current best one
|
||||
if ( pGraph != NULL && GainBest < GainCur )
|
||||
{
|
||||
// save this form
|
||||
nNodesSaveCur = nNodesSaved;
|
||||
GainBest = GainCur;
|
||||
p->pGraph = pGraph;
|
||||
p->pCut = pCut;
|
||||
p->pPerm = pPerm;
|
||||
p->fCompl = ((uPhase & (1<<4)) > 0);
|
||||
uTruthBest = uTruth;
|
||||
// collect fanins in the
|
||||
Vec_PtrClear( p->vFanins );
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Vec_PtrPush( p->vFanins, pFanin );
|
||||
}
|
||||
}
|
||||
p->timeRes += clock() - clk;
|
||||
|
||||
if ( GainBest == -1 )
|
||||
return -1;
|
||||
|
||||
// copy the leaves
|
||||
Ivy_GraphPrepare( p->pGraph, p->pCut, p->vFanins, p->pPerm );
|
||||
|
||||
p->nScores[p->pMap[uTruthBest]]++;
|
||||
p->nNodesGained += GainBest;
|
||||
if ( fUseZeroCost || GainBest > 0 )
|
||||
p->nNodesRewritten++;
|
||||
|
||||
/*
|
||||
if ( GainBest > 0 )
|
||||
{
|
||||
Ivy_Cut_t * pCut = p->pCut;
|
||||
printf( "Useful cut : {" );
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
printf( " %5d[%2d](%2d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]),
|
||||
Ivy_ObjRefs( Ivy_ManObj(pMan, Ivy_LeafId(pCut->pArray[i])) ) );
|
||||
printf( " }\n" );
|
||||
}
|
||||
*/
|
||||
|
||||
// report the progress
|
||||
if ( fVeryVerbose && GainBest > 0 )
|
||||
{
|
||||
printf( "Node %6d : ", Ivy_ObjId(pNode) );
|
||||
printf( "Fanins = %d. ", p->vFanins->nSize );
|
||||
printf( "Save = %d. ", nNodesSaveCur );
|
||||
printf( "Add = %d. ", nNodesSaveCur-GainBest );
|
||||
printf( "GAIN = %d. ", GainBest );
|
||||
printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 );
|
||||
printf( "Class = %d. ", p->pMap[uTruthBest] );
|
||||
printf( "\n" );
|
||||
}
|
||||
return GainBest;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Evaluates the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, char * pPerm, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int * pGainBest, unsigned uTruth )
|
||||
{
|
||||
Vec_Ptr_t * vSubgraphs;
|
||||
Dec_Graph_t * pGraphBest, * pGraphCur;
|
||||
Rwt_Node_t * pNode;
|
||||
int nNodesAdded, GainBest, i;
|
||||
// find the matching class of subgraphs
|
||||
vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] );
|
||||
p->nSubgraphs += vSubgraphs->nSize;
|
||||
// determine the best subgraph
|
||||
GainBest = -1;
|
||||
Vec_PtrForEachEntry( vSubgraphs, pNode, i )
|
||||
{
|
||||
// get the current graph
|
||||
pGraphCur = (Dec_Graph_t *)pNode->pNext;
|
||||
|
||||
// if ( pRoot->Id == 8648 )
|
||||
// Dec_GraphPrint( stdout, pGraphCur, NULL, NULL );
|
||||
// copy the leaves
|
||||
// Vec_PtrForEachEntry( vFaninsCur, pFanin, k )
|
||||
// Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
|
||||
Ivy_GraphPrepare( pGraphCur, pCut, vFaninsCur, pPerm );
|
||||
|
||||
// detect how many unlabeled nodes will be reused
|
||||
nNodesAdded = Ivy_GraphToNetworkSeqCountSeq( pMan, pRoot, pGraphCur, nNodesSaved );
|
||||
if ( nNodesAdded == -1 )
|
||||
continue;
|
||||
assert( nNodesSaved >= nNodesAdded );
|
||||
// count the gain at this node
|
||||
if ( GainBest < nNodesSaved - nNodesAdded )
|
||||
{
|
||||
GainBest = nNodesSaved - nNodesAdded;
|
||||
pGraphBest = pGraphCur;
|
||||
}
|
||||
}
|
||||
if ( GainBest == -1 )
|
||||
return NULL;
|
||||
*pGainBest = GainBest;
|
||||
return pGraphBest;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -41,6 +341,182 @@ static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_GraphPrepare( Dec_Graph_t * pGraph, Ivy_Cut_t * pCut, Vec_Ptr_t * vFanins, char * pPerm )
|
||||
{
|
||||
Dec_Node_t * pNode, * pNode0, * pNode1;
|
||||
int i;
|
||||
assert( Dec_GraphLeaveNum(pGraph) == pCut->nSize );
|
||||
assert( Vec_PtrSize(vFanins) == pCut->nSize );
|
||||
// label the leaves with latch numbers
|
||||
Dec_GraphForEachLeaf( pGraph, pNode, i )
|
||||
{
|
||||
pNode->pFunc = Vec_PtrEntry( vFanins, i );
|
||||
pNode->nLat2 = Ivy_LeafLat( pCut->pArray[pPerm[i]] );
|
||||
}
|
||||
// propagate latches through the nodes
|
||||
Dec_GraphForEachNode( pGraph, pNode, i )
|
||||
{
|
||||
// get the children of this node
|
||||
pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node );
|
||||
pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node );
|
||||
// distribute the latches
|
||||
pNode->nLat2 = IVY_MIN( pNode0->nLat2, pNode1->nLat2 );
|
||||
pNode->nLat0 = pNode0->nLat2 - pNode->nLat2;
|
||||
pNode->nLat1 = pNode1->nLat2 - pNode->nLat2;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of new nodes added when using this graph.]
|
||||
|
||||
Description [AIG nodes for the fanins should be assigned to pNode->pFunc
|
||||
of the leaves of the graph before calling this procedure.
|
||||
Returns -1 if the number of nodes and levels exceeded the given limit or
|
||||
the number of levels exceeded the maximum allowed level.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax )
|
||||
{
|
||||
Dec_Node_t * pNode, * pNode0, * pNode1;
|
||||
Ivy_Obj_t * pAnd, * pAnd0, * pAnd1;
|
||||
int i, k, Counter, fCompl;
|
||||
// check for constant function or a literal
|
||||
if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) )
|
||||
return 0;
|
||||
// compute the AIG size after adding the internal nodes
|
||||
Counter = 0;
|
||||
Dec_GraphForEachNode( pGraph, pNode, i )
|
||||
{
|
||||
// get the children of this node
|
||||
pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node );
|
||||
pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node );
|
||||
// get the AIG nodes corresponding to the children
|
||||
pAnd0 = pNode0->pFunc;
|
||||
pAnd1 = pNode1->pFunc;
|
||||
// skip the latches
|
||||
for ( k = 0; pAnd0 && k < (int)pNode->nLat0; k++ )
|
||||
{
|
||||
fCompl = Ivy_IsComplement(pAnd0);
|
||||
pAnd0 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd0), NULL, IVY_LATCH, IVY_INIT_DC) );
|
||||
if ( pAnd0 )
|
||||
pAnd0 = Ivy_NotCond( pAnd0, fCompl );
|
||||
}
|
||||
for ( k = 0; pAnd1 && k < (int)pNode->nLat1; k++ )
|
||||
{
|
||||
fCompl = Ivy_IsComplement(pAnd1);
|
||||
pAnd1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd1), NULL, IVY_LATCH, IVY_INIT_DC) );
|
||||
if ( pAnd1 )
|
||||
pAnd1 = Ivy_NotCond( pAnd1, fCompl );
|
||||
}
|
||||
// get the new node
|
||||
if ( pAnd0 && pAnd1 )
|
||||
{
|
||||
// if they are both present, find the resulting node
|
||||
pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl );
|
||||
pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl );
|
||||
assert( !Ivy_ObjIsLatch(Ivy_Regular(pAnd0)) || !Ivy_ObjIsLatch(Ivy_Regular(pAnd1)) );
|
||||
if ( Ivy_Regular(pAnd0) == Ivy_Regular(pAnd1) || Ivy_ObjIsConst1(Ivy_Regular(pAnd0)) || Ivy_ObjIsConst1(Ivy_Regular(pAnd1)) )
|
||||
pAnd = Ivy_And( p, pAnd0, pAnd1 );
|
||||
else
|
||||
pAnd = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) );
|
||||
// return -1 if the node is the same as the original root
|
||||
if ( Ivy_Regular(pAnd) == pRoot )
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
pAnd = NULL;
|
||||
// count the number of added nodes
|
||||
if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(p, Ivy_Regular(pAnd)) )
|
||||
{
|
||||
if ( ++Counter > NodeMax )
|
||||
return -1;
|
||||
}
|
||||
pNode->pFunc = pAnd;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transforms the decomposition graph into the AIG.]
|
||||
|
||||
Description [AIG nodes for the fanins should be assigned to pNode->pFunc
|
||||
of the leaves of the graph before calling this procedure.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph )
|
||||
{
|
||||
Ivy_Obj_t * pAnd0, * pAnd1;
|
||||
Dec_Node_t * pNode;
|
||||
int i, k;
|
||||
// check for constant function
|
||||
if ( Dec_GraphIsConst(pGraph) )
|
||||
return Ivy_NotCond( Ivy_ManConst1(p), Dec_GraphIsComplement(pGraph) );
|
||||
// check for a literal
|
||||
if ( Dec_GraphIsVar(pGraph) )
|
||||
{
|
||||
// get the variable node
|
||||
pNode = Dec_GraphVar(pGraph);
|
||||
// add the remaining latches
|
||||
for ( k = 0; k < (int)pNode->nLat2; k++ )
|
||||
pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC );
|
||||
return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
|
||||
}
|
||||
// build the AIG nodes corresponding to the AND gates of the graph
|
||||
Dec_GraphForEachNode( pGraph, pNode, i )
|
||||
{
|
||||
pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
|
||||
pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
|
||||
// add the latches
|
||||
for ( k = 0; k < (int)pNode->nLat0; k++ )
|
||||
pAnd0 = Ivy_Latch( p, pAnd0, IVY_INIT_DC );
|
||||
for ( k = 0; k < (int)pNode->nLat1; k++ )
|
||||
pAnd1 = Ivy_Latch( p, pAnd1, IVY_INIT_DC );
|
||||
// create the node
|
||||
pNode->pFunc = Ivy_And( p, pAnd0, pAnd1 );
|
||||
}
|
||||
// add the remaining latches
|
||||
for ( k = 0; k < (int)pNode->nLat2; k++ )
|
||||
pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC );
|
||||
// complement the result if necessary
|
||||
return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Replaces MFFC of the node by the new factored form.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_GraphUpdateNetworkSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain )
|
||||
{
|
||||
Ivy_Obj_t * pRootNew;
|
||||
int nNodesNew, nNodesOld;
|
||||
nNodesOld = Ivy_ManNodeNum(p);
|
||||
// create the new structure of nodes
|
||||
pRootNew = Ivy_GraphToNetworkSeq( p, pGraph );
|
||||
Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 0 );
|
||||
// compare the gains
|
||||
nNodesNew = Ivy_ManNodeNum(p);
|
||||
assert( nGain <= nNodesOld - nNodesNew );
|
||||
// propagate the buffer
|
||||
Ivy_ManPropagateBuffers( p, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -48,6 +524,94 @@ static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Ivy_CutGetTruth_rec( Ivy_Man_t * p, int Leaf, int * pNums, int nNums )
|
||||
{
|
||||
static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
|
||||
unsigned uTruth0, uTruth1;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
for ( i = 0; i < nNums; i++ )
|
||||
if ( Leaf == pNums[i] )
|
||||
return uMasks[i];
|
||||
pObj = Ivy_ManObj( p, Ivy_LeafId(Leaf) );
|
||||
if ( Ivy_ObjIsLatch(pObj) )
|
||||
{
|
||||
assert( !Ivy_ObjFaninC0(pObj) );
|
||||
Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) + 1 );
|
||||
return Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
|
||||
}
|
||||
assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) );
|
||||
Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) );
|
||||
uTruth0 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
|
||||
if ( Ivy_ObjFaninC0(pObj) )
|
||||
uTruth0 = ~uTruth0;
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
return uTruth0;
|
||||
Leaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pObj), Ivy_LeafLat(Leaf) );
|
||||
uTruth1 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
|
||||
if ( Ivy_ObjFaninC1(pObj) )
|
||||
uTruth1 = ~uTruth1;
|
||||
return uTruth0 & uTruth1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Ivy_CutGetTruth( Ivy_Man_t * p, Ivy_Obj_t * pObj, int * pNums, int nNums )
|
||||
{
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
assert( nNums < 6 );
|
||||
return Ivy_CutGetTruth_rec( p, Ivy_LeafCreate(pObj->Id, 0), pNums, nNums );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_CutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 )
|
||||
{
|
||||
int i;
|
||||
if ( pCut->nSize < pCut->nSizeMax )
|
||||
return 1;
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives new cut.]
|
||||
|
|
@ -59,7 +623,7 @@ static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
|
||||
static inline int Ivy_CutDeriveNew2( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
|
||||
{
|
||||
unsigned uHash = 0;
|
||||
int i, k;
|
||||
|
|
@ -124,6 +688,130 @@ static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int I
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives new cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
|
||||
{
|
||||
unsigned uHash = 0;
|
||||
int i, k;
|
||||
assert( pCut->nSize > 0 );
|
||||
assert( IdNew0 < IdNew1 );
|
||||
for ( i = k = 0; i < pCut->nSize; i++ )
|
||||
{
|
||||
if ( pCut->pArray[i] == IdOld )
|
||||
continue;
|
||||
if ( IdNew0 <= pCut->pArray[i] )
|
||||
{
|
||||
if ( IdNew0 < pCut->pArray[i] )
|
||||
{
|
||||
pCutNew->pArray[ k++ ] = IdNew0;
|
||||
uHash |= Ivy_CutHashValue( IdNew0 );
|
||||
}
|
||||
IdNew0 = 0x7FFFFFFF;
|
||||
}
|
||||
if ( IdNew1 <= pCut->pArray[i] )
|
||||
{
|
||||
if ( IdNew1 < pCut->pArray[i] )
|
||||
{
|
||||
pCutNew->pArray[ k++ ] = IdNew1;
|
||||
uHash |= Ivy_CutHashValue( IdNew1 );
|
||||
}
|
||||
IdNew1 = 0x7FFFFFFF;
|
||||
}
|
||||
pCutNew->pArray[ k++ ] = pCut->pArray[i];
|
||||
uHash |= Ivy_CutHashValue( pCut->pArray[i] );
|
||||
}
|
||||
if ( IdNew0 < 0x7FFFFFFF )
|
||||
{
|
||||
pCutNew->pArray[ k++ ] = IdNew0;
|
||||
uHash |= Ivy_CutHashValue( IdNew0 );
|
||||
}
|
||||
if ( IdNew1 < 0x7FFFFFFF )
|
||||
{
|
||||
pCutNew->pArray[ k++ ] = IdNew1;
|
||||
uHash |= Ivy_CutHashValue( IdNew1 );
|
||||
}
|
||||
pCutNew->nSize = k;
|
||||
pCutNew->uHash = uHash;
|
||||
assert( pCutNew->nSize <= pCut->nSizeMax );
|
||||
// for ( i = 1; i < pCutNew->nSize; i++ )
|
||||
// assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the hash value of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Ivy_NodeCutHash( Ivy_Cut_t * pCut )
|
||||
{
|
||||
int i;
|
||||
pCut->uHash = 0;
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
pCut->uHash |= (1 << (pCut->pArray[i] % 31));
|
||||
return pCut->uHash;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives new cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_CutDeriveNew3( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
|
||||
{
|
||||
int i, k;
|
||||
assert( pCut->nSize > 0 );
|
||||
assert( IdNew0 < IdNew1 );
|
||||
for ( i = k = 0; i < pCut->nSize; i++ )
|
||||
{
|
||||
if ( pCut->pArray[i] == IdOld )
|
||||
continue;
|
||||
if ( IdNew0 <= pCut->pArray[i] )
|
||||
{
|
||||
if ( IdNew0 < pCut->pArray[i] )
|
||||
pCutNew->pArray[ k++ ] = IdNew0;
|
||||
IdNew0 = 0x7FFFFFFF;
|
||||
}
|
||||
if ( IdNew1 <= pCut->pArray[i] )
|
||||
{
|
||||
if ( IdNew1 < pCut->pArray[i] )
|
||||
pCutNew->pArray[ k++ ] = IdNew1;
|
||||
IdNew1 = 0x7FFFFFFF;
|
||||
}
|
||||
pCutNew->pArray[ k++ ] = pCut->pArray[i];
|
||||
}
|
||||
if ( IdNew0 < 0x7FFFFFFF )
|
||||
pCutNew->pArray[ k++ ] = IdNew0;
|
||||
if ( IdNew1 < 0x7FFFFFFF )
|
||||
pCutNew->pArray[ k++ ] = IdNew1;
|
||||
pCutNew->nSize = k;
|
||||
assert( pCutNew->nSize <= pCut->nSizeMax );
|
||||
Ivy_NodeCutHash( pCutNew );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if pDom is contained in pCut.]
|
||||
|
|
@ -295,9 +983,12 @@ void Ivy_CutPrintForNodes( Ivy_Store_t * pCutStore )
|
|||
***********************************************************************/
|
||||
static inline int Ivy_CutReadLeaf( Ivy_Obj_t * pFanin )
|
||||
{
|
||||
int iLeaf;
|
||||
assert( !Ivy_IsComplement(pFanin) );
|
||||
if ( !Ivy_ObjIsLatch(pFanin) )
|
||||
return Ivy_LeafCreate( pFanin->Id, 0 );
|
||||
iLeaf = Ivy_CutReadLeaf( Ivy_ObjFanin0(pFanin) );
|
||||
assert( Ivy_LeafLat(iLeaf) < IVY_LEAF_MASK );
|
||||
return 1 + Ivy_CutReadLeaf( Ivy_ObjFanin0(pFanin) );
|
||||
}
|
||||
|
||||
|
|
@ -345,13 +1036,20 @@ Ivy_Store_t * Ivy_CutComputeForNode( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeave
|
|||
for ( k = 0; k < pCut->nSize; k++ )
|
||||
{
|
||||
pLeaf = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[k]) );
|
||||
if ( Ivy_ObjIsCi(pLeaf) )
|
||||
if ( Ivy_ObjIsCi(pLeaf) || Ivy_ObjIsConst1(pLeaf) )
|
||||
continue;
|
||||
assert( Ivy_ObjIsNode(pLeaf) );
|
||||
nLats = Ivy_LeafLat(pCut->pArray[k]);
|
||||
|
||||
// get the fanins fanins
|
||||
iLeaf0 = nLats + Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) );
|
||||
iLeaf1 = nLats + Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) );
|
||||
iLeaf0 = Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) );
|
||||
iLeaf1 = Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) );
|
||||
assert( nLats + Ivy_LeafLat(iLeaf0) < IVY_LEAF_MASK && nLats + Ivy_LeafLat(iLeaf1) < IVY_LEAF_MASK );
|
||||
iLeaf0 = nLats + iLeaf0;
|
||||
iLeaf1 = nLats + iLeaf1;
|
||||
if ( !Ivy_CutPrescreen( pCut, iLeaf0, iLeaf1 ) )
|
||||
continue;
|
||||
// the given cut exist
|
||||
if ( iLeaf0 > iLeaf1 )
|
||||
Temp = iLeaf0, iLeaf0 = iLeaf1, iLeaf1 = Temp;
|
||||
// create the new cut
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
|||
return NULL;
|
||||
assert( Ivy_ObjIsLatch(pObj) || Ivy_ObjFaninId0(pObj) > 0 );
|
||||
assert( Ivy_ObjFaninId1(pObj) == 0 || Ivy_ObjFaninId0(pObj) < Ivy_ObjFaninId1(pObj) );
|
||||
// if ( Ivy_ObjFanin0(pObj)->nRefs == 0 || (!Ivy_ObjIsLatch(pObj) && Ivy_ObjFanin1(pObj)->nRefs == 0) )
|
||||
// return NULL;
|
||||
if ( Ivy_ObjFanin0(pObj)->nRefs == 0 || (Ivy_ObjChild1(pObj) && Ivy_ObjFanin1(pObj)->nRefs == 0) )
|
||||
return NULL;
|
||||
for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
|
||||
{
|
||||
pEntry = Ivy_ManObj( p, p->pTable[i] );
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ int Ivy_ManLevels( Ivy_Man_t * p )
|
|||
***********************************************************************/
|
||||
int Ivy_ManResetLevels_rec( Ivy_Obj_t * pObj )
|
||||
{
|
||||
if ( pObj->Level || Ivy_ObjIsCi(pObj) )
|
||||
if ( pObj->Level || Ivy_ObjIsCi(pObj) || Ivy_ObjIsConst1(pObj) )
|
||||
return pObj->Level;
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
return pObj->Level = Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) );
|
||||
|
|
@ -292,10 +292,79 @@ void Ivy_ManResetLevels( Ivy_Man_t * p )
|
|||
int i;
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
pObj->Level = 0;
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
Ivy_ManForEachCo( p, pObj, i )
|
||||
Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [References/references the node and returns MFFC size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ObjRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel )
|
||||
{
|
||||
Ivy_Obj_t * pNode0, * pNode1;
|
||||
int Counter;
|
||||
// label visited nodes
|
||||
if ( fLabel )
|
||||
Ivy_ObjSetTravIdCurrent( p, pNode );
|
||||
// skip the CI
|
||||
if ( Ivy_ObjIsPi(pNode) )
|
||||
return 0;
|
||||
assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) || Ivy_ObjIsLatch(pNode) );
|
||||
// process the internal node
|
||||
pNode0 = Ivy_ObjFanin0(pNode);
|
||||
pNode1 = Ivy_ObjFanin1(pNode);
|
||||
Counter = Ivy_ObjIsNode(pNode);
|
||||
if ( fReference )
|
||||
{
|
||||
if ( pNode0->nRefs++ == 0 )
|
||||
Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel );
|
||||
if ( pNode1 && pNode1->nRefs++ == 0 )
|
||||
Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( pNode0->nRefs > 0 );
|
||||
assert( pNode1 == NULL || pNode1->nRefs > 0 );
|
||||
if ( --pNode0->nRefs == 0 )
|
||||
Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel );
|
||||
if ( pNode1 && --pNode1->nRefs == 0 )
|
||||
Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel );
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Labels MFFC with the current label.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode )
|
||||
{
|
||||
int nConeSize1, nConeSize2;
|
||||
assert( !Ivy_IsComplement( pNode ) );
|
||||
assert( Ivy_ObjIsNode( pNode ) );
|
||||
nConeSize1 = Ivy_ObjRefDeref( p, pNode, 0, 1 ); // dereference
|
||||
nConeSize2 = Ivy_ObjRefDeref( p, pNode, 1, 0 ); // reference
|
||||
assert( nConeSize1 == nConeSize2 );
|
||||
assert( nConeSize1 > 0 );
|
||||
return nConeSize1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively updates fanout levels.]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ SRC += src/temp/ivy/ivyBalance.c \
|
|||
src/temp/ivy/ivyDfs.c \
|
||||
src/temp/ivy/ivyDsd.c \
|
||||
src/temp/ivy/ivyFanout.c \
|
||||
src/temp/ivy/ivyIsop.c \
|
||||
src/temp/ivy/ivyMan.c \
|
||||
src/temp/ivy/ivyMem.c \
|
||||
src/temp/ivy/ivyMulti.c \
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ Mem_Flex_t * Mem_FlexStart()
|
|||
p->pCurrent = NULL;
|
||||
p->pEnd = NULL;
|
||||
|
||||
p->nChunkSize = (1 << 12);
|
||||
p->nChunkSize = (1 << 14);
|
||||
p->nChunksAlloc = 64;
|
||||
p->nChunks = 0;
|
||||
p->pChunks = ALLOC( char *, p->nChunksAlloc );
|
||||
|
|
@ -386,6 +386,34 @@ char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes )
|
|||
return pTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description [Relocates all the memory except the first chunk.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mem_FlexRestart( Mem_Flex_t * p )
|
||||
{
|
||||
int i;
|
||||
if ( p->nChunks == 0 )
|
||||
return;
|
||||
// deallocate all chunks except the first one
|
||||
for ( i = 1; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
p->nChunks = 1;
|
||||
p->nMemoryAlloc = p->nChunkSize;
|
||||
// transform these entries into a linked list
|
||||
p->pCurrent = p->pChunks[0];
|
||||
p->pEnd = p->pCurrent + p->nChunkSize;
|
||||
p->nEntriesUsed = 0;
|
||||
p->nMemoryUsed = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -399,7 +427,7 @@ char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes )
|
|||
***********************************************************************/
|
||||
int Mem_FlexReadMemUsage( Mem_Flex_t * p )
|
||||
{
|
||||
return p->nMemoryAlloc;
|
||||
return p->nMemoryUsed;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ extern int Mem_FixedReadMemUsage( Mem_Fixed_t * p );
|
|||
extern Mem_Flex_t * Mem_FlexStart();
|
||||
extern void Mem_FlexStop( Mem_Flex_t * p, int fVerbose );
|
||||
extern char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes );
|
||||
extern void Mem_FlexRestart( Mem_Flex_t * p );
|
||||
extern int Mem_FlexReadMemUsage( Mem_Flex_t * p );
|
||||
// hierarchical memory manager
|
||||
extern Mem_Step_t * Mem_StepStart( int nSteps );
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
SRC += src/temp/player/playerToAbc.c \
|
||||
src/temp/player/playerFast.c \
|
||||
src/temp/player/playerCore.c \
|
||||
src/temp/player/playerMan.c \
|
||||
src/temp/player/playerUtil.c
|
||||
|
|
|
|||
|
|
@ -86,9 +86,13 @@ static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) {
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== playerToAbc.c ==============================================================*/
|
||||
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nFaninMax, int fVerbose );
|
||||
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose );
|
||||
/*=== playerCore.c =============================================================*/
|
||||
extern Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose );
|
||||
/*=== playerFast.c =============================================================*/
|
||||
extern void Pla_ManFastLutMap( Ivy_Man_t * pAig, int nLimit );
|
||||
extern void Pla_ManFastLutMapStop( Ivy_Man_t * pAig );
|
||||
extern void Pla_ManFastLutMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves );
|
||||
/*=== playerMan.c ==============================================================*/
|
||||
extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax );
|
||||
extern void Pla_ManFree( Pla_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )
|
||||
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose )
|
||||
{
|
||||
int fUseRewriting = 1;
|
||||
Ivy_Man_t * pMan, * pManExt;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,367 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [playerFast.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLA decomposition package.]
|
||||
|
||||
Synopsis [Fast 8-LUT mapper.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: playerFast.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "player.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Ivy_SuppMan_t_ Ivy_SuppMan_t;
|
||||
struct Ivy_SuppMan_t_
|
||||
{
|
||||
int nLimit; // the limit on the number of inputs
|
||||
int nObjs; // the number of entries
|
||||
int nSize; // size of each entry in bytes
|
||||
char * pMem; // memory allocated
|
||||
};
|
||||
|
||||
typedef struct Ivy_Supp_t_ Ivy_Supp_t;
|
||||
struct Ivy_Supp_t_
|
||||
{
|
||||
char nSize; // the number of support nodes
|
||||
char fMark; // the node was processed for area counting
|
||||
short Delay; // the delay of the node
|
||||
int pArray[0]; // the support nodes
|
||||
};
|
||||
|
||||
static inline Ivy_Supp_t * Ivy_ObjSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj )
|
||||
{
|
||||
return (Ivy_Supp_t *)(((Ivy_SuppMan_t*)pAig->pData)->pMem + pObj->Id * ((Ivy_SuppMan_t*)pAig->pData)->nSize);
|
||||
}
|
||||
static inline Ivy_Supp_t * Ivy_ObjSuppStart( Ivy_Man_t * pAig, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Supp_t * pSupp;
|
||||
pSupp = Ivy_ObjSupp( pAig, pObj );
|
||||
pSupp->fMark = 0;
|
||||
pSupp->Delay = 0;
|
||||
pSupp->nSize = 1;
|
||||
pSupp->pArray[0] = pObj->Id;
|
||||
return pSupp;
|
||||
}
|
||||
|
||||
static int Pla_ManFastLutMapDelay( Ivy_Man_t * pAig );
|
||||
static int Pla_ManFastLutMapArea( Ivy_Man_t * pAig );
|
||||
static void Pla_ManFastLutMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit );
|
||||
static int Pla_ManFastLutMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs fast K-LUT mapping of the AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pla_ManFastLutMap( Ivy_Man_t * pAig, int nLimit )
|
||||
{
|
||||
Ivy_SuppMan_t * pMan;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, Delay, Area;
|
||||
int clk = clock(), clk2;
|
||||
// start the memory for supports
|
||||
pMan = ALLOC( Ivy_SuppMan_t, 1 );
|
||||
memset( pMan, 0, sizeof(Ivy_SuppMan_t) );
|
||||
pMan->nLimit = nLimit;
|
||||
pMan->nObjs = Ivy_ManObjIdMax(pAig) + 1;
|
||||
pMan->nSize = sizeof(Ivy_Supp_t) + nLimit * sizeof(int);
|
||||
pMan->pMem = (char *)malloc( pMan->nObjs * pMan->nSize );
|
||||
pAig->pData = pMan;
|
||||
clk2 = clock();
|
||||
// set the PI mapping
|
||||
Ivy_ObjSuppStart( pAig, Ivy_ManConst1(pAig) );
|
||||
Ivy_ManForEachPi( pAig, pObj, i )
|
||||
Ivy_ObjSuppStart( pAig, pObj );
|
||||
// iterate through all nodes in the topological order
|
||||
Ivy_ManForEachNode( pAig, pObj, i )
|
||||
Pla_ManFastLutMapNode( pAig, pObj, nLimit );
|
||||
// find the best arrival time and area
|
||||
Delay = Pla_ManFastLutMapDelay( pAig );
|
||||
Area = Pla_ManFastLutMapArea( pAig );
|
||||
clk2 = clock() - clk2;
|
||||
// print the report
|
||||
printf( "LUT levels = %3d. LUT number = %6d. ", Delay, Area );
|
||||
PRT( "Mapping time", clk2 );
|
||||
// PRT( "Total", clock() - clk );
|
||||
// Pla_ManFastLutMapStop( pAig );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cleans memory used for decomposition.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pla_ManFastLutMapStop( Ivy_Man_t * pAig )
|
||||
{
|
||||
free( ((Ivy_SuppMan_t*)pAig->pData)->pMem );
|
||||
free( pAig->pData );
|
||||
pAig->pData = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes delay after LUT mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pla_ManFastLutMapDelay( Ivy_Man_t * pAig )
|
||||
{
|
||||
Ivy_Supp_t * pSupp;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, DelayMax = 0;
|
||||
Ivy_ManForEachPo( pAig, pObj, i )
|
||||
{
|
||||
pObj = Ivy_ObjFanin0(pObj);
|
||||
if ( !Ivy_ObjIsNode(pObj) )
|
||||
continue;
|
||||
pSupp = Ivy_ObjSupp( pAig, pObj );
|
||||
if ( DelayMax < pSupp->Delay )
|
||||
DelayMax = pSupp->Delay;
|
||||
}
|
||||
return DelayMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area after mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pla_ManFastLutMapArea_rec( Ivy_Man_t * pAig, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Supp_t * pSupp;
|
||||
int i, Counter;
|
||||
pSupp = Ivy_ObjSupp( pAig, pObj );
|
||||
// skip visited nodes and PIs
|
||||
if ( pSupp->fMark || pSupp->nSize == 1 )
|
||||
return 0;
|
||||
pSupp->fMark = 1;
|
||||
// compute the area of this node
|
||||
Counter = 0;
|
||||
for ( i = 0; i < pSupp->nSize; i++ )
|
||||
Counter += Pla_ManFastLutMapArea_rec( pAig, Ivy_ManObj(pAig, pSupp->pArray[i]) );
|
||||
return 1 + Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area after mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pla_ManFastLutMapArea( Ivy_Man_t * pAig )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
Ivy_ManForEachPo( pAig, pObj, i )
|
||||
Counter += Pla_ManFastLutMapArea_rec( pAig, Ivy_ObjFanin0(pObj) );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs fast mapping for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pla_ManFastLutMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit )
|
||||
{
|
||||
Ivy_Supp_t * pSupp0, * pSupp1, * pSupp;
|
||||
int RetValue;
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
// get the supports
|
||||
pSupp0 = Ivy_ObjSupp( pAig, Ivy_ObjFanin0(pObj) );
|
||||
pSupp1 = Ivy_ObjSupp( pAig, Ivy_ObjFanin1(pObj) );
|
||||
pSupp = Ivy_ObjSupp( pAig, pObj );
|
||||
pSupp->fMark = 0;
|
||||
// get the delays
|
||||
if ( pSupp0->Delay == pSupp1->Delay )
|
||||
pSupp->Delay = (pSupp0->Delay == 0) ? pSupp0->Delay + 1: pSupp0->Delay;
|
||||
else if ( pSupp0->Delay > pSupp1->Delay )
|
||||
{
|
||||
pSupp->Delay = pSupp0->Delay;
|
||||
pSupp1 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) );
|
||||
pSupp1->pArray[0] = Ivy_ObjFaninId1(pObj);
|
||||
}
|
||||
else // if ( pSupp0->Delay < pSupp1->Delay )
|
||||
{
|
||||
pSupp->Delay = pSupp1->Delay;
|
||||
pSupp0 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) );
|
||||
pSupp0->pArray[0] = Ivy_ObjFaninId0(pObj);
|
||||
}
|
||||
// merge the cuts
|
||||
if ( pSupp0->nSize < pSupp1->nSize )
|
||||
RetValue = Pla_ManFastLutMapMerge( pSupp1, pSupp0, pSupp, nLimit );
|
||||
else
|
||||
RetValue = Pla_ManFastLutMapMerge( pSupp0, pSupp1, pSupp, nLimit );
|
||||
if ( !RetValue )
|
||||
{
|
||||
pSupp->Delay++;
|
||||
pSupp->nSize = 2;
|
||||
pSupp->pArray[0] = Ivy_ObjFaninId0(pObj);
|
||||
pSupp->pArray[1] = Ivy_ObjFaninId1(pObj);
|
||||
}
|
||||
assert( pSupp->Delay > 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Merges two supports]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pla_ManFastLutMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit )
|
||||
{
|
||||
int i, k, c;
|
||||
assert( pSupp0->nSize >= pSupp1->nSize );
|
||||
// the case of the largest cut sizes
|
||||
if ( pSupp0->nSize == nLimit && pSupp1->nSize == nLimit )
|
||||
{
|
||||
for ( i = 0; i < pSupp0->nSize; i++ )
|
||||
if ( pSupp0->pArray[i] != pSupp1->pArray[i] )
|
||||
return 0;
|
||||
for ( i = 0; i < pSupp0->nSize; i++ )
|
||||
pSupp->pArray[i] = pSupp0->pArray[i];
|
||||
pSupp->nSize = pSupp0->nSize;
|
||||
return 1;
|
||||
}
|
||||
// the case when one of the cuts is the largest
|
||||
if ( pSupp0->nSize == nLimit )
|
||||
{
|
||||
for ( i = 0; i < pSupp1->nSize; i++ )
|
||||
{
|
||||
for ( k = pSupp0->nSize - 1; k >= 0; k-- )
|
||||
if ( pSupp0->pArray[k] == pSupp1->pArray[i] )
|
||||
break;
|
||||
if ( k == -1 ) // did not find
|
||||
return 0;
|
||||
}
|
||||
for ( i = 0; i < pSupp0->nSize; i++ )
|
||||
pSupp->pArray[i] = pSupp0->pArray[i];
|
||||
pSupp->nSize = pSupp0->nSize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// compare two cuts with different numbers
|
||||
i = k = 0;
|
||||
for ( c = 0; c < nLimit; c++ )
|
||||
{
|
||||
if ( k == pSupp1->nSize )
|
||||
{
|
||||
if ( i == pSupp0->nSize )
|
||||
{
|
||||
pSupp->nSize = c;
|
||||
return 1;
|
||||
}
|
||||
pSupp->pArray[c] = pSupp0->pArray[i++];
|
||||
continue;
|
||||
}
|
||||
if ( i == pSupp0->nSize )
|
||||
{
|
||||
if ( k == pSupp1->nSize )
|
||||
{
|
||||
pSupp->nSize = c;
|
||||
return 1;
|
||||
}
|
||||
pSupp->pArray[c] = pSupp1->pArray[k++];
|
||||
continue;
|
||||
}
|
||||
if ( pSupp0->pArray[i] < pSupp1->pArray[k] )
|
||||
{
|
||||
pSupp->pArray[c] = pSupp0->pArray[i++];
|
||||
continue;
|
||||
}
|
||||
if ( pSupp0->pArray[i] > pSupp1->pArray[k] )
|
||||
{
|
||||
pSupp->pArray[c] = pSupp1->pArray[k++];
|
||||
continue;
|
||||
}
|
||||
pSupp->pArray[c] = pSupp0->pArray[i++];
|
||||
k++;
|
||||
}
|
||||
if ( i < pSupp0->nSize || k < pSupp1->nSize )
|
||||
return 0;
|
||||
pSupp->nSize = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates integer vector with the support of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pla_ManFastLutMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves )
|
||||
{
|
||||
Ivy_Supp_t * pSupp;
|
||||
pSupp = Ivy_ObjSupp( pAig, pObj );
|
||||
vLeaves->nCap = 8;
|
||||
vLeaves->nSize = pSupp->nSize;
|
||||
vLeaves->pArray = pSupp->pArray;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -26,9 +26,11 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p );
|
||||
static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p );
|
||||
static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode );
|
||||
static Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp );
|
||||
static Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp );
|
||||
static Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp );
|
||||
static int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose );
|
||||
|
||||
static inline void Abc_ObjSetIvy2Abc( Ivy_Man_t * p, int IvyId, Abc_Obj_t * pObjAbc ) { assert(Vec_PtrEntry(p->pCopy, IvyId) == NULL); assert(!Abc_ObjIsComplement(pObjAbc)); Vec_PtrWriteEntry( p->pCopy, IvyId, pObjAbc ); }
|
||||
static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId ) { return Vec_PtrEntry( p->pCopy, IvyId ); }
|
||||
|
|
@ -39,7 +41,7 @@ static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to PLAyer for processing.]
|
||||
Synopsis [Applies PLA/LUT mapping to the ABC network.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -48,12 +50,12 @@ static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )
|
||||
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose )
|
||||
{
|
||||
int fUseRewriting = 1;
|
||||
int fUseRewriting = 0;
|
||||
Pla_Man_t * p;
|
||||
Ivy_Man_t * pMan, * pManExt;
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
return NULL;
|
||||
// convert to the new AIG manager
|
||||
|
|
@ -75,20 +77,33 @@ void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )
|
|||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
}
|
||||
// perform decomposition/mapping into PLAs/LUTs
|
||||
p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
|
||||
// convert from the extended AIG manager into an SOP network
|
||||
pNtkAig = Ivy_ManToAbc( pNtk, pMan, p );
|
||||
Pla_ManFree( p );
|
||||
// perform decomposition
|
||||
if ( fFastMode )
|
||||
{
|
||||
// perform mapping into LUTs
|
||||
Pla_ManFastLutMap( pMan, nLutMax );
|
||||
// convert from the extended AIG manager into an SOP network
|
||||
pNtkNew = Ivy_ManToAbc( pNtk, pMan, NULL, fFastMode );
|
||||
Pla_ManFastLutMapStop( pMan );
|
||||
}
|
||||
else
|
||||
{
|
||||
// perform decomposition/mapping into PLAs/LUTs
|
||||
p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
|
||||
// convert from the extended AIG manager into an SOP network
|
||||
pNtkNew = Ivy_ManToAbc( pNtk, pMan, p, fFastMode );
|
||||
Pla_ManFree( p );
|
||||
}
|
||||
Ivy_ManStop( pMan );
|
||||
// chech the resulting network
|
||||
if ( !Abc_NtkCheck( pNtkAig ) )
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkPlayer: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkAig );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkAig;
|
||||
Abc_NtkPlayerCost( pNtkNew, RankCost, fVerbose );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -134,7 +149,7 @@ Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p )
|
||||
Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObjAbc, * pObj;
|
||||
|
|
@ -155,7 +170,11 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p )
|
|||
Ivy_ManForEachPo( pMan, pObjIvy, i )
|
||||
{
|
||||
// get the new ABC node corresponding to the old fanin of the PO in IVY
|
||||
pObjAbc = Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp );
|
||||
if ( fFastMode )
|
||||
pObjAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp );
|
||||
else
|
||||
pObjAbc = Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp );
|
||||
// consider the case of complemented fanin of the PO
|
||||
if ( Ivy_ObjFaninC0(pObjIvy) ) // complement
|
||||
{
|
||||
if ( Abc_ObjIsCi(pObjAbc) )
|
||||
|
|
@ -236,17 +255,20 @@ Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t *
|
|||
Abc_ObjAddFanin( pObjAbc, Abc_ObjGetIvy2Abc(pMan, Entry) );
|
||||
// check if the truth table is constant 0
|
||||
puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp );
|
||||
for ( i = 0; i < 8; i++ )
|
||||
if ( puTruth[i] )
|
||||
break;
|
||||
// create constant 0 node
|
||||
if ( i == 8 )
|
||||
// if the function is constant 0, create constant 0 node
|
||||
if ( Extra_TruthIsConst0(puTruth, 8) )
|
||||
{
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
|
||||
pObjAbc = Abc_NodeCreateConst0( pNtkNew );
|
||||
}
|
||||
else
|
||||
pObjAbc->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, Vec_IntSize(vSupp), puTruth );
|
||||
{
|
||||
int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes );
|
||||
pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes );
|
||||
if ( fCompl ) Abc_SopComplement(pObjAbc->pData);
|
||||
// printf( "Cover contains %d cubes.\n", Vec_IntSize(vNodes) );
|
||||
// pObjAbc->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, Vec_IntSize(vSupp), puTruth );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -309,6 +331,149 @@ Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t *
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively construct the new node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp )
|
||||
{
|
||||
Vec_Int_t Supp, * vSupp = &Supp;
|
||||
Abc_Obj_t * pObjAbc, * pFaninAbc;
|
||||
int i, Entry;
|
||||
unsigned * puTruth;
|
||||
// skip the node if it is a constant or already processed
|
||||
pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id );
|
||||
if ( pObjAbc )
|
||||
return pObjAbc;
|
||||
assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) );
|
||||
// get the support of K-LUT
|
||||
Pla_ManFastLutMapReadSupp( pMan, pObjIvy, vSupp );
|
||||
// create new ABC node and its fanins
|
||||
pObjAbc = Abc_NtkCreateNode( pNtkNew );
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
{
|
||||
pFaninAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ManObj(pMan, Entry), vNodes, vTemp );
|
||||
Abc_ObjAddFanin( pObjAbc, pFaninAbc );
|
||||
}
|
||||
// check if the truth table is constant 0
|
||||
puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp );
|
||||
// if the function is constant 0, create constant 0 node
|
||||
if ( Extra_TruthIsConst0(puTruth, 8) )
|
||||
{
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
|
||||
pObjAbc = Abc_NodeCreateConst0( pNtkNew );
|
||||
}
|
||||
else
|
||||
{
|
||||
int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes );
|
||||
pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes );
|
||||
if ( fCompl ) Abc_SopComplement(pObjAbc->pData);
|
||||
}
|
||||
Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc );
|
||||
return pObjAbc;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes cost of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Abc_NodePlayerCost( int nFanins )
|
||||
{
|
||||
if ( nFanins <= 4 )
|
||||
return 1;
|
||||
if ( nFanins <= 6 )
|
||||
return 2;
|
||||
if ( nFanins <= 8 )
|
||||
return 4;
|
||||
if ( nFanins <= 16 )
|
||||
return 8;
|
||||
if ( nFanins <= 32 )
|
||||
return 16;
|
||||
if ( nFanins <= 64 )
|
||||
return 32;
|
||||
if ( nFanins <= 128 )
|
||||
return 64;
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the number of ranks needed for one level.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Abc_NtkPlayerCostOne( int nCost, int RankCost )
|
||||
{
|
||||
return (nCost / RankCost) + ((nCost % RankCost) > 0);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cost function for the network (number of ranks).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int nFanins, nLevels, * pLevelCosts, CostTotal, nRanksTotal, i;
|
||||
// compute the costs for each level
|
||||
nLevels = Abc_NtkGetLevelNum( pNtk );
|
||||
pLevelCosts = ALLOC( int, nLevels + 1 );
|
||||
memset( pLevelCosts, 0, sizeof(int) * (nLevels + 1) );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
nFanins = Abc_ObjFaninNum(pObj);
|
||||
if ( nFanins == 0 )
|
||||
continue;
|
||||
pLevelCosts[ pObj->Level ] += Abc_NodePlayerCost( nFanins );
|
||||
}
|
||||
// compute the total cost
|
||||
CostTotal = nRanksTotal = 0;
|
||||
for ( i = 1; i <= nLevels; i++ )
|
||||
{
|
||||
CostTotal += pLevelCosts[i];
|
||||
nRanksTotal += Abc_NtkPlayerCostOne( pLevelCosts[i], RankCost );
|
||||
}
|
||||
// print out statistics
|
||||
if ( fVerbose )
|
||||
{
|
||||
for ( i = 1; i <= nLevels; i++ )
|
||||
printf( "Level %2d : Cost = %6d. Ranks = %6.3f.\n", i, pLevelCosts[i], ((double)pLevelCosts[i])/RankCost );
|
||||
printf( "TOTAL : Cost = %6d. Ranks = %3d.\n", CostTotal, nRanksTotal );
|
||||
}
|
||||
return nRanksTotal;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -70,7 +70,9 @@ struct Rwt_Man_t_
|
|||
int nClasses; // the number of NN classes
|
||||
// the result of resynthesis
|
||||
int fCompl; // indicates if the output of FF should be complemented
|
||||
void * pCut; // the decomposition tree (temporary)
|
||||
void * pGraph; // the decomposition tree (temporary)
|
||||
char * pPerm; // permutation used for the best cut
|
||||
Vec_Ptr_t * vFanins; // the fanins array (temporary)
|
||||
Vec_Ptr_t * vFaninsCur; // the fanins array (temporary)
|
||||
Vec_Int_t * vLevNums; // the array of levels (temporary)
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ void Rwt_ManPrintStats( Rwt_Man_t * p )
|
|||
PRT( "Update ", p->timeUpdate );
|
||||
PRT( "TOTAL ", p->timeTotal );
|
||||
|
||||
|
||||
/*
|
||||
printf( "The scores are:\n" );
|
||||
for ( i = 0; i < 222; i++ )
|
||||
if ( p->nScores[i] > 0 )
|
||||
|
|
@ -210,7 +210,7 @@ void Rwt_ManPrintStats( Rwt_Man_t * p )
|
|||
Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[i] | ((unsigned)p->pMapInv[i] << 16) );
|
||||
}
|
||||
printf( "\n" );
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
SRC += src/temp/xyz/xyzBuild.c \
|
||||
src/temp/xyz/xyzCore.c \
|
||||
src/temp/xyz/xyzMan.c \
|
||||
src/temp/xyz/xyzMinEsop.c \
|
||||
src/temp/xyz/xyzMinMan.c \
|
||||
src/temp/xyz/xyzMinSop.c \
|
||||
src/temp/xyz/xyzMinUtil.c \
|
||||
src/temp/xyz/xyzTest.c
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyz.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyz.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __XYZ_H__
|
||||
#define __XYZ_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "abc.h"
|
||||
#include "xyzInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Xyz_Man_t_ Xyz_Man_t;
|
||||
typedef struct Xyz_Obj_t_ Xyz_Obj_t;
|
||||
|
||||
// storage for node information
|
||||
struct Xyz_Obj_t_
|
||||
{
|
||||
Min_Cube_t * pCover[3]; // pos/neg/esop
|
||||
Vec_Int_t * vSupp; // computed support (all nodes except CIs)
|
||||
};
|
||||
|
||||
// storage for additional information
|
||||
struct Xyz_Man_t_
|
||||
{
|
||||
// general characteristics
|
||||
int nFaninMax; // the number of vars
|
||||
int nCubesMax; // the limit on the number of cubes in the intermediate covers
|
||||
int nWords; // the number of words
|
||||
Vec_Int_t * vFanCounts; // fanout counts
|
||||
Vec_Ptr_t * vObjStrs; // object structures
|
||||
void * pMemory; // memory for the internal data strctures
|
||||
Min_Man_t * pManMin; // the cub manager
|
||||
int fUseEsop; // enables ESOPs
|
||||
int fUseSop; // enables SOPs
|
||||
// arrays to map local variables
|
||||
Vec_Int_t * vComTo0; // mapping of common variables into first fanin
|
||||
Vec_Int_t * vComTo1; // mapping of common variables into second fanin
|
||||
Vec_Int_t * vPairs0; // the first var in each pair of common vars
|
||||
Vec_Int_t * vPairs1; // the second var in each pair of common vars
|
||||
Vec_Int_t * vTriv0; // trival support of the first node
|
||||
Vec_Int_t * vTriv1; // trival support of the second node
|
||||
// statistics
|
||||
int nSupps; // supports created
|
||||
int nSuppsMax; // the maximum number of supports
|
||||
int nBoundary; // the boundary size
|
||||
int nNodes; // the number of nodes processed
|
||||
};
|
||||
|
||||
static inline Xyz_Obj_t * Abc_ObjGetStr( Abc_Obj_t * pObj ) { return Vec_PtrEntry(((Xyz_Man_t *)pObj->pNtk->pManCut)->vObjStrs, pObj->Id); }
|
||||
|
||||
static inline void Abc_ObjSetSupp( Abc_Obj_t * pObj, Vec_Int_t * vVec ) { Abc_ObjGetStr(pObj)->vSupp = vVec; }
|
||||
static inline Vec_Int_t * Abc_ObjGetSupp( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->vSupp; }
|
||||
|
||||
static inline void Abc_ObjSetCover2( Abc_Obj_t * pObj, Min_Cube_t * pCov ) { Abc_ObjGetStr(pObj)->pCover[2] = pCov; }
|
||||
static inline Min_Cube_t * Abc_ObjGetCover2( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->pCover[2]; }
|
||||
|
||||
static inline void Abc_ObjSetCover( Abc_Obj_t * pObj, Min_Cube_t * pCov, int Pol ) { Abc_ObjGetStr(pObj)->pCover[Pol] = pCov; }
|
||||
static inline Min_Cube_t * Abc_ObjGetCover( Abc_Obj_t * pObj, int Pol ) { return Abc_ObjGetStr(pObj)->pCover[Pol]; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== xyzBuild.c ==========================================================*/
|
||||
extern Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk );
|
||||
extern Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk );
|
||||
/*=== xyzCore.c ===========================================================*/
|
||||
extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose );
|
||||
/*=== xyzMan.c ============================================================*/
|
||||
extern Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax );
|
||||
extern void Xyz_ManFree( Xyz_Man_t * p );
|
||||
extern void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj );
|
||||
/*=== xyzTest.c ===========================================================*/
|
||||
extern Abc_Ntk_t * Abc_NtkXyzTestSop( Abc_Ntk_t * pNtk );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,379 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyzBuild.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Network construction procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyzBuild.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "xyz.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NtkXyzDeriveCube( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp )
|
||||
{
|
||||
Vec_Int_t * vLits;
|
||||
Abc_Obj_t * pNodeNew, * pFanin;
|
||||
int i, iFanin, Lit;
|
||||
// create empty cube
|
||||
if ( pCube->nLits == 0 )
|
||||
return Abc_NodeCreateConst1(pNtkNew);
|
||||
// get the literals of this cube
|
||||
vLits = Vec_IntAlloc( 10 );
|
||||
Min_CubeGetLits( pCube, vLits );
|
||||
assert( pCube->nLits == (unsigned)vLits->nSize );
|
||||
// create special case when there is only one literal
|
||||
if ( pCube->nLits == 1 )
|
||||
{
|
||||
iFanin = Vec_IntEntry(vLits,0);
|
||||
pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
|
||||
Lit = Min_CubeGetVar(pCube, iFanin);
|
||||
assert( Lit == 1 || Lit == 2 );
|
||||
Vec_IntFree( vLits );
|
||||
if ( Lit == 1 )// negative
|
||||
return Abc_NodeCreateInv( pNtkNew, pFanin->pCopy );
|
||||
return pFanin->pCopy;
|
||||
}
|
||||
assert( pCube->nLits > 1 );
|
||||
// create the AND cube
|
||||
pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( i = 0; i < vLits->nSize; i++ )
|
||||
{
|
||||
iFanin = Vec_IntEntry(vLits,i);
|
||||
pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
|
||||
Lit = Min_CubeGetVar(pCube, iFanin);
|
||||
assert( Lit == 1 || Lit == 2 );
|
||||
Vec_IntWriteEntry( vLits, i, Lit==1 );
|
||||
Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
|
||||
}
|
||||
pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray );
|
||||
Vec_IntFree( vLits );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NtkXyzDeriveNode_rec( Xyz_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int Level )
|
||||
{
|
||||
Min_Cube_t * pCover, * pCube;
|
||||
Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin;
|
||||
Vec_Int_t * vSupp;
|
||||
int Entry, nCubes, i;
|
||||
|
||||
if ( Abc_ObjIsCi(pObj) )
|
||||
return pObj->pCopy;
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
// skip if already computed
|
||||
if ( pObj->pCopy )
|
||||
return pObj->pCopy;
|
||||
|
||||
// get the support and the cover
|
||||
vSupp = Abc_ObjGetSupp( pObj );
|
||||
pCover = Abc_ObjGetCover2( pObj );
|
||||
assert( vSupp );
|
||||
/*
|
||||
if ( pCover && pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) > 0 )
|
||||
{
|
||||
printf( "%d\n ", pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) );
|
||||
Min_CoverWrite( stdout, pCover );
|
||||
}
|
||||
*/
|
||||
/*
|
||||
// print the support of this node
|
||||
printf( "{ " );
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
printf( "%d ", Entry );
|
||||
printf( "} cubes = %d\n", Min_CoverCountCubes( pCover ) );
|
||||
*/
|
||||
// process the fanins
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
{
|
||||
pFanin = Abc_NtkObj(pObj->pNtk, Entry);
|
||||
Abc_NtkXyzDeriveNode_rec( p, pNtkNew, pFanin, Level+1 );
|
||||
}
|
||||
|
||||
// for each cube, construct the node
|
||||
nCubes = Min_CoverCountCubes( pCover );
|
||||
if ( nCubes == 0 )
|
||||
pNodeNew = Abc_NodeCreateConst0(pNtkNew);
|
||||
else if ( nCubes == 1 )
|
||||
pNodeNew = Abc_NtkXyzDeriveCube( pNtkNew, pObj, pCover, vSupp );
|
||||
else
|
||||
{
|
||||
pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
Min_CoverForEachCube( pCover, pCube )
|
||||
{
|
||||
pFaninNew = Abc_NtkXyzDeriveCube( pNtkNew, pObj, pCube, vSupp );
|
||||
Abc_ObjAddFanin( pNodeNew, pFaninNew );
|
||||
}
|
||||
pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes );
|
||||
}
|
||||
/*
|
||||
printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level );
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
{
|
||||
pFanin = Abc_NtkObj(pObj->pNtk, Entry);
|
||||
printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id );
|
||||
}
|
||||
printf( "\n" );
|
||||
Min_CoverWrite( stdout, pCover );
|
||||
*/
|
||||
pObj->pCopy = pNodeNew;
|
||||
return pNodeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
// perform strashing
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
// reconstruct the network
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
{
|
||||
Abc_NtkXyzDeriveNode_rec( p, pNtkNew, Abc_ObjFanin0(pObj), 0 );
|
||||
// printf( "*** CO %s : %d -> %d \n", Abc_ObjName(pObj), pObj->pCopy->Id, Abc_ObjFanin0(pObj)->pCopy->Id );
|
||||
}
|
||||
// add the COs
|
||||
Abc_NtkFinalize( pNtk, pNtkNew );
|
||||
Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
|
||||
// make sure everything is okay
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkXyzDerive: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NtkXyzDeriveInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl )
|
||||
{
|
||||
assert( pObj->pCopy );
|
||||
if ( !fCompl )
|
||||
return pObj->pCopy;
|
||||
if ( pObj->pCopy->pCopy == NULL )
|
||||
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
|
||||
return pObj->pCopy->pCopy;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NtkXyzDeriveCubeInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp )
|
||||
{
|
||||
Vec_Int_t * vLits;
|
||||
Abc_Obj_t * pNodeNew, * pFanin;
|
||||
int i, iFanin, Lit;
|
||||
// create empty cube
|
||||
if ( pCube->nLits == 0 )
|
||||
return Abc_NodeCreateConst1(pNtkNew);
|
||||
// get the literals of this cube
|
||||
vLits = Vec_IntAlloc( 10 );
|
||||
Min_CubeGetLits( pCube, vLits );
|
||||
assert( pCube->nLits == (unsigned)vLits->nSize );
|
||||
// create special case when there is only one literal
|
||||
if ( pCube->nLits == 1 )
|
||||
{
|
||||
iFanin = Vec_IntEntry(vLits,0);
|
||||
pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
|
||||
Lit = Min_CubeGetVar(pCube, iFanin);
|
||||
assert( Lit == 1 || Lit == 2 );
|
||||
Vec_IntFree( vLits );
|
||||
// if ( Lit == 1 )// negative
|
||||
// return Abc_NodeCreateInv( pNtkNew, pFanin->pCopy );
|
||||
// return pFanin->pCopy;
|
||||
return Abc_NtkXyzDeriveInv( pNtkNew, pFanin, Lit==1 );
|
||||
}
|
||||
assert( pCube->nLits > 1 );
|
||||
// create the AND cube
|
||||
pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( i = 0; i < vLits->nSize; i++ )
|
||||
{
|
||||
iFanin = Vec_IntEntry(vLits,i);
|
||||
pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) );
|
||||
Lit = Min_CubeGetVar(pCube, iFanin);
|
||||
assert( Lit == 1 || Lit == 2 );
|
||||
Vec_IntWriteEntry( vLits, i, Lit==1 );
|
||||
// Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NtkXyzDeriveInv( pNtkNew, pFanin, Lit==1 ) );
|
||||
}
|
||||
// pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray );
|
||||
pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, NULL );
|
||||
Vec_IntFree( vLits );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NtkXyzDeriveNodeInv_rec( Xyz_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl )
|
||||
{
|
||||
Min_Cube_t * pCover, * pCube;
|
||||
Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin;
|
||||
Vec_Int_t * vSupp;
|
||||
int Entry, nCubes, i;
|
||||
|
||||
// skip if already computed
|
||||
if ( pObj->pCopy )
|
||||
return Abc_NtkXyzDeriveInv( pNtkNew, pObj, fCompl );
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
|
||||
// get the support and the cover
|
||||
vSupp = Abc_ObjGetSupp( pObj );
|
||||
pCover = Abc_ObjGetCover2( pObj );
|
||||
assert( vSupp );
|
||||
|
||||
// process the fanins
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
{
|
||||
pFanin = Abc_NtkObj(pObj->pNtk, Entry);
|
||||
Abc_NtkXyzDeriveNodeInv_rec( p, pNtkNew, pFanin, 0 );
|
||||
}
|
||||
|
||||
// for each cube, construct the node
|
||||
nCubes = Min_CoverCountCubes( pCover );
|
||||
if ( nCubes == 0 )
|
||||
pNodeNew = Abc_NodeCreateConst0(pNtkNew);
|
||||
else if ( nCubes == 1 )
|
||||
pNodeNew = Abc_NtkXyzDeriveCubeInv( pNtkNew, pObj, pCover, vSupp );
|
||||
else
|
||||
{
|
||||
pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
Min_CoverForEachCube( pCover, pCube )
|
||||
{
|
||||
pFaninNew = Abc_NtkXyzDeriveCubeInv( pNtkNew, pObj, pCube, vSupp );
|
||||
Abc_ObjAddFanin( pNodeNew, pFaninNew );
|
||||
}
|
||||
pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes );
|
||||
}
|
||||
|
||||
pObj->pCopy = pNodeNew;
|
||||
return Abc_NtkXyzDeriveInv( pNtkNew, pObj, fCompl );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description [The resulting network contains only pure AND/OR/EXOR gates
|
||||
and inverters. This procedure is usedful to generate Verilog.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObj, * pNodeNew;
|
||||
int i;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
// perform strashing
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
// reconstruct the network
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
{
|
||||
pNodeNew = Abc_NtkXyzDeriveNodeInv_rec( p, pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) );
|
||||
Abc_ObjAddFanin( pObj->pCopy, pNodeNew );
|
||||
}
|
||||
// add the COs
|
||||
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
|
||||
// make sure everything is okay
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkXyzDeriveInv: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,642 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyzInt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Internal declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyzInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Min_Man_t_ Min_Man_t;
|
||||
typedef struct Min_Cube_t_ Min_Cube_t;
|
||||
|
||||
struct Min_Man_t_
|
||||
{
|
||||
int nVars; // the number of vars
|
||||
int nWords; // the number of words
|
||||
Extra_MmFixed_t * pMemMan; // memory manager for cubes
|
||||
// temporary cubes
|
||||
Min_Cube_t * pOne0; // tautology cube
|
||||
Min_Cube_t * pOne1; // tautology cube
|
||||
Min_Cube_t * pTriv0[2]; // trivial cube
|
||||
Min_Cube_t * pTriv1[2]; // trivial cube
|
||||
Min_Cube_t * pTemp; // cube for computing the distance
|
||||
Min_Cube_t * pBubble; // cube used as a separator
|
||||
// temporary storage for the new cover
|
||||
int nCubes; // the number of cubes
|
||||
Min_Cube_t ** ppStore; // storage for cubes by number of literals
|
||||
};
|
||||
|
||||
struct Min_Cube_t_
|
||||
{
|
||||
Min_Cube_t * pNext; // the pointer to the next cube in the cover
|
||||
unsigned nVars : 10; // the number of variables
|
||||
unsigned nWords : 12; // the number of machine words
|
||||
unsigned nLits : 10; // the number of literals in the cube
|
||||
unsigned uData[1]; // the bit-data for the cube
|
||||
};
|
||||
|
||||
|
||||
// iterators through the entries in the linked lists of cubes
|
||||
#define Min_CoverForEachCube( pCover, pCube ) \
|
||||
for ( pCube = pCover; \
|
||||
pCube; \
|
||||
pCube = pCube->pNext )
|
||||
#define Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \
|
||||
for ( pCube = pCover, \
|
||||
pCube2 = pCube? pCube->pNext: NULL; \
|
||||
pCube; \
|
||||
pCube = pCube2, \
|
||||
pCube2 = pCube? pCube->pNext: NULL )
|
||||
#define Min_CoverForEachCubePrev( pCover, pCube, ppPrev ) \
|
||||
for ( pCube = pCover, \
|
||||
ppPrev = &(pCover); \
|
||||
pCube; \
|
||||
ppPrev = &pCube->pNext, \
|
||||
pCube = pCube->pNext )
|
||||
|
||||
// macros to get hold of bits and values in the cubes
|
||||
static inline int Min_CubeHasBit( Min_Cube_t * p, int i ) { return (p->uData[(i)>>5] & (1<<((i) & 31))) > 0; }
|
||||
static inline void Min_CubeSetBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] |= (1<<((i) & 31)); }
|
||||
static inline void Min_CubeXorBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] ^= (1<<((i) & 31)); }
|
||||
static inline int Min_CubeGetVar( Min_Cube_t * p, int Var ) { return 3 & (p->uData[(2*Var)>>5] >> ((2*Var) & 31)); }
|
||||
static inline void Min_CubeXorVar( Min_Cube_t * p, int Var, int Value ) { p->uData[(2*Var)>>5] ^= (Value<<((2*Var) & 31)); }
|
||||
|
||||
/*=== xyzMinEsop.c ==========================================================*/
|
||||
extern void Min_EsopMinimize( Min_Man_t * p );
|
||||
extern void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube );
|
||||
/*=== xyzMinSop.c ==========================================================*/
|
||||
extern void Min_SopMinimize( Min_Man_t * p );
|
||||
extern void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube );
|
||||
/*=== xyzMinMan.c ==========================================================*/
|
||||
extern Min_Man_t * Min_ManAlloc( int nVars );
|
||||
extern void Min_ManClean( Min_Man_t * p, int nSupp );
|
||||
extern void Min_ManFree( Min_Man_t * p );
|
||||
/*=== xyzMinUtil.c ==========================================================*/
|
||||
extern void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube );
|
||||
extern void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover );
|
||||
extern void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p );
|
||||
extern void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop );
|
||||
extern void Min_CoverCheck( Min_Man_t * p );
|
||||
extern int Min_CubeCheck( Min_Cube_t * pCube );
|
||||
extern Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize );
|
||||
extern void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover );
|
||||
extern int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
pCube = (Min_Cube_t *)Extra_MmFixedEntryFetch( p->pMemMan );
|
||||
pCube->pNext = NULL;
|
||||
pCube->nVars = p->nVars;
|
||||
pCube->nWords = p->nWords;
|
||||
pCube->nLits = 0;
|
||||
memset( pCube->uData, 0xff, sizeof(unsigned) * p->nWords );
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the cube representing elementary var.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
pCube = Min_CubeAlloc( p );
|
||||
Min_CubeXorBit( pCube, iVar*2+fCompl );
|
||||
pCube->nLits = 1;
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
pCube = Min_CubeAlloc( p );
|
||||
memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords );
|
||||
pCube->nLits = pCopy->nLits;
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recycles the cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube )
|
||||
{
|
||||
Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recycles the cube cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover )
|
||||
{
|
||||
Min_Cube_t * pCube, * pCube2;
|
||||
Min_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of cubes in the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Min_CubeCountLits( Min_Cube_t * pCube )
|
||||
{
|
||||
unsigned uData;
|
||||
int Count = 0, i, w;
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
{
|
||||
uData = pCube->uData[w] ^ (pCube->uData[w] >> 1);
|
||||
for ( i = 0; i < 32; i += 2 )
|
||||
if ( uData & (1 << i) )
|
||||
Count++;
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of cubes in the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits )
|
||||
{
|
||||
unsigned uData;
|
||||
int i, w;
|
||||
Vec_IntClear( vLits );
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
{
|
||||
uData = pCube->uData[w] ^ (pCube->uData[w] >> 1);
|
||||
for ( i = 0; i < 32; i += 2 )
|
||||
if ( uData & (1 << i) )
|
||||
Vec_IntPush( vLits, w*16 + i/2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of cubes in the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Min_CoverCountCubes( Min_Cube_t * pCover )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
int Count = 0;
|
||||
Min_CoverForEachCube( pCover, pCube )
|
||||
Count++;
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes are disjoint.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
|
||||
{
|
||||
unsigned uData;
|
||||
int i;
|
||||
assert( pCube0->nVars == pCube1->nVars );
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
{
|
||||
uData = pCube0->uData[i] & pCube1->uData[i];
|
||||
uData = (uData | (uData >> 1)) & 0x55555555;
|
||||
if ( uData != 0x55555555 )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the disjoint variables of the two cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube, Vec_Int_t * vVars )
|
||||
{
|
||||
unsigned uData;
|
||||
int i, w;
|
||||
Vec_IntClear( vVars );
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
{
|
||||
uData = pThis->uData[w] & (pThis->uData[w] >> 1) & 0x55555555;
|
||||
uData &= (pCube->uData[w] ^ (pCube->uData[w] >> 1));
|
||||
if ( uData == 0 )
|
||||
continue;
|
||||
for ( i = 0; i < 32; i += 2 )
|
||||
if ( uData & (1 << i) )
|
||||
Vec_IntPush( vVars, w*16 + i/2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes are disjoint.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Min_Cube_t * pTemp )
|
||||
{
|
||||
unsigned uData;
|
||||
int i, fFound = 0;
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
{
|
||||
uData = pCube0->uData[i] ^ pCube1->uData[i];
|
||||
if ( uData == 0 )
|
||||
{
|
||||
if ( pTemp ) pTemp->uData[i] = 0;
|
||||
continue;
|
||||
}
|
||||
if ( fFound )
|
||||
return 0;
|
||||
uData = (uData | (uData >> 1)) & 0x55555555;
|
||||
if ( (uData & (uData-1)) > 0 ) // more than one 1
|
||||
return 0;
|
||||
if ( pTemp ) pTemp->uData[i] = uData | (uData << 1);
|
||||
fFound = 1;
|
||||
}
|
||||
if ( fFound == 0 )
|
||||
{
|
||||
printf( "\n" );
|
||||
Min_CubeWrite( stdout, pCube0 );
|
||||
Min_CubeWrite( stdout, pCube1 );
|
||||
printf( "Error: Min_CubesDistOne() looks at two equal cubes!\n" );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes are disjoint.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, int * pVar0, int * pVar1 )
|
||||
{
|
||||
unsigned uData;//, uData2;
|
||||
int i, k, Var0 = -1, Var1 = -1;
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
{
|
||||
uData = pCube0->uData[i] ^ pCube1->uData[i];
|
||||
if ( uData == 0 )
|
||||
continue;
|
||||
if ( Var0 >= 0 && Var1 >= 0 ) // more than two 1s
|
||||
return 0;
|
||||
uData = (uData | (uData >> 1)) & 0x55555555;
|
||||
if ( (Var0 >= 0 || Var1 >= 0) && (uData & (uData-1)) > 0 )
|
||||
return 0;
|
||||
for ( k = 0; k < 32; k += 2 )
|
||||
if ( uData & (1 << k) )
|
||||
{
|
||||
if ( Var0 == -1 )
|
||||
Var0 = 16 * i + k/2;
|
||||
else if ( Var1 == -1 )
|
||||
Var1 = 16 * i + k/2;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
if ( Var0 >= 0 )
|
||||
{
|
||||
uData &= 0xFFFF;
|
||||
uData2 = (uData >> 16);
|
||||
if ( uData && uData2 )
|
||||
return 0;
|
||||
if ( uData )
|
||||
{
|
||||
}
|
||||
uData }= uData2;
|
||||
uData &= 0x
|
||||
}
|
||||
*/
|
||||
}
|
||||
if ( Var0 >= 0 && Var1 >= 0 )
|
||||
{
|
||||
*pVar0 = Var0;
|
||||
*pVar1 = Var1;
|
||||
return 1;
|
||||
}
|
||||
if ( Var0 == -1 || Var1 == -1 )
|
||||
{
|
||||
printf( "\n" );
|
||||
Min_CubeWrite( stdout, pCube0 );
|
||||
Min_CubeWrite( stdout, pCube1 );
|
||||
printf( "Error: Min_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Makes the produce of two cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
int i;
|
||||
assert( pCube0->nVars == pCube1->nVars );
|
||||
pCube = Min_CubeAlloc( p );
|
||||
for ( i = 0; i < p->nWords; i++ )
|
||||
pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i];
|
||||
pCube->nLits = Min_CubeCountLits( pCube );
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Makes the produce of two cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
int i;
|
||||
assert( pCube0->nVars == pCube1->nVars );
|
||||
pCube = Min_CubeAlloc( p );
|
||||
for ( i = 0; i < p->nWords; i++ )
|
||||
pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i];
|
||||
pCube->nLits = Min_CubeCountLits( pCube );
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Makes the produce of two cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
if ( pCube0->uData[i] != pCube1->uData[i] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if pCube1 is contained in pCube0, bitwise.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < (int)pCube0->nWords; i++ )
|
||||
if ( (pCube0->uData[i] & pCube1->uData[i]) != pCube1->uData[i] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transforms the cube into the result of merging.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, Min_Cube_t * pMask )
|
||||
{
|
||||
int w;
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
{
|
||||
pCube->uData[w] = pCube->uData[w] ^ pDist->uData[w];
|
||||
pCube->uData[w] |= (pDist->uData[w] & ~pMask->uData[w]);
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transforms the cube into the result of distance-1 merging.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist )
|
||||
{
|
||||
int w;
|
||||
for ( w = 0; w < (int)pCube->nWords; w++ )
|
||||
pCube->uData[w] |= pDist->uData[w];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts the cover in the increasing number of literals.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCover )
|
||||
{
|
||||
Min_Cube_t * pCube, * pCube2, * pThis;
|
||||
if ( pCover == NULL )
|
||||
{
|
||||
Min_ManClean( p, p->nVars );
|
||||
return;
|
||||
}
|
||||
Min_ManClean( p, pCover->nVars );
|
||||
Min_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
{
|
||||
// go through the linked list
|
||||
Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
|
||||
if ( Min_CubesAreEqual( pCube, pThis ) )
|
||||
{
|
||||
Min_CubeRecycle( p, pCube );
|
||||
break;
|
||||
}
|
||||
if ( pThis != NULL )
|
||||
continue;
|
||||
pCube->pNext = p->ppStore[pCube->nLits];
|
||||
p->ppStore[pCube->nLits] = pCube;
|
||||
p->nCubes++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the given cube is contained in one of the cubes of the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Min_CoverContainsCube( Min_Man_t * p, Min_Cube_t * pCube )
|
||||
{
|
||||
Min_Cube_t * pThis;
|
||||
int i;
|
||||
/*
|
||||
// this cube cannot be equal to any cube
|
||||
Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
|
||||
{
|
||||
if ( Min_CubesAreEqual( pCube, pThis ) )
|
||||
{
|
||||
Min_CubeWrite( stdout, pCube );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
*/
|
||||
// try to find a containing cube
|
||||
for ( i = 0; i <= (int)pCube->nLits; i++ )
|
||||
Min_CoverForEachCube( p->ppStore[i], pThis )
|
||||
{
|
||||
// skip the bubble
|
||||
if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyzMan.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Decomposition manager.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyzMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "xyz.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax )
|
||||
{
|
||||
Xyz_Man_t * pMan;
|
||||
Xyz_Obj_t * pMem;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( pNtk->pManCut == NULL );
|
||||
|
||||
// start the manager
|
||||
pMan = ALLOC( Xyz_Man_t, 1 );
|
||||
memset( pMan, 0, sizeof(Xyz_Man_t) );
|
||||
pMan->nFaninMax = nFaninMax;
|
||||
pMan->nCubesMax = 2 * pMan->nFaninMax;
|
||||
pMan->nWords = Abc_BitWordNum( nFaninMax * 2 );
|
||||
|
||||
// get the cubes
|
||||
pMan->vComTo0 = Vec_IntAlloc( 2*nFaninMax );
|
||||
pMan->vComTo1 = Vec_IntAlloc( 2*nFaninMax );
|
||||
pMan->vPairs0 = Vec_IntAlloc( nFaninMax );
|
||||
pMan->vPairs1 = Vec_IntAlloc( nFaninMax );
|
||||
pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 );
|
||||
pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 );
|
||||
|
||||
// allocate memory for object structures
|
||||
pMan->pMemory = pMem = ALLOC( Xyz_Obj_t, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) );
|
||||
memset( pMem, 0, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) );
|
||||
// allocate storage for the pointers to the memory
|
||||
pMan->vObjStrs = Vec_PtrAlloc( Abc_NtkObjNumMax(pNtk) );
|
||||
Vec_PtrFill( pMan->vObjStrs, Abc_NtkObjNumMax(pNtk), NULL );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
Vec_PtrWriteEntry( pMan->vObjStrs, i, pMem + i );
|
||||
// create the cube manager
|
||||
pMan->pManMin = Min_ManAlloc( nFaninMax );
|
||||
return pMan;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Xyz_ManFree( Xyz_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vSupp;
|
||||
int i;
|
||||
for ( i = 0; i < p->vObjStrs->nSize; i++ )
|
||||
{
|
||||
vSupp = ((Xyz_Obj_t *)p->vObjStrs->pArray[i])->vSupp;
|
||||
if ( vSupp ) Vec_IntFree( vSupp );
|
||||
}
|
||||
|
||||
Min_ManFree( p->pManMin );
|
||||
Vec_PtrFree( p->vObjStrs );
|
||||
Vec_IntFree( p->vFanCounts );
|
||||
Vec_IntFree( p->vTriv0 );
|
||||
Vec_IntFree( p->vTriv1 );
|
||||
Vec_IntFree( p->vComTo0 );
|
||||
Vec_IntFree( p->vComTo1 );
|
||||
Vec_IntFree( p->vPairs0 );
|
||||
Vec_IntFree( p->vPairs1 );
|
||||
free( p->pMemory );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Drop the covers at the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
int nFanouts;
|
||||
assert( p->vFanCounts );
|
||||
nFanouts = Vec_IntEntry( p->vFanCounts, pObj->Id );
|
||||
assert( nFanouts > 0 );
|
||||
if ( --nFanouts == 0 )
|
||||
{
|
||||
Vec_IntFree( Abc_ObjGetSupp(pObj) );
|
||||
Abc_ObjSetSupp( pObj, NULL );
|
||||
Min_CoverRecycle( p->pManMin, Abc_ObjGetCover2(pObj) );
|
||||
Abc_ObjSetCover2( pObj, NULL );
|
||||
p->nSupps--;
|
||||
}
|
||||
Vec_IntWriteEntry( p->vFanCounts, pObj->Id, nFanouts );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,299 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyzMinEsop.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [ESOP manipulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyzMinEsop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "xyzInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Min_EsopRewrite( Min_Man_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_EsopMinimize( Min_Man_t * p )
|
||||
{
|
||||
int nCubesInit, nCubesOld, nIter;
|
||||
if ( p->nCubes < 3 )
|
||||
return;
|
||||
nIter = 0;
|
||||
nCubesInit = p->nCubes;
|
||||
do {
|
||||
nCubesOld = p->nCubes;
|
||||
Min_EsopRewrite( p );
|
||||
nIter++;
|
||||
}
|
||||
while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 );
|
||||
|
||||
// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs one round of rewriting using distance 2 cubes.]
|
||||
|
||||
Description [The weakness of this procedure is that it tries each cube
|
||||
with only one distance-2 cube. If this pair does not lead to improvement
|
||||
the cube is inserted into the cover anyhow, and we try another pair.
|
||||
A possible improvement would be to try this cube with all distance-2
|
||||
cubes, until an improvement is found, or until all such cubes are tried.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_EsopRewrite( Min_Man_t * p )
|
||||
{
|
||||
Min_Cube_t * pCube, ** ppPrev;
|
||||
Min_Cube_t * pThis, ** ppPrevT;
|
||||
int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld;
|
||||
int nPairs = 0;
|
||||
|
||||
// insert the bubble before the first cube
|
||||
p->pBubble->pNext = p->ppStore[0];
|
||||
p->ppStore[0] = p->pBubble;
|
||||
p->pBubble->nLits = 0;
|
||||
|
||||
// go through the cubes
|
||||
while ( 1 )
|
||||
{
|
||||
// get the index of the bubble
|
||||
Index = p->pBubble->nLits;
|
||||
|
||||
// find the bubble
|
||||
Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev )
|
||||
if ( pCube == p->pBubble )
|
||||
break;
|
||||
assert( pCube == p->pBubble );
|
||||
|
||||
// remove the bubble, get the next cube after the bubble
|
||||
*ppPrev = p->pBubble->pNext;
|
||||
pCube = p->pBubble->pNext;
|
||||
if ( pCube == NULL )
|
||||
for ( Index++; Index <= p->nVars; Index++ )
|
||||
if ( p->ppStore[Index] )
|
||||
{
|
||||
ppPrev = &(p->ppStore[Index]);
|
||||
pCube = p->ppStore[Index];
|
||||
break;
|
||||
}
|
||||
// stop if there is no more cubes
|
||||
if ( pCube == NULL )
|
||||
break;
|
||||
|
||||
// find the first dist2 cube
|
||||
Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
|
||||
if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
|
||||
break;
|
||||
if ( pThis == NULL && Index < p->nVars )
|
||||
Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
|
||||
if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
|
||||
break;
|
||||
if ( pThis == NULL && Index < p->nVars - 1 )
|
||||
Min_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT )
|
||||
if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
|
||||
break;
|
||||
// continue if there is no dist2 cube
|
||||
if ( pThis == NULL )
|
||||
{
|
||||
// insert the bubble after the cube
|
||||
p->pBubble->pNext = pCube->pNext;
|
||||
pCube->pNext = p->pBubble;
|
||||
p->pBubble->nLits = pCube->nLits;
|
||||
continue;
|
||||
}
|
||||
nPairs++;
|
||||
|
||||
// remove the cubes, insert the bubble instead of pCube
|
||||
*ppPrevT = pThis->pNext;
|
||||
*ppPrev = p->pBubble;
|
||||
p->pBubble->pNext = pCube->pNext;
|
||||
p->pBubble->nLits = pCube->nLits;
|
||||
p->nCubes -= 2;
|
||||
|
||||
// Exorlink-2:
|
||||
// A{v00} B{v01} + A{v10} B{v11} =
|
||||
// A{v00+v10} B{v01} + A{v10} B{v01+v11} =
|
||||
// A{v00} B{v01+v11} + A{v00+v10} B{v11}
|
||||
|
||||
// save the dist2 parameters
|
||||
v00 = Min_CubeGetVar( pCube, Var0 );
|
||||
v01 = Min_CubeGetVar( pCube, Var1 );
|
||||
v10 = Min_CubeGetVar( pThis, Var0 );
|
||||
v11 = Min_CubeGetVar( pThis, Var1 );
|
||||
//printf( "\n" );
|
||||
//Min_CubeWrite( stdout, pCube );
|
||||
//Min_CubeWrite( stdout, pThis );
|
||||
|
||||
// derive the first pair of resulting cubes
|
||||
Min_CubeXorVar( pCube, Var0, v10 );
|
||||
pCube->nLits -= (v00 != 3);
|
||||
pCube->nLits += ((v00 ^ v10) != 3);
|
||||
Min_CubeXorVar( pThis, Var1, v01 );
|
||||
pThis->nLits -= (v11 != 3);
|
||||
pThis->nLits += ((v01 ^ v11) != 3);
|
||||
|
||||
// add the cubes
|
||||
nCubesOld = p->nCubes;
|
||||
Min_EsopAddCube( p, pCube );
|
||||
Min_EsopAddCube( p, pThis );
|
||||
// check if the cubes were absorbed
|
||||
if ( p->nCubes < nCubesOld + 2 )
|
||||
continue;
|
||||
|
||||
// pull out both cubes
|
||||
assert( pThis == p->ppStore[pThis->nLits] );
|
||||
p->ppStore[pThis->nLits] = pThis->pNext;
|
||||
assert( pCube == p->ppStore[pCube->nLits] );
|
||||
p->ppStore[pCube->nLits] = pCube->pNext;
|
||||
p->nCubes -= 2;
|
||||
|
||||
// derive the second pair of resulting cubes
|
||||
Min_CubeXorVar( pCube, Var0, v10 );
|
||||
pCube->nLits -= ((v00 ^ v10) != 3);
|
||||
pCube->nLits += (v00 != 3);
|
||||
Min_CubeXorVar( pCube, Var1, v11 );
|
||||
pCube->nLits -= (v01 != 3);
|
||||
pCube->nLits += ((v01 ^ v11) != 3);
|
||||
|
||||
Min_CubeXorVar( pThis, Var0, v00 );
|
||||
pThis->nLits -= (v10 != 3);
|
||||
pThis->nLits += ((v00 ^ v10) != 3);
|
||||
Min_CubeXorVar( pThis, Var1, v01 );
|
||||
pThis->nLits -= ((v01 ^ v11) != 3);
|
||||
pThis->nLits += (v11 != 3);
|
||||
|
||||
// add them anyhow
|
||||
Min_EsopAddCube( p, pCube );
|
||||
Min_EsopAddCube( p, pThis );
|
||||
}
|
||||
// printf( "Pairs = %d ", nPairs );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the cube to storage.]
|
||||
|
||||
Description [Returns 0 if the cube is added or removed. Returns 1
|
||||
if the cube is glued with some other cube and has to be added again.
|
||||
Do not forget to clean the storage!]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube )
|
||||
{
|
||||
Min_Cube_t * pThis, ** ppPrev;
|
||||
// try to find the identical cube
|
||||
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
|
||||
{
|
||||
if ( Min_CubesAreEqual( pCube, pThis ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Min_CubeRecycle( p, pCube );
|
||||
Min_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// find a distance-1 cube if it exists
|
||||
if ( pCube->nLits < pCube->nVars )
|
||||
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev )
|
||||
{
|
||||
if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Min_CubesTransform( pCube, pThis, p->pTemp );
|
||||
pCube->nLits++;
|
||||
Min_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
|
||||
{
|
||||
if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Min_CubesTransform( pCube, pThis, p->pTemp );
|
||||
pCube->nLits--;
|
||||
Min_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ( pCube->nLits > 0 )
|
||||
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev )
|
||||
{
|
||||
if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Min_CubesTransform( pCube, pThis, p->pTemp );
|
||||
Min_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// add the cube
|
||||
pCube->pNext = p->ppStore[pCube->nLits];
|
||||
p->ppStore[pCube->nLits] = pCube;
|
||||
p->nCubes++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the cube to storage.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube )
|
||||
{
|
||||
assert( pCube != p->pBubble );
|
||||
assert( (int)pCube->nLits == Min_CubeCountLits(pCube) );
|
||||
while ( Min_EsopAddCubeInt( p, pCube ) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyzMinMan.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [SOP manipulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyzMinMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "xyzInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the minimization manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Min_Man_t * Min_ManAlloc( int nVars )
|
||||
{
|
||||
Min_Man_t * pMan;
|
||||
// start the manager
|
||||
pMan = ALLOC( Min_Man_t, 1 );
|
||||
memset( pMan, 0, sizeof(Min_Man_t) );
|
||||
pMan->nVars = nVars;
|
||||
pMan->nWords = Abc_BitWordNum( nVars * 2 );
|
||||
pMan->pMemMan = Extra_MmFixedStart( sizeof(Min_Cube_t) + sizeof(unsigned) * (pMan->nWords - 1) );
|
||||
// allocate storage for the temporary cover
|
||||
pMan->ppStore = ALLOC( Min_Cube_t *, pMan->nVars + 1 );
|
||||
// create tautology cubes
|
||||
Min_ManClean( pMan, nVars );
|
||||
pMan->pOne0 = Min_CubeAlloc( pMan );
|
||||
pMan->pOne1 = Min_CubeAlloc( pMan );
|
||||
pMan->pTemp = Min_CubeAlloc( pMan );
|
||||
pMan->pBubble = Min_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0;
|
||||
// create trivial cubes
|
||||
Min_ManClean( pMan, 1 );
|
||||
pMan->pTriv0[0] = Min_CubeAllocVar( pMan, 0, 0 );
|
||||
pMan->pTriv0[1] = Min_CubeAllocVar( pMan, 0, 1 );
|
||||
pMan->pTriv1[0] = Min_CubeAllocVar( pMan, 0, 0 );
|
||||
pMan->pTriv1[1] = Min_CubeAllocVar( pMan, 0, 1 );
|
||||
Min_ManClean( pMan, nVars );
|
||||
return pMan;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cleans the minimization manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_ManClean( Min_Man_t * p, int nSupp )
|
||||
{
|
||||
// set the size of the cube manager
|
||||
p->nVars = nSupp;
|
||||
p->nWords = Abc_BitWordNum(2*nSupp);
|
||||
// clean the storage
|
||||
memset( p->ppStore, 0, sizeof(Min_Cube_t *) * (nSupp + 1) );
|
||||
p->nCubes = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the minimization manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_ManFree( Min_Man_t * p )
|
||||
{
|
||||
Extra_MmFixedStop ( p->pMemMan, 0 );
|
||||
free( p->ppStore );
|
||||
free( p );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,615 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyzMinSop.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [SOP manipulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyzMinSop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "xyzInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Min_SopRewrite( Min_Man_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_SopMinimize( Min_Man_t * p )
|
||||
{
|
||||
int nCubesInit, nCubesOld, nIter;
|
||||
if ( p->nCubes < 3 )
|
||||
return;
|
||||
nIter = 0;
|
||||
nCubesInit = p->nCubes;
|
||||
do {
|
||||
nCubesOld = p->nCubes;
|
||||
Min_SopRewrite( p );
|
||||
nIter++;
|
||||
// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes );
|
||||
}
|
||||
while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 );
|
||||
// printf( "\n" );
|
||||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_SopRewrite( Min_Man_t * p )
|
||||
{
|
||||
Min_Cube_t * pCube, ** ppPrev;
|
||||
Min_Cube_t * pThis, ** ppPrevT;
|
||||
Min_Cube_t * pTemp;
|
||||
int v00, v01, v10, v11, Var0, Var1, Index, fCont0, fCont1, nCubesOld;
|
||||
int nPairs = 0;
|
||||
/*
|
||||
{
|
||||
Min_Cube_t * pCover;
|
||||
pCover = Min_CoverCollect( p, p->nVars );
|
||||
printf( "\n\n" );
|
||||
Min_CoverWrite( stdout, pCover );
|
||||
Min_CoverExpand( p, pCover );
|
||||
}
|
||||
*/
|
||||
|
||||
// insert the bubble before the first cube
|
||||
p->pBubble->pNext = p->ppStore[0];
|
||||
p->ppStore[0] = p->pBubble;
|
||||
p->pBubble->nLits = 0;
|
||||
|
||||
// go through the cubes
|
||||
while ( 1 )
|
||||
{
|
||||
// get the index of the bubble
|
||||
Index = p->pBubble->nLits;
|
||||
|
||||
// find the bubble
|
||||
Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev )
|
||||
if ( pCube == p->pBubble )
|
||||
break;
|
||||
assert( pCube == p->pBubble );
|
||||
|
||||
// remove the bubble, get the next cube after the bubble
|
||||
*ppPrev = p->pBubble->pNext;
|
||||
pCube = p->pBubble->pNext;
|
||||
if ( pCube == NULL )
|
||||
for ( Index++; Index <= p->nVars; Index++ )
|
||||
if ( p->ppStore[Index] )
|
||||
{
|
||||
ppPrev = &(p->ppStore[Index]);
|
||||
pCube = p->ppStore[Index];
|
||||
break;
|
||||
}
|
||||
// stop if there is no more cubes
|
||||
if ( pCube == NULL )
|
||||
break;
|
||||
|
||||
// find the first dist2 cube
|
||||
Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT )
|
||||
if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
|
||||
break;
|
||||
if ( pThis == NULL && Index < p->nVars )
|
||||
Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT )
|
||||
if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) )
|
||||
break;
|
||||
// continue if there is no dist2 cube
|
||||
if ( pThis == NULL )
|
||||
{
|
||||
// insert the bubble after the cube
|
||||
p->pBubble->pNext = pCube->pNext;
|
||||
pCube->pNext = p->pBubble;
|
||||
p->pBubble->nLits = pCube->nLits;
|
||||
continue;
|
||||
}
|
||||
nPairs++;
|
||||
/*
|
||||
printf( "\n" );
|
||||
Min_CubeWrite( stdout, pCube );
|
||||
Min_CubeWrite( stdout, pThis );
|
||||
*/
|
||||
// remove the cubes, insert the bubble instead of pCube
|
||||
*ppPrevT = pThis->pNext;
|
||||
*ppPrev = p->pBubble;
|
||||
p->pBubble->pNext = pCube->pNext;
|
||||
p->pBubble->nLits = pCube->nLits;
|
||||
p->nCubes -= 2;
|
||||
|
||||
assert( pCube != p->pBubble && pThis != p->pBubble );
|
||||
|
||||
|
||||
// save the dist2 parameters
|
||||
v00 = Min_CubeGetVar( pCube, Var0 );
|
||||
v01 = Min_CubeGetVar( pCube, Var1 );
|
||||
v10 = Min_CubeGetVar( pThis, Var0 );
|
||||
v11 = Min_CubeGetVar( pThis, Var1 );
|
||||
assert( v00 != v10 && v01 != v11 );
|
||||
assert( v00 != 3 || v01 != 3 );
|
||||
assert( v10 != 3 || v11 != 3 );
|
||||
|
||||
//printf( "\n" );
|
||||
//Min_CubeWrite( stdout, pCube );
|
||||
//Min_CubeWrite( stdout, pThis );
|
||||
|
||||
//printf( "\n" );
|
||||
//Min_CubeWrite( stdout, pCube );
|
||||
//Min_CubeWrite( stdout, pThis );
|
||||
|
||||
// consider the case when both cubes have non-empty literals
|
||||
if ( v00 != 3 && v01 != 3 && v10 != 3 && v11 != 3 )
|
||||
{
|
||||
assert( v00 == (v10 ^ 3) );
|
||||
assert( v01 == (v11 ^ 3) );
|
||||
// create the temporary cube equal to the first corner
|
||||
Min_CubeXorVar( pCube, Var0, 3 );
|
||||
// check if this cube is contained
|
||||
fCont0 = Min_CoverContainsCube( p, pCube );
|
||||
// create the temporary cube equal to the first corner
|
||||
Min_CubeXorVar( pCube, Var0, 3 );
|
||||
Min_CubeXorVar( pCube, Var1, 3 );
|
||||
//printf( "\n" );
|
||||
//Min_CubeWrite( stdout, pCube );
|
||||
//Min_CubeWrite( stdout, pThis );
|
||||
// check if this cube is contained
|
||||
fCont1 = Min_CoverContainsCube( p, pCube );
|
||||
// undo the change
|
||||
Min_CubeXorVar( pCube, Var1, 3 );
|
||||
|
||||
// check if the cubes can be overwritten
|
||||
if ( fCont0 && fCont1 )
|
||||
{
|
||||
// one of the cubes can be recycled, the other expanded and added
|
||||
Min_CubeRecycle( p, pThis );
|
||||
// remove the literals
|
||||
Min_CubeXorVar( pCube, Var0, v00 ^ 3 );
|
||||
Min_CubeXorVar( pCube, Var1, v01 ^ 3 );
|
||||
pCube->nLits -= 2;
|
||||
Min_SopAddCube( p, pCube );
|
||||
}
|
||||
else if ( fCont0 )
|
||||
{
|
||||
// expand both cubes and add them
|
||||
Min_CubeXorVar( pCube, Var0, v00 ^ 3 );
|
||||
pCube->nLits--;
|
||||
Min_SopAddCube( p, pCube );
|
||||
Min_CubeXorVar( pThis, Var1, v11 ^ 3 );
|
||||
pThis->nLits--;
|
||||
Min_SopAddCube( p, pThis );
|
||||
}
|
||||
else if ( fCont1 )
|
||||
{
|
||||
// expand both cubes and add them
|
||||
Min_CubeXorVar( pCube, Var1, v01 ^ 3 );
|
||||
pCube->nLits--;
|
||||
Min_SopAddCube( p, pCube );
|
||||
Min_CubeXorVar( pThis, Var0, v10 ^ 3 );
|
||||
pThis->nLits--;
|
||||
Min_SopAddCube( p, pThis );
|
||||
}
|
||||
else
|
||||
{
|
||||
Min_SopAddCube( p, pCube );
|
||||
Min_SopAddCube( p, pThis );
|
||||
}
|
||||
// otherwise, no change is possible
|
||||
continue;
|
||||
}
|
||||
|
||||
// if one of them does not have DC lit, move it
|
||||
if ( v00 != 3 && v01 != 3 )
|
||||
{
|
||||
assert( v10 == 3 || v11 == 3 );
|
||||
pTemp = pCube; pCube = pThis; pThis = pTemp;
|
||||
Index = v00; v00 = v10; v10 = Index;
|
||||
Index = v01; v01 = v11; v11 = Index;
|
||||
}
|
||||
|
||||
// make sure the first cube has first var DC
|
||||
if ( v00 != 3 )
|
||||
{
|
||||
assert( v01 == 3 );
|
||||
Index = Var0; Var0 = Var1; Var1 = Index;
|
||||
Index = v00; v00 = v01; v01 = Index;
|
||||
Index = v10; v10 = v11; v11 = Index;
|
||||
}
|
||||
|
||||
// consider both cases: both have DC lit
|
||||
if ( v00 == 3 && v11 == 3 )
|
||||
{
|
||||
assert( v01 != 3 && v10 != 3 );
|
||||
// try the remaining minterm
|
||||
// create the temporary cube equal to the first corner
|
||||
Min_CubeXorVar( pCube, Var0, v10 );
|
||||
Min_CubeXorVar( pCube, Var1, 3 );
|
||||
pCube->nLits++;
|
||||
// check if this cube is contained
|
||||
fCont0 = Min_CoverContainsCube( p, pCube );
|
||||
// undo the cube transformations
|
||||
Min_CubeXorVar( pCube, Var0, v10 );
|
||||
Min_CubeXorVar( pCube, Var1, 3 );
|
||||
pCube->nLits--;
|
||||
// check the case when both are covered
|
||||
if ( fCont0 )
|
||||
{
|
||||
// one of the cubes can be recycled, the other expanded and added
|
||||
Min_CubeRecycle( p, pThis );
|
||||
// remove the literals
|
||||
Min_CubeXorVar( pCube, Var1, v01 ^ 3 );
|
||||
pCube->nLits--;
|
||||
Min_SopAddCube( p, pCube );
|
||||
}
|
||||
else
|
||||
{
|
||||
// try two reduced cubes
|
||||
Min_CubeXorVar( pCube, Var0, v10 );
|
||||
pCube->nLits++;
|
||||
// remember the cubes
|
||||
nCubesOld = p->nCubes;
|
||||
Min_SopAddCube( p, pCube );
|
||||
// check if the cube is absorbed
|
||||
if ( p->nCubes < nCubesOld + 1 )
|
||||
{ // absorbed - add the second cube
|
||||
Min_SopAddCube( p, pThis );
|
||||
}
|
||||
else
|
||||
{ // remove this cube, and try another one
|
||||
assert( pCube == p->ppStore[pCube->nLits] );
|
||||
p->ppStore[pCube->nLits] = pCube->pNext;
|
||||
p->nCubes--;
|
||||
|
||||
// return the cube to the previous state
|
||||
Min_CubeXorVar( pCube, Var0, v10 );
|
||||
pCube->nLits--;
|
||||
|
||||
// generate another reduced cube
|
||||
Min_CubeXorVar( pThis, Var1, v01 );
|
||||
pThis->nLits++;
|
||||
|
||||
// add both cubes
|
||||
Min_SopAddCube( p, pCube );
|
||||
Min_SopAddCube( p, pThis );
|
||||
}
|
||||
}
|
||||
}
|
||||
else // the first cube has DC lit
|
||||
{
|
||||
assert( v01 != 3 && v10 != 3 && v11 != 3 );
|
||||
// try the remaining minterm
|
||||
// create the temporary cube equal to the minterm
|
||||
Min_CubeXorVar( pThis, Var0, 3 );
|
||||
// check if this cube is contained
|
||||
fCont0 = Min_CoverContainsCube( p, pThis );
|
||||
// undo the cube transformations
|
||||
Min_CubeXorVar( pThis, Var0, 3 );
|
||||
// check the case when both are covered
|
||||
if ( fCont0 )
|
||||
{
|
||||
// one of the cubes can be recycled, the other expanded and added
|
||||
Min_CubeRecycle( p, pThis );
|
||||
// remove the literals
|
||||
Min_CubeXorVar( pCube, Var1, v01 ^ 3 );
|
||||
pCube->nLits--;
|
||||
Min_SopAddCube( p, pCube );
|
||||
}
|
||||
else
|
||||
{
|
||||
// try reshaping the cubes
|
||||
// reduce the first cube
|
||||
Min_CubeXorVar( pCube, Var0, v10 );
|
||||
pCube->nLits++;
|
||||
// expand the second cube
|
||||
Min_CubeXorVar( pThis, Var1, v11 ^ 3 );
|
||||
pThis->nLits--;
|
||||
// add both cubes
|
||||
Min_SopAddCube( p, pCube );
|
||||
Min_SopAddCube( p, pThis );
|
||||
}
|
||||
}
|
||||
}
|
||||
// printf( "Pairs = %d ", nPairs );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds cube to the SOP cover stored in the manager.]
|
||||
|
||||
Description [Returns 0 if the cube is added or removed. Returns 1
|
||||
if the cube is glued with some other cube and has to be added again.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Min_SopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube )
|
||||
{
|
||||
Min_Cube_t * pThis, * pThis2, ** ppPrev;
|
||||
int i;
|
||||
// try to find the identical cube
|
||||
Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis )
|
||||
{
|
||||
if ( Min_CubesAreEqual( pCube, pThis ) )
|
||||
{
|
||||
Min_CubeRecycle( p, pCube );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// try to find a containing cube
|
||||
for ( i = 0; i < (int)pCube->nLits; i++ )
|
||||
Min_CoverForEachCube( p->ppStore[i], pThis )
|
||||
{
|
||||
if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) )
|
||||
{
|
||||
Min_CubeRecycle( p, pCube );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// try to find distance one in the same bin
|
||||
Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev )
|
||||
{
|
||||
if ( Min_CubesDistOne( pCube, pThis, NULL ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Min_CubesTransformOr( pCube, pThis );
|
||||
pCube->nLits--;
|
||||
Min_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// clean the other cubes using this one
|
||||
for ( i = pCube->nLits + 1; i <= (int)pCube->nVars; i++ )
|
||||
{
|
||||
ppPrev = &p->ppStore[i];
|
||||
Min_CoverForEachCubeSafe( p->ppStore[i], pThis, pThis2 )
|
||||
{
|
||||
if ( pThis != p->pBubble && Min_CubeIsContained( pCube, pThis ) )
|
||||
{
|
||||
*ppPrev = pThis->pNext;
|
||||
Min_CubeRecycle( p, pThis );
|
||||
p->nCubes--;
|
||||
}
|
||||
else
|
||||
ppPrev = &pThis->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
// add the cube
|
||||
pCube->pNext = p->ppStore[pCube->nLits];
|
||||
p->ppStore[pCube->nLits] = pCube;
|
||||
p->nCubes++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the cube to storage.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube )
|
||||
{
|
||||
assert( Min_CubeCheck( pCube ) );
|
||||
assert( pCube != p->pBubble );
|
||||
assert( (int)pCube->nLits == Min_CubeCountLits(pCube) );
|
||||
while ( Min_SopAddCubeInt( p, pCube ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_SopContain( Min_Man_t * p )
|
||||
{
|
||||
Min_Cube_t * pCube, * pCube2, ** ppPrev;
|
||||
int i, k;
|
||||
for ( i = 0; i <= p->nVars; i++ )
|
||||
{
|
||||
Min_CoverForEachCube( p->ppStore[i], pCube )
|
||||
Min_CoverForEachCubePrev( pCube->pNext, pCube2, ppPrev )
|
||||
{
|
||||
if ( !Min_CubesAreEqual( pCube, pCube2 ) )
|
||||
continue;
|
||||
*ppPrev = pCube2->pNext;
|
||||
Min_CubeRecycle( p, pCube2 );
|
||||
p->nCubes--;
|
||||
}
|
||||
for ( k = i + 1; k <= p->nVars; k++ )
|
||||
Min_CoverForEachCubePrev( p->ppStore[k], pCube2, ppPrev )
|
||||
{
|
||||
if ( !Min_CubeIsContained( pCube, pCube2 ) )
|
||||
continue;
|
||||
*ppPrev = pCube2->pNext;
|
||||
Min_CubeRecycle( p, pCube2 );
|
||||
p->nCubes--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_SopDist1Merge( Min_Man_t * p )
|
||||
{
|
||||
Min_Cube_t * pCube, * pCube2, * pCubeNew;
|
||||
int i;
|
||||
for ( i = p->nVars; i >= 0; i-- )
|
||||
{
|
||||
Min_CoverForEachCube( p->ppStore[i], pCube )
|
||||
Min_CoverForEachCube( pCube->pNext, pCube2 )
|
||||
{
|
||||
assert( pCube->nLits == pCube2->nLits );
|
||||
if ( !Min_CubesDistOne( pCube, pCube2, NULL ) )
|
||||
continue;
|
||||
pCubeNew = Min_CubesXor( p, pCube, pCube2 );
|
||||
assert( pCubeNew->nLits == pCube->nLits - 1 );
|
||||
pCubeNew->pNext = p->ppStore[pCubeNew->nLits];
|
||||
p->ppStore[pCubeNew->nLits] = pCubeNew;
|
||||
p->nCubes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Min_Cube_t * Min_SopComplement( Min_Man_t * p, Min_Cube_t * pSharp )
|
||||
{
|
||||
Vec_Int_t * vVars;
|
||||
Min_Cube_t * pCover, * pCube, * pNext, * pReady, * pThis, ** ppPrev;
|
||||
int Num, Value, i;
|
||||
|
||||
// get the variables
|
||||
vVars = Vec_IntAlloc( 100 );
|
||||
// create the tautology cube
|
||||
pCover = Min_CubeAlloc( p );
|
||||
// sharp it with all cubes
|
||||
Min_CoverForEachCube( pSharp, pCube )
|
||||
Min_CoverForEachCubePrev( pCover, pThis, ppPrev )
|
||||
{
|
||||
if ( Min_CubesDisjoint( pThis, pCube ) )
|
||||
continue;
|
||||
// remember the next pointer
|
||||
pNext = pThis->pNext;
|
||||
// get the variables, in which pThis is '-' while pCube is fixed
|
||||
Min_CoverGetDisjVars( pThis, pCube, vVars );
|
||||
// generate the disjoint cubes
|
||||
pReady = pThis;
|
||||
Vec_IntForEachEntryReverse( vVars, Num, i )
|
||||
{
|
||||
// correct the literal
|
||||
Min_CubeXorVar( pReady, vVars->pArray[i], 3 );
|
||||
if ( i == 0 )
|
||||
break;
|
||||
// create the new cube and clean this value
|
||||
Value = Min_CubeGetVar( pReady, vVars->pArray[i] );
|
||||
pReady = Min_CubeDup( p, pReady );
|
||||
Min_CubeXorVar( pReady, vVars->pArray[i], 3 ^ Value );
|
||||
// add to the cover
|
||||
*ppPrev = pReady;
|
||||
ppPrev = &pReady->pNext;
|
||||
}
|
||||
pThis = pReady;
|
||||
pThis->pNext = pNext;
|
||||
}
|
||||
Vec_IntFree( vVars );
|
||||
|
||||
// perform dist-1 merge and contain
|
||||
Min_CoverExpandRemoveEqual( p, pCover );
|
||||
Min_SopDist1Merge( p );
|
||||
Min_SopContain( p );
|
||||
return Min_CoverCollect( p, p->nVars );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Min_SopCheck( Min_Man_t * p )
|
||||
{
|
||||
Min_Cube_t * pCube, * pThis;
|
||||
int i;
|
||||
|
||||
pCube = Min_CubeAlloc( p );
|
||||
Min_CubeXorBit( pCube, 2*0+1 );
|
||||
Min_CubeXorBit( pCube, 2*1+1 );
|
||||
Min_CubeXorBit( pCube, 2*2+0 );
|
||||
Min_CubeXorBit( pCube, 2*3+0 );
|
||||
Min_CubeXorBit( pCube, 2*4+0 );
|
||||
Min_CubeXorBit( pCube, 2*5+1 );
|
||||
Min_CubeXorBit( pCube, 2*6+1 );
|
||||
pCube->nLits = 7;
|
||||
|
||||
// Min_CubeWrite( stdout, pCube );
|
||||
|
||||
// check that the cubes contain it
|
||||
for ( i = 0; i <= p->nVars; i++ )
|
||||
Min_CoverForEachCube( p->ppStore[i], pThis )
|
||||
if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) )
|
||||
{
|
||||
Min_CubeRecycle( p, pCube );
|
||||
return 1;
|
||||
}
|
||||
Min_CubeRecycle( p, pCube );
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,277 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyzMinUtil.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Utilities.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyzMinUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "xyzInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube )
|
||||
{
|
||||
int i;
|
||||
assert( (int)pCube->nLits == Min_CubeCountLits(pCube) );
|
||||
for ( i = 0; i < (int)pCube->nVars; i++ )
|
||||
if ( Min_CubeHasBit(pCube, i*2) )
|
||||
{
|
||||
if ( Min_CubeHasBit(pCube, i*2+1) )
|
||||
fprintf( pFile, "-" );
|
||||
else
|
||||
fprintf( pFile, "0" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Min_CubeHasBit(pCube, i*2+1) )
|
||||
fprintf( pFile, "1" );
|
||||
else
|
||||
fprintf( pFile, "?" );
|
||||
}
|
||||
fprintf( pFile, " 1\n" );
|
||||
// fprintf( pFile, " %d\n", pCube->nLits );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
Min_CoverForEachCube( pCover, pCube )
|
||||
Min_CubeWrite( pFile, pCube );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
int i;
|
||||
for ( i = 0; i <= p->nVars; i++ )
|
||||
{
|
||||
Min_CoverForEachCube( p->ppStore[i], pCube )
|
||||
{
|
||||
printf( "%2d : ", i );
|
||||
if ( pCube == p->pBubble )
|
||||
{
|
||||
printf( "Bubble\n" );
|
||||
continue;
|
||||
}
|
||||
Min_CubeWrite( pFile, pCube );
|
||||
}
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop )
|
||||
{
|
||||
char Buffer[1000];
|
||||
Min_Cube_t * pCube;
|
||||
FILE * pFile;
|
||||
int i;
|
||||
sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" );
|
||||
for ( i = strlen(Buffer) - 1; i >= 0; i-- )
|
||||
if ( Buffer[i] == '<' || Buffer[i] == '>' )
|
||||
Buffer[i] = '_';
|
||||
pFile = fopen( Buffer, "w" );
|
||||
fprintf( pFile, "# %s cover for output %s generated by ABC on %s\n", fEsop? "ESOP":"SOP", pName, Extra_TimeStamp() );
|
||||
fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 );
|
||||
fprintf( pFile, ".o %d\n", 1 );
|
||||
fprintf( pFile, ".p %d\n", Min_CoverCountCubes(pCover) );
|
||||
if ( fEsop ) fprintf( pFile, ".type esop\n" );
|
||||
Min_CoverForEachCube( pCover, pCube )
|
||||
Min_CubeWrite( pFile, pCube );
|
||||
fprintf( pFile, ".e\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_CoverCheck( Min_Man_t * p )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
int i;
|
||||
for ( i = 0; i <= p->nVars; i++ )
|
||||
Min_CoverForEachCube( p->ppStore[i], pCube )
|
||||
assert( i == (int)pCube->nLits );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Min_CubeCheck( Min_Cube_t * pCube )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < (int)pCube->nVars; i++ )
|
||||
if ( Min_CubeGetVar( pCube, i ) == 0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts the cover from the sorted structure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize )
|
||||
{
|
||||
Min_Cube_t * pCov = NULL, ** ppTail = &pCov;
|
||||
Min_Cube_t * pCube, * pCube2;
|
||||
int i;
|
||||
for ( i = 0; i <= nSuppSize; i++ )
|
||||
{
|
||||
Min_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 )
|
||||
{
|
||||
assert( i == (int)pCube->nLits );
|
||||
*ppTail = pCube;
|
||||
ppTail = &pCube->pNext;
|
||||
assert( pCube->uData[0] ); // not a bubble
|
||||
}
|
||||
}
|
||||
*ppTail = NULL;
|
||||
return pCov;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts the cover in the increasing number of literals.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover )
|
||||
{
|
||||
Min_Cube_t * pCube, * pCube2;
|
||||
Min_ManClean( p, p->nVars );
|
||||
Min_CoverForEachCubeSafe( pCover, pCube, pCube2 )
|
||||
{
|
||||
pCube->pNext = p->ppStore[pCube->nLits];
|
||||
p->ppStore[pCube->nLits] = pCube;
|
||||
p->nCubes++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts the cover in the increasing number of literals.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover )
|
||||
{
|
||||
Min_Cube_t * pCube;
|
||||
int i, Counter;
|
||||
if ( pCover == NULL )
|
||||
return 0;
|
||||
// clean the cube
|
||||
for ( i = 0; i < (int)pCover->nWords; i++ )
|
||||
p->pTemp->uData[i] = ~((unsigned)0);
|
||||
// add the bit data
|
||||
Min_CoverForEachCube( pCover, pCube )
|
||||
for ( i = 0; i < (int)pCover->nWords; i++ )
|
||||
p->pTemp->uData[i] &= pCube->uData[i];
|
||||
// count the vars
|
||||
Counter = 0;
|
||||
for ( i = 0; i < (int)pCover->nVars; i++ )
|
||||
Counter += ( Min_CubeGetVar(p->pTemp, i) != 3 );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,417 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [xyzTest.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Cover manipulation package.]
|
||||
|
||||
Synopsis [Testing procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: xyzTest.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "xyz.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Min_Cube_t * Abc_NodeDeriveCoverPro( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 )
|
||||
{
|
||||
Min_Cube_t * pCover;
|
||||
Min_Cube_t * pCube0, * pCube1, * pCube;
|
||||
if ( pCover0 == NULL || pCover1 == NULL )
|
||||
return NULL;
|
||||
// clean storage
|
||||
Min_ManClean( p, p->nVars );
|
||||
// go through the cube pairs
|
||||
Min_CoverForEachCube( pCover0, pCube0 )
|
||||
Min_CoverForEachCube( pCover1, pCube1 )
|
||||
{
|
||||
if ( Min_CubesDisjoint( pCube0, pCube1 ) )
|
||||
continue;
|
||||
pCube = Min_CubesProduct( p, pCube0, pCube1 );
|
||||
// add the cube to storage
|
||||
Min_SopAddCube( p, pCube );
|
||||
}
|
||||
Min_SopMinimize( p );
|
||||
pCover = Min_CoverCollect( p, p->nVars );
|
||||
assert( p->nCubes == Min_CoverCountCubes(pCover) );
|
||||
return pCover;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Min_Cube_t * Abc_NodeDeriveCoverSum( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 )
|
||||
{
|
||||
Min_Cube_t * pCover;
|
||||
Min_Cube_t * pThis, * pCube;
|
||||
if ( pCover0 == NULL || pCover1 == NULL )
|
||||
return NULL;
|
||||
// clean storage
|
||||
Min_ManClean( p, p->nVars );
|
||||
// add the cubes to storage
|
||||
Min_CoverForEachCube( pCover0, pThis )
|
||||
{
|
||||
pCube = Min_CubeDup( p, pThis );
|
||||
Min_SopAddCube( p, pCube );
|
||||
}
|
||||
Min_CoverForEachCube( pCover1, pThis )
|
||||
{
|
||||
pCube = Min_CubeDup( p, pThis );
|
||||
Min_SopAddCube( p, pCube );
|
||||
}
|
||||
Min_SopMinimize( p );
|
||||
pCover = Min_CoverCollect( p, p->nVars );
|
||||
assert( p->nCubes == Min_CoverCountCubes(pCover) );
|
||||
return pCover;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NodeDeriveSops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Min_Cube_t * pCov0[2], * pCov1[2];
|
||||
Min_Cube_t * pCoverP, * pCoverN;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, nCubes, fCompl0, fCompl1;
|
||||
|
||||
// set elementary vars
|
||||
Vec_PtrForEachEntry( vSupp, pObj, i )
|
||||
{
|
||||
pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 );
|
||||
pObj->pNext = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 1 );
|
||||
}
|
||||
|
||||
// get the cover for each node in the array
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
// get the complements
|
||||
fCompl0 = Abc_ObjFaninC0(pObj);
|
||||
fCompl1 = Abc_ObjFaninC1(pObj);
|
||||
// get the covers
|
||||
pCov0[0] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy;
|
||||
pCov0[1] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pNext;
|
||||
pCov1[0] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy;
|
||||
pCov1[1] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pNext;
|
||||
// compute the covers
|
||||
pCoverP = Abc_NodeDeriveCoverPro( p, pCov0[ fCompl0], pCov1[ fCompl1] );
|
||||
pCoverN = Abc_NodeDeriveCoverSum( p, pCov0[!fCompl0], pCov1[!fCompl1] );
|
||||
// set the covers
|
||||
pObj->pCopy = (Abc_Obj_t *)pCoverP;
|
||||
pObj->pNext = (Abc_Obj_t *)pCoverN;
|
||||
}
|
||||
|
||||
nCubes = ABC_MIN( Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverP) );
|
||||
|
||||
/*
|
||||
printf( "\n\n" );
|
||||
Min_CoverWrite( stdout, pCoverP );
|
||||
printf( "\n\n" );
|
||||
Min_CoverWrite( stdout, pCoverN );
|
||||
*/
|
||||
|
||||
// printf( "\n" );
|
||||
// Min_CoverWrite( stdout, pCoverP );
|
||||
|
||||
// Min_CoverExpand( p, pCoverP );
|
||||
// Min_SopMinimize( p );
|
||||
// pCoverP = Min_CoverCollect( p, p->nVars );
|
||||
|
||||
// printf( "\n" );
|
||||
// Min_CoverWrite( stdout, pCoverP );
|
||||
|
||||
// nCubes = Min_CoverCountCubes(pCoverP);
|
||||
|
||||
// clean the copy fields
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
pObj->pCopy = pObj->pNext = NULL;
|
||||
Vec_PtrForEachEntry( vSupp, pObj, i )
|
||||
pObj->pCopy = pObj->pNext = NULL;
|
||||
|
||||
// Min_CoverWriteFile( pCoverP, Abc_ObjName(pRoot), 0 );
|
||||
// printf( "\n" );
|
||||
// Min_CoverWrite( stdout, pCoverP );
|
||||
|
||||
// printf( "\n" );
|
||||
// Min_CoverWrite( stdout, pCoverP );
|
||||
// printf( "\n" );
|
||||
// Min_CoverWrite( stdout, pCoverN );
|
||||
return nCubes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkTestSop( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Min_Man_t * p;
|
||||
Vec_Ptr_t * vSupp, * vNodes;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, nCubes;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
||||
Abc_NtkCleanCopy(pNtk);
|
||||
Abc_NtkCleanNext(pNtk);
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
{
|
||||
if ( !Abc_NodeIsAigAnd(Abc_ObjFanin0(pObj)) )
|
||||
{
|
||||
printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) );
|
||||
continue;
|
||||
}
|
||||
|
||||
vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
|
||||
vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 );
|
||||
|
||||
printf( "%20s : Cone = %5d. Supp = %5d. ",
|
||||
Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize );
|
||||
// if ( vSupp->nSize <= 128 )
|
||||
{
|
||||
p = Min_ManAlloc( vSupp->nSize );
|
||||
nCubes = Abc_NodeDeriveSops( p, pObj, vSupp, vNodes );
|
||||
printf( "Cubes = %5d. ", nCubes );
|
||||
Min_ManFree( p );
|
||||
}
|
||||
printf( "\n" );
|
||||
|
||||
|
||||
Vec_PtrFree( vNodes );
|
||||
Vec_PtrFree( vSupp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Min_Cube_t * Abc_NodeDeriveCover( Min_Man_t * p, Min_Cube_t * pCov0, Min_Cube_t * pCov1, int fComp0, int fComp1 )
|
||||
{
|
||||
Min_Cube_t * pCover0, * pCover1, * pCover;
|
||||
Min_Cube_t * pCube0, * pCube1, * pCube;
|
||||
|
||||
// complement the first if needed
|
||||
if ( !fComp0 )
|
||||
pCover0 = pCov0;
|
||||
else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube
|
||||
pCover0 = pCov0->pNext;
|
||||
else
|
||||
pCover0 = p->pOne0, p->pOne0->pNext = pCov0;
|
||||
|
||||
// complement the second if needed
|
||||
if ( !fComp1 )
|
||||
pCover1 = pCov1;
|
||||
else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube
|
||||
pCover1 = pCov1->pNext;
|
||||
else
|
||||
pCover1 = p->pOne1, p->pOne1->pNext = pCov1;
|
||||
|
||||
if ( pCover0 == NULL || pCover1 == NULL )
|
||||
return NULL;
|
||||
|
||||
// clean storage
|
||||
Min_ManClean( p, p->nVars );
|
||||
// go through the cube pairs
|
||||
Min_CoverForEachCube( pCover0, pCube0 )
|
||||
Min_CoverForEachCube( pCover1, pCube1 )
|
||||
{
|
||||
if ( Min_CubesDisjoint( pCube0, pCube1 ) )
|
||||
continue;
|
||||
pCube = Min_CubesProduct( p, pCube0, pCube1 );
|
||||
// add the cube to storage
|
||||
Min_EsopAddCube( p, pCube );
|
||||
}
|
||||
|
||||
if ( p->nCubes > 10 )
|
||||
{
|
||||
// printf( "(%d,", p->nCubes );
|
||||
Min_EsopMinimize( p );
|
||||
// printf( "%d) ", p->nCubes );
|
||||
}
|
||||
|
||||
pCover = Min_CoverCollect( p, p->nVars );
|
||||
assert( p->nCubes == Min_CoverCountCubes(pCover) );
|
||||
|
||||
// if ( p->nCubes > 1000 )
|
||||
// printf( "%d ", p->nCubes );
|
||||
return pCover;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NodeDeriveEsops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Min_Cube_t * pCover, * pCube;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
|
||||
// set elementary vars
|
||||
Vec_PtrForEachEntry( vSupp, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 );
|
||||
|
||||
// get the cover for each node in the array
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
pCover = Abc_NodeDeriveCover( p,
|
||||
(Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy,
|
||||
(Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy,
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
||||
pObj->pCopy = (Abc_Obj_t *)pCover;
|
||||
if ( p->nCubes > 3000 )
|
||||
return -1;
|
||||
}
|
||||
|
||||
// add complement if needed
|
||||
if ( Abc_ObjFaninC0(pRoot) )
|
||||
{
|
||||
if ( pCover && pCover->nLits == 0 ) // topmost one is the tautology cube
|
||||
{
|
||||
pCube = pCover;
|
||||
pCover = pCover->pNext;
|
||||
Min_CubeRecycle( p, pCube );
|
||||
p->nCubes--;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCube = Min_CubeAlloc( p );
|
||||
pCube->pNext = pCover;
|
||||
p->nCubes++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Min_CoverExpand( p, pCover );
|
||||
Min_EsopMinimize( p );
|
||||
pCover = Min_CoverCollect( p, p->nVars );
|
||||
*/
|
||||
// clean the copy fields
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
pObj->pCopy = NULL;
|
||||
Vec_PtrForEachEntry( vSupp, pObj, i )
|
||||
pObj->pCopy = NULL;
|
||||
|
||||
// Min_CoverWriteFile( pCover, Abc_ObjName(pRoot), 1 );
|
||||
// Min_CoverWrite( stdout, pCover );
|
||||
return p->nCubes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkTestEsop( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Min_Man_t * p;
|
||||
Vec_Ptr_t * vSupp, * vNodes;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, nCubes;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
||||
Abc_NtkCleanCopy(pNtk);
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
{
|
||||
if ( !Abc_NodeIsAigAnd(Abc_ObjFanin0(pObj)) )
|
||||
{
|
||||
printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) );
|
||||
continue;
|
||||
}
|
||||
|
||||
vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
|
||||
vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 );
|
||||
|
||||
printf( "%20s : Cone = %5d. Supp = %5d. ",
|
||||
Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize );
|
||||
// if ( vSupp->nSize <= 128 )
|
||||
{
|
||||
p = Min_ManAlloc( vSupp->nSize );
|
||||
nCubes = Abc_NodeDeriveEsops( p, pObj, vSupp, vNodes );
|
||||
printf( "Cubes = %5d. ", nCubes );
|
||||
Min_ManFree( p );
|
||||
}
|
||||
printf( "\n" );
|
||||
|
||||
|
||||
Vec_PtrFree( vNodes );
|
||||
Vec_PtrFree( vSupp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
7
todo.txt
7
todo.txt
|
|
@ -47,3 +47,10 @@ Other great projects:
|
|||
Other:
|
||||
|
||||
- completely silent mode
|
||||
|
||||
High-priority changes:
|
||||
|
||||
- add a new mode to "fpga" to differentiate latch-to-latch and pad-to-latch paths
|
||||
- support asynchronous set/reset in retiming and retiming/mapping
|
||||
- port "mfs" into ABC
|
||||
- reduce the latch count in the new version of "retime" and "spfga"
|
||||
Loading…
Reference in New Issue