#include <stdio.h>
#include "defines.h"
Go to the source code of this file.
Functions | |
| func_unit * | funit_create () |
| Creates new functional unit from heap and initializes structure. | |
| func_unit * | funit_get_curr_module (func_unit *funit) |
| Returns the parent module of the given functional unit. | |
| 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). | |
| func_unit * | funit_get_curr_function (func_unit *funit) |
| Returns the parent function of the given functional unit (if there is one). | |
| func_unit * | funit_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_parm * | funit_find_param (char *name, func_unit *funit) |
| Finds specified module parameter given the current functional unit and its scope. | |
| vsignal * | funit_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_unit * | funit_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. | |
|
||||||||||||
|
Adds given thread to functional unit's thread pointer/thread pointer list.
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 }
|
|
|
Creates new functional unit from heap and initializes structure.
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 }
|
|
||||||||||||||||
|
Reads and merges two functional units into base functional unit.
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 }
|
|
||||||||||||||||||||
|
Read contents of current line from specified file, creates functional unit and adds to functional unit list.
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 }
|
|
||||||||||||||||||||||||||||||||
|
Writes contents of provided functional unit to specified output.
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 }
|
|
|
Deallocates functional unit element from heap. Deallocates functional unit; name and filename strings; and finally the structure itself from the heap.
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 }
|
|
||||||||||||
|
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.
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 }
|
|
|
Displays expressions stored in this functional unit.
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 }
|
|
|
Displays signals stored in this functional unit.
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 }
|
|
|
Finds the functional unit that contains the given statement/expression ID.
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 }
|
|
||||||||||||
|
Finds specified module parameter given the current functional unit and its scope.
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 }
|
|
||||||||||||
|
Finds specified signal given in the current functional unit.
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 }
|
|
|
Flattens the functional unit name by removing all unnamed scope portions.
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 }
|
|
||||||||||||
|
Generates the internally used task/function/named-block name for the specified 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 }
|
|
|
Returns the parent function of the given functional unit (if there is one).
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 }
|
|
|
Returns the parent module of the given functional unit.
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 }
|
|
|
Returns the parent module of the given functional unit (returning a const version).
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 }
|
|
|
Returns the parent task of the given functional unit (if there is one).
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 }
|
|
|
Returns the number of input, output and inout ports in the specified functional unit.
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 }
|
|
||||||||||||
|
Returns TRUE if the specified "parent" functional unit is a parent of the "child" functional unit.
|
|
|
Returns TRUE if the given functional unit does not contain any input, output or inout ports.
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 }
|
|
|
Returns TRUE if the given functional unit is an unnamed scope.
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 }
|
|
||||||||||||
|
Returns TRUE if the specified "parent" functional unit is a parent of the "child" functional unit.
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 }
|
|
||||||||||||
|
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.
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 }
|
|
||||||||||||||||
|
Outputs dumpvars calls to the given file. Outputs all of the needed signals to the specified file.
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 }
|
|
||||||||||||||||
|
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.
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 }
|
|
||||||||||||
|
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.
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 }
|
|
||||||||||||||||||||
|
Sizes all elements for the current functional unit from the given instance.
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 }
|
|
||||||||||||
|
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.
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 }
|
1.3.4