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. |
Contains functions for determining/reporting line coverage.
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.
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.
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.
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.
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.
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 }