Contains functions used to check for race conditions and proper signal use within the specified design. More...
#include <stdio.h>
#include "defines.h"
Go to the source code of this file.
Functions | |
void | race_check_modules () |
Checks the current module for race conditions. | |
void | race_db_write (race_blk *head, FILE *file) |
Writes contents of specified race condition block to specified file output. | |
void | race_db_read (char **line, func_unit *curr_mod) |
Reads contents from specified line for a race condition block and assigns the new block to the curr_mod. | |
void | race_get_stats (race_blk *curr, unsigned int *race_total, unsigned int type_total[][RACE_TYPE_NUM]) |
Get statistic information for the specified race condition block list. | |
void | race_report (FILE *ofile, bool verbose) |
Displays report information for race condition blocks in design. | |
void | race_collect_lines (func_unit *funit, int **slines, int **elines, int **reasons, int *line_cnt) |
Collects all of the lines in the specified module that were not verified due to race condition breach. | |
void | race_blk_delete_list (race_blk *rb) |
Deallocates the specified race condition block from memory. |
Contains functions used to check for race conditions and proper signal use within the specified design.
void race_blk_delete_list | ( | race_blk * | rb | ) |
Deallocates the specified race condition block from memory.
Recursively deallocates the specified race condition block list.
rb | Pointer to race condition block to deallocate |
References free_safe, race_blk_s::next, PROFILE, PROFILE_END, and race_blk_delete_list().
Referenced by funit_clean(), and race_blk_delete_list().
01091 { PROFILE(RACE_BLK_DELETE_LIST); 01092 01093 if( rb != NULL ) { 01094 01095 /* Delete the next race condition block first */ 01096 race_blk_delete_list( rb->next ); 01097 01098 /* Deallocate the memory for this race condition block */ 01099 free_safe( rb, sizeof( race_blk ) ); 01100 01101 } 01102 01103 PROFILE_END; 01104 01105 }
void race_check_modules | ( | ) |
Checks the current module for race conditions.
anonymous | race_check_race_count funit_size_elements |
Performs race checking for the currently loaded module. This function should be called when the endmodule keyword is detected in the current module.
References isuppl_u::assert_ovl, stmt_blk_s::bassign, stmt_blk_s::cmb, curr_db, DEBUG, debug_mode, FALSE, free_safe, funit_link_s::funit, db_s::funit_head, FUNIT_MODULE, funit_size_elements(), db_s::inst_head, inst_link_find_by_funit(), malloc_safe, func_unit_s::name, stmt_blk_s::nassign, funit_link_s::next, stmt_link_s::next, ovl_is_assertion_module(), statement_s::part, isuppl_u::part, print_output(), PROFILE, PROFILE_END, race_calc_assignments(), race_calc_stmt_blk_type(), race_check_assignment_types(), race_check_one_block_assignment(), race_check_race_count(), stmt_blk_s::remove, sb_size, stmt_blk_s::seq, stmt_blk_s::stmt, stmt_link_s::stmt, stmt_blk_add_to_remove_list(), stmt_conn_id, func_unit_s::stmt_head, str_link_find(), statement_s::suppl, and func_unit_s::type.
Referenced by parse_design().
00730 { PROFILE(RACE_CHECK_MODULES); 00731 00732 int sb_index; /* Index to statement block array */ 00733 stmt_link* curr; 00734 funit_link* modl; /* Pointer to current module link */ 00735 int i; /* Loop iterator */ 00736 int ignore; /* Placeholder */ 00737 funit_inst* inst; /* Instance of this functional unit */ 00738 00739 modl = db_list[curr_db]->funit_head; 00740 00741 while( modl != NULL ) { 00742 00743 /* Get instance */ 00744 ignore = 0; 00745 inst = inst_link_find_by_funit( modl->funit, db_list[curr_db]->inst_head, &ignore ); 00746 00747 /* Only perform race condition checking for modules that are instantiated and are not OVL assertions and are not ignored */ 00748 if( (modl->funit->type == FUNIT_MODULE) && 00749 (inst != NULL) && 00750 ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( modl->funit )) && 00751 (str_link_find( modl->funit->name, race_ignore_mod_head ) == NULL) ) { 00752 00753 /* Size elements for the current module */ 00754 funit_size_elements( modl->funit, inst, FALSE, FALSE ); 00755 00756 /* Clear statement block array size */ 00757 sb_size = 0; 00758 00759 /* First, get the size of the statement block array for this module */ 00760 curr = modl->funit->stmt_head; 00761 while( curr != NULL ) { 00762 if( (curr->stmt->suppl.part.head == 1) && 00763 (curr->stmt->suppl.part.is_called == 0) ) { 00764 sb_size++; 00765 } 00766 curr = curr->next; 00767 } 00768 00769 if( sb_size > 0 ) { 00770 00771 /* Allocate memory for the statement block array and clear current index */ 00772 sb = (stmt_blk*)malloc_safe( sizeof( stmt_blk ) * sb_size ); 00773 sb_index = 0; 00774 00775 /* Second, populate the statement block array with pointers to the head statements */ 00776 curr = modl->funit->stmt_head; 00777 while( curr != NULL ) { 00778 if( (curr->stmt->suppl.part.head == 1) && 00779 (curr->stmt->suppl.part.is_called == 0) ) { 00780 sb[sb_index].stmt = curr->stmt; 00781 sb[sb_index].remove = FALSE; 00782 sb[sb_index].seq = FALSE; 00783 sb[sb_index].cmb = FALSE; 00784 sb[sb_index].bassign = FALSE; 00785 sb[sb_index].nassign = FALSE; 00786 race_calc_stmt_blk_type( sb[sb_index].stmt->exp, sb_index ); 00787 race_calc_assignments( sb[sb_index].stmt, sb_index ); 00788 sb_index++; 00789 stmt_conn_id++; 00790 } 00791 curr = curr->next; 00792 } 00793 00794 /* Perform checks #1 - #5 */ 00795 race_check_assignment_types( modl->funit ); 00796 00797 /* Perform check #6 */ 00798 race_check_one_block_assignment( modl->funit ); 00799 00800 /* Cleanup statements to be removed */ 00801 curr_funit = modl->funit; 00802 for( i=0; i<sb_size; i++ ) { 00803 if( sb[i].remove ) { 00804 #ifdef DEBUG_MODE 00805 if( debug_mode ) { 00806 print_output( "Removing statement block because it was found to have a race condition", DEBUG, __FILE__, __LINE__ ); 00807 } 00808 #endif 00809 stmt_blk_add_to_remove_list( sb[i].stmt ); 00810 } 00811 } 00812 00813 /* Deallocate stmt_blk list */ 00814 free_safe( sb, (sizeof( stmt_blk ) * sb_size) ); 00815 00816 } 00817 00818 } 00819 00820 modl = modl->next; 00821 00822 } 00823 00824 /* Handle output if any race conditions were found */ 00825 race_check_race_count(); 00826 00827 PROFILE_END; 00828 00829 }
void race_collect_lines | ( | func_unit * | funit, | |
int ** | slines, | |||
int ** | elines, | |||
int ** | reasons, | |||
int * | line_cnt | |||
) |
Collects all of the lines in the specified module that were not verified due to race condition breach.
Collects all of the line numbers in the specified module that were ignored from coverage due to detecting a race condition. This function is primarily used by the GUI for outputting purposes.
funit | Pointer to functional unit | |
slines | Pointer to an array of starting line numbers that contain line numbers of race condition statements | |
elines | Pointer to an array of ending line numbers that contain line numbers of race condition statements | |
reasons | Pointer to an array of race condition reason integers, one for each line in the lines array | |
line_cnt | Pointer to number of elements that exist in lines array |
References race_blk_s::end_line, race_blk_s::next, PROFILE, PROFILE_END, func_unit_s::race_head, realloc_safe, race_blk_s::reason, and race_blk_s::start_line.
01056 { PROFILE(RACE_COLLECT_LINES); 01057 01058 race_blk* curr_race = NULL; /* Pointer to current race condition block */ 01059 01060 /* Begin by allocating some memory for the lines */ 01061 *slines = NULL; 01062 *elines = NULL; 01063 *reasons = NULL; 01064 *line_cnt = 0; 01065 01066 curr_race = funit->race_head; 01067 while( curr_race != NULL ) { 01068 01069 *slines = (int*)realloc_safe( *slines, (sizeof( int ) * (*line_cnt)), (sizeof( int ) * (*line_cnt + 1)) ); 01070 *elines = (int*)realloc_safe( *elines, (sizeof( int ) * (*line_cnt)), (sizeof( int ) * (*line_cnt + 1)) ); 01071 *reasons = (int*)realloc_safe( *reasons, (sizeof( int ) * (*line_cnt)), (sizeof( int ) * (*line_cnt + 1)) ); 01072 01073 (*slines)[*line_cnt] = curr_race->start_line; 01074 (*elines)[*line_cnt] = curr_race->end_line; 01075 (*reasons)[*line_cnt] = curr_race->reason; 01076 (*line_cnt)++; 01077 01078 curr_race = curr_race->next; 01079 01080 } 01081 01082 PROFILE_END; 01083 01084 }
void race_db_read | ( | char ** | line, | |
func_unit * | curr_mod | |||
) |
Reads contents from specified line for a race condition block and assigns the new block to the curr_mod.
anonymous | Throw Throw |
Reads the specified line from the CDD file and parses it for race condition block information.
line | Pointer to line containing information for a race condition block | |
curr_mod | Pointer to current module to store race condition block to |
References FATAL, race_blk_s::next, print_output(), PROFILE, PROFILE_END, race_blk_create(), func_unit_s::race_head, func_unit_s::race_tail, and Throw.
Referenced by db_read(), and funit_db_mod_merge().
00859 { PROFILE(RACE_DB_READ); 00860 00861 int start_line; /* Starting line for race condition block */ 00862 int end_line; /* Ending line for race condition block */ 00863 int reason; /* Reason for why the race condition block exists */ 00864 int chars_read; /* Number of characters read via sscanf */ 00865 race_blk* rb; /* Pointer to newly created race condition block */ 00866 00867 if( sscanf( *line, "%d %d %d%n", &reason, &start_line, &end_line, &chars_read ) == 3 ) { 00868 00869 *line = *line + chars_read; 00870 00871 if( curr_mod == NULL ) { 00872 00873 print_output( "Internal error: race condition in database written before its functional unit", FATAL, __FILE__, __LINE__ ); 00874 Throw 0; 00875 00876 } else { 00877 00878 /* Create the new race condition block */ 00879 rb = race_blk_create( reason, start_line, end_line ); 00880 00881 /* Add the new race condition block to the current module */ 00882 if( curr_mod->race_head == NULL ) { 00883 curr_mod->race_head = curr_mod->race_tail = rb; 00884 } else { 00885 curr_mod->race_tail->next = rb; 00886 curr_mod->race_tail = rb; 00887 } 00888 00889 } 00890 00891 } else { 00892 00893 print_output( "Unable to parse race condition line in database file. Unable to read.", FATAL, __FILE__, __LINE__ ); 00894 Throw 0; 00895 00896 } 00897 00898 PROFILE_END; 00899 00900 }
void race_db_write | ( | race_blk * | rb, | |
FILE * | file | |||
) |
Writes contents of specified race condition block to specified file output.
Writes contents of specified race condition block to the specified output stream.
rb | Pointer to race condition block to write to specified output file | |
file | File handle of output stream to write |
References DB_TYPE_RACE, race_blk_s::end_line, PROFILE, PROFILE_END, race_blk_s::reason, and race_blk_s::start_line.
Referenced by funit_db_write().
00837 { PROFILE(RACE_DB_WRITE); 00838 00839 fprintf( file, "%d %d %d %d\n", 00840 DB_TYPE_RACE, 00841 rb->reason, 00842 rb->start_line, 00843 rb->end_line 00844 ); 00845 00846 PROFILE_END; 00847 00848 }
void race_get_stats | ( | race_blk * | curr, | |
unsigned int * | race_total, | |||
unsigned int | type_total[][RACE_TYPE_NUM] | |||
) |
Get statistic information for the specified race condition block list.
Iterates through specified race condition block list, totaling the number of race conditions found as well as tallying each type of race condition.
curr | Pointer to head of race condition block list | |
race_total | Pointer to value that will hold the total number of race conditions in this module | |
type_total | Pointer to array containing number of race conditions found for each violation type |
References race_blk_s::next, PROFILE, PROFILE_END, and race_blk_s::reason.
Referenced by report_gather_funit_stats(), and report_gather_instance_stats().
00910 { PROFILE(RACE_GET_STATS); 00911 00912 int i; /* Loop iterator */ 00913 00914 /* Clear totals */ 00915 *race_total = 0; 00916 for( i=0; i<RACE_TYPE_NUM; i++ ) { 00917 (*type_total)[i] = 0; 00918 } 00919 00920 /* Tally totals */ 00921 while( curr != NULL ) { 00922 (*type_total)[curr->reason]++; 00923 (*race_total)++; 00924 curr = curr->next; 00925 } 00926 00927 PROFILE_END; 00928 00929 }
void race_report | ( | FILE * | ofile, | |
bool | verbose | |||
) |
Displays report information for race condition blocks in design.
Generates the race condition report information and displays it to the specified output stream.
ofile | Output stream to display report information to | |
verbose | Specifies if summary or verbose output should be displayed |
References curr_db, funit_head, PROFILE, PROFILE_END, race_report_summary(), and race_report_verbose().
Referenced by report_generate().
01023 { PROFILE(RACE_REPORT); 01024 01025 bool found; /* If set to TRUE, race conditions were found */ 01026 01027 fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ); 01028 fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RACE CONDITION VIOLATIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ); 01029 fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ); 01030 fprintf( ofile, "Module Filename Number of Violations found\n" ); 01031 fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" ); 01032 01033 found = race_report_summary( ofile, db_list[curr_db]->funit_head ); 01034 01035 if( verbose && found ) { 01036 fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" ); 01037 race_report_verbose( ofile, db_list[curr_db]->funit_head ); 01038 } 01039 01040 fprintf( ofile, "\n\n" ); 01041 01042 PROFILE_END; 01043 01044 }