VIS
|
#include "restrInt.h"
Go to the source code of this file.
Functions | |
bdd_node * | RestrMinimizeFsmByFaninFanout (bdd_manager *ddManager, bdd_node *equivRel, bdd_node *oldTR, bdd_node **addPTR, bdd_node **possessedProbMatrix, bdd_node *initBdd, bdd_node *reachable, bdd_node *stateProbs, bdd_node **piVars, bdd_node **xVars, bdd_node **yVars, bdd_node **uVars, bdd_node **vVars, int nVars, int nPi, RestructureHeuristic heuristic, array_t **outBdds, bdd_node **newInit) |
bdd_node* RestrMinimizeFsmByFaninFanout | ( | bdd_manager * | ddManager, |
bdd_node * | equivRel, | ||
bdd_node * | oldTR, | ||
bdd_node ** | addPTR, | ||
bdd_node ** | possessedProbMatrix, | ||
bdd_node * | initBdd, | ||
bdd_node * | reachable, | ||
bdd_node * | stateProbs, | ||
bdd_node ** | piVars, | ||
bdd_node ** | xVars, | ||
bdd_node ** | yVars, | ||
bdd_node ** | uVars, | ||
bdd_node ** | vVars, | ||
int | nVars, | ||
int | nPi, | ||
RestructureHeuristic | heuristic, | ||
array_t ** | outBdds, | ||
bdd_node ** | newInit | ||
) |
CFile***********************************************************************
FileName [restrFaninout.c]
PackageName [restr]
Synopsis [Routines in this file implement the Fanin and Fanin-Fanout oriented restructuring heuristics.]
Description [Routines in the file implement the Fanin oriented and Fanin-Fanout oriented restructuring heuristics.
Please refer to "A symbolic algorithm for low power sequential synthesis," ISLPED 97, for more details.]
SeeAlso [restrHammingD.c restrCProj.c]
Author [Balakrishna Kumthekar <kumtheka@colorado.edu>]
Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [This routine implements the Fanin oriented and Fanin-Fanout oriented restructuring heuristics. Returns the BDD of the restructured STG.]
Description [This routine implements the Fanin oriented and Fanin-Fanout oriented restructuring heuristics. Returns the BDD of the restructured STG.
equivRel
is the state equivalence relation of the fsm. oldTR
if the state transition relation. addPTR
is the 0-1 ADD of the augmented transition relation. possessedProbMatrix
is the weighted graph representing the augmented transition relation. The edge weights are the prob. of transition of that edge. stateProbs
is an ADD representing the steady state probabilities of the fsm. piVars
are the BDD variables for primary inputs. heuristic
takes on two values: RestrFanin_c and RestrFaninFanout_c.
Please refer to "A Symbolic Algorithm for Low-Power Sequential Synthesis", ISLPED 97 for more details.]
SideEffects [addPtr
and possessedProbMatrix
are dereferenced in this routine. outBdds
and newInit
are changed to reflect the restructured STG.]
SeeAlso [RestrMinimizeFsmByCProj RestrSelectLeastHammingDStates]
Definition at line 98 of file restrFaninout.c.
{ bdd_node *temp1, *temp2, *temp3; bdd_node *xCube, *yCube; bdd_node *Rxy,*Rxv; bdd_node *RxvgtRxy, *RxveqRxy; /* These are BDDs */ bdd_node **xAddVars,**yAddVars,**vAddVars; bdd_node *priority, *result, *matrix; bdd_node *newEquivRel; bdd_node *oneInitState; bdd_node *hammingWeight; bdd_node *lhs, *rhs; bdd_node *bddCProj; bdd_node *bddCProjvy, *addCProjvy; bdd_node *newCProjvy, *newCProjux; bdd_node *zeroProbs, *zeroProbFactor; bdd_node *weight; array_t *newOutBdds; int i, index; /* Collect the ADD variables for futre use */ xAddVars = ALLOC(bdd_node *,nVars); yAddVars = ALLOC(bdd_node *,nVars); vAddVars = ALLOC(bdd_node *,nVars); for(i = 0; i < nVars; i++) { index = bdd_node_read_index(yVars[i]); bdd_ref(yAddVars[i] = bdd_add_ith_var(ddManager,index)); index = bdd_node_read_index(vVars[i]); bdd_ref(vAddVars[i] = bdd_add_ith_var(ddManager,index)); index = bdd_node_read_index(xVars[i]); bdd_ref(xAddVars[i] = bdd_add_ith_var(ddManager,index)); } /* Restrict the equivalence relation only to the reachable states */ /* temp1 = R(v) */ bdd_ref(temp1 = bdd_bdd_swap_variables(ddManager,reachable,xVars, vVars,nVars)); /* temp2 = R(y) */ bdd_ref(temp2 = bdd_bdd_swap_variables(ddManager,reachable,xVars, yVars,nVars)); /* temp3 = R(v) * R(y) */ bdd_ref(temp3 = bdd_bdd_and(ddManager,temp1,temp2)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,temp2); /* newEquivRel(v,y) = E(v,y) * R(v) * R(y) */ bdd_ref(newEquivRel = bdd_bdd_and(ddManager,equivRel,temp3)); bdd_recursive_deref(ddManager,temp3); /* Select one state from the set of initial states */ oneInitState = bdd_bdd_pick_one_minterm(ddManager,initBdd,xVars,nVars); bdd_ref(oneInitState); /* Initially an arbitrary choice of a 'nominal representative' for each equivalence class is made--using compatible projection--with the initial state as the reference vertex. bddCProj is as the name indicates, in terms of y and x. bddCProj refers to $\Psi(x,y)$ in the ISLPED 97 reference. */ bdd_ref(temp1 = bdd_bdd_swap_variables(ddManager,oneInitState,xVars, vVars,nVars)); bdd_recursive_deref(ddManager,oneInitState); bdd_ref(bddCProjvy = bdd_bdd_cprojection(ddManager, newEquivRel, temp1)); bdd_recursive_deref(ddManager,newEquivRel); bdd_recursive_deref(ddManager,temp1); bdd_ref(bddCProj = bdd_bdd_swap_variables(ddManager,bddCProjvy,vVars, xVars,nVars)); bdd_ref(addCProjvy = bdd_bdd_to_add(ddManager,bddCProjvy)); bdd_recursive_deref(ddManager,bddCProjvy); /* Let's compute the weight matrix */ /* hammingWeight equal (nVars - HD(x,y)) */ bdd_ref(temp1 = bdd_add_const(ddManager,(double)nVars)); bdd_ref(temp2 = bdd_add_hamming(ddManager,xVars,yVars,nVars)); bdd_ref(hammingWeight = bdd_add_apply(ddManager,bdd_add_minus, temp1,temp2)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,temp2); /* temp1 = possessedProbMatrix * (nVars - HD(x,y)) */ bdd_ref(temp1 = bdd_add_apply(ddManager,bdd_add_times,hammingWeight, *possessedProbMatrix)); bdd_recursive_deref(ddManager,*possessedProbMatrix); /* matrix = possessedProbMatrix * (nVars - HD(x,y)) * stateProbs */ bdd_ref(matrix = bdd_add_apply(ddManager,bdd_add_times,temp1, stateProbs)); bdd_recursive_deref(ddManager,temp1); /* Compute the contribution of the edges that have a state with zero * probability as its source node. The contribution is measured in terms * of the hamming distance between the end points of the edge. * The total weight on any edge is the sum of "matrix" as computed * above and "zeroProbFactor" as computed below. */ bdd_ref(temp1 = bdd_add_bdd_strict_threshold(ddManager,stateProbs,0.0)); bdd_ref(temp2 = bdd_not_bdd_node(temp1)); bdd_recursive_deref(ddManager,temp1); /* zeroProbs evaluates to 1 for those states which have zero steady state * probability. zeroProbs is a 0-1 ADD. */ bdd_ref(zeroProbs = bdd_bdd_to_add(ddManager,temp2)); bdd_recursive_deref(ddManager,temp2); /* temp1 = (1 - HD(x,y)/nVars) */ bdd_ref(temp2 = bdd_add_const(ddManager,(double)nVars)); bdd_ref(temp1 = bdd_add_apply(ddManager,bdd_add_divide,hammingWeight, temp2)); bdd_recursive_deref(ddManager,temp2); bdd_recursive_deref(ddManager,hammingWeight); /* temp2 = (1 - HD(x,y)/nVars) * zeroProbs(x) */ bdd_ref(temp2 = bdd_add_apply(ddManager,bdd_add_times,temp1,zeroProbs)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,zeroProbs); /* zeroProbFactor = (1 - HD(x,y)/nVars) * zeroProbs(x) * addPTR */ bdd_ref(zeroProbFactor = bdd_add_apply(ddManager,bdd_add_times, *addPTR,temp2)); bdd_recursive_deref(ddManager,*addPTR); bdd_recursive_deref(ddManager,temp2); /* Total edge weight = matrix + zeroProbFactor */ bdd_ref(weight = bdd_add_apply(ddManager,bdd_add_plus,matrix, zeroProbFactor)); bdd_recursive_deref(ddManager,matrix); bdd_recursive_deref(ddManager,zeroProbFactor); /* lhs = Abs(x) (weight(x,y)*CProj(v,y)) */ bdd_ref(temp1 = bdd_add_apply(ddManager,bdd_add_times,weight, addCProjvy)); bdd_ref(temp3 = bdd_add_compute_cube(ddManager,xAddVars,NIL(int),nVars)); bdd_ref(lhs = bdd_add_exist_abstract(ddManager,temp1,temp3)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,temp3); /* Now lhs is a function of x and y */ bdd_ref(temp1 = bdd_add_swap_variables(ddManager,lhs,vAddVars,xAddVars, nVars)); bdd_recursive_deref(ddManager,lhs); lhs = temp1; if (heuristic == RestrFaninFanout_c) { /* let's compute the rhs */ bdd_ref(temp1 = bdd_add_swap_variables(ddManager,addCProjvy,yAddVars, xAddVars, nVars)); bdd_recursive_deref(ddManager,addCProjvy); bdd_ref(rhs = bdd_add_apply(ddManager,bdd_add_times,weight,temp1)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,weight); temp1 = rhs; bdd_ref(temp3 = bdd_add_compute_cube(ddManager,yAddVars,NIL(int),nVars)); bdd_ref(rhs = bdd_add_exist_abstract(ddManager,temp1,temp3)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,temp3); /* rhs is now a function of x and y */ bdd_ref(temp1 = bdd_add_swap_variables(ddManager,rhs,xAddVars, yAddVars,nVars)); bdd_recursive_deref(ddManager,rhs); bdd_ref(rhs = bdd_add_swap_variables(ddManager,temp1,vAddVars, xAddVars,nVars)); bdd_recursive_deref(ddManager,temp1); /* take the average of lhs and rhs */ bdd_ref(temp1 = bdd_add_apply(ddManager,bdd_add_plus,lhs,rhs)); bdd_recursive_deref(ddManager,lhs); bdd_recursive_deref(ddManager,rhs); bdd_ref(temp2 = bdd_add_const(ddManager,(double)2.0)); bdd_ref(Rxy = bdd_add_apply(ddManager,bdd_add_divide,temp1,temp2)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,temp2); } else { bdd_recursive_deref(ddManager,weight); bdd_recursive_deref(ddManager,addCProjvy); Rxy = lhs; } /* Rxv = Rxy(x,v) */ bdd_ref(Rxv = bdd_add_swap_variables(ddManager,Rxy,yAddVars,vAddVars, nVars)); /* RxvgtRxy(x,v,y) = Rxv(x,v) > Rxy(x,y) */ bdd_ref(temp1 = bdd_add_apply(ddManager,RestrAddMaximum,Rxv,Rxy)); bdd_ref(RxvgtRxy = bdd_add_bdd_threshold(ddManager,temp1,(double) 1.0)); bdd_recursive_deref(ddManager,temp1); /* RxveqRxy(x,v,y) = Rxz(x,v) == Rxy(x,y) */ bdd_ref(temp1 = bdd_add_apply(ddManager,RestrAddEqual,Rxv,Rxy)); bdd_ref(RxveqRxy = bdd_add_bdd_threshold(ddManager,temp1,(double) 1.0)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,Rxv); bdd_recursive_deref(ddManager,Rxy); /* temp1 is the tie-break function. (RxveqRxy . temp1 = temp2)*/ bdd_ref(temp1 = bdd_dxygtdxz(ddManager,nVars,xVars,yVars,vVars)); bdd_ref(temp2 = bdd_bdd_and(ddManager,RxveqRxy,temp1)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,RxveqRxy); bdd_ref(priority = bdd_bdd_or(ddManager,temp2,RxvgtRxy)); bdd_recursive_deref(ddManager,RxvgtRxy); bdd_recursive_deref(ddManager,temp2); /* temp1 represents the pair (oldrepresentative,newprepresentative) in terms of x and y respectively */ bdd_ref(temp1 = bdd_priority_select(ddManager,bddCProj,xVars, yVars,vVars,priority,nVars,NULL)); bdd_recursive_deref(ddManager,priority); bdd_ref(xCube = bdd_bdd_compute_cube(ddManager,xVars,NIL(int),nVars)); bdd_ref(yCube = bdd_bdd_compute_cube(ddManager,yVars,NIL(int),nVars)); /* newCProjvy is in terms of v,y */ /* v represents the new representative of equivalent states */ bdd_ref(temp2 = bdd_bdd_swap_variables(ddManager,temp1,yVars,vVars, nVars)); bdd_recursive_deref(ddManager,temp1); bdd_ref(newCProjvy = bdd_bdd_and_abstract(ddManager,bddCProj,temp2, xCube)); bdd_recursive_deref(ddManager,bddCProj); bdd_recursive_deref(ddManager,temp2); bdd_ref(temp1 = bdd_bdd_swap_variables(ddManager,newCProjvy,yVars, xVars,nVars)); bdd_ref(newCProjux = bdd_bdd_swap_variables(ddManager,temp1,vVars, uVars,nVars)); bdd_recursive_deref(ddManager,temp1); /* Change the output functions accordingly */ newOutBdds = array_alloc(bdd_node *,0); arrayForEachItem(bdd_node *,*outBdds,i,temp3) { bdd_ref(temp1 = bdd_bdd_and_abstract(ddManager,temp3,newCProjux, xCube)); bdd_ref(temp2 = bdd_bdd_swap_variables(ddManager,temp1,uVars,xVars, nVars)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,temp3); array_insert_last(bdd_node *,newOutBdds,temp2); } array_free(*outBdds); *outBdds = newOutBdds; /* Change the initBdd accordingly */ bdd_ref(temp1 = bdd_bdd_and_abstract(ddManager,initBdd,newCProjux,xCube)); bdd_ref(*newInit = bdd_bdd_swap_variables(ddManager,temp1,uVars,xVars, nVars)); bdd_recursive_deref(ddManager,temp1); /* Compute the new transition relation w.r.t the new CProjection function. * result = newCProjux * oldTR(x,y) * newCProjvy */ bdd_ref(temp1 = bdd_bdd_and(ddManager,xCube,yCube)); bdd_recursive_deref(ddManager,xCube); bdd_recursive_deref(ddManager,yCube); bdd_ref(temp2 = bdd_bdd_and(ddManager,newCProjux,oldTR)); bdd_recursive_deref(ddManager,newCProjux); bdd_ref(temp3 = bdd_bdd_and(ddManager,temp2,newCProjvy)); bdd_recursive_deref(ddManager,newCProjvy); bdd_recursive_deref(ddManager,temp2); bdd_ref(result = bdd_bdd_exist_abstract(ddManager,temp3,temp1)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,temp3); bdd_ref(temp1 = bdd_bdd_swap_variables(ddManager,result,uVars,xVars, nVars)); bdd_ref(temp2 = bdd_bdd_swap_variables(ddManager,temp1,vVars,yVars, nVars)); bdd_recursive_deref(ddManager,temp1); bdd_recursive_deref(ddManager,result); result = temp2; /* Clean up */ for(i = 0; i < nVars; i++) { bdd_recursive_deref(ddManager,yAddVars[i]); bdd_recursive_deref(ddManager,vAddVars[i]); bdd_recursive_deref(ddManager,xAddVars[i]); } FREE(yAddVars); FREE(vAddVars); FREE(xAddVars); /* Return the restructred STG */ return result; }