diff options
80 files changed, 2520 insertions, 7000 deletions
@@ -2114,6 +2114,10 @@ SOURCE=.\src\temp\ivy\ivyFanout.c # End Source File # Begin Source File +SOURCE=.\src\temp\ivy\ivyIsop.c +# End Source File +# Begin Source File + SOURCE=.\src\temp\ivy\ivyMan.c # End Source File # Begin Source File @@ -2166,6 +2170,10 @@ SOURCE=.\src\temp\player\playerCore.c # End Source File # Begin Source File +SOURCE=.\src\temp\player\playerFast.c +# End Source File +# Begin Source File + SOURCE=.\src\temp\player\playerMan.c # End Source File # Begin Source File @@ -1,9 +1,9 @@ # global parameters #set check # checks intermediate networks #set checkfio # prints warnings when fanins/fanouts are duplicated -set checkread # checks new networks after reading from file -set backup # saves backup networks retrived by "undo" and "recall" -set savesteps 1 # sets the maximum number of backup networks to save +#set checkread # checks new networks after reading from file +#set backup # saves backup networks retrived by "undo" and "recall" +#set savesteps 1 # sets the maximum number of backup networks to save # program names for internal calls set dotwin dot.exe diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index f89253f3..03f5a66f 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -640,6 +640,7 @@ extern char * Abc_SopCreateMux( Extra_MmFlex_t * pMan ); extern char * Abc_SopCreateInv( Extra_MmFlex_t * pMan ); extern char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan ); extern char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTruth ); +extern char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover ); extern int Abc_SopGetCubeNum( char * pSop ); extern int Abc_SopGetLitNum( char * pSop ); extern int Abc_SopGetVarNum( char * pSop ); diff --git a/src/base/abc/abcRefs.c b/src/base/abc/abcRefs.c index 91f37e8f..ea076e47 100644 --- a/src/base/abc/abcRefs.c +++ b/src/base/abc/abcRefs.c @@ -357,6 +357,32 @@ int Abc_NodeMffsInside( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vIns return Count1; } +/**Function************************************************************* + + Synopsis [Collects the internal nodes of the MFFC limited by cut.] + + Description [] + + SideEffects [Increments the trav ID and marks visited nodes.] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NodeMffsInsideCollect( Abc_Obj_t * pNode ) +{ + Vec_Ptr_t * vInside; + int Count1, Count2; + // dereference the node + Count1 = Abc_NodeDeref_rec( pNode ); + // collect the nodes inside the MFFC + vInside = Vec_PtrAlloc( 10 ); + Abc_NodeMffsConeSupp( pNode, vInside, NULL ); + // reference it back + Count2 = Abc_NodeRef_rec( pNode ); + assert( Count1 == Count2 ); + return vInside; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index a893f3e2..db0803c1 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -401,6 +401,44 @@ char * Abc_SopCreateFromTruth( Extra_MmFlex_t * pMan, int nVars, unsigned * pTru /**Function************************************************************* + Synopsis [Creates the cover from the ISOP computed from TT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover ) +{ + char * pSop, * pCube; + int i, k, Entry, Literal; + assert( Vec_IntSize(vCover) > 0 ); + if ( Vec_IntSize(vCover) == 0 ) + return NULL; + // start the cover + pSop = Abc_SopStart( pMan, Vec_IntSize(vCover), nVars ); + // create cubes + Vec_IntForEachEntry( vCover, Entry, i ) + { + pCube = pSop + i * (nVars + 3); + for ( k = 0; k < nVars; k++ ) + { + Literal = 3 & (Entry >> (k << 1)); + if ( Literal == 1 ) + pCube[k] = '1'; + else if ( Literal == 2 ) + pCube[k] = '0'; + else if ( Literal != 0 ) + assert( 0 ); + } + } + return pSop; +} + +/**Function************************************************************* + Synopsis [Reads the number of cubes in the cover.] Description [] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index eb98c722..7bee7f40 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -91,6 +91,7 @@ static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandIStrash ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandICut ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandIRewriteSeq ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIResyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -207,6 +208,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "New AIG", "istrash", Abc_CommandIStrash, 1 ); Cmd_CommandAdd( pAbc, "New AIG", "icut", Abc_CommandICut, 0 ); Cmd_CommandAdd( pAbc, "New AIG", "irw", Abc_CommandIRewrite, 1 ); + Cmd_CommandAdd( pAbc, "New AIG", "irws", Abc_CommandIRewriteSeq, 1 ); Cmd_CommandAdd( pAbc, "New AIG", "iresyn", Abc_CommandIResyn, 1 ); Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 ); @@ -4086,9 +4088,10 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) pParams->fGlobal = 0; // compute global cuts pParams->fLocal = 0; // compute local cuts pParams->fFancy = 0; // compute something fancy + pParams->fMap = 0; // compute mapping delay pParams->fVerbose = 0; // the verbosiness flag Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdxyglzvoh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdxyglzmvoh" ) ) != EOF ) { switch ( c ) { @@ -4138,6 +4141,9 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'z': pParams->fFancy ^= 1; break; + case 'm': + pParams->fMap ^= 1; + break; case 'v': pParams->fVerbose ^= 1; break; @@ -4175,7 +4181,6 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fOracle ) pParams->fRecord = 1; pCutMan = Abc_NtkCuts( pNtk, pParams ); - Cut_ManPrintStats( pCutMan ); if ( fOracle ) pCutOracle = Cut_OracleStart( pCutMan ); Cut_ManStop( pCutMan ); @@ -4187,7 +4192,7 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdxyzvh]\n" ); + fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdxyzmvh]\n" ); fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" ); fprintf( pErr, "\t-K num : max number of leaves (%d <= num <= %d) [default = %d]\n", CUT_SIZE_MIN, CUT_SIZE_MAX, pParams->nVarsMax ); fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax ); @@ -4199,6 +4204,7 @@ usage: fprintf( pErr, "\t-g : toggle computing only global cuts [default = %s]\n", pParams->fGlobal? "yes": "no" ); fprintf( pErr, "\t-l : toggle computing only local cuts [default = %s]\n", pParams->fLocal? "yes": "no" ); fprintf( pErr, "\t-z : toggle fancy computations [default = %s]\n", pParams->fFancy? "yes": "no" ); + fprintf( pErr, "\t-m : toggle delay-oriented FPGA mapping [default = %s]\n", pParams->fMap? "yes": "no" ); fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; @@ -4293,7 +4299,6 @@ int Abc_CommandScut( Abc_Frame_t * pAbc, int argc, char ** argv ) } pCutMan = Abc_NtkSeqCuts( pNtk, pParams ); - Cut_ManPrintStats( pCutMan ); Cut_ManStop( pCutMan ); return 0; @@ -4480,27 +4485,31 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int nLutMax; int nPlaMax; + int RankCost; + int fFastMode; int fVerbose; // extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nPlaMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); - extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose ); + extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); // set defaults - nLutMax = 8; - nPlaMax = 128; - fVerbose = 0; + nLutMax = 8; + nPlaMax = 128; + RankCost = 96000; + fFastMode = 0; + fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "LPvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "LPRfvh" ) ) != EOF ) { switch ( c ) { case 'L': if ( globalUtilOptind >= argc ) { - fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); + fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" ); goto usage; } nLutMax = atoi(argv[globalUtilOptind]); @@ -4511,7 +4520,7 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'P': if ( globalUtilOptind >= argc ) { - fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); + fprintf( pErr, "Command line switch \"-P\" should be followed by an integer.\n" ); goto usage; } nPlaMax = atoi(argv[globalUtilOptind]); @@ -4519,6 +4528,20 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nPlaMax < 0 ) goto usage; break; + case 'R': + if ( globalUtilOptind >= argc ) + { + fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" ); + goto usage; + } + RankCost = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( RankCost < 0 ) + goto usage; + break; + case 'f': + fFastMode ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -4548,7 +4571,7 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) // run the command // pNtkRes = Abc_NtkXyz( pNtk, nPlaMax, 1, 0, fUseInvs, fVerbose ); - pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, fVerbose ); + pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, RankCost, fFastMode, fVerbose ); if ( pNtkRes == NULL ) { fprintf( pErr, "Command has failed.\n" ); @@ -4559,10 +4582,12 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: xyz [-L num] [-P num] [-vh]\n" ); + fprintf( pErr, "usage: xyz [-L num] [-P num] [-R num] [-fvh]\n" ); fprintf( pErr, "\t specilized LUT/PLA decomposition\n" ); fprintf( pErr, "\t-L num : maximum number of LUT inputs (2<=num<=8) [default = %d]\n", nLutMax ); fprintf( pErr, "\t-P num : maximum number of PLA inputs/cubes (8<=num<=128) [default = %d]\n", nPlaMax ); + fprintf( pErr, "\t-R num : maximum are of one decomposition rank [default = %d]\n", RankCost ); + fprintf( pErr, "\t-f : toggle using fast LUT mapping mode [default = %s]\n", fFastMode? "yes": "no" ); fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; @@ -4744,7 +4769,7 @@ int Abc_CommandIStrash( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pNtkRes == NULL ) { fprintf( pErr, "Command has failed.\n" ); - return 1; + return 0; } // replace the current network Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); @@ -4886,7 +4911,7 @@ int Abc_CommandIRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pNtkRes == NULL ) { fprintf( pErr, "Command has failed.\n" ); - return 1; + return 0; } // replace the current network Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); @@ -4913,6 +4938,83 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandIRewriteSeq( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c, fUpdateLevel, fUseZeroCost, fVerbose; + extern Abc_Ntk_t * Abc_NtkIvyRewriteSeq( Abc_Ntk_t * pNtk, int fUseZeroCost, int fVerbose ); + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fUpdateLevel = 1; + fUseZeroCost = 0; + fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "lzvh" ) ) != EOF ) + { + switch ( c ) + { + case 'l': + fUpdateLevel ^= 1; + break; + case 'z': + fUseZeroCost ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( Abc_NtkIsSeq(pNtk) ) + { + fprintf( pErr, "Only works for non-sequential networks.\n" ); + return 1; + } + + pNtkRes = Abc_NtkIvyRewriteSeq( pNtk, fUseZeroCost, fVerbose ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Command has failed.\n" ); + return 0; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: irws [-zvh]\n" ); + fprintf( pErr, "\t perform sequential AIG rewriting\n" ); +// fprintf( pErr, "\t-l : toggle preserving the number of levels [default = %s]\n", fUpdateLevel? "yes": "no" ); + fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeroCost? "yes": "no" ); + fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandIResyn( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; @@ -4959,7 +5061,7 @@ int Abc_CommandIResyn( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pNtkRes == NULL ) { fprintf( pErr, "Command has failed.\n" ); - return 1; + return 0; } // replace the current network Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); @@ -5915,11 +6017,12 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fRecovery; int fSwitching; + int fLatchPaths; int fVerbose; int nLutSize; float DelayTarget; - extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fVerbose ); + extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -5928,11 +6031,12 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults fRecovery = 1; fSwitching = 0; + fLatchPaths = 0; fVerbose = 0; DelayTarget =-1; nLutSize =-1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "apvhDK" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "aplvhDK" ) ) != EOF ) { switch ( c ) { @@ -5942,6 +6046,9 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'p': fSwitching ^= 1; break; + case 'l': + fLatchPaths ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -5989,7 +6096,13 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) // create the new LUT library if ( nLutSize >= 3 && nLutSize <= 6 ) Fpga_SetSimpleLutLib( nLutSize ); - +/* + else + { + fprintf( pErr, "Cannot perform FPGA mapping with LUT size %d.\n", nLutSize ); + return 1; + } +*/ if ( !Abc_NtkIsStrash(pNtk) ) { // strash and balance the network @@ -6008,7 +6121,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) } fprintf( pOut, "The network was strashed and balanced before FPGA mapping.\n" ); // get the new network - pNtkRes = Abc_NtkFpga( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose ); + pNtkRes = Abc_NtkFpga( pNtk, DelayTarget, fRecovery, fSwitching, fLatchPaths, fVerbose ); if ( pNtkRes == NULL ) { Abc_NtkDelete( pNtk ); @@ -6020,7 +6133,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) else { // get the new network - pNtkRes = Abc_NtkFpga( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose ); + pNtkRes = Abc_NtkFpga( pNtk, DelayTarget, fRecovery, fSwitching, fLatchPaths, fVerbose ); if ( pNtkRes == NULL ) { fprintf( pErr, "FPGA mapping has failed.\n" ); @@ -6040,10 +6153,11 @@ usage: sprintf( LutSize, "library" ); else sprintf( LutSize, "%d", nLutSize ); - fprintf( pErr, "usage: fpga [-D float] [-K num] [-apvh]\n" ); + fprintf( pErr, "usage: fpga [-D float] [-K num] [-aplvh]\n" ); fprintf( pErr, "\t performs FPGA mapping of the current network\n" ); fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" ); fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", fSwitching? "yes": "no" ); + fprintf( pErr, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", fLatchPaths? "yes": "no" ); fprintf( pErr, "\t-D float : sets the required time for the mapping [default = %s]\n", Buffer ); fprintf( pErr, "\t-K num : the number of LUT inputs [default = %s]%s\n", LutSize, (nLutSize == -1 ? " (type \"print_lut\")" : "") ); fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c index 00045bf4..c7c164b9 100644 --- a/src/base/abci/abcCut.c +++ b/src/base/abci/abcCut.c @@ -32,6 +32,7 @@ static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ); extern int nTotal, nGood, nEqual; static Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ); +static int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -117,7 +118,9 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) Extra_ProgressBarStop( pProgress ); Vec_PtrFree( vNodes ); Vec_IntFree( vChoices ); -PRT( "Total", clock() - clk ); + Cut_ManPrintStats( p ); +PRT( "TOTAL ", clock() - clk ); + printf( "Area = %d.\n", Abc_NtkComputeArea( pNtk, p ) ); //Abc_NtkPrintCuts( p, pNtk, 0 ); // Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk ); @@ -279,7 +282,8 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) pObj->fMarkC = 0; if ( pParams->fVerbose ) { -PRT( "Total", clock() - clk ); + Cut_ManPrintStats( p ); +PRT( "TOTAL ", clock() - clk ); printf( "Converged after %d iterations.\n", nIters ); } //Abc_NtkPrintCuts( p, pNtk, 1 ); @@ -288,6 +292,27 @@ printf( "Converged after %d iterations.\n", nIters ); /**Function************************************************************* + Synopsis [Computes area.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p ) +{ + Abc_Obj_t * pObj; + int Counter, i; + Counter = 0; + Abc_NtkForEachCo( pNtk, pObj, i ) + Counter += Cut_ManMappingArea_rec( p, Abc_ObjFaninId0(pObj) ); + return Counter; +} + +/**Function************************************************************* + Synopsis [Computes the cuts for the network.] Description [] @@ -479,21 +504,51 @@ void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk ) +Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) { Vec_Int_t * vAttrs; - Abc_Obj_t * pObj; - int i; +// Vec_Ptr_t * vNodes; + Abc_Obj_t * pObj;//, * pTemp; + int i;//, k; + int nNodesTotal = 0, nMffcsTotal = 0; + extern Vec_Ptr_t * Abc_NodeMffsInsideCollect( Abc_Obj_t * pNode ); vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 ); // Abc_NtkForEachCi( pNtk, pObj, i ) // Vec_IntWriteEntry( vAttrs, pObj->Id, 1 ); + Abc_NtkForEachObj( pNtk, pObj, i ) { + if ( Abc_ObjIsNode(pObj) ) + nNodesTotal++; + if ( Abc_ObjIsCo(pObj) && Abc_ObjIsNode(Abc_ObjFanin0(pObj)) ) + nMffcsTotal += Abc_NodeMffcSize( Abc_ObjFanin0(pObj) ); // if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) ) - if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) ) - Vec_IntWriteEntry( vAttrs, pObj->Id, 1 ); +// if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) ) + if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) ) + { + int nMffc = Abc_NodeMffcSize(pObj); + nMffcsTotal += Abc_NodeMffcSize(pObj); +// printf( "%d ", nMffc ); + + if ( nMffc > 2 || Abc_ObjFanoutNum(pObj) > 8 ) + Vec_IntWriteEntry( vAttrs, pObj->Id, 1 ); + } } +/* + Abc_NtkForEachObj( pNtk, pObj, i ) + { + if ( Vec_IntEntry( vAttrs, pObj->Id ) ) + { + vNodes = Abc_NodeMffsInsideCollect( pObj ); + Vec_PtrForEachEntry( vNodes, pTemp, k ) + if ( pTemp != pObj ) + Vec_IntWriteEntry( vAttrs, pTemp->Id, 0 ); + Vec_PtrFree( vNodes ); + } + } +*/ + printf( "Total nodes = %d. Total MFFC nodes = %d.\n", nNodesTotal, nMffcsTotal ); return vAttrs; } @@ -533,7 +588,7 @@ int Abc_NtkSubDagSize_rec( Abc_Obj_t * pObj, Vec_Int_t * vAttrs ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) +Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk ) { Vec_Int_t * vAttrs; Abc_Obj_t * pObj; diff --git a/src/base/abci/abcFpga.c b/src/base/abci/abcFpga.c index 8ae0287c..a59ef2af 100644 --- a/src/base/abci/abcFpga.c +++ b/src/base/abci/abcFpga.c @@ -25,7 +25,7 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose ); +static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose ); static Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk ); static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga ); @@ -44,7 +44,7 @@ static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNo SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fVerbose ) +Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose ) { int fShowSwitching = 1; Abc_Ntk_t * pNtkNew; @@ -68,11 +68,13 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int } // perform FPGA mapping - pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fVerbose ); + pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fLatchPaths, fVerbose ); if ( pSwitching ) Vec_IntFree( vSwitching ); if ( pMan == NULL ) return NULL; Fpga_ManSetSwitching( pMan, fSwitching ); + Fpga_ManSetLatchPaths( pMan, fLatchPaths ); + Fpga_ManSetLatchNum( pMan, Abc_NtkLatchNum(pNtk) ); Fpga_ManSetDelayTarget( pMan, DelayTarget ); if ( !Fpga_Mapping( pMan ) ) { @@ -113,13 +115,14 @@ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int SeeAlso [] ***********************************************************************/ -Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose ) +Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose ) { Fpga_Man_t * pMan; ProgressBar * pProgress; Fpga_Node_t * pNodeFpga; Vec_Ptr_t * vNodes; Abc_Obj_t * pNode, * pFanin, * pPrev; + float * pfArrivals; int i; assert( Abc_NtkIsStrash(pNtk) ); @@ -130,7 +133,13 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, return NULL; Fpga_ManSetAreaRecovery( pMan, fRecovery ); Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) ); - Fpga_ManSetInputArrivals( pMan, Abc_NtkGetCiArrivalFloats(pNtk) ); + pfArrivals = Abc_NtkGetCiArrivalFloats(pNtk); + if ( fLatchPaths ) + { + for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ ) + pfArrivals[i] = -FPGA_FLOAT_LARGE; + } + Fpga_ManSetInputArrivals( pMan, pfArrivals ); // create PIs and remember them in the old nodes Abc_NtkCleanCopy( pNtk ); diff --git a/src/base/abci/abcFraig.c b/src/base/abci/abcFraig.c index 49b24be8..46f2cdf0 100644 --- a/src/base/abci/abcFraig.c +++ b/src/base/abci/abcFraig.c @@ -63,8 +63,8 @@ Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int f // perform fraiging pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes, fExdc ); // add algebraic choices - if ( pPars->fChoicing ) - Fraig_ManAddChoices( pMan, 0, 6 ); +// if ( pPars->fChoicing ) +// Fraig_ManAddChoices( pMan, 0, 6 ); // prove the miter if asked to if ( pPars->fTryProve ) Fraig_ManProveMiter( pMan ); diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index 1ef84c20..a3ffcf4e 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -50,7 +50,7 @@ static inline Abc_Obj_t * Abc_EdgeToNode( Abc_Ntk_t * p, Abc_Edge_t Edge ) { static inline Abc_Obj_t * Abc_ObjFanin0Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin0(pObj)->TravId), Ivy_ObjFaninC0(pObj) ); } static inline Abc_Obj_t * Abc_ObjFanin1Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin1(pObj)->TravId), Ivy_ObjFaninC1(pObj) ); } -static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk ); +static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -67,7 +67,7 @@ static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk ); SeeAlso [] ***********************************************************************/ -Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq ) +Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc ) { Ivy_Man_t * pMan; int fCleanup = 1; @@ -101,7 +101,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq ) if ( fSeq ) { int nLatches = Abc_NtkLatchNum(pNtk); - int * pInit = Abc_NtkCollectLatchValues( pNtk ); + int * pInit = Abc_NtkCollectLatchValues( pNtk, fUseDc ); Ivy_ManMakeSeq( pMan, nLatches, pInit ); FREE( pInit ); // Ivy_ManPrintStats( pMan ); @@ -160,7 +160,7 @@ Abc_Ntk_t * Abc_NtkIvyStrash( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkAig; Ivy_Man_t * pMan; - pMan = Abc_NtkIvyBefore( pNtk, 1 ); + pMan = Abc_NtkIvyBefore( pNtk, 1, 0 ); if ( pMan == NULL ) return NULL; pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 1 ); @@ -183,7 +183,7 @@ void Abc_NtkIvyCuts( Abc_Ntk_t * pNtk, int nInputs ) { extern void Ivy_CutComputeAll( Ivy_Man_t * p, int nInputs ); Ivy_Man_t * pMan; - pMan = Abc_NtkIvyBefore( pNtk, 1 ); + pMan = Abc_NtkIvyBefore( pNtk, 1, 0 ); if ( pMan == NULL ) return; Ivy_CutComputeAll( pMan, nInputs ); @@ -205,7 +205,7 @@ Abc_Ntk_t * Abc_NtkIvyRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeroC { Abc_Ntk_t * pNtkAig; Ivy_Man_t * pMan; - pMan = Abc_NtkIvyBefore( pNtk, 0 ); + pMan = Abc_NtkIvyBefore( pNtk, 0, 0 ); if ( pMan == NULL ) return NULL; Ivy_ManRewritePre( pMan, fUpdateLevel, fUseZeroCost, fVerbose ); @@ -225,11 +225,35 @@ Abc_Ntk_t * Abc_NtkIvyRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeroC SeeAlso [] ***********************************************************************/ +Abc_Ntk_t * Abc_NtkIvyRewriteSeq( Abc_Ntk_t * pNtk, int fUseZeroCost, int fVerbose ) +{ + Abc_Ntk_t * pNtkAig; + Ivy_Man_t * pMan; + pMan = Abc_NtkIvyBefore( pNtk, 1, 1 ); + if ( pMan == NULL ) + return NULL; + Ivy_ManRewriteSeq( pMan, fUseZeroCost, fVerbose ); + pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 1 ); + Ivy_ManStop( pMan ); + return pNtkAig; +} + +/**Function************************************************************* + + Synopsis [Gives the current ABC network to AIG manager for processing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose ) { Abc_Ntk_t * pNtkAig; Ivy_Man_t * pMan, * pTemp; - pMan = Abc_NtkIvyBefore( pNtk, 0 ); + pMan = Abc_NtkIvyBefore( pNtk, 0, 0 ); if ( pMan == NULL ) return NULL; pMan = Ivy_ManResyn( pTemp = pMan, fUpdateLevel, fVerbose ); @@ -253,11 +277,11 @@ Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose ) Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkAig; - Ivy_Man_t * pMan, * pTemp; + Ivy_Man_t * pMan;//, * pTemp; int fCleanup = 1; int nNodes; int nLatches = Abc_NtkLatchNum(pNtk); - int * pInit = Abc_NtkCollectLatchValues( pNtk ); + int * pInit = Abc_NtkCollectLatchValues( pNtk, 0 ); assert( !Abc_NtkIsNetlist(pNtk) ); assert( !Abc_NtkIsSeq(pNtk) ); @@ -304,7 +328,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ) // pMan = Ivy_ManResyn( pTemp = pMan, 1, 0 ); // Ivy_ManStop( pTemp ); - Ivy_ManTestCutsAll( pMan ); +// Ivy_ManTestCutsAll( pMan ); // Ivy_ManPrintStats( pMan ); @@ -319,6 +343,10 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ) // Ivy_ManRequiredLevels( pMan ); + Pla_ManFastLutMap( pMan, 8 ); + Ivy_ManStop( pMan ); + return NULL; +/* // convert from the AIG manager pNtkAig = Abc_NtkFromAig( pNtk, pMan ); // pNtkAig = Abc_NtkFromAigSeq( pNtk, pMan ); @@ -341,6 +369,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ) FREE( pInit ); return pNtkAig; +*/ } @@ -717,14 +746,14 @@ Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pRoot, cha SeeAlso [] ***********************************************************************/ -int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk ) +int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk, int fUseDcs ) { Abc_Obj_t * pLatch; int * pArray, i; pArray = ALLOC( int, Abc_NtkLatchNum(pNtk) ); Abc_NtkForEachLatch( pNtk, pLatch, i ) { - if ( Abc_LatchIsInitDc(pLatch) ) + if ( fUseDcs || Abc_LatchIsInitDc(pLatch) ) pArray[i] = IVY_INIT_DC; else if ( Abc_LatchIsInit1(pLatch) ) pArray[i] = IVY_INIT_1; diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index 0124d7bf..cb32def5 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -300,6 +300,7 @@ void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk ) nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) ); else nFanouts = Abc_ObjFanoutNum(pNode); +// nFanouts = Abc_NodeMffcSize(pNode); if ( nFanins > vFanins->nSize || nFanouts > vFanouts->nSize ) { nOldSize = vFanins->nSize; diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c index b21278f7..f447516f 100644 --- a/src/base/abci/abcSat.c +++ b/src/base/abci/abcSat.c @@ -396,6 +396,26 @@ void Abc_NtkCollectSupergate( Abc_Obj_t * pNode, int fStopAtMux, Vec_Ptr_t * vNo /**Function************************************************************* + Synopsis [Computes the factor of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkNodeFactor( Abc_Obj_t * pObj, int nLevelMax ) +{ +// nLevelMax = ((nLevelMax)/2)*3; + assert( pObj->Level <= nLevelMax ); +// return (int)(100000000.0 * pow(0.999, nLevelMax - pObj->Level)); + return (int)(100000000.0 * (1 + 0.01 * pObj->Level)); +// return (int)(100000000.0 / ((nLevelMax)/2)*3 - pObj->Level); +} + +/**Function************************************************************* + Synopsis [Sets up the SAT solver.] Description [] @@ -409,11 +429,13 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront ) { Abc_Obj_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE; Vec_Ptr_t * vNodes, * vSuper; +// Vec_Int_t * vLevels; Vec_Int_t * vVars, * vFanio; Vec_Vec_t * vCircuit; int i, k, fUseMuxes = 1; int clk1 = clock(), clk; int fOrderCiVarsFirst = 0; + int nLevelsMax = Abc_AigGetLevelNum(pNtk); assert( Abc_NtkIsStrash(pNtk) ); @@ -422,9 +444,9 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront ) pNode->pCopy = NULL; // start the data structures - vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver - vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate - vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause + vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver + vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate + vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause if ( fJFront ) vCircuit = Vec_VecAlloc( 1000 ); // vCircuit = Vec_VecStart( 184 ); @@ -565,7 +587,16 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront ) // Asat_JManStop( pSat ); // PRT( "Total", clock() - clk1 ); } - +/* + // create factors + vLevels = Vec_IntStart( Vec_PtrSize(vNodes) ); // the reverse levels of the nodes + Abc_NtkForEachObj( pNtk, pNode, i ) + if ( pNode->fMarkA ) + Vec_IntWriteEntry( vLevels, (int)pNode->pCopy, Abc_NtkNodeFactor(pNode, nLevelsMax) ); + assert( Vec_PtrSize(vNodes) == Vec_IntSize(vLevels) ); + Asat_SolverSetFactors( pSat, Vec_IntReleaseArray(vLevels) ); + Vec_IntFree( vLevels ); +*/ // delete Vec_IntFree( vVars ); Vec_PtrFree( vNodes ); diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index 39aebc83..ecf77f70 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -136,9 +136,11 @@ void Abc_FrameDeallocate( Abc_Frame_t * p ) { extern void Rwt_ManGlobalStop(); extern void undefine_cube_size(); + extern void Ivy_TruthManStop(); // Abc_HManStop(); undefine_cube_size(); Rwt_ManGlobalStop(); + Ivy_TruthManStop(); if ( p->pManDec ) Dec_ManStop( p->pManDec ); if ( p->dd ) Extra_StopManager( p->dd ); Abc_FrameDeleteAllNetworks( p ); diff --git a/src/map/fpga/fpga.h b/src/map/fpga/fpga.h index ee65f7a8..df4a9189 100644 --- a/src/map/fpga/fpga.h +++ b/src/map/fpga/fpga.h @@ -96,8 +96,9 @@ extern void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNode extern void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices ); extern void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose ); extern void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching ); -extern void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ); +extern void Fpga_ManSetLatchPaths( Fpga_Man_t * p, int fLatchPaths ); extern void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ); +extern void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ); extern void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ); extern int Fpga_LibReadLutMax( Fpga_LutLib_t * pLib ); diff --git a/src/map/fpga/fpgaCore.c b/src/map/fpga/fpgaCore.c index 36842ecf..fbf33816 100644 --- a/src/map/fpga/fpgaCore.c +++ b/src/map/fpga/fpgaCore.c @@ -100,6 +100,9 @@ int Fpga_MappingPostProcess( Fpga_Man_t * p ) float aAreaTotalCur, aAreaTotalCur2; int Iter, clk; +if ( p->fVerbose ) + printf( "Best clock period = %5.2f\n", Fpga_TimeComputeArrivalMax(p) ); + // compute area, set references, and collect nodes used in the mapping Iter = 1; aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); diff --git a/src/map/fpga/fpgaCreate.c b/src/map/fpga/fpgaCreate.c index e6a9716f..41bea4d0 100644 --- a/src/map/fpga/fpgaCreate.c +++ b/src/map/fpga/fpgaCreate.c @@ -66,8 +66,9 @@ void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes ) { p void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices ) { p->nChoices = nChoices; } void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; } void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; } -void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget; } +void Fpga_ManSetLatchPaths( Fpga_Man_t * p, int fLatchPaths ) { p->fLatchPaths = fLatchPaths; } void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ) { p->nLatches = nLatches; } +void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget; } void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ) { p->pFileName = pFileName; } /**Function************************************************************* diff --git a/src/map/fpga/fpgaCut.c b/src/map/fpga/fpgaCut.c index dc2e420b..01562708 100644 --- a/src/map/fpga/fpgaCut.c +++ b/src/map/fpga/fpgaCut.c @@ -35,9 +35,9 @@ struct Fpga_CutTableStrutct_t }; // the largest number of cuts considered -#define FPGA_CUTS_MAX_COMPUTE 5000 +#define FPGA_CUTS_MAX_COMPUTE 500 // the largest number of cuts used -#define FPGA_CUTS_MAX_USE 2000 +#define FPGA_CUTS_MAX_USE 200 // primes used to compute the hash key static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 }; diff --git a/src/map/fpga/fpgaInt.h b/src/map/fpga/fpgaInt.h index 318def25..74ab321c 100644 --- a/src/map/fpga/fpgaInt.h +++ b/src/map/fpga/fpgaInt.h @@ -122,6 +122,7 @@ struct Fpga_ManStruct_t_ int fAreaRecovery; // the flag to use area flow as the first parameter int fVerbose; // the verbosiness flag int fSwitching; // minimize the switching activity (instead of area) + int fLatchPaths; // optimize latch paths for delay, other paths for area int nTravIds; // the counter of traversal IDs float DelayTarget; // the target required times diff --git a/src/map/fpga/fpgaTime.c b/src/map/fpga/fpgaTime.c index 76109b6e..380ff592 100644 --- a/src/map/fpga/fpgaTime.c +++ b/src/map/fpga/fpgaTime.c @@ -87,13 +87,34 @@ float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p ) { float fRequired; int i; + if ( p->fLatchPaths && p->nLatches == 0 ) + { + printf( "Delay optimization of latch path is not performed because there is no latches.\n" ); + p->fLatchPaths = 0; + } // get the critical PO arrival time fRequired = -FPGA_FLOAT_LARGE; - for ( i = 0; i < p->nOutputs; i++ ) + if ( p->fLatchPaths ) { - if ( Fpga_NodeIsConst(p->pOutputs[i]) ) - continue; - fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); + for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ ) + { + if ( Fpga_NodeIsConst(p->pOutputs[i]) ) + continue; + fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); +// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); + } +// printf( "Required latches = %5.1f\n", fRequired ); + } + else + { + for ( i = 0; i < p->nOutputs; i++ ) + { + if ( Fpga_NodeIsConst(p->pOutputs[i]) ) + continue; + fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); +// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); + } +// printf( "Required outputs = %5.1f\n", fRequired ); } return fRequired; } @@ -148,10 +169,23 @@ void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired ) for ( i = 0; i < p->vAnds->nSize; i++ ) p->vAnds->pArray[i]->tRequired = FPGA_FLOAT_LARGE; // set the required times for the POs - for ( i = 0; i < p->nOutputs; i++ ) - Fpga_Regular(p->pOutputs[i])->tRequired = fRequired; + if ( p->fLatchPaths ) + for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ ) + Fpga_Regular(p->pOutputs[i])->tRequired = fRequired; + else + for ( i = 0; i < p->nOutputs; i++ ) + Fpga_Regular(p->pOutputs[i])->tRequired = fRequired; // collect nodes reachable from POs in the DFS order through the best cuts Fpga_TimePropagateRequired( p, p->vMapping ); +/* + { + int Counter = 0; + for ( i = 0; i < p->vAnds->nSize; i++ ) + if ( p->vAnds->pArray[i]->tRequired > FPGA_FLOAT_LARGE - 100 ) + Counter++; + printf( "The number of nodes with large required times = %d.\n", Counter ); + } +*/ } /**Function************************************************************* diff --git a/src/misc/extra/extraUtilTruth.c b/src/misc/extra/extraUtilTruth.c index 83153863..6b10813c 100644 --- a/src/misc/extra/extraUtilTruth.c +++ b/src/misc/extra/extraUtilTruth.c @@ -662,7 +662,7 @@ void Extra_TruthMux( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nV for ( i = 0; i < Step; i++ ) { pOut[i] = pCof0[i]; - pOut[Step+i] = pCof1[i]; + pOut[Step+i] = pCof1[Step+i]; } pOut += 2*Step; } diff --git a/src/misc/nm/nmApi.c b/src/misc/nm/nmApi.c index 3a9ac074..e44d1ef9 100644 --- a/src/misc/nm/nmApi.c +++ b/src/misc/nm/nmApi.c @@ -46,8 +46,8 @@ Nm_Man_t * Nm_ManCreate( int nSize ) p = ALLOC( Nm_Man_t, 1 ); memset( p, 0, sizeof(Nm_Man_t) ); // set the parameters - p->nSizeFactor = 3; // determined how much larger the table should be compared to data in it - p->nGrowthFactor = 3; // determined how much the table grows after resizing + p->nSizeFactor = 4; // determined how much larger the table should be compared to data in it + p->nGrowthFactor = 4; // determined how much the table grows after resizing // allocate and clean the bins p->nBins = Cudd_PrimeNm(p->nSizeFactor*nSize); p->pBinsI2N = ALLOC( Nm_Entry_t *, p->nBins ); diff --git a/src/misc/nm/nmTable.c b/src/misc/nm/nmTable.c index 65f16e04..4243244d 100644 --- a/src/misc/nm/nmTable.c +++ b/src/misc/nm/nmTable.c @@ -44,7 +44,7 @@ static unsigned Nm_HashString( char * pName, int TableSize ) }; unsigned i, Key = 0; for ( i = 0; pName[i] != '\0'; i++ ) - Key ^= s_Primes[i%10]*pName[i]*pName[i]; + Key ^= s_Primes[i%10]*pName[i]*pName[i]*pName[i]; return Key % TableSize; } diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h index f2413703..07ac0f17 100644 --- a/src/misc/vec/vecPtr.h +++ b/src/misc/vec/vecPtr.h @@ -525,10 +525,18 @@ static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry ) static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry ) { int i; + // delete assuming that it is closer to the end + for ( i = p->nSize - 1; i >= 0; i-- ) + if ( p->pArray[i] == Entry ) + break; + assert( i >= 0 ); +/* + // delete assuming that it is closer to the beginning for ( i = 0; i < p->nSize; i++ ) if ( p->pArray[i] == Entry ) break; assert( i < p->nSize ); +*/ for ( i++; i < p->nSize; i++ ) p->pArray[i-1] = p->pArray[i]; p->nSize--; diff --git a/src/opt/cut/abcCut.c b/src/opt/cut/abcCut.c deleted file mode 100644 index b4b879a3..00000000 --- a/src/opt/cut/abcCut.c +++ /dev/null @@ -1,491 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcCut.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Interface to cut computation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "cut.h" -#include "seqInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq ); -static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ); - - -extern int nTotal, nGood, nEqual; - -// temporary -//Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) { return NULL; } -Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) -{ - Vec_Int_t * vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 ); - int i; - Abc_Obj_t * pObj; - -// Abc_NtkForEachCi( pNtk, pObj, i ) -// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 ); - - Abc_NtkForEachObj( pNtk, pObj, i ) - { -// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) ) - if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) ) - Vec_IntWriteEntry( vAttrs, pObj->Id, 1 ); - } - return vAttrs; -} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) -{ - ProgressBar * pProgress; - Cut_Man_t * p; - Abc_Obj_t * pObj, * pNode; - Vec_Ptr_t * vNodes; - Vec_Int_t * vChoices; - int i; - int clk = clock(); - - extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk ); - extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk ); - - nTotal = nGood = nEqual = 0; - - assert( Abc_NtkIsStrash(pNtk) ); - // start the manager - pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); - p = Cut_ManStart( pParams ); - // compute node attributes if local or global cuts are requested - if ( pParams->fGlobal || pParams->fLocal ) - { - extern Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ); - Cut_ManSetNodeAttrs( p, Abc_NtkGetNodeAttributes(pNtk) ); - } - // prepare for cut dropping - if ( pParams->fDrop ) - Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) ); - // set cuts for PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_NodeSetTriv( p, pObj->Id ); - // compute cuts for internal nodes - vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs - vChoices = Vec_IntAlloc( 100 ); - pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // when we reached a CO, it is time to deallocate the cuts - if ( Abc_ObjIsCo(pObj) ) - { - if ( pParams->fDrop ) - Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - continue; - } - // skip constant node, it has no cuts - if ( Abc_NodeIsConst(pObj) ) - continue; - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // compute the cuts to the internal node - Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree ); - // consider dropping the fanins cuts - if ( pParams->fDrop ) - { - Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) ); - } - // add cuts due to choices - if ( Abc_NodeIsAigChoice(pObj) ) - { - Vec_IntClear( vChoices ); - for ( pNode = pObj; pNode; pNode = pNode->pData ) - Vec_IntPush( vChoices, pNode->Id ); - Cut_NodeUnionCuts( p, vChoices ); - } - } - Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); - Vec_IntFree( vChoices ); -PRT( "Total", clock() - clk ); -//Abc_NtkPrintCuts( p, pNtk, 0 ); -// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk ); - - // temporary printout of stats - if ( nTotal ) - printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal ); - return p; -} - -/**Function************************************************************* - - Synopsis [Cut computation using the oracle.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p ) -{ - Abc_Obj_t * pObj; - Vec_Ptr_t * vNodes; - int i, clk = clock(); - int fDrop = Cut_OracleReadDrop(p); - - assert( Abc_NtkIsStrash(pNtk) ); - - // prepare cut droppping - if ( fDrop ) - Cut_OracleSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) ); - - // set cuts for PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_OracleNodeSetTriv( p, pObj->Id ); - - // compute cuts for internal nodes - vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // when we reached a CO, it is time to deallocate the cuts - if ( Abc_ObjIsCo(pObj) ) - { - if ( fDrop ) - Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - continue; - } - // skip constant node, it has no cuts - if ( Abc_NodeIsConst(pObj) ) - continue; - // compute the cuts to the internal node - Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); - // consider dropping the fanins cuts - if ( fDrop ) - { - Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId1(pObj) ); - } - } - Vec_PtrFree( vNodes ); -//PRT( "Total", clock() - clk ); -//Abc_NtkPrintCuts_( p, pNtk, 0 ); -} - - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) -{ - Cut_Man_t * p; - Abc_Obj_t * pObj, * pNode; - int i, nIters, fStatus; - Vec_Int_t * vChoices; - int clk = clock(); - - assert( Abc_NtkIsSeq(pNtk) ); - assert( pParams->fSeq ); -// assert( Abc_NtkIsDfsOrdered(pNtk) ); - - // start the manager - pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); - pParams->nCutSet = Abc_NtkCutSetNodeNum( pNtk ); - p = Cut_ManStart( pParams ); - - // set cuts for the constant node and the PIs - pObj = Abc_NtkConst1(pNtk); - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_NodeSetTriv( p, pObj->Id ); - Abc_NtkForEachPi( pNtk, pObj, i ) - { -//printf( "Setting trivial cut %d.\n", pObj->Id ); - Cut_NodeSetTriv( p, pObj->Id ); - } - // label the cutset nodes and set their number in the array - // assign the elementary cuts to the cutset nodes - Abc_SeqForEachCutsetNode( pNtk, pObj, i ) - { - assert( pObj->fMarkC == 0 ); - pObj->fMarkC = 1; - pObj->pCopy = (Abc_Obj_t *)i; - Cut_NodeSetTriv( p, pObj->Id ); -//printf( "Setting trivial cut %d.\n", pObj->Id ); - } - - // process the nodes - vChoices = Vec_IntAlloc( 100 ); - for ( nIters = 0; nIters < 10; nIters++ ) - { -//printf( "ITERATION %d:\n", nIters ); - // compute the cuts for the internal nodes - Abc_AigForEachAnd( pNtk, pObj, i ) - { - Abc_NodeGetCutsSeq( p, pObj, nIters==0 ); - // add cuts due to choices - if ( Abc_NodeIsAigChoice(pObj) ) - { - Vec_IntClear( vChoices ); - for ( pNode = pObj; pNode; pNode = pNode->pData ) - Vec_IntPush( vChoices, pNode->Id ); - Cut_NodeUnionCutsSeq( p, vChoices, (pObj->fMarkC ? (int)pObj->pCopy : -1), nIters==0 ); - } - } - // merge the new cuts with the old cuts - Abc_NtkForEachPi( pNtk, pObj, i ) - Cut_NodeNewMergeWithOld( p, pObj->Id ); - Abc_AigForEachAnd( pNtk, pObj, i ) - Cut_NodeNewMergeWithOld( p, pObj->Id ); - // for the cutset, transfer temp cuts to new cuts - fStatus = 0; - Abc_SeqForEachCutsetNode( pNtk, pObj, i ) - fStatus |= Cut_NodeTempTransferToNew( p, pObj->Id, i ); - if ( fStatus == 0 ) - break; - } - Vec_IntFree( vChoices ); - - // if the status is not finished, transfer new to old for the cutset - Abc_SeqForEachCutsetNode( pNtk, pObj, i ) - Cut_NodeNewMergeWithOld( p, pObj->Id ); - - // transfer the old cuts to the new positions - Abc_NtkForEachObj( pNtk, pObj, i ) - Cut_NodeOldTransferToNew( p, pObj->Id ); - - // unlabel the cutset nodes - Abc_SeqForEachCutsetNode( pNtk, pObj, i ) - pObj->fMarkC = 0; -if ( pParams->fVerbose ) -{ -PRT( "Total", clock() - clk ); -printf( "Converged after %d iterations.\n", nIters ); -} -//Abc_NtkPrintCuts( p, pNtk, 1 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree ) -{ - void * pList; - if ( pList = Abc_NodeReadCuts( p, pObj ) ) - return pList; - Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree ); - Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree ); - return Abc_NodeGetCuts( p, pObj, fDag, fTree ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree ) -{ - Abc_Obj_t * pFanin; - int fDagNode, fTriv, TreeCode = 0; -// assert( Abc_NtkIsStrash(pObj->pNtk) ); - assert( Abc_ObjFaninNum(pObj) == 2 ); - - - // check if the node is a DAG node - fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj)); - // increment the counter of DAG nodes - if ( fDagNode ) Cut_ManIncrementDagNodes( p ); - // add the trivial cut if the node is a DAG node, or if we compute all cuts - fTriv = fDagNode || !fDag; - // check if fanins are DAG nodes - if ( fTree ) - { - pFanin = Abc_ObjFanin0(pObj); - TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)); - pFanin = Abc_ObjFanin1(pObj); - TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1); - } - - - // changes due to the global/local cut computation - { - Cut_Params_t * pParams = Cut_ManReadParams(p); - if ( pParams->fLocal ) - { - Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs(p); - fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id ); - if ( fDagNode ) Cut_ManIncrementDagNodes( p ); -// fTriv = fDagNode || !pParams->fGlobal; - fTriv = !Vec_IntEntry( vNodeAttrs, pObj->Id ); - TreeCode = 0; - pFanin = Abc_ObjFanin0(pObj); - TreeCode |= Vec_IntEntry( vNodeAttrs, pFanin->Id ); - pFanin = Abc_ObjFanin1(pObj); - TreeCode |= (Vec_IntEntry( vNodeAttrs, pFanin->Id ) << 1); - } - } - return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv ) -{ - int CutSetNum; - assert( Abc_NtkIsSeq(pObj->pNtk) ); - assert( Abc_ObjFaninNum(pObj) == 2 ); - fTriv = pObj->fMarkC ? 0 : fTriv; - CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1; - Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Seq_ObjFaninL0(pObj), Seq_ObjFaninL1(pObj), fTriv, CutSetNum ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj ) -{ - return Cut_NodeReadCutsNew( p, pObj->Id ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj ) -{ - Cut_NodeFreeCuts( p, pObj->Id ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq ) -{ - Cut_Man_t * pMan = p; - Cut_Cut_t * pList; - Abc_Obj_t * pObj; - int i; - printf( "Cuts of the network:\n" ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - pList = Abc_NodeReadCuts( p, pObj ); - printf( "Node %s:\n", Abc_ObjName(pObj) ); - Cut_CutPrintList( pList, fSeq ); - } -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ) -{ - Cut_Man_t * pMan = p; - Cut_Cut_t * pList; - Abc_Obj_t * pObj; - pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 ); - pList = Abc_NodeReadCuts( p, pObj ); - printf( "Node %s:\n", Abc_ObjName(pObj) ); - Cut_CutPrintList( pList, fSeq ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/cut.h b/src/opt/cut/cut.h index 4c5af98d..dee05dfc 100644 --- a/src/opt/cut/cut.h +++ b/src/opt/cut/cut.h @@ -65,6 +65,7 @@ struct Cut_ParamsStruct_t_ int fLocal; // compute only local cuts int fRecord; // record the cut computation flow int fFancy; // perform fancy computations + int fMap; // computes delay of FPGA mapping with cuts int fVerbose; // the verbosiness flag }; @@ -129,6 +130,7 @@ extern void Cut_ManIncrementDagNodes( Cut_Man_t * p ); extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode ); extern Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes ); extern Cut_Cut_t * Cut_NodeUnionCutsSeq( Cut_Man_t * p, Vec_Int_t * vNodes, int CutSetNum, int fFirst ); +extern int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node ); /*=== cutSeq.c ==========================================================*/ extern void Cut_NodeComputeCutsSeq( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int nLat0, int nLat1, int fTriv, int CutSetNum ); extern void Cut_NodeNewMergeWithOld( Cut_Man_t * p, int Node ); diff --git a/src/opt/cut/cutInt.h b/src/opt/cut/cutInt.h index 2a0139d3..17f268c7 100644 --- a/src/opt/cut/cutInt.h +++ b/src/opt/cut/cutInt.h @@ -71,6 +71,11 @@ struct Cut_ManStruct_t_ Vec_Int_t * vNodeCuts; // the number of cuts for each node Vec_Int_t * vNodeStarts; // the number of the starting cut of each node Vec_Int_t * vCutPairs; // the pairs of parent cuts for each cut + // minimum delay mapping with the given cuts + Vec_Ptr_t * vCutsMax; + Vec_Int_t * vDelays; + Vec_Int_t * vDelays2; + int nDelayMin; // statistics int nCutsCur; int nCutsAlloc; @@ -88,6 +93,7 @@ struct Cut_ManStruct_t_ int timeTruth; int timeFilter; int timeHash; + int timeMap; }; // iterator through all the cuts of the list diff --git a/src/opt/cut/cutMan.c b/src/opt/cut/cutMan.c index 30e5fa38..ca829471 100644 --- a/src/opt/cut/cutMan.c +++ b/src/opt/cut/cutMan.c @@ -95,6 +95,13 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams ) p->vNodeStarts = Vec_IntStart( pParams->nIdsMax ); p->vCutPairs = Vec_IntAlloc( 0 ); } + // allocate storage for delays + if ( pParams->fMap && !p->pParams->fSeq ) + { + p->vDelays = Vec_IntStart( pParams->nIdsMax ); + p->vDelays2 = Vec_IntStart( pParams->nIdsMax ); + p->vCutsMax = Vec_PtrStart( pParams->nIdsMax ); + } // memory for cuts p->pMmCuts = Extra_MmFixedStart( p->EntrySize ); p->vTemp = Vec_PtrAlloc( 100 ); @@ -130,6 +137,9 @@ void Cut_ManStop( Cut_Man_t * p ) if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts ); if ( p->vTemp ) Vec_PtrFree( p->vTemp ); + if ( p->vCutsMax ) Vec_PtrFree( p->vCutsMax ); + if ( p->vDelays ) Vec_IntFree( p->vDelays ); + if ( p->vDelays2 ) Vec_IntFree( p->vDelays2 ); if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts ); if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts ); if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs ); @@ -168,13 +178,20 @@ void Cut_ManPrintStats( Cut_Man_t * p ) printf( "The cut size = %8d bytes.\n", p->EntrySize ); printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) ); printf( "Total nodes = %8d.\n", p->nNodes ); + if ( p->pParams->fDag || p->pParams->fTree ) + { printf( "DAG nodes = %8d.\n", p->nNodesDag ); printf( "Tree nodes = %8d.\n", p->nNodes - p->nNodesDag ); + } printf( "Nodes w/o cuts = %8d.\n", p->nNodesNoCuts ); + if ( p->pParams->fMap && !p->pParams->fSeq ) + printf( "Mapping delay = %8d.\n", p->nDelayMin ); + PRT( "Merge ", p->timeMerge ); PRT( "Union ", p->timeUnion ); PRT( "Filter", p->timeFilter ); PRT( "Truth ", p->timeTruth ); + PRT( "Map ", p->timeMap ); // printf( "Nodes = %d. Multi = %d. Cuts = %d. Multi = %d.\n", // p->nNodes, p->nNodesMulti, p->nCutsCur-p->nCutsTriv, p->nCutsMulti ); // printf( "Count0 = %d. Count1 = %d. Count2 = %d.\n\n", p->Count0, p->Count1, p->Count2 ); diff --git a/src/opt/cut/cutNode.c b/src/opt/cut/cutNode.c index fafa89f7..adff525f 100644 --- a/src/opt/cut/cutNode.c +++ b/src/opt/cut/cutNode.c @@ -24,6 +24,9 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ); +static int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -396,15 +399,157 @@ p->timeMerge += clock() - clk; // set the list at the node Vec_PtrFillExtra( p->vCutsNew, Node + 1, NULL ); assert( Cut_NodeReadCutsNew(p, Node) == NULL ); + + ///// + pList->pNext = NULL; + ///// + Cut_NodeWriteCutsNew( p, Node, pList ); // filter the cuts //clk = clock(); // if ( p->pParams->fFilter ) // Cut_CutFilter( p, pList0 ); //p->timeFilter += clock() - clk; + // perform mapping of this node with these cuts +clk = clock(); + if ( p->pParams->fMap && !p->pParams->fSeq ) + { +// int Delay1, Delay2; +// Delay1 = Cut_NodeMapping( p, pList, Node, Node0, Node1 ); +// Delay2 = Cut_NodeMapping2( p, pList, Node, Node0, Node1 ); +// assert( Delay1 >= Delay2 ); + Cut_NodeMapping( p, pList, Node, Node0, Node1 ); + } +p->timeMap += clock() - clk; return pList; } - + +/**Function************************************************************* + + Synopsis [Returns optimum delay mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ) +{ + Cut_Cut_t * pCut; + int DelayMin, DelayCur, i; + if ( pCuts == NULL ) + p->nDelayMin = -1; + if ( p->nDelayMin == -1 ) + return -1; + DelayMin = 1000000; + Cut_ListForEachCut( pCuts, pCut ) + { + if ( pCut->nLeaves == 1 ) + continue; + DelayCur = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + if ( DelayCur < Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) ) + DelayCur = Vec_IntEntry(p->vDelays, pCut->pLeaves[i]); + if ( DelayMin > DelayCur ) + DelayMin = DelayCur; + } + if ( DelayMin == 1000000 ) + { + p->nDelayMin = -1; + return -1; + } + DelayMin++; + Vec_IntWriteEntry( p->vDelays, Node, DelayMin ); + if ( p->nDelayMin < DelayMin ) + p->nDelayMin = DelayMin; + return DelayMin; +} + +/**Function************************************************************* + + Synopsis [Returns optimum delay mapping using the largest cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ) +{ + Cut_Cut_t * pCut0, * pCut1, * pCut; + int Delay0, Delay1, Delay; + // get the fanin cuts + Delay0 = Vec_IntEntry( p->vDelays2, Node0 ); + Delay1 = Vec_IntEntry( p->vDelays2, Node1 ); + pCut0 = (Delay0 == 0) ? Vec_PtrEntry( p->vCutsNew, Node0 ) : Vec_PtrEntry( p->vCutsMax, Node0 ); + pCut1 = (Delay1 == 0) ? Vec_PtrEntry( p->vCutsNew, Node1 ) : Vec_PtrEntry( p->vCutsMax, Node1 ); + if ( Delay0 == Delay1 ) + Delay = (Delay0 == 0) ? Delay0 + 1: Delay0; + else if ( Delay0 > Delay1 ) + { + Delay = Delay0; + pCut1 = Vec_PtrEntry( p->vCutsNew, Node1 ); + assert( pCut1->nLeaves == 1 ); + } + else // if ( Delay0 < Delay1 ) + { + Delay = Delay1; + pCut0 = Vec_PtrEntry( p->vCutsNew, Node0 ); + assert( pCut0->nLeaves == 1 ); + } + // merge the cuts + if ( pCut0->nLeaves < pCut1->nLeaves ) + pCut = Cut_CutMergeTwo( p, pCut1, pCut0 ); + else + pCut = Cut_CutMergeTwo( p, pCut0, pCut1 ); + if ( pCut == NULL ) + { + Delay++; + pCut = Cut_CutAlloc( p ); + pCut->nLeaves = 2; + pCut->pLeaves[0] = Node0 < Node1 ? Node0 : Node1; + pCut->pLeaves[1] = Node0 < Node1 ? Node1 : Node0; + } + assert( Delay > 0 ); + Vec_IntWriteEntry( p->vDelays2, Node, Delay ); + Vec_PtrWriteEntry( p->vCutsMax, Node, pCut ); + if ( p->nDelayMin < Delay ) + p->nDelayMin = Delay; + return Delay; +} + +/**Function************************************************************* + + Synopsis [Computes area after mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node ) +{ + Cut_Cut_t * pCut; + int i, Counter; + if ( p->vCutsMax == NULL ) + return 0; + pCut = Vec_PtrEntry( p->vCutsMax, Node ); + if ( pCut == NULL || pCut->nLeaves == 1 ) + return 0; + Counter = 0; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Counter += Cut_ManMappingArea_rec( p, pCut->pLeaves[i] ); + Vec_PtrWriteEntry( p->vCutsMax, Node, NULL ); + return 1 + Counter; +} + + /**Function************************************************************* Synopsis [Computes the cuts by merging cuts at two nodes.] diff --git a/src/opt/cut/vec.h b/src/opt/cut/vec.h deleted file mode 100644 index 6ab23298..00000000 --- a/src/opt/cut/vec.h +++ /dev/null @@ -1,66 +0,0 @@ -/**CFile**************************************************************** - - FileName [vec.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resizable arrays.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __VEC_H__ -#define __VEC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 -#define inline __inline // compatible with MS VS 6.0 -#endif - -#include "vecInt.h" -#include "vecStr.h" -#include "vecPtr.h" -#include "vecVec.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/cut/vecInt.h b/src/opt/cut/vecInt.h deleted file mode 100644 index 4f193cf2..00000000 --- a/src/opt/cut/vecInt.h +++ /dev/null @@ -1,753 +0,0 @@ -/**CFile**************************************************************** - - FileName [vecInt.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resizable arrays.] - - Synopsis [Resizable arrays of integers.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __VEC_INT_H__ -#define __VEC_INT_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "extra.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Vec_Int_t_ Vec_Int_t; -struct Vec_Int_t_ -{ - int nCap; - int nSize; - int * pArray; -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -#define Vec_IntForEachEntry( vVec, Entry, i ) \ - for ( i = 0; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ ) -#define Vec_IntForEachEntryStart( vVec, Entry, i, Start ) \ - for ( i = Start; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ ) -#define Vec_IntForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \ - for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ ) -#define Vec_IntForEachEntryReverse( vVec, pEntry, i ) \ - for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Int_t * Vec_IntAlloc( int nCap ) -{ - Vec_Int_t * p; - p = ALLOC( Vec_Int_t, 1 ); - if ( nCap > 0 && nCap < 16 ) - nCap = 16; - p->nSize = 0; - p->nCap = nCap; - p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given size and cleans it.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Int_t * Vec_IntStart( int nSize ) -{ - Vec_Int_t * p; - p = Vec_IntAlloc( nSize ); - p->nSize = nSize; - memset( p->pArray, 0, sizeof(int) * nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Creates the vector from an integer array of the given size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize ) -{ - Vec_Int_t * p; - p = ALLOC( Vec_Int_t, 1 ); - p->nSize = nSize; - p->nCap = nSize; - p->pArray = pArray; - return p; -} - -/**Function************************************************************* - - Synopsis [Creates the vector from an integer array of the given size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Int_t * Vec_IntAllocArrayCopy( int * pArray, int nSize ) -{ - Vec_Int_t * p; - p = ALLOC( Vec_Int_t, 1 ); - p->nSize = nSize; - p->nCap = nSize; - p->pArray = ALLOC( int, nSize ); - memcpy( p->pArray, pArray, sizeof(int) * nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Duplicates the integer array.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Int_t * Vec_IntDup( Vec_Int_t * pVec ) -{ - Vec_Int_t * p; - p = ALLOC( Vec_Int_t, 1 ); - p->nSize = pVec->nSize; - p->nCap = pVec->nCap; - p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL; - memcpy( p->pArray, pVec->pArray, sizeof(int) * pVec->nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Transfers the array into another vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Int_t * Vec_IntDupArray( Vec_Int_t * pVec ) -{ - Vec_Int_t * p; - p = ALLOC( Vec_Int_t, 1 ); - p->nSize = pVec->nSize; - p->nCap = pVec->nCap; - p->pArray = pVec->pArray; - pVec->nSize = 0; - pVec->nCap = 0; - pVec->pArray = NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntFree( Vec_Int_t * p ) -{ - FREE( p->pArray ); - FREE( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int * Vec_IntReleaseArray( Vec_Int_t * p ) -{ - int * pArray = p->pArray; - p->nCap = 0; - p->nSize = 0; - p->pArray = NULL; - return pArray; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int * Vec_IntArray( Vec_Int_t * p ) -{ - return p->pArray; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntSize( Vec_Int_t * p ) -{ - return p->nSize; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntEntry( Vec_Int_t * p, int i ) -{ - assert( i >= 0 && i < p->nSize ); - return p->pArray[i]; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry ) -{ - assert( i >= 0 && i < p->nSize ); - p->pArray[i] = Entry; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition ) -{ - assert( i >= 0 && i < p->nSize ); - p->pArray[i] += Addition; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntEntryLast( Vec_Int_t * p ) -{ - assert( p->nSize > 0 ); - return p->pArray[p->nSize-1]; -} - -/**Function************************************************************* - - Synopsis [Resizes the vector to the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin ) -{ - if ( p->nCap >= nCapMin ) - return; - p->pArray = REALLOC( int, p->pArray, nCapMin ); - assert( p->pArray ); - p->nCap = nCapMin; -} - -/**Function************************************************************* - - Synopsis [Fills the vector with given number of entries.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry ) -{ - int i; - Vec_IntGrow( p, nSize ); - for ( i = 0; i < nSize; i++ ) - p->pArray[i] = Entry; - p->nSize = nSize; -} - -/**Function************************************************************* - - Synopsis [Fills the vector with given number of entries.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry ) -{ - int i; - if ( p->nSize >= nSize ) - return; - Vec_IntGrow( p, nSize ); - for ( i = p->nSize; i < nSize; i++ ) - p->pArray[i] = Entry; - p->nSize = nSize; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew ) -{ - assert( p->nSize >= nSizeNew ); - p->nSize = nSizeNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntClear( Vec_Int_t * p ) -{ - p->nSize = 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntPush( Vec_Int_t * p, int Entry ) -{ - if ( p->nSize == p->nCap ) - { - if ( p->nCap < 16 ) - Vec_IntGrow( p, 16 ); - else - Vec_IntGrow( p, 2 * p->nCap ); - } - p->pArray[p->nSize++] = Entry; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry ) -{ - int i; - if ( p->nSize == p->nCap ) - { - if ( p->nCap < 16 ) - Vec_IntGrow( p, 16 ); - else - Vec_IntGrow( p, 2 * p->nCap ); - } - p->nSize++; - for ( i = p->nSize - 1; i >= 1; i-- ) - p->pArray[i] = p->pArray[i-1]; - p->pArray[0] = Entry; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry ) -{ - if ( p->nSize == p->nCap ) - { - int * pArray; - int i; - - if ( p->nSize == 0 ) - p->nCap = 1; - pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 ); -// pArray = ALLOC( int, p->nCap * 2 ); - if ( p->pArray ) - { - for ( i = 0; i < p->nSize; i++ ) - pArray[i] = p->pArray[i]; - Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 ); -// free( p->pArray ); - } - p->nCap *= 2; - p->pArray = pArray; - } - p->pArray[p->nSize++] = Entry; -} - -/**Function************************************************************* - - Synopsis [Inserts the entry while preserving the increasing order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry ) -{ - int i; - if ( p->nSize == p->nCap ) - { - if ( p->nCap < 16 ) - Vec_IntGrow( p, 16 ); - else - Vec_IntGrow( p, 2 * p->nCap ); - } - p->nSize++; - for ( i = p->nSize-2; i >= 0; i-- ) - if ( p->pArray[i] > Entry ) - p->pArray[i+1] = p->pArray[i]; - else - break; - p->pArray[i+1] = Entry; -} - -/**Function************************************************************* - - Synopsis [Inserts the entry while preserving the increasing order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry ) -{ - int i; - for ( i = 0; i < p->nSize; i++ ) - if ( p->pArray[i] == Entry ) - return 1; - Vec_IntPushOrder( p, Entry ); - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry ) -{ - int i; - for ( i = 0; i < p->nSize; i++ ) - if ( p->pArray[i] == Entry ) - return 1; - Vec_IntPush( p, Entry ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Returns the last entry and removes it from the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntPop( Vec_Int_t * p ) -{ - assert( p->nSize > 0 ); - return p->pArray[--p->nSize]; -} - -/**Function************************************************************* - - Synopsis [Find entry.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntFind( Vec_Int_t * p, int Entry ) -{ - int i; - for ( i = 0; i < p->nSize; i++ ) - if ( p->pArray[i] == Entry ) - return i; - return -1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntRemove( Vec_Int_t * p, int Entry ) -{ - int i; - for ( i = 0; i < p->nSize; i++ ) - if ( p->pArray[i] == Entry ) - break; - if ( i == p->nSize ) - return 0; - assert( i < p->nSize ); - for ( i++; i < p->nSize; i++ ) - p->pArray[i-1] = p->pArray[i]; - p->nSize--; - return 1; -} - -/**Function************************************************************* - - Synopsis [Comparison procedure for two integers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntSortCompare1( int * pp1, int * pp2 ) -{ - // for some reason commenting out lines (as shown) led to crashing of the release version - if ( *pp1 < *pp2 ) - return -1; - if ( *pp1 > *pp2 ) // - return 1; - return 0; // -} - -/**Function************************************************************* - - Synopsis [Comparison procedure for two integers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntSortCompare2( int * pp1, int * pp2 ) -{ - // for some reason commenting out lines (as shown) led to crashing of the release version - if ( *pp1 > *pp2 ) - return -1; - if ( *pp1 < *pp2 ) // - return 1; - return 0; // -} - -/**Function************************************************************* - - Synopsis [Sorting the entries by their integer value.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntSort( Vec_Int_t * p, int fReverse ) -{ - if ( fReverse ) - qsort( (void *)p->pArray, p->nSize, sizeof(int), - (int (*)(const void *, const void *)) Vec_IntSortCompare2 ); - else - qsort( (void *)p->pArray, p->nSize, sizeof(int), - (int (*)(const void *, const void *)) Vec_IntSortCompare1 ); -} - - -/**Function************************************************************* - - Synopsis [Comparison procedure for two integers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_IntSortCompareUnsigned( unsigned * pp1, unsigned * pp2 ) -{ - if ( *pp1 < *pp2 ) - return -1; - if ( *pp1 > *pp2 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Sorting the entries by their integer value.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_IntSortUnsigned( Vec_Int_t * p ) -{ - qsort( (void *)p->pArray, p->nSize, sizeof(int), - (int (*)(const void *, const void *)) Vec_IntSortCompareUnsigned ); -} - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/cut/vecPtr.h b/src/opt/cut/vecPtr.h deleted file mode 100644 index f2413703..00000000 --- a/src/opt/cut/vecPtr.h +++ /dev/null @@ -1,579 +0,0 @@ -/**CFile**************************************************************** - - FileName [vecPtr.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resizable arrays.] - - Synopsis [Resizable arrays of generic pointers.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: vecPtr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __VEC_PTR_H__ -#define __VEC_PTR_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include <stdio.h> -#include "extra.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Vec_Ptr_t_ Vec_Ptr_t; -struct Vec_Ptr_t_ -{ - int nCap; - int nSize; - void ** pArray; -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -// iterators through entries -#define Vec_PtrForEachEntry( vVec, pEntry, i ) \ - for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) -#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \ - for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) -#define Vec_PtrForEachEntryStop( vVec, pEntry, i, Stop ) \ - for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) -#define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop ) \ - for ( i = Start; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) -#define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \ - for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap ) -{ - Vec_Ptr_t * p; - p = ALLOC( Vec_Ptr_t, 1 ); - if ( nCap > 0 && nCap < 8 ) - nCap = 8; - p->nSize = 0; - p->nCap = nCap; - p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given size and cleans it.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Ptr_t * Vec_PtrStart( int nSize ) -{ - Vec_Ptr_t * p; - p = Vec_PtrAlloc( nSize ); - p->nSize = nSize; - memset( p->pArray, 0, sizeof(void *) * nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Creates the vector from an integer array of the given size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Ptr_t * Vec_PtrAllocArray( void ** pArray, int nSize ) -{ - Vec_Ptr_t * p; - p = ALLOC( Vec_Ptr_t, 1 ); - p->nSize = nSize; - p->nCap = nSize; - p->pArray = pArray; - return p; -} - -/**Function************************************************************* - - Synopsis [Creates the vector from an integer array of the given size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Ptr_t * Vec_PtrAllocArrayCopy( void ** pArray, int nSize ) -{ - Vec_Ptr_t * p; - p = ALLOC( Vec_Ptr_t, 1 ); - p->nSize = nSize; - p->nCap = nSize; - p->pArray = ALLOC( void *, nSize ); - memcpy( p->pArray, pArray, sizeof(void *) * nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Duplicates the integer array.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Ptr_t * Vec_PtrDup( Vec_Ptr_t * pVec ) -{ - Vec_Ptr_t * p; - p = ALLOC( Vec_Ptr_t, 1 ); - p->nSize = pVec->nSize; - p->nCap = pVec->nCap; - p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL; - memcpy( p->pArray, pVec->pArray, sizeof(void *) * pVec->nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Transfers the array into another vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Ptr_t * Vec_PtrDupArray( Vec_Ptr_t * pVec ) -{ - Vec_Ptr_t * p; - p = ALLOC( Vec_Ptr_t, 1 ); - p->nSize = pVec->nSize; - p->nCap = pVec->nCap; - p->pArray = pVec->pArray; - pVec->nSize = 0; - pVec->nCap = 0; - pVec->pArray = NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [Frees the vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrFree( Vec_Ptr_t * p ) -{ - FREE( p->pArray ); - FREE( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void ** Vec_PtrReleaseArray( Vec_Ptr_t * p ) -{ - void ** pArray = p->pArray; - p->nCap = 0; - p->nSize = 0; - p->pArray = NULL; - return pArray; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void ** Vec_PtrArray( Vec_Ptr_t * p ) -{ - return p->pArray; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_PtrSize( Vec_Ptr_t * p ) -{ - return p->nSize; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i ) -{ - assert( i >= 0 && i < p->nSize ); - return p->pArray[i]; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void ** Vec_PtrEntryP( Vec_Ptr_t * p, int i ) -{ - assert( i >= 0 && i < p->nSize ); - return p->pArray + i; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry ) -{ - assert( i >= 0 && i < p->nSize ); - p->pArray[i] = Entry; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p ) -{ - assert( p->nSize > 0 ); - return p->pArray[p->nSize-1]; -} - -/**Function************************************************************* - - Synopsis [Resizes the vector to the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin ) -{ - if ( p->nCap >= nCapMin ) - return; - p->pArray = REALLOC( void *, p->pArray, nCapMin ); - p->nCap = nCapMin; -} - -/**Function************************************************************* - - Synopsis [Fills the vector with given number of entries.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry ) -{ - int i; - Vec_PtrGrow( p, nSize ); - for ( i = 0; i < nSize; i++ ) - p->pArray[i] = Entry; - p->nSize = nSize; -} - -/**Function************************************************************* - - Synopsis [Fills the vector with given number of entries.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry ) -{ - int i; - if ( p->nSize >= nSize ) - return; - if ( p->nSize < 2 * nSize ) - Vec_PtrGrow( p, 2 * nSize ); - else - Vec_PtrGrow( p, p->nSize ); - for ( i = p->nSize; i < nSize; i++ ) - p->pArray[i] = Entry; - p->nSize = nSize; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrShrink( Vec_Ptr_t * p, int nSizeNew ) -{ - assert( p->nSize >= nSizeNew ); - p->nSize = nSizeNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrClear( Vec_Ptr_t * p ) -{ - p->nSize = 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry ) -{ - if ( p->nSize == p->nCap ) - { - if ( p->nCap < 16 ) - Vec_PtrGrow( p, 16 ); - else - Vec_PtrGrow( p, 2 * p->nCap ); - } - p->pArray[p->nSize++] = Entry; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_PtrPushUnique( Vec_Ptr_t * p, void * Entry ) -{ - int i; - for ( i = 0; i < p->nSize; i++ ) - if ( p->pArray[i] == Entry ) - return 1; - Vec_PtrPush( p, Entry ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Returns the last entry and removes it from the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void * Vec_PtrPop( Vec_Ptr_t * p ) -{ - assert( p->nSize > 0 ); - return p->pArray[--p->nSize]; -} - -/**Function************************************************************* - - Synopsis [Find entry.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry ) -{ - int i; - for ( i = 0; i < p->nSize; i++ ) - if ( p->pArray[i] == Entry ) - return i; - return -1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry ) -{ - int i; - for ( i = 0; i < p->nSize; i++ ) - if ( p->pArray[i] == Entry ) - break; - assert( i < p->nSize ); - for ( i++; i < p->nSize; i++ ) - p->pArray[i-1] = p->pArray[i]; - p->nSize--; -} - -/**Function************************************************************* - - Synopsis [Moves the first nItems to the end.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems ) -{ - assert( nItems < p->nSize ); - Vec_PtrGrow( p, nItems + p->nSize ); - memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) ); - memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) ); -} - -/**Function************************************************************* - - Synopsis [Sorting the entries by their integer value.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() ) -{ - qsort( (void *)p->pArray, p->nSize, sizeof(void *), - (int (*)(const void *, const void *)) Vec_PtrSortCompare ); -} - -#endif - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/cut/vecStr.h b/src/opt/cut/vecStr.h deleted file mode 100644 index eb6aa41d..00000000 --- a/src/opt/cut/vecStr.h +++ /dev/null @@ -1,510 +0,0 @@ -/**CFile**************************************************************** - - FileName [vecStr.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resizable arrays.] - - Synopsis [Resizable arrays of characters.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: vecStr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __VEC_STR_H__ -#define __VEC_STR_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include <stdio.h> -#include "extra.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Vec_Str_t_ Vec_Str_t; -struct Vec_Str_t_ -{ - int nCap; - int nSize; - char * pArray; -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -#define Vec_StrForEachEntry( vVec, Entry, i ) \ - for ( i = 0; (i < Vec_StrSize(vVec)) && (((Entry) = Vec_StrEntry(vVec, i)), 1); i++ ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Str_t * Vec_StrAlloc( int nCap ) -{ - Vec_Str_t * p; - p = ALLOC( Vec_Str_t, 1 ); - if ( nCap > 0 && nCap < 16 ) - nCap = 16; - p->nSize = 0; - p->nCap = nCap; - p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given size and cleans it.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Str_t * Vec_StrStart( int nSize ) -{ - Vec_Str_t * p; - p = Vec_StrAlloc( nSize ); - p->nSize = nSize; - memset( p->pArray, 0, sizeof(char) * nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Creates the vector from an integer array of the given size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize ) -{ - Vec_Str_t * p; - p = ALLOC( Vec_Str_t, 1 ); - p->nSize = nSize; - p->nCap = nSize; - p->pArray = pArray; - return p; -} - -/**Function************************************************************* - - Synopsis [Creates the vector from an integer array of the given size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Str_t * Vec_StrAllocArrayCopy( char * pArray, int nSize ) -{ - Vec_Str_t * p; - p = ALLOC( Vec_Str_t, 1 ); - p->nSize = nSize; - p->nCap = nSize; - p->pArray = ALLOC( char, nSize ); - memcpy( p->pArray, pArray, sizeof(char) * nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Duplicates the integer array.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Str_t * Vec_StrDup( Vec_Str_t * pVec ) -{ - Vec_Str_t * p; - p = ALLOC( Vec_Str_t, 1 ); - p->nSize = pVec->nSize; - p->nCap = pVec->nCap; - p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL; - memcpy( p->pArray, pVec->pArray, sizeof(char) * pVec->nSize ); - return p; -} - -/**Function************************************************************* - - Synopsis [Transfers the array into another vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec ) -{ - Vec_Str_t * p; - p = ALLOC( Vec_Str_t, 1 ); - p->nSize = pVec->nSize; - p->nCap = pVec->nCap; - p->pArray = pVec->pArray; - pVec->nSize = 0; - pVec->nCap = 0; - pVec->pArray = NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrFree( Vec_Str_t * p ) -{ - FREE( p->pArray ); - FREE( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline char * Vec_StrReleaseArray( Vec_Str_t * p ) -{ - char * pArray = p->pArray; - p->nCap = 0; - p->nSize = 0; - p->pArray = NULL; - return pArray; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline char * Vec_StrArray( Vec_Str_t * p ) -{ - return p->pArray; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_StrSize( Vec_Str_t * p ) -{ - return p->nSize; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline char Vec_StrEntry( Vec_Str_t * p, int i ) -{ - assert( i >= 0 && i < p->nSize ); - return p->pArray[i]; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry ) -{ - assert( i >= 0 && i < p->nSize ); - p->pArray[i] = Entry; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline char Vec_StrEntryLast( Vec_Str_t * p ) -{ - assert( p->nSize > 0 ); - return p->pArray[p->nSize-1]; -} - -/**Function************************************************************* - - Synopsis [Resizes the vector to the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin ) -{ - if ( p->nCap >= nCapMin ) - return; - p->pArray = REALLOC( char, p->pArray, 2 * nCapMin ); - p->nCap = 2 * nCapMin; -} - -/**Function************************************************************* - - Synopsis [Fills the vector with given number of entries.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrFill( Vec_Str_t * p, int nSize, char Entry ) -{ - int i; - Vec_StrGrow( p, nSize ); - p->nSize = nSize; - for ( i = 0; i < p->nSize; i++ ) - p->pArray[i] = Entry; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrShrink( Vec_Str_t * p, int nSizeNew ) -{ - assert( p->nSize >= nSizeNew ); - p->nSize = nSizeNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrClear( Vec_Str_t * p ) -{ - p->nSize = 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrPush( Vec_Str_t * p, char Entry ) -{ - if ( p->nSize == p->nCap ) - { - if ( p->nCap < 16 ) - Vec_StrGrow( p, 16 ); - else - Vec_StrGrow( p, 2 * p->nCap ); - } - p->pArray[p->nSize++] = Entry; -} - -/**Function************************************************************* - - Synopsis [Appends the string to the char vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrAppend( Vec_Str_t * p, char * pString ) -{ - int i, nLength = strlen(pString); - Vec_StrGrow( p, p->nSize + nLength ); - for ( i = 0; i < nLength; i++ ) - p->pArray[p->nSize + i] = pString[i]; - p->nSize += nLength; -} - -/**Function************************************************************* - - Synopsis [Returns the last entry and removes it from the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline char Vec_StrPop( Vec_Str_t * p ) -{ - assert( p->nSize > 0 ); - return p->pArray[--p->nSize]; -} - -/**Function************************************************************* - - Synopsis [Comparison procedure for two clauses.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_StrSortCompare1( char * pp1, char * pp2 ) -{ - // for some reason commenting out lines (as shown) led to crashing of the release version - if ( *pp1 < *pp2 ) - return -1; - if ( *pp1 > *pp2 ) // - return 1; - return 0; // -} - -/**Function************************************************************* - - Synopsis [Comparison procedure for two clauses.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_StrSortCompare2( char * pp1, char * pp2 ) -{ - // for some reason commenting out lines (as shown) led to crashing of the release version - if ( *pp1 > *pp2 ) - return -1; - if ( *pp1 < *pp2 ) // - return 1; - return 0; // -} - -/**Function************************************************************* - - Synopsis [Sorting the entries by their integer value.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_StrSort( Vec_Str_t * p, int fReverse ) -{ - if ( fReverse ) - qsort( (void *)p->pArray, p->nSize, sizeof(char), - (int (*)(const void *, const void *)) Vec_StrSortCompare2 ); - else - qsort( (void *)p->pArray, p->nSize, sizeof(char), - (int (*)(const void *, const void *)) Vec_StrSortCompare1 ); -} - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/cut/vecVec.h b/src/opt/cut/vecVec.h deleted file mode 100644 index 5b725354..00000000 --- a/src/opt/cut/vecVec.h +++ /dev/null @@ -1,289 +0,0 @@ -/**CFile**************************************************************** - - FileName [vecVec.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resizable arrays.] - - Synopsis [Resizable vector of resizable vectors.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __VEC_VEC_H__ -#define __VEC_VEC_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include <stdio.h> -#include "extra.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Vec_Vec_t_ Vec_Vec_t; -struct Vec_Vec_t_ -{ - int nCap; - int nSize; - void ** pArray; -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -// iterators through levels -#define Vec_VecForEachLevel( vGlob, vVec, i ) \ - for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ ) -#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \ - for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ ) -#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \ - for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ ) -#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \ - for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- ) - -// iteratores through entries -#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \ - for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \ - Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k ) -#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \ - for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \ - Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k ) -#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \ - for ( i = LevelStart; i <= LevelStop; i++ ) \ - Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k ) -#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \ - for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \ - Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k ) -#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k ) \ - for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- ) \ - Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Vec_t * Vec_VecAlloc( int nCap ) -{ - Vec_Vec_t * p; - p = ALLOC( Vec_Vec_t, 1 ); - if ( nCap > 0 && nCap < 8 ) - nCap = 8; - p->nSize = 0; - p->nCap = nCap; - p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Vec_Vec_t * Vec_VecStart( int nSize ) -{ - Vec_Vec_t * p; - int i; - p = Vec_VecAlloc( nSize ); - for ( i = 0; i < nSize; i++ ) - p->pArray[i] = Vec_PtrAlloc( 0 ); - p->nSize = nSize; - return p; -} - -/**Function************************************************************* - - Synopsis [Allocates a vector with the given capacity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_VecExpand( Vec_Vec_t * p, int Level ) -{ - int i; - if ( p->nSize >= Level + 1 ) - return; - Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 ); - for ( i = p->nSize; i <= Level; i++ ) - p->pArray[i] = Vec_PtrAlloc( 0 ); - p->nSize = Level + 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_VecSize( Vec_Vec_t * p ) -{ - return p->nSize; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void * Vec_VecEntry( Vec_Vec_t * p, int i ) -{ - assert( i >= 0 && i < p->nSize ); - return p->pArray[i]; -} - -/**Function************************************************************* - - Synopsis [Frees the vector.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_VecFree( Vec_Vec_t * p ) -{ - Vec_Ptr_t * vVec; - int i; - Vec_VecForEachLevel( p, vVec, i ) - Vec_PtrFree( vVec ); - Vec_PtrFree( (Vec_Ptr_t *)p ); -} - -/**Function************************************************************* - - Synopsis [Frees the vector of vectors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_VecSizeSize( Vec_Vec_t * p ) -{ - Vec_Ptr_t * vVec; - int i, Counter = 0; - Vec_VecForEachLevel( p, vVec, i ) - Counter += vVec->nSize; - return Counter; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_VecClear( Vec_Vec_t * p ) -{ - Vec_Ptr_t * vVec; - int i; - Vec_VecForEachLevel( p, vVec, i ) - Vec_PtrClear( vVec ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry ) -{ - if ( p->nSize < Level + 1 ) - { - int i; - Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 ); - for ( i = p->nSize; i < Level + 1; i++ ) - p->pArray[i] = Vec_PtrAlloc( 0 ); - p->nSize = Level + 1; - } - Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry ) -{ - if ( p->nSize < Level + 1 ) - Vec_VecPush( p, Level, Entry ); - else - Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry ); -} - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/dec/dec.h b/src/opt/dec/dec.h index 2987723f..41d22649 100644 --- a/src/opt/dec/dec.h +++ b/src/opt/dec/dec.h @@ -51,11 +51,15 @@ struct Dec_Node_t_ Dec_Edge_t eEdge1; // the right child of the node // other info void * pFunc; // the function of the node (BDD or AIG) - unsigned Level : 16; // the level of this node in the global AIG + unsigned Level : 14; // the level of this node in the global AIG // printing info unsigned fNodeOr : 1; // marks the original OR node unsigned fCompl0 : 1; // marks the original complemented edge unsigned fCompl1 : 1; // marks the original complemented edge + // latch info + unsigned nLat0 : 5; // the number of latches on the first edge + unsigned nLat1 : 5; // the number of latches on the second edge + unsigned nLat2 : 5; // the number of latches on the output edge }; typedef struct Dec_Graph_t_ Dec_Graph_t; diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c index 4e5a3dc2..fc612f95 100644 --- a/src/opt/rwr/rwrEva.c +++ b/src/opt/rwr/rwrEva.c @@ -27,6 +27,7 @@ static Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest ); static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves ); +static int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -72,6 +73,8 @@ clk = clock(); assert( pCut != NULL ); p->timeCut += clock() - clk; +//printf( " %d", Rwr_CutCountNumNodes(pNode, pCut) ); + // go through the cuts clk = clock(); for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext ) @@ -104,6 +107,15 @@ clk = clock(); } p->nCutsGood++; + { + int Counter = 0; + Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + if ( Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) == 1 ) + Counter++; + if ( Counter > 2 ) + continue; + } + clk2 = clock(); /* printf( "Considering: (" ); @@ -306,6 +318,72 @@ int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves ) return RetValue; } + +/**Function************************************************************* + + Synopsis [Count the nodes in the cut space of a node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rwr_CutCountNumNodes_rec( Abc_Obj_t * pObj, Cut_Cut_t * pCut, Vec_Ptr_t * vNodes ) +{ + int i; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + if ( pCut->pLeaves[i] == pObj->Id ) + { + // check if the node is collected + if ( pObj->fMarkC == 0 ) + { + pObj->fMarkC = 1; + Vec_PtrPush( vNodes, pObj ); + } + return; + } + assert( Abc_ObjIsNode(pObj) ); + // check if the node is collected + if ( pObj->fMarkC == 0 ) + { + pObj->fMarkC = 1; + Vec_PtrPush( vNodes, pObj ); + } + // traverse the fanins + Rwr_CutCountNumNodes_rec( Abc_ObjFanin0(pObj), pCut, vNodes ); + Rwr_CutCountNumNodes_rec( Abc_ObjFanin1(pObj), pCut, vNodes ); +} + +/**Function************************************************************* + + Synopsis [Count the nodes in the cut space of a node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut ) +{ + Vec_Ptr_t * vNodes; + int i, Counter; + // collect all nodes + vNodes = Vec_PtrAlloc( 100 ); + for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext ) + Rwr_CutCountNumNodes_rec( pObj, pCut, vNodes ); + // clean all nodes + Vec_PtrForEachEntry( vNodes, pObj, i ) + pObj->fMarkC = 0; + // delete and return + Counter = Vec_PtrSize(vNodes); + Vec_PtrFree( vNodes ); + return Counter; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/asat/added.c b/src/sat/asat/added.c index 832bc0cf..100b823b 100644 --- a/src/sat/asat/added.c +++ b/src/sat/asat/added.c @@ -209,6 +209,23 @@ void Asat_SolverSetPrefVars(solver * s, int * pPrefVars, int nPrefVars) s->nPrefVars = nPrefVars; } +/**Function************************************************************* + + Synopsis [Sets the preferred variables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Asat_SolverSetFactors(solver * s, int * pFactors) +{ + assert( s->factors == NULL ); + s->factors = pFactors; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/sat/asat/solver.c b/src/sat/asat/solver.c index 548abd1d..f2642c38 100644 --- a/src/sat/asat/solver.c +++ b/src/sat/asat/solver.c @@ -254,6 +254,7 @@ static inline void act_var_rescale(solver* s) { static inline void act_var_bump(solver* s, int v) { double* activity = s->activity; if ((activity[v] += s->var_inc) > 1e100) +// if ((activity[v] += s->var_inc*s->factors[v]/100000000) > 1e100) act_var_rescale(s); //printf("bump %d %f\n", v-1, activity[v]); @@ -947,6 +948,7 @@ solver* solver_new(void) // initialize arrays s->wlists = 0; s->activity = 0; + s->factors = 0; s->assigns = 0; s->orderpos = 0; s->reasons = 0; @@ -1039,9 +1041,9 @@ void solver_delete(solver* s) free(s->trail ); free(s->tags ); } - if ( s->pJMan ) Asat_JManStop( s ); if ( s->pPrefVars ) free( s->pPrefVars ); + if ( s->factors ) free( s->factors ); free(s); } diff --git a/src/sat/asat/solver.h b/src/sat/asat/solver.h index 05e9dafa..7edfb537 100644 --- a/src/sat/asat/solver.h +++ b/src/sat/asat/solver.h @@ -89,6 +89,7 @@ extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName, int incrementVars); extern void Asat_SatPrintStats( FILE * pFile, solver * p ); extern void Asat_SolverSetPrefVars( solver * s, int * pPrefVars, int nPrefVars ); +extern void Asat_SolverSetFactors( solver * s, int * pFactors ); // J-frontier support extern Asat_JMan_t * Asat_JManStart( solver * pSat, void * vCircuit ); @@ -127,6 +128,7 @@ struct solver_t vec* wlists; // double* activity; // A heuristic measurement of the activity of a variable. + int * factors; // the factor of variable activity lbool* assigns; // Current values of variables. int* orderpos; // Index in variable order. clause** reasons; // diff --git a/src/sat/fraig/fraigSat.c b/src/sat/fraig/fraigSat.c index aa28a4f2..1a56cf0e 100644 --- a/src/sat/fraig/fraigSat.c +++ b/src/sat/fraig/fraigSat.c @@ -326,7 +326,7 @@ int Fraig_NodeIsEquivalent( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * Fraig_ManCreateSolver( p ); // make sure the SAT solver has enough variables for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ ) - Msat_SolverAddVar( p->pSat ); + Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level ); @@ -543,7 +543,7 @@ int Fraig_NodeIsImplication( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t Fraig_ManCreateSolver( p ); // make sure the SAT solver has enough variables for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ ) - Msat_SolverAddVar( p->pSat ); + Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level ); // get the logic cone clk = clock(); @@ -642,7 +642,7 @@ int Fraig_ManCheckClauseUsingSat( Fraig_Man_t * p, Fraig_Node_t * pNode1, Fraig_ Fraig_ManCreateSolver( p ); // make sure the SAT solver has enough variables for ( i = Msat_SolverReadVarNum(p->pSat); i < p->vNodes->nSize; i++ ) - Msat_SolverAddVar( p->pSat ); + Msat_SolverAddVar( p->pSat, p->vNodes->pArray[i]->Level ); // get the logic cone clk = clock(); diff --git a/src/sat/msat/msat.h b/src/sat/msat/msat.h index 5f8603a7..1d9c0005 100644 --- a/src/sat/msat/msat.h +++ b/src/sat/msat/msat.h @@ -80,7 +80,7 @@ typedef enum { MSAT_FALSE = -1, MSAT_UNKNOWN = 0, MSAT_TRUE = 1 } Msat_Type_t; extern bool Msat_SolverParseDimacs( FILE * pFile, Msat_Solver_t ** p, int fVerbose ); /*=== satSolver.c ===========================================================*/ // adding vars, clauses, simplifying the database, and solving -extern bool Msat_SolverAddVar( Msat_Solver_t * p ); +extern bool Msat_SolverAddVar( Msat_Solver_t * p, int Level ); extern bool Msat_SolverAddClause( Msat_Solver_t * p, Msat_IntVec_t * pLits ); extern bool Msat_SolverSimplifyDB( Msat_Solver_t * p ); extern bool Msat_SolverSolve( Msat_Solver_t * p, Msat_IntVec_t * pVecAssumps, int nBackTrackLimit, int nTimeLimit ); diff --git a/src/sat/msat/msatActivity.c b/src/sat/msat/msatActivity.c index 0947d6d5..f808d9bc 100644 --- a/src/sat/msat/msatActivity.c +++ b/src/sat/msat/msatActivity.c @@ -46,6 +46,7 @@ void Msat_SolverVarBumpActivity( Msat_Solver_t * p, Msat_Lit_t Lit ) return; Var = MSAT_LIT2VAR(Lit); if ( (p->pdActivity[Var] += p->dVarInc) > 1e100 ) +// if ( (p->pdActivity[Var] += p->dVarInc * (1.0 + 0.005*p->pLevel[Var])) > 1e100 ) Msat_SolverVarRescaleActivity( p ); Msat_OrderUpdate( p->pOrder, Var ); } diff --git a/src/sat/msat/msatInt.h b/src/sat/msat/msatInt.h index 03e7b873..15932c67 100644 --- a/src/sat/msat/msatInt.h +++ b/src/sat/msat/msatInt.h @@ -119,6 +119,7 @@ struct Msat_Solver_t_ double dClaDecay; // INVERSE decay factor for clause activity: stores 1/decay. double * pdActivity; // A heuristic measurement of the activity of a variable. + int * pLevels; // the levels of the variables double dVarInc; // Amount to bump next variable with. double dVarDecay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order. Msat_Order_t * pOrder; // Keeps track of the decision variable order. diff --git a/src/sat/msat/msatSolverApi.c b/src/sat/msat/msatSolverApi.c index e3d85774..8c1542df 100644 --- a/src/sat/msat/msatSolverApi.c +++ b/src/sat/msat/msatSolverApi.c @@ -174,8 +174,12 @@ Msat_Solver_t * Msat_SolverAlloc( int nVarsAlloc, p->dVarDecay = dVarDecay; p->pdActivity = ALLOC( double, p->nVarsAlloc ); + p->pLevels = ALLOC( int, p->nVarsAlloc ); for ( i = 0; i < p->nVarsAlloc; i++ ) + { p->pdActivity[i] = 0; + p->pLevels = 0; + } p->pAssigns = ALLOC( int, p->nVarsAlloc ); p->pModel = ALLOC( int, p->nVarsAlloc ); @@ -239,6 +243,7 @@ void Msat_SolverResize( Msat_Solver_t * p, int nVarsAlloc ) p->nVarsAlloc = nVarsAlloc; p->pdActivity = REALLOC( double, p->pdActivity, p->nVarsAlloc ); + p->pLevels = REALLOC( int, p->pLevels, p->nVarsAlloc ); for ( i = nVarsAllocOld; i < p->nVarsAlloc; i++ ) p->pdActivity[i] = 0; @@ -394,6 +399,7 @@ void Msat_SolverFree( Msat_Solver_t * p ) Msat_ClauseVecFree( p->vLearned ); FREE( p->pdActivity ); + FREE( p->pLevels ); Msat_OrderFree( p->pOrder ); for ( i = 0; i < 2 * p->nVarsAlloc; i++ ) diff --git a/src/sat/msat/msatSolverCore.c b/src/sat/msat/msatSolverCore.c index 397dbcdc..f9fee73c 100644 --- a/src/sat/msat/msatSolverCore.c +++ b/src/sat/msat/msatSolverCore.c @@ -39,10 +39,11 @@ SeeAlso [] ***********************************************************************/ -bool Msat_SolverAddVar( Msat_Solver_t * p ) +bool Msat_SolverAddVar( Msat_Solver_t * p, int Level ) { if ( p->nVars == p->nVarsAlloc ) Msat_SolverResize( p, 2 * p->nVarsAlloc ); + p->pLevel[p->nVars] = Level; p->nVars++; return 1; } diff --git a/src/temp/deco/deco.h b/src/temp/deco/deco.h index 89119c78..67126902 100644 --- a/src/temp/deco/deco.h +++ b/src/temp/deco/deco.h @@ -51,11 +51,15 @@ struct Dec_Node_t_ Dec_Edge_t eEdge1; // the right child of the node // other info void * pFunc; // the function of the node (BDD or AIG) - unsigned Level : 16; // the level of this node in the global AIG + unsigned Level : 14; // the level of this node in the global AIG // printing info unsigned fNodeOr : 1; // marks the original OR node unsigned fCompl0 : 1; // marks the original complemented edge unsigned fCompl1 : 1; // marks the original complemented edge + // latch info + unsigned nLat0 : 5; // the number of latches on the first edge + unsigned nLat1 : 5; // the number of latches on the second edge + unsigned nLat2 : 5; // the number of latches on the output edge }; typedef struct Dec_Graph_t_ Dec_Graph_t; diff --git a/src/temp/ivy/ivy.h b/src/temp/ivy/ivy.h index 8c5f130b..7fb054f7 100644 --- a/src/temp/ivy/ivy.h +++ b/src/temp/ivy/ivy.h @@ -80,6 +80,8 @@ struct Ivy_Obj_t_ // 24 bytes (32-bit) or 32 bytes (64-bit) int nRefs; // reference counter Ivy_Obj_t * pFanin0; // fanin Ivy_Obj_t * pFanin1; // fanin + Ivy_Obj_t * pFanout; // fanout + Ivy_Obj_t * pEquiv; // equivalent node }; // the AIG manager @@ -136,6 +138,9 @@ struct Ivy_Store_t_ Ivy_Cut_t pCuts[IVY_CUT_LIMIT]; // storage for cuts }; +#define IVY_LEAF_MASK 255 +#define IVY_LEAF_BITS 8 + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -170,9 +175,9 @@ static inline Ivy_Edge_t Ivy_EdgeNotCond( Ivy_Edge_t Edge, int fCond ) { ret static inline Ivy_Edge_t Ivy_EdgeFromNode( Ivy_Obj_t * pNode ) { return Ivy_EdgeCreate( Ivy_Regular(pNode)->Id, Ivy_IsComplement(pNode) ); } static inline Ivy_Obj_t * Ivy_EdgeToNode( Ivy_Man_t * p, Ivy_Edge_t Edge ){ return Ivy_NotCond( Ivy_ManObj(p, Ivy_EdgeId(Edge)), Ivy_EdgeIsComplement(Edge) ); } -static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << 4) | Lat; } -static inline int Ivy_LeafId( int Leaf ) { return Leaf >> 4; } -static inline int Ivy_LeafLat( int Leaf ) { return Leaf & 15; } +static inline int Ivy_LeafCreate( int Id, int Lat ) { return (Id << IVY_LEAF_BITS) | Lat; } +static inline int Ivy_LeafId( int Leaf ) { return Leaf >> IVY_LEAF_BITS; } +static inline int Ivy_LeafLat( int Leaf ) { return Leaf & IVY_LEAF_MASK; } static inline int Ivy_ManPiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PI]; } static inline int Ivy_ManPoNum( Ivy_Man_t * p ) { return p->nObjs[IVY_PO]; } @@ -261,12 +266,16 @@ static inline int Ivy_ObjFanoutC( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout static inline Ivy_Obj_t * Ivy_ObjCreateGhost( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type, Ivy_Init_t Init ) { Ivy_Obj_t * pGhost, * pTemp; + assert( Type != IVY_AND || !Ivy_ObjIsConst1(Ivy_Regular(p0)) ); + assert( p1 == NULL || !Ivy_ObjIsConst1(Ivy_Regular(p1)) ); + assert( Type == IVY_PI || Ivy_Regular(p0) != Ivy_Regular(p1) ); + assert( Type != IVY_LATCH || !Ivy_IsComplement(p0) ); +// assert( p1 == NULL || (!Ivy_ObjIsLatch(Ivy_Regular(p0)) || !Ivy_ObjIsLatch(Ivy_Regular(p1))) ); pGhost = Ivy_ManGhost(p); pGhost->Type = Type; pGhost->Init = Init; pGhost->pFanin0 = p0; pGhost->pFanin1 = p1; - assert( Type == IVY_PI || Ivy_ObjFanin0(pGhost) != Ivy_ObjFanin1(pGhost) ); if ( p1 && Ivy_ObjFaninId0(pGhost) > Ivy_ObjFaninId1(pGhost) ) pTemp = pGhost->pFanin0, pGhost->pFanin0 = pGhost->pFanin1, pGhost->pFanin1 = pTemp; return pGhost; @@ -384,6 +393,7 @@ extern Vec_Int_t * Ivy_ManDfsSeq( Ivy_Man_t * p, Vec_Int_t ** pvLatches ); extern void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone ); extern Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p ); extern Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p ); +extern int Ivy_ManIsAcyclic( Ivy_Man_t * p ); /*=== ivyDsd.c ==========================================================*/ extern int Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree ); extern void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree ); @@ -400,11 +410,14 @@ extern void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, V extern Ivy_Obj_t * Ivy_ObjReadOneFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj ); extern Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj ); extern int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj ); +/*=== ivyIsop.c ==========================================================*/ +extern int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover ); +extern void Ivy_TruthManStop(); /*=== ivyMan.c ==========================================================*/ extern Ivy_Man_t * Ivy_ManStart(); extern void Ivy_ManStop( Ivy_Man_t * p ); extern int Ivy_ManCleanup( Ivy_Man_t * p ); -extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p ); +extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel ); extern void Ivy_ManPrintStats( Ivy_Man_t * p ); extern void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits ); /*=== ivyMem.c ==========================================================*/ @@ -425,8 +438,8 @@ extern void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj ); extern void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew ); extern void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ); extern void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ); -extern void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop ); -extern void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode ); +extern void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel ); +extern void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel ); /*=== ivyOper.c =========================================================*/ extern Ivy_Obj_t * Ivy_Oper( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type ); extern Ivy_Obj_t * Ivy_And( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); @@ -442,6 +455,8 @@ extern Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * p, int fUpdateLevel, int fVerbo extern int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ); extern int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ); extern int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose ); +/*=== ivySeq.c =========================================================*/ +extern int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose ); /*=== ivyTable.c ========================================================*/ extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj ); extern void Ivy_TableInsert( Ivy_Man_t * p, Ivy_Obj_t * pObj ); @@ -456,6 +471,7 @@ extern unsigned * Ivy_ManCutTruth( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_In extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p ); extern int Ivy_ManLevels( Ivy_Man_t * p ); extern void Ivy_ManResetLevels( Ivy_Man_t * p ); +extern int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pObj ); extern void Ivy_ObjUpdateLevel_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj ); extern void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ReqNew ); extern int Ivy_ObjIsMuxType( Ivy_Obj_t * pObj ); diff --git a/src/temp/ivy/ivyCheck.c b/src/temp/ivy/ivyCheck.c index 4331c07e..36222f72 100644 --- a/src/temp/ivy/ivyCheck.c +++ b/src/temp/ivy/ivyCheck.c @@ -107,8 +107,8 @@ int Ivy_ManCheck( Ivy_Man_t * p ) printf( "Ivy_ManCheck: The AIG has node \"%d\" with a wrong ordering of fanins.\n", pObj->Id ); return 0; } -// if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) ) -// printf( "Ivy_ManCheck: Node with ID \"%d\" has level %d but should have level %d.\n", pObj->Id, Ivy_ObjLevel(pObj), Ivy_ObjLevelNew(pObj) ); + if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) ) + printf( "Ivy_ManCheck: Node with ID \"%d\" has level %d but should have level %d.\n", pObj->Id, Ivy_ObjLevel(pObj), Ivy_ObjLevelNew(pObj) ); pObj2 = Ivy_TableLookup( p, pObj ); if ( pObj2 != pObj ) printf( "Ivy_ManCheck: Node with ID \"%d\" is not in the structural hashing table.\n", pObj->Id ); @@ -124,6 +124,8 @@ int Ivy_ManCheck( Ivy_Man_t * p ) printf( "Ivy_ManCheck: The number of nodes in the structural hashing table is wrong.\n" ); return 0; } + if ( !Ivy_ManIsAcyclic(p) ) + return 0; return 1; } diff --git a/src/temp/ivy/ivyCut.c b/src/temp/ivy/ivyCut.c index 7d1ec63a..56f872e9 100644 --- a/src/temp/ivy/ivyCut.c +++ b/src/temp/ivy/ivyCut.c @@ -24,6 +24,8 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static inline int Ivy_NodeCutHashValue( int NodeId ) { return 1 << (NodeId % 31); } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -580,6 +582,88 @@ static inline int Ivy_NodeCutExtend( Ivy_Cut_t * pCut, int iNew ) /**Function************************************************************* + Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Ivy_NodeCutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 ) +{ + int i; + if ( pCut->nSize < pCut->nSizeMax ) + return 1; + for ( i = 0; i < pCut->nSize; i++ ) + if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Derives new cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Ivy_NodeCutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) +{ + unsigned uHash = 0; + int i, k; + assert( pCut->nSize > 0 ); + assert( IdNew0 < IdNew1 ); + for ( i = k = 0; i < pCut->nSize; i++ ) + { + if ( pCut->pArray[i] == IdOld ) + continue; + if ( IdNew0 <= pCut->pArray[i] ) + { + if ( IdNew0 < pCut->pArray[i] ) + { + pCutNew->pArray[ k++ ] = IdNew0; + uHash |= Ivy_NodeCutHashValue( IdNew0 ); + } + IdNew0 = 0x7FFFFFFF; + } + if ( IdNew1 <= pCut->pArray[i] ) + { + if ( IdNew1 < pCut->pArray[i] ) + { + pCutNew->pArray[ k++ ] = IdNew1; + uHash |= Ivy_NodeCutHashValue( IdNew1 ); + } + IdNew1 = 0x7FFFFFFF; + } + pCutNew->pArray[ k++ ] = pCut->pArray[i]; + uHash |= Ivy_NodeCutHashValue( pCut->pArray[i] ); + } + if ( IdNew0 < 0x7FFFFFFF ) + { + pCutNew->pArray[ k++ ] = IdNew0; + uHash |= Ivy_NodeCutHashValue( IdNew0 ); + } + if ( IdNew1 < 0x7FFFFFFF ) + { + pCutNew->pArray[ k++ ] = IdNew1; + uHash |= Ivy_NodeCutHashValue( IdNew1 ); + } + pCutNew->nSize = k; + pCutNew->uHash = uHash; + assert( pCutNew->nSize <= pCut->nSizeMax ); +// for ( i = 1; i < pCutNew->nSize; i++ ) +// assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] ); + return 1; +} + +/**Function************************************************************* + Synopsis [Check if the cut exists.] Description [Returns 1 if the cut exists.] @@ -789,7 +873,7 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut; Ivy_Man_t * pMan = p; Ivy_Obj_t * pLeaf; - int i, k; + int i, k, iLeaf0, iLeaf1; assert( nLeaves <= IVY_CUT_INPUT ); @@ -818,6 +902,7 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves pLeaf = Ivy_ManObj( p, pCut->pArray[k] ); if ( Ivy_ObjIsCi(pLeaf) ) continue; +/* *pCutNew = *pCut; Ivy_NodeCutShrink( pCutNew, pLeaf->Id ); if ( !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId0(pLeaf) ) ) @@ -825,6 +910,12 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves if ( Ivy_ObjIsNode(pLeaf) && !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId1(pLeaf) ) ) continue; Ivy_NodeCutHash( pCutNew ); +*/ + iLeaf0 = Ivy_ObjFaninId0(pLeaf); + iLeaf1 = Ivy_ObjFaninId1(pLeaf); + if ( !Ivy_NodeCutPrescreen( pCut, iLeaf0, iLeaf1 ) ) + continue; + Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ); Ivy_NodeCutFindOrAddFilter( pCutStore, pCutNew ); if ( pCutStore->nCuts == IVY_CUT_LIMIT ) break; diff --git a/src/temp/ivy/ivyDfs.c b/src/temp/ivy/ivyDfs.c index fb938c42..30671baf 100644 --- a/src/temp/ivy/ivyDfs.c +++ b/src/temp/ivy/ivyDfs.c @@ -250,6 +250,105 @@ Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p ) return vLevelsR; } +/**Function************************************************************* + + Synopsis [Recursively detects combinational loops.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManIsAcyclic_rec( Ivy_Man_t * p, Ivy_Obj_t * pNode ) +{ + if ( Ivy_ObjIsCi(pNode) || Ivy_ObjIsConst1(pNode) ) + return 1; + assert( Ivy_ObjIsNode( pNode ) ); + // make sure the node is not visited + assert( !Ivy_ObjIsTravIdPrevious(p, pNode) ); + // check if the node is part of the combinational loop + if ( Ivy_ObjIsTravIdCurrent(p, pNode) ) + { + fprintf( stdout, "Manager contains combinational loop!\n" ); + fprintf( stdout, "Node \"%d\" is encountered twice on the following path:\n", Ivy_ObjId(pNode) ); + fprintf( stdout, " %d", Ivy_ObjId(pNode) ); + return 0; + } + // mark this node as a node on the current path + Ivy_ObjSetTravIdCurrent( p, pNode ); + // check if the fanin is visited + if ( !Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin0(pNode)) ) + { + // traverse the fanin's cone searching for the loop + if ( !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pNode)) ) + { + // return as soon as the loop is detected + fprintf( stdout, " <-- %d", Ivy_ObjId(Ivy_ObjFanin0(pNode)) ); + return 0; + } + } + // check if the fanin is visited + if ( !Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin1(pNode)) ) + { + // traverse the fanin's cone searching for the loop + if ( !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin1(pNode)) ) + { + // return as soon as the loop is detected + fprintf( stdout, " <-- %d", Ivy_ObjId(Ivy_ObjFanin1(pNode)) ); + return 0; + } + } + // mark this node as a visited node + Ivy_ObjSetTravIdPrevious( p, pNode ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Detects combinational loops.] + + Description [This procedure is based on the idea suggested by Donald Chai. + As we traverse the network and visit the nodes, we need to distinquish + three types of nodes: (1) those that are visited for the first time, + (2) those that have been visited in this traversal but are currently not + on the traversal path, (3) those that have been visited and are currently + on the travesal path. When the node of type (3) is encountered, it means + that there is a combinational loop. To mark the three types of nodes, + two new values of the traversal IDs are used.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManIsAcyclic( Ivy_Man_t * p ) +{ + Ivy_Obj_t * pNode; + int fAcyclic, i; + // set the traversal ID for this DFS ordering + Ivy_ManIncrementTravId( p ); + Ivy_ManIncrementTravId( p ); + // pNode->TravId == pNet->nTravIds means "pNode is on the path" + // pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path" + // pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited" + // traverse the network to detect cycles + fAcyclic = 1; + Ivy_ManForEachCo( p, pNode, i ) + { + if ( Ivy_ObjIsTravIdPrevious(p, Ivy_ObjFanin0(pNode)) ) + continue; + // traverse the output logic cone + if ( fAcyclic = Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pNode)) ) + continue; + // stop as soon as the first loop is detected + fprintf( stdout, " (cone of CO \"%d\")\n", Ivy_ObjFaninId0(pNode) ); + break; + } + return fAcyclic; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/temp/ivy/ivyFanout.c b/src/temp/ivy/ivyFanout.c index 5911e051..2295516d 100644 --- a/src/temp/ivy/ivyFanout.c +++ b/src/temp/ivy/ivyFanout.c @@ -153,6 +153,7 @@ void Ivy_ObjDeleteFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout ) assert( *ppSpot == pFanout ); *ppSpot = NULL; } +// printf( " %d", Ivy_ObjFanoutNum(p, pObj) ); } /**Function************************************************************* diff --git a/src/temp/ivy/ivyIsop.c b/src/temp/ivy/ivyIsop.c index f53e513d..2d0101a7 100644 --- a/src/temp/ivy/ivyIsop.c +++ b/src/temp/ivy/ivyIsop.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "ivy.h" +#include "mem.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -33,7 +34,8 @@ struct Ivy_Sop_t_ static Mem_Flex_t * s_Man = NULL; -static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t * pcRes ); +static unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy_Sop_t * pcRes ); +static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t * pcRes ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -41,7 +43,7 @@ static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy /**Function************************************************************* - Synopsis [] + Synopsis [Deallocates memory used for computing ISOPs from TTs.] Description [] @@ -50,14 +52,15 @@ static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy SeeAlso [] ***********************************************************************/ -void Ivy_TruthManStart() +void Ivy_TruthManStop() { - s_Man = Mem_FlexStart(); + Mem_FlexStop( s_Man, 0 ); + s_Man = NULL; } /**Function************************************************************* - Synopsis [] + Synopsis [Computes ISOP from TT.] Description [] @@ -66,15 +69,37 @@ void Ivy_TruthManStart() SeeAlso [] ***********************************************************************/ -void Ivy_TruthManStop() +int Ivy_TruthIsopOne( unsigned * puTruth, int nVars, Vec_Int_t * vCover ) { - Mem_FlexStop( s_Man, 0 ); - s_Man = NULL; + Ivy_Sop_t cRes, * pcRes = &cRes; + unsigned * pResult; + int i; + assert( nVars >= 0 && nVars < 16 ); + // if nVars < 5, make sure it does not depend on those vars + for ( i = nVars; i < 5; i++ ) + assert( !Extra_TruthVarInSupport(puTruth, 5, i) ); + // prepare memory manager + if ( s_Man == NULL ) + s_Man = Mem_FlexStart(); + else + Mem_FlexRestart( s_Man ); + // compute ISOP + pResult = Ivy_TruthIsop_rec( puTruth, puTruth, nVars, pcRes ); +// Extra_PrintBinary( stdout, puTruth, 1 << nVars ); printf( "\n" ); +// Extra_PrintBinary( stdout, pResult, 1 << nVars ); printf( "\n" ); + assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) ); +//printf( "%d ", Mem_FlexReadMemUsage(s_Man) ); +//printf( "%d ", pcRes->nCubes ); + // copy the truth table + Vec_IntClear( vCover ); + for ( i = 0; i < pcRes->nCubes; i++ ) + Vec_IntPush( vCover, pcRes->pCubes[i] ); + return 0; } /**Function************************************************************* - Synopsis [] + Synopsis [Computes ISOP from TT.] Description [] @@ -83,13 +108,51 @@ void Ivy_TruthManStop() SeeAlso [] ***********************************************************************/ -Vec_Int_t * Ivy_TruthIsop( unsigned * uTruth, int nVars ) +int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover ) { + Ivy_Sop_t cRes, * pcRes = &cRes; + unsigned * pResult; + int i; + assert( nVars >= 0 && nVars < 16 ); + // if nVars < 5, make sure it does not depend on those vars + for ( i = nVars; i < 5; i++ ) + assert( !Extra_TruthVarInSupport(puTruth, 5, i) ); + // prepare memory manager + if ( s_Man == NULL ) + s_Man = Mem_FlexStart(); + else + Mem_FlexRestart( s_Man ); + // compute ISOP + pResult = Ivy_TruthIsop_rec( puTruth, puTruth, nVars, pcRes ); +// Extra_PrintBinary( stdout, puTruth, 1 << nVars ); printf( "\n" ); +// Extra_PrintBinary( stdout, pResult, 1 << nVars ); printf( "\n" ); + assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) ); +//printf( "%d ", Mem_FlexReadMemUsage(s_Man) ); +//printf( "%d ", pcRes->nCubes ); + // copy the truth table + Vec_IntClear( vCover ); + for ( i = 0; i < pcRes->nCubes; i++ ) + Vec_IntPush( vCover, pcRes->pCubes[i] ); + + // try other polarity + Mem_FlexRestart( s_Man ); + Extra_TruthNot( puTruth, puTruth, nVars ); + pResult = Ivy_TruthIsop_rec( puTruth, puTruth, nVars, pcRes ); + assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) ); + Extra_TruthNot( puTruth, puTruth, nVars ); + if ( Vec_IntSize(vCover) < pcRes->nCubes ) + return 0; + + // copy the truth table + Vec_IntClear( vCover ); + for ( i = 0; i < pcRes->nCubes; i++ ) + Vec_IntPush( vCover, pcRes->pCubes[i] ); + return 1; } /**Function************************************************************* - Synopsis [Computes ISOP for 5 variables or less.] + Synopsis [Computes ISOP 6 variables or more.] Description [] @@ -103,54 +166,59 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy Ivy_Sop_t cRes0, cRes1, cRes2; Ivy_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2; unsigned * puRes0, * puRes1, * puRes2; - unsigned * puOn0, * puOn1, * puOnDc0, * puOnDc1, * pTemp0, * pTemp1; - int i, k, Var, nWords; - assert( nVars > 5 ); + unsigned * puOn0, * puOn1, * puOnDc0, * puOnDc1, * pTemp, * pTemp0, * pTemp1; + int i, k, Var, nWords, nWordsAll; assert( Extra_TruthIsImply( puOn, puOnDc, nVars ) ); + // allocate room for the resulting truth table + nWordsAll = Extra_TruthWordNum( nVars ); + pTemp = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * nWordsAll ); + // check for constants if ( Extra_TruthIsConst0( puOn, nVars ) ) { pcRes->nCubes = 0; pcRes->pCubes = NULL; - return puOn; + Extra_TruthClear( pTemp, nVars ); + return pTemp; } if ( Extra_TruthIsConst1( puOnDc, nVars ) ) { pcRes->nCubes = 1; pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 ); pcRes->pCubes[0] = 0; - return puOnDc; + Extra_TruthFill( pTemp, nVars ); + return pTemp; } + assert( nVars > 0 ); // find the topmost var for ( Var = nVars-1; Var >= 0; Var-- ) if ( Extra_TruthVarInSupport( puOn, nVars, Var ) || Extra_TruthVarInSupport( puOnDc, nVars, Var ) ) break; assert( Var >= 0 ); + // consider a simple case when one-word computation can be used if ( Var < 5 ) { - unsigned * puRes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 ); - *puRes = Ivy_TruthIsop5_rec( puOn[0], puOnDc[0], Var + 1, pcRes ); - return puRes; + unsigned uRes = Ivy_TruthIsop5_rec( puOn[0], puOnDc[0], Var+1, pcRes ); + for ( i = 0; i < nWordsAll; i++ ) + pTemp[i] = uRes; + return pTemp; } - nWords = Extra_TruthWordNum( Var+1 ); + assert( Var >= 5 ); + nWords = Extra_TruthWordNum( Var ); // cofactor - puOn0 = puOn; - puOn1 = puOn + nWords; - puOnDc0 = puOnDc; - puOnDc1 = puOnDc + nWords; - // intermediate copies - pTemp0 = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * nWords ); - pTemp1 = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * nWords ); + puOn0 = puOn; puOn1 = puOn + nWords; + puOnDc0 = puOnDc; puOnDc1 = puOnDc + nWords; + pTemp0 = pTemp; pTemp1 = pTemp + nWords; // solve for cofactors - Extra_TruthSharp( pTemp0, puOn0, puOnDc1, Var + 1 ); - puRes0 = Ivy_TruthIsop5_rec( pTemp0, uOnDc0, Var-1, pcRes0 ); - Extra_TruthSharp( pTemp0, puOn1, puOnDc0, Var + 1 ); - puRes1 = Ivy_TruthIsop5_rec( pTemp1, uOnDc1, Var-1, pcRes1 ); - Extra_TruthSharp( pTemp0, puOn0, puRes0, Var + 1 ); - Extra_TruthSharp( pTemp1, puOn1, puRes1, Var + 1 ); - Extra_TruthOr( pTemp0, pTemp0, pTemp1, Var + 1 ); - Extra_TruthAnd( pTemp1, puOnDc0, puOnDc1, Var + 1 ); - puRes2 = Ivy_TruthIsop5_rec( pTemp0, pTemp1, Var-1, pcRes2 ); + Extra_TruthSharp( pTemp0, puOn0, puOnDc1, Var ); + puRes0 = Ivy_TruthIsop_rec( pTemp0, puOnDc0, Var, pcRes0 ); + Extra_TruthSharp( pTemp1, puOn1, puOnDc0, Var ); + puRes1 = Ivy_TruthIsop_rec( pTemp1, puOnDc1, Var, pcRes1 ); + Extra_TruthSharp( pTemp0, puOn0, puRes0, Var ); + Extra_TruthSharp( pTemp1, puOn1, puRes1, Var ); + Extra_TruthOr( pTemp0, pTemp0, pTemp1, Var ); + Extra_TruthAnd( pTemp1, puOnDc0, puOnDc1, Var ); + puRes2 = Ivy_TruthIsop_rec( pTemp0, pTemp1, Var, pcRes2 ); // create the resulting cover pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes; pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * pcRes->nCubes ); @@ -159,13 +227,21 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+1)); for ( i = 0; i < pcRes1->nCubes; i++ ) pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+0)); - for ( i = 0; i < pcRes1->nCubes; i++ ) + for ( i = 0; i < pcRes2->nCubes; i++ ) pcRes->pCubes[k++] = pcRes2->pCubes[i]; assert( k == pcRes->nCubes ); // create the resulting truth table - Extra_TruthSharp( pTemp0, Var, uRes0, uRes1, Var + 1 ); - Extra_TruthOr( pTemp0, pTemp0, uRes2, Var + 1 ); - return pTemp0; + Extra_TruthOr( pTemp0, puRes0, puRes2, Var ); + Extra_TruthOr( pTemp1, puRes1, puRes2, Var ); + // copy the table if needed + nWords <<= 1; + for ( i = 1; i < nWordsAll/nWords; i++ ) + for ( k = 0; k < nWords; k++ ) + pTemp[i*nWords + k] = pTemp[k]; + // verify in the end +// assert( Extra_TruthIsImply( puOn, pTemp, nVars ) ); +// assert( Extra_TruthIsImply( pTemp, puOnDc, nVars ) ); + return pTemp; } /**Function************************************************************* @@ -184,12 +260,11 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; Ivy_Sop_t cRes0, cRes1, cRes2; Ivy_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2; - unsigned uRes0, uRes1, uRes2; - unsigned uOn0, uOn1, uOnDc0, uOnDc1; + unsigned uOn0, uOn1, uOnDc0, uOnDc1, uRes0, uRes1, uRes2; int i, k, Var; assert( nVars <= 5 ); - assert( uOn & ~uOnDc == 0 ); - if ( Extra_TruthIsConst0( uOn == 0 ) + assert( (uOn & ~uOnDc) == 0 ); + if ( uOn == 0 ) { pcRes->nCubes = 0; pcRes->pCubes = NULL; @@ -202,6 +277,7 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t pcRes->pCubes[0] = 0; return 0xFFFFFFFF; } + assert( nVars > 0 ); // find the topmost var for ( Var = nVars-1; Var >= 0; Var-- ) if ( Extra_TruthVarInSupport( &uOn, 5, Var ) || @@ -209,16 +285,16 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t break; assert( Var >= 0 ); // cofactor - uOn0 = uOn1 = uOn; + uOn0 = uOn1 = uOn; uOnDc0 = uOnDc1 = uOnDc; - Extra_TruthCofactor0( &uOn0, 5, Var ); - Extra_TruthCofactor1( &uOn1, 5, Var ); - Extra_TruthCofactor0( &uOnDc0, 5, Var ); - Extra_TruthCofactor1( &uOnDc1, 5, Var ); + Extra_TruthCofactor0( &uOn0, Var + 1, Var ); + Extra_TruthCofactor1( &uOn1, Var + 1, Var ); + Extra_TruthCofactor0( &uOnDc0, Var + 1, Var ); + Extra_TruthCofactor1( &uOnDc1, Var + 1, Var ); // solve for cofactors - uRes0 = Ivy_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var-1, pcRes0 ); - uRes1 = Ivy_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var-1, pcRes1 ); - uRes2 = Ivy_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var-1, pcRes2 ); + uRes0 = Ivy_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var, pcRes0 ); + uRes1 = Ivy_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var, pcRes1 ); + uRes2 = Ivy_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var, pcRes2 ); // create the resulting cover pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes; pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * pcRes->nCubes ); @@ -227,10 +303,14 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+1)); for ( i = 0; i < pcRes1->nCubes; i++ ) pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+0)); - for ( i = 0; i < pcRes1->nCubes; i++ ) + for ( i = 0; i < pcRes2->nCubes; i++ ) pcRes->pCubes[k++] = pcRes2->pCubes[i]; assert( k == pcRes->nCubes ); - return (uRes0 & ~uMasks[Var]) | (uRes1 & uMasks[Var]) | uRes2; + // derive the final truth table + uRes2 |= (uRes0 & ~uMasks[Var]) | (uRes1 & uMasks[Var]); +// assert( (uOn & ~uRes2) == 0 ); +// assert( (uRes2 & ~uOnDc) == 0 ); + return uRes2; } diff --git a/src/temp/ivy/ivyMan.c b/src/temp/ivy/ivyMan.c index d1aca8a6..c5b66ad0 100644 --- a/src/temp/ivy/ivyMan.c +++ b/src/temp/ivy/ivyMan.c @@ -109,9 +109,10 @@ int Ivy_ManCleanup( Ivy_Man_t * p ) Ivy_Obj_t * pNode; int i, nNodesOld; nNodesOld = Ivy_ManNodeNum(p); - Ivy_ManForEachNode( p, pNode, i ) - if ( Ivy_ObjRefs(pNode) == 0 ) - Ivy_ObjDelete_rec( p, pNode, 1 ); + Ivy_ManForEachObj( p, pNode, i ) + if ( Ivy_ObjIsNode(pNode) || Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) ) + if ( Ivy_ObjRefs(pNode) == 0 ) + Ivy_ObjDelete_rec( p, pNode, 1 ); return nNodesOld - Ivy_ManNodeNum(p); } @@ -126,7 +127,7 @@ int Ivy_ManCleanup( Ivy_Man_t * p ) SeeAlso [] ***********************************************************************/ -int Ivy_ManPropagateBuffers( Ivy_Man_t * p ) +int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel ) { Ivy_Obj_t * pNode; int nSteps; @@ -135,7 +136,7 @@ int Ivy_ManPropagateBuffers( Ivy_Man_t * p ) pNode = Vec_PtrEntryLast(p->vBufs); while ( Ivy_ObjIsBuf(pNode) ) pNode = Ivy_ObjReadFirstFanout( p, pNode ); - Ivy_NodeFixBufferFanins( p, pNode ); + Ivy_NodeFixBufferFanins( p, pNode, fUpdateLevel ); } // printf( "Number of steps = %d\n", nSteps ); return nSteps; @@ -200,6 +201,9 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits ) pObj = Ivy_ManPo( p, Ivy_ManPoNum(p) - nLatches + i ); pLatch = Ivy_Latch( p, Ivy_ObjChild0(pObj), Init ); Ivy_ObjDisconnect( p, pObj ); + // recycle the old PO object + Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL ); + Ivy_ManRecycleMemory( p, pObj ); // convert the corresponding PI to a buffer and connect it to the latch pObj = Ivy_ManPi( p, Ivy_ManPiNum(p) - nLatches + i ); pObj->Type = IVY_BUF; @@ -215,8 +219,21 @@ void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits ) p->nObjs[IVY_PO] -= nLatches; p->nObjs[IVY_BUF] += nLatches; p->nDeleted -= 2 * nLatches; + // remove dangling nodes + Ivy_ManCleanup(p); +/* + // check for dangling nodes + Ivy_ManForEachObj( p, pObj, i ) + if ( !Ivy_ObjIsPi(pObj) && !Ivy_ObjIsPo(pObj) && !Ivy_ObjIsConst1(pObj) ) + { + assert( Ivy_ObjRefs(pObj) > 0 ); + assert( Ivy_ObjRefs(pObj) == Ivy_ObjFanoutNum(p, pObj) ); + } +*/ // perform hashing by propagating the buffers - Ivy_ManPropagateBuffers( p ); + Ivy_ManPropagateBuffers( p, 0 ); + // fix the levels + Ivy_ManResetLevels( p ); // check the resulting network if ( !Ivy_ManCheck(p) ) printf( "Ivy_ManMakeSeq(): The check has failed.\n" ); diff --git a/src/temp/ivy/ivyObj.c b/src/temp/ivy/ivyObj.c index de67c560..735d79c3 100644 --- a/src/temp/ivy/ivyObj.c +++ b/src/temp/ivy/ivyObj.c @@ -300,7 +300,7 @@ void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ) SeeAlso [] ***********************************************************************/ -void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop ) +void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel ) { int nRefsOld; // the object to be replaced cannot be complemented @@ -315,26 +315,32 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) ) pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) ); assert( !Ivy_IsComplement(pObjNew) ); - // if the new node's arrival time is different, recursively update arrival time of the fanouts - if ( p->vFanouts && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level ) + if ( fUpdateLevel ) { - assert( Ivy_ObjIsNode(pObjOld) ); - pObjOld->Level = pObjNew->Level; - Ivy_ObjUpdateLevel_rec( p, pObjOld ); - } - // if the new node's required time has changed, recursively update required time of the fanins - if ( p->vRequired ) - { - int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id); - if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) ) + // if the new node's arrival time is different, recursively update arrival time of the fanouts + if ( p->vFanouts && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level ) + { + assert( Ivy_ObjIsNode(pObjOld) ); + pObjOld->Level = pObjNew->Level; + Ivy_ObjUpdateLevel_rec( p, pObjOld ); + } + // if the new node's required time has changed, recursively update required time of the fanins + if ( p->vRequired ) { - Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew ); - Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew ); + int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id); + if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) ) + { + Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew ); + Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew ); + } } } // delete the old object if ( fDeleteOld ) Ivy_ObjDelete_rec( p, pObjOld, fFreeTop ); + // make sure object is pointing to itself + assert( Ivy_ObjFanin0(pObjNew) == NULL || pObjOld != Ivy_ObjFanin0(pObjNew) ); + assert( Ivy_ObjFanin1(pObjNew) == NULL || pObjOld != Ivy_ObjFanin1(pObjNew) ); // transfer the old object assert( Ivy_ObjRefs(pObjNew) == 0 ); nRefsOld = pObjOld->nRefs; @@ -370,7 +376,7 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in SeeAlso [] ***********************************************************************/ -void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode ) +void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel ) { Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult; if ( Ivy_ObjIsPo(pNode) ) @@ -394,7 +400,7 @@ void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode ) else assert( 0 ); // perform the replacement - Ivy_ObjReplace( p, pNode, pResult, 1, 0 ); + Ivy_ObjReplace( p, pNode, pResult, 1, 0, fUpdateLevel ); } //////////////////////////////////////////////////////////////////////// diff --git a/src/temp/ivy/ivyRwrAlg.c b/src/temp/ivy/ivyRwrAlg.c index 234827ff..fc48deb0 100644 --- a/src/temp/ivy/ivyRwrAlg.c +++ b/src/temp/ivy/ivyRwrAlg.c @@ -80,7 +80,7 @@ int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ) // the case of constant 0 cone if ( RetValue == -1 ) { - Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0 ); + Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0, 1 ); continue; } assert( Vec_PtrSize(vLeaves) > 2 ); @@ -94,7 +94,7 @@ int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ) if ( Ivy_ObjLevel(Ivy_Regular(pResult)) > LevelR && Ivy_ObjRefs(Ivy_Regular(pResult)) == 0 ) Ivy_ObjDelete_rec(Ivy_Regular(pResult), 1), CountUndo++; else - Ivy_ObjReplace( pObj, pResult, 1, 0 ), CountUsed++; + Ivy_ObjReplace( pObj, pResult, 1, 0, 1 ), CountUsed++; } printf( "Used = %d. Undo = %d.\n", CountUsed, CountUndo ); Vec_PtrFree( vFront ); diff --git a/src/temp/ivy/ivyRwrPre.c b/src/temp/ivy/ivyRwrPre.c index d2a1697e..537b64ff 100644 --- a/src/temp/ivy/ivyRwrPre.c +++ b/src/temp/ivy/ivyRwrPre.c @@ -27,9 +27,8 @@ //////////////////////////////////////////////////////////////////////// static unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums ); -static int Ivy_NodeMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pObj ); static int Ivy_NodeRewrite( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost ); -static Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, +static Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth ); static int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ); @@ -74,7 +73,7 @@ int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fV Ivy_ManForEachNode( p, pNode, i ) { // fix the fanin buffer problem - Ivy_NodeFixBufferFanins( p, pNode ); + Ivy_NodeFixBufferFanins( p, pNode, 1 ); if ( Ivy_ObjIsBuf(pNode) ) continue; // stop if all nodes have been tried once @@ -120,8 +119,8 @@ Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart ); // fix the levels if ( fUpdateLevel ) Vec_IntFree( p->vRequired ), p->vRequired = NULL; -// else -// Ivy_ManResetLevels( p ); + else + Ivy_ManResetLevels( p ); // check if ( i = Ivy_ManCleanup(p) ) printf( "Cleanup after rewriting removed %d dangling nodes.\n", i ); @@ -182,7 +181,11 @@ clk = clock(); if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, pCut->pArray[i]) ) ) break; if ( i != pCut->nSize ) + { + p->nCutsBad++; continue; + } + p->nCutsGood++; // get the fanin permutation clk2 = clock(); uTruth = 0xFFFF & Ivy_NodeGetTruth( pNode, pCut->pArray, pCut->nSize ); // truth table @@ -211,7 +214,7 @@ clk2 = clock(); Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); // label MFFC with current ID Ivy_ManIncrementTravId( pMan ); - nNodesSaved = Ivy_NodeMffcLabel( pMan, pNode ); + nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode ); // unmark the fanin boundary Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); @@ -219,7 +222,7 @@ p->timeMffc += clock() - clk2; // evaluate the cut clk2 = clock(); - pGraph = Rwt_CutEvaluate( pMan, p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth ); + pGraph = Rwt_CutEvaluate( pMan, p, pNode, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth ); p->timeEval += clock() - clk2; // check if the cut is better than the current best one @@ -289,75 +292,6 @@ p->timeRes += clock() - clk; return GainBest; } - -/**Function************************************************************* - - Synopsis [References/references the node and returns MFFC size.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel ) -{ - Ivy_Obj_t * pNode0, * pNode1; - int Counter; - // label visited nodes - if ( fLabel ) - Ivy_ObjSetTravIdCurrent( p, pNode ); - // skip the CI - if ( Ivy_ObjIsCi(pNode) ) - return 0; - assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) ); - // process the internal node - pNode0 = Ivy_ObjFanin0(pNode); - pNode1 = Ivy_ObjFanin1(pNode); - Counter = Ivy_ObjIsNode(pNode); - if ( fReference ) - { - if ( pNode0->nRefs++ == 0 ) - Counter += Ivy_NodeRefDeref( p, pNode0, fReference, fLabel ); - if ( pNode1 && pNode1->nRefs++ == 0 ) - Counter += Ivy_NodeRefDeref( p, pNode1, fReference, fLabel ); - } - else - { - assert( pNode0->nRefs > 0 ); - assert( pNode1 == NULL || pNode1->nRefs > 0 ); - if ( --pNode0->nRefs == 0 ) - Counter += Ivy_NodeRefDeref( p, pNode0, fReference, fLabel ); - if ( pNode1 && --pNode1->nRefs == 0 ) - Counter += Ivy_NodeRefDeref( p, pNode1, fReference, fLabel ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Computes the size of MFFC and labels nodes with the current TravId.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ivy_NodeMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode ) -{ - int nConeSize1, nConeSize2; - assert( !Ivy_IsComplement( pNode ) ); - assert( Ivy_ObjIsNode( pNode ) ); - nConeSize1 = Ivy_NodeRefDeref( p, pNode, 0, 1 ); // dereference - nConeSize2 = Ivy_NodeRefDeref( p, pNode, 1, 0 ); // reference - assert( nConeSize1 == nConeSize2 ); - assert( nConeSize1 > 0 ); - return nConeSize1; -} - /**Function************************************************************* Synopsis [Computes the truth table.] @@ -418,7 +352,7 @@ unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums ) SeeAlso [] ***********************************************************************/ -Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth ) +Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth ) { Vec_Ptr_t * vSubgraphs; Dec_Graph_t * pGraphBest, * pGraphCur; @@ -596,12 +530,12 @@ void Ivy_GraphUpdateNetwork( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGr printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) ); printf( " " ); */ - Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0 ); + Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 1 ); // compare the gains nNodesNew = Ivy_ManNodeNum(p); assert( nGain <= nNodesOld - nNodesNew ); // propagate the buffer - Ivy_ManPropagateBuffers( p ); + Ivy_ManPropagateBuffers( p, 1 ); } /**Function************************************************************* @@ -649,7 +583,7 @@ void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pG printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) ); printf( " " ); */ - Ivy_ObjReplace( p, pRoot, pRootNew, 0, 0 ); + Ivy_ObjReplace( p, pRoot, pRootNew, 0, 0, 1 ); //printf( "Replace = %d. ", Ivy_ManNodeNum(p) ); // delete remaining dangling nodes diff --git a/src/temp/ivy/ivySeq.c b/src/temp/ivy/ivySeq.c index 1cfa8c4b..8fd1b63b 100644 --- a/src/temp/ivy/ivySeq.c +++ b/src/temp/ivy/ivySeq.c @@ -13,17 +13,28 @@ Affiliation [UC Berkeley] Date [Ver. 1.0. Started - May 11, 2006.] - + Revision [$Id: ivySeq.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] ***********************************************************************/ #include "ivy.h" +#include "deco.h" +#include "rwt.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUseZeroCost ); +static void Ivy_GraphPrepare( Dec_Graph_t * pGraph, Ivy_Cut_t * pCut, Vec_Ptr_t * vFanins, char * pPerm ); +static unsigned Ivy_CutGetTruth( Ivy_Man_t * p, Ivy_Obj_t * pObj, int * pNums, int nNums ); +static Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, char * pPerm, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int * pGainBest, unsigned uTruth ); +static int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax ); +static Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph ); +static void Ivy_GraphUpdateNetworkSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain ); +static Ivy_Store_t * Ivy_CutComputeForNode( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves ); + static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); } //////////////////////////////////////////////////////////////////////// @@ -32,6 +43,295 @@ static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); } /**Function************************************************************* + Synopsis [Performs incremental rewriting of the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose ) +{ + Rwt_Man_t * pManRwt; + Ivy_Obj_t * pNode; + int i, nNodes, nGain; + int clk, clkStart = clock(); + // start the rewriting manager + pManRwt = Rwt_ManStart( 0 ); + p->pData = pManRwt; + if ( pManRwt == NULL ) + return 0; + // create fanouts + if ( p->vFanouts == NULL ) + Ivy_ManStartFanout( p ); + // resynthesize each node once + nNodes = Ivy_ManObjIdMax(p); + Ivy_ManForEachNode( p, pNode, i ) + { + assert( !Ivy_ObjIsBuf(pNode) ); + assert( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) ); + assert( !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) ); + // fix the fanin buffer problem +// Ivy_NodeFixBufferFanins( p, pNode ); +// if ( Ivy_ObjIsBuf(pNode) ) +// continue; + // stop if all nodes have been tried once + if ( i > nNodes ) + break; + if ( i == 8648 ) + { + int x = 0; + } + // for each cut, try to resynthesize it + nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost ); + if ( nGain > 0 || nGain == 0 && fUseZeroCost ) + { + Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt); + int fCompl = Rwt_ManReadCompl(pManRwt); + // complement the FF if needed +clk = clock(); + if ( fCompl ) Dec_GraphComplement( pGraph ); + Ivy_GraphUpdateNetworkSeq( p, pNode, pGraph, nGain ); + if ( fCompl ) Dec_GraphComplement( pGraph ); +Rwt_ManAddTimeUpdate( pManRwt, clock() - clk ); +/* + if ( !Ivy_ManIsAcyclic(p) ) + { + int x = 0; + } +*/ + } + } +Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart ); + // print stats + if ( fVerbose ) + Rwt_ManPrintStats( pManRwt ); + // delete the managers + Rwt_ManStop( pManRwt ); + p->pData = NULL; + // fix the levels + Ivy_ManResetLevels( p ); + // check + if ( !Ivy_ManCheck(p) ) + printf( "Ivy_ManRewritePre(): The check has failed.\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Performs rewriting for one node.] + + Description [This procedure considers all the cuts computed for the node + and tries to rewrite each of them using the "forest" of different AIG + structures precomputed and stored in the RWR manager. + Determines the best rewriting and computes the gain in the number of AIG + nodes in the final network. In the end, p->vFanins contains information + about the best cut that can be used for rewriting, while p->pGraph gives + the decomposition dag (represented using decomposition graph data structure). + Returns gain in the number of nodes or -1 if node cannot be rewritten.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUseZeroCost ) +{ + int fVeryVerbose = 0; + Dec_Graph_t * pGraph; + Ivy_Store_t * pStore; + Ivy_Cut_t * pCut; + Ivy_Obj_t * pFanin; + unsigned uPhase, uTruthBest, uTruth; + char * pPerm; + int nNodesSaved, nNodesSaveCur; + int i, c, GainCur, GainBest = -1; + int clk, clk2; + + p->nNodesConsidered++; + // get the node's cuts +clk = clock(); + pStore = Ivy_CutComputeForNode( pMan, pNode, 5 ); +p->timeCut += clock() - clk; + + // go through the cuts +clk = clock(); + for ( c = 1; c < pStore->nCuts; c++ ) + { + pCut = pStore->pCuts + c; + // consider only 4-input cuts + if ( pCut->nSize != 4 ) + continue; + // skip the cuts with buffers + for ( i = 0; i < (int)pCut->nSize; i++ ) + if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, Ivy_LeafId(pCut->pArray[i])) ) ) + break; + if ( i != pCut->nSize ) + { + p->nCutsBad++; + continue; + } + p->nCutsGood++; + // get the fanin permutation +clk2 = clock(); + uTruth = 0xFFFF & Ivy_CutGetTruth( pMan, pNode, pCut->pArray, pCut->nSize ); // truth table +p->timeTruth += clock() - clk2; + pPerm = p->pPerms4[ p->pPerms[uTruth] ]; + uPhase = p->pPhases[uTruth]; + // collect fanins with the corresponding permutation/phase + Vec_PtrClear( p->vFaninsCur ); + Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 ); + for ( i = 0; i < (int)pCut->nSize; i++ ) + { + pFanin = Ivy_ManObj( pMan, Ivy_LeafId( pCut->pArray[pPerm[i]] ) ); + assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) || Ivy_ObjIsConst1(pFanin) ); + pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) ); + Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin ); + } +clk2 = clock(); + // mark the fanin boundary + Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); + // label MFFC with current ID + Ivy_ManIncrementTravId( pMan ); + nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode ); + // unmark the fanin boundary + Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); +p->timeMffc += clock() - clk2; +/* +if ( pNode->Id == 8648 ) +{ + int i; + printf( "Trying cut : {" ); + for ( i = 0; i < pCut->nSize; i++ ) + printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) ); +// printf( " }\n" ); + printf( " } " ); + Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" ); +} +*/ + + // evaluate the cut +clk2 = clock(); + pGraph = Rwt_CutEvaluateSeq( pMan, p, pNode, pCut, pPerm, p->vFaninsCur, nNodesSaved, &GainCur, uTruth ); +p->timeEval += clock() - clk2; + + + // check if the cut is better than the current best one + if ( pGraph != NULL && GainBest < GainCur ) + { + // save this form + nNodesSaveCur = nNodesSaved; + GainBest = GainCur; + p->pGraph = pGraph; + p->pCut = pCut; + p->pPerm = pPerm; + p->fCompl = ((uPhase & (1<<4)) > 0); + uTruthBest = uTruth; + // collect fanins in the + Vec_PtrClear( p->vFanins ); + Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) + Vec_PtrPush( p->vFanins, pFanin ); + } + } +p->timeRes += clock() - clk; + + if ( GainBest == -1 ) + return -1; + + // copy the leaves + Ivy_GraphPrepare( p->pGraph, p->pCut, p->vFanins, p->pPerm ); + + p->nScores[p->pMap[uTruthBest]]++; + p->nNodesGained += GainBest; + if ( fUseZeroCost || GainBest > 0 ) + p->nNodesRewritten++; + +/* + if ( GainBest > 0 ) + { + Ivy_Cut_t * pCut = p->pCut; + printf( "Useful cut : {" ); + for ( i = 0; i < pCut->nSize; i++ ) + printf( " %5d[%2d](%2d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]), + Ivy_ObjRefs( Ivy_ManObj(pMan, Ivy_LeafId(pCut->pArray[i])) ) ); + printf( " }\n" ); + } +*/ + + // report the progress + if ( fVeryVerbose && GainBest > 0 ) + { + printf( "Node %6d : ", Ivy_ObjId(pNode) ); + printf( "Fanins = %d. ", p->vFanins->nSize ); + printf( "Save = %d. ", nNodesSaveCur ); + printf( "Add = %d. ", nNodesSaveCur-GainBest ); + printf( "GAIN = %d. ", GainBest ); + printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 ); + printf( "Class = %d. ", p->pMap[uTruthBest] ); + printf( "\n" ); + } + return GainBest; +} + + +/**Function************************************************************* + + Synopsis [Evaluates the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Rwt_CutEvaluateSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, char * pPerm, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int * pGainBest, unsigned uTruth ) +{ + Vec_Ptr_t * vSubgraphs; + Dec_Graph_t * pGraphBest, * pGraphCur; + Rwt_Node_t * pNode; + int nNodesAdded, GainBest, i; + // find the matching class of subgraphs + vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); + p->nSubgraphs += vSubgraphs->nSize; + // determine the best subgraph + GainBest = -1; + Vec_PtrForEachEntry( vSubgraphs, pNode, i ) + { + // get the current graph + pGraphCur = (Dec_Graph_t *)pNode->pNext; + +// if ( pRoot->Id == 8648 ) +// Dec_GraphPrint( stdout, pGraphCur, NULL, NULL ); + // copy the leaves +// Vec_PtrForEachEntry( vFaninsCur, pFanin, k ) +// Dec_GraphNode(pGraphCur, k)->pFunc = pFanin; + Ivy_GraphPrepare( pGraphCur, pCut, vFaninsCur, pPerm ); + + // detect how many unlabeled nodes will be reused + nNodesAdded = Ivy_GraphToNetworkSeqCountSeq( pMan, pRoot, pGraphCur, nNodesSaved ); + if ( nNodesAdded == -1 ) + continue; + assert( nNodesSaved >= nNodesAdded ); + // count the gain at this node + if ( GainBest < nNodesSaved - nNodesAdded ) + { + GainBest = nNodesSaved - nNodesAdded; + pGraphBest = pGraphCur; + } + } + if ( GainBest == -1 ) + return NULL; + *pGainBest = GainBest; + return pGraphBest; +} + +/**Function************************************************************* + Synopsis [] Description [] @@ -41,8 +341,250 @@ static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); } SeeAlso [] ***********************************************************************/ +void Ivy_GraphPrepare( Dec_Graph_t * pGraph, Ivy_Cut_t * pCut, Vec_Ptr_t * vFanins, char * pPerm ) +{ + Dec_Node_t * pNode, * pNode0, * pNode1; + int i; + assert( Dec_GraphLeaveNum(pGraph) == pCut->nSize ); + assert( Vec_PtrSize(vFanins) == pCut->nSize ); + // label the leaves with latch numbers + Dec_GraphForEachLeaf( pGraph, pNode, i ) + { + pNode->pFunc = Vec_PtrEntry( vFanins, i ); + pNode->nLat2 = Ivy_LeafLat( pCut->pArray[pPerm[i]] ); + } + // propagate latches through the nodes + Dec_GraphForEachNode( pGraph, pNode, i ) + { + // get the children of this node + pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); + pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); + // distribute the latches + pNode->nLat2 = IVY_MIN( pNode0->nLat2, pNode1->nLat2 ); + pNode->nLat0 = pNode0->nLat2 - pNode->nLat2; + pNode->nLat1 = pNode1->nLat2 - pNode->nLat2; + } +} + +/**Function************************************************************* + + Synopsis [Counts the number of new nodes added when using this graph.] + + Description [AIG nodes for the fanins should be assigned to pNode->pFunc + of the leaves of the graph before calling this procedure. + Returns -1 if the number of nodes and levels exceeded the given limit or + the number of levels exceeded the maximum allowed level.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_GraphToNetworkSeqCountSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax ) +{ + Dec_Node_t * pNode, * pNode0, * pNode1; + Ivy_Obj_t * pAnd, * pAnd0, * pAnd1; + int i, k, Counter, fCompl; + // check for constant function or a literal + if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) ) + return 0; + // compute the AIG size after adding the internal nodes + Counter = 0; + Dec_GraphForEachNode( pGraph, pNode, i ) + { + // get the children of this node + pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); + pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); + // get the AIG nodes corresponding to the children + pAnd0 = pNode0->pFunc; + pAnd1 = pNode1->pFunc; + // skip the latches + for ( k = 0; pAnd0 && k < (int)pNode->nLat0; k++ ) + { + fCompl = Ivy_IsComplement(pAnd0); + pAnd0 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd0), NULL, IVY_LATCH, IVY_INIT_DC) ); + if ( pAnd0 ) + pAnd0 = Ivy_NotCond( pAnd0, fCompl ); + } + for ( k = 0; pAnd1 && k < (int)pNode->nLat1; k++ ) + { + fCompl = Ivy_IsComplement(pAnd1); + pAnd1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd1), NULL, IVY_LATCH, IVY_INIT_DC) ); + if ( pAnd1 ) + pAnd1 = Ivy_NotCond( pAnd1, fCompl ); + } + // get the new node + if ( pAnd0 && pAnd1 ) + { + // if they are both present, find the resulting node + pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl ); + pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl ); + assert( !Ivy_ObjIsLatch(Ivy_Regular(pAnd0)) || !Ivy_ObjIsLatch(Ivy_Regular(pAnd1)) ); + if ( Ivy_Regular(pAnd0) == Ivy_Regular(pAnd1) || Ivy_ObjIsConst1(Ivy_Regular(pAnd0)) || Ivy_ObjIsConst1(Ivy_Regular(pAnd1)) ) + pAnd = Ivy_And( p, pAnd0, pAnd1 ); + else + pAnd = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) ); + // return -1 if the node is the same as the original root + if ( Ivy_Regular(pAnd) == pRoot ) + return -1; + } + else + pAnd = NULL; + // count the number of added nodes + if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(p, Ivy_Regular(pAnd)) ) + { + if ( ++Counter > NodeMax ) + return -1; + } + pNode->pFunc = pAnd; + } + return Counter; +} + + +/**Function************************************************************* + + Synopsis [Transforms the decomposition graph into the AIG.] + + Description [AIG nodes for the fanins should be assigned to pNode->pFunc + of the leaves of the graph before calling this procedure.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_GraphToNetworkSeq( Ivy_Man_t * p, Dec_Graph_t * pGraph ) +{ + Ivy_Obj_t * pAnd0, * pAnd1; + Dec_Node_t * pNode; + int i, k; + // check for constant function + if ( Dec_GraphIsConst(pGraph) ) + return Ivy_NotCond( Ivy_ManConst1(p), Dec_GraphIsComplement(pGraph) ); + // check for a literal + if ( Dec_GraphIsVar(pGraph) ) + { + // get the variable node + pNode = Dec_GraphVar(pGraph); + // add the remaining latches + for ( k = 0; k < (int)pNode->nLat2; k++ ) + pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC ); + return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); + } + // build the AIG nodes corresponding to the AND gates of the graph + Dec_GraphForEachNode( pGraph, pNode, i ) + { + pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); + pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); + // add the latches + for ( k = 0; k < (int)pNode->nLat0; k++ ) + pAnd0 = Ivy_Latch( p, pAnd0, IVY_INIT_DC ); + for ( k = 0; k < (int)pNode->nLat1; k++ ) + pAnd1 = Ivy_Latch( p, pAnd1, IVY_INIT_DC ); + // create the node + pNode->pFunc = Ivy_And( p, pAnd0, pAnd1 ); + } + // add the remaining latches + for ( k = 0; k < (int)pNode->nLat2; k++ ) + pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC ); + // complement the result if necessary + return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); +} + +/**Function************************************************************* + + Synopsis [Replaces MFFC of the node by the new factored form.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_GraphUpdateNetworkSeq( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain ) +{ + Ivy_Obj_t * pRootNew; + int nNodesNew, nNodesOld; + nNodesOld = Ivy_ManNodeNum(p); + // create the new structure of nodes + pRootNew = Ivy_GraphToNetworkSeq( p, pGraph ); + Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 0 ); + // compare the gains + nNodesNew = Ivy_ManNodeNum(p); + assert( nGain <= nNodesOld - nNodesNew ); + // propagate the buffer + Ivy_ManPropagateBuffers( p, 0 ); +} + + + + + + + + + +/**Function************************************************************* + + Synopsis [Computes the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Ivy_CutGetTruth_rec( Ivy_Man_t * p, int Leaf, int * pNums, int nNums ) +{ + static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; + unsigned uTruth0, uTruth1; + Ivy_Obj_t * pObj; + int i; + for ( i = 0; i < nNums; i++ ) + if ( Leaf == pNums[i] ) + return uMasks[i]; + pObj = Ivy_ManObj( p, Ivy_LeafId(Leaf) ); + if ( Ivy_ObjIsLatch(pObj) ) + { + assert( !Ivy_ObjFaninC0(pObj) ); + Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) + 1 ); + return Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); + } + assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) ); + Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) ); + uTruth0 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); + if ( Ivy_ObjFaninC0(pObj) ) + uTruth0 = ~uTruth0; + if ( Ivy_ObjIsBuf(pObj) ) + return uTruth0; + Leaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pObj), Ivy_LeafLat(Leaf) ); + uTruth1 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); + if ( Ivy_ObjFaninC1(pObj) ) + uTruth1 = ~uTruth1; + return uTruth0 & uTruth1; +} + + +/**Function************************************************************* + + Synopsis [Computes the truth table.] + Description [] + + SideEffects [] + SeeAlso [] + +***********************************************************************/ +unsigned Ivy_CutGetTruth( Ivy_Man_t * p, Ivy_Obj_t * pObj, int * pNums, int nNums ) +{ + assert( Ivy_ObjIsNode(pObj) ); + assert( nNums < 6 ); + return Ivy_CutGetTruth_rec( p, Ivy_LeafCreate(pObj->Id, 0), pNums, nNums ); +} @@ -50,6 +592,28 @@ static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); } /**Function************************************************************* + Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Ivy_CutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 ) +{ + int i; + if ( pCut->nSize < pCut->nSizeMax ) + return 1; + for ( i = 0; i < pCut->nSize; i++ ) + if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 ) + return 1; + return 0; +} + +/**Function************************************************************* + Synopsis [Derives new cut.] Description [] @@ -59,7 +623,7 @@ static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); } SeeAlso [] ***********************************************************************/ -static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) +static inline int Ivy_CutDeriveNew2( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) { unsigned uHash = 0; int i, k; @@ -126,6 +690,130 @@ static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int I /**Function************************************************************* + Synopsis [Derives new cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) +{ + unsigned uHash = 0; + int i, k; + assert( pCut->nSize > 0 ); + assert( IdNew0 < IdNew1 ); + for ( i = k = 0; i < pCut->nSize; i++ ) + { + if ( pCut->pArray[i] == IdOld ) + continue; + if ( IdNew0 <= pCut->pArray[i] ) + { + if ( IdNew0 < pCut->pArray[i] ) + { + pCutNew->pArray[ k++ ] = IdNew0; + uHash |= Ivy_CutHashValue( IdNew0 ); + } + IdNew0 = 0x7FFFFFFF; + } + if ( IdNew1 <= pCut->pArray[i] ) + { + if ( IdNew1 < pCut->pArray[i] ) + { + pCutNew->pArray[ k++ ] = IdNew1; + uHash |= Ivy_CutHashValue( IdNew1 ); + } + IdNew1 = 0x7FFFFFFF; + } + pCutNew->pArray[ k++ ] = pCut->pArray[i]; + uHash |= Ivy_CutHashValue( pCut->pArray[i] ); + } + if ( IdNew0 < 0x7FFFFFFF ) + { + pCutNew->pArray[ k++ ] = IdNew0; + uHash |= Ivy_CutHashValue( IdNew0 ); + } + if ( IdNew1 < 0x7FFFFFFF ) + { + pCutNew->pArray[ k++ ] = IdNew1; + uHash |= Ivy_CutHashValue( IdNew1 ); + } + pCutNew->nSize = k; + pCutNew->uHash = uHash; + assert( pCutNew->nSize <= pCut->nSizeMax ); +// for ( i = 1; i < pCutNew->nSize; i++ ) +// assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Find the hash value of the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Ivy_NodeCutHash( Ivy_Cut_t * pCut ) +{ + int i; + pCut->uHash = 0; + for ( i = 0; i < pCut->nSize; i++ ) + pCut->uHash |= (1 << (pCut->pArray[i] % 31)); + return pCut->uHash; +} + +/**Function************************************************************* + + Synopsis [Derives new cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Ivy_CutDeriveNew3( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 ) +{ + int i, k; + assert( pCut->nSize > 0 ); + assert( IdNew0 < IdNew1 ); + for ( i = k = 0; i < pCut->nSize; i++ ) + { + if ( pCut->pArray[i] == IdOld ) + continue; + if ( IdNew0 <= pCut->pArray[i] ) + { + if ( IdNew0 < pCut->pArray[i] ) + pCutNew->pArray[ k++ ] = IdNew0; + IdNew0 = 0x7FFFFFFF; + } + if ( IdNew1 <= pCut->pArray[i] ) + { + if ( IdNew1 < pCut->pArray[i] ) + pCutNew->pArray[ k++ ] = IdNew1; + IdNew1 = 0x7FFFFFFF; + } + pCutNew->pArray[ k++ ] = pCut->pArray[i]; + } + if ( IdNew0 < 0x7FFFFFFF ) + pCutNew->pArray[ k++ ] = IdNew0; + if ( IdNew1 < 0x7FFFFFFF ) + pCutNew->pArray[ k++ ] = IdNew1; + pCutNew->nSize = k; + assert( pCutNew->nSize <= pCut->nSizeMax ); + Ivy_NodeCutHash( pCutNew ); + return 1; +} + +/**Function************************************************************* + Synopsis [Returns 1 if pDom is contained in pCut.] Description [] @@ -295,9 +983,12 @@ void Ivy_CutPrintForNodes( Ivy_Store_t * pCutStore ) ***********************************************************************/ static inline int Ivy_CutReadLeaf( Ivy_Obj_t * pFanin ) { + int iLeaf; assert( !Ivy_IsComplement(pFanin) ); if ( !Ivy_ObjIsLatch(pFanin) ) return Ivy_LeafCreate( pFanin->Id, 0 ); + iLeaf = Ivy_CutReadLeaf( Ivy_ObjFanin0(pFanin) ); + assert( Ivy_LeafLat(iLeaf) < IVY_LEAF_MASK ); return 1 + Ivy_CutReadLeaf( Ivy_ObjFanin0(pFanin) ); } @@ -345,13 +1036,20 @@ Ivy_Store_t * Ivy_CutComputeForNode( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeave for ( k = 0; k < pCut->nSize; k++ ) { pLeaf = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[k]) ); - if ( Ivy_ObjIsCi(pLeaf) ) + if ( Ivy_ObjIsCi(pLeaf) || Ivy_ObjIsConst1(pLeaf) ) continue; assert( Ivy_ObjIsNode(pLeaf) ); nLats = Ivy_LeafLat(pCut->pArray[k]); + // get the fanins fanins - iLeaf0 = nLats + Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) ); - iLeaf1 = nLats + Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) ); + iLeaf0 = Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) ); + iLeaf1 = Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) ); + assert( nLats + Ivy_LeafLat(iLeaf0) < IVY_LEAF_MASK && nLats + Ivy_LeafLat(iLeaf1) < IVY_LEAF_MASK ); + iLeaf0 = nLats + iLeaf0; + iLeaf1 = nLats + iLeaf1; + if ( !Ivy_CutPrescreen( pCut, iLeaf0, iLeaf1 ) ) + continue; + // the given cut exist if ( iLeaf0 > iLeaf1 ) Temp = iLeaf0, iLeaf0 = iLeaf1, iLeaf1 = Temp; // create the new cut diff --git a/src/temp/ivy/ivyTable.c b/src/temp/ivy/ivyTable.c index f2617699..fe9c3570 100644 --- a/src/temp/ivy/ivyTable.c +++ b/src/temp/ivy/ivyTable.c @@ -74,8 +74,8 @@ Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj ) return NULL; assert( Ivy_ObjIsLatch(pObj) || Ivy_ObjFaninId0(pObj) > 0 ); assert( Ivy_ObjFaninId1(pObj) == 0 || Ivy_ObjFaninId0(pObj) < Ivy_ObjFaninId1(pObj) ); -// if ( Ivy_ObjFanin0(pObj)->nRefs == 0 || (!Ivy_ObjIsLatch(pObj) && Ivy_ObjFanin1(pObj)->nRefs == 0) ) -// return NULL; + if ( Ivy_ObjFanin0(pObj)->nRefs == 0 || (Ivy_ObjChild1(pObj) && Ivy_ObjFanin1(pObj)->nRefs == 0) ) + return NULL; for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize ) { pEntry = Ivy_ManObj( p, p->pTable[i] ); diff --git a/src/temp/ivy/ivyUtil.c b/src/temp/ivy/ivyUtil.c index 3b77bf41..77a55a39 100644 --- a/src/temp/ivy/ivyUtil.c +++ b/src/temp/ivy/ivyUtil.c @@ -265,7 +265,7 @@ int Ivy_ManLevels( Ivy_Man_t * p ) ***********************************************************************/ int Ivy_ManResetLevels_rec( Ivy_Obj_t * pObj ) { - if ( pObj->Level || Ivy_ObjIsCi(pObj) ) + if ( pObj->Level || Ivy_ObjIsCi(pObj) || Ivy_ObjIsConst1(pObj) ) return pObj->Level; if ( Ivy_ObjIsBuf(pObj) ) return pObj->Level = Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) ); @@ -292,12 +292,81 @@ void Ivy_ManResetLevels( Ivy_Man_t * p ) int i; Ivy_ManForEachObj( p, pObj, i ) pObj->Level = 0; - Ivy_ManForEachPo( p, pObj, i ) + Ivy_ManForEachCo( p, pObj, i ) Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) ); } /**Function************************************************************* + Synopsis [References/references the node and returns MFFC size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ObjRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel ) +{ + Ivy_Obj_t * pNode0, * pNode1; + int Counter; + // label visited nodes + if ( fLabel ) + Ivy_ObjSetTravIdCurrent( p, pNode ); + // skip the CI + if ( Ivy_ObjIsPi(pNode) ) + return 0; + assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) || Ivy_ObjIsLatch(pNode) ); + // process the internal node + pNode0 = Ivy_ObjFanin0(pNode); + pNode1 = Ivy_ObjFanin1(pNode); + Counter = Ivy_ObjIsNode(pNode); + if ( fReference ) + { + if ( pNode0->nRefs++ == 0 ) + Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel ); + if ( pNode1 && pNode1->nRefs++ == 0 ) + Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel ); + } + else + { + assert( pNode0->nRefs > 0 ); + assert( pNode1 == NULL || pNode1->nRefs > 0 ); + if ( --pNode0->nRefs == 0 ) + Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel ); + if ( pNode1 && --pNode1->nRefs == 0 ) + Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel ); + } + return Counter; +} + + +/**Function************************************************************* + + Synopsis [Labels MFFC with the current label.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode ) +{ + int nConeSize1, nConeSize2; + assert( !Ivy_IsComplement( pNode ) ); + assert( Ivy_ObjIsNode( pNode ) ); + nConeSize1 = Ivy_ObjRefDeref( p, pNode, 0, 1 ); // dereference + nConeSize2 = Ivy_ObjRefDeref( p, pNode, 1, 0 ); // reference + assert( nConeSize1 == nConeSize2 ); + assert( nConeSize1 > 0 ); + return nConeSize1; +} + +/**Function************************************************************* + Synopsis [Recursively updates fanout levels.] Description [] diff --git a/src/temp/ivy/module.make b/src/temp/ivy/module.make index a8f6a824..e7ba865a 100644 --- a/src/temp/ivy/module.make +++ b/src/temp/ivy/module.make @@ -5,6 +5,7 @@ SRC += src/temp/ivy/ivyBalance.c \ src/temp/ivy/ivyDfs.c \ src/temp/ivy/ivyDsd.c \ src/temp/ivy/ivyFanout.c \ + src/temp/ivy/ivyIsop.c \ src/temp/ivy/ivyMan.c \ src/temp/ivy/ivyMem.c \ src/temp/ivy/ivyMulti.c \ diff --git a/src/temp/mem/mem.c b/src/temp/mem/mem.c index 26d6485d..15199755 100644 --- a/src/temp/mem/mem.c +++ b/src/temp/mem/mem.c @@ -302,7 +302,7 @@ Mem_Flex_t * Mem_FlexStart() p->pCurrent = NULL; p->pEnd = NULL; - p->nChunkSize = (1 << 12); + p->nChunkSize = (1 << 14); p->nChunksAlloc = 64; p->nChunks = 0; p->pChunks = ALLOC( char *, p->nChunksAlloc ); @@ -390,6 +390,34 @@ char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes ) Synopsis [] + Description [Relocates all the memory except the first chunk.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mem_FlexRestart( Mem_Flex_t * p ) +{ + int i; + if ( p->nChunks == 0 ) + return; + // deallocate all chunks except the first one + for ( i = 1; i < p->nChunks; i++ ) + free( p->pChunks[i] ); + p->nChunks = 1; + p->nMemoryAlloc = p->nChunkSize; + // transform these entries into a linked list + p->pCurrent = p->pChunks[0]; + p->pEnd = p->pCurrent + p->nChunkSize; + p->nEntriesUsed = 0; + p->nMemoryUsed = 0; +} + +/**Function************************************************************* + + Synopsis [] + Description [] SideEffects [] @@ -399,7 +427,7 @@ char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes ) ***********************************************************************/ int Mem_FlexReadMemUsage( Mem_Flex_t * p ) { - return p->nMemoryAlloc; + return p->nMemoryUsed; } diff --git a/src/temp/mem/mem.h b/src/temp/mem/mem.h index 21296d99..611c968d 100644 --- a/src/temp/mem/mem.h +++ b/src/temp/mem/mem.h @@ -49,6 +49,7 @@ extern int Mem_FixedReadMemUsage( Mem_Fixed_t * p ); extern Mem_Flex_t * Mem_FlexStart(); extern void Mem_FlexStop( Mem_Flex_t * p, int fVerbose ); extern char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes ); +extern void Mem_FlexRestart( Mem_Flex_t * p ); extern int Mem_FlexReadMemUsage( Mem_Flex_t * p ); // hierarchical memory manager extern Mem_Step_t * Mem_StepStart( int nSteps ); diff --git a/src/temp/player/module.make b/src/temp/player/module.make index 5185f56e..37e236bb 100644 --- a/src/temp/player/module.make +++ b/src/temp/player/module.make @@ -1,4 +1,5 @@ SRC += src/temp/player/playerToAbc.c \ + src/temp/player/playerFast.c \ src/temp/player/playerCore.c \ src/temp/player/playerMan.c \ src/temp/player/playerUtil.c diff --git a/src/temp/player/player.h b/src/temp/player/player.h index 7f9598d8..b0bb0ec4 100644 --- a/src/temp/player/player.h +++ b/src/temp/player/player.h @@ -86,9 +86,13 @@ static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { //////////////////////////////////////////////////////////////////////// /*=== playerToAbc.c ==============================================================*/ -extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nFaninMax, int fVerbose ); +extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose ); /*=== playerCore.c =============================================================*/ extern Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose ); +/*=== playerFast.c =============================================================*/ +extern void Pla_ManFastLutMap( Ivy_Man_t * pAig, int nLimit ); +extern void Pla_ManFastLutMapStop( Ivy_Man_t * pAig ); +extern void Pla_ManFastLutMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves ); /*=== playerMan.c ==============================================================*/ extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax ); extern void Pla_ManFree( Pla_Man_t * p ); diff --git a/src/temp/player/playerAbc.c b/src/temp/player/playerAbc.c index 8b045d94..8e3823d5 100644 --- a/src/temp/player/playerAbc.c +++ b/src/temp/player/playerAbc.c @@ -45,7 +45,7 @@ static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p ); SeeAlso [] ***********************************************************************/ -void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose ) +void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose ) { int fUseRewriting = 1; Ivy_Man_t * pMan, * pManExt; diff --git a/src/temp/player/playerFast.c b/src/temp/player/playerFast.c new file mode 100644 index 00000000..c8edc1db --- /dev/null +++ b/src/temp/player/playerFast.c @@ -0,0 +1,367 @@ +/**CFile**************************************************************** + + FileName [playerFast.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [Fast 8-LUT mapper.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerFast.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Ivy_SuppMan_t_ Ivy_SuppMan_t; +struct Ivy_SuppMan_t_ +{ + int nLimit; // the limit on the number of inputs + int nObjs; // the number of entries + int nSize; // size of each entry in bytes + char * pMem; // memory allocated +}; + +typedef struct Ivy_Supp_t_ Ivy_Supp_t; +struct Ivy_Supp_t_ +{ + char nSize; // the number of support nodes + char fMark; // the node was processed for area counting + short Delay; // the delay of the node + int pArray[0]; // the support nodes +}; + +static inline Ivy_Supp_t * Ivy_ObjSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + return (Ivy_Supp_t *)(((Ivy_SuppMan_t*)pAig->pData)->pMem + pObj->Id * ((Ivy_SuppMan_t*)pAig->pData)->nSize); +} +static inline Ivy_Supp_t * Ivy_ObjSuppStart( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSupp; + pSupp = Ivy_ObjSupp( pAig, pObj ); + pSupp->fMark = 0; + pSupp->Delay = 0; + pSupp->nSize = 1; + pSupp->pArray[0] = pObj->Id; + return pSupp; +} + +static int Pla_ManFastLutMapDelay( Ivy_Man_t * pAig ); +static int Pla_ManFastLutMapArea( Ivy_Man_t * pAig ); +static void Pla_ManFastLutMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ); +static int Pla_ManFastLutMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs fast K-LUT mapping of the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManFastLutMap( Ivy_Man_t * pAig, int nLimit ) +{ + Ivy_SuppMan_t * pMan; + Ivy_Obj_t * pObj; + int i, Delay, Area; + int clk = clock(), clk2; + // start the memory for supports + pMan = ALLOC( Ivy_SuppMan_t, 1 ); + memset( pMan, 0, sizeof(Ivy_SuppMan_t) ); + pMan->nLimit = nLimit; + pMan->nObjs = Ivy_ManObjIdMax(pAig) + 1; + pMan->nSize = sizeof(Ivy_Supp_t) + nLimit * sizeof(int); + pMan->pMem = (char *)malloc( pMan->nObjs * pMan->nSize ); + pAig->pData = pMan; +clk2 = clock(); + // set the PI mapping + Ivy_ObjSuppStart( pAig, Ivy_ManConst1(pAig) ); + Ivy_ManForEachPi( pAig, pObj, i ) + Ivy_ObjSuppStart( pAig, pObj ); + // iterate through all nodes in the topological order + Ivy_ManForEachNode( pAig, pObj, i ) + Pla_ManFastLutMapNode( pAig, pObj, nLimit ); + // find the best arrival time and area + Delay = Pla_ManFastLutMapDelay( pAig ); + Area = Pla_ManFastLutMapArea( pAig ); +clk2 = clock() - clk2; + // print the report + printf( "LUT levels = %3d. LUT number = %6d. ", Delay, Area ); + PRT( "Mapping time", clk2 ); +// PRT( "Total", clock() - clk ); +// Pla_ManFastLutMapStop( pAig ); +} + +/**Function************************************************************* + + Synopsis [Cleans memory used for decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManFastLutMapStop( Ivy_Man_t * pAig ) +{ + free( ((Ivy_SuppMan_t*)pAig->pData)->pMem ); + free( pAig->pData ); + pAig->pData = NULL; +} + +/**Function************************************************************* + + Synopsis [Computes delay after LUT mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManFastLutMapDelay( Ivy_Man_t * pAig ) +{ + Ivy_Supp_t * pSupp; + Ivy_Obj_t * pObj; + int i, DelayMax = 0; + Ivy_ManForEachPo( pAig, pObj, i ) + { + pObj = Ivy_ObjFanin0(pObj); + if ( !Ivy_ObjIsNode(pObj) ) + continue; + pSupp = Ivy_ObjSupp( pAig, pObj ); + if ( DelayMax < pSupp->Delay ) + DelayMax = pSupp->Delay; + } + return DelayMax; +} + +/**Function************************************************************* + + Synopsis [Computes area after mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManFastLutMapArea_rec( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSupp; + int i, Counter; + pSupp = Ivy_ObjSupp( pAig, pObj ); + // skip visited nodes and PIs + if ( pSupp->fMark || pSupp->nSize == 1 ) + return 0; + pSupp->fMark = 1; + // compute the area of this node + Counter = 0; + for ( i = 0; i < pSupp->nSize; i++ ) + Counter += Pla_ManFastLutMapArea_rec( pAig, Ivy_ManObj(pAig, pSupp->pArray[i]) ); + return 1 + Counter; +} + +/**Function************************************************************* + + Synopsis [Computes area after mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManFastLutMapArea( Ivy_Man_t * pAig ) +{ + Ivy_Obj_t * pObj; + int i, Counter = 0; + Ivy_ManForEachPo( pAig, pObj, i ) + Counter += Pla_ManFastLutMapArea_rec( pAig, Ivy_ObjFanin0(pObj) ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Performs fast mapping for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManFastLutMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ) +{ + Ivy_Supp_t * pSupp0, * pSupp1, * pSupp; + int RetValue; + assert( Ivy_ObjIsNode(pObj) ); + // get the supports + pSupp0 = Ivy_ObjSupp( pAig, Ivy_ObjFanin0(pObj) ); + pSupp1 = Ivy_ObjSupp( pAig, Ivy_ObjFanin1(pObj) ); + pSupp = Ivy_ObjSupp( pAig, pObj ); + pSupp->fMark = 0; + // get the delays + if ( pSupp0->Delay == pSupp1->Delay ) + pSupp->Delay = (pSupp0->Delay == 0) ? pSupp0->Delay + 1: pSupp0->Delay; + else if ( pSupp0->Delay > pSupp1->Delay ) + { + pSupp->Delay = pSupp0->Delay; + pSupp1 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); + pSupp1->pArray[0] = Ivy_ObjFaninId1(pObj); + } + else // if ( pSupp0->Delay < pSupp1->Delay ) + { + pSupp->Delay = pSupp1->Delay; + pSupp0 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); + pSupp0->pArray[0] = Ivy_ObjFaninId0(pObj); + } + // merge the cuts + if ( pSupp0->nSize < pSupp1->nSize ) + RetValue = Pla_ManFastLutMapMerge( pSupp1, pSupp0, pSupp, nLimit ); + else + RetValue = Pla_ManFastLutMapMerge( pSupp0, pSupp1, pSupp, nLimit ); + if ( !RetValue ) + { + pSupp->Delay++; + pSupp->nSize = 2; + pSupp->pArray[0] = Ivy_ObjFaninId0(pObj); + pSupp->pArray[1] = Ivy_ObjFaninId1(pObj); + } + assert( pSupp->Delay > 0 ); +} + +/**Function************************************************************* + + Synopsis [Merges two supports] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManFastLutMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit ) +{ + int i, k, c; + assert( pSupp0->nSize >= pSupp1->nSize ); + // the case of the largest cut sizes + if ( pSupp0->nSize == nLimit && pSupp1->nSize == nLimit ) + { + for ( i = 0; i < pSupp0->nSize; i++ ) + if ( pSupp0->pArray[i] != pSupp1->pArray[i] ) + return 0; + for ( i = 0; i < pSupp0->nSize; i++ ) + pSupp->pArray[i] = pSupp0->pArray[i]; + pSupp->nSize = pSupp0->nSize; + return 1; + } + // the case when one of the cuts is the largest + if ( pSupp0->nSize == nLimit ) + { + for ( i = 0; i < pSupp1->nSize; i++ ) + { + for ( k = pSupp0->nSize - 1; k >= 0; k-- ) + if ( pSupp0->pArray[k] == pSupp1->pArray[i] ) + break; + if ( k == -1 ) // did not find + return 0; + } + for ( i = 0; i < pSupp0->nSize; i++ ) + pSupp->pArray[i] = pSupp0->pArray[i]; + pSupp->nSize = pSupp0->nSize; + return 1; + } + + // compare two cuts with different numbers + i = k = 0; + for ( c = 0; c < nLimit; c++ ) + { + if ( k == pSupp1->nSize ) + { + if ( i == pSupp0->nSize ) + { + pSupp->nSize = c; + return 1; + } + pSupp->pArray[c] = pSupp0->pArray[i++]; + continue; + } + if ( i == pSupp0->nSize ) + { + if ( k == pSupp1->nSize ) + { + pSupp->nSize = c; + return 1; + } + pSupp->pArray[c] = pSupp1->pArray[k++]; + continue; + } + if ( pSupp0->pArray[i] < pSupp1->pArray[k] ) + { + pSupp->pArray[c] = pSupp0->pArray[i++]; + continue; + } + if ( pSupp0->pArray[i] > pSupp1->pArray[k] ) + { + pSupp->pArray[c] = pSupp1->pArray[k++]; + continue; + } + pSupp->pArray[c] = pSupp0->pArray[i++]; + k++; + } + if ( i < pSupp0->nSize || k < pSupp1->nSize ) + return 0; + pSupp->nSize = c; + return 1; +} + +/**Function************************************************************* + + Synopsis [Creates integer vector with the support of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManFastLutMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves ) +{ + Ivy_Supp_t * pSupp; + pSupp = Ivy_ObjSupp( pAig, pObj ); + vLeaves->nCap = 8; + vLeaves->nSize = pSupp->nSize; + vLeaves->pArray = pSupp->pArray; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerToAbc.c b/src/temp/player/playerToAbc.c index 09bf5088..fc5e01ea 100644 --- a/src/temp/player/playerToAbc.c +++ b/src/temp/player/playerToAbc.c @@ -26,9 +26,11 @@ //////////////////////////////////////////////////////////////////////// static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p ); -static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p ); +static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode ); static Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp ); +static Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp ); static Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp ); +static int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose ); static inline void Abc_ObjSetIvy2Abc( Ivy_Man_t * p, int IvyId, Abc_Obj_t * pObjAbc ) { assert(Vec_PtrEntry(p->pCopy, IvyId) == NULL); assert(!Abc_ObjIsComplement(pObjAbc)); Vec_PtrWriteEntry( p->pCopy, IvyId, pObjAbc ); } static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId ) { return Vec_PtrEntry( p->pCopy, IvyId ); } @@ -39,7 +41,7 @@ static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId ) /**Function************************************************************* - Synopsis [Gives the current ABC network to PLAyer for processing.] + Synopsis [Applies PLA/LUT mapping to the ABC network.] Description [] @@ -48,12 +50,12 @@ static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId ) SeeAlso [] ***********************************************************************/ -void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose ) +void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose ) { - int fUseRewriting = 1; + int fUseRewriting = 0; Pla_Man_t * p; Ivy_Man_t * pMan, * pManExt; - Abc_Ntk_t * pNtkAig; + Abc_Ntk_t * pNtkNew; if ( !Abc_NtkIsStrash(pNtk) ) return NULL; // convert to the new AIG manager @@ -75,20 +77,33 @@ void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose ) if ( fVerbose ) Ivy_ManPrintStats( pMan ); } - // perform decomposition/mapping into PLAs/LUTs - p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose ); - // convert from the extended AIG manager into an SOP network - pNtkAig = Ivy_ManToAbc( pNtk, pMan, p ); - Pla_ManFree( p ); + // perform decomposition + if ( fFastMode ) + { + // perform mapping into LUTs + Pla_ManFastLutMap( pMan, nLutMax ); + // convert from the extended AIG manager into an SOP network + pNtkNew = Ivy_ManToAbc( pNtk, pMan, NULL, fFastMode ); + Pla_ManFastLutMapStop( pMan ); + } + else + { + // perform decomposition/mapping into PLAs/LUTs + p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose ); + // convert from the extended AIG manager into an SOP network + pNtkNew = Ivy_ManToAbc( pNtk, pMan, p, fFastMode ); + Pla_ManFree( p ); + } Ivy_ManStop( pMan ); // chech the resulting network - if ( !Abc_NtkCheck( pNtkAig ) ) + if ( !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkPlayer: The network check has failed.\n" ); - Abc_NtkDelete( pNtkAig ); + Abc_NtkDelete( pNtkNew ); return NULL; } - return pNtkAig; + Abc_NtkPlayerCost( pNtkNew, RankCost, fVerbose ); + return pNtkNew; } /**Function************************************************************* @@ -134,7 +149,7 @@ Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p ) +Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode ) { Abc_Ntk_t * pNtkNew; Abc_Obj_t * pObjAbc, * pObj; @@ -155,7 +170,11 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p ) Ivy_ManForEachPo( pMan, pObjIvy, i ) { // get the new ABC node corresponding to the old fanin of the PO in IVY - pObjAbc = Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp ); + if ( fFastMode ) + pObjAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp ); + else + pObjAbc = Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp ); + // consider the case of complemented fanin of the PO if ( Ivy_ObjFaninC0(pObjIvy) ) // complement { if ( Abc_ObjIsCi(pObjAbc) ) @@ -236,17 +255,20 @@ Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * Abc_ObjAddFanin( pObjAbc, Abc_ObjGetIvy2Abc(pMan, Entry) ); // check if the truth table is constant 0 puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp ); - for ( i = 0; i < 8; i++ ) - if ( puTruth[i] ) - break; - // create constant 0 node - if ( i == 8 ) + // if the function is constant 0, create constant 0 node + if ( Extra_TruthIsConst0(puTruth, 8) ) { pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL ); pObjAbc = Abc_NodeCreateConst0( pNtkNew ); } else - pObjAbc->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, Vec_IntSize(vSupp), puTruth ); + { + int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes ); + pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes ); + if ( fCompl ) Abc_SopComplement(pObjAbc->pData); +// printf( "Cover contains %d cubes.\n", Vec_IntSize(vNodes) ); +// pObjAbc->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, Vec_IntSize(vSupp), puTruth ); + } } else { @@ -309,6 +331,149 @@ Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * } + + +/**Function************************************************************* + + Synopsis [Recursively construct the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp ) +{ + Vec_Int_t Supp, * vSupp = &Supp; + Abc_Obj_t * pObjAbc, * pFaninAbc; + int i, Entry; + unsigned * puTruth; + // skip the node if it is a constant or already processed + pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id ); + if ( pObjAbc ) + return pObjAbc; + assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) ); + // get the support of K-LUT + Pla_ManFastLutMapReadSupp( pMan, pObjIvy, vSupp ); + // create new ABC node and its fanins + pObjAbc = Abc_NtkCreateNode( pNtkNew ); + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFaninAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ManObj(pMan, Entry), vNodes, vTemp ); + Abc_ObjAddFanin( pObjAbc, pFaninAbc ); + } + // check if the truth table is constant 0 + puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp ); + // if the function is constant 0, create constant 0 node + if ( Extra_TruthIsConst0(puTruth, 8) ) + { + pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL ); + pObjAbc = Abc_NodeCreateConst0( pNtkNew ); + } + else + { + int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes ); + pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes ); + if ( fCompl ) Abc_SopComplement(pObjAbc->pData); + } + Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc ); + return pObjAbc; +} + + +/**Function************************************************************* + + Synopsis [Computes cost of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_NodePlayerCost( int nFanins ) +{ + if ( nFanins <= 4 ) + return 1; + if ( nFanins <= 6 ) + return 2; + if ( nFanins <= 8 ) + return 4; + if ( nFanins <= 16 ) + return 8; + if ( nFanins <= 32 ) + return 16; + if ( nFanins <= 64 ) + return 32; + if ( nFanins <= 128 ) + return 64; + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Computes the number of ranks needed for one level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_NtkPlayerCostOne( int nCost, int RankCost ) +{ + return (nCost / RankCost) + ((nCost % RankCost) > 0); +} + +/**Function************************************************************* + + Synopsis [Computes the cost function for the network (number of ranks).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose ) +{ + Abc_Obj_t * pObj; + int nFanins, nLevels, * pLevelCosts, CostTotal, nRanksTotal, i; + // compute the costs for each level + nLevels = Abc_NtkGetLevelNum( pNtk ); + pLevelCosts = ALLOC( int, nLevels + 1 ); + memset( pLevelCosts, 0, sizeof(int) * (nLevels + 1) ); + Abc_NtkForEachNode( pNtk, pObj, i ) + { + nFanins = Abc_ObjFaninNum(pObj); + if ( nFanins == 0 ) + continue; + pLevelCosts[ pObj->Level ] += Abc_NodePlayerCost( nFanins ); + } + // compute the total cost + CostTotal = nRanksTotal = 0; + for ( i = 1; i <= nLevels; i++ ) + { + CostTotal += pLevelCosts[i]; + nRanksTotal += Abc_NtkPlayerCostOne( pLevelCosts[i], RankCost ); + } + // print out statistics + if ( fVerbose ) + { + for ( i = 1; i <= nLevels; i++ ) + printf( "Level %2d : Cost = %6d. Ranks = %6.3f.\n", i, pLevelCosts[i], ((double)pLevelCosts[i])/RankCost ); + printf( "TOTAL : Cost = %6d. Ranks = %3d.\n", CostTotal, nRanksTotal ); + } + return nRanksTotal; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/temp/rwt/rwt.h b/src/temp/rwt/rwt.h index f9c4dc51..8f24842b 100644 --- a/src/temp/rwt/rwt.h +++ b/src/temp/rwt/rwt.h @@ -70,7 +70,9 @@ struct Rwt_Man_t_ int nClasses; // the number of NN classes // the result of resynthesis int fCompl; // indicates if the output of FF should be complemented + void * pCut; // the decomposition tree (temporary) void * pGraph; // the decomposition tree (temporary) + char * pPerm; // permutation used for the best cut Vec_Ptr_t * vFanins; // the fanins array (temporary) Vec_Ptr_t * vFaninsCur; // the fanins array (temporary) Vec_Int_t * vLevNums; // the array of levels (temporary) diff --git a/src/temp/rwt/rwtMan.c b/src/temp/rwt/rwtMan.c index f7dd38a7..869043a4 100644 --- a/src/temp/rwt/rwtMan.c +++ b/src/temp/rwt/rwtMan.c @@ -200,7 +200,7 @@ void Rwt_ManPrintStats( Rwt_Man_t * p ) PRT( "Update ", p->timeUpdate ); PRT( "TOTAL ", p->timeTotal ); - +/* printf( "The scores are:\n" ); for ( i = 0; i < 222; i++ ) if ( p->nScores[i] > 0 ) @@ -210,7 +210,7 @@ void Rwt_ManPrintStats( Rwt_Man_t * p ) Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[i] | ((unsigned)p->pMapInv[i] << 16) ); } printf( "\n" ); - +*/ } /**Function************************************************************* diff --git a/src/temp/xyz/module.make b/src/temp/xyz/module.make deleted file mode 100644 index f84fa8cc..00000000 --- a/src/temp/xyz/module.make +++ /dev/null @@ -1,8 +0,0 @@ -SRC += src/temp/xyz/xyzBuild.c \ - src/temp/xyz/xyzCore.c \ - src/temp/xyz/xyzMan.c \ - src/temp/xyz/xyzMinEsop.c \ - src/temp/xyz/xyzMinMan.c \ - src/temp/xyz/xyzMinSop.c \ - src/temp/xyz/xyzMinUtil.c \ - src/temp/xyz/xyzTest.c diff --git a/src/temp/xyz/xyz.h b/src/temp/xyz/xyz.h deleted file mode 100644 index 4fec2150..00000000 --- a/src/temp/xyz/xyz.h +++ /dev/null @@ -1,110 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyz.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyz.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __XYZ_H__ -#define __XYZ_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "abc.h" -#include "xyzInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Xyz_Man_t_ Xyz_Man_t; -typedef struct Xyz_Obj_t_ Xyz_Obj_t; - -// storage for node information -struct Xyz_Obj_t_ -{ - Min_Cube_t * pCover[3]; // pos/neg/esop - Vec_Int_t * vSupp; // computed support (all nodes except CIs) -}; - -// storage for additional information -struct Xyz_Man_t_ -{ - // general characteristics - int nFaninMax; // the number of vars - int nCubesMax; // the limit on the number of cubes in the intermediate covers - int nWords; // the number of words - Vec_Int_t * vFanCounts; // fanout counts - Vec_Ptr_t * vObjStrs; // object structures - void * pMemory; // memory for the internal data strctures - Min_Man_t * pManMin; // the cub manager - int fUseEsop; // enables ESOPs - int fUseSop; // enables SOPs - // arrays to map local variables - Vec_Int_t * vComTo0; // mapping of common variables into first fanin - Vec_Int_t * vComTo1; // mapping of common variables into second fanin - Vec_Int_t * vPairs0; // the first var in each pair of common vars - Vec_Int_t * vPairs1; // the second var in each pair of common vars - Vec_Int_t * vTriv0; // trival support of the first node - Vec_Int_t * vTriv1; // trival support of the second node - // statistics - int nSupps; // supports created - int nSuppsMax; // the maximum number of supports - int nBoundary; // the boundary size - int nNodes; // the number of nodes processed -}; - -static inline Xyz_Obj_t * Abc_ObjGetStr( Abc_Obj_t * pObj ) { return Vec_PtrEntry(((Xyz_Man_t *)pObj->pNtk->pManCut)->vObjStrs, pObj->Id); } - -static inline void Abc_ObjSetSupp( Abc_Obj_t * pObj, Vec_Int_t * vVec ) { Abc_ObjGetStr(pObj)->vSupp = vVec; } -static inline Vec_Int_t * Abc_ObjGetSupp( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->vSupp; } - -static inline void Abc_ObjSetCover2( Abc_Obj_t * pObj, Min_Cube_t * pCov ) { Abc_ObjGetStr(pObj)->pCover[2] = pCov; } -static inline Min_Cube_t * Abc_ObjGetCover2( Abc_Obj_t * pObj ) { return Abc_ObjGetStr(pObj)->pCover[2]; } - -static inline void Abc_ObjSetCover( Abc_Obj_t * pObj, Min_Cube_t * pCov, int Pol ) { Abc_ObjGetStr(pObj)->pCover[Pol] = pCov; } -static inline Min_Cube_t * Abc_ObjGetCover( Abc_Obj_t * pObj, int Pol ) { return Abc_ObjGetStr(pObj)->pCover[Pol]; } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== xyzBuild.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk ); -/*=== xyzCore.c ===========================================================*/ -extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); -/*=== xyzMan.c ============================================================*/ -extern Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax ); -extern void Xyz_ManFree( Xyz_Man_t * p ); -extern void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj ); -/*=== xyzTest.c ===========================================================*/ -extern Abc_Ntk_t * Abc_NtkXyzTestSop( Abc_Ntk_t * pNtk ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - - diff --git a/src/temp/xyz/xyzBuild.c b/src/temp/xyz/xyzBuild.c deleted file mode 100644 index e32721e7..00000000 --- a/src/temp/xyz/xyzBuild.c +++ /dev/null @@ -1,379 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzBuild.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Network construction procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzBuild.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyz.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveCube( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp ) -{ - Vec_Int_t * vLits; - Abc_Obj_t * pNodeNew, * pFanin; - int i, iFanin, Lit; - // create empty cube - if ( pCube->nLits == 0 ) - return Abc_NodeCreateConst1(pNtkNew); - // get the literals of this cube - vLits = Vec_IntAlloc( 10 ); - Min_CubeGetLits( pCube, vLits ); - assert( pCube->nLits == (unsigned)vLits->nSize ); - // create special case when there is only one literal - if ( pCube->nLits == 1 ) - { - iFanin = Vec_IntEntry(vLits,0); - pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); - Lit = Min_CubeGetVar(pCube, iFanin); - assert( Lit == 1 || Lit == 2 ); - Vec_IntFree( vLits ); - if ( Lit == 1 )// negative - return Abc_NodeCreateInv( pNtkNew, pFanin->pCopy ); - return pFanin->pCopy; - } - assert( pCube->nLits > 1 ); - // create the AND cube - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - for ( i = 0; i < vLits->nSize; i++ ) - { - iFanin = Vec_IntEntry(vLits,i); - pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); - Lit = Min_CubeGetVar(pCube, iFanin); - assert( Lit == 1 || Lit == 2 ); - Vec_IntWriteEntry( vLits, i, Lit==1 ); - Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); - } - pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); - Vec_IntFree( vLits ); - return pNodeNew; -} - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveNode_rec( Xyz_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int Level ) -{ - Min_Cube_t * pCover, * pCube; - Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin; - Vec_Int_t * vSupp; - int Entry, nCubes, i; - - if ( Abc_ObjIsCi(pObj) ) - return pObj->pCopy; - assert( Abc_ObjIsNode(pObj) ); - // skip if already computed - if ( pObj->pCopy ) - return pObj->pCopy; - - // get the support and the cover - vSupp = Abc_ObjGetSupp( pObj ); - pCover = Abc_ObjGetCover2( pObj ); - assert( vSupp ); -/* - if ( pCover && pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) > 0 ) - { - printf( "%d\n ", pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) ); - Min_CoverWrite( stdout, pCover ); - } -*/ -/* - // print the support of this node - printf( "{ " ); - Vec_IntForEachEntry( vSupp, Entry, i ) - printf( "%d ", Entry ); - printf( "} cubes = %d\n", Min_CoverCountCubes( pCover ) ); -*/ - // process the fanins - Vec_IntForEachEntry( vSupp, Entry, i ) - { - pFanin = Abc_NtkObj(pObj->pNtk, Entry); - Abc_NtkXyzDeriveNode_rec( p, pNtkNew, pFanin, Level+1 ); - } - - // for each cube, construct the node - nCubes = Min_CoverCountCubes( pCover ); - if ( nCubes == 0 ) - pNodeNew = Abc_NodeCreateConst0(pNtkNew); - else if ( nCubes == 1 ) - pNodeNew = Abc_NtkXyzDeriveCube( pNtkNew, pObj, pCover, vSupp ); - else - { - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - Min_CoverForEachCube( pCover, pCube ) - { - pFaninNew = Abc_NtkXyzDeriveCube( pNtkNew, pObj, pCube, vSupp ); - Abc_ObjAddFanin( pNodeNew, pFaninNew ); - } - pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes ); - } -/* - printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level ); - Vec_IntForEachEntry( vSupp, Entry, i ) - { - pFanin = Abc_NtkObj(pObj->pNtk, Entry); - printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id ); - } - printf( "\n" ); - Min_CoverWrite( stdout, pCover ); -*/ - pObj->pCopy = pNodeNew; - return pNodeNew; -} - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkXyzDerive( Xyz_Man_t * p, Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj; - int i; - assert( Abc_NtkIsStrash(pNtk) ); - // perform strashing - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); - // reconstruct the network - Abc_NtkForEachCo( pNtk, pObj, i ) - { - Abc_NtkXyzDeriveNode_rec( p, pNtkNew, Abc_ObjFanin0(pObj), 0 ); -// printf( "*** CO %s : %d -> %d \n", Abc_ObjName(pObj), pObj->pCopy->Id, Abc_ObjFanin0(pObj)->pCopy->Id ); - } - // add the COs - Abc_NtkFinalize( pNtk, pNtkNew ); - Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); - // make sure everything is okay - if ( !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkXyzDerive: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - - - - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl ) -{ - assert( pObj->pCopy ); - if ( !fCompl ) - return pObj->pCopy; - if ( pObj->pCopy->pCopy == NULL ) - pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy ); - return pObj->pCopy->pCopy; - } - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveCubeInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp ) -{ - Vec_Int_t * vLits; - Abc_Obj_t * pNodeNew, * pFanin; - int i, iFanin, Lit; - // create empty cube - if ( pCube->nLits == 0 ) - return Abc_NodeCreateConst1(pNtkNew); - // get the literals of this cube - vLits = Vec_IntAlloc( 10 ); - Min_CubeGetLits( pCube, vLits ); - assert( pCube->nLits == (unsigned)vLits->nSize ); - // create special case when there is only one literal - if ( pCube->nLits == 1 ) - { - iFanin = Vec_IntEntry(vLits,0); - pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); - Lit = Min_CubeGetVar(pCube, iFanin); - assert( Lit == 1 || Lit == 2 ); - Vec_IntFree( vLits ); -// if ( Lit == 1 )// negative -// return Abc_NodeCreateInv( pNtkNew, pFanin->pCopy ); -// return pFanin->pCopy; - return Abc_NtkXyzDeriveInv( pNtkNew, pFanin, Lit==1 ); - } - assert( pCube->nLits > 1 ); - // create the AND cube - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - for ( i = 0; i < vLits->nSize; i++ ) - { - iFanin = Vec_IntEntry(vLits,i); - pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); - Lit = Min_CubeGetVar(pCube, iFanin); - assert( Lit == 1 || Lit == 2 ); - Vec_IntWriteEntry( vLits, i, Lit==1 ); -// Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); - Abc_ObjAddFanin( pNodeNew, Abc_NtkXyzDeriveInv( pNtkNew, pFanin, Lit==1 ) ); - } -// pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); - pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, NULL ); - Vec_IntFree( vLits ); - return pNodeNew; -} - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkXyzDeriveNodeInv_rec( Xyz_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl ) -{ - Min_Cube_t * pCover, * pCube; - Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin; - Vec_Int_t * vSupp; - int Entry, nCubes, i; - - // skip if already computed - if ( pObj->pCopy ) - return Abc_NtkXyzDeriveInv( pNtkNew, pObj, fCompl ); - assert( Abc_ObjIsNode(pObj) ); - - // get the support and the cover - vSupp = Abc_ObjGetSupp( pObj ); - pCover = Abc_ObjGetCover2( pObj ); - assert( vSupp ); - - // process the fanins - Vec_IntForEachEntry( vSupp, Entry, i ) - { - pFanin = Abc_NtkObj(pObj->pNtk, Entry); - Abc_NtkXyzDeriveNodeInv_rec( p, pNtkNew, pFanin, 0 ); - } - - // for each cube, construct the node - nCubes = Min_CoverCountCubes( pCover ); - if ( nCubes == 0 ) - pNodeNew = Abc_NodeCreateConst0(pNtkNew); - else if ( nCubes == 1 ) - pNodeNew = Abc_NtkXyzDeriveCubeInv( pNtkNew, pObj, pCover, vSupp ); - else - { - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - Min_CoverForEachCube( pCover, pCube ) - { - pFaninNew = Abc_NtkXyzDeriveCubeInv( pNtkNew, pObj, pCube, vSupp ); - Abc_ObjAddFanin( pNodeNew, pFaninNew ); - } - pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes ); - } - - pObj->pCopy = pNodeNew; - return Abc_NtkXyzDeriveInv( pNtkNew, pObj, fCompl ); -} - -/**Function************************************************************* - - Synopsis [Derives the decomposed network.] - - Description [The resulting network contains only pure AND/OR/EXOR gates - and inverters. This procedure is usedful to generate Verilog.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkXyzDeriveClean( Xyz_Man_t * p, Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pNodeNew; - int i; - assert( Abc_NtkIsStrash(pNtk) ); - // perform strashing - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); - // reconstruct the network - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pNodeNew = Abc_NtkXyzDeriveNodeInv_rec( p, pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) ); - Abc_ObjAddFanin( pObj->pCopy, pNodeNew ); - } - // add the COs - Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); - // make sure everything is okay - if ( !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkXyzDeriveInv: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/xyz/xyzCore.c b/src/temp/xyz/xyzCore.c deleted file mode 100644 index e5089788..00000000 --- a/src/temp/xyz/xyzCore.c +++ /dev/null @@ -1,1025 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzCore.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Core procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyz.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NtkXyzCovers( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ); -static int Abc_NtkXyzCoversOne( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ); -static void Abc_NtkXyzCovers_rec( Xyz_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary ); -/* -static int Abc_NodeXyzPropagateEsop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ); -static int Abc_NodeXyzPropagateSop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ); -static int Abc_NodeXyzUnionEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); -static int Abc_NodeXyzUnionSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); -static int Abc_NodeXyzProductEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); -static int Abc_NodeXyzProductSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); -*/ - -static int Abc_NodeXyzPropagate( Xyz_Man_t * p, Abc_Obj_t * pObj ); -static Min_Cube_t * Abc_NodeXyzProduct( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ); -static Min_Cube_t * Abc_NodeXyzSum( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ); - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs decomposition.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ) -{ - Abc_Ntk_t * pNtkNew; - Xyz_Man_t * p; - - assert( Abc_NtkIsStrash(pNtk) ); - - // create the manager - p = Xyz_ManAlloc( pNtk, nFaninMax ); - p->fUseEsop = fUseEsop; - p->fUseSop = 1;//fUseSop; - pNtk->pManCut = p; - - // perform mapping - Abc_NtkXyzCovers( p, pNtk, fVerbose ); - - // derive the final network - if ( fUseInvs ) - pNtkNew = Abc_NtkXyzDeriveClean( p, pNtk ); - else - pNtkNew = Abc_NtkXyzDerive( p, pNtk ); -// pNtkNew = NULL; - - - Xyz_ManFree( p ); - pNtk->pManCut = NULL; - - // make sure that everything is okay - if ( pNtkNew && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkXyz: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Compute the supports.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkXyzCovers( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ) -{ - Abc_Obj_t * pObj; - int i, clk = clock(); - - // start the manager - p->vFanCounts = Abc_NtkFanoutCounts(pNtk); - - // set trivial cuts for the constant and the CIs - pObj = Abc_NtkConst1(pNtk); - pObj->fMarkA = 1; - Abc_NtkForEachCi( pNtk, pObj, i ) - pObj->fMarkA = 1; - - // perform iterative decomposition - for ( i = 0; ; i++ ) - { - if ( fVerbose ) - printf( "Iter %d : ", i+1 ); - if ( Abc_NtkXyzCoversOne(p, pNtk, fVerbose) ) - break; - } - - // clean the cut-point markers - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->fMarkA = 0; - -if ( fVerbose ) -{ -PRT( "Total", clock() - clk ); -} -} - -/**Function************************************************************* - - Synopsis [Compute the supports.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkXyzCoversOne( Xyz_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ) -{ - ProgressBar * pProgress; - Abc_Obj_t * pObj; - Vec_Ptr_t * vBoundary; - int i, clk = clock(); - int Counter = 0; - int fStop = 1; - - // array to collect the nodes in the new boundary - vBoundary = Vec_PtrAlloc( 100 ); - - // start from the COs and mark visited nodes using pObj->fMarkB - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // skip the solved nodes (including the CIs) - pObj = Abc_ObjFanin0(pObj); - if ( pObj->fMarkA ) - { - Counter++; - continue; - } - - // traverse the cone starting from this node - if ( Abc_ObjGetSupp(pObj) == NULL ) - Abc_NtkXyzCovers_rec( p, pObj, vBoundary ); - - // count the number of solved cones - if ( Abc_ObjGetSupp(pObj) == NULL ) - fStop = 0; - else - Counter++; - -/* - printf( "%-15s : ", Abc_ObjName(pObj) ); - printf( "lev = %5d ", pObj->Level ); - if ( Abc_ObjGetSupp(pObj) == NULL ) - { - printf( "\n" ); - continue; - } - printf( "supp = %3d ", Abc_ObjGetSupp(pObj)->nSize ); - printf( "esop = %3d ", Min_CoverCountCubes( Abc_ObjGetCover2(pObj) ) ); - printf( "\n" ); -*/ - } - Extra_ProgressBarStop( pProgress ); - - // clean visited nodes - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->fMarkB = 0; - - // create the new boundary - p->nBoundary = 0; - Vec_PtrForEachEntry( vBoundary, pObj, i ) - { - if ( !pObj->fMarkA ) - { - pObj->fMarkA = 1; - p->nBoundary++; - } - } - Vec_PtrFree( vBoundary ); - -if ( fVerbose ) -{ - printf( "Outs = %4d (%4d) Node = %6d (%6d) Max = %6d Bound = %4d ", - Counter, Abc_NtkCoNum(pNtk), p->nSupps, Abc_NtkNodeNum(pNtk), p->nSuppsMax, p->nBoundary ); -PRT( "T", clock() - clk ); -} - return fStop; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkXyzCovers_rec( Xyz_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary ) -{ - Abc_Obj_t * pObj0, * pObj1; - // return if the support is already computed - if ( pObj->fMarkB || pObj->fMarkA )//|| Abc_ObjGetSupp(pObj) ) // why do we need Supp check here??? - return; - // mark as visited - pObj->fMarkB = 1; - // get the fanins - pObj0 = Abc_ObjFanin0(pObj); - pObj1 = Abc_ObjFanin1(pObj); - // solve for the fanins - Abc_NtkXyzCovers_rec( p, pObj0, vBoundary ); - Abc_NtkXyzCovers_rec( p, pObj1, vBoundary ); - // skip the node that spaced out - if ( !pObj0->fMarkA && !Abc_ObjGetSupp(pObj0) || // fanin is not ready - !pObj1->fMarkA && !Abc_ObjGetSupp(pObj1) || // fanin is not ready - !Abc_NodeXyzPropagate( p, pObj ) ) // node's support or covers cannot be computed - { - // save the nodes of the future boundary - if ( !pObj0->fMarkA && Abc_ObjGetSupp(pObj0) ) - Vec_PtrPush( vBoundary, pObj0 ); - if ( !pObj1->fMarkA && Abc_ObjGetSupp(pObj1) ) - Vec_PtrPush( vBoundary, pObj1 ); - return; - } - // consider dropping the fanin supports -// Abc_NodeXyzDropData( p, pObj0 ); -// Abc_NodeXyzDropData( p, pObj1 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NodeXyzSupport( Xyz_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1 ) -{ - Vec_Int_t * vSupp; - int k0, k1; - - assert( vSupp0 && vSupp1 ); - Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 ); - Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 ); - Vec_IntClear( p->vPairs0 ); - Vec_IntClear( p->vPairs1 ); - - vSupp = Vec_IntAlloc( vSupp0->nSize + vSupp1->nSize ); - for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; ) - { - if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] ) - { - Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); - Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); - Vec_IntPush( p->vPairs0, k0 ); - Vec_IntPush( p->vPairs1, k1 ); - Vec_IntPush( vSupp, vSupp0->pArray[k0] ); - k0++; k1++; - } - else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] ) - { - Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); - Vec_IntPush( vSupp, vSupp0->pArray[k0] ); - k0++; - } - else - { - Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); - Vec_IntPush( vSupp, vSupp1->pArray[k1] ); - k1++; - } - } - for ( ; k0 < vSupp0->nSize; k0++ ) - { - Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); - Vec_IntPush( vSupp, vSupp0->pArray[k0] ); - } - for ( ; k1 < vSupp1->nSize; k1++ ) - { - Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); - Vec_IntPush( vSupp, vSupp1->pArray[k1] ); - } -/* - printf( "Zero : " ); - for ( k0 = 0; k0 < vSupp0->nSize; k0++ ) - printf( "%d ", vSupp0->pArray[k0] ); - printf( "\n" ); - - printf( "One : " ); - for ( k1 = 0; k1 < vSupp1->nSize; k1++ ) - printf( "%d ", vSupp1->pArray[k1] ); - printf( "\n" ); - - printf( "Sum : " ); - for ( k0 = 0; k0 < vSupp->nSize; k0++ ) - printf( "%d ", vSupp->pArray[k0] ); - printf( "\n" ); - printf( "\n" ); -*/ - return vSupp; -} - -/**Function************************************************************* - - Synopsis [Propagates all types of covers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzPropagate( Xyz_Man_t * p, Abc_Obj_t * pObj ) -{ - Min_Cube_t * pCoverP = NULL, * pCoverN = NULL, * pCoverX = NULL; - Min_Cube_t * pCov0, * pCov1, * pCover0, * pCover1; - Vec_Int_t * vSupp, * vSupp0, * vSupp1; - Abc_Obj_t * pObj0, * pObj1; - int fCompl0, fCompl1; - - pObj0 = Abc_ObjFanin0( pObj ); - pObj1 = Abc_ObjFanin1( pObj ); - - if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); - if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); - - // get the resulting support - vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); - vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); - vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 ); - - // quit if support if too large - if ( vSupp->nSize > p->nFaninMax ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // get the complemented attributes - fCompl0 = Abc_ObjFaninC0( pObj ); - fCompl1 = Abc_ObjFaninC1( pObj ); - - // propagate ESOP - if ( p->fUseEsop ) - { - // get the covers - pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0); - pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1); - if ( pCov0 && pCov1 ) - { - // complement the first if needed - if ( !fCompl0 ) - pCover0 = pCov0; - else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube - pCover0 = pCov0->pNext; - else - pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0; - - // complement the second if needed - if ( !fCompl1 ) - pCover1 = pCov1; - else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube - pCover1 = pCov1->pNext; - else - pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1; - - // derive the new cover - pCoverX = Abc_NodeXyzProduct( p, pCover0, pCover1, 1, vSupp->nSize ); - } - } - // propagate SOPs - if ( p->fUseSop ) - { - // get the covers for the direct polarity - pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0); - pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1); - // derive the new cover - if ( pCover0 && pCover1 ) - pCoverP = Abc_NodeXyzProduct( p, pCover0, pCover1, 0, vSupp->nSize ); - - // get the covers for the inverse polarity - pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0); - pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1); - // derive the new cover - if ( pCover0 && pCover1 ) - pCoverN = Abc_NodeXyzSum( p, pCover0, pCover1, 0, vSupp->nSize ); - } - - // if none of the covers can be computed quit - if ( !pCoverX && !pCoverP && !pCoverN ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // set the covers - assert( Abc_ObjGetSupp(pObj) == NULL ); - Abc_ObjSetSupp( pObj, vSupp ); - Abc_ObjSetCover( pObj, pCoverP, 0 ); - Abc_ObjSetCover( pObj, pCoverN, 1 ); - Abc_ObjSetCover2( pObj, pCoverX ); -//printf( "%3d : %4d %4d %4d\n", pObj->Id, Min_CoverCountCubes(pCoverP), Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverX) ); - - // count statistics - p->nSupps++; - p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); - return 1; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeXyzProduct( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ) -{ - Min_Cube_t * pCube, * pCube0, * pCube1; - Min_Cube_t * pCover; - int i, Val0, Val1; - assert( pCover0 && pCover1 ); - - // clean storage - Min_ManClean( p->pManMin, nSupp ); - // go through the cube pairs - Min_CoverForEachCube( pCover0, pCube0 ) - Min_CoverForEachCube( pCover1, pCube1 ) - { - // go through the support variables of the cubes - for ( i = 0; i < p->vPairs0->nSize; i++ ) - { - Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); - Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); - if ( (Val0 & Val1) == 0 ) - break; - } - // check disjointness - if ( i < p->vPairs0->nSize ) - continue; - - if ( p->pManMin->nCubes > p->nCubesMax ) - { - pCover = Min_CoverCollect( p->pManMin, nSupp ); -//Min_CoverWriteFile( pCover, "large", 1 ); - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - - // create the product cube - pCube = Min_CubeAlloc( p->pManMin ); - - // add the literals - pCube->nLits = 0; - for ( i = 0; i < nSupp; i++ ) - { - if ( p->vComTo0->pArray[i] == -1 ) - Val0 = 3; - else - Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); - - if ( p->vComTo1->pArray[i] == -1 ) - Val1 = 3; - else - Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); - - if ( (Val0 & Val1) == 3 ) - continue; - - Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); - pCube->nLits++; - } - // add the cube to storage - if ( fEsop ) - Min_EsopAddCube( p->pManMin, pCube ); - else - Min_SopAddCube( p->pManMin, pCube ); - } - - // minimize the cover - if ( fEsop ) - Min_EsopMinimize( p->pManMin ); - else - Min_SopMinimize( p->pManMin ); - pCover = Min_CoverCollect( p->pManMin, nSupp ); - - // quit if the cover is too large - if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) - { -/* -Min_CoverWriteFile( pCover, "large", 1 ); - Min_CoverExpand( p->pManMin, pCover ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - Min_EsopMinimize( p->pManMin ); - pCover = Min_CoverCollect( p->pManMin, nSupp ); -*/ - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeXyzSum( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ) -{ - Min_Cube_t * pCube, * pCube0, * pCube1; - Min_Cube_t * pCover; - int i, Val0, Val1; - assert( pCover0 && pCover1 ); - - // clean storage - Min_ManClean( p->pManMin, nSupp ); - Min_CoverForEachCube( pCover0, pCube0 ) - { - // create the cube - pCube = Min_CubeAlloc( p->pManMin ); - pCube->nLits = 0; - for ( i = 0; i < p->vComTo0->nSize; i++ ) - { - if ( p->vComTo0->pArray[i] == -1 ) - continue; - Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); - if ( Val0 == 3 ) - continue; - Min_CubeXorVar( pCube, i, Val0 ^ 3 ); - pCube->nLits++; - } - if ( p->pManMin->nCubes > p->nCubesMax ) - { - pCover = Min_CoverCollect( p->pManMin, nSupp ); - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - // add the cube to storage - if ( fEsop ) - Min_EsopAddCube( p->pManMin, pCube ); - else - Min_SopAddCube( p->pManMin, pCube ); - } - Min_CoverForEachCube( pCover1, pCube1 ) - { - // create the cube - pCube = Min_CubeAlloc( p->pManMin ); - pCube->nLits = 0; - for ( i = 0; i < p->vComTo1->nSize; i++ ) - { - if ( p->vComTo1->pArray[i] == -1 ) - continue; - Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); - if ( Val1 == 3 ) - continue; - Min_CubeXorVar( pCube, i, Val1 ^ 3 ); - pCube->nLits++; - } - if ( p->pManMin->nCubes > p->nCubesMax ) - { - pCover = Min_CoverCollect( p->pManMin, nSupp ); - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - // add the cube to storage - if ( fEsop ) - Min_EsopAddCube( p->pManMin, pCube ); - else - Min_SopAddCube( p->pManMin, pCube ); - } - - // minimize the cover - if ( fEsop ) - Min_EsopMinimize( p->pManMin ); - else - Min_SopMinimize( p->pManMin ); - pCover = Min_CoverCollect( p->pManMin, nSupp ); - - // quit if the cover is too large - if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) - { - Min_CoverRecycle( p->pManMin, pCover ); - return NULL; - } - return pCover; -} - - - - - - - -#if 0 - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzPropagateEsop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ) -{ - Min_Cube_t * pCover, * pCover0, * pCover1, * pCov0, * pCov1; - Vec_Int_t * vSupp, * vSupp0, * vSupp1; - - if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); - if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); - - // get the resulting support - vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); - vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); - vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 ); - - // quit if support if too large - if ( vSupp->nSize > p->nFaninMax ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // get the covers - pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0); - pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1); - - // complement the first if needed - if ( !Abc_ObjFaninC0(pObj) ) - pCover0 = pCov0; - else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube - pCover0 = pCov0->pNext; - else - pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0; - - // complement the second if needed - if ( !Abc_ObjFaninC1(pObj) ) - pCover1 = pCov1; - else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube - pCover1 = pCov1->pNext; - else - pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1; - - // derive and minimize the cover (quit if too large) - if ( !Abc_NodeXyzProductEsop( p, pCover0, pCover1, vSupp->nSize ) ) - { - pCover = Min_CoverCollect( p->pManMin, vSupp->nSize ); - Min_CoverRecycle( p->pManMin, pCover ); - Vec_IntFree( vSupp ); - return 0; - } - - // minimize the cover - Min_EsopMinimize( p->pManMin ); - pCover = Min_CoverCollect( p->pManMin, vSupp->nSize ); - - // quit if the cover is too large - if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) - { - Min_CoverRecycle( p->pManMin, pCover ); - Vec_IntFree( vSupp ); - return 0; - } - - // count statistics - p->nSupps++; - p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); - - // set the covers - assert( Abc_ObjGetSupp(pObj) == NULL ); - Abc_ObjSetSupp( pObj, vSupp ); - Abc_ObjSetCover2( pObj, pCover ); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzPropagateSop( Xyz_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ) -{ - Min_Cube_t * pCoverP, * pCoverN, * pCover0, * pCover1; - Vec_Int_t * vSupp, * vSupp0, * vSupp1; - int fCompl0, fCompl1; - - if ( pObj0->fMarkA ) Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); - if ( pObj1->fMarkA ) Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); - - // get the resulting support - vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); - vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); - vSupp = Abc_NodeXyzSupport( p, vSupp0, vSupp1 ); - - // quit if support if too large - if ( vSupp->nSize > p->nFaninMax ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // get the complemented attributes - fCompl0 = Abc_ObjFaninC0(pObj); - fCompl1 = Abc_ObjFaninC1(pObj); - - // prepare the positive cover - pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0); - pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1); - - // derive and minimize the cover (quit if too large) - if ( !pCover0 || !pCover1 ) - pCoverP = NULL; - else if ( !Abc_NodeXyzProductSop( p, pCover0, pCover1, vSupp->nSize ) ) - { - pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize ); - Min_CoverRecycle( p->pManMin, pCoverP ); - pCoverP = NULL; - } - else - { - Min_SopMinimize( p->pManMin ); - pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize ); - // quit if the cover is too large - if ( Min_CoverCountCubes(pCoverP) > p->nFaninMax ) - { - Min_CoverRecycle( p->pManMin, pCoverP ); - pCoverP = NULL; - } - } - - // prepare the negative cover - pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0); - pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1); - - // derive and minimize the cover (quit if too large) - if ( !pCover0 || !pCover1 ) - pCoverN = NULL; - else if ( !Abc_NodeXyzUnionSop( p, pCover0, pCover1, vSupp->nSize ) ) - { - pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize ); - Min_CoverRecycle( p->pManMin, pCoverN ); - pCoverN = NULL; - } - else - { - Min_SopMinimize( p->pManMin ); - pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize ); - // quit if the cover is too large - if ( Min_CoverCountCubes(pCoverN) > p->nFaninMax ) - { - Min_CoverRecycle( p->pManMin, pCoverN ); - pCoverN = NULL; - } - } - - if ( pCoverP == NULL && pCoverN == NULL ) - { - Vec_IntFree( vSupp ); - return 0; - } - - // count statistics - p->nSupps++; - p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); - - // set the covers - assert( Abc_ObjGetSupp(pObj) == NULL ); - Abc_ObjSetSupp( pObj, vSupp ); - Abc_ObjSetCover( pObj, pCoverP, 0 ); - Abc_ObjSetCover( pObj, pCoverN, 1 ); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzProductEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) -{ - Min_Cube_t * pCube, * pCube0, * pCube1; - int i, Val0, Val1; - - // clean storage - Min_ManClean( p->pManMin, nSupp ); - if ( pCover0 == NULL || pCover1 == NULL ) - return 1; - - // go through the cube pairs - Min_CoverForEachCube( pCover0, pCube0 ) - Min_CoverForEachCube( pCover1, pCube1 ) - { - // go through the support variables of the cubes - for ( i = 0; i < p->vPairs0->nSize; i++ ) - { - Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); - Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); - if ( (Val0 & Val1) == 0 ) - break; - } - // check disjointness - if ( i < p->vPairs0->nSize ) - continue; - - if ( p->pManMin->nCubes >= p->nCubesMax ) - return 0; - - // create the product cube - pCube = Min_CubeAlloc( p->pManMin ); - - // add the literals - pCube->nLits = 0; - for ( i = 0; i < nSupp; i++ ) - { - if ( p->vComTo0->pArray[i] == -1 ) - Val0 = 3; - else - Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); - - if ( p->vComTo1->pArray[i] == -1 ) - Val1 = 3; - else - Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); - - if ( (Val0 & Val1) == 3 ) - continue; - - Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); - pCube->nLits++; - } - // add the cube to storage - Min_EsopAddCube( p->pManMin, pCube ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzProductSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) -{ - return 1; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzUnionEsop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) -{ - Min_Cube_t * pCube, * pCube0, * pCube1; - int i, Val0, Val1; - - // clean storage - Min_ManClean( p->pManMin, nSupp ); - if ( pCover0 ) - { - Min_CoverForEachCube( pCover0, pCube0 ) - { - // create the cube - pCube = Min_CubeAlloc( p->pManMin ); - pCube->nLits = 0; - for ( i = 0; i < p->vComTo0->nSize; i++ ) - { - if ( p->vComTo0->pArray[i] == -1 ) - continue; - Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); - if ( Val0 == 3 ) - continue; - Min_CubeXorVar( pCube, i, Val0 ^ 3 ); - pCube->nLits++; - } - if ( p->pManMin->nCubes >= p->nCubesMax ) - return 0; - // add the cube to storage - Min_EsopAddCube( p->pManMin, pCube ); - } - } - if ( pCover1 ) - { - Min_CoverForEachCube( pCover1, pCube1 ) - { - // create the cube - pCube = Min_CubeAlloc( p->pManMin ); - pCube->nLits = 0; - for ( i = 0; i < p->vComTo1->nSize; i++ ) - { - if ( p->vComTo1->pArray[i] == -1 ) - continue; - Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); - if ( Val1 == 3 ) - continue; - Min_CubeXorVar( pCube, i, Val1 ^ 3 ); - pCube->nLits++; - } - if ( p->pManMin->nCubes >= p->nCubesMax ) - return 0; - // add the cube to storage - Min_EsopAddCube( p->pManMin, pCube ); - } - } - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeXyzUnionSop( Xyz_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) -{ - return 1; -} - - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/xyz/xyzInt.h b/src/temp/xyz/xyzInt.h deleted file mode 100644 index 656612aa..00000000 --- a/src/temp/xyz/xyzInt.h +++ /dev/null @@ -1,642 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzInt.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Internal declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Min_Man_t_ Min_Man_t; -typedef struct Min_Cube_t_ Min_Cube_t; - -struct Min_Man_t_ -{ - int nVars; // the number of vars - int nWords; // the number of words - Extra_MmFixed_t * pMemMan; // memory manager for cubes - // temporary cubes - Min_Cube_t * pOne0; // tautology cube - Min_Cube_t * pOne1; // tautology cube - Min_Cube_t * pTriv0[2]; // trivial cube - Min_Cube_t * pTriv1[2]; // trivial cube - Min_Cube_t * pTemp; // cube for computing the distance - Min_Cube_t * pBubble; // cube used as a separator - // temporary storage for the new cover - int nCubes; // the number of cubes - Min_Cube_t ** ppStore; // storage for cubes by number of literals -}; - -struct Min_Cube_t_ -{ - Min_Cube_t * pNext; // the pointer to the next cube in the cover - unsigned nVars : 10; // the number of variables - unsigned nWords : 12; // the number of machine words - unsigned nLits : 10; // the number of literals in the cube - unsigned uData[1]; // the bit-data for the cube -}; - - -// iterators through the entries in the linked lists of cubes -#define Min_CoverForEachCube( pCover, pCube ) \ - for ( pCube = pCover; \ - pCube; \ - pCube = pCube->pNext ) -#define Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \ - for ( pCube = pCover, \ - pCube2 = pCube? pCube->pNext: NULL; \ - pCube; \ - pCube = pCube2, \ - pCube2 = pCube? pCube->pNext: NULL ) -#define Min_CoverForEachCubePrev( pCover, pCube, ppPrev ) \ - for ( pCube = pCover, \ - ppPrev = &(pCover); \ - pCube; \ - ppPrev = &pCube->pNext, \ - pCube = pCube->pNext ) - -// macros to get hold of bits and values in the cubes -static inline int Min_CubeHasBit( Min_Cube_t * p, int i ) { return (p->uData[(i)>>5] & (1<<((i) & 31))) > 0; } -static inline void Min_CubeSetBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] |= (1<<((i) & 31)); } -static inline void Min_CubeXorBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] ^= (1<<((i) & 31)); } -static inline int Min_CubeGetVar( Min_Cube_t * p, int Var ) { return 3 & (p->uData[(2*Var)>>5] >> ((2*Var) & 31)); } -static inline void Min_CubeXorVar( Min_Cube_t * p, int Var, int Value ) { p->uData[(2*Var)>>5] ^= (Value<<((2*Var) & 31)); } - -/*=== xyzMinEsop.c ==========================================================*/ -extern void Min_EsopMinimize( Min_Man_t * p ); -extern void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); -/*=== xyzMinSop.c ==========================================================*/ -extern void Min_SopMinimize( Min_Man_t * p ); -extern void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); -/*=== xyzMinMan.c ==========================================================*/ -extern Min_Man_t * Min_ManAlloc( int nVars ); -extern void Min_ManClean( Min_Man_t * p, int nSupp ); -extern void Min_ManFree( Min_Man_t * p ); -/*=== xyzMinUtil.c ==========================================================*/ -extern void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ); -extern void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ); -extern void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ); -extern void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ); -extern void Min_CoverCheck( Min_Man_t * p ); -extern int Min_CubeCheck( Min_Cube_t * pCube ); -extern Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ); -extern void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ); -extern int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates the cube.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p ) -{ - Min_Cube_t * pCube; - pCube = (Min_Cube_t *)Extra_MmFixedEntryFetch( p->pMemMan ); - pCube->pNext = NULL; - pCube->nVars = p->nVars; - pCube->nWords = p->nWords; - pCube->nLits = 0; - memset( pCube->uData, 0xff, sizeof(unsigned) * p->nWords ); - return pCube; -} - -/**Function************************************************************* - - Synopsis [Creates the cube representing elementary var.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl ) -{ - Min_Cube_t * pCube; - pCube = Min_CubeAlloc( p ); - Min_CubeXorBit( pCube, iVar*2+fCompl ); - pCube->nLits = 1; - return pCube; -} - -/**Function************************************************************* - - Synopsis [Creates the cube.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy ) -{ - Min_Cube_t * pCube; - pCube = Min_CubeAlloc( p ); - memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords ); - pCube->nLits = pCopy->nLits; - return pCube; -} - -/**Function************************************************************* - - Synopsis [Recycles the cube.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube ) -{ - Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); -} - -/**Function************************************************************* - - Synopsis [Recycles the cube cover.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover ) -{ - Min_Cube_t * pCube, * pCube2; - Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) - Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); -} - - -/**Function************************************************************* - - Synopsis [Counts the number of cubes in the cover.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Min_CubeCountLits( Min_Cube_t * pCube ) -{ - unsigned uData; - int Count = 0, i, w; - for ( w = 0; w < (int)pCube->nWords; w++ ) - { - uData = pCube->uData[w] ^ (pCube->uData[w] >> 1); - for ( i = 0; i < 32; i += 2 ) - if ( uData & (1 << i) ) - Count++; - } - return Count; -} - -/**Function************************************************************* - - Synopsis [Counts the number of cubes in the cover.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits ) -{ - unsigned uData; - int i, w; - Vec_IntClear( vLits ); - for ( w = 0; w < (int)pCube->nWords; w++ ) - { - uData = pCube->uData[w] ^ (pCube->uData[w] >> 1); - for ( i = 0; i < 32; i += 2 ) - if ( uData & (1 << i) ) - Vec_IntPush( vLits, w*16 + i/2 ); - } -} - -/**Function************************************************************* - - Synopsis [Counts the number of cubes in the cover.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Min_CoverCountCubes( Min_Cube_t * pCover ) -{ - Min_Cube_t * pCube; - int Count = 0; - Min_CoverForEachCube( pCover, pCube ) - Count++; - return Count; -} - - -/**Function************************************************************* - - Synopsis [Checks if two cubes are disjoint.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) -{ - unsigned uData; - int i; - assert( pCube0->nVars == pCube1->nVars ); - for ( i = 0; i < (int)pCube0->nWords; i++ ) - { - uData = pCube0->uData[i] & pCube1->uData[i]; - uData = (uData | (uData >> 1)) & 0x55555555; - if ( uData != 0x55555555 ) - return 1; - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Collects the disjoint variables of the two cubes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube, Vec_Int_t * vVars ) -{ - unsigned uData; - int i, w; - Vec_IntClear( vVars ); - for ( w = 0; w < (int)pCube->nWords; w++ ) - { - uData = pThis->uData[w] & (pThis->uData[w] >> 1) & 0x55555555; - uData &= (pCube->uData[w] ^ (pCube->uData[w] >> 1)); - if ( uData == 0 ) - continue; - for ( i = 0; i < 32; i += 2 ) - if ( uData & (1 << i) ) - Vec_IntPush( vVars, w*16 + i/2 ); - } -} - -/**Function************************************************************* - - Synopsis [Checks if two cubes are disjoint.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Min_Cube_t * pTemp ) -{ - unsigned uData; - int i, fFound = 0; - for ( i = 0; i < (int)pCube0->nWords; i++ ) - { - uData = pCube0->uData[i] ^ pCube1->uData[i]; - if ( uData == 0 ) - { - if ( pTemp ) pTemp->uData[i] = 0; - continue; - } - if ( fFound ) - return 0; - uData = (uData | (uData >> 1)) & 0x55555555; - if ( (uData & (uData-1)) > 0 ) // more than one 1 - return 0; - if ( pTemp ) pTemp->uData[i] = uData | (uData << 1); - fFound = 1; - } - if ( fFound == 0 ) - { - printf( "\n" ); - Min_CubeWrite( stdout, pCube0 ); - Min_CubeWrite( stdout, pCube1 ); - printf( "Error: Min_CubesDistOne() looks at two equal cubes!\n" ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Checks if two cubes are disjoint.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, int * pVar0, int * pVar1 ) -{ - unsigned uData;//, uData2; - int i, k, Var0 = -1, Var1 = -1; - for ( i = 0; i < (int)pCube0->nWords; i++ ) - { - uData = pCube0->uData[i] ^ pCube1->uData[i]; - if ( uData == 0 ) - continue; - if ( Var0 >= 0 && Var1 >= 0 ) // more than two 1s - return 0; - uData = (uData | (uData >> 1)) & 0x55555555; - if ( (Var0 >= 0 || Var1 >= 0) && (uData & (uData-1)) > 0 ) - return 0; - for ( k = 0; k < 32; k += 2 ) - if ( uData & (1 << k) ) - { - if ( Var0 == -1 ) - Var0 = 16 * i + k/2; - else if ( Var1 == -1 ) - Var1 = 16 * i + k/2; - else - return 0; - } - /* - if ( Var0 >= 0 ) - { - uData &= 0xFFFF; - uData2 = (uData >> 16); - if ( uData && uData2 ) - return 0; - if ( uData ) - { - } - uData }= uData2; - uData &= 0x - } - */ - } - if ( Var0 >= 0 && Var1 >= 0 ) - { - *pVar0 = Var0; - *pVar1 = Var1; - return 1; - } - if ( Var0 == -1 || Var1 == -1 ) - { - printf( "\n" ); - Min_CubeWrite( stdout, pCube0 ); - Min_CubeWrite( stdout, pCube1 ); - printf( "Error: Min_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" ); - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Makes the produce of two cubes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) -{ - Min_Cube_t * pCube; - int i; - assert( pCube0->nVars == pCube1->nVars ); - pCube = Min_CubeAlloc( p ); - for ( i = 0; i < p->nWords; i++ ) - pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i]; - pCube->nLits = Min_CubeCountLits( pCube ); - return pCube; -} - -/**Function************************************************************* - - Synopsis [Makes the produce of two cubes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) -{ - Min_Cube_t * pCube; - int i; - assert( pCube0->nVars == pCube1->nVars ); - pCube = Min_CubeAlloc( p ); - for ( i = 0; i < p->nWords; i++ ) - pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i]; - pCube->nLits = Min_CubeCountLits( pCube ); - return pCube; -} - -/**Function************************************************************* - - Synopsis [Makes the produce of two cubes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) -{ - int i; - for ( i = 0; i < (int)pCube0->nWords; i++ ) - if ( pCube0->uData[i] != pCube1->uData[i] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if pCube1 is contained in pCube0, bitwise.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) -{ - int i; - for ( i = 0; i < (int)pCube0->nWords; i++ ) - if ( (pCube0->uData[i] & pCube1->uData[i]) != pCube1->uData[i] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Transforms the cube into the result of merging.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, Min_Cube_t * pMask ) -{ - int w; - for ( w = 0; w < (int)pCube->nWords; w++ ) - { - pCube->uData[w] = pCube->uData[w] ^ pDist->uData[w]; - pCube->uData[w] |= (pDist->uData[w] & ~pMask->uData[w]); - } -} - -/**Function************************************************************* - - Synopsis [Transforms the cube into the result of distance-1 merging.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist ) -{ - int w; - for ( w = 0; w < (int)pCube->nWords; w++ ) - pCube->uData[w] |= pDist->uData[w]; -} - - - -/**Function************************************************************* - - Synopsis [Sorts the cover in the increasing number of literals.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCover ) -{ - Min_Cube_t * pCube, * pCube2, * pThis; - if ( pCover == NULL ) - { - Min_ManClean( p, p->nVars ); - return; - } - Min_ManClean( p, pCover->nVars ); - Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) - { - // go through the linked list - Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) - if ( Min_CubesAreEqual( pCube, pThis ) ) - { - Min_CubeRecycle( p, pCube ); - break; - } - if ( pThis != NULL ) - continue; - pCube->pNext = p->ppStore[pCube->nLits]; - p->ppStore[pCube->nLits] = pCube; - p->nCubes++; - } -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the given cube is contained in one of the cubes of the cover.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Min_CoverContainsCube( Min_Man_t * p, Min_Cube_t * pCube ) -{ - Min_Cube_t * pThis; - int i; -/* - // this cube cannot be equal to any cube - Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) - { - if ( Min_CubesAreEqual( pCube, pThis ) ) - { - Min_CubeWrite( stdout, pCube ); - assert( 0 ); - } - } -*/ - // try to find a containing cube - for ( i = 0; i <= (int)pCube->nLits; i++ ) - Min_CoverForEachCube( p->ppStore[i], pThis ) - { - // skip the bubble - if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) - return 1; - } - return 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/xyz/xyzMan.c b/src/temp/xyz/xyzMan.c deleted file mode 100644 index 844e8c13..00000000 --- a/src/temp/xyz/xyzMan.c +++ /dev/null @@ -1,144 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Decomposition manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyz.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Xyz_Man_t * Xyz_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax ) -{ - Xyz_Man_t * pMan; - Xyz_Obj_t * pMem; - Abc_Obj_t * pObj; - int i; - assert( pNtk->pManCut == NULL ); - - // start the manager - pMan = ALLOC( Xyz_Man_t, 1 ); - memset( pMan, 0, sizeof(Xyz_Man_t) ); - pMan->nFaninMax = nFaninMax; - pMan->nCubesMax = 2 * pMan->nFaninMax; - pMan->nWords = Abc_BitWordNum( nFaninMax * 2 ); - - // get the cubes - pMan->vComTo0 = Vec_IntAlloc( 2*nFaninMax ); - pMan->vComTo1 = Vec_IntAlloc( 2*nFaninMax ); - pMan->vPairs0 = Vec_IntAlloc( nFaninMax ); - pMan->vPairs1 = Vec_IntAlloc( nFaninMax ); - pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 ); - pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 ); - - // allocate memory for object structures - pMan->pMemory = pMem = ALLOC( Xyz_Obj_t, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) ); - memset( pMem, 0, sizeof(Xyz_Obj_t) * Abc_NtkObjNumMax(pNtk) ); - // allocate storage for the pointers to the memory - pMan->vObjStrs = Vec_PtrAlloc( Abc_NtkObjNumMax(pNtk) ); - Vec_PtrFill( pMan->vObjStrs, Abc_NtkObjNumMax(pNtk), NULL ); - Abc_NtkForEachObj( pNtk, pObj, i ) - Vec_PtrWriteEntry( pMan->vObjStrs, i, pMem + i ); - // create the cube manager - pMan->pManMin = Min_ManAlloc( nFaninMax ); - return pMan; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Xyz_ManFree( Xyz_Man_t * p ) -{ - Vec_Int_t * vSupp; - int i; - for ( i = 0; i < p->vObjStrs->nSize; i++ ) - { - vSupp = ((Xyz_Obj_t *)p->vObjStrs->pArray[i])->vSupp; - if ( vSupp ) Vec_IntFree( vSupp ); - } - - Min_ManFree( p->pManMin ); - Vec_PtrFree( p->vObjStrs ); - Vec_IntFree( p->vFanCounts ); - Vec_IntFree( p->vTriv0 ); - Vec_IntFree( p->vTriv1 ); - Vec_IntFree( p->vComTo0 ); - Vec_IntFree( p->vComTo1 ); - Vec_IntFree( p->vPairs0 ); - Vec_IntFree( p->vPairs1 ); - free( p->pMemory ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Drop the covers at the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeXyzDropData( Xyz_Man_t * p, Abc_Obj_t * pObj ) -{ - int nFanouts; - assert( p->vFanCounts ); - nFanouts = Vec_IntEntry( p->vFanCounts, pObj->Id ); - assert( nFanouts > 0 ); - if ( --nFanouts == 0 ) - { - Vec_IntFree( Abc_ObjGetSupp(pObj) ); - Abc_ObjSetSupp( pObj, NULL ); - Min_CoverRecycle( p->pManMin, Abc_ObjGetCover2(pObj) ); - Abc_ObjSetCover2( pObj, NULL ); - p->nSupps--; - } - Vec_IntWriteEntry( p->vFanCounts, pObj->Id, nFanouts ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/xyz/xyzMinEsop.c b/src/temp/xyz/xyzMinEsop.c deleted file mode 100644 index 839e2410..00000000 --- a/src/temp/xyz/xyzMinEsop.c +++ /dev/null @@ -1,299 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzMinEsop.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [ESOP manipulation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzMinEsop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyzInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Min_EsopRewrite( Min_Man_t * p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_EsopMinimize( Min_Man_t * p ) -{ - int nCubesInit, nCubesOld, nIter; - if ( p->nCubes < 3 ) - return; - nIter = 0; - nCubesInit = p->nCubes; - do { - nCubesOld = p->nCubes; - Min_EsopRewrite( p ); - nIter++; - } - while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); - -// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes ); -} - -/**Function************************************************************* - - Synopsis [Performs one round of rewriting using distance 2 cubes.] - - Description [The weakness of this procedure is that it tries each cube - with only one distance-2 cube. If this pair does not lead to improvement - the cube is inserted into the cover anyhow, and we try another pair. - A possible improvement would be to try this cube with all distance-2 - cubes, until an improvement is found, or until all such cubes are tried.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_EsopRewrite( Min_Man_t * p ) -{ - Min_Cube_t * pCube, ** ppPrev; - Min_Cube_t * pThis, ** ppPrevT; - int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld; - int nPairs = 0; - - // insert the bubble before the first cube - p->pBubble->pNext = p->ppStore[0]; - p->ppStore[0] = p->pBubble; - p->pBubble->nLits = 0; - - // go through the cubes - while ( 1 ) - { - // get the index of the bubble - Index = p->pBubble->nLits; - - // find the bubble - Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) - if ( pCube == p->pBubble ) - break; - assert( pCube == p->pBubble ); - - // remove the bubble, get the next cube after the bubble - *ppPrev = p->pBubble->pNext; - pCube = p->pBubble->pNext; - if ( pCube == NULL ) - for ( Index++; Index <= p->nVars; Index++ ) - if ( p->ppStore[Index] ) - { - ppPrev = &(p->ppStore[Index]); - pCube = p->ppStore[Index]; - break; - } - // stop if there is no more cubes - if ( pCube == NULL ) - break; - - // find the first dist2 cube - Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) - break; - if ( pThis == NULL && Index < p->nVars ) - Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) - break; - if ( pThis == NULL && Index < p->nVars - 1 ) - Min_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) - break; - // continue if there is no dist2 cube - if ( pThis == NULL ) - { - // insert the bubble after the cube - p->pBubble->pNext = pCube->pNext; - pCube->pNext = p->pBubble; - p->pBubble->nLits = pCube->nLits; - continue; - } - nPairs++; - - // remove the cubes, insert the bubble instead of pCube - *ppPrevT = pThis->pNext; - *ppPrev = p->pBubble; - p->pBubble->pNext = pCube->pNext; - p->pBubble->nLits = pCube->nLits; - p->nCubes -= 2; - - // Exorlink-2: - // A{v00} B{v01} + A{v10} B{v11} = - // A{v00+v10} B{v01} + A{v10} B{v01+v11} = - // A{v00} B{v01+v11} + A{v00+v10} B{v11} - - // save the dist2 parameters - v00 = Min_CubeGetVar( pCube, Var0 ); - v01 = Min_CubeGetVar( pCube, Var1 ); - v10 = Min_CubeGetVar( pThis, Var0 ); - v11 = Min_CubeGetVar( pThis, Var1 ); -//printf( "\n" ); -//Min_CubeWrite( stdout, pCube ); -//Min_CubeWrite( stdout, pThis ); - - // derive the first pair of resulting cubes - Min_CubeXorVar( pCube, Var0, v10 ); - pCube->nLits -= (v00 != 3); - pCube->nLits += ((v00 ^ v10) != 3); - Min_CubeXorVar( pThis, Var1, v01 ); - pThis->nLits -= (v11 != 3); - pThis->nLits += ((v01 ^ v11) != 3); - - // add the cubes - nCubesOld = p->nCubes; - Min_EsopAddCube( p, pCube ); - Min_EsopAddCube( p, pThis ); - // check if the cubes were absorbed - if ( p->nCubes < nCubesOld + 2 ) - continue; - - // pull out both cubes - assert( pThis == p->ppStore[pThis->nLits] ); - p->ppStore[pThis->nLits] = pThis->pNext; - assert( pCube == p->ppStore[pCube->nLits] ); - p->ppStore[pCube->nLits] = pCube->pNext; - p->nCubes -= 2; - - // derive the second pair of resulting cubes - Min_CubeXorVar( pCube, Var0, v10 ); - pCube->nLits -= ((v00 ^ v10) != 3); - pCube->nLits += (v00 != 3); - Min_CubeXorVar( pCube, Var1, v11 ); - pCube->nLits -= (v01 != 3); - pCube->nLits += ((v01 ^ v11) != 3); - - Min_CubeXorVar( pThis, Var0, v00 ); - pThis->nLits -= (v10 != 3); - pThis->nLits += ((v00 ^ v10) != 3); - Min_CubeXorVar( pThis, Var1, v01 ); - pThis->nLits -= ((v01 ^ v11) != 3); - pThis->nLits += (v11 != 3); - - // add them anyhow - Min_EsopAddCube( p, pCube ); - Min_EsopAddCube( p, pThis ); - } -// printf( "Pairs = %d ", nPairs ); -} - -/**Function************************************************************* - - Synopsis [Adds the cube to storage.] - - Description [Returns 0 if the cube is added or removed. Returns 1 - if the cube is glued with some other cube and has to be added again. - Do not forget to clean the storage!] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) -{ - Min_Cube_t * pThis, ** ppPrev; - // try to find the identical cube - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) - { - if ( Min_CubesAreEqual( pCube, pThis ) ) - { - *ppPrev = pThis->pNext; - Min_CubeRecycle( p, pCube ); - Min_CubeRecycle( p, pThis ); - p->nCubes--; - return 0; - } - } - // find a distance-1 cube if it exists - if ( pCube->nLits < pCube->nVars ) - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev ) - { - if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) - { - *ppPrev = pThis->pNext; - Min_CubesTransform( pCube, pThis, p->pTemp ); - pCube->nLits++; - Min_CubeRecycle( p, pThis ); - p->nCubes--; - return 1; - } - } - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) - { - if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) - { - *ppPrev = pThis->pNext; - Min_CubesTransform( pCube, pThis, p->pTemp ); - pCube->nLits--; - Min_CubeRecycle( p, pThis ); - p->nCubes--; - return 1; - } - } - if ( pCube->nLits > 0 ) - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev ) - { - if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) - { - *ppPrev = pThis->pNext; - Min_CubesTransform( pCube, pThis, p->pTemp ); - Min_CubeRecycle( p, pThis ); - p->nCubes--; - return 1; - } - } - // add the cube - pCube->pNext = p->ppStore[pCube->nLits]; - p->ppStore[pCube->nLits] = pCube; - p->nCubes++; - return 0; -} - -/**Function************************************************************* - - Synopsis [Adds the cube to storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) -{ - assert( pCube != p->pBubble ); - assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); - while ( Min_EsopAddCubeInt( p, pCube ) ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/xyz/xyzMinMan.c b/src/temp/xyz/xyzMinMan.c deleted file mode 100644 index 20314698..00000000 --- a/src/temp/xyz/xyzMinMan.c +++ /dev/null @@ -1,113 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzMinMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [SOP manipulation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzMinMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyzInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the minimization manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Man_t * Min_ManAlloc( int nVars ) -{ - Min_Man_t * pMan; - // start the manager - pMan = ALLOC( Min_Man_t, 1 ); - memset( pMan, 0, sizeof(Min_Man_t) ); - pMan->nVars = nVars; - pMan->nWords = Abc_BitWordNum( nVars * 2 ); - pMan->pMemMan = Extra_MmFixedStart( sizeof(Min_Cube_t) + sizeof(unsigned) * (pMan->nWords - 1) ); - // allocate storage for the temporary cover - pMan->ppStore = ALLOC( Min_Cube_t *, pMan->nVars + 1 ); - // create tautology cubes - Min_ManClean( pMan, nVars ); - pMan->pOne0 = Min_CubeAlloc( pMan ); - pMan->pOne1 = Min_CubeAlloc( pMan ); - pMan->pTemp = Min_CubeAlloc( pMan ); - pMan->pBubble = Min_CubeAlloc( pMan ); pMan->pBubble->uData[0] = 0; - // create trivial cubes - Min_ManClean( pMan, 1 ); - pMan->pTriv0[0] = Min_CubeAllocVar( pMan, 0, 0 ); - pMan->pTriv0[1] = Min_CubeAllocVar( pMan, 0, 1 ); - pMan->pTriv1[0] = Min_CubeAllocVar( pMan, 0, 0 ); - pMan->pTriv1[1] = Min_CubeAllocVar( pMan, 0, 1 ); - Min_ManClean( pMan, nVars ); - return pMan; -} - -/**Function************************************************************* - - Synopsis [Cleans the minimization manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_ManClean( Min_Man_t * p, int nSupp ) -{ - // set the size of the cube manager - p->nVars = nSupp; - p->nWords = Abc_BitWordNum(2*nSupp); - // clean the storage - memset( p->ppStore, 0, sizeof(Min_Cube_t *) * (nSupp + 1) ); - p->nCubes = 0; -} - -/**Function************************************************************* - - Synopsis [Stops the minimization manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_ManFree( Min_Man_t * p ) -{ - Extra_MmFixedStop ( p->pMemMan, 0 ); - free( p->ppStore ); - free( p ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/xyz/xyzMinSop.c b/src/temp/xyz/xyzMinSop.c deleted file mode 100644 index a5d57c66..00000000 --- a/src/temp/xyz/xyzMinSop.c +++ /dev/null @@ -1,615 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzMinSop.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [SOP manipulation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzMinSop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyzInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Min_SopRewrite( Min_Man_t * p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopMinimize( Min_Man_t * p ) -{ - int nCubesInit, nCubesOld, nIter; - if ( p->nCubes < 3 ) - return; - nIter = 0; - nCubesInit = p->nCubes; - do { - nCubesOld = p->nCubes; - Min_SopRewrite( p ); - nIter++; -// printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes ); - } - while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); -// printf( "\n" ); - -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopRewrite( Min_Man_t * p ) -{ - Min_Cube_t * pCube, ** ppPrev; - Min_Cube_t * pThis, ** ppPrevT; - Min_Cube_t * pTemp; - int v00, v01, v10, v11, Var0, Var1, Index, fCont0, fCont1, nCubesOld; - int nPairs = 0; -/* - { - Min_Cube_t * pCover; - pCover = Min_CoverCollect( p, p->nVars ); -printf( "\n\n" ); -Min_CoverWrite( stdout, pCover ); - Min_CoverExpand( p, pCover ); - } -*/ - - // insert the bubble before the first cube - p->pBubble->pNext = p->ppStore[0]; - p->ppStore[0] = p->pBubble; - p->pBubble->nLits = 0; - - // go through the cubes - while ( 1 ) - { - // get the index of the bubble - Index = p->pBubble->nLits; - - // find the bubble - Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) - if ( pCube == p->pBubble ) - break; - assert( pCube == p->pBubble ); - - // remove the bubble, get the next cube after the bubble - *ppPrev = p->pBubble->pNext; - pCube = p->pBubble->pNext; - if ( pCube == NULL ) - for ( Index++; Index <= p->nVars; Index++ ) - if ( p->ppStore[Index] ) - { - ppPrev = &(p->ppStore[Index]); - pCube = p->ppStore[Index]; - break; - } - // stop if there is no more cubes - if ( pCube == NULL ) - break; - - // find the first dist2 cube - Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) - break; - if ( pThis == NULL && Index < p->nVars ) - Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) - if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) - break; - // continue if there is no dist2 cube - if ( pThis == NULL ) - { - // insert the bubble after the cube - p->pBubble->pNext = pCube->pNext; - pCube->pNext = p->pBubble; - p->pBubble->nLits = pCube->nLits; - continue; - } - nPairs++; -/* -printf( "\n" ); -Min_CubeWrite( stdout, pCube ); -Min_CubeWrite( stdout, pThis ); -*/ - // remove the cubes, insert the bubble instead of pCube - *ppPrevT = pThis->pNext; - *ppPrev = p->pBubble; - p->pBubble->pNext = pCube->pNext; - p->pBubble->nLits = pCube->nLits; - p->nCubes -= 2; - - assert( pCube != p->pBubble && pThis != p->pBubble ); - - - // save the dist2 parameters - v00 = Min_CubeGetVar( pCube, Var0 ); - v01 = Min_CubeGetVar( pCube, Var1 ); - v10 = Min_CubeGetVar( pThis, Var0 ); - v11 = Min_CubeGetVar( pThis, Var1 ); - assert( v00 != v10 && v01 != v11 ); - assert( v00 != 3 || v01 != 3 ); - assert( v10 != 3 || v11 != 3 ); - -//printf( "\n" ); -//Min_CubeWrite( stdout, pCube ); -//Min_CubeWrite( stdout, pThis ); - -//printf( "\n" ); -//Min_CubeWrite( stdout, pCube ); -//Min_CubeWrite( stdout, pThis ); - - // consider the case when both cubes have non-empty literals - if ( v00 != 3 && v01 != 3 && v10 != 3 && v11 != 3 ) - { - assert( v00 == (v10 ^ 3) ); - assert( v01 == (v11 ^ 3) ); - // create the temporary cube equal to the first corner - Min_CubeXorVar( pCube, Var0, 3 ); - // check if this cube is contained - fCont0 = Min_CoverContainsCube( p, pCube ); - // create the temporary cube equal to the first corner - Min_CubeXorVar( pCube, Var0, 3 ); - Min_CubeXorVar( pCube, Var1, 3 ); -//printf( "\n" ); -//Min_CubeWrite( stdout, pCube ); -//Min_CubeWrite( stdout, pThis ); - // check if this cube is contained - fCont1 = Min_CoverContainsCube( p, pCube ); - // undo the change - Min_CubeXorVar( pCube, Var1, 3 ); - - // check if the cubes can be overwritten - if ( fCont0 && fCont1 ) - { - // one of the cubes can be recycled, the other expanded and added - Min_CubeRecycle( p, pThis ); - // remove the literals - Min_CubeXorVar( pCube, Var0, v00 ^ 3 ); - Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); - pCube->nLits -= 2; - Min_SopAddCube( p, pCube ); - } - else if ( fCont0 ) - { - // expand both cubes and add them - Min_CubeXorVar( pCube, Var0, v00 ^ 3 ); - pCube->nLits--; - Min_SopAddCube( p, pCube ); - Min_CubeXorVar( pThis, Var1, v11 ^ 3 ); - pThis->nLits--; - Min_SopAddCube( p, pThis ); - } - else if ( fCont1 ) - { - // expand both cubes and add them - Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); - pCube->nLits--; - Min_SopAddCube( p, pCube ); - Min_CubeXorVar( pThis, Var0, v10 ^ 3 ); - pThis->nLits--; - Min_SopAddCube( p, pThis ); - } - else - { - Min_SopAddCube( p, pCube ); - Min_SopAddCube( p, pThis ); - } - // otherwise, no change is possible - continue; - } - - // if one of them does not have DC lit, move it - if ( v00 != 3 && v01 != 3 ) - { - assert( v10 == 3 || v11 == 3 ); - pTemp = pCube; pCube = pThis; pThis = pTemp; - Index = v00; v00 = v10; v10 = Index; - Index = v01; v01 = v11; v11 = Index; - } - - // make sure the first cube has first var DC - if ( v00 != 3 ) - { - assert( v01 == 3 ); - Index = Var0; Var0 = Var1; Var1 = Index; - Index = v00; v00 = v01; v01 = Index; - Index = v10; v10 = v11; v11 = Index; - } - - // consider both cases: both have DC lit - if ( v00 == 3 && v11 == 3 ) - { - assert( v01 != 3 && v10 != 3 ); - // try the remaining minterm - // create the temporary cube equal to the first corner - Min_CubeXorVar( pCube, Var0, v10 ); - Min_CubeXorVar( pCube, Var1, 3 ); - pCube->nLits++; - // check if this cube is contained - fCont0 = Min_CoverContainsCube( p, pCube ); - // undo the cube transformations - Min_CubeXorVar( pCube, Var0, v10 ); - Min_CubeXorVar( pCube, Var1, 3 ); - pCube->nLits--; - // check the case when both are covered - if ( fCont0 ) - { - // one of the cubes can be recycled, the other expanded and added - Min_CubeRecycle( p, pThis ); - // remove the literals - Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); - pCube->nLits--; - Min_SopAddCube( p, pCube ); - } - else - { - // try two reduced cubes - Min_CubeXorVar( pCube, Var0, v10 ); - pCube->nLits++; - // remember the cubes - nCubesOld = p->nCubes; - Min_SopAddCube( p, pCube ); - // check if the cube is absorbed - if ( p->nCubes < nCubesOld + 1 ) - { // absorbed - add the second cube - Min_SopAddCube( p, pThis ); - } - else - { // remove this cube, and try another one - assert( pCube == p->ppStore[pCube->nLits] ); - p->ppStore[pCube->nLits] = pCube->pNext; - p->nCubes--; - - // return the cube to the previous state - Min_CubeXorVar( pCube, Var0, v10 ); - pCube->nLits--; - - // generate another reduced cube - Min_CubeXorVar( pThis, Var1, v01 ); - pThis->nLits++; - - // add both cubes - Min_SopAddCube( p, pCube ); - Min_SopAddCube( p, pThis ); - } - } - } - else // the first cube has DC lit - { - assert( v01 != 3 && v10 != 3 && v11 != 3 ); - // try the remaining minterm - // create the temporary cube equal to the minterm - Min_CubeXorVar( pThis, Var0, 3 ); - // check if this cube is contained - fCont0 = Min_CoverContainsCube( p, pThis ); - // undo the cube transformations - Min_CubeXorVar( pThis, Var0, 3 ); - // check the case when both are covered - if ( fCont0 ) - { - // one of the cubes can be recycled, the other expanded and added - Min_CubeRecycle( p, pThis ); - // remove the literals - Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); - pCube->nLits--; - Min_SopAddCube( p, pCube ); - } - else - { - // try reshaping the cubes - // reduce the first cube - Min_CubeXorVar( pCube, Var0, v10 ); - pCube->nLits++; - // expand the second cube - Min_CubeXorVar( pThis, Var1, v11 ^ 3 ); - pThis->nLits--; - // add both cubes - Min_SopAddCube( p, pCube ); - Min_SopAddCube( p, pThis ); - } - } - } -// printf( "Pairs = %d ", nPairs ); -} - -/**Function************************************************************* - - Synopsis [Adds cube to the SOP cover stored in the manager.] - - Description [Returns 0 if the cube is added or removed. Returns 1 - if the cube is glued with some other cube and has to be added again.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Min_SopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) -{ - Min_Cube_t * pThis, * pThis2, ** ppPrev; - int i; - // try to find the identical cube - Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) - { - if ( Min_CubesAreEqual( pCube, pThis ) ) - { - Min_CubeRecycle( p, pCube ); - return 0; - } - } - // try to find a containing cube - for ( i = 0; i < (int)pCube->nLits; i++ ) - Min_CoverForEachCube( p->ppStore[i], pThis ) - { - if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) - { - Min_CubeRecycle( p, pCube ); - return 0; - } - } - // try to find distance one in the same bin - Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) - { - if ( Min_CubesDistOne( pCube, pThis, NULL ) ) - { - *ppPrev = pThis->pNext; - Min_CubesTransformOr( pCube, pThis ); - pCube->nLits--; - Min_CubeRecycle( p, pThis ); - p->nCubes--; - return 1; - } - } - - // clean the other cubes using this one - for ( i = pCube->nLits + 1; i <= (int)pCube->nVars; i++ ) - { - ppPrev = &p->ppStore[i]; - Min_CoverForEachCubeSafe( p->ppStore[i], pThis, pThis2 ) - { - if ( pThis != p->pBubble && Min_CubeIsContained( pCube, pThis ) ) - { - *ppPrev = pThis->pNext; - Min_CubeRecycle( p, pThis ); - p->nCubes--; - } - else - ppPrev = &pThis->pNext; - } - } - - // add the cube - pCube->pNext = p->ppStore[pCube->nLits]; - p->ppStore[pCube->nLits] = pCube; - p->nCubes++; - return 0; -} - -/**Function************************************************************* - - Synopsis [Adds the cube to storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) -{ - assert( Min_CubeCheck( pCube ) ); - assert( pCube != p->pBubble ); - assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); - while ( Min_SopAddCubeInt( p, pCube ) ); -} - - - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopContain( Min_Man_t * p ) -{ - Min_Cube_t * pCube, * pCube2, ** ppPrev; - int i, k; - for ( i = 0; i <= p->nVars; i++ ) - { - Min_CoverForEachCube( p->ppStore[i], pCube ) - Min_CoverForEachCubePrev( pCube->pNext, pCube2, ppPrev ) - { - if ( !Min_CubesAreEqual( pCube, pCube2 ) ) - continue; - *ppPrev = pCube2->pNext; - Min_CubeRecycle( p, pCube2 ); - p->nCubes--; - } - for ( k = i + 1; k <= p->nVars; k++ ) - Min_CoverForEachCubePrev( p->ppStore[k], pCube2, ppPrev ) - { - if ( !Min_CubeIsContained( pCube, pCube2 ) ) - continue; - *ppPrev = pCube2->pNext; - Min_CubeRecycle( p, pCube2 ); - p->nCubes--; - } - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_SopDist1Merge( Min_Man_t * p ) -{ - Min_Cube_t * pCube, * pCube2, * pCubeNew; - int i; - for ( i = p->nVars; i >= 0; i-- ) - { - Min_CoverForEachCube( p->ppStore[i], pCube ) - Min_CoverForEachCube( pCube->pNext, pCube2 ) - { - assert( pCube->nLits == pCube2->nLits ); - if ( !Min_CubesDistOne( pCube, pCube2, NULL ) ) - continue; - pCubeNew = Min_CubesXor( p, pCube, pCube2 ); - assert( pCubeNew->nLits == pCube->nLits - 1 ); - pCubeNew->pNext = p->ppStore[pCubeNew->nLits]; - p->ppStore[pCubeNew->nLits] = pCubeNew; - p->nCubes++; - } - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Min_SopComplement( Min_Man_t * p, Min_Cube_t * pSharp ) -{ - Vec_Int_t * vVars; - Min_Cube_t * pCover, * pCube, * pNext, * pReady, * pThis, ** ppPrev; - int Num, Value, i; - - // get the variables - vVars = Vec_IntAlloc( 100 ); - // create the tautology cube - pCover = Min_CubeAlloc( p ); - // sharp it with all cubes - Min_CoverForEachCube( pSharp, pCube ) - Min_CoverForEachCubePrev( pCover, pThis, ppPrev ) - { - if ( Min_CubesDisjoint( pThis, pCube ) ) - continue; - // remember the next pointer - pNext = pThis->pNext; - // get the variables, in which pThis is '-' while pCube is fixed - Min_CoverGetDisjVars( pThis, pCube, vVars ); - // generate the disjoint cubes - pReady = pThis; - Vec_IntForEachEntryReverse( vVars, Num, i ) - { - // correct the literal - Min_CubeXorVar( pReady, vVars->pArray[i], 3 ); - if ( i == 0 ) - break; - // create the new cube and clean this value - Value = Min_CubeGetVar( pReady, vVars->pArray[i] ); - pReady = Min_CubeDup( p, pReady ); - Min_CubeXorVar( pReady, vVars->pArray[i], 3 ^ Value ); - // add to the cover - *ppPrev = pReady; - ppPrev = &pReady->pNext; - } - pThis = pReady; - pThis->pNext = pNext; - } - Vec_IntFree( vVars ); - - // perform dist-1 merge and contain - Min_CoverExpandRemoveEqual( p, pCover ); - Min_SopDist1Merge( p ); - Min_SopContain( p ); - return Min_CoverCollect( p, p->nVars ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Min_SopCheck( Min_Man_t * p ) -{ - Min_Cube_t * pCube, * pThis; - int i; - - pCube = Min_CubeAlloc( p ); - Min_CubeXorBit( pCube, 2*0+1 ); - Min_CubeXorBit( pCube, 2*1+1 ); - Min_CubeXorBit( pCube, 2*2+0 ); - Min_CubeXorBit( pCube, 2*3+0 ); - Min_CubeXorBit( pCube, 2*4+0 ); - Min_CubeXorBit( pCube, 2*5+1 ); - Min_CubeXorBit( pCube, 2*6+1 ); - pCube->nLits = 7; - -// Min_CubeWrite( stdout, pCube ); - - // check that the cubes contain it - for ( i = 0; i <= p->nVars; i++ ) - Min_CoverForEachCube( p->ppStore[i], pThis ) - if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) - { - Min_CubeRecycle( p, pCube ); - return 1; - } - Min_CubeRecycle( p, pCube ); - return 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/xyz/xyzMinUtil.c b/src/temp/xyz/xyzMinUtil.c deleted file mode 100644 index 9ec5f83f..00000000 --- a/src/temp/xyz/xyzMinUtil.c +++ /dev/null @@ -1,277 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzMinUtil.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Utilities.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzMinUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyzInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ) -{ - int i; - assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); - for ( i = 0; i < (int)pCube->nVars; i++ ) - if ( Min_CubeHasBit(pCube, i*2) ) - { - if ( Min_CubeHasBit(pCube, i*2+1) ) - fprintf( pFile, "-" ); - else - fprintf( pFile, "0" ); - } - else - { - if ( Min_CubeHasBit(pCube, i*2+1) ) - fprintf( pFile, "1" ); - else - fprintf( pFile, "?" ); - } - fprintf( pFile, " 1\n" ); -// fprintf( pFile, " %d\n", pCube->nLits ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ) -{ - Min_Cube_t * pCube; - Min_CoverForEachCube( pCover, pCube ) - Min_CubeWrite( pFile, pCube ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ) -{ - Min_Cube_t * pCube; - int i; - for ( i = 0; i <= p->nVars; i++ ) - { - Min_CoverForEachCube( p->ppStore[i], pCube ) - { - printf( "%2d : ", i ); - if ( pCube == p->pBubble ) - { - printf( "Bubble\n" ); - continue; - } - Min_CubeWrite( pFile, pCube ); - } - } - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ) -{ - char Buffer[1000]; - Min_Cube_t * pCube; - FILE * pFile; - int i; - sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" ); - for ( i = strlen(Buffer) - 1; i >= 0; i-- ) - if ( Buffer[i] == '<' || Buffer[i] == '>' ) - Buffer[i] = '_'; - pFile = fopen( Buffer, "w" ); - fprintf( pFile, "# %s cover for output %s generated by ABC on %s\n", fEsop? "ESOP":"SOP", pName, Extra_TimeStamp() ); - fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 ); - fprintf( pFile, ".o %d\n", 1 ); - fprintf( pFile, ".p %d\n", Min_CoverCountCubes(pCover) ); - if ( fEsop ) fprintf( pFile, ".type esop\n" ); - Min_CoverForEachCube( pCover, pCube ) - Min_CubeWrite( pFile, pCube ); - fprintf( pFile, ".e\n" ); - fclose( pFile ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_CoverCheck( Min_Man_t * p ) -{ - Min_Cube_t * pCube; - int i; - for ( i = 0; i <= p->nVars; i++ ) - Min_CoverForEachCube( p->ppStore[i], pCube ) - assert( i == (int)pCube->nLits ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Min_CubeCheck( Min_Cube_t * pCube ) -{ - int i; - for ( i = 0; i < (int)pCube->nVars; i++ ) - if ( Min_CubeGetVar( pCube, i ) == 0 ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Converts the cover from the sorted structure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ) -{ - Min_Cube_t * pCov = NULL, ** ppTail = &pCov; - Min_Cube_t * pCube, * pCube2; - int i; - for ( i = 0; i <= nSuppSize; i++ ) - { - Min_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 ) - { - assert( i == (int)pCube->nLits ); - *ppTail = pCube; - ppTail = &pCube->pNext; - assert( pCube->uData[0] ); // not a bubble - } - } - *ppTail = NULL; - return pCov; -} - -/**Function************************************************************* - - Synopsis [Sorts the cover in the increasing number of literals.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ) -{ - Min_Cube_t * pCube, * pCube2; - Min_ManClean( p, p->nVars ); - Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) - { - pCube->pNext = p->ppStore[pCube->nLits]; - p->ppStore[pCube->nLits] = pCube; - p->nCubes++; - } -} - -/**Function************************************************************* - - Synopsis [Sorts the cover in the increasing number of literals.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ) -{ - Min_Cube_t * pCube; - int i, Counter; - if ( pCover == NULL ) - return 0; - // clean the cube - for ( i = 0; i < (int)pCover->nWords; i++ ) - p->pTemp->uData[i] = ~((unsigned)0); - // add the bit data - Min_CoverForEachCube( pCover, pCube ) - for ( i = 0; i < (int)pCover->nWords; i++ ) - p->pTemp->uData[i] &= pCube->uData[i]; - // count the vars - Counter = 0; - for ( i = 0; i < (int)pCover->nVars; i++ ) - Counter += ( Min_CubeGetVar(p->pTemp, i) != 3 ); - return Counter; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/xyz/xyzTest.c b/src/temp/xyz/xyzTest.c deleted file mode 100644 index 38580790..00000000 --- a/src/temp/xyz/xyzTest.c +++ /dev/null @@ -1,417 +0,0 @@ -/**CFile**************************************************************** - - FileName [xyzTest.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Cover manipulation package.] - - Synopsis [Testing procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: xyzTest.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "xyz.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeDeriveCoverPro( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 ) -{ - Min_Cube_t * pCover; - Min_Cube_t * pCube0, * pCube1, * pCube; - if ( pCover0 == NULL || pCover1 == NULL ) - return NULL; - // clean storage - Min_ManClean( p, p->nVars ); - // go through the cube pairs - Min_CoverForEachCube( pCover0, pCube0 ) - Min_CoverForEachCube( pCover1, pCube1 ) - { - if ( Min_CubesDisjoint( pCube0, pCube1 ) ) - continue; - pCube = Min_CubesProduct( p, pCube0, pCube1 ); - // add the cube to storage - Min_SopAddCube( p, pCube ); - } - Min_SopMinimize( p ); - pCover = Min_CoverCollect( p, p->nVars ); - assert( p->nCubes == Min_CoverCountCubes(pCover) ); - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeDeriveCoverSum( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 ) -{ - Min_Cube_t * pCover; - Min_Cube_t * pThis, * pCube; - if ( pCover0 == NULL || pCover1 == NULL ) - return NULL; - // clean storage - Min_ManClean( p, p->nVars ); - // add the cubes to storage - Min_CoverForEachCube( pCover0, pThis ) - { - pCube = Min_CubeDup( p, pThis ); - Min_SopAddCube( p, pCube ); - } - Min_CoverForEachCube( pCover1, pThis ) - { - pCube = Min_CubeDup( p, pThis ); - Min_SopAddCube( p, pCube ); - } - Min_SopMinimize( p ); - pCover = Min_CoverCollect( p, p->nVars ); - assert( p->nCubes == Min_CoverCountCubes(pCover) ); - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeDeriveSops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes ) -{ - Min_Cube_t * pCov0[2], * pCov1[2]; - Min_Cube_t * pCoverP, * pCoverN; - Abc_Obj_t * pObj; - int i, nCubes, fCompl0, fCompl1; - - // set elementary vars - Vec_PtrForEachEntry( vSupp, pObj, i ) - { - pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 ); - pObj->pNext = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 1 ); - } - - // get the cover for each node in the array - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // get the complements - fCompl0 = Abc_ObjFaninC0(pObj); - fCompl1 = Abc_ObjFaninC1(pObj); - // get the covers - pCov0[0] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy; - pCov0[1] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pNext; - pCov1[0] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy; - pCov1[1] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pNext; - // compute the covers - pCoverP = Abc_NodeDeriveCoverPro( p, pCov0[ fCompl0], pCov1[ fCompl1] ); - pCoverN = Abc_NodeDeriveCoverSum( p, pCov0[!fCompl0], pCov1[!fCompl1] ); - // set the covers - pObj->pCopy = (Abc_Obj_t *)pCoverP; - pObj->pNext = (Abc_Obj_t *)pCoverN; - } - - nCubes = ABC_MIN( Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverP) ); - -/* -printf( "\n\n" ); -Min_CoverWrite( stdout, pCoverP ); -printf( "\n\n" ); -Min_CoverWrite( stdout, pCoverN ); -*/ - -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverP ); - -// Min_CoverExpand( p, pCoverP ); -// Min_SopMinimize( p ); -// pCoverP = Min_CoverCollect( p, p->nVars ); - -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverP ); - -// nCubes = Min_CoverCountCubes(pCoverP); - - // clean the copy fields - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = pObj->pNext = NULL; - Vec_PtrForEachEntry( vSupp, pObj, i ) - pObj->pCopy = pObj->pNext = NULL; - -// Min_CoverWriteFile( pCoverP, Abc_ObjName(pRoot), 0 ); -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverP ); - -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverP ); -// printf( "\n" ); -// Min_CoverWrite( stdout, pCoverN ); - return nCubes; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTestSop( Abc_Ntk_t * pNtk ) -{ - Min_Man_t * p; - Vec_Ptr_t * vSupp, * vNodes; - Abc_Obj_t * pObj; - int i, nCubes; - assert( Abc_NtkIsStrash(pNtk) ); - - Abc_NtkCleanCopy(pNtk); - Abc_NtkCleanNext(pNtk); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - if ( !Abc_NodeIsAigAnd(Abc_ObjFanin0(pObj)) ) - { - printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) ); - continue; - } - - vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); - vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); - - printf( "%20s : Cone = %5d. Supp = %5d. ", - Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize ); -// if ( vSupp->nSize <= 128 ) - { - p = Min_ManAlloc( vSupp->nSize ); - nCubes = Abc_NodeDeriveSops( p, pObj, vSupp, vNodes ); - printf( "Cubes = %5d. ", nCubes ); - Min_ManFree( p ); - } - printf( "\n" ); - - - Vec_PtrFree( vNodes ); - Vec_PtrFree( vSupp ); - } -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Min_Cube_t * Abc_NodeDeriveCover( Min_Man_t * p, Min_Cube_t * pCov0, Min_Cube_t * pCov1, int fComp0, int fComp1 ) -{ - Min_Cube_t * pCover0, * pCover1, * pCover; - Min_Cube_t * pCube0, * pCube1, * pCube; - - // complement the first if needed - if ( !fComp0 ) - pCover0 = pCov0; - else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube - pCover0 = pCov0->pNext; - else - pCover0 = p->pOne0, p->pOne0->pNext = pCov0; - - // complement the second if needed - if ( !fComp1 ) - pCover1 = pCov1; - else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube - pCover1 = pCov1->pNext; - else - pCover1 = p->pOne1, p->pOne1->pNext = pCov1; - - if ( pCover0 == NULL || pCover1 == NULL ) - return NULL; - - // clean storage - Min_ManClean( p, p->nVars ); - // go through the cube pairs - Min_CoverForEachCube( pCover0, pCube0 ) - Min_CoverForEachCube( pCover1, pCube1 ) - { - if ( Min_CubesDisjoint( pCube0, pCube1 ) ) - continue; - pCube = Min_CubesProduct( p, pCube0, pCube1 ); - // add the cube to storage - Min_EsopAddCube( p, pCube ); - } - - if ( p->nCubes > 10 ) - { -// printf( "(%d,", p->nCubes ); - Min_EsopMinimize( p ); -// printf( "%d) ", p->nCubes ); - } - - pCover = Min_CoverCollect( p, p->nVars ); - assert( p->nCubes == Min_CoverCountCubes(pCover) ); - -// if ( p->nCubes > 1000 ) -// printf( "%d ", p->nCubes ); - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeDeriveEsops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes ) -{ - Min_Cube_t * pCover, * pCube; - Abc_Obj_t * pObj; - int i; - - // set elementary vars - Vec_PtrForEachEntry( vSupp, pObj, i ) - pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 ); - - // get the cover for each node in the array - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - pCover = Abc_NodeDeriveCover( p, - (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy, - (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy, - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); - pObj->pCopy = (Abc_Obj_t *)pCover; - if ( p->nCubes > 3000 ) - return -1; - } - - // add complement if needed - if ( Abc_ObjFaninC0(pRoot) ) - { - if ( pCover && pCover->nLits == 0 ) // topmost one is the tautology cube - { - pCube = pCover; - pCover = pCover->pNext; - Min_CubeRecycle( p, pCube ); - p->nCubes--; - } - else - { - pCube = Min_CubeAlloc( p ); - pCube->pNext = pCover; - p->nCubes++; - } - } -/* - Min_CoverExpand( p, pCover ); - Min_EsopMinimize( p ); - pCover = Min_CoverCollect( p, p->nVars ); -*/ - // clean the copy fields - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = NULL; - Vec_PtrForEachEntry( vSupp, pObj, i ) - pObj->pCopy = NULL; - -// Min_CoverWriteFile( pCover, Abc_ObjName(pRoot), 1 ); -// Min_CoverWrite( stdout, pCover ); - return p->nCubes; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTestEsop( Abc_Ntk_t * pNtk ) -{ - Min_Man_t * p; - Vec_Ptr_t * vSupp, * vNodes; - Abc_Obj_t * pObj; - int i, nCubes; - assert( Abc_NtkIsStrash(pNtk) ); - - Abc_NtkCleanCopy(pNtk); - Abc_NtkForEachCo( pNtk, pObj, i ) - { - if ( !Abc_NodeIsAigAnd(Abc_ObjFanin0(pObj)) ) - { - printf( "%-20s : Trivial.\n", Abc_ObjName(pObj) ); - continue; - } - - vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); - vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); - - printf( "%20s : Cone = %5d. Supp = %5d. ", - Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize ); -// if ( vSupp->nSize <= 128 ) - { - p = Min_ManAlloc( vSupp->nSize ); - nCubes = Abc_NodeDeriveEsops( p, pObj, vSupp, vNodes ); - printf( "Cubes = %5d. ", nCubes ); - Min_ManFree( p ); - } - printf( "\n" ); - - - Vec_PtrFree( vNodes ); - Vec_PtrFree( vSupp ); - } -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - @@ -47,3 +47,10 @@ Other great projects: Other: - completely silent mode + +High-priority changes: + +- add a new mode to "fpga" to differentiate latch-to-latch and pad-to-latch paths +- support asynchronous set/reset in retiming and retiming/mapping +- port "mfs" into ABC +- reduce the latch count in the new version of "retime" and "spfga"
\ No newline at end of file |