#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "arc.h"
#include "db.h"
#include "defines.h"
#include "expr.h"
#include "func_unit.h"
#include "gen_item.h"
#include "instance.h"
#include "link.h"
#include "param.h"
#include "static.h"
#include "util.h"
Functions | |
| bool | instance_resolve_inst (funit_inst *, funit_inst *) |
| void | instance_dealloc_single (funit_inst *) |
| void | instance_display_tree_helper (funit_inst *root, char *prefix) |
| void | instance_display_tree (funit_inst *root) |
| Displays the current state of the instance tree. | |
| 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_gen_scope (char *scope, funit_inst *leaf, bool flatten) |
| Builds full hierarchy from leaf node to root. | |
| bool | instance_compare (char *inst_name, const funit_inst *inst) |
| 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. | |
| void | instance_find_by_funit_name (funit_inst *root, const char *funit_name, funit_inst **match_inst, unsigned int *matches) |
| funit_inst * | instance_find_by_funit_name_if_one (funit_inst *root, const char *funit_name) |
| 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_add_child (funit_inst *inst, func_unit *child, char *name, vector_width *range, bool resolve, bool ignore_child, bool gend_scope) |
| funit_inst * | instance_copy_helper (funit_inst *from_inst, funit_inst *to_inst, char *name, vector_width *range, bool resolve, bool is_root) |
| 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_helper (funit_inst *root, funit_inst *curr) |
| 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. | |
| bool | instance_merge_tree (funit_inst *root1, funit_inst *root2) |
| 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. | |
| void | instance_mark_lhier_diffs (funit_inst *root1, funit_inst *root2) |
| 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, bool report_save) |
| 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. | |
Variables | |
| int | curr_expr_id |
| db ** | db_list |
| unsigned int | curr_db |
| char | user_msg [USER_MSG_LENGTH] |
| int | curr_sig_id = 1 |
|
||||||||||||||||||||||||||||||||
|
00550 { PROFILE(INSTANCE_ADD_CHILD);
00551
00552 funit_inst* new_inst; /* Pointer to newly created instance to add */
00553
00554 /* Check to see if this instance already exists */
00555 new_inst = inst->child_head;
00556 while( (new_inst != NULL) && ((strcmp( new_inst->name, name ) != 0) || (new_inst->funit != child)) ) {
00557 new_inst = new_inst->next;
00558 }
00559
00560 /* If this instance already exists (unless the existing and new child is a placeholder), don't add it again */
00561 if( (new_inst == NULL) || (new_inst->suppl.ignore && ignore_child) ) {
00562
00563 /* Generate new instance */
00564 new_inst = instance_create( child, name, FALSE, ignore_child, gend_scope, range );
00565
00566 /* Add new instance to inst child instance list */
00567 if( inst->child_head == NULL ) {
00568 inst->child_head = new_inst;
00569 inst->child_tail = new_inst;
00570 } else {
00571 inst->child_tail->next = new_inst;
00572 inst->child_tail = new_inst;
00573 }
00574
00575 /* Point this instance's parent pointer to its parent */
00576 new_inst->parent = inst;
00577
00578 // inst_link_display( db_list[curr_db]->inst_head );
00579
00580 /* If the new instance needs to be resolved now, do so */
00581 if( resolve ) {
00582 inst_link* instl = db_list[curr_db]->inst_head;
00583 while( (instl != NULL) && !instance_resolve_inst( instl->inst, new_inst ) ) {
00584 instl = instl->next;
00585 }
00586 }
00587
00588 } else {
00589
00590 /* Set the ignore value in the instance to FALSE */
00591 new_inst->suppl.ignore = FALSE;
00592
00593 new_inst = NULL;
00594
00595 }
00596
00597 PROFILE_END;
00598
00599 return( new_inst );
00600
00601 }
|
|
||||||||||||
|
00213 { PROFILE(INSTANCE_COMPARE);
00214
00215 bool retval = FALSE; /* Return value of this function */
00216 char bname[4096]; /* Base name of inst_name */
00217 int index; /* Index of inst_name */
00218 unsigned int width; /* Width of instance range */
00219 int lsb; /* LSB of instance range */
00220 int big_endian; /* Specifies endianness */
00221
00222 /* If this instance has a range, handle it */
00223 if( inst->range != NULL ) {
00224
00225 /* Extract the index portion of inst_name if there is one */
00226 if( sscanf( inst_name, "%[a-zA-Z0-9_]\[%d]", bname, &index ) == 2 ) {
00227
00228 /* If the base names compare, check that the given index falls within this instance range */
00229 if( scope_compare( bname, inst->name ) ) {
00230
00231 /* Get range information from instance */
00232 static_expr_calc_lsb_and_width_post( inst->range->left, inst->range->right, &width, &lsb, &big_endian );
00233 assert( width != 0 );
00234 assert( lsb != -1 );
00235
00236 retval = (index >= lsb) && (index < (lsb + (int)width));
00237
00238 }
00239
00240 }
00241
00242 } else {
00243
00244 retval = scope_compare( inst_name, inst->name );
00245
00246 }
00247
00248 PROFILE_END;
00249
00250 return( retval );
00251
00252 }
|
|
||||||||||||||||||||||||
|
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.
00654 { PROFILE(INSTANCE_COPY);
00655
00656 funit_inst* new_inst;
00657
00658 new_inst = instance_copy_helper( from_inst, to_inst, name, range, resolve, TRUE );
00659
00660 PROFILE_END;
00661
00662 return( new_inst );
00663
00664 }
|
|
||||||||||||||||||||||||||||
|
Recursively copies the instance tree of from_inst to the instance to_inst, allocating memory for the new instances and resolving parameters.
00614 { PROFILE(INSTANCE_COPY_HELPER);
00615
00616 funit_inst* curr; /* Pointer to current functional unit instance to copy */
00617 funit_inst* new_inst; /* Pointer to newly created functional unit instance */
00618
00619 assert( from_inst != NULL );
00620 assert( to_inst != NULL );
00621 assert( name != NULL );
00622
00623 /* Add new child instance */
00624 new_inst = instance_add_child( to_inst, from_inst->funit, name, range, resolve, (from_inst->suppl.ignore && from_inst->suppl.gend_scope && !is_root), from_inst->suppl.gend_scope );
00625
00626 /* Do not add children if no child instance was created */
00627 if( new_inst != NULL ) {
00628
00629 /* Iterate through rest of current child's list of children */
00630 curr = from_inst->child_head;
00631 while( curr != NULL ) {
00632 (void)instance_copy_helper( curr, new_inst, curr->name, curr->range, resolve, FALSE );
00633 curr = curr->next;
00634 }
00635
00636 }
00637
00638 PROFILE_END;
00639
00640 return( new_inst );
00641
00642 }
|
|
||||||||||||||||||||||||||||
|
Creates a new instance with the given information.
00132 { PROFILE(INSTANCE_CREATE);
00133
00134 funit_inst* new_inst; /* Pointer to new functional unit instance */
00135
00136 new_inst = (funit_inst*)malloc_safe( sizeof( funit_inst ) );
00137 new_inst->funit = funit;
00138 new_inst->name = strdup_safe( inst_name );
00139 new_inst->suppl.name_diff = name_diff;
00140 new_inst->suppl.ignore = ignore;
00141 new_inst->suppl.gend_scope = gend_scope;
00142 new_inst->stat = NULL;
00143 new_inst->param_head = NULL;
00144 new_inst->param_tail = NULL;
00145 new_inst->gitem_head = NULL;
00146 new_inst->gitem_tail = NULL;
00147 new_inst->parent = NULL;
00148 new_inst->child_head = NULL;
00149 new_inst->child_tail = NULL;
00150 new_inst->next = NULL;
00151
00152 /* Create range (get a copy since this memory is managed by the parser) */
00153 if( range == NULL ) {
00154 new_inst->range = NULL;
00155 } else {
00156 assert( range->left != NULL );
00157 assert( range->right != NULL );
00158 new_inst->range = (vector_width*)malloc_safe( sizeof( vector_width ) );
00159 new_inst->range->left = (static_expr*)malloc_safe( sizeof( static_expr ) );
00160 new_inst->range->left->num = range->left->num;
00161 new_inst->range->left->exp = range->left->exp;
00162 new_inst->range->right = (static_expr*)malloc_safe( sizeof( static_expr ) );
00163 new_inst->range->right->num = range->right->num;
00164 new_inst->range->right->exp = range->right->exp;
00165 }
00166
00167 PROFILE_END;
00168
00169 return( new_inst );
00170
00171 }
|
|
||||||||||||||||||||||||||||
|
Displays contents of functional unit instance tree to specified file.
01142 { PROFILE(INSTANCE_DB_WRITE);
01143
01144 bool stop_recursive = FALSE;
01145
01146 assert( root != NULL );
01147
01148 if( root->funit != NULL ) {
01149
01150 if( (root->funit->type != FUNIT_NO_SCORE) && !root->suppl.ignore ) {
01151
01152 funit_inst* curr = parse_mode ? root : NULL;
01153
01154 assert( scope != NULL );
01155
01156 /* If we are in parse mode, re-issue expression IDs (we use the ulid field since it is not used in parse mode) */
01157 if( issue_ids && (root->funit != NULL) ) {
01158
01159 exp_link* expl;
01160 sig_link* sigl;
01161 #ifndef VPI_ONLY
01162 gitem_link* gil;
01163 #endif
01164
01165 /* First issue IDs to the expressions within the functional unit */
01166 expl = root->funit->exp_head;
01167 while( expl != NULL ) {
01168 expl->exp->ulid = curr_expr_id;
01169 curr_expr_id++;
01170 expl = expl->next;
01171 }
01172
01173 sigl = root->funit->sig_head;
01174 while( sigl != NULL ) {
01175 sigl->sig->id = curr_sig_id;
01176 curr_sig_id++;
01177 sigl = sigl->next;
01178 }
01179
01180 #ifndef VPI_ONLY
01181 /* Then issue IDs to any generated expressions/signals */
01182 gil = root->gitem_head;
01183 while( gil != NULL ) {
01184 gen_item_assign_ids( gil->gi, root->funit );
01185 gil = gil->next;
01186 }
01187 #endif
01188
01189 }
01190
01191 /* Display root functional unit */
01192 funit_db_write( root->funit, scope, root->suppl.name_diff, file, curr, report_save, issue_ids );
01193
01194 } else {
01195
01196 stop_recursive = TRUE;
01197
01198 }
01199
01200 } else {
01201
01202 fprintf( file, "%d %s %d\n", DB_TYPE_INST_ONLY, scope, root->suppl.name_diff );
01203
01204 }
01205
01206 if( !stop_recursive ) {
01207
01208 char tscope[4096];
01209
01210 /* Display children */
01211 funit_inst* curr = root->child_head;
01212 while( curr != NULL ) {
01213 unsigned int rv = snprintf( tscope, 4096, "%s.%s", scope, curr->name );
01214 assert( rv < 4096 );
01215 instance_db_write( curr, file, tscope, parse_mode, issue_ids, report_save );
01216 curr = curr->next;
01217 }
01218
01219 }
01220
01221 PROFILE_END;
01222
01223 }
|
|
||||||||||||
|
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.
01537 { PROFILE(INSTANCE_DEALLOC);
01538
01539 funit_inst* inst; /* Pointer to instance to remove */
01540 funit_inst* curr; /* Pointer to current child instance to remove */
01541 funit_inst* last; /* Last current child instance */
01542 char back[256]; /* Highest level of hierarchy in hierarchical reference */
01543 char rest[4096]; /* Rest of scope value */
01544
01545 assert( root != NULL );
01546 assert( scope != NULL );
01547
01548 if( scope_compare( root->name, scope ) ) {
01549
01550 /* We are the root so just remove the whole tree */
01551 instance_dealloc_tree( root );
01552
01553 } else {
01554
01555 /*
01556 Find parent instance of given scope and remove this instance
01557 from its child list.
01558 */
01559 scope_extract_back( scope, back, rest );
01560 assert( rest[0] != '\0' );
01561
01562 inst = instance_find_scope( root, rest, TRUE );
01563 assert( inst != NULL );
01564
01565 curr = inst->child_head;
01566 last = NULL;
01567 while( (curr != NULL) && !scope_compare( curr->name, scope ) ) {
01568 last = curr;
01569 curr = curr->next;
01570 }
01571
01572 if( curr != NULL ) {
01573 if( last != NULL ) {
01574 last->next = curr->next;
01575 }
01576 if( curr == inst->child_head ) {
01577 /* Move parent head pointer */
01578 inst->child_head = curr->next;
01579 }
01580 if( curr == inst->child_tail ) {
01581 /* Move parent tail pointer */
01582 inst->child_tail = last;
01583 }
01584 }
01585
01586 instance_dealloc_tree( curr );
01587
01588 }
01589
01590 PROFILE_END;
01591
01592 }
|
|
|
Deallocates all memory allocated for the given instance.
01437 { PROFILE(INSTANCE_DEALLOC_SINGLE);
01438
01439 if( inst != NULL ) {
01440
01441 /* Free up memory allocated for name */
01442 free_safe( inst->name, (strlen( inst->name ) + 1) );
01443
01444 /* Free up memory allocated for statistic, if necessary */
01445 free_safe( inst->stat, sizeof( statistic ) );
01446
01447 /* Free up memory for range, if necessary */
01448 if( inst->range != NULL ) {
01449 static_expr_dealloc( inst->range->left, FALSE );
01450 static_expr_dealloc( inst->range->right, FALSE );
01451 free_safe( inst->range, sizeof( vector_width ) );
01452 }
01453
01454 /* Deallocate memory for instance parameter list */
01455 inst_parm_dealloc( inst->param_head, TRUE );
01456
01457 #ifndef VPI_ONLY
01458 /* Deallocate memory for generate item list */
01459 gitem_link_delete_list( inst->gitem_head, FALSE );
01460 #endif
01461
01462 /* Free up memory for this functional unit instance */
01463 free_safe( inst, sizeof( funit_inst ) );
01464
01465 }
01466
01467 PROFILE_END;
01468
01469 }
|
|
|
Recursively deallocates all memory for the associated instance tree. Recursively traverses instance tree, deallocating heap memory used to store the the tree.
01505 { PROFILE(INSTANCE_DEALLOC_TREE);
01506
01507 funit_inst* curr; /* Pointer to current instance to evaluate */
01508 funit_inst* tmp; /* Temporary pointer to instance */
01509
01510 if( root != NULL ) {
01511
01512 /* Remove instance's children first */
01513 curr = root->child_head;
01514 while( curr != NULL ) {
01515 tmp = curr->next;
01516 instance_dealloc_tree( curr );
01517 curr = tmp;
01518 }
01519
01520 /* Deallocate the instance memory */
01521 instance_dealloc_single( root );
01522
01523 }
01524
01525 PROFILE_END;
01526
01527 }
|
|
|
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.
00111 { PROFILE(INSTANCE_DISPLAY_TREE);
00112
00113 instance_display_tree_helper( root, "" );
00114
00115 PROFILE_END;
00116
00117 }
|
|
||||||||||||
|
Helper function for the instance_display_tree function.
00068 { PROFILE(INSTANCE_DISPLAY_TREE_HELPER);
00069
00070 char sp[4096]; /* Contains prefix for children */
00071 funit_inst* curr; /* Pointer to current child instance */
00072 unsigned int rv; /* Return value from snprintf calls */
00073
00074 assert( root != NULL );
00075
00076 /* Get printable version of this instance and functional unit name */
00077 if( root->funit != NULL ) {
00078 char* piname = scope_gen_printable( root->name );
00079 char* pfname = scope_gen_printable( root->funit->name );
00080 printf( "%s%s (%s) - %p (ign: %d, gend: %d)\n", prefix, piname, pfname, root, root->suppl.ignore, root->suppl.gend_scope );
00081 free_safe( piname, (strlen( piname ) + 1) );
00082 free_safe( pfname, (strlen( pfname ) + 1) );
00083 } else {
00084 char* piname = scope_gen_printable( root->name );
00085 printf( "%s%s () - %p (%d %d)\n", prefix, piname, root, root->suppl.ignore, root->suppl.gend_scope );
00086 free_safe( piname, (strlen( piname ) + 1) );
00087 }
00088
00089 /* Calculate prefix */
00090 rv = snprintf( sp, 4096, "%s ", prefix );
00091 assert( rv < 4096 );
00092
00093 /* Display our children */
00094 curr = root->child_head;
00095 while( curr != NULL ) {
00096 instance_display_tree_helper( curr, sp );
00097 curr = curr->next;
00098 }
00099
00100
00101 PROFILE_END;
00102
00103 }
|
|
||||||||||||||||
|
Returns instance that points to specified functional unit for each instance.
00315 { PROFILE(INSTANCE_FIND_BY_FUNIT);
00316
00317 funit_inst* match_inst = NULL; /* Pointer to functional unit instance that found a match */
00318 funit_inst* curr_child; /* Pointer to current instances child functional unit instance */
00319
00320 if( root != NULL ) {
00321
00322 if( root->funit == funit ) {
00323
00324 if( *ignore == 0 ) {
00325 match_inst = root;
00326 } else {
00327 (*ignore)--;
00328 }
00329
00330 } else {
00331
00332 curr_child = root->child_head;
00333 while( (curr_child != NULL) && (match_inst == NULL) ) {
00334 match_inst = instance_find_by_funit( curr_child, funit, ignore );
00335 curr_child = curr_child->next;
00336 }
00337
00338 }
00339
00340 }
00341
00342 PROFILE_END;
00343
00344 return( match_inst );
00345
00346 }
|
|
||||||||||||||||||||
|
Recursively searches the given instance tree, setting match_inst and matches if a matched functional unit name was found.
00356 { PROFILE(INSTANCE_FIND_BY_FUNIT_NAME_IF_ONE_HELPER);
00357
00358 if( root != NULL ) {
00359
00360 funit_inst* child;
00361
00362 if( strcmp( root->funit->name, funit_name ) == 0 ) {
00363 (*matches)++;
00364 *match_inst = root;
00365 }
00366
00367 child = root->child_head;
00368 while( child != NULL ) {
00369 instance_find_by_funit_name( child, funit_name, match_inst, matches );
00370 child = child->next;
00371 }
00372
00373 }
00374
00375 PROFILE_END;
00376
00377 }
|
|
||||||||||||
|
00385 { PROFILE(INSTANCE_FIND_BY_FUNIT_NAME_IF_ONE);
00386
00387 funit_inst* match_inst = NULL;
00388 unsigned int matches = 0;
00389
00390 instance_find_by_funit_name( root, funit_name, &match_inst, &matches );
00391
00392 PROFILE_END;
00393
00394 return( (matches == 1) ? match_inst : NULL );
00395
00396 }
|
|
||||||||||||||||
|
Returns expression that matches the given exclusion ID.
00455 { PROFILE(INSTANCE_FIND_EXPRESSION_BY_EXCLUSION_ID);
00456
00457 expression* exp = NULL; /* Pointer to found expression */
00458
00459 if( root != NULL ) {
00460
00461 assert( root->funit != NULL );
00462
00463 if( (root->funit->exp_head != NULL) &&
00464 (root->funit->exp_head->exp->id <= id) &&
00465 (root->funit->exp_tail->exp->id >= id) ) {
00466
00467 exp_link* expl = root->funit->exp_head;
00468
00469 while( (expl != NULL) && (expl->exp->id != id) ) {
00470 expl = expl->next;
00471 }
00472 assert( expl->exp != NULL );
00473 exp = expl->exp;
00474 *found_funit = root->funit;
00475
00476 } else {
00477
00478 funit_inst* child = root->child_head;
00479 while( (child != NULL) && ((exp = instance_find_expression_by_exclusion_id( child, id, found_funit )) == NULL) ) {
00480 child = child->next;
00481 }
00482
00483 }
00484
00485 }
00486
00487 PROFILE_END;
00488
00489 return( exp );
00490
00491 }
|
|
||||||||||||||||||||
|
Returns FSM that matches the given exclusion ID.
00502 { PROFILE(INSTANCE_FIND_FSM_ARC_INDEX_BY_EXCLUSION_ID);
00503
00504 int arc_index = -1; /* Index of found FSM arc */
00505
00506 if( root != NULL ) {
00507
00508 fsm_link* fsml;
00509
00510 assert( root->funit != NULL );
00511
00512 fsml = root->funit->fsm_head;
00513 while( (fsml != NULL) && ((arc_index = arc_find_arc_by_exclusion_id( fsml->table->table, id )) == -1) ) {
00514 fsml = fsml->next;
00515 }
00516
00517 if( arc_index != -1 ) {
00518 *found_fsm = fsml->table->table;
00519 *found_funit = root->funit;
00520 } else {
00521 funit_inst* child = root->child_head;
00522 while( (child != NULL) && ((arc_index = instance_find_fsm_arc_index_by_exclusion_id( child, id, found_fsm, found_funit )) == -1) ) {
00523 child = child->next;
00524 }
00525 }
00526
00527 }
00528
00529 PROFILE_END;
00530
00531 return( arc_index );
00532
00533 }
|
|
||||||||||||||||
|
Finds specified scope in functional unit instance tree.
00265 { PROFILE(INSTANCE_FIND_SCOPE);
00266
00267 char front[256]; /* Front of scope value */
00268 char rest[4096]; /* Rest of scope value */
00269 funit_inst* inst = NULL; /* Pointer to found instance */
00270 funit_inst* child; /* Pointer to current child instance being traversed */
00271
00272 assert( root != NULL );
00273
00274 /* First extract the front scope */
00275 scope_extract_front( scope, front, rest );
00276
00277 /* Skip this instance and move onto the children if we are an unnamed scope that does not contain signals */
00278 if( !rm_unnamed && db_is_unnamed_scope( root->name ) && !funit_is_unnamed( root->funit ) ) {
00279 child = root->child_head;
00280 while( (child != NULL) && ((inst = instance_find_scope( child, scope, rm_unnamed )) == NULL) ) {
00281 child = child->next;
00282 }
00283
00284 /* Keep traversing if our name matches */
00285 } else if( instance_compare( front, root ) ) {
00286 if( rest[0] == '\0' ) {
00287 inst = root;
00288 } else {
00289 child = root->child_head;
00290 while( (child != NULL) && ((inst = instance_find_scope( child, rest, rm_unnamed )) == NULL) ) {
00291 child = child->next;
00292 }
00293 }
00294 }
00295
00296 PROFILE_END;
00297
00298 return( inst );
00299
00300 }
|
|
||||||||||||||||
|
Returns signal that matches the given exclusion ID.
00408 { PROFILE(INSTANCE_FIND_SIGNAL_BY_EXCLUSION_ID);
00409
00410 vsignal* sig = NULL; /* Pointer to found signal */
00411
00412 if( root != NULL ) {
00413
00414 if( (root->funit != NULL) &&
00415 (root->funit->sig_head != NULL) &&
00416 (root->funit->sig_head->sig->id <= id) &&
00417 (root->funit->sig_tail->sig->id >= id) ) {
00418
00419 sig_link* sigl = root->funit->sig_head;
00420
00421 while( (sigl != NULL) && (sigl->sig->id != id) ) {
00422 sigl = sigl->next;
00423 }
00424 assert( sigl->sig != NULL );
00425 sig = sigl->sig;
00426 *found_funit = root->funit;
00427
00428 } else {
00429
00430 funit_inst* child = root->child_head;
00431 while( (child != NULL) && ((sig = instance_find_signal_by_exclusion_id( child, id, found_funit )) == NULL) ) {
00432 child = child->next;
00433 }
00434
00435 }
00436
00437 }
00438
00439 PROFILE_END;
00440
00441 return( sig );
00442
00443 }
|
|
||||||||||||||||
|
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.
00182 { PROFILE(INSTANCE_GEN_SCOPE);
00183
00184 if( leaf != NULL ) {
00185
00186 /* Call parent instance first */
00187 instance_gen_scope( scope, leaf->parent, flatten );
00188
00189 if( !flatten || !db_is_unnamed_scope( leaf->name ) ) {
00190 if( scope[0] != '\0' ) {
00191 strcat( scope, "." );
00192 strcat( scope, leaf->name );
00193 } else {
00194 strcpy( scope, leaf->name );
00195 }
00196 }
00197
00198 }
00199
00200 PROFILE_END;
00201
00202 }
|
|
||||||||||||||||
|
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.
00998 { PROFILE(INSTANCE_GET_LEADING_HIERARCHY);
00999
01000 if( leading_hierarchy != NULL ) {
01001 strcat( leading_hierarchy, root->name );
01002 }
01003
01004 *top_inst = root;
01005
01006 if( root->funit == NULL ) {
01007
01008 do {
01009 root = root->child_head;
01010 if( leading_hierarchy != NULL ) {
01011 strcat( leading_hierarchy, "." );
01012 strcat( leading_hierarchy, root->name );
01013 }
01014 *top_inst = root;
01015 } while( (root != NULL) && (root->funit == NULL) );
01016
01017 }
01018
01019 PROFILE_END;
01020
01021 }
|
|
||||||||||||
|
Iterates up the scope for both functional unit
01029 { PROFILE(INSTANCE_MARK_LHIER_DIFFS);
01030
01031 /* Move up the scope hierarchy looking for a difference in instance names */
01032 while( (root1 != NULL) && (root2 != NULL) && (strcmp( root1->name, root2->name ) == 0) ) {
01033 root1 = root1->parent;
01034 root2 = root2->parent;
01035 }
01036
01037 /*
01038 Iterate up root1 instance, setting the name_diff variable to TRUE to specify that the instance name is really
01039 not accurate since its child tree with a child tree with a differen parent scope.
01040 */
01041 while( root1 != NULL ) {
01042 root1->suppl.name_diff = TRUE;
01043 root1 = root1->parent;
01044 }
01045
01046 PROFILE_END;
01047
01048 }
|
|
||||||||||||
|
00923 { PROFILE(INSTANCE_MERGE);
00924
00925 funit_inst* child2;
00926 funit_inst* last2 = NULL;
00927 bool retval = TRUE;
00928
00929 /* Perform functional unit merging */
00930 if( root1->funit != NULL ) {
00931 if( root2->funit != NULL ) {
00932 if( strcmp( root1->funit->name, root2->funit->name ) == 0 ) {
00933 funit_merge( root1->funit, root2->funit );
00934 } else {
00935 retval = FALSE;
00936 }
00937 }
00938 } else if( root2->funit != NULL ) {
00939 root1->funit = root2->funit;
00940 root2->funit = NULL;
00941 }
00942
00943 /* Recursively merge the child instances */
00944 child2 = root2->child_head;
00945 while( (child2 != NULL) && retval ) {
00946 funit_inst* child1 = root1->child_head;
00947 while( (child1 != NULL) && (strcmp( child1->name, child2->name ) != 0) ) {
00948 child1 = child1->next;
00949 }
00950 if( child1 != NULL ) {
00951 retval = instance_merge_tree( child1, child2 );
00952 last2 = child2;
00953 child2 = child2->next;
00954 } else {
00955 funit_inst* tmp = child2->next;
00956 child2->next = NULL;
00957 child2->parent = root1;
00958 if( root1->child_head == NULL ) {
00959 root1->child_head = child2;
00960 root1->child_tail = child2;
00961 } else {
00962 root1->child_tail->next = child2;
00963 root1->child_tail = child2;
00964 }
00965 if( last2 == NULL ) {
00966 root2->child_head = tmp;
00967 if( tmp == NULL ) {
00968 root2->child_tail = NULL;
00969 }
00970 } else if( tmp == NULL ) {
00971 root2->child_tail = last2;
00972 last2->next = NULL;
00973 } else {
00974 last2->next = tmp;
00975 }
00976 child2 = tmp;
00977 }
00978 }
00979
00980 PROFILE_END;
00981
00982 return( retval );
00983
00984 }
|
|
||||||||||||
|
Performs complex instance tree merging for two instance trees.
01059 { PROFILE(INSTANCE_MERGE_TWO_TREES);
01060
01061 bool retval = TRUE;
01062 char lhier1[4096];
01063 char lhier2[4096];
01064 funit_inst* tinst1 = NULL;
01065 funit_inst* tinst2 = NULL;
01066
01067 lhier1[0] = '\0';
01068 lhier2[0] = '\0';
01069
01070 /* Get leading hierarchy information */
01071 instance_get_leading_hierarchy( root1, lhier1, &tinst1 );
01072 instance_get_leading_hierarchy( root2, lhier2, &tinst2 );
01073
01074 /* If the top-level modules are the same, just merge them */
01075 if( (tinst1->funit != NULL) && (tinst2->funit != NULL) && (strcmp( tinst1->funit->name, tinst2->funit->name ) == 0) ) {
01076
01077 if( strcmp( lhier1, lhier2 ) == 0 ) {
01078
01079 bool rv = instance_merge_tree( tinst1, tinst2 );
01080 assert( rv );
01081
01082 } else if( strcmp( root1->name, root2->name ) == 0 ) {
01083
01084 bool rv = instance_merge_tree( root1, root2 );
01085 assert( rv );
01086
01087 } else {
01088
01089 bool rv = instance_merge_tree( tinst1, tinst2 );
01090 assert( rv );
01091 instance_mark_lhier_diffs( tinst1, tinst2 );
01092
01093 }
01094
01095 /* If the two trees share the same root name, merge them */
01096 } else if( (strcmp( root1->name, root2->name ) == 0) && instance_merge_tree( root1, root2 ) ) {
01097
01098 /* We've already merged so we don't have anything else to do */
01099
01100 /* Check to see if the module pointed to by tinst1 exists within the tree of tinst2 */
01101 } else if( (root2 = instance_find_by_funit_name_if_one( tinst2, tinst1->funit->name )) != NULL ) {
01102
01103 bool rv = instance_merge_tree( tinst1, root2 );
01104 assert( rv );
01105 instance_mark_lhier_diffs( tinst1, root2 );
01106
01107 /* Check to see if the module pointed to by tinst2 exists within the tree of tinst1 */
01108 } else if( (root1 = instance_find_by_funit_name_if_one( tinst1, tinst2->funit->name )) != NULL ) {
01109
01110 bool rv = instance_merge_tree( root1, tinst2 );
01111 assert( rv );
01112 instance_mark_lhier_diffs( root1, tinst2 );
01113
01114 /* Otherwise, we cannot merge the two CDD files so don't */
01115 } else {
01116
01117 retval = FALSE;
01118
01119 }
01120
01121 PROFILE_END;
01122
01123 return( retval );
01124
01125 }
|
|
|
Reads in and merges an instance-only line from the database. Merges instance-only constructs from two CDD files.
01290 { PROFILE(INSTANCE_ONLY_DB_MERGE);
01291
01292 char scope[4096];
01293 int chars_read;
01294 bool name_diff;
01295
01296 if( sscanf( *line, "%s %d%n", scope, &name_diff, &chars_read ) == 2 ) {
01297
01298 char* back = strdup_safe( scope );
01299 char* rest = strdup_safe( scope );
01300 funit_inst* child;
01301
01302 *line += chars_read;
01303
01304 scope_extract_back( scope, back, rest );
01305
01306 /* Create "placeholder" instance */
01307 child = instance_create( NULL, back, name_diff, FALSE, FALSE, NULL );
01308
01309 /* If we are the top-most instance, just add ourselves to the instance link list */
01310 if( rest[0] == '\0' ) {
01311
01312 /* Add a new instance link if was not able to be found in the instance linked list */
01313 if( inst_link_find_by_scope( scope, db_list[curr_db]->inst_head ) == NULL ) {
01314 (void)inst_link_add( child, &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
01315 }
01316
01317 /* Otherwise, find our parent instance and attach the new instance to it */
01318 } else {
01319 funit_inst* parent;
01320 if( (parent = inst_link_find_by_scope( rest, db_list[curr_db]->inst_head )) != NULL ) {
01321 if( parent->child_head == NULL ) {
01322 parent->child_head = parent->child_tail = child;
01323 } else {
01324 parent->child_tail->next = child;
01325 parent->child_tail = child;
01326 }
01327 child->parent = parent;
01328 } else {
01329 print_output( "Unable to find parent instance of instance-only line in database file.", FATAL, __FILE__, __LINE__ );
01330 Throw 0;
01331 }
01332 }
01333
01334 /* Deallocate memory */
01335 free_safe( back, (strlen( scope ) + 1) );
01336 free_safe( rest, (strlen( scope ) + 1) );
01337
01338 } else {
01339
01340 print_output( "Unable to merge instance-only line in database file.", FATAL, __FILE__, __LINE__ );
01341 Throw 0;
01342
01343 }
01344
01345 PROFILE_END;
01346
01347 }
|
|
|
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.
01230 { PROFILE(INSTANCE_ONLY_DB_READ);
01231
01232 char scope[4096];
01233 int chars_read;
01234 bool name_diff;
01235
01236 if( sscanf( *line, "%s %d%n", scope, &name_diff, &chars_read ) == 2 ) {
01237
01238 char* back = strdup_safe( scope );
01239 char* rest = strdup_safe( scope );
01240 funit_inst* child;
01241
01242 *line += chars_read;
01243
01244 scope_extract_back( scope, back, rest );
01245
01246 /* Create "placeholder" instance */
01247 child = instance_create( NULL, back, name_diff, FALSE, FALSE, NULL );
01248
01249 /* If we are the top-most instance, just add ourselves to the instance link list */
01250 if( rest[0] == '\0' ) {
01251 (void)inst_link_add( child, &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
01252
01253 /* Otherwise, find our parent instance and attach the new instance to it */
01254 } else {
01255 funit_inst* parent;
01256 if( (parent = inst_link_find_by_scope( rest, db_list[curr_db]->inst_tail )) != NULL ) {
01257 if( parent->child_head == NULL ) {
01258 parent->child_head = parent->child_tail = child;
01259 } else {
01260 parent->child_tail->next = child;
01261 parent->child_tail = child;
01262 }
01263 child->parent = parent;
01264 } else {
01265 print_output( "Unable to find parent instance of instance-only line in database file.", FATAL, __FILE__, __LINE__ );
01266 Throw 0;
01267 }
01268 }
01269
01270 /* Deallocate memory */
01271 free_safe( back, (strlen( scope ) + 1) );
01272 free_safe( rest, (strlen( scope ) + 1) );
01273
01274 } else {
01275
01276 print_output( "Unable to read instance-only line in database file.", FATAL, __FILE__, __LINE__ );
01277 Throw 0;
01278
01279 }
01280
01281 PROFILE_END;
01282
01283 }
|
|
||||||||||||
|
Outputs dumpvars to the given file for the given instance. Outputs dumpvars to the specified file.
01477 { PROFILE(INSTANCE_OUTPUT_DUMPVARS);
01478
01479 funit_inst* child = root->child_head;
01480 char scope[4096];
01481
01482 /* Generate instance scope */
01483 scope[0] = '\0';
01484 instance_gen_scope( scope, root, FALSE );
01485
01486 /* Outputs dumpvars for the given functional unit */
01487 funit_output_dumpvars( vfile, root->funit, scope );
01488
01489 /* Outputs all children instances */
01490 while( child != NULL ) {
01491 instance_output_dumpvars( vfile, child );
01492 child = child->next;
01493 }
01494
01495 PROFILE_END;
01496
01497 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
Adds new instance to specified instance tree during parse.
00685 { PROFILE(INSTANCE_PARSE_ADD);
00686
00687 bool retval = TRUE; /* Return value for this function */
00688 funit_inst* inst; /* Temporary pointer to functional unit instance to add to */
00689 funit_inst* cinst; /* Pointer to instance of child functional unit */
00690 int i; /* Loop iterator */
00691 int ignore; /* Number of matched instances to ignore */
00692
00693 if( *root == NULL ) {
00694
00695 *root = instance_create( child, inst_name, FALSE, ignore_child, gend_scope, range );
00696
00697 } else {
00698
00699 assert( parent != NULL );
00700
00701 i = 0;
00702 ignore = 0;
00703
00704 /*
00705 Check to see if the child functional unit has already been parsed and, if so, find
00706 one of its instances for copying the instance tree below it.
00707 */
00708 cinst = instance_find_by_funit( *root, child, &ignore);
00709
00710 /* Filename will be set to a value if the functional unit has been parsed */
00711 if( (cinst != NULL) && (cinst->funit->filename != NULL) ) {
00712
00713 ignore = 0;
00714 while( (ignore >= 0) && ((inst = instance_find_by_funit( *root, parent, &ignore )) != NULL) ) {
00715 (void)instance_copy( cinst, inst, inst_name, range, resolve );
00716 i++;
00717 ignore = child_gend ? -1 : i;
00718 }
00719
00720 } else {
00721
00722 ignore = 0;
00723 while( (ignore >= 0) && ((inst = instance_find_by_funit( *root, parent, &ignore )) != NULL) ) {
00724 cinst = instance_add_child( inst, child, inst_name, range, resolve, ignore_child, gend_scope );
00725 i++;
00726 ignore = (child_gend && (cinst != NULL)) ? -1 : i;
00727 }
00728
00729 }
00730
00731 /* Everything went well with the add if we found at least one parent instance */
00732 retval = (i > 0);
00733
00734 }
00735
00736 PROFILE_END;
00737
00738 return( retval );
00739
00740 }
|
|
||||||||||||||||||||
|
Adds new instance to specified instance tree during CDD read.
00870 { PROFILE(INSTANCE_READ_ADD);
00871
00872 bool retval = TRUE; /* Return value for this function */
00873 funit_inst* inst; /* Temporary pointer to functional unit instance to add to */
00874 funit_inst* new_inst; /* Pointer to new functional unit instance to add */
00875
00876 if( *root == NULL ) {
00877
00878 *root = instance_create( child, inst_name, FALSE, FALSE, FALSE, NULL );
00879
00880 } else {
00881
00882 assert( parent != NULL );
00883
00884 if( (inst = instance_find_scope( *root, parent, TRUE )) != NULL ) {
00885
00886 /* Create new instance */
00887 new_inst = instance_create( child, inst_name, FALSE, FALSE, FALSE, NULL );
00888
00889 if( inst->child_head == NULL ) {
00890 inst->child_head = new_inst;
00891 inst->child_tail = new_inst;
00892 } else {
00893 inst->child_tail->next = new_inst;
00894 inst->child_tail = new_inst;
00895 }
00896
00897 /* Set parent pointer of new instance */
00898 new_inst->parent = inst;
00899
00900 } else {
00901
00902 /* Unable to find parent of this child, needs to be added to a different instance tree */
00903 retval = FALSE;
00904
00905 }
00906
00907 }
00908
00909 PROFILE_END;
00910
00911 return( retval );
00912
00913 }
|
|
||||||||||||
|
Removes expressions from instance parameters within the given instance that match the given expression. Recursively traverses the given instance tree, removing the given statement.
01395 { PROFILE(INSTANCE_REMOVE_PARMS_WITH_EXPR);
01396
01397 funit_inst* curr_child; /* Pointer to current child instance to traverse */
01398 inst_parm* iparm; /* Pointer to current instance parameter */
01399 exp_link* expl; /* Pointer to current expression link */
01400 exp_link* texpl; /* Temporary pointer to current expression link */
01401
01402 /* Search for the given expression within the given instance parameter */
01403 iparm = root->param_head;
01404 while( iparm != NULL ) {
01405 if( iparm->sig != NULL ) {
01406 expl = iparm->sig->exp_head;
01407 while( expl != NULL ) {
01408 texpl = expl;
01409 expl = expl->next;
01410 if( expression_find_expr( stmt->exp, texpl->exp ) ) {
01411 if( iparm->mparm != NULL ) {
01412 exp_link_remove( texpl->exp, &(iparm->mparm->exp_head), &(iparm->mparm->exp_tail), FALSE );
01413 }
01414 exp_link_remove( texpl->exp, &(iparm->sig->exp_head), &(iparm->sig->exp_tail), FALSE );
01415 }
01416 }
01417 }
01418 iparm = iparm->next;
01419 }
01420
01421 /* Traverse children */
01422 curr_child = root->child_head;
01423 while( curr_child != NULL ) {
01424 instance_remove_parms_with_expr( curr_child, stmt );
01425 curr_child = curr_child->next;
01426 }
01427
01428 PROFILE_END;
01429
01430 }
|
|
||||||||||||
|
Removes all statement blocks that contain expressions that call the given statement. Removes all statement blocks in the design that call that specified statement.
01355 { PROFILE(INSTANCE_REMOVE_STMT_BLKS_CALLING_STMT);
01356
01357 funit_inst* curr_child; /* Pointer to current child instance to parse */
01358 #ifndef VPI_ONLY
01359 gitem_link* gil; /* Pointer to current generate item link */
01360 #endif
01361
01362 if( root != NULL ) {
01363
01364 /* First, handle the current functional unit */
01365 funit_remove_stmt_blks_calling_stmt( root->funit, stmt );
01366
01367 #ifndef VPI_ONLY
01368 /* Second, handle all generate items in this instance */
01369 gil = root->gitem_head;
01370 while( gil != NULL ) {
01371 gen_item_remove_if_contains_expr_calling_stmt( gil->gi, stmt );
01372 gil = gil->next;
01373 }
01374 #endif
01375
01376 /* Parse children */
01377 curr_child = root->child_head;
01378 while( curr_child != NULL ) {
01379 instance_remove_stmt_blks_calling_stmt( curr_child, stmt );
01380 curr_child = curr_child->next;
01381 }
01382
01383 }
01384
01385 PROFILE_END;
01386
01387 }
|
|
|
Resolves all instance arrays. Recursively iterates through entire instance tree, resolving any instance arrays that are found.
00847 { PROFILE(INSTANCE_RESOLVE);
00848
00849 /* Resolve all instance names */
00850 instance_resolve_helper( root, root );
00851
00852 PROFILE_END;
00853
00854 }
|
|
||||||||||||
|
Recursively iterates through the entire instance tree
00820 { PROFILE(INSTANCE_RESOLVE_HELPER);
00821
00822 funit_inst* curr_child; /* Pointer to current child */
00823
00824 if( curr != NULL ) {
00825
00826 /* Resolve all children first */
00827 curr_child = curr->child_head;
00828 while( curr_child != NULL ) {
00829 instance_resolve_helper( root, curr_child );
00830 curr_child = curr_child->next;
00831 }
00832
00833 /* Now resolve this instance */
00834 (void)instance_resolve_inst( root, curr );
00835
00836 }
00837
00838 PROFILE_END;
00839
00840 }
|
|
||||||||||||
|
00752 { PROFILE(INSTANCE_RESOLVE_INST);
00753
00754 unsigned int width = 0; /* Width of the instance range */
00755 int lsb; /* LSB of the instance range */
00756 int big_endian; /* Unused */
00757 char* name_copy; /* Copy of the instance name being resolved */
00758 char* new_name; /* New hierarchical name of the instance(s) being resolved */
00759 unsigned int i; /* Loop iterator */
00760
00761 assert( curr != NULL );
00762
00763 if( curr->range != NULL ) {
00764
00765 unsigned int rv;
00766 unsigned int slen;
00767
00768 /* Get LSB and width information */
00769 static_expr_calc_lsb_and_width_post( curr->range->left, curr->range->right, &width, &lsb, &big_endian );
00770 assert( width != 0 );
00771 assert( lsb != -1 );
00772
00773 /* Remove the range information from this instance */
00774 static_expr_dealloc( curr->range->left, FALSE );
00775 static_expr_dealloc( curr->range->right, FALSE );
00776 free_safe( curr->range, sizeof( vector_width ) );
00777 curr->range = NULL;
00778
00779 /* Copy and deallocate instance name */
00780 name_copy = strdup_safe( curr->name );
00781 free_safe( curr->name, (strlen( curr->name ) + 1) );
00782
00783 /* For the first instance, just modify the name */
00784 slen = strlen( name_copy ) + 23;
00785 new_name = (char*)malloc_safe( slen );
00786 rv = snprintf( new_name, slen, "%s[%d]", name_copy, lsb );
00787 assert( rv < slen );
00788 curr->name = strdup_safe( new_name );
00789
00790 /* For all of the rest of the instances, do the instance_parse_add function call */
00791 for( i=1; i<width; i++ ) {
00792
00793 /* Create the new name */
00794 rv = snprintf( new_name, slen, "%s[%d]", name_copy, (lsb + i) );
00795 assert( rv < slen );
00796
00797 /* Add the instance */
00798 (void)instance_parse_add( &root, ((curr->parent == NULL) ? NULL : curr->parent->funit), curr->funit, new_name, NULL, TRUE, FALSE, FALSE, FALSE );
00799
00800 }
00801
00802 /* Deallocate the new_name and name_copy pointers */
00803 free_safe( name_copy, (strlen( name_copy ) + 1) );
00804 free_safe( new_name, slen );
00805
00806 }
00807
00808 PROFILE_END;
00809
00810 return( width != 0 );
00811
00812 }
|
|
|
Index of current database in db_list array that is being handled. |
|
|
This static value contains the current expression ID number to use for the next expression found, it is incremented by one when an expression is found. This allows us to have a unique expression ID for each expression (since expressions have no intrinsic names). |
|
|
Signal ID that is used for identification purposes (each signal will receive a unique ID). |
|
|
Array of database pointers storing all currently loaded databases. |
|
|
Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it. |
1.3.4