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