#include "retInt.h"
Go to the source code of this file.
Enumerations | |
enum | { ABC_RET_UPDATE_FAIL, ABC_RET_UPDATE_NO, ABC_RET_UPDATE_YES } |
Functions | |
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_NodeComputeLag (int LValue, int Fi) |
static int | Abc_NodeGetLValue (Abc_Obj_t *pNode) |
static void | Abc_NodeSetLValue (Abc_Obj_t *pNode, int Value) |
int | Abc_NtkRetimeLValue (Abc_Ntk_t *pNtk, int nIterLimit, int fVerbose) |
void | Abc_ManCollectLatches_rec (Abc_Obj_t *pObj, Vec_Ptr_t *vLatches) |
anonymous enum |
CFile****************************************************************
FileName [retLvalue.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Retiming package.]
Synopsis [Implementation of Pan's retiming algorithm.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - Oct 31, 2006.]
Revision [
] DECLARATIONS ///
Definition at line 28 of file retLvalue.c.
00028 { ABC_RET_UPDATE_FAIL, ABC_RET_UPDATE_NO, ABC_RET_UPDATE_YES };
Function*************************************************************
Synopsis [Collects latches in the topological order.]
Description []
SideEffects []
SeeAlso []
Definition at line 333 of file retLvalue.c.
00334 { 00335 Vec_Ptr_t * vLatches; 00336 Abc_Obj_t * pObj; 00337 int i; 00338 vLatches = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) ); 00339 Abc_NtkIncrementTravId( pNtk ); 00340 Abc_NtkForEachLatch( pNtk, pObj, i ) 00341 Abc_ManCollectLatches_rec( pObj, vLatches ); 00342 assert( Vec_PtrSize(vLatches) == Abc_NtkLatchNum(pNtk) ); 00343 return vLatches; 00344 }
Function*************************************************************
Synopsis [Collects latches in the topological order.]
Description []
SideEffects []
SeeAlso []
Definition at line 304 of file retLvalue.c.
00305 { 00306 Abc_Obj_t * pDriver; 00307 if ( !Abc_ObjIsLatch(pObj) ) 00308 return; 00309 // skip already collected latches 00310 if ( Abc_NodeIsTravIdCurrent(pObj) ) 00311 return; 00312 Abc_NodeSetTravIdCurrent(pObj); 00313 // get the driver node feeding into the latch 00314 pDriver = Abc_ObjFanin0(Abc_ObjFanin0(pObj)); 00315 // call recursively if the driver looks like a latch output 00316 if ( Abc_ObjIsBo(pDriver) ) 00317 Abc_ManCollectLatches_rec( Abc_ObjFanin0(pDriver), vLatches ); 00318 // collect the latch 00319 Vec_PtrPush( vLatches, pObj ); 00320 }
static int Abc_NodeComputeLag | ( | int | LValue, | |
int | Fi | |||
) | [inline, static] |
Definition at line 39 of file retLvalue.c.
static int Abc_NodeGetLValue | ( | Abc_Obj_t * | pNode | ) | [inline, static] |
Definition at line 40 of file retLvalue.c.
00040 { return (int)pNode->pCopy; }
static void Abc_NodeSetLValue | ( | Abc_Obj_t * | pNode, | |
int | Value | |||
) | [inline, static] |
Definition at line 41 of file retLvalue.c.
00041 { pNode->pCopy = (void *)Value; }
int Abc_NtkRetimeForPeriod | ( | Abc_Ntk_t * | pNtk, | |
Vec_Ptr_t * | vNodes, | |||
Vec_Ptr_t * | vLatches, | |||
int | Fi, | |||
int | nMaxIters, | |||
int | fVerbose | |||
) | [static] |
Function*************************************************************
Synopsis [Returns 1 if retiming with this clock period is feasible.]
Description []
SideEffects []
SeeAlso []
Definition at line 191 of file retLvalue.c.
00192 { 00193 Abc_Obj_t * pObj; 00194 int c, i, fConverged; 00195 // set l-values of all nodes to be minus infinity, except PIs and constants 00196 Abc_NtkForEachObj( pNtk, pObj, i ) 00197 if ( Abc_ObjFaninNum(pObj) == 0 ) 00198 Abc_NodeSetLValue( pObj, 0 ); 00199 else 00200 Abc_NodeSetLValue( pObj, -ABC_INFINITY ); 00201 // update all values iteratively 00202 fConverged = 0; 00203 for ( c = 1; c <= nMaxIters; c++ ) 00204 { 00205 if ( !Abc_NtkRetimeUpdateLValue( pNtk, vNodes, vLatches, Fi ) ) 00206 { 00207 fConverged = 1; 00208 break; 00209 } 00210 if ( Abc_NtkRetimePosOverLimit(pNtk, Fi) ) 00211 break; 00212 } 00213 // report the results 00214 if ( fVerbose ) 00215 { 00216 if ( !fConverged ) 00217 printf( "Period = %3d. Iterations = %3d. Infeasible %s\n", Fi, c, (c > nMaxIters)? "(timeout)" : "" ); 00218 else 00219 printf( "Period = %3d. Iterations = %3d. Feasible\n", Fi, c ); 00220 } 00221 /* 00222 // check if any AND gates have infinite delay 00223 Counter = 0; 00224 Abc_NtkForEachNode( pNtk, pObj, i ) 00225 Counter += (Abc_NodeGetLValue(pObj) < -ABC_INFINITY/2); 00226 if ( Counter > 0 ) 00227 printf( "Warning: %d internal nodes have wrong l-values!\n", Counter ); 00228 */ 00229 return fConverged; 00230 }
Function*************************************************************
Synopsis [Computes the retiming lags.]
Description []
SideEffects []
SeeAlso []
Definition at line 88 of file retLvalue.c.
00089 { 00090 Vec_Int_t * vLags; 00091 Vec_Ptr_t * vNodes, * vLatches; 00092 Abc_Obj_t * pNode; 00093 int i, FiMax, FiBest, RetValue, clk, clkIter; 00094 char NodeLag; 00095 00096 // get the upper bound on the clock period 00097 FiMax = Abc_NtkLevel(pNtk); 00098 00099 // make sure this clock period is feasible 00100 vNodes = Abc_NtkDfs( pNtk, 0 ); 00101 vLatches = Abc_ManCollectLatches( pNtk ); 00102 if ( !Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, FiMax, nIterLimit, fVerbose ) ) 00103 { 00104 Vec_PtrFree( vNodes ); 00105 printf( "Abc_NtkRetimeGetLags() error: The upper bound on the clock period cannot be computed.\n" ); 00106 return Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 ); 00107 } 00108 00109 // search for the optimal clock period between 0 and nLevelMax 00110 clk = clock(); 00111 FiBest = Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, 0, FiMax, nIterLimit, fVerbose ); 00112 clkIter = clock() - clk; 00113 00114 // recompute the best l-values 00115 RetValue = Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, FiBest, nIterLimit, fVerbose ); 00116 assert( RetValue ); 00117 00118 // fix the problem with non-converged delays 00119 Abc_NtkForEachNode( pNtk, pNode, i ) 00120 if ( Abc_NodeGetLValue(pNode) < -ABC_INFINITY/2 ) 00121 Abc_NodeSetLValue( pNode, 0 ); 00122 00123 // write the retiming lags 00124 vLags = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 ); 00125 Abc_NtkForEachNode( pNtk, pNode, i ) 00126 { 00127 NodeLag = Abc_NodeComputeLag( Abc_NodeGetLValue(pNode), FiBest ); 00128 Vec_IntWriteEntry( vLags, pNode->Id, NodeLag ); 00129 } 00130 /* 00131 Abc_NtkForEachPo( pNtk, pNode, i ) 00132 printf( "%d ", Abc_NodeGetLValue(Abc_ObjFanin0(pNode)) ); 00133 printf( "\n" ); 00134 Abc_NtkForEachLatch( pNtk, pNode, i ) 00135 printf( "%d/%d ", Abc_NodeGetLValue(Abc_ObjFanout0(pNode)), Abc_NodeGetLValue(Abc_ObjFanout0(pNode)) + FiBest ); 00136 printf( "\n" ); 00137 */ 00138 00139 // print the result 00140 // if ( fVerbose ) 00141 printf( "The best clock period is %3d. (Currently, network is not modified.)\n", FiBest ); 00142 /* 00143 { 00144 FILE * pTable; 00145 pTable = fopen( "iscas/seqmap__stats2.txt", "a+" ); 00146 fprintf( pTable, "%d ", FiBest ); 00147 fprintf( pTable, "\n" ); 00148 fclose( pTable ); 00149 } 00150 */ 00151 Vec_PtrFree( vNodes ); 00152 Vec_PtrFree( vLatches ); 00153 return vLags; 00154 }
int Abc_NtkRetimeLValue | ( | Abc_Ntk_t * | pNtk, | |
int | nIterLimit, | |||
int | fVerbose | |||
) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Implements Pan's retiming algorithm.]
Description []
SideEffects []
SeeAlso []
Definition at line 58 of file retLvalue.c.
00059 { 00060 Vec_Int_t * vLags; 00061 int nLatches = Abc_NtkLatchNum(pNtk); 00062 assert( Abc_NtkIsLogic( pNtk ) ); 00063 // get the lags 00064 vLags = Abc_NtkRetimeGetLags( pNtk, nIterLimit, fVerbose ); 00065 // compute the retiming 00066 // Abc_NtkRetimeUsingLags( pNtk, vLags, fVerbose ); 00067 Vec_IntFree( vLags ); 00068 // fix the COs 00069 // Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); 00070 // check for correctness 00071 if ( !Abc_NtkCheck( pNtk ) ) 00072 fprintf( stdout, "Abc_NtkRetimeLValue(): Network check has failed.\n" ); 00073 // return the number of latches saved 00074 return nLatches - Abc_NtkLatchNum(pNtk); 00075 }
int Abc_NtkRetimePosOverLimit | ( | Abc_Ntk_t * | pNtk, | |
int | Fi | |||
) | [static] |
Function*************************************************************
Synopsis [Detects the case when l-values exceeded the limit.]
Description []
SideEffects []
SeeAlso []
Definition at line 283 of file retLvalue.c.
00284 { 00285 Abc_Obj_t * pObj; 00286 int i; 00287 Abc_NtkForEachPo( pNtk, pObj, i ) 00288 if ( Abc_NodeGetLValue(Abc_ObjFanin0(pObj)) > Fi ) 00289 return 1; 00290 return 0; 00291 }
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] |
Function*************************************************************
Synopsis [Performs binary search for the optimal clock period.]
Description [Assumes that FiMin is infeasible while FiMax is feasible.]
SideEffects []
SeeAlso []
Definition at line 167 of file retLvalue.c.
00168 { 00169 int Median; 00170 assert( FiMin < FiMax ); 00171 if ( FiMin + 1 == FiMax ) 00172 return FiMax; 00173 Median = FiMin + (FiMax - FiMin)/2; 00174 if ( Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, Median, nMaxIters, fVerbose ) ) 00175 return Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, FiMin, Median, nMaxIters, fVerbose ); // Median is feasible 00176 else 00177 return Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, Median, FiMax, nMaxIters, fVerbose ); // Median is infeasible 00178 }
int Abc_NtkRetimeUpdateLValue | ( | Abc_Ntk_t * | pNtk, | |
Vec_Ptr_t * | vNodes, | |||
Vec_Ptr_t * | vLatches, | |||
int | Fi | |||
) | [static] |
Function*************************************************************
Synopsis [Performs one iteration of l-value computation for the 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 []
Definition at line 244 of file retLvalue.c.
00245 { 00246 Abc_Obj_t * pObj, * pFanin; 00247 int i, k, lValueNew, fChange; 00248 // go through the nodes and detect change 00249 fChange = 0; 00250 Vec_PtrForEachEntry( vNodes, pObj, i ) 00251 { 00252 assert( Abc_ObjIsNode(pObj) ); 00253 lValueNew = -ABC_INFINITY; 00254 Abc_ObjForEachFanin( pObj, pFanin, k ) 00255 { 00256 if ( lValueNew < Abc_NodeGetLValue(pFanin) ) 00257 lValueNew = Abc_NodeGetLValue(pFanin); 00258 } 00259 lValueNew++; 00260 if ( Abc_NodeGetLValue(pObj) < lValueNew ) 00261 { 00262 Abc_NodeSetLValue( pObj, lValueNew ); 00263 fChange = 1; 00264 } 00265 } 00266 // propagate values through the latches 00267 Vec_PtrForEachEntry( vLatches, pObj, i ) 00268 Abc_NodeSetLValue( Abc_ObjFanout0(pObj), Abc_NodeGetLValue(Abc_ObjFanin0(Abc_ObjFanin0(pObj))) - Fi ); 00269 return fChange; 00270 }
Function*************************************************************
Synopsis [Implements the retiming given as the array of retiming lags.]
Description []
SideEffects []
SeeAlso []
Definition at line 357 of file retLvalue.c.
00358 { 00359 Abc_Obj_t * pObj; 00360 int fChanges, fForward, nTotalMoves, Lag, Counter, i; 00361 // iterate over the nodes 00362 nTotalMoves = 0; 00363 do { 00364 fChanges = 0; 00365 Abc_NtkForEachNode( pNtk, pObj, i ) 00366 { 00367 Lag = Vec_IntEntry( vLags, pObj->Id ); 00368 if ( !Lag ) 00369 continue; 00370 fForward = (Lag < 0); 00371 if ( Abc_NtkRetimeNodeIsEnabled( pObj, fForward ) ) 00372 { 00373 Abc_NtkRetimeNode( pObj, fForward, 0 ); 00374 fChanges = 1; 00375 nTotalMoves++; 00376 Vec_IntAddToEntry( vLags, pObj->Id, fForward? 1 : -1 ); 00377 } 00378 } 00379 } while ( fChanges ); 00380 if ( fVerbose ) 00381 printf( "Total latch moves = %d.\n", nTotalMoves ); 00382 // check if there are remaining lags 00383 Counter = 0; 00384 Abc_NtkForEachNode( pNtk, pObj, i ) 00385 Counter += (Vec_IntEntry( vLags, pObj->Id ) != 0); 00386 if ( Counter ) 00387 printf( "Warning! The number of nodes with unrealized lag = %d.\n", Counter ); 00388 return 1; 00389 }