New commands for truth table file processing.

This commit is contained in:
Alan Mishchenko 2025-04-05 22:40:24 -07:00
parent 3f479dc84f
commit 1b6b553922
2 changed files with 259 additions and 5 deletions

View File

@ -141,6 +141,8 @@ static int Abc_CommandTestDec ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandTestNpn ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTestRPO ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTestTruth ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTestSupp ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTestRand ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRunSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRunEco ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRunGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -955,6 +957,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Synthesis", "testnpn", Abc_CommandTestNpn, 0 );
Cmd_CommandAdd( pAbc, "LogiCS", "testrpo", Abc_CommandTestRPO, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "testtruth", Abc_CommandTestTruth, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "testsupp", Abc_CommandTestSupp, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "testrand", Abc_CommandTestRand, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "runsat", Abc_CommandRunSat, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "runeco", Abc_CommandRunEco, 0 );
Cmd_CommandAdd( pAbc, "Synthesis", "rungen", Abc_CommandRunGen, 0 );
@ -7267,6 +7271,130 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandTestSupp( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Abc_NtkSuppMinFile( char * pFileName );
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{
switch ( c )
{
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( argc != globalUtilOptind + 1 )
{
Abc_Print( 1,"Input file is not given.\n" );
return 0;
}
Abc_NtkSuppMinFile( argv[globalUtilOptind] );
return 0;
usage:
Abc_Print( -2, "usage: testsupp [-vh] <file>\n" );
Abc_Print( -2, "\t reads truth tables from file and support-minimizes them\n" );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t<file> : file to read the truth tables from\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandTestRand( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Abc_NtkRandFile( char * pFileName, int nVars, int nFuncs, int nMints );
int c, nVars = 0, nFuncs = 0, nMints = 0, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "NFMvh" ) ) != EOF )
{
switch ( c )
{
case 'N':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
goto usage;
}
nVars = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nVars < 0 )
goto usage;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
goto usage;
}
nFuncs = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'M':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
goto usage;
}
nMints = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( argc != globalUtilOptind + 1 )
{
Abc_Print( 1,"Input file is not given.\n" );
return 0;
}
Abc_NtkRandFile( argv[globalUtilOptind], nVars, nFuncs, nMints );
return 0;
usage:
Abc_Print( -2, "usage: testrand [-NFMvh] <file>\n" );
Abc_Print( -2, "\t generates truth tables and writes them into a file\n" );
Abc_Print( -2, "\t-N <num> : the number of input variables [default = %d]\n", nVars );
Abc_Print( -2, "\t-F <num> : the number of random functions to generate [default = %d]\n", nFuncs );
Abc_Print( -2, "\t-M <num> : the number of positive minterms in the random function [default = %d]\n", nMints );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t<file> : file to write the truth tables to\n");
return 1;
}
/**Function*************************************************************
Synopsis []
@ -10297,7 +10425,7 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
Bmc_EsPar_t Pars, * pPars = &Pars;
Bmc_EsParSetDefault( pPars );
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "INKTSRMiaocgvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "INKTSFMiaocgvh" ) ) != EOF )
{
switch ( c )
{
@ -10354,10 +10482,10 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->pSymStr = argv[globalUtilOptind];
globalUtilOptind++;
break;
case 'R':
case 'F':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" );
Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
goto usage;
}
pPars->nRandFuncs = atoi(argv[globalUtilOptind]);
@ -10439,13 +10567,13 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
Abc_Print( -2, "usage: lutexact [-INKTRM <num>] [-S string] [-iaocgvh] <hex>\n" );
Abc_Print( -2, "usage: lutexact [-INKTFM <num>] [-S string] [-iaocgvh] <hex>\n" );
Abc_Print( -2, "\t exact synthesis of I-input function using N K-input gates\n" );
Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", pPars->nVars );
Abc_Print( -2, "\t-N <num> : the number of K-input nodes [default = %d]\n", pPars->nNodes );
Abc_Print( -2, "\t-K <num> : the number of node fanins [default = %d]\n", pPars->nLutSize );
Abc_Print( -2, "\t-T <num> : the runtime limit in seconds [default = %d]\n", pPars->RuntimeLim );
Abc_Print( -2, "\t-R <num> : the number of random functions to try [default = unused]\n" );
Abc_Print( -2, "\t-F <num> : the number of random functions to try [default = unused]\n" );
Abc_Print( -2, "\t-M <num> : the number of positive minterms in the random function [default = unused]\n" );
Abc_Print( -2, "\t-S <str> : charasteristic string of a symmetric function [default = %d]\n", pPars->pSymStr );
Abc_Print( -2, "\t-i : toggle using incremental solving [default = %s]\n", pPars->fUseIncr ? "yes" : "no" );

View File

@ -1231,6 +1231,132 @@ void Abc_NtkLutCascadeFile( char * pFileName, int nVarsOrig, int nLutSize, int n
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Vec_WrdWriteTruthHex( char * pFileName, Vec_Wrd_t * vTruths, int nVars )
{
FILE * pFile = fopen( pFileName, "wb" );
if ( pFile == NULL ) { printf("Cannot open file \"%s\" for reading.\n", pFileName); return; }
int i, nWords = Abc_TtWordNum(nVars), nFuncs = Vec_WrdSize(vTruths)/nWords;
assert( nFuncs * nWords == Vec_WrdSize(vTruths) );
for ( i = 0; i < nFuncs; i++ )
Abc_TtPrintHexRev( pFile, Vec_WrdEntryP(vTruths, i*nWords), nVars ), fprintf( pFile, "\n" );
fclose( pFile );
}
void Abc_NtkSuppMinFile( char * pFileName )
{
int fError = 0, nFileSize = Gia_FileSize( pFileName );
FILE * pFile = fopen( pFileName, "rb" );
if ( pFile == NULL ) { printf("Cannot open file \"%s\" for reading.\n", pFileName); return; }
Vec_Wrd_t ** pvTruths = ABC_CALLOC( Vec_Wrd_t *, 32 );
char * pToken, * pLine = ABC_ALLOC( char, nFileSize );
word * pTruth = ABC_ALLOC( word, nFileSize/16 );
int Len, nVars = -1, nWords = -1, nFuncs = 0, nSuppSums[2] = {0};
for ( int i = 0; fgets(pLine, nFileSize, pFile); i++ ) {
pToken = strtok(pLine, " ,\n\r\r");
if ( pToken == NULL )
continue;
if ( pToken[0] == '0' && pToken[1] == 'x' )
pToken += 2;
Len = strlen(pToken);
nVars = Abc_Base2Log(Len);
if ( Len != (1 << nVars) ) {
printf( "The number of hex characters (%d) in the truth table listed in line %d is not a degree of 2.\n", Len, i );
fError = 1;
break;
}
nVars += 2;
if ( !Abc_TtReadHex( pTruth, pToken ) ) {
printf( "Line %d has truth table that cannot be read correctly (%s).\n", i, pToken );
fError = 1;
break;
}
nSuppSums[0] += nVars;
Abc_TtMinimumBase( pTruth, NULL, nVars, &nVars );
nSuppSums[1] += nVars;
if ( pvTruths[nVars] == NULL )
pvTruths[nVars] = Vec_WrdAlloc( 10000 );
nWords = Abc_TtWordNum(nVars);
for ( int w = 0; w < nWords; w++ )
Vec_WrdPush( pvTruths[nVars], pTruth[w] );
nFuncs++;
}
ABC_FREE( pTruth );
ABC_FREE( pLine );
fclose( pFile );
if ( fError ) {
for ( nVars = 0; nVars < 32; nVars++ )
if ( pvTruths[nVars] )
Vec_WrdFreeP( &pvTruths[nVars] );
ABC_FREE( pvTruths );
return;
}
// dump the resulting truth tables
printf( "Read and support-minimized %d functions. Total support reduction %d -> %d (%.2f %%).\n",
nFuncs, nSuppSums[0], nSuppSums[1], 100.0*(nSuppSums[0]-nSuppSums[1])/Abc_MaxInt(nSuppSums[0], 1) );
printf( "The resulting function statistics:\n" );
for ( nVars = 0; nVars < 32; nVars++ ) {
if ( pvTruths[nVars] == NULL )
continue;
char pFileName2[1000];
sprintf( pFileName2, "%s_%02d.txt", Extra_FileNameGeneric(pFileName), nVars );
Vec_WrdWriteTruthHex( pFileName2, pvTruths[nVars], nVars );
printf( "Support size %2d : Dumped %6d truth tables into file \"%s\".\n",
nVars, Vec_WrdSize(pvTruths[nVars])/Abc_TtWordNum(nVars), pFileName2 );
Vec_WrdFreeP( &pvTruths[nVars] );
}
ABC_FREE( pvTruths );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkRandFile( char * pFileName, int nVars, int nFuncs, int nMints )
{
int i, k, nWords = Abc_TtWordNum(nVars);
Vec_Wrd_t * vTruths = Vec_WrdStart( nWords * nFuncs );
Abc_Random(1);
for ( i = 0; i < nFuncs; i++ ) {
word * pTruth = Vec_WrdEntryP(vTruths, i*nWords);
if ( nMints == 0 )
for ( k = 0; k < nWords; k++ )
pTruth[k] = Abc_RandomW(0);
else {
for ( k = 0; k < nMints; k++ ) {
int iMint = 0;
do iMint = Abc_Random(0) % (1 << nVars);
while ( Abc_TtGetBit(pTruth, iMint) );
Abc_TtSetBit( pTruth, iMint );
}
}
}
Vec_WrdWriteTruthHex( pFileName, vTruths, nVars );
if ( nMints )
printf( "Generated %d random %d-variable functions with %d positive minterms and dumped them into file \"%s\".\n",
nFuncs, nVars, nMints, pFileName );
else
printf( "Generated %d random %d-variable functions and dumped them into file \"%s\".\n",
nFuncs, nVars, pFileName );
Vec_WrdFree( vTruths );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////