abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
dsdLocal.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [dsdLocal.c]
4 
5  PackageName [DSD: Disjoint-support decomposition package.]
6 
7  Synopsis [Deriving the local function of the DSD node.]
8 
9  Author [Alan Mishchenko]
10 
11  Affiliation [UC Berkeley]
12 
13  Date [Ver. 8.0. Started - September 22, 2003.]
14 
15  Revision [$Id: dsdLocal.c,v 1.0 2002/22/09 00:00:00 alanmi Exp $]
16 
17 ***********************************************************************/
18 
19 #include "dsdInt.h"
20 
22 
23 
24 ////////////////////////////////////////////////////////////////////////
25 /// FUNCTION DECLARATIONS ///
26 ////////////////////////////////////////////////////////////////////////
27 
28 ////////////////////////////////////////////////////////////////////////
29 /// STATIC VARIABLES ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 static DdNode * Extra_dsdRemap( DdManager * dd, DdNode * bFunc, st__table * pCache,
33  int * pVar2Form, int * pForm2Var, DdNode * pbCube0[], DdNode * pbCube1[] );
34 static DdNode * Extra_bddNodePointedByCube( DdManager * dd, DdNode * bF, DdNode * bC );
35 
36 ////////////////////////////////////////////////////////////////////////
37 /// FUNCTION DEFINITIONS ///
38 ////////////////////////////////////////////////////////////////////////
39 
40 /**Function*************************************************************
41 
42  Synopsis [Returns the local function of the DSD node. ]
43 
44  Description [The local function is computed using the global function
45  of the node and the global functions of the formal inputs. The resulting
46  local function is mapped using the topmost N variables of the manager.
47  The number of variables N is equal to the number of formal inputs.]
48 
49  SideEffects []
50 
51  SeeAlso []
52 
53 ***********************************************************************/
55 {
56  int * pForm2Var; // the mapping of each formal input into its first var
57  int * pVar2Form; // the mapping of each var into its formal inputs
58  int i, iVar, iLev, * pPermute;
59  DdNode ** pbCube0, ** pbCube1;
60  DdNode * bFunc, * bRes, * bTemp;
61  st__table * pCache;
62 
63  pPermute = ABC_ALLOC( int, dd->size );
64  pVar2Form = ABC_ALLOC( int, dd->size );
65  pForm2Var = ABC_ALLOC( int, dd->size );
66 
67  pbCube0 = ABC_ALLOC( DdNode *, dd->size );
68  pbCube1 = ABC_ALLOC( DdNode *, dd->size );
69 
70  // remap the global function in such a way that
71  // the support variables of each formal input are adjacent
72  iLev = 0;
73  for ( i = 0; i < pNode->nDecs; i++ )
74  {
75  pForm2Var[i] = dd->invperm[i];
76  for ( bTemp = pNode->pDecs[i]->S; bTemp != b1; bTemp = cuddT(bTemp) )
77  {
78  iVar = dd->invperm[iLev];
79  pPermute[bTemp->index] = iVar;
80  pVar2Form[iVar] = i;
81  iLev++;
82  }
83 
84  // collect the cubes representing each assignment
85  pbCube0[i] = Extra_bddGetOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) );
86  Cudd_Ref( pbCube0[i] );
87  pbCube1[i] = Extra_bddGetOneCube( dd, pNode->pDecs[i]->G );
88  Cudd_Ref( pbCube1[i] );
89  }
90 
91  // remap the function
92  bFunc = Cudd_bddPermute( dd, pNode->G, pPermute ); Cudd_Ref( bFunc );
93  // remap the cube
94  for ( i = 0; i < pNode->nDecs; i++ )
95  {
96  pbCube0[i] = Cudd_bddPermute( dd, bTemp = pbCube0[i], pPermute ); Cudd_Ref( pbCube0[i] );
97  Cudd_RecursiveDeref( dd, bTemp );
98  pbCube1[i] = Cudd_bddPermute( dd, bTemp = pbCube1[i], pPermute ); Cudd_Ref( pbCube1[i] );
99  Cudd_RecursiveDeref( dd, bTemp );
100  }
101 
102  // remap the function
104  bRes = Extra_dsdRemap( dd, bFunc, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes );
105  st__free_table( pCache );
106 
107  Cudd_RecursiveDeref( dd, bFunc );
108  for ( i = 0; i < pNode->nDecs; i++ )
109  {
110  Cudd_RecursiveDeref( dd, pbCube0[i] );
111  Cudd_RecursiveDeref( dd, pbCube1[i] );
112  }
113 /*
114 ////////////
115  // permute the function once again
116  // in such a way that i-th var stood for i-th formal input
117  for ( i = 0; i < dd->size; i++ )
118  pPermute[i] = -1;
119  for ( i = 0; i < pNode->nDecs; i++ )
120  pPermute[dd->invperm[i]] = i;
121  bRes = Cudd_bddPermute( dd, bTemp = bRes, pPermute ); Cudd_Ref( bRes );
122  Cudd_RecursiveDeref( dd, bTemp );
123 ////////////
124 */
125  ABC_FREE(pPermute);
126  ABC_FREE(pVar2Form);
127  ABC_FREE(pForm2Var);
128  ABC_FREE(pbCube0);
129  ABC_FREE(pbCube1);
130 
131  Cudd_Deref( bRes );
132  return bRes;
133 }
134 
135 /**Function*************************************************************
136 
137  Synopsis []
138 
139  Description []
140 
141  SideEffects []
142 
143  SeeAlso []
144 
145 ***********************************************************************/
147  int * pVar2Form, int * pForm2Var, DdNode * pbCube0[], DdNode * pbCube1[] )
148 {
149  DdNode * bFR, * bF0, * bF1;
150  DdNode * bRes0, * bRes1, * bRes;
151  int iForm;
152 
153  bFR = Cudd_Regular(bF);
154  if ( cuddIsConstant(bFR) )
155  return bF;
156 
157  // check the hash-table
158  if ( bFR->ref != 1 )
159  {
160  if ( st__lookup( pCache, (char *)bF, (char **)&bRes ) )
161  return bRes;
162  }
163 
164  // get the formal input
165  iForm = pVar2Form[bFR->index];
166 
167  // get the nodes pointed to by the cube
168  bF0 = Extra_bddNodePointedByCube( dd, bF, pbCube0[iForm] );
169  bF1 = Extra_bddNodePointedByCube( dd, bF, pbCube1[iForm] );
170 
171  // call recursively for these nodes
172  bRes0 = Extra_dsdRemap( dd, bF0, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes0 );
173  bRes1 = Extra_dsdRemap( dd, bF1, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes1 );
174 
175  // derive the result using ITE
176  bRes = Cudd_bddIte( dd, dd->vars[ pForm2Var[iForm] ], bRes1, bRes0 ); Cudd_Ref( bRes );
177  Cudd_RecursiveDeref( dd, bRes0 );
178  Cudd_RecursiveDeref( dd, bRes1 );
179 
180  // add to the hash table
181  if ( bFR->ref != 1 )
182  st__insert( pCache, (char *)bF, (char *)bRes );
183  Cudd_Deref( bRes );
184  return bRes;
185 }
186 
187 /**Function*************************************************************
188 
189  Synopsis []
190 
191  Description []
192 
193  SideEffects []
194 
195  SeeAlso []
196 
197 ***********************************************************************/
199 {
200  DdNode * bFR, * bCR;
201  DdNode * bF0, * bF1;
202  DdNode * bC0, * bC1;
203  int LevelF, LevelC;
204 
205  assert( bC != b0 );
206  if ( bC == b1 )
207  return bF;
208 
209 // bRes = cuddCacheLookup2( dd, Extra_bddNodePointedByCube, bF, bC );
210 // if ( bRes )
211 // return bRes;
212  // there is no need for caching because this operation is very fast
213  // there will no gain reusing the results of this operations
214  // instead, it will flush CUDD cache of other useful entries
215 
216 
217  bFR = Cudd_Regular( bF );
218  bCR = Cudd_Regular( bC );
219  assert( !cuddIsConstant( bFR ) );
220 
221  LevelF = dd->perm[bFR->index];
222  LevelC = dd->perm[bCR->index];
223 
224  if ( LevelF <= LevelC )
225  {
226  if ( bFR != bF )
227  {
228  bF0 = Cudd_Not( cuddE(bFR) );
229  bF1 = Cudd_Not( cuddT(bFR) );
230  }
231  else
232  {
233  bF0 = cuddE(bFR);
234  bF1 = cuddT(bFR);
235  }
236  }
237  else
238  {
239  bF0 = bF1 = bF;
240  }
241 
242  if ( LevelC <= LevelF )
243  {
244  if ( bCR != bC )
245  {
246  bC0 = Cudd_Not( cuddE(bCR) );
247  bC1 = Cudd_Not( cuddT(bCR) );
248  }
249  else
250  {
251  bC0 = cuddE(bCR);
252  bC1 = cuddT(bCR);
253  }
254  }
255  else
256  {
257  bC0 = bC1 = bC;
258  }
259 
260  assert( bC0 == b0 || bC1 == b0 );
261  if ( bC0 == b0 )
262  return Extra_bddNodePointedByCube( dd, bF1, bC1 );
263  return Extra_bddNodePointedByCube( dd, bF0, bC0 );
264 }
265 
266 #if 0
267 
268 /**Function*************************************************************
269 
270  Synopsis []
271 
272  Description []
273 
274  SideEffects []
275 
276  SeeAlso []
277 
278 ***********************************************************************/
279 DdNode * dsdTreeGetPrimeFunction( DdManager * dd, Dsd_Node_t * pNode, int fRemap )
280 {
281  DdNode * bCof0, * bCof1, * bCube0, * bCube1, * bNewFunc, * bTemp;
282  int i;
283  int fAllBuffs = 1;
284  static int Permute[MAXINPUTS];
285 
286  assert( pNode );
287  assert( !Dsd_IsComplement( pNode ) );
288  assert( pNode->Type == DT_PRIME );
289 
290  // transform the function of this block to depend on inputs
291  // corresponding to the formal inputs
292 
293  // first, substitute those inputs that have some blocks associated with them
294  // second, remap the inputs to the top of the manager (then, it is easy to output them)
295 
296  // start the function
297  bNewFunc = pNode->G; Cudd_Ref( bNewFunc );
298  // go over all primary inputs
299  for ( i = 0; i < pNode->nDecs; i++ )
300  if ( pNode->pDecs[i]->Type != DT_BUF ) // remap only if it is not the buffer
301  {
302  bCube0 = Extra_bddFindOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) ); Cudd_Ref( bCube0 );
303  bCof0 = Cudd_Cofactor( dd, bNewFunc, bCube0 ); Cudd_Ref( bCof0 );
304  Cudd_RecursiveDeref( dd, bCube0 );
305 
306  bCube1 = Extra_bddFindOneCube( dd, pNode->pDecs[i]->G ); Cudd_Ref( bCube1 );
307  bCof1 = Cudd_Cofactor( dd, bNewFunc, bCube1 ); Cudd_Ref( bCof1 );
308  Cudd_RecursiveDeref( dd, bCube1 );
309 
310  Cudd_RecursiveDeref( dd, bNewFunc );
311 
312  // use the variable in the i-th level of the manager
313 // bNewFunc = Cudd_bddIte( dd, dd->vars[dd->invperm[i]],bCof1,bCof0 ); Cudd_Ref( bNewFunc );
314  // use the first variale in the support of the component
315  bNewFunc = Cudd_bddIte( dd, dd->vars[pNode->pDecs[i]->S->index],bCof1,bCof0 ); Cudd_Ref( bNewFunc );
316  Cudd_RecursiveDeref( dd, bCof0 );
317  Cudd_RecursiveDeref( dd, bCof1 );
318  }
319 
320  if ( fRemap )
321  {
322  // remap the function to the top of the manager
323  // remap the function to the first variables of the manager
324  for ( i = 0; i < pNode->nDecs; i++ )
325  // Permute[ pNode->pDecs[i]->S->index ] = dd->invperm[i];
326  Permute[ pNode->pDecs[i]->S->index ] = i;
327 
328  bNewFunc = Cudd_bddPermute( dd, bTemp = bNewFunc, Permute ); Cudd_Ref( bNewFunc );
329  Cudd_RecursiveDeref( dd, bTemp );
330  }
331 
332  Cudd_Deref( bNewFunc );
333  return bNewFunc;
334 }
335 
336 #endif
337 
338 ////////////////////////////////////////////////////////////////////////
339 /// END OF FILE ///
340 ////////////////////////////////////////////////////////////////////////
342 
DdHalfWord ref
Definition: cudd.h:280
DdNode * S
Definition: dsdInt.h:58
void st__free_table(st__table *table)
Definition: st.c:81
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
DdNode * G
Definition: dsdInt.h:57
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
int size
Definition: cuddInt.h:361
#define MAXINPUTS
INCLUDES ///.
Definition: cas.h:38
#define b1
Definition: extraBdd.h:76
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdNode * Cudd_bddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:143
Dsd_Node_t ** pDecs
Definition: dsdInt.h:59
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:123
DdNode * Cudd_bddPermute(DdManager *manager, DdNode *node, int *permut)
Definition: cuddCompose.c:332
Definition: st.h:52
DdNode * Dsd_TreeGetPrimeFunction(DdManager *dd, Dsd_Node_t *pNode)
FUNCTION DEFINITIONS ///.
Definition: dsdLocal.c:54
DdNode * Extra_bddGetOneCube(DdManager *dd, DdNode *bFunc)
Definition: extraBddMisc.c:645
static Dds_Cache_t * pCache
Definition: dsdCheck.c:44
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
Dsd_Type_t Type
Definition: dsdInt.h:56
DdNode * Extra_bddFindOneCube(DdManager *dd, DdNode *bF)
Definition: extraBddMisc.c:605
#define Dsd_IsComplement(p)
MACRO DEFINITIONS ///.
Definition: dsd.h:68
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
#define b0
Definition: extraBdd.h:75
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
int * invperm
Definition: cuddInt.h:388
static ABC_NAMESPACE_IMPL_START DdNode * Extra_dsdRemap(DdManager *dd, DdNode *bFunc, st__table *pCache, int *pVar2Form, int *pForm2Var, DdNode *pbCube0[], DdNode *pbCube1[])
FUNCTION DECLARATIONS ///.
Definition: dsdLocal.c:146
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
int * perm
Definition: cuddInt.h:386
int st__ptrhash(const char *, int)
Definition: st.c:468
static DdNode * Extra_bddNodePointedByCube(DdManager *dd, DdNode *bF, DdNode *bC)
Definition: dsdLocal.c:198
short nDecs
Definition: dsdInt.h:61