VIS
|
00001 00032 #include <stdio.h> 00033 #include "rstInt.h" 00034 #include "cmd.h" 00035 #include "varInt.h" 00036 00037 static char rcsid[] UNUSED = "$Id: rstGroup.c,v 1.9 2005/05/16 06:22:35 fabio Exp $"; 00038 00039 /*---------------------------------------------------------------------------*/ 00040 /* Constant declarations */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 /* 00044 #define RST_GROUP_DEBUG 1 00045 */ 00046 00047 /*---------------------------------------------------------------------------*/ 00048 /* Structure declarations */ 00049 /*---------------------------------------------------------------------------*/ 00050 00051 /*---------------------------------------------------------------------------*/ 00052 /* Type declarations */ 00053 /*---------------------------------------------------------------------------*/ 00054 /*---------------------------------------------------------------------------*/ 00055 /* Variable declarations */ 00056 /*---------------------------------------------------------------------------*/ 00057 00058 /*---------------------------------------------------------------------------*/ 00059 /* Macro declarations */ 00060 /*---------------------------------------------------------------------------*/ 00061 00062 #define Rst_VarForEachVarInArray( \ 00063 /* array_t* */ array, \ 00064 /* int, local */ i, \ 00065 /* Var_Variable_t* */ var \ 00066 ) \ 00067 arrayForEachItem(Var_Variable_t*, array, i, var) 00068 00071 /*---------------------------------------------------------------------------*/ 00072 /* Static function prototypes */ 00073 /*---------------------------------------------------------------------------*/ 00074 00075 00079 /*---------------------------------------------------------------------------*/ 00080 /* Definition of exported functions */ 00081 /*---------------------------------------------------------------------------*/ 00082 00083 00084 00096 /* 00097 This was moved to VAR package by Yuji on 11/8 and renamed to 00098 Var_VariableResetNumFanoutTables() 00099 00100 void 00101 Var_VariableResetNumFanout( 00102 Var_Variable_t* var) 00103 { 00104 var->numFanoutTables = 0; 00105 } 00106 */ 00107 00108 00127 Tbl_Table_t* 00128 Tbl_TableDupAndSubstVars( 00129 Tbl_Table_t* Table, 00130 st_table* VartoVar) 00131 { 00132 int tblIndx, retVal; 00133 Var_Variable_t *var, *newVar; 00134 Tbl_Table_t* newTbl = Tbl_TableHardDup(Table); 00135 00136 Tbl_TableForEachInputVar(newTbl, tblIndx, var) { 00137 retVal = st_lookup(VartoVar, (char*) var, &newVar); 00138 assert(retVal); 00139 Tbl_TableSubstituteVar(newTbl, var, newVar); 00140 Var_VariableIncrementNumFanoutTables(newVar); 00141 } 00142 Tbl_TableForEachOutputVar(newTbl, tblIndx, var) { 00143 retVal = st_lookup(VartoVar, (char*) var,&newVar); 00144 assert(retVal); 00145 Tbl_TableSubstituteVar(newTbl, var, newVar); 00146 } 00147 return newTbl; 00148 } 00149 00166 array_t* 00167 Rst_VartoVarLookup( 00168 array_t* VarArray, 00169 st_table* VartoVarOne, 00170 st_table* VartoVarTwo) 00171 { 00172 int i, retVal; 00173 Var_Variable_t *var, *newVar, *tmpVar; 00174 array_t* newVarArray = array_alloc(Var_Variable_t*, array_n(VarArray)); 00175 00176 Rst_VarForEachVarInArray(VarArray, i, var) { 00177 retVal = st_lookup(VartoVarOne, (char*) var, &newVar); 00178 assert(retVal); 00179 if (VartoVarTwo) { 00180 tmpVar = newVar; 00181 retVal = st_lookup(VartoVarTwo, (char*) tmpVar, &newVar); 00182 } 00183 assert(retVal); 00184 array_insert(Var_Variable_t*, newVarArray, i, newVar); 00185 } 00186 return newVarArray; 00187 } 00188 00207 array_t* 00208 Rst_GetNamesUntilNextOption( 00209 array_t* nameArray, 00210 int argc, 00211 char **argv) 00212 { 00213 char* name; 00214 00215 while ((util_optind < argc) && (*argv[util_optind] != '-')) { 00216 name = util_strcat3(argv[util_optind], "", ""); 00217 array_insert_last(char*, nameArray, name); 00218 util_optind++; 00219 } 00220 return nameArray; 00221 } 00222 00235 array_t* 00236 Rst_LoadNameArrayFromFile( 00237 array_t* nameArray, 00238 FILE* fp) 00239 { 00240 char* name; 00241 char buffer[1024]; 00242 00243 while (fscanf(fp, "%s", buffer) != EOF) { 00244 name = util_strcat3(buffer, "", ""); 00245 array_insert_last(char*, nameArray, name); 00246 } 00247 return nameArray; 00248 } 00249 00273 Rst_Group_t* 00274 RstGroupComponents( 00275 Hrc_Model_t* CurModel, 00276 char* NewName, 00277 array_t* VarGroup, 00278 array_t* Subcircuits) 00279 { 00280 int i, j, tblIndx; 00281 long inGroup; 00282 char* latchName, *subcktName; 00283 Hrc_Latch_t* latch; 00284 Hrc_Subckt_t* subckt; 00285 Hrc_Node_t* curMaster; 00286 st_generator* sgen; 00287 Tbl_Table_t* tbl; 00288 Var_Variable_t* var = NIL(Var_Variable_t); 00289 array_t* subOutputs; 00290 Rst_Group_t* group = RstGroupAlloc(NewName); 00291 00292 curMaster = Hrc_ModelReadMasterNode(CurModel); 00293 00294 /* Make sure there is something to group */ 00295 i=0; 00296 if (VarGroup) { 00297 i += array_n(VarGroup); 00298 } 00299 if (Subcircuits) { 00300 i += array_n(Subcircuits); 00301 } 00302 if (i == 0) { 00303 return 0; 00304 } 00305 00306 /* Determine Input/Output Formal list from implied partitioning */ 00307 00308 if (VarGroup) { 00309 /* Store group variables (ie outputs of tables/latches) in hash 00310 table */ 00311 Rst_VarForEachVarInArray(VarGroup, i, var) { 00312 if ((var) && (! Var_VariableTestIsPI(var))) { 00313 st_insert(group->Vars, (char*) var, (char*) (long) 1); 00314 } else if ((var) && (Var_VariableTestIsPI(var))) { 00315 (void) fprintf(vis_stderr, 00316 "Warning: can't group a PI: %s\n", 00317 Var_VariableReadName(var)); 00318 } 00319 } 00320 } 00321 00322 if (Subcircuits) { 00323 /* Store Subckt in group Subcircuits hashtable. 00324 Store output vars of all group Subckts in var hash table */ 00325 for (i = 0; i < array_n(Subcircuits); i++) { 00326 subckt = array_fetch(Hrc_Subckt_t*, Subcircuits, i); 00327 st_insert(group->Subcircuits, (char*) subckt, (char*) (long) 1); 00328 Rst_VarForEachVarInArray(Hrc_SubcktReadActualOutputVars(subckt), 00329 j, var) { 00330 if (! st_lookup(group->Vars, (char*) var, &inGroup)) { 00331 st_insert(group->Vars, (char*) var, (char*) (long) 1); 00332 } 00333 } 00334 } 00335 } 00336 00337 /* Table and Latch outputs which are group vars become members of the group 00338 */ 00339 00340 Hrc_NodeForEachLatch(curMaster, sgen, latchName, latch) { 00341 if (st_lookup(group->Vars, (char*) Hrc_LatchReadOutput(latch), &inGroup)) { 00342 st_insert(group->Latches, (char*) latch, (char*) (long) 1); 00343 } 00344 } 00345 00346 Hrc_NodeForEachNameTable(curMaster, tblIndx, tbl) { 00347 Tbl_TableForEachOutputVar(tbl, j, var) { 00348 inGroup = 0; 00349 if (st_lookup(group->Vars, (char*) var, &inGroup)) { 00350 st_insert(group->Tables, (char*) tbl, (char*) (long) 1); 00351 break; 00352 } 00353 } 00354 /* FIXME: Table Splitting here */ 00355 00356 if ((inGroup) && (Tbl_TableReadNumOutputs(tbl) > 1)) { 00357 (void) fprintf(vis_stderr, 00358 "WARNING: multi-output table %s moved to group %s\n", 00359 Var_VariableReadName(var), group->name); 00360 } 00361 } 00362 /* If outputs of a subckt are in a group, the subckt moves 00363 into the group */ 00364 00365 Hrc_ModelForEachSubckt(CurModel, sgen, subcktName, subckt) { 00366 Var_Variable_t* outVar = NIL(Var_Variable_t); /* initialize to pacify */ 00367 if (! st_lookup(group->Subcircuits, (char*) subckt, &inGroup)) { 00368 subOutputs = Hrc_SubcktReadActualOutputVars(subckt); 00369 Rst_VarForEachVarInArray(subOutputs, i, outVar) { 00370 if (st_lookup(group->Vars, (char*) outVar, &inGroup)) { 00371 break; 00372 } 00373 } 00374 if (i < array_n(subOutputs)) { 00375 Rst_VarForEachVarInArray(subOutputs, j, var) { 00376 if (! st_lookup(group->Vars, (char*) var, &inGroup)) { 00377 st_insert(group->Vars, (char*) var, (char*) (long) 1); 00378 } 00379 } 00380 st_insert(group->Subcircuits, (char*) subckt, (char*) (long) 1); 00381 (void) fprintf(vis_stderr, 00382 "Warning: instance %s becomes member of group %s", 00383 subcktName, group->name); 00384 (void) fprintf(vis_stderr, " because of output variable %s\n", 00385 Var_VariableReadName(outVar)); 00386 } 00387 } 00388 } 00389 00390 /* Group Outputs: Scan parent outputs for group vars. Scan non-group 00391 component (Subcircuits/Latches/Tables) inputs for group vars */ 00392 00393 Hrc_NodeForEachFormalOutput(curMaster, i, var) { 00394 if ((st_lookup(group->Vars, (char*) var, &inGroup)) && 00395 (! st_lookup(group->Outputs, (char*) var, &inGroup))) { 00396 st_insert(group->Outputs, (char*) var, (char*) (long) 1); 00397 } 00398 } 00399 00400 Hrc_ModelForEachSubckt(CurModel, sgen, subcktName, subckt) { 00401 if (! st_lookup(group->Subcircuits, (char*) subckt, &inGroup)) { 00402 Rst_VarForEachVarInArray(Hrc_SubcktReadActualInputVars(subckt), i, var) { 00403 if ((st_lookup(group->Vars, (char*) var, &inGroup)) && 00404 (! st_lookup(group->Outputs, (char*) var, &inGroup))) { 00405 st_insert(group->Outputs, (char*) var, (char*) (long) 1); 00406 } 00407 } 00408 } 00409 } 00410 Hrc_NodeForEachLatch(curMaster, sgen, latchName, latch) { 00411 if (! st_lookup(group->Latches, (char*) latch, &inGroup)) { 00412 var = Hrc_LatchReadInput(latch); 00413 if ((st_lookup(group->Vars, (char*) var, &inGroup)) && 00414 (! st_lookup(group->Outputs, (char*) var, &inGroup))) { 00415 st_insert(group->Outputs, (char*) var, (char*) (long) 1); 00416 } 00417 } 00418 } 00419 Hrc_NodeForEachNameTable(curMaster, i, tbl) { 00420 if (! st_lookup(group->Tables, (char*) tbl, &inGroup)) { 00421 Tbl_TableForEachInputVar(tbl, j, var) { 00422 if ((st_lookup(group->Vars, (char*) var, &inGroup)) && 00423 (! st_lookup(group->Outputs, (char*) var, &inGroup))) { 00424 st_insert(group->Outputs, (char*) var, (char*) (long) 1); 00425 } 00426 } 00427 } 00428 } 00429 00430 /* Group Inputs: Scan group subcomponent inputs for non-group vars */ 00431 00432 /* Formal inputs are never vars of a group. Thus, they are always 00433 non-group vars when are inputs to group subcomponents, and are 00434 caught by the code below*/ 00435 00436 Hrc_ModelForEachSubckt(CurModel, sgen, subcktName, subckt) { 00437 if (st_lookup(group->Subcircuits, (char*) subckt, &inGroup)) { 00438 Rst_VarForEachVarInArray(Hrc_SubcktReadActualInputVars(subckt), i, var) { 00439 if ((! st_lookup(group->Vars, (char*) var, &inGroup)) && 00440 (! st_lookup(group->Inputs, (char*) var, &inGroup))) { 00441 st_insert(group->Inputs, (char*) var, (char*) (long) 1); 00442 } 00443 } 00444 } 00445 } 00446 Hrc_NodeForEachLatch(curMaster, sgen, latchName, latch) { 00447 if (st_lookup(group->Latches, (char*) latch, &inGroup)) { 00448 var = Hrc_LatchReadInput(latch); 00449 if ((! st_lookup(group->Vars, (char*) var, &inGroup)) && 00450 (! st_lookup(group->Inputs, (char*) var, &inGroup))) { 00451 st_insert(group->Inputs, (char*) var, (char*) (long) 1); 00452 } 00453 /* Reset table here */ 00454 tbl = Hrc_LatchReadResetTable(latch); 00455 Tbl_TableForEachInputVar(tbl, j, var) { 00456 if (! st_lookup(group->Vars, (char*) var, &inGroup)) 00457 st_insert(group->Vars, (char*) var, (char*) (long) 1); 00458 } 00459 } 00460 } 00461 Hrc_NodeForEachNameTable(curMaster, tblIndx, tbl) { 00462 if (st_lookup(group->Tables, (char*) tbl, &inGroup)) { 00463 Tbl_TableForEachInputVar(tbl, j, var) { 00464 if ((! st_lookup(group->Vars, (char*) var, &inGroup)) && 00465 (! st_lookup(group->Inputs, (char*) var, &inGroup))) { 00466 st_insert(group->Inputs, (char*) var, (char*) (long) 1); 00467 } 00468 } 00469 } 00470 } 00471 00472 return group; 00473 } 00474 00491 Hrc_Model_t* 00492 Rst_GroupRestructureModel( 00493 Hrc_Manager_t* Hmgr, 00494 Hrc_Model_t* ParentModel, 00495 array_t* GroupArray) 00496 { 00497 int i, j; 00498 char *newModelName; 00499 st_generator *sgen; 00500 Var_Variable_t *var, *newVar; 00501 Hrc_Model_t *newModel, *newParentModel; 00502 Hrc_Node_t *newMaster; 00503 Rst_Group_t *group, *parentGroup; 00504 st_table *varForwPtr; 00505 array_t *newModelArray, *newMasterArray, *newNodeArray; 00506 00507 for (i = 0; i < array_n(GroupArray); i++) { 00508 group = array_fetch(Rst_Group_t*, GroupArray, i); 00509 #ifdef RST_GROUP_DEBUG 00510 RstGroupPrint(group); 00511 #endif 00512 } 00513 /* Check group components for disjointness */ 00514 00515 if (RstGroupDisjointCheck(GroupArray)) 00516 return 0; 00517 00518 /* Construct a level of hierarchy for each group */ 00519 00520 newModelArray = array_alloc(Hrc_Model_t*, array_n(GroupArray)); 00521 newMasterArray = array_alloc(Hrc_Node_t*, array_n(GroupArray)); 00522 newNodeArray = array_alloc(Hrc_Node_t*, array_n(GroupArray)); 00523 00524 for (i = 0; i < array_n(GroupArray); i++) { 00525 group = array_fetch(Rst_Group_t*, GroupArray, i); 00526 newModel = RstGroupBuildModel(Hmgr, group); 00527 if (! newModel) { 00528 return 0; 00529 } 00530 newMaster = Hrc_ModelReadMasterNode(newModel); 00531 array_insert(Hrc_Model_t*, newModelArray, i, newModel); 00532 array_insert(Hrc_Node_t*, newMasterArray, i, newMaster); 00533 } 00534 00535 /* Build the new parent hierarchy */ 00536 00537 newModelName = RstGroupNewParentName(Hrc_ModelReadName(ParentModel)); 00538 parentGroup = RstCreateParentGroup(Hmgr, ParentModel, newModelName, 00539 GroupArray); 00540 FREE(newModelName); 00541 if (! parentGroup) { 00542 return 0; 00543 } 00544 #ifdef RST_GROUP_DEBUG 00545 RstGroupPrint(parentGroup); 00546 #endif 00547 newParentModel = RstGroupBuildModel(Hmgr, parentGroup); 00548 00549 /* Computing actuals: Group IO vars USED to be in the old parent. 00550 1) lookup what the new IO vars used to be in the old parent 00551 2) In the old parent, find the correspond new parent vars 00552 */ 00553 00554 /* Build Table: Parent to New Parent Vars, by reversing back pointers */ 00555 00556 varForwPtr = st_init_table(st_ptrcmp, st_ptrhash); 00557 st_foreach_item(parentGroup->VarBackPtr, sgen, &newVar, &var) { 00558 st_insert(varForwPtr, (char*) var, (char*) newVar); 00559 } 00560 00561 /* Free parent group now */ 00562 RstGroupFree(parentGroup); parentGroup = 0; 00563 00564 /* Instantiate groups as subckts */ 00565 00566 for (i = 0; i < array_n(GroupArray); i++) { 00567 array_t* actualInputArray, *actualOutputArray; 00568 00569 group = array_fetch(Rst_Group_t*, GroupArray, i); 00570 newModel = array_fetch(Hrc_Model_t*, newModelArray, i); 00571 newMaster = Hrc_ModelReadMasterNode(newModel); 00572 00573 actualInputArray = 00574 Rst_VartoVarLookup(Hrc_NodeReadFormalInputs(newMaster), 00575 group->VarBackPtr, varForwPtr); 00576 actualOutputArray = 00577 Rst_VartoVarLookup(Hrc_NodeReadFormalOutputs(newMaster), 00578 group->VarBackPtr, varForwPtr); 00579 00580 Hrc_ModelAddSubckt(newParentModel, newModel, group->name, 00581 actualInputArray, actualOutputArray); 00582 Rst_VarForEachVarInArray(actualInputArray, j, var) { 00583 Var_VariableSetSI(var); 00584 } 00585 Rst_VarForEachVarInArray(actualOutputArray, j, var) { 00586 Var_VariableSetSO(var); 00587 } 00588 } 00589 array_free(newModelArray); 00590 array_free(newMasterArray); 00591 array_free(newNodeArray); 00592 00593 st_free_table(varForwPtr); 00594 return newParentModel; 00595 } 00596 00613 Hrc_Node_t* 00614 Rst_GroupRestructureNode( 00615 Hrc_Manager_t* Hmgr, 00616 Hrc_Node_t* CurNode, 00617 array_t* GroupArray) 00618 { 00619 int retVal; 00620 #ifdef RST_GROUP_DEBUG 00621 st_generator* sgen; 00622 char* childName; 00623 Hrc_Node_t *child; 00624 #endif 00625 Hrc_Model_t *newParentModel; 00626 Hrc_Node_t *newNode = 0; 00627 Hrc_Model_t* CurModel= 00628 Hrc_ManagerFindModelByName(Hmgr, Hrc_NodeReadModelName(CurNode)); 00629 00630 newParentModel = Rst_GroupRestructureModel(Hmgr, CurModel, GroupArray); 00631 if (newParentModel) { 00632 00633 newNode = Hrc_ModelCreateHierarchy(Hmgr, newParentModel, 00634 Hrc_NodeReadInstanceName(CurNode)); 00635 00636 #ifdef RST_GROUP_DEBUG 00637 (void) fprintf(vis_stderr, "Checking New Node\n"); 00638 assert(Hrc_NodeCheckVariableConsistency(newNode)); 00639 (void) fprintf(vis_stderr, "Checking Subcircuits\n"); 00640 Hrc_NodeForEachChild(newNode, sgen, childName, child) { 00641 assert(Hrc_NodeCheckVariableConsistency(child)); 00642 } 00643 #endif 00644 00645 retVal = Hrc_TreeReplace(CurNode, newNode); 00646 assert(retVal); 00647 Hrc_ManagerSetCurrentNode(Hmgr, newNode); 00648 } 00649 return newNode; 00650 } 00651 00664 Hrc_Model_t* 00665 Rst_GroupGroupCombLogic( 00666 Hrc_Manager_t* Hmgr, 00667 Hrc_Model_t* CurModel) 00668 { 00669 long inGroup; 00670 int tblIndx, varIndx; 00671 Var_Variable_t *var; 00672 Tbl_Table_t* tbl; 00673 array_t* varArray = array_alloc(Var_Variable_t*, 0); 00674 Rst_Group_t *group; 00675 st_table *tableOutputs = st_init_table(st_ptrcmp, st_ptrhash); 00676 Hrc_Node_t *curMaster; 00677 Hrc_Model_t* newModel; 00678 00679 /* Perhaps this is better done with the NameTables so that we drop 00680 subckts from inclusion */ 00681 00682 curMaster = Hrc_ModelReadMasterNode(CurModel); 00683 00684 Hrc_NodeForEachNameTable(curMaster, tblIndx, tbl) { 00685 Tbl_TableForEachOutputVar(tbl, varIndx, var) { 00686 if (! st_lookup(tableOutputs, (char*) var, &inGroup)) { 00687 st_insert(tableOutputs, (char*) var, (char*) (long) 1); 00688 array_insert_last(Var_Variable_t*, varArray, var); 00689 } 00690 } 00691 } 00692 st_free_table(tableOutputs); 00693 group = RstGroupComponents(CurModel, 00694 util_strcat3(Hrc_ModelReadName(CurModel), 00695 "_comb", ""), 00696 varArray, NULL); 00697 array_free(varArray); 00698 00699 if (group) { 00700 array_t *groupArray = array_alloc(Rst_Group_t*, 1); 00701 array_insert_last(Rst_Group_t*, groupArray, group); 00702 newModel = Rst_GroupRestructureModel(Hmgr, CurModel, groupArray); 00703 array_free(groupArray); 00704 return newModel; 00705 } 00706 return 0; 00707 } 00708 00720 Hrc_Model_t* 00721 Rst_GroupGroupLatches( 00722 Hrc_Manager_t* Hmgr, 00723 Hrc_Model_t* CurModel) 00724 { 00725 char *latchName; 00726 st_generator *sgen; 00727 Hrc_Latch_t *latch; 00728 array_t* varArray = array_alloc(Var_Variable_t*, 0); 00729 Rst_Group_t *group; 00730 Hrc_Node_t* curMaster = Hrc_ModelReadMasterNode(CurModel); 00731 Hrc_Model_t* newModel; 00732 00733 Hrc_NodeForEachLatch(curMaster, sgen, latchName, latch) { 00734 array_insert_last(Var_Variable_t*, varArray, Hrc_LatchReadOutput(latch)); 00735 } 00736 00737 group = RstGroupComponents(CurModel, 00738 util_strcat3(Hrc_ModelReadName(CurModel), 00739 "_latch", ""), 00740 varArray, NULL); 00741 array_free(varArray); 00742 00743 if (group) { 00744 array_t *groupArray = array_alloc(Rst_Group_t*, 1); 00745 array_insert_last(Rst_Group_t*, groupArray, group); 00746 newModel = Rst_GroupRestructureModel(Hmgr, CurModel, groupArray); 00747 array_free(groupArray); 00748 return newModel; 00749 } 00750 return 0; 00751 } 00752 00827 int 00828 Rst_CommandGroupComponents( 00829 Hrc_Manager_t** Hmgr, 00830 int argc, 00831 char ** argv) 00832 { 00833 enum { SUBCKT_GROUP, VAR_GROUP } readType = SUBCKT_GROUP; 00834 int c, i, retVal, tblIndx; 00835 st_generator *sgen; 00836 Rst_Group_t* group; 00837 Var_Variable_t* var; 00838 Hrc_Subckt_t* child; 00839 char *fileName, *varName, *childName, *latchName; 00840 char* groupName = 0; 00841 array_t *vars = 0, *children = 0; 00842 Hrc_Latch_t* latch; 00843 Tbl_Table_t* tbl; 00844 array_t* nameArray = 0; 00845 array_t* groupArray = array_alloc(Rst_Group_t*, 1); 00846 Hrc_Node_t* curNode = Hrc_ManagerReadCurrentNode(*Hmgr); 00847 Hrc_Node_t* curMaster; 00848 FILE* fp; 00849 Hrc_Model_t* CurModel; 00850 00851 if (! curNode) { 00852 /* No node has been read in. The only sane thing we 00853 support is the -h option */ 00854 array_free(groupArray); groupArray = 0; 00855 util_getopt_reset(); 00856 if ((c = util_getopt(argc,argv,"h")) != EOF) { 00857 goto usage; 00858 } 00859 (void) fprintf(vis_stderr, "ERROR: no current Node\n"); 00860 return 1; 00861 } 00862 00863 CurModel= 00864 Hrc_ManagerFindModelByName(Hrc_NodeReadManager(curNode), 00865 Hrc_NodeReadModelName(curNode)); 00866 curMaster = Hrc_ModelReadMasterNode(CurModel); 00867 00868 /* This command processing loop is conceptually simple, but almost 00869 'goto' like and needs explanation. The command line is a sequence 00870 of groups between which are specified component names to group. 00871 00872 A group is started with a Naming operation '-n'. We get a list of 00873 component names to group either from the command line or from a 00874 file. Names can be anywhere on the command line (except between 00875 -n/-f and their argument). The names are interpreted as Variables 00876 or Children depending on the last -v or -c flag. Children is the 00877 default setting on entry. 00878 00879 After every option, we can read more names off command line, so we 00880 drop into this mode after completing a -n <name> or -f <file> 00881 operation. This means we always drop into the outer 'default'. 00882 00883 The goal is to collect a set of Variable and Child names for each 00884 Group Name specified. */ 00885 00886 util_getopt_reset(); 00887 while ((c = util_getopt(argc, argv, "n:f:cvtlh")) != EOF) { 00888 switch(c) { 00889 case 'n': /* expects a Name arg */ 00890 case 'f': /* expects a filename arg */ 00891 switch(c) { 00892 case 'n': /* Name a new group */ 00893 if (groupName != NULL) { 00894 group = RstGroupComponents(CurModel, groupName, 00895 vars, children); 00896 array_free(vars); vars = 0; 00897 array_free(children); children = 0; 00898 FREE(groupName); 00899 if (group) { 00900 array_insert_last(Rst_Group_t*, groupArray, group); 00901 } else { 00902 (void) fprintf(vis_stderr, 00903 "Warning: Incomplete group %s -- ignored\n", 00904 groupName); 00905 RstGroupFree(group); group = 0; 00906 } 00907 } 00908 vars = array_alloc(Var_Variable_t*, 0); 00909 children = array_alloc(Hrc_Subckt_t*, 0); 00910 groupName = util_strcat3(argv[util_optind -1], "",""); 00911 break; 00912 case 'f': /* Read component names from file */ 00913 fileName = argv[util_optind - 1]; 00914 fp = Cmd_FileOpen(util_optarg, "r", &fileName, 1); 00915 if (fp == NIL(FILE)) { 00916 (void) fprintf(vis_stderr, 00917 "Could not open file %s\n", fileName); 00918 return 1; 00919 } 00920 nameArray = array_alloc(char*, 0); 00921 Rst_LoadNameArrayFromFile(nameArray, fp); 00922 fclose(fp); 00923 break; 00924 } 00925 /* WE ALWAYS DROP IN HERE ON EVERY FLAG */ 00926 default: 00927 if (! groupName && (c != 'h')) { 00928 (void) fprintf(vis_stderr, "ERROR: Group not defined yet\n"); 00929 goto usage; 00930 } 00931 if (! nameArray) nameArray = array_alloc(char*, 0); 00932 switch(c) { 00933 case 'n': 00934 case 'f': 00935 break; 00936 case 'c': readType = SUBCKT_GROUP; break; 00937 case 'v': readType = VAR_GROUP; break; 00938 case 'l': 00939 /* Put latch ouput vars into group*/ 00940 Hrc_NodeForEachLatch(curMaster, sgen, latchName, latch) { 00941 var = Hrc_LatchReadOutput(latch); 00942 array_insert_last(Var_Variable_t*, vars, var); 00943 } 00944 break; 00945 case 't': 00946 /* Put table ouput vars into group*/ 00947 Hrc_NodeForEachNameTable(curMaster, tblIndx, tbl) { 00948 Tbl_TableForEachOutputVar(tbl, i, var) { 00949 array_insert_last(Var_Variable_t*, vars, var); 00950 } 00951 } 00952 break; 00953 default: goto usage; 00954 } 00955 /* Grab any more names off the command line, appending if 00956 possible to nameArray */ 00957 00958 Rst_GetNamesUntilNextOption(nameArray, argc, argv); 00959 00960 /* We store names read as either variable names or child names */ 00961 00962 switch(readType) { 00963 case VAR_GROUP: 00964 for (i=0; i < array_n(nameArray); i++) { 00965 varName = array_fetch(char*, nameArray, i); 00966 var = Hrc_NodeFindVariableByName(curMaster, varName); 00967 if (var) { 00968 array_insert_last(Var_Variable_t*, vars, var); 00969 } else { 00970 (void) fprintf(vis_stderr, "Could not find variable %s\n", 00971 varName); 00972 } 00973 } 00974 break; 00975 case SUBCKT_GROUP: 00976 for (i=0; i < array_n(nameArray); i++) { 00977 childName = array_fetch(char*, nameArray, i); 00978 retVal = st_lookup(Hrc_ModelReadSubcktTable(CurModel), 00979 childName, &child); 00980 if (retVal) { 00981 array_insert_last(Hrc_Subckt_t*, children, child); 00982 } else { 00983 (void) fprintf(vis_stderr, "Could not find instance %s\n", 00984 childName); 00985 } 00986 } 00987 break; 00988 default: /* Unreached */ 00989 break; 00990 } 00991 break; 00992 } 00993 for (i=0; i < array_n(nameArray); i++) { 00994 varName = array_fetch(char*, nameArray, i); 00995 FREE(varName); 00996 } 00997 array_free(nameArray); nameArray = 0; 00998 } 00999 if (groupName) { 01000 group = RstGroupComponents(CurModel, groupName, vars, children); 01001 if (group) 01002 array_insert_last(Rst_Group_t*, groupArray, group); 01003 else 01004 (void) fprintf(vis_stderr, "Incomplete group %s\n", groupName); 01005 array_free(vars); vars = 0; 01006 array_free(children); children = 0; 01007 FREE(groupName); 01008 } 01009 01010 if (array_n(groupArray) > 0) { 01011 Rst_GroupRestructureNode(*Hmgr, curNode, groupArray); 01012 for (i=0; i < array_n(groupArray); i++) { 01013 group = array_fetch(Rst_Group_t*, groupArray, i); 01014 RstGroupFree(group); 01015 } 01016 array_free(groupArray); groupArray = 0; 01017 } else { 01018 (void) fprintf(vis_stderr, "ERROR: no groups defined\n"); 01019 array_free(groupArray); 01020 return 1; 01021 } 01022 return 0; /* normal exit */ 01023 01024 usage: 01025 if (vars) array_free(vars); vars = 0; 01026 if (children) array_free(children); children = 0; 01027 FREE(groupName); groupName = 0; 01028 array_free(nameArray); nameArray = 0; 01029 array_free(groupArray); 01030 (void) fprintf(vis_stderr, "usage: decompose_child -n <groupname>"); 01031 (void) fprintf(vis_stderr, " [-f <filename>] [-c] [-v] [<names>] [-t] [-l] [-h] \n"); 01032 (void) fprintf(vis_stderr, " -n\t\tName of new child group \n"); 01033 (void) fprintf(vis_stderr, " -f\t\tLoad names from file \n"); 01034 (void) fprintf(vis_stderr, " -c\t\tGroup by children toggle (default)\n"); 01035 (void) fprintf(vis_stderr, " -v\t\tGroup by variable toggle \n"); 01036 (void) fprintf(vis_stderr, " -l\t\tGroup latches\n"); 01037 (void) fprintf(vis_stderr, " -t\t\tGroup combinational logic tables \n"); 01038 (void) fprintf(vis_stderr, " -h\t\thelp \n"); 01039 return 1; /* error exit */ 01040 01041 } 01042 01043 /*---------------------------------------------------------------------------*/ 01044 /* Definition of internal functions */ 01045 /*---------------------------------------------------------------------------*/ 01046 01047 01048 /*---------------------------------------------------------------------------*/ 01049 /* Definition of static functions */ 01050 /*---------------------------------------------------------------------------*/ 01051 01066 Rst_Group_t* 01067 RstGroupAlloc(char* Name) 01068 { 01069 Rst_Group_t* group = ALLOC(Rst_Group_t, 1); 01070 01071 group->Vars = st_init_table(st_ptrcmp, st_ptrhash); 01072 group->Latches = st_init_table(st_ptrcmp, st_ptrhash); 01073 group->Tables = st_init_table(st_ptrcmp, st_ptrhash); 01074 group->Subcircuits = st_init_table(st_ptrcmp, st_ptrhash); 01075 group->Inputs = st_init_table(st_ptrcmp, st_ptrhash); 01076 group->Outputs = st_init_table(st_ptrcmp, st_ptrhash); 01077 group->VarBackPtr = st_init_table(st_ptrcmp, st_ptrhash); 01078 group->name = ALLOC(char, strlen(Name) + 1); 01079 strcpy(group->name, Name); 01080 return group; 01081 } 01082 01095 void 01096 RstGroupFree(Rst_Group_t* Group) 01097 { 01098 st_free_table(Group->Vars); 01099 st_free_table(Group->Latches); 01100 st_free_table(Group->Tables); 01101 st_free_table(Group->Subcircuits); 01102 st_free_table(Group->Inputs); 01103 st_free_table(Group->Outputs); 01104 st_free_table(Group->VarBackPtr); 01105 FREE(Group->name); 01106 FREE(Group); /* Watch for dangling references */ 01107 } 01108 01120 char* 01121 RstGroupNewParentName( 01122 char* Name) 01123 { 01124 char* newName = util_strcat3(Name, "_N", ""); 01125 return newName; 01126 } 01127 01139 void 01140 RstGroupPrint( 01141 Rst_Group_t* group) 01142 { 01143 st_generator* sgen; 01144 Var_Variable_t* var; 01145 Hrc_Subckt_t* subckt; 01146 Hrc_Latch_t* latch; 01147 01148 printf("GROUP: %s\n\tInputs:\t", group->name); 01149 st_foreach_item(group->Inputs, sgen, &var, NIL(char *)) { 01150 printf("%s ", Var_VariableReadName(var)); 01151 } 01152 printf("\n\tOutputs:\t"); 01153 st_foreach_item(group->Outputs, sgen, &var, NIL(char *)) { 01154 printf("%s ", Var_VariableReadName(var)); 01155 } 01156 printf("\n\tSubcircuits:\t"); 01157 st_foreach_item(group->Subcircuits, sgen, &subckt, NIL(char *)) { 01158 printf("%s ", Hrc_SubcktReadInstanceName(subckt)); 01159 } 01160 printf("\n\tLatches:\t"); 01161 st_foreach_item(group->Latches, sgen, &latch, NIL(char *)) { 01162 printf("%s ", Var_VariableReadName(Hrc_LatchReadOutput(latch))); 01163 } 01164 printf("\n\tVars:\t"); 01165 st_foreach_item(group->Vars, sgen, &var, NIL(char *)) { 01166 printf("%s ", Var_VariableReadName(var)); 01167 } 01168 printf("\n"); 01169 } 01170 01183 int 01184 RstGroupDisjointCheck( 01185 array_t* GroupArray) 01186 { 01187 int i, j, retVal; 01188 st_generator *sgen; 01189 Hrc_Subckt_t* subckt; 01190 Rst_Group_t* group1, *group2; 01191 Hrc_Latch_t* latch; 01192 Tbl_Table_t* tbl; 01193 Var_Variable_t* var; 01194 01195 for (i = 0; i < array_n(GroupArray); i++) { 01196 group1 = array_fetch(Rst_Group_t*, GroupArray, i); 01197 for (j = i + 1; j < array_n(GroupArray); j++) { 01198 group2 = array_fetch(Rst_Group_t*, GroupArray, j); 01199 01200 st_foreach_item(group1->Subcircuits, sgen, &subckt, NULL) { 01201 retVal = st_lookup(group2->Subcircuits, (char*) subckt, NIL(char *)); 01202 if (retVal) { 01203 (void) fprintf(vis_stderr, 01204 "ERROR: component %s assigned to groups %s and %s\n", 01205 Hrc_SubcktReadInstanceName(subckt), 01206 group1->name, group2->name); 01207 return 1; 01208 } 01209 } 01210 st_foreach_item(group1->Vars, sgen, &var, NULL) { 01211 retVal = st_lookup(group2->Vars, (char*) var, NIL(char *)); 01212 if (retVal) { 01213 (void) fprintf(vis_stderr, 01214 "ERROR: var %s assigned to groups %s and %s\n", 01215 Var_VariableReadName(var), 01216 group1->name, group2->name); 01217 return 1; 01218 } 01219 } 01220 st_foreach_item(group1->Tables, sgen, &tbl, NULL) { 01221 retVal = st_lookup(group2->Tables, (char*) tbl, NIL(char *)); 01222 if (retVal) { 01223 (void) fprintf(vis_stderr, 01224 "ERROR: table assigned to groups %s and %s\n", 01225 group1->name, group2->name); 01226 return 1; 01227 } 01228 } 01229 st_foreach_item(group1->Latches, sgen, &latch, NULL) { 01230 retVal = st_lookup(group2->Latches, (char*) latch, NIL(char *)); 01231 if (retVal) { 01232 (void) fprintf(vis_stderr, 01233 "ERROR: latch %s assigned to groups %s and %s\n", 01234 Var_VariableReadName(Hrc_LatchReadOutput(latch)), 01235 group1->name, group2->name); 01236 return 1; 01237 } 01238 } 01239 } 01240 } 01241 return 0; 01242 } 01243 01259 Rst_Group_t* 01260 RstCreateParentGroup( 01261 Hrc_Manager_t* Hmgr, 01262 Hrc_Model_t* ParentModel, 01263 char* NewModelName, 01264 array_t* GroupArray) 01265 { 01266 int i, j, tblIndx, varIndx; 01267 long inGroup; 01268 char *latchName, *subcktName, *varName; 01269 st_generator* sgen; 01270 Var_Variable_t* var; 01271 Tbl_Table_t* tbl; 01272 Hrc_Latch_t* latch; 01273 Hrc_Subckt_t *subckt; 01274 Hrc_Node_t *parentMaster; 01275 Rst_Group_t *group, *parentGroup; 01276 array_t* subOutputs; 01277 01278 /* Build a parent group */ 01279 01280 parentGroup = RstGroupAlloc(NewModelName); 01281 parentMaster = Hrc_ModelReadMasterNode(ParentModel); 01282 01283 /* IO of latches of parent group are parent group vars */ 01284 01285 Hrc_NodeForEachLatch(parentMaster, sgen, latchName, latch) { 01286 for (i = 0; i < array_n(GroupArray); i++) { 01287 group = array_fetch(Rst_Group_t*, GroupArray, i); 01288 if (st_lookup(group->Latches, (char*) latch, &inGroup)) { 01289 break; 01290 } 01291 } 01292 if (i >= array_n(GroupArray)) { 01293 st_insert(parentGroup->Latches, (char*) latch, (char*) (long) 1); 01294 var = Hrc_LatchReadInput(latch); 01295 if (! st_lookup(parentGroup->Vars, (char*) var, &inGroup)) { 01296 st_insert(parentGroup->Vars, (char*) var, (char*) (long) 1); 01297 } 01298 var = Hrc_LatchReadOutput(latch); 01299 if (! st_lookup(parentGroup->Vars, (char*) var, &inGroup)) { 01300 st_insert(parentGroup->Vars, (char*) var, (char*) (long) 1); 01301 } 01302 } 01303 } 01304 01305 /* IO of parent group tables (that stay in parent) are parent group vars */ 01306 01307 Hrc_NodeForEachNameTable(parentMaster, tblIndx, tbl) { 01308 for (i = 0; i < array_n(GroupArray); i++) { 01309 group = array_fetch(Rst_Group_t*, GroupArray, i); 01310 if (st_lookup(group->Tables, (char*) tbl, &inGroup)) { 01311 break; 01312 } 01313 } 01314 if (i >= array_n(GroupArray)) { 01315 /* Table stays in parent */ 01316 st_insert(parentGroup->Tables, (char*) tbl, (char*) (long) 1); 01317 Tbl_TableForEachInputVar(tbl, varIndx, var) { 01318 if (! st_lookup(parentGroup->Vars, (char*) var, &inGroup)) { 01319 st_insert(parentGroup->Vars, (char*) var, (char*) (long) 1); 01320 } 01321 } 01322 Tbl_TableForEachOutputVar(tbl, varIndx, var) { 01323 if (! st_lookup(parentGroup->Vars, (char*) var, &inGroup)) { 01324 st_insert(parentGroup->Vars, (char*) var, (char*) (long) 1); 01325 } 01326 } 01327 } 01328 } 01329 01330 /* IO of groups are group Vars of the parent. Note that inputs are 01331 never group vars of a group EXCEPT in the case of the parent group */ 01332 01333 Hrc_NodeForEachVariable(parentMaster, sgen, varName, var) { 01334 if (! st_lookup(parentGroup->Vars, (char*) var, &inGroup)) { 01335 for (i = 0; i < array_n(GroupArray); i++) { 01336 group = array_fetch(Rst_Group_t*, GroupArray, i); 01337 if ((st_lookup(group->Inputs, (char*) var, &inGroup)) || 01338 (st_lookup(group->Outputs, (char*) var, &inGroup))) { 01339 break; 01340 } 01341 } 01342 if (i < array_n(GroupArray)) { 01343 st_insert(parentGroup->Vars, (char*) var, (char*) (long) 1); 01344 } 01345 } 01346 } 01347 01348 /* All formal IO of old parent remains part of the parent group */ 01349 01350 Hrc_NodeForEachFormalInput(parentMaster, i, var) 01351 st_insert(parentGroup->Inputs, (char*) var, (char*) (long) 1); 01352 01353 Hrc_NodeForEachFormalOutput(parentMaster, i, var) 01354 st_insert(parentGroup->Outputs, (char*) var, (char*) (long) 1); 01355 01356 /* Outputs of subckts of parent group are parent group vars 01357 We do this last to catch this possible dangling input scenario*/ 01358 01359 Hrc_ModelForEachSubckt(ParentModel, sgen, subcktName, subckt) { 01360 for (i = 0; i < array_n(GroupArray); i++) { 01361 group = array_fetch(Rst_Group_t*, GroupArray, i); 01362 if (st_lookup(group->Subcircuits, (char*) subckt, &inGroup)) { 01363 break; 01364 } 01365 } 01366 if (i >= array_n(GroupArray)) { 01367 st_insert(parentGroup->Subcircuits, (char*) subckt, (char*) (long) 1); 01368 subOutputs = Hrc_SubcktReadActualOutputVars(subckt); 01369 Rst_VarForEachVarInArray(subOutputs, j, var) { 01370 if (! st_lookup(parentGroup->Vars, (char*) var, &inGroup)) { 01371 st_insert(parentGroup->Vars, (char*) var, (char*) (long) 1); 01372 } 01373 } 01374 /* FIXME: Possible bug: inputs are caught because they are 01375 outputs of other components. But a dangling input (ie, one 01376 with no connection to anything) might get dropped. But adding 01377 an input var might cause it's driving component to be 01378 incorporated! We opt for a warning here. */ 01379 /* FIXME: Hack-using same array */ 01380 subOutputs = Hrc_SubcktReadActualInputVars(subckt); 01381 Rst_VarForEachVarInArray(subOutputs, j, var) { 01382 if ((! st_lookup(parentGroup->Vars, (char*) var, &inGroup)) && 01383 (! st_lookup(parentGroup->Inputs, (char*) var, &inGroup))) { 01384 (void) fprintf(vis_stderr, 01385 "Warning: subcircuit %s has input variable %s ", 01386 subcktName, Var_VariableReadName(var)); 01387 (void) fprintf(vis_stderr, "that has no driver in parent %s\n", 01388 parentGroup->name); 01389 } 01390 } 01391 } 01392 } 01393 return parentGroup; 01394 } 01395 01407 void 01408 RstModelPrint( 01409 Hrc_Model_t* newModel) 01410 { 01411 Hrc_Node_t* newMaster; 01412 int i; 01413 st_generator* sgen; 01414 char* varName; 01415 Var_Variable_t* var; 01416 01417 /* Print out new model */ 01418 printf("Model %s\n", Hrc_ModelReadName(newModel)); 01419 newMaster = Hrc_ModelReadMasterNode(newModel); 01420 printf("\tInputs :\t"); 01421 Rst_VarForEachVarInArray(Hrc_NodeReadFormalInputs(newMaster), i, var) { 01422 printf("%s ", Var_VariableReadName(var)); 01423 } 01424 printf("\n\tOutputs:\t"); 01425 Rst_VarForEachVarInArray(Hrc_NodeReadFormalOutputs(newMaster), i, var) { 01426 printf("%s ", Var_VariableReadName(var)); 01427 } 01428 printf("\n\tVars:\t"); 01429 Hrc_NodeForEachVariable(Hrc_ModelReadMasterNode(newModel), 01430 sgen, varName, var) { 01431 printf("%s ", Var_VariableReadName(var)); 01432 } 01433 printf("\n"); 01434 } 01435 01451 Hrc_Model_t* 01452 RstGroupBuildModel( 01453 Hrc_Manager_t* Hmgr, 01454 Rst_Group_t* Group) 01455 { 01456 long inGroup; 01457 int retVal, i; 01458 st_generator* sgen; 01459 Var_Variable_t* var, *newVar, *newLatchInput, *newLatchOutput; 01460 Tbl_Table_t* tbl, *newTbl; 01461 Hrc_Latch_t* latch, *newLatch; 01462 st_table* varForwPtr; 01463 Hrc_Node_t* newMaster; 01464 Hrc_Subckt_t *subckt; 01465 Hrc_Model_t* subcktModel; 01466 Hrc_Model_t* newModel = Hrc_ModelAlloc(Hmgr, Group->name); 01467 array_t* actualInputArray, *actualOutputArray; 01468 01469 if (! newModel) { 01470 (void) fprintf(vis_stderr, "ERROR: could not create Model %s\n", 01471 Group->name); 01472 return 0; 01473 } 01474 01475 newMaster = Hrc_ModelReadMasterNode(newModel); 01476 assert(newMaster); 01477 01478 varForwPtr = st_init_table(st_ptrcmp, st_ptrhash); 01479 /* Add group's Variables: Inputs, Outputs */ 01480 st_foreach_item(Group->Inputs, sgen, &var, &inGroup) { 01481 if (! st_lookup(varForwPtr, (char*) var, &newVar)) { 01482 newVar = Var_VariableDup(var, newMaster); 01483 Var_VariableResetAllTypes(newVar); 01484 Var_VariableResetNumFanoutTables(newVar); 01485 Hrc_NodeAddFormalInput(newMaster, newVar); 01486 Var_VariableSetPI(newVar); 01487 st_insert(Group->VarBackPtr, (char*) newVar, (char*) var); 01488 st_insert(varForwPtr, (char*) var, (char*) newVar); 01489 } 01490 } 01491 st_foreach_item(Group->Outputs, sgen, &var, &inGroup) { 01492 if (! st_lookup(varForwPtr, (char*) var, &newVar)) { 01493 newVar = Var_VariableDup(var, newMaster); 01494 Var_VariableResetAllTypes(newVar); 01495 Var_VariableResetNumFanoutTables(newVar); 01496 Hrc_NodeAddFormalOutput(newMaster, newVar); 01497 Var_VariableSetPO(newVar); 01498 st_insert(Group->VarBackPtr, (char*) newVar, (char*) var); 01499 st_insert(varForwPtr, (char*) var, (char*) newVar); 01500 } 01501 } 01502 st_foreach_item(Group->Vars, sgen, &var, &inGroup) { 01503 if (! st_lookup(varForwPtr, (char*) var, &newVar)) { 01504 newVar = Var_VariableDup(var, newMaster); 01505 Var_VariableResetAllTypes(newVar); 01506 Var_VariableResetNumFanoutTables(newVar); 01507 st_insert(Group->VarBackPtr, (char*) newVar, (char*) var); 01508 st_insert(varForwPtr, (char*) var, (char*) newVar); 01509 } 01510 } 01511 01512 /* Add group's Tables */ 01513 st_foreach_item(Group->Tables, sgen, &tbl, &inGroup) { 01514 Hrc_NodeAddNameTable(newMaster, Tbl_TableDupAndSubstVars(tbl, varForwPtr)); 01515 } 01516 01517 /* Add group's Latches */ 01518 st_foreach_item(Group->Latches, sgen, &latch, &inGroup) { 01519 retVal = st_lookup(varForwPtr, (char*) Hrc_LatchReadInput(latch), 01520 &newLatchInput); 01521 assert(retVal); 01522 retVal = st_lookup(varForwPtr, (char*) Hrc_LatchReadOutput(latch), 01523 &newLatchOutput); 01524 assert(retVal); 01525 01526 newLatch = Hrc_LatchCreate(newModel, newLatchInput, newLatchOutput); 01527 assert(newLatch != NULL); 01528 Var_VariableSetNS(newLatchInput); 01529 Var_VariableSetPS(newLatchOutput); 01530 01531 /* Duplicate and attach Reset Table */ 01532 tbl = Hrc_LatchReadResetTable(latch); 01533 newTbl = Tbl_TableDupAndSubstVars(tbl, varForwPtr); 01534 /* HACK: For some reason, we don't count latches in fanout count */ 01535 retVal = Hrc_LatchSetResetTable(newLatch, newTbl); 01536 /* newTbl = Hrc_LatchReadResetTable(latch); */ 01537 assert(retVal); 01538 Tbl_TableForEachInputVar(tbl, i, var) { 01539 retVal = st_lookup(varForwPtr, (char*) var, &newVar); 01540 assert(retVal); 01541 Var_VariableResetAllTypes(newVar); 01542 Var_VariableResetNumFanoutTables(newVar); 01543 } 01544 Hrc_NodeAddLatch(newMaster, newLatch); 01545 } 01546 01547 /* Add group's Subckts */ 01548 01549 st_foreach_item(Group->Subcircuits, sgen, &subckt, &inGroup) { 01550 actualInputArray = 01551 Rst_VartoVarLookup(Hrc_SubcktReadActualInputVars(subckt), 01552 varForwPtr, 0); 01553 actualOutputArray = 01554 Rst_VartoVarLookup(Hrc_SubcktReadActualOutputVars(subckt), 01555 varForwPtr, 0); 01556 subcktModel = Hrc_SubcktReadModel(subckt); 01557 Hrc_ModelAddSubckt(newModel, subcktModel, 01558 Hrc_SubcktReadInstanceName(subckt), 01559 actualInputArray, actualOutputArray); 01560 Rst_VarForEachVarInArray(actualInputArray, i, var) { 01561 Var_VariableSetSI(var); 01562 } 01563 Rst_VarForEachVarInArray(actualOutputArray, i, var) { 01564 Var_VariableSetSO(var); 01565 } 01566 } 01567 01568 st_free_table(varForwPtr); 01569 01570 #ifdef RST_GROUP_DEBUG 01571 RstModelPrint(newModel); 01572 #endif 01573 return newModel; 01574 } 01575 01576 /* Overrides for Emacs so that we follow VIS tabbing style. 01577 * Must remain at end of file. 01578 * --------------------------------------------------------------------------- 01579 * Local variables: 01580 * c-basic-offset: 2 01581 * c-indent-level: 2 01582 * c-brace-imaginary-offset: 0 01583 * c-brace-offset: -2 01584 * c-argdecl-indent: 2 01585 * c-comment-only-line-offset: 0 01586 * c-label-offset: -4 01587 * c-continued-statement-offset: 2 01588 * c-continued-brace-offset: 0 01589 * End: */