mirror of https://github.com/YosysHQ/abc.git
Updates to &if mapper.
This commit is contained in:
parent
7ae0f4966a
commit
fa5029da95
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -207,4 +207,3 @@ int If_ManPerformMappingComb( If_Man_t * p )
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue