diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 6eb020726..6e3bf2413 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -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] \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 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] \n" ); + Abc_Print( -2, "\t generates truth tables and writes them into a file\n" ); + Abc_Print( -2, "\t-N : the number of input variables [default = %d]\n", nVars ); + Abc_Print( -2, "\t-F : the number of random functions to generate [default = %d]\n", nFuncs ); + Abc_Print( -2, "\t-M : 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 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 ] [-S string] [-iaocgvh] \n" ); + Abc_Print( -2, "usage: lutexact [-INKTFM ] [-S string] [-iaocgvh] \n" ); Abc_Print( -2, "\t exact synthesis of I-input function using N K-input gates\n" ); Abc_Print( -2, "\t-I : the number of input variables [default = %d]\n", pPars->nVars ); Abc_Print( -2, "\t-N : the number of K-input nodes [default = %d]\n", pPars->nNodes ); Abc_Print( -2, "\t-K : the number of node fanins [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-T : the runtime limit in seconds [default = %d]\n", pPars->RuntimeLim ); - Abc_Print( -2, "\t-R : the number of random functions to try [default = unused]\n" ); + Abc_Print( -2, "\t-F : the number of random functions to try [default = unused]\n" ); Abc_Print( -2, "\t-M : the number of positive minterms in the random function [default = unused]\n" ); Abc_Print( -2, "\t-S : 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" ); diff --git a/src/base/abci/abcCas.c b/src/base/abci/abcCas.c index 612de7e64..4aadaf8f0 100644 --- a/src/base/abci/abcCas.c +++ b/src/base/abci/abcCas.c @@ -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 /// ////////////////////////////////////////////////////////////////////////