1 /**CFile****************************************************************
2
3 FileName [abcMap.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Network and node package.]
8
9 Synopsis [Interface with the SC mapping package.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - June 20, 2005.]
16
17 Revision [$Id: abcMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "base/abc/abc.h"
22 #include "base/main/main.h"
23 #include "map/mio/mio.h"
24 #include "map/mapper/mapper.h"
25 #include "misc/util/utilNam.h"
26 #include "map/scl/sclCon.h"
27
28 ABC_NAMESPACE_IMPL_START
29
30
31 ////////////////////////////////////////////////////////////////////////
32 /// DECLARATIONS ///
33 ////////////////////////////////////////////////////////////////////////
34
35 static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose );
36 static Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk, int fUseBuffs );
37 static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
38 static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
39
40 static Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
41 static void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
42 static void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase );
43 static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
44
45
46 ////////////////////////////////////////////////////////////////////////
47 /// FUNCTION DEFINITIONS ///
48 ////////////////////////////////////////////////////////////////////////
49
50 /**Function*************************************************************
51
52 Synopsis [Interface with the mapping package.]
53
54 Description []
55
56 SideEffects []
57
58 SeeAlso []
59
60 ***********************************************************************/
Abc_NtkMap(Abc_Ntk_t * pNtk,double DelayTarget,double AreaMulti,double DelayMulti,float LogFan,float Slew,float Gain,int nGatesMin,int fRecovery,int fSwitching,int fSkipFanout,int fUseProfile,int fUseBuffs,int fVerbose)61 Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, double AreaMulti, double DelayMulti, float LogFan, float Slew, float Gain, int nGatesMin, int fRecovery, int fSwitching, int fSkipFanout, int fUseProfile, int fUseBuffs, int fVerbose )
62 {
63 static int fUseMulti = 0;
64 int fShowSwitching = 1;
65 Abc_Ntk_t * pNtkNew;
66 Map_Man_t * pMan;
67 Vec_Int_t * vSwitching = NULL;
68 float * pSwitching = NULL;
69 abctime clk, clkTotal = Abc_Clock();
70 Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
71
72 assert( Abc_NtkIsStrash(pNtk) );
73 // derive library from SCL
74 // if the library is created here, it will be deleted when pSuperLib is deleted in Map_SuperLibFree()
75 if ( Abc_FrameReadLibScl() && Abc_SclHasDelayInfo( Abc_FrameReadLibScl() ) )
76 {
77 if ( pLib && Mio_LibraryHasProfile(pLib) )
78 pLib = Abc_SclDeriveGenlib( Abc_FrameReadLibScl(), pLib, Slew, Gain, nGatesMin, fVerbose );
79 else
80 pLib = Abc_SclDeriveGenlib( Abc_FrameReadLibScl(), NULL, Slew, Gain, nGatesMin, fVerbose );
81 if ( Abc_FrameReadLibGen() )
82 {
83 Mio_LibraryTransferDelays( (Mio_Library_t *)Abc_FrameReadLibGen(), pLib );
84 Mio_LibraryTransferProfile( pLib, (Mio_Library_t *)Abc_FrameReadLibGen() );
85 }
86 // remove supergate library
87 Map_SuperLibFree( (Map_SuperLib_t *)Abc_FrameReadLibSuper() );
88 Abc_FrameSetLibSuper( NULL );
89 }
90 // quit if there is no library
91 if ( pLib == NULL )
92 {
93 printf( "The current library is not available.\n" );
94 return 0;
95 }
96 if ( AreaMulti != 0.0 )
97 fUseMulti = 1, printf( "The cell areas are multiplied by the factor: <num_fanins> ^ (%.2f).\n", AreaMulti );
98 if ( DelayMulti != 0.0 )
99 fUseMulti = 1, printf( "The cell delays are multiplied by the factor: <num_fanins> ^ (%.2f).\n", DelayMulti );
100
101 // penalize large gates by increasing their area
102 if ( AreaMulti != 0.0 )
103 Mio_LibraryMultiArea( pLib, AreaMulti );
104 if ( DelayMulti != 0.0 )
105 Mio_LibraryMultiDelay( pLib, DelayMulti );
106
107 // derive the supergate library
108 if ( fUseMulti || Abc_FrameReadLibSuper() == NULL )
109 {
110 if ( fVerbose )
111 printf( "Converting \"%s\" into supergate library \"%s\".\n",
112 Mio_LibraryReadName(pLib), Extra_FileNameGenericAppend(Mio_LibraryReadName(pLib), ".super") );
113 // compute supergate library to be used for mapping
114 if ( Mio_LibraryHasProfile(pLib) )
115 printf( "Abc_NtkMap(): Genlib library has profile.\n" );
116 Map_SuperLibDeriveFromGenlib( pLib, fVerbose );
117 }
118
119 // return the library to normal
120 if ( AreaMulti != 0.0 )
121 Mio_LibraryMultiArea( (Mio_Library_t *)Abc_FrameReadLibGen(), -AreaMulti );
122 if ( DelayMulti != 0.0 )
123 Mio_LibraryMultiDelay( (Mio_Library_t *)Abc_FrameReadLibGen(), -DelayMulti );
124
125 // print a warning about choice nodes
126 if ( fVerbose && Abc_NtkGetChoiceNum( pNtk ) )
127 printf( "Performing mapping with choices.\n" );
128
129 // compute switching activity
130 fShowSwitching |= fSwitching;
131 if ( fShowSwitching )
132 {
133 extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns );
134 vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 );
135 pSwitching = (float *)vSwitching->pArray;
136 }
137
138 // perform the mapping
139 pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, pSwitching, fVerbose );
140 if ( pSwitching ) Vec_IntFree( vSwitching );
141 if ( pMan == NULL )
142 return NULL;
143 clk = Abc_Clock();
144 Map_ManSetSwitching( pMan, fSwitching );
145 Map_ManSetSkipFanout( pMan, fSkipFanout );
146 if ( fUseProfile )
147 Map_ManSetUseProfile( pMan );
148 if ( LogFan != 0 )
149 Map_ManCreateNodeDelays( pMan, LogFan );
150 if ( !Map_Mapping( pMan ) )
151 {
152 Map_ManFree( pMan );
153 return NULL;
154 }
155 // Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), Abc_Clock()-clk );
156
157 // reconstruct the network after mapping (use buffers when user requested or in the area mode)
158 pNtkNew = Abc_NtkFromMap( pMan, pNtk, fUseBuffs || (DelayTarget == (double)ABC_INFINITY) );
159 if ( Mio_LibraryHasProfile(pLib) )
160 Mio_LibraryTransferProfile2( (Mio_Library_t *)Abc_FrameReadLibGen(), pLib );
161 Map_ManFree( pMan );
162 if ( pNtkNew == NULL )
163 return NULL;
164
165 if ( pNtk->pExdc )
166 pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
167 if ( fVerbose )
168 {
169 ABC_PRT( "Total runtime", Abc_Clock() - clkTotal );
170 }
171
172 // make sure that everything is okay
173 if ( !Abc_NtkCheck( pNtkNew ) )
174 {
175 printf( "Abc_NtkMap: The network check has failed.\n" );
176 Abc_NtkDelete( pNtkNew );
177 return NULL;
178 }
179 return pNtkNew;
180 }
181
182 /**Function*************************************************************
183
184 Synopsis [Load the network into manager.]
185
186 Description []
187
188 SideEffects []
189
190 SeeAlso []
191
192 ***********************************************************************/
Abc_NtkMapCopyCiArrival(Abc_Ntk_t * pNtk,Abc_Time_t * ppTimes)193 Map_Time_t * Abc_NtkMapCopyCiArrival( Abc_Ntk_t * pNtk, Abc_Time_t * ppTimes )
194 {
195 Map_Time_t * p;
196 int i;
197 p = ABC_CALLOC( Map_Time_t, Abc_NtkCiNum(pNtk) );
198 for ( i = 0; i < Abc_NtkCiNum(pNtk); i++ )
199 {
200 p[i].Fall = ppTimes[i].Fall;
201 p[i].Rise = ppTimes[i].Rise;
202 p[i].Worst = Abc_MaxFloat( p[i].Fall, p[i].Rise );
203 }
204 ABC_FREE( ppTimes );
205 return p;
206 }
Abc_NtkMapCopyCoRequired(Abc_Ntk_t * pNtk,Abc_Time_t * ppTimes)207 Map_Time_t * Abc_NtkMapCopyCoRequired( Abc_Ntk_t * pNtk, Abc_Time_t * ppTimes )
208 {
209 Map_Time_t * p;
210 int i;
211 p = ABC_CALLOC( Map_Time_t, Abc_NtkCoNum(pNtk) );
212 for ( i = 0; i < Abc_NtkCoNum(pNtk); i++ )
213 {
214 p[i].Fall = ppTimes[i].Fall;
215 p[i].Rise = ppTimes[i].Rise;
216 p[i].Worst = Abc_MaxFloat( p[i].Fall, p[i].Rise );
217 }
218 ABC_FREE( ppTimes );
219 return p;
220 }
221
222 /**Function*************************************************************
223
224 Synopsis [Load the network into manager.]
225
226 Description []
227
228 SideEffects []
229
230 SeeAlso []
231
232 ***********************************************************************/
Abc_NtkMapCopyCiArrivalCon(Abc_Ntk_t * pNtk)233 Map_Time_t * Abc_NtkMapCopyCiArrivalCon( Abc_Ntk_t * pNtk )
234 {
235 Map_Time_t * p; int i;
236 p = ABC_CALLOC( Map_Time_t, Abc_NtkCiNum(pNtk) );
237 for ( i = 0; i < Abc_NtkCiNum(pNtk); i++ )
238 p[i].Fall = p[i].Rise = p[i].Worst = Scl_Int2Flt( Scl_ConGetInArr(i) );
239 return p;
240 }
Abc_NtkMapCopyCoRequiredCon(Abc_Ntk_t * pNtk)241 Map_Time_t * Abc_NtkMapCopyCoRequiredCon( Abc_Ntk_t * pNtk )
242 {
243 Map_Time_t * p; int i;
244 p = ABC_CALLOC( Map_Time_t, Abc_NtkCoNum(pNtk) );
245 for ( i = 0; i < Abc_NtkCoNum(pNtk); i++ )
246 p[i].Fall = p[i].Rise = p[i].Worst = Scl_Int2Flt( Scl_ConGetOutReq(i) );
247 return p;
248 }
249
250 /**Function*************************************************************
251
252 Synopsis [Load the network into manager.]
253
254 Description []
255
256 SideEffects []
257
258 SeeAlso []
259
260 ***********************************************************************/
Abc_NtkToMap(Abc_Ntk_t * pNtk,double DelayTarget,int fRecovery,float * pSwitching,int fVerbose)261 Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose )
262 {
263 Map_Man_t * pMan;
264 Map_Node_t * pNodeMap;
265 Vec_Ptr_t * vNodes;
266 Abc_Obj_t * pNode, * pFanin, * pPrev;
267 int i;
268
269 assert( Abc_NtkIsStrash(pNtk) );
270
271 // start the mapping manager and set its parameters
272 pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, fVerbose );
273 if ( pMan == NULL )
274 return NULL;
275 Map_ManSetAreaRecovery( pMan, fRecovery );
276 Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
277 Map_ManSetDelayTarget( pMan, (float)DelayTarget );
278
279 // set arrival and requireds
280 if ( Scl_ConIsRunning() && Scl_ConHasInArrs() )
281 Map_ManSetInputArrivals( pMan, Abc_NtkMapCopyCiArrivalCon(pNtk) );
282 else
283 Map_ManSetInputArrivals( pMan, Abc_NtkMapCopyCiArrival(pNtk, Abc_NtkGetCiArrivalTimes(pNtk)) );
284 if ( Scl_ConIsRunning() && Scl_ConHasOutReqs() )
285 Map_ManSetOutputRequireds( pMan, Abc_NtkMapCopyCoRequiredCon(pNtk) );
286 else
287 Map_ManSetOutputRequireds( pMan, Abc_NtkMapCopyCoRequired(pNtk, Abc_NtkGetCoRequiredTimes(pNtk)) );
288
289 // create PIs and remember them in the old nodes
290 Abc_NtkCleanCopy( pNtk );
291 Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
292 Abc_NtkForEachCi( pNtk, pNode, i )
293 {
294 if ( i == Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
295 break;
296 pNodeMap = Map_ManReadInputs(pMan)[i];
297 pNode->pCopy = (Abc_Obj_t *)pNodeMap;
298 if ( pSwitching )
299 Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
300 }
301
302 // load the AIG into the mapper
303 vNodes = Abc_AigDfsMap( pNtk );
304 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
305 {
306 if ( Abc_ObjIsLatch(pNode) )
307 {
308 pFanin = Abc_ObjFanin0(pNode);
309 pNodeMap = Map_NodeBuf( pMan, Map_NotCond( Abc_ObjFanin0(pFanin)->pCopy, (int)Abc_ObjFaninC0(pFanin) ) );
310 Abc_ObjFanout0(pNode)->pCopy = (Abc_Obj_t *)pNodeMap;
311 continue;
312 }
313 assert( Abc_ObjIsNode(pNode) );
314 // add the node to the mapper
315 pNodeMap = Map_NodeAnd( pMan,
316 Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) ),
317 Map_NotCond( Abc_ObjFanin1(pNode)->pCopy, (int)Abc_ObjFaninC1(pNode) ) );
318 assert( pNode->pCopy == NULL );
319 // remember the node
320 pNode->pCopy = (Abc_Obj_t *)pNodeMap;
321 if ( pSwitching )
322 Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
323 // set up the choice node
324 if ( Abc_AigNodeIsChoice( pNode ) )
325 for ( pPrev = pNode, pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pPrev = pFanin, pFanin = (Abc_Obj_t *)pFanin->pData )
326 {
327 Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy );
328 Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy );
329 }
330 }
331 assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
332 Vec_PtrFree( vNodes );
333
334 // set the primary outputs in the required phase
335 Abc_NtkForEachCo( pNtk, pNode, i )
336 {
337 if ( i == Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
338 break;
339 Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) );
340 }
341 return pMan;
342 }
343
344 /**Function*************************************************************
345
346 Synopsis [Creates the mapped network.]
347
348 Description []
349
350 SideEffects []
351
352 SeeAlso []
353
354 ***********************************************************************/
Abc_NodeFromMapSuper_rec(Abc_Ntk_t * pNtkNew,Map_Node_t * pNodeMap,Map_Super_t * pSuper,Abc_Obj_t * pNodePis[],int nNodePis)355 Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
356 {
357 Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
358 Mio_Gate_t * pRoot;
359 Map_Super_t ** ppFanins;
360 Abc_Obj_t * pNodeNew, * pNodeFanin;
361 int nFanins, Number, i;
362
363 // get the parameters of the supergate
364 pRoot = Map_SuperReadRoot(pSuper);
365 if ( pRoot == NULL )
366 {
367 Number = Map_SuperReadNum(pSuper);
368 if ( Number < nNodePis )
369 {
370 return pNodePis[Number];
371 }
372 else
373 {
374 // assert( 0 );
375 /* It might happen that a super gate with 5 inputs is constructed that
376 * actually depends only on the first four variables; i.e the fifth is a
377 * don't care -- in that case we connect constant node for the fifth
378 * (since the cut only has 4 variables). An interesting question is what
379 * if the first variable (and not the fifth one is the redundant one;
380 * can that happen?) */
381 return Abc_NtkCreateNodeConst0(pNtkNew);
382 }
383 }
384 pRoot = Mio_LibraryReadGateByName( pLib, Mio_GateReadName(pRoot), NULL );
385
386 // get information about the fanins of the supergate
387 nFanins = Map_SuperReadFaninNum( pSuper );
388 ppFanins = Map_SuperReadFanins( pSuper );
389 // create a new node with these fanins
390 pNodeNew = Abc_NtkCreateNode( pNtkNew );
391 for ( i = 0; i < nFanins; i++ )
392 {
393 pNodeFanin = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis );
394 Abc_ObjAddFanin( pNodeNew, pNodeFanin );
395 }
396 pNodeNew->pData = pRoot;
397 return pNodeNew;
398 }
Abc_NodeFromMapPhase_rec(Abc_Ntk_t * pNtkNew,Map_Node_t * pNodeMap,int fPhase)399 Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
400 {
401 Abc_Obj_t * pNodePIs[10];
402 Abc_Obj_t * pNodeNew;
403 Map_Node_t ** ppLeaves;
404 Map_Cut_t * pCutBest;
405 Map_Super_t * pSuperBest;
406 unsigned uPhaseBest;
407 int i, fInvPin, nLeaves;
408
409 // make sure the node can be implemented in this phase
410 assert( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
411 // check if the phase is already implemented
412 pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
413 if ( pNodeNew )
414 return pNodeNew;
415
416 // get the information about the best cut
417 pCutBest = Map_NodeReadCutBest( pNodeMap, fPhase );
418 pSuperBest = Map_CutReadSuperBest( pCutBest, fPhase );
419 uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase );
420 nLeaves = Map_CutReadLeavesNum( pCutBest );
421 ppLeaves = Map_CutReadLeaves( pCutBest );
422
423 // collect the PI nodes
424 for ( i = 0; i < nLeaves; i++ )
425 {
426 fInvPin = ((uPhaseBest & (1 << i)) > 0);
427 pNodePIs[i] = Abc_NodeFromMap_rec( pNtkNew, ppLeaves[i], !fInvPin );
428 assert( pNodePIs[i] != NULL );
429 }
430
431 // implement the supergate
432 pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves );
433 Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew );
434 return pNodeNew;
435 }
Abc_NodeFromMap_rec(Abc_Ntk_t * pNtkNew,Map_Node_t * pNodeMap,int fPhase)436 Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
437 {
438 Abc_Obj_t * pNodeNew, * pNodeInv;
439
440 // check the case of constant node
441 if ( Map_NodeIsConst(pNodeMap) )
442 {
443 pNodeNew = fPhase? Abc_NtkCreateNodeConst1(pNtkNew) : Abc_NtkCreateNodeConst0(pNtkNew);
444 if ( pNodeNew->pData == NULL )
445 printf( "Error creating mapped network: Library does not have a constant %d gate.\n", fPhase );
446 return pNodeNew;
447 }
448
449 // check if the phase is already implemented
450 pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
451 if ( pNodeNew )
452 return pNodeNew;
453
454 // implement the node if the best cut is assigned
455 if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL )
456 return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase );
457
458 // if the cut is not assigned, implement the node
459 assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
460 pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase );
461
462 // add the inverter
463 pNodeInv = Abc_NtkCreateNode( pNtkNew );
464 Abc_ObjAddFanin( pNodeInv, pNodeNew );
465 pNodeInv->pData = Mio_LibraryReadInv((Mio_Library_t *)Abc_FrameReadLibGen());
466
467 // set the inverter
468 Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv );
469 return pNodeInv;
470 }
Abc_NtkFromMap(Map_Man_t * pMan,Abc_Ntk_t * pNtk,int fUseBuffs)471 Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk, int fUseBuffs )
472 {
473 Abc_Ntk_t * pNtkNew;
474 Map_Node_t * pNodeMap;
475 Abc_Obj_t * pNode, * pNodeNew;
476 int i, nDupGates;
477 assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
478 // create the new network
479 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_MAP );
480 // make the mapper point to the new network
481 Map_ManCleanData( pMan );
482 Abc_NtkForEachCi( pNtk, pNode, i )
483 {
484 if ( i >= Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
485 break;
486 Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
487 }
488 Abc_NtkForEachCi( pNtk, pNode, i )
489 {
490 if ( i < Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
491 continue;
492 Map_NodeSetData( Map_ManReadBufs(pMan)[i - (Abc_NtkCiNum(pNtk) - pNtk->nBarBufs)], 1, (char *)pNode->pCopy );
493 }
494 // assign the mapping of the required phase to the POs
495 Abc_NtkForEachCo( pNtk, pNode, i )
496 {
497 if ( i < Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
498 continue;
499 pNodeMap = Map_ManReadBufDriver( pMan, i - (Abc_NtkCoNum(pNtk) - pNtk->nBarBufs) );
500 pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
501 assert( !Abc_ObjIsComplement(pNodeNew) );
502 Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
503 }
504 Abc_NtkForEachCo( pNtk, pNode, i )
505 {
506 if ( i >= Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
507 break;
508 pNodeMap = Map_ManReadOutputs(pMan)[i];
509 pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
510 assert( !Abc_ObjIsComplement(pNodeNew) );
511 Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
512 }
513 // decouple the PO driver nodes to reduce the number of levels
514 nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, !fUseBuffs );
515 // if ( nDupGates && Map_ManReadVerbose(pMan) )
516 // printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
517 return pNtkNew;
518 }
519
520 /**Function*************************************************************
521
522 Synopsis [Interface with the mapping package.]
523
524 Description []
525
526 SideEffects []
527
528 SeeAlso []
529
530 ***********************************************************************/
Abc_NtkSuperChoice(Abc_Ntk_t * pNtk)531 Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
532 {
533 Abc_Ntk_t * pNtkNew;
534
535 Map_Man_t * pMan;
536
537 assert( Abc_NtkIsStrash(pNtk) );
538
539 // check that the library is available
540 if ( Abc_FrameReadLibGen() == NULL )
541 {
542 printf( "The current library is not available.\n" );
543 return 0;
544 }
545
546 // derive the supergate library
547 if ( Abc_FrameReadLibSuper() == NULL && Abc_FrameReadLibGen() )
548 {
549 // printf( "A simple supergate library is derived from gate library \"%s\".\n",
550 // Mio_LibraryReadName((Mio_Library_t *)Abc_FrameReadLibGen()) );
551 Map_SuperLibDeriveFromGenlib( (Mio_Library_t *)Abc_FrameReadLibGen(), 0 );
552 }
553
554 // print a warning about choice nodes
555 if ( Abc_NtkGetChoiceNum( pNtk ) )
556 printf( "Performing mapping with choices.\n" );
557
558 // perform the mapping
559 pMan = Abc_NtkToMap( pNtk, -1, 1, NULL, 0 );
560 if ( pMan == NULL )
561 return NULL;
562 if ( !Map_Mapping( pMan ) )
563 {
564 Map_ManFree( pMan );
565 return NULL;
566 }
567
568 // reconstruct the network after mapping
569 pNtkNew = Abc_NtkFromMapSuperChoice( pMan, pNtk );
570 if ( pNtkNew == NULL )
571 return NULL;
572 Map_ManFree( pMan );
573
574 // make sure that everything is okay
575 if ( !Abc_NtkCheck( pNtkNew ) )
576 {
577 printf( "Abc_NtkMap: The network check has failed.\n" );
578 Abc_NtkDelete( pNtkNew );
579 return NULL;
580 }
581 return pNtkNew;
582 }
583
584
585 /**Function*************************************************************
586
587 Synopsis [Creates the mapped network.]
588
589 Description []
590
591 SideEffects []
592
593 SeeAlso []
594
595 ***********************************************************************/
Abc_NtkFromMapSuperChoice(Map_Man_t * pMan,Abc_Ntk_t * pNtk)596 Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
597 {
598 extern Abc_Ntk_t * Abc_NtkMulti( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor );
599 ProgressBar * pProgress;
600 Abc_Ntk_t * pNtkNew, * pNtkNew2;
601 Abc_Obj_t * pNode;
602 int i;
603
604 // save the pointer to the mapped nodes
605 Abc_NtkForEachCi( pNtk, pNode, i )
606 pNode->pNext = pNode->pCopy;
607 Abc_NtkForEachPo( pNtk, pNode, i )
608 pNode->pNext = pNode->pCopy;
609 Abc_NtkForEachNode( pNtk, pNode, i )
610 pNode->pNext = pNode->pCopy;
611
612 // duplicate the network
613 pNtkNew2 = Abc_NtkDup( pNtk );
614 pNtkNew = Abc_NtkMulti( pNtkNew2, 0, 20, 0, 0, 1, 0 );
615 if ( !Abc_NtkBddToSop( pNtkNew, -1, ABC_INFINITY ) )
616 {
617 printf( "Abc_NtkFromMapSuperChoice(): Converting to SOPs has failed.\n" );
618 return NULL;
619 }
620
621 // set the old network to point to the new network
622 Abc_NtkForEachCi( pNtk, pNode, i )
623 pNode->pCopy = pNode->pCopy->pCopy;
624 Abc_NtkForEachPo( pNtk, pNode, i )
625 pNode->pCopy = pNode->pCopy->pCopy;
626 Abc_NtkForEachNode( pNtk, pNode, i )
627 pNode->pCopy = pNode->pCopy->pCopy;
628 Abc_NtkDelete( pNtkNew2 );
629
630 // set the pointers from the mapper to the new nodes
631 Abc_NtkForEachCi( pNtk, pNode, i )
632 {
633 Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NtkCreateNodeInv(pNtkNew,pNode->pCopy) );
634 Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
635 }
636 Abc_NtkForEachNode( pNtk, pNode, i )
637 {
638 // if ( Abc_NodeIsConst(pNode) )
639 // continue;
640 Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NtkCreateNodeInv(pNtkNew,pNode->pCopy) );
641 Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy );
642 }
643
644 // assign the mapping of the required phase to the POs
645 pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
646 Abc_NtkForEachNode( pNtk, pNode, i )
647 {
648 Extra_ProgressBarUpdate( pProgress, i, NULL );
649 // if ( Abc_NodeIsConst(pNode) )
650 // continue;
651 Abc_NodeSuperChoice( pNtkNew, pNode );
652 }
653 Extra_ProgressBarStop( pProgress );
654 return pNtkNew;
655 }
656
657
658 /**Function*************************************************************
659
660 Synopsis [Creates the mapped network.]
661
662 Description []
663
664 SideEffects []
665
666 SeeAlso []
667
668 ***********************************************************************/
Abc_NodeSuperChoice(Abc_Ntk_t * pNtkNew,Abc_Obj_t * pNode)669 void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
670 {
671 Map_Node_t * pMapNode = (Map_Node_t *)pNode->pNext;
672 Map_Cut_t * pCuts, * pTemp;
673
674 pCuts = Map_NodeReadCuts(pMapNode);
675 for ( pTemp = Map_CutReadNext(pCuts); pTemp; pTemp = Map_CutReadNext(pTemp) )
676 {
677 Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 0 );
678 Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 1 );
679 }
680 }
681
682
683 /**Function*************************************************************
684
685 Synopsis [Constructs the nodes corrresponding to one node.]
686
687 Description []
688
689 SideEffects []
690
691 SeeAlso []
692
693 ***********************************************************************/
Abc_NodeFromMapCutPhase(Abc_Ntk_t * pNtkNew,Map_Cut_t * pCut,int fPhase)694 void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase )
695 {
696 Abc_Obj_t * pNodePIs[10];
697 Map_Node_t ** ppLeaves;
698 Map_Super_t * pSuperBest;
699 unsigned uPhaseBest;
700 int i, fInvPin, nLeaves;
701
702 pSuperBest = Map_CutReadSuperBest( pCut, fPhase );
703 if ( pSuperBest == NULL )
704 return;
705
706 // get the information about the best cut
707 uPhaseBest = Map_CutReadPhaseBest( pCut, fPhase );
708 nLeaves = Map_CutReadLeavesNum( pCut );
709 ppLeaves = Map_CutReadLeaves( pCut );
710
711 // collect the PI nodes
712 for ( i = 0; i < nLeaves; i++ )
713 {
714 fInvPin = ((uPhaseBest & (1 << i)) > 0);
715 pNodePIs[i] = (Abc_Obj_t *)Map_NodeReadData( ppLeaves[i], !fInvPin );
716 assert( pNodePIs[i] != NULL );
717 }
718
719 // implement the supergate
720 Abc_NodeFromMapSuperChoice_rec( pNtkNew, pSuperBest, pNodePIs, nLeaves );
721 }
722
723
724 /**Function*************************************************************
725
726 Synopsis [Constructs the nodes corrresponding to one supergate.]
727
728 Description []
729
730 SideEffects []
731
732 SeeAlso []
733
734 ***********************************************************************/
Abc_NodeFromMapSuperChoice_rec(Abc_Ntk_t * pNtkNew,Map_Super_t * pSuper,Abc_Obj_t * pNodePis[],int nNodePis)735 Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
736 {
737 Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
738 Mio_Gate_t * pRoot;
739 Map_Super_t ** ppFanins;
740 Abc_Obj_t * pNodeNew, * pNodeFanin;
741 int nFanins, Number, i;
742
743 // get the parameters of the supergate
744 pRoot = Map_SuperReadRoot(pSuper);
745 if ( pRoot == NULL )
746 {
747 Number = Map_SuperReadNum(pSuper);
748 if ( Number < nNodePis )
749 {
750 return pNodePis[Number];
751 }
752 else
753 {
754 // assert( 0 );
755 /* It might happen that a super gate with 5 inputs is constructed that
756 * actually depends only on the first four variables; i.e the fifth is a
757 * don't care -- in that case we connect constant node for the fifth
758 * (since the cut only has 4 variables). An interesting question is what
759 * if the first variable (and not the fifth one is the redundant one;
760 * can that happen?) */
761 return Abc_NtkCreateNodeConst0(pNtkNew);
762 }
763 }
764 pRoot = Mio_LibraryReadGateByName( pLib, Mio_GateReadName(pRoot), NULL );
765
766 // get information about the fanins of the supergate
767 nFanins = Map_SuperReadFaninNum( pSuper );
768 ppFanins = Map_SuperReadFanins( pSuper );
769 // create a new node with these fanins
770 pNodeNew = Abc_NtkCreateNode( pNtkNew );
771 for ( i = 0; i < nFanins; i++ )
772 {
773 pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis );
774 Abc_ObjAddFanin( pNodeNew, pNodeFanin );
775 }
776 pNodeNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, Mio_GateReadSop(pRoot) );
777 return pNodeNew;
778 }
779
780 /**Function*************************************************************
781
782 Synopsis [Returns the twin node if it exists.]
783
784 Description []
785
786 SideEffects []
787
788 SeeAlso []
789
790 ***********************************************************************/
Abc_NtkFetchTwinNode(Abc_Obj_t * pNode)791 Abc_Obj_t * Abc_NtkFetchTwinNode( Abc_Obj_t * pNode )
792 {
793 Abc_Obj_t * pNode2;
794 Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData;
795 assert( Abc_NtkHasMapping(pNode->pNtk) );
796 if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL )
797 return NULL;
798 // assuming the twin node is following next
799 if ( (int)Abc_ObjId(pNode) == Abc_NtkObjNumMax(pNode->pNtk) - 1 )
800 return NULL;
801 pNode2 = Abc_NtkObj( pNode->pNtk, Abc_ObjId(pNode) + 1 );
802 if ( pNode2 == NULL || !Abc_ObjIsNode(pNode2) || Abc_ObjFaninNum(pNode) != Abc_ObjFaninNum(pNode2) )
803 return NULL;
804 if ( Mio_GateReadTwin(pGate) != (Mio_Gate_t *)pNode2->pData )
805 return NULL;
806 return pNode2;
807 }
808
809
810 /**Function*************************************************************
811
812 Synopsis [Dumps mapped network in the mini-mapped format.]
813
814 Description []
815
816 SideEffects []
817
818 SeeAlso []
819
820 ***********************************************************************/
Abc_NtkWriteMiniMapping(Abc_Ntk_t * pNtk)821 Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
822 {
823 Vec_Ptr_t * vNodes;
824 Vec_Int_t * vMapping;
825 Vec_Str_t * vGates;
826 Abc_Obj_t * pObj, * pFanin;
827 int i, k, nNodes, nFanins, nExtra, * pArray;
828 assert( Abc_NtkHasMapping(pNtk) );
829 // collect nodes in the DFS order
830 vNodes = Abc_NtkDfs( pNtk, 0 );
831 // assign unique numbers
832 nNodes = nFanins = 0;
833 Abc_NtkForEachCi( pNtk, pObj, i )
834 pObj->iTemp = nNodes++;
835 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
836 pObj->iTemp = nNodes++, nFanins += Abc_ObjFaninNum(pObj);
837 // allocate attay to store mapping (4 counters + fanins for each node + PO drivers + gate names)
838 vMapping = Vec_IntAlloc( 4 + Abc_NtkNodeNum(pNtk) + nFanins + Abc_NtkCoNum(pNtk) + 10000 );
839 // write the numbers of CI/CO/Node/FF
840 Vec_IntPush( vMapping, Abc_NtkCiNum(pNtk) );
841 Vec_IntPush( vMapping, Abc_NtkCoNum(pNtk) );
842 Vec_IntPush( vMapping, Abc_NtkNodeNum(pNtk) );
843 Vec_IntPush( vMapping, Abc_NtkLatchNum(pNtk) );
844 // write the nodes
845 vGates = Vec_StrAlloc( 10000 );
846 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
847 {
848 Vec_IntPush( vMapping, Abc_ObjFaninNum(pObj) );
849 Abc_ObjForEachFanin( pObj, pFanin, k )
850 Vec_IntPush( vMapping, pFanin->iTemp );
851 // remember this gate (to be added to the mapping later)
852 Vec_StrPrintStr( vGates, Mio_GateReadName((Mio_Gate_t *)pObj->pData) );
853 Vec_StrPush( vGates, '\0' );
854 }
855 // write the COs literals
856 Abc_NtkForEachCo( pNtk, pObj, i )
857 Vec_IntPush( vMapping, Abc_ObjFanin0(pObj)->iTemp );
858 // finish off the array
859 nExtra = 4 - Vec_StrSize(vGates) % 4;
860 for ( i = 0; i < nExtra; i++ )
861 Vec_StrPush( vGates, '\0' );
862 // add gates to the array
863 assert( Vec_StrSize(vGates) % 4 == 0 );
864 nExtra = Vec_StrSize(vGates) / 4;
865 pArray = (int *)Vec_StrArray(vGates);
866 for ( i = 0; i < nExtra; i++ )
867 Vec_IntPush( vMapping, pArray[i] );
868 // cleanup and return
869 Vec_PtrFree( vNodes );
870 Vec_StrFree( vGates );
871 return vMapping;
872 }
873
874 /**Function*************************************************************
875
876 Synopsis [Prints mapped network represented in mini-mapped format.]
877
878 Description []
879
880 SideEffects []
881
882 SeeAlso []
883
884 ***********************************************************************/
Abc_NtkPrintMiniMapping(int * pArray)885 void Abc_NtkPrintMiniMapping( int * pArray )
886 {
887 int nCis, nCos, nNodes, nFlops;
888 int i, k, nLeaves, Pos = 4;
889 char * pBuffer, * pName;
890 nCis = pArray[0];
891 nCos = pArray[1];
892 nNodes = pArray[2];
893 nFlops = pArray[3];
894 printf( "Mapped network has %d CIs, %d COs, %d gates, and %d flops.\n", nCis, nCos, nNodes, nFlops );
895 printf( "The first %d object IDs (from 0 to %d) are reserved for the CIs.\n", nCis, nCis - 1 );
896 for ( i = 0; i < nNodes; i++ )
897 {
898 printf( "Node %d has fanins {", nCis + i );
899 nLeaves = pArray[Pos++];
900 for ( k = 0; k < nLeaves; k++ )
901 printf( " %d", pArray[Pos++] );
902 printf( " }\n" );
903 }
904 for ( i = 0; i < nCos; i++ )
905 printf( "CO %d is driven by node %d\n", i, pArray[Pos++] );
906 pBuffer = (char *)(pArray + Pos);
907 for ( i = 0; i < nNodes; i++ )
908 {
909 pName = pBuffer;
910 pBuffer += strlen(pName) + 1;
911 printf( "Node %d has gate \"%s\"\n", nCis + i, pName );
912 }
913 }
914
915 /**Function*************************************************************
916
917 Synopsis [This procedure outputs an array representing mini-mapped network.]
918
919 Description []
920
921 SideEffects []
922
923 SeeAlso []
924
925 ***********************************************************************/
Abc_NtkOutputMiniMapping(Abc_Frame_t * pAbc)926 int * Abc_NtkOutputMiniMapping( Abc_Frame_t * pAbc )
927 {
928 //Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
929 Abc_Ntk_t * pNtk;
930 Vec_Int_t * vMapping;
931 int * pArray;
932 if ( pAbc == NULL )
933 printf( "ABC framework is not initialized by calling Abc_Start()\n" );
934 pNtk = Abc_FrameReadNtk( pAbc );
935 if ( pNtk == NULL )
936 printf( "Current network in ABC framework is not defined.\n" );
937 if ( !Abc_NtkHasMapping(pNtk) )
938 printf( "Current network in ABC framework is not mapped.\n" );
939 // derive mini-mapping
940 vMapping = Abc_NtkWriteMiniMapping( pNtk );
941 pArray = Vec_IntArray( vMapping );
942 ABC_FREE( vMapping );
943 // print mini-mapping (optional)
944 // Abc_NtkPrintMiniMapping( pArray );
945 // return the array representation of mini-mapping
946 return pArray;
947 }
948
949 /**Function*************************************************************
950
951 Synopsis [Test for mini-mapped format.]
952
953 Description []
954
955 SideEffects []
956
957 SeeAlso []
958
959 ***********************************************************************/
Abc_NtkTestMiniMapping(Abc_Ntk_t * p)960 void Abc_NtkTestMiniMapping( Abc_Ntk_t * p )
961 {
962 Vec_Int_t * vMapping;
963 vMapping = Abc_NtkWriteMiniMapping( p );
964 Abc_NtkPrintMiniMapping( Vec_IntArray(vMapping) );
965 printf( "Array has size %d ints.\n", Vec_IntSize(vMapping) );
966 Vec_IntFree( vMapping );
967 }
968
969 /**Function*************************************************************
970
971 Synopsis [These APIs set arrival/required times of CIs/COs.]
972
973 Description []
974
975 SideEffects []
976
977 SeeAlso []
978
979 ***********************************************************************/
Abc_NtkSetCiArrivalTime(Abc_Frame_t * pAbc,int iCi,float Rise,float Fall)980 void Abc_NtkSetCiArrivalTime( Abc_Frame_t * pAbc, int iCi, float Rise, float Fall )
981 {
982 //Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
983 Abc_Ntk_t * pNtk;
984 Abc_Obj_t * pNode;
985 if ( pAbc == NULL )
986 {
987 printf( "ABC framework is not initialized by calling Abc_Start()\n" );
988 return;
989 }
990 pNtk = Abc_FrameReadNtk( pAbc );
991 if ( pNtk == NULL )
992 {
993 printf( "Current network in ABC framework is not defined.\n" );
994 return;
995 }
996 if ( iCi < 0 || iCi >= Abc_NtkCiNum(pNtk) )
997 {
998 printf( "CI index is not valid.\n" );
999 return;
1000 }
1001 pNode = Abc_NtkCi( pNtk, iCi );
1002 Abc_NtkTimeSetArrival( pNtk, Abc_ObjId(pNode), Rise, Fall );
1003 }
Abc_NtkSetCoRequiredTime(Abc_Frame_t * pAbc,int iCo,float Rise,float Fall)1004 void Abc_NtkSetCoRequiredTime( Abc_Frame_t * pAbc, int iCo, float Rise, float Fall )
1005 {
1006 //Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
1007 Abc_Ntk_t * pNtk;
1008 Abc_Obj_t * pNode;
1009 if ( pAbc == NULL )\
1010 {
1011 printf( "ABC framework is not initialized by calling Abc_Start()\n" );
1012 return;
1013 }
1014 pNtk = Abc_FrameReadNtk( pAbc );
1015 if ( pNtk == NULL )
1016 {
1017 printf( "Current network in ABC framework is not defined.\n" );
1018 return;
1019 }
1020 if ( iCo < 0 || iCo >= Abc_NtkCoNum(pNtk) )
1021 {
1022 printf( "CO index is not valid.\n" );
1023 return;
1024 }
1025 pNode = Abc_NtkCo( pNtk, iCo );
1026 Abc_NtkTimeSetRequired( pNtk, Abc_ObjId(pNode), Rise, Fall );
1027 }
1028
1029 /**Function*************************************************************
1030
1031 Synopsis [This APIs set AND gate delay.]
1032
1033 Description []
1034
1035 SideEffects []
1036
1037 SeeAlso []
1038
1039 ***********************************************************************/
Abc_NtkSetAndGateDelay(Abc_Frame_t * pAbc,float Delay)1040 void Abc_NtkSetAndGateDelay( Abc_Frame_t * pAbc, float Delay )
1041 {
1042 //Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
1043 Abc_Ntk_t * pNtk;
1044 if ( pAbc == NULL )
1045 {
1046 printf( "ABC framework is not initialized by calling Abc_Start()\n" );
1047 return;
1048 }
1049 pNtk = Abc_FrameReadNtk( pAbc );
1050 if ( pNtk == NULL )
1051 {
1052 printf( "Current network in ABC framework is not defined.\n" );
1053 return;
1054 }
1055 pNtk->AndGateDelay = Delay;
1056 }
1057
1058 ////////////////////////////////////////////////////////////////////////
1059 /// END OF FILE ///
1060 ////////////////////////////////////////////////////////////////////////
1061
1062
1063 ABC_NAMESPACE_IMPL_END
1064
1065