diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2006-11-28 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2006-11-28 08:01:00 -0800 |
commit | 44d220d28fa2ee56cb539e03684f021731814f17 (patch) | |
tree | 97ece1e77fa8fff2283c62fb9253424e566e7fba | |
parent | 6ad22b4d3b0446652919d95b15fefb374bddfac0 (diff) | |
download | abc-44d220d28fa2ee56cb539e03684f021731814f17.tar.gz abc-44d220d28fa2ee56cb539e03684f021731814f17.tar.bz2 abc-44d220d28fa2ee56cb539e03684f021731814f17.zip |
Version abc61128
-rw-r--r-- | abc.rc | 2 | ||||
-rw-r--r-- | src/base/abc/abc.h | 1 | ||||
-rw-r--r-- | src/base/abci/abc.c | 64 | ||||
-rw-r--r-- | src/base/abci/abcIf.c | 80 | ||||
-rw-r--r-- | src/base/abci/abcNtbdd.c | 34 | ||||
-rw-r--r-- | src/base/abci/abcSymm.c | 23 | ||||
-rw-r--r-- | src/map/fpga/fpga.c | 4 | ||||
-rw-r--r-- | src/map/fpga/fpgaCore.c | 19 | ||||
-rw-r--r-- | src/map/fpga/fpgaCut.c | 4 | ||||
-rw-r--r-- | src/map/fpga/fpgaMatch.c | 12 | ||||
-rw-r--r-- | src/map/if/if.h | 17 | ||||
-rw-r--r-- | src/map/if/ifCore.c | 68 | ||||
-rw-r--r-- | src/map/if/ifMan.c | 8 | ||||
-rw-r--r-- | src/map/if/ifMap.c | 334 | ||||
-rw-r--r-- | src/map/mapper/mapperCut.c | 3 |
15 files changed, 550 insertions, 123 deletions
@@ -1,7 +1,7 @@ # 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 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 progressbar # display the progress bar diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index c4c42f99..08e1323d 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -648,6 +648,7 @@ extern Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, extern Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk ); extern DdManager * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose ); extern DdManager * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ); +extern int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk ); /*=== abcNtk.c ==========================================================*/ extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan ); extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 9613ab40..4164f67a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -934,8 +934,9 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fUseBdds; int fNaive; + int fReorder; int fVerbose; - extern void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose ); + extern void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fReorder, int fVerbose ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -944,9 +945,10 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults fUseBdds = 0; fNaive = 0; + fReorder = 1; fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "bnvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "bnrvh" ) ) != EOF ) { switch ( c ) { @@ -956,6 +958,9 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'n': fNaive ^= 1; break; + case 'r': + fReorder ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -975,19 +980,22 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "This command works only for combinational networks.\n" ); return 1; } - if ( !Abc_NtkIsStrash(pNtk) ) + if ( Abc_NtkIsStrash(pNtk) ) + Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fReorder, fVerbose ); + else { - fprintf( pErr, "This command works only for AIGs (run \"strash\").\n" ); - return 1; + pNtk = Abc_NtkStrash( pNtk, 0, 0 ); + Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fReorder, fVerbose ); + Abc_NtkDelete( pNtk ); } - Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fVerbose ); return 0; usage: - fprintf( pErr, "usage: print_symm [-nbvh]\n" ); + fprintf( pErr, "usage: print_symm [-bnrvh]\n" ); fprintf( pErr, "\t computes symmetries of the PO functions\n" ); fprintf( pErr, "\t-b : toggle BDD-based or SAT-based computations [default = %s].\n", fUseBdds? "BDD": "SAT" ); fprintf( pErr, "\t-n : enable naive BDD-based computation [default = %s].\n", fNaive? "yes": "no" ); + fprintf( pErr, "\t-r : enable dynamic BDD variable reordering [default = %s].\n", fReorder? "yes": "no" ); fprintf( pErr, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; @@ -7082,7 +7090,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) fRecovery = 1; fSwitching = 0; fLatchPaths = 0; - fVerbose = 0; + fVerbose = 1; DelayTarget =-1; nLutSize =-1; Extra_UtilGetoptReset(); @@ -7383,19 +7391,19 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults memset( pPars, 0, sizeof(If_Par_t) ); - pPars->Mode = 1; - pPars->nLutSize = 4; -// pPars->pLutLib = Abc_FrameReadLibLut(); - pPars->nCutsMax = 2; - pPars->fSeq = 0; - pPars->fLatchPaths = 0; - pPars->nLatches = 0; - pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk); - pPars->pTimesReq = NULL; + pPars->Mode = 0; + pPars->nLutSize = 5; +// pPars->pLutLib = Abc_FrameReadLibLut(); + pPars->nCutsMax = 10; + pPars->fArea = 0; + pPars->fFancy = 0; + pPars->fLatchPaths = 0; + pPars->fSeq = 0; + pPars->nLatches = 0; pPars->DelayTarget = -1; - pPars->fVerbose = 0; + pPars->fVerbose = 1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "MKCDlsvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "MKCDaflsvh" ) ) != EOF ) { switch ( c ) { @@ -7443,6 +7451,12 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->DelayTarget <= 0.0 ) goto usage; break; + case 'a': + pPars->fArea ^= 1; + break; + case 'f': + pPars->fFancy ^= 1; + break; case 'l': pPars->fLatchPaths ^= 1; break; @@ -7467,7 +7481,13 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->Mode < 0 || pPars->Mode > 4 ) { fprintf( pErr, "Incorrect mapping mode.\n" ); - return 1; + goto usage; + } + + if ( pPars->nCutsMax < 2 || pPars->nCutsMax >= (1<<12) ) + { + fprintf( pErr, "Incorrect number of cuts.\n" ); + goto usage; } // set the latch paths @@ -7527,7 +7547,7 @@ usage: sprintf( LutSize, "library" ); else sprintf( LutSize, "%d", pPars->nLutSize ); - fprintf( pErr, "usage: if [-M num] [-K num] [-C num] [-D float] [-lsvh]\n" ); + fprintf( pErr, "usage: if [-M num] [-K num] [-C num] [-D float] [-aflsvh]\n" ); fprintf( pErr, "\t performs FPGA mapping of the network as follows:\n" ); fprintf( pErr, "\t 1 - delay only\n" ); fprintf( pErr, "\t 2 - area only\n" ); @@ -7537,6 +7557,8 @@ usage: fprintf( pErr, "\t-K num : the number of LUT inputs (2 < num < 32) [default = %s]\n", LutSize ); fprintf( pErr, "\t-C num : the max number of cuts to use (1 < num < 2^12) [default = %d]\n", pPars->nCutsMax ); fprintf( pErr, "\t-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer ); + fprintf( pErr, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" ); + fprintf( pErr, "\t-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" ); fprintf( pErr, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", pPars->fLatchPaths? "yes": "no" ); fprintf( pErr, "\t-s : toggles sequential mapping [default = %s]\n", pPars->fSeq? "yes": "no" ); fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); diff --git a/src/base/abci/abcIf.c b/src/base/abci/abcIf.c index 6b3e0e7c..70971952 100644 --- a/src/base/abci/abcIf.c +++ b/src/base/abci/abcIf.c @@ -29,6 +29,7 @@ static If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars ); static Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk ); static Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t * pIfObj ); static Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Cut_t * pCut ); +static Hop_Obj_t * Abc_NodeIfToHop2( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -56,6 +57,10 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars ) if ( Abc_NtkGetChoiceNum( pNtk ) ) printf( "Performing FPGA mapping with choices.\n" ); + // get timing information + pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk); + pPars->pTimesReq = NULL; + // perform FPGA mapping pIfMan = Abc_NtkToIf( pNtk, pPars ); if ( pIfMan == NULL ) @@ -115,7 +120,7 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars ) pNode->pCopy = (Abc_Obj_t *)If_ManCreatePi( pIfMan ); // load the AIG into the mapper - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) ); + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) ); Abc_AigForEachAnd( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); @@ -212,7 +217,8 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i ) Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf) ); // derive the function of this node - pNodeNew->pData = Abc_NodeIfToHop( pNtkNew->pManFunc, pIfMan, pCutBest ); +// pNodeNew->pData = Abc_NodeIfToHop( pNtkNew->pManFunc, pIfMan, pCutBest ); + pNodeNew->pData = Abc_NodeIfToHop2( pNtkNew->pManFunc, pIfMan, pIfObj ); If_ObjSetCopy( pIfObj, pNodeNew ); return pNodeNew; } @@ -280,6 +286,76 @@ Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Cut_t * return gFunc; } + +/**Function************************************************************* + + Synopsis [Recursively derives the truth table for the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Hop_Obj_t * Abc_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited ) +{ + If_Cut_t * pCut; + Hop_Obj_t * gFunc, * gFunc0, * gFunc1; + // get the best cut + pCut = If_ObjCutTriv(pIfObj); + // if the cut is visited, return the result + if ( If_CutData(pCut) ) + return If_CutData(pCut); + // compute the functions of the children + gFunc0 = Abc_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj->pFanin0, vVisited ); + gFunc1 = Abc_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj->pFanin1, vVisited ); + // get the function of the cut + gFunc = Hop_And( pHopMan, Hop_NotCond(gFunc0, pIfObj->fCompl0), Hop_NotCond(gFunc1, pIfObj->fCompl1) ); + gFunc = Hop_NotCond( gFunc, pCut->Phase ); + assert( If_CutData(pCut) == NULL ); + If_CutSetData( pCut, gFunc ); + // add this cut to the visited list + Vec_PtrPush( vVisited, pCut ); + return gFunc; +} + +/**Function************************************************************* + + Synopsis [Derives the truth table for one cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Hop_Obj_t * Abc_NodeIfToHop2( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj ) +{ + If_Cut_t * pCut; + Hop_Obj_t * gFunc; + If_Obj_t * pLeaf; + int i; + // get the best cut + pCut = If_ObjCutBest(pIfObj); + assert( pCut->nLeaves > 1 ); + // set the leaf variables + If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) + If_CutSetData( If_ObjCutTriv(pLeaf), Hop_IthVar(pHopMan, i) ); + // recursively compute the function while collecting visited cuts + Vec_PtrClear( pIfMan->vTemp ); + gFunc = Abc_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp ); +// printf( "%d ", Vec_PtrSize(p->vTemp) ); + // clean the cuts + If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) + If_CutSetData( If_ObjCutTriv(pLeaf), NULL ); + Vec_PtrForEachEntry( pIfMan->vTemp, pCut, i ) + If_CutSetData( pCut, NULL ); + return gFunc; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c index bd035eb0..fd5a38e1 100644 --- a/src/base/abci/abcNtbdd.c +++ b/src/base/abci/abcNtbdd.c @@ -269,15 +269,16 @@ DdManager * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDrop pObj = Abc_AigConst1(pNtk); if ( Abc_ObjFanoutNum(pObj) > 0 ) { - Abc_ObjSetGlobalBdd( pObj, dd->one ); - Cudd_Ref( dd->one ); + bFunc = dd->one; + Abc_ObjSetGlobalBdd( pObj, bFunc ); Cudd_Ref( bFunc ); } // set the elementary variables Abc_NtkForEachCi( pNtk, pObj, i ) if ( Abc_ObjFanoutNum(pObj) > 0 ) { - Abc_ObjSetGlobalBdd( pObj, dd->vars[i] ); - Cudd_Ref( dd->vars[i] ); + bFunc = dd->vars[i]; +// bFunc = dd->vars[Abc_NtkCiNum(pNtk) - 1 - i]; + Abc_ObjSetGlobalBdd( pObj, bFunc ); Cudd_Ref( bFunc ); } // collect the global functions of the COs @@ -462,6 +463,31 @@ DdManager * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ) /**Function************************************************************* + Synopsis [Returns the shared size of global BDDs of the COs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vFuncsGlob; + Abc_Obj_t * pObj; + int RetValue, i; + // complement the global functions + vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pObj, i ) + Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) ); + RetValue = Cudd_SharingSize( (DdNode **)Vec_PtrArray(vFuncsGlob), Vec_PtrSize(vFuncsGlob) ); + Vec_PtrFree( vFuncsGlob ); + return RetValue; +} + +/**Function************************************************************* + Synopsis [Computes the BDD of the logic cone of the node.] Description [] diff --git a/src/base/abci/abcSymm.c b/src/base/abci/abcSymm.c index d3fcb7c9..0f76065c 100644 --- a/src/base/abci/abcSymm.c +++ b/src/base/abci/abcSymm.c @@ -24,7 +24,7 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose ); +static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int fVerbose ); static void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose ); static void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose ); static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms ); @@ -44,10 +44,10 @@ static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms ) SeeAlso [] ***********************************************************************/ -void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose ) +void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fReorder, int fVerbose ) { - if ( fUseBdds ) - Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fVerbose ); + if ( fUseBdds || fNaive ) + Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fReorder, fVerbose ); else Abc_NtkSymmetriesUsingSandS( pNtk, fVerbose ); } @@ -81,15 +81,19 @@ void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose ) SeeAlso [] ***********************************************************************/ -void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose ) +void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int fVerbose ) { DdManager * dd; int clk, clkBdd, clkSym; + int fGarbCollect = 1; // compute the global functions clk = clock(); - dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); + dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, fVerbose ); + printf( "Shared BDD size = %d nodes.\n", Abc_NtkSizeOfGlobalBdds(pNtk) ); Cudd_AutodynDisable( dd ); + if ( !fGarbCollect ) + Cudd_DisableGarbageCollection( dd ); Cudd_zddVarsFromBddVars( dd, 2 ); clkBdd = clock() - clk; // create the collapsed network @@ -97,11 +101,10 @@ clk = clock(); Ntk_NetworkSymmsBdd( dd, pNtk, fNaive, fVerbose ); clkSym = clock() - clk; // undo the global functions -// Abc_NtkFreeGlobalBdds( pNtk ); -// Extra_StopManager( dd ); -// pNtk->pManGlob = NULL; Abc_NtkFreeGlobalBdds( pNtk, 1 ); - +printf( "Statistics of BDD-based symmetry detection:\n" ); +printf( "Algorithm = %s. Reordering = %s. Garbage collection = %s.\n", + fNaive? "naive" : "fast", fReorder? "yes" : "no", fGarbCollect? "yes" : "no" ); PRT( "Constructing BDDs", clkBdd ); PRT( "Computing symms ", clkSym ); PRT( "TOTAL ", clkBdd + clkSym ); diff --git a/src/map/fpga/fpga.c b/src/map/fpga/fpga.c index d04c9910..d7a128b0 100644 --- a/src/map/fpga/fpga.c +++ b/src/map/fpga/fpga.c @@ -57,8 +57,8 @@ void Fpga_Init( Abc_Frame_t * pAbc ) { // set the default library //Fpga_LutLib_t s_LutLib = { "lutlib", 6, {0,1,2,4,8,16,32}, {0,1,2,3,4,5,6} }; -// Fpga_LutLib_t s_LutLib = { "lutlib", 5, {0,1,1,1,1,1}, {0,1,1,1,1,1} }; - Fpga_LutLib_t s_LutLib = { "lutlib", 4, {0,1,1,1,1}, {0,1,1,1,1} }; + Fpga_LutLib_t s_LutLib = { "lutlib", 5, {0,1,1,1,1,1}, {0,1,1,1,1,1} }; +// Fpga_LutLib_t s_LutLib = { "lutlib", 4, {0,1,1,1,1}, {0,1,1,1,1} }; //Fpga_LutLib_t s_LutLib = { "lutlib", 3, {0,1,1,1}, {0,1,1,1} }; Abc_FrameSetLibLut( Fpga_LutLibDup(&s_LutLib) ); diff --git a/src/map/fpga/fpgaCore.c b/src/map/fpga/fpgaCore.c index 56facf20..634a8eb1 100644 --- a/src/map/fpga/fpgaCore.c +++ b/src/map/fpga/fpgaCore.c @@ -79,8 +79,12 @@ int Fpga_Mapping( Fpga_Man_t * p ) // print the AI-graph used for mapping //Fpga_ManShow( p, "test" ); +// if ( p->fVerbose ) +// Fpga_MappingPrintOutputArrivals( p ); if ( p->fVerbose ) - Fpga_MappingPrintOutputArrivals( p ); + { + PRT( "Total time", clock() - clkTotal ); + } return 1; } @@ -101,14 +105,14 @@ int Fpga_Mapping( Fpga_Man_t * p ) ***********************************************************************/ int Fpga_MappingPostProcess( Fpga_Man_t * p ) { - int fShowSwitching = 1; + int fShowSwitching = 0; int fRecoverAreaFlow = 1; int fRecoverArea = 1; float aAreaTotalCur, aAreaTotalCur2; int Iter, clk; -if ( p->fVerbose ) - printf( "Best clock period = %5.2f\n", Fpga_TimeComputeArrivalMax(p) ); +//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; @@ -118,6 +122,9 @@ if ( p->fVerbose ) printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); +else +printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); + PRT( "Time", p->timeMatch ); } @@ -141,6 +148,8 @@ if ( p->fVerbose ) printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); +else +printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); PRT( "Time", clock() - clk ); } } @@ -166,6 +175,8 @@ if ( p->fVerbose ) printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->fSwitching?"S":"A"), aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); +else +printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); PRT( "Time", clock() - clk ); } } diff --git a/src/map/fpga/fpgaCut.c b/src/map/fpga/fpgaCut.c index c2aba4a3..a5505e72 100644 --- a/src/map/fpga/fpgaCut.c +++ b/src/map/fpga/fpgaCut.c @@ -130,6 +130,7 @@ void Fpga_MappingCuts( Fpga_Man_t * p ) Fpga_CutTable_t * pTable; Fpga_Node_t * pNode; int nCuts, nNodes, i; + int clk = clock(); // set the elementary cuts for the PI variables assert( p->nVarsMax > 1 && p->nVarsMax < 11 ); @@ -154,8 +155,9 @@ void Fpga_MappingCuts( Fpga_Man_t * p ) if ( p->fVerbose ) { nCuts = Fpga_CutCountAll(p); - printf( "Nodes = %6d. Total %d-feasible cuts = %d. Cuts per node = %.1f.\n", + printf( "Nodes = %6d. Total %d-cuts = %d. Cuts per node = %.1f. ", p->nNodes, p->nVarsMax, nCuts, ((float)nCuts)/p->nNodes ); + PRT( "Time", clock() - clk ); } // print the cuts for the first primary output diff --git a/src/map/fpga/fpgaMatch.c b/src/map/fpga/fpgaMatch.c index 736d38b2..d413a067 100644 --- a/src/map/fpga/fpgaMatch.c +++ b/src/map/fpga/fpgaMatch.c @@ -87,6 +87,18 @@ int Fpga_MappingMatches( Fpga_Man_t * p, int fDelayOriented ) Extra_ProgressBarUpdate( pProgress, i, "Matches ..." ); } Extra_ProgressBarStop( pProgress ); +/* + if ( !fDelayOriented ) + { + float Area = 0.0; + for ( i = 0; i < p->nOutputs; i++ ) + { + printf( "%5.2f ", Fpga_Regular(p->pOutputs[i])->pCutBest->aFlow ); + Area += Fpga_Regular(p->pOutputs[i])->pCutBest->aFlow; + } + printf( "\nTotal = %5.2f\n", Area ); + } +*/ return 1; } diff --git a/src/map/if/if.h b/src/map/if/if.h index 04e1541e..a1d2d41b 100644 --- a/src/map/if/if.h +++ b/src/map/if/if.h @@ -75,8 +75,10 @@ struct If_Par_t_ If_Lib_t * pLutLib; // the LUT library int nCutsMax; // the max number of cuts int fVerbose; // the verbosity flag - int fSeq; // sequential mapping + int fArea; // area-oriented mapping + int fFancy; // a fancy feature int fLatchPaths; // reset timing on latch paths + int fSeq; // sequential mapping int nLatches; // the number of latches float DelayTarget; // delay target float * pTimesArr; // arrival times @@ -110,6 +112,9 @@ struct If_Man_t_ float fEpsilon; // epsilon used for comparison float RequiredGlo; // global required times float AreaGlo; // global area + int nCutsUsed; // the number of cuts currently used + int nCutsMerged; // the total number of cuts merged + int nCutsMax; // the maximum number of cuts at a node // memory management Mem_Fixed_t * pMem; // memory manager int nEntrySize; // the size of the entry @@ -123,7 +128,6 @@ struct If_Man_t_ struct If_Cut_t_ { float Delay; // the delay of the cut - float Flow; // the area flow of the cut float Area; // the area of the cut If_Cut_t * pOne; // the parent cut If_Cut_t * pTwo; // the parent cut @@ -162,6 +166,10 @@ static inline If_Obj_t * If_ManPo( If_Man_t * p, int i ) { r static inline If_Obj_t * If_ManObj( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vObjs, i ); } static inline If_Cut_t * If_ManCut( If_Man_t * p, int i ) { return p->ppCuts[i]; } +static inline int If_ManPiNum( If_Man_t * p ) { return p->nObjs[IF_PI]; } +static inline int If_ManPoNum( If_Man_t * p ) { return p->nObjs[IF_PO]; } +static inline int If_ManAndNum( If_Man_t * p ) { return p->nObjs[IF_AND]; } + static inline int If_ObjIsConst1( If_Obj_t * pObj ) { return pObj->Type == IF_CONST1; } static inline int If_ObjIsPi( If_Obj_t * pObj ) { return pObj->Type == IF_PI; } static inline int If_ObjIsPo( If_Obj_t * pObj ) { return pObj->Type == IF_PO; } @@ -229,6 +237,8 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/*=== ifCore.c ==========================================================*/ +extern int If_ManPerformMapping( If_Man_t * p ); /*=== ifMan.c ==========================================================*/ extern If_Man_t * If_ManStart( If_Par_t * pPars ); extern void If_ManStop( If_Man_t * p ); @@ -236,11 +246,12 @@ extern If_Obj_t * If_ManCreatePi( If_Man_t * p ); extern If_Obj_t * If_ManCreatePo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 ); extern If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_t * pFan1, int fCompl1 ); /*=== ifMap.c ==========================================================*/ -extern int If_ManPerformMapping( If_Man_t * p ); +extern void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode ); /*=== ifUtil.c ==========================================================*/ extern float If_ManDelayMax( If_Man_t * p ); extern void If_ManCleanNodeCopy( If_Man_t * p ); extern void If_ManCleanCutData( If_Man_t * p ); +extern void If_ManComputeRequired( If_Man_t * p, int fFirstTime ); extern float If_ManScanMapping( If_Man_t * p ); #ifdef __cplusplus diff --git a/src/map/if/ifCore.c b/src/map/if/ifCore.c index 4d7e92d0..37a22d8b 100644 --- a/src/map/if/ifCore.c +++ b/src/map/if/ifCore.c @@ -24,6 +24,8 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -39,6 +41,72 @@ SeeAlso [] ***********************************************************************/ +int If_ManPerformMapping( If_Man_t * p ) +{ + If_Obj_t * pObj; + int nItersFlow = 2; + int nItersArea = 1; + int clkTotal = clock(); + int i; + // set arrival times and trivial cuts at const 1 and PIs + If_ManConst1(p)->Cuts[0].Delay = 0.0; + If_ManForEachPi( p, pObj, i ) + pObj->Cuts[0].Delay = p->pPars->pTimesArr[i]; + // set the fanout estimates of the PIs + If_ManForEachPi( p, pObj, i ) + pObj->EstRefs = (float)1.0; + // delay oriented mapping + If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0 ); + // area flow oriented mapping + for ( i = 0; i < nItersFlow; i++ ) + If_ManPerformMappingRound( p, p->pPars->nCutsMax, 1 ); + // area oriented mapping + for ( i = 0; i < nItersArea; i++ ) + If_ManPerformMappingRound( p, p->pPars->nCutsMax, 2 ); + if ( p->pPars->fVerbose ) + { + PRT( "Total time", clock() - clkTotal ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode ) +{ + If_Obj_t * pObj; + int i, clk = clock(); + assert( Mode >= 0 && Mode <= 2 ); + // set the cut number + p->nCutsUsed = nCutsUsed; + p->nCutsMerged = 0; + p->nCutsMax = 0; + // map the internal nodes + If_ManForEachNode( p, pObj, i ) + If_ObjPerformMapping( p, pObj, Mode ); + // compute required times and stats + If_ManComputeRequired( p, Mode==0 ); + if ( p->pPars->fVerbose ) + { + char Symb = (Mode == 0)? 'D' : ((Mode == 1)? 'F' : 'A'); + printf( "%c: Del = %6.2f. Area = %8.2f. Cuts = %6d. Lim = %2d. Ave = %5.2f. ", + Symb, p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) ); + PRT( "T", clock() - clk ); +// printf( "Max number of cuts = %d. Average number of cuts = %5.2f.\n", +// p->nCutsMax, 1.0 * p->nCutsMerged / If_ManAndNum(p) ); + } + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/map/if/ifMan.c b/src/map/if/ifMan.c index 616c5cf6..bc13c6f0 100644 --- a/src/map/if/ifMan.c +++ b/src/map/if/ifMan.c @@ -97,7 +97,7 @@ void If_ManStop( If_Man_t * p ) FREE( p->pPars->pTimesReq ); // free temporary cut memory pTemp = p->ppCuts[0]; - for ( i = 1; i < p->pPars->nCutsMax * p->pPars->nCutsMax; i++ ) + for ( i = 1; i < 1 + p->pPars->nCutsMax * p->pPars->nCutsMax; i++ ) if ( pTemp > p->ppCuts[i] ) pTemp = p->ppCuts[i]; free( pTemp ); @@ -228,14 +228,18 @@ If_Cut_t ** If_ManSetupCuts( If_Man_t * p ) { If_Cut_t ** pCutStore; int * pArrays, nCutSize, nCutsTotal, i; - nCutsTotal = p->pPars->nCutsMax * p->pPars->nCutsMax; + // decide how many cuts to alloc + nCutsTotal = 1 + p->pPars->nCutsMax * p->pPars->nCutsMax; + // figure out the cut size nCutSize = sizeof(If_Cut_t) + sizeof(int) * p->pPars->nLutSize; + // allocate and clean space for cuts pCutStore = (If_Cut_t **)ALLOC( If_Cut_t *, (nCutsTotal + 1) ); memset( pCutStore, 0, sizeof(If_Cut_t *) * (nCutsTotal + 1) ); pCutStore[0] = (If_Cut_t *)ALLOC( char, nCutSize * nCutsTotal ); memset( pCutStore[0], 0, nCutSize * nCutsTotal ); for ( i = 1; i < nCutsTotal; i++ ) pCutStore[i] = (If_Cut_t *)((char *)pCutStore[0] + sizeof(If_Cut_t) * i); + // assign room for cut leaves pArrays = (int *)((char *)pCutStore[0] + sizeof(If_Cut_t) * nCutsTotal); for ( i = 0; i < nCutsTotal; i++ ) pCutStore[i]->pLeaves = pArrays + i * p->pPars->nLutSize; diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c index 5f2c4133..0b505062 100644 --- a/src/map/if/ifMap.c +++ b/src/map/if/ifMap.c @@ -24,13 +24,69 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/* + Ideas to try: + - reverse order of area recovery + - ordering of the outputs by size + - merging Delay, Delay2, and Area + - expand/reduce area recovery + +*/ + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Prepares the object for FPGA mapping.] + Synopsis [Returns 1 if pDom is contained in pCut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut ) +{ + int i, k; + for ( i = 0; i < (int)pDom->nLeaves; i++ ) + { + for ( k = 0; k < (int)pCut->nLeaves; k++ ) + if ( pDom->pLeaves[i] == pCut->pLeaves[k] ) + break; + if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut + return 0; + } + // every node in pDom is contained in pCut + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pDom is equal to pCut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int If_CutCheckEquality( If_Cut_t * pDom, If_Cut_t * pCut ) +{ + int i; + if ( (int)pDom->nLeaves != (int)pCut->nLeaves ) + return 0; + for ( i = 0; i < (int)pDom->nLeaves; i++ ) + if ( pDom->pLeaves[i] != pCut->pLeaves[i] ) + return 0; + return 1; +} +/**Function************************************************************* + + Synopsis [Returns 1 if the cut is contained.] Description [] @@ -39,8 +95,39 @@ SeeAlso [] ***********************************************************************/ -int If_CutMerge( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit ) +int If_CutFilter( If_Man_t * p, If_Cut_t * pCut ) { + If_Cut_t * pTemp; + int i; + for ( i = 0; i < p->nCuts; i++ ) + { + pTemp = p->ppCuts[i]; + if ( pTemp->nLeaves > pCut->nLeaves ) + continue; + // skip the non-contained cuts +// if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign ) +// continue; + // check containment seriously + if ( If_CutCheckDominance( pTemp, pCut ) ) +// if ( If_CutCheckEquality( pTemp, pCut ) ) + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Prepares the object for FPGA mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int If_CutMergeOrdered( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit ) +{ int i, k, c; assert( pC0->nLeaves >= pC1->nLeaves ); // the case of the largest cut sizes @@ -125,6 +212,33 @@ int If_CutMerge( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit ) SeeAlso [] ***********************************************************************/ +static inline int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut, int nLimit ) +{ + // merge the nodes + if ( pCut0->nLeaves < pCut1->nLeaves ) + { + if ( !If_CutMergeOrdered( pCut1, pCut0, pCut, nLimit ) ) + return 0; + } + else + { + if ( !If_CutMergeOrdered( pCut0, pCut1, pCut, nLimit ) ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Prepares the object for FPGA mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int If_CutCompareDelay( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) { If_Cut_t * pC0 = *ppC0; @@ -137,9 +251,39 @@ int If_CutCompareDelay( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) return -1; if ( pC0->nLeaves > pC1->nLeaves ) return 1; - if ( pC0->Flow < pC1->Flow ) + if ( pC0->Area < pC1->Area ) return -1; - if ( pC0->Flow > pC1->Flow ) + if ( pC0->Area > pC1->Area ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Prepares the object for FPGA mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int If_CutCompareDelayOld( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) +{ + If_Cut_t * pC0 = *ppC0; + If_Cut_t * pC1 = *ppC1; + if ( pC0->Delay < pC1->Delay ) + return -1; + if ( pC0->Delay > pC1->Delay ) + return 1; + if ( pC0->Area < pC1->Area ) + return -1; + if ( pC0->Area > pC1->Area ) + return 1; + if ( pC0->nLeaves < pC1->nLeaves ) + return -1; + if ( pC0->nLeaves > pC1->nLeaves ) return 1; return 0; } @@ -159,9 +303,9 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) { If_Cut_t * pC0 = *ppC0; If_Cut_t * pC1 = *ppC1; - if ( pC0->Flow < pC1->Flow ) + if ( pC0->Area < pC1->Area ) return -1; - if ( pC0->Flow > pC1->Flow ) + if ( pC0->Area > pC1->Area ) return 1; if ( pC0->nLeaves < pC1->nLeaves ) return -1; @@ -176,6 +320,28 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) /**Function************************************************************* + Synopsis [Sorts the cuts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void If_ManSortCuts( If_Man_t * p, int Mode ) +{ + // sort the cuts + if ( Mode || p->pPars->fArea ) // area + qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea ); + else if ( p->pPars->fFancy ) + qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelayOld ); + else + qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay ); +} + +/**Function************************************************************* + Synopsis [Computes delay.] Description [] @@ -190,6 +356,7 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut ) If_Obj_t * pLeaf; float Delay; int i; + assert( pCut->nLeaves > 1 ); Delay = -IF_FLOAT_LARGE; If_CutForEachLeaf( p, pCut, pLeaf, i ) Delay = IF_MAX( Delay, If_ObjCutBest(pLeaf)->Delay ); @@ -212,9 +379,18 @@ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut ) If_Obj_t * pLeaf; float Flow; int i; + assert( pCut->nLeaves > 1 ); Flow = If_CutLutArea(p, pCut); If_CutForEachLeaf( p, pCut, pLeaf, i ) - Flow += If_ObjCutBest(pLeaf)->Flow / pLeaf->EstRefs; + { + if ( pLeaf->nRefs == 0 ) + Flow += If_ObjCutBest(pLeaf)->Area; + else + { + assert( pLeaf->EstRefs > p->fEpsilon ); + Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs; + } + } return Flow; } @@ -229,15 +405,19 @@ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -float If_CutArea1( If_Man_t * p, If_Cut_t * pCut ) +float If_CutRef( If_Man_t * p, If_Cut_t * pCut, int nLevels ) { If_Obj_t * pLeaf; float Area; int i; Area = If_CutLutArea(p, pCut); If_CutForEachLeaf( p, pCut, pLeaf, i ) - if ( pLeaf->nRefs == 0 ) - Area += If_CutLutArea(p, If_ObjCutBest(pLeaf)); + { + assert( pLeaf->nRefs >= 0 ); + if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 ) + continue; + Area += If_CutRef( p, If_ObjCutBest(pLeaf), nLevels - 1 ); + } return Area; } @@ -252,12 +432,20 @@ float If_CutArea1( If_Man_t * p, If_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -void If_CutRef1( If_Man_t * p, If_Cut_t * pCut ) +float If_CutDeref( If_Man_t * p, If_Cut_t * pCut, int nLevels ) { If_Obj_t * pLeaf; + float Area; int i; + Area = If_CutLutArea(p, pCut); If_CutForEachLeaf( p, pCut, pLeaf, i ) - pLeaf->nRefs++; + { + assert( pLeaf->nRefs > 0 ); + if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 ) + continue; + Area += If_CutDeref( p, If_ObjCutBest(pLeaf), nLevels - 1 ); + } + return Area; } /**Function************************************************************* @@ -271,12 +459,14 @@ void If_CutRef1( If_Man_t * p, If_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -void If_CutDeref1( If_Man_t * p, If_Cut_t * pCut ) +float If_CutArea( If_Man_t * p, If_Cut_t * pCut, int nLevels ) { - If_Obj_t * pLeaf; - int i; - If_CutForEachLeaf( p, pCut, pLeaf, i ) - pLeaf->nRefs--; + float aResult, aResult2; + assert( pCut->nLeaves > 1 ); + aResult2 = If_CutRef( p, pCut, nLevels ); + aResult = If_CutDeref( p, pCut, nLevels ); + assert( aResult == aResult2 ); + return aResult; } /**Function************************************************************* @@ -303,85 +493,85 @@ void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc ) Synopsis [Finds the best cut.] - Description [] + Description [Mapping modes: delay (0), area flow (1), area (2).] SideEffects [] SeeAlso [] ***********************************************************************/ -void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj ) +void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode ) { If_Cut_t * pCut0, * pCut1, * pCut; int i, k; - // create cross-product of the cuts + + // prepare + if ( Mode == 0 ) + pObj->EstRefs = (float)pObj->nRefs; + else if ( Mode == 1 ) + pObj->EstRefs = (float)((2.0 * pObj->EstRefs + pObj->nRefs) / 3.0); + else if ( Mode == 2 && pObj->nRefs > 0 ) + If_CutDeref( p, If_ObjCutBest(pObj), 100 ); + + // recompute the parameters of the best cut p->nCuts = 0; - pCut = p->ppCuts[0]; + p->nCutsMerged++; + if ( Mode ) + { + pCut = If_ObjCutBest(pObj); + pCut->Delay = If_CutDelay( p, pCut ); + assert( pCut->Delay <= pObj->Required + p->fEpsilon ); + pCut->Area = (Mode == 2)? If_CutArea( p, pCut, 100 ) : If_CutFlow( p, pCut ); + // save the best cut from the previous iteration + If_CutCopy( p->ppCuts[p->nCuts++], pCut ); + p->nCutsMerged++; + } + + // generate cuts + pCut = p->ppCuts[p->nCuts]; If_ObjForEachCut( pObj->pFanin0, pCut0, i ) If_ObjForEachCut( pObj->pFanin1, pCut1, k ) { - if ( pCut0->nLeaves < pCut1->nLeaves ) - { - if ( !If_CutMerge( pCut1, pCut0, pCut, p->pPars->nLutSize ) ) - continue; - } - else - { - if ( !If_CutMerge( pCut0, pCut1, pCut, p->pPars->nLutSize ) ) - continue; - } + // prefilter using arrival times + if ( Mode && (pCut0->Delay > pObj->Required + p->fEpsilon || pCut1->Delay > pObj->Required + p->fEpsilon) ) + continue; + // merge the nodes + if ( !If_CutMerge( pCut0, pCut1, pCut, p->pPars->nLutSize ) ) + continue; + // check if this cut is contained in any of the available cuts + if ( If_CutFilter( p, pCut ) ) + continue; + // check if the cut satisfies the required times + pCut->Delay = If_CutDelay( p, pCut ); + if ( Mode && pCut->Delay > pObj->Required + p->fEpsilon ) + continue; // the cuts have been successfully merged pCut->pOne = pCut0; pCut->fCompl0 = pObj->fCompl0; pCut->pTwo = pCut1; pCut->fCompl1 = pObj->fCompl1; // pCut->Phase = ... - pCut->Delay = If_CutDelay( p, pCut ); - pCut->Flow = If_CutFlow( p, pCut ); + pCut->Area = (Mode == 2)? If_CutArea( p, pCut, 100 ) : If_CutFlow( p, pCut ); + p->nCutsMerged++; // prepare room for the next cut pCut = p->ppCuts[++p->nCuts]; } - // sort the cuts - if ( p->pPars->Mode == 1 ) // delay - qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay ); - else - qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea ); + assert( p->nCuts > 0 ); + If_ManSortCuts( p, Mode ); // take the first - pObj->nCuts = IF_MIN( p->nCuts + 1, p->pPars->nCutsMax ); + pObj->nCuts = IF_MIN( p->nCuts + 1, p->nCutsUsed ); If_ObjForEachCutStart( pObj, pCut, i, 1 ) If_CutCopy( pCut, p->ppCuts[i-1] ); pObj->iCut = 1; -} - -/**Function************************************************************* - - Synopsis [Maps the nodes for delay.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int If_ManPerformMapping( If_Man_t * p ) -{ - If_Obj_t * pObj; - float DelayBest; - int i, clk = clock(); - // set arrival times and trivial cuts at const 1 and PIs - If_ManConst1(p)->Cuts[0].Delay = 0.0; - If_ManForEachPi( p, pObj, i ) - pObj->Cuts[0].Delay = p->pPars->pTimesArr[i]; - // set the initial fanout estimates - If_ManForEachObj( p, pObj, i ) - pObj->EstRefs = (float)pObj->nRefs; - // map the internal nodes - If_ManForEachNode( p, pObj, i ) - If_ObjPerformMapping( p, pObj ); - // get the best arrival time of the POs - DelayBest = If_ManDelayMax(p); - printf( "Best delay = %d. ", (int)DelayBest ); - PRT( "Time", clock() - clk ); - return 1; + assert( If_ObjCutBest(pObj)->nLeaves > 1 ); + // assign delay of the trivial cut + If_ObjCutTriv(pObj)->Delay = If_ObjCutBest(pObj)->Delay; +//printf( "%d %d ", pObj->Id, (int)If_ObjCutBest(pObj)->Delay ); +//printf( "%d %d ", pObj->Id, pObj->nCuts ); + // ref the selected cut + if ( Mode == 2 && pObj->nRefs > 0 ) + If_CutRef( p, If_ObjCutBest(pObj), 100 ); + // find the largest cut + if ( p->nCutsMax < pObj->nCuts ) + p->nCutsMax = pObj->nCuts; } //////////////////////////////////////////////////////////////////////// diff --git a/src/map/mapper/mapperCut.c b/src/map/mapper/mapperCut.c index 9dad07d0..91ef6562 100644 --- a/src/map/mapper/mapperCut.c +++ b/src/map/mapper/mapperCut.c @@ -612,7 +612,8 @@ int Map_CutMergeTwo( Map_Cut_t * pCut1, Map_Cut_t * pCut2, Map_Node_t * ppNodes[ { min = i; for ( k = i+1; k < nTotal; k++ ) - if ( ppNodes[k] < ppNodes[min] ) +// if ( ppNodes[k] < ppNodes[min] ) // reported bug fix (non-determinism!) + if ( ppNodes[k]->Num < ppNodes[min]->Num ) min = k; pNodeTemp = ppNodes[i]; ppNodes[i] = ppNodes[min]; |