summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2018-02-10 15:45:54 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2018-02-10 15:45:54 -0800
commitf716948c27f5c1984ea2b6537f420256f5f1afb3 (patch)
tree83b46ce2976ec8d71d1dd7d17328c2a92169e69e
parentc6bce9c20e07587de48b157ed676d175ca8c1b31 (diff)
downloadabc-f716948c27f5c1984ea2b6537f420256f5f1afb3.tar.gz
abc-f716948c27f5c1984ea2b6537f420256f5f1afb3.tar.bz2
abc-f716948c27f5c1984ea2b6537f420256f5f1afb3.zip
Experiments with LUT mapping.
-rw-r--r--src/aig/gia/gia.h1
-rw-r--r--src/aig/gia/giaLf.c55
-rw-r--r--src/base/abci/abc.c23
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");