Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

/Users/trevorw/projects/release/covered-0.7.4/src/func_unit.h File Reference


Detailed Description

Contains functions for handling functional units.

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

#include <stdio.h>
#include "defines.h"

Go to the source code of this file.

Functions

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 report_save, 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_merge (func_unit *base, func_unit *other)
 Merges two functional units into the base functional unit.

void funit_db_merge (func_unit *base, FILE *file, bool same)
 Reads and merges two functional units into 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.

void funit_dealloc (func_unit *funit)
 Deallocates functional unit element from heap.


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.

01248   { PROFILE(STATEMENT_ADD_THREAD);
01249 
01250   assert( funit != NULL );
01251   assert( thr != NULL );
01252 
01253   /* Statement element should point to a thread */
01254   if( funit->elem_type == 0 ) {
01255 
01256     /* If the statement element currently points to nothing, simply point the statement element to the given thread */
01257     if( funit->elem.thr == NULL ) {
01258       funit->elem.thr = thr;
01259 
01260     /* Otherwise, change the type to a thread list, create a thread list, initialize it and continue */
01261     } else {
01262 
01263       thr_list* tlist;  /* Pointer to thread list */
01264 
01265       /* Allocate memory for the thread list */
01266       tlist = (thr_list*)malloc_safe( sizeof( thr_list ) );
01267 
01268       /* Create new thread link for existing thread */
01269       tlist->head      = (thr_link*)malloc_safe( sizeof( thr_link ) );
01270       tlist->head->thr = funit->elem.thr;
01271   
01272       /* Create new thread link for specified thread */
01273       tlist->tail       = (thr_link*)malloc_safe( sizeof( thr_link ) );
01274       tlist->tail->thr  = thr;
01275       tlist->tail->next = NULL;
01276       tlist->head->next = tlist->tail;
01277 
01278       /* Specify the next pointer to be NULL (to indicate that there aren't any available thread links to use) */
01279       tlist->next = NULL;
01280     
01281       /* Repopulate the functional unit */
01282       funit->elem.tlist = tlist;
01283       funit->elem_type  = 1;
01284   
01285     }
01286 
01287   /* Otherwise, the statement element is a pointer to a thread list already */
01288   } else {
01289 
01290     /* If there are no thread links already allocated and available, allocate a new thread link */
01291     if( funit->elem.tlist->next == NULL ) {
01292 
01293       thr_link* thrl;  /* Pointer to a thread link */
01294     
01295       /* Allocate and initialize thread link */
01296       thrl       = (thr_link*)malloc_safe( sizeof( thr_link ) );
01297       thrl->thr  = thr;
01298       thrl->next = NULL;
01299 
01300       /* Add the new thread link to the list */
01301       funit->elem.tlist->tail->next = thrl;
01302       funit->elem.tlist->tail       = thrl;
01303 
01304     /* Otherwise, use the link pointed at by next and adjust next */
01305     } else {
01306 
01307       funit->elem.tlist->next->thr = thr;
01308       funit->elem.tlist->next      = funit->elem.tlist->next->next;
01309 
01310     }
01311 
01312   }
01313 
01314 }

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.

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

void funit_db_merge func_unit base,
FILE *  file,
bool  same
 

Reads and merges two functional units into 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

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

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

00718   { PROFILE(FUNIT_DB_READ);
00719 
00720   int  chars_read;   /* Number of characters currently read */
00721   int  params;       /* Number of parameters in string that were parsed */
00722 
00723   /*@-duplicatequals -formattype@*/
00724   if( (params = sscanf( *line, "%d %s \"%[^\"]\" %d %s %d %d %llu%n", 
00725                         &(funit->type), funit->name, scope, name_diff, funit->filename,
00726                         &(funit->start_line), &(funit->end_line), &(funit->timescale), &chars_read )) == 8 ) {
00727   /*@=duplicatequals =formattype@*/
00728 
00729     *line = *line + chars_read;
00730 
00731   } else {
00732 
00733     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",
00734                                 params );
00735     assert( rv < USER_MSG_LENGTH );
00736     print_output( user_msg, FATAL, __FILE__, __LINE__ );
00737     Throw 0;
00738 
00739   }
00740 
00741   PROFILE_END;
00742 
00743 }

void funit_db_write func_unit funit,
char *  scope,
bool  name_diff,
FILE *  file,
funit_inst inst,
bool  report_save,
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
report_save  Specifies that we are attempting to save a CDD after modifying the database in the report command
ids_issued  Specifies if IDs have been issued prior to calling this function

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_iter       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 -formattype@*/
00588     fprintf( file, "%d %d %s \"%s\" %d %s %d %d %llu\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 =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     if( report_save ) {
00658       stmt_iter_reset( &curr_stmt, funit->stmt_tail );
00659     } else {
00660       stmt_iter_reset( &curr_stmt, funit->stmt_head );
00661     }
00662     while( curr_stmt.curr != NULL ) {
00663       statement_db_write( curr_stmt.curr->stmt, file, ids_issued );
00664       stmt_iter_next( &curr_stmt );
00665     }
00666 
00667 #ifndef VPI_ONLY
00668     /* Now print any generated statements in the current instance */
00669     if( inst != NULL ) {
00670       curr_gi = inst->gitem_head;
00671       while( curr_gi != NULL ) {
00672         gen_item_db_write( curr_gi->gi, GI_TYPE_STMT, file );
00673         curr_gi = curr_gi->next;
00674       }
00675     }
00676 #endif
00677 
00678     /* Now print all FSM structures in functional unit */
00679     curr_fsm = funit->fsm_head;
00680     while( curr_fsm != NULL ) {
00681       fsm_db_write( curr_fsm->table, file, ids_issued );
00682       curr_fsm = curr_fsm->next;
00683     }
00684 
00685     /* Now print all race condition block structures in functional unit (if we are a module) */
00686     if( funit->type == FUNIT_MODULE ) {
00687       curr_race = funit->race_head;
00688       while( curr_race != NULL ) {
00689         race_db_write( curr_race, file );
00690         curr_race = curr_race->next;
00691       }
00692     }
00693 
00694     /* Now print all of the exclusion reasons in the functional unit */
00695     curr_er = funit->er_head;
00696     while( curr_er != NULL ) {
00697       exclude_db_write( curr_er, file );
00698       curr_er = curr_er->next;
00699     }
00700 
00701   }
00702 
00703   PROFILE_END;
00704 
00705 }

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

01575   { PROFILE(FUNIT_DEALLOC);
01576 
01577   if( funit != NULL ) {
01578 
01579     /* Deallocate the contents of the functional unit itself */
01580     funit_clean( funit );
01581 
01582     /* Deallocate functional unit element itself */
01583     free_safe( funit, sizeof( func_unit ) );
01584 
01585   }
01586 
01587   PROFILE_END;
01588 
01589 }

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

01354   { PROFILE(STATEMENT_DELETE_THREAD);
01355 
01356   assert( funit != NULL );
01357   assert( thr != NULL );
01358 
01359   /* If the statement element type is a thread pointer, simply clear the thread pointer */
01360   if( funit->elem_type == 0 ) {
01361     funit->elem.thr = NULL;
01362 
01363   /* Otherwise, find the given thread in the statement thread list and remove it */
01364   } else {
01365 
01366     thr_link* curr = funit->elem.tlist->head;
01367     thr_link* last = NULL;
01368 
01369     /* Search the thread list for the matching thread */
01370     while( (curr != NULL) && (curr->thr != thr) ) {
01371       last = curr;
01372       curr = curr->next;
01373     }
01374 
01375     /* We should have found the thread in the statement list */
01376     assert( curr != NULL );
01377 
01378     /* Move this thread link to the end of the thread link list and clear out its values */
01379     if( funit->elem.tlist->tail != curr ) {
01380       if( funit->elem.tlist->head == curr ) {
01381         funit->elem.tlist->head = curr->next;
01382       } else {
01383         last->next = curr->next;
01384       }
01385       funit->elem.tlist->tail->next = curr;
01386       funit->elem.tlist->tail       = curr;
01387       curr->next = NULL;
01388     }
01389   
01390     /* Clear the thread pointer */
01391     curr->thr = NULL; 
01392   
01393     /* If the thread list next pointer is NULL, set it to the freed thread link structure */
01394     if( funit->elem.tlist->next == NULL ) {
01395       funit->elem.tlist->next = curr;
01396     }
01397   
01398   } 
01399 
01400   PROFILE_END;
01401     
01402 }

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.

01222                                                    { PROFILE(FUNIT_DISPLAY_EXPRESSIONS);
01223 
01224   exp_link* expl;    /* Pointer to current expression link element */
01225 
01226   printf( "%s => %s", get_funit_type( funit->type ), obf_funit( funit->name ) );
01227 
01228   expl = funit->exp_head;
01229   while( expl != NULL ) {
01230     expression_display( expl->exp );
01231     expl = expl->next;
01232   }
01233 
01234   PROFILE_END;
01235 
01236 }

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.

01200                                                { PROFILE(FUNIT_DISPLAY_SIGNALS);
01201 
01202   sig_link* sigl;  /* Pointer to current signal link element */
01203 
01204   printf( "%s => %s", get_funit_type( funit->type ), obf_funit( funit->name ) );
01205 
01206   sigl = funit->sig_head;
01207   while( sigl != NULL ) {
01208     vsignal_display( sigl->sig );
01209     sigl = sigl->next;
01210   }
01211 
01212   PROFILE_END;
01213 
01214 }

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

01075   { PROFILE(FUNIT_FIND_BY_ID);
01076 
01077   funit_link* funitl;       /* Temporary pointer to functional unit link */
01078   exp_link*   expl = NULL;  /* Temporary pointer to expression link */
01079 
01080   funitl = db_list[curr_db]->funit_head;
01081   while( (funitl != NULL) && (expl == NULL) ) {
01082     if( (expl = exp_link_find( id, funitl->funit->exp_head )) == NULL ) {
01083       funitl = funitl->next;
01084     }
01085   }
01086 
01087   PROFILE_END;
01088       
01089   return( (funitl == NULL) ? NULL : funitl->funit );
01090     
01091 }

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

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

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

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

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

01037   { PROFILE(FUNIT_FLATTEN_NAME);
01038 
01039   static char fscope[4096];  /* Flattened scope name */
01040   char        tmp[4096];     /* Temporary string storage */
01041   char        front[4096];   /* First portion of scope name */
01042   char        rest[4096];    /* Last portion of scope name */
01043 
01044   assert( funit != NULL );
01045 
01046   scope_extract_front( funit->name, fscope, rest );
01047   strcpy( tmp, rest );
01048   scope_extract_front( tmp, front, rest );
01049 
01050   while( front[0] != '\0' ) {
01051     if( !db_is_unnamed_scope( front ) ) {
01052       strcat( fscope, "." );
01053       strcat( fscope, front );
01054     }
01055     strcpy( tmp, rest );
01056     scope_extract_front( tmp, front, rest ); 
01057   }
01058 
01059   PROFILE_END;
01060 
01061   return fscope;
01062 
01063 }

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

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

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

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

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

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

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

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

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

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

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

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

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.

01182                                                               { PROFILE(FUNIT_IS_CHILD_OF);
01183 
01184   while( (child->parent != NULL) && (child->parent != parent) ) {
01185     child = child->parent;
01186   }
01187 
01188   PROFILE_END;
01189 
01190   return( child->parent == parent );
01191 
01192 }

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

01099   { PROFILE(FUNIT_IS_TOP_MODULE);
01100 
01101   bool      retval = FALSE;  /* Return value for this function */
01102   sig_link* sigl;            /* Pointer to current signal link */
01103 
01104   assert( funit != NULL );
01105 
01106   /* Only check the signal list if we are a MODULE type */
01107   if( funit->type == FUNIT_MODULE ) {
01108 
01109     sigl = funit->sig_head;
01110     while( (sigl != NULL) &&
01111            (sigl->sig->suppl.part.type != SSUPPL_TYPE_INPUT_NET)  &&
01112            (sigl->sig->suppl.part.type != SSUPPL_TYPE_INPUT_REG)  &&
01113            (sigl->sig->suppl.part.type != SSUPPL_TYPE_OUTPUT_NET) &&
01114            (sigl->sig->suppl.part.type != SSUPPL_TYPE_OUTPUT_REG) &&
01115            (sigl->sig->suppl.part.type != SSUPPL_TYPE_INOUT_NET)  &&
01116            (sigl->sig->suppl.part.type != SSUPPL_TYPE_INOUT_REG) ) {
01117       sigl = sigl->next;
01118     }
01119 
01120     retval = (sigl == NULL);
01121 
01122   }
01123 
01124   PROFILE_END;
01125 
01126   return( retval );
01127 
01128 }

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.

01140                                           { PROFILE(FUNIT_IS_UNNAMED);
01141 
01142   bool retval = FALSE;  /* Return value for this function */
01143   char back[256];       /* Last portion of functional unit name */
01144   char rest[4096];      /* Rest of functional unit name */
01145 
01146   /* Only begin..end blocks can be unnamed scopes */
01147   if( (funit->type == FUNIT_NAMED_BLOCK) || (funit->type == FUNIT_ANAMED_BLOCK) ) {
01148     scope_extract_back( funit->name, back, rest );
01149     retval = db_is_unnamed_scope( back );
01150   }
01151 
01152   PROFILE_END;
01153 
01154   return( retval );
01155 
01156 }

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.

01164                                                                       { PROFILE(FUNIT_IS_UNNAMED_CHILD_OF);
01165 
01166   while( (child->parent != NULL) && (child->parent != parent) && funit_is_unnamed( child->parent ) ) {
01167     child = child->parent;
01168   }
01169 
01170   PROFILE_END;
01171 
01172   return( child->parent == parent );
01173 
01174 }

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

00978   { PROFILE(FUNIT_MERGE);
00979 
00980   exp_link*       curr_base_exp;   /* Pointer to current expression in base functional unit expression list */
00981   exp_link*       curr_other_exp;  /* Pointer to current expression in other functional unit expression list */
00982   sig_link*       curr_base_sig;   /* Pointer to current signal in base functional unit signal list */
00983   sig_link*       curr_other_sig;  /* Pointer to current signal in other functional unit signal list */
00984   fsm_link*       curr_base_fsm;   /* Pointer to current FSM in base functional unit FSM list */
00985   fsm_link*       curr_other_fsm;  /* Pointer to current FSM in other functional unit FSM list */
00986   exclude_reason* curr_other_er;
00987 
00988   assert( base != NULL );
00989   assert( base->name != NULL );
00990 
00991   /* Handle all functional unit expressions */
00992   curr_base_exp  = base->exp_head;
00993   curr_other_exp = other->exp_head;
00994   while( (curr_base_exp != NULL) && (curr_other_exp != NULL) ) {
00995     expression_merge( curr_base_exp->exp, curr_other_exp->exp );
00996     curr_base_exp  = curr_base_exp->next;
00997     curr_other_exp = curr_other_exp->next;
00998   }
00999   assert( (curr_base_exp == NULL) && (curr_other_exp == NULL) );
01000 
01001   /* Handle all functional unit signals */
01002   curr_base_sig  = base->sig_head;
01003   curr_other_sig = other->sig_head;
01004   while( (curr_base_sig != NULL) && (curr_other_sig != NULL) ) {
01005     vsignal_merge( curr_base_sig->sig, curr_other_sig->sig );
01006     curr_base_sig  = curr_base_sig->next;
01007     curr_other_sig = curr_other_sig->next;
01008   }
01009   assert( (curr_base_sig == NULL) && (curr_other_exp == NULL) );
01010 
01011   /* Handle all functional unit FSMs */
01012   curr_base_fsm  = base->fsm_head;
01013   curr_other_fsm = other->fsm_head;
01014   while( (curr_base_fsm != NULL) && (curr_other_fsm != NULL) ) {
01015     fsm_merge( curr_base_fsm->table, curr_other_fsm->table );
01016     curr_base_fsm  = curr_base_fsm->next;
01017     curr_other_fsm = curr_other_fsm->next;
01018   }
01019   assert( (curr_base_fsm == NULL) && (curr_other_fsm == NULL) );
01020 
01021   /* Handle all functional unit exclusion reasons */
01022   curr_other_er = other->er_head;
01023   while( curr_other_er != NULL ) {
01024     exclude_merge( base, curr_other_er );
01025     curr_other_er = curr_other_er->next;
01026   }
01027 
01028   PROFILE_END;
01029 
01030 }

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

01411   { PROFILE(FUNIT_OUTPUT_DUMPVARS);
01412 
01413   sig_link* sigl  = funit->sig_head;
01414   bool      first = TRUE;
01415 
01416   while( sigl != NULL ) {
01417     if( (sigl->sig->suppl.part.assigned == 0) &&
01418         (sigl->sig->suppl.part.type != SSUPPL_TYPE_PARAM)      &&
01419         (sigl->sig->suppl.part.type != SSUPPL_TYPE_PARAM_REAL) &&
01420         (sigl->sig->suppl.part.type != SSUPPL_TYPE_ENUM)       &&
01421         (sigl->sig->suppl.part.type != SSUPPL_TYPE_MEM)        &&
01422         (sigl->sig->suppl.part.type != SSUPPL_TYPE_GENVAR)     &&
01423         (sigl->sig->suppl.part.type != SSUPPL_TYPE_EVENT) ) {
01424       if( first ) {
01425         first = FALSE;
01426         fprintf( vfile, "  $dumpvars( 1, %s.%s", scope, sigl->sig->name );
01427       } else {
01428         fprintf( vfile, ",\n                %s.%s", scope, sigl->sig->name );
01429       }
01430     }
01431     sigl = sigl->next;
01432   } 
01433 
01434   if( !first ) {
01435     fprintf( vfile, " );\n" );
01436   }
01437 
01438   PROFILE_END;
01439 
01440 }

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

01323   { PROFILE(FUNIT_PUSH_THREADS);
01324 
01325   assert( funit != NULL );
01326 
01327   if( funit->elem_type == 0 ) {
01328     if( (funit->elem.thr != NULL) && (funit->elem.thr->suppl.part.state == THR_ST_WAITING) && (funit->elem.thr->curr == stmt) ) {
01329       sim_thread_push( funit->elem.thr, time );
01330     }
01331   } else {
01332     thr_link* curr = funit->elem.tlist->head;
01333     while( (curr != NULL) && (curr->thr != NULL) ) {
01334       if( (curr->thr != NULL) && (curr->thr->suppl.part.state == THR_ST_WAITING) && (curr->thr->curr == stmt) ) {
01335         sim_thread_push( curr->thr, time );
01336       }
01337       curr = curr->next;
01338     }
01339   }
01340 
01341   PROFILE_END;
01342 
01343 }

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

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

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

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

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

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


Generated on Wed Jun 17 22:19:22 2009 for Covered by doxygen 1.3.4