Updates to &if mapper.

This commit is contained in:
Alan Mishchenko 2026-03-10 22:19:37 -07:00
parent 7ae0f4966a
commit fa5029da95
9 changed files with 249 additions and 47 deletions

View File

@ -1190,7 +1190,7 @@ int Gia_ManFromIfLogicCreateLutSpecialJ( Gia_Man_t * pNew, word * pRes, Vec_Int_
{
word Truth;
int i, iObjLit1, iObjLit2, iObjLit3;
word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1 );
word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1, 0 );
assert( z != 0 );
if ( ((z >> 63) & 1) == 0 )
{
@ -2135,7 +2135,7 @@ void Gia_ManConfigPrint2( unsigned char * pConfigData, int nLeaves )
SeeAlso []
***********************************************************************/
void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * pTruth, int nLeaves )
void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * pTruth, int nLeaves, int fDelay )
{
int i, CellId;
int startPos = Vec_StrSize(vConfigs2);
@ -2143,13 +2143,18 @@ void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * p
// Determine cell type based on the number of leaves and configuration
if ( nLeaves <= 4 ) // 7 bytes = 1 byte CellId + 4 bytes mapping + 2 bytes truth table
{
word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1, fDelay );
int fHavePerm = (z != 0) && ((z & ABC_CONST(0x4000000000000000)) != 0);
// Cell type 0: Simple LUT4
CellId = 0;
// Write CellId
Vec_StrPush( vConfigs2, (char)CellId );
// Write mapping
for ( i = 0; i < nLeaves; i++ )
Vec_StrPush( vConfigs2, 2+i );
{
int v = fHavePerm ? (int)((z >> (2 * i)) & 3) : i;
Vec_StrPush( vConfigs2, 2 + v );
}
for ( ; i < 4; i++ )
Vec_StrPush( vConfigs2, 0 );
// Write truth table (16 bits for LUT4)
@ -2161,7 +2166,7 @@ void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * p
}
else // 12 bytes = 1 byte CellId + 7 bytes mapping + 4 bytes truth tables
{
word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1 );
word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1, fDelay );
//Gia_ManConfigPrint( 0, z, nLeaves );
if ( ((z >> 63) & 1) == 0 )
{
@ -2551,7 +2556,16 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
Abc_TtFlip( pTruth, Abc_TtWordNum(pCutBest->nLeaves), k );
if ( Abc_LitIsCompl(pIfObj->iCopy) ^ pCutBest->fCompl )
Abc_TtNot( pTruth, Abc_TtWordNum(pCutBest->nLeaves) );
Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pTruth, pCutBest->nLeaves );
if ( pIfMan->pPars->fDelayOptCell )
{
pIfMan->nCutLeavesCur = pCutBest->nLeaves;
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
{
pIfMan->pCutLeavesCur[k] = pIfLeaf->Id;
pIfMan->pCutLeafArrCur[k] = If_ObjCutBest(pIfLeaf)->Delay;
}
}
Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pTruth, pCutBest->nLeaves, pIfMan->pPars->fDelayOptCell );
}
}
else
@ -3337,4 +3351,3 @@ Gia_Man_t * Gia_ManDupUnhashMapping( Gia_Man_t * p )
ABC_NAMESPACE_IMPL_END

View File

@ -33,6 +33,54 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static int Gia_ManConfig2GetBytePos( Gia_Man_t * p, int iObj )
{
int iLut, bytePos = 0;
if ( p == NULL || p->vConfigs2 == NULL )
return -1;
Gia_ManForEachLut( p, iLut )
{
unsigned char CellId;
if ( bytePos >= Vec_StrSize(p->vConfigs2) )
return -1;
if ( iLut == iObj )
return bytePos;
CellId = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos );
if ( CellId == 0 )
bytePos += 7;
else if ( CellId == 1 )
bytePos += 12;
else if ( CellId == 2 )
bytePos += 14;
else
return -1;
}
return -1;
}
static int Gia_ManConfig2DerivePinDelays( Gia_Man_t * p, int iObj, If_LibCell_t * pCellLib, int * pPinDelay, int nLutSize )
{
int bytePos, i, nPins;
unsigned char CellId;
if ( pCellLib == NULL || pPinDelay == NULL || nLutSize < 1 || nLutSize > 32 )
return 0;
for ( i = 0; i < nLutSize; i++ )
pPinDelay[i] = 1;
bytePos = Gia_ManConfig2GetBytePos( p, iObj );
if ( bytePos < 0 || bytePos >= Vec_StrSize(p->vConfigs2) )
return 0;
CellId = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos );
if ( CellId >= pCellLib->nCellNum )
return 0;
nPins = Abc_MinInt( pCellLib->nCellInputs[CellId], 9 );
for ( i = 0; i < nPins; i++ )
{
int v = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos + 1 + i );
if ( v >= 2 && v < 2 + nLutSize )
pPinDelay[v - 2] = pCellLib->pCellPinDelays[CellId][i];
}
return 1;
}
/**Function*************************************************************
Synopsis [Sorts the pins in the decreasing order of delays.]
@ -113,7 +161,7 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
int k, iFanin, pPinPerm[32];
int k, iFanin, pPinPerm[32], pPinDelay[32];
float pPinDelays[32];
float tArrival, * pDelays;
if ( Gia_ObjIsCi(pObj) )
@ -132,15 +180,17 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
{
// Handle cell library delays (use integer delays directly)
int nLutSize = Gia_ObjLutSize(p, iObj);
int fHaveCfg2 = Gia_ManConfig2DerivePinDelays( p, iObj, pCellLib, pPinDelay, nLutSize );
// Find matching cell (simple approach: use first cell with enough inputs)
int cellId = -1;
int i;
for ( i = 0; i < pCellLib->nCellNum; i++ )
if ( pCellLib->nCellInputs[i] >= nLutSize )
{
cellId = i;
break;
}
if ( !fHaveCfg2 )
for ( i = 0; i < pCellLib->nCellNum; i++ )
if ( pCellLib->nCellInputs[i] >= nLutSize )
{
cellId = i;
break;
}
if ( cellId >= 0 )
{
// Use cell delays as integers from the library
@ -151,6 +201,15 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
tArrival = Gia_ObjTimeArrival(p, iFanin) + delay;
}
}
else if ( fHaveCfg2 )
{
Gia_LutForEachFanin( p, iObj, iFanin, k )
{
float delay = (float)pPinDelay[k];
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + delay )
tArrival = Gia_ObjTimeArrival(p, iFanin) + delay;
}
}
else
{
// Fall back to default delay if no matching cell
@ -204,7 +263,7 @@ float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting )
{
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
int k, iFanin, pPinPerm[32];
int k, iFanin, pPinPerm[32], pPinDelay[32];
float pPinDelays[32];
float tRequired = 0.0; // Suppress "might be used uninitialized"
float * pDelays;
@ -223,15 +282,17 @@ float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting )
{
// Handle cell library delays (use integer delays directly)
int nLutSize = Gia_ObjLutSize(p, iObj);
int fHaveCfg2 = Gia_ManConfig2DerivePinDelays( p, iObj, pCellLib, pPinDelay, nLutSize );
// Find matching cell (simple approach: use first cell with enough inputs)
int cellId = -1;
int i;
for ( i = 0; i < pCellLib->nCellNum; i++ )
if ( pCellLib->nCellInputs[i] >= nLutSize )
{
cellId = i;
break;
}
if ( !fHaveCfg2 )
for ( i = 0; i < pCellLib->nCellNum; i++ )
if ( pCellLib->nCellInputs[i] >= nLutSize )
{
cellId = i;
break;
}
if ( cellId >= 0 )
{
// Use cell delays as integers from the library
@ -243,6 +304,15 @@ float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting )
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
}
}
else if ( fHaveCfg2 )
{
Gia_LutForEachFanin( p, iObj, iFanin, k )
{
tRequired = Gia_ObjTimeRequired( p, iObj ) - (float)pPinDelay[k];
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
}
}
else
{
// Fall back to default delay if no matching cell
@ -977,4 +1047,3 @@ Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerb
ABC_NAMESPACE_IMPL_END

View File

@ -22285,7 +22285,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, "KCFAGRNTXYUZDEWSJqalepmrsdbgxyzuojiktncfvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYZUDEWSJqalepmrsdbgxyzuoiktncfvh" ) ) != EOF )
{
switch ( c )
{
@ -22535,9 +22535,9 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'o':
pPars->fUseBuffs ^= 1;
break;
case 'j':
pPars->fEnableCheck07 ^= 1;
break;
//case 'j':
// pPars->fEnableCheck07 ^= 1;
// break;
case 'i':
pPars->fUseCofVars ^= 1;
break;
@ -22867,7 +22867,7 @@ usage:
sprintf(LutSize, "library" );
else
sprintf(LutSize, "%d", pPars->nLutSize );
Abc_Print( -2, "usage: if [-KCFAGRNTXYUZ num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuojiktnczfvh]\n" );
Abc_Print( -2, "usage: if [-KCFAGRNTXYZMU num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuoiktnczfvh]\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 );
@ -22901,7 +22901,7 @@ usage:
Abc_Print( -2, "\t-y : toggles delay optimization with recorded library [default = %s]\n", pPars->fUserRecLib? "yes": "no" );
Abc_Print( -2, "\t-u : toggles delay optimization with SAT-based library [default = %s]\n", pPars->fUserSesLib? "yes": "no" );
Abc_Print( -2, "\t-o : toggles using buffers to decouple combinational outputs [default = %s]\n", pPars->fUseBuffs? "yes": "no" );
Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" );
//Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" );
Abc_Print( -2, "\t-i : toggles using cofactoring variables [default = %s]\n", pPars->fUseCofVars? "yes": "no" );
Abc_Print( -2, "\t-k : toggles matching based on precomputed DSD manager [default = %s]\n", pPars->fUseDsdTune? "yes": "no" );
Abc_Print( -2, "\t-t : toggles optimizing average rather than maximum level [default = %s]\n", pPars->fDoAverage? "yes": "no" );
@ -44067,8 +44067,9 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_FrameSetLibLut( If_LibLutSetSimple( 6 ) );
}
pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut();
pPars->pCellLib = (If_LibCell_t *)Abc_FrameReadLibCell();
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSJTXYZqalepmrsdbgxyofuijkztncvwh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSJTXYZMqalepmrsdbgxyofuijkztncvwh" ) ) != EOF )
{
switch ( c )
{
@ -44084,6 +44085,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
// if the LUT size is specified, disable library
pPars->pLutLib = NULL;
pPars->pCellLib = NULL;
break;
case 'C':
if ( globalUtilOptind >= argc )
@ -44173,6 +44175,21 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nAndDelay < 0 )
goto usage;
break;
case 'M':
{
int Value;
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-M\" should be followed by 0 or 1.\n" );
goto usage;
}
Value = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Value < 0 || Value > 1 )
goto usage;
pPars->fDelayOptCell = Value;
break;
}
case 'D':
if ( globalUtilOptind >= argc )
{
@ -44349,6 +44366,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 1, "Auto-detected K=%d from cell library (max inputs).\n", nMaxInputs );
// Disable LUT library since we're using K from cell library
pPars->pLutLib = NULL;
pPars->pCellLib = pCellLib;
}
}
}
@ -44537,6 +44555,11 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->nLutSize = 4;
}
if ( pPars->fEnableCheck07 )
pPars->nCutsMax = Abc_MaxInt( pPars->nCutsMax, 16 );
else
pPars->pCellLib = NULL;
// enable truth table computation if cut minimization is selected
if ( pPars->fCutMin || pPars->fDeriveLuts )
{
@ -44672,7 +44695,7 @@ usage:
sprintf(LutSize, "library" );
else
sprintf(LutSize, "%d", pPars->nLutSize );
Abc_Print( -2, "usage: &if [-KCFAGRTXY num] [-DEW float] [-SJ str] [-qarlepmsdbgxyofuijkztnchvw]\n" );
Abc_Print( -2, "usage: &if [-KCFAGRTXYZM 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 );
@ -44683,6 +44706,7 @@ usage:
Abc_Print( -2, "\t-T num : the type of LUT structures [default = any]\n", pPars->nStructType );
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-M num : enables delay-driven decomposition [default = %d]\n", pPars->fDelayOptCell );
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 );
@ -48585,22 +48609,13 @@ int Abc_CommandAbc9Trace( Abc_Frame_t * pAbc, int argc, char ** argv )
pAbc->pGia->pLutLib = fUseLutLib ? Abc_FrameReadLibLut() : NULL;
pAbc->pGia->pCellLib = fUseCellLib ? Abc_FrameReadLibCell() : NULL;
if ( pFileName )
{
// Dump the delay trace to file
Gia_ManDelayTraceDump( pAbc->pGia, (char *)pFileName );
}
else
{
// Print the delay trace to console
Gia_ManDelayTraceLutPrint( pAbc->pGia, fVerbose );
}
Gia_ManDelayTraceDump( pAbc->pGia, (char *)pFileName );
return 0;
usage:
Abc_Print( -2, "usage: &trace [-F file] [-lcvh]\n" );
Abc_Print( -2, "\t performs delay trace of LUT-mapped network\n" );
Abc_Print( -2, "\t-F file : dump the critical path to a file [default = console output]\n" );
Abc_Print( -2, "\t-F file : dump the critical path to a file [default = stdout]\n" );
Abc_Print( -2, "\t-l : toggle using LUT-library-delay model [default = %s]\n", fUseLutLib? "yes": "no" );
Abc_Print( -2, "\t-c : toggle using cell-library-delay model [default = %s]\n", fUseCellLib? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" );

View File

@ -126,6 +126,7 @@ struct If_Par_t_
int fCutMin; // performs cut minimization by removing functionally reducdant variables
int fDelayOpt; // special delay optimization
int fDelayOptLut; // delay optimization for LUTs
int fDelayOptCell; // delay optimization for cells
int fDsdBalance; // special delay optimization
int fUserRecLib; // use recorded library
int fUserSesLib; // use SAT-based synthesis
@ -175,6 +176,7 @@ struct If_Par_t_
float FinalDelay; // final delay after mapping
float FinalArea; // final area after mapping
If_LibLut_t * pLutLib; // the LUT library
If_LibCell_t * pCellLib; // the cell library
float * pTimesArr; // arrival times
float * pTimesReq; // required times
int (* pFuncCost) (If_Man_t *, If_Cut_t *); // procedure to compute the user's cost of a cut
@ -299,6 +301,14 @@ struct If_Man_t_
Vec_Int_t * vVisited2;
Vec_Int_t * vCuts;
Vec_Int_t * vCutCosts;
// current cut context for user callbacks
If_Obj_t * pCutObjCur; // current object whose cut is being checked
If_Cut_t * pCutCur; // current cut being checked
int nCutLeavesCur; // number of leaves in current cut
int pCutLeavesCur[IF_MAX_LUTSIZE]; // current cut leaves (IDs)
float pCutLeafArrCur[IF_MAX_LUTSIZE]; // current cut leaf arrivals
float CutDelayCur; // current cut delay returned by user callback
int fCutDelayCurValid; // indicates CutDelayCur is valid
// timing manager
Tim_Man_t * pManTim;
@ -319,6 +329,7 @@ struct If_Cut_t_
float Edge; // the edge flow
float Power; // the power flow
float Delay; // delay of the cut
word Config; // configuration string
int iCutFunc; // TT ID of the cut
int uMaskFunc; // polarity bitmask
unsigned uSign; // cut signature
@ -564,7 +575,8 @@ extern float If_CutPowerDerefed( If_Man_t * p, If_Cut_t * pCut, If_Obj
extern float If_CutPowerRefed( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot );
/*=== ifDec.c =============================================================*/
extern word If_CutPerformDerive07( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive );
extern word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive, int fDelay );
extern void If_CutComputeIntrinsicJ( If_Man_t * p, word Config, int nLeaves, int * pIntrinsicDelays );
extern int If_CutPerformCheck07( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck08( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck10( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );

View File

@ -207,4 +207,3 @@ int If_ManPerformMappingComb( If_Man_t * p )
ABC_NAMESPACE_IMPL_END

View File

@ -35,10 +35,13 @@ int If_CutPerformCheckJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves
{
return 1;
}
word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive )
word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive, int fDelay )
{
return 0;
}
void If_CutComputeIntrinsicJ( If_Man_t * p, word Config, int nLeaves, int * pIntrinsicDelays )
{
}
void If_PermUnpack( unsigned Value, int Pla2Var[9] )
{
}
@ -52,4 +55,3 @@ void Gia_ManDelayTraceDump( Gia_Man_t * p, char * pFileName )
ABC_NAMESPACE_IMPL_END

View File

@ -719,6 +719,7 @@ void If_ManSetupCutTriv( If_Man_t * p, If_Cut_t * pCut, int ObjId )
pCut->uSign = If_ObjCutSign( pCut->pLeaves[0] );
pCut->iCutFunc = p->pPars->fUseTtPerm ? 3 : (p->pPars->fTruth ? 2: -1);
pCut->uMaskFunc = 0;
pCut->Config = 0;
assert( pCut->pLeaves[0] < p->vObjs->nSize );
}

View File

@ -162,6 +162,7 @@ int * If_CutArrTimeProfile( If_Man_t * p, If_Cut_t * pCut )
void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPreprocess, int fFirst )
{
If_Set_t * pCutSet;
If_Obj_t * pLeaf;
If_Cut_t * pCut0, * pCut1, * pCut;
If_Cut_t * pCut0R, * pCut1R;
int fFunc0R, fFunc1R;
@ -193,6 +194,31 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
pCut->Delay = If_CutSopBalanceEval( p, pCut, NULL );
else if ( p->pPars->fDsdBalance )
pCut->Delay = If_CutDsdBalanceEval( p, pCut, NULL );
else if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell )
{
int iLeaf, Intrinsic[IF_MAX_LUTSIZE];
float Delay = -IF_FLOAT_LARGE;
if ( pCut->nLeaves == 0 )
{
pCut->fUseless = 0;
pCut->Delay = 0.0;
goto IfMapBestCutDone;
}
assert( pCut->nLeaves == 1 || pCut->Config );
If_CutComputeIntrinsicJ( p, pCut->Config, pCut->nLeaves, Intrinsic );
If_CutForEachLeaf( p, pCut, pLeaf, iLeaf )
{
If_Cut_t * pBestCut = If_ObjCutBest( pLeaf );
assert( pBestCut != NULL );
assert( pBestCut->fUseless == 0 );
Delay = IF_MAX( Delay, If_ObjArrTime(pLeaf) + (float)Intrinsic[iLeaf] );
}
pCut->fUseless = (Delay > IF_FLOAT_LARGE/2);
pCut->Delay = Delay;
IfMapBestCutDone:
// if ( pCut->nLeaves == 9 && !pCut->fUseless )
// Abc_Print( 1, "Delay-debug(Map9-best): obj=%d delay=%.2f\n", pObj->Id, pCut->Delay );
}
else if ( p->pPars->fUserRecLib )
pCut->Delay = If_CutDelayRecCost3( p, pCut, pObj );
else if ( p->pPars->fUserSesLib )
@ -324,12 +350,32 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
{
assert( p->pPars->fUseTtPerm == 0 );
assert( pCut->nLimit >= 4 && pCut->nLimit <= 16 );
pCut->Config = 0;
if ( p->pPars->fUseDsd )
pCut->fUseless = If_DsdManCheckDec( p->pIfDsdMan, If_CutDsdLit(p, pCut) );
else if ( p->pPars->pFuncCell2 )
pCut->fUseless = !p->pPars->pFuncCell2( p, (word *)If_CutTruthW(p, pCut), pCut->nLeaves, NULL, NULL );
else
{
int iLeaf;
// Expose current cut context for user callbacks.
p->pCutObjCur = pObj;
p->pCutCur = pCut;
p->nCutLeavesCur = pCut->nLeaves;
for ( iLeaf = 0; iLeaf < p->nCutLeavesCur; iLeaf++ )
{
If_Obj_t * pLeaf = If_CutLeaf( p, pCut, iLeaf );
if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell && pCut->nLeaves > 1 )
{
If_Cut_t * pBestCut = If_ObjCutBest( pLeaf );
assert( pBestCut != NULL );
assert( pBestCut->fUseless == 0 );
}
p->pCutLeavesCur[iLeaf] = pLeaf->Id;
p->pCutLeafArrCur[iLeaf] = If_ObjArrTime( pLeaf );
}
pCut->fUseless = !p->pPars->pFuncCell( p, If_CutTruth(p, pCut), Abc_MaxInt(6, pCut->nLeaves), pCut->nLeaves, p->pPars->pLutStruct );
}
p->nCutsUselessAll += pCut->fUseless;
p->nCutsUseless[pCut->nLeaves] += pCut->fUseless;
p->nCutsCountAll++;
@ -427,6 +473,28 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
pCut->Delay = If_CutSopBalanceEval( p, pCut, NULL );
else if ( p->pPars->fDsdBalance )
pCut->Delay = If_CutDsdBalanceEval( p, pCut, NULL );
else if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell )
{
if ( pCut->nLeaves == 0 )
{
pCut->Delay = 0.0;
pCut->fUseless = 0;
goto IfMapCutEvalDone;
}
if ( pCut->nLeaves == 1 )
{
pLeaf = If_ManObj( p, pCut->pLeaves[0] );
pCut->Delay = If_ObjArrTime( pLeaf );
pCut->fUseless = 0;
goto IfMapCutEvalDone;
}
assert( pCut->fUseless || p->fCutDelayCurValid );
assert( pCut->fUseless || pCut->Config != 0 );
pCut->Delay = pCut->fUseless ? IF_FLOAT_LARGE : p->CutDelayCur;
IfMapCutEvalDone:
// if ( pCut->nLeaves == 9 && !pCut->fUseless )
// Abc_Print( 1, "Delay-debug(Map9): obj=%d delay=%.2f\n", pObj->Id, pCut->Delay );
}
else if ( p->pPars->fUserRecLib )
pCut->Delay = If_CutDelayRecCost3( p, pCut, pObj );
else if ( p->pPars->fUserLutDec )
@ -502,7 +570,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
if ( Mode && pObj->nRefs > 0 )
If_CutAreaRef( p, If_ObjCutBest(pObj) );
if ( If_ObjCutBest(pObj)->fUseless )
Abc_Print( 1, "The best cut is useless.\n" );
Abc_Print( 1, "The best cut is useless. Please increase the number of cuts used by the mapper, for example: \"&if -C 32\"\n" );
// call the user specified function for each cut
if ( p->pPars->pFuncUser )
If_ObjForEachCut( pObj, pCut, i )
@ -702,4 +770,3 @@ int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode, int fPrepr
ABC_NAMESPACE_IMPL_END

View File

@ -131,6 +131,20 @@ float If_CutDelay( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut )
}
else
{
if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell && p->pPars->pCellLib )
{
int Intrinsic[IF_MAX_LUTSIZE];
if ( pCut->nLeaves == 0 )
return 0.0;
assert( pCut->nLeaves == 1 || pCut->Config != 0 );
If_CutComputeIntrinsicJ( p, pCut->Config, pCut->nLeaves, Intrinsic );
If_CutForEachLeaf( p, pCut, pLeaf, i )
{
DelayCur = If_ObjCutBest(pLeaf)->Delay + (float)Intrinsic[i];
Delay = IF_MAX( Delay, DelayCur );
}
return Delay;
}
if ( pCut->fUser )
{
assert( !p->pPars->fLiftLeaves );
@ -219,6 +233,17 @@ void If_CutPropagateRequired( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut, fl
}
else
{
if ( p->pPars->fEnableCheck07 && p->pPars->fDelayOptCell && p->pPars->pCellLib )
{
int Intrinsic[IF_MAX_LUTSIZE];
if ( pCut->nLeaves == 0 )
return;
assert( (pObj && pObj->Id == 0) || pCut->nLeaves == 1 || pCut->Config != 0 );
If_CutComputeIntrinsicJ( p, pCut->Config, pCut->nLeaves, Intrinsic );
If_CutForEachLeaf( p, pCut, pLeaf, i )
pLeaf->Required = IF_MIN( pLeaf->Required, ObjRequired - (float)Intrinsic[i] );
return;
}
if ( pCut->fUser )
{
char Perm[IF_MAX_FUNC_LUTSIZE], * pPerm = Perm;
@ -528,4 +553,3 @@ void If_ManComputeRequired( If_Man_t * p )
ABC_NAMESPACE_IMPL_END