1 /**CFile****************************************************************
2 
3   FileName    [wlcNtk.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Verilog parser.]
8 
9   Synopsis    [Network data-structure.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - August 22, 2014.]
16 
17   Revision    [$Id: wlcNtk.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include <math.h>
22 #include "wlc.h"
23 #include "misc/vec/vecWec.h"
24 
25 ABC_NAMESPACE_IMPL_START
26 
27 
28 ////////////////////////////////////////////////////////////////////////
29 ///                        DECLARATIONS                              ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 // object types
33 static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
34     NULL,                  // 00: unknown
35     "pi",                  // 01: primary input
36     "po",                  // 02: primary output (unused)
37     "ff",                  // 03: flop output
38     "bi",                  // 04: flop input (unused)
39     "ff",                  // 05: flop (unused)
40     "const",               // 06: constant
41     "buf",                 // 07: buffer
42     "mux",                 // 08: multiplexer
43     ">>",                  // 09: shift right
44     ">>>",                 // 10: shift right (arithmetic)
45     "<<",                  // 11: shift left
46     "<<<",                 // 12: shift left (arithmetic)
47     "rotR",                // 13: rotate right
48     "rotL",                // 14: rotate left
49     "~",                   // 15: bitwise NOT
50     "&",                   // 16: bitwise AND
51     "|",                   // 17: bitwise OR
52     "^",                   // 18: bitwise XOR
53     "~&",                  // 19: bitwise NAND
54     "~|",                  // 20: bitwise NOR
55     "~^",                  // 21: bitwise NXOR
56     "[:]",                 // 22: bit selection
57     "{,}",                 // 23: bit concatenation
58     "zPad",                // 24: zero padding
59     "sExt",                // 25: sign extension
60     "!",                   // 26: logic NOT
61     "=>",                  // 27: logic implication
62     "&&",                  // 28: logic AND
63     "||",                  // 29: logic OR
64     "^^",                  // 30: logic XOR
65     "==",                  // 31: compare equal
66     "!=",                  // 32: compare not equal
67     "<",                   // 33: compare less
68     ">",                   // 34: compare more
69     "<=",                  // 35: compare less or equal
70     ">=",                  // 36: compare more or equal
71     "&",                   // 37: reduction AND
72     "|",                   // 38: reduction OR
73     "^",                   // 39: reduction XOR
74     "~&",                  // 40: reduction NAND
75     "~|",                  // 41: reduction NOR
76     "~^",                  // 42: reduction NXOR
77     "+",                   // 43: arithmetic addition
78     "-",                   // 44: arithmetic subtraction
79     "*",                   // 45: arithmetic multiplier
80     "/",                   // 46: arithmetic division
81     "%",                   // 47: arithmetic reminder
82     "mod",                 // 48: arithmetic modulus
83     "**",                  // 49: arithmetic power
84     "-",                   // 50: arithmetic minus
85     "sqrt",                // 51: integer square root
86     "squar",               // 52: integer square
87     "table",               // 53: bit table
88     "READ",                // 54: mem read port
89     "WRITE",               // 55: mem write port
90     "addsub",              // 56: adder/subtractor
91     "sel",                 // 57: selector
92     "dec",                 // 58: decoder
93     NULL                   // 58: unused
94 };
95 
Wlc_ObjTypeName(Wlc_Obj_t * p)96 char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; }
97 
98 ////////////////////////////////////////////////////////////////////////
99 ///                     FUNCTION DEFINITIONS                         ///
100 ////////////////////////////////////////////////////////////////////////
101 
102 /**Function*************************************************************
103 
104   Synopsis    []
105 
106   Description []
107 
108   SideEffects []
109 
110   SeeAlso     []
111 
112 ***********************************************************************/
Wlc_ManSetDefaultParams(Wlc_Par_t * pPars)113 void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars )
114 {
115     memset( pPars, 0, sizeof(Wlc_Par_t) );
116     pPars->nBitsAdd      = ABC_INFINITY;   // adder bit-width
117     pPars->nBitsMul      = ABC_INFINITY;   // multiplier bit-widht
118     pPars->nBitsMux      = ABC_INFINITY;   // MUX bit-width
119     pPars->nBitsFlop     = ABC_INFINITY;   // flop bit-width
120     pPars->nIterMax      =         1000;   // the max number of iterations
121     pPars->nLimit        = ABC_INFINITY;   // the max number of signals
122     pPars->fXorOutput    =            1;   // XOR outputs of word-level miter
123     pPars->fCheckClauses =            1;   // Check clauses in the reloaded trace
124     pPars->fPushClauses  =            0;   // Push clauses in the reloaded trace
125     pPars->fMFFC         =            1;   // Refine the entire MFFC of a PPI
126     pPars->fPdra         =            0;   // Use pdr -nct
127     pPars->fLoadTrace    =            1;   // Load previous PDR traces
128     pPars->fProofRefine  =            0;   // Use proof-based refinement
129     pPars->fHybrid       =            1;   // Use a hybrid of CBR and PBR
130     pPars->fCheckCombUnsat =          0;   // Check if ABS becomes comb. unsat
131     pPars->fAbs2         =            0;   // Use UFAR style createAbs
132     pPars->fProofUsePPI  =            0;   // Use PPI values in PBR
133     pPars->fUseBmc3      =            0;   // Run BMC3 in parallel
134     pPars->fShrinkAbs    =            0;   // Shrink Abs with BMC
135     pPars->fShrinkScratch=            0;   // Restart pdr from scratch after shrinking
136     pPars->fVerbose      =            0;   // verbose output`
137     pPars->fPdrVerbose   =            0;   // show verbose PDR output
138 }
139 
140 /**Function*************************************************************
141 
142   Synopsis    [Working with models.]
143 
144   Description []
145 
146   SideEffects []
147 
148   SeeAlso     []
149 
150 ***********************************************************************/
Wlc_NtkAlloc(char * pName,int nObjsAlloc)151 Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc )
152 {
153     Wlc_Ntk_t * p;
154     p = ABC_CALLOC( Wlc_Ntk_t, 1 );
155     p->pName = pName ? Extra_FileNameGeneric( pName ) : NULL;
156     Vec_IntGrow( &p->vPis, 111 );
157     Vec_IntGrow( &p->vPos, 111 );
158     Vec_IntGrow( &p->vCis, 111 );
159     Vec_IntGrow( &p->vCos, 111 );
160     Vec_IntGrow( &p->vFfs, 111 );
161     p->pMemFanin = Mem_FlexStart();
162     p->nObjsAlloc = nObjsAlloc;
163     p->pObjs = ABC_CALLOC( Wlc_Obj_t, p->nObjsAlloc );
164     p->iObj = 1;
165     return p;
166 }
Wlc_ObjSetCi(Wlc_Ntk_t * p,Wlc_Obj_t * pObj)167 void Wlc_ObjSetCi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
168 {
169     assert( Wlc_ObjIsCi(pObj) );
170     assert( Wlc_ObjFaninNum(pObj) == 0 );
171     if ( Wlc_NtkPiNum(p) == Wlc_NtkCiNum(p) || pObj->Type != WLC_OBJ_PI )
172     {
173         pObj->Fanins[1] = Vec_IntSize(&p->vCis);
174         Vec_IntPush( &p->vCis, Wlc_ObjId(p, pObj) );
175     }
176     else // insert in the array of CI at the end of PIs
177     {
178         Wlc_Obj_t * pTemp; int i;
179         Vec_IntInsert( &p->vCis, Wlc_NtkPiNum(p), Wlc_ObjId(p, pObj) );
180         // other CI IDs are invalidated... naive fix!
181         Wlc_NtkForEachCi( p, pTemp, i )
182             pTemp->Fanins[1] = i;
183     }
184     if ( pObj->Type == WLC_OBJ_PI )
185         Vec_IntPush( &p->vPis, Wlc_ObjId(p, pObj) );
186 }
Wlc_ObjSetCo(Wlc_Ntk_t * p,Wlc_Obj_t * pObj,int fFlopInput)187 void Wlc_ObjSetCo( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int fFlopInput )
188 {
189 //    pObj->Fanins[1] = Vec_IntSize(&p->vCos);
190     Vec_IntPush( &p->vCos, Wlc_ObjId(p, pObj) );
191     if ( !fFlopInput )
192         Vec_IntPush( &p->vPos, Wlc_ObjId(p, pObj) );
193     if ( fFlopInput )
194         pObj->fIsFi = 1;
195     else
196         pObj->fIsPo = 1;
197 }
Wlc_ObjAlloc(Wlc_Ntk_t * p,int Type,int Signed,int End,int Beg)198 int Wlc_ObjAlloc( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg )
199 {
200     Wlc_Obj_t * pObj;
201     assert( Type != WLC_OBJ_PO && Type != WLC_OBJ_FI );
202     if ( p->iObj == p->nObjsAlloc )
203     {
204         p->pObjs = ABC_REALLOC( Wlc_Obj_t, p->pObjs, 2 * p->nObjsAlloc );
205         memset( p->pObjs + p->nObjsAlloc, 0, sizeof(Wlc_Obj_t) * p->nObjsAlloc );
206         p->nObjsAlloc *= 2;
207     }
208     pObj = Wlc_NtkObj( p, p->iObj );
209     pObj->Type   = Type;
210     pObj->Signed = Signed;
211     pObj->End    = End;
212     pObj->Beg    = Beg;
213     if ( Wlc_ObjIsCi(pObj) )
214         Wlc_ObjSetCi( p, pObj );
215     p->nObjs[Type]++;
216     return p->iObj++;
217 }
Wlc_ObjCreate(Wlc_Ntk_t * p,int Type,int Signed,int End,int Beg,Vec_Int_t * vFanins)218 int Wlc_ObjCreate( Wlc_Ntk_t * p, int Type, int Signed, int End, int Beg, Vec_Int_t * vFanins )
219 {
220     int iFaninNew = Wlc_ObjAlloc( p, Type, Signed, End, Beg );
221     Wlc_ObjAddFanins( p, Wlc_NtkObj(p, iFaninNew), vFanins );
222     return iFaninNew;
223 }
Wlc_ObjName(Wlc_Ntk_t * p,int iObj)224 char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj )
225 {
226     static char Buffer[100];
227     if ( Wlc_NtkHasNameId(p) && Wlc_ObjNameId(p, iObj) )
228         return Abc_NamStr( p->pManName, Wlc_ObjNameId(p, iObj) );
229     sprintf( Buffer, "n%d", iObj );
230     return Buffer;
231 }
Wlc_ObjUpdateType(Wlc_Ntk_t * p,Wlc_Obj_t * pObj,int Type)232 void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type )
233 {
234     assert( pObj->Type == WLC_OBJ_NONE );
235     p->nObjs[pObj->Type]--;
236     pObj->Type = Type;
237     p->nObjs[pObj->Type]++;
238 }
Wlc_ObjAddFanins(Wlc_Ntk_t * p,Wlc_Obj_t * pObj,Vec_Int_t * vFanins)239 void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins )
240 {
241     assert( pObj->nFanins == 0 );
242     pObj->nFanins = Vec_IntSize(vFanins);
243     // special treatment of CONST, SELECT and TABLE
244     if ( pObj->Type == WLC_OBJ_CONST )
245         pObj->nFanins = 0;
246     else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE )
247         pObj->nFanins = 1;
248     if ( Wlc_ObjHasArray(pObj) )
249         pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) );
250     memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) );
251 }
Wlc_NtkFree(Wlc_Ntk_t * p)252 void Wlc_NtkFree( Wlc_Ntk_t * p )
253 {
254     if ( p->pManName )
255         Abc_NamStop( p->pManName );
256     if ( p->pMemFanin )
257         Mem_FlexStop( p->pMemFanin, 0 );
258     if ( p->pMemTable )
259         Mem_FlexStop( p->pMemTable, 0 );
260     ABC_FREE( p->vPoPairs.pArray );
261     Vec_PtrFreeP( &p->vTables );
262     Vec_WrdFreeP( &p->vLutTruths );
263     ABC_FREE( p->vPis.pArray );
264     ABC_FREE( p->vPos.pArray );
265     ABC_FREE( p->vCis.pArray );
266     ABC_FREE( p->vCos.pArray );
267     ABC_FREE( p->vFfs.pArray );
268     ABC_FREE( p->vFfs2.pArray );
269     Vec_IntFreeP( &p->vInits );
270     Vec_IntFreeP( &p->vArsts );
271     ABC_FREE( p->vTravIds.pArray );
272     ABC_FREE( p->vNameIds.pArray );
273     ABC_FREE( p->vValues.pArray );
274     ABC_FREE( p->vCopies.pArray );
275     ABC_FREE( p->vBits.pArray );
276     ABC_FREE( p->vLevels.pArray );
277     ABC_FREE( p->vRefs.pArray );
278     ABC_FREE( p->pInits );
279     ABC_FREE( p->pObjs );
280     ABC_FREE( p->pName );
281     ABC_FREE( p->pSpec );
282     ABC_FREE( p );
283 }
Wlc_NtkMemUsage(Wlc_Ntk_t * p)284 int Wlc_NtkMemUsage( Wlc_Ntk_t * p )
285 {
286     int Mem = sizeof(Wlc_Ntk_t);
287     Mem += 4 * p->vPis.nCap;
288     Mem += 4 * p->vPos.nCap;
289     Mem += 4 * p->vCis.nCap;
290     Mem += 4 * p->vCos.nCap;
291     Mem += 4 * p->vFfs.nCap;
292     Mem += 4 * p->vFfs2.nCap;
293     Mem += sizeof(Wlc_Obj_t) * p->nObjsAlloc;
294     Mem += Abc_NamMemUsed(p->pManName);
295     Mem += Mem_FlexReadMemUsage(p->pMemFanin);
296     return Mem;
297 }
298 
299 /**Function*************************************************************
300 
301   Synopsis    [Assigns object levels.]
302 
303   Description []
304 
305   SideEffects []
306 
307   SeeAlso     []
308 
309 ***********************************************************************/
Wlc_NtkCreateLevels_(Wlc_Ntk_t * p)310 int Wlc_NtkCreateLevels_( Wlc_Ntk_t * p )
311 {
312     Wlc_Obj_t * pObj;
313     int i, k, iFanin, Level, LevelMax = 0;
314     Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
315     Wlc_NtkForEachObj( p, pObj, i )
316     {
317         Level = 0;
318         Wlc_ObjForEachFanin( pObj, iFanin, k )
319             Level = Abc_MaxInt( Level, Wlc_ObjLevelId(p, iFanin) + 1 );
320         Vec_IntWriteEntry( &p->vLevels, i, Level );
321         LevelMax = Abc_MaxInt( LevelMax, Level );
322     }
323     return LevelMax;
324 }
Wlc_NtkCreateLevelsRev(Wlc_Ntk_t * p)325 int Wlc_NtkCreateLevelsRev( Wlc_Ntk_t * p )
326 {
327     Wlc_Obj_t * pObj;
328     int i, k, iFanin, Level, LevelMax = 0;
329     Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
330     Wlc_NtkForEachObjReverse( p, pObj, i )
331     {
332         if ( Wlc_ObjIsCi(pObj) )
333             continue;
334         Level = Wlc_ObjLevel(p, pObj) + 1;
335         Wlc_ObjForEachFanin( pObj, iFanin, k )
336             Vec_IntUpdateEntry( &p->vLevels, iFanin, Level );
337         LevelMax = Abc_MaxInt( LevelMax, Level );
338     }
339     // reverse the values
340     Wlc_NtkForEachObj( p, pObj, i )
341         Vec_IntWriteEntry( &p->vLevels, i, LevelMax - Wlc_ObjLevelId(p, i) );
342     Wlc_NtkForEachCi( p, pObj, i )
343         Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), 0 );
344     //Wlc_NtkForEachObj( p, pObj, i )
345     //    printf( "%d -> %d\n", i, Wlc_ObjLevelId(p, i) );
346     return LevelMax;
347 }
348 
349 /**Function*************************************************************
350 
351   Synopsis    [Assigns object levels.]
352 
353   Description []
354 
355   SideEffects []
356 
357   SeeAlso     []
358 
359 ***********************************************************************/
Wlc_NtkCreateLevels_rec(Wlc_Ntk_t * p,Wlc_Obj_t * pObj)360 void Wlc_NtkCreateLevels_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
361 {
362     int k, iFanin, Level = 0, iObj = Wlc_ObjId(p, pObj);
363     if ( Wlc_ObjIsCi(pObj) || Wlc_ObjIsFf(p, iObj) || Wlc_ObjFaninNum(pObj) == 0 || Wlc_ObjLevel(p, pObj) > 0 )
364         return;
365     Wlc_ObjForEachFanin( pObj, iFanin, k ) if ( iFanin )
366         Wlc_NtkCreateLevels_rec( p, Wlc_NtkObj(p, iFanin) );
367     Wlc_ObjForEachFanin( pObj, iFanin, k ) if ( iFanin )
368         Level = Abc_MaxInt( Level, Wlc_ObjLevelId(p, iFanin) );
369     Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), Level + 1 );
370 }
Wlc_NtkCreateLevels(Wlc_Ntk_t * p)371 int Wlc_NtkCreateLevels( Wlc_Ntk_t * p )
372 {
373     Wlc_Obj_t * pObj;  int i, LeveMax = 0;
374     Vec_IntFill( &p->vLevels, Wlc_NtkObjNumMax(p), 0 );
375     Wlc_NtkForEachObj( p, pObj, i )
376         Wlc_NtkCreateLevels_rec( p, pObj );
377     Wlc_NtkForEachObj( p, pObj, i )
378         if ( !Wlc_ObjIsCi(pObj) && Wlc_ObjFaninNum(pObj) )
379             Vec_IntAddToEntry( &p->vLevels, i, 1 );
380     LeveMax = Vec_IntFindMax( &p->vLevels );
381     Wlc_NtkForEachFf2( p, pObj, i )
382         Vec_IntWriteEntry( &p->vLevels, Wlc_ObjId(p, pObj), LeveMax+1 );
383     //Wlc_NtkPrintObjects( p );
384     return LeveMax+1;
385 }
Wlc_NtkRemapLevels(Wlc_Ntk_t * p,Vec_Int_t * vObjs,int nLevels)386 int Wlc_NtkRemapLevels( Wlc_Ntk_t * p, Vec_Int_t * vObjs, int nLevels )
387 {
388     int i, k, iFanin, iObj, Entry, Level = 0, Res = nLevels;
389     Vec_Int_t * vMap  = Vec_IntStart( nLevels+1 );
390     Vec_Int_t * vUsed = Vec_IntStart( nLevels+1 );
391     // mark used levels
392     Vec_IntWriteEntry( vUsed, nLevels, 1 );
393     Vec_IntForEachEntry( vObjs, iObj, i )
394     {
395         Vec_IntWriteEntry( vUsed, Wlc_ObjLevelId(p, iObj), 1 );
396         Wlc_ObjForEachFanin( Wlc_NtkObj(p, iObj), iFanin, k ) if ( iFanin )
397             Vec_IntWriteEntry( vUsed, Wlc_ObjLevelId(p, iFanin), 1 );
398     }
399     // create level map
400     Vec_IntForEachEntry( vUsed, Entry, i )
401         if ( Entry )
402             Vec_IntWriteEntry( vMap, i, Level++ );
403     //printf( "Total used levels %d -> %d\n", nLevels, Level );
404     // remap levels
405     Vec_IntForEachEntry( &p->vLevels, Level, i )
406     {
407         if ( Vec_IntEntry(vUsed, Level) )
408             Vec_IntWriteEntry( &p->vLevels, i, Vec_IntEntry(vMap, Level) );
409         else
410             Vec_IntWriteEntry( &p->vLevels, i, -1 );
411     }
412     Res = Vec_IntEntry( vMap, nLevels );
413     Vec_IntFree( vUsed );
414     Vec_IntFree( vMap );
415     return Res;
416 }
417 
418 /**Function*************************************************************
419 
420   Synopsis    [Collects statistics for each side of the miter.]
421 
422   Description []
423 
424   SideEffects []
425 
426   SeeAlso     []
427 
428 ***********************************************************************/
Wlc_NtkCollectStats(Wlc_Ntk_t * p,int nObjs[2][WLC_OBJ_NUMBER])429 void Wlc_NtkCollectStats( Wlc_Ntk_t * p, int nObjs[2][WLC_OBJ_NUMBER] )
430 {
431     Wlc_Obj_t * pObj;
432     int n, i;
433     if ( Wlc_NtkPoNum(p) != 2 )
434         return;
435     for ( n = 0; n < 2; n++ )
436     {
437         Wlc_NtkMarkCone( p, n, 1, 1, 0 );
438         Wlc_NtkForEachObj( p, pObj, i )
439             if ( pObj->Mark )
440                 nObjs[n][pObj->Type]++;
441     }
442     Wlc_NtkCleanMarks( p );
443 }
Wlc_NtkCountRealPis(Wlc_Ntk_t * p)444 int Wlc_NtkCountRealPis( Wlc_Ntk_t * p )
445 {
446     Wlc_Obj_t * pObj;
447     int i, Count = 0;
448     Wlc_NtkMarkCone( p, -1, -1, 1, 0 );
449     Wlc_NtkForEachPi( p, pObj, i )
450         Count += pObj->Mark;
451     Wlc_NtkCleanMarks( p );
452     return Count;
453 }
454 
455 /**Function*************************************************************
456 
457   Synopsis    [Prints distribution of operator types.]
458 
459   Description []
460 
461   SideEffects []
462 
463   SeeAlso     []
464 
465 ***********************************************************************/
Vec_WrdSelectSortCost2(word * pArray,int nSize,word * pCosts)466 static inline void Vec_WrdSelectSortCost2( word * pArray, int nSize, word * pCosts )
467 {
468     int i, j, best_i;
469     for ( i = 0; i < nSize-1; i++ )
470     {
471         best_i = i;
472         for ( j = i+1; j < nSize; j++ )
473             if ( pCosts[j] < pCosts[best_i] )
474                 best_i = j;
475         ABC_SWAP( word, pArray[i], pArray[best_i] );
476         ABC_SWAP( word, pCosts[i], pCosts[best_i] );
477     }
478 }
Wlc_NtkPrintDistribMakeSign(int s,int s0,int s1)479 static inline word Wlc_NtkPrintDistribMakeSign( int s, int s0, int s1 )
480 {
481     return ((word)s1 << 42) | ((word)s0 << 21) | (word)s;
482 }
Wlc_NtkPrintDistribFromSign(word sss,int * s,int * s0,int * s1)483 static inline void Wlc_NtkPrintDistribFromSign( word sss, int * s, int * s0, int * s1 )
484 {
485     *s1 =  (int)(sss >> 42);  *s0 = (int)(sss >> 21) & 0x1FFFFF;  *s  =  (int)sss & 0x1FFFFF;
486 }
Wlc_NtkPrintDistribAddOne(Vec_Ptr_t * vTypes,Vec_Ptr_t * vOccurs,int Type,word Sign)487 static inline void Wlc_NtkPrintDistribAddOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Type, word Sign )
488 {
489     Vec_Wrd_t * vType  = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, Type );
490     Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, Type );
491     word Entry; int i;
492     Vec_WrdForEachEntry( vType, Entry, i )
493         if ( Entry == Sign )
494         {
495             Vec_WrdAddToEntry( vOccur, i, 1 );
496             return;
497         }
498     Vec_WrdPush( vType, Sign );
499     Vec_WrdPush( vOccur, 1 );
500 }
Wlc_NtkPrintDistribSortOne(Vec_Ptr_t * vTypes,Vec_Ptr_t * vOccurs,int Type)501 void Wlc_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Type )
502 {
503     Vec_Wrd_t * vType  = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, Type );
504     Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, Type );
505     Vec_WrdSelectSortCost2( Vec_WrdArray(vType), Vec_WrdSize(vType), Vec_WrdArray(vOccur) );
506     Vec_WrdReverseOrder( vType );
507     Vec_WrdReverseOrder( vOccur );
508 }
Wlc_NtkPrintDistrib(Wlc_Ntk_t * p,int fTwoSides,int fVerbose)509 void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fTwoSides, int fVerbose )
510 {
511     int nObjs[2][WLC_OBJ_NUMBER] = {{0}}; // counter of objects of each type
512     Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0;
513     Vec_Ptr_t * vTypes, * vOccurs;
514     Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER );
515     word Sign;
516     int i, k, s, s0, s1;
517     if ( Wlc_NtkPoNum(p) != 2 )
518         fTwoSides = 0;
519     if ( fTwoSides )
520         Wlc_NtkCollectStats( p, nObjs );
521     // allocate statistics arrays
522     vTypes  = Vec_PtrStart( WLC_OBJ_NUMBER );
523     vOccurs = Vec_PtrStart( WLC_OBJ_NUMBER );
524     for ( i = 0; i < WLC_OBJ_NUMBER; i++ )
525         Vec_PtrWriteEntry( vTypes, i, Vec_WrdAlloc(16) );
526     for ( i = 0; i < WLC_OBJ_NUMBER; i++ )
527         Vec_PtrWriteEntry( vOccurs, i, Vec_WrdAlloc(16) );
528     // add nodes
529     Wlc_NtkForEachObj( p, pObj, i )
530     {
531 //        char * pName = Wlc_ObjName(p, i);
532         if ( Wlc_ObjSign(pObj) > 0x1FFFFF )
533             printf( "Object %6d has range %d, which is reduced to %d in the statistics.\n",
534                 i, Wlc_ObjRange(pObj), Wlc_ObjRange(pObj) & 0xFFFFF );
535         if ( pObj->Beg )
536         {
537             if ( pObjRange == NULL )
538                 pObjRange = pObj;
539             nCountRange++;
540         }
541         // 0-input types
542         if ( Wlc_ObjIsCi(pObj) || pObj->Type == WLC_OBJ_CONST || pObj->Type == WLC_OBJ_BIT_CONCAT )
543             Sign = Wlc_NtkPrintDistribMakeSign( Wlc_ObjSign(pObj), 0, 0 );
544         // 1-input types
545         else if ( pObj->Type == WLC_OBJ_BUF    || pObj->Type == WLC_OBJ_BIT_SELECT  || pObj->Type == WLC_OBJ_TABLE ||
546              pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT ||
547              pObj->Type == WLC_OBJ_BIT_NOT     || pObj->Type == WLC_OBJ_LOGIC_NOT   || pObj->Type == WLC_OBJ_ARI_MINUS )
548             Sign = Wlc_NtkPrintDistribMakeSign( Wlc_ObjSign(pObj), Wlc_ObjSign(Wlc_ObjFanin0(p, pObj)), 0 );
549         // 2-input types (including MUX)
550         else if ( Wlc_ObjFaninNum(pObj) == 0 )
551             printf( "Object %d with name \"%s\" has type 0. Looks like it was declared by not defined...\n", i, Wlc_ObjName(p, i) );
552         else if ( Wlc_ObjFaninNum(pObj) == 1 )
553             Sign = Wlc_NtkPrintDistribMakeSign( Wlc_ObjSign(pObj), Wlc_ObjSign(Wlc_ObjFanin0(p, pObj)), 0 );
554         else
555         {
556             assert( Wlc_ObjFaninNum(pObj) >= 2 );
557             Sign = Wlc_NtkPrintDistribMakeSign( Wlc_ObjSign(pObj), Wlc_ObjFaninId(pObj, 0) ? Wlc_ObjSign(Wlc_ObjFanin0(p, pObj)) : 0, Wlc_ObjFaninId(pObj, 1) ? Wlc_ObjSign(Wlc_ObjFanin1(p, pObj)) : 0 );
558         }
559         // add to storage
560         Wlc_NtkPrintDistribAddOne( vTypes, vOccurs, pObj->Type, Sign );
561         // count the number of AIG nodes
562         if ( pObj->Type == WLC_OBJ_MUX )
563             Vec_IntAddToEntry( vAnds, WLC_OBJ_MUX,      3 * Wlc_ObjRange(pObj) * (Wlc_ObjFaninNum(pObj) - 2) );
564         else if ( pObj->Type == WLC_OBJ_SHIFT_R )
565             Vec_IntAddToEntry( vAnds, WLC_OBJ_SHIFT_R,  Abc_MinInt(Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Abc_Base2Log(Wlc_ObjRange(pObj))) * 3 );
566         else if ( pObj->Type == WLC_OBJ_SHIFT_RA )
567             Vec_IntAddToEntry( vAnds, WLC_OBJ_SHIFT_RA, Wlc_ObjRange(pObj) * Abc_MinInt(Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Abc_Base2Log(Wlc_ObjRange(pObj))) * 3 );
568         else if ( pObj->Type == WLC_OBJ_SHIFT_L )
569             Vec_IntAddToEntry( vAnds, WLC_OBJ_SHIFT_L,  Wlc_ObjRange(pObj) * Abc_MinInt(Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Abc_Base2Log(Wlc_ObjRange(pObj))) * 3 );
570         else if ( pObj->Type == WLC_OBJ_SHIFT_LA )
571             Vec_IntAddToEntry( vAnds, WLC_OBJ_SHIFT_LA, Wlc_ObjRange(pObj) * Abc_MinInt(Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Abc_Base2Log(Wlc_ObjRange(pObj))) * 3 );
572         else if ( pObj->Type == WLC_OBJ_ROTATE_R )
573             Vec_IntAddToEntry( vAnds, WLC_OBJ_ROTATE_R, Wlc_ObjRange(pObj) * Abc_MinInt(Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Abc_Base2Log(Wlc_ObjRange(pObj))) * 3 );
574         else if ( pObj->Type == WLC_OBJ_ROTATE_L )
575             Vec_IntAddToEntry( vAnds, WLC_OBJ_ROTATE_L, Wlc_ObjRange(pObj) * Abc_MinInt(Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Abc_Base2Log(Wlc_ObjRange(pObj))) * 3 );
576         else if ( pObj->Type == WLC_OBJ_BIT_NOT )
577             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_NOT, 0 );
578         else if ( pObj->Type == WLC_OBJ_BIT_AND )
579             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_AND,      Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
580         else if ( pObj->Type == WLC_OBJ_BIT_OR )
581             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_OR,       Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
582         else if ( pObj->Type == WLC_OBJ_BIT_XOR )
583             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_XOR,  3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
584         else if ( pObj->Type == WLC_OBJ_BIT_NAND )
585             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_NAND,     Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
586         else if ( pObj->Type == WLC_OBJ_BIT_NOR )
587             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_NOR,      Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
588         else if ( pObj->Type == WLC_OBJ_BIT_NXOR )
589             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_NXOR, 3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
590         else if ( pObj->Type == WLC_OBJ_BIT_SELECT )
591             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_SELECT, 0 );
592         else if ( pObj->Type == WLC_OBJ_BIT_CONCAT )
593             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_CONCAT, 0 );
594         else if ( pObj->Type == WLC_OBJ_BIT_ZEROPAD )
595             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_ZEROPAD, 0 );
596         else if ( pObj->Type == WLC_OBJ_BIT_SIGNEXT )
597             Vec_IntAddToEntry( vAnds, WLC_OBJ_BIT_SIGNEXT, 0 );
598         else if ( pObj->Type == WLC_OBJ_LOGIC_NOT )
599             Vec_IntAddToEntry( vAnds, WLC_OBJ_LOGIC_NOT,        Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
600         else if ( pObj->Type == WLC_OBJ_LOGIC_IMPL )
601             Vec_IntAddToEntry( vAnds, WLC_OBJ_LOGIC_IMPL,       Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) + Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) - 1 );
602         else if ( pObj->Type == WLC_OBJ_LOGIC_AND )
603             Vec_IntAddToEntry( vAnds, WLC_OBJ_LOGIC_AND,        Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) + Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) - 1 );
604         else if ( pObj->Type == WLC_OBJ_LOGIC_OR )
605             Vec_IntAddToEntry( vAnds, WLC_OBJ_LOGIC_OR,         Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) + Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) - 1 );
606         else if ( pObj->Type == WLC_OBJ_LOGIC_XOR )
607             Vec_IntAddToEntry( vAnds, WLC_OBJ_LOGIC_XOR,        Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) + Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) + 1 );
608         else if ( pObj->Type == WLC_OBJ_COMP_EQU )
609             Vec_IntAddToEntry( vAnds, WLC_OBJ_COMP_EQU,     4 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
610         else if ( pObj->Type == WLC_OBJ_COMP_NOTEQU )
611             Vec_IntAddToEntry( vAnds, WLC_OBJ_COMP_NOTEQU,  4 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
612         else if ( pObj->Type == WLC_OBJ_COMP_LESS )
613             Vec_IntAddToEntry( vAnds, WLC_OBJ_COMP_LESS,    6 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 6 );
614         else if ( pObj->Type == WLC_OBJ_COMP_MORE )
615             Vec_IntAddToEntry( vAnds, WLC_OBJ_COMP_MORE,    6 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 6 );
616         else if ( pObj->Type == WLC_OBJ_COMP_LESSEQU )
617             Vec_IntAddToEntry( vAnds, WLC_OBJ_COMP_LESSEQU, 6 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 6 );
618         else if ( pObj->Type == WLC_OBJ_COMP_MOREEQU )
619             Vec_IntAddToEntry( vAnds, WLC_OBJ_COMP_MOREEQU, 6 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 6 );
620         else if ( pObj->Type == WLC_OBJ_REDUCT_AND )
621             Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_AND,       Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
622         else if ( pObj->Type == WLC_OBJ_REDUCT_OR )
623             Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_OR,        Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
624         else if ( pObj->Type == WLC_OBJ_REDUCT_XOR )
625             Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_XOR,   3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
626         else if ( pObj->Type == WLC_OBJ_REDUCT_NAND )
627             Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NAND,      Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
628         else if ( pObj->Type == WLC_OBJ_REDUCT_NOR )
629             Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NOR,       Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 1 );
630         else if ( pObj->Type == WLC_OBJ_REDUCT_NXOR )
631             Vec_IntAddToEntry( vAnds, WLC_OBJ_REDUCT_NXOR,  3 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 3 );
632         else if ( pObj->Type == WLC_OBJ_ARI_ADD )
633             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_ADD,      9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
634         else if ( pObj->Type == WLC_OBJ_ARI_SUB )
635             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SUB,      9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
636         else if ( pObj->Type == WLC_OBJ_ARI_MULTI )
637             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_MULTI,    9 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)) );
638         else if ( pObj->Type == WLC_OBJ_ARI_DIVIDE )
639             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_DIVIDE,  13 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 19 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) + 10 );
640         else if ( pObj->Type == WLC_OBJ_ARI_REM )
641             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_REM,     13 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 7 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 2  );
642         else if ( pObj->Type == WLC_OBJ_ARI_MODULUS )
643             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_MODULUS, 13 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 7 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) - 2  );
644         else if ( pObj->Type == WLC_OBJ_ARI_POWER )
645             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_POWER,   10 * (int)pow((double)Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)),(double)Wlc_ObjRange(Wlc_ObjFanin0(p, pObj))) );
646         else if ( pObj->Type == WLC_OBJ_ARI_MINUS )
647             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_MINUS,    4 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
648         else if ( pObj->Type == WLC_OBJ_ARI_SQRT )
649             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQRT,    11 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) / 8 + 5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) / 2 - 5  );
650         else if ( pObj->Type == WLC_OBJ_ARI_SQUARE )
651             Vec_IntAddToEntry( vAnds, WLC_OBJ_ARI_SQUARE,   5 * Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) * Wlc_ObjRange(Wlc_ObjFanin1(p, pObj))  );
652     }
653     if ( nCountRange && Vec_IntSize(&p->vNameIds) > 0 )
654     {
655         printf( "Warning: %d objects of the design have non-zero-based ranges.\n", nCountRange );
656         printf( "In particular, object %6d with name \"%s\" has range %d=[%d:%d]\n", Wlc_ObjId(p, pObjRange),
657             Abc_NamStr(p->pManName, Wlc_ObjNameId(p, Wlc_ObjId(p, pObjRange))), Wlc_ObjRange(pObjRange), pObjRange->End, pObjRange->Beg );
658     }
659     // print by occurrence
660     printf( "ID  :  name  occurrence%s    and2 (occurrence)<output_range>=<input_range>.<input_range> ...\n", fTwoSides ? "     Left Share Right":"" );
661     for ( i = 0; i < WLC_OBJ_NUMBER; i++ )
662     {
663         Vec_Wrd_t * vType  = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i );
664         Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, i );
665         if ( p->nObjs[i] == 0 )
666             continue;
667         printf( "%2d  :  %-8s  %6d", i, Wlc_Names[i], p->nObjs[i] );
668         if ( fTwoSides )
669         {
670             int nTotal = i == WLC_OBJ_PI ? Wlc_NtkCountRealPis(p) : p->nObjs[i];
671             printf( "   " );
672             printf( "%6d", nObjs[0][i] );
673             printf( "%6d", nObjs[0][i]+nObjs[1][i]-nTotal );
674             printf( "%6d", nObjs[1][i] );
675         }
676         printf( "%8d ", Vec_IntEntry(vAnds, i) );
677         // sort by occurence
678         Wlc_NtkPrintDistribSortOne( vTypes, vOccurs, i );
679         Vec_WrdForEachEntry( vType, Sign, k )
680         {
681             Wlc_NtkPrintDistribFromSign( Sign, &s, &s0, &s1 );
682             if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) )
683             {
684                 printf( "\n                                " );
685                 if ( fTwoSides )
686                     printf( "                     " );
687             }
688             printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) );
689             printf( "%s%d",      Abc_LitIsCompl(s)?"-":"",  Abc_Lit2Var(s) );
690             if ( s0 )
691                 printf( "=%s%d", Abc_LitIsCompl(s0)?"-":"", Abc_Lit2Var(s0) );
692             if ( s1 )
693                 printf( ".%s%d", Abc_LitIsCompl(s1)?"-":"", Abc_Lit2Var(s1) );
694             printf( " " );
695         }
696         printf( "\n" );
697     }
698     Vec_VecFree( (Vec_Vec_t *)vTypes );
699     Vec_VecFree( (Vec_Vec_t *)vOccurs );
700     Vec_IntFree( vAnds );
701 }
Wlc_NtkPrintNode(Wlc_Ntk_t * p,Wlc_Obj_t * pObj)702 void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
703 {
704     printf( "%8d  :  ", Wlc_ObjId(p, pObj) );
705     if ( Vec_IntSize(&p->vLevels) )
706         printf( "Lev = %2d  ", Vec_IntEntry(&p->vLevels, Wlc_ObjId(p,pObj)) );
707     printf( "%6d%s = ", Wlc_ObjRange(pObj), Wlc_ObjIsSigned(pObj) ? "s" : " " );
708     if ( pObj->Type == WLC_OBJ_PI )
709     {
710         printf( "            PI                   :    %-12s\n", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
711         return;
712     }
713     if ( pObj->Type == WLC_OBJ_FO )
714     {
715         printf( "            FO                   :    %-12s = %-12s\n", Wlc_ObjName(p, Wlc_ObjId(p, pObj)), Wlc_ObjName(p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj))) );
716         return;
717     }
718     if ( pObj->Type != WLC_OBJ_CONST && Wlc_ObjFaninNum(pObj) == 0 )
719     {
720         printf( "Unknown object without fanins    :    %-12s\n", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
721         return;
722     }
723     if ( pObj->Type != WLC_OBJ_CONST )
724     {
725         printf( "%6d%s  %5s  ",  Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin0(p, pObj)) ? "s" : " ", Wlc_Names[(int)pObj->Type] );
726         if ( Wlc_ObjFaninNum(pObj) > 1 )
727             printf( "%6d%s ",       Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin1(p, pObj)) ? "s" : " " );
728         else
729             printf( "        " );
730         if ( Wlc_ObjFaninNum(pObj) > 2 )
731             printf( "%6d%s ",       Wlc_ObjRange(Wlc_ObjFanin2(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin2(p, pObj)) ? "s" : " " );
732         else
733             printf( "        " );
734     }
735     else
736         printf( "                                " );
737     printf( " :    " );
738     printf( "%-12s",   Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
739     if ( pObj->Type == WLC_OBJ_CONST )
740     {
741         printf( " = %d\'%sh", Wlc_ObjRange(pObj), Wlc_ObjIsSigned(pObj) ? "s":"" );
742         if ( pObj->fXConst )
743         {
744             int k;
745             for ( k = 0; k < (Wlc_ObjRange(pObj) + 3) / 4; k++ )
746                 printf( "x" );
747         }
748         else
749             Abc_TtPrintHexArrayRev( stdout, (word *)Wlc_ObjConstValue(pObj), (Wlc_ObjRange(pObj) + 3) / 4 );
750     }
751     else
752     {
753         printf( " =  %-12s  %5s  ", Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)), Wlc_Names[(int)pObj->Type] );
754         if ( Wlc_ObjFaninNum(pObj) > 1 )
755             printf( "%-12s ",       Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) );
756         else
757             printf( "             " );
758         if ( Wlc_ObjFaninNum(pObj) > 2 )
759             printf( "%-12s ",       Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)) );
760     }
761     printf( "\n" );
762 }
Wlc_NtkPrintNodeArray(Wlc_Ntk_t * p,Vec_Int_t * vArray)763 void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray )
764 {
765     Wlc_Obj_t * pObj;
766     int i;
767     Wlc_NtkForEachObjVec( vArray, p, pObj, i )
768         Wlc_NtkPrintNode( p, pObj );
769 }
Wlc_NtkPrintNodes(Wlc_Ntk_t * p,int Type)770 void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type )
771 {
772     Wlc_Obj_t * pObj;
773     int i, Counter = 0;
774     printf( "Operation %s\n", Wlc_Names[Type] );
775     Wlc_NtkForEachObj( p, pObj, i )
776     {
777         if ( (int)pObj->Type != Type )
778             continue;
779         printf( "%8d  :", Counter++ );
780         Wlc_NtkPrintNode( p, pObj );
781     }
782 }
Wlc_NtkPrintStats(Wlc_Ntk_t * p,int fDistrib,int fTwoSides,int fVerbose)783 void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fTwoSides, int fVerbose )
784 {
785     int i;
786     printf( "%-20s : ",        p->pName );
787     printf( "PI = %4d  ",      Wlc_NtkCountRealPis(p) ); //Wlc_NtkPiNum(p) );
788     printf( "PO = %4d  ",      Wlc_NtkPoNum(p) );
789     printf( "FF = %4d  ",      Wlc_NtkFfNum(p) );
790     printf( "Obj = %6d  ",     Wlc_NtkObjNum(p) - Wlc_NtkPiNum(p) - Wlc_NtkPoNum(p) - Wlc_NtkFfNum(p) );
791     printf( "Mem = %.3f MB",   1.0*Wlc_NtkMemUsage(p)/(1<<20) );
792     printf( "\n" );
793     if ( fDistrib )
794     {
795         Wlc_NtkPrintDistrib( p, fTwoSides, fVerbose );
796         return;
797     }
798     if ( !fVerbose )
799         return;
800     printf( "Node type statistics:\n" );
801     for ( i = 1; i < WLC_OBJ_NUMBER; i++ )
802     {
803         if ( !p->nObjs[i] )
804             continue;
805         if ( p->nAnds[0] && p->nAnds[i] )
806             printf( "%2d  :  %-8s  %6d  %7.2f %%\n", i, Wlc_Names[i], p->nObjs[i], 100.0*p->nAnds[i]/p->nAnds[0] );
807         else
808             printf( "%2d  :  %-8s  %6d\n", i, Wlc_Names[i], p->nObjs[i] );
809     }
810 }
Wlc_NtkPrintObjects(Wlc_Ntk_t * p)811 void Wlc_NtkPrintObjects( Wlc_Ntk_t * p )
812 {
813     Wlc_Obj_t * pObj; int i;
814     Wlc_NtkForEachObj( p, pObj, i )
815         Wlc_NtkPrintNode( p, pObj );
816 }
817 
818 /**Function*************************************************************
819 
820   Synopsis    []
821 
822   Description []
823 
824   SideEffects []
825 
826   SeeAlso     []
827 
828 ***********************************************************************/
Wlc_NtkTransferNames(Wlc_Ntk_t * pNew,Wlc_Ntk_t * p)829 void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p )
830 {
831     int i;
832     assert( !Wlc_NtkHasCopy(pNew)   && Wlc_NtkHasCopy(p)   );
833     assert( !Wlc_NtkHasNameId(pNew) && Wlc_NtkHasNameId(p) );
834     assert( pNew->pManName  == NULL && p->pManName != NULL );
835     Wlc_NtkCleanNameId( pNew );
836     for ( i = 0; i < p->nObjsAlloc; i++ )
837         if ( Wlc_ObjCopy(p, i) > 0 && i < Vec_IntSize(&p->vNameIds) && Wlc_ObjNameId(p, i) )
838             Wlc_ObjSetNameId( pNew, Wlc_ObjCopy(p, i), Wlc_ObjNameId(p, i) );
839     pNew->pManName = p->pManName;
840     p->pManName = NULL;
841     Vec_IntErase( &p->vNameIds );
842     // transfer table
843     pNew->pMemTable = p->pMemTable;  p->pMemTable = NULL;
844     pNew->vTables = p->vTables;      p->vTables = NULL;
845 }
Wlc_NtkNewName(Wlc_Ntk_t * p,int iCoId,int fSeq)846 char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq )
847 {
848     static char pBuffer[1000];
849     sprintf( pBuffer, "%s_o%d_%s", p->pName, iCoId, fSeq ? "seq": "comb" );
850     return pBuffer;
851 }
852 
853 /**Function*************************************************************
854 
855   Synopsis    [Reduce init vector.]
856 
857   Description []
858 
859   SideEffects []
860 
861   SeeAlso     []
862 
863 ***********************************************************************/
Wlc_ReduceMarkedInitVec(Wlc_Ntk_t * p,Vec_Int_t * vInit)864 Vec_Int_t * Wlc_ReduceMarkedInitVec( Wlc_Ntk_t * p, Vec_Int_t * vInit )
865 {
866     Vec_Int_t * vInitNew = Vec_IntDup( vInit );
867     Wlc_Obj_t * pObj; int i, k = 0;
868     assert( Vec_IntSize(vInit) == Wlc_NtkCiNum(p) - Wlc_NtkPiNum(p) );
869     Wlc_NtkForEachCi( p, pObj, i )
870         if ( !Wlc_ObjIsPi(pObj) && pObj->Mark )
871             Vec_IntWriteEntry( vInitNew, k++, Vec_IntEntry(vInit, i - Wlc_NtkPiNum(p)) );
872     Vec_IntShrink( vInitNew, k );
873     return vInitNew;
874 }
Wlc_ReduceMarkedInitStr(Wlc_Ntk_t * p,char * pInit)875 char * Wlc_ReduceMarkedInitStr( Wlc_Ntk_t * p, char * pInit )
876 {
877     char * pInitNew = Abc_UtilStrsav( pInit );
878     Wlc_Obj_t * pObj; int i, b, nBits = 0, k = 0;
879     Wlc_NtkForEachCi( p, pObj, i )
880     {
881         if ( !Wlc_ObjIsPi(pObj) && pObj->Mark )
882             for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
883                 pInitNew[k++] = pInitNew[nBits+b];
884         if ( !Wlc_ObjIsPi(pObj) )
885             nBits += Wlc_ObjRange(pObj);
886     }
887     pInitNew[k] = '\0';
888     assert( nBits == (int)strlen(pInit) );
889     return pInitNew;
890 }
891 
892 /**Function*************************************************************
893 
894   Synopsis    [Duplicates the network in a topological order.]
895 
896   Description []
897 
898   SideEffects []
899 
900   SeeAlso     []
901 
902 ***********************************************************************/
Wlc_ObjCollectCopyFanins(Wlc_Ntk_t * p,int iObj,Vec_Int_t * vFanins)903 void Wlc_ObjCollectCopyFanins( Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins )
904 {
905     int i, iFanin;
906     Wlc_Obj_t * pObj = Wlc_NtkObj( p, iObj );
907     Vec_IntClear( vFanins );
908     Wlc_ObjForEachFanin( pObj, iFanin, i )
909         Vec_IntPush( vFanins, Wlc_ObjCopy(p, iFanin) );
910     // special treatment of CONST and SELECT
911     if ( pObj->Type == WLC_OBJ_CONST )
912     {
913         int * pInts = Wlc_ObjConstValue( pObj );
914         int nInts = Abc_BitWordNum( Wlc_ObjRange(pObj) );
915         for ( i = 0; i < nInts; i++ )
916             Vec_IntPush( vFanins, pInts[i] );
917     }
918     else if ( pObj->Type == WLC_OBJ_BIT_SELECT )
919     {
920         assert( Vec_IntSize(vFanins) == 1 );
921         Vec_IntPushTwo( vFanins, Wlc_ObjRangeEnd(pObj), Wlc_ObjRangeBeg(pObj) );
922     }
923     else if ( pObj->Type == WLC_OBJ_TABLE )
924     {
925         assert( Vec_IntSize(vFanins) == 1 );
926         Vec_IntPush( vFanins, pObj->Fanins[1] );
927     }
928 }
Wlc_ObjDup(Wlc_Ntk_t * pNew,Wlc_Ntk_t * p,int iObj,Vec_Int_t * vFanins)929 int Wlc_ObjDup( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins )
930 {
931     Wlc_Obj_t * pObj = Wlc_NtkObj( p, iObj );
932     int iFaninNew = Wlc_ObjAlloc( pNew, pObj->Type, Wlc_ObjIsSigned(pObj), pObj->End, pObj->Beg );
933     Wlc_Obj_t * pObjNew = Wlc_NtkObj(pNew, iFaninNew);
934     Wlc_ObjCollectCopyFanins( p, iObj, vFanins );
935     Wlc_ObjAddFanins( pNew, pObjNew, vFanins );
936     Wlc_ObjSetCopy( p, iObj, iFaninNew );
937     pObjNew->fXConst = pObj->fXConst;
938     return iFaninNew;
939 }
Wlc_NtkDupDfs_rec(Wlc_Ntk_t * pNew,Wlc_Ntk_t * p,int iObj,Vec_Int_t * vFanins)940 void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins )
941 {
942     Wlc_Obj_t * pObj;
943     int i, iFanin;
944     if ( iObj == 0 )
945         return;
946     if ( Wlc_ObjCopy(p, iObj) )
947         return;
948     //printf( "Visiting node %d with type %d (%s)\n", iObj, Wlc_NtkObj(p, iObj)->Type, Wlc_NtkObj(p, iObj)->Type < WLC_OBJ_NUMBER ? Wlc_Names[Wlc_NtkObj(p, iObj)->Type] : NULL );
949     pObj = Wlc_NtkObj( p, iObj );
950     assert( pObj->Type != WLC_OBJ_FF );
951     Wlc_ObjForEachFanin( pObj, iFanin, i )
952         Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
953     Wlc_ObjDup( pNew, p, iObj, vFanins );
954 }
955 
Wlc_NtkDupDfsSimple(Wlc_Ntk_t * p)956 Wlc_Ntk_t * Wlc_NtkDupDfsSimple( Wlc_Ntk_t * p )
957 {
958     Wlc_Ntk_t * pNew;
959     Wlc_Obj_t * pObj;
960     Vec_Int_t * vFanins;
961     int i;
962     Wlc_NtkCleanCopy( p );
963     vFanins = Vec_IntAlloc( 100 );
964     pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
965     pNew->fSmtLib = p->fSmtLib;
966     pNew->fAsyncRst = p->fAsyncRst;
967     pNew->fMemPorts = p->fMemPorts;
968     pNew->fEasyFfs = p->fEasyFfs;
969     Wlc_NtkForEachCi( p, pObj, i )
970         Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
971     Wlc_NtkForEachCo( p, pObj, i )
972         Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
973     Wlc_NtkForEachCo( p, pObj, i )
974         Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi );
975     if ( p->vInits )
976     pNew->vInits = Vec_IntDup( p->vInits );
977     if ( p->pInits )
978     pNew->pInits = Abc_UtilStrsav( p->pInits );
979     Vec_IntFree( vFanins );
980     if ( p->pSpec )
981     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
982     return pNew;
983 }
984 
Wlc_NtkDupDfs(Wlc_Ntk_t * p,int fMarked,int fSeq)985 Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq )
986 {
987     Wlc_Ntk_t * pNew;
988     Wlc_Obj_t * pObj, * pObjNew;
989     Vec_Int_t * vFanins;
990     int i, k, iObj, iFanin;
991     vFanins = Vec_IntAlloc( 100 );
992     Wlc_NtkCleanCopy( p );
993     pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
994     pNew->fSmtLib = p->fSmtLib;
995     pNew->fAsyncRst = p->fAsyncRst;
996     pNew->fMemPorts = p->fMemPorts;
997     pNew->fEasyFfs = p->fEasyFfs;
998     Wlc_NtkForEachCi( p, pObj, i )
999         if ( !fMarked || pObj->Mark )
1000         {
1001             unsigned Type = pObj->Type;
1002             if ( !fSeq ) pObj->Type = WLC_OBJ_PI;
1003             Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
1004             pObj->Type = Type;
1005         }
1006     Wlc_NtkForEachFf2( p, pObj, i )
1007     {
1008         int iObjNew = Wlc_ObjAlloc( pNew, pObj->Type, Wlc_ObjIsSigned(pObj), pObj->End, pObj->Beg );
1009         Wlc_ObjSetCopy( p, Wlc_ObjId(p, pObj), iObjNew );
1010         Vec_IntPush( &pNew->vFfs2, iObjNew );
1011     }
1012     Wlc_NtkForEachCo( p, pObj, i )
1013         if ( !fMarked || pObj->Mark )
1014             Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
1015     Wlc_NtkForEachCo( p, pObj, i )
1016         if ( !fMarked || pObj->Mark )
1017             Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 );
1018     Wlc_NtkForEachFf2( p, pObj, i )
1019     {
1020         iObj = Wlc_ObjId(p, pObj);
1021         Wlc_ObjForEachFanin( pObj, iFanin, k )
1022             Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
1023         Wlc_ObjCollectCopyFanins( p, iObj, vFanins );
1024         pObjNew = Wlc_NtkObj( pNew, Wlc_ObjCopy(p, iObj) );
1025         Wlc_ObjAddFanins( pNew, pObjNew, vFanins );
1026         pObjNew->fXConst = pObj->fXConst;
1027     }
1028     Vec_IntFree( vFanins );
1029     if ( fSeq && p->vInits )
1030     {
1031         if ( fMarked )
1032         {
1033             if ( p->vInits )
1034                 pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits );
1035             if ( p->pInits )
1036                 pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits );
1037         }
1038         else
1039         {
1040             if ( p->vInits )
1041                 pNew->vInits = Vec_IntDup( p->vInits );
1042             if ( p->pInits )
1043                 pNew->pInits = Abc_UtilStrsav( p->pInits );
1044         }
1045     }
1046     if ( p->pSpec )
1047         pNew->pSpec = Abc_UtilStrsav( p->pSpec );
1048     if ( Wlc_NtkHasNameId(p) )
1049         Wlc_NtkTransferNames( pNew, p );
1050     if ( Vec_IntSize(&p->vPoPairs) )
1051         Vec_IntAppend( &pNew->vPoPairs, &p->vPoPairs );
1052     return pNew;
1053 }
Wlc_NtkDupDfsAbs(Wlc_Ntk_t * p,Vec_Int_t * vPisOld,Vec_Int_t * vPisNew,Vec_Int_t * vFlops)1054 Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
1055 {
1056     Wlc_Ntk_t * pNew;
1057     Wlc_Obj_t * pObj;
1058     Vec_Int_t * vFanins;
1059     int i;
1060     Wlc_NtkCleanCopy( p );
1061     pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
1062     pNew->fSmtLib = p->fSmtLib;
1063     pNew->fAsyncRst = p->fAsyncRst;
1064     pNew->fMemPorts = p->fMemPorts;
1065     pNew->fEasyFfs = p->fEasyFfs;
1066 
1067     // duplicate marked PIs
1068     vFanins = Vec_IntAlloc( 100 );
1069     Wlc_NtkForEachObjVec( vPisOld, p, pObj, i )
1070     {
1071         assert( Wlc_ObjIsPi(pObj) );
1072         Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
1073     }
1074     // duplicate additional PIs
1075     Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
1076     {
1077         unsigned Type = pObj->Type;
1078         int nFanins = Wlc_ObjFaninNum(pObj);
1079         assert( !Wlc_ObjIsPi(pObj) );
1080         pObj->Type = WLC_OBJ_PI;
1081         pObj->nFanins = 0;
1082         Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
1083         pObj->Type = Type;
1084         pObj->nFanins = (unsigned)nFanins;
1085     }
1086     // duplicate flop outputs
1087     Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
1088     {
1089         assert( !Wlc_ObjIsPi(pObj) && Wlc_ObjIsCi(pObj) );
1090         Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
1091     }
1092 
1093     // duplicate logic cones of primary outputs
1094     Wlc_NtkForEachPo( p, pObj, i )
1095         Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
1096     // duplidate logic cone of flop inputs
1097     Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
1098         Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, Wlc_ObjFo2Fi(p, pObj)), vFanins );
1099 
1100     // duplicate POs
1101     Wlc_NtkForEachPo( p, pObj, i )
1102         Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), 0 );
1103     // duplicate flop inputs
1104     Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
1105         Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, Wlc_ObjFo2Fi(p, pObj)), 1 );
1106     Vec_IntFree( vFanins );
1107 
1108     // mark flop outputs
1109     Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
1110         pObj->Mark = 1;
1111     if ( p->vInits )
1112         pNew->vInits = Wlc_ReduceMarkedInitVec( p, p->vInits );
1113     if ( p->pInits )
1114         pNew->pInits = Wlc_ReduceMarkedInitStr( p, p->pInits );
1115     Wlc_NtkCleanMarks( p );
1116 
1117     if ( p->pSpec )
1118         pNew->pSpec = Abc_UtilStrsav( p->pSpec );
1119     //Wlc_NtkTransferNames( pNew, p );
1120     return pNew;
1121 }
1122 
1123 /**Function*************************************************************
1124 
1125   Synopsis    [Select the cone of the given output.]
1126 
1127   Description []
1128 
1129   SideEffects []
1130 
1131   SeeAlso     []
1132 
1133 ***********************************************************************/
Wlc_NtkCleanMarks(Wlc_Ntk_t * p)1134 void Wlc_NtkCleanMarks( Wlc_Ntk_t * p )
1135 {
1136     Wlc_Obj_t * pObj;
1137     int i;
1138     Wlc_NtkForEachObj( p, pObj, i )
1139         pObj->Mark = 0;
1140 }
Wlc_NtkCountMarked(Wlc_Ntk_t * p,int * pnPis,int * pnFos,int * pnAdders,int * pnMults)1141 int Wlc_NtkCountMarked( Wlc_Ntk_t * p, int * pnPis, int * pnFos, int * pnAdders, int * pnMults )
1142 {
1143     Wlc_Obj_t * pObj;
1144     int i, nNodes = 0;
1145     *pnPis = *pnFos = *pnAdders = *pnMults = 0;
1146     Wlc_NtkForEachObj( p, pObj, i )
1147     {
1148         if ( !pObj->Mark )
1149             continue;
1150         if ( Wlc_ObjIsPi(pObj) )
1151             (*pnPis)++;
1152         else if ( Wlc_ObjIsCi(pObj) )
1153             (*pnFos)++;
1154         else if ( pObj->Mark )
1155         {
1156             nNodes++;
1157             if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB )
1158                 (*pnAdders)++;
1159             else if ( pObj->Type == WLC_OBJ_ARI_MULTI )
1160                 (*pnMults)++;
1161         }
1162     }
1163     return nNodes;
1164 }
Wlc_NtkMarkCone_rec(Wlc_Ntk_t * p,Wlc_Obj_t * pObj,Vec_Int_t * vFlops)1165 void Wlc_NtkMarkCone_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFlops )
1166 {
1167     int i, iFanin;
1168     if ( pObj->Mark )
1169         return;
1170     pObj->Mark = 1;
1171     if ( Wlc_ObjIsCi(pObj) )
1172     {
1173         if ( !Wlc_ObjIsPi(pObj) )
1174             Vec_IntPush( vFlops, Wlc_ObjCiId(pObj) );
1175         return;
1176     }
1177     Wlc_ObjForEachFanin( pObj, iFanin, i ) if ( iFanin )
1178         Wlc_NtkMarkCone_rec( p, Wlc_NtkObj(p, iFanin), vFlops );
1179 }
Wlc_NtkMarkCone(Wlc_Ntk_t * p,int iCoId,int Range,int fSeq,int fAllPis)1180 void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis )
1181 {
1182     Vec_Int_t * vFlops;
1183     Wlc_Obj_t * pObj;
1184     int i, CiId, CoId;
1185     Wlc_NtkCleanMarks( p );
1186     if ( fAllPis )
1187     Wlc_NtkForEachPi( p, pObj, i )
1188         pObj->Mark = 1;
1189     vFlops = Vec_IntAlloc( 100 );
1190     Wlc_NtkForEachCo( p, pObj, i )
1191         if ( iCoId == -1 || (i >= iCoId && i < iCoId + Range) )
1192             Wlc_NtkMarkCone_rec( p, pObj, vFlops );
1193     if ( fSeq )
1194     Vec_IntForEachEntry( vFlops, CiId, i )
1195     {
1196         CoId = Wlc_NtkPoNum(p) + CiId - Wlc_NtkPiNum(p);
1197         Wlc_NtkMarkCone_rec( p, Wlc_NtkCo(p, CoId), vFlops );
1198     }
1199     Vec_IntFree( vFlops );
1200 }
Wlc_NtkProfileCones(Wlc_Ntk_t * p)1201 void Wlc_NtkProfileCones( Wlc_Ntk_t * p )
1202 {
1203     Wlc_Obj_t * pObj;
1204     int i, nPis, nFos, nNodes, nAdders, nMults;
1205     Wlc_NtkForEachCo( p, pObj, i )
1206     {
1207         Wlc_NtkMarkCone( p, i, 1, 0, 0 );
1208         nNodes = Wlc_NtkCountMarked( p, &nPis, &nFos, &nAdders, &nMults );
1209         printf( "Cone %5d : ", i );
1210         printf( "PI = %4d  ", nPis );
1211         printf( "FO = %4d  ", nFos );
1212         printf( "Node = %6d  ", nNodes );
1213         printf( "Add/Sub = %4d  ", nAdders );
1214         printf( "Mult = %4d  ", nMults );
1215         printf( "\n" );
1216     }
1217     Wlc_NtkCleanMarks( p );
1218 }
1219 
1220 /**Function*************************************************************
1221 
1222   Synopsis    [Duplicates the network by copying each node.]
1223 
1224   Description []
1225 
1226   SideEffects []
1227 
1228   SeeAlso     []
1229 
1230 ***********************************************************************/
Wlc_NtkDupSingleNodes(Wlc_Ntk_t * p)1231 Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p )
1232 {
1233     Wlc_Ntk_t * pNew;
1234     Vec_Int_t * vFanins;
1235     Wlc_Obj_t * pObj, * pObjNew;
1236     Wlc_Obj_t * pFanin, * pFaninNew;
1237     int i, k, iFanin, iFaninNew, iObjNew, Count = 0;
1238     // count objects
1239     Wlc_NtkForEachObj( p, pObj, i )
1240         if ( !Wlc_ObjIsCi(pObj) )
1241             Count += 1 + Wlc_ObjFaninNum(pObj);
1242     // copy objects
1243     Wlc_NtkCleanCopy( p );
1244     vFanins = Vec_IntAlloc( 100 );
1245     pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
1246     pNew->fSmtLib = p->fSmtLib;
1247     pNew->fAsyncRst = p->fAsyncRst;
1248     pNew->fMemPorts = p->fMemPorts;
1249     pNew->fEasyFfs = p->fEasyFfs;
1250     Wlc_NtkForEachObj( p, pObj, i )
1251     {
1252         if ( Wlc_ObjIsCi(pObj) )
1253             continue;
1254         if ( pObj->Type == WLC_OBJ_ARI_MULTI )
1255             continue;
1256         if ( pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3 )
1257             continue;
1258         // create CIs for the fanins
1259         Wlc_ObjForEachFanin( pObj, iFanin, k )
1260         {
1261             pFanin = Wlc_NtkObj(p, iFanin);
1262             iFaninNew = Wlc_ObjAlloc( pNew, WLC_OBJ_PI, pFanin->Signed, pFanin->End, pFanin->Beg );
1263             pFaninNew = Wlc_NtkObj(pNew, iFaninNew);
1264             Wlc_ObjSetCopy( p, iFanin, iFaninNew );
1265             //Wlc_ObjSetCi( pNew, pFaninNew );
1266         }
1267         // create object
1268         iObjNew = Wlc_ObjDup( pNew, p, i, vFanins );
1269         pObjNew = Wlc_NtkObj(pNew, iObjNew);
1270         pObjNew->fIsPo = 1;
1271         Vec_IntPush( &pNew->vPos, iObjNew );
1272     }
1273     Vec_IntFree( vFanins );
1274     Wlc_NtkTransferNames( pNew, p );
1275     if ( p->pSpec )
1276     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
1277     return pNew;
1278 }
1279 
1280 /**Function*************************************************************
1281 
1282   Synopsis    [Creates short names for all objects.]
1283 
1284   Description []
1285 
1286   SideEffects []
1287 
1288   SeeAlso     []
1289 
1290 ***********************************************************************/
Wlc_NtkShortNames(Wlc_Ntk_t * p)1291 void Wlc_NtkShortNames( Wlc_Ntk_t * p )
1292 {
1293     Wlc_Obj_t * pObj;
1294     char pBuffer[100];
1295     int nDigits, NameId, fFound, i;
1296     int nFlops = Wlc_NtkCoNum(p) - Wlc_NtkPoNum(p);
1297     nDigits = Abc_Base10Log( nFlops );
1298     Wlc_NtkForEachCo( p, pObj, i )
1299     {
1300         if ( Wlc_ObjIsPo(pObj) )
1301             continue;
1302         sprintf( pBuffer, "%s%0*d", "fi", nDigits, i - Wlc_NtkPoNum(p) );
1303         NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
1304         Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
1305     }
1306     Wlc_NtkForEachCi( p, pObj, i )
1307     {
1308         if ( Wlc_ObjIsPi(pObj) )
1309             continue;
1310         sprintf( pBuffer, "%s%0*d", "fo", nDigits, i - Wlc_NtkPiNum(p) );
1311         NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
1312         Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
1313     }
1314     nDigits = Abc_Base10Log( Wlc_NtkPoNum(p) );
1315     Wlc_NtkForEachPo( p, pObj, i )
1316     {
1317         sprintf( pBuffer, "%s%0*d", "po", nDigits, i );
1318         NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
1319         Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
1320     }
1321     nDigits = Abc_Base10Log( Wlc_NtkPiNum(p) );
1322     Wlc_NtkForEachPi( p, pObj, i )
1323     {
1324         sprintf( pBuffer, "%s%0*d", "pi", nDigits, i );
1325         NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
1326         Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
1327     }
1328     nDigits = Abc_Base10Log( Wlc_NtkObjNum(p) );
1329     Wlc_NtkForEachObj( p, pObj, i )
1330     {
1331         if ( Wlc_ObjIsCi(pObj) || Wlc_ObjIsCo(pObj) )
1332             continue;
1333         sprintf( pBuffer, "%s%0*d", "n", nDigits, i );
1334         NameId = Abc_NamStrFindOrAdd( p->pManName, pBuffer, &fFound );
1335         Wlc_ObjSetNameId( p, Wlc_ObjId(p, pObj), NameId );
1336     }
1337 }
1338 
1339 /**Function*************************************************************
1340 
1341   Synopsis    [Count the number of flops initialized to DC value.]
1342 
1343   Description []
1344 
1345   SideEffects []
1346 
1347   SeeAlso     []
1348 
1349 ***********************************************************************/
Wlc_NtkDcFlopNum(Wlc_Ntk_t * p)1350 int Wlc_NtkDcFlopNum( Wlc_Ntk_t * p )
1351 {
1352     int i, nFlops, Count = 0;
1353     if ( p->pInits == NULL )
1354         return 0;
1355     nFlops = strlen(p->pInits);
1356     for ( i = 0; i < nFlops; i++ )
1357         Count += (p->pInits[i] == 'x' || p->pInits[i] == 'X');
1358     return Count;
1359 }
1360 
1361 /**Function*************************************************************
1362 
1363   Synopsis    [Create references.]
1364 
1365   Description []
1366 
1367   SideEffects []
1368 
1369   SeeAlso     []
1370 
1371 ***********************************************************************/
Wlc_NtkSetRefs(Wlc_Ntk_t * p)1372 void Wlc_NtkSetRefs( Wlc_Ntk_t * p )
1373 {
1374     Wlc_Obj_t * pObj; int i, k, Fanin;
1375     Vec_IntFill( &p->vRefs, Wlc_NtkObjNumMax(p), 0 );
1376     Wlc_NtkForEachObj( p, pObj, i )
1377         Wlc_ObjForEachFanin( pObj, Fanin, k )
1378             Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
1379     Wlc_NtkForEachCo( p, pObj, i )
1380         Vec_IntAddToEntry( &p->vRefs, Wlc_ObjId(p, pObj), 1 );
1381 }
1382 
1383 /**Function*************************************************************
1384 
1385   Synopsis    [This procedure simply count the number of PPI bits.]
1386 
1387   Description []
1388 
1389   SideEffects []
1390 
1391   SeeAlso     []
1392 
1393 ***********************************************************************/
Wlc_NtkCountObjBits(Wlc_Ntk_t * p,Vec_Int_t * vPisNew)1394 int Wlc_NtkCountObjBits( Wlc_Ntk_t * p, Vec_Int_t * vPisNew )
1395 {
1396     Wlc_Obj_t * pObj;
1397     int i, Count = 0;
1398     Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
1399         Count += Wlc_ObjRange(pObj);
1400     return Count;
1401 }
1402 
1403 ////////////////////////////////////////////////////////////////////////
1404 ///                       END OF FILE                                ///
1405 ////////////////////////////////////////////////////////////////////////
1406 
1407 
1408 ABC_NAMESPACE_IMPL_END
1409 
1410