1 /**CFile****************************************************************
2 
3   FileName    [giaMan.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Scalable AIG package.]
8 
9   Synopsis    [Package 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: giaMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include <ctype.h>
22 
23 #include "gia.h"
24 #include "misc/tim/tim.h"
25 #include "proof/abs/abs.h"
26 #include "opt/dar/dar.h"
27 #include "misc/extra/extra.h"
28 
29 #ifdef WIN32
30 #include <windows.h>
31 #endif
32 
33 ABC_NAMESPACE_IMPL_START
34 
35 
36 ////////////////////////////////////////////////////////////////////////
37 ///                        DECLARATIONS                              ///
38 ////////////////////////////////////////////////////////////////////////
39 
40 extern void Gia_ManDfsSlacksPrint( Gia_Man_t * p );
41 
42 ////////////////////////////////////////////////////////////////////////
43 ///                     FUNCTION DEFINITIONS                         ///
44 ////////////////////////////////////////////////////////////////////////
45 
46 /**Function*************************************************************
47 
48   Synopsis    [Creates AIG.]
49 
50   Description []
51 
52   SideEffects []
53 
54   SeeAlso     []
55 
56 ***********************************************************************/
Gia_ManStart(int nObjsMax)57 Gia_Man_t * Gia_ManStart( int nObjsMax )
58 {
59     Gia_Man_t * p;
60     assert( nObjsMax > 0 );
61     p = ABC_CALLOC( Gia_Man_t, 1 );
62     p->nObjsAlloc = nObjsMax;
63     p->pObjs = ABC_CALLOC( Gia_Obj_t, nObjsMax );
64     p->pObjs->iDiff0 = p->pObjs->iDiff1 = GIA_NONE;
65     p->nObjs = 1;
66     p->vCis  = Vec_IntAlloc( nObjsMax / 20 );
67     p->vCos  = Vec_IntAlloc( nObjsMax / 20 );
68     return p;
69 }
70 
71 /**Function*************************************************************
72 
73   Synopsis    [Deletes AIG.]
74 
75   Description []
76 
77   SideEffects []
78 
79   SeeAlso     []
80 
81 ***********************************************************************/
Gia_ManStop(Gia_Man_t * p)82 void Gia_ManStop( Gia_Man_t * p )
83 {
84     extern void Gia_DatFree( Gia_Dat_t * p );
85     Gia_DatFree( p->pUData );
86     if ( p->vSeqModelVec )
87         Vec_PtrFreeFree( p->vSeqModelVec );
88     Gia_ManStaticFanoutStop( p );
89     Tim_ManStopP( (Tim_Man_t **)&p->pManTime );
90     assert( p->pManTime == NULL );
91     Vec_PtrFreeFree( p->vNamesIn );
92     Vec_PtrFreeFree( p->vNamesOut );
93     Vec_IntFreeP( &p->vSwitching );
94     Vec_IntFreeP( &p->vSuper );
95     Vec_IntFreeP( &p->vStore );
96     Vec_IntFreeP( &p->vClassNew );
97     Vec_IntFreeP( &p->vClassOld );
98     Vec_WrdFreeP( &p->vSims );
99     Vec_WrdFreeP( &p->vSimsPi );
100     Vec_WrdFreeP( &p->vSimsPo );
101     Vec_IntFreeP( &p->vTimeStamps );
102     Vec_FltFreeP( &p->vTiming );
103     Vec_VecFreeP( &p->vClockDoms );
104     Vec_IntFreeP( &p->vCofVars );
105     Vec_IntFreeP( &p->vIdsOrig );
106     Vec_IntFreeP( &p->vIdsEquiv );
107     Vec_IntFreeP( &p->vLutConfigs );
108     Vec_IntFreeP( &p->vEdgeDelay );
109     Vec_IntFreeP( &p->vEdgeDelayR );
110     Vec_IntFreeP( &p->vEdge1 );
111     Vec_IntFreeP( &p->vEdge2 );
112     Vec_IntFreeP( &p->vUserPiIds );
113     Vec_IntFreeP( &p->vUserPoIds );
114     Vec_IntFreeP( &p->vUserFfIds );
115     Vec_IntFreeP( &p->vFlopClasses );
116     Vec_IntFreeP( &p->vGateClasses );
117     Vec_IntFreeP( &p->vObjClasses );
118     Vec_IntFreeP( &p->vInitClasses );
119     Vec_IntFreeP( &p->vRegClasses );
120     Vec_IntFreeP( &p->vRegInits );
121     Vec_IntFreeP( &p->vDoms );
122     Vec_IntFreeP( &p->vBarBufs );
123     Vec_IntFreeP( &p->vXors );
124     Vec_IntFreeP( &p->vLevels );
125     Vec_IntFreeP( &p->vTruths );
126     Vec_IntErase( &p->vCopies );
127     Vec_IntErase( &p->vCopies2 );
128     Vec_IntFreeP( &p->vVar2Obj );
129     Vec_IntErase( &p->vCopiesTwo );
130     Vec_IntErase( &p->vSuppVars );
131     Vec_WrdFreeP( &p->vSuppWords );
132     Vec_IntFreeP( &p->vTtNums );
133     Vec_IntFreeP( &p->vTtNodes );
134     Vec_WrdFreeP( &p->vTtMemory );
135     Vec_PtrFreeP( &p->vTtInputs );
136     Vec_IntFreeP( &p->vMapping );
137     Vec_WecFreeP( &p->vMapping2 );
138     Vec_WecFreeP( &p->vFanouts2 );
139     Vec_IntFreeP( &p->vCellMapping );
140     Vec_IntFreeP( &p->vPacking );
141     Vec_IntFreeP( &p->vConfigs );
142     ABC_FREE( p->pCellStr );
143     Vec_FltFreeP( &p->vInArrs );
144     Vec_FltFreeP( &p->vOutReqs );
145     Vec_IntFreeP( &p->vCiArrs );
146     Vec_IntFreeP( &p->vCoReqs );
147     Vec_IntFreeP( &p->vCoArrs );
148     Vec_IntFreeP( &p->vCoAttrs );
149     Gia_ManStopP( &p->pAigExtra );
150     Vec_IntFree( p->vCis );
151     Vec_IntFree( p->vCos );
152     Vec_IntErase( &p->vHash );
153     Vec_IntErase( &p->vHTable );
154     Vec_IntErase( &p->vRefs );
155     ABC_FREE( p->pData2 );
156     ABC_FREE( p->pTravIds );
157     ABC_FREE( p->pPlacement );
158     ABC_FREE( p->pSwitching );
159     ABC_FREE( p->pCexSeq );
160     ABC_FREE( p->pCexComb );
161     ABC_FREE( p->pIso );
162 //    ABC_FREE( p->pMapping );
163     ABC_FREE( p->pFanData );
164     ABC_FREE( p->pReprsOld );
165     ABC_FREE( p->pReprs );
166     ABC_FREE( p->pNexts );
167     ABC_FREE( p->pSibls );
168     ABC_FREE( p->pRefs );
169     ABC_FREE( p->pLutRefs );
170     ABC_FREE( p->pMuxes );
171     ABC_FREE( p->pObjs );
172     ABC_FREE( p->pSpec );
173     ABC_FREE( p->pName );
174     ABC_FREE( p );
175 }
176 
177 /**Function*************************************************************
178 
179   Synopsis    [Returns memory used in megabytes.]
180 
181   Description []
182 
183   SideEffects []
184 
185   SeeAlso     []
186 
187 ***********************************************************************/
Gia_ManMemory(Gia_Man_t * p)188 double Gia_ManMemory( Gia_Man_t * p )
189 {
190     double Memory = sizeof(Gia_Man_t);
191     Memory += sizeof(Gia_Obj_t) * Gia_ManObjNum(p);
192     Memory += sizeof(int) * Gia_ManCiNum(p);
193     Memory += sizeof(int) * Gia_ManCoNum(p);
194     Memory += sizeof(int) * Vec_IntSize(&p->vHTable);
195     Memory += sizeof(int) * Gia_ManObjNum(p) * (p->pRefs != NULL);
196     Memory += Vec_IntMemory( p->vLevels );
197     Memory += Vec_IntMemory( p->vCellMapping );
198     Memory += Vec_IntMemory( &p->vCopies );
199     Memory += Vec_FltMemory( p->vInArrs );
200     Memory += Vec_FltMemory( p->vOutReqs );
201     Memory += Vec_PtrMemory( p->vNamesIn );
202     Memory += Vec_PtrMemory( p->vNamesOut );
203     return Memory;
204 }
205 
206 /**Function*************************************************************
207 
208   Synopsis    [Stops the AIG manager.]
209 
210   Description []
211 
212   SideEffects []
213 
214   SeeAlso     []
215 
216 ***********************************************************************/
Gia_ManStopP(Gia_Man_t ** p)217 void Gia_ManStopP( Gia_Man_t ** p )
218 {
219     if ( *p == NULL )
220         return;
221     Gia_ManStop( *p );
222     *p = NULL;
223 }
224 
225 /**Function*************************************************************
226 
227   Synopsis    [Prints stats for the AIG.]
228 
229   Description []
230 
231   SideEffects []
232 
233   SeeAlso     []
234 
235 ***********************************************************************/
Gia_ManPrintClasses_old(Gia_Man_t * p)236 void Gia_ManPrintClasses_old( Gia_Man_t * p )
237 {
238     Gia_Obj_t * pObj;
239     int i;
240     if ( p->vFlopClasses == NULL )
241         return;
242     Gia_ManForEachRo( p, pObj, i )
243         Abc_Print( 1, "%d", Vec_IntEntry(p->vFlopClasses, i) );
244     Abc_Print( 1, "\n" );
245 
246     {
247         Gia_Man_t * pTemp;
248         pTemp = Gia_ManDupFlopClass( p, 1 );
249         Gia_AigerWrite( pTemp, "dom1.aig", 0, 0, 0 );
250         Gia_ManStop( pTemp );
251         pTemp = Gia_ManDupFlopClass( p, 2 );
252         Gia_AigerWrite( pTemp, "dom2.aig", 0, 0, 0 );
253         Gia_ManStop( pTemp );
254     }
255 }
256 
257 /**Function*************************************************************
258 
259   Synopsis    [Prints stats for the AIG.]
260 
261   Description []
262 
263   SideEffects []
264 
265   SeeAlso     []
266 
267 ***********************************************************************/
Gia_ManPrintPlacement(Gia_Man_t * p)268 void Gia_ManPrintPlacement( Gia_Man_t * p )
269 {
270     int i, nFixed = 0, nUndef = 0;
271     if ( p->pPlacement == NULL )
272         return;
273     for ( i = 0; i < Gia_ManObjNum(p); i++ )
274     {
275         nFixed += p->pPlacement[i].fFixed;
276         nUndef += p->pPlacement[i].fUndef;
277     }
278     Abc_Print( 1, "Placement:  Objects = %8d.  Fixed = %8d.  Undef = %8d.\n", Gia_ManObjNum(p), nFixed, nUndef );
279 }
280 
281 
282 /**Function*************************************************************
283 
284   Synopsis    [Duplicates AIG for unrolling.]
285 
286   Description []
287 
288   SideEffects []
289 
290   SeeAlso     []
291 
292 ***********************************************************************/
Gia_ManPrintTents_rec(Gia_Man_t * p,Gia_Obj_t * pObj,Vec_Int_t * vObjs)293 void Gia_ManPrintTents_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs )
294 {
295     if ( Gia_ObjIsTravIdCurrent(p, pObj) )
296         return;
297     Gia_ObjSetTravIdCurrent(p, pObj);
298     Vec_IntPush( vObjs, Gia_ObjId(p, pObj) );
299     if ( Gia_ObjIsCi(pObj) )
300         return;
301     Gia_ManPrintTents_rec( p, Gia_ObjFanin0(pObj), vObjs );
302     if ( Gia_ObjIsAnd(pObj) )
303         Gia_ManPrintTents_rec( p, Gia_ObjFanin1(pObj), vObjs );
304 }
Gia_ManPrintTents(Gia_Man_t * p)305 void Gia_ManPrintTents( Gia_Man_t * p )
306 {
307     Vec_Int_t * vObjs;
308     Gia_Obj_t * pObj;
309     int t, i, iObjId, nSizePrev, nSizeCurr;
310     assert( Gia_ManPoNum(p) > 0 );
311     vObjs = Vec_IntAlloc( 100 );
312     // save constant class
313     Gia_ManIncrementTravId( p );
314     Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
315     Vec_IntPush( vObjs, 0 );
316     // create starting root
317     nSizePrev = Vec_IntSize(vObjs);
318     Gia_ManForEachPo( p, pObj, i )
319         Gia_ManPrintTents_rec( p, pObj, vObjs );
320     // build tents
321     Abc_Print( 1, "Tents:  " );
322     for ( t = 1; nSizePrev < Vec_IntSize(vObjs); t++ )
323     {
324         int nPis = 0;
325         nSizeCurr = Vec_IntSize(vObjs);
326         Vec_IntForEachEntryStartStop( vObjs, iObjId, i, nSizePrev, nSizeCurr )
327         {
328             nPis += Gia_ObjIsPi(p, Gia_ManObj(p, iObjId));
329             if ( Gia_ObjIsRo(p, Gia_ManObj(p, iObjId)) )
330                 Gia_ManPrintTents_rec( p, Gia_ObjRoToRi(p, Gia_ManObj(p, iObjId)), vObjs );
331         }
332         Abc_Print( 1, "%d=%d(%d)  ", t, nSizeCurr - nSizePrev, nPis );
333         nSizePrev = nSizeCurr;
334     }
335     Abc_Print( 1, " Unused=%d\n", Gia_ManObjNum(p) - Vec_IntSize(vObjs) );
336     Vec_IntFree( vObjs );
337     // the remaining objects are PIs without fanout
338 //    Gia_ManForEachObj( p, pObj, i )
339 //        if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
340 //            Gia_ObjPrint( p, pObj );
341 }
342 
343 /**Function*************************************************************
344 
345   Synopsis    []
346 
347   Description []
348 
349   SideEffects []
350 
351   SeeAlso     []
352 
353 ***********************************************************************/
Gia_ManPrintInitClasses(Vec_Int_t * vInits)354 void Gia_ManPrintInitClasses( Vec_Int_t * vInits )
355 {
356     int i, Value;
357     int Counts[6] = {0};
358     Vec_IntForEachEntry( vInits, Value, i )
359         Counts[Value]++;
360     for ( i = 0; i < 6; i++ )
361         if ( Counts[i] )
362             printf( "%d = %d  ", i, Counts[i] );
363     printf( "  " );
364     printf( "B = %d  ", Counts[0] + Counts[1] );
365     printf( "X = %d  ", Counts[2] + Counts[3] );
366     printf( "Q = %d\n", Counts[4] + Counts[5] );
367     Vec_IntForEachEntry( vInits, Value, i )
368     {
369         Counts[Value]++;
370         if ( Value == 0 )
371             printf( "0" );
372         else if ( Value == 1 )
373             printf( "1" );
374         else if ( Value == 2 )
375             printf( "2" );
376         else if ( Value == 3 )
377             printf( "3" );
378         else if ( Value == 4 )
379             printf( "4" );
380         else if ( Value == 5 )
381             printf( "5" );
382         else assert( 0 );
383     }
384     printf( "\n" );
385 
386 }
387 
388 /**Function*************************************************************
389 
390   Synopsis    [Prints stats for the AIG.]
391 
392   Description []
393 
394   SideEffects []
395 
396   SeeAlso     []
397 
398 ***********************************************************************/
Gia_ManPrintChoiceStats(Gia_Man_t * p)399 void Gia_ManPrintChoiceStats( Gia_Man_t * p )
400 {
401     Gia_Obj_t * pObj;
402     int i, nEquivs = 0, nChoices = 0;
403     Gia_ManMarkFanoutDrivers( p );
404     Gia_ManForEachAnd( p, pObj, i )
405     {
406         if ( !Gia_ObjSibl(p, i) )
407             continue;
408         nEquivs++;
409         if ( pObj->fMark0 )
410             nChoices++;
411         assert( !Gia_ObjSiblObj(p, i)->fMark0 );
412         assert( Gia_ObjIsAnd(Gia_ObjSiblObj(p, i)) );
413     }
414     Abc_Print( 1, "Choice stats: Equivs =%7d. Choices =%7d.\n", nEquivs, nChoices );
415     Gia_ManCleanMark0( p );
416 }
417 
418 
419 /**Function*************************************************************
420 
421   Synopsis    [Prints stats for the AIG.]
422 
423   Description []
424 
425   SideEffects []
426 
427   SeeAlso     []
428 
429 ***********************************************************************/
Gia_ManPrintEdges(Gia_Man_t * p)430 int Gia_ManPrintEdges( Gia_Man_t * p )
431 {
432     printf( "Edges (Q=2)    :                " );
433     printf( "edge =%8d  ", (Vec_IntCountPositive(p->vEdge1) + Vec_IntCountPositive(p->vEdge2))/2 );
434     printf( "lev =%5.1f",  0.1*Gia_ManEvalEdgeDelay(p) );
435     printf( "\n" );
436     return 0;
437 }
438 
439 /**Function*************************************************************
440 
441   Synopsis    [Prints stats for the AIG.]
442 
443   Description []
444 
445   SideEffects []
446 
447   SeeAlso     []
448 
449 ***********************************************************************/
450 /*
451 void Gia_ManLogAigStats( Gia_Man_t * p, char * pDumpFile )
452 {
453     FILE * pTable = fopen( pDumpFile, "wb" );
454     fprintf( pTable, "Name = %24s     ", p->pName );
455     fprintf( pTable, "In = %6d   ",      Gia_ManCiNum(p) );
456     fprintf( pTable, "Out = %6d   ",     Gia_ManCoNum(p) );
457     fprintf( pTable, "And = %8d   ",     Gia_ManAndNum(p) );
458     fprintf( pTable, "Lev = %6d",        Gia_ManLevelNum(p) );
459     fprintf( pTable, "\n" );
460     fclose( pTable );
461 }
462 */
Gia_ManLogAigStats(Gia_Man_t * p,char * pDumpFile)463 void Gia_ManLogAigStats( Gia_Man_t * p, char * pDumpFile )
464 {
465     FILE * pTable = fopen( pDumpFile, "wb" );
466     fprintf( pTable, "{\n" );
467     fprintf( pTable, "    \"name\" : \"%s\",\n", p->pName );
468     fprintf( pTable, "    \"input\" : %d,\n",    Gia_ManCiNum(p) );
469     fprintf( pTable, "    \"output\" : %d,\n",   Gia_ManCoNum(p) );
470     fprintf( pTable, "    \"and\" : %d,\n",      Gia_ManAndNum(p) );
471     fprintf( pTable, "    \"level\" : %d\n",     Gia_ManLevelNum(p) );
472     fprintf( pTable, "}\n" );
473     fclose( pTable );
474 }
475 
476 /**Function*************************************************************
477 
478   Synopsis    [Prints stats for the AIG.]
479 
480   Description []
481 
482   SideEffects []
483 
484   SeeAlso     []
485 
486 ***********************************************************************/
Gia_ManPrintStats(Gia_Man_t * p,Gps_Par_t * pPars)487 void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars )
488 {
489     extern float Gia_ManLevelAve( Gia_Man_t * p );
490     int fHaveLevels = p->vLevels != NULL;
491     if ( pPars && pPars->fMiter )
492     {
493         Gia_ManPrintStatsMiter( p, 0 );
494         return;
495     }
496     if ( pPars && pPars->fNoColor )
497     {
498         if ( p->pName )
499             Abc_Print( 1, "%-8s : ", p->pName );
500     }
501     else
502     {
503 #ifdef WIN32
504     SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), 15 ); // bright
505     if ( p->pName )
506         Abc_Print( 1, "%-8s : ", p->pName );
507     SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), 7 );  // normal
508 #else
509     if ( p->pName )
510         Abc_Print( 1, "%s%-8s%s : ", "\033[1;37m", p->pName, "\033[0m" );  // bright
511 #endif
512     }
513     Abc_Print( 1, "i/o =%7d/%7d",
514         Gia_ManPiNum(p) - Gia_ManBoxCiNum(p) - Gia_ManRegBoxNum(p),
515         Gia_ManPoNum(p) - Gia_ManBoxCoNum(p) - Gia_ManRegBoxNum(p) );
516     if ( Gia_ManConstrNum(p) )
517         Abc_Print( 1, "(c=%d)", Gia_ManConstrNum(p) );
518     if ( Gia_ManRegNum(p) )
519         Abc_Print( 1, "  ff =%7d", Gia_ManRegNum(p) );
520     if ( Gia_ManRegBoxNum(p) )
521         Abc_Print( 1, "  boxff =%d(%d)", Gia_ManRegBoxNum(p), Gia_ManClockDomainNum(p) );
522     if ( pPars && pPars->fNoColor )
523     {
524         Abc_Print( 1, "  %s =%8d", p->pMuxes? "nod" : "and", Gia_ManAndNum(p) );
525         Abc_Print( 1, "  lev =%5d", Gia_ManLevelNum(p) );
526         Abc_Print( 1, " (%.2f)", Gia_ManLevelAve(p) );
527     }
528     else
529     {
530 #ifdef WIN32
531     {
532     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
533     SetConsoleTextAttribute( hConsole, 11 ); // blue
534     Abc_Print( 1, "  %s =%8d", p->pMuxes? "nod" : "and", Gia_ManAndNum(p) );
535     SetConsoleTextAttribute( hConsole, 13 ); // magenta
536     Abc_Print( 1, "  lev =%5d", Gia_ManLevelNum(p) );
537     Abc_Print( 1, " (%.2f)", Gia_ManLevelAve(p) );
538     SetConsoleTextAttribute( hConsole, 7 ); // normal
539     }
540 #else
541     Abc_Print( 1, "  %s%s =%8d%s",  "\033[1;36m", p->pMuxes? "nod" : "and", Gia_ManAndNum(p), "\033[0m" ); // blue
542     Abc_Print( 1, "  %slev =%5d%s", "\033[1;35m", Gia_ManLevelNum(p), "\033[0m" ); // magenta
543     Abc_Print( 1, " %s(%.2f)%s",    "\033[1;35m", Gia_ManLevelAve(p), "\033[0m" );
544 #endif
545     }
546     if ( !fHaveLevels )
547         Vec_IntFreeP( &p->vLevels );
548     if ( pPars && pPars->fCut )
549         Abc_Print( 1, "  cut = %d(%d)", Gia_ManCrossCut(p, 0), Gia_ManCrossCut(p, 1) );
550     Abc_Print( 1, "  mem =%5.2f MB", Gia_ManMemory(p)/(1<<20) );
551     if ( Gia_ManHasChoices(p) )
552         Abc_Print( 1, "  ch =%5d", Gia_ManChoiceNum(p) );
553     if ( p->pManTime )
554         Abc_Print( 1, "  box = %d", Gia_ManNonRegBoxNum(p) );
555     if ( p->pManTime )
556         Abc_Print( 1, "  bb = %d", Gia_ManBlackBoxNum(p) );
557     if ( Gia_ManBufNum(p) )
558         Abc_Print( 1, "  buf = %d", Gia_ManBufNum(p) );
559     if ( Gia_ManXorNum(p) && p->pMuxes == NULL )
560         Abc_Print( 1, "  xor = %d", Gia_ManXorNum(p) );
561     if ( pPars && pPars->fMuxXor )
562         printf( "\nXOR/MUX " ), Gia_ManPrintMuxStats( p );
563     if ( pPars && pPars->fSwitch )
564     {
565         static int nPiPo = 0;
566         static float PrevSwiTotal = 0;
567         float SwiTotal = Gia_ManComputeSwitching( p, 48, 16, 0 );
568         Abc_Print( 1, "  power =%8.1f", SwiTotal );
569         if ( PrevSwiTotal > 0 && nPiPo == Gia_ManCiNum(p) + Gia_ManCoNum(p) )
570             Abc_Print( 1, " %6.2f %%", 100.0*(PrevSwiTotal-SwiTotal)/PrevSwiTotal );
571         else if ( PrevSwiTotal == 0 || nPiPo != Gia_ManCiNum(p) + Gia_ManCoNum(p) )
572             PrevSwiTotal = SwiTotal, nPiPo = Gia_ManCiNum(p) + Gia_ManCoNum(p);
573     }
574 //    Abc_Print( 1, "obj =%5d  ", Gia_ManObjNum(p) );
575     Abc_Print( 1, "\n" );
576 
577 //    Gia_ManSatExperiment( p );
578     if ( p->pReprs && p->pNexts )
579         Gia_ManEquivPrintClasses( p, 0, 0.0 );
580     if ( Gia_ManHasMapping(p) && (pPars == NULL || !pPars->fSkipMap) )
581         Gia_ManPrintMappingStats( p, pPars ? pPars->pDumpFile : NULL );
582     else if ( pPars && pPars->pDumpFile )
583         Gia_ManLogAigStats( p, pPars->pDumpFile );
584     if ( pPars && pPars->fNpn && Gia_ManHasMapping(p) && Gia_ManLutSizeMax(p) <= 4 )
585         Gia_ManPrintNpnClasses( p );
586     if ( p->vPacking )
587         Gia_ManPrintPackingStats( p );
588     if ( p->vEdge1 )
589         Gia_ManPrintEdges( p );
590     if ( pPars && pPars->fLutProf && Gia_ManHasMapping(p) )
591         Gia_ManPrintLutStats( p );
592     if ( p->pPlacement )
593         Gia_ManPrintPlacement( p );
594 //    if ( p->pManTime )
595 //        Tim_ManPrintStats( (Tim_Man_t *)p->pManTime, p->nAnd2Delay );
596     Gia_ManPrintFlopClasses( p );
597     Gia_ManPrintGateClasses( p );
598     Gia_ManPrintObjClasses( p );
599 //    if ( p->vRegClasses )
600 //    {
601 //        printf( "The design has %d flops with the following class info: ", Vec_IntSize(p->vRegClasses) );
602 //        Vec_IntPrint( p->vRegClasses );
603 //    }
604     if ( p->vInitClasses )
605         Gia_ManPrintInitClasses( p->vInitClasses );
606     // check integrity of boxes
607     Gia_ManCheckIntegrityWithBoxes( p );
608 /*
609     if ( Gia_ManRegBoxNum(p) )
610     {
611         int i, Limit = Vec_IntFindMax(p->vRegClasses);
612         for ( i = 1; i <= Limit; i++ )
613             printf( "%d ", Vec_IntCountEntry(p->vRegClasses, i) );
614         printf( "\n" );
615     }
616 */
617     if ( pPars && pPars->fTents )
618     {
619 /*
620         int k, Entry, Prev = 1;
621         Vec_Int_t * vLimit = Vec_IntAlloc( 1000 );
622         Gia_Man_t * pNew = Gia_ManUnrollDup( p, vLimit );
623         Abc_Print( 1, "Tents:  " );
624         Vec_IntForEachEntryStart( vLimit, Entry, k, 1 )
625             Abc_Print( 1, "%d=%d  ", k, Entry-Prev ), Prev = Entry;
626         Abc_Print( 1, " Unused=%d.", Gia_ManObjNum(p) - Gia_ManObjNum(pNew) );
627         Abc_Print( 1, "\n" );
628         Vec_IntFree( vLimit );
629         Gia_ManStop( pNew );
630 */
631         Gia_ManPrintTents( p );
632     }
633     if ( pPars && pPars->fSlacks )
634         Gia_ManDfsSlacksPrint( p );
635 }
636 
637 /**Function*************************************************************
638 
639   Synopsis    [Prints stats for the AIG.]
640 
641   Description []
642 
643   SideEffects []
644 
645   SeeAlso     []
646 
647 ***********************************************************************/
Gia_ManPrintStatsShort(Gia_Man_t * p)648 void Gia_ManPrintStatsShort( Gia_Man_t * p )
649 {
650     Abc_Print( 1, "i/o =%7d/%7d  ", Gia_ManPiNum(p), Gia_ManPoNum(p) );
651     Abc_Print( 1, "ff =%7d  ", Gia_ManRegNum(p) );
652     Abc_Print( 1, "and =%8d  ", Gia_ManAndNum(p) );
653     Abc_Print( 1, "lev =%5d  ", Gia_ManLevelNum(p) );
654 //    Abc_Print( 1, "mem =%5.2f MB", 12.0*Gia_ManObjNum(p)/(1<<20) );
655     Abc_Print( 1, "\n" );
656 }
657 
658 /**Function*************************************************************
659 
660   Synopsis    [Prints stats for the AIG.]
661 
662   Description []
663 
664   SideEffects []
665 
666   SeeAlso     []
667 
668 ***********************************************************************/
Gia_ManPrintMiterStatus(Gia_Man_t * p)669 void Gia_ManPrintMiterStatus( Gia_Man_t * p )
670 {
671     Gia_Obj_t * pObj, * pChild;
672     int i, nSat = 0, nUnsat = 0, nUndec = 0, iOut = -1;
673     Gia_ManForEachPo( p, pObj, i )
674     {
675         pChild = Gia_ObjChild0(pObj);
676         // check if the output is constant 0
677         if ( pChild == Gia_ManConst0(p) )
678             nUnsat++;
679         // check if the output is constant 1
680         else if ( pChild == Gia_ManConst1(p) )
681         {
682             nSat++;
683             if ( iOut == -1 )
684                 iOut = i;
685         }
686         // check if the output is a primary input
687         else if ( Gia_ObjIsPi(p, Gia_Regular(pChild)) )
688         {
689             nSat++;
690             if ( iOut == -1 )
691                 iOut = i;
692         }
693 /*
694         // check if the output is 1 for the 0000 pattern
695         else if ( Gia_Regular(pChild)->fPhase != (unsigned)Gia_IsComplement(pChild) )
696         {
697             nSat++;
698             if ( iOut == -1 )
699                 iOut = i;
700         }
701 */
702         else
703             nUndec++;
704     }
705     Abc_Print( 1, "Outputs = %7d.  Unsat = %7d.  Sat = %7d.  Undec = %7d.\n",
706         Gia_ManPoNum(p), nUnsat, nSat, nUndec );
707 }
708 
709 /**Function*************************************************************
710 
711   Synopsis    [Statistics of the miter.]
712 
713   Description []
714 
715   SideEffects []
716 
717   SeeAlso     []
718 
719 ***********************************************************************/
Gia_ManPrintStatsMiter(Gia_Man_t * p,int fVerbose)720 void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose )
721 {
722     Gia_Obj_t * pObj;
723     Vec_Flt_t * vProb;
724     int i, iObjId;
725     Gia_ManLevelNum( p );
726     Gia_ManCreateRefs( p );
727     vProb = Gia_ManPrintOutputProb( p );
728     printf( "Statistics for each outputs of the miter:\n" );
729     Gia_ManForEachPo( p, pObj, i )
730     {
731         iObjId = Gia_ObjId(p, pObj);
732         printf( "%4d : ", i );
733         printf( "Level = %5d  ",  Gia_ObjLevelId(p, iObjId) );
734         printf( "Supp = %5d  ",   Gia_ManSuppSize(p, &iObjId, 1) );
735         printf( "Cone = %5d  ",   Gia_ManConeSize(p, &iObjId, 1) );
736         printf( "Mffc = %5d  ",   Gia_NodeMffcSize(p, Gia_ObjFanin0(pObj)) );
737         printf( "Prob = %8.4f  ", Vec_FltEntry(vProb, iObjId) );
738         printf( "\n" );
739     }
740     Vec_FltFree( vProb );
741 }
742 
743 /**Function*************************************************************
744 
745   Synopsis    [Prints stats for the AIG.]
746 
747   Description []
748 
749   SideEffects []
750 
751   SeeAlso     []
752 
753 ***********************************************************************/
Gia_ManSetRegNum(Gia_Man_t * p,int nRegs)754 void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs )
755 {
756     assert( p->nRegs == 0 );
757     p->nRegs = nRegs;
758 }
759 
760 
761 /**Function*************************************************************
762 
763   Synopsis    [Reports the reduction of the AIG.]
764 
765   Description []
766 
767   SideEffects []
768 
769   SeeAlso     []
770 
771 ***********************************************************************/
Gia_ManReportImprovement(Gia_Man_t * p,Gia_Man_t * pNew)772 void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew )
773 {
774     Abc_Print( 1, "REG: Beg = %5d. End = %5d. (R =%5.1f %%)  ",
775         Gia_ManRegNum(p), Gia_ManRegNum(pNew),
776         Gia_ManRegNum(p)? 100.0*(Gia_ManRegNum(p)-Gia_ManRegNum(pNew))/Gia_ManRegNum(p) : 0.0 );
777     Abc_Print( 1, "AND: Beg = %6d. End = %6d. (R =%5.1f %%)",
778         Gia_ManAndNum(p), Gia_ManAndNum(pNew),
779         Gia_ManAndNum(p)? 100.0*(Gia_ManAndNum(p)-Gia_ManAndNum(pNew))/Gia_ManAndNum(p) : 0.0 );
780     Abc_Print( 1, "\n" );
781 }
782 
783 /**Function*************************************************************
784 
785   Synopsis    [Prints NPN class statistics.]
786 
787   Description []
788 
789   SideEffects []
790 
791   SeeAlso     []
792 
793 ***********************************************************************/
Gia_ManPrintNpnClasses(Gia_Man_t * p)794 void Gia_ManPrintNpnClasses( Gia_Man_t * p )
795 {
796     extern char ** Kit_DsdNpn4ClassNames();
797     char ** pNames = Kit_DsdNpn4ClassNames();
798     Vec_Int_t * vLeaves, * vTruth, * vVisited;
799     int * pLutClass, ClassCounts[222] = {0};
800     int i, k, iFan, Class, OtherClasses, OtherClasses2, nTotal, Counter, Counter2;
801     unsigned * pTruth;
802     assert( Gia_ManHasMapping(p) );
803     assert(  Gia_ManLutSizeMax( p ) <= 4 );
804     vLeaves   = Vec_IntAlloc( 100 );
805     vVisited  = Vec_IntAlloc( 100 );
806     vTruth    = Vec_IntAlloc( (1<<16) );
807     pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) );
808     Gia_ManCleanTruth( p );
809     Gia_ManForEachLut( p, i )
810     {
811         if ( Gia_ObjLutSize(p,i) > 4 )
812             continue;
813         Vec_IntClear( vLeaves );
814         Gia_LutForEachFanin( p, i, iFan, k )
815             Vec_IntPush( vLeaves, iFan );
816         for ( ; k < 4; k++ )
817             Vec_IntPush( vLeaves, 0 );
818         pTruth = Gia_ManConvertAigToTruth( p, Gia_ManObj(p, i), vLeaves, vTruth, vVisited );
819         Class = Dar_LibReturnClass( *pTruth );
820         ClassCounts[ Class ]++;
821         pLutClass[i] = Class;
822     }
823     Vec_IntFree( vLeaves );
824     Vec_IntFree( vTruth );
825     Vec_IntFree( vVisited );
826     Vec_IntFreeP( &p->vTruths );
827     nTotal = 0;
828     for ( i = 0; i < 222; i++ )
829         nTotal += ClassCounts[i];
830     Abc_Print( 1, "NPN CLASS STATISTICS (for %d LUT4 present in the current mapping):\n", nTotal );
831     OtherClasses = 0;
832     for ( i = k = 0; i < 222; i++ )
833     {
834         if ( ClassCounts[i] == 0 )
835             continue;
836 //        if ( 100.0 * ClassCounts[i] / (nTotal+1) < 0.1 ) // do not show anything below 0.1 percent
837 //            continue;
838         OtherClasses += ClassCounts[i];
839         Abc_Print( 1, "%3d: Class %3d :  Count = %6d   (%7.2f %%)   %s\n",
840             ++k, i, ClassCounts[i], 100.0 * ClassCounts[i] / (nTotal+1), pNames[i] );
841     }
842     OtherClasses = nTotal - OtherClasses;
843     Abc_Print( 1, "Other     :  Count = %6d   (%7.2f %%)\n",
844         OtherClasses, 100.0 * OtherClasses / (nTotal+1) );
845     // count the number of LUTs that have MUX function and two fanins with MUX functions
846     OtherClasses = OtherClasses2 = 0;
847     ABC_FREE( p->pRefs );
848     Gia_ManSetRefsMapped( p );
849     Gia_ManForEachLut( p, i )
850     {
851         if ( pLutClass[i] != 109 )
852             continue;
853         Counter = Counter2 = 0;
854         Gia_LutForEachFanin( p, i, iFan, k )
855         {
856             Counter  += (pLutClass[iFan] == 109);
857             Counter2 += (pLutClass[iFan] == 109) && (Gia_ObjRefNumId(p, iFan) == 1);
858         }
859         OtherClasses  += (Counter > 1);
860         OtherClasses2 += (Counter2 > 1);
861 //            Abc_Print( 1, "%d -- ", pLutClass[i] );
862 //            Gia_LutForEachFanin( p, i, iFan, k )
863 //                Abc_Print( 1, "%d ", pLutClass[iFan] );
864 //            Abc_Print( 1, "\n" );
865     }
866     ABC_FREE( p->pRefs );
867     Abc_Print( 1, "Approximate number of 4:1 MUX structures: All = %6d  (%7.2f %%)  MFFC = %6d  (%7.2f %%)\n",
868         OtherClasses,  100.0 * OtherClasses  / (nTotal+1),
869         OtherClasses2, 100.0 * OtherClasses2 / (nTotal+1) );
870     ABC_FREE( pLutClass );
871 }
872 
873 
874 /**Function*************************************************************
875 
876   Synopsis    [Collects internal nodes and boxes in the DFS order.]
877 
878   Description []
879 
880   SideEffects []
881 
882   SeeAlso     []
883 
884 ***********************************************************************/
Gia_ManDfsCollect_rec(Gia_Man_t * p,Gia_Obj_t * pObj,Vec_Int_t * vObjs)885 void Gia_ManDfsCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs )
886 {
887     if ( Gia_ObjIsTravIdCurrent( p, pObj ) )
888         return;
889     Gia_ObjSetTravIdCurrent( p, pObj );
890     if ( Gia_ObjIsCi(pObj) )
891     {
892         Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
893         if ( pManTime )
894         {
895             int i, iFirst, nTerms, iBox;
896             iBox = Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) );
897             if ( iBox >= 0 ) // pObj is a box input
898             {
899                 // mark box outputs
900                 iFirst = Tim_ManBoxOutputFirst( pManTime, iBox );
901                 nTerms = Tim_ManBoxOutputNum( pManTime, iBox );
902                 for ( i = 0; i < nTerms; i++ )
903                 {
904                     pObj = Gia_ManCi( p, iFirst + i );
905                     Gia_ObjSetTravIdCurrent( p, pObj );
906                 }
907                 // traverse box inputs
908                 iFirst = Tim_ManBoxInputFirst( pManTime, iBox );
909                 nTerms = Tim_ManBoxInputNum( pManTime, iBox );
910                 for ( i = 0; i < nTerms; i++ )
911                 {
912                     pObj = Gia_ManCo( p, iFirst + i );
913                     Gia_ManDfsCollect_rec( p, pObj, vObjs );
914                 }
915                 // save the box
916                 Vec_IntPush( vObjs, -iBox-1 );
917             }
918         }
919         return;
920     }
921     else if ( Gia_ObjIsCo(pObj) )
922     {
923         Gia_ManDfsCollect_rec( p, Gia_ObjFanin0(pObj), vObjs );
924     }
925     else if ( Gia_ObjIsAnd(pObj) )
926     {
927         int iFan, k, iObj = Gia_ObjId(p, pObj);
928         if ( Gia_ManHasMapping(p) )
929         {
930             assert( Gia_ObjIsLut(p, iObj) );
931             Gia_LutForEachFanin( p, iObj, iFan, k )
932                 Gia_ManDfsCollect_rec( p, Gia_ManObj(p, iFan), vObjs );
933         }
934         else
935         {
936             Gia_ManDfsCollect_rec( p, Gia_ObjFanin0(pObj), vObjs );
937             Gia_ManDfsCollect_rec( p, Gia_ObjFanin1(pObj), vObjs );
938         }
939         // save the object
940         Vec_IntPush( vObjs, iObj );
941     }
942     else if ( !Gia_ObjIsConst0(pObj) )
943         assert( 0 );
944 }
Gia_ManDfsCollect(Gia_Man_t * p)945 Vec_Int_t * Gia_ManDfsCollect( Gia_Man_t * p )
946 {
947     Vec_Int_t * vObjs = Vec_IntAlloc( Gia_ManObjNum(p) );
948     Gia_Obj_t * pObj; int i;
949     Gia_ManIncrementTravId( p );
950     Gia_ManForEachCo( p, pObj, i )
951         Gia_ManDfsCollect_rec( p, pObj, vObjs );
952     Gia_ManForEachCi( p, pObj, i )
953         Gia_ManDfsCollect_rec( p, pObj, vObjs );
954     return vObjs;
955 }
956 
957 /**Function*************************************************************
958 
959   Synopsis    [Compute arrival/required times.]
960 
961   Description []
962 
963   SideEffects []
964 
965   SeeAlso     []
966 
967 ***********************************************************************/
Gia_ManDfsArrivals(Gia_Man_t * p,Vec_Int_t * vObjs)968 Vec_Int_t * Gia_ManDfsArrivals( Gia_Man_t * p, Vec_Int_t * vObjs )
969 {
970     Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
971     Vec_Int_t * vTimes = Vec_IntStartFull( Gia_ManObjNum(p) );
972     Gia_Obj_t * pObj; int j, Entry, k, iFan;
973     Vec_IntWriteEntry( vTimes, 0, 0 );
974     if ( pManTime )
975     {
976         Tim_ManIncrementTravId( pManTime );
977         Gia_ManForEachCi( p, pObj, j )
978             if ( j < Tim_ManPiNum(pManTime) )
979             {
980                 float arrTime = Tim_ManGetCiArrival( pManTime, j );
981                 Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), (int)arrTime );
982             }
983     }
984     else
985     {
986         Gia_ManForEachCi( p, pObj, j )
987             Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), 0 );
988     }
989     Vec_IntForEachEntry( vObjs, Entry, j )
990     {
991         if ( Entry < 0 ) // box
992         {
993             int Time0, iFirst, nTerms, iBox = -Entry-1;
994             assert( iBox >= 0 );
995             // set arrivals for box inputs
996             iFirst = Tim_ManBoxInputFirst( pManTime, iBox );
997             nTerms = Tim_ManBoxInputNum( pManTime, iBox );
998             for ( k = 0; k < nTerms; k++ )
999             {
1000                 pObj  = Gia_ManCo( p, iFirst + k );
1001                 Time0 = Vec_IntEntry( vTimes, Gia_ObjFaninId0p(p, pObj) );
1002                 assert( Time0 >= 0 );
1003                 Tim_ManSetCoArrival( pManTime, Gia_ObjCioId(pObj), Time0 );
1004             }
1005             // derive arrivals for box outputs
1006             iFirst = Tim_ManBoxOutputFirst( pManTime, iBox );
1007             nTerms = Tim_ManBoxOutputNum( pManTime, iBox );
1008             for ( k = 0; k < nTerms; k++ )
1009             {
1010                 pObj  = Gia_ManCi( p, iFirst + k );
1011                 Time0 = Tim_ManGetCiArrival( pManTime, Gia_ObjCioId(pObj) );
1012                 assert( Time0 >= 0 );
1013                 Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), Time0 );
1014             }
1015         }
1016         else if ( Entry > 0 ) // node
1017         {
1018             int Time0, Time1, TimeMax = 0;
1019             if ( Gia_ManHasMapping(p) )
1020             {
1021                 assert( Gia_ObjIsLut(p, Entry) );
1022                 Gia_LutForEachFanin( p, Entry, iFan, k )
1023                 {
1024                     Time0 = Vec_IntEntry( vTimes, iFan );
1025                     assert( Time0 >= 0 );
1026                     TimeMax = Abc_MaxInt( TimeMax, Time0 );
1027                 }
1028             }
1029             else
1030             {
1031                 pObj  = Gia_ManObj( p, Entry );
1032                 Time0 = Vec_IntEntry( vTimes, Gia_ObjFaninId0(pObj, Entry) );
1033                 Time1 = Vec_IntEntry( vTimes, Gia_ObjFaninId1(pObj, Entry) );
1034                 assert( Time0 >= 0 && Time1 >= 0 );
1035                 TimeMax = Abc_MaxInt( Time0, Time1 );
1036             }
1037             Vec_IntWriteEntry( vTimes, Entry, TimeMax + 10 );
1038         }
1039         else assert( 0 );
1040     }
1041     return vTimes;
1042 }
Gia_ManDfsUpdateRequired(Vec_Int_t * vTimes,int iObj,int Req)1043 static inline void Gia_ManDfsUpdateRequired( Vec_Int_t * vTimes, int iObj, int Req )
1044 {
1045     int *pTime = Vec_IntEntryP( vTimes, iObj );
1046     if (*pTime == -1 || *pTime > Req)
1047         *pTime = Req;
1048 }
Gia_ManDfsRequireds(Gia_Man_t * p,Vec_Int_t * vObjs,int ReqTime)1049 Vec_Int_t * Gia_ManDfsRequireds( Gia_Man_t * p, Vec_Int_t * vObjs, int ReqTime )
1050 {
1051     Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
1052     Vec_Int_t * vTimes = Vec_IntStartFull( Gia_ManObjNum(p) );
1053     Gia_Obj_t * pObj;
1054     int j, Entry, k, iFan, Req;
1055     Vec_IntWriteEntry( vTimes, 0, 0 );
1056     if ( pManTime )
1057     {
1058         int nCoLimit = Gia_ManCoNum(p) - Tim_ManPoNum(pManTime);
1059         Tim_ManIncrementTravId( pManTime );
1060         //Tim_ManInitPoRequiredAll( pManTime, (float)ReqTime );
1061         Gia_ManForEachCo( p, pObj, j )
1062             if ( j >= nCoLimit )
1063             {
1064                 Tim_ManSetCoRequired( pManTime, j, ReqTime );
1065                 Gia_ManDfsUpdateRequired( vTimes, Gia_ObjFaninId0p(p, pObj), ReqTime );
1066             }
1067     }
1068     else
1069     {
1070         Gia_ManForEachCo( p, pObj, j )
1071             Gia_ManDfsUpdateRequired( vTimes, Gia_ObjFaninId0p(p, pObj), ReqTime );
1072     }
1073     Vec_IntForEachEntryReverse( vObjs, Entry, j )
1074     {
1075         if ( Entry < 0 ) // box
1076         {
1077             int iFirst, nTerms, iBox = -Entry-1;
1078             assert( iBox >= 0 );
1079             // set requireds for box outputs
1080             iFirst = Tim_ManBoxOutputFirst( pManTime, iBox );
1081             nTerms = Tim_ManBoxOutputNum( pManTime, iBox );
1082             for ( k = 0; k < nTerms; k++ )
1083             {
1084                 pObj = Gia_ManCi( p, iFirst + k );
1085                 Req  = Vec_IntEntry( vTimes, Gia_ObjId(p, pObj) );
1086                 Req  = Req == -1 ? ReqTime : Req; // dangling box output
1087                 assert( Req >= 0 );
1088                 Tim_ManSetCiRequired( pManTime, Gia_ObjCioId(pObj), Req );
1089             }
1090             // derive requireds for box inputs
1091             iFirst = Tim_ManBoxInputFirst( pManTime, iBox );
1092             nTerms = Tim_ManBoxInputNum( pManTime, iBox );
1093             for ( k = 0; k < nTerms; k++ )
1094             {
1095                 pObj = Gia_ManCo( p, iFirst + k );
1096                 Req  = Tim_ManGetCoRequired( pManTime, Gia_ObjCioId(pObj) );
1097                 assert( Req >= 0 );
1098                 Gia_ManDfsUpdateRequired( vTimes, Gia_ObjFaninId0p(p, pObj), Req );
1099             }
1100         }
1101         else if ( Entry > 0 ) // node
1102         {
1103             Req = Vec_IntEntry(vTimes, Entry) - 10;
1104             assert( Req >= 0 );
1105             if ( Gia_ManHasMapping(p) )
1106             {
1107                 assert( Gia_ObjIsLut(p, Entry) );
1108                 Gia_LutForEachFanin( p, Entry, iFan, k )
1109                     Gia_ManDfsUpdateRequired( vTimes, iFan, Req );
1110             }
1111             else
1112             {
1113                 pObj  = Gia_ManObj( p, Entry );
1114                 Gia_ManDfsUpdateRequired( vTimes, Gia_ObjFaninId0(pObj, Entry), Req );
1115                 Gia_ManDfsUpdateRequired( vTimes, Gia_ObjFaninId1(pObj, Entry), Req );
1116             }
1117         }
1118         else assert( 0 );
1119     }
1120     return vTimes;
1121 }
Gia_ManDfsSlacks(Gia_Man_t * p)1122 Vec_Int_t * Gia_ManDfsSlacks( Gia_Man_t * p )
1123 {
1124     Vec_Int_t * vSlack = Vec_IntStartFull( Gia_ManObjNum(p) );
1125     Vec_Int_t * vObjs  = Gia_ManDfsCollect( p );
1126     if ( Vec_IntSize(vObjs) > 0 )
1127     {
1128         Vec_Int_t * vArrs  = Gia_ManDfsArrivals( p, vObjs );
1129         int Required       = Vec_IntFindMax( vArrs );
1130         Vec_Int_t * vReqs  = Gia_ManDfsRequireds( p, vObjs, Required );
1131         int i, Arr, Req, Arrivals = ABC_INFINITY;
1132         Vec_IntForEachEntry( vReqs, Req, i )
1133             if ( Req != -1 )
1134                 Arrivals = Abc_MinInt( Arrivals, Req );
1135         //if ( Arrivals != 0 )
1136         //    printf( "\nGlobal timing check has failed.\n\n" );
1137         //assert( Arrivals == 0 );
1138         Vec_IntForEachEntryTwo( vArrs, vReqs, Arr, Req, i )
1139         {
1140             if ( !Gia_ObjIsAnd(Gia_ManObj(p, i)) )
1141                 continue;
1142             if ( Gia_ManHasMapping(p) && !Gia_ObjIsLut(p, i) )
1143                 continue;
1144             assert( Arr <= Req );
1145             Vec_IntWriteEntry( vSlack, i, Req - Arr );
1146         }
1147         Vec_IntFree( vArrs );
1148         Vec_IntFree( vReqs );
1149     }
1150     Vec_IntFree( vObjs );
1151     return vSlack;
1152 }
Gia_ManDfsSlacksPrint(Gia_Man_t * p)1153 void Gia_ManDfsSlacksPrint( Gia_Man_t * p )
1154 {
1155     Vec_Int_t * vCounts, * vSlacks = Gia_ManDfsSlacks( p );
1156     int i, Entry, nRange, nTotal;
1157     if ( Vec_IntSize(vSlacks) == 0 )
1158     {
1159         printf( "Network contains no internal objects.\n" );
1160         Vec_IntFree( vSlacks );
1161         return;
1162     }
1163     // compute slacks
1164     Vec_IntForEachEntry( vSlacks, Entry, i )
1165         if ( Entry != -1 )
1166             Vec_IntWriteEntry( vSlacks, i, Entry/10 );
1167     nRange = Vec_IntFindMax( vSlacks );
1168     // count items
1169     vCounts = Vec_IntStart( nRange + 1 );
1170     Vec_IntForEachEntry( vSlacks, Entry, i )
1171         if ( Entry != -1 )
1172             Vec_IntAddToEntry( vCounts, Entry, 1 );
1173     // print slack ranges
1174     nTotal = Vec_IntSum( vCounts );
1175     assert( nTotal > 0 );
1176     Vec_IntForEachEntry( vCounts, Entry, i )
1177     {
1178         printf( "Slack range %3d = ", i );
1179         printf( "[%4d, %4d)   ", 10*i, 10*(i+1) );
1180         printf( "Nodes = %5d  ", Entry );
1181         printf( "(%6.2f %%) ", 100.0*Entry/nTotal );
1182         printf( "\n" );
1183     }
1184     Vec_IntFree( vSlacks );
1185     Vec_IntFree( vCounts );
1186 }
1187 
1188 
1189 /**Function*************************************************************
1190 
1191   Synopsis    [Compute arrival/required times.]
1192 
1193   Description []
1194 
1195   SideEffects []
1196 
1197   SeeAlso     []
1198 
1199 ***********************************************************************/
Gia_ManGenUsed(Gia_Man_t * p,int fBuf)1200 Vec_Bit_t * Gia_ManGenUsed( Gia_Man_t * p, int fBuf )
1201 {
1202     Gia_Obj_t * pObj; int i;
1203     Vec_Bit_t * vUsed = Vec_BitStart( Gia_ManObjNum(p) );
1204     Gia_ManForEachAnd( p, pObj, i )
1205     {
1206         if ( fBuf )
1207             Vec_BitWriteEntry( vUsed, i, 1 );
1208         if ( Gia_ObjFaninC0(pObj) ^ fBuf )
1209             Vec_BitWriteEntry( vUsed, Gia_ObjFaninId0(pObj, i), 1 );
1210         if ( Gia_ObjFaninC1(pObj) ^ fBuf )
1211             Vec_BitWriteEntry( vUsed, Gia_ObjFaninId1(pObj, i), 1 );
1212     }
1213     Gia_ManForEachCo( p, pObj, i )
1214         if ( Gia_ObjFaninC0(pObj) ^ fBuf )
1215             Vec_BitWriteEntry( vUsed, Gia_ObjFaninId0p(p, pObj), 1 );
1216     Vec_BitWriteEntry( vUsed, 0, 0 ); // clean zero
1217     return vUsed;
1218 }
Gia_ManNameIsLegalInVerilog(char * pName)1219 int Gia_ManNameIsLegalInVerilog( char * pName )
1220 {
1221     // identifier ::= simple_identifier | escaped_identifier
1222     // simple_identifier ::= [a-zA-Z_][a-zA-Z0-9_$]
1223     // escaped_identifier ::= \ {Any_ASCII_character_except_white_space} white_space
1224     // white_space ::= space | tab | newline
1225     assert( pName != NULL && *pName != '\0' );
1226     if ( *pName == '\\' )
1227         return 1;
1228     if ( (*pName < 'a' || *pName > 'z') && (*pName < 'A' || *pName > 'Z') && *pName != '_' )
1229         return 0;
1230     while ( *(++pName) )
1231         if ( (*pName < 'a' || *pName > 'z') && (*pName < 'A' || *pName > 'Z') && (*pName < '0' || *pName > '9') && *pName != '_' && *pName != '$' )
1232             return 0;
1233     return 1;
1234 }
Gia_ObjGetDumpName(Vec_Ptr_t * vNames,char c,int i,int d)1235 char * Gia_ObjGetDumpName( Vec_Ptr_t * vNames, char c, int i, int d )
1236 {
1237     static char pBuffer[10000];
1238     if ( vNames )
1239     {
1240         char * pName = (char *)Vec_PtrEntry(vNames, i);
1241         if ( Gia_ManNameIsLegalInVerilog(pName) )
1242             sprintf( pBuffer, "%s", pName );
1243         else
1244             sprintf( pBuffer, "\\%s ", pName );
1245     }
1246     else
1247         sprintf( pBuffer, "%c%0*d%c", c, d, i, c );
1248     return pBuffer;
1249 }
Gia_ManWriteNames(FILE * pFile,char c,int n,Vec_Ptr_t * vNames,int Start,int Skip,Vec_Bit_t * vObjs)1250 void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Start, int Skip, Vec_Bit_t * vObjs )
1251 {
1252     int Digits = Abc_Base10Log( n );
1253     int Length = Start, i, fFirst = 1;
1254     char * pName;
1255     for ( i = 0; i < n; i++ )
1256     {
1257         if ( vObjs && !Vec_BitEntry(vObjs, i) )
1258             continue;
1259         pName = Gia_ObjGetDumpName( vNames, c, i, Digits );
1260         Length += strlen(pName) + 2;
1261         if ( Length > 60 )
1262         {
1263             fprintf( pFile, ",\n    " );
1264             Length = Skip;
1265             fFirst = 1;
1266         }
1267         fprintf( pFile, "%s%s", fFirst ? "":", ", pName );
1268         fFirst = 0;
1269     }
1270 }
Gia_ManDumpVerilog(Gia_Man_t * p,char * pFileName,Vec_Int_t * vObjs)1271 void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs )
1272 {
1273     FILE * pFile;
1274     Gia_Obj_t * pObj;
1275     Vec_Bit_t * vInvs, * vUsed;
1276     int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
1277     int nDigits2 = Abc_Base10Log( Gia_ManPiNum(p) );
1278     int i, k, iObj;
1279     if ( Gia_ManRegNum(p) )
1280     {
1281         printf( "Currently cannot write sequential AIG.\n" );
1282         return;
1283     }
1284     pFile = fopen( pFileName, "wb" );
1285     if ( pFile == NULL )
1286     {
1287         printf( "Cannot open output file \"%s\".\n", pFileName );
1288         return;
1289     }
1290 
1291     vInvs = Gia_ManGenUsed( p, 0 );
1292     vUsed = Gia_ManGenUsed( p, 1 );
1293 
1294     //fprintf( pFile, "// This Verilog file is written by ABC on %s\n\n", Extra_TimeStamp() );
1295 
1296     fprintf( pFile, "module " );
1297     for ( i = 0; i < (int)strlen(p->pName); i++ )
1298         if ( isalpha(p->pName[i]) || isdigit(p->pName[i]) )
1299             fprintf( pFile, "%c", p->pName[i] );
1300         else
1301             fprintf( pFile, "_" );
1302     fprintf( pFile, " (\n    " );
1303     Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL );
1304     fprintf( pFile, ",\n    " );
1305 
1306     Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL );
1307     fprintf( pFile, "\n  );\n\n" );
1308 
1309     fprintf( pFile, "  input " );
1310     Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
1311     fprintf( pFile, ";\n\n" );
1312 
1313     fprintf( pFile, "  output " );
1314     Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
1315     fprintf( pFile, ";\n\n" );
1316 
1317     if ( Vec_BitCount(vUsed) )
1318     {
1319         fprintf( pFile, "  wire " );
1320         Gia_ManWriteNames( pFile, 'n', Gia_ManObjNum(p), NULL, 7, 4, vUsed );
1321         fprintf( pFile, ";\n\n" );
1322     }
1323 
1324     if ( Vec_BitCount(vInvs) )
1325     {
1326         fprintf( pFile, "  wire " );
1327         Gia_ManWriteNames( pFile, 'i', Gia_ManObjNum(p), NULL, 7, 4, vInvs );
1328         fprintf( pFile, ";\n\n" );
1329     }
1330 
1331     if ( vObjs )
1332     {
1333         fprintf( pFile, "  wire " );
1334         Vec_IntForEachEntry( vObjs, iObj, i )
1335             fprintf( pFile, " t_%d%s", i, i==Vec_IntSize(vObjs)-1 ? "" : "," );
1336         fprintf( pFile, ";\n\n" );
1337         Vec_IntForEachEntry( vObjs, iObj, i )
1338         {
1339             fprintf( pFile, "  buf( %s,", Gia_ObjGetDumpName(NULL, 'n', iObj, nDigits) );
1340             fprintf( pFile, " t_%d );\n", i );
1341         }
1342         fprintf( pFile, "\n" );
1343     }
1344 
1345     // input inverters
1346     Gia_ManForEachPi( p, pObj, i )
1347     {
1348         if ( Vec_BitEntry(vUsed, Gia_ObjId(p, pObj)) )
1349         {
1350             fprintf( pFile, "  buf( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) );
1351             fprintf( pFile, " %s );\n",   Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigits2) );
1352         }
1353         if ( Vec_BitEntry(vInvs, Gia_ObjId(p, pObj)) )
1354         {
1355             fprintf( pFile, "  not( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) );
1356             fprintf( pFile, " %s );\n",   Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigits2) );
1357         }
1358     }
1359 
1360     // internal nodes and their inverters
1361     fprintf( pFile, "\n" );
1362     Gia_ManForEachAnd( p, pObj, i )
1363     {
1364         int fSkip = 0;
1365         if ( vObjs )
1366         {
1367             Vec_IntForEachEntry( vObjs, iObj, k )
1368                 if ( iObj == i )
1369                     break;
1370             if ( k < Vec_IntSize(vObjs) )
1371                 fSkip = 1;
1372         }
1373         if ( !fSkip )
1374         {
1375             fprintf( pFile, "  and( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
1376             fprintf( pFile, " %s,",       Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0(pObj, i), nDigits) );
1377             fprintf( pFile, " %s );\n",   Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC1(pObj)? 'i':'n'), Gia_ObjFaninId1(pObj, i), nDigits) );
1378         }
1379         if ( Vec_BitEntry(vInvs, i) )
1380         {
1381             fprintf( pFile, "  not( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) );
1382             fprintf( pFile, " %s );\n",   Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
1383         }
1384     }
1385 
1386     // output drivers
1387     fprintf( pFile, "\n" );
1388     nDigits2 = Abc_Base10Log( Gia_ManPoNum(p) );
1389     Gia_ManForEachPo( p, pObj, i )
1390     {
1391 /*
1392         fprintf( pFile, "  assign %s = ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigits2) );
1393         if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
1394             fprintf( pFile, "1\'b%d;\n", Gia_ObjFaninC0(pObj) );
1395         else
1396             fprintf( pFile, "%s;\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) );
1397 */
1398         fprintf( pFile, "  buf( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigits2) );
1399         if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
1400             fprintf( pFile, "1\'b%d );\n", Gia_ObjFaninC0(pObj) );
1401         else
1402             fprintf( pFile, "%s );\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) );
1403     }
1404 
1405     fprintf( pFile, "\nendmodule\n\n" );
1406     fclose( pFile );
1407 
1408     Vec_BitFree( vInvs );
1409     Vec_BitFree( vUsed );
1410 }
1411 
1412 ////////////////////////////////////////////////////////////////////////
1413 ///                       END OF FILE                                ///
1414 ////////////////////////////////////////////////////////////////////////
1415 
1416 
1417 ABC_NAMESPACE_IMPL_END
1418