1 /**CFile****************************************************************
2
3 FileName [cbaNtk.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Hierarchical word-level netlist.]
8
9 Synopsis [Network manipulation.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - July 21, 2015.]
16
17 Revision [$Id: cbaNtk.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include <math.h>
22 #include "cba.h"
23 #include "base/main/main.h"
24
25 ABC_NAMESPACE_IMPL_START
26
27 ////////////////////////////////////////////////////////////////////////
28 /// DECLARATIONS ///
29 ////////////////////////////////////////////////////////////////////////
30
31 ////////////////////////////////////////////////////////////////////////
32 /// FUNCTION DEFINITIONS ///
33 ////////////////////////////////////////////////////////////////////////
34
35 /**Function*************************************************************
36
37 Synopsis [Prints distribution of operator types.]
38
39 Description []
40
41 SideEffects []
42
43 SeeAlso []
44
45 ***********************************************************************/
Vec_WrdSelectSortCost2(word * pArray,int nSize,word * pCosts)46 static inline void Vec_WrdSelectSortCost2( word * pArray, int nSize, word * pCosts )
47 {
48 int i, j, best_i;
49 for ( i = 0; i < nSize-1; i++ )
50 {
51 best_i = i;
52 for ( j = i+1; j < nSize; j++ )
53 if ( pCosts[j] < pCosts[best_i] )
54 best_i = j;
55 ABC_SWAP( word, pArray[i], pArray[best_i] );
56 ABC_SWAP( word, pCosts[i], pCosts[best_i] );
57 }
58 }
Cba_NtkPrintDistribMakeSign(int s,int s0,int s1)59 static inline word Cba_NtkPrintDistribMakeSign( int s, int s0, int s1 )
60 {
61 return ((word)s1 << 42) | ((word)s0 << 21) | (word)s;
62 }
Cba_NtkPrintDistribFromSign(word sss,int * s,int * s0,int * s1)63 static inline void Cba_NtkPrintDistribFromSign( word sss, int * s, int * s0, int * s1 )
64 {
65 *s1 = (int)(sss >> 42); *s0 = (int)(sss >> 21) & 0x1FFFFF; *s = (int)sss & 0x1FFFFF;
66 }
Cba_NtkPrintDistribAddOne(Vec_Ptr_t * vTypes,Vec_Ptr_t * vOccurs,int Type,word Sign)67 static inline void Cba_NtkPrintDistribAddOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Type, word Sign )
68 {
69 Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, Type );
70 Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, Type );
71 word Entry; int i;
72 Vec_WrdForEachEntry( vType, Entry, i )
73 if ( Entry == Sign )
74 {
75 Vec_WrdAddToEntry( vOccur, i, 1 );
76 return;
77 }
78 Vec_WrdPush( vType, Sign );
79 Vec_WrdPush( vOccur, 1 );
80 }
Cba_NtkPrintDistribSortOne(Vec_Ptr_t * vTypes,Vec_Ptr_t * vOccurs,int Type)81 void Cba_NtkPrintDistribSortOne( Vec_Ptr_t * vTypes, Vec_Ptr_t * vOccurs, int Type )
82 {
83 Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, Type );
84 Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, Type );
85 Vec_WrdSelectSortCost2( Vec_WrdArray(vType), Vec_WrdSize(vType), Vec_WrdArray(vOccur) );
86 Vec_WrdReverseOrder( vType );
87 Vec_WrdReverseOrder( vOccur );
88 }
Cba_NtkPrintDistrib(Cba_Ntk_t * p,int fVerbose)89 void Cba_NtkPrintDistrib( Cba_Ntk_t * p, int fVerbose )
90 {
91 Vec_Ptr_t * vTypes, * vOccurs;
92 Vec_Int_t * vAnds = Vec_IntStart( CBA_BOX_LAST );
93 int iRnObj = -1, nCountRange = 0;
94 int i, k, s, s0, s1; word Sign;
95 Cba_ObjType_t Type;
96 char * pTypeNames[CBA_BOX_LAST];
97 Cba_ManCreatePrimMap( pTypeNames );
98 // allocate statistics arrays
99 vTypes = Vec_PtrStart( CBA_BOX_LAST );
100 vOccurs = Vec_PtrStart( CBA_BOX_LAST );
101 for ( i = 0; i < CBA_BOX_LAST; i++ )
102 Vec_PtrWriteEntry( vTypes, i, Vec_WrdAlloc(16) );
103 for ( i = 0; i < CBA_BOX_LAST; i++ )
104 Vec_PtrWriteEntry( vOccurs, i, Vec_WrdAlloc(16) );
105 // add nodes
106 Cba_NtkForEachObj( p, i )
107 {
108 // char * pName = Cba_ObjName(p, i);
109 Type = Cba_ObjType( p, i );
110 if ( Cba_ObjSign(p, i) > 0x1FFFFF )
111 printf( "Object %6d has range %d, which is reduced to %d in the statistics.\n",
112 i, Cba_ObjRangeSize(p, i), Cba_ObjRangeSize(p, i) & 0xFFFFF );
113 if ( Cba_ObjLeft(p, i) && Cba_ObjRight(p, i) )
114 {
115 if ( iRnObj == -1 )
116 iRnObj = 1;
117 nCountRange++;
118 }
119 // 0-input types
120 if ( Cba_ObjIsPi(p, i) || (Type == CBA_BOX_BUF && Cba_FonIsConst(Cba_ObjFinFon(p, i, 0))) || Type == CBA_BOX_CONCAT )
121 Sign = Cba_NtkPrintDistribMakeSign( Cba_ObjSign(p, i), 0, 0 );
122 // 1-input types
123 else if ( Cba_TypeIsUnary(Type) )
124 Sign = Cba_NtkPrintDistribMakeSign( Cba_ObjSign(p, i), Cba_ObjSign(p, Cba_ObjFinFon(p, i, 0)), 0 );
125 // 2-input types (including MUX)
126 else if ( Cba_ObjFinNum(p, i) == 1 )
127 Sign = Cba_NtkPrintDistribMakeSign( Cba_ObjSign(p, i), Cba_ObjSign(p, Cba_ObjFinFon(p, i, 0)), 0 );
128 else
129 {
130 assert( Cba_ObjFinNum(p, i) >= 2 );
131 Sign = Cba_NtkPrintDistribMakeSign( Cba_ObjSign(p, i), Cba_ObjSign(p, Cba_ObjFinFon(p, i, 0)), Cba_ObjSign(p, Cba_ObjFinFon(p, i, 1)) );
132 }
133 // add to storage
134 Cba_NtkPrintDistribAddOne( vTypes, vOccurs, Type, Sign );
135 // count the number of AIG nodes
136 if ( Type == CBA_BOX_MUX )
137 Vec_IntAddToEntry( vAnds, CBA_BOX_MUX, 3 * Cba_ObjRangeSize(p, i) * (Cba_ObjFinNum(p, i) - 2) );
138 else if ( Type == CBA_BOX_SHIR )
139 Vec_IntAddToEntry( vAnds, CBA_BOX_SHIR, Abc_MinInt(Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)), Abc_Base2Log(Cba_ObjRangeSize(p, i))) * 3 );
140 else if ( Type == CBA_BOX_SHIRA )
141 Vec_IntAddToEntry( vAnds, CBA_BOX_SHIRA, Cba_ObjRangeSize(p, i) * Abc_MinInt(Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)), Abc_Base2Log(Cba_ObjRangeSize(p, i))) * 3 );
142 else if ( Type == CBA_BOX_SHIL )
143 Vec_IntAddToEntry( vAnds, CBA_BOX_SHIL, Cba_ObjRangeSize(p, i) * Abc_MinInt(Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)), Abc_Base2Log(Cba_ObjRangeSize(p, i))) * 3 );
144 else if ( Type == CBA_BOX_SHILA )
145 Vec_IntAddToEntry( vAnds, CBA_BOX_SHILA, Cba_ObjRangeSize(p, i) * Abc_MinInt(Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)), Abc_Base2Log(Cba_ObjRangeSize(p, i))) * 3 );
146 else if ( Type == CBA_BOX_ROTR )
147 Vec_IntAddToEntry( vAnds, CBA_BOX_ROTR, Cba_ObjRangeSize(p, i) * Abc_MinInt(Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)), Abc_Base2Log(Cba_ObjRangeSize(p, i))) * 3 );
148 else if ( Type == CBA_BOX_ROTL )
149 Vec_IntAddToEntry( vAnds, CBA_BOX_ROTL, Cba_ObjRangeSize(p, i) * Abc_MinInt(Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)), Abc_Base2Log(Cba_ObjRangeSize(p, i))) * 3 );
150 else if ( Type == CBA_BOX_INV )
151 Vec_IntAddToEntry( vAnds, CBA_BOX_INV, 0 );
152 else if ( Type == CBA_BOX_AND )
153 Vec_IntAddToEntry( vAnds, CBA_BOX_AND, Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) );
154 else if ( Type == CBA_BOX_OR )
155 Vec_IntAddToEntry( vAnds, CBA_BOX_OR, Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) );
156 else if ( Type == CBA_BOX_XOR )
157 Vec_IntAddToEntry( vAnds, CBA_BOX_XOR, 3 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) );
158 else if ( Type == CBA_BOX_SLICE )
159 Vec_IntAddToEntry( vAnds, CBA_BOX_SLICE, 0 );
160 else if ( Type == CBA_BOX_CONCAT )
161 Vec_IntAddToEntry( vAnds, CBA_BOX_CONCAT, 0 );
162 else if ( Type == CBA_BOX_LNOT )
163 Vec_IntAddToEntry( vAnds, CBA_BOX_LNOT, Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 1 );
164 else if ( Type == CBA_BOX_LAND )
165 Vec_IntAddToEntry( vAnds, CBA_BOX_LAND, Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) + Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 1)) - 1 );
166 else if ( Type == CBA_BOX_LOR )
167 Vec_IntAddToEntry( vAnds, CBA_BOX_LOR, Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) + Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 1)) - 1 );
168 else if ( Type == CBA_BOX_LXOR )
169 Vec_IntAddToEntry( vAnds, CBA_BOX_LXOR, Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) + Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 1)) + 1 );
170 else if ( Type == CBA_BOX_EQU )
171 Vec_IntAddToEntry( vAnds, CBA_BOX_EQU, 4 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 1 );
172 else if ( Type == CBA_BOX_NEQU )
173 Vec_IntAddToEntry( vAnds, CBA_BOX_NEQU, 4 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 1 );
174 else if ( Type == CBA_BOX_LTHAN )
175 Vec_IntAddToEntry( vAnds, CBA_BOX_LTHAN, 6 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 6 );
176 else if ( Type == CBA_BOX_MTHAN )
177 Vec_IntAddToEntry( vAnds, CBA_BOX_MTHAN, 6 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 6 );
178 else if ( Type == CBA_BOX_LETHAN )
179 Vec_IntAddToEntry( vAnds, CBA_BOX_LETHAN, 6 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 6 );
180 else if ( Type == CBA_BOX_METHAN )
181 Vec_IntAddToEntry( vAnds, CBA_BOX_METHAN, 6 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 6 );
182 else if ( Type == CBA_BOX_RAND )
183 Vec_IntAddToEntry( vAnds, CBA_BOX_RAND, Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 1 );
184 else if ( Type == CBA_BOX_ROR )
185 Vec_IntAddToEntry( vAnds, CBA_BOX_ROR, Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 1 );
186 else if ( Type == CBA_BOX_RXOR )
187 Vec_IntAddToEntry( vAnds, CBA_BOX_RXOR, 3 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 3 );
188 else if ( Type == CBA_BOX_ADD )
189 Vec_IntAddToEntry( vAnds, CBA_BOX_ADD, 9 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) );
190 else if ( Type == CBA_BOX_SUB )
191 Vec_IntAddToEntry( vAnds, CBA_BOX_SUB, 9 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) );
192 else if ( Type == CBA_BOX_MUL )
193 Vec_IntAddToEntry( vAnds, CBA_BOX_MUL, 9 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 1)) );
194 else if ( Type == CBA_BOX_DIV )
195 Vec_IntAddToEntry( vAnds, CBA_BOX_DIV, 13 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 19 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) + 10 );
196 else if ( Type == CBA_BOX_MOD )
197 Vec_IntAddToEntry( vAnds, CBA_BOX_MOD, 13 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 7 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) - 2 );
198 else if ( Type == CBA_BOX_POW )
199 Vec_IntAddToEntry( vAnds, CBA_BOX_POW, 10 * (int)pow((double)Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)),(double)Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0))) );
200 else if ( Type == CBA_BOX_MIN )
201 Vec_IntAddToEntry( vAnds, CBA_BOX_MIN, 4 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) );
202 else if ( Type == CBA_BOX_SQRT )
203 Vec_IntAddToEntry( vAnds, CBA_BOX_SQRT, 11 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) / 8 + 5 * Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)) / 2 - 5 );
204 }
205 if ( nCountRange )
206 {
207 printf( "Warning: %d objects of the design have non-zero-based ranges.\n", nCountRange );
208 printf( "In particular, object %6d with name \"%s\" has range %d=[%d:%d]\n",
209 iRnObj, Cba_FonNameStr(p, Cba_ObjFon0(p, iRnObj)),
210 Cba_ObjRangeSize(p, iRnObj), Cba_ObjLeft(p, iRnObj), Cba_ObjRight(p, iRnObj) );
211 }
212 // print by occurrence
213 printf( "ID : name occurrence and2 (occurrence)<output_range>=<input_range>.<input_range> ...\n" );
214 for ( i = 0; i < CBA_BOX_LAST; i++ )
215 {
216 Vec_Wrd_t * vType = (Vec_Wrd_t *)Vec_PtrEntry( vTypes, i );
217 Vec_Wrd_t * vOccur = (Vec_Wrd_t *)Vec_PtrEntry( vOccurs, i );
218 if ( p->pDesign->nObjs[i] == 0 )
219 continue;
220 printf( "%2d : %-8s %6d%8d ", i, pTypeNames[i], p->pDesign->nObjs[i], Vec_IntEntry(vAnds, i) );
221 // sort by occurence
222 Cba_NtkPrintDistribSortOne( vTypes, vOccurs, i );
223 Vec_WrdForEachEntry( vType, Sign, k )
224 {
225 Cba_NtkPrintDistribFromSign( Sign, &s, &s0, &s1 );
226 if ( ((k % 6) == 5 && s1) || ((k % 8) == 7 && !s1) )
227 printf( "\n " );
228 printf( "(%d)", (int)Vec_WrdEntry( vOccur, k ) );
229 printf( "%s%d", Abc_LitIsCompl(s)?"-":"", Abc_Lit2Var(s) );
230 if ( s0 )
231 printf( "=%s%d", Abc_LitIsCompl(s0)?"-":"", Abc_Lit2Var(s0) );
232 if ( s1 )
233 printf( ".%s%d", Abc_LitIsCompl(s1)?"-":"", Abc_Lit2Var(s1) );
234 printf( " " );
235 }
236 printf( "\n" );
237 }
238 Vec_VecFree( (Vec_Vec_t *)vTypes );
239 Vec_VecFree( (Vec_Vec_t *)vOccurs );
240 Vec_IntFree( vAnds );
241 }
Cba_NtkPrintNodes(Cba_Ntk_t * p,int Type)242 void Cba_NtkPrintNodes( Cba_Ntk_t * p, int Type )
243 {
244 int i, iFon0, iFon1, Counter = 0;
245 char * pTypeNames[CBA_BOX_LAST];
246 Cba_ManCreatePrimMap( pTypeNames );
247 printf( "Operation %s\n", pTypeNames[Type] );
248 Cba_NtkForEachObj( p, i )
249 {
250 if ( (int)Type != Type )
251 continue;
252 iFon0 = Cba_ObjFinFon(p, i, 0);
253 iFon1 = Cba_ObjFinFon(p, i, 1);
254
255 printf( "%8d :", Counter++ );
256 printf( "%8d : ", i );
257 printf( "%3d%s = ", Cba_ObjRangeSize(p, i), Cba_ObjSigned(p, i) ? "s" : " " );
258 printf( "%3d%s %s ", Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 0)), Cba_ObjSigned(p, iFon0) ? "s" : " ", pTypeNames[Type] );
259 printf( "%3d%s ", Cba_ObjRangeSize(p, Cba_ObjFinFon(p, i, 1)), Cba_ObjSigned(p, iFon1) ? "s" : " " );
260 printf( " : " );
261 printf( "%-12s = ", Cba_ObjNameStr(p, i) );
262 printf( "%-12s %s ", Cba_FonIsConst(iFon0) ? Cba_NtkConst(p, Cba_FonConst(iFon0)) : Cba_FonNameStr(p, iFon0), pTypeNames[Type] );
263 printf( "%-12s ", Cba_FonIsConst(iFon1) ? Cba_NtkConst(p, Cba_FonConst(iFon1)) : Cba_FonNameStr(p, iFon1) );
264 printf( "\n" );
265 }
266 }
Cba_NtkPrintStatsFull(Cba_Ntk_t * p,int fDistrib,int fVerbose)267 void Cba_NtkPrintStatsFull( Cba_Ntk_t * p, int fDistrib, int fVerbose )
268 {
269 int i;
270 char * pTypeNames[CBA_BOX_LAST];
271 Cba_ManCreatePrimMap( pTypeNames );
272 printf( "%-20s : ", Cba_NtkName(p) );
273 printf( "PI = %4d ", Cba_NtkPiNum(p) );
274 printf( "PO = %4d ", Cba_NtkPoNum(p) );
275 printf( "FF = %4d ", Cba_NtkBoxSeqNum(p) );
276 printf( "Obj = %6d ", Cba_NtkObjNum(p) );
277 printf( "Mem = %.3f MB", 1.0*Cba_NtkMemory(p)/(1<<20) );
278 printf( "\n" );
279 if ( fDistrib )
280 {
281 Cba_NtkPrintDistrib( p, fVerbose );
282 return;
283 }
284 if ( !fVerbose )
285 return;
286 printf( "Node type statistics:\n" );
287 for ( i = 1; i < CBA_BOX_LAST; i++ )
288 {
289 if ( !p->pDesign->nObjs[i] )
290 continue;
291 if ( p->pDesign->nAnds[0] && p->pDesign->nAnds[i] )
292 printf( "%2d : %-8s %6d %7.2f %%\n", i, pTypeNames[i], p->pDesign->nObjs[i], 100.0*p->pDesign->nAnds[i]/p->pDesign->nAnds[0] );
293 else
294 printf( "%2d : %-8s %6d\n", i, pTypeNames[i], p->pDesign->nObjs[i] );
295 }
296 }
297
298
299 /**Function*************************************************************
300
301 Synopsis []
302
303 Description []
304
305 SideEffects []
306
307 SeeAlso []
308
309 ***********************************************************************/
Cba_NtkCollectDistrib(Cba_Ntk_t * p,int * pCounts,int * pUserCounts)310 void Cba_NtkCollectDistrib( Cba_Ntk_t * p, int * pCounts, int * pUserCounts )
311 {
312 int i;
313 Cba_NtkForEachBox( p, i )
314 if ( Cba_ObjIsBoxUser(p, i) )
315 pUserCounts[Cba_ObjNtkId(p, i)]++;
316 else
317 pCounts[Cba_ObjType(p, i)]++;
318 }
319
Cba_NtkPrintDistribStat(Cba_Ntk_t * p,int * pCounts,int * pUserCounts)320 void Cba_NtkPrintDistribStat( Cba_Ntk_t * p, int * pCounts, int * pUserCounts )
321 {
322 Cba_Ntk_t * pNtk; int i;
323 printf( "Primitives (%d):\n", Cba_NtkBoxPrimNum(p) );
324 for ( i = 0; i < CBA_BOX_LAST; i++ )
325 if ( pCounts[i] )
326 printf( "%-20s = %5d\n", Cba_NtkTypeName(p, i), pCounts[i] );
327 printf( "User hierarchy (%d):\n", Cba_NtkBoxUserNum(p) );
328 Cba_ManForEachNtk( p->pDesign, pNtk, i )
329 if ( pUserCounts[i] )
330 printf( "%-20s = %5d\n", Cba_NtkName(pNtk), pUserCounts[i] );
331 }
Cba_NtkPrintDistribOld(Cba_Ntk_t * p)332 void Cba_NtkPrintDistribOld( Cba_Ntk_t * p )
333 {
334 int pCounts[CBA_BOX_LAST] = {0};
335 int * pUserCounts = ABC_CALLOC( int, Cba_ManNtkNum(p->pDesign) + 1 );
336 Cba_ManCreatePrimMap( p->pDesign->pTypeNames );
337 Cba_NtkCollectDistrib( p, pCounts, pUserCounts );
338 Cba_NtkPrintDistribStat( p, pCounts, pUserCounts );
339 ABC_FREE( pUserCounts );
340 }
341
Cba_ManPrintDistribStat(Cba_Man_t * p,int * pCounts,int * pUserCounts)342 void Cba_ManPrintDistribStat( Cba_Man_t * p, int * pCounts, int * pUserCounts )
343 {
344 Cba_Ntk_t * pNtk = Cba_ManRoot(p); int i;
345 printf( "Primitives:\n" );
346 for ( i = 0; i < CBA_BOX_LAST; i++ )
347 if ( pCounts[i] )
348 printf( "%-20s = %5d\n", Cba_NtkTypeName(pNtk, i), pCounts[i] );
349 printf( "User hierarchy:\n" );
350 Cba_ManForEachNtk( p, pNtk, i )
351 if ( pUserCounts[i] )
352 printf( "%-20s = %5d\n", Cba_NtkName(pNtk), pUserCounts[i] );
353 }
Cba_ManPrintDistrib(Cba_Man_t * p)354 void Cba_ManPrintDistrib( Cba_Man_t * p )
355 {
356 Cba_Ntk_t * pNtk; int i;
357 int pCounts[CBA_BOX_LAST] = {0};
358 int * pUserCounts = ABC_CALLOC( int, Cba_ManNtkNum(p) + 1 );
359 Cba_ManCreatePrimMap( p->pTypeNames );
360 Cba_ManForEachNtk( p, pNtk, i )
361 Cba_NtkCollectDistrib( pNtk, pCounts, pUserCounts );
362 Cba_ManPrintDistribStat( p, pCounts, pUserCounts );
363 ABC_FREE( pUserCounts );
364 }
365
366 /**Function*************************************************************
367
368 Synopsis [Order objects by box type and then by name.]
369
370 Description []
371
372 SideEffects []
373
374 SeeAlso []
375
376 ***********************************************************************/
377 // compares two numbers with the first mismatching char in i-th position
Cba_CharIsDigit(char c)378 static inline int Cba_CharIsDigit( char c ) { return c >= '0' && c <= '9'; }
Cba_StrCmpInt(char * p1,char * p2,int i)379 int Cba_StrCmpInt( char * p1, char * p2, int i )
380 {
381 // check if one of the mismatching chars is a digit
382 if ( Cba_CharIsDigit(p1[i]) || Cba_CharIsDigit(p2[i]) )
383 {
384 // if previous (equal) char was a digit or if this is first digit on both sides, scroll back
385 if ( (i > 0 && Cba_CharIsDigit(p1[i-1])) || (Cba_CharIsDigit(p1[i]) && Cba_CharIsDigit(p2[i])) )
386 {
387 int Num1, Num2;
388 // find the first digit
389 for ( --i; i >= 0; i-- )
390 if ( !Cba_CharIsDigit(p1[i]) )
391 break;
392 i++;
393 // current char is digit
394 assert( Cba_CharIsDigit(p1[i]) );
395 assert( Cba_CharIsDigit(p2[i]) );
396 // previous char does not exist or is not a digit
397 assert( i == 0 || !Cba_CharIsDigit(p1[i-1]) );
398 assert( i == 0 || !Cba_CharIsDigit(p2[i-1]) );
399 // compare numbers
400 Num1 = atoi( p1 + i );
401 Num2 = atoi( p2 + i );
402 if ( Num1 < Num2 )
403 return -1;
404 if ( Num1 > Num2 )
405 return 1;
406 assert( 0 );
407 return 0;
408 }
409 }
410 // compare as usual
411 if ( p1[i] < p2[i] )
412 return -1;
413 if ( p1[i] > p2[i] )
414 return 1;
415 assert( 0 );
416 return 0;
417 }
Cba_StrCmp(char ** pp1,char ** pp2)418 int Cba_StrCmp( char ** pp1, char ** pp2 )
419 {
420 char * p1 = *pp1;
421 char * p2 = *pp2; int i;
422 for ( i = 0; p1[i] && p2[i]; i++ )
423 if ( p1[i] != p2[i] )
424 return Cba_StrCmpInt( p1, p2, i );
425 assert( !p1[i] || !p2[i] );
426 return Cba_StrCmpInt( p1, p2, i );
427 }
Cba_NtkObjOrder(Cba_Ntk_t * p,Vec_Int_t * vObjs,Vec_Int_t * vNameIds)428 void Cba_NtkObjOrder( Cba_Ntk_t * p, Vec_Int_t * vObjs, Vec_Int_t * vNameIds )
429 {
430 char Buffer[1000], * pName;
431 Vec_Ptr_t * vNames;
432 int i, iObj;
433 if ( Vec_IntSize(vObjs) < 2 )
434 return;
435 vNames = Vec_PtrAlloc( Vec_IntSize(vObjs) );
436 Vec_IntForEachEntry( vObjs, iObj, i )
437 {
438 char * pTypeName = Cba_NtkTypeName( p, Cba_ObjType(p, iObj) );
439 char * pInstName = vNameIds ? Cba_NtkStr(p, Vec_IntEntry(vNameIds, i)) : Cba_ObjNameStr(p, iObj);
440 sprintf( Buffer, "%s_%s_%d", pTypeName, pInstName, iObj );
441 Vec_PtrPush( vNames, Abc_UtilStrsav(Buffer) );
442 }
443 // print before
444 // Vec_PtrForEachEntry( char *, vNames, pName, i )
445 // printf( "%s \n", pName );
446 // printf( "\n" );
447 // do the sorting
448 Vec_PtrSort( vNames, (int (*)(void))Cba_StrCmp );
449 // print after
450 // Vec_PtrForEachEntry( char *, vNames, pName, i )
451 // printf( "%s \n", pName );
452 // printf( "\n" );
453 // reload in a new order
454 Vec_IntClear( vObjs );
455 Vec_PtrForEachEntry( char *, vNames, pName, i )
456 Vec_IntPush( vObjs, atoi(strrchr(pName, '_')+1) );
457 Vec_PtrFreeFree( vNames );
458 }
459
460
461 /**Function*************************************************************
462
463 Synopsis [Returns the number of CI fons.]
464
465 Description []
466
467 SideEffects []
468
469 SeeAlso []
470
471 ***********************************************************************/
Cba_NtkCiFonNum(Cba_Ntk_t * p)472 int Cba_NtkCiFonNum( Cba_Ntk_t * p )
473 {
474 int i, iObj, Count = Cba_NtkPiNum(p);
475 Cba_NtkForEachBoxSeq( p, iObj, i )
476 Count += Cba_ObjFonNum(p, iObj);
477 return Count;
478 }
Cba_NtkCoFinNum(Cba_Ntk_t * p)479 int Cba_NtkCoFinNum( Cba_Ntk_t * p )
480 {
481 int i, iObj, Count = Cba_NtkPoNum(p);
482 Cba_NtkForEachBoxSeq( p, iObj, i )
483 Count += Cba_ObjFinNum(p, iObj);
484 return Count;
485 }
486
487 /**Function*************************************************************
488
489 Synopsis [Returns 1 if the manager is in the topo order.]
490
491 Description []
492
493 SideEffects []
494
495 SeeAlso []
496
497 ***********************************************************************/
Cba_NtkIsTopoOrder(Cba_Ntk_t * p)498 int Cba_NtkIsTopoOrder( Cba_Ntk_t * p )
499 {
500 int i, k, iObj, iFin, iFanin, fTopo = 1;
501 Vec_Bit_t * vVisited = Vec_BitStart( Cba_NtkObjNum(p) + 1 );
502 // mark PIs and seq objects
503 Cba_NtkForEachPi( p, iObj, i )
504 Vec_BitWriteEntry( vVisited, iObj, 1 );
505 Cba_NtkForEachBoxSeq( p, iObj, i )
506 Vec_BitWriteEntry( vVisited, iObj, 1 );
507 // visit combinational nodes
508 Cba_NtkForEachBox( p, iObj )
509 if ( !Cba_ObjIsSeq(p, iObj) )
510 {
511 Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k )
512 if ( !Vec_BitEntry(vVisited, iFanin) )
513 fTopo = 0;
514 if ( !fTopo )
515 break;
516 Vec_BitWriteEntry( vVisited, iObj, 1 );
517 }
518 // visit POs and seq objects
519 if ( fTopo )
520 Cba_NtkForEachPo( p, iObj, i )
521 {
522 Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k )
523 if ( !Vec_BitEntry(vVisited, iFanin) )
524 fTopo = 0;
525 if ( !fTopo )
526 break;
527 }
528 if ( fTopo )
529 Cba_NtkForEachBoxSeq( p, iObj, i )
530 {
531 Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k )
532 if ( !Vec_BitEntry(vVisited, iFanin) )
533 fTopo = 0;
534 if ( !fTopo )
535 break;
536 }
537 Vec_BitFree( vVisited );
538 return fTopo;
539 }
Cba_ManIsTopoOrder(Cba_Man_t * p)540 int Cba_ManIsTopoOrder( Cba_Man_t * p )
541 {
542 Cba_Ntk_t * pNtk; int i;
543 Cba_ManForEachNtk( p, pNtk, i )
544 if ( !Cba_NtkIsTopoOrder(pNtk) )
545 return 0;
546 return 1;
547 }
548
549 /**Function*************************************************************
550
551 Synopsis [Collects user boxes in the DFS order.]
552
553 Description []
554
555 SideEffects []
556
557 SeeAlso []
558
559 ***********************************************************************/
Cba_NtkCheckComboLoop_rec(Cba_Ntk_t * p,int iObj)560 int Cba_NtkCheckComboLoop_rec( Cba_Ntk_t * p, int iObj )
561 {
562 int k, iFin, iFanin;
563 if ( Cba_ObjIsPi(p, iObj) )
564 return 1;
565 if ( Cba_ObjCopy(p, iObj) == 1 ) // visited
566 return 1;
567 if ( Cba_ObjCopy(p, iObj) == 0 ) // loop
568 return 0;
569 Cba_ObjSetCopy( p, iObj, 0 );
570 Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k )
571 if ( !Cba_ObjIsSeq(p, iFanin) )
572 if ( !Cba_NtkCheckComboLoop_rec( p, iFanin ) )
573 return 0;
574 //Cba_ObjSetCopy( p, iObj, 1 );
575 Vec_IntSetEntry( &p->vObjCopy, iObj, 1 );
576 return 1;
577 }
Cba_NtkCheckComboLoop(Cba_Ntk_t * p)578 int Cba_NtkCheckComboLoop( Cba_Ntk_t * p )
579 {
580 int iObj;
581 Cba_NtkCleanObjCopies( p ); // -1 = not visited; 0 = on the path; 1 = finished
582 Cba_NtkForEachBox( p, iObj )
583 if ( !Cba_ObjIsSeq(p, iObj) )
584 if ( !Cba_NtkCheckComboLoop_rec( p, iObj ) )
585 {
586 printf( "Cyclic dependency of user boxes is detected.\n" );
587 return 0;
588 }
589 return 1;
590 }
591
592 /**Function*************************************************************
593
594 Synopsis [Find one missing object.]
595
596 Description []
597
598 SideEffects []
599
600 SeeAlso []
601
602 ***********************************************************************/
Cba_NtkFindMissing(Vec_Int_t * vObjs,int nObjs)603 int Cba_NtkFindMissing( Vec_Int_t * vObjs, int nObjs )
604 {
605 Vec_Int_t * vMap = Vec_IntStartFull( nObjs + 1 );
606 int i, iObj;
607 Vec_IntForEachEntry( vObjs, iObj, i )
608 Vec_IntWriteEntry( vMap, iObj, i );
609 Vec_IntForEachEntryStart( vMap, i, iObj, 1 )
610 if ( i == -1 )
611 {
612 Vec_IntFree( vMap );
613 return iObj;
614 }
615 Vec_IntFree( vMap );
616 return -1;
617 }
618
619 /**Function*************************************************************
620
621 Synopsis [Collect nodes in the DFS order.]
622
623 Description []
624
625 SideEffects []
626
627 SeeAlso []
628
629 ***********************************************************************/
Cba_NtkCollectDfs_rec(Cba_Ntk_t * p,int iObj,Vec_Int_t * vObjs)630 void Cba_NtkCollectDfs_rec( Cba_Ntk_t * p, int iObj, Vec_Int_t * vObjs )
631 {
632 int iFin, iFanin, k;
633 if ( !Cba_ObjCopy(p, iObj) )
634 return;
635 Cba_ObjSetCopy( p, iObj, 0 );
636 Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k )
637 Cba_NtkCollectDfs_rec( p, iFanin, vObjs );
638 Vec_IntPush( vObjs, iObj );
639 }
Cba_NtkCollectDfs(Cba_Ntk_t * p)640 Vec_Int_t * Cba_NtkCollectDfs( Cba_Ntk_t * p )
641 {
642 int i, k, iObj, iFin, iFanin;
643 Vec_Int_t * vObjs = Vec_IntAlloc( Cba_NtkObjNum(p) );
644 // collect PIs and seq boxes
645 Cba_NtkForEachPi( p, iObj, i )
646 Vec_IntPush( vObjs, iObj );
647 Cba_NtkForEachBoxSeq( p, iObj, i )
648 Vec_IntPush( vObjs, iObj );
649 // prepare leaves
650 Cba_NtkCleanObjCopies( p );
651 Vec_IntForEachEntry( vObjs, iObj, i )
652 Cba_ObjSetCopy( p, iObj, 0 );
653 // collect internal
654 Cba_NtkForEachPo( p, iObj, i )
655 Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k )
656 Cba_NtkCollectDfs_rec( p, iFanin, vObjs );
657 Cba_NtkForEachBoxSeq( p, iObj, i )
658 Cba_ObjForEachFinFaninReal( p, iObj, iFin, iFanin, k )
659 Cba_NtkCollectDfs_rec( p, iFanin, vObjs );
660 // collect POs
661 Cba_NtkForEachPo( p, iObj, i )
662 Vec_IntPush( vObjs, iObj );
663 assert( Vec_IntSize(vObjs) <= Cba_NtkObjNum(p) );
664 if ( Vec_IntSize(vObjs) != Cba_NtkObjNum(p) && !Abc_FrameReadFlag("silentmode") )
665 {
666 int iObj = Cba_NtkFindMissing( vObjs, Cba_NtkObjNum(p) );
667 printf( "Warning: DSF ordering for module \"%s\" collected %d out of %d objects.\n", Cba_NtkName(p), Vec_IntSize(vObjs), Cba_NtkObjNum(p) );
668 printf( " For example, object %d with name \"%s\" is not reachable from outputs.\n",
669 iObj, iObj > 0 ? Cba_FonNameStr( p, Cba_ObjFon0(p, iObj) ) : "<unknown>" );
670 }
671 return vObjs;
672 }
673
674
675 /**Function*************************************************************
676
677 Synopsis [Count number of objects after collapsing.]
678
679 Description []
680
681 SideEffects []
682
683 SeeAlso []
684
685 ***********************************************************************/
Cba_ManGetClpStats_rec(Cba_Ntk_t * p,int * pCountN,int * pCountI,int * pCountO)686 void Cba_ManGetClpStats_rec( Cba_Ntk_t * p, int * pCountN, int * pCountI, int * pCountO )
687 {
688 int iObj, Id = Cba_NtkId(p);
689 if ( pCountN[Id] >= 0 )
690 return;
691 pCountN[Id] = pCountI[Id] = pCountO[Id] = 0;
692 Cba_NtkForEachObj( p, iObj )
693 if ( Cba_ObjIsBoxPrim(p, iObj) )
694 {
695 pCountN[Id] += 1;
696 pCountI[Id] += Cba_ObjFinNum(p, iObj);
697 pCountO[Id] += Cba_ObjFonNum(p, iObj);
698 }
699 else if ( Cba_ObjIsBoxUser(p, iObj) )
700 {
701 int NtkId = Cba_ObjNtkId(p, iObj);
702 Cba_ManGetClpStats_rec( Cba_ObjNtk(p, iObj), pCountN, pCountI, pCountO );
703 pCountN[Id] += pCountN[NtkId] + Cba_ObjFonNum(p, iObj);
704 pCountI[Id] += pCountI[NtkId] + Cba_ObjFonNum(p, iObj);
705 pCountO[Id] += pCountO[NtkId] + Cba_ObjFonNum(p, iObj);
706 }
707 }
Cba_ManGetClpStats(Cba_Man_t * p,int * nObjs,int * nFins,int * nFons)708 void Cba_ManGetClpStats( Cba_Man_t * p, int * nObjs, int * nFins, int * nFons )
709 {
710 int * pCountN = ABC_FALLOC( int, Cba_ManNtkNum(p) + 1 );
711 int * pCountI = ABC_FALLOC( int, Cba_ManNtkNum(p) + 1 );
712 int * pCountO = ABC_FALLOC( int, Cba_ManNtkNum(p) + 1 );
713 Cba_Ntk_t * pRoot = Cba_ManRoot(p);
714 Cba_ManGetClpStats_rec( pRoot, pCountN, pCountI, pCountO );
715 *nObjs = Cba_NtkPioNum(pRoot) + pCountN[Cba_NtkId(pRoot)];
716 *nFins = Cba_NtkPoNum(pRoot) + pCountI[Cba_NtkId(pRoot)];
717 *nFons = Cba_NtkPiNum(pRoot) + pCountO[Cba_NtkId(pRoot)];
718 ABC_FREE( pCountN );
719 ABC_FREE( pCountI );
720 ABC_FREE( pCountO );
721 }
722
723 /**Function*************************************************************
724
725 Synopsis []
726
727 Description []
728
729 SideEffects []
730
731 SeeAlso []
732
733 ***********************************************************************/
Cba_NtkCollapse_rec(Cba_Ntk_t * pNew,Cba_Ntk_t * p,Vec_Int_t * vSigs)734 void Cba_NtkCollapse_rec( Cba_Ntk_t * pNew, Cba_Ntk_t * p, Vec_Int_t * vSigs )
735 {
736 int i, iObj, iObjNew, iFin, iFon;
737 Cba_NtkCleanObjCopies( p );
738 Cba_NtkCleanFonCopies( p );
739 // set PI copies
740 assert( Vec_IntSize(vSigs) == Cba_NtkPiNum(p) );
741 Cba_NtkForEachPiFon( p, iObj, iFon, i )
742 Cba_FonSetCopy( p, iFon, Vec_IntEntry(vSigs, i) );
743 // duplicate primitives and create buffers for user instances
744 Cba_NtkForEachObj( p, iObj )
745 if ( Cba_ObjIsBoxPrim( p, iObj ) )
746 {
747 iObjNew = Cba_ObjDup( pNew, p, iObj );
748 Cba_ObjForEachFon( p, iObj, iFon, i )
749 Cba_FonSetCopy( p, iFon, Cba_ObjFon(pNew, iObjNew, i) );
750 if ( Cba_ObjAttr(p, iObj) )
751 Cba_ObjSetAttrs( pNew, iObjNew, Cba_ObjAttrArray(p, iObj), Cba_ObjAttrSize(p, iObj) );
752 }
753 else if ( Cba_ObjIsBoxUser( p, iObj ) )
754 {
755 Cba_ObjForEachFon( p, iObj, iFon, i )
756 {
757 iObjNew = Cba_ObjAlloc( pNew, CBA_BOX_BUF, 1, 1 );
758 Cba_FonSetCopy( p, iFon, Cba_ObjFon0(pNew, iObjNew) );
759 }
760 }
761 // connect primitives and collapse user instances
762 Cba_NtkForEachObj( p, iObj )
763 if ( Cba_ObjIsBoxPrim( p, iObj ) )
764 {
765 iObjNew = Cba_ObjCopy( p, iObj );
766 Cba_ObjForEachFinFon( p, iObj, iFin, iFon, i )
767 Cba_ObjSetFinFon( pNew, iObjNew, i, Cba_FonCopy(p, iFon) );
768 }
769 else if ( Cba_ObjIsBoxUser( p, iObj ) )
770 {
771 Vec_IntClear( vSigs );
772 Cba_ObjForEachFinFon( p, iObj, iFin, iFon, i )
773 Vec_IntPush( vSigs, Cba_FonCopy(p, iFon) );
774 assert( Vec_IntSize(vSigs) == Cba_ObjFinNum(p, iObj) );
775 Cba_NtkCollapse_rec( pNew, Cba_ObjNtk(p, iObj), vSigs );
776 assert( Vec_IntSize(vSigs) == Cba_ObjFonNum(p, iObj) );
777 Cba_ObjForEachFon( p, iObj, iFon, i )
778 {
779 iObjNew = Cba_FonObj( pNew, Cba_FonCopy(p, iFon) ); // buffer
780 Cba_ObjSetFinFon( pNew, iObjNew, 0, Vec_IntEntry(vSigs, i) );
781 }
782 }
783 // collect POs
784 Vec_IntClear( vSigs );
785 Cba_NtkForEachPoDriverFon( p, iObj, iFon, i )
786 Vec_IntPush( vSigs, Cba_FonCopy(p, iFon) );
787 }
Cba_ManCollapse(Cba_Man_t * p)788 Cba_Man_t * Cba_ManCollapse( Cba_Man_t * p )
789 {
790 Cba_Man_t * pNew = Cba_ManAlloc( p->pSpec, 1, Abc_NamRef(p->pStrs), Abc_NamRef(p->pFuns), Abc_NamStart(100, 24), Hash_IntManRef(p->vHash) );
791 Cba_Ntk_t * pRoot = Cba_ManRoot( p ), * pRootNew;
792 Vec_Int_t * vSigs = Vec_IntAlloc( 1000 );
793 int i, iObj, iObjNew, iFon, nObjs = 0, nFins = 0, nFons = 0;
794 Cba_ManDupTypeNames( pNew, p );
795 Cba_ManGetClpStats( p, &nObjs, &nFins, &nFons );
796 pRootNew = Cba_NtkAlloc( pNew, Cba_NtkNameId(pRoot), Cba_NtkPiNum(pRoot), Cba_NtkPoNum(pRoot), nObjs, nFins, nFons );
797 Cba_NtkAdd( pNew, pRootNew );
798 if ( Cba_NtkHasObjNames(pRoot) )
799 Cba_NtkCleanObjNames( pRootNew );
800 if ( Cba_NtkHasFonNames(pRoot) )
801 Cba_NtkCleanFonNames( pRootNew );
802 if ( Cba_NtkHasObjAttrs(pRoot) )
803 Cba_NtkCleanObjAttrs( pRootNew );
804 if ( Cba_ObjAttr(pRoot, 0) )
805 Cba_ObjSetAttrs( pRootNew, 0, Cba_ObjAttrArray(pRoot, 0), Cba_ObjAttrSize(pRoot, 0) );
806 Cba_NtkCleanObjCopies( pRoot );
807 Cba_NtkForEachPiFon( pRoot, iObj, iFon, i )
808 {
809 iObjNew = Cba_ObjDup( pRootNew, pRoot, iObj );
810 Vec_IntPush( vSigs, Cba_ObjFon0(pRootNew, iObjNew) );
811 if ( Cba_NtkHasObjNames(pRoot) )
812 Cba_ObjSetName( pRootNew, iObjNew, Cba_ObjName(pRoot, iObj) );
813 if ( Cba_NtkHasFonNames(pRoot) )
814 Cba_FonSetName( pRootNew, Cba_ObjFon0(pRootNew, iObjNew), Cba_FonName(pRoot, iFon) );
815 if ( Cba_ObjAttr(pRoot, iObj) )
816 Cba_ObjSetAttrs( pRootNew, iObjNew, Cba_ObjAttrArray(pRoot, iObj), Cba_ObjAttrSize(pRoot, iObj) );
817 }
818 assert( Vec_IntSize(vSigs) == Cba_NtkPiNum(pRoot) );
819 Cba_NtkCollapse_rec( pRootNew, pRoot, vSigs );
820 assert( Vec_IntSize(vSigs) == Cba_NtkPoNum(pRoot) );
821 Cba_NtkForEachPoDriverFon( pRoot, iObj, iFon, i )
822 {
823 iObjNew = Cba_ObjDup( pRootNew, pRoot, iObj );
824 Cba_ObjSetFinFon( pRootNew, iObjNew, 0, Vec_IntEntry(vSigs, i) );
825 if ( Cba_NtkHasObjNames(pRoot) )
826 Cba_ObjSetName( pRootNew, iObjNew, Cba_ObjName(pRoot, iObj) );
827 if ( Cba_NtkHasFonNames(pRoot) )
828 Cba_FonSetName( pRootNew, Vec_IntEntry(vSigs, i), Cba_FonName(pRoot, iFon) );
829 if ( Cba_ObjAttr(pRoot, iObj) )
830 Cba_ObjSetAttrs( pRootNew, iObjNew, Cba_ObjAttrArray(pRoot, iObj), Cba_ObjAttrSize(pRoot, iObj) );
831 }
832 Vec_IntFree( vSigs );
833 assert( Cba_NtkObjNum(pRootNew) == Cba_NtkObjNumAlloc(pRootNew) );
834 assert( Cba_NtkFinNum(pRootNew) == Cba_NtkFinNumAlloc(pRootNew) );
835 assert( Cba_NtkFonNum(pRootNew) == Cba_NtkFonNumAlloc(pRootNew) );
836 // create internal node names
837 Cba_NtkMissingFonNames( pRootNew, "m" );
838 //Cba_NtkPrepareSeq( pRootNew );
839 return pNew;
840 }
841
842
843
844 /**Function*************************************************************
845
846 Synopsis [Performs the reverse of collapsing.]
847
848 Description []
849
850 SideEffects []
851
852 SeeAlso []
853
854 ***********************************************************************/
Cba_NtkCollectInFons(Cba_Ntk_t * p,Vec_Int_t * vObjs)855 Vec_Int_t * Cba_NtkCollectInFons( Cba_Ntk_t * p, Vec_Int_t * vObjs )
856 {
857 Vec_Int_t * vFons = Vec_IntAlloc( 100 );
858 Vec_Bit_t * vVisFons = Vec_BitStart( Cba_NtkFonNum(p) + 1 );
859 int i, k, iObj, iFin, iFon, Entry;
860 // mark fanin fons
861 Vec_IntForEachEntry( vObjs, iObj, i )
862 Cba_ObjForEachFinFon( p, iObj, iFin, iFon, k )
863 if ( iFon > 0 )
864 Vec_BitWriteEntry( vVisFons, iFon, 1 );
865 // unmark internal fons
866 Vec_IntForEachEntry( vObjs, iObj, i )
867 Cba_ObjForEachFon( p, iObj, iFon, k )
868 Vec_BitWriteEntry( vVisFons, iFon, 0 );
869 // collect fons
870 Vec_BitForEachEntry( vVisFons, Entry, iFon )
871 if ( Entry )
872 Vec_IntPush( vFons, iFon );
873 Vec_BitFree( vVisFons );
874 return vFons;
875 }
Cba_NtkCollectOutFons(Cba_Ntk_t * p,Vec_Int_t * vObjs)876 Vec_Int_t * Cba_NtkCollectOutFons( Cba_Ntk_t * p, Vec_Int_t * vObjs )
877 {
878 Vec_Int_t * vFons = Vec_IntAlloc( 100 );
879 Vec_Bit_t * vMapObjs = Vec_BitStart( Cba_NtkObjNum(p) + 1 );
880 Vec_Bit_t * vVisFons = Vec_BitStart( Cba_NtkFonNum(p) + 1 );
881 int i, k, iObj, iFin, iFon;
882 // map objects
883 Vec_IntForEachEntry( vObjs, iObj, i )
884 Vec_BitWriteEntry( vMapObjs, iObj, 1 );
885 // mark those used by non-objects
886 Cba_NtkForEachObj( p, iObj )
887 if ( !Vec_BitEntry(vMapObjs, iObj) )
888 Cba_ObjForEachFinFon( p, iObj, iFin, iFon, k )
889 if ( iFon > 0 )
890 Vec_BitWriteEntry( vVisFons, iFon, 1 );
891 // collect pointed fons among those in objects
892 Vec_IntForEachEntry( vObjs, iObj, i )
893 Cba_ObjForEachFon( p, iObj, iFon, k )
894 if ( Vec_BitEntry(vVisFons, iFon) )
895 Vec_IntPush( vFons, iFon );
896 Vec_BitFree( vMapObjs );
897 Vec_BitFree( vVisFons );
898 return vFons;
899 }
Cba_NtkCollectGroupStats(Cba_Ntk_t * p,Vec_Int_t * vObjs,int * pnFins,int * pnFons)900 void Cba_NtkCollectGroupStats( Cba_Ntk_t * p, Vec_Int_t * vObjs, int * pnFins, int * pnFons )
901 {
902 int i, iObj, nFins = 0, nFons = 0;
903 Vec_IntForEachEntry( vObjs, iObj, i )
904 {
905 nFins += Cba_ObjFinNum(p, iObj);
906 nFons += Cba_ObjFonNum(p, iObj);
907 }
908 *pnFins = nFins;
909 *pnFons = nFons;
910 }
Cba_ManExtractGroupInt(Cba_Ntk_t * pNew,Cba_Ntk_t * p,Vec_Int_t * vObjs,Vec_Int_t * vFonIns,Vec_Int_t * vFonOuts)911 void Cba_ManExtractGroupInt( Cba_Ntk_t * pNew, Cba_Ntk_t * p, Vec_Int_t * vObjs, Vec_Int_t * vFonIns, Vec_Int_t * vFonOuts )
912 {
913 int i, k, iObj, iObjNew, iFin, iFon;
914 Cba_NtkCleanObjCopies( p );
915 Cba_NtkCleanFonCopies( p );
916 // create inputs and map fons
917 Vec_IntForEachEntry( vFonIns, iFon, i )
918 {
919 iObjNew = Cba_ObjAlloc( pNew, CBA_OBJ_PI, 0, 1 );
920 Cba_FonSetCopy( p, iFon, Cba_ObjFon0(pNew, iObjNew) );
921 if ( Cba_NtkHasObjNames(p) )
922 Cba_ObjSetName( pNew, iObjNew, Cba_ObjName(p, Cba_FonObj(p, iFon)) );
923 if ( Cba_NtkHasFonNames(p) )
924 Cba_FonSetName( pNew, Cba_ObjFon0(pNew, iObjNew), Cba_FonName(p, iFon) );
925
926 }
927 // create internal
928 Vec_IntForEachEntry( vObjs, iObj, i )
929 {
930 iObjNew = Cba_ObjDup( pNew, p, iObj );
931 if ( Cba_NtkHasObjNames(p) )
932 Cba_ObjSetName( pNew, iObjNew, Cba_ObjName(p, iObj) );
933 Cba_ObjForEachFon( p, iObj, iFon, k )
934 {
935 Cba_FonSetCopy( p, iFon, Cba_ObjFon(pNew, iObjNew, k) );
936 if ( Cba_NtkHasFonNames(p) )
937 Cba_FonSetName( pNew, Cba_ObjFon(pNew, iObjNew, k), Cba_FonName(p, iFon) );
938 }
939 }
940 // connect internal
941 Vec_IntForEachEntry( vObjs, iObj, i )
942 {
943 iObjNew = Cba_ObjCopy( p, iObj );
944 Cba_ObjForEachFinFon( p, iObj, iFin, iFon, k )
945 Cba_ObjSetFinFon( pNew, iObjNew, k, Cba_FonCopy(p, iFon) );
946 }
947 // create POs
948 Vec_IntForEachEntry( vFonOuts, iFon, i )
949 {
950 iObjNew = Cba_ObjAlloc( pNew, CBA_OBJ_PO, 1, 0 );
951 if ( Cba_NtkHasObjNames(p) )
952 Cba_ObjSetName( pNew, iObjNew, Cba_FonName(p, iFon) );
953 Cba_ObjSetFinFon( pNew, iObjNew, 0, Cba_FonCopy(p, iFon) );
954 }
955 assert( Cba_NtkObjNum(pNew) == Cba_NtkObjNumAlloc(pNew) );
956 assert( Cba_NtkFinNum(pNew) == Cba_NtkFinNumAlloc(pNew) );
957 assert( Cba_NtkFonNum(pNew) == Cba_NtkFonNumAlloc(pNew) );
958 }
Cba_ManExtractGroup(Cba_Man_t * p,Vec_Int_t * vObjs)959 Cba_Man_t * Cba_ManExtractGroup( Cba_Man_t * p, Vec_Int_t * vObjs )
960 {
961 Cba_Man_t * pNew = Cba_ManAlloc( p->pSpec, 1, Abc_NamRef(p->pStrs), Abc_NamRef(p->pFuns), Abc_NamStart(100, 24), Hash_IntManRef(p->vHash) );
962 Cba_Ntk_t * pRoot = Cba_ManRoot( p ), * pRootNew;
963 Vec_Int_t * vFonIns = Cba_NtkCollectInFons( pRoot, vObjs );
964 Vec_Int_t * vFonOuts = Cba_NtkCollectOutFons( pRoot, vObjs );
965 int nObjs, nFins, nFons;
966 Cba_ManDupTypeNames( pNew, p );
967 // collect stats
968 Cba_NtkCollectGroupStats( pRoot, vObjs, &nFins, &nFons );
969 nObjs = Vec_IntSize(vObjs) + Vec_IntSize(vFonIns) + Vec_IntSize(vFonOuts);
970 nFins += Vec_IntSize(vFonOuts);
971 nFons += Vec_IntSize(vFonIns);
972 // create network
973 pRootNew = Cba_NtkAlloc( pNew, Cba_NtkNameId(pRoot), Vec_IntSize(vFonIns), Vec_IntSize(vFonOuts), nObjs, nFins, nFons );
974 Cba_NtkAdd( pNew, pRootNew );
975 if ( Cba_NtkHasObjNames(pRoot) )
976 Cba_NtkCleanObjNames( pRootNew );
977 if ( Cba_NtkHasFonNames(pRoot) )
978 Cba_NtkCleanFonNames( pRootNew );
979 // add group nodes
980 Cba_ManExtractGroupInt( pRootNew, pRoot, vObjs, vFonIns, vFonOuts );
981 Cba_NtkMissingFonNames( pRootNew, "b" );
982 //Cba_NtkPrepareSeq( pRootNew );
983 // cleanup
984 Vec_IntFree( vFonIns );
985 Vec_IntFree( vFonOuts );
986 return pNew;
987 }
988
989
990 /**Function*************************************************************
991
992 Synopsis [Derives the design from the GIA manager.]
993
994 Description []
995
996 SideEffects []
997
998 SeeAlso []
999
1000 ***********************************************************************/
Cba_NtkInsertGiaLit(Cba_Ntk_t * p,int iLit,Vec_Int_t * vLit2Fon,int fUseXor)1001 static inline int Cba_NtkInsertGiaLit( Cba_Ntk_t * p, int iLit, Vec_Int_t * vLit2Fon, int fUseXor )
1002 {
1003 int iObjNew;
1004 if ( iLit == 0 || iLit == 1 )
1005 return Cba_FonFromConst(iLit);
1006 if ( Vec_IntEntry(vLit2Fon, iLit) >= 0 )
1007 return Vec_IntEntry(vLit2Fon, iLit);
1008 assert( Abc_LitIsCompl(iLit) );
1009 assert( Vec_IntEntry(vLit2Fon, Abc_LitNot(iLit)) >= 0 );
1010 // create inverter
1011 if ( fUseXor )
1012 {
1013 iObjNew = Cba_ObjAlloc( p, CBA_BOX_XOR, 2, 1 );
1014 Cba_ObjSetFinFon( p, iObjNew, 0, Vec_IntEntry(vLit2Fon, Abc_LitNot(iLit)) );
1015 Cba_ObjSetFinFon( p, iObjNew, 1, Cba_FonFromConst(1) );
1016 }
1017 else
1018 {
1019 iObjNew = Cba_ObjAlloc( p, CBA_BOX_INV, 1, 1 );
1020 Cba_ObjSetFinFon( p, iObjNew, 0, Vec_IntEntry(vLit2Fon, Abc_LitNot(iLit)) );
1021 }
1022 // save the result
1023 Vec_IntWriteEntry( vLit2Fon, iLit, Cba_ObjFon0(p, iObjNew) );
1024 return Cba_ObjFon0(p, iObjNew);
1025 }
Cba_NtkInsertGiaObj(Cba_Ntk_t * p,Gia_Man_t * pGia,int iObj,Vec_Int_t * vLit2Fon,int fUseXor)1026 static inline int Cba_NtkInsertGiaObj( Cba_Ntk_t * p, Gia_Man_t * pGia, int iObj, Vec_Int_t * vLit2Fon, int fUseXor )
1027 {
1028 Gia_Obj_t * pObj = Gia_ManObj( pGia, iObj );
1029 int iLit0 = Gia_ObjFaninLit0( pObj, iObj );
1030 int iLit1 = Gia_ObjFaninLit1( pObj, iObj );
1031 int iFon0 = Cba_NtkInsertGiaLit( p, iLit0, vLit2Fon, fUseXor );
1032 int iFon1 = Cba_NtkInsertGiaLit( p, iLit1, vLit2Fon, fUseXor );
1033 int iObjNew;
1034 if ( Gia_ObjIsMux(pGia, pObj) )
1035 {
1036 int iLit2 = Gia_ObjFaninLit2( pGia, iObj );
1037 int iFon2 = Cba_NtkInsertGiaLit( p, iLit2, vLit2Fon, fUseXor );
1038 iObjNew = Cba_ObjAlloc( p, CBA_BOX_MUX, 3, 1 );
1039 Cba_ObjSetFinFon( p, iObjNew, 0, iFon2 );
1040 Cba_ObjSetFinFon( p, iObjNew, 1, iFon1 );
1041 Cba_ObjSetFinFon( p, iObjNew, 2, iFon0 );
1042 }
1043 else
1044 {
1045 assert( Gia_ObjIsAnd(pObj) );
1046 iObjNew = Cba_ObjAlloc( p, Gia_ObjIsXor(pObj) ? CBA_BOX_XOR : CBA_BOX_AND, 2, 1 );
1047 Cba_ObjSetFinFon( p, iObjNew, 0, iFon0 );
1048 Cba_ObjSetFinFon( p, iObjNew, 1, iFon1 );
1049 }
1050 Vec_IntWriteEntry( vLit2Fon, Abc_Var2Lit(iObj, 0), Cba_ObjFon0(p, iObjNew) );
1051 return iObjNew;
1052 }
Cba_ManDeriveFromGia(Cba_Man_t * pOld,Gia_Man_t * pGia,int fUseXor)1053 Cba_Man_t * Cba_ManDeriveFromGia( Cba_Man_t * pOld, Gia_Man_t * pGia, int fUseXor )
1054 {
1055 Cba_Man_t * p = Cba_ManAlloc( pGia->pSpec, 1, pOld ? Abc_NamRef(pOld->pStrs) : NULL, pOld ? Abc_NamRef(pOld->pFuns) : NULL, NULL, NULL );
1056 Cba_Ntk_t * pNtk = Cba_NtkAlloc( p, Abc_NamStrFindOrAdd(p->pStrs, pGia->pName, NULL), Gia_ManCiNum(pGia), Gia_ManCoNum(pGia), 1000, 2000, 2000 );
1057 Vec_Int_t * vLit2Fon = Vec_IntStartFull( 2*Gia_ManObjNum(pGia) );
1058 int i, iObj, iObjNew, NameId, iLit0, iFon0;
1059 Gia_Obj_t * pObj;
1060 //Cba_ManPrepareTypeNames( p );
1061 Cba_NtkAdd( p, pNtk );
1062 Cba_NtkCleanObjNames( pNtk );
1063 Gia_ManForEachCiId( pGia, iObj, i )
1064 {
1065 NameId = pGia->vNamesIn? Abc_NamStrFindOrAdd(p->pStrs, (char*)Vec_PtrEntry(pGia->vNamesIn, i), NULL) : Cba_NtkNewStrId(pNtk, "i%d", i);
1066 iObjNew = Cba_ObjAlloc( pNtk, CBA_OBJ_PI, 0, 1 );
1067 Cba_ObjSetName( pNtk, iObjNew, NameId );
1068 Vec_IntWriteEntry( vLit2Fon, Abc_Var2Lit(iObj, 0), Cba_ObjFon0(pNtk, iObjNew) );
1069 }
1070 Gia_ManForEachAndId( pGia, iObj )
1071 Cba_NtkInsertGiaObj( pNtk, pGia, iObj, vLit2Fon, fUseXor );
1072 // create inverters if needed
1073 Gia_ManForEachCoId( pGia, iObj, i )
1074 {
1075 pObj = Gia_ManObj( pGia, iObj );
1076 iLit0 = Gia_ObjFaninLit0( pObj, iObj );
1077 iFon0 = Cba_NtkInsertGiaLit( pNtk, iLit0, vLit2Fon, fUseXor ); // can be const!
1078 }
1079 Gia_ManForEachCoId( pGia, iObj, i )
1080 {
1081 pObj = Gia_ManObj( pGia, iObj );
1082 iLit0 = Gia_ObjFaninLit0( pObj, iObj );
1083 iFon0 = Cba_NtkInsertGiaLit( pNtk, iLit0, vLit2Fon, fUseXor ); // can be const!
1084 iObjNew = Cba_ObjAlloc( pNtk, CBA_BOX_BUF, 1, 1 );
1085 Cba_ObjSetFinFon( pNtk, iObjNew, 0, iFon0 );
1086 iFon0 = Cba_ObjFon0(pNtk, iObjNew); // non-const fon unique for this output
1087 NameId = pGia->vNamesOut? Abc_NamStrFindOrAdd(p->pStrs, (char*)Vec_PtrEntry(pGia->vNamesOut, i), NULL) : Cba_NtkNewStrId(pNtk, "o%d", i);
1088 iObjNew = Cba_ObjAlloc( pNtk, CBA_OBJ_PO, 1, 0 );
1089 Cba_ObjSetName( pNtk, iObjNew, NameId );
1090 Cba_ObjSetFinFon( pNtk, iObjNew, 0, iFon0 );
1091 }
1092 Cba_NtkCleanFonNames( pNtk );
1093 Cba_NtkCreateFonNames( pNtk, "a" );
1094 Vec_IntFree( vLit2Fon );
1095 return p;
1096 }
1097
1098
1099 /**Function*************************************************************
1100
1101 Synopsis [Inserts the network into the root module instead of objects.]
1102
1103 Description []
1104
1105 SideEffects []
1106
1107 SeeAlso []
1108
1109 ***********************************************************************/
Cba_NtkInsertGroup(Cba_Ntk_t * p,Vec_Int_t * vObjs,Cba_Ntk_t * pSyn)1110 void Cba_NtkInsertGroup( Cba_Ntk_t * p, Vec_Int_t * vObjs, Cba_Ntk_t * pSyn )
1111 {
1112 Vec_Int_t * vFonIns = Cba_NtkCollectInFons( p, vObjs );
1113 Vec_Int_t * vFonOuts = Cba_NtkCollectOutFons( p, vObjs );
1114 int k, iObj, iObjNew, iFin, iFon;
1115 assert( Cba_NtkPiNum(pSyn) == Vec_IntSize(vFonIns) );
1116 assert( Cba_NtkPoNum(pSyn) == Vec_IntSize(vFonOuts) );
1117 // mark AIG with the input fons
1118 Cba_NtkCleanFonCopies( pSyn );
1119 Cba_NtkForEachPiFon( pSyn, iObj, iFon, k )
1120 Cba_FonSetCopy( pSyn, iFon, Vec_IntEntry(vFonIns, k) );
1121 Vec_IntFree( vFonIns );
1122 // build up internal nodes
1123 Cba_NtkCleanObjCopies( pSyn );
1124 Cba_NtkForEachBox( pSyn, iObj )
1125 {
1126 iObjNew = Cba_ObjDup( p, pSyn, iObj );
1127 Cba_ObjForEachFon( pSyn, iObj, iFon, k )
1128 Cba_FonSetCopy( pSyn, iFon, Cba_ObjFon(p, iObjNew, k) );
1129 }
1130 // connect internal nodes
1131 Cba_NtkForEachBox( pSyn, iObj )
1132 {
1133 iObjNew = Cba_ObjCopy( pSyn, iObj );
1134 Cba_ObjForEachFinFon( pSyn, iObj, iFin, iFon, k )
1135 Cba_ObjSetFinFon( p, iObjNew, k, Cba_FonCopy(pSyn, iFon) );
1136 }
1137 // connect output fons
1138 Cba_NtkCleanFonCopies( p );
1139 if ( Cba_NtkHasFonNames(p) )
1140 Vec_IntFillExtra( &p->vFonName, Cba_NtkFonNum(p) + 1, 0 );
1141 Cba_NtkForEachPoDriverFon( pSyn, iObj, iFon, k )
1142 {
1143 assert( Cba_FonIsReal(Cba_FonCopy(pSyn, iFon)) );
1144 Cba_FonSetCopy( p, Vec_IntEntry(vFonOuts, k), Cba_FonCopy(pSyn, iFon) );
1145 // transfer names
1146 if ( Cba_NtkHasFonNames(p) )
1147 {
1148 Cba_FonSetName( p, Cba_FonCopy(pSyn, iFon), Cba_FonName(p, Vec_IntEntry(vFonOuts, k)) );
1149 Cba_FonCleanName( p, Vec_IntEntry(vFonOuts, k) );
1150 }
1151 }
1152 Vec_IntFree( vFonOuts );
1153 // delete nodes
1154 // Vec_IntForEachEntry( vObjs, iObj, k )
1155 // Cba_ObjDelete( p, iObj );
1156 // update fins pointing to output fons to point to the new fons
1157 Cba_NtkForEachFinFon( p, iFon, iFin )
1158 if ( Cba_FonIsReal(iFon) && Cba_FonCopy(p, iFon) )
1159 Cba_PatchFinFon( p, iFin, Cba_FonCopy(p, iFon) );
1160 Cba_NtkMissingFonNames( p, "j" );
1161 /*
1162 // duplicate in DFS order
1163 pNew = Cba_NtkDupOrder( p->pDesign, p, Cba_NtkCollectDfs );
1164 Cba_NtkDupAttrs( pNew, p );
1165 // replace "p" with "pNew"
1166 Cba_NtkUpdate( Cba_NtkMan(p), pNew ); // removes "p"
1167 return pNew;
1168 */
1169 }
Cba_ManInsertGroup(Cba_Man_t * p,Vec_Int_t * vObjs,Cba_Ntk_t * pSyn)1170 Cba_Man_t * Cba_ManInsertGroup( Cba_Man_t * p, Vec_Int_t * vObjs, Cba_Ntk_t * pSyn )
1171 {
1172 Cba_NtkInsertGroup( Cba_ManRoot(p), vObjs, pSyn );
1173 Cba_NtkCheckComboLoop( Cba_ManRoot(p) );
1174 return Cba_ManDup( p, Cba_NtkCollectDfs );
1175 }
1176
1177 ////////////////////////////////////////////////////////////////////////
1178 /// END OF FILE ///
1179 ////////////////////////////////////////////////////////////////////////
1180
1181
1182 ABC_NAMESPACE_IMPL_END
1183
1184