ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
extraUtilMult.c
Go to the documentation of this file.
1
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <assert.h>
25#include "misc/vec/vec.h"
26#include "aig/gia/gia.h"
27
29
33
34typedef struct Abc_BddMan_ Abc_BddMan;
36{
37 int nVars; // the number of variables
38 int nObjs; // the number of nodes used
39 int nObjsAlloc; // the number of nodes allocated
40 int * pUnique; // unique table for nodes
41 int * pNexts; // next pointer for nodes
42 int * pCache; // array of triples <arg0, arg1, AND(arg0, arg1)>
43 int * pObjs; // array of pairs <cof0, cof1> for each node
44 unsigned char * pVars; // array of variables for each node
45 unsigned char * pMark; // array of marks for each BDD node
46 unsigned nUniqueMask; // selection mask for unique table
47 unsigned nCacheMask; // selection mask for computed table
48 int nCacheLookups; // the number of computed table lookups
49 int nCacheMisses; // the number of computed table misses
50 word nMemory; // total amount of memory used (in bytes)
51};
52
53static inline int Abc_BddIthVar( int i ) { return Abc_Var2Lit(i + 1, 0); }
54static inline unsigned Abc_BddHash( int Arg0, int Arg1, int Arg2 ) { return 12582917 * Arg0 + 4256249 * Arg1 + 741457 * Arg2; }
55
56static inline int Abc_BddVar( Abc_BddMan * p, int i ) { return (int)p->pVars[Abc_Lit2Var(i)]; }
57static inline int Abc_BddThen( Abc_BddMan * p, int i ) { return Abc_LitNotCond(p->pObjs[Abc_LitRegular(i)], Abc_LitIsCompl(i)); }
58static inline int Abc_BddElse( Abc_BddMan * p, int i ) { return Abc_LitNotCond(p->pObjs[Abc_LitRegular(i)+1], Abc_LitIsCompl(i)); }
59
60static inline int Abc_BddMark( Abc_BddMan * p, int i ) { return (int)p->pMark[Abc_Lit2Var(i)]; }
61static inline void Abc_BddSetMark( Abc_BddMan * p, int i, int m ){ p->pMark[Abc_Lit2Var(i)] = m; }
62
66
78static inline int Abc_BddUniqueCreateInt( Abc_BddMan * p, int Var, int Then, int Else )
79{
80 int *q = p->pUnique + (Abc_BddHash(Var, Then, Else) & p->nUniqueMask);
81 for ( ; *q; q = p->pNexts + *q )
82 if ( (int)p->pVars[*q] == Var && p->pObjs[*q+*q] == Then && p->pObjs[*q+*q+1] == Else )
83 return Abc_Var2Lit(*q, 0);
84 if ( p->nObjs == p->nObjsAlloc )
85 printf( "Aborting because the number of nodes exceeded %d.\n", p->nObjsAlloc ), fflush(stdout);
86 assert( p->nObjs < p->nObjsAlloc );
87 *q = p->nObjs++;
88 p->pVars[*q] = Var;
89 p->pObjs[*q+*q] = Then;
90 p->pObjs[*q+*q+1] = Else;
91// printf( "Added node %3d: Var = %3d. Then = %3d. Else = %3d\n", *q, Var, Then, Else );
92 assert( !Abc_LitIsCompl(Else) );
93 return Abc_Var2Lit(*q, 0);
94}
95static inline int Abc_BddUniqueCreate( Abc_BddMan * p, int Var, int Then, int Else )
96{
97 assert( Var >= 0 && Var < p->nVars );
98 assert( Var < Abc_BddVar(p, Then) );
99 assert( Var < Abc_BddVar(p, Else) );
100 if ( Then == Else )
101 return Else;
102 if ( !Abc_LitIsCompl(Else) )
103 return Abc_BddUniqueCreateInt( p, Var, Then, Else );
104 return Abc_LitNot( Abc_BddUniqueCreateInt(p, Var, Abc_LitNot(Then), Abc_LitNot(Else)) );
105}
106
118static inline int Abc_BddCacheLookup( Abc_BddMan * p, int Arg1, int Arg2 )
119{
120 int * pEnt = p->pCache + 3*(Abc_BddHash(0, Arg1, Arg2) & p->nCacheMask);
121 p->nCacheLookups++;
122 return (pEnt[0] == Arg1 && pEnt[1] == Arg2) ? pEnt[2] : -1;
123}
124static inline int Abc_BddCacheInsert( Abc_BddMan * p, int Arg1, int Arg2, int Res )
125{
126 int * pEnt = p->pCache + 3*(Abc_BddHash(0, Arg1, Arg2) & p->nCacheMask);
127 pEnt[0] = Arg1; pEnt[1] = Arg2; pEnt[2] = Res;
128 p->nCacheMisses++;
129 assert( Res >= 0 );
130 return Res;
131}
132
133
145Abc_BddMan * Abc_BddManAlloc( int nVars, int nObjs )
146{
147 Abc_BddMan * p; int i;
148 p = ABC_CALLOC( Abc_BddMan, 1 );
149 p->nVars = nVars;
150 p->nObjsAlloc = nObjs;
151 p->nUniqueMask = (1 << Abc_Base2Log(nObjs)) - 1;
152 p->nCacheMask = (1 << Abc_Base2Log(nObjs)) - 1;
153 p->pUnique = ABC_CALLOC( int, p->nUniqueMask + 1 );
154 p->pNexts = ABC_CALLOC( int, p->nObjsAlloc );
155 p->pCache = ABC_CALLOC( int, 3*(p->nCacheMask + 1) );
156 p->pObjs = ABC_CALLOC( int, 2*p->nObjsAlloc );
157 p->pMark = ABC_CALLOC( unsigned char, p->nObjsAlloc );
158 p->pVars = ABC_CALLOC( unsigned char, p->nObjsAlloc );
159 p->pVars[0] = 0xff;
160 p->nObjs = 1;
161 for ( i = 0; i < nVars; i++ )
162 Abc_BddUniqueCreate( p, i, 1, 0 );
163 assert( p->nObjs == nVars + 1 );
164 p->nMemory = sizeof(Abc_BddMan)/4 +
165 p->nUniqueMask + 1 + p->nObjsAlloc +
166 (p->nCacheMask + 1) * 3 * sizeof(int)/4 +
167 p->nObjsAlloc * 2 * sizeof(int)/4;
168 return p;
169}
171{
172 printf( "BDD stats: Var = %d Obj = %d Alloc = %d Hit = %d Miss = %d ",
173 p->nVars, p->nObjs, p->nObjsAlloc, p->nCacheLookups-p->nCacheMisses, p->nCacheMisses );
174 printf( "Mem = %.2f MB\n", 4.0*(int)(p->nMemory/(1<<20)) );
175 ABC_FREE( p->pUnique );
176 ABC_FREE( p->pNexts );
177 ABC_FREE( p->pCache );
178 ABC_FREE( p->pObjs );
179 ABC_FREE( p->pVars );
180 ABC_FREE( p );
181}
182
194int Abc_BddAnd( Abc_BddMan * p, int a, int b )
195{
196 int r0, r1, r;
197 if ( a == 0 ) return 0;
198 if ( b == 0 ) return 0;
199 if ( a == 1 ) return b;
200 if ( b == 1 ) return a;
201 if ( a == b ) return a;
202 if ( a > b ) return Abc_BddAnd( p, b, a );
203 if ( (r = Abc_BddCacheLookup(p, a, b)) >= 0 )
204 return r;
205 if ( Abc_BddVar(p, a) < Abc_BddVar(p, b) )
206 r0 = Abc_BddAnd( p, Abc_BddElse(p, a), b ),
207 r1 = Abc_BddAnd( p, Abc_BddThen(p, a), b );
208 else if ( Abc_BddVar(p, a) > Abc_BddVar(p, b) )
209 r0 = Abc_BddAnd( p, a, Abc_BddElse(p, b) ),
210 r1 = Abc_BddAnd( p, a, Abc_BddThen(p, b) );
211 else // if ( Abc_BddVar(p, a) == Abc_BddVar(p, b) )
212 r0 = Abc_BddAnd( p, Abc_BddElse(p, a), Abc_BddElse(p, b) ),
213 r1 = Abc_BddAnd( p, Abc_BddThen(p, a), Abc_BddThen(p, b) );
214 r = Abc_BddUniqueCreate( p, Abc_MinInt(Abc_BddVar(p, a), Abc_BddVar(p, b)), r1, r0 );
215 return Abc_BddCacheInsert( p, a, b, r );
216}
217int Abc_BddOr( Abc_BddMan * p, int a, int b )
218{
219 return Abc_LitNot( Abc_BddAnd(p, Abc_LitNot(a), Abc_LitNot(b)) );
220}
221
234{
235 if ( i < 2 )
236 return 0;
237 if ( Abc_BddMark(p, i) )
238 return 0;
239 Abc_BddSetMark( p, i, 1 );
240 return 1 + Abc_BddCount_rec(p, Abc_BddElse(p, i)) + Abc_BddCount_rec(p, Abc_BddThen(p, i));
241}
243{
244 if ( i < 2 )
245 return;
246 if ( !Abc_BddMark(p, i) )
247 return;
248 Abc_BddSetMark( p, i, 0 );
249 Abc_BddUnmark_rec( p, Abc_BddElse(p, i) );
250 Abc_BddUnmark_rec( p, Abc_BddThen(p, i) );
251}
253{
254 int Count = Abc_BddCount_rec( p, i );
255 Abc_BddUnmark_rec( p, i );
256 return Count;
257}
259{
260 int i, a, Count = 0;
261 Vec_IntForEachEntry( vNodes, a, i )
262 Count += Abc_BddCount_rec( p, a );
263 Vec_IntForEachEntry( vNodes, a, i )
264 Abc_BddUnmark_rec( p, a );
265 return Count;
266}
268{
269 int i, a, Count = 0;
270 Vec_IntForEachEntry( vNodes, a, i )
271 {
272 Count += Abc_BddCount_rec( p, a );
273 Abc_BddUnmark_rec( p, a );
274 }
275 return Count;
276}
277
278
279
291void Abc_BddPrint_rec( Abc_BddMan * p, int a, int * pPath )
292{
293 if ( a == 0 )
294 return;
295 if ( a == 1 )
296 {
297 int i;
298 for ( i = 0; i < p->nVars; i++ )
299 if ( pPath[i] == 0 || pPath[i] == 1 )
300 printf( "%c%d", pPath[i] ? '+' : '-', i );
301 printf( " " );
302 return;
303 }
304 pPath[Abc_BddVar(p, a)] = 0;
305 Abc_BddPrint_rec( p, Abc_BddElse(p, a), pPath );
306 pPath[Abc_BddVar(p, a)] = 1;
307 Abc_BddPrint_rec( p, Abc_BddThen(p, a), pPath );
308 pPath[Abc_BddVar(p, a)] = -1;
309}
310void Abc_BddPrint( Abc_BddMan * p, int a )
311{
312 int * pPath = ABC_FALLOC( int, p->nVars );
313 printf( "BDD %d = ", a );
314 Abc_BddPrint_rec( p, a, pPath );
315 ABC_FREE( pPath );
316 printf( "\n" );
317}
319{
320 int bVarA = Abc_BddIthVar(0);
321 int bVarB = Abc_BddIthVar(1);
322 int bVarC = Abc_BddIthVar(2);
323 int bVarD = Abc_BddIthVar(3);
324 int bAndAB = Abc_BddAnd( p, bVarA, bVarB );
325 int bAndCD = Abc_BddAnd( p, bVarC, bVarD );
326 int bFunc = Abc_BddOr( p, bAndAB, bAndCD );
327 Abc_BddPrint( p, bFunc );
328 printf( "Nodes = %d\n", Abc_BddCountNodes(p, bFunc) );
329}
330
331
343void Abc_BddGiaTest2( Gia_Man_t * pGia, int fVerbose )
344{
345 Abc_BddMan * p = Abc_BddManAlloc( 10, 100 );
347 Abc_BddManFree( p );
348}
349
350void Abc_BddGiaTest( Gia_Man_t * pGia, int fVerbose )
351{
352 Abc_BddMan * p;
353 Vec_Int_t * vNodes;
354 Gia_Obj_t * pObj; int i;
355 p = Abc_BddManAlloc( Gia_ManCiNum(pGia), 1 << 20 ); // 30 B/node
356 Gia_ManFillValue( pGia );
357 Gia_ManConst0(pGia)->Value = 0;
358 Gia_ManForEachCi( pGia, pObj, i )
359 pObj->Value = Abc_BddIthVar( i );
360 vNodes = Vec_IntAlloc( Gia_ManAndNum(pGia) );
361 Gia_ManForEachAnd( pGia, pObj, i )
362 {
363 int Cof0 = Abc_LitNotCond(Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj));
364 int Cof1 = Abc_LitNotCond(Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC1(pObj));
365 pObj->Value = Abc_BddAnd( p, Cof0, Cof1 );
366 }
367 Gia_ManForEachCo( pGia, pObj, i )
368 pObj->Value = Abc_LitNotCond(Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj));
369 Gia_ManForEachCo( pGia, pObj, i )
370 {
371 if ( fVerbose )
372 Abc_BddPrint( p, pObj->Value );
373 Vec_IntPush( vNodes, pObj->Value );
374 }
375 printf( "Shared nodes = %d.\n", Abc_BddCountNodesArray2(p, vNodes) );
376 Vec_IntFree( vNodes );
377 Abc_BddManFree( p );
378}
379
380/*
381 abc 04> c.aig; &get; &test
382 Shared nodes = 80.
383 BDD stats: Var = 23 Obj = 206 Alloc = 1048576 Hit = 59 Miss = 216 Mem = 28.00 MB
384
385 abc 05> c.aig; clp -r; ps
386 c : i/o = 23/ 2 lat = 0 nd = 2 edge = 46 bdd = 80 lev = 1
387*/
388
392
393
395
#define ABC_FALLOC(type, num)
Definition abc_global.h:266
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
Cube * p
Definition exorList.c:222
int Var
Definition exorList.c:228
void Abc_BddGiaTest2(Gia_Man_t *pGia, int fVerbose)
void Abc_BddPrintTest(Abc_BddMan *p)
int Abc_BddCount_rec(Abc_BddMan *p, int i)
typedefABC_NAMESPACE_IMPL_START struct Abc_BddMan_ Abc_BddMan
DECLARATIONS ///.
void Abc_BddUnmark_rec(Abc_BddMan *p, int i)
int Abc_BddAnd(Abc_BddMan *p, int a, int b)
void Abc_BddPrint(Abc_BddMan *p, int a)
void Abc_BddGiaTest(Gia_Man_t *pGia, int fVerbose)
int Abc_BddCountNodesArray(Abc_BddMan *p, Vec_Int_t *vNodes)
int Abc_BddCountNodesArray2(Abc_BddMan *p, Vec_Int_t *vNodes)
void Abc_BddPrint_rec(Abc_BddMan *p, int a, int *pPath)
int Abc_BddOr(Abc_BddMan *p, int a, int b)
void Abc_BddManFree(Abc_BddMan *p)
int Abc_BddCountNodes(Abc_BddMan *p, int i)
Abc_BddMan * Abc_BddManAlloc(int nVars, int nObjs)
#define Gia_ManForEachAnd(p, pObj, i)
Definition gia.h:1214
struct Gia_Obj_t_ Gia_Obj_t
Definition gia.h:76
void Gia_ManFillValue(Gia_Man_t *p)
Definition giaUtil.c:369
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
#define Gia_ManForEachCo(p, pObj, i)
Definition gia.h:1236
#define Gia_ManForEachCi(p, pObj, i)
Definition gia.h:1228
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
unsigned char * pMark
unsigned nCacheMask
unsigned nUniqueMask
unsigned char * pVars
unsigned Value
Definition gia.h:89
#define assert(ex)
Definition util_old.h:213
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54