Commit b9abf9c0 by Alan Mishchenko

Version abc61209

parent 4cf99cae
...@@ -11,7 +11,7 @@ MODULES := src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src ...@@ -11,7 +11,7 @@ MODULES := src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse src/bdd/reo \ src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse src/bdd/reo \
src/map/fpga src/map/mapper src/map/mio src/map/super src/map/if \ src/map/fpga src/map/mapper src/map/mio src/map/super src/map/if \
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/espresso src/misc/nm src/misc/vec src/misc/hash \ src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/espresso src/misc/nm src/misc/vec src/misc/hash \
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim src/opt/ret \ src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim src/opt/ret src/opt/kit \
src/sat/asat src/sat/bsat src/sat/csat src/sat/msat src/sat/fraig src/sat/asat src/sat/bsat src/sat/csat src/sat/msat src/sat/fraig
default: $(PROG) default: $(PROG)
......
...@@ -1854,6 +1854,10 @@ SOURCE=.\src\map\if\ifCut.c ...@@ -1854,6 +1854,10 @@ SOURCE=.\src\map\if\ifCut.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\if\ifLib.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifMan.c SOURCE=.\src\map\if\ifMan.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -218,9 +218,9 @@ int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk ) ...@@ -218,9 +218,9 @@ int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pNode, i ) Abc_NtkForEachNode( pNtk, pNode, i )
{ {
assert( pNode->pData ); assert( pNode->pData );
if ( Abc_NodeIsConst(pNode) ) if ( Abc_ObjFaninNum(pNode) < 2 )
continue; continue;
nNodes += pNode->pData? Cudd_DagSize( pNode->pData ) : 0; nNodes += pNode->pData? -1 + Cudd_DagSize( pNode->pData ) : 0;
} }
return nNodes; return nNodes;
} }
...@@ -244,7 +244,7 @@ int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk ) ...@@ -244,7 +244,7 @@ int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk )
Abc_NtkForEachNode( pNtk, pNode, i ) Abc_NtkForEachNode( pNtk, pNode, i )
{ {
assert( pNode->pData ); assert( pNode->pData );
if ( Abc_NodeIsConst(pNode) ) if ( Abc_ObjFaninNum(pNode) < 2 )
continue; continue;
nNodes += pNode->pData? Hop_DagSize( pNode->pData ) : 0; nNodes += pNode->pData? Hop_DagSize( pNode->pData ) : 0;
} }
......
...@@ -27,9 +27,9 @@ ...@@ -27,9 +27,9 @@
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
static int Abc_NtkRenodeEvalBdd( unsigned * pTruth, int nVars ); static int Abc_NtkRenodeEvalBdd( If_Cut_t * pCut );
static int Abc_NtkRenodeEvalSop( unsigned * pTruth, int nVars ); static int Abc_NtkRenodeEvalSop( If_Cut_t * pCut );
static int Abc_NtkRenodeEvalAig( unsigned * pTruth, int nVars ); static int Abc_NtkRenodeEvalAig( If_Cut_t * pCut );
static reo_man * s_pReo = NULL; static reo_man * s_pReo = NULL;
static DdManager * s_pDd = NULL; static DdManager * s_pDd = NULL;
...@@ -50,7 +50,7 @@ static Vec_Int_t * s_vMemory = NULL; ...@@ -50,7 +50,7 @@ static Vec_Int_t * s_vMemory = NULL;
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fUseBdds, int fUseSops, int fVerbose ) Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fArea, int fUseBdds, int fUseSops, int fVerbose )
{ {
extern Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars ); extern Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
If_Par_t Pars, * pPars = &Pars; If_Par_t Pars, * pPars = &Pars;
...@@ -59,19 +59,19 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fU ...@@ -59,19 +59,19 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fU
// set defaults // set defaults
memset( pPars, 0, sizeof(If_Par_t) ); memset( pPars, 0, sizeof(If_Par_t) );
// user-controlable paramters // user-controlable paramters
pPars->Mode = 0;
pPars->nLutSize = nFaninMax; pPars->nLutSize = nFaninMax;
pPars->nCutsMax = 10; pPars->nCutsMax = nCubeMax;
pPars->DelayTarget = -1; pPars->DelayTarget = -1;
pPars->fPreprocess = 1; pPars->fPreprocess = 1;
pPars->fArea = 0; pPars->fArea = fArea;
pPars->fFancy = 0; pPars->fFancy = 0;
pPars->fExpRed = 0; // pPars->fExpRed = 0; //
pPars->fLatchPaths = 0; pPars->fLatchPaths = 0;
pPars->fSeq = 0; pPars->fSeq = 0;
pPars->fVerbose = 0; pPars->fVerbose = fVerbose;
// internal parameters // internal parameters
pPars->fTruth = 1; pPars->fTruth = 1;
pPars->fUsePerm = 1; //!fUseSops;
pPars->nLatches = 0; pPars->nLatches = 0;
pPars->pLutLib = NULL; // Abc_FrameReadLibLut(); pPars->pLutLib = NULL; // Abc_FrameReadLibLut();
pPars->pTimesArr = NULL; pPars->pTimesArr = NULL;
...@@ -130,18 +130,22 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fU ...@@ -130,18 +130,22 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fU
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_NtkRenodeEvalBdd( unsigned * pTruth, int nVars ) int Abc_NtkRenodeEvalBdd( If_Cut_t * pCut )
{ {
int pOrder[IF_MAX_LUTSIZE];
DdNode * bFunc, * bFuncNew; DdNode * bFunc, * bFuncNew;
int nNodes, nSupport; int i, k, nNodes;
bFunc = Kit_TruthToBdd( s_pDd, pTruth, nVars ); Cudd_Ref( bFunc ); for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
bFuncNew = Extra_Reorder( s_pReo, s_pDd, bFunc, NULL ); Cudd_Ref( bFuncNew ); pCut->pPerm[i] = pOrder[i] = -100;
// nSupport = Cudd_SupportSize( s_pDd, bFuncNew ); bFunc = Kit_TruthToBdd( s_pDd, If_CutTruth(pCut), If_CutLeaveNum(pCut), 0 ); Cudd_Ref( bFunc );
nSupport = 1; bFuncNew = Extra_Reorder( s_pReo, s_pDd, bFunc, pOrder ); Cudd_Ref( bFuncNew );
nNodes = Cudd_DagSize( bFuncNew ); for ( i = k = 0; i < If_CutLeaveNum(pCut); i++ )
if ( pOrder[i] >= 0 )
pCut->pPerm[pOrder[i]] = ++k; // double-check this!
nNodes = -1 + Cudd_DagSize( bFuncNew );
Cudd_RecursiveDeref( s_pDd, bFuncNew ); Cudd_RecursiveDeref( s_pDd, bFuncNew );
Cudd_RecursiveDeref( s_pDd, bFunc ); Cudd_RecursiveDeref( s_pDd, bFunc );
return (nSupport << 16) | nNodes; return nNodes;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -155,13 +159,16 @@ int Abc_NtkRenodeEvalBdd( unsigned * pTruth, int nVars ) ...@@ -155,13 +159,16 @@ int Abc_NtkRenodeEvalBdd( unsigned * pTruth, int nVars )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_NtkRenodeEvalSop( unsigned * pTruth, int nVars ) int Abc_NtkRenodeEvalSop( If_Cut_t * pCut )
{ {
int nCubes, RetValue; int i, RetValue;
RetValue = Kit_TruthIsop( pTruth, nVars, s_vMemory, 0 ); for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
assert( RetValue == 0 ); pCut->pPerm[i] = 1;
nCubes = Vec_IntSize( s_vMemory ); RetValue = Kit_TruthIsop( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory, 1 );
return (1 << 16) | nCubes; if ( RetValue == -1 )
return ABC_INFINITY;
assert( RetValue == 0 || RetValue == 1 );
return Vec_IntSize( s_vMemory );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -175,16 +182,22 @@ int Abc_NtkRenodeEvalSop( unsigned * pTruth, int nVars ) ...@@ -175,16 +182,22 @@ int Abc_NtkRenodeEvalSop( unsigned * pTruth, int nVars )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_NtkRenodeEvalAig( unsigned * pTruth, int nVars ) int Abc_NtkRenodeEvalAig( If_Cut_t * pCut )
{ {
Kit_Graph_t * pGraph; Kit_Graph_t * pGraph;
int nNodes, nDepth; int i, nNodes;
pGraph = Kit_TruthToGraph( pTruth, nVars, s_vMemory ); pGraph = Kit_TruthToGraph( If_CutTruth(pCut), If_CutLeaveNum(pCut), s_vMemory );
if ( pGraph == NULL )
{
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
pCut->pPerm[i] = 100;
return ABC_INFINITY;
}
nNodes = Kit_GraphNodeNum( pGraph ); nNodes = Kit_GraphNodeNum( pGraph );
// nDepth = Kit_GraphLevelNum( pGraph ); for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
nDepth = 1; pCut->pPerm[i] = Kit_GraphLeafDepth_rec( pGraph, Kit_GraphNodeLast(pGraph), Kit_GraphNode(pGraph, i) );
Kit_GraphFree( pGraph ); Kit_GraphFree( pGraph );
return (nDepth << 16) | nNodes; return nNodes;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -56,10 +56,10 @@ static int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -56,10 +56,10 @@ static int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv )
void Fpga_Init( Abc_Frame_t * pAbc ) void Fpga_Init( Abc_Frame_t * pAbc )
{ {
// set the default library // set the default library
//Fpga_LutLib_t s_LutLib = { "lutlib", 6, {0,1,2,4,8,16,32}, {0,1,2,3,4,5,6} }; //Fpga_LutLib_t s_LutLib = { "lutlib", 6, 0, {0,1,2,4,8,16,32}, {{0},{1},{2},{3},{4},{5},{6}} };
// Fpga_LutLib_t s_LutLib = { "lutlib", 5, {0,1,1,1,1,1}, {0,1,1,1,1,1} }; // Fpga_LutLib_t s_LutLib = { "lutlib", 5, 0, {0,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1}} };
Fpga_LutLib_t s_LutLib = { "lutlib", 4, {0,1,1,1,1}, {0,1,1,1,1} }; Fpga_LutLib_t s_LutLib = { "lutlib", 4, 0, {0,1,1,1,1}, {{0},{1},{1},{1},{1}} };
//Fpga_LutLib_t s_LutLib = { "lutlib", 3, {0,1,1,1}, {0,1,1,1} }; //Fpga_LutLib_t s_LutLib = { "lutlib", 3, 0, {0,1,1,1}, {{0},{1},{1},{1}} };
Abc_FrameSetLibLut( Fpga_LutLibDup(&s_LutLib) ); Abc_FrameSetLibLut( Fpga_LutLibDup(&s_LutLib) );
...@@ -248,14 +248,14 @@ usage: ...@@ -248,14 +248,14 @@ usage:
***********************************************************************/ ***********************************************************************/
void Fpga_SetSimpleLutLib( int nLutSize ) void Fpga_SetSimpleLutLib( int nLutSize )
{ {
Fpga_LutLib_t s_LutLib10= { "lutlib",10, {0,1,1,1,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib10= { "lutlib",10, 0, {0,1,1,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1},{1},{1}} };
Fpga_LutLib_t s_LutLib9 = { "lutlib", 9, {0,1,1,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib9 = { "lutlib", 9, 0, {0,1,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1},{1}} };
Fpga_LutLib_t s_LutLib8 = { "lutlib", 8, {0,1,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib8 = { "lutlib", 8, 0, {0,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1}} };
Fpga_LutLib_t s_LutLib7 = { "lutlib", 7, {0,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib7 = { "lutlib", 7, 0, {0,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1}} };
Fpga_LutLib_t s_LutLib6 = { "lutlib", 6, {0,1,1,1,1,1,1}, {0,1,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib6 = { "lutlib", 6, 0, {0,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1}} };
Fpga_LutLib_t s_LutLib5 = { "lutlib", 5, {0,1,1,1,1,1}, {0,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib5 = { "lutlib", 5, 0, {0,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1}} };
Fpga_LutLib_t s_LutLib4 = { "lutlib", 4, {0,1,1,1,1}, {0,1,1,1,1} }; Fpga_LutLib_t s_LutLib4 = { "lutlib", 4, 0, {0,1,1,1,1}, {{0},{1},{1},{1},{1}} };
Fpga_LutLib_t s_LutLib3 = { "lutlib", 3, {0,1,1,1}, {0,1,1,1} }; Fpga_LutLib_t s_LutLib3 = { "lutlib", 3, 0, {0,1,1,1}, {{0},{1},{1},{1}} };
Fpga_LutLib_t * pLutLib; Fpga_LutLib_t * pLutLib;
assert( nLutSize >= 3 && nLutSize <= 10 ); assert( nLutSize >= 3 && nLutSize <= 10 );
switch ( nLutSize ) switch ( nLutSize )
......
...@@ -290,7 +290,9 @@ void Fpga_CutGetParameters( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ) ...@@ -290,7 +290,9 @@ void Fpga_CutGetParameters( Fpga_Man_t * pMan, Fpga_Cut_t * pCut )
// pCut->aFlow += pFaninCut->aFlow / pCut->ppLeaves[i]->nRefs; // pCut->aFlow += pFaninCut->aFlow / pCut->ppLeaves[i]->nRefs;
pCut->aFlow += pFaninCut->aFlow / pCut->ppLeaves[i]->aEstFanouts; pCut->aFlow += pFaninCut->aFlow / pCut->ppLeaves[i]->aEstFanouts;
} }
pCut->tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves]; // use the first pin to compute the delay of the LUT
// (this mapper does not support the variable pin delay model)
pCut->tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves][0];
} }
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#endif #endif
// the maximum number of cut leaves (currently does not work for 7) // the maximum number of cut leaves (currently does not work for 7)
#define FPGA_MAX_LEAVES 10 #define FPGA_MAX_LEAVES 6
// the bit masks // the bit masks
#define FPGA_MASK(n) ((~((unsigned)0)) >> (32-(n))) #define FPGA_MASK(n) ((~((unsigned)0)) >> (32-(n)))
...@@ -171,8 +171,9 @@ struct Fpga_LutLibStruct_t_ ...@@ -171,8 +171,9 @@ struct Fpga_LutLibStruct_t_
{ {
char * pName; // the name of the LUT library char * pName; // the name of the LUT library
int LutMax; // the maximum LUT size int LutMax; // the maximum LUT size
int fVarPinDelays; // set to 1 if variable pin delays are specified
float pLutAreas[FPGA_MAX_LUTSIZE+1]; // the areas of LUTs float pLutAreas[FPGA_MAX_LUTSIZE+1]; // the areas of LUTs
float pLutDelays[FPGA_MAX_LUTSIZE+1];// the delays of LUTs float pLutDelays[FPGA_MAX_LUTSIZE+1][FPGA_MAX_LUTSIZE+1];// the delays of LUTs
}; };
// the mapping node // the mapping node
......
...@@ -39,9 +39,7 @@ ...@@ -39,9 +39,7 @@
***********************************************************************/ ***********************************************************************/
int Fpga_LutLibReadVarMax( Fpga_LutLib_t * p ) { return p->LutMax; } int Fpga_LutLibReadVarMax( Fpga_LutLib_t * p ) { return p->LutMax; }
float * Fpga_LutLibReadLutAreas( Fpga_LutLib_t * p ) { return p->pLutAreas; } float * Fpga_LutLibReadLutAreas( Fpga_LutLib_t * p ) { return p->pLutAreas; }
float * Fpga_LutLibReadLutDelays( Fpga_LutLib_t * p ) { return p->pLutDelays; }
float Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutAreas[Size]; } float Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutAreas[Size]; }
float Fpga_LutLibReadLutDelay( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutDelays[Size]; }
/**Function************************************************************* /**Function*************************************************************
...@@ -59,7 +57,7 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose ) ...@@ -59,7 +57,7 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose )
char pBuffer[1000], * pToken; char pBuffer[1000], * pToken;
Fpga_LutLib_t * p; Fpga_LutLib_t * p;
FILE * pFile; FILE * pFile;
int i; int i, k;
pFile = fopen( FileName, "r" ); pFile = fopen( FileName, "r" );
if ( pFile == NULL ) if ( pFile == NULL )
...@@ -87,16 +85,30 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose ) ...@@ -87,16 +85,30 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose )
return NULL; return NULL;
} }
// read area
pToken = strtok( NULL, " \t\n" ); pToken = strtok( NULL, " \t\n" );
p->pLutAreas[i] = (float)atof(pToken); p->pLutAreas[i] = (float)atof(pToken);
pToken = strtok( NULL, " \t\n" ); // read delays
p->pLutDelays[i] = (float)atof(pToken); k = 0;
while ( pToken = strtok( NULL, " \t\n" ) )
p->pLutDelays[i][k++] = (float)atof(pToken);
// check for out-of-bound
if ( k > i )
{
printf( "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
return NULL;
}
// check if var delays are specifies
if ( k > 1 )
p->fVarPinDelays = 1;
if ( i == FPGA_MAX_LUTSIZE ) if ( i == FPGA_MAX_LUTSIZE )
{ {
printf( "Skipping LUTs of size more than %d.\n", i ); printf( "Skipping LUTs of size more than %d.\n", i );
break; return NULL;
} }
i++; i++;
} }
...@@ -106,6 +118,32 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose ) ...@@ -106,6 +118,32 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose )
p->LutMax = FPGA_MAX_LEAVES; p->LutMax = FPGA_MAX_LEAVES;
printf( "Warning: LUTs with more than %d input will not be used.\n", FPGA_MAX_LEAVES ); printf( "Warning: LUTs with more than %d input will not be used.\n", FPGA_MAX_LEAVES );
} }
// check the library
if ( p->fVarPinDelays )
{
for ( i = 1; i <= p->LutMax; i++ )
for ( k = 0; k < i; k++ )
{
if ( p->pLutDelays[i][k] <= 0.0 )
printf( "Warning: Pin %d of LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n",
k, i, p->pLutDelays[i][k] );
if ( k && p->pLutDelays[i][k-1] > p->pLutDelays[i][k] )
printf( "Warning: Pin %d of LUT %d has delay %f. Pin %d of LUT %d has delay %f. Pin delays should be in non-degreasing order. Technology mapping may not work correctly.\n",
k-1, i, p->pLutDelays[i][k-1],
k, i, p->pLutDelays[i][k] );
}
}
else
{
for ( i = 1; i <= p->LutMax; i++ )
{
if ( p->pLutDelays[i][0] <= 0.0 )
printf( "Warning: LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n",
k, i, p->pLutDelays[i][0] );
}
}
return p; return p;
} }
...@@ -162,11 +200,22 @@ void Fpga_LutLibFree( Fpga_LutLib_t * pLutLib ) ...@@ -162,11 +200,22 @@ void Fpga_LutLibFree( Fpga_LutLib_t * pLutLib )
***********************************************************************/ ***********************************************************************/
void Fpga_LutLibPrint( Fpga_LutLib_t * pLutLib ) void Fpga_LutLibPrint( Fpga_LutLib_t * pLutLib )
{ {
int i; int i, k;
printf( "# The area/delay of k-variable LUTs:\n" ); printf( "# The area/delay of k-variable LUTs:\n" );
printf( "# k area delay\n" ); printf( "# k area delay\n" );
for ( i = 1; i <= pLutLib->LutMax; i++ ) if ( pLutLib->fVarPinDelays )
printf( "%d %7.2f %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i] ); {
for ( i = 1; i <= pLutLib->LutMax; i++ )
{
printf( "%d %7.2f ", i, pLutLib->pLutAreas[i] );
for ( k = 0; k < i; k++ )
printf( " %7.2f", pLutLib->pLutDelays[i][k] );
printf( "\n" );
}
}
else
for ( i = 1; i <= pLutLib->LutMax; i++ )
printf( "%d %7.2f %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i][0] );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -186,7 +235,7 @@ int Fpga_LutLibDelaysAreDiscrete( Fpga_LutLib_t * pLutLib ) ...@@ -186,7 +235,7 @@ int Fpga_LutLibDelaysAreDiscrete( Fpga_LutLib_t * pLutLib )
int i; int i;
for ( i = 1; i <= pLutLib->LutMax; i++ ) for ( i = 1; i <= pLutLib->LutMax; i++ )
{ {
Delay = pLutLib->pLutDelays[i]; Delay = pLutLib->pLutDelays[i][0];
if ( ((float)((int)Delay)) != Delay ) if ( ((float)((int)Delay)) != Delay )
return 0; return 0;
} }
......
...@@ -323,7 +323,7 @@ clk = clock(); ...@@ -323,7 +323,7 @@ clk = clock();
if ( pNode->nRefs ) if ( pNode->nRefs )
{ {
pNode->pCutBest->aFlow = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 ); pNode->pCutBest->aFlow = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 );
assert( pNode->pCutBest->aFlow <= aAreaCutBest ); // assert( pNode->pCutBest->aFlow <= aAreaCutBest );
// assert( pNode->tRequired < FPGA_FLOAT_LARGE ); // assert( pNode->tRequired < FPGA_FLOAT_LARGE );
} }
return 1; return 1;
......
...@@ -46,7 +46,7 @@ float Fpga_TimeCutComputeArrival( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ) ...@@ -46,7 +46,7 @@ float Fpga_TimeCutComputeArrival( Fpga_Man_t * pMan, Fpga_Cut_t * pCut )
for ( i = 0; i < pCut->nLeaves; i++ ) for ( i = 0; i < pCut->nLeaves; i++ )
if ( tArrival < pCut->ppLeaves[i]->pCutBest->tArrival ) if ( tArrival < pCut->ppLeaves[i]->pCutBest->tArrival )
tArrival = pCut->ppLeaves[i]->pCutBest->tArrival; tArrival = pCut->ppLeaves[i]->pCutBest->tArrival;
tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves]; tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves][0];
return tArrival; return tArrival;
} }
...@@ -216,7 +216,7 @@ void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes ) ...@@ -216,7 +216,7 @@ void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes )
if ( !Fpga_NodeIsAnd(pNode) ) if ( !Fpga_NodeIsAnd(pNode) )
continue; continue;
// get the required time for children // get the required time for children
fRequired = pNode->tRequired - p->pLutLib->pLutDelays[pNode->pCutBest->nLeaves]; fRequired = pNode->tRequired - p->pLutLib->pLutDelays[pNode->pCutBest->nLeaves][0];
// update the required time of the children // update the required time of the children
for ( i = 0; i < pNode->pCutBest->nLeaves; i++ ) for ( i = 0; i < pNode->pCutBest->nLeaves; i++ )
{ {
......
...@@ -43,7 +43,7 @@ int If_ManPerformMapping( If_Man_t * p ) ...@@ -43,7 +43,7 @@ int If_ManPerformMapping( If_Man_t * p )
{ {
If_Obj_t * pObj; If_Obj_t * pObj;
int nItersFlow = 1; int nItersFlow = 1;
int nItersArea = 1; int nItersArea = 2;
int clkTotal = clock(); int clkTotal = clock();
int i; int i;
// set arrival times and trivial cuts at const 1 and PIs // set arrival times and trivial cuts at const 1 and PIs
...@@ -57,21 +57,21 @@ int If_ManPerformMapping( If_Man_t * p ) ...@@ -57,21 +57,21 @@ int If_ManPerformMapping( If_Man_t * p )
if ( p->pPars->fPreprocess && !p->pPars->fArea && p->pPars->nCutsMax >= 4 ) if ( p->pPars->fPreprocess && !p->pPars->fArea && p->pPars->nCutsMax >= 4 )
If_ManPerformMappingPreprocess( p ); If_ManPerformMappingPreprocess( p );
else else
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 1 ); If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 1, "Delay" );
// try to improve area by expanding and reducing the cuts // try to improve area by expanding and reducing the cuts
if ( p->pPars->fExpRed && !p->pPars->fTruth ) if ( p->pPars->fExpRed && !p->pPars->fTruth )
If_ManImproveMapping( p ); If_ManImproveMapping( p );
// area flow oriented mapping // area flow oriented mapping
for ( i = 0; i < nItersFlow; i++ ) for ( i = 0; i < nItersFlow; i++ )
{ {
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 1, 1 ); If_ManPerformMappingRound( p, p->pPars->nCutsMax, 1, 1, "Flow" );
if ( p->pPars->fExpRed && !p->pPars->fTruth ) if ( p->pPars->fExpRed && !p->pPars->fTruth )
If_ManImproveMapping( p ); If_ManImproveMapping( p );
} }
// area oriented mapping // area oriented mapping
for ( i = 0; i < nItersArea; i++ ) for ( i = 0; i < nItersArea; i++ )
{ {
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 2, 1 ); If_ManPerformMappingRound( p, p->pPars->nCutsMax, 2, 1, "Area" );
if ( p->pPars->fExpRed && !p->pPars->fTruth ) if ( p->pPars->fExpRed && !p->pPars->fTruth )
If_ManImproveMapping( p ); If_ManImproveMapping( p );
} }
...@@ -82,47 +82,6 @@ int If_ManPerformMapping( If_Man_t * p ) ...@@ -82,47 +82,6 @@ int If_ManPerformMapping( If_Man_t * p )
return 1; return 1;
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode, int fRequired )
{
If_Obj_t * pObj;
int i, clk = clock();
assert( Mode >= 0 && Mode <= 2 );
// set the cut number
p->nCutsUsed = nCutsUsed;
p->nCutsMerged = 0;
p->nCutsMax = 0;
// map the internal nodes
If_ManForEachNode( p, pObj, i )
If_ObjPerformMapping( p, pObj, Mode );
// compute required times and stats
if ( fRequired )
{
If_ManComputeRequired( p, Mode==0 );
if ( p->pPars->fVerbose )
{
char Symb = (Mode == 0)? 'D' : ((Mode == 1)? 'F' : 'A');
printf( "%c: Del = %6.2f. Area = %8.2f. Cuts = %6d. Lim = %2d. Ave = %5.2f. ",
Symb, p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
PRT( "T", clock() - clk );
// printf( "Max number of cuts = %d. Average number of cuts = %5.2f.\n",
// p->nCutsMax, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
}
}
return 1;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -96,7 +96,9 @@ int If_CutFilter( If_Man_t * p, If_Cut_t * pCut ) ...@@ -96,7 +96,9 @@ int If_CutFilter( If_Man_t * p, If_Cut_t * pCut )
pTemp = p->ppCuts[i]; pTemp = p->ppCuts[i];
if ( pTemp->nLeaves > pCut->nLeaves ) if ( pTemp->nLeaves > pCut->nLeaves )
{ {
// continue; // do not fiter the first cut
if ( i == 0 )
continue;
// skip the non-contained cuts // skip the non-contained cuts
if ( (pTemp->uSign & pCut->uSign) != pCut->uSign ) if ( (pTemp->uSign & pCut->uSign) != pCut->uSign )
continue; continue;
...@@ -368,6 +370,10 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) ...@@ -368,6 +370,10 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
return -1; return -1;
if ( pC0->Area > pC1->Area + 0.0001 ) if ( pC0->Area > pC1->Area + 0.0001 )
return 1; return 1;
if ( pC0->AveRefs > pC1->AveRefs )
return -1;
if ( pC0->AveRefs < pC1->AveRefs )
return 1;
if ( pC0->nLeaves < pC1->nLeaves ) if ( pC0->nLeaves < pC1->nLeaves )
return -1; return -1;
if ( pC0->nLeaves > pC1->nLeaves ) if ( pC0->nLeaves > pC1->nLeaves )
...@@ -403,7 +409,7 @@ void If_ManSortCuts( If_Man_t * p, int Mode ) ...@@ -403,7 +409,7 @@ void If_ManSortCuts( If_Man_t * p, int Mode )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Computes delay.] Synopsis [Computes area flow.]
Description [] Description []
...@@ -412,21 +418,29 @@ void If_ManSortCuts( If_Man_t * p, int Mode ) ...@@ -412,21 +418,29 @@ void If_ManSortCuts( If_Man_t * p, int Mode )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
float If_CutDelay( If_Man_t * p, If_Cut_t * pCut ) float If_CutFlow( If_Man_t * p, If_Cut_t * pCut )
{ {
If_Obj_t * pLeaf; If_Obj_t * pLeaf;
float Delay; float Flow;
int i; int i;
assert( pCut->nLeaves > 1 ); assert( pCut->nLeaves > 1 );
Delay = -IF_FLOAT_LARGE; Flow = If_CutLutArea(p, pCut);
If_CutForEachLeaf( p, pCut, pLeaf, i ) If_CutForEachLeaf( p, pCut, pLeaf, i )
Delay = IF_MAX( Delay, If_ObjCutBest(pLeaf)->Delay ); {
return Delay + If_CutLutDelay(p, pCut); if ( pLeaf->nRefs == 0 )
Flow += If_ObjCutBest(pLeaf)->Area;
else
{
assert( pLeaf->EstRefs > p->fEpsilon );
Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs;
}
}
return Flow;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Computes area flow.] Synopsis [Average number of references of the leaves.]
Description [] Description []
...@@ -435,24 +449,15 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut ) ...@@ -435,24 +449,15 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
float If_CutFlow( If_Man_t * p, If_Cut_t * pCut ) float If_CutAverageRefs( If_Man_t * p, If_Cut_t * pCut )
{ {
If_Obj_t * pLeaf; If_Obj_t * pLeaf;
float Flow; int nRefsTotal, i;
int i;
assert( pCut->nLeaves > 1 ); assert( pCut->nLeaves > 1 );
Flow = If_CutLutArea(p, pCut); nRefsTotal = 0;
If_CutForEachLeaf( p, pCut, pLeaf, i ) If_CutForEachLeaf( p, pCut, pLeaf, i )
{ nRefsTotal += pLeaf->nRefs;
if ( pLeaf->nRefs == 0 ) return ((float)nRefsTotal)/pCut->nLeaves;
Flow += If_ObjCutBest(pLeaf)->Area;
else
{
assert( pLeaf->EstRefs > p->fEpsilon );
Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs;
}
}
return Flow;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -531,6 +536,27 @@ void If_CutPrint( If_Man_t * p, If_Cut_t * pCut ) ...@@ -531,6 +536,27 @@ void If_CutPrint( If_Man_t * p, If_Cut_t * pCut )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Prints one cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_CutPrintTiming( If_Man_t * p, If_Cut_t * pCut )
{
If_Obj_t * pLeaf;
unsigned i;
printf( "{" );
If_CutForEachLeaf( p, pCut, pLeaf, i )
printf( " %d(%.2f/%.2f)", pLeaf->Id, If_ObjCutBest(pLeaf)->Delay, pLeaf->Required );
printf( " }\n" );
}
/**Function*************************************************************
Synopsis [Computes area of the first level.] Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.] Description [The cut need to be derefed.]
...@@ -585,15 +611,24 @@ float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut, int nLevels ) ...@@ -585,15 +611,24 @@ float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut, int nLevels )
void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc ) void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
{ {
int * pLeaves; int * pLeaves;
char * pPerm;
unsigned * pTruth; unsigned * pTruth;
// save old arrays
pLeaves = pCutDest->pLeaves; pLeaves = pCutDest->pLeaves;
pPerm = pCutDest->pPerm;
pTruth = pCutDest->pTruth; pTruth = pCutDest->pTruth;
// copy the cut info
*pCutDest = *pCutSrc; *pCutDest = *pCutSrc;
// restore the arrays
pCutDest->pLeaves = pLeaves; pCutDest->pLeaves = pLeaves;
pCutDest->pPerm = pPerm;
pCutDest->pTruth = pTruth; pCutDest->pTruth = pTruth;
// copy the array data
memcpy( pCutDest->pLeaves, pCutSrc->pLeaves, sizeof(int) * pCutSrc->nLeaves ); memcpy( pCutDest->pLeaves, pCutSrc->pLeaves, sizeof(int) * pCutSrc->nLeaves );
if ( pCutSrc->pPerm )
memcpy( pCutDest->pPerm, pCutSrc->pPerm, sizeof(unsigned) * If_CutPermWords(pCutSrc->nLimit) );
if ( pCutSrc->pTruth ) if ( pCutSrc->pTruth )
memcpy( pCutDest->pTruth, pCutSrc->pTruth, sizeof(unsigned) * If_CutTruthWords(pCutSrc->nLimit) ); memcpy( pCutDest->pTruth, pCutSrc->pTruth, sizeof(unsigned) * If_CutTruthWords(pCutSrc->nLimit) );
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [ifLib.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapping based on priority cuts.]
Synopsis [Computation of LUT paramters depending on the library.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - November 21, 2006.]
Revision [$Id: ifLib.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
***********************************************************************/
#include "if.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void If_CutSortInputPins( If_Man_t * p, If_Cut_t * pCut, int * pPinPerm, float * pPinDelays );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes delay.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
{
static int pPinPerm[IF_MAX_LUTSIZE];
static float pPinDelays[IF_MAX_LUTSIZE];
If_Obj_t * pLeaf;
float Delay, DelayCur;
float * pLutDelays;
int i;
assert( pCut->nLeaves > 1 );
Delay = -IF_FLOAT_LARGE;
if ( p->pPars->pLutLib )
{
pLutDelays = p->pPars->pLutLib->pLutDelays[pCut->nLeaves];
if ( p->pPars->pLutLib->fVarPinDelays )
{
// compute the delay using sorted pins
If_CutSortInputPins( p, pCut, pPinPerm, pPinDelays );
for ( i = 0; i < (int)pCut->nLeaves; i++ )
{
DelayCur = pPinDelays[pPinPerm[i]] + pLutDelays[i];
Delay = IF_MAX( Delay, DelayCur );
}
}
else
{
If_CutForEachLeaf( p, pCut, pLeaf, i )
{
DelayCur = If_ObjCutBest(pLeaf)->Delay + pLutDelays[0];
Delay = IF_MAX( Delay, DelayCur );
}
}
}
else
{
if ( pCut->fUser )
{
If_CutForEachLeaf( p, pCut, pLeaf, i )
{
DelayCur = If_ObjCutBest(pLeaf)->Delay + (float)pCut->pPerm[i];
Delay = IF_MAX( Delay, DelayCur );
}
}
else
{
If_CutForEachLeaf( p, pCut, pLeaf, i )
{
DelayCur = If_ObjCutBest(pLeaf)->Delay;
Delay = IF_MAX( Delay, DelayCur );
}
Delay += 1.0;
}
}
return Delay;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_CutPropagateRequired( If_Man_t * p, If_Cut_t * pCut, float ObjRequired )
{
static int pPinPerm[IF_MAX_LUTSIZE];
static float pPinDelays[IF_MAX_LUTSIZE];
If_Obj_t * pLeaf;
float * pLutDelays;
float Required;
int i;
// compute the pins
if ( p->pPars->pLutLib )
{
pLutDelays = p->pPars->pLutLib->pLutDelays[pCut->nLeaves];
if ( p->pPars->pLutLib->fVarPinDelays )
{
// compute the delay using sorted pins
If_CutSortInputPins( p, pCut, pPinPerm, pPinDelays );
for ( i = 0; i < (int)pCut->nLeaves; i++ )
{
Required = ObjRequired - pLutDelays[i];
pLeaf = If_ManObj( p, pCut->pLeaves[pPinPerm[i]] );
pLeaf->Required = IF_MIN( pLeaf->Required, Required );
}
}
else
{
Required = ObjRequired - pLutDelays[0];
If_CutForEachLeaf( p, pCut, pLeaf, i )
pLeaf->Required = IF_MIN( pLeaf->Required, Required );
}
}
else
{
if ( pCut->fUser )
{
If_CutForEachLeaf( p, pCut, pLeaf, i )
{
Required = ObjRequired - (float)pCut->pPerm[i];
pLeaf->Required = IF_MIN( pLeaf->Required, Required );
}
}
else
{
Required = ObjRequired - (float)1.0;
If_CutForEachLeaf( p, pCut, pLeaf, i )
pLeaf->Required = IF_MIN( pLeaf->Required, Required );
}
}
}
/**Function*************************************************************
Synopsis [Sorts the pins in the degreasing order of delays.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_CutSortInputPins( If_Man_t * p, If_Cut_t * pCut, int * pPinPerm, float * pPinDelays )
{
If_Obj_t * pLeaf;
int i, j, best_i, temp;
// start the trivial permutation and collect pin delays
If_CutForEachLeaf( p, pCut, pLeaf, i );
{
pPinPerm[i] = i;
pPinDelays[i] = If_ObjCutBest(pLeaf)->Delay;
}
// selection sort the pins in the decreasible order of delays
// this order will match the increasing order of LUT input pins
for ( i = 0; i < (int)pCut->nLeaves-1; i++ )
{
best_i = i;
for ( j = i+1; j < (int)pCut->nLeaves; j++ )
if ( pPinDelays[pPinPerm[j]] > pPinDelays[pPinPerm[best_i]] )
best_i = j;
if ( best_i == i )
continue;
temp = pPinPerm[i];
pPinPerm[i] = pPinPerm[best_i];
pPinPerm[best_i] = temp;
}
// verify
for ( i = 1; i < (int)pCut->nLeaves; i++ )
assert( pPinDelays[pPinPerm[i-1]] >= pPinDelays[pPinPerm[i]] );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...@@ -58,7 +58,8 @@ If_Man_t * If_ManStart( If_Par_t * pPars ) ...@@ -58,7 +58,8 @@ If_Man_t * If_ManStart( If_Par_t * pPars )
p->vTemp = Vec_PtrAlloc( 100 ); p->vTemp = Vec_PtrAlloc( 100 );
// prepare the memory manager // prepare the memory manager
p->nTruthSize = p->pPars->fTruth? If_CutTruthWords( p->pPars->nLutSize ) : 0; p->nTruthSize = p->pPars->fTruth? If_CutTruthWords( p->pPars->nLutSize ) : 0;
p->nCutSize = sizeof(If_Cut_t) + sizeof(int) * p->pPars->nLutSize + sizeof(unsigned) * p->nTruthSize; p->nPermSize = p->pPars->fUsePerm? If_CutPermWords( p->pPars->nLutSize ) : 0;
p->nCutSize = sizeof(If_Cut_t) + sizeof(int) * (p->pPars->nLutSize + p->nPermSize + p->nTruthSize);
p->nEntrySize = sizeof(If_Obj_t) + p->pPars->nCutsMax * p->nCutSize; p->nEntrySize = sizeof(If_Obj_t) + p->pPars->nCutsMax * p->nCutSize;
p->nEntryBase = sizeof(If_Obj_t) + p->pPars->nCutsMax * sizeof(If_Cut_t); p->nEntryBase = sizeof(If_Obj_t) + p->pPars->nCutsMax * sizeof(If_Cut_t);
p->pMem = Mem_FixedStart( p->nEntrySize ); p->pMem = Mem_FixedStart( p->nEntrySize );
...@@ -182,7 +183,7 @@ If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_ ...@@ -182,7 +183,7 @@ If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_
pObj->fCompl1 = fCompl1; pObj->fCompl1 = fCompl1;
pObj->pFanin0 = pFan0; pFan0->nRefs++; pObj->pFanin0 = pFan0; pFan0->nRefs++;
pObj->pFanin1 = pFan1; pFan1->nRefs++; pObj->pFanin1 = pFan1; pFan1->nRefs++;
pObj->fPhase = (fCompl0? !pFan0->fPhase : pFan0->fPhase) & (fCompl1? !pFan1->fPhase : pFan1->fPhase); pObj->fPhase = (fCompl0 ^ pFan0->fPhase) & (fCompl1 ^ pFan1->fPhase);
pObj->Level = 1 + IF_MAX( pFan0->Level, pFan1->Level ); pObj->Level = 1 + IF_MAX( pFan0->Level, pFan1->Level );
if ( p->nLevelMax < (int)pObj->Level ) if ( p->nLevelMax < (int)pObj->Level )
p->nLevelMax = (int)pObj->Level; p->nLevelMax = (int)pObj->Level;
...@@ -192,6 +193,31 @@ If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_ ...@@ -192,6 +193,31 @@ If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_
/**Function************************************************************* /**Function*************************************************************
Synopsis [Creates the choice node.]
Description [Should be called after the equivalence class nodes are linked.]
SideEffects []
SeeAlso []
***********************************************************************/
void If_ManCreateChoice( If_Man_t * p, If_Obj_t * pObj )
{
If_Obj_t * pTemp;
// mark the node as a representative if its class
assert( pObj->fRepr == 0 );
pObj->fRepr = 1;
// update the level of this node (needed for correct required time computation)
for ( pTemp = pObj->pEquiv; pTemp; pTemp = pTemp->pEquiv )
pObj->Level = IF_MAX( pObj->Level, pTemp->Level );
// mark the largest level
if ( p->nLevelMax < (int)pObj->Level )
p->nLevelMax = (int)pObj->Level;
}
/**Function*************************************************************
Synopsis [Prepares memory for the node with cuts.] Synopsis [Prepares memory for the node with cuts.]
Description [] Description []
...@@ -216,7 +242,8 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p ) ...@@ -216,7 +242,8 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
pCut = pObj->Cuts + i; pCut = pObj->Cuts + i;
pCut->nLimit = p->pPars->nLutSize; pCut->nLimit = p->pPars->nLutSize;
pCut->pLeaves = pArrays + i * p->pPars->nLutSize; pCut->pLeaves = pArrays + i * p->pPars->nLutSize;
pCut->pTruth = pArrays + p->pPars->nCutsMax * p->pPars->nLutSize + i * p->nTruthSize; pCut->pPerm = (char *)(p->pPars->fUsePerm? pArrays + p->pPars->nCutsMax * p->pPars->nLutSize + i * p->nPermSize : NULL);
pCut->pTruth = p->pPars->fTruth? pArrays + p->pPars->nCutsMax * (p->pPars->nLutSize + p->nPermSize) + i * p->nTruthSize : NULL;
} }
// assign ID and save // assign ID and save
pObj->Id = Vec_PtrSize(p->vObjs); pObj->Id = Vec_PtrSize(p->vObjs);
...@@ -270,7 +297,8 @@ If_Cut_t ** If_ManSetupCuts( If_Man_t * p ) ...@@ -270,7 +297,8 @@ If_Cut_t ** If_ManSetupCuts( If_Man_t * p )
pCutStore[i] = (If_Cut_t *)((char *)pCutStore[0] + sizeof(If_Cut_t) * i); pCutStore[i] = (If_Cut_t *)((char *)pCutStore[0] + sizeof(If_Cut_t) * i);
pCutStore[i]->nLimit = p->pPars->nLutSize; pCutStore[i]->nLimit = p->pPars->nLutSize;
pCutStore[i]->pLeaves = pArrays + i * p->pPars->nLutSize; pCutStore[i]->pLeaves = pArrays + i * p->pPars->nLutSize;
pCutStore[i]->pTruth = pArrays + nCutsTotal * p->pPars->nLutSize + i * p->nTruthSize; pCutStore[i]->pPerm = (char *)(p->pPars->fUsePerm? pArrays + nCutsTotal * p->pPars->nLutSize + i * p->nPermSize : NULL);
pCutStore[i]->pTruth = p->pPars->fTruth? pArrays + nCutsTotal * (p->pPars->nLutSize + p->nPermSize) + i * p->nTruthSize : NULL;
} }
return pCutStore; return pCutStore;
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
- ordering of the outputs by size - ordering of the outputs by size
- merging Delay, Delay2, and Area - merging Delay, Delay2, and Area
- expand/reduce area recovery - expand/reduce area recovery
- use average nrefs for tie-breaking
*/ */
...@@ -59,7 +60,7 @@ static inline int If_WordCountOnes( unsigned uWord ) ...@@ -59,7 +60,7 @@ static inline int If_WordCountOnes( unsigned uWord )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Finds the best cut.] Synopsis [Finds the best cut for the given node.]
Description [Mapping modes: delay (0), area flow (1), area (2).] Description [Mapping modes: delay (0), area flow (1), area (2).]
...@@ -71,7 +72,10 @@ static inline int If_WordCountOnes( unsigned uWord ) ...@@ -71,7 +72,10 @@ static inline int If_WordCountOnes( unsigned uWord )
void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode ) void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
{ {
If_Cut_t * pCut0, * pCut1, * pCut; If_Cut_t * pCut0, * pCut1, * pCut;
int i, k, iCut, Temp; int i, k, iCut;
assert( !If_ObjIsAnd(pObj->pFanin0) || pObj->pFanin0->nCuts > 1 );
assert( !If_ObjIsAnd(pObj->pFanin1) || pObj->pFanin1->nCuts > 1 );
// prepare // prepare
if ( Mode == 0 ) if ( Mode == 0 )
...@@ -105,29 +109,30 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode ) ...@@ -105,29 +109,30 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
// make sure K-feasible cut exists // make sure K-feasible cut exists
if ( If_WordCountOnes(pCut0->uSign | pCut1->uSign) > p->pPars->nLutSize ) if ( If_WordCountOnes(pCut0->uSign | pCut1->uSign) > p->pPars->nLutSize )
continue; continue;
// prefilter using arrival times
if ( Mode && (pCut0->Delay > pObj->Required + p->fEpsilon || pCut1->Delay > pObj->Required + p->fEpsilon) )
continue;
// merge the nodes // merge the nodes
if ( !If_CutMerge( pCut0, pCut1, pCut ) ) if ( !If_CutMerge( pCut0, pCut1, pCut ) )
continue; continue;
// check if this cut is contained in any of the available cuts // check if this cut is contained in any of the available cuts
pCut->uSign = pCut0->uSign | pCut1->uSign; pCut->uSign = pCut0->uSign | pCut1->uSign;
pCut->fCompl = 0;
// if ( p->pPars->pFuncCost == NULL && If_CutFilter( p, pCut ) ) // do not filter functionality cuts
if ( If_CutFilter( p, pCut ) ) if ( If_CutFilter( p, pCut ) )
continue; continue;
// check if the cut satisfies the required times
pCut->Delay = If_CutDelay( p, pCut );
if ( Mode && pCut->Delay > pObj->Required + p->fEpsilon )
continue;
// the cuts have been successfully merged // the cuts have been successfully merged
// compute the truth table // compute the truth table
if ( p->pPars->fTruth ) if ( p->pPars->fTruth )
If_CutComputeTruth( p, pCut, pCut0, pCut1, pObj->fCompl0, pObj->fCompl1 ); If_CutComputeTruth( p, pCut, pCut0, pCut1, pObj->fCompl0, pObj->fCompl1 );
// compute the application-specific cost and depth // compute the application-specific cost and depth
Temp = p->pPars->pFuncCost? p->pPars->pFuncCost(If_CutTruth(pCut), pCut->nLimit) : 0; pCut->fUser = (p->pPars->pFuncCost != NULL);
pCut->Cost = (Temp & 0xffff); pCut->Depth = (Temp >> 16); pCut->Cost = p->pPars->pFuncCost? p->pPars->pFuncCost(pCut) : 0;
// check if the cut satisfies the required times
pCut->Delay = If_CutDelay( p, pCut );
// printf( "%.2f ", pCut->Delay );
if ( Mode && pCut->Delay > pObj->Required + p->fEpsilon )
continue;
// compute area of the cut (this area may depend on the application specific cost) // compute area of the cut (this area may depend on the application specific cost)
pCut->Area = (Mode == 2)? If_CutAreaDerefed( p, pCut, 100 ) : If_CutFlow( p, pCut ); pCut->Area = (Mode == 2)? If_CutAreaDerefed( p, pCut, 100 ) : If_CutFlow( p, pCut );
pCut->AveRefs = (Mode == 0)? (float)0.0 : If_CutAverageRefs( p, pCut );
// make sure the cut is the last one (after filtering it may not be so) // make sure the cut is the last one (after filtering it may not be so)
assert( pCut == p->ppCuts[iCut] ); assert( pCut == p->ppCuts[iCut] );
p->ppCuts[iCut] = p->ppCuts[p->nCuts]; p->ppCuts[iCut] = p->ppCuts[p->nCuts];
...@@ -139,7 +144,6 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode ) ...@@ -139,7 +144,6 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
iCut = p->nCuts; iCut = p->nCuts;
pCut = p->ppCuts[iCut]; pCut = p->ppCuts[iCut];
} }
//printf( "%d ", p->nCuts );
assert( p->nCuts > 0 ); assert( p->nCuts > 0 );
// sort if we have more cuts // sort if we have more cuts
If_ManSortCuts( p, Mode ); If_ManSortCuts( p, Mode );
...@@ -149,10 +153,6 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode ) ...@@ -149,10 +153,6 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
If_ObjForEachCutStart( pObj, pCut, i, 1 ) If_ObjForEachCutStart( pObj, pCut, i, 1 )
If_CutCopy( pCut, p->ppCuts[i-1] ); If_CutCopy( pCut, p->ppCuts[i-1] );
assert( If_ObjCutBest(pObj)->nLeaves > 1 ); assert( If_ObjCutBest(pObj)->nLeaves > 1 );
// assign delay of the trivial cut
If_ObjCutTriv(pObj)->Delay = If_ObjCutBest(pObj)->Delay;
//printf( "%d %d ", pObj->Id, (int)If_ObjCutBest(pObj)->Delay );
//printf( "%d %d ", pObj->Id, pObj->nCuts );
// ref the selected cut // ref the selected cut
if ( Mode == 2 && pObj->nRefs > 0 ) if ( Mode == 2 && pObj->nRefs > 0 )
If_CutRef( p, If_ObjCutBest(pObj), 100 ); If_CutRef( p, If_ObjCutBest(pObj), 100 );
...@@ -161,6 +161,132 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode ) ...@@ -161,6 +161,132 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
p->nCutsMax = pObj->nCuts; p->nCutsMax = pObj->nCuts;
} }
/**Function*************************************************************
Synopsis [Finds the best cut for the choice node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_ObjMergeChoice( If_Man_t * p, If_Obj_t * pObj, int Mode )
{
If_Obj_t * pTemp;
If_Cut_t * pCutTemp, * pCut;
int i, iCut;
assert( pObj->pEquiv != NULL );
// prepare
if ( Mode == 2 && pObj->nRefs > 0 )
If_CutDeref( p, If_ObjCutBest(pObj), 100 );
// prepare room for the next cut
p->nCuts = 0;
iCut = p->nCuts;
pCut = p->ppCuts[iCut];
// generate cuts
for ( pTemp = pObj; pTemp; pTemp = pTemp->pEquiv )
If_ObjForEachCutStart( pTemp, pCutTemp, i, 1 )
{
assert( pTemp->nCuts > 1 );
assert( pTemp == pObj || pTemp->nRefs == 0 );
// copy the cut into storage
If_CutCopy( pCut, pCutTemp );
// check if this cut is contained in any of the available cuts
if ( If_CutFilter( p, pCut ) )
continue;
// the cuts have been successfully merged
// check if the cut satisfies the required times
assert( pCut->Delay == If_CutDelay( p, pCut ) );
if ( Mode && pCut->Delay > pObj->Required + p->fEpsilon )
continue;
// set the phase attribute
pCut->fCompl ^= (pObj->fPhase ^ pTemp->fPhase);
// compute area of the cut (this area may depend on the application specific cost)
pCut->Area = (Mode == 2)? If_CutAreaDerefed( p, pCut, 100 ) : If_CutFlow( p, pCut );
pCut->AveRefs = (Mode == 0)? (float)0.0 : If_CutAverageRefs( p, pCut );
// make sure the cut is the last one (after filtering it may not be so)
assert( pCut == p->ppCuts[iCut] );
p->ppCuts[iCut] = p->ppCuts[p->nCuts];
p->ppCuts[p->nCuts] = pCut;
// count the cut
p->nCuts++;
// prepare room for the next cut
iCut = p->nCuts;
pCut = p->ppCuts[iCut];
// quit if we exceeded the number of cuts
if ( p->nCuts >= p->pPars->nCutsMax * p->pPars->nCutsMax )
break;
}
assert( p->nCuts > 0 );
// sort if we have more cuts
If_ManSortCuts( p, Mode );
// decide how many cuts to use
pObj->nCuts = IF_MIN( p->nCuts + 1, p->nCutsUsed );
// take the first
If_ObjForEachCutStart( pObj, pCut, i, 1 )
If_CutCopy( pCut, p->ppCuts[i-1] );
assert( If_ObjCutBest(pObj)->nLeaves > 1 );
// ref the selected cut
if ( Mode == 2 && pObj->nRefs > 0 )
If_CutRef( p, If_ObjCutBest(pObj), 100 );
// find the largest cut
if ( p->nCutsMax < pObj->nCuts )
p->nCutsMax = pObj->nCuts;
}
/**Function*************************************************************
Synopsis [Performs one mapping pass over all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode, int fRequired, char * pLabel )
{
ProgressBar * pProgress;
If_Obj_t * pObj;
int i, clk = clock();
assert( Mode >= 0 && Mode <= 2 );
// set the cut number
p->nCutsUsed = nCutsUsed;
p->nCutsMerged = 0;
p->nCutsSaved = 0;
p->nCutsMax = 0;
// map the internal nodes
pProgress = Extra_ProgressBarStart( stdout, If_ManObjNum(p) );
If_ManForEachNode( p, pObj, i )
{
Extra_ProgressBarUpdate( pProgress, i, pLabel );
If_ObjPerformMapping( p, pObj, Mode );
if ( pObj->fRepr )
If_ObjMergeChoice( p, pObj, Mode );
}
Extra_ProgressBarStop( pProgress );
// compute required times and stats
if ( fRequired )
{
If_ManComputeRequired( p, Mode==0 );
if ( p->pPars->fVerbose )
{
char Symb = (Mode == 0)? 'D' : ((Mode == 1)? 'F' : 'A');
printf( "%c: Del = %6.2f. Area = %8.2f. Cuts = %8d. Lim = %2d. Ave = %5.2f. ",
Symb, p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
PRT( "T", clock() - clk );
// printf( "Saved cuts = %d.\n", p->nCutsSaved );
// printf( "Max number of cuts = %d. Average number of cuts = %5.2f.\n",
// p->nCutsMax, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
}
}
return 1;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -50,7 +50,7 @@ void If_ManPerformMappingPreprocess( If_Man_t * p ) ...@@ -50,7 +50,7 @@ void If_ManPerformMappingPreprocess( If_Man_t * p )
// perform min-area mapping and move the cut to the end // perform min-area mapping and move the cut to the end
p->pPars->fArea = 1; p->pPars->fArea = 1;
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 0 ); If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 0, "Start delay" );
p->pPars->fArea = 0; p->pPars->fArea = 0;
delayArea = If_ManDelayMax( p ); delayArea = If_ManDelayMax( p );
if ( p->pPars->DelayTarget != -1 && delayArea < p->pPars->DelayTarget - p->fEpsilon ) if ( p->pPars->DelayTarget != -1 && delayArea < p->pPars->DelayTarget - p->fEpsilon )
...@@ -59,15 +59,15 @@ void If_ManPerformMappingPreprocess( If_Man_t * p ) ...@@ -59,15 +59,15 @@ void If_ManPerformMappingPreprocess( If_Man_t * p )
// perfrom min-delay mapping and move the cut to the end // perfrom min-delay mapping and move the cut to the end
p->pPars->fFancy = 1; p->pPars->fFancy = 1;
If_ManPerformMappingRound( p, p->pPars->nCutsMax - 1, 0, 0 ); If_ManPerformMappingRound( p, p->pPars->nCutsMax - 1, 0, 0, "Start delay-2" );
p->pPars->fFancy = 0; p->pPars->fFancy = 0;
delayDelay = If_ManDelayMax( p ); delayDelay = If_ManDelayMax( p );
if ( p->pPars->DelayTarget != -1 && delayDelay < p->pPars->DelayTarget - p->fEpsilon ) if ( p->pPars->DelayTarget != -1 && delayDelay < p->pPars->DelayTarget - p->fEpsilon )
delayDelay = p->pPars->DelayTarget; delayDelay = p->pPars->DelayTarget;
If_ManPerformMappingMoveBestCut( p, p->pPars->nCutsMax - 2, 1 ); If_ManPerformMappingMoveBestCut( p, p->pPars->nCutsMax - 2, 1 );
// perform min-area mapping // perform min-delay mapping
If_ManPerformMappingRound( p, p->pPars->nCutsMax - 2, 0, 0 ); If_ManPerformMappingRound( p, p->pPars->nCutsMax - 2, 0, 0, "Start flow" );
delayPure = If_ManDelayMax( p ); delayPure = If_ManDelayMax( p );
if ( p->pPars->DelayTarget != -1 && delayPure < p->pPars->DelayTarget - p->fEpsilon ) if ( p->pPars->DelayTarget != -1 && delayPure < p->pPars->DelayTarget - p->fEpsilon )
delayPure = p->pPars->DelayTarget; delayPure = p->pPars->DelayTarget;
...@@ -100,7 +100,7 @@ void If_ManPerformMappingPreprocess( If_Man_t * p ) ...@@ -100,7 +100,7 @@ void If_ManPerformMappingPreprocess( If_Man_t * p )
If_ManComputeRequired( p, 1 ); If_ManComputeRequired( p, 1 );
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
{ {
printf( "S: Del = %6.2f. Area = %8.2f. Cuts = %6d. Lim = %2d. Ave = %5.2f. ", printf( "S: Del = %6.2f. Area = %8.2f. Cuts = %8d. Lim = %2d. Ave = %5.2f. ",
p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) ); p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
PRT( "T", clock() - clk ); PRT( "T", clock() - clk );
} }
......
...@@ -55,7 +55,7 @@ void If_ManImproveMapping( If_Man_t * p ) ...@@ -55,7 +55,7 @@ void If_ManImproveMapping( If_Man_t * p )
If_ManComputeRequired( p, 0 ); If_ManComputeRequired( p, 0 );
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
{ {
printf( "E: Del = %6.2f. Area = %8.2f. Cuts = %6d. Lim = %2d. Ave = %5.2f. ", printf( "E: Del = %6.2f. Area = %8.2f. Cuts = %8d. Lim = %2d. Ave = %5.2f. ",
p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) ); p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
PRT( "T", clock() - clk ); PRT( "T", clock() - clk );
} }
...@@ -65,7 +65,7 @@ void If_ManImproveMapping( If_Man_t * p ) ...@@ -65,7 +65,7 @@ void If_ManImproveMapping( If_Man_t * p )
If_ManComputeRequired( p, 0 ); If_ManComputeRequired( p, 0 );
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
{ {
printf( "R: Del = %6.2f. Area = %8.2f. Cuts = %6d. Lim = %2d. Ave = %5.2f. ", printf( "R: Del = %6.2f. Area = %8.2f. Cuts = %8d. Lim = %2d. Ave = %5.2f. ",
p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) ); p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
PRT( "T", clock() - clk ); PRT( "T", clock() - clk );
} }
...@@ -75,7 +75,7 @@ void If_ManImproveMapping( If_Man_t * p ) ...@@ -75,7 +75,7 @@ void If_ManImproveMapping( If_Man_t * p )
If_ManComputeRequired( p, 0 ); If_ManComputeRequired( p, 0 );
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
{ {
printf( "E: Del = %6.2f. Area = %8.2f. Cuts = %6d. Lim = %2d. Ave = %5.2f. ", printf( "E: Del = %6.2f. Area = %8.2f. Cuts = %8d. Lim = %2d. Ave = %5.2f. ",
p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) ); p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
PRT( "T", clock() - clk ); PRT( "T", clock() - clk );
} }
......
...@@ -58,7 +58,7 @@ int If_ManPerformMappingSeq( If_Man_t * p ) ...@@ -58,7 +58,7 @@ int If_ManPerformMappingSeq( If_Man_t * p )
pObj->EstRefs = (float)1.0; pObj->EstRefs = (float)1.0;
// delay oriented mapping // delay oriented mapping
p->pPars->fFancy = 1; p->pPars->fFancy = 1;
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 0 ); If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 0, NULL );
p->pPars->fFancy = 0; p->pPars->fFancy = 0;
// perform iterations over the circuit // perform iterations over the circuit
......
...@@ -72,18 +72,19 @@ void If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut ...@@ -72,18 +72,19 @@ void If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut
extern void Kit_FactorTest( unsigned * pTruth, int nVars ); extern void Kit_FactorTest( unsigned * pTruth, int nVars );
// permute the first table // permute the first table
if ( fCompl0 ) if ( fCompl0 ^ pCut0->fCompl )
Extra_TruthNot( p->puTemp[0], If_CutTruth(pCut0), pCut->nLimit ); Extra_TruthNot( p->puTemp[0], If_CutTruth(pCut0), pCut->nLimit );
else else
Extra_TruthCopy( p->puTemp[0], If_CutTruth(pCut0), pCut->nLimit ); Extra_TruthCopy( p->puTemp[0], If_CutTruth(pCut0), pCut->nLimit );
Extra_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nLeaves, pCut->nLimit, Cut_TruthPhase(pCut, pCut0) ); Extra_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nLeaves, pCut->nLimit, Cut_TruthPhase(pCut, pCut0) );
// permute the second table // permute the second table
if ( fCompl1 ) if ( fCompl1 ^ pCut1->fCompl )
Extra_TruthNot( p->puTemp[1], If_CutTruth(pCut1), pCut->nLimit ); Extra_TruthNot( p->puTemp[1], If_CutTruth(pCut1), pCut->nLimit );
else else
Extra_TruthCopy( p->puTemp[1], If_CutTruth(pCut1), pCut->nLimit ); Extra_TruthCopy( p->puTemp[1], If_CutTruth(pCut1), pCut->nLimit );
Extra_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nLeaves, pCut->nLimit, Cut_TruthPhase(pCut, pCut1) ); Extra_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nLeaves, pCut->nLimit, Cut_TruthPhase(pCut, pCut1) );
// produce the resulting table // produce the resulting table
assert( pCut->fCompl == 0 );
if ( pCut->fCompl ) if ( pCut->fCompl )
Extra_TruthNand( If_CutTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nLimit ); Extra_TruthNand( If_CutTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nLimit );
else else
...@@ -91,6 +92,7 @@ void If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut ...@@ -91,6 +92,7 @@ void If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut
// perform // perform
// Kit_FactorTest( If_CutTruth(pCut), pCut->nLimit ); // Kit_FactorTest( If_CutTruth(pCut), pCut->nLimit );
// printf( "%d ", If_CutLeaveNum(pCut) - Kit_TruthSupportSize(If_CutTruth(pCut), If_CutLeaveNum(pCut)) );
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -44,10 +44,24 @@ float If_ManDelayMax( If_Man_t * p ) ...@@ -44,10 +44,24 @@ float If_ManDelayMax( If_Man_t * p )
If_Obj_t * pObj; If_Obj_t * pObj;
float DelayBest; float DelayBest;
int i; int i;
if ( p->pPars->fLatchPaths && p->pPars->nLatches == 0 )
{
printf( "Delay optimization of latch path is not performed because there is no latches.\n" );
p->pPars->fLatchPaths = 0;
}
DelayBest = -IF_FLOAT_LARGE; DelayBest = -IF_FLOAT_LARGE;
If_ManForEachPo( p, pObj, i ) if ( p->pPars->fLatchPaths )
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay ) {
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay; If_ManForEachLatch( p, pObj, i )
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
}
else
{
If_ManForEachPo( p, pObj, i )
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
}
return DelayBest; return DelayBest;
} }
...@@ -174,10 +188,8 @@ float If_ManScanMapping( If_Man_t * p ) ...@@ -174,10 +188,8 @@ float If_ManScanMapping( If_Man_t * p )
***********************************************************************/ ***********************************************************************/
void If_ManComputeRequired( If_Man_t * p, int fFirstTime ) void If_ManComputeRequired( If_Man_t * p, int fFirstTime )
{ {
If_Obj_t * pObj, * pLeaf; If_Obj_t * pObj;
If_Cut_t * pCutBest; int i;
float Required;
int i, k;
// compute area, clean required times, collect nodes used in the mapping // compute area, clean required times, collect nodes used in the mapping
p->AreaGlo = If_ManScanMapping( p ); p->AreaGlo = If_ManScanMapping( p );
// get the global required times // get the global required times
...@@ -209,16 +221,8 @@ void If_ManComputeRequired( If_Man_t * p, int fFirstTime ) ...@@ -209,16 +221,8 @@ void If_ManComputeRequired( If_Man_t * p, int fFirstTime )
If_ObjFanin0(pObj)->Required = p->RequiredGlo; If_ObjFanin0(pObj)->Required = p->RequiredGlo;
} }
// go through the nodes in the reverse topological order // go through the nodes in the reverse topological order
Vec_PtrForEachEntry( p->vMapped, pObj, k ) Vec_PtrForEachEntry( p->vMapped, pObj, i )
{ If_CutPropagateRequired( p, If_ObjCutBest(pObj), pObj->Required );
// get the best cut of the node
pCutBest = If_ObjCutBest(pObj);
// get the required times for the leaves of the cut
Required = pObj->Required - If_CutLutDelay( p, pCutBest );
// update the required time of the leaves
If_CutForEachLeaf( p, pCutBest, pLeaf, i )
pLeaf->Required = IF_MIN( pLeaf->Required, Required );
}
} }
......
SRC += src/map/if/ifCore.c \ SRC += src/map/if/ifCore.c \
src/map/if/ifCut.c \ src/map/if/ifCut.c \
src/map/if/ifLib.c \
src/map/if/ifMan.c \ src/map/if/ifMan.c \
src/map/if/ifMap.c \ src/map/if/ifMap.c \
src/map/if/ifPrepro.c \ src/map/if/ifPrepro.c \
......
...@@ -149,7 +149,7 @@ void Map_MappingCuts( Map_Man_t * p ) ...@@ -149,7 +149,7 @@ void Map_MappingCuts( Map_Man_t * p )
if ( p->fVerbose ) if ( p->fVerbose )
{ {
nCuts = Map_MappingCountAllCuts(p); nCuts = Map_MappingCountAllCuts(p);
printf( "Nodes = %6d. Total %d-feasible cuts = %d. Per node = %.1f. ", printf( "Nodes = %6d. Total %d-feasible cuts = %10d. Per node = %.1f. ",
p->nNodes, p->nVarsMax, nCuts, ((float)nCuts)/p->nNodes ); p->nNodes, p->nVarsMax, nCuts, ((float)nCuts)/p->nNodes );
PRT( "Time", clock() - clk ); PRT( "Time", clock() - clk );
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
*/ */
#include <stdio.h> #include <stdio.h>
//#include "extra.h" #include <stdlib.h>
#include "st.h" #include "st.h"
#ifndef ABS #ifndef ABS
......
...@@ -91,6 +91,9 @@ struct Kit_Graph_t_ ...@@ -91,6 +91,9 @@ struct Kit_Graph_t_
/// MACRO DEFINITIONS /// /// MACRO DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#define KIT_MIN(a,b) (((a) < (b))? (a) : (b))
#define KIT_MAX(a,b) (((a) > (b))? (a) : (b))
#ifndef ALLOC #ifndef ALLOC
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) #define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
#endif #endif
...@@ -143,8 +146,10 @@ static inline Kit_Node_t * Kit_GraphNode( Kit_Graph_t * pGraph, int i ) ...@@ -143,8 +146,10 @@ static inline Kit_Node_t * Kit_GraphNode( Kit_Graph_t * pGraph, int i )
static inline Kit_Node_t * Kit_GraphNodeLast( Kit_Graph_t * pGraph ) { return pGraph->pNodes + pGraph->nSize - 1; } static inline Kit_Node_t * Kit_GraphNodeLast( Kit_Graph_t * pGraph ) { return pGraph->pNodes + pGraph->nSize - 1; }
static inline int Kit_GraphNodeInt( Kit_Graph_t * pGraph, Kit_Node_t * pNode ) { return pNode - pGraph->pNodes; } static inline int Kit_GraphNodeInt( Kit_Graph_t * pGraph, Kit_Node_t * pNode ) { return pNode - pGraph->pNodes; }
static inline int Kit_GraphNodeIsVar( Kit_Graph_t * pGraph, Kit_Node_t * pNode ) { return Kit_GraphNodeInt(pGraph,pNode) < pGraph->nLeaves; } static inline int Kit_GraphNodeIsVar( Kit_Graph_t * pGraph, Kit_Node_t * pNode ) { return Kit_GraphNodeInt(pGraph,pNode) < pGraph->nLeaves; }
static inline Kit_Node_t * Kit_GraphVar( Kit_Graph_t * pGraph ) { assert( Kit_GraphIsVar( pGraph ) ); return Kit_GraphNode( pGraph, pGraph->eRoot.Node ); } static inline Kit_Node_t * Kit_GraphVar( Kit_Graph_t * pGraph ) { assert( Kit_GraphIsVar( pGraph ) ); return Kit_GraphNode( pGraph, pGraph->eRoot.Node ); }
static inline int Kit_GraphVarInt( Kit_Graph_t * pGraph ) { assert( Kit_GraphIsVar( pGraph ) ); return Kit_GraphNodeInt( pGraph, Kit_GraphVar(pGraph) );} static inline int Kit_GraphVarInt( Kit_Graph_t * pGraph ) { assert( Kit_GraphIsVar( pGraph ) ); return Kit_GraphNodeInt( pGraph, Kit_GraphVar(pGraph) ); }
static inline Kit_Node_t * Kit_GraphNodeFanin0( Kit_Graph_t * pGraph, Kit_Node_t * pNode ){ return Kit_GraphNodeIsVar(pGraph, pNode)? NULL : Kit_GraphNode(pGraph, pNode->eEdge0.Node); }
static inline Kit_Node_t * Kit_GraphNodeFanin1( Kit_Graph_t * pGraph, Kit_Node_t * pNode ){ return Kit_GraphNodeIsVar(pGraph, pNode)? NULL : Kit_GraphNode(pGraph, pNode->eEdge1.Node); }
static inline int Kit_Float2Int( float Val ) { return *((int *)&Val); } static inline int Kit_Float2Int( float Val ) { return *((int *)&Val); }
static inline float Kit_Int2Float( int Num ) { return *((float *)&Num); } static inline float Kit_Int2Float( int Num ) { return *((float *)&Num); }
...@@ -272,7 +277,7 @@ static inline void Kit_TruthNand( unsigned * pOut, unsigned * pIn0, unsigned * p ...@@ -272,7 +277,7 @@ static inline void Kit_TruthNand( unsigned * pOut, unsigned * pIn0, unsigned * p
/*=== kitBdd.c ==========================================================*/ /*=== kitBdd.c ==========================================================*/
extern DdNode * Kit_SopToBdd( DdManager * dd, Kit_Sop_t * cSop, int nVars ); extern DdNode * Kit_SopToBdd( DdManager * dd, Kit_Sop_t * cSop, int nVars );
extern DdNode * Kit_GraphToBdd( DdManager * dd, Kit_Graph_t * pGraph ); extern DdNode * Kit_GraphToBdd( DdManager * dd, Kit_Graph_t * pGraph );
extern DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars ); extern DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars, int fMSBonTop );
/*=== kitFactor.c ==========================================================*/ /*=== kitFactor.c ==========================================================*/
extern Kit_Graph_t * Kit_SopFactor( Vec_Int_t * vCover, int fCompl, int nVars, Vec_Int_t * vMemory ); extern Kit_Graph_t * Kit_SopFactor( Vec_Int_t * vCover, int fCompl, int nVars, Vec_Int_t * vMemory );
/*=== kitGraph.c ==========================================================*/ /*=== kitGraph.c ==========================================================*/
...@@ -288,6 +293,7 @@ extern Kit_Edge_t Kit_GraphAddNodeXor( Kit_Graph_t * pGraph, Kit_Edge_t eEd ...@@ -288,6 +293,7 @@ extern Kit_Edge_t Kit_GraphAddNodeXor( Kit_Graph_t * pGraph, Kit_Edge_t eEd
extern Kit_Edge_t Kit_GraphAddNodeMux( Kit_Graph_t * pGraph, Kit_Edge_t eEdgeC, Kit_Edge_t eEdgeT, Kit_Edge_t eEdgeE, int Type ); extern Kit_Edge_t Kit_GraphAddNodeMux( Kit_Graph_t * pGraph, Kit_Edge_t eEdgeC, Kit_Edge_t eEdgeT, Kit_Edge_t eEdgeE, int Type );
extern unsigned Kit_GraphToTruth( Kit_Graph_t * pGraph ); extern unsigned Kit_GraphToTruth( Kit_Graph_t * pGraph );
extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemory ); extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
extern int Kit_GraphLeafDepth_rec( Kit_Graph_t * pGraph, Kit_Node_t * pNode, Kit_Node_t * pLeaf );
/*=== kitHop.c ==========================================================*/ /*=== kitHop.c ==========================================================*/
/*=== kitIsop.c ==========================================================*/ /*=== kitIsop.c ==========================================================*/
extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth ); extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth );
......
...@@ -135,26 +135,26 @@ DdNode * Kit_GraphToBdd( DdManager * dd, Kit_Graph_t * pGraph ) ...@@ -135,26 +135,26 @@ DdNode * Kit_GraphToBdd( DdManager * dd, Kit_Graph_t * pGraph )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
DdNode * Kit_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int nVars, int nVarsTotal ) DdNode * Kit_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int nVars, int nVarsTotal, int fMSBonTop )
{ {
DdNode * bF0, * bF1, * bF; DdNode * bF0, * bF1, * bF;
if ( nVars == 0 ) int Var;
if ( nVars <= 5 )
{ {
if ( pTruth[iBit>>5] & (1 << iBit&31) ) unsigned uTruth, uMask;
return b1; uMask = ((~(unsigned)0) >> (32 - (1<<nVars)));
return b0; uTruth = (pTruth[iBit>>5] >> (iBit&31)) & uMask;
} if ( uTruth == 0 )
if ( nVars == 5 )
{
if ( pTruth[iBit>>5] == 0xFFFFFFFF )
return b1;
if ( pTruth[iBit>>5] == 0 )
return b0; return b0;
if ( uTruth == uMask )
return b1;
} }
// find the variable to use
Var = fMSBonTop? nVarsTotal-nVars : nVars-1;
// other special cases can be added // other special cases can be added
bF0 = Kit_TruthToBdd_rec( dd, pTruth, iBit, nVars-1, nVarsTotal ); Cudd_Ref( bF0 ); bF0 = Kit_TruthToBdd_rec( dd, pTruth, iBit, nVars-1, nVarsTotal, fMSBonTop ); Cudd_Ref( bF0 );
bF1 = Kit_TruthToBdd_rec( dd, pTruth, iBit+(1<<(nVars-1)), nVars-1, nVarsTotal ); Cudd_Ref( bF1 ); bF1 = Kit_TruthToBdd_rec( dd, pTruth, iBit+(1<<(nVars-1)), nVars-1, nVarsTotal, fMSBonTop ); Cudd_Ref( bF1 );
bF = Cudd_bddIte( dd, dd->vars[nVarsTotal-nVars], bF1, bF0 ); Cudd_Ref( bF ); bF = Cudd_bddIte( dd, dd->vars[Var], bF1, bF0 ); Cudd_Ref( bF );
Cudd_RecursiveDeref( dd, bF0 ); Cudd_RecursiveDeref( dd, bF0 );
Cudd_RecursiveDeref( dd, bF1 ); Cudd_RecursiveDeref( dd, bF1 );
Cudd_Deref( bF ); Cudd_Deref( bF );
...@@ -176,9 +176,9 @@ DdNode * Kit_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int nV ...@@ -176,9 +176,9 @@ DdNode * Kit_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int nV
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars ) DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars, int fMSBonTop )
{ {
return Kit_TruthToBdd_rec( dd, pTruth, 0, nVars, nVars ); return Kit_TruthToBdd_rec( dd, pTruth, 0, nVars, nVars, fMSBonTop );
} }
/**Function************************************************************* /**Function*************************************************************
......
...@@ -197,6 +197,7 @@ Kit_Edge_t Kit_SopFactorTrivialCube_rec( Kit_Graph_t * pFForm, unsigned uCube, i ...@@ -197,6 +197,7 @@ Kit_Edge_t Kit_SopFactorTrivialCube_rec( Kit_Graph_t * pFForm, unsigned uCube, i
{ {
Kit_Edge_t eNode1, eNode2; Kit_Edge_t eNode1, eNode2;
int i, iLit, nLits, nLits1, nLits2; int i, iLit, nLits, nLits1, nLits2;
assert( uCube );
// count the number of literals in this interval // count the number of literals in this interval
nLits = 0; nLits = 0;
for ( i = nStart; i < nFinish; i++ ) for ( i = nStart; i < nFinish; i++ )
......
...@@ -354,13 +354,40 @@ Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemor ...@@ -354,13 +354,40 @@ Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemor
Kit_Graph_t * pGraph; Kit_Graph_t * pGraph;
int RetValue; int RetValue;
// derive SOP // derive SOP
RetValue = Kit_TruthIsop( pTruth, nVars, vMemory, 0 ); RetValue = Kit_TruthIsop( pTruth, nVars, vMemory, 0 ); // tried 1 and found not useful in "renode"
assert( RetValue == 0 ); if ( RetValue == -1 )
return NULL;
assert( RetValue == 0 || RetValue == 1 );
// derive factored form // derive factored form
pGraph = Kit_SopFactor( vMemory, 0, nVars, vMemory ); pGraph = Kit_SopFactor( vMemory, RetValue, nVars, vMemory );
return pGraph; return pGraph;
} }
/**Function*************************************************************
Synopsis [Derives the maximum depth from the leaf to the root.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Kit_GraphLeafDepth_rec( Kit_Graph_t * pGraph, Kit_Node_t * pNode, Kit_Node_t * pLeaf )
{
int Depth0, Depth1, Depth;
if ( pNode == pLeaf )
return 0;
if ( Kit_GraphNodeIsVar(pGraph, pNode) )
return -100;
Depth0 = Kit_GraphLeafDepth_rec( pGraph, Kit_GraphNodeFanin0(pGraph, pNode), pLeaf );
Depth1 = Kit_GraphLeafDepth_rec( pGraph, Kit_GraphNodeFanin1(pGraph, pNode), pLeaf );
Depth = KIT_MAX( Depth0, Depth1 );
Depth = (Depth == -100) ? -100 : Depth + 1;
return Depth;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -67,9 +67,14 @@ int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryB ...@@ -67,9 +67,14 @@ int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryB
if ( pcRes->nCubes == -1 ) if ( pcRes->nCubes == -1 )
{ {
vMemory->nSize = -1; vMemory->nSize = -1;
return 0; return -1;
} }
assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) ); assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) );
if ( pcRes->nCubes == 0 || (pcRes->nCubes == 1 && pcRes->pCubes[0] == 0) )
{
Vec_IntShrink( vMemory, pcRes->nCubes );
return 0;
}
if ( fTryBoth ) if ( fTryBoth )
{ {
// compute ISOP for the complemented polarity // compute ISOP for the complemented polarity
......
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