Version abc80207

This commit is contained in:
Alan Mishchenko 2008-02-07 08:01:00 -08:00
parent 7174787aba
commit 5a6924060b
20 changed files with 672 additions and 3539 deletions

1201
abc.plg

File diff suppressed because it is too large Load Diff

2208
abclib.plg

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: abctestlib - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP20B8.tmp" with contents
[
/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Release/abctestlib.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
"C:\_projects\abc\demo.c"
]
Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP20B8.tmp"
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP20B9.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib C:\_projects\abc\abclib\abclib_release.lib /nologo /subsystem:console /incremental:no /pdb:"Release/abctestlib.pdb" /machine:I386 /out:"_TEST/abctestlib.exe"
.\Release\demo.obj
]
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP20B9.tmp"
<h3>Output Window</h3>
Compiling...
demo.c
Linking...
<h3>Results</h3>
abctestlib.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -39,7 +39,7 @@ extern "C" {
#include "aig.h"
#include "dar.h"
#include "satSolver.h"
//#include "bar.h"
#include "ioa.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///

View File

@ -1530,7 +1530,7 @@ void Fra_ClausWriteIndClauses( Clu_Man_t * p )
extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
Aig_Man_t * pNew;
Aig_Obj_t * pClause, * pLiteral;
char Buffer[500];
char Buffer[500], * pName;
int * pStart, * pVar2Id;
int Beg, End, i, k;
// create mapping from SAT vars to node IDs
@ -1561,7 +1561,9 @@ void Fra_ClausWriteIndClauses( Clu_Man_t * p )
free( pVar2Id );
Aig_ManCleanup( pNew );
// write the manager into a file
sprintf( Buffer, "%s_care.aig", p->pAig->pName );
pName = Ioa_FileNameGeneric(p->pAig->pName);
sprintf( Buffer, "%s_care.aig", pName );
free( pName );
printf( "Care clauses are written into file \"%s\".\n", Buffer );
Ioa_WriteAiger( pNew, Buffer, 0, 1 );
Aig_ManStop( pNew );

View File

@ -130,7 +130,7 @@ int Fra_OneHotNodesAreClause( Fra_Sml_t * pSeq, Aig_Obj_t * pObj1, Aig_Obj_t * p
***********************************************************************/
Vec_Int_t * Fra_OneHotCompute( Fra_Man_t * p, Fra_Sml_t * pSim )
{
int fSkipConstEqu = 1;
int fSkipConstEqu = 0;
Vec_Int_t * vOneHots;
Aig_Obj_t * pObj1, * pObj2;
int i, k;

View File

@ -471,12 +471,14 @@ clk2 = clock();
if ( p->pPars->fWriteImps && p->vOneHots && Fra_OneHotCount(p, p->vOneHots) )
{
extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
char Buffer[500];
char Buffer[500], * pStart;
Aig_Man_t * pNew;
pManAigNew = Aig_ManDup( pManAig, 1 );
// pManAigNew->pManExdc = Fra_OneHotCreateExdc( p, p->vOneHots );
pNew = Fra_OneHotCreateExdc( p, p->vOneHots );
sprintf( Buffer, "%s_care.aig", p->pManAig->pName );
pStart = Ioa_FileNameGeneric(p->pManAig->pName);
sprintf( Buffer, "%s_care.aig", pStart );
free( pStart );
printf( "Care one-hotness clauses are written into file \"%s\".\n", Buffer );
Ioa_WriteAiger( pNew, Buffer, 0, 1 );
Aig_ManStop( pNew );

View File

@ -1025,7 +1025,7 @@ int Abc_NtkLevelReverse( Abc_Ntk_t * pNtk )
return LevelsMax;
}
/**Function*************************************************************
Synopsis [Recursively detects combinational loops.]

View File

@ -3130,7 +3130,7 @@ int Abc_CommandImfs( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->nWindow = 62;
pPars->nCands = 5;
pPars->nSimWords = 4;
pPars->nGrowthLevel = 0;
pPars->nGrowthLevel = 1;
pPars->fArea = 0;
pPars->fVerbose = 0;
pPars->fVeryVerbose = 0;
@ -3225,7 +3225,7 @@ usage:
fprintf( pErr, "\t-W <NM> : fanin/fanout levels (NxM) of the window (00 <= NM <= 99) [default = %d%d]\n", pPars->nWindow/10, pPars->nWindow%10 );
fprintf( pErr, "\t-C <num> : the max number of resub candidates (1 <= n) [default = %d]\n", pPars->nCands );
fprintf( pErr, "\t-S <num> : the number of simulation words (1 <= n <= 256) [default = %d]\n", pPars->nSimWords );
fprintf( pErr, "\t-L <num> : the largest increase in node level after resynthesis (0 <= num) [default = %d]\n", pPars->nGrowthLevel );
fprintf( pErr, "\t-L <num> : the max increase in node level after resynthesis (0 <= num) [default = %d]\n", pPars->nGrowthLevel );
fprintf( pErr, "\t-a : toggle optimization for area only [default = %s]\n", pPars->fArea? "yes": "no" );
fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( pErr, "\t-w : toggle printout subgraph statistics [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
@ -3264,13 +3264,15 @@ int Abc_CommandMfs( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->nDepthMax = 20;
pPars->nDivMax = 200;
pPars->nWinSizeMax = 300;
pPars->nGrowthLevel = 0;
pPars->nGrowthLevel = 1;
pPars->fResub = 1;
pPars->fArea = 0;
pPars->fMoreEffort = 0;
pPars->fSwapEdge = 0;
pPars->fVerbose = 0;
pPars->fVeryVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLravwh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLraesvwh" ) ) != EOF )
{
switch ( c )
{
@ -3335,6 +3337,12 @@ int Abc_CommandMfs( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'a':
pPars->fArea ^= 1;
break;
case 'e':
pPars->fMoreEffort ^= 1;
break;
case 's':
pPars->fSwapEdge ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
break;
@ -3368,15 +3376,17 @@ int Abc_CommandMfs( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: mfs [-WFDML <num>] [-arvh]\n" );
fprintf( pErr, "usage: mfs [-WFDML <num>] [-raesvh]\n" );
fprintf( pErr, "\t performs don't-care-based optimization of logic networks\n" );
fprintf( pErr, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nWinTfoLevs );
fprintf( pErr, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nFanoutsMax );
fprintf( pErr, "\t-D <num> : the max depth nodes to try (0 = no limit) [default = %d]\n", pPars->nDepthMax );
fprintf( pErr, "\t-M <num> : the max size of window to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax );
fprintf( pErr, "\t-L <num> : the largest increase in node level after resynthesis (0 <= num) [default = %d]\n", pPars->nGrowthLevel );
fprintf( pErr, "\t-a : toggle minimizing area or edges [default = %s]\n", pPars->fArea? "area": "edges" );
fprintf( pErr, "\t-L <num> : the max increase in node level after resynthesis (0 <= num) [default = %d]\n", pPars->nGrowthLevel );
fprintf( pErr, "\t-r : toggle resubstitution and dc-minimization [default = %s]\n", pPars->fResub? "resub": "dc-min" );
fprintf( pErr, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" );
fprintf( pErr, "\t-e : toggle high-effort resubstitution [default = %s]\n", pPars->fMoreEffort? "yes": "no" );
fprintf( pErr, "\t-s : toggle evaluation of edge swapping [default = %s]\n", pPars->fSwapEdge? "yes": "no" );
fprintf( pErr, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( pErr, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
@ -6208,12 +6218,14 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
int fSorter;
int fMesh;
int fFpga;
int fOneHot;
int fVerbose;
char * FileName;
extern void Abc_GenAdder( char * pFileName, int nVars );
extern void Abc_GenSorter( char * pFileName, int nVars );
extern void Abc_GenMesh( char * pFileName, int nVars );
extern void Abc_GenFpga( char * pFileName, int nLutSize, int nLuts, int nVars );
extern void Abc_GenOneHot( char * pFileName, int nVars );
pNtk = Abc_FrameReadNtk(pAbc);
@ -6226,9 +6238,10 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
fSorter = 0;
fMesh = 0;
fFpga = 0;
fOneHot = 0;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nasmfvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "Nasmftvh" ) ) != EOF )
{
switch ( c )
{
@ -6255,6 +6268,9 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'f':
fFpga ^= 1;
break;
case 't':
fOneHot ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
@ -6282,18 +6298,21 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_GenFpga( FileName, 4, 3, 10 );
// Abc_GenFpga( FileName, 2, 2, 3 );
// Abc_GenFpga( FileName, 3, 2, 5 );
else if ( fOneHot )
Abc_GenOneHot( FileName, nVars );
else
printf( "Type of circuit is not specified.\n" );
return 0;
usage:
fprintf( pErr, "usage: gen [-N] [-asmfvh] <file>\n" );
fprintf( pErr, "usage: gen [-N num] [-asmftvh] <file>\n" );
fprintf( pErr, "\t generates simple circuits\n" );
fprintf( pErr, "\t-N num : the number of variables [default = %d]\n", nVars );
fprintf( pErr, "\t-a : generate ripple-carry adder [default = %s]\n", fAdder? "yes": "no" );
fprintf( pErr, "\t-s : generate a sorter [default = %s]\n", fSorter? "yes": "no" );
fprintf( pErr, "\t-m : generate a mesh [default = %s]\n", fMesh? "yes": "no" );
fprintf( pErr, "\t-f : generate a LUT FPGA structure [default = %s]\n", fFpga? "yes": "no" );
fprintf( pErr, "\t-t : generate one-hotness conditions [default = %s]\n", fOneHot? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
fprintf( pErr, "\t<file> : output file name\n");
@ -6634,7 +6653,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
extern Abc_Ntk_t * Abc_NtkDarToCnf( Abc_Ntk_t * pNtk, char * pFileName );
extern Abc_Ntk_t * Abc_NtkFilter( Abc_Ntk_t * pNtk );
// extern Abc_Ntk_t * Abc_NtkDarRetime( Abc_Ntk_t * pNtk, int nStepsMax, int fVerbose );
extern Abc_Ntk_t * Abc_NtkPcmTest( Abc_Ntk_t * pNtk, int fVerbose );
// extern Abc_Ntk_t * Abc_NtkPcmTest( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_NtkDarHaigRecord( Abc_Ntk_t * pNtk );
// extern void Abc_NtkDarTestBlif( char * pFileName );

View File

@ -504,6 +504,48 @@ void Abc_GenFpga( char * pFileName, int nLutSize, int nLuts, int nVars )
fclose( pFile );
}
/**Function*************************************************************
Synopsis [Generates structure of L K-LUTs implementing an N-var function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_GenOneHot( char * pFileName, int nVars )
{
FILE * pFile;
int i, k, Counter, nDigitsIn, nDigitsOut;
pFile = fopen( pFileName, "w" );
fprintf( pFile, "# One-hotness condition for %d vars generated by ABC on %s\n", nVars, Extra_TimeStamp() );
fprintf( pFile, ".model 1hot_%dvars\n", nVars );
fprintf( pFile, ".inputs" );
nDigitsIn = Extra_Base10Log( nVars );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " i%0*d", nDigitsIn, i );
fprintf( pFile, "\n" );
fprintf( pFile, ".outputs" );
nDigitsOut = Extra_Base10Log( nVars * (nVars - 1) / 2 );
for ( i = 0; i < nVars * (nVars - 1) / 2; i++ )
fprintf( pFile, " o%0*d", nDigitsOut, i );
fprintf( pFile, "\n" );
Counter = 0;
for ( i = 0; i < nVars; i++ )
for ( k = i+1; k < nVars; k++ )
{
fprintf( pFile, ".names i%0*d i%0*d o%0*d\n", nDigitsIn, i, nDigitsIn, k, nDigitsOut, Counter );
fprintf( pFile, "11 0\n" );
Counter++;
}
fprintf( pFile, ".end\n" );
fprintf( pFile, "\n" );
fclose( pFile );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1130,6 +1130,7 @@ int Abc_NtkCombinePos( Abc_Ntk_t * pNtk, int fAnd )
pNode = Abc_NtkCreatePo( pNtk );
Abc_ObjAddFanin( pNode, pMiter );
Abc_ObjAssignName( pNode, "miter", NULL );
Abc_NtkOrderCisCos( pNtk );
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtk ) )
{

View File

@ -46,6 +46,7 @@ static int CmdCommandRecall ( Abc_Frame_t * pAbc, int argc, char ** argv
static int CmdCommandEmpty ( Abc_Frame_t * pAbc, int argc, char ** argv );
#ifdef WIN32
static int CmdCommandLs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandScrGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
#endif
static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -86,6 +87,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Basic", "empty", CmdCommandEmpty, 0);
#ifdef WIN32
Cmd_CommandAdd( pAbc, "Basic", "ls", CmdCommandLs, 0 );
Cmd_CommandAdd( pAbc, "Basic", "scrgen", CmdCommandScrGen, 0 );
#endif
Cmd_CommandAdd( pAbc, "Various", "sis", CmdCommandSis, 1);
@ -1068,17 +1070,6 @@ usage:
#ifdef WIN32
/**Function*************************************************************
Synopsis [Command to print the contents of the current directory (Windows).]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
#include <io.h>
// these structures are defined in <io.h> but are for some reason invisible
@ -1097,6 +1088,20 @@ extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
extern int _findnext( long handle, struct _finddata_t *fileinfo );
extern int _findclose( long handle );
extern char * _getcwd( char * buffer, int maxlen );
extern int _chdir( const char *dirname );
/**Function*************************************************************
Synopsis [Command to print the contents of the current directory (Windows).]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int CmdCommandLs( Abc_Frame_t * pAbc, int argc, char **argv )
{
struct _finddata_t c_file;
@ -1181,15 +1186,238 @@ int CmdCommandLs( Abc_Frame_t * pAbc, int argc, char **argv )
return 0;
usage:
fprintf( pAbc->Err, "Usage: ls [-l] [-b]\n" );
fprintf( pAbc->Err, "usage: ls [-l] [-b]\n" );
fprintf( pAbc->Err, " print the file names in the current directory\n" );
fprintf( pAbc->Err, " -l : print in the long format [default = short]\n" );
fprintf( pAbc->Err, " -b : print only .mv files [default = all]\n" );
return 1;
}
#endif
/**Function*************************************************************
Synopsis [Generates the script for running ABC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int CmdCommandScrGen( Abc_Frame_t * pAbc, int argc, char **argv )
{
struct _finddata_t c_file;
long hFile;
FILE * pFile = NULL;
char * pFileStr = "test.s";
char * pDirStr = NULL;
char * pComStr = "ps";
char * pWriteStr = NULL;
char Buffer[1000], Line[2000];
int nFileNameMax, nFileNameCur;
int Counter = 0;
int fUseCurrent;
char c;
fUseCurrent = 0;
Extra_UtilGetoptReset();
while ( (c = Extra_UtilGetopt(argc, argv, "FDCWch") ) != EOF )
{
switch (c)
{
case 'F':
if ( globalUtilOptind >= argc )
{
fprintf( pAbc->Err, "Command line switch \"-F\" should be followed by a string.\n" );
goto usage;
}
pFileStr = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
fprintf( pAbc->Err, "Command line switch \"-D\" should be followed by a string.\n" );
goto usage;
}
pDirStr = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 'C':
if ( globalUtilOptind >= argc )
{
fprintf( pAbc->Err, "Command line switch \"-C\" should be followed by a string.\n" );
goto usage;
}
pComStr = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 'W':
if ( globalUtilOptind >= argc )
{
fprintf( pAbc->Err, "Command line switch \"-W\" should be followed by a string.\n" );
goto usage;
}
pWriteStr = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 'c':
fUseCurrent ^= 1;
break;
default:
goto usage;
}
}
// printf( "File = %s.\n", pFileStr );
// printf( "Dir = %s.\n", pDirStr );
// printf( "Com = %s.\n", pComStr );
if ( pDirStr == NULL )
fUseCurrent = 1;
if ( _getcwd( Buffer, 1000 ) == NULL )
{
printf( "Cannot get the current directory.\n" );
return 0;
}
if ( fUseCurrent )
pFile = fopen( pFileStr, "w" );
if ( pDirStr )
{
if ( _chdir(pDirStr) )
{
printf( "Cannot change to directory: %s\n", pDirStr );
return 0;
}
}
if ( !fUseCurrent )
pFile = fopen( pFileStr, "w" );
if ( pFile == NULL )
{
printf( "Cannot open file %s.\n", pFileStr );
if ( pDirStr && _chdir(Buffer) )
{
printf( "Cannot change to the current directory: %s\n", Buffer );
return 0;
}
return 0;
}
// find the first file in the directory
if( (hFile = _findfirst( "*.*", &c_file )) == -1L )
{
if ( pDirStr )
printf( "No files in the current directory.\n" );
else
printf( "No files in directory: %s\n", pDirStr );
if ( pDirStr && _chdir(Buffer) )
{
printf( "Cannot change to the current directory: %s\n", Buffer );
return 0;
}
}
// get the longest file name
{
nFileNameMax = 0;
do
{
// skip script and txt files
nFileNameCur = strlen(c_file.name);
if ( c_file.name[nFileNameCur-1] == '.' )
continue;
if ( nFileNameCur > 2 &&
c_file.name[nFileNameCur-1] == 's' &&
c_file.name[nFileNameCur-2] == '.' )
continue;
if ( nFileNameCur > 4 &&
c_file.name[nFileNameCur-1] == 't' &&
c_file.name[nFileNameCur-2] == 'x' &&
c_file.name[nFileNameCur-3] == 't' &&
c_file.name[nFileNameCur-4] == '.' )
continue;
if ( nFileNameMax < nFileNameCur )
nFileNameMax = nFileNameCur;
}
while( _findnext( hFile, &c_file ) == 0 );
_findclose( hFile );
}
// print the script file
{
if( (hFile = _findfirst( "*.*", &c_file )) == -1L )
{
if ( pDirStr )
printf( "No files in the current directory.\n" );
else
printf( "No files in directory: %s\n", pDirStr );
}
fprintf( pFile, "# Script file produced by ABC on %s\n", Extra_TimeStamp() );
fprintf( pFile, "# Command line was: scrgen -F %s -D %s -C \"%s\"%s%s\n",
pFileStr, pDirStr, pComStr, pWriteStr?" -W ":"", pWriteStr?pWriteStr:"" );
do
{
// skip script and txt files
nFileNameCur = strlen(c_file.name);
if ( c_file.name[nFileNameCur-1] == '.' )
continue;
if ( nFileNameCur > 2 &&
c_file.name[nFileNameCur-1] == 's' &&
c_file.name[nFileNameCur-2] == '.' )
continue;
if ( nFileNameCur > 4 &&
c_file.name[nFileNameCur-1] == 't' &&
c_file.name[nFileNameCur-2] == 'x' &&
c_file.name[nFileNameCur-3] == 't' &&
c_file.name[nFileNameCur-4] == '.' )
continue;
sprintf( Line, "r %s%s%-*s ; %s", pDirStr?pDirStr:"", pDirStr?"/":"", nFileNameMax, c_file.name, pComStr );
for ( c = (int)strlen(Line)-1; c >= 0; c-- )
if ( Line[c] == '\\' )
Line[c] = '/';
fprintf( pFile, "%s", Line );
if ( pWriteStr )
{
sprintf( Line, " ; w %s/%-*s", pWriteStr, nFileNameMax, c_file.name );
for ( c = (int)strlen(Line)-1; c >= 0; c-- )
if ( Line[c] == '\\' )
Line[c] = '/';
fprintf( pFile, "%s", Line );
}
fprintf( pFile, "\n", Line );
}
while( _findnext( hFile, &c_file ) == 0 );
_findclose( hFile );
}
fclose( pFile );
if ( pDirStr && _chdir(Buffer) )
{
printf( "Cannot change to the current directory: %s\n", Buffer );
return 0;
}
// report
if ( fUseCurrent )
printf( "Script file \"%s\" was saved in the current directory.\n", pFileStr );
else
printf( "Script file \"%s\" was saved in directory: %s\n", pFileStr, pDirStr );
return 0;
usage:
fprintf( pAbc->Err, "usage: scrgen -F <str> -D <str> -C <str> -W <str> -ch\n" );
fprintf( pAbc->Err, "\t generates script for running ABC\n" );
fprintf( pAbc->Err, "\t-F str : the name of the script file [default = \"test.s\"]\n" );
fprintf( pAbc->Err, "\t-D str : the directory to read files from [default = current]\n" );
fprintf( pAbc->Err, "\t-C str : the sequence of commands to run [default = \"ps\"]\n" );
fprintf( pAbc->Err, "\t-W str : the directory to write the resulting files [default = no writing]\n" );
fprintf( pAbc->Err, "\t-c : toggle placing file in current/target dir [default = %s]\n", fUseCurrent? "current": "target" );
fprintf( pAbc->Err, "\t-h : print the command usage\n\n");
fprintf( pAbc->Err, "\tExample : scrgen -F test1.s -D a/in -C \"ps; st; ps\" -W a/out\n" );
return 1;
}
#endif
#ifdef WIN32
#define unlink _unlink

View File

@ -218,7 +218,20 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
p->pNtkCur = pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 );
// read the model name
if ( strcmp( p->vTokens->pArray[0], ".model" ) == 0 )
pNtk->pName = Extra_UtilStrsav( p->vTokens->pArray[1] );
{
char * pToken, * pPivot;
if ( Vec_PtrSize(p->vTokens) != 2 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "The .model line does not have exactly two entries." );
Io_ReadBlifPrintErrorMessage( p );
return NULL;
}
for ( pPivot = pToken = Vec_PtrEntry(p->vTokens, 1); *pToken; pToken++ )
if ( *pToken == '/' || *pToken == '\\' )
pPivot = pToken+1;
pNtk->pName = Extra_UtilStrsav( pPivot );
}
else if ( strcmp( p->vTokens->pArray[0], ".exdc" ) != 0 )
{
printf( "%s: File parsing skipped after line %d (\"%s\").\n", p->pFileName,

View File

@ -90,7 +90,7 @@ static Io_MvMod_t * Io_MvModAlloc();
static void Io_MvModFree( Io_MvMod_t * p );
static char * Io_MvLoadFile( char * pFileName );
static void Io_MvReadPreparse( Io_MvMan_t * p );
static void Io_MvReadInterfaces( Io_MvMan_t * p );
static int Io_MvReadInterfaces( Io_MvMan_t * p );
static Abc_Lib_t * Io_MvParse( Io_MvMan_t * p );
static int Io_MvParseLineModel( Io_MvMod_t * p, char * pLine );
static int Io_MvParseLineInputs( Io_MvMod_t * p, char * pLine );
@ -128,7 +128,7 @@ Abc_Ntk_t * Io_ReadBlifMv( char * pFileName, int fBlifMv, int fCheck )
FILE * pFile;
Io_MvMan_t * p;
Abc_Ntk_t * pNtk;
Abc_Lib_t * pDesign;
Abc_Lib_t * pDesign = NULL;
char * pDesignName;
int RetValue, i;
@ -161,10 +161,9 @@ Abc_Ntk_t * Io_ReadBlifMv( char * pFileName, int fBlifMv, int fCheck )
p->pDesign->pManFunc = NULL;
// prepare the file for parsing
Io_MvReadPreparse( p );
// parse interfaces of each network
Io_MvReadInterfaces( p );
// construct the network
pDesign = Io_MvParse( p );
// parse interfaces of each network and construct the network
if ( Io_MvReadInterfaces( p ) )
pDesign = Io_MvParse( p );
if ( p->sError[0] )
fprintf( stdout, "%s\n", p->sError );
Io_MvFree( p );
@ -646,7 +645,7 @@ static void Io_MvReadPreparse( Io_MvMan_t * p )
SeeAlso []
***********************************************************************/
static void Io_MvReadInterfaces( Io_MvMan_t * p )
static int Io_MvReadInterfaces( Io_MvMan_t * p )
{
Io_MvMod_t * pMod;
char * pLine;
@ -656,22 +655,23 @@ static void Io_MvReadInterfaces( Io_MvMan_t * p )
{
// parse the model
if ( !Io_MvParseLineModel( pMod, pMod->pName ) )
return;
return 0;
// add model to the design
if ( !Abc_LibAddModel( p->pDesign, pMod->pNtk ) )
{
sprintf( p->sError, "Line %d: Model %s is defined twice.", Io_MvGetLine(p, pMod->pName), pMod->pName );
return;
return 0;
}
// parse the inputs
Vec_PtrForEachEntry( pMod->vInputs, pLine, k )
if ( !Io_MvParseLineInputs( pMod, pLine ) )
return;
return 0;
// parse the outputs
Vec_PtrForEachEntry( pMod->vOutputs, pLine, k )
if ( !Io_MvParseLineOutputs( pMod, pLine ) )
return;
return 0;
}
return 1;
}
@ -767,7 +767,7 @@ static Abc_Lib_t * Io_MvParse( Io_MvMan_t * p )
static int Io_MvParseLineModel( Io_MvMod_t * p, char * pLine )
{
Vec_Ptr_t * vTokens = p->pMan->vTokens;
char * pToken;
char * pToken, * pPivot;
Io_MvSplitIntoTokens( vTokens, pLine, '\0' );
pToken = Vec_PtrEntry( vTokens, 0 );
assert( !strcmp(pToken, "model") );
@ -782,7 +782,10 @@ static int Io_MvParseLineModel( Io_MvMod_t * p, char * pLine )
p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_BLIFMV, 1 );
else
p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 );
p->pNtk->pName = Extra_UtilStrsav( Vec_PtrEntry(vTokens, 1) );
for ( pPivot = pToken = Vec_PtrEntry(vTokens, 1); *pToken; pToken++ )
if ( *pToken == '/' || *pToken == '\\' )
pPivot = pToken+1;
p->pNtk->pName = Extra_UtilStrsav( pPivot );
return 1;
}

View File

@ -703,6 +703,24 @@ static inline void Vec_PtrCleanSimInfo( Vec_Ptr_t * vInfo, int iWord, int nWords
memset( (char*)Vec_PtrEntry(vInfo,i) + 4*iWord, 0, 4*(nWords-iWord) );
}
/**Function*************************************************************
Synopsis [Cleans simulation info of each entry beginning with iWord.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_PtrFillSimInfo( Vec_Ptr_t * vInfo, int iWord, int nWords )
{
int i;
for ( i = 0; i < vInfo->nSize; i++ )
memset( (char*)Vec_PtrEntry(vInfo,i) + 4*iWord, 0xFF, 4*(nWords-iWord) );
}
/**Function*************************************************************
Synopsis [Resizes the array of simulation info.]

View File

@ -49,6 +49,8 @@ struct Mfs_Par_t_
int nGrowthLevel; // the maximum allowed growth in level
int fResub; // performs resubstitution
int fArea; // performs optimization for area
int fMoreEffort; // performs high-affort minimization
int fSwapEdge; // performs edge swapping
int fDelay; // performs optimization for delay
int fVerbose; // enable basic stats
int fVeryVerbose; // enable detailed stats

View File

@ -74,10 +74,14 @@ clk = clock();
return 1;
}
// solve the SAT problem
if ( p->pPars->fArea )
Abc_NtkMfsResubArea( p, pNode );
if ( p->pPars->fSwapEdge )
Abc_NtkMfsEdgeSwapEval( p, pNode );
else
Abc_NtkMfsResubEdge( p, pNode );
{
Abc_NtkMfsResubNode( p, pNode );
if ( p->pPars->fMoreEffort )
Abc_NtkMfsResubNode2( p, pNode );
}
p->timeSat += clock() - clk;
return 1;
}
@ -140,12 +144,13 @@ int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars )
ProgressBar * pProgress;
Mfs_Man_t * p;
Abc_Obj_t * pObj;
int i, clk = clock();
int i, nFaninMax, clk = clock();
int nTotalNodesBeg = Abc_NtkNodeNum(pNtk);
int nTotalEdgesBeg = Abc_NtkGetTotalFanins(pNtk);
assert( Abc_NtkIsLogic(pNtk) );
if ( Abc_NtkGetFaninMax(pNtk) > MFS_FANIN_MAX )
nFaninMax = Abc_NtkGetFaninMax(pNtk);
if ( nFaninMax > MFS_FANIN_MAX )
{
printf( "Some nodes have more than %d fanins. Quitting.\n", MFS_FANIN_MAX );
return 1;
@ -162,7 +167,8 @@ int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars )
// start the manager
p = Mfs_ManAlloc( pPars );
p->pNtk = pNtk;
p->pNtk = pNtk;
p->nFaninMax = nFaninMax;
if ( pNtk->pExcare )
{
Abc_Ntk_t * pTemp;
@ -170,7 +176,7 @@ int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars )
p->pCare = Abc_NtkToDar( pTemp, 0 );
Abc_NtkDelete( pTemp );
}
if ( pPars->fVerbose )
// if ( pPars->fVerbose )
{
if ( p->pCare != NULL )
printf( "Performing optimization with %d external care clauses.\n", Aig_ManPoNum(p->pCare) );

View File

@ -49,6 +49,7 @@ struct Mfs_Man_t_
Mfs_Par_t * pPars;
Abc_Ntk_t * pNtk;
Aig_Man_t * pCare;
int nFaninMax;
// intermeditate data for the node
Vec_Ptr_t * vRoots; // the roots of the window
Vec_Ptr_t * vSupp; // the support of the window
@ -78,7 +79,6 @@ struct Mfs_Man_t_
// performance statistics
int nNodesTried;
int nNodesResub;
int nNodesGained;
int nMintsCare;
int nMintsTotal;
int nNodesBad;
@ -119,8 +119,10 @@ extern Mfs_Man_t * Mfs_ManAlloc( Mfs_Par_t * pPars );
extern void Mfs_ManStop( Mfs_Man_t * p );
extern void Mfs_ManClean( Mfs_Man_t * p );
/*=== mfsResub.c ==========================================================*/
extern int Abc_NtkMfsResubArea( Mfs_Man_t * p, Abc_Obj_t * pNode );
extern int Abc_NtkMfsResubEdge( Mfs_Man_t * p, Abc_Obj_t * pNode );
extern void Abc_NtkMfsPrintResubStats( Mfs_Man_t * p );
extern int Abc_NtkMfsEdgeSwapEval( Mfs_Man_t * p, Abc_Obj_t * pNode );
extern int Abc_NtkMfsResubNode( Mfs_Man_t * p, Abc_Obj_t * pNode );
extern int Abc_NtkMfsResubNode2( Mfs_Man_t * p, Abc_Obj_t * pNode );
/*=== mfsSat.c ==========================================================*/
extern void Abc_NtkMfsSolveSat( Mfs_Man_t * p, Abc_Obj_t * pNode );
/*=== mfsStrash.c ==========================================================*/

View File

@ -85,12 +85,12 @@ void Mfs_ManClean( Mfs_Man_t * p )
if ( p->vDivs )
Vec_PtrFree( p->vDivs );
p->pAigWin = NULL;
p->pCnf = NULL;
p->pSat = NULL;
p->vRoots = NULL;
p->vSupp = NULL;
p->vNodes = NULL;
p->vDivs = NULL;
p->pCnf = NULL;
p->pSat = NULL;
p->vRoots = NULL;
p->vSupp = NULL;
p->vNodes = NULL;
p->vDivs = NULL;
}
/**Function*************************************************************
@ -117,6 +117,11 @@ void Mfs_ManPrint( Mfs_Man_t * p )
printf( "\n" );
printf( "Nodes = %d. Tried = %d. Resub = %d. Skipped = %d. SAT calls = %d.\n",
Abc_NtkNodeNum(p->pNtk), p->nNodesTried, p->nNodesResub, p->nNodesBad, p->nSatCalls );
if ( p->pPars->fSwapEdge )
printf( "Swappable edges = %d. Total edges = %d. Ratio = %5.2f.\n",
p->nNodesResub, Abc_NtkGetTotalFanins(p->pNtk), 1.00 * p->nNodesResub / Abc_NtkGetTotalFanins(p->pNtk) );
else
Abc_NtkMfsPrintResubStats( p );
}
else
{

View File

@ -55,6 +55,35 @@ void Abc_NtkMfsUpdateNetwork( Mfs_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFani
Abc_NtkUpdate( pObj, pObjNew, p->vLevels );
}
/**Function*************************************************************
Synopsis [Prints resub candidate stats.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkMfsPrintResubStats( Mfs_Man_t * p )
{
Abc_Obj_t * pFanin, * pNode;
int i, k, nAreaCrits = 0, nAreaExpanse = 0;
int nFaninMax = Abc_NtkGetFaninMax(p->pNtk);
Abc_NtkForEachNode( p->pNtk, pNode, i )
Abc_ObjForEachFanin( pNode, pFanin, k )
{
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
{
nAreaCrits++;
nAreaExpanse += (int)(Abc_ObjFaninNum(pNode) < nFaninMax);
}
}
printf( "Total area-critical fanins = %d. Belonging to expandable nodes = %d.\n",
nAreaCrits, nAreaExpanse );
}
/**Function*************************************************************
Synopsis [Tries resubstitution.]
@ -68,7 +97,7 @@ void Abc_NtkMfsUpdateNetwork( Mfs_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFani
***********************************************************************/
int Abc_NtkMfsTryResubOnce( Mfs_Man_t * p, int * pCands, int nCands )
{
unsigned * pData, * pDataTot;
unsigned * pData;
int RetValue, iVar, i;
p->nSatCalls++;
RetValue = sat_solver_solve( p->pSat, pCands, pCands + nCands, (sint64)0, (sint64)0, (sint64)0, (sint64)0 );
@ -77,17 +106,16 @@ int Abc_NtkMfsTryResubOnce( Mfs_Man_t * p, int * pCands, int nCands )
return 1;
p->nSatCexes++;
// store the counter-example
pData = Vec_PtrEntry( p->vDivCexes, p->nCexes++ );
assert( pData[0] == 0 );
Vec_IntForEachEntry( p->vProjVars, iVar, i )
{
if ( sat_solver_var_value( p->pSat, iVar ) )
Aig_InfoSetBit( pData, i );
pData = Vec_PtrEntry( p->vDivCexes, i );
if ( !sat_solver_var_value( p->pSat, iVar ) ) // remove 0s!!!
{
assert( Aig_InfoHasBit(pData, p->nCexes) );
Aig_InfoXorBit( pData, p->nCexes );
}
}
// AND the result with the previous ones
pDataTot = Vec_PtrEntry( p->vDivCexes, Vec_PtrSize(p->vDivs) );
for ( i = 0; i < p->nDivWords; i++ )
pDataTot[i] &= pData[i];
p->nCexes++;
return 0;
}
@ -102,22 +130,19 @@ int Abc_NtkMfsTryResubOnce( Mfs_Man_t * p, int * pCands, int nCands )
SeeAlso []
***********************************************************************/
int Abc_NtkMfsSolveSatResub( Mfs_Man_t * p, Abc_Obj_t * pNode, int iFanin, int fOnlyRemove )
int Abc_NtkMfsSolveSatResub( Mfs_Man_t * p, Abc_Obj_t * pNode, int iFanin, int fOnlyRemove, int fSkipUpdate )
{
int fVeryVerbose = p->pPars->fVeryVerbose && Vec_PtrSize(p->vDivs) < 80;
unsigned * pData;
int pCands[MFS_FANIN_MAX];
int iVar, i, nCands, clk;
int iVar, i, nCands, nWords, w, clk;
Abc_Obj_t * pFanin;
Hop_Obj_t * pFunc;
assert( iFanin >= 0 );
// clean simulation info
Vec_PtrCleanSimInfo( p->vDivCexes, 0, p->nDivWords );
pData = Vec_PtrEntry( p->vDivCexes, Vec_PtrSize(p->vDivs) );
memset( pData, 0xFF, sizeof(unsigned) * p->nDivWords );
Vec_PtrFillSimInfo( p->vDivCexes, 0, p->nDivWords );
p->nCexes = 0;
if ( fVeryVerbose )
{
printf( "\n" );
@ -143,7 +168,8 @@ int Abc_NtkMfsSolveSatResub( Mfs_Man_t * p, Abc_Obj_t * pNode, int iFanin, int f
if ( fVeryVerbose )
printf( "Node %d: Fanin %d can be removed.\n", pNode->Id, iFanin );
p->nNodesResub++;
// p->nNodesGained += Abc_NodeMffcLabel(pNode);
if ( fSkipUpdate )
return 1;
clk = clock();
// derive the function
pFunc = Abc_NtkMfsInterplate( p, pCands, nCands );
@ -156,11 +182,6 @@ p->timeInt += clock() - clk;
if ( fOnlyRemove )
return 0;
// shift variables by 1
for ( i = Vec_PtrSize(p->vFanins); i > 0; i-- )
p->vFanins->pArray[i] = p->vFanins->pArray[i-1];
p->vFanins->nSize++;
if ( fVeryVerbose )
{
for ( i = 0; i < 8; i++ )
@ -180,37 +201,52 @@ p->timeInt += clock() - clk;
if ( fVeryVerbose )
{
printf( "%3d: %2d ", p->nCexes, iVar );
pData = Vec_PtrEntry( p->vDivCexes, p->nCexes-1 );
// Extra_PrintBinary( stdout, pData, Vec_PtrSize(p->vDivs) );
for ( i = 0; i < Vec_PtrSize(p->vDivs); i++ )
printf( "%d", Aig_InfoHasBit(pData, i) );
{
pData = Vec_PtrEntry( p->vDivCexes, i );
printf( "%d", Aig_InfoHasBit(pData, p->nCexes-1) );
}
printf( "\n" );
}
// find the next divisor to try
pData = Vec_PtrEntry( p->vDivCexes, Vec_PtrSize(p->vDivs) );
nWords = Aig_BitWordNum(p->nCexes);
assert( nWords <= p->nDivWords );
for ( iVar = 0; iVar < Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode); iVar++ )
if ( Aig_InfoHasBit( pData, iVar ) )
{
pData = Vec_PtrEntry( p->vDivCexes, iVar );
for ( w = 0; w < nWords; w++ )
if ( pData[w] != ~0 )
break;
if ( w == nWords )
break;
}
if ( iVar == Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode) )
return 0;
pCands[nCands] = toLitCond( Vec_IntEntry(p->vProjVars, iVar), 1 );
if ( Abc_NtkMfsTryResubOnce( p, pCands, nCands+1 ) )
{
if ( fVeryVerbose )
printf( "Node %d: Fanin %d can be replaced by divisor %d.\n", pNode->Id, iFanin, iVar );
p->nNodesResub++;
// p->nNodesGained += Abc_NodeMffcLabel(pNode);
if ( fSkipUpdate )
return 1;
clk = clock();
// derive the function
pFunc = Abc_NtkMfsInterplate( p, pCands, nCands+1 );
// update the network
// Vec_PtrPush( p->vFanins, Vec_PtrEntry(p->vDivs, iVar) );
// shift fanins by 1
for ( i = Vec_PtrSize(p->vFanins); i > 0; i-- )
p->vFanins->pArray[i] = p->vFanins->pArray[i-1];
p->vFanins->nSize++;
Vec_PtrWriteEntry( p->vFanins, 0, Vec_PtrEntry(p->vDivs, iVar) );
// update the network
Abc_NtkMfsUpdateNetwork( p, pNode, p->vFanins, pFunc );
p->timeInt += clock() - clk;
return 1;
}
if ( p->nCexes >= p->pPars->nDivMax )
break;
}
return 0;
}
@ -226,14 +262,197 @@ p->timeInt += clock() - clk;
SeeAlso []
***********************************************************************/
int Abc_NtkMfsResubArea( Mfs_Man_t * p, Abc_Obj_t * pNode )
int Abc_NtkMfsSolveSatResub2( Mfs_Man_t * p, Abc_Obj_t * pNode, int iFanin, int iFanin2 )
{
int fVeryVerbose = p->pPars->fVeryVerbose && Vec_PtrSize(p->vDivs) < 80;
unsigned * pData, * pData2;
int pCands[MFS_FANIN_MAX];
int iVar, iVar2, i, w, nCands, clk, nWords, fBreak;
Abc_Obj_t * pFanin;
Hop_Obj_t * pFunc;
assert( iFanin >= 0 );
assert( iFanin2 >= 0 || iFanin2 == -1 );
// clean simulation info
Vec_PtrFillSimInfo( p->vDivCexes, 0, p->nDivWords );
p->nCexes = 0;
if ( fVeryVerbose )
{
printf( "\n" );
printf( "Node %5d : Level = %2d. Divs = %3d. Fanins = %d/%d (out of %d). MFFC = %d\n",
pNode->Id, pNode->Level, Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode),
iFanin, iFanin2, Abc_ObjFaninNum(pNode),
Abc_ObjFanoutNum(Abc_ObjFanin(pNode, iFanin)) == 1 ? Abc_NodeMffcLabel(Abc_ObjFanin(pNode, iFanin)) : 0 );
}
// try fanins without the critical fanin
nCands = 0;
Vec_PtrClear( p->vFanins );
Abc_ObjForEachFanin( pNode, pFanin, i )
{
if ( i == iFanin || i == iFanin2 )
continue;
Vec_PtrPush( p->vFanins, pFanin );
iVar = Vec_PtrSize(p->vDivs) - Abc_ObjFaninNum(pNode) + i;
pCands[nCands++] = toLitCond( Vec_IntEntry( p->vProjVars, iVar ), 1 );
}
if ( Abc_NtkMfsTryResubOnce( p, pCands, nCands ) )
{
if ( fVeryVerbose )
printf( "Node %d: Fanins %d/%d can be removed.\n", pNode->Id, iFanin, iFanin2 );
p->nNodesResub++;
clk = clock();
// derive the function
pFunc = Abc_NtkMfsInterplate( p, pCands, nCands );
// update the network
Abc_NtkMfsUpdateNetwork( p, pNode, p->vFanins, pFunc );
p->timeInt += clock() - clk;
return 1;
}
if ( fVeryVerbose )
{
for ( i = 0; i < 11; i++ )
printf( " " );
for ( i = 0; i < Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode); i++ )
printf( "%d", i % 10 );
for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
if ( i == iFanin || i == iFanin2 )
printf( "*" );
else
printf( "%c", 'a' + i );
printf( "\n" );
}
iVar = iVar2 = -1;
while ( 1 )
{
if ( fVeryVerbose )
{
printf( "%3d: %2d %2d ", p->nCexes, iVar, iVar2 );
for ( i = 0; i < Vec_PtrSize(p->vDivs); i++ )
{
pData = Vec_PtrEntry( p->vDivCexes, i );
printf( "%d", Aig_InfoHasBit(pData, p->nCexes-1) );
}
printf( "\n" );
}
// find the next divisor to try
nWords = Aig_BitWordNum(p->nCexes);
assert( nWords <= p->nDivWords );
fBreak = 0;
for ( iVar = 1; iVar < Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode); iVar++ )
{
pData = Vec_PtrEntry( p->vDivCexes, iVar );
for ( iVar2 = 0; iVar2 < iVar; iVar2++ )
{
pData2 = Vec_PtrEntry( p->vDivCexes, iVar2 );
for ( w = 0; w < nWords; w++ )
if ( (pData[w] | pData2[w]) != ~0 )
break;
if ( w == nWords )
{
fBreak = 1;
break;
}
}
if ( fBreak )
break;
}
if ( iVar == Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode) )
return 0;
pCands[nCands] = toLitCond( Vec_IntEntry(p->vProjVars, iVar2), 1 );
pCands[nCands+1] = toLitCond( Vec_IntEntry(p->vProjVars, iVar), 1 );
if ( Abc_NtkMfsTryResubOnce( p, pCands, nCands+2 ) )
{
if ( fVeryVerbose )
printf( "Node %d: Fanins %d/%d can be replaced by divisors %d/%d.\n", pNode->Id, iFanin, iFanin2, iVar, iVar2 );
p->nNodesResub++;
clk = clock();
// derive the function
pFunc = Abc_NtkMfsInterplate( p, pCands, nCands+2 );
// shift fanins by 1
for ( i = Vec_PtrSize(p->vFanins); i > 0; i-- )
p->vFanins->pArray[i] = p->vFanins->pArray[i-1];
p->vFanins->nSize++;
// shift fanins by 1
for ( i = Vec_PtrSize(p->vFanins); i > 0; i-- )
p->vFanins->pArray[i] = p->vFanins->pArray[i-1];
p->vFanins->nSize++;
Vec_PtrWriteEntry( p->vFanins, 0, Vec_PtrEntry(p->vDivs, iVar2) );
Vec_PtrWriteEntry( p->vFanins, 1, Vec_PtrEntry(p->vDivs, iVar) );
// update the network
Abc_NtkMfsUpdateNetwork( p, pNode, p->vFanins, pFunc );
p->timeInt += clock() - clk;
return 1;
}
if ( p->nCexes >= p->pPars->nDivMax )
break;
}
return 0;
}
/**Function*************************************************************
Synopsis [Evaluates the possibility of replacing given edge by another edge.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkMfsEdgeSwapEval( Mfs_Man_t * p, Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanin;
int i;
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 1 );
return 0;
}
/**Function*************************************************************
Synopsis [Performs resubstitution for the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkMfsResubNode( Mfs_Man_t * p, Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanin;
int i;
// try replacing area critical fanins
Abc_ObjForEachFanin( pNode, pFanin, i )
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
{
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 0 ) )
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
return 1;
}
// try removing redundant edges
if ( !p->pPars->fArea )
{
Abc_ObjForEachFanin( pNode, pFanin, i )
if ( Abc_ObjIsCi(pFanin) || Abc_ObjFanoutNum(pFanin) != 1 )
{
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 1, 0 ) )
return 1;
}
}
if ( Abc_ObjFaninNum(pNode) == p->nFaninMax )
return 0;
// try replacing area critical fanins while adding two new fanins
Abc_ObjForEachFanin( pNode, pFanin, i )
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
{
if ( Abc_NtkMfsSolveSatResub2( p, pNode, i, -1 ) )
return 1;
}
return 0;
@ -250,25 +469,37 @@ int Abc_NtkMfsResubArea( Mfs_Man_t * p, Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
int Abc_NtkMfsResubEdge( Mfs_Man_t * p, Abc_Obj_t * pNode )
int Abc_NtkMfsResubNode2( Mfs_Man_t * p, Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanin;
int i;
Abc_Obj_t * pFanin, * pFanin2;
int i, k;
/*
Abc_ObjForEachFanin( pNode, pFanin, i )
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
{
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 0 ) )
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
return 1;
}
*/
if ( Abc_ObjFaninNum(pNode) < 2 )
return 0;
// try replacing one area critical fanin and one other fanin while adding two new fanins
Abc_ObjForEachFanin( pNode, pFanin, i )
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) != 1 )
{
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
{
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 1 ) )
return 1;
// consider second fanin to remove at the same time
Abc_ObjForEachFanin( pNode, pFanin2, k )
{
if ( i != k && Abc_NtkMfsSolveSatResub2( p, pNode, i, k ) )
return 1;
}
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////