Skip to content

Commit

Permalink
Merge pull request #272 from aletempiac/acd
Browse files Browse the repository at this point in the history
LUT mapping with decomposition
  • Loading branch information
alanminko authored Jan 16, 2024
2 parents 5bc9957 + 5a00bba commit 9bdb8a7
Show file tree
Hide file tree
Showing 20 changed files with 2,766 additions and 61 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ MODULES := \
$(wildcard src/ext*) \
src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src/base/exor \
src/base/ver src/base/wlc src/base/wln src/base/acb src/base/bac src/base/cba src/base/pla src/base/test \
src/map/mapper src/map/mio src/map/super src/map/if \
src/map/mapper src/map/mio src/map/super src/map/if src/map/if/acd \
src/map/amap src/map/cov src/map/scl src/map/mpm \
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/nm \
src/misc/vec src/misc/hash src/misc/tim src/misc/bzlib src/misc/zlib \
Expand Down Expand Up @@ -151,7 +151,7 @@ ifdef ABC_USE_LIBSTDCXX
endif

$(info $(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
CXXFLAGS += $(CFLAGS)
CXXFLAGS += $(CFLAGS) -std=c++17

SRC :=
GARBAGE := core core.* *.stackdump ./tags $(PROG) arch_flags
Expand Down
37 changes: 34 additions & 3 deletions src/base/abci/abc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19447,7 +19447,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, "KCFAGRNTXYDEWSqaflepmrsdbgxyzuojiktncvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYZDEWSqaflepmrsdbgxyzuojiktncvh" ) ) != EOF )
{
switch ( c )
{
Expand Down Expand Up @@ -19563,6 +19563,17 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nAndDelay < 0 )
goto usage;
break;
case 'Z':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-Z\" should be followed by a positive integer 3, 4, 5, or 6.\n" );
goto usage;
}
pPars->nLutDecSize = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nLutDecSize < 3 || pPars->nLutDecSize > 6 )
goto usage;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
Expand Down Expand Up @@ -19654,7 +19665,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
break;
case 'z':
pPars->fUserLutDec ^= 1;
break;
break;
case 'u':
pPars->fUserSesLib ^= 1;
break;
Expand Down Expand Up @@ -19794,6 +19805,25 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->fCutMin = 1;
}

if ( pPars->fUserLutDec )
{
if ( pPars->nLutDecSize == 0 )
{
Abc_Print( -1, "LUT decomposition size (%d) must be set.\n", pPars->nLutDecSize );
return 1;
}
if ( pPars->nLutDecSize >= pPars->nLutSize )
{
Abc_Print( -1, "LUT size (%d) must be greater than the LUT decomposition size (%d).\n", pPars->nLutSize, pPars->nLutDecSize );
return 1;
}
if ( pPars->nLutSize < 4 || pPars->nLutSize > 10 )
{
Abc_Print( -1, "This feature only works for [4;10]-LUTs.\n" );
return 1;
}
}

// enable truth table computation if cut minimization is selected
if ( pPars->fCutMin )
{
Expand Down Expand Up @@ -19956,7 +19986,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
sprintf(LutSize, "library" );
else
sprintf(LutSize, "%d", pPars->nLutSize );
Abc_Print( -2, "usage: if [-KCFAGRNTXY num] [-DEW float] [-S str] [-qarlepmsdbgxyzuojiktncvh]\n" );
Abc_Print( -2, "usage: if [-KCFAGRNTXYZ num] [-DEW float] [-S str] [-qarlepmsdbgxyzuojiktncvh]\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 );
Expand All @@ -19968,6 +19998,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -2, "\t-T num : the type of LUT structures [default = any]\n" );
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-Z num : the number of LUT inputs for LUT decomposition [default = %d]\n", pPars->nLutDecSize );
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 );
Expand Down
130 changes: 112 additions & 18 deletions src/base/abci/abcIf.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,28 +427,117 @@ Hop_Obj_t * Abc_NodeBuildFromMini( Hop_Man_t * pMan, If_Man_t * p, If_Cut_t * pC
}

/**Function*************************************************************
Synopsis [Implements decomposed LUT-structure of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_DecRecordToHop( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Cut_t * pCutBest, If_Obj_t * pIfObj, Vec_Int_t * vCover, Abc_Obj_t * pNodeTop )
{
extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
assert( !pIfMan->pPars->fUseTtPerm );

Synopsis [Implements decomposed LUT-structure of the cut.]
// get the truth table
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
int v;
If_Obj_t * pIfLeaf;

Description []
SideEffects []
if ( pCutBest->nLeaves <= pIfMan->pPars->nLutDecSize )
{
/* add fanins */
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, v )
Abc_ObjAddFanin( pNodeTop, (Abc_Obj_t *)If_ObjCopy( pIfLeaf ) );

pNodeTop->Level = Abc_ObjLevelNew( pNodeTop );

SeeAlso []
pNodeTop->pData = Kit_TruthToHop( (Hop_Man_t *)pNtkNew->pManFunc, (unsigned *)pTruth, If_CutLeaveNum(pCutBest), vCover );
return;
}

// get the delay profile
unsigned delayProfile = pCutBest->decDelay;

***********************************************************************/
Hop_Obj_t * Abc_DecRecordToHop( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCutBest, If_Obj_t * pIfObj, Vec_Int_t * vCover )
{
// get the truth table
// perform LUT-decomposition and return the LUT-structure
unsigned char decompArray[92];
int val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
assert( val == 0 );

// convert the LUT-structure into a set of logic nodes in Abc_Ntk_t
unsigned char bytes_check = decompArray[0];
assert( bytes_check <= 92 );

int byte_p = 2;
unsigned char i, j, k, num_fanins, num_words, num_bytes;
int level, fanin;
word *tt;
Abc_Obj_t *pNewNodes[5];

/* create intermediate LUTs*/
assert( decompArray[1] <= 6 );
Abc_Obj_t * pFanin;
for ( i = 0; i < decompArray[1]; ++i )
{
if ( i < decompArray[1] - 1 )
{
pNewNodes[i] = Abc_NtkCreateNode( pNtkNew );
}
else
{
pNewNodes[i] = pNodeTop;
}
num_fanins = decompArray[byte_p++];
level = 0;
for ( j = 0; j < num_fanins; ++j )
{
fanin = (int)decompArray[byte_p++];
if ( fanin < If_CutLeaveNum(pCutBest) )
{
pFanin = (Abc_Obj_t *)If_ObjCopy( If_CutLeaf(pIfMan, pCutBest, fanin) );
}
else
{
assert( fanin - If_CutLeaveNum(pCutBest) < i );
pFanin = pNewNodes[fanin - If_CutLeaveNum(pCutBest)];
}
Abc_ObjAddFanin( pNewNodes[i], pFanin );
level = Abc_MaxInt( level, Abc_ObjLevel(pFanin) );
}

// this is a placeholder, which takes the truth table and converts it into an AIG without LUT-decomposition
extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
assert( !pIfMan->pPars->fUseTtPerm );
return Kit_TruthToHop( (Hop_Man_t *)pMan, (unsigned *)pTruth, If_CutLeaveNum(pCutBest), vCover );
}
pNewNodes[i]->Level = level + (int)(Abc_ObjFaninNum(pNewNodes[i]) > 0);

/* extract the truth table */
tt = pIfMan->puTempW;
num_words = ( num_fanins <= 6 ) ? 1 : ( 1 << ( num_fanins - 6 ) );
num_bytes = ( num_fanins <= 3 ) ? 1 : ( 1 << ( Abc_MinInt( (int)num_fanins, 6 ) - 3 ) );
for ( j = 0; j < num_words; ++j )
{
tt[j] = 0;
for ( k = 0; k < num_bytes; ++k )
{
tt[j] |= ( (word)(decompArray[byte_p++]) ) << ( k << 3 );
}
}

/* extend truth table if size < 5 */
assert( num_fanins != 1 );
if ( num_fanins == 2 )
{
tt[0] |= tt[0] << 4;
}
while ( num_bytes < 4 )
{
tt[0] |= tt[0] << ( num_bytes << 3 );
num_bytes <<= 1;
}

/* add node data */
pNewNodes[i]->pData = Kit_TruthToHop( (Hop_Man_t *)pNtkNew->pManFunc, (unsigned *)tt, (int) num_fanins, vCover );
}

/* check correct read */
assert( byte_p == decompArray[0] );
}

/**Function*************************************************************
Expand Down Expand Up @@ -488,13 +577,18 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
pNodeNew = Abc_NtkCreateNode( pNtkNew );
// if ( pIfMan->pPars->pLutLib && pIfMan->pPars->pLutLib->fVarPinDelays )
if ( !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->fDelayOptLut && !pIfMan->pPars->fDsdBalance && !pIfMan->pPars->fUseTtPerm &&
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->fUserLutDec && !pIfMan->pPars->nGateSize )
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserLutDec && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize )
If_CutRotatePins( pIfMan, pCutBest );
if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
{
If_CutForEachLeafReverse( pIfMan, pCutBest, pIfLeaf, i )
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover) );
}
else if ( pIfMan->pPars->fUserLutDec )
{
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover);
}
else
{
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
Expand Down Expand Up @@ -550,8 +644,8 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
}
else if ( pIfMan->pPars->fUserLutDec )
{
extern Hop_Obj_t * Abc_DecRecordToHop( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj, Vec_Int_t * vMemory );
pNodeNew->pData = Abc_DecRecordToHop( (Hop_Man_t *)pNtkNew->pManFunc, pIfMan, pCutBest, pIfObj, vCover );
extern void Abc_DecRecordToHop( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj, Vec_Int_t * vMemory, Abc_Obj_t * pNodeTop );
Abc_DecRecordToHop( pNtkNew, pIfMan, pCutBest, pIfObj, vCover, pNodeNew );
}
else
{
Expand Down
Loading

0 comments on commit 9bdb8a7

Please sign in to comment.