1 /**CFile****************************************************************
2 
3   FileName    [abcPrint.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Network and node package.]
8 
9   Synopsis    [Printing statistics.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: abcPrint.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include <math.h>
22 #include "base/abc/abc.h"
23 #include "bool/dec/dec.h"
24 #include "base/main/main.h"
25 #include "map/mio/mio.h"
26 #include "aig/aig/aig.h"
27 #include "map/if/if.h"
28 
29 #ifdef ABC_USE_CUDD
30 #include "bdd/extrab/extraBdd.h"
31 #endif
32 
33 #ifdef WIN32
34 #include <windows.h>
35 #endif
36 
37 ABC_NAMESPACE_IMPL_START
38 
39 
40 ////////////////////////////////////////////////////////////////////////
41 ///                        DECLARATIONS                              ///
42 ////////////////////////////////////////////////////////////////////////
43 
44 //extern int s_TotalNodes = 0;
45 //extern int s_TotalChanges = 0;
46 
47 abctime s_MappingTime = 0;
48 int s_MappingMem = 0;
49 abctime s_ResubTime = 0;
50 abctime s_ResynTime = 0;
51 
52 ////////////////////////////////////////////////////////////////////////
53 ///                     FUNCTION DEFINITIONS                         ///
54 ////////////////////////////////////////////////////////////////////////
55 
56 /**Function*************************************************************
57 
58   Synopsis    [If the network is best, saves it in "best.blif" and returns 1.]
59 
60   Description [If the networks are incomparable, saves the new network,
61   returns its parameters in the internal parameter structure, and returns 1.
62   If the new network is not a logic network, quits without saving and returns 0.]
63 
64   SideEffects []
65 
66   SeeAlso     []
67 
68 ***********************************************************************/
Abc_NtkCompareAndSaveBest(Abc_Ntk_t * pNtk)69 int Abc_NtkCompareAndSaveBest( Abc_Ntk_t * pNtk )
70 {
71     extern void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType );
72     static struct ParStruct {
73         char * pName;  // name of the best saved network
74         int    Depth;  // depth of the best saved network
75         int    Flops;  // flops in the best saved network
76         int    Nodes;  // nodes in the best saved network
77         int    Edges;  // edges in the best saved network
78         int    nPis;   // the number of primary inputs
79         int    nPos;   // the number of primary outputs
80     } ParsNew, ParsBest = { 0 };
81     char * pFileNameOut;
82     // free storage for the name
83     if ( pNtk == NULL )
84     {
85         ABC_FREE( ParsBest.pName );
86         return 0;
87     }
88     // quit if not a logic network
89     if ( !Abc_NtkIsLogic(pNtk) )
90         return 0;
91     // get the parameters
92     ParsNew.Depth = Abc_NtkLevel( pNtk );
93     ParsNew.Flops = Abc_NtkLatchNum( pNtk );
94     ParsNew.Nodes = Abc_NtkNodeNum( pNtk );
95     ParsNew.Edges = Abc_NtkGetTotalFanins( pNtk );
96     ParsNew.nPis  = Abc_NtkPiNum( pNtk );
97     ParsNew.nPos  = Abc_NtkPoNum( pNtk );
98     // reset the parameters if the network has the same name
99     if (  ParsBest.pName == NULL ||
100           strcmp(ParsBest.pName, pNtk->pName) ||
101           ParsBest.Depth >  ParsNew.Depth ||
102          (ParsBest.Depth == ParsNew.Depth && ParsBest.Flops >  ParsNew.Flops) ||
103          (ParsBest.Depth == ParsNew.Depth && ParsBest.Flops == ParsNew.Flops && ParsBest.Edges >  ParsNew.Edges) )
104     {
105         ABC_FREE( ParsBest.pName );
106         ParsBest.pName = Extra_UtilStrsav( pNtk->pName );
107         ParsBest.Depth = ParsNew.Depth;
108         ParsBest.Flops = ParsNew.Flops;
109         ParsBest.Nodes = ParsNew.Nodes;
110         ParsBest.Edges = ParsNew.Edges;
111         ParsBest.nPis  = ParsNew.nPis;
112         ParsBest.nPos  = ParsNew.nPos;
113         // writ the network
114         if ( strcmp(pNtk->pSpec + strlen(pNtk->pSpec) - strlen("_best.blif"), "_best.blif") )
115             pFileNameOut = Extra_FileNameGenericAppend( pNtk->pSpec, "_best.blif" );
116         else
117             pFileNameOut = pNtk->pSpec;
118         Io_Write( pNtk, pFileNameOut, IO_FILE_BLIF );
119         return 1;
120     }
121     return 0;
122 }
123 
124 /**Function*************************************************************
125 
126   Synopsis    [Collects memory usage.]
127 
128   Description []
129 
130   SideEffects []
131 
132   SeeAlso     []
133 
134 ***********************************************************************/
Abc_NtkMemory(Abc_Ntk_t * p)135 double Abc_NtkMemory( Abc_Ntk_t * p )
136 {
137     Abc_Obj_t * pObj; int i;
138     double Memory = sizeof(Abc_Ntk_t);
139     Memory += sizeof(Abc_Obj_t) * Abc_NtkObjNum(p);
140     Memory += Vec_PtrMemory(p->vPis);
141     Memory += Vec_PtrMemory(p->vPos);
142     Memory += Vec_PtrMemory(p->vCis);
143     Memory += Vec_PtrMemory(p->vCos);
144     Memory += Vec_PtrMemory(p->vObjs);
145     Memory += Vec_IntMemory(&p->vTravIds);
146     Memory += Vec_IntMemory(p->vLevelsR);
147     Abc_NtkForEachObj( p, pObj, i )
148         Memory += sizeof(int) * (Vec_IntCap(&pObj->vFanins) + Vec_IntCap(&pObj->vFanouts));
149     return Memory;
150 }
151 
152 /**Function*************************************************************
153 
154   Synopsis    [Marks nodes for power-optimization.]
155 
156   Description []
157 
158   SideEffects []
159 
160   SeeAlso     []
161 
162 ***********************************************************************/
Abc_NtkMfsTotalSwitching(Abc_Ntk_t * pNtk)163 float Abc_NtkMfsTotalSwitching( Abc_Ntk_t * pNtk )
164 {
165     extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
166     extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
167     Vec_Int_t * vSwitching;
168     float * pSwitching;
169     Abc_Ntk_t * pNtkStr;
170     Aig_Man_t * pAig;
171     Aig_Obj_t * pObjAig;
172     Abc_Obj_t * pObjAbc, * pObjAbc2;
173     float Result = (float)0;
174     int i;
175     // strash the network
176     pNtkStr = Abc_NtkStrash( pNtk, 0, 1, 0 );
177     Abc_NtkForEachObj( pNtk, pObjAbc, i )
178         if ( (pObjAbc->pTemp && Abc_ObjRegular((Abc_Obj_t *)pObjAbc->pTemp)->Type == ABC_FUNC_NONE) || (!Abc_ObjIsCi(pObjAbc) && !Abc_ObjIsNode(pObjAbc)) )
179             pObjAbc->pTemp = NULL;
180     // map network into an AIG
181     pAig = Abc_NtkToDar( pNtkStr, 0, (int)(Abc_NtkLatchNum(pNtk) > 0) );
182     vSwitching = Saig_ManComputeSwitchProbs( pAig, 48, 16, 0 );
183     pSwitching = (float *)vSwitching->pArray;
184     Abc_NtkForEachObj( pNtk, pObjAbc, i )
185     {
186         if ( (pObjAbc2 = Abc_ObjRegular((Abc_Obj_t *)pObjAbc->pTemp)) && (pObjAig = Aig_Regular((Aig_Obj_t *)pObjAbc2->pTemp)) )
187         {
188             Result += Abc_ObjFanoutNum(pObjAbc) * pSwitching[pObjAig->Id];
189 //            Abc_ObjPrint( stdout, pObjAbc );
190 //            printf( "%d = %.2f\n", i, Abc_ObjFanoutNum(pObjAbc) * pSwitching[pObjAig->Id] );
191         }
192     }
193     Vec_IntFree( vSwitching );
194     Aig_ManStop( pAig );
195     Abc_NtkDelete( pNtkStr );
196     return Result;
197 }
198 
199 /**Function*************************************************************
200 
201   Synopsis    [Compute area using LUT library.]
202 
203   Description []
204 
205   SideEffects []
206 
207   SeeAlso     []
208 
209 ***********************************************************************/
Abc_NtkGetArea(Abc_Ntk_t * pNtk)210 float Abc_NtkGetArea( Abc_Ntk_t * pNtk )
211 {
212     If_LibLut_t * pLutLib;
213     Abc_Obj_t * pObj;
214     float Counter = 0.0;
215     int i;
216     assert( Abc_NtkIsLogic(pNtk) );
217     // get the library
218     pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut();
219     if ( pLutLib && pLutLib->LutMax >= Abc_NtkGetFaninMax(pNtk) )
220     {
221         Abc_NtkForEachNode( pNtk, pObj, i )
222             Counter += pLutLib->pLutAreas[Abc_ObjFaninNum(pObj)];
223     }
224     return Counter;
225 }
226 
227 /**Function*************************************************************
228 
229   Synopsis    [Print the vital stats of the network.]
230 
231   Description []
232 
233   SideEffects []
234 
235   SeeAlso     []
236 
237 ***********************************************************************/
Abc_NtkPrintStats(Abc_Ntk_t * pNtk,int fFactored,int fSaveBest,int fDumpResult,int fUseLutLib,int fPrintMuxes,int fPower,int fGlitch,int fSkipBuf,int fSkipSmall,int fPrintMem)238 void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDumpResult, int fUseLutLib, int fPrintMuxes, int fPower, int fGlitch, int fSkipBuf, int fSkipSmall, int fPrintMem )
239 {
240     int nSingles = fSkipBuf ? Abc_NtkGetBufNum(pNtk) : 0;
241     if ( fPrintMuxes && Abc_NtkIsStrash(pNtk) )
242     {
243         extern int Abc_NtkCountMuxes( Abc_Ntk_t * pNtk );
244         int nXors = Abc_NtkGetExorNum(pNtk);
245         int nMuxs = Abc_NtkCountMuxes(pNtk) - nXors;
246         int nAnds = Abc_NtkNodeNum(pNtk) - (nMuxs + nXors) * 3 - nSingles;
247         Abc_Print( 1, "XMA stats:  " );
248         Abc_Print( 1,"Xor =%7d (%6.2f %%)  ", nXors, 300.0 * nXors / Abc_NtkNodeNum(pNtk) );
249         Abc_Print( 1,"Mux =%7d (%6.2f %%)  ", nMuxs, 300.0 * nMuxs / Abc_NtkNodeNum(pNtk) );
250         Abc_Print( 1,"And =%7d (%6.2f %%)  ",   nAnds, 100.0 * nAnds / Abc_NtkNodeNum(pNtk) );
251         Abc_Print( 1,"Total =%7d",   nAnds + nXors + nMuxs );
252         Abc_Print( 1,"\n" );
253         return;
254     }
255     if ( fSaveBest )
256         Abc_NtkCompareAndSaveBest( pNtk );
257 /*
258     if ( fDumpResult )
259     {
260         char Buffer[1000] = {0};
261         const char * pNameGen = pNtk->pSpec? Extra_FileNameGeneric( pNtk->pSpec ) : "nameless_";
262         sprintf( Buffer, "%s_dump.blif", pNameGen );
263         Io_Write( pNtk, Buffer, IO_FILE_BLIF );
264         if ( pNtk->pSpec ) ABC_FREE( pNameGen );
265     }
266 */
267 
268 //    if ( Abc_NtkIsStrash(pNtk) )
269 //        Abc_AigCountNext( pNtk->pManFunc );
270 
271 #ifdef WIN32
272     SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), 15 ); // bright
273     Abc_Print( 1,"%-30s:", pNtk->pName );
274     SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), 7 );  // normal
275 #else
276     Abc_Print( 1,"%s%-30s:%s", "\033[1;37m", pNtk->pName, "\033[0m" );  // bright
277 #endif
278     Abc_Print( 1," i/o =%5d/%5d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
279     if ( Abc_NtkConstrNum(pNtk) )
280         Abc_Print( 1,"(c=%d)", Abc_NtkConstrNum(pNtk) );
281     Abc_Print( 1,"  lat =%5d", Abc_NtkLatchNum(pNtk) );
282     if ( pNtk->nBarBufs )
283         Abc_Print( 1,"(b=%d)", pNtk->nBarBufs );
284     if ( Abc_NtkIsNetlist(pNtk) )
285     {
286         Abc_Print( 1,"  net =%5d", Abc_NtkNetNum(pNtk) );
287         Abc_Print( 1,"  nd =%5d",  fSkipSmall ? Abc_NtkGetLargeNodeNum(pNtk) : Abc_NtkNodeNum(pNtk) - nSingles );
288         Abc_Print( 1,"  wbox =%3d", Abc_NtkWhiteboxNum(pNtk) );
289         Abc_Print( 1,"  bbox =%3d", Abc_NtkBlackboxNum(pNtk) );
290     }
291     else if ( Abc_NtkIsStrash(pNtk) )
292     {
293         Abc_Print( 1,"  and =%7d", Abc_NtkNodeNum(pNtk) );
294         if ( Abc_NtkGetChoiceNum(pNtk) )
295             Abc_Print( 1," (choice = %d)", Abc_NtkGetChoiceNum(pNtk) );
296     }
297     else
298     {
299         Abc_Print( 1,"  nd =%6d", fSkipSmall ? Abc_NtkGetLargeNodeNum(pNtk) : Abc_NtkNodeNum(pNtk) - nSingles );
300         Abc_Print( 1,"  edge =%7d", Abc_NtkGetTotalFanins(pNtk) - nSingles );
301     }
302 
303     if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsNetlist(pNtk) )
304     {
305     }
306     else if ( Abc_NtkHasSop(pNtk) )
307     {
308 
309         Abc_Print( 1,"  cube =%6d",  Abc_NtkGetCubeNum(pNtk) - nSingles );
310         if ( fFactored )
311             Abc_Print( 1,"  lit(sop) =%6d",  Abc_NtkGetLitNum(pNtk) - nSingles );
312         if ( fFactored )
313             Abc_Print( 1,"  lit(fac) =%6d",  Abc_NtkGetLitFactNum(pNtk) - nSingles );
314     }
315     else if ( Abc_NtkHasAig(pNtk) )
316         Abc_Print( 1,"  aig  =%6d",  Abc_NtkGetAigNodeNum(pNtk) - nSingles );
317     else if ( Abc_NtkHasBdd(pNtk) )
318         Abc_Print( 1,"  bdd  =%6d",  Abc_NtkGetBddNodeNum(pNtk) - nSingles );
319     else if ( Abc_NtkHasMapping(pNtk) )
320     {
321         int fHasTimeMan = (int)(pNtk->pManTime != NULL);
322         assert( pNtk->pManFunc == Abc_FrameReadLibGen() );
323         Abc_Print( 1,"  area =%5.2f", Abc_NtkGetMappedArea(pNtk) );
324         Abc_Print( 1,"  delay =%5.2f", Abc_NtkDelayTrace(pNtk, NULL, NULL, 0) );
325         if ( !fHasTimeMan && pNtk->pManTime )
326         {
327             Abc_ManTimeStop( pNtk->pManTime );
328             pNtk->pManTime = NULL;
329         }
330     }
331     else if ( !Abc_NtkHasBlackbox(pNtk) )
332     {
333         assert( 0 );
334     }
335 
336     if ( Abc_NtkIsStrash(pNtk) )
337     {
338         extern int Abc_NtkGetMultiRefNum( Abc_Ntk_t * pNtk );
339         Abc_Print( 1,"  lev =%3d", Abc_AigLevel(pNtk) );
340 //        Abc_Print( 1,"  ff = %5d", Abc_NtkNodeNum(pNtk) + 2 * (Abc_NtkCoNum(pNtk)+Abc_NtkGetMultiRefNum(pNtk)) );
341 //        Abc_Print( 1,"  var = %5d", Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk)+Abc_NtkGetMultiRefNum(pNtk) );
342     }
343     else
344         Abc_Print( 1,"  lev = %d", Abc_NtkLevel(pNtk) );
345     if ( pNtk->nBarBufs2 )
346         Abc_Print( 1,"  buf = %d", pNtk->nBarBufs2 );
347     if ( fUseLutLib && Abc_FrameReadLibLut() )
348         Abc_Print( 1,"  delay =%5.2f", Abc_NtkDelayTraceLut(pNtk, 1) );
349     if ( fUseLutLib && Abc_FrameReadLibLut() )
350         Abc_Print( 1,"  area =%5.2f", Abc_NtkGetArea(pNtk) );
351     if ( fPower )
352         Abc_Print( 1,"  power =%7.2f", Abc_NtkMfsTotalSwitching(pNtk) );
353     if ( fGlitch )
354     {
355         if ( Abc_NtkIsLogic(pNtk) && Abc_NtkGetFaninMax(pNtk) <= 6 )
356             Abc_Print( 1,"  glitch =%7.2f %%", Abc_NtkMfsTotalGlitching(pNtk, 4000, 8, 0) );
357         else
358             printf( "\nCurrently computes glitching only for K-LUT networks with K <= 6." );
359     }
360     if ( fPrintMem )
361         Abc_Print( 1,"  mem =%5.2f MB", Abc_NtkMemory(pNtk)/(1<<20) );
362     Abc_Print( 1,"\n" );
363 
364     // print the statistic into a file
365     if ( fDumpResult )
366     {
367         FILE * pTable = fopen( "abcstats.txt", "a+" );
368         fprintf( pTable, "%s ",  pNtk->pName );
369         fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) );
370         fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) );
371         fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
372         fprintf( pTable, "%d ", Abc_NtkGetTotalFanins(pNtk) );
373         fprintf( pTable, "%d ", Abc_NtkLevel(pNtk) );
374         fprintf( pTable, "\n" );
375         fclose( pTable );
376     }
377 /*
378     {
379         FILE * pTable;
380         pTable = fopen( "ibm/seq_stats.txt", "a+" );
381 //        fprintf( pTable, "%s ",  pNtk->pName );
382 //        fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) );
383 //        fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) );
384         fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
385         fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) );
386         fprintf( pTable, "%d ", Abc_NtkLevel(pNtk) );
387         fprintf( pTable, "\n" );
388         fclose( pTable );
389     }
390 */
391 
392 /*
393     // print the statistic into a file
394     {
395         FILE * pTable;
396         pTable = fopen( "ucsb/stats.txt", "a+" );
397 //        fprintf( pTable, "%s ",  pNtk->pSpec );
398         fprintf( pTable, "%d ",  Abc_NtkNodeNum(pNtk) );
399 //        fprintf( pTable, "%d ",  Abc_NtkLevel(pNtk) );
400 //        fprintf( pTable, "%.0f ", Abc_NtkGetMappedArea(pNtk) );
401 //        fprintf( pTable, "%.2f ", Abc_NtkDelayTrace(pNtk) );
402         fprintf( pTable, "\n" );
403         fclose( pTable );
404     }
405 */
406 
407 /*
408     // print the statistic into a file
409     {
410         FILE * pTable;
411         pTable = fopen( "x/stats_new.txt", "a+" );
412         fprintf( pTable, "%s ",  pNtk->pName );
413 //        fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) );
414 //        fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) );
415 //        fprintf( pTable, "%d ", Abc_NtkLevel(pNtk) );
416 //        fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
417 //        fprintf( pTable, "%d ", Abc_NtkGetTotalFanins(pNtk) );
418 //        fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) );
419 //        fprintf( pTable, "%.2f ", (float)(s_MappingMem)/(float)(1<<20) );
420         fprintf( pTable, "%.2f", (float)(s_MappingTime)/(float)(CLOCKS_PER_SEC) );
421 //        fprintf( pTable, "%.2f", (float)(s_ResynTime)/(float)(CLOCKS_PER_SEC) );
422         fprintf( pTable, "\n" );
423         fclose( pTable );
424 
425         s_ResynTime = 0;
426     }
427 */
428 
429 /*
430     // print the statistic into a file
431     {
432         static int Counter = 0;
433         extern int timeRetime;
434         FILE * pTable;
435         Counter++;
436         pTable = fopen( "d/stats.txt", "a+" );
437         fprintf( pTable, "%s ", pNtk->pName );
438 //        fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) );
439 //        fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) );
440 //        fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) );
441         fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
442         fprintf( pTable, "%.2f ", (float)(timeRetime)/(float)(CLOCKS_PER_SEC) );
443         fprintf( pTable, "\n" );
444         fclose( pTable );
445     }
446 
447 
448     s_TotalNodes += Abc_NtkNodeNum(pNtk);
449     printf( "Total nodes = %6d   %6.2f MB   Changes = %6d.\n",
450         s_TotalNodes, s_TotalNodes * 20.0 / (1<<20), s_TotalChanges );
451 */
452 
453 //    if ( Abc_NtkHasSop(pNtk) )
454 //        printf( "The total number of cube pairs = %d.\n", Abc_NtkGetCubePairNum(pNtk) );
455 
456     fflush( stdout );
457     if ( pNtk->pExdc )
458         Abc_NtkPrintStats( pNtk->pExdc, fFactored, fSaveBest, fDumpResult, fUseLutLib, fPrintMuxes, fPower, fGlitch, fSkipBuf, fSkipSmall, fPrintMem );
459 }
460 
461 /**Function*************************************************************
462 
463   Synopsis    [Prints PIs/POs and LIs/LOs.]
464 
465   Description []
466 
467   SideEffects []
468 
469   SeeAlso     []
470 
471 ***********************************************************************/
Abc_NtkPrintIo(FILE * pFile,Abc_Ntk_t * pNtk,int fPrintFlops)472 void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintFlops )
473 {
474     Abc_Obj_t * pObj;
475     int i;
476 
477     fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) );
478     Abc_NtkForEachPi( pNtk, pObj, i )
479         fprintf( pFile, " %d=%s", i, Abc_ObjName(pObj) );
480 //        fprintf( pFile, " %s(%d)", Abc_ObjName(pObj), Abc_ObjFanoutNum(pObj) );
481     fprintf( pFile, "\n" );
482 
483     fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) );
484     Abc_NtkForEachPo( pNtk, pObj, i )
485         fprintf( pFile, " %d=%s", i, Abc_ObjName(pObj) );
486     fprintf( pFile, "\n" );
487 
488     if ( !fPrintFlops )
489         return;
490 
491     fprintf( pFile, "Latches (%d):  ", Abc_NtkLatchNum(pNtk) );
492     Abc_NtkForEachLatch( pNtk, pObj, i )
493         fprintf( pFile, " %s(%s=%s)", Abc_ObjName(pObj),
494             Abc_ObjName(Abc_ObjFanout0(pObj)), Abc_ObjName(Abc_ObjFanin0(pObj)) );
495     fprintf( pFile, "\n" );
496 }
497 
498 /**Function*************************************************************
499 
500   Synopsis    [Prints statistics about latches.]
501 
502   Description []
503 
504   SideEffects []
505 
506   SeeAlso     []
507 
508 ***********************************************************************/
Abc_NtkPrintLatch(FILE * pFile,Abc_Ntk_t * pNtk)509 void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
510 {
511     Abc_Obj_t * pLatch, * pFanin;
512     int i, Counter0, Counter1, Counter2;
513     int InitNums[4], Init;
514 
515     assert( !Abc_NtkIsNetlist(pNtk) );
516     if ( Abc_NtkLatchNum(pNtk) == 0 )
517     {
518         fprintf( pFile, "The network is combinational.\n" );
519         return;
520     }
521 
522     for ( i = 0; i < 4; i++ )
523         InitNums[i] = 0;
524     Counter0 = Counter1 = Counter2 = 0;
525     Abc_NtkForEachLatch( pNtk, pLatch, i )
526     {
527         Init = Abc_LatchInit( pLatch );
528         assert( Init < 4 );
529         InitNums[Init]++;
530 
531         pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
532         if ( Abc_NtkIsLogic(pNtk) )
533         {
534             if ( !Abc_NodeIsConst(pFanin) )
535                 continue;
536         }
537         else if ( Abc_NtkIsStrash(pNtk) )
538         {
539             if ( !Abc_AigNodeIsConst(pFanin) )
540                 continue;
541         }
542         else
543             assert( 0 );
544 
545         // the latch input is a constant node
546         Counter0++;
547         if ( Abc_LatchIsInitDc(pLatch) )
548         {
549             Counter1++;
550             continue;
551         }
552         // count the number of cases when the constant is equal to the initial value
553         if ( Abc_NtkIsStrash(pNtk) )
554         {
555             if ( Abc_LatchIsInit1(pLatch) == !Abc_ObjFaninC0(pLatch) )
556                 Counter2++;
557         }
558         else
559         {
560             if ( Abc_LatchIsInit1(pLatch) == Abc_NodeIsConst1(Abc_ObjFanin0(Abc_ObjFanin0(pLatch))) )
561                 Counter2++;
562         }
563     }
564 //    fprintf( pFile, "%-15s:  ", pNtk->pName );
565     fprintf( pFile, "Total latches = %5d. Init0 = %d. Init1 = %d. InitDC = %d. Const data = %d.\n",
566         Abc_NtkLatchNum(pNtk), InitNums[1], InitNums[2], InitNums[3], Counter0 );
567 //    fprintf( pFile, "Const fanin = %3d. DC init = %3d. Matching init = %3d. ", Counter0, Counter1, Counter2 );
568 //    fprintf( pFile, "Self-feed latches = %2d.\n", -1 ); //Abc_NtkCountSelfFeedLatches(pNtk) );
569 }
570 
571 /**Function*************************************************************
572 
573   Synopsis    [Prints the distribution of fanins/fanouts in the network.]
574 
575   Description []
576 
577   SideEffects []
578 
579   SeeAlso     []
580 
581 ***********************************************************************/
Abc_NtkFaninFanoutCounters(Abc_Ntk_t * pNtk,Vec_Int_t * vFan,Vec_Int_t * vFon,Vec_Int_t * vFanR,Vec_Int_t * vFonR)582 void Abc_NtkFaninFanoutCounters( Abc_Ntk_t * pNtk, Vec_Int_t * vFan, Vec_Int_t * vFon, Vec_Int_t * vFanR, Vec_Int_t * vFonR )
583 {
584     Abc_Obj_t * pNode;
585     int i, nFanins, nFanouts;
586     int nFaninsMax = 0, nFanoutsMax = 0;
587     Abc_NtkForEachObj( pNtk, pNode, i )
588     {
589         nFaninsMax  = Abc_MaxInt( nFaninsMax,  Abc_ObjFaninNum(pNode) );
590         nFanoutsMax = Abc_MaxInt( nFanoutsMax, Abc_ObjFanoutNum(pNode) );
591     }
592     Vec_IntFill( vFan, nFaninsMax + 1, 0 );
593     Vec_IntFill( vFon, nFanoutsMax + 1, 0 );
594     Vec_IntFill( vFanR, nFaninsMax + 1, 0 );
595     Vec_IntFill( vFonR, nFanoutsMax + 1, 0 );
596     Abc_NtkForEachObjReverse( pNtk, pNode, i )
597     {
598         nFanins  = Abc_ObjFaninNum( pNode );
599         nFanouts = Abc_ObjFanoutNum( pNode );
600         Vec_IntAddToEntry( vFan,  nFanins, 1 );
601         Vec_IntAddToEntry( vFon, nFanouts, 1 );
602         Vec_IntWriteEntry( vFanR, nFanins, i );
603         Vec_IntWriteEntry( vFonR, nFanouts, i );
604     }
605 }
Abc_NtkInputOutputCounters(Abc_Ntk_t * pNtk,Vec_Int_t * vFan,Vec_Int_t * vFon,Vec_Int_t * vFanR,Vec_Int_t * vFonR)606 void Abc_NtkInputOutputCounters( Abc_Ntk_t * pNtk, Vec_Int_t * vFan, Vec_Int_t * vFon, Vec_Int_t * vFanR, Vec_Int_t * vFonR )
607 {
608     Abc_Obj_t * pNode;
609     int i, nFanins, nFanouts;
610     int nFaninsMax = 0, nFanoutsMax = 0;
611     Abc_NtkForEachCi( pNtk, pNode, i )
612         nFanoutsMax = Abc_MaxInt( nFanoutsMax, Abc_ObjFanoutNum(pNode) );
613     Abc_NtkForEachCo( pNtk, pNode, i )
614         nFaninsMax  = Abc_MaxInt( nFaninsMax,  Abc_ObjFaninNum(Abc_ObjFanin0(pNode)) );
615     Vec_IntFill( vFan, nFaninsMax + 1, 0 );
616     Vec_IntFill( vFon, nFanoutsMax + 1, 0 );
617     Vec_IntFill( vFanR, nFaninsMax + 1, 0 );
618     Vec_IntFill( vFonR, nFanoutsMax + 1, 0 );
619     Abc_NtkForEachCi( pNtk, pNode, i )
620     {
621         nFanouts = Abc_ObjFanoutNum( pNode );
622         Vec_IntAddToEntry( vFon, nFanouts, 1 );
623         Vec_IntWriteEntry( vFonR, nFanouts, Abc_ObjId(pNode) );
624     }
625     Abc_NtkForEachCo( pNtk, pNode, i )
626     {
627         nFanins  = Abc_ObjFaninNum( Abc_ObjFanin0(pNode) );
628         Vec_IntAddToEntry( vFan,  nFanins, 1 );
629         Vec_IntWriteEntry( vFanR, nFanins, Abc_ObjId(pNode) );
630     }
631 }
Abc_NtkCollectCoSupps(Abc_Ntk_t * pNtk,int fVerbose)632 Vec_Int_t * Abc_NtkCollectCoSupps( Abc_Ntk_t * pNtk, int fVerbose )
633 {
634     abctime clk = Abc_Clock();
635     Abc_Obj_t * pNode; int i, k;
636     Vec_Ptr_t * vNodes = Abc_NtkDfs( pNtk, 0 );
637     Vec_Int_t * vFanin, * vFanout, * vTemp = Vec_IntAlloc( 0 );
638     Vec_Int_t * vSuppsCo = Vec_IntAlloc( Abc_NtkCoNum(pNtk) );
639     Vec_Wec_t * vSupps = Vec_WecStart( Abc_NtkObjNumMax(pNtk) );
640     Abc_NtkForEachCi( pNtk, pNode, i )
641         Vec_IntPush( Vec_WecEntry(vSupps, Abc_ObjId(pNode)), i );
642     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
643     {
644         vFanout = Vec_WecEntry(vSupps, Abc_ObjId(pNode));
645         for ( k = 0; k < Abc_ObjFaninNum(pNode); k++ )
646         {
647             vFanin = Vec_WecEntry(vSupps, Abc_ObjFaninId(pNode, k));
648             Vec_IntTwoMerge2( vFanout, vFanin, vTemp );
649             ABC_SWAP( Vec_Int_t, *vFanout, *vTemp );
650         }
651     }
652     Abc_NtkForEachCo( pNtk, pNode, i )
653         Vec_IntPush( vSuppsCo, Vec_IntSize(Vec_WecEntry(vSupps, Abc_ObjFaninId0(pNode))) );
654     Vec_WecFree( vSupps );
655     Vec_PtrFree( vNodes );
656     Vec_IntFree( vTemp );
657     if ( fVerbose )
658         Abc_PrintTime( 1, "Input  support computation", Abc_Clock() - clk );
659     //Vec_IntPrint( vSuppsCo );
660     return vSuppsCo;
661 }
Abc_NtkCollectCiSupps(Abc_Ntk_t * pNtk,int fVerbose)662 Vec_Int_t * Abc_NtkCollectCiSupps( Abc_Ntk_t * pNtk, int fVerbose )
663 {
664     abctime clk = Abc_Clock();
665     Abc_Obj_t * pNode; int i, k;
666     Vec_Ptr_t * vNodes = Abc_NtkDfs( pNtk, 0 );
667     Vec_Int_t * vFanin, * vFanout, * vTemp = Vec_IntAlloc( 0 );
668     Vec_Int_t * vSuppsCi = Vec_IntAlloc( Abc_NtkCiNum(pNtk) );
669     Vec_Wec_t * vSupps = Vec_WecStart( Abc_NtkObjNumMax(pNtk) );
670     Abc_NtkForEachCo( pNtk, pNode, i )
671     {
672         vFanout = Vec_WecEntry(vSupps, Abc_ObjId(pNode));
673         vFanin = Vec_WecEntry(vSupps, Abc_ObjFaninId0(pNode));
674         Vec_IntPush( vFanout, i );
675         Vec_IntTwoMerge2( vFanin, vFanout, vTemp );
676         ABC_SWAP( Vec_Int_t, *vFanin, *vTemp );
677     }
678     Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pNode, i )
679     {
680         vFanout = Vec_WecEntry(vSupps, Abc_ObjId(pNode));
681         for ( k = 0; k < Abc_ObjFaninNum(pNode); k++ )
682         {
683             vFanin = Vec_WecEntry(vSupps, Abc_ObjFaninId(pNode, k));
684             Vec_IntTwoMerge2( vFanin, vFanout, vTemp );
685             ABC_SWAP( Vec_Int_t, *vFanin, *vTemp );
686         }
687     }
688     Abc_NtkForEachCi( pNtk, pNode, i )
689         Vec_IntPush( vSuppsCi, Vec_IntSize(Vec_WecEntry(vSupps, Abc_ObjId(pNode))) );
690     Vec_WecFree( vSupps );
691     Vec_PtrFree( vNodes );
692     Vec_IntFree( vTemp );
693     if ( fVerbose )
694         Abc_PrintTime( 1, "Output support computation", Abc_Clock() - clk );
695     //Vec_IntPrint( vSuppsCi );
696     return vSuppsCi;
697 }
Abc_NtkInOutSupportCounters(Abc_Ntk_t * pNtk,Vec_Int_t * vFan,Vec_Int_t * vFon,Vec_Int_t * vFanR,Vec_Int_t * vFonR)698 void Abc_NtkInOutSupportCounters( Abc_Ntk_t * pNtk, Vec_Int_t * vFan, Vec_Int_t * vFon, Vec_Int_t * vFanR, Vec_Int_t * vFonR )
699 {
700     Abc_Obj_t * pNode;
701     Vec_Int_t * vSuppsCo = Abc_NtkCollectCoSupps( pNtk, 1 );
702     Vec_Int_t * vSuppsCi = Abc_NtkCollectCiSupps( pNtk, 1 );
703     int i, nFanins, nFanouts;
704     int nFaninsMax  = Vec_IntFindMax( vSuppsCo );
705     int nFanoutsMax = Vec_IntFindMax( vSuppsCi );
706     Vec_IntFill( vFan, nFaninsMax + 1, 0 );
707     Vec_IntFill( vFon, nFanoutsMax + 1, 0 );
708     Vec_IntFill( vFanR, nFaninsMax + 1, 0 );
709     Vec_IntFill( vFonR, nFanoutsMax + 1, 0 );
710     Abc_NtkForEachCo( pNtk, pNode, i )
711     {
712         nFanins  = Vec_IntEntry( vSuppsCo, i );
713         Vec_IntAddToEntry( vFan,  nFanins, 1 );
714         Vec_IntWriteEntry( vFanR, nFanins, Abc_ObjId(pNode) );
715     }
716     Abc_NtkForEachCi( pNtk, pNode, i )
717     {
718         nFanouts = Vec_IntEntry( vSuppsCi, i );
719         Vec_IntAddToEntry( vFon, nFanouts, 1 );
720         Vec_IntWriteEntry( vFonR, nFanouts, Abc_ObjId(pNode) );
721     }
722     Vec_IntFree( vSuppsCo );
723     Vec_IntFree( vSuppsCi );
724 }
725 
Abc_NtkCollectCoCones(Abc_Ntk_t * pNtk,int fVerbose)726 Vec_Int_t * Abc_NtkCollectCoCones( Abc_Ntk_t * pNtk, int fVerbose )
727 {
728     abctime clk = Abc_Clock();
729     Abc_Obj_t * pNode; int i, k;
730     Vec_Ptr_t * vNodes = Abc_NtkDfs( pNtk, 0 );
731     Vec_Int_t * vFanin, * vFanout, * vTemp = Vec_IntAlloc( 0 );
732     Vec_Int_t * vSuppsCo = Vec_IntAlloc( Abc_NtkCoNum(pNtk) );
733     Vec_Wec_t * vSupps = Vec_WecStart( Abc_NtkObjNumMax(pNtk) );
734     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
735     {
736         vFanout = Vec_WecEntry(vSupps, Abc_ObjId(pNode));
737         for ( k = 0; k < Abc_ObjFaninNum(pNode); k++ )
738         {
739             vFanin = Vec_WecEntry(vSupps, Abc_ObjFaninId(pNode, k));
740             Vec_IntTwoMerge2( vFanout, vFanin, vTemp );
741             ABC_SWAP( Vec_Int_t, *vFanout, *vTemp );
742         }
743         Vec_IntPush( vFanout, i );
744     }
745     Abc_NtkForEachCo( pNtk, pNode, i )
746         Vec_IntPush( vSuppsCo, Vec_IntSize(Vec_WecEntry(vSupps, Abc_ObjFaninId0(pNode))) );
747     Vec_WecFree( vSupps );
748     Vec_PtrFree( vNodes );
749     Vec_IntFree( vTemp );
750     if ( fVerbose )
751         Abc_PrintTime( 1, "Input  cone computation", Abc_Clock() - clk );
752     //Vec_IntPrint( vSuppsCo );
753     return vSuppsCo;
754 }
Abc_NtkCollectCiCones(Abc_Ntk_t * pNtk,int fVerbose)755 Vec_Int_t * Abc_NtkCollectCiCones( Abc_Ntk_t * pNtk, int fVerbose )
756 {
757     abctime clk = Abc_Clock();
758     Abc_Obj_t * pNode; int i, k;
759     Vec_Ptr_t * vNodes = Abc_NtkDfs( pNtk, 0 );
760     Vec_Int_t * vFanin, * vFanout, * vTemp = Vec_IntAlloc( 0 );
761     Vec_Int_t * vSuppsCi = Vec_IntAlloc( Abc_NtkCiNum(pNtk) );
762     Vec_Wec_t * vSupps = Vec_WecStart( Abc_NtkObjNumMax(pNtk) );
763     Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pNode, i )
764     {
765         vFanout = Vec_WecEntry(vSupps, Abc_ObjId(pNode));
766         Vec_IntPush( vFanout, i );
767         for ( k = 0; k < Abc_ObjFaninNum(pNode); k++ )
768         {
769             vFanin = Vec_WecEntry(vSupps, Abc_ObjFaninId(pNode, k));
770             Vec_IntTwoMerge2( vFanin, vFanout, vTemp );
771             ABC_SWAP( Vec_Int_t, *vFanin, *vTemp );
772         }
773     }
774     Abc_NtkForEachCi( pNtk, pNode, i )
775         Vec_IntPush( vSuppsCi, Vec_IntSize(Vec_WecEntry(vSupps, Abc_ObjId(pNode))) );
776     Vec_WecFree( vSupps );
777     Vec_PtrFree( vNodes );
778     Vec_IntFree( vTemp );
779     if ( fVerbose )
780         Abc_PrintTime( 1, "Output cone computation", Abc_Clock() - clk );
781     //Vec_IntPrint( vSuppsCi );
782     return vSuppsCi;
783 }
Abc_NtkInOutConeCounters(Abc_Ntk_t * pNtk,Vec_Int_t * vFan,Vec_Int_t * vFon,Vec_Int_t * vFanR,Vec_Int_t * vFonR)784 void Abc_NtkInOutConeCounters( Abc_Ntk_t * pNtk, Vec_Int_t * vFan, Vec_Int_t * vFon, Vec_Int_t * vFanR, Vec_Int_t * vFonR )
785 {
786     Abc_Obj_t * pNode;
787     Vec_Int_t * vSuppsCo = Abc_NtkCollectCoCones( pNtk, 1 );
788     Vec_Int_t * vSuppsCi = Abc_NtkCollectCiCones( pNtk, 1 );
789     int i, nFanins, nFanouts;
790     int nFaninsMax  = Vec_IntFindMax( vSuppsCo );
791     int nFanoutsMax = Vec_IntFindMax( vSuppsCi );
792     Vec_IntFill( vFan, nFaninsMax + 1, 0 );
793     Vec_IntFill( vFon, nFanoutsMax + 1, 0 );
794     Vec_IntFill( vFanR, nFaninsMax + 1, 0 );
795     Vec_IntFill( vFonR, nFanoutsMax + 1, 0 );
796     Abc_NtkForEachCo( pNtk, pNode, i )
797     {
798         nFanins  = Vec_IntEntry( vSuppsCo, i );
799         Vec_IntAddToEntry( vFan,  nFanins, 1 );
800         Vec_IntWriteEntry( vFanR, nFanins, Abc_ObjId(pNode) );
801     }
802     Abc_NtkForEachCi( pNtk, pNode, i )
803     {
804         nFanouts = Vec_IntEntry( vSuppsCi, i );
805         Vec_IntAddToEntry( vFon, nFanouts, 1 );
806         Vec_IntWriteEntry( vFonR, nFanouts, Abc_ObjId(pNode) );
807     }
808     Vec_IntFree( vSuppsCo );
809     Vec_IntFree( vSuppsCi );
810 }
811 
Abc_NtkPrintDistribInternal(FILE * pFile,Abc_Ntk_t * pNtk,char * pFanins,char * pFanouts,char * pNode,char * pFanin,char * pFanout,Vec_Int_t * vFan,Vec_Int_t * vFon,Vec_Int_t * vFanR,Vec_Int_t * vFonR)812 void Abc_NtkPrintDistribInternal( FILE * pFile, Abc_Ntk_t * pNtk, char * pFanins, char * pFanouts, char * pNode, char * pFanin, char * pFanout,
813                                  Vec_Int_t * vFan, Vec_Int_t * vFon, Vec_Int_t * vFanR, Vec_Int_t * vFonR )
814 {
815     int k, nSizeMax = Abc_MaxInt( Vec_IntSize(vFan), Vec_IntSize(vFon) );
816     fprintf( pFile, "The distribution of %s and %s in the network:\n", pFanins, pFanouts );
817     fprintf( pFile, "  Number   %s with %s  %s with %s          Repr1             Repr2\n", pNode, pFanin, pNode, pFanout );
818     for ( k = 0; k < nSizeMax; k++ )
819     {
820         int EntryFan = k < Vec_IntSize(vFan) ? Vec_IntEntry(vFan, k) : 0;
821         int EntryFon = k < Vec_IntSize(vFon) ? Vec_IntEntry(vFon, k) : 0;
822         if ( EntryFan == 0 && EntryFon == 0 )
823             continue;
824 
825         fprintf( pFile, "%5d : ", k );
826         if ( EntryFan == 0 )
827             fprintf( pFile, "              " );
828         else
829             fprintf( pFile, "%12d  ", EntryFan );
830         fprintf( pFile, "    " );
831         if ( EntryFon == 0 )
832             fprintf( pFile, "              " );
833         else
834             fprintf( pFile, "%12d  ", EntryFon );
835 
836         fprintf( pFile, "        " );
837         if ( EntryFan == 0 )
838             fprintf( pFile, "              " );
839         else
840             fprintf( pFile, "%12s  ", Abc_ObjName(Abc_NtkObj(pNtk, Vec_IntEntry(vFanR, k))) );
841         fprintf( pFile, "    " );
842         if ( EntryFon == 0 )
843             fprintf( pFile, "              " );
844         else
845             fprintf( pFile, "%12s  ", Abc_ObjName(Abc_NtkObj(pNtk, Vec_IntEntry(vFonR, k))) );
846         fprintf( pFile, "\n" );
847     }
848 }
Abc_NtkPrintFanio(FILE * pFile,Abc_Ntk_t * pNtk,int fUseFanio,int fUsePio,int fUseSupp,int fUseCone)849 void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk, int fUseFanio, int fUsePio, int fUseSupp, int fUseCone )
850 {
851     Vec_Int_t * vFan = Vec_IntAlloc( 0 );
852     Vec_Int_t * vFon = Vec_IntAlloc( 0 );
853     Vec_Int_t * vFanR = Vec_IntAlloc( 0 );
854     Vec_Int_t * vFonR = Vec_IntAlloc( 0 );
855     assert( fUseFanio + fUsePio + fUseSupp + fUseCone == 1 );
856     if ( fUseFanio )
857     {
858         Abc_NtkFaninFanoutCounters( pNtk, vFan, vFon, vFanR, vFonR );
859         Abc_NtkPrintDistribInternal( pFile, pNtk, "fanins", "fanouts", "Nodes", "fanin", "fanout", vFan, vFon, vFanR, vFonR );
860     }
861     else if ( fUsePio )
862     {
863         Abc_NtkInputOutputCounters( pNtk, vFan, vFon, vFanR, vFonR );
864         Abc_NtkPrintDistribInternal( pFile, pNtk, "fanins", "fanouts", "I/O", "fanin", "fanout", vFan, vFon, vFanR, vFonR );
865     }
866     else if ( fUseSupp )
867     {
868         Abc_NtkInOutSupportCounters( pNtk, vFan, vFon, vFanR, vFonR );
869         Abc_NtkPrintDistribInternal( pFile, pNtk, "input supports", "output supports", "I/O", "in-supp", "out-supp", vFan, vFon, vFanR, vFonR );
870     }
871     else if ( fUseCone )
872     {
873         Abc_NtkInOutConeCounters( pNtk, vFan, vFon, vFanR, vFonR );
874         Abc_NtkPrintDistribInternal( pFile, pNtk, "input cones", "output cones", "I/O", "in-cone", "out-cone", vFan, vFon, vFanR, vFonR );
875     }
876     Vec_IntFree( vFan );
877     Vec_IntFree( vFon );
878     Vec_IntFree( vFanR );
879     Vec_IntFree( vFonR );
880 }
881 
882 
883 /**Function*************************************************************
884 
885   Synopsis    [Prints the distribution of fanins/fanouts in the network.]
886 
887   Description []
888 
889   SideEffects []
890 
891   SeeAlso     []
892 
893 ***********************************************************************/
Abc_NtkPrintFanioNew(FILE * pFile,Abc_Ntk_t * pNtk,int fMffc)894 void Abc_NtkPrintFanioNew( FILE * pFile, Abc_Ntk_t * pNtk, int fMffc )
895 {
896     char Buffer[100];
897     Abc_Obj_t * pNode;
898     Vec_Int_t * vFanins, * vFanouts;
899     int nFanins, nFanouts, nFaninsMax, nFanoutsMax, nFaninsAll, nFanoutsAll;
900     int i, k, nSizeMax;
901 
902     // determine the largest fanin and fanout
903     nFaninsMax = nFanoutsMax = 0;
904     nFaninsAll = nFanoutsAll = 0;
905     Abc_NtkForEachNode( pNtk, pNode, i )
906     {
907         if ( fMffc && Abc_ObjFanoutNum(pNode) == 1 )
908             continue;
909         nFanins  = Abc_ObjFaninNum(pNode);
910         if ( Abc_NtkIsNetlist(pNtk) )
911             nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) );
912         else if ( fMffc )
913             nFanouts = Abc_NodeMffcSize(pNode);
914         else
915             nFanouts = Abc_ObjFanoutNum(pNode);
916         nFaninsAll  += nFanins;
917         nFanoutsAll += nFanouts;
918         nFaninsMax   = Abc_MaxInt( nFaninsMax, nFanins );
919         nFanoutsMax  = Abc_MaxInt( nFanoutsMax, nFanouts );
920     }
921 
922     // allocate storage for fanin/fanout numbers
923     nSizeMax = Abc_MaxInt( 10 * (Abc_Base10Log(nFaninsMax) + 1), 10 * (Abc_Base10Log(nFanoutsMax) + 1) );
924     vFanins  = Vec_IntStart( nSizeMax );
925     vFanouts = Vec_IntStart( nSizeMax );
926 
927     // count the number of fanins and fanouts
928     Abc_NtkForEachNode( pNtk, pNode, i )
929     {
930         if ( fMffc && Abc_ObjFanoutNum(pNode) == 1 )
931             continue;
932         nFanins  = Abc_ObjFaninNum(pNode);
933         if ( Abc_NtkIsNetlist(pNtk) )
934             nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) );
935         else if ( fMffc )
936             nFanouts = Abc_NodeMffcSize(pNode);
937         else
938             nFanouts = Abc_ObjFanoutNum(pNode);
939 
940         if ( nFanins < 10 )
941             Vec_IntAddToEntry( vFanins, nFanins, 1 );
942         else if ( nFanins < 100 )
943             Vec_IntAddToEntry( vFanins, 10 + nFanins/10, 1 );
944         else if ( nFanins < 1000 )
945             Vec_IntAddToEntry( vFanins, 20 + nFanins/100, 1 );
946         else if ( nFanins < 10000 )
947             Vec_IntAddToEntry( vFanins, 30 + nFanins/1000, 1 );
948         else if ( nFanins < 100000 )
949             Vec_IntAddToEntry( vFanins, 40 + nFanins/10000, 1 );
950         else if ( nFanins < 1000000 )
951             Vec_IntAddToEntry( vFanins, 50 + nFanins/100000, 1 );
952         else if ( nFanins < 10000000 )
953             Vec_IntAddToEntry( vFanins, 60 + nFanins/1000000, 1 );
954 
955         if ( nFanouts < 10 )
956             Vec_IntAddToEntry( vFanouts, nFanouts, 1 );
957         else if ( nFanouts < 100 )
958             Vec_IntAddToEntry( vFanouts, 10 + nFanouts/10, 1 );
959         else if ( nFanouts < 1000 )
960             Vec_IntAddToEntry( vFanouts, 20 + nFanouts/100, 1 );
961         else if ( nFanouts < 10000 )
962             Vec_IntAddToEntry( vFanouts, 30 + nFanouts/1000, 1 );
963         else if ( nFanouts < 100000 )
964             Vec_IntAddToEntry( vFanouts, 40 + nFanouts/10000, 1 );
965         else if ( nFanouts < 1000000 )
966             Vec_IntAddToEntry( vFanouts, 50 + nFanouts/100000, 1 );
967         else if ( nFanouts < 10000000 )
968             Vec_IntAddToEntry( vFanouts, 60 + nFanouts/1000000, 1 );
969     }
970 
971     fprintf( pFile, "The distribution of fanins and fanouts in the network:\n" );
972     fprintf( pFile, "         Number   Nodes with fanin  Nodes with fanout\n" );
973     for ( k = 0; k < nSizeMax; k++ )
974     {
975         if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 )
976             continue;
977         if ( k < 10 )
978             fprintf( pFile, "%15d : ", k );
979         else
980         {
981             sprintf( Buffer, "%d - %d", (int)pow((double)10, k/10) * (k%10), (int)pow((double)10, k/10) * (k%10+1) - 1 );
982             fprintf( pFile, "%15s : ", Buffer );
983         }
984         if ( vFanins->pArray[k] == 0 )
985             fprintf( pFile, "              " );
986         else
987             fprintf( pFile, "%12d  ", vFanins->pArray[k] );
988         fprintf( pFile, "    " );
989         if ( vFanouts->pArray[k] == 0 )
990             fprintf( pFile, "              " );
991         else
992             fprintf( pFile, "%12d  ", vFanouts->pArray[k] );
993         fprintf( pFile, "\n" );
994     }
995     Vec_IntFree( vFanins );
996     Vec_IntFree( vFanouts );
997 
998     fprintf( pFile, "Fanins: Max = %d. Ave = %.2f.  Fanouts: Max = %d. Ave =  %.2f.\n",
999         nFaninsMax,  1.0*nFaninsAll/Abc_NtkNodeNum(pNtk),
1000         nFanoutsMax, 1.0*nFanoutsAll/Abc_NtkNodeNum(pNtk)  );
1001 /*
1002     Abc_NtkForEachCi( pNtk, pNode, i )
1003     {
1004         printf( "%d ", Abc_ObjFanoutNum(pNode) );
1005     }
1006     printf( "\n" );
1007 */
1008 }
1009 
1010 /**Function*************************************************************
1011 
1012   Synopsis    [Prints the fanins/fanouts of a node.]
1013 
1014   Description []
1015 
1016   SideEffects []
1017 
1018   SeeAlso     []
1019 
1020 ***********************************************************************/
Abc_NodePrintFanio(FILE * pFile,Abc_Obj_t * pNode)1021 void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode )
1022 {
1023     Abc_Obj_t * pNode2;
1024     int i;
1025     if ( Abc_ObjIsPo(pNode) )
1026         pNode = Abc_ObjFanin0(pNode);
1027 
1028     fprintf( pFile, "Node %s", Abc_ObjName(pNode) );
1029     fprintf( pFile, "\n" );
1030 
1031     fprintf( pFile, "Fanins (%d): ", Abc_ObjFaninNum(pNode) );
1032     Abc_ObjForEachFanin( pNode, pNode2, i )
1033         fprintf( pFile, " %s", Abc_ObjName(pNode2) );
1034     fprintf( pFile, "\n" );
1035 
1036     fprintf( pFile, "Fanouts (%d): ", Abc_ObjFaninNum(pNode) );
1037     Abc_ObjForEachFanout( pNode, pNode2, i )
1038         fprintf( pFile, " %s", Abc_ObjName(pNode2) );
1039     fprintf( pFile, "\n" );
1040 }
1041 
1042 /**Function*************************************************************
1043 
1044   Synopsis    [Prints the MFFCs of the nodes.]
1045 
1046   Description []
1047 
1048   SideEffects []
1049 
1050   SeeAlso     []
1051 
1052 ***********************************************************************/
Abc_NtkPrintMffc(FILE * pFile,Abc_Ntk_t * pNtk)1053 void Abc_NtkPrintMffc( FILE * pFile, Abc_Ntk_t * pNtk )
1054 {
1055     Abc_Obj_t * pNode;
1056     int i;
1057     extern void Abc_NodeMffcConeSuppPrint( Abc_Obj_t * pNode );
1058     Abc_NtkForEachNode( pNtk, pNode, i )
1059         if ( Abc_ObjFanoutNum(pNode) > 1 )
1060             Abc_NodeMffcConeSuppPrint( pNode );
1061 }
1062 
1063 /**Function*************************************************************
1064 
1065   Synopsis    [Prints the factored form of one node.]
1066 
1067   Description []
1068 
1069   SideEffects []
1070 
1071   SeeAlso     []
1072 
1073 ***********************************************************************/
Abc_NtkPrintFactor(FILE * pFile,Abc_Ntk_t * pNtk,int fUseRealNames)1074 void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames )
1075 {
1076     Abc_Obj_t * pNode;
1077     int i;
1078     assert( Abc_NtkIsSopLogic(pNtk) );
1079     Abc_NtkForEachNode( pNtk, pNode, i )
1080         Abc_NodePrintFactor( pFile, pNode, fUseRealNames );
1081 }
1082 
1083 /**Function*************************************************************
1084 
1085   Synopsis    [Prints the factored form of one node.]
1086 
1087   Description []
1088 
1089   SideEffects []
1090 
1091   SeeAlso     []
1092 
1093 ***********************************************************************/
Abc_NodePrintFactor(FILE * pFile,Abc_Obj_t * pNode,int fUseRealNames)1094 void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames )
1095 {
1096     Dec_Graph_t * pGraph;
1097     Vec_Ptr_t * vNamesIn;
1098     if ( Abc_ObjIsCo(pNode) )
1099         pNode = Abc_ObjFanin0(pNode);
1100     if ( Abc_ObjIsPi(pNode) )
1101     {
1102         fprintf( pFile, "Skipping the PI node.\n" );
1103         return;
1104     }
1105     if ( Abc_ObjIsLatch(pNode) )
1106     {
1107         fprintf( pFile, "Skipping the latch.\n" );
1108         return;
1109     }
1110     assert( Abc_ObjIsNode(pNode) );
1111     pGraph = Dec_Factor( (char *)pNode->pData );
1112     if ( fUseRealNames )
1113     {
1114         vNamesIn = Abc_NodeGetFaninNames(pNode);
1115         Dec_GraphPrint( stdout, pGraph, (char **)vNamesIn->pArray, Abc_ObjName(pNode) );
1116         Abc_NodeFreeNames( vNamesIn );
1117     }
1118     else
1119         Dec_GraphPrint( stdout, pGraph, (char **)NULL, Abc_ObjName(pNode) );
1120     Dec_GraphFree( pGraph );
1121 }
1122 
1123 
1124 /**Function*************************************************************
1125 
1126   Synopsis    [Prints the level stats of the PO node.]
1127 
1128   Description []
1129 
1130   SideEffects []
1131 
1132   SeeAlso     []
1133 
1134 ***********************************************************************/
Abc_NtkPrintLevel(FILE * pFile,Abc_Ntk_t * pNtk,int fProfile,int fListNodes,int fVerbose)1135 void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes, int fVerbose )
1136 {
1137     Abc_Obj_t * pNode;
1138     int i, k, Length;
1139 
1140     if ( fListNodes )
1141     {
1142         int nLevels;
1143         nLevels = Abc_NtkLevel(pNtk);
1144         printf( "Nodes by level:\n" );
1145         for ( i = 0; i <= nLevels; i++ )
1146         {
1147             printf( "%2d : ", i );
1148             Abc_NtkForEachNode( pNtk, pNode, k )
1149                 if ( (int)pNode->Level == i )
1150                     printf( " %s", Abc_ObjName(pNode) );
1151             printf( "\n" );
1152         }
1153         return;
1154     }
1155 
1156     // print the delay profile
1157     if ( fProfile && Abc_NtkHasMapping(pNtk) )
1158     {
1159         int nIntervals = 12;
1160         float DelayMax, DelayCur, DelayDelta;
1161         int * pLevelCounts;
1162         int DelayInt, nOutsSum, nOutsTotal;
1163 
1164         // get the max delay and delta
1165         DelayMax   = Abc_NtkDelayTrace( pNtk, NULL, NULL, 0 );
1166         DelayDelta = DelayMax/nIntervals;
1167         // collect outputs by delay
1168         pLevelCounts = ABC_ALLOC( int, nIntervals );
1169         memset( pLevelCounts, 0, sizeof(int) * nIntervals );
1170         Abc_NtkForEachCo( pNtk, pNode, i )
1171         {
1172             if ( Abc_ObjIsNode(Abc_ObjFanin0(pNode)) && Abc_ObjFaninNum(Abc_ObjFanin0(pNode)) == 0 )
1173                 DelayInt = 0;
1174             else
1175             {
1176                 DelayCur  = Abc_NodeReadArrivalWorst( Abc_ObjFanin0(pNode) );
1177                 DelayInt  = (int)(DelayCur / DelayDelta);
1178                 if ( DelayInt >= nIntervals )
1179                     DelayInt = nIntervals - 1;
1180             }
1181             pLevelCounts[DelayInt]++;
1182         }
1183 
1184         nOutsSum   = 0;
1185         nOutsTotal = Abc_NtkCoNum(pNtk);
1186         for ( i = 0; i < nIntervals; i++ )
1187         {
1188             nOutsSum += pLevelCounts[i];
1189             printf( "[%8.2f - %8.2f] :   COs = %4d.   %5.1f %%\n",
1190                 DelayDelta * i, DelayDelta * (i+1), pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal );
1191         }
1192         ABC_FREE( pLevelCounts );
1193         return;
1194     }
1195     else if ( fProfile )
1196     {
1197         int LevelMax, * pLevelCounts;
1198         int nOutsSum, nOutsTotal;
1199 
1200         if ( !Abc_NtkIsStrash(pNtk) )
1201             Abc_NtkLevel(pNtk);
1202 
1203         LevelMax = 0;
1204         Abc_NtkForEachCo( pNtk, pNode, i )
1205             if ( LevelMax < (int)Abc_ObjFanin0(pNode)->Level )
1206                 LevelMax = Abc_ObjFanin0(pNode)->Level;
1207         pLevelCounts = ABC_ALLOC( int, LevelMax + 1 );
1208         memset( pLevelCounts, 0, sizeof(int) * (LevelMax + 1) );
1209         Abc_NtkForEachCo( pNtk, pNode, i )
1210             pLevelCounts[Abc_ObjFanin0(pNode)->Level]++;
1211 
1212         nOutsSum   = 0;
1213         nOutsTotal = Abc_NtkCoNum(pNtk);
1214         for ( i = 0; i <= LevelMax; i++ )
1215             if ( pLevelCounts[i] )
1216             {
1217                 nOutsSum += pLevelCounts[i];
1218                 printf( "Level = %4d.  COs = %4d.   %5.1f %%\n", i, pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal );
1219             }
1220         ABC_FREE( pLevelCounts );
1221         return;
1222     }
1223     assert( Abc_NtkIsStrash(pNtk) );
1224 
1225     if ( fVerbose )
1226     {
1227         // find the longest name
1228         Length = 0;
1229         Abc_NtkForEachCo( pNtk, pNode, i )
1230             if ( Length < (int)strlen(Abc_ObjName(pNode)) )
1231                 Length = strlen(Abc_ObjName(pNode));
1232         if ( Length < 5 )
1233             Length = 5;
1234         // print stats for each output
1235         Abc_NtkForEachCo( pNtk, pNode, i )
1236         {
1237             fprintf( pFile, "CO %4d :  %*s    ", i, Length, Abc_ObjName(pNode) );
1238             Abc_NodePrintLevel( pFile, pNode );
1239     }
1240     }
1241 }
1242 
1243 /**Function*************************************************************
1244 
1245   Synopsis    [Prints the factored form of one node.]
1246 
1247   Description []
1248 
1249   SideEffects []
1250 
1251   SeeAlso     []
1252 
1253 ***********************************************************************/
Abc_NodePrintLevel(FILE * pFile,Abc_Obj_t * pNode)1254 void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode )
1255 {
1256     Abc_Obj_t * pDriver;
1257     Vec_Ptr_t * vNodes;
1258 
1259     pDriver = Abc_ObjIsCo(pNode)? Abc_ObjFanin0(pNode) : pNode;
1260     if ( Abc_ObjIsPi(pDriver) )
1261     {
1262         fprintf( pFile, "Primary input.\n" );
1263         return;
1264     }
1265     if ( Abc_ObjIsLatch(pDriver) )
1266     {
1267         fprintf( pFile, "Latch.\n" );
1268         return;
1269     }
1270     if ( Abc_NodeIsConst(pDriver) )
1271     {
1272         fprintf( pFile, "Constant %d.\n", !Abc_ObjFaninC0(pNode) );
1273         return;
1274     }
1275     // print the level
1276     fprintf( pFile, "Level = %3d.  ", pDriver->Level );
1277     // print the size of MFFC
1278     fprintf( pFile, "Mffc = %5d.  ", Abc_NodeMffcSize(pDriver) );
1279     // print the size of the shole cone
1280     vNodes = Abc_NtkDfsNodes( pNode->pNtk, &pDriver, 1 );
1281     fprintf( pFile, "Cone = %5d.  ", Vec_PtrSize(vNodes) );
1282     Vec_PtrFree( vNodes );
1283     fprintf( pFile, "\n" );
1284 }
1285 
1286 /**Function*************************************************************
1287 
1288   Synopsis    [Prints the factored form of one node.]
1289 
1290   Description []
1291 
1292   SideEffects []
1293 
1294   SeeAlso     []
1295 
1296 ***********************************************************************/
Abc_NodePrintKMap(Abc_Obj_t * pNode,int fUseRealNames)1297 void Abc_NodePrintKMap( Abc_Obj_t * pNode, int fUseRealNames )
1298 {
1299 #ifdef ABC_USE_CUDD
1300     Vec_Ptr_t * vNamesIn;
1301     if ( fUseRealNames )
1302     {
1303         vNamesIn = Abc_NodeGetFaninNames(pNode);
1304         Extra_PrintKMap( stdout, (DdManager *)pNode->pNtk->pManFunc, (DdNode *)pNode->pData, Cudd_Not(pNode->pData),
1305             Abc_ObjFaninNum(pNode), NULL, 0, (char **)vNamesIn->pArray );
1306         Abc_NodeFreeNames( vNamesIn );
1307     }
1308     else
1309         Extra_PrintKMap( stdout, (DdManager *)pNode->pNtk->pManFunc, (DdNode *)pNode->pData, Cudd_Not(pNode->pData),
1310             Abc_ObjFaninNum(pNode), NULL, 0, NULL );
1311 #endif
1312 }
1313 
1314 /**Function*************************************************************
1315 
1316   Synopsis    [Prints statistics about gates used in the network.]
1317 
1318   Description []
1319 
1320   SideEffects []
1321 
1322   SeeAlso     []
1323 
1324 ***********************************************************************/
Abc_NtkPrintGates(Abc_Ntk_t * pNtk,int fUseLibrary,int fUpdateProfile)1325 void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary, int fUpdateProfile )
1326 {
1327     Abc_Obj_t * pObj;
1328     int fHasBdds, i;
1329     int CountConst, CountBuf, CountInv, CountAnd, CountOr, CountOther, CounterTotal, TotalDiff = 0;
1330     char * pSop;
1331 
1332     if ( fUseLibrary && Abc_NtkHasMapping(pNtk) )
1333     {
1334         Mio_Gate_t ** ppGates;
1335         double Area, AreaTotal;
1336         int Counter, nGates, i, nGateNameLen;
1337 
1338         // clean value of all gates
1339         nGates = Mio_LibraryReadGateNum( (Mio_Library_t *)pNtk->pManFunc );
1340         ppGates = Mio_LibraryReadGateArray( (Mio_Library_t *)pNtk->pManFunc );
1341         for ( i = 0; i < nGates; i++ )
1342         {
1343             Mio_GateSetValue( ppGates[i], 0 );
1344             if ( fUpdateProfile )
1345                 Mio_GateSetProfile2( ppGates[i], 0 );
1346         }
1347 
1348         // count the gates by name
1349         CounterTotal = 0;
1350         Abc_NtkForEachNodeNotBarBuf( pNtk, pObj, i )
1351         {
1352             if ( i == 0 ) continue;
1353             Mio_GateSetValue( (Mio_Gate_t *)pObj->pData, 1 + Mio_GateReadValue((Mio_Gate_t *)pObj->pData) );
1354             if ( fUpdateProfile )
1355                 Mio_GateIncProfile2( (Mio_Gate_t *)pObj->pData );
1356             CounterTotal++;
1357             // assuming that twin gates follow each other
1358             if ( Abc_NtkFetchTwinNode(pObj) )
1359                 i++;
1360         }
1361 
1362         // determine the longest gate name
1363         nGateNameLen = 5;
1364         for ( i = 0; i < nGates; i++ )
1365         {
1366             Counter = Mio_GateReadValue( ppGates[i] );
1367             if ( Counter == 0 )
1368                 continue;
1369             nGateNameLen = Abc_MaxInt( nGateNameLen, strlen(Mio_GateReadName(ppGates[i])) );
1370         }
1371 
1372         // print the gates
1373         AreaTotal = Abc_NtkGetMappedArea(pNtk);
1374         for ( i = 0; i < nGates; i++ )
1375         {
1376             Counter = Mio_GateReadValue( ppGates[i] );
1377             if ( Counter == 0 && Mio_GateReadProfile(ppGates[i]) == 0 )
1378                 continue;
1379             if ( Mio_GateReadPinNum(ppGates[i]) > 1 )
1380                 TotalDiff += Abc_AbsInt( Mio_GateReadProfile(ppGates[i]) - Mio_GateReadProfile2(ppGates[i]) );
1381             Area = Counter * Mio_GateReadArea( ppGates[i] );
1382             printf( "%-*s   Fanin = %2d   Instance = %8d   Area = %10.2f   %6.2f %%   %8d  %8d   %s\n",
1383                 nGateNameLen, Mio_GateReadName( ppGates[i] ),
1384                 Mio_GateReadPinNum( ppGates[i] ),
1385                 Counter, Area, 100.0 * Area / AreaTotal,
1386                 Mio_GateReadProfile(ppGates[i]),
1387                 Mio_GateReadProfile2(ppGates[i]),
1388                 Mio_GateReadForm(ppGates[i]) );
1389         }
1390         printf( "%-*s                Instance = %8d   Area = %10.2f   %6.2f %%   AbsDiff = %d\n",
1391             nGateNameLen, "TOTAL",
1392             CounterTotal, AreaTotal, 100.0, TotalDiff );
1393         return;
1394     }
1395 
1396     if ( Abc_NtkIsAigLogic(pNtk) )
1397         return;
1398 
1399     // transform logic functions from BDD to SOP
1400     if ( (fHasBdds = Abc_NtkIsBddLogic(pNtk)) )
1401     {
1402         if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
1403         {
1404             printf( "Abc_NtkPrintGates(): Converting to SOPs has failed.\n" );
1405             return;
1406         }
1407     }
1408 
1409     // get hold of the SOP of the node
1410     CountConst = CountBuf = CountInv = CountAnd = CountOr = CountOther = CounterTotal = 0;
1411     Abc_NtkForEachNodeNotBarBuf( pNtk, pObj, i )
1412     {
1413         if ( i == 0 ) continue;
1414         if ( Abc_NtkHasMapping(pNtk) )
1415             pSop = Mio_GateReadSop((Mio_Gate_t *)pObj->pData);
1416         else
1417             pSop = (char *)pObj->pData;
1418         // collect the stats
1419         if ( Abc_SopIsConst0(pSop) || Abc_SopIsConst1(pSop) )
1420             CountConst++;
1421         else if ( Abc_SopIsBuf(pSop) )
1422             CountBuf++;
1423         else if ( Abc_SopIsInv(pSop) )
1424             CountInv++;
1425         else if ( (!Abc_SopIsComplement(pSop) && Abc_SopIsAndType(pSop)) ||
1426                   ( Abc_SopIsComplement(pSop) && Abc_SopIsOrType(pSop)) )
1427             CountAnd++;
1428         else if ( ( Abc_SopIsComplement(pSop) && Abc_SopIsAndType(pSop)) ||
1429                   (!Abc_SopIsComplement(pSop) && Abc_SopIsOrType(pSop)) )
1430             CountOr++;
1431         else
1432             CountOther++;
1433         CounterTotal++;
1434     }
1435     printf( "Const        = %8d    %6.2f %%\n", CountConst  ,  100.0 * CountConst   / CounterTotal );
1436     printf( "Buffer       = %8d    %6.2f %%\n", CountBuf    ,  100.0 * CountBuf     / CounterTotal );
1437     printf( "Inverter     = %8d    %6.2f %%\n", CountInv    ,  100.0 * CountInv     / CounterTotal );
1438     printf( "And          = %8d    %6.2f %%\n", CountAnd    ,  100.0 * CountAnd     / CounterTotal );
1439     printf( "Or           = %8d    %6.2f %%\n", CountOr     ,  100.0 * CountOr      / CounterTotal );
1440     printf( "Other        = %8d    %6.2f %%\n", CountOther  ,  100.0 * CountOther   / CounterTotal );
1441     printf( "TOTAL        = %8d    %6.2f %%\n", CounterTotal,  100.0 * CounterTotal / CounterTotal );
1442 
1443     // convert the network back into BDDs if this is how it was
1444     if ( fHasBdds )
1445         Abc_NtkSopToBdd(pNtk);
1446 }
1447 
1448 /**Function*************************************************************
1449 
1450   Synopsis    [Prints statistics about gates used in the network.]
1451 
1452   Description []
1453 
1454   SideEffects []
1455 
1456   SeeAlso     []
1457 
1458 ***********************************************************************/
Abc_NtkPrintSharing(Abc_Ntk_t * pNtk)1459 void Abc_NtkPrintSharing( Abc_Ntk_t * pNtk )
1460 {
1461     Vec_Ptr_t * vNodes1, * vNodes2;
1462     Abc_Obj_t * pObj1, * pObj2, * pNode1, * pNode2;
1463     int i, k, m, n, Counter;
1464 
1465     // print the template
1466     printf( "Statistics about sharing of logic nodes among the CO pairs.\n" );
1467     printf( "(CO1,CO2)=NumShared : " );
1468     // go though the CO pairs
1469     Abc_NtkForEachCo( pNtk, pObj1, i )
1470     {
1471         vNodes1 = Abc_NtkDfsNodes( pNtk, &pObj1, 1 );
1472         // mark the nodes
1473         Vec_PtrForEachEntry( Abc_Obj_t *, vNodes1, pNode1, m )
1474             pNode1->fMarkA = 1;
1475         // go through the second COs
1476         Abc_NtkForEachCo( pNtk, pObj2, k )
1477         {
1478             if ( i >= k )
1479                 continue;
1480             vNodes2 = Abc_NtkDfsNodes( pNtk, &pObj2, 1 );
1481             // count the number of marked
1482             Counter = 0;
1483             Vec_PtrForEachEntry( Abc_Obj_t *, vNodes2, pNode2, n )
1484                 Counter += pNode2->fMarkA;
1485             // print
1486             printf( "(%d,%d)=%d ", i, k, Counter );
1487             Vec_PtrFree( vNodes2 );
1488         }
1489         // unmark the nodes
1490         Vec_PtrForEachEntry( Abc_Obj_t *, vNodes1, pNode1, m )
1491             pNode1->fMarkA = 0;
1492         Vec_PtrFree( vNodes1 );
1493     }
1494     printf( "\n" );
1495 }
1496 
1497 /**Function*************************************************************
1498 
1499   Synopsis    [Prints info for each output cone.]
1500 
1501   Description []
1502 
1503   SideEffects []
1504 
1505   SeeAlso     []
1506 
1507 ***********************************************************************/
Abc_NtkCountPis(Vec_Ptr_t * vSupp)1508 int Abc_NtkCountPis( Vec_Ptr_t * vSupp )
1509 {
1510     Abc_Obj_t * pObj;
1511     int i, Counter = 0;
1512     Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, i )
1513         Counter += Abc_ObjIsPi(pObj);
1514     return Counter;
1515 }
Abc_NtkPrintStrSupports(Abc_Ntk_t * pNtk,int fMatrix)1516 void Abc_NtkPrintStrSupports( Abc_Ntk_t * pNtk, int fMatrix )
1517 {
1518     Vec_Ptr_t * vSupp, * vNodes;
1519     Abc_Obj_t * pObj;
1520     int i, k, nPis;
1521     printf( "Structural support info:\n" );
1522     Abc_NtkForEachCo( pNtk, pObj, i )
1523     {
1524         vSupp  = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
1525         vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 );
1526         nPis   = Abc_NtkCountPis( vSupp );
1527         printf( "%5d  %20s :  Cone = %5d.  Supp = %5d. (PIs = %5d. FFs = %5d.)\n",
1528             i, Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize, nPis, vSupp->nSize - nPis );
1529         Vec_PtrFree( vNodes );
1530         Vec_PtrFree( vSupp );
1531     }
1532     if ( !fMatrix )
1533     {
1534         Abc_NtkCleanMarkA( pNtk );
1535         return;
1536     }
1537 
1538     Abc_NtkForEachCi( pNtk, pObj, k )
1539         pObj->fMarkA = 0;
1540 
1541     printf( "Actual support info:\n" );
1542     Abc_NtkForEachCo( pNtk, pObj, i )
1543     {
1544         vSupp  = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
1545         Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, k )
1546             pObj->fMarkA = 1;
1547         Vec_PtrFree( vSupp );
1548 
1549         Abc_NtkForEachCi( pNtk, pObj, k )
1550             printf( "%d", pObj->fMarkA );
1551         printf( "\n" );
1552 
1553         Abc_NtkForEachCi( pNtk, pObj, k )
1554             pObj->fMarkA = 0;
1555     }
1556     Abc_NtkCleanMarkA( pNtk );
1557 }
1558 
1559 /**Function*************************************************************
1560 
1561   Synopsis    [Prints information about the object.]
1562 
1563   Description []
1564 
1565   SideEffects []
1566 
1567   SeeAlso     []
1568 
1569 ***********************************************************************/
Abc_ObjPrint(FILE * pFile,Abc_Obj_t * pObj)1570 void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj )
1571 {
1572     Abc_Obj_t * pFanin;
1573     int i;
1574     fprintf( pFile, "Object %5d : ", pObj->Id );
1575     switch ( pObj->Type )
1576     {
1577         case ABC_OBJ_NONE:
1578             fprintf( pFile, "NONE   " );
1579             break;
1580         case ABC_OBJ_CONST1:
1581             fprintf( pFile, "Const1 " );
1582             break;
1583         case ABC_OBJ_PI:
1584             fprintf( pFile, "PI     " );
1585             break;
1586         case ABC_OBJ_PO:
1587             fprintf( pFile, "PO     " );
1588             break;
1589         case ABC_OBJ_BI:
1590             fprintf( pFile, "BI     " );
1591             break;
1592         case ABC_OBJ_BO:
1593             fprintf( pFile, "BO     " );
1594             break;
1595         case ABC_OBJ_NET:
1596             fprintf( pFile, "Net    " );
1597             break;
1598         case ABC_OBJ_NODE:
1599             fprintf( pFile, "Node   " );
1600             break;
1601         case ABC_OBJ_LATCH:
1602             fprintf( pFile, "Latch  " );
1603             break;
1604         case ABC_OBJ_WHITEBOX:
1605             fprintf( pFile, "Whitebox" );
1606             break;
1607         case ABC_OBJ_BLACKBOX:
1608             fprintf( pFile, "Blackbox" );
1609             break;
1610         default:
1611             assert(0);
1612             break;
1613     }
1614     // print the fanins
1615     fprintf( pFile, " Fanins ( " );
1616     Abc_ObjForEachFanin( pObj, pFanin, i )
1617         fprintf( pFile, "%d ", pFanin->Id );
1618     fprintf( pFile, ") " );
1619 /*
1620     fprintf( pFile, " Fanouts ( " );
1621     Abc_ObjForEachFanout( pObj, pFanin, i )
1622         fprintf( pFile, "%d(%c) ", pFanin->Id, Abc_NodeIsTravIdCurrent(pFanin)? '+' : '-' );
1623     fprintf( pFile, ") " );
1624 */
1625     // print the logic function
1626     if ( Abc_ObjIsNode(pObj) && Abc_NtkIsSopLogic(pObj->pNtk) )
1627         fprintf( pFile, " %s", (char*)pObj->pData );
1628     else if ( Abc_ObjIsNode(pObj) && Abc_NtkIsMappedLogic(pObj->pNtk) )
1629         fprintf( pFile, " %s\n", Mio_GateReadName((Mio_Gate_t *)pObj->pData) );
1630     else
1631         fprintf( pFile, "\n" );
1632 }
1633 
1634 
1635 /**Function*************************************************************
1636 
1637   Synopsis    [Checks the status of the miter.]
1638 
1639   Description []
1640 
1641   SideEffects []
1642 
1643   SeeAlso     []
1644 
1645 ***********************************************************************/
Abc_NtkPrintMiter(Abc_Ntk_t * pNtk)1646 void Abc_NtkPrintMiter( Abc_Ntk_t * pNtk )
1647 {
1648     Abc_Obj_t * pObj, * pChild, * pConst1 = Abc_AigConst1(pNtk);
1649     int i, iOut = -1;
1650     abctime Time = Abc_Clock();
1651     int nUnsat = 0;
1652     int nSat   = 0;
1653     int nUndec = 0;
1654     int nPis   = 0;
1655     Abc_NtkForEachPi( pNtk, pObj, i )
1656         nPis += (int)( Abc_ObjFanoutNum(pObj) > 0 );
1657     Abc_NtkForEachPo( pNtk, pObj, i )
1658     {
1659         pChild = Abc_ObjChild0(pObj);
1660         // check if the output is constant 0
1661         if ( pChild == Abc_ObjNot(pConst1) )
1662             nUnsat++;
1663         // check if the output is constant 1
1664         else if ( pChild == pConst1 )
1665         {
1666             nSat++;
1667             if ( iOut == -1 )
1668                 iOut = i;
1669         }
1670         // check if the output is a primary input
1671         else if ( Abc_ObjIsPi(Abc_ObjRegular(pChild)) )
1672         {
1673             nSat++;
1674             if ( iOut == -1 )
1675                 iOut = i;
1676         }
1677     // check if the output is 1 for the 0000 pattern
1678         else if ( Abc_ObjRegular(pChild)->fPhase != (unsigned)Abc_ObjIsComplement(pChild) )
1679         {
1680             nSat++;
1681             if ( iOut == -1 )
1682                 iOut = i;
1683         }
1684         else
1685             nUndec++;
1686     }
1687     printf( "Miter:  I =%6d", nPis );
1688     printf( "  N =%7d", Abc_NtkNodeNum(pNtk) );
1689     printf( "  ? =%7d", nUndec );
1690     printf( "  U =%6d", nUnsat );
1691     printf( "  S =%6d", nSat );
1692     Time = Abc_Clock() - Time;
1693     printf(" %7.2f sec\n", (float)(Time)/(float)(CLOCKS_PER_SEC));
1694     if ( iOut >= 0 )
1695         printf( "The first satisfiable output is number %d (%s).\n", iOut, Abc_ObjName( Abc_NtkPo(pNtk, iOut) ) );
1696 }
1697 
1698 /**Function*************************************************************
1699 
1700   Synopsis    [Checks the status of the miter.]
1701 
1702   Description []
1703 
1704   SideEffects []
1705 
1706   SeeAlso     []
1707 
1708 ***********************************************************************/
Abc_NtkPrintPoEquivs(Abc_Ntk_t * pNtk)1709 void Abc_NtkPrintPoEquivs( Abc_Ntk_t * pNtk )
1710 {
1711     Abc_Obj_t * pObj, * pDriver, * pRepr;  int i, iRepr;
1712     Vec_Int_t * vMap = Vec_IntStartFull( Abc_NtkObjNumMax(pNtk) );
1713     Abc_NtkForEachPo( pNtk, pObj, i )
1714     {
1715         pDriver = Abc_ObjFanin0(pObj);
1716         if ( Abc_NtkIsStrash(pNtk) && pDriver == Abc_AigConst1(pNtk) )
1717         {
1718             printf( "%s = Const%d\n", Abc_ObjName(pObj), !Abc_ObjFaninC0(pObj) );
1719             continue;
1720         }
1721         else if ( !Abc_NtkIsStrash(pNtk) && Abc_NodeIsConst(pDriver) )
1722         {
1723             printf( "%s = Const%d\n", Abc_ObjName(pObj), Abc_NodeIsConst1(pDriver) );
1724             continue;
1725         }
1726         iRepr = Vec_IntEntry( vMap, Abc_ObjId(pDriver) );
1727         if ( iRepr == -1 )
1728         {
1729             Vec_IntWriteEntry( vMap, Abc_ObjId(pDriver), i );
1730             continue;
1731         }
1732         pRepr = Abc_NtkCo(pNtk, iRepr);
1733         printf( "%s = %s%s\n", Abc_ObjName(pObj), Abc_ObjFaninC0(pRepr) == Abc_ObjFaninC0(pObj) ? "" : "!", Abc_ObjName(pRepr) );
1734     }
1735     Vec_IntFree( vMap );
1736 }
1737 
1738 
1739 
1740 
1741 typedef struct Gli_Man_t_ Gli_Man_t;
1742 
1743 extern Gli_Man_t * Gli_ManAlloc( int nObjs, int nRegs, int nFanioPairs );
1744 extern void        Gli_ManStop( Gli_Man_t * p );
1745 extern int         Gli_ManCreateCi( Gli_Man_t * p, int nFanouts );
1746 extern int         Gli_ManCreateCo( Gli_Man_t * p, int iFanin );
1747 extern int         Gli_ManCreateNode( Gli_Man_t * p, Vec_Int_t * vFanins, int nFanouts, word * pGateTruth );
1748 
1749 extern void        Gli_ManSwitchesAndGlitches( Gli_Man_t * p, int nPatterns, float PiTransProb, int fVerbose );
1750 extern int         Gli_ObjNumSwitches( Gli_Man_t * p, int iNode );
1751 extern int         Gli_ObjNumGlitches( Gli_Man_t * p, int iNode );
1752 
1753 /**Function*************************************************************
1754 
1755   Synopsis    [Returns the percentable of increased power due to glitching.]
1756 
1757   Description []
1758 
1759   SideEffects []
1760 
1761   SeeAlso     []
1762 
1763 ***********************************************************************/
Abc_NtkMfsTotalGlitchingLut(Abc_Ntk_t * pNtk,int nPats,int Prob,int fVerbose)1764 float Abc_NtkMfsTotalGlitchingLut( Abc_Ntk_t * pNtk, int nPats, int Prob, int fVerbose )
1765 {
1766     int nSwitches, nGlitches;
1767     Gli_Man_t * p;
1768     Vec_Ptr_t * vNodes;
1769     Vec_Int_t * vFanins, * vTruth;
1770     Abc_Obj_t * pObj, * pFanin;
1771     Vec_Wrd_t * vTruths; word * pTruth;
1772     unsigned * puTruth;
1773     int i, k;
1774     assert( Abc_NtkIsLogic(pNtk) );
1775     assert( Abc_NtkGetFaninMax(pNtk) <= 6 );
1776     if ( Abc_NtkGetFaninMax(pNtk) > 6 )
1777     {
1778         printf( "Abc_NtkMfsTotalGlitching() This procedure works only for mapped networks with LUTs size up to 6 inputs.\n" );
1779         return -1.0;
1780     }
1781     Abc_NtkToAig( pNtk );
1782     vNodes = Abc_NtkDfs( pNtk, 0 );
1783     vFanins = Vec_IntAlloc( 6 );
1784     vTruth = Vec_IntAlloc( 1 << 12 );
1785     vTruths = Vec_WrdStart( Abc_NtkObjNumMax(pNtk) );
1786 
1787     // derive network for glitch computation
1788     p = Gli_ManAlloc( Vec_PtrSize(vNodes) + Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk),
1789         Abc_NtkLatchNum(pNtk), Abc_NtkGetTotalFanins(pNtk) + Abc_NtkCoNum(pNtk) );
1790     Abc_NtkForEachObj( pNtk, pObj, i )
1791         pObj->iTemp = -1;
1792     Abc_NtkForEachCi( pNtk, pObj, i )
1793         pObj->iTemp = Gli_ManCreateCi( p, Abc_ObjFanoutNum(pObj) );
1794     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
1795     {
1796         Vec_IntClear( vFanins );
1797         Abc_ObjForEachFanin( pObj, pFanin, k )
1798             Vec_IntPush( vFanins, pFanin->iTemp );
1799         puTruth = Hop_ManConvertAigToTruth( (Hop_Man_t *)pNtk->pManFunc, (Hop_Obj_t *)pObj->pData, Abc_ObjFaninNum(pObj), vTruth, 0 );
1800         pTruth = Vec_WrdEntryP( vTruths, Abc_ObjId(pObj) );
1801         *pTruth = ((word)puTruth[Abc_ObjFaninNum(pObj) == 6] << 32) | (word)puTruth[0];
1802         pObj->iTemp = Gli_ManCreateNode( p, vFanins, Abc_ObjFanoutNum(pObj), pTruth );
1803     }
1804     Abc_NtkForEachCo( pNtk, pObj, i )
1805         Gli_ManCreateCo( p, Abc_ObjFanin0(pObj)->iTemp );
1806 
1807     // compute glitching
1808     Gli_ManSwitchesAndGlitches( p, 4000, 1.0/8.0, 0 );
1809 
1810     // compute the ratio
1811     nSwitches = nGlitches = 0;
1812     Abc_NtkForEachObj( pNtk, pObj, i )
1813         if ( pObj->iTemp >= 0 )
1814         {
1815             nSwitches += Abc_ObjFanoutNum(pObj) * Gli_ObjNumSwitches(p, pObj->iTemp);
1816             nGlitches += Abc_ObjFanoutNum(pObj) * Gli_ObjNumGlitches(p, pObj->iTemp);
1817         }
1818 
1819     Gli_ManStop( p );
1820     Vec_PtrFree( vNodes );
1821     Vec_IntFree( vTruth );
1822     Vec_IntFree( vFanins );
1823     Vec_WrdFree( vTruths );
1824     return nSwitches ? 100.0*(nGlitches-nSwitches)/nSwitches : 0.0;
1825 }
1826 
1827 /**Function*************************************************************
1828 
1829   Synopsis    [Returns the percentable of increased power due to glitching.]
1830 
1831   Description []
1832 
1833   SideEffects []
1834 
1835   SeeAlso     []
1836 
1837 ***********************************************************************/
Abc_NtkMfsTotalGlitching(Abc_Ntk_t * pNtk,int nPats,int Prob,int fVerbose)1838 float Abc_NtkMfsTotalGlitching( Abc_Ntk_t * pNtk, int nPats, int Prob, int fVerbose )
1839 {
1840     int nSwitches, nGlitches;
1841     Gli_Man_t * p;
1842     Vec_Ptr_t * vNodes;
1843     Vec_Int_t * vFanins;
1844     Abc_Obj_t * pObj, * pFanin;
1845     int i, k, nFaninMax = Abc_NtkGetFaninMax(pNtk);
1846     if ( !Abc_NtkIsMappedLogic(pNtk) )
1847         return Abc_NtkMfsTotalGlitchingLut( pNtk, nPats, Prob, fVerbose );
1848     assert( Abc_NtkIsMappedLogic(pNtk) );
1849     if ( nFaninMax > 16 )
1850     {
1851         printf( "Abc_NtkMfsTotalGlitching() This procedure works only for mapped networks with LUTs size up to 6 inputs.\n" );
1852         return -1.0;
1853     }
1854     vNodes = Abc_NtkDfs( pNtk, 0 );
1855     vFanins = Vec_IntAlloc( 6 );
1856 
1857     // derive network for glitch computation
1858     p = Gli_ManAlloc( Vec_PtrSize(vNodes) + Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk),
1859         Abc_NtkLatchNum(pNtk), Abc_NtkGetTotalFanins(pNtk) + Abc_NtkCoNum(pNtk) );
1860     Abc_NtkForEachObj( pNtk, pObj, i )
1861         pObj->iTemp = -1;
1862     Abc_NtkForEachCi( pNtk, pObj, i )
1863         pObj->iTemp = Gli_ManCreateCi( p, Abc_ObjFanoutNum(pObj) );
1864     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
1865     {
1866         Vec_IntClear( vFanins );
1867         Abc_ObjForEachFanin( pObj, pFanin, k )
1868             Vec_IntPush( vFanins, pFanin->iTemp );
1869         pObj->iTemp = Gli_ManCreateNode( p, vFanins, Abc_ObjFanoutNum(pObj), Mio_GateReadTruthP((Mio_Gate_t *)pObj->pData) );
1870     }
1871     Abc_NtkForEachCo( pNtk, pObj, i )
1872         Gli_ManCreateCo( p, Abc_ObjFanin0(pObj)->iTemp );
1873 
1874     // compute glitching
1875     Gli_ManSwitchesAndGlitches( p, nPats, 1.0/Prob, fVerbose );
1876 
1877     // compute the ratio
1878     nSwitches = nGlitches = 0;
1879     Abc_NtkForEachObj( pNtk, pObj, i )
1880         if ( pObj->iTemp >= 0 )
1881         {
1882             nSwitches += Abc_ObjFanoutNum(pObj) * Gli_ObjNumSwitches(p, pObj->iTemp);
1883             nGlitches += Abc_ObjFanoutNum(pObj) * Gli_ObjNumGlitches(p, pObj->iTemp);
1884         }
1885 
1886     Gli_ManStop( p );
1887     Vec_PtrFree( vNodes );
1888     Vec_IntFree( vFanins );
1889     return nSwitches ? 100.0*(nGlitches-nSwitches)/nSwitches : 0.0;
1890 }
1891 
1892 /**Function*************************************************************
1893 
1894   Synopsis    [Prints K-map of 6-var function represented by truth table.]
1895 
1896   Description []
1897 
1898   SideEffects []
1899 
1900   SeeAlso     []
1901 
1902 ***********************************************************************/
Abc_Show6VarFunc(word F0,word F1)1903 void Abc_Show6VarFunc( word F0, word F1 )
1904 {
1905     // order of cells in the Karnaugh map
1906 //    int Cells[8] = { 0, 1, 3, 2, 6, 7, 5, 4 };
1907     int Cells[8] = { 0, 4, 6, 2, 3, 7, 5, 1 };
1908     // intermediate variables
1909     int s; // symbol counter
1910     int h; // horizontal coordinate;
1911     int v; // vertical coordinate;
1912     assert( (F0 & F1) == 0 );
1913 
1914     // output minterms above
1915     for ( s = 0; s < 4; s++ )
1916         printf( " " );
1917     printf( " " );
1918     for ( h = 0; h < 8; h++ )
1919     {
1920         for ( s = 0; s < 3; s++ )
1921             printf( "%d",  ((Cells[h] >> (2-s)) & 1) );
1922         printf( " " );
1923     }
1924     printf( "\n" );
1925 
1926     // output horizontal line above
1927     for ( s = 0; s < 4; s++ )
1928         printf( " " );
1929     printf( "+" );
1930     for ( h = 0; h < 8; h++ )
1931     {
1932         for ( s = 0; s < 3; s++ )
1933             printf( "-" );
1934         printf( "+" );
1935     }
1936     printf( "\n" );
1937 
1938     // output lines with function values
1939     for ( v = 0; v < 8; v++ )
1940     {
1941         for ( s = 0; s < 3; s++ )
1942             printf( "%d",  ((Cells[v] >> (2-s)) & 1) );
1943         printf( " |" );
1944 
1945         for ( h = 0; h < 8; h++ )
1946         {
1947             printf( " " );
1948             if ( ((F0 >> ((Cells[v]*8)+Cells[h])) & 1) )
1949                 printf( "0" );
1950             else if ( ((F1 >> ((Cells[v]*8)+Cells[h])) & 1) )
1951                 printf( "1" );
1952             else
1953                 printf( " " );
1954             printf( " |" );
1955         }
1956         printf( "\n" );
1957 
1958         // output horizontal line above
1959         for ( s = 0; s < 4; s++ )
1960             printf( " " );
1961 //        printf( "%c", v == 7 ? '+' : '|' );
1962         printf( "+" );
1963         for ( h = 0; h < 8; h++ )
1964         {
1965             for ( s = 0; s < 3; s++ )
1966                 printf( "-" );
1967 //            printf( "%c", v == 7 ? '+' : '|' );
1968             printf( "%c", (v == 7 || h == 7) ? '+' : '|' );
1969         }
1970         printf( "\n" );
1971     }
1972 }
1973 
1974 /**Function*************************************************************
1975 
1976   Synopsis    [Prints K-map of 6-var function represented by truth table.]
1977 
1978   Description []
1979 
1980   SideEffects []
1981 
1982   SeeAlso     []
1983 
1984 ***********************************************************************/
Abc_NtkShow6VarFunc(char * pF0,char * pF1)1985 void Abc_NtkShow6VarFunc( char * pF0, char * pF1 )
1986 {
1987     word F0, F1;
1988     if ( strlen(pF0) != 16 )
1989     {
1990         printf( "Wrong length (%d) of 6-var truth table.\n", (int)strlen(pF0) );
1991         return;
1992     }
1993     if ( strlen(pF1) != 16 )
1994     {
1995         printf( "Wrong length (%d) of 6-var truth table.\n", (int)strlen(pF1) );
1996         return;
1997     }
1998     Extra_ReadHexadecimal( (unsigned *)&F0, pF0, 6 );
1999     Extra_ReadHexadecimal( (unsigned *)&F1, pF1, 6 );
2000     Abc_Show6VarFunc( F0, F1 );
2001 }
2002 
2003 
2004 ////////////////////////////////////////////////////////////////////////
2005 ///                       END OF FILE                                ///
2006 ////////////////////////////////////////////////////////////////////////
2007 
2008 
2009 ABC_NAMESPACE_IMPL_END
2010