abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
sclDnsize.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [sclDnsize.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Standard-cell library representation.]
8 
9  Synopsis [Selective decrease of gate sizes.]
10 
11  Author [Alan Mishchenko, Niklas Een]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - August 24, 2012.]
16 
17  Revision [$Id: sclDnsize.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "sclSize.h"
22 
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 /// DECLARATIONS ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 ////////////////////////////////////////////////////////////////////////
31 /// FUNCTION DEFINITIONS ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 /**Function*************************************************************
35 
36  Synopsis [Find the array of nodes to be updated.]
37 
38  Description []
39 
40  SideEffects []
41 
42  SeeAlso []
43 
44 ***********************************************************************/
45 void Abc_SclFindWindow( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int_t ** pvEvals )
46 {
47  Abc_Ntk_t * p = Abc_ObjNtk(pPivot);
48  Abc_Obj_t * pObj, * pNext, * pNext2;
49  Vec_Int_t * vNodes = *pvNodes;
50  Vec_Int_t * vEvals = *pvEvals;
51  int i, k;
52  assert( Abc_ObjIsNode(pPivot) );
53  // collect fanins, node, and fanouts
54  Vec_IntClear( vNodes );
55  Abc_ObjForEachFanin( pPivot, pNext, i )
56 // if ( Abc_ObjIsNode(pNext) && Abc_ObjFaninNum(pNext) > 0 )
57  if ( Abc_ObjIsCi(pNext) || Abc_ObjFaninNum(pNext) > 0 )
58  Vec_IntPush( vNodes, Abc_ObjId(pNext) );
59  Vec_IntPush( vNodes, Abc_ObjId(pPivot) );
60  Abc_ObjForEachFanout( pPivot, pNext, i )
61  if ( Abc_ObjIsNode(pNext) )
62  {
63  Vec_IntPush( vNodes, Abc_ObjId(pNext) );
64  Abc_ObjForEachFanout( pNext, pNext2, k )
65  if ( Abc_ObjIsNode(pNext2) )
66  Vec_IntPush( vNodes, Abc_ObjId(pNext2) );
67  }
68  Vec_IntUniqify( vNodes );
69  // label nodes
70  Abc_NtkForEachObjVec( vNodes, p, pObj, i )
71  {
72  assert( pObj->fMarkB == 0 );
73  pObj->fMarkB = 1;
74  }
75  // collect nodes visible from the critical paths
76  Vec_IntClear( vEvals );
77  Abc_NtkForEachObjVec( vNodes, p, pObj, i )
78  Abc_ObjForEachFanout( pObj, pNext, k )
79  if ( !pNext->fMarkB )
80  {
81  assert( pObj->fMarkB );
82  Vec_IntPush( vEvals, Abc_ObjId(pObj) );
83  break;
84  }
85  assert( Vec_IntSize(vEvals) > 0 );
86  // label nodes
87  Abc_NtkForEachObjVec( vNodes, p, pObj, i )
88  pObj->fMarkB = 0;
89 }
90 
91 /**Function*************************************************************
92 
93  Synopsis [Returns 1 if the node can be improved.]
94 
95  Description [Updated the node to have a new gate.]
96 
97  SideEffects []
98 
99  SeeAlso []
100 
101 ***********************************************************************/
102 int Abc_SclCheckImprovement( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vNodes, Vec_Int_t * vEvals, int Notches, int DelayGap )
103 {
104  Abc_Obj_t * pTemp;
105  SC_Cell * pCellOld, * pCellNew;
106  float dGain, dGainBest;
107  int i, k, gateBest;
108  abctime clk;
109 clk = Abc_Clock();
110 // printf( "%d -> %d\n", Vec_IntSize(vNodes), Vec_IntSize(vEvals) );
111  // save old gate, timing, fanin load
112  pCellOld = Abc_SclObjCell( pObj );
113  Abc_SclConeStore( p, vNodes );
114  Abc_SclEvalStore( p, vEvals );
115  Abc_SclLoadStore( p, pObj );
116  // try different gate sizes for this node
117  gateBest = -1;
118  dGainBest = -DelayGap;
119  SC_RingForEachCellRev( pCellOld, pCellNew, i )
120  {
121  if ( pCellNew->area >= pCellOld->area )
122  continue;
123  if ( i > Notches )
124  break;
125  // set new cell
126  Abc_SclObjSetCell( pObj, pCellNew );
127  Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
128  // recompute timing
129  Abc_SclTimeCone( p, vNodes );
130  // set old cell
131  Abc_SclObjSetCell( pObj, pCellOld );
132  Abc_SclLoadRestore( p, pObj );
133  // evaluate gain
134  dGain = Abc_SclEvalPerformLegal( p, vEvals, p->MaxDelay0 );
135  if ( dGain == -1 )
136  continue;
137  // save best gain
138  if ( dGainBest < dGain )
139  {
140  dGainBest = dGain;
141  gateBest = pCellNew->Id;
142  }
143  }
144  // put back old cell and timing
145  Abc_SclObjSetCell( pObj, pCellOld );
146  Abc_SclConeRestore( p, vNodes );
147 p->timeSize += Abc_Clock() - clk;
148  if ( gateBest >= 0 )
149  {
150  pCellNew = SC_LibCell( p->pLib, gateBest );
151  Abc_SclObjSetCell( pObj, pCellNew );
152  p->SumArea += pCellNew->area - pCellOld->area;
153 // printf( "%f %f -> %f\n", pCellNew->area - pCellOld->area, p->SumArea - (pCellNew->area - pCellOld->area), p->SumArea );
154 // printf( "%6d %20s -> %20s %f -> %f\n", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName, pCellOld->area, pCellNew->area );
155  // mark used nodes with the current trav ID
156  Abc_NtkForEachObjVec( vNodes, p->pNtk, pTemp, k )
157  Abc_NodeSetTravIdCurrent( pTemp );
158  // update load and timing...
159  Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
160  Abc_SclTimeIncInsert( p, pObj );
161  return 1;
162  }
163  return 0;
164 }
165 
166 /**Function*************************************************************
167 
168  Synopsis [Collect nodes by area.]
169 
170  Description []
171 
172  SideEffects []
173 
174  SeeAlso []
175 
176 ***********************************************************************/
178 {
179  Abc_Obj_t * pObj;
180  int i;
181  assert( Vec_QueSize(p->vNodeByGain) == 0 );
182  Vec_QueClear( p->vNodeByGain );
183  Abc_NtkForEachNode( pNtk, pObj, i )
184  if ( Abc_ObjFaninNum(pObj) > 0 )
185  {
186  Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pObj), Abc_SclObjCell(pObj)->area );
187  Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) );
188  }
189 }
190 int Abc_SclCheckOverlap( Abc_Ntk_t * pNtk, Vec_Int_t * vNodes )
191 {
192  Abc_Obj_t * pObj;
193  int i;
194  Abc_NtkForEachObjVec( vNodes, pNtk, pObj, i )
195  if ( Abc_NodeIsTravIdCurrent(pObj) )
196  return 1;
197  return 0;
198 }
199 
200 /**Function*************************************************************
201 
202  Synopsis [Print cumulative statistics.]
203 
204  Description []
205 
206  SideEffects []
207 
208  SeeAlso []
209 
210 ***********************************************************************/
211 void Abc_SclDnsizePrint( SC_Man * p, int Iter, int nAttempts, int nOverlaps, int nChanges, int fVerbose )
212 {
213  if ( Iter == -1 )
214  printf( "Total : " );
215  else
216  printf( "%5d : ", Iter );
217  printf( "Try =%6d ", nAttempts );
218  printf( "Over =%6d ", nOverlaps );
219  printf( "Fail =%6d ", nAttempts-nOverlaps-nChanges );
220  printf( "Win =%6d ", nChanges );
221  printf( "A: " );
222  printf( "%.2f ", p->SumArea );
223  printf( "(%+5.1f %%) ", 100.0 * (p->SumArea - p->SumArea0)/ p->SumArea0 );
224  printf( "D: " );
225  printf( "%.2f ps ", p->MaxDelay );
226  printf( "(%+5.1f %%) ", 100.0 * (p->MaxDelay - p->MaxDelay0)/ p->MaxDelay0 );
227  printf( "%8.2f sec ", 1.0*(Abc_Clock() - p->timeTotal)/(CLOCKS_PER_SEC) );
228  printf( "%c", fVerbose ? '\n' : '\r' );
229 }
230 
231 /**Function*************************************************************
232 
233  Synopsis []
234 
235  Description []
236 
237  SideEffects []
238 
239  SeeAlso []
240 
241 ***********************************************************************/
242 void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars )
243 {
244  SC_Man * p;
245  Abc_Obj_t * pObj;
246  Vec_Int_t * vNodes, * vEvals, * vTryLater;
247  abctime clk, nRuntimeLimit = pPars->TimeOut ? pPars->TimeOut * CLOCKS_PER_SEC + Abc_Clock() : 0;
248  int i, k;
249 
250  if ( pPars->fVerbose )
251  {
252  printf( "Parameters: " );
253  printf( "Iters =%5d. ", pPars->nIters );
254  printf( "UseDept =%2d. ", pPars->fUseDept );
255  printf( "UseWL =%2d. ", pPars->fUseWireLoads );
256  printf( "Target =%5d ps. ", pPars->DelayUser );
257  printf( "DelayGap =%3d ps. ", pPars->DelayGap );
258  printf( "Timeout =%4d sec", pPars->TimeOut );
259  printf( "\n" );
260  }
261 
262  // prepare the manager; collect init stats
263  p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, pPars->DelayUser, pPars->BuffTreeEst );
264  p->timeTotal = Abc_Clock();
265  assert( p->vGatesBest == NULL );
266  p->vGatesBest = Vec_IntDup( p->pNtk->vGates );
267 
268  // perform upsizing
269  vNodes = Vec_IntAlloc( 1000 );
270  vEvals = Vec_IntAlloc( 1000 );
271  vTryLater = Vec_IntAlloc( 1000 );
272  for ( i = 0; i < pPars->nIters; i++ )
273  {
274  int nRounds = 0;
275  int nAttemptAll = 0, nOverlapAll = 0, nChangesAll = 0;
276  Abc_NtkCollectNodesByArea( p, pNtk );
277  while ( Vec_QueSize(p->vNodeByGain) > 0 )
278  {
279  int nAttempt = 0, nOverlap = 0, nChanges = 0;
280  Vec_IntClear( vTryLater );
281  Abc_NtkIncrementTravId( pNtk );
282  while ( Vec_QueSize(p->vNodeByGain) > 0 )
283  {
284  clk = Abc_Clock();
285  pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) );
286  Abc_SclFindWindow( pObj, &vNodes, &vEvals );
287  p->timeCone += Abc_Clock() - clk;
288  if ( Abc_SclCheckOverlap( p->pNtk, vNodes ) )
289  nOverlap++, Vec_IntPush( vTryLater, Abc_ObjId(pObj) );
290  else
291  nChanges += Abc_SclCheckImprovement( p, pObj, vNodes, vEvals, pPars->Notches, pPars->DelayGap );
292  nAttempt++;
293  }
294  Abc_NtkForEachObjVec( vTryLater, pNtk, pObj, k )
295  Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) );
296 
297  clk = Abc_Clock();
298  if ( Vec_IntSize(p->vChanged) )
300  else
301  Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay, pPars->fUseDept, pPars->DelayUser );
302  p->timeTime += Abc_Clock() - clk;
303 
304  p->MaxDelay = Abc_SclReadMaxDelay( p );
305  if ( pPars->fUseDept && pPars->DelayUser > 0 && p->MaxDelay < pPars->DelayUser )
306  p->MaxDelay = pPars->DelayUser;
307  Abc_SclDnsizePrint( p, nRounds++, nAttempt, nOverlap, nChanges, pPars->fVeryVerbose );
308  nAttemptAll += nAttempt; nOverlapAll += nOverlap; nChangesAll += nChanges;
309  if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit )
310  break;
311  }
312  // recompute
313 // Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay, pPars->fUseDept, pPars->DelayUser );
314  if ( pPars->fVerbose )
315  Abc_SclDnsizePrint( p, -1, nAttemptAll, nOverlapAll, nChangesAll, 1 );
316  if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit )
317  break;
318  if ( nAttemptAll == 0 )
319  break;
320  }
321  Vec_IntFree( vNodes );
322  Vec_IntFree( vEvals );
323  Vec_IntFree( vTryLater );
324  if ( !pPars->fVerbose )
325  printf( " \r" );
326 
327  // report runtime
328  p->timeTotal = Abc_Clock() - p->timeTotal;
329  if ( pPars->fVerbose )
330  {
331  p->timeOther = p->timeTotal - p->timeCone - p->timeSize - p->timeTime;
332  ABC_PRTP( "Runtime: Critical path", p->timeCone, p->timeTotal );
333  ABC_PRTP( "Runtime: Sizing eval ", p->timeSize, p->timeTotal );
334  ABC_PRTP( "Runtime: Timing update", p->timeTime, p->timeTotal );
335  ABC_PRTP( "Runtime: Other ", p->timeOther, p->timeTotal );
336  ABC_PRTP( "Runtime: TOTAL ", p->timeTotal, p->timeTotal );
337  }
338  if ( pPars->fDumpStats )
339  Abc_SclDumpStats( p, "stats2.txt", p->timeTotal );
340  if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit )
341  printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut );
342 
343  // save the result and quit
344  Abc_SclSclGates2MioGates( pLib, pNtk ); // updates gate pointers
345  Abc_SclManFree( p );
346 // Abc_NtkCleanMarkAB( pNtk );
347 }
348 
349 ////////////////////////////////////////////////////////////////////////
350 /// END OF FILE ///
351 ////////////////////////////////////////////////////////////////////////
352 
353 
355 
static unsigned Abc_ObjId(Abc_Obj_t *pObj)
Definition: abc.h:329
static float Abc_SclReadMaxDelay(SC_Man *p)
Definition: sclSize.h:474
void Abc_SclTimeNtkRecompute(SC_Man *p, float *pArea, float *pDelay, int fReverse, float DUser)
Definition: sclSize.c:400
ABC_NAMESPACE_IMPL_START void Abc_SclFindWindow(Abc_Obj_t *pPivot, Vec_Int_t **pvNodes, Vec_Int_t **pvEvals)
DECLARATIONS ///.
Definition: sclDnsize.c:45
static int Abc_ObjIsCi(Abc_Obj_t *pObj)
Definition: abc.h:351
static void Abc_SclConeStore(SC_Man *p, Vec_Int_t *vCone)
Definition: sclSize.h:339
void Abc_SclTimeIncInsert(SC_Man *p, Abc_Obj_t *pObj)
Definition: sclSize.c:562
static void Vec_FltWriteEntry(Vec_Flt_t *p, int i, float Entry)
Definition: vecFlt.h:364
static Vec_Int_t * Vec_IntDup(Vec_Int_t *pVec)
Definition: vecInt.h:214
static Llb_Mgr_t * p
Definition: llb3Image.c:950
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
int DelayGap
Definition: sclLib.h:78
static void Abc_SclConeRestore(SC_Man *p, Vec_Int_t *vCone)
Definition: sclSize.h:352
int TimeOut
Definition: sclLib.h:79
static void Abc_SclObjSetCell(Abc_Obj_t *p, SC_Cell *pCell)
Definition: sclSize.h:111
static int Abc_ObjFaninNum(Abc_Obj_t *pObj)
Definition: abc.h:364
int fVeryVerbose
Definition: sclLib.h:86
#define SC_RingForEachCellRev(pRing, pCell, i)
Definition: sclLib.h:257
static int Vec_QuePop(Vec_Que_t *p)
Definition: vecQue.h:234
typedefABC_NAMESPACE_HEADER_START struct SC_Man_ SC_Man
INCLUDES ///.
Definition: sclSize.h:44
static abctime Abc_Clock()
Definition: abc_global.h:279
void Abc_NtkCollectNodesByArea(SC_Man *p, Abc_Ntk_t *pNtk)
Definition: sclDnsize.c:177
static Abc_Obj_t * Abc_NtkObj(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:314
int fVerbose
Definition: sclLib.h:85
int Abc_SclTimeIncUpdate(SC_Man *p)
Definition: sclSize.c:540
static void Abc_SclLoadStore(SC_Man *p, Abc_Obj_t *pObj)
Definition: sclSize.h:290
#define ABC_PRTP(a, t, T)
Definition: abc_global.h:223
static void Vec_QueClear(Vec_Que_t *p)
Definition: vecQue.h:110
static int Vec_QueSize(Vec_Que_t *p)
Definition: vecQue.h:134
static void Abc_SclLoadRestore(SC_Man *p, Abc_Obj_t *pObj)
Definition: sclSize.h:301
static int Abc_ObjIsNode(Abc_Obj_t *pObj)
Definition: abc.h:355
int fUseWireLoads
Definition: sclLib.h:84
static void Abc_SclManFree(SC_Man *p)
Definition: sclSize.h:192
static void Abc_SclDumpStats(SC_Man *p, char *pFileName, abctime Time)
Definition: sclSize.h:510
float area
Definition: sclLib.h:188
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: bblif.c:149
#define Abc_NtkForEachObjVec(vIds, pNtk, pObj, i)
Definition: abc.h:452
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
int Abc_SclCheckOverlap(Abc_Ntk_t *pNtk, Vec_Int_t *vNodes)
Definition: sclDnsize.c:190
int Id
Definition: sclLib.h:184
static int Vec_IntUniqify(Vec_Int_t *p)
Definition: vecInt.h:1314
static void Vec_IntPush(Vec_Int_t *p, int Entry)
Definition: bblif.c:468
void Abc_SclDnsizePrint(SC_Man *p, int Iter, int nAttempts, int nOverlaps, int nChanges, int fVerbose)
Definition: sclDnsize.c:211
int DelayUser
Definition: sclLib.h:77
static SC_Cell * SC_LibCell(SC_Lib *p, int i)
Definition: sclLib.h:240
void Abc_SclSclGates2MioGates(SC_Lib *pLib, Abc_Ntk_t *p)
Definition: sclUtil.c:73
static void Abc_SclEvalStore(SC_Man *p, Vec_Int_t *vCone)
Definition: sclSize.h:365
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition: abc.h:461
int Notches
Definition: sclLib.h:76
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
void Abc_SclTimeCone(SC_Man *p, Vec_Int_t *vCone)
Definition: sclSize.c:383
int fUseDept
Definition: sclLib.h:82
static int Abc_NodeIsTravIdCurrent(Abc_Obj_t *p)
Definition: abc.h:411
unsigned fMarkB
Definition: abc.h:135
static int Vec_IntSize(Vec_Int_t *p)
Definition: bblif.c:252
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition: abc.h:526
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition: abc.h:524
static void Abc_NtkIncrementTravId(Abc_Ntk_t *p)
Definition: abc.h:406
int nIters
Definition: sclLib.h:72
#define assert(ex)
Definition: util_old.h:213
static Abc_Ntk_t * Abc_ObjNtk(Abc_Obj_t *pObj)
Definition: abc.h:334
int Abc_SclCheckImprovement(SC_Man *p, Abc_Obj_t *pObj, Vec_Int_t *vNodes, Vec_Int_t *vEvals, int Notches, int DelayGap)
Definition: sclDnsize.c:102
int BuffTreeEst
Definition: sclLib.h:80
static void Vec_IntFree(Vec_Int_t *p)
Definition: bblif.c:235
static void Vec_IntClear(Vec_Int_t *p)
Definition: bblif.c:452
ABC_INT64_T abctime
Definition: abc_global.h:278
static float Abc_SclEvalPerformLegal(SC_Man *p, Vec_Int_t *vCone, float D)
Definition: sclSize.h:390
int fDumpStats
Definition: sclLib.h:83
static void Vec_QuePush(Vec_Que_t *p, int v)
Definition: vecQue.h:221
void Abc_SclDnsizePerform(SC_Lib *pLib, Abc_Ntk_t *pNtk, SC_SizePars *pPars)
Definition: sclDnsize.c:242
static void Abc_NodeSetTravIdCurrent(Abc_Obj_t *p)
Definition: abc.h:409
void Abc_SclUpdateLoad(SC_Man *p, Abc_Obj_t *pObj, SC_Cell *pOld, SC_Cell *pNew)
Definition: sclLoad.c:199
static SC_Cell * Abc_SclObjCell(Abc_Obj_t *p)
Definition: sclSize.h:110
SC_Man * Abc_SclManStart(SC_Lib *pLib, Abc_Ntk_t *pNtk, int fUseWireLoads, int fDept, float DUser, int nTreeCRatio)
Definition: sclSize.c:633