Contains functions for handling functional unit instances. More...
#include "defines.h"
Go to the source code of this file.
Functions | |
funit_inst * | instance_create (func_unit *funit, char *inst_name, bool name_diff, bool ignore, bool gend_scope, vector_width *range) |
Creates a new instance with the given information. | |
void | instance_display_tree (funit_inst *root) |
Displays the current state of the instance tree. | |
void | instance_gen_scope (char *scope, funit_inst *leaf, bool flatten) |
Builds full hierarchy from leaf node to root. | |
funit_inst * | instance_find_scope (funit_inst *root, char *scope, bool rm_unnamed) |
Finds specified scope in functional unit instance tree. | |
funit_inst * | instance_find_by_funit (funit_inst *root, const func_unit *funit, int *ignore) |
Returns instance that points to specified functional unit for each instance. | |
vsignal * | instance_find_signal_by_exclusion_id (funit_inst *root, int id, func_unit **found_funit) |
Returns signal that matches the given exclusion ID. | |
expression * | instance_find_expression_by_exclusion_id (funit_inst *root, int id, func_unit **found_funit) |
Returns expression that matches the given exclusion ID. | |
int | instance_find_fsm_arc_index_by_exclusion_id (funit_inst *root, int id, fsm_table **found_fsm, func_unit **found_funit) |
Returns FSM that matches the given exclusion ID. | |
funit_inst * | instance_copy (funit_inst *from_inst, funit_inst *to_inst, char *name, vector_width *range, bool resolve) |
Copies the given from_inst as a child of the given to_inst. | |
bool | instance_parse_add (funit_inst **root, func_unit *parent, func_unit *child, char *inst_name, vector_width *range, bool resolve, bool child_gend, bool ignore_child, bool gend_scope) |
Adds new instance to specified instance tree during parse. | |
void | instance_resolve (funit_inst *root) |
Resolves all instance arrays. | |
bool | instance_read_add (funit_inst **root, char *parent, func_unit *child, char *inst_name) |
Adds new instance to specified instance tree during CDD read. | |
void | instance_get_leading_hierarchy (funit_inst *root, char *leading_hierarchy, funit_inst **top_inst) |
Gets the leading hierarchy scope and instance for a particular instance tree. | |
bool | instance_merge_two_trees (funit_inst *root1, funit_inst *root2) |
Performs complex instance tree merging for two instance trees. | |
void | instance_db_write (funit_inst *root, FILE *file, char *scope, bool parse_mode, bool issue_ids) |
Displays contents of functional unit instance tree to specified file. | |
void | instance_only_db_read (char **line) |
Reads in and handles an instance-only line from the database. | |
void | instance_only_db_merge (char **line) |
Reads in and merges an instance-only line from the database. | |
void | instance_remove_stmt_blks_calling_stmt (funit_inst *root, statement *stmt) |
Removes all statement blocks that contain expressions that call the given statement. | |
void | instance_remove_parms_with_expr (funit_inst *root, statement *stmt) |
Removes expressions from instance parameters within the given instance that match the given expression. | |
void | instance_output_dumpvars (FILE *vfile, funit_inst *root) |
Outputs dumpvars to the given file for the given instance. | |
void | instance_dealloc_tree (funit_inst *root) |
Recursively deallocates all memory for the associated instance tree. | |
void | instance_dealloc (funit_inst *root, char *scope) |
Removes specified instance from tree. |
Contains functions for handling functional unit instances.
funit_inst* instance_copy | ( | funit_inst * | from_inst, | |
funit_inst * | to_inst, | |||
char * | name, | |||
vector_width * | range, | |||
bool | resolve | |||
) |
Copies the given from_inst as a child of the given to_inst.
Recursively copies the instance tree of from_inst to the instance to_inst, allocating memory for the new instances and resolving parameters.
from_inst | Pointer to instance tree to copy | |
to_inst | Pointer to instance to copy tree to | |
name | Instance name of current instance being copied | |
range | For arrays of instances, indicates the array range | |
resolve | Set to TRUE if newly added instance should be immediately resolved |
References instance_copy_helper(), PROFILE, PROFILE_END, and TRUE.
Referenced by gen_item_resolve(), and instance_parse_add().
00660 { PROFILE(INSTANCE_COPY); 00661 00662 funit_inst* new_inst; 00663 00664 new_inst = instance_copy_helper( from_inst, to_inst, name, range, resolve, TRUE ); 00665 00666 PROFILE_END; 00667 00668 return( new_inst ); 00669 00670 }
funit_inst* instance_create | ( | func_unit * | funit, | |
char * | inst_name, | |||
bool | name_diff, | |||
bool | ignore, | |||
bool | gend_scope, | |||
vector_width * | range | |||
) |
Creates a new instance with the given information.
Creates a new functional unit instance from heap, initializes its data and returns a pointer to it.
funit | Pointer to functional unit to store in this instance | |
inst_name | Instantiated name of this instance | |
name_diff | Specifies if the inst_name provided is not accurate due to merging | |
ignore | Specifies that this instance is just a placeholder, not to be written to CDD | |
gend_scope | Specifies if this instance is a generated scope | |
range | For arrays of instances, contains range information for this array |
References funit_inst_s::child_head, funit_inst_s::child_tail, static_expr_s::exp, funit_inst_s::funit, funit_inst_s::gend_scope, funit_inst_s::gitem_head, funit_inst_s::gitem_tail, funit_inst_s::ignore, vector_width_s::left, malloc_safe, funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::next, static_expr_s::num, funit_inst_s::param_head, funit_inst_s::param_tail, funit_inst_s::parent, PROFILE, PROFILE_END, funit_inst_s::range, vector_width_s::right, funit_inst_s::stat, strdup_safe, and funit_inst_s::suppl.
Referenced by db_add_instance(), db_read(), instance_add_child(), instance_only_db_merge(), instance_only_db_read(), instance_parse_add(), instance_read_add(), and search_init().
00137 { PROFILE(INSTANCE_CREATE); 00138 00139 funit_inst* new_inst; /* Pointer to new functional unit instance */ 00140 00141 new_inst = (funit_inst*)malloc_safe( sizeof( funit_inst ) ); 00142 new_inst->funit = funit; 00143 new_inst->name = strdup_safe( inst_name ); 00144 new_inst->suppl.name_diff = name_diff; 00145 new_inst->suppl.ignore = ignore; 00146 new_inst->suppl.gend_scope = gend_scope; 00147 new_inst->stat = NULL; 00148 new_inst->param_head = NULL; 00149 new_inst->param_tail = NULL; 00150 new_inst->gitem_head = NULL; 00151 new_inst->gitem_tail = NULL; 00152 new_inst->parent = NULL; 00153 new_inst->child_head = NULL; 00154 new_inst->child_tail = NULL; 00155 new_inst->next = NULL; 00156 00157 /* Create range (get a copy since this memory is managed by the parser) */ 00158 if( range == NULL ) { 00159 new_inst->range = NULL; 00160 } else { 00161 assert( range->left != NULL ); 00162 assert( range->right != NULL ); 00163 new_inst->range = (vector_width*)malloc_safe( sizeof( vector_width ) ); 00164 new_inst->range->left = (static_expr*)malloc_safe( sizeof( static_expr ) ); 00165 new_inst->range->left->num = range->left->num; 00166 new_inst->range->left->exp = range->left->exp; 00167 new_inst->range->right = (static_expr*)malloc_safe( sizeof( static_expr ) ); 00168 new_inst->range->right->num = range->right->num; 00169 new_inst->range->right->exp = range->right->exp; 00170 } 00171 00172 PROFILE_END; 00173 00174 return( new_inst ); 00175 00176 }
void instance_db_write | ( | funit_inst * | root, | |
FILE * | file, | |||
char * | scope, | |||
bool | parse_mode, | |||
bool | issue_ids | |||
) |
Displays contents of functional unit instance tree to specified file.
anonymous | gen_item_assign_expr_ids instance_db_write funit_db_write |
Calls each functional unit display function in instance tree, starting with the root functional unit and ending when all of the leaf functional units are output. Note: the function that calls this function originally should set the value of scope to NULL.
root | Root of functional unit instance tree to write | |
file | Output file to display contents to | |
scope | Scope of this functional unit | |
parse_mode | Specifies if we are parsing or scoring | |
issue_ids | Specifies that we need to issue expression and signal IDs |
References funit_inst_s::child_head, curr_expr_id, curr_sig_id, DB_TYPE_INST_ONLY, exp_link_s::exp, func_unit_s::exp_head, FALSE, funit_inst_s::funit, funit_db_write(), FUNIT_NO_SCORE, gen_item_assign_ids(), gitem_link_s::gi, funit_inst_s::gitem_head, vsignal_s::id, funit_inst_s::ignore, instance_db_write(), funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::next, gitem_link_s::next, sig_link_s::next, exp_link_s::next, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, funit_inst_s::suppl, TRUE, func_unit_s::type, and expression_s::ulid.
Referenced by db_write(), and instance_db_write().
01174 { PROFILE(INSTANCE_DB_WRITE); 01175 01176 bool stop_recursive = FALSE; 01177 01178 assert( root != NULL ); 01179 01180 if( root->funit != NULL ) { 01181 01182 if( (root->funit->type != FUNIT_NO_SCORE) && !root->suppl.ignore ) { 01183 01184 funit_inst* curr = parse_mode ? root : NULL; 01185 01186 assert( scope != NULL ); 01187 01188 /* If we are in parse mode, re-issue expression IDs (we use the ulid field since it is not used in parse mode) */ 01189 if( issue_ids && (root->funit != NULL) ) { 01190 01191 exp_link* expl; 01192 sig_link* sigl; 01193 #ifndef VPI_ONLY 01194 gitem_link* gil; 01195 #endif 01196 01197 /* First issue IDs to the expressions within the functional unit */ 01198 expl = root->funit->exp_head; 01199 while( expl != NULL ) { 01200 expl->exp->ulid = curr_expr_id; 01201 curr_expr_id++; 01202 expl = expl->next; 01203 } 01204 01205 sigl = root->funit->sig_head; 01206 while( sigl != NULL ) { 01207 sigl->sig->id = curr_sig_id; 01208 curr_sig_id++; 01209 sigl = sigl->next; 01210 } 01211 01212 #ifndef VPI_ONLY 01213 /* Then issue IDs to any generated expressions/signals */ 01214 gil = root->gitem_head; 01215 while( gil != NULL ) { 01216 gen_item_assign_ids( gil->gi, root->funit ); 01217 gil = gil->next; 01218 } 01219 #endif 01220 01221 } 01222 01223 /* Display root functional unit */ 01224 funit_db_write( root->funit, scope, root->suppl.name_diff, file, curr, issue_ids ); 01225 01226 } else { 01227 01228 stop_recursive = TRUE; 01229 01230 } 01231 01232 } else { 01233 01234 /*@-formatcode@*/ 01235 fprintf( file, "%d %s %hhu\n", DB_TYPE_INST_ONLY, scope, root->suppl.name_diff ); 01236 /*@=formatcode@*/ 01237 01238 } 01239 01240 if( !stop_recursive ) { 01241 01242 char tscope[4096]; 01243 01244 /* Display children */ 01245 funit_inst* curr = root->child_head; 01246 while( curr != NULL ) { 01247 unsigned int rv = snprintf( tscope, 4096, "%s.%s", scope, curr->name ); 01248 assert( rv < 4096 ); 01249 instance_db_write( curr, file, tscope, parse_mode, issue_ids ); 01250 curr = curr->next; 01251 } 01252 01253 } 01254 01255 PROFILE_END; 01256 01257 }
void instance_dealloc | ( | funit_inst * | root, | |
char * | scope | |||
) |
Removes specified instance from tree.
Searches tree for specified functional unit. If the functional unit instance is found, the functional unit instance is removed from the tree along with all of its child functional unit instances.
root | Root of functional unit instance tree | |
scope | Scope of functional unit to remove from tree |
References funit_inst_s::child_head, funit_inst_s::child_tail, instance_dealloc_tree(), instance_find_scope(), funit_inst_s::name, funit_inst_s::next, PROFILE, PROFILE_END, scope_compare(), scope_extract_back(), and TRUE.
Referenced by inst_link_delete_list().
01571 { PROFILE(INSTANCE_DEALLOC); 01572 01573 funit_inst* inst; /* Pointer to instance to remove */ 01574 funit_inst* curr; /* Pointer to current child instance to remove */ 01575 funit_inst* last; /* Last current child instance */ 01576 char back[256]; /* Highest level of hierarchy in hierarchical reference */ 01577 char rest[4096]; /* Rest of scope value */ 01578 01579 assert( root != NULL ); 01580 assert( scope != NULL ); 01581 01582 if( scope_compare( root->name, scope ) ) { 01583 01584 /* We are the root so just remove the whole tree */ 01585 instance_dealloc_tree( root ); 01586 01587 } else { 01588 01589 /* 01590 Find parent instance of given scope and remove this instance 01591 from its child list. 01592 */ 01593 scope_extract_back( scope, back, rest ); 01594 assert( rest[0] != '\0' ); 01595 01596 inst = instance_find_scope( root, rest, TRUE ); 01597 assert( inst != NULL ); 01598 01599 curr = inst->child_head; 01600 last = NULL; 01601 while( (curr != NULL) && !scope_compare( curr->name, scope ) ) { 01602 last = curr; 01603 curr = curr->next; 01604 } 01605 01606 if( curr != NULL ) { 01607 if( last != NULL ) { 01608 last->next = curr->next; 01609 } 01610 if( curr == inst->child_head ) { 01611 /* Move parent head pointer */ 01612 inst->child_head = curr->next; 01613 } 01614 if( curr == inst->child_tail ) { 01615 /* Move parent tail pointer */ 01616 inst->child_tail = last; 01617 } 01618 } 01619 01620 instance_dealloc_tree( curr ); 01621 01622 } 01623 01624 PROFILE_END; 01625 01626 }
void instance_dealloc_tree | ( | funit_inst * | root | ) |
Recursively deallocates all memory for the associated instance tree.
Recursively traverses instance tree, deallocating heap memory used to store the the tree.
root | Pointer to root instance of functional unit instance tree to remove |
References funit_inst_s::child_head, instance_dealloc_single(), instance_dealloc_tree(), funit_inst_s::next, PROFILE, and PROFILE_END.
Referenced by gen_item_dealloc(), instance_dealloc(), and instance_dealloc_tree().
01539 { PROFILE(INSTANCE_DEALLOC_TREE); 01540 01541 funit_inst* curr; /* Pointer to current instance to evaluate */ 01542 funit_inst* tmp; /* Temporary pointer to instance */ 01543 01544 if( root != NULL ) { 01545 01546 /* Remove instance's children first */ 01547 curr = root->child_head; 01548 while( curr != NULL ) { 01549 tmp = curr->next; 01550 instance_dealloc_tree( curr ); 01551 curr = tmp; 01552 } 01553 01554 /* Deallocate the instance memory */ 01555 instance_dealloc_single( root ); 01556 01557 } 01558 01559 PROFILE_END; 01560 01561 }
void instance_display_tree | ( | funit_inst * | root | ) |
Displays the current state of the instance tree.
Displays the given instance tree to standard output in a hierarchical format. Shows instance names as well as associated module name.
root | Pointer to root instance to display |
References instance_display_tree_helper(), PROFILE, and PROFILE_END.
Referenced by inst_link_display().
00116 { PROFILE(INSTANCE_DISPLAY_TREE); 00117 00118 instance_display_tree_helper( root, "" ); 00119 00120 PROFILE_END; 00121 00122 }
funit_inst* instance_find_by_funit | ( | funit_inst * | root, | |
const func_unit * | funit, | |||
int * | ignore | |||
) |
Returns instance that points to specified functional unit for each instance.
Searches the specified functional unit instance tree for the specified functional unit. When a functional unit instance is found that points to the specified functional unit and the ignore value is 0, a pointer to that functional unit instance is passed back to the calling function; otherwise, the ignore count is decremented and the searching continues.
root | Pointer to root functional unit instance of tree | |
funit | Pointer to functional unit to find in tree | |
ignore | Pointer to number of matches to ignore |
References funit_inst_s::child_head, funit_inst_s::funit, instance_find_by_funit(), funit_inst_s::next, PROFILE, and PROFILE_END.
Referenced by inst_link_find_by_funit(), instance_find_by_funit(), instance_parse_add(), and param_expr_eval().
00320 { PROFILE(INSTANCE_FIND_BY_FUNIT); 00321 00322 funit_inst* match_inst = NULL; /* Pointer to functional unit instance that found a match */ 00323 funit_inst* curr_child; /* Pointer to current instances child functional unit instance */ 00324 00325 if( root != NULL ) { 00326 00327 if( root->funit == funit ) { 00328 00329 if( *ignore == 0 ) { 00330 match_inst = root; 00331 } else { 00332 (*ignore)--; 00333 } 00334 00335 } else { 00336 00337 curr_child = root->child_head; 00338 while( (curr_child != NULL) && (match_inst == NULL) ) { 00339 match_inst = instance_find_by_funit( curr_child, funit, ignore ); 00340 curr_child = curr_child->next; 00341 } 00342 00343 } 00344 00345 } 00346 00347 PROFILE_END; 00348 00349 return( match_inst ); 00350 00351 }
expression* instance_find_expression_by_exclusion_id | ( | funit_inst * | root, | |
int | id, | |||
func_unit ** | found_funit | |||
) |
Returns expression that matches the given exclusion ID.
Recursively searches the given instance tree to find the expression that has the same exclusion ID as the one specified.
root | Pointer to root instance | |
id | Exclusion ID to search for | |
found_funit | Pointer to functional unit containing this expression |
References funit_inst_s::child_head, exp_link_s::exp, func_unit_s::exp_head, func_unit_s::exp_tail, funit_inst_s::funit, expression_s::id, instance_find_expression_by_exclusion_id(), funit_inst_s::next, exp_link_s::next, PROFILE, and PROFILE_END.
Referenced by exclude_find_expression(), and instance_find_expression_by_exclusion_id().
00461 { PROFILE(INSTANCE_FIND_EXPRESSION_BY_EXCLUSION_ID); 00462 00463 expression* exp = NULL; /* Pointer to found expression */ 00464 00465 if( root != NULL ) { 00466 00467 if( (root->funit != NULL) && 00468 (root->funit->exp_head != NULL) && 00469 (root->funit->exp_head->exp->id <= id) && 00470 (root->funit->exp_tail->exp->id >= id) ) { 00471 00472 exp_link* expl = root->funit->exp_head; 00473 00474 while( (expl != NULL) && (expl->exp->id != id) ) { 00475 expl = expl->next; 00476 } 00477 assert( expl != NULL ); 00478 assert( expl->exp != NULL ); 00479 exp = expl->exp; 00480 *found_funit = root->funit; 00481 00482 } else { 00483 00484 funit_inst* child = root->child_head; 00485 while( (child != NULL) && ((exp = instance_find_expression_by_exclusion_id( child, id, found_funit )) == NULL) ) { 00486 child = child->next; 00487 } 00488 00489 } 00490 00491 } 00492 00493 PROFILE_END; 00494 00495 return( exp ); 00496 00497 }
int instance_find_fsm_arc_index_by_exclusion_id | ( | funit_inst * | root, | |
int | id, | |||
fsm_table ** | found_fsm, | |||
func_unit ** | found_funit | |||
) |
Returns FSM that matches the given exclusion ID.
References arc_find_arc_by_exclusion_id(), funit_inst_s::child_head, func_unit_s::fsm_head, funit_inst_s::funit, instance_find_fsm_arc_index_by_exclusion_id(), funit_inst_s::next, fsm_link_s::next, PROFILE, PROFILE_END, fsm_s::table, and fsm_link_s::table.
Referenced by exclude_find_fsm_arc(), and instance_find_fsm_arc_index_by_exclusion_id().
00508 { PROFILE(INSTANCE_FIND_FSM_ARC_INDEX_BY_EXCLUSION_ID); 00509 00510 int arc_index = -1; /* Index of found FSM arc */ 00511 00512 if( root != NULL ) { 00513 00514 fsm_link* fsml; 00515 00516 if( root->funit != NULL ) { 00517 fsml = root->funit->fsm_head; 00518 while( (fsml != NULL) && ((arc_index = arc_find_arc_by_exclusion_id( fsml->table->table, id )) == -1) ) { 00519 fsml = fsml->next; 00520 } 00521 } 00522 00523 if( arc_index != -1 ) { 00524 *found_fsm = fsml->table->table; 00525 *found_funit = root->funit; 00526 } else { 00527 funit_inst* child = root->child_head; 00528 while( (child != NULL) && ((arc_index = instance_find_fsm_arc_index_by_exclusion_id( child, id, found_fsm, found_funit )) == -1) ) { 00529 child = child->next; 00530 } 00531 } 00532 00533 } 00534 00535 PROFILE_END; 00536 00537 return( arc_index ); 00538 00539 }
funit_inst* instance_find_scope | ( | funit_inst * | root, | |
char * | scope, | |||
bool | rm_unnamed | |||
) |
Finds specified scope in functional unit instance tree.
Searches the specified functional unit instance tree for the specified scope. When the functional unit instance is found, a pointer to that functional unit instance is passed back to the calling function.
root | Root of funit_inst tree to parse for scope | |
scope | Scope to search for | |
rm_unnamed | Set to TRUE if we need to remove unnamed scopes |
References funit_inst_s::child_head, db_is_unnamed_scope(), funit_inst_s::funit, funit_is_unnamed(), instance_compare(), instance_find_scope(), funit_inst_s::name, funit_inst_s::next, PROFILE, PROFILE_END, and scope_extract_front().
Referenced by gen_item_resolve(), inst_link_find_by_scope(), instance_dealloc(), instance_find_scope(), instance_read_add(), scope_find_funit_from_scope(), scope_get_parent_funit(), and scope_get_parent_module().
00270 { PROFILE(INSTANCE_FIND_SCOPE); 00271 00272 char front[256]; /* Front of scope value */ 00273 char rest[4096]; /* Rest of scope value */ 00274 funit_inst* inst = NULL; /* Pointer to found instance */ 00275 funit_inst* child; /* Pointer to current child instance being traversed */ 00276 00277 assert( root != NULL ); 00278 00279 /* First extract the front scope */ 00280 scope_extract_front( scope, front, rest ); 00281 00282 /* Skip this instance and move onto the children if we are an unnamed scope that does not contain signals */ 00283 if( !rm_unnamed && db_is_unnamed_scope( root->name ) && !funit_is_unnamed( root->funit ) ) { 00284 child = root->child_head; 00285 while( (child != NULL) && ((inst = instance_find_scope( child, scope, rm_unnamed )) == NULL) ) { 00286 child = child->next; 00287 } 00288 00289 /* Keep traversing if our name matches */ 00290 } else if( instance_compare( front, root ) ) { 00291 if( rest[0] == '\0' ) { 00292 inst = root; 00293 } else { 00294 child = root->child_head; 00295 while( (child != NULL) && ((inst = instance_find_scope( child, rest, rm_unnamed )) == NULL) ) { 00296 child = child->next; 00297 } 00298 } 00299 } 00300 00301 PROFILE_END; 00302 00303 return( inst ); 00304 00305 }
vsignal* instance_find_signal_by_exclusion_id | ( | funit_inst * | root, | |
int | id, | |||
func_unit ** | found_funit | |||
) |
Returns signal that matches the given exclusion ID.
Recursively searches the given instance tree to find the signal that has the same exclusion ID as the one specified.
root | Pointer to root instance | |
id | Exclusion ID to search for | |
found_funit | Pointer to functional unit containing this signal |
References funit_inst_s::child_head, funit_inst_s::funit, vsignal_s::id, instance_find_signal_by_exclusion_id(), funit_inst_s::next, sig_link_s::next, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, and func_unit_s::sig_tail.
Referenced by exclude_find_signal(), and instance_find_signal_by_exclusion_id().
00413 { PROFILE(INSTANCE_FIND_SIGNAL_BY_EXCLUSION_ID); 00414 00415 vsignal* sig = NULL; /* Pointer to found signal */ 00416 00417 if( root != NULL ) { 00418 00419 if( (root->funit != NULL) && 00420 (root->funit->sig_head != NULL) && 00421 (root->funit->sig_head->sig->id <= id) && 00422 (root->funit->sig_tail->sig->id >= id) ) { 00423 00424 sig_link* sigl = root->funit->sig_head; 00425 00426 while( (sigl != NULL) && (sigl->sig->id != id) ) { 00427 sigl = sigl->next; 00428 } 00429 assert( sigl != NULL ); 00430 assert( sigl->sig != NULL ); 00431 sig = sigl->sig; 00432 *found_funit = root->funit; 00433 00434 } else { 00435 00436 funit_inst* child = root->child_head; 00437 while( (child != NULL) && ((sig = instance_find_signal_by_exclusion_id( child, id, found_funit )) == NULL) ) { 00438 child = child->next; 00439 } 00440 00441 } 00442 00443 } 00444 00445 PROFILE_END; 00446 00447 return( sig ); 00448 00449 }
void instance_gen_scope | ( | char * | scope, | |
funit_inst * | leaf, | |||
bool | flatten | |||
) |
Builds full hierarchy from leaf node to root.
Recursively travels up to the root of the instance tree, building the scope string as it goes. When the root instance is reached, the string is returned. Assumes that scope is initialized to the NULL character.
scope | String pointer to store generated scope (assumed to be allocated) | |
leaf | Pointer to leaf instance in scope | |
flatten | Causes all unnamed scopes to be removed from generated scope if set to TRUE |
References db_is_unnamed_scope(), instance_gen_scope(), funit_inst_s::name, funit_inst_s::parent, PROFILE, and PROFILE_END.
Referenced by instance_gen_scope(), instance_output_dumpvars(), and param_has_defparam().
00187 { PROFILE(INSTANCE_GEN_SCOPE); 00188 00189 if( leaf != NULL ) { 00190 00191 /* Call parent instance first */ 00192 instance_gen_scope( scope, leaf->parent, flatten ); 00193 00194 if( !flatten || !db_is_unnamed_scope( leaf->name ) ) { 00195 if( scope[0] != '\0' ) { 00196 strcat( scope, "." ); 00197 strcat( scope, leaf->name ); 00198 } else { 00199 strcpy( scope, leaf->name ); 00200 } 00201 } 00202 00203 } 00204 00205 PROFILE_END; 00206 00207 }
void instance_get_leading_hierarchy | ( | funit_inst * | root, | |
char * | leading_hierarchy, | |||
funit_inst ** | top_inst | |||
) |
Gets the leading hierarchy scope and instance for a particular instance tree.
Retrieves the leading hierarchy string and the pointer to the top-most populated instance given the specified instance tree.
root | Pointer to instance tree to get information from | |
leading_hierarchy | Leading hierarchy to first populated instance | |
top_inst | Pointer to first populated instance |
References funit_inst_s::child_head, funit_inst_s::funit, funit_inst_s::name, PROFILE, and PROFILE_END.
Referenced by db_check_for_top_module(), and instance_merge_two_trees().
01031 { PROFILE(INSTANCE_GET_LEADING_HIERARCHY); 01032 01033 if( leading_hierarchy != NULL ) { 01034 strcat( leading_hierarchy, root->name ); 01035 } 01036 01037 *top_inst = root; 01038 01039 if( root->funit == NULL ) { 01040 01041 do { 01042 root = root->child_head; 01043 if( leading_hierarchy != NULL ) { 01044 strcat( leading_hierarchy, "." ); 01045 strcat( leading_hierarchy, root->name ); 01046 } 01047 *top_inst = root; 01048 } while( (root != NULL) && (root->funit == NULL) ); 01049 01050 } 01051 01052 PROFILE_END; 01053 01054 }
bool instance_merge_two_trees | ( | funit_inst * | root1, | |
funit_inst * | root2 | |||
) |
Performs complex instance tree merging for two instance trees.
Performs comples merges two instance trees into one instance tree.
root1 | Pointer to first instance tree to merge | |
root2 | Pointer to second instance tree to merge |
References FALSE, funit_inst_s::funit, instance_find_by_funit_name_if_one(), instance_get_leading_hierarchy(), instance_mark_lhier_diffs(), instance_merge_tree(), funit_inst_s::name, func_unit_s::name, PROFILE, PROFILE_END, and TRUE.
Referenced by db_merge_instance_trees().
01092 { PROFILE(INSTANCE_MERGE_TWO_TREES); 01093 01094 bool retval = TRUE; 01095 char lhier1[4096]; 01096 char lhier2[4096]; 01097 funit_inst* tinst1 = NULL; 01098 funit_inst* tinst2 = NULL; 01099 01100 lhier1[0] = '\0'; 01101 lhier2[0] = '\0'; 01102 01103 /* Get leading hierarchy information */ 01104 instance_get_leading_hierarchy( root1, lhier1, &tinst1 ); 01105 instance_get_leading_hierarchy( root2, lhier2, &tinst2 ); 01106 01107 /* If the top-level modules are the same, just merge them */ 01108 if( (tinst1->funit != NULL) && (tinst2->funit != NULL) && (strcmp( tinst1->funit->name, tinst2->funit->name ) == 0) ) { 01109 01110 if( strcmp( lhier1, lhier2 ) == 0 ) { 01111 01112 bool rv = instance_merge_tree( tinst1, tinst2 ); 01113 assert( rv ); 01114 01115 } else if( strcmp( root1->name, root2->name ) == 0 ) { 01116 01117 bool rv = instance_merge_tree( root1, root2 ); 01118 assert( rv ); 01119 01120 } else { 01121 01122 bool rv = instance_merge_tree( tinst1, tinst2 ); 01123 assert( rv ); 01124 instance_mark_lhier_diffs( tinst1, tinst2 ); 01125 01126 } 01127 01128 /* If the two trees share the same root name, merge them */ 01129 } else if( (strcmp( root1->name, root2->name ) == 0) && instance_merge_tree( root1, root2 ) ) { 01130 01131 /* We've already merged so we don't have anything else to do */ 01132 01133 /* Check to see if the module pointed to by tinst1 exists within the tree of tinst2 */ 01134 } else if( (tinst1->funit != NULL) && ((root2 = instance_find_by_funit_name_if_one( tinst2, tinst1->funit->name )) != NULL) ) { 01135 01136 bool rv = instance_merge_tree( tinst1, root2 ); 01137 assert( rv ); 01138 instance_mark_lhier_diffs( tinst1, root2 ); 01139 01140 /* Check to see if the module pointed to by tinst2 exists within the tree of tinst1 */ 01141 } else if( (tinst2->funit != NULL) && ((root1 = instance_find_by_funit_name_if_one( tinst1, tinst2->funit->name )) != NULL) ) { 01142 01143 bool rv = instance_merge_tree( root1, tinst2 ); 01144 assert( rv ); 01145 instance_mark_lhier_diffs( root1, tinst2 ); 01146 01147 /* Otherwise, we cannot merge the two CDD files so don't */ 01148 } else { 01149 01150 retval = FALSE; 01151 01152 } 01153 01154 PROFILE_END; 01155 01156 return( retval ); 01157 01158 }
void instance_only_db_merge | ( | char ** | line | ) |
Reads in and merges an instance-only line from the database.
Merges instance-only constructs from two CDD files.
line | Pointer to line being read from database file |
References funit_inst_s::child_head, funit_inst_s::child_tail, curr_db, FALSE, FATAL, free_safe, inst_head, inst_link_add(), inst_link_find_by_scope(), db_s::inst_tail, instance_create(), funit_inst_s::next, funit_inst_s::parent, print_output(), PROFILE, PROFILE_END, scope_extract_back(), strdup_safe, and Throw.
Referenced by db_read().
01324 { PROFILE(INSTANCE_ONLY_DB_MERGE); 01325 01326 char scope[4096]; 01327 int chars_read; 01328 bool name_diff; 01329 01330 if( sscanf( *line, "%s %d%n", scope, (int*)&name_diff, &chars_read ) == 2 ) { 01331 01332 char* back = strdup_safe( scope ); 01333 char* rest = strdup_safe( scope ); 01334 funit_inst* child; 01335 01336 *line += chars_read; 01337 01338 scope_extract_back( scope, back, rest ); 01339 01340 /* Create "placeholder" instance */ 01341 child = instance_create( NULL, back, name_diff, FALSE, FALSE, NULL ); 01342 01343 /* If we are the top-most instance, just add ourselves to the instance link list */ 01344 if( rest[0] == '\0' ) { 01345 01346 /* Add a new instance link if was not able to be found in the instance linked list */ 01347 if( inst_link_find_by_scope( scope, db_list[curr_db]->inst_head ) == NULL ) { 01348 (void)inst_link_add( child, &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) ); 01349 } 01350 01351 /* Otherwise, find our parent instance and attach the new instance to it */ 01352 } else { 01353 funit_inst* parent; 01354 if( (parent = inst_link_find_by_scope( rest, db_list[curr_db]->inst_head )) != NULL ) { 01355 if( parent->child_head == NULL ) { 01356 parent->child_head = parent->child_tail = child; 01357 } else { 01358 parent->child_tail->next = child; 01359 parent->child_tail = child; 01360 } 01361 child->parent = parent; 01362 } else { 01363 print_output( "Unable to find parent instance of instance-only line in database file.", FATAL, __FILE__, __LINE__ ); 01364 Throw 0; 01365 } 01366 } 01367 01368 /* Deallocate memory */ 01369 free_safe( back, (strlen( scope ) + 1) ); 01370 free_safe( rest, (strlen( scope ) + 1) ); 01371 01372 } else { 01373 01374 print_output( "Unable to merge instance-only line in database file.", FATAL, __FILE__, __LINE__ ); 01375 Throw 0; 01376 01377 } 01378 01379 PROFILE_END; 01380 01381 }
void instance_only_db_read | ( | char ** | line | ) |
Reads in and handles an instance-only line from the database.
Parses an instance-only database line and adds a "placeholder" instance in the instance tree.
line | Pointer to line being read from database file |
References funit_inst_s::child_head, funit_inst_s::child_tail, curr_db, FALSE, FATAL, free_safe, inst_head, inst_link_add(), inst_link_find_by_scope(), db_s::inst_tail, instance_create(), funit_inst_s::next, funit_inst_s::parent, print_output(), PROFILE, PROFILE_END, scope_extract_back(), strdup_safe, and Throw.
Referenced by db_read().
01264 { PROFILE(INSTANCE_ONLY_DB_READ); 01265 01266 char scope[4096]; 01267 int chars_read; 01268 bool name_diff; 01269 01270 if( sscanf( *line, "%s %d%n", scope, (int*)&name_diff, &chars_read ) == 2 ) { 01271 01272 char* back = strdup_safe( scope ); 01273 char* rest = strdup_safe( scope ); 01274 funit_inst* child; 01275 01276 *line += chars_read; 01277 01278 scope_extract_back( scope, back, rest ); 01279 01280 /* Create "placeholder" instance */ 01281 child = instance_create( NULL, back, name_diff, FALSE, FALSE, NULL ); 01282 01283 /* If we are the top-most instance, just add ourselves to the instance link list */ 01284 if( rest[0] == '\0' ) { 01285 (void)inst_link_add( child, &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) ); 01286 01287 /* Otherwise, find our parent instance and attach the new instance to it */ 01288 } else { 01289 funit_inst* parent; 01290 if( (parent = inst_link_find_by_scope( rest, db_list[curr_db]->inst_tail )) != NULL ) { 01291 if( parent->child_head == NULL ) { 01292 parent->child_head = parent->child_tail = child; 01293 } else { 01294 parent->child_tail->next = child; 01295 parent->child_tail = child; 01296 } 01297 child->parent = parent; 01298 } else { 01299 print_output( "Unable to find parent instance of instance-only line in database file.", FATAL, __FILE__, __LINE__ ); 01300 Throw 0; 01301 } 01302 } 01303 01304 /* Deallocate memory */ 01305 free_safe( back, (strlen( scope ) + 1) ); 01306 free_safe( rest, (strlen( scope ) + 1) ); 01307 01308 } else { 01309 01310 print_output( "Unable to read instance-only line in database file.", FATAL, __FILE__, __LINE__ ); 01311 Throw 0; 01312 01313 } 01314 01315 PROFILE_END; 01316 01317 }
void instance_output_dumpvars | ( | FILE * | vfile, | |
funit_inst * | root | |||
) |
Outputs dumpvars to the given file for the given instance.
Outputs dumpvars to the specified file.
vfile | Pointer to file to output dumpvars to | |
root | Pointer to current instance |
References funit_inst_s::child_head, FALSE, funit_inst_s::funit, funit_output_dumpvars(), instance_gen_scope(), instance_output_dumpvars(), funit_inst_s::next, PROFILE, and PROFILE_END.
Referenced by db_output_dumpvars(), and instance_output_dumpvars().
01511 { PROFILE(INSTANCE_OUTPUT_DUMPVARS); 01512 01513 funit_inst* child = root->child_head; 01514 char scope[4096]; 01515 01516 /* Generate instance scope */ 01517 scope[0] = '\0'; 01518 instance_gen_scope( scope, root, FALSE ); 01519 01520 /* Outputs dumpvars for the given functional unit */ 01521 funit_output_dumpvars( vfile, root->funit, scope ); 01522 01523 /* Outputs all children instances */ 01524 while( child != NULL ) { 01525 instance_output_dumpvars( vfile, child ); 01526 child = child->next; 01527 } 01528 01529 PROFILE_END; 01530 01531 }
bool instance_parse_add | ( | funit_inst ** | root, | |
func_unit * | parent, | |||
func_unit * | child, | |||
char * | inst_name, | |||
vector_width * | range, | |||
bool | resolve, | |||
bool | child_gend, | |||
bool | ignore_child, | |||
bool | gend_scope | |||
) |
Adds new instance to specified instance tree during parse.
Adds the child functional unit to the child functional unit pointer list located in the functional unit specified by the scope of parent in the functional unit instance tree pointed to by root. This function is used by the db_add_instance function during the parsing stage.
root | Root funit_inst pointer of functional unit instance tree | |
parent | Pointer to parent functional unit of specified child | |
child | Pointer to child functional unit to add | |
inst_name | Name of new functional unit instance | |
range | For array of instances, specifies the name range | |
resolve | If set to TRUE, resolve any added instance | |
child_gend | If set to TRUE, specifies that child is a generated instance and should only be added once | |
ignore_child | If set to TRUE, causes the child instance to be ignored when writing to CDD file | |
gend_scope | If set to TRUE, the child instance is a generated scope |
References FALSE, func_unit_s::filename, funit_inst_s::funit, instance_add_child(), instance_copy(), instance_create(), instance_find_by_funit(), PROFILE, PROFILE_END, and TRUE.
Referenced by db_add_instance(), gen_item_resolve(), and instance_resolve_inst().
00691 { PROFILE(INSTANCE_PARSE_ADD); 00692 00693 bool retval = TRUE; /* Return value for this function */ 00694 funit_inst* inst; /* Temporary pointer to functional unit instance to add to */ 00695 funit_inst* cinst; /* Pointer to instance of child functional unit */ 00696 int i; /* Loop iterator */ 00697 int ignore; /* Number of matched instances to ignore */ 00698 00699 if( *root == NULL ) { 00700 00701 *root = instance_create( child, inst_name, FALSE, ignore_child, gend_scope, range ); 00702 00703 } else { 00704 00705 assert( parent != NULL ); 00706 00707 i = 0; 00708 ignore = 0; 00709 00710 /* 00711 Check to see if the child functional unit has already been parsed and, if so, find 00712 one of its instances for copying the instance tree below it. 00713 */ 00714 cinst = instance_find_by_funit( *root, child, &ignore); 00715 00716 /* Filename will be set to a value if the functional unit has been parsed */ 00717 if( (cinst != NULL) && (cinst->funit->filename != NULL) ) { 00718 00719 ignore = 0; 00720 while( (ignore >= 0) && ((inst = instance_find_by_funit( *root, parent, &ignore )) != NULL) ) { 00721 (void)instance_copy( cinst, inst, inst_name, range, resolve ); 00722 i++; 00723 ignore = child_gend ? -1 : i; 00724 } 00725 00726 } else { 00727 00728 ignore = 0; 00729 while( (ignore >= 0) && ((inst = instance_find_by_funit( *root, parent, &ignore )) != NULL) ) { 00730 cinst = instance_add_child( inst, child, inst_name, range, resolve, ignore_child, gend_scope ); 00731 i++; 00732 ignore = (child_gend && (cinst != NULL)) ? -1 : i; 00733 } 00734 00735 } 00736 00737 /* Everything went well with the add if we found at least one parent instance */ 00738 retval = (i > 0); 00739 00740 } 00741 00742 PROFILE_END; 00743 00744 return( retval ); 00745 00746 }
bool instance_read_add | ( | funit_inst ** | root, | |
char * | parent, | |||
func_unit * | child, | |||
char * | inst_name | |||
) |
Adds new instance to specified instance tree during CDD read.
Adds the child functional unit to the child functional unit pointer list located in the functional unit specified by the scope of parent in the functional unit instance tree pointed to by root. This function is used by the db_read function during the CDD reading stage.
root | Pointer to root instance of functional unit instance tree | |
parent | String scope of parent instance | |
child | Pointer to child functional unit to add to specified parent's child list | |
inst_name | Instance name of this child functional unit instance |
References funit_inst_s::child_head, funit_inst_s::child_tail, FALSE, instance_create(), instance_find_scope(), funit_inst_s::next, funit_inst_s::parent, PROFILE, PROFILE_END, and TRUE.
Referenced by db_read().
00903 { PROFILE(INSTANCE_READ_ADD); 00904 00905 bool retval = TRUE; /* Return value for this function */ 00906 funit_inst* inst; /* Temporary pointer to functional unit instance to add to */ 00907 funit_inst* new_inst; /* Pointer to new functional unit instance to add */ 00908 00909 if( *root == NULL ) { 00910 00911 *root = instance_create( child, inst_name, FALSE, FALSE, FALSE, NULL ); 00912 00913 } else { 00914 00915 assert( parent != NULL ); 00916 00917 if( (inst = instance_find_scope( *root, parent, TRUE )) != NULL ) { 00918 00919 /* Create new instance */ 00920 new_inst = instance_create( child, inst_name, FALSE, FALSE, FALSE, NULL ); 00921 00922 if( inst->child_head == NULL ) { 00923 inst->child_head = new_inst; 00924 inst->child_tail = new_inst; 00925 } else { 00926 inst->child_tail->next = new_inst; 00927 inst->child_tail = new_inst; 00928 } 00929 00930 /* Set parent pointer of new instance */ 00931 new_inst->parent = inst; 00932 00933 } else { 00934 00935 /* Unable to find parent of this child, needs to be added to a different instance tree */ 00936 retval = FALSE; 00937 00938 } 00939 00940 } 00941 00942 PROFILE_END; 00943 00944 return( retval ); 00945 00946 }
void instance_remove_parms_with_expr | ( | funit_inst * | root, | |
statement * | stmt | |||
) |
Removes expressions from instance parameters within the given instance that match the given expression.
Recursively traverses the given instance tree, removing the given statement.
root | Pointer to functional unit instance to remove expression from | |
stmt | Pointer to statement to remove from list |
References funit_inst_s::child_head, exp_link_s::exp, statement_s::exp, mod_parm_s::exp_head, vsignal_s::exp_head, exp_link_remove(), vsignal_s::exp_tail, mod_parm_s::exp_tail, expression_find_expr(), FALSE, instance_remove_parms_with_expr(), inst_parm_s::mparm, funit_inst_s::next, inst_parm_s::next, exp_link_s::next, funit_inst_s::param_head, PROFILE, PROFILE_END, and inst_parm_s::sig.
Referenced by db_remove_statement_from_current_funit(), and instance_remove_parms_with_expr().
01429 { PROFILE(INSTANCE_REMOVE_PARMS_WITH_EXPR); 01430 01431 funit_inst* curr_child; /* Pointer to current child instance to traverse */ 01432 inst_parm* iparm; /* Pointer to current instance parameter */ 01433 exp_link* expl; /* Pointer to current expression link */ 01434 exp_link* texpl; /* Temporary pointer to current expression link */ 01435 01436 /* Search for the given expression within the given instance parameter */ 01437 iparm = root->param_head; 01438 while( iparm != NULL ) { 01439 if( iparm->sig != NULL ) { 01440 expl = iparm->sig->exp_head; 01441 while( expl != NULL ) { 01442 texpl = expl; 01443 expl = expl->next; 01444 if( expression_find_expr( stmt->exp, texpl->exp ) ) { 01445 if( iparm->mparm != NULL ) { 01446 exp_link_remove( texpl->exp, &(iparm->mparm->exp_head), &(iparm->mparm->exp_tail), FALSE ); 01447 } 01448 exp_link_remove( texpl->exp, &(iparm->sig->exp_head), &(iparm->sig->exp_tail), FALSE ); 01449 } 01450 } 01451 } 01452 iparm = iparm->next; 01453 } 01454 01455 /* Traverse children */ 01456 curr_child = root->child_head; 01457 while( curr_child != NULL ) { 01458 instance_remove_parms_with_expr( curr_child, stmt ); 01459 curr_child = curr_child->next; 01460 } 01461 01462 PROFILE_END; 01463 01464 }
void instance_remove_stmt_blks_calling_stmt | ( | funit_inst * | root, | |
statement * | stmt | |||
) |
Removes all statement blocks that contain expressions that call the given statement.
Removes all statement blocks in the design that call that specified statement.
root | Pointer to root instance to remove statements from | |
stmt | Pointer to statement to match |
References funit_inst_s::child_head, funit_inst_s::funit, funit_remove_stmt_blks_calling_stmt(), gen_item_remove_if_contains_expr_calling_stmt(), gitem_link_s::gi, funit_inst_s::gitem_head, instance_remove_stmt_blks_calling_stmt(), funit_inst_s::next, gitem_link_s::next, PROFILE, and PROFILE_END.
Referenced by db_remove_stmt_blks_calling_statement(), and instance_remove_stmt_blks_calling_stmt().
01389 { PROFILE(INSTANCE_REMOVE_STMT_BLKS_CALLING_STMT); 01390 01391 funit_inst* curr_child; /* Pointer to current child instance to parse */ 01392 #ifndef VPI_ONLY 01393 gitem_link* gil; /* Pointer to current generate item link */ 01394 #endif 01395 01396 if( root != NULL ) { 01397 01398 /* First, handle the current functional unit */ 01399 funit_remove_stmt_blks_calling_stmt( root->funit, stmt ); 01400 01401 #ifndef VPI_ONLY 01402 /* Second, handle all generate items in this instance */ 01403 gil = root->gitem_head; 01404 while( gil != NULL ) { 01405 gen_item_remove_if_contains_expr_calling_stmt( gil->gi, stmt ); 01406 gil = gil->next; 01407 } 01408 #endif 01409 01410 /* Parse children */ 01411 curr_child = root->child_head; 01412 while( curr_child != NULL ) { 01413 instance_remove_stmt_blks_calling_stmt( curr_child, stmt ); 01414 curr_child = curr_child->next; 01415 } 01416 01417 } 01418 01419 PROFILE_END; 01420 01421 }
void instance_resolve | ( | funit_inst * | root | ) |
Resolves all instance arrays.
Recursively iterates through entire instance tree, resolving any instance arrays that are found.
root | Pointer to current functional unit instance to resolve |
References instance_resolve_helper(), PROFILE, and PROFILE_END.
Referenced by bind_perform().
00880 { PROFILE(INSTANCE_RESOLVE); 00881 00882 /* Resolve all instance names */ 00883 instance_resolve_helper( root, root ); 00884 00885 PROFILE_END; 00886 00887 }