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