mirror of https://github.com/YosysHQ/abc.git
Version abc61128
This commit is contained in:
parent
6ad22b4d3b
commit
44d220d28f
2
abc.rc
2
abc.rc
|
|
@ -1,7 +1,7 @@
|
||||||
# global parameters
|
# global parameters
|
||||||
set check # checks intermediate networks
|
set check # checks intermediate networks
|
||||||
#set checkfio # prints warnings when fanins/fanouts are duplicated
|
#set checkfio # prints warnings when fanins/fanouts are duplicated
|
||||||
set checkread # checks new networks after reading from file
|
#set checkread # checks new networks after reading from file
|
||||||
set backup # saves backup networks retrived by "undo" and "recall"
|
set backup # saves backup networks retrived by "undo" and "recall"
|
||||||
set savesteps 1 # sets the maximum number of backup networks to save
|
set savesteps 1 # sets the maximum number of backup networks to save
|
||||||
set progressbar # display the progress bar
|
set progressbar # display the progress bar
|
||||||
|
|
|
||||||
|
|
@ -648,6 +648,7 @@ extern Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc,
|
||||||
extern Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk );
|
extern Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk );
|
||||||
extern DdManager * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose );
|
extern DdManager * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose );
|
||||||
extern DdManager * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan );
|
extern DdManager * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan );
|
||||||
|
extern int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk );
|
||||||
/*=== abcNtk.c ==========================================================*/
|
/*=== abcNtk.c ==========================================================*/
|
||||||
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan );
|
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan );
|
||||||
extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
||||||
|
|
|
||||||
|
|
@ -934,8 +934,9 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
int c;
|
int c;
|
||||||
int fUseBdds;
|
int fUseBdds;
|
||||||
int fNaive;
|
int fNaive;
|
||||||
|
int fReorder;
|
||||||
int fVerbose;
|
int fVerbose;
|
||||||
extern void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose );
|
extern void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fReorder, int fVerbose );
|
||||||
|
|
||||||
pNtk = Abc_FrameReadNtk(pAbc);
|
pNtk = Abc_FrameReadNtk(pAbc);
|
||||||
pOut = Abc_FrameReadOut(pAbc);
|
pOut = Abc_FrameReadOut(pAbc);
|
||||||
|
|
@ -944,9 +945,10 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
// set defaults
|
// set defaults
|
||||||
fUseBdds = 0;
|
fUseBdds = 0;
|
||||||
fNaive = 0;
|
fNaive = 0;
|
||||||
|
fReorder = 1;
|
||||||
fVerbose = 0;
|
fVerbose = 0;
|
||||||
Extra_UtilGetoptReset();
|
Extra_UtilGetoptReset();
|
||||||
while ( ( c = Extra_UtilGetopt( argc, argv, "bnvh" ) ) != EOF )
|
while ( ( c = Extra_UtilGetopt( argc, argv, "bnrvh" ) ) != EOF )
|
||||||
{
|
{
|
||||||
switch ( c )
|
switch ( c )
|
||||||
{
|
{
|
||||||
|
|
@ -956,6 +958,9 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
case 'n':
|
case 'n':
|
||||||
fNaive ^= 1;
|
fNaive ^= 1;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
fReorder ^= 1;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
fVerbose ^= 1;
|
fVerbose ^= 1;
|
||||||
break;
|
break;
|
||||||
|
|
@ -975,19 +980,22 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
fprintf( pErr, "This command works only for combinational networks.\n" );
|
fprintf( pErr, "This command works only for combinational networks.\n" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ( !Abc_NtkIsStrash(pNtk) )
|
if ( Abc_NtkIsStrash(pNtk) )
|
||||||
|
Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fReorder, fVerbose );
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fprintf( pErr, "This command works only for AIGs (run \"strash\").\n" );
|
pNtk = Abc_NtkStrash( pNtk, 0, 0 );
|
||||||
return 1;
|
Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fReorder, fVerbose );
|
||||||
|
Abc_NtkDelete( pNtk );
|
||||||
}
|
}
|
||||||
Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fVerbose );
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
fprintf( pErr, "usage: print_symm [-nbvh]\n" );
|
fprintf( pErr, "usage: print_symm [-bnrvh]\n" );
|
||||||
fprintf( pErr, "\t computes symmetries of the PO functions\n" );
|
fprintf( pErr, "\t computes symmetries of the PO functions\n" );
|
||||||
fprintf( pErr, "\t-b : toggle BDD-based or SAT-based computations [default = %s].\n", fUseBdds? "BDD": "SAT" );
|
fprintf( pErr, "\t-b : toggle BDD-based or SAT-based computations [default = %s].\n", fUseBdds? "BDD": "SAT" );
|
||||||
fprintf( pErr, "\t-n : enable naive BDD-based computation [default = %s].\n", fNaive? "yes": "no" );
|
fprintf( pErr, "\t-n : enable naive BDD-based computation [default = %s].\n", fNaive? "yes": "no" );
|
||||||
|
fprintf( pErr, "\t-r : enable dynamic BDD variable reordering [default = %s].\n", fReorder? "yes": "no" );
|
||||||
fprintf( pErr, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" );
|
fprintf( pErr, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" );
|
||||||
fprintf( pErr, "\t-h : print the command usage\n");
|
fprintf( pErr, "\t-h : print the command usage\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -7082,7 +7090,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
fRecovery = 1;
|
fRecovery = 1;
|
||||||
fSwitching = 0;
|
fSwitching = 0;
|
||||||
fLatchPaths = 0;
|
fLatchPaths = 0;
|
||||||
fVerbose = 0;
|
fVerbose = 1;
|
||||||
DelayTarget =-1;
|
DelayTarget =-1;
|
||||||
nLutSize =-1;
|
nLutSize =-1;
|
||||||
Extra_UtilGetoptReset();
|
Extra_UtilGetoptReset();
|
||||||
|
|
@ -7383,19 +7391,19 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
memset( pPars, 0, sizeof(If_Par_t) );
|
memset( pPars, 0, sizeof(If_Par_t) );
|
||||||
pPars->Mode = 1;
|
pPars->Mode = 0;
|
||||||
pPars->nLutSize = 4;
|
pPars->nLutSize = 5;
|
||||||
// pPars->pLutLib = Abc_FrameReadLibLut();
|
// pPars->pLutLib = Abc_FrameReadLibLut();
|
||||||
pPars->nCutsMax = 2;
|
pPars->nCutsMax = 10;
|
||||||
pPars->fSeq = 0;
|
pPars->fArea = 0;
|
||||||
pPars->fLatchPaths = 0;
|
pPars->fFancy = 0;
|
||||||
pPars->nLatches = 0;
|
pPars->fLatchPaths = 0;
|
||||||
pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk);
|
pPars->fSeq = 0;
|
||||||
pPars->pTimesReq = NULL;
|
pPars->nLatches = 0;
|
||||||
pPars->DelayTarget = -1;
|
pPars->DelayTarget = -1;
|
||||||
pPars->fVerbose = 0;
|
pPars->fVerbose = 1;
|
||||||
Extra_UtilGetoptReset();
|
Extra_UtilGetoptReset();
|
||||||
while ( ( c = Extra_UtilGetopt( argc, argv, "MKCDlsvh" ) ) != EOF )
|
while ( ( c = Extra_UtilGetopt( argc, argv, "MKCDaflsvh" ) ) != EOF )
|
||||||
{
|
{
|
||||||
switch ( c )
|
switch ( c )
|
||||||
{
|
{
|
||||||
|
|
@ -7443,6 +7451,12 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
if ( pPars->DelayTarget <= 0.0 )
|
if ( pPars->DelayTarget <= 0.0 )
|
||||||
goto usage;
|
goto usage;
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
pPars->fArea ^= 1;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
pPars->fFancy ^= 1;
|
||||||
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
pPars->fLatchPaths ^= 1;
|
pPars->fLatchPaths ^= 1;
|
||||||
break;
|
break;
|
||||||
|
|
@ -7467,7 +7481,13 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
if ( pPars->Mode < 0 || pPars->Mode > 4 )
|
if ( pPars->Mode < 0 || pPars->Mode > 4 )
|
||||||
{
|
{
|
||||||
fprintf( pErr, "Incorrect mapping mode.\n" );
|
fprintf( pErr, "Incorrect mapping mode.\n" );
|
||||||
return 1;
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pPars->nCutsMax < 2 || pPars->nCutsMax >= (1<<12) )
|
||||||
|
{
|
||||||
|
fprintf( pErr, "Incorrect number of cuts.\n" );
|
||||||
|
goto usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the latch paths
|
// set the latch paths
|
||||||
|
|
@ -7527,7 +7547,7 @@ usage:
|
||||||
sprintf( LutSize, "library" );
|
sprintf( LutSize, "library" );
|
||||||
else
|
else
|
||||||
sprintf( LutSize, "%d", pPars->nLutSize );
|
sprintf( LutSize, "%d", pPars->nLutSize );
|
||||||
fprintf( pErr, "usage: if [-M num] [-K num] [-C num] [-D float] [-lsvh]\n" );
|
fprintf( pErr, "usage: if [-M num] [-K num] [-C num] [-D float] [-aflsvh]\n" );
|
||||||
fprintf( pErr, "\t performs FPGA mapping of the network as follows:\n" );
|
fprintf( pErr, "\t performs FPGA mapping of the network as follows:\n" );
|
||||||
fprintf( pErr, "\t 1 - delay only\n" );
|
fprintf( pErr, "\t 1 - delay only\n" );
|
||||||
fprintf( pErr, "\t 2 - area only\n" );
|
fprintf( pErr, "\t 2 - area only\n" );
|
||||||
|
|
@ -7537,6 +7557,8 @@ usage:
|
||||||
fprintf( pErr, "\t-K num : the number of LUT inputs (2 < num < 32) [default = %s]\n", LutSize );
|
fprintf( pErr, "\t-K num : the number of LUT inputs (2 < num < 32) [default = %s]\n", LutSize );
|
||||||
fprintf( pErr, "\t-C num : the max number of cuts to use (1 < num < 2^12) [default = %d]\n", pPars->nCutsMax );
|
fprintf( pErr, "\t-C num : the max number of cuts to use (1 < num < 2^12) [default = %d]\n", pPars->nCutsMax );
|
||||||
fprintf( pErr, "\t-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer );
|
fprintf( pErr, "\t-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer );
|
||||||
|
fprintf( pErr, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" );
|
||||||
|
fprintf( pErr, "\t-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" );
|
||||||
fprintf( pErr, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", pPars->fLatchPaths? "yes": "no" );
|
fprintf( pErr, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", pPars->fLatchPaths? "yes": "no" );
|
||||||
fprintf( pErr, "\t-s : toggles sequential mapping [default = %s]\n", pPars->fSeq? "yes": "no" );
|
fprintf( pErr, "\t-s : toggles sequential mapping [default = %s]\n", pPars->fSeq? "yes": "no" );
|
||||||
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ static If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
|
||||||
static Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk );
|
static Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk );
|
||||||
static Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t * pIfObj );
|
static Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t * pIfObj );
|
||||||
static Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Cut_t * pCut );
|
static Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Cut_t * pCut );
|
||||||
|
static Hop_Obj_t * Abc_NodeIfToHop2( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj );
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// FUNCTION DEFINITIONS ///
|
/// FUNCTION DEFINITIONS ///
|
||||||
|
|
@ -56,6 +57,10 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
|
||||||
if ( Abc_NtkGetChoiceNum( pNtk ) )
|
if ( Abc_NtkGetChoiceNum( pNtk ) )
|
||||||
printf( "Performing FPGA mapping with choices.\n" );
|
printf( "Performing FPGA mapping with choices.\n" );
|
||||||
|
|
||||||
|
// get timing information
|
||||||
|
pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk);
|
||||||
|
pPars->pTimesReq = NULL;
|
||||||
|
|
||||||
// perform FPGA mapping
|
// perform FPGA mapping
|
||||||
pIfMan = Abc_NtkToIf( pNtk, pPars );
|
pIfMan = Abc_NtkToIf( pNtk, pPars );
|
||||||
if ( pIfMan == NULL )
|
if ( pIfMan == NULL )
|
||||||
|
|
@ -115,7 +120,7 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
|
||||||
pNode->pCopy = (Abc_Obj_t *)If_ManCreatePi( pIfMan );
|
pNode->pCopy = (Abc_Obj_t *)If_ManCreatePi( pIfMan );
|
||||||
|
|
||||||
// load the AIG into the mapper
|
// load the AIG into the mapper
|
||||||
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
|
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
|
||||||
Abc_AigForEachAnd( pNtk, pNode, i )
|
Abc_AigForEachAnd( pNtk, pNode, i )
|
||||||
{
|
{
|
||||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||||
|
|
@ -212,7 +217,8 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
|
||||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
|
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
|
||||||
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf) );
|
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf) );
|
||||||
// derive the function of this node
|
// derive the function of this node
|
||||||
pNodeNew->pData = Abc_NodeIfToHop( pNtkNew->pManFunc, pIfMan, pCutBest );
|
// pNodeNew->pData = Abc_NodeIfToHop( pNtkNew->pManFunc, pIfMan, pCutBest );
|
||||||
|
pNodeNew->pData = Abc_NodeIfToHop2( pNtkNew->pManFunc, pIfMan, pIfObj );
|
||||||
If_ObjSetCopy( pIfObj, pNodeNew );
|
If_ObjSetCopy( pIfObj, pNodeNew );
|
||||||
return pNodeNew;
|
return pNodeNew;
|
||||||
}
|
}
|
||||||
|
|
@ -280,6 +286,76 @@ Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Cut_t *
|
||||||
return gFunc;
|
return gFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Recursively derives the truth table for the cut.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
Hop_Obj_t * Abc_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited )
|
||||||
|
{
|
||||||
|
If_Cut_t * pCut;
|
||||||
|
Hop_Obj_t * gFunc, * gFunc0, * gFunc1;
|
||||||
|
// get the best cut
|
||||||
|
pCut = If_ObjCutTriv(pIfObj);
|
||||||
|
// if the cut is visited, return the result
|
||||||
|
if ( If_CutData(pCut) )
|
||||||
|
return If_CutData(pCut);
|
||||||
|
// compute the functions of the children
|
||||||
|
gFunc0 = Abc_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj->pFanin0, vVisited );
|
||||||
|
gFunc1 = Abc_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj->pFanin1, vVisited );
|
||||||
|
// get the function of the cut
|
||||||
|
gFunc = Hop_And( pHopMan, Hop_NotCond(gFunc0, pIfObj->fCompl0), Hop_NotCond(gFunc1, pIfObj->fCompl1) );
|
||||||
|
gFunc = Hop_NotCond( gFunc, pCut->Phase );
|
||||||
|
assert( If_CutData(pCut) == NULL );
|
||||||
|
If_CutSetData( pCut, gFunc );
|
||||||
|
// add this cut to the visited list
|
||||||
|
Vec_PtrPush( vVisited, pCut );
|
||||||
|
return gFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Derives the truth table for one cut.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
Hop_Obj_t * Abc_NodeIfToHop2( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj )
|
||||||
|
{
|
||||||
|
If_Cut_t * pCut;
|
||||||
|
Hop_Obj_t * gFunc;
|
||||||
|
If_Obj_t * pLeaf;
|
||||||
|
int i;
|
||||||
|
// get the best cut
|
||||||
|
pCut = If_ObjCutBest(pIfObj);
|
||||||
|
assert( pCut->nLeaves > 1 );
|
||||||
|
// set the leaf variables
|
||||||
|
If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
|
||||||
|
If_CutSetData( If_ObjCutTriv(pLeaf), Hop_IthVar(pHopMan, i) );
|
||||||
|
// recursively compute the function while collecting visited cuts
|
||||||
|
Vec_PtrClear( pIfMan->vTemp );
|
||||||
|
gFunc = Abc_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp );
|
||||||
|
// printf( "%d ", Vec_PtrSize(p->vTemp) );
|
||||||
|
// clean the cuts
|
||||||
|
If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
|
||||||
|
If_CutSetData( If_ObjCutTriv(pLeaf), NULL );
|
||||||
|
Vec_PtrForEachEntry( pIfMan->vTemp, pCut, i )
|
||||||
|
If_CutSetData( pCut, NULL );
|
||||||
|
return gFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// END OF FILE ///
|
/// END OF FILE ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -269,15 +269,16 @@ DdManager * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDrop
|
||||||
pObj = Abc_AigConst1(pNtk);
|
pObj = Abc_AigConst1(pNtk);
|
||||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||||
{
|
{
|
||||||
Abc_ObjSetGlobalBdd( pObj, dd->one );
|
bFunc = dd->one;
|
||||||
Cudd_Ref( dd->one );
|
Abc_ObjSetGlobalBdd( pObj, bFunc ); Cudd_Ref( bFunc );
|
||||||
}
|
}
|
||||||
// set the elementary variables
|
// set the elementary variables
|
||||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||||
{
|
{
|
||||||
Abc_ObjSetGlobalBdd( pObj, dd->vars[i] );
|
bFunc = dd->vars[i];
|
||||||
Cudd_Ref( dd->vars[i] );
|
// bFunc = dd->vars[Abc_NtkCiNum(pNtk) - 1 - i];
|
||||||
|
Abc_ObjSetGlobalBdd( pObj, bFunc ); Cudd_Ref( bFunc );
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect the global functions of the COs
|
// collect the global functions of the COs
|
||||||
|
|
@ -460,6 +461,31 @@ DdManager * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan )
|
||||||
return Abc_NtkAttrFree( pNtk, VEC_ATTR_GLOBAL_BDD, fFreeMan );
|
return Abc_NtkAttrFree( pNtk, VEC_ATTR_GLOBAL_BDD, fFreeMan );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Returns the shared size of global BDDs of the COs.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk )
|
||||||
|
{
|
||||||
|
Vec_Ptr_t * vFuncsGlob;
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
int RetValue, i;
|
||||||
|
// complement the global functions
|
||||||
|
vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
|
||||||
|
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||||
|
Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) );
|
||||||
|
RetValue = Cudd_SharingSize( (DdNode **)Vec_PtrArray(vFuncsGlob), Vec_PtrSize(vFuncsGlob) );
|
||||||
|
Vec_PtrFree( vFuncsGlob );
|
||||||
|
return RetValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Computes the BDD of the logic cone of the node.]
|
Synopsis [Computes the BDD of the logic cone of the node.]
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
/// DECLARATIONS ///
|
/// DECLARATIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose );
|
static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int fVerbose );
|
||||||
static void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose );
|
static void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose );
|
||||||
static void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose );
|
static void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose );
|
||||||
static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms );
|
static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms );
|
||||||
|
|
@ -44,10 +44,10 @@ static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms )
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose )
|
void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fReorder, int fVerbose )
|
||||||
{
|
{
|
||||||
if ( fUseBdds )
|
if ( fUseBdds || fNaive )
|
||||||
Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fVerbose );
|
Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fReorder, fVerbose );
|
||||||
else
|
else
|
||||||
Abc_NtkSymmetriesUsingSandS( pNtk, fVerbose );
|
Abc_NtkSymmetriesUsingSandS( pNtk, fVerbose );
|
||||||
}
|
}
|
||||||
|
|
@ -81,15 +81,19 @@ void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose )
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose )
|
void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int fVerbose )
|
||||||
{
|
{
|
||||||
DdManager * dd;
|
DdManager * dd;
|
||||||
int clk, clkBdd, clkSym;
|
int clk, clkBdd, clkSym;
|
||||||
|
int fGarbCollect = 1;
|
||||||
|
|
||||||
// compute the global functions
|
// compute the global functions
|
||||||
clk = clock();
|
clk = clock();
|
||||||
dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose );
|
dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, fVerbose );
|
||||||
|
printf( "Shared BDD size = %d nodes.\n", Abc_NtkSizeOfGlobalBdds(pNtk) );
|
||||||
Cudd_AutodynDisable( dd );
|
Cudd_AutodynDisable( dd );
|
||||||
|
if ( !fGarbCollect )
|
||||||
|
Cudd_DisableGarbageCollection( dd );
|
||||||
Cudd_zddVarsFromBddVars( dd, 2 );
|
Cudd_zddVarsFromBddVars( dd, 2 );
|
||||||
clkBdd = clock() - clk;
|
clkBdd = clock() - clk;
|
||||||
// create the collapsed network
|
// create the collapsed network
|
||||||
|
|
@ -97,11 +101,10 @@ clk = clock();
|
||||||
Ntk_NetworkSymmsBdd( dd, pNtk, fNaive, fVerbose );
|
Ntk_NetworkSymmsBdd( dd, pNtk, fNaive, fVerbose );
|
||||||
clkSym = clock() - clk;
|
clkSym = clock() - clk;
|
||||||
// undo the global functions
|
// undo the global functions
|
||||||
// Abc_NtkFreeGlobalBdds( pNtk );
|
|
||||||
// Extra_StopManager( dd );
|
|
||||||
// pNtk->pManGlob = NULL;
|
|
||||||
Abc_NtkFreeGlobalBdds( pNtk, 1 );
|
Abc_NtkFreeGlobalBdds( pNtk, 1 );
|
||||||
|
printf( "Statistics of BDD-based symmetry detection:\n" );
|
||||||
|
printf( "Algorithm = %s. Reordering = %s. Garbage collection = %s.\n",
|
||||||
|
fNaive? "naive" : "fast", fReorder? "yes" : "no", fGarbCollect? "yes" : "no" );
|
||||||
PRT( "Constructing BDDs", clkBdd );
|
PRT( "Constructing BDDs", clkBdd );
|
||||||
PRT( "Computing symms ", clkSym );
|
PRT( "Computing symms ", clkSym );
|
||||||
PRT( "TOTAL ", clkBdd + clkSym );
|
PRT( "TOTAL ", clkBdd + clkSym );
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,8 @@ 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,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,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,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,1,1,1}, {0,1,1,1} };
|
||||||
|
|
||||||
Abc_FrameSetLibLut( Fpga_LutLibDup(&s_LutLib) );
|
Abc_FrameSetLibLut( Fpga_LutLibDup(&s_LutLib) );
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,12 @@ int Fpga_Mapping( Fpga_Man_t * p )
|
||||||
|
|
||||||
// print the AI-graph used for mapping
|
// print the AI-graph used for mapping
|
||||||
//Fpga_ManShow( p, "test" );
|
//Fpga_ManShow( p, "test" );
|
||||||
|
// if ( p->fVerbose )
|
||||||
|
// Fpga_MappingPrintOutputArrivals( p );
|
||||||
if ( p->fVerbose )
|
if ( p->fVerbose )
|
||||||
Fpga_MappingPrintOutputArrivals( p );
|
{
|
||||||
|
PRT( "Total time", clock() - clkTotal );
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,14 +105,14 @@ int Fpga_Mapping( Fpga_Man_t * p )
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
int Fpga_MappingPostProcess( Fpga_Man_t * p )
|
int Fpga_MappingPostProcess( Fpga_Man_t * p )
|
||||||
{
|
{
|
||||||
int fShowSwitching = 1;
|
int fShowSwitching = 0;
|
||||||
int fRecoverAreaFlow = 1;
|
int fRecoverAreaFlow = 1;
|
||||||
int fRecoverArea = 1;
|
int fRecoverArea = 1;
|
||||||
float aAreaTotalCur, aAreaTotalCur2;
|
float aAreaTotalCur, aAreaTotalCur2;
|
||||||
int Iter, clk;
|
int Iter, clk;
|
||||||
|
|
||||||
if ( p->fVerbose )
|
//if ( p->fVerbose )
|
||||||
printf( "Best clock period = %5.2f\n", Fpga_TimeComputeArrivalMax(p) );
|
// printf( "Best clock period = %5.2f\n", Fpga_TimeComputeArrivalMax(p) );
|
||||||
|
|
||||||
// compute area, set references, and collect nodes used in the mapping
|
// compute area, set references, and collect nodes used in the mapping
|
||||||
Iter = 1;
|
Iter = 1;
|
||||||
|
|
@ -118,6 +122,9 @@ if ( p->fVerbose )
|
||||||
printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur );
|
printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur );
|
||||||
if ( fShowSwitching )
|
if ( fShowSwitching )
|
||||||
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
|
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
|
||||||
|
else
|
||||||
|
printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) );
|
||||||
|
|
||||||
PRT( "Time", p->timeMatch );
|
PRT( "Time", p->timeMatch );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,6 +148,8 @@ if ( p->fVerbose )
|
||||||
printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur );
|
printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur );
|
||||||
if ( fShowSwitching )
|
if ( fShowSwitching )
|
||||||
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
|
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
|
||||||
|
else
|
||||||
|
printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) );
|
||||||
PRT( "Time", clock() - clk );
|
PRT( "Time", clock() - clk );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +175,8 @@ if ( p->fVerbose )
|
||||||
printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->fSwitching?"S":"A"), aAreaTotalCur );
|
printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->fSwitching?"S":"A"), aAreaTotalCur );
|
||||||
if ( fShowSwitching )
|
if ( fShowSwitching )
|
||||||
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
|
printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
|
||||||
|
else
|
||||||
|
printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) );
|
||||||
PRT( "Time", clock() - clk );
|
PRT( "Time", clock() - clk );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ void Fpga_MappingCuts( Fpga_Man_t * p )
|
||||||
Fpga_CutTable_t * pTable;
|
Fpga_CutTable_t * pTable;
|
||||||
Fpga_Node_t * pNode;
|
Fpga_Node_t * pNode;
|
||||||
int nCuts, nNodes, i;
|
int nCuts, nNodes, i;
|
||||||
|
int clk = clock();
|
||||||
|
|
||||||
// set the elementary cuts for the PI variables
|
// set the elementary cuts for the PI variables
|
||||||
assert( p->nVarsMax > 1 && p->nVarsMax < 11 );
|
assert( p->nVarsMax > 1 && p->nVarsMax < 11 );
|
||||||
|
|
@ -154,8 +155,9 @@ void Fpga_MappingCuts( Fpga_Man_t * p )
|
||||||
if ( p->fVerbose )
|
if ( p->fVerbose )
|
||||||
{
|
{
|
||||||
nCuts = Fpga_CutCountAll(p);
|
nCuts = Fpga_CutCountAll(p);
|
||||||
printf( "Nodes = %6d. Total %d-feasible cuts = %d. Cuts per node = %.1f.\n",
|
printf( "Nodes = %6d. Total %d-cuts = %d. Cuts 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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// print the cuts for the first primary output
|
// print the cuts for the first primary output
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,18 @@ int Fpga_MappingMatches( Fpga_Man_t * p, int fDelayOriented )
|
||||||
Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
|
Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
|
||||||
}
|
}
|
||||||
Extra_ProgressBarStop( pProgress );
|
Extra_ProgressBarStop( pProgress );
|
||||||
|
/*
|
||||||
|
if ( !fDelayOriented )
|
||||||
|
{
|
||||||
|
float Area = 0.0;
|
||||||
|
for ( i = 0; i < p->nOutputs; i++ )
|
||||||
|
{
|
||||||
|
printf( "%5.2f ", Fpga_Regular(p->pOutputs[i])->pCutBest->aFlow );
|
||||||
|
Area += Fpga_Regular(p->pOutputs[i])->pCutBest->aFlow;
|
||||||
|
}
|
||||||
|
printf( "\nTotal = %5.2f\n", Area );
|
||||||
|
}
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,10 @@ struct If_Par_t_
|
||||||
If_Lib_t * pLutLib; // the LUT library
|
If_Lib_t * pLutLib; // the LUT library
|
||||||
int nCutsMax; // the max number of cuts
|
int nCutsMax; // the max number of cuts
|
||||||
int fVerbose; // the verbosity flag
|
int fVerbose; // the verbosity flag
|
||||||
int fSeq; // sequential mapping
|
int fArea; // area-oriented mapping
|
||||||
|
int fFancy; // a fancy feature
|
||||||
int fLatchPaths; // reset timing on latch paths
|
int fLatchPaths; // reset timing on latch paths
|
||||||
|
int fSeq; // sequential mapping
|
||||||
int nLatches; // the number of latches
|
int nLatches; // the number of latches
|
||||||
float DelayTarget; // delay target
|
float DelayTarget; // delay target
|
||||||
float * pTimesArr; // arrival times
|
float * pTimesArr; // arrival times
|
||||||
|
|
@ -110,6 +112,9 @@ struct If_Man_t_
|
||||||
float fEpsilon; // epsilon used for comparison
|
float fEpsilon; // epsilon used for comparison
|
||||||
float RequiredGlo; // global required times
|
float RequiredGlo; // global required times
|
||||||
float AreaGlo; // global area
|
float AreaGlo; // global area
|
||||||
|
int nCutsUsed; // the number of cuts currently used
|
||||||
|
int nCutsMerged; // the total number of cuts merged
|
||||||
|
int nCutsMax; // the maximum number of cuts at a node
|
||||||
// memory management
|
// memory management
|
||||||
Mem_Fixed_t * pMem; // memory manager
|
Mem_Fixed_t * pMem; // memory manager
|
||||||
int nEntrySize; // the size of the entry
|
int nEntrySize; // the size of the entry
|
||||||
|
|
@ -123,7 +128,6 @@ struct If_Man_t_
|
||||||
struct If_Cut_t_
|
struct If_Cut_t_
|
||||||
{
|
{
|
||||||
float Delay; // the delay of the cut
|
float Delay; // the delay of the cut
|
||||||
float Flow; // the area flow of the cut
|
|
||||||
float Area; // the area of the cut
|
float Area; // the area of the cut
|
||||||
If_Cut_t * pOne; // the parent cut
|
If_Cut_t * pOne; // the parent cut
|
||||||
If_Cut_t * pTwo; // the parent cut
|
If_Cut_t * pTwo; // the parent cut
|
||||||
|
|
@ -162,6 +166,10 @@ static inline If_Obj_t * If_ManPo( If_Man_t * p, int i ) { r
|
||||||
static inline If_Obj_t * If_ManObj( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vObjs, i ); }
|
static inline If_Obj_t * If_ManObj( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vObjs, i ); }
|
||||||
static inline If_Cut_t * If_ManCut( If_Man_t * p, int i ) { return p->ppCuts[i]; }
|
static inline If_Cut_t * If_ManCut( If_Man_t * p, int i ) { return p->ppCuts[i]; }
|
||||||
|
|
||||||
|
static inline int If_ManPiNum( If_Man_t * p ) { return p->nObjs[IF_PI]; }
|
||||||
|
static inline int If_ManPoNum( If_Man_t * p ) { return p->nObjs[IF_PO]; }
|
||||||
|
static inline int If_ManAndNum( If_Man_t * p ) { return p->nObjs[IF_AND]; }
|
||||||
|
|
||||||
static inline int If_ObjIsConst1( If_Obj_t * pObj ) { return pObj->Type == IF_CONST1; }
|
static inline int If_ObjIsConst1( If_Obj_t * pObj ) { return pObj->Type == IF_CONST1; }
|
||||||
static inline int If_ObjIsPi( If_Obj_t * pObj ) { return pObj->Type == IF_PI; }
|
static inline int If_ObjIsPi( If_Obj_t * pObj ) { return pObj->Type == IF_PI; }
|
||||||
static inline int If_ObjIsPo( If_Obj_t * pObj ) { return pObj->Type == IF_PO; }
|
static inline int If_ObjIsPo( If_Obj_t * pObj ) { return pObj->Type == IF_PO; }
|
||||||
|
|
@ -229,6 +237,8 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r
|
||||||
/// FUNCTION DECLARATIONS ///
|
/// FUNCTION DECLARATIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*=== ifCore.c ==========================================================*/
|
||||||
|
extern int If_ManPerformMapping( If_Man_t * p );
|
||||||
/*=== ifMan.c ==========================================================*/
|
/*=== ifMan.c ==========================================================*/
|
||||||
extern If_Man_t * If_ManStart( If_Par_t * pPars );
|
extern If_Man_t * If_ManStart( If_Par_t * pPars );
|
||||||
extern void If_ManStop( If_Man_t * p );
|
extern void If_ManStop( If_Man_t * p );
|
||||||
|
|
@ -236,11 +246,12 @@ extern If_Obj_t * If_ManCreatePi( If_Man_t * p );
|
||||||
extern If_Obj_t * If_ManCreatePo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 );
|
extern If_Obj_t * If_ManCreatePo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 );
|
||||||
extern If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_t * pFan1, int fCompl1 );
|
extern If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_t * pFan1, int fCompl1 );
|
||||||
/*=== ifMap.c ==========================================================*/
|
/*=== ifMap.c ==========================================================*/
|
||||||
extern int If_ManPerformMapping( If_Man_t * p );
|
extern void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode );
|
||||||
/*=== ifUtil.c ==========================================================*/
|
/*=== ifUtil.c ==========================================================*/
|
||||||
extern float If_ManDelayMax( If_Man_t * p );
|
extern float If_ManDelayMax( If_Man_t * p );
|
||||||
extern void If_ManCleanNodeCopy( If_Man_t * p );
|
extern void If_ManCleanNodeCopy( If_Man_t * p );
|
||||||
extern void If_ManCleanCutData( If_Man_t * p );
|
extern void If_ManCleanCutData( If_Man_t * p );
|
||||||
|
extern void If_ManComputeRequired( If_Man_t * p, int fFirstTime );
|
||||||
extern float If_ManScanMapping( If_Man_t * p );
|
extern float If_ManScanMapping( If_Man_t * p );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
/// DECLARATIONS ///
|
/// DECLARATIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode );
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// FUNCTION DEFINITIONS ///
|
/// FUNCTION DEFINITIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -39,6 +41,72 @@
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
int If_ManPerformMapping( If_Man_t * p )
|
||||||
|
{
|
||||||
|
If_Obj_t * pObj;
|
||||||
|
int nItersFlow = 2;
|
||||||
|
int nItersArea = 1;
|
||||||
|
int clkTotal = clock();
|
||||||
|
int i;
|
||||||
|
// set arrival times and trivial cuts at const 1 and PIs
|
||||||
|
If_ManConst1(p)->Cuts[0].Delay = 0.0;
|
||||||
|
If_ManForEachPi( p, pObj, i )
|
||||||
|
pObj->Cuts[0].Delay = p->pPars->pTimesArr[i];
|
||||||
|
// set the fanout estimates of the PIs
|
||||||
|
If_ManForEachPi( p, pObj, i )
|
||||||
|
pObj->EstRefs = (float)1.0;
|
||||||
|
// delay oriented mapping
|
||||||
|
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0 );
|
||||||
|
// area flow oriented mapping
|
||||||
|
for ( i = 0; i < nItersFlow; i++ )
|
||||||
|
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 1 );
|
||||||
|
// area oriented mapping
|
||||||
|
for ( i = 0; i < nItersArea; i++ )
|
||||||
|
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 2 );
|
||||||
|
if ( p->pPars->fVerbose )
|
||||||
|
{
|
||||||
|
PRT( "Total time", clock() - clkTotal );
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode )
|
||||||
|
{
|
||||||
|
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_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 ///
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ void If_ManStop( If_Man_t * p )
|
||||||
FREE( p->pPars->pTimesReq );
|
FREE( p->pPars->pTimesReq );
|
||||||
// free temporary cut memory
|
// free temporary cut memory
|
||||||
pTemp = p->ppCuts[0];
|
pTemp = p->ppCuts[0];
|
||||||
for ( i = 1; i < p->pPars->nCutsMax * p->pPars->nCutsMax; i++ )
|
for ( i = 1; i < 1 + p->pPars->nCutsMax * p->pPars->nCutsMax; i++ )
|
||||||
if ( pTemp > p->ppCuts[i] )
|
if ( pTemp > p->ppCuts[i] )
|
||||||
pTemp = p->ppCuts[i];
|
pTemp = p->ppCuts[i];
|
||||||
free( pTemp );
|
free( pTemp );
|
||||||
|
|
@ -228,14 +228,18 @@ If_Cut_t ** If_ManSetupCuts( If_Man_t * p )
|
||||||
{
|
{
|
||||||
If_Cut_t ** pCutStore;
|
If_Cut_t ** pCutStore;
|
||||||
int * pArrays, nCutSize, nCutsTotal, i;
|
int * pArrays, nCutSize, nCutsTotal, i;
|
||||||
nCutsTotal = p->pPars->nCutsMax * p->pPars->nCutsMax;
|
// decide how many cuts to alloc
|
||||||
|
nCutsTotal = 1 + p->pPars->nCutsMax * p->pPars->nCutsMax;
|
||||||
|
// figure out the cut size
|
||||||
nCutSize = sizeof(If_Cut_t) + sizeof(int) * p->pPars->nLutSize;
|
nCutSize = sizeof(If_Cut_t) + sizeof(int) * p->pPars->nLutSize;
|
||||||
|
// allocate and clean space for cuts
|
||||||
pCutStore = (If_Cut_t **)ALLOC( If_Cut_t *, (nCutsTotal + 1) );
|
pCutStore = (If_Cut_t **)ALLOC( If_Cut_t *, (nCutsTotal + 1) );
|
||||||
memset( pCutStore, 0, sizeof(If_Cut_t *) * (nCutsTotal + 1) );
|
memset( pCutStore, 0, sizeof(If_Cut_t *) * (nCutsTotal + 1) );
|
||||||
pCutStore[0] = (If_Cut_t *)ALLOC( char, nCutSize * nCutsTotal );
|
pCutStore[0] = (If_Cut_t *)ALLOC( char, nCutSize * nCutsTotal );
|
||||||
memset( pCutStore[0], 0, nCutSize * nCutsTotal );
|
memset( pCutStore[0], 0, nCutSize * nCutsTotal );
|
||||||
for ( i = 1; i < nCutsTotal; i++ )
|
for ( i = 1; i < nCutsTotal; i++ )
|
||||||
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);
|
||||||
|
// assign room for cut leaves
|
||||||
pArrays = (int *)((char *)pCutStore[0] + sizeof(If_Cut_t) * nCutsTotal);
|
pArrays = (int *)((char *)pCutStore[0] + sizeof(If_Cut_t) * nCutsTotal);
|
||||||
for ( i = 0; i < nCutsTotal; i++ )
|
for ( i = 0; i < nCutsTotal; i++ )
|
||||||
pCutStore[i]->pLeaves = pArrays + i * p->pPars->nLutSize;
|
pCutStore[i]->pLeaves = pArrays + i * p->pPars->nLutSize;
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,97 @@
|
||||||
/// DECLARATIONS ///
|
/// DECLARATIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ideas to try:
|
||||||
|
- reverse order of area recovery
|
||||||
|
- ordering of the outputs by size
|
||||||
|
- merging Delay, Delay2, and Area
|
||||||
|
- expand/reduce area recovery
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// FUNCTION DEFINITIONS ///
|
/// FUNCTION DEFINITIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Returns 1 if pDom is contained in pCut.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
int i, k;
|
||||||
|
for ( i = 0; i < (int)pDom->nLeaves; i++ )
|
||||||
|
{
|
||||||
|
for ( k = 0; k < (int)pCut->nLeaves; k++ )
|
||||||
|
if ( pDom->pLeaves[i] == pCut->pLeaves[k] )
|
||||||
|
break;
|
||||||
|
if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// every node in pDom is contained in pCut
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Returns 1 if pDom is equal to pCut.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static inline int If_CutCheckEquality( If_Cut_t * pDom, If_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if ( (int)pDom->nLeaves != (int)pCut->nLeaves )
|
||||||
|
return 0;
|
||||||
|
for ( i = 0; i < (int)pDom->nLeaves; i++ )
|
||||||
|
if ( pDom->pLeaves[i] != pCut->pLeaves[i] )
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Returns 1 if the cut is contained.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int If_CutFilter( If_Man_t * p, If_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
If_Cut_t * pTemp;
|
||||||
|
int i;
|
||||||
|
for ( i = 0; i < p->nCuts; i++ )
|
||||||
|
{
|
||||||
|
pTemp = p->ppCuts[i];
|
||||||
|
if ( pTemp->nLeaves > pCut->nLeaves )
|
||||||
|
continue;
|
||||||
|
// skip the non-contained cuts
|
||||||
|
// if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign )
|
||||||
|
// continue;
|
||||||
|
// check containment seriously
|
||||||
|
if ( If_CutCheckDominance( pTemp, pCut ) )
|
||||||
|
// if ( If_CutCheckEquality( pTemp, pCut ) )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Prepares the object for FPGA mapping.]
|
Synopsis [Prepares the object for FPGA mapping.]
|
||||||
|
|
@ -39,7 +126,7 @@
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
int If_CutMerge( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit )
|
int If_CutMergeOrdered( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit )
|
||||||
{
|
{
|
||||||
int i, k, c;
|
int i, k, c;
|
||||||
assert( pC0->nLeaves >= pC1->nLeaves );
|
assert( pC0->nLeaves >= pC1->nLeaves );
|
||||||
|
|
@ -114,6 +201,33 @@ int If_CutMerge( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Prepares the object for FPGA mapping.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static inline int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut, int nLimit )
|
||||||
|
{
|
||||||
|
// merge the nodes
|
||||||
|
if ( pCut0->nLeaves < pCut1->nLeaves )
|
||||||
|
{
|
||||||
|
if ( !If_CutMergeOrdered( pCut1, pCut0, pCut, nLimit ) )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !If_CutMergeOrdered( pCut0, pCut1, pCut, nLimit ) )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Prepares the object for FPGA mapping.]
|
Synopsis [Prepares the object for FPGA mapping.]
|
||||||
|
|
@ -137,9 +251,39 @@ int If_CutCompareDelay( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
|
||||||
return -1;
|
return -1;
|
||||||
if ( pC0->nLeaves > pC1->nLeaves )
|
if ( pC0->nLeaves > pC1->nLeaves )
|
||||||
return 1;
|
return 1;
|
||||||
if ( pC0->Flow < pC1->Flow )
|
if ( pC0->Area < pC1->Area )
|
||||||
return -1;
|
return -1;
|
||||||
if ( pC0->Flow > pC1->Flow )
|
if ( pC0->Area > pC1->Area )
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Prepares the object for FPGA mapping.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int If_CutCompareDelayOld( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
|
||||||
|
{
|
||||||
|
If_Cut_t * pC0 = *ppC0;
|
||||||
|
If_Cut_t * pC1 = *ppC1;
|
||||||
|
if ( pC0->Delay < pC1->Delay )
|
||||||
|
return -1;
|
||||||
|
if ( pC0->Delay > pC1->Delay )
|
||||||
|
return 1;
|
||||||
|
if ( pC0->Area < pC1->Area )
|
||||||
|
return -1;
|
||||||
|
if ( pC0->Area > pC1->Area )
|
||||||
|
return 1;
|
||||||
|
if ( pC0->nLeaves < pC1->nLeaves )
|
||||||
|
return -1;
|
||||||
|
if ( pC0->nLeaves > pC1->nLeaves )
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -159,9 +303,9 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
|
||||||
{
|
{
|
||||||
If_Cut_t * pC0 = *ppC0;
|
If_Cut_t * pC0 = *ppC0;
|
||||||
If_Cut_t * pC1 = *ppC1;
|
If_Cut_t * pC1 = *ppC1;
|
||||||
if ( pC0->Flow < pC1->Flow )
|
if ( pC0->Area < pC1->Area )
|
||||||
return -1;
|
return -1;
|
||||||
if ( pC0->Flow > pC1->Flow )
|
if ( pC0->Area > pC1->Area )
|
||||||
return 1;
|
return 1;
|
||||||
if ( pC0->nLeaves < pC1->nLeaves )
|
if ( pC0->nLeaves < pC1->nLeaves )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -174,6 +318,28 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Sorts the cuts.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void If_ManSortCuts( If_Man_t * p, int Mode )
|
||||||
|
{
|
||||||
|
// sort the cuts
|
||||||
|
if ( Mode || p->pPars->fArea ) // area
|
||||||
|
qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea );
|
||||||
|
else if ( p->pPars->fFancy )
|
||||||
|
qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelayOld );
|
||||||
|
else
|
||||||
|
qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay );
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Computes delay.]
|
Synopsis [Computes delay.]
|
||||||
|
|
@ -190,6 +356,7 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
|
||||||
If_Obj_t * pLeaf;
|
If_Obj_t * pLeaf;
|
||||||
float Delay;
|
float Delay;
|
||||||
int i;
|
int i;
|
||||||
|
assert( pCut->nLeaves > 1 );
|
||||||
Delay = -IF_FLOAT_LARGE;
|
Delay = -IF_FLOAT_LARGE;
|
||||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||||
Delay = IF_MAX( Delay, If_ObjCutBest(pLeaf)->Delay );
|
Delay = IF_MAX( Delay, If_ObjCutBest(pLeaf)->Delay );
|
||||||
|
|
@ -212,9 +379,18 @@ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut )
|
||||||
If_Obj_t * pLeaf;
|
If_Obj_t * pLeaf;
|
||||||
float Flow;
|
float Flow;
|
||||||
int i;
|
int i;
|
||||||
|
assert( pCut->nLeaves > 1 );
|
||||||
Flow = If_CutLutArea(p, pCut);
|
Flow = If_CutLutArea(p, pCut);
|
||||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||||
Flow += If_ObjCutBest(pLeaf)->Flow / pLeaf->EstRefs;
|
{
|
||||||
|
if ( pLeaf->nRefs == 0 )
|
||||||
|
Flow += If_ObjCutBest(pLeaf)->Area;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert( pLeaf->EstRefs > p->fEpsilon );
|
||||||
|
Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs;
|
||||||
|
}
|
||||||
|
}
|
||||||
return Flow;
|
return Flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,15 +405,19 @@ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut )
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
float If_CutArea1( If_Man_t * p, If_Cut_t * pCut )
|
float If_CutRef( If_Man_t * p, If_Cut_t * pCut, int nLevels )
|
||||||
{
|
{
|
||||||
If_Obj_t * pLeaf;
|
If_Obj_t * pLeaf;
|
||||||
float Area;
|
float Area;
|
||||||
int i;
|
int i;
|
||||||
Area = If_CutLutArea(p, pCut);
|
Area = If_CutLutArea(p, pCut);
|
||||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||||
if ( pLeaf->nRefs == 0 )
|
{
|
||||||
Area += If_CutLutArea(p, If_ObjCutBest(pLeaf));
|
assert( pLeaf->nRefs >= 0 );
|
||||||
|
if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 )
|
||||||
|
continue;
|
||||||
|
Area += If_CutRef( p, If_ObjCutBest(pLeaf), nLevels - 1 );
|
||||||
|
}
|
||||||
return Area;
|
return Area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,12 +432,20 @@ float If_CutArea1( If_Man_t * p, If_Cut_t * pCut )
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
void If_CutRef1( If_Man_t * p, If_Cut_t * pCut )
|
float If_CutDeref( If_Man_t * p, If_Cut_t * pCut, int nLevels )
|
||||||
{
|
{
|
||||||
If_Obj_t * pLeaf;
|
If_Obj_t * pLeaf;
|
||||||
|
float Area;
|
||||||
int i;
|
int i;
|
||||||
|
Area = If_CutLutArea(p, pCut);
|
||||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||||
pLeaf->nRefs++;
|
{
|
||||||
|
assert( pLeaf->nRefs > 0 );
|
||||||
|
if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 )
|
||||||
|
continue;
|
||||||
|
Area += If_CutDeref( p, If_ObjCutBest(pLeaf), nLevels - 1 );
|
||||||
|
}
|
||||||
|
return Area;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
@ -271,12 +459,14 @@ void If_CutRef1( If_Man_t * p, If_Cut_t * pCut )
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
void If_CutDeref1( If_Man_t * p, If_Cut_t * pCut )
|
float If_CutArea( If_Man_t * p, If_Cut_t * pCut, int nLevels )
|
||||||
{
|
{
|
||||||
If_Obj_t * pLeaf;
|
float aResult, aResult2;
|
||||||
int i;
|
assert( pCut->nLeaves > 1 );
|
||||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
aResult2 = If_CutRef( p, pCut, nLevels );
|
||||||
pLeaf->nRefs--;
|
aResult = If_CutDeref( p, pCut, nLevels );
|
||||||
|
assert( aResult == aResult2 );
|
||||||
|
return aResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
@ -303,85 +493,85 @@ void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
|
||||||
|
|
||||||
Synopsis [Finds the best cut.]
|
Synopsis [Finds the best cut.]
|
||||||
|
|
||||||
Description []
|
Description [Mapping modes: delay (0), area flow (1), area (2).]
|
||||||
|
|
||||||
SideEffects []
|
SideEffects []
|
||||||
|
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj )
|
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;
|
int i, k;
|
||||||
// create cross-product of the cuts
|
|
||||||
|
// prepare
|
||||||
|
if ( Mode == 0 )
|
||||||
|
pObj->EstRefs = (float)pObj->nRefs;
|
||||||
|
else if ( Mode == 1 )
|
||||||
|
pObj->EstRefs = (float)((2.0 * pObj->EstRefs + pObj->nRefs) / 3.0);
|
||||||
|
else if ( Mode == 2 && pObj->nRefs > 0 )
|
||||||
|
If_CutDeref( p, If_ObjCutBest(pObj), 100 );
|
||||||
|
|
||||||
|
// recompute the parameters of the best cut
|
||||||
p->nCuts = 0;
|
p->nCuts = 0;
|
||||||
pCut = p->ppCuts[0];
|
p->nCutsMerged++;
|
||||||
|
if ( Mode )
|
||||||
|
{
|
||||||
|
pCut = If_ObjCutBest(pObj);
|
||||||
|
pCut->Delay = If_CutDelay( p, pCut );
|
||||||
|
assert( pCut->Delay <= pObj->Required + p->fEpsilon );
|
||||||
|
pCut->Area = (Mode == 2)? If_CutArea( p, pCut, 100 ) : If_CutFlow( p, pCut );
|
||||||
|
// save the best cut from the previous iteration
|
||||||
|
If_CutCopy( p->ppCuts[p->nCuts++], pCut );
|
||||||
|
p->nCutsMerged++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate cuts
|
||||||
|
pCut = p->ppCuts[p->nCuts];
|
||||||
If_ObjForEachCut( pObj->pFanin0, pCut0, i )
|
If_ObjForEachCut( pObj->pFanin0, pCut0, i )
|
||||||
If_ObjForEachCut( pObj->pFanin1, pCut1, k )
|
If_ObjForEachCut( pObj->pFanin1, pCut1, k )
|
||||||
{
|
{
|
||||||
if ( pCut0->nLeaves < pCut1->nLeaves )
|
// prefilter using arrival times
|
||||||
{
|
if ( Mode && (pCut0->Delay > pObj->Required + p->fEpsilon || pCut1->Delay > pObj->Required + p->fEpsilon) )
|
||||||
if ( !If_CutMerge( pCut1, pCut0, pCut, p->pPars->nLutSize ) )
|
continue;
|
||||||
continue;
|
// merge the nodes
|
||||||
}
|
if ( !If_CutMerge( pCut0, pCut1, pCut, p->pPars->nLutSize ) )
|
||||||
else
|
continue;
|
||||||
{
|
// check if this cut is contained in any of the available cuts
|
||||||
if ( !If_CutMerge( pCut0, pCut1, pCut, p->pPars->nLutSize ) )
|
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
|
||||||
pCut->pOne = pCut0; pCut->fCompl0 = pObj->fCompl0;
|
pCut->pOne = pCut0; pCut->fCompl0 = pObj->fCompl0;
|
||||||
pCut->pTwo = pCut1; pCut->fCompl1 = pObj->fCompl1;
|
pCut->pTwo = pCut1; pCut->fCompl1 = pObj->fCompl1;
|
||||||
// pCut->Phase = ...
|
// pCut->Phase = ...
|
||||||
pCut->Delay = If_CutDelay( p, pCut );
|
pCut->Area = (Mode == 2)? If_CutArea( p, pCut, 100 ) : If_CutFlow( p, pCut );
|
||||||
pCut->Flow = If_CutFlow( p, pCut );
|
p->nCutsMerged++;
|
||||||
// prepare room for the next cut
|
// prepare room for the next cut
|
||||||
pCut = p->ppCuts[++p->nCuts];
|
pCut = p->ppCuts[++p->nCuts];
|
||||||
}
|
}
|
||||||
// sort the cuts
|
assert( p->nCuts > 0 );
|
||||||
if ( p->pPars->Mode == 1 ) // delay
|
If_ManSortCuts( p, Mode );
|
||||||
qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay );
|
|
||||||
else
|
|
||||||
qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea );
|
|
||||||
// take the first
|
// take the first
|
||||||
pObj->nCuts = IF_MIN( p->nCuts + 1, p->pPars->nCutsMax );
|
pObj->nCuts = IF_MIN( p->nCuts + 1, p->nCutsUsed );
|
||||||
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] );
|
||||||
pObj->iCut = 1;
|
pObj->iCut = 1;
|
||||||
}
|
assert( If_ObjCutBest(pObj)->nLeaves > 1 );
|
||||||
|
// assign delay of the trivial cut
|
||||||
/**Function*************************************************************
|
If_ObjCutTriv(pObj)->Delay = If_ObjCutBest(pObj)->Delay;
|
||||||
|
//printf( "%d %d ", pObj->Id, (int)If_ObjCutBest(pObj)->Delay );
|
||||||
Synopsis [Maps the nodes for delay.]
|
//printf( "%d %d ", pObj->Id, pObj->nCuts );
|
||||||
|
// ref the selected cut
|
||||||
Description []
|
if ( Mode == 2 && pObj->nRefs > 0 )
|
||||||
|
If_CutRef( p, If_ObjCutBest(pObj), 100 );
|
||||||
SideEffects []
|
// find the largest cut
|
||||||
|
if ( p->nCutsMax < pObj->nCuts )
|
||||||
SeeAlso []
|
p->nCutsMax = pObj->nCuts;
|
||||||
|
|
||||||
***********************************************************************/
|
|
||||||
int If_ManPerformMapping( If_Man_t * p )
|
|
||||||
{
|
|
||||||
If_Obj_t * pObj;
|
|
||||||
float DelayBest;
|
|
||||||
int i, clk = clock();
|
|
||||||
// set arrival times and trivial cuts at const 1 and PIs
|
|
||||||
If_ManConst1(p)->Cuts[0].Delay = 0.0;
|
|
||||||
If_ManForEachPi( p, pObj, i )
|
|
||||||
pObj->Cuts[0].Delay = p->pPars->pTimesArr[i];
|
|
||||||
// set the initial fanout estimates
|
|
||||||
If_ManForEachObj( p, pObj, i )
|
|
||||||
pObj->EstRefs = (float)pObj->nRefs;
|
|
||||||
// map the internal nodes
|
|
||||||
If_ManForEachNode( p, pObj, i )
|
|
||||||
If_ObjPerformMapping( p, pObj );
|
|
||||||
// get the best arrival time of the POs
|
|
||||||
DelayBest = If_ManDelayMax(p);
|
|
||||||
printf( "Best delay = %d. ", (int)DelayBest );
|
|
||||||
PRT( "Time", clock() - clk );
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -612,7 +612,8 @@ int Map_CutMergeTwo( Map_Cut_t * pCut1, Map_Cut_t * pCut2, Map_Node_t * ppNodes[
|
||||||
{
|
{
|
||||||
min = i;
|
min = i;
|
||||||
for ( k = i+1; k < nTotal; k++ )
|
for ( k = i+1; k < nTotal; k++ )
|
||||||
if ( ppNodes[k] < ppNodes[min] )
|
// if ( ppNodes[k] < ppNodes[min] ) // reported bug fix (non-determinism!)
|
||||||
|
if ( ppNodes[k]->Num < ppNodes[min]->Num )
|
||||||
min = k;
|
min = k;
|
||||||
pNodeTemp = ppNodes[i];
|
pNodeTemp = ppNodes[i];
|
||||||
ppNodes[i] = ppNodes[min];
|
ppNodes[i] = ppNodes[min];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue