diff options
-rw-r--r-- | src/aig/gia/gia.h | 1 | ||||
-rw-r--r-- | src/aig/gia/giaLf.c | 55 | ||||
-rw-r--r-- | src/base/abci/abc.c | 23 |
3 files changed, 65 insertions, 14 deletions
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 20648b39..c1968086 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -340,6 +340,7 @@ struct Jf_Par_t_ int fDoAverage; int fCutHashing; int fCutSimple; + int fCutGroup; int fVerbose; int fVeryVerbose; int nLutSizeMax; diff --git a/src/aig/gia/giaLf.c b/src/aig/gia/giaLf.c index 15ec3529..45a22db0 100644 --- a/src/aig/gia/giaLf.c +++ b/src/aig/gia/giaLf.c @@ -30,7 +30,7 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define LF_LEAF_MAX 12 +#define LF_LEAF_MAX 13 #define LF_CUT_MAX 32 #define LF_LOG_PAGE 12 #define LF_NO_LEAF 255 @@ -472,8 +472,8 @@ static inline float Lf_CutArea( Lf_Man_t * p, Lf_Cut_t * pCut ) if ( p->pPars->fPower ) return 1.0 * pCut->nLeaves + Lf_CutSwitches( p, pCut ); if ( p->pPars->fOptEdge ) - return pCut->nLeaves + p->pPars->nAreaTuner; - return 1; + return (pCut->nLeaves + p->pPars->nAreaTuner) * (1 + (p->pPars->fCutGroup && (int)pCut->nLeaves > p->pPars->nLutSize/2)); + return 1 + (p->pPars->fCutGroup && (int)pCut->nLeaves > p->pPars->nLutSize/2); } static inline int Lf_CutIsMux( Lf_Man_t * p, Lf_Cut_t * pCut, Gia_Obj_t * pMux ) { @@ -1184,7 +1184,7 @@ void Lf_ObjMergeOrder( Lf_Man_t * p, int iObj ) Lf_Bst_t * pBest = Lf_ObjReadBest(p, iObj); float FlowRefs = Lf_ObjFlowRefs(p, iObj); int Required = Lf_ObjRequired(p, iObj); - int nLutSize = p->pPars->nLutSize; + int nLutSize = p->pPars->fCutGroup ? p->pPars->nLutSize/2 : p->pPars->nLutSize; int nCutNum = p->pPars->nCutNum; int nCutWords = p->nCutWords; int fComp0 = Gia_ObjFaninC0(pObj); @@ -1239,13 +1239,15 @@ void Lf_ObjMergeOrder( Lf_Man_t * p, int iObj ) } if ( Gia_ObjIsMuxId(p->pGia, iObj) ) { + Lf_Cut_t * pCutSave = NULL; int fComp2 = Gia_ObjFaninC2(p->pGia, pObj); int nCuts2 = Lf_ManPrepareSet( p, Gia_ObjFaninId2(p->pGia, iObj), 2, &pCutSet2 ); p->CutCount[0] += nCuts0 * nCuts1 * nCuts2; - Lf_CutSetForEachCut( nCutWords, pCutSet0, pCut0, i, nCuts0 ) - Lf_CutSetForEachCut( nCutWords, pCutSet1, pCut1, k, nCuts1 ) - Lf_CutSetForEachCut( nCutWords, pCutSet2, pCut2, n, nCuts2 ) + Lf_CutSetForEachCut( nCutWords, pCutSet0, pCut0, i, nCuts0 ) if ( (int)pCut0->nLeaves <= nLutSize ) + Lf_CutSetForEachCut( nCutWords, pCutSet1, pCut1, k, nCuts1 ) if ( (int)pCut1->nLeaves <= nLutSize ) + Lf_CutSetForEachCut( nCutWords, pCutSet2, pCut2, n, nCuts2 ) if ( (int)pCut2->nLeaves <= nLutSize ) { + pCutSave = pCut2; if ( Lf_CutCountBits(pCut0->Sign | pCut1->Sign | pCut2->Sign) > nLutSize ) continue; p->CutCount[1]++; @@ -1262,13 +1264,38 @@ void Lf_ObjMergeOrder( Lf_Man_t * p, int iObj ) Lf_CutParams( p, pCutsR[nCutsR], Required, FlowRefs, pObj ); nCutsR = Lf_SetAddCut( pCutsR, nCutsR, nCutNum ); } + if ( p->pPars->fCutGroup ) + { + assert( pCutSave->nLeaves == 1 ); + assert( pCutSave->pLeaves[0] == Gia_ObjFaninId2(p->pGia, iObj) ); + Lf_CutSetForEachCut( nCutWords, pCutSet0, pCut0, i, nCuts0 ) if ( (int)pCut0->nLeaves <= nLutSize ) + Lf_CutSetForEachCut( nCutWords, pCutSet1, pCut1, k, nCuts1 ) if ( (int)pCut1->nLeaves <= nLutSize ) + { + assert( (int)pCut0->nLeaves + (int)pCut1->nLeaves + 1 <= p->pPars->nLutSize ); + // if ( Lf_CutCountBits(pCut0->Sign | pCut1->Sign | pCutSave->Sign) > p->pPars->nLutSize ) + // continue; + p->CutCount[1]++; + if ( !Lf_CutMergeOrderMux(pCut0, pCut1, pCutSave, pCutsR[nCutsR], p->pPars->nLutSize) ) + continue; + if ( Lf_SetLastCutIsContained(pCutsR, nCutsR) ) + continue; + p->CutCount[2]++; + if ( p->pPars->fCutMin && Lf_CutComputeTruthMux(p, pCut0, pCut1, pCutSave, fComp0, fComp1, fComp2, pCutsR[nCutsR]) ) + pCutsR[nCutsR]->Sign = Lf_CutGetSign(pCutsR[nCutsR]); + // if ( p->pPars->nLutSizeMux && p->pPars->nLutSizeMux == (int)pCutsR[nCutsR]->nLeaves && + // Lf_ManFindCofVar(Lf_CutTruth(p,pCutsR[nCutsR]), Abc_Truth6WordNum(nLutSize), pCutsR[nCutsR]->nLeaves) == -1 ) + // continue; + Lf_CutParams( p, pCutsR[nCutsR], Required, FlowRefs, pObj ); + nCutsR = Lf_SetAddCut( pCutsR, nCutsR, nCutNum ); + } + } } else { int fIsXor = Gia_ObjIsXor(pObj); p->CutCount[0] += nCuts0 * nCuts1; - Lf_CutSetForEachCut( nCutWords, pCutSet0, pCut0, i, nCuts0 ) - Lf_CutSetForEachCut( nCutWords, pCutSet1, pCut1, k, nCuts1 ) + Lf_CutSetForEachCut( nCutWords, pCutSet0, pCut0, i, nCuts0 ) if ( (int)pCut0->nLeaves <= nLutSize ) + Lf_CutSetForEachCut( nCutWords, pCutSet1, pCut1, k, nCuts1 ) if ( (int)pCut1->nLeaves <= nLutSize ) { if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nLutSize && Lf_CutCountBits(pCut0->Sign | pCut1->Sign) > nLutSize ) continue; @@ -2058,7 +2085,16 @@ void Lf_ManPrintQuit( Lf_Man_t * p, Gia_Man_t * pNew ) if ( p->CutCount[0] == 0 ) p->CutCount[0] = 1; if ( !p->pPars->fVerbose ) + { + int i, CountOver[2] = {0}; + int nLutSize = p->pPars->fCutGroup ? p->pPars->nLutSize/2 : p->pPars->nLutSize; + Gia_ManForEachLut( pNew, i ) + CountOver[Gia_ObjLutSize(pNew, i) > nLutSize]++; + if ( p->pPars->fCutGroup ) + printf( "Created %d regular %d-LUTs and %d dual %d-LUTs. The total of %d %d-LUTs.\n", + CountOver[0], nLutSize, CountOver[1], nLutSize, CountOver[0] + 2*CountOver[1], nLutSize ); return; + } printf( "CutPair = %.0f ", p->CutCount[0] ); printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] ); printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] ); @@ -2248,6 +2284,7 @@ Gia_Man_t * Lf_ManPerformMapping( Gia_Man_t * p, Jf_Par_t * pPars ) Gia_Man_t * Gia_ManPerformLfMapping( Gia_Man_t * p, Jf_Par_t * pPars, int fNormalized ) { Gia_Man_t * pNew; + assert( !pPars->fCutGroup || pPars->nLutSize == 9 || pPars->nLutSize == 11 || pPars->nLutSize == 13 ); // reconstruct GIA according to the hierarchy manager assert( pPars->pTimesArr == NULL ); assert( pPars->pTimesReq == NULL ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 67854f1a..4d0ddfea 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -36795,7 +36795,7 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_Man_t * pNew; int c; Lf_ManSetDefaultPars( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCFARLEDWMaekmupgtvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFARLEDWMekmupstgvwh" ) ) != EOF ) { switch ( c ) { @@ -36936,12 +36936,15 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'p': pPars->fPower ^= 1; break; - case 'g': + case 's': pPars->fPureAig ^= 1; break; case 't': pPars->fDoAverage ^= 1; break; + case 'g': + pPars->fCutGroup ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -36969,7 +36972,16 @@ int Abc_CommandAbc9Lf( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Flags \"-M\" and \"-u\" are incompatible.\n" ); return 1; } - + if ( pPars->fCutGroup ) + { + if ( pPars->nLutSize < 4 || pPars->nLutSize > 6 ) + { + Abc_Print( -1, "This feature works only for LUT size equal to 4, 5, and 6.\n" ); + return 1; + } + printf( "Using cut grouping for %d-LUTs. Considering cuts up to %d.\n", pPars->nLutSize, 2*pPars->nLutSize + 1 ); + pPars->nLutSize = 2*pPars->nLutSize + 1; + } pNew = Lf_ManPerformMapping( pAbc->pGia, pPars ); if ( pNew == NULL ) { @@ -36984,7 +36996,7 @@ usage: sprintf(Buffer, "best possible" ); else sprintf(Buffer, "%d", pPars->DelayTarget ); - Abc_Print( -2, "usage: &lf [-KCFARLEDM num] [-kmupgtvwh]\n" ); + Abc_Print( -2, "usage: &lf [-KCFARLEDM num] [-kmupstgvwh]\n" ); Abc_Print( -2, "\t performs technology mapping of the network\n" ); Abc_Print( -2, "\t-K num : LUT size for the mapping (2 <= K <= %d) [default = %d]\n", pPars->nLutSizeMax, pPars->nLutSize ); Abc_Print( -2, "\t-C num : the max number of priority cuts (1 <= C <= %d) [default = %d]\n", pPars->nCutNumMax, pPars->nCutNum ); @@ -37001,8 +37013,9 @@ usage: Abc_Print( -2, "\t-m : toggles cut minimization [default = %s]\n", pPars->fCutMin? "yes": "no" ); Abc_Print( -2, "\t-u : toggles using additional MUXes [default = %s]\n", pPars->fUseMux7? "yes": "no" ); Abc_Print( -2, "\t-p : toggles power-aware cut selection heuristics [default = %s]\n", pPars->fPower? "yes": "no" ); - Abc_Print( -2, "\t-g : toggles generating AIG without mapping [default = %s]\n", pPars->fPureAig? "yes": "no" ); + Abc_Print( -2, "\t-s : toggles generating AIG without mapping [default = %s]\n", pPars->fPureAig? "yes": "no" ); Abc_Print( -2, "\t-t : toggles optimizing average rather than maximum level [default = %s]\n", pPars->fDoAverage? "yes": "no" ); + Abc_Print( -2, "\t-g : toggles using cut splitting [default = %s]\n", pPars->fCutGroup? "yes": "no" ); Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggles very verbose output [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : prints the command usage\n"); |