scope.c File Reference

#include <stdlib.h>
#include <assert.h>
#include "defines.h"
#include "scope.h"
#include "link.h"
#include "instance.h"
#include "util.h"
#include "func_unit.h"
#include "gen_item.h"
#include "obfuscate.h"

Functions

static func_unitscope_find_funit_from_scope (const char *scope, func_unit *curr_funit, bool rm_unnamed)
bool scope_find_param (const char *name, func_unit *curr_funit, mod_parm **found_parm, func_unit **found_funit, int line)
 Find the given signal in the provided scope.
bool scope_find_signal (const char *name, func_unit *curr_funit, vsignal **found_sig, func_unit **found_funit, int line)
 Find the given signal in the provided scope.
bool scope_find_task_function_namedblock (const char *name, int type, func_unit *curr_funit, func_unit **found_funit, int line, bool must_find, bool rm_unnamed)
 Finds the given task or function in the provided scope.
func_unitscope_get_parent_funit (funit_inst *root, const char *scope)
 Finds the parent functional unit of the functional unit with the given scope.
func_unitscope_get_parent_module (funit_inst *root, const char *scope)
 Finds the parent module of the functional unit with the given scope.

Variables

db ** db_list
unsigned int curr_db
func_unitglobal_funit
char user_msg [USER_MSG_LENGTH]

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
11/10/2005

Function Documentation

static func_unit* scope_find_funit_from_scope ( const char *  scope,
func_unit curr_funit,
bool  rm_unnamed 
) [static]
Returns:
Returns a pointer to the functional unit being scoped if it can be found; otherwise, returns a value of NULL.

Searches the instance structure for the specified scope. Initially searches the tree assuming the user is attempting to do a relative hierarchical reference. If the reference is not relative, attempts a top-of-tree search. The specified scope should only be for a functional unit. If the user is attempting to get the functional unit for a signal, the signal name should be removed prior to calling this function.

Parameters:
scope Verilog hierachical scope to a functional unit
curr_funit Pointer to current functional unit whose member is calling this function
rm_unnamed Set to TRUE to cause unnamed scopes to be discarded

References curr_db, funit_inst_s::funit, inst_head, inst_link_find_by_funit(), instance_find_scope(), funit_inst_s::name, funit_inst_s::parent, PROFILE, and PROFILE_END.

Referenced by scope_find_param(), scope_find_signal(), and scope_find_task_function_namedblock().

00054   { PROFILE(SCOPE_FIND_FUNIT_FROM_SCOPE);
00055 
00056   funit_inst* curr_inst;      /* Pointer to current instance */
00057   funit_inst* funiti = NULL;  /* Pointer to functional unit instance found */
00058   int         ignore = 0;     /* Used for functional unit instance search */
00059   char        tscope[4096];   /* Temporary scope value */
00060 
00061   assert( curr_funit != NULL );
00062 
00063   /* Get current instance */
00064   if( (curr_inst = inst_link_find_by_funit( curr_funit, db_list[curr_db]->inst_head, &ignore )) != NULL ) {
00065 
00066     /* First check scope based on a relative path if unnamed scopes are not ignored */
00067     unsigned int rv = snprintf( tscope, 4096, "%s.%s", curr_inst->name, scope );
00068     assert( rv < 4096 );
00069     funiti = instance_find_scope( curr_inst, tscope, rm_unnamed );
00070 
00071     /*
00072      If we still did not find the functional unit, iterate up the scope tree looking for a module
00073      that matches.
00074     */
00075     if( funiti == NULL ) {
00076       do {
00077         if( curr_inst->parent == NULL ) {
00078           strcpy( tscope, scope );
00079           funiti = instance_find_scope( curr_inst, tscope, rm_unnamed );
00080           curr_inst = curr_inst->parent;
00081         } else {
00082           unsigned int rv;
00083           curr_inst = curr_inst->parent;
00084           rv = snprintf( tscope, 4096, "%s.%s", curr_inst->name, scope );
00085           assert( rv < 4096 );
00086           funiti = instance_find_scope( curr_inst, tscope, rm_unnamed );
00087         }
00088       } while( (curr_inst != NULL) && (funiti == NULL) );
00089     }
00090 
00091   }
00092 
00093   PROFILE_END;
00094 
00095   return( (funiti == NULL) ? NULL : funiti->funit );
00096 
00097 }

bool scope_find_param ( const char *  name,
func_unit curr_funit,
mod_parm **  found_parm,
func_unit **  found_funit,
int  line 
)

Find the given signal in the provided scope.

Returns:
Returns TRUE if specified signal was found in the design; otherwise, returns FALSE.
Exceptions:
anonymous Throw

Searches for a given parameter in the design starting with the functional unit in which the parameter is being accessed from. Attempts to find the parameter locally (if the name is not hierarchically referenced); otherwise, performs relative referencing to find the parameter. If the parameter is found, the found_parm and found_funit pointers are set to the found module parameter and its functional unit; otherwise, a value of FALSE is returned to the calling function.

Parameters:
name Name of parameter to find in design
curr_funit Pointer to current functional unit to start searching in
found_parm Pointer to module parameter that has been found in the design
found_funit Pointer to found signal's functional unit
line Line number where signal is being used (used for error output)

References Catch_anonymous, FATAL, func_unit_s::filename, free_safe, funit_find_param(), get_funit_type(), malloc_safe, func_unit_s::name, obf_file, obf_funit, obf_sig, print_output(), PROFILE, PROFILE_END, scope_extract_back(), scope_find_funit_from_scope(), scope_local(), strdup_safe, Throw, TRUE, Try, func_unit_s::type, user_msg, and USER_MSG_LENGTH.

Referenced by bind_param().

00116   { PROFILE(SCOPE_FIND_PARAM);
00117 
00118   char* parm_name;  /* Parameter basename holder */
00119   char* scope;      /* Parameter scope holder */
00120 
00121   assert( curr_funit != NULL );
00122 
00123   *found_funit = curr_funit;
00124   parm_name    = strdup_safe( name );
00125 
00126   Try {
00127 
00128     /* If there is a hierarchical reference being made, adjust the signal name and current functional unit */
00129     if( !scope_local( name ) ) {
00130 
00131       scope = (char *)malloc_safe( strlen( name ) + 1 );
00132 
00133       Try {
00134 
00135         /* Extract the signal name from its scope */
00136         scope_extract_back( name, parm_name, scope );
00137 
00138         /* Get the functional unit that contains this signal */
00139         if( (*found_funit = scope_find_funit_from_scope( scope, curr_funit, TRUE )) == NULL ) {
00140 
00141           if( line > 0 ) {
00142             unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Referencing undefined signal hierarchy (%s) in %s %s, file %s, line %d",
00143                                         obf_sig( name ), get_funit_type( curr_funit->type ), obf_funit( curr_funit->name ),
00144                                         obf_file( curr_funit->filename ), line );
00145             assert( rv < USER_MSG_LENGTH );
00146             print_output( user_msg, FATAL, __FILE__, __LINE__ );
00147             Throw 0;
00148           }
00149  
00150         }
00151 
00152       } Catch_anonymous {
00153         free_safe( scope, (strlen( name ) + 1) );
00154         Throw 0;
00155       }
00156 
00157       free_safe( scope, (strlen( name ) + 1) );
00158 
00159     }
00160 
00161     /* Get the module parameter, if it exists */
00162     *found_parm = funit_find_param( parm_name, *found_funit );
00163 
00164     /* If we could not find the module parameter in the found_funit, search the global funit, if it exists */
00165     if( (*found_parm == NULL) && (global_funit != NULL) ) {
00166       *found_funit = global_funit;
00167       *found_parm  = funit_find_param( parm_name, *found_funit );
00168     }
00169 
00170   } Catch_anonymous {
00171     free_safe( parm_name, (strlen( name ) + 1) );
00172     Throw 0;
00173   }
00174 
00175   free_safe( parm_name, (strlen( name ) + 1) );
00176 
00177   PROFILE_END;
00178 
00179   return( *found_parm != NULL );
00180 
00181 }

bool scope_find_signal ( const char *  name,
func_unit curr_funit,
vsignal **  found_sig,
func_unit **  found_funit,
int  line 
)

Find the given signal in the provided scope.

Returns:
Returns TRUE if specified signal was found in the design; otherwise, returns FALSE.
Exceptions:
anonymous Throw

Searches for a given signal in the design starting with the functional unit in which the signal is being accessed from. Attempts to find the signal locally (if the signal name is not hierarchically referenced); otherwise, performs relative referencing to find the signal. If the signal is found the found_sig and found_funit pointers are set to the found signal and its functional unit; otherwise, a value of FALSE is returned to the calling function.

Parameters:
name Name of signal to find in design
curr_funit Pointer to current functional unit to start searching in
found_sig Pointer to signal that has been found in the design
found_funit Pointer to found signal's functional unit
line Line number where signal is being used (used for error output)

References Catch_anonymous, FATAL, func_unit_s::filename, free_safe, funit_find_signal(), get_funit_type(), malloc_safe, func_unit_s::name, obf_file, obf_funit, obf_sig, func_unit_s::parent, print_output(), PROFILE, PROFILE_END, scope_extract_back(), scope_find_funit_from_scope(), scope_local(), strdup_safe, Throw, TRUE, Try, func_unit_s::type, user_msg, and USER_MSG_LENGTH.

Referenced by bind_find_sig_name(), bind_signal(), covered_create_value_change_cb(), db_assign_symbol(), db_find_signal(), and gen_item_resolve().

00199   { PROFILE(SCOPE_FIND_SIGNAL);
00200 
00201   char* sig_name;  /* Signal basename holder */
00202   char* scope;     /* Signal scope holder */
00203 
00204   assert( curr_funit != NULL );
00205 
00206   *found_funit = curr_funit;
00207   *found_sig   = NULL;
00208 
00209   sig_name = strdup_safe( name );
00210 
00211   Try {
00212 
00213     /* If there is a hierarchical reference being made, adjust the signal name and current functional unit */
00214     if( !scope_local( name ) ) {
00215 
00216       scope = (char *)malloc_safe( strlen( name ) + 1 );
00217 
00218       Try {
00219 
00220         /* Extract the signal name from its scope */
00221         scope_extract_back( name, sig_name, scope );
00222 
00223         /* Get the functional unit that contains this signal */
00224         if( (*found_funit = scope_find_funit_from_scope( scope, curr_funit, TRUE )) == NULL ) {
00225 
00226           if( line > 0 ) {
00227             unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Referencing undefined signal hierarchy (%s) in %s %s, file %s, line %d",
00228                                         obf_sig( name ), get_funit_type( curr_funit->type ), obf_funit( curr_funit->name ),
00229                                         obf_file( curr_funit->filename ), line );
00230             assert( rv < USER_MSG_LENGTH );
00231             print_output( user_msg, FATAL, __FILE__, __LINE__ );
00232             Throw 0;
00233           }
00234  
00235         }
00236 
00237       } Catch_anonymous {
00238         free_safe( scope, (strlen( name ) + 1) );
00239         Throw 0;
00240       }
00241 
00242       free_safe( scope, (strlen( name ) + 1) );
00243 
00244     }
00245 
00246     if( *found_funit != NULL ) {
00247 
00248       /* First, look in the current functional unit */
00249       if( (*found_sig = funit_find_signal( sig_name, *found_funit )) == NULL ) {
00250   
00251         /* Continue to look in parent modules (if there are any) */
00252         *found_funit = (*found_funit)->parent;
00253         while( (*found_funit != NULL) && ((*found_sig = funit_find_signal( sig_name, *found_funit )) == NULL) ) {
00254           *found_funit = (*found_funit)->parent;
00255         }
00256 
00257         /* If we could still not find the signal, look in the global funit, if it exists */
00258         if( (*found_sig == NULL) && (global_funit != NULL) ) {
00259           *found_funit = global_funit;
00260           *found_sig = funit_find_signal( sig_name, *found_funit );
00261         }
00262 
00263       }
00264 
00265     }
00266 
00267   } Catch_anonymous {
00268     free_safe( sig_name, (strlen( name ) + 1) );
00269     Throw 0;
00270   }
00271 
00272   free_safe( sig_name, (strlen( name ) + 1) );
00273 
00274   PROFILE_END;
00275 
00276   return( *found_sig != NULL );
00277 
00278 }

bool scope_find_task_function_namedblock ( const char *  name,
int  type,
func_unit curr_funit,
func_unit **  found_funit,
int  line,
bool  must_find,
bool  rm_unnamed 
)

Finds the given task or function in the provided scope.

Returns:
Returns TRUE if the functional unit was found in the design; otherwise, returns FALSE.
Exceptions:
anonymous Throw

Searches the design for the specified functional unit based on its scoped name. If the functional unit is found, the found_funit pointer is set to the functional unit and the function returns TRUE; otherwise, the function returns FALSE to the calling function.

Parameters:
name Name of functional unit to find based on scope information
type Type of functional unit to find
curr_funit Pointer to the functional unit which needs to bind to this functional unit
found_funit Pointer to found functional unit within the design
line Line number where functional unit is being used (for error output purposes only)
must_find Set to TRUE if the scope MUST be found
rm_unnamed Set to TRUE if unnamed scopes should be ignored

References FATAL, func_unit_s::filename, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, FUNIT_FUNCTION, FUNIT_NAMED_BLOCK, FUNIT_TASK, get_funit_type(), func_unit_s::name, obf_file, obf_funit, print_output(), PROFILE, PROFILE_END, scope_find_funit_from_scope(), Throw, func_unit_s::type, user_msg, and USER_MSG_LENGTH.

Referenced by bind_task_function_namedblock().

00297   { PROFILE(SCOPE_FIND_TASK_FUNCTION_NAMEDBLOCK);
00298 
00299   assert( (type == FUNIT_FUNCTION)  || (type == FUNIT_TASK)  || (type == FUNIT_NAMED_BLOCK) ||
00300           (type == FUNIT_AFUNCTION) || (type == FUNIT_ATASK) || (type == FUNIT_ANAMED_BLOCK) );
00301   assert( curr_funit != NULL );
00302 
00303   /*
00304    Find the functional unit that refers to this scope.
00305   */
00306   if( ((*found_funit = scope_find_funit_from_scope( name, curr_funit, rm_unnamed )) == NULL) && must_find ) {
00307 
00308     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Referencing undefined %s hierarchy (%s) in %s %s, file %s, line %d",
00309                                 get_funit_type( type ), obf_funit( name ), get_funit_type( curr_funit->type ),
00310                                 obf_funit( curr_funit->name ), obf_file( curr_funit->filename ), line );
00311     assert( rv < USER_MSG_LENGTH );
00312     print_output( user_msg, FATAL, __FILE__, __LINE__ );
00313     Throw 0;
00314 
00315   }
00316 
00317   PROFILE_END;
00318 
00319   return( *found_funit != NULL );
00320 
00321 }

func_unit* scope_get_parent_funit ( funit_inst root,
const char *  scope 
)

Finds the parent functional unit of the functional unit with the given scope.

Returns:
Returns a pointer to the parent functional unit of this functional unit.
Note:
This function should only be called when the scope refers to a functional unit that is NOT a module!
Parameters:
root Pointer to root of instance tree to search
scope Scope of current functional unit to get parent functional unit for

References free_safe, funit_inst_s::funit, instance_find_scope(), malloc_safe, PROFILE, PROFILE_END, scope_extract_back(), and TRUE.

Referenced by db_read().

00332   { PROFILE(SCOPE_GET_PARENT_FUNIT);
00333 
00334   funit_inst* inst;     /* Pointer to functional unit instance with the specified scope */
00335   char*       rest;     /* Temporary holder */
00336   char*       back;     /* Temporary holder */
00337   int         str_len;  /* Length of string to allocated/deallocate */
00338 
00339   /* Calculate the str_len */
00340   str_len = strlen( scope ) + 1;
00341 
00342   rest = (char*)malloc_safe( str_len );
00343   back = (char*)malloc_safe( str_len );
00344 
00345   /* Go up one in hierarchy */
00346   scope_extract_back( scope, back, rest );
00347 
00348   assert( rest != '\0' );
00349 
00350   /* Get functional instance for the rest of the scope */
00351   inst = instance_find_scope( root, rest, TRUE );
00352 
00353   assert( inst != NULL );
00354 
00355   free_safe( rest, str_len );
00356   free_safe( back, str_len );
00357 
00358   PROFILE_END;
00359 
00360   return( inst->funit );
00361 
00362 }

func_unit* scope_get_parent_module ( funit_inst root,
const char *  scope 
)

Finds the parent module of the functional unit with the given scope.

Returns:
Returns pointer to module that is the parent of the specified functional unit.
Note:
Assumes that the given scope is not that of a module itself!
Parameters:
root Pointer to root of instance tree to search
scope Full hierarchical scope of functional unit to find parent module for

References free_safe, funit_inst_s::funit, FUNIT_MODULE, instance_find_scope(), PROFILE, PROFILE_END, scope_extract_back(), strdup_safe, TRUE, and func_unit_s::type.

Referenced by db_read().

00372   { PROFILE(SCOPE_GET_PARENT_MODULE);
00373 
00374   funit_inst* inst;        /* Pointer to functional unit instance with the specified scope */
00375   char*       curr_scope;  /* Current scope to search for */
00376   char*       rest;        /* Temporary holder */
00377   char*       back;        /* Temporary holder */
00378   int         str_len;     /* Length of string to allocate */
00379 
00380   assert( scope != NULL );
00381 
00382   /* Calculate the length of the string */
00383   str_len = strlen( scope ) + 1;
00384 
00385   /* Get a local copy of the specified scope */
00386   curr_scope = strdup_safe( scope );
00387   rest       = strdup_safe( scope );
00388   back       = strdup_safe( scope );
00389 
00390   do {
00391     scope_extract_back( curr_scope, back, rest );
00392     assert( rest[0] != '\0' );
00393     strcpy( curr_scope, rest );
00394     inst = instance_find_scope( root, curr_scope, TRUE );
00395     assert( inst != NULL );
00396   } while( inst->funit->type != FUNIT_MODULE );
00397 
00398   free_safe( curr_scope, str_len );
00399   free_safe( rest,       str_len );
00400   free_safe( back,       str_len );
00401 
00402   PROFILE_END;
00403 
00404   return( inst->funit );
00405 
00406 }


Variable Documentation

unsigned int curr_db

Index of current database in db_list array that is being handled.

Array of database pointers storing all currently loaded databases.

Pointer to the global function unit that is available in SystemVerilog.

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 Sun Nov 21 00:55:40 2010 for Covered by  doxygen 1.6.3