race.h File Reference

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.

Detailed Description

Contains functions used to check for race conditions and proper signal use within the specified design.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
12/15/2004

Function Documentation

void race_blk_delete_list ( race_blk rb  ) 

Deallocates the specified race condition block from memory.

Recursively deallocates the specified race condition block list.

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

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

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

Exceptions:
anonymous Throw Throw

Reads the specified line from the CDD file and parses it for race condition block information.

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

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

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

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

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