diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index e733bccad..682d7b171 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -1190,7 +1190,7 @@ int Gia_ManFromIfLogicCreateLutSpecialJ( Gia_Man_t * pNew, word * pRes, Vec_Int_ { word Truth; int i, iObjLit1, iObjLit2, iObjLit3; - word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1 ); + word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1, 0 ); assert( z != 0 ); if ( ((z >> 63) & 1) == 0 ) { @@ -2135,7 +2135,7 @@ void Gia_ManConfigPrint2( unsigned char * pConfigData, int nLeaves ) SeeAlso [] ***********************************************************************/ -void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * pTruth, int nLeaves ) +void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * pTruth, int nLeaves, int fDelay ) { int i, CellId; int startPos = Vec_StrSize(vConfigs2); @@ -2143,13 +2143,18 @@ void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * p // Determine cell type based on the number of leaves and configuration if ( nLeaves <= 4 ) // 7 bytes = 1 byte CellId + 4 bytes mapping + 2 bytes truth table { + word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1, fDelay ); + int fHavePerm = (z != 0) && ((z & ABC_CONST(0x4000000000000000)) != 0); // Cell type 0: Simple LUT4 CellId = 0; // Write CellId Vec_StrPush( vConfigs2, (char)CellId ); // Write mapping for ( i = 0; i < nLeaves; i++ ) - Vec_StrPush( vConfigs2, 2+i ); + { + int v = fHavePerm ? (int)((z >> (2 * i)) & 3) : i; + Vec_StrPush( vConfigs2, 2 + v ); + } for ( ; i < 4; i++ ) Vec_StrPush( vConfigs2, 0 ); // Write truth table (16 bits for LUT4) @@ -2161,7 +2166,7 @@ void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * p } else // 12 bytes = 1 byte CellId + 7 bytes mapping + 4 bytes truth tables { - word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1 ); + word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1, fDelay ); //Gia_ManConfigPrint( 0, z, nLeaves ); if ( ((z >> 63) & 1) == 0 ) { @@ -2551,7 +2556,16 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan ) Abc_TtFlip( pTruth, Abc_TtWordNum(pCutBest->nLeaves), k ); if ( Abc_LitIsCompl(pIfObj->iCopy) ^ pCutBest->fCompl ) Abc_TtNot( pTruth, Abc_TtWordNum(pCutBest->nLeaves) ); - Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pTruth, pCutBest->nLeaves ); + if ( pIfMan->pPars->fDelayOptCell ) + { + pIfMan->nCutLeavesCur = pCutBest->nLeaves; + If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k ) + { + pIfMan->pCutLeavesCur[k] = pIfLeaf->Id; + pIfMan->pCutLeafArrCur[k] = If_ObjCutBest(pIfLeaf)->Delay; + } + } + Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pTruth, pCutBest->nLeaves, pIfMan->pPars->fDelayOptCell ); } } else @@ -3337,4 +3351,3 @@ Gia_Man_t * Gia_ManDupUnhashMapping( Gia_Man_t * p ) ABC_NAMESPACE_IMPL_END - diff --git a/src/aig/gia/giaSpeedup.c b/src/aig/gia/giaSpeedup.c index 4212c8966..e5caba8fc 100644 --- a/src/aig/gia/giaSpeedup.c +++ b/src/aig/gia/giaSpeedup.c @@ -33,6 +33,54 @@ ABC_NAMESPACE_IMPL_START /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +static int Gia_ManConfig2GetBytePos( Gia_Man_t * p, int iObj ) +{ + int iLut, bytePos = 0; + if ( p == NULL || p->vConfigs2 == NULL ) + return -1; + Gia_ManForEachLut( p, iLut ) + { + unsigned char CellId; + if ( bytePos >= Vec_StrSize(p->vConfigs2) ) + return -1; + if ( iLut == iObj ) + return bytePos; + CellId = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos ); + if ( CellId == 0 ) + bytePos += 7; + else if ( CellId == 1 ) + bytePos += 12; + else if ( CellId == 2 ) + bytePos += 14; + else + return -1; + } + return -1; +} +static int Gia_ManConfig2DerivePinDelays( Gia_Man_t * p, int iObj, If_LibCell_t * pCellLib, int * pPinDelay, int nLutSize ) +{ + int bytePos, i, nPins; + unsigned char CellId; + if ( pCellLib == NULL || pPinDelay == NULL || nLutSize < 1 || nLutSize > 32 ) + return 0; + for ( i = 0; i < nLutSize; i++ ) + pPinDelay[i] = 1; + bytePos = Gia_ManConfig2GetBytePos( p, iObj ); + if ( bytePos < 0 || bytePos >= Vec_StrSize(p->vConfigs2) ) + return 0; + CellId = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos ); + if ( CellId >= pCellLib->nCellNum ) + return 0; + nPins = Abc_MinInt( pCellLib->nCellInputs[CellId], 9 ); + for ( i = 0; i < nPins; i++ ) + { + int v = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos + 1 + i ); + if ( v >= 2 && v < 2 + nLutSize ) + pPinDelay[v - 2] = pCellLib->pCellPinDelays[CellId][i]; + } + return 1; +} + /**Function************************************************************* Synopsis [Sorts the pins in the decreasing order of delays.] @@ -113,7 +161,7 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting ) If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib; If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib; Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); - int k, iFanin, pPinPerm[32]; + int k, iFanin, pPinPerm[32], pPinDelay[32]; float pPinDelays[32]; float tArrival, * pDelays; if ( Gia_ObjIsCi(pObj) ) @@ -132,15 +180,17 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting ) { // Handle cell library delays (use integer delays directly) int nLutSize = Gia_ObjLutSize(p, iObj); + int fHaveCfg2 = Gia_ManConfig2DerivePinDelays( p, iObj, pCellLib, pPinDelay, nLutSize ); // Find matching cell (simple approach: use first cell with enough inputs) int cellId = -1; int i; - for ( i = 0; i < pCellLib->nCellNum; i++ ) - if ( pCellLib->nCellInputs[i] >= nLutSize ) - { - cellId = i; - break; - } + if ( !fHaveCfg2 ) + for ( i = 0; i < pCellLib->nCellNum; i++ ) + if ( pCellLib->nCellInputs[i] >= nLutSize ) + { + cellId = i; + break; + } if ( cellId >= 0 ) { // Use cell delays as integers from the library @@ -151,6 +201,15 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting ) tArrival = Gia_ObjTimeArrival(p, iFanin) + delay; } } + else if ( fHaveCfg2 ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + { + float delay = (float)pPinDelay[k]; + if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + delay ) + tArrival = Gia_ObjTimeArrival(p, iFanin) + delay; + } + } else { // Fall back to default delay if no matching cell @@ -204,7 +263,7 @@ float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting ) { If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib; If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib; - int k, iFanin, pPinPerm[32]; + int k, iFanin, pPinPerm[32], pPinDelay[32]; float pPinDelays[32]; float tRequired = 0.0; // Suppress "might be used uninitialized" float * pDelays; @@ -223,15 +282,17 @@ float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting ) { // Handle cell library delays (use integer delays directly) int nLutSize = Gia_ObjLutSize(p, iObj); + int fHaveCfg2 = Gia_ManConfig2DerivePinDelays( p, iObj, pCellLib, pPinDelay, nLutSize ); // Find matching cell (simple approach: use first cell with enough inputs) int cellId = -1; int i; - for ( i = 0; i < pCellLib->nCellNum; i++ ) - if ( pCellLib->nCellInputs[i] >= nLutSize ) - { - cellId = i; - break; - } + if ( !fHaveCfg2 ) + for ( i = 0; i < pCellLib->nCellNum; i++ ) + if ( pCellLib->nCellInputs[i] >= nLutSize ) + { + cellId = i; + break; + } if ( cellId >= 0 ) { // Use cell delays as integers from the library @@ -243,6 +304,15 @@ float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting ) Gia_ObjSetTimeRequired( p, iFanin, tRequired ); } } + else if ( fHaveCfg2 ) + { + Gia_LutForEachFanin( p, iObj, iFanin, k ) + { + tRequired = Gia_ObjTimeRequired( p, iObj ) - (float)pPinDelay[k]; + if ( Gia_ObjTimeRequired(p, iFanin) > tRequired ) + Gia_ObjSetTimeRequired( p, iFanin, tRequired ); + } + } else { // Fall back to default delay if no matching cell @@ -977,4 +1047,3 @@ Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerb ABC_NAMESPACE_IMPL_END - diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 63847c88b..e42dfb8a4 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -22285,7 +22285,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) If_ManSetDefaultPars( pPars ); pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYUZDEWSJqalepmrsdbgxyzuojiktncfvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYZUDEWSJqalepmrsdbgxyzuoiktncfvh" ) ) != EOF ) { switch ( c ) { @@ -22535,9 +22535,9 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'o': pPars->fUseBuffs ^= 1; break; - case 'j': - pPars->fEnableCheck07 ^= 1; - break; + //case 'j': + // pPars->fEnableCheck07 ^= 1; + // break; case 'i': pPars->fUseCofVars ^= 1; break; @@ -22867,7 +22867,7 @@ usage: sprintf(LutSize, "library" ); else sprintf(LutSize, "%d", pPars->nLutSize ); - Abc_Print( -2, "usage: if [-KCFAGRNTXYUZ num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuojiktnczfvh]\n" ); + Abc_Print( -2, "usage: if [-KCFAGRNTXYZMU num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuoiktnczfvh]\n" ); Abc_Print( -2, "\t performs FPGA technology mapping of the network\n" ); Abc_Print( -2, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize ); Abc_Print( -2, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax ); @@ -22901,7 +22901,7 @@ usage: Abc_Print( -2, "\t-y : toggles delay optimization with recorded library [default = %s]\n", pPars->fUserRecLib? "yes": "no" ); Abc_Print( -2, "\t-u : toggles delay optimization with SAT-based library [default = %s]\n", pPars->fUserSesLib? "yes": "no" ); Abc_Print( -2, "\t-o : toggles using buffers to decouple combinational outputs [default = %s]\n", pPars->fUseBuffs? "yes": "no" ); - Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" ); + //Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" ); Abc_Print( -2, "\t-i : toggles using cofactoring variables [default = %s]\n", pPars->fUseCofVars? "yes": "no" ); Abc_Print( -2, "\t-k : toggles matching based on precomputed DSD manager [default = %s]\n", pPars->fUseDsdTune? "yes": "no" ); Abc_Print( -2, "\t-t : toggles optimizing average rather than maximum level [default = %s]\n", pPars->fDoAverage? "yes": "no" ); @@ -44067,8 +44067,9 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameSetLibLut( If_LibLutSetSimple( 6 ) ); } pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); + pPars->pCellLib = (If_LibCell_t *)Abc_FrameReadLibCell(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSJTXYZqalepmrsdbgxyofuijkztncvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSJTXYZMqalepmrsdbgxyofuijkztncvwh" ) ) != EOF ) { switch ( c ) { @@ -44084,6 +44085,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; // if the LUT size is specified, disable library pPars->pLutLib = NULL; + pPars->pCellLib = NULL; break; case 'C': if ( globalUtilOptind >= argc ) @@ -44173,6 +44175,21 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nAndDelay < 0 ) goto usage; break; + case 'M': + { + int Value; + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by 0 or 1.\n" ); + goto usage; + } + Value = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Value < 0 || Value > 1 ) + goto usage; + pPars->fDelayOptCell = Value; + break; + } case 'D': if ( globalUtilOptind >= argc ) { @@ -44349,6 +44366,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Auto-detected K=%d from cell library (max inputs).\n", nMaxInputs ); // Disable LUT library since we're using K from cell library pPars->pLutLib = NULL; + pPars->pCellLib = pCellLib; } } } @@ -44537,6 +44555,11 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->nLutSize = 4; } + if ( pPars->fEnableCheck07 ) + pPars->nCutsMax = Abc_MaxInt( pPars->nCutsMax, 16 ); + else + pPars->pCellLib = NULL; + // enable truth table computation if cut minimization is selected if ( pPars->fCutMin || pPars->fDeriveLuts ) { @@ -44672,7 +44695,7 @@ usage: sprintf(LutSize, "library" ); else sprintf(LutSize, "%d", pPars->nLutSize ); - Abc_Print( -2, "usage: &if [-KCFAGRTXY num] [-DEW float] [-SJ str] [-qarlepmsdbgxyofuijkztnchvw]\n" ); + Abc_Print( -2, "usage: &if [-KCFAGRTXYZM num] [-DEW float] [-SJ str] [-qarlepmsdbgxyofuijkztnchvw]\n" ); Abc_Print( -2, "\t performs FPGA technology mapping of the network\n" ); Abc_Print( -2, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize ); Abc_Print( -2, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax ); @@ -44683,6 +44706,7 @@ usage: Abc_Print( -2, "\t-T num : the type of LUT structures [default = any]\n", pPars->nStructType ); Abc_Print( -2, "\t-X num : delay of AND-gate in LUT library units [default = %d]\n", pPars->nAndDelay ); Abc_Print( -2, "\t-Y num : area of AND-gate in LUT library units [default = %d]\n", pPars->nAndArea ); + Abc_Print( -2, "\t-M num : enables delay-driven decomposition [default = %d]\n", pPars->fDelayOptCell ); Abc_Print( -2, "\t-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer ); Abc_Print( -2, "\t-E float : sets epsilon used for tie-breaking [default = %f]\n", pPars->Epsilon ); Abc_Print( -2, "\t-W float : sets wire delay between adjects LUTs [default = %f]\n", pPars->WireDelay ); @@ -48585,22 +48609,13 @@ int Abc_CommandAbc9Trace( Abc_Frame_t * pAbc, int argc, char ** argv ) pAbc->pGia->pLutLib = fUseLutLib ? Abc_FrameReadLibLut() : NULL; pAbc->pGia->pCellLib = fUseCellLib ? Abc_FrameReadLibCell() : NULL; - if ( pFileName ) - { - // Dump the delay trace to file - Gia_ManDelayTraceDump( pAbc->pGia, (char *)pFileName ); - } - else - { - // Print the delay trace to console - Gia_ManDelayTraceLutPrint( pAbc->pGia, fVerbose ); - } + Gia_ManDelayTraceDump( pAbc->pGia, (char *)pFileName ); return 0; usage: Abc_Print( -2, "usage: &trace [-F file] [-lcvh]\n" ); Abc_Print( -2, "\t performs delay trace of LUT-mapped network\n" ); - Abc_Print( -2, "\t-F file : dump the critical path to a file [default = console output]\n" ); + Abc_Print( -2, "\t-F file : dump the critical path to a file [default = stdout]\n" ); Abc_Print( -2, "\t-l : toggle using LUT-library-delay model [default = %s]\n", fUseLutLib? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using cell-library-delay model [default = %s]\n", fUseCellLib? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" ); diff --git a/src/map/if/if.h b/src/map/if/if.h index 3f9ddd101..bfc451c6c 100644 --- a/src/map/if/if.h +++ b/src/map/if/if.h @@ -126,6 +126,7 @@ struct If_Par_t_ int fCutMin; // performs cut minimization by removing functionally reducdant variables int fDelayOpt; // special delay optimization int fDelayOptLut; // delay optimization for LUTs + int fDelayOptCell; // delay optimization for cells int fDsdBalance; // special delay optimization int fUserRecLib; // use recorded library int fUserSesLib; // use SAT-based synthesis @@ -175,6 +176,7 @@ struct If_Par_t_ float FinalDelay; // final delay after mapping float FinalArea; // final area after mapping If_LibLut_t * pLutLib; // the LUT library + If_LibCell_t * pCellLib; // the cell library float * pTimesArr; // arrival times float * pTimesReq; // required times int (* pFuncCost) (If_Man_t *, If_Cut_t *); // procedure to compute the user's cost of a cut @@ -299,6 +301,14 @@ struct If_Man_t_ Vec_Int_t * vVisited2; Vec_Int_t * vCuts; Vec_Int_t * vCutCosts; + // current cut context for user callbacks + If_Obj_t * pCutObjCur; // current object whose cut is being checked + If_Cut_t * pCutCur; // current cut being checked + int nCutLeavesCur; // number of leaves in current cut + int pCutLeavesCur[IF_MAX_LUTSIZE]; // current cut leaves (IDs) + float pCutLeafArrCur[IF_MAX_LUTSIZE]; // current cut leaf arrivals + float CutDelayCur; // current cut delay returned by user callback + int fCutDelayCurValid; // indicates CutDelayCur is valid // timing manager Tim_Man_t * pManTim; @@ -319,6 +329,7 @@ struct If_Cut_t_ float Edge; // the edge flow float Power; // the power flow float Delay; // delay of the cut + word Config; // configuration string int iCutFunc; // TT ID of the cut int uMaskFunc; // polarity bitmask unsigned uSign; // cut signature @@ -564,7 +575,8 @@ extern float If_CutPowerDerefed( If_Man_t * p, If_Cut_t * pCut, If_Obj extern float If_CutPowerRefed( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot ); /*=== ifDec.c =============================================================*/ extern word If_CutPerformDerive07( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr ); -extern word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive ); +extern word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive, int fDelay ); +extern void If_CutComputeIntrinsicJ( If_Man_t * p, word Config, int nLeaves, int * pIntrinsicDelays ); extern int If_CutPerformCheck07( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr ); extern int If_CutPerformCheck08( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr ); extern int If_CutPerformCheck10( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr ); diff --git a/src/map/if/ifCore.c b/src/map/if/ifCore.c index 58649b720..975a57306 100644 --- a/src/map/if/ifCore.c +++ b/src/map/if/ifCore.c @@ -207,4 +207,3 @@ int If_ManPerformMappingComb( If_Man_t * p ) ABC_NAMESPACE_IMPL_END - diff --git a/src/map/if/ifDecJ.c b/src/map/if/ifDecJ.c index 018ad4969..d9676727b 100644 --- a/src/map/if/ifDecJ.c +++ b/src/map/if/ifDecJ.c @@ -35,10 +35,13 @@ int If_CutPerformCheckJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves { return 1; } -word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive ) +word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive, int fDelay ) { return 0; } +void If_CutComputeIntrinsicJ( If_Man_t * p, word Config, int nLeaves, int * pIntrinsicDelays ) +{ +} void If_PermUnpack( unsigned Value, int Pla2Var[9] ) { } @@ -52,4 +55,3 @@ void Gia_ManDelayTraceDump( Gia_Man_t * p, char * pFileName ) ABC_NAMESPACE_IMPL_END - diff --git a/src/map/if/ifMan.c b/src/map/if/ifMan.c index 1a79014da..ebf650db4 100644 --- a/src/map/if/ifMan.c +++ b/src/map/if/ifMan.c @@ -719,6 +719,7 @@ void If_ManSetupCutTriv( If_Man_t * p, If_Cut_t * pCut, int ObjId ) pCut->uSign = If_ObjCutSign( pCut->pLeaves[0] ); pCut->iCutFunc = p->pPars->fUseTtPerm ? 3 : (p->pPars->fTruth ? 2: -1); pCut->uMaskFunc = 0; + pCut->Config = 0; assert( pCut->pLeaves[0] < p->vObjs->nSize ); } diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c index ac62e26e4..b03201a6b 100644 --- a/src/map/if/ifMap.c +++ b/src/map/if/ifMap.c @@ -162,6 +162,7 @@ int * If_CutArrTimeProfile( If_Man_t * p, If_Cut_t * pCut ) void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPreprocess, int fFirst ) { If_Set_t * pCutSet; + If_Obj_t * pLeaf; If_Cut_t * pCut0, * pCut1, * pCut; If_Cut_t * pCut0R, * pCut1R; int fFunc0R, fFunc1R; @@ -193,6 +194,31 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep pCut->Delay = If_CutSopBalanceEval( p, pCut, NULL ); else if ( p->pPars->fDsdBalance ) pCut->Delay = If_CutDsdBalanceEval( p, pCut, NULL ); + else if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell ) + { + int iLeaf, Intrinsic[IF_MAX_LUTSIZE]; + float Delay = -IF_FLOAT_LARGE; + if ( pCut->nLeaves == 0 ) + { + pCut->fUseless = 0; + pCut->Delay = 0.0; + goto IfMapBestCutDone; + } + assert( pCut->nLeaves == 1 || pCut->Config ); + If_CutComputeIntrinsicJ( p, pCut->Config, pCut->nLeaves, Intrinsic ); + If_CutForEachLeaf( p, pCut, pLeaf, iLeaf ) + { + If_Cut_t * pBestCut = If_ObjCutBest( pLeaf ); + assert( pBestCut != NULL ); + assert( pBestCut->fUseless == 0 ); + Delay = IF_MAX( Delay, If_ObjArrTime(pLeaf) + (float)Intrinsic[iLeaf] ); + } + pCut->fUseless = (Delay > IF_FLOAT_LARGE/2); + pCut->Delay = Delay; +IfMapBestCutDone: +// if ( pCut->nLeaves == 9 && !pCut->fUseless ) +// Abc_Print( 1, "Delay-debug(Map9-best): obj=%d delay=%.2f\n", pObj->Id, pCut->Delay ); + } else if ( p->pPars->fUserRecLib ) pCut->Delay = If_CutDelayRecCost3( p, pCut, pObj ); else if ( p->pPars->fUserSesLib ) @@ -324,12 +350,32 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep { assert( p->pPars->fUseTtPerm == 0 ); assert( pCut->nLimit >= 4 && pCut->nLimit <= 16 ); + pCut->Config = 0; if ( p->pPars->fUseDsd ) pCut->fUseless = If_DsdManCheckDec( p->pIfDsdMan, If_CutDsdLit(p, pCut) ); else if ( p->pPars->pFuncCell2 ) pCut->fUseless = !p->pPars->pFuncCell2( p, (word *)If_CutTruthW(p, pCut), pCut->nLeaves, NULL, NULL ); else + { + int iLeaf; + // Expose current cut context for user callbacks. + p->pCutObjCur = pObj; + p->pCutCur = pCut; + p->nCutLeavesCur = pCut->nLeaves; + for ( iLeaf = 0; iLeaf < p->nCutLeavesCur; iLeaf++ ) + { + If_Obj_t * pLeaf = If_CutLeaf( p, pCut, iLeaf ); + if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell && pCut->nLeaves > 1 ) + { + If_Cut_t * pBestCut = If_ObjCutBest( pLeaf ); + assert( pBestCut != NULL ); + assert( pBestCut->fUseless == 0 ); + } + p->pCutLeavesCur[iLeaf] = pLeaf->Id; + p->pCutLeafArrCur[iLeaf] = If_ObjArrTime( pLeaf ); + } pCut->fUseless = !p->pPars->pFuncCell( p, If_CutTruth(p, pCut), Abc_MaxInt(6, pCut->nLeaves), pCut->nLeaves, p->pPars->pLutStruct ); + } p->nCutsUselessAll += pCut->fUseless; p->nCutsUseless[pCut->nLeaves] += pCut->fUseless; p->nCutsCountAll++; @@ -427,6 +473,28 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep pCut->Delay = If_CutSopBalanceEval( p, pCut, NULL ); else if ( p->pPars->fDsdBalance ) pCut->Delay = If_CutDsdBalanceEval( p, pCut, NULL ); + else if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell ) + { + if ( pCut->nLeaves == 0 ) + { + pCut->Delay = 0.0; + pCut->fUseless = 0; + goto IfMapCutEvalDone; + } + if ( pCut->nLeaves == 1 ) + { + pLeaf = If_ManObj( p, pCut->pLeaves[0] ); + pCut->Delay = If_ObjArrTime( pLeaf ); + pCut->fUseless = 0; + goto IfMapCutEvalDone; + } + assert( pCut->fUseless || p->fCutDelayCurValid ); + assert( pCut->fUseless || pCut->Config != 0 ); + pCut->Delay = pCut->fUseless ? IF_FLOAT_LARGE : p->CutDelayCur; +IfMapCutEvalDone: +// if ( pCut->nLeaves == 9 && !pCut->fUseless ) +// Abc_Print( 1, "Delay-debug(Map9): obj=%d delay=%.2f\n", pObj->Id, pCut->Delay ); + } else if ( p->pPars->fUserRecLib ) pCut->Delay = If_CutDelayRecCost3( p, pCut, pObj ); else if ( p->pPars->fUserLutDec ) @@ -502,7 +570,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep if ( Mode && pObj->nRefs > 0 ) If_CutAreaRef( p, If_ObjCutBest(pObj) ); if ( If_ObjCutBest(pObj)->fUseless ) - Abc_Print( 1, "The best cut is useless.\n" ); + Abc_Print( 1, "The best cut is useless. Please increase the number of cuts used by the mapper, for example: \"&if -C 32\"\n" ); // call the user specified function for each cut if ( p->pPars->pFuncUser ) If_ObjForEachCut( pObj, pCut, i ) @@ -702,4 +770,3 @@ int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode, int fPrepr ABC_NAMESPACE_IMPL_END - diff --git a/src/map/if/ifTime.c b/src/map/if/ifTime.c index 216e4ce5c..2b3e21a5a 100644 --- a/src/map/if/ifTime.c +++ b/src/map/if/ifTime.c @@ -131,6 +131,20 @@ float If_CutDelay( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut ) } else { + if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell && p->pPars->pCellLib ) + { + int Intrinsic[IF_MAX_LUTSIZE]; + if ( pCut->nLeaves == 0 ) + return 0.0; + assert( pCut->nLeaves == 1 || pCut->Config != 0 ); + If_CutComputeIntrinsicJ( p, pCut->Config, pCut->nLeaves, Intrinsic ); + If_CutForEachLeaf( p, pCut, pLeaf, i ) + { + DelayCur = If_ObjCutBest(pLeaf)->Delay + (float)Intrinsic[i]; + Delay = IF_MAX( Delay, DelayCur ); + } + return Delay; + } if ( pCut->fUser ) { assert( !p->pPars->fLiftLeaves ); @@ -219,6 +233,17 @@ void If_CutPropagateRequired( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut, fl } else { + if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell && p->pPars->pCellLib ) + { + int Intrinsic[IF_MAX_LUTSIZE]; + if ( pCut->nLeaves == 0 ) + return; + assert( (pObj && pObj->Id == 0) || pCut->nLeaves == 1 || pCut->Config != 0 ); + If_CutComputeIntrinsicJ( p, pCut->Config, pCut->nLeaves, Intrinsic ); + If_CutForEachLeaf( p, pCut, pLeaf, i ) + pLeaf->Required = IF_MIN( pLeaf->Required, ObjRequired - (float)Intrinsic[i] ); + return; + } if ( pCut->fUser ) { char Perm[IF_MAX_FUNC_LUTSIZE], * pPerm = Perm; @@ -528,4 +553,3 @@ void If_ManComputeRequired( If_Man_t * p ) ABC_NAMESPACE_IMPL_END -