VIS
|
00001 00051 #include "ioInt.h" 00052 00053 static char rcsid[] UNUSED = "$Id: ioCheck.c,v 1.11 2005/04/16 06:17:45 fabio Exp $"; 00054 00055 /*---------------------------------------------------------------------------*/ 00056 /* Constant declarations */ 00057 /*---------------------------------------------------------------------------*/ 00058 00059 00060 /*---------------------------------------------------------------------------*/ 00061 /* Type declarations */ 00062 /*---------------------------------------------------------------------------*/ 00063 00064 00065 /*---------------------------------------------------------------------------*/ 00066 /* Stucture declarations */ 00067 /*---------------------------------------------------------------------------*/ 00068 00069 00070 /*---------------------------------------------------------------------------*/ 00071 /* Variable declarations */ 00072 /*---------------------------------------------------------------------------*/ 00073 00074 00075 /*---------------------------------------------------------------------------*/ 00076 /* Macro declarations */ 00077 /*---------------------------------------------------------------------------*/ 00078 00079 00082 /*---------------------------------------------------------------------------*/ 00083 /* Static function prototypes */ 00084 /*---------------------------------------------------------------------------*/ 00085 00086 static boolean _IoModelTestMasterNodeConsistency(Hrc_Model_t *model, Hrc_Node_t *hnode); 00087 static boolean _IoModelTestConnectionConsistency(Hrc_Manager_t *hmgr, Hrc_Model_t *model, Hrc_Node_t *hnode, array_t *subcktArray); 00088 static boolean _IoModelTestLatchConsistency(Hrc_Node_t *hnode); 00089 static boolean _IoModelTestResetConsistency(Hrc_Manager_t *hmgr, Hrc_Model_t *model, Hrc_Node_t *hnode, array_t *resetArray); 00090 static boolean _IoModelTestInternalConnectionConsistency(Hrc_Model_t *model, Hrc_Node_t *hnode, boolean isVerbose); 00091 static boolean _IoModelTestIsAcyclic(Hrc_Model_t *model, Hrc_Node_t *hnode, st_table *varToTable, st_table *outputVarToSubckt, st_table *visitTable); 00092 static void _IoModelTestIsAcyclicError(Hrc_Model_t *model, Var_Variable_t *var); 00093 static int _IoModelTestIsAcyclicRecursive(Hrc_Model_t *model, Hrc_Node_t *hnode, Var_Variable_t *var, st_table *varToTable, st_table *outputVarToSubckt, st_table *visitTable, boolean isResetLogic); 00094 00098 /*---------------------------------------------------------------------------*/ 00099 /* Definition of exported functions */ 00100 /*---------------------------------------------------------------------------*/ 00101 00102 00103 /*---------------------------------------------------------------------------*/ 00104 /* Definition of internal functions */ 00105 /*---------------------------------------------------------------------------*/ 00106 00118 boolean 00119 IoNetworkTestConsistency( 00120 Hrc_Manager_t *hmgr, 00121 array_t *modelArray, 00122 st_table *parserSubcktInfo, 00123 st_table *parserResetInfo, 00124 boolean isVerbose) 00125 { 00126 char *subcktArray, *resetArray; 00127 Hrc_Model_t *model; 00128 Hrc_Node_t *hnode; 00129 int i; 00130 00131 for (i=0; i < array_n(modelArray); i++){ 00132 model = array_fetch(Hrc_Model_t *,modelArray,i); 00133 00134 hnode = Hrc_ModelReadMasterNode(model); 00135 00136 if (_IoModelTestMasterNodeConsistency(model,hnode) == 0){ 00137 return 0; 00138 } 00139 /* the following st_lookup should return 1 */ 00140 (void)st_lookup(parserSubcktInfo,(char *)model,&subcktArray); 00141 if ((array_t *)subcktArray != NIL(array_t)){ 00142 if (_IoModelTestConnectionConsistency(hmgr,model,hnode,(array_t *)subcktArray) == 0){ 00143 return 0; 00144 } 00145 } 00146 /* the following st_lookup should return 1 */ 00147 (void)st_lookup(parserResetInfo,(char *)model,&resetArray); 00148 if ((array_t *)resetArray != NIL(array_t)){ 00149 if (_IoModelTestResetConsistency(hmgr,model,hnode,(array_t *)resetArray) == 0){ 00150 return 0; 00151 } 00152 } 00153 if (_IoModelTestLatchConsistency(hnode) == 0){ 00154 return 0; 00155 } 00156 if (_IoModelTestInternalConnectionConsistency(model,hnode,isVerbose) == 0){ 00157 return 0; 00158 } 00159 } 00160 return 1; 00161 } 00162 00163 /*---------------------------------------------------------------------------*/ 00164 /* Definition of static functions */ 00165 /*---------------------------------------------------------------------------*/ 00166 00178 static boolean 00179 _IoModelTestMasterNodeConsistency( 00180 Hrc_Model_t *model, 00181 Hrc_Node_t *hnode) 00182 { 00183 char *varName; 00184 Var_Variable_t *var; 00185 st_generator *gen; 00186 00187 Hrc_NodeForEachVariable(hnode,gen,varName,var){ 00188 if (Var_VariableTestTypeConsistency(var) == 0){ 00189 st_free_gen(gen); 00190 return 0; 00191 } 00192 } 00193 return 1; 00194 } 00195 00207 static boolean 00208 _IoModelTestConnectionConsistency( 00209 Hrc_Manager_t *hmgr, 00210 Hrc_Model_t *model, 00211 Hrc_Node_t *hnode, 00212 array_t *subcktArray) 00213 { 00214 int i, j; 00215 IoSubckt_t *subckt; 00216 char *nameOfSubcktModel, *instanceName, *formalName, *actualName, *actualPort; 00217 Hrc_Model_t *subcktModel; 00218 Hrc_Node_t *subcktHnode; 00219 st_table *tmpTable; 00220 st_table *outputCheckTable; 00221 array_t *formalNameArray, *actualNameArray, *actualInputArray, *actualOutputArray; 00222 Var_Variable_t *port, *var; 00223 00224 for (i=0; i < array_n(subcktArray); i++){ 00225 subckt = array_fetch(IoSubckt_t *,subcktArray,i); 00226 nameOfSubcktModel = subckt->modelName; 00227 if ((subcktModel = Hrc_ManagerFindModelByName(hmgr,nameOfSubcktModel)) == NIL(Hrc_Model_t)){ 00228 error_append("Error: Model "); 00229 error_append(Hrc_ModelReadName(model)); 00230 error_append(" has a subcircuit whose model "); 00231 error_append(nameOfSubcktModel); 00232 error_append(" is not defined.\n"); 00233 return 0; 00234 } 00235 00236 subcktHnode = Hrc_ModelReadMasterNode(subcktModel); 00237 instanceName = subckt->instanceName; 00238 formalNameArray = subckt->formalNameArray; 00239 actualNameArray = subckt->actualNameArray; 00240 assert(array_n(formalNameArray) == array_n(actualNameArray)); 00241 00242 if (array_n(formalNameArray) != 00243 Hrc_NodeReadNumFormalInputs(subcktHnode) + Hrc_NodeReadNumFormalOutputs(subcktHnode)){ 00244 error_append("Error: Subcircuit "); 00245 error_append(instanceName); 00246 error_append(" in model "); 00247 error_append(Hrc_ModelReadName(model)); 00248 error_append(" and the corresponding model "); 00249 error_append(nameOfSubcktModel); 00250 error_append(" have different number of i/o ports.\n"); 00251 return 0; 00252 } 00253 00254 /* creating a temporary hash table from formal names to actual names */ 00255 tmpTable = st_init_table(strcmp,st_strhash); 00256 for (j=0; j < array_n(formalNameArray); j++){ 00257 formalName = array_fetch(char *,formalNameArray,j); 00258 actualName = array_fetch(char *,actualNameArray,j); 00259 if (st_insert(tmpTable,(char *)formalName,(char *)actualName)){ 00260 error_append("Error: In subcircuit "); 00261 error_append(instanceName); 00262 error_append(" in model "); 00263 error_append(Hrc_ModelReadName(model)); 00264 error_append(", formal variable "); 00265 error_append(formalName); 00266 error_append(" is used more than once.\n"); 00267 st_free_table(tmpTable); 00268 return 0; 00269 } 00270 } 00271 00272 /* create actualInputArray */ 00273 actualInputArray = array_alloc(Var_Variable_t *,0); 00274 actualOutputArray = array_alloc(Var_Variable_t *,0); 00275 Hrc_NodeForEachFormalInput(subcktHnode,j,port){ 00276 if (st_lookup(tmpTable,(char *)Var_VariableReadName(port),&actualPort) == 0){ 00277 error_append("Error: Subcircuit "); 00278 error_append(instanceName); 00279 error_append(" in model "); 00280 error_append(Hrc_ModelReadName(model)); 00281 error_append(" has no actual variable defined for variable "); 00282 error_append(Var_VariableReadName(port)); 00283 error_append(".\n"); 00284 return 0; 00285 } 00286 /* var should get a non-nil pointer */ 00287 var = Hrc_NodeFindVariableByName(hnode,actualPort); 00288 if (Var_VariablesTestHaveSameDomain(var,port) == 0){ 00289 error_append("Error: Formal variable "); 00290 error_append(Var_VariableReadName(port)); 00291 error_append(" and actual variable "); 00292 error_append(actualPort); 00293 error_append(" have different types in subcircuit "); 00294 error_append(instanceName); 00295 error_append(" in model "); 00296 error_append(Hrc_ModelReadName(model)); 00297 error_append(".\n"); 00298 return 0; 00299 } 00300 if (Var_VariableSetSI(var) == -1){ 00301 return 0; 00302 }; 00303 array_insert_last(Var_Variable_t *,actualInputArray,var); 00304 } 00305 00306 /* create actualOutputArray */ 00307 outputCheckTable = st_init_table(strcmp,st_strhash); 00308 Hrc_NodeForEachFormalOutput(subcktHnode,j,port){ 00309 00310 if (st_lookup(tmpTable,(char *)Var_VariableReadName(port),&actualPort) == 0){ 00311 error_append("Error: Subcircuit "); 00312 error_append(instanceName); 00313 error_append(" in model "); 00314 error_append(Hrc_ModelReadName(model)); 00315 error_append(" has no actual variable defined for variable "); 00316 error_append(Var_VariableReadName(port)); 00317 error_append(".\n"); 00318 return 0; 00319 } 00320 if (st_is_member(outputCheckTable,actualPort) == 1){ 00321 error_append("Error: Subcircuit "); 00322 error_append(instanceName); 00323 error_append(" in model "); 00324 error_append(Hrc_ModelReadName(model)); 00325 error_append(" has more than one output connected to the same variable "); 00326 error_append(actualPort); 00327 error_append(".\n"); 00328 return 0; 00329 } 00330 (void)st_insert(outputCheckTable,actualPort,(char *)0); 00331 /* var should get a non-nil pointer */ 00332 var = Hrc_NodeFindVariableByName(hnode,actualPort); 00333 if (Var_VariablesTestHaveSameDomain(var,port) == 0){ 00334 error_append("Error: Formal variable "); 00335 error_append(Var_VariableReadName(port)); 00336 error_append(" and actual variable "); 00337 error_append(actualPort); 00338 error_append(" have different types in subcircuit "); 00339 error_append(instanceName); 00340 error_append(" in model "); 00341 error_append(Hrc_ModelReadName(model)); 00342 error_append(".\n"); 00343 return 0; 00344 } 00345 if (Var_VariableSetSO(var) == -1){ 00346 return 0; 00347 }; 00348 array_insert_last(Var_Variable_t *,actualOutputArray,var); 00349 } 00350 st_free_table(outputCheckTable); 00351 st_free_table(tmpTable); 00352 if (Hrc_ModelAddSubckt(model,subcktModel,instanceName,actualInputArray,actualOutputArray) == 0){ 00353 error_append("Error: Model "); 00354 error_append(Hrc_ModelReadName(model)); 00355 error_append(" has two subcircuits with the same instance name "); 00356 error_append(instanceName); 00357 error_append("\n"); 00358 return 0; 00359 } 00360 } 00361 return 1; 00362 } 00363 00364 00376 static boolean 00377 _IoModelTestLatchConsistency(Hrc_Node_t *hnode) 00378 { 00379 Hrc_Latch_t *latch; 00380 Var_Variable_t *varIn, *varOut; 00381 st_generator *gen; 00382 char *latchName; 00383 00384 Hrc_NodeForEachLatch(hnode,gen,latchName,latch){ 00385 varIn = Hrc_LatchReadInput(latch); 00386 varOut = Hrc_LatchReadOutput(latch); 00387 if (Var_VariablesTestHaveSameDomain(varIn,varOut) == 0){ 00388 error_append("Error: The input and the output of latch "); 00389 error_append(latchName); 00390 error_append(" have different domains.\n"); 00391 return 0; 00392 } 00393 if (Hrc_LatchReadResetTable(latch) == NIL(Tbl_Table_t)){ 00394 error_append("Error: Latch "); 00395 error_append(Var_VariableReadName(varOut)); 00396 error_append(" has no reset table.\n"); 00397 return 0; 00398 } 00399 } 00400 return 1; 00401 } 00402 00415 static boolean 00416 _IoModelTestResetConsistency( 00417 Hrc_Manager_t *hmgr, 00418 Hrc_Model_t *model, 00419 Hrc_Node_t *hnode, 00420 array_t *resetArray) 00421 { 00422 int i; 00423 Var_Variable_t *output; 00424 Tbl_Table_t *resetTable; 00425 Hrc_Latch_t *latch; 00426 00427 for (i=0; i < array_n(resetArray); i++){ 00428 resetTable = array_fetch(Tbl_Table_t *,resetArray,i); 00429 if (Tbl_TableReadNumOutputs(resetTable) != 1){ 00430 error_append("Error: Reset table with output "); 00431 error_append(Var_VariableReadName(Tbl_TableReadIndexVar(resetTable,0,1))); 00432 error_append(" has to be a single output table.\n"); 00433 return 0; 00434 } 00435 output = Tbl_TableReadIndexVar(resetTable,0,1); 00436 if (Var_VariableTestIsPS(output) == 0){ 00437 error_append("Error: Reset table with output "); 00438 error_append(Var_VariableReadName(output)); 00439 error_append(" is not attached to a latch.\n"); 00440 return 0; 00441 } 00442 latch = Hrc_NodeFindLatchByName(hnode,Var_VariableReadName(output)); 00443 if (Hrc_LatchSetResetTable(latch,resetTable) == 0){ 00444 error_append("Error: You try to overwrite the reset table of "); 00445 error_append(Var_VariableReadName(output)); 00446 error_append(".\n"); 00447 return 0; 00448 } 00449 /* once a reset table is associated with a latch, 00450 we remove the table from resetArray */ 00451 array_insert(Tbl_Table_t *,resetArray,i,NIL(Tbl_Table_t)); 00452 } 00453 return 1; 00454 } 00455 00456 00469 static boolean 00470 _IoModelTestInternalConnectionConsistency( 00471 Hrc_Model_t *model, 00472 Hrc_Node_t *hnode, 00473 boolean isVerbose) 00474 { 00475 st_table *varToTable, *outputVarToSubckt, *inputVarToSubckt, *visitTable; 00476 st_generator *gen; 00477 int i, j, status, warningStatus; 00478 Var_Variable_t *var, *actualOutput; 00479 Tbl_Table_t *table; 00480 char *varName, *subcktName, *latchName; 00481 Hrc_Subckt_t *subckt, *anotherSubckt; 00482 Hrc_Latch_t *latch; 00483 00484 /* creates a hash table from variables to tables */ 00485 varToTable = st_init_table(st_ptrcmp,st_ptrhash); 00486 Hrc_NodeForEachNameTable(hnode,i,table){ 00487 Tbl_TableForEachOutputVar(table,j,var){ 00488 if (Var_VariableTestIsPI(var) == 1){ 00489 error_append("Error: Primary input "); 00490 error_append(Var_VariableReadName(var)); 00491 error_append(" is an output of a table in model "); 00492 error_append(Hrc_ModelReadName(model)); 00493 error_append(".\n"); 00494 st_free_table(varToTable); 00495 return 0; 00496 } 00497 if (st_insert(varToTable,(char *)var,(char *)table) == 1){ 00498 error_append("Error: Variable "); 00499 error_append(Var_VariableReadName(var)); 00500 error_append(" is an output of more than one table in model "); 00501 error_append(Hrc_ModelReadName(model)); 00502 error_append(".\n"); 00503 st_free_table(varToTable); 00504 return 0; 00505 } 00506 } 00507 } 00508 Hrc_NodeForEachLatch(hnode,gen,latchName,latch){ 00509 if (st_insert(varToTable,(char *)Hrc_LatchReadOutput(latch),(char *)Hrc_LatchReadResetTable(latch)) == 1){ 00510 error_append("Error: Latch output "); 00511 error_append(Var_VariableReadName(Hrc_LatchReadOutput(latch))); 00512 error_append(" is an output of a table in model "); 00513 error_append(Hrc_ModelReadName(model)); 00514 error_append(".\n"); 00515 st_free_table(varToTable); 00516 return 0; 00517 } 00518 } 00519 00520 /* creates two hash tables 00521 one from output variables of subckts to subckts 00522 the other one from input variables of subckts to subckts */ 00523 outputVarToSubckt = st_init_table(st_ptrcmp,st_ptrhash); 00524 inputVarToSubckt = st_init_table(st_ptrcmp,st_ptrhash); 00525 00526 Hrc_ModelForEachSubckt(model,gen,subcktName,subckt){ 00527 array_t *actualOutputs = Hrc_SubcktReadActualOutputVars(subckt); 00528 array_t *actualInputs = Hrc_SubcktReadActualInputVars(subckt); 00529 00530 for (i=0; i < array_n(actualOutputs); i++){ 00531 actualOutput = array_fetch(Var_Variable_t *,actualOutputs,i); 00532 if (st_lookup(varToTable,(char *)actualOutput,&table) == 1){ 00533 error_append("Error: Subckt output "); 00534 error_append(Var_VariableReadName(actualOutput)); 00535 error_append(" in "); 00536 error_append(subcktName); 00537 error_append(" is an output of a table in model "); 00538 error_append(Hrc_ModelReadName(model)); 00539 error_append(".\n"); 00540 st_free_table(varToTable); 00541 st_free_table(outputVarToSubckt); 00542 st_free_gen(gen); 00543 return 0; 00544 } 00545 if (st_lookup(outputVarToSubckt,(char *)actualOutput,&anotherSubckt) == 1){ 00546 error_append("Error: Subckt output "); 00547 error_append(Var_VariableReadName(actualOutput)); 00548 error_append(" in "); 00549 error_append(subcktName); 00550 error_append(" is also a subckt output of "); 00551 error_append(Hrc_SubcktReadInstanceName(anotherSubckt)); 00552 error_append(" in model "); 00553 error_append(Hrc_ModelReadName(model)); 00554 error_append(".\n"); 00555 st_free_table(varToTable); 00556 st_free_table(outputVarToSubckt); 00557 st_free_gen(gen); 00558 return 0; 00559 } 00560 (void)st_insert(outputVarToSubckt,(char *)actualOutput,(char *)subckt); 00561 } 00562 00563 for (i=0; i < array_n(actualInputs); i++){ 00564 Var_Variable_t *actualInput = array_fetch(Var_Variable_t *,actualInputs,i); 00565 (void)st_insert(inputVarToSubckt,(char *)actualInput,(char *)subckt); 00566 } 00567 00568 } 00569 00570 /* start checking the consistency of a hnode */ 00571 Hrc_NodeForEachVariable(hnode,gen,varName,var) { 00572 if (st_lookup(varToTable,(char *)var,&table) == 0){ 00573 if (Var_VariableTestIsPS(var) == 1 || Var_VariableTestIsPI(var) == 1){ 00574 continue; 00575 } 00576 else { 00577 if (st_lookup(outputVarToSubckt,(char *)var,&subckt) == 0) { 00578 error_append("Error: Variable "); 00579 error_append(varName); 00580 error_append(" is not defined as an output of a table in model "); 00581 error_append(Hrc_ModelReadName(model)); 00582 error_append(".\n"); 00583 st_free_table(varToTable); 00584 st_free_gen(gen); 00585 return 0; 00586 } 00587 } 00588 } 00589 } 00590 00591 00592 /* compute numFanoutTables */ 00593 Hrc_NodeForEachNameTable(hnode,i,table){ 00594 Tbl_TableForEachInputVar(table,j,var){ 00595 Var_VariableIncrementNumFanoutTables(var); 00596 } 00597 } 00598 00599 /* acyclic check */ 00600 visitTable = st_init_table(st_ptrcmp,st_ptrhash); 00601 status = _IoModelTestIsAcyclic(model,hnode,varToTable,outputVarToSubckt,visitTable); 00602 warningStatus = 0; 00603 if (status == 1){ 00604 /* as a by-product of the acyclic check, visitTable now contains 00605 all the variables reachable from either PO, NS, or reset tables. 00606 We use this to detect all the variables not used in the hnode */ 00607 Hrc_NodeForEachVariable(hnode,gen,varName,var){ 00608 if (st_is_member(visitTable,(char *)var) == 0 && 00609 st_is_member(inputVarToSubckt,(char *)var) == 0 && 00610 Var_VariableTestIsPO(var) == 0 && 00611 Var_VariableTestIsNS(var) == 0 && 00612 Var_VariableTestIsPS(var) == 0 ){ 00613 warningStatus = 1; 00614 if (isVerbose){ 00615 /* the following is just a warning. We do not return a failure status */ 00616 error_append("Warning: Variable "); 00617 error_append(Var_VariableReadName(var)); 00618 error_append(" is not used in "); 00619 error_append(Hrc_ModelReadName(model)); 00620 error_append(".\n"); 00621 } 00622 } 00623 } 00624 } 00625 if (isVerbose == 0 && warningStatus == 1){ 00626 error_append("Warning: Some variables are unused in model "); 00627 error_append(Hrc_ModelReadName(model)); 00628 error_append(".\n"); 00629 } 00630 st_free_table(varToTable); 00631 st_free_table(outputVarToSubckt); 00632 st_free_table(inputVarToSubckt); 00633 st_free_table(visitTable); 00634 00635 return 1; 00636 } 00637 00638 00650 static boolean 00651 _IoModelTestIsAcyclic( 00652 Hrc_Model_t *model, 00653 Hrc_Node_t *hnode, 00654 st_table *varToTable, 00655 st_table *outputVarToSubckt, 00656 st_table *visitTable) 00657 { 00658 int i; 00659 Var_Variable_t *var; 00660 st_generator *gen; 00661 char *latchName; 00662 Hrc_Latch_t *latch; 00663 00664 Hrc_NodeForEachFormalOutput(hnode,i,var){ 00665 if (_IoModelTestIsAcyclicRecursive(model,hnode,var,varToTable,outputVarToSubckt,visitTable,0) == 0){ 00666 _IoModelTestIsAcyclicError(model,var); 00667 return 0; 00668 } 00669 } 00670 Hrc_NodeForEachLatch(hnode,gen,latchName,latch){ 00671 Tbl_Table_t *resetTable; 00672 00673 resetTable = Hrc_LatchReadResetTable(latch); 00674 Tbl_TableForEachInputVar(resetTable,i,var){ 00675 int status; 00676 if ((status = _IoModelTestIsAcyclicRecursive(model,hnode, 00677 var,varToTable,outputVarToSubckt,visitTable,1)) == 0){ 00678 _IoModelTestIsAcyclicError(model,var); 00679 st_free_gen(gen); 00680 return 0; 00681 } 00682 /* found a path from a PS to a reset table */ 00683 if (status == -1){ 00684 error_append(latchName); 00685 error_append(" in model "); 00686 error_append(Hrc_ModelReadName(model)); 00687 error_append(".\n"); 00688 st_free_gen(gen); 00689 return 0; 00690 } 00691 } 00692 } 00693 Hrc_NodeForEachLatch(hnode,gen,latchName,latch){ 00694 if (_IoModelTestIsAcyclicRecursive(model,hnode, 00695 (var = Hrc_LatchReadInput(latch)),varToTable,outputVarToSubckt,visitTable,0) == 0){ 00696 _IoModelTestIsAcyclicError(model,var); 00697 st_free_gen(gen); 00698 return 0; 00699 } 00700 } 00701 return 1; 00702 } 00703 00715 static void 00716 _IoModelTestIsAcyclicError( 00717 Hrc_Model_t *model, 00718 Var_Variable_t *var) 00719 { 00720 error_append("Warning: Model "); 00721 error_append(Hrc_ModelReadName(model)); 00722 error_append(" may have a cyclic connection which involves variable "); 00723 error_append(Var_VariableReadName(var)); 00724 error_append("\n"); 00725 } 00726 00738 static int 00739 _IoModelTestIsAcyclicRecursive( 00740 Hrc_Model_t *model, 00741 Hrc_Node_t *hnode, 00742 Var_Variable_t *var, 00743 st_table *varToTable, 00744 st_table *outputVarToSubckt, 00745 st_table *visitTable, 00746 boolean isResetLogic) 00747 { 00748 int val, i; 00749 Var_Variable_t *input; 00750 Tbl_Table_t *table; 00751 Hrc_Subckt_t *subckt; 00752 00753 if (st_lookup_int(visitTable,(char *)var, &val) == 1){ 00754 return (!val); 00755 } 00756 else{ 00757 (void)st_insert(visitTable,(char *)var,(char *)1); 00758 00759 if (Var_VariableTestIsPI(var) == 0 && 00760 (isResetLogic || Var_VariableTestIsPS(var) == 0)){ 00761 if (isResetLogic && (Var_VariableTestIsPS(var) == 1)){ 00762 error_append("Warning: There is a path from latch output "); 00763 error_append(Var_VariableReadName(var)); 00764 error_append(" to reset table "); 00765 00766 /* the error message is to be continued in _IoModelTestIsAcyclic() */ 00767 return -1; 00768 } 00769 if (st_lookup(varToTable,(char *)var,&table) == 1){ 00770 Tbl_TableForEachInputVar(table,i,input){ 00771 int status; 00772 if ((status = _IoModelTestIsAcyclicRecursive(model,hnode,input, 00773 varToTable,outputVarToSubckt,visitTable,isResetLogic)) == 0){ 00774 return 0; 00775 } 00776 if (status == -1){ 00777 return -1; 00778 } 00779 } 00780 } 00781 else { 00782 array_t *actualInputs; 00783 /* the return value of the following st_lookup should be 1 */ 00784 (void)st_lookup(outputVarToSubckt,(char *)var,&subckt); 00785 actualInputs = Hrc_SubcktReadActualInputVars(subckt); 00786 assert (actualInputs != NIL(array_t)); 00787 for (i=0; i < array_n(actualInputs); i++){ 00788 int status; 00789 input = array_fetch(Var_Variable_t *,actualInputs,i); 00790 if ((status = _IoModelTestIsAcyclicRecursive(model,hnode,input, 00791 varToTable,outputVarToSubckt,visitTable,0)) == 0){ 00792 return 0; 00793 } 00794 if (status == -1){ 00795 return -1; 00796 } 00797 } 00798 } 00799 } 00800 (void)st_insert(visitTable,(char *)var,(char *)0); 00801 return 1; 00802 } 00803 } 00804 00805 00806 00807 00808 00809 00810 00811 00812 00813 00814 00815 00816 00817