Commit 1d25ae3b by Alan Mishchenko

Experiment with technology mapping.

parent d2cab859
...@@ -13612,14 +13612,21 @@ usage: ...@@ -13612,14 +13612,21 @@ usage:
***********************************************************************/ ***********************************************************************/
int Abc_CommandIfif( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandIfif( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
extern void Abc_NtkPerformIfif( Abc_Ntk_t * pNtk, int nDelayLut, int nDegree, int fVerbose ); extern void Abc_NtkPerformIfif( Abc_Ntk_t * pNtk, Ifif_Par_t * pPars );
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
int c; Ifif_Par_t Pars, * pPars = &Pars;
int nDelayLut = 5; int c, fError;
int nDegree = 3;
int fVerbose = 0; pPars->nLutSize = -1; // the LUT size
pPars->pLutLib = (If_Lib_t *)Abc_FrameReadLibLut(); // the LUT library
pPars->DelayWire = (float)0.5; // wire delay
pPars->nDegree = 0; // structure degree
pPars->fCascade = 0; // cascade
pPars->fVerbose = 0; // verbose
pPars->fVeryVerbose = 0; // verbose
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "DNvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "DNcvwh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -13629,9 +13636,9 @@ int Abc_CommandIfif( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -13629,9 +13636,9 @@ int Abc_CommandIfif( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Command line switch \"-D\" should be followed by a floating point number.\n" ); Abc_Print( -1, "Command line switch \"-D\" should be followed by a floating point number.\n" );
goto usage; goto usage;
} }
nDelayLut = atoi(argv[globalUtilOptind]); pPars->DelayWire = atof(argv[globalUtilOptind]);
globalUtilOptind++; globalUtilOptind++;
if ( nDelayLut <= 0.0 ) if ( pPars->DelayWire < 0.0 )
goto usage; goto usage;
break; break;
case 'N': case 'N':
...@@ -13640,13 +13647,19 @@ int Abc_CommandIfif( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -13640,13 +13647,19 @@ int Abc_CommandIfif( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Command line switch \"-N\" should be followed by a floating point number.\n" ); Abc_Print( -1, "Command line switch \"-N\" should be followed by a floating point number.\n" );
goto usage; goto usage;
} }
nDegree = atoi(argv[globalUtilOptind]); pPars->nDegree = atoi(argv[globalUtilOptind]);
globalUtilOptind++; globalUtilOptind++;
if ( nDegree < 0 ) if ( pPars->nDegree < 0 )
goto usage; goto usage;
break; break;
case 'c':
pPars->fCascade ^= 1;
break;
case 'v': case 'v':
fVerbose ^= 1; pPars->fVerbose ^= 1;
break;
case 'w':
pPars->fVeryVerbose ^= 1;
break; break;
case 'h': case 'h':
goto usage; goto usage;
...@@ -13665,15 +13678,48 @@ int Abc_CommandIfif( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -13665,15 +13678,48 @@ int Abc_CommandIfif( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Need mapped network.\n" ); Abc_Print( -1, "Need mapped network.\n" );
return 1; return 1;
} }
Abc_NtkPerformIfif( pNtk, nDelayLut, nDegree, fVerbose ); if ( pPars->pLutLib == NULL )
{
Abc_Print( -1, "LUT library is not given.\n" );
return 1;
}
pPars->nLutSize = Abc_NtkGetFaninMax( pNtk );
if ( pPars->nLutSize > pPars->pLutLib->LutMax )
{
Abc_Print( -1, "The max node size (%d) exceeds the LUT size (%d).\n", pPars->nLutSize, pPars->pLutLib->LutMax );
return 1;
}
if ( pPars->nLutSize < pPars->pLutLib->LutMax )
Abc_Print( 0, "Node size (%d) is less than LUT size (%d).\n", pPars->nLutSize, pPars->pLutLib->LutMax );
// check delay information
fError = 0;
for ( c = 0; c < pPars->pLutLib->LutMax; c++ )
{
pPars->pLutDelays[c] = ( pPars->pLutLib->fVarPinDelays ? pPars->pLutLib->pLutDelays[pPars->pLutLib->LutMax][c] : pPars->pLutLib->pLutDelays[pPars->pLutLib->LutMax][0] );
if ( pPars->DelayWire >= pPars->pLutDelays[c] )
{
fError = 1;
printf(" Wire delay (%.2f) exceeds pin+wire delay (%.2f) for pin %d in the LUT library.\n", pPars->DelayWire, pPars->pLutDelays[c], c );
}
}
if ( fError )
return 1;
// call the mapper
Abc_NtkPerformIfif( pNtk, pPars );
return 0; return 0;
usage: usage:
Abc_Print( -2, "usage: ifif [-DNvh]\n" ); Abc_Print( -2, "usage: ifif [-DNcvwh]\n" );
Abc_Print( -2, "\t experimental technology mapper\n" ); Abc_Print( -2, "\t technology mapper into N-node K-LUT structures\n" );
Abc_Print( -2, "\t-D num : the ratio of LUT delay to wire delay [default = %d]\n", nDelayLut ); Abc_Print( -2, "\t (takes a LUT network and maps it into a delay-optimal network\n" );
Abc_Print( -2, "\t-N num : degree of the combination of LUTs [default = %d]\n", nDegree ); Abc_Print( -2, "\t of N-node K-LUT structures using the current LUT library)\n" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-D float : wire delay (should be less than the LUT delay) [default = %.2f]\n", pPars->DelayWire );
Abc_Print( -2, "\t-N num : degree of the LUT structure [default = %d]\n", pPars->nDegree );
Abc_Print( -2, "\t-c : toggles using LUT cascade vs LUT cluster [default = %s]\n", pPars->fCascade? "cascade": "cluster" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggles very verbose output [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t-h : print the command usage\n");
return 1; return 1;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
***********************************************************************/ ***********************************************************************/
#include "src/base/abc/abc.h" #include "src/base/abc/abc.h"
#include "src/map/if/if.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
...@@ -26,28 +27,29 @@ ABC_NAMESPACE_IMPL_START ...@@ -26,28 +27,29 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#define IFIF_MAX_LEAVES 6
typedef struct Abc_IffObj_t_ Abc_IffObj_t; typedef struct Abc_IffObj_t_ Abc_IffObj_t;
struct Abc_IffObj_t_ struct Abc_IffObj_t_
{ {
int Delay0; // separate delay float Delay[IFIF_MAX_LEAVES+1]; // separate delay
int Delay1; // combined delay // int nLeaves;
int nLeaves; // int pLeaves[IFIF_MAX_LEAVES];
int pLeaves[6];
}; };
typedef struct Abc_IffMan_t_ Abc_IffMan_t; typedef struct Abc_IffMan_t_ Abc_IffMan_t;
struct Abc_IffMan_t_ struct Abc_IffMan_t_
{ {
Abc_Ntk_t * pNtk; Abc_Ntk_t * pNtk;
int nObjs; Ifif_Par_t * pPars;
int nDelayLut;
int nDegree;
int fVerbose;
// internal data // internal data
int nObjs;
Abc_IffObj_t * pObjs; Abc_IffObj_t * pObjs;
}; };
static inline Abc_IffObj_t * Abc_IffObj( Abc_IffMan_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return p->pObjs + i; } static inline Abc_IffObj_t * Abc_IffObj( Abc_IffMan_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return p->pObjs + i; }
static inline float Abc_IffDelay( Abc_IffMan_t * p, Abc_Obj_t * pObj, int fDelay1 ) { return Abc_IffObj(p, Abc_ObjId(pObj))->Delay[fDelay1]; }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
...@@ -64,16 +66,14 @@ static inline Abc_IffObj_t * Abc_IffObj( Abc_IffMan_t * p, int i ) { asser ...@@ -64,16 +66,14 @@ static inline Abc_IffObj_t * Abc_IffObj( Abc_IffMan_t * p, int i ) { asser
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Abc_IffMan_t * Abc_NtkIfifStart( Abc_Ntk_t * pNtk, int nDelayLut, int nDegree, int fVerbose ) Abc_IffMan_t * Abc_NtkIfifStart( Abc_Ntk_t * pNtk, Ifif_Par_t * pPars )
{ {
Abc_IffMan_t * p; Abc_IffMan_t * p;
p = ABC_CALLOC( Abc_IffMan_t, 1 ); p = ABC_CALLOC( Abc_IffMan_t, 1 );
p->pNtk = pNtk; p->pNtk = pNtk;
p->nObjs = Abc_NtkObjNumMax( pNtk ); p->pPars = pPars;
p->nDelayLut = nDelayLut;
p->nDegree = nDegree;
p->fVerbose = fVerbose;
// internal data // internal data
p->nObjs = Abc_NtkObjNumMax( pNtk );
p->pObjs = ABC_CALLOC( Abc_IffObj_t, p->nObjs ); p->pObjs = ABC_CALLOC( Abc_IffObj_t, p->nObjs );
return p; return p;
} }
...@@ -84,10 +84,9 @@ void Abc_NtkIfifStop( Abc_IffMan_t * p ) ...@@ -84,10 +84,9 @@ void Abc_NtkIfifStop( Abc_IffMan_t * p )
ABC_FREE( p ); ABC_FREE( p );
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Compare nodes by Delay1 stored in pObj->iTemp.] Synopsis [Collects fanins into ppNodes in decreasing order.]
Description [] Description []
...@@ -96,17 +95,34 @@ void Abc_NtkIfifStop( Abc_IffMan_t * p ) ...@@ -96,17 +95,34 @@ void Abc_NtkIfifStop( Abc_IffMan_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_ObjIfifCompare( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) void Abc_ObjSortByDelay( Abc_IffMan_t * p, Abc_Obj_t * pObj, int fDelay1, Abc_Obj_t ** ppNodes )
{ {
Abc_Obj_t * pObj1 = *pp1; Abc_Obj_t * pFanin;
Abc_Obj_t * pObj2 = *pp2; int i, a, k = 0;
assert( Abc_ObjIsNode(pObj1) && Abc_ObjIsNode(pObj2) ); Abc_ObjForEachFanin( pObj, pFanin, i )
return (int)pObj2->iTemp - (int)pObj1->iTemp; {
ppNodes[k++] = pFanin;
if ( Abc_ObjIsCi(pFanin) )
continue;
for ( a = k-1; a > 0; a-- )
if ( Abc_IffDelay(p, ppNodes[a-1], fDelay1) + p->pPars->pLutDelays[a-1] < Abc_IffDelay(p, ppNodes[a], fDelay1) + p->pPars->pLutDelays[a] )
ABC_SWAP( Abc_Obj_t *, ppNodes[a-1], ppNodes[a] );
}
/*
for ( a = 1; a < k; a++ )
{
float D1 = Abc_IffDelay(p, ppNodes[a-1], fDelay1);
float D2 = Abc_IffDelay(p, ppNodes[a], fDelay1);
if ( Abc_ObjIsCi(ppNodes[a-1]) || Abc_ObjIsCi(ppNodes[a]) )
continue;
assert( Abc_IffDelay(p, ppNodes[a-1], fDelay1) + p->pPars->pLutDelays[a-1] >= Abc_IffDelay(p, ppNodes[a], fDelay1) + p->pPars->pLutDelays[a] - 0.01 );
}
*/
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [This is the delay which object may have all by itself.] Synopsis [This is the delay which object has all by itself.]
Description [This delay is stored in Delay0.] Description [This delay is stored in Delay0.]
...@@ -115,86 +131,114 @@ int Abc_ObjIfifCompare( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 ) ...@@ -115,86 +131,114 @@ int Abc_ObjIfifCompare( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_ObjDelay0( Abc_IffMan_t * p, Abc_Obj_t * pObj ) float Abc_ObjDelay0( Abc_IffMan_t * p, Abc_Obj_t * pObj )
{ {
Abc_Obj_t * pFanin; int i;
int i, Delay0 = 0; float Delay0 = 0;
Abc_ObjForEachFanin( pObj, pFanin, i ) Abc_Obj_t * ppNodes[6];
Delay0 = Abc_MaxInt( Delay0, Abc_IffObj(p, Abc_ObjId(pFanin))->Delay1 ); Abc_ObjSortByDelay( p, pObj, 1, ppNodes );
return p->nDelayLut + Delay0; for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ )
Delay0 = Abc_MaxFloat( Delay0, Abc_IffDelay(p, ppNodes[i], 1) + p->pPars->pLutDelays[i] );
return Delay0;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [This is the delay object may have in a group.] Synopsis [This is the delay object has in the structure.]
Description [This delay is stored in Delay1 and pObj->iTemp.] Description [This delay is stored in Delay1.]
SideEffects [] SideEffects []
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_ObjDelay1( Abc_IffMan_t * p, Abc_Obj_t * pObj ) float Abc_ObjDelay1( Abc_IffMan_t * p, Abc_Obj_t * pObj )
{ {
Abc_IffObj_t * pIfif; int i, fVeryVerbose = 0;
Abc_Obj_t * pNodes[6], * pFanin; // Abc_IffObj_t * pIfif = Abc_IffObj( p, Abc_ObjId(pObj) );
int i, nNodes, Delay1, DelayWorst; Abc_Obj_t * ppNodes[6];
float Delay1, DelayNew;
// find the object structure if ( Abc_ObjFaninNum(pObj) == 0 )
pIfif = Abc_IffObj( p, Abc_ObjId(pObj) ); return 0;
// collect relevant nodes // sort fanins by delay1+LutDelay
nNodes = 0; Abc_ObjSortByDelay( p, pObj, 1, ppNodes );
Abc_ObjForEachFanin( pObj, pFanin, i )
if ( Abc_ObjIsNode(pFanin) ) // print verbose results
if ( fVeryVerbose )
{
printf( "Object %d Level %d\n", Abc_ObjId(pObj), Abc_ObjLevel(pObj) );
for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ )
{ {
assert( pFanin->iTemp >= p->nDelayLut ); printf( "Fanin %d : ", i );
pNodes[nNodes++] = pFanin; printf( "D0 %3.2f ", Abc_IffDelay(p, ppNodes[i], 0) );
printf( "D0* %3.2f ", Abc_IffDelay(p, ppNodes[i], 0) + p->pPars->pLutDelays[i] - p->pPars->DelayWire );
printf( "D1 %3.2f", Abc_IffDelay(p, ppNodes[i], 1) + p->pPars->pLutDelays[i] );
printf( "\n" );
} }
printf( "\n" );
// process the result }
/*
// for the first nDegree delays, sort them by the minimum Delay1+LutDelay and Delay0-Wire+LutDelay
Delay1 = 0; Delay1 = 0;
pIfif->nLeaves = 0; pIfif->nLeaves = 0;
if ( nNodes > 0 ) for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ )
{ {
int fVerbose = 0; if ( Abc_ObjIsNode(ppNodes[i]) && pIfif->nLeaves < p->pPars->nDegree )
// sort fanins by delay
qsort( (void *)pNodes, nNodes, sizeof(Abc_Obj_t *), (int (*)(const void *, const void *)) Abc_ObjIfifCompare );
assert( pNodes[0]->iTemp >= pNodes[nNodes-1]->iTemp );
if ( fVerbose )
{ {
for ( i = 0; i < nNodes; i++ ) DelayNew = Abc_MinFloat( Abc_IffDelay(p, ppNodes[i], 1) + p->pPars->pLutDelays[i],
{ Abc_IffDelay(p, ppNodes[i], 0) + p->pPars->pLutDelays[i] - p->pPars->DelayWire );
printf( "Fanin %d : ", i ); pIfif->pLeaves[pIfif->nLeaves++] = Abc_ObjId(ppNodes[i]);
printf( "D0 %4d ", Abc_IffObj(p, Abc_ObjId(pNodes[i]))->Delay0 );
printf( "D0* %4d ", Abc_IffObj(p, Abc_ObjId(pNodes[0]))->Delay0 - (p->nDelayLut-1) );
printf( "D1 %4d ", Abc_IffObj(p, Abc_ObjId(pNodes[i]))->Delay1 );
printf( "\n" );
}
printf( "\n" );
} }
else
DelayNew = Abc_IffDelay(p, ppNodes[i], 1) + p->pPars->pLutDelays[i];
Delay1 = Abc_MaxFloat( Delay1, DelayNew );
}
*/
// for the first nDegree delays, sort them by the minimum Delay1+LutDelay and Delay0-Wire+LutDelay
Delay1 = 0;
for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ )
{
if ( i < p->pPars->nDegree )
DelayNew = Abc_MinFloat( Abc_IffDelay(p, ppNodes[i], 1) + p->pPars->pLutDelays[i],
Abc_IffDelay(p, ppNodes[i], 0) + p->pPars->pLutDelays[i] - p->pPars->DelayWire );
else
DelayNew = Abc_IffDelay(p, ppNodes[i], 1) + p->pPars->pLutDelays[i];
Delay1 = Abc_MaxFloat( Delay1, DelayNew );
}
assert( Delay1 > 0 );
return Delay1;
}
// get the worst-case fanin delay
// DelayWorst = Abc_IffObj(p, Abc_ObjId(pNodes[0]))->Delay0 - (p->nDelayLut-1); /**Function*************************************************************
DelayWorst = -1;
// find the delay and remember fanins Synopsis [This is the delay which object has all by itself.]
for ( i = 0; i < nNodes; i++ )
{ Description [This delay is stored in Delay0.]
if ( pIfif->nLeaves < p->nDegree && Abc_IffObj(p, Abc_ObjId(pNodes[i]))->Delay1 > DelayWorst )
{ SideEffects []
Delay1 = Abc_MaxInt( Delay1, Abc_IffObj(p, Abc_ObjId(pNodes[i]))->Delay0 - (p->nDelayLut-1) );
pIfif->pLeaves[pIfif->nLeaves++] = Abc_ObjId(pNodes[i]); SeeAlso []
}
else ***********************************************************************/
Delay1 = Abc_MaxInt( Delay1, Abc_IffObj(p, Abc_ObjId(pNodes[i]))->Delay1 ); float Abc_ObjDelayDegree( Abc_IffMan_t * p, Abc_Obj_t * pObj, int d )
} {
// assert( pIfif->nLeaves > 0 ); int i;
assert( Delay1 > 0 ); float Delay0 = 0, DelayNew;
Abc_Obj_t * ppNodes[6];
assert( d >= 0 && d <= p->pPars->nDegree );
Abc_ObjSortByDelay( p, pObj, p->pPars->nDegree, ppNodes );
for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ )
{
DelayNew = Abc_IffDelay(p, ppNodes[i], p->pPars->nDegree) + p->pPars->pLutDelays[i];
if ( i == 0 && d > 0 )
DelayNew = Abc_MinFloat(DelayNew, Abc_IffDelay(p, ppNodes[i], d-1) + p->pPars->pLutDelays[i] - p->pPars->DelayWire );
Delay0 = Abc_MaxFloat( Delay0, DelayNew );
} }
return p->nDelayLut + Delay1; return Delay0;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -208,26 +252,36 @@ int Abc_ObjDelay1( Abc_IffMan_t * p, Abc_Obj_t * pObj ) ...@@ -208,26 +252,36 @@ int Abc_ObjDelay1( Abc_IffMan_t * p, Abc_Obj_t * pObj )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_NtkPerformIfif( Abc_Ntk_t * pNtk, int nDelayLut, int nDegree, int fVerbose ) void Abc_NtkPerformIfif( Abc_Ntk_t * pNtk, Ifif_Par_t * pPars )
{ {
Abc_IffMan_t * p; Abc_IffMan_t * p;
Abc_IffObj_t * pIffObj; Abc_IffObj_t * pIffObj;
Vec_Ptr_t * vNodes; Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj; Abc_Obj_t * pObj;
int i, Delay, nLutSize = Abc_NtkGetFaninMax( pNtk ); float Delay, Delay10, DegreeFinal;
if ( nLutSize > 6 ) int i, d, Count10;
{ assert( pPars->pLutLib->LutMax >= 0 && pPars->pLutLib->LutMax <= IFIF_MAX_LEAVES );
printf( "LUT size (%d) is more than 6.\n", nLutSize ); assert( pPars->nLutSize >= 0 && pPars->nLutSize <= IFIF_MAX_LEAVES );
return; assert( pPars->nDegree >= 0 && pPars->nDegree <= IFIF_MAX_LEAVES );
}
// convert to AIGs // convert to AIGs
Abc_NtkToAig( pNtk ); Abc_NtkToAig( pNtk );
Abc_NtkLevel( pNtk );
assert( nDegree >= 0 && nDegree <= 6 ); // print parameters
if ( pPars->fVerbose )
{
printf( "Running mapper into LUT structures with the following parameters:\n" );
printf( "Pin+Wire: {" );
for ( i = 0; i < pPars->pLutLib->LutMax; i++ )
printf( " %3.2f", pPars->pLutDelays[i] );
printf( " } " );
printf( "Wire %3.2f Degree %d Type: %s\n",
pPars->DelayWire, pPars->nDegree, pPars->fCascade? "Cascade" : "Cluster" );
}
// start manager // start manager
p = Abc_NtkIfifStart( pNtk, nDelayLut, nDegree, fVerbose ); p = Abc_NtkIfifStart( pNtk, pPars );
// printf( "Running experiment with LUT delay %d and degree %d (LUT size is %d).\n", nDelayLut, nDegree, nLutSize ); // printf( "Running experiment with LUT delay %d and degree %d (LUT size is %d).\n", DelayWire, nDegree, nLutSize );
// compute the delay // compute the delay
vNodes = Abc_NtkDfs( pNtk, 0 ); vNodes = Abc_NtkDfs( pNtk, 0 );
...@@ -235,21 +289,50 @@ void Abc_NtkPerformIfif( Abc_Ntk_t * pNtk, int nDelayLut, int nDegree, int fVerb ...@@ -235,21 +289,50 @@ void Abc_NtkPerformIfif( Abc_Ntk_t * pNtk, int nDelayLut, int nDegree, int fVerb
{ {
assert( Abc_ObjIsNode(pObj) ); assert( Abc_ObjIsNode(pObj) );
pIffObj = Abc_IffObj( p, Abc_ObjId(pObj) ); pIffObj = Abc_IffObj( p, Abc_ObjId(pObj) );
pIffObj->Delay0 = Abc_ObjDelay0( p, pObj );
pIffObj->Delay1 = Abc_ObjDelay1( p, pObj );
pObj->iTemp = pIffObj->Delay1;
// printf( "Node %3d : Lev =%3d Delay0 =%4d Delay1 =%4d Leaves =%3d.\n", if ( pPars->fCascade )
// Abc_ObjId(pObj), Abc_ObjLevel(pObj), pIffObj->Delay0, pIffObj->Delay1, pIffObj->nLeaves ); {
for ( d = 0; d <= pPars->nDegree; d++ )
pIffObj->Delay[d] = Abc_ObjDelayDegree( p, pObj, d );
}
else
{
pIffObj->Delay[0] = Abc_ObjDelay0( p, pObj );
pIffObj->Delay[1] = Abc_ObjDelay1( p, pObj );
}
}
// get final degree number
if ( pPars->fCascade )
DegreeFinal = pPars->nDegree;
else
DegreeFinal = 1;
if ( p->pPars->fVeryVerbose )
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
{
printf( "Node %3d : Lev =%3d ", Abc_ObjId(pObj), Abc_ObjLevel(pObj) );
for ( d = 0; d <= DegreeFinal; d++ )
printf( "Del%d =%4.2f ", d, Abc_IffDelay(p, pObj, d) );
printf( "\n" );
} }
Vec_PtrFree( vNodes ); Vec_PtrFree( vNodes );
// consider delay at the outputs // consider delay at the outputs
Delay = 0; Delay = 0;
Abc_NtkForEachCo( pNtk, pObj, i ) Abc_NtkForEachCo( pNtk, pObj, i )
Delay = Abc_MaxInt( Delay, Abc_IffObj(p, Abc_ObjId(Abc_ObjFanin0(pObj)))->Delay1 ); Delay = Abc_MaxFloat( Delay, Abc_IffDelay(p, Abc_ObjFanin0(pObj), DegreeFinal) );
Delay10 = 0.9 * Delay;
// consider delay at the outputs
Count10 = 0;
Abc_NtkForEachCo( pNtk, pObj, i )
if ( Abc_IffDelay(p, Abc_ObjFanin0(pObj), DegreeFinal) >= Delay10 )
Count10++;
printf( "Critical delay is %5d (%7.2f).\n", Delay, 1.0 * Delay / nDelayLut ); printf( "Critical delay %5.2f. Critical outputs %5.2f %%\n", Delay, 100.0 * Count10 / Abc_NtkCoNum(pNtk) );
// printf( "%.2f %.2f\n", Delay, 100.0 * Count10 / Abc_NtkCoNum(pNtk) );
// derive a new network // derive a new network
......
...@@ -74,6 +74,19 @@ typedef struct If_Obj_t_ If_Obj_t; ...@@ -74,6 +74,19 @@ typedef struct If_Obj_t_ If_Obj_t;
typedef struct If_Cut_t_ If_Cut_t; typedef struct If_Cut_t_ If_Cut_t;
typedef struct If_Set_t_ If_Set_t; typedef struct If_Set_t_ If_Set_t;
typedef struct Ifif_Par_t_ Ifif_Par_t;
struct Ifif_Par_t_
{
int nLutSize; // the LUT size
If_Lib_t * pLutLib; // the LUT library
float pLutDelays[IF_MAX_LUTSIZE]; // pin-to-pin delays of the max LUT
float DelayWire; // wire delay
int nDegree; // structure degree
int fCascade; // cascade
int fVerbose; // verbose
int fVeryVerbose; // verbose
};
// parameters // parameters
struct If_Par_t_ struct If_Par_t_
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment