mirror of https://github.com/YosysHQ/abc.git
Restoring Aaron Hurst's "fretime" command
This commit is contained in:
parent
229ee5df22
commit
91d8040bd6
2
Makefile
2
Makefile
|
|
@ -21,7 +21,7 @@ MODULES := \
|
|||
src/misc/vec src/misc/hash src/misc/tim src/misc/bzlib src/misc/zlib \
|
||||
src/misc/mem src/misc/bar src/misc/bbl src/misc/parse \
|
||||
src/opt/cut src/opt/fxu src/opt/rwr src/opt/mfs src/opt/sim \
|
||||
src/opt/ret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
|
||||
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
|
||||
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/sfm \
|
||||
src/sat/bsat src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \
|
||||
src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \
|
||||
|
|
|
|||
|
|
@ -18037,18 +18037,10 @@ int Abc_CommandFlowRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int fFastButConservative;
|
||||
int maxDelay;
|
||||
|
||||
if ( argc == 2 && !strcmp(argv[1], "-h") )
|
||||
{
|
||||
Abc_Print( -2, "The fretime command is temporarily disabled.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Abc_Print( -1, "This command is temporarily disabled.\n" );
|
||||
return 0;
|
||||
// extern Abc_Ntk_t* Abc_FlowRetime_MinReg( Abc_Ntk_t * pNtk, int fVerbose,
|
||||
// int fComputeInit, int fGuaranteeInit, int fBlockConst,
|
||||
// int fForward, int fBackward, int nMaxIters,
|
||||
// int maxDelay, int fFastButConservative);
|
||||
extern Abc_Ntk_t* Abc_FlowRetime_MinReg( Abc_Ntk_t * pNtk, int fVerbose,
|
||||
int fComputeInit, int fGuaranteeInit, int fBlockConst,
|
||||
int fForward, int fBackward, int nMaxIters,
|
||||
int maxDelay, int fFastButConservative);
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
// set defaults
|
||||
|
|
@ -18136,7 +18128,7 @@ int Abc_CommandFlowRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
if ( !Abc_NtkLatchNum(pNtk) )
|
||||
{
|
||||
// Abc_Print( -1, "The network has no latches. Retiming is not performed.\n" );
|
||||
Abc_Print( -1, "The network has no latches. Retiming is not performed.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -18147,10 +18139,10 @@ int Abc_CommandFlowRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
|
||||
// perform the retiming
|
||||
// pNtkRes = Abc_FlowRetime_MinReg( pNtk, fVerbose, fComputeInit,
|
||||
// fGuaranteeInit, fBlockConst,
|
||||
// fForward, fBackward,
|
||||
// nMaxIters, maxDelay, fFastButConservative );
|
||||
pNtkRes = Abc_FlowRetime_MinReg( pNtk, fVerbose, fComputeInit,
|
||||
fGuaranteeInit, fBlockConst,
|
||||
fForward, fBackward,
|
||||
nMaxIters, maxDelay, fFastButConservative );
|
||||
|
||||
if (pNtkRes != pNtk)
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,700 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fretFlow.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Flow-based retiming package.]
|
||||
|
||||
Synopsis [Max-flow computation.]
|
||||
|
||||
Author [Aaron Hurst]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - January 1, 2008.]
|
||||
|
||||
Revision [$Id: fretFlow.c,v 1.00 2008/01/01 00:00:00 ahurst Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fretime.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void dfsfast_e_retreat( Abc_Obj_t *pObj );
|
||||
static void dfsfast_r_retreat( Abc_Obj_t *pObj );
|
||||
|
||||
#define FDIST(xn, xe, yn, ye) (FDATA(xn)->xe##_dist == (FDATA(yn)->ye##_dist + 1))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fast DFS.]
|
||||
|
||||
Description [Uses sink-distance-histogram heuristic. May not find all
|
||||
flow paths: this occurs in a small number of cases where
|
||||
the flow predecessor points to a non-adjacent node and
|
||||
the distance ordering is perturbed.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
void dfsfast_preorder( Abc_Ntk_t *pNtk ) {
|
||||
Abc_Obj_t *pObj, *pNext;
|
||||
Vec_Ptr_t *vTimeIn, *qn = Vec_PtrAlloc(Abc_NtkObjNum(pNtk));
|
||||
Vec_Int_t *qe = Vec_IntAlloc(Abc_NtkObjNum(pNtk));
|
||||
int i, j, d = 0, end;
|
||||
int qpos = 0;
|
||||
|
||||
// create reverse timing edges for backward traversal
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay) {
|
||||
Abc_NtkForEachObj( pNtk, pObj, i ) {
|
||||
Vec_PtrForEachEntry( Abc_Obj_t *, FTIMEEDGES(pObj), pNext, j ) {
|
||||
vTimeIn = FDATA(pNext)->vNodes;
|
||||
if (!vTimeIn) {
|
||||
vTimeIn = FDATA(pNext)->vNodes = Vec_PtrAlloc(2);
|
||||
}
|
||||
Vec_PtrPush(vTimeIn, pObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// clear histogram
|
||||
assert(pManMR->vSinkDistHist);
|
||||
memset(Vec_IntArray(pManMR->vSinkDistHist), 0, sizeof(int)*Vec_IntSize(pManMR->vSinkDistHist));
|
||||
|
||||
// seed queue : latches, PIOs, and blocks
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if (Abc_ObjIsPo(pObj) ||
|
||||
Abc_ObjIsLatch(pObj) ||
|
||||
(pManMR->fIsForward && FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask)) {
|
||||
Vec_PtrPush(qn, pObj);
|
||||
Vec_IntPush(qe, 'r');
|
||||
FDATA(pObj)->r_dist = 1;
|
||||
} else if (Abc_ObjIsPi(pObj) ||
|
||||
(!pManMR->fIsForward && FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask)) {
|
||||
Vec_PtrPush(qn, pObj);
|
||||
Vec_IntPush(qe, 'e');
|
||||
FDATA(pObj)->e_dist = 1;
|
||||
}
|
||||
|
||||
// until queue is empty...
|
||||
while(qpos < Vec_PtrSize(qn)) {
|
||||
pObj = (Abc_Obj_t *)Vec_PtrEntry(qn, qpos);
|
||||
assert(pObj);
|
||||
end = Vec_IntEntry(qe, qpos);
|
||||
qpos++;
|
||||
|
||||
if (end == 'r') {
|
||||
d = FDATA(pObj)->r_dist;
|
||||
|
||||
// 1. structural edges
|
||||
if (pManMR->fIsForward) {
|
||||
Abc_ObjForEachFanin( pObj, pNext, i )
|
||||
if (!FDATA(pNext)->e_dist) {
|
||||
FDATA(pNext)->e_dist = d+1;
|
||||
Vec_PtrPush(qn, pNext);
|
||||
Vec_IntPush(qe, 'e');
|
||||
}
|
||||
} else
|
||||
Abc_ObjForEachFanout( pObj, pNext, i )
|
||||
if (!FDATA(pNext)->e_dist) {
|
||||
FDATA(pNext)->e_dist = d+1;
|
||||
Vec_PtrPush(qn, pNext);
|
||||
Vec_IntPush(qe, 'e');
|
||||
}
|
||||
|
||||
if (d == 1) continue;
|
||||
|
||||
// 2. reverse edges (forward retiming only)
|
||||
if (pManMR->fIsForward) {
|
||||
Abc_ObjForEachFanout( pObj, pNext, i )
|
||||
if (!FDATA(pNext)->r_dist && !Abc_ObjIsLatch(pNext)) {
|
||||
FDATA(pNext)->r_dist = d+1;
|
||||
Vec_PtrPush(qn, pNext);
|
||||
Vec_IntPush(qe, 'r');
|
||||
}
|
||||
|
||||
// 3. timimg edges (forward retiming only)
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay && FDATA(pObj)->vNodes)
|
||||
Vec_PtrForEachEntry(Abc_Obj_t *, FDATA(pObj)->vNodes, pNext, i ) {
|
||||
if (!FDATA(pNext)->r_dist) {
|
||||
FDATA(pNext)->r_dist = d+1;
|
||||
Vec_PtrPush(qn, pNext);
|
||||
Vec_IntPush(qe, 'r');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} else { // if 'e'
|
||||
if (Abc_ObjIsLatch(pObj)) continue;
|
||||
|
||||
d = FDATA(pObj)->e_dist;
|
||||
|
||||
// 1. through node
|
||||
if (!FDATA(pObj)->r_dist) {
|
||||
FDATA(pObj)->r_dist = d+1;
|
||||
Vec_PtrPush(qn, pObj);
|
||||
Vec_IntPush(qe, 'r');
|
||||
}
|
||||
|
||||
// 2. reverse edges (backward retiming only)
|
||||
if (!pManMR->fIsForward) {
|
||||
Abc_ObjForEachFanin( pObj, pNext, i )
|
||||
if (!FDATA(pNext)->e_dist && !Abc_ObjIsLatch(pNext)) {
|
||||
FDATA(pNext)->e_dist = d+1;
|
||||
Vec_PtrPush(qn, pNext);
|
||||
Vec_IntPush(qe, 'e');
|
||||
}
|
||||
|
||||
// 3. timimg edges (backward retiming only)
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay && FDATA(pObj)->vNodes)
|
||||
Vec_PtrForEachEntry(Abc_Obj_t *, FDATA(pObj)->vNodes, pNext, i ) {
|
||||
if (!FDATA(pNext)->e_dist) {
|
||||
FDATA(pNext)->e_dist = d+1;
|
||||
Vec_PtrPush(qn, pNext);
|
||||
Vec_IntPush(qe, 'e');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// free time edges
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay) {
|
||||
Abc_NtkForEachObj( pNtk, pObj, i ) {
|
||||
vTimeIn = FDATA(pObj)->vNodes;
|
||||
if (vTimeIn) {
|
||||
Vec_PtrFree(vTimeIn);
|
||||
FDATA(pObj)->vNodes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Abc_NtkForEachObj( pNtk, pObj, i ) {
|
||||
Vec_IntAddToEntry(pManMR->vSinkDistHist, FDATA(pObj)->r_dist, 1);
|
||||
Vec_IntAddToEntry(pManMR->vSinkDistHist, FDATA(pObj)->e_dist, 1);
|
||||
|
||||
#ifdef DEBUG_PREORDER
|
||||
printf("node %d\t: r=%d\te=%d\n", Abc_ObjId(pObj), FDATA(pObj)->r_dist, FDATA(pObj)->e_dist);
|
||||
#endif
|
||||
}
|
||||
|
||||
// printf("\t\tpre-ordered (max depth=%d)\n", d+1);
|
||||
|
||||
// deallocate
|
||||
Vec_PtrFree( qn );
|
||||
Vec_IntFree( qe );
|
||||
}
|
||||
|
||||
int dfsfast_e( Abc_Obj_t *pObj, Abc_Obj_t *pPred ) {
|
||||
int i;
|
||||
Abc_Obj_t *pNext;
|
||||
|
||||
if (pManMR->fSinkDistTerminate) return 0;
|
||||
|
||||
// have we reached the sink?
|
||||
if(FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask ||
|
||||
Abc_ObjIsPi(pObj)) {
|
||||
assert(pPred);
|
||||
assert(!pManMR->fIsForward);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FSET(pObj, VISITED_E);
|
||||
|
||||
#ifdef DEBUG_VISITED
|
||||
printf("(%de=%d) ", Abc_ObjId(pObj), FDATA(pObj)->e_dist);
|
||||
#endif
|
||||
|
||||
// 1. structural edges
|
||||
if (pManMR->fIsForward)
|
||||
Abc_ObjForEachFanout( pObj, pNext, i ) {
|
||||
if (!FTEST(pNext, VISITED_R) &&
|
||||
FDIST(pObj, e, pNext, r) &&
|
||||
dfsfast_r(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("o");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
else
|
||||
Abc_ObjForEachFanin( pObj, pNext, i ) {
|
||||
if (!FTEST(pNext, VISITED_R) &&
|
||||
FDIST(pObj, e, pNext, r) &&
|
||||
dfsfast_r(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("o");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if (Abc_ObjIsLatch(pObj))
|
||||
goto not_found;
|
||||
|
||||
// 2. reverse edges (backward retiming only)
|
||||
if (!pManMR->fIsForward) {
|
||||
Abc_ObjForEachFanout( pObj, pNext, i ) {
|
||||
if (!FTEST(pNext, VISITED_E) &&
|
||||
FDIST(pObj, e, pNext, e) &&
|
||||
dfsfast_e(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("i");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. timing edges (backward retiming only)
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay)
|
||||
Vec_PtrForEachEntry(Abc_Obj_t *, FTIMEEDGES(pObj), pNext, i) {
|
||||
if (!FTEST(pNext, VISITED_E) &&
|
||||
FDIST(pObj, e, pNext, e) &&
|
||||
dfsfast_e(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("o");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// unwind
|
||||
if (FTEST(pObj, FLOW) &&
|
||||
!FTEST(pObj, VISITED_R) &&
|
||||
FDIST(pObj, e, pObj, r) &&
|
||||
dfsfast_r(pObj, FGETPRED(pObj))) {
|
||||
|
||||
FUNSET(pObj, FLOW);
|
||||
FSETPRED(pObj, NULL);
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("u");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
|
||||
not_found:
|
||||
FUNSET(pObj, VISITED_E);
|
||||
dfsfast_e_retreat(pObj);
|
||||
return 0;
|
||||
|
||||
found:
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("%d ", Abc_ObjId(pObj));
|
||||
#endif
|
||||
FUNSET(pObj, VISITED_E);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dfsfast_r( Abc_Obj_t *pObj, Abc_Obj_t *pPred ) {
|
||||
int i;
|
||||
Abc_Obj_t *pNext, *pOldPred;
|
||||
|
||||
if (pManMR->fSinkDistTerminate) return 0;
|
||||
|
||||
#ifdef DEBUG_VISITED
|
||||
printf("(%dr=%d) ", Abc_ObjId(pObj), FDATA(pObj)->r_dist);
|
||||
#endif
|
||||
|
||||
// have we reached the sink?
|
||||
if (Abc_ObjIsLatch(pObj) ||
|
||||
(pManMR->fIsForward && Abc_ObjIsPo(pObj)) ||
|
||||
(pManMR->fIsForward && FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask)) {
|
||||
assert(pPred);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FSET(pObj, VISITED_R);
|
||||
|
||||
if (FTEST(pObj, FLOW)) {
|
||||
|
||||
pOldPred = FGETPRED(pObj);
|
||||
if (pOldPred &&
|
||||
!FTEST(pOldPred, VISITED_E) &&
|
||||
FDIST(pObj, r, pOldPred, e) &&
|
||||
dfsfast_e(pOldPred, pOldPred)) {
|
||||
|
||||
FSETPRED(pObj, pPred);
|
||||
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("fr");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (!FTEST(pObj, VISITED_E) &&
|
||||
FDIST(pObj, r, pObj, e) &&
|
||||
dfsfast_e(pObj, pObj)) {
|
||||
|
||||
FSET(pObj, FLOW);
|
||||
FSETPRED(pObj, pPred);
|
||||
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("f");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. reverse edges (forward retiming only)
|
||||
if (pManMR->fIsForward) {
|
||||
Abc_ObjForEachFanin( pObj, pNext, i ) {
|
||||
if (!FTEST(pNext, VISITED_R) &&
|
||||
FDIST(pObj, r, pNext, r) &&
|
||||
!Abc_ObjIsLatch(pNext) &&
|
||||
dfsfast_r(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("i");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. timing edges (forward retiming only)
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay)
|
||||
Vec_PtrForEachEntry(Abc_Obj_t*, FTIMEEDGES(pObj), pNext, i) {
|
||||
if (!FTEST(pNext, VISITED_R) &&
|
||||
FDIST(pObj, r, pNext, r) &&
|
||||
dfsfast_r(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("o");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
FUNSET(pObj, VISITED_R);
|
||||
dfsfast_r_retreat(pObj);
|
||||
return 0;
|
||||
|
||||
found:
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("%d ", Abc_ObjId(pObj));
|
||||
#endif
|
||||
FUNSET(pObj, VISITED_R);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
dfsfast_e_retreat(Abc_Obj_t *pObj) {
|
||||
Abc_Obj_t *pNext;
|
||||
int i, *h;
|
||||
int old_dist = FDATA(pObj)->e_dist;
|
||||
int adj_dist, min_dist = MAX_DIST;
|
||||
|
||||
// 1. structural edges
|
||||
if (pManMR->fIsForward)
|
||||
Abc_ObjForEachFanout( pObj, pNext, i ) {
|
||||
adj_dist = FDATA(pNext)->r_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
else
|
||||
Abc_ObjForEachFanin( pObj, pNext, i ) {
|
||||
adj_dist = FDATA(pNext)->r_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
|
||||
if (Abc_ObjIsLatch(pObj)) goto update;
|
||||
|
||||
// 2. through
|
||||
if (FTEST(pObj, FLOW)) {
|
||||
adj_dist = FDATA(pObj)->r_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
|
||||
// 3. reverse edges (backward retiming only)
|
||||
if (!pManMR->fIsForward) {
|
||||
Abc_ObjForEachFanout( pObj, pNext, i ) {
|
||||
adj_dist = FDATA(pNext)->e_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
|
||||
// 4. timing edges (backward retiming only)
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay)
|
||||
Vec_PtrForEachEntry(Abc_Obj_t*, FTIMEEDGES(pObj), pNext, i) {
|
||||
adj_dist = FDATA(pNext)->e_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
update:
|
||||
++min_dist;
|
||||
if (min_dist >= MAX_DIST) min_dist = 0;
|
||||
// printf("[%de=%d->%d] ", Abc_ObjId(pObj), old_dist, min_dist+1);
|
||||
FDATA(pObj)->e_dist = min_dist;
|
||||
|
||||
assert(min_dist < Vec_IntSize(pManMR->vSinkDistHist));
|
||||
h = Vec_IntArray(pManMR->vSinkDistHist);
|
||||
h[old_dist]--;
|
||||
h[min_dist]++;
|
||||
if (!h[old_dist]) {
|
||||
pManMR->fSinkDistTerminate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dfsfast_r_retreat(Abc_Obj_t *pObj) {
|
||||
Abc_Obj_t *pNext;
|
||||
int i, *h;
|
||||
int old_dist = FDATA(pObj)->r_dist;
|
||||
int adj_dist, min_dist = MAX_DIST;
|
||||
|
||||
// 1. through or pred
|
||||
if (FTEST(pObj, FLOW)) {
|
||||
if (FGETPRED(pObj)) {
|
||||
adj_dist = FDATA(FGETPRED(pObj))->e_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
} else {
|
||||
adj_dist = FDATA(pObj)->e_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
|
||||
// 2. reverse edges (forward retiming only)
|
||||
if (pManMR->fIsForward) {
|
||||
Abc_ObjForEachFanin( pObj, pNext, i )
|
||||
if (!Abc_ObjIsLatch(pNext)) {
|
||||
adj_dist = FDATA(pNext)->r_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
|
||||
// 3. timing edges (forward retiming only)
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay)
|
||||
Vec_PtrForEachEntry(Abc_Obj_t*, FTIMEEDGES(pObj), pNext, i) {
|
||||
adj_dist = FDATA(pNext)->r_dist;
|
||||
if (adj_dist) min_dist = MIN(min_dist, adj_dist);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
++min_dist;
|
||||
if (min_dist >= MAX_DIST) min_dist = 0;
|
||||
//printf("[%dr=%d->%d] ", Abc_ObjId(pObj), old_dist, min_dist+1);
|
||||
FDATA(pObj)->r_dist = min_dist;
|
||||
|
||||
assert(min_dist < Vec_IntSize(pManMR->vSinkDistHist));
|
||||
h = Vec_IntArray(pManMR->vSinkDistHist);
|
||||
h[old_dist]--;
|
||||
h[min_dist]++;
|
||||
if (!h[old_dist]) {
|
||||
pManMR->fSinkDistTerminate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Plain DFS.]
|
||||
|
||||
Description [Does not use sink-distance-histogram heuristic.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
int dfsplain_e( Abc_Obj_t *pObj, Abc_Obj_t *pPred ) {
|
||||
int i;
|
||||
Abc_Obj_t *pNext;
|
||||
|
||||
if (FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask ||
|
||||
Abc_ObjIsPi(pObj)) {
|
||||
assert(pPred);
|
||||
assert(!pManMR->fIsForward);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FSET(pObj, VISITED_E);
|
||||
|
||||
// printf(" %de\n", Abc_ObjId(pObj));
|
||||
|
||||
// 1. structural edges
|
||||
if (pManMR->fIsForward)
|
||||
Abc_ObjForEachFanout( pObj, pNext, i ) {
|
||||
if (!FTEST(pNext, VISITED_R) &&
|
||||
dfsplain_r(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("o");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
else
|
||||
Abc_ObjForEachFanin( pObj, pNext, i ) {
|
||||
if (!FTEST(pNext, VISITED_R) &&
|
||||
dfsplain_r(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("o");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if (Abc_ObjIsLatch(pObj))
|
||||
return 0;
|
||||
|
||||
// 2. reverse edges (backward retiming only)
|
||||
if (!pManMR->fIsForward) {
|
||||
Abc_ObjForEachFanout( pObj, pNext, i ) {
|
||||
if (!FTEST(pNext, VISITED_E) &&
|
||||
dfsplain_e(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("i");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. timing edges (backward retiming only)
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay)
|
||||
Vec_PtrForEachEntry(Abc_Obj_t*, FTIMEEDGES(pObj), pNext, i) {
|
||||
if (!FTEST(pNext, VISITED_E) &&
|
||||
dfsplain_e(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("o");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// unwind
|
||||
if (FTEST(pObj, FLOW) &&
|
||||
!FTEST(pObj, VISITED_R) &&
|
||||
dfsplain_r(pObj, FGETPRED(pObj))) {
|
||||
FUNSET(pObj, FLOW);
|
||||
FSETPRED(pObj, NULL);
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("u");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
found:
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("%d ", Abc_ObjId(pObj));
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dfsplain_r( Abc_Obj_t *pObj, Abc_Obj_t *pPred ) {
|
||||
int i;
|
||||
Abc_Obj_t *pNext, *pOldPred;
|
||||
|
||||
// have we reached the sink?
|
||||
if (Abc_ObjIsLatch(pObj) ||
|
||||
(pManMR->fIsForward && Abc_ObjIsPo(pObj)) ||
|
||||
(pManMR->fIsForward && FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask)) {
|
||||
assert(pPred);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FSET(pObj, VISITED_R);
|
||||
|
||||
// printf(" %dr\n", Abc_ObjId(pObj));
|
||||
|
||||
if (FTEST(pObj, FLOW)) {
|
||||
|
||||
pOldPred = FGETPRED(pObj);
|
||||
if (pOldPred &&
|
||||
!FTEST(pOldPred, VISITED_E) &&
|
||||
dfsplain_e(pOldPred, pOldPred)) {
|
||||
|
||||
FSETPRED(pObj, pPred);
|
||||
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("fr");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (!FTEST(pObj, VISITED_E) &&
|
||||
dfsplain_e(pObj, pObj)) {
|
||||
|
||||
FSET(pObj, FLOW);
|
||||
FSETPRED(pObj, pPred);
|
||||
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("f");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. follow reverse edges
|
||||
if (pManMR->fIsForward) { // forward retiming only
|
||||
Abc_ObjForEachFanin( pObj, pNext, i ) {
|
||||
if (!FTEST(pNext, VISITED_R) &&
|
||||
!Abc_ObjIsLatch(pNext) &&
|
||||
dfsplain_r(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("i");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. timing edges (forward only)
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->maxDelay)
|
||||
Vec_PtrForEachEntry(Abc_Obj_t*, FTIMEEDGES(pObj), pNext, i) {
|
||||
if (!FTEST(pNext, VISITED_R) &&
|
||||
dfsplain_r(pNext, pPred)) {
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("o");
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
found:
|
||||
#ifdef DEBUG_PRINT_FLOWS
|
||||
printf("%d ", Abc_ObjId(pObj));
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,766 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fretTime.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Flow-based retiming package.]
|
||||
|
||||
Synopsis [Delay-constrained retiming code.]
|
||||
|
||||
Author [Aaron Hurst]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - January 1, 2008.]
|
||||
|
||||
Revision [$Id: fretTime.c,v 1.00 2008/01/01 00:00:00 ahurst Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fretime.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Abc_FlowRetime_Dfs_forw( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes );
|
||||
static void Abc_FlowRetime_Dfs_back( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes );
|
||||
|
||||
static void Abc_FlowRetime_ConstrainExact_forw( Abc_Obj_t * pObj );
|
||||
static void Abc_FlowRetime_ConstrainExact_back( Abc_Obj_t * pObj );
|
||||
static void Abc_FlowRetime_ConstrainConserv_forw( Abc_Ntk_t * pNtk );
|
||||
static void Abc_FlowRetime_ConstrainConserv_back( Abc_Ntk_t * pNtk );
|
||||
|
||||
|
||||
void trace2(Abc_Obj_t *pObj) {
|
||||
Abc_Obj_t *pNext;
|
||||
int i;
|
||||
|
||||
print_node(pObj);
|
||||
Abc_ObjForEachFanin(pObj, pNext, i)
|
||||
if (pNext->Level >= pObj->Level - 1) {
|
||||
trace2(pNext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Initializes timing]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FlowRetime_InitTiming( Abc_Ntk_t *pNtk ) {
|
||||
|
||||
pManMR->nConservConstraints = pManMR->nExactConstraints = 0;
|
||||
|
||||
pManMR->vExactNodes = Vec_PtrAlloc(1000);
|
||||
|
||||
pManMR->vTimeEdges = ABC_ALLOC( Vec_Ptr_t, Abc_NtkObjNumMax(pNtk)+1 );
|
||||
assert(pManMR->vTimeEdges);
|
||||
memset(pManMR->vTimeEdges, 0, (Abc_NtkObjNumMax(pNtk)+1) * sizeof(Vec_Ptr_t) );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Marks nodes with conservative constraints.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FlowRetime_ConstrainConserv( Abc_Ntk_t * pNtk ) {
|
||||
Abc_Obj_t *pObj;
|
||||
int i;
|
||||
void *pArray;
|
||||
|
||||
// clear all exact constraints
|
||||
pManMR->nExactConstraints = 0;
|
||||
while( Vec_PtrSize( pManMR->vExactNodes )) {
|
||||
pObj = Vec_PtrPop( pManMR->vExactNodes );
|
||||
|
||||
if ( Vec_PtrSize( FTIMEEDGES(pObj) )) {
|
||||
pArray = Vec_PtrReleaseArray( FTIMEEDGES(pObj) );
|
||||
ABC_FREE( pArray );
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->fIsForward) {
|
||||
Abc_FlowRetime_ConstrainConserv_forw(pNtk);
|
||||
} else {
|
||||
Abc_FlowRetime_ConstrainConserv_back(pNtk);
|
||||
}
|
||||
#endif
|
||||
|
||||
Abc_NtkForEachObj( pNtk, pObj, i)
|
||||
assert( !Vec_PtrSize(FTIMEEDGES(pObj)) );
|
||||
}
|
||||
|
||||
|
||||
void Abc_FlowRetime_ConstrainConserv_forw( Abc_Ntk_t * pNtk ) {
|
||||
Vec_Ptr_t *vNodes = pManMR->vNodes;
|
||||
Abc_Obj_t *pObj, *pNext, *pBi, *pBo;
|
||||
int i, j;
|
||||
|
||||
assert(!Vec_PtrSize( vNodes ));
|
||||
pManMR->nConservConstraints = 0;
|
||||
|
||||
// 1. hard constraints
|
||||
|
||||
// (i) collect TFO of PIs
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Abc_NtkForEachPi(pNtk, pObj, i)
|
||||
Abc_FlowRetime_Dfs_forw( pObj, vNodes );
|
||||
|
||||
// ... propagate values
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
Abc_ObjForEachFanin( pObj, pNext, j )
|
||||
{
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) &&
|
||||
pObj->Level < pNext->Level )
|
||||
pObj->Level = pNext->Level;
|
||||
}
|
||||
pObj->Level += Abc_ObjIsNode(pObj) ? 1 : 0;
|
||||
|
||||
if ( Abc_ObjIsBi(pObj) )
|
||||
pObj->fMarkA = 1;
|
||||
|
||||
assert(pObj->Level <= pManMR->maxDelay);
|
||||
}
|
||||
|
||||
// collect TFO of latches
|
||||
// seed arrival times from BIs
|
||||
Vec_PtrClear(vNodes);
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Abc_NtkForEachLatch(pNtk, pObj, i) {
|
||||
pBo = Abc_ObjFanout0( pObj );
|
||||
pBi = Abc_ObjFanin0( pObj );
|
||||
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
Abc_FlowRetime_Dfs_forw( pBo, vNodes );
|
||||
|
||||
if (pBi->fMarkA) {
|
||||
pBi->fMarkA = 0;
|
||||
pObj->Level = pBi->Level;
|
||||
assert(pObj->Level <= pManMR->maxDelay);
|
||||
} else
|
||||
pObj->Level = 0;
|
||||
}
|
||||
|
||||
#if defined(DEBUG_CHECK)
|
||||
// DEBUG: check DFS ordering
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->fMarkB = 1;
|
||||
|
||||
Abc_ObjForEachFanin( pObj, pNext, j )
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) && !Abc_ObjIsLatch(pNext))
|
||||
assert(pNext->fMarkB);
|
||||
}
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i)
|
||||
pObj->fMarkB = 0;
|
||||
#endif
|
||||
|
||||
// ... propagate values
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
Abc_ObjForEachFanin( pObj, pNext, j )
|
||||
{
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) &&
|
||||
pObj->Level < pNext->Level )
|
||||
pObj->Level = pNext->Level;
|
||||
}
|
||||
pObj->Level += Abc_ObjIsNode(pObj) ? 1 : 0;
|
||||
|
||||
if (pObj->Level > pManMR->maxDelay) {
|
||||
FSET(pObj, BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. conservative constraints
|
||||
|
||||
// first pass: seed latches with T=0
|
||||
Abc_NtkForEachLatch(pNtk, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
}
|
||||
|
||||
// ... propagate values
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
Abc_ObjForEachFanin( pObj, pNext, j ) {
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) &&
|
||||
pObj->Level < pNext->Level )
|
||||
pObj->Level = pNext->Level;
|
||||
}
|
||||
pObj->Level += Abc_ObjIsNode(pObj) ? 1 : 0;
|
||||
|
||||
if ( Abc_ObjIsBi(pObj) )
|
||||
pObj->fMarkA = 1;
|
||||
|
||||
assert(pObj->Level <= pManMR->maxDelay);
|
||||
}
|
||||
|
||||
Abc_NtkForEachLatch(pNtk, pObj, i) {
|
||||
pBo = Abc_ObjFanout0( pObj );
|
||||
pBi = Abc_ObjFanin0( pObj );
|
||||
|
||||
if (pBi->fMarkA) {
|
||||
pBi->fMarkA = 0;
|
||||
pObj->Level = pBi->Level;
|
||||
assert(pObj->Level <= pManMR->maxDelay);
|
||||
} else
|
||||
pObj->Level = 0;
|
||||
}
|
||||
|
||||
// ... propagate values
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
Abc_ObjForEachFanin( pObj, pNext, j ) {
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) &&
|
||||
pObj->Level < pNext->Level )
|
||||
pObj->Level = pNext->Level;
|
||||
}
|
||||
pObj->Level += Abc_ObjIsNode(pObj) ? 1 : 0;
|
||||
|
||||
// constrained?
|
||||
if (pObj->Level > pManMR->maxDelay) {
|
||||
FSET( pObj, CONSERVATIVE );
|
||||
pManMR->nConservConstraints++;
|
||||
} else
|
||||
FUNSET( pObj, CONSERVATIVE );
|
||||
}
|
||||
|
||||
Vec_PtrClear( vNodes );
|
||||
}
|
||||
|
||||
|
||||
void Abc_FlowRetime_ConstrainConserv_back( Abc_Ntk_t * pNtk ) {
|
||||
Vec_Ptr_t *vNodes = pManMR->vNodes;
|
||||
Abc_Obj_t *pObj, *pNext, *pBi, *pBo;
|
||||
int i, j, l;
|
||||
|
||||
assert(!Vec_PtrSize(vNodes));
|
||||
|
||||
pManMR->nConservConstraints = 0;
|
||||
|
||||
// 1. hard constraints
|
||||
|
||||
// (i) collect TFO of POs
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Abc_NtkForEachPo(pNtk, pObj, i)
|
||||
Abc_FlowRetime_Dfs_back( pObj, vNodes );
|
||||
|
||||
// ... propagate values
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
Abc_ObjForEachFanout( pObj, pNext, j )
|
||||
{
|
||||
l = pNext->Level + (Abc_ObjIsNode(pObj) ? 1 : 0);
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) &&
|
||||
pObj->Level < l )
|
||||
pObj->Level = l;
|
||||
}
|
||||
|
||||
if ( Abc_ObjIsBo(pObj) )
|
||||
pObj->fMarkA = 1;
|
||||
|
||||
assert(pObj->Level <= pManMR->maxDelay);
|
||||
}
|
||||
|
||||
// collect TFO of latches
|
||||
// seed arrival times from BIs
|
||||
Vec_PtrClear(vNodes);
|
||||
Abc_NtkIncrementTravId(pNtk);
|
||||
Abc_NtkForEachLatch(pNtk, pObj, i) {
|
||||
pBo = Abc_ObjFanout0( pObj );
|
||||
pBi = Abc_ObjFanin0( pObj );
|
||||
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
Abc_FlowRetime_Dfs_back( pBi, vNodes );
|
||||
|
||||
if (pBo->fMarkA) {
|
||||
pBo->fMarkA = 0;
|
||||
pObj->Level = pBo->Level;
|
||||
assert(pObj->Level <= pManMR->maxDelay);
|
||||
} else
|
||||
pObj->Level = 0;
|
||||
}
|
||||
|
||||
#if defined(DEBUG_CHECK)
|
||||
// DEBUG: check DFS ordering
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->fMarkB = 1;
|
||||
|
||||
Abc_ObjForEachFanout( pObj, pNext, j )
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) && !Abc_ObjIsLatch(pNext))
|
||||
assert(pNext->fMarkB);
|
||||
}
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i)
|
||||
pObj->fMarkB = 0;
|
||||
#endif
|
||||
|
||||
// ... propagate values
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
Abc_ObjForEachFanout( pObj, pNext, j )
|
||||
{
|
||||
l = pNext->Level + (Abc_ObjIsNode(pObj) ? 1 : 0);
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) &&
|
||||
pObj->Level < l )
|
||||
pObj->Level = l;
|
||||
}
|
||||
|
||||
if (pObj->Level + (Abc_ObjIsNode(pObj)?1:0) > pManMR->maxDelay) {
|
||||
FSET(pObj, BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. conservative constraints
|
||||
|
||||
// first pass: seed latches with T=0
|
||||
Abc_NtkForEachLatch(pNtk, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
}
|
||||
|
||||
// ... propagate values
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
Abc_ObjForEachFanout( pObj, pNext, j ) {
|
||||
l = pNext->Level + (Abc_ObjIsNode(pObj) ? 1 : 0);
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) &&
|
||||
pObj->Level < l )
|
||||
pObj->Level = l;
|
||||
}
|
||||
|
||||
if ( Abc_ObjIsBo(pObj) ) {
|
||||
pObj->fMarkA = 1;
|
||||
}
|
||||
|
||||
assert(pObj->Level <= pManMR->maxDelay);
|
||||
}
|
||||
|
||||
Abc_NtkForEachLatch(pNtk, pObj, i) {
|
||||
pBo = Abc_ObjFanout0( pObj );
|
||||
assert(Abc_ObjIsBo(pBo));
|
||||
pBi = Abc_ObjFanin0( pObj );
|
||||
assert(Abc_ObjIsBi(pBi));
|
||||
|
||||
if (pBo->fMarkA) {
|
||||
pBo->fMarkA = 0;
|
||||
pObj->Level = pBo->Level;
|
||||
} else
|
||||
pObj->Level = 0;
|
||||
}
|
||||
|
||||
// ... propagate values
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *,vNodes, pObj, i) {
|
||||
pObj->Level = 0;
|
||||
Abc_ObjForEachFanout( pObj, pNext, j ) {
|
||||
l = pNext->Level + (Abc_ObjIsNode(pObj) ? 1 : 0);
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) &&
|
||||
pObj->Level < l )
|
||||
pObj->Level = l;
|
||||
}
|
||||
|
||||
// constrained?
|
||||
if (pObj->Level > pManMR->maxDelay) {
|
||||
FSET( pObj, CONSERVATIVE );
|
||||
pManMR->nConservConstraints++;
|
||||
} else
|
||||
FUNSET( pObj, CONSERVATIVE );
|
||||
}
|
||||
|
||||
Vec_PtrClear( vNodes );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Introduces exact timing constraints for a node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FlowRetime_ConstrainExact( Abc_Obj_t * pObj ) {
|
||||
|
||||
if (FTEST( pObj, CONSERVATIVE )) {
|
||||
pManMR->nConservConstraints--;
|
||||
FUNSET( pObj, CONSERVATIVE );
|
||||
}
|
||||
|
||||
#if !defined(IGNORE_TIMING)
|
||||
if (pManMR->fIsForward) {
|
||||
Abc_FlowRetime_ConstrainExact_forw(pObj);
|
||||
} else {
|
||||
Abc_FlowRetime_ConstrainExact_back(pObj);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Abc_FlowRetime_ConstrainExact_forw_rec( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes, int latch ) {
|
||||
Abc_Obj_t *pNext;
|
||||
int i;
|
||||
|
||||
// terminate?
|
||||
if (Abc_ObjIsLatch(pObj)) {
|
||||
if (latch) return;
|
||||
latch = 1;
|
||||
}
|
||||
|
||||
// already visited?
|
||||
if (!latch) {
|
||||
if (pObj->fMarkA) return;
|
||||
pObj->fMarkA = 1;
|
||||
} else {
|
||||
if (pObj->fMarkB) return;
|
||||
pObj->fMarkB = 1;
|
||||
}
|
||||
|
||||
// recurse
|
||||
Abc_ObjForEachFanin(pObj, pNext, i) {
|
||||
Abc_FlowRetime_ConstrainExact_forw_rec( pNext, vNodes, latch );
|
||||
}
|
||||
|
||||
// add
|
||||
pObj->Level = 0;
|
||||
Vec_PtrPush(vNodes, Abc_ObjNotCond(pObj, latch));
|
||||
}
|
||||
|
||||
void Abc_FlowRetime_ConstrainExact_forw( Abc_Obj_t * pObj ) {
|
||||
Vec_Ptr_t *vNodes = pManMR->vNodes;
|
||||
Abc_Obj_t *pNext, *pCur, *pReg;
|
||||
// Abc_Ntk_t *pNtk = pManMR->pNtk;
|
||||
int i, j;
|
||||
|
||||
assert( !Vec_PtrSize(vNodes) );
|
||||
assert( !Abc_ObjIsLatch(pObj) );
|
||||
assert( !Vec_PtrSize( FTIMEEDGES(pObj) ));
|
||||
Vec_PtrPush( pManMR->vExactNodes, pObj );
|
||||
|
||||
// rev topo order
|
||||
Abc_FlowRetime_ConstrainExact_forw_rec( pObj, vNodes, 0 );
|
||||
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pCur, i) {
|
||||
pReg = Abc_ObjRegular( pCur );
|
||||
|
||||
if (pReg == pCur) {
|
||||
assert(!Abc_ObjIsLatch(pReg));
|
||||
Abc_ObjForEachFanin(pReg, pNext, j)
|
||||
pNext->Level = MAX( pNext->Level, pReg->Level + (Abc_ObjIsNode(pReg)?1:0));
|
||||
assert(pReg->Level <= pManMR->maxDelay);
|
||||
pReg->Level = 0;
|
||||
pReg->fMarkA = pReg->fMarkB = 0;
|
||||
}
|
||||
}
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pCur, i) {
|
||||
pReg = Abc_ObjRegular( pCur );
|
||||
if (pReg != pCur) {
|
||||
Abc_ObjForEachFanin(pReg, pNext, j)
|
||||
if (!Abc_ObjIsLatch(pNext))
|
||||
pNext->Level = MAX( pNext->Level, pReg->Level + (Abc_ObjIsNode(pReg)?1:0));
|
||||
|
||||
if (pReg->Level == pManMR->maxDelay) {
|
||||
Vec_PtrPush( FTIMEEDGES(pObj), pReg);
|
||||
pManMR->nExactConstraints++;
|
||||
}
|
||||
pReg->Level = 0;
|
||||
pReg->fMarkA = pReg->fMarkB = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Vec_PtrClear( vNodes );
|
||||
}
|
||||
|
||||
void Abc_FlowRetime_ConstrainExact_back_rec( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes, int latch ) {
|
||||
Abc_Obj_t *pNext;
|
||||
int i;
|
||||
|
||||
// terminate?
|
||||
if (Abc_ObjIsLatch(pObj)) {
|
||||
if (latch) return;
|
||||
latch = 1;
|
||||
}
|
||||
|
||||
// already visited?
|
||||
if (!latch) {
|
||||
if (pObj->fMarkA) return;
|
||||
pObj->fMarkA = 1;
|
||||
} else {
|
||||
if (pObj->fMarkB) return;
|
||||
pObj->fMarkB = 1;
|
||||
}
|
||||
|
||||
// recurse
|
||||
Abc_ObjForEachFanout(pObj, pNext, i) {
|
||||
Abc_FlowRetime_ConstrainExact_back_rec( pNext, vNodes, latch );
|
||||
}
|
||||
|
||||
// add
|
||||
pObj->Level = 0;
|
||||
Vec_PtrPush(vNodes, Abc_ObjNotCond(pObj, latch));
|
||||
}
|
||||
|
||||
|
||||
void Abc_FlowRetime_ConstrainExact_back( Abc_Obj_t * pObj ) {
|
||||
Vec_Ptr_t *vNodes = pManMR->vNodes;
|
||||
Abc_Obj_t *pNext, *pCur, *pReg;
|
||||
// Abc_Ntk_t *pNtk = pManMR->pNtk;
|
||||
int i, j;
|
||||
|
||||
assert( !Vec_PtrSize( vNodes ));
|
||||
assert( !Abc_ObjIsLatch(pObj) );
|
||||
assert( !Vec_PtrSize( FTIMEEDGES(pObj) ));
|
||||
Vec_PtrPush( pManMR->vExactNodes, pObj );
|
||||
|
||||
// rev topo order
|
||||
Abc_FlowRetime_ConstrainExact_back_rec( pObj, vNodes, 0 );
|
||||
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pCur, i) {
|
||||
pReg = Abc_ObjRegular( pCur );
|
||||
|
||||
if (pReg == pCur) {
|
||||
assert(!Abc_ObjIsLatch(pReg));
|
||||
Abc_ObjForEachFanout(pReg, pNext, j)
|
||||
pNext->Level = MAX( pNext->Level, pReg->Level + (Abc_ObjIsNode(pReg)?1:0));
|
||||
assert(pReg->Level <= pManMR->maxDelay);
|
||||
pReg->Level = 0;
|
||||
pReg->fMarkA = pReg->fMarkB = 0;
|
||||
}
|
||||
}
|
||||
Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pCur, i) {
|
||||
pReg = Abc_ObjRegular( pCur );
|
||||
if (pReg != pCur) {
|
||||
Abc_ObjForEachFanout(pReg, pNext, j)
|
||||
if (!Abc_ObjIsLatch(pNext))
|
||||
pNext->Level = MAX( pNext->Level, pReg->Level + (Abc_ObjIsNode(pReg)?1:0));
|
||||
|
||||
if (pReg->Level == pManMR->maxDelay) {
|
||||
Vec_PtrPush( FTIMEEDGES(pObj), pReg);
|
||||
pManMR->nExactConstraints++;
|
||||
}
|
||||
pReg->Level = 0;
|
||||
pReg->fMarkA = pReg->fMarkB = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Vec_PtrClear( vNodes );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Introduces all exact timing constraints in a network]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FlowRetime_ConstrainExactAll( Abc_Ntk_t * pNtk ) {
|
||||
int i;
|
||||
Abc_Obj_t *pObj;
|
||||
void *pArray;
|
||||
|
||||
// free existing constraints
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if ( Vec_PtrSize( FTIMEEDGES(pObj) )) {
|
||||
pArray = Vec_PtrReleaseArray( FTIMEEDGES(pObj) );
|
||||
ABC_FREE( pArray );
|
||||
}
|
||||
pManMR->nExactConstraints = 0;
|
||||
|
||||
// generate all constraints
|
||||
Abc_NtkForEachObj(pNtk, pObj, i)
|
||||
if (!Abc_ObjIsLatch(pObj) && FTEST( pObj, CONSERVATIVE ) && !FTEST( pObj, BLOCK ))
|
||||
if (!Vec_PtrSize( FTIMEEDGES( pObj ) ))
|
||||
Abc_FlowRetime_ConstrainExact( pObj );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates exact constraints.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FlowRetime_FreeTiming( Abc_Ntk_t *pNtk ) {
|
||||
Abc_Obj_t *pObj;
|
||||
void *pArray;
|
||||
|
||||
while( Vec_PtrSize( pManMR->vExactNodes )) {
|
||||
pObj = Vec_PtrPop( pManMR->vExactNodes );
|
||||
|
||||
if ( Vec_PtrSize( FTIMEEDGES(pObj) )) {
|
||||
pArray = Vec_PtrReleaseArray( FTIMEEDGES(pObj) );
|
||||
ABC_FREE( pArray );
|
||||
}
|
||||
}
|
||||
|
||||
Vec_PtrFree(pManMR->vExactNodes);
|
||||
ABC_FREE( pManMR->vTimeEdges );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FlowRetime_Dfs_forw( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes ) {
|
||||
Abc_Obj_t *pNext;
|
||||
int i;
|
||||
|
||||
if (Abc_ObjIsLatch(pObj)) return;
|
||||
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
|
||||
Abc_ObjForEachFanout( pObj, pNext, i )
|
||||
if (!Abc_NodeIsTravIdCurrent( pNext ))
|
||||
Abc_FlowRetime_Dfs_forw( pNext, vNodes );
|
||||
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
}
|
||||
|
||||
|
||||
void Abc_FlowRetime_Dfs_back( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes ) {
|
||||
Abc_Obj_t *pNext;
|
||||
int i;
|
||||
|
||||
if (Abc_ObjIsLatch(pObj)) return;
|
||||
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
|
||||
Abc_ObjForEachFanin( pObj, pNext, i )
|
||||
if (!Abc_NodeIsTravIdCurrent( pNext ))
|
||||
Abc_FlowRetime_Dfs_back( pNext, vNodes );
|
||||
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Main timing-constrained routine.]
|
||||
|
||||
Description [Refines constraints that are limiting area improvement.
|
||||
These are identified by computing
|
||||
the min-cuts both with and without the conservative
|
||||
constraints: these two situation represent an
|
||||
over- and under-constrained version of the timing.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_FlowRetime_RefineConstraints( ) {
|
||||
Abc_Ntk_t *pNtk = pManMR->pNtk;
|
||||
int i, flow, count = 0;
|
||||
Abc_Obj_t *pObj;
|
||||
int maxTighten = 99999;
|
||||
|
||||
vprintf("\t\tsubiter %d : constraints = {cons, exact} = %d, %d\n",
|
||||
pManMR->subIteration, pManMR->nConservConstraints, pManMR->nExactConstraints);
|
||||
|
||||
// 1. overconstrained
|
||||
pManMR->constraintMask = BLOCK | CONSERVATIVE;
|
||||
vprintf("\t\trefinement: over ");
|
||||
fflush(stdout);
|
||||
flow = Abc_FlowRetime_PushFlows( pNtk, 0 );
|
||||
vprintf("= %d ", flow);
|
||||
|
||||
// remember nodes
|
||||
if (pManMR->fIsForward) {
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if (!FTEST(pObj, VISITED_R))
|
||||
pObj->fMarkC = 1;
|
||||
} else {
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if (!FTEST(pObj, VISITED_E))
|
||||
pObj->fMarkC = 1;
|
||||
}
|
||||
|
||||
if (pManMR->fConservTimingOnly) {
|
||||
vprintf(" done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 2. underconstrained
|
||||
pManMR->constraintMask = BLOCK;
|
||||
Abc_FlowRetime_ClearFlows( 0 );
|
||||
vprintf("under = ");
|
||||
fflush(stdout);
|
||||
flow = Abc_FlowRetime_PushFlows( pNtk, 0 );
|
||||
vprintf("%d refined nodes = ", flow);
|
||||
fflush(stdout);
|
||||
|
||||
// find area-limiting constraints
|
||||
if (pManMR->fIsForward) {
|
||||
Abc_NtkForEachObj( pNtk, pObj, i ) {
|
||||
if (pObj->fMarkC &&
|
||||
FTEST(pObj, VISITED_R) &&
|
||||
FTEST(pObj, CONSERVATIVE) &&
|
||||
count < maxTighten) {
|
||||
count++;
|
||||
Abc_FlowRetime_ConstrainExact( pObj );
|
||||
}
|
||||
pObj->fMarkC = 0;
|
||||
}
|
||||
} else {
|
||||
Abc_NtkForEachObj( pNtk, pObj, i ) {
|
||||
if (pObj->fMarkC &&
|
||||
FTEST(pObj, VISITED_E) &&
|
||||
FTEST(pObj, CONSERVATIVE) &&
|
||||
count < maxTighten) {
|
||||
count++;
|
||||
Abc_FlowRetime_ConstrainExact( pObj );
|
||||
}
|
||||
pObj->fMarkC = 0;
|
||||
}
|
||||
}
|
||||
|
||||
vprintf("%d\n", count);
|
||||
|
||||
return (count > 0);
|
||||
}
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fretime.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Flow-based retiming package.]
|
||||
|
||||
Synopsis [Header file for retiming package.]
|
||||
|
||||
Author [Aaron Hurst]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - January 1, 2008.]
|
||||
|
||||
Revision [$Id: fretime.h,v 1.00 2008/01/01 00:00:00 ahurst Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#if !defined(RETIME_H_)
|
||||
#define RETIME_H_
|
||||
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
#include "misc/vec/vec.h"
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
|
||||
// #define IGNORE_TIMING
|
||||
// #define DEBUG_PRINT_FLOWS
|
||||
// #define DEBUG_VISITED
|
||||
// #define DEBUG_PREORDER
|
||||
#define DEBUG_CHECK
|
||||
// #define DEBUG_PRINT_LEVELS
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_DIST 30000
|
||||
|
||||
// flags in Flow_Data structure...
|
||||
#define VISITED_E 0x001
|
||||
#define VISITED_R 0x002
|
||||
#define VISITED (VISITED_E | VISITED_R)
|
||||
#define FLOW 0x004
|
||||
#define CROSS_BOUNDARY 0x008
|
||||
#define BLOCK 0x010
|
||||
#define INIT_0 0x020
|
||||
#define INIT_1 0x040
|
||||
#define INIT_CARE (INIT_0 | INIT_1)
|
||||
#define CONSERVATIVE 0x080
|
||||
#define BLOCK_OR_CONS (BLOCK | CONSERVATIVE)
|
||||
#define BIAS_NODE 0x100
|
||||
|
||||
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
|
||||
typedef struct Flow_Data_t_ {
|
||||
unsigned int mark : 16;
|
||||
|
||||
union {
|
||||
Abc_Obj_t *pred;
|
||||
/* unsigned int var; */
|
||||
Abc_Obj_t *pInitObj;
|
||||
Abc_Obj_t *pCopy;
|
||||
Vec_Ptr_t *vNodes;
|
||||
};
|
||||
|
||||
unsigned int e_dist : 16;
|
||||
unsigned int r_dist : 16;
|
||||
} Flow_Data_t;
|
||||
|
||||
// useful macros for manipulating Flow_Data structure...
|
||||
#define FDATA( x ) (pManMR->pDataArray+Abc_ObjId(x))
|
||||
#define FSET( x, y ) FDATA(x)->mark |= y
|
||||
#define FUNSET( x, y ) FDATA(x)->mark &= ~y
|
||||
#define FTEST( x, y ) (FDATA(x)->mark & y)
|
||||
#define FTIMEEDGES( x ) &(pManMR->vTimeEdges[Abc_ObjId( x )])
|
||||
|
||||
typedef struct NodeLag_T_ {
|
||||
int id;
|
||||
int lag;
|
||||
} NodeLag_t;
|
||||
|
||||
typedef struct InitConstraint_t_ {
|
||||
Abc_Obj_t *pBiasNode;
|
||||
|
||||
Vec_Int_t vNodes;
|
||||
Vec_Int_t vLags;
|
||||
|
||||
} InitConstraint_t;
|
||||
|
||||
typedef struct MinRegMan_t_ {
|
||||
|
||||
// problem description:
|
||||
int maxDelay;
|
||||
int fComputeInitState, fGuaranteeInitState, fBlockConst;
|
||||
int nNodes, nLatches;
|
||||
int fForwardOnly, fBackwardOnly;
|
||||
int fConservTimingOnly;
|
||||
int nMaxIters;
|
||||
int fVerbose;
|
||||
Abc_Ntk_t *pNtk;
|
||||
|
||||
int nPreRefine;
|
||||
|
||||
// problem state
|
||||
int fIsForward;
|
||||
int fSinkDistTerminate;
|
||||
int nExactConstraints, nConservConstraints;
|
||||
int fSolutionIsDc;
|
||||
int constraintMask;
|
||||
int iteration, subIteration;
|
||||
Vec_Int_t *vLags;
|
||||
|
||||
// problem data
|
||||
Vec_Int_t *vSinkDistHist;
|
||||
Flow_Data_t *pDataArray;
|
||||
Vec_Ptr_t *vTimeEdges;
|
||||
Vec_Ptr_t *vExactNodes;
|
||||
Vec_Ptr_t *vInitConstraints;
|
||||
Abc_Ntk_t *pInitNtk;
|
||||
Vec_Ptr_t *vNodes; // re-useable struct
|
||||
|
||||
NodeLag_t *pInitToOrig;
|
||||
int sizeInitToOrig;
|
||||
|
||||
} MinRegMan_t ;
|
||||
|
||||
extern MinRegMan_t *pManMR;
|
||||
|
||||
#define vprintf if (pManMR->fVerbose) printf
|
||||
|
||||
static inline void FSETPRED(Abc_Obj_t *pObj, Abc_Obj_t *pPred) {
|
||||
assert(!Abc_ObjIsLatch(pObj)); // must preserve field to maintain init state linkage
|
||||
FDATA(pObj)->pred = pPred;
|
||||
}
|
||||
static inline Abc_Obj_t * FGETPRED(Abc_Obj_t *pObj) {
|
||||
return FDATA(pObj)->pred;
|
||||
}
|
||||
|
||||
/*=== fretMain.c ==========================================================*/
|
||||
|
||||
Abc_Ntk_t * Abc_FlowRetime_MinReg( Abc_Ntk_t * pNtk, int fVerbose,
|
||||
int fComputeInitState, int fGuaranteeInitState, int fBlockConst,
|
||||
int fForward, int fBackward, int nMaxIters,
|
||||
int maxDelay, int fFastButConservative);
|
||||
|
||||
void print_node(Abc_Obj_t *pObj);
|
||||
|
||||
void Abc_ObjBetterTransferFanout( Abc_Obj_t * pFrom, Abc_Obj_t * pTo, int complement );
|
||||
|
||||
int Abc_FlowRetime_PushFlows( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
int Abc_FlowRetime_IsAcrossCut( Abc_Obj_t *pCur, Abc_Obj_t *pNext );
|
||||
void Abc_FlowRetime_ClearFlows( int fClearAll );
|
||||
|
||||
int Abc_FlowRetime_GetLag( Abc_Obj_t *pObj );
|
||||
void Abc_FlowRetime_SetLag( Abc_Obj_t *pObj, int lag );
|
||||
|
||||
void Abc_FlowRetime_UpdateLags( );
|
||||
|
||||
void Abc_ObjPrintNeighborhood( Abc_Obj_t *pObj, int depth );
|
||||
|
||||
Abc_Ntk_t * Abc_FlowRetime_NtkSilentRestrash( Abc_Ntk_t * pNtk, int fCleanup );
|
||||
|
||||
/*=== fretFlow.c ==========================================================*/
|
||||
|
||||
int dfsplain_e( Abc_Obj_t *pObj, Abc_Obj_t *pPred );
|
||||
int dfsplain_r( Abc_Obj_t *pObj, Abc_Obj_t *pPred );
|
||||
|
||||
void dfsfast_preorder( Abc_Ntk_t *pNtk );
|
||||
int dfsfast_e( Abc_Obj_t *pObj, Abc_Obj_t *pPred );
|
||||
int dfsfast_r( Abc_Obj_t *pObj, Abc_Obj_t *pPred );
|
||||
|
||||
/*=== fretInit.c ==========================================================*/
|
||||
|
||||
void Abc_FlowRetime_PrintInitStateInfo( Abc_Ntk_t * pNtk );
|
||||
|
||||
void Abc_FlowRetime_InitState( Abc_Ntk_t * pNtk );
|
||||
|
||||
void Abc_FlowRetime_UpdateForwardInit( Abc_Ntk_t * pNtk );
|
||||
void Abc_FlowRetime_UpdateBackwardInit( Abc_Ntk_t * pNtk );
|
||||
|
||||
void Abc_FlowRetime_SetupBackwardInit( Abc_Ntk_t * pNtk );
|
||||
int Abc_FlowRetime_SolveBackwardInit( Abc_Ntk_t * pNtk );
|
||||
|
||||
void Abc_FlowRetime_ConstrainInit( );
|
||||
void Abc_FlowRetime_AddInitBias( );
|
||||
void Abc_FlowRetime_RemoveInitBias( );
|
||||
|
||||
/*=== fretTime.c ==========================================================*/
|
||||
|
||||
void Abc_FlowRetime_InitTiming( Abc_Ntk_t *pNtk );
|
||||
void Abc_FlowRetime_FreeTiming( Abc_Ntk_t *pNtk );
|
||||
|
||||
int Abc_FlowRetime_RefineConstraints( );
|
||||
|
||||
void Abc_FlowRetime_ConstrainConserv( Abc_Ntk_t * pNtk );
|
||||
void Abc_FlowRetime_ConstrainExact( Abc_Obj_t * pObj );
|
||||
void Abc_FlowRetime_ConstrainExactAll( Abc_Ntk_t * pNtk );
|
||||
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
SRC += \
|
||||
src/opt/fret/fretMain.c \
|
||||
src/opt/fret/fretFlow.c \
|
||||
src/opt/fret/fretInit.c \
|
||||
src/opt/fret/fretTime.c
|
||||
Loading…
Reference in New Issue