func_unit.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "db.h"
#include "defines.h"
#include "enumerate.h"
#include "exclude.h"
#include "expr.h"
#include "fsm.h"
#include "func_unit.h"
#include "gen_item.h"
#include "instance.h"
#include "link.h"
#include "obfuscate.h"
#include "param.h"
#include "parser_misc.h"
#include "race.h"
#include "sim.h"
#include "stat.h"
#include "statement.h"
#include "stmt_blk.h"
#include "util.h"
#include "vsignal.h"

Functions

static void funit_init (func_unit *funit)
func_unitfunit_create ()
 Creates new functional unit from heap and initializes structure.
func_unitfunit_get_curr_module (func_unit *funit)
 Returns the parent module of the given functional unit.
const func_unitfunit_get_curr_module_safe (const func_unit *funit)
 Returns the parent module of the given functional unit (returning a const version).
func_unitfunit_get_curr_function (func_unit *funit)
 Returns the parent function of the given functional unit (if there is one).
func_unitfunit_get_curr_task (func_unit *funit)
 Returns the parent task of the given functional unit (if there is one).
int funit_get_port_count (func_unit *funit)
 Returns the number of input, output and inout ports in the specified functional unit.
mod_parmfunit_find_param (char *name, func_unit *funit)
 Finds specified module parameter given the current functional unit and its scope.
vsignalfunit_find_signal (char *name, func_unit *funit)
 Finds specified signal given in the current functional unit.
void funit_remove_stmt_blks_calling_stmt (func_unit *funit, statement *stmt)
 Finds all expressions that call the given statement.
char * funit_gen_task_function_namedblock_name (char *orig_name, func_unit *parent)
 Generates the internally used task/function/named-block name for the specified functional unit.
void funit_size_elements (func_unit *funit, funit_inst *inst, bool gen_all, bool alloc_exprs)
 Sizes all elements for the current functional unit from the given instance.
void funit_db_write (func_unit *funit, char *scope, bool name_diff, FILE *file, funit_inst *inst, bool ids_issued)
 Writes contents of provided functional unit to specified output.
void funit_db_read (func_unit *funit, char *scope, bool *name_diff, char **line)
 Read contents of current line from specified file, creates functional unit and adds to functional unit list.
void funit_version_db_read (func_unit *funit, char **line)
 Reads the functional unit version information from the functional unit line and adds it to the current functional unit.
void funit_db_inst_merge (func_unit *base, FILE *file, bool same)
 Performs an instance merge with the given base functional unit.
void funit_db_mod_merge (func_unit *base, FILE *file, bool same)
 Performs a module merge with the given base functional unit.
void funit_merge (func_unit *base, func_unit *other)
 Merges two functional units into the base functional unit.
char * funit_flatten_name (func_unit *funit)
 Flattens the functional unit name by removing all unnamed scope portions.
func_unitfunit_find_by_id (int id)
 Finds the functional unit that contains the given statement/expression ID.
bool funit_is_top_module (func_unit *funit)
 Returns TRUE if the given functional unit does not contain any input, output or inout ports.
bool funit_is_unnamed (func_unit *funit)
 Returns TRUE if the given functional unit is an unnamed scope.
bool funit_is_unnamed_child_of (func_unit *parent, func_unit *child)
 Returns TRUE if the specified "parent" functional unit is a parent of the "child" functional unit.
bool funit_is_child_of (func_unit *parent, func_unit *child)
 Returns TRUE if the specified "parent" functional unit is a parent of the "child" functional unit.
void funit_display_signals (func_unit *funit)
 Displays signals stored in this functional unit.
void funit_display_expressions (func_unit *funit)
 Displays expressions stored in this functional unit.
void funit_add_thread (func_unit *funit, thread *thr)
 Adds given thread to functional unit's thread pointer/thread pointer list.
void funit_push_threads (func_unit *funit, const statement *stmt, const sim_time *time)
 Pushes the threads associated with the given functional unit onto the active simulation queue.
void funit_delete_thread (func_unit *funit, thread *thr)
 Removes given thread from the given functional unit's thread pointer/thread pointer list.
void funit_output_dumpvars (FILE *vfile, func_unit *funit, const char *scope)
 Outputs dumpvars calls to the given file.
bool funit_is_one_signal_assigned (func_unit *funit)
 Returns TRUE if at least one signal was found that needs to be assigned by the dumpfile.
static void funit_clean (func_unit *funit)
void funit_dealloc (func_unit *funit)
 Deallocates functional unit element from heap.

Variables

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

Detailed Description

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

Function Documentation

void funit_add_thread ( func_unit funit,
thread thr 
)

Adds given thread to functional unit's thread pointer/thread pointer list.

Parameters:
funit Pointer to functional unit to add given thread pointer to
thr Pointer to thread associated with this statement

Adds the given thread to the given functional unit's thread/thread list element pointer, allocating memory as needed and adjusting values as needed.

References func_unit_s::elem, func_unit_s::elem_type, thr_list_s::head, malloc_safe, thr_list_s::next, thr_link_s::next, PROFILE, thr_list_s::tail, thr_link_s::thr, func_unit_s::thr, and func_unit_s::tlist.

Referenced by sim_create_thread().

01414   { PROFILE(STATEMENT_ADD_THREAD);
01415 
01416   assert( funit != NULL );
01417   assert( thr != NULL );
01418 
01419   /* Statement element should point to a thread */
01420   if( funit->elem_type == 0 ) {
01421 
01422     /* If the statement element currently points to nothing, simply point the statement element to the given thread */
01423     if( funit->elem.thr == NULL ) {
01424       funit->elem.thr = thr;
01425 
01426     /* Otherwise, change the type to a thread list, create a thread list, initialize it and continue */
01427     } else {
01428 
01429       thr_list* tlist;  /* Pointer to thread list */
01430 
01431       /* Allocate memory for the thread list */
01432       tlist = (thr_list*)malloc_safe( sizeof( thr_list ) );
01433 
01434       /* Create new thread link for existing thread */
01435       tlist->head      = (thr_link*)malloc_safe( sizeof( thr_link ) );
01436       tlist->head->thr = funit->elem.thr;
01437   
01438       /* Create new thread link for specified thread */
01439       tlist->tail       = (thr_link*)malloc_safe( sizeof( thr_link ) );
01440       tlist->tail->thr  = thr;
01441       tlist->tail->next = NULL;
01442       tlist->head->next = tlist->tail;
01443 
01444       /* Specify the next pointer to be NULL (to indicate that there aren't any available thread links to use) */
01445       tlist->next = NULL;
01446     
01447       /* Repopulate the functional unit */
01448       funit->elem.tlist = tlist;
01449       funit->elem_type  = 1;
01450   
01451     }
01452 
01453   /* Otherwise, the statement element is a pointer to a thread list already */
01454   } else {
01455 
01456     /* If there are no thread links already allocated and available, allocate a new thread link */
01457     if( funit->elem.tlist->next == NULL ) {
01458 
01459       thr_link* thrl;  /* Pointer to a thread link */
01460     
01461       /* Allocate and initialize thread link */
01462       thrl       = (thr_link*)malloc_safe( sizeof( thr_link ) );
01463       thrl->thr  = thr;
01464       thrl->next = NULL;
01465 
01466       /* Add the new thread link to the list */
01467       funit->elem.tlist->tail->next = thrl;
01468       funit->elem.tlist->tail       = thrl;
01469 
01470     /* Otherwise, use the link pointed at by next and adjust next */
01471     } else {
01472 
01473       funit->elem.tlist->next->thr = thr;
01474       funit->elem.tlist->next      = funit->elem.tlist->next->next;
01475 
01476     }
01477 
01478   }
01479 
01480 }

static void funit_clean ( func_unit funit  )  [static]

Deallocates functional unit contents: name and filename strings.

Parameters:
funit Pointer to functional unit element to clean

References func_unit_s::elem, func_unit_s::elem_type, enumerate_dealloc_list(), func_unit_s::er_head, func_unit_s::er_tail, func_unit_s::exp_head, exp_link_delete_list(), func_unit_s::exp_tail, FALSE, func_unit_s::filename, free_safe, func_unit_s::fsm_head, fsm_link_delete_list(), func_unit_s::fsm_tail, funit_link_delete_list(), func_unit_s::gitem_head, gitem_link_delete_list(), func_unit_s::gitem_tail, thr_list_s::head, mod_parm_dealloc(), func_unit_s::name, typedef_item_s::name, thr_link_s::next, exclude_reason_s::next, typedef_item_s::next, func_unit_s::param_head, func_unit_s::param_tail, parser_dealloc_sig_range(), typedef_item_s::prange, PROFILE, PROFILE_END, race_blk_delete_list(), func_unit_s::race_head, func_unit_s::race_tail, exclude_reason_s::reason, func_unit_s::sig_head, sig_link_delete_list(), func_unit_s::sig_tail, func_unit_s::stat, statistic_dealloc(), func_unit_s::stmt_head, stmt_link_delete_list(), func_unit_s::stmt_tail, func_unit_s::tdi_head, func_unit_s::tdi_tail, func_unit_s::tf_head, func_unit_s::tf_tail, func_unit_s::tlist, TRUE, typedef_item_s::urange, and func_unit_s::version.

Referenced by funit_dealloc().

01632   { PROFILE(FUNIT_CLEAN);
01633 
01634   func_unit*      old_funit = curr_funit;  /* Holds the original functional unit in curr_funit */
01635   typedef_item*   tdi;                     /* Pointer to current typedef item */
01636   typedef_item*   ttdi;                    /* Pointer to temporary typedef item */
01637   exclude_reason* er;                      /* Pointer to current exclude reason item */
01638   exclude_reason* ter;                     /* Pointer to temporary exclude reason item */
01639 
01640   if( funit != NULL ) {
01641 
01642     /* Set the global curr_funit to be the same as this funit */
01643     curr_funit = funit;
01644 
01645     /* Free signal list */
01646     sig_link_delete_list( funit->sig_head, TRUE );
01647     funit->sig_head = NULL;
01648     funit->sig_tail = NULL;
01649 
01650     /* Free FSM list */
01651     fsm_link_delete_list( funit->fsm_head );
01652     funit->fsm_head = NULL;
01653     funit->fsm_tail = NULL;
01654 
01655     /* Free expression list */
01656     exp_link_delete_list( funit->exp_head, TRUE );
01657     funit->exp_head = NULL;
01658     funit->exp_tail = NULL;
01659 
01660     /* Free statement list */
01661     stmt_link_delete_list( funit->stmt_head );
01662     funit->stmt_head = NULL;
01663     funit->stmt_tail = NULL;
01664 
01665     /* Free parameter list */
01666     mod_parm_dealloc( funit->param_head, TRUE );
01667     funit->param_head = NULL;
01668     funit->param_tail = NULL;
01669 
01670     /* Free race condition block list */
01671     race_blk_delete_list( funit->race_head );
01672     funit->race_head = NULL;
01673     funit->race_tail = NULL;
01674 
01675 #ifndef VPI_ONLY
01676     /* Free generate item list */
01677     gitem_link_delete_list( funit->gitem_head, TRUE );
01678     funit->gitem_head = NULL;
01679     funit->gitem_tail = NULL;
01680 #endif
01681 
01682     /* Free statistic structure */
01683     statistic_dealloc( funit->stat );
01684 
01685     /* Free tf elements */
01686     funit_link_delete_list( &(funit->tf_head), &(funit->tf_tail), FALSE );
01687 
01688     /* Free typedef items */
01689     tdi = funit->tdi_head;
01690     while( tdi != NULL ) {
01691       ttdi = tdi;
01692       tdi  = tdi->next;
01693       free_safe( ttdi->name, (strlen( ttdi->name ) + 1) );
01694       parser_dealloc_sig_range( ttdi->prange, TRUE );
01695       parser_dealloc_sig_range( ttdi->urange, TRUE );
01696       free_safe( ttdi, sizeof( typedef_item ) );
01697     }
01698     funit->tdi_head = NULL;
01699     funit->tdi_tail = NULL;
01700 
01701     /* Free exclusion reason items */
01702     er = funit->er_head;
01703     while( er != NULL ) {
01704       ter = er;
01705       er  = er->next;
01706       free_safe( ter->reason, (strlen( ter->reason ) + 1) );
01707       free_safe( ter, sizeof( exclude_reason ) );
01708     }
01709     funit->er_head = NULL;
01710     funit->er_tail = NULL;
01711 
01712     /* Free enumerated elements */
01713     enumerate_dealloc_list( funit );
01714 
01715     /* Free functional unit name */
01716     if( funit->name != NULL ) {
01717       free_safe( funit->name, (strlen( funit->name ) + 1) );
01718       funit->name = NULL;
01719     }
01720 
01721     /* Free functional unit filename */
01722     if( funit->filename != NULL ) {
01723       free_safe( funit->filename, (strlen( funit->filename ) + 1) );
01724       funit->filename = NULL;
01725     }
01726 
01727     /* Free functional unit version */
01728     if( funit->version != NULL ) {
01729       free_safe( funit->version, (strlen( funit->version ) + 1) );
01730       funit->version = NULL;
01731     }
01732 
01733     /* Free thread list, if available */
01734     if( funit->elem_type == 1 ) {
01735       thr_link* thrl = funit->elem.tlist->head;
01736       thr_link* tmpl;
01737       while( thrl != NULL ) {
01738         tmpl = thrl;
01739         thrl = thrl->next;
01740         free_safe( tmpl, sizeof( thr_link ) );
01741       }
01742       free_safe( funit->elem.tlist, sizeof( thr_list ) );
01743     }
01744 
01745     /* Reset curr_funit */
01746     curr_funit = old_funit;
01747 
01748   }
01749 
01750   PROFILE_END;
01751 
01752 }

func_unit* funit_create (  ) 

Creates new functional unit from heap and initializes structure.

Returns:
Returns pointer to newly created functional unit element that has been properly initialized.

Allocates memory from the heap for a functional unit element and initializes all contents to NULL. Returns a pointer to the newly created functional unit.

References funit_init(), malloc_safe, PROFILE, and PROFILE_END.

Referenced by db_add_instance(), db_read(), and search_init().

00113                           { PROFILE(FUNIT_CREATE);
00114 
00115   func_unit* funit;   /* Pointer to newly created functional unit element */
00116 
00117   /* Create and initialize functional unit */
00118   funit = (func_unit*)malloc_safe( sizeof( func_unit ) );
00119 
00120   funit_init( funit );
00121 
00122   PROFILE_END;
00123 
00124   return( funit );
00125 
00126 }

void funit_db_inst_merge ( func_unit base,
FILE *  file,
bool  same 
)

Performs an instance merge with the given base functional unit.

Exceptions:
anonymous fsm_db_merge Throw Throw expression_db_merge vsignal_db_merge

Parses specified line for functional unit information and performs a merge of the two specified functional units, placing the resulting merge functional unit into the functional unit named base. If there are any differences between the two functional units, a warning or error will be displayed to the user.

Parameters:
base Module that will merge in that data from the in functional unit
file Pointer to CDD file handle to read
same Specifies if functional unit to be merged should match existing functional unit exactly or not

References Catch_anonymous, DB_TYPE_EXPRESSION, DB_TYPE_FSM, DB_TYPE_FUNIT_VERSION, DB_TYPE_RACE, DB_TYPE_SIGNAL, DB_TYPE_STATEMENT, exp_link_s::exp, func_unit_s::exp_head, expression_db_merge(), FATAL, free_safe, fsm_db_merge(), func_unit_s::fsm_head, FUNIT_MODULE, func_unit_s::name, race_blk_s::next, fsm_link_s::next, stmt_link_s::next, sig_link_s::next, exp_link_s::next, print_output(), PROFILE, PROFILE_END, func_unit_s::race_head, sig_link_s::sig, func_unit_s::sig_head, func_unit_s::stmt_head, fsm_link_s::table, Throw, Try, func_unit_s::type, util_readline(), func_unit_s::version, and vsignal_db_merge().

Referenced by db_read().

00776   { PROFILE(FUNIT_DB_INST_MERGE);
00777 
00778   exp_link*    curr_base_exp;   /* Pointer to current expression in base functional unit expression list */
00779   sig_link*    curr_base_sig;   /* Pointer to current signal in base functional unit signal list */
00780   stmt_link*   curr_base_stmt;  /* Statement list iterator */
00781   fsm_link*    curr_base_fsm;   /* Pointer to current FSM in base functional unit FSM list */
00782   race_blk*    curr_base_race;  /* Pointer to current race condition block in base module list  */
00783   char*        curr_line;       /* Pointer to current line being read from CDD */
00784   unsigned int curr_line_size;  /* Number of bytes allocated for curr_line */
00785   char*        rest_line;       /* Pointer to rest of read line */
00786   int          type;            /* Specifies currently read CDD type */
00787   int          chars_read;      /* Number of characters read from current CDD line */
00788 
00789   assert( base != NULL );
00790   assert( base->name != NULL );
00791 
00792   /* Handle the functional unit version, if specified */
00793   if( base->version != NULL ) {
00794     if( util_readline( file, &curr_line, &curr_line_size ) ) {
00795       Try {
00796         if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) {
00797           rest_line = curr_line + chars_read;
00798           if( type == DB_TYPE_FUNIT_VERSION ) {
00799             while( *rest_line == ' ' ) rest_line++;
00800             if( strcmp( base->version, rest_line ) != 0 ) {
00801               print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00802               Throw 0;
00803             }
00804           } else {
00805             print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00806             Throw 0;
00807           }
00808         } else {
00809           print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00810           Throw 0;
00811         }
00812       } Catch_anonymous {
00813         free_safe( curr_line, curr_line_size );
00814         Throw 0;
00815       }
00816     } else {
00817       print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00818       Throw 0;
00819     }
00820   }
00821 
00822   /* Handle all functional unit expressions */
00823   curr_base_exp = base->exp_head;
00824   while( curr_base_exp != NULL ) {
00825     if( util_readline( file, &curr_line, &curr_line_size ) ) {
00826       Try {
00827         if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) {
00828           rest_line = curr_line + chars_read;
00829           if( type == DB_TYPE_EXPRESSION ) {
00830             expression_db_merge( curr_base_exp->exp, &rest_line, same );
00831           } else {
00832             print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00833             Throw 0;
00834           }
00835         } else {
00836           print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00837           Throw 0;
00838         }
00839       } Catch_anonymous {
00840         free_safe( curr_line, curr_line_size );
00841         Throw 0;
00842       }
00843       free_safe( curr_line, curr_line_size );
00844     } else {
00845       print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00846       Throw 0;
00847     }
00848     curr_base_exp = curr_base_exp->next;
00849   }
00850 
00851   /* Handle all functional unit signals */
00852   curr_base_sig = base->sig_head;
00853   while( curr_base_sig != NULL ) {
00854     if( util_readline( file, &curr_line, &curr_line_size ) ) {
00855       Try {
00856         if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) {
00857           rest_line = curr_line + chars_read;
00858           if( type == DB_TYPE_SIGNAL ) {
00859             vsignal_db_merge( curr_base_sig->sig, &rest_line, same );
00860           } else {
00861             print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00862             Throw 0;
00863           }
00864         } else {
00865           print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00866           Throw 0;
00867         }
00868       } Catch_anonymous {
00869         free_safe( curr_line, curr_line_size );
00870         Throw 0;
00871       }
00872       free_safe( curr_line, curr_line_size );
00873     } else {
00874       print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00875       Throw 0;
00876     }
00877     curr_base_sig = curr_base_sig->next;
00878   }
00879 
00880   /* Since statements don't get merged, we will just read these lines in */
00881   curr_base_stmt = base->stmt_head;
00882   while( curr_base_stmt != NULL ) {
00883     if( util_readline( file, &curr_line, &curr_line_size ) ) {
00884       Try {
00885         if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) {
00886           rest_line = curr_line + chars_read;
00887           if( type != DB_TYPE_STATEMENT ) {
00888             print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00889             Throw 0;
00890           }
00891         } else {
00892           print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00893           Throw 0;
00894         }
00895       } Catch_anonymous {
00896         free_safe( curr_line, curr_line_size );
00897         Throw 0;
00898       }
00899       free_safe( curr_line, curr_line_size );
00900     } else {
00901       print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00902       Throw 0;
00903     }
00904     curr_base_stmt = curr_base_stmt->next;
00905   }
00906 
00907   /* Handle all functional unit FSMs */
00908   curr_base_fsm = base->fsm_head;
00909   while( curr_base_fsm != NULL ) {
00910     if( util_readline( file, &curr_line, &curr_line_size ) ) {
00911       Try {
00912         if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) {
00913           rest_line = curr_line + chars_read;
00914           if( type == DB_TYPE_FSM ) {
00915             fsm_db_merge( curr_base_fsm->table, &rest_line );
00916           } else {
00917             print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00918             Throw 0;
00919           }
00920         } else {
00921           print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00922           Throw 0;
00923         }
00924       } Catch_anonymous {
00925         free_safe( curr_line, curr_line_size );
00926         Throw 0;
00927       }
00928       free_safe( curr_line, curr_line_size );
00929     } else {
00930       print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00931       Throw 0;
00932     }
00933     curr_base_fsm = curr_base_fsm->next;
00934   }
00935 
00936   /* Since race condition blocks don't get merged, we will just read these lines in */
00937   if( base->type == FUNIT_MODULE ) {
00938     curr_base_race = base->race_head;
00939     while( curr_base_race != NULL ) {
00940       if( util_readline( file, &curr_line, &curr_line_size ) ) {
00941         Try {
00942           if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) {
00943             rest_line = curr_line + chars_read;
00944             if( type != DB_TYPE_RACE ) {
00945               print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00946               Throw 0;
00947             }
00948           } else {
00949             print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00950             Throw 0;
00951           }
00952         } Catch_anonymous {
00953           free_safe( curr_line, curr_line_size );
00954           Throw 0;
00955         }
00956         free_safe( curr_line, curr_line_size );
00957       } else {
00958         print_output( "Databases being merged are incompatible.", FATAL, __FILE__, __LINE__ );
00959         Throw 0;
00960       }
00961       curr_base_race = curr_base_race->next;
00962     }
00963   }
00964 
00965   PROFILE_END;
00966 
00967 }

void funit_db_mod_merge ( func_unit base,
FILE *  file,
bool  same 
)

Performs a module merge with the given base functional unit.

Exceptions:
anonymous fsm_db_merge Throw Throw expression_db_merge vsignal_db_merge

Parses specified line for functional unit information and performs a merge of the two specified functional units, placing the resulting merge functional unit into the functional unit named base. If there are any differences between the two functional units, a warning or error will be displayed to the user.

Parameters:
base Module that will merge in that data from the in functional unit
file Pointer to CDD file handle to read
same Specifies if functional unit to be merged should match existing functional unit exactly or not

References Catch_anonymous, DB_TYPE_EXPRESSION, DB_TYPE_FSM, DB_TYPE_FUNIT, DB_TYPE_FUNIT_VERSION, DB_TYPE_RACE, DB_TYPE_SIGNAL, DB_TYPE_STATEMENT, race_blk_s::end_line, exp_link_s::exp, func_unit_s::exp_head, exp_link_find_by_pos(), expression_db_merge(), expression_db_read(), FALSE, FATAL, free_safe, fsm_db_merge(), fsm_db_read(), func_unit_s::fsm_head, fsm_link_find_by_pos(), func_unit_s::name, race_blk_s::next, print_output(), PROFILE, PROFILE_END, race_db_read(), func_unit_s::race_head, READ_MODE_REPORT_MOD_MERGE, race_blk_s::reason, sig_link_s::sig, func_unit_s::sig_head, sig_link_find(), race_blk_s::start_line, statement_db_read(), func_unit_s::stmt_head, stmt_link_find_by_pos(), fsm_link_s::table, Throw, TRUE, Try, util_readline(), vsignal_db_merge(), and vsignal_db_read().

Referenced by db_read().

00981   { PROFILE(FUNIT_DB_MOD_MERGE);
00982 
00983   fsm_link*    curr_base_fsm;   /* Pointer to current FSM in base functional unit FSM list */
00984   char*        curr_line;       /* Pointer to current line being read from CDD */
00985   unsigned int curr_line_size;  /* Number of bytes allocated for curr_line */
00986   char*        rest_line;       /* Pointer to rest of read line */
00987   int          type;            /* Specifies currently read CDD type */
00988   int          chars_read;      /* Number of characters read from current CDD line */
00989   bool         new_funit_found = FALSE;
00990 
00991   assert( base != NULL );
00992   assert( base->name != NULL );
00993 
00994   /* Initialize pointers */
00995   curr_base_fsm  = base->fsm_head;
00996 
00997   /* Parse the current functional unit in the CDD file */
00998   while( !new_funit_found && util_readline( file, &curr_line, &curr_line_size ) ) {
00999 
01000     if( sscanf( curr_line, "%d%n", &type, &chars_read ) == 1 ) {
01001 
01002       rest_line = curr_line + chars_read;
01003    
01004       Try {
01005 
01006         switch( type ) {
01007 
01008           case DB_TYPE_FUNIT_VERSION :
01009             /* Do nothing */
01010             break;
01011 
01012           case DB_TYPE_EXPRESSION :
01013             {
01014               int         id;
01015               exp_op_type op;
01016               int         line;
01017               uint32      col;
01018               if( sscanf( rest_line, "%d %x %d %x", &id, &op, &line, &col ) == 4 ) {
01019                 exp_link* expl = exp_link_find_by_pos( op, line, col, base->exp_head );
01020                 if( expl != NULL ) {
01021                   expression_db_merge( expl->exp, &rest_line, FALSE );
01022                 } else {
01023                   expression_db_read( &rest_line, base, FALSE );
01024                 }
01025               } else {
01026                 print_output( "Illegal CDD file format", FATAL, __FILE__, __LINE__ );
01027                 Throw 0;
01028               }
01029               break;
01030             }
01031 
01032           case DB_TYPE_SIGNAL :
01033             {
01034               char name[256];
01035               if( sscanf( rest_line, "%s", name ) == 1 ) {
01036                 sig_link* sigl = sig_link_find( name, base->sig_head );
01037                 if( sigl != NULL ) {
01038                   vsignal_db_merge( sigl->sig, &rest_line, FALSE );
01039                 } else {
01040                   vsignal_db_read( &rest_line, base );
01041                 }
01042               } else {
01043                 print_output( "Illegal CDD file format", FATAL, __FILE__, __LINE__ );
01044                 Throw 0;
01045               }
01046               break;
01047             }
01048 
01049           case DB_TYPE_STATEMENT :
01050             {
01051               int          id;
01052               unsigned int ppline;
01053               uint32       first_col;
01054               if( sscanf( rest_line, "%d %u %u", &id, &ppline, &first_col ) == 3 ) {
01055                 stmt_link* stmtl = stmt_link_find_by_pos( ppline, first_col, base->stmt_head );
01056                 if( stmtl == NULL ) {
01057                   statement_db_read( &rest_line, base, READ_MODE_REPORT_MOD_MERGE );
01058                 }
01059               } else {
01060                 print_output( "Illegal CDD file format", FATAL, __FILE__, __LINE__ );
01061                 Throw 0;
01062               }
01063               break;
01064             }
01065 
01066           case DB_TYPE_FSM :
01067             {
01068               int line;
01069               if( sscanf( rest_line, "%d", &line ) == 1 ) {
01070                 fsm_link* fsml = fsm_link_find_by_pos( line, base->fsm_head );
01071                 if( fsml == NULL ) {
01072                   fsm_db_read( &rest_line, base );
01073                 } else {
01074                   fsm_db_merge( curr_base_fsm->table, &rest_line );
01075                 }
01076               } else {
01077                 print_output( "Illegal CDD file format", FATAL, __FILE__, __LINE__ );
01078                 Throw 0;
01079               }
01080               break;
01081             }
01082 
01083           case DB_TYPE_RACE :
01084             {
01085               int reason;
01086               int start_line;
01087               int end_line;
01088               if( sscanf( rest_line, "%d %d %d", &reason, &start_line, &end_line ) == 3 ) {
01089                 race_blk* rb = base->race_head;
01090                 while( (rb != NULL) && ((rb->reason != reason) || (rb->start_line != start_line) || (rb->end_line != end_line)) ) {
01091                   rb = rb->next;
01092                 }
01093                 if( rb == NULL ) {
01094                   race_db_read( &rest_line, base );
01095                 }
01096               } else {
01097                 print_output( "Illegal CDD file format", FATAL, __FILE__, __LINE__ );
01098                 Throw 0;
01099               }
01100               break;
01101             }
01102 
01103           /* If the type is a new functional unit, move the current file pointer back to the beginning of the line */
01104           case DB_TYPE_FUNIT :
01105             {
01106               int rv = fseek( file, (0 - (strlen( curr_line ) + 1)), SEEK_CUR );
01107               assert( rv == 0 );
01108               new_funit_found = TRUE;
01109               break;
01110             }
01111 
01112           default :
01113             print_output( "Illegal CDD file format", FATAL, __FILE__, __LINE__ );
01114             Throw 0;
01115             /*@-unreachable@*/
01116             break;
01117             /*@=unreachable@*/
01118 
01119         }
01120 
01121       } Catch_anonymous {
01122         free_safe( curr_line, curr_line_size );
01123         Throw 0;
01124       }
01125 
01126     }
01127 
01128     /* Deallocate the current line string */
01129     free_safe( curr_line, curr_line_size );
01130 
01131   }
01132 
01133   PROFILE_END;
01134 
01135 }

void funit_db_read ( func_unit funit,
char *  scope,
bool name_diff,
char **  line 
)

Read contents of current line from specified file, creates functional unit and adds to functional unit list.

Exceptions:
anonymous Throw

Reads the current line of the specified file and parses it for a functional unit. If all is successful, returns TRUE; otherwise, returns FALSE.

Parameters:
funit Pointer to functional unit to read contents into
scope Pointer to name of read functional unit scope
name_diff Will cause the name_diff value of the instance to get set to the same value
line Pointer to current line to parse

References func_unit_s::end_line, FATAL, func_unit_s::filename, func_unit_s::name, print_output(), PROFILE, PROFILE_END, func_unit_s::start_line, Throw, func_unit_s::timescale, func_unit_s::type, user_msg, and USER_MSG_LENGTH.

Referenced by db_read().

00716   { PROFILE(FUNIT_DB_READ);
00717 
00718   int  chars_read;   /* Number of characters currently read */
00719   int  params;       /* Number of parameters in string that were parsed */
00720 
00721   /*@-duplicatequals -formatcode -formattype@*/
00722   if( (params = sscanf( *line, "%d %s \"%[^\"]\" %d %s %d %d %" FMT64 "u%n", 
00723                         &(funit->type), funit->name, scope, (int*)name_diff, funit->filename,
00724                         &(funit->start_line), &(funit->end_line), &(funit->timescale), &chars_read )) == 8 ) {
00725   /*@=duplicatequals =formatcode =formattype@*/
00726 
00727     *line = *line + chars_read;
00728 
00729   } else {
00730 
00731     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Internal Error:  Incorrect number of parameters for func_unit, should be 7 but is %d\n",
00732                                 params );
00733     assert( rv < USER_MSG_LENGTH );
00734     print_output( user_msg, FATAL, __FILE__, __LINE__ );
00735     Throw 0;
00736 
00737   }
00738 
00739   PROFILE_END;
00740 
00741 }

void funit_db_write ( func_unit funit,
char *  scope,
bool  name_diff,
FILE *  file,
funit_inst inst,
bool  ids_issued 
)

Writes contents of provided functional unit to specified output.

Exceptions:
anonymous funit_size_elements

Prints the database line for the specified functional unit to the specified database file. If there are any problems with the write, returns FALSE; otherwise, returns TRUE.

Parameters:
funit Pointer to functional unit to write to output
scope String version of functional unit scope in hierarchy
name_diff Specifies that this instance has an inaccurate way
file Pointer to specified output file to write contents
inst Pointer to the current functional unit instance
ids_issued Specifies if IDs have been issued prior to calling this function

References curr_db, db_scale_to_precision(), DB_TYPE_FUNIT, DB_TYPE_FUNIT_VERSION, DEBUG, func_unit_s::end_line, func_unit_s::er_head, exclude_db_write(), exp_link_s::exp, func_unit_s::exp_head, expression_db_write(), FALSE, func_unit_s::filename, fsm_db_write(), func_unit_s::fsm_head, funit_inst_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, FUNIT_FUNCTION, FUNIT_MODULE, FUNIT_NAMED_BLOCK, FUNIT_NO_SCORE, funit_size_elements(), FUNIT_TASK, db_s::fver_head, gen_item_db_write(), gen_item_db_write_expr_tree(), get_funit_type(), gitem_link_s::gi, GI_TYPE_SIG, GI_TYPE_STMT, funit_inst_s::gitem_head, funit_inst_s::name, func_unit_s::name, exclude_reason_s::next, race_blk_s::next, fsm_link_s::next, stmt_link_s::next, inst_parm_s::next, sig_link_s::next, gitem_link_s::next, exp_link_s::next, obf_funit, param_db_write(), funit_inst_s::param_head, funit_inst_s::parent, print_output(), PROFILE, PROFILE_END, race_db_write(), func_unit_s::race_head, stmt_link_s::rm_stmt, scope_local(), sig_link_s::sig, func_unit_s::sig_head, func_unit_s::start_line, statement_db_write(), stmt_link_s::stmt, func_unit_s::stmt_head, str_link_s::str2, str_link_find(), strdup_safe, fsm_link_s::table, func_unit_s::timescale, TRUE, func_unit_s::type, user_msg, USER_MSG_LENGTH, func_unit_s::version, and vsignal_db_write().

Referenced by instance_db_write().

00532   { PROFILE(FUNIT_DB_WRITE);
00533 
00534   sig_link*       curr_sig;       /* Pointer to current functional unit sig_link element */
00535   exp_link*       curr_exp;       /* Pointer to current functional unit exp_link element */
00536   stmt_link*      curr_stmt;      /* Statement list iterator */
00537   inst_parm*      curr_parm;      /* Pointer to current instance parameter */
00538   fsm_link*       curr_fsm;       /* Pointer to current functional unit fsm_link element */
00539   race_blk*       curr_race;      /* Pointer to current race condition block */
00540 #ifndef VPI_ONLY
00541   gitem_link*     curr_gi;        /* Pointer to current gitem_link element */
00542 #endif
00543   exclude_reason* curr_er;        /* Pointer to current exclude reason element */
00544   char            modname[4096];  /* Name of module */
00545   char            tmp[4096];      /* Temporary string holder */
00546   str_link*       strl;           /* Pointer to string link */
00547 
00548   if( funit->type != FUNIT_NO_SCORE ) {
00549 
00550 #ifdef DEBUG_MODE
00551     assert( (funit->type == FUNIT_MODULE)    || (funit->type == FUNIT_NAMED_BLOCK) ||
00552             (funit->type == FUNIT_FUNCTION)  || (funit->type == FUNIT_TASK)        ||
00553             (funit->type == FUNIT_AFUNCTION) || (funit->type == FUNIT_ATASK)       ||
00554             (funit->type == FUNIT_ANAMED_BLOCK) );
00555     {
00556       unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Writing %s %s", get_funit_type( funit->type ), obf_funit( funit->name ) );
00557       assert( rv < USER_MSG_LENGTH );
00558       print_output( user_msg, DEBUG, __FILE__, __LINE__ );
00559     }
00560 #endif
00561 
00562     /* Calculate module name to display */
00563     if( scope_local( funit->name ) || (inst == NULL) ) {
00564       strcpy( modname, funit->name );
00565     } else {
00566       funit_inst*  parent_inst = inst->parent;
00567       unsigned int rv;
00568       strcpy( modname, inst->name );
00569       assert( parent_inst != NULL );
00570       while( parent_inst->funit->type != FUNIT_MODULE ) {
00571         unsigned int rv = snprintf( tmp, 4096, "%s.%s", parent_inst->name, modname );
00572         assert( rv < 4096 );
00573         strcpy( modname, tmp );
00574         parent_inst = parent_inst->parent;
00575       }
00576       rv = snprintf( tmp, 4096, "%s.%s", parent_inst->funit->name, modname );
00577       assert( rv < 4096 );
00578       strcpy( modname, tmp );
00579     }
00580 
00581     /* Size all elements in this functional unit and calculate timescale if we are in parse mode */
00582     if( inst != NULL ) {
00583       funit_size_elements( funit, inst, TRUE, FALSE );
00584       funit->timescale = db_scale_to_precision( (uint64)1, funit );
00585     }
00586   
00587     /*@-duplicatequals -formatcode -formattype@*/
00588     fprintf( file, "%d %d %s \"%s\" %d %s %d %d %" FMT64 "u\n",
00589       DB_TYPE_FUNIT,
00590       funit->type,
00591       modname,
00592       scope,
00593       name_diff,
00594       funit->filename,
00595       funit->start_line,
00596       funit->end_line,
00597       funit->timescale
00598     );
00599     /*@=duplicatequals =formatcode =formattype@*/
00600 
00601     /* Figure out if a file version exists for this functional unit */
00602     if( (funit->version == NULL) && ((strl = str_link_find( funit->filename, db_list[curr_db]->fver_head )) != NULL) ) {
00603       funit->version = strdup_safe( strl->str2 );
00604     }
00605 
00606     /* If a version was specified for this functional unit, write it now */
00607     if( funit->version != NULL ) {
00608       fprintf( file, "%d %s\n", DB_TYPE_FUNIT_VERSION, funit->version );
00609     }
00610 
00611     /* Now print all expressions in functional unit */
00612     curr_exp = funit->exp_head;
00613     while( curr_exp != NULL ) {
00614       expression_db_write( curr_exp->exp, file, (inst != NULL), ids_issued );
00615       curr_exp = curr_exp->next;
00616     }
00617 
00618 #ifndef VPI_ONLY
00619     /* Now print all expressions within generated statements in functional unit */
00620     if( inst != NULL ) {
00621       curr_gi = inst->gitem_head;
00622       while( curr_gi != NULL ) {
00623         gen_item_db_write_expr_tree( curr_gi->gi, file );
00624         curr_gi = curr_gi->next;
00625       }
00626     }
00627 #endif
00628 
00629     /* Now print all signals in functional unit */
00630     curr_sig = funit->sig_head;
00631     while( curr_sig != NULL ) {
00632       vsignal_db_write( curr_sig->sig, file );
00633       curr_sig = curr_sig->next; 
00634     }
00635 
00636     /* Now print all parameters in functional unit */
00637     if( inst != NULL ) {
00638       curr_parm = inst->param_head;
00639       while( curr_parm != NULL ) {
00640         param_db_write( curr_parm, file );
00641         curr_parm = curr_parm->next;
00642       }
00643     }
00644 
00645 #ifndef VPI_ONLY
00646     /* Now print any generated signals in the current instance */
00647     if( inst != NULL ) {
00648       curr_gi = inst->gitem_head;
00649       while( curr_gi != NULL ) {
00650         gen_item_db_write( curr_gi->gi, GI_TYPE_SIG, file );
00651         curr_gi = curr_gi->next;
00652       }
00653     }
00654 #endif
00655 
00656     /* Now print all statements in functional unit */
00657     curr_stmt = funit->stmt_head;
00658     while( curr_stmt != NULL ) {
00659       if( curr_stmt->rm_stmt ) {
00660         statement_db_write( curr_stmt->stmt, file, ids_issued );
00661       }
00662       curr_stmt = curr_stmt->next;
00663     }
00664 
00665 #ifndef VPI_ONLY
00666     /* Now print any generated statements in the current instance */
00667     if( inst != NULL ) {
00668       curr_gi = inst->gitem_head;
00669       while( curr_gi != NULL ) {
00670         gen_item_db_write( curr_gi->gi, GI_TYPE_STMT, file );
00671         curr_gi = curr_gi->next;
00672       }
00673     }
00674 #endif
00675 
00676     /* Now print all FSM structures in functional unit */
00677     curr_fsm = funit->fsm_head;
00678     while( curr_fsm != NULL ) {
00679       fsm_db_write( curr_fsm->table, file, ids_issued );
00680       curr_fsm = curr_fsm->next;
00681     }
00682 
00683     /* Now print all race condition block structures in functional unit (if we are a module) */
00684     if( funit->type == FUNIT_MODULE ) {
00685       curr_race = funit->race_head;
00686       while( curr_race != NULL ) {
00687         race_db_write( curr_race, file );
00688         curr_race = curr_race->next;
00689       }
00690     }
00691 
00692     /* Now print all of the exclusion reasons in the functional unit */
00693     curr_er = funit->er_head;
00694     while( curr_er != NULL ) {
00695       exclude_db_write( curr_er, file );
00696       curr_er = curr_er->next;
00697     }
00698 
00699   }
00700 
00701   PROFILE_END;
00702 
00703 }

void funit_dealloc ( func_unit funit  ) 

Deallocates functional unit element from heap.

Deallocates functional unit; name and filename strings; and finally the structure itself from the heap.

Parameters:
funit Pointer to functional unit element to deallocate

References free_safe, funit_clean(), PROFILE, and PROFILE_END.

Referenced by db_add_instance(), db_read(), funit_link_delete_list(), funit_link_remove(), and gen_item_resolve().

01760   { PROFILE(FUNIT_DEALLOC);
01761 
01762   if( funit != NULL ) {
01763 
01764     /* Deallocate the contents of the functional unit itself */
01765     funit_clean( funit );
01766 
01767     /* Deallocate functional unit element itself */
01768     free_safe( funit, sizeof( func_unit ) );
01769 
01770   }
01771 
01772   PROFILE_END;
01773 
01774 }

void funit_delete_thread ( func_unit funit,
thread thr 
)

Removes given thread from the given functional unit's thread pointer/thread pointer list.

Searches the given functional unit thread element for the given thread. When the thread is found, its corresponding thread link is moved to the end of the thread list, the next pointer is updated accordingly and the thread pointer is set to NULL. This function will be called whenever a thread is killed in the simulator.

Parameters:
funit Pointer to functional unit to delete thread from thread pointer/thread list
thr Pointer to thread to remove from the given statement

References func_unit_s::elem, func_unit_s::elem_type, thr_list_s::head, thr_list_s::next, thr_link_s::next, PROFILE, PROFILE_END, thr_list_s::tail, thr_link_s::thr, func_unit_s::thr, and func_unit_s::tlist.

Referenced by sim_kill_thread().

01520   { PROFILE(STATEMENT_DELETE_THREAD);
01521 
01522   assert( funit != NULL );
01523   assert( thr != NULL );
01524 
01525   /* If the statement element type is a thread pointer, simply clear the thread pointer */
01526   if( funit->elem_type == 0 ) {
01527     funit->elem.thr = NULL;
01528 
01529   /* Otherwise, find the given thread in the statement thread list and remove it */
01530   } else {
01531 
01532     thr_link* curr = funit->elem.tlist->head;
01533     thr_link* last = NULL;
01534 
01535     /* Search the thread list for the matching thread */
01536     while( (curr != NULL) && (curr->thr != thr) ) {
01537       last = curr;
01538       curr = curr->next;
01539     }
01540 
01541     /* We should have found the thread in the statement list */
01542     assert( curr != NULL );
01543 
01544     /* Move this thread link to the end of the thread link list and clear out its values */
01545     if( funit->elem.tlist->tail != curr ) {
01546       if( funit->elem.tlist->head == curr ) {
01547         funit->elem.tlist->head = curr->next;
01548       } else {
01549         last->next = curr->next;
01550       }
01551       funit->elem.tlist->tail->next = curr;
01552       funit->elem.tlist->tail       = curr;
01553       curr->next = NULL;
01554     }
01555   
01556     /* Clear the thread pointer */
01557     curr->thr = NULL; 
01558   
01559     /* If the thread list next pointer is NULL, set it to the freed thread link structure */
01560     if( funit->elem.tlist->next == NULL ) {
01561       funit->elem.tlist->next = curr;
01562     }
01563   
01564   } 
01565 
01566   PROFILE_END;
01567     
01568 }

void funit_display_expressions ( func_unit funit  ) 

Displays expressions stored in this functional unit.

Parameters:
funit Pointer to functional unit element to display expressions

Iterates through expression list of specified functional unit, displaying each expression's id.

References exp_link_s::exp, func_unit_s::exp_head, expression_display(), get_funit_type(), func_unit_s::name, exp_link_s::next, obf_funit, PROFILE, PROFILE_END, and func_unit_s::type.

01388                                                    { PROFILE(FUNIT_DISPLAY_EXPRESSIONS);
01389 
01390   exp_link* expl;    /* Pointer to current expression link element */
01391 
01392   printf( "%s => %s", get_funit_type( funit->type ), obf_funit( funit->name ) );
01393 
01394   expl = funit->exp_head;
01395   while( expl != NULL ) {
01396     expression_display( expl->exp );
01397     expl = expl->next;
01398   }
01399 
01400   PROFILE_END;
01401 
01402 }

void funit_display_signals ( func_unit funit  ) 

Displays signals stored in this functional unit.

Parameters:
funit Pointer to functional unit element to display signals.

Iterates through signal list of specified functional unit, displaying each signal's name, width, lsb and value.

References get_funit_type(), func_unit_s::name, sig_link_s::next, obf_funit, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, func_unit_s::type, and vsignal_display().

01366                                                { PROFILE(FUNIT_DISPLAY_SIGNALS);
01367 
01368   sig_link* sigl;  /* Pointer to current signal link element */
01369 
01370   printf( "%s => %s", get_funit_type( funit->type ), obf_funit( funit->name ) );
01371 
01372   sigl = funit->sig_head;
01373   while( sigl != NULL ) {
01374     vsignal_display( sigl->sig );
01375     sigl = sigl->next;
01376   }
01377 
01378   PROFILE_END;
01379 
01380 }

func_unit* funit_find_by_id ( int  id  ) 

Finds the functional unit that contains the given statement/expression ID.

Returns:
Returns a pointer to the functional unit that contains the specified expression/statement ID if one exists; otherwise, returns NULL.

Searches the functional units until one is found that contains the expression/statement identified by the specified ID and returns a pointer to this functional unit. If no such ID exists in the design, a value of NULL is returned to the calling statement.

Parameters:
id Expression/statement ID to search for

References curr_db, func_unit_s::exp_head, exp_link_find(), funit_link_s::funit, db_s::funit_head, funit_link_s::next, PROFILE, and PROFILE_END.

Referenced by combination_get_coverage(), combination_get_expression(), stmt_blk_add_to_remove_list(), and stmt_blk_remove().

01241   { PROFILE(FUNIT_FIND_BY_ID);
01242 
01243   funit_link* funitl;       /* Temporary pointer to functional unit link */
01244   exp_link*   expl = NULL;  /* Temporary pointer to expression link */
01245 
01246   funitl = db_list[curr_db]->funit_head;
01247   while( (funitl != NULL) && (expl == NULL) ) {
01248     if( (expl = exp_link_find( id, funitl->funit->exp_head )) == NULL ) {
01249       funitl = funitl->next;
01250     }
01251   }
01252 
01253   PROFILE_END;
01254       
01255   return( (funitl == NULL) ? NULL : funitl->funit );
01256     
01257 }

mod_parm* funit_find_param ( char *  name,
func_unit funit 
)

Finds specified module parameter given the current functional unit and its scope.

Returns:
Returns a pointer to the module parameter structure that contains the specified parameter name if it exists; otherwise, returns NULL.

Recursively searches from the current functional unit up through its scope until either the parameter is found or until we have exhausted the scope.

Parameters:
name Name of parameter to search for
funit Functional unit to check for existence of named parameter

References funit_find_param(), mod_parm_find(), func_unit_s::param_head, func_unit_s::parent, PROFILE, and PROFILE_END.

Referenced by funit_find_param(), and scope_find_param().

00252   { PROFILE(FUNIT_FIND_PARAM);
00253 
00254   mod_parm* mparm = NULL;  /* Pointer to found module parameter */
00255 
00256   if( funit != NULL ) {
00257 
00258     if( (mparm = mod_parm_find( name, funit->param_head )) == NULL ) {
00259       mparm = funit_find_param( name, funit->parent );
00260     }
00261 
00262   }
00263 
00264   PROFILE_END;
00265 
00266   return( mparm );
00267 
00268 }

vsignal* funit_find_signal ( char *  name,
func_unit funit 
)

Finds specified signal given in the current functional unit.

Returns:
Returns a pointer to the found signal in the given functional unit; otherwise, returns NULL if the signal could not be found.

Searches the signal list in the given functional unit for the specified signal name. If it isn't found there, we look in the generate item list for the same signal.

Parameters:
name Name of the signal that we are searching for
funit Pointer to functional unit to search in

References gen_item_s::elem, FALSE, gen_item_create_sig(), gen_item_dealloc(), gen_item_find(), gitem_link_s::gi, func_unit_s::gitem_head, gitem_link_find(), vsignal_s::name, PROFILE, PROFILE_END, gen_item_s::sig, sig_link_s::sig, func_unit_s::sig_head, and sig_link_find().

Referenced by scope_find_signal().

00280   { PROFILE(FUNIT_FIND_SIGNAL);
00281 
00282   vsignal*    found_sig = NULL;  /* Pointer to the found signal */
00283   vsignal     sig;               /* Holder for signal to search for */
00284   sig_link*   sigl;              /* Pointer to signal link */
00285 #ifndef VPI_ONLY
00286   gen_item*   gi;                /* Pointer to temporary generate item */
00287   gen_item*   found_gi;          /* Pointer to found generate item */
00288   gitem_link* gil;               /* Pointer to found generate item link */
00289 #endif
00290 
00291   sig.name = name;
00292 
00293   /* Search for signal in given functional unit signal list */
00294   if( (sigl = sig_link_find( name, funit->sig_head )) != NULL ) {
00295 
00296     found_sig = sigl->sig;
00297 
00298 #ifndef VPI_ONLY
00299   } else {
00300 
00301     /* If it was not found, search in the functional unit generate item list */
00302     gi = gen_item_create_sig( &sig );
00303 
00304     if( ((gil = gitem_link_find( gi, funit->gitem_head )) != NULL) && ((found_gi = gen_item_find( gil->gi, gi )) != NULL) ) {
00305       found_sig = found_gi->elem.sig;
00306     }
00307 
00308     /* Deallocate temporary generate item */
00309     gen_item_dealloc( gi, FALSE );
00310 #endif
00311 
00312   }
00313 
00314   PROFILE_END;
00315 
00316   return( found_sig );
00317 
00318 }

char* funit_flatten_name ( func_unit funit  ) 

Flattens the functional unit name by removing all unnamed scope portions.

Returns:
Returns the flattened name of the given functional unit
Parameters:
funit Pointer to functional unit to flatten name

References db_is_unnamed_scope(), func_unit_s::name, PROFILE, PROFILE_END, and scope_extract_front().

Referenced by assertion_funit_summary(), assertion_funit_verbose(), assertion_instance_verbose(), combination_funit_summary(), combination_funit_verbose(), combination_instance_verbose(), fsm_funit_summary(), fsm_funit_verbose(), fsm_instance_verbose(), line_funit_summary(), line_funit_verbose(), line_instance_verbose(), memory_ae_funit_summary(), memory_funit_verbose(), memory_instance_verbose(), memory_toggle_funit_summary(), ovl_display_verbose(), race_report_summary(), race_report_verbose(), toggle_funit_summary(), toggle_funit_verbose(), and toggle_instance_verbose().

01203   { PROFILE(FUNIT_FLATTEN_NAME);
01204 
01205   static char fscope[4096];  /* Flattened scope name */
01206   char        tmp[4096];     /* Temporary string storage */
01207   char        front[4096];   /* First portion of scope name */
01208   char        rest[4096];    /* Last portion of scope name */
01209 
01210   assert( funit != NULL );
01211 
01212   scope_extract_front( funit->name, fscope, rest );
01213   strcpy( tmp, rest );
01214   scope_extract_front( tmp, front, rest );
01215 
01216   while( front[0] != '\0' ) {
01217     if( !db_is_unnamed_scope( front ) ) {
01218       strcat( fscope, "." );
01219       strcat( fscope, front );
01220     }
01221     strcpy( tmp, rest );
01222     scope_extract_front( tmp, front, rest ); 
01223   }
01224 
01225   PROFILE_END;
01226 
01227   return fscope;
01228 
01229 }

char* funit_gen_task_function_namedblock_name ( char *  orig_name,
func_unit parent 
)

Generates the internally used task/function/named-block name for the specified functional unit.

Returns:
Returns dynamically allocated string containing internally used task, function or named-block name.
Parameters:
orig_name Verilog name of task, function or named-block
parent Pointer to parent functional unit of this functional unit

References func_unit_s::name, PROFILE, PROFILE_END, and strdup_safe.

Referenced by db_add_function_task_namedblock().

00353   { PROFILE(FUNIT_GEN_TASK_FUNCTION_NAMEDBLOCK_NAME);
00354 
00355   char         full_name[4096];  /* Container for new name */
00356   unsigned int rv;               /* Return value for snprintf calls */
00357 
00358   assert( parent != NULL );
00359   assert( orig_name != NULL );
00360 
00361   /* Generate full name to use for the function/task */
00362   rv = snprintf( full_name, 4096, "%s.%s", parent->name, orig_name );
00363   assert( rv < 4096 );
00364 
00365   PROFILE_END;
00366 
00367   return( strdup_safe( full_name ) );
00368 
00369 }

func_unit* funit_get_curr_function ( func_unit funit  ) 

Returns the parent function of the given functional unit (if there is one).

Returns:
Returns a pointer to the function that contains the specified functional unit if one exists; otherwise, returns NULL.
Parameters:
funit Functional unit that may be nested in a function

References FUNIT_AFUNCTION, FUNIT_FUNCTION, FUNIT_MODULE, func_unit_s::parent, PROFILE, PROFILE_END, and func_unit_s::type.

Referenced by db_create_expression().

00177   { PROFILE(FUNIT_GET_CURR_FUNCTION);
00178 
00179   assert( funit != NULL );
00180 
00181   while( (funit->type != FUNIT_FUNCTION) && (funit->type != FUNIT_AFUNCTION) && (funit->type != FUNIT_MODULE) ) {
00182     funit = funit->parent;
00183   }
00184 
00185   PROFILE_END;
00186 
00187   return( ((funit->type == FUNIT_FUNCTION) || (funit->type == FUNIT_AFUNCTION)) ? funit : NULL );
00188 
00189 }

func_unit* funit_get_curr_module ( func_unit funit  ) 

Returns the parent module of the given functional unit.

Returns:
Returns a pointer to the module that contains the specified functional unit.

Traverses up parent list until the FUNIT_MODULE is found (parent should be NULL).

Parameters:
funit Pointer to functional unit to get its module from

References func_unit_s::parent, PROFILE, and PROFILE_END.

Referenced by combination_get_expression(), db_add_function_task_namedblock(), db_find_typedef(), exclude_find_expression(), exclude_find_fsm_arc(), exclude_find_signal(), func_iter_add_sig_links(), func_iter_add_stmt_links(), func_iter_count_scopes(), and mod_parm_add().

00135   { PROFILE(FUNIT_GET_CURR_MODULE);
00136 
00137   assert( funit != NULL );
00138 
00139   while( funit->parent != NULL ) {
00140     funit = funit->parent;
00141   }
00142 
00143   PROFILE_END;
00144 
00145   return( funit );
00146 
00147 }

const func_unit* funit_get_curr_module_safe ( const func_unit funit  ) 

Returns the parent module of the given functional unit (returning a const version).

Returns:
Returns a const pointer to the module that contains the specified functional unit.

Traverses up parent list until the FUNIT_MODULE is found (parent should be NULL). Does this in a way that guarantees that the found functional unit will not be modified.

Parameters:
funit Pointer to functional unit to get its module from

References func_unit_s::parent, PROFILE, and PROFILE_END.

Referenced by bind_find_sig_name().

00157   { PROFILE(FUNIT_GET_CURR_MODULE_SAFE);
00158 
00159   assert( funit != NULL );
00160 
00161   while( funit->parent != NULL ) {
00162     funit = funit->parent;
00163   }
00164 
00165   PROFILE_END;
00166 
00167   return( funit );
00168 
00169 }

func_unit* funit_get_curr_task ( func_unit funit  ) 

Returns the parent task of the given functional unit (if there is one).

Returns:
Returns a pointer to the function that contains the specified functional unit if one exists; otherwise, returns NULL.
Parameters:
funit Functional unit that may be nested in a function

References FUNIT_ATASK, FUNIT_MODULE, FUNIT_TASK, func_unit_s::parent, PROFILE, PROFILE_END, and func_unit_s::type.

00197   { PROFILE(FUNIT_GET_CURR_TASK);
00198 
00199   assert( funit != NULL );
00200 
00201   while( (funit->type != FUNIT_TASK) && (funit->type != FUNIT_ATASK) && (funit->type != FUNIT_MODULE) ) {
00202     funit = funit->parent;
00203   }
00204 
00205   PROFILE_END;
00206 
00207   return( ((funit->type == FUNIT_TASK) || (funit->type == FUNIT_ATASK)) ? funit : NULL );
00208 
00209 }

int funit_get_port_count ( func_unit funit  ) 

Returns the number of input, output and inout ports in the specified functional unit.

Returns:
Returns the number of input, output and inout ports specified in this functional unit
Parameters:
funit Pointer to functional unit to process

References sig_link_s::next, ssuppl_u::part, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, SSUPPL_TYPE_INOUT_NET, SSUPPL_TYPE_INOUT_REG, SSUPPL_TYPE_INPUT_NET, SSUPPL_TYPE_INPUT_REG, SSUPPL_TYPE_OUTPUT_NET, SSUPPL_TYPE_OUTPUT_REG, vsignal_s::suppl, and ssuppl_u::type.

Referenced by bind_task_function_namedblock().

00216   { PROFILE(FUNIT_GET_PORT_COUNT);
00217 
00218   sig_link* sigl;          /* Pointer to current signal link to examine */
00219   int       port_cnt = 0;  /* Return value for this function */
00220 
00221   assert( funit != NULL );
00222 
00223   sigl = funit->sig_head;
00224   while( sigl != NULL ) {
00225     if( (sigl->sig->suppl.part.type == SSUPPL_TYPE_INPUT_NET)  ||
00226         (sigl->sig->suppl.part.type == SSUPPL_TYPE_INPUT_REG)  ||
00227         (sigl->sig->suppl.part.type == SSUPPL_TYPE_OUTPUT_NET) ||
00228         (sigl->sig->suppl.part.type == SSUPPL_TYPE_OUTPUT_REG) ||
00229         (sigl->sig->suppl.part.type == SSUPPL_TYPE_INOUT_NET)  ||
00230         (sigl->sig->suppl.part.type == SSUPPL_TYPE_INOUT_REG) ) {
00231       port_cnt++;
00232     }
00233     sigl = sigl->next;
00234   }
00235 
00236   PROFILE_END;
00237 
00238   return( port_cnt );
00239 
00240 }

static void funit_init ( func_unit funit  )  [static]

Initializes all contents to NULL.

Parameters:
funit Pointer to functional unit to initialize

References func_unit_s::ei_head, func_unit_s::ei_tail, func_unit_s::elem, func_unit_s::elem_type, func_unit_s::end_line, func_unit_s::er_head, func_unit_s::er_tail, func_unit_s::exp_head, func_unit_s::exp_tail, func_unit_s::filename, func_unit_s::first_stmt, func_unit_s::fsm_head, func_unit_s::fsm_tail, FUNIT_MODULE, func_unit_s::gitem_head, func_unit_s::gitem_tail, func_unit_s::name, func_unit_s::param_head, func_unit_s::param_tail, func_unit_s::parent, PROFILE, PROFILE_END, func_unit_s::race_head, func_unit_s::race_tail, func_unit_s::sig_head, func_unit_s::sig_tail, func_unit_s::start_line, func_unit_s::stat, func_unit_s::stmt_head, func_unit_s::stmt_tail, func_unit_s::tdi_head, func_unit_s::tdi_tail, func_unit_s::tf_head, func_unit_s::tf_tail, func_unit_s::thr, func_unit_s::type, and func_unit_s::version.

Referenced by funit_create().

00066   { PROFILE(FUNIT_INIT);
00067     
00068   funit->type       = FUNIT_MODULE;
00069   funit->name       = NULL;
00070   funit->filename   = NULL;
00071   funit->version    = NULL;
00072   funit->start_line = 0;
00073   funit->end_line   = 0;
00074   funit->stat       = NULL;
00075   funit->sig_head   = NULL;
00076   funit->sig_tail   = NULL;
00077   funit->exp_head   = NULL;
00078   funit->exp_tail   = NULL;
00079   funit->first_stmt = NULL;
00080   funit->stmt_head  = NULL;
00081   funit->stmt_tail  = NULL;
00082   funit->fsm_head   = NULL;
00083   funit->fsm_tail   = NULL;
00084   funit->race_head  = NULL;
00085   funit->race_tail  = NULL;
00086   funit->param_head = NULL;
00087   funit->param_tail = NULL;
00088   funit->gitem_head = NULL;
00089   funit->gitem_tail = NULL;
00090   funit->tf_head    = NULL;
00091   funit->tf_tail    = NULL;
00092   funit->tdi_head   = NULL;
00093   funit->tdi_tail   = NULL;
00094   funit->ei_head    = NULL;
00095   funit->ei_tail    = NULL;
00096   funit->er_head    = NULL;
00097   funit->er_tail    = NULL;
00098   funit->parent     = NULL;
00099   funit->elem_type  = 0;
00100   funit->elem.thr   = NULL;
00101 
00102   PROFILE_END;
00103 
00104 }

bool funit_is_child_of ( func_unit parent,
func_unit child 
)

Returns TRUE if the specified "parent" functional unit is a parent of the "child" functional unit.

Parameters:
parent Potential parent functional unit to check for relationship to child
child Potential child functional unit to check for relationship to parent
Returns:
Returns TRUE if the relationship of the "parent" and "child" is just that.

References func_unit_s::parent, PROFILE, and PROFILE_END.

Referenced by sim_kill_thread_with_funit().

01348                                                               { PROFILE(FUNIT_IS_CHILD_OF);
01349 
01350   while( (child->parent != NULL) && (child->parent != parent) ) {
01351     child = child->parent;
01352   }
01353 
01354   PROFILE_END;
01355 
01356   return( child->parent == parent );
01357 
01358 }

bool funit_is_one_signal_assigned ( func_unit funit  ) 

Returns TRUE if at least one signal was found that needs to be assigned by the dumpfile.

Returns:
Returns TRUE if at least one signal was found that needs to be assigned by the dumpfile.
Parameters:
funit Pointer to functional unit to check

References vsignal_s::exp_head, sig_link_s::next, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, and SIGNAL_ASSIGN_FROM_DUMPFILE.

Referenced by db_check_dumpfile_scopes().

01613   { PROFILE(FUNIT_IS_ONE_SIGNAL_ASSIGNED);
01614 
01615   sig_link* sigl = funit->sig_head;
01616 
01617   while( (sigl != NULL) && ((sigl->sig->exp_head == NULL) || !SIGNAL_ASSIGN_FROM_DUMPFILE( sigl->sig )) ) {
01618     sigl = sigl->next;
01619   }
01620 
01621   PROFILE_END;
01622 
01623   return( sigl != NULL );
01624 
01625 }

bool funit_is_top_module ( func_unit funit  ) 

Returns TRUE if the given functional unit does not contain any input, output or inout ports.

Returns:
Returns TRUE if the specified functional unit does not contain any inputs, outputs or inouts and is of type MODULE.
Parameters:
funit Pointer to functional unit to check

References FALSE, FUNIT_MODULE, sig_link_s::next, ssuppl_u::part, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, SSUPPL_TYPE_INOUT_NET, SSUPPL_TYPE_INOUT_REG, SSUPPL_TYPE_INPUT_NET, SSUPPL_TYPE_INPUT_REG, SSUPPL_TYPE_OUTPUT_NET, SSUPPL_TYPE_OUTPUT_REG, vsignal_s::suppl, ssuppl_u::type, and func_unit_s::type.

Referenced by db_check_for_top_module().

01265   { PROFILE(FUNIT_IS_TOP_MODULE);
01266 
01267   bool      retval = FALSE;  /* Return value for this function */
01268   sig_link* sigl;            /* Pointer to current signal link */
01269 
01270   assert( funit != NULL );
01271 
01272   /* Only check the signal list if we are a MODULE type */
01273   if( funit->type == FUNIT_MODULE ) {
01274 
01275     sigl = funit->sig_head;
01276     while( (sigl != NULL) &&
01277            (sigl->sig->suppl.part.type != SSUPPL_TYPE_INPUT_NET)  &&
01278            (sigl->sig->suppl.part.type != SSUPPL_TYPE_INPUT_REG)  &&
01279            (sigl->sig->suppl.part.type != SSUPPL_TYPE_OUTPUT_NET) &&
01280            (sigl->sig->suppl.part.type != SSUPPL_TYPE_OUTPUT_REG) &&
01281            (sigl->sig->suppl.part.type != SSUPPL_TYPE_INOUT_NET)  &&
01282            (sigl->sig->suppl.part.type != SSUPPL_TYPE_INOUT_REG) ) {
01283       sigl = sigl->next;
01284     }
01285 
01286     retval = (sigl == NULL);
01287 
01288   }
01289 
01290   PROFILE_END;
01291 
01292   return( retval );
01293 
01294 }

bool funit_is_unnamed ( func_unit funit  ) 

Returns TRUE if the given functional unit is an unnamed scope.

Parameters:
funit Pointer to functional unit to check.
Returns:
Returns TRUE if the specified functional unit is an unnamed scope; otherwise, returns FALSE.

A functional unit is considered to be an unnamed scope if it is of type FUNIT_NAMED_BLOCK and the last portion of its functional unit name returns TRUE after calling the db_is_unnamed_scope() function.

References db_is_unnamed_scope(), FALSE, FUNIT_ANAMED_BLOCK, FUNIT_NAMED_BLOCK, func_unit_s::name, PROFILE, PROFILE_END, scope_extract_back(), and func_unit_s::type.

Referenced by assertion_funit_summary(), assertion_funit_verbose(), assertion_instance_summary(), assertion_instance_verbose(), combination_funit_summary(), combination_funit_verbose(), combination_get_stats(), combination_instance_summary(), combination_instance_verbose(), combination_reset_counted_exprs(), fsm_funit_summary(), fsm_funit_verbose(), fsm_instance_summary(), fsm_instance_verbose(), func_iter_add_sig_links(), func_iter_add_stmt_links(), func_iter_count_scopes(), funit_is_unnamed_child_of(), instance_find_scope(), line_funit_summary(), line_funit_verbose(), line_get_stats(), line_instance_summary(), line_instance_verbose(), memory_ae_funit_summary(), memory_ae_instance_summary(), memory_funit_verbose(), memory_get_stats(), memory_instance_verbose(), memory_toggle_funit_summary(), memory_toggle_instance_summary(), rank_gather_comp_cdd_cov(), toggle_funit_summary(), toggle_funit_verbose(), toggle_get_stats(), toggle_instance_summary(), and toggle_instance_verbose().

01306                                           { PROFILE(FUNIT_IS_UNNAMED);
01307 
01308   bool retval = FALSE;  /* Return value for this function */
01309   char back[256];       /* Last portion of functional unit name */
01310   char rest[4096];      /* Rest of functional unit name */
01311 
01312   /* Only begin..end blocks can be unnamed scopes */
01313   if( (funit->type == FUNIT_NAMED_BLOCK) || (funit->type == FUNIT_ANAMED_BLOCK) ) {
01314     scope_extract_back( funit->name, back, rest );
01315     retval = db_is_unnamed_scope( back );
01316   }
01317 
01318   PROFILE_END;
01319 
01320   return( retval );
01321 
01322 }

bool funit_is_unnamed_child_of ( func_unit parent,
func_unit child 
)

Returns TRUE if the specified "parent" functional unit is a parent of the "child" functional unit.

Parameters:
parent Potential parent functional unit to check for relationship to child
child Potential child functional unit to check for relationship to parent
Returns:
Returns TRUE if the relationship of the "parent" and "child" is just that.

References funit_is_unnamed(), func_unit_s::parent, PROFILE, and PROFILE_END.

01330                                                                       { PROFILE(FUNIT_IS_UNNAMED_CHILD_OF);
01331 
01332   while( (child->parent != NULL) && (child->parent != parent) && funit_is_unnamed( child->parent ) ) {
01333     child = child->parent;
01334   }
01335 
01336   PROFILE_END;
01337 
01338   return( child->parent == parent );
01339 
01340 }

void funit_merge ( func_unit base,
func_unit other 
)

Merges two functional units into the base functional unit.

Merges two functional units into the base functional unit. Used for creating merged results for GUI usage.

Parameters:
base Base functional unit that will contain the merged results
other Other functional unit that will be merged

References func_unit_s::er_head, exclude_merge(), exp_link_s::exp, func_unit_s::exp_head, expression_merge(), func_unit_s::fsm_head, fsm_merge(), func_unit_s::name, exclude_reason_s::next, fsm_link_s::next, sig_link_s::next, exp_link_s::next, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, fsm_link_s::table, and vsignal_merge().

Referenced by instance_merge_tree().

01144   { PROFILE(FUNIT_MERGE);
01145 
01146   exp_link*       curr_base_exp;   /* Pointer to current expression in base functional unit expression list */
01147   exp_link*       curr_other_exp;  /* Pointer to current expression in other functional unit expression list */
01148   sig_link*       curr_base_sig;   /* Pointer to current signal in base functional unit signal list */
01149   sig_link*       curr_other_sig;  /* Pointer to current signal in other functional unit signal list */
01150   fsm_link*       curr_base_fsm;   /* Pointer to current FSM in base functional unit FSM list */
01151   fsm_link*       curr_other_fsm;  /* Pointer to current FSM in other functional unit FSM list */
01152   exclude_reason* curr_other_er;
01153 
01154   assert( base != NULL );
01155   assert( base->name != NULL );
01156 
01157   /* Handle all functional unit expressions */
01158   curr_base_exp  = base->exp_head;
01159   curr_other_exp = other->exp_head;
01160   while( (curr_base_exp != NULL) && (curr_other_exp != NULL) ) {
01161     expression_merge( curr_base_exp->exp, curr_other_exp->exp );
01162     curr_base_exp  = curr_base_exp->next;
01163     curr_other_exp = curr_other_exp->next;
01164   }
01165   assert( (curr_base_exp == NULL) && (curr_other_exp == NULL) );
01166 
01167   /* Handle all functional unit signals */
01168   curr_base_sig  = base->sig_head;
01169   curr_other_sig = other->sig_head;
01170   while( (curr_base_sig != NULL) && (curr_other_sig != NULL) ) {
01171     vsignal_merge( curr_base_sig->sig, curr_other_sig->sig );
01172     curr_base_sig  = curr_base_sig->next;
01173     curr_other_sig = curr_other_sig->next;
01174   }
01175   assert( (curr_base_sig == NULL) && (curr_other_exp == NULL) );
01176 
01177   /* Handle all functional unit FSMs */
01178   curr_base_fsm  = base->fsm_head;
01179   curr_other_fsm = other->fsm_head;
01180   while( (curr_base_fsm != NULL) && (curr_other_fsm != NULL) ) {
01181     fsm_merge( curr_base_fsm->table, curr_other_fsm->table );
01182     curr_base_fsm  = curr_base_fsm->next;
01183     curr_other_fsm = curr_other_fsm->next;
01184   }
01185   assert( (curr_base_fsm == NULL) && (curr_other_fsm == NULL) );
01186 
01187   /* Handle all functional unit exclusion reasons */
01188   curr_other_er = other->er_head;
01189   while( curr_other_er != NULL ) {
01190     exclude_merge( base, curr_other_er );
01191     curr_other_er = curr_other_er->next;
01192   }
01193 
01194   PROFILE_END;
01195 
01196 }

void funit_output_dumpvars ( FILE *  vfile,
func_unit funit,
const char *  scope 
)

Outputs dumpvars calls to the given file.

Outputs all of the needed signals to the specified file.

Parameters:
vfile Pointer to file to output dumpvars information to
funit Pointer to functional unit to output
scope Instance scope

References ssuppl_u::assigned, FALSE, vsignal_s::name, sig_link_s::next, ssuppl_u::part, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, SSUPPL_TYPE_ENUM, SSUPPL_TYPE_EVENT, SSUPPL_TYPE_GENVAR, SSUPPL_TYPE_MEM, SSUPPL_TYPE_PARAM, SSUPPL_TYPE_PARAM_REAL, vsignal_s::suppl, TRUE, and ssuppl_u::type.

Referenced by instance_output_dumpvars().

01577   { PROFILE(FUNIT_OUTPUT_DUMPVARS);
01578 
01579   sig_link* sigl  = funit->sig_head;
01580   bool      first = TRUE;
01581 
01582   while( sigl != NULL ) {
01583     if( (sigl->sig->suppl.part.assigned == 0) &&
01584         (sigl->sig->suppl.part.type != SSUPPL_TYPE_PARAM)      &&
01585         (sigl->sig->suppl.part.type != SSUPPL_TYPE_PARAM_REAL) &&
01586         (sigl->sig->suppl.part.type != SSUPPL_TYPE_ENUM)       &&
01587         (sigl->sig->suppl.part.type != SSUPPL_TYPE_MEM)        &&
01588         (sigl->sig->suppl.part.type != SSUPPL_TYPE_GENVAR)     &&
01589         (sigl->sig->suppl.part.type != SSUPPL_TYPE_EVENT) ) {
01590       if( first ) {
01591         first = FALSE;
01592         fprintf( vfile, "  $dumpvars( 1, %s.%s", scope, sigl->sig->name );
01593       } else {
01594         fprintf( vfile, ",\n                %s.%s", scope, sigl->sig->name );
01595       }
01596     }
01597     sigl = sigl->next;
01598   } 
01599 
01600   if( !first ) {
01601     fprintf( vfile, " );\n" );
01602   }
01603 
01604   PROFILE_END;
01605 
01606 }

void funit_push_threads ( func_unit funit,
const statement stmt,
const sim_time time 
)

Pushes the threads associated with the given functional unit onto the active simulation queue.

Adds all of the given functional unit threads to the active simulation queue.

Parameters:
funit Pointer of functional unit to push threads from
stmt Pointer to the statement to search for in functional unit threads
time Pointer to current simulation time

References thread_s::curr, func_unit_s::elem, func_unit_s::elem_type, thr_list_s::head, thr_link_s::next, thread_s::part, PROFILE, PROFILE_END, sim_thread_push(), thread_s::suppl, thr_link_s::thr, func_unit_s::thr, THR_ST_WAITING, and func_unit_s::tlist.

Referenced by sim_expr_changed().

01489   { PROFILE(FUNIT_PUSH_THREADS);
01490 
01491   assert( funit != NULL );
01492 
01493   if( funit->elem_type == 0 ) {
01494     if( (funit->elem.thr != NULL) && (funit->elem.thr->suppl.part.state == THR_ST_WAITING) && (funit->elem.thr->curr == stmt) ) {
01495       sim_thread_push( funit->elem.thr, time );
01496     }
01497   } else {
01498     thr_link* curr = funit->elem.tlist->head;
01499     while( (curr != NULL) && (curr->thr != NULL) ) {
01500       if( (curr->thr != NULL) && (curr->thr->suppl.part.state == THR_ST_WAITING) && (curr->thr->curr == stmt) ) {
01501         sim_thread_push( curr->thr, time );
01502       }
01503       curr = curr->next;
01504     }
01505   }
01506 
01507   PROFILE_END;
01508 
01509 }

void funit_remove_stmt_blks_calling_stmt ( func_unit funit,
statement stmt 
)

Finds all expressions that call the given statement.

Searches all statement blocks in the given functional unit that have expressions that call the functional unit containing the given statement as its first statement.

Parameters:
funit Pointer to functional unit to search in
stmt Pointer to statement to search for

References stmt_link_s::next, statement_s::part, PROFILE, PROFILE_END, statement_contains_expr_calling_stmt(), stmt_link_s::stmt, stmt_blk_add_to_remove_list(), func_unit_s::stmt_head, and statement_s::suppl.

Referenced by instance_remove_stmt_blks_calling_stmt().

00327   { PROFILE(FUNIT_REMOVE_STMT_BLKS_CALLING_STMT);
00328 
00329   if( funit != NULL ) {
00330 
00331     stmt_link* curr = funit->stmt_head;
00332 
00333     /* Search all of the statement blocks */
00334     while( curr != NULL ) {
00335       if( (curr->stmt->suppl.part.head == 1) && statement_contains_expr_calling_stmt( curr->stmt, stmt ) ) {
00336         stmt_blk_add_to_remove_list( curr->stmt );
00337       }
00338       curr = curr->next;
00339     }
00340 
00341   }
00342 
00343   PROFILE_END;
00344 
00345 }

void funit_size_elements ( func_unit funit,
funit_inst inst,
bool  gen_all,
bool  alloc_exprs 
)

Sizes all elements for the current functional unit from the given instance.

Exceptions:
anonymous expression_resize enumerate_resolve param_resolve expression_set_value expression_set_value expression_set_value vsignal_create_vec gen_item_resize_stmts_and_sigs

Resizes signals if they are contigent upon parameter values. After all signals have been resized, the signal's corresponding expressions are resized. This function should be called just prior to outputting this funtional unit's contents to the CDD file (after parsing phase only)

Parameters:
funit Pointer to functional unit containing elements to resize
inst Pointer to instance containing this functional unit
gen_all Set to TRUE to generate all components (this should only be set by the funit_db_write function)
alloc_exprs Allocates vector data for all expressions if set to TRUE

References enumerate_resolve(), ESUPPL_IS_ROOT, exp_link_s::exp, func_unit_s::exp_head, mod_parm_s::exp_head, vsignal_s::exp_head, EXP_OP_FUNC_CALL, EXP_OP_PASSIGN, expression_resize(), expression_set_value(), FALSE, fsm_create_tables(), func_unit_s::fsm_head, esuppl_u::gen_expr, gen_item_bind(), gen_item_resize_stmts_and_sigs(), gitem_link_s::gi, funit_inst_s::gitem_head, inst_parm_bind(), inst_parm_s::mparm, fsm_link_s::next, sig_link_s::next, gitem_link_s::next, inst_parm_s::next, exp_link_s::next, expression_s::op, funit_inst_s::param_head, param_resolve(), param_set_sig_size(), esuppl_u::part, PROFILE, PROFILE_END, expression_s::sig, sig_link_s::sig, mod_parm_s::sig, inst_parm_s::sig, func_unit_s::sig_head, expression_s::suppl, fsm_link_s::table, TRUE, vector_s::ul, vector_s::value, expression_s::value, and vsignal_create_vec().

Referenced by expression_resize(), funit_db_write(), param_size_function(), and race_check_modules().

00385   { PROFILE(FUNIT_SIZE_ELEMENTS);
00386   
00387   inst_parm*  curr_iparm;       /* Pointer to current instance parameter to evaluate */
00388   exp_link*   curr_exp;         /* Pointer to current expression link to evaluate */
00389   fsm_link*   curr_fsm;         /* Pointer to current FSM structure to evaluate */
00390 #ifndef VPI_ONLY
00391   gitem_link* curr_gi;          /* Pointer to current generate item link to evaluate */
00392 #endif
00393   sig_link*   curr_sig;         /* Pointer to current signal link to evaluate */
00394   bool        resolve = FALSE;  /* If set to TRUE, perform one more parameter resolution */
00395 
00396   assert( funit != NULL );
00397   assert( inst != NULL );
00398 
00399   /*
00400    First, traverse through current instance's parameter list and resolve
00401    any unresolved parameters created via generate statements.
00402   */
00403   curr_iparm = inst->param_head;
00404   while( curr_iparm != NULL ) {
00405     if( curr_iparm->mparm == NULL ) {
00406       curr_exp = curr_iparm->sig->exp_head;
00407       while( curr_exp != NULL ) {
00408         if( curr_exp->exp->suppl.part.gen_expr == 0 ) {
00409           expression_set_value( curr_exp->exp, curr_iparm->sig, funit );
00410           resolve = TRUE;
00411         }
00412         curr_exp = curr_exp->next;
00413       }
00414     }
00415     curr_iparm = curr_iparm->next;
00416   }
00417   
00418   /* If we need to do another parameter resolution for generate blocks, do it now */
00419   if( resolve ) {
00420     param_resolve( inst );
00421   }
00422 
00423 #ifndef VPI_ONLY
00424   /*
00425    Second, traverse through any BIND generate items and update the expression name.
00426   */
00427   curr_gi = inst->gitem_head;
00428   while( curr_gi != NULL ) {
00429     gen_item_bind( curr_gi->gi );
00430     curr_gi = curr_gi->next;
00431   }
00432 #endif
00433 
00434   /* 
00435    Third, traverse through current instance's instance parameter list and
00436    set sizes of signals and expressions.
00437   */
00438   curr_iparm = inst->param_head;
00439   while( curr_iparm != NULL ) {
00440     inst_parm_bind( curr_iparm );
00441     if( curr_iparm->mparm != NULL ) {
00442       /* This parameter sizes a signal so perform the signal size */
00443       if( curr_iparm->mparm->sig != NULL ) {
00444         param_set_sig_size( curr_iparm->mparm->sig, curr_iparm );
00445       } else {
00446         /* This parameter attaches to an expression tree */
00447         curr_exp = curr_iparm->mparm->exp_head;
00448         while( curr_exp != NULL ) {
00449           expression_set_value( curr_exp->exp, curr_iparm->sig, funit );
00450           curr_exp = curr_exp->next;
00451         }
00452       }
00453     }
00454     curr_iparm = curr_iparm->next;
00455   }
00456 
00457   /* Traverse through all signals, calculating and creating their vector values */
00458   curr_sig = funit->sig_head;
00459   while( curr_sig != NULL ) {
00460     vsignal_create_vec( curr_sig->sig );
00461     curr_sig = curr_sig->next;
00462   }
00463 
00464   /*
00465    Fourth, resolve all enumerated values for this functional unit
00466   */
00467   enumerate_resolve( inst );
00468 
00469   /*
00470    Fifth, traverse all expressions and set expressions to specified
00471    signals.  Makes the assumption that all children expressions come
00472    before the root expression in the list (this is currently the case).
00473   */
00474   curr_exp = funit->exp_head;
00475   while( curr_exp != NULL ) {
00476     if( ESUPPL_IS_ROOT( curr_exp->exp->suppl ) ) {
00477       /* Perform an entire expression resize */
00478       expression_resize( curr_exp->exp, funit, TRUE, alloc_exprs );
00479     }
00480     if( (curr_exp->exp->sig != NULL) &&
00481         (curr_exp->exp->op != EXP_OP_FUNC_CALL) &&
00482         (curr_exp->exp->op != EXP_OP_PASSIGN) ) {
00483       expression_set_value( curr_exp->exp, curr_exp->exp->sig, funit );
00484       assert( curr_exp->exp->value->value.ul != NULL );
00485     }
00486     curr_exp = curr_exp->next;
00487   }
00488 
00489 #ifndef VPI_ONLY
00490   /* Sixth, traverse all generate items and resize all expressions and signals. */
00491   curr_gi = inst->gitem_head;
00492   while( curr_gi != NULL ) {
00493     gen_item_resize_stmts_and_sigs( curr_gi->gi, funit );
00494     curr_gi = curr_gi->next;
00495   }
00496 #endif
00497 
00498   if( gen_all ) {
00499 
00500     /*
00501      Last, size all FSMs.  Since the FSM structure is reliant on the size
00502      of the state variable signal to which it is attached, its tables
00503      cannot be created until the state variable size can be calculated.
00504      Since this has been done now, size the FSMs.
00505     */
00506     curr_fsm = funit->fsm_head;
00507     while( curr_fsm != NULL ) {
00508       fsm_create_tables( curr_fsm->table );
00509       curr_fsm = curr_fsm->next;
00510     }
00511 
00512   }
00513 
00514   PROFILE_END;
00515     
00516 }

void funit_version_db_read ( func_unit funit,
char **  line 
)

Reads the functional unit version information from the functional unit line and adds it to the current functional unit.

Reads in the functional unit version information from the specified CDD line.

Parameters:
funit Pointer to current functional unit to read version into
line Pointer to current line to parse

References PROFILE, PROFILE_END, strdup_safe, and func_unit_s::version.

Referenced by db_read().

00749   { PROFILE(FUNIT_VERSION_DB_READ);
00750 
00751   /* The current functional unit version must not have already been set */
00752   assert( funit->version == NULL );
00753 
00754   /* Strip the leading whitespace */
00755   while( **line == ' ' ) (*line)++;
00756   
00757   /* The rest of the line will be the version information (internal whitespace is allowed) */
00758   funit->version = strdup_safe( *line );
00759 
00760   PROFILE_END;
00761 
00762 }


Variable Documentation

unsigned int curr_db

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

Pointer to the functional unit structure for the functional unit that is currently being parsed.

Array of database pointers storing all currently loaded databases.

char user_msg[USER_MSG_LENGTH]

Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it.

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