instance.h File Reference

Contains functions for handling functional unit instances. More...

#include "defines.h"

Go to the source code of this file.

Functions

funit_instinstance_create (func_unit *funit, char *inst_name, bool name_diff, bool ignore, bool gend_scope, vector_width *range)
 Creates a new instance with the given information.
void instance_display_tree (funit_inst *root)
 Displays the current state of the instance tree.
void instance_gen_scope (char *scope, funit_inst *leaf, bool flatten)
 Builds full hierarchy from leaf node to root.
funit_instinstance_find_scope (funit_inst *root, char *scope, bool rm_unnamed)
 Finds specified scope in functional unit instance tree.
funit_instinstance_find_by_funit (funit_inst *root, const func_unit *funit, int *ignore)
 Returns instance that points to specified functional unit for each instance.
vsignalinstance_find_signal_by_exclusion_id (funit_inst *root, int id, func_unit **found_funit)
 Returns signal that matches the given exclusion ID.
expressioninstance_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_instinstance_copy (funit_inst *from_inst, funit_inst *to_inst, char *name, vector_width *range, bool resolve)
 Copies the given from_inst as a child of the given to_inst.
bool instance_parse_add (funit_inst **root, func_unit *parent, func_unit *child, char *inst_name, vector_width *range, bool resolve, bool child_gend, bool ignore_child, bool gend_scope)
 Adds new instance to specified instance tree during parse.
void instance_resolve (funit_inst *root)
 Resolves all instance arrays.
bool instance_read_add (funit_inst **root, char *parent, func_unit *child, char *inst_name)
 Adds new instance to specified instance tree during CDD read.
void instance_get_leading_hierarchy (funit_inst *root, char *leading_hierarchy, funit_inst **top_inst)
 Gets the leading hierarchy scope and instance for a particular instance tree.
bool instance_merge_two_trees (funit_inst *root1, funit_inst *root2)
 Performs complex instance tree merging for two instance trees.
void instance_db_write (funit_inst *root, FILE *file, char *scope, bool parse_mode, bool issue_ids)
 Displays contents of functional unit instance tree to specified file.
void instance_only_db_read (char **line)
 Reads in and handles an instance-only line from the database.
void instance_only_db_merge (char **line)
 Reads in and merges an instance-only line from the database.
void instance_remove_stmt_blks_calling_stmt (funit_inst *root, statement *stmt)
 Removes all statement blocks that contain expressions that call the given statement.
void instance_remove_parms_with_expr (funit_inst *root, statement *stmt)
 Removes expressions from instance parameters within the given instance that match the given expression.
void instance_output_dumpvars (FILE *vfile, funit_inst *root)
 Outputs dumpvars to the given file for the given instance.
void instance_dealloc_tree (funit_inst *root)
 Recursively deallocates all memory for the associated instance tree.
void instance_dealloc (funit_inst *root, char *scope)
 Removes specified instance from tree.

Detailed Description

Contains functions for handling functional unit instances.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
3/11/2002

Function Documentation

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.

Parameters:
from_inst Pointer to instance tree to copy
to_inst Pointer to instance to copy tree to
name Instance name of current instance being copied
range For arrays of instances, indicates the array range
resolve Set to TRUE if newly added instance should be immediately resolved

References instance_copy_helper(), PROFILE, PROFILE_END, and TRUE.

Referenced by gen_item_resolve(), and instance_parse_add().

00660   { PROFILE(INSTANCE_COPY);
00661 
00662   funit_inst* new_inst;
00663 
00664   new_inst = instance_copy_helper( from_inst, to_inst, name, range, resolve, TRUE );
00665 
00666   PROFILE_END;
00667 
00668   return( new_inst );
00669 
00670 }

funit_inst* instance_create ( func_unit funit,
char *  inst_name,
bool  name_diff,
bool  ignore,
bool  gend_scope,
vector_width range 
)

Creates a new instance with the given information.

Returns:
Returns pointer to newly created functional unit instance.

Creates a new functional unit instance from heap, initializes its data and returns a pointer to it.

Parameters:
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.

Exceptions:
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.

Parameters:
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.

Parameters:
root Root of functional unit instance tree
scope Scope of functional unit to remove from tree

References funit_inst_s::child_head, funit_inst_s::child_tail, instance_dealloc_tree(), instance_find_scope(), funit_inst_s::name, funit_inst_s::next, PROFILE, PROFILE_END, scope_compare(), scope_extract_back(), and TRUE.

Referenced by inst_link_delete_list().

01571   { PROFILE(INSTANCE_DEALLOC);
01572   
01573   funit_inst* inst;        /* Pointer to instance to remove */
01574   funit_inst* curr;        /* Pointer to current child instance to remove */
01575   funit_inst* last;        /* Last current child instance */
01576   char        back[256];   /* Highest level of hierarchy in hierarchical reference */
01577   char        rest[4096];  /* Rest of scope value */
01578   
01579   assert( root  != NULL );
01580   assert( scope != NULL );
01581   
01582   if( scope_compare( root->name, scope ) ) {
01583     
01584     /* We are the root so just remove the whole tree */
01585     instance_dealloc_tree( root );
01586     
01587   } else {
01588     
01589     /* 
01590      Find parent instance of given scope and remove this instance
01591      from its child list.
01592     */  
01593     scope_extract_back( scope, back, rest );
01594     assert( rest[0] != '\0' );
01595 
01596     inst = instance_find_scope( root, rest, TRUE );
01597     assert( inst != NULL );
01598 
01599     curr = inst->child_head;
01600     last = NULL;
01601     while( (curr != NULL) && !scope_compare( curr->name, scope ) ) {
01602       last = curr;
01603       curr = curr->next;
01604     }
01605 
01606     if( curr != NULL ) {
01607       if( last != NULL ) {
01608         last->next = curr->next;
01609       }
01610       if( curr == inst->child_head ) {
01611         /* Move parent head pointer */
01612         inst->child_head = curr->next;
01613       }
01614       if( curr == inst->child_tail ) {
01615         /* Move parent tail pointer */
01616         inst->child_tail = last;
01617       }
01618     }
01619 
01620     instance_dealloc_tree( curr );
01621 
01622   }
01623 
01624   PROFILE_END;
01625 
01626 }

void instance_dealloc_tree ( funit_inst root  ) 

Recursively deallocates all memory for the associated instance tree.

Recursively traverses instance tree, deallocating heap memory used to store the the tree.

Parameters:
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.

Parameters:
root Pointer to root instance to display

References instance_display_tree_helper(), PROFILE, and PROFILE_END.

Referenced by inst_link_display().

00116   { PROFILE(INSTANCE_DISPLAY_TREE);
00117 
00118   instance_display_tree_helper( root, "" );
00119 
00120   PROFILE_END;
00121 
00122 }

funit_inst* instance_find_by_funit ( funit_inst root,
const func_unit funit,
int *  ignore 
)

Returns instance that points to specified functional unit for each instance.

Returns:
Returns pointer to functional unit instance found by scope.

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.

Parameters:
root Pointer to root functional unit instance of tree
funit Pointer to functional unit to find in tree
ignore Pointer to number of matches to ignore

References funit_inst_s::child_head, funit_inst_s::funit, instance_find_by_funit(), funit_inst_s::next, PROFILE, and PROFILE_END.

Referenced by inst_link_find_by_funit(), instance_find_by_funit(), instance_parse_add(), and param_expr_eval().

00320   { PROFILE(INSTANCE_FIND_BY_FUNIT);
00321 
00322   funit_inst* match_inst = NULL;  /* Pointer to functional unit instance that found a match */
00323   funit_inst* curr_child;         /* Pointer to current instances child functional unit instance */
00324 
00325   if( root != NULL ) {
00326 
00327     if( root->funit == funit ) {
00328 
00329       if( *ignore == 0 ) {
00330         match_inst = root;
00331       } else {
00332         (*ignore)--;
00333       }
00334 
00335     } else {
00336 
00337       curr_child = root->child_head;
00338       while( (curr_child != NULL) && (match_inst == NULL) ) {
00339         match_inst = instance_find_by_funit( curr_child, funit, ignore );
00340         curr_child = curr_child->next;
00341       }
00342 
00343     }
00344     
00345   }
00346 
00347   PROFILE_END;
00348 
00349   return( match_inst );
00350 
00351 }

expression* instance_find_expression_by_exclusion_id ( funit_inst root,
int  id,
func_unit **  found_funit 
)

Returns expression that matches the given exclusion ID.

Returns:
Returns the pointer to the expression that contains the same exclusion ID.

Recursively searches the given instance tree to find the expression that has the same exclusion ID as the one specified.

Parameters:
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.

Returns:
Returns the index of the state transition in the arcs array of the found_fsm in the found_funit that matches the given exclusion ID (if one is found); otherwise, returns -1.

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.

Returns:
Returns pointer to functional unit instance found by scope.

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.

Parameters:
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.

Returns:
Returns the pointer to the signal that contains the same exclusion ID.

Recursively searches the given instance tree to find the signal that has the same exclusion ID as the one specified.

Parameters:
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.

Parameters:
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.

Note:
This function requires that the leading_hierarchy string be previously allocated and initialized to the NULL string.
Parameters:
root Pointer to instance tree to get information from
leading_hierarchy Leading hierarchy to first populated instance
top_inst Pointer to first populated instance

References funit_inst_s::child_head, funit_inst_s::funit, funit_inst_s::name, PROFILE, and PROFILE_END.

Referenced by db_check_for_top_module(), and instance_merge_two_trees().

01031   { PROFILE(INSTANCE_GET_LEADING_HIERARCHY);
01032 
01033   if( leading_hierarchy != NULL ) {
01034     strcat( leading_hierarchy, root->name );
01035   }
01036 
01037   *top_inst = root;
01038 
01039   if( root->funit == NULL ) {
01040 
01041     do {
01042       root = root->child_head;
01043       if( leading_hierarchy != NULL ) {
01044         strcat( leading_hierarchy, "." );
01045         strcat( leading_hierarchy, root->name );
01046       }
01047       *top_inst = root;
01048     } while( (root != NULL) && (root->funit == NULL) );
01049 
01050   }
01051 
01052   PROFILE_END;
01053 
01054 }

bool instance_merge_two_trees ( funit_inst root1,
funit_inst root2 
)

Performs complex instance tree merging for two instance trees.

Returns:
Returns TRUE if the second instance tree should have its link removed from the instance tree list for the current database; otherwise, returns FALSE.

Performs comples merges two instance trees into one instance tree.

Parameters:
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.

Parameters:
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.

Parameters:
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.

Parameters:
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.

Returns:
Returns TRUE if specified instance was successfully added to the specified instance tree; otherwise, returns FALSE.

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.

Parameters:
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.

Returns:
Returns TRUE if instance was added to the specified functional unit instance tree; otherwise, returns FALSE (indicates that the instance is from a different hierarchy).

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.

Parameters:
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.

Parameters:
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.

Parameters:
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.

Parameters:
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 }

Generated on Sun Nov 21 00:55:39 2010 for Covered by  doxygen 1.6.3