mirror of https://github.com/YosysHQ/abc.git
Merge pull request #297 from aletempiac/yosys-flow
Integrating delay-driven LUT decomposition in &if
This commit is contained in:
commit
ae92ea0214
|
|
@ -1308,12 +1308,25 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t
|
|||
{
|
||||
if ( Length == 2 )
|
||||
{
|
||||
if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
if ( ((If_Man_t *)pIfMan)->pPars->fEnableStructN )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
if ( !If_CluCheckXXExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1411,6 +1424,90 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t
|
|||
return iObjLit3;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements delay-driven decomposition of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManFromIfLogicHop( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Cut_t * pCutBest, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2 )
|
||||
{
|
||||
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
|
||||
unsigned char decompArray[92];
|
||||
int val;
|
||||
|
||||
assert( pCutBest->nLeaves > pIfMan->pPars->nLutDecSize );
|
||||
|
||||
unsigned delayProfile = pCutBest->decDelay;
|
||||
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 Gia_Man_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 iObjLits[5];
|
||||
int fanin;
|
||||
word *tt;
|
||||
|
||||
for ( i = 0; i < decompArray[1]; ++i )
|
||||
{
|
||||
num_fanins = decompArray[byte_p++];
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( j = 0; j < num_fanins; ++j )
|
||||
{
|
||||
fanin = (int)decompArray[byte_p++];
|
||||
if ( fanin < If_CutLeaveNum(pCutBest) )
|
||||
{
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, fanin) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_IntPush( vLeavesTemp, iObjLits[fanin - If_CutLeaveNum(pCutBest)] );
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
iObjLits[i] = Gia_ManFromIfLogicCreateLut( pNew, tt, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
|
||||
/* check correct read */
|
||||
assert( byte_p == decompArray[0] );
|
||||
|
||||
return iObjLits[i-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively derives the local AIG for the cut.]
|
||||
|
|
@ -1894,7 +1991,7 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
if ( !pIfMan->pPars->fUseTtPerm && !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->fDelayOptLut && !pIfMan->pPars->fDsdBalance &&
|
||||
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize &&
|
||||
!pIfMan->pPars->fEnableCheck75 && !pIfMan->pPars->fEnableCheck75u && !pIfMan->pPars->fEnableCheck07 && !pIfMan->pPars->fUseDsdTune &&
|
||||
!pIfMan->pPars->fUseCofVars && !pIfMan->pPars->fUseAndVars && !pIfMan->pPars->fUseCheck1 && !pIfMan->pPars->fUseCheck2 )
|
||||
!pIfMan->pPars->fUseCofVars && !pIfMan->pPars->fUseAndVars && !pIfMan->pPars->fUseCheck1 && !pIfMan->pPars->fUseCheck2 && !pIfMan->pPars->fUserLutDec )
|
||||
If_CutRotatePins( pIfMan, pCutBest );
|
||||
// collect leaves of the best cut
|
||||
Vec_IntClear( vLeaves );
|
||||
|
|
@ -1946,6 +2043,10 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
{
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicCofVars( pNew, pIfMan, pCutBest, vLeaves, vLeaves2, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
else if ( pIfMan->pPars->fUserLutDec && (int)pCutBest->nLeaves > pIfMan->pPars->nLutDecSize )
|
||||
{
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicHop( pNew, pIfMan, pCutBest, vLeaves, vLeaves2, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
else if ( (pIfMan->pPars->fDeriveLuts && pIfMan->pPars->fTruth) || pIfMan->pPars->fUseDsd || pIfMan->pPars->fUseTtPerm || pIfMan->pPars->pFuncCell2 )
|
||||
{
|
||||
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
|
||||
|
|
|
|||
|
|
@ -19543,7 +19543,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, "KCFAGRNTXYUZDEWSJqaflepmrsdbgxyuojiktncvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYUZDEWSJqaflepmrsdbgxyzuojiktncvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -19814,6 +19814,9 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'v':
|
||||
pPars->fVerbose ^= 1;
|
||||
break;
|
||||
case 'z':
|
||||
pPars->fDeriveLuts ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
|
|
@ -19931,6 +19934,11 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pPars->pFuncCell = pPars->fDelayOptLut ? NULL : If_CutPerformCheck16;
|
||||
}
|
||||
pPars->fCutMin = 1;
|
||||
pPars->nLutDecSize = pPars->pLutStruct[0] - '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
pPars->fDeriveLuts = 0;
|
||||
}
|
||||
|
||||
if ( pPars->fUserLutDec || pPars->fUserLut2D )
|
||||
|
|
@ -20114,7 +20122,7 @@ usage:
|
|||
sprintf(LutSize, "library" );
|
||||
else
|
||||
sprintf(LutSize, "%d", pPars->nLutSize );
|
||||
Abc_Print( -2, "usage: if [-KCFAGRNTXYUZ num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuojiktncvh]\n" );
|
||||
Abc_Print( -2, "usage: if [-KCFAGRNTXYUZ num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuojiktnczvh]\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 );
|
||||
|
|
@ -20154,6 +20162,7 @@ usage:
|
|||
Abc_Print( -2, "\t-t : toggles optimizing average rather than maximum level [default = %s]\n", pPars->fDoAverage? "yes": "no" );
|
||||
Abc_Print( -2, "\t-n : toggles computing DSDs of the cut functions [default = %s]\n", pPars->fUseDsd? "yes": "no" );
|
||||
Abc_Print( -2, "\t-c : toggles computing truth tables in a new way [default = %s]\n", pPars->fUseTtPerm? "yes": "no" );
|
||||
Abc_Print( -2, "\t-z : toggles deriving LUTs when mapping into LUT structures [default = %s]\n", pPars->fDeriveLuts? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : prints the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -40405,7 +40414,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
pPars->pLutLib = (If_LibLut_t *)pAbc->pLibLut;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSTXYqalepmrsdbgxyofuijkztncvwh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSJTXYZqalepmrsdbgxyofuijkztncvwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -40557,6 +40566,33 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
goto usage;
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-S\" should be followed by string.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->pLutStruct = argv[globalUtilOptind];
|
||||
pPars->fEnableStructN = 1;
|
||||
globalUtilOptind++;
|
||||
if ( strlen(pPars->pLutStruct) != 2 )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-J\" should be followed by a 2-char string (e.g. \"44\" or \"55\").\n" );
|
||||
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]);
|
||||
pPars->fUserLutDec = 1;
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nLutDecSize < 3 || pPars->nLutDecSize > 6 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'q':
|
||||
pPars->fPreprocess ^= 1;
|
||||
break;
|
||||
|
|
@ -40791,8 +40827,35 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "This feature only works for [6;16]-LUTs.\n" );
|
||||
return 1;
|
||||
}
|
||||
pPars->pFuncCell = pPars->fDelayOptLut ? NULL : If_CutPerformCheck16;
|
||||
if ( pPars->fEnableStructN )
|
||||
{
|
||||
pPars->pFuncCell = pPars->fDelayOptLut ? NULL : If_CutPerformCheckXX;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPars->pFuncCell = pPars->fDelayOptLut ? NULL : If_CutPerformCheck16;
|
||||
}
|
||||
pPars->fCutMin = 1;
|
||||
pPars->nLutDecSize = pPars->pLutStruct[0] - '0';
|
||||
}
|
||||
|
||||
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 > 11 )
|
||||
{
|
||||
Abc_Print( -1, "This feature only works for [4;11]-LUTs.\n" );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pPars->fUse34Spec )
|
||||
|
|
@ -40820,7 +40883,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pPars->pLutLib = NULL;
|
||||
}
|
||||
// modify for delay optimization
|
||||
if ( pPars->fDelayOpt || pPars->fDsdBalance || pPars->fDelayOptLut )
|
||||
if ( pPars->fDelayOpt || pPars->fDsdBalance || pPars->fDelayOptLut || pPars->fUserLutDec )
|
||||
{
|
||||
pPars->fTruth = 1;
|
||||
pPars->fCutMin = 1;
|
||||
|
|
@ -40937,7 +41000,7 @@ usage:
|
|||
sprintf(LutSize, "library" );
|
||||
else
|
||||
sprintf(LutSize, "%d", pPars->nLutSize );
|
||||
Abc_Print( -2, "usage: &if [-KCFAGRTXY num] [-DEW float] [-S str] [-qarlepmsdbgxyofuijkztnchvw]\n" );
|
||||
Abc_Print( -2, "usage: &if [-KCFAGRTXY 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 );
|
||||
|
|
@ -40952,6 +41015,8 @@ usage:
|
|||
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 );
|
||||
Abc_Print( -2, "\t-S str : string representing the LUT structure [default = %s]\n", pPars->pLutStruct ? pPars->pLutStruct : "not used" );
|
||||
Abc_Print( -2, "\t-J str : string representing the LUT structure [default = %s]\n", pPars->pLutStruct ? pPars->pLutStruct : "not used" );
|
||||
Abc_Print( -2, "\t-Z num : the number of LUT inputs for delay-driven LUT decomposition [default = not used]\n" );
|
||||
Abc_Print( -2, "\t-q : toggles preprocessing using several starting points [default = %s]\n", pPars->fPreprocess? "yes": "no" );
|
||||
Abc_Print( -2, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" );
|
||||
Abc_Print( -2, "\t-r : enables expansion/reduction of the best cuts [default = %s]\n", pPars->fExpRed? "yes": "no" );
|
||||
|
|
|
|||
|
|
@ -465,10 +465,14 @@ void Abc_DecRecordToHop( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Cut_t * pCut
|
|||
{
|
||||
val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
}
|
||||
else
|
||||
else if ( pIfMan->pPars->fUserLut2D )
|
||||
{
|
||||
val = acd2_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
}
|
||||
else
|
||||
{
|
||||
val = acdXX_decompose( pTruth, pIfMan->pPars->nLutDecSize, pCutBest->nLeaves, decompArray );
|
||||
}
|
||||
assert( val == 0 );
|
||||
|
||||
// convert the LUT-structure into a set of logic nodes in Abc_Ntk_t
|
||||
|
|
@ -593,7 +597,7 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
|
|||
If_CutForEachLeafReverse( pIfMan, pCutBest, pIfLeaf, i )
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover) );
|
||||
}
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D )
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D || pIfMan->pPars->fDeriveLuts )
|
||||
{
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
|
||||
Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover);
|
||||
|
|
@ -651,7 +655,7 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
|
|||
extern Hop_Obj_t * Abc_RecToHop3( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj );
|
||||
pNodeNew->pData = Abc_RecToHop3( (Hop_Man_t *)pNtkNew->pManFunc, pIfMan, pCutBest, pIfObj );
|
||||
}
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D )
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D || pIfMan->pPars->fDeriveLuts )
|
||||
{
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ private:
|
|||
if ( free_set_size == offset )
|
||||
{
|
||||
best_cost = fn( tt );
|
||||
return { tt, permutations, best_cost };
|
||||
return std::make_tuple( tt, permutations, best_cost );
|
||||
}
|
||||
|
||||
/* works up to 16 input truth tables */
|
||||
|
|
|
|||
|
|
@ -118,32 +118,25 @@ int acd2_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay
|
|||
return 0;
|
||||
}
|
||||
|
||||
inline int acd66_decompose( word * pTruth, unsigned nVars, unsigned char *decomposition )
|
||||
inline int acd66_evaluate( word * pTruth, unsigned nVars )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
acd66_impl acd( nVars, true, false );
|
||||
|
||||
if ( acd.run( pTruth ) == 0 )
|
||||
return 0;
|
||||
if ( decomposition == NULL )
|
||||
return 1;
|
||||
int val = acd.compute_decomposition();
|
||||
if ( val != 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
acd.get_decomposition( decomposition );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned char *decomposition )
|
||||
int acdXX_evaluate( word * pTruth, unsigned lutSize, unsigned nVars )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
if ( lutSize == 6 )
|
||||
{
|
||||
return acd66_decompose( pTruth, nVars, decomposition );
|
||||
return acd66_evaluate( pTruth, nVars );
|
||||
}
|
||||
|
||||
acdXX_params ps;
|
||||
|
|
@ -153,14 +146,29 @@ int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned c
|
|||
|
||||
if ( acd.run( pTruth ) == 0 )
|
||||
return 0;
|
||||
if ( decomposition == NULL )
|
||||
return 1;
|
||||
int val = acd.compute_decomposition();
|
||||
if ( val != 0 )
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned char *decomposition )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
acdXX_params ps;
|
||||
ps.lut_size = lutSize;
|
||||
|
||||
for ( int i = 0; i <= lutSize - 2; ++i )
|
||||
{
|
||||
ps.max_shared_vars = i;
|
||||
ps.min_shared_vars = i;
|
||||
acdXX_impl acd( nVars, ps );
|
||||
|
||||
if ( acd.run( pTruth ) == 0 )
|
||||
continue;
|
||||
acd.compute_decomposition();
|
||||
acd.get_decomposition( decomposition );
|
||||
return 0;
|
||||
}
|
||||
acd.get_decomposition( decomposition );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ int acd_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay,
|
|||
int acd2_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival );
|
||||
int acd2_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition );
|
||||
|
||||
int acdXX_evaluate( word * pTruth, unsigned lutSize, unsigned nVars );
|
||||
int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned char *decomposition );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ struct acdXX_params
|
|||
/* Maximum number of variables in the shared set */
|
||||
uint32_t max_shared_vars{ 4 };
|
||||
|
||||
/* Minimum number of variables in the shared set */
|
||||
uint32_t min_shared_vars{ 0 };
|
||||
|
||||
/* Run verification */
|
||||
bool verify{ false };
|
||||
};
|
||||
|
|
@ -795,7 +798,7 @@ private:
|
|||
uint32_t max_shared_vars = std::min( ps.lut_size - best_free_set - 1, ps.max_shared_vars );
|
||||
|
||||
/* search for a feasible shared set */
|
||||
for ( uint32_t i = target_num_ss; i <= max_shared_vars; ++i )
|
||||
for ( uint32_t i = std::max( target_num_ss, ps.min_shared_vars ); i <= max_shared_vars; ++i )
|
||||
{
|
||||
for ( uint32_t i = 0; i < 6; ++i )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <iostream>
|
||||
|
||||
#include "kitty_algorithm.hpp"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
|
||||
#include "kitty_constants.hpp"
|
||||
#include "kitty_dynamic_tt.hpp"
|
||||
|
|
|
|||
|
|
@ -563,6 +563,8 @@ extern int If_CluCheckExt( void * p, word * pTruth, int nVars, int n
|
|||
char * pLut0, char * pLut1, word * pFunc0, word * pFunc1 );
|
||||
extern int If_CluCheckExt3( void * p, word * pTruth, int nVars, int nLutLeaf, int nLutLeaf2, int nLutRoot,
|
||||
char * pLut0, char * pLut1, char * pLut2, word * pFunc0, word * pFunc1, word * pFunc2 );
|
||||
extern int If_CluCheckXXExt( void * p, word * pTruth, int nVars, int nLutLeaf, int nLutRoot,
|
||||
char * pLut0, char * pLut1, word * pFunc0, word * pFunc1 );
|
||||
extern int If_MatchCheck1( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern int If_MatchCheck2( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
/*=== ifDelay.c =============================================================*/
|
||||
|
|
|
|||
|
|
@ -104,6 +104,27 @@ static inline int If_CluWordNum2( int nVars )
|
|||
return nVars <= 6 ? 1 : 1 << (nVars-6);
|
||||
}
|
||||
|
||||
static inline word If_CluAdjust2( word t, int nVars )
|
||||
{
|
||||
assert( nVars >= 0 && nVars <= 6 );
|
||||
if ( nVars == 6 )
|
||||
return t;
|
||||
t &= (((word)1) << (1 << nVars)) - 1;
|
||||
if ( nVars == 0 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 1 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 2 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 3 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 4 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 5 )
|
||||
t |= t << (1<<nVars++);
|
||||
return t;
|
||||
}
|
||||
|
||||
int If_CluHashFindMedian2( If_Man_t * p, int t )
|
||||
{
|
||||
If_Hte_t * pEntry;
|
||||
|
|
@ -267,7 +288,7 @@ int If_CluCheckXX( If_Man_t * p, word * pTruth0, int lutSize, int nVars, int fHa
|
|||
/* new entry */
|
||||
if ( G1.nVars == 0 )
|
||||
{
|
||||
G1.nVars = acdXX_decompose( pTruth0, lutSize, nVars, NULL );
|
||||
G1.nVars = acdXX_evaluate( pTruth0, lutSize, nVars );
|
||||
}
|
||||
|
||||
if ( pHashed )
|
||||
|
|
@ -276,6 +297,58 @@ int If_CluCheckXX( If_Man_t * p, word * pTruth0, int lutSize, int nVars, int fHa
|
|||
return G1.nVars;
|
||||
}
|
||||
|
||||
// returns the best group found
|
||||
int If_CluCheckXXExt( void * pMan, word * pTruth, int nVars, int nLutLeaf, int nLutRoot,
|
||||
char * pLut0, char * pLut1, word * pFunc0, word * pFunc1 )
|
||||
{
|
||||
(void)pMan;
|
||||
assert( nLutLeaf == nLutRoot );
|
||||
unsigned char result[32];
|
||||
int i;
|
||||
|
||||
if ( acdXX_decompose( pTruth, nLutRoot, nVars, result ) )
|
||||
{
|
||||
/* decomposition failed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy LUT bound set */
|
||||
unsigned char * pResult = result + 2;
|
||||
int Lut1Size = (int) (*pResult++);
|
||||
pLut1[0] = Lut1Size;
|
||||
pLut1[1] = 0; /* not used */
|
||||
for (i = 0; i < Lut1Size; ++i)
|
||||
{
|
||||
pLut1[2+i] = *pResult++;
|
||||
}
|
||||
int func_num_bytes = ( Lut1Size <= 3 ) ? 1 : ( 1 << ( Lut1Size - 3 ) );
|
||||
*pFunc1 = 0;
|
||||
for (i = 0; i < func_num_bytes; ++i)
|
||||
{
|
||||
*pFunc1 |= ( ( (word) *pResult++ ) & 0xFF ) << 8*i;
|
||||
}
|
||||
|
||||
/* copy LUT composition */
|
||||
int Lut0Size = (int) (*pResult++);
|
||||
pLut0[0] = Lut0Size;
|
||||
pLut0[1] = 0; /* not used */
|
||||
for (i = 0; i < Lut0Size; ++i)
|
||||
{
|
||||
pLut0[2+i] = *pResult++;
|
||||
}
|
||||
func_num_bytes = ( Lut0Size <= 3 ) ? 1 : ( 1 << ( Lut0Size - 3 ) );
|
||||
*pFunc0 = 0;
|
||||
for (i = 0; i < func_num_bytes; ++i)
|
||||
{
|
||||
*pFunc0 |= ( ( (word) *pResult++ ) & 0xFF ) << 8*i;
|
||||
}
|
||||
|
||||
*pFunc1 = If_CluAdjust2( *pFunc1, Lut1Size );
|
||||
*pFunc0 = If_CluAdjust2( *pFunc0, Lut0Size );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs ACD into 66 cascade.]
|
||||
|
|
|
|||
Loading…
Reference in New Issue