Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

/Users/trevorw/projects/release/covered-0.7.4/src/instance.h File Reference


Detailed Description

Contains functions for handling functional unit instances.

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

#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, bool report_save)
 Displays contents of functional unit instance tree to specified file.

void instance_only_db_read (char **line)
 Reads in and handles an instance-only line from the database.

void instance_only_db_merge (char **line)
 Reads in and merges an instance-only line from the database.

void instance_remove_stmt_blks_calling_stmt (funit_inst *root, statement *stmt)
 Removes all statement blocks that contain expressions that call the given statement.

void instance_remove_parms_with_expr (funit_inst *root, statement *stmt)
 Removes expressions from instance parameters within the given instance that match the given expression.

void instance_output_dumpvars (FILE *vfile, funit_inst *root)
 Outputs dumpvars to the given file for the given instance.

void instance_dealloc_tree (funit_inst *root)
 Recursively deallocates all memory for the associated instance tree.

void instance_dealloc (funit_inst *root, char *scope)
 Removes specified instance from tree.


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

00654   { PROFILE(INSTANCE_COPY);
00655 
00656   funit_inst* new_inst;
00657 
00658   new_inst = instance_copy_helper( from_inst, to_inst, name, range, resolve, TRUE );
00659 
00660   PROFILE_END;
00661 
00662   return( new_inst );
00663 
00664 }

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

00132   { PROFILE(INSTANCE_CREATE);
00133 
00134   funit_inst* new_inst;  /* Pointer to new functional unit instance */
00135 
00136   new_inst                   = (funit_inst*)malloc_safe( sizeof( funit_inst ) );
00137   new_inst->funit            = funit;
00138   new_inst->name             = strdup_safe( inst_name );
00139   new_inst->suppl.name_diff  = name_diff;
00140   new_inst->suppl.ignore     = ignore;
00141   new_inst->suppl.gend_scope = gend_scope;
00142   new_inst->stat             = NULL;
00143   new_inst->param_head       = NULL;
00144   new_inst->param_tail       = NULL;
00145   new_inst->gitem_head       = NULL;
00146   new_inst->gitem_tail       = NULL;
00147   new_inst->parent           = NULL;
00148   new_inst->child_head       = NULL;
00149   new_inst->child_tail       = NULL;
00150   new_inst->next             = NULL;
00151 
00152   /* Create range (get a copy since this memory is managed by the parser) */
00153   if( range == NULL ) {
00154     new_inst->range = NULL;
00155   } else {
00156     assert( range->left  != NULL );
00157     assert( range->right != NULL );
00158     new_inst->range             = (vector_width*)malloc_safe( sizeof( vector_width ) );
00159     new_inst->range->left       = (static_expr*)malloc_safe( sizeof( static_expr ) );
00160     new_inst->range->left->num  = range->left->num;
00161     new_inst->range->left->exp  = range->left->exp;
00162     new_inst->range->right      = (static_expr*)malloc_safe( sizeof( static_expr ) );
00163     new_inst->range->right->num = range->right->num;
00164     new_inst->range->right->exp = range->right->exp;
00165   }
00166 
00167   PROFILE_END;
00168 
00169   return( new_inst );
00170 
00171 }

void instance_db_write funit_inst root,
FILE *  file,
char *  scope,
bool  parse_mode,
bool  issue_ids,
bool  report_save
 

Displays contents of functional unit instance tree to specified file.

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
report_save  Specifies if we are saving a CDD file after modifying it with the report command

01142   { PROFILE(INSTANCE_DB_WRITE);
01143 
01144   bool stop_recursive = FALSE;
01145 
01146   assert( root != NULL );
01147 
01148   if( root->funit != NULL ) {
01149 
01150     if( (root->funit->type != FUNIT_NO_SCORE) && !root->suppl.ignore ) {
01151 
01152       funit_inst* curr = parse_mode ? root : NULL;
01153 
01154       assert( scope != NULL );
01155 
01156       /* If we are in parse mode, re-issue expression IDs (we use the ulid field since it is not used in parse mode) */
01157       if( issue_ids && (root->funit != NULL) ) {
01158 
01159         exp_link*   expl;
01160         sig_link*   sigl;
01161 #ifndef VPI_ONLY
01162         gitem_link* gil;
01163 #endif
01164 
01165         /* First issue IDs to the expressions within the functional unit */
01166         expl = root->funit->exp_head;
01167         while( expl != NULL ) {
01168           expl->exp->ulid = curr_expr_id;
01169           curr_expr_id++;
01170           expl = expl->next;
01171         }
01172 
01173         sigl = root->funit->sig_head;
01174         while( sigl != NULL ) {
01175           sigl->sig->id = curr_sig_id;
01176           curr_sig_id++;
01177           sigl = sigl->next;
01178         }
01179     
01180 #ifndef VPI_ONLY
01181         /* Then issue IDs to any generated expressions/signals */
01182         gil = root->gitem_head;
01183         while( gil != NULL ) {
01184           gen_item_assign_ids( gil->gi, root->funit );
01185           gil = gil->next;
01186         }
01187 #endif
01188 
01189       }
01190 
01191       /* Display root functional unit */
01192       funit_db_write( root->funit, scope, root->suppl.name_diff, file, curr, report_save, issue_ids );
01193 
01194     } else {
01195 
01196       stop_recursive = TRUE;
01197 
01198     }
01199 
01200   } else {
01201 
01202     fprintf( file, "%d %s %d\n", DB_TYPE_INST_ONLY, scope, root->suppl.name_diff );
01203 
01204   }
01205 
01206   if( !stop_recursive ) {
01207  
01208     char tscope[4096];
01209 
01210     /* Display children */
01211     funit_inst* curr = root->child_head;
01212     while( curr != NULL ) {
01213       unsigned int rv = snprintf( tscope, 4096, "%s.%s", scope, curr->name );
01214       assert( rv < 4096 );
01215       instance_db_write( curr, file, tscope, parse_mode, issue_ids, report_save );
01216       curr = curr->next;
01217     }
01218 
01219   }
01220 
01221   PROFILE_END;
01222 
01223 }

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

01537   { PROFILE(INSTANCE_DEALLOC);
01538   
01539   funit_inst* inst;        /* Pointer to instance to remove */
01540   funit_inst* curr;        /* Pointer to current child instance to remove */
01541   funit_inst* last;        /* Last current child instance */
01542   char        back[256];   /* Highest level of hierarchy in hierarchical reference */
01543   char        rest[4096];  /* Rest of scope value */
01544   
01545   assert( root  != NULL );
01546   assert( scope != NULL );
01547   
01548   if( scope_compare( root->name, scope ) ) {
01549     
01550     /* We are the root so just remove the whole tree */
01551     instance_dealloc_tree( root );
01552     
01553   } else {
01554     
01555     /* 
01556      Find parent instance of given scope and remove this instance
01557      from its child list.
01558     */  
01559     scope_extract_back( scope, back, rest );
01560     assert( rest[0] != '\0' );
01561 
01562     inst = instance_find_scope( root, rest, TRUE );
01563     assert( inst != NULL );
01564 
01565     curr = inst->child_head;
01566     last = NULL;
01567     while( (curr != NULL) && !scope_compare( curr->name, scope ) ) {
01568       last = curr;
01569       curr = curr->next;
01570     }
01571 
01572     if( curr != NULL ) {
01573       if( last != NULL ) {
01574         last->next = curr->next;
01575       }
01576       if( curr == inst->child_head ) {
01577         /* Move parent head pointer */
01578         inst->child_head = curr->next;
01579       }
01580       if( curr == inst->child_tail ) {
01581         /* Move parent tail pointer */
01582         inst->child_tail = last;
01583       }
01584     }
01585 
01586     instance_dealloc_tree( curr );
01587 
01588   }
01589 
01590   PROFILE_END;
01591 
01592 }

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

01505   { PROFILE(INSTANCE_DEALLOC_TREE);
01506 
01507   funit_inst* curr;  /* Pointer to current instance to evaluate */
01508   funit_inst* tmp;   /* Temporary pointer to instance */
01509 
01510   if( root != NULL ) {
01511 
01512     /* Remove instance's children first */
01513     curr = root->child_head;
01514     while( curr != NULL ) {
01515       tmp = curr->next;
01516       instance_dealloc_tree( curr );
01517       curr = tmp;
01518     }
01519 
01520     /* Deallocate the instance memory */
01521     instance_dealloc_single( root );
01522 
01523   }
01524 
01525   PROFILE_END;
01526 
01527 }

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

00111   { PROFILE(INSTANCE_DISPLAY_TREE);
00112 
00113   instance_display_tree_helper( root, "" );
00114 
00115   PROFILE_END;
00116 
00117 }

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

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

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

00455   { PROFILE(INSTANCE_FIND_EXPRESSION_BY_EXCLUSION_ID); 
00456     
00457   expression* exp = NULL;  /* Pointer to found expression */
00458     
00459   if( root != NULL ) {
00460 
00461     assert( root->funit != NULL );
00462  
00463     if( (root->funit->exp_head != NULL) && 
00464         (root->funit->exp_head->exp->id <= id) && 
00465         (root->funit->exp_tail->exp->id >= id) ) {
00466 
00467       exp_link* expl = root->funit->exp_head;
00468 
00469       while( (expl != NULL) && (expl->exp->id != id) ) {
00470         expl = expl->next;           
00471       }
00472       assert( expl->exp != NULL );
00473       exp          = expl->exp;
00474       *found_funit = root->funit;
00475 
00476     } else {
00477 
00478       funit_inst* child = root->child_head;
00479       while( (child != NULL) && ((exp = instance_find_expression_by_exclusion_id( child, id, found_funit )) == NULL) ) {
00480         child = child->next;
00481       }
00482 
00483     }
00484     
00485   }
00486   
00487   PROFILE_END; 
00488   
00489   return( exp );
00490   
00491 }

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.

00502   { PROFILE(INSTANCE_FIND_FSM_ARC_INDEX_BY_EXCLUSION_ID);
00503 
00504   int arc_index = -1;  /* Index of found FSM arc */
00505 
00506   if( root != NULL ) {
00507 
00508     fsm_link* fsml;
00509 
00510     assert( root->funit != NULL );
00511   
00512     fsml = root->funit->fsm_head;
00513     while( (fsml != NULL) && ((arc_index = arc_find_arc_by_exclusion_id( fsml->table->table, id )) == -1) ) {
00514       fsml = fsml->next;
00515     }
00516 
00517     if( arc_index != -1 ) {
00518       *found_fsm   = fsml->table->table;
00519       *found_funit = root->funit;
00520     } else {
00521       funit_inst* child = root->child_head;
00522       while( (child != NULL) && ((arc_index = instance_find_fsm_arc_index_by_exclusion_id( child, id, found_fsm, found_funit )) == -1) ) {
00523         child = child->next;
00524       }
00525     }
00526 
00527   }
00528 
00529   PROFILE_END;
00530 
00531   return( arc_index );
00532 
00533 }

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

00265   { PROFILE(INSTANCE_FIND_SCOPE);
00266  
00267   char        front[256];   /* Front of scope value */
00268   char        rest[4096];   /* Rest of scope value */
00269   funit_inst* inst = NULL;  /* Pointer to found instance */
00270   funit_inst* child;        /* Pointer to current child instance being traversed */
00271 
00272   assert( root != NULL );
00273 
00274   /* First extract the front scope */
00275   scope_extract_front( scope, front, rest );
00276 
00277   /* Skip this instance and move onto the children if we are an unnamed scope that does not contain signals */
00278   if( !rm_unnamed && db_is_unnamed_scope( root->name ) && !funit_is_unnamed( root->funit ) ) {
00279     child = root->child_head;
00280     while( (child != NULL) && ((inst = instance_find_scope( child, scope, rm_unnamed )) == NULL) ) {
00281       child = child->next;
00282     }
00283 
00284   /* Keep traversing if our name matches */
00285   } else if( instance_compare( front, root ) ) {
00286     if( rest[0] == '\0' ) {
00287       inst = root;
00288     } else {
00289       child = root->child_head;
00290       while( (child != NULL) && ((inst = instance_find_scope( child, rest, rm_unnamed )) == NULL) ) {
00291         child = child->next;
00292       }
00293     }
00294   }
00295 
00296   PROFILE_END;
00297 
00298   return( inst );
00299 
00300 }

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

00408   { PROFILE(INSTANCE_FIND_SIGNAL_BY_EXCLUSION_ID);
00409  
00410   vsignal* sig = NULL;  /* Pointer to found signal */
00411 
00412   if( root != NULL ) {
00413 
00414     if( (root->funit != NULL) &&
00415         (root->funit->sig_head != NULL) &&
00416         (root->funit->sig_head->sig->id <= id) &&
00417         (root->funit->sig_tail->sig->id >= id) ) {
00418 
00419       sig_link* sigl = root->funit->sig_head;
00420 
00421       while( (sigl != NULL) && (sigl->sig->id != id) ) {
00422         sigl = sigl->next;
00423       }
00424       assert( sigl->sig != NULL );
00425       sig          = sigl->sig;
00426       *found_funit = root->funit;
00427 
00428     } else {
00429 
00430       funit_inst* child = root->child_head;
00431       while( (child != NULL) && ((sig = instance_find_signal_by_exclusion_id( child, id, found_funit )) == NULL) ) {
00432         child = child->next;
00433       }
00434 
00435     }
00436     
00437   }
00438 
00439   PROFILE_END;
00440 
00441   return( sig );
00442 
00443 }

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

00182   { PROFILE(INSTANCE_GEN_SCOPE);
00183 
00184   if( leaf != NULL ) {
00185 
00186     /* Call parent instance first */
00187     instance_gen_scope( scope, leaf->parent, flatten );
00188 
00189     if( !flatten || !db_is_unnamed_scope( leaf->name ) ) {
00190       if( scope[0] != '\0' ) {
00191         strcat( scope, "." );
00192         strcat( scope, leaf->name );
00193       } else {
00194         strcpy( scope, leaf->name );
00195       }
00196     }
00197 
00198   }
00199 
00200   PROFILE_END;
00201 
00202 }

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

00998   { PROFILE(INSTANCE_GET_LEADING_HIERARCHY);
00999 
01000   if( leading_hierarchy != NULL ) {
01001     strcat( leading_hierarchy, root->name );
01002   }
01003 
01004   *top_inst = root;
01005 
01006   if( root->funit == NULL ) {
01007 
01008     do {
01009       root = root->child_head;
01010       if( leading_hierarchy != NULL ) {
01011         strcat( leading_hierarchy, "." );
01012         strcat( leading_hierarchy, root->name );
01013       }
01014       *top_inst = root;
01015     } while( (root != NULL) && (root->funit == NULL) );
01016 
01017   }
01018 
01019   PROFILE_END;
01020 
01021 }

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

01059   { PROFILE(INSTANCE_MERGE_TWO_TREES);
01060 
01061   bool        retval = TRUE;
01062   char        lhier1[4096];
01063   char        lhier2[4096];
01064   funit_inst* tinst1 = NULL;
01065   funit_inst* tinst2 = NULL;
01066 
01067   lhier1[0] = '\0';
01068   lhier2[0] = '\0';
01069 
01070   /* Get leading hierarchy information */
01071   instance_get_leading_hierarchy( root1, lhier1, &tinst1 );
01072   instance_get_leading_hierarchy( root2, lhier2, &tinst2 );
01073 
01074   /* If the top-level modules are the same, just merge them */
01075   if( (tinst1->funit != NULL) && (tinst2->funit != NULL) && (strcmp( tinst1->funit->name, tinst2->funit->name ) == 0) ) {
01076 
01077     if( strcmp( lhier1, lhier2 ) == 0 ) {
01078 
01079       bool rv = instance_merge_tree( tinst1, tinst2 );
01080       assert( rv );
01081 
01082     } else if( strcmp( root1->name, root2->name ) == 0 ) {
01083 
01084       bool rv = instance_merge_tree( root1, root2 );
01085       assert( rv );
01086 
01087     } else {
01088       
01089       bool rv = instance_merge_tree( tinst1, tinst2 );
01090       assert( rv );
01091       instance_mark_lhier_diffs( tinst1, tinst2 );
01092 
01093     }
01094 
01095   /* If the two trees share the same root name, merge them */
01096   } else if( (strcmp( root1->name, root2->name ) == 0) && instance_merge_tree( root1, root2 ) ) {
01097 
01098     /* We've already merged so we don't have anything else to do */
01099 
01100   /* Check to see if the module pointed to by tinst1 exists within the tree of tinst2 */
01101   } else if( (root2 = instance_find_by_funit_name_if_one( tinst2, tinst1->funit->name )) != NULL ) {
01102 
01103     bool rv = instance_merge_tree( tinst1, root2 );
01104     assert( rv );
01105     instance_mark_lhier_diffs( tinst1, root2 );
01106 
01107   /* Check to see if the module pointed to by tinst2 exists within the tree of tinst1 */
01108   } else if( (root1 = instance_find_by_funit_name_if_one( tinst1, tinst2->funit->name )) != NULL ) {
01109 
01110     bool rv = instance_merge_tree( root1, tinst2 );
01111     assert( rv );
01112     instance_mark_lhier_diffs( root1, tinst2 );
01113 
01114   /* Otherwise, we cannot merge the two CDD files so don't */
01115   } else {
01116 
01117     retval = FALSE;
01118 
01119   }
01120 
01121   PROFILE_END;
01122 
01123   return( retval );
01124 
01125 }

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

01290   { PROFILE(INSTANCE_ONLY_DB_MERGE);
01291 
01292   char scope[4096];
01293   int  chars_read;
01294   bool name_diff;
01295 
01296   if( sscanf( *line, "%s %d%n", scope, &name_diff, &chars_read ) == 2 ) {
01297 
01298     char*       back = strdup_safe( scope );
01299     char*       rest = strdup_safe( scope );
01300     funit_inst* child;
01301 
01302     *line += chars_read;
01303 
01304     scope_extract_back( scope, back, rest );
01305 
01306     /* Create "placeholder" instance */
01307     child = instance_create( NULL, back, name_diff, FALSE, FALSE, NULL );
01308 
01309     /* If we are the top-most instance, just add ourselves to the instance link list */
01310     if( rest[0] == '\0' ) {
01311 
01312       /* Add a new instance link if was not able to be found in the instance linked list */
01313       if( inst_link_find_by_scope( scope, db_list[curr_db]->inst_head ) == NULL ) {
01314         (void)inst_link_add( child, &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
01315       }
01316 
01317     /* Otherwise, find our parent instance and attach the new instance to it */
01318     } else {
01319       funit_inst* parent;
01320       if( (parent = inst_link_find_by_scope( rest, db_list[curr_db]->inst_head )) != NULL ) {
01321         if( parent->child_head == NULL ) {
01322           parent->child_head = parent->child_tail = child;
01323         } else {
01324           parent->child_tail->next = child;
01325           parent->child_tail       = child;
01326         }
01327         child->parent = parent;
01328       } else {
01329         print_output( "Unable to find parent instance of instance-only line in database file.", FATAL, __FILE__, __LINE__ );
01330         Throw 0;
01331       }
01332     }
01333 
01334     /* Deallocate memory */
01335     free_safe( back, (strlen( scope ) + 1) );
01336     free_safe( rest, (strlen( scope ) + 1) );
01337 
01338   } else {
01339 
01340     print_output( "Unable to merge instance-only line in database file.", FATAL, __FILE__, __LINE__ );
01341     Throw 0;
01342 
01343   }
01344 
01345   PROFILE_END;
01346 
01347 }

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

01230   { PROFILE(INSTANCE_ONLY_DB_READ);
01231 
01232   char  scope[4096];
01233   int   chars_read;
01234   bool  name_diff;
01235 
01236   if( sscanf( *line, "%s %d%n", scope, &name_diff, &chars_read ) == 2 ) {
01237 
01238     char*       back = strdup_safe( scope );
01239     char*       rest = strdup_safe( scope );
01240     funit_inst* child;
01241 
01242     *line += chars_read;
01243 
01244     scope_extract_back( scope, back, rest ); 
01245 
01246     /* Create "placeholder" instance */
01247     child = instance_create( NULL, back, name_diff, FALSE, FALSE, NULL );
01248 
01249     /* If we are the top-most instance, just add ourselves to the instance link list */
01250     if( rest[0] == '\0' ) {
01251       (void)inst_link_add( child, &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
01252 
01253     /* Otherwise, find our parent instance and attach the new instance to it */
01254     } else {
01255       funit_inst* parent;
01256       if( (parent = inst_link_find_by_scope( rest, db_list[curr_db]->inst_tail )) != NULL ) {
01257         if( parent->child_head == NULL ) {
01258           parent->child_head = parent->child_tail = child;
01259         } else {
01260           parent->child_tail->next = child;
01261           parent->child_tail       = child;
01262         }
01263         child->parent = parent;
01264       } else {
01265         print_output( "Unable to find parent instance of instance-only line in database file.", FATAL, __FILE__, __LINE__ );
01266         Throw 0;
01267       }
01268     }
01269 
01270     /* Deallocate memory */
01271     free_safe( back, (strlen( scope ) + 1) );
01272     free_safe( rest, (strlen( scope ) + 1) );
01273 
01274   } else {
01275 
01276     print_output( "Unable to read instance-only line in database file.", FATAL, __FILE__, __LINE__ );
01277     Throw 0;
01278 
01279   }
01280 
01281   PROFILE_END;
01282 
01283 }

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

01477   { PROFILE(INSTANCE_OUTPUT_DUMPVARS);
01478 
01479   funit_inst* child = root->child_head;
01480   char        scope[4096];
01481 
01482   /* Generate instance scope */
01483   scope[0] = '\0';
01484   instance_gen_scope( scope, root, FALSE );
01485 
01486   /* Outputs dumpvars for the given functional unit */
01487   funit_output_dumpvars( vfile, root->funit, scope );
01488 
01489   /* Outputs all children instances */
01490   while( child != NULL ) {
01491     instance_output_dumpvars( vfile, child );
01492     child = child->next;
01493   }
01494 
01495   PROFILE_END;
01496 
01497 }

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

00685   { PROFILE(INSTANCE_PARSE_ADD);
00686   
00687   bool        retval = TRUE;  /* Return value for this function */
00688   funit_inst* inst;           /* Temporary pointer to functional unit instance to add to */
00689   funit_inst* cinst;          /* Pointer to instance of child functional unit */
00690   int         i;              /* Loop iterator */
00691   int         ignore;         /* Number of matched instances to ignore */
00692 
00693   if( *root == NULL ) {
00694 
00695     *root = instance_create( child, inst_name, FALSE, ignore_child, gend_scope, range );
00696 
00697   } else {
00698 
00699     assert( parent != NULL );
00700 
00701     i      = 0;
00702     ignore = 0;
00703 
00704     /*
00705      Check to see if the child functional unit has already been parsed and, if so, find
00706      one of its instances for copying the instance tree below it.
00707     */
00708     cinst = instance_find_by_funit( *root, child, &ignore);
00709     
00710     /* Filename will be set to a value if the functional unit has been parsed */
00711     if( (cinst != NULL) && (cinst->funit->filename != NULL) ) { 
00712 
00713       ignore = 0;
00714       while( (ignore >= 0) && ((inst = instance_find_by_funit( *root, parent, &ignore )) != NULL) ) {
00715         (void)instance_copy( cinst, inst, inst_name, range, resolve );
00716         i++;
00717         ignore = child_gend ? -1 : i;
00718       }
00719 
00720     } else {
00721 
00722       ignore = 0;
00723       while( (ignore >= 0) && ((inst = instance_find_by_funit( *root, parent, &ignore )) != NULL) ) {
00724         cinst = instance_add_child( inst, child, inst_name, range, resolve, ignore_child, gend_scope );
00725         i++;
00726         ignore = (child_gend && (cinst != NULL)) ? -1 : i;
00727       }
00728 
00729     }
00730 
00731     /* Everything went well with the add if we found at least one parent instance */
00732     retval = (i > 0);
00733 
00734   }
00735 
00736   PROFILE_END;
00737 
00738   return( retval );
00739 
00740 }

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

00870   { PROFILE(INSTANCE_READ_ADD);
00871 
00872   bool        retval = TRUE;  /* Return value for this function */
00873   funit_inst* inst;           /* Temporary pointer to functional unit instance to add to */
00874   funit_inst* new_inst;       /* Pointer to new functional unit instance to add */
00875 
00876   if( *root == NULL ) {
00877 
00878     *root = instance_create( child, inst_name, FALSE, FALSE, FALSE, NULL );
00879 
00880   } else {
00881 
00882     assert( parent != NULL );
00883   
00884     if( (inst = instance_find_scope( *root, parent, TRUE )) != NULL ) {
00885 
00886       /* Create new instance */
00887       new_inst = instance_create( child, inst_name, FALSE, FALSE, FALSE, NULL );
00888 
00889       if( inst->child_head == NULL ) {
00890         inst->child_head = new_inst;
00891         inst->child_tail = new_inst;
00892       } else {
00893         inst->child_tail->next = new_inst;
00894         inst->child_tail       = new_inst;
00895       }
00896 
00897       /* Set parent pointer of new instance */
00898       new_inst->parent = inst;
00899 
00900     } else {
00901 
00902       /* Unable to find parent of this child, needs to be added to a different instance tree */
00903       retval = FALSE;
00904 
00905     }
00906  
00907   }
00908 
00909   PROFILE_END;
00910 
00911   return( retval );
00912 
00913 }

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

01395   { PROFILE(INSTANCE_REMOVE_PARMS_WITH_EXPR);
01396 
01397   funit_inst* curr_child;  /* Pointer to current child instance to traverse */
01398   inst_parm*  iparm;       /* Pointer to current instance parameter */
01399   exp_link*   expl;        /* Pointer to current expression link */
01400   exp_link*   texpl;       /* Temporary pointer to current expression link */
01401 
01402   /* Search for the given expression within the given instance parameter */
01403   iparm = root->param_head;
01404   while( iparm != NULL ) {
01405     if( iparm->sig != NULL ) {
01406       expl = iparm->sig->exp_head;
01407       while( expl != NULL ) {
01408         texpl = expl;
01409         expl  = expl->next;
01410         if( expression_find_expr( stmt->exp, texpl->exp ) ) {
01411           if( iparm->mparm != NULL ) {
01412             exp_link_remove( texpl->exp, &(iparm->mparm->exp_head), &(iparm->mparm->exp_tail), FALSE );
01413           }
01414           exp_link_remove( texpl->exp, &(iparm->sig->exp_head), &(iparm->sig->exp_tail), FALSE );
01415         }
01416       }
01417     }
01418     iparm = iparm->next;
01419   }
01420 
01421   /* Traverse children */
01422   curr_child = root->child_head;
01423   while( curr_child != NULL ) {
01424     instance_remove_parms_with_expr( curr_child, stmt );
01425     curr_child = curr_child->next;
01426   }
01427 
01428   PROFILE_END;
01429 
01430 }

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

01355   { PROFILE(INSTANCE_REMOVE_STMT_BLKS_CALLING_STMT);
01356 
01357   funit_inst* curr_child;  /* Pointer to current child instance to parse */
01358 #ifndef VPI_ONLY
01359   gitem_link* gil;         /* Pointer to current generate item link */
01360 #endif
01361 
01362   if( root != NULL ) {
01363 
01364     /* First, handle the current functional unit */
01365     funit_remove_stmt_blks_calling_stmt( root->funit, stmt );
01366 
01367 #ifndef VPI_ONLY
01368     /* Second, handle all generate items in this instance */
01369     gil = root->gitem_head;
01370     while( gil != NULL ) {
01371       gen_item_remove_if_contains_expr_calling_stmt( gil->gi, stmt );
01372       gil = gil->next;
01373     }
01374 #endif
01375 
01376     /* Parse children */
01377     curr_child = root->child_head;
01378     while( curr_child != NULL ) {
01379       instance_remove_stmt_blks_calling_stmt( curr_child, stmt );
01380       curr_child = curr_child->next;
01381     }
01382 
01383   }
01384 
01385   PROFILE_END;
01386 
01387 }

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

00847   { PROFILE(INSTANCE_RESOLVE);
00848 
00849   /* Resolve all instance names */
00850   instance_resolve_helper( root, root );
00851 
00852   PROFILE_END;
00853 
00854 }


Generated on Wed Jun 17 22:19:22 2009 for Covered by doxygen 1.3.4