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