VIS
|
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