#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_unit * | scope_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_unit * | scope_get_parent_funit (funit_inst *root, const char *scope) |
Finds the parent functional unit of the functional unit with the given scope. | |
func_unit * | scope_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_unit * | global_funit |
char | user_msg [USER_MSG_LENGTH] |
static func_unit* scope_find_funit_from_scope | ( | const char * | scope, | |
func_unit * | curr_funit, | |||
bool | rm_unnamed | |||
) | [static] |
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 }
unsigned int curr_db |
Index of current database in db_list array that is being handled.
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.