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

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


Detailed Description

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

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "arc.h"
#include "db.h"
#include "defines.h"
#include "expr.h"
#include "func_unit.h"
#include "gen_item.h"
#include "instance.h"
#include "link.h"
#include "param.h"
#include "static.h"
#include "util.h"

Functions

bool instance_resolve_inst (funit_inst *, funit_inst *)
void instance_dealloc_single (funit_inst *)
void instance_display_tree_helper (funit_inst *root, char *prefix)
void instance_display_tree (funit_inst *root)
 Displays the current state of the instance tree.

funit_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_gen_scope (char *scope, funit_inst *leaf, bool flatten)
 Builds full hierarchy from leaf node to root.

bool instance_compare (char *inst_name, const funit_inst *inst)
funit_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.

void instance_find_by_funit_name (funit_inst *root, const char *funit_name, funit_inst **match_inst, unsigned int *matches)
funit_instinstance_find_by_funit_name_if_one (funit_inst *root, const char *funit_name)
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_add_child (funit_inst *inst, func_unit *child, char *name, vector_width *range, bool resolve, bool ignore_child, bool gend_scope)
funit_instinstance_copy_helper (funit_inst *from_inst, funit_inst *to_inst, char *name, vector_width *range, bool resolve, bool is_root)
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_helper (funit_inst *root, funit_inst *curr)
void instance_resolve (funit_inst *root)
 Resolves all instance arrays.

bool instance_read_add (funit_inst **root, char *parent, func_unit *child, char *inst_name)
 Adds new instance to specified instance tree during CDD read.

bool instance_merge_tree (funit_inst *root1, funit_inst *root2)
void instance_get_leading_hierarchy (funit_inst *root, char *leading_hierarchy, funit_inst **top_inst)
 Gets the leading hierarchy scope and instance for a particular instance tree.

void instance_mark_lhier_diffs (funit_inst *root1, funit_inst *root2)
bool instance_merge_two_trees (funit_inst *root1, funit_inst *root2)
 Performs complex instance tree merging for two instance trees.

void instance_db_write (funit_inst *root, FILE *file, char *scope, bool parse_mode, bool issue_ids, bool report_save)
 Displays contents of functional unit instance tree to specified file.

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

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

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

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

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

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

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


Variables

int curr_expr_id
db ** db_list
unsigned int curr_db
char user_msg [USER_MSG_LENGTH]
int curr_sig_id = 1


Function Documentation

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]
 

Returns:
Returns pointer to newly created functional unit instance if this instance name isn't already in use in the current instance; otherwise, returns NULL.
Generates new instance, adds it to the child list of the inst functional unit instance, and resolves any parameters.
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

00550   { PROFILE(INSTANCE_ADD_CHILD);
00551 
00552   funit_inst* new_inst;  /* Pointer to newly created instance to add */
00553 
00554   /* Check to see if this instance already exists */
00555   new_inst = inst->child_head;
00556   while( (new_inst != NULL) && ((strcmp( new_inst->name, name ) != 0) || (new_inst->funit != child)) ) {
00557     new_inst = new_inst->next;
00558   }
00559 
00560   /* If this instance already exists (unless the existing and new child is a placeholder), don't add it again */
00561   if( (new_inst == NULL) || (new_inst->suppl.ignore && ignore_child) ) {
00562 
00563     /* Generate new instance */
00564     new_inst = instance_create( child, name, FALSE, ignore_child, gend_scope, range );
00565 
00566     /* Add new instance to inst child instance list */
00567     if( inst->child_head == NULL ) {
00568       inst->child_head       = new_inst;
00569       inst->child_tail       = new_inst;
00570     } else {
00571       inst->child_tail->next = new_inst;
00572       inst->child_tail       = new_inst;
00573     }
00574 
00575     /* Point this instance's parent pointer to its parent */
00576     new_inst->parent = inst;
00577 
00578     // inst_link_display( db_list[curr_db]->inst_head );
00579 
00580     /* If the new instance needs to be resolved now, do so */
00581     if( resolve ) {
00582       inst_link* instl = db_list[curr_db]->inst_head;
00583       while( (instl != NULL) && !instance_resolve_inst( instl->inst, new_inst ) ) {
00584         instl = instl->next;
00585       }
00586     }
00587 
00588   } else {
00589 
00590     /* Set the ignore value in the instance to FALSE */
00591     new_inst->suppl.ignore = FALSE;
00592 
00593     new_inst = NULL;
00594 
00595   }
00596 
00597   PROFILE_END;
00598 
00599   return( new_inst );
00600 
00601 }

bool instance_compare char *  inst_name,
const funit_inst inst
[static]
 

Returns:
Returns TRUE if the given instance name and instance match. If the specified instance is a part of an array of instances and the base name matches the base name of inst_name, we also check to make sure that the index of inst_name falls within the legal range of this instance.
Parameters:
inst_name  Instance name to compare to this instance's name (may contain array information)
inst  Pointer to instance to compare name against

00213   { PROFILE(INSTANCE_COMPARE);
00214 
00215   bool         retval = FALSE;  /* Return value of this function */
00216   char         bname[4096];     /* Base name of inst_name */
00217   int          index;           /* Index of inst_name */
00218   unsigned int width;           /* Width of instance range */
00219   int          lsb;             /* LSB of instance range */
00220   int          big_endian;      /* Specifies endianness */
00221 
00222   /* If this instance has a range, handle it */
00223   if( inst->range != NULL ) {
00224 
00225     /* Extract the index portion of inst_name if there is one */
00226     if( sscanf( inst_name, "%[a-zA-Z0-9_]\[%d]", bname, &index ) == 2 ) {
00227       
00228       /* If the base names compare, check that the given index falls within this instance range */
00229       if( scope_compare( bname, inst->name ) ) {
00230 
00231         /* Get range information from instance */
00232         static_expr_calc_lsb_and_width_post( inst->range->left, inst->range->right, &width, &lsb, &big_endian );
00233         assert( width != 0 );
00234         assert( lsb   != -1 );
00235 
00236         retval = (index >= lsb) && (index < (lsb + (int)width));
00237 
00238       }
00239       
00240     }
00241 
00242   } else {
00243 
00244     retval = scope_compare( inst_name, inst->name );
00245 
00246   }
00247 
00248   PROFILE_END;
00249 
00250   return( retval );
00251 
00252 }

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_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.

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

00614   { PROFILE(INSTANCE_COPY_HELPER);
00615 
00616   funit_inst* curr;      /* Pointer to current functional unit instance to copy */
00617   funit_inst* new_inst;  /* Pointer to newly created functional unit instance */
00618 
00619   assert( from_inst != NULL );
00620   assert( to_inst   != NULL );
00621   assert( name      != NULL );
00622 
00623   /* Add new child instance */
00624   new_inst = instance_add_child( to_inst, from_inst->funit, name, range, resolve, (from_inst->suppl.ignore && from_inst->suppl.gend_scope && !is_root), from_inst->suppl.gend_scope );
00625 
00626   /* Do not add children if no child instance was created */
00627   if( new_inst != NULL ) {
00628 
00629     /* Iterate through rest of current child's list of children */
00630     curr = from_inst->child_head;
00631     while( curr != NULL ) {
00632       (void)instance_copy_helper( curr, new_inst, curr->name, curr->range, resolve, FALSE );
00633       curr = curr->next;
00634     }
00635 
00636   }
00637 
00638   PROFILE_END;
00639 
00640   return( new_inst );
00641 
00642 }

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_single funit_inst inst  )  [static]
 

Deallocates all memory allocated for the given instance.

Parameters:
inst  Pointer to instance to deallocate memory for

01437   { PROFILE(INSTANCE_DEALLOC_SINGLE);
01438 
01439   if( inst != NULL ) {
01440 
01441     /* Free up memory allocated for name */
01442     free_safe( inst->name, (strlen( inst->name ) + 1) );
01443 
01444     /* Free up memory allocated for statistic, if necessary */
01445     free_safe( inst->stat, sizeof( statistic ) );
01446 
01447     /* Free up memory for range, if necessary */
01448     if( inst->range != NULL ) {
01449       static_expr_dealloc( inst->range->left,  FALSE );
01450       static_expr_dealloc( inst->range->right, FALSE );
01451       free_safe( inst->range, sizeof( vector_width ) );
01452     }
01453 
01454     /* Deallocate memory for instance parameter list */
01455     inst_parm_dealloc( inst->param_head, TRUE );
01456 
01457 #ifndef VPI_ONLY
01458     /* Deallocate memory for generate item list */
01459     gitem_link_delete_list( inst->gitem_head, FALSE );
01460 #endif
01461 
01462     /* Free up memory for this functional unit instance */
01463     free_safe( inst, sizeof( funit_inst ) );
01464 
01465   }
01466 
01467   PROFILE_END;
01468 
01469 }

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 }

void instance_display_tree_helper funit_inst root,
char *  prefix
[static]
 

Helper function for the instance_display_tree function.

Parameters:
root  Pointer to functional unit instance to display
prefix  Prefix string to be used when outputting (used to indent children)

00068   { PROFILE(INSTANCE_DISPLAY_TREE_HELPER);
00069 
00070   char         sp[4096];  /* Contains prefix for children */
00071   funit_inst*  curr;      /* Pointer to current child instance */
00072   unsigned int rv;        /* Return value from snprintf calls */
00073 
00074   assert( root != NULL );
00075 
00076   /* Get printable version of this instance and functional unit name */
00077   if( root->funit != NULL ) {
00078     char* piname = scope_gen_printable( root->name );
00079     char* pfname = scope_gen_printable( root->funit->name );
00080     printf( "%s%s (%s) - %p (ign: %d, gend: %d)\n", prefix, piname, pfname, root, root->suppl.ignore, root->suppl.gend_scope );
00081     free_safe( piname, (strlen( piname ) + 1) );
00082     free_safe( pfname, (strlen( pfname ) + 1) );
00083   } else {
00084     char* piname = scope_gen_printable( root->name );
00085     printf( "%s%s () - %p (%d %d)\n", prefix, piname, root, root->suppl.ignore, root->suppl.gend_scope );
00086     free_safe( piname, (strlen( piname ) + 1) );
00087   }
00088 
00089   /* Calculate prefix */
00090   rv = snprintf( sp, 4096, "%s   ", prefix );
00091   assert( rv < 4096 );
00092 
00093   /* Display our children */
00094   curr = root->child_head;
00095   while( curr != NULL ) {
00096     instance_display_tree_helper( curr, sp );
00097     curr = curr->next;
00098   }
00099 
00100 
00101   PROFILE_END;
00102 
00103 }

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 }

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.

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

00356   { PROFILE(INSTANCE_FIND_BY_FUNIT_NAME_IF_ONE_HELPER);
00357 
00358   if( root != NULL ) {
00359 
00360     funit_inst* child;
00361 
00362     if( strcmp( root->funit->name, funit_name ) == 0 ) {
00363       (*matches)++;
00364       *match_inst = root;
00365     }
00366 
00367     child = root->child_head;
00368     while( child != NULL ) {
00369       instance_find_by_funit_name( child, funit_name, match_inst, matches );
00370       child = child->next;
00371     }
00372 
00373   }
00374 
00375   PROFILE_END;
00376 
00377 }

funit_inst* instance_find_by_funit_name_if_one funit_inst root,
const char *  funit_name
[static]
 

Returns:
Returns a pointer to the found instance, if one exists; otherwise, returns NULL.
Parameters:
root  Pointer to root functional unit instance to search
funit_name  Name of module to find

00385   { PROFILE(INSTANCE_FIND_BY_FUNIT_NAME_IF_ONE);
00386 
00387   funit_inst*  match_inst = NULL;
00388   unsigned int matches    = 0;
00389 
00390   instance_find_by_funit_name( root, funit_name, &match_inst, &matches );
00391 
00392   PROFILE_END;
00393 
00394   return( (matches == 1) ? match_inst : NULL );
00395 
00396 }

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 }

void instance_mark_lhier_diffs funit_inst root1,
funit_inst root2
[static]
 

Iterates up the scope for both functional unit

01029   { PROFILE(INSTANCE_MARK_LHIER_DIFFS);
01030 
01031   /* Move up the scope hierarchy looking for a difference in instance names */
01032   while( (root1 != NULL) && (root2 != NULL) && (strcmp( root1->name, root2->name ) == 0) ) {
01033     root1 = root1->parent;
01034     root2 = root2->parent;
01035   }
01036 
01037   /*
01038    Iterate up root1 instance, setting the name_diff variable to TRUE to specify that the instance name is really
01039    not accurate since its child tree with a child tree with a differen parent scope.
01040   */
01041   while( root1 != NULL ) {
01042     root1->suppl.name_diff = TRUE;
01043     root1 = root1->parent;
01044   }
01045 
01046   PROFILE_END;
01047 
01048 }

bool instance_merge_tree funit_inst root1,
funit_inst root2
[static]
 

Returns:
Returns TRUE if the instance merge was successful.
Merges to instance trees that have the same instance root.
Parameters:
root1  Pointer to root of first instance tree to merge
root2  Pointer to root of second instance tree to merge

00923   { PROFILE(INSTANCE_MERGE);
00924 
00925   funit_inst* child2;
00926   funit_inst* last2  = NULL;
00927   bool        retval = TRUE;
00928 
00929   /* Perform functional unit merging */
00930   if( root1->funit != NULL ) {
00931     if( root2->funit != NULL ) {
00932       if( strcmp( root1->funit->name, root2->funit->name ) == 0 ) {
00933         funit_merge( root1->funit, root2->funit );
00934       } else {
00935         retval = FALSE;
00936       }
00937     }
00938   } else if( root2->funit != NULL ) {
00939     root1->funit = root2->funit;
00940     root2->funit = NULL;
00941   }
00942 
00943   /* Recursively merge the child instances */
00944   child2 = root2->child_head;
00945   while( (child2 != NULL) && retval ) {
00946     funit_inst* child1 = root1->child_head;
00947     while( (child1 != NULL) && (strcmp( child1->name, child2->name ) != 0) ) {
00948       child1 = child1->next;
00949     }
00950     if( child1 != NULL ) {
00951       retval = instance_merge_tree( child1, child2 );
00952       last2  = child2;
00953       child2 = child2->next;
00954     } else {
00955       funit_inst* tmp = child2->next;
00956       child2->next   = NULL;
00957       child2->parent = root1;
00958       if( root1->child_head == NULL ) {
00959         root1->child_head = child2;
00960         root1->child_tail = child2;
00961       } else {
00962         root1->child_tail->next = child2;
00963         root1->child_tail       = child2;
00964       }
00965       if( last2 == NULL ) {
00966         root2->child_head = tmp;
00967         if( tmp == NULL ) {
00968           root2->child_tail = NULL;
00969         }
00970       } else if( tmp == NULL ) {
00971         root2->child_tail = last2;
00972         last2->next = NULL;
00973       } else {
00974         last2->next = tmp;
00975       }
00976       child2 = tmp;
00977     }
00978   }
00979 
00980   PROFILE_END;
00981 
00982   return( retval );
00983 
00984 }

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 }

void instance_resolve_helper funit_inst root,
funit_inst curr
[static]
 

Recursively iterates through the entire instance tree

Parameters:
root  Pointer to root of instance tree
curr  Pointer to current instance

00820   { PROFILE(INSTANCE_RESOLVE_HELPER);
00821 
00822   funit_inst* curr_child;  /* Pointer to current child */
00823 
00824   if( curr != NULL ) {
00825 
00826     /* Resolve all children first */
00827     curr_child = curr->child_head;
00828     while( curr_child != NULL ) {
00829       instance_resolve_helper( root, curr_child );
00830       curr_child = curr_child->next;
00831     }
00832 
00833     /* Now resolve this instance */
00834     (void)instance_resolve_inst( root, curr );
00835 
00836   }
00837 
00838   PROFILE_END;
00839 
00840 }

bool instance_resolve_inst funit_inst root,
funit_inst curr
[static]
 

Returns:
Returns TRUE if instance was resolved; otherwise, returns FALSE.
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.
Parameters:
root  Pointer to root functional unit to traverse
curr  Pointer to current instance to resolve

00752   { PROFILE(INSTANCE_RESOLVE_INST);
00753 
00754   unsigned int width = 0;   /* Width of the instance range */
00755   int          lsb;         /* LSB of the instance range */
00756   int          big_endian;  /* Unused */
00757   char*        name_copy;   /* Copy of the instance name being resolved */
00758   char*        new_name;    /* New hierarchical name of the instance(s) being resolved */
00759   unsigned int i;           /* Loop iterator */
00760 
00761   assert( curr != NULL );
00762 
00763   if( curr->range != NULL ) {
00764 
00765     unsigned int rv;
00766     unsigned int slen;
00767 
00768     /* Get LSB and width information */
00769     static_expr_calc_lsb_and_width_post( curr->range->left, curr->range->right, &width, &lsb, &big_endian );
00770     assert( width != 0 );
00771     assert( lsb != -1 );
00772 
00773     /* Remove the range information from this instance */
00774     static_expr_dealloc( curr->range->left,  FALSE );
00775     static_expr_dealloc( curr->range->right, FALSE );
00776     free_safe( curr->range, sizeof( vector_width ) );
00777     curr->range = NULL;
00778 
00779     /* Copy and deallocate instance name */
00780     name_copy = strdup_safe( curr->name );
00781     free_safe( curr->name, (strlen( curr->name ) + 1) );
00782 
00783     /* For the first instance, just modify the name */
00784     slen     = strlen( name_copy ) + 23;
00785     new_name = (char*)malloc_safe( slen );
00786     rv = snprintf( new_name, slen, "%s[%d]", name_copy, lsb );
00787     assert( rv < slen );
00788     curr->name = strdup_safe( new_name );
00789 
00790     /* For all of the rest of the instances, do the instance_parse_add function call */
00791     for( i=1; i<width; i++ ) {
00792 
00793       /* Create the new name */
00794       rv = snprintf( new_name, slen, "%s[%d]", name_copy, (lsb + i) );
00795       assert( rv < slen );
00796 
00797       /* Add the instance */
00798       (void)instance_parse_add( &root, ((curr->parent == NULL) ? NULL : curr->parent->funit), curr->funit, new_name, NULL, TRUE, FALSE, FALSE, FALSE );
00799 
00800     }
00801 
00802     /* Deallocate the new_name and name_copy pointers */
00803     free_safe( name_copy, (strlen( name_copy ) + 1) );
00804     free_safe( new_name, slen );
00805 
00806   }
00807 
00808   PROFILE_END;
00809   
00810   return( width != 0 );
00811 
00812 }


Variable Documentation

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).

db** db_list
 

Array of database pointers storing all currently loaded databases.

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.


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