00001
00021 #include "retInt.h"
00022
00026
00027 static int Abc_NtkRetimeMinDelayTry( Abc_Ntk_t * pNtk, int fForward, int fInitial, int nIterLimit, int * pIterBest, int fVerbose );
00028 static int Abc_NtkRetimeTiming( Abc_Ntk_t * pNtk, int fForward, Vec_Ptr_t * vCritical );
00029 static int Abc_NtkRetimeTiming_rec( Abc_Obj_t * pObj, int fForward );
00030
00034
00047 int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkCopy, int nIterLimit, int fForward, int fVerbose )
00048 {
00049 int IterBest, DelayBest;
00050 int IterBest2, DelayBest2;
00051
00052 DelayBest = Abc_NtkRetimeMinDelayTry( pNtkCopy, fForward, 0, nIterLimit, &IterBest, fVerbose );
00053 if ( IterBest == 0 )
00054 return 1;
00055
00056 DelayBest2 = Abc_NtkRetimeMinDelayTry( pNtk, fForward, 1, IterBest, &IterBest2, fVerbose );
00057 assert( DelayBest == DelayBest2 );
00058 assert( IterBest == IterBest2 );
00059 return 1;
00060 }
00061
00073 int Abc_NtkRetimeMinDelayTry( Abc_Ntk_t * pNtk, int fForward, int fInitial, int nIterLimit, int * pIterBest, int fVerbose )
00074 {
00075 Abc_Ntk_t * pNtkNew = NULL;
00076 Vec_Ptr_t * vCritical;
00077 Vec_Int_t * vValues;
00078 Abc_Obj_t * pObj;
00079 int i, k, IterBest, DelayCur, DelayBest, DelayStart, LatchesBest;
00080
00081 if ( fInitial )
00082 {
00083 if ( fForward )
00084 Abc_NtkRetimeTranferToCopy( pNtk );
00085 else
00086 {
00087
00088 vValues = Abc_NtkRetimeCollectLatchValues( pNtk );
00089
00090 pNtkNew = Abc_NtkRetimeBackwardInitialStart( pNtk );
00091 }
00092 }
00093
00094 if ( fVerbose && !fInitial )
00095 printf( "Performing analysis:\n" );
00096
00097 DelayBest = ABC_INFINITY; IterBest = 0; LatchesBest = Abc_NtkLatchNum(pNtk);
00098 vCritical = Vec_PtrAlloc( 100 );
00099 for ( i = 0; ; i++ )
00100 {
00101
00102 DelayCur = Abc_NtkRetimeTiming( pNtk, fForward, vCritical );
00103 if ( i == 0 )
00104 DelayStart = DelayCur;
00105
00106 if ( DelayBest > DelayCur )
00107 {
00108 if ( fVerbose && !fInitial )
00109 printf( "%s Iter = %3d. Delay = %3d. Latches = %5d. Delta = %6.2f. Ratio = %4.2f %%\n",
00110 fForward ? "Fwd": "Bwd", i, DelayCur, Abc_NtkLatchNum(pNtk),
00111 1.0*(Abc_NtkLatchNum(pNtk)-LatchesBest)/(DelayBest-DelayCur),
00112 100.0*(Abc_NtkLatchNum(pNtk)-LatchesBest)/Abc_NtkLatchNum(pNtk)/(DelayBest-DelayCur) );
00113
00114 DelayBest = DelayCur;
00115 IterBest = i;
00116 LatchesBest = Abc_NtkLatchNum(pNtk);
00117 }
00118
00119 if ( i == nIterLimit )
00120 break;
00121
00122 if ( i - IterBest > 20 )
00123 break;
00124
00125 Vec_PtrForEachEntry( vCritical, pObj, k )
00126 if ( Abc_NtkRetimeNodeIsEnabled(pObj, fForward) )
00127 Abc_NtkRetimeNode( pObj, fForward, fInitial );
00128
00129 if ( !fForward )
00130 Abc_NtkRetimeShareLatches( pNtk, fInitial );
00131 }
00132 Vec_PtrFree( vCritical );
00133
00134 if ( fInitial )
00135 {
00136 if ( fForward )
00137 Abc_NtkRetimeTranferFromCopy( pNtk );
00138 else
00139 {
00140 Abc_NtkRetimeBackwardInitialFinish( pNtk, pNtkNew, vValues, fVerbose );
00141 Abc_NtkDelete( pNtkNew );
00142 Vec_IntFree( vValues );
00143 }
00144 }
00145 if ( fVerbose && !fInitial )
00146 printf( "%s : Starting delay = %3d. Final delay = %3d. IterBest = %2d (out of %2d).\n",
00147 fForward? "Forward " : "Backward", DelayStart, DelayBest, IterBest, nIterLimit );
00148 *pIterBest = (nIterLimit == 1) ? 1 : IterBest;
00149 return DelayBest;
00150 }
00151
00164 int Abc_NtkRetimeTiming( Abc_Ntk_t * pNtk, int fForward, Vec_Ptr_t * vCritical )
00165 {
00166 Vec_Ptr_t * vLatches;
00167 Abc_Obj_t * pObj, * pNext;
00168 int i, k, LevelCur, LevelMax = 0;
00169
00170 Abc_NtkIncrementTravId(pNtk);
00171 vLatches = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) );
00172 Abc_NtkForEachObj( pNtk, pObj, i )
00173 {
00174 if ( Abc_ObjIsLatch(pObj) )
00175 Vec_PtrPush( vLatches, pObj );
00176 if ( Abc_ObjIsNode(pObj) )
00177 continue;
00178 pObj->Level = 0;
00179 Abc_NodeSetTravIdCurrent( pObj );
00180 }
00181
00182 if ( fForward )
00183 {
00184 Vec_PtrForEachEntry( vLatches, pObj, i )
00185 {
00186 Abc_ObjForEachFanout( pObj, pNext, k )
00187 {
00188 LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward );
00189 if ( LevelMax < LevelCur )
00190 LevelMax = LevelCur;
00191 }
00192 }
00193 Abc_NtkForEachPi( pNtk, pObj, i )
00194 {
00195 Abc_ObjForEachFanout( pObj, pNext, k )
00196 {
00197 LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward );
00198 if ( LevelMax < LevelCur )
00199 LevelMax = LevelCur;
00200 }
00201 }
00202 }
00203 else
00204 {
00205 Vec_PtrForEachEntry( vLatches, pObj, i )
00206 {
00207 LevelCur = Abc_NtkRetimeTiming_rec( Abc_ObjFanin0(pObj), fForward );
00208 if ( LevelMax < LevelCur )
00209 LevelMax = LevelCur;
00210 }
00211 Abc_NtkForEachPo( pNtk, pObj, i )
00212 {
00213 LevelCur = Abc_NtkRetimeTiming_rec( Abc_ObjFanin0(pObj), fForward );
00214 if ( LevelMax < LevelCur )
00215 LevelMax = LevelCur;
00216 }
00217 }
00218
00219 Vec_PtrClear( vCritical );
00220 Abc_NtkIncrementTravId(pNtk);
00221 if ( fForward )
00222 {
00223 Vec_PtrForEachEntry( vLatches, pObj, i )
00224 {
00225 Abc_ObjForEachFanout( pObj, pNext, k )
00226 {
00227 if ( Abc_NodeIsTravIdCurrent(pNext) )
00228 continue;
00229 if ( LevelMax != (int)pNext->Level )
00230 continue;
00231
00232 Vec_PtrPush( vCritical, pNext );
00233 Abc_NodeSetTravIdCurrent( pNext );
00234 }
00235 }
00236 }
00237 else
00238 {
00239 Vec_PtrForEachEntry( vLatches, pObj, i )
00240 {
00241 Abc_ObjForEachFanin( pObj, pNext, k )
00242 {
00243 if ( Abc_NodeIsTravIdCurrent(pNext) )
00244 continue;
00245 if ( LevelMax != (int)pNext->Level )
00246 continue;
00247
00248 Vec_PtrPush( vCritical, pNext );
00249 Abc_NodeSetTravIdCurrent( pNext );
00250 }
00251 }
00252 }
00253 Vec_PtrFree( vLatches );
00254 return LevelMax;
00255 }
00256
00269 int Abc_NtkRetimeTiming_rec( Abc_Obj_t * pObj, int fForward )
00270 {
00271 Abc_Obj_t * pNext;
00272 int i, LevelCur, LevelMax = 0;
00273
00274 if ( Abc_NodeIsTravIdCurrent(pObj) )
00275 return pObj->Level;
00276 Abc_NodeSetTravIdCurrent(pObj);
00277
00278 if ( fForward )
00279 {
00280 Abc_ObjForEachFanout( pObj, pNext, i )
00281 {
00282 LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward );
00283 if ( LevelMax < LevelCur )
00284 LevelMax = LevelCur;
00285 }
00286 }
00287 else
00288 {
00289 Abc_ObjForEachFanin( pObj, pNext, i )
00290 {
00291 LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward );
00292 if ( LevelMax < LevelCur )
00293 LevelMax = LevelCur;
00294 }
00295 }
00296
00297 pObj->Level = LevelMax + 1;
00298 return pObj->Level;
00299 }
00300
00304
00305