line.h File Reference

Contains functions for determining/reporting line coverage. More...

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

Go to the source code of this file.

Functions

void line_get_stats (func_unit *funit, unsigned int *hit, unsigned int *excluded, unsigned int *total)
 Calculates line coverage numbers for the specified expression list.
void line_collect (func_unit *funit, int cov, int **lines, int **excludes, char ***reasons, int *line_cnt, int *line_size)
 Gathers line numbers from specified functional unit that were not hit during simulation.
void line_get_funit_summary (func_unit *funit, unsigned int *hit, unsigned int *excluded, unsigned int *total)
 Returns hit and total information for specified functional unit.
void line_get_inst_summary (funit_inst *inst, unsigned int *hit, unsigned int *excluded, unsigned int *total)
 Returns hit and total information for specified functional unit instance.
void line_report (FILE *ofile, bool verbose)
 Generates report output for line coverage.

Detailed Description

Contains functions for determining/reporting line coverage.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
3/31/2002

Function Documentation

void line_collect ( func_unit funit,
int  cov,
int **  lines,
int **  excludes,
char ***  reasons,
int *  line_cnt,
int *  line_size 
)

Gathers line numbers from specified functional unit that were not hit during simulation.

Allocates and populates the lines and exludes array with the line numbers and exclusion values (respectively) that were not hit during simulation.

Parameters:
funit Pointer to functional unit
cov If set to 1, gets covered lines, if 0 retrieves uncovered lines; otherwise, gets all lines
lines Pointer to array of integers that will contain the line numbers
excludes Pointer to array of integers that will contain the exclude values
reasons Pointer to array of strings that may contain exclusion reasons
line_cnt Pointer to size of lines and excludes arrays
line_size Pointer to the total number of lines/excludes integers allocated

References ESUPPL_EXCLUDED, exclude_find_exclude_reason(), expression_s::exec_num, statement_s::exp, EXP_OP_CASE, EXP_OP_CASEX, EXP_OP_CASEZ, EXP_OP_DEFAULT, EXP_OP_DELAY, EXP_OP_FOREVER, EXP_OP_FORK, EXP_OP_JOIN, EXP_OP_NB_CALL, EXP_OP_NOOP, EXP_OP_RASSIGN, expression_get_last_line_expr(), FALSE, func_iter_dealloc(), func_iter_get_next_statement(), func_iter_init(), expression_s::id, expression_s::line, malloc_safe, expression_s::op, PROFILE, PROFILE_END, realloc_safe, exclude_reason_s::reason, strdup_safe, expression_s::suppl, and TRUE.

00129   { PROFILE(LINE_COLLECT);
00130 
00131   int         i;          /* Loop iterator */
00132   int         last_line;  /* Specifies the last line of the current expression  */
00133   statement*  stmt;       /* Pointer to current statement */
00134   func_iter   fi;         /* Functional unit iterator */
00135 
00136   /* Create an array that will hold the number of uncovered lines */
00137   *line_size = 20;
00138   *line_cnt  = 0;
00139   *lines     = (int*)malloc_safe( sizeof( int ) * (*line_size) );
00140   *excludes  = (int*)malloc_safe( sizeof( int ) * (*line_size) );
00141   *reasons   = (char**)malloc_safe( sizeof( char* ) * (*line_size) );
00142 
00143   /* Initialize the functional unit iterator */
00144   func_iter_init( &fi, funit, TRUE, FALSE );
00145 
00146   stmt = func_iter_get_next_statement( &fi );
00147   while( stmt != NULL ) {
00148 
00149     if( (stmt->exp->op != EXP_OP_DELAY)   &&
00150         (stmt->exp->op != EXP_OP_CASE)    &&
00151         (stmt->exp->op != EXP_OP_CASEX)   &&
00152         (stmt->exp->op != EXP_OP_CASEZ)   &&
00153         (stmt->exp->op != EXP_OP_DEFAULT) &&
00154         (stmt->exp->op != EXP_OP_NB_CALL) &&
00155         (stmt->exp->op != EXP_OP_FORK)    &&
00156         (stmt->exp->op != EXP_OP_JOIN)    &&
00157         (stmt->exp->op != EXP_OP_NOOP)    &&
00158         (stmt->exp->op != EXP_OP_FOREVER) &&
00159         (stmt->exp->op != EXP_OP_RASSIGN) &&
00160         (stmt->exp->line != 0) ) {
00161 
00162       if( ((stmt->exp->exec_num > 0) ? 1 : 0) == cov ) {
00163 
00164         last_line = expression_get_last_line_expr( stmt->exp )->line;
00165         for( i=stmt->exp->line; i<=last_line; i++ ) {
00166           exclude_reason* er;
00167           if( *line_cnt == *line_size ) {
00168             *line_size += 20;
00169             *lines      = (int*)realloc_safe( *lines,    (sizeof( int ) * (*line_size - 20)), (sizeof( int ) * (*line_size)) );
00170             *excludes   = (int*)realloc_safe( *excludes, (sizeof( int ) * (*line_size - 20)), (sizeof( int ) * (*line_size)) );
00171             *reasons    = (char**)realloc_safe( *reasons, (sizeof( char* ) * (*line_size - 20)), (sizeof( char* ) * (*line_size)) );
00172           }
00173           (*lines)[(*line_cnt)]    = i;
00174           (*excludes)[(*line_cnt)] = ESUPPL_EXCLUDED( stmt->exp->suppl );
00175 
00176           /* If the toggle is currently excluded, check to see if there's a reason associated with it */
00177           if( (ESUPPL_EXCLUDED( stmt->exp->suppl ) == 1) && ((er = exclude_find_exclude_reason( 'L', stmt->exp->id, funit )) != NULL) ) {
00178             (*reasons)[(*line_cnt)] = strdup_safe( er->reason );
00179           } else {
00180             (*reasons)[(*line_cnt)] = NULL;
00181           }
00182           (*line_cnt)++;
00183         }
00184 
00185       }
00186 
00187     }
00188 
00189     stmt = func_iter_get_next_statement( &fi );
00190 
00191   }
00192 
00193   func_iter_dealloc( &fi );
00194 
00195   PROFILE_END;
00196 
00197 }

void line_get_funit_summary ( func_unit funit,
unsigned int *  hit,
unsigned int *  excluded,
unsigned int *  total 
)

Returns hit and total information for specified functional unit.

Looks up summary information for specified functional unit.

Parameters:
funit Pointer to functional unit
hit Pointer to number of lines hit in this functional unit
excluded Pointer to number of lines excluded in this functional unit
total Pointer to total number of lines in this functional unit

References statistic_s::line_excluded, statistic_s::line_hit, statistic_s::line_total, PROFILE, PROFILE_END, and func_unit_s::stat.

00207   { PROFILE(LINE_GET_FUNIT_SUMMARY);
00208 
00209   *hit      = funit->stat->line_hit;
00210   *excluded = funit->stat->line_excluded; 
00211   *total    = funit->stat->line_total;
00212 
00213   PROFILE_END;
00214 
00215 }

void line_get_inst_summary ( funit_inst inst,
unsigned int *  hit,
unsigned int *  excluded,
unsigned int *  total 
)

Returns hit and total information for specified functional unit instance.

Looks up summary information for specified functional unit instance.

Parameters:
inst Pointer to functional unit instance
hit Pointer to number of lines hit in this functional unit
excluded Pointer to number of lines excluded in this functional unit
total Pointer to total number of lines in this functional unit

References statistic_s::line_excluded, statistic_s::line_hit, statistic_s::line_total, PROFILE, PROFILE_END, and funit_inst_s::stat.

00225   { PROFILE(LINE_GET_INST_SUMMARY);
00226 
00227   *hit      = inst->stat->line_hit;
00228   *excluded = inst->stat->line_excluded;
00229   *total    = inst->stat->line_total;
00230 
00231   PROFILE_END;
00232 
00233 }

void line_get_stats ( func_unit funit,
unsigned int *  hit,
unsigned int *  excluded,
unsigned int *  total 
)

Calculates line coverage numbers for the specified expression list.

Iterates through given statement list, gathering information about which lines exist in the list, which lines were hit during simulation and which lines were missed during simulation. This information is used to report summary information about line coverage.

Parameters:
funit Pointer to current functional unit to explore
hit Holds total number of lines hit
excluded Pointer to the number of excluded lines
total Holds total number of lines parsed

References expression_s::exec_num, statement_s::exp, EXP_OP_CASE, EXP_OP_CASEX, EXP_OP_CASEZ, EXP_OP_DEFAULT, EXP_OP_DELAY, EXP_OP_FOREVER, EXP_OP_FORK, EXP_OP_JOIN, EXP_OP_NB_CALL, EXP_OP_NOOP, EXP_OP_RASSIGN, FALSE, func_iter_dealloc(), func_iter_get_next_statement(), func_iter_init(), funit_is_unnamed(), expression_s::line, expression_s::op, statement_s::part, PROFILE, PROFILE_END, statement_s::suppl, and TRUE.

Referenced by report_gather_funit_stats(), and report_gather_instance_stats().

00071   { PROFILE(LINE_GET_STATS);
00072 
00073   statement* stmt;  /* Pointer to current statement */
00074   func_iter  fi;    /* Functional unit iterator */
00075 
00076   if( !funit_is_unnamed( funit ) ) {
00077 
00078     /* Initialize the functional unit iterator */
00079     func_iter_init( &fi, funit, TRUE, FALSE );
00080 
00081     stmt = func_iter_get_next_statement( &fi );
00082     while( stmt != NULL ) {
00083 
00084       if( (stmt->exp->op != EXP_OP_DELAY)   &&
00085           (stmt->exp->op != EXP_OP_CASE)    &&
00086           (stmt->exp->op != EXP_OP_CASEX)   &&
00087           (stmt->exp->op != EXP_OP_CASEZ)   &&
00088           (stmt->exp->op != EXP_OP_DEFAULT) &&
00089           (stmt->exp->op != EXP_OP_NB_CALL) &&
00090           (stmt->exp->op != EXP_OP_FORK)    &&
00091           (stmt->exp->op != EXP_OP_JOIN)    &&
00092           (stmt->exp->op != EXP_OP_NOOP)    &&
00093           (stmt->exp->op != EXP_OP_FOREVER) &&
00094           (stmt->exp->op != EXP_OP_RASSIGN) &&
00095           (stmt->exp->line != 0) ) {
00096         *total = *total + 1;
00097         if( (stmt->exp->exec_num > 0) || (stmt->suppl.part.excluded == 1) ) {
00098           (*hit)++;
00099           if( stmt->suppl.part.excluded == 1 ) {
00100             (*excluded)++;
00101           }
00102         }
00103       }
00104 
00105       stmt = func_iter_get_next_statement( &fi );
00106 
00107     }
00108 
00109     func_iter_dealloc( &fi );
00110 
00111   }
00112 
00113   PROFILE_END;
00114 
00115 }

void line_report ( FILE *  ofile,
bool  verbose 
)

Generates report output for line coverage.

After the design is read into the functional unit hierarchy, parses the hierarchy by functional unit, reporting the line coverage for each functional unit encountered. The parent functional unit will specify its own line coverage along with a total line coverage including its children.

Parameters:
ofile Pointer to file to output results to
verbose Specifies whether to generate summary or verbose output

References curr_db, FALSE, funit_head, inst_link_s::inst, db_s::inst_head, line_display_funit_summary(), line_display_instance_summary(), line_funit_summary(), line_funit_verbose(), line_instance_summary(), line_instance_verbose(), funit_inst_s::name_diff, inst_link_s::next, PROFILE, PROFILE_END, report_covered, report_exclusions, report_instance, and funit_inst_s::suppl.

Referenced by report_generate().

00624   { PROFILE(LINE_REPORT);
00625 
00626   bool       missed_found = FALSE;  /* If set to TRUE, lines were found to be missed */
00627   inst_link* instl;                 /* Pointer to current instance link */
00628   int        acc_hits     = 0;      /* Accumulated line hits for entire design */
00629   int        acc_total    = 0;      /* Accumulated line total for entire design */
00630 
00631   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
00632   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   LINE COVERAGE RESULTS   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
00633   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
00634 
00635   if( report_instance ) {
00636 
00637     fprintf( ofile, "Instance                                           Hit/ Miss/Total    Percent hit\n" );
00638     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
00639 
00640     instl = db_list[curr_db]->inst_head;
00641     while( instl != NULL ) {
00642       missed_found |= line_instance_summary( ofile, instl->inst, (instl->inst->suppl.name_diff ? "<NA>" : "*"), &acc_hits, &acc_total );
00643       instl = instl->next;
00644     }
00645     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
00646     (void)line_display_instance_summary( ofile, "Accumulated", acc_hits, acc_total );
00647     
00648     if( verbose && (missed_found || report_covered || report_exclusions) ) {
00649       fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
00650       instl = db_list[curr_db]->inst_head;
00651       while( instl != NULL ) {
00652         line_instance_verbose( ofile, instl->inst, (instl->inst->suppl.name_diff ? "<NA>" : "*") );
00653         instl = instl->next;
00654       }
00655     }
00656 
00657   } else {
00658 
00659     fprintf( ofile, "Module/Task/Function      Filename                 Hit/ Miss/Total    Percent hit\n" );
00660     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
00661 
00662     missed_found = line_funit_summary( ofile, db_list[curr_db]->funit_head, &acc_hits, &acc_total );
00663     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
00664     (void)line_display_funit_summary( ofile, "Accumulated", "", acc_hits, acc_total );
00665 
00666     if( verbose && (missed_found || report_covered || report_exclusions) ) {
00667       fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
00668       line_funit_verbose( ofile, db_list[curr_db]->funit_head );
00669     }
00670 
00671   }
00672 
00673   fprintf( ofile, "\n\n" );
00674 
00675   PROFILE_END;
00676 
00677 }

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