#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 | |
static bool | instance_resolve_inst (funit_inst *, funit_inst *) |
static void | instance_dealloc_single (funit_inst *) |
static 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. | |
static 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. | |
static void | instance_find_by_funit_name (funit_inst *root, const char *funit_name, funit_inst **match_inst, unsigned int *matches) |
static 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. | |
static funit_inst * | instance_add_child (funit_inst *inst, func_unit *child, char *name, vector_width *range, bool resolve, bool ignore_child, bool gend_scope) |
static 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. | |
static 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. | |
static 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. | |
static 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) |
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] |
bool | debug_mode |
int | curr_sig_id = 1 |
static funit_inst* instance_add_child | ( | funit_inst * | inst, | |
func_unit * | child, | |||
char * | name, | |||
vector_width * | range, | |||
bool | resolve, | |||
bool | ignore_child, | |||
bool | gend_scope | |||
) | [static] |
Generates new instance, adds it to the child list of the inst functional unit instance, and resolves any parameters.
inst | Pointer to instance to add child instance to | |
child | Pointer to child functional unit to create instance for | |
name | Name of instance to add | |
range | For arrays of instances, contains the range of the instance array | |
resolve | Set to TRUE if newly added instance should be immediately resolved | |
ignore_child | Set to TRUE if the child to be added should not be written to a CDD file | |
gend_scope | Set to TRUE if the child scope is a generated scope |
References funit_inst_s::child_head, funit_inst_s::child_tail, curr_db, FALSE, funit_inst_s::funit, funit_inst_s::ignore, inst_link_s::inst, db_s::inst_head, instance_create(), instance_resolve_inst(), funit_inst_s::name, inst_link_s::next, funit_inst_s::next, funit_inst_s::parent, PROFILE, PROFILE_END, and funit_inst_s::suppl.
Referenced by instance_copy_helper(), and instance_parse_add().
00556 { PROFILE(INSTANCE_ADD_CHILD); 00557 00558 funit_inst* new_inst; /* Pointer to newly created instance to add */ 00559 00560 /* Check to see if this instance already exists */ 00561 new_inst = inst->child_head; 00562 while( (new_inst != NULL) && ((strcmp( new_inst->name, name ) != 0) || (new_inst->funit != child)) ) { 00563 new_inst = new_inst->next; 00564 } 00565 00566 /* If this instance already exists (unless the existing and new child is a placeholder), don't add it again */ 00567 if( (new_inst == NULL) || (new_inst->suppl.ignore && ignore_child) ) { 00568 00569 /* Generate new instance */ 00570 new_inst = instance_create( child, name, FALSE, ignore_child, gend_scope, range ); 00571 00572 /* Add new instance to inst child instance list */ 00573 if( inst->child_head == NULL ) { 00574 inst->child_head = new_inst; 00575 inst->child_tail = new_inst; 00576 } else { 00577 inst->child_tail->next = new_inst; 00578 inst->child_tail = new_inst; 00579 } 00580 00581 /* Point this instance's parent pointer to its parent */ 00582 new_inst->parent = inst; 00583 00584 // inst_link_display( db_list[curr_db]->inst_head ); 00585 00586 /* If the new instance needs to be resolved now, do so */ 00587 if( resolve ) { 00588 inst_link* instl = db_list[curr_db]->inst_head; 00589 while( (instl != NULL) && !instance_resolve_inst( instl->inst, new_inst ) ) { 00590 instl = instl->next; 00591 } 00592 } 00593 00594 } else { 00595 00596 /* Set the ignore value in the instance to FALSE */ 00597 new_inst->suppl.ignore = FALSE; 00598 00599 new_inst = NULL; 00600 00601 } 00602 00603 PROFILE_END; 00604 00605 return( new_inst ); 00606 00607 }
static bool instance_compare | ( | char * | inst_name, | |
const funit_inst * | inst | |||
) | [static] |
inst_name | Instance name to compare to this instance's name (may contain array information) | |
inst | Pointer to instance to compare name against |
References FALSE, vector_width_s::left, funit_inst_s::name, PROFILE, PROFILE_END, funit_inst_s::range, vector_width_s::right, scope_compare(), and static_expr_calc_lsb_and_width_post().
Referenced by instance_find_scope().
00218 { PROFILE(INSTANCE_COMPARE); 00219 00220 bool retval = FALSE; /* Return value of this function */ 00221 char bname[4096]; /* Base name of inst_name */ 00222 int index; /* Index of inst_name */ 00223 unsigned int width; /* Width of instance range */ 00224 int lsb; /* LSB of instance range */ 00225 int big_endian; /* Specifies endianness */ 00226 00227 /* If this instance has a range, handle it */ 00228 if( inst->range != NULL ) { 00229 00230 /* Extract the index portion of inst_name if there is one */ 00231 if( sscanf( inst_name, "%[a-zA-Z0-9_]\[%d]", bname, &index ) == 2 ) { 00232 00233 /* If the base names compare, check that the given index falls within this instance range */ 00234 if( scope_compare( bname, inst->name ) ) { 00235 00236 /* Get range information from instance */ 00237 static_expr_calc_lsb_and_width_post( inst->range->left, inst->range->right, &width, &lsb, &big_endian ); 00238 assert( width != 0 ); 00239 assert( lsb != -1 ); 00240 00241 retval = (index >= lsb) && (index < (lsb + (int)width)); 00242 00243 } 00244 00245 } 00246 00247 } else { 00248 00249 retval = scope_compare( inst_name, inst->name ); 00250 00251 } 00252 00253 PROFILE_END; 00254 00255 return( retval ); 00256 00257 }
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 }
static funit_inst* instance_copy_helper | ( | funit_inst * | from_inst, | |
funit_inst * | to_inst, | |||
char * | name, | |||
vector_width * | range, | |||
bool | resolve, | |||
bool | is_root | |||
) | [static] |
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 | |
is_root | Set to TRUE if the from_inst is the root instance |
References funit_inst_s::child_head, FALSE, funit_inst_s::funit, funit_inst_s::gend_scope, funit_inst_s::ignore, instance_add_child(), funit_inst_s::name, funit_inst_s::next, PROFILE, PROFILE_END, funit_inst_s::range, and funit_inst_s::suppl.
Referenced by instance_copy().
00620 { PROFILE(INSTANCE_COPY_HELPER); 00621 00622 funit_inst* curr; /* Pointer to current functional unit instance to copy */ 00623 funit_inst* new_inst; /* Pointer to newly created functional unit instance */ 00624 00625 assert( from_inst != NULL ); 00626 assert( to_inst != NULL ); 00627 assert( name != NULL ); 00628 00629 /* Add new child instance */ 00630 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 ); 00631 00632 /* Do not add children if no child instance was created */ 00633 if( new_inst != NULL ) { 00634 00635 /* Iterate through rest of current child's list of children */ 00636 curr = from_inst->child_head; 00637 while( curr != NULL ) { 00638 (void)instance_copy_helper( curr, new_inst, curr->name, curr->range, resolve, FALSE ); 00639 curr = curr->next; 00640 } 00641 00642 } 00643 00644 PROFILE_END; 00645 00646 return( new_inst ); 00647 00648 }
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_single | ( | funit_inst * | inst | ) | [static] |
Deallocates all memory allocated for the given instance.
inst | Pointer to instance to deallocate memory for |
References FALSE, free_safe, funit_inst_s::gitem_head, gitem_link_delete_list(), inst_parm_dealloc(), vector_width_s::left, funit_inst_s::name, funit_inst_s::param_head, PROFILE, PROFILE_END, funit_inst_s::range, vector_width_s::right, funit_inst_s::stat, static_expr_dealloc(), and TRUE.
Referenced by instance_dealloc_tree().
01471 { PROFILE(INSTANCE_DEALLOC_SINGLE); 01472 01473 if( inst != NULL ) { 01474 01475 /* Free up memory allocated for name */ 01476 free_safe( inst->name, (strlen( inst->name ) + 1) ); 01477 01478 /* Free up memory allocated for statistic, if necessary */ 01479 free_safe( inst->stat, sizeof( statistic ) ); 01480 01481 /* Free up memory for range, if necessary */ 01482 if( inst->range != NULL ) { 01483 static_expr_dealloc( inst->range->left, FALSE ); 01484 static_expr_dealloc( inst->range->right, FALSE ); 01485 free_safe( inst->range, sizeof( vector_width ) ); 01486 } 01487 01488 /* Deallocate memory for instance parameter list */ 01489 inst_parm_dealloc( inst->param_head, TRUE ); 01490 01491 #ifndef VPI_ONLY 01492 /* Deallocate memory for generate item list */ 01493 gitem_link_delete_list( inst->gitem_head, FALSE ); 01494 #endif 01495 01496 /* Free up memory for this functional unit instance */ 01497 free_safe( inst, sizeof( funit_inst ) ); 01498 01499 } 01500 01501 PROFILE_END; 01502 01503 }
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 }
static void instance_display_tree_helper | ( | funit_inst * | root, | |
char * | prefix | |||
) | [static] |
Helper function for the instance_display_tree function.
root | Pointer to functional unit instance to display | |
prefix | Prefix string to be used when outputting (used to indent children) |
References funit_inst_s::child_head, free_safe, funit_inst_s::funit, funit_inst_s::gend_scope, funit_inst_s::ignore, func_unit_s::name, funit_inst_s::name, funit_inst_s::next, PROFILE, PROFILE_END, scope_gen_printable(), and funit_inst_s::suppl.
Referenced by instance_display_tree().
00069 { PROFILE(INSTANCE_DISPLAY_TREE_HELPER); 00070 00071 char sp[4096]; /* Contains prefix for children */ 00072 funit_inst* curr; /* Pointer to current child instance */ 00073 unsigned int rv; /* Return value from snprintf calls */ 00074 00075 assert( root != NULL ); 00076 00077 /* Get printable version of this instance and functional unit name */ 00078 if( root->funit != NULL ) { 00079 char* piname = scope_gen_printable( root->name ); 00080 char* pfname = scope_gen_printable( root->funit->name ); 00081 /*@-formatcode@*/ 00082 printf( "%s%s (%s) - %p (ign: %hhu, gend: %hhu)\n", prefix, piname, pfname, root, root->suppl.ignore, root->suppl.gend_scope ); 00083 /*@=formatcode@*/ 00084 free_safe( piname, (strlen( piname ) + 1) ); 00085 free_safe( pfname, (strlen( pfname ) + 1) ); 00086 } else { 00087 char* piname = scope_gen_printable( root->name ); 00088 /*@-formatcode@*/ 00089 printf( "%s%s () - %p (ign: %hhu, gend: %hhu)\n", prefix, piname, root, root->suppl.ignore, root->suppl.gend_scope ); 00090 /*@=formatcode@*/ 00091 free_safe( piname, (strlen( piname ) + 1) ); 00092 } 00093 00094 /* Calculate prefix */ 00095 rv = snprintf( sp, 4096, "%s ", prefix ); 00096 assert( rv < 4096 ); 00097 00098 /* Display our children */ 00099 curr = root->child_head; 00100 while( curr != NULL ) { 00101 instance_display_tree_helper( curr, sp ); 00102 curr = curr->next; 00103 } 00104 00105 00106 PROFILE_END; 00107 00108 }
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 }
static void instance_find_by_funit_name | ( | funit_inst * | root, | |
const char * | funit_name, | |||
funit_inst ** | match_inst, | |||
unsigned int * | matches | |||
) | [static] |
Recursively searches the given instance tree, setting match_inst and matches if a matched functional unit name was found.
root | Pointer to root functional unit instance to search | |
funit_name | Name of module to find | |
match_inst | Pointer to matched functional unit instance | |
matches | Specifies the number of matched modules |
References funit_inst_s::child_head, funit_inst_s::funit, func_unit_s::name, funit_inst_s::next, PROFILE, and PROFILE_END.
Referenced by instance_find_by_funit_name_if_one().
00361 { PROFILE(INSTANCE_FIND_BY_FUNIT_NAME_IF_ONE_HELPER); 00362 00363 if( root != NULL ) { 00364 00365 funit_inst* child; 00366 00367 if( strcmp( root->funit->name, funit_name ) == 0 ) { 00368 (*matches)++; 00369 *match_inst = root; 00370 } 00371 00372 child = root->child_head; 00373 while( child != NULL ) { 00374 instance_find_by_funit_name( child, funit_name, match_inst, matches ); 00375 child = child->next; 00376 } 00377 00378 } 00379 00380 PROFILE_END; 00381 00382 }
static funit_inst* instance_find_by_funit_name_if_one | ( | funit_inst * | root, | |
const char * | funit_name | |||
) | [static] |
root | Pointer to root functional unit instance to search | |
funit_name | Name of module to find |
References instance_find_by_funit_name(), PROFILE, and PROFILE_END.
Referenced by instance_merge_two_trees().
00390 { PROFILE(INSTANCE_FIND_BY_FUNIT_NAME_IF_ONE); 00391 00392 funit_inst* match_inst = NULL; 00393 unsigned int matches = 0; 00394 00395 instance_find_by_funit_name( root, funit_name, &match_inst, &matches ); 00396 00397 PROFILE_END; 00398 00399 return( (matches == 1) ? match_inst : NULL ); 00400 00401 }
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 }
static void instance_mark_lhier_diffs | ( | funit_inst * | root1, | |
funit_inst * | root2 | |||
) | [static] |
Iterates up the scope for both functional unit
References funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::parent, PROFILE, PROFILE_END, funit_inst_s::suppl, and TRUE.
Referenced by instance_merge_two_trees().
01062 { PROFILE(INSTANCE_MARK_LHIER_DIFFS); 01063 01064 /* Move up the scope hierarchy looking for a difference in instance names */ 01065 while( (root1 != NULL) && (root2 != NULL) && (strcmp( root1->name, root2->name ) == 0) ) { 01066 root1 = root1->parent; 01067 root2 = root2->parent; 01068 } 01069 01070 /* 01071 Iterate up root1 instance, setting the name_diff variable to TRUE to specify that the instance name is really 01072 not accurate since its child tree with a child tree with a differen parent scope. 01073 */ 01074 while( root1 != NULL ) { 01075 root1->suppl.name_diff = TRUE; 01076 root1 = root1->parent; 01077 } 01078 01079 PROFILE_END; 01080 01081 }
static bool instance_merge_tree | ( | funit_inst * | root1, | |
funit_inst * | root2 | |||
) | [static] |
Merges to instance trees that have the same instance root.
root1 | Pointer to root of first instance tree to merge | |
root2 | Pointer to root of second instance tree to merge |
References funit_inst_s::child_head, funit_inst_s::child_tail, FALSE, funit_inst_s::funit, funit_merge(), funit_inst_s::name, func_unit_s::name, funit_inst_s::next, funit_inst_s::parent, PROFILE, PROFILE_END, and TRUE.
Referenced by instance_merge_two_trees().
00956 { PROFILE(INSTANCE_MERGE); 00957 00958 funit_inst* child2; 00959 funit_inst* last2 = NULL; 00960 bool retval = TRUE; 00961 00962 /* Perform functional unit merging */ 00963 if( root1->funit != NULL ) { 00964 if( root2->funit != NULL ) { 00965 if( strcmp( root1->funit->name, root2->funit->name ) == 0 ) { 00966 funit_merge( root1->funit, root2->funit ); 00967 } else { 00968 retval = FALSE; 00969 } 00970 } 00971 } else if( root2->funit != NULL ) { 00972 root1->funit = root2->funit; 00973 root2->funit = NULL; 00974 } 00975 00976 /* Recursively merge the child instances */ 00977 child2 = root2->child_head; 00978 while( (child2 != NULL) && retval ) { 00979 funit_inst* child1 = root1->child_head; 00980 while( (child1 != NULL) && (strcmp( child1->name, child2->name ) != 0) ) { 00981 child1 = child1->next; 00982 } 00983 if( child1 != NULL ) { 00984 retval = instance_merge_tree( child1, child2 ); 00985 last2 = child2; 00986 child2 = child2->next; 00987 } else { 00988 funit_inst* tmp = child2->next; 00989 child2->next = NULL; 00990 child2->parent = root1; 00991 if( root1->child_head == NULL ) { 00992 root1->child_head = child2; 00993 root1->child_tail = child2; 00994 } else { 00995 root1->child_tail->next = child2; 00996 root1->child_tail = child2; 00997 } 00998 if( last2 == NULL ) { 00999 root2->child_head = tmp; 01000 if( tmp == NULL ) { 01001 root2->child_tail = NULL; 01002 } 01003 } else if( tmp == NULL ) { 01004 root2->child_tail = last2; 01005 last2->next = NULL; 01006 } else { 01007 last2->next = tmp; 01008 } 01009 child2 = tmp; 01010 } 01011 } 01012 01013 PROFILE_END; 01014 01015 return( retval ); 01016 01017 }
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 }
static void instance_resolve_helper | ( | funit_inst * | root, | |
funit_inst * | curr | |||
) | [static] |
Recursively iterates through the entire instance tree
root | Pointer to root of instance tree | |
curr | Pointer to current instance |
References funit_inst_s::child_head, DEBUG, debug_mode, generate_resolve_inst(), instance_resolve_inst(), funit_inst_s::name, funit_inst_s::next, param_resolve_inst(), print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by instance_resolve().
00826 { PROFILE(INSTANCE_RESOLVE_HELPER); 00827 00828 funit_inst* curr_child; /* Pointer to current child */ 00829 00830 if( curr != NULL ) { 00831 00832 /* Resolve parameters */ 00833 #ifdef DEBUG_MODE 00834 if( debug_mode ) { 00835 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Resolving parameters for instance %s...", curr->name ); 00836 assert( rv < USER_MSG_LENGTH ); 00837 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00838 } 00839 #endif 00840 param_resolve_inst( curr ); 00841 00842 /* Resolve generate blocks */ 00843 #ifdef DEBUG_MODE 00844 if( debug_mode ) { 00845 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Resolving generate statements for instance %s...", curr->name ); 00846 assert( rv < USER_MSG_LENGTH ); 00847 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00848 } 00849 #endif 00850 generate_resolve_inst( curr ); 00851 00852 /* Resolve children */ 00853 curr_child = curr->child_head; 00854 while( curr_child != NULL ) { 00855 instance_resolve_helper( root, curr_child ); 00856 curr_child = curr_child->next; 00857 } 00858 00859 /* Now resolve this instance's arrays */ 00860 #ifdef DEBUG_MODE 00861 if( debug_mode ) { 00862 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Resolving instance arrays for instance %s...", curr->name ); 00863 assert( rv < USER_MSG_LENGTH ); 00864 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00865 } 00866 #endif 00867 (void)instance_resolve_inst( root, curr ); 00868 00869 } 00870 00871 PROFILE_END; 00872 00873 }
bool instance_resolve_inst | ( | funit_inst * | root, | |
funit_inst * | curr | |||
) | [static] |
Checks the given instance to see if a range was specified in its instantiation. If a range was found, create all of the instances for this range and add them to the instance tree.
root | Pointer to root functional unit to traverse | |
curr | Pointer to current instance to resolve |
References FALSE, free_safe, funit_inst_s::funit, instance_parse_add(), vector_width_s::left, malloc_safe, funit_inst_s::name, funit_inst_s::parent, PROFILE, PROFILE_END, funit_inst_s::range, vector_width_s::right, static_expr_calc_lsb_and_width_post(), static_expr_dealloc(), strdup_safe, and TRUE.
Referenced by instance_add_child(), and instance_resolve_helper().
00758 { PROFILE(INSTANCE_RESOLVE_INST); 00759 00760 unsigned int width = 0; /* Width of the instance range */ 00761 int lsb; /* LSB of the instance range */ 00762 int big_endian; /* Unused */ 00763 char* name_copy; /* Copy of the instance name being resolved */ 00764 char* new_name; /* New hierarchical name of the instance(s) being resolved */ 00765 unsigned int i; /* Loop iterator */ 00766 00767 assert( curr != NULL ); 00768 00769 if( curr->range != NULL ) { 00770 00771 unsigned int rv; 00772 unsigned int slen; 00773 00774 /* Get LSB and width information */ 00775 static_expr_calc_lsb_and_width_post( curr->range->left, curr->range->right, &width, &lsb, &big_endian ); 00776 assert( width != 0 ); 00777 assert( lsb != -1 ); 00778 00779 /* Remove the range information from this instance */ 00780 static_expr_dealloc( curr->range->left, FALSE ); 00781 static_expr_dealloc( curr->range->right, FALSE ); 00782 free_safe( curr->range, sizeof( vector_width ) ); 00783 curr->range = NULL; 00784 00785 /* Copy and deallocate instance name */ 00786 name_copy = strdup_safe( curr->name ); 00787 free_safe( curr->name, (strlen( curr->name ) + 1) ); 00788 00789 /* For the first instance, just modify the name */ 00790 slen = strlen( name_copy ) + 23; 00791 new_name = (char*)malloc_safe( slen ); 00792 rv = snprintf( new_name, slen, "%s[%d]", name_copy, lsb ); 00793 assert( rv < slen ); 00794 curr->name = strdup_safe( new_name ); 00795 00796 /* For all of the rest of the instances, do the instance_parse_add function call */ 00797 for( i=1; i<width; i++ ) { 00798 00799 /* Create the new name */ 00800 rv = snprintf( new_name, slen, "%s[%d]", name_copy, (lsb + i) ); 00801 assert( rv < slen ); 00802 00803 /* Add the instance */ 00804 (void)instance_parse_add( &root, ((curr->parent == NULL) ? NULL : curr->parent->funit), curr->funit, new_name, NULL, TRUE, FALSE, FALSE, FALSE ); 00805 00806 } 00807 00808 /* Deallocate the new_name and name_copy pointers */ 00809 free_safe( name_copy, (strlen( name_copy ) + 1) ); 00810 free_safe( new_name, slen ); 00811 00812 } 00813 00814 PROFILE_END; 00815 00816 return( width != 0 ); 00817 00818 }
unsigned int curr_db |
Index of current database in db_list array that is being handled.
int curr_expr_id |
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).
int curr_sig_id = 1 |
Signal ID that is used for identification purposes (each signal will receive a unique ID).
Referenced by db_get_exclusion_id_size(), gen_item_assign_ids(), instance_db_write(), and param_db_write().
If set to TRUE, causes debug information to be spewed to screen.
char user_msg[USER_MSG_LENGTH] |
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.