#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, bool report_save) |
| Writes contents of expressions, functional units and vsignals to database file. | |
| void | 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) |
| 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. | |
|
||||||||||||||||||||||||||||
|
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.
01305 { PROFILE(DB_ADD_DECLARED_PARAM);
01306
01307 mod_parm* mparm; /* Pointer to added module parameter */
01308
01309 assert( name != NULL );
01310
01311 /* If a parameter value type is not supported, don't create this parameter */
01312 if( expr != NULL ) {
01313
01314 #ifdef DEBUG_MODE
01315 if( debug_mode ) {
01316 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 );
01317 assert( rv < USER_MSG_LENGTH );
01318 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01319 }
01320 #endif
01321
01322 if( mod_parm_find( name, curr_funit->param_head ) == NULL ) {
01323
01324 /* Add parameter to module parameter list */
01325 mparm = mod_parm_add( name, msb, lsb, is_signed, expr, (local ? PARAM_TYPE_DECLARED_LOCAL : PARAM_TYPE_DECLARED), curr_funit, NULL );
01326
01327 }
01328
01329 }
01330
01331 PROFILE_END;
01332
01333 }
|
|
||||||||||||
|
Adds specified defparam to parameter override list. Called by parser. Adds specified parameter to the defparam list.
01411 { PROFILE(DB_ADD_DEFPARAM);
01412
01413 #ifdef DEBUG_MODE
01414 if( debug_mode ) {
01415 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_defparam, defparam: %s", obf_sig( name ) );
01416 assert( rv < USER_MSG_LENGTH );
01417 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01418 }
01419 #endif
01420
01421 {
01422 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "defparam construct is not supported, line: %d. Use -P option to score instead", expr->line );
01423 assert( rv < USER_MSG_LENGTH );
01424 print_output( user_msg, WARNING, __FILE__, __LINE__ );
01425 }
01426
01427 expression_dealloc( expr, FALSE );
01428
01429 PROFILE_END;
01430
01431 }
|
|
||||||||||||
|
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.
01589 { PROFILE(DB_ADD_ENUM);
01590
01591 assert( enum_sig != NULL );
01592
01593 #ifdef DEBUG_MODE
01594 if( debug_mode ) {
01595 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_enum, sig_name: %s", enum_sig->name );
01596 assert( rv < USER_MSG_LENGTH );
01597 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01598 }
01599 #endif
01600
01601 enumerate_add_item( enum_sig, value, curr_funit );
01602
01603 PROFILE_END;
01604
01605 }
|
|
|
Adds specified expression to expression list. Called by parser. Adds the specified expression to the current module's expression list.
02121 { PROFILE(DB_ADD_EXPRESSION);
02122
02123 if( (root != NULL) && (root->suppl.part.exp_added == 0) ) {
02124
02125 #ifdef DEBUG_MODE
02126 if( debug_mode ) {
02127 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_expression, id: %d, op: %s, line: %d",
02128 root->id, expression_string_op( root->op ), root->line );
02129 assert( rv < USER_MSG_LENGTH );
02130 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02131 }
02132 #endif
02133
02134 if( generate_top_mode > 0 ) {
02135
02136 if( root->suppl.part.gen_expr == 1 ) {
02137
02138 /* Add root expression to the generate item list for the current functional unit */
02139 last_gi = gen_item_create_expr( root );
02140
02141 /* Attach it to the curr_gi_block, if one exists */
02142 if( curr_gi_block != NULL ) {
02143 db_gen_item_connect( curr_gi_block, last_gi );
02144 } else {
02145 curr_gi_block = last_gi;
02146 }
02147
02148 }
02149
02150 } else {
02151
02152 /* Add expression's children first. */
02153 db_add_expression( root->right );
02154 db_add_expression( root->left );
02155
02156 /* Now add this expression to the list. */
02157 exp_link_add( root, &(curr_funit->exp_head), &(curr_funit->exp_tail) );
02158
02159 }
02160
02161 /* Specify that this expression has already been added */
02162 root->suppl.part.exp_added = 1;
02163
02164 }
02165
02166 PROFILE_END;
02167
02168 }
|
|
||||||||||||
|
Adds the given filename and version information to the database. Adds the given filename and version information to the database.
00952 { PROFILE(DB_ADD_FILE_VERSION);
00953
00954 str_link* strl;
00955
00956 #ifdef DEBUG_MODE
00957 if( debug_mode ) {
00958 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_file_version, file: %s, version: %s", obf_file( file ), version );
00959 assert( rv < USER_MSG_LENGTH );
00960 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
00961 }
00962 #endif
00963
00964 /* Add the new file version information */
00965 strl = str_link_add( strdup_safe( file ), &(db_list[curr_db]->fver_head), &(db_list[curr_db]->fver_tail) );
00966 strl->str2 = strdup_safe( version );
00967
00968 PROFILE_END;
00969
00970 }
|
|
|
Creates statement block that acts like a fork join block from a standard statement block.
|
|
||||||||||||||||||||
|
Adds specified task/function to functional unit list. Called by parser.
01182 { PROFILE(DB_ADD_FUNCTION_TASK_NAMEDBLOCK);
01183
01184 func_unit* tf = NULL; /* Pointer to created functional unit */
01185 func_unit* parent; /* Pointer to parent module for the newly created functional unit */
01186 char* full_name; /* Full name of function/task/namedblock which includes the parent module name */
01187
01188 assert( (type == FUNIT_FUNCTION) || (type == FUNIT_TASK) || (type == FUNIT_NAMED_BLOCK) ||
01189 (type == FUNIT_AFUNCTION) || (type == FUNIT_ATASK) );
01190
01191 #ifdef DEBUG_MODE
01192 if( debug_mode ) {
01193 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_function_task_namedblock, %s: %s, file: %s, start_line: %d",
01194 get_funit_type( type ), obf_funit( name ), obf_file( file ), start_line );
01195 assert( rv < USER_MSG_LENGTH );
01196 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01197 }
01198 #endif
01199
01200 /* Generate full name to use for the function/task */
01201 full_name = funit_gen_task_function_namedblock_name( name, curr_funit );
01202
01203 Try {
01204
01205 /* Add this as an instance so we can get scope */
01206 if( (tf = db_add_instance( name, full_name, type, NULL )) != NULL ) {
01207
01208 /* Get parent */
01209 parent = funit_get_curr_module( curr_funit );
01210
01211 if( generate_expr_mode > 0 ) {
01212 /* Change the recently created instance generate item to a TFN item */
01213 last_gi->suppl.part.type = GI_TYPE_TFN;
01214 } else {
01215 /* Store this functional unit in the parent module list */
01216 funit_link_add( tf, &(parent->tf_head), &(parent->tf_tail) );
01217 }
01218
01219 /* Set our parent pointer to the current functional unit */
01220 tf->parent = curr_funit;
01221
01222 /* If we are in an automatic task or function, set our type to FUNIT_ANAMED_BLOCK */
01223 if( (curr_funit->type == FUNIT_AFUNCTION) ||
01224 (curr_funit->type == FUNIT_ATASK) ||
01225 (curr_funit->type == FUNIT_ANAMED_BLOCK) ) {
01226 assert( tf->type == FUNIT_NAMED_BLOCK );
01227 tf->type = FUNIT_ANAMED_BLOCK;
01228 }
01229
01230 /* Set current functional unit to this functional unit */
01231 curr_funit = tf;
01232 curr_funit->filename = strdup_safe( file );
01233 curr_funit->start_line = start_line;
01234 curr_funit->ts_unit = current_timescale_unit;
01235
01236 }
01237
01238 } Catch_anonymous {
01239 free_safe( full_name, (strlen( full_name ) + 1) );
01240 Throw 0;
01241 }
01242
01243 free_safe( full_name, (strlen( full_name ) + 1) );
01244
01245 PROFILE_END;
01246
01247 return( tf != NULL );
01248
01249 }
|
|
|
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.
01723 { PROFILE(DB_ADD_GEN_ITEM_BLOCK);
01724
01725 if( gi != NULL ) {
01726
01727 /* Add the generate block to the list of generate blocks for this functional unit */
01728 gitem_link_add( gi, &(curr_funit->gitem_head), &(curr_funit->gitem_tail) );
01729
01730 }
01731
01732 PROFILE_END;
01733
01734 }
|
|
||||||||||||||||||||
|
Adds specified functional unit node to functional unit tree. Called by parser.
01005 { PROFILE(DB_ADD_INSTANCE);
01006
01007 func_unit* funit = NULL; /* Pointer to functional unit */
01008 funit_link* found_funit_link; /* Pointer to found funit_link in functional unit list */
01009 bool score; /* Specifies if this module should be scored */
01010
01011 /* There should always be a parent so internal error if it does not exist. */
01012 assert( curr_funit != NULL );
01013
01014 /* If this functional unit name is in our list of no_score functional units, skip adding the instance */
01015 score = str_link_find( name, no_score_head ) == NULL;
01016
01017 #ifdef DEBUG_MODE
01018 if( debug_mode ) {
01019 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_instance, instance: %s, %s: %s (curr_funit: %s)",
01020 obf_inst( scope ), get_funit_type( type ), obf_funit( name ), obf_funit( curr_funit->name ) );
01021 assert( rv < USER_MSG_LENGTH );
01022 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01023 }
01024 #endif
01025
01026 /* Create new functional unit node */
01027 funit = funit_create();
01028 funit->name = strdup_safe( name );
01029 funit->type = score ? type : FUNIT_NO_SCORE;
01030
01031 /* If a range has been specified, calculate its width and lsb now */
01032 if( (range != NULL) && score ) {
01033 if( (range->left != NULL) && (range->left->exp != NULL) ) {
01034 (void)mod_parm_add( NULL, NULL, NULL, FALSE, range->left->exp, PARAM_TYPE_INST_MSB, curr_funit, scope );
01035 }
01036 if( (range->right != NULL) && (range->right->exp != NULL) ) {
01037 (void)mod_parm_add( NULL, NULL, NULL, FALSE, range->right->exp, PARAM_TYPE_INST_LSB, curr_funit, scope );
01038 }
01039 }
01040
01041 if( ((found_funit_link = funit_link_find( funit->name, funit->type, db_list[curr_db]->funit_head )) != NULL) && (generate_top_mode == 0) ) {
01042
01043 if( type != FUNIT_MODULE ) {
01044 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Multiple identical task/function/named-begin-end names (%s) found in module %s, file %s",
01045 scope, obf_funit( curr_funit->name ), obf_file( curr_funit->filename ) );
01046 assert( rv < USER_MSG_LENGTH );
01047 print_output( user_msg, FATAL, __FILE__, __LINE__ );
01048 funit_dealloc( funit );
01049 Throw 0;
01050 }
01051
01052 if( (last_gi == NULL) || (last_gi->suppl.part.type != GI_TYPE_INST) ||
01053 !instance_parse_add( &last_gi->elem.inst, curr_funit, found_funit_link->funit, scope, range, FALSE, TRUE, FALSE, FALSE ) ) {
01054 inst_link* instl = db_list[curr_db]->inst_head;
01055 while( (instl != NULL) && !instance_parse_add( &instl->inst, curr_funit, found_funit_link->funit, scope, range, FALSE, FALSE, FALSE, FALSE ) ) {
01056 instl = instl->next;
01057 }
01058 if( instl == NULL ) {
01059 (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) );
01060 }
01061 }
01062
01063 funit_dealloc( funit );
01064
01065 } else {
01066
01067 /* Add new functional unit to functional unit list. */
01068 funit_link_add( funit, &(db_list[curr_db]->funit_head), &(db_list[curr_db]->funit_tail) );
01069
01070 /* If we are currently within a generate block, create a generate item for this instance to resolve it later */
01071 if( generate_top_mode > 0 ) {
01072 last_gi = gen_item_create_inst( instance_create( funit, scope, FALSE, FALSE, FALSE, range ) );
01073 if( curr_gi_block != NULL ) {
01074 db_gen_item_connect( curr_gi_block, last_gi );
01075 } else {
01076 curr_gi_block = last_gi;
01077 }
01078 }
01079
01080 /* Add the instance to the instance tree in the proper place */
01081 {
01082 inst_link* instl = db_list[curr_db]->inst_head;
01083 while( (instl != NULL) && !instance_parse_add( &instl->inst, curr_funit, funit, scope, range, FALSE, FALSE, (generate_top_mode > 0), (generate_expr_mode > 0) ) ) {
01084 instl = instl->next;
01085 }
01086 if( instl == NULL ) {
01087 (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) );
01088 }
01089 }
01090
01091 if( (type == FUNIT_MODULE) && score && (str_link_find( name, modlist_head ) == NULL) ) {
01092 (void)str_link_add( strdup_safe( name ), &modlist_head, &modlist_tail );
01093 }
01094
01095 }
01096
01097 PROFILE_END;
01098
01099 return( score ? funit : NULL );
01100
01101 }
|
|
||||||||||||||||
|
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.
01113 { PROFILE(DB_ADD_MODULE);
01114
01115 funit_link* modl; /* Pointer to found tree node */
01116
01117 #ifdef DEBUG_MODE
01118 if( debug_mode ) {
01119 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_module, module: %s, file: %s, start_line: %d",
01120 obf_funit( name ), obf_file( file ), start_line );
01121 assert( rv < USER_MSG_LENGTH );
01122 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01123 }
01124 #endif
01125
01126 modl = funit_link_find( name, FUNIT_MODULE, db_list[curr_db]->funit_head );
01127
01128 assert( modl != NULL );
01129
01130 curr_funit = modl->funit;
01131 curr_funit->filename = strdup_safe( file );
01132 curr_funit->start_line = start_line;
01133 curr_funit->ts_unit = current_timescale_unit;
01134
01135 /* Clear the unnamed scope ID */
01136 unnamed_scope_id = 0;
01137
01138 PROFILE_END;
01139
01140 }
|
|
||||||||||||||||
|
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.
01343 { PROFILE(DB_ADD_OVERRIDE_PARAM);
01344
01345 mod_parm* mparm; /* Pointer to module parameter added to current module */
01346
01347 #ifdef DEBUG_MODE
01348 if( debug_mode ) {
01349 unsigned int rv;
01350 if( param_name != NULL ) {
01351 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_override_param, instance: %s, param_name: %s",
01352 obf_inst( inst_name ), obf_sig( param_name ) );
01353 } else {
01354 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_override_param, instance: %s", obf_inst( inst_name ) );
01355 }
01356 assert( rv < USER_MSG_LENGTH );
01357 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01358 }
01359 #endif
01360
01361 /* Add override parameter to module parameter list */
01362 mparm = mod_parm_add( param_name, NULL, NULL, FALSE, expr, PARAM_TYPE_OVERRIDE, curr_funit, inst_name );
01363
01364 PROFILE_END;
01365
01366 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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.
01450 { PROFILE(DB_ADD_SIGNAL);
01451
01452 vsignal* sig = NULL; /* Container for newly created signal */
01453 sig_link* sigl; /* Pointer to found signal link */
01454 unsigned int i; /* Loop iterator */
01455 int j = 0; /* Loop iterator */
01456
01457 #ifdef DEBUG_MODE
01458 if( debug_mode ) {
01459 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 );
01460 assert( rv < USER_MSG_LENGTH );
01461 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01462 }
01463 #endif
01464
01465 /* Add signal to current module's signal list if it does not already exist */
01466 if( (sigl = sig_link_find( name, curr_funit->sig_head )) == NULL ) {
01467
01468 /* Create the signal */
01469 if( (type == SSUPPL_TYPE_GENVAR) || (type == SSUPPL_TYPE_DECL_SREAL) ) {
01470 /* For genvars and shortreals, set the size to 32, automatically */
01471 sig = vsignal_create( name, type, 32, line, col );
01472 } else if( type == SSUPPL_TYPE_DECL_REAL ) {
01473 /* For real types, they should be automatically sized to 64, automatically */
01474 sig = vsignal_create( name, type, 64, line, col );
01475 } else {
01476 /* For normal signals just make the width a value of 1 for now -- it will be resized during funit_resize_elements */
01477 sig = vsignal_create( name, type, 1, line, col );
01478 }
01479
01480 /* If the signal has currently existed, check to see if the signal is unsized, and, if so, size it now */
01481 } else if( sigl->sig->suppl.part.implicit_size ) {
01482
01483 sig = sigl->sig;
01484 sig->suppl.part.implicit_size = 0;
01485
01486 }
01487
01488 /* Check all of the dimensions within range and create vector parameters, if necessary */
01489 if( sig != NULL ) {
01490 if( sig->dim != NULL ) {
01491 free_safe( sig->dim, (sizeof( dim_range ) * (sig->pdim_num + sig->udim_num)) );
01492 }
01493 assert( prange != NULL );
01494 sig->udim_num = (urange != NULL) ? urange->dim_num : 0;
01495 sig->pdim_num = prange->dim_num;
01496 assert( (sig->pdim_num + sig->udim_num) > 0 );
01497 sig->dim = (dim_range*)malloc_safe( sizeof( dim_range ) * (sig->pdim_num + sig->udim_num) );
01498 for( i=0; i<sig->udim_num; i++ ) {
01499 assert( urange->dim[i].left != NULL );
01500 if( urange->dim[i].left->exp != NULL ) {
01501 db_add_vector_param( sig, urange->dim[i].left->exp, PARAM_TYPE_SIG_MSB, j );
01502 } else {
01503 sig->dim[j].msb = urange->dim[i].left->num;
01504 }
01505 assert( urange->dim[i].right != NULL );
01506 if( urange->dim[i].right->exp != NULL ) {
01507 db_add_vector_param( sig, urange->dim[i].right->exp, PARAM_TYPE_SIG_LSB, j );
01508 } else {
01509 sig->dim[j].lsb = urange->dim[i].right->num;
01510 }
01511 j++;
01512 }
01513 for( i=0; i<sig->pdim_num; i++ ) {
01514 assert( prange->dim[i].left != NULL );
01515 if( prange->dim[i].left->exp != NULL ) {
01516 db_add_vector_param( sig, prange->dim[i].left->exp, PARAM_TYPE_SIG_MSB, j );
01517 } else {
01518 sig->dim[j].msb = prange->dim[i].left->num;
01519 }
01520 assert( prange->dim[i].right != NULL );
01521 if( prange->dim[i].right->exp != NULL ) {
01522 db_add_vector_param( sig, prange->dim[i].right->exp, PARAM_TYPE_SIG_LSB, j );
01523 } else {
01524 sig->dim[j].lsb = prange->dim[i].right->num;
01525 }
01526 j++;
01527 }
01528
01529 /* If exclude_mode is not zero, set the exclude bit in the signal */
01530 sig->suppl.part.excluded = (exclude_mode > 0) ? 1 : 0;
01531
01532 /* Specify that we should not deallocate the expressions */
01533 if( prange != NULL ) {
01534 prange->exp_dealloc = FALSE;
01535 }
01536 if( urange != NULL ) {
01537 urange->exp_dealloc = FALSE;
01538 }
01539 }
01540
01541 /* Only do the following if the signal was not previously found */
01542 if( sigl == NULL ) {
01543
01544 /* Add the signal to either the functional unit or a generate item */
01545 if( (generate_top_mode > 0) && (type != SSUPPL_TYPE_GENVAR) ) {
01546 last_gi = gen_item_create_sig( sig );
01547 if( curr_gi_block != NULL ) {
01548 db_gen_item_connect( curr_gi_block, last_gi );
01549 } else {
01550 curr_gi_block = last_gi;
01551 }
01552 } else {
01553 /* Add signal to current module's signal list */
01554 sig_link_add( sig, &(curr_funit->sig_head), &(curr_funit->sig_tail) );
01555 }
01556
01557 /* Indicate if signal must be assigned by simulated results or not */
01558 if( mba ) {
01559 sig->suppl.part.mba = 1;
01560 sig->suppl.part.assigned = 1;
01561 }
01562
01563 /* Indicate signed attribute */
01564 sig->value->suppl.part.is_signed = is_signed;
01565
01566 /* Indicate handled attribute */
01567 sig->suppl.part.not_handled = handled ? 0 : 1;
01568
01569 /* Set the implicit_size attribute */
01570 sig->suppl.part.implicit_size = (((type == SSUPPL_TYPE_INPUT_NET) || (type == SSUPPL_TYPE_INPUT_REG) ||
01571 (type == SSUPPL_TYPE_OUTPUT_NET) || (type == SSUPPL_TYPE_OUTPUT_REG) ||
01572 (type == SSUPPL_TYPE_INOUT_NET) || (type == SSUPPL_TYPE_INOUT_REG)) &&
01573 (prange != NULL) && prange->dim[0].implicit &&
01574 (prange->dim[0].left->exp == NULL) && (prange->dim[0].left->num == 0) &&
01575 (prange->dim[0].right->exp == NULL) && (prange->dim[0].right->num == 0)) ? 1 : 0;
01576
01577 }
01578
01579 PROFILE_END;
01580
01581 }
|
|
||||||||||||
|
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.
02369 { PROFILE(DB_ADD_STATEMENT);
02370
02371 if( (stmt != NULL) && (stmt->suppl.part.added == 0) ) {
02372
02373 #ifdef DEBUG_MODE
02374 if( debug_mode ) {
02375 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_statement, id: %d, start id: %d", stmt->exp->id, start->exp->id );
02376 assert( rv < USER_MSG_LENGTH );
02377 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02378 }
02379 #endif
02380
02381 /* Now add current statement */
02382 if( generate_top_mode > 0 ) {
02383
02384 last_gi = gen_item_create_stmt( stmt );
02385
02386 if( curr_gi_block != NULL ) {
02387 db_gen_item_connect( curr_gi_block, last_gi );
02388 } else {
02389 curr_gi_block = last_gi;
02390 }
02391
02392 } else {
02393
02394 /* Add the associated expression tree */
02395 db_add_expression( stmt->exp );
02396
02397 /* Add TRUE and FALSE statement paths to list */
02398 if( (stmt->suppl.part.stop_false == 0) && (stmt->next_false != start) ) {
02399 db_add_statement( stmt->next_false, start );
02400 }
02401
02402 if( (stmt->suppl.part.stop_true == 0) && (stmt->next_true != stmt->next_false) && (stmt->next_true != start) ) {
02403 db_add_statement( stmt->next_true, start );
02404 }
02405
02406 /* Set ADDED bit of this statement */
02407 stmt->suppl.part.added = 1;
02408
02409 /* Finally, add the statement to the functional unit statement list */
02410 stmt_link_add_tail( stmt, &(curr_funit->stmt_head), &(curr_funit->stmt_tail) );
02411
02412 }
02413
02414 }
02415
02416 PROFILE_END;
02417
02418 }
|
|
||||||||||||||||||||||||||||
|
Adds given typedefs to the database. Adds the given names and information to the list of typedefs for the current module.
01634 { PROFILE(DB_ADD_TYPEDEF);
01635
01636 typedef_item* tdi; /* Typedef item to create */
01637
01638 #ifdef DEBUG_MODE
01639 if( debug_mode ) {
01640 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_add_typedef, name: %s, is_signed: %d, is_handled: %d, is_sizeable: %d",
01641 name, is_signed, is_handled, is_sizeable );
01642 assert( rv < USER_MSG_LENGTH );
01643 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01644 }
01645 #endif
01646
01647 /* Allocate memory and initialize the structure */
01648 tdi = (typedef_item*)malloc_safe( sizeof( typedef_item ) );
01649 tdi->name = strdup_safe( name );
01650 tdi->is_signed = is_signed;
01651 tdi->is_handled = is_handled;
01652 tdi->is_sizeable = is_sizeable;
01653 tdi->prange = prange;
01654 tdi->urange = urange;
01655 tdi->next = NULL;
01656
01657 /* Add it the current module's typedef list */
01658 if( curr_funit->tdi_head == NULL ) {
01659 curr_funit->tdi_head = curr_funit->tdi_tail = tdi;
01660 } else {
01661 curr_funit->tdi_tail->next = tdi;
01662 curr_funit->tdi_tail = tdi;
01663 }
01664
01665 /* Specify that the prange and urange expressions should not be deallocated */
01666 if( prange != NULL ) {
01667 prange->exp_dealloc = FALSE;
01668 }
01669 if( urange != NULL ) {
01670 urange->exp_dealloc = FALSE;
01671 }
01672
01673 PROFILE_END;
01674
01675 }
|
|
||||||||||||||||||||
|
Adds symbol to signal specified by name. Creates a new entry in the symbol table for the specified signal and symbol.
02937 { PROFILE(DB_ASSIGN_SYMBOL);
02938
02939 #ifdef DEBUG_MODE
02940 if( debug_mode ) {
02941 char* scope = db_gen_curr_inst_scope();
02942 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",
02943 obf_sig( name ), symbol, obf_inst( scope ), msb, lsb );
02944 assert( rv < USER_MSG_LENGTH );
02945 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02946 free_safe( scope, (strlen( scope ) + 1) );
02947 }
02948 #endif
02949
02950 assert( name != NULL );
02951
02952 if( (curr_instance != NULL) && (curr_instance->funit != NULL) ) {
02953
02954 sig_link* sigl;
02955 vsignal* sig;
02956 func_unit* found_funit;
02957
02958 /* Find the signal that matches the specified signal name */
02959 if( ((sigl = sig_link_find( name, curr_instance->funit->sig_head )) != NULL) ||
02960 scope_find_signal( name, curr_instance->funit, &sig, &found_funit, 0 ) ) {
02961
02962 /* If the signal exists in the current scope, assign the signal pointer to our temporary pointer */
02963 if( sigl != NULL ) {
02964 sig = sigl->sig;
02965 }
02966
02967 /* Only add the symbol if we are not going to generate this value ourselves */
02968 if( (sig->suppl.part.assigned == 0) &&
02969 (sig->suppl.part.type != SSUPPL_TYPE_PARAM) &&
02970 (sig->suppl.part.type != SSUPPL_TYPE_PARAM_REAL) &&
02971 (sig->suppl.part.type != SSUPPL_TYPE_ENUM) &&
02972 (sig->suppl.part.type != SSUPPL_TYPE_MEM) &&
02973 (sig->suppl.part.type != SSUPPL_TYPE_GENVAR) &&
02974 (sig->suppl.part.type != SSUPPL_TYPE_EVENT) ) {
02975
02976 /* Add this signal */
02977 symtable_add( symbol, sig, msb, lsb );
02978
02979 }
02980
02981 }
02982
02983 }
02984
02985 PROFILE_END;
02986
02987 }
|
|
||||||||||||
|
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.
02021 { PROFILE(DB_BIND_EXPR_TREE);
02022
02023 assert( sig_name != NULL );
02024
02025 if( root != NULL ) {
02026
02027 #ifdef DEBUG_MODE
02028 if( debug_mode ) {
02029 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_bind_expr_tree, root id: %d, sig_name: %s", root->id, sig_name );
02030 assert( rv < USER_MSG_LENGTH );
02031 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02032 }
02033 #endif
02034
02035 /* Bind the children first */
02036 db_bind_expr_tree( root->left, sig_name );
02037 db_bind_expr_tree( root->right, sig_name );
02038
02039 /* Now bind ourselves if necessary */
02040 if( (root->op == EXP_OP_SBIT_SEL) ||
02041 (root->op == EXP_OP_MBIT_SEL) ||
02042 (root->op == EXP_OP_MBIT_POS) ||
02043 (root->op == EXP_OP_MBIT_NEG) ) {
02044 bind_add( 0, sig_name, root, curr_funit );
02045 }
02046
02047 }
02048
02049 PROFILE_END;
02050
02051 }
|
|
|
Checks to see if the module specified by the -t option is the top-level module of the simulator.
00311 { PROFILE(DB_CHECK_FOR_TOP_MODULE);
00312
00313 bool retval;
00314 funit_inst* top_inst;
00315
00316 /* Get the top-most instance */
00317 instance_get_leading_hierarchy( db_list[curr_db]->inst_tail->inst, NULL, &top_inst );
00318
00319 /* Check to see if the signal list is void of ports */
00320 retval = funit_is_top_module( top_inst->funit );
00321
00322 PROFILE_END;
00323
00324 return( retval );
00325
00326 }
|
|
|
Deallocates all memory consumed by the database. Deallocates all memory associated with the databases.
00235 { PROFILE(DB_CLOSE);
00236
00237 unsigned int i, j;
00238
00239 for( i=0; i<db_size; i++ ) {
00240
00241 if( db_list[i]->inst_head != NULL ) {
00242
00243 /* Remove memory allocated for inst_head */
00244 inst_link_delete_list( db_list[i]->inst_head );
00245 db_list[i]->inst_head = NULL;
00246 db_list[i]->inst_tail = NULL;
00247
00248 /* Remove memory allocated for all functional units */
00249 funit_link_delete_list( &(db_list[i]->funit_head), &(db_list[i]->funit_tail), TRUE );
00250
00251 }
00252
00253 /* Deallocate all information regarding hierarchies */
00254 for( j=0; j<db_list[i]->leading_hier_num; j++ ) {
00255 free_safe( db_list[i]->leading_hierarchies[j], (strlen( db_list[i]->leading_hierarchies[j] ) + 1) );
00256 }
00257 free_safe( db_list[i]->leading_hierarchies, (sizeof( char* ) * db_list[i]->leading_hier_num) );
00258
00259 /* Deallocate the file version information */
00260 str_link_delete_list( db_list[i]->fver_head );
00261 db_list[i]->fver_head = NULL;
00262 db_list[i]->fver_tail = NULL;
00263
00264 /* Deallocate database structure */
00265 free_safe( db_list[i], sizeof( db ) );
00266
00267 }
00268
00269 /* Clear the global functional unit */
00270 global_funit = NULL;
00271
00272 /* Deallocate preprocessor define tree */
00273 tree_dealloc( def_table );
00274 def_table = NULL;
00275
00276 /* Deallocate the binding list */
00277 bind_dealloc();
00278
00279 /* Deallocate database information */
00280 info_dealloc();
00281
00282 /* Deallocate the needed module list */
00283 str_link_delete_list( modlist_head );
00284 modlist_head = NULL;
00285 modlist_tail = NULL;
00286
00287 /* Free memory associated with current instance scope */
00288 assert( curr_inst_scope_size == 0 );
00289
00290 /* Deallocate the exclusion identifier container, if it exists */
00291 free_safe( exclusion_id, db_get_exclusion_id_size() );
00292
00293 /* Finally, deallocate the database list */
00294 free_safe( db_list, (sizeof( db ) * db_size) );
00295 db_list = NULL;
00296 db_size = 0;
00297 curr_db = 0;
00298
00299 PROFILE_END;
00300
00301 }
|
|
||||||||||||
|
Connects false statement to specified statement. Connects the specified statement's false statement.
02537 { PROFILE(DB_CONNECT_STATEMENT_FALSE);
02538
02539 #ifdef DEBUG_MODE
02540 int next_id; /* Statement ID of next FALSE statement */
02541 #endif
02542
02543 if( stmt != NULL ) {
02544
02545 #ifdef DEBUG_MODE
02546 if( debug_mode ) {
02547 unsigned int rv;
02548 if( next_false == NULL ) {
02549 next_id = 0;
02550 } else {
02551 next_id = next_false->exp->id;
02552 }
02553
02554 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_connect_statement_false, id: %d, next: %d", stmt->exp->id, next_id );
02555 assert( rv < USER_MSG_LENGTH );
02556 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02557 }
02558 #endif
02559
02560 stmt->next_false = next_false;
02561
02562 }
02563
02564 PROFILE_END;
02565
02566 }
|
|
||||||||||||
|
Connects true statement to specified statement. Connects the specified statement's true statement.
02500 { PROFILE(DB_CONNECT_STATEMENT_TRUE);
02501
02502 #ifdef DEBUG_MODE
02503 int next_id; /* Statement ID of next TRUE statement */
02504 #endif
02505
02506 if( stmt != NULL ) {
02507
02508 #ifdef DEBUG_MODE
02509 if( debug_mode ) {
02510 unsigned int rv;
02511 if( next_true == NULL ) {
02512 next_id = 0;
02513 } else {
02514 next_id = next_true->exp->id;
02515 }
02516
02517 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_connect_statement_true, id: %d, next: %d", stmt->exp->id, next_id );
02518 assert( rv < USER_MSG_LENGTH );
02519 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02520 }
02521 #endif
02522
02523 stmt->next_true = next_true;
02524
02525 }
02526
02527 PROFILE_END;
02528
02529 }
|
|
|
Creates a new database.
00205 { PROFILE(DB_CREATE);
00206
00207 db* new_db; /* Pointer to new database structure */
00208
00209 /* Allocate new database */
00210 new_db = (db*)malloc_safe( sizeof( db ) );
00211 new_db->inst_head = NULL;
00212 new_db->inst_tail = NULL;
00213 new_db->funit_head = NULL;
00214 new_db->funit_tail = NULL;
00215 new_db->fver_head = NULL;
00216 new_db->fver_tail = NULL;
00217 new_db->leading_hierarchies = NULL;
00218 new_db->leading_hier_num = 0;
00219 new_db->leading_hiers_differ = FALSE;
00220
00221 /* Add this new database to the database array */
00222 db_list = (db**)realloc_safe( db_list, (sizeof( db ) * db_size), (sizeof( db ) * (db_size + 1)) );
00223 db_list[db_size] = new_db;
00224 db_size++;
00225
00226 PROFILE_END;
00227
00228 return( new_db );
00229
00230 }
|
|
||||||||||||
|
Allocates and initializes an attribute parameter.
02714 { PROFILE(DB_CREATE_ATTR_PARAM);
02715
02716 attr_param* attr; /* Pointer to newly allocated/initialized attribute parameter */
02717
02718 #ifdef DEBUG_MODE
02719 if( debug_mode ) {
02720 unsigned int rv;
02721 if( expr != NULL ) {
02722 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_attr_param, name: %s, expr: %d", name, expr->id );
02723 } else {
02724 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_attr_param, name: %s", name );
02725 }
02726 assert( rv < USER_MSG_LENGTH );
02727 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02728 }
02729 #endif
02730
02731 attr = attribute_create( name, expr );
02732
02733 PROFILE_END;
02734
02735 return( attr );
02736
02737 }
|
|
||||||||||||||||||||
|
Creates an expression from the specified static expression.
02065 { PROFILE(DB_CREATE_EXPR_FROM_STATIC);
02066
02067 expression* expr = NULL; /* Return value for this function */
02068 vector* vec; /* Temporary vector */
02069
02070 #ifdef DEBUG_MODE
02071 if( debug_mode ) {
02072 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",
02073 se, line, first_col, last_col );
02074 assert( rv < USER_MSG_LENGTH );
02075 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02076 }
02077 #endif
02078
02079 Try {
02080
02081 if( se->exp == NULL ) {
02082
02083 /* This static expression is a static value so create a static expression from its value */
02084 expr = db_create_expression( NULL, NULL, EXP_OP_STATIC, FALSE, line, first_col, last_col, NULL );
02085
02086 /* Create the new vector */
02087 vec = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE );
02088 (void)vector_from_int( vec, se->num );
02089
02090 /* Assign the new vector to the expression's vector (after deallocating the expression's old vector) */
02091 assert( expr->value->value.ul == NULL );
02092 free_safe( expr->value, sizeof( vector ) );
02093 expr->value = vec;
02094
02095 } else {
02096
02097 /* The static expression is unresolved, so just get its expression */
02098 expr = se->exp;
02099
02100 }
02101
02102 } Catch_anonymous {
02103 static_expr_dealloc( se, FALSE );
02104 Throw 0;
02105 }
02106
02107 /* Deallocate static expression */
02108 static_expr_dealloc( se, FALSE );
02109
02110 PROFILE_END;
02111
02112 return( expr );
02113
02114 }
|
|
||||||||||||||||||||||||||||||||||||
|
Creates new expression from specified information. Called by parser and db_add_expression.
01879 { PROFILE(DB_CREATE_EXPRESSION);
01880
01881 expression* expr; /* Temporary pointer to newly created expression */
01882 func_unit* func_funit; /* Pointer to function, if we are nested in one */
01883
01884 #ifdef DEBUG_MODE
01885 if( debug_mode ) {
01886 int right_id; /* ID of right expression */
01887 int left_id; /* ID of left expression */
01888 unsigned int rv; /* Return value from snprintf call */
01889
01890 if( right == NULL ) {
01891 right_id = 0;
01892 } else {
01893 right_id = right->id;
01894 }
01895
01896 if( left == NULL ) {
01897 left_id = 0;
01898 } else {
01899 left_id = left->id;
01900 }
01901
01902 if( sig_name == NULL ) {
01903 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",
01904 right_id, left_id, curr_expr_id, expression_string_op( op ), lhs, line, first, last );
01905 } else {
01906 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",
01907 right_id, left_id, curr_expr_id, expression_string_op( op ), lhs, line, first, last, sig_name );
01908 }
01909 assert( rv < USER_MSG_LENGTH );
01910 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01911 }
01912 #endif
01913
01914 /* Check to see if current expression is in a function */
01915 func_funit = funit_get_curr_function( curr_funit );
01916
01917 /* Check to make sure that expression is allowed for the current functional unit type */
01918 if( (func_funit != NULL) &&
01919 ((op == EXP_OP_DELAY) ||
01920 (op == EXP_OP_TASK_CALL) ||
01921 (op == EXP_OP_NASSIGN) ||
01922 (op == EXP_OP_PEDGE) ||
01923 (op == EXP_OP_NEDGE) ||
01924 (op == EXP_OP_AEDGE) ||
01925 (op == EXP_OP_EOR)) ) {
01926 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",
01927 obf_funit( func_funit->name ), obf_file( curr_funit->filename ), line );
01928 assert( rv < USER_MSG_LENGTH );
01929 print_output( user_msg, FATAL, __FILE__, __LINE__ );
01930 Throw 0;
01931 }
01932
01933 /* Create expression with next expression ID */
01934 expr = expression_create( right, left, op, lhs, curr_expr_id, line, first, last, FALSE );
01935 curr_expr_id++;
01936
01937 /* If current functional unit is nested in a function, set the IN_FUNC supplemental field bit */
01938 expr->suppl.part.in_func = (func_funit != NULL) ? 1 : 0;
01939
01940 /* Set the clear_changed bit if any of our children have their clear_changed bit set or if we are a system function expression */
01941 if( ((left != NULL) &&
01942 ((left->suppl.part.clear_changed == 1) ||
01943 (left->op == EXP_OP_STIME) || (left->op == EXP_OP_SRANDOM) || (left->op == EXP_OP_SURANDOM) || (left->op == EXP_OP_SURAND_RANGE) ||
01944 (left->op == EXP_OP_SB2R) || (left->op == EXP_OP_SR2B) || (left->op == EXP_OP_SI2R) || (left->op == EXP_OP_SR2I) ||
01945 (left->op == EXP_OP_SB2SR) || (left->op == EXP_OP_SSR2B))) ||
01946 ((right != NULL) &&
01947 ((right->suppl.part.clear_changed == 1) ||
01948 (right->op == EXP_OP_STIME) || (right->op == EXP_OP_SRANDOM) || (right->op == EXP_OP_SURANDOM) || (right->op == EXP_OP_SURAND_RANGE) ||
01949 (right->op == EXP_OP_SB2R) || (right->op == EXP_OP_SR2B) || (right->op == EXP_OP_SI2R) || (right->op == EXP_OP_SR2I) ||
01950 (right->op == EXP_OP_SB2SR) || (right->op == EXP_OP_SSR2B))) ) {
01951 expr->suppl.part.clear_changed = 1;
01952 }
01953
01954 /* If we are in exclude mode, set the exclude and stmt_exclude bits */
01955 if( exclude_mode > 0 ) {
01956 expr->suppl.part.excluded = 1;
01957 }
01958
01959 /* If this expression is in the for control, set its bit */
01960 if( for_mode > 0 ) {
01961 expr->suppl.part.for_cntrl = 1;
01962 }
01963
01964 /*
01965 If this is some kind of assignment expression operator, set the our expression vector to that of
01966 the right expression.
01967 */
01968 if( (expr->op == EXP_OP_BASSIGN) ||
01969 (expr->op == EXP_OP_NASSIGN) ||
01970 (expr->op == EXP_OP_RASSIGN) ||
01971 (expr->op == EXP_OP_DASSIGN) ||
01972 (expr->op == EXP_OP_ASSIGN) ||
01973 (expr->op == EXP_OP_IF) ||
01974 (expr->op == EXP_OP_WHILE) ||
01975 (expr->op == EXP_OP_DIM) ||
01976 (expr->op == EXP_OP_DLY_ASSIGN) ) {
01977 vector_dealloc( expr->value );
01978 expr->suppl.part.owns_vec = 0;
01979 expr->value = right->value;
01980 }
01981
01982 /* Add expression and signal to binding list */
01983 if( sig_name != NULL ) {
01984
01985 /*
01986 If we are in a generate block and the signal name contains a generate variable/expression,
01987 create a generate item to handle the binding later.
01988 */
01989 if( (generate_mode > 0) && gen_item_varname_contains_genvar( sig_name ) ) {
01990 last_gi = gen_item_create_bind( sig_name, expr );
01991 if( curr_gi_block != NULL ) {
01992 db_gen_item_connect( curr_gi_block, last_gi );
01993 } else {
01994 curr_gi_block = last_gi;
01995 }
01996 } else {
01997 switch( op ) {
01998 case EXP_OP_FUNC_CALL : bind_add( FUNIT_FUNCTION, sig_name, expr, curr_funit ); break;
01999 case EXP_OP_TASK_CALL : bind_add( FUNIT_TASK, sig_name, expr, curr_funit ); break;
02000 case EXP_OP_NB_CALL : bind_add( FUNIT_NAMED_BLOCK, sig_name, expr, curr_funit ); break;
02001 case EXP_OP_DISABLE : bind_add( 1, sig_name, expr, curr_funit ); break;
02002 default : bind_add( 0, sig_name, expr, curr_funit ); break;
02003 }
02004 }
02005
02006 }
02007
02008 PROFILE_END;
02009
02010 return( expr );
02011
02012 }
|
|
|
Creates an expression tree sensitivity list for the given statement block.
02177 { PROFILE(DB_CREATE_SENSITIVITY_LIST);
02178
02179 str_link* sig_head = NULL; /* Pointer to head of signal name list containing RHS used signals */
02180 str_link* sig_tail = NULL; /* Pointer to tail of signal name list containing RHS used signals */
02181 str_link* strl; /* Pointer to current signal name link */
02182 expression* exps; /* Pointer to created expression for type SIG */
02183 expression* expa; /* Pointer to created expression for type AEDGE */
02184 expression* expe; /* Pointer to created expression for type EOR */
02185 expression* expc = NULL; /* Pointer to left child expression */
02186
02187 /* Get the list of all RHS signals in the given statement block */
02188 statement_find_rhs_sigs( stmt, &sig_head, &sig_tail );
02189
02190 /* Create sensitivity expression tree for the list of RHS signals */
02191 if( sig_head != NULL ) {
02192
02193 Try {
02194
02195 strl = sig_head;
02196 while( strl != NULL ) {
02197
02198 /* Create AEDGE and EOR for subsequent signals */
02199 exps = db_create_expression( NULL, NULL, EXP_OP_SIG, FALSE, 0, 0, 0, strl->str );
02200 expa = db_create_expression( exps, NULL, EXP_OP_AEDGE, FALSE, 0, 0, 0, NULL );
02201
02202 /* If we have a child expression already, create the EOR expression to connect them */
02203 if( expc != NULL ) {
02204 expe = db_create_expression( expa, expc, EXP_OP_EOR, FALSE, 0, 0, 0, NULL );
02205 expc = expe;
02206 } else {
02207 expc = expa;
02208 }
02209
02210 strl = strl->next;
02211
02212 }
02213
02214 } Catch_anonymous {
02215 str_link_delete_list( sig_head );
02216 Throw 0;
02217 }
02218
02219 /* Deallocate string list */
02220 str_link_delete_list( sig_head );
02221
02222 }
02223
02224 PROFILE_END;
02225
02226 return( expc );
02227
02228 }
|
|
||||||||||||
|
Creates new statement expression from specified information. Called by parser.
02315 { PROFILE(DB_CREATE_STATEMENT);
02316
02317 statement* stmt = NULL; /* Pointer to newly created statement */
02318
02319 /* If the statement expression is NULL, we can't create the statement */
02320 if( exp != NULL ) {
02321
02322 #ifdef DEBUG_MODE
02323 if( debug_mode ) {
02324 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_create_statement, id: %d, line: %d", exp->id, exp->line );
02325 assert( rv < USER_MSG_LENGTH );
02326 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02327 }
02328 #endif
02329
02330 /* Create the given statement */
02331 stmt = statement_create( exp, curr_funit, ppline );
02332
02333 /* If we are in the exclude mode, exclude this statement */
02334 if( exclude_mode > 0 ) {
02335 stmt->suppl.part.excluded = 1;
02336 }
02337
02338 /* If we need to exclude this statement from race condition checking, do so */
02339 if( ignore_racecheck_mode > 0 ) {
02340 stmt->suppl.part.ignore_rc = 1;
02341 }
02342
02343 Try {
02344
02345 /* If we are a parallel statement, create a FORK statement for this statement block */
02346 stmt = db_parallelize_statement( stmt );
02347
02348 } Catch_anonymous {
02349 statement_dealloc( stmt );
02350 expression_dealloc( exp, FALSE );
02351 Throw 0;
02352 }
02353
02354 }
02355
02356 PROFILE_END;
02357
02358 return( stmt );
02359
02360 }
|
|
|
Creates a scope name for an unnamed scope. Called only during parsing.
00794 { PROFILE(DB_CREATE_UNNAMED_SCOPE);
00795
00796 char tmpname[30];
00797 char* name;
00798 unsigned int rv = snprintf( tmpname, 30, "$u%d", unnamed_scope_id );
00799
00800 assert( rv < 30 );
00801
00802 name = strdup_safe( tmpname );
00803 unnamed_scope_id++;
00804
00805 PROFILE_END;
00806
00807 return( name );
00808
00809 }
|
|
||||||||||||
|
Performs a timestep for all signal changes during this timestep.
03061 { PROFILE(DB_DO_TIMESTEP);
03062
03063 bool retval; /* Return value for this function */
03064 static sim_time curr_time;
03065 static uint64 last_sim_update = 0;
03066
03067 #ifdef DEBUG_MODE
03068 if( debug_mode ) {
03069 if( final ) {
03070 print_output( "Performing final timestep", DEBUG, __FILE__, __LINE__ );
03071 } else {
03072 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Performing timestep #%lld", time );
03073 assert( rv < USER_MSG_LENGTH );
03074 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
03075 }
03076 }
03077 #endif
03078
03079 num_timesteps++;
03080
03081 curr_time.lo = (time & 0xffffffffLL);
03082 curr_time.hi = ((time >> 32) & 0xffffffffLL);
03083 curr_time.full = time;
03084 curr_time.final = final;
03085
03086 if( (timestep_update > 0) && ((time - last_sim_update) >= timestep_update) && !debug_mode && !final ) {
03087 unsigned int rv;
03088 last_sim_update = time;
03089 /*@-formattype -duplicatequals@*/
03090 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 %10llu", time );
03091 /*@=formattype =duplicatequals@*/
03092 rv = fflush( stdout );
03093 assert( rv == 0 );
03094 }
03095
03096 /* Simulate the current timestep */
03097 retval = sim_simulate( &curr_time );
03098
03099 /* If this is the last timestep, add the final list and do one more simulate */
03100 if( final && retval ) {
03101 curr_time.lo = 0xffffffff;
03102 curr_time.hi = 0xffffffff;
03103 curr_time.full = 0xffffffffffffffffLL;
03104 retval = sim_simulate( &curr_time );
03105 }
03106
03107 #ifdef DEBUG_MODE
03108 if( debug_mode ) {
03109 print_output( "Assigning postsimulation signals...", DEBUG, __FILE__, __LINE__ );
03110 }
03111 #endif
03112
03113 if( retval ) {
03114
03115 /* Assign all stored values in current post-timestep to stored signals */
03116 symtable_assign( &curr_time );
03117
03118 /* Perform non-blocking assignment */
03119 sim_perform_nba( &curr_time );
03120
03121 }
03122
03123 PROFILE_END;
03124
03125 return( retval );
03126
03127 }
|
|
|
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.
01610 { PROFILE(DB_END_ENUM_LIST);
01611
01612 #ifdef DEBUG_MODE
01613 if( debug_mode ) {
01614 print_output( "In db_end_enum_list", DEBUG, __FILE__, __LINE__ );
01615 }
01616 #endif
01617
01618 enumerate_end_list( curr_funit );
01619
01620 PROFILE_END;
01621
01622 }
|
|
|
Called when the endfunction or endtask keyword is parsed.
|
|
|
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.
01256 { PROFILE(DB_END_FUNCTION_TASK_NAMEDBLOCK);
01257
01258 stmt_iter si; /* Statement iterator for finding the first statement of the functional unit */
01259
01260 #ifdef DEBUG_MODE
01261 if( debug_mode ) {
01262 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_end_function_task_namedblock, end_line: %d", end_line );
01263 assert( rv < USER_MSG_LENGTH );
01264 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01265 }
01266 #endif
01267
01268 /* Store last line information */
01269 curr_funit->end_line = end_line;
01270
01271 /* Set the first statement pointer */
01272 if( curr_funit->stmt_head != NULL ) {
01273
01274 assert( curr_funit->stmt_head->stmt != NULL );
01275
01276 /* Set functional unit's first_stmt pointer to its head statement */
01277 stmt_iter_reset( &si, curr_funit->stmt_tail );
01278 stmt_iter_find_head( &si, FALSE );
01279
01280 if( si.curr->stmt != NULL ) {
01281 curr_funit->first_stmt = si.curr->stmt;
01282 }
01283
01284 }
01285
01286 /* Set the current functional unit to the parent module */
01287 curr_funit = curr_funit->parent;
01288
01289 PROFILE_END;
01290
01291 }
|
|
|
Called when the endmodule keyword is parsed. Updates the modlist for parsing purposes.
01147 { PROFILE(DB_END_MODULE);
01148
01149 #ifdef DEBUG_MODE
01150 if( debug_mode ) {
01151 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_end_module, end_line: %d", end_line );
01152 assert( rv < USER_MSG_LENGTH );
01153 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01154 }
01155 #endif
01156
01157 curr_funit->end_line = end_line;
01158
01159 str_link_remove( curr_funit->name, &modlist_head, &modlist_tail );
01160
01161 /* Return the current functional unit to the global functional unit, if it exists */
01162 curr_funit = global_funit;
01163
01164 PROFILE_END;
01165
01166 }
|
|
||||||||||||
|
Find specified generate item in the current functional unit. Called by parser.
01748 { PROFILE(DB_FIND_GEN_ITEM);
01749
01750 gen_item* found; /* Return value for this function */
01751
01752 #ifdef DEBUG_MODE
01753 if( debug_mode ) {
01754 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_find_gen_item, type %d", gi->suppl.part.type );
01755 assert( rv < USER_MSG_LENGTH );
01756 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01757 }
01758 #endif
01759
01760 /* Search for the specified generate item */
01761 found = gen_item_find( root, gi );
01762
01763 /* Deallocate the user-specified generate item */
01764 gen_item_dealloc( gi, FALSE );
01765
01766 PROFILE_END;
01767
01768 return( found );
01769
01770 }
|
|
||||||||||||
|
Finds specified signal in functional unit and returns pointer to the signal structure. Called by parser.
01689 { PROFILE(DB_FIND_SIGNAL);
01690
01691 vsignal* found_sig; /* Pointer to found signal (return value) */
01692 func_unit* found_funit; /* Pointer to found functional unit (not used) */
01693
01694 #ifdef DEBUG_MODE
01695 if( debug_mode ) {
01696 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_find_signal, searching for signal %s", obf_sig( name ) );
01697 assert( rv < USER_MSG_LENGTH );
01698 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01699 }
01700 #endif
01701
01702 if( !scope_find_signal( name, curr_funit, &found_sig, &found_funit, 0 ) && !okay_if_not_found ) {
01703
01704 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 ) );
01705 assert( rv < USER_MSG_LENGTH );
01706 print_output( user_msg, FATAL, __FILE__, __LINE__ );
01707 Throw 0;
01708
01709 }
01710
01711 PROFILE_END;
01712
01713 return( found_sig );
01714
01715 }
|
|
|
Finds specified typedef and returns TRUE if it is found.
01779 { PROFILE(DB_FIND_TYPEDEF);
01780
01781 func_unit* parent; /* Pointer to parent module */
01782 typedef_item* tdi = NULL; /* Pointer to current typedef item */
01783
01784 assert( name != NULL );
01785
01786 #ifdef DEBUG_MODE
01787 if( debug_mode ) {
01788 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_find_typedef, searching for name: %s", name );
01789 assert( rv < USER_MSG_LENGTH );
01790 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
01791 }
01792 #endif
01793
01794 if( curr_funit != NULL ) {
01795
01796 parent = funit_get_curr_module( curr_funit );
01797
01798 tdi = parent->tdi_head;
01799 while( (tdi != NULL) && (strcmp( tdi->name, name ) != 0) ) {
01800 tdi = tdi->next;
01801 }
01802
01803 /* If we could not find the typedef in the current functional unit, look in the global funit, if it exists */
01804 if( (tdi == NULL) && (global_funit != NULL) ) {
01805 tdi = global_funit->tdi_head;
01806 while( (tdi != NULL) && (strcmp( tdi->name, name ) != 0) ) {
01807 tdi = tdi->next;
01808 }
01809 }
01810
01811 }
01812
01813 PROFILE_END;
01814
01815 return( tdi );
01816
01817 }
|
|
||||||||||||
|
Allocates memory for and generates the exclusion identifier.
00918 { PROFILE(DB_GEN_EXCLUSION_ID);
00919
00920 char tmp[30];
00921 int size = db_get_exclusion_id_size();
00922 unsigned int rv;
00923
00924 /* If the exclusion ID has not been created, create it now */
00925 if( exclusion_id == NULL ) {
00926
00927 /* Allocate the memory needed */
00928 exclusion_id = (char*)malloc_safe( size );
00929
00930 }
00931
00932 /* Create format string */
00933 rv = snprintf( tmp, 30, "%%c%%0%dd", (size - 2) );
00934 assert( rv < 30 );
00935
00936 /* Generate exclusion_id string */
00937 rv = snprintf( exclusion_id, size, tmp, type, id );
00938 assert( rv < size );
00939
00940 PROFILE_END;
00941
00942 return( exclusion_id );
00943
00944 }
|
|
||||||||||||
|
Connects one generate item block to another. Connects two generate items together.
02622 { PROFILE(DB_GEN_ITEM_CONNECT);
02623
02624 bool rv;
02625
02626 #ifdef DEBUG_MODE
02627 if( debug_mode ) {
02628 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 );
02629 assert( rv < USER_MSG_LENGTH );
02630 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02631 }
02632 #endif
02633
02634 /* Connect generate items */
02635 rv = gen_item_connect( gi1, gi2, gi_conn_id, FALSE );
02636 assert( rv );
02637
02638 /* Increment gi_conn_id for next connection */
02639 gi_conn_id++;
02640
02641 PROFILE_END;
02642
02643 }
|
|
||||||||||||
|
Connects gi2 to the false path of gi1. Connects gi2 to gi1's next_false pointer.
02598 { PROFILE(DB_GEN_ITEM_CONNECT_FALSE);
02599
02600 assert( gi1 != NULL );
02601
02602 #ifdef DEBUG_MODE
02603 if( debug_mode ) {
02604 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_gen_item_connect_false, gi1: %p, gi2: %p", gi1, gi2 );
02605 assert( rv < USER_MSG_LENGTH );
02606 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02607 }
02608 #endif
02609
02610 gi1->next_false = gi2;
02611
02612 PROFILE_END;
02613
02614 }
|
|
||||||||||||
|
Connects gi2 to the true path of gi1. Connects gi2 to gi1's next_true pointer.
02574 { PROFILE(DB_GEN_ITEM_CONNECT_TRUE);
02575
02576 assert( gi1 != NULL );
02577
02578 #ifdef DEBUG_MODE
02579 if( debug_mode ) {
02580 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_gen_item_connect_true, gi1: %p, gi2: %p", gi1, gi2 );
02581 assert( rv < USER_MSG_LENGTH );
02582 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02583 }
02584 #endif
02585
02586 gi1->next_true = gi2;
02587
02588 PROFILE_END;
02589
02590 }
|
|
|
Returns a pointer to the current functional unit.
00851 { PROFILE(DB_GET_CURR_FUNIT);
00852
00853 PROFILE_END;
00854
00855 return( curr_funit );
00856
00857 }
|
|
|
Returns a pointer to the current implicitly connected generate block. Called by parser.
01822 { PROFILE(DB_GET_CURR_GEN_BLOCK);
01823
01824 gen_item* block = curr_gi_block; /* Temporary pointer to current generate item block */
01825
01826 #ifdef DEBUG_MODE
01827 if( debug_mode ) {
01828 print_output( "In db_get_curr_gen_block", DEBUG, __FILE__, __LINE__ );
01829 }
01830 #endif
01831
01832 /* Clear the curr_gi_block and last_gi pointers */
01833 curr_gi_block = NULL;
01834 last_gi = NULL;
01835
01836 PROFILE_END;
01837
01838 return( block );
01839
01840 }
|
|
|
Calculates and returns the size of the exclusion ID string.
00862 { PROFILE(DB_GET_EXCLUSION_ID_SIZE);
00863
00864 static unsigned int exclusion_id_size = 0;
00865
00866 if( exclusion_id_size == 0 ) {
00867
00868 char tmp[30];
00869 unsigned int rv;
00870
00871 /* Calculate the size needed to store the largest signal ID */
00872 rv = snprintf( tmp, 30, "%d", curr_sig_id );
00873 assert( rv < 30 );
00874 exclusion_id_size = strlen( tmp ) + 2;
00875
00876 /* Now calculate the size needed to store the largest expression ID */
00877 rv = snprintf( tmp, 30, "%d", curr_expr_id );
00878 assert( rv < 30 );
00879
00880 /* Figure out which value is greater and use that for the size of the exclusion ID */
00881 if( (strlen( tmp ) + 2) > exclusion_id_size ) {
00882 exclusion_id_size = strlen( tmp ) + 2;
00883 }
00884
00885 /* Now calculate the size needed to store the largest arc ID */
00886 rv = snprintf( tmp, 30, "%d", curr_arc_id );
00887 assert( rv < 30 );
00888
00889 /* Figure out which value is greater and use that for the size of the exclusion ID */
00890 if( (strlen( tmp ) + 2) > exclusion_id_size ) {
00891 exclusion_id_size = strlen( tmp ) + 2;
00892 }
00893
00894 /* The minimum size of the exclusion ID should be 3 characters */
00895 if( exclusion_id_size < 4 ) {
00896 exclusion_id_size = 4;
00897 }
00898
00899 }
00900
00901 PROFILE_END;
00902
00903 return( exclusion_id_size );
00904
00905 }
|
|
|
Returns TRUE if the given scope is an unnamed scope name; otherwise, returns FALSE.
00816 { PROFILE(DB_IS_UNNAMED_SCOPE);
00817
00818 bool is_unnamed = (scope != NULL) && (scope[0] == '$') && (scope[1] == 'u');
00819
00820 PROFILE_END;
00821
00822 return( is_unnamed );
00823
00824 }
|
|
|
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.
00721 { PROFILE(DB_MERGE_INSTANCE_TREES);
00722
00723 funit_inst* base = NULL;
00724 inst_link* instl = db_list[curr_db]->inst_head;
00725 bool done = FALSE;
00726
00727 /* Merge all root trees */
00728 instl = db_list[curr_db]->inst_head;
00729 while( instl != NULL ) {
00730 if( strcmp( instl->inst->name, "$root" ) == 0 ) {
00731 if( base == NULL ) {
00732 base = instl->inst;
00733 instl->base = TRUE;
00734 } else {
00735 instl->ignore = instance_merge_two_trees( base, instl->inst );
00736 }
00737 }
00738 instl = instl->next;
00739 }
00740
00741 /* Merge all other trees */
00742 while( !done ) {
00743 base = NULL;
00744 instl = db_list[curr_db]->inst_head;
00745 while( instl != NULL ) {
00746 if( strcmp( instl->inst->name, "$root" ) != 0 ) {
00747 if( !instl->ignore && !instl->base ) {
00748 if( base == NULL ) {
00749 base = instl->inst;
00750 instl->base = TRUE;
00751 } else {
00752 instl->ignore = instance_merge_two_trees( base, instl->inst );
00753 }
00754 }
00755 }
00756 instl = instl->next;
00757 }
00758 done = (base == NULL);
00759 }
00760
00761 PROFILE_END;
00762
00763 }
|
|
|
Outputs all needed signals in $dumpvars calls to the specified file. Outputs all signals that need to be dumped to the given files.
00977 { PROFILE(DB_OUTPUT_DUMPVARS);
00978
00979 inst_link* instl = db_list[curr_db]->inst_head;
00980
00981 while( instl != NULL ) {
00982 instance_output_dumpvars( vfile, instl->inst );
00983 instl = instl->next;
00984 }
00985
00986 PROFILE_END;
00987
00988 }
|
|
|
Checks specified statement for parallelization and if it must be, creates a parallel statement block.
02238 { PROFILE(DB_PARALLELIZE_STATEMENT);
02239
02240 expression* exp; /* Expression containing FORK statement */
02241 char* scope; /* Name of current parallelized statement scope */
02242
02243 /* If we are a parallel statement, create a FORK statement for this statement block */
02244 if( (stmt != NULL) && (fork_depth != -1) && (fork_block_depth[fork_depth] == block_depth) ) {
02245
02246 #ifdef DEBUG_MODE
02247 if( debug_mode ) {
02248 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",
02249 stmt->exp->id, expression_string_op( stmt->exp->op ), stmt->exp->line, fork_depth, block_depth, fork_block_depth[fork_depth] );
02250 assert( rv < USER_MSG_LENGTH );
02251 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02252 }
02253 #endif
02254
02255 /* Create FORK expression */
02256 exp = db_create_expression( NULL, NULL, EXP_OP_FORK, FALSE, stmt->exp->line, ((stmt->exp->col & 0xffff0000) >> 16), (stmt->exp->col & 0xffff), NULL );
02257
02258 /* Create unnamed scope */
02259 scope = db_create_unnamed_scope();
02260 if( db_add_function_task_namedblock( FUNIT_NAMED_BLOCK, scope, curr_funit->filename, stmt->exp->line ) ) {
02261
02262 /* Create a thread block for this statement block */
02263 stmt->suppl.part.head = 1;
02264 stmt->suppl.part.is_called = 1;
02265 db_add_statement( stmt, stmt );
02266
02267 /* Bind the FORK expression now */
02268 exp->elem.funit = curr_funit;
02269 exp->suppl.part.type = ETYPE_FUNIT;
02270 exp->name = strdup_safe( scope );
02271
02272 /* Restore the original functional unit */
02273 db_end_function_task_namedblock( stmt->exp->line );
02274
02275 }
02276 free_safe( scope, (strlen( scope ) + 1) );
02277
02278 /* Reduce fork and block depth for the new statement */
02279 fork_depth--;
02280 block_depth--;
02281
02282 Try {
02283
02284 /* Create FORK statement and add the expression */
02285 stmt = db_create_statement( exp, stmt->ppline );
02286
02287 } Catch_anonymous {
02288 expression_dealloc( exp, FALSE );
02289 Throw 0;
02290 }
02291
02292 /* Restore fork and block depth values for parser */
02293 fork_depth++;
02294 block_depth++;
02295
02296 }
02297
02298 PROFILE_END;
02299
02300 return( stmt );
02301
02302 }
|
|
|
Parses the specified attribute parameter list for Covered attributes.
02746 { PROFILE(DB_PARSE_ATTRIBUTE);
02747
02748 #ifdef DEBUG_MODE
02749 if( debug_mode ) {
02750 print_output( "In db_parse_attribute", DEBUG, __FILE__, __LINE__ );
02751 }
02752 #endif
02753
02754 Try {
02755
02756 /* First, parse the entire attribute */
02757 attribute_parse( ap, curr_funit, (exclude_mode > 0) );
02758
02759 } Catch_anonymous {
02760 attribute_dealloc( ap );
02761 Throw 0;
02762 }
02763
02764 /* Then deallocate the structure */
02765 attribute_dealloc( ap );
02766
02767 PROFILE_END;
02768
02769 }
|
|
||||||||||||
|
Reads contents of database file and stores into internal lists.
00407 { PROFILE(DB_READ);
00408
00409 FILE* db_handle; /* Pointer to database file being read */
00410 int type; /* Specifies object type */
00411 func_unit tmpfunit; /* Temporary functional unit pointer */
00412 char* curr_line; /* Pointer to current line being read from db */
00413 unsigned int curr_line_size; /* Allocated number of bytes for curr_line */
00414 char* rest_line; /* Pointer to rest of the current line */
00415 int chars_read; /* Number of characters currently read on line */
00416 char parent_scope[4096]; /* Scope of parent functional unit to the current instance */
00417 char back[4096]; /* Current functional unit instance name */
00418 char funit_scope[4096]; /* Current scope of functional unit instance */
00419 char funit_name[256]; /* Current name of functional unit instance */
00420 char funit_file[4096]; /* Current filename of functional unit instance */
00421 funit_link* foundfunit; /* Found functional unit link */
00422 funit_inst* foundinst; /* Found functional unit instance */
00423 bool merge_mode = FALSE; /* If TRUE, we should currently be merging data */
00424 func_unit* parent_mod; /* Pointer to parent module of this functional unit */
00425 bool inst_name_diff; /* Specifies the read value of the name diff for the current instance */
00426
00427 #ifdef DEBUG_MODE
00428 if( debug_mode ) {
00429 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_read, file: %s, mode: %d", obf_file( file ), read_mode );
00430 assert( rv < USER_MSG_LENGTH );
00431 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
00432 }
00433 #endif
00434
00435 /* Setup temporary module for storage */
00436 tmpfunit.name = funit_name;
00437 tmpfunit.filename = funit_file;
00438
00439 curr_funit = NULL;
00440
00441 if( (db_handle = fopen( file, "r" )) != NULL ) {
00442
00443 unsigned int rv;
00444
00445 Try {
00446
00447 while( util_readline( db_handle, &curr_line, &curr_line_size ) ) {
00448
00449 Try {
00450
00451 if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) {
00452
00453 rest_line = curr_line + chars_read;
00454
00455 if( type == DB_TYPE_INFO ) {
00456
00457 (void)db_create();
00458
00459 /* Parse rest of line for general info */
00460 info_db_read( &rest_line );
00461
00462 /* If we are in report mode and this CDD file has not been written bow out now */
00463 if( (info_suppl.part.scored == 0) &&
00464 ((read_mode == READ_MODE_REPORT_NO_MERGE) ||
00465 (read_mode == READ_MODE_REPORT_MOD_MERGE)) ) {
00466 print_output( "Attempting to generate report on non-scored design. Not supported.", FATAL, __FILE__, __LINE__ );
00467 Throw 0;
00468 }
00469
00470 } else if( type == DB_TYPE_SCORE_ARGS ) {
00471
00472 assert( !merge_mode );
00473
00474 /* Parse rest of line for argument info (if we are not instance merging) */
00475 if( read_mode != READ_MODE_MERGE_INST_MERGE ) {
00476 args_db_read( &rest_line );
00477 }
00478
00479 } else if( type == DB_TYPE_MESSAGE ) {
00480
00481 assert( !merge_mode );
00482
00483 /* Parse rest of line for user-supplied message */
00484 if( (read_mode != READ_MODE_MERGE_NO_MERGE) && (read_mode != READ_MODE_MERGE_INST_MERGE) ) {
00485 message_db_read( &rest_line );
00486 }
00487
00488 } else if( type == DB_TYPE_MERGED_CDD ) {
00489
00490 assert( !merge_mode );
00491
00492 /* Parse rest of line for merged CDD information */
00493 merged_cdd_db_read( &rest_line );
00494
00495 } else if( type == DB_TYPE_SIGNAL ) {
00496
00497 assert( !merge_mode );
00498
00499 /* Parse rest of line for signal info */
00500 vsignal_db_read( &rest_line, curr_funit );
00501
00502 } else if( type == DB_TYPE_EXPRESSION ) {
00503
00504 assert( !merge_mode );
00505
00506 /* Parse rest of line for expression info */
00507 expression_db_read( &rest_line, curr_funit, (read_mode == READ_MODE_NO_MERGE) );
00508
00509 } else if( type == DB_TYPE_STATEMENT ) {
00510
00511 assert( !merge_mode );
00512
00513 /* Parse rest of line for statement info */
00514 statement_db_read( &rest_line, curr_funit, read_mode );
00515
00516 } else if( type == DB_TYPE_FSM ) {
00517
00518 assert( !merge_mode );
00519
00520 /* Parse rest of line for FSM info */
00521 fsm_db_read( &rest_line, curr_funit );
00522
00523 } else if( type == DB_TYPE_EXCLUDE ) {
00524
00525 /* Parse rest of line for exclude info */
00526 if( merge_mode ) {
00527 exclude_db_merge( curr_funit, &rest_line );
00528 } else {
00529 exclude_db_read( &rest_line, curr_funit );
00530 }
00531
00532 } else if( type == DB_TYPE_RACE ) {
00533
00534 assert( !merge_mode );
00535
00536 /* Parse rest of line for race condition block info */
00537 race_db_read( &rest_line, curr_funit );
00538
00539 } else if( type == DB_TYPE_FUNIT_VERSION ) {
00540
00541 assert( !merge_mode );
00542
00543 /* Parse rest of line for functional unit version information */
00544 funit_version_db_read( curr_funit, &rest_line );
00545
00546 } else if( (type == DB_TYPE_FUNIT ) || (type == DB_TYPE_INST_ONLY) ) {
00547
00548 /* Finish handling last functional unit read from CDD file */
00549 if( curr_funit != NULL ) {
00550
00551 if( (read_mode != READ_MODE_MERGE_INST_MERGE) || !merge_mode ) {
00552
00553 /* Get the scope of the parent module */
00554 scope_extract_back( funit_scope, back, parent_scope );
00555
00556 /* Attempt to add it to the last instance tree */
00557 if( (db_list[curr_db]->inst_tail == NULL) ||
00558 !instance_read_add( &(db_list[curr_db]->inst_tail->inst), parent_scope, curr_funit, back ) ) {
00559 (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) );
00560 }
00561
00562 }
00563
00564 /* If the current functional unit is a merged unit, don't add it to the funit list again */
00565 if( !merge_mode ) {
00566 funit_link_add( curr_funit, &(db_list[curr_db]->funit_head), &(db_list[curr_db]->funit_tail) );
00567 }
00568
00569 }
00570
00571 if( type == DB_TYPE_INST_ONLY ) {
00572
00573 /* Parse rest of the line for an instance-only structure */
00574 if( !merge_mode ) {
00575 instance_only_db_read( &rest_line );
00576 } else {
00577 instance_only_db_merge( &rest_line );
00578 }
00579
00580 /* Specify that the current functional unit does not exist */
00581 curr_funit = NULL;
00582
00583 } else {
00584
00585 /* Reset merge mode */
00586 merge_mode = FALSE;
00587
00588 /* Now finish reading functional unit line */
00589 funit_db_read( &tmpfunit, funit_scope, &inst_name_diff, &rest_line );
00590 if( (read_mode == READ_MODE_MERGE_INST_MERGE) &&
00591 ((foundinst = inst_link_find_by_scope( funit_scope, db_list[curr_db]->inst_head )) != NULL) ) {
00592 merge_mode = TRUE;
00593 curr_funit = foundinst->funit;
00594 funit_db_merge( foundinst->funit, db_handle, TRUE );
00595 } else if( (read_mode == READ_MODE_REPORT_MOD_MERGE) &&
00596 ((foundfunit = funit_link_find( tmpfunit.name, tmpfunit.type, db_list[curr_db]->funit_head )) != NULL) ) {
00597 merge_mode = TRUE;
00598 curr_funit = foundfunit->funit;
00599 funit_db_merge( foundfunit->funit, db_handle, FALSE );
00600 } else {
00601 curr_funit = funit_create();
00602 curr_funit->name = strdup_safe( funit_name );
00603 curr_funit->type = tmpfunit.type;
00604 curr_funit->filename = strdup_safe( funit_file );
00605 curr_funit->start_line = tmpfunit.start_line;
00606 curr_funit->end_line = tmpfunit.end_line;
00607 curr_funit->timescale = tmpfunit.timescale;
00608 if( tmpfunit.type != FUNIT_MODULE ) {
00609 curr_funit->parent = scope_get_parent_funit( db_list[curr_db]->inst_tail->inst, funit_scope );
00610 parent_mod = scope_get_parent_module( db_list[curr_db]->inst_tail->inst, funit_scope );
00611 funit_link_add( curr_funit, &(parent_mod->tf_head), &(parent_mod->tf_tail) );
00612 }
00613 }
00614
00615 /* Set global functional unit, if it has been found */
00616 if( (curr_funit != NULL) && (strncmp( curr_funit->name, "$root", 5 ) == 0) ) {
00617 global_funit = curr_funit;
00618 }
00619
00620 }
00621
00622 } else {
00623
00624 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unexpected type %d when parsing database file %s", type, obf_file( file ) );
00625 assert( rv < USER_MSG_LENGTH );
00626 print_output( user_msg, FATAL, __FILE__, __LINE__ );
00627 Throw 0;
00628
00629 }
00630
00631 } else {
00632
00633 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unexpected line in database file %s", obf_file( file ) );
00634 assert( rv < USER_MSG_LENGTH );
00635 print_output( user_msg, FATAL, __FILE__, __LINE__ );
00636 Throw 0;
00637
00638 }
00639
00640 } Catch_anonymous {
00641
00642 free_safe( curr_line, curr_line_size );
00643 if( (read_mode != READ_MODE_MERGE_INST_MERGE) && (read_mode != READ_MODE_REPORT_MOD_MERGE) ) {
00644 funit_dealloc( curr_funit );
00645 }
00646 Throw 0;
00647
00648 }
00649
00650 free_safe( curr_line, curr_line_size );
00651
00652 }
00653
00654 } Catch_anonymous {
00655
00656 unsigned int rv = fclose( db_handle );
00657 assert( rv == 0 );
00658 Throw 0;
00659
00660 }
00661
00662 rv = fclose( db_handle );
00663 assert( rv == 0 );
00664
00665 } else {
00666
00667 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Could not open %s for reading", obf_file( file ) );
00668 assert( rv < USER_MSG_LENGTH );
00669 print_output( user_msg, FATAL, __FILE__, __LINE__ );
00670 Throw 0;
00671
00672 }
00673
00674 /* If the last functional unit was being read, add it now */
00675 if( curr_funit != NULL ) {
00676
00677 if( (read_mode != READ_MODE_MERGE_INST_MERGE) || !merge_mode ) {
00678
00679 /* Get the scope of the parent module */
00680 scope_extract_back( funit_scope, back, parent_scope );
00681
00682 /* Attempt to add it to the last instance tree */
00683 if( (db_list[curr_db]->inst_tail == NULL) ||
00684 !instance_read_add( &(db_list[curr_db]->inst_tail->inst), parent_scope, curr_funit, back ) ) {
00685 (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) );
00686 }
00687
00688 }
00689
00690 /* If the current functional unit was being merged, don't add it to the functional unit list again */
00691 if( !merge_mode ) {
00692 funit_link_add( curr_funit, &(db_list[curr_db]->funit_head), &(db_list[curr_db]->funit_tail) );
00693 }
00694
00695 curr_funit = NULL;
00696
00697 }
00698
00699 #ifdef DEBUG_MODE
00700 /* Display the instance trees, if we are debugging */
00701 if( debug_mode && (db_list != NULL) ) {
00702 inst_link_display( db_list[curr_db]->inst_head );
00703 printf( "-----------------------------------\n" );
00704 }
00705 #endif
00706
00707 /* Check to make sure that the CDD file contained valid information */
00708 if( (db_size == 0) || (db_list[0]->inst_head == NULL) ) {
00709 print_output( "CDD file was found to be empty", FATAL, __FILE__, __LINE__ );
00710 Throw 0;
00711 }
00712
00713 PROFILE_END;
00714
00715 }
|
|
|
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.
02472 { PROFILE(DB_REMOVE_STATEMENT);
02473
02474 if( stmt != NULL ) {
02475
02476 #ifdef DEBUG_MODE
02477 if( debug_mode ) {
02478 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_remove_statement, stmt id: %d, line: %d",
02479 stmt->exp->id, stmt->exp->line );
02480 assert( rv < USER_MSG_LENGTH );
02481 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02482 }
02483 #endif
02484
02485 /* Call the recursive statement deallocation function */
02486 statement_dealloc_recursive( stmt, TRUE );
02487
02488 }
02489
02490 PROFILE_END;
02491
02492 }
|
|
|
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.
02427 { PROFILE(DB_REMOVE_STATEMENT_FROM_CURRENT_FUNIT);
02428
02429 inst_link* instl; /* Pointer to current functional unit instance */
02430
02431 if( (stmt != NULL) && (stmt->exp != NULL) ) {
02432
02433 #ifdef DEBUG_MODE
02434 if( debug_mode ) {
02435 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_remove_statement_from_current_funit %s, stmt id: %d, %s, line: %d",
02436 obf_funit( curr_funit->name ), stmt->exp->id, expression_string_op( stmt->exp->op ), stmt->exp->line );
02437 assert( rv < USER_MSG_LENGTH );
02438 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02439 }
02440 #endif
02441
02442 /*
02443 Get a list of all parameters within the given statement expression tree and remove them from
02444 an instance and module parameters.
02445 */
02446 instl = db_list[curr_db]->inst_head;
02447 while( instl != NULL ) {
02448 instance_remove_parms_with_expr( instl->inst, stmt );
02449 instl = instl->next;
02450 }
02451
02452 /* Remove expression from current module expression list and delete expressions */
02453 exp_link_remove( stmt->exp, &(curr_funit->exp_head), &(curr_funit->exp_tail), TRUE );
02454
02455 /* Remove this statement link from the current module's stmt_link list */
02456 stmt_link_unlink( stmt, &(curr_funit->stmt_head), &(curr_funit->stmt_tail) );
02457
02458 }
02459
02460 PROFILE_END;
02461
02462 }
|
|
|
Searches entire design for expressions that call the specified statement.
02784 { PROFILE(DB_REMOVE_STMT_BLKS_CALLING_STATEMENT);
02785
02786 inst_link* instl; /* Pointer to current instance */
02787
02788 assert( stmt != NULL );
02789
02790 instl = db_list[curr_db]->inst_head;
02791 while( instl != NULL ) {
02792 instance_remove_stmt_blks_calling_stmt( instl->inst, stmt );
02793 instl = instl->next;
02794 }
02795
02796 PROFILE_END;
02797
02798 }
|
|
||||||||||||
|
Returns a scaled version of the given value to the timescale for the given functional unit.
00774 { PROFILE(DB_SCALE_TO_PRECISION);
00775
00776 int units = funit->ts_unit;
00777
00778 assert( units >= global_timescale_precision );
00779
00780 while( units > global_timescale_precision ) {
00781 units--;
00782 value *= (uint64)10;
00783 }
00784
00785 PROFILE_END;
00786
00787 return( value );
00788
00789 }
|
|
||||||||||||
|
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.
02998 { PROFILE(DB_SET_SYMBOL_CHAR);
02999
03000 char val[2]; /* Value to store */
03001
03002 #ifdef DEBUG_MODE
03003 if( debug_mode ) {
03004 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_set_symbol_char, sym: %s, value: %c", sym, value );
03005 assert( rv < USER_MSG_LENGTH );
03006 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
03007 }
03008 #endif
03009
03010 /* Put together value string */
03011 val[0] = value;
03012 val[1] = '\0';
03013
03014 /* Set value of all matching occurrences in current timestep. */
03015 symtable_set_value( sym, val );
03016
03017 PROFILE_END;
03018
03019 }
|
|
||||||||||||
|
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.
03030 { PROFILE(DB_SET_SYMBOL_STRING);
03031
03032 #ifdef DEBUG_MODE
03033 if( debug_mode ) {
03034 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_set_symbol_string, sym: %s, value: %s", sym, value );
03035 assert( rv < USER_MSG_LENGTH );
03036 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
03037 }
03038 #endif
03039
03040 /* Set value of all matching occurrences in current timestep. */
03041 symtable_set_value( sym, value );
03042
03043 PROFILE_END;
03044
03045 }
|
|
||||||||||||
|
Sets the global timescale unit and precision variables. Sets the global timescale unit and precision variables.
00833 { PROFILE(DB_SET_TIMESCALE);
00834
00835 current_timescale_unit = unit;
00836
00837 /* Set the global precision value to the lowest precision value specified */
00838 if( precision < global_timescale_precision ) {
00839 global_timescale_precision = precision;
00840 }
00841
00842 PROFILE_END;
00843
00844 }
|
|
|
Sets current VCD scope to specified scope. Sets the curr_inst_scope global variable to the specified scope.
02874 { PROFILE(DB_SET_VCD_SCOPE);
02875
02876 #ifdef DEBUG_MODE
02877 if( debug_mode ) {
02878 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_set_vcd_scope, scope: %s", obf_inst( scope ) );
02879 assert( rv < USER_MSG_LENGTH );
02880 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02881 }
02882 #endif
02883
02884 assert( scope != NULL );
02885
02886 /* Create a new scope item */
02887 curr_inst_scope = (char**)realloc_safe( curr_inst_scope, (sizeof( char* ) * curr_inst_scope_size), (sizeof( char* ) * (curr_inst_scope_size + 1)) );
02888 curr_inst_scope[curr_inst_scope_size] = strdup_safe( scope );
02889 curr_inst_scope_size++;
02890
02891 /* Synchronize the current instance to the value of curr_inst_scope */
02892 db_sync_curr_instance();
02893
02894 PROFILE_END;
02895
02896 }
|
|
||||||||||||
|
Connects one statement block to another.
02656 { PROFILE(DB_STATEMENT_CONNECT);
02657
02658 bool retval; /* Return value for this function */
02659
02660 #ifdef DEBUG_MODE
02661 if( debug_mode ) {
02662 int curr_id; /* Current statement ID */
02663 int next_id; /* Next statement ID */
02664 unsigned int rv;
02665
02666 if( curr_stmt == NULL ) {
02667 curr_id = 0;
02668 } else {
02669 curr_id = curr_stmt->exp->id;
02670 }
02671
02672 if( next_stmt == NULL ) {
02673 next_id = 0;
02674 } else {
02675 next_id = next_stmt->exp->id;
02676 }
02677
02678 rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_statement_connect, curr_stmt: %d, next_stmt: %d", curr_id, next_id );
02679 assert( rv < USER_MSG_LENGTH );
02680 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02681 }
02682 #endif
02683
02684 /*
02685 Connect statement, if it was not successful, add it to the functional unit's statement list immediately
02686 as it will not be later on.
02687 */
02688 if( !(retval = statement_connect( curr_stmt, next_stmt, stmt_conn_id )) ) {
02689
02690 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unreachable statement found starting at line %d in file %s. Ignoring...",
02691 next_stmt->exp->line, obf_file( curr_funit->filename ) );
02692 assert( rv < USER_MSG_LENGTH );
02693 print_output( user_msg, WARNING, __FILE__, __LINE__ );
02694
02695 }
02696
02697 /* Increment stmt_conn_id for next statement connection */
02698 stmt_conn_id++;
02699
02700 PROFILE_END;
02701
02702 return( retval );
02703
02704 }
|
|
|
Synchronizes the curr_instance pointer to match the curr_inst_scope hierarchy. Synchronizes the curr_instance pointer to match the curr_inst_scope hierarchy.
02837 { PROFILE(DB_SYNC_CURR_INSTANCE);
02838
02839 char stripped_scope[4096]; /* Temporary string */
02840 char* scope; /* Current instance scope string */
02841
02842 assert( db_list[curr_db]->leading_hier_num > 0 );
02843
02844 if( (scope = db_gen_curr_inst_scope()) != NULL ) {
02845
02846 if( scope[0] != '\0' ) {
02847
02848 curr_instance = inst_link_find_by_scope( scope, db_list[curr_db]->inst_head );
02849
02850 /* If we have found at least one matching instance, set the one_instance_found flag */
02851 if( curr_instance != NULL ) {
02852 one_instance_found = TRUE;
02853 }
02854
02855 }
02856
02857 free_safe( scope, (strlen( scope ) + 1) );
02858
02859 } else {
02860
02861 curr_instance = NULL;
02862
02863 }
02864
02865 PROFILE_END;
02866
02867 }
|
|
|
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.
02902 { PROFILE(DB_VCD_UPSCOPE);
02903
02904 #ifdef DEBUG_MODE
02905 if( debug_mode ) {
02906 char* scope = db_gen_curr_inst_scope();
02907 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In db_vcd_upscope, curr_inst_scope: %s", obf_inst( scope ) );
02908 assert( rv < USER_MSG_LENGTH );
02909 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
02910 free_safe( scope, (strlen( scope ) + 1) );
02911 }
02912 #endif
02913
02914 /* Deallocate the last scope item */
02915 if( curr_inst_scope_size > 0 ) {
02916
02917 curr_inst_scope_size--;
02918 free_safe( curr_inst_scope[curr_inst_scope_size], (strlen( curr_inst_scope[curr_inst_scope_size] ) + 1) );
02919 curr_inst_scope = (char**)realloc_safe( curr_inst_scope, (sizeof( char* ) * (curr_inst_scope_size + 1)), (sizeof( char* ) * curr_inst_scope_size) );
02920
02921 db_sync_curr_instance();
02922
02923 }
02924
02925 PROFILE_END;
02926
02927 }
|
|
||||||||||||||||||||
|
Writes contents of expressions, functional units and vsignals to database file.
00341 { PROFILE(DB_WRITE);
00342
00343 FILE* db_handle; /* Pointer to database file being written */
00344 inst_link* instl; /* Pointer to current instance link */
00345
00346 if( (db_handle = fopen( file, "w" )) != NULL ) {
00347
00348 unsigned int rv;
00349
00350 Try {
00351
00352 /* Reset expression IDs */
00353 curr_expr_id = 1;
00354
00355 /* Iterate through instance tree */
00356 assert( db_list[curr_db]->inst_head != NULL );
00357 info_db_write( db_handle );
00358
00359 instl = db_list[curr_db]->inst_head;
00360 while( instl != NULL ) {
00361
00362 /* Only output the given instance tree if it is not ignored */
00363 if( !instl->ignore ) {
00364
00365 /* Now write the instance */
00366 instance_db_write( instl->inst, db_handle, instl->inst->name, parse_mode, issue_ids, report_save );
00367
00368 }
00369
00370 instl = instl->next;
00371
00372 }
00373
00374 } Catch_anonymous {
00375 rv = fclose( db_handle );
00376 assert( rv == 0 );
00377 Throw 0;
00378 }
00379
00380 rv = fclose( db_handle );
00381 assert( rv == 0 );
00382
00383 } else {
00384
00385 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Could not open %s for writing", obf_file( file ) );
00386 assert( rv < USER_MSG_LENGTH );
00387 print_output( user_msg, FATAL, __FILE__, __LINE__ );
00388 Throw 0;
00389
00390 }
00391
00392 PROFILE_END;
00393
00394 }
|
1.3.4