Contains functions for writing and reading contents of covered database file. More...
#include "defines.h"
Go to the source code of this file.
Functions | |
db * | db_create () |
Creates a new database. | |
void | db_close () |
Deallocates all memory consumed by the database. | |
bool | db_check_for_top_module () |
Checks to see if the module specified by the -t option is the top-level module of the simulator. | |
void | db_write (const char *file, bool parse_mode, bool issue_ids) |
Writes contents of expressions, functional units and vsignals to database file. | |
bool | db_read (const char *file, int read_mode) |
Reads contents of database file and stores into internal lists. | |
void | db_merge_instance_trees () |
Merges the current instance trees. | |
uint64 | db_scale_to_precision (uint64 value, func_unit *funit) |
Returns a scaled version of the given value to the timescale for the given functional unit. | |
void | db_set_timescale (int unit, int precision) |
Sets the global timescale unit and precision variables. | |
func_unit * | db_get_curr_funit () |
Returns a pointer to the current functional unit. | |
unsigned int | db_get_exclusion_id_size () |
Calculates and returns the size of the exclusion ID string. | |
char * | db_gen_exclusion_id (char type, int id) |
Allocates memory for and generates the exclusion identifier. | |
char * | db_create_unnamed_scope () |
Creates a scope name for an unnamed scope. Called only during parsing. | |
bool | db_is_unnamed_scope (char *scope) |
Returns TRUE if the given scope is an unnamed scope name; otherwise, returns FALSE. | |
void | db_add_file_version (const char *file, const char *version) |
Adds the given filename and version information to the database. | |
void | db_output_dumpvars (FILE *vfile) |
Outputs all needed signals in $dumpvars calls to the specified file. | |
func_unit * | db_add_instance (char *scope, char *name, int type, vector_width *range) |
Adds specified functional unit node to functional unit tree. Called by parser. | |
void | db_add_module (char *name, char *file, int start_line) |
Adds specified module to module list. Called by parser. | |
bool | db_add_function_task_namedblock (int type, char *name, char *file, int start_line) |
Adds specified task/function to functional unit list. Called by parser. | |
void | db_end_function_task_namedblock (int end_line) |
Performs actions necessary when the end of a function/task/named-block is seen. Called by parser. | |
void | db_add_declared_param (bool is_signed, static_expr *msb, static_expr *lsb, char *name, expression *expr, bool local) |
Adds specified declared parameter to parameter list. Called by parser. | |
void | db_add_override_param (char *inst_name, expression *expr, char *param_name) |
Adds specified override parameter to parameter list. Called by parser. | |
void | db_add_defparam (char *name, expression *expr) |
Adds specified defparam to parameter override list. Called by parser. | |
void | db_add_signal (char *name, int type, sig_range *prange, sig_range *urange, bool is_signed, bool mba, int line, int col, bool handled) |
Adds specified vsignal to vsignal list. Called by parser. | |
statement * | db_add_fork_join (statement *stmt) |
Creates statement block that acts like a fork join block from a standard statement block. | |
void | db_add_enum (vsignal *enum_sig, static_expr *value) |
Creates an enumerated list based on the given parameters. | |
void | db_end_enum_list () |
Called after all enumerated values for the current list have been added. | |
void | db_add_typedef (const char *name, bool is_signed, bool is_handled, bool is_sizable, sig_range *prange, sig_range *urange) |
Adds given typedefs to the database. | |
void | db_end_module (int end_line) |
Called when the endmodule keyword is parsed. | |
void | db_end_function_task (int end_line) |
Called when the endfunction or endtask keyword is parsed. | |
vsignal * | db_find_signal (char *name, bool okay_if_not_found) |
Finds specified signal in functional unit and returns pointer to the signal structure. Called by parser. | |
void | db_add_gen_item_block (gen_item *gi) |
Adds a generate block to the database. Called by parser. | |
gen_item * | db_find_gen_item (gen_item *root, gen_item *gi) |
Find specified generate item in the current functional unit. Called by parser. | |
typedef_item * | db_find_typedef (const char *name) |
Finds specified typedef and returns TRUE if it is found. | |
gen_item * | db_get_curr_gen_block () |
Returns a pointer to the current implicitly connected generate block. Called by parser. | |
expression * | db_create_expression (expression *right, expression *left, exp_op_type op, bool lhs, int line, int first, int last, char *sig_name) |
Creates new expression from specified information. Called by parser and db_add_expression. | |
void | db_bind_expr_tree (expression *root, char *sig_name) |
Binds all necessary sub-expressions in the given tree to the given signal name. | |
expression * | db_create_expr_from_static (static_expr *se, int line, int first_col, int last_col) |
Creates an expression from the specified static expression. | |
void | db_add_expression (expression *root) |
Adds specified expression to expression list. Called by parser. | |
expression * | db_create_sensitivity_list (statement *stmt) |
Creates an expression tree sensitivity list for the given statement block. | |
statement * | db_parallelize_statement (statement *stmt) |
Checks specified statement for parallelization and if it must be, creates a parallel statement block. | |
statement * | db_create_statement (expression *exp, unsigned int ppline) |
Creates new statement expression from specified information. Called by parser. | |
void | db_add_statement (statement *stmt, statement *start) |
Adds specified statement to current functional unit's statement list. Called by parser. | |
void | db_remove_statement_from_current_funit (statement *stmt) |
Removes specified statement from current functional unit. | |
void | db_remove_statement (statement *stmt) |
Removes specified statement and associated expression from list and memory. | |
void | db_gen_item_connect_true (gen_item *gi1, gen_item *gi2) |
Connects gi2 to the true path of gi1. | |
void | db_gen_item_connect_false (gen_item *gi1, gen_item *gi2) |
Connects gi2 to the false path of gi1. | |
void | db_gen_item_connect (gen_item *gi1, gen_item *gi2) |
Connects one generate item block to another. | |
bool | db_statement_connect (statement *curr_stmt, statement *next_stmt) |
Connects one statement block to another. | |
void | db_connect_statement_true (statement *stmt, statement *exp_true) |
Connects true statement to specified statement. | |
void | db_connect_statement_false (statement *stmt, statement *exp_false) |
Connects false statement to specified statement. | |
attr_param * | db_create_attr_param (char *name, expression *expr) |
Allocates and initializes an attribute parameter. | |
void | db_parse_attribute (attr_param *ap, int line) |
Parses the specified attribute parameter list for Covered attributes. | |
void | db_remove_stmt_blks_calling_statement (statement *stmt) |
Searches entire design for expressions that call the specified statement. | |
void | db_sync_curr_instance () |
Synchronizes the curr_instance pointer to match the curr_inst_scope hierarchy. | |
void | db_set_vcd_scope (const char *scope) |
Sets current VCD scope to specified scope. | |
void | db_vcd_upscope () |
Moves current VCD hierarchy up one level. | |
void | db_assign_symbol (const char *name, const char *symbol, int msb, int lsb) |
Adds symbol to signal specified by name. | |
void | db_set_symbol_char (const char *sym, char value) |
Sets the found symbol value to specified character value. Called by VCD lexer. | |
void | db_set_symbol_string (const char *sym, const char *value) |
Sets the found symbol value to specified string value. Called by VCD lexer. | |
bool | db_do_timestep (uint64 time, bool final) |
Performs a timestep for all signal changes during this timestep. | |
void | db_check_dumpfile_scopes () |
Called after all signals are parsed from dumpfile. Checks to see if dumpfile results were correct for the covered design. |
Contains functions for writing and reading contents of covered database file.
void db_add_declared_param | ( | bool | is_signed, | |
static_expr * | msb, | |||
static_expr * | lsb, | |||
char * | name, | |||
expression * | expr, | |||
bool | local | |||
) |
Adds specified declared parameter to parameter list. Called by parser.
Searches current module to verify that specified parameter name has not been previously used in the module. If the parameter name has not been found, it is created added to the current module's parameter list.
is_signed | Specified if the declared parameter needs to be handled as a signed value | |
msb | Static expression containing MSB of this declared parameter | |
lsb | Static expression containing LSB of this declared parameter | |
name | Name of declared parameter to add | |
expr | Expression containing value of this parameter | |
local | If TRUE, specifies that this parameter is a local parameter |
References DEBUG, debug_mode, expression_s::id, mod_parm_add(), mod_parm_find(), obf_sig, func_unit_s::param_head, PARAM_TYPE_DECLARED, PARAM_TYPE_DECLARED_LOCAL, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
01316 { PROFILE(DB_ADD_DECLARED_PARAM); 01317 01318 assert( name != NULL ); 01319 01320 /* If a parameter value type is not supported, don't create this parameter */ 01321 if( expr != NULL ) { 01322 01323 #ifdef DEBUG_MODE 01324 if( debug_mode ) { 01325 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_declared_param, param: %s, expr: %d, local: %d", obf_sig( name ), expr->id, local ); 01326 assert( rv < USER_MSG_LENGTH ); 01327 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01328 } 01329 #endif 01330 01331 if( mod_parm_find( name, curr_funit->param_head ) == NULL ) { 01332 01333 /* Add parameter to module parameter list */ 01334 (void)mod_parm_add( name, msb, lsb, is_signed, expr, (local ? PARAM_TYPE_DECLARED_LOCAL : PARAM_TYPE_DECLARED), curr_funit, NULL ); 01335 01336 } 01337 01338 } 01339 01340 PROFILE_END; 01341 01342 }
void db_add_defparam | ( | char * | name, | |
expression * | expr | |||
) |
Adds specified defparam to parameter override list. Called by parser.
Adds specified parameter to the defparam list.
name | Name of parameter value to override | |
expr | Expression value of parameter override |
References DEBUG, debug_mode, expression_dealloc(), FALSE, expression_s::line, obf_sig, print_output(), PROFILE, PROFILE_END, user_msg, USER_MSG_LENGTH, and WARNING.
01418 { PROFILE(DB_ADD_DEFPARAM); 01419 01420 #ifdef DEBUG_MODE 01421 if( debug_mode ) { 01422 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_defparam, defparam: %s", obf_sig( name ) ); 01423 assert( rv < USER_MSG_LENGTH ); 01424 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01425 } 01426 #endif 01427 01428 { 01429 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "defparam construct is not supported, line: %d. Use -P option to score instead", expr->line ); 01430 assert( rv < USER_MSG_LENGTH ); 01431 print_output( user_msg, WARNING, __FILE__, __LINE__ ); 01432 } 01433 01434 expression_dealloc( expr, FALSE ); 01435 01436 PROFILE_END; 01437 01438 }
void db_add_enum | ( | vsignal * | enum_sig, | |
static_expr * | value | |||
) |
Creates an enumerated list based on the given parameters.
Allocates and adds an enum_item to the current module's list to be elaborated later.
enum_sig | Pointer to signal created for the given enumerated value | |
value | Value to later assign to the enum_sig (during elaboration) |
References DEBUG, debug_mode, enumerate_add_item(), vsignal_s::name, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
01598 { PROFILE(DB_ADD_ENUM); 01599 01600 assert( enum_sig != NULL ); 01601 01602 #ifdef DEBUG_MODE 01603 if( debug_mode ) { 01604 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_enum, sig_name: %s", enum_sig->name ); 01605 assert( rv < USER_MSG_LENGTH ); 01606 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01607 } 01608 #endif 01609 01610 enumerate_add_item( enum_sig, value, curr_funit ); 01611 01612 PROFILE_END; 01613 01614 }
void db_add_expression | ( | expression * | root | ) |
Adds specified expression to expression list. Called by parser.
Adds the specified expression to the current module's expression list.
root | Pointer to root expression to add to module expression list |
References db_add_expression(), db_gen_item_connect(), DEBUG, debug_mode, esuppl_u::exp_added, func_unit_s::exp_head, exp_link_add(), func_unit_s::exp_tail, expression_string_op(), esuppl_u::gen_expr, gen_item_create_expr(), generate_top_mode, expression_s::id, expression_s::left, expression_s::line, expression_s::op, esuppl_u::part, print_output(), PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, user_msg, and USER_MSG_LENGTH.
Referenced by db_add_expression(), db_add_statement(), fsm_var_add_expr(), and parser_handle_generate_case_statement().
02131 { PROFILE(DB_ADD_EXPRESSION); 02132 02133 if( (root != NULL) && (root->suppl.part.exp_added == 0) ) { 02134 02135 #ifdef DEBUG_MODE 02136 if( debug_mode ) { 02137 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_expression, id: %d, op: %s, line: %d", 02138 root->id, expression_string_op( root->op ), root->line ); 02139 assert( rv < USER_MSG_LENGTH ); 02140 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02141 } 02142 #endif 02143 02144 if( generate_top_mode > 0 ) { 02145 02146 if( root->suppl.part.gen_expr == 1 ) { 02147 02148 /* Add root expression to the generate item list for the current functional unit */ 02149 last_gi = gen_item_create_expr( root ); 02150 02151 /* Attach it to the curr_gi_block, if one exists */ 02152 if( curr_gi_block != NULL ) { 02153 db_gen_item_connect( curr_gi_block, last_gi ); 02154 } else { 02155 curr_gi_block = last_gi; 02156 } 02157 02158 } 02159 02160 } else { 02161 02162 /* Add expression's children first. */ 02163 db_add_expression( root->right ); 02164 db_add_expression( root->left ); 02165 02166 /* Now add this expression to the list. */ 02167 exp_link_add( root, &(curr_funit->exp_head), &(curr_funit->exp_tail) ); 02168 02169 } 02170 02171 /* Specify that this expression has already been added */ 02172 root->suppl.part.exp_added = 1; 02173 02174 } 02175 02176 PROFILE_END; 02177 02178 }
void db_add_file_version | ( | const char * | file, | |
const char * | version | |||
) |
Adds the given filename and version information to the database.
file | Name of file to set version information to | |
version | Name of file version |
References curr_db, DEBUG, debug_mode, obf_file, print_output(), PROFILE, PROFILE_END, str_link_s::str2, str_link_add(), strdup_safe, user_msg, and USER_MSG_LENGTH.
00972 { PROFILE(DB_ADD_FILE_VERSION); 00973 00974 str_link* strl; 00975 00976 #ifdef DEBUG_MODE 00977 if( debug_mode ) { 00978 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_file_version, file: %s, version: %s", obf_file( file ), version ); 00979 assert( rv < USER_MSG_LENGTH ); 00980 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00981 } 00982 #endif 00983 00984 /* Add the new file version information */ 00985 strl = str_link_add( strdup_safe( file ), &(db_list[curr_db]->fver_head), &(db_list[curr_db]->fver_tail) ); 00986 strl->str2 = strdup_safe( version ); 00987 00988 PROFILE_END; 00989 00990 }
Creates statement block that acts like a fork join block from a standard statement block.
bool db_add_function_task_namedblock | ( | int | type, | |
char * | name, | |||
char * | file, | |||
int | start_line | |||
) |
Adds specified task/function to functional unit list. Called by parser.
anonymous | Throw |
Creates a new function, task or named block scope and adds it to the instance tree. Also sets the curr_funit global pointer to point to this new functional unit.
type | Specifies type of functional unit being added (function, task or named_block) | |
name | Name of functional unit | |
file | File containing the specified functional unit | |
start_line | Starting line number of functional unit |
References Catch_anonymous, current_timescale_unit, db_add_instance(), DEBUG, debug_mode, func_unit_s::filename, free_safe, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, FUNIT_FUNCTION, funit_gen_task_function_namedblock_name(), funit_get_curr_module(), funit_link_add(), FUNIT_NAMED_BLOCK, FUNIT_TASK, generate_expr_mode, get_funit_type(), GI_TYPE_TFN, obf_file, obf_funit, func_unit_s::parent, gen_item_s::part, print_output(), PROFILE, PROFILE_END, func_unit_s::start_line, strdup_safe, gen_item_s::suppl, func_unit_s::tf_head, func_unit_s::tf_tail, Throw, Try, func_unit_s::ts_unit, func_unit_s::type, user_msg, and USER_MSG_LENGTH.
Referenced by db_parallelize_statement().
01204 { PROFILE(DB_ADD_FUNCTION_TASK_NAMEDBLOCK); 01205 01206 func_unit* tf = NULL; /* Pointer to created functional unit */ 01207 func_unit* parent; /* Pointer to parent module for the newly created functional unit */ 01208 char* full_name; /* Full name of function/task/namedblock which includes the parent module name */ 01209 01210 assert( (type == FUNIT_FUNCTION) || (type == FUNIT_TASK) || (type == FUNIT_NAMED_BLOCK) || 01211 (type == FUNIT_AFUNCTION) || (type == FUNIT_ATASK) ); 01212 01213 #ifdef DEBUG_MODE 01214 if( debug_mode ) { 01215 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_function_task_namedblock, %s: %s, file: %s, start_line: %d", 01216 get_funit_type( type ), obf_funit( name ), obf_file( file ), start_line ); 01217 assert( rv < USER_MSG_LENGTH ); 01218 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01219 } 01220 #endif 01221 01222 /* Generate full name to use for the function/task */ 01223 full_name = funit_gen_task_function_namedblock_name( name, curr_funit ); 01224 01225 Try { 01226 01227 /* Add this as an instance so we can get scope */ 01228 if( (tf = db_add_instance( name, full_name, type, NULL )) != NULL ) { 01229 01230 /* Get parent */ 01231 parent = funit_get_curr_module( curr_funit ); 01232 01233 if( generate_expr_mode > 0 ) { 01234 /* Change the recently created instance generate item to a TFN item */ 01235 last_gi->suppl.part.type = GI_TYPE_TFN; 01236 } else { 01237 /* Store this functional unit in the parent module list */ 01238 funit_link_add( tf, &(parent->tf_head), &(parent->tf_tail) ); 01239 } 01240 01241 /* Set our parent pointer to the current functional unit */ 01242 tf->parent = curr_funit; 01243 01244 /* If we are in an automatic task or function, set our type to FUNIT_ANAMED_BLOCK */ 01245 if( (curr_funit->type == FUNIT_AFUNCTION) || 01246 (curr_funit->type == FUNIT_ATASK) || 01247 (curr_funit->type == FUNIT_ANAMED_BLOCK) ) { 01248 assert( tf->type == FUNIT_NAMED_BLOCK ); 01249 tf->type = FUNIT_ANAMED_BLOCK; 01250 } 01251 01252 /* Set current functional unit to this functional unit */ 01253 curr_funit = tf; 01254 curr_funit->filename = strdup_safe( file ); 01255 curr_funit->start_line = start_line; 01256 curr_funit->ts_unit = current_timescale_unit; 01257 01258 } 01259 01260 } Catch_anonymous { 01261 free_safe( full_name, (strlen( full_name ) + 1) ); 01262 Throw 0; 01263 } 01264 01265 free_safe( full_name, (strlen( full_name ) + 1) ); 01266 01267 PROFILE_END; 01268 01269 return( tf != NULL ); 01270 01271 }
void db_add_gen_item_block | ( | gen_item * | gi | ) |
Adds a generate block to the database. Called by parser.
Adds the specified generate item block to the list of generate blocks for the current functional unit.
gi | Pointer to the head of a generate item block to add |
References func_unit_s::gitem_head, gitem_link_add(), func_unit_s::gitem_tail, PROFILE, and PROFILE_END.
01732 { PROFILE(DB_ADD_GEN_ITEM_BLOCK); 01733 01734 if( gi != NULL ) { 01735 01736 /* Add the generate block to the list of generate blocks for this functional unit */ 01737 gitem_link_add( gi, &(curr_funit->gitem_head), &(curr_funit->gitem_tail) ); 01738 01739 } 01740 01741 PROFILE_END; 01742 01743 }
func_unit* db_add_instance | ( | char * | scope, | |
char * | name, | |||
int | type, | |||
vector_width * | range | |||
) |
Adds specified functional unit node to functional unit tree. Called by parser.
anonymous | Throw |
Creates a new functional unit node with the instantiation name, search for matching functional unit. If functional unit hasn't been created previously, create it now without a filename associated (NULL). Add functional unit node to tree if there are no problems in doing so.
scope | Name of functional unit instance being added | |
name | Name of functional unit being instantiated | |
type | Type of functional unit being instantiated | |
range | Optional range (used for arrays of instances) |
References curr_db, db_gen_item_connect(), DEBUG, debug_mode, gen_item_s::elem, static_expr_s::exp, FALSE, FATAL, func_unit_s::filename, funit_link_s::funit, funit_create(), funit_dealloc(), funit_head, db_s::funit_head, funit_link_add(), funit_link_find(), FUNIT_MODULE, FUNIT_NO_SCORE, gen_item_create_inst(), generate_expr_mode, generate_top_mode, get_funit_type(), GI_TYPE_INST, inst_link_s::inst, gen_item_s::inst, db_s::inst_head, inst_link_add(), instance_create(), instance_parse_add(), vector_width_s::left, mod_parm_add(), func_unit_s::name, inst_link_s::next, obf_file, obf_funit, obf_inst, PARAM_TYPE_INST_LSB, PARAM_TYPE_INST_MSB, gen_item_s::part, print_output(), PROFILE, PROFILE_END, vector_width_s::right, str_link_add(), str_link_find(), strdup_safe, gen_item_s::suppl, Throw, TRUE, func_unit_s::type, user_msg, and USER_MSG_LENGTH.
Referenced by db_add_function_task_namedblock().
01025 { PROFILE(DB_ADD_INSTANCE); 01026 01027 func_unit* funit = NULL; /* Pointer to functional unit */ 01028 funit_link* found_funit_link; /* Pointer to found funit_link in functional unit list */ 01029 bool score; /* Specifies if this module should be scored */ 01030 01031 /* There should always be a parent so internal error if it does not exist. */ 01032 assert( curr_funit != NULL ); 01033 01034 /* If this functional unit name is in our list of no_score functional units, skip adding the instance */ 01035 score = str_link_find( name, no_score_head ) == NULL; 01036 01037 #ifdef DEBUG_MODE 01038 if( debug_mode ) { 01039 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_instance, instance: %s, %s: %s (curr_funit: %s)", 01040 obf_inst( scope ), get_funit_type( type ), obf_funit( name ), obf_funit( curr_funit->name ) ); 01041 assert( rv < USER_MSG_LENGTH ); 01042 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01043 } 01044 #endif 01045 01046 /* Create new functional unit node */ 01047 funit = funit_create(); 01048 funit->name = strdup_safe( name ); 01049 funit->type = score ? type : FUNIT_NO_SCORE; 01050 01051 /* If a range has been specified, calculate its width and lsb now */ 01052 if( (range != NULL) && score ) { 01053 if( (range->left != NULL) && (range->left->exp != NULL) ) { 01054 (void)mod_parm_add( NULL, NULL, NULL, FALSE, range->left->exp, PARAM_TYPE_INST_MSB, curr_funit, scope ); 01055 } 01056 if( (range->right != NULL) && (range->right->exp != NULL) ) { 01057 (void)mod_parm_add( NULL, NULL, NULL, FALSE, range->right->exp, PARAM_TYPE_INST_LSB, curr_funit, scope ); 01058 } 01059 } 01060 01061 if( ((found_funit_link = funit_link_find( funit->name, funit->type, db_list[curr_db]->funit_head )) != NULL) && (generate_top_mode == 0) ) { 01062 01063 if( type != FUNIT_MODULE ) { 01064 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Multiple identical task/function/named-begin-end names (%s) found in module %s, file %s", 01065 scope, obf_funit( curr_funit->name ), obf_file( curr_funit->filename ) ); 01066 assert( rv < USER_MSG_LENGTH ); 01067 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 01068 funit_dealloc( funit ); 01069 Throw 0; 01070 } 01071 01072 if( (last_gi == NULL) || (last_gi->suppl.part.type != GI_TYPE_INST) || 01073 !instance_parse_add( &last_gi->elem.inst, curr_funit, found_funit_link->funit, scope, range, FALSE, TRUE, FALSE, FALSE ) ) { 01074 inst_link* instl = db_list[curr_db]->inst_head; 01075 while( (instl != NULL) && !instance_parse_add( &instl->inst, curr_funit, found_funit_link->funit, scope, range, FALSE, FALSE, FALSE, FALSE ) ) { 01076 instl = instl->next; 01077 } 01078 if( instl == NULL ) { 01079 (void)inst_link_add( instance_create( found_funit_link->funit, scope, FALSE, FALSE, FALSE, range ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) ); 01080 } 01081 } 01082 01083 funit_dealloc( funit ); 01084 01085 } else { 01086 01087 /* Add new functional unit to functional unit list if we are not within a generate block. */ 01088 if( (found_funit_link == NULL) || (funit->type != FUNIT_MODULE) ) { 01089 funit_link_add( funit, &(db_list[curr_db]->funit_head), &(db_list[curr_db]->funit_tail) ); 01090 } 01091 01092 /* If we are currently within a generate block, create a generate item for this instance to resolve it later */ 01093 if( generate_top_mode > 0 ) { 01094 last_gi = gen_item_create_inst( instance_create( funit, scope, FALSE, FALSE, FALSE, range ) ); 01095 if( curr_gi_block != NULL ) { 01096 db_gen_item_connect( curr_gi_block, last_gi ); 01097 } else { 01098 curr_gi_block = last_gi; 01099 } 01100 } 01101 01102 /* Add the instance to the instance tree in the proper place */ 01103 { 01104 inst_link* instl = db_list[curr_db]->inst_head; 01105 while( (instl != NULL) && !instance_parse_add( &instl->inst, curr_funit, funit, scope, range, FALSE, FALSE, (generate_top_mode > 0), (generate_expr_mode > 0) ) ) { 01106 instl = instl->next; 01107 } 01108 if( instl == NULL ) { 01109 (void)inst_link_add( instance_create( funit, scope, FALSE, (generate_top_mode > 0), (generate_expr_mode > 0), range ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) ); 01110 } 01111 } 01112 01113 if( (type == FUNIT_MODULE) && score && (str_link_find( name, modlist_head ) == NULL) ) { 01114 (void)str_link_add( strdup_safe( name ), &modlist_head, &modlist_tail ); 01115 } 01116 01117 } 01118 01119 PROFILE_END; 01120 01121 return( score ? funit : NULL ); 01122 01123 }
void db_add_module | ( | char * | name, | |
char * | file, | |||
int | start_line | |||
) |
Adds specified module to module list. Called by parser.
Creates a new module element with the contents specified by the parameters given and inserts this module into the module list. This function can only be called when we are actually parsing a module which implies that we must have the name of the module at the head of the modlist linked-list structure.
name | Name of module being added to tree | |
file | Filename that module is a part of | |
start_line | Starting line number of this module in the file |
References curr_db, current_timescale_unit, DEBUG, debug_mode, func_unit_s::filename, funit_link_s::funit, funit_head, funit_link_find(), FUNIT_MODULE, obf_file, obf_funit, print_output(), PROFILE, PROFILE_END, func_unit_s::start_line, strdup_safe, func_unit_s::ts_unit, unnamed_scope_id, user_msg, and USER_MSG_LENGTH.
01135 { PROFILE(DB_ADD_MODULE); 01136 01137 funit_link* modl; /* Pointer to found tree node */ 01138 01139 #ifdef DEBUG_MODE 01140 if( debug_mode ) { 01141 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_module, module: %s, file: %s, start_line: %d", 01142 obf_funit( name ), obf_file( file ), start_line ); 01143 assert( rv < USER_MSG_LENGTH ); 01144 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01145 } 01146 #endif 01147 01148 modl = funit_link_find( name, FUNIT_MODULE, db_list[curr_db]->funit_head ); 01149 01150 assert( modl != NULL ); 01151 01152 curr_funit = modl->funit; 01153 curr_funit->filename = strdup_safe( file ); 01154 curr_funit->start_line = start_line; 01155 curr_funit->ts_unit = current_timescale_unit; 01156 01157 /* Clear the unnamed scope ID */ 01158 unnamed_scope_id = 0; 01159 01160 PROFILE_END; 01161 01162 }
void db_add_override_param | ( | char * | inst_name, | |
expression * | expr, | |||
char * | param_name | |||
) |
Adds specified override parameter to parameter list. Called by parser.
Creates override parameter and stores this in the current module as well as all associated instances.
inst_name | Name of instance being overridden | |
expr | Expression containing value of override parameter | |
param_name | Name of parameter being overridden (for parameter_value_byname syntax) |
References DEBUG, debug_mode, FALSE, mod_parm_add(), obf_inst, obf_sig, PARAM_TYPE_OVERRIDE, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
01352 { PROFILE(DB_ADD_OVERRIDE_PARAM); 01353 01354 #ifdef DEBUG_MODE 01355 if( debug_mode ) { 01356 unsigned int rv; 01357 if( param_name != NULL ) { 01358 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_override_param, instance: %s, param_name: %s", 01359 obf_inst( inst_name ), obf_sig( param_name ) ); 01360 } else { 01361 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_override_param, instance: %s", obf_inst( inst_name ) ); 01362 } 01363 assert( rv < USER_MSG_LENGTH ); 01364 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01365 } 01366 #endif 01367 01368 /* Add override parameter to module parameter list */ 01369 (void)mod_parm_add( param_name, NULL, NULL, FALSE, expr, PARAM_TYPE_OVERRIDE, curr_funit, inst_name ); 01370 01371 PROFILE_END; 01372 01373 }
void db_add_signal | ( | char * | name, | |
int | type, | |||
sig_range * | prange, | |||
sig_range * | urange, | |||
bool | is_signed, | |||
bool | mba, | |||
int | line, | |||
int | col, | |||
bool | handled | |||
) |
Adds specified vsignal to vsignal list. Called by parser.
Creates a new signal with the specified parameter information and adds this to the signal list if it does not already exist. If width == 0, the sig_msb and sig_lsb values are interrogated. If sig_msb and/or is non-NULL, its value is add to the current module's parameter list and all associated instances are updated to contain new value.
name | Name of signal being added | |
type | Type of signal being added | |
prange | Specifies packed signal range information | |
urange | Specifies unpacked signal range information | |
is_signed | Specifies that this signal is signed (TRUE) or not (FALSE) | |
mba | Set to TRUE if specified signal must be assigned by simulated results | |
line | Line number where signal was declared | |
col | Starting column where signal was declared | |
handled | Specifies if this signal is handled by Covered or not |
References ssuppl_u::assigned, db_add_vector_param(), db_gen_item_connect(), DEBUG, debug_mode, sig_range_s::dim, vsignal_s::dim, sig_range_s::dim_num, exclude_mode, ssuppl_u::excluded, static_expr_s::exp, sig_range_s::exp_dealloc, FALSE, free_safe, gen_item_create_sig(), generate_top_mode, vector_width_s::implicit, ssuppl_u::implicit_size, vsuppl_u::is_signed, vector_width_s::left, dim_range_s::lsb, malloc_safe, ssuppl_u::mba, dim_range_s::msb, ssuppl_u::not_handled, static_expr_s::num, obf_sig, PARAM_TYPE_SIG_LSB, PARAM_TYPE_SIG_MSB, vsuppl_u::part, ssuppl_u::part, vsignal_s::pdim_num, print_output(), PROFILE, PROFILE_END, vector_width_s::right, sig_link_s::sig, func_unit_s::sig_head, sig_link_add(), sig_link_find(), func_unit_s::sig_tail, SSUPPL_TYPE_DECL_REAL, SSUPPL_TYPE_DECL_SREAL, SSUPPL_TYPE_GENVAR, SSUPPL_TYPE_INOUT_NET, SSUPPL_TYPE_INOUT_REG, SSUPPL_TYPE_INPUT_NET, SSUPPL_TYPE_INPUT_REG, SSUPPL_TYPE_OUTPUT_NET, SSUPPL_TYPE_OUTPUT_REG, vector_s::suppl, vsignal_s::suppl, vsignal_s::udim_num, user_msg, USER_MSG_LENGTH, vsignal_s::value, and vsignal_create().
01457 { PROFILE(DB_ADD_SIGNAL); 01458 01459 vsignal* sig = NULL; /* Container for newly created signal */ 01460 sig_link* sigl; /* Pointer to found signal link */ 01461 unsigned int i; /* Loop iterator */ 01462 int j = 0; /* Loop iterator */ 01463 01464 #ifdef DEBUG_MODE 01465 if( debug_mode ) { 01466 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_signal, signal: %s, type: %d, line: %d, col: %d", obf_sig( name ), type, line, col ); 01467 assert( rv < USER_MSG_LENGTH ); 01468 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01469 } 01470 #endif 01471 01472 /* Add signal to current module's signal list if it does not already exist */ 01473 if( (sigl = sig_link_find( name, curr_funit->sig_head )) == NULL ) { 01474 01475 /* Create the signal */ 01476 if( (type == SSUPPL_TYPE_GENVAR) || (type == SSUPPL_TYPE_DECL_SREAL) ) { 01477 /* For genvars and shortreals, set the size to 32, automatically */ 01478 sig = vsignal_create( name, type, 32, line, col ); 01479 } else if( type == SSUPPL_TYPE_DECL_REAL ) { 01480 /* For real types, they should be automatically sized to 64, automatically */ 01481 sig = vsignal_create( name, type, 64, line, col ); 01482 } else { 01483 /* For normal signals just make the width a value of 1 for now -- it will be resized during funit_resize_elements */ 01484 sig = vsignal_create( name, type, 1, line, col ); 01485 } 01486 01487 assert( sig != NULL ); 01488 01489 /* If the signal has currently existed, check to see if the signal is unsized, and, if so, size it now */ 01490 } else if( sigl->sig->suppl.part.implicit_size ) { 01491 01492 sig = sigl->sig; 01493 sig->suppl.part.implicit_size = 0; 01494 01495 } 01496 01497 /* Check all of the dimensions within range and create vector parameters, if necessary */ 01498 if( sig != NULL ) { 01499 if( sig->dim != NULL ) { 01500 free_safe( sig->dim, (sizeof( dim_range ) * (sig->pdim_num + sig->udim_num)) ); 01501 } 01502 assert( prange != NULL ); 01503 sig->udim_num = (urange != NULL) ? urange->dim_num : 0; 01504 sig->pdim_num = prange->dim_num; 01505 assert( (sig->pdim_num + sig->udim_num) > 0 ); 01506 sig->dim = (dim_range*)malloc_safe( sizeof( dim_range ) * (sig->pdim_num + sig->udim_num) ); 01507 for( i=0; i<sig->udim_num; i++ ) { 01508 assert( urange->dim[i].left != NULL ); 01509 if( urange->dim[i].left->exp != NULL ) { 01510 db_add_vector_param( sig, urange->dim[i].left->exp, PARAM_TYPE_SIG_MSB, j ); 01511 } else { 01512 sig->dim[j].msb = urange->dim[i].left->num; 01513 } 01514 assert( urange->dim[i].right != NULL ); 01515 if( urange->dim[i].right->exp != NULL ) { 01516 db_add_vector_param( sig, urange->dim[i].right->exp, PARAM_TYPE_SIG_LSB, j ); 01517 } else { 01518 sig->dim[j].lsb = urange->dim[i].right->num; 01519 } 01520 j++; 01521 } 01522 for( i=0; i<sig->pdim_num; i++ ) { 01523 assert( prange->dim[i].left != NULL ); 01524 if( prange->dim[i].left->exp != NULL ) { 01525 db_add_vector_param( sig, prange->dim[i].left->exp, PARAM_TYPE_SIG_MSB, j ); 01526 } else { 01527 sig->dim[j].msb = prange->dim[i].left->num; 01528 } 01529 assert( prange->dim[i].right != NULL ); 01530 if( prange->dim[i].right->exp != NULL ) { 01531 db_add_vector_param( sig, prange->dim[i].right->exp, PARAM_TYPE_SIG_LSB, j ); 01532 } else { 01533 sig->dim[j].lsb = prange->dim[i].right->num; 01534 } 01535 j++; 01536 } 01537 01538 /* If exclude_mode is not zero, set the exclude bit in the signal */ 01539 sig->suppl.part.excluded = (exclude_mode > 0) ? 1 : 0; 01540 01541 /* Specify that we should not deallocate the expressions */ 01542 if( prange != NULL ) { 01543 prange->exp_dealloc = FALSE; 01544 } 01545 if( urange != NULL ) { 01546 urange->exp_dealloc = FALSE; 01547 } 01548 } 01549 01550 /* Only do the following if the signal was not previously found */ 01551 if( sigl == NULL ) { 01552 01553 /* Add the signal to either the functional unit or a generate item */ 01554 if( (generate_top_mode > 0) && (type != SSUPPL_TYPE_GENVAR) ) { 01555 last_gi = gen_item_create_sig( sig ); 01556 if( curr_gi_block != NULL ) { 01557 db_gen_item_connect( curr_gi_block, last_gi ); 01558 } else { 01559 curr_gi_block = last_gi; 01560 } 01561 } else { 01562 /* Add signal to current module's signal list */ 01563 sig_link_add( sig, &(curr_funit->sig_head), &(curr_funit->sig_tail) ); 01564 } 01565 01566 /* Indicate if signal must be assigned by simulated results or not */ 01567 if( mba ) { 01568 sig->suppl.part.mba = 1; 01569 sig->suppl.part.assigned = 1; 01570 } 01571 01572 /* Indicate signed attribute */ 01573 sig->value->suppl.part.is_signed = is_signed; 01574 01575 /* Indicate handled attribute */ 01576 sig->suppl.part.not_handled = handled ? 0 : 1; 01577 01578 /* Set the implicit_size attribute */ 01579 sig->suppl.part.implicit_size = (((type == SSUPPL_TYPE_INPUT_NET) || (type == SSUPPL_TYPE_INPUT_REG) || 01580 (type == SSUPPL_TYPE_OUTPUT_NET) || (type == SSUPPL_TYPE_OUTPUT_REG) || 01581 (type == SSUPPL_TYPE_INOUT_NET) || (type == SSUPPL_TYPE_INOUT_REG)) && 01582 (prange != NULL) && prange->dim[0].implicit && 01583 (prange->dim[0].left->exp == NULL) && (prange->dim[0].left->num == 0) && 01584 (prange->dim[0].right->exp == NULL) && (prange->dim[0].right->num == 0)) ? 1 : 0; 01585 01586 } 01587 01588 PROFILE_END; 01589 01590 }
Adds specified statement to current functional unit's statement list. Called by parser.
Adds the specified statement tree to the tail of the current module's statement list. The start statement is specified to avoid infinite looping.
stmt | Pointer to statement add to current module's statement list | |
start | Pointer to starting statement of statement tree |
References db_add_expression(), db_add_statement(), db_gen_item_connect(), DEBUG, debug_mode, statement_s::exp, gen_item_create_stmt(), generate_top_mode, statement_s::head, expression_s::id, statement_s::next_false, statement_s::next_true, statement_s::part, print_output(), PROFILE, PROFILE_END, func_unit_s::stmt_head, stmt_link_add(), func_unit_s::stmt_tail, statement_s::suppl, TRUE, user_msg, and USER_MSG_LENGTH.
Referenced by db_add_statement(), and db_parallelize_statement().
02379 { PROFILE(DB_ADD_STATEMENT); 02380 02381 if( (stmt != NULL) && (stmt->suppl.part.added == 0) ) { 02382 02383 #ifdef DEBUG_MODE 02384 if( debug_mode ) { 02385 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_statement, id: %d, start id: %d", stmt->exp->id, start->exp->id ); 02386 assert( rv < USER_MSG_LENGTH ); 02387 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02388 } 02389 #endif 02390 02391 /* Set the head statement pointer */ 02392 stmt->head = start; 02393 02394 /* Now add current statement */ 02395 if( generate_top_mode > 0 ) { 02396 02397 last_gi = gen_item_create_stmt( stmt ); 02398 02399 if( curr_gi_block != NULL ) { 02400 db_gen_item_connect( curr_gi_block, last_gi ); 02401 } else { 02402 curr_gi_block = last_gi; 02403 } 02404 02405 } else { 02406 02407 /* Add the associated expression tree */ 02408 db_add_expression( stmt->exp ); 02409 02410 /* Add TRUE and FALSE statement paths to list */ 02411 if( (stmt->suppl.part.stop_false == 0) && (stmt->next_false != start) ) { 02412 db_add_statement( stmt->next_false, start ); 02413 } 02414 02415 if( (stmt->suppl.part.stop_true == 0) && (stmt->next_true != stmt->next_false) && (stmt->next_true != start) ) { 02416 db_add_statement( stmt->next_true, start ); 02417 } 02418 02419 /* Set ADDED bit of this statement */ 02420 stmt->suppl.part.added = 1; 02421 02422 /* Finally, add the statement to the functional unit statement list */ 02423 (void)stmt_link_add( stmt, TRUE, &(curr_funit->stmt_head), &(curr_funit->stmt_tail) ); 02424 02425 } 02426 02427 } 02428 02429 PROFILE_END; 02430 02431 }
void db_add_typedef | ( | const char * | name, | |
bool | is_signed, | |||
bool | is_handled, | |||
bool | is_sizeable, | |||
sig_range * | prange, | |||
sig_range * | urange | |||
) |
Adds given typedefs to the database.
Adds the given names and information to the list of typedefs for the current module.
name | Typedef name for this type | |
is_signed | Specifies if this typedef is signed or not | |
is_handled | Specifies if this typedef is handled or not | |
is_sizeable | Specifies if a range can be later placed on this value | |
prange | Dimensional packed range information for this value | |
urange | Dimensional unpacked range information for this value |
References DEBUG, debug_mode, sig_range_s::exp_dealloc, FALSE, typedef_item_s::is_handled, typedef_item_s::is_signed, typedef_item_s::is_sizeable, malloc_safe, typedef_item_s::name, typedef_item_s::next, typedef_item_s::prange, print_output(), PROFILE, PROFILE_END, strdup_safe, func_unit_s::tdi_head, func_unit_s::tdi_tail, typedef_item_s::urange, user_msg, and USER_MSG_LENGTH.
01643 { PROFILE(DB_ADD_TYPEDEF); 01644 01645 typedef_item* tdi; /* Typedef item to create */ 01646 01647 #ifdef DEBUG_MODE 01648 if( debug_mode ) { 01649 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_typedef, name: %s, is_signed: %d, is_handled: %d, is_sizeable: %d", 01650 name, is_signed, is_handled, is_sizeable ); 01651 assert( rv < USER_MSG_LENGTH ); 01652 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01653 } 01654 #endif 01655 01656 /* Allocate memory and initialize the structure */ 01657 tdi = (typedef_item*)malloc_safe( sizeof( typedef_item ) ); 01658 tdi->name = strdup_safe( name ); 01659 tdi->is_signed = is_signed; 01660 tdi->is_handled = is_handled; 01661 tdi->is_sizeable = is_sizeable; 01662 tdi->prange = prange; 01663 tdi->urange = urange; 01664 tdi->next = NULL; 01665 01666 /* Add it the current module's typedef list */ 01667 if( curr_funit->tdi_head == NULL ) { 01668 curr_funit->tdi_head = curr_funit->tdi_tail = tdi; 01669 } else { 01670 curr_funit->tdi_tail->next = tdi; 01671 curr_funit->tdi_tail = tdi; 01672 } 01673 01674 /* Specify that the prange and urange expressions should not be deallocated */ 01675 if( prange != NULL ) { 01676 prange->exp_dealloc = FALSE; 01677 } 01678 if( urange != NULL ) { 01679 urange->exp_dealloc = FALSE; 01680 } 01681 01682 PROFILE_END; 01683 01684 }
void db_assign_symbol | ( | const char * | name, | |
const char * | symbol, | |||
int | msb, | |||
int | lsb | |||
) |
Adds symbol to signal specified by name.
Creates a new entry in the symbol table for the specified signal and symbol.
name | Name of signal to set value to | |
symbol | Symbol value of signal used in VCD dumpfile | |
msb | Most significant bit of symbol to set | |
lsb | Least significant bit of symbol to set |
References db_gen_curr_inst_scope(), DEBUG, debug_mode, free_safe, funit_inst_s::funit, obf_inst, obf_sig, print_output(), PROFILE, PROFILE_END, scope_find_signal(), sig_link_s::sig, func_unit_s::sig_head, sig_link_find(), SIGNAL_ASSIGN_FROM_DUMPFILE, symtable_add(), user_msg, and USER_MSG_LENGTH.
Referenced by covered_create_value_change_cb(), fst_reader_process_hier(), lxt_parse(), and vcd_parse_def_var().
02947 { PROFILE(DB_ASSIGN_SYMBOL); 02948 02949 #ifdef DEBUG_MODE 02950 if( debug_mode ) { 02951 char* scope = db_gen_curr_inst_scope(); 02952 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_assign_symbol, name: %s, symbol: %s, curr_inst_scope: %s, msb: %d, lsb: %d", 02953 obf_sig( name ), symbol, obf_inst( scope ), msb, lsb ); 02954 assert( rv < USER_MSG_LENGTH ); 02955 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02956 free_safe( scope, (strlen( scope ) + 1) ); 02957 } 02958 #endif 02959 02960 assert( name != NULL ); 02961 02962 if( (curr_instance != NULL) && (curr_instance->funit != NULL) ) { 02963 02964 sig_link* sigl; 02965 vsignal* sig; 02966 func_unit* found_funit; 02967 02968 /* Find the signal that matches the specified signal name */ 02969 if( ((sigl = sig_link_find( name, curr_instance->funit->sig_head )) != NULL) || 02970 scope_find_signal( name, curr_instance->funit, &sig, &found_funit, 0 ) ) { 02971 02972 /* If the signal exists in the current scope, assign the signal pointer to our temporary pointer */ 02973 if( sigl != NULL ) { 02974 sig = sigl->sig; 02975 } 02976 02977 /* Only add the symbol if we are not going to generate this value ourselves */ 02978 if( SIGNAL_ASSIGN_FROM_DUMPFILE( sig ) ) { 02979 02980 /* Add this signal */ 02981 symtable_add( symbol, sig, msb, lsb ); 02982 02983 } 02984 02985 } 02986 02987 } 02988 02989 PROFILE_END; 02990 02991 }
void db_bind_expr_tree | ( | expression * | root, | |
char * | sig_name | |||
) |
Binds all necessary sub-expressions in the given tree to the given signal name.
Recursively iterates through the entire expression tree binding all selection expressions within that tree to the given signal.
root | Pointer to root of expression tree to bind | |
sig_name | Name of signal to bind to |
References bind_add(), db_bind_expr_tree(), DEBUG, debug_mode, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_SBIT_SEL, expression_s::id, expression_s::left, expression_s::op, print_output(), PROFILE, PROFILE_END, expression_s::right, user_msg, and USER_MSG_LENGTH.
Referenced by db_bind_expr_tree().
02031 { PROFILE(DB_BIND_EXPR_TREE); 02032 02033 assert( sig_name != NULL ); 02034 02035 if( root != NULL ) { 02036 02037 #ifdef DEBUG_MODE 02038 if( debug_mode ) { 02039 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_bind_expr_tree, root id: %d, sig_name: %s", root->id, sig_name ); 02040 assert( rv < USER_MSG_LENGTH ); 02041 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02042 } 02043 #endif 02044 02045 /* Bind the children first */ 02046 db_bind_expr_tree( root->left, sig_name ); 02047 db_bind_expr_tree( root->right, sig_name ); 02048 02049 /* Now bind ourselves if necessary */ 02050 if( (root->op == EXP_OP_SBIT_SEL) || 02051 (root->op == EXP_OP_MBIT_SEL) || 02052 (root->op == EXP_OP_MBIT_POS) || 02053 (root->op == EXP_OP_MBIT_NEG) ) { 02054 bind_add( 0, sig_name, root, curr_funit ); 02055 } 02056 02057 } 02058 02059 PROFILE_END; 02060 02061 }
void db_check_dumpfile_scopes | ( | ) |
Called after all signals are parsed from dumpfile. Checks to see if dumpfile results were correct for the covered design.
Checks to make sure that if the current design has any signals that need to be assigned from the dumpfile that at least one of these signals was satisfied for this need.
References curr_db, FATAL, funit_link_s::funit, db_s::funit_head, funit_is_one_signal_assigned(), instance_specified, funit_link_s::next, print_output(), PROFILE, PROFILE_END, Throw, top_instance, user_msg, USER_MSG_LENGTH, and vcd_symtab_size.
Referenced by fst_parse(), lxt_parse(), and vcd_parse_def().
03137 { PROFILE(DB_CHECK_DUMPFILE_SCOPES); 03138 03139 /* If no signals were used from the VCD dumpfile, check to see if any signals were needed */ 03140 if( vcd_symtab_size == 0 ) { 03141 03142 funit_link* funitl = db_list[curr_db]->funit_head; 03143 03144 while( (funitl != NULL) && !funit_is_one_signal_assigned( funitl->funit ) ) { 03145 funitl = funitl->next; 03146 } 03147 03148 /* 03149 If at least one functional unit contains a signal that needs to be assigned from the dumpfile, 03150 we have some bad/unuseful dumpfile results. 03151 */ 03152 if( funitl != NULL ) { 03153 03154 print_output( "No instances were found in specified VCD file that matched design", FATAL, __FILE__, __LINE__ ); 03155 03156 /* If the -i option was not specified, let the user know */ 03157 if( !instance_specified ) { 03158 print_output( " Please use -i option to specify correct hierarchy to top-level module to score", 03159 FATAL, __FILE__, __LINE__ ); 03160 } else { 03161 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, " Incorrect hierarchical path specified in -i option: %s", top_instance ); 03162 assert( rv < USER_MSG_LENGTH ); 03163 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03164 } 03165 03166 Throw 0; 03167 03168 } 03169 03170 } 03171 03172 PROFILE_END; 03173 03174 }
bool db_check_for_top_module | ( | ) |
Checks to see if the module specified by the -t option is the top-level module of the simulator.
Iterates through the signal list of the top-level module. Returns TRUE if no signals with type INPUT, OUTPUT or INOUT were found; otherwise, returns FALSE. Called by the parse_design() function.
References curr_db, funit_inst_s::funit, funit_is_top_module(), instance_get_leading_hierarchy(), PROFILE, and PROFILE_END.
Referenced by parse_design().
00313 { PROFILE(DB_CHECK_FOR_TOP_MODULE); 00314 00315 bool retval; 00316 funit_inst* top_inst; 00317 00318 /* Get the top-most instance */ 00319 instance_get_leading_hierarchy( db_list[curr_db]->inst_tail->inst, NULL, &top_inst ); 00320 00321 /* Check to see if the signal list is void of ports */ 00322 retval = funit_is_top_module( top_inst->funit ); 00323 00324 PROFILE_END; 00325 00326 return( retval ); 00327 00328 }
void db_close | ( | ) |
Deallocates all memory consumed by the database.
Deallocates all memory associated with the databases.
References bind_dealloc(), curr_db, curr_inst_scope_size, db_get_exclusion_id_size(), db_size, exclusion_id, free_safe, funit_head, funit_link_delete_list(), db_s::fver_head, db_s::fver_tail, info_dealloc(), db_s::inst_head, inst_head, inst_link_delete_list(), db_s::inst_tail, db_s::leading_hier_num, PROFILE, PROFILE_END, str_link_delete_list(), tree_dealloc(), and TRUE.
Referenced by command_exclude(), command_merge(), command_report(), command_score(), covered_end_of_sim(), parse_design(), rank_read_cdd(), and report_close_cdd().
00237 { PROFILE(DB_CLOSE); 00238 00239 unsigned int i, j; 00240 00241 for( i=0; i<db_size; i++ ) { 00242 00243 if( db_list[i]->inst_head != NULL ) { 00244 00245 /* Remove memory allocated for inst_head */ 00246 inst_link_delete_list( db_list[i]->inst_head ); 00247 db_list[i]->inst_head = NULL; 00248 db_list[i]->inst_tail = NULL; 00249 00250 /* Remove memory allocated for all functional units */ 00251 funit_link_delete_list( &(db_list[i]->funit_head), &(db_list[i]->funit_tail), TRUE ); 00252 00253 } 00254 00255 /* Deallocate all information regarding hierarchies */ 00256 for( j=0; j<db_list[i]->leading_hier_num; j++ ) { 00257 free_safe( db_list[i]->leading_hierarchies[j], (strlen( db_list[i]->leading_hierarchies[j] ) + 1) ); 00258 } 00259 free_safe( db_list[i]->leading_hierarchies, (sizeof( char* ) * db_list[i]->leading_hier_num) ); 00260 00261 /* Deallocate the file version information */ 00262 str_link_delete_list( db_list[i]->fver_head ); 00263 db_list[i]->fver_head = NULL; 00264 db_list[i]->fver_tail = NULL; 00265 00266 /* Deallocate database structure */ 00267 free_safe( db_list[i], sizeof( db ) ); 00268 00269 } 00270 00271 /* Clear the global functional unit */ 00272 global_funit = NULL; 00273 00274 /* Deallocate preprocessor define tree */ 00275 tree_dealloc( def_table ); 00276 def_table = NULL; 00277 00278 /* Deallocate the binding list */ 00279 bind_dealloc(); 00280 00281 /* Deallocate database information */ 00282 info_dealloc(); 00283 00284 /* Deallocate the needed module list */ 00285 str_link_delete_list( modlist_head ); 00286 modlist_head = NULL; 00287 modlist_tail = NULL; 00288 00289 /* Free memory associated with current instance scope */ 00290 assert( curr_inst_scope_size == 0 ); 00291 00292 /* Deallocate the exclusion identifier container, if it exists */ 00293 free_safe( exclusion_id, db_get_exclusion_id_size() ); 00294 00295 /* Finally, deallocate the database list */ 00296 free_safe( db_list, (sizeof( db ) * db_size) ); 00297 db_list = NULL; 00298 db_size = 0; 00299 curr_db = 0; 00300 00301 PROFILE_END; 00302 00303 }
Connects false statement to specified statement.
Connects the specified statement's false statement.
stmt | Pointer to statement to connect false path to | |
next_false | Pointer to statement to run if statement evaluates to FALSE |
References DEBUG, debug_mode, statement_s::exp, expression_s::id, statement_s::next_false, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by parser_handle_case_statement().
02550 { PROFILE(DB_CONNECT_STATEMENT_FALSE); 02551 02552 #ifdef DEBUG_MODE 02553 int next_id; /* Statement ID of next FALSE statement */ 02554 #endif 02555 02556 if( stmt != NULL ) { 02557 02558 #ifdef DEBUG_MODE 02559 if( debug_mode ) { 02560 unsigned int rv; 02561 if( next_false == NULL ) { 02562 next_id = 0; 02563 } else { 02564 next_id = next_false->exp->id; 02565 } 02566 02567 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_connect_statement_false, id: %d, next: %d", stmt->exp->id, next_id ); 02568 assert( rv < USER_MSG_LENGTH ); 02569 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02570 } 02571 #endif 02572 02573 stmt->next_false = next_false; 02574 02575 } 02576 02577 PROFILE_END; 02578 02579 }
Connects true statement to specified statement.
Connects the specified statement's true statement.
stmt | Pointer to statement to connect true path to | |
next_true | Pointer to statement to run if statement evaluates to TRUE |
References DEBUG, debug_mode, statement_s::exp, expression_s::id, statement_s::next_true, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by parser_handle_case_statement().
02513 { PROFILE(DB_CONNECT_STATEMENT_TRUE); 02514 02515 #ifdef DEBUG_MODE 02516 int next_id; /* Statement ID of next TRUE statement */ 02517 #endif 02518 02519 if( stmt != NULL ) { 02520 02521 #ifdef DEBUG_MODE 02522 if( debug_mode ) { 02523 unsigned int rv; 02524 if( next_true == NULL ) { 02525 next_id = 0; 02526 } else { 02527 next_id = next_true->exp->id; 02528 } 02529 02530 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_connect_statement_true, id: %d, next: %d", stmt->exp->id, next_id ); 02531 assert( rv < USER_MSG_LENGTH ); 02532 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02533 } 02534 #endif 02535 02536 stmt->next_true = next_true; 02537 02538 } 02539 02540 PROFILE_END; 02541 02542 }
db* db_create | ( | ) |
Creates a new database.
Allocates, initializes and stores new database structure into global database array.
References db_size, FALSE, db_s::funit_head, db_s::funit_tail, db_s::fver_head, db_s::fver_tail, db_s::inst_head, db_s::inst_tail, db_s::leading_hier_num, db_s::leading_hierarchies, db_s::leading_hiers_differ, malloc_safe, PROFILE, PROFILE_END, and realloc_safe.
Referenced by command_score(), and info_db_read().
00207 { PROFILE(DB_CREATE); 00208 00209 db* new_db; /* Pointer to new database structure */ 00210 00211 /* Allocate new database */ 00212 new_db = (db*)malloc_safe( sizeof( db ) ); 00213 new_db->inst_head = NULL; 00214 new_db->inst_tail = NULL; 00215 new_db->funit_head = NULL; 00216 new_db->funit_tail = NULL; 00217 new_db->fver_head = NULL; 00218 new_db->fver_tail = NULL; 00219 new_db->leading_hierarchies = NULL; 00220 new_db->leading_hier_num = 0; 00221 new_db->leading_hiers_differ = FALSE; 00222 00223 /* Add this new database to the database array */ 00224 db_list = (db**)realloc_safe( db_list, (sizeof( db ) * db_size), (sizeof( db ) * (db_size + 1)) ); 00225 db_list[db_size] = new_db; 00226 db_size++; 00227 00228 PROFILE_END; 00229 00230 return( new_db ); 00231 00232 }
attr_param* db_create_attr_param | ( | char * | name, | |
expression * | expr | |||
) |
Allocates and initializes an attribute parameter.
Calls the attribute_create() function and returns the pointer returned by this function.
name | Attribute parameter identifier | |
expr | Pointer to constant expression that is assigned to the identifier |
References attribute_create(), DEBUG, debug_mode, expression_s::id, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
02730 { PROFILE(DB_CREATE_ATTR_PARAM); 02731 02732 attr_param* attr; /* Pointer to newly allocated/initialized attribute parameter */ 02733 02734 #ifdef DEBUG_MODE 02735 if( debug_mode ) { 02736 unsigned int rv; 02737 if( expr != NULL ) { 02738 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_attr_param, name: %s, expr: %d", name, expr->id ); 02739 } else { 02740 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_attr_param, name: %s", name ); 02741 } 02742 assert( rv < USER_MSG_LENGTH ); 02743 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02744 } 02745 #endif 02746 02747 attr = attribute_create( name, expr ); 02748 02749 PROFILE_END; 02750 02751 return( attr ); 02752 02753 }
expression* db_create_expr_from_static | ( | static_expr * | se, | |
int | line, | |||
int | first_col, | |||
int | last_col | |||
) |
Creates an expression from the specified static expression.
anonymous | db_create_expression Throw |
Creates an expression structure from a static expression structure.
se | Pointer to static expression structure | |
line | Line number that static expression was found on | |
first_col | Column that the static expression starts on | |
last_col | Column that the static expression ends on |
References Catch_anonymous, db_create_expression(), DEBUG, debug_mode, static_expr_s::exp, EXP_OP_STATIC, FALSE, free_safe, static_expr_s::num, print_output(), PROFILE, PROFILE_END, static_expr_dealloc(), Throw, TRUE, Try, vector_s::ul, user_msg, USER_MSG_LENGTH, vector_s::value, expression_s::value, VDATA_UL, vector_create(), vector_from_int(), and VTYPE_VAL.
02075 { PROFILE(DB_CREATE_EXPR_FROM_STATIC); 02076 02077 expression* expr = NULL; /* Return value for this function */ 02078 vector* vec; /* Temporary vector */ 02079 02080 #ifdef DEBUG_MODE 02081 if( debug_mode ) { 02082 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_expr_from_static, se: %p, line: %d, first_col: %d, last_col: %d", 02083 se, line, first_col, last_col ); 02084 assert( rv < USER_MSG_LENGTH ); 02085 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02086 } 02087 #endif 02088 02089 Try { 02090 02091 if( se->exp == NULL ) { 02092 02093 /* This static expression is a static value so create a static expression from its value */ 02094 expr = db_create_expression( NULL, NULL, EXP_OP_STATIC, FALSE, line, first_col, last_col, NULL ); 02095 02096 /* Create the new vector */ 02097 vec = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 02098 (void)vector_from_int( vec, se->num ); 02099 02100 /* Assign the new vector to the expression's vector (after deallocating the expression's old vector) */ 02101 assert( expr->value->value.ul == NULL ); 02102 free_safe( expr->value, sizeof( vector ) ); 02103 expr->value = vec; 02104 02105 } else { 02106 02107 /* The static expression is unresolved, so just get its expression */ 02108 expr = se->exp; 02109 02110 } 02111 02112 } Catch_anonymous { 02113 static_expr_dealloc( se, FALSE ); 02114 Throw 0; 02115 } 02116 02117 /* Deallocate static expression */ 02118 static_expr_dealloc( se, FALSE ); 02119 02120 PROFILE_END; 02121 02122 return( expr ); 02123 02124 }
expression* db_create_expression | ( | expression * | right, | |
expression * | left, | |||
exp_op_type | op, | |||
bool | lhs, | |||
int | line, | |||
int | first, | |||
int | last, | |||
char * | sig_name | |||
) |
Creates new expression from specified information. Called by parser and db_add_expression.
anonymous | expression_create Throw |
Creates a new expression with the specified parameter information and returns a pointer to the newly created expression.
right | Pointer to expression on right side of expression | |
left | Pointer to expression on left side of expression | |
op | Operation to perform on expression | |
lhs | Specifies this expression is a left-hand-side assignment expression | |
line | Line number of current expression | |
first | Column index of first character in this expression | |
last | Column index of last character in this expression | |
sig_name | Name of signal that expression is attached to (if valid) |
References bind_add(), esuppl_u::clear_changed, curr_expr_id, db_gen_item_connect(), DEBUG, debug_mode, exclude_mode, esuppl_u::excluded, EXP_OP_AEDGE, EXP_OP_ASSIGN, EXP_OP_BASSIGN, EXP_OP_DASSIGN, EXP_OP_DELAY, EXP_OP_DIM, EXP_OP_DISABLE, EXP_OP_DLY_ASSIGN, EXP_OP_EOR, EXP_OP_FUNC_CALL, EXP_OP_IF, EXP_OP_NASSIGN, EXP_OP_NB_CALL, EXP_OP_NEDGE, EXP_OP_PEDGE, EXP_OP_RASSIGN, EXP_OP_SB2R, EXP_OP_SB2SR, EXP_OP_SI2R, EXP_OP_SR2B, EXP_OP_SR2I, EXP_OP_SRANDOM, EXP_OP_SSR2B, EXP_OP_STIME, EXP_OP_SURAND_RANGE, EXP_OP_SURANDOM, EXP_OP_TASK_CALL, EXP_OP_WHILE, expression_create(), expression_string_op(), FALSE, FATAL, func_unit_s::filename, esuppl_u::for_cntrl, for_mode, FUNIT_FUNCTION, funit_get_curr_function(), FUNIT_NAMED_BLOCK, FUNIT_TASK, gen_item_create_bind(), gen_item_varname_contains_genvar(), generate_mode, expression_s::id, esuppl_u::in_func, func_unit_s::name, obf_file, obf_funit, expression_s::op, esuppl_u::owns_vec, esuppl_u::part, print_output(), PROFILE, PROFILE_END, expression_s::suppl, Throw, user_msg, USER_MSG_LENGTH, expression_s::value, and vector_dealloc().
Referenced by db_create_expr_from_static(), db_create_sensitivity_list(), db_parallelize_statement(), parser_handle_case_statement(), and parser_handle_generate_case_statement().
01888 { PROFILE(DB_CREATE_EXPRESSION); 01889 01890 expression* expr; /* Temporary pointer to newly created expression */ 01891 func_unit* func_funit; /* Pointer to function, if we are nested in one */ 01892 01893 #ifdef DEBUG_MODE 01894 if( debug_mode ) { 01895 int right_id; /* ID of right expression */ 01896 int left_id; /* ID of left expression */ 01897 unsigned int rv; /* Return value from snprintf call */ 01898 01899 if( right == NULL ) { 01900 right_id = 0; 01901 } else { 01902 right_id = right->id; 01903 } 01904 01905 if( left == NULL ) { 01906 left_id = 0; 01907 } else { 01908 left_id = left->id; 01909 } 01910 01911 if( sig_name == NULL ) { 01912 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_expression, right: %d, left: %d, id: %d, op: %s, lhs: %d, line: %d, first: %d, last: %d", 01913 right_id, left_id, curr_expr_id, expression_string_op( op ), lhs, line, first, last ); 01914 } else { 01915 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_expression, right: %d, left: %d, id: %d, op: %s, lhs: %d, line: %d, first: %d, last: %d, sig_name: %s", 01916 right_id, left_id, curr_expr_id, expression_string_op( op ), lhs, line, first, last, sig_name ); 01917 } 01918 assert( rv < USER_MSG_LENGTH ); 01919 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01920 } 01921 #endif 01922 01923 /* Check to see if current expression is in a function */ 01924 func_funit = funit_get_curr_function( curr_funit ); 01925 01926 /* Check to make sure that expression is allowed for the current functional unit type */ 01927 if( (func_funit != NULL) && 01928 ((op == EXP_OP_DELAY) || 01929 (op == EXP_OP_TASK_CALL) || 01930 (op == EXP_OP_NASSIGN) || 01931 (op == EXP_OP_PEDGE) || 01932 (op == EXP_OP_NEDGE) || 01933 (op == EXP_OP_AEDGE) || 01934 (op == EXP_OP_EOR)) ) { 01935 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Attempting to use a delay, task call, non-blocking assign or event controls in function %s, file %s, line %d", 01936 obf_funit( func_funit->name ), obf_file( curr_funit->filename ), line ); 01937 assert( rv < USER_MSG_LENGTH ); 01938 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 01939 Throw 0; 01940 } 01941 01942 /* Create expression with next expression ID */ 01943 expr = expression_create( right, left, op, lhs, curr_expr_id, line, first, last, FALSE ); 01944 curr_expr_id++; 01945 01946 /* If current functional unit is nested in a function, set the IN_FUNC supplemental field bit */ 01947 expr->suppl.part.in_func = (func_funit != NULL) ? 1 : 0; 01948 01949 /* Set the clear_changed bit if any of our children have their clear_changed bit set or if we are a system function expression */ 01950 if( ((left != NULL) && 01951 ((left->suppl.part.clear_changed == 1) || 01952 (left->op == EXP_OP_STIME) || (left->op == EXP_OP_SRANDOM) || (left->op == EXP_OP_SURANDOM) || (left->op == EXP_OP_SURAND_RANGE) || 01953 (left->op == EXP_OP_SB2R) || (left->op == EXP_OP_SR2B) || (left->op == EXP_OP_SI2R) || (left->op == EXP_OP_SR2I) || 01954 (left->op == EXP_OP_SB2SR) || (left->op == EXP_OP_SSR2B))) || 01955 ((right != NULL) && 01956 ((right->suppl.part.clear_changed == 1) || 01957 (right->op == EXP_OP_STIME) || (right->op == EXP_OP_SRANDOM) || (right->op == EXP_OP_SURANDOM) || (right->op == EXP_OP_SURAND_RANGE) || 01958 (right->op == EXP_OP_SB2R) || (right->op == EXP_OP_SR2B) || (right->op == EXP_OP_SI2R) || (right->op == EXP_OP_SR2I) || 01959 (right->op == EXP_OP_SB2SR) || (right->op == EXP_OP_SSR2B))) ) { 01960 expr->suppl.part.clear_changed = 1; 01961 } 01962 01963 /* If we are in exclude mode, set the exclude and stmt_exclude bits */ 01964 if( exclude_mode > 0 ) { 01965 expr->suppl.part.excluded = 1; 01966 } 01967 01968 /* If this expression is in the for control, set its bit */ 01969 if( for_mode > 0 ) { 01970 expr->suppl.part.for_cntrl = 1; 01971 } 01972 01973 /* 01974 If this is some kind of assignment expression operator, set the our expression vector to that of 01975 the right expression. 01976 */ 01977 if( (expr->op == EXP_OP_BASSIGN) || 01978 (expr->op == EXP_OP_NASSIGN) || 01979 (expr->op == EXP_OP_RASSIGN) || 01980 (expr->op == EXP_OP_DASSIGN) || 01981 (expr->op == EXP_OP_ASSIGN) || 01982 (expr->op == EXP_OP_IF) || 01983 (expr->op == EXP_OP_WHILE) || 01984 (expr->op == EXP_OP_DIM) || 01985 (expr->op == EXP_OP_DLY_ASSIGN) ) { 01986 vector_dealloc( expr->value ); 01987 expr->suppl.part.owns_vec = 0; 01988 assert( right != NULL ); 01989 expr->value = right->value; 01990 } 01991 01992 /* Add expression and signal to binding list */ 01993 if( sig_name != NULL ) { 01994 01995 /* 01996 If we are in a generate block and the signal name contains a generate variable/expression, 01997 create a generate item to handle the binding later. 01998 */ 01999 if( (generate_mode > 0) && gen_item_varname_contains_genvar( sig_name ) ) { 02000 last_gi = gen_item_create_bind( sig_name, expr ); 02001 if( curr_gi_block != NULL ) { 02002 db_gen_item_connect( curr_gi_block, last_gi ); 02003 } else { 02004 curr_gi_block = last_gi; 02005 } 02006 } else { 02007 switch( op ) { 02008 case EXP_OP_FUNC_CALL : bind_add( FUNIT_FUNCTION, sig_name, expr, curr_funit ); break; 02009 case EXP_OP_TASK_CALL : bind_add( FUNIT_TASK, sig_name, expr, curr_funit ); break; 02010 case EXP_OP_NB_CALL : bind_add( FUNIT_NAMED_BLOCK, sig_name, expr, curr_funit ); break; 02011 case EXP_OP_DISABLE : bind_add( 1, sig_name, expr, curr_funit ); break; 02012 default : bind_add( 0, sig_name, expr, curr_funit ); break; 02013 } 02014 } 02015 02016 } 02017 02018 PROFILE_END; 02019 02020 return( expr ); 02021 02022 }
expression* db_create_sensitivity_list | ( | statement * | stmt | ) |
Creates an expression tree sensitivity list for the given statement block.
anonymous | db_create_expression db_create_expression db_create_expression db_create_expression Throw |
stmt | Pointer to statement block to parse |
References Catch_anonymous, db_create_expression(), EXP_OP_AEDGE, EXP_OP_EOR, EXP_OP_SIG, FALSE, str_link_s::next, PROFILE, PROFILE_END, statement_find_rhs_sigs(), str_link_s::str, str_link_delete_list(), Throw, and Try.
02187 { PROFILE(DB_CREATE_SENSITIVITY_LIST); 02188 02189 str_link* sig_head = NULL; /* Pointer to head of signal name list containing RHS used signals */ 02190 str_link* sig_tail = NULL; /* Pointer to tail of signal name list containing RHS used signals */ 02191 str_link* strl; /* Pointer to current signal name link */ 02192 expression* exps; /* Pointer to created expression for type SIG */ 02193 expression* expa; /* Pointer to created expression for type AEDGE */ 02194 expression* expe; /* Pointer to created expression for type EOR */ 02195 expression* expc = NULL; /* Pointer to left child expression */ 02196 02197 /* Get the list of all RHS signals in the given statement block */ 02198 statement_find_rhs_sigs( stmt, &sig_head, &sig_tail ); 02199 02200 /* Create sensitivity expression tree for the list of RHS signals */ 02201 if( sig_head != NULL ) { 02202 02203 Try { 02204 02205 strl = sig_head; 02206 while( strl != NULL ) { 02207 02208 /* Create AEDGE and EOR for subsequent signals */ 02209 exps = db_create_expression( NULL, NULL, EXP_OP_SIG, FALSE, 0, 0, 0, strl->str ); 02210 expa = db_create_expression( exps, NULL, EXP_OP_AEDGE, FALSE, 0, 0, 0, NULL ); 02211 02212 /* If we have a child expression already, create the EOR expression to connect them */ 02213 if( expc != NULL ) { 02214 expe = db_create_expression( expa, expc, EXP_OP_EOR, FALSE, 0, 0, 0, NULL ); 02215 expc = expe; 02216 } else { 02217 expc = expa; 02218 } 02219 02220 strl = strl->next; 02221 02222 } 02223 02224 } Catch_anonymous { 02225 str_link_delete_list( sig_head ); 02226 Throw 0; 02227 } 02228 02229 /* Deallocate string list */ 02230 str_link_delete_list( sig_head ); 02231 02232 } 02233 02234 PROFILE_END; 02235 02236 return( expc ); 02237 02238 }
statement* db_create_statement | ( | expression * | exp, | |
unsigned int | ppline | |||
) |
Creates new statement expression from specified information. Called by parser.
anonymous | db_parallelize_statement Throw |
Creates an statement structure and adds created statement to current module's statement list.
exp | Pointer to associated "root" expression | |
ppline | First line of the statement in the preprocessor file |
References Catch_anonymous, db_parallelize_statement(), DEBUG, debug_mode, exclude_mode, expression_dealloc(), FALSE, expression_s::id, ignore_racecheck_mode, expression_s::line, statement_s::part, print_output(), PROFILE, PROFILE_END, statement_create(), statement_dealloc(), statement_s::suppl, Throw, Try, user_msg, and USER_MSG_LENGTH.
Referenced by db_parallelize_statement(), and parser_handle_case_statement().
02325 { PROFILE(DB_CREATE_STATEMENT); 02326 02327 statement* stmt = NULL; /* Pointer to newly created statement */ 02328 02329 /* If the statement expression is NULL, we can't create the statement */ 02330 if( exp != NULL ) { 02331 02332 #ifdef DEBUG_MODE 02333 if( debug_mode ) { 02334 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_statement, id: %d, line: %d", exp->id, exp->line ); 02335 assert( rv < USER_MSG_LENGTH ); 02336 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02337 } 02338 #endif 02339 02340 /* Create the given statement */ 02341 stmt = statement_create( exp, curr_funit, ppline ); 02342 02343 /* If we are in the exclude mode, exclude this statement */ 02344 if( exclude_mode > 0 ) { 02345 stmt->suppl.part.excluded = 1; 02346 } 02347 02348 /* If we need to exclude this statement from race condition checking, do so */ 02349 if( ignore_racecheck_mode > 0 ) { 02350 stmt->suppl.part.ignore_rc = 1; 02351 } 02352 02353 Try { 02354 02355 /* If we are a parallel statement, create a FORK statement for this statement block */ 02356 stmt = db_parallelize_statement( stmt ); 02357 02358 } Catch_anonymous { 02359 statement_dealloc( stmt ); 02360 expression_dealloc( exp, FALSE ); 02361 Throw 0; 02362 } 02363 02364 } 02365 02366 PROFILE_END; 02367 02368 return( stmt ); 02369 02370 }
char* db_create_unnamed_scope | ( | ) |
Creates a scope name for an unnamed scope. Called only during parsing.
References PROFILE, PROFILE_END, strdup_safe, and unnamed_scope_id.
Referenced by db_parallelize_statement().
00814 { PROFILE(DB_CREATE_UNNAMED_SCOPE); 00815 00816 char tmpname[30]; 00817 char* name; 00818 unsigned int rv = snprintf( tmpname, 30, "$u%d", unnamed_scope_id ); 00819 00820 assert( rv < 30 ); 00821 00822 name = strdup_safe( tmpname ); 00823 unnamed_scope_id++; 00824 00825 PROFILE_END; 00826 00827 return( name ); 00828 00829 }
Performs a timestep for all signal changes during this timestep.
anonymous | symtable_assign |
Cycles through expression queue, performing expression evaluations as we go. If an expression has a parent expression, that parent expression is placed in the expression queue after that expression has completed its evaluation. When the expression queue is empty, we are finished for this clock period.
time | Current time step value being performed | |
final | Specifies that this is the final timestep |
References DEBUG, debug_mode, sim_time_s::final, sim_time_s::full, sim_time_s::hi, sim_time_s::lo, num_timesteps, print_output(), PROFILE, PROFILE_END, sim_perform_nba(), sim_simulate(), symtable_assign(), timestep_update, user_msg, and USER_MSG_LENGTH.
Referenced by covered_end_of_sim(), covered_value_change_bin(), covered_value_change_real(), fst_callback(), fst_parse(), lxt_parse(), parse_and_score_dumpfile(), vcd_callback(), and vcd_parse_sim().
03065 { PROFILE(DB_DO_TIMESTEP); 03066 03067 bool retval; /* Return value for this function */ 03068 static sim_time curr_time; 03069 static uint64 last_sim_update = 0; 03070 03071 #ifdef DEBUG_MODE 03072 if( debug_mode ) { 03073 if( final ) { 03074 print_output( "Performing final timestep", DEBUG, __FILE__, __LINE__ ); 03075 } else { 03076 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Performing timestep #%" FMT64 "u", time ); 03077 assert( rv < USER_MSG_LENGTH ); 03078 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 03079 } 03080 } 03081 #endif 03082 03083 num_timesteps++; 03084 03085 curr_time.lo = (time & 0xffffffffLL); 03086 curr_time.hi = ((time >> 32) & 0xffffffffLL); 03087 curr_time.full = time; 03088 curr_time.final = final; 03089 03090 if( (timestep_update > 0) && ((time - last_sim_update) >= timestep_update) && !debug_mode && !final ) { 03091 unsigned int rv; 03092 last_sim_update = time; 03093 /*@-formattype -formatcode -duplicatequals@*/ 03094 printf( "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bPerforming timestep %10" FMT64 "u", time ); 03095 /*@=formattype =formatcode =duplicatequals@*/ 03096 rv = fflush( stdout ); 03097 assert( rv == 0 ); 03098 } 03099 03100 /* Simulate the current timestep */ 03101 retval = sim_simulate( &curr_time ); 03102 03103 /* If this is the last timestep, add the final list and do one more simulate */ 03104 if( final && retval ) { 03105 curr_time.lo = 0xffffffff; 03106 curr_time.hi = 0xffffffff; 03107 curr_time.full = 0xffffffffffffffffLL; 03108 retval = sim_simulate( &curr_time ); 03109 } 03110 03111 #ifdef DEBUG_MODE 03112 if( debug_mode ) { 03113 print_output( "Assigning postsimulation signals...", DEBUG, __FILE__, __LINE__ ); 03114 } 03115 #endif 03116 03117 if( retval ) { 03118 03119 /* Assign all stored values in current post-timestep to stored signals */ 03120 symtable_assign( &curr_time ); 03121 03122 /* Perform non-blocking assignment */ 03123 sim_perform_nba( &curr_time ); 03124 03125 } 03126 03127 PROFILE_END; 03128 03129 return( retval ); 03130 03131 }
void db_end_enum_list | ( | ) |
Called after all enumerated values for the current list have been added.
Called after an entire enum list has been parsed and added to the database.
References DEBUG, debug_mode, enumerate_end_list(), print_output(), PROFILE, and PROFILE_END.
01619 { PROFILE(DB_END_ENUM_LIST); 01620 01621 #ifdef DEBUG_MODE 01622 if( debug_mode ) { 01623 print_output( "In db_end_enum_list", DEBUG, __FILE__, __LINE__ ); 01624 } 01625 #endif 01626 01627 enumerate_end_list( curr_funit ); 01628 01629 PROFILE_END; 01630 01631 }
void db_end_function_task | ( | int | end_line | ) |
Called when the endfunction or endtask keyword is parsed.
void db_end_function_task_namedblock | ( | int | end_line | ) |
Performs actions necessary when the end of a function/task/named-block is seen. Called by parser.
Causes the current function/task/named block to be ended and added to the database.
end_line | Line number of end of this task/function |
References DEBUG, debug_mode, func_unit_s::end_line, func_unit_s::first_stmt, statement_s::head, func_unit_s::parent, print_output(), PROFILE, PROFILE_END, stmt_link_s::stmt, func_unit_s::stmt_head, user_msg, and USER_MSG_LENGTH.
Referenced by db_parallelize_statement().
01278 { PROFILE(DB_END_FUNCTION_TASK_NAMEDBLOCK); 01279 01280 #ifdef DEBUG_MODE 01281 if( debug_mode ) { 01282 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_end_function_task_namedblock, end_line: %d", end_line ); 01283 assert( rv < USER_MSG_LENGTH ); 01284 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01285 } 01286 #endif 01287 01288 /* Store last line information */ 01289 curr_funit->end_line = end_line; 01290 01291 /* Set the first statement pointer */ 01292 if( curr_funit->stmt_head != NULL ) { 01293 assert( curr_funit->stmt_head->stmt != NULL ); 01294 curr_funit->first_stmt = curr_funit->stmt_head->stmt->head; 01295 } 01296 01297 /* Set the current functional unit to the parent module */ 01298 curr_funit = curr_funit->parent; 01299 01300 PROFILE_END; 01301 01302 }
void db_end_module | ( | int | end_line | ) |
Called when the endmodule keyword is parsed.
Updates the modlist for parsing purposes.
end_line | Ending line number of specified module in file |
References DEBUG, debug_mode, func_unit_s::end_line, func_unit_s::name, print_output(), PROFILE, PROFILE_END, str_link_remove(), user_msg, and USER_MSG_LENGTH.
01169 { PROFILE(DB_END_MODULE); 01170 01171 #ifdef DEBUG_MODE 01172 if( debug_mode ) { 01173 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_end_module, end_line: %d", end_line ); 01174 assert( rv < USER_MSG_LENGTH ); 01175 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01176 } 01177 #endif 01178 01179 curr_funit->end_line = end_line; 01180 01181 str_link_remove( curr_funit->name, &modlist_head, &modlist_tail ); 01182 01183 /* Return the current functional unit to the global functional unit, if it exists */ 01184 curr_funit = global_funit; 01185 01186 PROFILE_END; 01187 01188 }
Find specified generate item in the current functional unit. Called by parser.
Searches the current functional unit for the generate item that matches the specified generate item. If it is found, a pointer to the stored generate item is returned. If it is not found, a value of NULL is returned. Additionally, the specified generate item is automatically deallocated on behalf of the caller. This function should only be called during the parsing stage.
root | Pointer to root generate item to start searching in | |
gi | Pointer to created generate item to search for |
References DEBUG, debug_mode, FALSE, gen_item_dealloc(), gen_item_find(), gen_item_s::part, print_output(), PROFILE, PROFILE_END, gen_item_s::suppl, user_msg, and USER_MSG_LENGTH.
01757 { PROFILE(DB_FIND_GEN_ITEM); 01758 01759 gen_item* found; /* Return value for this function */ 01760 01761 #ifdef DEBUG_MODE 01762 if( debug_mode ) { 01763 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_find_gen_item, type %d", gi->suppl.part.type ); 01764 assert( rv < USER_MSG_LENGTH ); 01765 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01766 } 01767 #endif 01768 01769 /* Search for the specified generate item */ 01770 found = gen_item_find( root, gi ); 01771 01772 /* Deallocate the user-specified generate item */ 01773 gen_item_dealloc( gi, FALSE ); 01774 01775 PROFILE_END; 01776 01777 return( found ); 01778 01779 }
Finds specified signal in functional unit and returns pointer to the signal structure. Called by parser.
anonymous | Throw |
Searches signal matching the specified name using normal scoping rules. If the signal is found, returns a pointer to the calling function for that signal. If the signal is not found, emits a user error and immediately halts execution.
name | String name of signal to find in current module | |
okay_if_not_found | If set to TRUE, does not emit error message if signal is not found (returns NULL) |
References DEBUG, debug_mode, FATAL, func_unit_s::name, obf_funit, obf_sig, print_output(), PROFILE, PROFILE_END, scope_find_signal(), Throw, user_msg, and USER_MSG_LENGTH.
01698 { PROFILE(DB_FIND_SIGNAL); 01699 01700 vsignal* found_sig; /* Pointer to found signal (return value) */ 01701 func_unit* found_funit; /* Pointer to found functional unit (not used) */ 01702 01703 #ifdef DEBUG_MODE 01704 if( debug_mode ) { 01705 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_find_signal, searching for signal %s", obf_sig( name ) ); 01706 assert( rv < USER_MSG_LENGTH ); 01707 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01708 } 01709 #endif 01710 01711 if( !scope_find_signal( name, curr_funit, &found_sig, &found_funit, 0 ) && !okay_if_not_found ) { 01712 01713 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to find variable %s in module %s", obf_sig( name ), obf_funit( curr_funit->name ) ); 01714 assert( rv < USER_MSG_LENGTH ); 01715 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 01716 Throw 0; 01717 01718 } 01719 01720 PROFILE_END; 01721 01722 return( found_sig ); 01723 01724 }
typedef_item* db_find_typedef | ( | const char * | name | ) |
Finds specified typedef and returns TRUE if it is found.
Searches for the given typedef name in the current module.
name | Name of typedef to search for |
References DEBUG, debug_mode, funit_get_curr_module(), typedef_item_s::name, typedef_item_s::next, print_output(), PROFILE, PROFILE_END, func_unit_s::tdi_head, user_msg, and USER_MSG_LENGTH.
01788 { PROFILE(DB_FIND_TYPEDEF); 01789 01790 func_unit* parent; /* Pointer to parent module */ 01791 typedef_item* tdi = NULL; /* Pointer to current typedef item */ 01792 01793 assert( name != NULL ); 01794 01795 #ifdef DEBUG_MODE 01796 if( debug_mode ) { 01797 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_find_typedef, searching for name: %s", name ); 01798 assert( rv < USER_MSG_LENGTH ); 01799 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 01800 } 01801 #endif 01802 01803 if( curr_funit != NULL ) { 01804 01805 parent = funit_get_curr_module( curr_funit ); 01806 01807 tdi = parent->tdi_head; 01808 while( (tdi != NULL) && (strcmp( tdi->name, name ) != 0) ) { 01809 tdi = tdi->next; 01810 } 01811 01812 /* If we could not find the typedef in the current functional unit, look in the global funit, if it exists */ 01813 if( (tdi == NULL) && (global_funit != NULL) ) { 01814 tdi = global_funit->tdi_head; 01815 while( (tdi != NULL) && (strcmp( tdi->name, name ) != 0) ) { 01816 tdi = tdi->next; 01817 } 01818 } 01819 01820 } 01821 01822 PROFILE_END; 01823 01824 return( tdi ); 01825 01826 }
char* db_gen_exclusion_id | ( | char | type, | |
int | id | |||
) |
Allocates memory for and generates the exclusion identifier.
Generates the exclusion ID string and stores the result in the excl_id array.
type | Single character specifying the metric type (L, T, M, C, A, F) | |
id | Numerical unique identifier |
References db_get_exclusion_id_size(), exclusion_id, malloc_safe, PROFILE, and PROFILE_END.
Referenced by combination_event(), combination_multi_vars(), combination_two_vars(), combination_unary(), exclude_resolve_reason(), fsm_display_arc_verbose(), line_display_verbose(), memory_display_verbose(), ovl_display_verbose(), and toggle_display_verbose().
00938 { PROFILE(DB_GEN_EXCLUSION_ID); 00939 00940 char tmp[30]; 00941 int size = db_get_exclusion_id_size(); 00942 unsigned int rv; 00943 00944 /* If the exclusion ID has not been created, create it now */ 00945 if( exclusion_id == NULL ) { 00946 00947 /* Allocate the memory needed */ 00948 exclusion_id = (char*)malloc_safe( size ); 00949 00950 } 00951 00952 /* Create format string */ 00953 rv = snprintf( tmp, 30, "%%c%%0%dd", (size - 2) ); 00954 assert( rv < 30 ); 00955 00956 /* Generate exclusion_id string */ 00957 rv = snprintf( exclusion_id, size, tmp, type, id ); 00958 assert( rv < size ); 00959 00960 PROFILE_END; 00961 00962 return( exclusion_id ); 00963 00964 }
Connects one generate item block to another.
Connects two generate items together.
gi1 | Pointer to generate item block to connect to gi2 | |
gi2 | Pointer to generate item that will be connected to gi1 |
References DEBUG, debug_mode, FALSE, gen_item_connect(), gi_conn_id, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by db_add_expression(), db_add_instance(), db_add_signal(), db_add_statement(), and db_create_expression().
02635 { PROFILE(DB_GEN_ITEM_CONNECT); 02636 02637 bool rv; 02638 02639 #ifdef DEBUG_MODE 02640 if( debug_mode ) { 02641 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_gen_item_connect, gi1: %p, gi2: %p, conn_id: %d", gi1, gi2, gi_conn_id ); 02642 assert( rv < USER_MSG_LENGTH ); 02643 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02644 } 02645 #endif 02646 02647 /* Connect generate items */ 02648 rv = gen_item_connect( gi1, gi2, gi_conn_id, FALSE ); 02649 assert( rv ); 02650 02651 /* Increment gi_conn_id for next connection */ 02652 gi_conn_id++; 02653 02654 PROFILE_END; 02655 02656 }
Connects gi2 to the false path of gi1.
Connects gi2 to gi1's next_false pointer.
gi1 | Pointer to generate item holding next_false | |
gi2 | Pointer to generate item to connect |
References DEBUG, debug_mode, gen_item_s::next_false, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by parser_handle_generate_case_statement().
02611 { PROFILE(DB_GEN_ITEM_CONNECT_FALSE); 02612 02613 assert( gi1 != NULL ); 02614 02615 #ifdef DEBUG_MODE 02616 if( debug_mode ) { 02617 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_gen_item_connect_false, gi1: %p, gi2: %p", gi1, gi2 ); 02618 assert( rv < USER_MSG_LENGTH ); 02619 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02620 } 02621 #endif 02622 02623 gi1->next_false = gi2; 02624 02625 PROFILE_END; 02626 02627 }
Connects gi2 to the true path of gi1.
Connects gi2 to gi1's next_true pointer.
gi1 | Pointer to generate item holding next_true | |
gi2 | Pointer to generate item to connect |
References DEBUG, debug_mode, gen_item_s::next_true, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by parser_handle_generate_case_statement().
02587 { PROFILE(DB_GEN_ITEM_CONNECT_TRUE); 02588 02589 assert( gi1 != NULL ); 02590 02591 #ifdef DEBUG_MODE 02592 if( debug_mode ) { 02593 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_gen_item_connect_true, gi1: %p, gi2: %p", gi1, gi2 ); 02594 assert( rv < USER_MSG_LENGTH ); 02595 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02596 } 02597 #endif 02598 02599 gi1->next_true = gi2; 02600 02601 PROFILE_END; 02602 02603 }
func_unit* db_get_curr_funit | ( | ) |
Returns a pointer to the current functional unit.
This function returns a pointer to the current functional unit being parsed.
References PROFILE, and PROFILE_END.
00871 { PROFILE(DB_GET_CURR_FUNIT); 00872 00873 PROFILE_END; 00874 00875 return( curr_funit ); 00876 00877 }
gen_item* db_get_curr_gen_block | ( | ) |
Returns a pointer to the current implicitly connected generate block. Called by parser.
References DEBUG, debug_mode, print_output(), PROFILE, and PROFILE_END.
Referenced by parser_handle_generate_case_statement().
01831 { PROFILE(DB_GET_CURR_GEN_BLOCK); 01832 01833 gen_item* block = curr_gi_block; /* Temporary pointer to current generate item block */ 01834 01835 #ifdef DEBUG_MODE 01836 if( debug_mode ) { 01837 print_output( "In db_get_curr_gen_block", DEBUG, __FILE__, __LINE__ ); 01838 } 01839 #endif 01840 01841 /* Clear the curr_gi_block and last_gi pointers */ 01842 curr_gi_block = NULL; 01843 last_gi = NULL; 01844 01845 PROFILE_END; 01846 01847 return( block ); 01848 01849 }
unsigned int db_get_exclusion_id_size | ( | ) |
Calculates and returns the size of the exclusion ID string.
References curr_arc_id, curr_expr_id, curr_sig_id, exclusion_id_size, PROFILE, and PROFILE_END.
Referenced by combination_event(), combination_list_missed(), combination_multi_expr_output(), combination_multi_vars(), combination_two_vars(), combination_unary(), db_close(), db_gen_exclusion_id(), fsm_display_arc_verbose(), line_display_verbose(), ovl_display_verbose(), and toggle_display_verbose().
00882 { PROFILE(DB_GET_EXCLUSION_ID_SIZE); 00883 00884 static unsigned int exclusion_id_size = 0; 00885 00886 if( exclusion_id_size == 0 ) { 00887 00888 char tmp[30]; 00889 unsigned int rv; 00890 00891 /* Calculate the size needed to store the largest signal ID */ 00892 rv = snprintf( tmp, 30, "%d", curr_sig_id ); 00893 assert( rv < 30 ); 00894 exclusion_id_size = strlen( tmp ) + 2; 00895 00896 /* Now calculate the size needed to store the largest expression ID */ 00897 rv = snprintf( tmp, 30, "%d", curr_expr_id ); 00898 assert( rv < 30 ); 00899 00900 /* Figure out which value is greater and use that for the size of the exclusion ID */ 00901 if( (strlen( tmp ) + 2) > exclusion_id_size ) { 00902 exclusion_id_size = strlen( tmp ) + 2; 00903 } 00904 00905 /* Now calculate the size needed to store the largest arc ID */ 00906 rv = snprintf( tmp, 30, "%d", curr_arc_id ); 00907 assert( rv < 30 ); 00908 00909 /* Figure out which value is greater and use that for the size of the exclusion ID */ 00910 if( (strlen( tmp ) + 2) > exclusion_id_size ) { 00911 exclusion_id_size = strlen( tmp ) + 2; 00912 } 00913 00914 /* The minimum size of the exclusion ID should be 3 characters */ 00915 if( exclusion_id_size < 4 ) { 00916 exclusion_id_size = 4; 00917 } 00918 00919 } 00920 00921 PROFILE_END; 00922 00923 return( exclusion_id_size ); 00924 00925 }
bool db_is_unnamed_scope | ( | char * | scope | ) |
Returns TRUE if the given scope is an unnamed scope name; otherwise, returns FALSE.
scope | Name to check |
References PROFILE, and PROFILE_END.
Referenced by assertion_instance_summary(), assertion_instance_verbose(), combination_instance_summary(), combination_instance_verbose(), fsm_instance_summary(), fsm_instance_verbose(), funit_flatten_name(), funit_is_unnamed(), instance_find_scope(), instance_gen_scope(), line_instance_summary(), line_instance_verbose(), memory_ae_instance_summary(), memory_instance_verbose(), memory_toggle_instance_summary(), toggle_instance_summary(), and toggle_instance_verbose().
00836 { PROFILE(DB_IS_UNNAMED_SCOPE); 00837 00838 bool is_unnamed = (scope != NULL) && (scope[0] == '$') && (scope[1] == 'u'); 00839 00840 PROFILE_END; 00841 00842 return( is_unnamed ); 00843 00844 }
void db_merge_instance_trees | ( | ) |
Merges the current instance trees.
Iterates through the instance tree list, merging all instances into the first instance tree that is not the $root instance tree.
References inst_link_s::base, curr_db, FALSE, FATAL, inst_link_s::ignore, inst_link_s::inst, db_s::inst_head, instance_merge_two_trees(), funit_inst_s::name, inst_link_s::next, print_output(), PROFILE, PROFILE_END, Throw, and TRUE.
Referenced by command_merge().
00732 { PROFILE(DB_MERGE_INSTANCE_TREES); 00733 00734 funit_inst* base = NULL; 00735 inst_link* instl; 00736 bool done = FALSE; 00737 00738 if( db_list != NULL ) { 00739 00740 /* Merge all root trees */ 00741 instl = db_list[curr_db]->inst_head; 00742 while( instl != NULL ) { 00743 if( strcmp( instl->inst->name, "$root" ) == 0 ) { 00744 if( base == NULL ) { 00745 base = instl->inst; 00746 instl->base = TRUE; 00747 } else { 00748 instl->ignore = instance_merge_two_trees( base, instl->inst ); 00749 } 00750 } 00751 instl = instl->next; 00752 } 00753 00754 /* Merge all other trees */ 00755 while( !done ) { 00756 base = NULL; 00757 instl = db_list[curr_db]->inst_head; 00758 while( instl != NULL ) { 00759 if( strcmp( instl->inst->name, "$root" ) != 0 ) { 00760 if( !instl->ignore && !instl->base ) { 00761 if( base == NULL ) { 00762 base = instl->inst; 00763 instl->base = TRUE; 00764 } else { 00765 instl->ignore = instance_merge_two_trees( base, instl->inst ); 00766 } 00767 } 00768 } 00769 instl = instl->next; 00770 } 00771 done = (base == NULL); 00772 } 00773 00774 } else { 00775 00776 print_output( "Attempting to merge unscored CDDs", FATAL, __FILE__, __LINE__ ); 00777 Throw 0; 00778 00779 } 00780 00781 PROFILE_END; 00782 00783 }
void db_output_dumpvars | ( | FILE * | vfile | ) |
Outputs all needed signals in $dumpvars calls to the specified file.
Outputs all signals that need to be dumped to the given files.
vfile | Pointer to file to output dumpvars output to |
References curr_db, inst_link_s::inst, db_s::inst_head, instance_output_dumpvars(), inst_link_s::next, PROFILE, and PROFILE_END.
Referenced by score_generate_top_dumpvars_module().
00997 { PROFILE(DB_OUTPUT_DUMPVARS); 00998 00999 inst_link* instl = db_list[curr_db]->inst_head; 01000 01001 while( instl != NULL ) { 01002 instance_output_dumpvars( vfile, instl->inst ); 01003 instl = instl->next; 01004 } 01005 01006 PROFILE_END; 01007 01008 }
Checks specified statement for parallelization and if it must be, creates a parallel statement block.
anonymous | db_create_statement Throw db_create_expression |
stmt | Pointer to statement to check for parallelization |
References block_depth, Catch_anonymous, expression_s::col, db_add_function_task_namedblock(), db_add_statement(), db_create_expression(), db_create_statement(), db_create_unnamed_scope(), db_end_function_task_namedblock(), DEBUG, debug_mode, expression_s::elem, ETYPE_FUNIT, statement_s::exp, EXP_OP_FORK, expression_dealloc(), expression_string_op(), FALSE, func_unit_s::filename, fork_block_depth, fork_depth, free_safe, expression_s::funit, FUNIT_NAMED_BLOCK, expression_s::id, expression_s::line, expression_s::name, expression_s::op, esuppl_u::part, statement_s::part, expression_s::part, statement_s::ppline, print_output(), PROFILE, PROFILE_END, strdup_safe, expression_s::suppl, statement_s::suppl, Throw, Try, esuppl_u::type, user_msg, and USER_MSG_LENGTH.
Referenced by db_create_statement().
02248 { PROFILE(DB_PARALLELIZE_STATEMENT); 02249 02250 expression* exp; /* Expression containing FORK statement */ 02251 char* scope; /* Name of current parallelized statement scope */ 02252 02253 /* If we are a parallel statement, create a FORK statement for this statement block */ 02254 if( (stmt != NULL) && (fork_depth != -1) && (fork_block_depth[fork_depth] == block_depth) ) { 02255 02256 #ifdef DEBUG_MODE 02257 if( debug_mode ) { 02258 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_parallelize_statement, id: %d, %s, line: %d, fork_depth: %d, block_depth: %d, fork_block_depth: %d", 02259 stmt->exp->id, expression_string_op( stmt->exp->op ), stmt->exp->line, fork_depth, block_depth, fork_block_depth[fork_depth] ); 02260 assert( rv < USER_MSG_LENGTH ); 02261 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02262 } 02263 #endif 02264 02265 /* Create FORK expression */ 02266 exp = db_create_expression( NULL, NULL, EXP_OP_FORK, FALSE, stmt->exp->line, stmt->exp->col.part.first, stmt->exp->col.part.last, NULL ); 02267 02268 /* Create unnamed scope */ 02269 scope = db_create_unnamed_scope(); 02270 if( db_add_function_task_namedblock( FUNIT_NAMED_BLOCK, scope, curr_funit->filename, stmt->exp->line ) ) { 02271 02272 /* Create a thread block for this statement block */ 02273 stmt->suppl.part.head = 1; 02274 stmt->suppl.part.is_called = 1; 02275 db_add_statement( stmt, stmt ); 02276 02277 /* Bind the FORK expression now */ 02278 exp->elem.funit = curr_funit; 02279 exp->suppl.part.type = ETYPE_FUNIT; 02280 exp->name = strdup_safe( scope ); 02281 02282 /* Restore the original functional unit */ 02283 db_end_function_task_namedblock( stmt->exp->line ); 02284 02285 } 02286 free_safe( scope, (strlen( scope ) + 1) ); 02287 02288 /* Reduce fork and block depth for the new statement */ 02289 fork_depth--; 02290 block_depth--; 02291 02292 Try { 02293 02294 /* Create FORK statement and add the expression */ 02295 stmt = db_create_statement( exp, stmt->ppline ); 02296 02297 } Catch_anonymous { 02298 expression_dealloc( exp, FALSE ); 02299 Throw 0; 02300 } 02301 02302 /* Restore fork and block depth values for parser */ 02303 fork_depth++; 02304 block_depth++; 02305 02306 } 02307 02308 PROFILE_END; 02309 02310 return( stmt ); 02311 02312 }
void db_parse_attribute | ( | attr_param * | ap, | |
int | line | |||
) |
Parses the specified attribute parameter list for Covered attributes.
anonymous | attribute_parse Throw |
Calls the attribute_parse() function and deallocates this list.
ap | Pointer to attribute parameter list to parse | |
line | First line of attribute |
References attribute_dealloc(), attribute_parse(), Catch_anonymous, DEBUG, debug_mode, exclude_mode, print_output(), PROFILE, PROFILE_END, Throw, and Try.
02763 { PROFILE(DB_PARSE_ATTRIBUTE); 02764 02765 #ifdef DEBUG_MODE 02766 if( debug_mode ) { 02767 print_output( "In db_parse_attribute", DEBUG, __FILE__, __LINE__ ); 02768 } 02769 #endif 02770 02771 Try { 02772 02773 /* First, parse the entire attribute */ 02774 attribute_parse( ap, line, curr_funit, (exclude_mode > 0) ); 02775 02776 } Catch_anonymous { 02777 attribute_dealloc( ap ); 02778 Throw 0; 02779 } 02780 02781 /* Then deallocate the structure */ 02782 attribute_dealloc( ap ); 02783 02784 PROFILE_END; 02785 02786 }
bool db_read | ( | const char * | file, | |
int | read_mode | |||
) |
Reads contents of database file and stores into internal lists.
anonymous | info_db_read args_db_read Throw Throw Throw expression_db_read fsm_db_read race_db_read funit_db_read vsignal_db_read funit_db_merge funit_db_merge statement_db_read |
Opens specified database file for reading. Reads in each line from the file examining its contents and creating the appropriate type to store the specified information and stores it into the appropriate internal list.
file | Name of database file to read contents from | |
read_mode | Specifies what to do with read data (see Modes for reading database file for legal values) |
References args_db_read(), Catch_anonymous, curr_db, DB_TYPE_EXCLUDE, DB_TYPE_EXPRESSION, DB_TYPE_FSM, DB_TYPE_FUNIT, DB_TYPE_FUNIT_VERSION, DB_TYPE_INFO, DB_TYPE_INST_ONLY, DB_TYPE_MERGED_CDD, DB_TYPE_MESSAGE, DB_TYPE_RACE, DB_TYPE_SCORE_ARGS, DB_TYPE_SIGNAL, DB_TYPE_STATEMENT, DEBUG, debug_mode, func_unit_s::end_line, exclude_db_merge(), exclude_db_read(), expression_db_read(), FALSE, FATAL, func_unit_s::filename, free_safe, fsm_db_read(), funit_link_s::funit, funit_inst_s::funit, funit_create(), funit_db_inst_merge(), funit_db_mod_merge(), funit_db_read(), funit_dealloc(), db_s::funit_head, funit_head, funit_link_add(), funit_link_find(), FUNIT_MODULE, funit_version_db_read(), info_db_read(), inst_head, db_s::inst_head, inst_link_add(), inst_link_display(), inst_link_find_by_scope(), instance_create(), instance_only_db_merge(), instance_only_db_read(), instance_read_add(), merged_cdd_db_read(), message_db_read(), func_unit_s::name, obf_file, func_unit_s::parent, isuppl_u::part, print_output(), PROFILE, PROFILE_END, race_db_read(), READ_MODE_MERGE_INST_MERGE, READ_MODE_MERGE_NO_MERGE, READ_MODE_NO_MERGE, READ_MODE_REPORT_MOD_MERGE, READ_MODE_REPORT_NO_MERGE, scope_extract_back(), scope_get_parent_funit(), scope_get_parent_module(), isuppl_u::scored, func_unit_s::start_line, statement_db_read(), strdup_safe, func_unit_s::tf_head, func_unit_s::tf_tail, Throw, func_unit_s::timescale, TRUE, Try, func_unit_s::type, user_msg, USER_MSG_LENGTH, util_readline(), and vsignal_db_read().
Referenced by command_exclude(), command_merge(), command_report(), covered_sim_calltf(), parse_and_score_dumpfile(), rank_read_cdd(), and report_read_cdd_and_ready().
00410 { PROFILE(DB_READ); 00411 00412 FILE* db_handle; /* Pointer to database file being read */ 00413 int type; /* Specifies object type */ 00414 func_unit tmpfunit; /* Temporary functional unit pointer */ 00415 char* curr_line; /* Pointer to current line being read from db */ 00416 unsigned int curr_line_size; /* Allocated number of bytes for curr_line */ 00417 char* rest_line; /* Pointer to rest of the current line */ 00418 int chars_read; /* Number of characters currently read on line */ 00419 char parent_scope[4096]; /* Scope of parent functional unit to the current instance */ 00420 char back[4096]; /* Current functional unit instance name */ 00421 char funit_scope[4096]; /* Current scope of functional unit instance */ 00422 char funit_name[256]; /* Current name of functional unit instance */ 00423 char funit_file[4096]; /* Current filename of functional unit instance */ 00424 funit_link* foundfunit; /* Found functional unit link */ 00425 funit_inst* foundinst; /* Found functional unit instance */ 00426 bool merge_mode = FALSE; /* If TRUE, we should currently be merging data */ 00427 func_unit* parent_mod; /* Pointer to parent module of this functional unit */ 00428 bool inst_name_diff; /* Specifies the read value of the name diff for the current instance */ 00429 bool stop_reading = FALSE; 00430 bool one_line_read = FALSE; 00431 00432 #ifdef DEBUG_MODE 00433 if( debug_mode ) { 00434 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_read, file: %s, mode: %d", obf_file( file ), read_mode ); 00435 assert( rv < USER_MSG_LENGTH ); 00436 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00437 } 00438 #endif 00439 00440 /* Setup temporary module for storage */ 00441 tmpfunit.name = funit_name; 00442 tmpfunit.filename = funit_file; 00443 00444 curr_funit = NULL; 00445 00446 if( (db_handle = fopen( file, "r" )) != NULL ) { 00447 00448 unsigned int rv; 00449 00450 Try { 00451 00452 while( !stop_reading && util_readline( db_handle, &curr_line, &curr_line_size ) ) { 00453 00454 one_line_read = TRUE; 00455 00456 Try { 00457 00458 if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) { 00459 00460 rest_line = curr_line + chars_read; 00461 00462 if( type == DB_TYPE_INFO ) { 00463 00464 stop_reading = !info_db_read( &rest_line, read_mode ); 00465 00466 /* Parse rest of line for general info */ 00467 if( !stop_reading ) { 00468 00469 /* If we are in report mode and this CDD file has not been written bow out now */ 00470 if( (info_suppl.part.scored == 0) && 00471 ((read_mode == READ_MODE_REPORT_NO_MERGE) || 00472 (read_mode == READ_MODE_REPORT_MOD_MERGE)) ) { 00473 print_output( "Attempting to generate report on non-scored design. Not supported.", FATAL, __FILE__, __LINE__ ); 00474 Throw 0; 00475 } 00476 00477 } 00478 00479 } else if( type == DB_TYPE_SCORE_ARGS ) { 00480 00481 assert( !merge_mode ); 00482 00483 /* Parse rest of line for argument info (if we are not instance merging) */ 00484 if( read_mode != READ_MODE_MERGE_INST_MERGE ) { 00485 args_db_read( &rest_line ); 00486 } 00487 00488 } else if( type == DB_TYPE_MESSAGE ) { 00489 00490 assert( !merge_mode ); 00491 00492 /* Parse rest of line for user-supplied message */ 00493 if( (read_mode != READ_MODE_MERGE_NO_MERGE) && (read_mode != READ_MODE_MERGE_INST_MERGE) ) { 00494 message_db_read( &rest_line ); 00495 } 00496 00497 } else if( type == DB_TYPE_MERGED_CDD ) { 00498 00499 assert( !merge_mode ); 00500 00501 /* Parse rest of line for merged CDD information */ 00502 merged_cdd_db_read( &rest_line ); 00503 00504 } else if( type == DB_TYPE_SIGNAL ) { 00505 00506 assert( !merge_mode ); 00507 00508 /* Parse rest of line for signal info */ 00509 vsignal_db_read( &rest_line, curr_funit ); 00510 00511 } else if( type == DB_TYPE_EXPRESSION ) { 00512 00513 assert( !merge_mode ); 00514 00515 /* Parse rest of line for expression info */ 00516 expression_db_read( &rest_line, curr_funit, (read_mode == READ_MODE_NO_MERGE) ); 00517 00518 } else if( type == DB_TYPE_STATEMENT ) { 00519 00520 assert( !merge_mode ); 00521 00522 /* Parse rest of line for statement info */ 00523 statement_db_read( &rest_line, curr_funit, read_mode ); 00524 00525 } else if( type == DB_TYPE_FSM ) { 00526 00527 assert( !merge_mode ); 00528 00529 /* Parse rest of line for FSM info */ 00530 fsm_db_read( &rest_line, curr_funit ); 00531 00532 } else if( type == DB_TYPE_EXCLUDE ) { 00533 00534 /* Parse rest of line for exclude info */ 00535 if( merge_mode ) { 00536 exclude_db_merge( curr_funit, &rest_line ); 00537 } else { 00538 exclude_db_read( &rest_line, curr_funit ); 00539 } 00540 00541 } else if( type == DB_TYPE_RACE ) { 00542 00543 assert( !merge_mode ); 00544 00545 /* Parse rest of line for race condition block info */ 00546 race_db_read( &rest_line, curr_funit ); 00547 00548 } else if( type == DB_TYPE_FUNIT_VERSION ) { 00549 00550 assert( !merge_mode ); 00551 00552 /* Parse rest of line for functional unit version information */ 00553 funit_version_db_read( curr_funit, &rest_line ); 00554 00555 } else if( (type == DB_TYPE_FUNIT ) || (type == DB_TYPE_INST_ONLY) ) { 00556 00557 /* Finish handling last functional unit read from CDD file */ 00558 if( curr_funit != NULL ) { 00559 00560 if( (read_mode != READ_MODE_MERGE_INST_MERGE) || !merge_mode ) { 00561 00562 /* Get the scope of the parent module */ 00563 scope_extract_back( funit_scope, back, parent_scope ); 00564 00565 /* Attempt to add it to the last instance tree */ 00566 if( (db_list[curr_db]->inst_tail == NULL) || 00567 !instance_read_add( &(db_list[curr_db]->inst_tail->inst), parent_scope, curr_funit, back ) ) { 00568 (void)inst_link_add( instance_create( curr_funit, funit_scope, inst_name_diff, FALSE, FALSE, NULL ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) ); 00569 } 00570 00571 } 00572 00573 /* If the current functional unit is a merged unit, don't add it to the funit list again */ 00574 if( !merge_mode ) { 00575 funit_link_add( curr_funit, &(db_list[curr_db]->funit_head), &(db_list[curr_db]->funit_tail) ); 00576 } 00577 00578 } 00579 00580 if( type == DB_TYPE_INST_ONLY ) { 00581 00582 /* Parse rest of the line for an instance-only structure */ 00583 if( !merge_mode ) { 00584 instance_only_db_read( &rest_line ); 00585 } else { 00586 instance_only_db_merge( &rest_line ); 00587 } 00588 00589 /* Specify that the current functional unit does not exist */ 00590 curr_funit = NULL; 00591 00592 } else { 00593 00594 /* Reset merge mode */ 00595 merge_mode = FALSE; 00596 00597 /* Now finish reading functional unit line */ 00598 funit_db_read( &tmpfunit, funit_scope, &inst_name_diff, &rest_line ); 00599 if( (read_mode == READ_MODE_MERGE_INST_MERGE) && 00600 ((foundinst = inst_link_find_by_scope( funit_scope, db_list[curr_db]->inst_head )) != NULL) ) { 00601 merge_mode = TRUE; 00602 curr_funit = foundinst->funit; 00603 funit_db_inst_merge( foundinst->funit, db_handle, TRUE ); 00604 } else if( (read_mode == READ_MODE_REPORT_MOD_MERGE) && 00605 ((foundfunit = funit_link_find( tmpfunit.name, tmpfunit.type, db_list[curr_db]->funit_head )) != NULL) ) { 00606 merge_mode = TRUE; 00607 curr_funit = foundfunit->funit; 00608 funit_db_mod_merge( foundfunit->funit, db_handle, FALSE ); 00609 } else { 00610 curr_funit = funit_create(); 00611 curr_funit->name = strdup_safe( funit_name ); 00612 curr_funit->type = tmpfunit.type; 00613 curr_funit->filename = strdup_safe( funit_file ); 00614 curr_funit->start_line = tmpfunit.start_line; 00615 curr_funit->end_line = tmpfunit.end_line; 00616 curr_funit->timescale = tmpfunit.timescale; 00617 if( tmpfunit.type != FUNIT_MODULE ) { 00618 curr_funit->parent = scope_get_parent_funit( db_list[curr_db]->inst_tail->inst, funit_scope ); 00619 parent_mod = scope_get_parent_module( db_list[curr_db]->inst_tail->inst, funit_scope ); 00620 funit_link_add( curr_funit, &(parent_mod->tf_head), &(parent_mod->tf_tail) ); 00621 } 00622 } 00623 00624 /* Set global functional unit, if it has been found */ 00625 if( (curr_funit != NULL) && (strncmp( curr_funit->name, "$root", 5 ) == 0) ) { 00626 global_funit = curr_funit; 00627 } 00628 00629 } 00630 00631 } else { 00632 00633 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unexpected type %d when parsing database file %s", type, obf_file( file ) ); 00634 assert( rv < USER_MSG_LENGTH ); 00635 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00636 Throw 0; 00637 00638 } 00639 00640 } else { 00641 00642 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unexpected line in database file %s", obf_file( file ) ); 00643 assert( rv < USER_MSG_LENGTH ); 00644 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00645 Throw 0; 00646 00647 } 00648 00649 } Catch_anonymous { 00650 00651 free_safe( curr_line, curr_line_size ); 00652 if( (read_mode != READ_MODE_MERGE_INST_MERGE) && (read_mode != READ_MODE_REPORT_MOD_MERGE) ) { 00653 funit_dealloc( curr_funit ); 00654 } 00655 Throw 0; 00656 00657 } 00658 00659 free_safe( curr_line, curr_line_size ); 00660 00661 } 00662 00663 } Catch_anonymous { 00664 00665 unsigned int rv = fclose( db_handle ); 00666 assert( rv == 0 ); 00667 Throw 0; 00668 00669 } 00670 00671 rv = fclose( db_handle ); 00672 assert( rv == 0 ); 00673 00674 } else { 00675 00676 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Could not open %s for reading", obf_file( file ) ); 00677 assert( rv < USER_MSG_LENGTH ); 00678 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00679 Throw 0; 00680 00681 } 00682 00683 /* If the last functional unit was being read, add it now */ 00684 if( curr_funit != NULL ) { 00685 00686 if( (read_mode != READ_MODE_MERGE_INST_MERGE) || !merge_mode ) { 00687 00688 /* Get the scope of the parent module */ 00689 scope_extract_back( funit_scope, back, parent_scope ); 00690 00691 /* Attempt to add it to the last instance tree */ 00692 if( (db_list[curr_db]->inst_tail == NULL) || 00693 !instance_read_add( &(db_list[curr_db]->inst_tail->inst), parent_scope, curr_funit, back ) ) { 00694 (void)inst_link_add( instance_create( curr_funit, funit_scope, inst_name_diff, FALSE, FALSE, NULL ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) ); 00695 } 00696 00697 } 00698 00699 /* If the current functional unit was being merged, don't add it to the functional unit list again */ 00700 if( !merge_mode ) { 00701 funit_link_add( curr_funit, &(db_list[curr_db]->funit_head), &(db_list[curr_db]->funit_tail) ); 00702 } 00703 00704 curr_funit = NULL; 00705 00706 } 00707 00708 #ifdef DEBUG_MODE 00709 /* Display the instance trees, if we are debugging */ 00710 if( debug_mode && (db_list != NULL) ) { 00711 inst_link_display( db_list[curr_db]->inst_head ); 00712 printf( "-----------------------------------\n" ); 00713 } 00714 #endif 00715 00716 /* Check to make sure that the CDD file contained valid information */ 00717 if( !stop_reading && !one_line_read ) { 00718 print_output( "CDD file was found to be empty", FATAL, __FILE__, __LINE__ ); 00719 Throw 0; 00720 } 00721 00722 PROFILE_END; 00723 00724 return( !stop_reading ); 00725 00726 }
void db_remove_statement | ( | statement * | stmt | ) |
Removes specified statement and associated expression from list and memory.
Removes specified statement expression and its tree from current module expression list and deallocates both the expression and statement from heap memory. Called when a statement structure is found to contain a statement that is not supported by Covered.
stmt | Pointer to statement to remove from memory |
References DEBUG, debug_mode, statement_s::exp, expression_s::id, expression_s::line, print_output(), PROFILE, PROFILE_END, statement_dealloc_recursive(), TRUE, user_msg, and USER_MSG_LENGTH.
02485 { PROFILE(DB_REMOVE_STATEMENT); 02486 02487 if( stmt != NULL ) { 02488 02489 #ifdef DEBUG_MODE 02490 if( debug_mode ) { 02491 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_remove_statement, stmt id: %d, line: %d", 02492 stmt->exp->id, stmt->exp->line ); 02493 assert( rv < USER_MSG_LENGTH ); 02494 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02495 } 02496 #endif 02497 02498 /* Call the recursive statement deallocation function */ 02499 statement_dealloc_recursive( stmt, TRUE ); 02500 02501 } 02502 02503 PROFILE_END; 02504 02505 }
void db_remove_statement_from_current_funit | ( | statement * | stmt | ) |
Removes specified statement from current functional unit.
Removes specified statement expression from the current functional unit. Called by statement_dealloc_recursive in statement.c in its deallocation algorithm.
stmt | Pointer to statement to remove from memory |
References curr_db, DEBUG, debug_mode, statement_s::exp, func_unit_s::exp_head, exp_link_remove(), func_unit_s::exp_tail, expression_string_op(), expression_s::id, inst_link_s::inst, db_s::inst_head, instance_remove_parms_with_expr(), expression_s::line, func_unit_s::name, inst_link_s::next, obf_funit, expression_s::op, print_output(), PROFILE, PROFILE_END, func_unit_s::stmt_head, stmt_link_unlink(), func_unit_s::stmt_tail, TRUE, user_msg, and USER_MSG_LENGTH.
Referenced by statement_dealloc_recursive().
02440 { PROFILE(DB_REMOVE_STATEMENT_FROM_CURRENT_FUNIT); 02441 02442 inst_link* instl; /* Pointer to current functional unit instance */ 02443 02444 if( (stmt != NULL) && (stmt->exp != NULL) ) { 02445 02446 #ifdef DEBUG_MODE 02447 if( debug_mode ) { 02448 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_remove_statement_from_current_funit %s, stmt id: %d, %s, line: %d", 02449 obf_funit( curr_funit->name ), stmt->exp->id, expression_string_op( stmt->exp->op ), stmt->exp->line ); 02450 assert( rv < USER_MSG_LENGTH ); 02451 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02452 } 02453 #endif 02454 02455 /* 02456 Get a list of all parameters within the given statement expression tree and remove them from 02457 an instance and module parameters. 02458 */ 02459 instl = db_list[curr_db]->inst_head; 02460 while( instl != NULL ) { 02461 instance_remove_parms_with_expr( instl->inst, stmt ); 02462 instl = instl->next; 02463 } 02464 02465 /* Remove expression from current module expression list and delete expressions */ 02466 exp_link_remove( stmt->exp, &(curr_funit->exp_head), &(curr_funit->exp_tail), TRUE ); 02467 02468 /* Remove this statement link from the current module's stmt_link list */ 02469 stmt_link_unlink( stmt, &(curr_funit->stmt_head), &(curr_funit->stmt_tail) ); 02470 02471 } 02472 02473 PROFILE_END; 02474 02475 }
void db_remove_stmt_blks_calling_statement | ( | statement * | stmt | ) |
Searches entire design for expressions that call the specified statement.
Searches the list of all expressions in all functional units that call the specified statement and returns these in a list format to the calling function. This function should only be called after the entire design has been parsed to be completely correct.
stmt | Pointer to statement to compare with all expressions |
References curr_db, inst_link_s::inst, db_s::inst_head, instance_remove_stmt_blks_calling_stmt(), inst_link_s::next, PROFILE, and PROFILE_END.
Referenced by stmt_blk_remove().
02801 { PROFILE(DB_REMOVE_STMT_BLKS_CALLING_STATEMENT); 02802 02803 inst_link* instl; /* Pointer to current instance */ 02804 02805 assert( stmt != NULL ); 02806 02807 instl = db_list[curr_db]->inst_head; 02808 while( instl != NULL ) { 02809 instance_remove_stmt_blks_calling_stmt( instl->inst, stmt ); 02810 instl = instl->next; 02811 } 02812 02813 PROFILE_END; 02814 02815 }
uint64 db_scale_to_precision | ( | uint64 | value, | |
func_unit * | funit | |||
) |
Returns a scaled version of the given value to the timescale for the given functional unit.
Takes in specified delay value and scales it to the correct timescale for the given module.
value | Delay value to scale | |
funit | Pointer to current functional unit of expression to scale |
References global_timescale_precision, PROFILE, PROFILE_END, and func_unit_s::ts_unit.
Referenced by funit_db_write().
00794 { PROFILE(DB_SCALE_TO_PRECISION); 00795 00796 int units = funit->ts_unit; 00797 00798 assert( units >= global_timescale_precision ); 00799 00800 while( units > global_timescale_precision ) { 00801 units--; 00802 value *= (uint64)10; 00803 } 00804 00805 PROFILE_END; 00806 00807 return( value ); 00808 00809 }
void db_set_symbol_char | ( | const char * | sym, | |
char | value | |||
) |
Sets the found symbol value to specified character value. Called by VCD lexer.
Searches the timestep symtable followed by the VCD symbol table searching for the symbol that matches the specified argument. Once a symbol is found, its value parameter is set to the specified character. If the symbol was found in the VCD symbol table, it is copied to the timestep symbol table.
sym | Name of symbol to set character value to | |
value | String version of value to set symbol table entry to |
References DEBUG, debug_mode, print_output(), PROFILE, PROFILE_END, symtable_set_value(), user_msg, and USER_MSG_LENGTH.
Referenced by fst_callback(), vcd_callback(), and vcd_parse_sim().
03002 { PROFILE(DB_SET_SYMBOL_CHAR); 03003 03004 char val[2]; /* Value to store */ 03005 03006 #ifdef DEBUG_MODE 03007 if( debug_mode ) { 03008 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_set_symbol_char, sym: %s, value: %c", sym, value ); 03009 assert( rv < USER_MSG_LENGTH ); 03010 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 03011 } 03012 #endif 03013 03014 /* Put together value string */ 03015 val[0] = value; 03016 val[1] = '\0'; 03017 03018 /* Set value of all matching occurrences in current timestep. */ 03019 symtable_set_value( sym, val ); 03020 03021 PROFILE_END; 03022 03023 }
void db_set_symbol_string | ( | const char * | sym, | |
const char * | value | |||
) |
Sets the found symbol value to specified string value. Called by VCD lexer.
Searches the timestep symtable followed by the VCD symbol table searching for the symbol that matches the specified argument. Once a symbol is found, its value parameter is set to the specified string. If the symbol was found in the VCD symbol table, it is copied to the timestep symbol table.
sym | Name of symbol to set character value to | |
value | String version of value to set symbol table entry to |
References DEBUG, debug_mode, print_output(), PROFILE, PROFILE_END, symtable_set_value(), user_msg, and USER_MSG_LENGTH.
Referenced by add_sym_values_to_sim(), covered_value_change_bin(), covered_value_change_real(), fst_callback(), vcd_callback(), vcd_parse_sim_real(), and vcd_parse_sim_vector().
03034 { PROFILE(DB_SET_SYMBOL_STRING); 03035 03036 #ifdef DEBUG_MODE 03037 if( debug_mode ) { 03038 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_set_symbol_string, sym: %s, value: %s", sym, value ); 03039 assert( rv < USER_MSG_LENGTH ); 03040 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 03041 } 03042 #endif 03043 03044 /* Set value of all matching occurrences in current timestep. */ 03045 symtable_set_value( sym, value ); 03046 03047 PROFILE_END; 03048 03049 }
void db_set_timescale | ( | int | unit, | |
int | precision | |||
) |
Sets the global timescale unit and precision variables.
unit | Timescale unit offset value | |
precision | Timescale precision offset value |
References current_timescale_unit, global_timescale_precision, PROFILE, and PROFILE_END.
00853 { PROFILE(DB_SET_TIMESCALE); 00854 00855 current_timescale_unit = unit; 00856 00857 /* Set the global precision value to the lowest precision value specified */ 00858 if( precision < global_timescale_precision ) { 00859 global_timescale_precision = precision; 00860 } 00861 00862 PROFILE_END; 00863 00864 }
void db_set_vcd_scope | ( | const char * | scope | ) |
Sets current VCD scope to specified scope.
Sets the curr_inst_scope global variable to the specified scope.
scope | Current VCD scope |
References curr_inst_scope, curr_inst_scope_size, db_sync_curr_instance(), DEBUG, debug_mode, obf_inst, print_output(), PROFILE, PROFILE_END, realloc_safe, strdup_safe, user_msg, and USER_MSG_LENGTH.
Referenced by fst_reader_process_hier(), and vcd_parse_def_scope().
02884 { PROFILE(DB_SET_VCD_SCOPE); 02885 02886 #ifdef DEBUG_MODE 02887 if( debug_mode ) { 02888 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_set_vcd_scope, scope: %s", obf_inst( scope ) ); 02889 assert( rv < USER_MSG_LENGTH ); 02890 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02891 } 02892 #endif 02893 02894 assert( scope != NULL ); 02895 02896 /* Create a new scope item */ 02897 curr_inst_scope = (char**)realloc_safe( curr_inst_scope, (sizeof( char* ) * curr_inst_scope_size), (sizeof( char* ) * (curr_inst_scope_size + 1)) ); 02898 curr_inst_scope[curr_inst_scope_size] = strdup_safe( scope ); 02899 curr_inst_scope_size++; 02900 02901 /* Synchronize the current instance to the value of curr_inst_scope */ 02902 db_sync_curr_instance(); 02903 02904 PROFILE_END; 02905 02906 }
Connects one statement block to another.
Calls the statement_connect function located in statement.c with the specified parameters. If the statement connection was not achieved, displays warning to user and returns FALSE. The calling function should throw this statement away.
curr_stmt | Pointer to current statement to attach | |
next_stmt | Pointer to next statement to attach to |
References DEBUG, debug_mode, statement_s::exp, func_unit_s::filename, expression_s::id, expression_s::line, obf_file, print_output(), PROFILE, PROFILE_END, statement_connect(), stmt_conn_id, user_msg, USER_MSG_LENGTH, and WARNING.
02669 { PROFILE(DB_STATEMENT_CONNECT); 02670 02671 bool retval; /* Return value for this function */ 02672 02673 #ifdef DEBUG_MODE 02674 if( debug_mode ) { 02675 int curr_id; /* Current statement ID */ 02676 int next_id; /* Next statement ID */ 02677 unsigned int rv; 02678 02679 if( curr_stmt == NULL ) { 02680 curr_id = 0; 02681 } else { 02682 curr_id = curr_stmt->exp->id; 02683 } 02684 02685 if( next_stmt == NULL ) { 02686 next_id = 0; 02687 } else { 02688 next_id = next_stmt->exp->id; 02689 } 02690 02691 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_statement_connect, curr_stmt: %d, next_stmt: %d", curr_id, next_id ); 02692 assert( rv < USER_MSG_LENGTH ); 02693 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02694 } 02695 #endif 02696 02697 /* 02698 Connect statement, if it was not successful, add it to the functional unit's statement list immediately 02699 as it will not be later on. 02700 */ 02701 if( !(retval = statement_connect( curr_stmt, next_stmt, stmt_conn_id )) ) { 02702 02703 unsigned int rv; 02704 02705 assert( next_stmt != NULL ); 02706 rv = snprintf( user_msg, USER_MSG_LENGTH, "Unreachable statement found starting at line %d in file %s. Ignoring...", 02707 next_stmt->exp->line, obf_file( curr_funit->filename ) ); 02708 assert( rv < USER_MSG_LENGTH ); 02709 print_output( user_msg, WARNING, __FILE__, __LINE__ ); 02710 02711 } 02712 02713 /* Increment stmt_conn_id for next statement connection */ 02714 stmt_conn_id++; 02715 02716 PROFILE_END; 02717 02718 return( retval ); 02719 02720 }
void db_sync_curr_instance | ( | ) |
Synchronizes the curr_instance pointer to match the curr_inst_scope hierarchy.
References curr_db, db_gen_curr_inst_scope(), free_safe, inst_head, inst_link_find_by_scope(), PROFILE, and PROFILE_END.
Referenced by covered_parse_instance(), covered_parse_task_func(), db_set_vcd_scope(), db_vcd_upscope(), and lxt_parse().
02854 { PROFILE(DB_SYNC_CURR_INSTANCE); 02855 02856 char stripped_scope[4096]; /* Temporary string */ 02857 char* scope; /* Current instance scope string */ 02858 02859 assert( db_list[curr_db]->leading_hier_num > 0 ); 02860 02861 if( (scope = db_gen_curr_inst_scope()) != NULL ) { 02862 02863 if( scope[0] != '\0' ) { 02864 curr_instance = inst_link_find_by_scope( scope, db_list[curr_db]->inst_head ); 02865 } 02866 02867 free_safe( scope, (strlen( scope ) + 1) ); 02868 02869 } else { 02870 02871 curr_instance = NULL; 02872 02873 } 02874 02875 PROFILE_END; 02876 02877 }
void db_vcd_upscope | ( | ) |
Moves current VCD hierarchy up one level.
Moves the curr_inst_scope up one level of hierarchy. This function is called when the $upscope keyword is seen in a VCD file.
References curr_inst_scope, curr_inst_scope_size, db_gen_curr_inst_scope(), db_sync_curr_instance(), DEBUG, debug_mode, free_safe, obf_inst, print_output(), PROFILE, PROFILE_END, realloc_safe, user_msg, and USER_MSG_LENGTH.
Referenced by fst_reader_process_hier(), and vcd_parse_def().
02912 { PROFILE(DB_VCD_UPSCOPE); 02913 02914 #ifdef DEBUG_MODE 02915 if( debug_mode ) { 02916 char* scope = db_gen_curr_inst_scope(); 02917 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_vcd_upscope, curr_inst_scope: %s", obf_inst( scope ) ); 02918 assert( rv < USER_MSG_LENGTH ); 02919 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 02920 free_safe( scope, (strlen( scope ) + 1) ); 02921 } 02922 #endif 02923 02924 /* Deallocate the last scope item */ 02925 if( curr_inst_scope_size > 0 ) { 02926 02927 curr_inst_scope_size--; 02928 free_safe( curr_inst_scope[curr_inst_scope_size], (strlen( curr_inst_scope[curr_inst_scope_size] ) + 1) ); 02929 curr_inst_scope = (char**)realloc_safe( curr_inst_scope, (sizeof( char* ) * (curr_inst_scope_size + 1)), (sizeof( char* ) * curr_inst_scope_size) ); 02930 02931 db_sync_curr_instance(); 02932 02933 } 02934 02935 PROFILE_END; 02936 02937 }
Writes contents of expressions, functional units and vsignals to database file.
anonymous | Throw Throw instance_db_write |
Opens specified database for writing. If database open successful, iterates through functional unit, expression and signal lists, displaying each to the database file. If database write successful, returns TRUE; otherwise, returns FALSE to the calling function.
file | Name of database file to output contents to | |
parse_mode | Specifies if we are outputting parse data or score data | |
issue_ids | Specifies if we need to issue/reissue expression and signal IDs |
References Catch_anonymous, curr_db, curr_expr_id, FATAL, inst_link_s::ignore, info_db_write(), inst_link_s::inst, db_s::inst_head, inst_head, instance_db_write(), funit_inst_s::name, inst_link_s::next, obf_file, print_output(), PROFILE, PROFILE_END, Throw, Try, user_msg, and USER_MSG_LENGTH.
Referenced by command_exclude(), command_merge(), covered_end_of_sim(), parse_and_score_dumpfile(), parse_design(), and report_save_cdd().
00342 { PROFILE(DB_WRITE); 00343 00344 FILE* db_handle; /* Pointer to database file being written */ 00345 inst_link* instl; /* Pointer to current instance link */ 00346 00347 if( (db_handle = fopen( file, "w" )) != NULL ) { 00348 00349 unsigned int rv; 00350 00351 Try { 00352 00353 /* Reset expression IDs */ 00354 curr_expr_id = 1; 00355 00356 /* Iterate through instance tree */ 00357 assert( db_list[curr_db]->inst_head != NULL ); 00358 info_db_write( db_handle ); 00359 00360 instl = db_list[curr_db]->inst_head; 00361 while( instl != NULL ) { 00362 00363 /* Only output the given instance tree if it is not ignored */ 00364 if( !instl->ignore ) { 00365 00366 /* Now write the instance */ 00367 instance_db_write( instl->inst, db_handle, instl->inst->name, parse_mode, issue_ids ); 00368 00369 } 00370 00371 instl = instl->next; 00372 00373 } 00374 00375 } Catch_anonymous { 00376 rv = fclose( db_handle ); 00377 assert( rv == 0 ); 00378 Throw 0; 00379 } 00380 00381 rv = fclose( db_handle ); 00382 assert( rv == 0 ); 00383 00384 } else { 00385 00386 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Could not open %s for writing", obf_file( file ) ); 00387 assert( rv < USER_MSG_LENGTH ); 00388 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00389 Throw 0; 00390 00391 } 00392 00393 PROFILE_END; 00394 00395 }