mirror of https://github.com/YosysHQ/abc.git
Adding new command if -U for 2-LUT decompositions under delay profile
This commit is contained in:
parent
e8924e5534
commit
6052d10fde
|
|
@ -19514,7 +19514,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, "KCFAGRNTXYZDEWSJqaflepmrsdbgxyuojiktncvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYUZDEWSJqaflepmrsdbgxyuojiktncvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -19630,6 +19630,18 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pPars->nAndDelay < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'U':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-U\" should be followed by a positive integer 3, 4, 5, or 6.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nLutDecSize = atoi(argv[globalUtilOptind]);
|
||||
pPars->fUserLut2D = 1;
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nLutDecSize < 3 || pPars->nLutDecSize > 6 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'Z':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
|
|
@ -19892,7 +19904,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pPars->fCutMin = 1;
|
||||
}
|
||||
|
||||
if ( pPars->fUserLutDec )
|
||||
if ( pPars->fUserLutDec || pPars->fUserLut2D )
|
||||
{
|
||||
if ( pPars->nLutDecSize == 0 )
|
||||
{
|
||||
|
|
@ -19927,7 +19939,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pPars->pLutLib = NULL;
|
||||
}
|
||||
// modify for delay optimization
|
||||
if ( pPars->fDelayOpt || pPars->fDsdBalance || pPars->fDelayOptLut || pPars->fUserLutDec )
|
||||
if ( pPars->fDelayOpt || pPars->fDsdBalance || pPars->fDelayOptLut || pPars->fUserLutDec || pPars->fUserLut2D )
|
||||
{
|
||||
pPars->fTruth = 1;
|
||||
pPars->fCutMin = 1;
|
||||
|
|
@ -20073,7 +20085,7 @@ usage:
|
|||
sprintf(LutSize, "library" );
|
||||
else
|
||||
sprintf(LutSize, "%d", pPars->nLutSize );
|
||||
Abc_Print( -2, "usage: if [-KCFAGRNTXYZ num] [-DEW float] [-S str] [-qarlepmsdbgxyuojiktncvh]\n" );
|
||||
Abc_Print( -2, "usage: if [-KCFAGRNTXYUZ num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuojiktncvh]\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 );
|
||||
|
|
@ -20085,6 +20097,7 @@ usage:
|
|||
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-U num : the number of LUT inputs for delay-driven LUT decomposition [default = not used]\n" );
|
||||
Abc_Print( -2, "\t-Z num : the number of LUT inputs for delay-driven LUT decomposition [default = not used]\n" );
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
|
|||
pPars->pTimesReq = Abc_NtkGetCoRequiredFloats(pNtk);
|
||||
|
||||
// update timing info to reflect logic level
|
||||
if ( (pPars->fDelayOpt || pPars->fDsdBalance || pPars->fUserRecLib || pPars->fUserSesLib || pPars->fUserLutDec) && pNtk->pManTime )
|
||||
if ( (pPars->fDelayOpt || pPars->fDsdBalance || pPars->fUserRecLib || pPars->fUserSesLib || pPars->fUserLutDec || pPars->fUserLut2D ) && pNtk->pManTime )
|
||||
{
|
||||
int c;
|
||||
if ( pNtk->AndGateDelay == 0.0 )
|
||||
|
|
@ -433,8 +433,8 @@ Hop_Obj_t * Abc_NodeBuildFromMini( Hop_Man_t * pMan, If_Man_t * p, If_Cut_t * pC
|
|||
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 )
|
||||
{
|
||||
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 );
|
||||
|
||||
|
|
@ -460,7 +460,15 @@ Hop_Obj_t * Abc_NodeBuildFromMini( Hop_Man_t * pMan, If_Man_t * p, If_Cut_t * pC
|
|||
|
||||
// perform LUT-decomposition and return the LUT-structure
|
||||
unsigned char decompArray[92];
|
||||
int val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
int val;
|
||||
if ( pIfMan->pPars->fUserLutDec )
|
||||
{
|
||||
val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
}
|
||||
else
|
||||
{
|
||||
val = acd2_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
|
||||
|
|
@ -473,7 +481,7 @@ Hop_Obj_t * Abc_NodeBuildFromMini( Hop_Man_t * pMan, If_Man_t * p, If_Cut_t * pC
|
|||
word *tt;
|
||||
Abc_Obj_t *pNewNodes[5];
|
||||
|
||||
/* create intermediate LUTs*/
|
||||
/* create intermediate LUTs */
|
||||
assert( decompArray[1] <= 6 );
|
||||
Abc_Obj_t * pFanin;
|
||||
for ( i = 0; i < decompArray[1]; ++i )
|
||||
|
|
@ -537,7 +545,7 @@ Hop_Obj_t * Abc_NodeBuildFromMini( Hop_Man_t * pMan, If_Man_t * p, If_Cut_t * pC
|
|||
|
||||
/* check correct read */
|
||||
assert( byte_p == decompArray[0] );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -577,14 +585,15 @@ 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->fUserLutDec && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize )
|
||||
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserLutDec && !pIfMan->pPars->fUserLut2D && !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 )
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D )
|
||||
{
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
|
||||
Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover);
|
||||
|
|
@ -642,7 +651,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 )
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D )
|
||||
{
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -147,7 +147,8 @@ struct If_Par_t_
|
|||
int fDeriveLuts; // enables deriving LUT structures
|
||||
int fDoAverage; // optimize average rather than maximum level
|
||||
int fHashMapping; // perform AIG hashing after mapping
|
||||
int fUserLutDec; // perform AIG hashing after mapping
|
||||
int fUserLutDec; // perform Boolean decomposition during mapping
|
||||
int fUserLut2D; // perform Boolean decomposition during mapping
|
||||
int fVerbose; // the verbosity flag
|
||||
int fVerboseTrace; // the verbosity flag
|
||||
char * pLutStruct; // LUT structure
|
||||
|
|
@ -573,6 +574,7 @@ extern int If_CutSopBalancePinDelays( If_Man_t * p, If_Cut_t * pCut,
|
|||
extern int If_CutLutBalanceEval( If_Man_t * p, If_Cut_t * pCut );
|
||||
extern int If_CutLutBalancePinDelays( If_Man_t * p, If_Cut_t * pCut, char * pPerm );
|
||||
extern int If_LutDecEval( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pObj, int optDelay, int fFirst );
|
||||
extern int If_Lut2DecEval( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pObj, int optDelay, int fFirst );
|
||||
extern int If_LutDecReEval( If_Man_t * p, If_Cut_t * pCut );
|
||||
extern float If_LutDecPinRequired( If_Man_t * p, If_Cut_t * pCut, int i, float required );
|
||||
/*=== ifDsd.c =============================================================*/
|
||||
|
|
@ -704,6 +706,8 @@ extern void If_ObjPrint( If_Obj_t * pObj );
|
|||
|
||||
extern int acd_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival );
|
||||
extern int acd_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition );
|
||||
extern int acd2_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival );
|
||||
extern int acd2_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ void If_ManSetDefaultPars( If_Par_t * pPars )
|
|||
pPars->fCutMin = 0;
|
||||
pPars->fBidec = 0;
|
||||
pPars->fUserLutDec = 0;
|
||||
pPars->fUserLut2D = 0;
|
||||
pPars->fVerbose = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -761,7 +761,7 @@ void If_CutSort( If_Man_t * p, If_Set_t * pCutSet, If_Cut_t * pCut )
|
|||
|
||||
if ( !pCut->fUseless &&
|
||||
(p->pPars->fUseDsd || p->pPars->pFuncCell2 || p->pPars->fUseBat ||
|
||||
p->pPars->pLutStruct || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUserLutDec ||
|
||||
p->pPars->pLutStruct || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUserLutDec || p->pPars->fUserLut2D ||
|
||||
p->pPars->fEnableCheck07 || p->pPars->fUseCofVars || p->pPars->fUseAndVars || p->pPars->fUse34Spec ||
|
||||
p->pPars->fUseDsdTune || p->pPars->fEnableCheck75 || p->pPars->fEnableCheck75u || p->pPars->fUseCheck1 || p->pPars->fUseCheck2) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -505,6 +505,95 @@ int If_LutDecEval( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pObj, int optDelay,
|
|||
return DelayMax + val;
|
||||
}
|
||||
|
||||
int If_Lut2DecEval( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pObj, int optDelay, int fFirst )
|
||||
{
|
||||
pCut->fUser = 1;
|
||||
pCut->Cost = pCut->nLeaves > 1 ? 1 : 0;
|
||||
pCut->decDelay = 0;
|
||||
if ( pCut->nLeaves == 0 ) // const
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 0 );
|
||||
return 0;
|
||||
}
|
||||
if ( pCut->nLeaves == 1 ) // variable
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 1 );
|
||||
return (int)If_ObjCutBest(If_CutLeaf(p, pCut, 0))->Delay;
|
||||
}
|
||||
|
||||
int LutSize = p->pPars->nLutDecSize;
|
||||
int i, leaf_delay;
|
||||
int DelayMax = -1, nLeafMax = 0;
|
||||
unsigned uLeafMask = 0;
|
||||
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
|
||||
{
|
||||
leaf_delay = If_ObjCutBest(If_CutLeaf(p, pCut, i))->Delay;
|
||||
|
||||
if ( DelayMax < leaf_delay )
|
||||
{
|
||||
DelayMax = leaf_delay;
|
||||
nLeafMax = 1;
|
||||
uLeafMask = (1 << i);
|
||||
}
|
||||
else if ( DelayMax == leaf_delay )
|
||||
{
|
||||
nLeafMax++;
|
||||
uLeafMask |= (1 << i);
|
||||
}
|
||||
}
|
||||
if ( If_CutLeaveNum(pCut) <= LutSize )
|
||||
{
|
||||
pCut->decDelay = ( 1 << LutSize ) - 1;
|
||||
return DelayMax + 1;
|
||||
}
|
||||
|
||||
/* compute the decomposition */
|
||||
int use_late_arrival = 0;
|
||||
unsigned cost = 1;
|
||||
|
||||
if ( !fFirst )
|
||||
{
|
||||
if ( optDelay )
|
||||
{
|
||||
/* checks based on delay: must be better than the previous best cut */
|
||||
use_late_arrival = DelayMax + 2 >= If_ObjCutBest(pObj)->Delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* checks based on delay: look at the required time */
|
||||
use_late_arrival = DelayMax + 2 > pObj->Required + p->fEpsilon;
|
||||
}
|
||||
}
|
||||
|
||||
/* Too many late-arriving signals */
|
||||
if ( nLeafMax == LutSize && use_late_arrival )
|
||||
{
|
||||
/* unfeasible decomposition */
|
||||
pCut->Cost = IF_COST_MAX;
|
||||
return ABC_INFINITY;
|
||||
}
|
||||
|
||||
if ( !use_late_arrival )
|
||||
{
|
||||
uLeafMask = 0;
|
||||
}
|
||||
|
||||
/* returns the delay of the decomposition */
|
||||
word *pTruth = If_CutTruthW( p, pCut );
|
||||
int val = acd2_evaluate( pTruth, pCut->nLeaves, LutSize, &uLeafMask, &cost, !use_late_arrival );
|
||||
|
||||
/* not feasible decomposition */
|
||||
pCut->decDelay = uLeafMask;
|
||||
if ( val < 0 )
|
||||
{
|
||||
pCut->Cost = IF_COST_MAX;
|
||||
return ABC_INFINITY;
|
||||
}
|
||||
|
||||
pCut->Cost = 2;
|
||||
return DelayMax + val;
|
||||
}
|
||||
|
||||
int If_LutDecReEval( If_Man_t * p, If_Cut_t * pCut )
|
||||
{
|
||||
// pCut->fUser = 1;
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
If_Cut_t * pCut0R, * pCut1R;
|
||||
int fFunc0R, fFunc1R;
|
||||
int i, k, v, iCutDsd, fChange;
|
||||
int fSave0 = p->pPars->fDelayOpt || p->pPars->fDelayOptLut || p->pPars->fDsdBalance || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUserLutDec ||
|
||||
int fSave0 = p->pPars->fDelayOpt || p->pPars->fDelayOptLut || p->pPars->fDsdBalance || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUserLutDec || p->pPars->fUserLut2D ||
|
||||
p->pPars->fUseDsdTune || p->pPars->fUseCofVars || p->pPars->fUseAndVars || p->pPars->fUse34Spec || p->pPars->pLutStruct || p->pPars->pFuncCell2 || p->pPars->fUseCheck1 || p->pPars->fUseCheck2;
|
||||
int fUseAndCut = (p->pPars->nAndDelay > 0) || (p->pPars->nAndArea > 0);
|
||||
assert( !If_ObjIsAnd(pObj->pFanin0) || pObj->pFanin0->pCutSet->nCuts > 0 );
|
||||
|
|
@ -208,7 +208,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
pCut->fUseless = 1;
|
||||
}
|
||||
}
|
||||
else if ( p->pPars->fUserLutDec )
|
||||
else if ( p->pPars->fUserLutDec || p->pPars->fUserLut2D )
|
||||
{
|
||||
pCut->Delay = If_LutDecReEval( p, pCut );
|
||||
}
|
||||
|
|
@ -434,6 +434,11 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
pCut->Delay = If_LutDecEval( p, pCut, pObj, Mode == 0, fFirst );
|
||||
pCut->fUseless = pCut->Delay == ABC_INFINITY;
|
||||
}
|
||||
else if ( p->pPars->fUserLut2D )
|
||||
{
|
||||
pCut->Delay = If_Lut2DecEval( p, pCut, pObj, Mode == 0, fFirst );
|
||||
pCut->fUseless = pCut->Delay == ABC_INFINITY;
|
||||
}
|
||||
else if ( p->pPars->fUserSesLib )
|
||||
{
|
||||
int Cost = 0;
|
||||
|
|
@ -518,7 +523,7 @@ void If_ObjPerformMappingChoice( If_Man_t * p, If_Obj_t * pObj, int Mode, int fP
|
|||
If_Set_t * pCutSet;
|
||||
If_Obj_t * pTemp;
|
||||
If_Cut_t * pCutTemp, * pCut;
|
||||
int i, fSave0 = p->pPars->fDelayOpt || p->pPars->fDelayOptLut || p->pPars->fDsdBalance || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUse34Spec || p->pPars->fUserLutDec;
|
||||
int i, fSave0 = p->pPars->fDelayOpt || p->pPars->fDelayOptLut || p->pPars->fDsdBalance || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUse34Spec || p->pPars->fUserLutDec || p->pPars->fUserLut2D;
|
||||
assert( pObj->pEquiv != NULL );
|
||||
|
||||
// prepare
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ void If_CutPropagateRequired( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut, fl
|
|||
pLeaf->Required = IF_MIN( pLeaf->Required, Required - pLutDelays[0] );
|
||||
}
|
||||
}
|
||||
else if ( p->pPars->fUserLutDec )
|
||||
else if ( p->pPars->fUserLutDec || p->pPars->fUserLut2D )
|
||||
{
|
||||
Required = ObjRequired;
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
|
|
|
|||
Loading…
Reference in New Issue