1 /**CFile****************************************************************
2
3 FileName [sclBuffer.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Standard-cell library representation.]
8
9 Synopsis [Buffering algorithms.]
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: sclBuffer.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "sclSize.h"
22 #include "map/mio/mio.h"
23
24 ABC_NAMESPACE_IMPL_START
25
26
27 ////////////////////////////////////////////////////////////////////////
28 /// DECLARATIONS ///
29 ////////////////////////////////////////////////////////////////////////
30
31 #define BUF_SCALE 1000
32
33 typedef struct Buf_Man_t_ Buf_Man_t;
34 struct Buf_Man_t_
35 {
36 // parameters
37 int nFanMin; // the smallest fanout count to consider
38 int nFanMax; // the largest fanout count allowed off CP
39 int fBufPis; // enables buffing of the combinational inputs
40 // internal deta
41 Abc_Ntk_t * pNtk; // logic network
42 Vec_Int_t * vOffsets; // offsets into edge delays
43 Vec_Int_t * vEdges; // edge delays
44 Vec_Int_t * vArr; // arrival times
45 Vec_Int_t * vDep; // departure times
46 Vec_Flt_t * vCounts; // fanout counts
47 Vec_Que_t * vQue; // queue by fanout count
48 int nObjStart; // the number of starting objects
49 int nObjAlloc; // the number of allocated objects
50 int DelayMax; // maximum delay (percentage of inverter delay)
51 float DelayInv; // inverter delay
52 // sorting fanouts
53 Vec_Int_t * vOrder; // ordering of fanouts
54 Vec_Int_t * vDelays; // fanout delays
55 Vec_Int_t * vNonCrit; // non-critical fanouts
56 Vec_Int_t * vTfCone; // TFI/TFO cone of the node including the node
57 Vec_Ptr_t * vFanouts; // temp storage for fanouts
58 // statistics
59 int nSeparate;
60 int nDuplicate;
61 int nBranch0;
62 int nBranch1;
63 int nBranchCrit;
64 };
65
Abc_BufNodeArr(Buf_Man_t * p,Abc_Obj_t * pObj)66 static inline int Abc_BufNodeArr( Buf_Man_t * p, Abc_Obj_t * pObj ) { return Vec_IntEntry( p->vArr, Abc_ObjId(pObj) ); }
Abc_BufNodeDep(Buf_Man_t * p,Abc_Obj_t * pObj)67 static inline int Abc_BufNodeDep( Buf_Man_t * p, Abc_Obj_t * pObj ) { return Vec_IntEntry( p->vDep, Abc_ObjId(pObj) ); }
Abc_BufSetNodeArr(Buf_Man_t * p,Abc_Obj_t * pObj,int f)68 static inline void Abc_BufSetNodeArr( Buf_Man_t * p, Abc_Obj_t * pObj, int f ) { Vec_IntWriteEntry( p->vArr, Abc_ObjId(pObj), f ); }
Abc_BufSetNodeDep(Buf_Man_t * p,Abc_Obj_t * pObj,int f)69 static inline void Abc_BufSetNodeDep( Buf_Man_t * p, Abc_Obj_t * pObj, int f ) { Vec_IntWriteEntry( p->vDep, Abc_ObjId(pObj), f ); }
Abc_BufEdgeDelay(Buf_Man_t * p,Abc_Obj_t * pObj,int i)70 static inline int Abc_BufEdgeDelay( Buf_Man_t * p, Abc_Obj_t * pObj, int i ) { return Vec_IntEntry( p->vEdges, Vec_IntEntry(p->vOffsets, Abc_ObjId(pObj)) + i ); }
Abc_BufSetEdgeDelay(Buf_Man_t * p,Abc_Obj_t * pObj,int i,int f)71 static inline void Abc_BufSetEdgeDelay( Buf_Man_t * p, Abc_Obj_t * pObj, int i, int f ) { Vec_IntWriteEntry( p->vEdges, Vec_IntEntry(p->vOffsets, Abc_ObjId(pObj)) + i, f ); }
Abc_BufNodeSlack(Buf_Man_t * p,Abc_Obj_t * pObj)72 static inline int Abc_BufNodeSlack( Buf_Man_t * p, Abc_Obj_t * pObj ) { return p->DelayMax - Abc_BufNodeArr(p, pObj) - Abc_BufNodeDep(p, pObj); }
Abc_BufEdgeSlack(Buf_Man_t * p,Abc_Obj_t * pObj,Abc_Obj_t * pFan)73 static inline int Abc_BufEdgeSlack( Buf_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pFan ) { return p->DelayMax - Abc_BufNodeArr(p, pObj) - Abc_BufNodeDep(p, pFan) - Abc_BufEdgeDelay(p, pFan, Abc_NodeFindFanin(pFan, pObj)); }
74
75 ////////////////////////////////////////////////////////////////////////
76 /// FUNCTION DEFINITIONS ///
77 ////////////////////////////////////////////////////////////////////////
78
79 /**Function*************************************************************
80
81 Synopsis [Make sure fanins of gates are not duplicated.]
82
83 Description []
84
85 SideEffects []
86
87 SeeAlso []
88
89 ***********************************************************************/
Abc_SclReportDupFanins(Abc_Ntk_t * pNtk)90 void Abc_SclReportDupFanins( Abc_Ntk_t * pNtk )
91 {
92 Abc_Obj_t * pObj, * pFanin, * pFanin2;
93 int i, k, k2;
94 Abc_NtkForEachNode( pNtk, pObj, i )
95 Abc_ObjForEachFanin( pObj, pFanin, k )
96 Abc_ObjForEachFanin( pObj, pFanin2, k2 )
97 if ( k != k2 && pFanin == pFanin2 )
98 printf( "Node %d has dup fanin %d.\n", i, Abc_ObjId(pFanin) );
99 }
100
101 /**Function*************************************************************
102
103 Synopsis [Removes buffers and inverters.]
104
105 Description []
106
107 SideEffects []
108
109 SeeAlso []
110
111 ***********************************************************************/
Abc_SclObjIsBufInv(Abc_Obj_t * pObj)112 static inline int Abc_SclObjIsBufInv( Abc_Obj_t * pObj )
113 {
114 return Abc_ObjIsNode(pObj) && Abc_ObjFaninNum(pObj) == 1;
115 }
Abc_SclIsInv(Abc_Obj_t * pObj)116 int Abc_SclIsInv( Abc_Obj_t * pObj )
117 {
118 assert( Abc_ObjIsNode(pObj) );
119 return Mio_GateReadTruth((Mio_Gate_t *)pObj->pData) == ABC_CONST(0x5555555555555555);
120 }
Abc_SclGetRealFaninLit(Abc_Obj_t * pObj)121 int Abc_SclGetRealFaninLit( Abc_Obj_t * pObj )
122 {
123 int iLit;
124 if ( !Abc_SclObjIsBufInv(pObj) )
125 return Abc_Var2Lit( Abc_ObjId(pObj), 0 );
126 iLit = Abc_SclGetRealFaninLit( Abc_ObjFanin0(pObj) );
127 return Abc_LitNotCond( iLit, Abc_SclIsInv(pObj) );
128 }
Abc_SclUnBufferPerform(Abc_Ntk_t * pNtk,int fVerbose)129 Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose )
130 {
131 Vec_Int_t * vLits;
132 Abc_Obj_t * pObj, * pFanin, * pFaninNew;
133 int i, k, iLit, nNodesOld = Abc_NtkObjNumMax(pNtk);
134 // assign inverters
135 vLits = Vec_IntStartFull( Abc_NtkObjNumMax(pNtk) );
136 Abc_NtkForEachNode( pNtk, pObj, i )
137 if ( Abc_SclIsInv(pObj) && !Abc_SclObjIsBufInv(Abc_ObjFanin0(pObj)) )
138 Vec_IntWriteEntry( vLits, Abc_ObjFaninId0(pObj), Abc_ObjId(pObj) );
139 // transfer fanins
140 Abc_NtkForEachNodeCo( pNtk, pObj, i )
141 {
142 if ( i >= nNodesOld )
143 break;
144 Abc_ObjForEachFanin( pObj, pFanin, k )
145 {
146 if ( !Abc_SclObjIsBufInv(pFanin) )
147 continue;
148 iLit = Abc_SclGetRealFaninLit( pFanin );
149 pFaninNew = Abc_NtkObj( pNtk, Abc_Lit2Var(iLit) );
150 if ( Abc_LitIsCompl(iLit) )
151 {
152 if ( Vec_IntEntry( vLits, Abc_Lit2Var(iLit) ) == -1 )
153 {
154 pFaninNew = Abc_NtkCreateNodeInv( pNtk, pFaninNew );
155 Vec_IntWriteEntry( vLits, Abc_Lit2Var(iLit), Abc_ObjId(pFaninNew) );
156 }
157 else
158 pFaninNew = Abc_NtkObj( pNtk, Vec_IntEntry( vLits, Abc_Lit2Var(iLit) ) );
159 assert( Abc_ObjFaninNum(pFaninNew) == 1 );
160 }
161 if ( pFanin != pFaninNew )
162 Abc_ObjPatchFanin( pObj, pFanin, pFaninNew );
163 }
164 }
165 Vec_IntFree( vLits );
166 // duplicate network in topo order
167 return Abc_NtkDupDfs( pNtk );
168 }
169
170 /**Function*************************************************************
171
172 Synopsis [Removes buffers and inverters.]
173
174 Description []
175
176 SideEffects []
177
178 SeeAlso []
179
180 ***********************************************************************/
Abc_SclCountMaxPhases(Abc_Ntk_t * pNtk)181 int Abc_SclCountMaxPhases( Abc_Ntk_t * pNtk )
182 {
183 Vec_Int_t * vPhLevel;
184 Abc_Obj_t * pObj, * pFanin;
185 int i, k, Max = 0, MaxAll = 0;
186 vPhLevel = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
187 Abc_NtkForEachNodeCo( pNtk, pObj, i )
188 {
189 Max = 0;
190 Abc_ObjForEachFanin( pObj, pFanin, k )
191 Max = Abc_MaxInt( Max, Vec_IntEntry(vPhLevel, Abc_ObjId(pFanin)) + Abc_ObjFaninPhase(pObj, k) );
192 Vec_IntWriteEntry( vPhLevel, i, Max );
193 MaxAll = Abc_MaxInt( MaxAll, Max );
194 }
195 Vec_IntFree( vPhLevel );
196 return MaxAll;
197 }
Abc_SclBufferPhase(Abc_Ntk_t * pNtk,int fVerbose)198 Abc_Ntk_t * Abc_SclBufferPhase( Abc_Ntk_t * pNtk, int fVerbose )
199 {
200 Abc_Ntk_t * pNtkNew;
201 Vec_Int_t * vInvs;
202 Abc_Obj_t * pObj, * pFanin, * pFaninNew;
203 int nNodesOld = Abc_NtkObjNumMax(pNtk);
204 int i, k, Counter = 0, Counter2 = 0, Total = 0;
205 assert( pNtk->vPhases != NULL );
206 vInvs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
207 Abc_NtkForEachNodeCo( pNtk, pObj, i )
208 {
209 if ( i >= nNodesOld )
210 break;
211 Abc_ObjForEachFanin( pObj, pFanin, k )
212 {
213 Total++;
214 if ( !Abc_ObjFaninPhase(pObj, k) )
215 continue;
216 if ( Vec_IntEntry(vInvs, Abc_ObjId(pFanin)) == 0 || Abc_ObjIsCi(pFanin) ) // allow PIs to have high fanout - to be fixed later
217 {
218 pFaninNew = Abc_NtkCreateNodeInv( pNtk, pFanin );
219 Vec_IntWriteEntry( vInvs, Abc_ObjId(pFanin), Abc_ObjId(pFaninNew) );
220 Counter++;
221 }
222 pFaninNew = Abc_NtkObj( pNtk, Vec_IntEntry(vInvs, Abc_ObjId(pFanin)) );
223 Abc_ObjPatchFanin( pObj, pFanin, pFaninNew );
224 Counter2++;
225 }
226 }
227 if ( fVerbose )
228 printf( "Added %d inverters (%.2f %% fanins) (%.2f %% compl fanins).\n",
229 Counter, 100.0 * Counter / Total, 100.0 * Counter2 / Total );
230 Vec_IntFree( vInvs );
231 Vec_IntFillExtra( pNtk->vPhases, Abc_NtkObjNumMax(pNtk), 0 );
232 // duplicate network in topo order
233 vInvs = pNtk->vPhases;
234 pNtk->vPhases = NULL;
235 pNtkNew = Abc_NtkDupDfs( pNtk );
236 pNtk->vPhases = vInvs;
237 return pNtkNew;
238 }
Abc_SclUnBufferPhase(Abc_Ntk_t * pNtk,int fVerbose)239 Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose )
240 {
241 Abc_Ntk_t * pNtkNew;
242 Abc_Obj_t * pObj, * pFanin, * pFaninNew;
243 int i, k, iLit, Counter = 0, Total = 0;
244 assert( pNtk->vPhases == NULL );
245 pNtk->vPhases = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
246 Abc_NtkForEachNodeCo( pNtk, pObj, i )
247 {
248 if ( Abc_SclObjIsBufInv(pObj) )
249 continue;
250 Abc_ObjForEachFanin( pObj, pFanin, k )
251 {
252 Total++;
253 iLit = Abc_SclGetRealFaninLit( pFanin );
254 pFaninNew = Abc_NtkObj( pNtk, Abc_Lit2Var(iLit) );
255 if ( pFaninNew == pFanin )
256 continue;
257 // skip fanins which are already fanins of the node
258 if ( Abc_NodeFindFanin( pObj, pFaninNew ) >= 0 )
259 continue;
260 Abc_ObjPatchFanin( pObj, pFanin, pFaninNew );
261 if ( Abc_LitIsCompl(iLit) )
262 Abc_ObjFaninFlipPhase( pObj, k ), Counter++;
263 }
264 }
265 if ( fVerbose )
266 printf( "Saved %d (%.2f %%) fanin phase bits. ", Counter, 100.0 * Counter / Total );
267 // duplicate network in topo order
268 pNtkNew = Abc_NtkDupDfs( pNtk );
269 if ( fVerbose )
270 printf( "Max depth = %d.\n", Abc_SclCountMaxPhases(pNtkNew) );
271 Abc_SclReportDupFanins( pNtkNew );
272 return pNtkNew;
273 }
274
275 /**Function*************************************************************
276
277 Synopsis [Make sure the network is in topo order without dangling nodes.]
278
279 Description [Returns 1 iff the network is fine.]
280
281 SideEffects []
282
283 SeeAlso []
284
285 ***********************************************************************/
Abc_SclCheckNtk(Abc_Ntk_t * p,int fVerbose)286 int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )
287 {
288 Abc_Obj_t * pObj, * pFanin;
289 int i, k, fFlag = 1;
290 Abc_NtkIncrementTravId( p );
291 Abc_NtkForEachCi( p, pObj, i )
292 Abc_NodeSetTravIdCurrent( pObj );
293 Abc_NtkForEachNode( p, pObj, i )
294 {
295 Abc_ObjForEachFanin( pObj, pFanin, k )
296 if ( !Abc_NodeIsTravIdCurrent( pFanin ) )
297 printf( "obj %d and its fanin %d are not in the topo order\n", Abc_ObjId(pObj), Abc_ObjId(pFanin) ), fFlag = 0;
298 Abc_NodeSetTravIdCurrent( pObj );
299 if ( Abc_ObjIsBarBuf(pObj) )
300 continue;
301 if ( Abc_ObjFanoutNum(pObj) == 0 )
302 printf( "node %d has no fanout\n", Abc_ObjId(pObj) ), fFlag = 0;
303 if ( !fFlag )
304 break;
305 }
306 if ( fFlag && fVerbose )
307 printf( "The network is in topo order and no dangling nodes.\n" );
308 return fFlag;
309 }
310
311 /**Function*************************************************************
312
313 Synopsis [Performs buffering of the mapped network (old code).]
314
315 Description []
316
317 SideEffects []
318
319 SeeAlso []
320
321 ***********************************************************************/
Abc_NodeInvUpdateFanPolarity(Abc_Obj_t * pObj)322 void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj )
323 {
324 Abc_Obj_t * pFanout;
325 int i;
326 assert( Abc_ObjFaninNum(pObj) == 0 || Abc_SclObjIsBufInv(pObj) );
327 Abc_ObjForEachFanout( pObj, pFanout, i )
328 {
329 assert( Abc_ObjFaninNum(pFanout) > 0 );
330 if ( Abc_SclObjIsBufInv(pFanout) )
331 Abc_NodeInvUpdateFanPolarity( pFanout );
332 else
333 Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) );
334 }
335 }
Abc_NodeInvUpdateObjFanoutPolarity(Abc_Obj_t * pObj,Abc_Obj_t * pFanout)336 void Abc_NodeInvUpdateObjFanoutPolarity( Abc_Obj_t * pObj, Abc_Obj_t * pFanout )
337 {
338 if ( Abc_SclObjIsBufInv(pFanout) )
339 Abc_NodeInvUpdateFanPolarity( pFanout );
340 else
341 Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) );
342 }
Abc_NodeCompareLevels(Abc_Obj_t ** pp1,Abc_Obj_t ** pp2)343 int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
344 {
345 int Diff = Abc_ObjLevel(*pp1) - Abc_ObjLevel(*pp2);
346 if ( Diff < 0 )
347 return -1;
348 if ( Diff > 0 )
349 return 1;
350 Diff = (*pp1)->Id - (*pp2)->Id; // needed to make qsort() platform-infependent
351 if ( Diff < 0 )
352 return -1;
353 if ( Diff > 0 )
354 return 1;
355 return 0;
356 }
Abc_SclComputeReverseLevel(Abc_Obj_t * pObj)357 int Abc_SclComputeReverseLevel( Abc_Obj_t * pObj )
358 {
359 Abc_Obj_t * pFanout;
360 int i, Level = 0;
361 Abc_ObjForEachFanout( pObj, pFanout, i )
362 Level = Abc_MaxInt( Level, pFanout->Level );
363 return Level + 1;
364 }
Abc_SclPerformBufferingOne(Abc_Obj_t * pObj,int Degree,int fUseInvs,int fVerbose)365 Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose )
366 {
367 Vec_Ptr_t * vFanouts;
368 Abc_Obj_t * pBuffer, * pFanout;
369 int i, Degree0 = Degree;
370 assert( Abc_ObjFanoutNum(pObj) > Degree );
371 // collect fanouts and sort by reverse level
372 vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) );
373 Abc_NodeCollectFanouts( pObj, vFanouts );
374 Vec_PtrSort( vFanouts, (int (*)(void))Abc_NodeCompareLevels );
375 // select the first Degree fanouts
376 if ( fUseInvs )
377 pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL );
378 else
379 pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL );
380 // check if it is possible to not increase level
381 if ( Vec_PtrSize(vFanouts) < 2 * Degree )
382 {
383 Abc_Obj_t * pFanPrev = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, Vec_PtrSize(vFanouts)-1-Degree);
384 Abc_Obj_t * pFanThis = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, Degree-1);
385 Abc_Obj_t * pFanLast = (Abc_Obj_t *)Vec_PtrEntryLast(vFanouts);
386 if ( Abc_ObjLevel(pFanThis) == Abc_ObjLevel(pFanLast) &&
387 Abc_ObjLevel(pFanPrev) < Abc_ObjLevel(pFanThis) )
388 {
389 // find the first one whose level is the same as last
390 Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i )
391 if ( Abc_ObjLevel(pFanout) == Abc_ObjLevel(pFanLast) )
392 break;
393 assert( i < Vec_PtrSize(vFanouts) );
394 if ( i > 1 )
395 Degree = i;
396 }
397 // make the last two more well-balanced
398 if ( Degree == Degree0 && Degree > Vec_PtrSize(vFanouts) - Degree )
399 Degree = Vec_PtrSize(vFanouts)/2 + (Vec_PtrSize(vFanouts) & 1);
400 assert( Degree <= Degree0 );
401 }
402 // select fanouts
403 Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, i, Degree )
404 Abc_ObjPatchFanin( pFanout, pObj, pBuffer );
405 if ( fVerbose )
406 {
407 printf( "%5d : ", Abc_ObjId(pObj) );
408 Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i )
409 printf( "%d%s ", Abc_ObjLevel(pFanout), i == Degree-1 ? " " : "" );
410 printf( "\n" );
411 }
412 Vec_PtrFree( vFanouts );
413 Abc_ObjAddFanin( pBuffer, pObj );
414 pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
415 if ( fUseInvs )
416 Abc_NodeInvUpdateFanPolarity( pBuffer );
417 return pBuffer;
418 }
Abc_SclPerformBuffering_rec(Abc_Obj_t * pObj,int DegreeR,int Degree,int fUseInvs,int fVerbose)419 void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int fUseInvs, int fVerbose )
420 {
421 Vec_Ptr_t * vFanouts;
422 Abc_Obj_t * pBuffer;
423 Abc_Obj_t * pFanout;
424 int i, nOldFanNum;
425 if ( Abc_NodeIsTravIdCurrent( pObj ) )
426 return;
427 Abc_NodeSetTravIdCurrent( pObj );
428 pObj->Level = 0;
429 if ( Abc_ObjIsCo(pObj) )
430 return;
431 assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) );
432 // buffer fanouts and collect reverse levels
433 Abc_ObjForEachFanout( pObj, pFanout, i )
434 Abc_SclPerformBuffering_rec( pFanout, DegreeR, Degree, fUseInvs, fVerbose );
435 // perform buffering as long as needed
436 nOldFanNum = Abc_ObjFanoutNum(pObj);
437 while ( Abc_ObjFanoutNum(pObj) > Degree )
438 Abc_SclPerformBufferingOne( pObj, Degree, fUseInvs, fVerbose );
439 // add yet another level of buffers
440 if ( DegreeR && nOldFanNum > DegreeR )
441 {
442 if ( fUseInvs )
443 pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL );
444 else
445 pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL );
446 vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) );
447 Abc_NodeCollectFanouts( pObj, vFanouts );
448 Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i )
449 Abc_ObjPatchFanin( pFanout, pObj, pBuffer );
450 Vec_PtrFree( vFanouts );
451 Abc_ObjAddFanin( pBuffer, pObj );
452 pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
453 if ( fUseInvs )
454 Abc_NodeInvUpdateFanPolarity( pBuffer );
455 }
456 // compute the new level of the node
457 pObj->Level = Abc_SclComputeReverseLevel( pObj );
458 }
Abc_SclPerformBuffering(Abc_Ntk_t * p,int DegreeR,int Degree,int fUseInvs,int fVerbose)459 Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int DegreeR, int Degree, int fUseInvs, int fVerbose )
460 {
461 Vec_Int_t * vCiLevs;
462 Abc_Ntk_t * pNew;
463 Abc_Obj_t * pObj;
464 int i;
465 assert( Abc_NtkHasMapping(p) );
466 if ( fUseInvs )
467 {
468 printf( "Warning!!! Using inverters instead of buffers.\n" );
469 if ( p->vPhases == NULL )
470 printf( "The phases are not given. The result will not verify.\n" );
471 }
472 // remember CI levels
473 vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) );
474 Abc_NtkForEachCi( p, pObj, i )
475 Vec_IntPush( vCiLevs, Abc_ObjLevel(pObj) );
476 // perform buffering
477 Abc_NtkIncrementTravId( p );
478 Abc_NtkForEachCi( p, pObj, i )
479 Abc_SclPerformBuffering_rec( pObj, DegreeR, Degree, fUseInvs, fVerbose );
480 // recompute logic levels
481 Abc_NtkForEachCi( p, pObj, i )
482 pObj->Level = Vec_IntEntry( vCiLevs, i );
483 Abc_NtkForEachNode( p, pObj, i )
484 Abc_ObjLevelNew( pObj );
485 Vec_IntFree( vCiLevs );
486 // if phases are present
487 if ( p->vPhases )
488 Vec_IntFillExtra( p->vPhases, Abc_NtkObjNumMax(p), 0 );
489 // duplication in topo order
490 pNew = Abc_NtkDupDfs( p );
491 Abc_SclCheckNtk( pNew, fVerbose );
492 // Abc_NtkDelete( pNew );
493 return pNew;
494 }
495
496
497
498 /**Function*************************************************************
499
500 Synopsis []
501
502 Description []
503
504 SideEffects []
505
506 SeeAlso []
507
508 ***********************************************************************/
Abc_BufComputeArr(Buf_Man_t * p,Abc_Obj_t * pObj)509 float Abc_BufComputeArr( Buf_Man_t * p, Abc_Obj_t * pObj )
510 {
511 Abc_Obj_t * pFanin;
512 int i;
513 float DelayF, Delay = -ABC_INFINITY;
514 Abc_ObjForEachFanin( pObj, pFanin, i )
515 {
516 if ( Vec_IntEntry(p->vOffsets, Abc_ObjId(pObj)) == -ABC_INFINITY )
517 continue;
518 DelayF = Abc_BufNodeArr(p, pFanin) + Abc_BufEdgeDelay(p, pObj, i);
519 if ( Delay < DelayF )
520 Delay = DelayF;
521 }
522 Abc_BufSetNodeArr( p, pObj, Delay );
523 return Delay;
524 }
Abc_BufComputeDep(Buf_Man_t * p,Abc_Obj_t * pObj)525 float Abc_BufComputeDep( Buf_Man_t * p, Abc_Obj_t * pObj )
526 {
527 Abc_Obj_t * pFanout;
528 int i;
529 float DelayF, Delay = -ABC_INFINITY;
530 Abc_ObjForEachFanout( pObj, pFanout, i )
531 {
532 if ( Vec_IntEntry(p->vOffsets, Abc_ObjId(pFanout)) == -ABC_INFINITY )
533 continue;
534 DelayF = Abc_BufNodeDep(p, pFanout) + Abc_BufEdgeDelay(p, pFanout, Abc_NodeFindFanin(pFanout, pObj));
535 if ( Delay < DelayF )
536 Delay = DelayF;
537 }
538 Abc_BufSetNodeDep( p, pObj, Delay );
539 return Delay;
540 }
Abc_BufUpdateGlobal(Buf_Man_t * p)541 void Abc_BufUpdateGlobal( Buf_Man_t * p )
542 {
543 Abc_Obj_t * pObj;
544 int i;
545 p->DelayMax = 0;
546 Abc_NtkForEachCo( p->pNtk, pObj, i )
547 p->DelayMax = Abc_MaxInt( p->DelayMax, Abc_BufNodeArr(p, Abc_ObjFanin0(pObj)) );
548 }
Abc_BufCreateEdges(Buf_Man_t * p,Abc_Obj_t * pObj)549 void Abc_BufCreateEdges( Buf_Man_t * p, Abc_Obj_t * pObj )
550 {
551 int k;
552 Mio_Gate_t * pGate = Abc_ObjIsCo(pObj) ? NULL : (Mio_Gate_t *)pObj->pData;
553 Vec_IntWriteEntry( p->vOffsets, Abc_ObjId(pObj), Vec_IntSize(p->vEdges) );
554 for ( k = 0; k < Abc_ObjFaninNum(pObj); k++ )
555 Vec_IntPush( p->vEdges, pGate ? (int)(1.0 * BUF_SCALE * Mio_GateReadPinDelay(pGate, k) / p->DelayInv) : 0 );
556 }
Abc_BufAddToQue(Buf_Man_t * p,Abc_Obj_t * pObj)557 void Abc_BufAddToQue( Buf_Man_t * p, Abc_Obj_t * pObj )
558 {
559 if ( Abc_ObjFanoutNum(pObj) < p->nFanMin || (!p->fBufPis && Abc_ObjIsCi(pObj)) )
560 return;
561 Vec_FltWriteEntry( p->vCounts, Abc_ObjId(pObj), Abc_ObjFanoutNum(pObj) );
562 if ( Vec_QueIsMember(p->vQue, Abc_ObjId(pObj)) )
563 Vec_QueUpdate( p->vQue, Abc_ObjId(pObj) );
564 else
565 Vec_QuePush( p->vQue, Abc_ObjId(pObj) );
566 }
567
568
569 /**Function*************************************************************
570
571 Synopsis []
572
573 Description []
574
575 SideEffects []
576
577 SeeAlso []
578
579 ***********************************************************************/
Abc_BufCollectTfoCone_rec(Abc_Obj_t * pNode,Vec_Int_t * vNodes)580 void Abc_BufCollectTfoCone_rec( Abc_Obj_t * pNode, Vec_Int_t * vNodes )
581 {
582 Abc_Obj_t * pNext;
583 int i;
584 if ( Abc_NodeIsTravIdCurrent( pNode ) )
585 return;
586 Abc_NodeSetTravIdCurrent( pNode );
587 if ( Abc_ObjIsCo(pNode) )
588 return;
589 assert( Abc_ObjIsCi(pNode) || Abc_ObjIsNode(pNode) );
590 Abc_ObjForEachFanout( pNode, pNext, i )
591 Abc_BufCollectTfoCone_rec( pNext, vNodes );
592 if ( Abc_ObjIsNode(pNode) )
593 Vec_IntPush( vNodes, Abc_ObjId(pNode) );
594 }
Abc_BufCollectTfoCone(Buf_Man_t * p,Abc_Obj_t * pObj)595 void Abc_BufCollectTfoCone( Buf_Man_t * p, Abc_Obj_t * pObj )
596 {
597 Vec_IntClear( p->vTfCone );
598 Abc_NtkIncrementTravId( p->pNtk );
599 Abc_BufCollectTfoCone_rec( pObj, p->vTfCone );
600 }
Abc_BufUpdateArr(Buf_Man_t * p,Abc_Obj_t * pObj)601 void Abc_BufUpdateArr( Buf_Man_t * p, Abc_Obj_t * pObj )
602 {
603 Abc_Obj_t * pNext;
604 int i, Delay;
605 // assert( Abc_ObjIsNode(pObj) );
606 Abc_BufCollectTfoCone( p, pObj );
607 Vec_IntReverseOrder( p->vTfCone );
608 Abc_NtkForEachObjVec( p->vTfCone, p->pNtk, pNext, i )
609 {
610 Delay = Abc_BufComputeArr( p, pNext );
611 p->DelayMax = Abc_MaxInt( p->DelayMax, Delay );
612 }
613 }
614
615 /**Function*************************************************************
616
617 Synopsis []
618
619 Description []
620
621 SideEffects []
622
623 SeeAlso []
624
625 ***********************************************************************/
Abc_BufCollectTfiCone_rec(Abc_Obj_t * pNode,Vec_Int_t * vNodes)626 void Abc_BufCollectTfiCone_rec( Abc_Obj_t * pNode, Vec_Int_t * vNodes )
627 {
628 Abc_Obj_t * pNext;
629 int i;
630 if ( Abc_NodeIsTravIdCurrent( pNode ) )
631 return;
632 Abc_NodeSetTravIdCurrent( pNode );
633 if ( Abc_ObjIsCi(pNode) )
634 return;
635 assert( Abc_ObjIsNode(pNode) );
636 Abc_ObjForEachFanin( pNode, pNext, i )
637 Abc_BufCollectTfiCone_rec( pNext, vNodes );
638 Vec_IntPush( vNodes, Abc_ObjId(pNode) );
639 }
Abc_BufCollectTfiCone(Buf_Man_t * p,Abc_Obj_t * pObj)640 void Abc_BufCollectTfiCone( Buf_Man_t * p, Abc_Obj_t * pObj )
641 {
642 Vec_IntClear( p->vTfCone );
643 Abc_NtkIncrementTravId( p->pNtk );
644 Abc_BufCollectTfiCone_rec( pObj, p->vTfCone );
645 }
Abc_BufUpdateDep(Buf_Man_t * p,Abc_Obj_t * pObj)646 void Abc_BufUpdateDep( Buf_Man_t * p, Abc_Obj_t * pObj )
647 {
648 Abc_Obj_t * pNext;
649 int i, Delay;
650 // assert( Abc_ObjIsNode(pObj) );
651 Abc_BufCollectTfiCone( p, pObj );
652 Vec_IntReverseOrder( p->vTfCone );
653 Abc_NtkForEachObjVec( p->vTfCone, p->pNtk, pNext, i )
654 {
655 Delay = Abc_BufComputeDep( p, pNext );
656 p->DelayMax = Abc_MaxInt( p->DelayMax, Delay );
657 }
658 }
659
660 /**Function*************************************************************
661
662 Synopsis []
663
664 Description []
665
666 SideEffects []
667
668 SeeAlso []
669
670 ***********************************************************************/
Buf_ManStart(Abc_Ntk_t * pNtk,int FanMin,int FanMax,int fBufPis)671 Buf_Man_t * Buf_ManStart( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis )
672 {
673 Buf_Man_t * p;
674 Abc_Obj_t * pObj;
675 Vec_Ptr_t * vNodes;
676 int i;
677 p = ABC_CALLOC( Buf_Man_t, 1 );
678 p->pNtk = pNtk;
679 p->nFanMin = FanMin;
680 p->nFanMax = FanMax;
681 p->fBufPis = fBufPis;
682 // allocate arrays
683 p->nObjStart = Abc_NtkObjNumMax(p->pNtk);
684 p->nObjAlloc = (6 * Abc_NtkObjNumMax(p->pNtk) / 3) + 100;
685 p->vOffsets = Vec_IntAlloc( p->nObjAlloc );
686 p->vArr = Vec_IntAlloc( p->nObjAlloc );
687 p->vDep = Vec_IntAlloc( p->nObjAlloc );
688 p->vCounts = Vec_FltAlloc( p->nObjAlloc );
689 p->vQue = Vec_QueAlloc( p->nObjAlloc );
690 Vec_IntFill( p->vOffsets, p->nObjAlloc, -ABC_INFINITY );
691 Vec_IntFill( p->vArr, p->nObjAlloc, 0 );
692 Vec_IntFill( p->vDep, p->nObjAlloc, 0 );
693 Vec_FltFill( p->vCounts, p->nObjAlloc, -ABC_INFINITY );
694 Vec_QueSetPriority( p->vQue, Vec_FltArrayP(p->vCounts) );
695 // collect edge delays
696 p->DelayInv = Mio_GateReadPinDelay( Mio_LibraryReadInv((Mio_Library_t *)pNtk->pManFunc), 0 );
697 p->vEdges = Vec_IntAlloc( 1000 );
698 // create edges
699 vNodes = Abc_NtkDfs( p->pNtk, 0 );
700 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
701 Abc_BufCreateEdges( p, pObj );
702 Abc_NtkForEachCo( p->pNtk, pObj, i )
703 Abc_BufCreateEdges( p, pObj );
704 // derive delays
705 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
706 Abc_BufComputeArr( p, pObj );
707 Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pObj, i )
708 Abc_BufComputeDep( p, pObj );
709 Abc_BufUpdateGlobal( p );
710 // Abc_NtkForEachNode( p->pNtk, pObj, i )
711 // printf( "%4d : %4d %4d\n", i, Abc_BufNodeArr(p, pObj), Abc_BufNodeDep(p, pObj) );
712 // create fanout queue
713 // Abc_NtkForEachCi( p->pNtk, pObj, i )
714 // Abc_BufAddToQue( p, pObj );
715 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
716 Abc_BufAddToQue( p, pObj );
717 Vec_PtrFree( vNodes );
718 p->vDelays = Vec_IntAlloc( 100 );
719 p->vOrder = Vec_IntAlloc( 100 );
720 p->vNonCrit = Vec_IntAlloc( 100 );
721 p->vTfCone = Vec_IntAlloc( 100 );
722 p->vFanouts = Vec_PtrAlloc( 100 );
723 return p;
724 }
Buf_ManStop(Buf_Man_t * p)725 void Buf_ManStop( Buf_Man_t * p )
726 {
727 printf( "Sep = %d. Dup = %d. Br0 = %d. Br1 = %d. BrC = %d. ",
728 p->nSeparate, p->nDuplicate, p->nBranch0, p->nBranch1, p->nBranchCrit );
729 printf( "Orig = %d. Add = %d. Rem = %d.\n",
730 p->nObjStart, Abc_NtkObjNumMax(p->pNtk) - p->nObjStart,
731 p->nObjAlloc - Abc_NtkObjNumMax(p->pNtk) );
732 Vec_PtrFree( p->vFanouts );
733 Vec_IntFree( p->vTfCone );
734 Vec_IntFree( p->vNonCrit );
735 Vec_IntFree( p->vDelays );
736 Vec_IntFree( p->vOrder );
737 Vec_IntFree( p->vOffsets );
738 Vec_IntFree( p->vEdges );
739 Vec_IntFree( p->vArr );
740 Vec_IntFree( p->vDep );
741 // Vec_QueCheck( p->vQue );
742 Vec_QueFree( p->vQue );
743 Vec_FltFree( p->vCounts );
744 ABC_FREE( p );
745 }
746
747 /**Function*************************************************************
748
749 Synopsis []
750
751 Description []
752
753 SideEffects []
754
755 SeeAlso []
756
757 ***********************************************************************/
Abc_BufSortByDelay(Buf_Man_t * p,int iPivot)758 Vec_Int_t * Abc_BufSortByDelay( Buf_Man_t * p, int iPivot )
759 {
760 Abc_Obj_t * pObj, * pFanout;
761 int i, Slack, * pOrder;
762 Vec_IntClear( p->vDelays );
763 pObj = Abc_NtkObj( p->pNtk, iPivot );
764 Abc_ObjForEachFanout( pObj, pFanout, i )
765 {
766 Slack = Abc_BufEdgeSlack(p, pObj, pFanout);
767 assert( Slack >= 0 );
768 Vec_IntPush( p->vDelays, Abc_MaxInt(0, Slack) );
769 }
770 pOrder = Abc_QuickSortCost( Vec_IntArray(p->vDelays), Vec_IntSize(p->vDelays), 0 );
771 Vec_IntClear( p->vOrder );
772 for ( i = 0; i < Vec_IntSize(p->vDelays); i++ )
773 Vec_IntPush( p->vOrder, Abc_ObjId(Abc_ObjFanout(pObj, pOrder[i])) );
774 ABC_FREE( pOrder );
775 // for ( i = 0; i < Vec_IntSize(p->vDelays); i++ )
776 // printf( "%5d - %5d ", Vec_IntEntry(p->vOrder, i), Abc_BufEdgeSlack(p, pObj, Abc_NtkObj(p->pNtk, Vec_IntEntry(p->vOrder, i))) );
777 return p->vOrder;
778 }
Abc_BufPrintOne(Buf_Man_t * p,int iPivot)779 void Abc_BufPrintOne( Buf_Man_t * p, int iPivot )
780 {
781 Abc_Obj_t * pObj, * pFanout;
782 Vec_Int_t * vOrder;
783 int i, Slack;
784 pObj = Abc_NtkObj( p->pNtk, iPivot );
785 vOrder = Abc_BufSortByDelay( p, iPivot );
786 printf( "Node %5d Fi = %d Fo = %3d Lev = %3d : {", iPivot, Abc_ObjFaninNum(pObj), Abc_ObjFanoutNum(pObj), Abc_ObjLevel(pObj) );
787 Abc_NtkForEachObjVec( vOrder, p->pNtk, pFanout, i )
788 {
789 Slack = Abc_BufEdgeSlack( p, pObj, pFanout );
790 printf( " %d(%d)", Abc_ObjId(pFanout), Slack );
791 }
792 printf( " }\n" );
793 }
794
795 /**Function*************************************************************
796
797 Synopsis []
798
799 Description []
800
801 SideEffects []
802
803 SeeAlso []
804
805 ***********************************************************************/
Abc_BufReplaceBufsByInvs(Abc_Ntk_t * pNtk)806 void Abc_BufReplaceBufsByInvs( Abc_Ntk_t * pNtk )
807 {
808 Abc_Obj_t * pObj, * pInv;
809 int i, Counter = 0;
810 Abc_NtkForEachNode( pNtk, pObj, i )
811 {
812 if ( !Abc_NodeIsBuf(pObj) )
813 continue;
814 assert( pObj->pData == Mio_LibraryReadBuf((Mio_Library_t *)pNtk->pManFunc) );
815 pObj->pData = Mio_LibraryReadInv((Mio_Library_t *)pNtk->pManFunc);
816 pInv = Abc_NtkCreateNodeInv( pNtk, Abc_ObjFanin0(pObj) );
817 Abc_ObjPatchFanin( pObj, Abc_ObjFanin0(pObj), pInv );
818 Counter++;
819 }
820 printf( "Replaced %d buffers by invertor pairs.\n", Counter );
821 }
822
823 /**Function*************************************************************
824
825 Synopsis []
826
827 Description []
828
829 SideEffects []
830
831 SeeAlso []
832
833 ***********************************************************************/
Abc_BufComputeAverage(Buf_Man_t * p,int iPivot,Vec_Int_t * vOrder)834 int Abc_BufComputeAverage( Buf_Man_t * p, int iPivot, Vec_Int_t * vOrder )
835 {
836 Abc_Obj_t * pObj, * pFanout;
837 int i, Average = 0;
838 pObj = Abc_NtkObj( p->pNtk, iPivot );
839 Abc_NtkForEachObjVec( vOrder, p->pNtk, pFanout, i )
840 Average += Abc_BufEdgeSlack( p, pObj, pFanout );
841 return Average / Vec_IntSize(vOrder);
842 }
Abc_BufFindNonBuffDriver(Buf_Man_t * p,Abc_Obj_t * pObj)843 Abc_Obj_t * Abc_BufFindNonBuffDriver( Buf_Man_t * p, Abc_Obj_t * pObj )
844 {
845 return (Abc_ObjIsNode(pObj) && Abc_NodeIsBuf(pObj)) ? Abc_BufFindNonBuffDriver(p, Abc_ObjFanin0(pObj)) : pObj;
846 }
847
848 /**Function*************************************************************
849
850 Synopsis []
851
852 Description []
853
854 SideEffects []
855
856 SeeAlso []
857
858 ***********************************************************************/
Abc_BufCountNonCritical(Buf_Man_t * p,Abc_Obj_t * pObj)859 int Abc_BufCountNonCritical( Buf_Man_t * p, Abc_Obj_t * pObj )
860 {
861 Abc_Obj_t * pFanout;
862 int i;
863 Vec_IntClear( p->vNonCrit );
864 Abc_ObjForEachFanout( pObj, pFanout, i )
865 if ( Abc_BufEdgeSlack( p, pObj, pFanout ) > 7*BUF_SCALE/2 )
866 Vec_IntPush( p->vNonCrit, Abc_ObjId(pFanout) );
867 return Vec_IntSize(p->vNonCrit);
868 }
Abc_BufPerformOne(Buf_Man_t * p,int iPivot,int fSkipDup,int fVerbose)869 void Abc_BufPerformOne( Buf_Man_t * p, int iPivot, int fSkipDup, int fVerbose )
870 {
871 Abc_Obj_t * pObj, * pFanout;
872 int i, j, nCrit, nNonCrit;
873 // int DelayMax = p->DelayMax;
874 assert( Abc_NtkObjNumMax(p->pNtk) + 30 < p->nObjAlloc );
875 pObj = Abc_NtkObj( p->pNtk, iPivot );
876 // assert( Vec_FltEntry(p->vCounts, iPivot) == (float)Abc_ObjFanoutNum(pObj) );
877 nNonCrit = Abc_BufCountNonCritical( p, pObj );
878 nCrit = Abc_ObjFanoutNum(pObj) - nNonCrit;
879 if ( fVerbose )
880 {
881 //Abc_BufPrintOne( p, iPivot );
882 printf( "ObjId = %6d : %-10s FI = %d. FO =%4d. Crit =%4d. ",
883 Abc_ObjId(pObj), Mio_GateReadName((Mio_Gate_t *)pObj->pData), Abc_ObjFaninNum(pObj), Abc_ObjFanoutNum(pObj), nCrit );
884 }
885 // consider three cases
886 if ( nCrit > 0 && nNonCrit > 1 )
887 {
888 // (1) both critical and non-critical are present - split them by adding buffer
889 Abc_Obj_t * pBuffer = Abc_NtkCreateNodeBuf( p->pNtk, pObj );
890 Abc_NtkForEachObjVec( p->vNonCrit, p->pNtk, pFanout, i )
891 Abc_ObjPatchFanin( pFanout, pObj, pBuffer );
892 // update timing
893 Abc_BufCreateEdges( p, pBuffer );
894 Abc_BufUpdateArr( p, pBuffer );
895 Abc_BufUpdateDep( p, pBuffer );
896 Abc_BufAddToQue( p, pObj );
897 Abc_BufAddToQue( p, pBuffer );
898 Abc_SclTimeIncUpdateLevel( pBuffer );
899 p->nSeparate++;
900 if ( fVerbose )
901 printf( "Adding buffer\n" );
902 }
903 else if ( !fSkipDup && nCrit > 0 && Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > p->nFanMin )//&& Abc_ObjLevel(pObj) < 4 )//&& Abc_ObjFaninNum(pObj) < 2 )
904 {
905 // (2) only critical are present - duplicate
906 Abc_Obj_t * pClone = Abc_NtkDupObj( p->pNtk, pObj, 0 );
907 Abc_ObjForEachFanin( pObj, pFanout, i )
908 Abc_ObjAddFanin( pClone, pFanout );
909 Abc_NodeCollectFanouts( pObj, p->vFanouts );
910 Vec_PtrForEachEntryStop( Abc_Obj_t *, p->vFanouts, pFanout, i, Vec_PtrSize(p->vFanouts)/2 )
911 Abc_ObjPatchFanin( pFanout, pObj, pClone );
912 // update timing
913 Abc_BufCreateEdges( p, pClone );
914 Abc_BufSetNodeArr( p, pClone, Abc_BufNodeArr(p, pObj) );
915 Abc_BufUpdateDep( p, pObj );
916 Abc_BufUpdateDep( p, pClone );
917 Abc_BufAddToQue( p, pObj );
918 Abc_BufAddToQue( p, pClone );
919 Abc_ObjForEachFanin( pObj, pFanout, i )
920 Abc_BufAddToQue( p, pFanout );
921 Abc_SclTimeIncUpdateLevel( pClone );
922 p->nDuplicate++;
923 // printf( "Duplicating %s on level %d\n", Mio_GateReadName((Mio_Gate_t *)pObj->pData), Abc_ObjLevel(pObj) );
924 if ( fVerbose )
925 printf( "Duplicating node\n" );
926 }
927 else if ( (nCrit > 0 && Abc_ObjFanoutNum(pObj) > 8) || Abc_ObjFanoutNum(pObj) > p->nFanMax )
928 {
929 // (2) only critical or only non-critical - add buffer/inverter tree
930 int nDegree, n1Degree, n1Number, nFirst;
931 int iFirstBuf = Abc_NtkObjNumMax( p->pNtk );
932 // nDegree = Abc_MinInt( 3, (int)pow(Abc_ObjFanoutNum(pObj), 0.34) );
933 nDegree = Abc_MinInt( 10, (int)pow(Abc_ObjFanoutNum(pObj), 0.5) );
934 n1Degree = Abc_ObjFanoutNum(pObj) / nDegree + 1;
935 n1Number = Abc_ObjFanoutNum(pObj) % nDegree;
936 nFirst = n1Degree * n1Number;
937 p->nBranchCrit += (nCrit > 0);
938 // create inverters
939 Abc_NodeCollectFanouts( pObj, p->vFanouts );
940 if ( Abc_ObjIsNode(pObj) && Abc_NodeIsBuf(pObj) )
941 {
942 p->nBranch0++;
943 pObj->pData = Mio_LibraryReadInv((Mio_Library_t *)p->pNtk->pManFunc);
944 Abc_BufSetEdgeDelay( p, pObj, 0, BUF_SCALE );
945 assert( Abc_NodeIsInv(pObj) );
946 for ( i = 0; i < nDegree; i++ )
947 Abc_NtkCreateNodeInv( p->pNtk, pObj );
948 if ( fVerbose )
949 printf( "Adding %d inverters\n", nDegree );
950 }
951 else
952 {
953 p->nBranch1++;
954 for ( i = 0; i < nDegree; i++ )
955 Abc_NtkCreateNodeBuf( p->pNtk, pObj );
956 if ( fVerbose )
957 printf( "Adding %d buffers\n", nDegree );
958 }
959 // connect inverters
960 Vec_PtrForEachEntry( Abc_Obj_t *, p->vFanouts, pFanout, i )
961 {
962 j = (i < nFirst) ? i/n1Degree : n1Number + ((i - nFirst)/(n1Degree - 1));
963 assert( j >= 0 && j < nDegree );
964 Abc_ObjPatchFanin( pFanout, pObj, Abc_NtkObj(p->pNtk, iFirstBuf + j) );
965 }
966 // update timing
967 for ( i = 0; i < nDegree; i++ )
968 Abc_BufCreateEdges( p, Abc_NtkObj(p->pNtk, iFirstBuf + i) );
969 Abc_BufUpdateArr( p, pObj );
970 for ( i = 0; i < nDegree; i++ )
971 Abc_BufComputeDep( p, Abc_NtkObj(p->pNtk, iFirstBuf + i) );
972 Abc_BufUpdateDep( p, pObj );
973 for ( i = 0; i < nDegree; i++ )
974 Abc_BufAddToQue( p, Abc_NtkObj(p->pNtk, iFirstBuf + i) );
975 for ( i = 0; i < nDegree; i++ )
976 Abc_SclTimeIncUpdateLevel( Abc_NtkObj(p->pNtk, iFirstBuf + i) );
977 }
978 else
979 {
980 if ( fVerbose )
981 printf( "Doing nothing\n" );
982 }
983 // if ( DelayMax != p->DelayMax )
984 // printf( "%d (%.2f) ", p->DelayMax, 1.0 * p->DelayMax * p->DelayInv / BUF_SCALE );
985 }
Abc_SclBufPerform(Abc_Ntk_t * pNtk,int FanMin,int FanMax,int fBufPis,int fSkipDup,int fVerbose)986 Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis, int fSkipDup, int fVerbose )
987 {
988 Abc_Ntk_t * pNew;
989 Buf_Man_t * p = Buf_ManStart( pNtk, FanMin, FanMax, fBufPis );
990 int i, Limit = ABC_INFINITY;
991 Abc_NtkLevel( pNtk );
992 // if ( Abc_NtkNodeNum(pNtk) < 1000 )
993 // fSkipDup = 1;
994 for ( i = 0; i < Limit && Vec_QueSize(p->vQue); i++ )
995 Abc_BufPerformOne( p, Vec_QuePop(p->vQue), fSkipDup, fVerbose );
996 Buf_ManStop( p );
997 // Abc_BufReplaceBufsByInvs( pNtk );
998 // duplicate network in topo order
999 pNew = Abc_NtkDupDfs( pNtk );
1000 Abc_SclCheckNtk( pNew, fVerbose );
1001 return pNew;
1002 }
1003
1004 ////////////////////////////////////////////////////////////////////////
1005 /// END OF FILE ///
1006 ////////////////////////////////////////////////////////////////////////
1007
1008
1009 ABC_NAMESPACE_IMPL_END
1010
1011