db.h File Reference

Contains functions for writing and reading contents of covered database file. More...

#include "defines.h"

Go to the source code of this file.

Functions

dbdb_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_unitdb_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_unitdb_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.
statementdb_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.
vsignaldb_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_itemdb_find_gen_item (gen_item *root, gen_item *gi)
 Find specified generate item in the current functional unit. Called by parser.
typedef_itemdb_find_typedef (const char *name)
 Finds specified typedef and returns TRUE if it is found.
gen_itemdb_get_curr_gen_block ()
 Returns a pointer to the current implicitly connected generate block. Called by parser.
expressiondb_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.
expressiondb_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.
expressiondb_create_sensitivity_list (statement *stmt)
 Creates an expression tree sensitivity list for the given statement block.
statementdb_parallelize_statement (statement *stmt)
 Checks specified statement for parallelization and if it must be, creates a parallel statement block.
statementdb_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_paramdb_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.

Detailed Description

Contains functions for writing and reading contents of covered database file.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
12/7/2001

Function Documentation

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.

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

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

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

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

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

statement* db_add_fork_join ( statement stmt  ) 

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.

Returns:
Returns TRUE if the new functional unit was added to the design; otherwise, returns FALSE to indicate that this block should be ignored.
Exceptions:
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.

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

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

Returns:
Returns a pointer to the created functional unit if the instance was added to the hierarchy; otherwise, returns NULL.
Exceptions:
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.

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

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

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

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

void db_add_statement ( statement stmt,
statement start 
)

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.

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

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

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

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

Returns:
Returns TRUE if the top module specified in the -t option is the top-level module of the simulation; otherwise, returns FALSE.

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 }

void db_connect_statement_false ( statement stmt,
statement next_false 
)

Connects false statement to specified statement.

Connects the specified statement's false statement.

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

void db_connect_statement_true ( statement stmt,
statement next_true 
)

Connects true statement to specified statement.

Connects the specified statement's true statement.

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

Returns:
Returns pointer to newly allocated and initialized database structure

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.

Returns:
Returns a pointer to the newly created attribute parameter.

Calls the attribute_create() function and returns the pointer returned by this function.

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

Returns:
Returns a pointer to an expression that represents the static expression specified
Exceptions:
anonymous db_create_expression Throw

Creates an expression structure from a static expression structure.

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

Returns:
Returns pointer to newly created expression.
Exceptions:
anonymous expression_create Throw

Creates a new expression with the specified parameter information and returns a pointer to the newly created expression.

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

Returns:
Returns expression tree to execute a sensitivity list for the given statement block.
Exceptions:
anonymous db_create_expression db_create_expression db_create_expression db_create_expression Throw
Parameters:
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.

Returns:
Returns pointer to created statement.
Exceptions:
anonymous db_parallelize_statement Throw

Creates an statement structure and adds created statement to current module's statement list.

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

Returns:
Returns a scope name for an unnamed scope. Only called for parsing purposes.

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 }

bool db_do_timestep ( uint64  time,
bool  final 
)

Performs a timestep for all signal changes during this timestep.

Returns:
Returns TRUE if simulation should continue to advance; otherwise, returns FALSE to indicate that simulation should stop immediately.
Exceptions:
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.

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

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

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

gen_item* db_find_gen_item ( gen_item root,
gen_item gi 
)

Find specified generate item in the current functional unit. Called by parser.

Returns:
Returns pointer to found matching generate item (NULL if not found)

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.

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

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.

Returns:
Returns pointer to the found signal.
Exceptions:
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.

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

Returns:
Returns pointer to found typedef item or NULL if none was found.

Searches for the given typedef name in the current module.

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

Returns:
Returns the generated exclusion ID given the parameters and the value of the report_exclusions global flag.

Generates the exclusion ID string and stores the result in the excl_id array.

Note:
This function should ONLY be called when the flag_output_exclusion_ids is set to TRUE.
Parameters:
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 }

void db_gen_item_connect ( gen_item gi1,
gen_item gi2 
)

Connects one generate item block to another.

Connects two generate items together.

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

void db_gen_item_connect_false ( gen_item gi1,
gen_item gi2 
)

Connects gi2 to the false path of gi1.

Connects gi2 to gi1's next_false pointer.

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

void db_gen_item_connect_true ( gen_item gi1,
gen_item gi2 
)

Connects gi2 to the true path of gi1.

Connects gi2 to gi1's next_true pointer.

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

Returns:
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.

Returns:
Returns a pointer to the last generate item added to the current functional unit.

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.

Returns:
Returns the size needed to allocate for an entire exclusion ID.

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.

Returns:
Returns TRUE if the given scope is an unnamed scope name; otherwise, returns FALSE.
Parameters:
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.

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

statement* db_parallelize_statement ( statement stmt  ) 

Checks specified statement for parallelization and if it must be, creates a parallel statement block.

Returns:
Returns pointer to parallelized statement block
Exceptions:
anonymous db_create_statement Throw db_create_expression
Parameters:
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.

Exceptions:
anonymous attribute_parse Throw

Calls the attribute_parse() function and deallocates this list.

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

Exceptions:
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
Returns:
Returns TRUE if the read in CDD created a database; otherwise, returns FALSE.

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.

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

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

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

Returns:
Returns a pointer to a list of all expressions found that call the specified statement. Returns NULL if no expressions were found in the design that match this 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.

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

Returns:
Returns scaled version of input value.

Takes in specified delay value and scales it to the correct timescale for the given module.

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

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

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

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

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

bool db_statement_connect ( statement curr_stmt,
statement next_stmt 
)

Connects one statement block to another.

Returns:
Returns TRUE if statement was properly connected to the given statement list; otherwise, returns FALSE.

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.

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

void db_write ( const char *  file,
bool  parse_mode,
bool  issue_ids 
)

Writes contents of expressions, functional units and vsignals to database file.

Exceptions:
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.

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

Generated on Sun Nov 21 00:55:37 2010 for Covered by  doxygen 1.6.3