1 /**CFile****************************************************************
2 
3   FileName    [abcHieCec.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Network and node package.]
8 
9   Synopsis    [Hierarchical CEC manager.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: abcHieCec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "abc.h"
22 #include "base/io/ioAbc.h"
23 #include "aig/gia/gia.h"
24 
25 ABC_NAMESPACE_IMPL_START
26 
27 ////////////////////////////////////////////////////////////////////////
28 ///                        DECLARATIONS                              ///
29 ////////////////////////////////////////////////////////////////////////
30 
31 #define Abc_ObjForEachFaninReal( pObj, pFanin, i )          \
32     for ( i = 0; (i < Abc_ObjFaninNum(pObj)) && (((pFanin) = Abc_ObjFaninReal(pObj, i)), 1); i++ )
33 
34 ////////////////////////////////////////////////////////////////////////
35 ///                     FUNCTION DEFINITIONS                         ///
36 ////////////////////////////////////////////////////////////////////////
37 
38 /**Function*************************************************************
39 
40   Synopsis    [Returns the real faniin of the object.]
41 
42   Description []
43 
44   SideEffects []
45 
46   SeeAlso     []
47 
48 ***********************************************************************/
Abc_ObjFaninReal(Abc_Obj_t * pObj,int i)49 static inline Abc_Obj_t * Abc_ObjFaninReal( Abc_Obj_t * pObj, int i )
50 {
51     Abc_Obj_t * pRes;
52     if ( Abc_ObjIsBox(pObj) )
53         pRes = Abc_ObjFanin0( Abc_ObjFanin0( Abc_ObjFanin(pObj, i) ) );
54     else
55     {
56         assert( Abc_ObjIsPo(pObj) || Abc_ObjIsNode(pObj) );
57         pRes = Abc_ObjFanin0( Abc_ObjFanin(pObj, i) );
58     }
59     if ( Abc_ObjIsBo(pRes) )
60         return Abc_ObjFanin0(pRes);
61     return pRes;
62 }
63 
64 /**Function*************************************************************
65 
66   Synopsis    [Performs DFS for one node.]
67 
68   Description []
69 
70   SideEffects []
71 
72   SeeAlso     []
73 
74 ***********************************************************************/
Abc_NtkDfsBoxes_rec(Abc_Obj_t * pNode,Vec_Ptr_t * vNodes)75 void Abc_NtkDfsBoxes_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
76 {
77     Abc_Obj_t * pFanin;
78     int i;
79     if ( Abc_ObjIsPi(pNode) )
80         return;
81     assert( Abc_ObjIsNode(pNode) || Abc_ObjIsBox(pNode) );
82     // if this node is already visited, skip
83     if ( Abc_NodeIsTravIdCurrent( pNode ) )
84         return;
85     Abc_NodeSetTravIdCurrent( pNode );
86     // visit the transitive fanin of the node
87     Abc_ObjForEachFaninReal( pNode, pFanin, i )
88         Abc_NtkDfsBoxes_rec( pFanin, vNodes );
89     // add the node after the fanins have been added
90     Vec_PtrPush( vNodes, pNode );
91 }
92 
93 /**Function*************************************************************
94 
95   Synopsis    [Returns the array of node and boxes reachable from POs.]
96 
97   Description []
98 
99   SideEffects []
100 
101   SeeAlso     []
102 
103 ***********************************************************************/
Abc_NtkDfsBoxes(Abc_Ntk_t * pNtk)104 Vec_Ptr_t * Abc_NtkDfsBoxes( Abc_Ntk_t * pNtk )
105 {
106     Vec_Ptr_t * vNodes;
107     Abc_Obj_t * pObj;
108     int i;
109     assert( Abc_NtkIsNetlist(pNtk) );
110     // set the traversal ID
111     Abc_NtkIncrementTravId( pNtk );
112     // start the array of nodes
113     vNodes = Vec_PtrAlloc( 100 );
114     Abc_NtkForEachPo( pNtk, pObj, i )
115         Abc_NtkDfsBoxes_rec( Abc_ObjFaninReal(pObj, 0), vNodes );
116     return vNodes;
117 }
118 
119 
120 /**Function*************************************************************
121 
122   Synopsis    [Strashes one logic node using its SOP.]
123 
124   Description []
125 
126   SideEffects []
127 
128   SeeAlso     []
129 
130 ***********************************************************************/
Abc_NtkDeriveFlatGiaSop(Gia_Man_t * pGia,int * gFanins,char * pSop)131 int Abc_NtkDeriveFlatGiaSop( Gia_Man_t * pGia, int * gFanins, char * pSop )
132 {
133     char * pCube;
134     int gAnd, gSum;
135     int i, Value, nFanins;
136     // get the number of variables
137     nFanins = Abc_SopGetVarNum(pSop);
138     if ( Abc_SopIsExorType(pSop) )
139     {
140         gSum = 0;
141         for ( i = 0; i < nFanins; i++ )
142             gSum = Gia_ManHashXor( pGia, gSum, gFanins[i] );
143     }
144     else
145     {
146         // go through the cubes of the node's SOP
147         gSum = 0;
148         Abc_SopForEachCube( pSop, nFanins, pCube )
149         {
150             // create the AND of literals
151             gAnd = 1;
152             Abc_CubeForEachVar( pCube, Value, i )
153             {
154                 if ( Value == '1' )
155                     gAnd = Gia_ManHashAnd( pGia, gAnd, gFanins[i] );
156                 else if ( Value == '0' )
157                     gAnd = Gia_ManHashAnd( pGia, gAnd, Abc_LitNot(gFanins[i]) );
158             }
159             // add to the sum of cubes
160             gSum = Gia_ManHashAnd( pGia, Abc_LitNot(gSum), Abc_LitNot(gAnd) );
161             gSum = Abc_LitNot( gSum );
162         }
163     }
164     // decide whether to complement the result
165     if ( Abc_SopIsComplement(pSop) )
166         gSum = Abc_LitNot(gSum);
167     return gSum;
168 }
169 
170 /**Function*************************************************************
171 
172   Synopsis    [Flattens the logic hierarchy of the netlist.]
173 
174   Description []
175 
176   SideEffects []
177 
178   SeeAlso     []
179 
180 ***********************************************************************/
Abc_NtkDeriveFlatGia_rec(Gia_Man_t * pGia,Abc_Ntk_t * pNtk)181 void Abc_NtkDeriveFlatGia_rec( Gia_Man_t * pGia, Abc_Ntk_t * pNtk )
182 {
183     int gFanins[16];
184     Vec_Ptr_t * vOrder = (Vec_Ptr_t *)pNtk->pData;
185     Abc_Obj_t * pObj, * pTerm;
186     Abc_Ntk_t * pNtkModel;
187     int i, k;
188     Abc_NtkForEachPi( pNtk, pTerm, i )
189         assert( Abc_ObjFanout0(pTerm)->iTemp >= 0 );
190     Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pObj, i )
191     {
192         if ( Abc_ObjIsNode(pObj) )
193         {
194             char * pSop = (char *)pObj->pData;
195 /*
196             int nLength = strlen(pSop);
197             if ( nLength == 4 ) // buf/inv
198             {
199                 assert( pSop[2] == '1' );
200                 assert( pSop[0] == '0' || pSop[0] == '1' );
201                 assert( Abc_ObjFanin0(pObj)->iTemp >= 0 );
202                 Abc_ObjFanout0(pObj)->iTemp = Abc_LitNotCond( Abc_ObjFanin0(pObj)->iTemp, pSop[0]=='0' );
203                 continue;
204             }
205             if ( nLength == 5 ) // and2
206             {
207                 assert( pSop[3] == '1' );
208                 assert( pSop[0] == '0' || pSop[0] == '1' );
209                 assert( pSop[1] == '0' || pSop[1] == '1' );
210                 assert( Abc_ObjFanin0(pObj)->iTemp >= 0 );
211                 assert( Abc_ObjFanin1(pObj)->iTemp >= 0 );
212                 Abc_ObjFanout0(pObj)->iTemp = Gia_ManHashAnd( pGia,
213                     Abc_LitNotCond( Abc_ObjFanin0(pObj)->iTemp, pSop[0]=='0' ),
214                     Abc_LitNotCond( Abc_ObjFanin1(pObj)->iTemp, pSop[1]=='0' )
215                     );
216                 continue;
217             }
218 */
219             assert( Abc_ObjFaninNum(pObj) <= 16 );
220             assert( Abc_ObjFaninNum(pObj) == Abc_SopGetVarNum(pSop) );
221             Abc_ObjForEachFanin( pObj, pTerm, k )
222             {
223                 gFanins[k] = pTerm->iTemp;
224                 assert( gFanins[k] >= 0 );
225             }
226             Abc_ObjFanout0(pObj)->iTemp = Abc_NtkDeriveFlatGiaSop( pGia, gFanins, pSop );
227             continue;
228         }
229         assert( Abc_ObjIsBox(pObj) );
230         pNtkModel = (Abc_Ntk_t *)pObj->pData;
231         Abc_NtkFillTemp( pNtkModel );
232         // check the match between the number of actual and formal parameters
233         assert( Abc_ObjFaninNum(pObj) == Abc_NtkPiNum(pNtkModel) );
234         assert( Abc_ObjFanoutNum(pObj) == Abc_NtkPoNum(pNtkModel) );
235         // assign PIs
236         Abc_ObjForEachFanin( pObj, pTerm, k )
237             Abc_ObjFanout0( Abc_NtkPi(pNtkModel, k) )->iTemp = Abc_ObjFanin0(pTerm)->iTemp;
238         // call recursively
239         Abc_NtkDeriveFlatGia_rec( pGia, pNtkModel );
240         // assign POs
241         Abc_ObjForEachFanout( pObj, pTerm, k )
242             Abc_ObjFanout0(pTerm)->iTemp = Abc_ObjFanin0( Abc_NtkPo(pNtkModel, k) )->iTemp;
243     }
244     Abc_NtkForEachPo( pNtk, pTerm, i )
245         assert( Abc_ObjFanin0(pTerm)->iTemp >= 0 );
246 }
247 
248 /**Function*************************************************************
249 
250   Synopsis    [Flattens the logic hierarchy of the netlist.]
251 
252   Description []
253 
254   SideEffects []
255 
256   SeeAlso     []
257 
258 ***********************************************************************/
Abc_NtkDeriveFlatGia(Abc_Ntk_t * pNtk)259 Gia_Man_t * Abc_NtkDeriveFlatGia( Abc_Ntk_t * pNtk )
260 {
261     Gia_Man_t * pTemp, * pGia = NULL;
262     Abc_Obj_t * pTerm;
263     int i;
264 
265     assert( Abc_NtkIsNetlist(pNtk) );
266     assert( !Abc_NtkLatchNum(pNtk) );
267     Abc_NtkFillTemp( pNtk );
268     // start the network
269     pGia = Gia_ManStart( (1<<16) );
270     pGia->pName = Abc_UtilStrsav( Abc_NtkName(pNtk) );
271     pGia->pSpec = Abc_UtilStrsav( Abc_NtkSpec(pNtk) );
272     Gia_ManHashAlloc( pGia );
273     // create PIs
274     Abc_NtkForEachPi( pNtk, pTerm, i )
275         Abc_ObjFanout0(pTerm)->iTemp = Gia_ManAppendCi( pGia );
276     // recursively flatten hierarchy
277     Abc_NtkDeriveFlatGia_rec( pGia, pNtk );
278     // create POs
279     Abc_NtkForEachPo( pNtk, pTerm, i )
280         Gia_ManAppendCo( pGia, Abc_ObjFanin0(pTerm)->iTemp );
281     // prepare return value
282     Gia_ManHashStop( pGia );
283     Gia_ManSetRegNum( pGia, 0 );
284     pGia = Gia_ManCleanup( pTemp = pGia );
285     Gia_ManStop( pTemp );
286     return pGia;
287 }
288 
289 /**Function*************************************************************
290 
291   Synopsis    [Counts the total number of AIG nodes before flattening.]
292 
293   Description []
294 
295   SideEffects []
296 
297   SeeAlso     []
298 
299 ***********************************************************************/
Abc_NtkCountAndNodes(Vec_Ptr_t * vOrder)300 int Abc_NtkCountAndNodes( Vec_Ptr_t * vOrder )
301 {
302     Gia_Man_t * pGiaBox;
303     Abc_Ntk_t * pNtkModel;
304     Abc_Obj_t * pObj;
305     int i, Counter = 0;
306     Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pObj, i )
307     {
308         if ( Abc_ObjIsNode(pObj) )
309         {
310             Counter++;
311             continue;
312         }
313         assert( Abc_ObjIsBox(pObj) );
314         pNtkModel = (Abc_Ntk_t *)pObj->pData;
315         pGiaBox   = (Gia_Man_t *)pNtkModel->pData;
316         Counter  += Gia_ManAndNum(pGiaBox);
317     }
318     return Counter;
319 }
320 
321 /**Function*************************************************************
322 
323   Synopsis    [Flattens the logic hierarchy of the netlist.]
324 
325   Description []
326 
327   SideEffects []
328 
329   SeeAlso     []
330 
331 ***********************************************************************/
Abc_NtkDeriveFlatGia2Derive(Abc_Ntk_t * pNtk,Vec_Ptr_t * vOrder)332 Gia_Man_t * Abc_NtkDeriveFlatGia2Derive( Abc_Ntk_t * pNtk, Vec_Ptr_t * vOrder )
333 {
334     int gFanins[16];
335     Abc_Ntk_t * pNtkModel;
336     Gia_Man_t * pGiaBox, * pGia = NULL;
337     Gia_Obj_t * pGiaObj;
338     Abc_Obj_t * pTerm, * pObj;
339     int i, k;
340 
341     assert( Abc_NtkIsNetlist(pNtk) );
342     assert( !Abc_NtkLatchNum(pNtk) );
343     Abc_NtkFillTemp( pNtk );
344 
345     // start the network
346     pGia = Gia_ManStart( (1<<15) );
347     pGia->pName = Abc_UtilStrsav( Abc_NtkName(pNtk) );
348     pGia->pSpec = Abc_UtilStrsav( Abc_NtkSpec(pNtk) );
349     Gia_ManHashAlloc( pGia );
350     // create PIs
351     Abc_NtkForEachPi( pNtk, pTerm, i )
352         Abc_ObjFanout0(pTerm)->iTemp = Gia_ManAppendCi( pGia );
353     // recursively flatten hierarchy
354     Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pObj, i )
355     {
356         if ( Abc_ObjIsNode(pObj) )
357         {
358             char * pSop = (char *)pObj->pData;
359             assert( Abc_ObjFaninNum(pObj) <= 16 );
360             assert( Abc_ObjFaninNum(pObj) == Abc_SopGetVarNum(pSop) );
361             Abc_ObjForEachFanin( pObj, pTerm, k )
362             {
363                 gFanins[k] = pTerm->iTemp;
364                 assert( gFanins[k] >= 0 );
365             }
366             Abc_ObjFanout0(pObj)->iTemp = Abc_NtkDeriveFlatGiaSop( pGia, gFanins, pSop );
367             continue;
368         }
369         assert( Abc_ObjIsBox(pObj) );
370         pNtkModel = (Abc_Ntk_t *)pObj->pData;
371         // check the match between the number of actual and formal parameters
372         assert( Abc_ObjFaninNum(pObj) == Abc_NtkPiNum(pNtkModel) );
373         assert( Abc_ObjFanoutNum(pObj) == Abc_NtkPoNum(pNtkModel) );
374 /*
375         // assign PIs
376         Abc_ObjForEachFanin( pObj, pTerm, k )
377             Abc_ObjFanout0( Abc_NtkPi(pNtkModel, k) )->iTemp = Abc_ObjFanin0(pTerm)->iTemp;
378         // call recursively
379         Abc_NtkDeriveFlatGia_rec( pGia, pNtkModel );
380         // assign POs
381         Abc_ObjForEachFanout( pObj, pTerm, k )
382             Abc_ObjFanout0(pTerm)->iTemp = Abc_ObjFanin0( Abc_NtkPo(pNtkModel, k) )->iTemp;
383 */
384         // duplicate the AIG
385         pGiaBox = (Gia_Man_t *)pNtkModel->pData;
386         assert( Abc_ObjFaninNum(pObj) == Gia_ManPiNum(pGiaBox) );
387         assert( Abc_ObjFanoutNum(pObj) == Gia_ManPoNum(pGiaBox) );
388         Gia_ManFillValue( pGiaBox );
389         Gia_ManConst0(pGiaBox)->Value = 0;
390         Abc_ObjForEachFanin( pObj, pTerm, k )
391             Gia_ManPi(pGiaBox, k)->Value = Abc_ObjFanin0(pTerm)->iTemp;
392         Gia_ManForEachAnd( pGiaBox, pGiaObj, k )
393             pGiaObj->Value = Gia_ManHashAnd( pGia, Gia_ObjFanin0Copy(pGiaObj), Gia_ObjFanin1Copy(pGiaObj) );
394         Abc_ObjForEachFanout( pObj, pTerm, k )
395             Abc_ObjFanout0(pTerm)->iTemp = Gia_ObjFanin0Copy(Gia_ManPo(pGiaBox, k));
396     }
397     // create POs
398     Abc_NtkForEachPo( pNtk, pTerm, i )
399         Gia_ManAppendCo( pGia, Abc_ObjFanin0(pTerm)->iTemp );
400     // prepare return value
401     Gia_ManHashStop( pGia );
402     Gia_ManSetRegNum( pGia, 0 );
403     pGia = Gia_ManCleanup( pGiaBox = pGia );
404     Gia_ManStop( pGiaBox );
405 
406     printf( "%8d -> ", Abc_NtkCountAndNodes(vOrder) );
407     Gia_ManPrintStats( pGia, NULL );
408     return pGia;
409 }
410 /*
411 void Abc_NtkDeriveFlatGia2_rec( Abc_Ntk_t * pNtk )
412 {
413     Vec_Ptr_t * vOrder;
414     Abc_Obj_t * pObj;
415     int i;
416     if ( pNtk->pData != NULL )
417         return;
418     vOrder = Abc_NtkDfsBoxes( pNtk );
419     Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pObj, i )
420         if ( Abc_ObjIsBox(pObj) )
421             Abc_NtkDeriveFlatGia2_rec( (Abc_Ntk_t *)pObj->pData );
422     pNtk->pData = Abc_NtkDeriveFlatGia2Derive( pNtk, vOrder );
423     Vec_PtrFree( vOrder );
424 }
425 
426 Gia_Man_t * Abc_NtkDeriveFlatGia2( Abc_Ntk_t * pNtk )
427 {
428     Vec_Ptr_t * vMods;
429     Abc_Ntk_t * pModel;
430     Gia_Man_t * pGia = NULL;
431     int i;
432 
433     assert( Abc_NtkIsNetlist(pNtk) );
434     assert( !Abc_NtkLatchNum(pNtk) );
435 
436     vMods = pNtk->pDesign->vModules;
437     Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
438         pModel->pData = NULL;
439 
440     Abc_NtkDeriveFlatGia2_rec( pNtk );
441     pGia = pNtk->pData;  pNtk->pData = NULL;
442 
443     Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
444         Gia_ManStopP( (Gia_Man_t **)&pModel->pData );
445 
446     return pGia;
447 }
448 */
Abc_NtkDeriveFlatGia2(Abc_Ntk_t * pNtk,Vec_Ptr_t * vModels)449 Gia_Man_t * Abc_NtkDeriveFlatGia2( Abc_Ntk_t * pNtk, Vec_Ptr_t * vModels )
450 {
451     Vec_Ptr_t * vOrder;
452     Abc_Ntk_t * pModel = NULL;
453     Gia_Man_t * pGia = NULL;
454     int i;
455 
456     Vec_PtrForEachEntry( Abc_Ntk_t *, vModels, pModel, i )
457     {
458         vOrder = Abc_NtkDfsBoxes( pModel );
459         pModel->pData = Abc_NtkDeriveFlatGia2Derive( pModel, vOrder );
460         Vec_PtrFree( vOrder );
461     }
462 
463     pGia = (Gia_Man_t *)pModel->pData;  pModel->pData = NULL;
464 
465     Vec_PtrForEachEntry( Abc_Ntk_t *, vModels, pModel, i )
466         Gia_ManStopP( (Gia_Man_t **)&pModel->pData );
467 
468     return pGia;
469 }
470 
471 
472 /**Function*************************************************************
473 
474   Synopsis    [Collect models in the DFS order.]
475 
476   Description []
477 
478   SideEffects []
479 
480   SeeAlso     []
481 
482 ***********************************************************************/
Abc_NtkCollectHie_rec(Abc_Ntk_t * pNtk,Vec_Ptr_t * vModels)483 void Abc_NtkCollectHie_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vModels )
484 {
485     Vec_Ptr_t * vOrder;
486     Abc_Obj_t * pObj;
487     int i;
488     if ( pNtk->iStep >= 0 )
489         return;
490     vOrder = Abc_NtkDfsBoxes( pNtk );
491     Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pObj, i )
492         if ( Abc_ObjIsBox(pObj) && (Abc_Ntk_t *)pObj->pData != pNtk )
493             Abc_NtkCollectHie_rec( (Abc_Ntk_t *)pObj->pData, vModels );
494     Vec_PtrFree( vOrder );
495     pNtk->iStep = Vec_PtrSize(vModels);
496     Vec_PtrPush( vModels, pNtk );
497 }
498 
Abc_NtkCollectHie(Abc_Ntk_t * pNtk)499 Vec_Ptr_t * Abc_NtkCollectHie( Abc_Ntk_t * pNtk )
500 {
501     Vec_Ptr_t * vMods, * vResult;
502     Abc_Ntk_t * pModel;
503     int i;
504 
505     assert( Abc_NtkIsNetlist(pNtk) );
506     assert( !Abc_NtkLatchNum(pNtk) );
507 
508     vResult = Vec_PtrAlloc( 1000 );
509     if ( pNtk->pDesign == NULL )
510     {
511         Vec_PtrPush( vResult, pNtk );
512         return vResult;
513     }
514 
515     vMods = pNtk->pDesign->vModules;
516     Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
517         pModel->iStep = -1;
518 
519     Abc_NtkCollectHie_rec( pNtk, vResult );
520     return vResult;
521 }
522 
523 /**Function*************************************************************
524 
525   Synopsis    [Counts the number of intstances.]
526 
527   Description []
528 
529   SideEffects []
530 
531   SeeAlso     []
532 
533 ***********************************************************************/
Abc_NtkCountInst_rec(Abc_Ntk_t * pNtk)534 int Abc_NtkCountInst_rec( Abc_Ntk_t * pNtk )
535 {
536     Vec_Ptr_t * vOrder;
537     Abc_Obj_t * pObj;
538     int i, Counter = 0;
539     if ( pNtk->iStep >= 0 )
540         return pNtk->iStep;
541     vOrder = Abc_NtkDfsBoxes( pNtk );
542     Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pObj, i )
543         if ( Abc_ObjIsBox(pObj) && (Abc_Ntk_t *)pObj->pData != pNtk )
544             Counter += Abc_NtkCountInst_rec( (Abc_Ntk_t *)pObj->pData );
545     Vec_PtrFree( vOrder );
546     return pNtk->iStep = 1 + Counter;
547 }
548 
Abc_NtkCountInst(Abc_Ntk_t * pNtk)549 void Abc_NtkCountInst( Abc_Ntk_t * pNtk )
550 {
551     Vec_Ptr_t * vMods;
552     Abc_Ntk_t * pModel;
553     int i, Counter;
554 
555     if ( pNtk->pDesign == NULL )
556         Counter = Abc_NtkNodeNum(pNtk);
557     else
558     {
559         vMods = pNtk->pDesign->vModules;
560         Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
561             pModel->iStep = -1;
562         Counter = Abc_NtkCountInst_rec( pNtk );
563     }
564     printf( "Instances = %10d.\n", Counter );
565 }
566 
567 /**Function*************************************************************
568 
569   Synopsis    [Counts the number of nodes.]
570 
571   Description []
572 
573   SideEffects []
574 
575   SeeAlso     []
576 
577 ***********************************************************************/
Abc_NtkCountNodes_rec(Abc_Ntk_t * pNtk)578 double Abc_NtkCountNodes_rec( Abc_Ntk_t * pNtk )
579 {
580     Vec_Ptr_t * vOrder;
581     Abc_Obj_t * pObj;
582     double Counter = 0;
583     int i;
584     if ( pNtk->dTemp >= 0 )
585         return pNtk->dTemp;
586     vOrder = Abc_NtkDfsBoxes( pNtk );
587     Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pObj, i )
588         if ( Abc_ObjIsNode(pObj) )
589             Counter++;
590         else if ( Abc_ObjIsBox(pObj) && (Abc_Ntk_t *)pObj->pData != pNtk )
591             Counter += Abc_NtkCountNodes_rec( (Abc_Ntk_t *)pObj->pData );
592     Vec_PtrFree( vOrder );
593     return pNtk->dTemp = Counter;
594 }
595 
Abc_NtkCountNodes(Abc_Ntk_t * pNtk)596 void Abc_NtkCountNodes( Abc_Ntk_t * pNtk )
597 {
598     Vec_Ptr_t * vMods;
599     Abc_Ntk_t * pModel;
600     double Counter;
601     int i;
602 
603     if ( pNtk->pDesign == NULL )
604         Counter = Abc_NtkNodeNum(pNtk);
605     else
606     {
607         vMods = pNtk->pDesign->vModules;
608         Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
609             pModel->dTemp = -1;
610         Counter = Abc_NtkCountNodes_rec( pNtk );
611     }
612     printf( "Nodes = %.0f\n", Counter );
613 }
614 
615 /**Function*************************************************************
616 
617   Synopsis    [Checks if there is a recursive definition.]
618 
619   Description []
620 
621   SideEffects []
622 
623   SeeAlso     []
624 
625 ***********************************************************************/
Abc_NtkCheckRecursive(Abc_Ntk_t * pNtk)626 int Abc_NtkCheckRecursive( Abc_Ntk_t * pNtk )
627 {
628     Vec_Ptr_t * vMods;
629     Abc_Ntk_t * pModel;
630     Abc_Obj_t * pObj;
631     int i, k, RetValue = 0;
632 
633     assert( Abc_NtkIsNetlist(pNtk) );
634     assert( !Abc_NtkLatchNum(pNtk) );
635 
636     if ( pNtk->pDesign == NULL )
637         return RetValue;
638 
639     vMods = pNtk->pDesign->vModules;
640     Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
641     {
642         Abc_NtkForEachObj( pModel, pObj, k )
643             if ( Abc_ObjIsBox(pObj) && pObj->pData == (void *)pModel )
644             {
645                 printf( "WARNING: Model \"%s\" contains a recursive definition.\n", Abc_NtkName(pModel) );
646                 RetValue = 1;
647                 break;
648             }
649     }
650     return RetValue;
651 }
652 
653 /**Function*************************************************************
654 
655   Synopsis    [Performs hierarchical equivalence checking.]
656 
657   Description []
658 
659   SideEffects []
660 
661   SeeAlso     []
662 
663 ***********************************************************************/
Abc_NtkHieCecTest(char * pFileName,int fVerbose)664 Gia_Man_t * Abc_NtkHieCecTest( char * pFileName, int fVerbose )
665 {
666     int fUseTest = 1;
667     int fUseNew = 0;
668     int fCheck = 1;
669     Vec_Ptr_t * vMods, * vOrder;
670     Abc_Ntk_t * pNtk, * pModel;
671     Gia_Man_t * pGia;
672     int i;
673     abctime clk = Abc_Clock();
674 
675     // read hierarchical netlist
676     pNtk = Io_ReadBlifMv( pFileName, 0, fCheck );
677     if ( pNtk == NULL )
678     {
679         printf( "Reading BLIF file has failed.\n" );
680         return NULL;
681     }
682     if ( pNtk->pDesign == NULL || pNtk->pDesign->vModules == NULL )
683     {
684         printf( "There is no hierarchy information.\n" );
685 //        Abc_NtkDelete( pNtk );
686 //        return NULL;
687     }
688     Abc_PrintTime( 1, "Reading file", Abc_Clock() - clk );
689 
690     assert( Abc_NtkIsNetlist(pNtk) );
691     assert( !Abc_NtkLatchNum(pNtk) );
692 /*
693     if ( pNtk->pDesign != NULL )
694     {
695         clk = Abc_Clock();
696         Abc_NtkCountNodes( pNtk );
697         Abc_PrintTime( 1, "Count nodes", Abc_Clock() - clk );
698     }
699 */
700     // print stats
701     if ( fVerbose )
702         Abc_NtkPrintBoxInfo( pNtk );
703 
704     // test the new data-structure
705     if ( fUseTest )
706     {
707         extern Gia_Man_t * Au_ManDeriveTest( Abc_Ntk_t * pRoot );
708         Gia_Man_t * pGia;
709         pGia = Au_ManDeriveTest( pNtk );
710         Abc_NtkDelete( pNtk );
711         return pGia;
712     }
713 
714     if ( Abc_NtkCheckRecursive(pNtk) )
715         return NULL;
716 
717     if ( fUseNew )
718     {
719         clk = Abc_Clock();
720         vOrder = Abc_NtkCollectHie( pNtk );
721         Abc_PrintTime( 1, "Collect DFS ", Abc_Clock() - clk );
722 
723         // derive GIA
724         clk = Abc_Clock();
725         pGia = Abc_NtkDeriveFlatGia2( pNtk, vOrder );
726         Abc_PrintTime( 1, "Deriving GIA", Abc_Clock() - clk );
727         Gia_ManPrintStats( pGia, NULL );
728     //    Gia_ManStop( pGia );
729 
730         Vec_PtrFree( vOrder );
731     }
732     else
733     {
734         // order nodes/boxes of all models
735         vMods = pNtk->pDesign->vModules;
736         Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
737             pModel->pData = Abc_NtkDfsBoxes( pModel );
738 
739         // derive GIA
740         clk = Abc_Clock();
741         pGia = Abc_NtkDeriveFlatGia( pNtk );
742         Abc_PrintTime( 1, "Deriving GIA", Abc_Clock() - clk );
743         Gia_ManPrintStats( pGia, NULL );
744 
745         // clean nodes/boxes of all nodes
746         Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
747             Vec_PtrFree( (Vec_Ptr_t *)pModel->pData );
748     }
749 
750     clk = Abc_Clock();
751     Abc_NtkCountInst( pNtk );
752     Abc_PrintTime( 1, "Gather stats", Abc_Clock() - clk );
753 
754     Abc_NtkDelete( pNtk );
755     return pGia;
756 }
757 
758 ////////////////////////////////////////////////////////////////////////
759 ///                       END OF FILE                                ///
760 ////////////////////////////////////////////////////////////////////////
761 
762 
763 ABC_NAMESPACE_IMPL_END
764 
765