48static inline int * Wln_RetFanins(
Wln_Ret_t *
p,
int i ) {
return Vec_IntEntryP( &
p->vFanins, Vec_IntEntry(&
p->vFanins, i) ); }
49static inline int * Wln_RetFanouts(
Wln_Ret_t *
p,
int i ) {
return Vec_IntEntryP( &
p->vFanouts, Vec_IntEntry(&
p->vFanouts, i) ); }
51#define Wln_RetForEachFanin( p, iObj, iFanin, pLink, i ) \
52 for ( i = 0; (i < Wln_ObjFaninNum(p->pNtk, iObj)) && \
53 (((iFanin) = Wln_RetFanins(p, iObj)[2*i]), 1) && \
54 ((pLink) = (Wln_RetFanins(p, iObj)+2*i+1)); i++ ) if ( !iFanin || (!Wln_ObjFaninNum(p->pNtk, iFanin) && !Wln_ObjIsCi(p->pNtk, iFanin)) ) {} else
56#define Wln_RetForEachFanout( p, iObj, iFanout, pLink, i ) \
57 for ( i = 0; (i < Wln_ObjRefs(p->pNtk, iObj)) && \
58 (((iFanout) = Wln_RetFanouts(p, iObj)[2*i]), 1) && \
59 ((pLink) = Vec_IntEntryP(&p->vFanins, Wln_RetFanouts(p, iObj)[2*i+1])); i++ ) if ( !iFanout ) {} else
78 int k, iFanin, Type = Wln_ObjType(
p->pNtk, iObj), * pLink;
79 printf(
"Obj %6d : Type = %6s NameId = %5d InstId = %5d Fanins = %d : ",
80 iObj, Abc_OperName(Type), Wln_ObjNameId(
p->pNtk, iObj), Wln_ObjInstId(
p->pNtk, iObj), Wln_ObjFaninNum(
p->pNtk, iObj) );
83 printf(
"%5d ", iFanin );
86 printf(
"(%d : %d %d) ", pLink[0],
87 Vec_IntEntry(&
p->vEdgeLinks, pLink[0]),
88 Vec_IntEntry(&
p->vEdgeLinks, pLink[0]+1) );
96 if ( Wln_ObjInstId(
p->pNtk, iObj) > 1 )
98 printf(
"Total number of objects = %d. Objects with non-trivial delay = %d.\n", Wln_NtkObjNum(
p->pNtk), nCount );
101 int nPrints = 0, nLimit = 5;
102 printf(
"The following %d objects have non-trivial delays:\n", nLimit );
105 if ( Wln_ObjInstId(
p->pNtk, iObj) <= 1 )
108 if ( ++nPrints == nLimit )
113 printf(
"Printing %d objects of network \"%s\":\n", Wln_NtkObjNum(
p->pNtk),
p->pNtk->pName );
132 int i, k, iObj, nClasses;
135 Vec_IntFill( vClasses, Wln_NtkObjNum(pNtk), -1 );
138 Vec_IntClear( vFlop );
139 for ( k = 1; k <= 6; k++ )
140 Vec_IntPush( vFlop, Wln_ObjFanin(pNtk, iObj, k) );
141 Vec_IntWriteEntry( vClasses, iObj, Hsh_VecManAdd(
p, vFlop) );
143 nClasses = Hsh_VecSize(
p );
145 Vec_IntFree( vFlop );
146 printf(
"Detected %d flops and %d flop classes.\n", Wln_NtkFfNum(pNtk), nClasses );
151 Wln_Ret_t *
p;
int k, iObj, iFanin, fFirst = 1;
158 if ( Wln_ObjRefs(pNtk, iObj) == 0 && !Wln_ObjIsCio(pNtk, iObj) )
163 printf(
"Objects without fanout:\n" );
171 Wln_NtkCleanRefs( pNtk );
172 Vec_IntGrow( &
p->vEdgeLinks, 10*Wln_NtkFfNum(pNtk) );
173 Vec_IntPushTwo( &
p->vEdgeLinks, -1, -1 );
177 int * pFanins = Wln_RetFanins(
p, iObj );
178 int * pFanouts = Wln_RetFanouts(
p, iFanin );
179 int Index = Wln_ObjRefsInc( pNtk, iFanin );
180 pFanins[2*k+0] = iFanin;
181 pFanins[2*k+1] = Wln_ObjIsFf(pNtk, iFanin) ? Vec_IntSize(&
p->vEdgeLinks) : 0;
182 pFanouts[2*Index+0] = iObj;
183 pFanouts[2*Index+1] = Vec_IntEntry(&
p->vFanins, iObj) + 2*k + 1;
184 if ( Wln_ObjIsFf(pNtk, iFanin) )
185 Vec_IntPushTwo( &
p->vEdgeLinks, 0, iFanin );
189 assert( Wln_ObjRefs(pNtk, iObj) == Vec_IntEntry(vRefsCopy, iObj) );
190 Vec_IntFree( vRefsCopy );
194 Vec_IntAppend( &
p->vNodeDelays, &pNtk->
vInstIds );
195 Vec_IntGrow( &
p->vSources, 1000 );
196 Vec_IntGrow( &
p->vSinks, 1000 );
197 Vec_IntGrow( &
p->vFront, 1000 );
198 Vec_IntGrow( &
p->vMoves, 1000 );
218 Mem += 4 *
p->vFanins.nCap;
219 Mem += 4 *
p->vFanouts.nCap;
220 Mem += 4 *
p->vEdgeLinks.nCap;
221 Mem += 4 *
p->vFfClasses.nCap;
222 Mem += 4 *
p->vNodeDelays.nCap;
223 Mem += 4 *
p->vPathDelays.nCap;
224 Mem += 4 *
p->vSources.nCap;
225 Mem += 4 *
p->vSinks.nCap;
226 Mem += 4 *
p->vFront.nCap;
227 Mem += 4 *
p->vMoves.nCap;
244 int k, iFanout, * pLink, * pDelay = Vec_IntEntryP( &
p->vPathDelays, iObj );
262 Vec_IntFill( &
p->vPathDelays, Wln_NtkObjNum(
p->pNtk), -1 );
264 Vec_IntWriteEntry( &
p->vPathDelays, iObj, 0 );
269 int k, iFanin, * pLink, * pDelay = Vec_IntEntryP( &
p->vPathDelays, iObj );
275 if ( Wln_ObjIsFf(
p->pNtk, iObj) && k > 0 )
278 *pDelay = Abc_MaxInt(*pDelay, 0);
282 *pDelay += Vec_IntEntry( &
p->vNodeDelays, iObj );
287 int iObj, DelayMax = 0;
288 Vec_IntClear( &
p->vSinks );
290 if ( !Wln_ObjIsCio(
p->pNtk, iObj) )
293 if ( DelayMax == Delay )
294 Vec_IntPush( &
p->vSinks, iObj );
295 else if ( DelayMax < Delay )
298 Vec_IntFill( &
p->vSinks, 1, iObj );
314 int k, iFanin, * pLink, FaninDelay;
315 if ( Wln_ObjIsCi(
p->pNtk, iObj) || Wln_ObjCheckTravId(
p->pNtk, iObj) )
317 FaninDelay = Vec_IntEntry( &
p->vPathDelays, iObj ) - Vec_IntEntry( &
p->vNodeDelays, iObj );
319 if ( !pLink[0] && Vec_IntEntry(&
p->vPathDelays, iFanin) == FaninDelay )
321 if ( FaninDelay == 0 )
322 Vec_IntPush( &
p->vSources, iObj );
327 Vec_IntClear( &
p->vSources );
328 Wln_NtkIncrementTravId(
p->pNtk );
349 int k, iFanin, fPrev = 1;
350 if ( Wln_ObjIsTravIdPrevious(
p, iObj) )
352 if ( Wln_ObjIsTravIdCurrent(
p, iObj) )
354 if ( Wln_ObjIsCio(
p, iObj) || Wln_ObjIsFf(
p, iObj) )
360 Wln_ObjSetTravIdPrevious(
p, iObj );
361 if ( Vec_IntEntry(&
p->vInstIds, iObj) > 0 )
364 printf(
"Updating delay %5d -> %5d : ", Vec_IntEntry(&
p->vInstIds, iObj), 1 );
367 Vec_IntWriteEntry( &
p->vInstIds, iObj, 1 );
371 Wln_ObjSetTravIdCurrent(
p, iObj );
377 Wln_NtkIncrementTravId(
p );
378 Wln_NtkIncrementTravId(
p );
380 Wln_ObjSetTravIdPrevious(
p, iObj );
400 pLink = Vec_IntEntryP( &
p->vEdgeLinks, pHead[0] );
406static inline int Wln_RetCheckForwardOne(
Wln_Ret_t *
p,
int iObj )
408 int k, iFanin, * pLink, iFlop, Class = -1;
411 if ( Wln_ObjIsFf(
p->pNtk, iObj) && k > 0 )
415 iFlop = Vec_IntEntry( &
p->vEdgeLinks, pLink[0] + 1 );
416 assert( Wln_ObjIsFf(
p->pNtk, iFlop ) );
418 Class = Vec_IntEntry( &
p->vFfClasses, iFlop );
419 else if ( Class != Vec_IntEntry( &
p->vFfClasses, iFlop ) )
428 if ( !Wln_RetCheckForwardOne(
p, iObj ) )
433static inline int Wln_RetCheckBackwardOne(
Wln_Ret_t *
p,
int iObj )
435 int k, iFanin, * pLink, iFlop, Class = -1;
436 if ( Wln_ObjRefs(
p->pNtk, iObj) == 0 )
443 iFlop = Vec_IntEntry( &
p->vEdgeLinks, pLink[0] + 1 );
444 assert( Wln_ObjIsFf(
p->pNtk, iFlop ) );
446 Class = Vec_IntEntry( &
p->vFfClasses, iFlop );
447 else if ( Class != Vec_IntEntry( &
p->vFfClasses, iFlop ) )
456 if ( !Wln_RetCheckBackwardOne(
p, iObj ) )
475 int k, iFanin, * pLink, iFlop, iFlop1 = -1;
476 int * pFanins = Wln_RetFanins(
p, iObj );
479 if ( Wln_ObjIsFf(
p->pNtk, iObj) && k > 0 )
482 iFlop = Vec_IntEntry( &
p->vEdgeLinks, pLink[0] + 1 );
483 pFanins[2*k+1] = Vec_IntEntry( &
p->vEdgeLinks, pLink[0] );
484 assert( Wln_ObjIsFf(
p->pNtk, iFlop ) );
492 int k, iFanin, * pLink, iFlop, iFlop1 = -1;
498 iFlop = Vec_IntEntry( &
p->vEdgeLinks, pLink[0] + 1 );
500 assert( Wln_ObjIsFf(
p->pNtk, iFlop ) );
508 int k, iHead, iFanin, * pLink;
509 int * pFanins = Wln_RetFanins(
p, iObj );
510 assert( Wln_ObjIsFf(
p->pNtk, iFlop ) );
513 if ( Wln_ObjIsFf(
p->pNtk, iObj) && k > 0 )
515 iHead = pFanins[2*k+1];
516 pFanins[2*k+1] = Vec_IntSize(&
p->vEdgeLinks);
517 Vec_IntPushTwo( &
p->vEdgeLinks, iHead, iFlop );
522 int k, iFanin, * pLink;
523 assert( Wln_ObjIsFf(
p->pNtk, iFlop ) );
529 pLink[0] = Vec_IntSize(&
p->vEdgeLinks);
530 Vec_IntPushTwo( &
p->vEdgeLinks, 0, iFlop );
560 printf(
"Move %4d : Recording initial state (delay = %6d)\n", nMoves, Delay );
561 Vec_IntPushTwo( &
p->vMoves, Delay, 0 );
564 printf(
"Move %4d : Recording %s retiming (delay = %6d) :", nMoves, fForward ?
"forward " :
"backward", Delay );
565 Vec_IntPush( &
p->vMoves, Delay );
568 int NameId = Vec_IntEntry( &
p->pNtk->vNameIds, iObj );
571 Vec_IntPush( &
p->vMoves, fForward ? -NameId : NameId );
573 printf(
" %d (NameID = %d) ", fForward ? -iObj : iObj, fForward ? -NameId : NameId );
575 Vec_IntPush( &
p->vMoves, 0 );
577 printf(
" %3d retimed objects", Vec_IntSize(vSet) );
597 if ( Wln_NtkHasInstId(pNtk) )
599 printf(
"Using delays given by the user in the input file.\n" );
601 if ( !Wln_ObjIsCio(pNtk, iObj) && !Wln_ObjIsConst(pNtk, iObj) && Wln_ObjInstId(pNtk, iObj) == 0 )
602 printf(
"Warning: Object %d of type %s has zero delay. Retiming will not work correctly.\n", iObj, Abc_OperName(Wln_ObjType(pNtk, iObj)) );
606 printf(
"The design has no delay information.\n" );
607 Wln_NtkCleanInstId(pNtk);
611 Wln_ObjSetInstId( pNtk, iObj, 1 );
612 else if ( !Wln_ObjIsCio(pNtk, iObj) && Wln_ObjFaninNum(pNtk, iObj) > 0 )
613 Wln_ObjSetInstId( pNtk, iObj, 10 );
617 if ( Wln_ObjType(pNtk, Wln_ObjFanin0(pNtk, iObj)) !=
ABC_OPER_LUT )
618 Wln_ObjSetInstId( pNtk, Wln_ObjFanin0(pNtk, iObj), 1 );
620 printf(
"Assuming default delays: 10 units for most nodes and 1 unit for bit-slice, concat, and buffers driving COs.\n" );
630 int nMoves = 0, fPrevFwd = 0, fPrevBwd = 0, nCountIncrease = 0;
631 int DelayInit = 0, DelayBest = 0, nChange = 0;
637 while ( Vec_IntSize(vSources) || Vec_IntSize(vSinks) )
639 int DelayMaxPrev =
p->DelayMax;
642 Vec_IntSort( vSources, 0 );
643 Vec_IntSort( vSinks, 0 );
645 if ( !fForward && !fBackward )
647 printf(
"Cannot retime forward and backward.\n" );
650 if ( Vec_IntTwoCountCommon(vSources, vSinks) )
652 printf(
"Cannot reduce delay by retiming.\n" );
656 Vec_IntClear( vFront );
657 if ( (fPrevFwd && fForward) || (!(fPrevBwd && fBackward) && ((fForward && !fBackward) || (fForward && fBackward && Vec_IntSize(vSources) < Vec_IntSize(vSinks)))) )
659 Vec_IntAppend( vFront, vSources );
663 fForward = 1, fBackward = 0;
668 Vec_IntAppend( vFront, vSinks );
672 fForward = 0, fBackward = 1;
675 DelayBest = Abc_MinInt( DelayBest,
p->DelayMax );
683 Vec_IntPrint( &
p->vSinks );
684 printf(
"Sources: " );
685 Vec_IntPrint( &
p->vSources );
687 if (
p->DelayMax >= DelayMaxPrev )
691 if ( nCountIncrease > 0 )
695 if ( nCountIncrease > 3 )
700 if ( 2*Vec_IntSize(&
p->vEdgeLinks) > Vec_IntCap(&
p->vEdgeLinks) )
701 Vec_IntGrow( &
p->vEdgeLinks, 4*Vec_IntSize(&
p->vEdgeLinks) );
707 printf(
"\nThe resulting moves recorded in terms of name IDs of the NDR nodes:\n" );
708 Vec_IntPrint( vMoves );
712 printf(
"Retiming instruction contains %d moves and %d total retimed objects.\n", nMoves, Vec_IntSize(vMoves)-2*nMoves-2 );
713 printf(
"Initial delay = %d. The best delay achieved = %d. Improvement = %d. (%6.2f %%)\n",
714 DelayInit, DelayBest, DelayInit - DelayBest, 100.0 * (DelayInit - DelayBest) / DelayInit );
#define ABC_SWAP(Type, a, b)
#define ABC_CALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
struct Hsh_VecMan_t_ Hsh_VecMan_t
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
int Wln_RetMemUsage(Wln_Ret_t *p)
void Wln_RetMarkChanges_rec(Wln_Ret_t *p, int iObj)
int * Wln_RetHeadToTail(Wln_Ret_t *p, int *pHead)
int Wln_RetRemoveOneFanin(Wln_Ret_t *p, int iObj)
int Wln_RetComputeFfClasses(Wln_Ntk_t *pNtk, Vec_Int_t *vClasses)
void Wln_RetPrint(Wln_Ret_t *p, int fVerbose)
#define Wln_RetForEachFanin(p, iObj, iFanin, pLink, i)
int Wln_RetPropDelay_rec(Wln_Ret_t *p, int iObj)
void Wln_RetRetimeBackward(Wln_Ret_t *p, Vec_Int_t *vSet)
int Wln_RetRemoveOneFanout(Wln_Ret_t *p, int iObj)
int Wln_RetPropDelay(Wln_Ret_t *p)
void Wln_RetRetimeForward(Wln_Ret_t *p, Vec_Int_t *vSet)
int Wln_RetCheckForward(Wln_Ret_t *p, Vec_Int_t *vSet)
void Wln_RetFindSources_rec(Wln_Ret_t *p, int iObj)
typedefABC_NAMESPACE_IMPL_START struct Wln_Ret_t_ Wln_Ret_t
DECLARATIONS ///.
#define Wln_RetForEachFanout(p, iObj, iFanout, pLink, i)
void Wln_NtkRetimeCreateDelayInfo(Wln_Ntk_t *pNtk)
void Wln_RetFindSources(Wln_Ret_t *p)
Vec_Int_t * Wln_NtkRetime_int(Wln_Ntk_t *pNtk, int fSkipSimple, int fVerbose)
void Wln_RetMarkPaths(Wln_Ntk_t *p, int fVerbose)
void Wln_RetFree(Wln_Ret_t *p)
void Wln_RetAddToMoves(Wln_Ret_t *p, Vec_Int_t *vSet, int Delay, int fForward, int nMoves, int fSkipSimple, int fVerbose)
void Wln_RetMarkChanges(Wln_Ret_t *p, Vec_Int_t *vFront)
int Wln_RetMarkPaths_rec(Wln_Ntk_t *p, int iObj, int fVerbose)
void Wln_RetPrintObj(Wln_Ret_t *p, int iObj)
FUNCTION DEFINITIONS ///.
void Wln_RetInsertOneFanout(Wln_Ret_t *p, int iObj, int iFlop)
Wln_Ret_t * Wln_RetAlloc(Wln_Ntk_t *pNtk)
void Wln_RetInsertOneFanin(Wln_Ret_t *p, int iObj, int iFlop)
Vec_Int_t * Wln_NtkRetime(Wln_Ntk_t *pNtk, int fIgnoreIO, int fSkipSimple, int fVerbose)
int Wln_RetCheckBackward(Wln_Ret_t *p, Vec_Int_t *vSet)
#define Wln_NtkForEachFf(p, iFf, i)
#define Wln_NtkForEachCo(p, iCo, i)
void Wln_ObjPrint(Wln_Ntk_t *p, int iObj)
#define Wln_ObjForEachFanin(p, iObj, iFanin, i)
#define Wln_NtkForEachPo(p, iPo, i)
void Wln_NtkStartFaninMap(Wln_Ntk_t *p, Vec_Int_t *vFaninMap, int nMulti)
#define Wln_NtkForEachCi(p, iCi, i)
void Wln_NtkStartFanoutMap(Wln_Ntk_t *p, Vec_Int_t *vFanoutMap, Vec_Int_t *vFanoutNums, int nMulti)
#define Wln_NtkForEachPi(p, iPi, i)
void Wln_NtkCreateRefs(Wln_Ntk_t *p)
struct Wln_Ntk_t_ Wln_Ntk_t
#define Wln_NtkForEachObj(p, i)
MACRO DEFINITIONS ///.