VIS

src/restr/restrUtil.c

Go to the documentation of this file.
00001 
00022 #include "restrInt.h"
00023 
00024 /*---------------------------------------------------------------------------*/
00025 /* Constant declarations                                                     */
00026 /*---------------------------------------------------------------------------*/
00027 
00028 
00029 /*---------------------------------------------------------------------------*/
00030 /* Type declarations                                                         */
00031 /*---------------------------------------------------------------------------*/
00032 
00033 
00034 /*---------------------------------------------------------------------------*/
00035 /* Structure declarations                                                    */
00036 /*---------------------------------------------------------------------------*/
00037 
00038 
00039 /*---------------------------------------------------------------------------*/
00040 /* Variable declarations                                                     */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 
00044 /*---------------------------------------------------------------------------*/
00045 /* Macro declarations                                                        */
00046 /*---------------------------------------------------------------------------*/
00047 
00050 /*---------------------------------------------------------------------------*/
00051 /* Static function prototypes                                                */
00052 /*---------------------------------------------------------------------------*/
00053 
00054 
00058 /*---------------------------------------------------------------------------*/
00059 /* Definition of exported functions                                          */
00060 /*---------------------------------------------------------------------------*/
00061 
00062 
00063 /*---------------------------------------------------------------------------*/
00064 /* Definition of internal functions                                          */
00065 /*---------------------------------------------------------------------------*/
00066 
00078 array_t *
00079 RestrGetOutputArray(Ntk_Network_t *network)
00080 {
00081     lsGen                gen;
00082     Ntk_Node_t  *node;
00083     array_t     *outputArray;
00084 
00085     outputArray = array_alloc(char *, 0);
00086     Ntk_NetworkForEachPrimaryOutput(network, gen, node) {
00087         array_insert_last(char *, outputArray, Ntk_NodeReadName(node));
00088     }
00089 
00090     return outputArray;
00091 }
00092 
00109 bdd_node *
00110 RestrCreateProductOutput(
00111   bdd_manager   *ddManager,
00112   array_t       *funArray,
00113   bdd_node      **xVars,
00114   bdd_node      **yVars,
00115   int           nVars)
00116 {
00117   bdd_node      *ddtemp, *ddtemp1;
00118   bdd_node      *fn, *result;
00119   int           i, num = array_n(funArray);
00120 
00121   bdd_ref(result = bdd_read_one(ddManager));
00122 
00123   for(i = 0; i < num; i++) {
00124 
00125     ddtemp = array_fetch(bdd_node *, funArray, i);;
00126 
00127     ddtemp1 = bdd_bdd_swap_variables(ddManager,ddtemp,xVars,yVars,nVars);
00128     bdd_ref(ddtemp1);
00129     fn = bdd_bdd_xnor(ddManager,ddtemp1,ddtemp);
00130     bdd_ref(fn);
00131     bdd_recursive_deref(ddManager,ddtemp1);
00132     ddtemp1 = bdd_bdd_and(ddManager,result,fn);
00133     bdd_ref(ddtemp1);
00134     bdd_recursive_deref(ddManager,fn);
00135     bdd_recursive_deref(ddManager,result);
00136     result = ddtemp1;
00137   }
00138 
00139   return result;
00140 }
00141 
00162 array_t *
00163 RestrComputeTRWithIds(
00164   bdd_manager   *ddManager,
00165   array_t       *nextBdds,
00166   bdd_node      **xVars,
00167   bdd_node      **yVars,
00168   bdd_node      **uVars,
00169   bdd_node      **vVars,
00170   int           nVars)
00171 {
00172   bdd_node      *ddtemp1, *ddtemp2;
00173   bdd_node      *oldTR, *fn;
00174   array_t       *composite;
00175   int            i;
00176 
00177 
00178   /* First compute oldTR(x,y) = \prod_{i=0}^{i=n-1} (y_i \equiv f_i(x)) */
00179   bdd_ref(oldTR = bdd_read_one(ddManager));
00180 
00181   for(i = 0; i < nVars; i++) {
00182     ddtemp2  = array_fetch(bdd_node *, nextBdds, i);
00183 
00184     fn = bdd_bdd_xnor(ddManager,ddtemp2,yVars[i]);
00185     bdd_ref(fn);
00186     ddtemp1 = bdd_bdd_and(ddManager,oldTR,fn);
00187     bdd_ref(ddtemp1);
00188     bdd_recursive_deref(ddManager,fn);
00189     bdd_recursive_deref(ddManager,oldTR);
00190     oldTR = ddtemp1;
00191   }
00192   
00193   /* fn(u,v) = oldTR(x-->u,y-->v) */
00194   ddtemp2 = bdd_bdd_swap_variables(ddManager,oldTR,xVars,uVars,nVars);
00195   bdd_ref(ddtemp2);
00196   fn = bdd_bdd_swap_variables(ddManager,ddtemp2,yVars,vVars,nVars);
00197   bdd_ref(fn);
00198   bdd_recursive_deref(ddManager,ddtemp2);
00199   ddtemp1 = bdd_bdd_and(ddManager,fn,oldTR);
00200   bdd_ref(ddtemp1);
00201   bdd_recursive_deref(ddManager,fn);
00202 
00203   /* Return both the relations */
00204   composite = array_alloc(bdd_node *,0);
00205   array_insert_last(bdd_node *,composite,oldTR);
00206   array_insert_last(bdd_node *,composite,ddtemp1);
00207 
00208   return composite;
00209 }
00210 
00232 bdd_node *
00233 RestrGetEquivRelation(
00234   bdd_manager           *mgr,
00235   bdd_node        *Lambda,
00236   bdd_node        *tranRelation,
00237   bdd_node      **xVars,
00238   bdd_node      **yVars,
00239   bdd_node      **uVars,
00240   bdd_node      **vVars,
00241   bdd_node      **piVars,
00242   int             nVars,
00243   int             nPi,
00244   boolean restrVerbose)
00245 
00246 {
00247     bdd_node *initialEsp, *espK;
00248     bdd_node *espKPlusOne;
00249     bdd_node *inputCube, *nextCube;
00250     bdd_node **allPreVars, **allNexVars;
00251     bdd_node *temp;
00252     int i,depth;
00253 
00254     allPreVars = ALLOC(bdd_node *, 2*nVars);
00255     allNexVars = ALLOC(bdd_node *, 2*nVars);
00256     for(i = 0; i < nVars;i++) {
00257         allPreVars[i] = xVars[i];
00258         allNexVars[i] = yVars[i];
00259     } 
00260     for(i = 0; i < nVars;i++) {
00261         allPreVars[i+nVars] = uVars[i];
00262         allNexVars[i+nVars] = vVars[i];
00263     } 
00264 
00265     nextCube = bdd_bdd_compute_cube(mgr,allNexVars,NIL(int),2*nVars);
00266     bdd_ref(nextCube);
00267 
00268     inputCube = bdd_bdd_compute_cube(mgr,piVars,NIL(int),nPi);
00269     bdd_ref(inputCube);
00270 
00271     initialEsp = bdd_bdd_univ_abstract(mgr,Lambda,inputCube);
00272     bdd_ref(initialEsp);
00273 
00274     espK = bdd_bdd_swap_variables(mgr,initialEsp,allPreVars,
00275                                  allNexVars,2*nVars);
00276     bdd_ref(espK);
00277     
00278     depth = 0;
00279     do {
00280         bdd_node *image, *temp1;
00281         image = bdd_bdd_and_abstract(mgr,tranRelation, espK, nextCube);
00282         bdd_ref(image);
00283 
00284         temp1 = bdd_bdd_univ_abstract(mgr,image,inputCube);
00285         bdd_ref(temp1);
00286         bdd_recursive_deref(mgr,image);
00287 
00288         espKPlusOne = bdd_bdd_and(mgr,temp1,initialEsp);
00289         bdd_ref(espKPlusOne);
00290         bdd_recursive_deref(mgr,temp1);
00291         temp1 = bdd_bdd_swap_variables(mgr,espKPlusOne,allPreVars,
00292                                      allNexVars,2*nVars);
00293         bdd_ref(temp1);
00294         bdd_recursive_deref(mgr,espKPlusOne);
00295         espKPlusOne = temp1;
00296         
00297         if (espKPlusOne == espK) {
00298           break;
00299         }
00300         bdd_recursive_deref(mgr,espK);
00301         espK = espKPlusOne;
00302         depth++;
00303     } while (1);
00304 
00305     if (restrVerbose)
00306       (void) fprintf(vis_stdout,"** restr info: EQ. relation computation depth = %d\n",
00307                      depth);
00308 
00309     bdd_recursive_deref(mgr,espKPlusOne);
00310     bdd_recursive_deref(mgr,initialEsp);
00311     bdd_recursive_deref(mgr,inputCube);
00312     bdd_recursive_deref(mgr,nextCube);
00313 
00314     bdd_ref(temp = bdd_bdd_swap_variables(mgr,espK,allNexVars,
00315                                           allPreVars,2*nVars));
00316     bdd_recursive_deref(mgr,espK);
00317     espK = temp;
00318 
00319     FREE(allPreVars);
00320     FREE(allNexVars);
00321 
00322     return espK;
00323 }
00324 
00346 bdd_node *
00347 RestrComputeEquivRelationUsingCofactors(
00348   bdd_manager   *mgr,
00349   bdd_node      *Lambda,
00350   bdd_node      *TR,
00351   bdd_node      **xVars,
00352   bdd_node      **yVars,
00353   bdd_node      **uVars,
00354   bdd_node      **vVars,
00355   bdd_node      **piVars,
00356   int             nVars,
00357   int             nPi,
00358   boolean         restrVerbose)
00359 
00360 {
00361   bdd_node *espKxu, *espKyv, *espKPlusOne, *espKMinusOne;
00362   bdd_node *espKCofKMinusOne;
00363   bdd_node *inputCube, *nextCube;
00364   bdd_node *tranRelation;
00365   bdd_node *newTran;
00366   bdd_node **allPreVars, **allNexVars;
00367   int i,depth;
00368 
00369   bdd_ref(tranRelation = TR);
00370 
00371   allPreVars = ALLOC(bdd_node *, 2*nVars);
00372   allNexVars = ALLOC(bdd_node *, 2*nVars);
00373   for(i = 0; i < nVars;i++) {
00374     allPreVars[i] = xVars[i];
00375     allNexVars[i] = yVars[i];
00376   } 
00377   for(i = 0; i < nVars;i++) {
00378     allPreVars[i+nVars] = uVars[i];
00379     allNexVars[i+nVars] = vVars[i];
00380   } 
00381 
00382   /* nextCube is a cube of yVars and vVars */
00383   nextCube = bdd_bdd_compute_cube(mgr,allNexVars,NIL(int),2*nVars);
00384   bdd_ref(nextCube);
00385 
00386   /* inputCube is a cube of piVars */
00387   inputCube = bdd_bdd_compute_cube(mgr,piVars,NIL(int),nPi);
00388   bdd_ref(inputCube);
00389 
00390   /* espKxu = \forall_{piVars} Lambda */
00391   espKxu = bdd_bdd_univ_abstract(mgr,Lambda,inputCube);
00392   bdd_ref(espKxu);
00393 
00394   espKyv = bdd_bdd_swap_variables(mgr,espKxu,allPreVars,
00395                                   allNexVars,2*nVars);
00396   bdd_ref(espKyv);
00397   bdd_ref(espKMinusOne = bdd_read_one(mgr));
00398   bdd_ref(espKPlusOne = bdd_read_one(mgr));
00399 
00400   /* The following loop is essentially the following:
00401    * E_{k+1} = E_k \wedge (\forall_x(func)) where
00402    * func = \exists_{yv} ((TR \downarrow E_k) \wedge (E_k \downarrow E_{k-1}))
00403    */
00404   depth = 0;
00405   while (1) {
00406     bdd_node *image, *temp1;
00407         
00408     bdd_recursive_deref(mgr, espKPlusOne);
00409     bdd_ref(espKCofKMinusOne = bdd_bdd_constrain(mgr, espKyv, 
00410                                                  espKMinusOne));
00411     bdd_recursive_deref(mgr, espKMinusOne);
00412     bdd_ref(espKMinusOne = espKyv);
00413 
00414     bdd_ref(newTran = bdd_bdd_constrain(mgr, tranRelation, espKxu));
00415 
00416     image = bdd_bdd_and_abstract(mgr,newTran, espKCofKMinusOne, nextCube);
00417     bdd_ref(image);
00418     bdd_recursive_deref(mgr, newTran);
00419     bdd_recursive_deref(mgr, espKCofKMinusOne);
00420 
00421     temp1 = bdd_bdd_univ_abstract(mgr,image,inputCube);
00422     bdd_ref(temp1);
00423     bdd_recursive_deref(mgr,image);
00424     espKPlusOne = bdd_bdd_and(mgr,temp1,espKxu);
00425     bdd_ref(espKPlusOne);
00426     bdd_recursive_deref(mgr,temp1);
00427 
00428     if (espKPlusOne == espKxu) {
00429       bdd_recursive_deref(mgr,espKMinusOne);
00430       bdd_recursive_deref(mgr,espKxu);
00431       bdd_recursive_deref(mgr,espKyv);
00432       bdd_recursive_deref(mgr,tranRelation);
00433       bdd_recursive_deref(mgr,inputCube);
00434       bdd_recursive_deref(mgr,nextCube);
00435       FREE(allPreVars);
00436       FREE(allNexVars);
00437       if (restrVerbose) {
00438         (void) fprintf(vis_stdout,"** restr info: EQ. relation computation depth = %d\n",
00439                        depth);
00440       }
00441       return espKPlusOne;
00442     }
00443 
00444     bdd_recursive_deref(mgr, espKxu);
00445     bdd_ref(espKxu = espKPlusOne);
00446     bdd_recursive_deref(mgr, espKyv);
00447     espKyv = bdd_bdd_swap_variables(mgr,espKxu,allPreVars,
00448                                     allNexVars,2*nVars);
00449     bdd_ref(espKyv);
00450         
00451     depth++;
00452   }
00453 
00454 }
00455 
00478 bdd_node *
00479 RestrComputeTrWithGhostEdges(
00480   bdd_manager *mgr,
00481   bdd_node **yVars,
00482   bdd_node **vVars,
00483   bdd_node *tr,
00484   bdd_node *equivRelation,
00485   int nVars)
00486 {
00487   bdd_node *abstractCube;
00488   bdd_node *temp;
00489   bdd_node *ghostTR;
00490 
00491   abstractCube = bdd_bdd_compute_cube(mgr,yVars,NIL(int),nVars);
00492   bdd_ref(abstractCube);
00493 
00494   temp = bdd_bdd_and_abstract(mgr,tr,equivRelation,abstractCube);
00495   bdd_ref(temp);
00496   bdd_recursive_deref(mgr,abstractCube);
00497 
00498   ghostTR = bdd_bdd_swap_variables(mgr,temp,vVars,yVars,nVars);
00499   bdd_ref(ghostTR);
00500   bdd_recursive_deref(mgr,temp);
00501 
00502   return ghostTR;
00503 }
00504 
00517 bdd_node *
00518 RestrAddMaximum(
00519   bdd_manager *ddManager,
00520   bdd_node **f,
00521   bdd_node **g)
00522 {
00523   bdd_node *plusInf;
00524   bdd_node *zero, *one;
00525 
00526   zero = bdd_read_zero(ddManager);
00527   one = bdd_read_one(ddManager);
00528   plusInf = bdd_read_plus_infinity(ddManager);
00529 
00530   if(*g == plusInf) {
00531     return zero;
00532   }
00533 
00534   if(bdd_is_constant(*f) && bdd_is_constant(*g)) {
00535     if(bdd_add_value(*f) > bdd_add_value(*g)) {
00536       return one;
00537     } else {
00538       return zero;
00539     }
00540   }
00541   return NULL;
00542 }
00543 
00544 
00558 bdd_node *
00559 RestrAddEqual(
00560   bdd_manager *ddManager,
00561   bdd_node **f,
00562   bdd_node **g)
00563 {
00564   bdd_node *zero, *one;
00565 
00566   zero = bdd_read_zero(ddManager);
00567   one = bdd_read_one(ddManager);
00568 
00569   if(*f == *g) {
00570     return one;
00571   }
00572 
00573   if(bdd_is_constant(*f) && bdd_is_constant(*g)) {
00574       return zero;
00575   }
00576   return NULL;
00577 }
00578 
00592 bdd_node **
00593 RestrBddNodeArrayFromIdArray(
00594   bdd_manager   *ddManager,
00595   array_t       *idArray)
00596 {
00597   bdd_node **xvars;
00598   int i,id;
00599   int nvars = array_n(idArray);
00600 
00601   xvars = ALLOC(bdd_node *, nvars);
00602   if (xvars == NULL)
00603     return NULL;
00604 
00605   for(i = 0; i < nvars; i++) {
00606     id = array_fetch(int,idArray,i);
00607     xvars[i] = bdd_bdd_ith_var(ddManager,id);
00608     bdd_ref(xvars[i]);
00609   }
00610   return xvars;
00611 }
00612 
00628 double 
00629 RestrAverageBitChange(
00630   bdd_manager *manager,
00631   bdd_node *probTR,
00632   bdd_node **xVars,
00633   bdd_node **yVars,
00634   int nVars)
00635 {
00636   bdd_node *diff, *cube, *PA, *QA;
00637   bdd_node **vars;
00638   double Mean;
00639   int i;
00640 
00641   vars = ALLOC(bdd_node *,2*nVars);
00642   for (i = 0; i < nVars; i++) {
00643     vars[i] = bdd_add_ith_var(manager,bdd_node_read_index(xVars[i]));
00644     bdd_ref(vars[i]);
00645   }
00646   for (i = nVars; i < 2*nVars; i++) {
00647     vars[i] = bdd_add_ith_var(manager,bdd_node_read_index(yVars[i-nVars]));
00648     bdd_ref(vars[i]);
00649   }
00650 
00651   cube = bdd_add_compute_cube(manager,vars,NIL(int),2*nVars);
00652   bdd_ref(cube);
00653 
00654   /* Calculate the Hamming distance ADD. This ADD represents the hamming
00655    * distance between two vectors represented by xVars and yVars.
00656    */
00657   bdd_ref(diff = bdd_add_hamming(manager,xVars,yVars,nVars));
00658   bdd_ref(PA = bdd_add_apply(manager,bdd_add_times,probTR,diff));
00659   bdd_recursive_deref(manager,diff);
00660   
00661   /* And now add and abstract all the variables.*/
00662   bdd_ref(QA = bdd_add_exist_abstract(manager,PA,cube));
00663   bdd_recursive_deref(manager,PA);
00664   bdd_recursive_deref(manager,cube);
00665   Mean = (double)bdd_add_value(QA);
00666   bdd_recursive_deref(manager,QA); 
00667 
00668   for (i = 0; i < 2*nVars; i++) {
00669     bdd_recursive_deref(manager,vars[i]);
00670   }
00671   FREE(vars);
00672   return Mean;
00673 }
00674 
00686 array_t *
00687 RestrCreateNewStateVars(
00688   Ntk_Network_t *network,
00689   bdd_manager *ddManager,
00690   bdd_node **xVars,
00691   bdd_node **yVars)
00692 
00693 {
00694   Ntk_Node_t *node1;
00695   char *name, *name1;
00696   array_t *varValues;
00697   array_t *nameArray;
00698   int i,id,index;
00699   int nVars = Ntk_NetworkReadNumLatches(network);
00700 
00701   array_t *uVarIds, *vVarIds;
00702   array_t *result;
00703 
00704   varValues = array_alloc(int, 0);
00705   nameArray = array_alloc(char *,0);    
00706   uVarIds = array_alloc(int, 0);
00707   vVarIds = array_alloc(int, 0);
00708   result = array_alloc(array_t *, 0);
00709 
00710   id = bdd_num_vars(ddManager);
00711 
00712   for (i = 0; i < nVars; i++) {
00713     index = bdd_node_read_index(yVars[i]);
00714     node1 = Ntk_NetworkFindNodeByMddId(network,index);
00715     name = Ntk_NodeReadName(node1);
00716     name1 = util_strcat3(name,"$NTK2","");
00717     array_insert_last(int,varValues,2);
00718     array_insert_last(char *,nameArray,name1);
00719     array_insert_last(int, vVarIds, id);
00720     id++;
00721 
00722     index = bdd_node_read_index(xVars[i]);
00723     node1 = Ntk_NetworkFindNodeByMddId(network,index);
00724     name = Ntk_NodeReadName(node1);
00725     name1 = util_strcat3(name,"$NTK2","");
00726     array_insert_last(int,varValues,2);
00727     array_insert_last(char *,nameArray,name1);
00728     array_insert_last(int, uVarIds, id);
00729     id++;
00730 
00731   }
00732   mdd_create_variables(ddManager,varValues,nameArray,NIL(array_t));
00733 
00734   arrayForEachItem(char *,nameArray,i,name) {
00735     FREE(name);
00736   }
00737   array_free(nameArray);
00738   array_free(varValues);
00739 
00740   array_insert_last(array_t *, result, uVarIds);
00741   array_insert_last(array_t *, result, vVarIds);
00742 
00743   return result;
00744 }
00745 
00746 
00763 void
00764 RestrSetInitialOrder(
00765   Ntk_Network_t *network,
00766   bdd_manager   *ddManager)
00767 
00768 {
00769   Ntk_Node_t *node, *node1;
00770   lsGen gen;
00771   char *name;
00772   array_t       *varValues;
00773   array_t       *nameArray;
00774   int           id;
00775 
00776   varValues = array_alloc(int,0);
00777   nameArray = array_alloc(char *,0);
00778 
00779   id = 0;
00780   Ntk_NetworkForEachLatch(network,gen,node) {
00781     node1 = Ntk_NodeReadShadow(node);
00782     name = util_strsav(Ntk_NodeReadName(node1));
00783     Ntk_NodeSetMddId(node1,id);
00784     array_insert_last(int,varValues,2);
00785     array_insert_last(char *,nameArray,name);
00786     id++;
00787 
00788     name = util_strsav(Ntk_NodeReadName(node));
00789     Ntk_NodeSetMddId(node,id);
00790     array_insert_last(int,varValues,2);
00791     array_insert_last(char *,nameArray,name);
00792     id++;
00793   }
00794 
00795   Ntk_NetworkForEachPrimaryInput(network,gen,node) {
00796     name = util_strsav(Ntk_NodeReadName(node));
00797     Ntk_NodeSetMddId(node,id);
00798     array_insert_last(int,varValues,2);
00799     array_insert_last(char *,nameArray,name);
00800     id++;
00801   }
00802 
00803   mdd_create_variables(ddManager,varValues,nameArray,NIL(array_t));
00804 
00805   id = 0;
00806   arrayForEachItem(char *, nameArray, id, name) {
00807     FREE(name);
00808   }
00809   array_free(nameArray);
00810   array_free(varValues);
00811 
00812 }
00813