From 5351ab4b13aa46db5710ca3ffe659e8e691ba126 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 12 Dec 2016 16:20:38 -0200 Subject: =?UTF-8?q?xSAT=20is=20an=20experimental=20SAT=20Solver=20based=20?= =?UTF-8?q?on=20Glucose=20v3(see=20Glucose=20copyrights=20below)=20and=20A?= =?UTF-8?q?BC=20C=20version=20of=20MiniSat=20(bsat)=20developed=20by=20Nik?= =?UTF-8?q?las=20Sorensson=20and=20modified=20by=20Alan=20Mishchenko.=20It?= =?UTF-8?q?=E2=80=99s=20development=20has=20reached=20sufficient=20maturit?= =?UTF-8?q?y=20to=20be=20committed=20in=20ABC,=20but=20still=20in=20a=20be?= =?UTF-8?q?ta=20state.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TODO: * Read compressed CNF files. * Study the use of floating point for variables and clauses activity. * Better documentation. * Improve verbose messages. * Expose parameters for tuning. --- src/base/abci/abc.c | 339 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 240 insertions(+), 99 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7da88d3c..dabeb982 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -1,15 +1,15 @@ /**CFile**************************************************************** - - FileName [abc.c] + + FileName [abc.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Network and node package.] - + Synopsis [Command file.] Author [Alan Mishchenko] - + Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] @@ -42,6 +42,7 @@ #include "bool/kit/kit.h" #include "map/amap/amap.h" #include "opt/ret/retInt.h" +#include "sat/xsat/xsat.h" #include "sat/cnf/cnf.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" @@ -306,6 +307,7 @@ static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -520,7 +522,7 @@ extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -545,7 +547,7 @@ void Abc_FrameReplaceCex( Abc_Frame_t * pAbc, Abc_Cex_t ** ppCex ) Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -623,7 +625,7 @@ Vec_Int_t * Abc_FrameDeriveStatusArray( Vec_Ptr_t * vCexes ) Vec_PtrForEachEntry( Abc_Cex_t *, vCexes, pCex, i ) if ( pCex != NULL ) Vec_IntWriteEntry( vStatuses, i, 0 ); // set this output as SAT - return vStatuses; + return vStatuses; } /**Function************************************************************* @@ -951,6 +953,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "match", Abc_CommandMatch, 0 ); Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -966,8 +969,8 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "constr", Abc_CommandConstr, 0 ); Cmd_CommandAdd( pAbc, "Verification", "unfold", Abc_CommandUnfold, 1 ); Cmd_CommandAdd( pAbc, "Verification", "fold", Abc_CommandFold, 1 ); - Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong - Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong + Cmd_CommandAdd( pAbc, "Verification", "unfold2", Abc_CommandUnfold2, 1 ); // jlong + Cmd_CommandAdd( pAbc, "Verification", "fold2", Abc_CommandFold2, 1 ); // jlong Cmd_CommandAdd( pAbc, "Verification", "bm", Abc_CommandBm, 1 ); Cmd_CommandAdd( pAbc, "Verification", "bm2", Abc_CommandBm2, 1 ); Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); @@ -2717,8 +2720,8 @@ int Abc_CommandPrintStatus( Abc_Frame_t * pAbc, int argc, char ** argv ) { if ( fShort ) { - printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).", - Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1), + printf( "Status array contains %d SAT, %d UNSAT, and %d UNDEC entries (out of %d).", + Vec_IntCountEntry(pAbc->vStatuses, 0), Vec_IntCountEntry(pAbc->vStatuses, 1), Vec_IntCountEntry(pAbc->vStatuses, -1), Vec_IntSize(pAbc->vStatuses) ); } else @@ -5296,7 +5299,7 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( Vec_IntSize(pAbc->vIndFlops) != Abc_NtkLatchNum(pNtk) ) { - Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n", + Abc_Print( -1, "The saved flop count (%d) does not match that of the current network (%d).\n", Vec_IntSize(pAbc->vIndFlops), Abc_NtkLatchNum(pNtk) ); return 0; } @@ -6380,7 +6383,7 @@ int Abc_CommandTestRPO(Abc_Frame_t * pAbc, int argc, char ** argv) { goto usage; } } - if (argc != globalUtilOptind + 1) + if (argc != globalUtilOptind + 1) { Abc_Print(1, "Input file is not given.\n"); goto usage; @@ -12007,7 +12010,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) } */ // if ( pNtk ) -// Abc_NtkMakeLegit( pNtk ); +// Abc_NtkMakeLegit( pNtk ); { // extern void Ifd_ManDsdTest(); // Ifd_ManDsdTest(); @@ -14270,7 +14273,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -14311,7 +14314,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -14390,7 +14393,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -15765,7 +15768,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv ) } nGatesMin = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nGatesMin < 0 ) + if ( nGatesMin < 0 ) goto usage; break; case 'a': @@ -16468,7 +16471,7 @@ usage: SeeAlso [] ***********************************************************************/ -#if 0 +#if 0 int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) { char Buffer[100]; @@ -16839,7 +16842,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'N': @@ -17213,7 +17216,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } } - + // complain if truth tables are requested but the cut size is too large if ( pPars->fTruth && pPars->nLutSize > IF_MAX_FUNC_LUTSIZE ) { @@ -18120,7 +18123,7 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_LatchSetInit0( pObj ); else if ( pInitStr[i] == '1' ) Abc_LatchSetInit1( pObj ); - else + else Abc_LatchSetInitDc( pObj ); return 0; } @@ -18302,7 +18305,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fUseCex ) { - char * pInit; + char * pInit; Abc_Cex_t * pTemp; int k, nFlopsX = 0; if ( pAbc->pCex == NULL ) @@ -18317,7 +18320,7 @@ int Abc_CommandUndc( Abc_Frame_t * pAbc, int argc, char ** argv ) // compare this value if ( Abc_NtkPiNum(pNtk) + nFlopsX != pAbc->pCex->nPis ) { - Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n", + Abc_Print( -1, "The number of PIs (%d) plus X-valued flops (%d) in the original network does not match the number of PIs in the current CEX (%d).\n", Abc_NtkPiNum(pNtk), Abc_NtkLatchNum(pNtk), pAbc->pCex->nPis ); return 1; } @@ -20701,7 +20704,7 @@ int Abc_CommandSim3( Abc_Frame_t * pAbc, int argc, char ** argv ) extern int Abc_NtkDarSeqSim3( Abc_Ntk_t * pNtk, Ssw_RarPars_t * pPars ); Ssw_RarPars_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtkRes, * pNtk = Abc_FrameReadNtk(pAbc); - Vec_Ptr_t * vSeqModelVec; + Vec_Ptr_t * vSeqModelVec; int c; Ssw_RarSetDefaultParams( pPars ); Extra_UtilGetoptReset(); @@ -23157,6 +23160,144 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandXSat( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + abctime clk; + int c; + int fVerbose = 0; + int nConfLimit = 0; + int nInsLimit = 0; + int nLearnedStart = 0; + int nLearnedDelta = 0; + int nLearnedPerce = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CILDEhv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + nConfLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nConfLimit < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + nInsLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nInsLimit < 0 ) + goto usage; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedStart = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedStart < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedDelta = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedDelta < 0 ) + goto usage; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an integer.\n" ); + goto usage; + } + nLearnedPerce = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLearnedPerce < 0 ) + goto usage; + break; + case 'h': + goto usage; + case 'v': + fVerbose ^= 1; + break; + + default: + goto usage; + } + } + + if ( argc == globalUtilOptind + 1 ) + { + char * pFileName = argv[globalUtilOptind]; + xSAT_Solver_t * p; + int status; + + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + return 0; + } + xSAT_SolverParseDimacs( pFile, &p ); + + clk = Abc_Clock(); + status = xSAT_SolverSolve( p ); + fclose( pFile ); + + xSAT_SolverPrintStats( p ); + if ( status == 0 ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == 1 ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + xSAT_SolverDestroy( p ); + return 0; + } + +usage: + Abc_Print( -2, "usage: xsat [-CILDE num] [-hv].cnf\n" ); + Abc_Print( -2, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" ); + Abc_Print( -2, "\t derives CNF from the current network and leaves it unchanged\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit ); + Abc_Print( -2, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit ); + Abc_Print( -2, "\t-L num : starting value for learned clause removal [default = %d]\n", nLearnedStart ); + Abc_Print( -2, "\t-D num : delta value for learned clause removal [default = %d]\n", nLearnedDelta ); + Abc_Print( -2, "\t-E num : ratio percentage for learned clause removal [default = %d]\n", nLearnedPerce ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] @@ -24155,7 +24296,7 @@ int Abc_CommandBmc3( Abc_Frame_t * pAbc, int argc, char ** argv ) } } vStatuses = Abc_FrameDeriveStatusArray( vSeqModelVec ); - Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); + Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); if ( vSeqModelVec ) Abc_FrameReplaceCexVec( pAbc, &vSeqModelVec ); else @@ -25483,47 +25624,47 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ +{ FILE * pOut, * pErr; Abc_Ntk_t *pNtk, *pNtk1, *pNtk2; - int fDelete1, fDelete2; + int fDelete1, fDelete2; Abc_Obj_t * pObj; char ** pArgvNew; - int c, nArgcNew, i; + int c, nArgcNew, i; extern void saucyGateWay( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodePo, FILE * gFile, int fBooleanMatching, int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - + pErr = Abc_FrameReadErr(pAbc); + Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) { switch ( c ) { case 'h': - goto usage; + goto usage; default: Abc_Print( -2, "Unknown switch.\n"); goto usage; } } - + pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew , &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) return 1; - - if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) || + + if( (unsigned)Abc_NtkPiNum(pNtk1) != (unsigned)Abc_NtkPiNum(pNtk2) || (unsigned)Abc_NtkPoNum(pNtk1) != (unsigned)Abc_NtkPoNum(pNtk2) ) { Abc_Print( -2, "Mismatch in the number of inputs or outputs\n"); @@ -25532,7 +25673,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); return 1; } - + Abc_NtkPermute(pNtk2, 1, 1, 0, NULL ); Abc_NtkShortNames(pNtk2); @@ -25562,7 +25703,7 @@ int Abc_CommandBm2( Abc_Frame_t * pAbc, int argc, char ** argv ) saucyGateWay( pNtk1, NULL, NULL, 1, 0, 0, 0, 0, 0); if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); - if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); + if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); return 0; usage: @@ -25570,8 +25711,8 @@ usage: Abc_Print( -2, "\t performs Boolean matching (PP-equivalence)\n" ); Abc_Print( -2, "\t for equivalent circuits, permutation that maps one circuit\n" ); Abc_Print( -2, "\t to another is printed to standard output (PIs and POs of the\n" ); - Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" ); - Abc_Print( -2, "\t second network have prefix \"N2:\")\n" ); + Abc_Print( -2, "\t first network have prefix \"N1:\", while PIs and POs of the\n" ); + Abc_Print( -2, "\t second network have prefix \"N2:\")\n" ); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\tfile1 : the file with the first network\n"); Abc_Print( -2, "\tfile2 : the file with the second network\n"); @@ -25593,14 +25734,14 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ +{ Abc_Ntk_t *pNtk; char * outputName = NULL; FILE * gFile = NULL; @@ -25629,20 +25770,20 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) outputName = argv[globalUtilOptind]; if ( !strcmp(argv[globalUtilOptind], "all") ) fOutputsOneAtTime ^= 1; - globalUtilOptind++; + globalUtilOptind++; break; case 'F': if ( globalUtilOptind >= argc ) { Abc_Print( -1, "Command line switch \"-F\" should be followed by a file name.\n" ); goto usage; - } + } if ( (gFile = fopen( argv[globalUtilOptind], "w" )) == NULL ) { - Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] ); + Abc_Print( -1, "Cannot create output file \"%s\". ", argv[globalUtilOptind] ); return 1; } - globalUtilOptind++; + globalUtilOptind++; break; case 'i': fFixOutputs ^= 1; @@ -25665,9 +25806,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -2, "Unknown switch.\n"); goto usage; } - } - - pNtk = Abc_FrameReadNtk(pAbc); + } + + pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk == NULL ) { @@ -25690,21 +25831,21 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_NtkForEachPo( pNtk, pNodePo, i ) { printf("Ouput %s\n\n", Abc_ObjName(pNodePo)); saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); - printf("----------------------------------------\n"); + printf("----------------------------------------\n"); } fclose(hadi); } else if (outputName != NULL) { int i; - Abc_Obj_t * pNodePo; + Abc_Obj_t * pNodePo; Abc_NtkForEachPo( pNtk, pNodePo, i ) { if (!strcmp(Abc_ObjName(pNodePo), outputName)) { saucyGateWay( pNtk, pNodePo, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); Abc_NtkDelete( pNtk ); return 0; - } + } } Abc_Print( -1, "Output not found\n" ); - return 1; + return 1; } else saucyGateWay( pNtk, NULL, gFile, 0, fLookForSwaps, fFixOutputs, fFixInputs, fQuiet, fPrintTree ); @@ -25715,9 +25856,9 @@ int Abc_CommandSaucy( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: saucy3 [-O ] [-F ] [-iosqvh]\n\n" ); Abc_Print( -2, "\t computes functional symmetries of the netowrk\n" ); - Abc_Print( -2, "\t prints symmetry generators to the standard output\n" ); + Abc_Print( -2, "\t prints symmetry generators to the standard output\n" ); Abc_Print( -2, "\t-O : (optional) compute symmetries only for output given by name\n"); - Abc_Print( -2, "\t only inputs in the output cone are permuted\n"); + Abc_Print( -2, "\t only inputs in the output cone are permuted\n"); Abc_Print( -2, "\t (special case) name=all, compute symmetries for each\n" ); Abc_Print( -2, "\t output, but only one output at a time\n" ); Abc_Print( -2, "\t [default = compute symmetries by permuting all I/Os]\n" ); @@ -25726,8 +25867,8 @@ usage: Abc_Print( -2, "\t-o : permute just the outputs (fix the inputs) [default = no]\n"); Abc_Print( -2, "\t-s : only look for swaps of inputs [default = no]\n"); Abc_Print( -2, "\t-q : quiet (do not print symmetry generators) [default = no]\n"); - Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n"); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t-v : verbose (print the search tree) [default = no]\n"); + Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t \n" ); Abc_Print( -2, "\t This command was contributed by Hadi Katebi from U Michigan.\n" ); @@ -27055,7 +27196,7 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) pAig = Gia_ManReadMiniLut( FileName ); // else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) ) // Abc3_ReadShowHie( FileName, fSkipStrash ); - else + else pAig = Gia_AigerRead( FileName, fGiaSimple, fSkipStrash, 0 ); if ( pAig ) Abc_FrameUpdateGia( pAbc, pAig ); @@ -27466,8 +27607,8 @@ int Abc_CommandAbc9Get( Abc_Frame_t * pAbc, int argc, char ** argv ) Vec_FltFreeP( &pGia->vOutReqs ); pGia->DefInArrs = Abc_NtkReadDefaultArrivalWorst(pNtk); pGia->DefOutReqs = Abc_NtkReadDefaultRequiredWorst(pNtk); - pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) ); - pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) ); + pGia->vInArrs = Vec_FltAllocArray( Abc_NtkGetCiArrivalFloats(pNtk), Abc_NtkCiNum(pNtk) ); + pGia->vOutReqs = Vec_FltAllocArray( Abc_NtkGetCoRequiredFloats(pNtk), Abc_NtkCoNum(pNtk) ); } Abc_FrameUpdateGia( pAbc, pGia ); return 0; @@ -27626,7 +27767,7 @@ usage: Synopsis [Compares to versions of the design and finds the best.] Description [] - + SideEffects [] SeeAlso [] @@ -27637,11 +27778,11 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int int nCurLuts, nCurEdges, nCurLevels; Gia_ManLutParams( p, &nCurLuts, &nCurEdges, &nCurLevels ); if ( pBest == NULL || - Gia_ManPiNum(pBest) != Gia_ManPiNum(p) || - Gia_ManPoNum(pBest) != Gia_ManPoNum(p) || + Gia_ManPiNum(pBest) != Gia_ManPiNum(p) || + Gia_ManPoNum(pBest) != Gia_ManPoNum(p) || Gia_ManRegNum(pBest) != Gia_ManRegNum(p) || strcmp(Gia_ManName(pBest), Gia_ManName(p)) || - (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) || + (!fArea && (*pnBestLevels > nCurLevels || (*pnBestLevels == nCurLevels && 2*(*pnBestLuts) + *pnBestEdges > 2*nCurLuts + nCurEdges))) || ( fArea && (*pnBestLuts > nCurLuts || (*pnBestLuts == nCurLuts && *pnBestLevels > nCurLevels))) ) { @@ -27659,7 +27800,7 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -27697,7 +27838,7 @@ int Abc_CommandAbc9Save( Abc_Frame_t * pAbc, int argc, char ** argv ) // save the design as best Gia_ManStopP( &pAbc->pGiaBest ); pAbc->pGiaBest = Gia_ManDupWithAttributes( pAbc->pGia ); - return 0; + return 0; usage: Abc_Print( -2, "usage: &save [-ah]\n" ); @@ -27712,7 +27853,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -30868,7 +31009,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv ) } nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nRelaxRatio < 0 ) + if ( nRelaxRatio < 0 ) goto usage; break; case 'a': @@ -30908,7 +31049,7 @@ int Abc_CommandAbc9Syn2( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "DSD manager has incompatible number of variables. Delay minimization is not performed.\n" ); fDelayMin = 0; } - } + } pTemp = Gia_ManAigSyn2( pAbc->pGia, fOldAlgo, fCoarsen, fCutMin, nRelaxRatio, fDelayMin, fVerbose, fVeryVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; @@ -31005,7 +31146,7 @@ int Abc_CommandAbc9Synch2( Abc_Frame_t * pAbc, int argc, char ** argv ) } nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( nRelaxRatio < 0 ) + if ( nRelaxRatio < 0 ) goto usage; break; case 'f': @@ -32857,7 +32998,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) pAbc->Status = Cec_ManVerify( pTemp, pPars ); ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb ); Gia_ManStop( pTemp ); - } + } Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); return 0; } @@ -33749,7 +33890,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'T': @@ -34867,7 +35008,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -34878,7 +35019,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -34889,7 +35030,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35099,7 +35240,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35110,7 +35251,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35121,7 +35262,7 @@ int Abc_CommandAbc9Mf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35303,7 +35444,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35314,7 +35455,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35325,7 +35466,7 @@ int Abc_CommandAbc9Nf( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35518,7 +35659,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nRelaxRatio = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nRelaxRatio < 0 ) + if ( pPars->nRelaxRatio < 0 ) goto usage; break; case 'L': @@ -35529,7 +35670,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nCoarseLimit = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nCoarseLimit < 0 ) + if ( pPars->nCoarseLimit < 0 ) goto usage; break; case 'E': @@ -35540,7 +35681,7 @@ int Abc_CommandAbc9Of( Abc_Frame_t * pAbc, int argc, char ** argv ) } pPars->nAreaTuner = atoi(argv[globalUtilOptind]); globalUtilOptind++; - if ( pPars->nAreaTuner < 0 ) + if ( pPars->nAreaTuner < 0 ) goto usage; break; case 'D': @@ -35886,7 +36027,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) { //Edg_ManAssignEdgeNew( pAbc->pGia, nEdges, fVerbose ); Seg_ManComputeDelay( pAbc->pGia, DelayMax, nFanouts, nEdges==2, fVerbose ); - return 0; + return 0; } if ( pAbc->pGia->pManTime && fReverse ) { @@ -35895,7 +36036,7 @@ int Abc_CommandAbc9Edge( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( fReverse ) DelayMax = Gia_ManComputeEdgeDelay2( pAbc->pGia ); - else + else DelayMax = Gia_ManComputeEdgeDelay( pAbc->pGia, nEdges == 2 ); //printf( "The number of edges = %d. Delay = %d.\n", Gia_ManEvalEdgeCount(pAbc->pGia), DelayMax ); return 0; @@ -38307,7 +38448,7 @@ int Abc_CommandAbc9MultiProve( Abc_Frame_t * pAbc, int argc, char ** argv ) } pAbc->Status = Gia_ManMultiProve( pAbc->pGia, pPars ); vStatuses = Abc_FrameDeriveStatusArray( pAbc->pGia->vSeqModelVec ); - Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); + Abc_FrameReplacePoStatuses( pAbc, &vStatuses ); Abc_FrameReplaceCexVec( pAbc, &pAbc->pGia->vSeqModelVec ); return 0; @@ -38454,7 +38595,7 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv ) Bmc_AndPar_t Pars, * pPars = &Pars; memset( pPars, 0, sizeof(Bmc_AndPar_t) ); pPars->nStart = 0; // starting timeframe - pPars->nFramesMax = 0; // maximum number of timeframes + pPars->nFramesMax = 0; // maximum number of timeframes pPars->nFramesAdd = 50; // the number of additional frames pPars->nConfLimit = 0; // maximum number of conflicts at a node pPars->nTimeOut = 0; // timeout in seconds @@ -38463,9 +38604,9 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->fDumpFrames = 0; // dump unrolled timeframes pPars->fUseSynth = 0; // use synthesis pPars->fUseOldCnf = 0; // use old CNF construction - pPars->fVerbose = 0; // verbose - pPars->fVeryVerbose = 0; // very verbose - pPars->fNotVerbose = 0; // skip line-by-line print-out + pPars->fVerbose = 0; // verbose + pPars->fVeryVerbose = 0; // very verbose + pPars->fNotVerbose = 0; // skip line-by-line print-out pPars->iFrame = 0; // explored up to this frame pPars->nFailOuts = 0; // the number of failed outputs pPars->nDropOuts = 0; // the number of dropped outputs @@ -39166,7 +39307,7 @@ usage: Abc_Print( -2, "\t ((a&b)^p) complement at the output\n"); Abc_Print( -2, "\t (((a^p)&(b^q))^r) complement at the inputs and at the output\n"); Abc_Print( -2, "\t (a?(b?~s:r):(b?q:p)) functionally observable fault at the output\n"); - Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n"); + Abc_Print( -2, "\t (p?(a|b):(a&b)) replace AND by OR\n"); return 1; } @@ -40039,7 +40180,7 @@ int Abc_CommandAbc9Demiter( Abc_Frame_t * pAbc, int argc, char ** argv ) { char pName0[1000] = "miter_part0.aig"; char pName1[1000] = "miter_part1.aig"; - Gia_Man_t * pPart1, * pPart2; + Gia_Man_t * pPart1, * pPart2; if ( Gia_ManPoNum(pAbc->pGia) % 2 != 0 ) { Abc_Print( -1, "Abc_CommandAbc9Demiter(): Does not look like a dual-output miter.\n" ); @@ -40481,7 +40622,7 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManDemiterDual( pDual, &pGia0, &pGia1 ); Gia_ManStop( pDual ); pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); - } + } Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb ); Gia_ManStop( pGia0 ); Gia_ManStop( pGia1 ); @@ -40687,7 +40828,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -40701,7 +40842,7 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv ) Sfm_ParSetDefault( pPars ); pPars->nTfoLevMax = 5; pPars->nDepthMax = 100; - pPars->nWinSizeMax = 2000; + pPars->nWinSizeMax = 2000; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMLCNdaebvwh" ) ) != EOF ) { @@ -40852,7 +40993,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -41324,7 +41465,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] @@ -41385,7 +41526,7 @@ usage: Synopsis [] Description [] - + SideEffects [] SeeAlso [] -- cgit v1.2.3 From cf5d4ad07f87e936a114afca483ed66ffb1a2120 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 21 Dec 2016 15:34:02 +0700 Subject: Converting some errors into warnings. --- src/base/abci/abc.c | 4 ++-- src/base/abci/abcMfs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dabeb982..fb301790 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -19532,7 +19532,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( Abc_NtkIsComb(pNtk) ) { - Abc_Print( -1, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" ); + Abc_Print( 0, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" ); return 0; } @@ -31954,7 +31954,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( Gia_ManRegNum(pAbc->pGia) == 0 ) { - Abc_Print( -1, "The network is combinational.\n" ); + Abc_Print( 0, "The network is combinational.\n" ); return 0; } pTemp = Cec_ManLSCorrespondence( pAbc->pGia, pPars ); diff --git a/src/base/abci/abcMfs.c b/src/base/abci/abcMfs.c index e33d6c73..d44ca1a0 100644 --- a/src/base/abci/abcMfs.c +++ b/src/base/abci/abcMfs.c @@ -259,7 +259,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars ) if ( nFaninMax > 6 ) { Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" ); - return 0; + return 1; } if ( !Abc_NtkHasSop(pNtk) ) if ( !Abc_NtkToSop( pNtk, -1, ABC_INFINITY ) ) -- cgit v1.2.3 From b56a532682e34ae440bc6ffa939e82d06cf06e62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 22 Dec 2016 17:27:32 +0700 Subject: Several changes in arithmetic circuit manipulation. --- src/base/abci/abc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fb301790..7866b22d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -28592,15 +28592,18 @@ usage: int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) { Vec_Int_t * vBold = NULL; - int c, fAdders = 0; + int c, fAdders = 0, fFadds = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "afh" ) ) != EOF ) { switch ( c ) { case 'a': fAdders ^= 1; break; + case 'f': + fFadds ^= 1; + break; case 'h': goto usage; default: @@ -28623,14 +28626,15 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManForEachLut( pAbc->pGia, c ) Vec_IntPush( vBold, c ); } - Gia_ManShow( pAbc->pGia, vBold, fAdders ); + Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds ); Vec_IntFreeP( &vBold ); return 0; usage: - Abc_Print( -2, "usage: &show [-ah]\n" ); + Abc_Print( -2, "usage: &show [-afh]\n" ); Abc_Print( -2, "\t shows the current GIA using GSView\n" ); Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle only showing full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } -- cgit v1.2.3 From 54b4692d4bb2a6c5e59b5f54aaff95e2c4966e77 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 29 Dec 2016 21:26:02 +0700 Subject: Updates to delay optimization project. --- src/base/abci/abc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7866b22d..f9717aa8 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSWFMCacvwh" ) ) != EOF ) { switch ( c ) { @@ -41025,6 +41025,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutSize < 0 ) goto usage; break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLutNum < 0 ) + goto usage; + break; case 'W': if ( globalUtilOptind >= argc ) { @@ -41107,9 +41118,10 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSWFMC ] [-acvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); + Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); Abc_Print( -2, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels ); Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); -- cgit v1.2.3 From 01924ca118cad9bc8bf84de0525e54f5c4a832ec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 20:21:46 +0700 Subject: Updates to delay optimization project. --- src/base/abci/abc.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f9717aa8..fccd4f63 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KSWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCacvwh" ) ) != EOF ) { switch ( c ) { @@ -41036,6 +41036,28 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutNum < 0 ) goto usage; break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nCutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutSize < 0 ) + goto usage; + break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nCutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nCutNum < 0 ) + goto usage; + break; case 'W': if ( globalUtilOptind >= argc ) { @@ -41118,10 +41140,12 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KSWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-acvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); + Abc_Print( -2, "\t-N : the cut size considered for optimization (2 <= num <= 10) [default = %d]\n", pPars->nCutSize ); + Abc_Print( -2, "\t-P : the number of cuts computed at a node (1 <= num <= 500) [default = %d]\n", pPars->nCutNum ); Abc_Print( -2, "\t-W : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels ); Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); -- cgit v1.2.3 From 3f2899d6ea1a141f40d7fdfe4556bb349d53c250 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 31 Dec 2016 22:00:26 +0700 Subject: Compiler warnings. --- src/base/main/mainReal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/main/mainReal.c b/src/base/main/mainReal.c index ee43d38d..31bfef75 100644 --- a/src/base/main/mainReal.c +++ b/src/base/main/mainReal.c @@ -196,7 +196,7 @@ int Abc_RealMain( int argc, char * argv[] ) case 't': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { - if ( !strcmp(globalUtilOptarg, "none") == 0 ) + if ( (!strcmp(globalUtilOptarg, "none")) == 0 ) { fInitRead = 1; sprintf( sReadCmd, "read_%s", globalUtilOptarg ); @@ -211,7 +211,7 @@ int Abc_RealMain( int argc, char * argv[] ) case 'T': if ( TypeCheck( pAbc, globalUtilOptarg ) ) { - if (!strcmp(globalUtilOptarg, "none") == 0) + if ( (!strcmp(globalUtilOptarg, "none")) == 0) { fFinalWrite = 1; sprintf( sWriteCmd, "write_%s", globalUtilOptarg); -- cgit v1.2.3 From 74c8d35f330f80e6e489f6829288093e798fbfc2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 2 Jan 2017 16:29:10 +0700 Subject: Updates to delay optimization project. --- src/base/abci/abc.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index fccd4f63..2be65ed0 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41010,7 +41010,7 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) Sbd_Par_t Pars, * pPars = &Pars; Sbd_ParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCacvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KSNPWFMCmcdpvwh" ) ) != EOF ) { switch ( c ) { @@ -41102,11 +41102,17 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBTLimit < 0 ) goto usage; break; - case 'a': - pPars->fArea ^= 1; + case 'm': + pPars->fMapping ^= 1; break; case 'c': - pPars->fCover ^= 1; + pPars->fMoreCuts ^= 1; + break; + case 'd': + pPars->fFindDivs ^= 1; + break; + case 'p': + pPars->fUsePath ^= 1; break; case 'v': pPars->fVerbose ^= 1; @@ -41122,25 +41128,22 @@ int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pGia == NULL ) { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): There is no AIG.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Mfsd(): There is no AIG.\n" ); return 0; } if ( Gia_ManBufNum(pAbc->pGia) ) { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): This command does not work with barrier buffers.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Mfsd(): This command does not work with barrier buffers.\n" ); return 1; } if ( Gia_ManHasMapping(pAbc->pGia) ) - { - Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has mapping (run &st to unmap).\n" ); - return 0; - } + Abc_Print( 1, "The current AIG has mapping, which can be used to determine critical path if \"-p\" is selected.\n" ); pTemp = Sbd_NtkPerform( pAbc->pGia, pPars ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-acvwh]\n" ); + Abc_Print( -2, "usage: &mfsd [-KSNPWFMC ] [-mcdpvwh]\n" ); Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" ); Abc_Print( -2, "\t-K : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-S : the LUT structure size (1 <= num <= 2) [default = %d]\n", pPars->nLutNum ); @@ -41150,8 +41153,10 @@ usage: Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); Abc_Print( -2, "\t-C : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit ); - Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" ); - Abc_Print( -2, "\t-c : toggle using complete slow covering procedure [default = %s]\n", pPars->fCover? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "area": "area+edges" ); + Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); -- cgit v1.2.3 From 460167ec747aed778bfc13f2040dd8a205169fa2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 08:57:08 +0700 Subject: Compiler warnings. --- src/base/abci/abcExact.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c index 757034cd..adb64d79 100644 --- a/src/base/abci/abcExact.c +++ b/src/base/abci/abcExact.c @@ -873,7 +873,7 @@ static void Ses_StoreRead( Ses_Store_t * pStore, const char * pFilename, int fSy fclose( pFile ); - printf( "read %lu entries from file\n", nEntries ); + printf( "read %lu entries from file\n", (long)nEntries ); } // computes top decomposition of variables wrt. to AND and OR -- cgit v1.2.3 From 3dd2325aa8572bbe0689a537101f138a0c7b8c87 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 7 Jan 2017 09:51:38 +0700 Subject: Adding an option to not add buffers to decouple COs driven by the same internal node. --- src/base/abc/abcUtil.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/base') diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index f01ef07a..dd3a75b7 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -1077,6 +1077,7 @@ void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate ) ***********************************************************************/ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate ) { + int fAddBuffers = 1; Vec_Ptr_t * vDrivers, * vCoTerms; Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin; int i, k, LevelMax, nTotal = 0; @@ -1191,6 +1192,12 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate ) // collect COs that needs fixing by adding buffers or duplicating vCoTerms = Vec_PtrAlloc( 100 ); Abc_NtkIncrementTravId( pNtk ); + + // The following cases should be addressed only if the network is written + // into a BLIF file. Otherwise, it is possible to skip them: + // (1) if a CO points to a CI with a different name + // (2) if an internal node drives more than one CO + if ( fAddBuffers ) Abc_NtkForEachCo( pNtk, pNode, i ) { // if the driver is a CI and has different name, this is an error -- cgit v1.2.3 From feb57982a999b6c6faf58b0e279d9b8949802962 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 10:46:29 +0700 Subject: Change suggested by Udi Finkelstein. --- src/base/cmd/cmd.c | 21 +-------------------- src/base/cmd/cmdLoad.c | 21 +-------------------- 2 files changed, 2 insertions(+), 40 deletions(-) (limited to 'src/base') diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index 0b7c1788..ab037139 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -1147,26 +1147,7 @@ usage: #if defined(WIN32) && !defined(__cplusplus) #include - -// these structures are defined in but are for some reason invisible -typedef unsigned long _fsize_t; // Could be 64 bits for Win32 - -struct _finddata_t { - unsigned attrib; - time_t time_create; // -1 for FAT file systems - time_t time_access; // -1 for FAT file systems - time_t time_write; - _fsize_t size; - char name[260]; -}; - -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 ); - +#include /**Function************************************************************* diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c index 7f7c1b60..accd9440 100644 --- a/src/base/cmd/cmdLoad.c +++ b/src/base/cmd/cmdLoad.c @@ -97,26 +97,7 @@ int CmdCommandLoad( Abc_Frame_t * pAbc, int argc, char ** argv ) #if defined(WIN32) && !defined(__cplusplus) #include - - -// these structures are defined in but are for some reason invisible -typedef unsigned long _fsize_t; // Could be 64 bits for Win32 - -struct _finddata_t { - unsigned attrib; - time_t time_create; // -1 for FAT file systems - time_t time_access; // -1 for FAT file systems - time_t time_write; - _fsize_t size; - char name[260]; -}; - -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 ); +#include /**Function************************************************************* -- cgit v1.2.3 From 9514c327e3d8703775d138fe029b247adbf06099 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 11:04:48 +0700 Subject: Bug fix in delay-opt framework. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 2be65ed0..a69737ea 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -41153,7 +41153,7 @@ usage: Abc_Print( -2, "\t-F : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax ); Abc_Print( -2, "\t-M : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax ); Abc_Print( -2, "\t-C : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit ); - Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "area": "area+edges" ); + Abc_Print( -2, "\t-m : toggle generating delay-oriented mapping [default = %s]\n", pPars->fMapping? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using several cuts at each node [default = %s]\n", pPars->fMoreCuts? "yes": "no" ); Abc_Print( -2, "\t-d : toggle additional search for good divisors [default = %s]\n", pPars->fFindDivs? "yes": "no" ); Abc_Print( -2, "\t-p : toggle optimizing critical path only [default = %s]\n", pPars->fUsePath? "yes": "no" ); -- cgit v1.2.3 From fbdf28e4c937067737d84db37ff6e1a65348df5f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 9 Jan 2017 19:50:05 +0700 Subject: Updated to arithmetic verification. --- src/base/abci/abc.c | 146 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 51 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index a69737ea..dd157afd 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40532,14 +40532,12 @@ usage: int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pFile; - Cec_ParCec_t ParsCec, * pPars = &ParsCec; - Gia_Man_t * pSecond; - char * FileName, * pTemp; + Acec_ParCec_t ParsCec, * pPars = &ParsCec; char ** pArgvNew; - int c, nArgcNew, fMiter = 0, fDualOutput = 0, fTwoOutput = 0; - Cec_ManCecSetDefaultParams( pPars ); + int c, nArgcNew; + Acec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdtvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtvh" ) ) != EOF ) { switch ( c ) { @@ -40565,17 +40563,14 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->TimeLimit < 0 ) goto usage; break; - case 'n': - pPars->fNaive ^= 1; - break; case 'm': - fMiter ^= 1; + pPars->fMiter ^= 1; break; case 'd': - fDualOutput ^= 1; + pPars->fDualOutput ^= 1; break; case 't': - fTwoOutput ^= 1; + pPars->fTwoOutput ^= 1; break; case 'v': pPars->fVerbose ^= 1; @@ -40586,15 +40581,20 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( fMiter ) + if ( pPars->fMiter ) { Gia_Man_t * pGia0, * pGia1, * pDual; + if ( argc != globalUtilOptind ) + { + Abc_Print( -1, "Abc_CommandAbc9Acec(): If the input is a miter, it cannot be given on the command line.\n" ); + return 1; + } if ( pAbc->pGia == NULL ) { Abc_Print( -1, "Abc_CommandAbc9Acec(): There is no AIG.\n" ); return 1; } - if ( fDualOutput ) + if ( pPars->fDualOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) { @@ -40604,28 +40604,28 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( !pPars->fSilent ) Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); Gia_ManDemiterDual( pAbc->pGia, &pGia0, &pGia1 ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } - else if ( fTwoOutput ) + else if ( pPars->fTwoOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) { - Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" ); + Abc_Print( -1, "The two-output miter should have an even number of outputs.\n" ); return 1; } if ( !pPars->fSilent ) Abc_Print( 1, "Assuming the current network is a two-word miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); Gia_ManDemiterTwoWords( pAbc->pGia, &pGia0, &pGia1 ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } - else + else // regular single- or multi-output miter { if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a regular single- or multi-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); pDual = Gia_ManDemiterToDual( pAbc->pGia ); Gia_ManDemiterDual( pDual, &pGia0, &pGia1 ); Gia_ManStop( pDual ); - pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars ); + pAbc->Status = Acec_Solve( pGia0, pGia1, pPars ); } Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb ); Gia_ManStop( pGia0 ); @@ -40635,52 +40635,96 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 1 ) + if ( nArgcNew == 0 || nArgcNew == 1 ) { - if ( pAbc->pGia->pSpec == NULL ) + Gia_Man_t * pSecond; + char * pTemp, * FileName = NULL; + if ( nArgcNew == 0 ) { - Abc_Print( -1, "File name is not given on the command line.\n" ); - return 1; + FileName = pAbc->pGia->pSpec; + if ( FileName == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } } - FileName = pAbc->pGia->pSpec; + else // if ( nArgcNew == 1 ) + { + FileName = pArgvNew[0]; + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + } + pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pSecond == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + pAbc->Status = Acec_Solve( pAbc->pGia, pSecond, pPars ); + Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Gia_ManStop( pSecond ); } - else - FileName = pArgvNew[0]; - // fix the wrong symbol - for ( pTemp = FileName; *pTemp; pTemp++ ) - if ( *pTemp == '>' ) - *pTemp = '\\'; - if ( (pFile = fopen( FileName, "r" )) == NULL ) + else if ( nArgcNew == 2 ) { - Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); - if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", FileName ); - Abc_Print( 1, "\n" ); - return 1; + Gia_Man_t * pGias[2] = {NULL}; int i; + char * pTemp, * FileName[2] = { pArgvNew[0], pArgvNew[1] }; + for ( i = 0; i < 2; i++ ) + { + // fix the wrong symbol + for ( pTemp = FileName[i]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName[i], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName[i] ); + if ( (FileName[i] = Extra_FileGetSimilarName( FileName[i], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName[i] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[i] = Gia_AigerRead( FileName[i], 0, 0, 0 ); + if ( pGias[i] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + } + pAbc->Status = Acec_Solve( pGias[0], pGias[1], pPars ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); } - fclose( pFile ); - pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); - if ( pSecond == NULL ) + else { - Abc_Print( -1, "Reading AIGER has failed.\n" ); - return 0; + Abc_Print( -1, "Too many command-line arguments.\n" ); + return 1; } - pAbc->Status = Gia_PolynCec( pAbc->pGia, pSecond, pPars ); - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); - Gia_ManStop( pSecond ); return 0; usage: - Abc_Print( -2, "usage: &acec [-CT num] [-nmdtvh]\n" ); + Abc_Print( -2, "usage: &acec [-CT num] [-mdtvh] \n" ); Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); - Abc_Print( -2, "\t-n : toggle using naive SAT-based checking [default = %s]\n", pPars->fNaive? "yes":"no"); - Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits"); - Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no"); - Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", fTwoOutput? "yes":"no"); + Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits"); + Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no"); + Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n"); + Abc_Print( -2, "\tfile2 : (optional) the file with the second network\n"); return 1; } -- cgit v1.2.3 From 55b6b4bdab816b34bfa81a58eb4e9fefe0c1cba4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 11 Jan 2017 16:08:23 +0700 Subject: Updates to arithmetic verification. --- src/base/abci/abc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcBlast.c | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index dd157afd..20d44227 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -481,6 +481,7 @@ static int Abc_CommandAbc9Fadds ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1124,6 +1125,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&atree", Abc_CommandAbc9ATree, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 ); @@ -40728,6 +40730,52 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + 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 ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" ); + return 0; + } + pTemp = Acec_Normalize( pAbc->pGia, fVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &anorm [-vh]\n" ); + Abc_Print( -2, "\t normalize adder trees in the current AIG\n" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index ec3b040d..5e6a1a47 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1509,7 +1509,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) ); } - pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName ); + //pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName ); // dump the miter parts if ( 0 ) { -- cgit v1.2.3 From d52dafa6c2365837543f15be7abd274f8654ba14 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 12 Jan 2017 16:12:48 +0700 Subject: Updates to arithmetic verification. --- src/base/wlc/wlcBlast.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/base') diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 5e6a1a47..b22ac6cd 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -643,6 +643,31 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) Vec_IntInsert( vProd, i + 1, Node ); Vec_IntInsert( vLevel, i + 1, Level ); } +void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) +{ + Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); + Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); + Vec_Int_t * vLevel; word Truth; + int i, k, iLit; + Vec_WecForEachLevel( vProds, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + { + printf( "Obj = %4d : ", Abc_Lit2Var(iLit) ); + printf( "Compl = %d ", Abc_LitIsCompl(iLit) ); + printf( "Rank = %2d ", i ); + Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp ); + Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) ); + if ( Vec_IntSize(vSupp) == 4 ) printf( " " ); + if ( Vec_IntSize(vSupp) == 3 ) printf( " " ); + if ( Vec_IntSize(vSupp) <= 2 ) printf( " " ); + printf( " " ); + Vec_IntPrint( vSupp ); + if ( k == Vec_IntSize(vLevel)-1 ) + printf( "\n" ); + } + Vec_IntFree( vSupp ); + Vec_WrdFree( vTemp ); +} void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes ) { Vec_Int_t * vLevel, * vProd; @@ -812,6 +837,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int Vec_WecPush( vLevels, k, 0 ); } //Vec_WecPrint( vProds, 0 ); + //Wlc_BlastPrintMatrix( pNew, vProds ); //printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) ); Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); -- cgit v1.2.3 From 1a39fb39462d34e40e4ed9da4615d18a463471e0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 17:32:58 +0700 Subject: Adding print-out of critical path for mapped AIGs to &show. --- src/base/abci/abc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 20d44227..910014c6 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -28594,9 +28594,9 @@ usage: int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) { Vec_Int_t * vBold = NULL; - int c, fAdders = 0, fFadds = 0; + int c, fAdders = 0, fFadds = 0, fPath = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "afh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "afph" ) ) != EOF ) { switch ( c ) { @@ -28606,6 +28606,9 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'f': fFadds ^= 1; break; + case 'p': + fPath ^= 1; + break; case 'h': goto usage; default: @@ -28628,15 +28631,16 @@ int Abc_CommandAbc9Show( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManForEachLut( pAbc->pGia, c ) Vec_IntPush( vBold, c ); } - Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds ); + Gia_ManShow( pAbc->pGia, vBold, fAdders, fFadds, fPath ); Vec_IntFreeP( &vBold ); return 0; usage: - Abc_Print( -2, "usage: &show [-afh]\n" ); + Abc_Print( -2, "usage: &show [-afph]\n" ); Abc_Print( -2, "\t shows the current GIA using GSView\n" ); Abc_Print( -2, "\t-a : toggle visualazing adders [default = %s]\n", fAdders? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle only showing full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle showing only full-adders with \"-a\" [default = %s]\n", fFadds? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle showing the critical path of a LUT mapping [default = %s]\n", fPath? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -42679,7 +42683,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); // Gia_PolynExplore( pAbc->pGia ); -// Gia_ManTestSatEnum( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; -- cgit v1.2.3 From 6d606b51ab084c96d92848be789397700bb3591f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 13 Jan 2017 21:17:00 +0700 Subject: Updates to arithmetic verification. --- src/base/wlc/wlcBlast.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/base') diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index b22ac6cd..b49c2dd7 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -645,10 +645,20 @@ void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level ) } void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) { + int fVerbose = 0; Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) ); Vec_Int_t * vLevel; word Truth; int i, k, iLit; + Vec_WecForEachLevel( vProds, vLevel, i ) + Vec_IntForEachEntry( vLevel, iLit, k ) + if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) ) + Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) ); + printf( "Booth partial products: %d pps, %d unique, %d nodes.\n", + Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) ); + Vec_IntPrint( vSupp ); + + if ( fVerbose ) Vec_WecForEachLevel( vProds, vLevel, i ) Vec_IntForEachEntry( vLevel, iLit, k ) { -- cgit v1.2.3 From 79701f8b4603596095d3d04a13018c8e9598f7a0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Jan 2017 16:11:59 +0700 Subject: Updates to arithmetic verification. --- src/base/abci/abc.c | 20 ++++++++++++++------ src/base/abci/abcDress3.c | 30 +++--------------------------- 2 files changed, 17 insertions(+), 33 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 910014c6..1e94f28f 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40543,7 +40543,7 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) int c, nArgcNew; Acec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTmdtbvh" ) ) != EOF ) { switch ( c ) { @@ -40578,6 +40578,9 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) case 't': pPars->fTwoOutput ^= 1; break; + case 'b': + pPars->fBooth ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -40720,13 +40723,14 @@ int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &acec [-CT num] [-mdtvh] \n" ); + Abc_Print( -2, "usage: &acec [-CT num] [-mdtbvh] \n" ); Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", pPars->fMiter? "miter":"two circuits"); Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", pPars->fDualOutput? "yes":"no"); Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", pPars->fTwoOutput? "yes":"no"); + Abc_Print( -2, "\t-b : toggle working with Booth multipliers [default = %s]\n", pPars->fBooth? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\tfile1 : (optional) the file with the first network\n"); @@ -40748,12 +40752,15 @@ usage: int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; - int c, fVerbose = 0; + int c, fBooth = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) { switch ( c ) { + case 'b': + fBooth ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -40768,13 +40775,14 @@ int Abc_CommandAbc9Anorm( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Anorm(): There is no AIG.\n" ); return 0; } - pTemp = Acec_Normalize( pAbc->pGia, fVerbose ); + pTemp = Acec_Normalize( pAbc->pGia, fBooth, fVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &anorm [-vh]\n" ); + Abc_Print( -2, "usage: &anorm [-bvh]\n" ); Abc_Print( -2, "\t normalize adder trees in the current AIG\n" ); + Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/abci/abcDress3.c b/src/base/abci/abcDress3.c index 33545f0a..ce0cb7f5 100644 --- a/src/base/abci/abcDress3.c +++ b/src/base/abci/abcDress3.c @@ -33,32 +33,6 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [Compute equivalence classes of nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose ) -{ - Gia_Man_t * pTemp; - Cec_ParFra_t ParsFra, * pPars = &ParsFra; - Cec_ManFraSetDefaultParams( pPars ); - pPars->fUseOrigIds = 1; - pPars->fSatSweeping = 1; - pPars->nBTLimit = nConfs; - pPars->fVerbose = fVerbose; - pTemp = Cec_ManSatSweeping( pGia, pPars, 0 ); - Gia_ManStop( pTemp ); - pTemp = Gia_ManOrigIdsReduce( pGia, pGia->vIdsEquiv ); - Gia_ManStop( pTemp ); -} - /**Function************************************************************* Synopsis [Converts AIG from HOP to GIA.] @@ -315,13 +289,15 @@ void Abc_NtkDumpEquivFile( char * pFileName, Vec_Int_t * vClasses, Abc_Ntk_t * p void Abc_NtkDumpEquiv( Abc_Ntk_t * pNtks[2], char * pFileName, int nConfs, int fByName, int fVerbose ) { //abctime clk = Abc_Clock(); + Gia_Man_t * pTemp; Vec_Int_t * vClasses; // derive shared AIG for the two networks Gia_Man_t * pGia = Abc_NtkAigToGiaTwo( pNtks[0], pNtks[1], fByName ); if ( fVerbose ) printf( "Computing equivalences for networks \"%s\" and \"%s\" with conflict limit %d.\n", Abc_NtkName(pNtks[0]), Abc_NtkName(pNtks[1]), nConfs ); // compute equivalences in this AIG - Abc_NtkComputeGiaEquivs( pGia, nConfs, fVerbose ); + pTemp = Gia_ManComputeGiaEquivs( pGia, nConfs, fVerbose ); + Gia_ManStop( pTemp ); //if ( fVerbose ) // Abc_PrintTime( 1, "Equivalence computation time", Abc_Clock() - clk ); if ( fVerbose ) -- cgit v1.2.3 From 1b86911c4fe0b193c3a281e823de7934664da798 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 14 Jan 2017 20:28:26 +0700 Subject: Updates to arithmetic verification. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1e94f28f..9db3d7d6 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -42690,7 +42690,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); -// Gia_PolynExplore( pAbc->pGia ); + Acec_MultFindPPsTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; -- cgit v1.2.3 From 153b71c1403ed79d7650ad702bb343e0490e36c9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 15 Jan 2017 20:59:59 +0700 Subject: Updates to arithmetic verification. --- src/base/abci/abc.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 9db3d7d6..58a14e81 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -482,6 +482,7 @@ static int Abc_CommandAbc9ATree ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Anorm ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Decla ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1126,6 +1127,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&anorm", Abc_CommandAbc9Anorm, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&decla", Abc_CommandAbc9Decla, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 ); @@ -40788,6 +40790,57 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Decla( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Gia_Man_t * pTemp; + int c, fBooth = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fBooth ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Decla(): There is no AIG.\n" ); + return 0; + } + pTemp = Acec_ManDecla( pAbc->pGia, fBooth, fVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &decla [-bvh]\n" ); + Abc_Print( -2, "\t removes carry look ahead adders\n" ); + Abc_Print( -2, "\t-b : toggles working with Booth multipliers [default = %s]\n", fBooth? "yes": "no" ); + Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + /**Function************************************************************* Synopsis [] @@ -42690,7 +42743,6 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); - Acec_MultFindPPsTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; -- cgit v1.2.3 From a28be94ac79c0cbb0960565573985838d7a27a79 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Jan 2017 11:59:01 +0800 Subject: Small fixes and a change to &cec to allow two files names given as command-line arguments. --- src/base/abci/abc.c | 121 +++++++++++++++++++++++++++++++--------------- src/base/abci/abcVerify.c | 14 ++++-- 2 files changed, 91 insertions(+), 44 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 58a14e81..806a5de7 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -32927,8 +32927,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) { Cec_ParCec_t ParsCec, * pPars = &ParsCec; FILE * pFile; - Gia_Man_t * pSecond, * pMiter; - char * FileName, * pTemp; + Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; char ** pArgvNew; int c, nArgcNew, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; Cec_ManCecSetDefaultParams( pPars ); @@ -32983,13 +32982,15 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( pAbc->pGia == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no AIG.\n" ); - return 1; - } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; if ( fMiter ) { + if ( pAbc->pGia == NULL || nArgcNew != 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): A miter cannot be given as an argument of command &cec and should be entered using &r.\n" ); + return 1; + } if ( fDualOutput ) { if ( Gia_ManPoNum(pAbc->pGia) & 1 ) @@ -32998,14 +32999,14 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a double-output miter.\n" ); pAbc->Status = Cec_ManVerify( pAbc->pGia, pPars ); } else { Gia_Man_t * pTemp; if ( !pPars->fSilent ) - Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit ); + Abc_Print( 1, "Assuming the current network is a single-output miter.\n" ); pTemp = Gia_ManDemiterToDual( pAbc->pGia ); pAbc->Status = Cec_ManVerify( pTemp, pPars ); ABC_SWAP( Abc_Cex_t *, pAbc->pGia->pCexComb, pTemp->pCexComb ); @@ -33014,41 +33015,81 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); return 0; } - - pArgvNew = argv + globalUtilOptind; - nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 1 ) + if ( nArgcNew > 2 ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" ); + return 1; + } + if ( nArgcNew == 2 ) { - if ( pAbc->pGia->pSpec == NULL ) + char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp; + int n; + for ( n = 0; n < 2; n++ ) { - Abc_Print( -1, "File name is not given on the command line.\n" ); - return 1; + // fix the wrong symbol + for ( pTemp = pFileNames[n]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( pFileNames[n], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] ); + if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 ); + if ( pGias[n] == NULL ) + { + Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] ); + return 0; + } } - FileName = pAbc->pGia->pSpec; } else - FileName = pArgvNew[0]; - // fix the wrong symbol - for ( pTemp = FileName; *pTemp; pTemp++ ) - if ( *pTemp == '>' ) - *pTemp = '\\'; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); - if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", FileName ); - Abc_Print( 1, "\n" ); - return 1; - } - fclose( pFile ); - pSecond = Gia_AigerRead( FileName, 0, 0, 0 ); - if ( pSecond == NULL ) { - Abc_Print( -1, "Reading AIGER has failed.\n" ); - return 0; + char * FileName, * pTemp; + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" ); + return 1; + } + pGias[0] = pAbc->pGia; + if ( nArgcNew == 1 ) + FileName = pArgvNew[0]; + else + { + assert( nArgcNew == 0 ); + if ( pAbc->pGia->pSpec == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } + FileName = pAbc->pGia->pSpec; + } + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pGias[1] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } } // compute the miter - pMiter = Gia_ManMiter( pAbc->pGia, pSecond, 0, 1, 0, 0, pPars->fVerbose ); + pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, 1, 0, 0, pPars->fVerbose ); if ( pMiter ) { if ( fDumpMiter ) @@ -33057,10 +33098,12 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0 ); } pAbc->Status = Cec_ManVerify( pMiter, pPars ); - Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); Gia_ManStop( pMiter ); } - Gia_ManStop( pSecond ); + if ( pGias[0] != pAbc->pGia ) + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); return 0; usage: @@ -36178,7 +36221,7 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: &satlut [-NICDQ num] [-drwvh]\n" ); - Abc_Print( -2, "\t performs SAT-based remapping of the 4-LUT network\n" ); + Abc_Print( -2, "\t performs SAT-based remapping of the LUT-mapped network\n" ); Abc_Print( -2, "\t-N num : the limit on AIG nodes in the window (num <= 128) [default = %d]\n", nNumber ); Abc_Print( -2, "\t-I num : the limit on the number of improved windows [default = %d]\n", nImproves ); Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nBTLimit ); diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c index 25d1d113..7199c529 100644 --- a/src/base/abci/abcVerify.c +++ b/src/base/abci/abcVerify.c @@ -122,6 +122,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI ***********************************************************************/ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ) { + abctime clk = Abc_Clock(); Prove_Params_t Params, * pParams = &Params; // Fraig_Params_t Params; // Fraig_Man_t * pMan; @@ -170,18 +171,20 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV RetValue = Abc_NtkMiterIsConstant( pMiter ); if ( RetValue == 0 ) { - printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); + printf( "Networks are NOT EQUIVALENT after structural hashing. " ); // report the error pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 ); Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); ABC_FREE( pMiter->pModel ); Abc_NtkDelete( pMiter ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return; } if ( RetValue == 1 ) { - printf( "Networks are equivalent after structural hashing.\n" ); + printf( "Networks are equivalent after structural hashing. " ); Abc_NtkDelete( pMiter ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return; } /* @@ -220,18 +223,19 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV // pParams->fVerbose = 1; RetValue = Abc_NtkIvyProve( &pMiter, pParams ); if ( RetValue == -1 ) - printf( "Networks are undecided (resource limits is reached).\n" ); + printf( "Networks are undecided (resource limits is reached). " ); else if ( RetValue == 0 ) { int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel ); if ( pSimInfo[0] != 1 ) printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" ); else - printf( "Networks are NOT EQUIVALENT.\n" ); + printf( "Networks are NOT EQUIVALENT. " ); ABC_FREE( pSimInfo ); } else - printf( "Networks are equivalent.\n" ); + printf( "Networks are equivalent. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); if ( pMiter->pModel ) Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); Abc_NtkDelete( pMiter ); -- cgit v1.2.3 From cf539dcca475d1c7f862834e8718bb318b54d5fd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 21 Jan 2017 12:48:40 +0800 Subject: Fix mismatch in output formatting. --- src/base/abci/abcDar.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 9f672485..147f7c2f 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -1946,17 +1946,17 @@ finish: // report the miter if ( RetValue == 1 ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } fflush( stdout ); @@ -3695,17 +3695,17 @@ int Abc_NtkDarInduction( Abc_Ntk_t * pNtk, int nTimeOut, int nFramesMax, int nCo RetValue = Saig_ManInduction( pMan, nTimeOut, nFramesMax, nConfMax, fUnique, fUniqueAll, fGetCex, fVerbose, fVeryVerbose ); if ( RetValue == 1 ) { - Abc_Print( 1, "Networks are equivalent. " ); + Abc_Print( 1, "Networks are equivalent. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else if ( RetValue == 0 ) { - Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); + Abc_Print( 1, "Networks are NOT EQUIVALENT. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } else { - Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_Print( 1, "Networks are UNDECIDED. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( fGetCex ) -- cgit v1.2.3 From 51f4dab475af1ffd22d23b5aeb8d7cf243739f75 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:02:19 -0800 Subject: Adding features for invariant minimization. --- src/base/main/mainFrame.c | 4 - src/base/main/mainInt.h | 2 - src/base/wlc/wlcAbc.c | 151 ++++++++++++++++----- src/base/wlc/wlcCom.c | 338 +++++++++++++++++++++++++++++++++++++--------- 4 files changed, 395 insertions(+), 100 deletions(-) (limited to 'src/base') diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index 05cb09c1..9647d020 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -95,8 +95,6 @@ void Abc_FrameSetStatus( int Status ) { ABC_FREE( s_Globa void Abc_FrameSetManDsd( void * pMan ) { if (s_GlobalFrame->pManDsd && s_GlobalFrame->pManDsd != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd, 0); s_GlobalFrame->pManDsd = pMan; } void Abc_FrameSetManDsd2( void * pMan ) { if (s_GlobalFrame->pManDsd2 && s_GlobalFrame->pManDsd2 != pMan) If_DsdManFree((If_DsdMan_t *)s_GlobalFrame->pManDsd2, 0); s_GlobalFrame->pManDsd2 = pMan; } void Abc_FrameSetInv( Vec_Int_t * vInv ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcInv); s_GlobalFrame->pAbcWlcInv = vInv; } -void Abc_FrameSetCnf( Vec_Int_t * vCnf ) { Vec_IntFreeP(&s_GlobalFrame->pAbcWlcCnf); s_GlobalFrame->pAbcWlcCnf = vCnf; } -void Abc_FrameSetStr( Vec_Str_t * vStr ) { Vec_StrFreeP(&s_GlobalFrame->pAbcWlcStr); s_GlobalFrame->pAbcWlcStr = vStr; } void Abc_FrameSetJsonStrs( Abc_Nam_t * pStrs ) { Abc_NamDeref( s_GlobalFrame->pJsonStrs ); s_GlobalFrame->pJsonStrs = pStrs; } void Abc_FrameSetJsonObjs( Vec_Wec_t * vObjs ) { Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); s_GlobalFrame->vJsonObjs = vObjs; } @@ -227,8 +225,6 @@ void Abc_FrameDeallocate( Abc_Frame_t * p ) ABC_FREE( p->pCex2 ); ABC_FREE( p->pCex ); Vec_IntFreeP( &p->pAbcWlcInv ); - Vec_IntFreeP( &p->pAbcWlcCnf ); - Vec_StrFreeP( &p->pAbcWlcStr ); Abc_NamDeref( s_GlobalFrame->pJsonStrs ); Vec_WecFreeP(&s_GlobalFrame->vJsonObjs ); ABC_FREE( p ); diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index ff59b81a..278a9191 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -129,8 +129,6 @@ struct Abc_Frame_t_ void * pAbc85Delay; void * pAbcWlc; Vec_Int_t * pAbcWlcInv; - Vec_Int_t * pAbcWlcCnf; - Vec_Str_t * pAbcWlcStr; void * pAbcBac; void * pAbcCba; void * pAbcPla; diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 0bf27f7b..1a98fb71 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -42,7 +42,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) +void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose ) { Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; @@ -53,7 +53,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) nRange = Wlc_ObjRange(pObj); for ( k = 0; k < nRange; k++ ) { - nNum = Vec_IntEntry(vInv, nBits + k); + nNum = Vec_IntEntry(vCounts, nBits + k); if ( nNum ) break; } @@ -65,7 +65,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); for ( k = 0; k < nRange; k++ ) { - nNum = Vec_IntEntry( vInv, nBits + k ); + nNum = Vec_IntEntry( vCounts, nBits + k ); if ( nNum == 0 ) continue; printf( " [%d] -> %d", k, nNum ); @@ -73,8 +73,8 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) printf( "\n"); nBits += nRange; } - //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); - assert( Vec_IntSize(vInv) == nBits ); + //printf( "%d %d\n", Vec_IntSize(vCounts), nBits ); + assert( Vec_IntSize(vCounts) == nBits ); } /**Function************************************************************* @@ -88,8 +88,14 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ) +Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) { + extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); + extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ); + + Vec_Int_t * vCounts = Pdr_InvCounts( vInv ); + Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts ); + Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; Abc_Ntk_t * pMainNtk = NULL; @@ -98,46 +104,69 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, // start the network pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); // duplicate the name and the spec - pMainNtk->pName = Extra_UtilStrsav(pNtk->pName); + pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv"); // create primary inputs - Wlc_NtkForEachCi( pNtk, pObj, i ) + if ( pNtk == NULL ) { - if ( pObj->Type != WLC_OBJ_FO ) - continue; - nRange = Wlc_ObjRange(pObj); - for ( k = 0; k < nRange; k++ ) + int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) ); + Vec_IntForEachEntry( vCounts, Entry, i ) { - nNum = Vec_IntEntry(vInv, nBits + k); - if ( nNum ) - break; + if ( Entry == 0 ) + continue; + pMainObj = Abc_NtkCreatePi( pMainNtk ); + sprintf( Buffer, "pi%d", i ); + Abc_ObjAssignName( pMainObj, Buffer, NULL ); } - if ( k == nRange ) + if ( Abc_NtkPiNum(pMainNtk) != nInputs ) { - nBits += nRange; - continue; + printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" ); + Abc_NtkDelete( pMainNtk ); + return NULL; } - //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); - for ( k = 0; k < nRange; k++ ) + } + else + { + Wlc_NtkForEachCi( pNtk, pObj, i ) { - nNum = Vec_IntEntry( vInv, nBits + k ); - if ( nNum == 0 ) + if ( pObj->Type != WLC_OBJ_FO ) continue; - //printf( " [%d] -> %d", k, nNum ); - pMainObj = Abc_NtkCreatePi( pMainNtk ); - sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); - Abc_ObjAssignName( pMainObj, Buffer, NULL ); - + nRange = Wlc_ObjRange(pObj); + for ( k = 0; k < nRange; k++ ) + { + nNum = Vec_IntEntry(vCounts, nBits + k); + if ( nNum ) + break; + } + if ( k == nRange ) + { + nBits += nRange; + continue; + } + //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); + for ( k = 0; k < nRange; k++ ) + { + nNum = Vec_IntEntry( vCounts, nBits + k ); + if ( nNum == 0 ) + continue; + //printf( " [%d] -> %d", k, nNum ); + pMainObj = Abc_NtkCreatePi( pMainNtk ); + sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); + Abc_ObjAssignName( pMainObj, Buffer, NULL ); + + } + //printf( "\n"); + nBits += nRange; } - //printf( "\n"); - nBits += nRange; } - //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); - assert( Vec_IntSize(vInv) == nBits ); + //printf( "%d %d\n", Vec_IntSize(vCounts), nBits ); + assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits ); // create node pMainObj = Abc_NtkCreateNode( pMainNtk ); Abc_NtkForEachPi( pMainNtk, pMainTemp, i ) Abc_ObjAddFanin( pMainObj, pMainTemp ); pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) ); + Vec_IntFree( vCounts ); + Vec_StrFree( vSop ); // create PO pMainTemp = Abc_NtkCreatePo( pMainNtk ); Abc_ObjAddFanin( pMainTemp, pMainObj ); @@ -145,6 +174,66 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, return pMainNtk; } +/**Function************************************************************* + + Synopsis [Translate current network into an interpolant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) +{ + Vec_Int_t * vRes = NULL; + if ( Abc_NtkPoNum(pNtk) != 1 ) + printf( "The number of outputs is other than 1.\n" ); + else if ( Abc_NtkNodeNum(pNtk) != 1 ) + printf( "The number of internal nodes is other than 1.\n" ); + else + { + Abc_Obj_t * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); + char * pName, * pCube, * pSop = (char *)pNode->pData; + Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) ); + Abc_Obj_t * pFanin; int i, k, Value, nLits; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + assert( Abc_ObjIsCi(pFanin) ); + pName = Abc_ObjName(pFanin); + for ( k = (int)strlen(pName)-1; k >= 0; k-- ) + if ( pName[k] < '0' || pName[k] > '9' ) + break; + if ( k == (int)strlen(pName)-1 ) + { + printf( "Cannot read input name of fanin %d.\n", i ); + Value = i; + } + else + Value = atoi(pName + k + 1); + Vec_IntPush( vFanins, Value ); + } + assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) ); + vRes = Vec_IntAlloc( 1000 ); + Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) ); + Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube ) + { + nLits = 0; + Abc_CubeForEachVar( pCube, Value, k ) + if ( Value != '-' ) + nLits++; + Vec_IntPush( vRes, nLits ); + Abc_CubeForEachVar( pCube, Value, k ) + if ( Value != '-' ) + Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') ); + } + Vec_IntPush( vRes, nRegs ); + Vec_IntFree( vFanins ); + } + return vRes; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index f3eb6dd7..93614938 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,18 +32,21 @@ static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); + static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; } static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; } -static inline Vec_Int_t * Wlc_AbcGetCnf( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcCnf; } -static inline Vec_Str_t * Wlc_AbcGetStr( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcStr; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -66,10 +69,15 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); + + Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); } /**Function******************************************************************** @@ -440,10 +448,108 @@ usage: SeeAlso [] ******************************************************************************/ -int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv ) { + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + 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 ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" ); + return 0; + } + Wlc_WinProfileArith( pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%profile [-vh]\n" ); + Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p ); + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + 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 ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" ); + return 0; + } + // transform + //pNtk = Wlc_NtkUifNodePairs( pNtk, NULL ); + //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL ); + //Wlc_AbcUpdateNtk( pAbc, pNtk ); + //Wlc_GenerateSmtStdout( pAbc ); + //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc ); + pNtk = Wlc_NtkDupSingleNodes( pNtk ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%test [-vh]\n" ); + Abc_Print( -2, "\t experiments with word-level networks\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); extern void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, int fVerbose ); Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Vec_Int_t * vCounts; int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -461,24 +567,66 @@ int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pNtk == NULL ) { - Abc_Print( 1, "Abc_CommandPsInv(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandInvPs(): There is no current design.\n" ); return 0; } - if ( Wlc_AbcGetNtk(pAbc) == NULL ) + if ( Wlc_AbcGetInv(pAbc) == NULL ) { - Abc_Print( 1, "Abc_CommandPsInv(): There is no saved invariant.\n" ); + Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); return 0; } + vCounts = Pdr_InvCounts( Wlc_AbcGetInv(pAbc) ); + Wlc_NtkPrintInvStats( pNtk, vCounts, fVerbose ); + Vec_IntFree( vCounts ); + return 0; +usage: + Abc_Print( -2, "usage: inv_ps [-vh]\n" ); + Abc_Print( -2, "\t prints statistics for inductive invariant\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Pdr_InvPrint( Vec_Int_t * vInv ); + 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 ( Wlc_AbcGetInv(pAbc) == NULL ) { - Abc_Print( 1, "Abc_CommandPsInv(): Invariant is not available.\n" ); + Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); return 0; } - Wlc_NtkPrintInvStats( pNtk, Wlc_AbcGetInv(pAbc), fVerbose ); + Pdr_InvPrint( Wlc_AbcGetInv(pAbc) ); return 0; - usage: - Abc_Print( -2, "usage: %%psinv [-vh]\n" ); - Abc_Print( -2, "\t prints statistics for inductive invariant\n" ); +usage: + Abc_Print( -2, "usage: inv_print [-vh]\n" ); + Abc_Print( -2, "\t prints the current inductive invariant\n" ); Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); @@ -496,11 +644,9 @@ int Abc_CommandPsInv( Abc_Frame_t * pAbc, int argc, char ** argv ) SeeAlso [] ******************************************************************************/ -int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ); - Abc_Ntk_t * pMainNtk; - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + extern Vec_Int_t * Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -516,28 +662,76 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( pNtk == NULL ) + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" ); + return 0; + } + if ( Wlc_AbcGetInv(pAbc) == NULL ) { - Abc_Print( 1, "Abc_CommandGetInv(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandInvMin(): There is no saved invariant.\n" ); return 0; } - if ( Wlc_AbcGetNtk(pAbc) == NULL ) + if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(Wlc_AbcGetInv(pAbc)) ) { - Abc_Print( 1, "Abc_CommandGetInv(): There is no saved invariant.\n" ); + Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } + Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + return 0; +usage: + Abc_Print( -2, "usage: inv_check [-vh]\n" ); + Abc_Print( -2, "\t checks that the invariant is indeed an inductive invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ); + Abc_Ntk_t * pMainNtk; + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + 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 ( Wlc_AbcGetInv(pAbc) == NULL ) { - Abc_Print( 1, "Abc_CommandGetInv(): Invariant is not available.\n" ); + Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" ); return 0; } // derive the network - pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), Wlc_AbcGetStr(pAbc), fVerbose ); + pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) ); // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); + if ( pMainNtk ) + Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); return 0; - usage: - Abc_Print( -2, "usage: %%getinv [-vh]\n" ); +usage: + Abc_Print( -2, "usage: inv_get [-vh]\n" ); Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" ); Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); @@ -556,34 +750,45 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv ) SeeAlso [] ******************************************************************************/ -int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ); + Vec_Int_t * vInv = NULL; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); 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; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; } } if ( pNtk == NULL ) { - Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandInvPut(): There is no current design.\n" ); return 0; } - Wlc_WinProfileArith( pNtk ); + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvPut(): There is no current AIG.\n" ); + return 0; + } + // derive the network + vInv = Wlc_NtkGetPut( pNtk, Gia_ManRegNum(pAbc->pGia) ); + if ( vInv ) + Abc_FrameSetInv( vInv ); return 0; usage: - Abc_Print( -2, "usage: %%profile [-vh]\n" ); - Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" ); + Abc_Print( -2, "usage: inv_put [-vh]\n" ); + Abc_Print( -2, "\t inputs the current network in the main-space as an invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -600,42 +805,49 @@ usage: SeeAlso [] ******************************************************************************/ -int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p ); - Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); + Vec_Int_t * vInv, * vInv2; 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; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; } } - if ( pNtk == NULL ) + if ( pAbc->pGia == NULL ) { - Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" ); + Abc_Print( 1, "Abc_CommandInvMin(): There is no current design.\n" ); return 0; } - // transform - //pNtk = Wlc_NtkUifNodePairs( pNtk, NULL ); - //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL ); - //Wlc_AbcUpdateNtk( pAbc, pNtk ); - //Wlc_GenerateSmtStdout( pAbc ); - //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc ); - pNtk = Wlc_NtkDupSingleNodes( pNtk ); - Wlc_AbcUpdateNtk( pAbc, pNtk ); + if ( Wlc_AbcGetInv(pAbc) == NULL ) + { + Abc_Print( 1, "Abc_CommandInvMin(): Invariant is not available.\n" ); + return 0; + } + vInv = Wlc_AbcGetInv(pAbc); + if ( Gia_ManRegNum(pAbc->pGia) != Vec_IntEntryLast(vInv) ) + { + Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); + return 0; + } + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + if ( vInv2 ) + Abc_FrameSetInv( vInv2 ); return 0; usage: - Abc_Print( -2, "usage: %%test [-vh]\n" ); - Abc_Print( -2, "\t experiments with word-level networks\n" ); + Abc_Print( -2, "usage: inv_min [-vh]\n" ); + Abc_Print( -2, "\t minimizes the number of clauses in the current invariant\n" ); + Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; -- cgit v1.2.3 From 849f18076411a54c21e593e3bd9e72bf6d56883e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 20:44:25 -0800 Subject: Adding features for invariant minimization. --- src/base/wlc/wlcAbc.c | 2 +- src/base/wlc/wlcCom.c | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 1a98fb71..1f10d7b0 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -176,7 +176,7 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) /**Function************************************************************* - Synopsis [Translate current network into an interpolant.] + Synopsis [Translate current network into an invariant.] Description [] diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 93614938..85b3b35d 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -646,8 +646,8 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); - int c, fVerbose = 0; + extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); + int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) { @@ -677,7 +677,11 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + if ( nFailed ) + printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); + else + printf( "Invariant verification passes.\n" ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); @@ -808,13 +812,17 @@ usage: int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); + extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ); Vec_Int_t * vInv, * vInv2; - int c, fVerbose = 0; + int c, fLits = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "lvh" ) ) != EOF ) { switch ( c ) { + case 'l': + fLits ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -840,14 +848,18 @@ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + if ( fLits ) + vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv ); + else + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); if ( vInv2 ) Abc_FrameSetInv( vInv2 ); return 0; usage: - Abc_Print( -2, "usage: inv_min [-vh]\n" ); - Abc_Print( -2, "\t minimizes the number of clauses in the current invariant\n" ); + Abc_Print( -2, "usage: inv_min [-lvh]\n" ); + Abc_Print( -2, "\t performs minimization of the current invariant\n" ); Abc_Print( -2, "\t (AIG representing the design should be in the &-space)\n" ); + Abc_Print( -2, "\t-l : toggle minimizing literals rather than clauses [default = %s]\n", fLits? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; -- cgit v1.2.3 From cf1106aba8d940a6d9d5f410b6773c24bdf0d393 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 24 Jan 2017 22:28:28 -0800 Subject: Adding features for invariant minimization. --- src/base/wlc/wlcCom.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 85b3b35d..be9ba7f6 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -601,7 +601,7 @@ usage: ******************************************************************************/ int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Pdr_InvPrint( Vec_Int_t * vInv ); + extern void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose ); int c, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -622,7 +622,7 @@ int Abc_CommandInvPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvPs(): Invariant is not available.\n" ); return 0; } - Pdr_InvPrint( Wlc_AbcGetInv(pAbc) ); + Pdr_InvPrint( Wlc_AbcGetInv(pAbc), fVerbose ); return 0; usage: Abc_Print( -2, "usage: inv_print [-vh]\n" ); @@ -646,7 +646,7 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv ); + extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) @@ -677,7 +677,7 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvMin(): The number of flops in the invariant and in GIA should be the same.\n" ); return 0; } - nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc) ); + nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc), fVerbose ); if ( nFailed ) printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else @@ -811,8 +811,8 @@ usage: ******************************************************************************/ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv ); - extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv ); + extern Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); + extern Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); Vec_Int_t * vInv, * vInv2; int c, fLits = 0, fVerbose = 0; Extra_UtilGetoptReset(); @@ -849,9 +849,9 @@ int Abc_CommandInvMin( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } if ( fLits ) - vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv ); + vInv2 = Pdr_InvMinimizeLits( pAbc->pGia, vInv, fVerbose ); else - vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv ); + vInv2 = Pdr_InvMinimize( pAbc->pGia, vInv, fVerbose ); if ( vInv2 ) Abc_FrameSetInv( vInv2 ); return 0; -- cgit v1.2.3 From 3119e1e30f8a44eb6236792c69f8cca64c99f7a8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 25 Jan 2017 13:56:16 -0800 Subject: Adding features for invariant minimization. --- src/base/wlc/wlcCom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index be9ba7f6..2828fea3 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -681,7 +681,7 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nFailed ) printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else - printf( "Invariant verification passes.\n" ); + printf( "Invariant verification succeeded.\n" ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); -- cgit v1.2.3 From 3c8c807ac16dbfc9b1960f77dd49fd244e3d718d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 11:56:17 -0800 Subject: Improvements to SMT-LIB parser. --- src/base/wlc/wlc.h | 1 + src/base/wlc/wlcNtk.c | 6 +- src/base/wlc/wlcReadSmt.c | 320 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 243 insertions(+), 84 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 1df3e5e9..6f64b47a 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -140,6 +140,7 @@ struct Wlc_Ntk_t_ int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type int nAnds[WLC_OBJ_NUMBER]; // counter of AND gates after blasting int fSmtLib; // the network comes from an SMT-LIB file + int nAssert; // the number of asserts // memory for objects Wlc_Obj_t * pObjs; int iObj; diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 6f396771..a0799ba0 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -195,14 +195,14 @@ void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ) { assert( pObj->nFanins == 0 ); pObj->nFanins = Vec_IntSize(vFanins); - if ( Wlc_ObjHasArray(pObj) ) - pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) ); - memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) ); // special treatment of CONST, SELECT and TABLE if ( pObj->Type == WLC_OBJ_CONST ) pObj->nFanins = 0; else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE ) pObj->nFanins = 1; + if ( Wlc_ObjHasArray(pObj) ) + pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) ); + memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) ); } void Wlc_NtkFree( Wlc_Ntk_t * p ) { diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index d07a54c4..61d0bca8 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -219,6 +219,8 @@ static inline int Smt_StrToType( char * pName, int * pfSigned ) Type = WLC_OBJ_ARI_REM, *pfSigned = 1; // 40: arithmetic remainder else if ( !strcmp(pName, "bvsmod") ) Type = WLC_OBJ_ARI_MODULUS, *pfSigned = 1; // 40: arithmetic modulus + else if ( !strcmp(pName, "=") ) + Type = WLC_OBJ_COMP_EQU; // 40: arithmetic modulus // else if ( !strcmp(pName, "") ) // Type = WLC_OBJ_ARI_POWER; // 41: arithmetic power else if ( !strcmp(pName, "bvneg") ) @@ -255,6 +257,8 @@ static inline int Smt_PrsReadType( Smt_Prs_t * p, int iSig, int * pfSigned, int } } +static inline int Smt_StrType( char * str ) { return Smt_StrToType(str, NULL); } + /**Function************************************************************* Synopsis [] @@ -274,20 +278,27 @@ static inline int Smt_PrsCreateNodeOld( Wlc_Ntk_t * pNtk, int Type, int fSigned, assert( Type > 0 ); assert( Range >= 0 ); assert( fSigned >= 0 ); - Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); - if ( fSigned ) - Wlc_NtkObj(pNtk, iObj)->Signed = fSigned; - if ( Type == WLC_OBJ_SHIFT_RA ) - Wlc_NtkObj(pNtk, iObj)->Signed = 1; + + // add node's name if ( pName == NULL ) { sprintf( Buffer, "_n%d_", iObj ); pName = Buffer; } - // add node's name NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); assert( !fFound ); assert( iObj == NameId ); + + Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins ); + if ( fSigned ) + { + Wlc_NtkObj(pNtk, iObj)->Signed = fSigned; +// if ( Vec_IntSize(vFanins) > 0 ) +// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 0))->Signed = fSigned; +// if ( Vec_IntSize(vFanins) > 1 ) +// Wlc_NtkObj(pNtk, Vec_IntEntry(vFanins, 1))->Signed = fSigned; + } + return iObj; } static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, int Range, Vec_Int_t * vFanins, char * pName ) @@ -302,8 +313,7 @@ static inline int Smt_PrsCreateNode( Wlc_Ntk_t * pNtk, int Type, int fSigned, in assert( Range >= 0 ); assert( fSigned >= 0 ); - // allow more than 2 fanins for specific operators - // if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX ) + //if (Vec_IntSize(vFanins)<=2 || Type == WLC_OBJ_BIT_CONCAT || Type == WLC_OBJ_MUX ) // explicitely secify allowed multi operators if (Vec_IntSize(vFanins)<=2 || !( Type == WLC_OBJ_BIT_AND || // 16:`` bitwise AND @@ -362,17 +372,17 @@ FINISHED_WITH_FANINS: Vec_IntFree(v2Fanins); - // to deal with long shifts create extra bit select (ROTATE as well ??) + //added to deal with long shifts create extra bit select (ROTATE as well ??) // this is a temporary hack - // basically we keep only 32 bits. - // bits 0 - 30 are kept same as original - // bit 31 will be the reduction or of all bits from 31 to Range-1 + // basically we keep only 32 bits. + // bit[31] will be the copy of original MSB (sign bit, just in case) UPDATE: assume it is unsigned first???? + // bit[31] will be the reduction or of any bits from [31] to Range if (Type == WLC_OBJ_SHIFT_R || Type == WLC_OBJ_SHIFT_RA || Type == WLC_OBJ_SHIFT_L) { - int iFanin1 = Vec_IntEntry(vFanins,1); - int range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) ); - int iObj1, iObj2, iObj3; + int range1, iObj1, iObj2, iObj3; assert(Vec_IntSize(vFanins)>=2); + iFanin1 = Vec_IntEntry(vFanins,1); + range1 = Wlc_ObjRange( Wlc_NtkObj(pNtk, iFanin1) ); if (range1>32) { Vec_Int_t * newFanins = Vec_IntAlloc(10); @@ -389,6 +399,8 @@ FINISHED_WITH_FANINS: Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj1), newFanins ); + //printf("obj1: %d\n",iObj1); + // bit select of larger bits Vec_IntPop(newFanins); Vec_IntPop(newFanins); @@ -402,6 +414,7 @@ FINISHED_WITH_FANINS: assert( iObj2 == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj2), newFanins ); + //printf("obj2: %d\n",iObj2); // reduction or Vec_IntPop( newFanins ); @@ -416,6 +429,7 @@ FINISHED_WITH_FANINS: assert( iObj3 == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj3), newFanins ); + //printf("obj3: %d\n",iObj3); // concat all together Vec_IntWriteEntry( newFanins, 0, iObj3 ); @@ -429,6 +443,7 @@ FINISHED_WITH_FANINS: assert( iObj == NameId ); Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), newFanins ); + //printf("obj: %d\n",iObj); // pushing the new node Vec_IntWriteEntry(vFanins, 1, iObj); @@ -461,34 +476,22 @@ FINISHED_WITH_FANINS: return iObj; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ static inline char * Smt_GetHexFromDecimalString(char * pStr) { int i,k=0, nDigits = strlen(pStr); int digit, carry = 0; - int metNonZeroBit; - int nBits; - char * hex; + int metNonZeroBit = 0; Vec_Int_t * decimal = Vec_IntAlloc(nDigits); Vec_Int_t * rev; + int nBits; + char * hex; for (i=0;i= '0' && pStr[0] <= '9' ) { + // added: sanity check for large constants + /* + Vec_Int_t * temp = Vec_IntAlloc(10); + int fullBits = -1; + Smt_GetBinaryFromDecimalString(pStr,temp,&fullBits); + Vec_IntFree(temp); + assert(fullBits < 32);*/ + + char * pHex = Smt_GetHexFromDecimalString(pStr); + + if ( nBits == -1 ) + nBits = strlen(pHex)*4; + + //printf("nbits: %d\n",nBits); + + Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); + nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex ); + ABC_FREE( pHex ); + /* int w, nWords, Number = atoi( pStr ); if ( nBits == -1 ) @@ -589,15 +616,6 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits for ( w = 0; w < nWords; w++ ) Vec_IntPush( vFanins, w ? 0 : Number ); */ - - // convert decimal to hex to parse large constants - char * pHex = Smt_GetHexFromDecimalString(pStr); - - if ( nBits == -1 ) - nBits = strlen(pHex)*4; - - Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); - nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pHex ); } else { @@ -648,12 +666,6 @@ int Smt_PrsBuildNode( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int RangeOut, // s3087 int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); assert( fFound ); - // create buffer if the name of the fanin has different name - if ( pName && strcmp(pStr, pName) ) - { - Vec_IntFill( &p->vTempFans, 1, iObj ); - iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, RangeOut, &p->vTempFans, pName ); - } return iObj; } } @@ -804,13 +816,6 @@ Wlc_Ntk_t * Smt_PrsBuild( Smt_Prs_t * p ) // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); - vFans2 = Smt_VecEntryNode(p, vFans, 2); - if ( Vec_IntSize(vFans2) > 0 ) - { - printf( "File parsing error: Uninterpreted functions are not supported.\n" ); - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } // check type (Bool or BitVec) Fan = Vec_IntEntry(vFans, 3); if ( Smt_EntryIsName(Fan) ) @@ -1006,6 +1011,14 @@ char * Smt_PrsGenName( Smt_Prs_t * p ) } int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pName ) { + char suffix[100]; + sprintf(suffix,"_as%d",pNtk->nAssert); + + //char * prepStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode)); + //printf("prestr: %s\n",prepStr); + + //printf("inode: %d %d\n",iNode,Smt_EntryIsName(iNode)); + if ( Smt_EntryIsName(iNode) ) { char * pStr = Abc_NamStr(p->pStrs, Abc_Lit2Var(iNode)); @@ -1018,7 +1031,27 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, return Smt_PrsBuildConstant( pNtk, pStr, -1, pName ? pName : Smt_PrsGenName(p) ); else { - int fFound, iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); + int fFound, iObj; + // look either for global DECLARE-FUN variable or local LET + char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb + char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1); + strcpy(pStr_glb,pStr); + strcat(pStr_glb,"_glb"); + strcpy(pStr_loc,pStr); + strcat(pStr_loc,suffix); + + fFound = Abc_NamStrFind( pNtk->pManName, pStr_glb ); + + if (fFound) + pStr = pStr_glb; + else + { + assert( Abc_NamStrFind( pNtk->pManName, pStr_loc )); + pStr = pStr_loc; + } + // FIXME: delete memory of pStr + + iObj = Abc_NamStrFindOrAdd( pNtk->pManName, pStr, &fFound ); assert( fFound ); // create buffer if the name of the fanin has different name if ( pName && strcmp(Wlc_ObjName(pNtk, iObj), pName) ) @@ -1026,9 +1059,11 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, Vec_IntFill( &p->vTempFans, 1, iObj ); iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, Wlc_ObjRange(Wlc_NtkObj(pNtk, iObj)), &p->vTempFans, pName ); } + ABC_FREE( pStr_glb ); + ABC_FREE( pStr_loc ); return iObj; } - } + } else { Vec_Int_t * vRoots, * vRoots1, * vFans3; @@ -1039,7 +1074,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, if ( Smt_EntryIsName(iRoot0) ) { char * pName2, * pStr0 = Abc_NamStr(p->pStrs, Abc_Lit2Var(iRoot0)); - if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET ) + if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET || Abc_Lit2Var(iRoot0) == SMT_PRS_DEFINE_FUN) //added define-fun is similar to let { // let ((s35550 (bvor s48 s35549))) assert( Vec_IntSize(vRoots) == 3 ); @@ -1051,6 +1086,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, // iterate through the parts Vec_IntForEachEntry( vRoots1, Fan, k ) { + char * temp; // s35550 (bvor s48 s35549) assert( !Smt_EntryIsName(Fan) ); vFans3 = Smt_EntryNode(p, Fan); @@ -1059,11 +1095,26 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, Fan3 = Vec_IntEntry(vFans3, 0); assert( Smt_EntryIsName(Fan3) ); pName2 = Smt_EntryName(p, Fan3); + // create a local name with suffix + if ( Abc_Lit2Var(iRoot0) == SMT_PRS_LET ) + { + temp = (char *)malloc(strlen(pName2) + strlen(suffix) + 1); + strcpy(temp, pName2); + strcat(temp,suffix); + } + else + { temp = (char *)malloc(strlen(pName2) + 4 + 1); + strcpy(temp, pName2); + strcat(temp,"_glb"); + } + // FIXME: need to delete memory of pName2 + pName2 = temp; // get function Fan3 = Vec_IntEntry(vFans3, 1); //assert( !Smt_EntryIsName(Fan3) ); // solve the problem iObj = Smt_PrsBuild2_rec( pNtk, p, Fan3, -1, pName2 ); // NULL ); //pName2 ); + ABC_FREE( temp ); if ( iObj == 0 ) return 0; // create buffer @@ -1133,7 +1184,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, int iObj = Abc_NamStrFind( pNtk->pManName, pStr0 ); if ( iObj ) return iObj; - Type0 = Smt_StrToType( pStr0, &fSigned ); if ( Type0 == 0 ) return 0; @@ -1151,7 +1201,6 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, } Vec_IntPush( vFanins, iObj ); } - // find range Range = 0; if ( Type0 >= WLC_OBJ_LOGIC_NOT && Type0 <= WLC_OBJ_REDUCT_XOR ) @@ -1197,7 +1246,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Wlc_Ntk_t * pNtk; Vec_Int_t * vFansRoot, * vFans, * vFans2; Vec_Int_t * vAsserts = Vec_IntAlloc(100); - int i, Root, Fan, iObj, NameId, Range, Status, nBits = 0; + int i, Root, Fan, iObj, NameId, Range, nBits = 0; char * pName, * pRange; // start network and create primary inputs pNtk = Wlc_NtkAlloc( p->pName, 1000 ); @@ -1214,22 +1263,22 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // create variables if ( Abc_Lit2Var(Fan) == SMT_PRS_DECLARE_FUN ) { + char * pName_glb; assert( Vec_IntSize(vFans) == 4 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DECLARE_FUN) ); // get name Fan = Vec_IntEntry(vFans, 1); assert( Smt_EntryIsName(Fan) ); pName = Smt_EntryName(p, Fan); + // added: giving a global suffix + pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); - vFans2 = Smt_VecEntryNode(p, vFans, 2); - if ( Vec_IntSize(vFans2) > 0 ) - { - printf( "File parsing error: Uninterpreted functions are not supported.\n" ); - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } // check type (Bool or BitVec) Fan = Vec_IntEntry(vFans, 3); if ( Smt_EntryIsName(Fan) ) @@ -1259,9 +1308,11 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Vec_IntPush( &pNtk->vValues, nBits ); Vec_IntPush( &pNtk->vValues, Range ); nBits += Range; + ABC_FREE( pName_glb ); } // create constants - else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) + /* + else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) // added: we parse DEFINE_FUN in LET { assert( Vec_IntSize(vFans) == 5 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) ); @@ -1269,6 +1320,14 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) Fan = Vec_IntEntry(vFans, 1); assert( Smt_EntryIsName(Fan) ); pName = Smt_EntryName(p, Fan); + + // added: giving a global suffix + char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; + // skip () Fan = Vec_IntEntry(vFans, 2); assert( !Smt_EntryIsName(Fan) ); @@ -1278,13 +1337,17 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) { // (define-fun s_2 () Bool false) assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) ); - iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), -1, pName ); - if ( iObj == 0 ) - { - Wlc_NtkFree( pNtk ); pNtk = NULL; - goto finish; - } - continue; + Range = 1; + pValue = Smt_VecEntryName(p, vFans, 4); + + //printf("value: %s\n",pValue); + + if ( !strcmp("false", pValue) ) + pValue = "#b0"; + else if ( !strcmp("true", pValue) ) + pValue = "#b1"; + else assert( 0 ); + Status = Smt_PrsBuildConstant( pNtk, pValue, Range, pName ); } else { @@ -1292,6 +1355,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // (define-fun s1 () (_ BitVec 8) (bvneg #x7f)) // get range Fan = Vec_IntEntry(vFans, 3); + assert( !Smt_EntryIsName(Fan) ); vFans2 = Smt_VecEntryNode(p, vFans, 3); assert( Vec_IntSize(vFans2) == 3 ); @@ -1299,11 +1363,24 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) ); // get range Fan = Vec_IntEntry(vFans2, 2); + assert( Smt_EntryIsName(Fan) ); pRange = Smt_EntryName(p, Fan); Range = atoi(pRange); + + // added: can parse functions too + Vec_Int_t * vFans3 = Smt_VecEntryNode(p, vFans, 4); + Fan = Vec_IntEntry(vFans3, 0); + // get constant - Fan = Vec_IntEntry(vFans, 4); + //Fan = Vec_IntEntry(vFans, 4); + + //printf("fan3: %s\n",Fan); + //printf("fan0: %s\n",Smt_VecEntryName(p, vFans3, 0)); + //printf("fan1: %s\n",Smt_VecEntryName(p, vFans3, 1)); + //printf("fan2: %s\n",Smt_VecEntryName(p, vFans3, 2)); + //printf("fan3: %s\n",Smt_VecEntryName(p, vFans3, 3)); + Status = Smt_PrsBuildNode( pNtk, p, Fan, Range, pName ); } if ( !Status ) @@ -1312,6 +1389,57 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) goto finish; } } + */ + // added: new way to parse define-fun + // create constants + else if ( Abc_Lit2Var(Fan) == SMT_PRS_DEFINE_FUN ) + { + char * pName_glb; + // (define-fun def_16001 () Bool (or def_15999 def_16000)) + // (define-fun def_15990 () (_ BitVec 24) (concat def_15988 def_15989)) + assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_DEFINE_FUN) ); + assert( Vec_IntSize(vFans) == 5 ); // const or definition + + // get name + Fan = Vec_IntEntry(vFans, 1); + assert( Smt_EntryIsName(Fan) ); + pName = Smt_EntryName(p, Fan); + // added: giving a global suffix + pName_glb = (char *) malloc(strlen(pName) + 4 + 1); + strcpy(pName_glb,pName); + strcat(pName_glb,"_glb"); + // FIXME: delete memory of pName + pName = pName_glb; + + //get range + Fan = Vec_IntEntry(vFans, 3); + if ( Smt_EntryIsName(Fan) ) + { + // (define-fun s_2 () Bool false) + assert( !strcmp("Bool", Smt_VecEntryName(p, vFans, 3)) ); + Range = 1; + } + else + { + // (define-fun s702 () (_ BitVec 4) #xe) + // (define-fun s1 () (_ BitVec 8) (bvneg #x7f)) + assert( !Smt_EntryIsName(Fan) ); + vFans2 = Smt_VecEntryNode(p, vFans, 3); + assert( Vec_IntSize(vFans2) == 3 ); + assert( !strcmp("_", Smt_VecEntryName(p, vFans2, 0)) ); + assert( !strcmp("BitVec", Smt_VecEntryName(p, vFans2, 1)) ); + // get range + Fan = Vec_IntEntry(vFans2, 2); + assert( Smt_EntryIsName(Fan) ); + pRange = Smt_EntryName(p, Fan); + Range = atoi(pRange); + } + + iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 4), Range, pName ); + assert( iObj ); + ABC_FREE( pName_glb ); + } + // collect assertion outputs else if ( Abc_Lit2Var(Fan) == SMT_PRS_ASSERT ) { @@ -1321,6 +1449,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) //(assert (not (= s0 #x00))) assert( Vec_IntSize(vFans) == 2 ); assert( Smt_VecEntryIsType(vFans, 0, SMT_PRS_ASSERT) ); + pNtk->nAssert++; // added iObj = Smt_PrsBuild2_rec( pNtk, p, Vec_IntEntry(vFans, 1), -1, NULL ); if ( iObj == 0 ) { @@ -1336,6 +1465,9 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // build AND of asserts if ( Vec_IntSize(vAsserts) == 1 ) iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BUF, 0, 1, vAsserts, "miter" ); + // added: 0 asserts + else if ( Vec_IntSize(vAsserts) == 0 ) + iObj = Smt_PrsBuildConstant( pNtk, "#b1", 1, "miter" ); else { iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vAsserts), vAsserts, NULL ); @@ -1413,18 +1545,35 @@ static inline char * Smt_PrsLoadFile( char * pFileName, char ** ppLimit ) static inline int Smt_PrsRemoveComments( char * pBuffer, char * pLimit ) { char * pTemp; int nCount1 = 0, nCount2 = 0, fHaveBar = 0; + int backslash = 0; for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ ) { if ( *pTemp == '(' ) - nCount1++; + { if ( !fHaveBar ) nCount1++; } else if ( *pTemp == ')' ) - nCount2++; + { if ( !fHaveBar ) nCount2++; } else if ( *pTemp == '|' ) fHaveBar ^= 1; else if ( *pTemp == ';' && !fHaveBar ) while ( *pTemp && *pTemp != '\n' ) *pTemp++ = ' '; + // added: hack to remove quotes + else if ( *pTemp == '\"' && *(pTemp-1) != '\\' && !fHaveBar ) + { + *pTemp++ = ' '; + while ( *pTemp && (*pTemp != '\"' || backslash)) + { + if (*pTemp == '\\') + backslash = 1; + else + backslash = 0; + *pTemp++ = ' '; + } + // remove the last quote symbol + *pTemp = ' '; + } } + if ( nCount1 != nCount2 ) printf( "The input SMTLIB file has different number of opening and closing parentheses (%d and %d).\n", nCount1, nCount2 ); else if ( nCount1 == 0 ) @@ -1455,7 +1604,6 @@ static inline void Smt_PrsFree( Smt_Prs_t * p ) Vec_IntErase( &p->vStack ); Vec_IntErase( &p->vTempFans ); //Vec_WecErase( &p->vDepth ); - Vec_WecErase( &p->vObjs ); ABC_FREE( p ); } @@ -1499,6 +1647,15 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ ) { Smt_PrsSkipSpaces( p ); + if ( *p->pCur == '|' ) + { + *p->pCur = ' '; + while ( *p->pCur && *p->pCur != '|' ) + *p->pCur++ = ' '; + if ( *p->pCur == '|' ) + *p->pCur = ' '; + continue; + } if ( *p->pCur == '(' ) { // add new node at this depth @@ -1524,12 +1681,13 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) { // remove strange characters (this can lead to name clashes) int iToken; + /* commented out for SMT comp char * pTemp; if ( *pStart == '?' ) *pStart = '_'; for ( pTemp = pStart; pTemp < p->pCur; pTemp++ ) if ( *pTemp == '.' ) - *pTemp = '_'; + *pTemp = '_';*/ // create and save token for this string iToken = Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur--, NULL ); Vec_IntPush( Vec_WecEntry(&p->vObjs, Vec_IntEntryLast(&p->vStack)), Abc_Var2Lit(iToken, 1) ); -- cgit v1.2.3 From 7d82819d519595854c4e1b9dbf99d91e1d2ab9f9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 15:17:02 -0800 Subject: Adding visualization of word-level networks Wlc_Ntk_t. --- src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 12 +- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcCom.c | 116 ++++++++++++++++ src/base/wlc/wlcNtk.c | 162 ++++++++++++++++++++++- src/base/wlc/wlcReadVer.c | 2 +- src/base/wlc/wlcShow.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 617 insertions(+), 11 deletions(-) create mode 100644 src/base/wlc/wlcShow.c (limited to 'src/base') diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index 5a95a63f..ae7899ec 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -7,6 +7,7 @@ SRC += src/base/wlc/wlcAbs.c \ src/base/wlc/wlcReadSmt.c \ src/base/wlc/wlcReadVer.c \ src/base/wlc/wlcSim.c \ + src/base/wlc/wlcShow.c \ src/base/wlc/wlcStdin.c \ src/base/wlc/wlcWin.c \ src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 6f64b47a..e4a818e5 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -157,6 +157,7 @@ struct Wlc_Ntk_t_ Vec_Int_t vTravIds; // trav IDs of the objects Vec_Int_t vCopies; // object first bits Vec_Int_t vBits; // object mapping into AIG nodes + Vec_Int_t vLevels; // object levels }; static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } @@ -206,6 +207,8 @@ static inline int Wlc_ObjSign( Wlc_Obj_t * p ) static inline int * Wlc_ObjConstValue( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_CONST); return Wlc_ObjFanins(p); } static inline int Wlc_ObjTableId( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_TABLE); return p->Fanins[1]; } static inline word * Wlc_ObjTable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return (word *)Vec_PtrEntry( p->vTables, Wlc_ObjTableId(pObj) ); } +static inline int Wlc_ObjLevelId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vLevels, iObj ); } +static inline int Wlc_ObjLevel( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { return Wlc_ObjLevelId( p, Wlc_ObjId(p, pObj) ); } static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vCopies, p->nObjsAlloc, 0 ); } static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; } @@ -230,6 +233,8 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) #define Wlc_NtkForEachObj( p, pObj, i ) \ for ( i = 1; (i < Wlc_NtkObjNumMax(p)) && (((pObj) = Wlc_NtkObj(p, i)), 1); i++ ) +#define Wlc_NtkForEachObjReverse( p, pObj, i ) \ + for ( i = Wlc_NtkObjNumMax(p) - 1; (i > 0) && (((pObj) = Wlc_NtkObj(p, i)), 1); i-- ) #define Wlc_NtkForEachObjVec( vVec, p, pObj, i ) \ for ( i = 0; (i < Vec_IntSize(vVec)) && (((pObj) = Wlc_NtkObj(p, Vec_IntEntry(vVec, i))), 1); i++ ) #define Wlc_NtkForEachPi( p, pPi, i ) \ @@ -266,6 +271,7 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i /*=== wlcCom.c ========================================================*/ extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ +extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); extern int Wlc_ObjCreate( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg, Vec_Int_t * vFanins ); @@ -275,12 +281,16 @@ extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj ); extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type ); extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ); extern void Wlc_NtkFree( Wlc_Ntk_t * p ); +extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ); +extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ); extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ); extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray ); extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); +extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 73ff7328..368652d6 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p ); + pNew = Wlc_NtkDupDfs( p, 0 ); Wlc_NtkTransferNames( pNew, p ); return pNew; } @@ -278,7 +278,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p ); + pNew = Wlc_NtkDupDfs( p, 0 ); Wlc_NtkTransferNames( pNew, p ); return pNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 2828fea3..316d2883 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -31,8 +31,10 @@ ABC_NAMESPACE_IMPL_START static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -68,8 +70,10 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); @@ -332,6 +336,70 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, iOutput = -1, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Ovh" ) ) != EOF ) + { + switch ( c ) + { + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + iOutput = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( iOutput < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + if ( iOutput < 0 || iOutput >= Wlc_NtkPoNum(pNtk) ) + { + Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkPoNum(pNtk) ); + return 0; + } + printf( "Extracting output %d.\n", iOutput ); + Wlc_NtkMarkCone( pNtk, iOutput ); + pNtk = Wlc_NtkDupDfs( pNtk, 1 ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%cone [-O num] [-vh]\n" ); + Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); + Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] @@ -481,6 +549,54 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandShow( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold ); + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + // set defaults + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + Wlc_NtkShow( pNtk, NULL ); + return 0; + +usage: + Abc_Print( -2, "usage: %%show [-h]\n" ); + Abc_Print( -2, " visualizes the network structure using DOT and GSVIEW\n" ); +#ifdef WIN32 + Abc_Print( -2, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); + Abc_Print( -2, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); +#endif + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index a0799ba0..fa0074d3 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -88,6 +88,8 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { NULL // 54: unused }; +char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -224,6 +226,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vValues.pArray ); ABC_FREE( p->vCopies.pArray ); ABC_FREE( p->vBits.pArray ); + ABC_FREE( p->vLevels.pArray ); ABC_FREE( p->pInits ); ABC_FREE( p->pObjs ); ABC_FREE( p->pName ); @@ -244,6 +247,81 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p ) return Mem; } +/**Function************************************************************* + + Synopsis [Assigns object levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, k, iFanin, Level, LevelMax = 0; + Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObj( p, pObj, i ) + { + Level = 0; + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Level = Abc_MaxInt( Level, Wlc_ObjLevelId(p, iFanin) + 1 ); + Vec_IntWriteEntry( &p->vLevels, i, Level ); + LevelMax = Abc_MaxInt( LevelMax, Level ); + } + return LevelMax; +} +int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, k, iFanin, Level, LevelMax = 0; + Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObjReverse( p, pObj, i ) + { + if ( Wlc_ObjIsCi(pObj) ) + continue; + Level = Wlc_ObjLevel(p, pObj) + 1; + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Vec_IntUpdateEntry( &p->vLevels, iFanin, Level ); + LevelMax = Abc_MaxInt( LevelMax, Level ); + } + // reverse the values + Wlc_NtkForEachObj( p, pObj, i ) + Vec_IntWriteEntry( &p->vLevels, i, LevelMax - Wlc_ObjLevelId(p, i) ); + Wlc_NtkForEachCi( p, pObj, i ) + Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), 0 ); + return LevelMax; +} + +/**Function************************************************************* + + Synopsis [Collects statistics for each side of the miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) +{ + Wlc_Obj_t * pObj; + int n, i; + if ( Wlc_NtkPoNum(p) != 2 ) + return; + for ( n = 0; n < 2; n++ ) + { + Wlc_NtkMarkCone( p, n ); + Wlc_NtkForEachObj( p, pObj, i ) + if ( pObj->Mark ) + nObjs[n][pObj->Type]++; + } + Wlc_NtkCleanMarks( p ); +} + /**Function************************************************************* Synopsis [Prints distribution of operator types.] @@ -300,11 +378,13 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty } void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) { + int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0; Vec_Ptr_t * vTypes, * vOccurs; Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER ); word Sign; int i, k, s, s0, s1; + Wlc_NtkCollectStats( p, nObjs ); // allocate statistics arrays vTypes = Vec_PtrStart( WLC_OBJ_NUMBER ); vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER ); @@ -435,28 +515,40 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) else if ( pObj->Type == WLC_OBJ_ARI_SQUARE ) Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQUARE, 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) ); } - if ( nCountRange ) + if ( nCountRange && Vec_IntSize(&p->vNameIds) > 0 ) { printf( "Warning: %d objects of the design have non-zero-based ranges.\n", nCountRange ); printf( "In particular, object %6d with name \"%s\" has range %d=[%d:%d]\n", Wlc_ObjId(p, pObjRange), Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg ); } // print by occurrence - printf( "ID : name occurrence and2 (occurrence)=. ...\n" ); + printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", Wlc_NtkPoNum(p) == 2 ? " Left Share Right":"" ); for ( i = 0; i < WLC_OBJ_NUMBER; i++ ) { Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i ); Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, i ); if ( p->nObjs[i] == 0 ) continue; - printf( "%2d : %-8s %6d%8d ", i, Wlc_Names[i], p->nObjs[i], Vec_IntEntry(vAnds, i) ); + printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] ); + if ( Wlc_NtkPoNum(p) == 2 ) + { + printf( " " ); + printf( "%6d", nObjs[0][i] ); + printf( "%6d", nObjs[0][i]+nObjs[1][i]-p->nObjs[i] ); + printf( "%6d", nObjs[1][i] ); + } + printf( "%8d ", Vec_IntEntry(vAnds, i) ); // sort by occurence Wlc_NtkPrintDistribSortOne( vTypes, vOccurs, i ); Vec_WrdForEachEntry( vType, Sign, k ) { Wlc_NtkPrintDistribFromSign( Sign, &s, &s0, &s1 ); if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) ) + { printf( "\n " ); + if ( Wlc_NtkPoNum(p) == 2 ) + printf( " " ); + } printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) ); printf( "%s%d", Abc_LitIsCompl(s)?"-":"", Abc_Lit2Var(s) ); if ( s0 ) @@ -623,7 +715,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -634,11 +726,14 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p ) pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; Wlc_NtkForEachCi( p, pObj, i ) - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + if ( !fMarked || pObj->Mark ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + if ( !fMarked || pObj->Mark ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); + if ( !fMarked || pObj->Mark ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); if ( p->vInits ) pNew->vInits = Vec_IntDup( p->vInits ); if ( p->pInits ) @@ -666,6 +761,59 @@ void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) pNew->vTables = p->vTables; p->vTables = NULL; } +/**Function************************************************************* + + Synopsis [Select the cone of the given output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i; + Wlc_NtkForEachObj( p, pObj, i ) + pObj->Mark = 0; +} +void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Wlc_ObjIsCi(pObj) ) + { + if ( !Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); +} +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) +{ + Vec_Int_t * vFlops; + Wlc_Obj_t * pObj; + int i, CiId, CoId; + Wlc_NtkCleanMarks( p ); + Wlc_NtkForEachPi( p, pObj, i ) + pObj->Mark = 1; + vFlops = Vec_IntAlloc( 100 ); + Wlc_NtkForEachPo( p, pObj, i ) + if ( i == iPo ) + Wlc_NtkMarkCone_rec( p, pObj, vFlops ); + Vec_IntForEachEntry( vFlops, CiId, i ) + { + CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); + Wlc_NtkMarkCone_rec( p, Wlc_NtkCo(p, CoId), vFlops ); + } + Vec_IntFree( vFlops ); +} + /**Function************************************************************* Synopsis [Duplicates the network by copying each node.] diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index fa3efacd..2959f4a1 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0 ); Wlc_NtkTransferNames( pNtk, p->pNtk ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c new file mode 100644 index 00000000..dd25c7a3 --- /dev/null +++ b/src/base/wlc/wlcShow.c @@ -0,0 +1,331 @@ +/**CFile**************************************************************** + + FileName [wlcShow.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Parses several flavors of word-level Verilog.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcShow.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Writes the graph structure of WLC for DOT.] + + Description [Useful for graph visualization using tools such as GraphViz: + http://www.graphviz.org/] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) +{ + FILE * pFile; + Wlc_Obj_t * pNode; + int LevelMax, Prev, Level, i; + + if ( Wlc_NtkObjNum(p) > 500 ) + { + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 500 ); + return; + } + if ( (pFile = fopen( pFileName, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); + return; + } + + // mark the nodes + if ( vBold ) + Wlc_NtkForEachObjVec( vBold, p, pNode, i ) + pNode->Mark = 1; + + // compute levels + LevelMax = 1 + Wlc_NtkCreateLevelsRev( p ); + + // write the DOT header + fprintf( pFile, "# %s\n", "WLC structure generated by ABC" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "digraph WLC {\n" ); + fprintf( pFile, "size = \"7.5,10\";\n" ); +// fprintf( pFile, "ranksep = 0.5;\n" ); +// fprintf( pFile, "nodesep = 0.5;\n" ); + fprintf( pFile, "center = true;\n" ); +// fprintf( pFile, "orientation = landscape;\n" ); +// fprintf( pFile, "edge [fontsize = 10];\n" ); +// fprintf( pFile, "edge [dir = none];\n" ); + fprintf( pFile, "edge [dir = back];\n" ); + fprintf( pFile, "\n" ); + + // labels on the left of the picture + fprintf( pFile, "{\n" ); + fprintf( pFile, " node [shape = plaintext];\n" ); + fprintf( pFile, " edge [style = invis];\n" ); + fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); + fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); + // generate node names with labels + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + fprintf( pFile, " [label = " ); + // label name + fprintf( pFile, "\"" ); + fprintf( pFile, "\"" ); + fprintf( pFile, "];\n" ); + } + + // genetate the sequence of visible/invisible nodes to mark levels + fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); + for ( Level = LevelMax; Level >= 0; Level-- ) + { + // the visible node name + fprintf( pFile, " Level%d", Level ); + // the connector + if ( Level != 0 ) + fprintf( pFile, " ->" ); + else + fprintf( pFile, ";" ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate title box on top + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle1;\n" ); + fprintf( pFile, " title1 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=20,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "%s", "WLC structure generated by ABC" ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "Benchmark \\\"%s\\\". ", p->pName ); +// fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate statistics box + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + fprintf( pFile, " LevelTitle2;\n" ); + fprintf( pFile, " title2 [shape=plaintext,\n" ); + fprintf( pFile, " fontsize=18,\n" ); + fprintf( pFile, " fontname = \"Times-Roman\",\n" ); + fprintf( pFile, " label=\"" ); + fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkPiNum(p)-Wlc_NtkPoNum(p)-Wlc_NtkFfNum(p), LevelMax-1 ); + fprintf( pFile, "\\n" ); + fprintf( pFile, "\"\n" ); + fprintf( pFile, " ];\n" ); + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate the COs + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", LevelMax ); + // generate the CO nodes + Wlc_NtkForEachCo( p, pNode, i ) + { + fprintf( pFile, " NodePo%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", "invtriangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate nodes of each rank + for ( Level = LevelMax - 1; Level > 0; Level-- ) + { + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", Level ); + Wlc_NtkForEachObj( p, pNode, i ) + { + if ( (int)Wlc_ObjLevel(p, pNode) != Level ) + continue; + + if ( pNode->Type == WLC_OBJ_CONST ) + { + fprintf( pFile, " Node%d [label = \"0x", i ); + Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 ); + fprintf( pFile, "\"" ); + } + else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_MUX ) + fprintf( pFile, " Node%d [label = \"%d\"", i, Wlc_ObjRange(pNode) ); + else if ( pNode->Type >= WLC_OBJ_LOGIC_NOT && pNode->Type <= WLC_OBJ_COMP_MOREEQU ) + fprintf( pFile, " Node%d [label = \"%s\"", i, Wlc_ObjTypeName(pNode) ); + else + fprintf( pFile, " Node%d [label = \"%s %d\"", i, Wlc_ObjTypeName(pNode), Wlc_ObjRange(pNode) ); + + if ( pNode->Type == WLC_OBJ_ARI_MULTI ) + fprintf( pFile, ", shape = doublecircle" ); + else if ( pNode->Type >= WLC_OBJ_COMP_EQU && pNode->Type <= WLC_OBJ_COMP_MOREEQU ) + fprintf( pFile, ", shape = diamond" ); + else if ( pNode->Type == WLC_OBJ_BIT_SELECT || pNode->Type == WLC_OBJ_BIT_CONCAT ) + fprintf( pFile, ", shape = box" ); + else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_BIT_ZEROPAD || pNode->Type == WLC_OBJ_BIT_SIGNEXT ) + fprintf( pFile, ", shape = triangle" ); + else if ( pNode->Type == WLC_OBJ_MUX ) + fprintf( pFile, ", shape = trapezium" ); + else + fprintf( pFile, ", shape = ellipse" ); + + if ( vBold ? pNode->Mark : ((pNode->Type >= WLC_OBJ_ARI_ADD && pNode->Type <= WLC_OBJ_ARI_SQUARE) || pNode->Type == WLC_OBJ_BIT_NOT) ) + fprintf( pFile, ", style = filled" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + } + + // generate the CI nodes + fprintf( pFile, "{\n" ); + fprintf( pFile, " rank = same;\n" ); + // the labeling node of this level + fprintf( pFile, " Level%d;\n", 0 ); + // generate the CI nodes + Wlc_NtkForEachCi( p, pNode, i ) + { + fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", color = coral, fillcolor = coral" ); + fprintf( pFile, "];\n" ); + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + + // generate invisible edges from the square down + fprintf( pFile, "title1 -> title2 [style = invis];\n" ); + Wlc_NtkForEachCo( p, pNode, i ) + fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) ); + // generate invisible edges among the COs + Prev = -1; + Wlc_NtkForEachCo( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); + Prev = Wlc_ObjId(p, pNode); + } + // generate invisible edges among the CIs + Prev = -1; + Wlc_NtkForEachCi( p, pNode, i ) + { + if ( i > 0 ) + fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); + Prev = Wlc_ObjId(p, pNode); + } + + // generate edges + Wlc_NtkForEachObj( p, pNode, i ) + { + int k, iFanin; + if ( Wlc_ObjIsCi(pNode) ) + continue; + if ( Wlc_ObjIsCo(pNode) ) + { + // generate the edge from this node to the next + fprintf( pFile, "NodePo%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + // generate the edge from this node to the next + Wlc_ObjForEachFanin( pNode, iFanin, k ) + { + fprintf( pFile, "Node%d", i ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", iFanin ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + } + fprintf( pFile, "}" ); + fprintf( pFile, "\n" ); + fprintf( pFile, "\n" ); + fclose( pFile ); + + // unmark nodes + if ( vBold ) + Wlc_NtkCleanMarks( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold ) +{ + extern void Abc_ShowFile( char * FileNameDot ); + FILE * pFile; + char FileNameDot[200]; + sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(p->pName, ".dot") ); + // check that the file can be opened + if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot ); + return; + } + fclose( pFile ); + // generate the file + Wlc_NtkDumpDot( p, FileNameDot, vBold ); + // visualize the file + Abc_ShowFile( FileNameDot ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3 From 64d7119ddc7fb1720542b8071f490763466a5d31 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 21:43:28 -0800 Subject: Adding visualization of word-level networks Wlc_Ntk_t. --- src/base/wlc/wlc.h | 13 ++- src/base/wlc/wlcAbs.c | 6 +- src/base/wlc/wlcCom.c | 156 ++++++++++++++++++++++--------- src/base/wlc/wlcNtk.c | 226 ++++++++++++++++++++++++++++++++++++--------- src/base/wlc/wlcReadVer.c | 5 +- src/base/wlc/wlcShow.c | 38 ++++---- src/base/wlc/wlcWriteVer.c | 2 +- 7 files changed, 331 insertions(+), 115 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index e4a818e5..b898078f 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -221,7 +221,8 @@ static inline int Wlc_NtkHasNameId( Wlc_Ntk_t * p ) static inline void Wlc_ObjSetNameId( Wlc_Ntk_t * p, int iObj, int i ) { Vec_IntWriteEntry( &p->vNameIds, iObj, i ); } static inline int Wlc_ObjNameId( Wlc_Ntk_t * p, int iObj ) { return Vec_IntEntry( &p->vNameIds, iObj ); } -static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkCoNum(p) - Wlc_NtkCiNum(p) + Wlc_ObjCiId(pObj)); } +static inline Wlc_Obj_t * Wlc_ObjFo2Fi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) { assert( pObj->Type == WLC_OBJ_FO ); return Wlc_NtkCo(p, Wlc_NtkPoNum(p) + Wlc_ObjCiId(pObj) - Wlc_NtkPiNum(p)); } +static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) { return iCoId < Wlc_NtkPoNum(p) ? Wlc_NtkPo(p, iCoId) : Wlc_NtkCi(p, Wlc_NtkPiNum(p) + iCoId - Wlc_NtkPoNum(p)); } //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// @@ -283,15 +284,19 @@ extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int extern void Wlc_NtkFree( Wlc_Ntk_t * p ); extern int Wlc_NtkCreateLevels( Wlc_Ntk_t * p ); extern int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p ); +extern int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ); extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ); extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray ); extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); -extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ); +extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); +extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); -extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); +extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 368652d6..ce6b8de9 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,8 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0 ); - Wlc_NtkTransferNames( pNew, p ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } @@ -278,8 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0 ); - Wlc_NtkTransferNames( pNew, p ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 316d2883..9f36ad56 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -28,21 +28,22 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandInvPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvGet ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } @@ -67,21 +68,22 @@ static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) ******************************************************************************/ void Wlc_Init( Abc_Frame_t * pAbc ) { - Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); - - Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); + + Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_get", Abc_CommandInvGet, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_put", Abc_CommandInvPut, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_min", Abc_CommandInvMin, 0 ); } /**Function******************************************************************** @@ -287,15 +289,20 @@ usage: int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int fShowCones = 0; int fShowMulti = 0; int fShowAdder = 0; int fDistrib = 0; + int fTwoSides = 0; int c, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "madvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "cmadtvh" ) ) != EOF ) { switch ( c ) { + case 'c': + fShowCones ^= 1; + break; case 'm': fShowMulti ^= 1; break; @@ -305,6 +312,9 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'd': fDistrib ^= 1; break; + case 't': + fTwoSides ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -319,19 +329,23 @@ int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandPs(): There is no current design.\n" ); return 0; } - Wlc_NtkPrintStats( pNtk, fDistrib, fVerbose ); + Wlc_NtkPrintStats( pNtk, fDistrib, fTwoSides, fVerbose ); + if ( fShowCones ) + Wlc_NtkProfileCones( pNtk ); if ( fShowMulti ) Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_MULTI ); if ( fShowAdder ) Wlc_NtkPrintNodes( pNtk, WLC_OBJ_ARI_ADD ); return 0; usage: - Abc_Print( -2, "usage: %%ps [-madvh]\n" ); + Abc_Print( -2, "usage: %%ps [-cmadtvh]\n" ); Abc_Print( -2, "\t prints statistics\n" ); - Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" ); - Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" ); - Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle printing cones [default = %s]\n", fShowCones? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" ); + Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle printing stats for LHS and RHS [default = %s]\n", fTwoSides? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -350,9 +364,10 @@ usage: int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, iOutput = -1, fVerbose = 0; + int c, iOutput = -1, fSeq = 0, fVerbose = 0; + char * pName; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Ovh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Osvh" ) ) != EOF ) { switch ( c ) { @@ -367,6 +382,9 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( iOutput < 0 ) goto usage; break; + case 's': + fSeq ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -381,20 +399,24 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - if ( iOutput < 0 || iOutput >= Wlc_NtkPoNum(pNtk) ) + if ( iOutput < 0 || iOutput >= Wlc_NtkCoNum(pNtk) ) { - Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkPoNum(pNtk) ); + Abc_Print( 1, "Abc_CommandCone(): Illegal output index (%d) (should be 0 <= num < %d).\n", iOutput, Wlc_NtkCoNum(pNtk) ); return 0; } - printf( "Extracting output %d.\n", iOutput ); - Wlc_NtkMarkCone( pNtk, iOutput ); - pNtk = Wlc_NtkDupDfs( pNtk, 1 ); + printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); + pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); + Wlc_NtkMarkCone( pNtk, iOutput, fSeq ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); + ABC_FREE( pNtk->pName ); + pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); return 0; usage: - Abc_Print( -2, "usage: %%cone [-O num] [-vh]\n" ); + Abc_Print( -2, "usage: %%cone [-O num] [-svh]\n" ); Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-s : toggle performing extracting sequential cones [default = %s]\n", fSeq? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -549,6 +571,50 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + 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 ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" ); + return 0; + } + Wlc_NtkShortNames( pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%short_names [-vh]\n" ); + Abc_Print( -2, "\t derives short names for all objects of the network\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index fa0074d3..822c2eb5 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -314,13 +314,23 @@ void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) return; for ( n = 0; n < 2; n++ ) { - Wlc_NtkMarkCone( p, n ); + Wlc_NtkMarkCone( p, n, 1 ); Wlc_NtkForEachObj( p, pObj, i ) if ( pObj->Mark ) nObjs[n][pObj->Type]++; } Wlc_NtkCleanMarks( p ); } +int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, Count = 0; + Wlc_NtkMarkCone( p, -1, 1 ); + Wlc_NtkForEachPi( p, pObj, i ) + Count += pObj->Mark; + Wlc_NtkCleanMarks( p ); + return Count; +} /**Function************************************************************* @@ -376,7 +386,7 @@ void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Ty Vec_WrdReverseOrder( vType ); Vec_WrdReverseOrder( vOccur ); } -void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) +void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fTwoSides, int fVerbose ) { int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0; @@ -384,7 +394,10 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER ); word Sign; int i, k, s, s0, s1; - Wlc_NtkCollectStats( p, nObjs ); + if ( Wlc_NtkPoNum(p) != 2 ) + fTwoSides = 0; + if ( fTwoSides ) + Wlc_NtkCollectStats( p, nObjs ); // allocate statistics arrays vTypes = Vec_PtrStart( WLC_OBJ_NUMBER ); vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER ); @@ -489,11 +502,11 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) else if ( pObj->Type == WLC_OBJ_REDUCT_XOR ) Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_XOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NAND ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NOR ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR, Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 ); else if ( pObj->Type == WLC_OBJ_REDUCT_NXOR ) - Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); + Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 ); else if ( pObj->Type == WLC_OBJ_ARI_ADD ) Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_ADD, 9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) ); else if ( pObj->Type == WLC_OBJ_ARI_SUB ) @@ -522,7 +535,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg ); } // print by occurrence - printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", Wlc_NtkPoNum(p) == 2 ? " Left Share Right":"" ); + printf( "ID : name occurrence%s and2 (occurrence)=. ...\n", fTwoSides ? " Left Share Right":"" ); for ( i = 0; i < WLC_OBJ_NUMBER; i++ ) { Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i ); @@ -530,11 +543,12 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) if ( p->nObjs[i] == 0 ) continue; printf( "%2d : %-8s %6d", i, Wlc_Names[i], p->nObjs[i] ); - if ( Wlc_NtkPoNum(p) == 2 ) + if ( fTwoSides ) { + int nTotal = i == WLC_OBJ_PI ? Wlc_NtkCountRealPis(p) : p->nObjs[i]; printf( " " ); printf( "%6d", nObjs[0][i] ); - printf( "%6d", nObjs[0][i]+nObjs[1][i]-p->nObjs[i] ); + printf( "%6d", nObjs[0][i]+nObjs[1][i]-nTotal ); printf( "%6d", nObjs[1][i] ); } printf( "%8d ", Vec_IntEntry(vAnds, i) ); @@ -546,7 +560,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose ) if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) ) { printf( "\n " ); - if ( Wlc_NtkPoNum(p) == 2 ) + if ( fTwoSides ) printf( " " ); } printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) ); @@ -627,11 +641,11 @@ void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ) Wlc_NtkPrintNode( p, pObj ); } } -void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) +void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ) { int i; printf( "%-20s : ", p->pName ); - printf( "PI = %4d ", Wlc_NtkPiNum(p) ); + printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) ); printf( "PO = %4d ", Wlc_NtkPoNum(p) ); printf( "FF = %4d ", Wlc_NtkFfNum(p) ); printf( "Obj = %6d ", Wlc_NtkObjNum(p) ); @@ -639,7 +653,7 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) printf( "\n" ); if ( fDistrib ) { - Wlc_NtkPrintDistrib( p, fVerbose ); + Wlc_NtkPrintDistrib( p, fTwoSides, fVerbose ); return; } if ( !fVerbose ) @@ -656,6 +670,41 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose ) } } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) +{ + int i; + assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) ); + assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) ); + assert( pNew->pManName == NULL && p->pManName != NULL ); + Wlc_NtkCleanNameId( pNew ); + for ( i = 0; i < p->nObjsAlloc; i++ ) + if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) ) + Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) ); + pNew->pManName = p->pManName; + p->pManName = NULL; + Vec_IntErase( &p->vNameIds ); + // transfer table + pNew->pMemTable = p->pMemTable; p->pMemTable = NULL; + pNew->vTables = p->vTables; p->vTables = NULL; +} +char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ) +{ + static char pBuffer[1000]; + sprintf( pBuffer, "%s_o%d_%s", p->pName, iCoId, fSeq ? "seq": "comb" ); + return pBuffer; +} + /**Function************************************************************* Synopsis [Duplicates the network in a topological order.] @@ -715,51 +764,43 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; Vec_Int_t * vFanins; int i; - Wlc_NtkCleanCopy( p ); vFanins = Vec_IntAlloc( 100 ); + Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; Wlc_NtkForEachCi( p, pObj, i ) if ( !fMarked || pObj->Mark ) + { + unsigned Type = pObj->Type; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) - Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); - if ( p->vInits ) - pNew->vInits = Vec_IntDup( p->vInits ); - if ( p->pInits ) - pNew->pInits = Abc_UtilStrsav( p->pInits ); + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); Vec_IntFree( vFanins ); + if ( !fMarked ) + { + if ( p->vInits ) + pNew->vInits = Vec_IntDup( p->vInits ); + if ( p->pInits ) + pNew->pInits = Abc_UtilStrsav( p->pInits ); + } if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Wlc_NtkTransferNames( pNew, p ); return pNew; } -void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) -{ - int i; - assert( !Wlc_NtkHasCopy(pNew) && Wlc_NtkHasCopy(p) ); - assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) ); - assert( pNew->pManName == NULL && p->pManName != NULL ); - Wlc_NtkCleanNameId( pNew ); - for ( i = 0; i < p->nObjsAlloc; i++ ) - if ( Wlc_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) ) - Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) ); - pNew->pManName = p->pManName; - p->pManName = NULL; - Vec_IntErase( &p->vNameIds ); - // transfer table - pNew->pMemTable = p->pMemTable; p->pMemTable = NULL; - pNew->vTables = p->vTables; p->vTables = NULL; -} /**Function************************************************************* @@ -779,6 +820,30 @@ void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ) Wlc_NtkForEachObj( p, pObj, i ) pObj->Mark = 0; } +int Wlc_NtkCountMarked( Wlc_Ntk_t * p, int * pnPis, int * pnFos, int * pnAdders, int * pnMults ) +{ + Wlc_Obj_t * pObj; + int i, nNodes = 0; + *pnPis = *pnFos = *pnAdders = *pnMults = 0; + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( !pObj->Mark ) + continue; + if ( Wlc_ObjIsPi(pObj) ) + (*pnPis)++; + else if ( Wlc_ObjIsCi(pObj) ) + (*pnFos)++; + else if ( pObj->Mark ) + { + nNodes++; + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB ) + (*pnAdders)++; + else if ( pObj->Type == WLC_OBJ_ARI_MULTI ) + (*pnMults)++; + } + } + return nNodes; +} void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) { int i, iFanin; @@ -794,18 +859,19 @@ void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); } -void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ) { Vec_Int_t * vFlops; Wlc_Obj_t * pObj; int i, CiId, CoId; Wlc_NtkCleanMarks( p ); - Wlc_NtkForEachPi( p, pObj, i ) - pObj->Mark = 1; +// Wlc_NtkForEachPi( p, pObj, i ) +// pObj->Mark = 1; vFlops = Vec_IntAlloc( 100 ); - Wlc_NtkForEachPo( p, pObj, i ) - if ( i == iPo ) + Wlc_NtkForEachCo( p, pObj, i ) + if ( iCoId == -1 || i == iCoId ) Wlc_NtkMarkCone_rec( p, pObj, vFlops ); + if ( fSeq ) Vec_IntForEachEntry( vFlops, CiId, i ) { CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); @@ -813,6 +879,24 @@ void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iPo ) } Vec_IntFree( vFlops ); } +void Wlc_NtkProfileCones( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + int i, nPis, nFos, nNodes, nAdders, nMults; + Wlc_NtkForEachCo( p, pObj, i ) + { + Wlc_NtkMarkCone( p, i, 0 ); + nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults ); + printf( "Cone %5d : ", i ); + printf( "PI = %4d ", nPis ); + printf( "FO = %4d ", nFos ); + printf( "Node = %6d ", nNodes ); + printf( "Add/Sub = %4d ", nAdders ); + printf( "Mult = %4d ", nMults ); + printf( "\n" ); + } + Wlc_NtkCleanMarks( p ); +} /**Function************************************************************* @@ -871,6 +955,64 @@ Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [Creates short names for all objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkShortNames( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; + char pBuffer[100]; + int nDigits, NameId, fFound, i; + int nFlops = Wlc_NtkCoNum(p) - Wlc_NtkPoNum(p); + nDigits = Abc_Base10Log( nFlops ); + Wlc_NtkForEachCo( p, pObj, i ) + { + if ( Wlc_ObjIsPo(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "fi", nDigits, i - Wlc_NtkPoNum(p) ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + Wlc_NtkForEachCi( p, pObj, i ) + { + if ( Wlc_ObjIsPi(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "fo", nDigits, i - Wlc_NtkPiNum(p) ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkPoNum(p) ); + Wlc_NtkForEachPo( p, pObj, i ) + { + sprintf( pBuffer, "%s%0*d", "po", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkPiNum(p) ); + Wlc_NtkForEachPi( p, pObj, i ) + { + sprintf( pBuffer, "%s%0*d", "pi", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } + nDigits = Abc_Base10Log( Wlc_NtkObjNum(p) ); + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( Wlc_ObjIsCi(pObj) || Wlc_ObjIsCo(pObj) ) + continue; + sprintf( pBuffer, "%s%0*d", "n", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound ); + Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId ); + } +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 2959f4a1..e4a65ecf 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -28,7 +28,7 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// // Word-level Verilog file parser -#define WLV_PRS_MAX_LINE 1000 +#define WLV_PRS_MAX_LINE 10000 typedef struct Wlc_Prs_t_ Wlc_Prs_t; struct Wlc_Prs_t_ @@ -1265,8 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0 ); - Wlc_NtkTransferNames( pNtk, p->pNtk ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index dd25c7a3..8ef21d29 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -143,7 +143,7 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkPiNum(p)-Wlc_NtkPoNum(p)-Wlc_NtkFfNum(p), LevelMax-1 ); + fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkCiNum(p), LevelMax-1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -159,8 +159,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) // generate the CO nodes Wlc_NtkForEachCo( p, pNode, i ) { - fprintf( pFile, " NodePo%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); - fprintf( pFile, ", shape = %s", "invtriangle" ); + pNode = Wlc_ObjCo2PoFo(p, i); + fprintf( pFile, " NodePo%d [label = \"%s_in %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); + fprintf( pFile, ", shape = %s", i < Wlc_NtkPoNum(p) ? "invtriangle" : "box" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } @@ -224,7 +225,7 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_NtkForEachCi( p, pNode, i ) { fprintf( pFile, " Node%d [label = \"%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) ); - fprintf( pFile, ", shape = %s", "triangle" ); + fprintf( pFile, ", shape = %s", i < Wlc_NtkPiNum(p) ? "triangle" : "box" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } @@ -235,11 +236,15 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) // generate invisible edges from the square down fprintf( pFile, "title1 -> title2 [style = invis];\n" ); Wlc_NtkForEachCo( p, pNode, i ) + { + pNode = Wlc_ObjCo2PoFo( p, i ); fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) ); + } // generate invisible edges among the COs Prev = -1; Wlc_NtkForEachCo( p, pNode, i ) { + pNode = Wlc_ObjCo2PoFo( p, i ); if ( i > 0 ) fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) ); Prev = Wlc_ObjId(p, pNode); @@ -254,22 +259,21 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) } // generate edges + Wlc_NtkForEachCo( p, pNode, i ) + { + fprintf( pFile, "NodePo%d", Wlc_ObjId(p, Wlc_ObjCo2PoFo(p, i)) ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d", Wlc_ObjId(p, pNode) ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "solid" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } Wlc_NtkForEachObj( p, pNode, i ) { int k, iFanin; if ( Wlc_ObjIsCi(pNode) ) continue; - if ( Wlc_ObjIsCo(pNode) ) - { - // generate the edge from this node to the next - fprintf( pFile, "NodePo%d", i ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", i ); - fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "bold" ); - fprintf( pFile, "]" ); - fprintf( pFile, ";\n" ); - } // generate the edge from this node to the next Wlc_ObjForEachFanin( pNode, iFanin, k ) { @@ -277,7 +281,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", iFanin ); fprintf( pFile, " [" ); - fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "bold" ); + fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "solid" ); + if ( pNode->Type == WLC_OBJ_MUX && k == 0 ) + fprintf( pFile, ", style = %s", "bold" ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index cf0e528f..c4dee094 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -409,7 +409,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, " reg%d (", i ); fprintf( pFile, " .q( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) ); fprintf( pFile, " .qbar()," ); - fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFoToFi(p, pObj))) ); + fprintf( pFile, " .d( %s ),", Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj))) ); fprintf( pFile, " .clk( %s ),", "1\'b0" ); fprintf( pFile, " .arst( %s ),", "1\'b0" ); if ( p->vInits ) -- cgit v1.2.3 From c2b805dc85fa3c6e96cac04fa1d8ea182e9aab62 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 26 Jan 2017 22:22:22 -0800 Subject: Adding visualization of word-level networks Wlc_Ntk_t. --- src/base/wlc/wlc.h | 2 +- src/base/wlc/wlcCom.c | 28 ++++++++++++++++++++++------ src/base/wlc/wlcNtk.c | 15 ++++++++------- 3 files changed, 31 insertions(+), 14 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index b898078f..d51b699c 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -293,7 +293,7 @@ extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); -extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ); +extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 9f36ad56..82321d3b 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -364,10 +364,10 @@ usage: int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, iOutput = -1, fSeq = 0, fVerbose = 0; + int c, iOutput = -1, Range = 1, fAllPis = 0, fSeq = 0, fVerbose = 0; char * pName; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Osvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORisvh" ) ) != EOF ) { switch ( c ) { @@ -382,6 +382,20 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( iOutput < 0 ) goto usage; break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); + goto usage; + } + Range = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Range < 0 ) + goto usage; + break; + case 'i': + fAllPis ^= 1; + break; case 's': fSeq ^= 1; break; @@ -406,16 +420,18 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) } printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); - Wlc_NtkMarkCone( pNtk, iOutput, fSeq ); + Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); return 0; usage: - Abc_Print( -2, "usage: %%cone [-O num] [-svh]\n" ); - Abc_Print( -2, "\t extracts cone of the given word-level output\n" ); - Abc_Print( -2, "\t-O num : zero-based index of the word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "usage: %%cone [-OR num] [-isvh]\n" ); + Abc_Print( -2, "\t extracts logic cone of one or more word-level outputs\n" ); + Abc_Print( -2, "\t-O num : zero-based index of the first word-level output to extract [default = %d]\n", iOutput ); + Abc_Print( -2, "\t-R num : total number of word-level outputs to extract [default = %d]\n", Range ); + Abc_Print( -2, "\t-i : toggle using support composed of all primary inputs [default = %s]\n", fAllPis? "yes": "no" ); Abc_Print( -2, "\t-s : toggle performing extracting sequential cones [default = %s]\n", fSeq? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 822c2eb5..bd00a570 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -314,7 +314,7 @@ void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] ) return; for ( n = 0; n < 2; n++ ) { - Wlc_NtkMarkCone( p, n, 1 ); + Wlc_NtkMarkCone( p, n, 1, 1, 0 ); Wlc_NtkForEachObj( p, pObj, i ) if ( pObj->Mark ) nObjs[n][pObj->Type]++; @@ -325,7 +325,7 @@ int Wlc_NtkCountRealPis( Wlc_Ntk_t * p ) { Wlc_Obj_t * pObj; int i, Count = 0; - Wlc_NtkMarkCone( p, -1, 1 ); + Wlc_NtkMarkCone( p, -1, -1, 1, 0 ); Wlc_NtkForEachPi( p, pObj, i ) Count += pObj->Mark; Wlc_NtkCleanMarks( p ); @@ -859,17 +859,18 @@ void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops ) Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops ); } -void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int fSeq ) +void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ) { Vec_Int_t * vFlops; Wlc_Obj_t * pObj; int i, CiId, CoId; Wlc_NtkCleanMarks( p ); -// Wlc_NtkForEachPi( p, pObj, i ) -// pObj->Mark = 1; + if ( fAllPis ) + Wlc_NtkForEachPi( p, pObj, i ) + pObj->Mark = 1; vFlops = Vec_IntAlloc( 100 ); Wlc_NtkForEachCo( p, pObj, i ) - if ( iCoId == -1 || i == iCoId ) + if ( iCoId == -1 || (i >= iCoId && i < iCoId + Range) ) Wlc_NtkMarkCone_rec( p, pObj, vFlops ); if ( fSeq ) Vec_IntForEachEntry( vFlops, CiId, i ) @@ -885,7 +886,7 @@ void Wlc_NtkProfileCones( Wlc_Ntk_t * p ) int i, nPis, nFos, nNodes, nAdders, nMults; Wlc_NtkForEachCo( p, pObj, i ) { - Wlc_NtkMarkCone( p, i, 0 ); + Wlc_NtkMarkCone( p, i, 1, 0, 0 ); nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults ); printf( "Cone %5d : ", i ); printf( "PI = %4d ", nPis ); -- cgit v1.2.3 From f701a0c659c57b8aa452bed93143a45cf5dcfeb8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 27 Jan 2017 10:48:56 -0800 Subject: Commenting out &mfs report message. --- src/base/wlc/wlcShow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index 8ef21d29..7914cd7a 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -49,9 +49,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_Obj_t * pNode; int LevelMax, Prev, Level, i; - if ( Wlc_NtkObjNum(p) > 500 ) + if ( Wlc_NtkObjNum(p) > 1000 ) { - fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 500 ); + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 1000 ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) -- cgit v1.2.3 From e9566a1e3db178a6111d227439354fcbb935ffa7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 29 Jan 2017 13:37:29 -0800 Subject: Updates to arithmetic verification. --- src/base/wlc/wlcReadVer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/base') diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index e4a65ecf..16de4943 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -429,6 +429,7 @@ char * Wlc_PrsConvertInitValues( Wlc_Ntk_t * p ) Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); Vec_IntForEachEntry( p->vInits, Value, i ) { + char * pname = Wlc_ObjName( p, Value ); if ( Value < 0 ) { for ( k = 0; k < -Value; k++ ) -- cgit v1.2.3 From 3020d57ea67f7f897c93524b9c3025767db3933b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 29 Jan 2017 13:39:35 -0800 Subject: Commenting out debug code. --- src/base/wlc/wlcReadVer.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 16de4943..e4a65ecf 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -429,7 +429,6 @@ char * Wlc_PrsConvertInitValues( Wlc_Ntk_t * p ) Vec_Str_t * vStr = Vec_StrAlloc( 1000 ); Vec_IntForEachEntry( p->vInits, Value, i ) { - char * pname = Wlc_ObjName( p, Value ); if ( Value < 0 ) { for ( k = 0; k < -Value; k++ ) -- cgit v1.2.3 From e21c7d72f3f43f38e5af10a38602de6f6ce9a20e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 30 Jan 2017 08:39:26 -0800 Subject: Updates to arithmetic verification. --- src/base/io/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/io/io.c b/src/base/io/io.c index 093eccca..4cec0157 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2150,7 +2150,7 @@ int IoCommandWriteCnf2( Abc_Frame_t * pAbc, int argc, char **argv ) extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); FILE * pFile; char * pFileName; - int nLutSize = 6; + int nLutSize = 8; int fNewAlgo = 1; int fCnfObjIds = 0; int fAddOrCla = 1; -- cgit v1.2.3 From 452a19f70c692372ef694af7f00ea38bf546cf01 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 30 Jan 2017 18:30:59 -0800 Subject: Improvements to SMT-LIB parser (bug fixes). --- src/base/wlc/wlcReadSmt.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index 61d0bca8..69a01ab0 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -48,6 +48,9 @@ struct Smt_Prs_t_ char ErrorStr[1000]; }; +//#define SMT_GLO_SUFFIX "_glb" +#define SMT_GLO_SUFFIX "" + // parser name types typedef enum { SMT_PRS_NONE = 0, @@ -634,7 +637,10 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits if ( pStr[2+i] == '1' ) Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i ); else if ( pStr[2+i] != '0' ) + { + Vec_IntFree( vFanins ); return 0; + } } else if ( pStr[1] == 'x' ) // hexadecimal { @@ -643,9 +649,16 @@ static inline int Smt_PrsBuildConstant( Wlc_Ntk_t * pNtk, char * pStr, int nBits Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 ); if ( nDigits != (nBits + 3)/4 ) + { + Vec_IntFree( vFanins ); return 0; + } + } + else + { + Vec_IntFree( vFanins ); + return 0; } - else return 0; // create constant node iObj = Smt_PrsCreateNode( pNtk, WLC_OBJ_CONST, 0, nBits, vFanins, pName ); Vec_IntFree( vFanins ); @@ -1036,7 +1049,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, char * pStr_glb = (char *)malloc(strlen(pStr) + 4 +1); //glb char * pStr_loc = (char *)malloc(strlen(pStr) + strlen(suffix) +1); strcpy(pStr_glb,pStr); - strcat(pStr_glb,"_glb"); + strcat(pStr_glb,SMT_GLO_SUFFIX); strcpy(pStr_loc,pStr); strcat(pStr_loc,suffix); @@ -1105,7 +1118,7 @@ int Smt_PrsBuild2_rec( Wlc_Ntk_t * pNtk, Smt_Prs_t * p, int iNode, int iObjPrev, else { temp = (char *)malloc(strlen(pName2) + 4 + 1); strcpy(temp, pName2); - strcat(temp,"_glb"); + strcat(temp,SMT_GLO_SUFFIX); } // FIXME: need to delete memory of pName2 pName2 = temp; @@ -1273,7 +1286,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; // skip () @@ -1324,7 +1337,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix char * pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; @@ -1407,7 +1420,7 @@ Wlc_Ntk_t * Smt_PrsBuild2( Smt_Prs_t * p ) // added: giving a global suffix pName_glb = (char *) malloc(strlen(pName) + 4 + 1); strcpy(pName_glb,pName); - strcat(pName_glb,"_glb"); + strcat(pName_glb,SMT_GLO_SUFFIX); // FIXME: delete memory of pName pName = pName_glb; @@ -1604,6 +1617,7 @@ static inline void Smt_PrsFree( Smt_Prs_t * p ) Vec_IntErase( &p->vStack ); Vec_IntErase( &p->vTempFans ); //Vec_WecErase( &p->vDepth ); + Vec_WecErase( &p->vObjs ); ABC_FREE( p ); } @@ -1634,6 +1648,7 @@ static inline void Smt_PrsSkipNonSpaces( Smt_Prs_t * p ) } void Smt_PrsReadLines( Smt_Prs_t * p ) { + int fFirstTime = 1; assert( Vec_IntSize(&p->vStack) == 0 ); //assert( Vec_WecSize(&p->vDepth) == 0 ); assert( Vec_WecSize(&p->vObjs) == 0 ); @@ -1647,8 +1662,9 @@ void Smt_PrsReadLines( Smt_Prs_t * p ) for ( p->pCur = p->pBuffer; p->pCur < p->pLimit; p->pCur++ ) { Smt_PrsSkipSpaces( p ); - if ( *p->pCur == '|' ) + if ( fFirstTime && *p->pCur == '|' ) { + fFirstTime = 0; *p->pCur = ' '; while ( *p->pCur && *p->pCur != '|' ) *p->pCur++ = ' '; -- cgit v1.2.3 From a226496bf9174b5d50df5a438e1ee52770492f4d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 31 Jan 2017 19:53:57 -0800 Subject: Adding API for generating a monitor of a set of internal signals in a sequential logic network. --- src/base/abc/abcUtil.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) (limited to 'src/base') diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index dd3a75b7..77b55bb3 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -2933,6 +2933,160 @@ void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk ) Vec_IntWriteEntry( pNtkNew->vPhases, Abc_ObjId( (Abc_Obj_t *)pObj->pCopy ), Vec_IntEntry(pNtk->vPhases, i) ); } +/**Function************************************************************* + + Synopsis [Starts a new network using existing network as a model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkDeriveWithOnePo( Abc_Ntk_t * pNtk, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues ) +{ + int fCopyNames = 1; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pFanin, * pObjNew, * pOutputNew; + Vec_Ptr_t * vFanins = Vec_PtrAlloc( 100 ); + int i, k, Id, Value; + // start the network + pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); + // duplicate the name and the spec + pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); + pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); + // clean the node copy fields + Abc_NtkCleanCopy( pNtk ); + // map the constant nodes + if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); + // clone CIs/CIs/boxes + Abc_NtkForEachPi( pNtk, pObj, i ) + Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); + //Abc_NtkForEachPo( pNtk, pObj, i ) + // Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); + // create one PO + pObjNew = Abc_NtkCreateObj( pNtkNew, ABC_OBJ_PO ); + Abc_ObjAssignName( pObjNew, "monitor", NULL ); + // create boxes + Abc_NtkForEachBox( pNtk, pObj, i ) + Abc_NtkDupBox( pNtkNew, pObj, fCopyNames ); + + // duplicate nodes (CIs/COs/latches are already duplicated) + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( pObj->pCopy == NULL && !Abc_ObjIsPo(pObj) ) + Abc_NtkDupObj(pNtkNew, pObj, 0); + // reconnect all objects except boxes (they are already connected) and POs (they will be connected later) + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( !Abc_ObjIsPo(pObj) && !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + + // AND nodes (with interters if needed) + pOutputNew = NULL; + Vec_IntForEachEntryTwo( vNodeIds, vNodeValues, Id, Value, i ) + { + pObjNew = Abc_NtkObj( pNtk, Id )->pCopy; + if ( Value == 0 ) // negative polarity - add inverter + pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew ); + if ( pOutputNew == NULL ) + pOutputNew = pObjNew; + else + { + Vec_PtrFillTwo( vFanins, 2, pOutputNew, pObjNew ); + pOutputNew = Abc_NtkCreateNodeAnd( pNtkNew, vFanins ); + } + } + Vec_PtrFree( vFanins ); + // create the only POs, which is the AND of the corresponding nodes + Abc_ObjAddFanin( Abc_NtkPo(pNtkNew, 0), pOutputNew ); + + // check that the CI/CO/latches are copied correctly + assert( Abc_NtkPoNum(pNtkNew) == 1 ); + assert( Abc_NtkCiNum(pNtkNew) == Abc_NtkCiNum(pNtk) ); + assert( Abc_NtkLatchNum(pNtkNew) == Abc_NtkLatchNum(pNtk) ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Derives the AIG representing a property.] + + Description [Given is a sequential logic network (Abc_Ntk_t) and + an array of nodes (vector of object IDs) and their values (vector of 0s or 1s). + This procedure creates a sequential AIG (Abc_Ntk_t), which can be given to a + sequential model checker (in particular "pdr") to prove that the given + combination of values never appears at the intenal nodes of the network, + or produce a counter-example showing that it can appear.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreatePropertyMonitor( Abc_Ntk_t * p, Vec_Int_t * vNodeIds, Vec_Int_t * vNodeValues ) +{ + Abc_Ntk_t * pMonitor, * pStrashed, * pResult; + // sequential cleanup parameters + int fLatchConst = 1; + int fLatchEqual = 1; + int fSaveNames = 1; + int fUseMvSweep = 0; + int nFramesSymb = 1; + int nFramesSatur = 512; + int fVerbose = 0; + int fVeryVerbose = 0; + // expecting sequential logic network + assert( Abc_NtkIsLogic(p) ); + assert( Abc_NtkLatchNum(p) > 0 ); + assert( Vec_IntSize(vNodeIds) > 0 ); + assert( Vec_IntSize(vNodeIds) == Vec_IntSize(vNodeValues) ); + // derive ABC network whose only output is 1 iff the given nodes have the given values + pMonitor = Abc_NtkDeriveWithOnePo( p, vNodeIds, vNodeValues ); + // perform structural hashing + pStrashed = Abc_NtkStrash( pMonitor, 0, 1, 0 ); + Abc_NtkDelete( pMonitor ); + // it is a good idea to run sequential cleanup before giving the network to PDR + pResult = Abc_NtkDarLatchSweep( pStrashed, fLatchConst, fLatchEqual, fSaveNames, fUseMvSweep, nFramesSymb, nFramesSatur, fVerbose, fVeryVerbose ); + Abc_NtkDelete( pStrashed ); + return pResult; +} + +/**Function************************************************************* + + Synopsis [Testbench.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreatePropertyMonitorTest( Abc_Ntk_t * p ) +{ + Abc_Ntk_t * pNtk; + Vec_Int_t * vNodeIds = Vec_IntAlloc( 100 ); + Vec_Int_t * vNodeValues = Vec_IntAlloc( 100 ); + + // this test will only work for the network, which has nodes with internal IDs such as these + Vec_IntPush( vNodeIds, 90 ); + Vec_IntPush( vNodeIds, 80 ); + Vec_IntPush( vNodeIds, 100 ); + + Vec_IntPush( vNodeValues, 1 ); + Vec_IntPush( vNodeValues, 0 ); + Vec_IntPush( vNodeValues, 1 ); + + pNtk = Abc_NtkCreatePropertyMonitor( p, vNodeIds, vNodeValues ); + + Vec_IntFree( vNodeIds ); + Vec_IntFree( vNodeValues ); + + return pNtk; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From e91abd6307e15d9d4a4985146025e12ae6780cff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Feb 2017 16:03:40 -0800 Subject: Improvements to inductive generalization in IC3/PDR by Zyad Hassan. --- src/base/abci/abc.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 806a5de7..7ff404b0 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGaxrmsipdegovwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmsipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26100,6 +26100,17 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nTimeOutGap < 0 ) goto usage; break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRandomSeed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRandomSeed < 0 ) + goto usage; + break; case 'a': pPars->fSolveAll ^= 1; break; @@ -26133,6 +26144,12 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'o': pPars->fUsePropOut ^= 1; break; + case 'n': + pPars->fSkipDown ^= 1; + break; + case 'c': + pPars->fCtgs ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26174,9 +26191,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHG ] [-axrmsipdegovwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmsipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); - Abc_Print( -2, "\t pioneered by Aaron Bradley (http://ecee.colorado.edu/~bradleya/ic3/)\n" ); + Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); @@ -26186,6 +26203,7 @@ usage: Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); + Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); @@ -26197,10 +26215,19 @@ usage: Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); + Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); + Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t-h : print the command usage\n\n"); + Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); + Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); + Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); + Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); + + + return 1; } -- cgit v1.2.3 From 6d088bc440fb6b7a5b3eb2c9ea7b9950a1698166 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 17:02:36 -0800 Subject: Enabling new X-valued simulation in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7ff404b0..b8a0a301 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmsipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmusipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26123,6 +26123,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'm': pPars->fMonoCnf ^= 1; break; + case 'u': + pPars->fNewXSim ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26191,7 +26194,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmsipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmusipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26208,6 +26211,7 @@ usage: Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); + Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); -- cgit v1.2.3 From 45bf0369a84f9fdc55dd8cdc6227bdfd7c146dee Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Feb 2017 19:51:53 -0800 Subject: Adding structural flop priority heuristics in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index b8a0a301..319525cf 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmusipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuysipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26126,6 +26126,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'u': pPars->fNewXSim ^= 1; break; + case 'y': + pPars->fFlopPrio ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26194,7 +26197,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmusipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuysipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26212,6 +26215,7 @@ usage: Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); -- cgit v1.2.3 From f34029dd09a3ddb5ec726ef5ae541e2342544cd9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Feb 2017 12:28:34 -0800 Subject: Improvements in AIG visualization. --- src/base/io/ioWriteDot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c index 3431c761..d9687c6e 100644 --- a/src/base/io/ioWriteDot.c +++ b/src/base/io/ioWriteDot.c @@ -394,7 +394,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho fprintf( pFile, "Node%d", pNode->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pFanin->Id ); - fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" ); + fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" ); // fprintf( pFile, ", label = \"%c\"", 'a' + k ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); @@ -764,7 +764,7 @@ void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho fprintf( pFile, "Node%d", pNode->Id ); fprintf( pFile, " -> " ); fprintf( pFile, "Node%d", pFanin->Id ); - fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" ); + fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" ); // fprintf( pFile, ", label = \"%c\"", 'a' + k ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); -- cgit v1.2.3 From aed9a87282bcb7937fd74e078d30ed74786abc75 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Feb 2017 00:54:18 -0800 Subject: Adding specialized flop ordering before generalization in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 319525cf..008adbae 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26008,7 +26008,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuysipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegoncvwzh" ) ) != EOF ) { switch ( c ) { @@ -26129,6 +26129,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'y': pPars->fFlopPrio ^= 1; break; + case 'f': + pPars->fFlopOrder ^= 1; + break; case 's': pPars->fShortest ^= 1; break; @@ -26197,7 +26200,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuysipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegoncvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26216,6 +26219,7 @@ usage: Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); -- cgit v1.2.3 From cac3967b52ae44fae3962ee9eba456221e0efda3 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 6 Feb 2017 11:34:52 -0800 Subject: =?UTF-8?q?Adding=20a=20new=20SAT=20solver=20to=20ABC.=20(Satoko)?= =?UTF-8?q?=20The=20command=20is=20=E2=80=98satoko=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base/abci/abc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 008adbae..efb82fcc 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43,6 +43,7 @@ #include "map/amap/amap.h" #include "opt/ret/retInt.h" #include "sat/xsat/xsat.h" +#include "sat/satoko/satoko.h" #include "sat/cnf/cnf.h" #include "proof/cec/cec.h" #include "proof/acec/acec.h" @@ -308,6 +309,7 @@ static int Abc_CommandDSec ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -956,6 +958,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -23302,6 +23305,83 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + abctime clk; + int c; + satoko_opts_t opts; + + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Chv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + goto usage; + break; + case 'h': + goto usage; + case 'v': + opts.verbose ^= 1; + break; + + default: + goto usage; + } + } + + if ( argc == globalUtilOptind + 1 ) + { + char * pFileName = argv[globalUtilOptind]; + satoko_t * p; + int status; + + satoko_parse_dimacs( pFileName, &p ); + satoko_configure(p, &opts); + + clk = Abc_Clock(); + status = satoko_solve( p ); + + if ( status == SATOKO_UNDEC ) + Abc_Print( 1, "UNDECIDED " ); + else if ( status == SATOKO_SAT ) + Abc_Print( 1, "SATISFIABLE " ); + else + Abc_Print( 1, "UNSATISFIABLE " ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + satoko_destroy( p ); + return 0; + } + +usage: + Abc_Print( -2, "usage: satoko [-CILDE num] [-hv].cnf\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} /**Function************************************************************* Synopsis [] @@ -26238,7 +26318,7 @@ usage: Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); - + return 1; } -- cgit v1.2.3 From 0fb4442a8208ccc36067db034c12a840095c0911 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Mon, 6 Feb 2017 19:50:57 -0800 Subject: Small changes to support old compilers. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index efb82fcc..65974acb 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23357,7 +23357,7 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) int status; satoko_parse_dimacs( pFileName, &p ); - satoko_configure(p, &opts); + satoko_configure(p, &opts); clk = Abc_Clock(); status = satoko_solve( p ); -- cgit v1.2.3 From de4bf41c53665ca8389d74b15be24ab407e8ff65 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 14:10:08 -0800 Subject: New command &satoko. --- src/base/abci/abc.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/base/wlc/wlcShow.c | 4 +-- 2 files changed, 73 insertions(+), 4 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 65974acb..1ecc5e68 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -310,6 +310,7 @@ static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandDSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Satoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -959,6 +960,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "xsat", Abc_CommandXSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "&satoko", Abc_CommandAbc9Satoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -23356,11 +23358,12 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) satoko_t * p; int status; - satoko_parse_dimacs( pFileName, &p ); + status = satoko_parse_dimacs( pFileName, &p ); satoko_configure(p, &opts); clk = Abc_Clock(); - status = satoko_solve( p ); + if ( status == SATOKO_OK ) + status = satoko_solve( p ); if ( status == SATOKO_UNDEC ) Abc_Print( 1, "UNDECIDED " ); @@ -23382,6 +23385,72 @@ usage: Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ); + int c, fSplit = 0; + + satoko_opts_t opts; + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Csvh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + goto usage; + break; + case 's': + fSplit ^= 1; + break; + case 'v': + opts.verbose ^= 1; + break; + case 'h': + goto usage; + + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" ); + return 1; + } + Gia_ManCallSatoko( pAbc->pGia, &opts, fSplit ); + return 0; + +usage: + Abc_Print( -2, "usage: &satoko [-C num] [-svh]\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\t-s : split multi-output miter into individual outputs [default = %s]\n", fSplit? "yes": "no" ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index 7914cd7a..1601d602 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -49,9 +49,9 @@ void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold ) Wlc_Obj_t * pNode; int LevelMax, Prev, Level, i; - if ( Wlc_NtkObjNum(p) > 1000 ) + if ( Wlc_NtkObjNum(p) > 2000 ) { - fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 1000 ); + fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 2000 ); return; } if ( (pFile = fopen( pFileName, "w" )) == NULL ) -- cgit v1.2.3 From 77e2b1ff53bd806a681c9a887cd5b026681d271b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 18:57:16 -0800 Subject: Autotuner for 'satoko'. --- src/base/abci/abc.c | 27 ++- src/base/cmd/cmd.c | 114 +++++++++++ src/base/cmd/cmdAuto.c | 522 +++++++++++++++++++++++++++++++++++++++++++++++ src/base/cmd/module.make | 1 + 4 files changed, 660 insertions(+), 4 deletions(-) create mode 100644 src/base/cmd/cmdAuto.c (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1ecc5e68..38a555d8 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -16782,7 +16782,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) If_ManSetDefaultPars( pPars ); pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "K:CFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) { switch ( c ) { @@ -38135,9 +38135,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; Vec_Int_t * vPos; - int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fVerbose = 0; + int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWavh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaevh" ) ) != EOF ) { switch ( c ) { @@ -38199,6 +38199,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'a': fUseAllCis ^= 1; break; + case 'e': + fExtractAll ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -38213,6 +38216,21 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Cone(): There is no AIG.\n" ); return 1; } + if ( fExtractAll ) + { + char Buffer[1000]; + Gia_Obj_t * pObj; + int i, nDigits = Abc_Base10Log(Gia_ManPoNum(pAbc->pGia)); + Gia_ManForEachPo( pAbc->pGia, pObj, i ) + { + Gia_Man_t * pOne = Gia_ManDupDfsCone( pAbc->pGia, pObj ); + sprintf( Buffer, "%s_%0*d.aig", Extra_FileNameGeneric(pAbc->pGia->pSpec), nDigits, i ); + Gia_AigerWrite( pOne, Buffer, 0, 0 ); + Gia_ManStop( pOne ); + } + printf( "Dumped all outputs into individual AIGER files.\n" ); + return 0; + } if ( nLevelMax || nTimeWindow ) { if ( nLevelMax && nTimeWindow ) @@ -38260,7 +38278,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &cone [-ORPLW num] [-avh]\n" ); + Abc_Print( -2, "usage: &cone [-ORPLW num] [-aevh]\n" ); Abc_Print( -2, "\t extracting multi-output sequential logic cones\n" ); Abc_Print( -2, "\t-O num : the index of first PO to extract [default = %d]\n", iOutNum ); Abc_Print( -2, "\t-R num : (optional) the number of outputs to extract [default = %d]\n", nOutRange ); @@ -38268,6 +38286,7 @@ usage: Abc_Print( -2, "\t-L num : (optional) extract cones with higher level [default = %d]\n", nLevelMax ); Abc_Print( -2, "\t-W num : (optional) extract cones falling into this window [default = %d]\n", nTimeWindow ); Abc_Print( -2, "\t-a : toggle keeping all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" ); + Abc_Print( -2, "\t-e : toggle writing all outputs into individual files [default = %s]\n", fExtractAll? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index ab037139..ec4a0c86 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -60,6 +60,7 @@ static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int CmdCommandStarter ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int CmdCommandAutoTuner ( Abc_Frame_t * pAbc, int argc, char ** argv ); extern int Cmd_CommandAbcLoadPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -110,6 +111,7 @@ void Cmd_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1 ); Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0 ); Cmd_CommandAdd( pAbc, "Various", "starter", CmdCommandStarter, 0 ); + Cmd_CommandAdd( pAbc, "Various", "autotuner", CmdCommandAutoTuner, 0 ); Cmd_CommandAdd( pAbc, "Various", "load_plugin", Cmd_CommandAbcLoadPlugIn, 0 ); } @@ -2457,6 +2459,118 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ); + FILE * pFile; + char * pFileConf = NULL; + char * pFileList = NULL; + char * pFileName; + int c, nCores = 3; + int fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "NCFvh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nCores = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCores < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by a string (possibly in quotes).\n" ); + goto usage; + } + pFileConf = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by a string (possibly in quotes).\n" ); + goto usage; + } + pFileList = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pFileConf == NULL ) + { + Abc_Print( -2, "File containing configuration for autotuning is not given.\n" ); + return 1; + } + if ( pFileList == NULL ) + { + Abc_Print( -2, "File contining list of files for autotuning is not given.\n" ); + return 1; + } + // get the input file name + pFileName = pFileConf; + if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL ) +// if ( (pFile = fopen( pFileName, "rb" )) == NULL ) + { + Abc_Print( -2, "Cannot open configuration file \"%s\". ", pFileName ); + if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) )) + Abc_Print( -2, "Did you mean \"%s\"?", pFileName ); + Abc_Print( -2, "\n" ); + return 1; + } + fclose( pFile ); + // get the input file name + pFileName = pFileList; + if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL ) +// if ( (pFile = fopen( pFileName, "rb" )) == NULL ) + { + Abc_Print( -2, "Cannot open the file list \"%s\". ", pFileName ); + if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) )) + Abc_Print( -2, "Did you mean \"%s\"?", pFileName ); + Abc_Print( -2, "\n" ); + return 1; + } + fclose( pFile ); + // run commands + Cmd_RunAutoTuner( pFileConf, pFileList, nCores ); + return 0; + +usage: + Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" ); + Abc_Print( -2, "\t runs command lines listed in concurrently on CPUs\n" ); + Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores ); + Abc_Print( -2, "\t-C cmd : configuration file for autotuning\n" ); + Abc_Print( -2, "\t-F cmd : list of files to be used for autotuning\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [Print the version string.] diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c new file mode 100644 index 00000000..28b209fa --- /dev/null +++ b/src/base/cmd/cmdAuto.c @@ -0,0 +1,522 @@ +/**CFile**************************************************************** + + FileName [cmdAuto.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Autotuner.] + + Author [Alan Mishchenko, Bruno Schmitt] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cmdAuto.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include +#include +#include +#include +#include "misc/util/abc_global.h" +#include "misc/extra/extra.h" +#include "aig/gia/gia.h" +#include "sat/satoko/satoko.h" + +#ifdef ABC_USE_PTHREADS + +#ifdef _WIN32 +#include "../lib/pthread.h" +#else +#include +#include +#endif + +#endif + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string +#define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call + +extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Printing option structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) +{ + printf( "-C %d ", pOpts->conf_limit ); + printf( "-V %.3f ", pOpts->var_decay ); + printf( "-W %.3f ", pOpts->clause_decay ); + if ( pOpts->verbose ) + printf( "-v", pOpts->verbose ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [The main evaluation procedure for an array of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts ) +{ + Gia_Man_t * pGia; + int i, TotalCost = 0; + //printf( "Tuning with options: " ); + //Cmd_RunAutoTunerPrintOptions( pOpts ); + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) + TotalCost += Gia_ManCallSatokoOne( pGia, pOpts, -1 ); + return TotalCost; +} + +/**Function************************************************************* + + Synopsis [The main evaluation procedure for the set of AIGs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +#ifndef ABC_USE_PTHREADS + +int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nCores ) +{ + return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts ); +} + +#else // pthreads are used + + +#define CMD_THR_MAX 100 +typedef struct Cmd_AutoData_t_ +{ + Gia_Man_t * pGia; + satoko_opts_t * pOpts; + int iThread; + int nTimeOut; + int fWorking; + int Result; +} Cmd_AutoData_t; + +void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) +{ + Cmd_AutoData_t * pThData = (Cmd_AutoData_t *)pArg; + volatile int * pPlace = &pThData->fWorking; + while ( 1 ) + { + while ( *pPlace == 0 ); + assert( pThData->fWorking ); + if ( pThData->pGia == NULL ) // kills itself when there is nothing to do + { + pthread_exit( NULL ); + assert( 0 ); + return NULL; + } + pThData->Result = Gia_ManCallSatokoOne( pThData->pGia, pThData->pOpts, -1 ); + pThData->fWorking = 0; + } + assert( 0 ); + return NULL; +} +int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs ) +{ + abctime clkTotal = Abc_Clock(); + Cmd_AutoData_t ThData[CMD_THR_MAX]; + pthread_t WorkerThread[CMD_THR_MAX]; + int i, status, fWorkToDo = 1, TotalCost = 0; + Vec_Ptr_t * vStack; + if ( nProcs == 1 ) + return Cmd_RunAutoTunerEvalSimple( vAigs, pOpts ); + // subtract manager thread + nProcs--; + assert( nProcs >= 1 && nProcs <= CMD_THR_MAX ); + // start threads + for ( i = 0; i < nProcs; i++ ) + { + ThData[i].pGia = NULL; + ThData[i].pOpts = pOpts; + ThData[i].iThread = i; + ThData[i].nTimeOut = -1; + ThData[i].fWorking = 0; + ThData[i].Result = -1; + status = pthread_create( WorkerThread + i, NULL,Cmd_RunAutoTunerEvalWorkerThread, (void *)(ThData + i) ); assert( status == 0 ); + } + // look at the threads + vStack = Vec_PtrDup(vAigs); + while ( fWorkToDo ) + { + fWorkToDo = (int)(Vec_PtrSize(vStack) > 0); + for ( i = 0; i < nProcs; i++ ) + { + // check if this thread is working + if ( ThData[i].fWorking ) + { + fWorkToDo = 1; + continue; + } + // check if this thread has recently finished + if ( ThData[i].pGia != NULL ) + { + assert( ThData[i].Result >= 0 ); + TotalCost += ThData[i].Result; + ThData[i].pGia = NULL; + } + if ( Vec_PtrSize(vStack) == 0 ) + continue; + // give this thread a new job + assert( ThData[i].pGia == NULL ); + ThData[i].pGia = (Gia_Man_t *)Vec_PtrPop( vStack ); + ThData[i].fWorking = 1; + } + } + Vec_PtrFree( vStack ); + // stop threads + for ( i = 0; i < nProcs; i++ ) + { + assert( !ThData[i].fWorking ); + // stop + ThData[i].pGia = NULL; + ThData[i].fWorking = 1; + } + return TotalCost; +} + +#endif // pthreads are used + + +/**Function************************************************************* + + Synopsis [Derives all possible param stucts according to the config file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Cmd_DeriveConvertIntoString( int argc, char ** argv ) +{ + char pBuffer[CMD_AUTO_LINE_MAX] = {0}; + int i; + for ( i = 0; i < argc; i++ ) + { + strcat( pBuffer, argv[i] ); + strcat( pBuffer, " " ); + } + return Abc_UtilStrsav(pBuffer); +} +satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) +{ + int c; + satoko_opts_t opts, * pOpts; + satoko_default_opts(&opts); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CVWhv" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + return NULL; + } + opts.conf_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.conf_limit < 0 ) + return NULL; + break; + case 'V': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-V\" should be followed by an integer.\n" ); + return NULL; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + return NULL; + break; + case 'W': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + return NULL; + break; + case 'v': + opts.verbose ^= 1; + break; + default: + return NULL; + } + } + // return a copy of this parameter structure + pOpts = ABC_ALLOC( satoko_opts_t, 1 ); + memcpy( pOpts, &opts, sizeof(satoko_opts_t) ); + return pOpts; +} +void Cmf_CreateOptions_rec( Vec_Wec_t * vPars, int iPar, char Argv[CMD_AUTO_ARG_MAX][20], int Argc, Vec_Ptr_t * vOpts ) +{ + Vec_Int_t * vLine; + int Symb, Num, i; + assert( Argc <= CMD_AUTO_ARG_MAX ); + if ( Vec_WecSize(vPars) == iPar ) + { + satoko_opts_t * pOpts; + char * pArgv[CMD_AUTO_ARG_MAX]; + for ( i = 0; i < Argc; i++ ) + pArgv[i] = Argv[i]; + pOpts = Cmd_DeriveOptionFromSettings( Argc, pArgv ); + if ( pOpts == NULL ) + printf( "Cannot parse command line options...\n" ); + else + { + Vec_PtrPush( vOpts, pOpts ); + Vec_PtrPush( vOpts, Cmd_DeriveConvertIntoString(Argc, pArgv) ); + printf( "Adding settings %s\n", (char *)Vec_PtrEntryLast(vOpts) ); + } + return; + } + vLine = Vec_WecEntry( vPars, iPar ); + // consider binary option + if ( Vec_IntSize(vLine) == 2 ) + { + Symb = Vec_IntEntry( vLine, 0 ); + Num = Vec_IntEntry( vLine, 1 ); + assert( Abc_Int2Float(Num) == -1.0 ); + // create one setting without this option + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc, vOpts ); + // create another setting with this option + sprintf( Argv[Argc], "-%c", Symb ); + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+1, vOpts ); + return; + } + // consider numeric option + Vec_IntForEachEntryDouble( vLine, Symb, Num, i ) + { + float NumF = Abc_Int2Float(Num); + // create setting with this option + assert( NumF >= 0 ); + sprintf( Argv[Argc], "-%c", Symb ); + if ( NumF == (float)(int)NumF ) + sprintf( Argv[Argc+1], "%d", (int)NumF ); + else + sprintf( Argv[Argc+1], "%.3f", NumF ); + Cmf_CreateOptions_rec( vPars, iPar+1, Argv, Argc+2, vOpts ); + } +} +Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars ) +{ + char Argv[CMD_AUTO_ARG_MAX][20]; + int Symb, Num, i, Argc = 0; + Vec_Ptr_t * vOpts = Vec_PtrAlloc( 100 ); + Vec_Int_t * vLine = Vec_WecEntry( vPars, 0 ); + printf( "Creating all possible settings to be used by the autotuner:\n" ); + sprintf( Argv[Argc++], "autotuner" ); + Vec_IntForEachEntryDouble( vLine, Symb, Num, i ) + { + float NumF = Abc_Int2Float(Num); + sprintf( Argv[Argc++], "-%c", Symb ); + if ( NumF < 0.0 ) + continue; + if ( NumF == (float)(int)NumF ) + sprintf( Argv[Argc++], "%d", (int)NumF ); + else + sprintf( Argv[Argc++], "%.3f", NumF ); + } + Cmf_CreateOptions_rec( vPars, 1, Argv, Argc, vOpts ); + printf( "Finished creating %d settings.\n\n", Vec_PtrSize(vOpts)/2 ); + return vOpts; +} + + +/**Function************************************************************* + + Synopsis [Parses config file and derives AIGs listed in file list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } +static inline Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } +static inline Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } +static inline Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } + +Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig ) +{ + Vec_Wec_t * vPars; + Vec_Int_t * vLine; + char * pThis, pBuffer[CMD_AUTO_LINE_MAX]; + FILE * pFile = fopen( pConfig, "rb" ); + if ( pFile == NULL ) + { printf( "File containing list of files \"%s\" cannot be opened.\n", pConfig ); return NULL; } + vPars = Vec_WecAlloc( 100 ); + while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL ) + { + // get the command from the file + if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#') + continue; + // skip trailing spaces + while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) ) + pBuffer[strlen(pBuffer)-1] = 0; + // read the line + vLine = Vec_WecPushLevel( vPars ); + for ( pThis = pBuffer; *pThis; ) + { + if ( Cmf_IsLowerCaseChar(*pThis) ) + { + Vec_IntPushTwo( vLine, (int)*pThis, Abc_Float2Int((float)-1.0) ); + pThis++; + while ( Cmf_IsSpace(*pThis) ) + pThis++; + continue; + } + if ( Cmf_IsUpperCaseChar(*pThis) ) + { + char Param = *pThis++; + if ( !Cmf_IsDigit(*pThis) ) + { printf( "Upper-case character (%c) should be followed by a number without space in line \"%s\".\n", Param, pBuffer ); return NULL; } + Vec_IntPushTwo( vLine, (int)Param, Abc_Float2Int(atof(pThis)) ); + while ( Cmf_IsDigit(*pThis) ) + pThis++; + while ( Cmf_IsSpace(*pThis) ) + pThis++; + continue; + } + printf( "Expecting a leading lower-case or upper-case digit in line \"%s\".\n", pBuffer ); + return NULL; + } + } + fclose( pFile ); + return vPars; +} +Vec_Ptr_t * Cmd_ReadFiles( char * pFileList ) +{ + Gia_Man_t * pGia; + Vec_Ptr_t * vAigs; + char pBuffer[CMD_AUTO_LINE_MAX]; + FILE * pFile = fopen( pFileList, "rb" ); + if ( pFile == NULL ) + { printf( "File containing list of files \"%s\" cannot be opened.\n", pFileList ); return NULL; } + vAigs = Vec_PtrAlloc( 100 ); + while ( fgets( pBuffer, CMD_AUTO_LINE_MAX, pFile ) != NULL ) + { + // get the command from the file + if ( Cmf_IsSpace(pBuffer[0]) || pBuffer[0] == '#') + continue; + // skip trailing spaces + while ( Cmf_IsSpace(pBuffer[strlen(pBuffer)-1]) ) + pBuffer[strlen(pBuffer)-1] = 0; + // read the file + pGia = Gia_AigerRead( pBuffer, 0, 0, 0 ); + if ( pGia == NULL ) + { + printf( "Cannot read AIG from file \"%s\".\n", pBuffer ); + continue; + } + Vec_PtrPush( vAigs, pGia ); + } + fclose( pFile ); + return vAigs; +} + +/**Function************************************************************* + + Synopsis [Autotuner for SAT solver "satoko".] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) +{ + abctime clk = Abc_Clock(); + Vec_Wec_t * vPars = Cmd_ReadParamChoices( pConfig ); + Vec_Ptr_t * vAigs = Cmd_ReadFiles( pFileList ); + Vec_Ptr_t * vOpts = vPars ? Cmf_CreateOptions( vPars ) : NULL; + int i; char * pString, * pStringBest = NULL; + satoko_opts_t * pOpts, * pOptsBest = NULL; + int Result, ResultBest = 0x7FFFFFFF; + Gia_Man_t * pGia; + // iterate through all possible option settings + if ( vAigs && vOpts ) + { + Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i ) + { + abctime clk = Abc_Clock(); + printf( "Evaluating options %20s... ", pString ); + Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores ); + printf( "Cost = %6d. ", Result ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( ResultBest > Result ) + { + ResultBest = Result; + pStringBest = pString; + pOptsBest = pOpts; + } + } + printf( "The best options are: %20s ", pStringBest ); + printf( "Best cost = %6d. ", ResultBest ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + // cleanup + if ( vPars ) Vec_WecFree( vPars ); + if ( vOpts ) Vec_PtrFreeFree( vOpts ); + if ( vAigs ) + { + Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) + Gia_ManStop( pGia ); + Vec_PtrFree( vAigs ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/cmd/module.make b/src/base/cmd/module.make index b09ffa81..1042fbb0 100644 --- a/src/base/cmd/module.make +++ b/src/base/cmd/module.make @@ -1,6 +1,7 @@ SRC += src/base/cmd/cmd.c \ src/base/cmd/cmdAlias.c \ src/base/cmd/cmdApi.c \ + src/base/cmd/cmdAuto.c \ src/base/cmd/cmdFlag.c \ src/base/cmd/cmdHist.c \ src/base/cmd/cmdLoad.c \ -- cgit v1.2.3 From 1e62fb4a92b49639b8ee554a8fb6aafde428daf8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 18:59:07 -0800 Subject: Compiler warning. --- src/base/cmd/cmdAuto.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src/base') diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 28b209fa..e029f6d2 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -66,11 +66,11 @@ extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutpu ***********************************************************************/ void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) { - printf( "-C %d ", pOpts->conf_limit ); + printf( "-C %d ", (int)pOpts->conf_limit ); printf( "-V %.3f ", pOpts->var_decay ); printf( "-W %.3f ", pOpts->clause_decay ); if ( pOpts->verbose ) - printf( "-v", pOpts->verbose ); + printf( "-v" ); printf( "\n" ); } @@ -150,7 +150,6 @@ void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) } int Cmd_RunAutoTunerEval( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts, int nProcs ) { - abctime clkTotal = Abc_Clock(); Cmd_AutoData_t ThData[CMD_THR_MAX]; pthread_t WorkerThread[CMD_THR_MAX]; int i, status, fWorkToDo = 1, TotalCost = 0; @@ -377,10 +376,10 @@ Vec_Ptr_t * Cmf_CreateOptions( Vec_Wec_t * vPars ) SeeAlso [] ***********************************************************************/ -static inline Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } -static inline Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } -static inline Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } -static inline Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } +static inline int Cmf_IsSpace( char p ) { return p == ' ' || p == '\t' || p == '\n' || p == '\r'; } +static inline int Cmf_IsLowerCaseChar( char p ) { return p >= 'a' && p <= 'z'; } +static inline int Cmf_IsUpperCaseChar( char p ) { return p >= 'A' && p <= 'Z'; } +static inline int Cmf_IsDigit( char p ) { return (p >= '0' && p <= '9') || p == '.'; } Vec_Wec_t * Cmd_ReadParamChoices( char * pConfig ) { -- cgit v1.2.3 From 778ea6bb8ac56a716f457932fbc1a211692f238c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:07:21 -0800 Subject: Editing output messages. --- src/base/cmd/cmdAuto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/base') diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index e029f6d2..7d0cc8af 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -486,7 +486,7 @@ void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) Vec_PtrForEachEntryDouble( satoko_opts_t *, char *, vOpts, pOpts, pString, i ) { abctime clk = Abc_Clock(); - printf( "Evaluating options %20s... ", pString ); + printf( "Evaluating settings: %20s... \n", pString ); Result = Cmd_RunAutoTunerEval( vAigs, pOpts, nCores ); printf( "Cost = %6d. ", Result ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); @@ -497,9 +497,9 @@ void Cmd_RunAutoTuner( char * pConfig, char * pFileList, int nCores ) pOptsBest = pOpts; } } - printf( "The best options are: %20s ", pStringBest ); + printf( "The best settings are: %20s \n", pStringBest ); printf( "Best cost = %6d. ", ResultBest ); - Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); } // cleanup if ( vPars ) Vec_WecFree( vPars ); -- cgit v1.2.3 From 2a9902eec7287735db933a8d55f7f7458aa9d939 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:10:15 -0800 Subject: Accidental change. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 38a555d8..26e9c0f8 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -16782,7 +16782,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) If_ManSetDefaultPars( pPars ); pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "K:CFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYDEWSqaflepmrsdbgxyuojiktncvh" ) ) != EOF ) { switch ( c ) { -- cgit v1.2.3 From 040b88a7c6bc437f6f9dc792510d5d905b516eb5 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Feb 2017 19:12:57 -0800 Subject: Editing output messages. --- src/base/cmd/cmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/base') diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index ec4a0c86..853f5710 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -2562,10 +2562,10 @@ int CmdCommandAutoTuner( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: autotuner [-N num] [-C file] [-F file] [-vh]\n" ); - Abc_Print( -2, "\t runs command lines listed in concurrently on CPUs\n" ); + Abc_Print( -2, "\t performs autotuning\n" ); Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controler [default = %d]\n", nCores ); - Abc_Print( -2, "\t-C cmd : configuration file for autotuning\n" ); - Abc_Print( -2, "\t-F cmd : list of files to be used for autotuning\n" ); + Abc_Print( -2, "\t-C cmd : configuration file with settings for autotuning\n" ); + Abc_Print( -2, "\t-F cmd : list of AIGER files to be used for autotuning\n" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; -- cgit v1.2.3 From e20ef654d99d5cf1f0f73466b931d53833f6a1eb Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 13:31:07 -0800 Subject: Word-level abstraction. --- src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 15 +++- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcAbs2.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcCom.c | 99 +++++++++++++++++++++++- src/base/wlc/wlcNtk.c | 86 ++++++++++++++++++--- src/base/wlc/wlcReadVer.c | 2 +- 7 files changed, 379 insertions(+), 14 deletions(-) create mode 100644 src/base/wlc/wlcAbs2.c (limited to 'src/base') diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index ae7899ec..3485bd4d 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -1,4 +1,5 @@ SRC += src/base/wlc/wlcAbs.c \ + src/base/wlc/wlcAbs2.c \ src/base/wlc/wlcAbc.c \ src/base/wlc/wlcBlast.c \ src/base/wlc/wlcCom.c \ diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index d51b699c..0a17cfe6 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -160,6 +160,16 @@ struct Wlc_Ntk_t_ Vec_Int_t vLevels; // object levels }; +typedef struct Wlc_Par_t_ Wlc_Par_t; +struct Wlc_Par_t_ +{ + int nBitsAdd; // adder bit-width + int nBitsMul; // multiplier bit-widht + int nBitsMux; // MUX bit-width + int nBitsFlop; // flop bit-width + int fVerbose; // verbose output` +}; + static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -267,6 +277,9 @@ extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); +/*=== wlcAbs2.c ========================================================*/ +extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); +extern Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth ); /*=== wlcCom.c ========================================================*/ @@ -291,7 +304,7 @@ extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index ce6b8de9..8662e509 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); + pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); return pNew; } @@ -277,7 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); + pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); return pNew; } diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c new file mode 100644 index 00000000..9da59f42 --- /dev/null +++ b/src/base/wlc/wlcAbs2.c @@ -0,0 +1,186 @@ +/**CFile**************************************************************** + + FileName [wlcAbs2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Abstraction for word-level networks.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcAbs2.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Wabs_Par_t_ Wabs_Par_t; +struct Wabs_Par_t_ +{ + Wlc_Ntk_t * pNtk; + Wlc_Par_t * pPars; + Vec_Bit_t * vLeaves; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Wlc_Par_t) ); + pPars->nBitsAdd = 16; // adder bit-width + pPars->nBitsMul = 8; // multiplier bit-widht + pPars->nBitsMux = 32; // MUX bit-width + pPars->nBitsFlop = 32; // flop bit-width + pPars->fVerbose = 0; // verbose output` +} + +/**Function************************************************************* + + Synopsis [Mark operators that meet the criteria.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + Wlc_Obj_t * pObj; int i; + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( pObj->Type == WLC_OBJ_MUX ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + continue; + } + } + return vLeaves; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vFlops, Vec_Int_t * vPisNew ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) + { + Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); + return; + } + if ( Wlc_ObjIsCi(pObj) ) + { + if ( !Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vFlops, vPisNew ); +} + +Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) +{ + Vec_Int_t * vFlops; + Vec_Int_t * vPisNew; + Wlc_Obj_t * pObj; + int i, CiId, CoId; + Wlc_NtkCleanMarks( p ); + vFlops = Vec_IntAlloc( 100 ); + vPisNew = Vec_IntAlloc( 100 ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vFlops, vPisNew ); + Vec_IntForEachEntry( vFlops, CiId, i ) + { + CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkCo(p, CoId), vLeaves, vFlops, vPisNew ); + } + Vec_IntFree( vFlops ); + return vPisNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); + Vec_Int_t * vPisNew = Wlc_NtkAbsMarkNodes( p, vLeaves ); + Wlc_Ntk_t * pNtkNew = Wlc_NtkDupDfs( p, 1, 1, vPisNew ); + Vec_IntFree( vPisNew ); + Vec_BitFree( vLeaves ); + return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 82321d3b..3bbe843f 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,6 +32,7 @@ static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -72,6 +73,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); @@ -421,7 +423,7 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); - pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq, NULL ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); @@ -438,6 +440,101 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFvh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 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; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + pNtk = Wlc_NtkAbs( pNtk, pPars ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%abs [-AMXF num] [-vh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index bd00a570..6eab4442 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -705,6 +705,45 @@ char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ) return pBuffer; } +/**Function************************************************************* + + Synopsis [Reduce init vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit ) +{ + Vec_Int_t * vInitNew = Vec_IntDup( vInit ); + Wlc_Obj_t * pObj; int i, k = 0; + assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) ); + Wlc_NtkForEachCi( p, pObj, i ) + if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) + Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i) ); + Vec_IntShrink( vInitNew, k ); + return vInitNew; +} +char * Wlc_ReduceMarkedInitStr( Wlc_Ntk_t * p, char * pInit ) +{ + char * pInitNew = Abc_UtilStrsav( pInit ); + Wlc_Obj_t * pObj; int i, b, nBits = 0, k = 0; + Wlc_NtkForEachCi( p, pObj, i ) + { + if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + pInitNew[k++] = pInitNew[nBits+b]; + if ( !Wlc_ObjIsPi(pObj) ) + nBits += Wlc_ObjRange(pObj); + } + pInitNew[k] = '\0'; + assert( nBits == (int)strlen(pInit) ); + return pInitNew; +} + /**Function************************************************************* Synopsis [Duplicates the network in a topological order.] @@ -764,7 +803,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -774,14 +813,33 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; - Wlc_NtkForEachCi( p, pObj, i ) - if ( !fMarked || pObj->Mark ) + if ( vPisNew ) + { + // duplicate marked PIs + Wlc_NtkForEachPi( p, pObj, i ) + if ( pObj->Mark ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + // duplicated additional PIs + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) { unsigned Type = pObj->Type; - if ( !fSeq ) pObj->Type = WLC_OBJ_PI; + assert( !Wlc_ObjIsPi(pObj) ); + pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); pObj->Type = Type; } + } + else + { + Wlc_NtkForEachCi( p, pObj, i ) + if ( !fMarked || pObj->Mark ) + { + unsigned Type = pObj->Type; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + } + } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); @@ -789,12 +847,22 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) if ( !fMarked || pObj->Mark ) Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); Vec_IntFree( vFanins ); - if ( !fMarked ) + if ( fSeq ) { - if ( p->vInits ) - pNew->vInits = Vec_IntDup( p->vInits ); - if ( p->pInits ) - pNew->pInits = Abc_UtilStrsav( p->pInits ); + if ( fMarked ) + { + if ( p->vInits ) + pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits ); + if ( p->pInits ) + pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits ); + } + else + { + if ( p->vInits ) + pNew->vInits = Vec_IntDup( p->vInits ); + if ( p->pInits ) + pNew->pInits = Abc_UtilStrsav( p->pInits ); + } } if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index e4a65ecf..f7546b5b 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1, NULL ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); -- cgit v1.2.3 From 32712ec9abb3f27e3bd00690838b054f5bdc0f77 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 14:17:19 -0800 Subject: Making sure 'inv_out' can match flops by name. --- src/base/wlc/wlcAbc.c | 54 +++++++++++++++++++++++++++++++++++++++---------- src/base/wlc/wlcBlast.c | 11 +++++----- src/base/wlc/wlcCom.c | 4 ++-- 3 files changed, 51 insertions(+), 18 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index 1f10d7b0..e19aaaec 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -185,8 +185,9 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) +Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ) { + int nRegs = Gia_ManRegNum(pGia); Vec_Int_t * vRes = NULL; if ( Abc_NtkPoNum(pNtk) != 1 ) printf( "The number of outputs is other than 1.\n" ); @@ -194,26 +195,57 @@ Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ) printf( "The number of internal nodes is other than 1.\n" ); else { - Abc_Obj_t * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); + Abc_Nam_t * pNames = NULL; + Abc_Obj_t * pFanin, * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) ); char * pName, * pCube, * pSop = (char *)pNode->pData; Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) ); - Abc_Obj_t * pFanin; int i, k, Value, nLits; + int i, k, Value, nLits, Counter = 0; + if ( pGia->vNamesIn ) + { + // hash the names + pNames = Abc_NamStart( 100, 16 ); + Vec_PtrForEachEntry( char *, pGia->vNamesIn, pName, i ) + { + Value = Abc_NamStrFindOrAdd( pNames, pName, NULL ); + assert( Value == i+1 ); + //printf( "%s(%d) ", pName, i ); + } + //printf( "\n" ); + } Abc_ObjForEachFanin( pNode, pFanin, i ) { assert( Abc_ObjIsCi(pFanin) ); pName = Abc_ObjName(pFanin); - for ( k = (int)strlen(pName)-1; k >= 0; k-- ) - if ( pName[k] < '0' || pName[k] > '9' ) - break; - if ( k == (int)strlen(pName)-1 ) + if ( pNames ) + { + Value = Abc_NamStrFind(pNames, pName) - 1; + if ( Value == -1 ) + { + if ( Counter++ == 0 ) + printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); + Value = i; + } + } + else { - printf( "Cannot read input name of fanin %d.\n", i ); - Value = i; + for ( k = (int)strlen(pName)-1; k >= 0; k-- ) + if ( pName[k] < '0' || pName[k] > '9' ) + break; + if ( k == (int)strlen(pName)-1 ) + { + if ( Counter++ == 0 ) + printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); + Value = i; + } + else + Value = atoi(pName + k + 1); } - else - Value = atoi(pName + k + 1); Vec_IntPush( vFanins, Value ); } + if ( Counter ) + printf( "Cannot read names for %d inputs of the invariant.\n", Counter ); + if ( pNames ) + Abc_NamStop( pNames ); assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) ); vRes = Vec_IntAlloc( 1000 ); Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) ); diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index b49c2dd7..67d7c902 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -872,6 +872,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { int fVerbose = 0; int fUseOldMultiplierBlasting = 0; + int fSkipBitRange = 0; Tim_Man_t * pManTime = NULL; Gia_Man_t * pTemp, * pNew, * pExtra = NULL; Wlc_Obj_t * pObj; @@ -1448,7 +1449,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1475,7 +1476,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1498,7 +1499,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1513,7 +1514,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) @@ -1532,7 +1533,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in { char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); nRange = Wlc_ObjRange( pObj ); - if ( nRange == 1 ) + if ( fSkipBitRange && nRange == 1 ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); else for ( k = 0; k < nRange; k++ ) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 3bbe843f..cc69c636 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -1051,7 +1051,7 @@ usage: ******************************************************************************/ int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, int nRegs ); + extern Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ); Vec_Int_t * vInv = NULL; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c, fVerbose = 0; @@ -1080,7 +1080,7 @@ int Abc_CommandInvPut( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // derive the network - vInv = Wlc_NtkGetPut( pNtk, Gia_ManRegNum(pAbc->pGia) ); + vInv = Wlc_NtkGetPut( pNtk, pAbc->pGia ); if ( vInv ) Abc_FrameSetInv( vInv ); return 0; -- cgit v1.2.3 From 2fe17c1f4bf2a4df4076ad2fee336f568c52786f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 14:30:10 -0800 Subject: Word-level abstraction. --- src/base/cmd/cmdAuto.c | 4 ++-- src/base/wlc/wlcAbc.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/base') diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 7d0cc8af..35f155fa 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -67,8 +67,8 @@ extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutpu void Cmd_RunAutoTunerPrintOptions( satoko_opts_t * pOpts ) { printf( "-C %d ", (int)pOpts->conf_limit ); - printf( "-V %.3f ", pOpts->var_decay ); - printf( "-W %.3f ", pOpts->clause_decay ); + printf( "-V %.3f ", (float)pOpts->var_decay ); + printf( "-W %.3f ", (float)pOpts->clause_decay ); if ( pOpts->verbose ) printf( "-v" ); printf( "\n" ); diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index e19aaaec..1836f4ed 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -218,8 +218,8 @@ Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia ) pName = Abc_ObjName(pFanin); if ( pNames ) { - Value = Abc_NamStrFind(pNames, pName) - 1; - if ( Value == -1 ) + Value = Abc_NamStrFind(pNames, pName) - 1 - Gia_ManPiNum(pGia); + if ( Value < 0 ) { if ( Counter++ == 0 ) printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i ); -- cgit v1.2.3 From 7a2984bbe9e2d9e76851c0ce440e08f6788fcb70 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 9 Feb 2017 16:38:08 -0800 Subject: Word-level abstraction. --- src/base/wlc/wlc.h | 3 +- src/base/wlc/wlcAbs.c | 4 +- src/base/wlc/wlcAbs2.c | 76 ++++++++++++++++++++---------------- src/base/wlc/wlcCom.c | 8 ++-- src/base/wlc/wlcNtk.c | 98 ++++++++++++++++++++++++++++++++++------------- src/base/wlc/wlcReadVer.c | 2 +- 6 files changed, 125 insertions(+), 66 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 0a17cfe6..21ba73a3 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -304,7 +304,8 @@ extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type ); extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose ); extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq ); -extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ); +extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ); +extern Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ); extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p ); extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis ); extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8662e509..ce6b8de9 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -173,7 +173,7 @@ Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) if ( vNodes != vNodesInit ) Vec_IntFree( vNodes ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } @@ -277,7 +277,7 @@ Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) if ( vPairs != vPairsInit ) Vec_IntFree( vPairs ); // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1, NULL ); + pNew = Wlc_NtkDupDfs( p, 0, 1 ); return pNew; } diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c index 9da59f42..f5a7b46d 100644 --- a/src/base/wlc/wlcAbs2.c +++ b/src/base/wlc/wlcAbs2.c @@ -52,11 +52,11 @@ struct Wabs_Par_t_ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) { memset( pPars, 0, sizeof(Wlc_Par_t) ); - pPars->nBitsAdd = 16; // adder bit-width - pPars->nBitsMul = 8; // multiplier bit-widht - pPars->nBitsMux = 32; // MUX bit-width - pPars->nBitsFlop = 32; // flop bit-width - pPars->fVerbose = 0; // verbose output` + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->fVerbose = 0; // verbose output` } /**Function************************************************************* @@ -73,40 +73,41 @@ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); - Wlc_Obj_t * pObj; int i; + Wlc_Obj_t * pObj; int i, Count[4] = {0}; Wlc_NtkForEachObj( p, pObj, i ) { if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++; continue; } if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++; continue; } if ( pObj->Type == WLC_OBJ_MUX ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++; continue; } if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) - Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ); + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++; continue; } } + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); return vLeaves; } /**Function************************************************************* - Synopsis [] + Synopsis [Marks nodes to be included in the abstracted network.] Description [] @@ -115,7 +116,7 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vFlops, Vec_Int_t * vPisNew ) +void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { int i, iFanin; if ( pObj->Mark ) @@ -123,42 +124,45 @@ void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeav pObj->Mark = 1; if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) { + assert( !Wlc_ObjIsPi(pObj) ); Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); return; } if ( Wlc_ObjIsCi(pObj) ) { - if ( !Wlc_ObjIsPi(pObj) ) - Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) ); + if ( Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) ); + else + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); return; } Wlc_ObjForEachFanin( pObj, iFanin, i ) - Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vFlops, vPisNew ); + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); } -Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) +void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { - Vec_Int_t * vFlops; - Vec_Int_t * vPisNew; Wlc_Obj_t * pObj; - int i, CiId, CoId; + int i, Count = 0; Wlc_NtkCleanMarks( p ); - vFlops = Vec_IntAlloc( 100 ); - vPisNew = Vec_IntAlloc( 100 ); Wlc_NtkForEachCo( p, pObj, i ) - Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vFlops, vPisNew ); - Vec_IntForEachEntry( vFlops, CiId, i ) - { - CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p); - Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkCo(p, CoId), vLeaves, vFlops, vPisNew ); - } - Vec_IntFree( vFlops ); - return vPisNew; + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObj( p, pObj, i ) + Count += pObj->Mark; +// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n", +// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops), +// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) ); + Vec_IntSort( vPisOld, 0 ); + Vec_IntSort( vPisNew, 0 ); + Vec_IntSort( vFlops, 0 ); + Wlc_NtkCleanMarks( p ); } /**Function************************************************************* - Synopsis [] + Synopsis [Derive abstraction based on the parameter values.] Description [] @@ -169,11 +173,17 @@ Vec_Int_t * Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves ) ***********************************************************************/ Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { + Wlc_Ntk_t * pNtkNew = NULL; + Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); + Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); + Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); - Vec_Int_t * vPisNew = Wlc_NtkAbsMarkNodes( p, vLeaves ); - Wlc_Ntk_t * pNtkNew = Wlc_NtkDupDfs( p, 1, 1, vPisNew ); - Vec_IntFree( vPisNew ); + Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); Vec_BitFree( vLeaves ); + pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); + Vec_IntFree( vPisOld ); + Vec_IntFree( vPisNew ); + Vec_IntFree( vFlops ); return pNtkNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index cc69c636..346a9076 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -423,7 +423,7 @@ int Abc_CommandCone( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Extracting output %d as a %s word-level network.\n", iOutput, fSeq ? "sequential" : "combinational" ); pName = Wlc_NtkNewName( pNtk, iOutput, fSeq ); Wlc_NtkMarkCone( pNtk, iOutput, Range, fSeq, fAllPis ); - pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq, NULL ); + pNtk = Wlc_NtkDupDfs( pNtk, 1, fSeq ); ABC_FREE( pNtk->pName ); pNtk->pName = Abc_UtilStrsav( pName ); Wlc_AbcUpdateNtk( pAbc, pNtk ); @@ -941,6 +941,7 @@ usage: ******************************************************************************/ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) { + abctime clk = Abc_Clock(); extern int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose ); int c, nFailed, fVerbose = 0; Extra_UtilGetoptReset(); @@ -974,9 +975,10 @@ int Abc_CommandInvCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) } nFailed = Pdr_InvCheck( pAbc->pGia, Wlc_AbcGetInv(pAbc), fVerbose ); if ( nFailed ) - printf( "Invariant verification failed for %d clauses (out of %d).\n", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); + printf( "Invariant verification failed for %d clauses (out of %d). ", nFailed, Vec_IntEntry(Wlc_AbcGetInv(pAbc),0) ); else - printf( "Invariant verification succeeded.\n" ); + printf( "Invariant verification succeeded. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); return 0; usage: Abc_Print( -2, "usage: inv_check [-vh]\n" ); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 6eab4442..86b0c17e 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -648,7 +648,7 @@ void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose printf( "PI = %4d ", Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) ); printf( "PO = %4d ", Wlc_NtkPoNum(p) ); printf( "FF = %4d ", Wlc_NtkFfNum(p) ); - printf( "Obj = %6d ", Wlc_NtkObjNum(p) ); + printf( "Obj = %6d ", Wlc_NtkObjNum(p) - Wlc_NtkPiNum(p) - Wlc_NtkPoNum(p) - Wlc_NtkFfNum(p) ); printf( "Mem = %.3f MB", 1.0*Wlc_NtkMemUsage(p)/(1<<20) ); printf( "\n" ); if ( fDistrib ) @@ -723,7 +723,7 @@ Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit ) assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) ); Wlc_NtkForEachCi( p, pObj, i ) if ( !Wlc_ObjIsPi(pObj) && pObj->Mark ) - Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i) ); + Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i - Wlc_NtkPiNum(p)) ); Vec_IntShrink( vInitNew, k ); return vInitNew; } @@ -803,7 +803,7 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); } -Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPisNew ) +Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) { Wlc_Ntk_t * pNew; Wlc_Obj_t * pObj; @@ -813,33 +813,14 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPi Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); pNew->fSmtLib = p->fSmtLib; - if ( vPisNew ) - { - // duplicate marked PIs - Wlc_NtkForEachPi( p, pObj, i ) - if ( pObj->Mark ) - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); - // duplicated additional PIs - Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + Wlc_NtkForEachCi( p, pObj, i ) + if ( !fMarked || pObj->Mark ) { unsigned Type = pObj->Type; - assert( !Wlc_ObjIsPi(pObj) ); - pObj->Type = WLC_OBJ_PI; + if ( !fSeq ) pObj->Type = WLC_OBJ_PI; Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); pObj->Type = Type; } - } - else - { - Wlc_NtkForEachCi( p, pObj, i ) - if ( !fMarked || pObj->Mark ) - { - unsigned Type = pObj->Type; - if ( !fSeq ) pObj->Type = WLC_OBJ_PI; - Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); - pObj->Type = Type; - } - } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); @@ -865,7 +846,72 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq, Vec_Int_t * vPi } } if ( p->pSpec ) - pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Wlc_NtkTransferNames( pNew, p ); + return pNew; +} +Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +{ + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + Vec_Int_t * vFanins; + int i; + Wlc_NtkCleanCopy( p ); + pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); + pNew->fSmtLib = p->fSmtLib; + + // duplicate marked PIs + vFanins = Vec_IntAlloc( 100 ); + Wlc_NtkForEachObjVec( vPisOld, p, pObj, i ) + { + assert( Wlc_ObjIsPi(pObj) ); + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + } + // duplicate additional PIs + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + { + unsigned Type = pObj->Type; + int nFanins = Wlc_ObjFaninNum(pObj); + assert( !Wlc_ObjIsPi(pObj) ); + pObj->Type = WLC_OBJ_PI; + pObj->nFanins = 0; + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + pObj->Type = Type; + pObj->nFanins = (unsigned)nFanins; + } + // duplicate flop outputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + { + assert( !Wlc_ObjIsPi(pObj) && Wlc_ObjIsCi(pObj) ); + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + } + + // duplicate logic cones of primary outputs + Wlc_NtkForEachPo( p, pObj, i ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + // duplidate logic cone of flop inputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj)), vFanins ); + + // duplicate POs + Wlc_NtkForEachPo( p, pObj, i ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), 0 ); + // duplicate flop inputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, Wlc_ObjFo2Fi(p, pObj)), 1 ); + Vec_IntFree( vFanins ); + + // mark flop outputs + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + pObj->Mark = 1; + if ( p->vInits ) + pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits ); + if ( p->pInits ) + pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits ); + Wlc_NtkCleanMarks( p ); + + if ( p->pSpec ) + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Wlc_NtkTransferNames( pNew, p ); return pNew; } diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index f7546b5b..e4a65ecf 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1265,7 +1265,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) if ( !Wlc_PrsDerive( p ) ) goto finish; // derive topological order - pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1, NULL ); + pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); finish: Wlc_PrsPrintErrorMessage( p ); -- cgit v1.2.3 From d335ee096e902844b9a94076e8ce5855f74d9bde Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 11:05:00 -0800 Subject: Standardizing the use of new CNF generator. Adding CNF variable connectivity information. --- src/base/abci/abcCollapse.c | 4 +--- src/base/abci/abcDetect.c | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c index 8c2b3b39..1542c25a 100644 --- a/src/base/abci/abcCollapse.c +++ b/src/base/abci/abcCollapse.c @@ -537,8 +537,6 @@ extern Vec_Wec_t * Gia_ManCreateCoSupps( Gia_Man_t * p, int fVerbose ); extern int Gia_ManCoLargestSupp( Gia_Man_t * p, Vec_Wec_t * vSupps ); extern Vec_Wec_t * Gia_ManIsoStrashReduceInt( Gia_Man_t * p, Vec_Wec_t * vSupps, int fVerbose ); -extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - /**Function************************************************************* Synopsis [Derives GIA for the network.] @@ -802,7 +800,7 @@ Vec_Ptr_t * Abc_GiaDeriveSops( Abc_Ntk_t * pNtkNew, Gia_Man_t * p, Vec_Wec_t * v if ( fCnfShared ) { vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); - pCnf = Mf_ManGenerateCnf( p, 8, 1, 0, 0 ); + pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 1, 0, 0, 0 ); } vSopsRepr = Vec_PtrStart( Vec_IntSize(vReprs) ); pProgress = Extra_ProgressBarStart( stdout, Vec_IntSize(vReprs) ); diff --git a/src/base/abci/abcDetect.c b/src/base/abci/abcDetect.c index 8b8bba64..7adbed5d 100644 --- a/src/base/abci/abcDetect.c +++ b/src/base/abci/abcDetect.c @@ -901,8 +901,7 @@ Vec_Int_t * Abc_NtkFinCheckPair( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t } else { - extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); - Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { -- cgit v1.2.3 From f2d096c9f04acf95e959842d63b6febf2f8eb786 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 13:20:20 -0800 Subject: Improving CEX minimization. --- src/base/io/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/io/io.c b/src/base/io/io.c index 4cec0157..c2cf15d4 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv ) Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose ); } else - pCare = Bmc_CexCareMinimize( pAig, pCex, fCheckCex, fVerbose ); + pCare = Bmc_CexCareMinimize( pAig, 0, pCex, fCheckCex, fVerbose ); Aig_ManStop( pAig ); } // output flop values (unaffected by the minimization) -- cgit v1.2.3 From fce2b16a602dcdd3bef8529e51f9a06c2aaf1fec Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 13:31:29 -0800 Subject: Re-introducing floating-point activity in the SAT solver. --- src/base/abci/abc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 26e9c0f8..72fcafe2 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26157,7 +26157,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegoncvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26308,6 +26308,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'c': pPars->fCtgs ^= 1; break; + case 't': + pPars->fUseAbs ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26349,7 +26352,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegoncvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26378,6 +26381,7 @@ usage: Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); -- cgit v1.2.3 From 342d2d9f5cd3f89289d84e2dc695516ec959e252 Mon Sep 17 00:00:00 2001 From: Bruno Schmitt Date: Fri, 10 Feb 2017 17:26:45 -0800 Subject: New fixed point data type. Expose all options to command line. Expose search statistics to users. --- src/base/abci/abc.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 214 insertions(+), 4 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 26e9c0f8..ea0ed377 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23326,7 +23326,11 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Chv" ) ) != EOF ) +#ifdef SATOKO_ACT_VAR_FIXED + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) +#else + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) +#endif { switch ( c ) { @@ -23341,6 +23345,184 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( opts.conf_limit < 0 ) goto usage; break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + opts.prop_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.prop_limit < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); + goto usage; + } + opts.f_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.f_rst < 0 ) + goto usage; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); + goto usage; + } + opts.b_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.b_rst < 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; + } + opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + goto usage; + } + opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + goto usage; + } + opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'J': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); + goto usage; + } + opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + goto usage; + } + opts.lbd_freeze_clause = (unsigned)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; + } + opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.learnt_ratio < 0 ) + goto usage; + break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.garbage_max_ratio < 0 ) + goto usage; + break; + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); + goto usage; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); + goto usage; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + goto usage; + break; +#ifdef SATOKO_ACT_VAR_FIXED + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); + goto usage; + } + opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; + case 'U': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); + goto usage; + } + opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; +#endif case 'h': goto usage; case 'v': @@ -23379,9 +23561,37 @@ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) } usage: - Abc_Print( -2, "usage: satoko [-CILDE num] [-hv].cnf\n" ); +#ifdef SATOKO_ACT_VAR_FIXED + Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRSTU num] [-hv].cnf\n" ); +#else + Abc_Print( -2, "usage: satoko [-CPDEFGHIJKLMNOQRS num] [-hv].cnf\n" ); +#endif Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); - Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); + Abc_Print( -2, "\t-P num : limit on the number of propagations [default = %d]\n", opts.conf_limit ); + Abc_Print( -2, "\n\tConstants used for restart heuristic:\n"); + Abc_Print( -2, "\t-D num : Constant value used by restart heuristics in forcing restarts [default = %f]\n", opts.f_rst ); + Abc_Print( -2, "\t-E num : Constant value used by restart heuristics in blocking restarts [default = %f]\n", opts.b_rst ); + Abc_Print( -2, "\t-F num : Lower bound n.of conflicts for start blocking restarts [default = %d]\n", opts.fst_block_rst ); + Abc_Print( -2, "\t-G num : Size of the moving avarege queue for LBD (force restart) [default = %d]\n", opts.sz_lbd_bqueue ); + Abc_Print( -2, "\t-H num : Size of the moving avarege queue for Trail size (block restart) [default = %d]\n", opts.sz_trail_bqueue ); + Abc_Print( -2, "\n\tConstants used for clause database reduction heuristic:\n"); + Abc_Print( -2, "\t-I num : N.of conflicts before first clause databese reduction [default = %d]\n", opts.n_conf_fst_reduce ); + Abc_Print( -2, "\t-J num : Increment to reduce [default = %d]\n", opts.inc_reduce ); + Abc_Print( -2, "\t-K num : Special increment to reduce [default = %d]\n", opts.inc_special_reduce ); + Abc_Print( -2, "\t-L num : Protecs clauses from deletion for one turn if its LBD is lower [default = %d]\n", opts.lbd_freeze_clause ); + Abc_Print( -2, "\t-M num : Percentage of learned clauses to remove [default = %d]\n", ( int )( 100 * opts.learnt_ratio ) ); + Abc_Print( -2, "\t-N num : Max percentage of garbage in clause database [default = %d]\n", ( int )( 100 * opts.garbage_max_ratio ) ); + Abc_Print( -2, "\n\tConstants used for binary resolution (clause minimization):\n"); + Abc_Print( -2, "\t-O num : Max clause size for binary resolution [default = %d]\n", opts.clause_max_sz_bin_resol ); + Abc_Print( -2, "\t-Q num : Min clause LBD for binary resolution [default = %d]\n", opts.clause_min_lbd_bin_resol ); + Abc_Print( -2, "\n\tConstants used for branching (VSIDS heuristic):\n"); + Abc_Print( -2, "\t-R num : Clause activity decay factor (when using float clause activity) [default = %f]\n", opts.clause_decay ); + Abc_Print( -2, "\t-S num : Varibale activity decay factor [default = %f]\n", opts.var_decay ); +#ifdef SATOKO_ACT_VAR_FIXED + Abc_Print( -2, "\t-T num : Variable activity limit valeu [default = 0x%08X]\n", opts.var_act_limit ); + Abc_Print( -2, "\t-U num : Variable activity re-scale factor [default = 0x%08X]\n", opts.var_act_rescale ); +#endif + Abc_Print( -2, "\n\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -38219,7 +38429,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fExtractAll ) { char Buffer[1000]; - Gia_Obj_t * pObj; + Gia_Obj_t * pObj; int i, nDigits = Abc_Base10Log(Gia_ManPoNum(pAbc->pGia)); Gia_ManForEachPo( pAbc->pGia, pObj, i ) { -- cgit v1.2.3 From 8bff9aa1cd118028db47d886254dc4c76c516166 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 17:36:20 -0800 Subject: Adding PDR with abstraction. --- src/base/io/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/io/io.c b/src/base/io/io.c index c2cf15d4..2e1ae591 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2420,7 +2420,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv ) Bmc_CexCareVerify( pAig, pCex, pCare, fVerbose ); } else - pCare = Bmc_CexCareMinimize( pAig, 0, pCex, fCheckCex, fVerbose ); + pCare = Bmc_CexCareMinimize( pAig, Saig_ManPiNum(pAig), pCex, 4, fCheckCex, fVerbose ); Aig_ManStop( pAig ); } // output flop values (unaffected by the minimization) -- cgit v1.2.3 From 5d717256d3b856d8f29c4a5e442af624f0b0bb69 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Feb 2017 18:14:06 -0800 Subject: Updates to the autotuner. --- src/base/abci/abc.c | 220 +++---------------------------------------------- src/base/cmd/cmdAuto.c | 209 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 196 insertions(+), 233 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 933f9778..f10be02b 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23320,222 +23320,22 @@ usage: ***********************************************************************/ int Abc_CommandSatoko( Abc_Frame_t * pAbc, int argc, char ** argv ) { - abctime clk; - int c; - satoko_opts_t opts; + extern satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ); + // create default options + satoko_opts_t opts, * popts; satoko_default_opts(&opts); - Extra_UtilGetoptReset(); -#ifdef SATOKO_ACT_VAR_FIXED - while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) -#else - while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) -#endif - { - switch ( c ) - { - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - opts.conf_limit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.conf_limit < 0 ) - goto usage; - break; - case 'P': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); - goto usage; - } - opts.prop_limit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.prop_limit < 0 ) - goto usage; - break; - case 'D': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); - goto usage; - } - opts.f_rst = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.f_rst < 0 ) - goto usage; - break; - case 'E': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); - goto usage; - } - opts.b_rst = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.b_rst < 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; - } - opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'G': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); - goto usage; - } - opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'H': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); - goto usage; - } - opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'I': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); - goto usage; - } - opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'J': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); - goto usage; - } - opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'K': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); - goto usage; - } - opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'L': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); - goto usage; - } - opts.lbd_freeze_clause = (unsigned)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; - } - opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; - globalUtilOptind++; - if ( opts.learnt_ratio < 0 ) - goto usage; - break; - case 'N': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; - globalUtilOptind++; - if ( opts.garbage_max_ratio < 0 ) - goto usage; - break; - case 'O': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); - goto usage; - } - opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'Q': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); - goto usage; - } - opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); - globalUtilOptind++; - break; - case 'R': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); - goto usage; - } - opts.clause_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.clause_decay < 0 ) - goto usage; - break; - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); - goto usage; - } - opts.var_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.var_decay < 0 ) - goto usage; - break; -#ifdef SATOKO_ACT_VAR_FIXED - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); - goto usage; - } - opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); - globalUtilOptind++; - break; - case 'U': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); - goto usage; - } - opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); - globalUtilOptind++; - break; -#endif - case 'h': - goto usage; - case 'v': - opts.verbose ^= 1; - break; - default: - goto usage; - } - } + // override default options + popts = Cmd_DeriveOptionFromSettings( argc, argv ); + if ( popts == NULL ) + goto usage; + memcpy( &opts, popts, sizeof(satoko_opts_t) ); + ABC_FREE( popts ); if ( argc == globalUtilOptind + 1 ) { + abctime clk; char * pFileName = argv[globalUtilOptind]; satoko_t * p; int status; diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index 35f155fa..e279b19d 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -241,7 +241,11 @@ satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) satoko_opts_t opts, * pOpts; satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CVWhv" ) ) != EOF ) +#ifdef SATOKO_ACT_VAR_FIXED + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRSTUhv" ) ) != EOF ) +#else + while ( ( c = Extra_UtilGetopt( argc, argv, "CPDEFGHIJKLMNOQRShv" ) ) != EOF ) +#endif { switch ( c ) { @@ -256,31 +260,190 @@ satoko_opts_t * Cmd_DeriveOptionFromSettings( int argc, char ** argv ) if ( opts.conf_limit < 0 ) return NULL; break; - case 'V': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-V\" should be followed by an integer.\n" ); - return NULL; - } - opts.var_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.var_decay < 0 ) - return NULL; - break; - case 'W': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); - return NULL; - } - opts.clause_decay = atof(argv[globalUtilOptind]); - globalUtilOptind++; - if ( opts.clause_decay < 0 ) - return NULL; - break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + return NULL; + } + opts.prop_limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.prop_limit < 0 ) + return NULL; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an float.\n" ); + return NULL; + } + opts.f_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.f_rst < 0 ) + return NULL; + break; + case 'E': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-E\" should be followed by an float.\n" ); + return NULL; + } + opts.b_rst = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.b_rst < 0 ) + return NULL; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + return NULL; + } + opts.fst_block_rst = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + return NULL; + } + opts.sz_lbd_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + return NULL; + } + opts.sz_trail_bqueue = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + return NULL; + } + opts.n_conf_fst_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'J': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-J\" should be followed by an integer.\n" ); + return NULL; + } + opts.inc_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + return NULL; + } + opts.inc_special_reduce = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'L': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" ); + return NULL; + } + opts.lbd_freeze_clause = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + return NULL; + } + opts.learnt_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.learnt_ratio < 0 ) + return NULL; + break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + return NULL; + } + opts.garbage_max_ratio = atof(argv[globalUtilOptind]) / 100; + globalUtilOptind++; + if ( opts.garbage_max_ratio < 0 ) + return NULL; + break; + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_max_sz_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + return NULL; + } + opts.clause_min_lbd_bin_resol = (unsigned)atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an float.\n" ); + return NULL; + } + opts.clause_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.clause_decay < 0 ) + return NULL; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an float.\n" ); + return NULL; + } + opts.var_decay = atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( opts.var_decay < 0 ) + return NULL; + break; +#ifdef SATOKO_ACT_VAR_FIXED + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an float.\n" ); + return NULL; + } + opts.var_act_limit = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; + case 'U': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-U\" should be followed by an float.\n" ); + return NULL; + } + opts.var_act_rescale = (unsigned)strtol(argv[globalUtilOptind], NULL, 16); + globalUtilOptind++; + break; +#endif + case 'h': + return NULL; case 'v': opts.verbose ^= 1; break; + default: return NULL; } -- cgit v1.2.3 From 2a5fa67d36393ab3ddb14e5bf542b0f29c8634e1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 11 Feb 2017 17:28:37 -0800 Subject: Adding APIs to mark cones. Creating test-bench for incremental solving &satoko -i. --- src/base/abci/abc.c | 14 +++++++++----- src/base/cmd/cmdAuto.c | 6 +++--- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f10be02b..bb0b8c8d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -23410,13 +23410,13 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Gia_ManCallSatoko( Gia_Man_t * p, satoko_opts_t * opts, int fSplit ); - int c, fSplit = 0; + extern void Gia_ManSatokoCall( Gia_Man_t * p, satoko_opts_t * opts, int fSplit, int fIncrem ); + int c, fSplit = 0, fIncrem = 0; satoko_opts_t opts; satoko_default_opts(&opts); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Csvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Csivh" ) ) != EOF ) { switch ( c ) { @@ -23434,6 +23434,9 @@ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) case 's': fSplit ^= 1; break; + case 'i': + fIncrem ^= 1; + break; case 'v': opts.verbose ^= 1; break; @@ -23449,13 +23452,14 @@ int Abc_CommandAbc9Satoko( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" ); return 1; } - Gia_ManCallSatoko( pAbc->pGia, &opts, fSplit ); + Gia_ManSatokoCall( pAbc->pGia, &opts, fSplit, fIncrem ); return 0; usage: - Abc_Print( -2, "usage: &satoko [-C num] [-svh]\n" ); + Abc_Print( -2, "usage: &satoko [-C num] [-sivh]\n" ); Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", opts.conf_limit ); Abc_Print( -2, "\t-s : split multi-output miter into individual outputs [default = %s]\n", fSplit? "yes": "no" ); + Abc_Print( -2, "\t-i : split multi-output miter and solve incrementally [default = %s]\n", fIncrem? "yes": "no" ); Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", opts.verbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/cmd/cmdAuto.c b/src/base/cmd/cmdAuto.c index e279b19d..8151c2e5 100644 --- a/src/base/cmd/cmdAuto.c +++ b/src/base/cmd/cmdAuto.c @@ -47,7 +47,7 @@ ABC_NAMESPACE_IMPL_START #define CMD_AUTO_LINE_MAX 1000 // max number of chars in the string #define CMD_AUTO_ARG_MAX 100 // max number of arguments in the call -extern int Gia_ManCallSatokoOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); +extern int Gia_ManSatokoCallOne( Gia_Man_t * p, satoko_opts_t * opts, int iOutput ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -92,7 +92,7 @@ int Cmd_RunAutoTunerEvalSimple( Vec_Ptr_t * vAigs, satoko_opts_t * pOpts ) //printf( "Tuning with options: " ); //Cmd_RunAutoTunerPrintOptions( pOpts ); Vec_PtrForEachEntry( Gia_Man_t *, vAigs, pGia, i ) - TotalCost += Gia_ManCallSatokoOne( pGia, pOpts, -1 ); + TotalCost += Gia_ManSatokoCallOne( pGia, pOpts, -1 ); return TotalCost; } @@ -142,7 +142,7 @@ void * Cmd_RunAutoTunerEvalWorkerThread( void * pArg ) assert( 0 ); return NULL; } - pThData->Result = Gia_ManCallSatokoOne( pThData->pGia, pThData->pOpts, -1 ); + pThData->Result = Gia_ManSatokoCallOne( pThData->pGia, pThData->pOpts, -1 ); pThData->fWorking = 0; } assert( 0 ); -- cgit v1.2.3 From ab387953ab3a50200384f5619cf999e3f729f28f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 15 Feb 2017 17:16:19 -0800 Subject: Word-level abstraction engine. --- src/base/abci/abc.c | 10 +- src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 25 ++- src/base/wlc/wlcAbs.c | 484 +++++++++++++++++++++++++++++------------------ src/base/wlc/wlcAbs2.c | 298 +++++++++++++++++++++++++---- src/base/wlc/wlcBlast.c | 2 +- src/base/wlc/wlcCom.c | 143 +++++++++++++- src/base/wlc/wlcNtk.c | 91 ++++++++- src/base/wlc/wlcUif.c | 290 ++++++++++++++++++++++++++++ 9 files changed, 1101 insertions(+), 243 deletions(-) create mode 100644 src/base/wlc/wlcUif.c (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index bb0b8c8d..af5d0ccf 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDRTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26219,10 +26219,10 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nConfGenLimit < 0 ) goto usage; break; - case 'R': + case 'Q': if ( globalUtilOptind >= argc ) { - Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); + Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); goto usage; } pPars->nRestLimit = atoi(argv[globalUtilOptind]); @@ -26366,7 +26366,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDRTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26374,7 +26374,7 @@ usage: Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); - Abc_Print( -2, "\t-R num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); + Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index 3485bd4d..c4330264 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -10,5 +10,6 @@ SRC += src/base/wlc/wlcAbs.c \ src/base/wlc/wlcSim.c \ src/base/wlc/wlcShow.c \ src/base/wlc/wlcStdin.c \ + src/base/wlc/wlcUif.c \ src/base/wlc/wlcWin.c \ src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 21ba73a3..91dc0573 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -158,6 +158,7 @@ struct Wlc_Ntk_t_ Vec_Int_t vCopies; // object first bits Vec_Int_t vBits; // object mapping into AIG nodes Vec_Int_t vLevels; // object levels + Vec_Int_t vRefs; // object reference counters }; typedef struct Wlc_Par_t_ Wlc_Par_t; @@ -167,7 +168,10 @@ struct Wlc_Par_t_ int nBitsMul; // multiplier bit-widht int nBitsMux; // MUX bit-width int nBitsFlop; // flop bit-width - int fVerbose; // verbose output` + int nIterMax; // the max number of iterations + int fXorOutput; // XOR outputs of word-level miter + int fVerbose; // verbose output + int fPdrVerbose; // verbose output }; static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } @@ -272,19 +276,15 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) //////////////////////////////////////////////////////////////////////// /*=== wlcAbs.c ========================================================*/ -extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ); -extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); -extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); -extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); -extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); +extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ -extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); -extern Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, int nRange, int fGiaSimple, int fAddOutputs, int fBooth ); /*=== wlcCom.c ========================================================*/ extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ +extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); @@ -311,6 +311,9 @@ extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p ); extern Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p ); extern void Wlc_NtkShortNames( Wlc_Ntk_t * p ); +extern int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p ); +extern void Wlc_NtkSetRefs( Wlc_Ntk_t * p ); +extern int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit, int fOldParser, int fPrintTree ); extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName, int fOldParser, int fPrintTree ); @@ -321,6 +324,12 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p ); extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd ); /*=== wlcReadVer.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ); +/*=== wlcUif.c ========================================================*/ +extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ); +extern Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ); +extern Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ); +extern Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * pNtk, Vec_Int_t * vNodes ); +extern Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * pNtk, Vec_Int_t * vPairs ); /*=== wlcWin.c =============================================================*/ extern void Wlc_WinProfileArith( Wlc_Ntk_t * p ); /*=== wlcWriteVer.c ========================================================*/ diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index ce6b8de9..318df4dd 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [wlcAbs.c] + FileName [wlcAbs1.c] SystemName [ABC: Logic synthesis and verification system.] @@ -14,11 +14,14 @@ Date [Ver. 1.0. Started - August 22, 2014.] - Revision [$Id: wlcAbs.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + Revision [$Id: wlcAbs1.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] ***********************************************************************/ #include "wlc.h" +#include "proof/pdr/pdr.h" +#include "aig/gia/giaAig.h" +#include "sat/bmc/bmc.h" ABC_NAMESPACE_IMPL_START @@ -32,253 +35,370 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* - Synopsis [Check if two objects have the same input/output signatures.] + Synopsis [Mark operators that meet the abstraction criteria.] - Description [] + Description [This procedure returns the array of objects (vLeaves) that + should be abstracted because of their high bit-width. It uses input array (vUnmark) + to not abstract those objects that have been refined in the previous rounds.] SideEffects [] SeeAlso [] ***********************************************************************/ -int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { - Wlc_Obj_t * pFanin, * pFanin2; int k; - if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) ) - return 0; - if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) ) - return 0; - if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) ) - return 0; - for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ ) + Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + Wlc_Obj_t * pObj; int i, Count[4] = {0}; + Wlc_NtkForEachObj( p, pObj, i ) { - pFanin = Wlc_ObjFanin(p, pObj, k); - pFanin2 = Wlc_ObjFanin(p, pObj2, k); - if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) ) - return 0; - if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) ) - return 0; + if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away + continue; + if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++; + continue; + } + if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++; + continue; + } + if ( pObj->Type == WLC_OBJ_MUX ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++; + continue; + } + if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) ) + { + if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop ) + Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++; + continue; + } } - return 1; + if ( fVerbose ) + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); + return vLeaves; } /**Function************************************************************* - Synopsis [Collect IDs of the multipliers.] + Synopsis [Marks nodes to be included in the abstracted network.] - Description [] + Description [Marks all objects that will be included in the abstracted model. + Stops at the objects (vLeaves) that are abstracted away. Returns three arrays: + a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the + set of flops present as flops in the abstracted network.] SideEffects [] SeeAlso [] ***********************************************************************/ -Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ) +static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +{ + int i, iFanin; + if ( pObj->Mark ) + return; + pObj->Mark = 1; + if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) ) + { + assert( !Wlc_ObjIsPi(pObj) ); + Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) ); + return; + } + if ( Wlc_ObjIsCi(pObj) ) + { + if ( Wlc_ObjIsPi(pObj) ) + Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) ); + else + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); + return; + } + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); +} +static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { - Wlc_Obj_t * pObj; int i; - Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 ); + Wlc_Obj_t * pObj; + int i, Count = 0; + Wlc_NtkCleanMarks( p ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) + Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); Wlc_NtkForEachObj( p, pObj, i ) - if ( pObj->Type == WLC_OBJ_ARI_MULTI ) - Vec_IntPush( vBoxIds, i ); - if ( Vec_IntSize( vBoxIds ) > 0 ) - return vBoxIds; - Vec_IntFree( vBoxIds ); - return NULL; + Count += pObj->Mark; +// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n", +// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops), +// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) ); + Vec_IntSort( vPisOld, 0 ); + Vec_IntSort( vPisNew, 0 ); + Vec_IntSort( vFlops, 0 ); + Wlc_NtkCleanMarks( p ); } /**Function************************************************************* - Synopsis [Returns all pairs of uifable multipliers.] + Synopsis [Derive word-level abstracted model based on the parameter values.] - Description [] + Description [Retuns the word-level abstracted network and the set of pseudo-PIs + (vPisNew), which were created during abstraction. If the abstraction is + satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs + and their MFFC cones will be listed in the array (vUnmark), which will + force the abstraction to not stop at these pseudo-PIs in the future.] SideEffects [] SeeAlso [] ***********************************************************************/ -Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { - Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p ); - Vec_Int_t * vPairs = Vec_IntAlloc( 2 ); - Wlc_Obj_t * pObj, * pObj2; int i, k; - // iterate through unique pairs - Wlc_NtkForEachObjVec( vMultis, p, pObj, i ) - Wlc_NtkForEachObjVec( vMultis, p, pObj2, k ) - { - if ( k == i ) - break; - if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) ) - { - Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) ); - Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) ); - } - } - Vec_IntFree( vMultis ); - if ( Vec_IntSize( vPairs ) > 0 ) - return vPairs; - Vec_IntFree( vPairs ); - return NULL; + Wlc_Ntk_t * pNtkNew = NULL; + Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); + Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); + Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose ); + Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); + Vec_BitFree( vLeaves ); + pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); + Vec_IntFree( vPisOld ); + Vec_IntFree( vFlops ); + if ( pvPisNew ) + *pvPisNew = vPisNew; + else + Vec_IntFree( vPisNew ); + return pNtkNew; } +/**Function************************************************************* + + Synopsis [Find what objects need to be un-abstracted.] + Description [Returns a subset of pseudo-PIs (vPisNew), which will be + prevented from being abstracted in the future rounds of abstraction. + The AIG manager (pGia) is a bit-level view of the abstracted model. + The counter-example (pCex) is used to find waht PPIs to refine.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew ) +{ + Vec_Int_t * vRefine = Vec_IntAlloc( 100 ); + Abc_Cex_t * pCexCare; + Wlc_Obj_t * pObj; + // count the number of bit-level PPIs and map them into word-level objects they were derived from + int f, i, b, nRealPis, nPpiBits = 0; + Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis ); + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) ); + // since PPIs are ordered last, the previous bits are real PIs + nRealPis = pCex->nPis - nPpiBits; + // find the care-set + pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 ); + assert( pCexCare->nPis == pCex->nPis ); + // detect care PPIs + for ( f = 0; f <= pCexCare->iFrame; f++ ) + for ( i = nRealPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) ); + Abc_CexFree( pCexCare ); + Vec_IntFree( vMap ); + if ( Vec_IntSize(vRefine) == 0 )// real CEX + Vec_IntFreeP( &vRefine ); + return vRefine; +} /**Function************************************************************* - Synopsis [Abstracts nodes by replacing their outputs with new PIs.] + Synopsis [Mark MFFC cones of the un-abstracted objects.] - Description [If array is NULL, abstract all multipliers.] + Description [The MFFC cones of the objects in vRefine are traversed + and all their nodes are marked in vUnmark.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) +static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) { - Vec_Int_t * vNodes = vNodesInit; - Wlc_Ntk_t * pNew; - Wlc_Obj_t * pObj; - int i, k, iObj, iFanin; - // get multipliers if not given - if ( vNodes == NULL ) - vNodes = Wlc_NtkCollectMultipliers( p ); - if ( vNodes == NULL ) - return NULL; - // mark nodes - Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) - pObj->Mark = 1; - // iterate through the nodes in the DFS order - Wlc_NtkCleanCopy( p ); - Wlc_NtkForEachObj( p, pObj, i ) + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + Wlc_ObjForEachFanin( pNode, Fanin, i ) { - if ( i == Vec_IntSize(&p->vCopies) ) - break; - if ( pObj->Mark ) { - // clean - pObj->Mark = 0; - // add fresh PI with the same number of bits - iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ); - } - else { - // update fanins - Wlc_ObjForEachFanin( pObj, iFanin, k ) - Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin); - // node to remain - iObj = i; - } - Wlc_ObjSetCopy( p, i, iObj ); + Vec_IntAddToEntry( &p->vRefs, Fanin, -1 ); + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark ); + } + return Counter; +} +static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Wlc_ObjForEachFanin( pNode, Fanin, i ) + { + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) ); + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); } - // POs do not change in this procedure - if ( vNodes != vNodesInit ) - Vec_IntFree( vNodes ); - // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); - return pNew; + return Counter; +} +static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int Count1, Count2; + // if this is a flop output, compute MFFC of the corresponding flop input + while ( Wlc_ObjIsCi(pNode) ) + { + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + pNode = Wlc_ObjFo2Fi(p, pNode); + } + assert( !Wlc_ObjIsCi(pNode) ); + // dereference the node (and set the bits in vUnmark) + Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark ); + // reference it back + Count2 = Wlc_NtkNodeRef_rec( p, pNode ); + assert( Count1 == Count2 ); + return Count1; +} +static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark ) +{ + Wlc_Obj_t * pObj; int i, nNodes = 0; + if ( Vec_IntSize(&p->vRefs) == 0 ) + Wlc_NtkSetRefs( p ); + Wlc_NtkForEachObjVec( vRefine, p, pObj, i ) + nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark ); + return nNodes; } /**Function************************************************************* - Synopsis [Adds UIF constraints to node pairs and updates POs.] + Synopsis [Performs abstraction.] - Description [] + Description [Derives initial abstraction based on user-specified + parameter values, which tell what is the smallest bit-width of a + primitive that is being abstracted away. Currently only add/sub, + mul/div, mux, and flop are supported with individual parameters. + The second step is to refine the initial abstraction until the + point when the property is proved.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) +int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { - Vec_Int_t * vPairs = vPairsInit; - Wlc_Ntk_t * pNew; - Wlc_Obj_t * pObj, * pObj2; - Vec_Int_t * vUifConstrs, * vCompares, * vFanins; - int i, k, iObj, iObj2, iObjNew, iObjNew2; - int iFanin, iFanin2, iFaninNew; - // get multiplier pairs if not given - if ( vPairs == NULL ) - vPairs = Wlc_NtkFindUifableMultiplierPairs( p ); - if ( vPairs == NULL ) - return NULL; - // sanity checks - assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 ); - // iterate through node pairs - vFanins = Vec_IntAlloc( 100 ); - vCompares = Vec_IntAlloc( 100 ); - vUifConstrs = Vec_IntAlloc( 100 ); - Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i ) + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this + pPdrPars->fVerbose = pPars->fPdrVerbose; + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) { - // get two nodes - pObj = Wlc_NtkObj( p, iObj ); - pObj2 = Wlc_NtkObj( p, iObj2 ); - assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) ); - // create fanin comparator nodes - Vec_IntClear( vCompares ); - Wlc_ObjForEachFanin( pObj, iFanin, k ) + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present { - iFanin2 = Wlc_ObjFaninId( pObj2, k ); - Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 ); - iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins ); - Vec_IntPush( vCompares, iFaninNew ); - // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to - // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... - pObj = Wlc_NtkObj( p, iObj ); + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); } - // concatenate fanin comparators - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares ); - // create reduction-OR node - Vec_IntFill( vFanins, 1, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins ); - // craete output comparator node - Vec_IntFillTwo( vFanins, 2, iObj, iObj2 ); - iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins ); - // create implication node (iObjNew is already complemented above) - Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins ); - // save the constraint - Vec_IntPush( vUifConstrs, iObjNew ); - } - // derive the AND of the UIF contraints - assert( Vec_IntSize(vUifConstrs) > 0 ); - if ( Vec_IntSize(vUifConstrs) == 1 ) - iObjNew = Vec_IntEntry( vUifConstrs, 0 ); - else - { - // concatenate - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs ); - // create reduction-AND node - Vec_IntFill( vFanins, 1, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins ); - } - // update each PO to point to the new node - Wlc_NtkForEachPo( p, pObj, i ) - { - iObj = Wlc_ObjId(p, pObj); - Vec_IntFillTwo( vFanins, 2, iObj, iObjNew ); - iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins ); - // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to - // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... - pObj = Wlc_NtkObj( p, iObj ); - // update PO/CO arrays - assert( Vec_IntEntry(&p->vPos, i) == iObj ); - assert( Vec_IntEntry(&p->vCos, i) == iObj ); - Vec_IntWriteEntry( &p->vPos, i, iObjNew ); - Vec_IntWriteEntry( &p->vCos, i, iObjNew ); - // transfer the PO attribute - Wlc_NtkObj(p, iObjNew)->fIsPo = 1; - assert( pObj->fIsPo ); - pObj->fIsPo = 0; + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); } - // cleanup - Vec_IntFree( vUifConstrs ); - Vec_IntFree( vCompares ); - Vec_IntFree( vFanins ); - if ( vPairs != vPairsInit ) - Vec_IntFree( vPairs ); - // reconstruct topological order - pNew = Wlc_NtkDupDfs( p, 0, 1 ); - return pNew; + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcAbs2.c b/src/base/wlc/wlcAbs2.c index f5a7b46d..9bccdf62 100644 --- a/src/base/wlc/wlcAbs2.c +++ b/src/base/wlc/wlcAbs2.c @@ -19,6 +19,9 @@ ***********************************************************************/ #include "wlc.h" +#include "proof/pdr/pdr.h" +#include "aig/gia/giaAig.h" +#include "sat/bmc/bmc.h" ABC_NAMESPACE_IMPL_START @@ -26,56 +29,31 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct Wabs_Par_t_ Wabs_Par_t; -struct Wabs_Par_t_ -{ - Wlc_Ntk_t * pNtk; - Wlc_Par_t * pPars; - Vec_Bit_t * vLeaves; -}; - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) -{ - memset( pPars, 0, sizeof(Wlc_Par_t) ); - pPars->nBitsAdd = ABC_INFINITY; // adder bit-width - pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht - pPars->nBitsMux = ABC_INFINITY; // MUX bit-width - pPars->nBitsFlop = ABC_INFINITY; // flop bit-width - pPars->fVerbose = 0; // verbose output` -} - -/**Function************************************************************* - - Synopsis [Mark operators that meet the criteria.] + Synopsis [Mark operators that meet the abstraction criteria.] - Description [] + Description [This procedure returns the array of objects (vLeaves) that + should be abstracted because of their high bit-width. It uses input array (vUnmark) + to not abstract those objects that have been refined in the previous rounds.] SideEffects [] SeeAlso [] ***********************************************************************/ -Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; Wlc_NtkForEachObj( p, pObj, i ) { + if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away + continue; if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS ) { if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd ) @@ -101,7 +79,8 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) continue; } } - printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); + if ( fVerbose ) + printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] ); return vLeaves; } @@ -109,14 +88,17 @@ Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Synopsis [Marks nodes to be included in the abstracted network.] - Description [] + Description [Marks all objects that will be included in the abstracted model. + Stops at the objects (vLeaves) that are abstracted away. Returns three arrays: + a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the + set of flops present as flops in the abstracted network.] SideEffects [] SeeAlso [] ***********************************************************************/ -void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { int i, iFanin; if ( pObj->Mark ) @@ -139,8 +121,7 @@ void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeav Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops ); } - -void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) +static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops ) { Wlc_Obj_t * pObj; int i, Count = 0; @@ -162,31 +143,264 @@ void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOl /**Function************************************************************* - Synopsis [Derive abstraction based on the parameter values.] + Synopsis [Derive word-level abstracted model based on the parameter values.] - Description [] + Description [Retuns the word-level abstracted network and the set of pseudo-PIs + (vPisNew), which were created during abstraction. If the abstraction is + satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs + and their MFFC cones will be listed in the array (vUnmark), which will + force the abstraction to not stop at these pseudo-PIs in the future.] SideEffects [] SeeAlso [] ***********************************************************************/ -Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); Vec_Int_t * vPisNew = Vec_IntAlloc( 100 ); Vec_Int_t * vFlops = Vec_IntAlloc( 100 ); - Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars ); + Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose ); Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops ); Vec_BitFree( vLeaves ); pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); Vec_IntFree( vPisOld ); - Vec_IntFree( vPisNew ); Vec_IntFree( vFlops ); + if ( pvPisNew ) + *pvPisNew = vPisNew; + else + Vec_IntFree( vPisNew ); return pNtkNew; } +/**Function************************************************************* + + Synopsis [Find what objects need to be un-abstracted.] + + Description [Returns a subset of pseudo-PIs (vPisNew), which will be + prevented from being abstracted in the future rounds of abstraction. + The AIG manager (pGia) is a bit-level view of the abstracted model. + The counter-example (pCex) is used to find waht PPIs to refine.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew ) +{ + Vec_Int_t * vRefine = Vec_IntAlloc( 100 ); + Abc_Cex_t * pCexCare; + Wlc_Obj_t * pObj; + // count the number of bit-level PPIs and map them into word-level objects they were derived from + int f, i, b, nRealPis, nPpiBits = 0; + Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis ); + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + for ( b = 0; b < Wlc_ObjRange(pObj); b++ ) + Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) ); + // since PPIs are ordered last, the previous bits are real PIs + nRealPis = pCex->nPis - nPpiBits; + // find the care-set + pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 ); + assert( pCexCare->nPis == pCex->nPis ); + // detect care PPIs + for ( f = 0; f <= pCexCare->iFrame; f++ ) + for ( i = nRealPis; i < pCexCare->nPis; i++ ) + if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) ) + Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) ); + Abc_CexFree( pCexCare ); + Vec_IntFree( vMap ); + if ( Vec_IntSize(vRefine) == 0 )// real CEX + Vec_IntFreeP( &vRefine ); + return vRefine; +} + +/**Function************************************************************* + + Synopsis [Mark MFFC cones of the un-abstracted objects.] + + Description [The MFFC cones of the objects in vRefine are traversed + and all their nodes are marked in vUnmark.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + Wlc_ObjForEachFanin( pNode, Fanin, i ) + { + Vec_IntAddToEntry( &p->vRefs, Fanin, -1 ); + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark ); + } + return Counter; +} +static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode ) +{ + int i, Fanin, Counter = 1; + if ( Wlc_ObjIsCi(pNode) ) + return 0; + Wlc_ObjForEachFanin( pNode, Fanin, i ) + { + if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 ) + Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) ); + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); + } + return Counter; +} +static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark ) +{ + int Count1, Count2; + // if this is a flop output, compute MFFC of the corresponding flop input + while ( Wlc_ObjIsCi(pNode) ) + { + Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 ); + pNode = Wlc_ObjFo2Fi(p, pNode); + } + assert( !Wlc_ObjIsCi(pNode) ); + // dereference the node (and set the bits in vUnmark) + Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark ); + // reference it back + Count2 = Wlc_NtkNodeRef_rec( p, pNode ); + assert( Count1 == Count2 ); + return Count1; +} +static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark ) +{ + Wlc_Obj_t * pObj; int i, nNodes = 0; + if ( Vec_IntSize(&p->vRefs) == 0 ) + Wlc_NtkSetRefs( p ); + Wlc_NtkForEachObjVec( vRefine, p, pObj, i ) + nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark ); + return nNodes; +} + +/**Function************************************************************* + + Synopsis [Performs abstraction.] + + Description [Derives initial abstraction based on user-specified + parameter values, which tell what is the smallest bit-width of a + primitive that is being abstracted away. Currently only add/sub, + mul/div, mux, and flop are supported with individual parameters. + The second step is to refine the initial abstraction until the + point when the property is proved.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this + pPdrPars->fVerbose = pPars->fPdrVerbose; + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) + { + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present + { + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); + } + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); + } + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 67d7c902..f4de8ee6 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1418,7 +1418,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in } else { - pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 1 ); + pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, fGiaSimple, 0 ); Gia_ManDupRemapLiterals( vBits, pTemp ); Gia_ManStop( pTemp ); } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 346a9076..97717b09 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -33,6 +33,7 @@ static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -74,6 +75,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); @@ -458,7 +460,7 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Wlc_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) { switch ( c ) { @@ -506,9 +508,26 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nBitsFlop < 0 ) goto usage; break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; case 'h': goto usage; default: @@ -520,17 +539,133 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - pNtk = Wlc_NtkAbs( pNtk, pPars ); - Wlc_AbcUpdateNtk( pAbc, pNtk ); + Wlc_NtkAbsCore( pNtk, pPars ); + return 0; +usage: + Abc_Print( -2, "usage: %%abs [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandAbs2( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 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; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + Wlc_NtkAbsCore2( pNtk, pPars ); return 0; usage: - Abc_Print( -2, "usage: %%abs [-AMXF num] [-vh]\n" ); + Abc_Print( -2, "usage: %%abs2 [-AMXFI num] [-xvwh]\n" ); Abc_Print( -2, "\t abstraction for word-level networks\n" ); Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 86b0c17e..e6ab0739 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -94,6 +94,30 @@ char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(Wlc_Par_t) ); + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-widht + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->nIterMax = 1000; // the max number of iterations + pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fVerbose = 0; // verbose output` + pPars->fPdrVerbose = 0; // show verbose PDR output +} + /**Function************************************************************* Synopsis [Working with models.] @@ -227,6 +251,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vCopies.pArray ); ABC_FREE( p->vBits.pArray ); ABC_FREE( p->vLevels.pArray ); + ABC_FREE( p->vRefs.pArray ); ABC_FREE( p->pInits ); ABC_FREE( p->pObjs ); ABC_FREE( p->pName ); @@ -912,7 +937,7 @@ Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vP if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); - Wlc_NtkTransferNames( pNew, p ); + //Wlc_NtkTransferNames( pNew, p ); return pNew; } @@ -1129,6 +1154,70 @@ void Wlc_NtkShortNames( Wlc_Ntk_t * p ) } } +/**Function************************************************************* + + Synopsis [Count the number of flops initialized to DC value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p ) +{ + int i, nFlops, Count = 0; + if ( p->pInits == NULL ) + return 0; + nFlops = strlen(p->pInits); + for ( i = 0; i < nFlops; i++ ) + Count += (p->pInits[i] == 'x' || p->pInits[i] == 'X'); + return Count; +} + +/**Function************************************************************* + + Synopsis [Create references.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkSetRefs( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; int i, k, Fanin; + Vec_IntFill( &p->vRefs, Wlc_NtkObjNumMax(p), 0 ); + Wlc_NtkForEachObj( p, pObj, i ) + Wlc_ObjForEachFanin( pObj, Fanin, k ) + Vec_IntAddToEntry( &p->vRefs, Fanin, 1 ); + Wlc_NtkForEachCo( p, pObj, i ) + Vec_IntAddToEntry( &p->vRefs, Wlc_ObjId(p, pObj), 1 ); +} + +/**Function************************************************************* + + Synopsis [This procedure simply count the number of PPI bits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew ) +{ + Wlc_Obj_t * pObj; + int i, Count = 0; + Wlc_NtkForEachObjVec( vPisNew, p, pObj, i ) + Count += Wlc_ObjRange(pObj); + return Count; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcUif.c b/src/base/wlc/wlcUif.c new file mode 100644 index 00000000..78451c17 --- /dev/null +++ b/src/base/wlc/wlcUif.c @@ -0,0 +1,290 @@ +/**CFile**************************************************************** + + FileName [wlcUif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [Abstraction for word-level networks.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlcUif.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Check if two objects have the same input/output signatures.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 ) +{ + Wlc_Obj_t * pFanin, * pFanin2; int k; + if ( Wlc_ObjRange(pObj) != Wlc_ObjRange(pObj2) ) + return 0; + if ( Wlc_ObjIsSigned(pObj) != Wlc_ObjIsSigned(pObj2) ) + return 0; + if ( Wlc_ObjFaninNum(pObj) != Wlc_ObjFaninNum(pObj2) ) + return 0; + for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ ) + { + pFanin = Wlc_ObjFanin(p, pObj, k); + pFanin2 = Wlc_ObjFanin(p, pObj2, k); + if ( Wlc_ObjRange(pFanin) != Wlc_ObjRange(pFanin2) ) + return 0; + if ( Wlc_ObjIsSigned(pFanin) != Wlc_ObjIsSigned(pFanin2) ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Collect IDs of the multipliers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkCollectMultipliers( Wlc_Ntk_t * p ) +{ + Wlc_Obj_t * pObj; int i; + Vec_Int_t * vBoxIds = Vec_IntAlloc( 100 ); + Wlc_NtkForEachObj( p, pObj, i ) + if ( pObj->Type == WLC_OBJ_ARI_MULTI ) + Vec_IntPush( vBoxIds, i ); + if ( Vec_IntSize( vBoxIds ) > 0 ) + return vBoxIds; + Vec_IntFree( vBoxIds ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Returns all pairs of uifable multipliers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkFindUifableMultiplierPairs( Wlc_Ntk_t * p ) +{ + Vec_Int_t * vMultis = Wlc_NtkCollectMultipliers( p ); + Vec_Int_t * vPairs = Vec_IntAlloc( 2 ); + Wlc_Obj_t * pObj, * pObj2; int i, k; + // iterate through unique pairs + Wlc_NtkForEachObjVec( vMultis, p, pObj, i ) + Wlc_NtkForEachObjVec( vMultis, p, pObj2, k ) + { + if ( k == i ) + break; + if ( Wlc_NtkPairIsUifable( p, pObj, pObj2 ) ) + { + Vec_IntPush( vPairs, Wlc_ObjId(p, pObj) ); + Vec_IntPush( vPairs, Wlc_ObjId(p, pObj2) ); + } + } + Vec_IntFree( vMultis ); + if ( Vec_IntSize( vPairs ) > 0 ) + return vPairs; + Vec_IntFree( vPairs ); + return NULL; +} + + + +/**Function************************************************************* + + Synopsis [Abstracts nodes by replacing their outputs with new PIs.] + + Description [If array is NULL, abstract all multipliers.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkAbstractNodes( Wlc_Ntk_t * p, Vec_Int_t * vNodesInit ) +{ + Vec_Int_t * vNodes = vNodesInit; + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + int i, k, iObj, iFanin; + // get multipliers if not given + if ( vNodes == NULL ) + vNodes = Wlc_NtkCollectMultipliers( p ); + if ( vNodes == NULL ) + return NULL; + // mark nodes + Wlc_NtkForEachObjVec( vNodes, p, pObj, i ) + pObj->Mark = 1; + // iterate through the nodes in the DFS order + Wlc_NtkCleanCopy( p ); + Wlc_NtkForEachObj( p, pObj, i ) + { + if ( i == Vec_IntSize(&p->vCopies) ) + break; + if ( pObj->Mark ) { + // clean + pObj->Mark = 0; + // add fresh PI with the same number of bits + iObj = Wlc_ObjAlloc( p, WLC_OBJ_PI, Wlc_ObjIsSigned(pObj), Wlc_ObjRange(pObj) - 1, 0 ); + } + else { + // update fanins + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Wlc_ObjFanins(pObj)[k] = Wlc_ObjCopy(p, iFanin); + // node to remain + iObj = i; + } + Wlc_ObjSetCopy( p, i, iObj ); + } + // POs do not change in this procedure + if ( vNodes != vNodesInit ) + Vec_IntFree( vNodes ); + // reconstruct topological order + pNew = Wlc_NtkDupDfs( p, 0, 1 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Adds UIF constraints to node pairs and updates POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wlc_Ntk_t * Wlc_NtkUifNodePairs( Wlc_Ntk_t * p, Vec_Int_t * vPairsInit ) +{ + Vec_Int_t * vPairs = vPairsInit; + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj, * pObj2; + Vec_Int_t * vUifConstrs, * vCompares, * vFanins; + int i, k, iObj, iObj2, iObjNew, iObjNew2; + int iFanin, iFanin2, iFaninNew; + // get multiplier pairs if not given + if ( vPairs == NULL ) + vPairs = Wlc_NtkFindUifableMultiplierPairs( p ); + if ( vPairs == NULL ) + return NULL; + // sanity checks + assert( Vec_IntSize(vPairs) > 0 && Vec_IntSize(vPairs) % 2 == 0 ); + // iterate through node pairs + vFanins = Vec_IntAlloc( 100 ); + vCompares = Vec_IntAlloc( 100 ); + vUifConstrs = Vec_IntAlloc( 100 ); + Vec_IntForEachEntryDouble( vPairs, iObj, iObj2, i ) + { + // get two nodes + pObj = Wlc_NtkObj( p, iObj ); + pObj2 = Wlc_NtkObj( p, iObj2 ); + assert( Wlc_NtkPairIsUifable(p, pObj, pObj2) ); + // create fanin comparator nodes + Vec_IntClear( vCompares ); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + { + iFanin2 = Wlc_ObjFaninId( pObj2, k ); + Vec_IntFillTwo( vFanins, 2, iFanin, iFanin2 ); + iFaninNew = Wlc_ObjCreate( p, WLC_OBJ_COMP_NOTEQU, 0, 0, 0, vFanins ); + Vec_IntPush( vCompares, iFaninNew ); + // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to + // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... + pObj = Wlc_NtkObj( p, iObj ); + } + // concatenate fanin comparators + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vCompares) - 1, 0, vCompares ); + // create reduction-OR node + Vec_IntFill( vFanins, 1, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_OR, 0, 0, 0, vFanins ); + // craete output comparator node + Vec_IntFillTwo( vFanins, 2, iObj, iObj2 ); + iObjNew2 = Wlc_ObjCreate( p, WLC_OBJ_COMP_EQU, 0, 0, 0, vFanins ); + // create implication node (iObjNew is already complemented above) + Vec_IntFillTwo( vFanins, 2, iObjNew, iObjNew2 ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_OR, 0, 0, 0, vFanins ); + // save the constraint + Vec_IntPush( vUifConstrs, iObjNew ); + } + // derive the AND of the UIF contraints + assert( Vec_IntSize(vUifConstrs) > 0 ); + if ( Vec_IntSize(vUifConstrs) == 1 ) + iObjNew = Vec_IntEntry( vUifConstrs, 0 ); + else + { + // concatenate + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_BIT_CONCAT, 0, Vec_IntSize(vUifConstrs) - 1, 0, vUifConstrs ); + // create reduction-AND node + Vec_IntFill( vFanins, 1, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_REDUCT_AND, 0, 0, 0, vFanins ); + } + // update each PO to point to the new node + Wlc_NtkForEachPo( p, pObj, i ) + { + iObj = Wlc_ObjId(p, pObj); + Vec_IntFillTwo( vFanins, 2, iObj, iObjNew ); + iObjNew = Wlc_ObjCreate( p, WLC_OBJ_LOGIC_AND, 0, 0, 0, vFanins ); + // note that a pointer to Wlc_Obj_t (for example, pObj) can be invalidated after a call to + // Wlc_ObjCreate() due to a possible realloc of the internal array of objects... + pObj = Wlc_NtkObj( p, iObj ); + // update PO/CO arrays + assert( Vec_IntEntry(&p->vPos, i) == iObj ); + assert( Vec_IntEntry(&p->vCos, i) == iObj ); + Vec_IntWriteEntry( &p->vPos, i, iObjNew ); + Vec_IntWriteEntry( &p->vCos, i, iObjNew ); + // transfer the PO attribute + Wlc_NtkObj(p, iObjNew)->fIsPo = 1; + assert( pObj->fIsPo ); + pObj->fIsPo = 0; + } + // cleanup + Vec_IntFree( vUifConstrs ); + Vec_IntFree( vCompares ); + Vec_IntFree( vFanins ); + if ( vPairs != vPairsInit ) + Vec_IntFree( vPairs ); + // reconstruct topological order + pNew = Wlc_NtkDupDfs( p, 0, 1 ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + -- cgit v1.2.3 From c7b68c5e3f547679b524ec5e0dcb85cc3735deef Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 10:03:34 -0800 Subject: Promising modification of the generalization procedure in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index af5d0ccf..44e4bc16 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctvwzh" ) ) != EOF ) { switch ( c ) { @@ -26313,6 +26313,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'g': pPars->fSkipGeneral ^= 1; break; + case 'j': + pPars->fSimpleGeneral ^= 1; + break; case 'o': pPars->fUsePropOut ^= 1; break; @@ -26366,7 +26369,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26392,6 +26395,7 @@ usage: Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); + Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); -- cgit v1.2.3 From 632ca7ed11be3bd57ac1a730a9775658c17d9b53 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Feb 2017 13:37:46 -0800 Subject: Promising alternative of CEX minimization in 'pdr'. --- src/base/abci/abc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 44e4bc16..52684f8c 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26171,7 +26171,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Pdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctvwzh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) { switch ( c ) { @@ -26328,6 +26328,9 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) case 't': pPars->fUseAbs ^= 1; break; + case 'k': + pPars->fUseSimpleRef ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -26369,7 +26372,7 @@ int Abc_CommandPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctvwzh]\n" ); + Abc_Print( -2, "usage: pdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); @@ -26400,6 +26403,7 @@ usage: Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); + Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); -- cgit v1.2.3 From 1d3ff5338a0c98f2319578b25f9695c3a326dd9d Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Fri, 17 Feb 2017 18:55:00 -0800 Subject: added ipdr --- src/base/abci/abc.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 52684f8c..af79a66d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -333,6 +333,7 @@ static int Abc_CommandBm2 ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSaucy ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTestCex ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandIPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); #ifdef ABC_USE_CUDD static int Abc_CommandReconcile ( Abc_Frame_t * pAbc, int argc, char ** argv ); #endif @@ -983,6 +984,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); Cmd_CommandAdd( pAbc, "Verification", "testcex", Abc_CommandTestCex, 0 ); Cmd_CommandAdd( pAbc, "Verification", "pdr", Abc_CommandPdr, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "ipdr", Abc_CommandIPdr, 0 ); #ifdef ABC_USE_CUDD Cmd_CommandAdd( pAbc, "Verification", "reconcile", Abc_CommandReconcile, 1 ); #endif @@ -26415,6 +26417,272 @@ usage: + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + Pdr_Par_t Pars, * pPars = &Pars; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + int c; + Pdr_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) + { + switch ( c ) + { + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRecycle = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRecycle < 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; + } + pPars->nFrameMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nFrameMax < 0 ) + goto usage; + break; + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nConfLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nConfLimit < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nConfGenLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nConfGenLimit < 0 ) + goto usage; + break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRestLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRestLimit < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOut = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOut < 0 ) + goto usage; + break; + case 'H': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOutOne = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOutOne < 0 ) + goto usage; + break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOutGap = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOutGap < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nRandomSeed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nRandomSeed < 0 ) + goto usage; + break; + case 'a': + pPars->fSolveAll ^= 1; + break; + case 'x': + pPars->fStoreCex ^= 1; + break; + case 'r': + pPars->fTwoRounds ^= 1; + break; + case 'm': + pPars->fMonoCnf ^= 1; + break; + case 'u': + pPars->fNewXSim ^= 1; + break; + case 'y': + pPars->fFlopPrio ^= 1; + break; + case 'f': + pPars->fFlopOrder ^= 1; + break; + case 's': + pPars->fShortest ^= 1; + break; + case 'i': + pPars->fShiftStart ^= 1; + break; + case 'p': + pPars->fReuseProofOblig ^= 1; + break; + case 'd': + pPars->fDumpInv ^= 1; + break; + case 'e': + pPars->fUseSupp ^= 1; + break; + case 'g': + pPars->fSkipGeneral ^= 1; + break; + case 'j': + pPars->fSimpleGeneral ^= 1; + break; + case 'o': + pPars->fUsePropOut ^= 1; + break; + case 'n': + pPars->fSkipDown ^= 1; + break; + case 'c': + pPars->fCtgs ^= 1; + break; + case 't': + pPars->fUseAbs ^= 1; + break; + case 'k': + pPars->fUseSimpleRef ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fVeryVerbose ^= 1; + break; + case 'z': + pPars->fNotVerbose ^= 1; + break; + case 'h': + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( -2, "There is no current network.\n"); + return 0; + } + if ( Abc_NtkLatchNum(pNtk) == 0 ) + { + Abc_Print( 0, "The current network is combinational.\n"); + return 0; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + Abc_Print( -2, "The current network is not an AIG (run \"strash\").\n"); + return 0; + } + // run the procedure + pPars->fUseBridge = pAbc->fBridgeMode; + pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); + pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; + Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); + if ( pNtk->vSeqModelVec ) + Abc_FrameReplaceCexVec( pAbc, &pNtk->vSeqModelVec ); + else + Abc_FrameReplaceCex( pAbc, &pNtk->pSeqModel ); + return 0; + +usage: + Abc_Print( -2, "usage: ipdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); + Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); + Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); + Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); + Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); + Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); + Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); + Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); + Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); + Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); + Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); + Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); + Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); + Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); + Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); + Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); + Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); + Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); + Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); + Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); + Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); + Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); + Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); + Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); + Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n\n"); + Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); + Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); + Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); + Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); + + + return 1; } -- cgit v1.2.3 From 196b3591830e9fbe0877411b8053233c11d0f4ce Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 09:51:54 -0800 Subject: started pdrIncr.c --- src/base/abci/abc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index af79a66d..0e3a1d3a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26434,6 +26434,7 @@ usage: int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + extern int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); Pdr_Par_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c; @@ -26629,6 +26630,7 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // run the procedure + IPdr_ManSolve( pNtk, pPars ); pPars->fUseBridge = pAbc->fBridgeMode; pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; -- cgit v1.2.3 From 91a0a0fc3b5dfd5aa71122106dbdacf6268e51fb Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 10:28:16 -0800 Subject: copied pdr_mansolve --- src/base/abci/abc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0e3a1d3a..f12e3727 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26630,9 +26630,8 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } // run the procedure - IPdr_ManSolve( pNtk, pPars ); pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = Abc_NtkDarPdr( pNtk, pPars ); + pAbc->Status = IPdr_ManSolve( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); if ( pNtk->vSeqModelVec ) -- cgit v1.2.3 From b93a80512941e5039e48a7b74e625d7d6f9f720a Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sat, 18 Feb 2017 12:43:03 -0800 Subject: copied some functions from pdr --- src/base/abci/abc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f12e3727..0645c6e3 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -26434,7 +26434,7 @@ usage: int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - extern int IPdr_ManSolve( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); + extern int Abc_NtkDarIPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); Pdr_Par_t Pars, * pPars = &Pars; Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c; @@ -26631,7 +26631,7 @@ int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) } // run the procedure pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = IPdr_ManSolve( pNtk, pPars ); + pAbc->Status = Abc_NtkDarIPdr( pNtk, pPars ); pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); if ( pNtk->vSeqModelVec ) -- cgit v1.2.3 From 429f52ce15d1c10e71d98d8c1388b93809a425e1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 14:20:10 -0800 Subject: Experiments with SAT sweeping. --- src/base/wlc/wlcSim.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcSim.c b/src/base/wlc/wlcSim.c index 20ac8c61..e2fcd1f8 100644 --- a/src/base/wlc/wlcSim.c +++ b/src/base/wlc/wlcSim.c @@ -43,13 +43,13 @@ ABC_NAMESPACE_IMPL_START ***********************************************************************/ static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj ) { - return Vec_WrdEntryP( p->vSims, p->iPatsPi * iObj ); + return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); } static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj ) { int w; word * pSim = Wlc_ObjSim( p, iObj ); - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = Gia_ManRandomW( 0 ); } static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj ) @@ -57,7 +57,7 @@ static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj ) int w; word * pSimRo = Wlc_ObjSim( p, iObj ); word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimRo[w] = pSimRi[w]; } static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj ) @@ -67,10 +67,10 @@ static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj ) word * pSimCo = Wlc_ObjSim( p, iObj ); word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); if ( Gia_ObjFaninC0(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimCo[w] = ~pSimDri[w]; else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSimCo[w] = pSimDri[w]; } static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj ) @@ -81,16 +81,16 @@ static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj ) word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = ~pSim0[w] & ~pSim1[w]; else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = ~pSim0[w] & pSim1[w]; else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = pSim0[w] & ~pSim1[w]; else - for ( w = 0; w < p->iPatsPi; w++ ) + for ( w = 0; w < p->nSimWords; w++ ) pSim[w] = pSim0[w] & pSim1[w]; } @@ -135,7 +135,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int // allocate simulation info for one timeframe Vec_WrdFreeP( &pGia->vSims ); pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords ); - pGia->iPatsPi = nWords; + pGia->nSimWords = nWords; // allocate resulting simulation info vRes = Vec_PtrAlloc( Vec_IntSize(vNodes) ); Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i ) @@ -188,7 +188,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int printf( "Replaced %d dangling internal bits with constant 0.\n", Counter ); } Vec_WrdFreeP( &pGia->vSims ); - pGia->iPatsPi = 0; + pGia->nSimWords = 0; Gia_ManStop( pGia ); return vRes; } -- cgit v1.2.3 From 27caed8dc812db321730ee9451a2a0788ad0ab28 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 18 Feb 2017 20:20:50 -0800 Subject: Experiments with SAT sweeping. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 52684f8c..4c37242d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43019,7 +43019,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); - +Cec2_ManSimulateTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; usage: -- cgit v1.2.3 From 24fdcecb2d034af4d7f7c26ec083f6baf1434018 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 09:20:44 -0800 Subject: started %pdra --- src/base/wlc/wlcCom.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) (limited to 'src/base') diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 97717b09..6b542b94 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -33,6 +33,7 @@ static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPdrAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -75,6 +76,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%pdra", Abc_CommandPdrAbs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); @@ -442,6 +444,121 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + Wlc_Par_t Pars, * pPars = &Pars; + int c; + Wlc_ManSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsAdd = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsAdd < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMul = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMul < 0 ) + goto usage; + break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBitsMux = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsMux < 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; + } + pPars->nBitsFlop = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBitsFlop < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nIterMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nIterMax < 0 ) + goto usage; + break; + case 'x': + pPars->fXorOutput ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fPdrVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); + return 0; + } + Wlc_NtkAbsCore( pNtk, pPars ); + return 0; +usage: + Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "\t abstraction for word-level networks\n" ); + Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); + Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); + Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux ); + Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); + Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); + Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + /**Function******************************************************************** Synopsis [] -- cgit v1.2.3 From 6cf289dadd41354eb03ef1fa0a4d366ab5f62f8c Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 09:55:58 -0800 Subject: working on pdr with wla --- src/base/wlc/wlc.h | 1 + src/base/wlc/wlcAbs.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcCom.c | 2 +- 3 files changed, 113 insertions(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 91dc0573..9ca56917 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -277,6 +277,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 318df4dd..cfd1155d 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -283,6 +283,117 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec return nNodes; } +/**Function************************************************************* + + Synopsis [Performs PDR with word-level abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +{ + abctime clk = Abc_Clock(); + int nIters, nNodes, nDcFlops, RetValue = -1; + // start the bitmap to mark objects that cannot be abstracted because of refinement + // currently, this bitmap is empty because abstraction begins without refinement + Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); + // set up parameters to run PDR + Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; + Pdr_ManSetDefaultParams( pPdrPars ); + pPdrPars->fVerbose = pPars->fPdrVerbose; + + // perform refinement iterations + for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) + { + Aig_Man_t * pAig; + Abc_Cex_t * pCex; + Vec_Int_t * vPisNew, * vRefine; + Gia_Man_t * pGia, * pTemp; + Wlc_Ntk_t * pAbs; + + if ( pPars->fVerbose ) + printf( "\nIteration %d:\n", nIters ); + + // get abstracted GIA and the set of pseudo-PIs (vPisNew) + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + + // if the abstraction has flops with DC-init state, + // new PIs were introduced by bit-blasting at the end of the PI list + // here we move these variables to be *before* PPIs, because + // PPIs are supposed to be at the end of the PI list for refinement + nDcFlops = Wlc_NtkDcFlopNum(pAbs); + if ( nDcFlops > 0 ) // DC-init flops are present + { + pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops ); + Gia_ManStop( pTemp ); + } + // if the word-level outputs have to be XORs, this is a place to do it + if ( pPars->fXorOutput ) + { + pGia = Gia_ManTransformMiter2( pTemp = pGia ); + Gia_ManStop( pTemp ); + } + if ( pPars->fVerbose ) + { + printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) ); + Gia_ManPrintStats( pGia, NULL ); + } + Wlc_NtkFree( pAbs ); + + // try to prove abstracted GIA by converting it to AIG and calling PDR + pAig = Gia_ManToAigSimple( pGia ); + RetValue = Pdr_ManSolve( pAig, pPdrPars ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; + Aig_ManStop( pAig ); + + // consider outcomes + if ( pCex == NULL ) + { + assert( RetValue ); // proved or undecided + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + break; + } + + // perform refinement + vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew ); + Gia_ManStop( pGia ); + Vec_IntFree( vPisNew ); + if ( vRefine == NULL ) // real CEX + { + Abc_CexFree( pCex ); // return CEX in the future + break; + } + + // update the set of objects to be un-abstracted + nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); + if ( pPars->fVerbose ) + printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); + Vec_IntFree( vRefine ); + Abc_CexFree( pCex ); + } + + Vec_BitFree( vUnmark ); + // report the result + if ( pPars->fVerbose ) + printf( "\n" ); + printf( "Abstraction " ); + if ( RetValue == 0 ) + printf( "resulted in a real CEX" ); + else if ( RetValue == 1 ) + printf( "is successfully proved" ); + else + printf( "timed out" ); + printf( " after %d iterations. ", nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return RetValue; +} + /**Function************************************************************* Synopsis [Performs abstraction.] diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 6b542b94..e980752b 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -541,7 +541,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandCone(): There is no current design.\n" ); return 0; } - Wlc_NtkAbsCore( pNtk, pPars ); + Wlc_NtkPdrAbs( pNtk, pPars ); return 0; usage: Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); -- cgit v1.2.3 From 840f5d1ca8d8d51fa28c2ac3cd7bc9dd2e245f29 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 10:22:15 -0800 Subject: working on pdr with wla --- src/base/wlc/wlcAbs.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index cfd1155d..b6571e53 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -20,6 +20,7 @@ #include "wlc.h" #include "proof/pdr/pdr.h" +#include "proof/pdr/pdrInt.h" #include "aig/gia/giaAig.h" #include "sat/bmc/bmc.h" @@ -29,6 +30,10 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); +extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); +extern int IPdr_ManSolveInt( Pdr_Man_t * p ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -297,6 +302,8 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); + Pdr_Man_t * pPdr; + Vec_Vec_t * vClauses = NULL; int nIters, nNodes, nDcFlops, RetValue = -1; // start the bitmap to mark objects that cannot be abstracted because of refinement // currently, this bitmap is empty because abstraction begins without refinement @@ -347,9 +354,14 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // try to prove abstracted GIA by converting it to AIG and calling PDR pAig = Gia_ManToAigSimple( pGia ); - RetValue = Pdr_ManSolve( pAig, pPdrPars ); + + pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + if (vClauses) + IPdr_ManRestore(pPdr, vClauses); + + RetValue = IPdr_ManSolveInt( pPdr ); + pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; - Aig_ManStop( pAig ); // consider outcomes if ( pCex == NULL ) @@ -357,6 +369,8 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) assert( RetValue ); // proved or undecided Gia_ManStop( pGia ); Vec_IntFree( vPisNew ); + Pdr_ManStop( pPdr ); + Aig_ManStop( pAig ); break; } @@ -367,15 +381,22 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) if ( vRefine == NULL ) // real CEX { Abc_CexFree( pCex ); // return CEX in the future + Pdr_ManStop( pPdr ); + Aig_ManStop( pAig ); break; } + // spurious CEX, continue solving + vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + Pdr_ManStop( pPdr ); + // update the set of objects to be un-abstracted nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark ); if ( pPars->fVerbose ) printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes ); Vec_IntFree( vRefine ); Abc_CexFree( pCex ); + Aig_ManStop( pAig ); } Vec_BitFree( vUnmark ); -- cgit v1.2.3 From 2732cbc1ee3b82fa7f609ef4c7156132058612dc Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 12:31:28 -0800 Subject: working on pdr with wla --- src/base/wlc/wlcAbs.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index b6571e53..342d667f 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -133,6 +133,17 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * Wlc_NtkCleanMarks( p ); Wlc_NtkForEachCo( p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); + + + Vec_IntClear(vFlops); + Wlc_NtkForEachCi( p, pObj, i ) { + if ( !Wlc_ObjIsPi(pObj) ) { + Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) ); + pObj->Mark = 1; + } + } + + Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); Wlc_NtkForEachObj( p, pObj, i ) @@ -312,6 +323,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); pPdrPars->fVerbose = pPars->fPdrVerbose; + pPdrPars->fVeryVerbose = 1; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) @@ -356,8 +368,15 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); - if (vClauses) - IPdr_ManRestore(pPdr, vClauses); + if ( vClauses ) { + if ( Vec_VecSize( vClauses) == 1 ) { + Vec_VecFree( vClauses ); + vClauses = NULL; + } else { + assert( Vec_VecSize( vClauses) >= 2 ); + IPdr_ManRestore(pPdr, vClauses); + } + } RetValue = IPdr_ManSolveInt( pPdr ); @@ -441,11 +460,12 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // set up parameters to run PDR Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); - pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) - pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) - pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) + //pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction) + //pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization) + //pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this pPdrPars->fVerbose = pPars->fPdrVerbose; + pPdrPars->fVeryVerbose = 1; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) { -- cgit v1.2.3 From 2d1792040a8c09a12d70413ceb99bd11bb145c2b Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 15:57:13 -0800 Subject: working on pdr with wla --- src/base/wlc/wlcAbs.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 342d667f..8cc79722 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -323,7 +323,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Pdr_Par_t PdrPars, * pPdrPars = &PdrPars; Pdr_ManSetDefaultParams( pPdrPars ); pPdrPars->fVerbose = pPars->fPdrVerbose; - pPdrPars->fVeryVerbose = 1; + pPdrPars->fVeryVerbose = 0; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) @@ -368,14 +368,10 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + if ( vClauses ) { - if ( Vec_VecSize( vClauses) == 1 ) { - Vec_VecFree( vClauses ); - vClauses = NULL; - } else { - assert( Vec_VecSize( vClauses) >= 2 ); - IPdr_ManRestore(pPdr, vClauses); - } + assert( Vec_VecSize( vClauses) >= 2 ); + IPdr_ManRestore( pPdr, vClauses ); } RetValue = IPdr_ManSolveInt( pPdr ); @@ -406,7 +402,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } // spurious CEX, continue solving - vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + vClauses = IPdr_ManSaveClauses( pPdr, 1 ); Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted @@ -465,7 +461,7 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) //pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization) //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this pPdrPars->fVerbose = pPars->fPdrVerbose; - pPdrPars->fVeryVerbose = 1; + pPdrPars->fVeryVerbose = 0; // perform refinement iterations for ( nIters = 1; nIters < pPars->nIterMax; nIters++ ) { -- cgit v1.2.3 From 1a66a5823a37123c099e63cb94bba1fd844487d1 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Sun, 19 Feb 2017 16:09:59 -0800 Subject: working on pdr with wla --- src/base/wlc/wlcAbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8cc79722..47bd9a3f 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -402,7 +402,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } // spurious CEX, continue solving - vClauses = IPdr_ManSaveClauses( pPdr, 1 ); + vClauses = IPdr_ManSaveClauses( pPdr, 0 ); Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted -- cgit v1.2.3 From 222b3741a40af2913132ef385936b955bbc19b4d Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 10:13:18 -0800 Subject: fixed time profiling in pdr --- src/base/wlc/wlcAbs.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/base') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 47bd9a3f..902c060d 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -313,6 +313,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); + abctime pdrClk; Pdr_Man_t * pPdr; Vec_Vec_t * vClauses = NULL; int nIters, nNodes, nDcFlops, RetValue = -1; @@ -368,6 +369,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) pAig = Gia_ManToAigSimple( pGia ); pPdr = Pdr_ManStart( pAig, pPdrPars, NULL ); + pdrClk = Abc_Clock(); if ( vClauses ) { assert( Vec_VecSize( vClauses) >= 2 ); @@ -375,6 +377,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } RetValue = IPdr_ManSolveInt( pPdr ); + pPdr->tTotal += Abc_Clock() - pdrClk; pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; @@ -403,6 +406,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) // spurious CEX, continue solving vClauses = IPdr_ManSaveClauses( pPdr, 0 ); + Pdr_ManStop( pPdr ); // update the set of objects to be un-abstracted -- cgit v1.2.3 From 19510bd38e46fd913bf6dc29393938e50fd717ee Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 11:07:12 -0800 Subject: added datastructure for %pdra options --- src/base/wlc/wlc.h | 18 +++++++++++++++++- src/base/wlc/wlcAbs.c | 27 ++++++++++++++++++++++++++- src/base/wlc/wlcCom.c | 4 ++-- 3 files changed, 45 insertions(+), 4 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 9ca56917..cf8bdab4 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -174,6 +174,21 @@ struct Wlc_Par_t_ int fPdrVerbose; // verbose output }; + +typedef struct WlcPdr_Par_t_ WlcPdr_Par_t; +struct WlcPdr_Par_t_ +{ + int nBitsAdd; // adder bit-width + int nBitsMul; // multiplier bit-widht + int nBitsMux; // MUX bit-width + int nBitsFlop; // flop bit-width + int nIterMax; // the max number of iterations + int fXorOutput; // XOR outputs of word-level miter + int fVerbose; // verbose output + int fPdrVerbose; // verbose output +}; + + static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -277,7 +292,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); -extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ @@ -286,6 +301,7 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); +extern void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 902c060d..8fde7f56 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -38,6 +38,31 @@ extern int IPdr_ManSolveInt( Pdr_Man_t * p ); /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(WlcPdr_Par_t) ); + pPars->nBitsAdd = ABC_INFINITY; // adder bit-width + pPars->nBitsMul = ABC_INFINITY; // multiplier bit-width + pPars->nBitsMux = ABC_INFINITY; // MUX bit-width + pPars->nBitsFlop = ABC_INFINITY; // flop bit-width + pPars->nIterMax = 1000; // the max number of iterations + pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fVerbose = 0; // verbose output + pPars->fPdrVerbose = 0; // show verbose PDR output +} + /**Function************************************************************* Synopsis [Mark operators that meet the abstraction criteria.] @@ -310,7 +335,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec SeeAlso [] ***********************************************************************/ -int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) { abctime clk = Abc_Clock(); abctime pdrClk; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index e980752b..d30b376e 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -458,9 +458,9 @@ usage: int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - Wlc_Par_t Pars, * pPars = &Pars; + WlcPdr_Par_t Pars, * pPars = &Pars; int c; - Wlc_ManSetDefaultParams( pPars ); + WlcPdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) { -- cgit v1.2.3 From ac1eb60db9129110e7795614ad82d85cb74d854e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 20 Feb 2017 12:32:32 -0800 Subject: Experiments with SAT sweeping. --- src/base/abci/abc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 4c37242d..466af66a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -43019,7 +43019,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Jf_ManTestCnf( pAbc->pGia ); // Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); // Gia_ParTest( pAbc->pGia, nWords, nProcs ); -Cec2_ManSimulateTest( pAbc->pGia ); +//Cec2_ManSimulateTest( pAbc->pGia ); // printf( "\nThis command is currently disabled.\n\n" ); return 0; usage: -- cgit v1.2.3 From 9f43c84501cf8c5a8ae74cc5bebea63dafc3a714 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Mon, 20 Feb 2017 12:51:04 -0800 Subject: added options of checking and pushing to %pdra --- src/base/wlc/wlc.h | 2 ++ src/base/wlc/wlcAbs.c | 10 ++++++---- src/base/wlc/wlcCom.c | 12 ++++++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index cf8bdab4..9cb34bf3 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -184,6 +184,8 @@ struct WlcPdr_Par_t_ int nBitsFlop; // flop bit-width int nIterMax; // the max number of iterations int fXorOutput; // XOR outputs of word-level miter + int fCheckClauses; // Check clauses in the reloaded trace + int fPushClauses; // Push clauses in the reloaded trace int fVerbose; // verbose output int fPdrVerbose; // verbose output }; diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 8fde7f56..fbaa1b8a 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -32,7 +32,7 @@ ABC_NAMESPACE_IMPL_START extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); -extern int IPdr_ManSolveInt( Pdr_Man_t * p ); +extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -59,6 +59,8 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) pPars->nBitsFlop = ABC_INFINITY; // flop bit-width pPars->nIterMax = 1000; // the max number of iterations pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fCheckClauses = 1; // Check clauses in the reloaded trace + pPars->fPushClauses = 0; // Push clauses in the reloaded trace pPars->fVerbose = 0; // verbose output pPars->fPdrVerbose = 0; // show verbose PDR output } @@ -76,7 +78,7 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; @@ -197,7 +199,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -401,7 +403,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) IPdr_ManRestore( pPdr, vClauses ); } - RetValue = IPdr_ManSolveInt( pPdr ); + RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses ); pPdr->tTotal += Abc_Clock() - pdrClk; pCex = pAig->pSeqModel; pAig->pSeqModel = NULL; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index d30b376e..7801abc6 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -462,7 +462,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; WlcPdr_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF ) { switch ( c ) { @@ -524,6 +524,12 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'x': pPars->fXorOutput ^= 1; break; + case 'c': + pPars->fCheckClauses ^= 1; + break; + case 'p': + pPars->fPushClauses ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -544,7 +550,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) Wlc_NtkPdrAbs( pNtk, pPars ); return 0; usage: - Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-xvwh]\n" ); + Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-cpxvwh]\n" ); Abc_Print( -2, "\t abstraction for word-level networks\n" ); Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd ); Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul ); @@ -552,6 +558,8 @@ usage: Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop ); Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax ); Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle checking clauses in the reloaded trace [default = %s]\n", pPars->fCheckClauses? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle pushing clauses in the reloaded trace [default = %s]\n", pPars->fPushClauses? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); -- cgit v1.2.3 From 01e6beea8e617eb5ef4f9b621b009eded9498a1f Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Tue, 21 Feb 2017 20:06:13 -0800 Subject: clean up --- src/base/wlc/wlc.h | 18 +----------------- src/base/wlc/wlcAbs.c | 33 +++------------------------------ src/base/wlc/wlcCom.c | 4 ++-- src/base/wlc/wlcNtk.c | 2 ++ 4 files changed, 8 insertions(+), 49 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 9cb34bf3..686d9f00 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -163,20 +163,6 @@ struct Wlc_Ntk_t_ typedef struct Wlc_Par_t_ Wlc_Par_t; struct Wlc_Par_t_ -{ - int nBitsAdd; // adder bit-width - int nBitsMul; // multiplier bit-widht - int nBitsMux; // MUX bit-width - int nBitsFlop; // flop bit-width - int nIterMax; // the max number of iterations - int fXorOutput; // XOR outputs of word-level miter - int fVerbose; // verbose output - int fPdrVerbose; // verbose output -}; - - -typedef struct WlcPdr_Par_t_ WlcPdr_Par_t; -struct WlcPdr_Par_t_ { int nBitsAdd; // adder bit-width int nBitsMul; // multiplier bit-widht @@ -190,7 +176,6 @@ struct WlcPdr_Par_t_ int fPdrVerbose; // verbose output }; - static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } static inline int Wlc_NtkObjNumMax( Wlc_Ntk_t * p ) { return p->iObj; } static inline int Wlc_NtkPiNum( Wlc_Ntk_t * p ) { return Vec_IntSize(&p->vPis); } @@ -294,7 +279,7 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) /*=== wlcAbs.c ========================================================*/ extern int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); -extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ); +extern int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcAbs2.c ========================================================*/ extern int Wlc_NtkAbsCore2( Wlc_Ntk_t * p, Wlc_Par_t * pPars ); /*=== wlcBlast.c ========================================================*/ @@ -303,7 +288,6 @@ extern Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int i extern void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ extern void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ); -extern void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ); extern char * Wlc_ObjTypeName( Wlc_Obj_t * p ); extern Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ); extern int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg ); diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index fbaa1b8a..1e5df918 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -38,33 +38,6 @@ extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPu /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) -{ - memset( pPars, 0, sizeof(WlcPdr_Par_t) ); - pPars->nBitsAdd = ABC_INFINITY; // adder bit-width - pPars->nBitsMul = ABC_INFINITY; // multiplier bit-width - pPars->nBitsMux = ABC_INFINITY; // MUX bit-width - pPars->nBitsFlop = ABC_INFINITY; // flop bit-width - pPars->nIterMax = 1000; // the max number of iterations - pPars->fXorOutput = 1; // XOR outputs of word-level miter - pPars->fCheckClauses = 1; // Check clauses in the reloaded trace - pPars->fPushClauses = 0; // Push clauses in the reloaded trace - pPars->fVerbose = 0; // verbose output - pPars->fPdrVerbose = 0; // show verbose PDR output -} - /**Function************************************************************* Synopsis [Mark operators that meet the abstraction criteria.] @@ -78,7 +51,7 @@ void WlcPdr_ManSetDefaultParams( WlcPdr_Par_t * pPars ) SeeAlso [] ***********************************************************************/ -static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) +static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose ) { Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) ); Wlc_Obj_t * pObj; int i, Count[4] = {0}; @@ -199,7 +172,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -337,7 +310,7 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec SeeAlso [] ***********************************************************************/ -int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, WlcPdr_Par_t * pPars ) +int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) { abctime clk = Abc_Clock(); abctime pdrClk; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 7801abc6..df736e70 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -458,9 +458,9 @@ usage: int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - WlcPdr_Par_t Pars, * pPars = &Pars; + Wlc_Par_t Pars, * pPars = &Pars; int c; - WlcPdr_ManSetDefaultParams( pPars ); + Wlc_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF ) { diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index e6ab0739..c8fc15a7 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -114,6 +114,8 @@ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars ) pPars->nBitsFlop = ABC_INFINITY; // flop bit-width pPars->nIterMax = 1000; // the max number of iterations pPars->fXorOutput = 1; // XOR outputs of word-level miter + pPars->fCheckClauses = 1; // Check clauses in the reloaded trace + pPars->fPushClauses = 0; // Push clauses in the reloaded trace pPars->fVerbose = 0; // verbose output` pPars->fPdrVerbose = 0; // show verbose PDR output } -- cgit v1.2.3 From fb2fbd70bd31eb08dd50c66788d5165697ca6925 Mon Sep 17 00:00:00 2001 From: Yen-Sheng Ho Date: Tue, 21 Feb 2017 20:10:11 -0800 Subject: clean up --- src/base/abci/abc.c | 269 ---------------------------------------------------- 1 file changed, 269 deletions(-) (limited to 'src/base') diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0645c6e3..52684f8c 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -333,7 +333,6 @@ static int Abc_CommandBm2 ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSaucy ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTestCex ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandIPdr ( Abc_Frame_t * pAbc, int argc, char ** argv ); #ifdef ABC_USE_CUDD static int Abc_CommandReconcile ( Abc_Frame_t * pAbc, int argc, char ** argv ); #endif @@ -984,7 +983,6 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "saucy3", Abc_CommandSaucy, 1 ); Cmd_CommandAdd( pAbc, "Verification", "testcex", Abc_CommandTestCex, 0 ); Cmd_CommandAdd( pAbc, "Verification", "pdr", Abc_CommandPdr, 0 ); - Cmd_CommandAdd( pAbc, "Verification", "ipdr", Abc_CommandIPdr, 0 ); #ifdef ABC_USE_CUDD Cmd_CommandAdd( pAbc, "Verification", "reconcile", Abc_CommandReconcile, 1 ); #endif @@ -26417,273 +26415,6 @@ usage: - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandIPdr( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern int Abc_NtkDarPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - extern int Abc_NtkDarIPdr( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars ); - Pdr_Par_t Pars, * pPars = &Pars; - Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); - int c; - Pdr_ManSetDefaultParams( pPars ); - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MFCDQTHGSaxrmuyfsipdegjonctkvwzh" ) ) != EOF ) - { - switch ( c ) - { - case 'M': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRecycle = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRecycle < 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; - } - pPars->nFrameMax = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nFrameMax < 0 ) - goto usage; - break; - case 'C': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfLimit < 0 ) - goto usage; - break; - case 'D': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nConfGenLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nConfGenLimit < 0 ) - goto usage; - break; - case 'Q': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-Q\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRestLimit = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRestLimit < 0 ) - goto usage; - break; - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOut = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOut < 0 ) - goto usage; - break; - case 'H': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-H\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOutOne = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOutOne < 0 ) - goto usage; - break; - case 'G': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-G\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nTimeOutGap = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nTimeOutGap < 0 ) - goto usage; - break; - case 'S': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); - goto usage; - } - pPars->nRandomSeed = atoi(argv[globalUtilOptind]); - globalUtilOptind++; - if ( pPars->nRandomSeed < 0 ) - goto usage; - break; - case 'a': - pPars->fSolveAll ^= 1; - break; - case 'x': - pPars->fStoreCex ^= 1; - break; - case 'r': - pPars->fTwoRounds ^= 1; - break; - case 'm': - pPars->fMonoCnf ^= 1; - break; - case 'u': - pPars->fNewXSim ^= 1; - break; - case 'y': - pPars->fFlopPrio ^= 1; - break; - case 'f': - pPars->fFlopOrder ^= 1; - break; - case 's': - pPars->fShortest ^= 1; - break; - case 'i': - pPars->fShiftStart ^= 1; - break; - case 'p': - pPars->fReuseProofOblig ^= 1; - break; - case 'd': - pPars->fDumpInv ^= 1; - break; - case 'e': - pPars->fUseSupp ^= 1; - break; - case 'g': - pPars->fSkipGeneral ^= 1; - break; - case 'j': - pPars->fSimpleGeneral ^= 1; - break; - case 'o': - pPars->fUsePropOut ^= 1; - break; - case 'n': - pPars->fSkipDown ^= 1; - break; - case 'c': - pPars->fCtgs ^= 1; - break; - case 't': - pPars->fUseAbs ^= 1; - break; - case 'k': - pPars->fUseSimpleRef ^= 1; - break; - case 'v': - pPars->fVerbose ^= 1; - break; - case 'w': - pPars->fVeryVerbose ^= 1; - break; - case 'z': - pPars->fNotVerbose ^= 1; - break; - case 'h': - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - Abc_Print( -2, "There is no current network.\n"); - return 0; - } - if ( Abc_NtkLatchNum(pNtk) == 0 ) - { - Abc_Print( 0, "The current network is combinational.\n"); - return 0; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - Abc_Print( -2, "The current network is not an AIG (run \"strash\").\n"); - return 0; - } - // run the procedure - pPars->fUseBridge = pAbc->fBridgeMode; - pAbc->Status = Abc_NtkDarIPdr( pNtk, pPars ); - pAbc->nFrames = pNtk->vSeqModelVec ? -1 : pPars->iFrame; - Abc_FrameReplacePoStatuses( pAbc, &pPars->vOutMap ); - if ( pNtk->vSeqModelVec ) - Abc_FrameReplaceCexVec( pAbc, &pNtk->vSeqModelVec ); - else - Abc_FrameReplaceCex( pAbc, &pNtk->pSeqModel ); - return 0; - -usage: - Abc_Print( -2, "usage: ipdr [-MFCDQTHGS ] [-axrmuyfsipdegjonctkvwzh]\n" ); - Abc_Print( -2, "\t model checking using property directed reachability (aka IC3)\n" ); - Abc_Print( -2, "\t pioneered by Aaron R. Bradley (http://theory.stanford.edu/~arbrad/)\n" ); - Abc_Print( -2, "\t with improvements by Niklas Een (http://een.se/niklas/)\n" ); - Abc_Print( -2, "\t-M num : limit on unused vars to trigger SAT solver recycling [default = %d]\n", pPars->nRecycle ); - Abc_Print( -2, "\t-F num : limit on timeframes explored to stop computation [default = %d]\n", pPars->nFrameMax ); - Abc_Print( -2, "\t-C num : limit on conflicts in one SAT call (0 = no limit) [default = %d]\n", pPars->nConfLimit ); - Abc_Print( -2, "\t-D num : limit on conflicts during ind-generalization (0 = no limit) [default = %d]\n",pPars->nConfGenLimit ); - Abc_Print( -2, "\t-Q num : limit on proof obligations before a restart (0 = no limit) [default = %d]\n", pPars->nRestLimit ); - Abc_Print( -2, "\t-T num : runtime limit, in seconds (0 = no limit) [default = %d]\n", pPars->nTimeOut ); - Abc_Print( -2, "\t-H num : runtime limit per output, in miliseconds (with \"-a\") [default = %d]\n", pPars->nTimeOutOne ); - Abc_Print( -2, "\t-G num : runtime gap since the last CEX (0 = no limit) [default = %d]\n", pPars->nTimeOutGap ); - Abc_Print( -2, "\t-S num : * value to seed the SAT solver with [default = %d]\n", pPars->nRandomSeed ); - Abc_Print( -2, "\t-a : toggle solving all outputs even if one of them is SAT [default = %s]\n", pPars->fSolveAll? "yes": "no" ); - Abc_Print( -2, "\t-x : toggle storing CEXes when solving all outputs [default = %s]\n", pPars->fStoreCex? "yes": "no" ); - Abc_Print( -2, "\t-r : toggle using more effort in generalization [default = %s]\n", pPars->fTwoRounds? "yes": "no" ); - Abc_Print( -2, "\t-m : toggle using monolythic CNF computation [default = %s]\n", pPars->fMonoCnf? "yes": "no" ); - Abc_Print( -2, "\t-u : toggle updated X-valued simulation [default = %s]\n", pPars->fNewXSim? "yes": "no" ); - Abc_Print( -2, "\t-y : toggle using structural flop priorities [default = %s]\n", pPars->fFlopPrio? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle ordering flops by cost before generalization [default = %s]\n", pPars->fFlopOrder? "yes": "no" ); - Abc_Print( -2, "\t-s : toggle creating only shortest counter-examples [default = %s]\n", pPars->fShortest? "yes": "no" ); - Abc_Print( -2, "\t-i : toggle clause pushing from an intermediate timeframe [default = %s]\n", pPars->fShiftStart? "yes": "no" ); - Abc_Print( -2, "\t-p : toggle reusing proof-obligations in the last timeframe [default = %s]\n", pPars->fReuseProofOblig? "yes": "no" ); - Abc_Print( -2, "\t-d : toggle dumping invariant (valid if init state is all-0) [default = %s]\n", pPars->fDumpInv? "yes": "no" ); - Abc_Print( -2, "\t-e : toggle using only support variables in the invariant [default = %s]\n", pPars->fUseSupp? "yes": "no" ); - Abc_Print( -2, "\t-g : toggle skipping expensive generalization step [default = %s]\n", pPars->fSkipGeneral? "yes": "no" ); - Abc_Print( -2, "\t-j : toggle using simplified generalization step [default = %s]\n", pPars->fSimpleGeneral? "yes": "no" ); - Abc_Print( -2, "\t-o : toggle using property output as inductive hypothesis [default = %s]\n", pPars->fUsePropOut? "yes": "no" ); - Abc_Print( -2, "\t-n : * toggle skipping \'down\' in generalization [default = %s]\n", pPars->fSkipDown? "yes": "no" ); - Abc_Print( -2, "\t-c : * toggle handling CTGs in \'down\' [default = %s]\n", pPars->fCtgs? "yes": "no" ); - Abc_Print( -2, "\t-t : toggle using abstraction [default = %s]\n", pPars->fUseAbs? "yes": "no" ); - Abc_Print( -2, "\t-k : toggle using simplified refinement [default = %s]\n", pPars->fUseSimpleRef? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-w : toggle printing detailed stats default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); - Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n\n"); - Abc_Print( -2, "\t* Implementation of switches -S, -n, and -c is contributed by Zyad Hassan.\n"); - Abc_Print( -2, "\t The theory and experiments supporting this work can be found in the following paper:\n"); - Abc_Print( -2, "\t Zyad Hassan, Aaron R. Bradley, Fabio Somenzi, \"Better Generalization in IC3\", FMCAD 2013.\n"); - Abc_Print( -2, "\t (http://www.cs.utexas.edu/users/hunt/FMCAD/FMCAD13/papers/85-Better-Generalization-IC3.pdf)\n"); - - - return 1; } -- cgit v1.2.3 From 53b1d46b8d19e491679d9374c9758b09e2becf59 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 21 Feb 2017 22:20:03 -0800 Subject: Remapping flops in '%pdra. --- src/base/wlc/wlcAbs.c | 95 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 12 deletions(-) (limited to 'src/base') diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 1e5df918..e33424f7 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [wlcAbs1.c] + FileName [wlcAbs.c] SystemName [ABC: Logic synthesis and verification system.] @@ -8,13 +8,13 @@ Synopsis [Abstraction for word-level networks.] - Author [Alan Mishchenko] + Author [Yen-Sheng Ho, Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - August 22, 2014.] - Revision [$Id: wlcAbs1.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + Revision [$Id: wlcAbs.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -31,7 +31,7 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast ); -extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses ); +extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap ); extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses ); //////////////////////////////////////////////////////////////////////// @@ -134,7 +134,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * Wlc_NtkForEachCo( p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops ); - +/* Vec_IntClear(vFlops); Wlc_NtkForEachCi( p, pObj, i ) { if ( !Wlc_ObjIsPi(pObj) ) { @@ -142,7 +142,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * pObj->Mark = 1; } } - +*/ Wlc_NtkForEachObjVec( vFlops, p, pObj, i ) Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops ); @@ -172,7 +172,7 @@ static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * SeeAlso [] ***********************************************************************/ -static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose ) +static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, Vec_Int_t ** pvFlops, int fVerbose ) { Wlc_Ntk_t * pNtkNew = NULL; Vec_Int_t * vPisOld = Vec_IntAlloc( 100 ); @@ -183,7 +183,10 @@ static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUn Vec_BitFree( vLeaves ); pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops ); Vec_IntFree( vPisOld ); - Vec_IntFree( vFlops ); + if ( pvFlops ) + *pvFlops = vFlops; + else + Vec_IntFree( vFlops ); if ( pvPisNew ) *pvPisNew = vPisNew; else @@ -299,6 +302,55 @@ static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec return nNodes; } +/**Function************************************************************* + + Synopsis [Computes the map for remapping flop IDs used in the clauses.] + + Description [Takes the original network (Wlc_Ntk_t) and the array of word-level + flops used in the old abstraction (vFfOld) and those used in the new abstraction + (vFfNew). Returns the integer map, which remaps every binary flop found + in the old abstraction into a binary flop found in the new abstraction.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_NtkFlopsRemap( Wlc_Ntk_t * p, Vec_Int_t * vFfOld, Vec_Int_t * vFfNew ) +{ + Vec_Int_t * vMap = Vec_IntAlloc( 1000 ); // the resulting map + Vec_Int_t * vMapFfNew2Bit1 = Vec_IntAlloc( 1000 ); // first binary bit of each new word-level flop + int i, b, iFfOld, iFfNew, iBit1New, nBits = 0; + // map object IDs of old flops into their flop indexes + Vec_Int_t * vMapFfObj2FfId = Vec_IntStartFull( Wlc_NtkObjNumMax(p) ); + Vec_IntForEachEntry( vFfNew, iFfNew, i ) + Vec_IntWriteEntry( vMapFfObj2FfId, iFfNew, i ); + // map each new flop index into its first bit + Vec_IntForEachEntry( vFfNew, iFfNew, i ) + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfNew ); + int nRange = Wlc_ObjRange( pObj ); + Vec_IntPush( vMapFfNew2Bit1, nBits ); + nBits += nRange; + } + assert( Vec_IntSize(vMapFfNew2Bit1) == Vec_IntSize(vFfNew) ); + // remap old binary flops into new binary flops + Vec_IntForEachEntry( vFfOld, iFfOld, i ) + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p, iFfOld ); + int nRange = Wlc_ObjRange( pObj ); + iFfNew = Vec_IntEntry( vMapFfObj2FfId, iFfOld ); + assert( iFfNew >= 0 ); // every old flop should be present in the new abstraction + // find the first bit of this new flop + iBit1New = Vec_IntEntry( vMapFfNew2Bit1, iFfNew ); + for ( b = 0; b < nRange; b++ ) + Vec_IntPush( vMap, iBit1New + b ); + } + Vec_IntFree( vMapFfNew2Bit1 ); + Vec_IntFree( vMapFfObj2FfId ); + return vMap; +} + /**Function************************************************************* Synopsis [Performs PDR with word-level abstraction.] @@ -316,7 +368,8 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) abctime pdrClk; Pdr_Man_t * pPdr; Vec_Vec_t * vClauses = NULL; - int nIters, nNodes, nDcFlops, RetValue = -1; + Vec_Int_t * vFfOld = NULL, * vFfNew = NULL, * vMap = NULL; + int nIters, nNodes, nDcFlops, RetValue = -1, nGiaFfNumOld = -1; // start the bitmap to mark objects that cannot be abstracted because of refinement // currently, this bitmap is empty because abstraction begins without refinement Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) ); @@ -339,9 +392,25 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) printf( "\nIteration %d:\n", nIters ); // get abstracted GIA and the set of pseudo-PIs (vPisNew) - pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, &vFfNew, pPars->fVerbose ); pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); + // map old flops into new flops + if ( vFfOld ) + { + assert( nGiaFfNumOld >= 0 ); + vMap = Wlc_NtkFlopsRemap( p, vFfOld, vFfNew ); + //Vec_IntPrint( vMap ); + // if reset flop was added in the previous iteration, it will be added again in this iteration + // remap the last flop (reset flop) into the last flop (reset flop) of the current AIG + if ( Vec_IntSize(vMap) + 1 == nGiaFfNumOld ) + Vec_IntPush( vMap, Gia_ManRegNum(pGia)-1 ); + assert( Vec_IntSize(vMap) == nGiaFfNumOld ); + Vec_IntFreeP( &vFfOld ); + } + ABC_SWAP( Vec_Int_t *, vFfOld, vFfNew ); + nGiaFfNumOld = Gia_ManRegNum(pGia); + // if the abstraction has flops with DC-init state, // new PIs were introduced by bit-blasting at the end of the PI list // here we move these variables to be *before* PPIs, because @@ -373,8 +442,9 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) if ( vClauses ) { assert( Vec_VecSize( vClauses) >= 2 ); - IPdr_ManRestore( pPdr, vClauses ); + IPdr_ManRestore( pPdr, vClauses, vMap ); } + Vec_IntFreeP( &vMap ); RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses ); pPdr->tTotal += Abc_Clock() - pdrClk; @@ -418,6 +488,7 @@ int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Aig_ManStop( pAig ); } + Vec_IntFreeP( &vFfOld ); Vec_BitFree( vUnmark ); // report the result if ( pPars->fVerbose ) @@ -479,7 +550,7 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) printf( "\nIteration %d:\n", nIters ); // get abstracted GIA and the set of pseudo-PIs (vPisNew) - pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose ); + pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, NULL, pPars->fVerbose ); pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 ); // if the abstraction has flops with DC-init state, -- cgit v1.2.3