VIS
|
00001 00021 #include "spfdInt.h" 00022 00023 /*---------------------------------------------------------------------------*/ 00024 /* Constant declarations */ 00025 /*---------------------------------------------------------------------------*/ 00026 00027 00028 /*---------------------------------------------------------------------------*/ 00029 /* Type declarations */ 00030 /*---------------------------------------------------------------------------*/ 00031 00032 00033 /*---------------------------------------------------------------------------*/ 00034 /* Structure declarations */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 00038 /*---------------------------------------------------------------------------*/ 00039 /* Variable declarations */ 00040 /*---------------------------------------------------------------------------*/ 00041 00042 00043 /*---------------------------------------------------------------------------*/ 00044 /* Macro declarations */ 00045 /*---------------------------------------------------------------------------*/ 00046 00047 00050 /*---------------------------------------------------------------------------*/ 00051 /* Static function prototypes */ 00052 /*---------------------------------------------------------------------------*/ 00053 00054 static bdd_node * ComputeAuxRel(SpfdApplData_t *applData, bdd_node *faninRel, Ntk_Node_t *from, int piSwap); 00055 00059 /*---------------------------------------------------------------------------*/ 00060 /* Definition of exported functions */ 00061 /*---------------------------------------------------------------------------*/ 00062 00063 00064 /*---------------------------------------------------------------------------*/ 00065 /* Definition of internal functions */ 00066 /*---------------------------------------------------------------------------*/ 00067 00076 bdd_node * 00077 SpfdNodeComputeSpfdFromOnAndOffSet( 00078 SpfdApplData_t *applData, 00079 Ntk_Node_t *regNode, 00080 bdd_node *bdd1, 00081 bdd_node *bdd0) 00082 { 00083 bdd_manager *ddManager = applData->ddManager; 00084 int numFanin = Ntk_NodeReadNumFanins(regNode); 00085 bdd_node **yVars,**yAuxVars; 00086 bdd_node *ddTemp,*rel,*spfd; 00087 Ntk_Node_t *fanin; 00088 int j,clean; 00089 00090 /* If bdd1 and bdd0 are not specified, replace bdd1 and bdd0 by the 00091 node's local ON-set and OFF-set respectively */ 00092 clean = 0; 00093 if (bdd1 == NIL(bdd_node) || 00094 bdd0 == NIL(bdd_node)) { 00095 Ntk_Network_t *network; 00096 network = Ntk_NodeReadNetwork(regNode); 00097 bdd_ref(bdd1 = SpfdNodeReadLocalBdd(network,regNode)); 00098 bdd_ref(bdd0 = bdd_not_bdd_node(bdd1)); 00099 /* Delete bdd1 and bdd0 at the end.*/ 00100 clean = 1; 00101 } 00102 00103 /* Array of variables for swapping */ 00104 numFanin = Ntk_NodeReadNumFanins(regNode); 00105 yVars = ALLOC(bdd_node *,numFanin); 00106 yAuxVars = ALLOC(bdd_node *,numFanin); 00107 Ntk_NodeForEachFanin(regNode,j,fanin) { 00108 yVars[j] = bdd_bdd_ith_var(ddManager,Ntk_NodeReadMddId(fanin)); 00109 yAuxVars[j] = bdd_bdd_ith_var(ddManager, 00110 SpfdNodeReadAuxId(applData,fanin)); 00111 } 00112 00113 /* spfd is bdd1(y) * bdd0(y') + bdd1(y') * bdd0(y) */ 00114 bdd_ref(ddTemp = bdd_bdd_swap_variables(ddManager,bdd0, 00115 yVars,yAuxVars,numFanin)); 00116 bdd_ref(rel = bdd_bdd_and(ddManager,bdd1,ddTemp)); 00117 bdd_recursive_deref(ddManager,ddTemp); 00118 00119 bdd_ref(ddTemp = bdd_bdd_swap_variables(ddManager,rel, 00120 yVars,yAuxVars,numFanin)); 00121 bdd_ref(spfd = bdd_bdd_or(ddManager,rel,ddTemp)); 00122 bdd_recursive_deref(ddManager,rel); 00123 bdd_recursive_deref(ddManager,ddTemp); 00124 FREE(yVars); 00125 FREE(yAuxVars); 00126 00127 if (clean) { 00128 bdd_recursive_deref(ddManager,bdd1); 00129 bdd_recursive_deref(ddManager,bdd0); 00130 } 00131 return spfd; 00132 } /* End of SpfdNodeComputeSpfdFromOnAndOffSet */ 00133 00134 00143 bdd_node * 00144 SpfdNodeComputeSpfdFromFanouts( 00145 SpfdApplData_t *applData, 00146 Ntk_Node_t *from) 00147 { 00148 bdd_manager *ddManager = applData->ddManager; 00149 st_table *currBddReq; 00150 st_table *wireTable,*wiresRemoved; 00151 array_t *ordArray; 00152 bdd_node *result,*var,*varAux,*ddTemp,*ddTemp2; 00153 bdd_node *wireSpfd,*toSpfd,*fromSpfd,*xCube; 00154 bdd_node *step1,*faninRel,*faninRelAux,*inter,*final; 00155 bdd_node **firstCompose,**secondCompose; 00156 bdd_node *logicZero; 00157 Ntk_Node_t *fanin,*to; 00158 int index,i,j; 00159 int size,piSwap; 00160 00161 00162 if (Ntk_NodeReadNumFanouts(from) < 1) { 00163 (void) fprintf(vis_stdout, 00164 "** spfd error: Node %s has no fanouts.\n", 00165 Ntk_NodeReadName(from)); 00166 return NIL(bdd_node); 00167 } 00168 currBddReq = applData->currBddReq; 00169 xCube = applData->currXCube; 00170 logicZero = bdd_read_logic_zero(ddManager); 00171 00172 /* Compute the characteristic function of the fanin relation: 00173 faninRel = \prod y_i == f_i(X) */ 00174 faninRel = SpfdComputeNodeArrayRelation(applData,currBddReq,NIL(array_t), 00175 Ntk_NodeReadFanins(from), 00176 TRUE,&piSwap); 00177 00178 /* Convert faninRel(y,pi) to faninRel(\hat{y},pi) */ 00179 faninRelAux = ComputeAuxRel(applData,faninRel,from,piSwap); 00180 00181 /* Compute SPFD wire by wire according to the order specified for 00182 each fanout node. */ 00183 wireTable = applData->currWireTable; 00184 wiresRemoved = applData->wiresRemoved; 00185 bdd_ref(fromSpfd = logicZero); 00186 Ntk_NodeForEachFanout(from,j,to) { 00187 00188 bdd_ref(result = bdd_read_one(ddManager)); 00189 ordArray = SpfdNodeReadFaninOrder(applData,to); 00190 arrayForEachItem(Ntk_Node_t *,ordArray,i,fanin) { 00191 var = bdd_bdd_ith_var(ddManager,Ntk_NodeReadMddId(fanin)); 00192 index = SpfdNodeReadAuxId(applData,fanin); 00193 varAux = bdd_bdd_ith_var(ddManager,index); 00194 00195 if (fanin != from) { 00196 /* XNOR */ 00197 bdd_ref(ddTemp = bdd_bdd_xnor(ddManager,var,varAux)); 00198 } else { 00199 /* XOR */ 00200 bdd_ref(ddTemp = bdd_bdd_xor(ddManager,var,varAux)); 00201 } 00202 bdd_ref(ddTemp2 = bdd_bdd_and(ddManager,result,ddTemp)); 00203 bdd_recursive_deref(ddManager,result); 00204 bdd_recursive_deref(ddManager,ddTemp); 00205 result = ddTemp2; 00206 00207 if (fanin == from) 00208 break; 00209 } 00210 00211 /* Compute AND of result and the SPFD of 'to'. */ 00212 toSpfd = SpfdNodeReadSpfd(applData,to); 00213 if (toSpfd == NIL(bdd_node)) { 00214 (void) fprintf(vis_stderr, 00215 "** spfd error: Spfd expected but not found.\n"); 00216 (void) fprintf(vis_stderr, "To node:\n"); 00217 Ntk_NodePrint(vis_stderr, to, TRUE, TRUE); 00218 (void) fprintf(vis_stderr, "From node:\n"); 00219 Ntk_NodePrint(vis_stderr, from, TRUE, TRUE); 00220 fflush(vis_stderr); 00221 assert(0); 00222 } 00223 bdd_ref(wireSpfd = bdd_bdd_and(ddManager,toSpfd,result)); 00224 bdd_recursive_deref(ddManager,result); 00225 00226 /* Convert wireSpfd from fanout space to fanin space */ 00227 /* Prepare the vectors for composition */ 00228 size = bdd_num_vars(ddManager); 00229 firstCompose = ALLOC(bdd_node *,size); 00230 secondCompose = ALLOC(bdd_node *,size); 00231 for (i = 0; i < size; i++) { 00232 firstCompose[i] = bdd_bdd_ith_var(ddManager,i); 00233 secondCompose[i] = bdd_bdd_ith_var(ddManager,i); 00234 } 00235 00236 arrayForEachItem(Ntk_Node_t *,ordArray,i,fanin) { 00237 int id,auxId; 00238 00239 id = Ntk_NodeReadMddId(fanin); 00240 auxId = SpfdNodeReadAuxId(applData,fanin); 00241 st_lookup(currBddReq,(char *)fanin,(char **)&firstCompose[id]); 00242 secondCompose[auxId] = firstCompose[id]; 00243 } 00244 00245 /* Perform the steps of compose --> existential abstraction twice */ 00246 bdd_ref(step1 = bdd_bdd_vector_compose(ddManager,wireSpfd,firstCompose)); 00247 bdd_recursive_deref(ddManager,wireSpfd); 00248 FREE(firstCompose); 00249 bdd_ref(inter = bdd_bdd_and_abstract(ddManager,faninRel,step1,xCube)); 00250 bdd_recursive_deref(ddManager,step1); 00251 00252 /* The second of compose --> existential abstraction steps */ 00253 bdd_ref(ddTemp = bdd_bdd_vector_compose(ddManager,inter,secondCompose)); 00254 bdd_recursive_deref(ddManager,inter); 00255 FREE(secondCompose); 00256 bdd_ref(final = bdd_bdd_and_abstract(ddManager,faninRelAux, 00257 ddTemp,xCube)); 00258 bdd_recursive_deref(ddManager,ddTemp); 00259 00260 /* Now 'final' is in the fanin space */ 00261 if (final == logicZero) { 00262 st_table *sinkTable; 00263 Ntk_Node_t *tempNode; 00264 boolean add; 00265 00266 /* Check if this wire has already been removed. If yes, skip */ 00267 add = TRUE; 00268 if (st_lookup(wiresRemoved,(char *)from,&sinkTable) && 00269 st_lookup(sinkTable,(char *)to,&tempNode)) { 00270 add = FALSE; 00271 } 00272 00273 if (add) { 00274 if (spfdVerbose > 2) 00275 (void) fprintf(vis_stdout, 00276 "** spfd info: wire %s --> %s has empty spfd.\n", 00277 Ntk_NodeReadName(from),Ntk_NodeReadName(to)); 00278 00279 /* Add to the wireTable */ 00280 if (st_lookup(wireTable,(char *)from,&sinkTable)) { 00281 st_insert(sinkTable,(char *)to,(char *)to); 00282 } else { 00283 sinkTable = st_init_table(st_ptrcmp,st_ptrhash); 00284 st_insert(sinkTable,(char *)to,(char *)to); 00285 st_insert(wireTable,(char *)from,(char *)sinkTable); 00286 } 00287 } 00288 } 00289 00290 bdd_ref(ddTemp = bdd_bdd_or(ddManager,fromSpfd,final)); 00291 bdd_recursive_deref(ddManager,fromSpfd); 00292 bdd_recursive_deref(ddManager,final); 00293 00294 fromSpfd = ddTemp; 00295 } 00296 bdd_recursive_deref(ddManager,faninRel); 00297 bdd_recursive_deref(ddManager,faninRelAux); 00298 00299 /* Swap variables for fromSpfd if necessary */ 00300 if (piSwap) { /* If we have used alternate PI ids */ 00301 ddTemp = SpfdSwapPiAndAltPi(applData,fromSpfd); 00302 bdd_recursive_deref(ddManager,fromSpfd); 00303 fromSpfd = ddTemp; 00304 } 00305 00306 return fromSpfd; 00307 00308 } /* End of SpfdNodeComputeSpfdFromFanouts */ 00309 00310 00324 st_table * 00325 SpfdNodeComputeSCCs( 00326 SpfdApplData_t *applData, 00327 Ntk_Node_t *regNode, 00328 bdd_node **tempVars) 00329 { 00330 bdd_manager *ddManager = applData->ddManager; 00331 st_table *inUseVars = applData->currInUseVars; 00332 Ntk_Node_t *fanin; 00333 st_table *SCC; 00334 bdd_node *spfd,*spfd2,*auxCube; 00335 bdd_node *ddTemp1,*ddTemp2,*logicZero,*faninCube; 00336 bdd_node *Ny,*E1y,*E0y; 00337 bdd_node *from,*To,*new_,*reached; 00338 bdd_node **faninVars,**auxVars; 00339 int i,numFanin,varsAllocated; 00340 00341 numFanin = Ntk_NodeReadNumFanins(regNode); 00342 SCC = st_init_table(st_ptrcmp,st_ptrhash); 00343 spfd = SpfdNodeReadSpfd(applData,regNode); 00344 logicZero = bdd_read_logic_zero(ddManager); 00345 00346 if (spfd == logicZero) 00347 return SCC; 00348 00349 varsAllocated = 0; 00350 /* Allocate variables if necessary */ 00351 if (tempVars == NIL(bdd_node *)) { 00352 tempVars = SpfdAllocateTemporaryVariables(ddManager,inUseVars,numFanin); 00353 varsAllocated = 1; 00354 } 00355 00356 faninVars = ALLOC(bdd_node *,numFanin); 00357 auxVars = ALLOC(bdd_node *,numFanin); 00358 Ntk_NodeForEachFanin(regNode,i,fanin) { 00359 faninVars[i] = bdd_bdd_ith_var(ddManager,Ntk_NodeReadMddId(fanin)); 00360 auxVars[i] = bdd_bdd_ith_var(ddManager, 00361 SpfdNodeReadAuxId(applData,fanin)); 00362 } 00363 00364 bdd_ref(auxCube = bdd_bdd_compute_cube(ddManager,auxVars, 00365 NIL(int),numFanin)); 00366 /* Compute spfd2 = \exists_{\hat{y}} spfd(y,\hat{y}) * 00367 spfd(\hat{y},\tilde{y}) */ 00368 bdd_ref(ddTemp1 = bdd_bdd_swap_variables(ddManager,spfd,faninVars, 00369 auxVars,numFanin)); 00370 bdd_ref(ddTemp2 = bdd_bdd_swap_variables(ddManager,ddTemp1,faninVars, 00371 tempVars,numFanin)); 00372 bdd_recursive_deref(ddManager,ddTemp1); 00373 bdd_ref(spfd2 = bdd_bdd_and_abstract(ddManager,spfd,ddTemp2,auxCube)); 00374 bdd_recursive_deref(ddManager,ddTemp2); 00375 00376 /* SCC computation */ 00377 bdd_ref(faninCube = bdd_bdd_compute_cube(ddManager,faninVars, 00378 NIL(int),numFanin)); 00379 /* Compute N(y) = \exists_{\hat{y}} spfd(y,\hat{y}) */ 00380 bdd_ref(Ny = bdd_bdd_exist_abstract(ddManager,spfd,auxCube)); 00381 bdd_recursive_deref(ddManager,auxCube); 00382 00383 while (Ny != logicZero) { 00384 /* To compute E1(y) perform the fixpoint image computation */ 00385 bdd_ref(from = bdd_bdd_pick_one_minterm(ddManager,Ny,faninVars,numFanin)); 00386 bdd_ref(reached = from); 00387 do { 00388 bdd_ref(ddTemp1 = bdd_bdd_and_abstract(ddManager,spfd2,from,faninCube)); 00389 bdd_recursive_deref(ddManager,from); 00390 bdd_ref(To = bdd_bdd_swap_variables(ddManager,ddTemp1,tempVars, 00391 faninVars,numFanin)); 00392 bdd_recursive_deref(ddManager,ddTemp1); 00393 bdd_ref(new_ = bdd_bdd_and(ddManager,To,bdd_not_bdd_node(reached))); 00394 bdd_recursive_deref(ddManager,To); 00395 bdd_ref(ddTemp1 = bdd_bdd_or(ddManager,reached,new_)); 00396 bdd_recursive_deref(ddManager,reached); 00397 reached = ddTemp1; 00398 from = new_; 00399 } while (new_ != logicZero); 00400 00401 E1y = reached; 00402 00403 /* E_0(y) = \exists_{\hat{y}} spfd(y,\hat{y}) * E_1(y) */ 00404 bdd_ref(ddTemp1 = bdd_bdd_and_abstract(ddManager,spfd,E1y,faninCube)); 00405 bdd_ref(E0y = bdd_bdd_swap_variables(ddManager,ddTemp1,auxVars, 00406 faninVars,numFanin)); 00407 bdd_recursive_deref(ddManager,ddTemp1); 00408 00409 /* Update Ny: Ny = Ny * (E1y + E0y)' */ 00410 bdd_ref(ddTemp1 = bdd_bdd_or(ddManager,E1y,E0y)); 00411 bdd_ref(ddTemp2 = bdd_bdd_and(ddManager,Ny,bdd_not_bdd_node(ddTemp1))); 00412 bdd_recursive_deref(ddManager,ddTemp1); 00413 bdd_recursive_deref(ddManager,Ny); 00414 Ny = ddTemp2; 00415 00416 /* Store E1y and E0y in an st_table */ 00417 st_insert(SCC,(char *)E1y,(char *)E0y); 00418 } 00419 bdd_recursive_deref(ddManager,faninCube); 00420 bdd_recursive_deref(ddManager,Ny); 00421 00422 FREE(auxVars); 00423 FREE(faninVars); 00424 00425 if (varsAllocated) { 00426 long id; 00427 for (i = 0; i < numFanin; i++) { 00428 id = (long) bdd_node_read_index(tempVars[i]); 00429 st_delete(inUseVars,&id,NIL(char *)); 00430 } 00431 FREE(tempVars); 00432 } 00433 00434 return SCC; 00435 00436 } /* End of SpfdNodeComputeSCCs */ 00437 00438 /*---------------------------------------------------------------------------*/ 00439 /* Definition of static functions */ 00440 /*---------------------------------------------------------------------------*/ 00441 00450 static bdd_node * 00451 ComputeAuxRel( 00452 SpfdApplData_t *applData, 00453 bdd_node *faninRel, 00454 Ntk_Node_t *from, 00455 int piSwap) 00456 { 00457 bdd_node **fromVars,**toVars; 00458 int numFi = Ntk_NodeReadNumFanins(from); 00459 int k,altId; 00460 Ntk_Node_t *fanin; 00461 bdd_node *faninRelAux; 00462 st_table *piAltVars; 00463 bdd_manager *ddManager = applData->ddManager; 00464 00465 piAltVars = applData->currPiAltVars; 00466 00467 /* Collect variables for swapping. */ 00468 fromVars = ALLOC(bdd_node *,numFi); 00469 toVars = ALLOC(bdd_node *,numFi); 00470 Ntk_NodeForEachFanin(from,k,fanin) { 00471 int id = Ntk_NodeReadMddId(fanin); 00472 if (piSwap && st_lookup(piAltVars,(char *)(long)id,&altId)) { 00473 fromVars[k] = bdd_bdd_ith_var(ddManager,altId); 00474 } else { 00475 fromVars[k] = bdd_bdd_ith_var(ddManager,id); 00476 } 00477 toVars[k] = bdd_bdd_ith_var(ddManager,SpfdNodeReadAuxId(applData,fanin)); 00478 } 00479 bdd_ref(faninRelAux = bdd_bdd_swap_variables(ddManager,faninRel,fromVars, 00480 toVars,numFi)); 00481 FREE(fromVars); 00482 FREE(toVars); 00483 00484 return faninRelAux; 00485 00486 } /* End of ComputeAuxRel */