mirror of https://github.com/YosysHQ/abc.git
Version abc61210
This commit is contained in:
parent
b9abf9c00c
commit
ae037e4503
8
abc.dsp
8
abc.dsp
|
|
@ -1854,10 +1854,6 @@ SOURCE=.\src\map\if\ifCut.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifLib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -1878,6 +1874,10 @@ SOURCE=.\src\map\if\ifSeq.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifTime.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifTruth.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
1
abc.rc
1
abc.rc
|
|
@ -30,6 +30,7 @@ alias fs fraig_sweep
|
|||
alias fsto fraig_store
|
||||
alias fres fraig_restore
|
||||
alias ft fraig_trust
|
||||
alias ifs if -s
|
||||
alias pex print_exdc -d
|
||||
alias pf print_factor
|
||||
alias pfan print_fanio
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
// check CI/CO numbers
|
||||
if ( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCiNum(pNtk) )
|
||||
{
|
||||
|
|
@ -127,7 +127,7 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
|
|||
fprintf( stdout, "in procedure Abc_NtkCreateObj() and in the user's code.\n" );
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// check the names
|
||||
if ( !Abc_NtkCheckNames( pNtk ) )
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -7529,25 +7529,26 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
memset( pPars, 0, sizeof(If_Par_t) );
|
||||
// user-controlable paramters
|
||||
pPars->nLutSize = 4;
|
||||
pPars->nCutsMax = 10;
|
||||
pPars->nCutsMax = 8;
|
||||
pPars->DelayTarget = -1;
|
||||
pPars->fPreprocess = 1;
|
||||
pPars->fArea = 0;
|
||||
pPars->fFancy = 0;
|
||||
pPars->fExpRed = 1;
|
||||
pPars->fLatchPaths = 0;
|
||||
pPars->fSeq = 0;
|
||||
pPars->fSeqMap = 0;
|
||||
pPars->fVerbose = 0;
|
||||
// internal parameters
|
||||
pPars->fTruth = 0;
|
||||
pPars->nLatches = pNtk? Abc_NtkLatchNum(pNtk) : 0;
|
||||
pPars->fLiftLeaves = 0;
|
||||
pPars->pLutLib = NULL; // Abc_FrameReadLibLut();
|
||||
pPars->pTimesArr = NULL;
|
||||
pPars->pTimesArr = NULL;
|
||||
pPars->pFuncCost = NULL;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCDpaflrsvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCDpaflrstvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -7600,7 +7601,10 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pPars->fExpRed ^= 1;
|
||||
break;
|
||||
case 's':
|
||||
pPars->fSeq ^= 1;
|
||||
pPars->fSeqMap ^= 1;
|
||||
break;
|
||||
case 't':
|
||||
pPars->fLiftLeaves ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
pPars->fVerbose ^= 1;
|
||||
|
|
@ -7616,12 +7620,18 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( pPars->fSeq )
|
||||
{
|
||||
fprintf( pErr, "Sequential mapping is currently being implemented.\n" );
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
if ( pPars->fSeqMap && pPars->nLatches == 0 )
|
||||
{
|
||||
fprintf( pErr, "The network has no latches. Use combinational mapping instead of sequential.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( pPars->nLutSize < 3 || pPars->nLutSize > IF_MAX_LUTSIZE )
|
||||
{
|
||||
|
|
@ -7649,13 +7659,6 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
// set the latch paths
|
||||
if ( pPars->fLatchPaths )
|
||||
{
|
||||
for ( c = 0; c < Abc_NtkPiNum(pNtk); c++ )
|
||||
pPars->pTimesArr[c] = -ABC_INFINITY;
|
||||
}
|
||||
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
// strash and balance the network
|
||||
|
|
@ -7679,7 +7682,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
{
|
||||
Abc_NtkDelete( pNtk );
|
||||
fprintf( pErr, "FPGA mapping has failed.\n" );
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
Abc_NtkDelete( pNtk );
|
||||
}
|
||||
|
|
@ -7690,7 +7693,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "FPGA mapping has failed.\n" );
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// replace the current network
|
||||
|
|
@ -7706,17 +7709,18 @@ usage:
|
|||
sprintf( LutSize, "library" );
|
||||
else
|
||||
sprintf( LutSize, "%d", pPars->nLutSize );
|
||||
fprintf( pErr, "usage: if [-K num] [-C num] [-D float] [-pafrsvh]\n" );
|
||||
fprintf( pErr, "usage: if [-K num] [-C num] [-D float] [-pafrstvh]\n" );
|
||||
fprintf( pErr, "\t performs FPGA technology mapping of the network\n" );
|
||||
fprintf( pErr, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, 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-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer );
|
||||
fprintf( pErr, "\t-p : toggles preprocessing using several starting points [default = %s]\n", pPars->fPreprocess? "yes": "no" );
|
||||
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-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" );
|
||||
fprintf( pErr, "\t-r : enables expansion/reduction of the best cuts [default = %s]\n", pPars->fExpRed? "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->fSeqMap? "yes": "no" );
|
||||
fprintf( pErr, "\t-t : toggles the use of true sequential cuts [default = %s]\n", pPars->fLiftLeaves? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : prints the command usage\n");
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExd
|
|||
// create PIs and remember them in the old nodes
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i);
|
||||
|
||||
|
||||
// perform strashing
|
||||
vNodes = Abc_AigDfs( pNtk, fAllNodes, 0 );
|
||||
if ( !fInternal )
|
||||
|
|
|
|||
|
|
@ -58,6 +58,14 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
|
|||
pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk);
|
||||
pPars->pTimesReq = NULL;
|
||||
|
||||
// set the latch paths
|
||||
if ( pPars->fLatchPaths && pPars->pTimesArr )
|
||||
{
|
||||
int c;
|
||||
for ( c = 0; c < Abc_NtkPiNum(pNtk); c++ )
|
||||
pPars->pTimesArr[c] = -ABC_INFINITY;
|
||||
}
|
||||
|
||||
// perform FPGA mapping
|
||||
pIfMan = Abc_NtkToIf( pNtk, pPars );
|
||||
if ( pIfMan == NULL )
|
||||
|
|
@ -117,7 +125,10 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
|
|||
// create PIs and remember them in the old nodes
|
||||
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)If_ManConst1( pIfMan );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
pNode->pCopy = (Abc_Obj_t *)If_ManCreatePi( pIfMan );
|
||||
{
|
||||
pNode->pCopy = (Abc_Obj_t *)If_ManCreateCi( pIfMan );
|
||||
//printf( "AIG CI %2d -> IF CI %2d\n", pNode->Id, ((If_Obj_t *)pNode->pCopy)->Id );
|
||||
}
|
||||
|
||||
// load the AIG into the mapper
|
||||
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
|
||||
|
|
@ -136,13 +147,14 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
|
|||
If_ObjSetChoice( (If_Obj_t *)pPrev->pCopy, (If_Obj_t *)pFanin->pCopy );
|
||||
If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pCopy );
|
||||
}
|
||||
//printf( "AIG node %2d -> IF node %2d\n", pNode->Id, ((If_Obj_t *)pNode->pCopy)->Id );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
||||
// set the primary outputs without copying the phase
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
If_ManCreatePo( pIfMan, (If_Obj_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
|
||||
If_ManCreateCo( pIfMan, (If_Obj_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
|
||||
return pIfMan;
|
||||
}
|
||||
|
||||
|
|
@ -177,15 +189,15 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
|
|||
// make the mapper point to the new network
|
||||
If_ObjSetCopy( If_ManConst1(pIfMan), Abc_NtkCreateNodeConst1(pNtkNew) );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
If_ObjSetCopy( If_ManPi(pIfMan, i), pNode->pCopy );
|
||||
If_ObjSetCopy( If_ManCi(pIfMan, i), pNode->pCopy );
|
||||
// process the nodes in topological order
|
||||
vCover = Vec_IntAlloc( 1 << 16 );
|
||||
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
{
|
||||
Extra_ProgressBarUpdate( pProgress, i, "Final" );
|
||||
pNodeNew = Abc_NodeFromIf_rec( pNtkNew, pIfMan, If_ObjFanin0(If_ManPo(pIfMan, i)), vCover );
|
||||
pNodeNew = Abc_ObjNotCond( pNodeNew, If_ObjFaninC0(If_ManPo(pIfMan, i)) );
|
||||
pNodeNew = Abc_NodeFromIf_rec( pNtkNew, pIfMan, If_ObjFanin0(If_ManCo(pIfMan, i)), vCover );
|
||||
pNodeNew = Abc_ObjNotCond( pNodeNew, If_ObjFaninC0(If_ManCo(pIfMan, i)) );
|
||||
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
|
|
|
|||
|
|
@ -118,15 +118,19 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
|
|||
fprintf( pFile, " lev = %3d", Abc_NtkLevel(pNtk) );
|
||||
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
|
||||
// print the statistic into a file
|
||||
/*
|
||||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "stats.txt", "a+" );
|
||||
pTable = fopen( "a/seqmap__stats.txt", "a+" );
|
||||
fprintf( pTable, "%s ", pNtk->pName );
|
||||
fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) );
|
||||
fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) );
|
||||
fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) );
|
||||
fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
|
||||
fprintf( pTable, "%d ", Abc_AigLevel(pNtk) );
|
||||
fprintf( pTable, "%d ", Abc_NtkLevel(pNtk) );
|
||||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fA
|
|||
If_Par_t Pars, * pPars = &Pars;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
|
||||
if ( Abc_NtkGetChoiceNum( pNtk ) )
|
||||
printf( "Performing renoding with choices.\n" );
|
||||
|
||||
// set defaults
|
||||
memset( pPars, 0, sizeof(If_Par_t) );
|
||||
// user-controlable paramters
|
||||
|
|
@ -67,11 +70,11 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fA
|
|||
pPars->fFancy = 0;
|
||||
pPars->fExpRed = 0; //
|
||||
pPars->fLatchPaths = 0;
|
||||
pPars->fSeq = 0;
|
||||
pPars->fSeqMap = 0;
|
||||
pPars->fVerbose = fVerbose;
|
||||
// internal parameters
|
||||
pPars->fTruth = 1;
|
||||
pPars->fUsePerm = 1; //!fUseSops;
|
||||
pPars->fUsePerm = 1;
|
||||
pPars->nLatches = 0;
|
||||
pPars->pLutLib = NULL; // Abc_FrameReadLibLut();
|
||||
pPars->pTimesArr = NULL;
|
||||
|
|
|
|||
|
|
@ -151,7 +151,8 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
|
|||
int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
char * pName;
|
||||
int i, nNewCis;
|
||||
// the first network should be an AIG
|
||||
assert( Abc_NtkIsStrash(pNtk1) );
|
||||
assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) );
|
||||
|
|
@ -165,13 +166,20 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos )
|
|||
if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1, 1 ) )
|
||||
printf( "Abc_NtkAppend(): The union of the network PIs is computed (warning).\n" );
|
||||
// perform strashing
|
||||
nNewCis = 0;
|
||||
Abc_NtkCleanCopy( pNtk2 );
|
||||
Abc_NtkForEachCi( pNtk2, pObj, i )
|
||||
{
|
||||
pName = Abc_ObjName(pObj);
|
||||
pObj->pCopy = Abc_NtkFindCi(pNtk1, Abc_ObjName(pObj));
|
||||
if ( pObj->pCopy == NULL )
|
||||
{
|
||||
pObj->pCopy = Abc_NtkDupObj(pNtk1, pObj, 1);
|
||||
nNewCis++;
|
||||
}
|
||||
}
|
||||
if ( nNewCis )
|
||||
printf( "Warning: Procedure Abc_NtkAppend() added %d new CIs.\n", nNewCis );
|
||||
// add pNtk2 to pNtk1 while strashing
|
||||
if ( Abc_NtkIsLogic(pNtk2) )
|
||||
Abc_NtkStrashPerform( pNtk2, pNtk1, 1 );
|
||||
|
|
|
|||
101
src/map/if/if.h
101
src/map/if/if.h
|
|
@ -50,8 +50,8 @@ extern "C" {
|
|||
typedef enum {
|
||||
IF_NONE, // 0: non-existent object
|
||||
IF_CONST1, // 1: constant 1
|
||||
IF_PI, // 2: primary input
|
||||
IF_PO, // 3: primary output
|
||||
IF_CI, // 2: combinational input
|
||||
IF_CO, // 3: combinational output
|
||||
IF_AND, // 4: AND node
|
||||
IF_BI, // 5: box input
|
||||
IF_BO, // 6: box output
|
||||
|
|
@ -63,9 +63,9 @@ typedef enum {
|
|||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct If_Man_t_ If_Man_t;
|
||||
typedef struct If_Par_t_ If_Par_t;
|
||||
typedef struct If_Lib_t_ If_Lib_t;
|
||||
typedef struct If_Man_t_ If_Man_t;
|
||||
typedef struct If_Obj_t_ If_Obj_t;
|
||||
typedef struct If_Cut_t_ If_Cut_t;
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ struct If_Par_t_
|
|||
int fFancy; // a fancy feature
|
||||
int fExpRed; // expand/reduce of the best cuts
|
||||
int fLatchPaths; // reset timing on latch paths
|
||||
int fSeq; // sequential mapping
|
||||
int fSeqMap; // sequential mapping
|
||||
int fVerbose; // the verbosity flag
|
||||
// internal parameters
|
||||
int fTruth; // truth table computation enabled
|
||||
|
|
@ -89,6 +89,7 @@ struct If_Par_t_
|
|||
int fUseBdds; // sets local BDDs at the nodes
|
||||
int fUseSops; // sets local SOPs at the nodes
|
||||
int nLatches; // the number of latches in seq mapping
|
||||
int fLiftLeaves; // shift the leaves for seq mapping
|
||||
If_Lib_t * pLutLib; // the LUT library
|
||||
float * pTimesArr; // arrival times
|
||||
float * pTimesReq; // required times
|
||||
|
|
@ -113,8 +114,8 @@ struct If_Man_t_
|
|||
If_Par_t * pPars;
|
||||
// mapping nodes
|
||||
If_Obj_t * pConst1; // the constant 1 node
|
||||
Vec_Ptr_t * vPis; // the primary inputs
|
||||
Vec_Ptr_t * vPos; // the primary outputs
|
||||
Vec_Ptr_t * vCis; // the primary inputs
|
||||
Vec_Ptr_t * vCos; // the primary outputs
|
||||
Vec_Ptr_t * vObjs; // all objects
|
||||
Vec_Ptr_t * vMapped; // objects used in the mapping
|
||||
Vec_Ptr_t * vTemp; // temporary array
|
||||
|
|
@ -126,10 +127,13 @@ struct If_Man_t_
|
|||
float AreaGlo; // global area
|
||||
int nCutsUsed; // the number of cuts currently used
|
||||
int nCutsMerged; // the total number of cuts merged
|
||||
int nCutsSaved; // the total number of cuts saved
|
||||
int nCutsMax; // the maximum number of cuts at a node
|
||||
float Fi; // the current value of the clock period (for seq mapping)
|
||||
unsigned * puTemp[4]; // used for the truth table computation
|
||||
// sequential mapping
|
||||
Vec_Ptr_t * vLatchOrder; // topological ordering of latches
|
||||
Vec_Int_t * vLags; // sequentail lags of all nodes
|
||||
int nAttempts; // the number of attempts in binary search
|
||||
int nMaxIters; // the maximum number of iterations
|
||||
int Period; // the current value of the clock period (for seq mapping)
|
||||
// memory management
|
||||
Mem_Fixed_t * pMem; // memory manager
|
||||
int nEntrySize; // the size of the entry
|
||||
|
|
@ -168,7 +172,8 @@ struct If_Obj_t_
|
|||
unsigned fPhase : 1; // phase of the node
|
||||
unsigned fRepr : 1; // representative of the equivalence class
|
||||
unsigned fMark : 1; // multipurpose mark
|
||||
unsigned Level : 23; // logic level of the node
|
||||
unsigned fVisit : 1; // multipurpose mark
|
||||
unsigned Level : 22; // logic level of the node
|
||||
int Id; // integer ID
|
||||
int nRefs; // the number of references
|
||||
int nCuts; // the number of cuts
|
||||
|
|
@ -182,19 +187,21 @@ struct If_Obj_t_
|
|||
};
|
||||
|
||||
static inline If_Obj_t * If_ManConst1( If_Man_t * p ) { return p->pConst1; }
|
||||
static inline If_Obj_t * If_ManPi( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vPis, i ); }
|
||||
static inline If_Obj_t * If_ManPo( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vPos, i ); }
|
||||
static inline If_Obj_t * If_ManCi( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vCis, i ); }
|
||||
static inline If_Obj_t * If_ManCo( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vCos, 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 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_ManCiNum( If_Man_t * p ) { return p->nObjs[IF_CI]; }
|
||||
static inline int If_ManCoNum( If_Man_t * p ) { return p->nObjs[IF_CO]; }
|
||||
static inline int If_ManAndNum( If_Man_t * p ) { return p->nObjs[IF_AND]; }
|
||||
static inline int If_ManObjNum( If_Man_t * p ) { return Vec_PtrSize(p->vObjs); }
|
||||
|
||||
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_ObjIsPo( If_Obj_t * pObj ) { return pObj->Type == IF_PO; }
|
||||
static inline int If_ObjIsCi( If_Obj_t * pObj ) { return pObj->Type == IF_CI; }
|
||||
static inline int If_ObjIsCo( If_Obj_t * pObj ) { return pObj->Type == IF_CO; }
|
||||
static inline int If_ObjIsPi( If_Obj_t * pObj ) { return If_ObjIsCi(pObj) && pObj->pFanin0 == NULL; }
|
||||
static inline int If_ObjIsLatch( If_Obj_t * pObj ) { return If_ObjIsCi(pObj) && pObj->pFanin0 != NULL; }
|
||||
static inline int If_ObjIsAnd( If_Obj_t * pObj ) { return pObj->Type == IF_AND; }
|
||||
static inline int If_ObjIsBi( If_Obj_t * pObj ) { return pObj->Type == IF_BI; }
|
||||
static inline int If_ObjIsBo( If_Obj_t * pObj ) { return pObj->Type == IF_BO; }
|
||||
|
|
@ -210,9 +217,12 @@ static inline void If_ObjSetChoice( If_Obj_t * pObj, If_Obj_t * pEqu ) { p
|
|||
|
||||
static inline If_Cut_t * If_ObjCut( If_Obj_t * pObj, int iCut ) { return pObj->Cuts + iCut; }
|
||||
static inline If_Cut_t * If_ObjCutTriv( If_Obj_t * pObj ) { return pObj->Cuts; }
|
||||
static inline If_Cut_t * If_ObjCutBest( If_Obj_t * pObj ) { return pObj->Cuts + 1; }
|
||||
static inline If_Cut_t * If_ObjCutBest( If_Obj_t * pObj ) { return pObj->Cuts + (int)(pObj->nCuts > 1); }
|
||||
static inline unsigned If_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId % 31)); }
|
||||
|
||||
static inline float If_ObjLValue( If_Obj_t * pObj ) { return If_ObjCutTriv(pObj)->Delay; }
|
||||
static inline void If_ObjSetLValue( If_Obj_t * pObj, float LValue ) { If_ObjCutTriv(pObj)->Delay = LValue; }
|
||||
|
||||
static inline void * If_CutData( If_Cut_t * pCut ) { return *(void **)pCut; }
|
||||
static inline void If_CutSetData( If_Cut_t * pCut, void * pData ) { *(void **)pCut = pData; }
|
||||
|
||||
|
|
@ -227,23 +237,29 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define IF_MIN(a,b) (((a) < (b))? (a) : (b))
|
||||
#define IF_MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
#define IF_MIN(a,b) (((a) < (b))? (a) : (b))
|
||||
#define IF_MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
|
||||
// the small and large numbers (min/max float are 1.17e-38/3.40e+38)
|
||||
#define IF_FLOAT_LARGE ((float)1.0e+20)
|
||||
#define IF_FLOAT_SMALL ((float)1.0e-20)
|
||||
#define IF_INT_LARGE (10000000)
|
||||
|
||||
// iterator over the primary inputs
|
||||
#define If_ManForEachCi( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vCis, pObj, i )
|
||||
// iterator over the primary outputs
|
||||
#define If_ManForEachCo( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vCos, pObj, i )
|
||||
// iterator over the primary inputs
|
||||
#define If_ManForEachPi( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vPis, pObj, i )
|
||||
Vec_PtrForEachEntryStop( p->vCis, pObj, i, If_ManCiNum(p) - p->pPars->nLatches )
|
||||
// iterator over the primary outputs
|
||||
#define If_ManForEachPo( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vPos, pObj, i )
|
||||
Vec_PtrForEachEntryStop( p->vCos, pObj, i, If_ManCoNum(p) - p->pPars->nLatches )
|
||||
// iterator over the latches
|
||||
#define If_ManForEachLatch( p, pObj, i ) \
|
||||
Vec_PtrForEachEntryStart( p->vPos, pObj, i, If_ManPoNum(p) - p->pPars->nLatches )
|
||||
Vec_PtrForEachEntryStart( p->vCos, pObj, i, If_ManCoNum(p) - p->pPars->nLatches )
|
||||
// iterator over all objects, including those currently not used
|
||||
#define If_ManForEachObj( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vObjs, pObj, i )
|
||||
|
|
@ -256,17 +272,22 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r
|
|||
// iterator over cuts of the node
|
||||
#define If_ObjForEachCutStart( pObj, pCut, i, Start ) \
|
||||
for ( i = Start; (i < (int)(pObj)->nCuts) && ((pCut) = (pObj)->Cuts + i); i++ )
|
||||
// iterator leaves of the cut
|
||||
// iterator over the leaves of the cut
|
||||
//#define If_CutForEachLeaf( p, pCut, pLeaf, i ) \
|
||||
// for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, (pCut)->pLeaves[i])); i++ )
|
||||
#define If_CutForEachLeaf( p, pCut, pLeaf, i ) \
|
||||
for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, (pCut)->pLeaves[i])); i++ )
|
||||
for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, p->pPars->fLiftLeaves? (pCut)->pLeaves[i] >> 8 : (pCut)->pLeaves[i])); i++ )
|
||||
// iterator over the leaves of the sequential cut
|
||||
#define If_CutForEachLeafSeq( p, pCut, pLeaf, Shift, i ) \
|
||||
for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, (pCut)->pLeaves[i] >> 8)) && (((Shift) = ((pCut)->pLeaves[i] & 255)) >= 0); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== ifCore.c ==========================================================*/
|
||||
/*=== ifCore.c ===========================================================*/
|
||||
extern int If_ManPerformMapping( If_Man_t * p );
|
||||
/*=== ifCut.c ==========================================================*/
|
||||
/*=== ifCut.c ============================================================*/
|
||||
extern float If_CutAreaDerefed( If_Man_t * p, If_Cut_t * pCut, int nLevels );
|
||||
extern float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut, int nLevels );
|
||||
extern float If_CutDeref( If_Man_t * p, If_Cut_t * pCut, int nLevels );
|
||||
|
|
@ -277,35 +298,39 @@ extern float If_CutFlow( If_Man_t * p, If_Cut_t * pCut );
|
|||
extern float If_CutAverageRefs( If_Man_t * p, If_Cut_t * pCut );
|
||||
extern int If_CutFilter( If_Man_t * p, If_Cut_t * pCut );
|
||||
extern int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut );
|
||||
extern void If_CutLift( If_Cut_t * pCut );
|
||||
extern void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc );
|
||||
extern void If_ManSortCuts( If_Man_t * p, int Mode );
|
||||
/*=== ifLib.c ==========================================================*/
|
||||
extern float If_CutDelay( If_Man_t * p, If_Cut_t * pCut );
|
||||
extern void If_CutPropagateRequired( If_Man_t * p, If_Cut_t * pCut, float Required );
|
||||
/*=== ifMan.c ==========================================================*/
|
||||
/*=== ifMan.c =============================================================*/
|
||||
extern If_Man_t * If_ManStart( If_Par_t * pPars );
|
||||
extern void If_ManStop( If_Man_t * p );
|
||||
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_ManCreateCi( If_Man_t * p );
|
||||
extern If_Obj_t * If_ManCreateCo( 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 void If_ManCreateChoice( If_Man_t * p, If_Obj_t * pRepr );
|
||||
/*=== ifMap.c ==========================================================*/
|
||||
extern void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode );
|
||||
/*=== ifMap.c =============================================================*/
|
||||
extern void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode );
|
||||
extern void If_ObjPerformMappingChoice( If_Man_t * p, If_Obj_t * pObj, int Mode );
|
||||
extern int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode, int fRequired, char * pLabel );
|
||||
/*=== ifPrepro.c ==========================================================*/
|
||||
extern void If_ManPerformMappingPreprocess( If_Man_t * p );
|
||||
/*=== ifReduce.c ==========================================================*/
|
||||
extern void If_ManImproveMapping( If_Man_t * p );
|
||||
/*=== ifSeq.c ==========================================================*/
|
||||
/*=== ifSeq.c =============================================================*/
|
||||
extern int If_ManPerformMappingSeq( If_Man_t * p );
|
||||
/*=== ifTruth.c ==========================================================*/
|
||||
/*=== ifTime.c ============================================================*/
|
||||
extern float If_CutDelay( If_Man_t * p, If_Cut_t * pCut );
|
||||
extern void If_CutPropagateRequired( If_Man_t * p, If_Cut_t * pCut, float Required );
|
||||
/*=== ifTruth.c ===========================================================*/
|
||||
extern void If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 );
|
||||
/*=== ifUtil.c ==========================================================*/
|
||||
extern float If_ManDelayMax( If_Man_t * p );
|
||||
/*=== ifUtil.c ============================================================*/
|
||||
extern void If_ManCleanNodeCopy( If_Man_t * p );
|
||||
extern void If_ManCleanCutData( If_Man_t * p );
|
||||
extern void If_ManCleanMarkV( If_Man_t * p );
|
||||
extern float If_ManDelayMax( If_Man_t * p, int fSeq );
|
||||
extern void If_ManComputeRequired( If_Man_t * p, int fFirstTime );
|
||||
extern float If_ManScanMapping( If_Man_t * p );
|
||||
extern float If_ManScanMappingSeq( If_Man_t * p );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,13 +45,25 @@ int If_ManPerformMapping( If_Man_t * p )
|
|||
int nItersFlow = 1;
|
||||
int nItersArea = 2;
|
||||
int clkTotal = clock();
|
||||
int i;
|
||||
int RetValue, i;
|
||||
|
||||
// try sequential mapping
|
||||
if ( p->pPars->fSeqMap )
|
||||
{
|
||||
RetValue = If_ManPerformMappingSeq( p );
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
PRT( "Total time", clock() - clkTotal );
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
// set arrival times and trivial cuts at const 1 and PIs
|
||||
If_ManConst1(p)->Cuts[0].Delay = 0.0;
|
||||
If_ManForEachPi( p, pObj, i )
|
||||
If_ManForEachCi( p, pObj, i )
|
||||
pObj->Cuts[0].Delay = p->pPars->pTimesArr[i];
|
||||
// set the fanout estimates of the PIs
|
||||
If_ManForEachPi( p, pObj, i )
|
||||
If_ManForEachCi( p, pObj, i )
|
||||
pObj->EstRefs = (float)1.0;
|
||||
// delay oriented mapping
|
||||
if ( p->pPars->fPreprocess && !p->pPars->fArea && p->pPars->nCutsMax >= 4 )
|
||||
|
|
|
|||
|
|
@ -423,13 +423,15 @@ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut )
|
|||
If_Obj_t * pLeaf;
|
||||
float Flow;
|
||||
int i;
|
||||
assert( pCut->nLeaves > 1 );
|
||||
assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
|
||||
Flow = If_CutLutArea(p, pCut);
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
{
|
||||
if ( pLeaf->nRefs == 0 )
|
||||
Flow += If_ObjCutBest(pLeaf)->Area;
|
||||
else
|
||||
else if ( p->pPars->fSeqMap ) // seq
|
||||
Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->nRefs;
|
||||
else
|
||||
{
|
||||
assert( pLeaf->EstRefs > p->fEpsilon );
|
||||
Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs;
|
||||
|
|
@ -453,7 +455,7 @@ float If_CutAverageRefs( If_Man_t * p, If_Cut_t * pCut )
|
|||
{
|
||||
If_Obj_t * pLeaf;
|
||||
int nRefsTotal, i;
|
||||
assert( pCut->nLeaves > 1 );
|
||||
assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
|
||||
nRefsTotal = 0;
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
nRefsTotal += pLeaf->nRefs;
|
||||
|
|
@ -569,7 +571,7 @@ void If_CutPrintTiming( If_Man_t * p, If_Cut_t * pCut )
|
|||
float If_CutAreaDerefed( If_Man_t * p, If_Cut_t * pCut, int nLevels )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
assert( pCut->nLeaves > 1 );
|
||||
assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
|
||||
aResult2 = If_CutRef( p, pCut, nLevels );
|
||||
aResult = If_CutDeref( p, pCut, nLevels );
|
||||
assert( aResult == aResult2 );
|
||||
|
|
@ -590,13 +592,34 @@ float If_CutAreaDerefed( If_Man_t * p, If_Cut_t * pCut, int nLevels )
|
|||
float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut, int nLevels )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
assert( pCut->nLeaves > 1 );
|
||||
assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
|
||||
aResult2 = If_CutDeref( p, pCut, nLevels );
|
||||
aResult = If_CutRef( p, pCut, nLevels );
|
||||
assert( aResult == aResult2 );
|
||||
return aResult;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Moves the cut over the latch.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_CutLift( If_Cut_t * pCut )
|
||||
{
|
||||
unsigned i;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
assert( (pCut->pLeaves[i] & 255) < 255 );
|
||||
pCut->pLeaves[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area of the first level.]
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ If_Man_t * If_ManStart( If_Par_t * pPars )
|
|||
p->pPars = pPars;
|
||||
p->fEpsilon = (float)0.001;
|
||||
// allocate arrays for nodes
|
||||
p->vPis = Vec_PtrAlloc( 100 );
|
||||
p->vPos = Vec_PtrAlloc( 100 );
|
||||
p->vCis = Vec_PtrAlloc( 100 );
|
||||
p->vCos = Vec_PtrAlloc( 100 );
|
||||
p->vObjs = Vec_PtrAlloc( 100 );
|
||||
p->vMapped = Vec_PtrAlloc( 100 );
|
||||
p->vTemp = Vec_PtrAlloc( 100 );
|
||||
|
|
@ -96,11 +96,13 @@ void If_ManStop( If_Man_t * p )
|
|||
{
|
||||
If_Cut_t * pTemp;
|
||||
int i;
|
||||
Vec_PtrFree( p->vPis );
|
||||
Vec_PtrFree( p->vPos );
|
||||
Vec_PtrFree( p->vCis );
|
||||
Vec_PtrFree( p->vCos );
|
||||
Vec_PtrFree( p->vObjs );
|
||||
Vec_PtrFree( p->vMapped );
|
||||
Vec_PtrFree( p->vTemp );
|
||||
if ( p->vLatchOrder ) Vec_PtrFree( p->vLatchOrder );
|
||||
if ( p->vLags ) Vec_IntFree( p->vLags );
|
||||
Mem_FixedStop( p->pMem, 0 );
|
||||
// free pars memory
|
||||
if ( p->pPars->pTimesArr )
|
||||
|
|
@ -129,13 +131,13 @@ void If_ManStop( If_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
If_Obj_t * If_ManCreatePi( If_Man_t * p )
|
||||
If_Obj_t * If_ManCreateCi( If_Man_t * p )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
pObj = If_ManSetupObj( p );
|
||||
pObj->Type = IF_PI;
|
||||
Vec_PtrPush( p->vPis, pObj );
|
||||
p->nObjs[IF_PI]++;
|
||||
pObj->Type = IF_CI;
|
||||
Vec_PtrPush( p->vCis, pObj );
|
||||
p->nObjs[IF_CI]++;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
|
|
@ -150,15 +152,15 @@ If_Obj_t * If_ManCreatePi( If_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
If_Obj_t * If_ManCreatePo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 )
|
||||
If_Obj_t * If_ManCreateCo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
pObj = If_ManSetupObj( p );
|
||||
pObj->Type = IF_PO;
|
||||
pObj->Type = IF_CO;
|
||||
pObj->fCompl0 = fCompl0;
|
||||
Vec_PtrPush( p->vPos, pObj );
|
||||
Vec_PtrPush( p->vCos, pObj );
|
||||
pObj->pFanin0 = pDriver; pDriver->nRefs++;
|
||||
p->nObjs[IF_PO]++;
|
||||
p->nObjs[IF_CO]++;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +253,7 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
|
|||
// assign elementary cut
|
||||
pCut = pObj->Cuts;
|
||||
pCut->nLeaves = 1;
|
||||
pCut->pLeaves[0] = p->pPars->fSeq? (pObj->Id << 8) : pObj->Id;
|
||||
pCut->pLeaves[0] = p->pPars->fLiftLeaves? (pObj->Id << 8) : pObj->Id;
|
||||
pCut->uSign = If_ObjCutSign( pCut->pLeaves[0] );
|
||||
// set the number of cuts
|
||||
pObj->nCuts = 1;
|
||||
|
|
|
|||
|
|
@ -69,27 +69,31 @@ static inline int If_WordCountOnes( unsigned uWord )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
|
||||
void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode )
|
||||
{
|
||||
If_Cut_t * pCut0, * pCut1, * pCut;
|
||||
int i, k, iCut;
|
||||
|
||||
assert( !If_ObjIsAnd(pObj->pFanin0) || pObj->pFanin0->nCuts > 1 );
|
||||
assert( !If_ObjIsAnd(pObj->pFanin1) || pObj->pFanin1->nCuts > 1 );
|
||||
assert( p->pPars->fSeqMap || !If_ObjIsAnd(pObj->pFanin0) || pObj->pFanin0->nCuts > 1 );
|
||||
assert( p->pPars->fSeqMap || !If_ObjIsAnd(pObj->pFanin1) || pObj->pFanin1->nCuts > 1 );
|
||||
|
||||
// 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 ( !p->pPars->fSeqMap )
|
||||
{
|
||||
if ( Mode == 0 )
|
||||
pObj->EstRefs = (float)pObj->nRefs;
|
||||
else if ( Mode == 1 )
|
||||
pObj->EstRefs = (float)((2.0 * pObj->EstRefs + pObj->nRefs) / 3.0);
|
||||
}
|
||||
if ( Mode && pObj->nRefs > 0 )
|
||||
If_CutDeref( p, If_ObjCutBest(pObj), 100 );
|
||||
|
||||
// recompute the parameters of the best cut
|
||||
// save the best cut as one of the candidate cuts
|
||||
p->nCuts = 0;
|
||||
p->nCutsMerged++;
|
||||
if ( Mode )
|
||||
{
|
||||
// recompute the parameters of the best cut
|
||||
pCut = If_ObjCutBest(pObj);
|
||||
pCut->Delay = If_CutDelay( p, pCut );
|
||||
assert( pCut->Delay <= pObj->Required + p->fEpsilon );
|
||||
|
|
@ -114,12 +118,12 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
|
|||
continue;
|
||||
// check if this cut is contained in any of the available cuts
|
||||
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 ) )
|
||||
continue;
|
||||
// the cuts have been successfully merged
|
||||
// compute the truth table
|
||||
pCut->fCompl = 0;
|
||||
if ( p->pPars->fTruth )
|
||||
If_CutComputeTruth( p, pCut, pCut0, pCut1, pObj->fCompl0, pObj->fCompl1 );
|
||||
// compute the application-specific cost and depth
|
||||
|
|
@ -149,16 +153,14 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
|
|||
If_ManSortCuts( p, Mode );
|
||||
// decide how many cuts to use
|
||||
pObj->nCuts = IF_MIN( p->nCuts + 1, p->nCutsUsed );
|
||||
//printf( "%d(%d) ", p->nCuts, pObj->nCuts );
|
||||
// take the first
|
||||
If_ObjForEachCutStart( pObj, pCut, i, 1 )
|
||||
If_CutCopy( pCut, p->ppCuts[i-1] );
|
||||
assert( If_ObjCutBest(pObj)->nLeaves > 1 );
|
||||
assert( p->pPars->fSeqMap || If_ObjCutBest(pObj)->nLeaves > 1 );
|
||||
// ref the selected cut
|
||||
if ( Mode == 2 && pObj->nRefs > 0 )
|
||||
if ( Mode && pObj->nRefs > 0 )
|
||||
If_CutRef( p, If_ObjCutBest(pObj), 100 );
|
||||
// find the largest cut
|
||||
if ( p->nCutsMax < pObj->nCuts )
|
||||
p->nCutsMax = pObj->nCuts;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -172,14 +174,14 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ObjMergeChoice( If_Man_t * p, If_Obj_t * pObj, int Mode )
|
||||
void If_ObjPerformMappingChoice( 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 ( Mode && pObj->nRefs > 0 )
|
||||
If_CutDeref( p, If_ObjCutBest(pObj), 100 );
|
||||
// prepare room for the next cut
|
||||
p->nCuts = 0;
|
||||
|
|
@ -227,13 +229,10 @@ void If_ObjMergeChoice( If_Man_t * p, If_Obj_t * pObj, int Mode )
|
|||
// take the first
|
||||
If_ObjForEachCutStart( pObj, pCut, i, 1 )
|
||||
If_CutCopy( pCut, p->ppCuts[i-1] );
|
||||
assert( If_ObjCutBest(pObj)->nLeaves > 1 );
|
||||
assert( p->pPars->fSeqMap || If_ObjCutBest(pObj)->nLeaves > 1 );
|
||||
// ref the selected cut
|
||||
if ( Mode == 2 && pObj->nRefs > 0 )
|
||||
if ( Mode && pObj->nRefs > 0 )
|
||||
If_CutRef( p, If_ObjCutBest(pObj), 100 );
|
||||
// find the largest cut
|
||||
if ( p->nCutsMax < pObj->nCuts )
|
||||
p->nCutsMax = pObj->nCuts;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -249,25 +248,23 @@ void If_ObjMergeChoice( If_Man_t * p, If_Obj_t * pObj, int Mode )
|
|||
***********************************************************************/
|
||||
int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode, int fRequired, char * pLabel )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
// 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) );
|
||||
// pProgress = Extra_ProgressBarStart( stdout, If_ManObjNum(p) );
|
||||
If_ManForEachNode( p, pObj, i )
|
||||
{
|
||||
Extra_ProgressBarUpdate( pProgress, i, pLabel );
|
||||
If_ObjPerformMapping( p, pObj, Mode );
|
||||
// Extra_ProgressBarUpdate( pProgress, i, pLabel );
|
||||
If_ObjPerformMappingAnd( p, pObj, Mode );
|
||||
if ( pObj->fRepr )
|
||||
If_ObjMergeChoice( p, pObj, Mode );
|
||||
If_ObjPerformMappingChoice( p, pObj, Mode );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
// Extra_ProgressBarStop( pProgress );
|
||||
// compute required times and stats
|
||||
if ( fRequired )
|
||||
{
|
||||
|
|
@ -278,7 +275,6 @@ int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode, int fRequi
|
|||
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) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ void If_ManPerformMappingPreprocess( If_Man_t * p )
|
|||
p->pPars->fArea = 1;
|
||||
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 0, "Start delay" );
|
||||
p->pPars->fArea = 0;
|
||||
delayArea = If_ManDelayMax( p );
|
||||
delayArea = If_ManDelayMax( p, 0 );
|
||||
if ( p->pPars->DelayTarget != -1 && delayArea < p->pPars->DelayTarget - p->fEpsilon )
|
||||
delayArea = p->pPars->DelayTarget;
|
||||
If_ManPerformMappingMoveBestCut( p, p->pPars->nCutsMax - 1, 1 );
|
||||
|
|
@ -61,14 +61,14 @@ void If_ManPerformMappingPreprocess( If_Man_t * p )
|
|||
p->pPars->fFancy = 1;
|
||||
If_ManPerformMappingRound( p, p->pPars->nCutsMax - 1, 0, 0, "Start delay-2" );
|
||||
p->pPars->fFancy = 0;
|
||||
delayDelay = If_ManDelayMax( p );
|
||||
delayDelay = If_ManDelayMax( p, 0 );
|
||||
if ( p->pPars->DelayTarget != -1 && delayDelay < p->pPars->DelayTarget - p->fEpsilon )
|
||||
delayDelay = p->pPars->DelayTarget;
|
||||
If_ManPerformMappingMoveBestCut( p, p->pPars->nCutsMax - 2, 1 );
|
||||
|
||||
// perform min-delay mapping
|
||||
If_ManPerformMappingRound( p, p->pPars->nCutsMax - 2, 0, 0, "Start flow" );
|
||||
delayPure = If_ManDelayMax( p );
|
||||
delayPure = If_ManDelayMax( p, 0 );
|
||||
if ( p->pPars->DelayTarget != -1 && delayPure < p->pPars->DelayTarget - p->fEpsilon )
|
||||
delayPure = p->pPars->DelayTarget;
|
||||
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ int If_ManImproveNodeFaninCompact0( If_Man_t * p, If_Obj_t * pObj, int nLimit, V
|
|||
int i;
|
||||
Vec_PtrForEachEntry( vFront, pFanin, i )
|
||||
{
|
||||
if ( If_ObjIsPi(pFanin) )
|
||||
if ( If_ObjIsCi(pFanin) )
|
||||
continue;
|
||||
if ( If_ManImproveNodeWillGrow(p, pFanin) )
|
||||
continue;
|
||||
|
|
@ -391,7 +391,7 @@ int If_ManImproveNodeFaninCompact1( If_Man_t * p, If_Obj_t * pObj, int nLimit, V
|
|||
int i;
|
||||
Vec_PtrForEachEntry( vFront, pFanin, i )
|
||||
{
|
||||
if ( If_ObjIsPi(pFanin) )
|
||||
if ( If_ObjIsCi(pFanin) )
|
||||
continue;
|
||||
if ( If_ManImproveNodeFaninCost(p, pFanin) < 0 )
|
||||
{
|
||||
|
|
@ -419,7 +419,7 @@ int If_ManImproveNodeFaninCompact2( If_Man_t * p, If_Obj_t * pObj, int nLimit, V
|
|||
int i;
|
||||
Vec_PtrForEachEntry( vFront, pFanin, i )
|
||||
{
|
||||
if ( If_ObjIsPi(pFanin) )
|
||||
if ( If_ObjIsCi(pFanin) )
|
||||
continue;
|
||||
if ( If_ManImproveNodeFaninCost(p, pFanin) <= 0 )
|
||||
{
|
||||
|
|
@ -498,8 +498,8 @@ void If_ManImproveNodeReduce( If_Man_t * p, If_Obj_t * pObj, int nLimit )
|
|||
pFanin1 = If_ObjFanin1(pObj);
|
||||
// get the cuts
|
||||
pCut = If_ObjCutBest(pObj);
|
||||
pCut0 = If_ObjIsPi(pFanin0) ? If_ObjCutTriv(pFanin0) : If_ObjCutBest(pFanin0);
|
||||
pCut1 = If_ObjIsPi(pFanin1) ? If_ObjCutTriv(pFanin1) : If_ObjCutBest(pFanin1);
|
||||
pCut0 = If_ObjIsCi(pFanin0) ? If_ObjCutTriv(pFanin0) : If_ObjCutBest(pFanin0);
|
||||
pCut1 = If_ObjIsCi(pFanin1) ? If_ObjCutTriv(pFanin1) : If_ObjCutBest(pFanin1);
|
||||
assert( pCut->Delay <= pObj->Required + p->fEpsilon );
|
||||
|
||||
// deref the cut if the node is refed
|
||||
|
|
|
|||
|
|
@ -24,9 +24,11 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void If_ObjPerformMappingLI( If_Man_t * p, If_Obj_t * pLatch );
|
||||
static void If_ObjPerformMappingLO( If_Man_t * p, If_Obj_t * pLatch, If_Obj_t * pObj );
|
||||
static int If_ManMappingSeqConverged( If_Man_t * p );
|
||||
static int If_ManBinarySearchPeriod( If_Man_t * p, int Mode );
|
||||
static int If_ManBinarySearch_rec( If_Man_t * p, int Mode, int FiMin, int FiMax );
|
||||
static int If_ManPerformMappingRoundSeq( If_Man_t * p, int Mode, int nIter, char * pLabel );
|
||||
static int If_ManPrepareMappingSeq( If_Man_t * p );
|
||||
static int If_ObjPerformMappingLatch( If_Man_t * p, If_Obj_t * pObj );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -45,46 +47,327 @@ static int If_ManMappingSeqConverged( If_Man_t * p );
|
|||
***********************************************************************/
|
||||
int If_ManPerformMappingSeq( If_Man_t * p )
|
||||
{
|
||||
If_Obj_t * pObj, * pLatch;
|
||||
int i, clkTotal = clock();
|
||||
// set the number of cuts used
|
||||
p->nCutsUsed = p->pPars->nCutsMax;
|
||||
// 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
|
||||
p->pPars->fFancy = 1;
|
||||
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 0, NULL );
|
||||
p->pPars->fFancy = 0;
|
||||
int PeriodBest, Mode = 0;
|
||||
|
||||
// perform iterations over the circuit
|
||||
while ( !If_ManMappingSeqConverged( p ) )
|
||||
// collect nodes in the sequential order
|
||||
If_ManPrepareMappingSeq( p );
|
||||
|
||||
// perform combinational mapping to get the upper bound on the clock period
|
||||
If_ManPerformMappingRound( p, 2, 0, 0, NULL );
|
||||
p->RequiredGlo = If_ManDelayMax( p, 0 );
|
||||
|
||||
// set parameters
|
||||
p->nCutsUsed = p->pPars->nCutsMax;
|
||||
p->nAttempts = 0;
|
||||
p->nMaxIters = 50;
|
||||
p->Period = (int)p->RequiredGlo;
|
||||
|
||||
// make sure the clock period words
|
||||
if ( !If_ManBinarySearchPeriod( p, Mode ) )
|
||||
{
|
||||
// assign cuts to latches
|
||||
If_ManForEachLatch( p, pLatch, i )
|
||||
If_ObjPerformMappingLI( p, pLatch );
|
||||
// assign cuts to primary inputs
|
||||
If_ManForEachLatch( p, pLatch, i )
|
||||
If_ObjPerformMappingLO( p, pLatch, If_ManPi(p, If_ManPiNum(p) - If_ManPoNum(p) + i) );
|
||||
// map the nodes
|
||||
If_ManForEachNode( p, pObj, i )
|
||||
If_ObjPerformMapping( p, pObj, 0 );
|
||||
printf( "If_ManPerformMappingSeq(): The upper bound on the clock period cannot be computed.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// perform binary search
|
||||
PeriodBest = If_ManBinarySearch_rec( p, Mode, 0, p->Period );
|
||||
|
||||
// recompute the best l-values
|
||||
if ( p->Period != PeriodBest )
|
||||
{
|
||||
p->Period = PeriodBest;
|
||||
if ( !If_ManBinarySearchPeriod( p, Mode ) )
|
||||
{
|
||||
printf( "If_ManPerformMappingSeq(): The final clock period cannot be confirmed.\n" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// fix the problem with non-converged delays
|
||||
If_ManForEachNode( p, pObj, i )
|
||||
if ( pObj->LValue < -ABC_INFINITY/2 )
|
||||
pObj->LValue = (float)0.0;
|
||||
// write the retiming lags
|
||||
p->vLags = Vec_IntStart( If_ManObjNum(p) + 1 );
|
||||
If_ManForEachNode( p, pObj, i )
|
||||
Vec_IntWriteEntry( vLags, i, Abc_NodeComputeLag(pObj->LValue, p->Period) );
|
||||
*/
|
||||
/*
|
||||
// print the statistic into a file
|
||||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "a/seqmap__stats.txt", "a+" );
|
||||
fprintf( pTable, "%d ", p->Period );
|
||||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
*/
|
||||
// print the result
|
||||
if ( p->pPars->fLiftLeaves )
|
||||
{
|
||||
// if ( p->pPars->fVerbose )
|
||||
printf( "The best clock period is %3d. (Currently, network is not modified, so mapping will fail.)\n", p->Period );
|
||||
return 0;
|
||||
}
|
||||
// if ( p->pPars->fVerbose )
|
||||
printf( "The best clock period is %3d.\n", p->Period );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs binary search for the optimal clock period.]
|
||||
|
||||
Description [Assumes that FiMin is infeasible while FiMax is feasible.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_ManBinarySearch_rec( If_Man_t * p, int Mode, int FiMin, int FiMax )
|
||||
{
|
||||
assert( FiMin < FiMax );
|
||||
if ( FiMin + 1 == FiMax )
|
||||
return FiMax;
|
||||
// compute the median
|
||||
p->Period = FiMin + (FiMax - FiMin)/2;
|
||||
if ( If_ManBinarySearchPeriod( p, Mode ) )
|
||||
return If_ManBinarySearch_rec( p, Mode, FiMin, p->Period ); // Median is feasible
|
||||
else
|
||||
return If_ManBinarySearch_rec( p, Mode, p->Period, FiMax ); // Median is infeasible
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if retiming with this clock period is feasible.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_ManBinarySearchPeriod( If_Man_t * p, int Mode )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
int i, c, fConverged;
|
||||
int fResetRefs = 0;
|
||||
|
||||
p->nAttempts++;
|
||||
|
||||
// set l-values of all nodes to be minus infinity, except PIs and constants
|
||||
If_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
pObj->nCuts = 1;
|
||||
If_ObjSetLValue( pObj, -IF_FLOAT_LARGE );
|
||||
if ( fResetRefs )
|
||||
pObj->nRefs = 0;
|
||||
}
|
||||
If_ObjSetLValue( If_ManConst1(p), (float)0.0 );
|
||||
If_ManForEachPi( p, pObj, i )
|
||||
If_ObjSetLValue( pObj, (float)0.0 );
|
||||
|
||||
// reset references to their original state
|
||||
if ( fResetRefs )
|
||||
{
|
||||
If_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( If_ObjIsCo(pObj) )
|
||||
continue;
|
||||
if ( pObj->pFanin0 ) pObj->pFanin0->nRefs++;
|
||||
if ( pObj->pFanin1 ) pObj->pFanin1->nRefs++;
|
||||
}
|
||||
}
|
||||
|
||||
// update all values iteratively
|
||||
fConverged = 0;
|
||||
for ( c = 1; c <= p->nMaxIters; c++ )
|
||||
{
|
||||
if ( !If_ManPerformMappingRoundSeq( p, Mode, c, NULL ) )
|
||||
{
|
||||
fConverged = 1;
|
||||
break;
|
||||
}
|
||||
p->RequiredGlo = If_ManDelayMax( p, 1 );
|
||||
if ( p->RequiredGlo > p->Period + p->fEpsilon )
|
||||
break;
|
||||
}
|
||||
|
||||
// report the results
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
PRT( "Total time", clock() - clkTotal );
|
||||
p->AreaGlo = p->pPars->fLiftLeaves? If_ManScanMappingSeq(p) : If_ManScanMapping(p);
|
||||
printf( "Attempt = %2d. Iters = %3d. Area = %10.2f. Fi = %6.2f. ", p->nAttempts, c, p->AreaGlo, (float)p->Period );
|
||||
if ( fConverged )
|
||||
printf( " Feasible" );
|
||||
else if ( c > p->nMaxIters )
|
||||
printf( "Infeasible (timeout)" );
|
||||
else
|
||||
printf( "Infeasible" );
|
||||
printf( "\n" );
|
||||
}
|
||||
return fConverged;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs one pass of l-value computation over all nodes.]
|
||||
|
||||
Description [Experimentally it was found that checking POs changes
|
||||
is not enough to detect the convergence of l-values in the network.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_ManPerformMappingRoundSeq( If_Man_t * p, int Mode, int nIter, char * pLabel )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
If_Obj_t * pObj;
|
||||
int i, clk = clock();
|
||||
int fVeryVerbose = 0;
|
||||
int fChange = 0;
|
||||
assert( Mode >= 0 && Mode <= 2 );
|
||||
if ( !p->pPars->fVerbose )
|
||||
pProgress = Extra_ProgressBarStart( stdout, If_ManObjNum(p) );
|
||||
// map the internal nodes
|
||||
p->nCutsMerged = 0;
|
||||
If_ManForEachNode( p, pObj, i )
|
||||
{
|
||||
if ( !p->pPars->fVerbose )
|
||||
Extra_ProgressBarUpdate( pProgress, i, pLabel );
|
||||
// consider the camse of an AND gate
|
||||
assert( If_ObjIsAnd(pObj) );
|
||||
If_ObjPerformMappingAnd( p, pObj, Mode );
|
||||
if ( pObj->fRepr )
|
||||
If_ObjPerformMappingChoice( p, pObj, Mode );
|
||||
// check if updating happens
|
||||
if ( If_ObjLValue(pObj) < If_ObjCutBest(pObj)->Delay - p->fEpsilon )
|
||||
{
|
||||
If_ObjSetLValue( pObj, If_ObjCutBest(pObj)->Delay );
|
||||
fChange = 1;
|
||||
}
|
||||
//if ( If_ObjLValue(pObj) > -1000.0 )
|
||||
//printf( "Node %d %.2f ", pObj->Id, If_ObjLValue(pObj) );
|
||||
}
|
||||
if ( !p->pPars->fVerbose )
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
// propagate arrival times from the registers
|
||||
Vec_PtrForEachEntry( p->vLatchOrder, pObj, i )
|
||||
fChange |= If_ObjPerformMappingLatch( p, pObj );
|
||||
//printf( "\n\n" );
|
||||
// compute area and delay
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
p->RequiredGlo = If_ManDelayMax( p, 1 );
|
||||
p->AreaGlo = p->pPars->fLiftLeaves? If_ManScanMappingSeq(p) : If_ManScanMapping(p);
|
||||
printf( "S%d: Fi = %6.2f. Del = %6.2f. Area = %8.2f. Cuts = %8d. Lim = %2d. Ave = %5.2f. ",
|
||||
nIter, (float)p->Period, p->RequiredGlo, p->AreaGlo, p->nCutsMerged, p->nCutsUsed, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
|
||||
PRT( "T", clock() - clk );
|
||||
}
|
||||
return fChange;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects latches in the topological order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ManCollectLatches_rec( If_Obj_t * pObj, Vec_Ptr_t * vLatches )
|
||||
{
|
||||
if ( !If_ObjIsLatch(pObj) )
|
||||
return;
|
||||
if ( pObj->fMark )
|
||||
return;
|
||||
pObj->fMark = 1;
|
||||
If_ManCollectLatches_rec( pObj->pFanin0, vLatches );
|
||||
Vec_PtrPush( vLatches, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects latches in the topological order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * If_ManCollectLatches( If_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vLatches;
|
||||
If_Obj_t * pObj;
|
||||
int i;
|
||||
// collect latches
|
||||
vLatches = Vec_PtrAlloc( p->pPars->nLatches );
|
||||
Vec_PtrForEachEntryStart( p->vCis, pObj, i, If_ManCiNum(p) - p->pPars->nLatches )
|
||||
If_ManCollectLatches_rec( pObj, vLatches );
|
||||
// clean marks
|
||||
Vec_PtrForEachEntry( vLatches, pObj, i )
|
||||
pObj->fMark = 0;
|
||||
assert( Vec_PtrSize(vLatches) == p->pPars->nLatches );
|
||||
return vLatches;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares for sequential mapping by linking the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_ManPrepareMappingSeq( If_Man_t * p )
|
||||
{
|
||||
If_Obj_t * pObj, * pObjLi, * pObjLo, * pTemp;
|
||||
If_Cut_t * pCut;
|
||||
int i;
|
||||
// link the latch outputs (PIs) directly to the drivers of latch inputs (POs)
|
||||
for ( i = 0; i < p->pPars->nLatches; i++ )
|
||||
{
|
||||
pObjLo = If_ManCi( p, If_ManCiNum(p) - p->pPars->nLatches + i );
|
||||
pObjLi = If_ManCo( p, If_ManCoNum(p) - p->pPars->nLatches + i );
|
||||
pObjLo->pFanin0 = If_ObjFanin0( pObjLi );
|
||||
pObjLo->fCompl0 = If_ObjFaninC0( pObjLi );
|
||||
// pObjLo->pFanin0 = pObjLi;
|
||||
}
|
||||
// collect latches
|
||||
p->vLatchOrder = If_ManCollectLatches( p );
|
||||
// propagate elementary cuts
|
||||
if ( p->pPars->fLiftLeaves )
|
||||
{
|
||||
Vec_PtrForEachEntry( p->vLatchOrder, pObj, i )
|
||||
{
|
||||
pCut = If_ObjCutTriv(pObj);
|
||||
If_CutCopy( pCut, If_ObjFanin0(pObj)->Cuts );
|
||||
If_CutLift( pCut );
|
||||
pCut->Delay -= p->Period;
|
||||
pCut->fCompl ^= pObj->fCompl0;
|
||||
|
||||
pTemp = If_ManObj(p, pCut->pLeaves[0] >> 8);
|
||||
assert( !If_ObjIsLatch(pTemp) );
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs sequential mapping.]
|
||||
Synopsis [Performs mapping of the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -93,76 +376,36 @@ int If_ManPerformMappingSeq( If_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_CutLift( If_Cut_t * pCut )
|
||||
{
|
||||
unsigned i;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
pCut->pLeaves[i] = ((pCut->pLeaves[i] >> 8) << 8) | ((pCut->pLeaves[i] & 255) + 1);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs sequential mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ObjPerformMappingLI( If_Man_t * p, If_Obj_t * pLatch )
|
||||
int If_ObjPerformMappingLatch( If_Man_t * p, If_Obj_t * pObj )
|
||||
{
|
||||
If_Obj_t * pFanin;
|
||||
int c;
|
||||
assert( If_ObjIsPo(pLatch) );
|
||||
pFanin = If_ObjFanin0(pLatch);
|
||||
for ( c = 0; c < pFanin->nCuts; c++ )
|
||||
If_CutCopy( pLatch->Cuts + c, pFanin->Cuts + c );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs sequential mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ObjPerformMappingLO( If_Man_t * p, If_Obj_t * pLatch, If_Obj_t * pObj )
|
||||
{
|
||||
If_Cut_t * pCut;
|
||||
int c, Limit = IF_MIN( p->nCuts + 1, p->nCutsUsed );
|
||||
assert( If_ObjIsPo(pLatch) );
|
||||
for ( c = 1; c < Limit; c++ )
|
||||
float LValueOld;
|
||||
int i;
|
||||
assert( If_ObjIsLatch(pObj) );
|
||||
// save old l-value
|
||||
LValueOld = If_ObjLValue(pObj);
|
||||
pFanin = If_ObjFanin0(pObj);
|
||||
assert( pFanin->nCuts > 0 );
|
||||
if ( !p->pPars->fLiftLeaves )
|
||||
{
|
||||
pCut = pObj->Cuts + c;
|
||||
If_CutCopy( pCut, pLatch->Cuts + c - 1 );
|
||||
If_CutLift( pCut );
|
||||
pCut->Delay -= p->Fi;
|
||||
pObj->nCuts = 1;
|
||||
If_ObjSetLValue( pObj, If_ObjLValue(pFanin) - p->Period );
|
||||
}
|
||||
else
|
||||
{
|
||||
pObj->nCuts = pFanin->nCuts;
|
||||
If_ObjForEachCut( pObj, pCut, i )
|
||||
{
|
||||
If_CutCopy( pCut, pFanin->Cuts + i );
|
||||
If_CutLift( pCut );
|
||||
pCut->Delay -= p->Period;
|
||||
pCut->fCompl ^= pObj->fCompl0;
|
||||
}
|
||||
}
|
||||
return LValueOld != If_ObjLValue(pObj);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs sequential mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_ManMappingSeqConverged( If_Man_t * p )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ifLib.c]
|
||||
FileName [ifTime.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [FPGA mapping based on priority cuts.]
|
||||
|
||||
Synopsis [Computation of LUT paramters depending on the library.]
|
||||
Synopsis [Computation of delay paramters depending on the library.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
Date [Ver. 1.0. Started - November 21, 2006.]
|
||||
|
||||
Revision [$Id: ifLib.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: ifTime.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
|
@ -48,11 +48,12 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
|
|||
If_Obj_t * pLeaf;
|
||||
float Delay, DelayCur;
|
||||
float * pLutDelays;
|
||||
int i;
|
||||
assert( pCut->nLeaves > 1 );
|
||||
int i, Shift;
|
||||
assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
|
||||
Delay = -IF_FLOAT_LARGE;
|
||||
if ( p->pPars->pLutLib )
|
||||
{
|
||||
assert( !p->pPars->fLiftLeaves );
|
||||
pLutDelays = p->pPars->pLutLib->pLutDelays[pCut->nLeaves];
|
||||
if ( p->pPars->pLutLib->fVarPinDelays )
|
||||
{
|
||||
|
|
@ -77,6 +78,7 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
|
|||
{
|
||||
if ( pCut->fUser )
|
||||
{
|
||||
assert( !p->pPars->fLiftLeaves );
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
{
|
||||
DelayCur = If_ObjCutBest(pLeaf)->Delay + (float)pCut->pPerm[i];
|
||||
|
|
@ -85,10 +87,21 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
|
|||
}
|
||||
else
|
||||
{
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
if ( p->pPars->fLiftLeaves )
|
||||
{
|
||||
DelayCur = If_ObjCutBest(pLeaf)->Delay;
|
||||
Delay = IF_MAX( Delay, DelayCur );
|
||||
If_CutForEachLeafSeq( p, pCut, pLeaf, Shift, i )
|
||||
{
|
||||
DelayCur = If_ObjCutBest(pLeaf)->Delay - Shift * p->Period;
|
||||
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;
|
||||
}
|
||||
|
|
@ -115,6 +128,7 @@ void If_CutPropagateRequired( If_Man_t * p, If_Cut_t * pCut, float ObjRequired )
|
|||
float * pLutDelays;
|
||||
float Required;
|
||||
int i;
|
||||
assert( !p->pPars->fLiftLeaves );
|
||||
// compute the pins
|
||||
if ( p->pPars->pLutLib )
|
||||
{
|
||||
|
|
@ -28,43 +28,6 @@
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the max delay of the POs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float If_ManDelayMax( If_Man_t * p )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
float DelayBest;
|
||||
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;
|
||||
if ( p->pPars->fLatchPaths )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets all the node copy to NULL.]
|
||||
|
|
@ -105,6 +68,119 @@ void If_ManCleanCutData( If_Man_t * p )
|
|||
If_CutSetData( pCut, NULL );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets all visited marks to 0.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ManCleanMarkV( If_Man_t * p )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
int i;
|
||||
If_ManForEachObj( p, pObj, i )
|
||||
pObj->fVisit = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the max delay of the POs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float If_ManDelayMax( If_Man_t * p, int fSeq )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
float DelayBest;
|
||||
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;
|
||||
if ( fSeq )
|
||||
{
|
||||
assert( p->pPars->nLatches > 0 );
|
||||
If_ManForEachPo( p, pObj, i )
|
||||
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
|
||||
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
|
||||
}
|
||||
else if ( p->pPars->fLatchPaths )
|
||||
{
|
||||
If_ManForEachLatch( p, pObj, i )
|
||||
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
|
||||
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
If_ManForEachCo( p, pObj, i )
|
||||
if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
|
||||
DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
|
||||
}
|
||||
return DelayBest;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of all nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ManComputeRequired( If_Man_t * p, int fFirstTime )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
int i;
|
||||
// compute area, clean required times, collect nodes used in the mapping
|
||||
p->AreaGlo = If_ManScanMapping( p );
|
||||
// get the global required times
|
||||
p->RequiredGlo = If_ManDelayMax( p, 0 );
|
||||
// update the required times according to the target
|
||||
if ( p->pPars->DelayTarget != -1 )
|
||||
{
|
||||
if ( p->RequiredGlo > p->pPars->DelayTarget + p->fEpsilon )
|
||||
{
|
||||
if ( fFirstTime )
|
||||
printf( "Cannot meet the target required times (%4.2f). Mapping continues anyway.\n", p->pPars->DelayTarget );
|
||||
}
|
||||
else if ( p->RequiredGlo < p->pPars->DelayTarget - p->fEpsilon )
|
||||
{
|
||||
if ( fFirstTime )
|
||||
printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->RequiredGlo, p->pPars->DelayTarget );
|
||||
p->RequiredGlo = p->pPars->DelayTarget;
|
||||
}
|
||||
}
|
||||
// set the required times for the POs
|
||||
if ( p->pPars->fLatchPaths )
|
||||
{
|
||||
If_ManForEachLatch( p, pObj, i )
|
||||
If_ObjFanin0(pObj)->Required = p->RequiredGlo;
|
||||
}
|
||||
else
|
||||
{
|
||||
If_ManForEachCo( p, pObj, i )
|
||||
If_ObjFanin0(pObj)->Required = p->RequiredGlo;
|
||||
}
|
||||
// go through the nodes in the reverse topological order
|
||||
Vec_PtrForEachEntry( p->vMapped, pObj, i )
|
||||
If_CutPropagateRequired( p, If_ObjCutBest(pObj), pObj->Required );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area, references, and nodes used in the mapping.]
|
||||
|
|
@ -122,7 +198,7 @@ float If_ManScanMapping_rec( If_Man_t * p, If_Obj_t * pObj, If_Obj_t ** ppStore
|
|||
If_Cut_t * pCutBest;
|
||||
float aArea;
|
||||
int i;
|
||||
if ( pObj->nRefs++ || If_ObjIsPi(pObj) || If_ObjIsConst1(pObj) )
|
||||
if ( pObj->nRefs++ || If_ObjIsCi(pObj) || If_ObjIsConst1(pObj) )
|
||||
return 0.0;
|
||||
// store the node in the structure by level
|
||||
assert( If_ObjIsAnd(pObj) );
|
||||
|
|
@ -153,6 +229,7 @@ float If_ManScanMapping( If_Man_t * p )
|
|||
If_Obj_t * pObj, ** ppStore;
|
||||
float aArea;
|
||||
int i;
|
||||
assert( !p->pPars->fLiftLeaves );
|
||||
// clean all references
|
||||
If_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
|
|
@ -164,7 +241,7 @@ float If_ManScanMapping( If_Man_t * p )
|
|||
memset( ppStore, 0, sizeof(If_Obj_t *) * (p->nLevelMax + 1) );
|
||||
// collect nodes reachable from POs in the DFS order through the best cuts
|
||||
aArea = 0;
|
||||
If_ManForEachPo( p, pObj, i )
|
||||
If_ManForEachCo( p, pObj, i )
|
||||
aArea += If_ManScanMapping_rec( p, If_ObjFanin0(pObj), ppStore );
|
||||
// reconnect the nodes in reverse topological order
|
||||
Vec_PtrClear( p->vMapped );
|
||||
|
|
@ -177,7 +254,7 @@ float If_ManScanMapping( If_Man_t * p )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of all nodes.]
|
||||
Synopsis [Computes area, references, and nodes used in the mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -186,45 +263,54 @@ float If_ManScanMapping( If_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ManComputeRequired( If_Man_t * p, int fFirstTime )
|
||||
float If_ManScanMappingSeq_rec( If_Man_t * p, If_Obj_t * pObj, Vec_Ptr_t * vMapped )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
int i;
|
||||
// compute area, clean required times, collect nodes used in the mapping
|
||||
p->AreaGlo = If_ManScanMapping( p );
|
||||
// get the global required times
|
||||
p->RequiredGlo = If_ManDelayMax( p );
|
||||
// update the required times according to the target
|
||||
if ( p->pPars->DelayTarget != -1 )
|
||||
{
|
||||
if ( p->RequiredGlo > p->pPars->DelayTarget + p->fEpsilon )
|
||||
{
|
||||
if ( fFirstTime )
|
||||
printf( "Cannot meet the target required times (%4.2f). Mapping continues anyway.\n", p->pPars->DelayTarget );
|
||||
}
|
||||
else if ( p->RequiredGlo < p->pPars->DelayTarget - p->fEpsilon )
|
||||
{
|
||||
if ( fFirstTime )
|
||||
printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->RequiredGlo, p->pPars->DelayTarget );
|
||||
p->RequiredGlo = p->pPars->DelayTarget;
|
||||
}
|
||||
}
|
||||
// set the required times for the POs
|
||||
if ( p->pPars->fLatchPaths )
|
||||
{
|
||||
If_ManForEachLatch( p, pObj, i )
|
||||
If_ObjFanin0(pObj)->Required = p->RequiredGlo;
|
||||
}
|
||||
else
|
||||
{
|
||||
If_ManForEachPo( p, pObj, i )
|
||||
If_ObjFanin0(pObj)->Required = p->RequiredGlo;
|
||||
}
|
||||
// go through the nodes in the reverse topological order
|
||||
Vec_PtrForEachEntry( p->vMapped, pObj, i )
|
||||
If_CutPropagateRequired( p, If_ObjCutBest(pObj), pObj->Required );
|
||||
If_Obj_t * pLeaf;
|
||||
If_Cut_t * pCutBest;
|
||||
float aArea;
|
||||
int i, Shift;
|
||||
if ( pObj->nRefs++ || If_ObjIsCi(pObj) || If_ObjIsConst1(pObj) )
|
||||
return 0.0;
|
||||
// store the node in the structure by level
|
||||
assert( If_ObjIsAnd(pObj) );
|
||||
// visit the transitive fanin of the selected cut
|
||||
pCutBest = If_ObjCutBest(pObj);
|
||||
aArea = If_ObjIsAnd(pObj)? If_CutLutArea(p, pCutBest) : (float)0.0;
|
||||
If_CutForEachLeafSeq( p, pCutBest, pLeaf, Shift, i )
|
||||
aArea += If_ManScanMappingSeq_rec( p, pLeaf, vMapped );
|
||||
// add the node
|
||||
Vec_PtrPush( vMapped, pObj );
|
||||
return aArea;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area, references, and nodes used in the mapping.]
|
||||
|
||||
Description [Collects the nodes in reverse topological order in array
|
||||
p->vMapping.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float If_ManScanMappingSeq( If_Man_t * p )
|
||||
{
|
||||
If_Obj_t * pObj;
|
||||
float aArea;
|
||||
int i;
|
||||
assert( p->pPars->fLiftLeaves );
|
||||
// clean all references
|
||||
If_ManForEachObj( p, pObj, i )
|
||||
pObj->nRefs = 0;
|
||||
// collect nodes reachable from POs in the DFS order through the best cuts
|
||||
aArea = 0;
|
||||
Vec_PtrClear( p->vMapped );
|
||||
If_ManForEachPo( p, pObj, i )
|
||||
aArea += If_ManScanMappingSeq_rec( p, If_ObjFanin0(pObj), p->vMapped );
|
||||
return aArea;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
SRC += src/map/if/ifCore.c \
|
||||
src/map/if/ifCut.c \
|
||||
src/map/if/ifLib.c \
|
||||
src/map/if/ifMan.c \
|
||||
src/map/if/ifMap.c \
|
||||
src/map/if/ifPrepro.c \
|
||||
src/map/if/ifReduce.c \
|
||||
src/map/if/ifSeq.c \
|
||||
src/map/if/ifTime.c \
|
||||
src/map/if/ifTruth.c \
|
||||
src/map/if/ifUtil.c
|
||||
|
|
|
|||
|
|
@ -187,12 +187,22 @@ Nm_Entry_t * Nm_ManTableLookupId( Nm_Man_t * p, int ObjId )
|
|||
***********************************************************************/
|
||||
Nm_Entry_t * Nm_ManTableLookupName( Nm_Man_t * p, char * pName, int Type )
|
||||
{
|
||||
Nm_Entry_t * pEntry;
|
||||
Nm_Entry_t * pEntry, * pTemp;
|
||||
int Counter = 0;
|
||||
for ( pEntry = p->pBinsN2I[ Nm_HashString(pName, p->nBins) ]; pEntry; pEntry = pEntry->pNextN2I )
|
||||
{
|
||||
// check the entry itself
|
||||
if ( !strcmp(pEntry->Name, pName) && (Type == -1 || pEntry->Type == (unsigned)Type) )
|
||||
return pEntry;
|
||||
return pEntry;
|
||||
// if there is no namesakes, continue
|
||||
if ( pEntry->pNameSake == NULL )
|
||||
continue;
|
||||
// check the list of namesakes
|
||||
for ( pTemp = pEntry->pNameSake; pTemp != pEntry; pTemp = pTemp->pNameSake )
|
||||
if ( !strcmp(pTemp->Name, pName) && (Type == -1 || pTemp->Type == (unsigned)Type) )
|
||||
return pTemp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOn
|
|||
RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, fVerbose );
|
||||
break;
|
||||
case 6: // Pan's algorithm
|
||||
RetValue = Abc_NtkRetimeLValue( pNtk, 200, fVerbose );
|
||||
RetValue = Abc_NtkRetimeLValue( pNtk, 500, fVerbose );
|
||||
break;
|
||||
default:
|
||||
printf( "Unknown retiming option.\n" );
|
||||
|
|
|
|||
|
|
@ -90,13 +90,9 @@ int Abc_NtkRetimeMinDelayTry( Abc_Ntk_t * pNtk, int fForward, int fInitial, int
|
|||
pNtkNew = Abc_NtkRetimeBackwardInitialStart( pNtk );
|
||||
}
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( !fInitial )
|
||||
printf( "Performing analysis:\n" );
|
||||
else
|
||||
printf( "Moving latches to the best position:\n" );
|
||||
}
|
||||
|
||||
if ( fVerbose && !fInitial )
|
||||
printf( "Performing analysis:\n" );
|
||||
// find the best iteration
|
||||
DelayBest = ABC_INFINITY; IterBest = 0; LatchesBest = Abc_NtkLatchNum(pNtk);
|
||||
vCritical = Vec_PtrAlloc( 100 );
|
||||
|
|
@ -109,7 +105,7 @@ if ( fVerbose )
|
|||
// record this position if it has the best delay
|
||||
if ( DelayBest > DelayCur )
|
||||
{
|
||||
if ( fVerbose )
|
||||
if ( fVerbose && !fInitial )
|
||||
printf( "%s Iter = %3d. Delay = %3d. Latches = %5d. Delta = %6.2f. Ratio = %4.2f %%\n",
|
||||
fForward ? "Fwd": "Bwd", i, DelayCur, Abc_NtkLatchNum(pNtk),
|
||||
1.0*(Abc_NtkLatchNum(pNtk)-LatchesBest)/(DelayBest-DelayCur),
|
||||
|
|
@ -146,9 +142,9 @@ if ( fVerbose )
|
|||
Vec_IntFree( vValues );
|
||||
}
|
||||
}
|
||||
if ( !fInitial && fVerbose )
|
||||
printf( "%s : Starting delay = %3d. Final delay = %3d. IterBest = %2d (out of %2d).\n",
|
||||
fForward? "Forward " : "Backward", DelayStart, DelayBest, IterBest, nIterLimit );
|
||||
if ( fVerbose && !fInitial )
|
||||
printf( "%s : Starting delay = %3d. Final delay = %3d. IterBest = %2d (out of %2d).\n",
|
||||
fForward? "Forward " : "Backward", DelayStart, DelayBest, IterBest, nIterLimit );
|
||||
*pIterBest = IterBest;
|
||||
return DelayBest;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,11 +29,12 @@ enum { ABC_RET_UPDATE_FAIL, ABC_RET_UPDATE_NO, ABC_RET_UPDATE_YES };
|
|||
|
||||
// the internal procedures
|
||||
static Vec_Int_t * Abc_NtkRetimeGetLags( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose );
|
||||
static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int FiMin, int FiMax, int nMaxIters, int fVerbose );
|
||||
static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int Fi, int nMaxIters, int fVerbose );
|
||||
static int Abc_NtkRetimeUpdateLValue( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int Fi );
|
||||
static int Abc_NtkRetimePosOverLimit( Abc_Ntk_t * pNtk, int Fi );
|
||||
static Vec_Ptr_t * Abc_ManCollectLatches( Abc_Ntk_t * pNtk );
|
||||
static int Abc_NtkRetimeUsingLags( Abc_Ntk_t * pNtk, Vec_Int_t * vLags, int fVerbose );
|
||||
static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int FiMin, int FiMax, int nMaxIters, int fVerbose );
|
||||
static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int Fi, int nMaxIters, int fVerbose );
|
||||
static int Abc_NtkRetimeNodeUpdateLValue( Abc_Obj_t * pObj, int Fi );
|
||||
static Vec_Ptr_t * Abc_NtkRetimeCollect( Abc_Ntk_t * pNtk );
|
||||
|
||||
static inline int Abc_NodeComputeLag( int LValue, int Fi ) { return (LValue + (1<<16)*Fi)/Fi - (1<<16) - (int)(LValue % Fi == 0); }
|
||||
static inline int Abc_NodeGetLValue( Abc_Obj_t * pNode ) { return (int)pNode->pCopy; }
|
||||
|
|
@ -87,17 +88,18 @@ int Abc_NtkRetimeLValue( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose )
|
|||
Vec_Int_t * Abc_NtkRetimeGetLags( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vLags;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Vec_Ptr_t * vNodes, * vLatches;
|
||||
Abc_Obj_t * pNode;
|
||||
int i, FiMax, FiBest, RetValue, clk, clkIter;
|
||||
char NodeLag;
|
||||
|
||||
// get the upper bound on the clock period
|
||||
FiMax = 10 + Abc_NtkLevel(pNtk);
|
||||
FiMax = Abc_NtkLevel(pNtk);
|
||||
|
||||
// make sure this clock period is feasible
|
||||
vNodes = Abc_NtkRetimeCollect(pNtk);
|
||||
if ( !Abc_NtkRetimeForPeriod( pNtk, vNodes, FiMax, nIterLimit, fVerbose ) )
|
||||
vNodes = Abc_NtkDfs( pNtk, 0 );
|
||||
vLatches = Abc_ManCollectLatches( pNtk );
|
||||
if ( !Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, FiMax, nIterLimit, fVerbose ) )
|
||||
{
|
||||
Vec_PtrFree( vNodes );
|
||||
printf( "Abc_NtkRetimeGetLags() error: The upper bound on the clock period cannot be computed.\n" );
|
||||
|
|
@ -106,13 +108,12 @@ Vec_Int_t * Abc_NtkRetimeGetLags( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose
|
|||
|
||||
// search for the optimal clock period between 0 and nLevelMax
|
||||
clk = clock();
|
||||
FiBest = Abc_NtkRetimeSearch_rec( pNtk, vNodes, 0, FiMax, nIterLimit, fVerbose );
|
||||
FiBest = Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, 0, FiMax, nIterLimit, fVerbose );
|
||||
clkIter = clock() - clk;
|
||||
|
||||
// recompute the best l-values
|
||||
RetValue = Abc_NtkRetimeForPeriod( pNtk, vNodes, FiBest, nIterLimit, fVerbose );
|
||||
RetValue = Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, FiBest, nIterLimit, fVerbose );
|
||||
assert( RetValue );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
||||
// fix the problem with non-converged delays
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
|
|
@ -131,31 +132,16 @@ clkIter = clock() - clk;
|
|||
// if ( fVerbose )
|
||||
printf( "The best clock period is %3d. (Currently, network is not modified.)\n", FiBest );
|
||||
/*
|
||||
// print the statistic into a file
|
||||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "a/ret__stats.txt", "a+" );
|
||||
fprintf( pTable, "%d ", FiBest );
|
||||
fclose( pTable );
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
printf( "lvalues and lags : " );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
printf( "%d=%d(%d) ", pNode->Id, Abc_NodeGetLValue(pNode), Abc_NodeGetLag(pNode) );
|
||||
printf( "\n" );
|
||||
*/
|
||||
/*
|
||||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "a/ret_stats_pan.txt", "a+" );
|
||||
fprintf( pTable, "%s ", pNtk->pName );
|
||||
pTable = fopen( "a/seqmap__stats.txt", "a+" );
|
||||
fprintf( pTable, "%d ", FiBest );
|
||||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
*/
|
||||
Vec_PtrFree( vNodes );
|
||||
Vec_PtrFree( vLatches );
|
||||
return vLags;
|
||||
}
|
||||
|
||||
|
|
@ -170,17 +156,17 @@ clkIter = clock() - clk;
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int FiMin, int FiMax, int nMaxIters, int fVerbose )
|
||||
int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int FiMin, int FiMax, int nMaxIters, int fVerbose )
|
||||
{
|
||||
int Median;
|
||||
assert( FiMin < FiMax );
|
||||
if ( FiMin + 1 == FiMax )
|
||||
return FiMax;
|
||||
Median = FiMin + (FiMax - FiMin)/2;
|
||||
if ( Abc_NtkRetimeForPeriod( pNtk, vNodes, Median, nMaxIters, fVerbose ) )
|
||||
return Abc_NtkRetimeSearch_rec( pNtk, vNodes, FiMin, Median, nMaxIters, fVerbose ); // Median is feasible
|
||||
if ( Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, Median, nMaxIters, fVerbose ) )
|
||||
return Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, FiMin, Median, nMaxIters, fVerbose ); // Median is feasible
|
||||
else
|
||||
return Abc_NtkRetimeSearch_rec( pNtk, vNodes, Median, FiMax, nMaxIters, fVerbose ); // Median is infeasible
|
||||
return Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, Median, FiMax, nMaxIters, fVerbose ); // Median is infeasible
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -194,56 +180,35 @@ int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int FiMin, in
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int Fi, int nMaxIters, int fVerbose )
|
||||
int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int Fi, int nMaxIters, int fVerbose )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i, c, fContained, fChange, RetValue, Counter;
|
||||
char * pReason = "";
|
||||
|
||||
int c, i, fConverged;
|
||||
// set l-values of all nodes to be minus infinity, except PIs and constants
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 )
|
||||
Abc_NodeSetLValue( pObj, 0 );
|
||||
else
|
||||
Abc_NodeSetLValue( pObj, -ABC_INFINITY );
|
||||
|
||||
// update all values iteratively
|
||||
Counter = 0;
|
||||
fContained = 1;
|
||||
fChange = 1;
|
||||
for ( c = 0; fContained && fChange && c < nMaxIters; c++ )
|
||||
fConverged = 0;
|
||||
for ( c = 1; c <= nMaxIters; c++ )
|
||||
{
|
||||
// go through the nodes and detect change
|
||||
fChange = 0;
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
if ( !Abc_NtkRetimeUpdateLValue( pNtk, vNodes, vLatches, Fi ) )
|
||||
{
|
||||
RetValue = Abc_NtkRetimeNodeUpdateLValue( pObj, Fi );
|
||||
if ( RetValue == ABC_RET_UPDATE_FAIL )
|
||||
{
|
||||
fContained = 0;
|
||||
break;
|
||||
}
|
||||
if ( RetValue == ABC_RET_UPDATE_NO )
|
||||
continue;
|
||||
// updating happened
|
||||
fChange = 1;
|
||||
Counter++;
|
||||
fConverged = 1;
|
||||
break;
|
||||
}
|
||||
if ( Abc_NtkRetimePosOverLimit(pNtk, Fi) )
|
||||
break;
|
||||
}
|
||||
if ( c == nMaxIters )
|
||||
{
|
||||
fContained = 0;
|
||||
pReason = "(timeout)";
|
||||
}
|
||||
else
|
||||
c++;
|
||||
// report the results
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( !fContained )
|
||||
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Infeasible %s\n", Fi, c, Counter, pReason );
|
||||
if ( !fConverged )
|
||||
printf( "Period = %3d. Iterations = %3d. Infeasible %s\n", Fi, c, (c > nMaxIters)? "(timeout)" : "" );
|
||||
else
|
||||
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Feasible\n", Fi, c, Counter );
|
||||
printf( "Period = %3d. Iterations = %3d. Feasible\n", Fi, c );
|
||||
}
|
||||
/*
|
||||
// check if any AND gates have infinite delay
|
||||
|
|
@ -253,55 +218,126 @@ int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int Fi, int nM
|
|||
if ( Counter > 0 )
|
||||
printf( "Warning: %d internal nodes have wrong l-values!\n", Counter );
|
||||
*/
|
||||
return fContained;
|
||||
return fConverged;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the l-value of the node.]
|
||||
Synopsis [Performs one iteration of l-value computation for the nodes.]
|
||||
|
||||
Description [The node can be internal or a PO.]
|
||||
Description [Experimentally it was found that checking POs changes
|
||||
is not enough to detect the convergence of l-values in the network.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimeNodeUpdateLValue( Abc_Obj_t * pObj, int Fi )
|
||||
int Abc_NtkRetimeUpdateLValue( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int Fi )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int lValueNew, i;
|
||||
// terminals
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 )
|
||||
return ABC_RET_UPDATE_NO;
|
||||
// primary outputs
|
||||
if ( Abc_ObjIsPo(pObj) )
|
||||
return (Abc_NodeGetLValue(Abc_ObjFanin0(pObj)) > Fi)? ABC_RET_UPDATE_FAIL : ABC_RET_UPDATE_NO;
|
||||
// other types of objects
|
||||
if ( Abc_ObjIsBi(pObj) || Abc_ObjIsBo(pObj) )
|
||||
lValueNew = Abc_NodeGetLValue(Abc_ObjFanin0(pObj));
|
||||
else if ( Abc_ObjIsLatch(pObj) )
|
||||
lValueNew = Abc_NodeGetLValue(Abc_ObjFanin0(pObj)) - Fi;
|
||||
else
|
||||
Abc_Obj_t * pObj, * pFanin;
|
||||
int i, k, lValueNew, fChange;
|
||||
// go through the nodes and detect change
|
||||
fChange = 0;
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
lValueNew = -ABC_INFINITY;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
{
|
||||
if ( lValueNew < Abc_NodeGetLValue(pFanin) )
|
||||
lValueNew = Abc_NodeGetLValue(pFanin);
|
||||
}
|
||||
lValueNew++;
|
||||
if ( Abc_NodeGetLValue(pObj) < lValueNew )
|
||||
{
|
||||
Abc_NodeSetLValue( pObj, lValueNew );
|
||||
fChange = 1;
|
||||
}
|
||||
}
|
||||
// check if it needs to be updated
|
||||
if ( lValueNew <= Abc_NodeGetLValue(pObj) )
|
||||
return ABC_RET_UPDATE_NO;
|
||||
// update if needed
|
||||
Abc_NodeSetLValue( pObj, lValueNew );
|
||||
return ABC_RET_UPDATE_YES;
|
||||
// propagate values through the latches
|
||||
Vec_PtrForEachEntry( vLatches, pObj, i )
|
||||
Abc_NodeSetLValue( Abc_ObjFanout0(pObj), Abc_NodeGetLValue(Abc_ObjFanin0(Abc_ObjFanin0(pObj))) - Fi );
|
||||
return fChange;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements the retiming given as a set of retiming lags.]
|
||||
Synopsis [Detects the case when l-values exceeded the limit.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRetimePosOverLimit( Abc_Ntk_t * pNtk, int Fi )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
if ( Abc_NodeGetLValue(Abc_ObjFanin0(pObj)) > Fi )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects latches in the topological order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ManCollectLatches_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLatches )
|
||||
{
|
||||
Abc_Obj_t * pDriver;
|
||||
if ( !Abc_ObjIsLatch(pObj) )
|
||||
return;
|
||||
// skip already collected latches
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// get the driver node feeding into the latch
|
||||
pDriver = Abc_ObjFanin0(Abc_ObjFanin0(pObj));
|
||||
// call recursively if the driver looks like a latch output
|
||||
if ( Abc_ObjIsBo(pDriver) )
|
||||
Abc_ManCollectLatches_rec( Abc_ObjFanin0(pDriver), vLatches );
|
||||
// collect the latch
|
||||
Vec_PtrPush( vLatches, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects latches in the topological order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_ManCollectLatches( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vLatches;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
vLatches = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) );
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ManCollectLatches_rec( pObj, vLatches );
|
||||
assert( Vec_PtrSize(vLatches) == Abc_NtkLatchNum(pNtk) );
|
||||
return vLatches;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements the retiming given as the array of retiming lags.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -344,74 +380,6 @@ int Abc_NtkRetimeUsingLags( Abc_Ntk_t * pNtk, Vec_Int_t * vLags, int fVerbose )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect objects in the topological order from the latch inputs.]
|
||||
|
||||
Description [If flag fOnlyMarked is set, collects only marked nodes.
|
||||
Otherwise, collects only unmarked nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRetimeCollect_rec( Abc_Obj_t * pObj, int fOnlyMarked, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
// skip collected nodes
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// collect recursively
|
||||
if ( fOnlyMarked ^ pObj->fMarkA )
|
||||
return;
|
||||
// visit the fanins
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
Abc_NtkRetimeCollect_rec( pFanin, fOnlyMarked, vNodes );
|
||||
// collect non-trivial objects
|
||||
if ( Abc_ObjFaninNum(pObj) > 0 )
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect objects in the topological order using LIs as a cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_NtkRetimeCollect( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj, * pFanin;
|
||||
int i, k;
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
// mark the latch inputs
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjFanin0(pObj)->fMarkA = 1;
|
||||
// collect nodes in the DFS order from the marked nodes
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_NtkRetimeCollect_rec( pObj, 0, vNodes );
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjForEachFanin( Abc_ObjFanin0(pObj), pFanin, k )
|
||||
Abc_NtkRetimeCollect_rec( pFanin, 0, vNodes );
|
||||
// collect marked nodes
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_NtkRetimeCollect_rec( Abc_ObjFanin0(pObj), 1, vNodes );
|
||||
// clean the marks
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjFanin0(pObj)->fMarkA = 0;
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Reference in New Issue